qcacmn: Add MLO NAWDS support

Changes to support NAWDS (Non Association based
WDS) when MLO is enabled.
Since NAWDS repeater works without association, user
inputs capabilities and puncture_bitmap associated with
each link. The same information is to be passed to
mlme peer create API to configure the STA nodes per
capability & puncture bitmap provided by user.

Change-Id: Ia0722a454321bf9d408860276f852dd10712c12c
CRs-Fixed: 3077880
This commit is contained in:
Shwetha G K
2021-12-09 03:34:35 +05:30
committed by Madan Koyyalamudi
parent 9a4ae1a05a
commit 3c5ce319c3
5 changed files with 161 additions and 2 deletions

View File

@@ -23,6 +23,7 @@
#include <wlan_mlo_mgr_cmn.h>
#include <wlan_mlo_mgr_public_structs.h>
#include "wlan_mlo_mgr_msgq.h"
#define WLAN_RESV_AID_BITS 0xc000
#define WLAN_AID(b) ((b) & ~0xc000)
@@ -404,4 +405,39 @@ void mlo_ap_vdev_quiet_clear(struct wlan_objmgr_vdev *vdev);
* Return: true, if any index is set, else false
*/
bool mlo_ap_vdev_quiet_is_any_idx_set(struct wlan_objmgr_vdev *vdev);
#ifdef UMAC_SUPPORT_MLNAWDS
/**
* mlo_peer_populate_nawds_params() - Populate nawds parameters in ml_peer
* @ml_peer: ml_peer to which nawds config parameters need to be populated
* @ml_info: ml_info with nawds config associated with this link
*
* Return: void
*/
void mlo_peer_populate_nawds_params(
struct wlan_mlo_peer_context *ml_peer,
struct mlo_partner_info *ml_info);
#else
static inline
void mlo_peer_populate_nawds_params(
struct wlan_mlo_peer_context *ml_peer,
struct mlo_partner_info *ml_info)
{
}
#endif
/**
* mlo_peer_create_get_frm_buf() - get frm_buf to peer_create
* @ml_peer: MLO peer
* @peer_create: pointer to peer_create_notif context
* @frm_buf: pointer to frame buffer to be cloned to peer_create
*
* Return: SUCCESS if
* - peer_create frame buffer cloned successfully in non NAWDS case Or
* - ml_peer is in NAWDS mode.
*/
QDF_STATUS mlo_peer_create_get_frm_buf(
struct wlan_mlo_peer_context *ml_peer,
struct peer_create_notif_s *peer_create,
qdf_nbuf_t frm_buf);
#endif

View File

@@ -505,4 +505,20 @@ static inline void wlan_peer_clear_mlo(struct wlan_objmgr_peer *peer)
{
return wlan_peer_mlme_flag_ext_clear(peer, WLAN_PEER_FEXT_MLO);
}
#ifdef UMAC_SUPPORT_MLNAWDS
/**
* wlan_mlo_peer_is_nawds() - Check if ml_peer is configured to operate as NAWDS
* @ml_peer: MLO peer
*
* Return TRUE if ml peer is configured as NAWDS
*/
bool wlan_mlo_peer_is_nawds(struct wlan_mlo_peer_context *ml_peer);
#else
static inline
bool wlan_mlo_peer_is_nawds(struct wlan_mlo_peer_context *ml_peer)
{
return false;
}
#endif
#endif

View File

