1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* Copyright(c) 2019-2022 Realtek Corporation 3 */ 4 #include "cam.h" 5 #include "core.h" 6 #include "debug.h" 7 #include "fw.h" 8 #include "mac.h" 9 #include "phy.h" 10 #include "ps.h" 11 #include "reg.h" 12 #include "util.h" 13 #include "wow.h" 14 15 void __rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb) 16 { 17 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; 18 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 19 size_t hdr_len = offsetof(struct ieee80211_mgmt, u.assoc_req.variable); 20 const u8 *rsn, *ies = mgmt->u.assoc_req.variable; 21 struct rtw89_rsn_ie *rsn_ie; 22 23 if (skb->len < hdr_len) 24 return; 25 26 rsn = cfg80211_find_ie(WLAN_EID_RSN, ies, skb->len - hdr_len); 27 if (!rsn) 28 return; 29 30 rsn_ie = (struct rtw89_rsn_ie *)rsn; 31 rtw_wow->akm = rsn_ie->akm_cipher_suite.type; 32 } 33 34 #define RTW89_CIPHER_INFO_DEF(cipher) \ 35 {WLAN_CIPHER_SUITE_ ## cipher, .fw_alg = RTW89_WOW_FW_ALG_ ## cipher, \ 36 .len = WLAN_KEY_LEN_ ## cipher} 37 38 static const struct rtw89_cipher_info rtw89_cipher_info_defs[] = { 39 RTW89_CIPHER_INFO_DEF(WEP40), 40 RTW89_CIPHER_INFO_DEF(WEP104), 41 RTW89_CIPHER_INFO_DEF(TKIP), 42 RTW89_CIPHER_INFO_DEF(CCMP), 43 RTW89_CIPHER_INFO_DEF(GCMP), 44 RTW89_CIPHER_INFO_DEF(CCMP_256), 45 RTW89_CIPHER_INFO_DEF(GCMP_256), 46 RTW89_CIPHER_INFO_DEF(AES_CMAC), 47 }; 48 49 #undef RTW89_CIPHER_INFO_DEF 50 51 static const 52 struct rtw89_cipher_info *rtw89_cipher_alg_recognize(u32 cipher) 53 { 54 const struct rtw89_cipher_info *cipher_info_defs; 55 int i; 56 57 for (i = 0; i < ARRAY_SIZE(rtw89_cipher_info_defs); i++) { 58 cipher_info_defs = &rtw89_cipher_info_defs[i]; 59 if (cipher_info_defs->cipher == cipher) 60 return cipher_info_defs; 61 } 62 63 return NULL; 64 } 65 66 static int _pn_to_iv(struct rtw89_dev *rtwdev, struct ieee80211_key_conf *key, 67 u8 *iv, u64 pn, u8 key_idx) 68 { 69 switch (key->cipher) { 70 case WLAN_CIPHER_SUITE_TKIP: 71 iv[0] = u64_get_bits(pn, RTW89_KEY_PN_1); 72 iv[1] = (u64_get_bits(pn, RTW89_KEY_PN_1) | 0x20) & 0x7f; 73 iv[2] = u64_get_bits(pn, RTW89_KEY_PN_0); 74 break; 75 case WLAN_CIPHER_SUITE_CCMP: 76 case WLAN_CIPHER_SUITE_GCMP: 77 case WLAN_CIPHER_SUITE_CCMP_256: 78 case WLAN_CIPHER_SUITE_GCMP_256: 79 iv[0] = u64_get_bits(pn, RTW89_KEY_PN_0); 80 iv[1] = u64_get_bits(pn, RTW89_KEY_PN_1); 81 iv[2] = 0; 82 break; 83 default: 84 return -EINVAL; 85 } 86 87 iv[3] = BIT(5) | ((key_idx & 0x3) << 6); 88 iv[4] = u64_get_bits(pn, RTW89_KEY_PN_2); 89 iv[5] = u64_get_bits(pn, RTW89_KEY_PN_3); 90 iv[6] = u64_get_bits(pn, RTW89_KEY_PN_4); 91 iv[7] = u64_get_bits(pn, RTW89_KEY_PN_5); 92 93 return 0; 94 } 95 96 static int rtw89_rx_pn_to_iv(struct rtw89_dev *rtwdev, 97 struct ieee80211_key_conf *key, 98 u8 *iv) 99 { 100 struct ieee80211_key_seq seq; 101 int err; 102 u64 pn; 103 104 ieee80211_get_key_rx_seq(key, 0, &seq); 105 106 switch (key->cipher) { 107 case WLAN_CIPHER_SUITE_TKIP: 108 pn = u64_encode_bits(seq.tkip.iv32, RTW89_KEY_TKIP_PN_IV32) | 109 u64_encode_bits(seq.tkip.iv16, RTW89_KEY_TKIP_PN_IV16); 110 break; 111 case WLAN_CIPHER_SUITE_CCMP: 112 case WLAN_CIPHER_SUITE_GCMP: 113 case WLAN_CIPHER_SUITE_CCMP_256: 114 case WLAN_CIPHER_SUITE_GCMP_256: 115 /* seq.ccmp.pn[] is BE order array */ 116 pn = u64_encode_bits(seq.ccmp.pn[0], RTW89_KEY_PN_5) | 117 u64_encode_bits(seq.ccmp.pn[1], RTW89_KEY_PN_4) | 118 u64_encode_bits(seq.ccmp.pn[2], RTW89_KEY_PN_3) | 119 u64_encode_bits(seq.ccmp.pn[3], RTW89_KEY_PN_2) | 120 u64_encode_bits(seq.ccmp.pn[4], RTW89_KEY_PN_1) | 121 u64_encode_bits(seq.ccmp.pn[5], RTW89_KEY_PN_0); 122 break; 123 default: 124 return -EINVAL; 125 } 126 127 err = _pn_to_iv(rtwdev, key, iv, pn, key->keyidx); 128 if (err) 129 return err; 130 131 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx to iv-%*ph\n", 132 __func__, key->keyidx, pn, 8, iv); 133 134 return 0; 135 } 136 137 static int rtw89_tx_pn_to_iv(struct rtw89_dev *rtwdev, 138 struct ieee80211_key_conf *key, 139 u8 *iv) 140 { 141 int err; 142 u64 pn; 143 144 pn = atomic64_inc_return(&key->tx_pn); 145 err = _pn_to_iv(rtwdev, key, iv, pn, key->keyidx); 146 if (err) 147 return err; 148 149 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx to iv-%*ph\n", 150 __func__, key->keyidx, pn, 8, iv); 151 152 return 0; 153 } 154 155 static int _iv_to_pn(struct rtw89_dev *rtwdev, u8 *iv, u64 *pn, u8 *key_id, 156 struct ieee80211_key_conf *key) 157 { 158 switch (key->cipher) { 159 case WLAN_CIPHER_SUITE_TKIP: 160 *pn = u64_encode_bits(iv[2], RTW89_KEY_PN_0) | 161 u64_encode_bits(iv[0], RTW89_KEY_PN_1); 162 break; 163 case WLAN_CIPHER_SUITE_CCMP: 164 case WLAN_CIPHER_SUITE_GCMP: 165 case WLAN_CIPHER_SUITE_CCMP_256: 166 case WLAN_CIPHER_SUITE_GCMP_256: 167 *pn = u64_encode_bits(iv[0], RTW89_KEY_PN_0) | 168 u64_encode_bits(iv[1], RTW89_KEY_PN_1); 169 break; 170 default: 171 return -EINVAL; 172 } 173 174 *pn |= u64_encode_bits(iv[4], RTW89_KEY_PN_2) | 175 u64_encode_bits(iv[5], RTW89_KEY_PN_3) | 176 u64_encode_bits(iv[6], RTW89_KEY_PN_4) | 177 u64_encode_bits(iv[7], RTW89_KEY_PN_5); 178 179 if (key_id) 180 *key_id = *(iv + 3) >> 6; 181 182 return 0; 183 } 184 185 static int rtw89_rx_iv_to_pn(struct rtw89_dev *rtwdev, 186 struct ieee80211_key_conf *key, 187 u8 *iv) 188 { 189 struct ieee80211_key_seq seq; 190 int err; 191 u64 pn; 192 193 err = _iv_to_pn(rtwdev, iv, &pn, NULL, key); 194 if (err) 195 return err; 196 197 switch (key->cipher) { 198 case WLAN_CIPHER_SUITE_TKIP: 199 seq.tkip.iv32 = u64_get_bits(pn, RTW89_KEY_TKIP_PN_IV32); 200 seq.tkip.iv16 = u64_get_bits(pn, RTW89_KEY_TKIP_PN_IV16); 201 break; 202 case WLAN_CIPHER_SUITE_CCMP: 203 case WLAN_CIPHER_SUITE_GCMP: 204 case WLAN_CIPHER_SUITE_CCMP_256: 205 case WLAN_CIPHER_SUITE_GCMP_256: 206 /* seq.ccmp.pn[] is BE order array */ 207 seq.ccmp.pn[0] = u64_get_bits(pn, RTW89_KEY_PN_5); 208 seq.ccmp.pn[1] = u64_get_bits(pn, RTW89_KEY_PN_4); 209 seq.ccmp.pn[2] = u64_get_bits(pn, RTW89_KEY_PN_3); 210 seq.ccmp.pn[3] = u64_get_bits(pn, RTW89_KEY_PN_2); 211 seq.ccmp.pn[4] = u64_get_bits(pn, RTW89_KEY_PN_1); 212 seq.ccmp.pn[5] = u64_get_bits(pn, RTW89_KEY_PN_0); 213 break; 214 default: 215 return -EINVAL; 216 } 217 218 ieee80211_set_key_rx_seq(key, 0, &seq); 219 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d iv-%*ph to pn-%*ph\n", 220 __func__, key->keyidx, 8, iv, 6, seq.ccmp.pn); 221 222 return 0; 223 } 224 225 static int rtw89_tx_iv_to_pn(struct rtw89_dev *rtwdev, 226 struct ieee80211_key_conf *key, 227 u8 *iv) 228 { 229 int err; 230 u64 pn; 231 232 err = _iv_to_pn(rtwdev, iv, &pn, NULL, key); 233 if (err) 234 return err; 235 236 atomic64_set(&key->tx_pn, pn); 237 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d iv-%*ph to pn-%llx\n", 238 __func__, key->keyidx, 8, iv, pn); 239 240 return 0; 241 } 242 243 static int rtw89_rx_pn_get_pmf(struct rtw89_dev *rtwdev, 244 struct ieee80211_key_conf *key, 245 struct rtw89_wow_gtk_info *gtk_info) 246 { 247 struct ieee80211_key_seq seq; 248 u64 pn; 249 250 if (key->keyidx == 4) 251 memcpy(gtk_info->igtk[0], key->key, key->keylen); 252 else if (key->keyidx == 5) 253 memcpy(gtk_info->igtk[1], key->key, key->keylen); 254 else 255 return -EINVAL; 256 257 ieee80211_get_key_rx_seq(key, 0, &seq); 258 259 /* seq.ccmp.pn[] is BE order array */ 260 pn = u64_encode_bits(seq.ccmp.pn[0], RTW89_KEY_PN_5) | 261 u64_encode_bits(seq.ccmp.pn[1], RTW89_KEY_PN_4) | 262 u64_encode_bits(seq.ccmp.pn[2], RTW89_KEY_PN_3) | 263 u64_encode_bits(seq.ccmp.pn[3], RTW89_KEY_PN_2) | 264 u64_encode_bits(seq.ccmp.pn[4], RTW89_KEY_PN_1) | 265 u64_encode_bits(seq.ccmp.pn[5], RTW89_KEY_PN_0); 266 gtk_info->ipn = cpu_to_le64(pn); 267 gtk_info->igtk_keyid = cpu_to_le32(key->keyidx); 268 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx\n", 269 __func__, key->keyidx, pn); 270 271 return 0; 272 } 273 274 static int rtw89_rx_pn_set_pmf(struct rtw89_dev *rtwdev, 275 struct ieee80211_key_conf *key, 276 u64 pn) 277 { 278 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 279 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; 280 struct ieee80211_key_seq seq; 281 282 if (key->keyidx != aoac_rpt->igtk_key_id) 283 return 0; 284 285 /* seq.ccmp.pn[] is BE order array */ 286 seq.ccmp.pn[0] = u64_get_bits(pn, RTW89_KEY_PN_5); 287 seq.ccmp.pn[1] = u64_get_bits(pn, RTW89_KEY_PN_4); 288 seq.ccmp.pn[2] = u64_get_bits(pn, RTW89_KEY_PN_3); 289 seq.ccmp.pn[3] = u64_get_bits(pn, RTW89_KEY_PN_2); 290 seq.ccmp.pn[4] = u64_get_bits(pn, RTW89_KEY_PN_1); 291 seq.ccmp.pn[5] = u64_get_bits(pn, RTW89_KEY_PN_0); 292 293 ieee80211_set_key_rx_seq(key, 0, &seq); 294 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%*ph\n", 295 __func__, key->keyidx, 6, seq.ccmp.pn); 296 297 return 0; 298 } 299 300 static void rtw89_wow_get_key_info_iter(struct ieee80211_hw *hw, 301 struct ieee80211_vif *vif, 302 struct ieee80211_sta *sta, 303 struct ieee80211_key_conf *key, 304 void *data) 305 { 306 struct rtw89_dev *rtwdev = hw->priv; 307 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 308 struct rtw89_wow_key_info *key_info = &rtw_wow->key_info; 309 struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info; 310 const struct rtw89_cipher_info *cipher_info; 311 bool *err = data; 312 int ret; 313 314 cipher_info = rtw89_cipher_alg_recognize(key->cipher); 315 316 switch (key->cipher) { 317 case WLAN_CIPHER_SUITE_TKIP: 318 if (sta) 319 memcpy(gtk_info->txmickey, 320 key->key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY, 321 sizeof(gtk_info->txmickey)); 322 fallthrough; 323 case WLAN_CIPHER_SUITE_CCMP: 324 case WLAN_CIPHER_SUITE_GCMP: 325 case WLAN_CIPHER_SUITE_CCMP_256: 326 case WLAN_CIPHER_SUITE_GCMP_256: 327 if (sta) { 328 ret = rtw89_tx_pn_to_iv(rtwdev, key, 329 key_info->ptk_tx_iv); 330 if (ret) 331 goto err; 332 ret = rtw89_rx_pn_to_iv(rtwdev, key, 333 key_info->ptk_rx_iv); 334 if (ret) 335 goto err; 336 337 rtw_wow->ptk_alg = cipher_info->fw_alg; 338 rtw_wow->ptk_keyidx = key->keyidx; 339 } else { 340 ret = rtw89_rx_pn_to_iv(rtwdev, key, 341 key_info->gtk_rx_iv[key->keyidx]); 342 if (ret) 343 goto err; 344 345 rtw_wow->gtk_alg = cipher_info->fw_alg; 346 key_info->gtk_keyidx = key->keyidx; 347 } 348 break; 349 case WLAN_CIPHER_SUITE_AES_CMAC: 350 ret = rtw89_rx_pn_get_pmf(rtwdev, key, gtk_info); 351 if (ret) 352 goto err; 353 break; 354 case WLAN_CIPHER_SUITE_WEP40: 355 case WLAN_CIPHER_SUITE_WEP104: 356 /* WEP only set group key in mac80211, but fw need to set 357 * both of pairwise key and group key. 358 */ 359 rtw_wow->ptk_alg = cipher_info->fw_alg; 360 rtw_wow->ptk_keyidx = key->keyidx; 361 rtw_wow->gtk_alg = cipher_info->fw_alg; 362 key_info->gtk_keyidx = key->keyidx; 363 break; 364 default: 365 rtw89_debug(rtwdev, RTW89_DBG_WOW, "unsupported cipher %x\n", 366 key->cipher); 367 goto err; 368 } 369 370 return; 371 err: 372 *err = true; 373 } 374 375 static void rtw89_wow_set_key_info_iter(struct ieee80211_hw *hw, 376 struct ieee80211_vif *vif, 377 struct ieee80211_sta *sta, 378 struct ieee80211_key_conf *key, 379 void *data) 380 { 381 struct rtw89_dev *rtwdev = hw->priv; 382 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 383 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; 384 struct rtw89_set_key_info_iter_data *iter_data = data; 385 bool update_tx_key_info = iter_data->rx_ready; 386 u8 tmp[RTW89_MIC_KEY_LEN]; 387 int ret; 388 389 switch (key->cipher) { 390 case WLAN_CIPHER_SUITE_TKIP: 391 /* 392 * TX MIC KEY and RX MIC KEY is oppsite in FW, 393 * need to swap it before sending to mac80211. 394 */ 395 if (!sta && update_tx_key_info && aoac_rpt->rekey_ok && 396 !iter_data->tkip_gtk_swapped) { 397 memcpy(tmp, &aoac_rpt->gtk[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], 398 RTW89_MIC_KEY_LEN); 399 memcpy(&aoac_rpt->gtk[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], 400 &aoac_rpt->gtk[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], 401 RTW89_MIC_KEY_LEN); 402 memcpy(&aoac_rpt->gtk[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], 403 tmp, RTW89_MIC_KEY_LEN); 404 iter_data->tkip_gtk_swapped = true; 405 } 406 fallthrough; 407 case WLAN_CIPHER_SUITE_CCMP: 408 case WLAN_CIPHER_SUITE_GCMP: 409 case WLAN_CIPHER_SUITE_CCMP_256: 410 case WLAN_CIPHER_SUITE_GCMP_256: 411 if (sta && !update_tx_key_info) { 412 ret = rtw89_rx_iv_to_pn(rtwdev, key, 413 aoac_rpt->ptk_rx_iv); 414 if (ret) 415 goto err; 416 } 417 418 if (sta && update_tx_key_info) { 419 ret = rtw89_tx_iv_to_pn(rtwdev, key, 420 aoac_rpt->ptk_tx_iv); 421 if (ret) 422 goto err; 423 } 424 425 if (!sta && !update_tx_key_info) { 426 ret = rtw89_rx_iv_to_pn(rtwdev, key, 427 aoac_rpt->gtk_rx_iv[key->keyidx]); 428 if (ret) 429 goto err; 430 } 431 432 if (!sta && update_tx_key_info && aoac_rpt->rekey_ok) 433 iter_data->gtk_cipher = key->cipher; 434 break; 435 case WLAN_CIPHER_SUITE_AES_CMAC: 436 if (update_tx_key_info) { 437 if (aoac_rpt->rekey_ok) 438 iter_data->igtk_cipher = key->cipher; 439 } else { 440 ret = rtw89_rx_pn_set_pmf(rtwdev, key, 441 aoac_rpt->igtk_ipn); 442 if (ret) 443 goto err; 444 } 445 break; 446 case WLAN_CIPHER_SUITE_WEP40: 447 case WLAN_CIPHER_SUITE_WEP104: 448 break; 449 default: 450 rtw89_debug(rtwdev, RTW89_DBG_WOW, "unsupported cipher %x\n", 451 key->cipher); 452 goto err; 453 } 454 455 return; 456 457 err: 458 iter_data->error = true; 459 } 460 461 static void rtw89_wow_key_clear(struct rtw89_dev *rtwdev) 462 { 463 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 464 465 memset(&rtw_wow->aoac_rpt, 0, sizeof(rtw_wow->aoac_rpt)); 466 memset(&rtw_wow->gtk_info, 0, sizeof(rtw_wow->gtk_info)); 467 memset(&rtw_wow->key_info, 0, sizeof(rtw_wow->key_info)); 468 rtw_wow->ptk_alg = 0; 469 rtw_wow->gtk_alg = 0; 470 } 471 472 static void rtw89_wow_construct_key_info(struct rtw89_dev *rtwdev) 473 { 474 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 475 struct rtw89_wow_key_info *key_info = &rtw_wow->key_info; 476 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; 477 struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); 478 bool err = false; 479 480 ieee80211_iter_keys(rtwdev->hw, wow_vif, 481 rtw89_wow_get_key_info_iter, &err); 482 483 if (err) { 484 rtw89_wow_key_clear(rtwdev); 485 return; 486 } 487 488 key_info->valid_check = RTW89_WOW_VALID_CHECK; 489 key_info->symbol_check_en = RTW89_WOW_SYMBOL_CHK_PTK | 490 RTW89_WOW_SYMBOL_CHK_GTK; 491 } 492 493 static void rtw89_wow_debug_aoac_rpt(struct rtw89_dev *rtwdev) 494 { 495 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 496 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; 497 498 if (!rtw89_debug_is_enabled(rtwdev, RTW89_DBG_WOW)) 499 return; 500 501 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] rpt_ver = %d\n", 502 aoac_rpt->rpt_ver); 503 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] sec_type = %d\n", 504 aoac_rpt->sec_type); 505 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] key_idx = %d\n", 506 aoac_rpt->key_idx); 507 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] pattern_idx = %d\n", 508 aoac_rpt->pattern_idx); 509 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] rekey_ok = %d\n", 510 aoac_rpt->rekey_ok); 511 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] ptk_tx_iv = %*ph\n", 512 8, aoac_rpt->ptk_tx_iv); 513 rtw89_debug(rtwdev, RTW89_DBG_WOW, 514 "[aoac_rpt] eapol_key_replay_count = %*ph\n", 515 8, aoac_rpt->eapol_key_replay_count); 516 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] ptk_rx_iv = %*ph\n", 517 8, aoac_rpt->ptk_rx_iv); 518 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[0] = %*ph\n", 519 8, aoac_rpt->gtk_rx_iv[0]); 520 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[1] = %*ph\n", 521 8, aoac_rpt->gtk_rx_iv[1]); 522 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[2] = %*ph\n", 523 8, aoac_rpt->gtk_rx_iv[2]); 524 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] gtk_rx_iv[3] = %*ph\n", 525 8, aoac_rpt->gtk_rx_iv[3]); 526 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] igtk_key_id = %llu\n", 527 aoac_rpt->igtk_key_id); 528 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] igtk_ipn = %llu\n", 529 aoac_rpt->igtk_ipn); 530 rtw89_debug(rtwdev, RTW89_DBG_WOW, "[aoac_rpt] igtk = %*ph\n", 531 32, aoac_rpt->igtk); 532 } 533 534 static int rtw89_wow_get_aoac_rpt_reg(struct rtw89_dev *rtwdev) 535 { 536 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 537 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; 538 struct rtw89_mac_c2h_info c2h_info = {}; 539 struct rtw89_mac_h2c_info h2c_info = {}; 540 u8 igtk_ipn[8]; 541 u8 key_idx; 542 int ret; 543 544 h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_1; 545 h2c_info.content_len = 2; 546 ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info); 547 if (ret) 548 return ret; 549 550 aoac_rpt->key_idx = 551 u32_get_bits(c2h_info.u.c2hreg[0], RTW89_C2HREG_AOAC_RPT_1_W0_KEY_IDX); 552 key_idx = aoac_rpt->key_idx; 553 if (key_idx >= ARRAY_SIZE(aoac_rpt->gtk_rx_iv)) 554 return -EINVAL; 555 556 aoac_rpt->gtk_rx_iv[key_idx][0] = 557 u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_0); 558 aoac_rpt->gtk_rx_iv[key_idx][1] = 559 u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_1); 560 aoac_rpt->gtk_rx_iv[key_idx][2] = 561 u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_2); 562 aoac_rpt->gtk_rx_iv[key_idx][3] = 563 u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_1_W1_IV_3); 564 aoac_rpt->gtk_rx_iv[key_idx][4] = 565 u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_4); 566 aoac_rpt->gtk_rx_iv[key_idx][5] = 567 u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_5); 568 aoac_rpt->gtk_rx_iv[key_idx][6] = 569 u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_6); 570 aoac_rpt->gtk_rx_iv[key_idx][7] = 571 u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_1_W2_IV_7); 572 aoac_rpt->ptk_rx_iv[0] = 573 u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_0); 574 aoac_rpt->ptk_rx_iv[1] = 575 u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_1); 576 aoac_rpt->ptk_rx_iv[2] = 577 u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_2); 578 aoac_rpt->ptk_rx_iv[3] = 579 u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_1_W3_PTK_IV_3); 580 581 h2c_info.id = RTW89_FWCMD_H2CREG_FUNC_AOAC_RPT_2; 582 h2c_info.content_len = 2; 583 ret = rtw89_fw_msg_reg(rtwdev, &h2c_info, &c2h_info); 584 if (ret) 585 return ret; 586 587 aoac_rpt->ptk_rx_iv[4] = 588 u32_get_bits(c2h_info.u.c2hreg[0], RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_4); 589 aoac_rpt->ptk_rx_iv[5] = 590 u32_get_bits(c2h_info.u.c2hreg[0], RTW89_C2HREG_AOAC_RPT_2_W0_PTK_IV_5); 591 aoac_rpt->ptk_rx_iv[6] = 592 u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_6); 593 aoac_rpt->ptk_rx_iv[7] = 594 u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_PTK_IV_7); 595 igtk_ipn[0] = 596 u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_0); 597 igtk_ipn[1] = 598 u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_AOAC_RPT_2_W1_IGTK_IPN_IV_1); 599 igtk_ipn[2] = 600 u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_2); 601 igtk_ipn[3] = 602 u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_3); 603 igtk_ipn[4] = 604 u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_4); 605 igtk_ipn[5] = 606 u32_get_bits(c2h_info.u.c2hreg[2], RTW89_C2HREG_AOAC_RPT_2_W2_IGTK_IPN_IV_5); 607 igtk_ipn[6] = 608 u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_6); 609 igtk_ipn[7] = 610 u32_get_bits(c2h_info.u.c2hreg[3], RTW89_C2HREG_AOAC_RPT_2_W3_IGTK_IPN_IV_7); 611 aoac_rpt->igtk_ipn = u64_encode_bits(igtk_ipn[0], RTW89_IGTK_IPN_0) | 612 u64_encode_bits(igtk_ipn[1], RTW89_IGTK_IPN_1) | 613 u64_encode_bits(igtk_ipn[2], RTW89_IGTK_IPN_2) | 614 u64_encode_bits(igtk_ipn[3], RTW89_IGTK_IPN_3) | 615 u64_encode_bits(igtk_ipn[4], RTW89_IGTK_IPN_4) | 616 u64_encode_bits(igtk_ipn[5], RTW89_IGTK_IPN_5) | 617 u64_encode_bits(igtk_ipn[6], RTW89_IGTK_IPN_6) | 618 u64_encode_bits(igtk_ipn[7], RTW89_IGTK_IPN_7); 619 620 return 0; 621 } 622 623 static int rtw89_wow_get_aoac_rpt(struct rtw89_dev *rtwdev, bool rx_ready) 624 { 625 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 626 int ret; 627 628 if (!rtw_wow->ptk_alg) 629 return -EPERM; 630 631 if (!rx_ready) { 632 ret = rtw89_wow_get_aoac_rpt_reg(rtwdev); 633 if (ret) { 634 rtw89_err(rtwdev, "wow: failed to get aoac rpt by reg\n"); 635 return ret; 636 } 637 } else { 638 ret = rtw89_fw_h2c_wow_request_aoac(rtwdev); 639 if (ret) { 640 rtw89_err(rtwdev, "wow: failed to get aoac rpt by pkt\n"); 641 return ret; 642 } 643 } 644 645 rtw89_wow_debug_aoac_rpt(rtwdev); 646 647 return 0; 648 } 649 650 static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev, 651 u32 cipher, u8 keyidx, u8 *gtk) 652 { 653 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; 654 struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); 655 const struct rtw89_cipher_info *cipher_info; 656 struct ieee80211_key_conf *rekey_conf; 657 struct ieee80211_key_conf *key; 658 u8 sz; 659 660 lockdep_assert_wiphy(rtwdev->hw->wiphy); 661 662 cipher_info = rtw89_cipher_alg_recognize(cipher); 663 sz = struct_size(rekey_conf, key, cipher_info->len); 664 rekey_conf = kmalloc(sz, GFP_KERNEL); 665 if (!rekey_conf) 666 return NULL; 667 668 rekey_conf->cipher = cipher; 669 rekey_conf->keyidx = keyidx; 670 rekey_conf->keylen = cipher_info->len; 671 memcpy(rekey_conf->key, gtk, 672 flex_array_size(rekey_conf, key, cipher_info->len)); 673 674 if (ieee80211_vif_is_mld(wow_vif)) 675 key = ieee80211_gtk_rekey_add(wow_vif, keyidx, gtk, 676 cipher_info->len, 677 rtwvif_link->link_id, 678 false); 679 else 680 key = ieee80211_gtk_rekey_add(wow_vif, keyidx, gtk, 681 cipher_info->len, -1, 682 false); 683 684 kfree(rekey_conf); 685 if (IS_ERR(key)) { 686 rtw89_err(rtwdev, "ieee80211_gtk_rekey_add failed\n"); 687 return NULL; 688 } 689 690 return key; 691 } 692 693 static void rtw89_wow_update_key_info(struct rtw89_dev *rtwdev, bool rx_ready) 694 { 695 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; 696 struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); 697 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 698 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; 699 struct rtw89_set_key_info_iter_data data = {.error = false, 700 .rx_ready = rx_ready, 701 .tkip_gtk_swapped = false}; 702 struct ieee80211_bss_conf *bss_conf; 703 struct ieee80211_key_conf *key; 704 705 ieee80211_iter_keys(rtwdev->hw, wow_vif, 706 rtw89_wow_set_key_info_iter, &data); 707 708 if (data.error) { 709 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s error\n", __func__); 710 return; 711 } 712 713 if (!data.gtk_cipher) 714 return; 715 716 key = rtw89_wow_gtk_rekey(rtwdev, data.gtk_cipher, aoac_rpt->key_idx, 717 aoac_rpt->gtk); 718 if (!key) 719 return; 720 721 rtw89_rx_iv_to_pn(rtwdev, key, 722 aoac_rpt->gtk_rx_iv[key->keyidx]); 723 724 if (!data.igtk_cipher) 725 return; 726 727 key = rtw89_wow_gtk_rekey(rtwdev, data.igtk_cipher, aoac_rpt->igtk_key_id, 728 aoac_rpt->igtk); 729 if (!key) 730 return; 731 732 rtw89_rx_pn_set_pmf(rtwdev, key, aoac_rpt->igtk_ipn); 733 734 rcu_read_lock(); 735 736 bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); 737 ieee80211_gtk_rekey_notify(wow_vif, bss_conf->bssid, 738 aoac_rpt->eapol_key_replay_count, 739 GFP_ATOMIC); 740 741 rcu_read_unlock(); 742 } 743 744 static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev) 745 { 746 __rtw89_leave_ps_mode(rtwdev); 747 } 748 749 static void rtw89_wow_enter_deep_ps(struct rtw89_dev *rtwdev) 750 { 751 __rtw89_enter_ps_mode(rtwdev); 752 } 753 754 static void rtw89_wow_enter_ps(struct rtw89_dev *rtwdev) 755 { 756 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; 757 758 if (rtw89_wow_mgd_linked(rtwdev)) { 759 rtw89_enter_lps(rtwdev, rtwvif_link->rtwvif, false); 760 } else if (rtw89_wow_no_link(rtwdev)) { 761 rtw89_fw_h2c_fwips(rtwdev, rtwvif_link, true); 762 rtw89_fw_h2c_lps_ch_ml_info_routing(rtwdev, rtwvif_link->rtwvif); 763 } 764 } 765 766 static void rtw89_wow_leave_ps(struct rtw89_dev *rtwdev, bool enable_wow) 767 { 768 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; 769 770 if (rtw89_wow_mgd_linked(rtwdev)) { 771 rtw89_leave_lps(rtwdev); 772 } else if (rtw89_wow_no_link(rtwdev)) { 773 if (enable_wow) 774 rtw89_leave_ips(rtwdev); 775 else 776 rtw89_fw_h2c_fwips(rtwdev, rtwvif_link, false); 777 } 778 } 779 780 static int rtw89_wow_config_mac(struct rtw89_dev *rtwdev, bool enable_wow) 781 { 782 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 783 784 return mac->wow_config_mac(rtwdev, enable_wow); 785 } 786 787 static void rtw89_wow_set_rx_filter(struct rtw89_dev *rtwdev, bool enable) 788 { 789 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 790 enum rtw89_mac_fwd_target fwd_target = enable ? 791 RTW89_FWD_DONT_CARE : 792 RTW89_FWD_TO_HOST; 793 794 mac->typ_fltr_opt(rtwdev, RTW89_MGNT, fwd_target, RTW89_MAC_0); 795 mac->typ_fltr_opt(rtwdev, RTW89_CTRL, fwd_target, RTW89_MAC_0); 796 mac->typ_fltr_opt(rtwdev, RTW89_DATA, fwd_target, RTW89_MAC_0); 797 } 798 799 static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev) 800 { 801 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; 802 struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); 803 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 804 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; 805 struct cfg80211_wowlan_nd_info nd_info; 806 struct cfg80211_wowlan_wakeup wakeup = { 807 .pattern_idx = -1, 808 }; 809 u32 wow_reason_reg; 810 u8 reason; 811 812 if (RTW89_CHK_FW_FEATURE(WOW_REASON_V1, &rtwdev->fw)) 813 wow_reason_reg = rtwdev->chip->wow_reason_reg[RTW89_WOW_REASON_V1]; 814 else 815 wow_reason_reg = rtwdev->chip->wow_reason_reg[RTW89_WOW_REASON_V0]; 816 817 reason = rtw89_read8(rtwdev, wow_reason_reg); 818 switch (reason) { 819 case RTW89_WOW_RSN_RX_DISASSOC: 820 wakeup.disconnect = true; 821 rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx disassoc\n"); 822 break; 823 case RTW89_WOW_RSN_RX_DEAUTH: 824 wakeup.disconnect = true; 825 rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx deauth\n"); 826 break; 827 case RTW89_WOW_RSN_DISCONNECT: 828 wakeup.disconnect = true; 829 rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: AP is off\n"); 830 break; 831 case RTW89_WOW_RSN_RX_MAGIC_PKT: 832 wakeup.magic_pkt = true; 833 rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx magic packet\n"); 834 break; 835 case RTW89_WOW_RSN_RX_GTK_REKEY: 836 wakeup.gtk_rekey_failure = true; 837 rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx gtk rekey\n"); 838 break; 839 case RTW89_WOW_RSN_RX_PATTERN_MATCH: 840 wakeup.pattern_idx = aoac_rpt->pattern_idx; 841 rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: Rx pattern match packet\n"); 842 break; 843 case RTW89_WOW_RSN_RX_NLO: 844 /* Current firmware and driver don't report ssid index. 845 * Use 0 for n_matches based on its comment. 846 */ 847 nd_info.n_matches = 0; 848 wakeup.net_detect = &nd_info; 849 rtw89_debug(rtwdev, RTW89_DBG_WOW, "Rx NLO\n"); 850 break; 851 default: 852 rtw89_warn(rtwdev, "Unknown wakeup reason %x\n", reason); 853 ieee80211_report_wowlan_wakeup(wow_vif, NULL, GFP_KERNEL); 854 return; 855 } 856 857 ieee80211_report_wowlan_wakeup(wow_vif, &wakeup, GFP_KERNEL); 858 } 859 860 static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev, 861 struct rtw89_vif_link *rtwvif_link) 862 { 863 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 864 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 865 866 /* Current WoWLAN function support setting of only vif in 867 * infra mode or no link mode. When one suitable vif is found, 868 * stop the iteration. 869 */ 870 if (rtw_wow->rtwvif_link || vif->type != NL80211_IFTYPE_STATION) 871 return; 872 873 switch (rtwvif_link->net_type) { 874 case RTW89_NET_TYPE_INFRA: 875 if (rtw_wow_has_mgd_features(rtwdev)) 876 rtw_wow->rtwvif_link = rtwvif_link; 877 break; 878 case RTW89_NET_TYPE_NO_LINK: 879 if (rtw_wow->pno_inited) 880 rtw_wow->rtwvif_link = rtwvif_link; 881 break; 882 default: 883 break; 884 } 885 } 886 887 static u16 __rtw89_cal_crc16(u8 data, u16 crc) 888 { 889 u8 shift_in, data_bit; 890 u8 crc_bit4, crc_bit11, crc_bit15; 891 u16 crc_result; 892 int index; 893 894 for (index = 0; index < 8; index++) { 895 crc_bit15 = crc & BIT(15) ? 1 : 0; 896 data_bit = data & BIT(index) ? 1 : 0; 897 shift_in = crc_bit15 ^ data_bit; 898 899 crc_result = crc << 1; 900 901 if (shift_in == 0) 902 crc_result &= ~BIT(0); 903 else 904 crc_result |= BIT(0); 905 906 crc_bit11 = (crc & BIT(11) ? 1 : 0) ^ shift_in; 907 908 if (crc_bit11 == 0) 909 crc_result &= ~BIT(12); 910 else 911 crc_result |= BIT(12); 912 913 crc_bit4 = (crc & BIT(4) ? 1 : 0) ^ shift_in; 914 915 if (crc_bit4 == 0) 916 crc_result &= ~BIT(5); 917 else 918 crc_result |= BIT(5); 919 920 crc = crc_result; 921 } 922 return crc; 923 } 924 925 static u16 rtw89_calc_crc(u8 *pdata, int length) 926 { 927 u16 crc = 0xffff; 928 int i; 929 930 for (i = 0; i < length; i++) 931 crc = __rtw89_cal_crc16(pdata[i], crc); 932 933 /* get 1' complement */ 934 return ~crc; 935 } 936 937 static int rtw89_wow_pattern_get_type(struct rtw89_vif_link *rtwvif_link, 938 struct rtw89_wow_cam_info *rtw_pattern, 939 const u8 *pattern, u8 da_mask) 940 { 941 u8 da[ETH_ALEN]; 942 943 ether_addr_copy_mask(da, pattern, da_mask); 944 945 /* Each pattern is divided into different kinds by DA address 946 * a. DA is broadcast address: set bc = 0; 947 * b. DA is multicast address: set mc = 0 948 * c. DA is unicast address same as dev's mac address: set uc = 0 949 * d. DA is unmasked. Also called wildcard type: set uc = bc = mc = 0 950 * e. Others is invalid type. 951 */ 952 953 if (is_broadcast_ether_addr(da)) 954 rtw_pattern->bc = true; 955 else if (is_multicast_ether_addr(da)) 956 rtw_pattern->mc = true; 957 else if (ether_addr_equal(da, rtwvif_link->mac_addr) && 958 da_mask == GENMASK(5, 0)) 959 rtw_pattern->uc = true; 960 else if (!da_mask) /*da_mask == 0 mean wildcard*/ 961 return 0; 962 else 963 return -EPERM; 964 965 return 0; 966 } 967 968 static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev, 969 struct rtw89_vif_link *rtwvif_link, 970 const struct cfg80211_pkt_pattern *pkt_pattern, 971 struct rtw89_wow_cam_info *rtw_pattern) 972 { 973 u8 mask_hw[RTW89_MAX_PATTERN_MASK_SIZE * 4] = {0}; 974 u8 content[RTW89_MAX_PATTERN_SIZE] = {0}; 975 const u8 *mask; 976 const u8 *pattern; 977 u8 mask_len; 978 u16 count; 979 u32 len; 980 int i, ret; 981 982 pattern = pkt_pattern->pattern; 983 len = pkt_pattern->pattern_len; 984 mask = pkt_pattern->mask; 985 mask_len = DIV_ROUND_UP(len, 8); 986 memset(rtw_pattern, 0, sizeof(*rtw_pattern)); 987 988 ret = rtw89_wow_pattern_get_type(rtwvif_link, rtw_pattern, pattern, 989 mask[0] & GENMASK(5, 0)); 990 if (ret) 991 return ret; 992 993 /* translate mask from os to mask for hw 994 * pattern from OS uses 'ethenet frame', like this: 995 * | 6 | 6 | 2 | 20 | Variable | 4 | 996 * |--------+--------+------+-----------+------------+-----| 997 * | 802.3 Mac Header | IP Header | TCP Packet | FCS | 998 * | DA | SA | Type | 999 * 1000 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC 1001 * | 24 or 30 | 6 | 2 | 20 | Variable | 4 | 1002 * |-------------------+--------+------+-----------+------------+-----| 1003 * | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS | 1004 * | Others | Tpye | 1005 * 1006 * Therefore, we need translate mask_from_OS to mask_to_hw. 1007 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0, 1008 * because new mask[0~5] means 'SA', but our HW packet begins from LLC, 1009 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match. 1010 */ 1011 1012 /* Shift 6 bits */ 1013 for (i = 0; i < mask_len - 1; i++) { 1014 mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6)) | 1015 u8_get_bits(mask[i + 1], GENMASK(5, 0)) << 2; 1016 } 1017 mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6)); 1018 1019 /* Set bit 0-5 to zero */ 1020 mask_hw[0] &= ~GENMASK(5, 0); 1021 1022 memcpy(rtw_pattern->mask, mask_hw, sizeof(rtw_pattern->mask)); 1023 1024 /* To get the wake up pattern from the mask. 1025 * We do not count first 12 bits which means 1026 * DA[6] and SA[6] in the pattern to match HW design. 1027 */ 1028 count = 0; 1029 for (i = 12; i < len; i++) { 1030 if ((mask[i / 8] >> (i % 8)) & 0x01) { 1031 content[count] = pattern[i]; 1032 count++; 1033 } 1034 } 1035 1036 rtw_pattern->crc = rtw89_calc_crc(content, count); 1037 1038 return 0; 1039 } 1040 1041 static int rtw89_wow_parse_patterns(struct rtw89_dev *rtwdev, 1042 struct rtw89_vif_link *rtwvif_link, 1043 struct cfg80211_wowlan *wowlan) 1044 { 1045 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1046 struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; 1047 int i; 1048 int ret; 1049 1050 if (!wowlan->n_patterns || !wowlan->patterns) 1051 return 0; 1052 1053 for (i = 0; i < wowlan->n_patterns; i++) { 1054 rtw_pattern = &rtw_wow->patterns[i]; 1055 ret = rtw89_wow_pattern_generate(rtwdev, rtwvif_link, 1056 &wowlan->patterns[i], 1057 rtw_pattern); 1058 if (ret) { 1059 rtw89_err(rtwdev, "failed to generate pattern(%d)\n", i); 1060 rtw_wow->pattern_cnt = 0; 1061 return ret; 1062 } 1063 1064 rtw_pattern->r_w = true; 1065 rtw_pattern->idx = i; 1066 rtw_pattern->negative_pattern_match = false; 1067 rtw_pattern->skip_mac_hdr = true; 1068 rtw_pattern->valid = true; 1069 } 1070 rtw_wow->pattern_cnt = wowlan->n_patterns; 1071 1072 return 0; 1073 } 1074 1075 static void rtw89_wow_pattern_clear_cam(struct rtw89_dev *rtwdev) 1076 { 1077 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1078 struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; 1079 int i = 0; 1080 1081 for (i = 0; i < rtw_wow->pattern_cnt; i++) { 1082 rtw_pattern = &rtw_wow->patterns[i]; 1083 rtw_pattern->valid = false; 1084 rtw89_chip_h2c_wow_cam_update(rtwdev, rtw_pattern); 1085 } 1086 } 1087 1088 static void rtw89_wow_pattern_write(struct rtw89_dev *rtwdev) 1089 { 1090 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1091 struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; 1092 int i; 1093 1094 for (i = 0; i < rtw_wow->pattern_cnt; i++) 1095 rtw89_chip_h2c_wow_cam_update(rtwdev, rtw_pattern + i); 1096 } 1097 1098 static void rtw89_wow_pattern_clear(struct rtw89_dev *rtwdev) 1099 { 1100 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1101 1102 rtw89_wow_pattern_clear_cam(rtwdev); 1103 1104 rtw_wow->pattern_cnt = 0; 1105 memset(rtw_wow->patterns, 0, sizeof(rtw_wow->patterns)); 1106 } 1107 1108 static void rtw89_wow_clear_wakeups(struct rtw89_dev *rtwdev) 1109 { 1110 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1111 1112 rtw_wow->rtwvif_link = NULL; 1113 rtw89_core_release_all_bits_map(rtw_wow->flags, RTW89_WOW_FLAG_NUM); 1114 rtw_wow->pattern_cnt = 0; 1115 rtw_wow->pno_inited = false; 1116 } 1117 1118 static void rtw89_wow_init_pno(struct rtw89_dev *rtwdev, 1119 struct cfg80211_sched_scan_request *nd_config) 1120 { 1121 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1122 1123 if (!nd_config->n_match_sets || !nd_config->n_channels) 1124 return; 1125 1126 rtw_wow->nd_config = nd_config; 1127 rtw_wow->pno_inited = true; 1128 1129 INIT_LIST_HEAD(&rtw_wow->pno_pkt_list); 1130 1131 rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: net-detect is enabled\n"); 1132 } 1133 1134 static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev, 1135 struct cfg80211_wowlan *wowlan) 1136 { 1137 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1138 struct rtw89_vif_link *rtwvif_link; 1139 struct rtw89_vif *rtwvif; 1140 1141 if (wowlan->disconnect) 1142 set_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags); 1143 if (wowlan->magic_pkt) 1144 set_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags); 1145 if (wowlan->n_patterns && wowlan->patterns) 1146 set_bit(RTW89_WOW_FLAG_EN_PATTERN, rtw_wow->flags); 1147 1148 if (wowlan->nd_config) 1149 rtw89_wow_init_pno(rtwdev, wowlan->nd_config); 1150 1151 rtw89_for_each_rtwvif(rtwdev, rtwvif) { 1152 rtwvif_link = rtw89_get_designated_link(rtwvif); 1153 if (!rtwvif_link) 1154 continue; 1155 1156 rtw89_wow_vif_iter(rtwdev, rtwvif_link); 1157 } 1158 1159 rtwvif_link = rtw_wow->rtwvif_link; 1160 if (!rtwvif_link) 1161 return -EPERM; 1162 1163 return rtw89_wow_parse_patterns(rtwdev, rtwvif_link, wowlan); 1164 } 1165 1166 static int rtw89_wow_cfg_wake_pno(struct rtw89_dev *rtwdev, bool wow) 1167 { 1168 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; 1169 int ret; 1170 1171 ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif_link, true); 1172 if (ret) { 1173 rtw89_err(rtwdev, "failed to config pno\n"); 1174 return ret; 1175 } 1176 1177 ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif_link, wow); 1178 if (ret) { 1179 rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n"); 1180 return ret; 1181 } 1182 1183 ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif_link, wow); 1184 if (ret) { 1185 rtw89_err(rtwdev, "failed to fw wow global\n"); 1186 return ret; 1187 } 1188 1189 return 0; 1190 } 1191 1192 static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) 1193 { 1194 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1195 struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; 1196 struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); 1197 struct ieee80211_sta *wow_sta; 1198 struct rtw89_sta_link *rtwsta_link = NULL; 1199 struct rtw89_sta *rtwsta; 1200 int ret; 1201 1202 wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr); 1203 if (wow_sta) { 1204 rtwsta = sta_to_rtwsta(wow_sta); 1205 rtwsta_link = rtwsta->links[rtwvif_link->link_id]; 1206 if (!rtwsta_link) 1207 return -ENOLINK; 1208 } 1209 1210 if (wow) { 1211 if (rtw_wow->pattern_cnt) 1212 rtwvif_link->wowlan_pattern = true; 1213 if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) 1214 rtwvif_link->wowlan_magic = true; 1215 } else { 1216 rtwvif_link->wowlan_pattern = false; 1217 rtwvif_link->wowlan_magic = false; 1218 } 1219 1220 ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif_link, wow); 1221 if (ret) { 1222 rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n"); 1223 return ret; 1224 } 1225 1226 if (wow) { 1227 ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link); 1228 if (ret) { 1229 rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n", 1230 ret); 1231 return ret; 1232 } 1233 } 1234 1235 ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, 1236 RTW89_ROLE_INFO_CHANGE); 1237 if (ret) { 1238 rtw89_warn(rtwdev, "failed to send h2c cam\n"); 1239 return ret; 1240 } 1241 1242 ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif_link, wow); 1243 if (ret) { 1244 rtw89_err(rtwdev, "failed to fw wow global\n"); 1245 return ret; 1246 } 1247 1248 return 0; 1249 } 1250 1251 static int rtw89_wow_check_fw_status(struct rtw89_dev *rtwdev, bool wow_enable) 1252 { 1253 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 1254 u8 polling; 1255 int ret; 1256 1257 ret = read_poll_timeout_atomic(rtw89_read8_mask, polling, 1258 wow_enable == !!polling, 1259 50, 50000, false, rtwdev, 1260 mac->wow_ctrl.addr, mac->wow_ctrl.mask); 1261 if (ret) 1262 rtw89_err(rtwdev, "failed to check wow status %s\n", 1263 str_enabled_disabled(wow_enable)); 1264 return ret; 1265 } 1266 1267 static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow) 1268 { 1269 enum rtw89_fw_type fw_type = wow ? RTW89_FW_WOWLAN : RTW89_FW_NORMAL; 1270 enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; 1271 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1272 struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; 1273 struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link); 1274 enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; 1275 const struct rtw89_chip_info *chip = rtwdev->chip; 1276 bool include_bb = !!chip->bbmcu_nr; 1277 bool disable_intr_for_dlfw = true; 1278 struct ieee80211_sta *wow_sta; 1279 struct rtw89_sta_link *rtwsta_link = NULL; 1280 struct rtw89_sta *rtwsta; 1281 bool is_conn = true; 1282 int ret; 1283 1284 if (chip->chip_gen == RTW89_CHIP_AX && chip_id != RTL8852C) 1285 disable_intr_for_dlfw = false; 1286 1287 wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr); 1288 if (wow_sta) { 1289 rtwsta = sta_to_rtwsta(wow_sta); 1290 rtwsta_link = rtwsta->links[rtwvif_link->link_id]; 1291 if (!rtwsta_link) 1292 return -ENOLINK; 1293 } else { 1294 is_conn = false; 1295 } 1296 1297 if (disable_intr_for_dlfw) 1298 rtw89_hci_disable_intr(rtwdev); 1299 1300 ret = rtw89_fw_download(rtwdev, fw_type, include_bb); 1301 if (ret) { 1302 rtw89_warn(rtwdev, "download fw failed\n"); 1303 return ret; 1304 } 1305 1306 if (disable_intr_for_dlfw) 1307 rtw89_hci_enable_intr(rtwdev); 1308 1309 if (chip->chip_gen == RTW89_CHIP_AX) 1310 rtw89_phy_init_rf_reg(rtwdev, true); 1311 1312 ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link, 1313 RTW89_ROLE_FW_RESTORE); 1314 if (ret) { 1315 rtw89_warn(rtwdev, "failed to send h2c role maintain\n"); 1316 return ret; 1317 } 1318 1319 ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link); 1320 if (ret) { 1321 rtw89_warn(rtwdev, "failed to send h2c assoc cmac tbl\n"); 1322 return ret; 1323 } 1324 1325 if (!is_conn) 1326 rtw89_cam_reset_keys(rtwdev); 1327 1328 ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, !is_conn); 1329 if (ret) { 1330 rtw89_warn(rtwdev, "failed to send h2c join info\n"); 1331 return ret; 1332 } 1333 1334 ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, 1335 RTW89_ROLE_FW_RESTORE); 1336 if (ret) { 1337 rtw89_warn(rtwdev, "failed to send h2c cam\n"); 1338 return ret; 1339 } 1340 1341 if (is_conn) { 1342 ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta_link->mac_id); 1343 if (ret) { 1344 rtw89_warn(rtwdev, "failed to send h2c general packet\n"); 1345 return ret; 1346 } 1347 rtw89_phy_ra_assoc(rtwdev, rtwsta_link); 1348 rtw89_phy_set_bss_color(rtwdev, rtwvif_link); 1349 rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link); 1350 } 1351 1352 if (chip_gen == RTW89_CHIP_BE) 1353 rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, RTW89_PHY_0, 5); 1354 1355 rtw89_mac_hw_mgnt_sec(rtwdev, wow); 1356 1357 return 0; 1358 } 1359 1360 static int rtw89_wow_enable_trx_pre(struct rtw89_dev *rtwdev) 1361 { 1362 int ret; 1363 1364 rtw89_hci_ctrl_txdma_ch(rtwdev, false); 1365 rtw89_hci_ctrl_txdma_fw_ch(rtwdev, true); 1366 1367 rtw89_mac_ptk_drop_by_band_and_wait(rtwdev, RTW89_MAC_0); 1368 1369 ret = rtw89_hci_poll_txdma_ch_idle(rtwdev); 1370 if (ret) { 1371 rtw89_err(rtwdev, "txdma ch busy\n"); 1372 return ret; 1373 } 1374 rtw89_wow_set_rx_filter(rtwdev, true); 1375 1376 ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, false); 1377 if (ret) { 1378 rtw89_err(rtwdev, "cfg ppdu status\n"); 1379 return ret; 1380 } 1381 1382 return 0; 1383 } 1384 1385 static int rtw89_wow_enable_trx_post(struct rtw89_dev *rtwdev) 1386 { 1387 int ret; 1388 1389 rtw89_hci_disable_intr(rtwdev); 1390 rtw89_hci_ctrl_trxhci(rtwdev, false); 1391 1392 ret = rtw89_hci_poll_txdma_ch_idle(rtwdev); 1393 if (ret) { 1394 rtw89_err(rtwdev, "failed to poll txdma ch idle pcie\n"); 1395 return ret; 1396 } 1397 1398 ret = rtw89_wow_config_mac(rtwdev, true); 1399 if (ret) { 1400 rtw89_err(rtwdev, "failed to config mac\n"); 1401 return ret; 1402 } 1403 1404 rtw89_wow_set_rx_filter(rtwdev, false); 1405 rtw89_hci_reset(rtwdev); 1406 1407 return 0; 1408 } 1409 1410 static int rtw89_wow_disable_trx_pre(struct rtw89_dev *rtwdev) 1411 { 1412 int ret; 1413 1414 rtw89_hci_clr_idx_all(rtwdev); 1415 1416 ret = rtw89_hci_rst_bdram(rtwdev); 1417 if (ret) { 1418 rtw89_warn(rtwdev, "reset bdram busy\n"); 1419 return ret; 1420 } 1421 1422 rtw89_hci_ctrl_trxhci(rtwdev, true); 1423 rtw89_hci_ctrl_txdma_ch(rtwdev, true); 1424 1425 ret = rtw89_wow_config_mac(rtwdev, false); 1426 if (ret) { 1427 rtw89_err(rtwdev, "failed to config mac\n"); 1428 return ret; 1429 } 1430 1431 /* Before enabling interrupt, we need to get AOAC report by reg due to RX 1432 * not enabled yet. Also, we need to sync RX related IV from firmware to 1433 * mac80211 before receiving RX packets from driver. 1434 * After enabling interrupt, we can get AOAC report from h2c and c2h, and 1435 * can get TX IV and complete rekey info. We need to update TX related IV 1436 * and new GTK info if rekey happened. 1437 */ 1438 ret = rtw89_wow_get_aoac_rpt(rtwdev, false); 1439 if (!ret) 1440 rtw89_wow_update_key_info(rtwdev, false); 1441 1442 rtw89_hci_enable_intr(rtwdev); 1443 ret = rtw89_wow_get_aoac_rpt(rtwdev, true); 1444 if (!ret) 1445 rtw89_wow_update_key_info(rtwdev, true); 1446 1447 return 0; 1448 } 1449 1450 static int rtw89_wow_disable_trx_post(struct rtw89_dev *rtwdev) 1451 { 1452 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; 1453 int ret; 1454 1455 ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true); 1456 if (ret) 1457 rtw89_err(rtwdev, "cfg ppdu status\n"); 1458 1459 rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true); 1460 1461 return ret; 1462 } 1463 1464 static void rtw89_fw_release_pno_pkt_list(struct rtw89_dev *rtwdev, 1465 struct rtw89_vif_link *rtwvif_link) 1466 { 1467 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 1468 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1469 struct list_head *pkt_list = &rtw_wow->pno_pkt_list; 1470 struct rtw89_pktofld_info *info, *tmp; 1471 u8 idx, wildcard_pkt_id; 1472 1473 for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { 1474 if (!(rtwdev->chip->support_bands & BIT(idx))) 1475 continue; 1476 1477 wildcard_pkt_id = scan_info->wildcard_pkt_id[idx]; 1478 if (wildcard_pkt_id != RTW89_SCANOFLD_PKT_NONE) 1479 rtw89_fw_h2c_del_pkt_offload(rtwdev, wildcard_pkt_id); 1480 } 1481 1482 list_for_each_entry_safe(info, tmp, pkt_list, list) { 1483 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); 1484 list_del(&info->list); 1485 kfree(info); 1486 } 1487 } 1488 1489 static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev, 1490 struct rtw89_vif_link *rtwvif_link) 1491 { 1492 static const u8 basic_rate_ie[] = {WLAN_EID_SUPP_RATES, 0x08, 1493 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c}; 1494 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1495 struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; 1496 u8 num = nd_config->n_match_sets, i; 1497 struct rtw89_pktofld_info *info; 1498 struct sk_buff *skb; 1499 int ret; 1500 1501 ret = rtw89_hw_scan_append_wildcard_probe_req(rtwdev, rtwvif_link, 1502 rtwvif_link->mac_addr, true); 1503 if (ret) 1504 return ret; 1505 1506 for (i = 0; i < num; i++) { 1507 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, 1508 nd_config->match_sets[i].ssid.ssid, 1509 nd_config->match_sets[i].ssid.ssid_len, 1510 nd_config->ie_len + sizeof(basic_rate_ie)); 1511 if (!skb) 1512 return -ENOMEM; 1513 1514 skb_put_data(skb, basic_rate_ie, sizeof(basic_rate_ie)); 1515 skb_put_data(skb, nd_config->ie, nd_config->ie_len); 1516 1517 info = kzalloc_obj(*info); 1518 if (!info) { 1519 kfree_skb(skb); 1520 rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link); 1521 return -ENOMEM; 1522 } 1523 1524 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); 1525 if (ret) { 1526 kfree_skb(skb); 1527 kfree(info); 1528 rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link); 1529 return ret; 1530 } 1531 1532 list_add_tail(&info->list, &rtw_wow->pno_pkt_list); 1533 kfree_skb(skb); 1534 } 1535 1536 return 0; 1537 } 1538 1539 static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable) 1540 { 1541 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 1542 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1543 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; 1544 int interval = rtw_wow->nd_config->scan_plans[0].interval; 1545 struct rtw89_scan_option opt = {}; 1546 int ret; 1547 1548 if (enable) { 1549 rtw89_hw_scan_calc_req_ssid(rtwdev, rtwvif_link, true); 1550 memset(rtwdev->scan_info.wildcard_pkt_id, RTW89_SCANOFLD_PKT_NONE, 1551 sizeof(rtwdev->scan_info.wildcard_pkt_id)); 1552 1553 ret = rtw89_pno_scan_update_probe_req(rtwdev, rtwvif_link); 1554 if (ret) { 1555 rtw89_err(rtwdev, "Update probe request failed\n"); 1556 return ret; 1557 } 1558 1559 ret = mac->add_chan_list_pno(rtwdev, rtwvif_link); 1560 if (ret) { 1561 rtw89_err(rtwdev, "Update channel list failed\n"); 1562 return ret; 1563 } 1564 } 1565 1566 opt.enable = enable; 1567 opt.repeat = RTW89_SCAN_NORMAL; 1568 opt.norm_pd = max(interval, 1) * 10; /* in unit of 100ms */ 1569 opt.delay = max(rtw_wow->nd_config->delay, 1) * 1000; 1570 1571 if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { 1572 opt.operation = enable ? RTW89_SCAN_OP_START : RTW89_SCAN_OP_STOP; 1573 opt.scan_mode = RTW89_SCAN_MODE_SA; 1574 opt.band = RTW89_PHY_0; 1575 opt.num_macc_role = 0; 1576 opt.mlo_mode = rtwdev->mlo_dbcc_mode; 1577 opt.num_opch = 0; 1578 opt.opch_end = RTW89_CHAN_INVALID; 1579 } 1580 1581 rtw89_mac_scan_offload(rtwdev, &opt, rtwvif_link, true); 1582 1583 return 0; 1584 } 1585 1586 static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev) 1587 { 1588 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1589 struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; 1590 int ret; 1591 1592 if (rtw89_wow_no_link(rtwdev)) { 1593 ret = rtw89_pno_scan_offload(rtwdev, false); 1594 if (ret) { 1595 rtw89_err(rtwdev, "wow: failed to disable pno scan offload\n"); 1596 return ret; 1597 } 1598 1599 ret = rtw89_pno_scan_offload(rtwdev, true); 1600 if (ret) { 1601 rtw89_err(rtwdev, "wow: failed to enable pno scan offload\n"); 1602 return ret; 1603 } 1604 } else { 1605 rtw89_wow_pattern_write(rtwdev); 1606 rtw89_wow_construct_key_info(rtwdev); 1607 1608 ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif_link, true); 1609 if (ret) { 1610 rtw89_err(rtwdev, "wow: failed to enable keep alive\n"); 1611 return ret; 1612 } 1613 1614 ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif_link, true); 1615 if (ret) { 1616 rtw89_err(rtwdev, "wow: failed to enable disconnect detect\n"); 1617 return ret; 1618 } 1619 1620 ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif_link, true); 1621 if (ret) { 1622 rtw89_err(rtwdev, "wow: failed to enable GTK offload\n"); 1623 return ret; 1624 } 1625 1626 ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif_link, true); 1627 if (ret) 1628 rtw89_warn(rtwdev, "wow: failed to enable arp offload\n"); 1629 } 1630 1631 if (rtw89_wow_no_link(rtwdev)) { 1632 ret = rtw89_wow_cfg_wake_pno(rtwdev, true); 1633 if (ret) { 1634 rtw89_err(rtwdev, "wow: failed to config wake PNO\n"); 1635 return ret; 1636 } 1637 } else { 1638 ret = rtw89_wow_cfg_wake(rtwdev, true); 1639 if (ret) { 1640 rtw89_err(rtwdev, "wow: failed to config wake\n"); 1641 return ret; 1642 } 1643 } 1644 1645 ret = rtw89_wow_check_fw_status(rtwdev, true); 1646 if (ret) { 1647 rtw89_err(rtwdev, "wow: failed to check enable fw ready\n"); 1648 return ret; 1649 } 1650 1651 return 0; 1652 } 1653 1654 static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev) 1655 { 1656 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; 1657 struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; 1658 int ret; 1659 1660 if (rtw89_wow_no_link(rtwdev)) { 1661 ret = rtw89_pno_scan_offload(rtwdev, false); 1662 if (ret) { 1663 rtw89_err(rtwdev, "wow: failed to disable pno scan offload\n"); 1664 return ret; 1665 } 1666 1667 ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif_link, false); 1668 if (ret) { 1669 rtw89_err(rtwdev, "wow: failed to disable pno\n"); 1670 return ret; 1671 } 1672 1673 rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link); 1674 } else { 1675 rtw89_wow_pattern_clear(rtwdev); 1676 1677 ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif_link, false); 1678 if (ret) { 1679 rtw89_err(rtwdev, "wow: failed to disable keep alive\n"); 1680 return ret; 1681 } 1682 1683 ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif_link, false); 1684 if (ret) { 1685 rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n"); 1686 return ret; 1687 } 1688 1689 ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif_link, false); 1690 if (ret) { 1691 rtw89_err(rtwdev, "wow: failed to disable GTK offload\n"); 1692 return ret; 1693 } 1694 1695 ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif_link, false); 1696 if (ret) 1697 rtw89_warn(rtwdev, "wow: failed to disable arp offload\n"); 1698 1699 rtw89_wow_key_clear(rtwdev); 1700 rtw89_fw_release_general_pkt_list(rtwdev, true); 1701 } 1702 1703 1704 ret = rtw89_wow_cfg_wake(rtwdev, false); 1705 if (ret) { 1706 rtw89_err(rtwdev, "wow: failed to disable config wake\n"); 1707 return ret; 1708 } 1709 1710 ret = rtw89_wow_check_fw_status(rtwdev, false); 1711 if (ret) { 1712 rtw89_err(rtwdev, "wow: failed to check disable fw ready\n"); 1713 return ret; 1714 } 1715 1716 return 0; 1717 } 1718 1719 static int rtw89_wow_enable(struct rtw89_dev *rtwdev) 1720 { 1721 int ret; 1722 1723 set_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); 1724 1725 ret = rtw89_wow_enable_trx_pre(rtwdev); 1726 if (ret) { 1727 rtw89_err(rtwdev, "wow: failed to enable trx_pre\n"); 1728 goto out; 1729 } 1730 1731 rtw89_fw_release_general_pkt_list(rtwdev, true); 1732 1733 ret = rtw89_wow_swap_fw(rtwdev, true); 1734 if (ret) { 1735 rtw89_err(rtwdev, "wow: failed to swap to wow fw\n"); 1736 goto out; 1737 } 1738 1739 ret = rtw89_wow_fw_start(rtwdev); 1740 if (ret) { 1741 rtw89_err(rtwdev, "wow: failed to let wow fw start\n"); 1742 goto out; 1743 } 1744 1745 rtw89_wow_enter_ps(rtwdev); 1746 1747 ret = rtw89_wow_enable_trx_post(rtwdev); 1748 if (ret) { 1749 rtw89_err(rtwdev, "wow: failed to enable trx_post\n"); 1750 goto out; 1751 } 1752 1753 return 0; 1754 1755 out: 1756 clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); 1757 return ret; 1758 } 1759 1760 static int rtw89_wow_disable(struct rtw89_dev *rtwdev) 1761 { 1762 int ret; 1763 1764 ret = rtw89_wow_disable_trx_pre(rtwdev); 1765 if (ret) { 1766 rtw89_err(rtwdev, "wow: failed to disable trx_pre\n"); 1767 goto out; 1768 } 1769 1770 rtw89_wow_leave_ps(rtwdev, false); 1771 1772 rtw89_core_tid_rx_stats_reset(rtwdev); 1773 1774 ret = rtw89_wow_fw_stop(rtwdev); 1775 if (ret) { 1776 rtw89_err(rtwdev, "wow: failed to swap to normal fw\n"); 1777 goto out; 1778 } 1779 1780 ret = rtw89_wow_swap_fw(rtwdev, false); 1781 if (ret) { 1782 rtw89_err(rtwdev, "wow: failed to disable trx_post\n"); 1783 goto out; 1784 } 1785 1786 ret = rtw89_wow_disable_trx_post(rtwdev); 1787 if (ret) { 1788 rtw89_err(rtwdev, "wow: failed to disable trx_pre\n"); 1789 goto out; 1790 } 1791 1792 out: 1793 clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); 1794 return ret; 1795 } 1796 1797 static void rtw89_wow_restore_ps(struct rtw89_dev *rtwdev) 1798 { 1799 if (rtw89_wow_no_link(rtwdev)) 1800 rtw89_enter_ips(rtwdev); 1801 } 1802 1803 int rtw89_wow_resume(struct rtw89_dev *rtwdev) 1804 { 1805 int ret; 1806 1807 if (!test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags)) { 1808 rtw89_err(rtwdev, "wow is not enabled\n"); 1809 ret = -EPERM; 1810 goto out; 1811 } 1812 1813 if (!rtw89_mac_get_power_state(rtwdev)) { 1814 rtw89_err(rtwdev, "chip is no power when resume\n"); 1815 ret = -EPERM; 1816 goto out; 1817 } 1818 1819 rtw89_wow_leave_deep_ps(rtwdev); 1820 1821 rtw89_wow_show_wakeup_reason(rtwdev); 1822 1823 ret = rtw89_wow_disable(rtwdev); 1824 if (ret) 1825 rtw89_err(rtwdev, "failed to disable wow\n"); 1826 1827 rtw89_wow_restore_ps(rtwdev); 1828 out: 1829 rtw89_wow_clear_wakeups(rtwdev); 1830 return ret; 1831 } 1832 1833 int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan) 1834 { 1835 int ret; 1836 1837 ret = rtw89_wow_set_wakeups(rtwdev, wowlan); 1838 if (ret) { 1839 rtw89_err(rtwdev, "failed to set wakeup event\n"); 1840 return ret; 1841 } 1842 1843 rtw89_wow_leave_ps(rtwdev, true); 1844 1845 ret = rtw89_wow_enable(rtwdev); 1846 if (ret) { 1847 rtw89_err(rtwdev, "failed to enable wow\n"); 1848 return ret; 1849 } 1850 1851 rtw89_wow_enter_deep_ps(rtwdev); 1852 1853 return 0; 1854 } 1855