diff options
author | Arik Nemtsov <arik@wizery.com> | 2013-03-12 11:19:44 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2013-03-25 06:33:12 -0400 |
commit | 0e752df6fda25993acc30e1162808fbb2543be03 (patch) | |
tree | de0faa9284fada9d779975ab24c511400caf0de8 | |
parent | 5a99610c99625ae86d76014da25659dff72e8792 (diff) |
wlcore: AP-mode - recover security seq num for stations
Save the sequence number of the broadcast AP link in the wlvif. For each
connected station, save the sequence number in the drv_priv part of
ieee80211_sta. Use the saved numbers on recovery/resume, with the
obligatory increment on recovery.
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
-rw-r--r-- | drivers/net/wireless/ti/wlcore/cmd.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/main.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/wlcore_i.h | 9 |
3 files changed, 44 insertions, 1 deletions
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 56d248a0acc1..c9e060795d13 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c | |||
@@ -366,7 +366,9 @@ void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) | |||
366 | wl1271_tx_reset_link_queues(wl, *hlid); | 366 | wl1271_tx_reset_link_queues(wl, *hlid); |
367 | wl->links[*hlid].wlvif = NULL; | 367 | wl->links[*hlid].wlvif = NULL; |
368 | 368 | ||
369 | if (wlvif->bss_type != BSS_TYPE_AP_BSS) { | 369 | if (wlvif->bss_type == BSS_TYPE_STA_BSS || |
370 | (wlvif->bss_type == BSS_TYPE_AP_BSS && | ||
371 | *hlid == wlvif->ap.bcast_hlid)) { | ||
370 | /* | 372 | /* |
371 | * save the total freed packets in the wlvif, in case this is | 373 | * save the total freed packets in the wlvif, in case this is |
372 | * recovery or suspend | 374 | * recovery or suspend |
@@ -635,6 +637,10 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
635 | if (ret < 0) | 637 | if (ret < 0) |
636 | goto out_free_global; | 638 | goto out_free_global; |
637 | 639 | ||
640 | /* use the previous security seq, if this is a recovery/resume */ | ||
641 | wl->links[wlvif->ap.bcast_hlid].total_freed_pkts = | ||
642 | wlvif->total_freed_pkts; | ||
643 | |||
638 | cmd->role_id = wlvif->role_id; | 644 | cmd->role_id = wlvif->role_id; |
639 | cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period); | 645 | cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period); |
640 | cmd->ap.bss_index = WL1271_AP_BSS_INDEX; | 646 | cmd->ap.bss_index = WL1271_AP_BSS_INDEX; |
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 4da558460449..43865d1348ec 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
@@ -4505,6 +4505,9 @@ static int wl1271_allocate_sta(struct wl1271 *wl, | |||
4505 | return -EBUSY; | 4505 | return -EBUSY; |
4506 | } | 4506 | } |
4507 | 4507 | ||
4508 | /* use the previous security seq, if this is a recovery/resume */ | ||
4509 | wl->links[wl_sta->hlid].total_freed_pkts = wl_sta->total_freed_pkts; | ||
4510 | |||
4508 | set_bit(wl_sta->hlid, wlvif->ap.sta_hlid_map); | 4511 | set_bit(wl_sta->hlid, wlvif->ap.sta_hlid_map); |
4509 | memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN); | 4512 | memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN); |
4510 | wl->active_sta_count++; | 4513 | wl->active_sta_count++; |
@@ -4513,12 +4516,37 @@ static int wl1271_allocate_sta(struct wl1271 *wl, | |||
4513 | 4516 | ||
4514 | void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid) | 4517 | void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid) |
4515 | { | 4518 | { |
4519 | struct wl1271_station *wl_sta; | ||
4520 | struct ieee80211_sta *sta; | ||
4521 | struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); | ||
4522 | |||
4516 | if (!test_bit(hlid, wlvif->ap.sta_hlid_map)) | 4523 | if (!test_bit(hlid, wlvif->ap.sta_hlid_map)) |
4517 | return; | 4524 | return; |
4518 | 4525 | ||
4519 | clear_bit(hlid, wlvif->ap.sta_hlid_map); | 4526 | clear_bit(hlid, wlvif->ap.sta_hlid_map); |
4520 | __clear_bit(hlid, &wl->ap_ps_map); | 4527 | __clear_bit(hlid, &wl->ap_ps_map); |
4521 | __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); | 4528 | __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); |
4529 | |||
4530 | /* | ||
4531 | * save the last used PN in the private part of iee80211_sta, | ||
4532 | * in case of recovery/suspend | ||
4533 | */ | ||
4534 | rcu_read_lock(); | ||
4535 | sta = ieee80211_find_sta(vif, wl->links[hlid].addr); | ||
4536 | if (sta) { | ||
4537 | wl_sta = (void *)sta->drv_priv; | ||
4538 | wl_sta->total_freed_pkts = wl->links[hlid].total_freed_pkts; | ||
4539 | |||
4540 | /* | ||
4541 | * increment the initial seq number on recovery to account for | ||
4542 | * transmitted packets that we haven't yet got in the FW status | ||
4543 | */ | ||
4544 | if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) | ||
4545 | wl_sta->total_freed_pkts += | ||
4546 | WL1271_TX_SQN_POST_RECOVERY_PADDING; | ||
4547 | } | ||
4548 | rcu_read_unlock(); | ||
4549 | |||
4522 | wl12xx_free_link(wl, wlvif, &hlid); | 4550 | wl12xx_free_link(wl, wlvif, &hlid); |
4523 | wl->active_sta_count--; | 4551 | wl->active_sta_count--; |
4524 | 4552 | ||
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index 47d2f6000a42..7b55ef9c4288 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h | |||
@@ -325,6 +325,13 @@ struct wl12xx_rx_filter { | |||
325 | struct wl1271_station { | 325 | struct wl1271_station { |
326 | u8 hlid; | 326 | u8 hlid; |
327 | bool in_connection; | 327 | bool in_connection; |
328 | |||
329 | /* | ||
330 | * total freed FW packets on the link to the STA - used for tracking the | ||
331 | * AES/TKIP PN across recoveries. Re-initialized each time from the | ||
332 | * wl1271_station structure. | ||
333 | */ | ||
334 | u64 total_freed_pkts; | ||
328 | }; | 335 | }; |
329 | 336 | ||
330 | struct wl12xx_vif { | 337 | struct wl12xx_vif { |
@@ -461,6 +468,8 @@ struct wl12xx_vif { | |||
461 | * total freed FW packets on the link - used for | 468 | * total freed FW packets on the link - used for |
462 | * storing the AES/TKIP PN during recovery, as this | 469 | * storing the AES/TKIP PN during recovery, as this |
463 | * structure is not zeroed out. | 470 | * structure is not zeroed out. |
471 | * For STA this holds the PN of the link to the AP. | ||
472 | * For AP this holds the PN of the broadcast link. | ||
464 | */ | 473 | */ |
465 | u64 total_freed_pkts; | 474 | u64 total_freed_pkts; |
466 | }; | 475 | }; |