Browse Source

qcacld-3.0: Add support to update ch_width of peer to DP

When the STA connects to a peer, max supported ch_width is
calculated and configured to firmware. This is calculated from
self and peer capability in case of STA/SAP. Cache this in
peer object. Currently, data path module isn't aware of the final
ch_width configured.
Fetch the phymode and covert it to the DP expected ch_width
format. Update the ch_width to DP.
phymode of NDI peers is not maintained in host. So, get the NDI
self phymode and update to DP.

Change-Id: I25993053ae1f129c8fc9a352a05c788451060b2d
CRs-Fixed: 3227453
Srinivas Dasari 2 years ago
parent
commit
db79080a21

+ 19 - 0
components/mlme/dispatcher/inc/wlan_mlme_api.h

@@ -3792,4 +3792,23 @@ QDF_STATUS wlan_connect_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev,
 					    uint8_t vdev_id,
 					    wlan_cm_id cm_id,
 					    QDF_STATUS status);
+
+/**
+ * wlan_mlme_get_ch_width_from_phymode() - Convert phymode to ch_width
+ * @phy_mode: Phy mode
+ *
+ * Return: enum phy_ch_width
+ */
+enum phy_ch_width
+wlan_mlme_get_ch_width_from_phymode(enum wlan_phymode phy_mode);
+
+/**
+ * wlan_mlme_get_peer_ch_width() - get ch_width of the given peer
+ * @psoc: psoc context
+ * @mac: peer mac
+ *
+ * Return: enum phy_ch_width
+ */
+enum phy_ch_width
+wlan_mlme_get_peer_ch_width(struct wlan_objmgr_psoc *psoc, uint8_t *mac);
 #endif /* _WLAN_MLME_API_H_ */

+ 35 - 0
components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h

@@ -4711,4 +4711,39 @@ ucfg_mlme_get_connection_roaming_ini_present(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_E_NOSUPPORT;
 }
 #endif /* CONNECTION_ROAMING_CFG */
+
+/**
+ * ucfg_mlme_get_ch_width_from_phymode() - Convert phymode to ch_width
+ * @phy_mode: phy mode
+ *
+ * Return: enum phy_ch_width
+ */
+static inline enum phy_ch_width
+ucfg_mlme_get_ch_width_from_phymode(enum wlan_phymode phy_mode)
+{
+	return wlan_mlme_get_ch_width_from_phymode(phy_mode);
+}
+
+/**
+ * ucfg_mlme_get_peer_ch_width() - get ch_width of the given peer
+ * @psoc: pointer to psoc object
+ * @mac: peer mac
+ *
+ * Return: enum phy_ch_width
+ */
+static inline enum phy_ch_width
+ucfg_mlme_get_peer_ch_width(struct wlan_objmgr_psoc *psoc, uint8_t *mac)
+{
+	return wlan_mlme_get_peer_ch_width(psoc, mac);
+}
+
+/**
+ * ucfg_mlme_get_vdev_phy_mode() - Get phymode of a vdev
+ * @psoc: pointer to psoc object
+ * @vdev_id: vdev id
+ *
+ * Return: enum wlan_phymode
+ */
+enum wlan_phymode
+ucfg_mlme_get_vdev_phy_mode(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id);
 #endif /* _WLAN_MLME_UCFG_API_H_ */

+ 60 - 0
components/mlme/dispatcher/src/wlan_mlme_api.c

@@ -5969,3 +5969,63 @@ QDF_STATUS wlan_connect_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev,
 	return wlan_cm_handle_hw_mode_change_resp(pdev, vdev_id, cm_id,
 						  status);
 }
