diff options
author | Eliad Peller <eliad@wizery.com> | 2014-07-10 20:01:26 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-07-15 15:59:51 -0400 |
commit | 50d26aa338fb290f0488e8f87c1c080d2de26e21 (patch) | |
tree | ea5d017e3b5e98d923396612fe6ba223218b342f /drivers/net/wireless/ti | |
parent | 72fcd3d16c16cd47a897cd72cd9a231aab01ac5b (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.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/main.c | 77 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/wlcore_i.h | 17 |
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 | ||
901 | static 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 | |||
918 | static 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 | |||
901 | static void wlcore_print_recovery(struct wl1271 *wl) | 936 | static 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 | ||
4704 | void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid) | 4746 | void 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 | ||