Lines Matching +full:valid +full:- +full:wakeup +full:- +full:mask

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;
18 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
19 const u8 *rsn, *ies = mgmt->u.assoc_req.variable;
22 rsn = cfg80211_find_ie(WLAN_EID_RSN, ies, skb->len);
27 rtw_wow->akm = rsn_ie->akm_cipher_suite.type;
55 if (cipher_info_defs->cipher == cipher)
65 switch (key->cipher) {
80 return -EINVAL;
110 err = _pn_to_iv(rtwdev, key, iv, pn, key->keyidx);
114 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx to iv-%*ph\n",
115 __func__, key->keyidx, pn, 8, iv);
127 pn = atomic64_inc_return(&key->tx_pn);
128 err = _pn_to_iv(rtwdev, key, iv, pn, key->keyidx);
132 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx to iv-%*ph\n",
133 __func__, key->keyidx, pn, 8, iv);
141 switch (key->cipher) {
154 return -EINVAL;
189 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d iv-%*ph to pn-%*ph\n",
190 __func__, key->keyidx, 8, iv, 6, seq.ccmp.pn);
206 atomic64_set(&key->tx_pn, pn);
207 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d iv-%*ph to pn-%llx\n",
208 __func__, key->keyidx, 8, iv, pn);
220 if (key->keyidx == 4)
221 memcpy(gtk_info->igtk[0], key->key, key->keylen);
222 else if (key->keyidx == 5)
223 memcpy(gtk_info->igtk[1], key->key, key->keylen);
225 return -EINVAL;
236 gtk_info->ipn = cpu_to_le64(pn);
237 gtk_info->igtk_keyid = cpu_to_le32(key->keyidx);
238 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%llx\n",
239 __func__, key->keyidx, pn);
248 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
249 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
252 if (key->keyidx != aoac_rpt->igtk_key_id)
264 rtw89_debug(rtwdev, RTW89_DBG_WOW, "%s key %d pn-%*ph\n",
265 __func__, key->keyidx, 6, seq.ccmp.pn);
276 struct rtw89_dev *rtwdev = hw->priv;
277 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
278 struct rtw89_wow_key_info *key_info = &rtw_wow->key_info;
279 struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info;
284 cipher_info = rtw89_cipher_alg_recognize(key->cipher);
286 switch (key->cipher) {
294 key_info->ptk_tx_iv);
298 key_info->ptk_rx_iv);
302 rtw_wow->ptk_alg = cipher_info->fw_alg;
303 rtw_wow->ptk_keyidx = key->keyidx;
306 key_info->gtk_rx_iv[key->keyidx]);
310 rtw_wow->gtk_alg = cipher_info->fw_alg;
311 key_info->gtk_keyidx = key->keyidx;
324 rtw_wow->ptk_alg = cipher_info->fw_alg;
325 rtw_wow->ptk_keyidx = key->keyidx;
326 rtw_wow->gtk_alg = cipher_info->fw_alg;
327 key_info->gtk_keyidx = key->keyidx;
331 key->cipher);
346 struct rtw89_dev *rtwdev = hw->priv;
347 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
348 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
350 bool update_tx_key_info = iter_data->rx_ready;
353 switch (key->cipher) {
361 aoac_rpt->ptk_rx_iv);
368 aoac_rpt->ptk_tx_iv);
375 aoac_rpt->gtk_rx_iv[key->keyidx]);
380 if (!sta && update_tx_key_info && aoac_rpt->rekey_ok)
381 iter_data->gtk_cipher = key->cipher;
385 if (aoac_rpt->rekey_ok)
386 iter_data->igtk_cipher = key->cipher;
389 aoac_rpt->igtk_ipn);
399 key->cipher);
406 iter_data->error = true;
411 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
413 memset(&rtw_wow->aoac_rpt, 0, sizeof(rtw_wow->aoac_rpt));
414 memset(&rtw_wow->gtk_info, 0, sizeof(rtw_wow->gtk_info));
415 memset(&rtw_wow->key_info, 0, sizeof(rtw_wow->key_info));
416 rtw_wow->ptk_alg = 0;
417 rtw_wow->gtk_alg = 0;
422 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
423 struct rtw89_wow_key_info *key_info = &rtw_wow->key_info;
424 struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
428 ieee80211_iter_keys_rcu(rtwdev->hw, wow_vif,
437 key_info->valid_check = RTW89_WOW_VALID_CHECK;
438 key_info->symbol_check_en = RTW89_WOW_SYMBOL_CHK_PTK |
444 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
445 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
451 aoac_rpt->rpt_ver);
453 aoac_rpt->sec_type);
455 aoac_rpt->key_idx);
457 aoac_rpt->pattern_idx);
459 aoac_rpt->rekey_ok);
461 8, aoac_rpt->ptk_tx_iv);
464 8, aoac_rpt->eapol_key_replay_count);
466 8, aoac_rpt->ptk_rx_iv);
468 8, aoac_rpt->gtk_rx_iv[0]);
470 8, aoac_rpt->gtk_rx_iv[1]);
472 8, aoac_rpt->gtk_rx_iv[2]);
474 8, aoac_rpt->gtk_rx_iv[3]);
476 aoac_rpt->igtk_key_id);
478 aoac_rpt->igtk_ipn);
480 32, aoac_rpt->igtk);
485 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
486 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
499 aoac_rpt->key_idx =
501 key_idx = aoac_rpt->key_idx;
502 aoac_rpt->gtk_rx_iv[key_idx][0] =
504 aoac_rpt->gtk_rx_iv[key_idx][1] =
506 aoac_rpt->gtk_rx_iv[key_idx][2] =
508 aoac_rpt->gtk_rx_iv[key_idx][3] =
510 aoac_rpt->gtk_rx_iv[key_idx][4] =
512 aoac_rpt->gtk_rx_iv[key_idx][5] =
514 aoac_rpt->gtk_rx_iv[key_idx][6] =
516 aoac_rpt->gtk_rx_iv[key_idx][7] =
518 aoac_rpt->ptk_rx_iv[0] =
520 aoac_rpt->ptk_rx_iv[1] =
522 aoac_rpt->ptk_rx_iv[2] =
524 aoac_rpt->ptk_rx_iv[3] =
533 aoac_rpt->ptk_rx_iv[4] =
535 aoac_rpt->ptk_rx_iv[5] =
537 aoac_rpt->ptk_rx_iv[6] =
539 aoac_rpt->ptk_rx_iv[7] =
557 aoac_rpt->igtk_ipn = u64_encode_bits(igtk_ipn[0], RTW89_IGTK_IPN_0) |
571 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
574 if (!rtw_wow->ptk_alg)
575 return -EPERM;
599 struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
606 sz = struct_size(rekey_conf, key, cipher_info->len);
611 rekey_conf->cipher = cipher;
612 rekey_conf->keyidx = keyidx;
613 rekey_conf->keylen = cipher_info->len;
614 memcpy(rekey_conf->key, gtk,
615 flex_array_size(rekey_conf, key, cipher_info->len));
620 mutex_unlock(&rtwdev->mutex);
621 key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, -1);
622 mutex_lock(&rtwdev->mutex);
635 struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
636 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
637 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
643 ieee80211_iter_keys_rcu(rtwdev->hw, wow_vif,
655 key = rtw89_wow_gtk_rekey(rtwdev, data.gtk_cipher, aoac_rpt->key_idx,
656 aoac_rpt->gtk);
661 aoac_rpt->gtk_rx_iv[key->keyidx]);
666 key = rtw89_wow_gtk_rekey(rtwdev, data.igtk_cipher, aoac_rpt->igtk_key_id,
667 aoac_rpt->igtk);
671 rtw89_rx_pn_set_pmf(rtwdev, key, aoac_rpt->igtk_ipn);
672 ieee80211_gtk_rekey_notify(wow_vif, wow_vif->bss_conf.bssid,
673 aoac_rpt->eapol_key_replay_count,
684 struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
685 struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
692 struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
693 struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
705 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
707 return mac->wow_config_mac(rtwdev, enable_wow);
712 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
717 mac->typ_fltr_opt(rtwdev, RTW89_MGNT, fwd_target, RTW89_MAC_0);
718 mac->typ_fltr_opt(rtwdev, RTW89_CTRL, fwd_target, RTW89_MAC_0);
719 mac->typ_fltr_opt(rtwdev, RTW89_DATA, fwd_target, RTW89_MAC_0);
724 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
725 struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
727 struct cfg80211_wowlan_wakeup wakeup = {
728 .pattern_idx = -1,
733 if (RTW89_CHK_FW_FEATURE(WOW_REASON_V1, &rtwdev->fw))
734 wow_reason_reg = rtwdev->chip->wow_reason_reg[RTW89_WOW_REASON_V1];
736 wow_reason_reg = rtwdev->chip->wow_reason_reg[RTW89_WOW_REASON_V0];
741 wakeup.disconnect = true;
745 wakeup.disconnect = true;
749 wakeup.magic_pkt = true;
753 wakeup.gtk_rekey_failure = true;
757 wakeup.pattern_idx = aoac_rpt->pattern_idx;
765 wakeup.net_detect = &nd_info;
769 rtw89_warn(rtwdev, "Unknown wakeup reason %x\n", reason);
770 ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, NULL,
775 ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, &wakeup,
781 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
787 if (rtw_wow->wow_vif || vif->type != NL80211_IFTYPE_STATION)
790 switch (rtwvif->net_type) {
792 rtw_wow->wow_vif = vif;
867 rtw_pattern->bc = true;
869 rtw_pattern->mc = true;
870 else if (ether_addr_equal(da, rtwvif->mac_addr) &&
872 rtw_pattern->uc = true;
876 return -EPERM;
888 const u8 *mask;
895 pattern = pkt_pattern->pattern;
896 len = pkt_pattern->pattern_len;
897 mask = pkt_pattern->mask;
902 mask[0] & GENMASK(5, 0));
906 /* translate mask from os to mask for hw
909 * |--------+--------+------+-----------+------------+-----|
915 * |-------------------+--------+------+-----------+------------+-----|
920 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
921 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
926 for (i = 0; i < mask_len - 1; i++) {
927 mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6)) |
928 u8_get_bits(mask[i + 1], GENMASK(5, 0)) << 2;
930 mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6));
932 /* Set bit 0-5 to zero */
935 memcpy(rtw_pattern->mask, mask_hw, sizeof(rtw_pattern->mask));
937 /* To get the wake up pattern from the mask.
943 if ((mask[i / 8] >> (i % 8)) & 0x01) {
949 rtw_pattern->crc = rtw89_calc_crc(content, count);
958 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
959 struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns;
963 if (!wowlan->n_patterns || !wowlan->patterns)
966 for (i = 0; i < wowlan->n_patterns; i++) {
967 rtw_pattern = &rtw_wow->patterns[i];
969 &wowlan->patterns[i],
973 rtw_wow->pattern_cnt = 0;
977 rtw_pattern->r_w = true;
978 rtw_pattern->idx = i;
979 rtw_pattern->negative_pattern_match = false;
980 rtw_pattern->skip_mac_hdr = true;
981 rtw_pattern->valid = true;
983 rtw_wow->pattern_cnt = wowlan->n_patterns;
990 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
991 struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns;
994 for (i = 0; i < rtw_wow->pattern_cnt; i++) {
995 rtw_pattern = &rtw_wow->patterns[i];
996 rtw_pattern->valid = false;
1003 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
1004 struct rtw89_wow_cam_info *rtw_pattern = rtw_wow->patterns;
1007 for (i = 0; i < rtw_wow->pattern_cnt; i++)
1013 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
1017 rtw_wow->pattern_cnt = 0;
1018 memset(rtw_wow->patterns, 0, sizeof(rtw_wow->patterns));
1023 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
1025 rtw_wow->wow_vif = NULL;
1026 rtw89_core_release_all_bits_map(rtw_wow->flags, RTW89_WOW_FLAG_NUM);
1027 rtw_wow->pattern_cnt = 0;
1033 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
1036 if (wowlan->disconnect)
1037 set_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags);
1038 if (wowlan->magic_pkt)
1039 set_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags);
1044 if (!rtw_wow->wow_vif)
1045 return -EPERM;
1047 rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv;
1053 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
1054 struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
1055 struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
1060 wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid);
1062 rtwsta = (struct rtw89_sta *)wow_sta->drv_priv;
1065 if (rtw_wow->pattern_cnt)
1066 rtwvif->wowlan_pattern = true;
1067 if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags))
1068 rtwvif->wowlan_magic = true;
1070 rtwvif->wowlan_pattern = false;
1071 rtwvif->wowlan_magic = false;
1076 rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n");
1106 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
1113 mac->wow_ctrl.addr, mac->wow_ctrl.mask);
1123 enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
1124 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
1125 struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
1126 struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
1127 enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
1128 const struct rtw89_chip_info *chip = rtwdev->chip;
1129 bool include_bb = !!chip->bbmcu_nr;
1139 wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid);
1141 rtwsta = (struct rtw89_sta *)wow_sta->drv_priv;
1188 ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id);
1298 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
1299 struct ieee80211_vif *vif = rtw_wow->wow_vif;
1313 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
1314 struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv;
1360 struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
1361 struct rtw89_vif *rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv;
1411 set_bit(RTW89_FLAG_WOWLAN, rtwdev->flags);
1444 clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags);
1479 clear_bit(RTW89_FLAG_WOWLAN, rtwdev->flags);
1487 if (!test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags)) {
1489 ret = -EPERM;
1495 ret = -EPERM;
1518 rtw89_err(rtwdev, "failed to set wakeup event\n");