qcacld-3.0: Update connected VDEV channel bandwidth

Host receives QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH vendor
command indication to update STA adapter channel width.

On receiving channel width update indication from upper layer,
first host updates internally and send new channel width value
to FW via WMI_VDEV_PARAM_CHWIDTH_WITH_NOTIFY.

Target firmware should take care of notifying associated peers
(except TDLS) about change in bandwidth, through OMN/OMI
notification before performing bandwidth update internally.

Change-Id: I517ed1fbf8d074e511f8fb43c9c1dac824c9f084
CRs-Fixed: 3469473
This commit is contained in:
abhinav kumar
2023-04-10 00:21:43 +05:30
committed by Madan Koyyalamudi
parent 076551fd20
commit 80fc700acf
5 changed files with 249 additions and 0 deletions

View File

@@ -35,6 +35,7 @@
#include "wlan_psoc_mlme_api.h"
#include "wlan_action_oui_main.h"
#include "target_if.h"
#include "wlan_vdev_mgr_tgt_if_tx_api.h"
/* quota in milliseconds */
#define MCC_DUTY_CYCLE 70
@@ -6682,6 +6683,121 @@ void wlan_mlme_chan_stats_scan_event_cb(struct wlan_objmgr_vdev *vdev,
mlme_send_scan_done_complete_cb(event->vdev_id);
}
static QDF_STATUS
wlan_mlme_update_vdev_chwidth_with_notify(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev,
uint8_t vdev_id,
enum phy_ch_width ch_width)
{
struct vdev_mlme_obj *vdev_mlme;
struct vdev_set_params param = {0};
QDF_STATUS status;
vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
if (!vdev_mlme)
return QDF_STATUS_E_FAILURE;
param.param_id = wmi_vdev_param_chwidth_with_notify;
param.vdev_id = vdev_id;
param.param_value = ch_width;
status = tgt_vdev_mgr_set_param_send(vdev_mlme, &param);
policy_mgr_handle_ml_sta_link_on_traffic_type_change(psoc, vdev);
return status;
}
static QDF_STATUS wlan_mlme_update_ch_width(struct wlan_objmgr_vdev *vdev,
uint8_t vdev_id,
enum phy_ch_width ch_width)
{
struct wlan_channel *des_chan;
struct wlan_channel *bss_chan;
uint16_t curr_op_freq;
struct ch_params ch_params = {0};
struct wlan_objmgr_pdev *pdev;
des_chan = wlan_vdev_mlme_get_des_chan(vdev);
if (!des_chan)
return QDF_STATUS_E_FAILURE;
bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
if (!bss_chan)
return QDF_STATUS_E_FAILURE;
pdev = wlan_vdev_get_pdev(vdev);
if (!pdev) {
mlme_err("vdev %d: Pdev is NULL", vdev_id);
return QDF_STATUS_E_INVAL;
}
ch_params.ch_width = ch_width;
curr_op_freq = des_chan->ch_freq;
wlan_reg_set_channel_params_for_pwrmode(pdev, curr_op_freq,
0, &ch_params,
REG_CURRENT_PWR_MODE);
des_chan->ch_width = ch_width;
des_chan->ch_freq_seg1 = ch_params.center_freq_seg0;
des_chan->ch_freq_seg2 = ch_params.center_freq_seg1;
des_chan->ch_cfreq1 = ch_params.mhz_freq_seg0;
des_chan->ch_cfreq2 = ch_params.mhz_freq_seg1;
qdf_mem_copy(bss_chan, des_chan, sizeof(struct wlan_channel));
mlme_legacy_debug("vdev id %d freq %d seg0 %d seg1 %d ch_width %d mhz seg0 %d mhz seg1 %d",
vdev_id, curr_op_freq, ch_params.center_freq_seg0,
ch_params.center_freq_seg1, ch_params.ch_width,
ch_params.mhz_freq_seg0, ch_params.mhz_freq_seg1);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
wlan_mlme_send_ch_width_update_with_notify(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev,
uint8_t vdev_id,
enum phy_ch_width ch_width)
{
QDF_STATUS status;
enum phy_ch_width associated_ch_width;
struct wlan_channel *des_chan;
des_chan = wlan_vdev_mlme_get_des_chan(vdev);
if (!des_chan)
return QDF_STATUS_E_INVAL;
if (wlan_reg_is_24ghz_ch_freq(des_chan->ch_freq)) {
mlme_debug("vdev %d: CW:%d update not supported for freq:%d",
vdev_id, ch_width, des_chan->ch_freq);
return QDF_STATUS_E_NOSUPPORT;
}
associated_ch_width = wlan_cm_get_associated_ch_width(psoc, vdev_id);
if (ch_width > associated_ch_width) {
mlme_debug("vdev %d: Invalid new chwidth:%d, assoc ch_width:%d",
vdev_id, ch_width, associated_ch_width);
return QDF_STATUS_E_INVAL;
}
/* update ch width to internal host structure */
status = wlan_mlme_update_ch_width(vdev, vdev_id, ch_width);
if (QDF_IS_STATUS_ERROR(status)) {
mlme_err("vdev %d: Failed to update CW:%d to host, status:%d",
vdev_id, ch_width, status);
return status;
}
/* update ch width to fw */
status = wlan_mlme_update_vdev_chwidth_with_notify(psoc, vdev, vdev_id,
ch_width);
if (QDF_IS_STATUS_ERROR(status))
mlme_err("vdev %d: Failed to update CW:%d to fw, status:%d",
vdev_id, ch_width, status);
return status;
}
enum phy_ch_width wlan_mlme_convert_vht_op_bw_to_phy_ch_width(
uint8_t channel_width)
{

View File

@@ -373,6 +373,46 @@ void ucfg_mlme_connected_chan_stats_request(struct wlan_objmgr_psoc *psoc,
mlme_connected_chan_stats_request(psoc, vdev_id);
}
bool
ucfg_mlme_is_chwidth_with_notify_supported(struct wlan_objmgr_psoc *psoc)
{
return wlan_psoc_nif_fw_ext2_cap_get(psoc,
WLAN_VDEV_PARAM_CHWIDTH_WITH_NOTIFY_SUPPORT);
}
QDF_STATUS
ucfg_mlme_send_ch_width_update_with_notify(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
enum phy_ch_width ch_width)
{
struct wlan_objmgr_vdev *vdev;
QDF_STATUS status;
enum QDF_OPMODE mode;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
WLAN_MLME_OBJMGR_ID);
if (!vdev) {
mlme_legacy_err("vdev %d: vdev not found", vdev_id);
return QDF_STATUS_E_FAILURE;
}
mode = wlan_vdev_mlme_get_opmode(vdev);
if (mode != QDF_STA_MODE) {
mlme_legacy_debug("vdev %d: mode %d, CW update not supported",
vdev_id, mode);
status = QDF_STATUS_E_NOSUPPORT;
goto release;
}
status = wlan_mlme_send_ch_width_update_with_notify(psoc, vdev,
vdev_id, ch_width);
release:
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
return status;
}
QDF_STATUS
ucfg_mlme_set_vdev_traffic_low_latency(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id, bool set)