diff --git a/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c b/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c index e3b92b9968..c6684b9ded 100644 --- a/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c +++ b/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_tx_ops.c @@ -1024,6 +1024,43 @@ static QDF_STATUS target_if_vdev_mgr_multiple_vdev_restart_req_cmd( return status; } +static QDF_STATUS target_if_vdev_mgr_multiple_vdev_set_param_cmd( + struct wlan_objmgr_pdev *pdev, + struct multiple_vdev_set_param *param) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct wmi_unified *wmi_handle; + struct wlan_objmgr_psoc *psoc; + + if (!pdev || !param) { + mlme_err("Invalid input"); + return QDF_STATUS_E_INVAL; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + mlme_err("PSOC is NULL"); + return QDF_STATUS_E_INVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_pdev(pdev); + if (!wmi_handle) { + mlme_err("PDEV WMI Handle is NULL!"); + return QDF_STATUS_E_INVAL; + } + + if (param->num_vdevs > WLAN_UMAC_PDEV_MAX_VDEVS) { + mlme_err("param->num_vdevs: %u exceed the limit", + param->num_vdevs); + return QDF_STATUS_E_INVAL; + } + + status = wmi_unified_send_multiple_vdev_set_param_cmd(wmi_handle, + param); + + return status; +} + static QDF_STATUS target_if_vdev_mgr_beacon_send( struct wlan_objmgr_vdev *vdev, struct beacon_params *param) @@ -1204,6 +1241,8 @@ target_if_vdev_mgr_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) target_if_vdev_mgr_peer_flush_tids_send; mlme_tx_ops->multiple_vdev_restart_req_cmd = target_if_vdev_mgr_multiple_vdev_restart_req_cmd; + mlme_tx_ops->multiple_vdev_set_param_cmd = + target_if_vdev_mgr_multiple_vdev_set_param_cmd; mlme_tx_ops->beacon_cmd_send = target_if_vdev_mgr_beacon_send; mlme_tx_ops->beacon_tmpl_send = target_if_vdev_mgr_beacon_tmpl_send; mlme_tx_ops->vdev_set_param_send = diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h index ec3af02ff7..75cf0d1e10 100644 --- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h +++ b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h @@ -302,6 +302,7 @@ enum wlan_mlme_cfg_id; * @vdev_config_ratemask_cmd_send: function to send ratemask * @peer_flush_tids_send: function to flush peer tids * @multiple_vdev_restart_req_cmd: function to send multiple vdev restart + * @multiple_vdev_set_param_cmd: function to send multiple vdev param * @beacon_send_cmd: function to send beacon * @beacon_tmpl_send: function to send beacon template * @vdev_bcn_miss_offload_send: function to send beacon miss offload @@ -358,6 +359,9 @@ struct wlan_lmac_if_mlme_tx_ops { QDF_STATUS (*multiple_vdev_restart_req_cmd)( struct wlan_objmgr_pdev *pdev, struct multiple_vdev_restart_params *param); + QDF_STATUS (*multiple_vdev_set_param_cmd)( + struct wlan_objmgr_pdev *pdev, + struct multiple_vdev_set_param *param); QDF_STATUS (*beacon_cmd_send)(struct wlan_objmgr_vdev *vdev, struct beacon_params *param); QDF_STATUS (*beacon_tmpl_send)(struct wlan_objmgr_vdev *vdev, diff --git a/umac/mlme/include/wlan_vdev_mlme.h b/umac/mlme/include/wlan_vdev_mlme.h index 6db0879e18..884bb6978b 100644 --- a/umac/mlme/include/wlan_vdev_mlme.h +++ b/umac/mlme/include/wlan_vdev_mlme.h @@ -56,6 +56,7 @@ struct cnx_mgr; #define WLAN_VDEV_MLME_FLAGS_TRANSMIT_AP 0x00000002 #define WLAN_VDEV_MLME_FLAGS_NON_TRANSMIT_AP 0x00000004 #define WLAN_VDEV_MLME_FLAGS_EMA_MODE 0x00000008 +#define WLAN_VDEV_MLME_FLAGS_MBSS_CMN_PARAM 0x00000010 /** * struct vdev_mlme_proto_generic - generic mlme proto structure @@ -481,6 +482,8 @@ struct vdev_mlme_beacon_info { * 0 means non-MBSS AP. * @mbssid-flags: MBSS IE flags indicating vdev type * @vdevid_trans: id of transmitting vdev for MBSS IE + * @vdev_bmap: vdev bitmap of VAPs in MBSS group + * @is_cmn_param: flag to check mbss common param * @trans_bssid: bssid of transmitted AP (MBSS IE case) */ struct vdev_mlme_mbss_11ax { @@ -488,6 +491,8 @@ struct vdev_mlme_mbss_11ax { uint32_t profile_num; uint32_t mbssid_flags; uint8_t vdevid_trans; + unsigned long vdev_bmap; + bool is_cmn_param; uint8_t trans_bssid[QDF_MAC_ADDR_SIZE]; }; diff --git a/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_api.h b/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_api.h index ddca045633..6a38f7bc7f 100644 --- a/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_api.h +++ b/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2019, 2021 The Linux Foundation. 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 @@ -260,6 +260,18 @@ QDF_STATUS tgt_vdev_mgr_multiple_vdev_restart_send( struct wlan_objmgr_pdev *pdev, struct multiple_vdev_restart_params *param); +/** + * tgt_vdev_mgr_multiple_vdev_set_param() – API to send multiple vdev + * param + * @pdev: pointer to pdev + * @param: pointer to multiple_vdev_set_param + * + * Return: QDF_STATUS - Success or Failure + */ +QDF_STATUS tgt_vdev_mgr_multiple_vdev_set_param( + struct wlan_objmgr_pdev *pdev, + struct multiple_vdev_set_param *param); + /** * tgt_vdev_mgr_set_tx_rx_decap_type() – API to send tx rx decap type * @mlme_obj: pointer to vdev mlme obj diff --git a/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_tx_api.c b/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_tx_api.c index 040d9cacac..4abcd6e51e 100644 --- a/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_tx_api.c +++ b/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_tx_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021 The Linux Foundation. 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 @@ -539,6 +539,41 @@ QDF_STATUS tgt_vdev_mgr_multiple_vdev_restart_send( return status; } +QDF_STATUS tgt_vdev_mgr_multiple_vdev_set_param( + struct wlan_objmgr_pdev *pdev, + struct multiple_vdev_set_param *param) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_lmac_if_mlme_tx_ops *txops; + struct wlan_objmgr_vdev *vdev; + + if (!param) { + mlme_err("Invalid input"); + return QDF_STATUS_E_INVAL; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, + param->vdev_ids[0], + WLAN_VDEV_TARGET_IF_ID); + if (vdev) { + txops = wlan_vdev_mlme_get_lmac_txops(vdev); + if (!txops || !txops->multiple_vdev_set_param_cmd) { + mlme_err("VDEV_%d: No Tx Ops", wlan_vdev_get_id(vdev)); + wlan_objmgr_vdev_release_ref(vdev, + WLAN_VDEV_TARGET_IF_ID); + return QDF_STATUS_E_INVAL; + } + + status = txops->multiple_vdev_set_param_cmd(pdev, param); + if (QDF_IS_STATUS_ERROR(status)) + mlme_err("Tx Ops Error: %d", status); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); + } + + return status; +} + QDF_STATUS tgt_vdev_mgr_set_tx_rx_decap_type(struct vdev_mlme_obj *mlme_obj, enum wlan_mlme_cfg_id param_id, uint32_t value) diff --git a/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_utils_api.c b/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_utils_api.c index 216df02736..2541a32f0c 100644 --- a/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_utils_api.c +++ b/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_utils_api.c @@ -128,6 +128,65 @@ wlan_util_vdev_mlme_set_ratemask_config(struct vdev_mlme_obj *vdev_mlme) qdf_export_symbol(wlan_util_vdev_mlme_set_ratemask_config); +static QDF_STATUS +tgt_vdev_mgr_vdev_set_param_wrapper(struct vdev_mlme_obj *vdev_mlme, + enum wlan_mlme_cfg_id param_id, + struct wlan_vdev_mgr_cfg mlme_cfg) +{ + uint8_t id, count = 0; + bool is_mbss_enabled, is_cmn_param = 0; + unsigned long vdev_bmap = 0; + struct wlan_objmgr_pdev *pdev; + struct vdev_mlme_mbss_11ax *mbss; + struct vdev_set_params param1 = {0}; + struct multiple_vdev_set_param param2 = {0}; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + mbss = &vdev_mlme->mgmt.mbss_11ax; + is_mbss_enabled = (mbss->mbssid_flags + & WLAN_VDEV_MLME_FLAGS_NON_MBSSID_AP) ? 0 : 1; + + if (is_mbss_enabled) { + vdev_bmap = mbss->vdev_bmap; + is_cmn_param = mbss->is_cmn_param; + } + + /* 1. if non tx vap and cmn param, dont send any WMI + * 2. if tx vap and cmn param, send multi vdev set WMI + * 3. if non tx vap and non cmn param, send vdev set WMI + * 4. if tx vap and non cmn param, send vdev set WMI + * 5. if non mbss vap, send vdev set WMI + */ + if (!is_mbss_enabled || !is_cmn_param) { + param1.param_id = param_id; + param1.vdev_id = wlan_vdev_get_id(vdev_mlme->vdev); + param1.param_value = mlme_cfg.value; + return tgt_vdev_mgr_set_param_send(vdev_mlme, ¶m1); + } + + if (is_cmn_param && vdev_bmap) { + pdev = wlan_vdev_get_pdev(vdev_mlme->vdev); + param2.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + param2.param_id = param_id; + param2.param_value = mlme_cfg.value; + + for (id = 0; id < WLAN_UMAC_PDEV_MAX_VDEVS; id++) { + if (qdf_test_bit(id, &vdev_bmap)) { + param2.vdev_ids[count] = id; + count++; + } + } + param2.num_vdevs = count; + status = tgt_vdev_mgr_multiple_vdev_set_param(pdev, ¶m2); + mbss->vdev_bmap = 0; + } + + /* Reset the is_cmn_param for this vap */ + mbss->is_cmn_param = 0; + + return status; +} + QDF_STATUS wlan_util_vdev_mlme_set_param(struct vdev_mlme_obj *vdev_mlme, enum wlan_mlme_cfg_id param_id, @@ -139,7 +198,6 @@ wlan_util_vdev_mlme_set_param(struct vdev_mlme_obj *vdev_mlme, struct vdev_mlme_inactivity_params *inactivity_params; bool is_wmi_cmd = false; int ret = QDF_STATUS_SUCCESS; - struct vdev_set_params param = {0}; if (!vdev_mlme) { mlme_err("VDEV MLME is NULL"); @@ -414,12 +472,9 @@ wlan_util_vdev_mlme_set_param(struct vdev_mlme_obj *vdev_mlme, break; } - if (is_wmi_cmd) { - param.param_id = param_id; - param.vdev_id = wlan_vdev_get_id(vdev); - param.param_value = mlme_cfg.value; - ret = tgt_vdev_mgr_set_param_send(vdev_mlme, ¶m); - } + if (is_wmi_cmd) + ret = tgt_vdev_mgr_vdev_set_param_wrapper(vdev_mlme, param_id, + mlme_cfg); return ret; }