@@ -274,6 +274,21 @@ enum mlo_peer_state {
ML_PEER_DISCONN_INITIATED,
};
#ifdef UMAC_SUPPORT_MLNAWDS
/*
* struct mlnawds_config - MLO NAWDS configuration
* @caps: Bandwidth & NSS capabilities to be configured on NAWDS peer
* @puncture_bitmap: puncture bitmap to be configured on NAWDS peer
* @mac: MAC address of the NAWDS peer to which the caps & puncture bitmap is
* to be configured.
*/
struct mlnawds_config {
uint64_t caps;
uint16_t puncture_bitmap;
uint8_t mac[QDF_MAC_ADDR_SIZE];
};
#endif
/*
* struct wlan_mlo_peer_context - MLO peer context
*
@@ -290,6 +305,8 @@ enum mlo_peer_state {
* @ml_dev: MLO dev context
* @mlpeer_state: MLO peer state
* @avg_link_rssi: avg RSSI of ML peer
* @is_nawds_ml_peer: flag to indicate if ml_peer is NAWDS configured
* @nawds_config: eack link peer's NAWDS configuration
*/
struct wlan_mlo_peer_context {
qdf_list_node_t peer_node;
@@ -310,6 +327,10 @@ struct wlan_mlo_peer_context {
struct wlan_mlo_dev_context *ml_dev;
enum mlo_peer_state mlpeer_state;
int8_t avg_link_rssi;
#ifdef UMAC_SUPPORT_MLNAWDS
bool is_nawds_ml_peer;
struct mlnawds_config nawds_config[MAX_MLO_LINK_PEERS];
#endif
};
/*
@@ -317,11 +338,15 @@ struct wlan_mlo_peer_context {
* @link_addr: link mac address
* @link_id: link index
* @chan_freq: Operating channel frequency
* @nawds_config: peer's NAWDS configurarion
*/
struct mlo_link_info {
struct qdf_mac_addr link_addr;
uint8_t link_id;
uint16_t chan_freq;
#ifdef UMAC_SUPPORT_MLNAWDS
struct mlnawds_config nawds_config;
#endif
};
/*

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. 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
@@ -295,3 +296,65 @@ bool mlo_ap_vdev_quiet_is_any_idx_set(struct wlan_objmgr_vdev *vdev)
mld_ctx->ap_ctx->mlo_vdev_quiet_bmap,
sizeof(mld_ctx->ap_ctx->mlo_vdev_quiet_bmap));
}
#ifdef UMAC_SUPPORT_MLNAWDS
QDF_STATUS
mlo_peer_create_get_frm_buf(
struct wlan_mlo_peer_context *ml_peer,
struct peer_create_notif_s *peer_create,
qdf_nbuf_t frm_buf)
{
if (ml_peer->is_nawds_ml_peer) {
peer_create->frm_buf = NULL;
return QDF_STATUS_SUCCESS;
}
peer_create->frm_buf = qdf_nbuf_clone(frm_buf);
if (!peer_create->frm_buf)
return QDF_STATUS_E_NOMEM;
return QDF_STATUS_SUCCESS;
}
void mlo_peer_populate_nawds_params(
struct wlan_mlo_peer_context *ml_peer,
struct mlo_partner_info *ml_info)
{
uint8_t i;
uint8_t null_mac[QDF_MAC_ADDR_SIZE] = {0x00, 0x00, 0x00,
0x00, 0x00, 0x00};
struct mlnawds_config nawds_config;
mlo_peer_lock_acquire(ml_peer);
ml_peer->is_nawds_ml_peer = false;
for (i = 0; i < ml_info->num_partner_links; i++) {
nawds_config = ml_info->partner_link_info[i].nawds_config;
/**
* if ml_info->partner_link_info[i].nawds_config has valid
* config(check for non-null mac or non-0 caps), then mark
* ml_peer's is_nawds_ml_peer true & copy the config
*/
if ((nawds_config.caps) ||
(qdf_mem_cmp(null_mac,
nawds_config.mac,
sizeof(null_mac)))) {
ml_peer->is_nawds_ml_peer = true;
ml_peer->nawds_config[i] = nawds_config;
}
}
mlo_peer_lock_release(ml_peer);
}
#else
QDF_STATUS
mlo_peer_create_get_frm_buf(
struct wlan_mlo_peer_context *ml_peer,
struct peer_create_notif_s *peer_create,
qdf_nbuf_t frm_buf)
{
peer_create->frm_buf = qdf_nbuf_clone(frm_buf);
if (!peer_create->frm_buf)
return QDF_STATUS_E_NOMEM;
return QDF_STATUS_SUCCESS;
}
#endif

View File

@@ -56,8 +56,9 @@ static void mlo_partner_peer_create_post(struct wlan_mlo_dev_context *ml_dev,
break;
}
peer_create.frm_buf = qdf_nbuf_clone(frm_buf);
if (!peer_create.frm_buf) {
status = mlo_peer_create_get_frm_buf(ml_peer, &peer_create, frm_buf);
if (QDF_IS_STATUS_ERROR(status)) {
wlan_mlo_peer_release_ref(ml_peer);
wlan_objmgr_vdev_release_ref(vdev_link, WLAN_MLO_MGR_ID);
mlo_err("nbuf clone is failed");
@@ -786,6 +787,8 @@ QDF_STATUS wlan_mlo_peer_create(struct wlan_objmgr_vdev *vdev,
/* Store AID, MLO Peer pointer in link peer, take link peer ref count */
mlo_peer_populate_link_peer(ml_peer, link_peer);
mlo_peer_populate_nawds_params(ml_peer, ml_info);
if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE) ||
((wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) &&
!wlan_vdev_mlme_is_mlo_link_vdev(vdev))) {
@@ -934,3 +937,19 @@ void wlan_mlo_peer_get_links_info(struct wlan_objmgr_peer *peer,
}
qdf_export_symbol(wlan_mlo_peer_get_links_info);
#ifdef UMAC_SUPPORT_MLNAWDS
bool wlan_mlo_peer_is_nawds(struct wlan_mlo_peer_context *ml_peer)
{
bool status = false;
mlo_peer_lock_acquire(ml_peer);
if (ml_peer->is_nawds_ml_peer)
status = true;
mlo_peer_lock_release(ml_peer);
return status;
}
qdf_export_symbol(wlan_mlo_peer_is_nawds);
#endif