Browse Source

qcacmn: VoW IGMP improvements

As part of the VoW IGMP improvements, which deals with
conversion of igmp packets to unicast packets, the
following changes are done when the new feature is enabled:

1. IGMP/MLD packets with special addresses (addresses not
   part of any multicast group) will be converted to all
   existing clients of the AP. These packets will be
   directly fed to igmp multicast to unicast conversion
   module.
2. The IGMP/MLD packets with group specific addresses will
   first go to multicast enhancement module, where they
   will be allowed to pass and will be converted to unicast.
3. The new feature will be enabled only when multicast
   enhancement feature is enabled, which will be ensured
   at the configuration level.
FR : 61063

Change-Id: I2fd5a67766c806432fbe1a12cb9654a3600100f5
Pavankumar Nandeshwar 5 years ago
parent
commit
0eeac59b4e

+ 3 - 2
dp/inc/cdp_txrx_cmn.h

@@ -2600,6 +2600,7 @@ cdp_tx_send_exc(ol_txrx_soc_handle soc,
  * @vdev_id: vdev id
  * @newmac: Table of the clients mac
  * @mac_cnt: No. of MACs required
+ * @limit: Limit the number of clients
  *
  * return: no of clients
  */
@@ -2607,7 +2608,7 @@ static inline uint16_t
 cdp_vdev_get_peer_mac_list(ol_txrx_soc_handle soc,
 			   uint8_t vdev_id,
 			   uint8_t newmac[][QDF_MAC_ADDR_SIZE],
-			   uint16_t mac_cnt)
+			   uint16_t mac_cnt, bool limit)
 {
 	if (!soc || !soc->ops) {
 		QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
@@ -2621,7 +2622,7 @@ cdp_vdev_get_peer_mac_list(ol_txrx_soc_handle soc,
 		return 0;
 
 	return soc->ops->cmn_drv_ops->get_peer_mac_list
-			(soc, vdev_id, newmac, mac_cnt);
+			(soc, vdev_id, newmac, mac_cnt, limit);
 }
 
 /*

+ 3 - 0
dp/inc/cdp_txrx_cmn_struct.h

@@ -1148,6 +1148,7 @@ typedef union cdp_config_param_t {
 	bool cdp_vdev_param_update_multipass;
 	uint8_t cdp_vdev_param_da_war;
 	uint8_t cdp_vdev_param_mcast_en;
+	uint8_t cdp_vdev_param_igmp_mcast_en;
 	uint8_t cdp_vdev_param_tidmap_prty;
 	uint8_t cdp_vdev_param_tidmap_tbl_id;
 	uint32_t cdp_vdev_param_aging_tmr;
@@ -1266,6 +1267,7 @@ enum cdp_pdev_bpr_param {
  * @CDP_MESH_MODE: set mesh mode
  * @CDP_SAFEMODE: set safe mode
  * @CDP_DROP_UNENC: set drop unencrypted flag
+ * @CDP_ENABLE_IGMP_MCAST_EN: enable/disable igmp multicast enhancement
  */
 enum cdp_vdev_param_type {
 	CDP_ENABLE_NAWDS,
@@ -1291,6 +1293,7 @@ enum cdp_vdev_param_type {
 	CDP_SAFEMODE,
 	CDP_DROP_UNENC,
 	CDP_ENABLE_CSUM,
+	CDP_ENABLE_IGMP_MCAST_EN,
 };
 
 /*

+ 2 - 2
dp/inc/cdp_txrx_me.h

@@ -65,7 +65,7 @@ cdp_tx_me_free_descriptor(ol_txrx_soc_handle soc, uint8_t pdev_id)
 static inline uint16_t
 cdp_tx_me_convert_ucast(ol_txrx_soc_handle soc, uint8_t vdev_id,
 			qdf_nbuf_t wbuf, u_int8_t newmac[][6],
-			uint8_t newmaccnt)
+			uint8_t newmaccnt, uint8_t tid)
 {
 	if (!soc || !soc->ops) {
 		QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
@@ -79,7 +79,7 @@ cdp_tx_me_convert_ucast(ol_txrx_soc_handle soc, uint8_t vdev_id,
 		return 0;
 
 	return soc->ops->me_ops->tx_me_convert_ucast
-			(soc, vdev_id, wbuf, newmac, newmaccnt);
+			(soc, vdev_id, wbuf, newmac, newmaccnt, tid);
 }
 
 #endif

+ 3 - 2
dp/inc/cdp_txrx_ops.h

@@ -543,7 +543,8 @@ struct cdp_cmn_ops {
 
 	uint16_t (*get_peer_mac_list)
 		 (ol_txrx_soc_handle soc, uint8_t vdev_id,
-		  u_int8_t newmac[][QDF_MAC_ADDR_SIZE], uint16_t mac_cnt);
+		  u_int8_t newmac[][QDF_MAC_ADDR_SIZE], uint16_t mac_cnt,
+		  bool limit);
 };
 
 struct cdp_ctrl_ops {
@@ -768,7 +769,7 @@ struct cdp_me_ops {
 
 	uint16_t (*tx_me_convert_ucast)(struct cdp_soc_t *soc, uint8_t vdev_id,
 					qdf_nbuf_t wbuf, u_int8_t newmac[][6],
-					uint8_t newmaccnt);
+					uint8_t newmaccnt, uint8_t tid);
 };
 
 struct cdp_mon_ops {

+ 3 - 2
dp/wifi3.0/dp_internal.h

@@ -1194,7 +1194,7 @@ void dp_rx_bar_stats_cb(struct dp_soc *soc, void *cb_ctxt,
 uint16_t dp_tx_me_send_convert_ucast(struct cdp_soc_t *soc, uint8_t vdev_id,
 				     qdf_nbuf_t nbuf,
 				     uint8_t newmac[][QDF_MAC_ADDR_SIZE],
-				     uint8_t new_mac_cnt);
+				     uint8_t new_mac_cnt, uint8_t tid);
 void dp_tx_me_alloc_descriptor(struct cdp_soc_t *soc, uint8_t pdev_id);
 
 void dp_tx_me_free_descriptor(struct cdp_soc_t *soc, uint8_t pdev_id);
@@ -2222,12 +2222,13 @@ QDF_STATUS dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t
  * @vdev_id: vdev id
  * @newmac: Table of the clients mac
  * @mac_cnt: No. of MACs required
+ * @limit: Limit the number of clients
  *
  * return: no of clients
  */
 uint16_t dp_get_peer_mac_list(ol_txrx_soc_handle soc, uint8_t vdev_id,
 			      u_int8_t newmac[][QDF_MAC_ADDR_SIZE],
-			      u_int16_t mac_cnt);
+			      u_int16_t mac_cnt, bool limit);
 /*
  * dp_is_hw_dbs_enable() - Procedure to check if DBS is supported
  * @soc:		DP SoC context

+ 15 - 1
dp/wifi3.0/dp_main.c

@@ -5190,6 +5190,7 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc,
 	vdev->rx_decap_type = wlan_cfg_pkt_type(soc->wlan_cfg_ctx);
 	vdev->dscp_tid_map_id = 0;
 	vdev->mcast_enhancement_en = 0;
+	vdev->igmp_mcast_enhanc_en = 0;
 	vdev->raw_mode_war = wlan_cfg_get_raw_mode_war(soc->wlan_cfg_ctx);
 	vdev->prev_tx_enq_tstamp = 0;
 	vdev->prev_rx_deliver_tstamp = 0;
@@ -8451,6 +8452,12 @@ static QDF_STATUS dp_get_vdev_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id,
 	case CDP_ENABLE_DA_WAR:
 		val->cdp_vdev_param_da_war = vdev->pdev->soc->da_war_enabled;
 		break;
+	case CDP_ENABLE_IGMP_MCAST_EN:
+		val->cdp_vdev_param_igmp_mcast_en = vdev->igmp_mcast_enhanc_en;
+		break;
+	case CDP_ENABLE_MCAST_EN:
+		val->cdp_vdev_param_mcast_en = vdev->mcast_enhancement_en;
+		break;
 	default:
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 			  "param value %d is wrong\n",
@@ -8511,6 +8518,9 @@ dp_set_vdev_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id,
 	case CDP_ENABLE_MCAST_EN:
 		vdev->mcast_enhancement_en = val.cdp_vdev_param_mcast_en;
 		break;
+	case CDP_ENABLE_IGMP_MCAST_EN:
+		vdev->igmp_mcast_enhanc_en = val.cdp_vdev_param_igmp_mcast_en;
+		break;
 	case CDP_ENABLE_PROXYSTA:
 		vdev->proxysta_vdev = val.cdp_vdev_param_proxysta;
 		break;
@@ -12149,12 +12159,13 @@ void dp_update_delay_stats(struct dp_pdev *pdev, uint32_t delay,
  * @vdev_id: vdev id
  * @newmac: Table of the clients mac
  * @mac_cnt: No. of MACs required
+ * @limit: Limit the number of clients
  *
  * return: no of clients
  */
 uint16_t dp_get_peer_mac_list(ol_txrx_soc_handle soc, uint8_t vdev_id,
 			      u_int8_t newmac[][QDF_MAC_ADDR_SIZE],
-			      u_int16_t mac_cnt)
+			      u_int16_t mac_cnt, bool limit)
 {
 	struct dp_soc *dp_soc = (struct dp_soc *)soc;
 	struct dp_vdev *vdev =
@@ -12165,6 +12176,9 @@ uint16_t dp_get_peer_mac_list(ol_txrx_soc_handle soc, uint8_t vdev_id,
 	if (!vdev)
 		return new_mac_cnt;
 
+	if (limit && (vdev->num_peers > mac_cnt))
+		return 0;
+
 	qdf_spin_lock_bh(&vdev->peer_list_lock);
 	TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
 		if (peer->bss_peer)

+ 7 - 0
dp/wifi3.0/dp_tx.c

@@ -2658,6 +2658,13 @@ qdf_nbuf_t dp_tx_send(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 					QDF_STATUS_SUCCESS) {
 				return NULL;
 			}
+
+			if (qdf_unlikely(vdev->igmp_mcast_enhanc_en > 0)) {
+				if (dp_tx_prepare_send_igmp_me(vdev, nbuf) ==
+					QDF_STATUS_SUCCESS) {
+					return NULL;
+				}
+			}
 		}
 	}
 #endif

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

@@ -285,6 +285,9 @@ uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
 QDF_STATUS
 dp_tx_prepare_send_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf);
 
+QDF_STATUS
+dp_tx_prepare_send_igmp_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf);
+
 #ifndef FEATURE_WDS
 static inline void dp_tx_mec_handler(struct dp_vdev *vdev, uint8_t *status)
 {

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

@@ -2130,6 +2130,9 @@ struct dp_vdev {
 	/* Multicast enhancement enabled */
 	uint8_t mcast_enhancement_en;
 
+	/* IGMP multicast enhancement enabled */
+	uint8_t igmp_mcast_enhanc_en;
+
 	/* HW TX Checksum Enabled Flag */
 	uint8_t csum_enabled;