aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ti
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2014-07-10 20:01:26 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-07-15 15:59:51 -0400
commit50d26aa338fb290f0488e8f87c1c080d2de26e21 (patch)
treeea5d017e3b5e98d923396612fe6ba223218b342f /drivers/net/wireless/ti
parent72fcd3d16c16cd47a897cd72cd9a231aab01ac5b (diff)
wlcore: save seq num only between recoveries
We want seq num (freed_pkts) to be initialized on each new connection, but keep persistent between recoveries/suspends. Save the freed_pkts in the private block of the sta struct (we already do a similar thing for AP's stations). However, keep the old wlvif->total_freed_pkts in order to avoid too intrusive change. Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ti')
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c5
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c77
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h17
3 files changed, 68 insertions, 31 deletions
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index e269c0a57017..d298ead88c70 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -372,9 +372,8 @@ void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
372 wl1271_tx_reset_link_queues(wl, *hlid); 372 wl1271_tx_reset_link_queues(wl, *hlid);
373 wl->links[*hlid].wlvif = NULL; 373 wl->links[*hlid].wlvif = NULL;
374 374
375 if (wlvif->bss_type == BSS_TYPE_STA_BSS || 375 if (wlvif->bss_type == BSS_TYPE_AP_BSS &&
376 (wlvif->bss_type == BSS_TYPE_AP_BSS && 376 *hlid == wlvif->ap.bcast_hlid) {
377 *hlid == wlvif->ap.bcast_hlid)) {
378 /* 377 /*
379 * save the total freed packets in the wlvif, in case this is 378 * save the total freed packets in the wlvif, in case this is
380 * recovery or suspend 379 * recovery or suspend
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 48f83868f9cb..2996cefe4aed 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -898,6 +898,41 @@ out:
898 wlcore_set_partition(wl, &old_part); 898 wlcore_set_partition(wl, &old_part);
899} 899}
900 900
901static void wlcore_save_freed_pkts(struct wl1271 *wl, struct wl12xx_vif *wlvif,
902 u8 hlid, struct ieee80211_sta *sta)
903{
904 struct wl1271_station *wl_sta;
905
906 wl_sta = (void *)sta->drv_priv;
907 wl_sta->total_freed_pkts = wl->links[hlid].total_freed_pkts;
908
909 /*
910 * increment the initial seq number on recovery to account for
911 * transmitted packets that we haven't yet got in the FW status
912 */
913 if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
914 wl_sta->total_freed_pkts +=
915 WL1271_TX_SQN_POST_RECOVERY_PADDING;
916}
917
918static void wlcore_save_freed_pkts_addr(struct wl1271 *wl,
919 struct wl12xx_vif *wlvif,
920 u8 hlid, const u8 *addr)
921{
922 struct ieee80211_sta *sta;
923 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
924
925 if (WARN_ON(hlid == WL12XX_INVALID_LINK_ID ||
926 is_zero_ether_addr(addr)))
927 return;
928
929 rcu_read_lock();
930 sta = ieee80211_find_sta(vif, addr);
931 if (sta)
932 wlcore_save_freed_pkts(wl, wlvif, hlid, sta);
933 rcu_read_unlock();
934}
935
901static void wlcore_print_recovery(struct wl1271 *wl) 936static void wlcore_print_recovery(struct wl1271 *wl)
902{ 937{
903 u32 pc = 0; 938 u32 pc = 0;
@@ -961,6 +996,13 @@ static void wl1271_recovery_work(struct work_struct *work)
961 wlvif = list_first_entry(&wl->wlvif_list, 996 wlvif = list_first_entry(&wl->wlvif_list,
962 struct wl12xx_vif, list); 997 struct wl12xx_vif, list);
963 vif = wl12xx_wlvif_to_vif(wlvif); 998 vif = wl12xx_wlvif_to_vif(wlvif);
999
1000 if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
1001 test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
1002 wlcore_save_freed_pkts_addr(wl, wlvif, wlvif->sta.hlid,
1003 vif->bss_conf.bssid);
1004 }
1005
964 __wl1271_op_remove_interface(wl, vif, false); 1006 __wl1271_op_remove_interface(wl, vif, false);
965 } 1007 }
966 1008
@@ -4703,10 +4745,6 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
4703 4745
4704void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid) 4746void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
4705{ 4747{
4706 struct wl1271_station *wl_sta;
4707 struct ieee80211_sta *sta;
4708 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
4709
4710 if (!test_bit(hlid, wlvif->ap.sta_hlid_map)) 4748 if (!test_bit(hlid, wlvif->ap.sta_hlid_map))
4711 return; 4749 return;
4712 4750
@@ -4718,21 +4756,7 @@ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
4718 * save the last used PN in the private part of iee80211_sta, 4756 * save the last used PN in the private part of iee80211_sta,
4719 * in case of recovery/suspend 4757 * in case of recovery/suspend
4720 */ 4758 */
4721 rcu_read_lock(); 4759 wlcore_save_freed_pkts_addr(wl, wlvif, hlid, wl->links[hlid].addr);
4722 sta = ieee80211_find_sta(vif, wl->links[hlid].addr);
4723 if (sta) {
4724 wl_sta = (void *)sta->drv_priv;
4725 wl_sta->total_freed_pkts = wl->links[hlid].total_freed_pkts;
4726
4727 /*
4728 * increment the initial seq number on recovery to account for
4729 * transmitted packets that we haven't yet got in the FW status
4730 */
4731 if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
4732 wl_sta->total_freed_pkts +=
4733 WL1271_TX_SQN_POST_RECOVERY_PADDING;
4734 }
4735 rcu_read_unlock();
4736 4760
4737 wl12xx_free_link(wl, wlvif, &hlid); 4761 wl12xx_free_link(wl, wlvif, &hlid);
4738 wl->active_sta_count--; 4762 wl->active_sta_count--;
@@ -4915,6 +4939,21 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
4915 clear_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags); 4939 clear_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags);
4916 } 4940 }
4917 4941
4942 /* save seq number on disassoc (suspend) */
4943 if (is_sta &&
4944 old_state == IEEE80211_STA_ASSOC &&
4945 new_state == IEEE80211_STA_AUTH) {
4946 wlcore_save_freed_pkts(wl, wlvif, wlvif->sta.hlid, sta);
4947 wlvif->total_freed_pkts = 0;
4948 }
4949
4950 /* restore seq number on assoc (resume) */
4951 if (is_sta &&
4952 old_state == IEEE80211_STA_AUTH &&
4953 new_state == IEEE80211_STA_ASSOC) {
4954 wlvif->total_freed_pkts = wl_sta->total_freed_pkts;
4955 }
4956
4918 /* clear ROCs on failure or authorization */ 4957 /* clear ROCs on failure or authorization */
4919 if (is_sta && 4958 if (is_sta &&
4920 (new_state == IEEE80211_STA_AUTHORIZED || 4959 (new_state == IEEE80211_STA_AUTHORIZED ||
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index c2c34a84ff3d..986da43ecfdd 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -324,6 +324,7 @@ struct wl1271_station {
324 * total freed FW packets on the link to the STA - used for tracking the 324 * total freed FW packets on the link to the STA - used for tracking the
325 * AES/TKIP PN across recoveries. Re-initialized each time from the 325 * AES/TKIP PN across recoveries. Re-initialized each time from the
326 * wl1271_station structure. 326 * wl1271_station structure.
327 * Used in both AP and STA mode.
327 */ 328 */
328 u64 total_freed_pkts; 329 u64 total_freed_pkts;
329}; 330};
@@ -460,21 +461,19 @@ struct wl12xx_vif {
460 struct delayed_work pending_auth_complete_work; 461 struct delayed_work pending_auth_complete_work;
461 462
462 /* 463 /*
464 * total freed FW packets on the link.
465 * For STA this holds the PN of the link to the AP.
466 * For AP this holds the PN of the broadcast link.
467 */
468 u64 total_freed_pkts;
469
470 /*
463 * This struct must be last! 471 * This struct must be last!
464 * data that has to be saved acrossed reconfigs (e.g. recovery) 472 * data that has to be saved acrossed reconfigs (e.g. recovery)
465 * should be declared in this struct. 473 * should be declared in this struct.
466 */ 474 */
467 struct { 475 struct {
468 u8 persistent[0]; 476 u8 persistent[0];
469
470 /*
471 * total freed FW packets on the link - used for
472 * storing the AES/TKIP PN during recovery, as this
473 * structure is not zeroed out.
474 * For STA this holds the PN of the link to the AP.
475 * For AP this holds the PN of the broadcast link.
476 */
477 u64 total_freed_pkts;
478 }; 477 };
479}; 478};
480 479