diff options
author | Arend van Spriel <arend@broadcom.com> | 2013-04-03 06:40:34 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-04-03 15:07:05 -0400 |
commit | 29e04ae31ddb08794afbbef3cb72249d3804f47e (patch) | |
tree | d88e33096a73897f33754e8ffdfa149f8bff9087 /drivers/net/wireless/brcm80211 | |
parent | fba1400a9b8149b3c7ee02be3b1ea0429912372e (diff) |
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/brcm80211')
-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 64006edeb430..af307c101c94 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; | |||
555 | struct brcmf_fws_mac_descriptor; | 555 | struct brcmf_fws_mac_descriptor; |
556 | 556 | ||
557 | /** | 557 | /** |
558 | * enum brcmf_netif_stop_reason - reason for stopping netif queue. | ||
559 | * | ||
560 | * @BRCMF_NETIF_STOP_REASON_FWS_FC: | ||
561 | * netif stopped due to firmware signalling flow control. | ||
562 | * @BRCMF_NETIF_STOP_REASON_BLOCK_BUS: | ||
563 | * netif stopped due to bus blocking. | ||
564 | */ | ||
565 | enum brcmf_netif_stop_reason { | ||
566 | BRCMF_NETIF_STOP_REASON_FWS_FC = 1, | ||
567 | BRCMF_NETIF_STOP_REASON_BLOCK_BUS = 2 | ||
568 | }; | ||
569 | |||
570 | /** | ||
558 | * struct brcmf_if - interface control information. | 571 | * struct brcmf_if - interface control information. |
559 | * | 572 | * |
560 | * @drvr: points to device related information. | 573 | * @drvr: points to device related information. |
@@ -567,6 +580,7 @@ struct brcmf_fws_mac_descriptor; | |||
567 | * @ifidx: interface index in device firmware. | 580 | * @ifidx: interface index in device firmware. |
568 | * @bssidx: index of bss associated with this interface. | 581 | * @bssidx: index of bss associated with this interface. |
569 | * @mac_addr: assigned mac address. | 582 | * @mac_addr: assigned mac address. |
583 | * @netif_stop: bitmap indicates reason why netif queues are stopped. | ||
570 | * @pend_8021x_cnt: tracks outstanding number of 802.1x frames. | 584 | * @pend_8021x_cnt: tracks outstanding number of 802.1x frames. |
571 | * @pend_8021x_wait: used for signalling change in count. | 585 | * @pend_8021x_wait: used for signalling change in count. |
572 | */ | 586 | */ |
@@ -581,6 +595,7 @@ struct brcmf_if { | |||
581 | int ifidx; | 595 | int ifidx; |
582 | s32 bssidx; | 596 | s32 bssidx; |
583 | u8 mac_addr[ETH_ALEN]; | 597 | u8 mac_addr[ETH_ALEN]; |
598 | u8 netif_stop; | ||
584 | atomic_t pend_8021x_cnt; | 599 | atomic_t pend_8021x_cnt; |
585 | wait_queue_head_t pend_8021x_wait; | 600 | wait_queue_head_t pend_8021x_wait; |
586 | }; | 601 | }; |
@@ -605,6 +620,8 @@ extern int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); | |||
605 | extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, | 620 | extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, |
606 | s32 ifidx, char *name, u8 *mac_addr); | 621 | s32 ifidx, char *name, u8 *mac_addr); |
607 | extern void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx); | 622 | extern void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx); |
623 | void brcmf_txflowblock_if(struct brcmf_if *ifp, | ||
624 | enum brcmf_netif_stop_reason reason, bool state); | ||
608 | extern u32 brcmf_get_chip_info(struct brcmf_if *ifp); | 625 | extern u32 brcmf_get_chip_info(struct brcmf_if *ifp); |
609 | 626 | ||
610 | #endif /* _BRCMF_H_ */ | 627 | #endif /* _BRCMF_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index a08db02537fc..3ba9e1049f3b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -248,9 +248,27 @@ done: | |||
248 | return NETDEV_TX_OK; | 248 | return NETDEV_TX_OK; |
249 | } | 249 | } |
250 | 250 | ||
251 | void brcmf_txflowblock_if(struct brcmf_if *ifp, | ||
252 | enum brcmf_netif_stop_reason reason, bool state) | ||
253 | { | ||
254 | if (!ifp) | ||
255 | return; | ||
256 | |||
257 | brcmf_dbg(TRACE, "enter: idx=%d stop=0x%X reason=%d state=%d\n", | ||
258 | ifp->bssidx, ifp->netif_stop, reason, state); | ||
259 | if (state) { | ||
260 | if (!ifp->netif_stop) | ||
261 | netif_stop_queue(ifp->ndev); | ||
262 | ifp->netif_stop |= reason; | ||
263 | } else { | ||
264 | ifp->netif_stop &= ~reason; | ||
265 | if (!ifp->netif_stop) | ||
266 | netif_wake_queue(ifp->ndev); | ||
267 | } | ||
268 | } | ||
269 | |||
251 | void brcmf_txflowblock(struct device *dev, bool state) | 270 | void brcmf_txflowblock(struct device *dev, bool state) |
252 | { | 271 | { |
253 | struct net_device *ndev; | ||
254 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 272 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
255 | struct brcmf_pub *drvr = bus_if->drvr; | 273 | struct brcmf_pub *drvr = bus_if->drvr; |
256 | int i; | 274 | int i; |
@@ -258,13 +276,8 @@ void brcmf_txflowblock(struct device *dev, bool state) | |||
258 | brcmf_dbg(TRACE, "Enter\n"); | 276 | brcmf_dbg(TRACE, "Enter\n"); |
259 | 277 | ||
260 | for (i = 0; i < BRCMF_MAX_IFS; i++) | 278 | for (i = 0; i < BRCMF_MAX_IFS; i++) |
261 | if (drvr->iflist[i]) { | 279 | brcmf_txflowblock_if(drvr->iflist[i], |
262 | ndev = drvr->iflist[i]->ndev; | 280 | BRCMF_NETIF_STOP_REASON_BLOCK_BUS, state); |
263 | if (state) | ||
264 | netif_stop_queue(ndev); | ||
265 | else | ||
266 | netif_wake_queue(ndev); | ||
267 | } | ||
268 | } | 281 | } |
269 | 282 | ||
270 | void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) | 283 | void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) |