From 48b496eabd69e5ae51bf68f6498ed475ada3b575 Mon Sep 17 00:00:00 2001 From: Karthik Kantamneni Date: Thu, 26 Aug 2021 13:00:48 +0530 Subject: [PATCH] qcacmn: Conditionally update BAR frame info to H.W Host updates BAR info to H.W when out of order or 2K jump BAR frame is received. But some AP's frequently transmitting out of order BAR frames even before reception of all the frames in the current window, if station updates window and SSN based on BAR frame, RX frames sequence number in older window range which are yet to be received suffers REO aging timeout and causes RX packet delay to avoid this skipping BAR update to H.W conditionally. Change-Id: If56571ffc0dc0880d7104ea3bb193ed9766124dd CRs-Fixed: 3015643 --- dp/inc/cdp_txrx_cmn_struct.h | 5 +++++ dp/wifi3.0/dp_main.c | 8 ++++++++ dp/wifi3.0/dp_rx_err.c | 37 ++++++++++++++++++++++++++++++++++++ dp/wifi3.0/dp_types.h | 8 ++++++++ 4 files changed, 58 insertions(+) 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;