qcacld-3.0: Update bss rate flags as per BW update

Supplicant sends SET_MAX_BANDWIDTH driver command to update
connected channel width dynamically.

Host should update connected bss rate flags so that host
can send proper cp stats as per updated channel bandwidth.

Change-Id: I676635b108f91f4fd8471fbe66352aa471dd9a9f
CRs-Fixed: 3519930
This commit is contained in:
abhinav kumar
2023-06-05 13:23:02 +05:30
committed by Rahul Choudhary
parent 95948e947f
commit 8d585706ca
8 changed files with 294 additions and 5 deletions

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -269,12 +269,12 @@ QDF_STATUS ucfg_mc_cp_stats_cca_stats_get(struct wlan_objmgr_vdev *vdev,
/**
* ucfg_mc_cp_stats_set_rate_flags() - API to set rate flags
* @vdev: pointer to vdev object
* @flags: value to set (enum tx_rate_info)
* @flags: value to set
*
* Return: status of operation
*/
QDF_STATUS ucfg_mc_cp_stats_set_rate_flags(struct wlan_objmgr_vdev *vdev,
enum tx_rate_info flags);
uint32_t flags);
/**
* ucfg_mc_cp_stats_register_lost_link_info_cb() - API to register lost link
@@ -425,7 +425,7 @@ static inline QDF_STATUS ucfg_mc_cp_stats_send_stats_request(
static inline QDF_STATUS ucfg_mc_cp_stats_set_rate_flags(
struct wlan_objmgr_vdev *vdev,
enum tx_rate_info flags)
uint32_t flags)
{
return QDF_STATUS_SUCCESS;
}

View File

@@ -1157,6 +1157,27 @@ wlan_mlme_send_ch_width_update_with_notify(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
enum phy_ch_width ch_width);
/**
* wlan_mlme_update_bss_rate_flags() - update bss rate flag as per new channel
* width
* @psoc: pointer to psoc object
* @vdev_id: Vdev id
* @cw: channel width to update
* @eht_present: connected bss is eht capable or not
* @he_present: connected bss is he capable or not
* @vht_present: connected bss is vht capable or not
* @ht_present: connected bss is ht capable or not
*
* Return: QDF_STATUS
*/
QDF_STATUS wlan_mlme_update_bss_rate_flags(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
enum phy_ch_width cw,
uint8_t eht_present,
uint8_t he_present,
uint8_t vht_present,
uint8_t ht_present);
#ifdef WLAN_FEATURE_11BE
/**
* mlme_update_tgt_eht_caps_in_cfg() - Update tgt eht cap in mlme component

View File

@@ -4728,6 +4728,27 @@ QDF_STATUS
ucfg_mlme_set_vdev_traffic_low_latency(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id, bool set);
/**
* ucfg_mlme_update_bss_rate_flags() - update bss rate flag as per new channel
* width
* @psoc: pointer to psoc object
* @vdev_id: Vdev id
* @ch_width: channel width to update
* @eht_present: connected bss is eht capable or not
* @he_present: connected bss is he capable or not
* @vht_present: connected bss is vht capable or not
* @ht_present: connected bss is ht capable or not
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_mlme_update_bss_rate_flags(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
enum phy_ch_width ch_width,
uint8_t eht_present,
uint8_t he_present,
uint8_t vht_present,
uint8_t ht_present);
/**
* ucfg_mlme_send_ch_width_update_with_notify() - Send chwidth with notify
* capability of FW

View File

@@ -37,6 +37,7 @@
#include "target_if.h"
#include "wlan_vdev_mgr_tgt_if_tx_api.h"
#include "wmi_unified_vdev_api.h"
#include "../../core/src/wlan_cp_stats_defs.h"
/* quota in milliseconds */
#define MCC_DUTY_CYCLE 70
@@ -7025,6 +7026,192 @@ static QDF_STATUS wlan_mlme_update_ch_width(struct wlan_objmgr_vdev *vdev,
return QDF_STATUS_SUCCESS;
}
static uint32_t
wlan_mlme_get_vht_rate_flags(enum phy_ch_width ch_width)
{
uint32_t rate_flags = 0;
if (ch_width == CH_WIDTH_80P80MHZ || ch_width == CH_WIDTH_160MHZ)
rate_flags |= TX_RATE_VHT160 | TX_RATE_VHT80 | TX_RATE_VHT40 |
TX_RATE_VHT20;
if (ch_width == CH_WIDTH_80MHZ)
rate_flags |= TX_RATE_VHT80 | TX_RATE_VHT40 | TX_RATE_VHT20;
else if (ch_width)
rate_flags |= TX_RATE_VHT40 | TX_RATE_VHT20;
else
rate_flags |= TX_RATE_VHT20;
return rate_flags;
}
static uint32_t wlan_mlme_get_ht_rate_flags(enum phy_ch_width ch_width)
{
uint32_t rate_flags = 0;
if (ch_width)
rate_flags |= TX_RATE_HT40 | TX_RATE_HT20;
else
rate_flags |= TX_RATE_HT20;
return rate_flags;
}
#ifdef WLAN_FEATURE_11BE
static uint32_t
wlan_mlme_get_eht_rate_flags(enum phy_ch_width ch_width)
{
uint32_t rate_flags = 0;
if (ch_width == CH_WIDTH_320MHZ)
rate_flags |= TX_RATE_EHT320 | TX_RATE_EHT160 |
TX_RATE_EHT80 | TX_RATE_EHT40 | TX_RATE_EHT20;
else if (ch_width == CH_WIDTH_160MHZ || ch_width == CH_WIDTH_80P80MHZ)
rate_flags |= TX_RATE_EHT160 | TX_RATE_EHT80 | TX_RATE_EHT40 |
TX_RATE_EHT20;
else if (ch_width == CH_WIDTH_80MHZ)
rate_flags |= TX_RATE_EHT80 | TX_RATE_EHT40 | TX_RATE_EHT20;
else if (ch_width)
rate_flags |= TX_RATE_EHT40 | TX_RATE_EHT20;
else
rate_flags |= TX_RATE_EHT20;
return rate_flags;
}
static QDF_STATUS
wlan_mlme_set_bss_rate_flags_eht(uint32_t *rate_flags, uint8_t eht_present,
enum phy_ch_width ch_width)
{
if (!eht_present)
return QDF_STATUS_E_NOSUPPORT;
*rate_flags |= wlan_mlme_get_eht_rate_flags(ch_width);
return QDF_STATUS_SUCCESS;
}
#else
static inline QDF_STATUS
wlan_mlme_set_bss_rate_flags_eht(uint32_t *rate_flags, uint8_t eht_present,
enum phy_ch_width ch_width)
{
return QDF_STATUS_E_NOSUPPORT;
}
#endif
#ifdef WLAN_FEATURE_11AX
static uint32_t wlan_mlme_get_he_rate_flags(enum phy_ch_width ch_width)
{
uint32_t rate_flags = 0;
if (ch_width == CH_WIDTH_160MHZ ||
ch_width == CH_WIDTH_80P80MHZ)
rate_flags |= TX_RATE_HE160 | TX_RATE_HE80 | TX_RATE_HE40 |
TX_RATE_HE20;
else if (ch_width == CH_WIDTH_80MHZ)
rate_flags |= TX_RATE_HE80 | TX_RATE_HE40 | TX_RATE_HE20;
else if (ch_width)
rate_flags |= TX_RATE_HE40 | TX_RATE_HE20;
else
rate_flags |= TX_RATE_HE20;
return rate_flags;
}
static QDF_STATUS wlan_mlme_set_bss_rate_flags_he(uint32_t *rate_flags,
uint8_t he_present,
enum phy_ch_width ch_width)
{
if (!he_present)
return QDF_STATUS_E_NOSUPPORT;
*rate_flags |= wlan_mlme_get_he_rate_flags(ch_width);
return QDF_STATUS_SUCCESS;
}
#else
static inline QDF_STATUS
wlan_mlme_set_bss_rate_flags_he(uint32_t *rate_flags,
uint8_t he_present,
enum phy_ch_width ch_width)
{
return QDF_STATUS_E_NOSUPPORT;
}
#endif
static QDF_STATUS
wlan_mlme_cp_stats_set_rate_flags(struct wlan_objmgr_vdev *vdev,
uint32_t flags)
{
struct vdev_mc_cp_stats *vdev_mc_stats;
struct vdev_cp_stats *vdev_cp_stats_priv;
vdev_cp_stats_priv = wlan_cp_stats_get_vdev_stats_obj(vdev);
if (!vdev_cp_stats_priv) {
cp_stats_err("vdev cp stats object is null");
return QDF_STATUS_E_NULL_VALUE;
}
wlan_cp_stats_vdev_obj_lock(vdev_cp_stats_priv);
vdev_mc_stats = vdev_cp_stats_priv->vdev_stats;
vdev_mc_stats->tx_rate_flags = flags;
wlan_cp_stats_vdev_obj_unlock(vdev_cp_stats_priv);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
wlan_mlme_update_bss_rate_flags(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
enum phy_ch_width cw, uint8_t eht_present,
uint8_t he_present, uint8_t vht_present,
uint8_t ht_present)
{
uint32_t *rate_flags;
struct vdev_mlme_obj *vdev_mlme;
struct wlan_objmgr_vdev *vdev;
QDF_STATUS status;
if (!eht_present && !he_present && !vht_present && !ht_present)
return QDF_STATUS_E_INVAL;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
WLAN_HDD_ID_OBJ_MGR);
if (!vdev) {
mlme_debug("vdev: %d vdev not found", vdev_id);
return QDF_STATUS_E_INVAL;
}
vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
if (!vdev_mlme) {
mlme_debug("vdev: %d mlme obj not found", vdev_id);
wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
return QDF_STATUS_E_INVAL;
}
rate_flags = &vdev_mlme->mgmt.rate_info.rate_flags;
*rate_flags = 0;
status = wlan_mlme_set_bss_rate_flags_eht(rate_flags, eht_present, cw);
if (QDF_IS_STATUS_ERROR(status)) {
status = wlan_mlme_set_bss_rate_flags_he(rate_flags,
he_present, cw);
if (QDF_IS_STATUS_ERROR(status)) {
if (vht_present)
*rate_flags = wlan_mlme_get_vht_rate_flags(cw);
else if (ht_present)
*rate_flags |= wlan_mlme_get_ht_rate_flags(cw);
}
}
mlme_debug("vdev:%d, eht:%u, he:%u, vht:%u, ht:%u, flag:%x, cw:%d",
vdev_id, eht_present, he_present, vht_present, ht_present,
*rate_flags, cw);
status = wlan_mlme_cp_stats_set_rate_flags(vdev, *rate_flags);
wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);
return status;
}
QDF_STATUS
wlan_mlme_send_ch_width_update_with_notify(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev,

View File

@@ -380,6 +380,19 @@ ucfg_mlme_is_chwidth_with_notify_supported(struct wlan_objmgr_psoc *psoc)
WLAN_VDEV_PARAM_CHWIDTH_WITH_NOTIFY_SUPPORT);
}
QDF_STATUS ucfg_mlme_update_bss_rate_flags(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
enum phy_ch_width ch_width,
uint8_t eht_present,
uint8_t he_present,
uint8_t vht_present,
uint8_t ht_present)
{
return wlan_mlme_update_bss_rate_flags(psoc, vdev_id, ch_width,
eht_present, he_present,
vht_present, ht_present);
}
QDF_STATUS
ucfg_mlme_send_ch_width_update_with_notify(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,

View File

@@ -69,6 +69,7 @@ enum peer_status {
* @hs20_present: hs20 element present or not
* @ht_op_present: ht operation present or not
* @vht_op_present: vht operation present or not
* @he_present: he operation present or not
* @reserved: reserved spare bits
*/
struct hdd_conn_flag {
@@ -78,7 +79,8 @@ struct hdd_conn_flag {
uint8_t hs20_present:1;
uint8_t ht_op_present:1;
uint8_t vht_op_present:1;
uint8_t reserved:2;
uint8_t he_present:1;
uint8_t reserved:1;
};
/*defines for tx_BF_cap_info */

View File

@@ -2171,6 +2171,37 @@ hdd_convert_chwidth_to_phy_chwidth(enum eSirMacHTChannelWidth chwidth)
return ch_width;
}
/**
* hdd_update_bss_rate_flags() - update bss rate flag as per new channel width
* @adapter: adapter being modified
* @psoc: psoc common object
* @cw: channel width for which bss rate flag being updated
*
* Return: QDF_STATUS
*/
static QDF_STATUS hdd_update_bss_rate_flags(struct hdd_adapter *adapter,
struct wlan_objmgr_psoc *psoc,
enum phy_ch_width cw)
{
struct hdd_station_ctx *hdd_sta_ctx;
uint8_t eht_present, he_present, vht_present, ht_present;
hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink);
if (!hdd_sta_ctx) {
hdd_err("hdd_sta_ctx is null");
return QDF_STATUS_E_INVAL;
}
eht_present = hdd_sta_ctx->conn_info.conn_flag.eht_present;
he_present = hdd_sta_ctx->conn_info.conn_flag.he_present;
vht_present = hdd_sta_ctx->conn_info.conn_flag.vht_present;
ht_present = hdd_sta_ctx->conn_info.conn_flag.ht_present;
return ucfg_mlme_update_bss_rate_flags(psoc, adapter->deflink->vdev_id,
cw, eht_present, he_present,
vht_present, ht_present);
}
int hdd_update_channel_width(struct hdd_adapter *adapter,
enum eSirMacHTChannelWidth chwidth,
uint32_t bonding_mode)
@@ -2197,6 +2228,10 @@ int hdd_update_channel_width(struct hdd_adapter *adapter,
adapter->deflink->vdev_id, ch_width);
if (QDF_IS_STATUS_ERROR(status))
return -EIO;
status = hdd_update_bss_rate_flags(adapter, hdd_ctx->psoc,
ch_width);
if (QDF_IS_STATUS_ERROR(status))
return -EIO;
}
sme_config = qdf_mem_malloc(sizeof(*sme_config));

View File

@@ -1133,6 +1133,16 @@ static void hdd_cm_save_bss_info(struct wlan_hdd_link_info *link_info,
hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false;
}
if (assoc_resp->he_cap.present)
hdd_sta_ctx->conn_info.conn_flag.he_present = true;
else
hdd_sta_ctx->conn_info.conn_flag.he_present = false;
if (assoc_resp->eht_cap.present)
hdd_sta_ctx->conn_info.conn_flag.eht_present = true;
else
hdd_sta_ctx->conn_info.conn_flag.eht_present = false;
/*
* Cache connection info only in case of station
*/