diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 3d898ccdbeb5..b14150e54f11 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -1107,6 +1107,7 @@ struct assoc_ind { const uint8_t *owe_ie; uint32_t owe_ie_len; uint16_t owe_status; + bool need_assoc_rsp_tx_cb; }; /** @@ -1131,6 +1132,7 @@ struct assoc_cnf { enum mac_status_code mac_status_code; uint8_t *owe_ie; uint32_t owe_ie_len; + bool need_assoc_rsp_tx_cb; }; /* / Enum definition for Wireless medium status change codes */ diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index 289df70859be..e79db84d1de5 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -72,8 +72,9 @@ enum eWniMsgTypes { eWNI_SME_DELTS_IND = SIR_SME_MSG_TYPES_BEGIN + 32, /* * unused SIR_SME_MSG_TYPES_BEGIN + 33 to - * to SIR_SME_MSG_TYPES_BEGIN + 36 + * to SIR_SME_MSG_TYPES_BEGIN + 35 */ + eWNI_SME_ASSOC_IND_UPPER_LAYER = SIR_SME_MSG_TYPES_BEGIN + 36, eWNI_SME_WPS_PBC_PROBE_REQ_IND = SIR_SME_MSG_TYPES_BEGIN + 37, eWNI_SME_UPPER_LAYER_ASSOC_CNF = SIR_SME_MSG_TYPES_BEGIN + 38, eWNI_SME_SESSION_UPDATE_PARAM = SIR_SME_MSG_TYPES_BEGIN + 39, diff --git a/core/mac/src/pe/lim/lim_assoc_utils.c b/core/mac/src/pe/lim/lim_assoc_utils.c index 00e6f3290d6c..b5cc37bdf4a1 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.c +++ b/core/mac/src/pe/lim/lim_assoc_utils.c @@ -918,9 +918,11 @@ lim_reject_association(struct mac_context *mac_ctx, tSirMacAddr peer_addr, } if (delete_sta == false) { - lim_send_assoc_rsp_mgmt_frame(mac_ctx, + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS, - 1, peer_addr, sub_type, 0, session_entry); + 1, peer_addr, sub_type, 0, session_entry, + false); pe_warn("received Re/Assoc req when max associated STAs reached from"); lim_print_mac_addr(mac_ctx, peer_addr, LOGW); lim_send_sme_max_assoc_exceeded_ntf(mac_ctx, peer_addr, @@ -950,7 +952,7 @@ lim_reject_association(struct mac_context *mac_ctx, tSirMacAddr peer_addr, * status code to requesting STA. */ lim_send_assoc_rsp_mgmt_frame(mac_ctx, result_code, 0, peer_addr, - sub_type, 0, session_entry); + sub_type, 0, session_entry, false); if (session_entry->parsedAssocReq[sta_ds->assocId]) { uint8_t *assoc_req_frame; diff --git a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c index 6a81d510056e..1228c4078235 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c @@ -221,7 +221,7 @@ static bool lim_chk_sa_da(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, pe_err("Assoc Req rejected: wlan.sa = wlan.da"); lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS, - 1, hdr->sa, sub_type, 0, session); + 1, hdr->sa, sub_type, 0, session, false); return false; } @@ -248,7 +248,7 @@ static bool lim_chk_tkip(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, pe_err("Assoc Req rejected: TKIP counter measure is active"); lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_MIC_FAILURE_REASON, 1, - hdr->sa, sub_type, 0, session); + hdr->sa, sub_type, 0, session, false); return false; } @@ -289,7 +289,7 @@ static bool lim_chk_assoc_req_parse_error(struct mac_context *mac_ctx, pe_warn("Assoc Req rejected: frame parsing error. source addr:" QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(hdr->sa)); lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS, - 1, hdr->sa, sub_type, 0, session); + 1, hdr->sa, sub_type, 0, session, false); return false; } @@ -331,9 +331,9 @@ static bool lim_chk_capab(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, * local capabilities. Respond with 'unsupported capabilities' * status code. */ - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, - 1, hdr->sa, sub_type, 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, + 1, hdr->sa, sub_type, 0, session, false); return false; } return true; @@ -371,7 +371,7 @@ static bool lim_chk_ssid(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, * status code. */ lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS, - 1, hdr->sa, sub_type, 0, session); + 1, hdr->sa, sub_type, 0, session, false); return false; } @@ -423,9 +423,9 @@ static bool lim_chk_rates(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, * Requesting STA does not support ALL BSS basic rates. Respond with * 'basic rates not supported' status code. */ - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS, 1, - hdr->sa, sub_type, 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS, 1, + hdr->sa, sub_type, 0, session, false); return false; } @@ -451,9 +451,9 @@ static bool lim_chk_11g_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, pe_err("SOFTAP was in 11G only mode, rejecting legacy STA: " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(hdr->sa)); - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, - 1, hdr->sa, sub_type, 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, + 1, hdr->sa, sub_type, 0, session, false); return false; } return true; @@ -481,9 +481,9 @@ static bool lim_chk_11n_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, pe_err("SOFTAP was in 11N only mode, rejecting legacy STA: " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(hdr->sa)); - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, - 1, hdr->sa, sub_type, 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, + 1, hdr->sa, sub_type, 0, session, false); return false; } return true; @@ -518,9 +518,9 @@ static bool lim_chk_11ac_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, if (LIM_IS_AP_ROLE(session) && (session->dot11mode == MLME_DOT11_MODE_11AC_ONLY) && ((!vht_caps) || ((vht_caps) && (!vht_caps->present)))) { - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, - 1, hdr->sa, sub_type, 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, + 1, hdr->sa, sub_type, 0, session, false); pe_err("SOFTAP was in 11AC only mode, reject"); return false; } @@ -547,9 +547,9 @@ static bool lim_chk_11ax_only(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, if (LIM_IS_AP_ROLE(session) && (session->dot11mode == MLME_DOT11_MODE_11AX_ONLY) && !assoc_req->he_cap.present) { - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, - 1, hdr->sa, sub_type, 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, + 1, hdr->sa, sub_type, 0, session, false); pe_err("SOFTAP was in 11AX only mode, reject"); return false; } @@ -585,9 +585,10 @@ static bool lim_check_11ax_basic_mcs(struct mac_context *mac_ctx, (uint16_t)mac_ctx->mlme_cfg->he_caps.he_ops_basic_mcs_nss; final_mcs = HE_INTERSECT_MCS(sta_mcs, basic_mcs); if (final_mcs != basic_mcs) { - lim_send_assoc_rsp_mgmt_frame(mac_ctx, + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, - 1, hdr->sa, sub_type, 0, session); + 1, hdr->sa, sub_type, 0, session, false); pe_err("STA did not support basic MCS required by SAP"); return false; } @@ -728,9 +729,9 @@ static bool lim_chk_mcs(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, * rates. Spec does not define any status code for this * scenario. */ - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS, - 1, hdr->sa, sub_type, 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS, + 1, hdr->sa, sub_type, 0, session, false); return false; } return true; @@ -765,9 +766,10 @@ static bool lim_chk_is_11b_sta_supported(struct mac_context *mac_ctx, * only policy option is set. Reject with unspecified * status code. */ - lim_send_assoc_rsp_mgmt_frame(mac_ctx, + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS, - 1, hdr->sa, sub_type, 0, session); + 1, hdr->sa, sub_type, 0, session, false); pe_warn("Rejecting Re/Assoc req from 11b STA:"); lim_print_mac_addr(mac_ctx, hdr->sa, LOGW); @@ -990,9 +992,9 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, * rcvd Assoc req frame with RSN IE but * length is zero */ - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_INVALID_IE_STATUS, 1, - hdr->sa, sub_type, 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_INVALID_IE_STATUS, 1, + hdr->sa, sub_type, 0, session, false); return false; } @@ -1005,7 +1007,7 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, pe_err("Invalid RSN IE"); lim_send_assoc_rsp_mgmt_frame( mac_ctx, eSIR_MAC_INVALID_IE_STATUS, 1, - hdr->sa, sub_type, 0, session); + hdr->sa, sub_type, 0, session, false); return false; } @@ -1020,9 +1022,9 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(hdr->sa)); - lim_send_assoc_rsp_mgmt_frame(mac_ctx, status, - 1, hdr->sa, sub_type, - 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, status, 1, hdr->sa, sub_type, + 0, session, false); return false; } } else { @@ -1032,9 +1034,10 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, * rcvd Assoc req frame with RSN IE but * IE version is wrong */ - lim_send_assoc_rsp_mgmt_frame(mac_ctx, + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS, - 1, hdr->sa, sub_type, 0, session); + 1, hdr->sa, sub_type, 0, session, false); return false; } *akm_type = lim_translate_rsn_oui_to_akm_type( @@ -1048,7 +1051,7 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, QDF_MAC_ADDR_ARRAY(hdr->sa)); lim_send_assoc_rsp_mgmt_frame(mac_ctx, status, 1, hdr->sa, sub_type, - 0, session); + 0, session, false); return false; } @@ -1059,9 +1062,9 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, QDF_MAC_ADDR_ARRAY(hdr->sa)); /* rcvd Assoc req frame with invalid WPA IE length */ - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_INVALID_IE_STATUS, 1, - hdr->sa, sub_type, 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_INVALID_IE_STATUS, 1, + hdr->sa, sub_type, 0, session, false); return false; } /* Unpack the WPA IE */ @@ -1073,7 +1076,7 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, pe_err("Invalid WPA IE"); lim_send_assoc_rsp_mgmt_frame( mac_ctx, eSIR_MAC_INVALID_IE_STATUS, 1, - hdr->sa, sub_type, 0, session); + hdr->sa, sub_type, 0, session, false); return false; } @@ -1088,8 +1091,9 @@ static bool lim_check_wpa_rsn_ie(struct pe_session *session, * rcvd Assoc req frame with WPA IE * but there is mismatch */ - lim_send_assoc_rsp_mgmt_frame(mac_ctx, status, 1, - hdr->sa, sub_type, 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, status, 1, + hdr->sa, sub_type, 0, session, false); return false; } *akm_type = lim_translate_rsn_oui_to_akm_type( @@ -1280,9 +1284,9 @@ static bool lim_process_assoc_req_sta_ctx(struct mac_context *mac_ctx, * query procedure we will end up using the stale value. */ sta_ds->pmfSaQueryRetryCount = 0; - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_TRY_AGAIN_LATER, 1, hdr->sa, - sub_type, sta_ds, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_TRY_AGAIN_LATER, 1, hdr->sa, + sub_type, sta_ds, session, false); lim_send_sa_query_request_frame(mac_ctx, (uint8_t *) &(sta_ds->pmfSaQueryCurrentTransId), hdr->sa, session); @@ -1303,9 +1307,9 @@ static bool lim_process_assoc_req_sta_ctx(struct mac_context *mac_ctx, * Request with try again later */ case DPH_SA_QUERY_IN_PROGRESS: - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_TRY_AGAIN_LATER, 1, - hdr->sa, sub_type, 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_TRY_AGAIN_LATER, 1, + hdr->sa, sub_type, 0, session, false); return false; /* @@ -1389,9 +1393,11 @@ static bool lim_chk_wmm(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, 0, false, NULL, &tspecIdx, session) != QDF_STATUS_SUCCESS) { pe_warn("AdmitControl: TSPEC rejected"); - lim_send_assoc_rsp_mgmt_frame(mac_ctx, + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_QAP_NO_BANDWIDTH_REASON, - 1, hdr->sa, sub_type, 0, session); + 1, hdr->sa, sub_type, 0, session, + false); #ifdef WLAN_DEBUG mac_ctx->lim.gLimNumAssocReqDropACRejectTS++; #endif @@ -1400,9 +1406,9 @@ static bool lim_chk_wmm(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, } else if (lim_admit_control_add_sta(mac_ctx, hdr->sa, false) != QDF_STATUS_SUCCESS) { pe_warn("AdmitControl: Sta rejected"); - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_QAP_NO_BANDWIDTH_REASON, 1, - hdr->sa, sub_type, 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_QAP_NO_BANDWIDTH_REASON, 1, + hdr->sa, sub_type, 0, session, false); #ifdef WLAN_DEBUG mac_ctx->lim.gLimNumAssocReqDropACRejectSta++; #endif @@ -2214,10 +2220,10 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in * some STA doesn't like 4way handshake after reassoc * where some STA does expect 4-way handshake. */ - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS, - sta_ds->assocId, sta_ds->staAddr, - sub_type, sta_ds, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS, + sta_ds->assocId, sta_ds->staAddr, + sub_type, sta_ds, session, false); pe_err("Rejecting reassoc req from STA"); return; } else if (!sta_ds->rmfEnabled) { @@ -2226,10 +2232,11 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in * STA might have missed the assoc response, so it is * sending assoc request frame again. */ - lim_send_assoc_rsp_mgmt_frame(mac_ctx, QDF_STATUS_SUCCESS, - sta_ds->assocId, sta_ds->staAddr, - sub_type, - sta_ds, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, QDF_STATUS_SUCCESS, + sta_ds->assocId, sta_ds->staAddr, + sub_type, + sta_ds, session, false); pe_err("DUT already received an assoc request frame and STA is sending another assoc req.So, do not Process sessionid: %d sys sub_type: %d for role: %d from: " QDF_MAC_ADDR_STR, session->peSessionId, sub_type, @@ -2250,10 +2257,10 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in * other vdev. */ lim_send_assoc_rsp_mgmt_frame( - mac_ctx, - eSIR_MAC_UNSPEC_FAILURE_STATUS, - 1, hdr->sa, - sub_type, 0, session); + mac_ctx, + eSIR_MAC_UNSPEC_FAILURE_STATUS, + 1, hdr->sa, + sub_type, 0, session, false); return; } @@ -2296,9 +2303,9 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_in frame_len - LIM_ASSOC_REQ_IE_OFFSET)) { pe_err("Vendor ie not present and access policy is %x, Rejected association", session->access_policy); - lim_send_assoc_rsp_mgmt_frame(mac_ctx, - eSIR_MAC_UNSPEC_FAILURE_STATUS, 1, hdr->sa, - sub_type, 0, session); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, eSIR_MAC_UNSPEC_FAILURE_STATUS, + 1, hdr->sa, sub_type, 0, session, false); return; } } @@ -2456,6 +2463,13 @@ static void lim_fill_assoc_ind_wapi_info(struct mac_context *mac_ctx, } return; } +#else +static void lim_fill_assoc_ind_wapi_info( + struct mac_context *mac_ctx, + tpSirAssocReq assoc_req, tpLimMlmAssocInd assoc_ind, + const uint8_t *wpsie) +{ +} #endif /** @@ -2591,6 +2605,224 @@ static void fill_mlm_assoc_ind_vht(tpSirAssocReq assocreq, } } +bool lim_fill_lim_assoc_ind_params( + tpLimMlmAssocInd assoc_ind, + struct mac_context *mac_ctx, + tpDphHashNode sta_ds, + struct pe_session *session_entry) +{ + tpSirAssocReq assoc_req; + uint16_t rsn_len; + uint32_t phy_mode; + const uint8_t *wpsie = NULL; + uint8_t maxidx, i; + bool wme_enable; + + if (!session_entry->parsedAssocReq) { + pe_err(" Parsed Assoc req is NULL"); + return false; + } + + /* Get a copy of the already parsed Assoc Request */ + assoc_req = + (tpSirAssocReq)session_entry->parsedAssocReq[sta_ds->assocId]; + + if (!assoc_req) { + pe_err("assoc req for assoc_id:%d is NULL", sta_ds->assocId); + return false; + } + + /* Get the phy_mode */ + lim_get_phy_mode(mac_ctx, &phy_mode, session_entry); + + qdf_mem_copy((uint8_t *)assoc_ind->peerMacAddr, + (uint8_t *)sta_ds->staAddr, sizeof(tSirMacAddr)); + assoc_ind->aid = sta_ds->assocId; + qdf_mem_copy((uint8_t *)&assoc_ind->ssId, + (uint8_t *)&assoc_req->ssId, + assoc_req->ssId.length + 1); + assoc_ind->sessionId = session_entry->peSessionId; + assoc_ind->authType = sta_ds->mlmStaContext.authType; + assoc_ind->akm_type = sta_ds->mlmStaContext.akm_type; + assoc_ind->capabilityInfo = assoc_req->capabilityInfo; + + /* Fill in RSN IE information */ + assoc_ind->rsnIE.length = 0; + /* if WPS IE is present, ignore RSN IE */ + if (assoc_req->addIEPresent && assoc_req->addIE.length) { + wpsie = limGetWscIEPtr( + mac_ctx, + assoc_req->addIE.addIEdata, + assoc_req->addIE.length); + } + if (assoc_req->rsnPresent && !wpsie) { + pe_debug("Assoc Req RSN IE len: %d", + assoc_req->rsn.length); + assoc_ind->rsnIE.length = 2 + assoc_req->rsn.length; + assoc_ind->rsnIE.rsnIEdata[0] = WLAN_ELEMID_RSN; + assoc_ind->rsnIE.rsnIEdata[1] = + assoc_req->rsn.length; + qdf_mem_copy( + &assoc_ind->rsnIE.rsnIEdata[2], + assoc_req->rsn.info, + assoc_req->rsn.length); + } + /* Fill in 802.11h related info */ + if (assoc_req->powerCapabilityPresent && + assoc_req->supportedChannelsPresent) { + assoc_ind->spectrumMgtIndicator = true; + assoc_ind->powerCap.minTxPower = + assoc_req->powerCapability.minTxPower; + assoc_ind->powerCap.maxTxPower = + assoc_req->powerCapability.maxTxPower; + lim_convert_supported_channels( + mac_ctx, assoc_ind, + assoc_req); + } else { + assoc_ind->spectrumMgtIndicator = false; + } + + /* This check is to avoid extra Sec IEs present incase of WPS */ + if (assoc_req->wpaPresent && !wpsie) { + rsn_len = assoc_ind->rsnIE.length; + if ((rsn_len + assoc_req->wpa.length) + >= WLAN_MAX_IE_LEN) { + pe_err("rsnIEdata index out of bounds: %d", + rsn_len); + return false; + } + assoc_ind->rsnIE.rsnIEdata[rsn_len] = + SIR_MAC_WPA_EID; + assoc_ind->rsnIE.rsnIEdata[rsn_len + 1] + = assoc_req->wpa.length; + qdf_mem_copy( + &assoc_ind->rsnIE.rsnIEdata[rsn_len + 2], + assoc_req->wpa.info, assoc_req->wpa.length); + assoc_ind->rsnIE.length += 2 + assoc_req->wpa.length; + } + lim_fill_assoc_ind_wapi_info(mac_ctx, assoc_req, assoc_ind, wpsie); + + assoc_ind->addIE.length = 0; + if (assoc_req->addIEPresent) { + qdf_mem_copy( + &assoc_ind->addIE.addIEdata, + assoc_req->addIE.addIEdata, + assoc_req->addIE.length); + assoc_ind->addIE.length = assoc_req->addIE.length; + } + /* + * Add HT Capabilities into addIE for OBSS + * processing in hostapd + */ + if (assoc_req->HTCaps.present) { + qdf_mem_copy(&assoc_ind->ht_caps, &assoc_req->HTCaps, + sizeof(tDot11fIEHTCaps)); + rsn_len = assoc_ind->addIE.length; + if (assoc_ind->addIE.length + DOT11F_IE_HTCAPS_MIN_LEN + + 2 < WLAN_MAX_IE_LEN) { + assoc_ind->addIE.addIEdata[rsn_len] = + WLAN_ELEMID_HTCAP_ANA; + assoc_ind->addIE.addIEdata[rsn_len + 1] = + DOT11F_IE_HTCAPS_MIN_LEN; + qdf_mem_copy( + &assoc_ind->addIE.addIEdata[rsn_len + 2], + ((uint8_t *)&assoc_req->HTCaps) + 1, + DOT11F_IE_HTCAPS_MIN_LEN); + assoc_ind->addIE.length += + 2 + DOT11F_IE_HTCAPS_MIN_LEN; + } else { + pe_err("Fail:HT capabilities IE to addIE"); + } + } + + if (assoc_req->wmeInfoPresent) { + /* Set whether AP is enabled with WMM or not */ + wme_enable = mac_ctx->mlme_cfg->wmm_params.wme_enabled; + assoc_ind->WmmStaInfoPresent = wme_enable; + /* + * Note: we are not rejecting association here + * because IOT will fail + */ + } + /* Required for indicating the frames to upper layer */ + assoc_ind->assocReqLength = assoc_req->assocReqFrameLength; + assoc_ind->assocReqPtr = assoc_req->assocReqFrame; + assoc_ind->beaconPtr = session_entry->beacon; + assoc_ind->beaconLength = session_entry->bcnLen; + + assoc_ind->chan_info.mhz = session_entry->curr_op_freq; + assoc_ind->chan_info.band_center_freq1 = + session_entry->curr_op_freq; + assoc_ind->chan_info.band_center_freq2 = 0; + assoc_ind->chan_info.reg_info_1 = + (session_entry->maxTxPower << 16); + assoc_ind->chan_info.reg_info_2 = + (session_entry->maxTxPower << 8); + assoc_ind->chan_info.nss = sta_ds->nss; + assoc_ind->chan_info.rate_flags = + lim_get_max_rate_flags(mac_ctx, sta_ds); + assoc_ind->ampdu = false; + assoc_ind->sgi_enable = false; + assoc_ind->tx_stbc = false; + assoc_ind->rx_stbc = false; + assoc_ind->ch_width = eHT_CHANNEL_WIDTH_20MHZ; + assoc_ind->mode = SIR_SME_PHY_MODE_LEGACY; + assoc_ind->max_supp_idx = 0xff; + assoc_ind->max_ext_idx = 0xff; + assoc_ind->max_mcs_idx = 0xff; + assoc_ind->rx_mcs_map = 0xff; + assoc_ind->tx_mcs_map = 0xff; + + if (assoc_req->supportedRates.numRates) + assoc_ind->max_supp_idx = + lim_get_max_rate_idx(&assoc_req->supportedRates); + if (assoc_req->extendedRates.numRates) + assoc_ind->max_ext_idx = + lim_get_max_rate_idx(&assoc_req->extendedRates); + + if (sta_ds->mlmStaContext.htCapability) { + /* ampdu */ + assoc_ind->ampdu = true; + + /* sgi */ + if (sta_ds->htShortGI20Mhz || sta_ds->htShortGI40Mhz) + assoc_ind->sgi_enable = true; + + /* stbc */ + assoc_ind->tx_stbc = assoc_req->HTCaps.txSTBC; + assoc_ind->rx_stbc = assoc_req->HTCaps.rxSTBC; + + /* ch width */ + assoc_ind->ch_width = + sta_ds->htSupportedChannelWidthSet ? + eHT_CHANNEL_WIDTH_40MHZ : + eHT_CHANNEL_WIDTH_20MHZ; + /* mode */ + assoc_ind->mode = SIR_SME_PHY_MODE_HT; + maxidx = 0; + for (i = 0; i < 8; i++) { + if (assoc_req->HTCaps.supportedMCSSet[0] & + (1 << i)) + maxidx = i; + } + assoc_ind->max_mcs_idx = maxidx; + } + fill_mlm_assoc_ind_vht(assoc_req, sta_ds, assoc_ind); + if (assoc_req->ExtCap.present) + assoc_ind->ecsa_capable = + ((struct s_ext_cap *)assoc_req->ExtCap.bytes)->ext_chan_switch; + /* updates VHT information in assoc indication */ + qdf_mem_copy(&assoc_ind->vht_caps, &assoc_req->VHTCaps, + sizeof(tDot11fIEVHTCaps)); + lim_fill_assoc_ind_vht_info(mac_ctx, session_entry, assoc_req, + assoc_ind, sta_ds); + assoc_ind->he_caps_present = assoc_req->he_cap.present; + assoc_ind->is_sae_authenticated = + assoc_req->is_sae_authenticated; + + return true; +} + /** * lim_send_mlm_assoc_ind() - Sends assoc indication to SME * @mac_ctx: Global Mac context @@ -2605,14 +2837,11 @@ static void fill_mlm_assoc_ind_vht(tpSirAssocReq assocreq, void lim_send_mlm_assoc_ind(struct mac_context *mac_ctx, tpDphHashNode sta_ds, struct pe_session *session_entry) { - tpLimMlmAssocInd assoc_ind = NULL; + tpLimMlmAssocInd assoc_ind; tpSirAssocReq assoc_req; - uint16_t temp, rsn_len; + uint16_t temp; uint32_t phy_mode; uint8_t sub_type; - const uint8_t *wpsie = NULL; - uint8_t maxidx, i; - bool wme_enable; if (!session_entry->parsedAssocReq) { pe_err(" Parsed Assoc req is NULL"); @@ -2639,8 +2868,8 @@ void lim_send_mlm_assoc_ind(struct mac_context *mac_ctx, pe_debug("Sessionid: %d ssid: %s sub_type: %d Associd: %d staAddr: " QDF_MAC_ADDR_STR, session_entry->peSessionId, - assoc_req->ssId.ssId, sub_type, sta_ds->assocId, - QDF_MAC_ADDR_ARRAY(sta_ds->staAddr)); + assoc_req->ssId.ssId, sub_type, sta_ds->assocId, + QDF_MAC_ADDR_ARRAY(sta_ds->staAddr)); if (sub_type == LIM_ASSOC || sub_type == LIM_REASSOC) { temp = sizeof(tLimMlmAssocInd); @@ -2648,203 +2877,18 @@ void lim_send_mlm_assoc_ind(struct mac_context *mac_ctx, assoc_ind = qdf_mem_malloc(temp); if (!assoc_ind) { lim_release_peer_idx(mac_ctx, sta_ds->assocId, - session_entry); + session_entry); return; } - qdf_mem_copy((uint8_t *) assoc_ind->peerMacAddr, - (uint8_t *) sta_ds->staAddr, sizeof(tSirMacAddr)); - assoc_ind->aid = sta_ds->assocId; - qdf_mem_copy((uint8_t *) &assoc_ind->ssId, - (uint8_t *) &(assoc_req->ssId), - assoc_req->ssId.length + 1); - assoc_ind->sessionId = session_entry->peSessionId; - assoc_ind->authType = sta_ds->mlmStaContext.authType; - assoc_ind->akm_type = sta_ds->mlmStaContext.akm_type; - assoc_ind->capabilityInfo = assoc_req->capabilityInfo; - - /* Fill in RSN IE information */ - assoc_ind->rsnIE.length = 0; - /* if WPS IE is present, ignore RSN IE */ - if (assoc_req->addIEPresent && assoc_req->addIE.length) { - wpsie = limGetWscIEPtr(mac_ctx, - assoc_req->addIE.addIEdata, - assoc_req->addIE.length); + if (!lim_fill_lim_assoc_ind_params(assoc_ind, mac_ctx, + sta_ds, session_entry)) { + qdf_mem_free(assoc_ind); + return; } - if (assoc_req->rsnPresent && (!wpsie)) { - pe_debug("Assoc Req RSN IE len: %d", - assoc_req->rsn.length); - assoc_ind->rsnIE.length = 2 + assoc_req->rsn.length; - assoc_ind->rsnIE.rsnIEdata[0] = WLAN_ELEMID_RSN; - assoc_ind->rsnIE.rsnIEdata[1] = - assoc_req->rsn.length; - qdf_mem_copy(&assoc_ind->rsnIE.rsnIEdata[2], - assoc_req->rsn.info, - assoc_req->rsn.length); - } - /* Fill in 802.11h related info */ - if (assoc_req->powerCapabilityPresent - && assoc_req->supportedChannelsPresent) { - assoc_ind->spectrumMgtIndicator = true; - assoc_ind->powerCap.minTxPower = - assoc_req->powerCapability.minTxPower; - assoc_ind->powerCap.maxTxPower = - assoc_req->powerCapability.maxTxPower; - lim_convert_supported_channels(mac_ctx, assoc_ind, - assoc_req); - } else { - assoc_ind->spectrumMgtIndicator = false; - } - - /* This check is to avoid extra Sec IEs present incase of WPS */ - if (assoc_req->wpaPresent && (!wpsie)) { - rsn_len = assoc_ind->rsnIE.length; - if ((rsn_len + assoc_req->wpa.length) - >= WLAN_MAX_IE_LEN) { - pe_err("rsnIEdata index out of bounds: %d", - rsn_len); - qdf_mem_free(assoc_ind); - return; - } - assoc_ind->rsnIE.rsnIEdata[rsn_len] = - SIR_MAC_WPA_EID; - assoc_ind->rsnIE.rsnIEdata[rsn_len + 1] - = assoc_req->wpa.length; - qdf_mem_copy( - &assoc_ind->rsnIE.rsnIEdata[rsn_len + 2], - assoc_req->wpa.info, assoc_req->wpa.length); - assoc_ind->rsnIE.length += 2 + assoc_req->wpa.length; - } -#ifdef FEATURE_WLAN_WAPI - lim_fill_assoc_ind_wapi_info(mac_ctx, assoc_req, assoc_ind, - wpsie); -#endif - - assoc_ind->addIE.length = 0; - if (assoc_req->addIEPresent) { - qdf_mem_copy(&assoc_ind->addIE.addIEdata, - assoc_req->addIE.addIEdata, - assoc_req->addIE.length); - assoc_ind->addIE.length = assoc_req->addIE.length; - } - /* - * Add HT Capabilities into addIE for OBSS - * processing in hostapd - */ - if (assoc_req->HTCaps.present) { - qdf_mem_copy(&assoc_ind->ht_caps, &assoc_req->HTCaps, - sizeof(tDot11fIEHTCaps)); - - rsn_len = assoc_ind->addIE.length; - if (assoc_ind->addIE.length + DOT11F_IE_HTCAPS_MIN_LEN - + 2 < WLAN_MAX_IE_LEN) { - assoc_ind->addIE.addIEdata[rsn_len] = - WLAN_ELEMID_HTCAP_ANA; - assoc_ind->addIE.addIEdata[rsn_len + 1] = - DOT11F_IE_HTCAPS_MIN_LEN; - qdf_mem_copy( - &assoc_ind->addIE.addIEdata[rsn_len+2], - ((uint8_t *)&assoc_req->HTCaps) + 1, - DOT11F_IE_HTCAPS_MIN_LEN); - assoc_ind->addIE.length += - 2 + DOT11F_IE_HTCAPS_MIN_LEN; - } else { - pe_err("Fail:HT capabilities IE to addIE"); - } - } - - if (assoc_req->wmeInfoPresent) { - /* Set whether AP is enabled with WMM or not */ - wme_enable = mac_ctx->mlme_cfg->wmm_params.wme_enabled; - assoc_ind->WmmStaInfoPresent = wme_enable; - /* - * Note: we are not rejecting association here - * because IOT will fail - */ - } - /* Required for indicating the frames to upper layer */ - assoc_ind->assocReqLength = assoc_req->assocReqFrameLength; - assoc_ind->assocReqPtr = assoc_req->assocReqFrame; - - assoc_ind->beaconPtr = session_entry->beacon; - assoc_ind->beaconLength = session_entry->bcnLen; - - assoc_ind->chan_info.mhz = session_entry->curr_op_freq; - assoc_ind->chan_info.band_center_freq1 = - session_entry->curr_op_freq; - assoc_ind->chan_info.band_center_freq2 = 0; - assoc_ind->chan_info.reg_info_1 = - (session_entry->maxTxPower << 16); - assoc_ind->chan_info.reg_info_2 = - (session_entry->maxTxPower << 8); - assoc_ind->chan_info.nss = sta_ds->nss; - assoc_ind->chan_info.rate_flags = - lim_get_max_rate_flags(mac_ctx, sta_ds); - assoc_ind->ampdu = false; - assoc_ind->sgi_enable = false; - assoc_ind->tx_stbc = false; - assoc_ind->rx_stbc = false; - assoc_ind->ch_width = eHT_CHANNEL_WIDTH_20MHZ; - assoc_ind->mode = SIR_SME_PHY_MODE_LEGACY; - assoc_ind->max_supp_idx = 0xff; - assoc_ind->max_ext_idx = 0xff; - assoc_ind->max_mcs_idx = 0xff; - assoc_ind->rx_mcs_map = 0xff; - assoc_ind->tx_mcs_map = 0xff; - - if (assoc_req->supportedRates.numRates) - assoc_ind->max_supp_idx = - lim_get_max_rate_idx( - &assoc_req->supportedRates); - if (assoc_req->extendedRates.numRates) - assoc_ind->max_ext_idx = - lim_get_max_rate_idx( - &assoc_req->extendedRates); - - if (sta_ds->mlmStaContext.htCapability) { - /* ampdu */ - assoc_ind->ampdu = true; - - /* sgi */ - if (sta_ds->htShortGI20Mhz || sta_ds->htShortGI40Mhz) - assoc_ind->sgi_enable = true; - - /* stbc */ - assoc_ind->tx_stbc = assoc_req->HTCaps.txSTBC; - assoc_ind->rx_stbc = assoc_req->HTCaps.rxSTBC; - - /* ch width */ - assoc_ind->ch_width = - sta_ds->htSupportedChannelWidthSet ? - eHT_CHANNEL_WIDTH_40MHZ : - eHT_CHANNEL_WIDTH_20MHZ; - - /* mode */ - assoc_ind->mode = SIR_SME_PHY_MODE_HT; - maxidx = 0; - for (i = 0; i < 8; i++) { - if (assoc_req->HTCaps.supportedMCSSet[0] & - (1 << i)) - maxidx = i; - } - assoc_ind->max_mcs_idx = maxidx; - } - fill_mlm_assoc_ind_vht(assoc_req, sta_ds, assoc_ind); - if (assoc_req->ExtCap.present) - assoc_ind->ecsa_capable = - ((struct s_ext_cap *)assoc_req->ExtCap.bytes)-> - ext_chan_switch; - - /* updates VHT information in assoc indication */ - qdf_mem_copy(&assoc_ind->vht_caps, &assoc_req->VHTCaps, - sizeof(tDot11fIEVHTCaps)); - lim_fill_assoc_ind_vht_info(mac_ctx, session_entry, assoc_req, - assoc_ind, sta_ds); - assoc_ind->he_caps_present = assoc_req->he_cap.present; - assoc_ind->is_sae_authenticated = - assoc_req->is_sae_authenticated; lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_IND, - (uint32_t *) assoc_ind); + (uint32_t *)assoc_ind); qdf_mem_free(assoc_ind); } + return; } diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c index e12e7900d005..1eb0e09edaab 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c @@ -640,21 +640,9 @@ void lim_process_mlm_assoc_cnf(struct mac_context *mac_ctx, } } -/** - * lim_fill_assoc_ind_params() - Initialize association indication - * mac_ctx: Pointer to Global MAC structure - * assoc_ind: PE association indication structure - * sme_assoc_ind: SME association indication - * session_entry: PE session entry - * - * This function is called to initialzie the association - * indication strucutre to process association indication. - * - * Return: None - */ - -static void -lim_fill_assoc_ind_params(struct mac_context *mac_ctx, +void +lim_fill_sme_assoc_ind_params( + struct mac_context *mac_ctx, tpLimMlmAssocInd assoc_ind, struct assoc_ind *sme_assoc_ind, struct pe_session *session_entry) { @@ -775,9 +763,9 @@ void lim_process_mlm_assoc_ind(struct mac_context *mac, uint32_t *msg_buf) } pSirSmeAssocInd->messageType = eWNI_SME_ASSOC_IND; - lim_fill_assoc_ind_params(mac, (tpLimMlmAssocInd) msg_buf, - pSirSmeAssocInd, - pe_session); + lim_fill_sme_assoc_ind_params(mac, (tpLimMlmAssocInd)msg_buf, + pSirSmeAssocInd, + pe_session); msg.type = eWNI_SME_ASSOC_IND; msg.bodyptr = pSirSmeAssocInd; msg.bodyval = 0; diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index 0f4533a732f0..de2d91e9018f 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -3118,12 +3118,14 @@ void __lim_process_sme_assoc_cnf_new(struct mac_context *mac_ctx, uint32_t msg_t eLIM_MLM_LINK_ESTABLISHED_STATE; sta_ds->mlmStaContext.owe_ie = assoc_cnf.owe_ie; sta_ds->mlmStaContext.owe_ie_len = assoc_cnf.owe_ie_len; - pe_debug("sending Assoc Rsp frame to STA (assoc id=%d)", - sta_ds->assocId); - lim_send_assoc_rsp_mgmt_frame(mac_ctx, QDF_STATUS_SUCCESS, + pe_debug("sending Assoc Rsp frame to STA assoc id=%d, tx cb %d", + sta_ds->assocId, assoc_cnf.need_assoc_rsp_tx_cb); + lim_send_assoc_rsp_mgmt_frame( + mac_ctx, QDF_STATUS_SUCCESS, sta_ds->assocId, sta_ds->staAddr, sta_ds->mlmStaContext.subType, sta_ds, - session_entry); + session_entry, + assoc_cnf.need_assoc_rsp_tx_cb); sta_ds->mlmStaContext.owe_ie = NULL; sta_ds->mlmStaContext.owe_ie_len = 0; goto end; @@ -3160,7 +3162,8 @@ void __lim_process_sme_assoc_cnf_new(struct mac_context *mac_ctx, uint32_t msg_t } end: if (((session_entry) && (sta_ds)) && - (session_entry->parsedAssocReq[sta_ds->assocId])) { + (session_entry->parsedAssocReq[sta_ds->assocId]) && + !assoc_cnf.need_assoc_rsp_tx_cb) { assoc_req = (tpSirAssocReq) session_entry->parsedAssocReq[sta_ds->assocId]; if (assoc_req->assocReqFrame) { diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c index 1fa9b92d8b33..6f84694ed5c1 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/core/mac/src/pe/lim/lim_send_management_frames.c @@ -1011,24 +1011,135 @@ lim_send_addts_req_action_frame(struct mac_context *mac, } /* End lim_send_addts_req_action_frame. */ /** - * lim_send_assoc_rsp_mgmt_frame() - Send assoc response - * @mac_ctx: Handle for mac context - * @status_code: Status code for assoc response frame - * @aid: Association ID - * @peer_addr: Mac address of requesting peer - * @subtype: Assoc/Reassoc - * @sta: Pointer to station node - * @pe_session: PE session id. + * lim_assoc_rsp_tx_complete() - Confirmation for assoc rsp OTA + * @context: pointer to global mac + * @buf: buffer which is nothing but entire assoc rsp frame + * @tx_complete : Sent status + * @params; tx completion params * - * Builds and sends association response frame to the requesting peer. - * - * Return: void + * Return: This returns QDF_STATUS */ +static QDF_STATUS lim_assoc_rsp_tx_complete( + void *context, + qdf_nbuf_t buf, + uint32_t tx_complete, + void *params) +{ + struct mac_context *mac_ctx = (struct mac_context *)context; + tSirMacMgmtHdr *mac_hdr; + struct pe_session *session_entry; + uint8_t session_id; + tpLimMlmAssocInd lim_assoc_ind; + tpDphHashNode sta_ds; + uint16_t aid; + uint8_t *data; + struct assoc_ind *sme_assoc_ind; + struct scheduler_msg msg; + tpSirAssocReq assoc_req; + + if (!buf) { + pe_err("Assoc rsp frame buffer is NULL"); + goto null_buf; + } + + data = qdf_nbuf_data(buf); + + if (!data) { + pe_err("Assoc rsp frame is NULL"); + goto end; + } + + mac_hdr = (tSirMacMgmtHdr *)data; + + session_entry = pe_find_session_by_bssid( + mac_ctx, mac_hdr->sa, + &session_id); + if (!session_entry) { + pe_err("session entry is NULL"); + goto end; + } + + sta_ds = dph_lookup_hash_entry(mac_ctx, + (uint8_t *)mac_hdr->da, &aid, + &session_entry->dph.dphHashTable); + if (!sta_ds) { + pe_err("sta_ds is NULL"); + goto end; + } + + /* Get a copy of the already parsed Assoc Request */ + assoc_req = + (tpSirAssocReq)session_entry->parsedAssocReq[sta_ds->assocId]; + + if (!assoc_req) { + pe_err("assoc req for assoc_id:%d is NULL", sta_ds->assocId); + goto end; + } + + lim_assoc_ind = qdf_mem_malloc(sizeof(tLimMlmAssocInd)); + if (!lim_assoc_ind) { + pe_err("lim assoc ind is NULL"); + goto free_assoc_req; + } + if (!lim_fill_lim_assoc_ind_params(lim_assoc_ind, mac_ctx, + sta_ds, session_entry)) { + pe_err("lim assoc ind fill error"); + goto lim_assoc_ind; + } + + sme_assoc_ind = qdf_mem_malloc(sizeof(struct assoc_ind)); + if (!sme_assoc_ind) { + pe_err("sme assoc ind is NULL"); + goto lim_assoc_ind; + } + sme_assoc_ind->messageType = eWNI_SME_ASSOC_IND_UPPER_LAYER; + lim_fill_sme_assoc_ind_params( + mac_ctx, lim_assoc_ind, + sme_assoc_ind, + session_entry); + + qdf_mem_zero(&msg, sizeof(struct scheduler_msg)); + msg.type = eWNI_SME_ASSOC_IND_UPPER_LAYER; + msg.bodyptr = sme_assoc_ind; + msg.bodyval = 0; + sme_assoc_ind->staId = sta_ds->staIndex; + sme_assoc_ind->reassocReq = sta_ds->mlmStaContext.subType; + sme_assoc_ind->timingMeasCap = sta_ds->timingMeasCap; + + mac_ctx->lim.sme_msg_callback(mac_ctx, &msg); + + qdf_mem_free(lim_assoc_ind); + if (assoc_req->assocReqFrame) { + qdf_mem_free(assoc_req->assocReqFrame); + assoc_req->assocReqFrame = NULL; + } + qdf_mem_free(session_entry->parsedAssocReq[sta_ds->assocId]); + session_entry->parsedAssocReq[sta_ds->assocId] = NULL; + qdf_nbuf_free(buf); + + return QDF_STATUS_SUCCESS; + +lim_assoc_ind: + qdf_mem_free(lim_assoc_ind); +free_assoc_req: + if (assoc_req->assocReqFrame) { + qdf_mem_free(assoc_req->assocReqFrame); + assoc_req->assocReqFrame = NULL; + } + qdf_mem_free(session_entry->parsedAssocReq[sta_ds->assocId]); + session_entry->parsedAssocReq[sta_ds->assocId] = NULL; +end: + qdf_nbuf_free(buf); +null_buf: + return QDF_STATUS_E_FAILURE; +} void -lim_send_assoc_rsp_mgmt_frame(struct mac_context *mac_ctx, +lim_send_assoc_rsp_mgmt_frame( + struct mac_context *mac_ctx, uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr, - uint8_t subtype, tpDphHashNode sta, struct pe_session *pe_session) + uint8_t subtype, tpDphHashNode sta, struct pe_session *pe_session, + bool tx_complete) { static tDot11fAssocResponse frm; uint8_t *frame; @@ -1371,7 +1482,17 @@ lim_send_assoc_rsp_mgmt_frame(struct mac_context *mac_ctx, lim_diag_mgmt_tx_event_report(mac_ctx, mac_hdr, pe_session, QDF_STATUS_SUCCESS, status_code); /* Queue Association Response frame in high priority WQ */ - qdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes, + if (tx_complete) + qdf_status = wma_tx_frameWithTxComplete( + mac_ctx, packet, (uint16_t)bytes, + TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7, lim_tx_complete, frame, + lim_assoc_rsp_tx_complete, tx_flag, + sme_session, false, 0, RATEID_DEFAULT); + else + qdf_status = wma_tx_frame( + mac_ctx, packet, (uint16_t)bytes, TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7, lim_tx_complete, frame, tx_flag, diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h index db6a18d90800..b0d5d1ca9ea0 100644 --- a/core/mac/src/pe/lim/lim_types.h +++ b/core/mac/src/pe/lim/lim_types.h @@ -404,6 +404,36 @@ QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac, uint8_t *bd, void *body); void lim_process_assoc_req_frame(struct mac_context *, uint8_t *, uint8_t, struct pe_session *); + +/** + * lim_fill_lim_assoc_ind_params() - Initialize lim association indication + * @assoc_ind: PE association indication structure + * @mac_ctx: Pointer to Global MAC structure + * @sta_ds: station dph entry + * @session_entry: PE session entry + * + * Return: true if lim assoc ind filled successfully + */ +bool lim_fill_lim_assoc_ind_params( + tpLimMlmAssocInd assoc_ind, + struct mac_context *mac_ctx, + tpDphHashNode sta_ds, + struct pe_session *session_entry); + +/** + * lim_fill_sme_assoc_ind_params() - Initialize association indication + * @mac_ctx: Pointer to Global MAC structure + * @assoc_ind: PE association indication structure + * @sme_assoc_ind: SME association indication + * @session_entry: PE session entry + * + * Return: None + */ +void +lim_fill_sme_assoc_ind_params( + struct mac_context *mac_ctx, + tpLimMlmAssocInd assoc_ind, struct assoc_ind *sme_assoc_ind, + struct pe_session *session_entry); void lim_send_mlm_assoc_ind(struct mac_context *mac, tpDphHashNode sta, struct pe_session *pe_session); @@ -565,8 +595,27 @@ void lim_send_delts_req_action_frame(struct mac_context *mac, tSirMacAddr peer, void lim_send_addts_req_action_frame(struct mac_context *mac, tSirMacAddr peerMacAddr, tSirAddtsReqInfo *addts, struct pe_session *); -void lim_send_assoc_rsp_mgmt_frame(struct mac_context *, uint16_t, uint16_t, tSirMacAddr, - uint8_t, tpDphHashNode pSta, struct pe_session *); +/** + * lim_send_assoc_rsp_mgmt_frame() - Send assoc response + * @mac_ctx: Handle for mac context + * @status_code: Status code for assoc response frame + * @aid: Association ID + * @peer_addr: Mac address of requesting peer + * @subtype: Assoc/Reassoc + * @sta: Pointer to station node + * @pe_session: PE session id. + * @tx_complete: Need tx complete callback or not + * + * Builds and sends association response frame to the requesting peer. + * + * Return: void + */ +void +lim_send_assoc_rsp_mgmt_frame( + struct mac_context *mac_ctx, + uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr, + uint8_t subtype, tpDphHashNode sta, struct pe_session *pe_session, + bool tx_complete); void lim_send_disassoc_mgmt_frame(struct mac_context *, uint16_t, tSirMacAddr, struct pe_session *, bool waitForAck); diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 8fe3f3241360..66fb944152fb 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -302,6 +302,8 @@ char *lim_msg_str(uint32_t msgType) return "eWNI_SME_START_BSS_RSP"; case eWNI_SME_ASSOC_IND: return "eWNI_SME_ASSOC_IND"; + case eWNI_SME_ASSOC_IND_UPPER_LAYER: + return "eWNI_SME_ASSOC_IND_UPPER_LAYER"; case eWNI_SME_ASSOC_CNF: return "eWNI_SME_ASSOC_CNF"; case eWNI_SME_SWITCH_CHL_IND: diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c index 9c18a6edf9be..99b2cd8e2ecd 100644 --- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c +++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c @@ -245,6 +245,7 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg) CASE_RETURN_STRING(eWNI_SME_DELTS_REQ); CASE_RETURN_STRING(eWNI_SME_DELTS_RSP); CASE_RETURN_STRING(eWNI_SME_DELTS_IND); + CASE_RETURN_STRING(eWNI_SME_ASSOC_IND_UPPER_LAYER); CASE_RETURN_STRING(eWNI_SME_WPS_PBC_PROBE_REQ_IND); CASE_RETURN_STRING(eWNI_SME_UPPER_LAYER_ASSOC_CNF); CASE_RETURN_STRING(eWNI_SME_SESSION_UPDATE_PARAM); diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 7a8c582bc138..1ec779774a33 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -11619,6 +11619,26 @@ csr_send_assoc_ind_to_upper_layer_cnf_msg(struct mac_context *mac, return QDF_STATUS_SUCCESS; } +static void +csr_roam_chk_lnk_assoc_ind_upper_layer( + struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) +{ + uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX; + struct assoc_ind *assoc_ind; + QDF_STATUS status; + + assoc_ind = (struct assoc_ind *)msg_ptr; + status = csr_roam_get_session_id_from_bssid( + mac_ctx, (struct qdf_mac_addr *)assoc_ind->bssId, + &session_id); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sme_debug("Couldn't find session_id for given BSSID"); + return; + } + csr_send_assoc_ind_to_upper_layer_cnf_msg( + mac_ctx, assoc_ind, status, session_id); +} + static void csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) { @@ -11743,19 +11763,12 @@ csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) } if (csr_akm_type != eCSR_AUTH_TYPE_OWE) { + if (CSR_IS_INFRA_AP(roam_info->u.pConnectedProfile) && + roam_info->status_code != eSIR_SME_ASSOC_REFUSED) + pAssocInd->need_assoc_rsp_tx_cb = true; /* Send Association completion message to PE */ status = csr_send_assoc_cnf_msg(mac_ctx, pAssocInd, status, mac_status_code); - /* - * send a message to CSR itself just to avoid the EAPOL frames - * going OTA before association response - */ - if (CSR_IS_INFRA_AP(roam_info->u.pConnectedProfile) && - roam_info->status_code != eSIR_SME_ASSOC_REFUSED) { - roam_info->fReassocReq = pAssocInd->reassocReq; - status = csr_send_assoc_ind_to_upper_layer_cnf_msg( - mac_ctx, pAssocInd, status, sessionId); - } } qdf_mem_free(roam_info); @@ -12557,6 +12570,9 @@ void csr_roam_check_for_link_status_change(struct mac_context *mac, case eWNI_SME_ASSOC_IND: csr_roam_chk_lnk_assoc_ind(mac, pSirMsg); break; + case eWNI_SME_ASSOC_IND_UPPER_LAYER: + csr_roam_chk_lnk_assoc_ind_upper_layer(mac, pSirMsg); + break; case eWNI_SME_DISASSOC_IND: csr_roam_chk_lnk_disassoc_ind(mac, pSirMsg); break; @@ -16567,6 +16583,7 @@ QDF_STATUS csr_send_assoc_cnf_msg(struct mac_context *mac, pAssocInd->owe_ie_len); pMsg->owe_ie_len = pAssocInd->owe_ie_len; } + pMsg->need_assoc_rsp_tx_cb = pAssocInd->need_assoc_rsp_tx_cb; msg.type = pMsg->messageType; msg.bodyval = 0;