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-$(CONFIG_PACKAGE_MAC80211_MESH) += MAC80211_MESH | ||||
| config-$(CONFIG_PACKAGE_MAC80211_NSS_SUPPORT) += MAC80211_NSS_SUPPORT | ||||
|  | ||||
| include ath.mk | ||||
| include broadcom.mk | ||||
| @@ -129,7 +130,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 | ||||
| @@ -140,6 +141,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 | ||||
| @@ -281,9 +292,10 @@ 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)" \ | ||||
| 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) \ | ||||
|   | ||||
| @@ -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