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