diff options
author | Arend van Spriel <arend@broadcom.com> | 2013-04-05 04:57:40 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-04-08 15:28:41 -0400 |
commit | 33753d47d390624f09ee57dbb2bc611b15a10e8f (patch) | |
tree | 3b9c025274b278d2a4827304dcddb654a3fb43cb /drivers/net/wireless | |
parent | a2ffc5668e2742db7bae48ad6098e45f8d3ea19e (diff) |
brcmfmac: handle firmware signalling destination entry state
Firmware can signal whether the host driver may sent packets for
a specific destination or interface. This can happen when a
destination is sleeping or when going off-channel.
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-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')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 80 |
3 files changed, 79 insertions, 7 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c index bd16f0b17aab..202869cd0932 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c | |||
@@ -143,6 +143,8 @@ ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data, | |||
143 | "tlv_parse_failed: %u\n" | 143 | "tlv_parse_failed: %u\n" |
144 | "tlv_invalid_type: %u\n" | 144 | "tlv_invalid_type: %u\n" |
145 | "mac_update_fails: %u\n" | 145 | "mac_update_fails: %u\n" |
146 | "ps_update_fails: %u\n" | ||
147 | "if_update_fails: %u\n" | ||
146 | "pkt2bus: %u\n" | 148 | "pkt2bus: %u\n" |
147 | "generic_error: %u\n" | 149 | "generic_error: %u\n" |
148 | "rollback_success: %u\n" | 150 | "rollback_success: %u\n" |
@@ -161,6 +163,8 @@ ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data, | |||
161 | fwstats->tlv_parse_failed, | 163 | fwstats->tlv_parse_failed, |
162 | fwstats->tlv_invalid_type, | 164 | fwstats->tlv_invalid_type, |
163 | fwstats->mac_update_failed, | 165 | fwstats->mac_update_failed, |
166 | fwstats->mac_ps_update_failed, | ||
167 | fwstats->if_update_failed, | ||
164 | fwstats->pkt2bus, | 168 | fwstats->pkt2bus, |
165 | fwstats->generic_error, | 169 | fwstats->generic_error, |
166 | fwstats->rollback_success, | 170 | fwstats->rollback_success, |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index a6b16a1e72fb..e1058892dccc 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | |||
@@ -144,6 +144,8 @@ struct brcmf_fws_stats { | |||
144 | u32 fifo_credits_back[6]; | 144 | u32 fifo_credits_back[6]; |
145 | u32 generic_error; | 145 | u32 generic_error; |
146 | u32 mac_update_failed; | 146 | u32 mac_update_failed; |
147 | u32 mac_ps_update_failed; | ||
148 | u32 if_update_failed; | ||
147 | u32 rollback_success; | 149 | u32 rollback_success; |
148 | u32 rollback_failed; | 150 | u32 rollback_failed; |
149 | u32 delayq_full_error; | 151 | u32 delayq_full_error; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index 451cfc1b2c47..57cbfb661d58 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | |||
@@ -896,6 +896,69 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data) | |||
896 | return 0; | 896 | return 0; |
897 | } | 897 | } |
898 | 898 | ||
899 | static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws, | ||
900 | u8 type, u8 *data) | ||
901 | { | ||
902 | struct brcmf_fws_mac_descriptor *entry; | ||
903 | u8 mac_handle; | ||
904 | int i; | ||
905 | |||
906 | mac_handle = data[0]; | ||
907 | entry = &fws->desc.nodes[mac_handle & 0x1F]; | ||
908 | if (!entry->occupied) { | ||
909 | fws->stats.mac_ps_update_failed++; | ||
910 | return -ESRCH; | ||
911 | } | ||
912 | |||
913 | /* a state update should wipe old credits? */ | ||
914 | entry->requested_credit = 0; | ||
915 | if (type == BRCMF_FWS_TYPE_MAC_OPEN) { | ||
916 | entry->state = BRCMF_FWS_STATE_OPEN; | ||
917 | } else { | ||
918 | entry->state = BRCMF_FWS_STATE_CLOSE; | ||
919 | for (i = BRCMF_FWS_FIFO_AC_BE; i < NL80211_NUM_ACS; i++) | ||
920 | brcmf_fws_tim_update(fws, entry, i); | ||
921 | } | ||
922 | return 0; | ||
923 | } | ||
924 | |||
925 | static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws, | ||
926 | u8 type, u8 *data) | ||
927 | { | ||
928 | struct brcmf_fws_mac_descriptor *entry; | ||
929 | u8 ifidx; | ||
930 | int ret; | ||
931 | |||
932 | ifidx = data[0]; | ||
933 | |||
934 | brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx); | ||
935 | if (ifidx >= BRCMF_MAX_IFS) { | ||
936 | ret = -ERANGE; | ||
937 | goto fail; | ||
938 | } | ||
939 | |||
940 | entry = &fws->desc.iface[ifidx]; | ||
941 | if (!entry->occupied) { | ||
942 | ret = -ESRCH; | ||
943 | goto fail; | ||
944 | } | ||
945 | |||
946 | switch (type) { | ||
947 | case BRCMF_FWS_TYPE_INTERFACE_OPEN: | ||
948 | entry->state = BRCMF_FWS_STATE_OPEN; | ||
949 | return 0; | ||
950 | case BRCMF_FWS_TYPE_INTERFACE_CLOSE: | ||
951 | entry->state = BRCMF_FWS_STATE_CLOSE; | ||
952 | return 0; | ||
953 | default: | ||
954 | ret = -EINVAL; | ||
955 | break; | ||
956 | } | ||
957 | fail: | ||
958 | fws->stats.if_update_failed++; | ||
959 | return ret; | ||
960 | } | ||
961 | |||
899 | static void brcmf_fws_return_credits(struct brcmf_fws_info *fws, | 962 | static void brcmf_fws_return_credits(struct brcmf_fws_info *fws, |
900 | u8 fifo, u8 credits) | 963 | u8 fifo, u8 credits) |
901 | { | 964 | { |
@@ -1111,8 +1174,6 @@ brcmf_fws_txstatus_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot, | |||
1111 | struct sk_buff *skb; | 1174 | struct sk_buff *skb; |
1112 | struct brcmf_fws_mac_descriptor *entry = NULL; | 1175 | struct brcmf_fws_mac_descriptor *entry = NULL; |
1113 | 1176 | ||
1114 | fws->stats.txs_indicate++; | ||
1115 | |||
1116 | brcmf_dbg(TRACE, "status: flags=0x%X, hslot=%d\n", | 1177 | brcmf_dbg(TRACE, "status: flags=0x%X, hslot=%d\n", |
1117 | flags, hslot); | 1178 | flags, hslot); |
1118 | 1179 | ||
@@ -1305,11 +1366,7 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, | |||
1305 | break; | 1366 | break; |
1306 | 1367 | ||
1307 | switch (type) { | 1368 | switch (type) { |
1308 | case BRCMF_FWS_TYPE_MAC_OPEN: | ||
1309 | case BRCMF_FWS_TYPE_MAC_CLOSE: | ||
1310 | case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT: | 1369 | case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT: |
1311 | case BRCMF_FWS_TYPE_INTERFACE_OPEN: | ||
1312 | case BRCMF_FWS_TYPE_INTERFACE_CLOSE: | ||
1313 | case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET: | 1370 | case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET: |
1314 | case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS: | 1371 | case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS: |
1315 | case BRCMF_FWS_TYPE_COMP_TXSTATUS: | 1372 | case BRCMF_FWS_TYPE_COMP_TXSTATUS: |
@@ -1318,6 +1375,14 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, | |||
1318 | case BRCMF_FWS_TYPE_MACDESC_DEL: | 1375 | case BRCMF_FWS_TYPE_MACDESC_DEL: |
1319 | brcmf_fws_macdesc_indicate(fws, type, data); | 1376 | brcmf_fws_macdesc_indicate(fws, type, data); |
1320 | break; | 1377 | break; |
1378 | case BRCMF_FWS_TYPE_MAC_OPEN: | ||
1379 | case BRCMF_FWS_TYPE_MAC_CLOSE: | ||
1380 | brcmf_fws_macdesc_state_indicate(fws, type, data); | ||
1381 | break; | ||
1382 | case BRCMF_FWS_TYPE_INTERFACE_OPEN: | ||
1383 | case BRCMF_FWS_TYPE_INTERFACE_CLOSE: | ||
1384 | brcmf_fws_interface_state_indicate(fws, type, data); | ||
1385 | break; | ||
1321 | case BRCMF_FWS_TYPE_TXSTATUS: | 1386 | case BRCMF_FWS_TYPE_TXSTATUS: |
1322 | brcmf_fws_txstatus_indicate(fws, data); | 1387 | brcmf_fws_txstatus_indicate(fws, data); |
1323 | break; | 1388 | break; |
@@ -1779,7 +1844,8 @@ int brcmf_fws_init(struct brcmf_pub *drvr) | |||
1779 | /* enable firmware signalling if fcmode active */ | 1844 | /* enable firmware signalling if fcmode active */ |
1780 | if (drvr->fws->fcmode != BRCMF_FWS_FCMODE_NONE) | 1845 | if (drvr->fws->fcmode != BRCMF_FWS_FCMODE_NONE) |
1781 | tlv |= BRCMF_FWS_FLAGS_XONXOFF_SIGNALS | | 1846 | tlv |= BRCMF_FWS_FLAGS_XONXOFF_SIGNALS | |
1782 | BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS; | 1847 | BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS | |
1848 | BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE; | ||
1783 | 1849 | ||
1784 | rc = brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv); | 1850 | rc = brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv); |
1785 | if (rc < 0) { | 1851 | if (rc < 0) { |