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
This commit is contained in:
Srinivas Dasari
2022-06-21 16:40:45 +05:30
committed by Madan Koyyalamudi
parent 82fbeff919
commit db79080a21
7 changed files with 199 additions and 2 deletions

View File

@@ -3792,4 +3792,23 @@ QDF_STATUS wlan_connect_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev,
uint8_t vdev_id, uint8_t vdev_id,
wlan_cm_id cm_id, wlan_cm_id cm_id,
QDF_STATUS status); 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_ */ #endif /* _WLAN_MLME_API_H_ */

View File

@@ -4711,4 +4711,39 @@ ucfg_mlme_get_connection_roaming_ini_present(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_E_NOSUPPORT; return QDF_STATUS_E_NOSUPPORT;
} }
#endif /* CONNECTION_ROAMING_CFG */ #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_ */ #endif /* _WLAN_MLME_UCFG_API_H_ */

View File

@@ -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, return wlan_cm_handle_hw_mode_change_resp(pdev, vdev_id, cm_id,
status); 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);
}

View File

@@ -1873,3 +1873,31 @@ ucfg_mlme_get_connection_roaming_ini_present(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
#endif #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;
}

View File

@@ -569,6 +569,13 @@ hdd_translate_wapi_to_csr_encryption_type(uint8_t cipher_suite[4])
} }
#endif #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 #endif

View File

@@ -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_desc_type txrx_desc = {0};
struct ol_txrx_ops txrx_ops; struct ol_txrx_ops txrx_ops;
void *soc = cds_get_context(QDF_MODULE_ID_SOC); 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 */ /* Get the Station ID from the one saved during the association */
if (!QDF_IS_ADDR_BROADCAST(bssid->bytes)) 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; 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); qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &txrx_desc);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
hdd_err("cdp_peer_register() failed Status: %d [0x%08X]", 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_desc_type txrx_desc = { 0 };
struct ol_txrx_ops txrx_ops; struct ol_txrx_ops txrx_ops;
void *soc = cds_get_context(QDF_MODULE_ID_SOC); 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 * 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; 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... */ /* Register the Station with TL... */
qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &txrx_desc); qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &txrx_desc);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { 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 */ #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 #ifdef WLAN_FEATURE_FILS_SK
bool hdd_is_fils_connection(struct hdd_context *hdd_ctx, bool hdd_is_fils_connection(struct hdd_context *hdd_ctx,
struct hdd_adapter *adapter) struct hdd_adapter *adapter)

View File

@@ -1335,6 +1335,7 @@ QDF_STATUS hdd_softap_register_sta(struct hdd_adapter *adapter,
bool wmm_enabled = false; bool wmm_enabled = false;
enum qca_wlan_802_11_mode dot11mode = QCA_WLAN_802_11_MODE_INVALID; enum qca_wlan_802_11_mode dot11mode = QCA_WLAN_802_11_MODE_INVALID;
bool is_macaddr_broadcast = false; bool is_macaddr_broadcast = false;
enum phy_ch_width ch_width;
if (event) { if (event) {
wmm_enabled = event->wmmEnabled; 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; 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); qdf_status = cdp_peer_register(soc, OL_TXRX_PDEV_ID, &txrx_desc);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
hdd_debug("cdp_peer_register() failed to register. Status = %d [0x%08X]", hdd_debug("cdp_peer_register() failed to register. Status = %d [0x%08X]",