From 032e69194a501e26347c6e08d262cd6c3a9b8293 Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Mon, 28 Sep 2020 22:37:43 +0530 Subject: [PATCH] qcacld-3.0: Enable host optimization for latency based on WLM mode Enable host optimization for latency based on WLM mode and ini configuration. Change-Id: I67f49493f623287d0e420dab379d2d0116603ced CRs-Fixed: 2789141 --- components/mlme/core/src/wlan_mlme_main.c | 8 + .../mlme/dispatcher/inc/cfg_mlme_fe_wlm.h | 193 +++++++++++++++++- .../dispatcher/inc/wlan_mlme_public_struct.h | 2 + .../mlme/dispatcher/inc/wlan_mlme_ucfg_api.h | 23 +++ .../mlme/dispatcher/src/wlan_mlme_ucfg_api.c | 31 +++ core/hdd/inc/wlan_hdd_main.h | 4 + core/hdd/src/wlan_hdd_assoc.c | 2 + core/hdd/src/wlan_hdd_cfg80211.c | 51 +++++ core/hdd/src/wlan_hdd_main.c | 4 +- core/hdd/src/wlan_hdd_softap_tx_rx.c | 1 + core/hdd/src/wlan_hdd_tx_rx.c | 14 +- 11 files changed, 322 insertions(+), 11 deletions(-) diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index 2d3aa2e6f2..5412a11f06 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -2164,6 +2164,14 @@ static void mlme_init_fe_wlm_in_cfg(struct wlan_objmgr_psoc *psoc, wlm_config->latency_flags[1] = cfg_get(psoc, CFG_LATENCY_FLAGS_MOD); wlm_config->latency_flags[2] = cfg_get(psoc, CFG_LATENCY_FLAGS_LOW); wlm_config->latency_flags[3] = cfg_get(psoc, CFG_LATENCY_FLAGS_ULTLOW); + wlm_config->latency_host_flags[0] = + cfg_get(psoc, CFG_LATENCY_HOST_FLAGS_NORMAL); + wlm_config->latency_host_flags[1] = + cfg_get(psoc, CFG_LATENCY_HOST_FLAGS_MOD); + wlm_config->latency_host_flags[2] = + cfg_get(psoc, CFG_LATENCY_HOST_FLAGS_LOW); + wlm_config->latency_host_flags[3] = + cfg_get(psoc, CFG_LATENCY_HOST_FLAGS_ULTLOW); } /** diff --git a/components/mlme/dispatcher/inc/cfg_mlme_fe_wlm.h b/components/mlme/dispatcher/inc/cfg_mlme_fe_wlm.h index c9411b03c1..66a1de0c07 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_fe_wlm.h +++ b/components/mlme/dispatcher/inc/cfg_mlme_fe_wlm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,6 +23,29 @@ #ifndef __CFG_MLME_FE_WLM_H #define __CFG_MLME_FE_WLM_H +/* + * |31 18| 17 | 16 |15 8|7 2| 1 | 0 | + * +------+------+--------+-----------+------+----------+-----------+ + * | RSVD | HBB | PM-QOS | RSVD | RSVD | REO Ring | RX Thread | + * +------+------+--------+-----------+------+----------+-----------+ + * | common | TX Path | RX Path | + * + * bit 0-7: Rx path related optimization + * bit 0: disable rx_thread for vdev + * bit 1: Reduce REO ring timer threshold to 32us(applicable for all REO ring) + * bit 2-7: Reserved + * bit 8-15: Tx path related optimization + * bit 8-15: Reserved + * bit 16-31: common changes + * bit 16: Request for pm_qos vote + * bit 17: Request for high ddr bus bandwidth + */ + +#define WLM_HOST_RX_THREAD_FLAG (1 << 0) +#define WLM_HOST_REO_RING_FLAG (1 << 1) +#define WLM_HOST_PM_QOS_FLAG (1 << 16) +#define WLM_HOST_HBB_FLAG (1 << 17) + /* * * wlm_latency_enable - WLM latency Enable @@ -69,7 +92,7 @@ * * @min: 0x0 * @max: 0xffffffff - * @defalut: 0x0 + * @default: 0x0 * * |31 12| 11 | 10 |9 8|7 6|5 4|3 2| 1 | 0 | * +------+------+------+------+------+------+------+-----+-----+ @@ -112,7 +135,7 @@ * * @min: 0x0 * @max: 0xffffffff - * @defalut: 0x8 + * @default: 0x8 * * |31 12| 11 | 10 |9 8|7 6|5 4|3 2| 1 | 0 | * +------+------+------+------+------+------+------+-----+-----+ @@ -155,7 +178,7 @@ * * @min: 0x0 * @max: 0xffffffff - * @defalut: 0xa + * @default: 0xa * * |31 12| 11 | 10 |9 8|7 6|5 4|3 2| 1 | 0 | * +------+------+------+------+------+------+------+-----+-----+ @@ -198,7 +221,7 @@ * * @min: 0x0 * @max: 0xffffffff - * @defalut: 0xc83 + * @default: 0xc83 * * |31 12| 11 | 10 |9 8|7 6|5 4|3 2| 1 | 0 | * +------+------+------+------+------+------+------+-----+-----+ @@ -235,12 +258,170 @@ CFG_VALUE_OR_DEFAULT, \ "WLM flags for ultralow level") +/* + * + * wlm_latency_host_flags_normal - WLM Host flags setting for normal level + * + * @min: 0x0 + * @max: 0xffffffff + * @default: 0x0 + * + * This ini decides which host latency features gets enabled + * in normal latency mode. + * + * Usage: External + * + * |31 18| 17 | 16 |15 8|7 2| 1 | 0 | + * +------+------+--------+-----------+------+----------+-----------+ + * | RSVD | HBB | PM-QOS | RSVD | RSVD | REO Ring | RX Thread | + * +------+------+--------+-----------+------+----------+-----------+ + * | common | TX Path | RX Path | + * + * bit 0-7: Rx path related optimization + * bit 0: disable rx_thread for vdev + * bit 1: Reduce REO ring timer threshold to 32us(applicable for all REO ring) + * bit 2-7: Reserved + * bit 8-15: Tx path related optimization + * bit 8-15: Reserved + * bit 16-31: common changes + * bit 16: Request for pm_qos vote + * bit 17: Request for high ddr bus bandwidth + * + * + */ +#define CFG_LATENCY_HOST_FLAGS_NORMAL \ + CFG_INI_UINT("wlm_latency_host_flags_normal",\ + 0, \ + 0xffffffff, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "WLM Host flags for normal level") + +/* + * + * wlm_latency_host_flags_moderate - WLM Host flags setting for moderate level + * + * @min: 0x0 + * @max: 0xffffffff + * @default: 0x0 + * + * This ini decides which host latency features gets enabled + * in moderate latency mode. + * + * Usage: External + * + * |31 18| 17 | 16 |15 8|7 2| 1 | 0 | + * +------+------+--------+-----------+------+----------+-----------+ + * | RSVD | HBB | PM-QOS | RSVD | RSVD | REO Ring | RX Thread | + * +------+------+--------+-----------+------+----------+-----------+ + * | common | TX Path | RX Path | + * + * bit 0-7: Rx path related optimization + * bit 0: disable rx_thread for vdev + * bit 1: Reduce REO ring timer threshold to 32us(applicable for all REO ring) + * bit 2-7: Reserved + * bit 8-15: Tx path related optimization + * bit 8-15: Reserved + * bit 16-31: common changes + * bit 16: Request for pm_qos vote + * bit 17: Request for high ddr bus bandwidth + * + * + */ +#define CFG_LATENCY_HOST_FLAGS_MOD \ + CFG_INI_UINT("wlm_latency_host_flags_moderate",\ + 0, \ + 0xffffffff, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "WLM Host flags for moderate level") +/* + * + * wlm_latency_host_flags_low - WLM Host flags setting for low level + * + * @min: 0x0 + * @max: 0xffffffff + * @default: 0x0 + * + * This ini decides which host latency features gets enabled + * in low latency mode. + * + * Usage: External + * + * |31 18| 17 | 16 |15 8|7 2| 1 | 0 | + * +------+------+--------+-----------+------+----------+-----------+ + * | RSVD | HBB | PM-QOS | RSVD | RSVD | REO Ring | RX Thread | + * +------+------+--------+-----------+------+----------+-----------+ + * | common | TX Path | RX Path | + * + * bit 0-7: Rx path related optimization + * bit 0: disable rx_thread for vdev + * bit 1: Reduce REO ring timer threshold to 32us(applicable for all REO ring) + * bit 2-7: Reserved + * bit 8-15: Tx path related optimization + * bit 8-15: Reserved + * bit 16-31: common changes + * bit 16: Request for pm_qos vote + * bit 17: Request for high ddr bus bandwidth + * + * + */ +#define CFG_LATENCY_HOST_FLAGS_LOW CFG_INI_UINT("wlm_latency_host_flags_low",\ + 0, \ + 0xffffffff, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "WLM Host flags for low level") + +/* + * + * wlm_latency_host_flags_ultralow - WLM Host flags setting for ultralow level + * + * @min: 0x0 + * @max: 0xffffffff + * @default: 0x0 + * + * This ini decides which host latency features gets enabled + * in ultra low latency mode. + * + * Usage: External + * + * |31 18| 17 | 16 |15 8|7 2| 1 | 0 | + * +------+------+--------+-----------+------+----------+-----------+ + * | RSVD | HBB | PM-QOS | RSVD | RSVD | REO Ring | RX Thread | + * +------+------+--------+-----------+------+----------+-----------+ + * | common | TX Path | RX Path | + * + * bit 0-7: Rx path related optimization + * bit 0: disable rx_thread for vdev + * bit 1: Reduce REO ring timer threshold to 32us(applicable for all REO ring) + * bit 2-7: Reserved + * bit 8-15: Tx path related optimization + * bit 8-15: Reserved + * bit 16-31: common changes + * bit 16: Request for pm_qos vote + * bit 17: Request for high ddr bus bandwidth + * + * + */ +#define CFG_LATENCY_HOST_FLAGS_ULTLOW \ + CFG_INI_UINT("wlm_latency_host_flags_ultralow",\ + 0, \ + 0xffffffff, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "WLM Host flags for ultralow level") + #define CFG_FE_WLM_ALL \ CFG(CFG_LATENCY_ENABLE) \ CFG(CFG_LATENCY_LEVEL) \ CFG(CFG_LATENCY_FLAGS_NORMAL) \ CFG(CFG_LATENCY_FLAGS_MOD) \ CFG(CFG_LATENCY_FLAGS_LOW) \ - CFG(CFG_LATENCY_FLAGS_ULTLOW) + CFG(CFG_LATENCY_FLAGS_ULTLOW) \ + CFG(CFG_LATENCY_HOST_FLAGS_NORMAL) \ + CFG(CFG_LATENCY_HOST_FLAGS_MOD) \ + CFG(CFG_LATENCY_HOST_FLAGS_LOW) \ + CFG(CFG_LATENCY_HOST_FLAGS_ULTLOW) #endif /* __CFG_MLME_FE_WLM_H */ diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 2f459a3961..1481d5d137 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -2212,11 +2212,13 @@ struct wlan_mlme_btm { * @latency_enable: Flag to check if latency is enabled * @latency_level: WLM latency level * @latency_flags: WLM latency flags setting + * @latency_host_flags: WLM latency host flags setting */ struct wlan_mlme_fe_wlm { bool latency_enable; uint8_t latency_level; uint32_t latency_flags[MLME_NUM_WLM_LATENCY_LEVEL]; + uint32_t latency_host_flags[MLME_NUM_WLM_LATENCY_LEVEL]; }; /** diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 2ba2180df0..927c4e0284 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -3617,6 +3617,29 @@ QDF_STATUS ucfg_wlan_mlme_get_rrm_enabled(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_mlme_get_latency_enable(struct wlan_objmgr_psoc *psoc, bool *value); +/** + * ucfg_mlme_get_latency_level() - Get the latency level + * @psoc: pointer to psoc object + * @value: Value that needs to be get from the caller + * latency values are defined in WMI_WLM_LATENCY_LEVEL + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_latency_level(struct wlan_objmgr_psoc *psoc, uint8_t *value); + +/** + * ucfg_mlme_get_latency_host_flags() - Get host flags for latency level + * @psoc: pointer to psoc object + * @latency_level: latency level + * @value: Value that needs to be get from the caller + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_latency_host_flags(struct wlan_objmgr_psoc *psoc, + uint8_t latency_level, uint32_t *value); + /** * ucfg_mlme_get_dtim_selection_diversity() - get dtim selection diversity * bitmap diff --git a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c index 46770aa948..33e39cb7f1 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c @@ -1366,6 +1366,37 @@ ucfg_mlme_get_latency_enable(struct wlan_objmgr_psoc *psoc, bool *value) return QDF_STATUS_SUCCESS; } +QDF_STATUS +ucfg_mlme_get_latency_level(struct wlan_objmgr_psoc *psoc, uint8_t *value) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + mlme_legacy_err("mlme obj null"); + return QDF_STATUS_E_INVAL; + } + + *value = mlme_obj->cfg.wlm_config.latency_level; + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_get_latency_host_flags(struct wlan_objmgr_psoc *psoc, + uint8_t latency_level, uint32_t *value) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + mlme_legacy_err("mlme obj null"); + return QDF_STATUS_E_INVAL; + } + + *value = mlme_obj->cfg.wlm_config.latency_host_flags[latency_level]; + return QDF_STATUS_SUCCESS; +} + #ifdef MWS_COEX QDF_STATUS ucfg_mlme_get_mws_coex_4g_quick_tdm(struct wlan_objmgr_psoc *psoc, diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 70df7a0e48..d604ca0ca1 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1424,6 +1424,8 @@ struct hdd_adapter { uint8_t gro_disallowed[DP_MAX_RX_THREADS]; uint8_t gro_flushed[DP_MAX_RX_THREADS]; bool handle_feature_update; + bool runtime_disable_rx_thread; + ol_txrx_rx_fp rx_stack; qdf_work_t netdev_features_update_work; }; @@ -2068,6 +2070,8 @@ struct hdd_context { #ifdef FW_THERMAL_THROTTLE_SUPPORT uint8_t dutycycle_off_percent; #endif + uint8_t pm_qos_request_flags; + uint8_t high_bus_bw_request; qdf_work_t country_change_work; struct { qdf_atomic_t rx_aggregation; diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 03c89a59f4..8261ecb4ca 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -2269,6 +2269,7 @@ QDF_STATUS hdd_roam_register_sta(struct hdd_adapter *adapter, txrx_ops.rx.rx_stack = hdd_rx_packet_cbk; txrx_ops.rx.rx_flush = hdd_rx_flush_packet_cbk; txrx_ops.rx.rx_gro_flush = hdd_rx_thread_gro_flush_ind_cbk; + adapter->rx_stack = hdd_rx_packet_cbk; } else { txrx_ops.rx.rx = hdd_rx_packet_cbk; txrx_ops.rx.rx_stack = NULL; @@ -3740,6 +3741,7 @@ QDF_STATUS hdd_roam_register_tdlssta(struct hdd_adapter *adapter, txrx_ops.rx.rx_stack = hdd_rx_packet_cbk; txrx_ops.rx.rx_flush = hdd_rx_flush_packet_cbk; txrx_ops.rx.rx_gro_flush = hdd_rx_thread_gro_flush_ind_cbk; + adapter->rx_stack = hdd_rx_packet_cbk; } else { txrx_ops.rx.rx = hdd_rx_packet_cbk; txrx_ops.rx.rx_stack = NULL; diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 3e8eedf16c..6a43468509 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -8165,12 +8165,53 @@ void wlan_hdd_set_wlm_mode(struct hdd_context *hdd_ctx, uint16_t latency_level) } #endif +/** + * hdd_set_wlm_host_latency_level() - set latency flags based on latency flags + * @hdd_ctx: hdd context + * @adapter: adapter context + * @latency_host_flags: host latency flags + * + * Return: none + */ +static void hdd_set_wlm_host_latency_level(struct hdd_context *hdd_ctx, + struct hdd_adapter *adapter, + uint32_t latency_host_flags) +{ + ol_txrx_soc_handle soc_hdl = cds_get_context(QDF_MODULE_ID_SOC); + + if (!soc_hdl) { + hdd_err("txrx soc handle NULL"); + return; + } + + if (latency_host_flags & WLM_HOST_PM_QOS_FLAG) + hdd_ctx->pm_qos_request_flags |= (1 << adapter->vdev_id); + else + hdd_ctx->pm_qos_request_flags &= ~(1 << adapter->vdev_id); + + if (hdd_ctx->pm_qos_request_flags) + wlan_hdd_set_pm_qos_request(hdd_ctx, true); + else + wlan_hdd_set_pm_qos_request(hdd_ctx, false); + + if (latency_host_flags & WLM_HOST_HBB_FLAG) + hdd_ctx->high_bus_bw_request |= (1 << adapter->vdev_id); + else + hdd_ctx->high_bus_bw_request &= ~(1 << adapter->vdev_id); + + if (latency_host_flags & WLM_HOST_RX_THREAD_FLAG) + adapter->runtime_disable_rx_thread = true; + else + adapter->runtime_disable_rx_thread = false; +} + static int hdd_config_latency_level(struct hdd_adapter *adapter, const struct nlattr *attr) { struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); uint16_t latency_level; QDF_STATUS status; + uint32_t latency_host_flags = 0; if (!hdd_is_wlm_latency_manager_supported(hdd_ctx)) return -ENOTSUPP; @@ -8194,6 +8235,16 @@ static int hdd_config_latency_level(struct hdd_adapter *adapter, * 0 - normal, 1 - moderate, 2 - low, 3 - ultralow */ adapter->latency_level = latency_level - 1; + + status = ucfg_mlme_get_latency_host_flags(hdd_ctx->psoc, + adapter->latency_level, + &latency_host_flags); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("failed to get latency host flags"); + else + hdd_set_wlm_host_latency_level(hdd_ctx, adapter, + latency_host_flags); + status = sme_set_wlm_latency_level(hdd_ctx->mac_handle, adapter->vdev_id, adapter->latency_level); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index d387a72b9d..134b8ec66e 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -9738,7 +9738,9 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx, cpumask_clear(&pm_qos_cpu_mask); - if (total_pkts > hdd_ctx->config->bus_bw_very_high_threshold) + if (hdd_ctx->high_bus_bw_request) + next_vote_level = PLD_BUS_WIDTH_VERY_HIGH; + else if (total_pkts > hdd_ctx->config->bus_bw_very_high_threshold) next_vote_level = PLD_BUS_WIDTH_VERY_HIGH; else if (total_pkts > hdd_ctx->config->bus_bw_high_threshold) next_vote_level = PLD_BUS_WIDTH_HIGH; diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c index 0b16fb36e7..ecc4656b58 100644 --- a/core/hdd/src/wlan_hdd_softap_tx_rx.c +++ b/core/hdd/src/wlan_hdd_softap_tx_rx.c @@ -1297,6 +1297,7 @@ QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter, txrx_ops.rx.rx_stack = hdd_softap_rx_packet_cbk; txrx_ops.rx.rx_flush = hdd_rx_flush_packet_cbk; txrx_ops.rx.rx_gro_flush = hdd_rx_thread_gro_flush_ind_cbk; + adapter->rx_stack = hdd_softap_rx_packet_cbk; } else { txrx_ops.rx.rx = hdd_softap_rx_packet_cbk; txrx_ops.rx.rx_stack = NULL; diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index 318a8478ef..5f6a2fdb74 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -2085,6 +2085,10 @@ QDF_STATUS hdd_rx_pkt_thread_enqueue_cbk(void *adapter, if (hdd_validate_adapter(hdd_adapter)) return QDF_STATUS_E_FAILURE; + if (hdd_adapter->runtime_disable_rx_thread && + hdd_adapter->rx_stack) + return hdd_adapter->rx_stack(adapter, nbuf_list); + vdev_id = hdd_adapter->vdev_id; head_ptr = nbuf_list; while (head_ptr) { @@ -2255,8 +2259,9 @@ QDF_STATUS hdd_rx_deliver_to_stack(struct hdd_adapter *adapter, /* Account for GRO/LRO ineligible packets, mostly UDP */ hdd_ctx->no_rx_offload_pkt_cnt++; - if (qdf_likely(hdd_ctx->enable_dp_rx_threads || - hdd_ctx->enable_rxthread)) { + if (qdf_likely((hdd_ctx->enable_dp_rx_threads || + hdd_ctx->enable_rxthread) && + !adapter->runtime_disable_rx_thread)) { local_bh_disable(); netif_status = netif_receive_skb(skb); local_bh_enable(); @@ -2312,8 +2317,9 @@ QDF_STATUS hdd_rx_deliver_to_stack(struct hdd_adapter *adapter, /* Account for GRO/LRO ineligible packets, mostly UDP */ hdd_ctx->no_rx_offload_pkt_cnt++; - if (qdf_likely(hdd_ctx->enable_dp_rx_threads || - hdd_ctx->enable_rxthread)) { + if (qdf_likely((hdd_ctx->enable_dp_rx_threads || + hdd_ctx->enable_rxthread) && + !adapter->runtime_disable_rx_thread)) { local_bh_disable(); netif_status = netif_receive_skb(skb); local_bh_enable();