diff options
author | Arend van Spriel <arend@broadcom.com> | 2013-04-03 06:40:39 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-04-03 15:07:06 -0400 |
commit | c7f34a69a2e32b139a6b66c8599252c46f37abba (patch) | |
tree | fe924689dda2164ce5affe3448e003a168254ea6 /drivers/net/wireless/brcm80211/brcmfmac | |
parent | e2432b6787a15e0b3c255a017d16033ba30204c0 (diff) |
brcmfmac: add flow-control mode to firmware signalling
Upcoming patches will add firmware signalled flow control. Prepare
by adding the mode, which defaults to disable it. The mode can be
queried by brcmf_fws_fc_active() and set by a module parameter.
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Piotr Haber <phaber@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@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/brcmfmac')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 26 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h | 1 |
4 files changed, 41 insertions, 11 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index af307c101c94..ef5e3a92deb1 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h | |||
@@ -623,5 +623,7 @@ extern void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx); | |||
623 | void brcmf_txflowblock_if(struct brcmf_if *ifp, | 623 | void brcmf_txflowblock_if(struct brcmf_if *ifp, |
624 | enum brcmf_netif_stop_reason reason, bool state); | 624 | enum brcmf_netif_stop_reason reason, bool state); |
625 | extern u32 brcmf_get_chip_info(struct brcmf_if *ifp); | 625 | extern u32 brcmf_get_chip_info(struct brcmf_if *ifp); |
626 | extern void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, | ||
627 | bool success); | ||
626 | 628 | ||
627 | #endif /* _BRCMF_H_ */ | 629 | #endif /* _BRCMF_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 3ba9e1049f3b..05c8840392e5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -363,21 +363,20 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) | |||
363 | } | 363 | } |
364 | } | 364 | } |
365 | 365 | ||
366 | void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) | 366 | void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, |
367 | bool success) | ||
367 | { | 368 | { |
368 | u8 ifidx; | 369 | struct brcmf_if *ifp; |
369 | struct ethhdr *eh; | 370 | struct ethhdr *eh; |
371 | u8 ifidx; | ||
370 | u16 type; | 372 | u16 type; |
371 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||
372 | struct brcmf_pub *drvr = bus_if->drvr; | ||
373 | struct brcmf_if *ifp; | ||
374 | int res; | 373 | int res; |
375 | 374 | ||
376 | res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp); | 375 | res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp); |
377 | 376 | ||
378 | ifp = drvr->iflist[ifidx]; | 377 | ifp = drvr->iflist[ifidx]; |
379 | if (!ifp) | 378 | if (!ifp) |
380 | goto done; | 379 | return; |
381 | 380 | ||
382 | if (res == 0) { | 381 | if (res == 0) { |
383 | eh = (struct ethhdr *)(txp->data); | 382 | eh = (struct ethhdr *)(txp->data); |
@@ -391,8 +390,18 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) | |||
391 | } | 390 | } |
392 | if (!success) | 391 | if (!success) |
393 | ifp->stats.tx_errors++; | 392 | ifp->stats.tx_errors++; |
393 | } | ||
394 | 394 | ||
395 | done: | 395 | void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) |
396 | { | ||
397 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||
398 | struct brcmf_pub *drvr = bus_if->drvr; | ||
399 | |||
400 | /* await txstatus signal for firmware is active */ | ||
401 | if (success && brcmf_fws_fc_active(drvr->fws)) | ||
402 | return; | ||
403 | |||
404 | brcmf_txfinalize(drvr, txp, success); | ||
396 | brcmu_pkt_buf_free_skb(txp); | 405 | brcmu_pkt_buf_free_skb(txp); |
397 | } | 406 | } |
398 | 407 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index 2afd850f22c6..cb1414d93a67 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | |||
@@ -14,6 +14,7 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/module.h> | ||
17 | #include <linux/if_ether.h> | 18 | #include <linux/if_ether.h> |
18 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
19 | #include <linux/skbuff.h> | 20 | #include <linux/skbuff.h> |
@@ -124,10 +125,6 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id) | |||
124 | #define BRCMF_FWS_STATE_OPEN 1 | 125 | #define BRCMF_FWS_STATE_OPEN 1 |
125 | #define BRCMF_FWS_STATE_CLOSE 2 | 126 | #define BRCMF_FWS_STATE_CLOSE 2 |
126 | 127 | ||
127 | #define BRCMF_FWS_FCMODE_NONE 0 | ||
128 | #define BRCMF_FWS_FCMODE_IMPLIED_CREDIT 1 | ||
129 | #define BRCMF_FWS_FCMODE_EXPLICIT_CREDIT 2 | ||
130 | |||
131 | #define BRCMF_FWS_MAC_DESC_TABLE_SIZE 32 | 128 | #define BRCMF_FWS_MAC_DESC_TABLE_SIZE 32 |
132 | #define BRCMF_FWS_MAX_IFNUM 16 | 129 | #define BRCMF_FWS_MAX_IFNUM 16 |
133 | #define BRCMF_FWS_MAC_DESC_ID_INVALID 0xff | 130 | #define BRCMF_FWS_MAC_DESC_ID_INVALID 0xff |
@@ -245,6 +242,12 @@ struct brcmf_skbuff_cb { | |||
245 | BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \ | 242 | BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \ |
246 | BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT) | 243 | BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT) |
247 | 244 | ||
245 | enum brcmf_fws_fcmode { | ||
246 | BRCMF_FWS_FCMODE_NONE, | ||
247 | BRCMF_FWS_FCMODE_IMPLIED_CREDIT, | ||
248 | BRCMF_FWS_FCMODE_EXPLICIT_CREDIT | ||
249 | }; | ||
250 | |||
248 | /** | 251 | /** |
249 | * struct brcmf_fws_mac_descriptor - firmware signalling data per node/interface | 252 | * struct brcmf_fws_mac_descriptor - firmware signalling data per node/interface |
250 | * | 253 | * |
@@ -328,9 +331,14 @@ struct brcmf_fws_info { | |||
328 | struct brcmf_fws_hanger hanger; | 331 | struct brcmf_fws_hanger hanger; |
329 | struct brcmf_fws_mac_descriptor nodes[BRCMF_FWS_MAC_DESC_TABLE_SIZE]; | 332 | struct brcmf_fws_mac_descriptor nodes[BRCMF_FWS_MAC_DESC_TABLE_SIZE]; |
330 | struct brcmf_fws_mac_descriptor other; | 333 | struct brcmf_fws_mac_descriptor other; |
334 | enum brcmf_fws_fcmode fcmode; | ||
331 | int fifo_credit[NL80211_NUM_ACS+1+1]; | 335 | int fifo_credit[NL80211_NUM_ACS+1+1]; |
332 | }; | 336 | }; |
333 | 337 | ||
338 | static int fcmode; | ||
339 | module_param(fcmode, int, S_IRUSR); | ||
340 | MODULE_PARM_DESC(fcmode, "mode of firmware signalled flow control"); | ||
341 | |||
334 | /** | 342 | /** |
335 | * brcmf_fws_get_tlv_len() - returns defined length for given tlv id. | 343 | * brcmf_fws_get_tlv_len() - returns defined length for given tlv id. |
336 | */ | 344 | */ |
@@ -745,6 +753,7 @@ int brcmf_fws_init(struct brcmf_pub *drvr) | |||
745 | 753 | ||
746 | /* set linkage back */ | 754 | /* set linkage back */ |
747 | drvr->fws->drvr = drvr; | 755 | drvr->fws->drvr = drvr; |
756 | drvr->fws->fcmode = fcmode; | ||
748 | 757 | ||
749 | /* TODO: remove upon feature delivery */ | 758 | /* TODO: remove upon feature delivery */ |
750 | brcmf_err("%s bdcv2 tlv signaling [%x]\n", | 759 | brcmf_err("%s bdcv2 tlv signaling [%x]\n", |
@@ -920,3 +929,12 @@ void brcmf_fws_del_interface(struct brcmf_if *ifp) | |||
920 | brcmf_fws_cleanup(ifp->drvr->fws, ifp->ifidx); | 929 | brcmf_fws_cleanup(ifp->drvr->fws, ifp->ifidx); |
921 | kfree(entry); | 930 | kfree(entry); |
922 | } | 931 | } |
932 | |||
933 | bool brcmf_fws_fc_active(struct brcmf_fws_info *fws) | ||
934 | { | ||
935 | if (!fws) | ||
936 | return false; | ||
937 | |||
938 | brcmf_dbg(TRACE, "enter: mode=%d\n", fws->fcmode); | ||
939 | return fws->fcmode != BRCMF_FWS_FCMODE_NONE; | ||
940 | } | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h index 38a75e494d7d..1566f4de0eda 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | int brcmf_fws_init(struct brcmf_pub *drvr); | 21 | int brcmf_fws_init(struct brcmf_pub *drvr); |
22 | void brcmf_fws_deinit(struct brcmf_pub *drvr); | 22 | void brcmf_fws_deinit(struct brcmf_pub *drvr); |
23 | bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); | ||
23 | int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, | 24 | int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, |
24 | struct sk_buff *skb); | 25 | struct sk_buff *skb); |
25 | 26 | ||