diff --git a/core/mac/src/cfg/cfgUtil/dot11f.frms b/core/mac/src/cfg/cfgUtil/dot11f.frms index 636bbc10151f..92e7f37e4845 100644 --- a/core/mac/src/cfg/cfgUtil/dot11f.frms +++ b/core/mac/src/cfg/cfgUtil/dot11f.frms @@ -2361,6 +2361,13 @@ IE PTIControl (EID_PTI_CONTROL) // 7.3.2.65 sequence_control, 2; } +IE oci (EID_EXTN_ID_ELEMENT) OUI ( 0x36 ) +{ + op_class, 1; + prim_ch_num, 1; + freq_seg_1_ch_num, 1; +} + IE PUBufferStatus (EID_PU_BUFFER_STATUS) // 7.3.2.66 { { @@ -4406,6 +4413,7 @@ FRAME SaQueryReq FF Category; FF Action; FF TransactionId; + OPTIE oci; } FRAME SaQueryRsp @@ -4413,6 +4421,7 @@ FRAME SaQueryRsp FF Category; FF Action; FF TransactionId; + OPTIE oci; } FRAME QosMapConfigure diff --git a/core/mac/src/include/dot11f.h b/core/mac/src/include/dot11f.h index 52a9243ee2b6..bb66262a4e4b 100644 --- a/core/mac/src/include/dot11f.h +++ b/core/mac/src/include/dot11f.h @@ -26,7 +26,7 @@ * * * This file was automatically generated by 'framesc' - * Thu Oct 1 12:01:17 2020 from the following file(s): + * Fri Oct 9 22:48:44 2020 from the following file(s): * * dot11f.frms * @@ -9706,6 +9706,47 @@ uint32_t dot11f_get_packed_ie_mu_edca_param_set( }; /* End extern "C". */ #endif /* C++ */ +/* EID 255 (0xff) Extended EID 54 (0x36) */ +typedef struct sDot11fIEoci { + uint8_t present; + uint8_t op_class; + uint8_t prim_ch_num; + uint8_t freq_seg_1_ch_num; +} tDot11fIEoci; + +#define DOT11F_EID_OCI (255) + +/* N.B. These #defines do *not* include the EID & length */ +#define DOT11F_IE_OCI_MIN_LEN (3) + +#define DOT11F_IE_OCI_MAX_LEN (3) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +__must_check uint32_t dot11f_unpack_ie_oci( + tpAniSirGlobal, + uint8_t *, + uint8_t, + tDot11fIEoci*, + bool); + +uint32_t dot11f_pack_ie_oci( + tpAniSirGlobal, + tDot11fIEoci *, + uint8_t *, + uint32_t, + uint32_t*); + +uint32_t dot11f_get_packed_ie_oci( + tpAniSirGlobal, + tDot11fIEoci *, + uint32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ + /* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x12} */ typedef struct sDot11fIEosen_ie { uint8_t present; @@ -11091,6 +11132,7 @@ typedef struct sDot11fSaQueryReq{ tDot11fFfCategory Category; tDot11fFfAction Action; tDot11fFfTransactionId TransactionId; + tDot11fIEoci oci; } tDot11fSaQueryReq; #define DOT11F_SAQUERYREQ (29) @@ -11117,6 +11159,7 @@ typedef struct sDot11fSaQueryRsp{ tDot11fFfCategory Category; tDot11fFfAction Action; tDot11fFfTransactionId TransactionId; + tDot11fIEoci oci; } tDot11fSaQueryRsp; #define DOT11F_SAQUERYRSP (30) diff --git a/core/mac/src/include/dph_global.h b/core/mac/src/include/dph_global.h index e9e609a9dd10..572b07962c34 100644 --- a/core/mac/src/include/dph_global.h +++ b/core/mac/src/include/dph_global.h @@ -102,6 +102,7 @@ typedef struct sDphHashNode { uint8_t wsmEnabled:1; uint8_t fAniCount:1; uint8_t rmfEnabled:1; + uint8_t ocv_enabled:1; /* LIM state */ struct lim_sta_context mlmStaContext; /* qos parameter info */ 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 756478471e6f..eb513f8f63ec 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 @@ -1422,6 +1422,29 @@ static void lim_update_sta_ds_op_classes(tpSirAssocReq assoc_req, sizeof(tDot11fIESuppOperatingClasses)); } +static bool lim_is_ocv_enable_in_assoc_req(struct mac_context *mac_ctx, + struct sSirAssocReq *assoc_req) +{ + uint32_t ret; + tDot11fIERSN dot11f_ie_rsn = {0}; + + if ((assoc_req->rsnPresent) && !(assoc_req->rsn.length)) + return false; + + /* Unpack the RSN IE */ + ret = dot11f_unpack_ie_rsn(mac_ctx, &assoc_req->rsn.info[0], + assoc_req->rsn.length, &dot11f_ie_rsn, + false); + if (!DOT11F_SUCCEEDED(ret)) + return false; + + if (*(uint16_t *)&dot11f_ie_rsn.RSN_Cap & + WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED) + return true; + + return false; +} + /** * lim_update_sta_ds() - updates ds dph entry * @mac_ctx: pointer to Global MAC structure @@ -1773,6 +1796,8 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, retry_interval = cfg_default(CFG_PMF_SA_QUERY_RETRY_INTERVAL); } if (sta_ds->rmfEnabled) { + sta_ds->ocv_enabled = lim_is_ocv_enable_in_assoc_req(mac_ctx, + assoc_req); /* Try to delete it before, creating.*/ lim_delete_pmf_query_timer(sta_ds); if (tx_timer_create(mac_ctx, &sta_ds->pmfSaQueryTimer, 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 0e6933c75a54..7a89bd1bda6a 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/core/mac/src/pe/lim/lim_send_management_frames.c @@ -57,6 +57,7 @@ #include "wlan_utility.h" #include #include +#include "wlan_crypto_global_api.h" /** * @@ -5064,6 +5065,44 @@ returnAfterError: return nSirStatus; } /* End lim_send_sa_query_request_frame */ +static bool +lim_is_self_and_peer_ocv_capable(struct mac_context *mac, + uint8_t *peer, + struct pe_session *pe_session) +{ + uint16_t self_rsn_cap, aid; + tpDphHashNode sta_ds; + + self_rsn_cap = wlan_crypto_get_param(pe_session->vdev, + WLAN_CRYPTO_PARAM_RSN_CAP); + if (!(self_rsn_cap & WLAN_CRYPTO_RSN_CAP_OCV_SUPPORTED)) + return false; + + sta_ds = dph_lookup_hash_entry(mac, peer, &aid, + &pe_session->dph.dphHashTable); + + if (sta_ds && sta_ds->ocv_enabled) + return true; + + return false; +} + +static void +lim_fill_oci_params(struct mac_context *mac, struct pe_session *session, + tDot11fIEoci *oci) +{ + uint8_t country_code[CDS_COUNTRY_CODE_LEN + 1]; + + wlan_reg_read_current_country(mac->psoc, country_code); + oci->op_class = wlan_reg_dmn_get_opclass_from_channel( + country_code, + wlan_reg_freq_to_chan(mac->pdev, session->curr_op_freq), + session->ch_width); + oci->prim_ch_num = session->ch_center_freq_seg0; + oci->freq_seg_1_ch_num = session->ch_center_freq_seg1; + oci->present = 1; +} + /** * \brief Send SA query response action frame to peer * @@ -5108,6 +5147,8 @@ QDF_STATUS lim_send_sa_query_response_frame(struct mac_context *mac, /*11w SA query response transId is same as SA query request transId */ qdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2); + if (lim_is_self_and_peer_ocv_capable(mac, peer, pe_session)) + lim_fill_oci_params(mac, pe_session, &frm.oci); nStatus = dot11f_get_packed_sa_query_rsp_size(mac, &frm, &nPayload); if (DOT11F_FAILED(nStatus)) { @@ -5119,7 +5160,6 @@ QDF_STATUS lim_send_sa_query_response_frame(struct mac_context *mac, pe_warn("There were warnings while calculating the packed size for an SA Query Response (0x%08x)", nStatus); } - nBytes = nPayload + sizeof(tSirMacMgmtHdr); qdf_status = cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket); diff --git a/core/mac/src/sys/legacy/src/utils/src/dot11f.c b/core/mac/src/sys/legacy/src/utils/src/dot11f.c index 117ce9c00cba..eb11c3e55b4f 100644 --- a/core/mac/src/sys/legacy/src/utils/src/dot11f.c +++ b/core/mac/src/sys/legacy/src/utils/src/dot11f.c @@ -24,7 +24,7 @@ * * * This file was automatically generated by 'framesc' - * Thu Oct 1 12:01:17 2020 from the following file(s): + * Fri Oct 9 22:48:44 2020 from the following file(s): * * dot11f.frms * @@ -9710,6 +9710,46 @@ uint32_t dot11f_unpack_ie_mu_edca_param_set(tpAniSirGlobal pCtx, #define SigIemu_edca_param_set (0x0094) +uint32_t dot11f_unpack_ie_oci(tpAniSirGlobal pCtx, + uint8_t *pBuf, + uint8_t ielen, + tDot11fIEoci *pDst, + bool append_ie) +{ + uint32_t status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) + return DOT11F_DUPLICATE_IE; + pDst->present = 1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + + pDst->op_class = *pBuf; + pBuf += 1; + ielen -= (uint8_t)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + + pDst->prim_ch_num = *pBuf; + pBuf += 1; + ielen -= (uint8_t)1; + if (unlikely(ielen < 1)) { + pDst->present = 0; + return DOT11F_INCOMPLETE_IE; + } + + pDst->freq_seg_1_ch_num = *pBuf; + (void)pCtx; + return status; +} /* End dot11f_unpack_ie_oci. */ + +#define SigIeoci (0x0095) + + uint32_t dot11f_unpack_ie_osen_ie(tpAniSirGlobal pCtx, uint8_t *pBuf, uint8_t ielen, @@ -9727,7 +9767,7 @@ uint32_t dot11f_unpack_ie_osen_ie(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_osen_ie. */ -#define SigIeosen_ie (0x0095) +#define SigIeosen_ie (0x0096) static const tTLVDefn TLVS_qcn_ie[] = { @@ -9782,7 +9822,7 @@ uint32_t dot11f_unpack_ie_qcn_ie(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_qcn_ie. */ -#define SigIeqcn_ie (0x0096) +#define SigIeqcn_ie (0x0097) uint32_t dot11f_unpack_ie_roaming_consortium_sel(tpAniSirGlobal pCtx, @@ -9802,7 +9842,7 @@ uint32_t dot11f_unpack_ie_roaming_consortium_sel(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_roaming_consortium_sel. */ -#define SigIeroaming_consortium_sel (0x0097) +#define SigIeroaming_consortium_sel (0x0098) uint32_t dot11f_unpack_ie_sec_chan_offset_ele(tpAniSirGlobal pCtx, @@ -9826,7 +9866,7 @@ uint32_t dot11f_unpack_ie_sec_chan_offset_ele(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_sec_chan_offset_ele. */ -#define SigIesec_chan_offset_ele (0x0098) +#define SigIesec_chan_offset_ele (0x0099) static const tFFDefn FFS_vendor_vht_ie[] = { @@ -9875,7 +9915,7 @@ uint32_t dot11f_unpack_ie_vendor_vht_ie(tpAniSirGlobal pCtx, return status; } /* End dot11f_unpack_ie_vendor_vht_ie. */ -#define SigIevendor_vht_ie (0x0099) +#define SigIevendor_vht_ie (0x009a) static const tFFDefn FFS_AddTSRequest[] = { @@ -12192,6 +12232,8 @@ static const tFFDefn FFS_SaQueryReq[] = { }; static const tIEDefn IES_SaQueryReq[] = { + { offsetof(tDot11fSaQueryReq, oci), offsetof(tDot11fIEoci, present), 0, + "oci", 0, 5, 5, SigIeoci, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OCI, 54, 0, }, {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },}; uint32_t dot11f_unpack_sa_query_req(tpAniSirGlobal pCtx, @@ -12220,6 +12262,8 @@ static const tFFDefn FFS_SaQueryRsp[] = { }; static const tIEDefn IES_SaQueryRsp[] = { + { offsetof(tDot11fSaQueryRsp, oci), offsetof(tDot11fIEoci, present), 0, + "oci", 0, 5, 5, SigIeoci, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OCI, 54, 0, }, {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },}; uint32_t dot11f_unpack_sa_query_rsp(tpAniSirGlobal pCtx, @@ -15047,6 +15091,16 @@ static uint32_t unpack_core(tpAniSirGlobal pCtx, countOffset), append_ie); break; + case SigIeoci: + status |= + dot11f_unpack_ie_oci( + pCtx, pBufRemaining, len, + (tDot11fIEoci *) + (pFrm + pIe->offset + + sizeof(tDot11fIEoci) * + countOffset), + append_ie); + break; case SigIeosen_ie: status |= dot11f_unpack_ie_osen_ie( @@ -18322,6 +18376,13 @@ static uint32_t get_packed_size_core(tpAniSirGlobal pCtx, (pFrm + pIe->offset + offset * i))-> present; break; + case SigIeoci: + offset = sizeof(tDot11fIEoci); + byteCount = 3; + pIePresent = ((tDot11fIEoci *) + (pFrm + pIe->offset + offset * i))-> + present; + break; case SigIeosen_ie: offset = sizeof(tDot11fIEosen_ie); byteCount = ((tDot11fIEosen_ie *) @@ -27998,6 +28059,43 @@ uint32_t dot11f_pack_ie_mu_edca_param_set(tpAniSirGlobal pCtx, return DOT11F_PARSE_SUCCESS; } /* End dot11f_pack_ie_mu_edca_param_set. */ +uint32_t dot11f_pack_ie_oci(tpAniSirGlobal pCtx, + tDot11fIEoci *pSrc, + uint8_t *pBuf, + uint32_t nBuf, + uint32_t *pnConsumed) +{ + uint8_t *pIeLen = 0; + uint32_t nConsumedOnEntry = *pnConsumed; + uint32_t nNeeded = 0U; + nNeeded += 3; + while (pSrc->present) { + if (nNeeded > nBuf) + return DOT11F_BUFFER_OVERFLOW; + *pBuf = 255; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 54; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->op_class; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->prim_ch_num; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->freq_seg_1_ch_num; + *pnConsumed += 1; + /* fieldsEndFlag = 1 */ + break; + } + (void)pCtx; + if (pIeLen) { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11f_pack_ie_oci. */ + uint32_t dot11f_pack_ie_osen_ie(tpAniSirGlobal pCtx, tDot11fIEosen_ie *pSrc, uint8_t *pBuf, @@ -30435,6 +30533,14 @@ static uint32_t pack_core(tpAniSirGlobal pCtx, sizeof(tDot11fIEmu_edca_param_set) * i), pBufRemaining, nBufRemaining, &len); break; + case SigIeoci: + status |= + dot11f_pack_ie_oci( + pCtx, (tDot11fIEoci *) + (pSrc + pIe->offset + + sizeof(tDot11fIEoci) * i), + pBufRemaining, nBufRemaining, &len); + break; case SigIeosen_ie: status |= dot11f_pack_ie_osen_ie(