qcacld-3.0: Add support for roaming in case of NUD failure

Add support for roaming in case the driver
detects a nud failure. The STA then would roam
to another BSSID, else if the roaming gets failed
the STA would remain connected to the same BSSID
as connected before.

Change-Id: Idbc99b0ce2f9cacd97564dd8cf9892120958eda2
CRs-Fixed: 2461675
Esse commit está contido em:
gaurank kathpalia
2019-05-29 19:41:25 +05:30
commit de nshrivas
commit 7ef7218496
18 arquivos alterados com 532 adições e 57 exclusões

Ver arquivo

@@ -121,6 +121,7 @@ struct blm_reject_ap_timestamp {
* @bad_bssid_counter: It represent how many times data stall happened.
* @ap_timestamp: Ap timestamp.
* @reject_ap_type: what is the type of rejection for the AP (avoid, black etc.)
* @connect_timestamp: Timestamp when the STA got connected with this BSSID
*/
struct blm_reject_ap {
qdf_list_node_t node;
@@ -139,6 +140,7 @@ struct blm_reject_ap {
};
uint8_t reject_ap_type;
};
qdf_time_t connect_timestamp;
};
/**
@@ -197,6 +199,25 @@ blm_add_userspace_black_list(struct wlan_objmgr_pdev *pdev,
struct qdf_mac_addr *bssid_black_list,
uint8_t num_of_bssid);
/**
* blm_update_bssid_connect_params() - Inform the BLM about connect/disconnect
* with the current AP.
* @pdev: pdev object
* @bssid: BSSID of the AP
* @con_state: Connection stae (connected/disconnected)
*
* This API will inform the BLM about the state with the AP so that if the AP
* is selected, and the connection went through, and the connection did not
* face any data stall till the bad bssid reset timer, BLM can remove the
* AP from the reject ap list maintained by it.
*
* Return: None
*/
void
blm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
struct qdf_mac_addr bssid,
enum blm_connection_state con_state);
/**
* blm_delete_reject_ap_list() - Clear away BSSID and destroy the reject ap list
* @blm_ctx: blacklist manager pdev priv object

Ver arquivo

@@ -300,6 +300,8 @@ blm_handle_avoid_list(struct blm_reject_ap *entry,
blm_debug("Added %pM to avoid list type %d, counter %d",
entry->bssid.bytes, ap_info->reject_ap_type,
entry->bad_bssid_counter);
entry->connect_timestamp = qdf_mc_timer_get_system_time();
}
static void
@@ -454,7 +456,14 @@ blm_is_oldest_entry(enum blm_reject_ap_type list_type,
{
switch (list_type) {
case DRIVER_RSSI_REJECT_TYPE:
if (cur_node_delta < oldest_node_delta)
/*
* For RSSI reject type, the lowest retry delay has to be found
* out hence if oldest_node_delta is 0, mean this is the first
* entry and thus return true, If oldest_node_delta is non
* zero, compare the delta and return true if the cur entry
* has lower retry delta.
*/
if (!oldest_node_delta || (cur_node_delta < oldest_node_delta))
return true;
break;
case USERSPACE_AVOID_TYPE:
@@ -483,17 +492,6 @@ blm_try_delete_bssid_in_list(qdf_list_t *reject_ap_list,
qdf_time_t oldest_node_delta = 0;
qdf_time_t cur_node_delta = 0;
/*
* For RSSI reject type, the lowest retry delay has to be found out,
* hence for reference oldest node delta should be max, and then the
* first entry entry would always be less than oldest entry delta. For
* every other case the delta is the current timestamp minus the time
* when the AP was added, hence it has to be maximum, so a greater than
* check has to be there, so the oldest node delta should be minimum.
*/
if (list_type == DRIVER_RSSI_REJECT_TYPE)
oldest_node_delta = 0xFFFFFFFFFFFFFFFF;
qdf_list_peek_front(reject_ap_list, &cur_node);
while (cur_node) {
@@ -641,7 +639,7 @@ blm_send_reject_ap_list_to_fw(struct wlan_objmgr_pdev *pdev,
struct blm_config *cfg)
{
QDF_STATUS status;
struct reject_ap_params reject_params;
struct reject_ap_params reject_params = {0};
reject_params.bssid_list =
qdf_mem_malloc(sizeof(*reject_params.bssid_list) *
@@ -699,7 +697,7 @@ blm_add_bssid_to_reject_list(struct wlan_objmgr_pdev *pdev,
blm_ctx = blm_get_pdev_obj(pdev);
blm_psoc_obj = blm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
if (!blm_ctx || blm_psoc_obj) {
if (!blm_ctx || !blm_psoc_obj) {
blm_err("blm_ctx or blm_psoc_obj is NULL");
return QDF_STATUS_E_INVAL;
}
@@ -893,7 +891,7 @@ blm_get_bssid_reject_list(struct wlan_objmgr_pdev *pdev,
blm_ctx = blm_get_pdev_obj(pdev);
blm_psoc_obj = blm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
if (!blm_ctx || blm_psoc_obj) {
if (!blm_ctx || !blm_psoc_obj) {
blm_err("blm_ctx or blm_psoc_obj is NULL");
return 0;
}
@@ -912,3 +910,77 @@ blm_get_bssid_reject_list(struct wlan_objmgr_pdev *pdev,
return num_of_reject_bssid;
}
void
blm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
struct qdf_mac_addr bssid,
enum blm_connection_state con_state)
{
struct blm_pdev_priv_obj *blm_ctx;
struct blm_psoc_priv_obj *blm_psoc_obj;
qdf_list_node_t *cur_node = NULL, *next_node = NULL;
QDF_STATUS status;
struct blm_reject_ap *blm_entry = NULL;
qdf_time_t connection_age = 0;
bool entry_found = false;
blm_ctx = blm_get_pdev_obj(pdev);
blm_psoc_obj = blm_get_psoc_obj(wlan_pdev_get_psoc(pdev));
if (!blm_ctx || !blm_psoc_obj) {
blm_err("blm_ctx or blm_psoc_obj is NULL");
return;
}
status = qdf_mutex_acquire(&blm_ctx->reject_ap_list_lock);
if (QDF_IS_STATUS_ERROR(status)) {
blm_err("failed to acquire reject_ap_list_lock");
return;
}
qdf_list_peek_front(&blm_ctx->reject_ap_list, &cur_node);
while (cur_node) {
qdf_list_peek_next(&blm_ctx->reject_ap_list, cur_node,
&next_node);
blm_entry = qdf_container_of(cur_node, struct blm_reject_ap,
node);
if (!qdf_mem_cmp(blm_entry->bssid.bytes, bssid.bytes,
QDF_MAC_ADDR_SIZE)) {
blm_debug("%pM present in BLM reject list, updating connect info",
blm_entry->bssid.bytes);
entry_found = true;
break;
}
cur_node = next_node;
next_node = NULL;
}
/* This means that the BSSID was not added in the reject list of BLM */
if (!entry_found) {
qdf_mutex_release(&blm_ctx->reject_ap_list_lock);
return;
}
switch (con_state) {
case BLM_AP_CONNECTED:
blm_entry->connect_timestamp = qdf_mc_timer_get_system_time();
break;
case BLM_AP_DISCONNECTED:
connection_age = qdf_mc_timer_get_system_time() -
blm_entry->connect_timestamp;
if (connection_age >
blm_psoc_obj->blm_cfg.bad_bssid_counter_reset_time) {
blm_debug("Bad Bssid timer expired, removed %pM from list",
blm_entry->bssid.bytes);
qdf_list_remove_node(&blm_ctx->reject_ap_list,
&blm_entry->node);
qdf_mem_free(blm_entry);
}
break;
default:
blm_debug("Invalid AP connection state recevied %d", con_state);
};
qdf_mutex_release(&blm_ctx->reject_ap_list_lock);
}

Ver arquivo

@@ -56,6 +56,16 @@ enum blm_reject_ap_type {
DRIVER_MONITOR_TYPE = 5
};
/**
* enum blm_connection_state - State with AP (Connected, Disconnected)
* @BLM_AP_CONNECTED: Connected with the AP
* @BLM_AP_DISCONNECTED: Disconnected with the AP
*/
enum blm_connection_state {
BLM_AP_CONNECTED,
BLM_AP_DISCONNECTED,
};
/**
* struct reject_ap_config_params - Structure to send reject ap list to FW
* @bssid: BSSID of the AP

Ver arquivo

@@ -83,6 +83,25 @@ ucfg_blm_add_userspace_black_list(struct wlan_objmgr_pdev *pdev,
struct qdf_mac_addr *bssid_black_list,
uint8_t num_of_bssid);
/**
* ucfg_blm_update_bssid_connect_params() - Inform the BLM about connect or
* disconnect with the current AP.
* @pdev: pdev object
* @bssid: BSSID of the AP
* @con_state: Connection stae (connected/disconnected)
*
* This API will inform the BLM about the state with the AP so that if the AP
* is selected, and the connection went through, and the connection did not
* face any data stall till the bad bssid reset timer, BLM can remove the
* AP from the reject ap list maintained by it.
*
* Return: None
*/
void
ucfg_blm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
struct qdf_mac_addr bssid,
enum blm_connection_state con_state);
/**
* ucfg_blm_add_bssid_to_reject_list() - Add BSSID to the specific reject list.
* @pdev: Pdev object
@@ -137,5 +156,13 @@ ucfg_blm_add_userspace_black_list(struct wlan_objmgr_pdev *pdev,
{
return QDF_STATUS_SUCCESS;
}
static inline void
ucfg_blm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
struct qdf_mac_addr bssid,
enum blm_connection_state con_state)
{
}
#endif
#endif /* _WLAN_BLM_UCFG_H_ */

Ver arquivo

@@ -130,3 +130,11 @@ ucfg_blm_add_userspace_black_list(struct wlan_objmgr_pdev *pdev,
return blm_add_userspace_black_list(pdev, bssid_black_list,
num_of_bssid);
}
void
ucfg_blm_update_bssid_connect_params(struct wlan_objmgr_pdev *pdev,
struct qdf_mac_addr bssid,
enum blm_connection_state con_state)
{
blm_update_bssid_connect_params(pdev, bssid, con_state);
}

Ver arquivo

@@ -75,6 +75,7 @@ enum vdev_assoc_type {
* @dynamic_cfg: current configuration of nss, chains for vdev.
* @ini_cfg: Max configuration of nss, chains supported for vdev.
* @sta_dynamic_oce_value: Dyanmic oce flags value for sta
* @roam_invoke_params: Roam invoke params
*/
struct mlme_legacy_priv {
bool chan_switch_in_progress;
@@ -86,6 +87,7 @@ struct mlme_legacy_priv {
struct wlan_mlme_nss_chains dynamic_cfg;
struct wlan_mlme_nss_chains ini_cfg;
uint8_t sta_dynamic_oce_value;
struct mlme_roam_after_data_stall roam_invoke_params;
};
#ifndef CRYPTO_SET_KEY_CONVERGED
@@ -200,6 +202,15 @@ struct wlan_mlme_nss_chains *mlme_get_dynamic_vdev_config(
struct wlan_mlme_nss_chains *mlme_get_ini_vdev_config(
struct wlan_objmgr_vdev *vdev);
/**
* mlme_get_roam_invoke_params() - get the roam invoke params
* @vdev: vdev pointer
*
* Return: pointer to the vdev roam invoke config structure
*/
struct mlme_roam_after_data_stall *
mlme_get_roam_invoke_params(struct wlan_objmgr_vdev *vdev);
/**
* mlme_psoc_object_created_notification(): mlme psoc create handler
* @psoc: psoc which is going to created by objmgr

Ver arquivo

@@ -78,6 +78,21 @@ struct wlan_mlme_nss_chains *mlme_get_ini_vdev_config(
return &mlme_priv->ini_cfg;
}
struct mlme_roam_after_data_stall *
mlme_get_roam_invoke_params(struct wlan_objmgr_vdev *vdev)
{
struct vdev_mlme_obj *vdev_mlme;
struct mlme_legacy_priv *mlme_priv;
vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
if (!vdev_mlme)
return NULL;
mlme_priv = vdev_mlme->ext_vdev_ptr;
return &mlme_priv->roam_invoke_params;
}
uint8_t *mlme_get_dynamic_oce_flags(struct wlan_objmgr_vdev *vdev)
{
struct vdev_mlme_obj *vdev_mlme;

Ver arquivo

@@ -62,6 +62,17 @@ QDF_STATUS wlan_mlme_set_cfg_str(uint8_t *src, struct mlme_cfg_str *dst_cfg_str,
QDF_STATUS wlan_mlme_get_edca_params(struct wlan_mlme_edca_params *edca_params,
uint8_t *data, enum e_edca_type edca_ac);
/**
* wlan_mlme_update_cfg_with_tgt_caps() - Update mlme cfg with tgt caps
* @psoc: pointer to psoc object
* @tgt_caps: Pointer to the mlme related capability structure
*
* Return: None
*/
void
wlan_mlme_update_cfg_with_tgt_caps(struct wlan_objmgr_psoc *psoc,
struct mlme_tgt_caps *tgt_caps);
/*
* mlme_get_wep_key() - get the wep key to process during auth frame
* @vdev: VDEV object for which the wep key is being requested

Ver arquivo

@@ -189,6 +189,26 @@ struct wlan_mlme_dot11_mode {
enum mlme_dot11_mode dot11_mode;
};
/**
* enum roam_invoke_source_entity - Source of invoking roam invoke command.
* @USERSPACE_INITIATED: Userspace (supplicant)
* @CONNECTION_MGR_INITIATED: connection mgr initiated.
*/
enum roam_invoke_source_entity {
USERSPACE_INITIATED,
CONNECTION_MGR_INITIATED,
};
/**
* struct mlme_roam_after_data_stall - roam invoke entity params
* @roam_invoke_in_progress: is roaming already in progress.
* @source: source of the roam invoke command.
*/
struct mlme_roam_after_data_stall {
bool roam_invoke_in_progress;
enum roam_invoke_source_entity source;
};
/**
* struct mlme_edca_ac_vi - cwmin, cwmax and aifs value for edca_ac_vi
*
@@ -865,6 +885,17 @@ struct wlan_mlme_chain_cfg {
uint8_t max_rx_chains_5g;
};
/**
* struct mlme_tgt_caps - mlme related capability coming from target (FW)
* @data_stall_recovery_fw_support: does target supports data stall recovery.
*
* Add all the mlme-tgt related capablities here, and the public API would fill
* the related capability in the required mlme cfg structure.
*/
struct mlme_tgt_caps {
bool data_stall_recovery_fw_support;
};
/**
* struct wlan_mlme_rates - RATES related config items
* @cfpPeriod: cfp period info
@@ -1029,6 +1060,7 @@ struct wlan_mlme_chainmask {
* @enabled_11d: enable 11d flag
* @enable_beacon_reception_stats: enable beacon reception stats
* @enable_remove_time_stamp_sync_cmd: Enable remove time stamp sync cmd
* @data_stall_recovery_fw_support: whether FW supports Data stall recovery.
* @enable_change_channel_bandwidth: enable/disable change channel bw in mission
* mode
*/
@@ -1059,6 +1091,7 @@ struct wlan_mlme_generic {
bool enable_deauth_to_disassoc_map;
bool enable_beacon_reception_stats;
bool enable_remove_time_stamp_sync_cmd;
bool data_stall_recovery_fw_support;
bool enable_change_channel_bandwidth;
};

Ver arquivo

@@ -440,6 +440,22 @@ QDF_STATUS wlan_mlme_get_tx_chainmask_1ss(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_SUCCESS;
}
void
wlan_mlme_update_cfg_with_tgt_caps(struct wlan_objmgr_psoc *psoc,
struct mlme_tgt_caps *tgt_caps)
{
struct wlan_mlme_psoc_obj *mlme_obj;
mlme_obj = mlme_get_psoc_obj(psoc);
if (!mlme_obj)
return;
/* Update the mlme cfg according to the tgt capability received */
mlme_obj->cfg.gen.data_stall_recovery_fw_support =
tgt_caps->data_stall_recovery_fw_support;
}
#ifdef WLAN_FEATURE_11AX
QDF_STATUS wlan_mlme_cfg_get_he_ul_mumimo(struct wlan_objmgr_psoc *psoc,
uint32_t *value)