qcacld-3.0: Add support to configure UL MU

Add support to inform peer enable/disable UL_MU
support in STA mode using OMI frame.

Change-Id: Ie12f4991654f7504802b4ae0fbdd26aecda1ee63
CRs-Fixed: 3546176
This commit is contained in:
Prasanna JS
2023-06-14 02:53:42 -07:00
committed by Rahul Choudhary
parent fe6f4d208b
commit d20796e882
4 changed files with 229 additions and 0 deletions

View File

@@ -4415,4 +4415,17 @@ enum phy_ch_width wlan_mlme_get_max_bw(void);
*/
QDF_STATUS wlan_mlme_get_sta_ch_width(struct wlan_objmgr_vdev *vdev,
enum phy_ch_width *ch_width);
/**
* wlan_mlme_set_ul_mu_config() - set ul mu config
*
* @psoc: pointer to psoc object
* @vdev_id : vdev_id
* @ulmu_disable : ulmu_disable value
*
* Return: QDF Status
*/
QDF_STATUS
wlan_mlme_set_ul_mu_config(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
uint8_t ulmu_disable);
#endif /* _WLAN_MLME_API_H_ */

View File

@@ -5143,4 +5143,22 @@ ucfg_mlme_get_sr_enable_modes(struct wlan_objmgr_psoc *psoc,
QDF_STATUS
ucfg_mlme_get_valid_channels(struct wlan_objmgr_psoc *psoc,
uint32_t *ch_freq_list, uint32_t *list_len);
/**
* ucfg_mlme_set_ul_mu_config - set ul mu config
* @psoc: pointer to psoc object
* @vdev_id : vdev ID
* @ulmu_disable: ul mu value
*
* Inline UCFG API to be used by HDD/OSIF callers
*
* Return: QDF_STATUS_SUCCESS or non-zero on failure
*/
static inline
QDF_STATUS ucfg_mlme_set_ul_mu_config(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
uint8_t ulmu_disable)
{
return wlan_mlme_set_ul_mu_config(psoc, vdev_id, ulmu_disable);
}
#endif /* _WLAN_MLME_UCFG_API_H_ */

View File

@@ -7099,3 +7099,151 @@ wlan_mlme_get_sap_ps_with_twt(struct wlan_objmgr_psoc *psoc)
return mlme_obj->cfg.sap_cfg.sap_ps_with_twt_enable;
}
/**
* set_omi_ch_width() - set OMI ch_bw/eht_ch_bw_ext bit value from channel width
* @ch_width: channel width
* @omi_data: Pointer to omi_data object
*
* If the channel width is 20Mhz, 40Mhz, 80Mhz, 160Mhz and 80+80Mhz ch_bw set
* to 0, 1, 2, 3 accordingly, if channel width is 320Mhz then eht_ch_bw_ext
* set to 1
*
* Return: QDF_STATUS_SUCCESS on success or QDF_STATUS_E_INVAL on failure
*/
static QDF_STATUS
set_omi_ch_width(enum phy_ch_width ch_width, struct omi_ctrl_tx *omi_data)
{
switch (ch_width) {
case CH_WIDTH_20MHZ:
omi_data->ch_bw = 0;
break;
case CH_WIDTH_40MHZ:
omi_data->ch_bw = 1;
break;
case CH_WIDTH_80MHZ:
omi_data->ch_bw = 2;
break;
case CH_WIDTH_160MHZ:
case CH_WIDTH_80P80MHZ:
omi_data->ch_bw = 3;
break;
case CH_WIDTH_320MHZ:
omi_data->eht_ch_bw_ext = 1;
break;
default:
return QDF_STATUS_E_INVAL;
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
wlan_mlme_set_ul_mu_config(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
uint8_t ulmu_disable)
{
struct omi_ctrl_tx omi_data = {0};
uint32_t param_val = 0;
struct wlan_objmgr_pdev *pdev;
struct wlan_objmgr_vdev *vdev;
enum phy_ch_width ch_width;
uint8_t rx_nss, tx_nsts;
struct qdf_mac_addr macaddr = {0};
enum wlan_phymode peer_phymode;
qdf_freq_t op_chan_freq;
qdf_freq_t freq_seg_0;
QDF_STATUS status = QDF_STATUS_SUCCESS;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
WLAN_MLME_OBJMGR_ID);
if (!vdev) {
mlme_err("vdev %d: vdev is NULL", vdev_id);
return QDF_STATUS_E_INVAL;
}
pdev = wlan_vdev_get_pdev(vdev);
if (!pdev) {
mlme_err("pdev is NULL");
status = QDF_STATUS_E_INVAL;
goto err;
}
if (!cm_is_vdevid_connected(pdev, vdev_id)) {
mlme_err("STA is not connected, Session_id: %d", vdev_id);
status = QDF_STATUS_E_INVAL;
goto err;
}
status = wlan_vdev_get_bss_peer_mac(vdev, &macaddr);
if (QDF_STATUS_SUCCESS != status) {
mlme_err("Failed to get bss peer mac, Err : %d", status);
goto err;
}
status = mlme_get_peer_phymode(psoc, macaddr.bytes, &peer_phymode);
if (QDF_STATUS_SUCCESS != status) {
mlme_err("Failed to get peer phymode, Err : %d", status);
goto err;
}
if (!(IS_WLAN_PHYMODE_HE(peer_phymode) ||
IS_WLAN_PHYMODE_EHT(peer_phymode))) {
mlme_err("Invalid mode");
status = QDF_STATUS_E_INVAL;
goto err;
}
status = wlan_mlme_get_sta_rx_nss(psoc, vdev, &rx_nss);
if (QDF_STATUS_SUCCESS != status) {
mlme_err("Failed to get sta_rx_nss, Err : %d", status);
goto err;
}
status = wlan_mlme_get_sta_tx_nss(psoc, vdev, &tx_nsts);
if (QDF_STATUS_SUCCESS != status) {
mlme_err("Failed to get sta_tx_nss, Err : %d", status);
goto err;
}
status = wlan_get_op_chan_freq_info_vdev_id(pdev, vdev_id,
&op_chan_freq,
&freq_seg_0, &ch_width);
if (QDF_STATUS_SUCCESS != status) {
mlme_err("Failed to get bw, Err : %d", status);
goto err;
}
omi_data.omi_in_vht = 0x1;
omi_data.omi_in_he = 0x1;
omi_data.a_ctrl_id = 0x1;
status = set_omi_ch_width(ch_width, &omi_data);
if (QDF_STATUS_SUCCESS != status) {
mlme_err("Failed to set bw, Err : %d", status);
goto err;
}
omi_data.rx_nss = rx_nss - 1;
omi_data.tx_nsts = tx_nsts - 1;
omi_data.ul_mu_dis = ulmu_disable;
omi_data.ul_mu_data_dis = 0;
qdf_mem_copy(&param_val, &omi_data, sizeof(omi_data));
mlme_debug("OMI: BW %d TxNSTS %d RxNSS %d ULMU %d OMI_VHT %d OMI_HE %d, EHT OMI: BW %d RxNSS %d TxNSS %d, param val: %08X, bssid:" QDF_MAC_ADDR_FMT,
omi_data.ch_bw, omi_data.tx_nsts, omi_data.rx_nss,
omi_data.ul_mu_dis, omi_data.omi_in_vht, omi_data.omi_in_he,
omi_data.eht_ch_bw_ext, omi_data.eht_rx_nss_ext,
omi_data.eht_tx_nss_ext, param_val,
QDF_MAC_ADDR_REF(macaddr.bytes));
status = wlan_util_vdev_peer_set_param_send(vdev, macaddr.bytes,
WMI_PEER_PARAM_XMIT_OMI,
param_val);
if (QDF_STATUS_SUCCESS != status)
mlme_err("set_peer_param_cmd returned %d", status);
err:
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
return status;
}