Ver código fonte

qcacmn: Add API to extract MSD caps from cmn info field

Add API to extract MLD AP MSD capabilities from MLO IE
common info field if present. This will be shared with FW
via peer assoc cmd.

Change-Id: I0ebcd5408a40f3314932d4a2a7e586c208af2ee5
CRs-Fixed: 3271118
Gururaj Pandurangi 2 anos atrás
pai
commit
9fa8fc8b46

+ 31 - 0
umac/mlo_mgr/inc/utils_mlo.h

@@ -224,6 +224,29 @@ util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 			bool *eml_cap_found,
 			uint16_t *eml_cap);
 
+/**
+ * util_get_bvmlie_msd_cap() - Get the MSD capabilities for Basic variant
+ * MLO IE
+ * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
+ * fragment sequence
+ * @mlieseqlen: Total length of the Multi-Link element or Multi-Link element
+ * fragment sequence
+ * @msd_cap_found: Pointer to the location where a boolean status should be
+ * updated indicating whether the MSD cabalility was found or not. This should
+ * be ignored by the caller if the function returns error.
+ * @msd_cap: Pointer to the location where the MSD capabilities should be
+ * updated. This should be ignored by the caller if the function indicates
+ * that the MSD capability was not found.
+ *
+ * Get the MSD capabilities from a given Basic variant Multi-Link element or
+ * element fragment sequence.
+ *
+ * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving
+ * the reason for error in the case of failure
+ */
+QDF_STATUS
+util_get_bvmlie_msd_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
+			bool *msd_cap_found, uint16_t *msd_cap);
 /**
  * util_get_bvmlie_primary_linkid() - Get the link identifier
  * @mlieseq: Starting address of the Multi-Link element or Multi-Link element
@@ -463,6 +486,14 @@ util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 	return QDF_STATUS_E_NOSUPPORT;
 }
 
+static inline QDF_STATUS
+util_get_bvmlie_msd_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
+			bool *msd_cap_found,
+			uint16_t *msd_cap)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
 static inline QDF_STATUS
 util_get_bvmlie_primary_linkid(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 			       bool *linkidfound, uint8_t *linkid)

+ 17 - 0
umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h

@@ -568,6 +568,18 @@ struct wlan_mlo_eml_cap {
 		 reserved:1;
 };
 
+/**
+ * struct wlan_mlo_msd_cap - MSD capabilities of MLD
+ * @medium_sync_duration: Medium Sync Duration
+ * @medium_sync_ofdm_ed_thresh: MSD threshold value
+ * @medium_sync_max_txop_num: Max number of TXOP
+ */
+struct wlan_mlo_msd_cap {
+	uint16_t medium_sync_duration:8,
+		 medium_sync_ofdm_ed_thresh:4,
+		 medium_sync_max_txop_num:4;
+};
+
 /**
  * struct wlan_mlo_mld_cap - MLD capabilities of MLD
  * @max_simult_link: Maximum number of simultaneous links
@@ -607,6 +619,9 @@ struct wlan_mlo_mld_cap {
  * @nawds_config: eack link peer's NAWDS configuration
  * @pending_auth: Holds pending auth request
  * @t2lm_policy: TID-to-link mapping information
+ * @msd_cap_present: Medium Sync Capability present bit
+ * @mlpeer_emlcap: EML capability information for ML peer
+ * @mlpeer_msdcap: Medium Sync Delay capability information for ML peer
  */
 struct wlan_mlo_peer_context {
 	qdf_list_node_t peer_node;
@@ -637,7 +652,9 @@ struct wlan_mlo_peer_context {
 #ifdef WLAN_FEATURE_11BE
 	struct wlan_mlo_peer_t2lm_policy t2lm_policy;
 #endif
+	bool msd_cap_present;
 	struct wlan_mlo_eml_cap mlpeer_emlcap;
+	struct wlan_mlo_msd_cap mlpeer_msdcap;
 };
 
 /*

+ 84 - 0
umac/mlo_mgr/src/utils_mlo.c

@@ -2946,6 +2946,90 @@ util_get_bvmlie_eml_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS
+util_get_bvmlie_msd_cap(uint8_t *mlieseq, qdf_size_t mlieseqlen,
+			bool *msd_cap_found,
+			uint16_t *msd_cap)
+{
+	struct wlan_ie_multilink *mlie_fixed;
+	enum wlan_ml_variant variant;
+	uint16_t mlcontrol;
+	uint8_t msd_cap_offset;
+	uint8_t commoninfo_len;
+	uint16_t presencebitmap;
+
+	if (!mlieseq || !mlieseqlen || !msd_cap_found || !msd_cap)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	*msd_cap = 0;
+	*msd_cap_found = false;
+
+	if (mlieseqlen < sizeof(struct wlan_ie_multilink))
+		return QDF_STATUS_E_INVAL;
+
+	mlie_fixed = (struct wlan_ie_multilink *)mlieseq;
+
+	if ((mlie_fixed->elem_id != WLAN_ELEMID_EXTN_ELEM) ||
+	    (mlie_fixed->elem_id_ext != WLAN_EXTN_ELEMID_MULTI_LINK))
+		return QDF_STATUS_E_INVAL;
+
+	mlcontrol = qdf_le16_to_cpu(mlie_fixed->mlcontrol);
+
+	variant = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_TYPE_IDX,
+			       WLAN_ML_CTRL_TYPE_BITS);
+
+	if (variant != WLAN_ML_VARIANT_BASIC)
+		return QDF_STATUS_E_INVAL;
+
+	presencebitmap = QDF_GET_BITS(mlcontrol, WLAN_ML_CTRL_PBM_IDX,
+				      WLAN_ML_CTRL_PBM_BITS);
+
+	/* msd_cap_offset stores the offset of MSD capabilities within
+	 * Common Info
+	 */
+	msd_cap_offset = WLAN_ML_BV_CINFO_LENGTH_SIZE + QDF_MAC_ADDR_SIZE;
+	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_LINKIDINFO_P)
+		msd_cap_offset += WLAN_ML_BV_CINFO_LINKIDINFO_SIZE;
+	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_BSSPARAMCHANGECNT_P)
+		msd_cap_offset += WLAN_ML_BSSPARAMCHNGCNT_SIZE;
+	if (presencebitmap & WLAN_ML_BV_CTRL_PBM_MEDIUMSYNCDELAYINFO_P) {
+		/* Common Info starts at
+		 * mlieseq + sizeof(struct wlan_ie_multilink).
+		 * Check if there is sufficient space in the buffer for
+		 * the Common Info Length.
+		 */
+		if (mlieseqlen < (sizeof(struct wlan_ie_multilink) +
+				  WLAN_ML_BV_CINFO_LENGTH_SIZE))
+			return QDF_STATUS_E_PROTO;
+
+		/* Check if the value indicated in the Common Info Length
+		 * subfield is sufficient to access the MSD capabilities.
+		 */
+		commoninfo_len = *(mlieseq + sizeof(struct wlan_ie_multilink));
+		if (commoninfo_len < (msd_cap_offset +
+				      WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_SIZE))
+			return QDF_STATUS_E_PROTO;
+
+		/* Common Info starts at mlieseq + sizeof(struct
+		 * wlan_ie_multilink). Check if there is sufficient space in
+		 * Common Info for the MSD capability.
+		 */
+		if (mlieseqlen < (sizeof(struct wlan_ie_multilink) +
+				  msd_cap_offset +
+				  WLAN_ML_BV_CINFO_MEDMSYNCDELAYINFO_SIZE))
+			return QDF_STATUS_E_PROTO;
+
+		*msd_cap_found = true;
+		*msd_cap = qdf_le16_to_cpu(*(uint16_t *)(mlieseq +
+							 sizeof(struct wlan_ie_multilink) +
+							 msd_cap_offset));
+	} else {
+		mlo_debug("MSD caps not found in assoc rsp");
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS
 util_get_bvmlie_mldmacaddr(uint8_t *mlieseq, qdf_size_t mlieseqlen,
 			   struct qdf_mac_addr *mldmacaddr)

+ 9 - 1
wmi/inc/wmi_unified_param.h

@@ -1127,6 +1127,7 @@ struct wmi_host_tid_to_link_map_params {
  * @mlo_force_link_inactive: force the peer inactive
  * @emlsr_support: indicate if eMLSR supported
  * @emlmr_support: indicate if eMLMR supported
+ * @msd_cap_support: indicate if MSD supported
  * @mld_mac: MLD mac address
  * @logical_link_index: Unique index for links of the mlo. Starts with Zero
  * @ml_peer_id: ML peer id if generated by host. Otherwise invalid peer id
@@ -1135,6 +1136,9 @@ struct wmi_host_tid_to_link_map_params {
  * @emlsr_trans_delay_us: eMLSR Transition Delay from peer in us
  * @emlmr_delay_us: eMLMR Delay from peer in us
  * @trans_timeout_us: EML Transition Timeout in us
+ * @medium_sync_duration: medium sync duration in us
+ * @medium_sync_ofdm_ed_thresh: medium sync ofdm threshold in us
+ * @medium_sync_max_txop_num: Max number of TXOPs
  */
 struct peer_assoc_mlo_params {
 	uint32_t mlo_enabled:1,
@@ -1145,7 +1149,8 @@ struct peer_assoc_mlo_params {
 		 mlo_force_link_inactive:1,
 		 emlsr_support:1,
 		 emlmr_support:1,
-		 unused:25;
+		 msd_cap_support:1,
+		 unused:23;
 	uint8_t mld_mac[QDF_MAC_ADDR_SIZE];
 	uint32_t logical_link_index;
 	uint32_t ml_peer_id;
@@ -1154,6 +1159,9 @@ struct peer_assoc_mlo_params {
 	uint16_t emlsr_trans_delay_us;
 	uint16_t emlmr_delay_us;
 	uint32_t trans_timeout_us;
+	uint16_t medium_sync_duration;
+	uint16_t medium_sync_ofdm_ed_thresh;
+	uint16_t medium_sync_max_txop_num;
 };
 
 /**

+ 6 - 0
wmi/src/wmi_unified_11be_tlv.c

@@ -259,6 +259,12 @@ uint8_t *peer_assoc_add_mlo_params(uint8_t *buf_ptr,
 	mlo_params->emlsr_trans_delay_us = req->mlo_params.emlsr_trans_delay_us;
 	mlo_params->emlsr_padding_delay_us = req->mlo_params.emlsr_pad_delay_us;
 
+	mlo_params->msd_dur_us = req->mlo_params.medium_sync_duration;
+	mlo_params->msd_ofdm_ed_thr =
+			req->mlo_params.medium_sync_ofdm_ed_thresh;
+	mlo_params->msd_max_num_txops =
+			req->mlo_params.medium_sync_max_txop_num;
+
 	return buf_ptr + sizeof(wmi_peer_assoc_mlo_params);
 }