diff --git a/umac/mlo_mgr/inc/wlan_mlo_mgr_ap.h b/umac/mlo_mgr/inc/wlan_mlo_mgr_ap.h index 50d753d7f9..955947026f 100644 --- a/umac/mlo_mgr/inc/wlan_mlo_mgr_ap.h +++ b/umac/mlo_mgr/inc/wlan_mlo_mgr_ap.h @@ -23,6 +23,7 @@ #include #include +#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 diff --git a/umac/mlo_mgr/inc/wlan_mlo_mgr_peer.h b/umac/mlo_mgr/inc/wlan_mlo_mgr_peer.h index 3b70574cc6..c70040ec0d 100644 --- a/umac/mlo_mgr/inc/wlan_mlo_mgr_peer.h +++ b/umac/mlo_mgr/inc/wlan_mlo_mgr_peer.h @@ -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 diff --git a/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h b/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h index 859f4a8b7f..e6a407d535 100644 --- a/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h +++ b/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h @@ -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 }; /* diff --git a/umac/mlo_mgr/src/wlan_mlo_mgr_ap.c b/umac/mlo_mgr/src/wlan_mlo_mgr_ap.c index 7acc6a157d..ac303795f4 100644 --- a/umac/mlo_mgr/src/wlan_mlo_mgr_ap.c +++ b/umac/mlo_mgr/src/wlan_mlo_mgr_ap.c @@ -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 diff --git a/umac/mlo_mgr/src/wlan_mlo_mgr_peer.c b/umac/mlo_mgr/src/wlan_mlo_mgr_peer.c index 89bf45f26a..d9fd8e7542 100644 --- a/umac/mlo_mgr/src/wlan_mlo_mgr_peer.c +++ b/umac/mlo_mgr/src/wlan_mlo_mgr_peer.c @@ -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