瀏覽代碼

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
Shwetha G K 3 年之前
父節點
當前提交
3c5ce319c3

+ 36 - 0
umac/mlo_mgr/inc/wlan_mlo_mgr_ap.h

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

+ 16 - 0
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

+ 25 - 0
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
 };
 
 /*

+ 63 - 0
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

+ 21 - 2
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