diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 3cc5014868..3cfe1ecf6c 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -1290,6 +1290,8 @@ typedef union cdp_config_param_t { bool cdp_psoc_param_pext_stats; bool cdp_enable_tx_checksum; + + bool cdp_skip_bar_update; } cdp_config_param_type; /** @@ -1401,6 +1403,9 @@ enum cdp_vdev_param_type { CDP_ENABLE_PEER_TID_LATENCY, CDP_SET_VAP_MESH_TID, #endif +#ifdef WLAN_VENDOR_SPECIFIC_BAR_UPDATE + CDP_SKIP_BAR_UPDATE_AP, +#endif }; /* diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index ff3ce6b396..6bf8ce3d64 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -8803,6 +8803,14 @@ dp_set_vdev_param(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, vdev->mesh_tid_latency_config.latency_tid = val.cdp_vdev_param_mesh_tid; break; +#endif +#ifdef WLAN_VENDOR_SPECIFIC_BAR_UPDATE + case CDP_SKIP_BAR_UPDATE_AP: + dp_info("vdev_id %d skip BAR update: %u", vdev_id, + val.cdp_skip_bar_update); + vdev->skip_bar_update = val.cdp_skip_bar_update; + vdev->skip_bar_update_last_ts = 0; + break; #endif default: break; diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index d39b5ddb88..f6dc2feaa1 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -546,6 +546,40 @@ dp_rx_err_nbuf_pn_check(struct dp_soc *soc, hal_ring_desc_t ring_desc, return QDF_STATUS_E_FAILURE; } +#ifdef WLAN_VENDOR_SPECIFIC_BAR_UPDATE +/** + * dp_rx_skip_bar_frame() - Check whether BAR update need to be skipped + * + * @vdev: vdev reference + * + * Function to check whether BAR update need to be skipped + * + * Return: none + */ +static bool dp_rx_skip_bar_frame(struct dp_vdev *vdev) +{ + unsigned long cur_ts, prev_ts; + + if (vdev->skip_bar_update) { + prev_ts = vdev->skip_bar_update_last_ts; + cur_ts = qdf_get_system_timestamp(); + vdev->skip_bar_update_last_ts = cur_ts; + if ((cur_ts - prev_ts) < DP_SKIP_BAR_UPDATE_TIMEOUT) { + dp_info_rl("Skipping BAR update for vdev_id:%u", + vdev->vdev_id); + return true; + } + } + + return false; +} +#else +static bool dp_rx_skip_bar_frame(struct dp_vdev *vdev) +{ + return false; +} +#endif + static void dp_rx_err_handle_bar(struct dp_soc *soc, struct dp_peer *peer, @@ -558,6 +592,9 @@ void dp_rx_err_handle_bar(struct dp_soc *soc, QDF_STATUS status; struct ieee80211_frame_bar *bar; + if (dp_rx_skip_bar_frame(peer->vdev)) + return; + /* * 1. Is this a BAR frame. If not Discard it. * 2. If it is, get the peer id, tid, ssn diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 7ee70112e2..a0a325507b 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -140,6 +140,10 @@ #define DP_RX_REFILL_THRD_THRESHOLD 512 #endif +#ifdef WLAN_VENDOR_SPECIFIC_BAR_UPDATE +#define DP_SKIP_BAR_UPDATE_TIMEOUT 5000 +#endif + enum rx_pktlog_mode { DP_RX_PKTLOG_DISABLED = 0, DP_RX_PKTLOG_FULL, @@ -2626,6 +2630,10 @@ struct dp_vdev { bool wds_ext_enabled; #endif /* QCA_SUPPORT_WDS_EXTENDED */ +#ifdef WLAN_VENDOR_SPECIFIC_BAR_UPDATE + bool skip_bar_update; + unsigned long skip_bar_update_last_ts; +#endif /* WDS Aging timer period */ uint32_t wds_aging_timer_val;