Selaa lähdekoodia

qcacmn: Add mcast enhance flow for single dev

Add mcast enhancement for single dev/bonding feature

Change-Id: I8bc0c3c78e3eb8c6679e00442d607615bab38f96
CRs-Fixed: 3350461
KARTHIK KUMAR T 2 vuotta sitten
vanhempi
sitoutus
7ae4979be0

+ 4 - 0
dp/inc/cdp_txrx_cmn_struct.h

@@ -662,6 +662,7 @@ enum cdp_sec_type {
  * @is_intrabss_fwd:
  * @ppdu_cookie: 16-bit ppdu cookie that has to be replayed back in completions
  * @is_wds_extended:
+ * @is_mlo_mcast: Indicates if mlo_mcast enable or not
  *
  * This structure holds the parameters needed in the exception path of tx
  *
@@ -677,6 +678,9 @@ struct cdp_tx_exception_metadata {
 #ifdef QCA_SUPPORT_WDS_EXTENDED
 	uint8_t is_wds_extended;
 #endif
+#ifdef WLAN_MCAST_MLO
+	uint8_t is_mlo_mcast;
+#endif
 };
 
 /**

+ 14 - 0
dp/wifi3.0/be/dp_be.c

@@ -2517,6 +2517,19 @@ static bool dp_reo_remap_config_be(struct dp_soc *soc,
 }
 #endif
 
+#ifdef CONFIG_MLO_SINGLE_DEV
+static inline
+void dp_initialize_arch_ops_be_single_dev(struct dp_arch_ops *arch_ops)
+{
+	arch_ops->dp_tx_mlo_mcast_send = dp_tx_mlo_mcast_send_be;
+}
+#else
+static inline
+void dp_initialize_arch_ops_be_single_dev(struct dp_arch_ops *arch_ops)
+{
+}
+#endif
+
 #ifdef IPA_OFFLOAD
 static int8_t dp_ipa_get_bank_id_be(struct dp_soc *soc)
 {
@@ -2621,4 +2634,5 @@ void dp_initialize_arch_ops_be(struct dp_arch_ops *arch_ops)
 	arch_ops->reo_remap_config = dp_reo_remap_config_be;
 	arch_ops->txrx_get_vdev_mcast_param = dp_txrx_get_vdev_mcast_param_be;
 	dp_initialize_arch_ops_be_ipa(arch_ops);
+	dp_initialize_arch_ops_be_single_dev(arch_ops);
 }

+ 73 - 0
dp/wifi3.0/be/dp_be_tx.c

@@ -809,6 +809,79 @@ bool dp_tx_mlo_is_mcast_primary_be(struct dp_soc *soc,
 
 	return false;
 }
+
+#if defined(CONFIG_MLO_SINGLE_DEV)
+static void
+dp_tx_mlo_mcast_enhance_be(struct dp_vdev_be *be_vdev,
+			   struct dp_vdev *ptnr_vdev,
+			   void *arg)
+{
+	struct dp_vdev *vdev = (struct dp_vdev *)be_vdev;
+	qdf_nbuf_t  nbuf = (qdf_nbuf_t)arg;
+
+	if (vdev == ptnr_vdev)
+		return;
+
+	/*
+	 * Hold the reference to avoid free of nbuf in
+	 * dp_tx_mcast_enhance() in case of successful
+	 * conversion
+	 */
+	qdf_nbuf_ref(nbuf);
+
+	if (qdf_unlikely(!dp_tx_mcast_enhance(ptnr_vdev, nbuf)))
+		return;
+
+	qdf_nbuf_free(nbuf);
+}
+
+qdf_nbuf_t
+dp_tx_mlo_mcast_send_be(struct dp_soc *soc, struct dp_vdev *vdev,
+			qdf_nbuf_t nbuf,
+			struct cdp_tx_exception_metadata *tx_exc_metadata)
+{
+	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
+	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
+
+	if (!tx_exc_metadata->is_mlo_mcast)
+		return nbuf;
+
+	if (!be_vdev->mcast_primary) {
+		qdf_nbuf_free(nbuf);
+		return NULL;
+	}
+
+	/*
+	 * In the single netdev model avoid reinjection path as mcast
+	 * packet is identified in upper layers while peer search to find
+	 * primary TQM based on dest mac addr
+	 *
+	 * New bonding interface added into the bridge so MCSD will update
+	 * snooping table and wifi driver populates the entries in appropriate
+	 * child net devices.
+	 */
+	if (vdev->mcast_enhancement_en) {
+		/*
+		 * As dp_tx_mcast_enhance() can consume the nbuf incase of
+		 * successful conversion hold the reference of nbuf.
+		 *
+		 * Hold the reference to tx on partner links
+		 */
+		qdf_nbuf_ref(nbuf);
+		if (qdf_unlikely(!dp_tx_mcast_enhance(vdev, nbuf))) {
+			dp_mcast_mlo_iter_ptnr_vdev(be_soc, be_vdev,
+						    dp_tx_mlo_mcast_enhance_be,
+						    nbuf, DP_MOD_ID_TX);
+			qdf_nbuf_free(nbuf);
+			return NULL;
+		}
+		/* release reference taken above */
+		qdf_nbuf_free(nbuf);
+	}
+	dp_tx_mlo_mcast_handler_be(soc, vdev, nbuf);
+	return NULL;
+}
+#endif
 #else
 static inline void
 dp_tx_vdev_id_set_hal_tx_desc(uint32_t *hal_tx_desc_cached,

+ 19 - 1
dp/wifi3.0/be/dp_be_tx.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -253,6 +253,24 @@ bool dp_tx_mlo_is_mcast_primary_be(struct dp_soc *soc,
 				   struct dp_vdev *vdev);
 #ifdef WLAN_MCAST_MLO
 #ifdef WLAN_MLO_MULTI_CHIP
+#ifdef CONFIG_MLO_SINGLE_DEV
+/**
+ * dp_tx_mlo_mcast_send_be() - Tx send handler for mlo mcast enhance
+ * @soc: DP soc handle
+ * @vdev_id: id of DP vdev handle
+ * @nbuf: skb
+ * @tx_exc_metadata: Handle that holds exception path meta data
+ * @pkt_drop_st: if packet drop will set for 1
+ *
+ * Return: NULL for success
+ *         nbuf for failure
+ */
+
+qdf_nbuf_t dp_tx_mlo_mcast_send_be(struct dp_soc *soc, struct dp_vdev *vdev,
+				   qdf_nbuf_t nbuf,
+				   struct cdp_tx_exception_metadata
+				   *tx_exc_metadata);
+#endif
 /**
  * dp_tx_mlo_mcast_pkt_send() - handler to send MLO Mcast packets
  * @be_vdev: Handle to DP be_vdev structure

+ 15 - 2
dp/wifi3.0/dp_tx.c

@@ -3090,7 +3090,7 @@ static bool dp_check_exc_metadata(struct cdp_tx_exception_metadata *tx_exc)
  * Return: true on success,
  *         false on failure
  */
-static inline bool dp_tx_mcast_enhance(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
+bool dp_tx_mcast_enhance(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
 {
 	qdf_ether_header_t *eh;
 
@@ -3122,7 +3122,7 @@ static inline bool dp_tx_mcast_enhance(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
 	return true;
 }
 #else
-static inline bool dp_tx_mcast_enhance(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
+bool dp_tx_mcast_enhance(struct dp_vdev *vdev, qdf_nbuf_t nbuf)
 {
 	return true;
 }
@@ -3395,6 +3395,19 @@ dp_tx_send_exception(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 	 */
 	dp_tx_get_queue(vdev, nbuf, &msdu_info.tx_queue);
 
+	/*
+	 * if the packet is mcast packet send through mlo_macst handler
+	 * for all prnt_vdevs
+	 */
+
+	if (soc->arch_ops.dp_tx_mlo_mcast_send) {
+		nbuf = soc->arch_ops.dp_tx_mlo_mcast_send(soc, vdev,
+							  nbuf,
+							  tx_exc_metadata);
+		if (!nbuf)
+			goto fail;
+	}
+
 	if (qdf_likely(tx_exc_metadata->is_intrabss_fwd)) {
 		if (qdf_unlikely(vdev->nawds_enabled)) {
 			/*

+ 10 - 0
dp/wifi3.0/dp_tx.h

@@ -337,6 +337,16 @@ dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
 		       struct dp_tx_msdu_info_s *msdu_info, uint16_t peer_id,
 		       struct cdp_tx_exception_metadata *tx_exc_metadata);
 
+/**
+ * dp_tx_mcast_enhance
+ * @vdev: DP vdev handle
+ * @nbuf: network buffer to be transmitted
+ *
+ * Return: true on success
+ *         false on failure
+ */
+bool dp_tx_mcast_enhance(struct dp_vdev *vdev, qdf_nbuf_t buf);
+
 #if QDF_LOCK_STATS
 noinline qdf_nbuf_t
 dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,

+ 7 - 0
dp/wifi3.0/dp_types.h

@@ -2241,6 +2241,13 @@ struct dp_arch_ops {
 	void (*tx_comp_get_params_from_hal_desc)(struct dp_soc *soc,
 						 void *tx_comp_hal_desc,
 						 struct dp_tx_desc_s **desc);
+
+	qdf_nbuf_t (*dp_tx_mlo_mcast_send)(struct dp_soc *soc,
+					   struct dp_vdev *vdev,
+					   qdf_nbuf_t nbuf,
+					   struct cdp_tx_exception_metadata
+					   *tx_exc_metadata);
+
 	void (*dp_tx_process_htt_completion)(struct dp_soc *soc,
 					     struct dp_tx_desc_s *tx_desc,
 					     uint8_t *status,