summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mediatek/mt7601u/dma.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-06-26 19:12:17 +0200
committerDavid S. Miller <davem@davemloft.net>2019-06-26 19:12:17 +0200
commita8b79105239d3aecdf4942f7e53a14e0842dd5d2 (patch)
tree94498223d0ddde3517e651da73ec5da5450ada78 /drivers/net/wireless/mediatek/mt7601u/dma.c
parentnet: stmmac: Fix crash observed if PHY does not support EEE (diff)
parentairo: switch to skcipher interface (diff)
downloadlinux-a8b79105239d3aecdf4942f7e53a14e0842dd5d2.tar.xz
linux-a8b79105239d3aecdf4942f7e53a14e0842dd5d2.zip
Merge tag 'wireless-drivers-next-for-davem-2019-06-26' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valu says: ==================== wireless-drivers-next patches for 5.3 First set of patches for 5.3, but not that many patches this time. This pull request fails to compile with the tip tree due to ktime_get_boot_ns() API changes there. It should be easy for Linus to fix it in p54 driver once he pulls this, an example resolution here: https://lkml.kernel.org/r/20190625160432.533aa140@canb.auug.org.au Major changes: airo * switch to use skcipher interface p54 * support boottime in scan results rtw88 * add fast xmit support * add random mac address on scan support rt2x00 * add software watchdog to detect hangs, it's disabled by default ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/mediatek/mt7601u/dma.c')
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/dma.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/drivers/net/wireless/mediatek/mt7601u/dma.c b/drivers/net/wireless/mediatek/mt7601u/dma.c
index 66d60283e456..f6a0454abe04 100644
--- a/drivers/net/wireless/mediatek/mt7601u/dma.c
+++ b/drivers/net/wireless/mediatek/mt7601u/dma.c
@@ -185,10 +185,23 @@ static void mt7601u_complete_rx(struct urb *urb)
struct mt7601u_rx_queue *q = &dev->rx_q;
unsigned long flags;
- spin_lock_irqsave(&dev->rx_lock, flags);
+ /* do no schedule rx tasklet if urb has been unlinked
+ * or the device has been removed
+ */
+ switch (urb->status) {
+ case -ECONNRESET:
+ case -ESHUTDOWN:
+ case -ENOENT:
+ return;
+ default:
+ dev_err_ratelimited(dev->dev, "rx urb failed: %d\n",
+ urb->status);
+ /* fall through */
+ case 0:
+ break;
+ }
- if (mt7601u_urb_has_error(urb))
- dev_err(dev->dev, "Error: RX urb failed:%d\n", urb->status);
+ spin_lock_irqsave(&dev->rx_lock, flags);
if (WARN_ONCE(q->e[q->end].urb != urb, "RX urb mismatch"))
goto out;
@@ -220,14 +233,25 @@ static void mt7601u_complete_tx(struct urb *urb)
struct sk_buff *skb;
unsigned long flags;
- spin_lock_irqsave(&dev->tx_lock, flags);
+ switch (urb->status) {
+ case -ECONNRESET:
+ case -ESHUTDOWN:
+ case -ENOENT:
+ return;
+ default:
+ dev_err_ratelimited(dev->dev, "tx urb failed: %d\n",
+ urb->status);
+ /* fall through */
+ case 0:
+ break;
+ }
- if (mt7601u_urb_has_error(urb))
- dev_err(dev->dev, "Error: TX urb failed:%d\n", urb->status);
+ spin_lock_irqsave(&dev->tx_lock, flags);
if (WARN_ONCE(q->e[q->start].urb != urb, "TX urb mismatch"))
goto out;
skb = q->e[q->start].skb;
+ q->e[q->start].skb = NULL;
trace_mt_tx_dma_done(dev, skb);
__skb_queue_tail(&dev->tx_skb_done, skb);
@@ -355,19 +379,9 @@ int mt7601u_dma_enqueue_tx(struct mt7601u_dev *dev, struct sk_buff *skb,
static void mt7601u_kill_rx(struct mt7601u_dev *dev)
{
int i;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->rx_lock, flags);
-
- for (i = 0; i < dev->rx_q.entries; i++) {
- int next = dev->rx_q.end;
- spin_unlock_irqrestore(&dev->rx_lock, flags);
- usb_poison_urb(dev->rx_q.e[next].urb);
- spin_lock_irqsave(&dev->rx_lock, flags);
- }
-
- spin_unlock_irqrestore(&dev->rx_lock, flags);
+ for (i = 0; i < dev->rx_q.entries; i++)
+ usb_poison_urb(dev->rx_q.e[i].urb);
}
static int mt7601u_submit_rx_buf(struct mt7601u_dev *dev,
@@ -437,10 +451,10 @@ static void mt7601u_free_tx_queue(struct mt7601u_tx_queue *q)
{
int i;
- WARN_ON(q->used);
-
for (i = 0; i < q->entries; i++) {
usb_poison_urb(q->e[i].urb);
+ if (q->e[i].skb)
+ mt7601u_tx_status(q->dev, q->e[i].skb);
usb_free_urb(q->e[i].urb);
}
}