diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 0f58711782..00027c6d01 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/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_ */ diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index a73720982b..8c6942f9d7 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/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_ */ diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index b3fe185d0d..d7cb8a1336 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/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); +} diff --git a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c index 336fc33fa0..514db0c7d2 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c +++ b/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; +} diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h index 47d29aada3..ffa64524a8 100644 --- a/core/hdd/inc/wlan_hdd_assoc.h +++ b/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 diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 713cd1b207..b1466728a8 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/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) diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c index 059e800838..47c4c9b8f5 100644 --- a/core/hdd/src/wlan_hdd_softap_tx_rx.c +++ b/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]",