qcacld-3.0: Add support of pmf comeback timer for SAE assoc retry

If STA DUT receives assoc response with assoc response status as
eSIR_MAC_TRY_AGAIN_LATER, host starts a pmf comeback timer to
send assoc request again on pmf comeback timer timeout.

Change-Id: Ifb28e44af86daef90db7146572cdfae26dfcaa20
CRs-Fixed: 2728459
Цей коміт міститься в:
Abhishek Ambure
2020-07-09 13:20:26 +05:30
зафіксовано nshrivas
джерело 91903a81ba
коміт 7c07f228f6
8 змінених файлів з 223 додано та 3 видалено

Переглянути файл

@@ -37,7 +37,8 @@ typedef struct sPowersaveoffloadInfo {
#ifdef WLAN_FEATURE_11W
struct comeback_timer_info {
struct mac_context *mac;
uint8_t session_id;
uint8_t vdev_id;
uint8_t retried;
tLimMlmStates lim_prev_mlm_state; /* Previous MLM State */
tLimMlmStates lim_mlm_state; /* MLM State */
};
@@ -476,6 +477,10 @@ struct pe_session {
/* Fast Transition (FT) */
tftPEContext ftPEContext;
bool isNonRoamReassoc;
#ifdef WLAN_FEATURE_11W
qdf_mc_timer_t pmf_retry_timer;
struct comeback_timer_info pmf_retry_timer_info;
#endif /* WLAN_FEATURE_11W */
uint8_t is_key_installed;
/* timer for resetting protection fileds at regular intervals */
qdf_mc_timer_t protection_fields_reset_timer;

Переглянути файл

@@ -592,6 +592,21 @@ static inline void lim_nan_register_callbacks(struct mac_context *mac_ctx)
}
#endif
#ifdef WLAN_FEATURE_11W
static void lim_stop_pmfcomeback_timer(struct pe_session *session)
{
if (session->opmode != QDF_STA_MODE)
return;
qdf_mc_timer_stop(&session->pmf_retry_timer);
session->pmf_retry_timer_info.retried = false;
}
#else
static void lim_stop_pmfcomeback_timer(struct pe_session *session)
{
}
#endif
/*
* pe_shutdown_notifier_cb - Shutdown notifier callback
* @ctx: Pointer to Global MAC structure
@@ -611,6 +626,7 @@ static void pe_shutdown_notifier_cb(void *ctx)
if (LIM_IS_AP_ROLE(session))
qdf_mc_timer_stop(&session->
protection_fields_reset_timer);
lim_stop_pmfcomeback_timer(session);
}
}
}

Переглянути файл

@@ -560,6 +560,68 @@ static inline void lim_process_he_info(tpSirProbeRespBeacon beacon,
}
#endif
#ifdef WLAN_FEATURE_11W
#define MAX_RETRY_TIMER 1500
static QDF_STATUS
lim_handle_pmfcomeback_timer(struct pe_session *session_entry,
tpSirAssocRsp assoc_rsp)
{
uint16_t timeout_value;
if (session_entry->opmode != QDF_STA_MODE)
return QDF_STATUS_E_FAILURE;
if (session_entry->limRmfEnabled &&
session_entry->pmf_retry_timer_info.retried &&
assoc_rsp->status_code == eSIR_MAC_TRY_AGAIN_LATER) {
pe_debug("Already retry in progress");
return QDF_STATUS_SUCCESS;
}
/*
* Handle association Response for sta mode with RMF enabled and TRY
* again later with timeout interval and Assoc comeback type
*/
if (!session_entry->limRmfEnabled || assoc_rsp->status_code !=
eSIR_MAC_TRY_AGAIN_LATER || !assoc_rsp->TimeoutInterval.present ||
assoc_rsp->TimeoutInterval.timeoutType !=
SIR_MAC_TI_TYPE_ASSOC_COMEBACK ||
session_entry->pmf_retry_timer_info.retried)
return QDF_STATUS_E_FAILURE;
timeout_value = assoc_rsp->TimeoutInterval.timeoutValue;
if (timeout_value < 10) {
/*
* if this value is less than 10 then our timer
* will fail to start and due to this we will
* never re-attempt. Better modify the timer
* value here.
*/
timeout_value = 10;
}
timeout_value = QDF_MIN(MAX_RETRY_TIMER, timeout_value);
pe_debug("ASSOC res with eSIR_MAC_TRY_AGAIN_LATER recvd.Starting timer to wait timeout: %d",
timeout_value);
if (QDF_STATUS_SUCCESS !=
qdf_mc_timer_start(&session_entry->pmf_retry_timer,
timeout_value)) {
pe_err("Failed to start comeback timer");
return QDF_STATUS_E_FAILURE;
}
session_entry->pmf_retry_timer_info.retried = true;
return QDF_STATUS_SUCCESS;
}
#else
static QDF_STATUS
lim_handle_pmfcomeback_timer(struct pe_session *session_entry,
tpSirAssocRsp assoc_rsp)
{
return QDF_STATUS_E_FAILURE;
}
#endif
/**
* lim_process_assoc_rsp_frame() - Processes assoc response
* @mac_ctx: Pointer to Global MAC structure
@@ -593,6 +655,7 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx,
#endif
uint8_t ap_nss;
int8_t rssi;
QDF_STATUS status;
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
vdev_id = session_entry->vdev_id;
@@ -802,6 +865,15 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx,
qdf_mem_copy(ap_info.bssid.bytes, hdr->sa, QDF_MAC_ADDR_SIZE);
lim_add_bssid_to_reject_list(mac_ctx->pdev, &ap_info);
}
status = lim_handle_pmfcomeback_timer(session_entry, assoc_rsp);
/* return if retry again timer is started and ignore this assoc resp */
if (QDF_IS_STATUS_SUCCESS(status)) {
qdf_mem_free(beacon);
qdf_mem_free(assoc_rsp);
return;
}
if (assoc_rsp->status_code != eSIR_MAC_SUCCESS_STATUS) {
/*
*Re/Association response was received

Переглянути файл

@@ -798,6 +798,27 @@ end:
(uint32_t *) &mlm_auth_cnf);
}
#ifdef WLAN_FEATURE_11W
static void lim_store_pmfcomeback_timerinfo(struct pe_session *session_entry)
{
if (session_entry->opmode != QDF_STA_MODE ||
!session_entry->limRmfEnabled)
return;
/*
* Store current MLM state in case ASSOC response returns with
* TRY_AGAIN_LATER return code.
*/
session_entry->pmf_retry_timer_info.lim_prev_mlm_state =
session_entry->limPrevMlmState;
session_entry->pmf_retry_timer_info.lim_mlm_state =
session_entry->limMlmState;
}
#else
static void lim_store_pmfcomeback_timerinfo(struct pe_session *session_entry)
{
}
#endif /* WLAN_FEATURE_11W */
/**
* lim_process_mlm_assoc_req() - This function is called to process
* MLM_ASSOC_REQ message from SME
@@ -858,6 +879,7 @@ static void lim_process_mlm_assoc_req(struct mac_context *mac_ctx, uint32_t *msg
/* map the session entry pointer to the AssocFailureTimer */
mac_ctx->lim.lim_timers.gLimAssocFailureTimer.sessionId =
mlm_assoc_req->sessionId;
lim_store_pmfcomeback_timerinfo(session_entry);
session_entry->limPrevMlmState = session_entry->limMlmState;
session_entry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,

