diff options
Diffstat (limited to 'drivers/net/wireless/ti/wlcore/main.c')
-rw-r--r-- | drivers/net/wireless/ti/wlcore/main.c | 55 |
1 files changed, 28 insertions, 27 deletions
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index c3e2471..c1a60cd 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -418,13 +418,21 @@ static int wlcore_fw_status(struct wl1271 *wl, for_each_set_bit(i, wl->links_map, WL12XX_MAX_LINKS) { + u8 diff; lnk = &wl->links[i]; + /* prevent wrap-around in freed-packets counter */ - lnk->allocated_pkts -= - (status_2->counters.tx_lnk_free_pkts[i] - - lnk->prev_freed_pkts) & 0xff; + diff = (status_2->counters.tx_lnk_free_pkts[i] - + lnk->prev_freed_pkts) & 0xff; + + if (diff == 0) + continue; + lnk->allocated_pkts -= diff; lnk->prev_freed_pkts = status_2->counters.tx_lnk_free_pkts[i]; + + /* accumulate the prev_freed_pkts counter */ + lnk->total_freed_pkts += diff; } /* prevent wrap-around in total blocks counter */ @@ -923,18 +931,6 @@ static void wl1271_recovery_work(struct work_struct *work) goto out_unlock; } - /* - * Advance security sequence number to overcome potential progress - * in the firmware during recovery. This doens't hurt if the network is - * not encrypted. - */ - wl12xx_for_each_wlvif(wl, wlvif) { - if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) || - test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) - wlvif->tx_security_seq += - WL1271_TX_SQN_POST_RECOVERY_PADDING; - } - /* Prevent spurious TX during FW restart */ wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART); @@ -2864,10 +2860,6 @@ static int wlcore_unset_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif) wlvif->sta.klv_template_id, ACX_KEEP_ALIVE_TPL_INVALID); - /* reset TX security counters on a clean disconnect */ - wlvif->tx_security_last_seq_lsb = 0; - wlvif->tx_security_seq = 0; - return 0; } @@ -3266,6 +3258,7 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, u32 tx_seq_32 = 0; u16 tx_seq_16 = 0; u8 key_type; + u8 hlid; wl1271_debug(DEBUG_MAC80211, "mac80211 set key"); @@ -3275,6 +3268,22 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, key_conf->keylen, key_conf->flags); wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen); + if (wlvif->bss_type == BSS_TYPE_AP_BSS) + if (sta) { + struct wl1271_station *wl_sta = (void *)sta->drv_priv; + hlid = wl_sta->hlid; + } else { + hlid = wlvif->ap.bcast_hlid; + } + else + hlid = wlvif->sta.hlid; + + if (hlid != WL12XX_INVALID_LINK_ID) { + u64 tx_seq = wl->links[hlid].total_freed_pkts; + tx_seq_32 = WL1271_TX_SECURITY_HI32(tx_seq); + tx_seq_16 = WL1271_TX_SECURITY_LO16(tx_seq); + } + switch (key_conf->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: @@ -3284,22 +3293,14 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, break; case WLAN_CIPHER_SUITE_TKIP: key_type = KEY_TKIP; - key_conf->hw_key_idx = key_conf->keyidx; - tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq); - tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq); break; case WLAN_CIPHER_SUITE_CCMP: key_type = KEY_AES; - key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE; - tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq); - tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq); break; case WL1271_CIPHER_SUITE_GEM: key_type = KEY_GEM; - tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq); - tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq); break; default: wl1271_error("Unknown key algo 0x%x", key_conf->cipher); |