933 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/module.h>6#include <linux/if_ether.h>7#include <linux/nospec.h>8 9#include "core.h"10#include "bus.h"11#include "trans.h"12#include "commands.h"13#include "cfg80211.h"14#include "event.h"15#include "util.h"16#include "switchdev.h"17 18#define QTNF_PRIMARY_VIF_IDX 019 20static bool slave_radar = true;21module_param(slave_radar, bool, 0644);22MODULE_PARM_DESC(slave_radar, "set 0 to disable radar detection in slave mode");23 24static bool dfs_offload;25module_param(dfs_offload, bool, 0644);26MODULE_PARM_DESC(dfs_offload, "set 1 to enable DFS offload to firmware");27 28static struct dentry *qtnf_debugfs_dir;29 30bool qtnf_slave_radar_get(void)31{32 return slave_radar;33}34 35bool qtnf_dfs_offload_get(void)36{37 return dfs_offload;38}39 40struct qtnf_wmac *qtnf_core_get_mac(const struct qtnf_bus *bus, u8 macid)41{42 struct qtnf_wmac *mac = NULL;43 44 if (macid >= QTNF_MAX_MAC) {45 pr_err("invalid MAC index %u\n", macid);46 return NULL;47 }48 49 macid = array_index_nospec(macid, QTNF_MAX_MAC);50 mac = bus->mac[macid];51 52 if (unlikely(!mac)) {53 pr_err("MAC%u: not initialized\n", macid);54 return NULL;55 }56 57 return mac;58}59 60/* Netdev handler for open.61 */62static int qtnf_netdev_open(struct net_device *ndev)63{64 netif_carrier_off(ndev);65 qtnf_netdev_updown(ndev, 1);66 return 0;67}68 69/* Netdev handler for close.70 */71static int qtnf_netdev_close(struct net_device *ndev)72{73 netif_carrier_off(ndev);74 qtnf_virtual_intf_cleanup(ndev);75 qtnf_netdev_updown(ndev, 0);76 return 0;77}78 79static void qtnf_packet_send_hi_pri(struct sk_buff *skb)80{81 struct qtnf_vif *vif = qtnf_netdev_get_priv(skb->dev);82 83 skb_queue_tail(&vif->high_pri_tx_queue, skb);84 queue_work(vif->mac->bus->hprio_workqueue, &vif->high_pri_tx_work);85}86 87/* Netdev handler for data transmission.88 */89static netdev_tx_t90qtnf_netdev_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)91{92 struct qtnf_vif *vif;93 struct qtnf_wmac *mac;94 95 vif = qtnf_netdev_get_priv(ndev);96 97 if (unlikely(skb->dev != ndev)) {98 pr_err_ratelimited("invalid skb->dev");99 dev_kfree_skb_any(skb);100 return 0;101 }102 103 if (unlikely(vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)) {104 pr_err_ratelimited("%s: VIF not initialized\n", ndev->name);105 dev_kfree_skb_any(skb);106 return 0;107 }108 109 mac = vif->mac;110 if (unlikely(!mac)) {111 pr_err_ratelimited("%s: NULL mac pointer", ndev->name);112 dev_kfree_skb_any(skb);113 return 0;114 }115 116 if (!skb->len || (skb->len > ETH_FRAME_LEN)) {117 pr_err_ratelimited("%s: invalid skb len %d\n", ndev->name,118 skb->len);119 dev_kfree_skb_any(skb);120 ndev->stats.tx_dropped++;121 return 0;122 }123 124 /* tx path is enabled: reset vif timeout */125 vif->cons_tx_timeout_cnt = 0;126 127 if (unlikely(skb->protocol == htons(ETH_P_PAE))) {128 qtnf_packet_send_hi_pri(skb);129 dev_sw_netstats_tx_add(ndev, 1, skb->len);130 return NETDEV_TX_OK;131 }132 133 return qtnf_bus_data_tx(mac->bus, skb, mac->macid, vif->vifid);134}135 136/* Netdev handler for transmission timeout.137 */138static void qtnf_netdev_tx_timeout(struct net_device *ndev, unsigned int txqueue)139{140 struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);141 struct qtnf_wmac *mac;142 struct qtnf_bus *bus;143 144 if (unlikely(!vif || !vif->mac || !vif->mac->bus))145 return;146 147 mac = vif->mac;148 bus = mac->bus;149 150 pr_warn("VIF%u.%u: Tx timeout- %lu\n", mac->macid, vif->vifid, jiffies);151 152 qtnf_bus_data_tx_timeout(bus, ndev);153 ndev->stats.tx_errors++;154 155 if (++vif->cons_tx_timeout_cnt > QTNF_TX_TIMEOUT_TRSHLD) {156 pr_err("Tx timeout threshold exceeded !\n");157 pr_err("schedule interface %s reset !\n", netdev_name(ndev));158 queue_work(bus->workqueue, &vif->reset_work);159 }160}161 162static int qtnf_netdev_set_mac_address(struct net_device *ndev, void *addr)163{164 struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);165 struct sockaddr *sa = addr;166 int ret;167 unsigned char old_addr[ETH_ALEN];168 169 memcpy(old_addr, sa->sa_data, sizeof(old_addr));170 171 ret = eth_mac_addr(ndev, sa);172 if (ret)173 return ret;174 175 qtnf_scan_done(vif->mac, true);176 177 ret = qtnf_cmd_send_change_intf_type(vif, vif->wdev.iftype,178 vif->wdev.use_4addr,179 sa->sa_data);180 181 if (ret)182 eth_hw_addr_set(ndev, old_addr);183 184 return ret;185}186 187static int qtnf_netdev_port_parent_id(struct net_device *ndev,188 struct netdev_phys_item_id *ppid)189{190 const struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);191 const struct qtnf_bus *bus = vif->mac->bus;192 193 ppid->id_len = sizeof(bus->hw_id);194 memcpy(&ppid->id, bus->hw_id, ppid->id_len);195 196 return 0;197}198 199/* Network device ops handlers */200const struct net_device_ops qtnf_netdev_ops = {201 .ndo_open = qtnf_netdev_open,202 .ndo_stop = qtnf_netdev_close,203 .ndo_start_xmit = qtnf_netdev_hard_start_xmit,204 .ndo_tx_timeout = qtnf_netdev_tx_timeout,205 .ndo_set_mac_address = qtnf_netdev_set_mac_address,206 .ndo_get_port_parent_id = qtnf_netdev_port_parent_id,207};208 209static int qtnf_mac_init_single_band(struct wiphy *wiphy,210 struct qtnf_wmac *mac,211 enum nl80211_band band)212{213 int ret;214 215 wiphy->bands[band] = kzalloc(sizeof(*wiphy->bands[band]), GFP_KERNEL);216 if (!wiphy->bands[band])217 return -ENOMEM;218 219 wiphy->bands[band]->band = band;220 221 ret = qtnf_cmd_band_info_get(mac, wiphy->bands[band]);222 if (ret) {223 pr_err("MAC%u: band %u: failed to get chans info: %d\n",224 mac->macid, band, ret);225 return ret;226 }227 228 qtnf_band_init_rates(wiphy->bands[band]);229 230 return 0;231}232 233static int qtnf_mac_init_bands(struct qtnf_wmac *mac)234{235 struct wiphy *wiphy = priv_to_wiphy(mac);236 int ret = 0;237 238 if (mac->macinfo.bands_cap & QLINK_BAND_2GHZ) {239 ret = qtnf_mac_init_single_band(wiphy, mac, NL80211_BAND_2GHZ);240 if (ret)241 goto out;242 }243 244 if (mac->macinfo.bands_cap & QLINK_BAND_5GHZ) {245 ret = qtnf_mac_init_single_band(wiphy, mac, NL80211_BAND_5GHZ);246 if (ret)247 goto out;248 }249 250 if (mac->macinfo.bands_cap & QLINK_BAND_60GHZ)251 ret = qtnf_mac_init_single_band(wiphy, mac, NL80211_BAND_60GHZ);252 253out:254 return ret;255}256 257struct qtnf_vif *qtnf_mac_get_free_vif(struct qtnf_wmac *mac)258{259 struct qtnf_vif *vif;260 int i;261 262 for (i = 0; i < QTNF_MAX_INTF; i++) {263 vif = &mac->iflist[i];264 if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)265 return vif;266 }267 268 return NULL;269}270 271struct qtnf_vif *qtnf_mac_get_base_vif(struct qtnf_wmac *mac)272{273 struct qtnf_vif *vif;274 275 vif = &mac->iflist[QTNF_PRIMARY_VIF_IDX];276 277 if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)278 return NULL;279 280 return vif;281}282 283void qtnf_mac_iface_comb_free(struct qtnf_wmac *mac)284{285 struct ieee80211_iface_combination *comb;286 int i;287 288 if (mac->macinfo.if_comb) {289 for (i = 0; i < mac->macinfo.n_if_comb; i++) {290 comb = &mac->macinfo.if_comb[i];291 kfree(comb->limits);292 comb->limits = NULL;293 }294 295 kfree(mac->macinfo.if_comb);296 mac->macinfo.if_comb = NULL;297 }298}299 300void qtnf_mac_ext_caps_free(struct qtnf_wmac *mac)301{302 if (mac->macinfo.extended_capabilities_len) {303 kfree(mac->macinfo.extended_capabilities);304 mac->macinfo.extended_capabilities = NULL;305 306 kfree(mac->macinfo.extended_capabilities_mask);307 mac->macinfo.extended_capabilities_mask = NULL;308 309 mac->macinfo.extended_capabilities_len = 0;310 }311}312 313static void qtnf_vif_reset_handler(struct work_struct *work)314{315 struct qtnf_vif *vif = container_of(work, struct qtnf_vif, reset_work);316 317 rtnl_lock();318 319 if (vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED) {320 rtnl_unlock();321 return;322 }323 324 /* stop tx completely */325 netif_tx_stop_all_queues(vif->netdev);326 if (netif_carrier_ok(vif->netdev))327 netif_carrier_off(vif->netdev);328 329 qtnf_cfg80211_vif_reset(vif);330 331 rtnl_unlock();332}333 334static void qtnf_mac_init_primary_intf(struct qtnf_wmac *mac)335{336 struct qtnf_vif *vif = &mac->iflist[QTNF_PRIMARY_VIF_IDX];337 338 vif->wdev.iftype = NL80211_IFTYPE_STATION;339 vif->bss_priority = QTNF_DEF_BSS_PRIORITY;340 vif->wdev.wiphy = priv_to_wiphy(mac);341 INIT_WORK(&vif->reset_work, qtnf_vif_reset_handler);342 vif->cons_tx_timeout_cnt = 0;343}344 345static void qtnf_mac_scan_finish(struct qtnf_wmac *mac, bool aborted)346{347 struct cfg80211_scan_info info = {348 .aborted = aborted,349 };350 351 mutex_lock(&mac->mac_lock);352 353 if (mac->scan_req) {354 cfg80211_scan_done(mac->scan_req, &info);355 mac->scan_req = NULL;356 }357 358 mutex_unlock(&mac->mac_lock);359}360 361void qtnf_scan_done(struct qtnf_wmac *mac, bool aborted)362{363 cancel_delayed_work_sync(&mac->scan_timeout);364 qtnf_mac_scan_finish(mac, aborted);365}366 367static void qtnf_mac_scan_timeout(struct work_struct *work)368{369 struct qtnf_wmac *mac =370 container_of(work, struct qtnf_wmac, scan_timeout.work);371 372 pr_warn("MAC%d: scan timed out\n", mac->macid);373 qtnf_mac_scan_finish(mac, true);374}375 376static void qtnf_vif_send_data_high_pri(struct work_struct *work)377{378 struct qtnf_vif *vif =379 container_of(work, struct qtnf_vif, high_pri_tx_work);380 struct sk_buff *skb;381 382 if (!vif->netdev ||383 vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)384 return;385 386 while ((skb = skb_dequeue(&vif->high_pri_tx_queue))) {387 qtnf_cmd_send_frame(vif, 0, QLINK_FRAME_TX_FLAG_8023,388 0, skb->data, skb->len);389 dev_kfree_skb_any(skb);390 }391}392 393static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus,394 unsigned int macid)395{396 struct platform_device *pdev = NULL;397 struct qtnf_wmac *mac;398 struct qtnf_vif *vif;399 struct wiphy *wiphy;400 unsigned int i;401 402 if (bus->hw_info.num_mac > 1) {403 pdev = platform_device_register_data(bus->dev,404 dev_name(bus->dev),405 macid, NULL, 0);406 if (IS_ERR(pdev))407 return ERR_PTR(-EINVAL);408 }409 410 wiphy = qtnf_wiphy_allocate(bus, pdev);411 if (!wiphy) {412 if (pdev)413 platform_device_unregister(pdev);414 return ERR_PTR(-ENOMEM);415 }416 417 mac = wiphy_priv(wiphy);418 419 mac->macid = macid;420 mac->pdev = pdev;421 mac->bus = bus;422 mutex_init(&mac->mac_lock);423 INIT_DELAYED_WORK(&mac->scan_timeout, qtnf_mac_scan_timeout);424 425 for (i = 0; i < QTNF_MAX_INTF; i++) {426 vif = &mac->iflist[i];427 428 memset(vif, 0, sizeof(*vif));429 vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;430 vif->mac = mac;431 vif->vifid = i;432 qtnf_sta_list_init(&vif->sta_list);433 INIT_WORK(&vif->high_pri_tx_work, qtnf_vif_send_data_high_pri);434 skb_queue_head_init(&vif->high_pri_tx_queue);435 }436 437 qtnf_mac_init_primary_intf(mac);438 bus->mac[macid] = mac;439 440 return mac;441}442 443static const struct ethtool_ops qtnf_ethtool_ops = {444 .get_drvinfo = cfg80211_get_drvinfo,445};446 447int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *vif,448 const char *name, unsigned char name_assign_type)449{450 struct wiphy *wiphy = priv_to_wiphy(mac);451 struct net_device *dev;452 void *qdev_vif;453 int ret;454 455 dev = alloc_netdev_mqs(sizeof(struct qtnf_vif *), name,456 name_assign_type, ether_setup, 1, 1);457 if (!dev)458 return -ENOMEM;459 460 vif->netdev = dev;461 462 dev->netdev_ops = &qtnf_netdev_ops;463 dev->needs_free_netdev = true;464 dev_net_set(dev, wiphy_net(wiphy));465 dev->ieee80211_ptr = &vif->wdev;466 eth_hw_addr_set(dev, vif->mac_addr);467 dev->flags |= IFF_BROADCAST | IFF_MULTICAST;468 dev->watchdog_timeo = QTNF_DEF_WDOG_TIMEOUT;469 dev->tx_queue_len = 100;470 dev->ethtool_ops = &qtnf_ethtool_ops;471 dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;472 473 if (qtnf_hwcap_is_set(&mac->bus->hw_info, QLINK_HW_CAPAB_HW_BRIDGE))474 dev->needed_tailroom = sizeof(struct qtnf_frame_meta_info);475 476 qdev_vif = netdev_priv(dev);477 *((void **)qdev_vif) = vif;478 479 SET_NETDEV_DEV(dev, wiphy_dev(wiphy));480 481 ret = cfg80211_register_netdevice(dev);482 if (ret) {483 free_netdev(dev);484 vif->netdev = NULL;485 }486 487 return ret;488}489 490static void qtnf_core_mac_detach(struct qtnf_bus *bus, unsigned int macid)491{492 struct qtnf_wmac *mac;493 struct wiphy *wiphy;494 struct qtnf_vif *vif;495 unsigned int i;496 enum nl80211_band band;497 498 mac = bus->mac[macid];499 500 if (!mac)501 return;502 503 wiphy = priv_to_wiphy(mac);504 505 for (i = 0; i < QTNF_MAX_INTF; i++) {506 vif = &mac->iflist[i];507 rtnl_lock();508 if (vif->netdev &&509 vif->wdev.iftype != NL80211_IFTYPE_UNSPECIFIED) {510 qtnf_virtual_intf_cleanup(vif->netdev);511 qtnf_del_virtual_intf(wiphy, &vif->wdev);512 }513 rtnl_unlock();514 qtnf_sta_list_free(&vif->sta_list);515 }516 517 if (mac->wiphy_registered)518 wiphy_unregister(wiphy);519 520 for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; ++band) {521 if (!wiphy->bands[band])522 continue;523 524 kfree((__force void *)wiphy->bands[band]->iftype_data);525 wiphy->bands[band]->n_iftype_data = 0;526 527 kfree(wiphy->bands[band]->channels);528 wiphy->bands[band]->n_channels = 0;529 530 kfree(wiphy->bands[band]);531 wiphy->bands[band] = NULL;532 }533 534 platform_device_unregister(mac->pdev);535 qtnf_mac_iface_comb_free(mac);536 qtnf_mac_ext_caps_free(mac);537 kfree(mac->macinfo.wowlan);538 kfree(mac->rd);539 mac->rd = NULL;540 wiphy_free(wiphy);541 bus->mac[macid] = NULL;542}543 544static int qtnf_core_mac_attach(struct qtnf_bus *bus, unsigned int macid)545{546 struct qtnf_wmac *mac;547 struct qtnf_vif *vif;548 int ret;549 550 if (!(bus->hw_info.mac_bitmap & BIT(macid))) {551 pr_info("MAC%u is not active in FW\n", macid);552 return 0;553 }554 555 mac = qtnf_core_mac_alloc(bus, macid);556 if (IS_ERR(mac)) {557 pr_err("MAC%u allocation failed\n", macid);558 return PTR_ERR(mac);559 }560 561 vif = qtnf_mac_get_base_vif(mac);562 if (!vif) {563 pr_err("MAC%u: primary VIF is not ready\n", macid);564 ret = -EFAULT;565 goto error;566 }567 568 ret = qtnf_cmd_send_add_intf(vif, vif->wdev.iftype,569 vif->wdev.use_4addr, vif->mac_addr);570 if (ret) {571 pr_err("MAC%u: failed to add VIF\n", macid);572 goto error;573 }574 575 ret = qtnf_cmd_get_mac_info(mac);576 if (ret) {577 pr_err("MAC%u: failed to get MAC info\n", macid);578 goto error_del_vif;579 }580 581 /* Use MAC address of the first active radio as a unique device ID */582 if (is_zero_ether_addr(mac->bus->hw_id))583 ether_addr_copy(mac->bus->hw_id, mac->macaddr);584 585 ret = qtnf_mac_init_bands(mac);586 if (ret) {587 pr_err("MAC%u: failed to init bands\n", macid);588 goto error_del_vif;589 }590 591 ret = qtnf_wiphy_register(&bus->hw_info, mac);592 if (ret) {593 pr_err("MAC%u: wiphy registration failed\n", macid);594 goto error_del_vif;595 }596 597 mac->wiphy_registered = 1;598 599 rtnl_lock();600 wiphy_lock(priv_to_wiphy(mac));601 ret = qtnf_core_net_attach(mac, vif, "wlan%d", NET_NAME_ENUM);602 wiphy_unlock(priv_to_wiphy(mac));603 rtnl_unlock();604 605 if (ret) {606 pr_err("MAC%u: failed to attach netdev\n", macid);607 goto error_del_vif;608 }609 610 if (qtnf_hwcap_is_set(&bus->hw_info, QLINK_HW_CAPAB_HW_BRIDGE)) {611 ret = qtnf_cmd_netdev_changeupper(vif, vif->netdev->ifindex);612 if (ret)613 goto error;614 }615 616 pr_debug("MAC%u initialized\n", macid);617 618 return 0;619 620error_del_vif:621 qtnf_cmd_send_del_intf(vif);622 vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;623error:624 qtnf_core_mac_detach(bus, macid);625 return ret;626}627 628bool qtnf_netdev_is_qtn(const struct net_device *ndev)629{630 return ndev->netdev_ops == &qtnf_netdev_ops;631}632 633static int qtnf_check_br_ports(struct net_device *dev,634 struct netdev_nested_priv *priv)635{636 struct net_device *ndev = (struct net_device *)priv->data;637 638 if (dev != ndev && netdev_port_same_parent_id(dev, ndev))639 return -ENOTSUPP;640 641 return 0;642}643 644static int qtnf_core_netdevice_event(struct notifier_block *nb,645 unsigned long event, void *ptr)646{647 struct net_device *ndev = netdev_notifier_info_to_dev(ptr);648 const struct netdev_notifier_changeupper_info *info;649 struct netdev_nested_priv priv = {650 .data = (void *)ndev,651 };652 struct net_device *brdev;653 struct qtnf_vif *vif;654 struct qtnf_bus *bus;655 int br_domain;656 int ret = 0;657 658 if (!qtnf_netdev_is_qtn(ndev))659 return NOTIFY_DONE;660 661 if (!net_eq(dev_net(ndev), &init_net))662 return NOTIFY_OK;663 664 vif = qtnf_netdev_get_priv(ndev);665 bus = vif->mac->bus;666 667 switch (event) {668 case NETDEV_CHANGEUPPER:669 info = ptr;670 brdev = info->upper_dev;671 672 if (!netif_is_bridge_master(brdev))673 break;674 675 pr_debug("[VIF%u.%u] change bridge: %s %s\n",676 vif->mac->macid, vif->vifid, netdev_name(brdev),677 info->linking ? "add" : "del");678 679 if (IS_ENABLED(CONFIG_NET_SWITCHDEV) &&680 qtnf_hwcap_is_set(&bus->hw_info,681 QLINK_HW_CAPAB_HW_BRIDGE)) {682 if (info->linking)683 br_domain = brdev->ifindex;684 else685 br_domain = ndev->ifindex;686 687 ret = qtnf_cmd_netdev_changeupper(vif, br_domain);688 } else {689 ret = netdev_walk_all_lower_dev(brdev,690 qtnf_check_br_ports,691 &priv);692 }693 694 break;695 default:696 break;697 }698 699 return notifier_from_errno(ret);700}701 702int qtnf_core_attach(struct qtnf_bus *bus)703{704 unsigned int i;705 int ret;706 707 qtnf_trans_init(bus);708 qtnf_bus_data_rx_start(bus);709 710 bus->workqueue = alloc_ordered_workqueue("QTNF_BUS", 0);711 if (!bus->workqueue) {712 pr_err("failed to alloc main workqueue\n");713 ret = -ENOMEM;714 goto error;715 }716 717 bus->hprio_workqueue = alloc_workqueue("QTNF_HPRI", WQ_HIGHPRI, 0);718 if (!bus->hprio_workqueue) {719 pr_err("failed to alloc high prio workqueue\n");720 ret = -ENOMEM;721 goto error;722 }723 724 INIT_WORK(&bus->event_work, qtnf_event_work_handler);725 726 ret = qtnf_cmd_send_init_fw(bus);727 if (ret) {728 pr_err("failed to init FW: %d\n", ret);729 goto error;730 }731 732 if (QLINK_VER_MAJOR(bus->hw_info.ql_proto_ver) !=733 QLINK_PROTO_VER_MAJOR) {734 pr_err("qlink driver vs FW version mismatch: %u vs %u\n",735 QLINK_PROTO_VER_MAJOR,736 QLINK_VER_MAJOR(bus->hw_info.ql_proto_ver));737 ret = -EPROTONOSUPPORT;738 goto error;739 }740 741 bus->fw_state = QTNF_FW_STATE_ACTIVE;742 ret = qtnf_cmd_get_hw_info(bus);743 if (ret) {744 pr_err("failed to get HW info: %d\n", ret);745 goto error;746 }747 748 if (qtnf_hwcap_is_set(&bus->hw_info, QLINK_HW_CAPAB_HW_BRIDGE) &&749 bus->bus_ops->data_tx_use_meta_set)750 bus->bus_ops->data_tx_use_meta_set(bus, true);751 752 if (bus->hw_info.num_mac > QTNF_MAX_MAC) {753 pr_err("no support for number of MACs=%u\n",754 bus->hw_info.num_mac);755 ret = -ERANGE;756 goto error;757 }758 759 for (i = 0; i < bus->hw_info.num_mac; i++) {760 ret = qtnf_core_mac_attach(bus, i);761 762 if (ret) {763 pr_err("MAC%u: attach failed: %d\n", i, ret);764 goto error;765 }766 }767 768 bus->netdev_nb.notifier_call = qtnf_core_netdevice_event;769 ret = register_netdevice_notifier(&bus->netdev_nb);770 if (ret) {771 pr_err("failed to register netdev notifier: %d\n", ret);772 goto error;773 }774 775 bus->fw_state = QTNF_FW_STATE_RUNNING;776 return 0;777 778error:779 qtnf_core_detach(bus);780 return ret;781}782EXPORT_SYMBOL_GPL(qtnf_core_attach);783 784void qtnf_core_detach(struct qtnf_bus *bus)785{786 unsigned int macid;787 788 unregister_netdevice_notifier(&bus->netdev_nb);789 qtnf_bus_data_rx_stop(bus);790 791 for (macid = 0; macid < QTNF_MAX_MAC; macid++)792 qtnf_core_mac_detach(bus, macid);793 794 if (qtnf_fw_is_up(bus))795 qtnf_cmd_send_deinit_fw(bus);796 797 bus->fw_state = QTNF_FW_STATE_DETACHED;798 799 if (bus->workqueue) {800 destroy_workqueue(bus->workqueue);801 bus->workqueue = NULL;802 }803 804 if (bus->hprio_workqueue) {805 destroy_workqueue(bus->hprio_workqueue);806 bus->hprio_workqueue = NULL;807 }808 809 qtnf_trans_free(bus);810}811EXPORT_SYMBOL_GPL(qtnf_core_detach);812 813static inline int qtnf_is_frame_meta_magic_valid(struct qtnf_frame_meta_info *m)814{815 return m->magic_s == HBM_FRAME_META_MAGIC_PATTERN_S &&816 m->magic_e == HBM_FRAME_META_MAGIC_PATTERN_E;817}818 819struct net_device *qtnf_classify_skb(struct qtnf_bus *bus, struct sk_buff *skb)820{821 struct qtnf_frame_meta_info *meta;822 struct net_device *ndev = NULL;823 struct qtnf_wmac *mac;824 struct qtnf_vif *vif;825 826 if (unlikely(bus->fw_state != QTNF_FW_STATE_RUNNING))827 return NULL;828 829 meta = (struct qtnf_frame_meta_info *)830 (skb_tail_pointer(skb) - sizeof(*meta));831 832 if (unlikely(!qtnf_is_frame_meta_magic_valid(meta))) {833 pr_err_ratelimited("invalid magic 0x%x:0x%x\n",834 meta->magic_s, meta->magic_e);835 goto out;836 }837 838 if (unlikely(meta->macid >= QTNF_MAX_MAC)) {839 pr_err_ratelimited("invalid mac(%u)\n", meta->macid);840 goto out;841 }842 843 if (unlikely(meta->ifidx >= QTNF_MAX_INTF)) {844 pr_err_ratelimited("invalid vif(%u)\n", meta->ifidx);845 goto out;846 }847 848 mac = bus->mac[meta->macid];849 850 if (unlikely(!mac)) {851 pr_err_ratelimited("mac(%d) does not exist\n", meta->macid);852 goto out;853 }854 855 vif = &mac->iflist[meta->ifidx];856 857 if (unlikely(vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)) {858 pr_err_ratelimited("vif(%u) does not exists\n", meta->ifidx);859 goto out;860 }861 862 ndev = vif->netdev;863 864 if (unlikely(!ndev)) {865 pr_err_ratelimited("netdev for wlan%u.%u does not exists\n",866 meta->macid, meta->ifidx);867 goto out;868 }869 870 __skb_trim(skb, skb->len - sizeof(*meta));871 /* Firmware always handles packets that require flooding */872 qtnfmac_switch_mark_skb_flooded(skb);873 874out:875 return ndev;876}877EXPORT_SYMBOL_GPL(qtnf_classify_skb);878 879void qtnf_wake_all_queues(struct net_device *ndev)880{881 struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);882 struct qtnf_wmac *mac;883 struct qtnf_bus *bus;884 int macid;885 int i;886 887 if (unlikely(!vif || !vif->mac || !vif->mac->bus))888 return;889 890 bus = vif->mac->bus;891 892 for (macid = 0; macid < QTNF_MAX_MAC; macid++) {893 if (!(bus->hw_info.mac_bitmap & BIT(macid)))894 continue;895 896 mac = bus->mac[macid];897 for (i = 0; i < QTNF_MAX_INTF; i++) {898 vif = &mac->iflist[i];899 if (vif->netdev && netif_queue_stopped(vif->netdev))900 netif_tx_wake_all_queues(vif->netdev);901 }902 }903}904EXPORT_SYMBOL_GPL(qtnf_wake_all_queues);905 906struct dentry *qtnf_get_debugfs_dir(void)907{908 return qtnf_debugfs_dir;909}910EXPORT_SYMBOL_GPL(qtnf_get_debugfs_dir);911 912static int __init qtnf_core_register(void)913{914 qtnf_debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);915 916 if (IS_ERR(qtnf_debugfs_dir))917 qtnf_debugfs_dir = NULL;918 919 return 0;920}921 922static void __exit qtnf_core_exit(void)923{924 debugfs_remove(qtnf_debugfs_dir);925}926 927module_init(qtnf_core_register);928module_exit(qtnf_core_exit);929 930MODULE_AUTHOR("Quantenna Communications");931MODULE_DESCRIPTION("Quantenna 802.11 wireless LAN FullMAC driver.");932MODULE_LICENSE("GPL");933