Skip to content

Commit 1ad4f63

Browse files
elpjmberg-intel
authored andcommitted
iwlwifi: mvm: move TX PN assignment for TKIP to the driver
If protocol offloading is configured, the fw might generate some frames (e.g. arp response) on its own during d3/d0i3. On d3/d0i3 exit the driver queries the updated PN (if relevant), and updates its keys (for the d0i3 case, this is done by iwl_mvm_d0i3_exit_work(), which is scheduled on d0i3 exit) While in d0i3, iwlmvm defers tx frames until d0i3 exit, and then continues their processing. This is problematic with TKIP, since the frame's PN has already been set at this stage (in contrast to CCMP, where the PN is being set only later on), so both the frame's PN and the upcoming PN update (from d0i3 exit work) might be wrong. Fix it by moving the TX PN assignment (for TKIP) to the driver, similarly to CCMP. Signed-off-by: Eliad Peller <[email protected]> Signed-off-by: Emmanuel Grumbach <[email protected]> Signed-off-by: Johannes Berg <[email protected]>
1 parent f8079d4 commit 1ad4f63

File tree

3 files changed

+13
-6
lines changed

3 files changed

+13
-6
lines changed

drivers/net/wireless/intel/iwlwifi/mvm/d3.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,16 +249,19 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
249249
return;
250250
case WLAN_CIPHER_SUITE_TKIP:
251251
if (sta) {
252+
u64 pn64;
253+
252254
tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc;
253255
tkip_tx_sc = &data->rsc_tsc->all_tsc_rsc.tkip.tsc;
254256

255257
rx_p1ks = data->tkip->rx_uni;
256258

257-
ieee80211_get_key_tx_seq(key, &seq);
258-
tkip_tx_sc->iv16 = cpu_to_le16(seq.tkip.iv16);
259-
tkip_tx_sc->iv32 = cpu_to_le32(seq.tkip.iv32);
259+
pn64 = atomic64_read(&key->tx_pn);
260+
tkip_tx_sc->iv16 = cpu_to_le16(TKIP_PN_TO_IV16(pn64));
261+
tkip_tx_sc->iv32 = cpu_to_le32(TKIP_PN_TO_IV32(pn64));
260262

261-
ieee80211_get_tkip_p1k_iv(key, seq.tkip.iv32, p1k);
263+
ieee80211_get_tkip_p1k_iv(key, TKIP_PN_TO_IV32(pn64),
264+
p1k);
262265
iwl_mvm_convert_p1k(p1k, data->tkip->tx.p1k);
263266

264267
memcpy(data->tkip->mic_keys.tx,
@@ -1601,7 +1604,9 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
16011604
case WLAN_CIPHER_SUITE_TKIP:
16021605
iwl_mvm_tkip_sc_to_seq(&sc->tkip.tsc, &seq);
16031606
iwl_mvm_set_tkip_rx_seq(sc->tkip.unicast_rsc, key);
1604-
ieee80211_set_key_tx_seq(key, &seq);
1607+
atomic64_set(&key->tx_pn,
1608+
(u64)seq.tkip.iv16 |
1609+
((u64)seq.tkip.iv32 << 16));
16051610
break;
16061611
}
16071612

drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2585,7 +2585,7 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
25852585
switch (key->cipher) {
25862586
case WLAN_CIPHER_SUITE_TKIP:
25872587
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
2588-
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
2588+
key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
25892589
break;
25902590
case WLAN_CIPHER_SUITE_CCMP:
25912591
key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;

drivers/net/wireless/intel/iwlwifi/mvm/tx.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm,
299299

300300
case WLAN_CIPHER_SUITE_TKIP:
301301
tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
302+
pn = atomic64_inc_return(&keyconf->tx_pn);
303+
ieee80211_tkip_add_iv(crypto_hdr, keyconf, pn);
302304
ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
303305
break;
304306

0 commit comments

Comments
 (0)