qcacld-3.0: mlo sap bss start

mlo sap bss start implementation

Change-Id: I662c0b469dc5e4430ec7a819ec4ba954bccf5a25
CRs-Fixed: 2974664
This commit is contained in:
bings
2021-04-02 15:08:32 +08:00
zatwierdzone przez Madan Koyyalamudi
rodzic 675c5796ac
commit ec8096ea07
7 zmienionych plików z 515 dodań i 1 usunięć

4
Kbuild
Wyświetl plik

@@ -625,6 +625,10 @@ ifeq ($(CONFIG_QCACLD_WLAN_LFR2), y)
$(MAC_SRC_DIR)/pe/lim/lim_reassoc_utils.o
endif
ifeq ($(CONFIG_WLAN_FEATURE_11BE_MLO), y)
MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/lim_mlo.o
endif
MAC_SCH_OBJS := $(MAC_SRC_DIR)/pe/sch/sch_api.o \
$(MAC_SRC_DIR)/pe/sch/sch_beacon_gen.o \
$(MAC_SRC_DIR)/pe/sch/sch_beacon_process.o \

Wyświetl plik

@@ -3855,6 +3855,7 @@ struct sir_nss_update_request {
* @REASON_SET_HT2040: HT2040 update
* @REASON_COLOR_CHANGE: Color change
* @REASON_CHANNEL_SWITCH: channel switch
* @REASON_MLO_IE_UPDATE: mlo ie update
*/
enum sir_bcn_update_reason {
REASON_DEFAULT = 0,
@@ -3863,6 +3864,7 @@ enum sir_bcn_update_reason {
REASON_SET_HT2040 = 3,
REASON_COLOR_CHANGE = 4,
REASON_CHANNEL_SWITCH = 5,
REASON_MLO_IE_UPDATE = 6,
};
/**

Wyświetl plik

@@ -124,6 +124,74 @@ struct obss_detection_cfg {
#define ADAPTIVE_11R_DATA_LEN 0x04
#define ADAPTIVE_11R_OUI_DATA "\x00\x00\x00\x01"
#ifdef WLAN_FEATURE_11BE_MLO
/**
* struct mlo_link_ie - IE per link to populate mlo ie
* @link_ds: DS IE
* @link_edca: ecsa IE
* @link_wmm_params: wmm params IE
* @link_wmm_caps: wmm caps IE
* @link_csa: csa IE
* @link_ecsa:ecsa IE
* @link_swt_time: switch time IE
* @link_quiet: quiet IE
* @link_ht_cap: ht cap IE
* @link_ht_info: ht info IE
* @link_cap: link caps IE
* @link_ext_cap: link extend cap IE
* @link_vht_cap: vht cap IE
* @link_vht_op: vht op IE
* @link_qcn_ie: qcn IE
* @link_he_cap: he cap IE
* @link_he_op: he op IE
* @link_he_6ghz_band_cap: 6G band cap IE
* @link_eht_cap: eht cap IE
* @link_eht_op: eht op IE
* @max_chan_swt_time: MLOTD
* @bss_param_change_cnt: bss param change count
*/
struct mlo_link_ie {
tDot11fIEDSParams link_ds;
tDot11fIEEDCAParamSet link_edca;
tDot11fIEWMMParams link_wmm_params;
tDot11fIEWMMCaps link_wmm_caps;
tDot11fIEChanSwitchAnn link_csa;
tDot11fIEext_chan_switch_ann link_ecsa;
tDot11fIEmax_chan_switch_time link_swt_time;
tDot11fIEQuiet link_quiet;
tDot11fIEHTCaps link_ht_cap;
tDot11fIEHTInfo link_ht_info;
tDot11fFfCapabilities link_cap;
tDot11fIEExtCap link_ext_cap;
tDot11fIEVHTCaps link_vht_cap;
tDot11fIEVHTOperation link_vht_op;
tDot11fIEqcn_ie link_qcn_ie;
tDot11fIEhe_cap link_he_cap;
tDot11fIEhe_op link_he_op;
tDot11fIEhe_6ghz_band_cap link_he_6ghz_band_cap;
tDot11fIEeht_cap link_eht_cap;
tDot11fIEeht_op link_eht_op;
uint32_t max_chan_swt_time;
uint8_t bss_param_change_cnt;
};
/**
* struct mlo_link_ie_info - information per link to populate mlo ie
* @upt_bcn_mlo_ie: notify partner links to update their mlo ie of bcn temp
* @mlo_rnr_updated: link already notified partner link to update rnr
* @bss_param_change: bss param changed
* @bcn_tmpl_exist: bcn template is generated or not
* @link_ie: IEs which will be used for generating partner mlo IE
*/
struct mlo_link_ie_info {
bool upt_bcn_mlo_ie;
bool mlo_rnr_updated;
bool bss_param_change;
bool bcn_tmpl_exist;
struct mlo_link_ie link_ie;
};
#endif
/**
* struct pe_session - per-vdev PE context
* @available: true if the entry is available, false if it is in use
@@ -583,6 +651,9 @@ struct pe_session {
bool eht_capable;
tDot11fIEeht_cap eht_config;
tDot11fIEeht_op eht_op;
#ifdef WLAN_FEATURE_11BE_MLO
struct mlo_link_ie_info mlo_link_info;
#endif
#endif /* WLAN_FEATURE_11BE */
};

Wyświetl plik

@@ -0,0 +1,124 @@
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC : lim_mlo.c
*
* WLAN Host Device Driver file for 802.11be (Extremely High Throughput)
* support.
*
*/
#include "lim_mlo.h"
#include "sch_api.h"
#include "lim_types.h"
#include "wlan_mlo_mgr_ap.h"
/**
* lim_send_mlo_ie_update - mlo ie is changed, populate new beacon template
* @session: pe session
*
* Return: void
*/
static void lim_send_mlo_ie_update(struct mac_context *mac_ctx,
struct pe_session *session)
{
if (QDF_IS_STATUS_ERROR(
sch_set_fixed_beacon_fields(mac_ctx, session))) {
pe_err("Unable to update mlo IE in beacon");
return;
}
lim_send_beacon_ind(mac_ctx, session, REASON_MLO_IE_UPDATE);
}
QDF_STATUS lim_partner_link_info_change(struct wlan_objmgr_vdev *vdev)
{
struct pe_session *session;
struct mac_context *mac;
mac = cds_get_context(QDF_MODULE_ID_PE);
if (!mac) {
pe_err("mac ctx is null");
return QDF_STATUS_E_INVAL;
}
if (!vdev) {
pe_err("vdev is null");
return QDF_STATUS_E_INVAL;
}
session = pe_find_session_by_vdev_id(
mac, vdev->vdev_objmgr.vdev_id);
if (!session) {
pe_err("session is NULL");
return QDF_STATUS_E_INVAL;
}
if (session->mlo_link_info.bcn_tmpl_exist)
lim_send_mlo_ie_update(mac, session);
return QDF_STATUS_SUCCESS;
}
uint8_t lim_get_max_simultaneous_link_num(struct pe_session *session)
{
struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS];
uint16_t vdev_count = 0;
mlo_ap_get_vdev_list(session->vdev, &vdev_count,
wlan_vdev_list);
return vdev_count;
}
void lim_mlo_release_vdev_ref(struct wlan_objmgr_vdev *vdev)
{
mlo_release_vdev_ref(vdev);
}
struct pe_session *pe_find_partner_session_by_link_id(
struct pe_session *session, uint8_t link_id)
{
struct wlan_objmgr_vdev *vdev;
struct mac_context *mac;
mac = cds_get_context(QDF_MODULE_ID_PE);
if (!mac) {
pe_err("mac ctx is null");
return NULL;
}
if (!session) {
pe_err("session is null");
return NULL;
}
vdev = mlo_get_partner_vdev_by_link_id(session->vdev, link_id);
if (!vdev) {
pe_err("vdev is null");
return NULL;
}
return pe_find_session_by_vdev_id(
mac, vdev->vdev_objmgr.vdev_id);
}
void lim_get_mlo_vdev_list(struct pe_session *session, uint16_t *vdev_count,
struct wlan_objmgr_vdev **wlan_vdev_list)
{
mlo_ap_get_vdev_list(session->vdev, vdev_count,
wlan_vdev_list);
}

