|
@@ -48,6 +48,163 @@
|
|
|
|
|
|
const uint8_t p2p_oui[] = { 0x50, 0x6F, 0x9A, 0x9 };
|
|
|
|
|
|
+#ifdef WLAN_FEATURE_11BE_MLO
|
|
|
+/**
|
|
|
+ * lim_update_link_info() - update mlo_link_info
|
|
|
+ * @mac_ctx: mac context
|
|
|
+ * @session: pe session
|
|
|
+ * @bcn_1: pointer to tDot11fBeacon1
|
|
|
+ * @bcn_2: pointer to tDot11fBeacon2
|
|
|
+ *
|
|
|
+ * Return: void
|
|
|
+ */
|
|
|
+static void lim_update_link_info(struct mac_context *mac_ctx,
|
|
|
+ struct pe_session *session,
|
|
|
+ tDot11fBeacon1 *bcn_1,
|
|
|
+ tDot11fBeacon2 *bcn_2)
|
|
|
+{
|
|
|
+ struct mlo_link_ie *link_ie = &session->mlo_link_info.link_ie;
|
|
|
+ uint16_t offset;
|
|
|
+ uint8_t *ptr;
|
|
|
+ uint32_t n_bytes;
|
|
|
+
|
|
|
+ session->mlo_link_info.upt_bcn_mlo_ie = false;
|
|
|
+ session->mlo_link_info.bss_param_change = false;
|
|
|
+
|
|
|
+ if (qdf_mem_cmp(&link_ie->link_ds, &bcn_1->DSParams,
|
|
|
+ sizeof(bcn_1->DSParams))) {
|
|
|
+ qdf_mem_copy(&link_ie->link_ds, &bcn_1->DSParams,
|
|
|
+ sizeof(bcn_1->DSParams));
|
|
|
+ session->mlo_link_info.bss_param_change = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ qdf_mem_copy(&link_ie->link_wmm_params, &bcn_2->WMMParams,
|
|
|
+ sizeof(bcn_2->WMMParams));
|
|
|
+
|
|
|
+ qdf_mem_copy(&link_ie->link_wmm_caps, &bcn_2->WMMCaps,
|
|
|
+ sizeof(bcn_2->WMMCaps));
|
|
|
+
|
|
|
+ if (qdf_mem_cmp(&link_ie->link_edca, &bcn_2->EDCAParamSet,
|
|
|
+ sizeof(bcn_2->EDCAParamSet))) {
|
|
|
+ qdf_mem_copy(&link_ie->link_edca, &bcn_2->EDCAParamSet,
|
|
|
+ sizeof(bcn_2->EDCAParamSet));
|
|
|
+ session->mlo_link_info.bss_param_change = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (qdf_mem_cmp(&link_ie->link_csa, &bcn_2->ChanSwitchAnn,
|
|
|
+ sizeof(bcn_2->ChanSwitchAnn))) {
|
|
|
+ session->mlo_link_info.upt_bcn_mlo_ie = true;
|
|
|
+ qdf_mem_copy(&link_ie->link_csa, &bcn_2->ChanSwitchAnn,
|
|
|
+ sizeof(bcn_2->ChanSwitchAnn));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (qdf_mem_cmp(&link_ie->link_ecsa, &bcn_2->ext_chan_switch_ann,
|
|
|
+ sizeof(bcn_2->ext_chan_switch_ann))) {
|
|
|
+ session->mlo_link_info.upt_bcn_mlo_ie = true;
|
|
|
+ qdf_mem_copy(&link_ie->link_ecsa, &bcn_2->ext_chan_switch_ann,
|
|
|
+ sizeof(bcn_2->ext_chan_switch_ann));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (qdf_mem_cmp(&link_ie->link_swt_time, &bcn_2->max_chan_switch_time,
|
|
|
+ sizeof(bcn_2->max_chan_switch_time))) {
|
|
|
+ session->mlo_link_info.upt_bcn_mlo_ie = true;
|
|
|
+ qdf_mem_copy(&link_ie->link_swt_time,
|
|
|
+ &bcn_2->max_chan_switch_time,
|
|
|
+ sizeof(bcn_2->max_chan_switch_time));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (qdf_mem_cmp(&link_ie->link_quiet, &bcn_2->Quiet,
|
|
|
+ sizeof(bcn_2->Quiet))) {
|
|
|
+ session->mlo_link_info.upt_bcn_mlo_ie = true;
|
|
|
+ qdf_mem_copy(&link_ie->link_quiet, &bcn_2->Quiet,
|
|
|
+ sizeof(bcn_2->Quiet));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (qdf_mem_cmp(&link_ie->link_ht_info, &bcn_2->HTInfo,
|
|
|
+ sizeof(bcn_2->HTInfo))) {
|
|
|
+ qdf_mem_copy(&link_ie->link_ht_info, &bcn_2->HTInfo,
|
|
|
+ sizeof(bcn_2->HTInfo));
|
|
|
+ session->mlo_link_info.bss_param_change = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (qdf_mem_cmp(&link_ie->link_vht_op, &bcn_2->VHTOperation,
|
|
|
+ sizeof(bcn_2->VHTOperation))) {
|
|
|
+ qdf_mem_copy(&link_ie->link_vht_op, &bcn_2->VHTOperation,
|
|
|
+ sizeof(bcn_2->VHTOperation));
|
|
|
+ session->mlo_link_info.bss_param_change = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (qdf_mem_cmp(&link_ie->link_he_op, &bcn_2->he_op,
|
|
|
+ sizeof(bcn_2->he_op))) {
|
|
|
+ qdf_mem_copy(&link_ie->link_he_op, &bcn_2->he_op,
|
|
|
+ sizeof(bcn_2->he_op));
|
|
|
+ session->mlo_link_info.bss_param_change = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (qdf_mem_cmp(&link_ie->link_eht_op, &bcn_2->eht_op,
|
|
|
+ sizeof(bcn_2->eht_op))) {
|
|
|
+ qdf_mem_copy(&link_ie->link_eht_op, &bcn_2->eht_op,
|
|
|
+ sizeof(bcn_2->eht_op));
|
|
|
+ session->mlo_link_info.bss_param_change = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * MLOTD
|
|
|
+ * If max channel switch time is not exist, calculate one for partner
|
|
|
+ * link, if current link enters CAC
|
|
|
+ */
|
|
|
+
|
|
|
+ if (session->mlo_link_info.bcn_tmpl_exist) {
|
|
|
+ if (bcn_2->ChanSwitchAnn.present ||
|
|
|
+ bcn_2->ext_chan_switch_ann.present ||
|
|
|
+ bcn_2->Quiet.present ||
|
|
|
+ bcn_2->WiderBWChanSwitchAnn.present ||
|
|
|
+ bcn_2->ChannelSwitchWrapper.present ||
|
|
|
+ bcn_2->OperatingMode.present ||
|
|
|
+ bcn_2->bss_color_change.present)
|
|
|
+ session->mlo_link_info.bss_param_change = true;
|
|
|
+ if (session->mlo_link_info.bss_param_change) {
|
|
|
+ link_ie->bss_param_change_cnt++;
|
|
|
+ offset = sizeof(tAniBeaconStruct);
|
|
|
+ bcn_1->Capabilities.criticalUpdateFlag = 1;
|
|
|
+ ptr = session->pSchBeaconFrameBegin + offset;
|
|
|
+ dot11f_pack_beacon1(mac_ctx, bcn_1, ptr,
|
|
|
+ SIR_MAX_BEACON_SIZE - offset,
|
|
|
+ &n_bytes);
|
|
|
+ bcn_1->Capabilities.criticalUpdateFlag = 0;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //save one time
|
|
|
+ session->mlo_link_info.bcn_tmpl_exist = true;
|
|
|
+ session->mlo_link_info.link_ie.bss_param_change_cnt = 0;
|
|
|
+ qdf_mem_copy(&link_ie->link_cap, &bcn_1->Capabilities,
|
|
|
+ sizeof(bcn_1->Capabilities));
|
|
|
+ qdf_mem_copy(&link_ie->link_qcn_ie, &bcn_2->qcn_ie,
|
|
|
+ sizeof(bcn_2->qcn_ie));
|
|
|
+ qdf_mem_copy(&link_ie->link_ht_cap, &bcn_2->HTCaps,
|
|
|
+ sizeof(bcn_2->HTCaps));
|
|
|
+ qdf_mem_copy(&link_ie->link_ext_cap, &bcn_2->ExtCap,
|
|
|
+ sizeof(bcn_2->ExtCap));
|
|
|
+ qdf_mem_copy(&link_ie->link_vht_cap, &bcn_2->VHTCaps,
|
|
|
+ sizeof(bcn_2->VHTCaps));
|
|
|
+ qdf_mem_copy(&link_ie->link_he_cap, &bcn_2->he_cap,
|
|
|
+ sizeof(bcn_2->he_cap));
|
|
|
+ qdf_mem_copy(&link_ie->link_he_6ghz_band_cap,
|
|
|
+ &bcn_2->he_6ghz_band_cap,
|
|
|
+ sizeof(bcn_2->he_6ghz_band_cap));
|
|
|
+ qdf_mem_copy(&link_ie->link_eht_cap, &bcn_2->eht_cap,
|
|
|
+ sizeof(bcn_2->eht_cap));
|
|
|
+ }
|
|
|
+}
|
|
|
+#else
|
|
|
+static void lim_update_link_info(struct mac_context *mac_ctx,
|
|
|
+ struct pe_session *session,
|
|
|
+ tDot11fBeacon1 *bcn_1,
|
|
|
+ tDot11fBeacon2 *bcn_2)
|
|
|
+{
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
static QDF_STATUS sch_get_p2p_ie_offset(uint8_t *pextra_ie,
|
|
|
uint32_t extra_ie_len,
|
|
|
uint16_t *pie_offset)
|
|
@@ -437,6 +594,11 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if (bcn_2->ext_chan_switch_ann.present || bcn_2->ChanSwitchAnn.present)
|
|
|
+ populate_dot11f_max_chan_switch_time(
|
|
|
+ mac_ctx, &bcn_2->max_chan_switch_time, session);
|
|
|
+
|
|
|
if (mac_ctx->rrm.rrmConfig.sap_rrm_enabled)
|
|
|
populate_dot11f_rrm_ie(mac_ctx, &bcn_2->RRMEnabledCap,
|
|
|
session);
|
|
@@ -548,6 +710,14 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
|
|
|
}
|
|
|
|
|
|
if (LIM_IS_AP_ROLE(session)) {
|
|
|
+ if (wlan_vdev_mlme_is_mlo_ap(session->vdev)) {
|
|
|
+ lim_update_link_info(mac_ctx, session, bcn_1, bcn_2);
|
|
|
+ populate_dot11f_bcn_mlo_ie(mac_ctx, session,
|
|
|
+ &bcn_2->mlo_ie);
|
|
|
+ populate_dot11f_mlo_rnr(
|
|
|
+ mac_ctx, session,
|
|
|
+ &bcn_2->reduced_neighbor_report);
|
|
|
+ }
|
|
|
/*
|
|
|
* Can be efficiently updated whenever new IE added in Probe
|
|
|
* response in future
|
|
@@ -959,6 +1129,21 @@ void lim_update_probe_rsp_template_ie_bitmap_beacon2(struct mac_context *mac,
|
|
|
sizeof(beacon2->eht_op));
|
|
|
}
|
|
|
|
|
|
+ if (beacon2->mlo_ie.present) {
|
|
|
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
|
|
|
+ DOT11F_EID_MLO_IE);
|
|
|
+ qdf_mem_copy((void *)&prb_rsp->mlo_ie,
|
|
|
+ (void *)&beacon2->mlo_ie,
|
|
|
+ sizeof(beacon2->mlo_ie));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (beacon2->reduced_neighbor_report.present) {
|
|
|
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
|
|
|
+ DOT11F_EID_REDUCED_NEIGHBOR_REPORT);
|
|
|
+ qdf_mem_copy((void *)&prb_rsp->reduced_neighbor_report,
|
|
|
+ (void *)&beacon2->reduced_neighbor_report,
|
|
|
+ sizeof(beacon2->reduced_neighbor_report));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void set_probe_rsp_ie_bitmap(uint32_t *IeBitmap, uint32_t pos)
|