1290 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/* Copyright (c) 2015-2016 Quantenna Communications. All rights reserved. */3 4#include <linux/kernel.h>5#include <linux/etherdevice.h>6#include <linux/vmalloc.h>7#include <linux/ieee80211.h>8#include <net/cfg80211.h>9#include <net/netlink.h>10 11#include "cfg80211.h"12#include "commands.h"13#include "core.h"14#include "util.h"15#include "bus.h"16 17/* Supported rates to be advertised to the cfg80211 */18static struct ieee80211_rate qtnf_rates_2g[] = {19 {.bitrate = 10, .hw_value = 2, },20 {.bitrate = 20, .hw_value = 4, },21 {.bitrate = 55, .hw_value = 11, },22 {.bitrate = 110, .hw_value = 22, },23 {.bitrate = 60, .hw_value = 12, },24 {.bitrate = 90, .hw_value = 18, },25 {.bitrate = 120, .hw_value = 24, },26 {.bitrate = 180, .hw_value = 36, },27 {.bitrate = 240, .hw_value = 48, },28 {.bitrate = 360, .hw_value = 72, },29 {.bitrate = 480, .hw_value = 96, },30 {.bitrate = 540, .hw_value = 108, },31};32 33/* Supported rates to be advertised to the cfg80211 */34static struct ieee80211_rate qtnf_rates_5g[] = {35 {.bitrate = 60, .hw_value = 12, },36 {.bitrate = 90, .hw_value = 18, },37 {.bitrate = 120, .hw_value = 24, },38 {.bitrate = 180, .hw_value = 36, },39 {.bitrate = 240, .hw_value = 48, },40 {.bitrate = 360, .hw_value = 72, },41 {.bitrate = 480, .hw_value = 96, },42 {.bitrate = 540, .hw_value = 108, },43};44 45/* Supported crypto cipher suits to be advertised to cfg80211 */46static const u32 qtnf_cipher_suites[] = {47 WLAN_CIPHER_SUITE_TKIP,48 WLAN_CIPHER_SUITE_CCMP,49 WLAN_CIPHER_SUITE_AES_CMAC,50};51 52/* Supported mgmt frame types to be advertised to cfg80211 */53static const struct ieee80211_txrx_stypes54qtnf_mgmt_stypes[NUM_NL80211_IFTYPES] = {55 [NL80211_IFTYPE_STATION] = {56 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |57 BIT(IEEE80211_STYPE_AUTH >> 4),58 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |59 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |60 BIT(IEEE80211_STYPE_AUTH >> 4),61 },62 [NL80211_IFTYPE_AP] = {63 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |64 BIT(IEEE80211_STYPE_AUTH >> 4),65 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |66 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |67 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |68 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |69 BIT(IEEE80211_STYPE_AUTH >> 4),70 },71};72 73static int74qtnf_validate_iface_combinations(struct wiphy *wiphy,75 struct qtnf_vif *change_vif,76 enum nl80211_iftype new_type)77{78 struct qtnf_wmac *mac;79 struct qtnf_vif *vif;80 int i;81 int ret = 0;82 struct iface_combination_params params = {83 .num_different_channels = 1,84 };85 86 mac = wiphy_priv(wiphy);87 if (!mac)88 return -EFAULT;89 90 for (i = 0; i < QTNF_MAX_INTF; i++) {91 vif = &mac->iflist[i];92 if (vif->wdev.iftype != NL80211_IFTYPE_UNSPECIFIED)93 params.iftype_num[vif->wdev.iftype]++;94 }95 96 if (change_vif) {97 params.iftype_num[new_type]++;98 params.iftype_num[change_vif->wdev.iftype]--;99 } else {100 params.iftype_num[new_type]++;101 }102 103 ret = cfg80211_check_combinations(wiphy, ¶ms);104 105 if (ret)106 return ret;107 108 /* Check repeater interface combination: primary VIF should be STA only.109 * STA (primary) + AP (secondary) is OK.110 * AP (primary) + STA (secondary) is not supported.111 */112 vif = qtnf_mac_get_base_vif(mac);113 if (vif && vif->wdev.iftype == NL80211_IFTYPE_AP &&114 vif != change_vif && new_type == NL80211_IFTYPE_STATION) {115 ret = -EINVAL;116 pr_err("MAC%u invalid combination: AP as primary repeater interface is not supported\n",117 mac->macid);118 }119 120 return ret;121}122 123static int124qtnf_change_virtual_intf(struct wiphy *wiphy,125 struct net_device *dev,126 enum nl80211_iftype type,127 struct vif_params *params)128{129 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);130 u8 *mac_addr = NULL;131 int use4addr = 0;132 int ret;133 134 ret = qtnf_validate_iface_combinations(wiphy, vif, type);135 if (ret) {136 pr_err("VIF%u.%u combination check: failed to set type %d\n",137 vif->mac->macid, vif->vifid, type);138 return ret;139 }140 141 if (params) {142 mac_addr = params->macaddr;143 use4addr = params->use_4addr;144 }145 146 qtnf_scan_done(vif->mac, true);147 148 ret = qtnf_cmd_send_change_intf_type(vif, type, use4addr, mac_addr);149 if (ret) {150 pr_err("VIF%u.%u: failed to change type to %d\n",151 vif->mac->macid, vif->vifid, type);152 return ret;153 }154 155 vif->wdev.iftype = type;156 return 0;157}158 159int qtnf_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)160{161 struct net_device *netdev = wdev->netdev;162 struct qtnf_vif *vif;163 struct sk_buff *skb;164 165 if (WARN_ON(!netdev))166 return -EFAULT;167 168 vif = qtnf_netdev_get_priv(wdev->netdev);169 170 qtnf_scan_done(vif->mac, true);171 172 /* Stop data */173 netif_tx_stop_all_queues(netdev);174 if (netif_carrier_ok(netdev))175 netif_carrier_off(netdev);176 177 while ((skb = skb_dequeue(&vif->high_pri_tx_queue)))178 dev_kfree_skb_any(skb);179 180 cancel_work_sync(&vif->high_pri_tx_work);181 182 if (netdev->reg_state == NETREG_REGISTERED)183 cfg80211_unregister_netdevice(netdev);184 185 if (qtnf_cmd_send_del_intf(vif))186 pr_err("VIF%u.%u: failed to delete VIF\n", vif->mac->macid,187 vif->vifid);188 189 vif->netdev->ieee80211_ptr = NULL;190 vif->netdev = NULL;191 vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;192 193 return 0;194}195 196static struct wireless_dev *qtnf_add_virtual_intf(struct wiphy *wiphy,197 const char *name,198 unsigned char name_assign_t,199 enum nl80211_iftype type,200 struct vif_params *params)201{202 struct qtnf_wmac *mac;203 struct qtnf_vif *vif;204 u8 *mac_addr = NULL;205 int use4addr = 0;206 int ret;207 208 mac = wiphy_priv(wiphy);209 210 if (!mac)211 return ERR_PTR(-EFAULT);212 213 ret = qtnf_validate_iface_combinations(wiphy, NULL, type);214 if (ret) {215 pr_err("MAC%u invalid combination: failed to add type %d\n",216 mac->macid, type);217 return ERR_PTR(ret);218 }219 220 switch (type) {221 case NL80211_IFTYPE_STATION:222 case NL80211_IFTYPE_AP:223 vif = qtnf_mac_get_free_vif(mac);224 if (!vif) {225 pr_err("MAC%u: no free VIF available\n", mac->macid);226 return ERR_PTR(-EFAULT);227 }228 229 eth_zero_addr(vif->mac_addr);230 eth_zero_addr(vif->bssid);231 vif->bss_priority = QTNF_DEF_BSS_PRIORITY;232 memset(&vif->wdev, 0, sizeof(vif->wdev));233 vif->wdev.wiphy = wiphy;234 vif->wdev.iftype = type;235 break;236 default:237 pr_err("MAC%u: unsupported IF type %d\n", mac->macid, type);238 return ERR_PTR(-ENOTSUPP);239 }240 241 if (params) {242 mac_addr = params->macaddr;243 use4addr = params->use_4addr;244 }245 246 ret = qtnf_cmd_send_add_intf(vif, type, use4addr, mac_addr);247 if (ret) {248 pr_err("VIF%u.%u: failed to add VIF %pM\n",249 mac->macid, vif->vifid, mac_addr);250 goto err_cmd;251 }252 253 if (!is_valid_ether_addr(vif->mac_addr)) {254 pr_err("VIF%u.%u: FW reported bad MAC: %pM\n",255 mac->macid, vif->vifid, vif->mac_addr);256 ret = -EINVAL;257 goto error_del_vif;258 }259 260 ret = qtnf_core_net_attach(mac, vif, name, name_assign_t);261 if (ret) {262 pr_err("VIF%u.%u: failed to attach netdev\n", mac->macid,263 vif->vifid);264 goto error_del_vif;265 }266 267 if (qtnf_hwcap_is_set(&mac->bus->hw_info, QLINK_HW_CAPAB_HW_BRIDGE)) {268 ret = qtnf_cmd_netdev_changeupper(vif, vif->netdev->ifindex);269 if (ret) {270 cfg80211_unregister_netdevice(vif->netdev);271 vif->netdev = NULL;272 goto error_del_vif;273 }274 }275 276 vif->wdev.netdev = vif->netdev;277 return &vif->wdev;278 279error_del_vif:280 qtnf_cmd_send_del_intf(vif);281err_cmd:282 vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;283 284 return ERR_PTR(ret);285}286 287static int qtnf_mgmt_set_appie(struct qtnf_vif *vif,288 const struct cfg80211_beacon_data *info)289{290 int ret = 0;291 292 if (!info->beacon_ies || !info->beacon_ies_len) {293 ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_IE_SET_BEACON_IES,294 NULL, 0);295 } else {296 ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_IE_SET_BEACON_IES,297 info->beacon_ies,298 info->beacon_ies_len);299 }300 301 if (ret)302 goto out;303 304 if (!info->proberesp_ies || !info->proberesp_ies_len) {305 ret = qtnf_cmd_send_mgmt_set_appie(vif,306 QLINK_IE_SET_PROBE_RESP_IES,307 NULL, 0);308 } else {309 ret = qtnf_cmd_send_mgmt_set_appie(vif,310 QLINK_IE_SET_PROBE_RESP_IES,311 info->proberesp_ies,312 info->proberesp_ies_len);313 }314 315 if (ret)316 goto out;317 318 if (!info->assocresp_ies || !info->assocresp_ies_len) {319 ret = qtnf_cmd_send_mgmt_set_appie(vif,320 QLINK_IE_SET_ASSOC_RESP,321 NULL, 0);322 } else {323 ret = qtnf_cmd_send_mgmt_set_appie(vif,324 QLINK_IE_SET_ASSOC_RESP,325 info->assocresp_ies,326 info->assocresp_ies_len);327 }328 329out:330 return ret;331}332 333static int qtnf_change_beacon(struct wiphy *wiphy, struct net_device *dev,334 struct cfg80211_ap_update *info)335{336 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);337 338 return qtnf_mgmt_set_appie(vif, &info->beacon);339}340 341static int qtnf_start_ap(struct wiphy *wiphy, struct net_device *dev,342 struct cfg80211_ap_settings *settings)343{344 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);345 int ret;346 347 ret = qtnf_cmd_send_start_ap(vif, settings);348 if (ret)349 pr_err("VIF%u.%u: failed to start AP\n", vif->mac->macid,350 vif->vifid);351 352 return ret;353}354 355static int qtnf_stop_ap(struct wiphy *wiphy, struct net_device *dev,356 unsigned int link_id)357{358 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);359 int ret;360 361 qtnf_scan_done(vif->mac, true);362 363 ret = qtnf_cmd_send_stop_ap(vif);364 if (ret)365 pr_err("VIF%u.%u: failed to stop AP operation in FW\n",366 vif->mac->macid, vif->vifid);367 368 netif_carrier_off(vif->netdev);369 370 return ret;371}372 373static int qtnf_set_wiphy_params(struct wiphy *wiphy, u32 changed)374{375 struct qtnf_wmac *mac = wiphy_priv(wiphy);376 struct qtnf_vif *vif;377 int ret;378 379 vif = qtnf_mac_get_base_vif(mac);380 if (!vif) {381 pr_err("MAC%u: primary VIF is not configured\n", mac->macid);382 return -EFAULT;383 }384 385 ret = qtnf_cmd_send_update_phy_params(mac, changed);386 if (ret)387 pr_err("MAC%u: failed to update PHY params\n", mac->macid);388 389 return ret;390}391 392static void393qtnf_update_mgmt_frame_registrations(struct wiphy *wiphy,394 struct wireless_dev *wdev,395 struct mgmt_frame_regs *upd)396{397 struct qtnf_vif *vif = qtnf_netdev_get_priv(wdev->netdev);398 u16 new_mask = upd->interface_stypes;399 u16 old_mask = vif->mgmt_frames_bitmask;400 static const struct {401 u16 mask, qlink_type;402 } updates[] = {403 {404 .mask = BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |405 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4),406 .qlink_type = QLINK_MGMT_FRAME_ASSOC_REQ,407 },408 {409 .mask = BIT(IEEE80211_STYPE_AUTH >> 4),410 .qlink_type = QLINK_MGMT_FRAME_AUTH,411 },412 {413 .mask = BIT(IEEE80211_STYPE_PROBE_REQ >> 4),414 .qlink_type = QLINK_MGMT_FRAME_PROBE_REQ,415 },416 {417 .mask = BIT(IEEE80211_STYPE_ACTION >> 4),418 .qlink_type = QLINK_MGMT_FRAME_ACTION,419 },420 };421 unsigned int i;422 423 if (new_mask == old_mask)424 return;425 426 for (i = 0; i < ARRAY_SIZE(updates); i++) {427 u16 mask = updates[i].mask;428 u16 qlink_frame_type = updates[i].qlink_type;429 bool reg;430 431 /* the ! are here due to the assoc/reassoc merge */432 if (!(new_mask & mask) == !(old_mask & mask))433 continue;434 435 reg = new_mask & mask;436 437 if (qtnf_cmd_send_register_mgmt(vif, qlink_frame_type, reg))438 pr_warn("VIF%u.%u: failed to %sregister qlink frame type 0x%x\n",439 vif->mac->macid, vif->vifid, reg ? "" : "un",440 qlink_frame_type);441 }442 443 vif->mgmt_frames_bitmask = new_mask;444}445 446static int447qtnf_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,448 struct cfg80211_mgmt_tx_params *params, u64 *cookie)449{450 struct qtnf_vif *vif = qtnf_netdev_get_priv(wdev->netdev);451 const struct ieee80211_mgmt *mgmt_frame = (void *)params->buf;452 u32 short_cookie = get_random_u32();453 u16 flags = 0;454 u16 freq;455 456 *cookie = short_cookie;457 458 if (params->offchan)459 flags |= QLINK_FRAME_TX_FLAG_OFFCHAN;460 461 if (params->no_cck)462 flags |= QLINK_FRAME_TX_FLAG_NO_CCK;463 464 if (params->dont_wait_for_ack)465 flags |= QLINK_FRAME_TX_FLAG_ACK_NOWAIT;466 467 /* If channel is not specified, pass "freq = 0" to tell device468 * firmware to use current channel.469 */470 if (params->chan)471 freq = params->chan->center_freq;472 else473 freq = 0;474 475 pr_debug("%s freq:%u; FC:%.4X; DA:%pM; len:%zu; C:%.8X; FL:%.4X\n",476 wdev->netdev->name, freq,477 le16_to_cpu(mgmt_frame->frame_control), mgmt_frame->da,478 params->len, short_cookie, flags);479 480 return qtnf_cmd_send_frame(vif, short_cookie, flags,481 freq, params->buf, params->len);482}483 484static int485qtnf_get_station(struct wiphy *wiphy, struct net_device *dev,486 const u8 *mac, struct station_info *sinfo)487{488 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);489 490 sinfo->generation = vif->generation;491 return qtnf_cmd_get_sta_info(vif, mac, sinfo);492}493 494static int495qtnf_dump_station(struct wiphy *wiphy, struct net_device *dev,496 int idx, u8 *mac, struct station_info *sinfo)497{498 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);499 const struct qtnf_sta_node *sta_node;500 int ret;501 502 switch (vif->wdev.iftype) {503 case NL80211_IFTYPE_STATION:504 if (idx != 0 || !vif->wdev.connected)505 return -ENOENT;506 507 ether_addr_copy(mac, vif->bssid);508 break;509 case NL80211_IFTYPE_AP:510 sta_node = qtnf_sta_list_lookup_index(&vif->sta_list, idx);511 if (unlikely(!sta_node))512 return -ENOENT;513 514 ether_addr_copy(mac, sta_node->mac_addr);515 break;516 default:517 return -ENOTSUPP;518 }519 520 ret = qtnf_cmd_get_sta_info(vif, mac, sinfo);521 522 if (vif->wdev.iftype == NL80211_IFTYPE_AP) {523 if (ret == -ENOENT) {524 cfg80211_del_sta(vif->netdev, mac, GFP_KERNEL);525 sinfo->filled = 0;526 }527 }528 529 sinfo->generation = vif->generation;530 531 return ret;532}533 534static int qtnf_add_key(struct wiphy *wiphy, struct net_device *dev,535 int link_id, u8 key_index, bool pairwise,536 const u8 *mac_addr, struct key_params *params)537{538 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);539 int ret;540 541 ret = qtnf_cmd_send_add_key(vif, key_index, pairwise, mac_addr, params);542 if (ret)543 pr_err("VIF%u.%u: failed to add key: cipher=%x idx=%u pw=%u\n",544 vif->mac->macid, vif->vifid, params->cipher, key_index,545 pairwise);546 547 return ret;548}549 550static int qtnf_del_key(struct wiphy *wiphy, struct net_device *dev,551 int link_id, u8 key_index, bool pairwise,552 const u8 *mac_addr)553{554 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);555 int ret;556 557 ret = qtnf_cmd_send_del_key(vif, key_index, pairwise, mac_addr);558 if (ret) {559 if (ret == -ENOENT) {560 pr_debug("VIF%u.%u: key index %d out of bounds\n",561 vif->mac->macid, vif->vifid, key_index);562 } else {563 pr_err("VIF%u.%u: failed to delete key: idx=%u pw=%u\n",564 vif->mac->macid, vif->vifid,565 key_index, pairwise);566 }567 }568 569 return ret;570}571 572static int qtnf_set_default_key(struct wiphy *wiphy, struct net_device *dev,573 int link_id, u8 key_index, bool unicast,574 bool multicast)575{576 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);577 int ret;578 579 ret = qtnf_cmd_send_set_default_key(vif, key_index, unicast, multicast);580 if (ret)581 pr_err("VIF%u.%u: failed to set dflt key: idx=%u uc=%u mc=%u\n",582 vif->mac->macid, vif->vifid, key_index, unicast,583 multicast);584 585 return ret;586}587 588static int589qtnf_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *dev,590 int link_id, u8 key_index)591{592 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);593 int ret;594 595 ret = qtnf_cmd_send_set_default_mgmt_key(vif, key_index);596 if (ret)597 pr_err("VIF%u.%u: failed to set default MGMT key: idx=%u\n",598 vif->mac->macid, vif->vifid, key_index);599 600 return ret;601}602 603static int604qtnf_change_station(struct wiphy *wiphy, struct net_device *dev,605 const u8 *mac, struct station_parameters *params)606{607 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);608 int ret;609 610 ret = qtnf_cmd_send_change_sta(vif, mac, params);611 if (ret)612 pr_err("VIF%u.%u: failed to change STA %pM\n",613 vif->mac->macid, vif->vifid, mac);614 615 return ret;616}617 618static int619qtnf_del_station(struct wiphy *wiphy, struct net_device *dev,620 struct station_del_parameters *params)621{622 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);623 int ret;624 625 if (params->mac &&626 (vif->wdev.iftype == NL80211_IFTYPE_AP) &&627 !is_broadcast_ether_addr(params->mac) &&628 !qtnf_sta_list_lookup(&vif->sta_list, params->mac))629 return 0;630 631 ret = qtnf_cmd_send_del_sta(vif, params);632 if (ret)633 pr_err("VIF%u.%u: failed to delete STA %pM\n",634 vif->mac->macid, vif->vifid, params->mac);635 636 return ret;637}638 639static int640qtnf_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)641{642 struct qtnf_wmac *mac = wiphy_priv(wiphy);643 int ret;644 645 cancel_delayed_work_sync(&mac->scan_timeout);646 647 mac->scan_req = request;648 649 ret = qtnf_cmd_send_scan(mac);650 if (ret) {651 pr_err("MAC%u: failed to start scan\n", mac->macid);652 mac->scan_req = NULL;653 goto out;654 }655 656 pr_debug("MAC%u: scan started\n", mac->macid);657 queue_delayed_work(mac->bus->workqueue, &mac->scan_timeout,658 QTNF_SCAN_TIMEOUT_SEC * HZ);659 660out:661 return ret;662}663 664static int665qtnf_connect(struct wiphy *wiphy, struct net_device *dev,666 struct cfg80211_connect_params *sme)667{668 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);669 int ret;670 671 if (vif->wdev.iftype != NL80211_IFTYPE_STATION)672 return -EOPNOTSUPP;673 674 if (sme->auth_type == NL80211_AUTHTYPE_SAE &&675 !(sme->flags & CONNECT_REQ_EXTERNAL_AUTH_SUPPORT)) {676 pr_err("can not offload authentication to userspace\n");677 return -EOPNOTSUPP;678 }679 680 if (sme->bssid)681 ether_addr_copy(vif->bssid, sme->bssid);682 else683 eth_zero_addr(vif->bssid);684 685 ret = qtnf_cmd_send_connect(vif, sme);686 if (ret)687 pr_err("VIF%u.%u: failed to connect\n",688 vif->mac->macid, vif->vifid);689 690 return ret;691}692 693static int694qtnf_external_auth(struct wiphy *wiphy, struct net_device *dev,695 struct cfg80211_external_auth_params *auth)696{697 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);698 int ret;699 700 if (vif->wdev.iftype == NL80211_IFTYPE_STATION &&701 !ether_addr_equal(vif->bssid, auth->bssid))702 pr_warn("unexpected bssid: %pM", auth->bssid);703 704 ret = qtnf_cmd_send_external_auth(vif, auth);705 if (ret)706 pr_err("VIF%u.%u: failed to report external auth\n",707 vif->mac->macid, vif->vifid);708 709 return ret;710}711 712static int713qtnf_disconnect(struct wiphy *wiphy, struct net_device *dev,714 u16 reason_code)715{716 struct qtnf_wmac *mac = wiphy_priv(wiphy);717 struct qtnf_vif *vif;718 int ret = 0;719 720 vif = qtnf_mac_get_base_vif(mac);721 if (!vif) {722 pr_err("MAC%u: primary VIF is not configured\n", mac->macid);723 return -EFAULT;724 }725 726 if (vif->wdev.iftype != NL80211_IFTYPE_STATION)727 return -EOPNOTSUPP;728 729 ret = qtnf_cmd_send_disconnect(vif, reason_code);730 if (ret)731 pr_err("VIF%u.%u: failed to disconnect\n",732 mac->macid, vif->vifid);733 734 if (vif->wdev.connected) {735 netif_carrier_off(vif->netdev);736 cfg80211_disconnected(vif->netdev, reason_code,737 NULL, 0, true, GFP_KERNEL);738 }739 740 return ret;741}742 743static int744qtnf_dump_survey(struct wiphy *wiphy, struct net_device *dev,745 int idx, struct survey_info *survey)746{747 struct qtnf_wmac *mac = wiphy_priv(wiphy);748 struct wireless_dev *wdev = dev->ieee80211_ptr;749 struct ieee80211_supported_band *sband;750 const struct cfg80211_chan_def *chandef = wdev_chandef(wdev, 0);751 struct ieee80211_channel *chan;752 int ret;753 754 sband = wiphy->bands[NL80211_BAND_2GHZ];755 if (sband && idx >= sband->n_channels) {756 idx -= sband->n_channels;757 sband = NULL;758 }759 760 if (!sband)761 sband = wiphy->bands[NL80211_BAND_5GHZ];762 763 if (!sband || idx >= sband->n_channels)764 return -ENOENT;765 766 chan = &sband->channels[idx];767 survey->channel = chan;768 survey->filled = 0x0;769 770 if (chandef && chan == chandef->chan)771 survey->filled = SURVEY_INFO_IN_USE;772 773 ret = qtnf_cmd_get_chan_stats(mac, chan->center_freq, survey);774 if (ret)775 pr_debug("failed to get chan(%d) stats from card\n",776 chan->hw_value);777 778 return ret;779}780 781static int782qtnf_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev,783 unsigned int link_id, struct cfg80211_chan_def *chandef)784{785 struct net_device *ndev = wdev->netdev;786 struct qtnf_vif *vif;787 int ret;788 789 if (!ndev)790 return -ENODEV;791 792 vif = qtnf_netdev_get_priv(wdev->netdev);793 794 ret = qtnf_cmd_get_channel(vif, chandef);795 if (ret) {796 pr_err("%s: failed to get channel: %d\n", ndev->name, ret);797 ret = -ENODATA;798 goto out;799 }800 801 if (!cfg80211_chandef_valid(chandef)) {802 pr_err("%s: bad channel freq=%u cf1=%u cf2=%u bw=%u\n",803 ndev->name, chandef->chan->center_freq,804 chandef->center_freq1, chandef->center_freq2,805 chandef->width);806 ret = -ENODATA;807 goto out;808 }809 810out:811 return ret;812}813 814static int qtnf_channel_switch(struct wiphy *wiphy, struct net_device *dev,815 struct cfg80211_csa_settings *params)816{817 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);818 int ret;819 820 pr_debug("%s: chan(%u) count(%u) radar(%u) block_tx(%u)\n", dev->name,821 params->chandef.chan->hw_value, params->count,822 params->radar_required, params->block_tx);823 824 if (!cfg80211_chandef_valid(¶ms->chandef)) {825 pr_err("%s: invalid channel\n", dev->name);826 return -EINVAL;827 }828 829 ret = qtnf_cmd_send_chan_switch(vif, params);830 if (ret)831 pr_warn("%s: failed to switch to channel (%u)\n",832 dev->name, params->chandef.chan->hw_value);833 834 return ret;835}836 837static int qtnf_start_radar_detection(struct wiphy *wiphy,838 struct net_device *ndev,839 struct cfg80211_chan_def *chandef,840 u32 cac_time_ms, int link_id)841{842 struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);843 int ret;844 845 if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD))846 return -ENOTSUPP;847 848 ret = qtnf_cmd_start_cac(vif, chandef, cac_time_ms);849 if (ret)850 pr_err("%s: failed to start CAC ret=%d\n", ndev->name, ret);851 852 return ret;853}854 855static int qtnf_set_mac_acl(struct wiphy *wiphy,856 struct net_device *dev,857 const struct cfg80211_acl_data *params)858{859 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);860 int ret;861 862 ret = qtnf_cmd_set_mac_acl(vif, params);863 if (ret)864 pr_err("%s: failed to set mac ACL ret=%d\n", dev->name, ret);865 866 return ret;867}868 869static int qtnf_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,870 bool enabled, int timeout)871{872 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);873 int ret;874 875 ret = qtnf_cmd_send_pm_set(vif, enabled ? QLINK_PM_AUTO_STANDBY :876 QLINK_PM_OFF, timeout);877 if (ret)878 pr_err("%s: failed to set PM mode ret=%d\n", dev->name, ret);879 880 return ret;881}882 883static int qtnf_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,884 int *dbm)885{886 struct qtnf_vif *vif = qtnf_netdev_get_priv(wdev->netdev);887 int ret;888 889 ret = qtnf_cmd_get_tx_power(vif, dbm);890 if (ret)891 pr_err("MAC%u: failed to get Tx power\n", vif->mac->macid);892 893 return ret;894}895 896static int qtnf_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,897 enum nl80211_tx_power_setting type, int mbm)898{899 struct qtnf_vif *vif;900 int ret;901 902 if (wdev) {903 vif = qtnf_netdev_get_priv(wdev->netdev);904 } else {905 struct qtnf_wmac *mac = wiphy_priv(wiphy);906 907 vif = qtnf_mac_get_base_vif(mac);908 if (!vif) {909 pr_err("MAC%u: primary VIF is not configured\n",910 mac->macid);911 return -EFAULT;912 }913 }914 915 ret = qtnf_cmd_set_tx_power(vif, type, mbm);916 if (ret)917 pr_err("MAC%u: failed to set Tx power\n", vif->mac->macid);918 919 return ret;920}921 922static int qtnf_update_owe_info(struct wiphy *wiphy, struct net_device *dev,923 struct cfg80211_update_owe_info *owe_info)924{925 struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);926 int ret;927 928 if (vif->wdev.iftype != NL80211_IFTYPE_AP)929 return -EOPNOTSUPP;930 931 ret = qtnf_cmd_send_update_owe(vif, owe_info);932 if (ret)933 pr_err("VIF%u.%u: failed to update owe info\n",934 vif->mac->macid, vif->vifid);935 936 return ret;937}938 939#ifdef CONFIG_PM940static int qtnf_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wowlan)941{942 struct qtnf_wmac *mac = wiphy_priv(wiphy);943 struct qtnf_vif *vif;944 int ret = 0;945 946 vif = qtnf_mac_get_base_vif(mac);947 if (!vif) {948 pr_err("MAC%u: primary VIF is not configured\n", mac->macid);949 ret = -EFAULT;950 goto exit;951 }952 953 if (!wowlan) {954 pr_debug("WoWLAN triggers are not enabled\n");955 qtnf_virtual_intf_cleanup(vif->netdev);956 goto exit;957 }958 959 qtnf_scan_done(vif->mac, true);960 961 ret = qtnf_cmd_send_wowlan_set(vif, wowlan);962 if (ret) {963 pr_err("MAC%u: failed to set WoWLAN triggers\n",964 mac->macid);965 goto exit;966 }967 968exit:969 return ret;970}971 972static int qtnf_resume(struct wiphy *wiphy)973{974 struct qtnf_wmac *mac = wiphy_priv(wiphy);975 struct qtnf_vif *vif;976 int ret = 0;977 978 vif = qtnf_mac_get_base_vif(mac);979 if (!vif) {980 pr_err("MAC%u: primary VIF is not configured\n", mac->macid);981 return -EFAULT;982 }983 984 ret = qtnf_cmd_send_wowlan_set(vif, NULL);985 if (ret)986 pr_err("MAC%u: failed to reset WoWLAN triggers\n",987 mac->macid);988 989 return ret;990}991 992static void qtnf_set_wakeup(struct wiphy *wiphy, bool enabled)993{994 struct qtnf_wmac *mac = wiphy_priv(wiphy);995 struct qtnf_bus *bus = mac->bus;996 997 device_set_wakeup_enable(bus->dev, enabled);998}999#endif1000 1001static struct cfg80211_ops qtn_cfg80211_ops = {1002 .add_virtual_intf = qtnf_add_virtual_intf,1003 .change_virtual_intf = qtnf_change_virtual_intf,1004 .del_virtual_intf = qtnf_del_virtual_intf,1005 .start_ap = qtnf_start_ap,1006 .change_beacon = qtnf_change_beacon,1007 .stop_ap = qtnf_stop_ap,1008 .set_wiphy_params = qtnf_set_wiphy_params,1009 .update_mgmt_frame_registrations =1010 qtnf_update_mgmt_frame_registrations,1011 .mgmt_tx = qtnf_mgmt_tx,1012 .change_station = qtnf_change_station,1013 .del_station = qtnf_del_station,1014 .get_station = qtnf_get_station,1015 .dump_station = qtnf_dump_station,1016 .add_key = qtnf_add_key,1017 .del_key = qtnf_del_key,1018 .set_default_key = qtnf_set_default_key,1019 .set_default_mgmt_key = qtnf_set_default_mgmt_key,1020 .scan = qtnf_scan,1021 .connect = qtnf_connect,1022 .external_auth = qtnf_external_auth,1023 .disconnect = qtnf_disconnect,1024 .dump_survey = qtnf_dump_survey,1025 .get_channel = qtnf_get_channel,1026 .channel_switch = qtnf_channel_switch,1027 .start_radar_detection = qtnf_start_radar_detection,1028 .set_mac_acl = qtnf_set_mac_acl,1029 .set_power_mgmt = qtnf_set_power_mgmt,1030 .get_tx_power = qtnf_get_tx_power,1031 .set_tx_power = qtnf_set_tx_power,1032 .update_owe_info = qtnf_update_owe_info,1033#ifdef CONFIG_PM1034 .suspend = qtnf_suspend,1035 .resume = qtnf_resume,1036 .set_wakeup = qtnf_set_wakeup,1037#endif1038};1039 1040static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy,1041 struct regulatory_request *req)1042{1043 struct qtnf_wmac *mac = wiphy_priv(wiphy);1044 enum nl80211_band band;1045 int ret;1046 1047 pr_debug("MAC%u: initiator=%d alpha=%c%c\n", mac->macid, req->initiator,1048 req->alpha2[0], req->alpha2[1]);1049 1050 ret = qtnf_cmd_reg_notify(mac, req, qtnf_slave_radar_get(),1051 qtnf_dfs_offload_get());1052 if (ret) {1053 pr_err("MAC%u: failed to update region to %c%c: %d\n",1054 mac->macid, req->alpha2[0], req->alpha2[1], ret);1055 return;1056 }1057 1058 for (band = 0; band < NUM_NL80211_BANDS; ++band) {1059 if (!wiphy->bands[band])1060 continue;1061 1062 ret = qtnf_cmd_band_info_get(mac, wiphy->bands[band]);1063 if (ret)1064 pr_err("MAC%u: failed to update band %u\n",1065 mac->macid, band);1066 }1067}1068 1069struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus,1070 struct platform_device *pdev)1071{1072 struct wiphy *wiphy;1073 1074 if (qtnf_dfs_offload_get() &&1075 qtnf_hwcap_is_set(&bus->hw_info, QLINK_HW_CAPAB_DFS_OFFLOAD))1076 qtn_cfg80211_ops.start_radar_detection = NULL;1077 1078 if (!qtnf_hwcap_is_set(&bus->hw_info, QLINK_HW_CAPAB_PWR_MGMT))1079 qtn_cfg80211_ops.set_power_mgmt = NULL;1080 1081 wiphy = wiphy_new(&qtn_cfg80211_ops, sizeof(struct qtnf_wmac));1082 if (!wiphy)1083 return NULL;1084 1085 if (pdev)1086 set_wiphy_dev(wiphy, &pdev->dev);1087 else1088 set_wiphy_dev(wiphy, bus->dev);1089 1090 return wiphy;1091}1092 1093static int1094qtnf_wiphy_setup_if_comb(struct wiphy *wiphy, struct qtnf_mac_info *mac_info)1095{1096 struct ieee80211_iface_combination *if_comb;1097 size_t n_if_comb;1098 u16 interface_modes = 0;1099 size_t i, j;1100 1101 if_comb = mac_info->if_comb;1102 n_if_comb = mac_info->n_if_comb;1103 1104 if (!if_comb || !n_if_comb)1105 return -ENOENT;1106 1107 for (i = 0; i < n_if_comb; i++) {1108 if_comb[i].radar_detect_widths = mac_info->radar_detect_widths;1109 1110 for (j = 0; j < if_comb[i].n_limits; j++)1111 interface_modes |= if_comb[i].limits[j].types;1112 }1113 1114 wiphy->iface_combinations = if_comb;1115 wiphy->n_iface_combinations = n_if_comb;1116 wiphy->interface_modes = interface_modes;1117 1118 return 0;1119}1120 1121int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)1122{1123 struct wiphy *wiphy = priv_to_wiphy(mac);1124 struct qtnf_mac_info *macinfo = &mac->macinfo;1125 int ret;1126 bool regdomain_is_known;1127 1128 if (!wiphy) {1129 pr_err("invalid wiphy pointer\n");1130 return -EFAULT;1131 }1132 1133 wiphy->frag_threshold = macinfo->frag_thr;1134 wiphy->rts_threshold = macinfo->rts_thr;1135 wiphy->retry_short = macinfo->sretry_limit;1136 wiphy->retry_long = macinfo->lretry_limit;1137 wiphy->coverage_class = macinfo->coverage_class;1138 1139 wiphy->max_scan_ssids =1140 (macinfo->max_scan_ssids) ? macinfo->max_scan_ssids : 1;1141 wiphy->max_scan_ie_len = QTNF_MAX_VSIE_LEN;1142 wiphy->mgmt_stypes = qtnf_mgmt_stypes;1143 wiphy->max_remain_on_channel_duration = 5000;1144 wiphy->max_acl_mac_addrs = macinfo->max_acl_mac_addrs;1145 wiphy->max_num_csa_counters = 2;1146 1147 ret = qtnf_wiphy_setup_if_comb(wiphy, macinfo);1148 if (ret)1149 goto out;1150 1151 /* Initialize cipher suits */1152 wiphy->cipher_suites = qtnf_cipher_suites;1153 wiphy->n_cipher_suites = ARRAY_SIZE(qtnf_cipher_suites);1154 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;1155 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |1156 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |1157 WIPHY_FLAG_AP_UAPSD |1158 WIPHY_FLAG_HAS_CHANNEL_SWITCH |1159 WIPHY_FLAG_4ADDR_STATION |1160 WIPHY_FLAG_NETNS_OK;1161 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;1162 1163 if (qtnf_dfs_offload_get() &&1164 qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_DFS_OFFLOAD))1165 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD);1166 1167 if (qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_SCAN_DWELL))1168 wiphy_ext_feature_set(wiphy,1169 NL80211_EXT_FEATURE_SET_SCAN_DWELL);1170 1171 wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |1172 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2;1173 1174 wiphy->available_antennas_tx = macinfo->num_tx_chain;1175 wiphy->available_antennas_rx = macinfo->num_rx_chain;1176 1177 wiphy->max_ap_assoc_sta = macinfo->max_ap_assoc_sta;1178 wiphy->ht_capa_mod_mask = &macinfo->ht_cap_mod_mask;1179 wiphy->vht_capa_mod_mask = &macinfo->vht_cap_mod_mask;1180 1181 ether_addr_copy(wiphy->perm_addr, mac->macaddr);1182 1183 if (qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_STA_INACT_TIMEOUT))1184 wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;1185 1186 if (qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_SCAN_RANDOM_MAC_ADDR))1187 wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;1188 1189 if (!qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_OBSS_SCAN))1190 wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN;1191 1192 if (qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_SAE))1193 wiphy->features |= NL80211_FEATURE_SAE;1194 1195#ifdef CONFIG_PM1196 if (macinfo->wowlan)1197 wiphy->wowlan = macinfo->wowlan;1198#endif1199 1200 regdomain_is_known = isalpha(mac->rd->alpha2[0]) &&1201 isalpha(mac->rd->alpha2[1]);1202 1203 if (qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_REG_UPDATE)) {1204 wiphy->reg_notifier = qtnf_cfg80211_reg_notifier;1205 1206 if (mac->rd->alpha2[0] == '9' && mac->rd->alpha2[1] == '9') {1207 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |1208 REGULATORY_STRICT_REG;1209 wiphy_apply_custom_regulatory(wiphy, mac->rd);1210 } else if (regdomain_is_known) {1211 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;1212 }1213 } else {1214 wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;1215 }1216 1217 if (mac->macinfo.extended_capabilities_len) {1218 wiphy->extended_capabilities =1219 mac->macinfo.extended_capabilities;1220 wiphy->extended_capabilities_mask =1221 mac->macinfo.extended_capabilities_mask;1222 wiphy->extended_capabilities_len =1223 mac->macinfo.extended_capabilities_len;1224 }1225 1226 strscpy(wiphy->fw_version, hw_info->fw_version,1227 sizeof(wiphy->fw_version));1228 wiphy->hw_version = hw_info->hw_version;1229 1230 ret = wiphy_register(wiphy);1231 if (ret < 0)1232 goto out;1233 1234 if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)1235 ret = regulatory_set_wiphy_regd(wiphy, mac->rd);1236 else if (regdomain_is_known)1237 ret = regulatory_hint(wiphy, mac->rd->alpha2);1238 1239out:1240 return ret;1241}1242 1243void qtnf_netdev_updown(struct net_device *ndev, bool up)1244{1245 struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);1246 1247 if (qtnf_cmd_send_updown_intf(vif, up))1248 pr_err("failed to send %s command to VIF%u.%u\n",1249 up ? "UP" : "DOWN", vif->mac->macid, vif->vifid);1250}1251 1252void qtnf_virtual_intf_cleanup(struct net_device *ndev)1253{1254 struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);1255 struct qtnf_wmac *mac = wiphy_priv(vif->wdev.wiphy);1256 1257 if (vif->wdev.iftype == NL80211_IFTYPE_STATION)1258 qtnf_disconnect(vif->wdev.wiphy, ndev,1259 WLAN_REASON_DEAUTH_LEAVING);1260 1261 qtnf_scan_done(mac, true);1262}1263 1264void qtnf_cfg80211_vif_reset(struct qtnf_vif *vif)1265{1266 if (vif->wdev.iftype == NL80211_IFTYPE_STATION)1267 cfg80211_disconnected(vif->netdev, WLAN_REASON_DEAUTH_LEAVING,1268 NULL, 0, 1, GFP_KERNEL);1269 1270 cfg80211_shutdown_all_interfaces(vif->wdev.wiphy);1271}1272 1273void qtnf_band_init_rates(struct ieee80211_supported_band *band)1274{1275 switch (band->band) {1276 case NL80211_BAND_2GHZ:1277 band->bitrates = qtnf_rates_2g;1278 band->n_bitrates = ARRAY_SIZE(qtnf_rates_2g);1279 break;1280 case NL80211_BAND_5GHZ:1281 band->bitrates = qtnf_rates_5g;1282 band->n_bitrates = ARRAY_SIZE(qtnf_rates_5g);1283 break;1284 default:1285 band->bitrates = NULL;1286 band->n_bitrates = 0;1287 break;1288 }1289}1290