Lines Matching +full:key +full:- +full:wakeup
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2019-2022 Realtek Corporation
17 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; in rtw89_wow_parse_akm()
18 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_parse_akm()
19 const u8 *rsn, *ies = mgmt->u.assoc_req.variable; in rtw89_wow_parse_akm()
22 rsn = cfg80211_find_ie(WLAN_EID_RSN, ies, skb->len); in rtw89_wow_parse_akm()
27 rtw_wow->akm = rsn_ie->akm_cipher_suite.type; in rtw89_wow_parse_akm()
55 if (cipher_info_defs->cipher == cipher) in rtw89_cipher_alg_recognize()
62 static int _pn_to_iv(struct rtw89_dev *rtwdev, struct ieee80211_key_conf *key, in _pn_to_iv() argument
65 switch (key->cipher) { in _pn_to_iv()
80 return -EINVAL; in _pn_to_iv()
93 struct ieee80211_key_conf *key, in rtw89_rx_pn_to_iv() argument
100 ieee80211_get_key_rx_seq(key, 0, &seq); in rtw89_rx_pn_to_iv()
110 err = _pn_to_iv(rtwdev, key, iv, pn, key->keyidx); in rtw89_rx_pn_to_iv()
114 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx to iv-%*ph\n", in rtw89_rx_pn_to_iv()
115 __func__, key->keyidx, pn, 8, iv); in rtw89_rx_pn_to_iv()
121 struct ieee80211_key_conf *key, in rtw89_tx_pn_to_iv() argument
127 pn = atomic64_inc_return(&key->tx_pn); in rtw89_tx_pn_to_iv()
128 err = _pn_to_iv(rtwdev, key, iv, pn, key->keyidx); in rtw89_tx_pn_to_iv()
132 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx to iv-%*ph\n", in rtw89_tx_pn_to_iv()
133 __func__, key->keyidx, pn, 8, iv); in rtw89_tx_pn_to_iv()
139 struct ieee80211_key_conf *key) in _iv_to_pn() argument
141 switch (key->cipher) { in _iv_to_pn()
154 return -EINVAL; in _iv_to_pn()
169 struct ieee80211_key_conf *key, in rtw89_rx_iv_to_pn() argument
176 err = _iv_to_pn(rtwdev, iv, &pn, NULL, key); in rtw89_rx_iv_to_pn()
188 ieee80211_set_key_rx_seq(key, 0, &seq); in rtw89_rx_iv_to_pn()
189 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d iv-%*ph to pn-%*ph\n", in rtw89_rx_iv_to_pn()
190 __func__, key->keyidx, 8, iv, 6, seq.ccmp.pn); in rtw89_rx_iv_to_pn()
196 struct ieee80211_key_conf *key, in rtw89_tx_iv_to_pn() argument
202 err = _iv_to_pn(rtwdev, iv, &pn, NULL, key); in rtw89_tx_iv_to_pn()
206 atomic64_set(&key->tx_pn, pn); in rtw89_tx_iv_to_pn()
207 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d iv-%*ph to pn-%llx\n", in rtw89_tx_iv_to_pn()
208 __func__, key->keyidx, 8, iv, pn); in rtw89_tx_iv_to_pn()
214 struct ieee80211_key_conf *key, in rtw89_rx_pn_get_pmf() argument
220 if (key->keyidx == 4) in rtw89_rx_pn_get_pmf()
221 memcpy(gtk_info->igtk[0], key->key, key->keylen); in rtw89_rx_pn_get_pmf()
222 else if (key->keyidx == 5) in rtw89_rx_pn_get_pmf()
223 memcpy(gtk_info->igtk[1], key->key, key->keylen); in rtw89_rx_pn_get_pmf()
225 return -EINVAL; in rtw89_rx_pn_get_pmf()
227 ieee80211_get_key_rx_seq(key, 0, &seq); in rtw89_rx_pn_get_pmf()
236 gtk_info->ipn = cpu_to_le64(pn); in rtw89_rx_pn_get_pmf()
237 gtk_info->igtk_keyid = cpu_to_le32(key->keyidx); in rtw89_rx_pn_get_pmf()
238 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx\n", in rtw89_rx_pn_get_pmf()
239 __func__, key->keyidx, pn); in rtw89_rx_pn_get_pmf()
245 struct ieee80211_key_conf *key, in rtw89_rx_pn_set_pmf() argument
248 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_rx_pn_set_pmf()
249 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; in rtw89_rx_pn_set_pmf()
252 if (key->keyidx != aoac_rpt->igtk_key_id) in rtw89_rx_pn_set_pmf()
263 ieee80211_set_key_rx_seq(key, 0, &seq); in rtw89_rx_pn_set_pmf()
264 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%*ph\n", in rtw89_rx_pn_set_pmf()
265 __func__, key->keyidx, 6, seq.ccmp.pn); in rtw89_rx_pn_set_pmf()
273 struct ieee80211_key_conf *key, in rtw89_wow_get_key_info_iter() argument
276 struct rtw89_dev *rtwdev = hw->priv; in rtw89_wow_get_key_info_iter()
277 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_get_key_info_iter()
278 struct rtw89_wow_key_info *key_info = &rtw_wow->key_info; in rtw89_wow_get_key_info_iter()
279 struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info; in rtw89_wow_get_key_info_iter()
284 cipher_info = rtw89_cipher_alg_recognize(key->cipher); in rtw89_wow_get_key_info_iter()
286 switch (key->cipher) { in rtw89_wow_get_key_info_iter()
293 ret = rtw89_tx_pn_to_iv(rtwdev, key, in rtw89_wow_get_key_info_iter()
294 key_info->ptk_tx_iv); in rtw89_wow_get_key_info_iter()
297 ret = rtw89_rx_pn_to_iv(rtwdev, key, in rtw89_wow_get_key_info_iter()
298 key_info->ptk_rx_iv); in rtw89_wow_get_key_info_iter()
302 rtw_wow->ptk_alg = cipher_info->fw_alg; in rtw89_wow_get_key_info_iter()
303 rtw_wow->ptk_keyidx = key->keyidx; in rtw89_wow_get_key_info_iter()
305 ret = rtw89_rx_pn_to_iv(rtwdev, key, in rtw89_wow_get_key_info_iter()
306 key_info->gtk_rx_iv[key->keyidx]); in rtw89_wow_get_key_info_iter()
310 rtw_wow->gtk_alg = cipher_info->fw_alg; in rtw89_wow_get_key_info_iter()
311 key_info->gtk_keyidx = key->keyidx; in rtw89_wow_get_key_info_iter()
315 ret = rtw89_rx_pn_get_pmf(rtwdev, key, gtk_info); in rtw89_wow_get_key_info_iter()
321 /* WEP only set group key in mac80211, but fw need to set in rtw89_wow_get_key_info_iter()
322 * both of pairwise key and group key. in rtw89_wow_get_key_info_iter()
324 rtw_wow->ptk_alg = cipher_info->fw_alg; in rtw89_wow_get_key_info_iter()
325 rtw_wow->ptk_keyidx = key->keyidx; in rtw89_wow_get_key_info_iter()
326 rtw_wow->gtk_alg = cipher_info->fw_alg; in rtw89_wow_get_key_info_iter()
327 key_info->gtk_keyidx = key->keyidx; in rtw89_wow_get_key_info_iter()
331 key->cipher); in rtw89_wow_get_key_info_iter()
343 struct ieee80211_key_conf *key, in rtw89_wow_set_key_info_iter() argument
346 struct rtw89_dev *rtwdev = hw->priv; in rtw89_wow_set_key_info_iter()
347 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_set_key_info_iter()
348 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; in rtw89_wow_set_key_info_iter()
350 bool update_tx_key_info = iter_data->rx_ready; in rtw89_wow_set_key_info_iter()
353 switch (key->cipher) { in rtw89_wow_set_key_info_iter()
360 ret = rtw89_rx_iv_to_pn(rtwdev, key, in rtw89_wow_set_key_info_iter()
361 aoac_rpt->ptk_rx_iv); in rtw89_wow_set_key_info_iter()
367 ret = rtw89_tx_iv_to_pn(rtwdev, key, in rtw89_wow_set_key_info_iter()
368 aoac_rpt->ptk_tx_iv); in rtw89_wow_set_key_info_iter()
374 ret = rtw89_rx_iv_to_pn(rtwdev, key, in rtw89_wow_set_key_info_iter()
375 aoac_rpt->gtk_rx_iv[key->keyidx]); in rtw89_wow_set_key_info_iter()
380 if (!sta && update_tx_key_info && aoac_rpt->rekey_ok) in rtw89_wow_set_key_info_iter()
381 iter_data->gtk_cipher = key->cipher; in rtw89_wow_set_key_info_iter()
385 if (aoac_rpt->rekey_ok) in rtw89_wow_set_key_info_iter()
386 iter_data->igtk_cipher = key->cipher; in rtw89_wow_set_key_info_iter()
388 ret = rtw89_rx_pn_set_pmf(rtwdev, key, in rtw89_wow_set_key_info_iter()
389 aoac_rpt->igtk_ipn); in rtw89_wow_set_key_info_iter()
399 key->cipher); in rtw89_wow_set_key_info_iter()
406 iter_data->error = true; in rtw89_wow_set_key_info_iter()
411 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_key_clear()
413 memset(&rtw_wow->aoac_rpt, 0, sizeof(rtw_wow->aoac_rpt)); in rtw89_wow_key_clear()
414 memset(&rtw_wow->gtk_info, 0, sizeof(rtw_wow->gtk_info)); in rtw89_wow_key_clear()
415 memset(&rtw_wow->key_info, 0, sizeof(rtw_wow->key_info)); in rtw89_wow_key_clear()
416 rtw_wow->ptk_alg = 0; in rtw89_wow_key_clear()
417 rtw_wow->gtk_alg = 0; in rtw89_wow_key_clear()
422 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_construct_key_info()
423 struct rtw89_wow_key_info *key_info = &rtw_wow->key_info; in rtw89_wow_construct_key_info()
424 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_construct_key_info()
429 ieee80211_iter_keys_rcu(rtwdev->hw, wow_vif, in rtw89_wow_construct_key_info()
438 key_info->valid_check = RTW89_WOW_VALID_CHECK; in rtw89_wow_construct_key_info()
439 key_info->symbol_check_en = RTW89_WOW_SYMBOL_CHK_PTK | in rtw89_wow_construct_key_info()
445 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_debug_aoac_rpt()
446 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; in rtw89_wow_debug_aoac_rpt()
452 aoac_rpt->rpt_ver); in rtw89_wow_debug_aoac_rpt()
454 aoac_rpt->sec_type); in rtw89_wow_debug_aoac_rpt()
456 aoac_rpt->key_idx); in rtw89_wow_debug_aoac_rpt()
458 aoac_rpt->pattern_idx); in rtw89_wow_debug_aoac_rpt()
460 aoac_rpt->rekey_ok); in rtw89_wow_debug_aoac_rpt()
462 8, aoac_rpt->ptk_tx_iv); in rtw89_wow_debug_aoac_rpt()
465 8, aoac_rpt->eapol_key_replay_count); in rtw89_wow_debug_aoac_rpt()
467 8, aoac_rpt->ptk_rx_iv); in rtw89_wow_debug_aoac_rpt()
469 8, aoac_rpt->gtk_rx_iv[0]); in rtw89_wow_debug_aoac_rpt()
471 8, aoac_rpt->gtk_rx_iv[1]); in rtw89_wow_debug_aoac_rpt()
473 8, aoac_rpt->gtk_rx_iv[2]); in rtw89_wow_debug_aoac_rpt()
475 8, aoac_rpt->gtk_rx_iv[3]); in rtw89_wow_debug_aoac_rpt()
477 aoac_rpt->igtk_key_id); in rtw89_wow_debug_aoac_rpt()
479 aoac_rpt->igtk_ipn); in rtw89_wow_debug_aoac_rpt()
481 32, aoac_rpt->igtk); in rtw89_wow_debug_aoac_rpt()
486 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_get_aoac_rpt_reg()
487 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; in rtw89_wow_get_aoac_rpt_reg()
500 aoac_rpt->key_idx = in rtw89_wow_get_aoac_rpt_reg()
502 key_idx = aoac_rpt->key_idx; in rtw89_wow_get_aoac_rpt_reg()
503 aoac_rpt->gtk_rx_iv[key_idx][0] = in rtw89_wow_get_aoac_rpt_reg()
505 aoac_rpt->gtk_rx_iv[key_idx][1] = in rtw89_wow_get_aoac_rpt_reg()
507 aoac_rpt->gtk_rx_iv[key_idx][2] = in rtw89_wow_get_aoac_rpt_reg()
509 aoac_rpt->gtk_rx_iv[key_idx][3] = in rtw89_wow_get_aoac_rpt_reg()
511 aoac_rpt->gtk_rx_iv[key_idx][4] = in rtw89_wow_get_aoac_rpt_reg()
513 aoac_rpt->gtk_rx_iv[key_idx][5] = in rtw89_wow_get_aoac_rpt_reg()
515 aoac_rpt->gtk_rx_iv[key_idx][6] = in rtw89_wow_get_aoac_rpt_reg()
517 aoac_rpt->gtk_rx_iv[key_idx][7] = in rtw89_wow_get_aoac_rpt_reg()
519 aoac_rpt->ptk_rx_iv[0] = in rtw89_wow_get_aoac_rpt_reg()
521 aoac_rpt->ptk_rx_iv[1] = in rtw89_wow_get_aoac_rpt_reg()
523 aoac_rpt->ptk_rx_iv[2] = in rtw89_wow_get_aoac_rpt_reg()
525 aoac_rpt->ptk_rx_iv[3] = in rtw89_wow_get_aoac_rpt_reg()
534 aoac_rpt->ptk_rx_iv[4] = in rtw89_wow_get_aoac_rpt_reg()
536 aoac_rpt->ptk_rx_iv[5] = in rtw89_wow_get_aoac_rpt_reg()
538 aoac_rpt->ptk_rx_iv[6] = in rtw89_wow_get_aoac_rpt_reg()
540 aoac_rpt->ptk_rx_iv[7] = in rtw89_wow_get_aoac_rpt_reg()
558 aoac_rpt->igtk_ipn = u64_encode_bits(igtk_ipn[0], RTW89_IGTK_IPN_0) | in rtw89_wow_get_aoac_rpt_reg()
572 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_get_aoac_rpt()
575 if (!rtw_wow->ptk_alg) in rtw89_wow_get_aoac_rpt()
576 return -EPERM; in rtw89_wow_get_aoac_rpt()
600 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_gtk_rekey()
604 struct ieee80211_key_conf *key; in rtw89_wow_gtk_rekey() local
607 lockdep_assert_wiphy(rtwdev->hw->wiphy); in rtw89_wow_gtk_rekey()
610 sz = struct_size(rekey_conf, key, cipher_info->len); in rtw89_wow_gtk_rekey()
615 rekey_conf->cipher = cipher; in rtw89_wow_gtk_rekey()
616 rekey_conf->keyidx = keyidx; in rtw89_wow_gtk_rekey()
617 rekey_conf->keylen = cipher_info->len; in rtw89_wow_gtk_rekey()
618 memcpy(rekey_conf->key, gtk, in rtw89_wow_gtk_rekey()
619 flex_array_size(rekey_conf, key, cipher_info->len)); in rtw89_wow_gtk_rekey()
622 key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, rtwvif_link->link_id); in rtw89_wow_gtk_rekey()
624 key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, -1); in rtw89_wow_gtk_rekey()
627 if (IS_ERR(key)) { in rtw89_wow_gtk_rekey()
632 return key; in rtw89_wow_gtk_rekey()
637 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_update_key_info()
639 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_update_key_info()
640 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; in rtw89_wow_update_key_info()
644 struct ieee80211_key_conf *key; in rtw89_wow_update_key_info() local
647 ieee80211_iter_keys_rcu(rtwdev->hw, wow_vif, in rtw89_wow_update_key_info()
659 key = rtw89_wow_gtk_rekey(rtwdev, data.gtk_cipher, aoac_rpt->key_idx, in rtw89_wow_update_key_info()
660 aoac_rpt->gtk); in rtw89_wow_update_key_info()
661 if (!key) in rtw89_wow_update_key_info()
664 rtw89_rx_iv_to_pn(rtwdev, key, in rtw89_wow_update_key_info()
665 aoac_rpt->gtk_rx_iv[key->keyidx]); in rtw89_wow_update_key_info()
670 key = rtw89_wow_gtk_rekey(rtwdev, data.igtk_cipher, aoac_rpt->igtk_key_id, in rtw89_wow_update_key_info()
671 aoac_rpt->igtk); in rtw89_wow_update_key_info()
672 if (!key) in rtw89_wow_update_key_info()
675 rtw89_rx_pn_set_pmf(rtwdev, key, aoac_rpt->igtk_ipn); in rtw89_wow_update_key_info()
680 ieee80211_gtk_rekey_notify(wow_vif, bss_conf->bssid, in rtw89_wow_update_key_info()
681 aoac_rpt->eapol_key_replay_count, in rtw89_wow_update_key_info()
699 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_enter_ps()
702 rtw89_enter_lps(rtwdev, rtwvif_link->rtwvif, false); in rtw89_wow_enter_ps()
709 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_leave_ps()
723 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; in rtw89_wow_config_mac()
725 return mac->wow_config_mac(rtwdev, enable_wow); in rtw89_wow_config_mac()
730 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; in rtw89_wow_set_rx_filter()
735 mac->typ_fltr_opt(rtwdev, RTW89_MGNT, fwd_target, RTW89_MAC_0); in rtw89_wow_set_rx_filter()
736 mac->typ_fltr_opt(rtwdev, RTW89_CTRL, fwd_target, RTW89_MAC_0); in rtw89_wow_set_rx_filter()
737 mac->typ_fltr_opt(rtwdev, RTW89_DATA, fwd_target, RTW89_MAC_0); in rtw89_wow_set_rx_filter()
742 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_show_wakeup_reason()
744 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_show_wakeup_reason()
745 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; in rtw89_wow_show_wakeup_reason()
747 struct cfg80211_wowlan_wakeup wakeup = { in rtw89_wow_show_wakeup_reason() local
748 .pattern_idx = -1, in rtw89_wow_show_wakeup_reason()
753 if (RTW89_CHK_FW_FEATURE(WOW_REASON_V1, &rtwdev->fw)) in rtw89_wow_show_wakeup_reason()
754 wow_reason_reg = rtwdev->chip->wow_reason_reg[RTW89_WOW_REASON_V1]; in rtw89_wow_show_wakeup_reason()
756 wow_reason_reg = rtwdev->chip->wow_reason_reg[RTW89_WOW_REASON_V0]; in rtw89_wow_show_wakeup_reason()
761 wakeup.disconnect = true; in rtw89_wow_show_wakeup_reason()
765 wakeup.disconnect = true; in rtw89_wow_show_wakeup_reason()
769 wakeup.magic_pkt = true; in rtw89_wow_show_wakeup_reason()
773 wakeup.gtk_rekey_failure = true; in rtw89_wow_show_wakeup_reason()
777 wakeup.pattern_idx = aoac_rpt->pattern_idx; in rtw89_wow_show_wakeup_reason()
785 wakeup.net_detect = &nd_info; in rtw89_wow_show_wakeup_reason()
789 rtw89_warn(rtwdev, "Unknown wakeup reason %x\n", reason); in rtw89_wow_show_wakeup_reason()
794 ieee80211_report_wowlan_wakeup(wow_vif, &wakeup, GFP_KERNEL); in rtw89_wow_show_wakeup_reason()
800 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_vif_iter()
807 if (rtw_wow->rtwvif_link || vif->type != NL80211_IFTYPE_STATION) in rtw89_wow_vif_iter()
810 switch (rtwvif_link->net_type) { in rtw89_wow_vif_iter()
813 rtw_wow->rtwvif_link = rtwvif_link; in rtw89_wow_vif_iter()
816 if (rtw_wow->pno_inited) in rtw89_wow_vif_iter()
817 rtw_wow->rtwvif_link = rtwvif_link; in rtw89_wow_vif_iter()
891 rtw_pattern->bc = true; in rtw89_wow_pattern_get_type()
893 rtw_pattern->mc = true; in rtw89_wow_pattern_get_type()
894 else if (ether_addr_equal(da, rtwvif_link->mac_addr) && in rtw89_wow_pattern_get_type()
896 rtw_pattern->uc = true; in rtw89_wow_pattern_get_type()
900 return -EPERM; in rtw89_wow_pattern_get_type()
919 pattern = pkt_pattern->pattern; in rtw89_wow_pattern_generate()
920 len = pkt_pattern->pattern_len; in rtw89_wow_pattern_generate()
921 mask = pkt_pattern->mask; in rtw89_wow_pattern_generate()
933 * |--------+--------+------+-----------+------------+-----| in rtw89_wow_pattern_generate()
939 * |-------------------+--------+------+-----------+------------+-----| in rtw89_wow_pattern_generate()
944 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0, in rtw89_wow_pattern_generate()
950 for (i = 0; i < mask_len - 1; i++) { in rtw89_wow_pattern_generate()
956 /* Set bit 0-5 to zero */ in rtw89_wow_pattern_generate()
959 memcpy(rtw_pattern->mask, mask_hw, sizeof(rtw_pattern->mask)); in rtw89_wow_pattern_generate()
973 rtw_pattern->crc = rtw89_calc_crc(content, count); in rtw89_wow_pattern_generate()
982 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_parse_patterns()
983 struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; in rtw89_wow_parse_patterns()
987 if (!wowlan->n_patterns || !wowlan->patterns) in rtw89_wow_parse_patterns()
990 for (i = 0; i < wowlan->n_patterns; i++) { in rtw89_wow_parse_patterns()
991 rtw_pattern = &rtw_wow->patterns[i]; in rtw89_wow_parse_patterns()
993 &wowlan->patterns[i], in rtw89_wow_parse_patterns()
997 rtw_wow->pattern_cnt = 0; in rtw89_wow_parse_patterns()
1001 rtw_pattern->r_w = true; in rtw89_wow_parse_patterns()
1002 rtw_pattern->idx = i; in rtw89_wow_parse_patterns()
1003 rtw_pattern->negative_pattern_match = false; in rtw89_wow_parse_patterns()
1004 rtw_pattern->skip_mac_hdr = true; in rtw89_wow_parse_patterns()
1005 rtw_pattern->valid = true; in rtw89_wow_parse_patterns()
1007 rtw_wow->pattern_cnt = wowlan->n_patterns; in rtw89_wow_parse_patterns()
1014 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_pattern_clear_cam()
1015 struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; in rtw89_wow_pattern_clear_cam()
1018 for (i = 0; i < rtw_wow->pattern_cnt; i++) { in rtw89_wow_pattern_clear_cam()
1019 rtw_pattern = &rtw_wow->patterns[i]; in rtw89_wow_pattern_clear_cam()
1020 rtw_pattern->valid = false; in rtw89_wow_pattern_clear_cam()
1027 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_pattern_write()
1028 struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; in rtw89_wow_pattern_write()
1031 for (i = 0; i < rtw_wow->pattern_cnt; i++) in rtw89_wow_pattern_write()
1037 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_pattern_clear()
1041 rtw_wow->pattern_cnt = 0; in rtw89_wow_pattern_clear()
1042 memset(rtw_wow->patterns, 0, sizeof(rtw_wow->patterns)); in rtw89_wow_pattern_clear()
1047 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_clear_wakeups()
1049 rtw_wow->rtwvif_link = NULL; in rtw89_wow_clear_wakeups()
1050 rtw89_core_release_all_bits_map(rtw_wow->flags, RTW89_WOW_FLAG_NUM); in rtw89_wow_clear_wakeups()
1051 rtw_wow->pattern_cnt = 0; in rtw89_wow_clear_wakeups()
1052 rtw_wow->pno_inited = false; in rtw89_wow_clear_wakeups()
1058 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_init_pno()
1060 if (!nd_config->n_match_sets || !nd_config->n_channels) in rtw89_wow_init_pno()
1063 rtw_wow->nd_config = nd_config; in rtw89_wow_init_pno()
1064 rtw_wow->pno_inited = true; in rtw89_wow_init_pno()
1066 INIT_LIST_HEAD(&rtw_wow->pno_pkt_list); in rtw89_wow_init_pno()
1068 rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: net-detect is enabled\n"); in rtw89_wow_init_pno()
1074 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_set_wakeups()
1078 if (wowlan->disconnect) in rtw89_wow_set_wakeups()
1079 set_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags); in rtw89_wow_set_wakeups()
1080 if (wowlan->magic_pkt) in rtw89_wow_set_wakeups()
1081 set_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags); in rtw89_wow_set_wakeups()
1082 if (wowlan->n_patterns && wowlan->patterns) in rtw89_wow_set_wakeups()
1083 set_bit(RTW89_WOW_FLAG_EN_PATTERN, rtw_wow->flags); in rtw89_wow_set_wakeups()
1085 if (wowlan->nd_config) in rtw89_wow_set_wakeups()
1086 rtw89_wow_init_pno(rtwdev, wowlan->nd_config); in rtw89_wow_set_wakeups()
1089 /* use the link on HW-0 to do wow flow */ in rtw89_wow_set_wakeups()
1097 rtwvif_link = rtw_wow->rtwvif_link; in rtw89_wow_set_wakeups()
1099 return -EPERM; in rtw89_wow_set_wakeups()
1106 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_cfg_wake_pno()
1117 rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n"); in rtw89_wow_cfg_wake_pno()
1132 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_cfg_wake()
1133 struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; in rtw89_wow_cfg_wake()
1140 wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr); in rtw89_wow_cfg_wake()
1143 rtwsta_link = rtwsta->links[rtwvif_link->link_id]; in rtw89_wow_cfg_wake()
1145 return -ENOLINK; in rtw89_wow_cfg_wake()
1149 if (rtw_wow->pattern_cnt) in rtw89_wow_cfg_wake()
1150 rtwvif_link->wowlan_pattern = true; in rtw89_wow_cfg_wake()
1151 if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) in rtw89_wow_cfg_wake()
1152 rtwvif_link->wowlan_magic = true; in rtw89_wow_cfg_wake()
1154 rtwvif_link->wowlan_pattern = false; in rtw89_wow_cfg_wake()
1155 rtwvif_link->wowlan_magic = false; in rtw89_wow_cfg_wake()
1160 rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n"); in rtw89_wow_cfg_wake()
1190 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; in rtw89_wow_check_fw_status()
1197 mac->wow_ctrl.addr, mac->wow_ctrl.mask); in rtw89_wow_check_fw_status()
1207 enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; in rtw89_wow_swap_fw()
1208 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_swap_fw()
1209 struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; in rtw89_wow_swap_fw()
1211 enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; in rtw89_wow_swap_fw()
1212 const struct rtw89_chip_info *chip = rtwdev->chip; in rtw89_wow_swap_fw()
1213 bool include_bb = !!chip->bbmcu_nr; in rtw89_wow_swap_fw()
1224 wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr); in rtw89_wow_swap_fw()
1227 rtwsta_link = rtwsta->links[rtwvif_link->link_id]; in rtw89_wow_swap_fw()
1229 return -ENOLINK; in rtw89_wow_swap_fw()
1277 ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta_link->mac_id); in rtw89_wow_swap_fw()
1387 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_disable_trx_post()
1402 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_fw_release_pno_pkt_list()
1403 struct list_head *pkt_list = &rtw_wow->pno_pkt_list; in rtw89_fw_release_pno_pkt_list()
1407 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); in rtw89_fw_release_pno_pkt_list()
1408 list_del(&info->list); in rtw89_fw_release_pno_pkt_list()
1416 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_pno_scan_update_probe_req()
1417 struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; in rtw89_pno_scan_update_probe_req()
1418 u8 num = nd_config->n_match_sets, i; in rtw89_pno_scan_update_probe_req()
1424 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, in rtw89_pno_scan_update_probe_req()
1425 nd_config->match_sets[i].ssid.ssid, in rtw89_pno_scan_update_probe_req()
1426 nd_config->match_sets[i].ssid.ssid_len, in rtw89_pno_scan_update_probe_req()
1427 nd_config->ie_len); in rtw89_pno_scan_update_probe_req()
1429 return -ENOMEM; in rtw89_pno_scan_update_probe_req()
1431 skb_put_data(skb, nd_config->ie, nd_config->ie_len); in rtw89_pno_scan_update_probe_req()
1437 return -ENOMEM; in rtw89_pno_scan_update_probe_req()
1440 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); in rtw89_pno_scan_update_probe_req()
1448 list_add_tail(&info->list, &rtw_wow->pno_pkt_list); in rtw89_pno_scan_update_probe_req()
1457 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; in rtw89_pno_scan_offload()
1458 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_pno_scan_offload()
1459 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_pno_scan_offload()
1460 int interval = rtw_wow->nd_config->scan_plans[0].interval; in rtw89_pno_scan_offload()
1471 ret = mac->add_chan_list_pno(rtwdev, rtwvif_link); in rtw89_pno_scan_offload()
1481 opt.delay = max(rtw_wow->nd_config->delay, 1); in rtw89_pno_scan_offload()
1483 if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { in rtw89_pno_scan_offload()
1488 opt.mlo_mode = rtwdev->mlo_dbcc_mode; in rtw89_pno_scan_offload()
1493 mac->scan_offload(rtwdev, &opt, rtwvif_link, true); in rtw89_pno_scan_offload()
1500 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_fw_start()
1501 struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; in rtw89_wow_fw_start()
1568 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_fw_stop()
1569 struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; in rtw89_wow_fw_stop()
1635 set_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); in rtw89_wow_enable()
1668 clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); in rtw89_wow_enable()
1703 clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); in rtw89_wow_disable()
1717 if (!test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags)) { in rtw89_wow_resume()
1719 ret = -EPERM; in rtw89_wow_resume()
1725 ret = -EPERM; in rtw89_wow_resume()
1749 rtw89_err(rtwdev, "failed to set wakeup event\n"); in rtw89_wow_suspend()