+
+#ifdef WLAN_FEATURE_11BE
+static inline bool
+wlan_mlme_is_phymode_320_mhz(enum wlan_phymode phy_mode,
+			     enum phy_ch_width *ch_width)
+{
+	if (IS_WLAN_PHYMODE_320MHZ(phy_mode)) {
+		*ch_width = CH_WIDTH_320MHZ;
+		return true;
+	}
+
+	return false;
+}
+#else
+static inline bool
+wlan_mlme_is_phymode_320_mhz(enum wlan_phymode phy_mode,
+			     enum phy_ch_width *ch_width)
+{
+	return false;
+}
+#endif
+
+enum phy_ch_width
+wlan_mlme_get_ch_width_from_phymode(enum wlan_phymode phy_mode)
+{
+	enum phy_ch_width ch_width = CH_WIDTH_20MHZ;
+
+	if (wlan_mlme_is_phymode_320_mhz(phy_mode, &ch_width))
+		goto done;
+
+	if (IS_WLAN_PHYMODE_160MHZ(phy_mode))
+		ch_width = CH_WIDTH_160MHZ;
+	else if (IS_WLAN_PHYMODE_80MHZ(phy_mode))
+		ch_width = CH_WIDTH_80MHZ;
+	else if (IS_WLAN_PHYMODE_40MHZ(phy_mode))
+		ch_width = CH_WIDTH_40MHZ;
+	else
+		ch_width = CH_WIDTH_20MHZ;
+
+done:
+	mlme_legacy_debug("phymode: %d, ch_width: %d ", phy_mode, ch_width);
+
+	return ch_width;
+}
+
+enum phy_ch_width
+wlan_mlme_get_peer_ch_width(struct wlan_objmgr_psoc *psoc, uint8_t *mac)
+{
+	enum wlan_phymode phy_mode;
+	QDF_STATUS status;
+
+	status = mlme_get_peer_phymode(psoc, mac, &phy_mode);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		mlme_legacy_err("failed to fetch phy_mode status: %d for mac: " QDF_MAC_ADDR_FMT,
+				status, QDF_MAC_ADDR_REF(mac));
+		return CH_WIDTH_20MHZ;
+	}
+
+	return wlan_mlme_get_ch_width_from_phymode(phy_mode);
+}

+ 28 - 0
components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c

@@ -1873,3 +1873,31 @@ ucfg_mlme_get_connection_roaming_ini_present(struct wlan_objmgr_psoc *psoc,
 	return QDF_STATUS_SUCCESS;
 }
 #endif
+
+enum wlan_phymode
+ucfg_mlme_get_vdev_phy_mode(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct vdev_mlme_obj *mlme_obj;
+	enum wlan_phymode phymode;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev) {
+		mlme_err("get vdev failed for vdev_id: %d", vdev_id);
+		return WLAN_PHYMODE_AUTO;
+	}
+
+	mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!mlme_obj) {
+		mlme_err("failed to get mlme_obj vdev_id: %d", vdev_id);
+		phymode = WLAN_PHYMODE_AUTO;
+		goto done;
+	}
+	phymode = mlme_obj->mgmt.generic.phy_mode;
+
+done:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+
+	return phymode;
+}

+ 8 - 1
core/hdd/inc/wlan_hdd_assoc.h

@@ -569,6 +569,13 @@ hdd_translate_wapi_to_csr_encryption_type(uint8_t cipher_suite[4])
 }
 #endif
 
-
+/**
+ * hdd_convert_ch_width_to_cdp_peer_bw() - Convert ch_width to DP format
+ * @ch_width: ch_width
+ *
+ * Return: cdp_peer_bw enumeration
+ */
+enum cdp_peer_bw
+hdd_convert_ch_width_to_cdp_peer_bw(enum phy_ch_width ch_width);
 
 #endif

+ 45 - 1
core/hdd/src/wlan_hdd_assoc.c

