mac80211: add tasklet_kill step during NSS interface take down
This commit is contained in:
parent
800501b488
commit
4790aa244b
@ -37,12 +37,16 @@
|
|||||||
struct ieee80211_local;
|
struct ieee80211_local;
|
||||||
|
|
||||||
/* Maximum number of broadcast/multicast frames to buffer when some of the
|
/* Maximum number of broadcast/multicast frames to buffer when some of the
|
||||||
@@ -988,6 +992,10 @@ struct ieee80211_sub_if_data {
|
@@ -988,6 +992,14 @@ struct ieee80211_sub_if_data {
|
||||||
|
|
||||||
bool hw_80211_encap;
|
bool hw_80211_encap;
|
||||||
|
|
||||||
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
||||||
+ struct nss_virt_if_handle *nssctx;
|
+ struct nss_virt_if_handle *nssctx;
|
||||||
|
+
|
||||||
|
+ struct tasklet_struct ieee80211_nss_rq_tasklet;
|
||||||
|
+ struct sk_buff_head rq_for_nss;
|
||||||
|
+ int nss_rq_tasklet_pending;
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
/* must be last, dynamically sized area in this! */
|
/* must be last, dynamically sized area in this! */
|
||||||
@ -71,58 +75,11 @@
|
|||||||
/**
|
/**
|
||||||
* DOC: Interface list locking
|
* DOC: Interface list locking
|
||||||
*
|
*
|
||||||
@@ -645,6 +652,13 @@
|
@@ -695,6 +702,96 @@
|
||||||
{
|
ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev));
|
||||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
|
||||||
|
|
||||||
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
||||||
+ if (sdata->nssctx) {
|
|
||||||
+ nss_virt_if_destroy_sync(sdata->nssctx);
|
|
||||||
+ sdata_info(sdata, "Destroyed NSS virtual interface\n");
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
ieee80211_do_stop(sdata, true);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
@@ -1343,6 +1357,18 @@
|
|
||||||
|
|
||||||
ieee80211_recalc_ps(local);
|
|
||||||
|
|
||||||
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
||||||
+ if (is_nss_enable) {
|
|
||||||
+ sdata->nssctx = nss_virt_if_create_sync(dev);
|
|
||||||
+ if (sdata->nssctx)
|
|
||||||
+ sdata_info(sdata, "Created a NSS virtual interface\n");
|
|
||||||
+ else
|
|
||||||
+ sdata_err(sdata, "Failed to create a NSS virtual interface\n");
|
|
||||||
+ } else {
|
|
||||||
+ sdata->nssctx = NULL;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
|
|
||||||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
|
|
||||||
local->ops->wake_tx_queue) {
|
|
||||||
--- a/net/mac80211/rx.c 2019-01-03 21:09:29.503001000 +0800
|
|
||||||
+++ b/net/mac80211/rx.c 2019-01-03 21:17:42.463001000 +0800
|
|
||||||
@@ -32,6 +32,10 @@
|
|
||||||
#include "wme.h"
|
|
||||||
#include "rate.h"
|
|
||||||
|
|
||||||
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
|
||||||
+extern bool is_nss_enable;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
static inline void ieee80211_rx_stats(struct net_device *dev, u32 len)
|
|
||||||
{
|
|
||||||
struct pcpu_sw_netstats *tstats = this_cpu_ptr(netdev_tstats(dev));
|
|
||||||
@@ -42,6 +46,63 @@
|
|
||||||
u64_stats_update_end(&tstats->syncp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
||||||
+
|
|
||||||
+#define case_rtn_string(val) case val: return #val
|
+#define case_rtn_string(val) case val: return #val
|
||||||
+
|
+
|
||||||
+static const char *nss_tx_status_str(nss_tx_status_t status)
|
+static const char *nss_tx_status_str(nss_tx_status_t status)
|
||||||
@ -145,52 +102,117 @@
|
|||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void netif_rx_nss(struct ieee80211_sub_if_data *sdata,
|
+static void ieee80211_nss_rq_tasklet(unsigned long _txp)
|
||||||
+ struct sk_buff *skb)
|
|
||||||
+{
|
+{
|
||||||
|
+ struct ieee80211_sub_if_data *sdata = (struct ieee80211_sub_if_data *)_txp;
|
||||||
|
+ struct sk_buff *skb;
|
||||||
+ int ret;
|
+ int ret;
|
||||||
+ int push_mac_header = 0;
|
|
||||||
+
|
+
|
||||||
+ if (!sdata->nssctx)
|
+ while ((skb = __skb_dequeue(&sdata->rq_for_nss)) != NULL) {
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
+ if (unlikely((skb->data - skb_mac_header(skb)) == ETH_HLEN)) {
|
|
||||||
+ skb_push(skb, ETH_HLEN);
|
+ skb_push(skb, ETH_HLEN);
|
||||||
+ push_mac_header = 1;
|
|
||||||
+ }
|
|
||||||
+
|
+
|
||||||
+ ret = nss_virt_if_tx_buf(sdata->nssctx, skb);
|
+ ret = nss_virt_if_tx_buf(sdata->nssctx, skb);
|
||||||
+ if (ret) {
|
+ if (unlikely(ret)) {
|
||||||
+ if (net_ratelimit()) {
|
|
||||||
+ sdata_err(sdata, "NSS TX failed with error[%d]: %s\n", ret,
|
+ sdata_err(sdata, "NSS TX failed with error[%d]: %s\n", ret,
|
||||||
+ nss_tx_status_str(ret));
|
+ nss_tx_status_str(ret));
|
||||||
|
+
|
||||||
|
+ skb_pull(skb, ETH_HLEN);
|
||||||
|
+ netif_receive_skb(skb);
|
||||||
+ }
|
+ }
|
||||||
+ goto out;
|
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ return;
|
+ skb = skb_peek(&sdata->rq_for_nss);
|
||||||
+out:
|
+ if (!skb) {
|
||||||
+ if (unlikely(push_mac_header)) {
|
+ sdata->nss_rq_tasklet_pending = 0;
|
||||||
+ skb_pull(skb, ETH_HLEN);
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ sdata->nss_rq_tasklet_pending = 1;
|
||||||
|
+ tasklet_schedule(&sdata->ieee80211_nss_rq_tasklet);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int ieee80211_init_nss(struct net_device *dev)
|
||||||
|
+{
|
||||||
|
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||||
|
+
|
||||||
|
+ sdata->nssctx = nss_virt_if_create_sync(dev);
|
||||||
|
+ if (sdata->nssctx) {
|
||||||
|
+ sdata_info(sdata, "Created a NSS virtual interface.\n");
|
||||||
|
+
|
||||||
|
+ __skb_queue_head_init(&sdata->rq_for_nss);
|
||||||
|
+ tasklet_init(&sdata->ieee80211_nss_rq_tasklet, ieee80211_nss_rq_tasklet,
|
||||||
|
+ (unsigned long)sdata);
|
||||||
|
+ sdata_info(sdata, "RX-Q and tasklet initialized.\n");
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ sdata->nssctx = NULL;
|
||||||
|
+ sdata_err(sdata, "Failed to create a NSS virtual interface\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void ieee80211_uninit_nss(struct net_device *dev)
|
||||||
|
+{
|
||||||
|
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||||
|
+
|
||||||
|
+ ieee80211_uninit(dev);
|
||||||
|
+
|
||||||
|
+ if (sdata->nssctx) {
|
||||||
|
+ nss_virt_if_destroy_sync(sdata->nssctx);
|
||||||
|
+ sdata_info(sdata, "Destroyed NSS virtual interface\n");
|
||||||
|
+
|
||||||
|
+ tasklet_kill(&sdata->ieee80211_nss_rq_tasklet);
|
||||||
|
+ __skb_queue_purge(&sdata->rq_for_nss);
|
||||||
|
+ sdata_info(sdata, "RX-Q purged.\n");
|
||||||
+ }
|
+ }
|
||||||
+ netif_receive_skb(skb);
|
|
||||||
+}
|
+}
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
|
#if LINUX_VERSION_IS_GEQ(5,2,0)
|
||||||
|
static u16 ieee80211_netdev_select_queue(struct net_device *dev,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
@@ -742,7 +839,12 @@
|
||||||
|
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_nss,
|
||||||
|
+ .ndo_uninit = ieee80211_uninit_nss,
|
||||||
|
+#else
|
||||||
|
.ndo_uninit = ieee80211_uninit,
|
||||||
|
+#endif
|
||||||
|
.ndo_start_xmit = ieee80211_subif_start_xmit,
|
||||||
|
.ndo_set_rx_mode = ieee80211_set_multicast_list,
|
||||||
|
.ndo_set_mac_address = ieee80211_change_mac,
|
||||||
|
--- a/net/mac80211/rx.c 2019-01-03 21:09:29.503001000 +0800
|
||||||
|
+++ b/net/mac80211/rx.c 2019-01-03 21:17:42.463001000 +0800
|
||||||
|
@@ -32,6 +32,10 @@
|
||||||
|
#include "wme.h"
|
||||||
|
#include "rate.h"
|
||||||
|
|
||||||
|
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
||||||
|
+extern bool is_nss_enable;
|
||||||
|
+#endif
|
||||||
+
|
+
|
||||||
/*
|
static inline void ieee80211_rx_stats(struct net_device *dev, u32 len)
|
||||||
* monitor mode reception
|
{
|
||||||
*
|
struct pcpu_sw_netstats *tstats = this_cpu_ptr(netdev_tstats(dev));
|
||||||
@@ -2604,6 +2665,16 @@
|
@@ -2604,6 +2608,21 @@
|
||||||
ether_addr_copy(ehdr->h_dest, sdata->vif.addr);
|
ether_addr_copy(ehdr->h_dest, sdata->vif.addr);
|
||||||
|
|
||||||
/* deliver to local stack */
|
/* deliver to local stack */
|
||||||
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
||||||
+ if (likely(is_nss_enable))
|
+ if (likely(is_nss_enable && sdata->nssctx)) {
|
||||||
+ netif_rx_nss(sdata, skb);
|
+ __skb_queue_tail(&sdata->rq_for_nss, skb);
|
||||||
|
+ if(!sdata->nss_rq_tasklet_pending) {
|
||||||
|
+ sdata->nss_rq_tasklet_pending = 1;
|
||||||
|
+ tasklet_schedule(&sdata->ieee80211_nss_rq_tasklet);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
+ else {
|
+ else {
|
||||||
+ if (rx->napi)
|
+ if (rx->list)
|
||||||
+ napi_gro_receive(rx->napi, skb);
|
+ list_add_tail(&skb->list, rx->list);
|
||||||
+ else
|
+ else
|
||||||
+ netif_receive_skb(skb);
|
+ netif_receive_skb(skb);
|
||||||
+ }
|
+ }
|
||||||
@ -198,7 +220,7 @@
|
|||||||
if (rx->list)
|
if (rx->list)
|
||||||
#if LINUX_VERSION_IS_GEQ(4,19,0)
|
#if LINUX_VERSION_IS_GEQ(4,19,0)
|
||||||
list_add_tail(&skb->list, rx->list);
|
list_add_tail(&skb->list, rx->list);
|
||||||
@@ -2612,6 +2683,7 @@
|
@@ -2612,6 +2631,7 @@
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
netif_receive_skb(skb);
|
netif_receive_skb(skb);
|
||||||
@ -206,16 +228,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4461,6 +4533,16 @@
|
@@ -4461,6 +4481,21 @@
|
||||||
/* deliver to local stack */
|
/* deliver to local stack */
|
||||||
skb->protocol = eth_type_trans(skb, fast_rx->dev);
|
skb->protocol = eth_type_trans(skb, fast_rx->dev);
|
||||||
memset(skb->cb, 0, sizeof(skb->cb));
|
memset(skb->cb, 0, sizeof(skb->cb));
|
||||||
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
|
||||||
+ if (likely(is_nss_enable))
|
+ if (likely(is_nss_enable && rx->sdata->nssctx)) {
|
||||||
+ netif_rx_nss(rx->sdata, skb);
|
+ __skb_queue_tail(&rx->sdata->rq_for_nss, skb);
|
||||||
|
+ if(!rx->sdata->nss_rq_tasklet_pending) {
|
||||||
|
+ rx->sdata->nss_rq_tasklet_pending = 1;
|
||||||
|
+ tasklet_schedule(&rx->sdata->ieee80211_nss_rq_tasklet);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
+ else {
|
+ else {
|
||||||
+ if (rx->napi)
|
+ if (rx->list)
|
||||||
+ napi_gro_receive(rx->napi, skb);
|
+ list_add_tail(&skb->list, rx->list);
|
||||||
+ else
|
+ else
|
||||||
+ netif_receive_skb(skb);
|
+ netif_receive_skb(skb);
|
||||||
+ }
|
+ }
|
||||||
@ -223,7 +250,7 @@
|
|||||||
if (rx->list)
|
if (rx->list)
|
||||||
#if LINUX_VERSION_IS_GEQ(4,19,0)
|
#if LINUX_VERSION_IS_GEQ(4,19,0)
|
||||||
list_add_tail(&skb->list, rx->list);
|
list_add_tail(&skb->list, rx->list);
|
||||||
@@ -4469,7 +4551,7 @@
|
@@ -4469,7 +4504,7 @@
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
netif_receive_skb(skb);
|
netif_receive_skb(skb);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user