diff options
author | Arend van Spriel <arend@broadcom.com> | 2013-04-03 10:40:34 (GMT) |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-04-03 19:07:05 (GMT) |
commit | 29e04ae31ddb08794afbbef3cb72249d3804f47e (patch) | |
tree | d88e33096a73897f33754e8ffdfa149f8bff9087 /drivers/net/wireless | |
parent | fba1400a9b8149b3c7ee02be3b1ea0429912372e (diff) | |
download | linux-29e04ae31ddb08794afbbef3cb72249d3804f47e.tar.xz |
brcmfmac: allow stopping netif queue for different reasons
Currently, the netif queue is only stopped when the bus interface is
giving a push back. This will change soon so prepare the driver by
adding a stop reason and stop/resume the queue accordingly.
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Piotr Haber <phaber@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 17 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 29 |
2 files changed, 38 insertions, 8 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 64006ed..af307c1 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -555,6 +555,19 @@ struct brcmf_cfg80211_vif; struct brcmf_fws_mac_descriptor; /** + * enum brcmf_netif_stop_reason - reason for stopping netif queue. + * + * @BRCMF_NETIF_STOP_REASON_FWS_FC: + * netif stopped due to firmware signalling flow control. + * @BRCMF_NETIF_STOP_REASON_BLOCK_BUS: + * netif stopped due to bus blocking. + */ +enum brcmf_netif_stop_reason { + BRCMF_NETIF_STOP_REASON_FWS_FC = 1, + BRCMF_NETIF_STOP_REASON_BLOCK_BUS = 2 +}; + +/** * struct brcmf_if - interface control information. * * @drvr: points to device related information. @@ -567,6 +580,7 @@ struct brcmf_fws_mac_descriptor; * @ifidx: interface index in device firmware. * @bssidx: index of bss associated with this interface. * @mac_addr: assigned mac address. + * @netif_stop: bitmap indicates reason why netif queues are stopped. * @pend_8021x_cnt: tracks outstanding number of 802.1x frames. * @pend_8021x_wait: used for signalling change in count. */ @@ -581,6 +595,7 @@ struct brcmf_if { int ifidx; s32 bssidx; u8 mac_addr[ETH_ALEN]; + u8 netif_stop; atomic_t pend_8021x_cnt; wait_queue_head_t pend_8021x_wait; }; @@ -605,6 +620,8 @@ extern int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, char *name, u8 *mac_addr); extern void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx); +void brcmf_txflowblock_if(struct brcmf_if *ifp, + enum brcmf_netif_stop_reason reason, bool state); extern u32 brcmf_get_chip_info(struct brcmf_if *ifp); #endif /* _BRCMF_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index a08db02..3ba9e104 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -248,9 +248,27 @@ done: return NETDEV_TX_OK; } +void brcmf_txflowblock_if(struct brcmf_if *ifp, + enum brcmf_netif_stop_reason reason, bool state) +{ + if (!ifp) + return; + + brcmf_dbg(TRACE, "enter: idx=%d stop=0x%X reason=%d state=%d\n", + ifp->bssidx, ifp->netif_stop, reason, state); + if (state) { + if (!ifp->netif_stop) + netif_stop_queue(ifp->ndev); + ifp->netif_stop |= reason; + } else { + ifp->netif_stop &= ~reason; + if (!ifp->netif_stop) + netif_wake_queue(ifp->ndev); + } +} + void brcmf_txflowblock(struct device *dev, bool state) { - struct net_device *ndev; struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_pub *drvr = bus_if->drvr; int i; @@ -258,13 +276,8 @@ void brcmf_txflowblock(struct device *dev, bool state) brcmf_dbg(TRACE, "Enter\n"); for (i = 0; i < BRCMF_MAX_IFS; i++) - if (drvr->iflist[i]) { - ndev = drvr->iflist[i]->ndev; - if (state) - netif_stop_queue(ndev); - else - netif_wake_queue(ndev); - } + brcmf_txflowblock_if(drvr->iflist[i], + BRCMF_NETIF_STOP_REASON_BLOCK_BUS, state); } void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) |