mac80211: add support for NSS on ipq806x platform
SqTER-PL <r.napierala@asta-net.pl>
This commit is contained in:
		| @@ -86,6 +86,7 @@ config-$(CONFIG_PACKAGE_CFG80211_TESTMODE) += NL80211_TESTMODE | |||||||
|  |  | ||||||
| config-$(call config_package,mac80211,$(ALL_VARIANTS)) += MAC80211 | config-$(call config_package,mac80211,$(ALL_VARIANTS)) += MAC80211 | ||||||
| config-$(CONFIG_PACKAGE_MAC80211_MESH) += MAC80211_MESH | config-$(CONFIG_PACKAGE_MAC80211_MESH) += MAC80211_MESH | ||||||
|  | config-$(CONFIG_PACKAGE_MAC80211_NSS_SUPPORT) += MAC80211_NSS_SUPPORT | ||||||
|  |  | ||||||
| include ath.mk | include ath.mk | ||||||
| include broadcom.mk | include broadcom.mk | ||||||
| @@ -129,7 +130,7 @@ define KernelPackage/mac80211 | |||||||
|   $(call KernelPackage/mac80211/Default) |   $(call KernelPackage/mac80211/Default) | ||||||
|   TITLE:=Linux 802.11 Wireless Networking Stack |   TITLE:=Linux 802.11 Wireless Networking Stack | ||||||
|   # +kmod-crypto-cmac is a runtime only dependency of net/mac80211/aes_cmac.c |   # +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:=\ |   KCONFIG:=\ | ||||||
| 	CONFIG_AVERAGE=y | 	CONFIG_AVERAGE=y | ||||||
|   FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko |   FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko | ||||||
| @@ -140,6 +141,16 @@ endef | |||||||
| define KernelPackage/mac80211/config | define KernelPackage/mac80211/config | ||||||
|   if PACKAGE_kmod-mac80211 |   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 | 	config PACKAGE_MAC80211_DEBUGFS | ||||||
| 		bool "Export mac80211 internals in DebugFS" | 		bool "Export mac80211 internals in DebugFS" | ||||||
| 		select KERNEL_DEBUG_FS | 		select KERNEL_DEBUG_FS | ||||||
| @@ -281,9 +292,10 @@ ifeq ($(BUILD_VARIANT),smallbuffers) | |||||||
| 	C_DEFINES+= -DCONFIG_ATH10K_SMALLBUFFERS | 	C_DEFINES+= -DCONFIG_ATH10K_SMALLBUFFERS | ||||||
| endif | endif | ||||||
|  |  | ||||||
| MAKE_OPTS:= \ | MAKE_OPTS:= -C "$(PKG_BUILD_DIR)" \ | ||||||
| 	$(subst -C $(LINUX_DIR),-C "$(PKG_BUILD_DIR)",$(KERNEL_MAKEOPTS)) \ | 	$(KERNEL_MAKE_FLAGS) \ | ||||||
| 	EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS) $(C_DEFINES)" \ | 	EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS) $(C_DEFINES) \ | ||||||
|  | 		-I$(STAGING_DIR)/usr/include/qca-nss-drv" \ | ||||||
| 	KLIB_BUILD="$(LINUX_DIR)" \ | 	KLIB_BUILD="$(LINUX_DIR)" \ | ||||||
| 	MODPROBE=true \ | 	MODPROBE=true \ | ||||||
| 	KLIB=$(TARGET_MODULES_DIR) \ | 	KLIB=$(TARGET_MODULES_DIR) \ | ||||||
|   | |||||||
| @@ -0,0 +1,296 @@ | |||||||
|  | From 3acca4ecfe25a7d97e7cb820fd8c7c6324a1f318 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org> | ||||||
|  | Date: Tue, 18 Aug 2020 16:17:25 +0530 | ||||||
|  | Subject: [PATCH] ath11k : Add NSS redirect support | ||||||
|  |  | ||||||
|  | Add NSS Redirect support for ath11k. Tested on ipq8074 | ||||||
|  | Most of the changes are similar to the one done for ath10k with | ||||||
|  | minor changes to send to nss with eth header | ||||||
|  |  | ||||||
|  | Redirect can be enabled by setting nss_redirect module param during | ||||||
|  | mac80211 insmod followed by ecm start | ||||||
|  | insmod mac80211.ko nss_redirect=1 | ||||||
|  | /etc/init.d/qca-nss-ecm start | ||||||
|  |  | ||||||
|  | Check for ipv4_hash_hits counts in ipv4 stats and eth_rx | ||||||
|  | in qca-nss-drv to check whether packets are redirected or not. | ||||||
|  |  | ||||||
|  | Verified both in nwifi and ethernet mode by running tcp and udp | ||||||
|  | traffic. | ||||||
|  |  | ||||||
|  | Co-developed by: Sriram R <srirrama@codeaurora.org> | ||||||
|  | Signed-off-by: Sriram R <srirrama@codeaurora.org> | ||||||
|  | Signed-off-by: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org> | ||||||
|  | --- | ||||||
|  |  net/mac80211/ieee80211_i.h |  2 ++ | ||||||
|  |  net/mac80211/iface.c       | 43 ++++++++++++++++++++++++++++++++ | ||||||
|  |  net/mac80211/rx.c          | 61 +++++++++++++++++++++++++++++++++++++--------- | ||||||
|  |  net/mac80211/tx.c          | 32 ++++++++++++++++++++++++ | ||||||
|  |  4 files changed, 126 insertions(+), 12 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/local-symbols | ||||||
|  | +++ b/local-symbols | ||||||
|  | @@ -32,6 +32,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/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 Netgear R7800. | ||||||
|  | + | ||||||
|  |  config MAC80211_HAS_RC | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  | --- a/net/mac80211/ieee80211_i.h | ||||||
|  | +++ b/net/mac80211/ieee80211_i.h | ||||||
|  | @@ -36,6 +36,10 @@ | ||||||
|  |  #include "debug.h" | ||||||
|  |  #include "drop.h" | ||||||
|  |   | ||||||
|  | +#ifdef CPTCFG_MAC80211_NSS_SUPPORT | ||||||
|  | +#include <nss_api_if.h> | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  extern const struct cfg80211_ops mac80211_config_ops; | ||||||
|  |   | ||||||
|  |  struct ieee80211_local; | ||||||
|  | @@ -1185,6 +1189,10 @@ struct ieee80211_sub_if_data { | ||||||
|  |  	} debugfs; | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +#ifdef CPTCFG_MAC80211_NSS_SUPPORT | ||||||
|  | +	struct nss_virt_if_handle *nssctx; | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  	/* must be last, dynamically sized area in this! */ | ||||||
|  |  	struct ieee80211_vif vif; | ||||||
|  |  }; | ||||||
|  | --- a/net/mac80211/iface.c | ||||||
|  | +++ b/net/mac80211/iface.c | ||||||
|  | @@ -27,6 +27,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 | ||||||
|  |   * | ||||||
|  | @@ -776,6 +782,13 @@ static int ieee80211_stop(struct net_dev | ||||||
|  |  		ieee80211_stop_mbssid(sdata); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +#ifdef CPTCFG_MAC80211_NSS_SUPPORT | ||||||
|  | +	if (sdata->nssctx) { | ||||||
|  | +		nss_virt_if_destroy_sync(sdata->nssctx); | ||||||
|  | +		sdata_info(sdata, "Destroyed NSS virtual interface\n"); | ||||||
|  | +	} | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  	wiphy_lock(sdata->local->hw.wiphy); | ||||||
|  |  	wiphy_work_cancel(sdata->local->hw.wiphy, &sdata->activate_links_work); | ||||||
|  |   | ||||||
|  | @@ -1226,6 +1239,34 @@ void ieee80211_del_virtual_monitor(struc | ||||||
|  |  	kfree(sdata); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +#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); | ||||||
|  | +} | ||||||
|  | +#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 | ||||||
|  | @@ -1456,6 +1497,19 @@ int ieee80211_do_open(struct wireless_de | ||||||
|  |   | ||||||
|  |  	ieee80211_recalc_ps(local); | ||||||
|  |   | ||||||
|  | +#ifdef CPTCFG_MAC80211_NSS_SUPPORT | ||||||
|  | +       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_info(sdata, "Failed to create a NSS virtual interface\n"); | ||||||
|  | +               } | ||||||
|  | +       } | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  	set_bit(SDATA_STATE_RUNNING, &sdata->state); | ||||||
|  |   | ||||||
|  |  	return 0; | ||||||
|  | --- a/net/mac80211/rx.c | ||||||
|  | +++ b/net/mac80211/rx.c | ||||||
|  | @@ -2613,6 +2613,54 @@ static bool ieee80211_frame_allowed(stru | ||||||
|  |  	return true; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +#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); | ||||||
|  | +	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 | ||||||
|  | + | ||||||
|  |  static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb, | ||||||
|  |  						 struct ieee80211_rx_data *rx) | ||||||
|  |  { | ||||||
|  | @@ -2653,10 +2701,14 @@ 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 | ||||||
|  | +		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 | ||||||
|  | @@ -4495,6 +4495,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 | ||||||
|  | @@ -4510,6 +4539,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; | ||||||
|  |   | ||||||
|  | @@ -4696,6 +4729,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; | ||||||
| @@ -0,0 +1,11 @@ | |||||||
|  | --- a/net/mac80211/main.c | ||||||
|  | +++ b/net/mac80211/main.c | ||||||
|  | @@ -269,7 +269,7 @@ void ieee80211_hw_conf_init(struct ieee8 | ||||||
|  |  						       ctx ? &ctx->conf : NULL); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	WARN_ON(drv_config(local, changed)); | ||||||
|  | +	drv_config(local, changed); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  int ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw, | ||||||
		Reference in New Issue
	
	Block a user
	 Lucas Asvio
					Lucas Asvio