Переглянути файл

@@ -416,6 +416,38 @@ static void lim_send_mlm_assoc_req(struct mac_context *mac_ctx,
(uint32_t *) assoc_req);
}
#ifdef WLAN_FEATURE_11W
/**
* lim_pmf_comeback_timer_callback() -PMF callback handler
* @context: Timer context
*
* This function is called to processes the PMF comeback
* callback
*
* Return: None
*/
void lim_pmf_comeback_timer_callback(void *context)
{
struct comeback_timer_info *info =
(struct comeback_timer_info *)context;
struct mac_context *mac_ctx = info->mac;
struct pe_session *session;
session = pe_find_session_by_vdev_id(mac_ctx, info->vdev_id);
if (!session) {
pe_err("no session found for vdev %d", info->vdev_id);
return;
}
pe_info("comeback later timer expired. sending MLM ASSOC req for vdev %d",
session->vdev_id);
/* set MLM state such that ASSOC REQ packet will be sent out */
session->limPrevMlmState = info->lim_prev_mlm_state;
session->limMlmState = info->lim_mlm_state;
lim_send_mlm_assoc_req(mac_ctx, session);
}
#endif /* WLAN_FEATURE_11W */
/**
* lim_process_mlm_auth_cnf()-Process Auth confirmation
* @mac_ctx: Pointer to Global MAC structure

Переглянути файл

@@ -1872,7 +1872,7 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx,
void *packet;
QDF_STATUS qdf_status;
uint16_t add_ie_len, current_len = 0, vendor_ie_len = 0;
uint8_t *add_ie;
uint8_t *add_ie = NULL;
const uint8_t *wps_ie = NULL;
uint8_t power_caps = false;
uint8_t tx_flag = 0;
@@ -1907,11 +1907,26 @@ lim_send_assoc_req_mgmt_frame(struct mac_context *mac_ctx,
return;
}
add_ie_len = pe_session->lim_join_req->addIEAssoc.length;
add_ie = pe_session->lim_join_req->addIEAssoc.addIEdata;
if (add_ie_len) {
add_ie = qdf_mem_malloc(add_ie_len);
if (!add_ie) {
qdf_mem_free(mlm_assoc_req);
return;
}
/*
* copy the additional ie to local, as this func modify
* the IE, these IE will be required in assoc/re-assoc
* retry. So do not modify the original IE.
*/
qdf_mem_copy(add_ie, pe_session->lim_join_req->addIEAssoc.addIEdata,
add_ie_len);
}
frm = qdf_mem_malloc(sizeof(tDot11fAssocRequest));
if (!frm) {
qdf_mem_free(mlm_assoc_req);
qdf_mem_free(add_ie);
return;
}
qdf_mem_zero((uint8_t *) frm, sizeof(tDot11fAssocRequest));
@@ -2456,6 +2471,7 @@ end:
/* Free up buffer allocated for mlm_assoc_req */
qdf_mem_free(adaptive_11r_ie);
qdf_mem_free(mlm_assoc_req);
qdf_mem_free(add_ie);
mlm_assoc_req = NULL;
qdf_mem_free(frm);
return;

