qcacld-3.0: Disable Tx Queues upon sta kick out event

Upon receiving a STA kick out event or a beacon miss event,
disable the Tx Queues immediately so that there is no influx
of packets anymore as the STA is going to disconnect further.

Change-Id: Ic6d7a3acbd8b90aec68771c1520359d39e0534db
CRs-Fixed: 2171633
This commit is contained in:
Varun Reddy Yeturu 2018-01-16 12:16:14 -08:00 • committed by snandini
commit 076eaa810d
10 changed files with 120 additions and 6 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@ -66,6 +66,19 @@ QDF_STATUS hdd_get_peer_sta_id(struct hdd_station_ctx *sta_ctx,
struct qdf_mac_addr *peer_mac_addr,
uint8_t *sta_id);
/**
* hdd_tx_queue_cb() - Disable/Enable the Transmit Queues
* @context: HDD context
* @vdev_id: vdev id
* @action: Action to be taken on the Tx Queues
* @reason: Reason for the netif action
*
* Return: None
*/
void hdd_tx_queue_cb(void *context, uint32_t vdev_id,
enum netif_action_type action,
enum netif_reason_type reason);
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
void hdd_tx_resume_cb(void *adapter_context, bool tx_resume);

View file

@ -10650,6 +10650,11 @@ int hdd_register_cb(struct hdd_context *hdd_ctx)
if (!QDF_IS_STATUS_SUCCESS(status))
hdd_err("set bt activity info callback failed");
status = sme_register_tx_queue_cb(hdd_ctx->hHal,
hdd_tx_queue_cb);
if (!QDF_IS_STATUS_SUCCESS(status))
hdd_err("Register tx queue callback failed");
EXIT();
return ret;
@ -10670,6 +10675,7 @@ void hdd_deregister_cb(struct hdd_context *hdd_ctx)
ENTER();
sme_deregister_tx_queue_cb(hdd_ctx->hHal);
status = sme_deregister_for_dcc_stats_event(hdd_ctx->hHal);
if (!QDF_IS_STATUS_SUCCESS(status))
hdd_err("De-register of dcc stats callback failed: %d",

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@ -1893,6 +1893,35 @@ void hdd_send_rps_disable_ind(struct hdd_adapter *adapter)
cds_cfg->rps_enabled = false;
}
void hdd_tx_queue_cb(void *context, uint32_t vdev_id,
enum netif_action_type action,
enum netif_reason_type reason)
{
struct hdd_context *hdd_ctx = (struct hdd_context *)context;
struct hdd_adapter *adapter = NULL;
/*
* Validating the context is not required here.
* if there is a driver unload/SSR in progress happening in a
* different context and it has been scheduled to run and
* driver got a firmware event of sta kick out, then it is
* good to disable the Tx Queue to stop the influx of traffic.
*/
if (hdd_ctx == NULL) {
hdd_err("Invalid context passed");
return;
}
adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
if (adapter == NULL) {
hdd_err("vdev_id %d does not exist with host", vdev_id);
return;
}
hdd_debug("Tx Queue action %d on vdev %d", action, vdev_id);
wlan_hdd_netif_queue_control(adapter, action, reason);
}
#ifdef MSM_PLATFORM
/**
* hdd_reset_tcp_delack() - Reset tcp delack value to default

View file

@ -485,15 +485,16 @@ void lim_handle_heart_beat_failure(tpAniSirGlobal mac_ctx,
(session->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) &&
(session->limSmeState != eLIM_SME_WT_DISASSOC_STATE) &&
(session->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) {
if (!mac_ctx->sys.gSysEnableLinkMonitorMode)
return;
if (!mac_ctx->sys.gSysEnableLinkMonitorMode) {
goto hb_handler_fail;
}
/* Ignore HB if channel switch is in progress */
if (session->gLimSpecMgmt.dot11hChanSwState ==
eLIM_11H_CHANSW_RUNNING) {
pe_debug("Ignore Heartbeat failure as Channel switch is in progress");
session->pmmOffloadInfo.bcnmiss = false;
return;
goto hb_handler_fail;
}
/* Beacon frame not received within heartbeat timeout. */
pe_warn("Heartbeat Failure");
@ -561,4 +562,10 @@ void lim_handle_heart_beat_failure(tpAniSirGlobal mac_ctx,
lim_print_mlm_state(mac_ctx, LOG1, session->limMlmState);
mac_ctx->lim.gLimHBfailureCntInOtherStates++;
}
hb_handler_fail:
if (mac_ctx->sme.tx_queue_cb)
mac_ctx->sme.tx_queue_cb(mac_ctx->hHdd, session->smeSessionId,
WLAN_WAKE_ALL_NETIF_QUEUE,
WLAN_CONTROL_PATH);
}

View file

