aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-04-03 06:40:39 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-03 15:07:06 -0400
commitc7f34a69a2e32b139a6b66c8599252c46f37abba (patch)
treefe924689dda2164ce5affe3448e003a168254ea6 /drivers/net/wireless/brcm80211/brcmfmac
parente2432b6787a15e0b3c255a017d16033ba30204c0 (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.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c23
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c26
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h1
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);
623void brcmf_txflowblock_if(struct brcmf_if *ifp, 623void 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);
625extern u32 brcmf_get_chip_info(struct brcmf_if *ifp); 625extern u32 brcmf_get_chip_info(struct brcmf_if *ifp);
626extern 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
366void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) 366void 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
395done: 395void 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
245enum 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
338static int fcmode;
339module_param(fcmode, int, S_IRUSR);
340MODULE_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
933bool 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
21int brcmf_fws_init(struct brcmf_pub *drvr); 21int brcmf_fws_init(struct brcmf_pub *drvr);
22void brcmf_fws_deinit(struct brcmf_pub *drvr); 22void brcmf_fws_deinit(struct brcmf_pub *drvr);
23bool brcmf_fws_fc_active(struct brcmf_fws_info *fws);
23int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, 24int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
24 struct sk_buff *skb); 25 struct sk_buff *skb);
25 26