From 91df8aa674d2d4064ab22f47515c3fb126527208 Mon Sep 17 00:00:00 2001
From: Karthikeyan Kathirvel <kathirve@codeaurora.org>
Date: Thu, 12 Nov 2020 15:02:56 +0530
Subject: [PATCH] ath11k: NSS MCBC Exception added for STA

Since NSS FW is not supporting PN check for MCBC pkts, those pkts are
excepted from NSS offload to pass through mac80211 PN check.

Signed-off-by: Karthikeyan Kathirvel <kathirve@codeaurora.org>
Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70
---
 drivers/net/wireless/ath/ath11k/nss.c    | 128 +++++++++++++++++++++
 drivers/net/wireless/ath/ath11k/nss.h |  51 ++++----
 2 files changed, 153 insertions(+), 26 deletions(-)
 create mode 100644 mac80211/patches/301-ath11k-nss-mcbc-exception.patch

--- a/drivers/net/wireless/ath/ath11k/nss.c
+++ b/drivers/net/wireless/ath/ath11k/nss.c
@@ -769,6 +769,7 @@ ath11k_nss_vdev_special_data_receive(str
 	struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata = NULL;
 	struct ath11k_vif *arvif;
 	struct ath11k_base *ab;
+	struct ath11k_skb_rxcb *rxcb;
 	bool drop = false;
 	bool eth_decap = false;
 	int data_offs = 0;
@@ -799,15 +800,32 @@ ath11k_nss_vdev_special_data_receive(str
 		return;
 	}
 
-	if (eth_decap && wifi_metadata->pkt_type ==
-	    NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_WDS_LEARN) {
-		wds_metadata = &wifi_metadata->metadata.wds_metadata;
-		ath11k_nss_vdev_spl_receive_ext_wdsdata(arvif, skb,
-							wds_metadata, &drop);
-	}
+	switch(wifi_metadata->pkt_type) {
+	case NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_WDS_LEARN:
+		if (eth_decap) {
+			wds_metadata = &wifi_metadata->metadata.wds_metadata;
+			ath11k_nss_vdev_spl_receive_ext_wdsdata(arvif, skb,
+								wds_metadata, &drop);
+		}
+		if (!drop)
+			ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi);
+	break;
+	case NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_MCBC_RX:
+		ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "",
+			        "mcbc packet exception from nss: ",
+			        skb->data, skb->len);
+		rxcb = ATH11K_SKB_RXCB(skb);
+		rxcb->rx_desc = (struct hal_rx_desc *)skb->head;
+		rxcb->is_first_msdu = rxcb->is_last_msdu = true;
+		rxcb->is_continuation = false;
+		rxcb->is_mcbc = true;
+		ath11k_dp_rx_from_nss(arvif->ar, skb, napi);
+	break;
 
-	if (!drop)
-		ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi);
+	default:
+		ath11k_warn(ab, "unsupported pkt_type %d from nss\n", wifi_metadata->pkt_type);
+		dev_kfree_skb_any(skb);
+	}
 }
 
 static void
@@ -1953,6 +1971,7 @@ ath11k_nss_mesh_link_vdev_special_data_r
 		rxcb->rx_desc = (struct hal_rx_desc *)skb->head;
 		rxcb->is_first_msdu = rxcb->is_last_msdu = true;
 		rxcb->is_continuation = false;
+		rxcb->is_mcbc = true;
 		ath11k_dp_rx_from_nss(arvif->ar, skb, napi);
 		break;
 	case NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_MESH:
@@ -2568,8 +2587,15 @@ int ath11k_nss_vdev_create(struct ath11k
 		goto free_vdev;
 
 	switch (arvif->vif->type) {
-	case NL80211_IFTYPE_AP:
 	case NL80211_IFTYPE_STATION:
+		ret = ath11k_nss_vdev_set_cmd(arvif,
+					      NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD,
+					      ATH11K_NSS_ENABLE_MCBC_EXC);
+		if (ret) {
+			ath11k_err(ab, "failed to set MCBC in nss %d\n", ret);
+			goto unregister_vdev;
+		}
+	case NL80211_IFTYPE_AP:
 		ret = ath11k_nss_vdev_configure(arvif);
 		if (ret)
 			goto unregister_vdev;
--- a/drivers/net/wireless/ath/ath11k/nss.h
+++ b/drivers/net/wireless/ath/ath11k/nss.h
@@ -106,6 +106,9 @@ do {	\
 
 #define ATH11K_MPP_EXPIRY_TIMER_INTERVAL_MS	60 * HZ
 
+/* Enables the MCBC exception in NSS fw, 1 = enable */
+#define ATH11K_NSS_ENABLE_MCBC_EXC	1
+
 enum ath11k_nss_opmode {
 	ATH11K_NSS_OPMODE_UNKNOWN,
 	ATH11K_NSS_OPMODE_AP,
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -2711,7 +2711,11 @@ static void ath11k_dp_rx_h_mpdu(struct a
 
 	/* PN for multicast packets will be checked in mac80211 */
 	rxcb = ATH11K_SKB_RXCB(msdu);
-	rxcb->is_mcbc = fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc);
+
+	if (!ar->ab->nss.enabled)
+		rxcb->is_mcbc = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc);
+
+	fill_crypto_hdr = rxcb->is_mcbc;
 
 	if (rxcb->is_mcbc) {
 		rxcb->peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(ar->ab, rx_desc);
