root/drivers/net/wireless/quantenna/qtnfmac/core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qtnf_core_get_mac
  2. qtnf_netdev_open
  3. qtnf_netdev_close
  4. qtnf_netdev_hard_start_xmit
  5. qtnf_netdev_get_stats64
  6. qtnf_netdev_tx_timeout
  7. qtnf_netdev_set_mac_address
  8. qtnf_mac_init_single_band
  9. qtnf_mac_init_bands
  10. qtnf_mac_get_free_vif
  11. qtnf_mac_get_base_vif
  12. qtnf_mac_iface_comb_free
  13. qtnf_mac_ext_caps_free
  14. qtnf_vif_reset_handler
  15. qtnf_mac_init_primary_intf
  16. qtnf_mac_scan_finish
  17. qtnf_scan_done
  18. qtnf_mac_scan_timeout
  19. qtnf_vif_send_data_high_pri
  20. qtnf_core_mac_alloc
  21. qtnf_mac_slave_radar_get
  22. qtnf_core_net_attach
  23. qtnf_core_mac_detach
  24. qtnf_core_mac_attach
  25. qtnf_core_attach
  26. qtnf_core_detach
  27. qtnf_is_frame_meta_magic_valid
  28. qtnf_classify_skb
  29. qtnf_wake_all_queues
  30. qtnf_update_rx_stats
  31. qtnf_update_tx_stats
  32. qtnf_packet_send_hi_pri
  33. qtnf_get_debugfs_dir
  34. qtnf_core_register
  35. qtnf_core_exit

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

/* [<][>][^][v][top][bottom][index][help] */