@ -1715,7 +1715,6 @@ static void lim_process_messages(tpAniSirGlobal mac_ctx,
case SIR_LIM_PROBE_HB_FAILURE_TIMEOUT:
lim_handle_heart_beat_failure_timeout(mac_ctx);
break;
break;
case SIR_LIM_CNF_WAIT_TIMEOUT:
/* Does not receive CNF or dummy packet */
lim_handle_cnf_wait_timeout(mac_ctx, (uint16_t) msg->bodyval);

View file

@ -5546,6 +5546,11 @@ void lim_handle_heart_beat_failure_timeout(tpAniSirGlobal mac_ctx)
pe_err("Unexpected wt-probe-timeout in state");
lim_print_mlm_state(mac_ctx, LOGE,
psession_entry->limMlmState);
if (mac_ctx->sme.tx_queue_cb)
mac_ctx->sme.tx_queue_cb(mac_ctx->hHdd,
psession_entry->smeSessionId,
WLAN_WAKE_ALL_NETIF_QUEUE,
WLAN_CONTROL_PATH);
}
}
/*

View file

@ -1561,6 +1561,27 @@ QDF_STATUS sme_fast_reassoc(tHalHandle hal, tCsrRoamProfile *profile,
QDF_STATUS sme_congestion_register_callback(tHalHandle hal,
void (*congestion_cb)(void *, uint32_t congestion, uint32_t vdev_id));
/**
* sme_register_tx_queue_cb(): Register tx queue callback
* @hal: handler for HAL
* @tx_queue_cb: Transmit Queues callback
*
* Return: QDF_STATUS
*/
QDF_STATUS sme_register_tx_queue_cb(tHalHandle hal,
void (*tx_queue_cb)(void *,
uint32_t vdev_id,
enum netif_action_type action,
enum netif_reason_type reason));
/**
* sme_deregister_tx_queue_cb() - Deregister the tx queue callback
* @hal: HAL handle
*
* Return: QDF status
*/
QDF_STATUS sme_deregister_tx_queue_cb(tHalHandle hal);
/**
* sme_rso_cmd_status_cb() - Set RSO cmd status callback
* @hal: HAL Handle

View file

@ -264,6 +264,9 @@ typedef struct tagSmeStruct {
void (*get_arp_stats_cb)(void *, struct rsp_stats *);
get_chain_rssi_callback get_chain_rssi_cb;
void *get_chain_rssi_context;
void (*tx_queue_cb)(void *, uint32_t vdev_id,
enum netif_action_type action,
enum netif_reason_type reason);
} tSmeStruct, *tpSmeStruct;
#endif /* #if !defined( __SMEINTERNAL_H ) */

View file

@ -15499,6 +15499,32 @@ QDF_STATUS sme_congestion_register_callback(tHalHandle hal,
return status;
}
QDF_STATUS sme_register_tx_queue_cb(tHalHandle hal,
void (*tx_queue_cb)(void *,
uint32_t vdev_id,
enum netif_action_type action,
enum netif_reason_type reason))
{
QDF_STATUS status;
tpAniSirGlobal mac = PMAC_STRUCT(hal);
status = sme_acquire_global_lock(&mac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
mac->sme.tx_queue_cb = tx_queue_cb;
sme_release_global_lock(&mac->sme);
sme_debug("Tx queue callback set");
} else {
sme_err("Aquiring lock failed %d", status);
}
return status;
}
QDF_STATUS sme_deregister_tx_queue_cb(tHalHandle hal)
{
return sme_register_tx_queue_cb(hal, NULL);
}
QDF_STATUS sme_set_smps_cfg(uint32_t vdev_id, uint32_t param_id,
uint32_t param_val)
{

View file

@ -2772,6 +2772,7 @@ void wma_set_keepalive_req(tp_wma_handle wma,
void wma_beacon_miss_handler(tp_wma_handle wma, uint32_t vdev_id, int32_t rssi)
{
tSirSmeMissedBeaconInd *beacon_miss_ind;
tpAniSirGlobal mac = cds_get_context(QDF_MODULE_ID_PE);
beacon_miss_ind = (tSirSmeMissedBeaconInd *) qdf_mem_malloc
(sizeof(tSirSmeMissedBeaconInd));
@ -2780,6 +2781,10 @@ void wma_beacon_miss_handler(tp_wma_handle wma, uint32_t vdev_id, int32_t rssi)
WMA_LOGE("%s: Memory allocation failure", __func__);
return;
}
if (mac && mac->sme.tx_queue_cb)
mac->sme.tx_queue_cb(mac->hHdd, vdev_id,
WLAN_STOP_ALL_NETIF_QUEUE,
WLAN_CONTROL_PATH);
beacon_miss_ind->messageType = WMA_MISSED_BEACON_IND;
beacon_miss_ind->length = sizeof(tSirSmeMissedBeaconInd);
beacon_miss_ind->bssIdx = vdev_id;