summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-03-03 12:45:30 +0100
committerJohn W. Linville <linville@tuxdriver.com>2013-03-06 22:28:46 +0100
commit6fc9ca138515880cc038b9588bd3637e66743343 (patch)
tree84b8f428d0af6f7284a315327897a385b5ff71f9 /drivers
parentbrcmfmac: release transmit packet in brcmf_txcomplete() (diff)
downloadlinux-6fc9ca138515880cc038b9588bd3637e66743343.tar.xz
linux-6fc9ca138515880cc038b9588bd3637e66743343.zip
brcmfmac: assure brcmf_txcomplete() is called in failure paths
For transmit packets the function brcmf_txcomplete() must be called. This should be done as well when for some reason the transmit fails to assure proper tx post processing. This patch fixes the code paths in brcmf_usb_tx() that forgot to do so. Reviewed-by: Piotr Haber <phaber@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index bf5bb8768e7b..01aed7ad6bec 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -570,15 +570,17 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
int ret;
brcmf_dbg(USB, "Enter, skb=%p\n", skb);
- if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP)
- return -EIO;
+ if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) {
+ ret = -EIO;
+ goto fail;
+ }
req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq,
&devinfo->tx_freecount);
if (!req) {
- brcmu_pkt_buf_free_skb(skb);
brcmf_err("no req to send\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto fail;
}
req->skb = skb;
@@ -591,18 +593,21 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
if (ret) {
brcmf_err("brcmf_usb_tx usb_submit_urb FAILED\n");
brcmf_usb_del_fromq(devinfo, req);
- brcmu_pkt_buf_free_skb(req->skb);
req->skb = NULL;
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req,
- &devinfo->tx_freecount);
- } else {
- if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
- !devinfo->tx_flowblock) {
- brcmf_txflowblock(dev, true);
- devinfo->tx_flowblock = true;
- }
+ &devinfo->tx_freecount);
+ goto fail;
}
+ if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
+ !devinfo->tx_flowblock) {
+ brcmf_txflowblock(dev, true);
+ devinfo->tx_flowblock = true;
+ }
+ return 0;
+
+fail:
+ brcmf_txcomplete(dev, skb, false);
return ret;
}