aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-04-05 04:57:40 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-08 15:28:41 -0400
commit33753d47d390624f09ee57dbb2bc611b15a10e8f (patch)
tree3b9c025274b278d2a4827304dcddb654a3fb43cb /drivers/net/wireless
parenta2ffc5668e2742db7bae48ad6098e45f8d3ea19e (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.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c80
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
899static 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
925static 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 }
957fail:
958 fws->stats.if_update_failed++;
959 return ret;
960}
961
899static void brcmf_fws_return_credits(struct brcmf_fws_info *fws, 962static 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) {