qcacld-3.0: Add support to dynamic MAC address update
Currently, MAC address update is supported only when interface is down. Because of this framework needs to issue interface down and interface up to update the MAC address. Interface down and up will lead to VDEV delete and VDEV create commands to the FW. To optimize Host-FW interactions during set MAC address, add support to update the MAC address without bringing the interface to down state. Change-Id: I76afa8f8c2504e8271bf689392d526f994afff0a CRs-Fixed: 3063201
This commit is contained in:
parent
5f2a05fcab
commit
0de141916d
4
Kbuild
4
Kbuild
@ -1004,7 +1004,8 @@ OS_IF_OBJ += $(OS_IF_DIR)/linux/wlan_osif_request_manager.o \
|
||||
$(OS_IF_DIR)/linux/mlme/src/osif_cm_connect_rsp.o \
|
||||
$(OS_IF_DIR)/linux/mlme/src/osif_cm_disconnect_rsp.o \
|
||||
$(OS_IF_DIR)/linux/mlme/src/osif_cm_req.o \
|
||||
$(OS_IF_DIR)/linux/mlme/src/osif_cm_roam_rsp.o
|
||||
$(OS_IF_DIR)/linux/mlme/src/osif_cm_roam_rsp.o \
|
||||
$(OS_IF_DIR)/linux/mlme/src/osif_vdev_mgr_util.o
|
||||
|
||||
CONFIG_CRYPTO_COMPONENT := y
|
||||
|
||||
@ -3727,6 +3728,7 @@ cppflags-$(CONFIG_FEATURE_ALIGN_STATS_FROM_DP) += -DFEATURE_ALIGN_STATS_FROM_DP
|
||||
cppflags-$(CONFIG_DP_RX_SPECIAL_FRAME_NEED) += -DDP_RX_SPECIAL_FRAME_NEED
|
||||
cppflags-$(CONFIG_FEATURE_STATS_EXT_V2) += -DFEATURE_STATS_EXT_V2
|
||||
cppflags-$(CONFIG_WLAN_FEATURE_CAL_FAILURE_TRIGGER) += -DWLAN_FEATURE_CAL_FAILURE_TRIGGER
|
||||
cppflags-$(CONFIG_WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE) += -DWLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
|
||||
cppflags-$(CONFIG_VERBOSE_DEBUG) += -DENABLE_VERBOSE_DEBUG
|
||||
cppflags-$(CONFIG_RX_DESC_DEBUG_CHECK) += -DRX_DESC_DEBUG_CHECK
|
||||
|
@ -1389,6 +1389,16 @@ QDF_STATUS vdevmgr_mlme_ext_hdl_destroy(struct vdev_mlme_obj *vdev_mlme)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
static
|
||||
QDF_STATUS vdevmgr_mlme_vdev_send_set_mac_addr(struct qdf_mac_addr mac_addr,
|
||||
struct qdf_mac_addr mld_addr,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return vdev_mgr_send_set_mac_addr(mac_addr, mld_addr, vdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ap_vdev_dfs_cac_timer_stop() – callback to stop cac timer
|
||||
* @vdev_mlme: vdev mlme object
|
||||
@ -1907,6 +1917,9 @@ static struct mlme_ext_ops ext_ops = {
|
||||
.mlme_cm_ext_vdev_down_req_cb = cm_send_vdev_down_req,
|
||||
.mlme_cm_ext_reassoc_req_cb = cm_handle_reassoc_req,
|
||||
.mlme_cm_ext_roam_start_ind_cb = cm_handle_roam_start,
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
.mlme_vdev_send_set_mac_addr = vdevmgr_mlme_vdev_send_set_mac_addr,
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
|
@ -1247,6 +1247,7 @@ struct hdd_context;
|
||||
* progress, and any operation using rtnl lock inside
|
||||
* the driver can be avoided/skipped.
|
||||
* @mon_adapter: hdd_adapter of monitor mode.
|
||||
* @set_mac_addr_req_ctx: Set MAC address command request context
|
||||
*/
|
||||
struct hdd_adapter {
|
||||
/* Magic cookie for adapter sanity verification. Note that this
|
||||
@ -1572,6 +1573,9 @@ struct hdd_adapter {
|
||||
#if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
|
||||
struct hdd_mlo_adapter_info mlo_adapter_info;
|
||||
#endif
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
void *set_mac_addr_req_ctx;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define WLAN_HDD_GET_STATION_CTX_PTR(adapter) (&(adapter)->session.station)
|
||||
@ -2309,6 +2313,10 @@ struct hdd_context {
|
||||
bool is_therm_stats_in_progress;
|
||||
#endif
|
||||
qdf_atomic_t rx_skip_qdisc_chk_conc;
|
||||
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
bool is_vdev_macaddr_dynamic_update_supported;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@ -5148,6 +5156,60 @@ static inline void hdd_dp_ssr_unprotect(void)
|
||||
qdf_atomic_dec(&dp_protect_entry_count);
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
/**
|
||||
* hdd_dynamic_mac_address_set(): API to set MAC address, when interface
|
||||
* is up.
|
||||
* @hdd_context: Pointer to HDD context
|
||||
* @adapter: Pointer to hdd_adapter
|
||||
* @mac_addr: MAC address to set
|
||||
*
|
||||
* This API is used to update the current VDEV MAC address.
|
||||
*
|
||||
* Return: 0 for success. non zero valure for failure.
|
||||
*/
|
||||
int hdd_dynamic_mac_address_set(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter,
|
||||
struct qdf_mac_addr mac_addr);
|
||||
|
||||
#if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
|
||||
/**
|
||||
* hdd_update_vdev_mac_address() - Update VDEV MAC address dynamically
|
||||
* @hdd_ctx: Pointer to HDD context
|
||||
* @adapter: Pointer to HDD adapter
|
||||
* @mac_addr: MAC address to be updated
|
||||
*
|
||||
* API to update VDEV MAC address during interface is in UP state.
|
||||
*
|
||||
* Return: 0 for Success. Error code for failure
|
||||
*/
|
||||
int hdd_update_vdev_mac_address(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter,
|
||||
struct qdf_mac_addr mac_addr);
|
||||
#else
|
||||
static inline int hdd_update_vdev_mac_address(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter,
|
||||
struct qdf_mac_addr mac_addr)
|
||||
{
|
||||
return hdd_dynamic_mac_address_set(hdd_ctx, adapter, mac_addr);
|
||||
}
|
||||
#endif /* WLAN_FEATURE_11BE_MLO */
|
||||
#else
|
||||
static inline int hdd_update_vdev_mac_address(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter,
|
||||
struct qdf_mac_addr mac_addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int hdd_dynamic_mac_address_set(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter,
|
||||
struct qdf_mac_addr mac_addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE */
|
||||
|
||||
#ifdef FEATURE_WLAN_FULL_POWER_DOWN_SUPPORT
|
||||
/**
|
||||
* hdd_set_suspend_mode: set the suspend_mode state to pld based on the
|
||||
|
@ -42,9 +42,12 @@ struct hdd_adapter_create_param {
|
||||
#if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
|
||||
#define hdd_adapter_is_link_adapter(x) ((x)->mlo_adapter_info.is_link_adapter)
|
||||
#define hdd_adapter_is_ml_adapter(x) ((x)->mlo_adapter_info.is_ml_adapter)
|
||||
#define hdd_adapter_is_associated_with_ml_adapter(x) \
|
||||
((x)->mlo_adapter_info.associate_with_ml_adapter)
|
||||
#else
|
||||
#define hdd_adapter_is_link_adapter(x) (0)
|
||||
#define hdd_adapter_is_ml_adapter(x) (0)
|
||||
#define hdd_adapter_is_associated_with_ml_adapter(x) (0)
|
||||
#endif
|
||||
|
||||
#if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
|
||||
|
@ -769,6 +769,13 @@ static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
|
||||
hdd_debug("Changing MAC to " QDF_MAC_ADDR_FMT " of interface %s ",
|
||||
QDF_MAC_ADDR_REF(mac_addr.bytes),
|
||||
dev->name);
|
||||
|
||||
if (adapter->vdev) {
|
||||
ret = hdd_dynamic_mac_address_set(hdd_ctx, adapter, mac_addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr);
|
||||
memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
|
||||
memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
|
||||
|
@ -212,8 +212,10 @@
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
#include <wlan_mlo_mgr_ap.h>
|
||||
#endif
|
||||
#include "wlan_vdev_mgr_ucfg_api.h"
|
||||
#include <wlan_objmgr_psoc_obj_i.h>
|
||||
#include <wlan_objmgr_vdev_obj_i.h>
|
||||
#include "osif_vdev_mgr_util.h"
|
||||
|
||||
#ifdef MODULE
|
||||
#define WLAN_MODULE_NAME module_name(THIS_MODULE)
|
||||
@ -1811,6 +1813,22 @@ void hdd_update_fw_tdls_11ax_capability(struct hdd_context *hdd_ctx,
|
||||
{}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
static inline void
|
||||
hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx,
|
||||
struct wma_tgt_services *cfg)
|
||||
{
|
||||
hdd_ctx->is_vdev_macaddr_dynamic_update_supported =
|
||||
cfg->dynamic_vdev_macaddr_support;
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
hdd_set_dynamic_macaddr_update_capability(struct hdd_context *hdd_ctx,
|
||||
struct wma_tgt_services *cfg)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
|
||||
struct wma_tgt_services *cfg)
|
||||
{
|
||||
@ -1898,6 +1916,7 @@ static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
|
||||
cfg_get(hdd_ctx->psoc,
|
||||
CFG_THERMAL_MITIGATION_ENABLE);
|
||||
hdd_update_fw_tdls_11ax_capability(hdd_ctx, cfg);
|
||||
hdd_set_dynamic_macaddr_update_capability(hdd_ctx, cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5236,6 +5255,184 @@ hdd_set_mld_address(struct hdd_adapter *adapter, struct hdd_context *hdd_ctx,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter,
|
||||
void *req_ctx)
|
||||
{
|
||||
adapter->set_mac_addr_req_ctx = req_ctx;
|
||||
if (adapter->mlo_adapter_info.associate_with_ml_adapter)
|
||||
adapter->mlo_adapter_info.ml_adapter->set_mac_addr_req_ctx =
|
||||
req_ctx;
|
||||
}
|
||||
#else
|
||||
static void hdd_update_set_mac_addr_req_ctx(struct hdd_adapter *adapter,
|
||||
void *req_ctx)
|
||||
{
|
||||
adapter->set_mac_addr_req_ctx = req_ctx;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hdd_is_dynamic_set_mac_addr_allowed() - API to check dynamic MAC address
|
||||
* update is allowed or not
|
||||
* @adapter: Pointer to the adapter structure
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
static bool hdd_is_dynamic_set_mac_addr_allowed(struct hdd_adapter *adapter)
|
||||
{
|
||||
if (!adapter->vdev) {
|
||||
hdd_err("VDEV is NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (adapter->device_mode) {
|
||||
case QDF_STA_MODE:
|
||||
if (!cm_is_vdev_disconnected(adapter->vdev)) {
|
||||
hdd_err("VDEV is not in disconnected state, set mac address isn't supported");
|
||||
return false;
|
||||
}
|
||||
case QDF_P2P_DEVICE_MODE:
|
||||
return true;
|
||||
default:
|
||||
hdd_err("Dynamic set mac address isn't supported for opmode:%d",
|
||||
adapter->device_mode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_is_dynamic_set_mac_addr_supported() - API to check dynamic MAC address
|
||||
* update is supported or not
|
||||
* @hdd_ctx: Pointer to the HDD context
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
static inline bool
|
||||
hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
return hdd_ctx->is_vdev_macaddr_dynamic_update_supported;
|
||||
}
|
||||
|
||||
int hdd_dynamic_mac_address_set(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter,
|
||||
struct qdf_mac_addr mac_addr)
|
||||
{
|
||||
uint32_t *fw_resp_status;
|
||||
void *cookie;
|
||||
struct osif_request *request;
|
||||
static const struct osif_request_params params = {
|
||||
.priv_size = sizeof(*fw_resp_status),
|
||||
.timeout_ms = WLAN_SET_MAC_ADDR_TIMEOUT
|
||||
};
|
||||
int ret;
|
||||
QDF_STATUS qdf_ret_status;
|
||||
struct qdf_mac_addr mld_addr;
|
||||
|
||||
qdf_ret_status = ucfg_vdev_mgr_cdp_vdev_detach(adapter->vdev);
|
||||
if (QDF_IS_STATUS_ERROR(qdf_ret_status)) {
|
||||
hdd_err("Failed to detach CDP vdev. Status:%d", qdf_ret_status);
|
||||
return qdf_status_to_os_return(qdf_ret_status);
|
||||
}
|
||||
|
||||
request = osif_request_alloc(¶ms);
|
||||
if (!request) {
|
||||
ret = -ENOMEM;
|
||||
goto status_ret;
|
||||
}
|
||||
|
||||
cookie = osif_request_cookie(request);
|
||||
hdd_update_set_mac_addr_req_ctx(adapter, cookie);
|
||||
|
||||
qdf_mem_copy(&mld_addr, adapter->mld_addr.bytes, sizeof(mld_addr));
|
||||
qdf_ret_status = sme_send_set_mac_addr(mac_addr, mld_addr,
|
||||
adapter->vdev);
|
||||
ret = qdf_status_to_os_return(qdf_ret_status);
|
||||
if (QDF_STATUS_SUCCESS != qdf_ret_status) {
|
||||
hdd_nofl_err("Failed to send set MAC address command. Status:%d",
|
||||
qdf_ret_status);
|
||||
osif_request_put(request);
|
||||
goto status_ret;
|
||||
} else {
|
||||
ret = osif_request_wait_for_response(request);
|
||||
if (ret) {
|
||||
hdd_err("Set MAC address response timed out");
|
||||
} else {
|
||||
fw_resp_status = (uint32_t *)osif_request_priv(request);
|
||||
if (*fw_resp_status) {
|
||||
hdd_err("Set MAC address failed in FW. Status: %d",
|
||||
*fw_resp_status);
|
||||
ret = -EAGAIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
osif_request_put(request);
|
||||
|
||||
qdf_ret_status = sme_update_vdev_mac_addr(
|
||||
hdd_ctx->psoc, mac_addr, adapter->vdev,
|
||||
hdd_adapter_is_associated_with_ml_adapter(adapter),
|
||||
ret);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(qdf_ret_status))
|
||||
ret = qdf_status_to_os_return(qdf_ret_status);
|
||||
|
||||
status_ret:
|
||||
qdf_ret_status = ucfg_vdev_mgr_cdp_vdev_attach(adapter->vdev);
|
||||
if (QDF_IS_STATUS_ERROR(qdf_ret_status)) {
|
||||
hdd_err("Failed to attach CDP vdev. status:%d", qdf_ret_status);
|
||||
return qdf_status_to_os_return(qdf_ret_status);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hdd_set_mac_addr_event_cb(uint8_t vdev_id, uint8_t status)
|
||||
{
|
||||
struct hdd_context *hdd_ctx;
|
||||
struct hdd_adapter *adapter;
|
||||
struct osif_request *req;
|
||||
uint32_t *fw_response_status;
|
||||
|
||||
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
|
||||
if (!hdd_ctx) {
|
||||
hdd_err("Invalid HDD context");
|
||||
return;
|
||||
}
|
||||
|
||||
adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
|
||||
if (!adapter) {
|
||||
hdd_err("No adapter found for VDEV ID:%d", vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
req = osif_request_get(adapter->set_mac_addr_req_ctx);
|
||||
if (!req) {
|
||||
osif_err("Obsolete request for VDEV ID:%d", vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
fw_response_status = (uint32_t *)osif_request_priv(req);
|
||||
*fw_response_status = status;
|
||||
|
||||
osif_request_complete(req);
|
||||
osif_request_put(req);
|
||||
}
|
||||
#else
|
||||
static inline bool
|
||||
hdd_is_dynamic_set_mac_addr_allowed(struct hdd_adapter *adapter)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
hdd_is_dynamic_set_mac_addr_supported(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* __hdd_set_mac_address() - set the user specified mac address
|
||||
* @dev: Pointer to the net device.
|
||||
@ -5255,19 +5452,25 @@ static int __hdd_set_mac_address(struct net_device *dev, void *addr)
|
||||
QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
|
||||
int ret;
|
||||
struct qdf_mac_addr mac_addr;
|
||||
bool net_if_running = netif_running(dev);
|
||||
|
||||
hdd_enter_dev(dev);
|
||||
|
||||
if (netif_running(dev)) {
|
||||
hdd_err("On iface up, set mac address change isn't supported");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||
ret = wlan_hdd_validate_context(hdd_ctx);
|
||||
if (0 != ret)
|
||||
return ret;
|
||||
|
||||
if (net_if_running) {
|
||||
if (hdd_is_dynamic_set_mac_addr_supported(hdd_ctx)) {
|
||||
if (!hdd_is_dynamic_set_mac_addr_allowed(adapter))
|
||||
return -ENOTSUPP;
|
||||
} else {
|
||||
hdd_err("On iface up, set mac address change isn't supported");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
|
||||
adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes);
|
||||
if (adapter_temp) {
|
||||
@ -5278,7 +5481,6 @@ static int __hdd_set_mac_address(struct net_device *dev, void *addr)
|
||||
QDF_MAC_ADDR_REF(mac_addr.bytes));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr);
|
||||
if (QDF_IS_STATUS_ERROR(qdf_ret_status))
|
||||
return -EINVAL;
|
||||
@ -5287,6 +5489,12 @@ static int __hdd_set_mac_address(struct net_device *dev, void *addr)
|
||||
QDF_MAC_ADDR_FMT " of the interface %s ",
|
||||
QDF_MAC_ADDR_REF(mac_addr.bytes), dev->name);
|
||||
|
||||
if (net_if_running && adapter->vdev) {
|
||||
ret = hdd_update_vdev_mac_address(hdd_ctx, adapter, mac_addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (hdd_adapter_is_ml_adapter(adapter))
|
||||
hdd_set_mld_address(adapter, hdd_ctx, &mac_addr);
|
||||
else
|
||||
@ -5296,7 +5504,7 @@ static int __hdd_set_mac_address(struct net_device *dev, void *addr)
|
||||
memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
|
||||
|
||||
hdd_exit();
|
||||
return qdf_ret_status;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -17017,6 +17225,23 @@ static void wlan_hdd_state_ctrl_param_destroy(void)
|
||||
|
||||
#endif /* WLAN_CTRL_NAME */
|
||||
|
||||
struct osif_vdev_mgr_ops osif_vdev_mgrlegacy_ops = {
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
.osif_vdev_mgr_set_mac_addr_response = hdd_set_mac_addr_event_cb
|
||||
#endif
|
||||
};
|
||||
|
||||
static QDF_STATUS hdd_vdev_mgr_register_cb(void)
|
||||
{
|
||||
osif_vdev_mgr_set_legacy_cb(&osif_vdev_mgrlegacy_ops);
|
||||
return osif_vdev_mgr_register_cb();
|
||||
}
|
||||
|
||||
static void hdd_vdev_mgr_unregister_cb(void)
|
||||
{
|
||||
osif_vdev_mgr_reset_legacy_cb();
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_component_cb_init() - Initialize component callbacks
|
||||
*
|
||||
@ -17028,7 +17253,17 @@ static void wlan_hdd_state_ctrl_param_destroy(void)
|
||||
*/
|
||||
static QDF_STATUS hdd_component_cb_init(void)
|
||||
{
|
||||
return hdd_cm_register_cb();
|
||||
QDF_STATUS status;
|
||||
|
||||
status = hdd_cm_register_cb();
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return status;
|
||||
|
||||
status = hdd_vdev_mgr_register_cb();
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return status;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -17041,7 +17276,9 @@ static QDF_STATUS hdd_component_cb_init(void)
|
||||
*/
|
||||
static void hdd_component_cb_deinit(void)
|
||||
{
|
||||
return hdd_cm_unregister_cb();
|
||||
hdd_cm_unregister_cb();
|
||||
|
||||
hdd_vdev_mgr_unregister_cb();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -326,4 +326,28 @@ struct hdd_adapter *hdd_get_ml_adater(struct hdd_context *hdd_ctx)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
int hdd_update_vdev_mac_address(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter,
|
||||
struct qdf_mac_addr mac_addr)
|
||||
{
|
||||
int i, ret = 0;
|
||||
struct hdd_mlo_adapter_info *mlo_adapter_info;
|
||||
struct hdd_adapter *link_adapter;
|
||||
|
||||
mlo_adapter_info = &adapter->mlo_adapter_info;
|
||||
|
||||
for (i = 0; i < WLAN_MAX_MLD; i++) {
|
||||
link_adapter = mlo_adapter_info->link_adapter[i];
|
||||
if (!link_adapter)
|
||||
continue;
|
||||
ret = hdd_dynamic_mac_address_set(hdd_ctx, link_adapter,
|
||||
mac_addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -821,7 +821,6 @@ struct mac_context {
|
||||
tDot11fIEeht_cap eht_cap_2g;
|
||||
tDot11fIEeht_cap eht_cap_5g;
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_CAL_FAILURE_TRIGGER
|
||||
void (*cal_failure_event_cb)(uint8_t cal_type, uint8_t reason);
|
||||
#endif
|
||||
|
@ -4498,4 +4498,40 @@ QDF_STATUS sme_switch_channel(mac_handle_t mac_handle,
|
||||
struct qdf_mac_addr *bssid,
|
||||
qdf_freq_t chan_freq,
|
||||
enum phy_ch_width chan_width);
|
||||
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
/**
|
||||
* sme_send_set_mac_addr() - Send set MAC address command to FW
|
||||
* @mac_addr: VDEV MAC address
|
||||
* @mld_addr: VDEV MLD address
|
||||
* @vdev: Pointer to object manager VDEV
|
||||
*
|
||||
* API to send set MAC address request command to FW
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS sme_send_set_mac_addr(struct qdf_mac_addr mac_addr,
|
||||
struct qdf_mac_addr mld_addr,
|
||||
struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* sme_update_vdev_mac_addr() - Update VDEV MAC address
|
||||
* @psoc: Pointer to PSOC structure
|
||||
* @mac_addr: VDEV MAC address
|
||||
* @vdev: Pointer to object manager VDEV
|
||||
* @update_sta_self_peer: Flag to check self peer MAC address or not.
|
||||
* @req_status: Status of the set MAC address request to the FW
|
||||
*
|
||||
* API to update MLME structures with new MAC address. This will be invoked
|
||||
* after receiving success status form the FW for the set MAC address request
|
||||
* command.
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS sme_update_vdev_mac_addr(struct wlan_objmgr_psoc *psoc,
|
||||
struct qdf_mac_addr mac_addr,
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
bool update_sta_self_peer, int req_status);
|
||||
#endif
|
||||
|
||||
#endif /* #if !defined( __SME_API_H ) */
|
||||
|
@ -16071,6 +16071,149 @@ QDF_STATUS sme_switch_channel(mac_handle_t mac_handle,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE
|
||||
static inline bool sme_is_11be_capable(void)
|
||||
{
|
||||
return sme_is_feature_supported_by_fw(DOT11BE);
|
||||
}
|
||||
#else
|
||||
static inline bool sme_is_11be_capable(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
QDF_STATUS sme_send_set_mac_addr(struct qdf_mac_addr mac_addr,
|
||||
struct qdf_mac_addr mld_addr,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
enum QDF_OPMODE vdev_opmode;
|
||||
struct qdf_mac_addr vdev_mac_addr = mac_addr;
|
||||
QDF_STATUS qdf_ret_status;
|
||||
struct vdev_mlme_obj *vdev_mlme;
|
||||
|
||||
if (!vdev) {
|
||||
sme_err("Invalid VDEV");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
vdev_opmode = wlan_vdev_mlme_get_opmode(vdev);
|
||||
|
||||
if (vdev_opmode == QDF_P2P_DEVICE_MODE) {
|
||||
qdf_ret_status = wma_p2p_self_peer_remove(vdev);
|
||||
if (QDF_IS_STATUS_ERROR(qdf_ret_status))
|
||||
return qdf_ret_status;
|
||||
}
|
||||
|
||||
if (sme_is_11be_capable() && (vdev_opmode == QDF_STA_MODE)) {
|
||||
/* Set new MAC addr as MLD address incase of MLO */
|
||||
mld_addr = mac_addr;
|
||||
qdf_mem_copy(&vdev_mac_addr, wlan_vdev_mlme_get_linkaddr(vdev),
|
||||
sizeof(struct qdf_mac_addr));
|
||||
}
|
||||
|
||||
qdf_ret_status = wlan_vdev_mlme_send_set_mac_addr(vdev_mac_addr,
|
||||
mld_addr, vdev);
|
||||
|
||||
if (QDF_IS_STATUS_SUCCESS(qdf_ret_status))
|
||||
return qdf_ret_status;
|
||||
|
||||
/**
|
||||
* Failed to send set MAC address command to FW. Create P2P self peer
|
||||
* again with old MAC address
|
||||
*/
|
||||
if (vdev_opmode == QDF_P2P_DEVICE_MODE) {
|
||||
vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
|
||||
if (!vdev_mlme) {
|
||||
sme_err("Invalid vdev MLME context");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
qdf_ret_status = wma_vdev_self_peer_create(vdev_mlme);
|
||||
if (QDF_IS_STATUS_ERROR(qdf_ret_status)) {
|
||||
sme_nofl_err("Failed to create self peer for P2P device mode. Status:%d",
|
||||
qdf_ret_status);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
QDF_STATUS sme_update_vdev_mac_addr(struct wlan_objmgr_psoc *psoc,
|
||||
struct qdf_mac_addr mac_addr,
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
bool update_sta_self_peer, int req_status)
|
||||
{
|
||||
enum QDF_OPMODE vdev_opmode;
|
||||
uint8_t *old_mac_addr_bytes;
|
||||
QDF_STATUS qdf_ret_status;
|
||||
struct wlan_objmgr_peer *peer;
|
||||
struct vdev_mlme_obj *vdev_mlme;
|
||||
|
||||
if (!vdev) {
|
||||
sme_err("Invalid VDEV");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
vdev_opmode = wlan_vdev_mlme_get_opmode(vdev);
|
||||
|
||||
if (req_status)
|
||||
goto p2p_self_peer_create;
|
||||
|
||||
if ((vdev_opmode == QDF_STA_MODE) && update_sta_self_peer) {
|
||||
if (sme_is_11be_capable())
|
||||
old_mac_addr_bytes = wlan_vdev_mlme_get_mldaddr(vdev);
|
||||
else
|
||||
old_mac_addr_bytes = wlan_vdev_mlme_get_macaddr(vdev);
|
||||
|
||||
/* Update self peer MAC address */
|
||||
peer = wlan_objmgr_get_peer_by_mac(psoc, old_mac_addr_bytes,
|
||||
WLAN_MLME_NB_ID);
|
||||
if (peer) {
|
||||
qdf_ret_status = wlan_peer_update_macaddr(
|
||||
peer, mac_addr.bytes);
|
||||
wlan_objmgr_peer_release_ref(peer, WLAN_MLME_NB_ID);
|
||||
if (QDF_IS_STATUS_ERROR(qdf_ret_status)) {
|
||||
sme_nofl_err("Failed to update self peer MAC address. Status:%d",
|
||||
qdf_ret_status);
|
||||
return qdf_ret_status;
|
||||
}
|
||||
} else {
|
||||
sme_err("Self peer not found with MAC addr:"
|
||||
QDF_MAC_ADDR_FMT,
|
||||
QDF_MAC_ADDR_REF(old_mac_addr_bytes));
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update VDEV MAC address */
|
||||
if ((vdev_opmode == QDF_STA_MODE) && sme_is_11be_capable())
|
||||
wlan_vdev_mlme_set_mldaddr(vdev, mac_addr.bytes);
|
||||
else
|
||||
wlan_vdev_mlme_set_macaddr(vdev, mac_addr.bytes);
|
||||
|
||||
p2p_self_peer_create:
|
||||
if (vdev_opmode == QDF_P2P_DEVICE_MODE) {
|
||||
vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
|
||||
if (!vdev_mlme) {
|
||||
sme_err("Invalid vdev MLME context");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
qdf_ret_status = wma_vdev_self_peer_create(vdev_mlme);
|
||||
if (QDF_IS_STATUS_ERROR(qdf_ret_status)) {
|
||||
sme_nofl_err("Failed to create self peer for P2P device mode. Status:%d",
|
||||
qdf_ret_status);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
|
||||
void sme_roam_events_register_callback(mac_handle_t mac_handle,
|
||||
void (*roam_rt_stats_cb)(
|
||||
|
@ -2564,5 +2564,16 @@ QDF_STATUS wma_send_ani_level_request(tp_wma_handle wma_handle,
|
||||
* Return: QDF status
|
||||
*/
|
||||
QDF_STATUS wma_vdev_detach(struct del_vdev_params *pdel_vdev_req_param);
|
||||
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
/**
|
||||
* wma_p2p_self_peer_remove() - Send P2P self peer delete command to FW
|
||||
* @vdev: Object manager vdev
|
||||
*
|
||||
* Return: success if peer delete command sent to firmware, else failure.
|
||||
*/
|
||||
|
||||
QDF_STATUS wma_p2p_self_peer_remove(struct wlan_objmgr_vdev *vdev);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021 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
|
||||
@ -51,6 +52,8 @@
|
||||
* @is_fw_therm_throt_supp: Get thermal throttling threshold
|
||||
* @igmp_offload_enable: Get igmp offload enable or disable
|
||||
* @en_11be: enable 11be
|
||||
* @dynamic_vdev_macaddr_support: Dynamic update of vdev MAC addr is
|
||||
* supported or not
|
||||
*/
|
||||
struct wma_tgt_services {
|
||||
uint32_t sta_power_save;
|
||||
@ -96,6 +99,9 @@ struct wma_tgt_services {
|
||||
bool igmp_offload_enable;
|
||||
#endif
|
||||
bool en_11be;
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
bool dynamic_vdev_macaddr_support;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -576,6 +576,32 @@ error:
|
||||
return qdf_status;
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
QDF_STATUS wma_p2p_self_peer_remove(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct del_vdev_params *del_self_peer_req;
|
||||
tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!wma_handle)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
del_self_peer_req = qdf_mem_malloc(sizeof(*del_self_peer_req));
|
||||
if (!del_self_peer_req)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
del_self_peer_req->vdev = vdev;
|
||||
del_self_peer_req->vdev_id = wlan_vdev_get_id(vdev);
|
||||
qdf_mem_copy(del_self_peer_req->self_mac_addr,
|
||||
wlan_vdev_mlme_get_macaddr(vdev),
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
|
||||
status = wma_self_peer_remove(wma_handle, del_self_peer_req);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wma_remove_objmgr_peer() - remove objmgr peer information from host driver
|
||||
* @wma: wma handle
|
||||
|
@ -4688,6 +4688,22 @@ wma_get_tdls_ax_support(struct wmi_unified *wmi_handle,
|
||||
{}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
|
||||
static inline void wma_get_dynamic_vdev_macaddr_support(
|
||||
struct wmi_unified *wmi_handle, struct wma_tgt_services *cfg)
|
||||
{
|
||||
cfg->dynamic_vdev_macaddr_support =
|
||||
wmi_service_enabled(
|
||||
wmi_handle,
|
||||
wmi_service_dynamic_update_vdev_macaddr_support);
|
||||
}
|
||||
#else
|
||||
static inline void wma_get_dynamic_vdev_macaddr_support(
|
||||
struct wmi_unified *wmi_handle, struct wma_tgt_services *cfg)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wma_update_target_services() - update target services from wma handle
|
||||
* @wmi_handle: Unified wmi handle
|
||||
@ -4831,6 +4847,8 @@ static inline void wma_update_target_services(struct wmi_unified *wmi_handle,
|
||||
|
||||
wma_get_igmp_offload_enable(wmi_handle, cfg);
|
||||
wma_get_tdls_ax_support(wmi_handle, cfg);
|
||||
|
||||
wma_get_dynamic_vdev_macaddr_support(wmi_handle, cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user