diff options
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 36 |
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 | ||
931 | static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws, | 935 | static 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 | ||
991 | static void brcmf_fws_return_credits(struct brcmf_fws_info *fws, | 995 | static 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 | ||
1275 | static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) | 1278 | static 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 | */ |