qcacld-3.0: Add logic to set wifi standard for vdev

Add logic to set wifi standard per the vendor
attribute QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE
and QCA_WLAN_VENDOR_ATTR_CONFIG_IFINDEX for vdev.

Change-Id: Ib03d233bf6f290859e2d754b3193ae5020d872d5
CRs-Fixed: 3554395
This commit is contained in:
Paul Zhang
2023-07-09 23:44:20 -07:00
committed by Rahul Choudhary
parent 136e98f779
commit 012efd118b
4 changed files with 139 additions and 6 deletions

View File

@@ -1248,6 +1248,7 @@ struct wlan_hdd_tx_power {
* @delta_qtime: delta between host qtime and monotonic time
* @traffic_end_ind_en: traffic end indication feature enable/disable
* @is_dbam_configured:
* @user_phy_mode: phy mode is set per vdev
* @deflink: Default link pointing to the 0th index of the linkinfo array
* @link_info: Data structure to hold link specific information
* @tx_power: Structure to hold connection tx Power info
@@ -1436,6 +1437,7 @@ struct hdd_adapter {
#ifdef WLAN_FEATURE_DBAM_CONFIG
bool is_dbam_configured;
#endif
enum qca_wlan_vendor_phy_mode user_phy_mode;
struct wlan_hdd_link_info *deflink;
struct wlan_hdd_link_info link_info[WLAN_MAX_ML_BSS_LINKS];
struct wlan_hdd_tx_power tx_power;

View File

@@ -8635,6 +8635,54 @@ wlan_hdd_cfg80211_wifi_set_rx_blocksize(struct wlan_hdd_link_info *link_info,
return ret_val;
}
int hdd_set_vdev_phy_mode(struct hdd_adapter *adapter,
enum qca_wlan_vendor_phy_mode vendor_phy_mode)
{
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
struct wlan_hdd_link_info *link_info = adapter->deflink;
eCsrPhyMode phymode;
WMI_HOST_WIFI_STANDARD std;
enum hdd_dot11_mode dot11_mode;
uint8_t supported_band;
int ret;
if (hdd_cm_is_vdev_connected(link_info)) {
hdd_err("Station is connected, command is not supported");
return -EINVAL;
}
adapter->user_phy_mode = vendor_phy_mode;
ret = hdd_vendor_mode_to_phymode(vendor_phy_mode, &phymode);
if (ret)
return ret;
ret = hdd_phymode_to_dot11_mode(phymode, &dot11_mode);
if (ret)
return ret;
ret = hdd_vendor_mode_to_band(vendor_phy_mode, &supported_band,
wlan_reg_is_6ghz_supported(psoc));
if (ret)
return ret;
std = hdd_get_wifi_standard(hdd_ctx, dot11_mode, supported_band);
hdd_debug("wifi_standard %d, vendor_phy_mode %d", std, vendor_phy_mode);
ret = sme_cli_set_command(link_info->vdev_id,
wmi_vdev_param_wifi_standard_version,
std, VDEV_CMD);
if (ret) {
hdd_err("Failed to set standard version to fw");
return ret;
}
ucfg_mlme_set_vdev_wifi_std(hdd_ctx->psoc, link_info->vdev_id, std);
return 0;
}
int hdd_set_phy_mode(struct hdd_adapter *adapter,
enum qca_wlan_vendor_phy_mode vendor_phy_mode)
{
@@ -8670,18 +8718,33 @@ int hdd_set_phy_mode(struct hdd_adapter *adapter,
/**
* hdd_config_phy_mode() - set PHY mode
* @link_info: Link info pointer in HDD adapter
* @attr: nla attr sent from userspace
* @tb: nla attr sent from userspace
*
* Return: 0 on success; error number otherwise
*/
static int hdd_config_phy_mode(struct wlan_hdd_link_info *link_info,
const struct nlattr *attr)
struct nlattr *tb[])
{
enum qca_wlan_vendor_phy_mode vendor_phy_mode;
uint32_t ifindex;
struct nlattr *phy_mode_attr = tb[QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE];
struct nlattr *ifindex_attr = tb[QCA_WLAN_VENDOR_ATTR_CONFIG_IFINDEX];
vendor_phy_mode = nla_get_u32(attr);
if (!phy_mode_attr)
return 0;
return hdd_set_phy_mode(link_info->adapter, vendor_phy_mode);
vendor_phy_mode = nla_get_u32(phy_mode_attr);
if (!ifindex_attr)
return hdd_set_phy_mode(link_info->adapter, vendor_phy_mode);
ifindex = nla_get_u32(ifindex_attr);
if (ifindex == link_info->adapter->dev->ifindex)
return hdd_set_vdev_phy_mode(link_info->adapter,
vendor_phy_mode);
hdd_err_rl("ifindex %d, expected ifindex %d", ifindex,
link_info->adapter->dev->ifindex);
return -EINVAL;
}
/**
@@ -11512,8 +11575,6 @@ static const struct independent_setters independent_setters[] = {
hdd_config_tx_stbc},
{QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC,
hdd_config_rx_stbc},
{QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE,
hdd_config_phy_mode},
{QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH,
hdd_set_channel_width},
{QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_BW,
@@ -12281,6 +12342,7 @@ static const interdependent_setter_fn interdependent_setters[] = {
hdd_config_ani,
hdd_config_tx_rx_nss,
hdd_process_generic_set_cmd,
hdd_config_phy_mode,
};
/**

View File

@@ -1122,6 +1122,15 @@ QDF_STATUS hdd_mlo_dev_t2lm_notify_link_update(struct wlan_objmgr_vdev *vdev,
}
#endif
/** hdd_set_vdev_phy_mode() - Set vdev phy mode
* @adapter: adapter pointer
* @vendor_phy_mode: vendor phy mode
*
* Return: 0 for success
*/
int hdd_set_vdev_phy_mode(struct hdd_adapter *adapter,
enum qca_wlan_vendor_phy_mode vendor_phy_mode);
#if defined(WLAN_FEATURE_11BE_MLO) && \
defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT)
/**

View File

@@ -1971,6 +1971,54 @@ static void lim_check_oui_and_update_session(struct mac_context *mac_ctx,
lim_update_he_caps_htc(session, !is_vendor_ap_present);
}
static enum mlme_dot11_mode
lim_get_user_dot11_mode(struct wlan_objmgr_vdev *vdev)
{
WMI_HOST_WIFI_STANDARD wifi_std;
wifi_std = mlme_get_vdev_wifi_std(vdev);
switch (wifi_std) {
case WMI_HOST_WIFI_STANDARD_4:
return MLME_DOT11_MODE_11N;
case WMI_HOST_WIFI_STANDARD_5:
return MLME_DOT11_MODE_11AC;
case WMI_HOST_WIFI_STANDARD_6:
case WMI_HOST_WIFI_STANDARD_6E:
return MLME_DOT11_MODE_11AX;
case WMI_HOST_WIFI_STANDARD_7:
default:
return MLME_DOT11_MODE_11BE;
}
}
static enum mlme_dot11_mode
lim_intersect_user_dot11_mode(struct mac_context *mac_ctx,
enum QDF_OPMODE opmode, uint8_t vdev_id,
enum mlme_dot11_mode self_mode)
{
struct wlan_objmgr_vdev *vdev;
enum mlme_dot11_mode user_mode;
switch (opmode) {
case QDF_STA_MODE:
case QDF_P2P_CLIENT_MODE:
break;
default:
return self_mode;
}
vdev = wlan_objmgr_get_vdev_by_id_from_pdev(mac_ctx->pdev, vdev_id,
WLAN_MLME_OBJMGR_ID);
if (!vdev)
return self_mode;
user_mode = lim_get_user_dot11_mode(vdev);
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
return user_mode > self_mode ? self_mode : user_mode;
}
static enum mlme_dot11_mode
lim_get_self_dot11_mode(struct mac_context *mac_ctx, enum QDF_OPMODE opmode,
uint8_t vdev_id)
@@ -2675,6 +2723,13 @@ lim_fill_dot11_mode(struct mac_context *mac_ctx, struct pe_session *session,
self_dot11_mode = lim_get_self_dot11_mode(mac_ctx, session->opmode,
session->vdev_id);
/* if user set dot11 mode by cmd, need to do intersect first */
self_dot11_mode =
lim_intersect_user_dot11_mode(mac_ctx, session->opmode,
session->vdev_id,
self_dot11_mode);
bss_dot11_mode = lim_get_bss_dot11_mode(mac_ctx, bss_desc, ie_struct);
pe_debug("vdev id %d opmode %d self dot11mode %d bss_dot11 mode %d",
@@ -5306,6 +5361,11 @@ lim_fill_preauth_req_dot11_mode(struct mac_context *mac_ctx,
self_dot11_mode = lim_get_self_dot11_mode(mac_ctx, QDF_STA_MODE,
vdev_id);
/* if user set dot11 mode by cmd, need to do intersect first */
self_dot11_mode =
lim_intersect_user_dot11_mode(mac_ctx, QDF_STA_MODE,
vdev_id, self_dot11_mode);
bss_dot11_mode = lim_get_bss_dot11_mode(mac_ctx, bss_desc, ie_struct);
status = lim_get_intersected_dot11_mode_sta_ap(mac_ctx, self_dot11_mode,