From 55d0f3ae945364ee545c1aa8c7f4df6c82341703 Mon Sep 17 00:00:00 2001 From: ACwifidude Date: Fri, 18 Jun 2021 14:40:33 -0500 Subject: [PATCH] ipq806x: NSS Hardware Offloading mac80211 Offloading Patches --- package/kernel/mac80211/Makefile | 15 +- ...-mac80211-add-option-for-NSS-support.patch | 230 ++++++++++++++++++ .../subsys/999-mac80211-nss-classify-tx.patch | 45 ++++ .../subsys/999-mac80211-xmit-busy.patch | 20 ++ 4 files changed, 308 insertions(+), 2 deletions(-) create mode 100644 package/kernel/mac80211/patches/subsys/999-mac80211-add-option-for-NSS-support.patch create mode 100644 package/kernel/mac80211/patches/subsys/999-mac80211-nss-classify-tx.patch create mode 100644 package/kernel/mac80211/patches/subsys/999-mac80211-xmit-busy.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index dd39c2d069..4de9d1557c 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -84,6 +84,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 @@ -127,7 +128,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 @@ -137,6 +138,15 @@ 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" @@ -436,7 +446,8 @@ config-$(CONFIG_LEDS_TRIGGERS) += MAC80211_LEDS MAKE_OPTS:= -C "$(PKG_BUILD_DIR)" \ $(KERNEL_MAKE_FLAGS) \ - EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS)" \ + EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS) \ + -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-add-option-for-NSS-support.patch b/package/kernel/mac80211/patches/subsys/999-mac80211-add-option-for-NSS-support.patch new file mode 100644 index 0000000000..3b0e5c05d8 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/999-mac80211-add-option-for-NSS-support.patch @@ -0,0 +1,230 @@ +--- 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 ++#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); diff --git a/package/kernel/mac80211/patches/subsys/999-mac80211-nss-classify-tx.patch b/package/kernel/mac80211/patches/subsys/999-mac80211-nss-classify-tx.patch new file mode 100644 index 0000000000..b03b94d21f --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/999-mac80211-nss-classify-tx.patch @@ -0,0 +1,45 @@ +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -38,6 +38,11 @@ + #include "wme.h" + #include "rate.h" + ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++#include ++#include ++#endif ++ + /* misc utils */ + + static inline void ieee80211_tx_stats(struct net_device *dev, u32 len) +@@ -3561,6 +3566,30 @@ void __ieee80211_subif_start_xmit(struct + netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, + struct net_device *dev) + { ++#ifdef CPTCFG_MAC80211_NSS_SUPPORT ++ /* 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. ++ */ ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ ++ 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 ++ + if (unlikely(ieee80211_multicast_to_unicast(skb, dev))) { + struct sk_buff_head queue; + diff --git a/package/kernel/mac80211/patches/subsys/999-mac80211-xmit-busy.patch b/package/kernel/mac80211/patches/subsys/999-mac80211-xmit-busy.patch new file mode 100644 index 0000000000..1b5723f5f8 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/999-mac80211-xmit-busy.patch @@ -0,0 +1,20 @@ +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1580,7 +1580,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 + * later transmission from the tx-pending