Wyświetl plik

@@ -0,0 +1,82 @@
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC : lim_mlo.h
*
* WLAN Host Device Driver file for 802.11be (Extremely High Throughput)
* support.
*
*/
#if !defined(LIM_MLO_H)
#define LIM_MLO_H
#include "ani_global.h"
#include "lim_session.h"
#ifdef WLAN_FEATURE_11BE_MLO
/**
* lim_update_partner_link_info - Update partner link information
*
* This function is triggered from mlo mgr
*
* @vdev: vdev pointer
*
* Return: QDF_STATUS_SUCCESS on successful update link info else failure.
*/
QDF_STATUS lim_partner_link_info_change(struct wlan_objmgr_vdev *vdev);
/**
* lim_get_max_simultaneous_link_num() - Get max simultaneous link num
* It is max vdev number for sap
* @session: pe session
*
* Return: max simultaneous link num
*/
uint8_t lim_get_max_simultaneous_link_num(struct pe_session *session);
/**
* lim_mlo_free_vdev_ref() - release vdev reference
* @vdev: vdev obj
*
* Return: void
*/
void lim_mlo_release_vdev_ref(struct wlan_objmgr_vdev *vdev);
/**
* pe_find_partner_session_by_link_id() - Get partner session by link id
* @session: pe session
* @link_id: link id
*
* Return: partner session
*/
struct pe_session *pe_find_partner_session_by_link_id(
struct pe_session *session, uint8_t link_id);
/**
* lim_get_mlo_vdev_list() - Get mlo vdev list
* @session: pe session
* @vdev_count: vdev count
* @wlan_vdev_list: vdev list
*
* Return: void
*/
void lim_get_mlo_vdev_list(struct pe_session *session, uint16_t *vdev_count,
struct wlan_objmgr_vdev **wlan_vdev_list);
#endif
#endif

