diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index e69f3c725c31..2c09426a1b48 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -1368,6 +1368,7 @@ static void hdd_send_re_assoc_event(struct net_device *dev, unsigned int len = 0; u8 *pFTAssocRsp = NULL; uint8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL); + uint8_t *assoc_req_ies = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL); uint32_t rspRsnLength = 0; struct ieee80211_channel *chan; hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); @@ -1383,6 +1384,10 @@ static void hdd_send_re_assoc_event(struct net_device *dev, return; } + if (!assoc_req_ies) { + hdd_err("Unable to allocate Assoc Req IE"); + return; + } if (pCsrRoamInfo == NULL) { hddLog(LOGE, FL("Invalid CSR roam info")); goto done; @@ -1462,14 +1467,24 @@ static void hdd_send_re_assoc_event(struct net_device *dev, final_req_ie, (ssid_ie_len + reqRsnLength), rspRsnIe, rspRsnLength, GFP_KERNEL); + cdf_mem_copy(assoc_req_ies, + (u8 *)pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength, + pCsrRoamInfo->nAssocReqLength); + + hdd_notice("ReAssoc Req IE dump"); + CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_DEBUG, + assoc_req_ies, pCsrRoamInfo->nAssocReqLength); + wlan_hdd_send_roam_auth_event(pHddCtx, pCsrRoamInfo->bssid.bytes, - reqRsnIe, reqRsnLength, rspRsnIe, rspRsnLength, + assoc_req_ies, pCsrRoamInfo->nAssocReqLength, + rspRsnIe, rspRsnLength, pCsrRoamInfo); done: sme_roam_free_connect_profile(hal_handle, &roam_profile); if (final_req_ie) kfree(final_req_ie); kfree(rspRsnIe); + kfree(assoc_req_ies); } /** @@ -1967,6 +1982,15 @@ defined(FEATURE_WLAN_LFR) "assocReqlen %d assocRsplen %d", assocReqlen, assocRsplen); + + hdd_notice( + "Reassoc Req IE dump"); + CDF_TRACE_HEX_DUMP( + CDF_MODULE_ID_HDD, + CDF_TRACE_LEVEL_DEBUG, + pFTAssocReq, + assocReqlen); + cfg80211_roamed(dev, chan, pRoamInfo-> bssid.bytes, diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index aa2004dc00ee..8d830a3cbc0d 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -3047,16 +3047,29 @@ int wlan_hdd_send_roam_auth_event(hdd_context_t *hdd_ctx_ptr, uint8_t *bssid, if (roam_info_ptr->synchAuthStatus == CSR_ROAM_AUTH_STATUS_AUTHENTICATED) { hddLog(CDF_TRACE_LEVEL_DEBUG, FL("Include Auth Params TLV's")); - if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED, - true) || - nla_put(skb, - QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR, - SIR_REPLAY_CTR_LEN, roam_info_ptr->replay_ctr) - || nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK, - SIR_KCK_KEY_LEN, roam_info_ptr->kck) - || nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK, - SIR_KEK_KEY_LEN, roam_info_ptr->kek)) { - hddLog(CDF_TRACE_LEVEL_ERROR, FL("nla put fail")); + if (nla_put_u8(skb, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED, true)) { + hdd_err("nla put fail"); + goto nla_put_failure; + } + /* if FT connection: dont send ROAM_AUTH_KEY_REPLAY_CTR */ + if (roam_info_ptr->u.pConnectedProfile->AuthType != + eCSR_AUTH_TYPE_FT_RSN && + roam_info_ptr->u.pConnectedProfile->AuthType != + eCSR_AUTH_TYPE_FT_RSN_PSK && + nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR, + SIR_REPLAY_CTR_LEN, roam_info_ptr->replay_ctr)) { + hdd_err("non FT connection."); + hdd_err("failed to send replay counter."); + goto nla_put_failure; + } + if (nla_put(skb, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK, + SIR_KCK_KEY_LEN, roam_info_ptr->kck) || + nla_put(skb, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK, + SIR_KEK_KEY_LEN, roam_info_ptr->kek)) { + hdd_err("nla put fail"); goto nla_put_failure; } } else { diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index d0c794834bf3..d41818245bca 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -3941,6 +3941,8 @@ typedef struct sSirSmeRoamOffloadSynchInd { uint16_t beaconProbeRespLength; uint16_t reassocRespOffset; uint16_t reassocRespLength; + uint16_t reassoc_req_offset; + uint16_t reassoc_req_length; uint8_t isBeacon; uint8_t roamedVdevId; struct cdf_mac_addr bssid; diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index 2a2134ad58fd..af61ed339e0e 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -2036,6 +2036,31 @@ void lim_roam_offload_synch_ind(tpAniSirGlobal pMac, tpSirMsgQ pMsg) /* Prepare the session right now with as much as possible */ lim_fill_ft_session(pMac, bss_desc_ptr, ft_session_ptr, session_ptr); + + if (ft_session_ptr->assocReqLen) { + /* + * For LFR3 the Assoc Request frame was sent by firmware, hence + * pe session struct does not have corresponding IEs. Firmware + * sends whole ASSOC req frame upto host in Roam Sync Event. + * Copy this frame pe session's buffer, so that it can follow + * LFR2 code path to send them to supplicant. + */ + ft_session_ptr->assocReqLen = + roam_sync_ind_ptr->reassoc_req_length + - SIR_MAC_HDR_LEN_3A - SIR_MAC_REASSOC_SSID_OFFSET; + ft_session_ptr->assocReq = + cdf_mem_malloc(ft_session_ptr->assocReqLen); + if (NULL == ft_session_ptr->assocReq) { + CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR, + "LFR3: Failed to alloc memory for Assoc Req"); + return; + } + cdf_mem_copy(ft_session_ptr->assocReq, + (uint8_t *)roam_sync_ind_ptr + + roam_sync_ind_ptr->reassoc_req_offset + + SIR_MAC_HDR_LEN_3A + SIR_MAC_REASSOC_SSID_OFFSET, + ft_session_ptr->assocReqLen); + } lim_ft_prepare_add_bss_req(pMac, false, ft_session_ptr, bss_desc_ptr); mmh_msg.type = roam_sync_ind_ptr->messageType; diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index f170cca1c1a4..d4bb3367ecf2 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -2728,6 +2728,7 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, wmi_roam_synch_event_fixed_param *synch_event = NULL; uint8_t *bcn_probersp_ptr = NULL; uint8_t *reassoc_rsp_ptr = NULL; + uint8_t *reassoc_req_ptr = NULL; tp_wma_handle wma = (tp_wma_handle) handle; wmi_channel *chan = NULL; wmi_key_material *key = NULL; @@ -2759,7 +2760,8 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, } wma->interfaces[synch_event->vdev_id].roam_synch_in_progress = true; len = sizeof(roam_offload_synch_ind) + - synch_event->bcn_probe_rsp_len + synch_event->reassoc_rsp_len; + synch_event->bcn_probe_rsp_len + synch_event->reassoc_rsp_len + + synch_event->reassoc_req_len; roam_synch_ind_ptr = (roam_offload_synch_ind *) cdf_mem_malloc(len); if (!roam_synch_ind_ptr) { @@ -2786,6 +2788,7 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, roam_synch_ind_ptr->isBeacon = synch_event->is_beacon; WMI_MAC_ADDR_TO_CHAR_ARRAY(&synch_event->bssid, roam_synch_ind_ptr->bssid.bytes); + /* Beacon/Probe Rsp data */ roam_synch_ind_ptr->beaconProbeRespOffset = sizeof(roam_offload_synch_ind); bcn_probersp_ptr = @@ -2795,6 +2798,8 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, synch_event->bcn_probe_rsp_len; cdf_mem_copy(bcn_probersp_ptr, param_buf->bcn_probe_rsp_frame, roam_synch_ind_ptr->beaconProbeRespLength); + + /* ReAssoc Rsp data */ roam_synch_ind_ptr->reassocRespOffset = sizeof(roam_offload_synch_ind) + roam_synch_ind_ptr->beaconProbeRespLength; @@ -2804,18 +2809,37 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, cdf_mem_copy(reassoc_rsp_ptr, param_buf->reassoc_rsp_frame, roam_synch_ind_ptr->reassocRespLength); + + /* ReAssoc Req data */ + roam_synch_ind_ptr->reassoc_req_offset = + sizeof(roam_offload_synch_ind) + + roam_synch_ind_ptr->beaconProbeRespLength + + roam_synch_ind_ptr->reassocRespLength; + roam_synch_ind_ptr->reassoc_req_length = synch_event->reassoc_req_len; + reassoc_req_ptr = (uint8_t *) roam_synch_ind_ptr + + roam_synch_ind_ptr->reassoc_req_offset; + cdf_mem_copy(reassoc_req_ptr, param_buf->reassoc_req_frame, + roam_synch_ind_ptr->reassoc_req_length); + chan = (wmi_channel *) param_buf->chan; roam_synch_ind_ptr->chan_freq = chan->mhz; key = (wmi_key_material *) param_buf->key; if (key != NULL) { - CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_WMA, CDF_TRACE_LEVEL_DEBUG, - key->replay_counter, SIR_REPLAY_CTR_LEN); cdf_mem_copy(roam_synch_ind_ptr->kck, key->kck, SIR_KCK_KEY_LEN); cdf_mem_copy(roam_synch_ind_ptr->kek, key->kek, SIR_KEK_KEY_LEN); cdf_mem_copy(roam_synch_ind_ptr->replay_ctr, key->replay_counter, SIR_REPLAY_CTR_LEN); + WMA_LOGD("%s: KCK dump", __func__); + CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_WMA, CDF_TRACE_LEVEL_DEBUG, + key->kck, SIR_KCK_KEY_LEN); + WMA_LOGD("%s: KEK dump", __func__); + CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_WMA, CDF_TRACE_LEVEL_DEBUG, + key->kek, SIR_KEK_KEY_LEN); + WMA_LOGD("%s: Key Replay Counter dump", __func__); + CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_WMA, CDF_TRACE_LEVEL_DEBUG, + key->replay_counter, SIR_REPLAY_CTR_LEN); } wma_send_msg(wma, WMA_ROAM_OFFLOAD_SYNCH_IND, (void *) roam_synch_ind_ptr, 0);