Переглянути файл

@@ -269,6 +269,41 @@ restart_timer:
}
}
#ifdef WLAN_FEATURE_11W
/**
* pe_init_pmf_comeback_timer: init PMF comeback timer
* @mac_ctx: pointer to global adapter context
* @session: pe session
*
* Return: void
*/
static void
pe_init_pmf_comeback_timer(tpAniSirGlobal mac_ctx, struct pe_session *session)
{
QDF_STATUS status;
if (session->opmode != QDF_STA_MODE)
return;
pe_debug("init pmf comeback timer for vdev %d", session->vdev_id);
session->pmf_retry_timer_info.mac = mac_ctx;
session->pmf_retry_timer_info.vdev_id = session->vdev_id;
session->pmf_retry_timer_info.retried = false;
status = qdf_mc_timer_init(
&session->pmf_retry_timer, QDF_TIMER_TYPE_SW,
lim_pmf_comeback_timer_callback,
(void *)&session->pmf_retry_timer_info);
if (!QDF_IS_STATUS_SUCCESS(status))
pe_err("cannot init pmf comeback timer");
}
#else
static inline void
pe_init_pmf_comeback_timer(tpAniSirGlobal mac_ctx, struct pe_session *session,
uint8_t vdev_id)
{
}
#endif
#ifdef WLAN_FEATURE_FILS_SK
/**
* pe_delete_fils_info: API to delete fils session info
@@ -653,6 +688,7 @@ struct pe_session *pe_create_session(struct mac_context *mac,
pe_err("cannot create ap_ecsa_timer");
}
pe_init_fils_info(session_ptr);
pe_init_pmf_comeback_timer(mac, session_ptr);
session_ptr->ht_client_cnt = 0;
/* following is invalid value since seq number is 12 bit */
session_ptr->prev_auth_seq_num = 0xFFFF;
@@ -777,6 +813,25 @@ struct pe_session *pe_find_session_by_session_id(struct mac_context *mac,
return NULL;
}
#ifdef WLAN_FEATURE_11W
static void lim_clear_pmfcomeback_timer(struct pe_session *session)
{
if (session->opmode != QDF_STA_MODE)
return;
pe_debug("deinit pmf comeback timer for vdev %d", session->vdev_id);
if (QDF_TIMER_STATE_RUNNING ==
qdf_mc_timer_get_current_state(&session->pmf_retry_timer))
qdf_mc_timer_stop(&session->pmf_retry_timer);
qdf_mc_timer_destroy(&session->pmf_retry_timer);
session->pmf_retry_timer_info.retried = false;
}
#else
static void lim_clear_pmfcomeback_timer(struct pe_session *session)
{
}
#endif
/**
* pe_delete_session() - deletes the PE session given the session ID.
* @mac_ctx: pointer to global adapter context
@@ -957,6 +1012,7 @@ void pe_delete_session(struct mac_context *mac_ctx, struct pe_session *session)
session->add_ie_params.probeRespBCNDataLen = 0;
}
pe_delete_fils_info(session);
lim_clear_pmfcomeback_timer(session);
session->valid = false;
session->mac_ctx = NULL;

Переглянути файл

@@ -833,6 +833,7 @@ bool lim_check_disassoc_deauth_ack_pending(struct mac_context *mac,
#ifdef WLAN_FEATURE_11W
void lim_pmf_sa_query_timer_handler(void *pMacGlobal, uint32_t param);
void lim_pmf_comeback_timer_callback(void *context);
void lim_set_protected_bit(struct mac_context *mac,
struct pe_session *pe_session,
tSirMacAddr peer, tpSirMacMgmtHdr pMacHdr);