Files
openwrt-kernel5.4-nss-qsdk10.0/package/kernel/mac80211/patches/subsys/999-mac80211-add-option-for-NSS-support.patch
2025-06-24 13:14:22 +02:00

231 lines
6.4 KiB
Diff

--- a/net/mac80211/Kconfig 2019-01-03 21:03:17.839001000 +0800
+++ b/net/mac80211/Kconfig 2019-01-03 21:04:43.931001000 +0800
@@ -16,6 +16,13 @@
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 2019-01-03 21:24:00.087001000 +0800
+++ b/local-symbols 2019-01-03 21:24:56.535001000 +0800
@@ -47,6 +47,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 2019-01-03 21:04:57.527001000 +0800
+++ b/net/mac80211/ieee80211_i.h 2019-01-03 21:05:44.827001000 +0800
@@ -35,6 +35,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
@@ -990,6 +994,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
@@ -645,6 +645,15 @@ static int ieee80211_stop(struct net_device *dev)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
+ if (sdata->nssctx) {
+ cancel_work_sync(&sdata->rx_work);
+ skb_queue_purge(&sdata->rx_queue);
+ nss_virt_if_destroy_sync(sdata->nssctx);
+ sdata_info(sdata, "Destroyed NSS virtual interface\n");
+ }
+#endif
+
ieee80211_do_stop(sdata, true);
return 0;
@@ -1090,6 +1099,89 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
kfree(sdata);
}
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
+#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_work(struct work_struct *work)
+{
+ int ret;
+ unsigned long flags;
+ struct sk_buff *skb;
+ struct sk_buff_head *list;
+ struct ieee80211_sub_if_data *sdata =
+ container_of(work, struct ieee80211_sub_if_data, rx_work);
+
+ list = &sdata->rx_queue;
+ skb = skb_dequeue(list);
+
+ while (skb != NULL) {
+ skb_push(skb, ETH_HLEN);
+ ret = nss_virt_if_tx_buf(sdata->nssctx, skb);
+ if (unlikely(ret)) {
+ if (net_ratelimit()) {
+ sdata_err(sdata, "NSS TX failed with error: %s\n",
+ nss_tx_status_str(ret));
+ }
+ skb_pull(skb, ETH_HLEN);
+ netif_receive_skb(skb);
+ }
+
+ skb = skb_dequeue(list);
+ }
+
+ /* Check if we there are more packet to process and resched */
+ skb = skb_peek(list);
+ if (skb)
+ schedule_work(&sdata->rx_work);
+}
+
+/* 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);
+}
+#endif
+
/*
* NOTE: Be very careful when changing this function, it must NOT return
* an error on interface type changes that have been pre-checked, so most
@@ -1348,6 +1417,17 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
ieee80211_recalc_ps(local);
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
+ 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);
+ skb_queue_head_init(&sdata->rx_queue);
+ INIT_WORK(&sdata->rx_work, &netif_rx_nss_work);
+ } else
+ sdata_err(sdata, "Failed to create a NSS virtual interface\n");
+#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
+++ b/net/mac80211/rx.c
@@ -2519,6 +2519,13 @@ static bool ieee80211_frame_allowed(stru
return true;
}
+static inline void netif_rx_nss(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
+{
+ skb_queue_tail(&sdata->rx_queue, skb);
+
+ schedule_work(&sdata->rx_work);
+}
+
static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb,
struct ieee80211_rx_data *rx)
{
@@ -2537,6 +2544,13 @@ static void ieee80211_deliver_skb_to_loc
} else {
memset(skb->cb, 0, sizeof(skb->cb));
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
+ if (sdata->nssctx) {
+ netif_rx_nss(skb, sdata);
+ return;
+ }
+#endif
+
/* deliver to local stack */
if (rx->list)
#if LINUX_VERSION_IS_GEQ(4,19,0)
@@ -4306,6 +4306,7 @@ static void ieee80211_rx_8023(struct iee
{
struct ieee80211_sta_rx_stats *stats;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
+ struct ieee80211_sub_if_data *sdata = rx->sdata;
struct sta_info *sta = rx->sta;
struct sk_buff *skb = rx->skb;
void *sa = skb->data + ETH_ALEN;
@@ -4377,6 +4391,13 @@ static void ieee80211_rx_8023(struct iee
/* deliver to local stack */
skb->protocol = eth_type_trans(skb, fast_rx->dev);
memset(skb->cb, 0, sizeof(skb->cb));
+#ifdef CPTCFG_MAC80211_NSS_SUPPORT
+ if (sdata->nssctx) {
+ netif_rx_nss(skb, sdata);
+ return;
+ }
+#endif
+
if (rx->list)
#if LINUX_VERSION_IS_GEQ(4,19,0)
list_add_tail(&skb->list, rx->list);