Wyświetl plik

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -46,6 +46,47 @@
#include "wma_types.h"
#ifdef WLAN_FEATURE_11BE_MLO
#include "lim_mlo.h"
#endif
#ifdef WLAN_FEATURE_11BE_MLO
/**
* lim_notify_link_info() - notify partner link to update beacon template
* @pe_session: pointer to pe session
*
* Return: void
*/
static void lim_notify_link_info(struct pe_session *pe_session)
{
struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS];
uint16_t vdev_count = 0;
int link;
if (!pe_session->mlo_link_info.upt_bcn_mlo_ie &&
pe_session->mlo_link_info.mlo_rnr_updated)
return;
pe_session->mlo_link_info.mlo_rnr_updated = true;
pe_debug("mlo notify beacon change info to partner link");
lim_get_mlo_vdev_list(pe_session, &vdev_count,
wlan_vdev_list);
for (link = 0; link < vdev_count; link++) {
if (!wlan_vdev_list[link])
continue;
if (wlan_vdev_list[link] == session->vdev) {
lim_mlo_release_vdev_ref(wlan_vdev_list[link]);
continue;
}
lim_partner_link_info_change(wlan_vdev_list[link]);
lim_mlo_release_vdev_ref(wlan_vdev_list[link]);
}
}
#else
static void lim_notify_link_info(struct pe_session *pe_session)
{
}
#endif
QDF_STATUS sch_send_beacon_req(struct mac_context *mac, uint8_t *beaconPayload,
uint16_t size, struct pe_session *pe_session,
enum sir_bcn_update_reason reason)
@@ -121,6 +162,11 @@ QDF_STATUS sch_send_beacon_req(struct mac_context *mac, uint8_t *beaconPayload,
pe_err("Posting SEND_BEACON_REQ to HAL failed, reason=%X",
retCode);
if (QDF_IS_STATUS_SUCCESS(retCode)) {
if (wlan_vdev_mlme_is_mlo_ap(pe_session->vdev))
lim_notify_link_info(pe_session);
}
return retCode;
}

Wyświetl plik

@@ -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)