summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
diff options
context:
space:
mode:
authorHante Meuleman2013-06-18 13:29:22 +0200
committerJohn W. Linville2013-06-18 20:46:48 +0200
commit7d747037b0642f6d939d6b0bb255b938b5f3c3ab (patch)
treef83c56f462cb28d66027f39240302be6f14c6814 /drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
parentath9k: Program initvals for CUS217 (diff)
downloadkernel-qcow2-linux-7d747037b0642f6d939d6b0bb255b938b5f3c3ab.tar.gz
kernel-qcow2-linux-7d747037b0642f6d939d6b0bb255b938b5f3c3ab.tar.xz
kernel-qcow2-linux-7d747037b0642f6d939d6b0bb255b938b5f3c3ab.zip
brcmfmac: Only use credits for bcmc when firmware indicates it.
The firmware will sent an event message when bc/mc traffic should be sent to the device using credit mechanism. Reviewed-by: Arend Van Spriel <arend@broadcom.com> Signed-off-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/net/wireless/brcm80211/brcmfmac/fwsignal.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 70f70cea7f7d..1d8fa7dfa53d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -426,6 +426,7 @@ struct brcmf_fws_info {
struct brcmf_fws_stats stats;
struct brcmf_fws_hanger hanger;
enum brcmf_fws_fcmode fcmode;
+ bool bcmc_credit_check;
struct brcmf_fws_macdesc_table desc;
struct workqueue_struct *fws_wq;
struct work_struct fws_dequeue_work;
@@ -1438,6 +1439,20 @@ static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp,
return 0;
}
+static int brcmf_fws_notify_bcmc_credit_support(struct brcmf_if *ifp,
+ const struct brcmf_event_msg *e,
+ void *data)
+{
+ struct brcmf_fws_info *fws = ifp->drvr->fws;
+ ulong flags;
+
+ brcmf_fws_lock(ifp->drvr, flags);
+ if (fws)
+ fws->bcmc_credit_check = true;
+ brcmf_fws_unlock(ifp->drvr, flags);
+ return 0;
+}
+
int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
struct sk_buff *skb)
{
@@ -1806,6 +1821,12 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
eh->h_dest, multicast, fifo);
brcmf_fws_lock(drvr, flags);
+ /* multicast credit support is conditional, setting
+ * flag to false to assure credit is consumed below.
+ */
+ if (fws->bcmc_credit_check)
+ multicast = false;
+
if (skcb->mac->suppressed ||
fws->bus_flow_blocked ||
brcmf_fws_mac_desc_closed(fws, skcb->mac, fifo) ||
@@ -1878,7 +1899,8 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
brcmf_fws_lock(fws->drvr, flags);
for (fifo = NL80211_NUM_ACS; fifo >= 0 && !fws->bus_flow_blocked;
fifo--) {
- while (fws->fifo_credit[fifo]) {
+ while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) &&
+ (fifo == BRCMF_FWS_FIFO_BCMC))) {
skb = brcmf_fws_deq(fws, fifo);
if (!skb)
break;
@@ -1947,6 +1969,13 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
brcmf_err("register credit map handler failed\n");
goto fail;
}
+ rc = brcmf_fweh_register(drvr, BRCMF_E_BCMC_CREDIT_SUPPORT,
+ brcmf_fws_notify_bcmc_credit_support);
+ if (rc < 0) {
+ brcmf_err("register bcmc credit handler failed\n");
+ brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP);
+ goto fail;
+ }
/* setting the iovar may fail if feature is unsupported
* so leave the rc as is so driver initialization can
@@ -1971,6 +2000,7 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
return 0;
fail_event:
+ brcmf_fweh_unregister(drvr, BRCMF_E_BCMC_CREDIT_SUPPORT);
brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP);
fail:
brcmf_fws_deinit(drvr);