From 0eeac59b4ecfcc3438f5c7d8789646935218cc01 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Tue, 14 Apr 2020 12:46:13 +0530 Subject: [PATCH] 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 --- dp/inc/cdp_txrx_cmn.h | 5 +++-- dp/inc/cdp_txrx_cmn_struct.h | 3 +++ dp/inc/cdp_txrx_me.h | 4 ++-- dp/inc/cdp_txrx_ops.h | 5 +++-- dp/wifi3.0/dp_internal.h | 5 +++-- dp/wifi3.0/dp_main.c | 16 +++++++++++++++- dp/wifi3.0/dp_tx.c | 7 +++++++ dp/wifi3.0/dp_tx.h | 3 +++ dp/wifi3.0/dp_types.h | 3 +++ 9 files changed, 42 insertions(+), 9 deletions(-) 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;