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
608 sz = struct_size(rekey_conf, key, cipher_info->len); in rtw89_wow_gtk_rekey()
613 rekey_conf->cipher = cipher; in rtw89_wow_gtk_rekey()
614 rekey_conf->keyidx = keyidx; in rtw89_wow_gtk_rekey()
615 rekey_conf->keylen = cipher_info->len; in rtw89_wow_gtk_rekey()
616 memcpy(rekey_conf->key, gtk, in rtw89_wow_gtk_rekey()
617 flex_array_size(rekey_conf, key, cipher_info->len)); in rtw89_wow_gtk_rekey()
622 mutex_unlock(&rtwdev->mutex); in rtw89_wow_gtk_rekey()
624 key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, rtwvif_link->link_id); in rtw89_wow_gtk_rekey()
626 key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, -1); in rtw89_wow_gtk_rekey()
627 mutex_lock(&rtwdev->mutex); in rtw89_wow_gtk_rekey()
630 if (IS_ERR(key)) { in rtw89_wow_gtk_rekey()
635 return key; in rtw89_wow_gtk_rekey()
640 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_update_key_info()
642 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_update_key_info()
643 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; in rtw89_wow_update_key_info()
647 struct ieee80211_key_conf *key; in rtw89_wow_update_key_info() local
650 ieee80211_iter_keys_rcu(rtwdev->hw, wow_vif, in rtw89_wow_update_key_info()
662 key = rtw89_wow_gtk_rekey(rtwdev, data.gtk_cipher, aoac_rpt->key_idx, in rtw89_wow_update_key_info()
663 aoac_rpt->gtk); in rtw89_wow_update_key_info()
664 if (!key) in rtw89_wow_update_key_info()
667 rtw89_rx_iv_to_pn(rtwdev, key, in rtw89_wow_update_key_info()
668 aoac_rpt->gtk_rx_iv[key->keyidx]); in rtw89_wow_update_key_info()
673 key = rtw89_wow_gtk_rekey(rtwdev, data.igtk_cipher, aoac_rpt->igtk_key_id, in rtw89_wow_update_key_info()
674 aoac_rpt->igtk); in rtw89_wow_update_key_info()
675 if (!key) in rtw89_wow_update_key_info()
678 rtw89_rx_pn_set_pmf(rtwdev, key, aoac_rpt->igtk_ipn); in rtw89_wow_update_key_info()
683 ieee80211_gtk_rekey_notify(wow_vif, bss_conf->bssid, in rtw89_wow_update_key_info()
684 aoac_rpt->eapol_key_replay_count, in rtw89_wow_update_key_info()
702 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_enter_ps()
705 rtw89_enter_lps(rtwdev, rtwvif_link->rtwvif, false); in rtw89_wow_enter_ps()
712 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_leave_ps()
726 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; in rtw89_wow_config_mac()
728 return mac->wow_config_mac(rtwdev, enable_wow); in rtw89_wow_config_mac()
733 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; in rtw89_wow_set_rx_filter()
738 mac->typ_fltr_opt(rtwdev, RTW89_MGNT, fwd_target, RTW89_MAC_0); in rtw89_wow_set_rx_filter()
739 mac->typ_fltr_opt(rtwdev, RTW89_CTRL, fwd_target, RTW89_MAC_0); in rtw89_wow_set_rx_filter()
740 mac->typ_fltr_opt(rtwdev, RTW89_DATA, fwd_target, RTW89_MAC_0); in rtw89_wow_set_rx_filter()
745 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_show_wakeup_reason()
747 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_show_wakeup_reason()
748 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt; in rtw89_wow_show_wakeup_reason()
750 struct cfg80211_wowlan_wakeup wakeup = { in rtw89_wow_show_wakeup_reason() local
751 .pattern_idx = -1, in rtw89_wow_show_wakeup_reason()
756 if (RTW89_CHK_FW_FEATURE(WOW_REASON_V1, &rtwdev->fw)) in rtw89_wow_show_wakeup_reason()
757 wow_reason_reg = rtwdev->chip->wow_reason_reg[RTW89_WOW_REASON_V1]; in rtw89_wow_show_wakeup_reason()
759 wow_reason_reg = rtwdev->chip->wow_reason_reg[RTW89_WOW_REASON_V0]; in rtw89_wow_show_wakeup_reason()
764 wakeup.disconnect = true; in rtw89_wow_show_wakeup_reason()
768 wakeup.disconnect = true; in rtw89_wow_show_wakeup_reason()
772 wakeup.magic_pkt = true; in rtw89_wow_show_wakeup_reason()
776 wakeup.gtk_rekey_failure = true; in rtw89_wow_show_wakeup_reason()
780 wakeup.pattern_idx = aoac_rpt->pattern_idx; in rtw89_wow_show_wakeup_reason()
788 wakeup.net_detect = &nd_info; in rtw89_wow_show_wakeup_reason()
792 rtw89_warn(rtwdev, "Unknown wakeup reason %x\n", reason); in rtw89_wow_show_wakeup_reason()
797 ieee80211_report_wowlan_wakeup(wow_vif, &wakeup, GFP_KERNEL); in rtw89_wow_show_wakeup_reason()
803 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_vif_iter()
810 if (rtw_wow->rtwvif_link || vif->type != NL80211_IFTYPE_STATION) in rtw89_wow_vif_iter()
813 switch (rtwvif_link->net_type) { in rtw89_wow_vif_iter()
816 rtw_wow->rtwvif_link = rtwvif_link; in rtw89_wow_vif_iter()
819 if (rtw_wow->pno_inited) in rtw89_wow_vif_iter()
820 rtw_wow->rtwvif_link = rtwvif_link; in rtw89_wow_vif_iter()
894 rtw_pattern->bc = true; in rtw89_wow_pattern_get_type()
896 rtw_pattern->mc = true; in rtw89_wow_pattern_get_type()
897 else if (ether_addr_equal(da, rtwvif_link->mac_addr) && in rtw89_wow_pattern_get_type()
899 rtw_pattern->uc = true; in rtw89_wow_pattern_get_type()
903 return -EPERM; in rtw89_wow_pattern_get_type()
922 pattern = pkt_pattern->pattern; in rtw89_wow_pattern_generate()
923 len = pkt_pattern->pattern_len; in rtw89_wow_pattern_generate()
924 mask = pkt_pattern->mask; in rtw89_wow_pattern_generate()
936 * |--------+--------+------+-----------+------------+-----| in rtw89_wow_pattern_generate()
942 * |-------------------+--------+------+-----------+------------+-----| in rtw89_wow_pattern_generate()
947 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0, in rtw89_wow_pattern_generate()
953 for (i = 0; i < mask_len - 1; i++) { in rtw89_wow_pattern_generate()
959 /* Set bit 0-5 to zero */ in rtw89_wow_pattern_generate()
962 memcpy(rtw_pattern->mask, mask_hw, sizeof(rtw_pattern->mask)); in rtw89_wow_pattern_generate()
976 rtw_pattern->crc = rtw89_calc_crc(content, count); in rtw89_wow_pattern_generate()
985 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_parse_patterns()
986 struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; in rtw89_wow_parse_patterns()
990 if (!wowlan->n_patterns || !wowlan->patterns) in rtw89_wow_parse_patterns()
993 for (i = 0; i < wowlan->n_patterns; i++) { in rtw89_wow_parse_patterns()
994 rtw_pattern = &rtw_wow->patterns[i]; in rtw89_wow_parse_patterns()
996 &wowlan->patterns[i], in rtw89_wow_parse_patterns()
1000 rtw_wow->pattern_cnt = 0; in rtw89_wow_parse_patterns()
1004 rtw_pattern->r_w = true; in rtw89_wow_parse_patterns()
1005 rtw_pattern->idx = i; in rtw89_wow_parse_patterns()
1006 rtw_pattern->negative_pattern_match = false; in rtw89_wow_parse_patterns()
1007 rtw_pattern->skip_mac_hdr = true; in rtw89_wow_parse_patterns()
1008 rtw_pattern->valid = true; in rtw89_wow_parse_patterns()
1010 rtw_wow->pattern_cnt = wowlan->n_patterns; in rtw89_wow_parse_patterns()
1017 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_pattern_clear_cam()
1018 struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; in rtw89_wow_pattern_clear_cam()
1021 for (i = 0; i < rtw_wow->pattern_cnt; i++) { in rtw89_wow_pattern_clear_cam()
1022 rtw_pattern = &rtw_wow->patterns[i]; in rtw89_wow_pattern_clear_cam()
1023 rtw_pattern->valid = false; in rtw89_wow_pattern_clear_cam()
1030 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_pattern_write()
1031 struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns; in rtw89_wow_pattern_write()
1034 for (i = 0; i < rtw_wow->pattern_cnt; i++) in rtw89_wow_pattern_write()
1040 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_pattern_clear()
1044 rtw_wow->pattern_cnt = 0; in rtw89_wow_pattern_clear()
1045 memset(rtw_wow->patterns, 0, sizeof(rtw_wow->patterns)); in rtw89_wow_pattern_clear()
1050 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_clear_wakeups()
1052 rtw_wow->rtwvif_link = NULL; in rtw89_wow_clear_wakeups()
1053 rtw89_core_release_all_bits_map(rtw_wow->flags, RTW89_WOW_FLAG_NUM); in rtw89_wow_clear_wakeups()
1054 rtw_wow->pattern_cnt = 0; in rtw89_wow_clear_wakeups()
1055 rtw_wow->pno_inited = false; in rtw89_wow_clear_wakeups()
1061 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_init_pno()
1063 if (!nd_config->n_match_sets || !nd_config->n_channels) in rtw89_wow_init_pno()
1066 rtw_wow->nd_config = nd_config; in rtw89_wow_init_pno()
1067 rtw_wow->pno_inited = true; in rtw89_wow_init_pno()
1069 INIT_LIST_HEAD(&rtw_wow->pno_pkt_list); in rtw89_wow_init_pno()
1071 rtw89_debug(rtwdev, RTW89_DBG_WOW, "WOW: net-detect is enabled\n"); in rtw89_wow_init_pno()
1077 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_set_wakeups()
1081 if (wowlan->disconnect) in rtw89_wow_set_wakeups()
1082 set_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags); in rtw89_wow_set_wakeups()
1083 if (wowlan->magic_pkt) in rtw89_wow_set_wakeups()
1084 set_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags); in rtw89_wow_set_wakeups()
1085 if (wowlan->n_patterns && wowlan->patterns) in rtw89_wow_set_wakeups()
1086 set_bit(RTW89_WOW_FLAG_EN_PATTERN, rtw_wow->flags); in rtw89_wow_set_wakeups()
1088 if (wowlan->nd_config) in rtw89_wow_set_wakeups()
1089 rtw89_wow_init_pno(rtwdev, wowlan->nd_config); in rtw89_wow_set_wakeups()
1092 /* use the link on HW-0 to do wow flow */ in rtw89_wow_set_wakeups()
1100 rtwvif_link = rtw_wow->rtwvif_link; in rtw89_wow_set_wakeups()
1102 return -EPERM; in rtw89_wow_set_wakeups()
1109 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_cfg_wake_pno()
1120 rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n"); in rtw89_wow_cfg_wake_pno()
1135 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_cfg_wake()
1136 struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; in rtw89_wow_cfg_wake()
1143 wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr); in rtw89_wow_cfg_wake()
1146 rtwsta_link = rtwsta->links[rtwvif_link->link_id]; in rtw89_wow_cfg_wake()
1148 return -ENOLINK; in rtw89_wow_cfg_wake()
1152 if (rtw_wow->pattern_cnt) in rtw89_wow_cfg_wake()
1153 rtwvif_link->wowlan_pattern = true; in rtw89_wow_cfg_wake()
1154 if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) in rtw89_wow_cfg_wake()
1155 rtwvif_link->wowlan_magic = true; in rtw89_wow_cfg_wake()
1157 rtwvif_link->wowlan_pattern = false; in rtw89_wow_cfg_wake()
1158 rtwvif_link->wowlan_magic = false; in rtw89_wow_cfg_wake()
1163 rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n"); in rtw89_wow_cfg_wake()
1193 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; in rtw89_wow_check_fw_status()
1200 mac->wow_ctrl.addr, mac->wow_ctrl.mask); in rtw89_wow_check_fw_status()
1210 enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen; in rtw89_wow_swap_fw()
1211 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_swap_fw()
1212 struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; in rtw89_wow_swap_fw()
1214 enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id; in rtw89_wow_swap_fw()
1215 const struct rtw89_chip_info *chip = rtwdev->chip; in rtw89_wow_swap_fw()
1216 bool include_bb = !!chip->bbmcu_nr; in rtw89_wow_swap_fw()
1227 wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr); in rtw89_wow_swap_fw()
1230 rtwsta_link = rtwsta->links[rtwvif_link->link_id]; in rtw89_wow_swap_fw()
1232 return -ENOLINK; in rtw89_wow_swap_fw()
1280 ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta_link->mac_id); in rtw89_wow_swap_fw()
1390 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_wow_disable_trx_post()
1405 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_fw_release_pno_pkt_list()
1406 struct list_head *pkt_list = &rtw_wow->pno_pkt_list; in rtw89_fw_release_pno_pkt_list()
1410 rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); in rtw89_fw_release_pno_pkt_list()
1411 list_del(&info->list); in rtw89_fw_release_pno_pkt_list()
1419 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_pno_scan_update_probe_req()
1420 struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config; in rtw89_pno_scan_update_probe_req()
1421 u8 num = nd_config->n_match_sets, i; in rtw89_pno_scan_update_probe_req()
1427 skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr, in rtw89_pno_scan_update_probe_req()
1428 nd_config->match_sets[i].ssid.ssid, in rtw89_pno_scan_update_probe_req()
1429 nd_config->match_sets[i].ssid.ssid_len, in rtw89_pno_scan_update_probe_req()
1430 nd_config->ie_len); in rtw89_pno_scan_update_probe_req()
1432 return -ENOMEM; in rtw89_pno_scan_update_probe_req()
1434 skb_put_data(skb, nd_config->ie, nd_config->ie_len); in rtw89_pno_scan_update_probe_req()
1440 return -ENOMEM; in rtw89_pno_scan_update_probe_req()
1443 ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); in rtw89_pno_scan_update_probe_req()
1451 list_add_tail(&info->list, &rtw_wow->pno_pkt_list); in rtw89_pno_scan_update_probe_req()
1460 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; in rtw89_pno_scan_offload()
1461 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_pno_scan_offload()
1462 struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link; in rtw89_pno_scan_offload()
1463 int interval = rtw_wow->nd_config->scan_plans[0].interval; in rtw89_pno_scan_offload()
1474 ret = mac->add_chan_list_pno(rtwdev, rtwvif_link); in rtw89_pno_scan_offload()
1484 opt.delay = max(rtw_wow->nd_config->delay, 1); in rtw89_pno_scan_offload()
1486 if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { in rtw89_pno_scan_offload()
1491 opt.mlo_mode = rtwdev->mlo_dbcc_mode; in rtw89_pno_scan_offload()
1496 mac->scan_offload(rtwdev, &opt, rtwvif_link, true); in rtw89_pno_scan_offload()
1503 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_fw_start()
1504 struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; in rtw89_wow_fw_start()
1571 struct rtw89_wow_param *rtw_wow = &rtwdev->wow; in rtw89_wow_fw_stop()
1572 struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link; in rtw89_wow_fw_stop()
1638 set_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); in rtw89_wow_enable()
1671 clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); in rtw89_wow_enable()
1706 clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags); in rtw89_wow_disable()
1720 if (!test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags)) { in rtw89_wow_resume()
1722 ret = -EPERM; in rtw89_wow_resume()
1728 ret = -EPERM; in rtw89_wow_resume()
1752 rtw89_err(rtwdev, "failed to set wakeup event\n"); in rtw89_wow_suspend()