hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/drivers/net/wireless/quantenna/qtnfmac/core.c
....@@ -1,22 +1,10 @@
1
-/*
2
- * Copyright (c) 2015-2016 Quantenna Communications, Inc.
3
- * All rights reserved.
4
- *
5
- * This program is free software; you can redistribute it and/or
6
- * modify it under the terms of the GNU General Public License
7
- * as published by the Free Software Foundation; either version 2
8
- * of the License, or (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- */
1
+// SPDX-License-Identifier: GPL-2.0+
2
+/* Copyright (c) 2015-2016 Quantenna Communications. All rights reserved. */
163
174 #include <linux/kernel.h>
185 #include <linux/module.h>
196 #include <linux/if_ether.h>
7
+#include <linux/nospec.h>
208
219 #include "core.h"
2210 #include "bus.h"
....@@ -25,26 +13,40 @@
2513 #include "cfg80211.h"
2614 #include "event.h"
2715 #include "util.h"
16
+#include "switchdev.h"
2817
29
-#define QTNF_DMP_MAX_LEN 48
3018 #define QTNF_PRIMARY_VIF_IDX 0
3119
32
-struct qtnf_frame_meta_info {
33
- u8 magic_s;
34
- u8 ifidx;
35
- u8 macid;
36
- u8 magic_e;
37
-} __packed;
20
+static bool slave_radar = true;
21
+module_param(slave_radar, bool, 0644);
22
+MODULE_PARM_DESC(slave_radar, "set 0 to disable radar detection in slave mode");
23
+
24
+static bool dfs_offload;
25
+module_param(dfs_offload, bool, 0644);
26
+MODULE_PARM_DESC(dfs_offload, "set 1 to enable DFS offload to firmware");
27
+
28
+static struct dentry *qtnf_debugfs_dir;
29
+
30
+bool qtnf_slave_radar_get(void)
31
+{
32
+ return slave_radar;
33
+}
34
+
35
+bool qtnf_dfs_offload_get(void)
36
+{
37
+ return dfs_offload;
38
+}
3839
3940 struct qtnf_wmac *qtnf_core_get_mac(const struct qtnf_bus *bus, u8 macid)
4041 {
4142 struct qtnf_wmac *mac = NULL;
4243
43
- if (unlikely(macid >= QTNF_MAX_MAC)) {
44
+ if (macid >= QTNF_MAX_MAC) {
4445 pr_err("invalid MAC index %u\n", macid);
4546 return NULL;
4647 }
4748
49
+ macid = array_index_nospec(macid, QTNF_MAX_MAC);
4850 mac = bus->mac[macid];
4951
5052 if (unlikely(!mac)) {
....@@ -72,6 +74,14 @@
7274 qtnf_virtual_intf_cleanup(ndev);
7375 qtnf_netdev_updown(ndev, 0);
7476 return 0;
77
+}
78
+
79
+static 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);
7585 }
7686
7787 /* Netdev handler for data transmission.
....@@ -114,7 +124,13 @@
114124 /* tx path is enabled: reset vif timeout */
115125 vif->cons_tx_timeout_cnt = 0;
116126
117
- return qtnf_bus_data_tx(mac->bus, skb);
127
+ if (unlikely(skb->protocol == htons(ETH_P_PAE))) {
128
+ qtnf_packet_send_hi_pri(skb);
129
+ qtnf_update_tx_stats(ndev, skb);
130
+ return NETDEV_TX_OK;
131
+ }
132
+
133
+ return qtnf_bus_data_tx(mac->bus, skb, mac->macid, vif->vifid);
118134 }
119135
120136 /* Netdev handler for getting stats.
....@@ -123,39 +139,18 @@
123139 struct rtnl_link_stats64 *stats)
124140 {
125141 struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
126
- unsigned int start;
127
- int cpu;
128142
129143 netdev_stats_to_stats64(stats, &ndev->stats);
130144
131145 if (!vif->stats64)
132146 return;
133147
134
- for_each_possible_cpu(cpu) {
135
- struct pcpu_sw_netstats *stats64;
136
- u64 rx_packets, rx_bytes;
137
- u64 tx_packets, tx_bytes;
138
-
139
- stats64 = per_cpu_ptr(vif->stats64, cpu);
140
-
141
- do {
142
- start = u64_stats_fetch_begin_irq(&stats64->syncp);
143
- rx_packets = stats64->rx_packets;
144
- rx_bytes = stats64->rx_bytes;
145
- tx_packets = stats64->tx_packets;
146
- tx_bytes = stats64->tx_bytes;
147
- } while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
148
-
149
- stats->rx_packets += rx_packets;
150
- stats->rx_bytes += rx_bytes;
151
- stats->tx_packets += tx_packets;
152
- stats->tx_bytes += tx_bytes;
153
- }
148
+ dev_fetch_sw_netstats(stats, vif->stats64);
154149 }
155150
156151 /* Netdev handler for transmission timeout.
157152 */
158
-static void qtnf_netdev_tx_timeout(struct net_device *ndev)
153
+static void qtnf_netdev_tx_timeout(struct net_device *ndev, unsigned int txqueue)
159154 {
160155 struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
161156 struct qtnf_wmac *mac;
....@@ -195,12 +190,25 @@
195190 qtnf_scan_done(vif->mac, true);
196191
197192 ret = qtnf_cmd_send_change_intf_type(vif, vif->wdev.iftype,
193
+ vif->wdev.use_4addr,
198194 sa->sa_data);
199195
200196 if (ret)
201197 memcpy(ndev->dev_addr, old_addr, ETH_ALEN);
202198
203199 return ret;
200
+}
201
+
202
+static int qtnf_netdev_port_parent_id(struct net_device *ndev,
203
+ struct netdev_phys_item_id *ppid)
204
+{
205
+ const struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev);
206
+ const struct qtnf_bus *bus = vif->mac->bus;
207
+
208
+ ppid->id_len = sizeof(bus->hw_id);
209
+ memcpy(&ppid->id, bus->hw_id, ppid->id_len);
210
+
211
+ return 0;
204212 }
205213
206214 /* Network device ops handlers */
....@@ -211,6 +219,7 @@
211219 .ndo_tx_timeout = qtnf_netdev_tx_timeout,
212220 .ndo_get_stats64 = qtnf_netdev_get_stats64,
213221 .ndo_set_mac_address = qtnf_netdev_set_mac_address,
222
+ .ndo_get_port_parent_id = qtnf_netdev_port_parent_id,
214223 };
215224
216225 static int qtnf_mac_init_single_band(struct wiphy *wiphy,
....@@ -380,33 +389,67 @@
380389 qtnf_mac_scan_finish(mac, true);
381390 }
382391
392
+static void qtnf_vif_send_data_high_pri(struct work_struct *work)
393
+{
394
+ struct qtnf_vif *vif =
395
+ container_of(work, struct qtnf_vif, high_pri_tx_work);
396
+ struct sk_buff *skb;
397
+
398
+ if (!vif->netdev ||
399
+ vif->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED)
400
+ return;
401
+
402
+ while ((skb = skb_dequeue(&vif->high_pri_tx_queue))) {
403
+ qtnf_cmd_send_frame(vif, 0, QLINK_FRAME_TX_FLAG_8023,
404
+ 0, skb->data, skb->len);
405
+ dev_kfree_skb_any(skb);
406
+ }
407
+}
408
+
383409 static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus,
384410 unsigned int macid)
385411 {
386
- struct wiphy *wiphy;
412
+ struct platform_device *pdev = NULL;
387413 struct qtnf_wmac *mac;
414
+ struct qtnf_vif *vif;
415
+ struct wiphy *wiphy;
388416 unsigned int i;
389417
390
- wiphy = qtnf_wiphy_allocate(bus);
391
- if (!wiphy)
418
+ if (bus->hw_info.num_mac > 1) {
419
+ pdev = platform_device_register_data(bus->dev,
420
+ dev_name(bus->dev),
421
+ macid, NULL, 0);
422
+ if (IS_ERR(pdev))
423
+ return ERR_PTR(-EINVAL);
424
+ }
425
+
426
+ wiphy = qtnf_wiphy_allocate(bus, pdev);
427
+ if (!wiphy) {
428
+ if (pdev)
429
+ platform_device_unregister(pdev);
392430 return ERR_PTR(-ENOMEM);
431
+ }
393432
394433 mac = wiphy_priv(wiphy);
395434
396435 mac->macid = macid;
436
+ mac->pdev = pdev;
397437 mac->bus = bus;
438
+ mutex_init(&mac->mac_lock);
439
+ INIT_DELAYED_WORK(&mac->scan_timeout, qtnf_mac_scan_timeout);
398440
399441 for (i = 0; i < QTNF_MAX_INTF; i++) {
400
- memset(&mac->iflist[i], 0, sizeof(struct qtnf_vif));
401
- mac->iflist[i].wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
402
- mac->iflist[i].mac = mac;
403
- mac->iflist[i].vifid = i;
404
- qtnf_sta_list_init(&mac->iflist[i].sta_list);
405
- mutex_init(&mac->mac_lock);
406
- INIT_DELAYED_WORK(&mac->scan_timeout, qtnf_mac_scan_timeout);
407
- mac->iflist[i].stats64 =
408
- netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
409
- if (!mac->iflist[i].stats64)
442
+ vif = &mac->iflist[i];
443
+
444
+ memset(vif, 0, sizeof(*vif));
445
+ vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
446
+ vif->mac = mac;
447
+ vif->vifid = i;
448
+ qtnf_sta_list_init(&vif->sta_list);
449
+ INIT_WORK(&vif->high_pri_tx_work, qtnf_vif_send_data_high_pri);
450
+ skb_queue_head_init(&vif->high_pri_tx_queue);
451
+ vif->stats64 = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
452
+ if (!vif->stats64)
410453 pr_warn("VIF%u.%u: per cpu stats allocation failed\n",
411454 macid, i);
412455 }
....@@ -431,10 +474,8 @@
431474
432475 dev = alloc_netdev_mqs(sizeof(struct qtnf_vif *), name,
433476 name_assign_type, ether_setup, 1, 1);
434
- if (!dev) {
435
- vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
477
+ if (!dev)
436478 return -ENOMEM;
437
- }
438479
439480 vif->netdev = dev;
440481
....@@ -443,21 +484,23 @@
443484 dev_net_set(dev, wiphy_net(wiphy));
444485 dev->ieee80211_ptr = &vif->wdev;
445486 ether_addr_copy(dev->dev_addr, vif->mac_addr);
446
- SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
447487 dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
448488 dev->watchdog_timeo = QTNF_DEF_WDOG_TIMEOUT;
449489 dev->tx_queue_len = 100;
450490 dev->ethtool_ops = &qtnf_ethtool_ops;
451491
492
+ if (qtnf_hwcap_is_set(&mac->bus->hw_info, QLINK_HW_CAPAB_HW_BRIDGE))
493
+ dev->needed_tailroom = sizeof(struct qtnf_frame_meta_info);
494
+
452495 qdev_vif = netdev_priv(dev);
453496 *((void **)qdev_vif) = vif;
454497
455
- SET_NETDEV_DEV(dev, mac->bus->dev);
498
+ SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
456499
457500 ret = register_netdevice(dev);
458501 if (ret) {
459502 free_netdev(dev);
460
- vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
503
+ vif->netdev = NULL;
461504 }
462505
463506 return ret;
....@@ -498,6 +541,9 @@
498541 if (!wiphy->bands[band])
499542 continue;
500543
544
+ kfree(wiphy->bands[band]->iftype_data);
545
+ wiphy->bands[band]->n_iftype_data = 0;
546
+
501547 kfree(wiphy->bands[band]->channels);
502548 wiphy->bands[band]->n_channels = 0;
503549
....@@ -505,9 +551,12 @@
505551 wiphy->bands[band] = NULL;
506552 }
507553
554
+ platform_device_unregister(mac->pdev);
508555 qtnf_mac_iface_comb_free(mac);
509556 qtnf_mac_ext_caps_free(mac);
510557 kfree(mac->macinfo.wowlan);
558
+ kfree(mac->rd);
559
+ mac->rd = NULL;
511560 wiphy_free(wiphy);
512561 bus->mac[macid] = NULL;
513562 }
....@@ -529,12 +578,6 @@
529578 return PTR_ERR(mac);
530579 }
531580
532
- ret = qtnf_cmd_get_mac_info(mac);
533
- if (ret) {
534
- pr_err("MAC%u: failed to get info\n", macid);
535
- goto error;
536
- }
537
-
538581 vif = qtnf_mac_get_base_vif(mac);
539582 if (!vif) {
540583 pr_err("MAC%u: primary VIF is not ready\n", macid);
....@@ -542,28 +585,33 @@
542585 goto error;
543586 }
544587
545
- ret = qtnf_cmd_send_add_intf(vif, vif->wdev.iftype, vif->mac_addr);
588
+ ret = qtnf_cmd_send_add_intf(vif, vif->wdev.iftype,
589
+ vif->wdev.use_4addr, vif->mac_addr);
546590 if (ret) {
547591 pr_err("MAC%u: failed to add VIF\n", macid);
548592 goto error;
549593 }
550594
551
- ret = qtnf_cmd_send_get_phy_params(mac);
595
+ ret = qtnf_cmd_get_mac_info(mac);
552596 if (ret) {
553
- pr_err("MAC%u: failed to get PHY settings\n", macid);
554
- goto error;
597
+ pr_err("MAC%u: failed to get MAC info\n", macid);
598
+ goto error_del_vif;
555599 }
600
+
601
+ /* Use MAC address of the first active radio as a unique device ID */
602
+ if (is_zero_ether_addr(mac->bus->hw_id))
603
+ ether_addr_copy(mac->bus->hw_id, mac->macaddr);
556604
557605 ret = qtnf_mac_init_bands(mac);
558606 if (ret) {
559607 pr_err("MAC%u: failed to init bands\n", macid);
560
- goto error;
608
+ goto error_del_vif;
561609 }
562610
563611 ret = qtnf_wiphy_register(&bus->hw_info, mac);
564612 if (ret) {
565613 pr_err("MAC%u: wiphy registration failed\n", macid);
566
- goto error;
614
+ goto error_del_vif;
567615 }
568616
569617 mac->wiphy_registered = 1;
....@@ -575,18 +623,99 @@
575623
576624 if (ret) {
577625 pr_err("MAC%u: failed to attach netdev\n", macid);
578
- vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
579
- vif->netdev = NULL;
580
- goto error;
626
+ goto error_del_vif;
627
+ }
628
+
629
+ if (qtnf_hwcap_is_set(&bus->hw_info, QLINK_HW_CAPAB_HW_BRIDGE)) {
630
+ ret = qtnf_cmd_netdev_changeupper(vif, vif->netdev->ifindex);
631
+ if (ret)
632
+ goto error;
581633 }
582634
583635 pr_debug("MAC%u initialized\n", macid);
584636
585637 return 0;
586638
639
+error_del_vif:
640
+ qtnf_cmd_send_del_intf(vif);
641
+ vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
587642 error:
588643 qtnf_core_mac_detach(bus, macid);
589644 return ret;
645
+}
646
+
647
+bool qtnf_netdev_is_qtn(const struct net_device *ndev)
648
+{
649
+ return ndev->netdev_ops == &qtnf_netdev_ops;
650
+}
651
+
652
+static int qtnf_check_br_ports(struct net_device *dev,
653
+ struct netdev_nested_priv *priv)
654
+{
655
+ struct net_device *ndev = (struct net_device *)priv->data;
656
+
657
+ if (dev != ndev && netdev_port_same_parent_id(dev, ndev))
658
+ return -ENOTSUPP;
659
+
660
+ return 0;
661
+}
662
+
663
+static int qtnf_core_netdevice_event(struct notifier_block *nb,
664
+ unsigned long event, void *ptr)
665
+{
666
+ struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
667
+ const struct netdev_notifier_changeupper_info *info;
668
+ struct netdev_nested_priv priv = {
669
+ .data = (void *)ndev,
670
+ };
671
+ struct net_device *brdev;
672
+ struct qtnf_vif *vif;
673
+ struct qtnf_bus *bus;
674
+ int br_domain;
675
+ int ret = 0;
676
+
677
+ if (!qtnf_netdev_is_qtn(ndev))
678
+ return NOTIFY_DONE;
679
+
680
+ if (!net_eq(dev_net(ndev), &init_net))
681
+ return NOTIFY_OK;
682
+
683
+ vif = qtnf_netdev_get_priv(ndev);
684
+ bus = vif->mac->bus;
685
+
686
+ switch (event) {
687
+ case NETDEV_CHANGEUPPER:
688
+ info = ptr;
689
+ brdev = info->upper_dev;
690
+
691
+ if (!netif_is_bridge_master(brdev))
692
+ break;
693
+
694
+ pr_debug("[VIF%u.%u] change bridge: %s %s\n",
695
+ vif->mac->macid, vif->vifid, netdev_name(brdev),
696
+ info->linking ? "add" : "del");
697
+
698
+ if (IS_ENABLED(CONFIG_NET_SWITCHDEV) &&
699
+ qtnf_hwcap_is_set(&bus->hw_info,
700
+ QLINK_HW_CAPAB_HW_BRIDGE)) {
701
+ if (info->linking)
702
+ br_domain = brdev->ifindex;
703
+ else
704
+ br_domain = ndev->ifindex;
705
+
706
+ ret = qtnf_cmd_netdev_changeupper(vif, br_domain);
707
+ } else {
708
+ ret = netdev_walk_all_lower_dev(brdev,
709
+ qtnf_check_br_ports,
710
+ &priv);
711
+ }
712
+
713
+ break;
714
+ default:
715
+ break;
716
+ }
717
+
718
+ return notifier_from_errno(ret);
590719 }
591720
592721 int qtnf_core_attach(struct qtnf_bus *bus)
....@@ -595,13 +724,18 @@
595724 int ret;
596725
597726 qtnf_trans_init(bus);
598
-
599
- bus->fw_state = QTNF_FW_STATE_BOOT_DONE;
600727 qtnf_bus_data_rx_start(bus);
601728
602729 bus->workqueue = alloc_ordered_workqueue("QTNF_BUS", 0);
603730 if (!bus->workqueue) {
604731 pr_err("failed to alloc main workqueue\n");
732
+ ret = -ENOMEM;
733
+ goto error;
734
+ }
735
+
736
+ bus->hprio_workqueue = alloc_workqueue("QTNF_HPRI", WQ_HIGHPRI, 0);
737
+ if (!bus->hprio_workqueue) {
738
+ pr_err("failed to alloc high prio workqueue\n");
605739 ret = -ENOMEM;
606740 goto error;
607741 }
....@@ -614,20 +748,25 @@
614748 goto error;
615749 }
616750
617
- bus->fw_state = QTNF_FW_STATE_ACTIVE;
751
+ if (QLINK_VER_MAJOR(bus->hw_info.ql_proto_ver) !=
752
+ QLINK_PROTO_VER_MAJOR) {
753
+ pr_err("qlink driver vs FW version mismatch: %u vs %u\n",
754
+ QLINK_PROTO_VER_MAJOR,
755
+ QLINK_VER_MAJOR(bus->hw_info.ql_proto_ver));
756
+ ret = -EPROTONOSUPPORT;
757
+ goto error;
758
+ }
618759
760
+ bus->fw_state = QTNF_FW_STATE_ACTIVE;
619761 ret = qtnf_cmd_get_hw_info(bus);
620762 if (ret) {
621763 pr_err("failed to get HW info: %d\n", ret);
622764 goto error;
623765 }
624766
625
- if (bus->hw_info.ql_proto_ver != QLINK_PROTO_VER) {
626
- pr_err("qlink version mismatch %u != %u\n",
627
- QLINK_PROTO_VER, bus->hw_info.ql_proto_ver);
628
- ret = -EPROTONOSUPPORT;
629
- goto error;
630
- }
767
+ if (qtnf_hwcap_is_set(&bus->hw_info, QLINK_HW_CAPAB_HW_BRIDGE) &&
768
+ bus->bus_ops->data_tx_use_meta_set)
769
+ bus->bus_ops->data_tx_use_meta_set(bus, true);
631770
632771 if (bus->hw_info.num_mac > QTNF_MAX_MAC) {
633772 pr_err("no support for number of MACs=%u\n",
....@@ -645,11 +784,18 @@
645784 }
646785 }
647786
787
+ bus->netdev_nb.notifier_call = qtnf_core_netdevice_event;
788
+ ret = register_netdevice_notifier(&bus->netdev_nb);
789
+ if (ret) {
790
+ pr_err("failed to register netdev notifier: %d\n", ret);
791
+ goto error;
792
+ }
793
+
794
+ bus->fw_state = QTNF_FW_STATE_RUNNING;
648795 return 0;
649796
650797 error:
651798 qtnf_core_detach(bus);
652
-
653799 return ret;
654800 }
655801 EXPORT_SYMBOL_GPL(qtnf_core_attach);
....@@ -658,12 +804,13 @@
658804 {
659805 unsigned int macid;
660806
807
+ unregister_netdevice_notifier(&bus->netdev_nb);
661808 qtnf_bus_data_rx_stop(bus);
662809
663810 for (macid = 0; macid < QTNF_MAX_MAC; macid++)
664811 qtnf_core_mac_detach(bus, macid);
665812
666
- if (bus->fw_state == QTNF_FW_STATE_ACTIVE)
813
+ if (qtnf_fw_is_up(bus))
667814 qtnf_cmd_send_deinit_fw(bus);
668815
669816 bus->fw_state = QTNF_FW_STATE_DETACHED;
....@@ -671,10 +818,14 @@
671818 if (bus->workqueue) {
672819 flush_workqueue(bus->workqueue);
673820 destroy_workqueue(bus->workqueue);
821
+ bus->workqueue = NULL;
674822 }
675823
676
- kfree(bus->hw_info.rd);
677
- bus->hw_info.rd = NULL;
824
+ if (bus->hprio_workqueue) {
825
+ flush_workqueue(bus->hprio_workqueue);
826
+ destroy_workqueue(bus->hprio_workqueue);
827
+ bus->hprio_workqueue = NULL;
828
+ }
678829
679830 qtnf_trans_free(bus);
680831 }
....@@ -682,7 +833,8 @@
682833
683834 static inline int qtnf_is_frame_meta_magic_valid(struct qtnf_frame_meta_info *m)
684835 {
685
- return m->magic_s == 0xAB && m->magic_e == 0xBA;
836
+ return m->magic_s == HBM_FRAME_META_MAGIC_PATTERN_S &&
837
+ m->magic_e == HBM_FRAME_META_MAGIC_PATTERN_E;
686838 }
687839
688840 struct net_device *qtnf_classify_skb(struct qtnf_bus *bus, struct sk_buff *skb)
....@@ -691,6 +843,9 @@
691843 struct net_device *ndev = NULL;
692844 struct qtnf_wmac *mac;
693845 struct qtnf_vif *vif;
846
+
847
+ if (unlikely(bus->fw_state != QTNF_FW_STATE_RUNNING))
848
+ return NULL;
694849
695850 meta = (struct qtnf_frame_meta_info *)
696851 (skb_tail_pointer(skb) - sizeof(*meta));
....@@ -734,6 +889,8 @@
734889 }
735890
736891 __skb_trim(skb, skb->len - sizeof(*meta));
892
+ /* Firmware always handles packets that require flooding */
893
+ qtnfmac_switch_mark_skb_flooded(skb);
737894
738895 out:
739896 return ndev;
....@@ -807,6 +964,30 @@
807964 }
808965 EXPORT_SYMBOL_GPL(qtnf_update_tx_stats);
809966
967
+struct dentry *qtnf_get_debugfs_dir(void)
968
+{
969
+ return qtnf_debugfs_dir;
970
+}
971
+EXPORT_SYMBOL_GPL(qtnf_get_debugfs_dir);
972
+
973
+static int __init qtnf_core_register(void)
974
+{
975
+ qtnf_debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
976
+
977
+ if (IS_ERR(qtnf_debugfs_dir))
978
+ qtnf_debugfs_dir = NULL;
979
+
980
+ return 0;
981
+}
982
+
983
+static void __exit qtnf_core_exit(void)
984
+{
985
+ debugfs_remove(qtnf_debugfs_dir);
986
+}
987
+
988
+module_init(qtnf_core_register);
989
+module_exit(qtnf_core_exit);
990
+
810991 MODULE_AUTHOR("Quantenna Communications");
811992 MODULE_DESCRIPTION("Quantenna 802.11 wireless LAN FullMAC driver.");
812993 MODULE_LICENSE("GPL");