Skip to content

Commit

Permalink
brcmfmac: schedule dequeue upon firmware-signal reception
Browse files Browse the repository at this point in the history
Several firmware signals should be considered as opportunity to
send packets to the firmware. This patch adds conditional scheduling
of the dequeue worker thread while handling those signals.

Reviewed-by: Hante Meuleman <meuleman@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>
  • Loading branch information
Arend van Spriel authored and John W. Linville committed Apr 22, 2013
1 parent b75c1a3 commit a5e9d80
Showing 1 changed file with 24 additions and 12 deletions.
36 changes: 24 additions & 12 deletions drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
#define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01
#define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02

#define BRCMF_FWS_RET_OK_NOSCHEDULE 0
#define BRCMF_FWS_RET_OK_SCHEDULE 1

/**
* enum brcmf_fws_skb_state - indicates processing state of skb.
*
Expand Down Expand Up @@ -920,12 +923,13 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws,
entry->requested_credit = 0;
if (type == BRCMF_FWS_TYPE_MAC_OPEN) {
entry->state = BRCMF_FWS_STATE_OPEN;
return BRCMF_FWS_RET_OK_SCHEDULE;
} else {
entry->state = BRCMF_FWS_STATE_CLOSE;
for (i = BRCMF_FWS_FIFO_AC_BE; i < NL80211_NUM_ACS; i++)
brcmf_fws_tim_update(fws, entry, i);
}
return 0;
return BRCMF_FWS_RET_OK_NOSCHEDULE;
}

static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws,
Expand All @@ -952,10 +956,10 @@ static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws,
switch (type) {
case BRCMF_FWS_TYPE_INTERFACE_OPEN:
entry->state = BRCMF_FWS_STATE_OPEN;
return 0;
return BRCMF_FWS_RET_OK_SCHEDULE;
case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
entry->state = BRCMF_FWS_STATE_CLOSE;
return 0;
return BRCMF_FWS_RET_OK_NOSCHEDULE;
default:
ret = -EINVAL;
break;
Expand Down Expand Up @@ -985,7 +989,7 @@ static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type,
entry->requested_packet = data[0];

entry->ac_bitmap = data[2];
return 0;
return BRCMF_FWS_RET_OK_SCHEDULE;
}

static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
Expand Down Expand Up @@ -1259,7 +1263,7 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,

if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) {
brcmf_dbg(INFO, "ignored\n");
return 0;
return BRCMF_FWS_RET_OK_NOSCHEDULE;
}

brcmf_dbg(TRACE, "enter: data %pM\n", data);
Expand All @@ -1268,8 +1272,7 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,

brcmf_dbg(INFO, "map: credit %x delay %x\n", fws->fifo_credit_map,
fws->fifo_delay_map);
brcmf_fws_schedule_deq(fws);
return 0;
return BRCMF_FWS_RET_OK_SCHEDULE;
}

static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
Expand Down Expand Up @@ -1353,6 +1356,8 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
u8 type;
u8 len;
u8 *data;
s32 status;
s32 err;

brcmf_dbg(TRACE, "enter: ifidx %d, skblen %u, sig %d\n",
ifidx, skb->len, signal_len);
Expand All @@ -1372,6 +1377,7 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
data_len = signal_len;
signal_data = skb->data;

status = BRCMF_FWS_RET_OK_NOSCHEDULE;
while (data_len > 0) {
/* extract tlv info */
type = signal_data[0];
Expand All @@ -1397,6 +1403,7 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
if (len != brcmf_fws_get_tlv_len(fws, type))
break;

err = BRCMF_FWS_RET_OK_NOSCHEDULE;
switch (type) {
case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS:
case BRCMF_FWS_TYPE_COMP_TXSTATUS:
Expand All @@ -1407,21 +1414,22 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
break;
case BRCMF_FWS_TYPE_MAC_OPEN:
case BRCMF_FWS_TYPE_MAC_CLOSE:
brcmf_fws_macdesc_state_indicate(fws, type, data);
err = brcmf_fws_macdesc_state_indicate(fws, type, data);
break;
case BRCMF_FWS_TYPE_INTERFACE_OPEN:
case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
brcmf_fws_interface_state_indicate(fws, type, data);
err = brcmf_fws_interface_state_indicate(fws, type,
data);
break;
case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT:
case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET:
brcmf_fws_request_indicate(fws, type, data);
err = brcmf_fws_request_indicate(fws, type, data);
break;
case BRCMF_FWS_TYPE_TXSTATUS:
brcmf_fws_txstatus_indicate(fws, data);
break;
case BRCMF_FWS_TYPE_FIFO_CREDITBACK:
brcmf_fws_fifocreditback_indicate(fws, data);
err = brcmf_fws_fifocreditback_indicate(fws, data);
break;
case BRCMF_FWS_TYPE_RSSI:
brcmf_fws_rssi_indicate(fws, *data);
Expand All @@ -1435,14 +1443,18 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
fws->stats.tlv_invalid_type++;
break;
}

if (err == BRCMF_FWS_RET_OK_SCHEDULE)
status = BRCMF_FWS_RET_OK_SCHEDULE;
signal_data += len + 2;
data_len -= len + 2;
}

if (data_len != 0)
fws->stats.tlv_parse_failed++;

if (status == BRCMF_FWS_RET_OK_SCHEDULE)
brcmf_fws_schedule_deq(fws);

/* signalling processing result does
* not affect the actual ethernet packet.
*/
Expand Down

0 comments on commit a5e9d80

Please sign in to comment.