diff --git a/dp/inc/cdp_txrx_cmn.h b/dp/inc/cdp_txrx_cmn.h index 9dc5021fea7d..ff67236a0b1a 100644 --- a/dp/inc/cdp_txrx_cmn.h +++ b/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); } /* diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 21b248cfcc0e..396995d83f60 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/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, }; /* diff --git a/dp/inc/cdp_txrx_me.h b/dp/inc/cdp_txrx_me.h index 010b4c383a8a..9d4c3e29db91 100644 --- a/dp/inc/cdp_txrx_me.h +++ b/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 diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 124b7abd91c5..416a34547447 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/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 { diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 94c3c70c3d32..6c8b11fa2062 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/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 diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 7e741c8af947..c9ed2d39cd42 100644 --- a/dp/wifi3.0/dp_main.c +++ b/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) diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index e671169771ca..055cb6f240d6 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/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 diff --git a/dp/wifi3.0/dp_tx.h b/dp/wifi3.0/dp_tx.h index 6c082944ce1e..c9b8da1ab303 100644 --- a/dp/wifi3.0/dp_tx.h +++ b/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) { diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index a41f6af71144..cf05fea20067 100644 --- a/dp/wifi3.0/dp_types.h +++ b/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;