Lines Matching +full:cs +full:- +full:dev +full:- +full:assoc

1 // SPDX-License-Identifier: ISC
3 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
109 if (!test_bit(WMI_FW_CAPABILITY_CHANNEL_4, wil->fw_capabilities)) in wil_num_supported_channels()
110 num_channels--; in wil_num_supported_channels()
121 wiphy->bands[NL80211_BAND_60GHZ]->n_channels = in update_supported_bands()
124 if (test_bit(WMI_FW_CAPABILITY_CHANNEL_BONDING, wil->fw_capabilities)) { in update_supported_bands()
125 wiphy->bands[NL80211_BAND_60GHZ]->edmg_cap.channels = in update_supported_bands()
127 wiphy->bands[NL80211_BAND_60GHZ]->edmg_cap.bw_config = in update_supported_bands()
136 * qca_wlan_vendor_attr is open source file src/common/qca-vendor.h in
175 QCA_ATTR_DMG_RF_SECTOR_CFG_AFTER_LAST - 1
265 /* MCS 1..12 - SC PHY */
347 return -EOPNOTSUPP; in wil_iftype_nl2wmi()
384 return -EINVAL; in wil_spec2wmi_ch()
424 return -EINVAL; in wil_wmi2spec_ch()
442 struct wil_net_stats *stats = &wil->sta[cid].stats; in wil_cid_fill_sinfo()
450 rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, vif->mid, &cmd, sizeof(cmd), in wil_cid_fill_sinfo()
464 cid, vif->mid, WIL_EXTENDED_MCS_CHECK(tx_mcs), in wil_cid_fill_sinfo()
477 sinfo->generation = wil->sinfo_gen; in wil_cid_fill_sinfo()
479 sinfo->filled = BIT_ULL(NL80211_STA_INFO_RX_BYTES) | in wil_cid_fill_sinfo()
488 if (wil->use_enhanced_dma_hw && reply.evt.tx_mode != WMI_TX_MODE_DMG) { in wil_cid_fill_sinfo()
493 rx_mcs = stats->last_mcs_rx; in wil_cid_fill_sinfo()
507 sinfo->txrate.flags = tx_rate_flag; in wil_cid_fill_sinfo()
508 sinfo->rxrate.flags = rx_rate_flag; in wil_cid_fill_sinfo()
509 sinfo->txrate.mcs = tx_mcs; in wil_cid_fill_sinfo()
510 sinfo->rxrate.mcs = rx_mcs; in wil_cid_fill_sinfo()
512 sinfo->txrate.n_bonded_ch = in wil_cid_fill_sinfo()
514 sinfo->rxrate.n_bonded_ch = in wil_cid_fill_sinfo()
515 wil_rx_cb_mode_to_n_bonded(stats->last_cb_mode_rx); in wil_cid_fill_sinfo()
516 sinfo->rx_bytes = stats->rx_bytes; in wil_cid_fill_sinfo()
517 sinfo->rx_packets = stats->rx_packets; in wil_cid_fill_sinfo()
518 sinfo->rx_dropped_misc = stats->rx_dropped; in wil_cid_fill_sinfo()
519 sinfo->tx_bytes = stats->tx_bytes; in wil_cid_fill_sinfo()
520 sinfo->tx_packets = stats->tx_packets; in wil_cid_fill_sinfo()
521 sinfo->tx_failed = stats->tx_errors; in wil_cid_fill_sinfo()
523 if (test_bit(wil_vif_fwconnected, vif->status)) { in wil_cid_fill_sinfo()
524 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); in wil_cid_fill_sinfo()
526 wil->fw_capabilities)) in wil_cid_fill_sinfo()
527 sinfo->signal = reply.evt.rssi; in wil_cid_fill_sinfo()
529 sinfo->signal = reply.evt.sqi; in wil_cid_fill_sinfo()
543 int cid = wil_find_cid(wil, vif->mid, mac); in wil_cfg80211_get_station()
546 vif->mid); in wil_cfg80211_get_station()
548 return -ENOENT; in wil_cfg80211_get_station()
556 * Find @idx-th active STA for specific MID for station dump.
562 for (i = 0; i < wil->max_assoc_sta; i++) { in wil_find_cid_by_idx()
563 if (wil->sta[i].status == wil_sta_unused) in wil_find_cid_by_idx()
565 if (wil->sta[i].mid != mid) in wil_find_cid_by_idx()
569 idx--; in wil_find_cid_by_idx()
572 return -ENOENT; in wil_find_cid_by_idx()
576 struct net_device *dev, int idx, in wil_cfg80211_dump_station() argument
579 struct wil6210_vif *vif = ndev_to_vif(dev); in wil_cfg80211_dump_station()
582 int cid = wil_find_cid_by_idx(wil, vif->mid, idx); in wil_cfg80211_dump_station()
585 return -ENOENT; in wil_cfg80211_dump_station()
587 ether_addr_copy(mac, wil->sta[cid].addr); in wil_cfg80211_dump_station()
589 vif->mid); in wil_cfg80211_dump_station()
602 wil->p2p_dev_started = 1; in wil_cfg80211_start_p2p_device()
611 if (!wil->p2p_dev_started) in wil_cfg80211_stop_p2p_device()
615 mutex_lock(&wil->mutex); in wil_cfg80211_stop_p2p_device()
616 mutex_lock(&wil->vif_mutex); in wil_cfg80211_stop_p2p_device()
618 wil->p2p_dev_started = 0; in wil_cfg80211_stop_p2p_device()
619 mutex_unlock(&wil->vif_mutex); in wil_cfg80211_stop_p2p_device()
620 mutex_unlock(&wil->mutex); in wil_cfg80211_stop_p2p_device()
633 if (wil->vifs[i]) { in wil_cfg80211_validate_add_iface()
634 wdev = vif_to_wdev(wil->vifs[i]); in wil_cfg80211_validate_add_iface()
635 params.iftype_num[wdev->iftype]++; in wil_cfg80211_validate_add_iface()
639 return cfg80211_check_combinations(wil->wiphy, &params); in wil_cfg80211_validate_add_iface()
654 struct wil6210_vif *vif_pos = wil->vifs[i]; in wil_cfg80211_validate_change_iface()
658 params.iftype_num[wdev->iftype]++; in wil_cfg80211_validate_change_iface()
665 ret = cfg80211_check_combinations(wil->wiphy, &params); in wil_cfg80211_validate_change_iface()
677 struct net_device *ndev_main = wil->main_ndev, *ndev; in wil_cfg80211_add_iface()
684 /* P2P device is not a real virtual interface, it is a management-only in wil_cfg80211_add_iface()
689 if (wil->p2p_wdev) { in wil_cfg80211_add_iface()
691 return ERR_PTR(-EINVAL); in wil_cfg80211_add_iface()
696 return ERR_PTR(-ENOMEM); in wil_cfg80211_add_iface()
698 p2p_wdev->iftype = type; in wil_cfg80211_add_iface()
699 p2p_wdev->wiphy = wiphy; in wil_cfg80211_add_iface()
701 ether_addr_copy(p2p_wdev->address, ndev_main->perm_addr); in wil_cfg80211_add_iface()
703 wil->p2p_wdev = p2p_wdev; in wil_cfg80211_add_iface()
708 if (!wil->wiphy->n_iface_combinations) { in wil_cfg80211_add_iface()
710 return ERR_PTR(-EINVAL); in wil_cfg80211_add_iface()
724 ether_addr_copy(ndev->perm_addr, ndev_main->perm_addr); in wil_cfg80211_add_iface()
725 if (is_valid_ether_addr(params->macaddr)) { in wil_cfg80211_add_iface()
726 eth_hw_addr_set(ndev, params->macaddr); in wil_cfg80211_add_iface()
730 ether_addr_copy(addr, ndev_main->perm_addr); in wil_cfg80211_add_iface()
731 addr[0] = (addr[0] ^ (1 << vif->mid)) | 0x2; /* locally administered */ in wil_cfg80211_add_iface()
735 ether_addr_copy(wdev->address, ndev->dev_addr); in wil_cfg80211_add_iface()
742 vif->mid, type, wdev->address); in wil_cfg80211_add_iface()
756 if (wdev->iftype != NL80211_IFTYPE_AP) in wil_vif_prepare_stop()
783 if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) { in wil_cfg80211_del_iface()
784 if (wdev != wil->p2p_wdev) { in wil_cfg80211_del_iface()
787 return -EINVAL; in wil_cfg80211_del_iface()
795 if (vif->mid == 0) { in wil_cfg80211_del_iface()
797 return -EINVAL; in wil_cfg80211_del_iface()
805 vif->mid, wdev->iftype, wdev->address); in wil_cfg80211_del_iface()
807 wil_vif_remove(wil, vif->mid); in wil_cfg80211_del_iface()
835 if (wiphy->n_iface_combinations) { in wil_cfg80211_change_iface()
848 !wil_is_safe_switch(wdev->iftype, type)) { in wil_cfg80211_change_iface()
850 mutex_lock(&wil->mutex); in wil_cfg80211_change_iface()
853 mutex_unlock(&wil->mutex); in wil_cfg80211_change_iface()
867 if (params->flags) in wil_cfg80211_change_iface()
868 wil->monitor_flags = params->flags; in wil_cfg80211_change_iface()
871 return -EOPNOTSUPP; in wil_cfg80211_change_iface()
874 if (vif->mid != 0 && wil_has_active_ifaces(wil, true, false)) { in wil_cfg80211_change_iface()
877 rc = wmi_port_delete(wil, vif->mid); in wil_cfg80211_change_iface()
880 rc = wmi_port_allocate(wil, vif->mid, ndev->dev_addr, type); in wil_cfg80211_change_iface()
885 wdev->iftype = type; in wil_cfg80211_change_iface()
893 struct wireless_dev *wdev = request->wdev; in wil_cfg80211_scan()
900 wil_dbg_misc(wil, "scan: wdev=0x%p iftype=%d\n", wdev, wdev->iftype); in wil_cfg80211_scan()
903 switch (wdev->iftype) { in wil_cfg80211_scan()
910 return -EOPNOTSUPP; in wil_cfg80211_scan()
914 if (test_bit(wil_status_dontscan, wil->status)) { in wil_cfg80211_scan()
916 return -EBUSY; in wil_cfg80211_scan()
919 mutex_lock(&wil->mutex); in wil_cfg80211_scan()
921 mutex_lock(&wil->vif_mutex); in wil_cfg80211_scan()
922 if (vif->scan_request || vif->p2p.discovery_started) { in wil_cfg80211_scan()
924 mutex_unlock(&wil->vif_mutex); in wil_cfg80211_scan()
925 rc = -EAGAIN; in wil_cfg80211_scan()
928 mutex_unlock(&wil->vif_mutex); in wil_cfg80211_scan()
930 if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) { in wil_cfg80211_scan()
931 if (!wil->p2p_dev_started) { in wil_cfg80211_scan()
933 rc = -EIO; in wil_cfg80211_scan()
938 vif->scan_request = request; in wil_cfg80211_scan()
939 if (vif->mid == 0) in wil_cfg80211_scan()
940 wil->radio_wdev = wdev; in wil_cfg80211_scan()
943 if (vif->mid == 0) in wil_cfg80211_scan()
944 wil->radio_wdev = in wil_cfg80211_scan()
945 wil->main_ndev->ieee80211_ptr; in wil_cfg80211_scan()
946 vif->scan_request = NULL; in wil_cfg80211_scan()
955 wil_dbg_misc(wil, "SSID count: %d", request->n_ssids); in wil_cfg80211_scan()
957 for (i = 0; i < request->n_ssids; i++) { in wil_cfg80211_scan()
960 request->ssids[i].ssid, in wil_cfg80211_scan()
961 request->ssids[i].ssid_len, true); in wil_cfg80211_scan()
964 if (request->n_ssids) in wil_cfg80211_scan()
965 rc = wmi_set_ssid(vif, request->ssids[0].ssid_len, in wil_cfg80211_scan()
966 request->ssids[0].ssid); in wil_cfg80211_scan()
975 vif->scan_request = request; in wil_cfg80211_scan()
976 mod_timer(&vif->scan_timer, jiffies + WIL6210_SCAN_TO); in wil_cfg80211_scan()
978 cmd->scan_type = WMI_ACTIVE_SCAN; in wil_cfg80211_scan()
979 cmd->num_channels = 0; in wil_cfg80211_scan()
980 n = min(request->n_channels, 4U); in wil_cfg80211_scan()
982 int ch = request->channels[i]->hw_value; in wil_cfg80211_scan()
987 request->channels[i]->center_freq); in wil_cfg80211_scan()
990 /* 0-based channel indexes */ in wil_cfg80211_scan()
991 cmd->num_channels++; in wil_cfg80211_scan()
992 cmd->channel_list[cmd->num_channels - 1].channel = ch - 1; in wil_cfg80211_scan()
994 request->channels[i]->center_freq); in wil_cfg80211_scan()
997 if (request->ie_len) in wil_cfg80211_scan()
999 request->ie, request->ie_len, true); in wil_cfg80211_scan()
1004 request->ie_len, request->ie); in wil_cfg80211_scan()
1008 if (wil->discovery_mode && cmd->scan_type == WMI_ACTIVE_SCAN) { in wil_cfg80211_scan()
1009 cmd->discovery_mode = 1; in wil_cfg80211_scan()
1013 if (vif->mid == 0) in wil_cfg80211_scan()
1014 wil->radio_wdev = wdev; in wil_cfg80211_scan()
1015 rc = wmi_send(wil, WMI_START_SCAN_CMDID, vif->mid, in wil_cfg80211_scan()
1016 cmd, struct_size(cmd, channel_list, cmd->num_channels)); in wil_cfg80211_scan()
1020 del_timer_sync(&vif->scan_timer); in wil_cfg80211_scan()
1021 if (vif->mid == 0) in wil_cfg80211_scan()
1022 wil->radio_wdev = wil->main_ndev->ieee80211_ptr; in wil_cfg80211_scan()
1023 vif->scan_request = NULL; in wil_cfg80211_scan()
1026 mutex_unlock(&wil->mutex); in wil_cfg80211_scan()
1036 wil_dbg_misc(wil, "wdev=0x%p iftype=%d\n", wdev, wdev->iftype); in wil_cfg80211_abort_scan()
1038 mutex_lock(&wil->mutex); in wil_cfg80211_abort_scan()
1039 mutex_lock(&wil->vif_mutex); in wil_cfg80211_abort_scan()
1041 if (!vif->scan_request) in wil_cfg80211_abort_scan()
1044 if (wdev != vif->scan_request->wdev) { in wil_cfg80211_abort_scan()
1049 if (wdev == wil->p2p_wdev && wil->radio_wdev == wil->p2p_wdev) in wil_cfg80211_abort_scan()
1055 mutex_unlock(&wil->vif_mutex); in wil_cfg80211_abort_scan()
1056 mutex_unlock(&wil->mutex); in wil_cfg80211_abort_scan()
1065 c->wpa_versions, c->cipher_group); in wil_print_crypto()
1066 wil_dbg_misc(wil, "Pairwise ciphers [%d] {\n", c->n_ciphers_pairwise); in wil_print_crypto()
1067 n = min_t(int, c->n_ciphers_pairwise, ARRAY_SIZE(c->ciphers_pairwise)); in wil_print_crypto()
1070 c->ciphers_pairwise[i]); in wil_print_crypto()
1072 wil_dbg_misc(wil, "AKM suites [%d] {\n", c->n_akm_suites); in wil_print_crypto()
1073 n = min_t(int, c->n_akm_suites, ARRAY_SIZE(c->akm_suites)); in wil_print_crypto()
1076 c->akm_suites[i]); in wil_print_crypto()
1079 c->control_port, be16_to_cpu(c->control_port_ethertype), in wil_print_crypto()
1080 c->control_port_no_encrypt); in wil_print_crypto()
1107 if (sme->channel) { in wil_print_connect_params()
1109 sme->channel->hw_value, sme->channel->center_freq); in wil_print_connect_params()
1111 if (sme->bssid) in wil_print_connect_params()
1112 wil_info(wil, " BSSID: %pM\n", sme->bssid); in wil_print_connect_params()
1113 if (sme->ssid) in wil_print_connect_params()
1115 16, 1, sme->ssid, sme->ssid_len, true); in wil_print_connect_params()
1116 if (sme->prev_bssid) in wil_print_connect_params()
1117 wil_info(wil, " Previous BSSID=%pM\n", sme->prev_bssid); in wil_print_connect_params()
1119 wil_get_auth_type_name(sme->auth_type)); in wil_print_connect_params()
1120 wil_info(wil, " Privacy: %s\n", sme->privacy ? "secure" : "open"); in wil_print_connect_params()
1121 wil_info(wil, " PBSS: %d\n", sme->pbss); in wil_print_connect_params()
1122 wil_print_crypto(wil, &sme->crypto); in wil_print_connect_params()
1134 if (!test_bit(WMI_FW_CAPABILITY_FT_ROAMING, wil->fw_capabilities)) { in wil_ft_connect()
1136 return -EOPNOTSUPP; in wil_ft_connect()
1139 if (!sme->prev_bssid) { in wil_ft_connect()
1141 return -EINVAL; in wil_ft_connect()
1144 if (ether_addr_equal(sme->prev_bssid, sme->bssid)) { in wil_ft_connect()
1146 return -EINVAL; in wil_ft_connect()
1149 if (!test_bit(wil_vif_fwconnected, vif->status)) { in wil_ft_connect()
1151 return -EINVAL; in wil_ft_connect()
1154 if (vif->privacy != sme->privacy) { in wil_ft_connect()
1156 vif->privacy, sme->privacy); in wil_ft_connect()
1157 return -EINVAL; in wil_ft_connect()
1160 if (sme->pbss) { in wil_ft_connect()
1162 return -EINVAL; in wil_ft_connect()
1166 auth_cmd.channel = sme->channel->hw_value - 1; in wil_ft_connect()
1167 ether_addr_copy(auth_cmd.bssid, sme->bssid); in wil_ft_connect()
1171 set_bit(wil_vif_ft_roam, vif->status); in wil_ft_connect()
1172 rc = wmi_send(wil, WMI_FT_AUTH_CMDID, vif->mid, in wil_ft_connect()
1175 mod_timer(&vif->connect_timer, in wil_ft_connect()
1178 clear_bit(wil_vif_ft_roam, vif->status); in wil_ft_connect()
1201 return -EINVAL; in wil_get_wmi_edmg_channel()
1206 return -EINVAL; in wil_get_wmi_edmg_channel()
1226 wil_dbg_misc(wil, "connect, mid=%d\n", vif->mid); in wil_cfg80211_connect()
1229 if (sme->auth_type == NL80211_AUTHTYPE_FT) in wil_cfg80211_connect()
1231 if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC && in wil_cfg80211_connect()
1232 test_bit(wil_vif_fwconnected, vif->status)) in wil_cfg80211_connect()
1236 if (test_bit(wil_vif_fwconnecting, vif->status) || in wil_cfg80211_connect()
1237 test_bit(wil_vif_fwconnected, vif->status)) in wil_cfg80211_connect()
1238 return -EALREADY; in wil_cfg80211_connect()
1240 if (sme->ie_len > WMI_MAX_IE_LEN) { in wil_cfg80211_connect()
1241 wil_err(wil, "IE too large (%td bytes)\n", sme->ie_len); in wil_cfg80211_connect()
1242 return -ERANGE; in wil_cfg80211_connect()
1245 rsn_eid = sme->ie ? in wil_cfg80211_connect()
1246 cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) : in wil_cfg80211_connect()
1248 if (sme->privacy && !rsn_eid) { in wil_cfg80211_connect()
1252 return -EINVAL; in wil_cfg80211_connect()
1256 if (sme->pbss) in wil_cfg80211_connect()
1259 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, in wil_cfg80211_connect()
1260 sme->ssid, sme->ssid_len, in wil_cfg80211_connect()
1264 return -ENOENT; in wil_cfg80211_connect()
1270 rc = -ENOENT; in wil_cfg80211_connect()
1273 vif->privacy = sme->privacy; in wil_cfg80211_connect()
1274 vif->pbss = sme->pbss; in wil_cfg80211_connect()
1276 rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie); in wil_cfg80211_connect()
1280 switch (bss->capability & WLAN_CAPABILITY_DMG_TYPE_MASK) { in wil_cfg80211_connect()
1289 bss->capability); in wil_cfg80211_connect()
1290 rc = -EINVAL; in wil_cfg80211_connect()
1294 ch = bss->channel->hw_value; in wil_cfg80211_connect()
1297 bss->channel->center_freq); in wil_cfg80211_connect()
1298 rc = -EOPNOTSUPP; in wil_cfg80211_connect()
1305 bss->capability); in wil_cfg80211_connect()
1306 rc = -EINVAL; in wil_cfg80211_connect()
1311 vif->bss = bss; in wil_cfg80211_connect()
1315 if (vif->privacy) { in wil_cfg80211_connect()
1316 /* For secure assoc, remove old keys */ in wil_cfg80211_connect()
1317 rc = wmi_del_cipher_key(vif, 0, bss->bssid, in wil_cfg80211_connect()
1323 rc = wmi_del_cipher_key(vif, 0, bss->bssid, in wil_cfg80211_connect()
1334 if (vif->privacy) { in wil_cfg80211_connect()
1353 conn.channel = ch - 1; in wil_cfg80211_connect()
1355 rc = wil_get_wmi_edmg_channel(wil, sme->edmg.bw_config, in wil_cfg80211_connect()
1356 sme->edmg.channels, &conn.edmg_channel); in wil_cfg80211_connect()
1360 ether_addr_copy(conn.bssid, bss->bssid); in wil_cfg80211_connect()
1361 ether_addr_copy(conn.dst_mac, bss->bssid); in wil_cfg80211_connect()
1363 set_bit(wil_vif_fwconnecting, vif->status); in wil_cfg80211_connect()
1365 rc = wmi_send(wil, WMI_CONNECT_CMDID, vif->mid, &conn, sizeof(conn)); in wil_cfg80211_connect()
1370 vif->bss = bss; in wil_cfg80211_connect()
1372 mod_timer(&vif->connect_timer, in wil_cfg80211_connect()
1375 clear_bit(wil_vif_fwconnecting, vif->status); in wil_cfg80211_connect()
1393 reason_code, vif->mid); in wil_cfg80211_disconnect()
1395 if (!(test_bit(wil_vif_fwconnecting, vif->status) || in wil_cfg80211_disconnect()
1396 test_bit(wil_vif_fwconnected, vif->status))) { in wil_cfg80211_disconnect()
1401 vif->locally_generated_disc = true; in wil_cfg80211_disconnect()
1402 rc = wmi_call(wil, WMI_DISCONNECT_CMDID, vif->mid, NULL, 0, in wil_cfg80211_disconnect()
1420 return -ENOTSUPP; in wil_cfg80211_set_wiphy_params()
1423 rc = wmi_set_mgmt_retry(wil, wiphy->retry_short); in wil_cfg80211_set_wiphy_params()
1435 const u8 *buf = params->buf; in wil_cfg80211_mgmt_tx()
1436 size_t len = params->len; in wil_cfg80211_mgmt_tx()
1443 params->chan ? params->chan->hw_value : -1, in wil_cfg80211_mgmt_tx()
1444 params->offchan, in wil_cfg80211_mgmt_tx()
1445 params->wait); in wil_cfg80211_mgmt_tx()
1448 * In other modes, user-space must call remain_on_channel before in wil_cfg80211_mgmt_tx()
1452 if (params->chan && params->chan->hw_value == 0) { in wil_cfg80211_mgmt_tx()
1454 return -EINVAL; in wil_cfg80211_mgmt_tx()
1457 if (wdev->iftype != NL80211_IFTYPE_AP) { in wil_cfg80211_mgmt_tx()
1459 "send WMI_SW_TX_REQ_CMDID on non-AP interfaces\n"); in wil_cfg80211_mgmt_tx()
1464 if (!params->chan || params->chan->hw_value == vif->channel) { in wil_cfg80211_mgmt_tx()
1466 "send WMI_SW_TX_REQ_CMDID for on-channel\n"); in wil_cfg80211_mgmt_tx()
1471 if (params->offchan == 0) { in wil_cfg80211_mgmt_tx()
1473 "invalid channel params: current %d requested %d, off-channel not allowed\n", in wil_cfg80211_mgmt_tx()
1474 vif->channel, params->chan->hw_value); in wil_cfg80211_mgmt_tx()
1475 return -EBUSY; in wil_cfg80211_mgmt_tx()
1478 /* use the wmi_mgmt_tx_ext only on AP mode and off-channel */ in wil_cfg80211_mgmt_tx()
1479 rc = wmi_mgmt_tx_ext(vif, buf, len, params->chan->hw_value, in wil_cfg80211_mgmt_tx()
1480 params->wait); in wil_cfg80211_mgmt_tx()
1484 * be -EAGAIN. In this case this function needs to return success, in wil_cfg80211_mgmt_tx()
1488 rc = (rc == -EAGAIN) ? 0 : rc; in wil_cfg80211_mgmt_tx()
1500 wil->monitor_chandef = *chandef; in wil_cfg80211_set_channel()
1514 switch (wdev->iftype) { in wil_detect_key_usage()
1530 wil_dbg_misc(wil, "detect_key_usage: -> %s\n", key_usage_str[rc]); in wil_detect_key_usage()
1539 int cid = -EINVAL; in wil_find_sta_by_key_usage()
1555 return &wil->sta[cid]; in wil_find_sta_by_key_usage()
1559 struct wil_sta_info *cs, in wil_set_crypto_rx() argument
1565 if (!cs) in wil_set_crypto_rx()
1572 cc = &cs->tid_crypto_rx[tid].key_id[key_index]; in wil_set_crypto_rx()
1573 if (params->seq) in wil_set_crypto_rx()
1574 memcpy(cc->pn, params->seq, in wil_set_crypto_rx()
1577 memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN); in wil_set_crypto_rx()
1578 cc->key_set = true; in wil_set_crypto_rx()
1582 cc = &cs->group_crypto_rx.key_id[key_index]; in wil_set_crypto_rx()
1583 if (params->seq) in wil_set_crypto_rx()
1584 memcpy(cc->pn, params->seq, IEEE80211_GCMP_PN_LEN); in wil_set_crypto_rx()
1586 memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN); in wil_set_crypto_rx()
1587 cc->key_set = true; in wil_set_crypto_rx()
1595 struct wil_sta_info *cs) in wil_del_rx_key() argument
1600 if (!cs) in wil_del_rx_key()
1606 cc = &cs->tid_crypto_rx[tid].key_id[key_index]; in wil_del_rx_key()
1607 cc->key_set = false; in wil_del_rx_key()
1611 cc = &cs->group_crypto_rx.key_id[key_index]; in wil_del_rx_key()
1612 cc->key_set = false; in wil_del_rx_key()
1630 struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, vif->mid, in wil_cfg80211_add_key() local
1636 return -EINVAL; in wil_cfg80211_add_key()
1641 params->seq_len, params->seq); in wil_cfg80211_add_key()
1643 if (IS_ERR(cs)) { in wil_cfg80211_add_key()
1647 if (!test_bit(wil_vif_ft_roam, vif->status)) { in wil_cfg80211_add_key()
1650 params->seq_len, params->seq); in wil_cfg80211_add_key()
1651 return -EINVAL; in wil_cfg80211_add_key()
1654 wil_del_rx_key(key_index, key_usage, cs); in wil_cfg80211_add_key()
1657 if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) { in wil_cfg80211_add_key()
1660 params->seq_len, mac_addr, in wil_cfg80211_add_key()
1662 params->seq_len, params->seq); in wil_cfg80211_add_key()
1663 return -EINVAL; in wil_cfg80211_add_key()
1666 spin_lock_bh(&wil->eap_lock); in wil_cfg80211_add_key()
1667 if (pairwise && wdev->iftype == NL80211_IFTYPE_STATION && in wil_cfg80211_add_key()
1668 (vif->ptk_rekey_state == WIL_REKEY_M3_RECEIVED || in wil_cfg80211_add_key()
1669 vif->ptk_rekey_state == WIL_REKEY_WAIT_M4_SENT)) { in wil_cfg80211_add_key()
1671 vif->ptk_rekey_state = WIL_REKEY_WAIT_M4_SENT; in wil_cfg80211_add_key()
1674 spin_unlock_bh(&wil->eap_lock); in wil_cfg80211_add_key()
1676 rc = wmi_add_cipher_key(vif, key_index, mac_addr, params->key_len, in wil_cfg80211_add_key()
1677 params->key, key_usage); in wil_cfg80211_add_key()
1678 if (!rc && !IS_ERR(cs)) { in wil_cfg80211_add_key()
1680 if (key_usage == WMI_KEY_USE_TX_GROUP && params->key && in wil_cfg80211_add_key()
1681 params->key_len <= WMI_MAX_KEY_LEN) { in wil_cfg80211_add_key()
1682 vif->gtk_index = key_index; in wil_cfg80211_add_key()
1683 memcpy(vif->gtk, params->key, params->key_len); in wil_cfg80211_add_key()
1684 vif->gtk_len = params->key_len; in wil_cfg80211_add_key()
1689 wil_set_crypto_rx(key_index, key_usage, cs, params); in wil_cfg80211_add_key()
1704 struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, vif->mid, in wil_cfg80211_del_key() local
1711 if (IS_ERR(cs)) in wil_cfg80211_del_key()
1715 if (!IS_ERR_OR_NULL(cs)) in wil_cfg80211_del_key()
1716 wil_del_rx_key(key_index, key_usage, cs); in wil_cfg80211_del_key()
1744 chan->center_freq, duration, wdev->iftype); in wil_remain_on_channel()
1784 oui = vie->oui[0] << 16 | vie->oui[1] << 8 | vie->oui[2]; in _wil_cfg80211_find_ie()
1785 return cfg80211_find_vendor_ie(oui, vie->oui_type, ies, in _wil_cfg80211_find_ie()
1793 * the merged list sorted (since vendor-specific IE has the
1818 return -ENOMEM; in _wil_cfg80211_merge_extra_ies()
1839 *merged_len = dpos - buf; in _wil_cfg80211_merge_extra_ies()
1846 b->head, b->head_len, true); in wil_print_bcon_data()
1848 b->tail, b->tail_len, true); in wil_print_bcon_data()
1850 b->beacon_ies, b->beacon_ies_len, true); in wil_print_bcon_data()
1852 b->probe_resp, b->probe_resp_len, true); in wil_print_bcon_data()
1854 b->proberesp_ies, b->proberesp_ies_len, true); in wil_print_bcon_data()
1855 wil_hex_dump_misc("ASSOC IE ", DUMP_PREFIX_OFFSET, 16, 1, in wil_print_bcon_data()
1856 b->assocresp_ies, b->assocresp_ies_len, true); in wil_print_bcon_data()
1872 ies = f->u.probe_resp.variable; in _wil_cfg80211_get_proberesp_ies()
1874 *ies_len = proberesp_len - hlen; in _wil_cfg80211_get_proberesp_ies()
1888 wil_memdup_ie(&vif->proberesp, &vif->proberesp_len, bcon->probe_resp, in _wil_cfg80211_set_ies()
1889 bcon->probe_resp_len); in _wil_cfg80211_set_ies()
1890 wil_memdup_ie(&vif->proberesp_ies, &vif->proberesp_ies_len, in _wil_cfg80211_set_ies()
1891 bcon->proberesp_ies, bcon->proberesp_ies_len); in _wil_cfg80211_set_ies()
1892 wil_memdup_ie(&vif->assocresp_ies, &vif->assocresp_ies_len, in _wil_cfg80211_set_ies()
1893 bcon->assocresp_ies, bcon->assocresp_ies_len); in _wil_cfg80211_set_ies()
1895 proberesp = _wil_cfg80211_get_proberesp_ies(bcon->probe_resp, in _wil_cfg80211_set_ies()
1896 bcon->probe_resp_len, in _wil_cfg80211_set_ies()
1900 bcon->proberesp_ies, in _wil_cfg80211_set_ies()
1901 bcon->proberesp_ies_len, in _wil_cfg80211_set_ies()
1911 if (bcon->assocresp_ies) in _wil_cfg80211_set_ies()
1913 bcon->assocresp_ies_len, bcon->assocresp_ies); in _wil_cfg80211_set_ies()
1921 bcon->tail_len, bcon->tail); in _wil_cfg80211_set_ies()
1938 struct wireless_dev *wdev = ndev->ieee80211_ptr; in _wil_cfg80211_start_ap()
1939 u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype); in _wil_cfg80211_start_ap()
1940 u8 is_go = (wdev->iftype == NL80211_IFTYPE_P2P_GO); in _wil_cfg80211_start_ap()
1948 wil_dbg_misc(wil, "start_ap: mid=%d, is_go=%d\n", vif->mid, is_go); in _wil_cfg80211_start_ap()
1951 return -ENOTSUPP; in _wil_cfg80211_start_ap()
1956 proberesp = _wil_cfg80211_get_proberesp_ies(bcon->probe_resp, in _wil_cfg80211_start_ap()
1957 bcon->probe_resp_len, in _wil_cfg80211_start_ap()
1968 wil->fw_capabilities)) { in _wil_cfg80211_start_ap()
1970 return -ENOTSUPP; in _wil_cfg80211_start_ap()
1972 set_bit(wil_vif_ft_roam, vif->status); in _wil_cfg80211_start_ap()
1975 mutex_lock(&wil->mutex); in _wil_cfg80211_start_ap()
1992 vif->privacy = privacy; in _wil_cfg80211_start_ap()
1993 vif->channel = chan; in _wil_cfg80211_start_ap()
1994 vif->wmi_edmg_channel = wmi_edmg_channel; in _wil_cfg80211_start_ap()
1995 vif->hidden_ssid = hidden_ssid; in _wil_cfg80211_start_ap()
1996 vif->pbss = pbss; in _wil_cfg80211_start_ap()
1997 vif->bi = bi; in _wil_cfg80211_start_ap()
1998 memcpy(vif->ssid, ssid, ssid_len); in _wil_cfg80211_start_ap()
1999 vif->ssid_len = ssid_len; in _wil_cfg80211_start_ap()
2023 mutex_unlock(&wil->mutex); in _wil_cfg80211_start_ap()
2033 struct wil6210_vif *vif = wil->vifs[i]; in wil_cfg80211_ap_recovery()
2038 if (!vif || vif->ssid_len == 0) in wil_cfg80211_ap_recovery()
2042 bcon.proberesp_ies = vif->proberesp_ies; in wil_cfg80211_ap_recovery()
2043 bcon.assocresp_ies = vif->assocresp_ies; in wil_cfg80211_ap_recovery()
2044 bcon.probe_resp = vif->proberesp; in wil_cfg80211_ap_recovery()
2045 bcon.proberesp_ies_len = vif->proberesp_ies_len; in wil_cfg80211_ap_recovery()
2046 bcon.assocresp_ies_len = vif->assocresp_ies_len; in wil_cfg80211_ap_recovery()
2047 bcon.probe_resp_len = vif->proberesp_len; in wil_cfg80211_ap_recovery()
2051 i, vif->privacy, vif->bi, vif->channel, in wil_cfg80211_ap_recovery()
2052 vif->hidden_ssid, vif->pbss); in wil_cfg80211_ap_recovery()
2054 vif->ssid, vif->ssid_len, true); in wil_cfg80211_ap_recovery()
2056 vif->ssid, vif->ssid_len, in wil_cfg80211_ap_recovery()
2057 vif->privacy, vif->bi, in wil_cfg80211_ap_recovery()
2058 vif->channel, in wil_cfg80211_ap_recovery()
2059 vif->wmi_edmg_channel, &bcon, in wil_cfg80211_ap_recovery()
2060 vif->hidden_ssid, vif->pbss); in wil_cfg80211_ap_recovery()
2066 if (!vif->privacy || vif->gtk_len == 0) in wil_cfg80211_ap_recovery()
2069 key_params.key = vif->gtk; in wil_cfg80211_ap_recovery()
2070 key_params.key_len = vif->gtk_len; in wil_cfg80211_ap_recovery()
2072 rc = wil_cfg80211_add_key(wiphy, ndev, -1, vif->gtk_index, in wil_cfg80211_ap_recovery()
2085 struct wireless_dev *wdev = ndev->ieee80211_ptr; in wil_cfg80211_change_beacon()
2087 struct cfg80211_beacon_data *bcon = &params->beacon; in wil_cfg80211_change_beacon()
2091 wil_dbg_misc(wil, "change_beacon, mid=%d\n", vif->mid); in wil_cfg80211_change_beacon()
2094 if (bcon->tail && in wil_cfg80211_change_beacon()
2095 cfg80211_find_ie(WLAN_EID_RSN, bcon->tail, in wil_cfg80211_change_beacon()
2096 bcon->tail_len)) in wil_cfg80211_change_beacon()
2099 memcpy(vif->ssid, wdev->u.ap.ssid, wdev->u.ap.ssid_len); in wil_cfg80211_change_beacon()
2100 vif->ssid_len = wdev->u.ap.ssid_len; in wil_cfg80211_change_beacon()
2103 if (vif->privacy != privacy) { in wil_cfg80211_change_beacon()
2105 vif->privacy, privacy); in wil_cfg80211_change_beacon()
2107 rc = _wil_cfg80211_start_ap(wiphy, ndev, vif->ssid, in wil_cfg80211_change_beacon()
2108 vif->ssid_len, privacy, in wil_cfg80211_change_beacon()
2109 wdev->links[0].ap.beacon_interval, in wil_cfg80211_change_beacon()
2110 vif->channel, in wil_cfg80211_change_beacon()
2111 vif->wmi_edmg_channel, bcon, in wil_cfg80211_change_beacon()
2112 vif->hidden_ssid, in wil_cfg80211_change_beacon()
2113 vif->pbss); in wil_cfg80211_change_beacon()
2127 struct ieee80211_channel *channel = info->chandef.chan; in wil_cfg80211_start_ap()
2128 struct cfg80211_beacon_data *bcon = &info->beacon; in wil_cfg80211_start_ap()
2129 struct cfg80211_crypto_settings *crypto = &info->crypto; in wil_cfg80211_start_ap()
2135 rc = wil_get_wmi_edmg_channel(wil, info->chandef.edmg.bw_config, in wil_cfg80211_start_ap()
2136 info->chandef.edmg.channels, in wil_cfg80211_start_ap()
2143 return -EINVAL; in wil_cfg80211_start_ap()
2146 switch (info->hidden_ssid) { in wil_cfg80211_start_ap()
2160 wil_err(wil, "AP: Invalid hidden SSID %d\n", info->hidden_ssid); in wil_cfg80211_start_ap()
2161 return -EOPNOTSUPP; in wil_cfg80211_start_ap()
2163 wil_dbg_misc(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value, in wil_cfg80211_start_ap()
2164 channel->center_freq, info->privacy ? "secure" : "open"); in wil_cfg80211_start_ap()
2166 info->privacy, info->auth_type); in wil_cfg80211_start_ap()
2168 info->hidden_ssid); in wil_cfg80211_start_ap()
2169 wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval, in wil_cfg80211_start_ap()
2170 info->dtim_period); in wil_cfg80211_start_ap()
2171 wil_dbg_misc(wil, "PBSS %d\n", info->pbss); in wil_cfg80211_start_ap()
2173 info->ssid, info->ssid_len, true); in wil_cfg80211_start_ap()
2178 info->ssid, info->ssid_len, info->privacy, in wil_cfg80211_start_ap()
2179 info->beacon_interval, channel->hw_value, in wil_cfg80211_start_ap()
2181 info->pbss); in wil_cfg80211_start_ap()
2194 wil_dbg_misc(wil, "stop_ap, mid=%d\n", vif->mid); in wil_cfg80211_stop_ap()
2201 set_bit(wil_status_resetting, wil->status); in wil_cfg80211_stop_ap()
2204 mutex_lock(&wil->mutex); in wil_cfg80211_stop_ap()
2207 clear_bit(wil_vif_ft_roam, vif->status); in wil_cfg80211_stop_ap()
2208 vif->ssid_len = 0; in wil_cfg80211_stop_ap()
2209 wil_memdup_ie(&vif->proberesp, &vif->proberesp_len, NULL, 0); in wil_cfg80211_stop_ap()
2210 wil_memdup_ie(&vif->proberesp_ies, &vif->proberesp_ies_len, NULL, 0); in wil_cfg80211_stop_ap()
2211 wil_memdup_ie(&vif->assocresp_ies, &vif->assocresp_ies_len, NULL, 0); in wil_cfg80211_stop_ap()
2212 memset(vif->gtk, 0, WMI_MAX_KEY_LEN); in wil_cfg80211_stop_ap()
2213 vif->gtk_len = 0; in wil_cfg80211_stop_ap()
2220 mutex_unlock(&wil->mutex); in wil_cfg80211_stop_ap()
2226 struct net_device *dev, in wil_cfg80211_add_station() argument
2230 struct wil6210_vif *vif = ndev_to_vif(dev); in wil_cfg80211_add_station()
2234 mac, params->aid, vif->mid, in wil_cfg80211_add_station()
2235 params->sta_flags_mask, params->sta_flags_set); in wil_cfg80211_add_station()
2239 return -EOPNOTSUPP; in wil_cfg80211_add_station()
2242 if (params->aid > WIL_MAX_DMG_AID) { in wil_cfg80211_add_station()
2244 return -EINVAL; in wil_cfg80211_add_station()
2247 return wmi_new_sta(vif, mac, params->aid); in wil_cfg80211_add_station()
2251 struct net_device *dev, in wil_cfg80211_del_station() argument
2254 struct wil6210_vif *vif = ndev_to_vif(dev); in wil_cfg80211_del_station()
2258 params->mac, params->reason_code, vif->mid); in wil_cfg80211_del_station()
2260 mutex_lock(&wil->mutex); in wil_cfg80211_del_station()
2261 wil6210_disconnect(vif, params->mac, params->reason_code); in wil_cfg80211_del_station()
2262 mutex_unlock(&wil->mutex); in wil_cfg80211_del_station()
2268 struct net_device *dev, in wil_cfg80211_change_station() argument
2272 struct wil6210_vif *vif = ndev_to_vif(dev); in wil_cfg80211_change_station()
2279 mac, params->sta_flags_mask, params->sta_flags_set, in wil_cfg80211_change_station()
2280 vif->mid); in wil_cfg80211_change_station()
2284 return -EOPNOTSUPP; in wil_cfg80211_change_station()
2287 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED))) in wil_cfg80211_change_station()
2290 cid = wil_find_cid(wil, vif->mid, mac); in wil_cfg80211_change_station()
2293 return -ENOLINK; in wil_cfg80211_change_station()
2296 for (i = 0; i < ARRAY_SIZE(wil->ring2cid_tid); i++) in wil_cfg80211_change_station()
2297 if (wil->ring2cid_tid[i][0] == cid) { in wil_cfg80211_change_station()
2298 txdata = &wil->ring_tx_data[i]; in wil_cfg80211_change_station()
2304 return -ENOLINK; in wil_cfg80211_change_station()
2307 authorize = params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED); in wil_cfg80211_change_station()
2308 txdata->dot1x_open = authorize ? 1 : 0; in wil_cfg80211_change_station()
2310 txdata->dot1x_open); in wil_cfg80211_change_station()
2321 struct wil_sta_info *sta = &wil->sta[req->cid]; in wil_probe_client_handle()
2325 bool alive = (sta->status == wil_sta_connected); in wil_probe_client_handle()
2327 cfg80211_probe_status(ndev, sta->addr, req->cookie, alive, in wil_probe_client_handle()
2335 mutex_lock(&vif->probe_client_mutex); in next_probe_client()
2337 if (!list_empty(&vif->probe_client_pending)) { in next_probe_client()
2338 ret = vif->probe_client_pending.next; in next_probe_client()
2342 mutex_unlock(&vif->probe_client_mutex); in next_probe_client()
2370 mutex_lock(&vif->probe_client_mutex); in wil_probe_client_flush()
2372 list_for_each_entry_safe(req, t, &vif->probe_client_pending, list) { in wil_probe_client_flush()
2373 list_del(&req->list); in wil_probe_client_flush()
2377 mutex_unlock(&vif->probe_client_mutex); in wil_probe_client_flush()
2381 struct net_device *dev, in wil_cfg80211_probe_client() argument
2385 struct wil6210_vif *vif = ndev_to_vif(dev); in wil_cfg80211_probe_client()
2387 int cid = wil_find_cid(wil, vif->mid, peer); in wil_cfg80211_probe_client()
2390 peer, cid, vif->mid); in wil_cfg80211_probe_client()
2393 return -ENOLINK; in wil_cfg80211_probe_client()
2397 return -ENOMEM; in wil_cfg80211_probe_client()
2399 req->cid = cid; in wil_cfg80211_probe_client()
2400 req->cookie = cid; in wil_cfg80211_probe_client()
2402 mutex_lock(&vif->probe_client_mutex); in wil_cfg80211_probe_client()
2403 list_add_tail(&req->list, &vif->probe_client_pending); in wil_cfg80211_probe_client()
2404 mutex_unlock(&vif->probe_client_mutex); in wil_cfg80211_probe_client()
2406 *cookie = req->cookie; in wil_cfg80211_probe_client()
2407 queue_work(wil->wq_service, &vif->probe_client_worker); in wil_cfg80211_probe_client()
2412 struct net_device *dev, in wil_cfg80211_change_bss() argument
2416 struct wil6210_vif *vif = ndev_to_vif(dev); in wil_cfg80211_change_bss()
2418 if (params->ap_isolate >= 0) { in wil_cfg80211_change_bss()
2420 vif->mid, vif->ap_isolate, params->ap_isolate); in wil_cfg80211_change_bss()
2421 vif->ap_isolate = params->ap_isolate; in wil_cfg80211_change_bss()
2428 struct net_device *dev, in wil_cfg80211_set_power_mgmt() argument
2453 if (test_bit(wil_status_suspended, wil->status)) { in wil_cfg80211_suspend()
2464 mutex_lock(&wil->mutex); in wil_cfg80211_suspend()
2465 mutex_lock(&wil->vif_mutex); in wil_cfg80211_suspend()
2468 mutex_unlock(&wil->vif_mutex); in wil_cfg80211_suspend()
2469 mutex_unlock(&wil->mutex); in wil_cfg80211_suspend()
2486 struct net_device *dev, in wil_cfg80211_sched_scan_start() argument
2490 struct wil6210_vif *vif = ndev_to_vif(dev); in wil_cfg80211_sched_scan_start()
2493 if (vif->mid != 0) in wil_cfg80211_sched_scan_start()
2494 return -EOPNOTSUPP; in wil_cfg80211_sched_scan_start()
2498 request->n_ssids, request->ie_len, request->flags); in wil_cfg80211_sched_scan_start()
2499 for (i = 0; i < request->n_ssids; i++) { in wil_cfg80211_sched_scan_start()
2502 request->ssids[i].ssid, in wil_cfg80211_sched_scan_start()
2503 request->ssids[i].ssid_len, true); in wil_cfg80211_sched_scan_start()
2506 for (i = 0; i < request->n_channels; i++) in wil_cfg80211_sched_scan_start()
2507 wil_dbg_misc(wil, " %d%s", request->channels[i]->hw_value, in wil_cfg80211_sched_scan_start()
2508 i == request->n_channels - 1 ? "\n" : ""); in wil_cfg80211_sched_scan_start()
2510 request->n_match_sets, request->min_rssi_thold, in wil_cfg80211_sched_scan_start()
2511 request->delay); in wil_cfg80211_sched_scan_start()
2512 for (i = 0; i < request->n_match_sets; i++) { in wil_cfg80211_sched_scan_start()
2513 struct cfg80211_match_set *ms = &request->match_sets[i]; in wil_cfg80211_sched_scan_start()
2516 i, ms->rssi_thold); in wil_cfg80211_sched_scan_start()
2518 ms->ssid.ssid, in wil_cfg80211_sched_scan_start()
2519 ms->ssid.ssid_len, true); in wil_cfg80211_sched_scan_start()
2521 wil_dbg_misc(wil, "n_scan_plans %d\n", request->n_scan_plans); in wil_cfg80211_sched_scan_start()
2522 for (i = 0; i < request->n_scan_plans; i++) { in wil_cfg80211_sched_scan_start()
2523 struct cfg80211_sched_scan_plan *sp = &request->scan_plans[i]; in wil_cfg80211_sched_scan_start()
2526 i, sp->interval, sp->iterations); in wil_cfg80211_sched_scan_start()
2530 request->ie_len, request->ie); in wil_cfg80211_sched_scan_start()
2537 wil_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev, in wil_cfg80211_sched_scan_stop() argument
2541 struct wil6210_vif *vif = ndev_to_vif(dev); in wil_cfg80211_sched_scan_stop()
2544 if (vif->mid != 0) in wil_cfg80211_sched_scan_stop()
2545 return -EOPNOTSUPP; in wil_cfg80211_sched_scan_stop()
2549 * ignore the return code so user space and driver gets back in-sync in wil_cfg80211_sched_scan_stop()
2557 wil_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, in wil_cfg80211_update_ft_ies() argument
2561 struct wil6210_vif *vif = ndev_to_vif(dev); in wil_cfg80211_update_ft_ies()
2566 wil_dbg_misc(wil, "update ft ies, mid=%d\n", vif->mid); in wil_cfg80211_update_ft_ies()
2568 ftie->ie, ftie->ie_len, true); in wil_cfg80211_update_ft_ies()
2570 if (!test_bit(WMI_FW_CAPABILITY_FT_ROAMING, wil->fw_capabilities)) { in wil_cfg80211_update_ft_ies()
2572 return -EOPNOTSUPP; in wil_cfg80211_update_ft_ies()
2575 rc = wmi_update_ft_ies(vif, ftie->ie_len, ftie->ie); in wil_cfg80211_update_ft_ies()
2579 if (!test_bit(wil_vif_ft_roam, vif->status)) in wil_cfg80211_update_ft_ies()
2587 bss = vif->bss; in wil_cfg80211_update_ft_ies()
2590 return -EINVAL; in wil_cfg80211_update_ft_ies()
2594 ether_addr_copy(reassoc.bssid, bss->bssid); in wil_cfg80211_update_ft_ies()
2596 rc = wmi_send(wil, WMI_FT_REASSOC_CMDID, vif->mid, in wil_cfg80211_update_ft_ies()
2605 struct net_device *dev, in wil_cfg80211_set_multicast_to_unicast() argument
2610 if (wil->multicast_to_unicast == enabled) in wil_cfg80211_set_multicast_to_unicast()
2614 wil->multicast_to_unicast = enabled; in wil_cfg80211_set_multicast_to_unicast()
2620 struct net_device *dev, in wil_cfg80211_set_cqm_rssi_config() argument
2626 wil->cqm_rssi_thold = rssi_thold; in wil_cfg80211_set_cqm_rssi_config()
2631 wil->cqm_rssi_thold = 0; in wil_cfg80211_set_cqm_rssi_config()
2678 wiphy->max_scan_ssids = 1; in wil_wiphy_init()
2679 wiphy->max_scan_ie_len = WMI_MAX_IE_LEN; in wil_wiphy_init()
2680 wiphy->max_remain_on_channel_duration = WIL_MAX_ROC_DURATION_MS; in wil_wiphy_init()
2681 wiphy->max_num_pmkids = 0 /* TODO: */; in wil_wiphy_init()
2682 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | in wil_wiphy_init()
2688 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | in wil_wiphy_init()
2692 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME; in wil_wiphy_init()
2694 __func__, wiphy->flags); in wil_wiphy_init()
2695 wiphy->probe_resp_offload = in wil_wiphy_init()
2700 wiphy->bands[NL80211_BAND_60GHZ] = &wil_band_60ghz; in wil_wiphy_init()
2703 wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; in wil_wiphy_init()
2705 wiphy->cipher_suites = wil_cipher_suites; in wil_wiphy_init()
2706 wiphy->n_cipher_suites = ARRAY_SIZE(wil_cipher_suites); in wil_wiphy_init()
2707 wiphy->mgmt_stypes = wil_mgmt_stypes; in wil_wiphy_init()
2708 wiphy->features |= NL80211_FEATURE_SK_TX_STATUS; in wil_wiphy_init()
2710 wiphy->n_vendor_commands = ARRAY_SIZE(wil_nl80211_vendor_commands); in wil_wiphy_init()
2711 wiphy->vendor_commands = wil_nl80211_vendor_commands; in wil_wiphy_init()
2714 wiphy->wowlan = &wil_wowlan_support; in wil_wiphy_init()
2730 if (wiphy->iface_combinations) { in wil_cfg80211_iface_combinations_from_fw()
2736 n_combos = le16_to_cpu(conc->n_combos); in wil_cfg80211_iface_combinations_from_fw()
2738 total_limits += combo->n_limits; in wil_cfg80211_iface_combinations_from_fw()
2739 limit = combo->limits + combo->n_limits; in wil_cfg80211_iface_combinations_from_fw()
2748 return -ENOMEM; in wil_cfg80211_iface_combinations_from_fw()
2753 iface_combinations[i].max_interfaces = combo->max_interfaces; in wil_cfg80211_iface_combinations_from_fw()
2755 combo->n_diff_channels; in wil_cfg80211_iface_combinations_from_fw()
2757 combo->same_bi; in wil_cfg80211_iface_combinations_from_fw()
2758 iface_combinations[i].n_limits = combo->n_limits; in wil_cfg80211_iface_combinations_from_fw()
2764 limit = combo->limits; in wil_cfg80211_iface_combinations_from_fw()
2765 for (j = 0; j < combo->n_limits; j++) { in wil_cfg80211_iface_combinations_from_fw()
2773 iface_limit += combo->n_limits; in wil_cfg80211_iface_combinations_from_fw()
2774 limit += combo->n_limits; in wil_cfg80211_iface_combinations_from_fw()
2778 wil_dbg_misc(wil, "multiple VIFs supported, n_mids %d\n", conc->n_mids); in wil_cfg80211_iface_combinations_from_fw()
2779 wil->max_vifs = conc->n_mids + 1; /* including main interface */ in wil_cfg80211_iface_combinations_from_fw()
2780 if (wil->max_vifs > WIL_MAX_VIFS) { in wil_cfg80211_iface_combinations_from_fw()
2782 WIL_MAX_VIFS, wil->max_vifs); in wil_cfg80211_iface_combinations_from_fw()
2783 wil->max_vifs = WIL_MAX_VIFS; in wil_cfg80211_iface_combinations_from_fw()
2785 wiphy->n_iface_combinations = n_combos; in wil_cfg80211_iface_combinations_from_fw()
2786 wiphy->iface_combinations = iface_combinations; in wil_cfg80211_iface_combinations_from_fw()
2790 struct wil6210_priv *wil_cfg80211_init(struct device *dev) in wil_cfg80211_init() argument
2796 dev_dbg(dev, "%s()\n", __func__); in wil_cfg80211_init()
2804 return ERR_PTR(-ENOMEM); in wil_cfg80211_init()
2806 set_wiphy_dev(wiphy, dev); in wil_cfg80211_init()
2810 wil->wiphy = wiphy; in wil_cfg80211_init()
2813 ch = wiphy->bands[NL80211_BAND_60GHZ]->channels; in wil_cfg80211_init()
2814 cfg80211_chandef_create(&wil->monitor_chandef, ch, NL80211_CHAN_NO_HT); in wil_cfg80211_init()
2828 kfree(wiphy->iface_combinations); in wil_cfg80211_deinit()
2829 wiphy->iface_combinations = NULL; in wil_cfg80211_deinit()
2839 mutex_lock(&wil->vif_mutex); in wil_p2p_wdev_free()
2840 p2p_wdev = wil->p2p_wdev; in wil_p2p_wdev_free()
2841 wil->p2p_wdev = NULL; in wil_p2p_wdev_free()
2842 wil->radio_wdev = wil->main_ndev->ieee80211_ptr; in wil_p2p_wdev_free()
2843 mutex_unlock(&wil->vif_mutex); in wil_p2p_wdev_free()
2856 return -EINVAL; in wil_rf_sector_status_to_rc()
2858 return -EAGAIN; in wil_rf_sector_status_to_rc()
2860 return -EOPNOTSUPP; in wil_rf_sector_status_to_rc()
2862 return -EINVAL; in wil_rf_sector_status_to_rc()
2889 if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities)) in wil_rf_sector_get_cfg()
2890 return -EOPNOTSUPP; in wil_rf_sector_get_cfg()
2903 return -EINVAL; in wil_rf_sector_get_cfg()
2910 return -EINVAL; in wil_rf_sector_get_cfg()
2916 return -EINVAL; in wil_rf_sector_get_cfg()
2923 return -EINVAL; in wil_rf_sector_get_cfg()
2929 rc = wmi_call(wil, WMI_GET_RF_SECTOR_PARAMS_CMDID, vif->mid, in wil_rf_sector_get_cfg()
2944 return -ENOMEM; in wil_rf_sector_get_cfg()
2964 le32_to_cpu(si->etype0)) || in wil_rf_sector_get_cfg()
2966 le32_to_cpu(si->etype1)) || in wil_rf_sector_get_cfg()
2968 le32_to_cpu(si->etype2)) || in wil_rf_sector_get_cfg()
2970 le32_to_cpu(si->psh_hi)) || in wil_rf_sector_get_cfg()
2972 le32_to_cpu(si->psh_lo)) || in wil_rf_sector_get_cfg()
2974 le32_to_cpu(si->dtype_swch_off))) in wil_rf_sector_get_cfg()
2984 return -ENOBUFS; in wil_rf_sector_get_cfg()
3009 if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities)) in wil_rf_sector_set_cfg()
3010 return -EOPNOTSUPP; in wil_rf_sector_set_cfg()
3023 return -EINVAL; in wil_rf_sector_set_cfg()
3030 return -EINVAL; in wil_rf_sector_set_cfg()
3036 return -EINVAL; in wil_rf_sector_set_cfg()
3052 return -EINVAL; in wil_rf_sector_set_cfg()
3063 return -EINVAL; in wil_rf_sector_set_cfg()
3071 return -EINVAL; in wil_rf_sector_set_cfg()
3075 si->etype0 = cpu_to_le32(nla_get_u32( in wil_rf_sector_set_cfg()
3077 si->etype1 = cpu_to_le32(nla_get_u32( in wil_rf_sector_set_cfg()
3079 si->etype2 = cpu_to_le32(nla_get_u32( in wil_rf_sector_set_cfg()
3081 si->psh_hi = cpu_to_le32(nla_get_u32( in wil_rf_sector_set_cfg()
3083 si->psh_lo = cpu_to_le32(nla_get_u32( in wil_rf_sector_set_cfg()
3085 si->dtype_swch_off = cpu_to_le32(nla_get_u32( in wil_rf_sector_set_cfg()
3090 rc = wmi_call(wil, WMI_SET_RF_SECTOR_PARAMS_CMDID, vif->mid, in wil_rf_sector_set_cfg()
3118 if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities)) in wil_rf_sector_get_selected()
3119 return -EOPNOTSUPP; in wil_rf_sector_get_selected()
3130 return -EINVAL; in wil_rf_sector_get_selected()
3135 return -EINVAL; in wil_rf_sector_get_selected()
3140 cid = wil_find_cid(wil, vif->mid, mac_addr); in wil_rf_sector_get_selected()
3143 return -ENOENT; in wil_rf_sector_get_selected()
3146 if (test_bit(wil_vif_fwconnected, vif->status)) { in wil_rf_sector_get_selected()
3148 return -EINVAL; in wil_rf_sector_get_selected()
3155 rc = wmi_call(wil, WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID, vif->mid, in wil_rf_sector_get_selected()
3171 return -ENOMEM; in wil_rf_sector_get_selected()
3184 return -ENOBUFS; in wil_rf_sector_get_selected()
3226 if (!test_bit(WMI_FW_CAPABILITY_RF_SECTORS, wil->fw_capabilities)) in wil_rf_sector_set_selected()
3227 return -EOPNOTSUPP; in wil_rf_sector_set_selected()
3239 return -EINVAL; in wil_rf_sector_set_selected()
3247 return -EINVAL; in wil_rf_sector_set_selected()
3253 return -EINVAL; in wil_rf_sector_set_selected()
3259 cid = wil_find_cid(wil, vif->mid, mac_addr); in wil_rf_sector_set_selected()
3263 return -ENOENT; in wil_rf_sector_set_selected()
3268 return -EINVAL; in wil_rf_sector_set_selected()
3270 cid = -1; in wil_rf_sector_set_selected()
3273 if (test_bit(wil_vif_fwconnected, vif->status)) { in wil_rf_sector_set_selected()
3275 return -EINVAL; in wil_rf_sector_set_selected()
3281 rc = wil_rf_sector_wmi_set_selected(wil, vif->mid, sector_index, in wil_rf_sector_set_selected()
3286 wil, vif->mid, WMI_INVALID_RF_SECTOR_INDEX, in wil_rf_sector_set_selected()
3288 if (rc == -EINVAL) { in wil_rf_sector_set_selected()
3289 for (i = 0; i < wil->max_assoc_sta; i++) { in wil_rf_sector_set_selected()
3290 if (wil->sta[i].mid != vif->mid) in wil_rf_sector_set_selected()
3293 wil, vif->mid, in wil_rf_sector_set_selected()