|
@@ -1,415 +0,0 @@
|
|
-From fc0a9dd3c5f4e6a545b98239affd1d1e3f8c55ca Mon Sep 17 00:00:00 2001
|
|
|
|
-From: ACwifidude <[email protected]>
|
|
|
|
-Date: Fri, 30 Sep 2022 11:33:18 -0500
|
|
|
|
-Subject: [PATCH] ipq806x: NSS Hardware Offloading mac80211 support
|
|
|
|
-
|
|
|
|
----
|
|
|
|
- package/kernel/mac80211/Makefile | 22 +-
|
|
|
|
- .../subsys/999-mac80211-NSS-support.patch | 292 ++++++++++++++++++
|
|
|
|
- 2 files changed, 310 insertions(+), 4 deletions(-)
|
|
|
|
- create mode 100644 package/kernel/mac80211/patches/subsys/999-mac80211-NSS-support.patch
|
|
|
|
-
|
|
|
|
-diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile
|
|
|
|
-index 248b48c3c15..d1840c91758 100644
|
|
|
|
---- a/package/kernel/mac80211/Makefile
|
|
|
|
-+++ b/package/kernel/mac80211/Makefile
|
|
|
|
-@@ -78,6 +78,7 @@ config-$(CONFIG_PACKAGE_CFG80211_TESTMODE) += NL80211_TESTMODE
|
|
|
|
-
|
|
|
|
- config-$(call config_package,mac80211) += MAC80211
|
|
|
|
- config-$(CONFIG_PACKAGE_MAC80211_MESH) += MAC80211_MESH
|
|
|
|
-+config-$(CONFIG_PACKAGE_MAC80211_NSS_SUPPORT) += MAC80211_NSS_SUPPORT
|
|
|
|
-
|
|
|
|
- include ath.mk
|
|
|
|
- include broadcom.mk
|
|
|
|
-@@ -121,7 +122,7 @@ define KernelPackage/mac80211
|
|
|
|
- $(call KernelPackage/mac80211/Default)
|
|
|
|
- TITLE:=Linux 802.11 Wireless Networking Stack
|
|
|
|
- # +kmod-crypto-cmac is a runtime only dependency of net/mac80211/aes_cmac.c
|
|
|
|
-- DEPENDS+= +kmod-cfg80211 +kmod-crypto-cmac +kmod-crypto-ccm +kmod-crypto-gcm +hostapd-common
|
|
|
|
-+ DEPENDS+= +kmod-cfg80211 +kmod-crypto-cmac +kmod-crypto-ccm +kmod-crypto-gcm +hostapd-common +PACKAGE_kmod-qca-nss-drv:kmod-qca-nss-drv
|
|
|
|
- KCONFIG:=\
|
|
|
|
- CONFIG_AVERAGE=y
|
|
|
|
- FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko
|
|
|
|
-@@ -132,6 +133,16 @@ endef
|
|
|
|
- define KernelPackage/mac80211/config
|
|
|
|
- if PACKAGE_kmod-mac80211
|
|
|
|
-
|
|
|
|
-+ if PACKAGE_kmod-qca-nss-drv
|
|
|
|
-+ config PACKAGE_MAC80211_NSS_SUPPORT
|
|
|
|
-+ bool "Enable NSS support for IPQ platform"
|
|
|
|
-+ default y
|
|
|
|
-+ help
|
|
|
|
-+ This option enables support for NSS in boards
|
|
|
|
-+ like Netgear R7800.
|
|
|
|
-+ endif
|
|
|
|
-+
|
|
|
|
-+
|
|
|
|
- config PACKAGE_MAC80211_DEBUGFS
|
|
|
|
- bool "Export mac80211 internals in DebugFS"
|
|
|
|
- select KERNEL_DEBUG_FS
|
|
|
|
-@@ -273,9 +284,12 @@ ifeq ($(BUILD_VARIANT),smallbuffers)
|
|
|
|
- C_DEFINES+= -DCONFIG_ATH10K_SMALLBUFFERS
|
|
|
|
- endif
|
|
|
|
-
|
|
|
|
--MAKE_OPTS:= \
|
|
|
|
-- $(subst -C $(LINUX_DIR),-C "$(PKG_BUILD_DIR)",$(KERNEL_MAKEOPTS)) \
|
|
|
|
-- EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS) $(C_DEFINES)" \
|
|
|
|
-+C_DEFINES+= -DSTANDALONE_CT
|
|
|
|
-+
|
|
|
|
-+MAKE_OPTS:= -C "$(PKG_BUILD_DIR)" \
|
|
|
|
-+ $(KERNEL_MAKE_FLAGS) \
|
|
|
|
-+ EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS) $(C_DEFINES) \
|
|
|
|
-+ -I$(STAGING_DIR)/usr/include/qca-nss-drv" \
|
|
|
|
- KLIB_BUILD="$(LINUX_DIR)" \
|
|
|
|
- MODPROBE=true \
|
|
|
|
- KLIB=$(TARGET_MODULES_DIR) \
|
|
|
|
-diff --git a/package/kernel/mac80211/patches/subsys/999-mac80211-NSS-support.patch b/package/kernel/mac80211/patches/subsys/999-mac80211-NSS-support.patch
|
|
|
|
-new file mode 100644
|
|
|
|
-index 00000000000..a0c1720c71a
|
|
|
|
---- /dev/null
|
|
|
|
-+++ b/package/kernel/mac80211/patches/subsys/999-mac80211-NSS-support.patch
|
|
|
|
-@@ -0,0 +1,344 @@
|
|
|
|
-+--- a/net/mac80211/Kconfig
|
|
|
|
-++++ b/net/mac80211/Kconfig
|
|
|
|
-+@@ -19,6 +19,13 @@ comment "CFG80211 needs to be enabled fo
|
|
|
|
-+
|
|
|
|
-+ if MAC80211 != n
|
|
|
|
-+
|
|
|
|
-++config MAC80211_NSS_SUPPORT
|
|
|
|
-++ bool "Enable NSS support for IPQ platform"
|
|
|
|
-++ default n
|
|
|
|
-++ ---help---
|
|
|
|
-++ This option enables support for NSS in boards
|
|
|
|
-++ like AP148.
|
|
|
|
-++
|
|
|
|
-+ config MAC80211_HAS_RC
|
|
|
|
-+ bool
|
|
|
|
-+
|
|
|
|
-+--- a/local-symbols
|
|
|
|
-++++ b/local-symbols
|
|
|
|
-+@@ -39,6 +39,7 @@ LIB80211_CRYPT_CCMP=
|
|
|
|
-+ LIB80211_CRYPT_TKIP=
|
|
|
|
-+ LIB80211_DEBUG=
|
|
|
|
-+ MAC80211=
|
|
|
|
-++MAC80211_NSS_SUPPORT=
|
|
|
|
-+ MAC80211_HAS_RC=
|
|
|
|
-+ MAC80211_RC_MINSTREL=
|
|
|
|
-+ MAC80211_RC_DEFAULT_MINSTREL=
|
|
|
|
-+--- a/net/mac80211/ieee80211_i.h
|
|
|
|
-++++ b/net/mac80211/ieee80211_i.h
|
|
|
|
-+@@ -36,6 +36,10 @@
|
|
|
|
-+
|
|
|
|
-+ extern const struct cfg80211_ops mac80211_config_ops;
|
|
|
|
-+
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++#include <nss_api_if.h>
|
|
|
|
-++#endif
|
|
|
|
-++
|
|
|
|
-+ struct ieee80211_local;
|
|
|
|
-+
|
|
|
|
-+ /* Maximum number of broadcast/multicast frames to buffer when some of the
|
|
|
|
-+@@ -1097,6 +1101,12 @@ struct ieee80211_sub_if_data {
|
|
|
|
-+ } debugfs;
|
|
|
|
-+ #endif
|
|
|
|
-+
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++ struct nss_virt_if_handle *nssctx;
|
|
|
|
-++ struct sk_buff_head rx_queue;
|
|
|
|
-++ struct work_struct rx_work;
|
|
|
|
-++#endif
|
|
|
|
-++
|
|
|
|
-+ /* must be last, dynamically sized area in this! */
|
|
|
|
-+ struct ieee80211_vif vif;
|
|
|
|
-+ };
|
|
|
|
-+--- a/net/mac80211/iface.c
|
|
|
|
-++++ b/net/mac80211/iface.c
|
|
|
|
-+@@ -15,6 +15,7 @@
|
|
|
|
-+ #include <linux/if_arp.h>
|
|
|
|
-+ #include <linux/netdevice.h>
|
|
|
|
-+ #include <linux/rtnetlink.h>
|
|
|
|
-++#include <linux/module.h>
|
|
|
|
-+ #include <linux/kcov.h>
|
|
|
|
-+ #include <net/mac80211.h>
|
|
|
|
-+ #include <net/ieee80211_radiotap.h>
|
|
|
|
-+@@ -27,6 +28,12 @@
|
|
|
|
-+ #include "wme.h"
|
|
|
|
-+ #include "rate.h"
|
|
|
|
-+
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++bool nss_redirect = true;
|
|
|
|
-++module_param(nss_redirect, bool, 0644);
|
|
|
|
-++MODULE_PARM_DESC(nss_redirect, "module param to enable NSS Redirect; 1-enable, 0-disable");
|
|
|
|
-++#endif
|
|
|
|
-++
|
|
|
|
-+ /**
|
|
|
|
-+ * DOC: Interface list locking
|
|
|
|
-+ *
|
|
|
|
-+@@ -439,6 +446,64 @@ static int ieee80211_open(struct net_dev
|
|
|
|
-+ return err;
|
|
|
|
-+ }
|
|
|
|
-+
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++/* This callback is registered for nss redirect to receive packet exceptioned from nss in Rx path.
|
|
|
|
-++ * When packet does not match any of the ecm rules is redirected back here.
|
|
|
|
-++ */
|
|
|
|
-++void receive_from_nss(struct net_device *dev, struct sk_buff *sk_buff, struct napi_struct *napi)
|
|
|
|
-++{
|
|
|
|
-++ struct net_device *netdev;
|
|
|
|
-++ struct sk_buff *skb;
|
|
|
|
-++ struct ieee80211_sub_if_data *sdata;
|
|
|
|
-++
|
|
|
|
-++ if (!dev) {
|
|
|
|
-++ kfree(sk_buff);
|
|
|
|
-++ return;
|
|
|
|
-++ }
|
|
|
|
-++
|
|
|
|
-++ netdev = (struct net_device *)dev;
|
|
|
|
-++ sdata = netdev_priv(netdev);
|
|
|
|
-++ if (sdata->dev != dev) {
|
|
|
|
-++ kfree(sk_buff);
|
|
|
|
-++ return;
|
|
|
|
-++ }
|
|
|
|
-++ skb = (struct sk_buff *)sk_buff;
|
|
|
|
-++ skb->dev = netdev;
|
|
|
|
-++ skb->protocol = eth_type_trans(skb, netdev);
|
|
|
|
-++ napi_gro_receive(napi, skb);
|
|
|
|
-++}
|
|
|
|
-++
|
|
|
|
-++static int ieee80211_create_nss_virtif(struct ieee80211_sub_if_data *sdata, struct net_device *dev)
|
|
|
|
-++{
|
|
|
|
-++ if (sdata->nssctx != NULL) {
|
|
|
|
-++ sdata_err(sdata, "Cannot create a NSS virtual interface. Already exists[n2h:%d, h2n:%d]!\n",
|
|
|
|
-++ sdata->nssctx->if_num_n2h, sdata->nssctx->if_num_h2n);
|
|
|
|
-++ return 1;
|
|
|
|
-++ }
|
|
|
|
-++
|
|
|
|
-++ sdata->nssctx = NULL;
|
|
|
|
-++ if (nss_redirect) {
|
|
|
|
-++ sdata->nssctx = nss_virt_if_create_sync(dev);
|
|
|
|
-++ if (sdata->nssctx) {
|
|
|
|
-++ sdata_info(sdata, "Created a NSS virtual interface\n");
|
|
|
|
-++ nss_virt_if_register(sdata->nssctx, receive_from_nss, sdata->dev);
|
|
|
|
-++ }
|
|
|
|
-++ else
|
|
|
|
-++ sdata_err(sdata, "Failed to create a NSS virtual interface\n");
|
|
|
|
-++ }
|
|
|
|
-++
|
|
|
|
-++ return 0;
|
|
|
|
-++}
|
|
|
|
-++
|
|
|
|
-++static void ieee80211_destroy_nss_virtif(struct ieee80211_sub_if_data *sdata)
|
|
|
|
-++{
|
|
|
|
-++ if (sdata->nssctx) {
|
|
|
|
-++ nss_virt_if_destroy_sync(sdata->nssctx);
|
|
|
|
-++ sdata_info(sdata, "Destroyed NSS virtual interface\n");
|
|
|
|
-++ }
|
|
|
|
-++}
|
|
|
|
-++#endif
|
|
|
|
-++
|
|
|
|
-+ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_down)
|
|
|
|
-+ {
|
|
|
|
-+ struct ieee80211_local *local = sdata->local;
|
|
|
|
-+@@ -800,8 +865,24 @@ static void ieee80211_teardown_sdata(str
|
|
|
|
-+ ieee80211_link_stop(&sdata->deflink);
|
|
|
|
-+ }
|
|
|
|
-+
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++static int ieee80211_init(struct net_device *dev)
|
|
|
|
-++{
|
|
|
|
-++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
|
|
|
-++
|
|
|
|
-++ ieee80211_create_nss_virtif(sdata, dev);
|
|
|
|
-++
|
|
|
|
-++ return 0;
|
|
|
|
-++}
|
|
|
|
-++#endif
|
|
|
|
-++
|
|
|
|
-+ static void ieee80211_uninit(struct net_device *dev)
|
|
|
|
-+ {
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
|
|
|
-++
|
|
|
|
-++ ieee80211_destroy_nss_virtif(sdata);
|
|
|
|
-++#endif
|
|
|
|
-+ ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev));
|
|
|
|
-+ }
|
|
|
|
-+
|
|
|
|
-+@@ -814,6 +895,9 @@ ieee80211_get_stats64(struct net_device
|
|
|
|
-+ static const struct net_device_ops ieee80211_dataif_ops = {
|
|
|
|
-+ .ndo_open = ieee80211_open,
|
|
|
|
-+ .ndo_stop = ieee80211_stop,
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++ .ndo_init = ieee80211_init,
|
|
|
|
-++#endif
|
|
|
|
-+ .ndo_uninit = ieee80211_uninit,
|
|
|
|
-+ .ndo_start_xmit = ieee80211_subif_start_xmit,
|
|
|
|
-+ .ndo_set_rx_mode = ieee80211_set_multicast_list,
|
|
|
|
-+--- a/net/mac80211/rx.c
|
|
|
|
-++++ b/net/mac80211/rx.c
|
|
|
|
-+@@ -33,6 +33,60 @@
|
|
|
|
-+ #include "wme.h"
|
|
|
|
-+ #include "rate.h"
|
|
|
|
-+
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++extern bool nss_redirect;
|
|
|
|
-++
|
|
|
|
-++#define case_rtn_string(val) case val: return #val
|
|
|
|
-++
|
|
|
|
-++static const char *nss_tx_status_str(nss_tx_status_t status)
|
|
|
|
-++{
|
|
|
|
-++ switch (status) {
|
|
|
|
-++ case_rtn_string(NSS_TX_SUCCESS);
|
|
|
|
-++ case_rtn_string(NSS_TX_FAILURE);
|
|
|
|
-++ case_rtn_string(NSS_TX_FAILURE_QUEUE);
|
|
|
|
-++ case_rtn_string(NSS_TX_FAILURE_NOT_READY);
|
|
|
|
-++ case_rtn_string(NSS_TX_FAILURE_TOO_LARGE);
|
|
|
|
-++ case_rtn_string(NSS_TX_FAILURE_TOO_SHORT);
|
|
|
|
-++ case_rtn_string(NSS_TX_FAILURE_NOT_SUPPORTED);
|
|
|
|
-++ case_rtn_string(NSS_TX_FAILURE_BAD_PARAM);
|
|
|
|
-++ case_rtn_string(NSS_TX_FAILURE_NOT_ENABLED);
|
|
|
|
-++ case_rtn_string(NSS_TX_FAILURE_SYNC_BAD_PARAM);
|
|
|
|
-++ case_rtn_string(NSS_TX_FAILURE_SYNC_TIMEOUT);
|
|
|
|
-++ case_rtn_string(NSS_TX_FAILURE_SYNC_FW_ERR);
|
|
|
|
-++ default:
|
|
|
|
-++ return "Unknown NSS TX status";
|
|
|
|
-++ }
|
|
|
|
-++}
|
|
|
|
-++
|
|
|
|
-++static void netif_rx_nss(struct ieee80211_rx_data *rx,
|
|
|
|
-++ struct sk_buff *skb)
|
|
|
|
-++{
|
|
|
|
-++ struct ieee80211_sub_if_data *sdata = rx->sdata;
|
|
|
|
-++ int ret;
|
|
|
|
-++
|
|
|
|
-++ if (!sdata->nssctx)
|
|
|
|
-++ goto out;
|
|
|
|
-++
|
|
|
|
-++ /* NSS expects ethernet header in skb data so resetting here */
|
|
|
|
-++ skb_push(skb, ETH_HLEN);
|
|
|
|
-++ ret = nss_virt_if_tx_buf(sdata->nssctx, skb);
|
|
|
|
-++ if (ret) {
|
|
|
|
-++ if (net_ratelimit()) {
|
|
|
|
-++ sdata_err(sdata, "NSS TX failed with error: %s\n",
|
|
|
|
-++ nss_tx_status_str(ret));
|
|
|
|
-++ }
|
|
|
|
-++ goto out;
|
|
|
|
-++ }
|
|
|
|
-++
|
|
|
|
-++ return;
|
|
|
|
-++out:
|
|
|
|
-++ if (rx->list)
|
|
|
|
-++ list_add_tail(&skb->list, rx->list);
|
|
|
|
-++ else
|
|
|
|
-++ netif_receive_skb(skb);
|
|
|
|
-++}
|
|
|
|
-++#endif
|
|
|
|
-++
|
|
|
|
-+ /*
|
|
|
|
-+ * monitor mode reception
|
|
|
|
-+ *
|
|
|
|
-+@@ -2635,10 +2689,16 @@ static void ieee80211_deliver_skb_to_loc
|
|
|
|
-+ ether_addr_copy(ehdr->h_dest, sdata->vif.addr);
|
|
|
|
-+
|
|
|
|
-+ /* deliver to local stack */
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++ if (likely(nss_redirect)) {
|
|
|
|
-++ netif_rx_nss(rx, skb);
|
|
|
|
-++ }
|
|
|
|
-++#else
|
|
|
|
-+ if (rx->list)
|
|
|
|
-+ list_add_tail(&skb->list, rx->list);
|
|
|
|
-+ else
|
|
|
|
-+ netif_receive_skb(skb);
|
|
|
|
-++#endif
|
|
|
|
-+ }
|
|
|
|
-+ }
|
|
|
|
-+
|
|
|
|
-+--- a/net/mac80211/tx.c
|
|
|
|
-++++ b/net/mac80211/tx.c
|
|
|
|
-+@@ -36,6 +36,11 @@
|
|
|
|
-+ #include "wme.h"
|
|
|
|
-+ #include "rate.h"
|
|
|
|
-+
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++#include <net/ip.h>
|
|
|
|
-++#include <net/dsfield.h>
|
|
|
|
-++#endif
|
|
|
|
-++
|
|
|
|
-+ /* misc utils */
|
|
|
|
-+
|
|
|
|
-+ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
|
|
|
|
-+@@ -1729,6 +1734,16 @@ static bool ieee80211_tx_frags(struct ie
|
|
|
|
-+ return true;
|
|
|
|
-+ }
|
|
|
|
-+ } else {
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++ if (skb_queue_len(&local->pending[q]) >= 1000) {
|
|
|
|
-++ spin_unlock_irqrestore(
|
|
|
|
-++ &local->queue_stop_reason_lock,
|
|
|
|
-++ flags);
|
|
|
|
-++ ieee80211_purge_tx_queue(&local->hw,
|
|
|
|
-++ skbs);
|
|
|
|
-++ return false;
|
|
|
|
-++ }
|
|
|
|
-++#endif
|
|
|
|
-+
|
|
|
|
-+ /*
|
|
|
|
-+ * Since queue is stopped, queue up frames for
|
|
|
|
-+@@ -4448,6 +4463,35 @@ static void ieee80211_mlo_multicast_tx(s
|
|
|
|
-+ kfree_skb(skb);
|
|
|
|
-+ }
|
|
|
|
-+
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++void ieee80211_xmit_nss_fixup(struct sk_buff *skb,
|
|
|
|
-++ struct net_device *dev)
|
|
|
|
-++{
|
|
|
|
-++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
|
|
|
-++
|
|
|
|
-++ /* Packets from NSS does not have valid protocol, priority and other
|
|
|
|
-++ * network stack values. Derive required parameters (priority
|
|
|
|
-++ * and network_header) from payload for QoS header.
|
|
|
|
-++ * XXX: Here the assumption is that packet are in 802.3 format.
|
|
|
|
-++ * As of now priority is handled only for IPv4 and IPv6.
|
|
|
|
-++ */
|
|
|
|
-++
|
|
|
|
-++ if (sdata->nssctx && likely(!skb->protocol)) {
|
|
|
|
-++ skb_set_network_header(skb, 14);
|
|
|
|
-++ switch (((struct ethhdr *)skb->data)->h_proto) {
|
|
|
|
-++ case htons(ETH_P_IP):
|
|
|
|
-++ skb->priority = (ipv4_get_dsfield(ip_hdr(skb)) &
|
|
|
|
-++ 0xfc) >> 5;
|
|
|
|
-++ break;
|
|
|
|
-++ case htons(ETH_P_IPV6):
|
|
|
|
-++ skb->priority = (ipv6_get_dsfield(ipv6_hdr(skb)) &
|
|
|
|
-++ 0xfc) >> 5;
|
|
|
|
-++ break;
|
|
|
|
-++ }
|
|
|
|
-++ }
|
|
|
|
-++}
|
|
|
|
-++#endif
|
|
|
|
-++
|
|
|
|
-+ /**
|
|
|
|
-+ * ieee80211_subif_start_xmit - netif start_xmit function for 802.3 vifs
|
|
|
|
-+ * @skb: packet to be sent
|
|
|
|
-+@@ -4461,6 +4505,10 @@ netdev_tx_t ieee80211_subif_start_xmit(s
|
|
|
|
-+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
|
|
|
-+ const struct ethhdr *eth = (void *)skb->data;
|
|
|
|
-+
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++ ieee80211_xmit_nss_fixup(skb, dev);
|
|
|
|
-++#endif
|
|
|
|
-++
|
|
|
|
-+ if (likely(!is_multicast_ether_addr(eth->h_dest)))
|
|
|
|
-+ goto normal;
|
|
|
|
-+
|
|
|
|
-+@@ -4646,6 +4694,10 @@ netdev_tx_t ieee80211_subif_start_xmit_8
|
|
|
|
-+ struct ieee80211_key *key;
|
|
|
|
-+ struct sta_info *sta;
|
|
|
|
-+
|
|
|
|
-++#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
|
|
-++ ieee80211_xmit_nss_fixup(skb, dev);
|
|
|
|
-++#endif
|
|
|
|
-++
|
|
|
|
-+ if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) {
|
|
|
|
-+ kfree_skb(skb);
|
|
|
|
-+ return NETDEV_TX_OK;
|
|
|