diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index d05ceb5cfa05..baf220620369 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -600,6 +600,7 @@ enum cdp_pdev_param_type { * @CDP_UPDATE_TDLS_FLAGS: tdls link flags * @CDP_ENABLE_AP_BRIDGE: set ap_bridging enable/disable * @CDP_ENABLE_CIPHER : set cipher type based on security + * @CDP_ENABLE_QWRAP_ISOLATION: qwrap isolation mode */ enum cdp_vdev_param_type { CDP_ENABLE_NAWDS, @@ -609,7 +610,8 @@ enum cdp_vdev_param_type { CDP_UPDATE_TDLS_FLAGS, CDP_CFG_WDS_AGING_TIMER, CDP_ENABLE_AP_BRIDGE, - CDP_ENABLE_CIPHER + CDP_ENABLE_CIPHER, + CDP_ENABLE_QWRAP_ISOLATION }; #define TXRX_FW_STATS_TXSTATS 1 diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 82cf7e26d065..f2c2747bfa8a 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -5089,6 +5089,9 @@ static void dp_set_vdev_param(struct cdp_vdev *vdev_handle, case CDP_ENABLE_CIPHER: vdev->sec_type = val; break; + case CDP_ENABLE_QWRAP_ISOLATION: + vdev->isolation_vdev = val; + break; default: break; } diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index 00f6b3a3653f..0987b42b2796 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -613,6 +613,50 @@ static inline QDF_STATUS dp_rx_ast_set_active(struct dp_soc *soc, uint16_t sa_id } #endif +/* + * check_qwrap_multicast_loopback() - Check if rx packet is a loopback packet. + * In qwrap mode, packets originated from + * any vdev should not loopback and + * should be dropped. + * @vdev: vdev on which rx packet is received + * @nbuf: rx pkt + * + */ +#if ATH_SUPPORT_WRAP +static inline bool check_qwrap_multicast_loopback(struct dp_vdev *vdev, + qdf_nbuf_t nbuf) +{ + struct dp_vdev *psta_vdev; + struct dp_pdev *pdev = vdev->pdev; + uint8_t *data = qdf_nbuf_data(nbuf); + + if (qdf_unlikely(vdev->proxysta_vdev)) { + /* In qwrap isolation mode, allow loopback packets as all + * packets go to RootAP and Loopback on the mpsta. + */ + if (vdev->isolation_vdev) + return false; + TAILQ_FOREACH(psta_vdev, &pdev->vdev_list, vdev_list_elem) { + if (qdf_unlikely(psta_vdev->proxysta_vdev && + !qdf_mem_cmp(psta_vdev->mac_addr.raw, + &data[DP_MAC_ADDR_LEN], DP_MAC_ADDR_LEN))) { + /* Drop packet if source address is equal to + * any of the vdev addresses. + */ + return true; + } + } + } + return false; +} +#else +static inline bool check_qwrap_multicast_loopback(struct dp_vdev *vdev, + qdf_nbuf_t nbuf) +{ + return false; +} +#endif + /* * dp_rx_buffers_replenish() - replenish rxdma ring with rx nbufs * called during dp rx initialization diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 75bc9beda87b..dc5cfd279722 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -485,6 +485,16 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_free(nbuf); return; } + /* + * In qwrap mode if the received packet matches with any of the vdev + * mac addresses, drop it. Donot receive multicast packets originated + * from any proxysta. + */ + if (check_qwrap_multicast_loopback(vdev, nbuf)) { + qdf_nbuf_free(nbuf); + return; + } + if (qdf_unlikely((peer->nawds_enabled == true) && hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr))) { diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index b49ee24cb7aa..5b55699f3e49 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1227,6 +1227,8 @@ struct dp_vdev { /* Is this a proxySTA VAP */ bool proxysta_vdev; + /* Is isolation mode enabled */ + bool isolation_vdev; /* Address search flags to be configured in HAL descriptor */ uint8_t hal_desc_addr_search_flags;