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
Цей коміт міститься в:
@@ -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);
|
||||
|
Посилання в новій задачі
Заблокувати користувача