@@ -1241,6 +1241,8 @@ QDF_STATUS hdd_roam_register_sta(struct hdd_adapter *adapter,
 	struct ol_txrx_desc_type txrx_desc = {0};
 	struct ol_txrx_ops txrx_ops;
 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	enum phy_ch_width ch_width;
+	enum wlan_phymode phymode;
 
 	/* Get the Station ID from the one saved during the association */
 	if (!QDF_IS_ADDR_BROADCAST(bssid->bytes))
@@ -1299,6 +1301,16 @@ QDF_STATUS hdd_roam_register_sta(struct hdd_adapter *adapter,
 	}
 
 	adapter->tx_fn = txrx_ops.tx.tx;
+
+	if (adapter->device_mode == QDF_NDI_MODE) {
+		phymode = ucfg_mlme_get_vdev_phy_mode(adapter->hdd_ctx->psoc,
+						      adapter->vdev_id);
+		ch_width = ucfg_mlme_get_ch_width_from_phymode(phymode);
+	} else {
+		ch_width = ucfg_mlme_get_peer_ch_width(adapter->hdd_ctx->psoc,
+						txrx_desc.peer_addr.bytes);
+	}
+	txrx_desc.bw = hdd_convert_ch_width_to_cdp_peer_bw(ch_width);
 	qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &txrx_desc);
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
 		hdd_err("cdp_peer_register() failed Status: %d [0x%08X]",
@@ -1555,6 +1567,7 @@ QDF_STATUS hdd_roam_register_tdlssta(struct hdd_adapter *adapter,
 	struct ol_txrx_desc_type txrx_desc = { 0 };
 	struct ol_txrx_ops txrx_ops;
 	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	enum phy_ch_width ch_width;
 
 	/*
 	 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
@@ -1599,7 +1612,9 @@ QDF_STATUS hdd_roam_register_tdlssta(struct hdd_adapter *adapter,
 
 	adapter->tx_fn = txrx_ops.tx.tx;
 
-
+	ch_width = ucfg_mlme_get_peer_ch_width(adapter->hdd_ctx->psoc,
+					       txrx_desc.peer_addr.bytes);
+	txrx_desc.bw = hdd_convert_ch_width_to_cdp_peer_bw(ch_width);
 	/* Register the Station with TL...  */
 	qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &txrx_desc);
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
@@ -2422,6 +2437,35 @@ hdd_translate_wapi_to_csr_encryption_type(uint8_t cipher_suite[4])
 }
 #endif /* FEATURE_WLAN_WAPI */
 
+enum cdp_peer_bw
+hdd_convert_ch_width_to_cdp_peer_bw(enum phy_ch_width ch_width)
+{
+	switch (ch_width) {
+	case CH_WIDTH_20MHZ:
+		return CDP_20_MHZ;
+	case CH_WIDTH_40MHZ:
+		return CDP_40_MHZ;
+	case CH_WIDTH_80MHZ:
+		return CDP_80_MHZ;
+	case CH_WIDTH_160MHZ:
+		return CDP_160_MHZ;
+	case CH_WIDTH_80P80MHZ:
+		return CDP_80P80_MHZ;
+	case CH_WIDTH_5MHZ:
+		return CDP_5_MHZ;
+	case CH_WIDTH_10MHZ:
+		return CDP_10_MHZ;
+#ifdef WLAN_FEATURE_11BE
+	case CH_WIDTH_320MHZ:
+		return CDP_320_MHZ;
+#endif
+	default:
+		return CDP_BW_INVALID;
+	}
+
+	return CDP_BW_INVALID;
+}
+
 #ifdef WLAN_FEATURE_FILS_SK
 bool hdd_is_fils_connection(struct hdd_context *hdd_ctx,
 			    struct hdd_adapter *adapter)

+ 4 - 0
core/hdd/src/wlan_hdd_softap_tx_rx.c

@@ -1335,6 +1335,7 @@ QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter,
 	bool wmm_enabled = false;
 	enum qca_wlan_802_11_mode dot11mode = QCA_WLAN_802_11_MODE_INVALID;
 	bool is_macaddr_broadcast = false;
+	enum phy_ch_width ch_width;
 
 	if (event) {
 		wmm_enabled = event->wmmEnabled;
@@ -1400,6 +1401,9 @@ QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter,
 		adapter->tx_fn = txrx_ops.tx.tx;
 	}
 
+	ch_width = ucfg_mlme_get_peer_ch_width(adapter->hdd_ctx->psoc,
+					       txrx_desc.peer_addr.bytes);
+	txrx_desc.bw = hdd_convert_ch_width_to_cdp_peer_bw(ch_width);
 	qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &txrx_desc);
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
 		hdd_debug("cdp_peer_register() failed to register.  Status = %d [0x%08X]",