Commit 7d747037 authored by Hante Meuleman's avatar Hante Meuleman Committed by John W. Linville

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: default avatarArend Van Spriel <arend@broadcom.com>
Signed-off-by: default avatarHante Meuleman <meuleman@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent c177fabe
...@@ -101,7 +101,8 @@ struct brcmf_event; ...@@ -101,7 +101,8 @@ struct brcmf_event;
BRCMF_ENUM_DEF(P2P_PROBEREQ_MSG, 72) \ BRCMF_ENUM_DEF(P2P_PROBEREQ_MSG, 72) \
BRCMF_ENUM_DEF(DCS_REQUEST, 73) \ BRCMF_ENUM_DEF(DCS_REQUEST, 73) \
BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \ BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127)
#define BRCMF_ENUM_DEF(id, val) \ #define BRCMF_ENUM_DEF(id, val) \
BRCMF_E_##id = (val), BRCMF_E_##id = (val),
......
...@@ -426,6 +426,7 @@ struct brcmf_fws_info { ...@@ -426,6 +426,7 @@ struct brcmf_fws_info {
struct brcmf_fws_stats stats; struct brcmf_fws_stats stats;
struct brcmf_fws_hanger hanger; struct brcmf_fws_hanger hanger;
enum brcmf_fws_fcmode fcmode; enum brcmf_fws_fcmode fcmode;
bool bcmc_credit_check;
struct brcmf_fws_macdesc_table desc; struct brcmf_fws_macdesc_table desc;
struct workqueue_struct *fws_wq; struct workqueue_struct *fws_wq;
struct work_struct fws_dequeue_work; struct work_struct fws_dequeue_work;
...@@ -1438,6 +1439,20 @@ static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp, ...@@ -1438,6 +1439,20 @@ static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp,
return 0; 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, int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
struct sk_buff *skb) struct sk_buff *skb)
{ {
...@@ -1806,6 +1821,12 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, 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); eh->h_dest, multicast, fifo);
brcmf_fws_lock(drvr, flags); 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 || if (skcb->mac->suppressed ||
fws->bus_flow_blocked || fws->bus_flow_blocked ||
brcmf_fws_mac_desc_closed(fws, skcb->mac, fifo) || brcmf_fws_mac_desc_closed(fws, skcb->mac, fifo) ||
...@@ -1878,7 +1899,8 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker) ...@@ -1878,7 +1899,8 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
brcmf_fws_lock(fws->drvr, flags); brcmf_fws_lock(fws->drvr, flags);
for (fifo = NL80211_NUM_ACS; fifo >= 0 && !fws->bus_flow_blocked; for (fifo = NL80211_NUM_ACS; fifo >= 0 && !fws->bus_flow_blocked;
fifo--) { 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); skb = brcmf_fws_deq(fws, fifo);
if (!skb) if (!skb)
break; break;
...@@ -1947,6 +1969,13 @@ int brcmf_fws_init(struct brcmf_pub *drvr) ...@@ -1947,6 +1969,13 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
brcmf_err("register credit map handler failed\n"); brcmf_err("register credit map handler failed\n");
goto fail; 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 /* setting the iovar may fail if feature is unsupported
* so leave the rc as is so driver initialization can * so leave the rc as is so driver initialization can
...@@ -1971,6 +2000,7 @@ int brcmf_fws_init(struct brcmf_pub *drvr) ...@@ -1971,6 +2000,7 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
return 0; return 0;
fail_event: fail_event:
brcmf_fweh_unregister(drvr, BRCMF_E_BCMC_CREDIT_SUPPORT);
brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP); brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP);
fail: fail:
brcmf_fws_deinit(drvr); brcmf_fws_deinit(drvr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment