1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* 3 * Copyright (C) 2024-2026 Intel Corporation 4 */ 5 #include "mld.h" 6 7 #include "d3.h" 8 #include "power.h" 9 #include "hcmd.h" 10 #include "iface.h" 11 #include "mcc.h" 12 #include "sta.h" 13 #include "mlo.h" 14 #include "key.h" 15 16 #include "fw/api/d3.h" 17 #include "fw/api/offload.h" 18 #include "fw/api/sta.h" 19 #include "fw/dbg.h" 20 21 #include <net/ipv6.h> 22 #include <net/addrconf.h> 23 #include <linux/bitops.h> 24 25 /** 26 * enum iwl_mld_d3_notif - d3 notifications 27 * @IWL_D3_NOTIF_WOWLAN_INFO: WOWLAN_INFO_NOTIF is expected/was received 28 * @IWL_D3_NOTIF_WOWLAN_WAKE_PKT: WOWLAN_WAKE_PKT_NOTIF is expected/was received 29 * @IWL_D3_NOTIF_PROT_OFFLOAD: PROT_OFFLOAD_NOTIF is expected/was received 30 * @IWL_D3_ND_MATCH_INFO: OFFLOAD_MATCH_INFO_NOTIF is expected/was received 31 * @IWL_D3_NOTIF_D3_END_NOTIF: D3_END_NOTIF is expected/was received 32 */ 33 enum iwl_mld_d3_notif { 34 IWL_D3_NOTIF_WOWLAN_INFO = BIT(0), 35 IWL_D3_NOTIF_WOWLAN_WAKE_PKT = BIT(1), 36 IWL_D3_NOTIF_PROT_OFFLOAD = BIT(2), 37 IWL_D3_ND_MATCH_INFO = BIT(3), 38 IWL_D3_NOTIF_D3_END_NOTIF = BIT(4) 39 }; 40 41 struct iwl_mld_resume_key_iter_data { 42 struct iwl_mld *mld; 43 struct iwl_mld_wowlan_status *wowlan_status; 44 }; 45 46 struct iwl_mld_rsc_resume_iter_data { 47 struct iwl_mld *mld; 48 const struct iwl_wowlan_all_rsc_tsc_v5 *notif; 49 int queue; 50 }; 51 52 struct iwl_mld_suspend_key_iter_data { 53 struct iwl_wowlan_rsc_tsc_params_cmd *rsc; 54 bool have_rsc; 55 int gtks; 56 int found_gtk_idx[4]; 57 __le32 gtk_cipher; 58 __le32 igtk_cipher; 59 __le32 bigtk_cipher; 60 }; 61 62 struct iwl_mld_mcast_key_data { 63 u8 key[WOWLAN_KEY_MAX_SIZE]; 64 u8 len; 65 u8 flags; 66 u8 id; 67 union { 68 struct { 69 struct ieee80211_key_seq aes_seq[IWL_MAX_TID_COUNT]; 70 struct ieee80211_key_seq tkip_seq[IWL_MAX_TID_COUNT]; 71 } gtk; 72 struct { 73 struct ieee80211_key_seq cmac_gmac_seq; 74 } igtk_bigtk; 75 }; 76 77 }; 78 79 struct iwl_mld_wowlan_mlo_key { 80 u8 key[WOWLAN_KEY_MAX_SIZE]; 81 u8 idx, type, link_id; 82 u8 pn[6]; 83 }; 84 85 /** 86 * struct iwl_mld_wowlan_status - contains wowlan status data from 87 * all wowlan notifications 88 * @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason 89 * @replay_ctr: GTK rekey replay counter 90 * @pattern_number: number of the matched patterns on packets 91 * @last_qos_seq: QoS sequence counter of offloaded tid 92 * @num_of_gtk_rekeys: number of GTK rekeys during D3 93 * @tid_offloaded_tx: tid used by the firmware to transmit data packets 94 * while in wowlan 95 * @wake_packet: wakeup packet received 96 * @wake_packet_length: wake packet length 97 * @wake_packet_bufsize: wake packet bufsize 98 * @gtk: data of the last two used gtk's by the FW upon resume 99 * @igtk: data of the last used igtk by the FW upon resume 100 * @bigtk: data of the last two used gtk's by the FW upon resume 101 * @ptk: last seq numbers per tid passed by the FW, 102 * holds both in tkip and aes formats 103 * @num_mlo_keys: number of &struct iwl_mld_wowlan_mlo_key structs 104 * @mlo_keys: array of MLO keys 105 */ 106 struct iwl_mld_wowlan_status { 107 u32 wakeup_reasons; 108 u64 replay_ctr; 109 u16 pattern_number; 110 u16 last_qos_seq; 111 u32 num_of_gtk_rekeys; 112 u8 tid_offloaded_tx; 113 u8 *wake_packet; 114 u32 wake_packet_length; 115 u32 wake_packet_bufsize; 116 struct iwl_mld_mcast_key_data gtk[WOWLAN_GTK_KEYS_NUM]; 117 struct iwl_mld_mcast_key_data igtk; 118 struct iwl_mld_mcast_key_data bigtk[WOWLAN_BIGTK_KEYS_NUM]; 119 struct { 120 struct ieee80211_key_seq aes_seq[IWL_MAX_TID_COUNT]; 121 struct ieee80211_key_seq tkip_seq[IWL_MAX_TID_COUNT]; 122 123 } ptk; 124 125 int num_mlo_keys; 126 struct iwl_mld_wowlan_mlo_key mlo_keys[WOWLAN_MAX_MLO_KEYS]; 127 }; 128 129 #define NETDETECT_QUERY_BUF_LEN \ 130 (sizeof(struct iwl_scan_offload_profile_match) * \ 131 IWL_SCAN_MAX_PROFILES_V2) 132 133 /** 134 * struct iwl_mld_netdetect_res - contains netdetect results from 135 * match_info_notif 136 * @matched_profiles: bitmap of matched profiles, referencing the 137 * matches passed in the scan offload request 138 * @matches: array of match information, one for each match 139 */ 140 struct iwl_mld_netdetect_res { 141 u32 matched_profiles; 142 u8 matches[NETDETECT_QUERY_BUF_LEN]; 143 }; 144 145 /** 146 * struct iwl_mld_resume_data - d3 resume flow data 147 * @notifs_expected: bitmap of expected notifications from fw, 148 * see &enum iwl_mld_d3_notif 149 * @notifs_received: bitmap of received notifications from fw, 150 * see &enum iwl_mld_d3_notif 151 * @d3_end_flags: bitmap of flags from d3_end_notif 152 * @notif_handling_err: error handling one of the resume notifications 153 * @wowlan_status: wowlan status data from all wowlan notifications 154 * @netdetect_res: contains netdetect results from match_info_notif 155 */ 156 struct iwl_mld_resume_data { 157 u32 notifs_expected; 158 u32 notifs_received; 159 u32 d3_end_flags; 160 bool notif_handling_err; 161 struct iwl_mld_wowlan_status *wowlan_status; 162 struct iwl_mld_netdetect_res *netdetect_res; 163 }; 164 165 #define IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT \ 166 (IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET | \ 167 IWL_WOWLAN_WAKEUP_BY_PATTERN | \ 168 IWL_WAKEUP_BY_PATTERN_IPV4_TCP_SYN |\ 169 IWL_WAKEUP_BY_PATTERN_IPV4_TCP_SYN_WILDCARD |\ 170 IWL_WAKEUP_BY_PATTERN_IPV6_TCP_SYN |\ 171 IWL_WAKEUP_BY_PATTERN_IPV6_TCP_SYN_WILDCARD) 172 173 #define IWL_WOWLAN_OFFLOAD_TID 0 174 175 void iwl_mld_set_rekey_data(struct ieee80211_hw *hw, 176 struct ieee80211_vif *vif, 177 struct cfg80211_gtk_rekey_data *data) 178 { 179 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 180 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 181 struct iwl_mld_wowlan_data *wowlan_data = &mld_vif->wowlan_data; 182 183 lockdep_assert_wiphy(mld->wiphy); 184 185 wowlan_data->rekey_data.kek_len = data->kek_len; 186 wowlan_data->rekey_data.kck_len = data->kck_len; 187 memcpy(wowlan_data->rekey_data.kek, data->kek, data->kek_len); 188 memcpy(wowlan_data->rekey_data.kck, data->kck, data->kck_len); 189 wowlan_data->rekey_data.akm = data->akm & 0xFF; 190 wowlan_data->rekey_data.replay_ctr = 191 cpu_to_le64(be64_to_cpup((const __be64 *)data->replay_ctr)); 192 wowlan_data->rekey_data.valid = true; 193 } 194 195 #if IS_ENABLED(CONFIG_IPV6) 196 void iwl_mld_ipv6_addr_change(struct ieee80211_hw *hw, 197 struct ieee80211_vif *vif, 198 struct inet6_dev *idev) 199 { 200 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 201 struct iwl_mld_wowlan_data *wowlan_data = &mld_vif->wowlan_data; 202 struct inet6_ifaddr *ifa; 203 int idx = 0; 204 205 memset(wowlan_data->tentative_addrs, 0, 206 sizeof(wowlan_data->tentative_addrs)); 207 208 read_lock_bh(&idev->lock); 209 list_for_each_entry(ifa, &idev->addr_list, if_list) { 210 wowlan_data->target_ipv6_addrs[idx] = ifa->addr; 211 if (ifa->flags & IFA_F_TENTATIVE) 212 __set_bit(idx, wowlan_data->tentative_addrs); 213 idx++; 214 if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX) 215 break; 216 } 217 read_unlock_bh(&idev->lock); 218 219 wowlan_data->num_target_ipv6_addrs = idx; 220 } 221 #endif 222 223 static int 224 iwl_mld_netdetect_config(struct iwl_mld *mld, 225 struct ieee80211_vif *vif, 226 const struct cfg80211_wowlan *wowlan) 227 { 228 int ret; 229 struct cfg80211_sched_scan_request *netdetect_cfg = 230 wowlan->nd_config; 231 struct ieee80211_scan_ies ies = {}; 232 233 ret = iwl_mld_scan_stop(mld, IWL_MLD_SCAN_SCHED, true); 234 if (ret) 235 return ret; 236 237 ret = iwl_mld_sched_scan_start(mld, vif, netdetect_cfg, &ies, 238 IWL_MLD_SCAN_NETDETECT); 239 return ret; 240 } 241 242 static void 243 iwl_mld_le64_to_tkip_seq(__le64 le_pn, struct ieee80211_key_seq *seq) 244 { 245 u64 pn = le64_to_cpu(le_pn); 246 247 seq->tkip.iv16 = (u16)pn; 248 seq->tkip.iv32 = (u32)(pn >> 16); 249 } 250 251 static void 252 iwl_mld_le64_to_aes_seq(__le64 le_pn, struct ieee80211_key_seq *seq) 253 { 254 u64 pn = le64_to_cpu(le_pn); 255 256 seq->ccmp.pn[0] = pn >> 40; 257 seq->ccmp.pn[1] = pn >> 32; 258 seq->ccmp.pn[2] = pn >> 24; 259 seq->ccmp.pn[3] = pn >> 16; 260 seq->ccmp.pn[4] = pn >> 8; 261 seq->ccmp.pn[5] = pn; 262 } 263 264 static void 265 iwl_mld_convert_gtk_resume_seq(struct iwl_mld_mcast_key_data *gtk_data, 266 const struct iwl_wowlan_all_rsc_tsc_v5 *sc, 267 int rsc_idx) 268 { 269 struct ieee80211_key_seq *aes_seq = gtk_data->gtk.aes_seq; 270 struct ieee80211_key_seq *tkip_seq = gtk_data->gtk.tkip_seq; 271 272 if (rsc_idx >= ARRAY_SIZE(sc->mcast_rsc)) 273 return; 274 275 /* We store both the TKIP and AES representations coming from the 276 * FW because we decode the data from there before we iterate 277 * the keys and know which type is used. 278 */ 279 for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { 280 iwl_mld_le64_to_tkip_seq(sc->mcast_rsc[rsc_idx][tid], 281 &tkip_seq[tid]); 282 iwl_mld_le64_to_aes_seq(sc->mcast_rsc[rsc_idx][tid], 283 &aes_seq[tid]); 284 } 285 } 286 287 static void 288 iwl_mld_convert_gtk_resume_data(struct iwl_mld *mld, 289 struct iwl_mld_wowlan_status *wowlan_status, 290 const struct iwl_wowlan_gtk_status *gtk_data, 291 const struct iwl_wowlan_all_rsc_tsc_v5 *sc, 292 int rsc_notif_ver) 293 { 294 int status_idx = 0; 295 296 BUILD_BUG_ON(sizeof(wowlan_status->gtk[0].key) < 297 sizeof(gtk_data[0].key)); 298 BUILD_BUG_ON(ARRAY_SIZE(wowlan_status->gtk) < WOWLAN_GTK_KEYS_NUM); 299 300 for (int notif_idx = 0; notif_idx < ARRAY_SIZE(wowlan_status->gtk); 301 notif_idx++) { 302 int rsc_idx; 303 u8 key_status = gtk_data[notif_idx].key_status; 304 305 if (!key_status) 306 continue; 307 308 wowlan_status->gtk[status_idx].len = 309 gtk_data[notif_idx].key_len; 310 wowlan_status->gtk[status_idx].flags = 311 gtk_data[notif_idx].key_flags; 312 wowlan_status->gtk[status_idx].id = 313 wowlan_status->gtk[status_idx].flags & 314 IWL_WOWLAN_GTK_IDX_MASK; 315 /* If RSC_NOTIF is not supported */ 316 if (rsc_notif_ver == IWL_FW_CMD_VER_UNKNOWN) { 317 /* The rsc for both gtk keys are stored in 318 * gtk[0]->sc->mcast_rsc. The gtk ids can be any two 319 * numbers between 0 and 3, the id_map maps between the 320 * key id and the index in sc->mcast 321 */ 322 rsc_idx = 323 sc->mcast_key_id_map[wowlan_status->gtk[status_idx].id]; 324 iwl_mld_convert_gtk_resume_seq(&wowlan_status->gtk[status_idx], 325 sc, rsc_idx); 326 } 327 328 if (key_status == IWL_WOWLAN_STATUS_NEW_KEY) { 329 memcpy(wowlan_status->gtk[status_idx].key, 330 gtk_data[notif_idx].key, 331 sizeof(gtk_data[notif_idx].key)); 332 333 /* if it's as long as the TKIP encryption key, 334 * copy MIC key 335 */ 336 if (wowlan_status->gtk[status_idx].len == 337 NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY) 338 memcpy(wowlan_status->gtk[status_idx].key + 339 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, 340 gtk_data[notif_idx].tkip_mic_key, 341 sizeof(gtk_data[notif_idx].tkip_mic_key)); 342 } else { 343 /* If the key status is WOWLAN_STATUS_OLD_KEY, it 344 * indicates that no key material is present, Set the 345 * key length to 0 as an indication 346 */ 347 wowlan_status->gtk[status_idx].len = 0; 348 } 349 status_idx++; 350 } 351 } 352 353 static void 354 iwl_mld_convert_ptk_resume_seq(struct iwl_mld *mld, 355 struct iwl_mld_wowlan_status *wowlan_status, 356 const struct iwl_wowlan_all_rsc_tsc_v5 *sc) 357 { 358 struct ieee80211_key_seq *aes_seq = wowlan_status->ptk.aes_seq; 359 struct ieee80211_key_seq *tkip_seq = wowlan_status->ptk.tkip_seq; 360 361 BUILD_BUG_ON(ARRAY_SIZE(sc->ucast_rsc) != IWL_MAX_TID_COUNT); 362 363 for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { 364 iwl_mld_le64_to_aes_seq(sc->ucast_rsc[tid], &aes_seq[tid]); 365 iwl_mld_le64_to_tkip_seq(sc->ucast_rsc[tid], &tkip_seq[tid]); 366 } 367 } 368 369 static void 370 iwl_mld_convert_mcast_ipn(struct iwl_mld_mcast_key_data *key_status, 371 const struct iwl_wowlan_igtk_status *key) 372 { 373 struct ieee80211_key_seq *seq = 374 &key_status->igtk_bigtk.cmac_gmac_seq; 375 u8 ipn_len = ARRAY_SIZE(key->ipn); 376 377 BUILD_BUG_ON(ipn_len != ARRAY_SIZE(seq->aes_gmac.pn)); 378 BUILD_BUG_ON(ipn_len != ARRAY_SIZE(seq->aes_cmac.pn)); 379 BUILD_BUG_ON(offsetof(struct ieee80211_key_seq, aes_gmac) != 380 offsetof(struct ieee80211_key_seq, aes_cmac)); 381 382 /* mac80211 expects big endian for memcmp() to work, convert. 383 * We don't have the key cipher yet so copy to both to cmac and gmac 384 */ 385 for (int i = 0; i < ipn_len; i++) { 386 seq->aes_gmac.pn[i] = key->ipn[ipn_len - i - 1]; 387 seq->aes_cmac.pn[i] = key->ipn[ipn_len - i - 1]; 388 } 389 } 390 391 static void 392 iwl_mld_convert_igtk_resume_data(struct iwl_mld_wowlan_status *wowlan_status, 393 const struct iwl_wowlan_igtk_status *igtk) 394 { 395 if (!igtk->key_status) 396 return; 397 398 BUILD_BUG_ON(sizeof(wowlan_status->igtk.key) < sizeof(igtk->key)); 399 400 wowlan_status->igtk.len = igtk->key_len; 401 wowlan_status->igtk.flags = igtk->key_flags; 402 wowlan_status->igtk.id = 403 u32_get_bits(igtk->key_flags, 404 IWL_WOWLAN_IGTK_BIGTK_IDX_MASK) + 405 WOWLAN_IGTK_MIN_INDEX; 406 407 if (igtk->key_status == IWL_WOWLAN_STATUS_NEW_KEY) 408 memcpy(wowlan_status->igtk.key, igtk->key, sizeof(igtk->key)); 409 else 410 /* If the key status is WOWLAN_STATUS_OLD_KEY, it indicates 411 * that no key material is present. Set the key length to 0 412 * as an indication. 413 */ 414 wowlan_status->igtk.len = 0; 415 416 iwl_mld_convert_mcast_ipn(&wowlan_status->igtk, igtk); 417 } 418 419 static void 420 iwl_mld_convert_bigtk_resume_data(struct iwl_mld_wowlan_status *wowlan_status, 421 const struct iwl_wowlan_igtk_status *bigtk) 422 { 423 int status_idx = 0; 424 425 BUILD_BUG_ON(ARRAY_SIZE(wowlan_status->bigtk) < WOWLAN_BIGTK_KEYS_NUM); 426 427 for (int notif_idx = 0; notif_idx < WOWLAN_BIGTK_KEYS_NUM; 428 notif_idx++) { 429 if (!bigtk[notif_idx].key_status) 430 continue; 431 432 wowlan_status->bigtk[status_idx].len = bigtk[notif_idx].key_len; 433 wowlan_status->bigtk[status_idx].flags = 434 bigtk[notif_idx].key_flags; 435 wowlan_status->bigtk[status_idx].id = 436 u32_get_bits(bigtk[notif_idx].key_flags, 437 IWL_WOWLAN_IGTK_BIGTK_IDX_MASK) 438 + WOWLAN_BIGTK_MIN_INDEX; 439 440 BUILD_BUG_ON(sizeof(wowlan_status->bigtk[status_idx].key) < 441 sizeof(bigtk[notif_idx].key)); 442 if (bigtk[notif_idx].key_status == IWL_WOWLAN_STATUS_NEW_KEY) 443 memcpy(wowlan_status->bigtk[status_idx].key, 444 bigtk[notif_idx].key, 445 sizeof(bigtk[notif_idx].key)); 446 else 447 /* If the key status is WOWLAN_STATUS_OLD_KEY, it 448 * indicates that no key material is present. Set the 449 * key length to 0 as an indication. 450 */ 451 wowlan_status->bigtk[status_idx].len = 0; 452 453 iwl_mld_convert_mcast_ipn(&wowlan_status->bigtk[status_idx], 454 &bigtk[notif_idx]); 455 status_idx++; 456 } 457 } 458 459 static void 460 iwl_mld_convert_mlo_keys(struct iwl_mld *mld, 461 const struct iwl_wowlan_info_notif *notif, 462 struct iwl_mld_wowlan_status *wowlan_status) 463 { 464 if (!notif->num_mlo_link_keys) 465 return; 466 467 wowlan_status->num_mlo_keys = notif->num_mlo_link_keys; 468 469 if (IWL_FW_CHECK(mld, wowlan_status->num_mlo_keys > WOWLAN_MAX_MLO_KEYS, 470 "Too many MLO keys: %d, max %d\n", 471 wowlan_status->num_mlo_keys, WOWLAN_MAX_MLO_KEYS)) 472 wowlan_status->num_mlo_keys = WOWLAN_MAX_MLO_KEYS; 473 474 for (int i = 0; i < wowlan_status->num_mlo_keys; i++) { 475 const struct iwl_wowlan_mlo_gtk *fw_mlo_key = ¬if->mlo_gtks[i]; 476 struct iwl_mld_wowlan_mlo_key *driver_mlo_key = 477 &wowlan_status->mlo_keys[i]; 478 u16 flags = le16_to_cpu(fw_mlo_key->flags); 479 480 driver_mlo_key->link_id = 481 u16_get_bits(flags, WOWLAN_MLO_GTK_FLAG_LINK_ID_MSK); 482 driver_mlo_key->type = 483 u16_get_bits(flags, WOWLAN_MLO_GTK_FLAG_KEY_TYPE_MSK); 484 driver_mlo_key->idx = 485 u16_get_bits(flags, WOWLAN_MLO_GTK_FLAG_KEY_ID_MSK); 486 487 BUILD_BUG_ON(sizeof(driver_mlo_key->key) != sizeof(fw_mlo_key->key)); 488 BUILD_BUG_ON(sizeof(driver_mlo_key->pn) != sizeof(fw_mlo_key->pn)); 489 490 memcpy(driver_mlo_key->key, fw_mlo_key->key, sizeof(fw_mlo_key->key)); 491 memcpy(driver_mlo_key->pn, fw_mlo_key->pn, sizeof(fw_mlo_key->pn)); 492 } 493 } 494 495 static void 496 iwl_mld_convert_wowlan_notif_v5(const struct iwl_wowlan_info_notif_v5 *notif_v5, 497 struct iwl_wowlan_info_notif *notif) 498 { 499 /* Convert GTK from v3 to the new format */ 500 BUILD_BUG_ON(ARRAY_SIZE(notif->gtk) != ARRAY_SIZE(notif_v5->gtk)); 501 502 for (int i = 0; i < ARRAY_SIZE(notif_v5->gtk); i++) { 503 const struct iwl_wowlan_gtk_status_v3 *gtk_v3 = ¬if_v5->gtk[i]; 504 struct iwl_wowlan_gtk_status *gtk = ¬if->gtk[i]; 505 506 /* Copy key material and metadata */ 507 BUILD_BUG_ON(sizeof(gtk->key) != sizeof(gtk_v3->key)); 508 BUILD_BUG_ON(sizeof(gtk->tkip_mic_key) != sizeof(gtk_v3->tkip_mic_key)); 509 510 memcpy(gtk->key, gtk_v3->key, sizeof(gtk_v3->key)); 511 512 gtk->key_len = gtk_v3->key_len; 513 gtk->key_flags = gtk_v3->key_flags; 514 515 memcpy(gtk->tkip_mic_key, gtk_v3->tkip_mic_key, 516 sizeof(gtk_v3->tkip_mic_key)); 517 gtk->sc = gtk_v3->sc; 518 519 /* Set key_status based on whether key material is present. 520 * in v5, a key is either invalid (should be skipped) or has 521 * both meta data and the key itself. 522 */ 523 if (gtk_v3->key_len) 524 gtk->key_status = IWL_WOWLAN_STATUS_NEW_KEY; 525 } 526 527 /* Convert IGTK from v1 to the new format, only one IGTK is passed by FW */ 528 BUILD_BUG_ON(offsetof(struct iwl_wowlan_igtk_status, key_status) != 529 sizeof(struct iwl_wowlan_igtk_status_v1)); 530 531 memcpy(¬if->igtk[0], ¬if_v5->igtk[0], 532 offsetof(struct iwl_wowlan_igtk_status, key_status)); 533 534 /* Set key_status based on whether key material is present. 535 * in v5, a key is either invalid (should be skipped) or has 536 * both meta data and the key itself. 537 */ 538 if (notif_v5->igtk[0].key_len) 539 notif->igtk[0].key_status = IWL_WOWLAN_STATUS_NEW_KEY; 540 541 /* Convert BIGTK from v1 to the new format */ 542 BUILD_BUG_ON(ARRAY_SIZE(notif->bigtk) != ARRAY_SIZE(notif_v5->bigtk)); 543 544 for (int i = 0; i < ARRAY_SIZE(notif_v5->bigtk); i++) { 545 /* Copy everything until key_status */ 546 memcpy(¬if->bigtk[i], ¬if_v5->bigtk[i], 547 offsetof(struct iwl_wowlan_igtk_status, key_status)); 548 549 /* Set key_status based on whether key material is present. 550 * in v5, a key is either invalid (should be skipped) or has 551 * both meta data and the key itself. 552 */ 553 if (notif_v5->bigtk[i].key_len) 554 notif->bigtk[i].key_status = IWL_WOWLAN_STATUS_NEW_KEY; 555 } 556 557 notif->replay_ctr = notif_v5->replay_ctr; 558 notif->pattern_number = notif_v5->pattern_number; 559 notif->qos_seq_ctr = notif_v5->qos_seq_ctr; 560 notif->wakeup_reasons = notif_v5->wakeup_reasons; 561 notif->num_of_gtk_rekeys = notif_v5->num_of_gtk_rekeys; 562 notif->transmitted_ndps = notif_v5->transmitted_ndps; 563 notif->received_beacons = notif_v5->received_beacons; 564 notif->tid_tear_down = notif_v5->tid_tear_down; 565 notif->station_id = notif_v5->station_id; 566 notif->num_mlo_link_keys = notif_v5->num_mlo_link_keys; 567 notif->tid_offloaded_tx = notif_v5->tid_offloaded_tx; 568 569 /* Copy MLO GTK keys */ 570 if (notif_v5->num_mlo_link_keys) { 571 memcpy(notif->mlo_gtks, notif_v5->mlo_gtks, 572 notif_v5->num_mlo_link_keys * sizeof(struct iwl_wowlan_mlo_gtk)); 573 } 574 } 575 576 static bool iwl_mld_validate_wowlan_notif_size(struct iwl_mld *mld, 577 u32 len, 578 u32 expected_len, 579 u8 num_mlo_keys, 580 int version) 581 { 582 u32 len_with_mlo_keys; 583 584 if (IWL_FW_CHECK(mld, len < expected_len, 585 "Invalid wowlan_info_notif v%d (expected=%u got=%u)\n", 586 version, expected_len, len)) 587 return false; 588 589 len_with_mlo_keys = expected_len + 590 (num_mlo_keys * sizeof(struct iwl_wowlan_mlo_gtk)); 591 592 if (IWL_FW_CHECK(mld, len < len_with_mlo_keys, 593 "Invalid wowlan_info_notif v%d with MLO keys (expected=%u got=%u)\n", 594 version, len_with_mlo_keys, len)) 595 return false; 596 597 return true; 598 } 599 600 static bool 601 iwl_mld_handle_wowlan_info_notif(struct iwl_mld *mld, 602 struct iwl_mld_wowlan_status *wowlan_status, 603 struct iwl_rx_packet *pkt) 604 { 605 const struct iwl_wowlan_info_notif *notif; 606 struct iwl_wowlan_info_notif *converted_notif __free(kfree) = NULL; 607 u32 len = iwl_rx_packet_payload_len(pkt); 608 int wowlan_info_ver = iwl_fw_lookup_notif_ver(mld->fw, 609 PROT_OFFLOAD_GROUP, 610 WOWLAN_INFO_NOTIFICATION, 611 IWL_FW_CMD_VER_UNKNOWN); 612 int rsc_notif_ver = iwl_fw_lookup_notif_ver(mld->fw, 613 DATA_PATH_GROUP, 614 RSC_NOTIF, 615 IWL_FW_CMD_VER_UNKNOWN); 616 617 if (wowlan_info_ver == 5) { 618 /* v5 format - validate before conversion */ 619 const struct iwl_wowlan_info_notif_v5 *notif_v5 = (void *)pkt->data; 620 621 if (!iwl_mld_validate_wowlan_notif_size(mld, len, 622 sizeof(*notif_v5), 623 notif_v5->num_mlo_link_keys, 624 5)) 625 return true; 626 627 converted_notif = kzalloc_flex(*converted_notif, mlo_gtks, 628 notif_v5->num_mlo_link_keys, 629 GFP_ATOMIC); 630 if (!converted_notif) { 631 IWL_ERR(mld, 632 "Failed to allocate memory for converted wowlan_info_notif\n"); 633 return true; 634 } 635 636 iwl_mld_convert_wowlan_notif_v5(notif_v5, 637 converted_notif); 638 notif = converted_notif; 639 } else if (wowlan_info_ver == 6) { 640 notif = (void *)pkt->data; 641 if (!iwl_mld_validate_wowlan_notif_size(mld, len, 642 sizeof(*notif), 643 notif->num_mlo_link_keys, 644 6)) 645 return true; 646 } else { 647 /* smaller versions are not supported */ 648 IWL_WARN(mld, 649 "Unsupported wowlan_info_notif version %d\n", 650 wowlan_info_ver); 651 return true; 652 } 653 654 if (IWL_FW_CHECK(mld, notif->tid_offloaded_tx != IWL_WOWLAN_OFFLOAD_TID, 655 "Invalid tid_offloaded_tx %d\n", 656 notif->tid_offloaded_tx)) 657 return true; 658 659 iwl_mld_convert_gtk_resume_data(mld, wowlan_status, notif->gtk, 660 ¬if->gtk[0].sc, rsc_notif_ver); 661 if (rsc_notif_ver == IWL_FW_CMD_VER_UNKNOWN) 662 iwl_mld_convert_ptk_resume_seq(mld, wowlan_status, 663 ¬if->gtk[0].sc); 664 /* only one igtk is passed by FW */ 665 iwl_mld_convert_igtk_resume_data(wowlan_status, ¬if->igtk[0]); 666 iwl_mld_convert_bigtk_resume_data(wowlan_status, notif->bigtk); 667 668 wowlan_status->replay_ctr = le64_to_cpu(notif->replay_ctr); 669 wowlan_status->pattern_number = le16_to_cpu(notif->pattern_number); 670 671 wowlan_status->tid_offloaded_tx = notif->tid_offloaded_tx; 672 wowlan_status->last_qos_seq = le16_to_cpu(notif->qos_seq_ctr); 673 wowlan_status->num_of_gtk_rekeys = 674 le32_to_cpu(notif->num_of_gtk_rekeys); 675 wowlan_status->wakeup_reasons = le32_to_cpu(notif->wakeup_reasons); 676 677 iwl_mld_convert_mlo_keys(mld, notif, wowlan_status); 678 679 return false; 680 } 681 682 static bool 683 iwl_mld_handle_wake_pkt_notif(struct iwl_mld *mld, 684 struct iwl_mld_wowlan_status *wowlan_status, 685 struct iwl_rx_packet *pkt) 686 { 687 const struct iwl_wowlan_wake_pkt_notif *notif = (void *)pkt->data; 688 u32 actual_size, len = iwl_rx_packet_payload_len(pkt); 689 u32 expected_size = le32_to_cpu(notif->wake_packet_length); 690 691 if (IWL_FW_CHECK(mld, len < sizeof(*notif), 692 "Invalid WoWLAN wake packet notification (expected size=%zu got=%u)\n", 693 sizeof(*notif), len)) 694 return true; 695 696 if (IWL_FW_CHECK(mld, !(wowlan_status->wakeup_reasons & 697 IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT), 698 "Got wake packet but wakeup reason is %x\n", 699 wowlan_status->wakeup_reasons)) 700 return true; 701 702 actual_size = len - offsetof(struct iwl_wowlan_wake_pkt_notif, 703 wake_packet); 704 705 /* actual_size got the padding from the notification, remove it. */ 706 if (expected_size < actual_size) 707 actual_size = expected_size; 708 wowlan_status->wake_packet = kmemdup(notif->wake_packet, actual_size, 709 GFP_ATOMIC); 710 if (!wowlan_status->wake_packet) 711 return true; 712 713 wowlan_status->wake_packet_length = expected_size; 714 wowlan_status->wake_packet_bufsize = actual_size; 715 716 return false; 717 } 718 719 static void 720 iwl_mld_set_wake_packet(struct iwl_mld *mld, 721 struct ieee80211_vif *vif, 722 const struct iwl_mld_wowlan_status *wowlan_status, 723 struct cfg80211_wowlan_wakeup *wakeup, 724 struct sk_buff **_pkt) 725 { 726 int pkt_bufsize = wowlan_status->wake_packet_bufsize; 727 int expected_pktlen = wowlan_status->wake_packet_length; 728 const u8 *pktdata = wowlan_status->wake_packet; 729 const struct ieee80211_hdr *hdr = (const void *)pktdata; 730 int truncated = expected_pktlen - pkt_bufsize; 731 732 if (ieee80211_is_data(hdr->frame_control)) { 733 int hdrlen = ieee80211_hdrlen(hdr->frame_control); 734 int ivlen = 0, icvlen = 4; /* also FCS */ 735 736 struct sk_buff *pkt = alloc_skb(pkt_bufsize, GFP_KERNEL); 737 *_pkt = pkt; 738 if (!pkt) 739 return; 740 741 skb_put_data(pkt, pktdata, hdrlen); 742 pktdata += hdrlen; 743 pkt_bufsize -= hdrlen; 744 745 /* if truncated, FCS/ICV is (partially) gone */ 746 if (truncated >= icvlen) { 747 truncated -= icvlen; 748 icvlen = 0; 749 } else { 750 icvlen -= truncated; 751 truncated = 0; 752 } 753 754 pkt_bufsize -= ivlen + icvlen; 755 pktdata += ivlen; 756 757 skb_put_data(pkt, pktdata, pkt_bufsize); 758 759 if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) 760 return; 761 wakeup->packet = pkt->data; 762 wakeup->packet_present_len = pkt->len; 763 wakeup->packet_len = pkt->len - truncated; 764 wakeup->packet_80211 = false; 765 } else { 766 int fcslen = 4; 767 768 if (truncated >= 4) { 769 truncated -= 4; 770 fcslen = 0; 771 } else { 772 fcslen -= truncated; 773 truncated = 0; 774 } 775 pkt_bufsize -= fcslen; 776 wakeup->packet = wowlan_status->wake_packet; 777 wakeup->packet_present_len = pkt_bufsize; 778 wakeup->packet_len = expected_pktlen - truncated; 779 wakeup->packet_80211 = true; 780 } 781 } 782 783 static void 784 iwl_mld_report_wowlan_wakeup(struct iwl_mld *mld, 785 struct ieee80211_vif *vif, 786 struct iwl_mld_wowlan_status *wowlan_status) 787 { 788 struct sk_buff *pkt = NULL; 789 struct cfg80211_wowlan_wakeup wakeup = { 790 .pattern_idx = -1, 791 }; 792 u32 reasons = wowlan_status->wakeup_reasons; 793 794 if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) { 795 ieee80211_report_wowlan_wakeup(vif, NULL, GFP_KERNEL); 796 return; 797 } 798 799 pm_wakeup_event(mld->dev, 0); 800 801 if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) 802 wakeup.magic_pkt = true; 803 804 if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) 805 wakeup.pattern_idx = 806 wowlan_status->pattern_number; 807 808 if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | 809 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH | 810 IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)) 811 wakeup.disconnect = true; 812 813 if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) 814 wakeup.gtk_rekey_failure = true; 815 816 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) 817 wakeup.rfkill_release = true; 818 819 if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) 820 wakeup.eap_identity_req = true; 821 822 if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) 823 wakeup.four_way_handshake = true; 824 825 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS) 826 wakeup.tcp_connlost = true; 827 828 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE) 829 wakeup.tcp_nomoretokens = true; 830 831 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET) 832 wakeup.tcp_match = true; 833 834 if (reasons & IWL_WAKEUP_BY_11W_UNPROTECTED_DEAUTH_OR_DISASSOC) 835 wakeup.unprot_deauth_disassoc = true; 836 837 if (wowlan_status->wake_packet) 838 iwl_mld_set_wake_packet(mld, vif, wowlan_status, &wakeup, &pkt); 839 840 ieee80211_report_wowlan_wakeup(vif, &wakeup, GFP_KERNEL); 841 kfree_skb(pkt); 842 } 843 844 static void 845 iwl_mld_set_key_rx_seq_tids(struct ieee80211_key_conf *key, 846 struct ieee80211_key_seq *seq) 847 { 848 int tid; 849 850 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) 851 ieee80211_set_key_rx_seq(key, tid, &seq[tid]); 852 } 853 854 static void 855 iwl_mld_update_mcast_rx_seq(struct ieee80211_key_conf *key, 856 struct iwl_mld_mcast_key_data *key_data) 857 { 858 switch (key->cipher) { 859 case WLAN_CIPHER_SUITE_CCMP: 860 case WLAN_CIPHER_SUITE_GCMP: 861 case WLAN_CIPHER_SUITE_GCMP_256: 862 iwl_mld_set_key_rx_seq_tids(key, 863 key_data->gtk.aes_seq); 864 break; 865 case WLAN_CIPHER_SUITE_TKIP: 866 iwl_mld_set_key_rx_seq_tids(key, 867 key_data->gtk.tkip_seq); 868 break; 869 case WLAN_CIPHER_SUITE_BIP_GMAC_128: 870 case WLAN_CIPHER_SUITE_BIP_GMAC_256: 871 case WLAN_CIPHER_SUITE_BIP_CMAC_256: 872 case WLAN_CIPHER_SUITE_AES_CMAC: 873 /* igtk/bigtk ciphers*/ 874 ieee80211_set_key_rx_seq(key, 0, 875 &key_data->igtk_bigtk.cmac_gmac_seq); 876 break; 877 default: 878 WARN_ON(1); 879 } 880 } 881 882 static void 883 iwl_mld_update_ptk_rx_seq(struct iwl_mld *mld, 884 struct iwl_mld_wowlan_status *wowlan_status, 885 struct ieee80211_sta *sta, 886 struct ieee80211_key_conf *key, 887 bool is_tkip) 888 { 889 struct iwl_mld_sta *mld_sta = 890 iwl_mld_sta_from_mac80211(sta); 891 struct iwl_mld_ptk_pn *mld_ptk_pn = 892 wiphy_dereference(mld->wiphy, 893 mld_sta->ptk_pn[key->keyidx]); 894 895 iwl_mld_set_key_rx_seq_tids(key, is_tkip ? 896 wowlan_status->ptk.tkip_seq : 897 wowlan_status->ptk.aes_seq); 898 if (is_tkip) 899 return; 900 901 if (WARN_ON(!mld_ptk_pn)) 902 return; 903 904 for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { 905 for (int i = 1; i < mld->trans->info.num_rxqs; i++) 906 memcpy(mld_ptk_pn->q[i].pn[tid], 907 wowlan_status->ptk.aes_seq[tid].ccmp.pn, 908 IEEE80211_CCMP_PN_LEN); 909 } 910 } 911 912 static void 913 iwl_mld_resume_keys_iter(struct ieee80211_hw *hw, 914 struct ieee80211_vif *vif, 915 struct ieee80211_sta *sta, 916 struct ieee80211_key_conf *key, 917 void *_data) 918 { 919 struct iwl_mld_resume_key_iter_data *data = _data; 920 struct iwl_mld_wowlan_status *wowlan_status = data->wowlan_status; 921 u8 status_idx; 922 int rsc_notif_ver = iwl_fw_lookup_notif_ver(data->mld->fw, 923 DATA_PATH_GROUP, 924 RSC_NOTIF, 925 IWL_FW_CMD_VER_UNKNOWN); 926 927 /* If RSC_NOTIF is not supported */ 928 if (rsc_notif_ver == IWL_FW_CMD_VER_UNKNOWN && 929 key->keyidx >= 0 && key->keyidx <= 3) { 930 /* PTK */ 931 if (sta) { 932 iwl_mld_update_ptk_rx_seq(data->mld, wowlan_status, 933 sta, key, 934 key->cipher == 935 WLAN_CIPHER_SUITE_TKIP); 936 /* GTK */ 937 } else { 938 status_idx = key->keyidx == wowlan_status->gtk[1].id; 939 iwl_mld_update_mcast_rx_seq(key, 940 &wowlan_status->gtk[status_idx]); 941 } 942 } 943 944 /* IGTK */ 945 if (key->keyidx == 4 || key->keyidx == 5) { 946 if (key->keyidx == wowlan_status->igtk.id) 947 iwl_mld_update_mcast_rx_seq(key, &wowlan_status->igtk); 948 } 949 950 /* BIGTK */ 951 if (key->keyidx == 6 || key->keyidx == 7) { 952 status_idx = key->keyidx == wowlan_status->bigtk[1].id; 953 iwl_mld_update_mcast_rx_seq(key, 954 &wowlan_status->bigtk[status_idx]); 955 } 956 } 957 958 static void 959 iwl_mld_rsc_update_key_iter(struct ieee80211_hw *hw, 960 struct ieee80211_vif *vif, 961 struct ieee80211_sta *sta, 962 struct ieee80211_key_conf *key, 963 void *_data) 964 { 965 struct iwl_mld_rsc_resume_iter_data *data = _data; 966 struct ieee80211_key_seq seq; 967 968 if (key->keyidx > 3) 969 return; 970 971 if (sta) { 972 /* PTK */ 973 BUILD_BUG_ON(ARRAY_SIZE(data->notif->ucast_rsc) != 974 IWL_MAX_TID_COUNT); 975 976 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { 977 /* TKIP: just update key sequences */ 978 for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { 979 iwl_mld_le64_to_tkip_seq(data->notif->ucast_rsc[tid], 980 &seq); 981 ieee80211_set_key_rx_seq(key, tid, &seq); 982 } 983 } else { 984 struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta); 985 struct iwl_mld_ptk_pn *mld_ptk_pn = 986 rcu_dereference_wiphy(data->mld->wiphy, 987 mld_sta->ptk_pn[key->keyidx]); 988 989 if (WARN_ON(!mld_ptk_pn)) 990 return; 991 992 if (WARN_ON(data->queue >= 993 data->mld->trans->info.num_rxqs)) 994 return; 995 996 for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { 997 iwl_mld_le64_to_aes_seq(data->notif->ucast_rsc[tid], 998 &seq); 999 ieee80211_set_key_rx_seq(key, tid, &seq); 1000 memcpy(mld_ptk_pn->q[data->queue].pn[tid], 1001 seq.ccmp.pn, 1002 IEEE80211_CCMP_PN_LEN); 1003 } 1004 } 1005 1006 IWL_DEBUG_WOWLAN(data->mld, 1007 "Updated PTK RSC for key %d on queue %d\n", 1008 key->keyidx, data->queue); 1009 } else { 1010 /* GTK */ 1011 int rsc_idx = data->notif->mcast_key_id_map[key->keyidx]; 1012 1013 if (rsc_idx == IWL_MCAST_KEY_MAP_INVALID) 1014 return; 1015 1016 if (IWL_FW_CHECK(data->mld, 1017 rsc_idx >= ARRAY_SIZE(data->notif->mcast_rsc), 1018 "Invalid mcast key mapping: %d for key %d\n", 1019 rsc_idx, key->keyidx)) 1020 return; 1021 1022 for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { 1023 __le64 rsc = 1024 data->notif->mcast_rsc[rsc_idx][tid]; 1025 1026 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) 1027 iwl_mld_le64_to_tkip_seq(rsc, &seq); 1028 else 1029 iwl_mld_le64_to_aes_seq(rsc, &seq); 1030 ieee80211_set_key_rx_seq(key, tid, &seq); 1031 } 1032 1033 IWL_DEBUG_WOWLAN(data->mld, 1034 "Updated GTK %d RSC (rsc_idx %d) on queue %d\n", 1035 key->keyidx, rsc_idx, data->queue); 1036 } 1037 } 1038 1039 void 1040 iwl_mld_process_rsc_notification(struct iwl_mld *mld, 1041 struct ieee80211_vif *vif, 1042 const struct iwl_wowlan_all_rsc_tsc_v5 *notif, 1043 int queue) 1044 { 1045 struct iwl_mld_rsc_resume_iter_data iter_data = { 1046 .mld = mld, 1047 .notif = notif, 1048 .queue = queue, 1049 }; 1050 1051 /* Iterate through all active keys and update RSC */ 1052 ieee80211_iter_keys_rcu(mld->hw, vif, 1053 iwl_mld_rsc_update_key_iter, 1054 &iter_data); 1055 } 1056 1057 static void 1058 iwl_mld_add_mcast_rekey(struct ieee80211_vif *vif, 1059 struct iwl_mld *mld, 1060 struct iwl_mld_mcast_key_data *key_data, 1061 struct ieee80211_bss_conf *link_conf) 1062 { 1063 struct ieee80211_key_conf *key_config; 1064 int link_id = vif->active_links ? __ffs(vif->active_links) : -1; 1065 1066 if (!key_data->len) 1067 return; 1068 1069 key_config = ieee80211_gtk_rekey_add(vif, key_data->id, key_data->key, 1070 sizeof(key_data->key), link_id); 1071 if (IS_ERR(key_config)) 1072 return; 1073 1074 iwl_mld_update_mcast_rx_seq(key_config, key_data); 1075 1076 /* The FW holds only one IGTK so we keep track of the valid one */ 1077 if (key_config->keyidx == 4 || key_config->keyidx == 5) { 1078 struct iwl_mld_link_sta *mld_ap_link_sta; 1079 1080 mld_ap_link_sta = iwl_mld_get_ap_link_sta(vif, 1081 link_conf->link_id); 1082 if (WARN_ON(!mld_ap_link_sta)) 1083 return; 1084 1085 /* If we had more than one rekey, mac80211 will tell us to 1086 * remove the old and add the new so we will update the IGTK in 1087 * drv_set_key 1088 */ 1089 if (mld_ap_link_sta->rx_igtk && 1090 mld_ap_link_sta->rx_igtk != key_config) { 1091 /* mark the old IGTK as not in FW */ 1092 mld_ap_link_sta->rx_igtk->hw_key_idx = 1093 STA_KEY_IDX_INVALID; 1094 mld_ap_link_sta->rx_igtk = key_config; 1095 } 1096 } 1097 1098 /* Also keep track of the new BIGTK */ 1099 if (key_config->keyidx == 6 || key_config->keyidx == 7) 1100 iwl_mld_track_bigtk(mld, vif, key_config, true); 1101 } 1102 1103 static void 1104 iwl_mld_add_all_rekeys(struct iwl_mld *mld, 1105 struct ieee80211_vif *vif, 1106 struct iwl_mld_wowlan_status *wowlan_status, 1107 struct ieee80211_bss_conf *link_conf) 1108 { 1109 int i; 1110 1111 for (i = 0; i < ARRAY_SIZE(wowlan_status->gtk); i++) 1112 iwl_mld_add_mcast_rekey(vif, mld, &wowlan_status->gtk[i], 1113 link_conf); 1114 1115 iwl_mld_add_mcast_rekey(vif, mld, &wowlan_status->igtk, link_conf); 1116 1117 for (i = 0; i < ARRAY_SIZE(wowlan_status->bigtk); i++) 1118 iwl_mld_add_mcast_rekey(vif, mld, &wowlan_status->bigtk[i], 1119 link_conf); 1120 } 1121 1122 static void iwl_mld_mlo_rekey(struct iwl_mld *mld, 1123 struct iwl_mld_wowlan_status *wowlan_status, 1124 struct ieee80211_vif *vif) 1125 { 1126 IWL_DEBUG_WOWLAN(mld, "Num of MLO Keys: %d\n", wowlan_status->num_mlo_keys); 1127 1128 if (!wowlan_status->num_mlo_keys) 1129 return; 1130 1131 for (int i = 0; i < wowlan_status->num_mlo_keys; i++) { 1132 struct iwl_mld_wowlan_mlo_key *mlo_key = &wowlan_status->mlo_keys[i]; 1133 struct ieee80211_key_conf *key; 1134 struct ieee80211_key_seq seq; 1135 u8 link_id = mlo_key->link_id; 1136 1137 if (IWL_FW_CHECK(mld, mlo_key->link_id >= IEEE80211_MLD_MAX_NUM_LINKS || 1138 mlo_key->idx >= 8 || 1139 mlo_key->type >= WOWLAN_MLO_GTK_KEY_NUM_TYPES, 1140 "Invalid MLO key link_id %d, idx %d, type %d\n", 1141 mlo_key->link_id, mlo_key->idx, mlo_key->type)) 1142 continue; 1143 1144 if (!(vif->valid_links & BIT(link_id)) || 1145 (vif->active_links & BIT(link_id))) 1146 continue; 1147 1148 IWL_DEBUG_WOWLAN(mld, "Add MLO key id %d, link id %d\n", 1149 mlo_key->idx, link_id); 1150 1151 key = ieee80211_gtk_rekey_add(vif, mlo_key->idx, mlo_key->key, 1152 sizeof(mlo_key->key), link_id); 1153 1154 if (IS_ERR(key)) 1155 continue; 1156 1157 /* 1158 * mac80211 expects the PN in big-endian 1159 * also note that seq is a union of all cipher types 1160 * (ccmp, gcmp, cmac, gmac), and they all have the same 1161 * pn field (of length 6) so just copy it to ccmp.pn. 1162 */ 1163 for (int j = 5; j >= 0; j--) 1164 seq.ccmp.pn[5 - j] = mlo_key->pn[j]; 1165 1166 /* group keys are non-QoS and use TID 0 */ 1167 ieee80211_set_key_rx_seq(key, 0, &seq); 1168 } 1169 } 1170 1171 static bool 1172 iwl_mld_update_sec_keys(struct iwl_mld *mld, 1173 struct ieee80211_vif *vif, 1174 struct iwl_mld_wowlan_status *wowlan_status) 1175 { 1176 int link_id = vif->active_links ? __ffs(vif->active_links) : 0; 1177 struct ieee80211_bss_conf *link_conf = 1178 link_conf_dereference_protected(vif, link_id); 1179 __be64 replay_ctr = cpu_to_be64(wowlan_status->replay_ctr); 1180 struct iwl_mld_resume_key_iter_data key_iter_data = { 1181 .mld = mld, 1182 .wowlan_status = wowlan_status, 1183 }; 1184 1185 if (WARN_ON(!link_conf)) 1186 return false; 1187 1188 ieee80211_iter_keys(mld->hw, vif, iwl_mld_resume_keys_iter, 1189 &key_iter_data); 1190 1191 IWL_DEBUG_WOWLAN(mld, "Number of rekeys: %d\n", 1192 wowlan_status->num_of_gtk_rekeys); 1193 1194 if (!wowlan_status->num_of_gtk_rekeys) 1195 return true; 1196 1197 iwl_mld_add_all_rekeys(mld, vif, wowlan_status, 1198 link_conf); 1199 1200 iwl_mld_mlo_rekey(mld, wowlan_status, vif); 1201 1202 ieee80211_gtk_rekey_notify(vif, link_conf->bssid, 1203 (void *)&replay_ctr, GFP_KERNEL); 1204 return true; 1205 } 1206 1207 static bool 1208 iwl_mld_process_wowlan_status(struct iwl_mld *mld, 1209 struct ieee80211_vif *vif, 1210 struct iwl_mld_wowlan_status *wowlan_status) 1211 { 1212 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 1213 struct ieee80211_sta *ap_sta = mld_vif->ap_sta; 1214 struct iwl_mld_txq *mld_txq; 1215 1216 iwl_mld_report_wowlan_wakeup(mld, vif, wowlan_status); 1217 1218 if (WARN_ON(!ap_sta)) 1219 return false; 1220 1221 mld_txq = 1222 iwl_mld_txq_from_mac80211(ap_sta->txq[wowlan_status->tid_offloaded_tx]); 1223 1224 /* Update the pointers of the Tx queue that may have moved during 1225 * suspend if the firmware sent frames. 1226 * The firmware stores last-used value, we store next value. 1227 */ 1228 WARN_ON(!mld_txq->status.allocated); 1229 iwl_trans_set_q_ptrs(mld->trans, mld_txq->fw_id, 1230 (wowlan_status->last_qos_seq + 1231 0x10) >> 4); 1232 1233 if (!iwl_mld_update_sec_keys(mld, vif, wowlan_status)) 1234 return false; 1235 1236 if (wowlan_status->wakeup_reasons & 1237 (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | 1238 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH | 1239 IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)) 1240 return false; 1241 1242 return true; 1243 } 1244 1245 static bool 1246 iwl_mld_netdetect_match_info_handler(struct iwl_mld *mld, 1247 struct iwl_mld_resume_data *resume_data, 1248 struct iwl_rx_packet *pkt) 1249 { 1250 struct iwl_mld_netdetect_res *results = resume_data->netdetect_res; 1251 const struct iwl_scan_offload_match_info *notif = (void *)pkt->data; 1252 u32 len = iwl_rx_packet_payload_len(pkt); 1253 1254 if (IWL_FW_CHECK(mld, !mld->netdetect, 1255 "Got scan match info notif when mld->netdetect==%d\n", 1256 mld->netdetect)) 1257 return true; 1258 1259 if (IWL_FW_CHECK(mld, len < sizeof(*notif), 1260 "Invalid scan offload match notif of length: %d\n", 1261 len)) 1262 return true; 1263 1264 if (IWL_FW_CHECK(mld, resume_data->wowlan_status->wakeup_reasons != 1265 IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS, 1266 "Ignore scan match info: unexpected wakeup reason (expected=0x%x got=0x%x)\n", 1267 IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS, 1268 resume_data->wowlan_status->wakeup_reasons)) 1269 return true; 1270 1271 results->matched_profiles = le32_to_cpu(notif->matched_profiles); 1272 IWL_DEBUG_WOWLAN(mld, "number of matched profiles=%u\n", 1273 results->matched_profiles); 1274 1275 if (results->matched_profiles) 1276 memcpy(results->matches, notif->matches, 1277 NETDETECT_QUERY_BUF_LEN); 1278 1279 /* No scan should be active at this point */ 1280 mld->scan.status = 0; 1281 memset(mld->scan.uid_status, 0, sizeof(mld->scan.uid_status)); 1282 return false; 1283 } 1284 1285 static void 1286 iwl_mld_set_netdetect_info(struct iwl_mld *mld, 1287 const struct cfg80211_sched_scan_request *netdetect_cfg, 1288 struct cfg80211_wowlan_nd_info *netdetect_info, 1289 struct iwl_mld_netdetect_res *netdetect_res, 1290 unsigned long matched_profiles) 1291 { 1292 int i; 1293 1294 for_each_set_bit(i, &matched_profiles, netdetect_cfg->n_match_sets) { 1295 struct cfg80211_wowlan_nd_match *match; 1296 int idx, j, n_channels = 0; 1297 struct iwl_scan_offload_profile_match *matches = 1298 (void *)netdetect_res->matches; 1299 1300 for (int k = 0; k < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN; k++) 1301 n_channels += 1302 hweight8(matches[i].matching_channels[k]); 1303 match = kzalloc_flex(*match, channels, n_channels); 1304 if (!match) 1305 return; 1306 1307 netdetect_info->matches[netdetect_info->n_matches] = match; 1308 netdetect_info->n_matches++; 1309 1310 /* We inverted the order of the SSIDs in the scan 1311 * request, so invert the index here. 1312 */ 1313 idx = netdetect_cfg->n_match_sets - i - 1; 1314 match->ssid.ssid_len = 1315 netdetect_cfg->match_sets[idx].ssid.ssid_len; 1316 memcpy(match->ssid.ssid, 1317 netdetect_cfg->match_sets[idx].ssid.ssid, 1318 match->ssid.ssid_len); 1319 1320 if (netdetect_cfg->n_channels < n_channels) 1321 continue; 1322 1323 for_each_set_bit(j, 1324 (unsigned long *)&matches[i].matching_channels[0], 1325 sizeof(matches[i].matching_channels)) { 1326 match->channels[match->n_channels] = 1327 netdetect_cfg->channels[j]->center_freq; 1328 match->n_channels++; 1329 } 1330 } 1331 } 1332 1333 static void 1334 iwl_mld_process_netdetect_res(struct iwl_mld *mld, 1335 struct ieee80211_vif *vif, 1336 struct iwl_mld_resume_data *resume_data) 1337 { 1338 struct cfg80211_wowlan_nd_info *netdetect_info = NULL; 1339 const struct cfg80211_sched_scan_request *netdetect_cfg; 1340 struct cfg80211_wowlan_wakeup wakeup = { 1341 .pattern_idx = -1, 1342 }; 1343 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; 1344 unsigned long matched_profiles; 1345 u32 wakeup_reasons; 1346 int n_matches; 1347 1348 lockdep_assert_wiphy(mld->wiphy); 1349 1350 if (WARN_ON(!mld->wiphy->wowlan_config || 1351 !mld->wiphy->wowlan_config->nd_config)) { 1352 IWL_DEBUG_WOWLAN(mld, 1353 "Netdetect isn't configured on resume flow\n"); 1354 goto out; 1355 } 1356 1357 netdetect_cfg = mld->wiphy->wowlan_config->nd_config; 1358 wakeup_reasons = resume_data->wowlan_status->wakeup_reasons; 1359 1360 if (wakeup_reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) 1361 wakeup.rfkill_release = true; 1362 1363 if (wakeup_reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) 1364 goto out; 1365 1366 if (!resume_data->netdetect_res->matched_profiles) { 1367 IWL_DEBUG_WOWLAN(mld, 1368 "Netdetect results aren't valid\n"); 1369 wakeup_report = NULL; 1370 goto out; 1371 } 1372 1373 matched_profiles = resume_data->netdetect_res->matched_profiles; 1374 if (!netdetect_cfg->n_match_sets) { 1375 IWL_DEBUG_WOWLAN(mld, 1376 "No netdetect match sets are configured\n"); 1377 goto out; 1378 } 1379 n_matches = hweight_long(matched_profiles); 1380 netdetect_info = kzalloc_flex(*netdetect_info, matches, n_matches); 1381 if (netdetect_info) 1382 iwl_mld_set_netdetect_info(mld, netdetect_cfg, netdetect_info, 1383 resume_data->netdetect_res, 1384 matched_profiles); 1385 1386 wakeup.net_detect = netdetect_info; 1387 out: 1388 ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL); 1389 if (netdetect_info) { 1390 for (int i = 0; i < netdetect_info->n_matches; i++) 1391 kfree(netdetect_info->matches[i]); 1392 kfree(netdetect_info); 1393 } 1394 } 1395 1396 static bool iwl_mld_handle_d3_notif(struct iwl_notif_wait_data *notif_wait, 1397 struct iwl_rx_packet *pkt, void *data) 1398 { 1399 struct iwl_mld_resume_data *resume_data = data; 1400 struct iwl_mld *mld = 1401 container_of(notif_wait, struct iwl_mld, notif_wait); 1402 1403 switch (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd)) { 1404 case WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION): { 1405 if (resume_data->notifs_received & IWL_D3_NOTIF_WOWLAN_INFO) { 1406 IWL_DEBUG_WOWLAN(mld, 1407 "got additional wowlan_info notif\n"); 1408 break; 1409 } 1410 resume_data->notif_handling_err = 1411 iwl_mld_handle_wowlan_info_notif(mld, 1412 resume_data->wowlan_status, 1413 pkt); 1414 resume_data->notifs_received |= IWL_D3_NOTIF_WOWLAN_INFO; 1415 1416 if (resume_data->wowlan_status->wakeup_reasons & 1417 IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT) 1418 resume_data->notifs_expected |= 1419 IWL_D3_NOTIF_WOWLAN_WAKE_PKT; 1420 break; 1421 } 1422 case WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_WAKE_PKT_NOTIFICATION): { 1423 if (resume_data->notifs_received & 1424 IWL_D3_NOTIF_WOWLAN_WAKE_PKT) { 1425 /* We shouldn't get two wake packet notifications */ 1426 IWL_DEBUG_WOWLAN(mld, 1427 "Got additional wowlan wake packet notification\n"); 1428 break; 1429 } 1430 resume_data->notif_handling_err = 1431 iwl_mld_handle_wake_pkt_notif(mld, 1432 resume_data->wowlan_status, 1433 pkt); 1434 resume_data->notifs_received |= IWL_D3_NOTIF_WOWLAN_WAKE_PKT; 1435 break; 1436 } 1437 case WIDE_ID(SCAN_GROUP, OFFLOAD_MATCH_INFO_NOTIF): { 1438 if (resume_data->notifs_received & IWL_D3_ND_MATCH_INFO) { 1439 IWL_ERR(mld, 1440 "Got additional netdetect match info\n"); 1441 break; 1442 } 1443 1444 resume_data->notif_handling_err = 1445 iwl_mld_netdetect_match_info_handler(mld, resume_data, 1446 pkt); 1447 resume_data->notifs_received |= IWL_D3_ND_MATCH_INFO; 1448 break; 1449 } 1450 case WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION): { 1451 struct iwl_d3_end_notif *notif = (void *)pkt->data; 1452 1453 resume_data->d3_end_flags = le32_to_cpu(notif->flags); 1454 resume_data->notifs_received |= IWL_D3_NOTIF_D3_END_NOTIF; 1455 break; 1456 } 1457 default: 1458 WARN_ON(1); 1459 } 1460 1461 return resume_data->notifs_received == resume_data->notifs_expected; 1462 } 1463 1464 #define IWL_MLD_D3_NOTIF_TIMEOUT (HZ / 3) 1465 1466 static int iwl_mld_wait_d3_notif(struct iwl_mld *mld, 1467 struct iwl_mld_resume_data *resume_data, 1468 bool with_wowlan) 1469 { 1470 static const u16 wowlan_resume_notif[] = { 1471 WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION), 1472 WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_WAKE_PKT_NOTIFICATION), 1473 WIDE_ID(SCAN_GROUP, OFFLOAD_MATCH_INFO_NOTIF), 1474 WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION) 1475 }; 1476 static const u16 d3_resume_notif[] = { 1477 WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION) 1478 }; 1479 struct iwl_notification_wait wait_d3_notif; 1480 int ret; 1481 1482 if (with_wowlan) 1483 iwl_init_notification_wait(&mld->notif_wait, &wait_d3_notif, 1484 wowlan_resume_notif, 1485 ARRAY_SIZE(wowlan_resume_notif), 1486 iwl_mld_handle_d3_notif, 1487 resume_data); 1488 else 1489 iwl_init_notification_wait(&mld->notif_wait, &wait_d3_notif, 1490 d3_resume_notif, 1491 ARRAY_SIZE(d3_resume_notif), 1492 iwl_mld_handle_d3_notif, 1493 resume_data); 1494 1495 ret = iwl_trans_d3_resume(mld->trans, false); 1496 if (ret) { 1497 /* Avoid sending commands if the FW is dead */ 1498 iwl_trans_notify_fw_error(mld->trans); 1499 iwl_remove_notification(&mld->notif_wait, &wait_d3_notif); 1500 return ret; 1501 } 1502 1503 ret = iwl_wait_notification(&mld->notif_wait, &wait_d3_notif, 1504 IWL_MLD_D3_NOTIF_TIMEOUT); 1505 if (ret) 1506 IWL_ERR(mld, "Couldn't get the d3 notif %d\n", ret); 1507 1508 if (resume_data->notif_handling_err) 1509 ret = -EIO; 1510 1511 return ret; 1512 } 1513 1514 int iwl_mld_no_wowlan_suspend(struct iwl_mld *mld) 1515 { 1516 struct iwl_d3_manager_config d3_cfg_cmd_data = {}; 1517 int ret; 1518 1519 if (mld->debug_max_sleep) { 1520 d3_cfg_cmd_data.wakeup_host_timer = 1521 cpu_to_le32(mld->debug_max_sleep); 1522 d3_cfg_cmd_data.wakeup_flags = 1523 cpu_to_le32(IWL_WAKEUP_D3_HOST_TIMER); 1524 } 1525 1526 lockdep_assert_wiphy(mld->wiphy); 1527 1528 IWL_DEBUG_WOWLAN(mld, "Starting the no wowlan suspend flow\n"); 1529 1530 iwl_mld_low_latency_stop(mld); 1531 1532 ret = iwl_mld_update_device_power(mld, true); 1533 if (ret) { 1534 IWL_ERR(mld, 1535 "d3 suspend: couldn't send power_device %d\n", ret); 1536 return ret; 1537 } 1538 1539 ret = iwl_mld_send_cmd_pdu(mld, D3_CONFIG_CMD, 1540 &d3_cfg_cmd_data); 1541 if (ret) { 1542 IWL_ERR(mld, 1543 "d3 suspend: couldn't send D3_CONFIG_CMD %d\n", ret); 1544 return ret; 1545 } 1546 1547 ret = iwl_trans_d3_suspend(mld->trans, false); 1548 if (ret) { 1549 IWL_ERR(mld, "d3 suspend: trans_d3_suspend failed %d\n", ret); 1550 /* We are going to stop the FW. Avoid sending commands in that flow */ 1551 iwl_trans_notify_fw_error(mld->trans); 1552 } else { 1553 /* Async notification might send hcmds, which is not allowed in suspend */ 1554 iwl_mld_cancel_async_notifications(mld); 1555 mld->fw_status.in_d3 = true; 1556 } 1557 1558 return ret; 1559 } 1560 1561 int iwl_mld_no_wowlan_resume(struct iwl_mld *mld) 1562 { 1563 struct iwl_mld_resume_data resume_data = { 1564 .notifs_expected = 1565 IWL_D3_NOTIF_D3_END_NOTIF, 1566 }; 1567 int ret; 1568 1569 lockdep_assert_wiphy(mld->wiphy); 1570 1571 IWL_DEBUG_WOWLAN(mld, "Starting the no wowlan resume flow\n"); 1572 1573 mld->fw_status.in_d3 = false; 1574 iwl_fw_dbg_read_d3_debug_data(&mld->fwrt); 1575 1576 ret = iwl_mld_wait_d3_notif(mld, &resume_data, false); 1577 if (ret) 1578 return ret; 1579 1580 if (!ret && (resume_data.d3_end_flags & IWL_D0I3_RESET_REQUIRE)) 1581 return -ENODEV; 1582 1583 iwl_mld_low_latency_restart(mld); 1584 1585 return iwl_mld_update_device_power(mld, false); 1586 } 1587 1588 static void 1589 iwl_mld_aes_seq_to_le64_pn(struct ieee80211_key_conf *key, 1590 __le64 *key_rsc) 1591 { 1592 for (int i = 0; i < IWL_MAX_TID_COUNT; i++) { 1593 struct ieee80211_key_seq seq; 1594 u8 *pn = key->cipher == WLAN_CIPHER_SUITE_CCMP ? seq.ccmp.pn : 1595 seq.gcmp.pn; 1596 1597 ieee80211_get_key_rx_seq(key, i, &seq); 1598 key_rsc[i] = cpu_to_le64((u64)pn[5] | 1599 ((u64)pn[4] << 8) | 1600 ((u64)pn[3] << 16) | 1601 ((u64)pn[2] << 24) | 1602 ((u64)pn[1] << 32) | 1603 ((u64)pn[0] << 40)); 1604 } 1605 } 1606 1607 static void 1608 iwl_mld_suspend_set_ucast_pn(struct iwl_mld *mld, struct ieee80211_sta *sta, 1609 struct ieee80211_key_conf *key, __le64 *key_rsc) 1610 { 1611 struct iwl_mld_sta *mld_sta = 1612 iwl_mld_sta_from_mac80211(sta); 1613 struct iwl_mld_ptk_pn *mld_ptk_pn; 1614 1615 if (WARN_ON(key->keyidx >= ARRAY_SIZE(mld_sta->ptk_pn))) 1616 return; 1617 1618 mld_ptk_pn = wiphy_dereference(mld->wiphy, 1619 mld_sta->ptk_pn[key->keyidx]); 1620 if (WARN_ON(!mld_ptk_pn)) 1621 return; 1622 1623 for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) { 1624 struct ieee80211_key_seq seq; 1625 u8 *max_pn = seq.ccmp.pn; 1626 1627 /* get the PN from mac80211, used on the default queue */ 1628 ieee80211_get_key_rx_seq(key, tid, &seq); 1629 1630 /* and use the internal data for all queues */ 1631 for (int que = 1; que < mld->trans->info.num_rxqs; que++) { 1632 u8 *cur_pn = mld_ptk_pn->q[que].pn[tid]; 1633 1634 if (memcmp(max_pn, cur_pn, IEEE80211_CCMP_PN_LEN) < 0) 1635 max_pn = cur_pn; 1636 } 1637 key_rsc[tid] = cpu_to_le64((u64)max_pn[5] | 1638 ((u64)max_pn[4] << 8) | 1639 ((u64)max_pn[3] << 16) | 1640 ((u64)max_pn[2] << 24) | 1641 ((u64)max_pn[1] << 32) | 1642 ((u64)max_pn[0] << 40)); 1643 } 1644 } 1645 1646 static void 1647 iwl_mld_suspend_convert_tkip_ipn(struct ieee80211_key_conf *key, 1648 __le64 *rsc) 1649 { 1650 struct ieee80211_key_seq seq; 1651 1652 for (int i = 0; i < IWL_MAX_TID_COUNT; i++) { 1653 ieee80211_get_key_rx_seq(key, i, &seq); 1654 rsc[i] = 1655 cpu_to_le64(((u64)seq.tkip.iv32 << 16) | 1656 seq.tkip.iv16); 1657 } 1658 } 1659 1660 static void 1661 iwl_mld_suspend_key_data_iter(struct ieee80211_hw *hw, 1662 struct ieee80211_vif *vif, 1663 struct ieee80211_sta *sta, 1664 struct ieee80211_key_conf *key, 1665 void *_data) 1666 { 1667 struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); 1668 struct iwl_mld_suspend_key_iter_data *data = _data; 1669 __le64 *key_rsc; 1670 __le32 cipher = 0; 1671 1672 switch (key->cipher) { 1673 case WLAN_CIPHER_SUITE_CCMP: 1674 cipher = cpu_to_le32(STA_KEY_FLG_CCM); 1675 fallthrough; 1676 case WLAN_CIPHER_SUITE_GCMP: 1677 case WLAN_CIPHER_SUITE_GCMP_256: 1678 if (!cipher) 1679 cipher = cpu_to_le32(STA_KEY_FLG_GCMP); 1680 fallthrough; 1681 case WLAN_CIPHER_SUITE_TKIP: 1682 if (!cipher) 1683 cipher = cpu_to_le32(STA_KEY_FLG_TKIP); 1684 if (sta) { 1685 key_rsc = data->rsc->ucast_rsc; 1686 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) 1687 iwl_mld_suspend_convert_tkip_ipn(key, key_rsc); 1688 else 1689 iwl_mld_suspend_set_ucast_pn(mld, sta, key, 1690 key_rsc); 1691 1692 data->have_rsc = true; 1693 return; 1694 } 1695 /* We're iterating from old to new, there're 4 possible 1696 * gtk ids, and only the last two keys matter 1697 */ 1698 if (WARN_ON(data->gtks >= 1699 ARRAY_SIZE(data->found_gtk_idx))) 1700 return; 1701 1702 if (WARN_ON(key->keyidx >= 1703 ARRAY_SIZE(data->rsc->mcast_key_id_map))) 1704 return; 1705 data->gtk_cipher = cipher; 1706 data->found_gtk_idx[data->gtks] = key->keyidx; 1707 key_rsc = data->rsc->mcast_rsc[data->gtks % 2]; 1708 data->rsc->mcast_key_id_map[key->keyidx] = 1709 data->gtks % 2; 1710 1711 if (data->gtks >= 2) { 1712 int prev = data->gtks % 2; 1713 int prev_idx = data->found_gtk_idx[prev]; 1714 1715 data->rsc->mcast_key_id_map[prev_idx] = 1716 IWL_MCAST_KEY_MAP_INVALID; 1717 } 1718 1719 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) 1720 iwl_mld_suspend_convert_tkip_ipn(key, key_rsc); 1721 else 1722 iwl_mld_aes_seq_to_le64_pn(key, key_rsc); 1723 1724 data->gtks++; 1725 data->have_rsc = true; 1726 break; 1727 case WLAN_CIPHER_SUITE_BIP_GMAC_128: 1728 case WLAN_CIPHER_SUITE_BIP_GMAC_256: 1729 cipher = cpu_to_le32(STA_KEY_FLG_GCMP); 1730 fallthrough; 1731 case WLAN_CIPHER_SUITE_BIP_CMAC_256: 1732 case WLAN_CIPHER_SUITE_AES_CMAC: 1733 if (!cipher) 1734 cipher = cpu_to_le32(STA_KEY_FLG_CCM); 1735 if (key->keyidx == 4 || key->keyidx == 5) 1736 data->igtk_cipher = cipher; 1737 1738 if (key->keyidx == 6 || key->keyidx == 7) 1739 data->bigtk_cipher = cipher; 1740 1741 break; 1742 } 1743 } 1744 1745 static int 1746 iwl_mld_send_kek_kck_cmd(struct iwl_mld *mld, 1747 struct iwl_mld_vif *mld_vif, 1748 struct iwl_mld_suspend_key_iter_data data, 1749 int ap_sta_id) 1750 { 1751 struct iwl_wowlan_kek_kck_material_cmd_v4 kek_kck_cmd = {}; 1752 struct iwl_mld_rekey_data *rekey_data = 1753 &mld_vif->wowlan_data.rekey_data; 1754 1755 memcpy(kek_kck_cmd.kck, rekey_data->kck, 1756 rekey_data->kck_len); 1757 kek_kck_cmd.kck_len = cpu_to_le16(rekey_data->kck_len); 1758 memcpy(kek_kck_cmd.kek, rekey_data->kek, 1759 rekey_data->kek_len); 1760 kek_kck_cmd.kek_len = cpu_to_le16(rekey_data->kek_len); 1761 kek_kck_cmd.replay_ctr = rekey_data->replay_ctr; 1762 kek_kck_cmd.akm = cpu_to_le32(rekey_data->akm); 1763 kek_kck_cmd.sta_id = cpu_to_le32(ap_sta_id); 1764 kek_kck_cmd.gtk_cipher = data.gtk_cipher; 1765 kek_kck_cmd.igtk_cipher = data.igtk_cipher; 1766 kek_kck_cmd.bigtk_cipher = data.bigtk_cipher; 1767 1768 IWL_DEBUG_WOWLAN(mld, "setting akm %d\n", 1769 rekey_data->akm); 1770 1771 return iwl_mld_send_cmd_pdu(mld, WOWLAN_KEK_KCK_MATERIAL, 1772 &kek_kck_cmd); 1773 } 1774 1775 static int 1776 iwl_mld_suspend_send_security_cmds(struct iwl_mld *mld, 1777 struct ieee80211_vif *vif, 1778 struct iwl_mld_vif *mld_vif, 1779 int ap_sta_id) 1780 { 1781 struct iwl_mld_suspend_key_iter_data data = {}; 1782 int ret; 1783 1784 data.rsc = kzalloc_obj(*data.rsc); 1785 if (!data.rsc) 1786 return -ENOMEM; 1787 1788 memset(data.rsc->mcast_key_id_map, IWL_MCAST_KEY_MAP_INVALID, 1789 ARRAY_SIZE(data.rsc->mcast_key_id_map)); 1790 1791 data.rsc->sta_id = cpu_to_le32(ap_sta_id); 1792 ieee80211_iter_keys(mld->hw, vif, 1793 iwl_mld_suspend_key_data_iter, 1794 &data); 1795 1796 if (data.have_rsc) 1797 ret = iwl_mld_send_cmd_pdu(mld, WOWLAN_TSC_RSC_PARAM, 1798 data.rsc); 1799 else 1800 ret = 0; 1801 1802 if (!ret && mld_vif->wowlan_data.rekey_data.valid) 1803 ret = iwl_mld_send_kek_kck_cmd(mld, mld_vif, data, ap_sta_id); 1804 1805 kfree(data.rsc); 1806 1807 return ret; 1808 } 1809 1810 static void 1811 iwl_mld_set_wowlan_config_cmd(struct iwl_mld *mld, 1812 struct cfg80211_wowlan *wowlan, 1813 struct iwl_wowlan_config_cmd *wowlan_config_cmd, 1814 struct ieee80211_sta *ap_sta, 1815 struct ieee80211_bss_conf *link) 1816 { 1817 wowlan_config_cmd->is_11n_connection = 1818 ap_sta->deflink.ht_cap.ht_supported; 1819 wowlan_config_cmd->flags = ENABLE_L3_FILTERING | 1820 ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING; 1821 1822 if (ap_sta->mfp) 1823 wowlan_config_cmd->flags |= IS_11W_ASSOC; 1824 1825 if (iwl_mld_beacon_protection_enabled(mld, link)) 1826 wowlan_config_cmd->flags |= HAS_BEACON_PROTECTION; 1827 1828 if (wowlan->disconnect) 1829 wowlan_config_cmd->wakeup_filter |= 1830 cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS | 1831 IWL_WOWLAN_WAKEUP_LINK_CHANGE); 1832 if (wowlan->magic_pkt) 1833 wowlan_config_cmd->wakeup_filter |= 1834 cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET); 1835 if (wowlan->gtk_rekey_failure) 1836 wowlan_config_cmd->wakeup_filter |= 1837 cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL); 1838 if (wowlan->eap_identity_req) 1839 wowlan_config_cmd->wakeup_filter |= 1840 cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ); 1841 if (wowlan->four_way_handshake) 1842 wowlan_config_cmd->wakeup_filter |= 1843 cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE); 1844 if (wowlan->n_patterns) 1845 wowlan_config_cmd->wakeup_filter |= 1846 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH); 1847 1848 if (wowlan->rfkill_release) 1849 wowlan_config_cmd->wakeup_filter |= 1850 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); 1851 1852 if (wowlan->any) { 1853 wowlan_config_cmd->wakeup_filter |= 1854 cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS | 1855 IWL_WOWLAN_WAKEUP_LINK_CHANGE | 1856 IWL_WOWLAN_WAKEUP_RX_FRAME | 1857 IWL_WOWLAN_WAKEUP_BCN_FILTERING); 1858 } 1859 } 1860 1861 static int iwl_mld_send_patterns(struct iwl_mld *mld, 1862 struct cfg80211_wowlan *wowlan, 1863 int ap_sta_id) 1864 { 1865 struct iwl_wowlan_patterns_cmd *pattern_cmd; 1866 struct iwl_host_cmd cmd = { 1867 .id = WOWLAN_PATTERNS, 1868 .dataflags[0] = IWL_HCMD_DFL_NOCOPY, 1869 }; 1870 int ret; 1871 1872 if (!wowlan->n_patterns) 1873 return 0; 1874 1875 cmd.len[0] = struct_size(pattern_cmd, patterns, wowlan->n_patterns); 1876 1877 pattern_cmd = kzalloc(cmd.len[0], GFP_KERNEL); 1878 if (!pattern_cmd) 1879 return -ENOMEM; 1880 1881 pattern_cmd->n_patterns = wowlan->n_patterns; 1882 pattern_cmd->sta_id = ap_sta_id; 1883 1884 for (int i = 0; i < wowlan->n_patterns; i++) { 1885 int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8); 1886 1887 pattern_cmd->patterns[i].pattern_type = 1888 WOWLAN_PATTERN_TYPE_BITMASK; 1889 1890 memcpy(&pattern_cmd->patterns[i].u.bitmask.mask, 1891 wowlan->patterns[i].mask, mask_len); 1892 memcpy(&pattern_cmd->patterns[i].u.bitmask.pattern, 1893 wowlan->patterns[i].pattern, 1894 wowlan->patterns[i].pattern_len); 1895 pattern_cmd->patterns[i].u.bitmask.mask_size = mask_len; 1896 pattern_cmd->patterns[i].u.bitmask.pattern_size = 1897 wowlan->patterns[i].pattern_len; 1898 } 1899 1900 cmd.data[0] = pattern_cmd; 1901 ret = iwl_mld_send_cmd(mld, &cmd); 1902 kfree(pattern_cmd); 1903 return ret; 1904 } 1905 1906 static int 1907 iwl_mld_send_proto_offload(struct iwl_mld *mld, 1908 struct ieee80211_vif *vif, 1909 u8 ap_sta_id) 1910 { 1911 struct iwl_proto_offload_cmd_v4 *cmd __free(kfree); 1912 struct iwl_host_cmd hcmd = { 1913 .id = PROT_OFFLOAD_CONFIG_CMD, 1914 .dataflags[0] = IWL_HCMD_DFL_NOCOPY, 1915 .len[0] = sizeof(*cmd), 1916 }; 1917 u32 enabled = 0; 1918 1919 cmd = kzalloc(hcmd.len[0], GFP_KERNEL); 1920 if (!cmd) { 1921 IWL_DEBUG_WOWLAN(mld, "Failed to allocate proto offload cmd\n"); 1922 return -ENOMEM; 1923 } 1924 1925 #if IS_ENABLED(CONFIG_IPV6) 1926 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); 1927 struct iwl_mld_wowlan_data *wowlan_data = &mld_vif->wowlan_data; 1928 struct iwl_ns_config *nsc; 1929 struct iwl_targ_addr *addrs; 1930 int n_nsc, n_addrs; 1931 int i, c; 1932 int num_skipped = 0; 1933 1934 nsc = cmd->ns_config; 1935 n_nsc = IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L; 1936 addrs = cmd->targ_addrs; 1937 n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L; 1938 1939 /* For each address we have (and that will fit) fill a target 1940 * address struct and combine for NS offload structs with the 1941 * solicited node addresses. 1942 */ 1943 for (i = 0, c = 0; 1944 i < wowlan_data->num_target_ipv6_addrs && 1945 i < n_addrs && c < n_nsc; i++) { 1946 int j; 1947 struct in6_addr solicited_addr; 1948 1949 /* Because ns is offloaded skip tentative address to avoid 1950 * violating RFC4862. 1951 */ 1952 if (test_bit(i, wowlan_data->tentative_addrs)) { 1953 num_skipped++; 1954 continue; 1955 } 1956 1957 addrconf_addr_solict_mult(&wowlan_data->target_ipv6_addrs[i], 1958 &solicited_addr); 1959 for (j = 0; j < n_nsc && j < c; j++) 1960 if (ipv6_addr_cmp(&nsc[j].dest_ipv6_addr, 1961 &solicited_addr) == 0) 1962 break; 1963 if (j == c) 1964 c++; 1965 addrs[i].addr = wowlan_data->target_ipv6_addrs[i]; 1966 addrs[i].config_num = cpu_to_le32(j); 1967 nsc[j].dest_ipv6_addr = solicited_addr; 1968 memcpy(nsc[j].target_mac_addr, vif->addr, ETH_ALEN); 1969 } 1970 1971 if (wowlan_data->num_target_ipv6_addrs - num_skipped) 1972 enabled |= IWL_D3_PROTO_IPV6_VALID; 1973 1974 cmd->num_valid_ipv6_addrs = cpu_to_le32(i - num_skipped); 1975 if (enabled & IWL_D3_PROTO_IPV6_VALID) 1976 enabled |= IWL_D3_PROTO_OFFLOAD_NS; 1977 #endif 1978 1979 if (vif->cfg.arp_addr_cnt) { 1980 enabled |= IWL_D3_PROTO_OFFLOAD_ARP | IWL_D3_PROTO_IPV4_VALID; 1981 cmd->common.host_ipv4_addr = vif->cfg.arp_addr_list[0]; 1982 ether_addr_copy(cmd->common.arp_mac_addr, vif->addr); 1983 } 1984 1985 enabled |= IWL_D3_PROTO_OFFLOAD_BTM; 1986 cmd->common.enabled = cpu_to_le32(enabled); 1987 cmd->sta_id = cpu_to_le32(ap_sta_id); 1988 hcmd.data[0] = cmd; 1989 return iwl_mld_send_cmd(mld, &hcmd); 1990 } 1991 1992 static int 1993 iwl_mld_wowlan_config(struct iwl_mld *mld, struct ieee80211_vif *bss_vif, 1994 struct cfg80211_wowlan *wowlan) 1995 { 1996 struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(bss_vif); 1997 struct ieee80211_sta *ap_sta = mld_vif->ap_sta; 1998 struct iwl_wowlan_config_cmd wowlan_config_cmd = { 1999 .offloading_tid = IWL_WOWLAN_OFFLOAD_TID, 2000 }; 2001 u32 sta_id_mask; 2002 int ap_sta_id, ret; 2003 int link_id = iwl_mld_get_primary_link(bss_vif); 2004 struct ieee80211_bss_conf *link_conf; 2005 2006 ret = iwl_mld_block_emlsr_sync(mld, bss_vif, 2007 IWL_MLD_EMLSR_BLOCKED_WOWLAN, link_id); 2008 if (ret) 2009 return ret; 2010 2011 link_conf = link_conf_dereference_protected(bss_vif, link_id); 2012 2013 if (WARN_ON(!ap_sta || !link_conf)) 2014 return -EINVAL; 2015 2016 sta_id_mask = iwl_mld_fw_sta_id_mask(mld, ap_sta); 2017 if (WARN_ON(hweight32(sta_id_mask) != 1)) 2018 return -EINVAL; 2019 2020 ap_sta_id = __ffs(sta_id_mask); 2021 wowlan_config_cmd.sta_id = ap_sta_id; 2022 2023 ret = iwl_mld_ensure_queue(mld, 2024 ap_sta->txq[wowlan_config_cmd.offloading_tid]); 2025 if (ret) 2026 return ret; 2027 2028 iwl_mld_set_wowlan_config_cmd(mld, wowlan, 2029 &wowlan_config_cmd, ap_sta, link_conf); 2030 ret = iwl_mld_send_cmd_pdu(mld, WOWLAN_CONFIGURATION, 2031 &wowlan_config_cmd); 2032 if (ret) 2033 return ret; 2034 2035 ret = iwl_mld_suspend_send_security_cmds(mld, bss_vif, mld_vif, 2036 ap_sta_id); 2037 if (ret) 2038 return ret; 2039 2040 ret = iwl_mld_send_patterns(mld, wowlan, ap_sta_id); 2041 if (ret) 2042 return ret; 2043 2044 ret = iwl_mld_send_proto_offload(mld, bss_vif, ap_sta_id); 2045 if (ret) 2046 return ret; 2047 2048 iwl_mld_enable_beacon_filter(mld, link_conf, true); 2049 return iwl_mld_update_mac_power(mld, bss_vif, true); 2050 } 2051 2052 int iwl_mld_wowlan_suspend(struct iwl_mld *mld, struct cfg80211_wowlan *wowlan) 2053 { 2054 struct ieee80211_vif *bss_vif; 2055 2056 lockdep_assert_wiphy(mld->wiphy); 2057 2058 if (WARN_ON(!wowlan)) 2059 return 1; 2060 2061 bss_vif = iwl_mld_get_bss_vif(mld); 2062 if (!bss_vif) 2063 return 1; 2064 2065 IWL_DEBUG_WOWLAN(mld, "Starting the wowlan suspend flow\n"); 2066 2067 if (!bss_vif->cfg.assoc) { 2068 int ret; 2069 /* 2070 * If not associated we can only do netdetect, if 2071 * that's not enabled then just suspend normally. 2072 */ 2073 if (!wowlan->nd_config) 2074 return 1; 2075 2076 ret = iwl_mld_netdetect_config(mld, bss_vif, wowlan); 2077 if (!ret) 2078 mld->netdetect = true; 2079 2080 return ret; 2081 } 2082 2083 return iwl_mld_wowlan_config(mld, bss_vif, wowlan); 2084 } 2085 2086 /* Returns 0 on success, 1 if an error occurred in firmware during d3, 2087 * A negative value is expected only in unrecovreable cases. 2088 */ 2089 int iwl_mld_wowlan_resume(struct iwl_mld *mld) 2090 { 2091 struct ieee80211_vif *bss_vif; 2092 struct ieee80211_bss_conf *link_conf; 2093 struct iwl_mld_netdetect_res netdetect_res; 2094 struct iwl_mld_resume_data resume_data = { 2095 .notifs_expected = 2096 IWL_D3_NOTIF_WOWLAN_INFO | 2097 IWL_D3_NOTIF_D3_END_NOTIF, 2098 .netdetect_res = &netdetect_res, 2099 }; 2100 int link_id; 2101 int ret; 2102 2103 lockdep_assert_wiphy(mld->wiphy); 2104 2105 IWL_DEBUG_WOWLAN(mld, "Starting the wowlan resume flow\n"); 2106 2107 if (!mld->fw_status.in_d3) { 2108 IWL_DEBUG_WOWLAN(mld, 2109 "Device_powered_off() was called during wowlan\n"); 2110 goto err; 2111 } 2112 2113 mld->fw_status.resuming = true; 2114 mld->fw_status.in_d3 = false; 2115 mld->scan.last_start_time_jiffies = jiffies; 2116 2117 bss_vif = iwl_mld_get_bss_vif(mld); 2118 if (WARN_ON(!bss_vif)) 2119 goto err; 2120 2121 /* We can't have several links upon wowlan entry, 2122 * this is enforced in the suspend flow. 2123 */ 2124 WARN_ON(hweight16(bss_vif->active_links) > 1); 2125 link_id = bss_vif->active_links ? __ffs(bss_vif->active_links) : 0; 2126 link_conf = link_conf_dereference_protected(bss_vif, link_id); 2127 2128 if (WARN_ON(!link_conf)) 2129 goto err; 2130 2131 iwl_fw_dbg_read_d3_debug_data(&mld->fwrt); 2132 2133 resume_data.wowlan_status = kzalloc_obj(*resume_data.wowlan_status); 2134 if (!resume_data.wowlan_status) 2135 return -ENOMEM; 2136 2137 if (mld->netdetect) 2138 resume_data.notifs_expected |= IWL_D3_ND_MATCH_INFO; 2139 2140 ret = iwl_mld_wait_d3_notif(mld, &resume_data, true); 2141 if (ret) { 2142 IWL_ERR(mld, "Couldn't get the d3 notifs %d\n", ret); 2143 goto err; 2144 } 2145 2146 if (resume_data.d3_end_flags & IWL_D0I3_RESET_REQUIRE) { 2147 mld->fw_status.in_hw_restart = true; 2148 goto process_wakeup_results; 2149 } 2150 2151 iwl_mld_update_changed_regdomain(mld); 2152 iwl_mld_update_mac_power(mld, bss_vif, false); 2153 iwl_mld_enable_beacon_filter(mld, link_conf, false); 2154 iwl_mld_update_device_power(mld, false); 2155 2156 if (mld->netdetect) 2157 ret = iwl_mld_scan_stop(mld, IWL_MLD_SCAN_NETDETECT, false); 2158 2159 process_wakeup_results: 2160 if (mld->netdetect) { 2161 iwl_mld_process_netdetect_res(mld, bss_vif, &resume_data); 2162 mld->netdetect = false; 2163 } else { 2164 bool keep_connection = 2165 iwl_mld_process_wowlan_status(mld, bss_vif, 2166 resume_data.wowlan_status); 2167 2168 /* EMLSR state will be cleared if the connection is not kept */ 2169 if (keep_connection) 2170 iwl_mld_unblock_emlsr(mld, bss_vif, 2171 IWL_MLD_EMLSR_BLOCKED_WOWLAN); 2172 else 2173 ieee80211_resume_disconnect(bss_vif); 2174 } 2175 2176 goto out; 2177 2178 err: 2179 mld->fw_status.in_hw_restart = true; 2180 ret = 1; 2181 out: 2182 mld->fw_status.resuming = false; 2183 2184 if (resume_data.wowlan_status) { 2185 kfree(resume_data.wowlan_status->wake_packet); 2186 kfree(resume_data.wowlan_status); 2187 } 2188 2189 return ret; 2190 } 2191