aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-04-17 15:25:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-22 15:20:22 -0400
commita5e9d805f907bb910fe3d10a721c24f6a4ee8237 (patch)
treeea03f819078ac5b340d56851237662797f2b77f0
parentb75c1a301b7d4e55f2354d8a7210a17d8402a218 (diff)
brcmfmac: schedule dequeue upon firmware-signal reception
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>
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 0d2ff60e925d..648f9bd89dac 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -147,6 +147,9 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
147#define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01 147#define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01
148#define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02 148#define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02
149 149
150#define BRCMF_FWS_RET_OK_NOSCHEDULE 0
151#define BRCMF_FWS_RET_OK_SCHEDULE 1
152
150/** 153/**
151 * enum brcmf_fws_skb_state - indicates processing state of skb. 154 * enum brcmf_fws_skb_state - indicates processing state of skb.
152 * 155 *
@@ -920,12 +923,13 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws,
920 entry->requested_credit = 0; 923 entry->requested_credit = 0;
921 if (type == BRCMF_FWS_TYPE_MAC_OPEN) { 924 if (type == BRCMF_FWS_TYPE_MAC_OPEN) {
922 entry->state = BRCMF_FWS_STATE_OPEN; 925 entry->state = BRCMF_FWS_STATE_OPEN;
926 return BRCMF_FWS_RET_OK_SCHEDULE;
923 } else { 927 } else {
924 entry->state = BRCMF_FWS_STATE_CLOSE; 928 entry->state = BRCMF_FWS_STATE_CLOSE;
925 for (i = BRCMF_FWS_FIFO_AC_BE; i < NL80211_NUM_ACS; i++) 929 for (i = BRCMF_FWS_FIFO_AC_BE; i < NL80211_NUM_ACS; i++)
926 brcmf_fws_tim_update(fws, entry, i); 930 brcmf_fws_tim_update(fws, entry, i);
927 } 931 }
928 return 0; 932 return BRCMF_FWS_RET_OK_NOSCHEDULE;
929} 933}
930 934
931static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws, 935static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws,
@@ -952,10 +956,10 @@ static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws,
952 switch (type) { 956 switch (type) {
953 case BRCMF_FWS_TYPE_INTERFACE_OPEN: 957 case BRCMF_FWS_TYPE_INTERFACE_OPEN:
954 entry->state = BRCMF_FWS_STATE_OPEN; 958 entry->state = BRCMF_FWS_STATE_OPEN;
955 return 0; 959 return BRCMF_FWS_RET_OK_SCHEDULE;
956 case BRCMF_FWS_TYPE_INTERFACE_CLOSE: 960 case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
957 entry->state = BRCMF_FWS_STATE_CLOSE; 961 entry->state = BRCMF_FWS_STATE_CLOSE;
958 return 0; 962 return BRCMF_FWS_RET_OK_NOSCHEDULE;
959 default: 963 default:
960 ret = -EINVAL; 964 ret = -EINVAL;
961 break; 965 break;
@@ -985,7 +989,7 @@ static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type,
985 entry->requested_packet = data[0]; 989 entry->requested_packet = data[0];
986 990
987 entry->ac_bitmap = data[2]; 991 entry->ac_bitmap = data[2];
988 return 0; 992 return BRCMF_FWS_RET_OK_SCHEDULE;
989} 993}
990 994
991static void brcmf_fws_return_credits(struct brcmf_fws_info *fws, 995static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
@@ -1259,7 +1263,7 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
1259 1263
1260 if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) { 1264 if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) {
1261 brcmf_dbg(INFO, "ignored\n"); 1265 brcmf_dbg(INFO, "ignored\n");
1262 return 0; 1266 return BRCMF_FWS_RET_OK_NOSCHEDULE;
1263 } 1267 }
1264 1268
1265 brcmf_dbg(TRACE, "enter: data %pM\n", data); 1269 brcmf_dbg(TRACE, "enter: data %pM\n", data);
@@ -1268,8 +1272,7 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
1268 1272
1269 brcmf_dbg(INFO, "map: credit %x delay %x\n", fws->fifo_credit_map, 1273 brcmf_dbg(INFO, "map: credit %x delay %x\n", fws->fifo_credit_map,
1270 fws->fifo_delay_map); 1274 fws->fifo_delay_map);
1271 brcmf_fws_schedule_deq(fws); 1275 return BRCMF_FWS_RET_OK_SCHEDULE;
1272 return 0;
1273} 1276}
1274 1277
1275static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) 1278static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
@@ -1353,6 +1356,8 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
1353 u8 type; 1356 u8 type;
1354 u8 len; 1357 u8 len;
1355 u8 *data; 1358 u8 *data;
1359 s32 status;
1360 s32 err;
1356 1361
1357 brcmf_dbg(TRACE, "enter: ifidx %d, skblen %u, sig %d\n", 1362 brcmf_dbg(TRACE, "enter: ifidx %d, skblen %u, sig %d\n",
1358 ifidx, skb->len, signal_len); 1363 ifidx, skb->len, signal_len);
@@ -1372,6 +1377,7 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
1372 data_len = signal_len; 1377 data_len = signal_len;
1373 signal_data = skb->data; 1378 signal_data = skb->data;
1374 1379
1380 status = BRCMF_FWS_RET_OK_NOSCHEDULE;
1375 while (data_len > 0) { 1381 while (data_len > 0) {
1376 /* extract tlv info */ 1382 /* extract tlv info */
1377 type = signal_data[0]; 1383 type = signal_data[0];
@@ -1397,6 +1403,7 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
1397 if (len != brcmf_fws_get_tlv_len(fws, type)) 1403 if (len != brcmf_fws_get_tlv_len(fws, type))
1398 break; 1404 break;
1399 1405
1406 err = BRCMF_FWS_RET_OK_NOSCHEDULE;
1400 switch (type) { 1407 switch (type) {
1401 case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS: 1408 case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS:
1402 case BRCMF_FWS_TYPE_COMP_TXSTATUS: 1409 case BRCMF_FWS_TYPE_COMP_TXSTATUS:
@@ -1407,21 +1414,22 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
1407 break; 1414 break;
1408 case BRCMF_FWS_TYPE_MAC_OPEN: 1415 case BRCMF_FWS_TYPE_MAC_OPEN:
1409 case BRCMF_FWS_TYPE_MAC_CLOSE: 1416 case BRCMF_FWS_TYPE_MAC_CLOSE:
1410 brcmf_fws_macdesc_state_indicate(fws, type, data); 1417 err = brcmf_fws_macdesc_state_indicate(fws, type, data);
1411 break; 1418 break;
1412 case BRCMF_FWS_TYPE_INTERFACE_OPEN: 1419 case BRCMF_FWS_TYPE_INTERFACE_OPEN:
1413 case BRCMF_FWS_TYPE_INTERFACE_CLOSE: 1420 case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
1414 brcmf_fws_interface_state_indicate(fws, type, data); 1421 err = brcmf_fws_interface_state_indicate(fws, type,
1422 data);
1415 break; 1423 break;
1416 case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT: 1424 case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT:
1417 case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET: 1425 case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET:
1418 brcmf_fws_request_indicate(fws, type, data); 1426 err = brcmf_fws_request_indicate(fws, type, data);
1419 break; 1427 break;
1420 case BRCMF_FWS_TYPE_TXSTATUS: 1428 case BRCMF_FWS_TYPE_TXSTATUS:
1421 brcmf_fws_txstatus_indicate(fws, data); 1429 brcmf_fws_txstatus_indicate(fws, data);
1422 break; 1430 break;
1423 case BRCMF_FWS_TYPE_FIFO_CREDITBACK: 1431 case BRCMF_FWS_TYPE_FIFO_CREDITBACK:
1424 brcmf_fws_fifocreditback_indicate(fws, data); 1432 err = brcmf_fws_fifocreditback_indicate(fws, data);
1425 break; 1433 break;
1426 case BRCMF_FWS_TYPE_RSSI: 1434 case BRCMF_FWS_TYPE_RSSI:
1427 brcmf_fws_rssi_indicate(fws, *data); 1435 brcmf_fws_rssi_indicate(fws, *data);
@@ -1435,7 +1443,8 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
1435 fws->stats.tlv_invalid_type++; 1443 fws->stats.tlv_invalid_type++;
1436 break; 1444 break;
1437 } 1445 }
1438 1446 if (err == BRCMF_FWS_RET_OK_SCHEDULE)
1447 status = BRCMF_FWS_RET_OK_SCHEDULE;
1439 signal_data += len + 2; 1448 signal_data += len + 2;
1440 data_len -= len + 2; 1449 data_len -= len + 2;
1441 } 1450 }
@@ -1443,6 +1452,9 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
1443 if (data_len != 0) 1452 if (data_len != 0)
1444 fws->stats.tlv_parse_failed++; 1453 fws->stats.tlv_parse_failed++;
1445 1454
1455 if (status == BRCMF_FWS_RET_OK_SCHEDULE)
1456 brcmf_fws_schedule_deq(fws);
1457
1446 /* signalling processing result does 1458 /* signalling processing result does
1447 * not affect the actual ethernet packet. 1459 * not affect the actual ethernet packet.
1448 */ 1460 */