mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 07:37:31 -04:00
qcacld-3.0: Add vendor attribute to configure ARP/NS offload
In some scenario, it is required to receive every ARP/NS packet even it is not to solicit address itself. So add this vendor attribute configuration to enable/disable ARP/NS offload on fly. On some platform, if target suspend to WoW mode, APF filter will drop such ARP/NS packet in the front, so prevent runtime suspend happen if disable ARP/NS offload. System suspend still allow in consideration of potential power impact. It only support on STA/P2P-Client mode device, and this configure is optional, while default behavior is ARP/NS offload enable. It will restore to default behavior if interface being closed. Change-Id: Icd49e230024bc1ce51519cd9fafee9bc9f79f382 CRs-Fixed: 2974176
This commit is contained in:
parent
74058400d1
commit
77e345df5b
11 changed files with 378 additions and 11 deletions
1
Kbuild
1
Kbuild
|
|
@ -2620,6 +2620,7 @@ cppflags-$(CONFIG_FEATURE_WLAN_SCAN_PNO) += -DFEATURE_WLAN_SCAN_PNO
|
|||
cppflags-$(CONFIG_WLAN_FEATURE_PACKET_FILTERING) += -DWLAN_FEATURE_PACKET_FILTERING
|
||||
cppflags-$(CONFIG_DHCP_SERVER_OFFLOAD) += -DDHCP_SERVER_OFFLOAD
|
||||
cppflags-$(CONFIG_WLAN_NS_OFFLOAD) += -DWLAN_NS_OFFLOAD
|
||||
cppflags-$(CONFIG_WLAN_DYNAMIC_ARP_NS_OFFLOAD) += -DFEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
|
||||
cppflags-$(CONFIG_FEATURE_WLAN_RA_FILTERING) += -DFEATURE_WLAN_RA_FILTERING
|
||||
cppflags-$(CONFIG_FEATURE_WLAN_LPHB) += -DFEATURE_WLAN_LPHB
|
||||
cppflags-$(CONFIG_QCA_SUPPORT_TX_THROTTLE) += -DQCA_SUPPORT_TX_THROTTLE
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-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
|
||||
|
|
@ -110,6 +111,9 @@ struct wlan_pmo_ctx {
|
|||
* @dyn_listen_interval: dynamically user configured listen interval
|
||||
* @restore_dtim_setting: DTIM settings restore flag
|
||||
* @pmo_vdev_lock: spin lock for pmo vdev priv ctx
|
||||
* @dyn_arp_ns_offload_disable: true when arp/ns offload is disable
|
||||
* @dyn_arp_ns_offload_rt_lock: wake lock which prevent runtime pm happen if
|
||||
* arp/ns offload is disable
|
||||
*/
|
||||
struct pmo_vdev_priv_obj {
|
||||
struct pmo_psoc_priv_obj *pmo_psoc_ctx;
|
||||
|
|
@ -132,6 +136,10 @@ struct pmo_vdev_priv_obj {
|
|||
uint32_t dyn_listen_interval;
|
||||
bool restore_dtim_setting;
|
||||
qdf_spinlock_t pmo_vdev_lock;
|
||||
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
|
||||
bool dyn_arp_ns_offload_disable;
|
||||
qdf_runtime_lock_t dyn_arp_ns_offload_rt_lock;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
|
||||
|
|
|
|||
|
|
@ -180,6 +180,112 @@ bool pmo_core_vdev_get_restore_dtim(struct wlan_objmgr_vdev *vdev)
|
|||
return value;
|
||||
}
|
||||
|
||||
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
|
||||
/**
|
||||
* pmo_core_dynamic_arp_ns_offload_enable() - Enable vdev arp/ns offload
|
||||
* @vdev: objmgr vdev handle
|
||||
*
|
||||
* Return: QDF_STATUS_E_ALREADY if arp/ns offload already enable
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
pmo_core_dynamic_arp_ns_offload_enable(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
bool value;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
struct pmo_vdev_priv_obj *vdev_ctx;
|
||||
|
||||
vdev_ctx = pmo_vdev_get_priv(vdev);
|
||||
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
value = vdev_ctx->dyn_arp_ns_offload_disable;
|
||||
if (!value)
|
||||
status = QDF_STATUS_E_ALREADY;
|
||||
else
|
||||
vdev_ctx->dyn_arp_ns_offload_disable = false;
|
||||
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pmo_core_dynamic_arp_ns_offload_disable() - Disable vdev arp/ns offload
|
||||
* @vdev: objmgr vdev handle
|
||||
*
|
||||
* Return: QDF_STATUS_E_ALREADY if arp/ns offload already disable
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
pmo_core_dynamic_arp_ns_offload_disable(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
bool value;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
struct pmo_vdev_priv_obj *vdev_ctx;
|
||||
|
||||
vdev_ctx = pmo_vdev_get_priv(vdev);
|
||||
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
value = vdev_ctx->dyn_arp_ns_offload_disable;
|
||||
if (value)
|
||||
status = QDF_STATUS_E_ALREADY;
|
||||
else
|
||||
vdev_ctx->dyn_arp_ns_offload_disable = true;
|
||||
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pmo_core_get_dynamic_arp_ns_offload_disable() - Get arp/ns offload state
|
||||
* @vdev: objmgr vdev handle
|
||||
*
|
||||
* Return: true if vdev arp/ns offload is disable
|
||||
*/
|
||||
static inline bool
|
||||
pmo_core_get_dynamic_arp_ns_offload_disable(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
bool value;
|
||||
struct pmo_vdev_priv_obj *vdev_ctx;
|
||||
|
||||
vdev_ctx = pmo_vdev_get_priv(vdev);
|
||||
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
value = vdev_ctx->dyn_arp_ns_offload_disable;
|
||||
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* pmo_core_dynamic_arp_ns_offload_runtime_prevent() - Prevent runtime suspend
|
||||
* @vdev: objmgr vdev handle
|
||||
*
|
||||
* API to prevent runtime suspend happen when arp/ns offload is disable
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void
|
||||
pmo_core_dynamic_arp_ns_offload_runtime_prevent(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct pmo_vdev_priv_obj *vdev_ctx;
|
||||
|
||||
vdev_ctx = pmo_vdev_get_priv(vdev);
|
||||
qdf_runtime_pm_prevent_suspend(&vdev_ctx->dyn_arp_ns_offload_rt_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* pmo_core_dynamic_arp_ns_offload_runtime_allow() - Allow runtime suspend
|
||||
* @vdev: objmgr vdev handle
|
||||
*
|
||||
* API to allow runtime suspend happen when arp/ns offload is enable
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void
|
||||
pmo_core_dynamic_arp_ns_offload_runtime_allow(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct pmo_vdev_priv_obj *vdev_ctx;
|
||||
|
||||
vdev_ctx = pmo_vdev_get_priv(vdev);
|
||||
qdf_runtime_pm_allow_suspend(&vdev_ctx->dyn_arp_ns_offload_rt_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* pmo_core_update_power_save_mode() - update power save mode
|
||||
* @vdev: objmgr vdev handle
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-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
|
||||
|
|
@ -129,6 +129,7 @@ pmo_core_do_enable_arp_offload(struct wlan_objmgr_vdev *vdev,
|
|||
status = pmo_tgt_enable_arp_offload_req(vdev, vdev_id);
|
||||
break;
|
||||
case pmo_apps_suspend:
|
||||
case pmo_arp_ns_offload_dynamic_update:
|
||||
/* enable arp when active offload is false (apps suspend) */
|
||||
status = pmo_tgt_enable_arp_offload_req(vdev, vdev_id);
|
||||
break;
|
||||
|
|
@ -162,6 +163,7 @@ static QDF_STATUS pmo_core_do_disable_arp_offload(struct wlan_objmgr_vdev *vdev,
|
|||
|
||||
switch (trigger) {
|
||||
case pmo_apps_resume:
|
||||
case pmo_arp_ns_offload_dynamic_update:
|
||||
/* disable arp on apps resume when active offload is disable */
|
||||
status = pmo_tgt_disable_arp_offload_req(vdev, vdev_id);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-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
|
||||
|
|
@ -166,6 +166,7 @@ static QDF_STATUS pmo_core_do_enable_ns_offload(struct wlan_objmgr_vdev *vdev,
|
|||
status = pmo_tgt_enable_ns_offload_req(vdev, vdev_id);
|
||||
break;
|
||||
case pmo_apps_suspend:
|
||||
case pmo_arp_ns_offload_dynamic_update:
|
||||
/* enable arp when active offload is false (apps suspend) */
|
||||
status = pmo_tgt_enable_ns_offload_req(vdev, vdev_id);
|
||||
break;
|
||||
|
|
@ -201,6 +202,7 @@ static QDF_STATUS pmo_core_do_disable_ns_offload(struct wlan_objmgr_vdev *vdev,
|
|||
status = pmo_tgt_disable_ns_offload_req(vdev, vdev_id);
|
||||
break;
|
||||
case pmo_apps_resume:
|
||||
case pmo_arp_ns_offload_dynamic_update:
|
||||
status = pmo_tgt_disable_ns_offload_req(vdev, vdev_id);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2021 The Linux Foundation. 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
|
||||
|
|
@ -205,6 +206,7 @@ typedef QDF_STATUS(*pmo_psoc_resume_handler)
|
|||
* @pmo_ns_offload_dynamic_update: enable/disable ns offload on the fly
|
||||
* @pmo_peer_disconnect: trigger is peer disconnect
|
||||
* @pmo_mcbc_setting_dynamic_update: mcbc value update on the fly
|
||||
* @pmo_arp_ns_offload_dynamic_update: enable/disable arp/ns offload on the fly
|
||||
*
|
||||
* @pmo_offload_trigger_max: Max trigger value
|
||||
*/
|
||||
|
|
@ -219,6 +221,7 @@ enum pmo_offload_trigger {
|
|||
pmo_ns_offload_dynamic_update,
|
||||
pmo_peer_disconnect,
|
||||
pmo_mcbc_setting_dynamic_update,
|
||||
pmo_arp_ns_offload_dynamic_update,
|
||||
|
||||
pmo_offload_trigger_max,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -545,6 +545,79 @@ ucfg_pmo_enhanced_mc_filter_disable(struct wlan_objmgr_vdev *vdev)
|
|||
return pmo_core_enhanced_mc_filter_disable(vdev);
|
||||
}
|
||||
|
||||
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
|
||||
/**
|
||||
* ucfg_pmo_dynamic_arp_ns_offload_enable() - enable arp/ns offload
|
||||
* @vdev: vdev objmgr handle
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS
|
||||
ucfg_pmo_dynamic_arp_ns_offload_enable(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* ucfg_pmo_dynamic_arp_ns_offload_disable() - disable arp/ns offload
|
||||
* @vdev: vdev objmgr handle
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS
|
||||
ucfg_pmo_dynamic_arp_ns_offload_disable(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* ucfg_pmo_get_arp_ns_offload_dynamic_disable() - get arp/ns offload state
|
||||
* @vdev: vdev objmgr handle
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
bool
|
||||
ucfg_pmo_get_arp_ns_offload_dynamic_disable(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* ucfg_pmo_dynamic_arp_ns_offload_runtime_prevent() - prevent runtime suspend
|
||||
* @vdev: vdev objmgr handle
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void
|
||||
ucfg_pmo_dynamic_arp_ns_offload_runtime_prevent(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* ucfg_pmo_dynamic_arp_ns_offload_runtime_allow() - allow runtime suspend
|
||||
* @vdev: vdev objmgr handle
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void
|
||||
ucfg_pmo_dynamic_arp_ns_offload_runtime_allow(struct wlan_objmgr_vdev *vdev);
|
||||
#else
|
||||
static inline QDF_STATUS
|
||||
ucfg_pmo_dynamic_arp_ns_offload_enable(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
ucfg_pmo_dynamic_arp_ns_offload_disable(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ucfg_pmo_get_arp_ns_offload_dynamic_disable(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ucfg_pmo_dynamic_arp_ns_offload_runtime_prevent(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
ucfg_pmo_dynamic_arp_ns_offload_runtime_allow(struct wlan_objmgr_vdev *vdev) {}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ucfg_pmo_enable_mc_addr_filtering_in_fwr(): Enable cached mc add list in fwr
|
||||
* @psoc: objmgr psoc handle
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 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
|
||||
|
|
@ -227,6 +228,26 @@ out:
|
|||
return status;
|
||||
}
|
||||
|
||||
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
|
||||
static inline void
|
||||
pmo_vdev_dynamic_arp_ns_offload_init(struct pmo_vdev_priv_obj *vdev_ctx)
|
||||
{
|
||||
qdf_runtime_lock_init(&vdev_ctx->dyn_arp_ns_offload_rt_lock);
|
||||
}
|
||||
|
||||
static inline void
|
||||
pmo_vdev_dynamic_arp_ns_offload_deinit(struct pmo_vdev_priv_obj *vdev_ctx)
|
||||
{
|
||||
qdf_runtime_lock_deinit(&vdev_ctx->dyn_arp_ns_offload_rt_lock);
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
pmo_vdev_dynamic_arp_ns_offload_init(struct pmo_vdev_priv_obj *vdev_ctx) {}
|
||||
|
||||
static inline void
|
||||
pmo_vdev_dynamic_arp_ns_offload_deinit(struct pmo_vdev_priv_obj *vdev_ctx) {}
|
||||
#endif
|
||||
|
||||
QDF_STATUS pmo_vdev_object_created_notification(
|
||||
struct wlan_objmgr_vdev *vdev, void *arg)
|
||||
{
|
||||
|
|
@ -261,6 +282,7 @@ QDF_STATUS pmo_vdev_object_created_notification(
|
|||
psoc_ctx->psoc_cfg.ptrn_match_enable_all_vdev;
|
||||
vdev_ctx->pmo_psoc_ctx = psoc_ctx;
|
||||
qdf_atomic_init(&vdev_ctx->gtk_err_enable);
|
||||
pmo_vdev_dynamic_arp_ns_offload_init(vdev_ctx);
|
||||
|
||||
out:
|
||||
pmo_exit();
|
||||
|
|
@ -306,6 +328,7 @@ QDF_STATUS pmo_vdev_object_destroyed_notification(
|
|||
pmo_err("Failed to detach vdev_ctx with vdev");
|
||||
|
||||
qdf_spinlock_destroy(&vdev_ctx->pmo_vdev_lock);
|
||||
pmo_vdev_dynamic_arp_ns_offload_deinit(vdev_ctx);
|
||||
qdf_mem_free(vdev_ctx);
|
||||
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -195,6 +195,38 @@ ucfg_pmo_disable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
|
|||
}
|
||||
#endif /* WLAN_NS_OFFLOAD */
|
||||
|
||||
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
|
||||
QDF_STATUS
|
||||
ucfg_pmo_dynamic_arp_ns_offload_enable(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return pmo_core_dynamic_arp_ns_offload_enable(vdev);
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
ucfg_pmo_dynamic_arp_ns_offload_disable(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return pmo_core_dynamic_arp_ns_offload_disable(vdev);
|
||||
}
|
||||
|
||||
bool
|
||||
ucfg_pmo_get_arp_ns_offload_dynamic_disable(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return pmo_core_get_dynamic_arp_ns_offload_disable(vdev);
|
||||
}
|
||||
|
||||
void
|
||||
ucfg_pmo_dynamic_arp_ns_offload_runtime_prevent(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return pmo_core_dynamic_arp_ns_offload_runtime_prevent(vdev);
|
||||
}
|
||||
|
||||
void
|
||||
ucfg_pmo_dynamic_arp_ns_offload_runtime_allow(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return pmo_core_dynamic_arp_ns_offload_runtime_allow(vdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
QDF_STATUS
|
||||
ucfg_pmo_get_ns_offload_params(struct wlan_objmgr_vdev *vdev,
|
||||
struct pmo_ns_offload_params *params)
|
||||
|
|
|
|||
|
|
@ -7242,6 +7242,7 @@ const struct nla_policy wlan_hdd_wifi_config_policy[
|
|||
[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS] = {.type = NLA_U8 },
|
||||
[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS] = {.type = NLA_U8 },
|
||||
[QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS] = {.type = NLA_U8 },
|
||||
[QCA_WLAN_VENDOR_ATTR_CONFIG_ARP_NS_OFFLOAD] = {.type = NLA_U8 },
|
||||
[QCA_WLAN_VENDOR_ATTR_CONFIG_WFC_STATE] = {
|
||||
.type = NLA_U8 },
|
||||
};
|
||||
|
|
@ -9024,6 +9025,103 @@ static int hdd_set_nss(struct hdd_adapter *adapter,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
|
||||
#define DYNAMIC_ARP_NS_ENABLE 1
|
||||
#define DYNAMIC_ARP_NS_DISABLE 0
|
||||
|
||||
/**
|
||||
* hdd_set_arp_ns_offload() - enable/disable arp/ns offload feature
|
||||
* @adapter: hdd adapter
|
||||
* @attr: pointer to nla attr
|
||||
*
|
||||
* Return: 0 on success, negative errno on failure
|
||||
*/
|
||||
static int hdd_set_arp_ns_offload(struct hdd_adapter *adapter,
|
||||
const struct nlattr *attr)
|
||||
{
|
||||
uint8_t offload_state;
|
||||
int errno;
|
||||
QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
|
||||
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
|
||||
errno = wlan_hdd_validate_context(hdd_ctx);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
if (!ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc) ||
|
||||
!ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc)) {
|
||||
hdd_err_rl("ARP/NS Offload is disabled by ini");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!ucfg_pmo_is_active_mode_offloaded(hdd_ctx->psoc)) {
|
||||
hdd_err_rl("active mode offload is disabled by ini");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (adapter->device_mode != QDF_STA_MODE &&
|
||||
adapter->device_mode != QDF_P2P_CLIENT_MODE) {
|
||||
hdd_err_rl("only support on sta/p2p-cli mode");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vdev = hdd_objmgr_get_vdev(adapter);
|
||||
if (!vdev) {
|
||||
hdd_err("vdev is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
offload_state = nla_get_u8(attr);
|
||||
|
||||
if (offload_state == DYNAMIC_ARP_NS_ENABLE)
|
||||
qdf_status = ucfg_pmo_dynamic_arp_ns_offload_enable(vdev);
|
||||
else if (offload_state == DYNAMIC_ARP_NS_DISABLE)
|
||||
qdf_status = ucfg_pmo_dynamic_arp_ns_offload_disable(vdev);
|
||||
|
||||
if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
|
||||
if (offload_state == DYNAMIC_ARP_NS_ENABLE)
|
||||
ucfg_pmo_dynamic_arp_ns_offload_runtime_allow(vdev);
|
||||
else
|
||||
ucfg_pmo_dynamic_arp_ns_offload_runtime_prevent(vdev);
|
||||
}
|
||||
|
||||
hdd_objmgr_put_vdev(vdev);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(qdf_status)) {
|
||||
if (qdf_status == QDF_STATUS_E_ALREADY) {
|
||||
hdd_info_rl("already set arp/ns offload %d",
|
||||
offload_state);
|
||||
return 0;
|
||||
}
|
||||
return qdf_status_to_os_return(qdf_status);
|
||||
}
|
||||
|
||||
if (!hdd_is_vdev_in_conn_state(adapter)) {
|
||||
hdd_info("set not in connect state, updated state %d",
|
||||
offload_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (offload_state == DYNAMIC_ARP_NS_ENABLE) {
|
||||
hdd_enable_arp_offload(adapter,
|
||||
pmo_arp_ns_offload_dynamic_update);
|
||||
hdd_enable_ns_offload(adapter,
|
||||
pmo_arp_ns_offload_dynamic_update);
|
||||
} else if (offload_state == DYNAMIC_ARP_NS_DISABLE) {
|
||||
hdd_disable_arp_offload(adapter,
|
||||
pmo_arp_ns_offload_dynamic_update);
|
||||
hdd_disable_ns_offload(adapter,
|
||||
pmo_arp_ns_offload_dynamic_update);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef DYNAMIC_ARP_NS_ENABLE
|
||||
#undef DYNAMIC_ARP_NS_DISABLE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hdd_set_wfc_state() - Set wfc state
|
||||
* @adapter: hdd adapter
|
||||
|
|
@ -9168,6 +9266,10 @@ static const struct independent_setters independent_setters[] = {
|
|||
hdd_config_udp_qos_upgrade_threshold},
|
||||
{QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS,
|
||||
hdd_set_ft_over_ds},
|
||||
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
|
||||
{QCA_WLAN_VENDOR_ATTR_CONFIG_ARP_NS_OFFLOAD,
|
||||
hdd_set_arp_ns_offload},
|
||||
#endif
|
||||
{QCA_WLAN_VENDOR_ATTR_CONFIG_WFC_STATE,
|
||||
hdd_set_wfc_state},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -572,11 +572,23 @@ void hdd_enable_ns_offload(struct hdd_adapter *adapter,
|
|||
ns_req->trigger = trigger;
|
||||
ns_req->count = 0;
|
||||
|
||||
vdev = hdd_objmgr_get_vdev(adapter);
|
||||
if (!vdev) {
|
||||
hdd_err("vdev is NULL");
|
||||
goto free_req;
|
||||
}
|
||||
|
||||
/* check if offload cache and send is required or not */
|
||||
status = ucfg_pmo_ns_offload_check(psoc, trigger, adapter->vdev_id);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
hdd_debug("NS offload is not required");
|
||||
goto free_req;
|
||||
goto put_vdev;
|
||||
}
|
||||
|
||||
if (ucfg_pmo_get_arp_ns_offload_dynamic_disable(vdev)) {
|
||||
hdd_debug("Dynamic arp ns offload disabled");
|
||||
ucfg_pmo_flush_ns_offload_req(vdev);
|
||||
goto skip_cache_ns;
|
||||
}
|
||||
|
||||
/* Unicast Addresses */
|
||||
|
|
@ -586,7 +598,7 @@ void hdd_enable_ns_offload(struct hdd_adapter *adapter,
|
|||
if (errno) {
|
||||
hdd_disable_ns_offload(adapter, trigger);
|
||||
hdd_debug("Max supported addresses: disabling NS offload");
|
||||
goto free_req;
|
||||
goto put_vdev;
|
||||
}
|
||||
|
||||
/* Anycast Addresses */
|
||||
|
|
@ -596,21 +608,17 @@ void hdd_enable_ns_offload(struct hdd_adapter *adapter,
|
|||
if (errno) {
|
||||
hdd_disable_ns_offload(adapter, trigger);
|
||||
hdd_debug("Max supported addresses: disabling NS offload");
|
||||
goto free_req;
|
||||
goto put_vdev;
|
||||
}
|
||||
|
||||
/* cache ns request */
|
||||
status = ucfg_pmo_cache_ns_offload_req(ns_req);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
hdd_debug("Failed to cache ns request; status:%d", status);
|
||||
goto free_req;
|
||||
goto put_vdev;
|
||||
}
|
||||
|
||||
vdev = hdd_objmgr_get_vdev(adapter);
|
||||
if (!vdev) {
|
||||
hdd_err("vdev is NULL");
|
||||
goto free_req;
|
||||
}
|
||||
skip_cache_ns:
|
||||
/* enable ns request */
|
||||
status = ucfg_pmo_enable_ns_offload_in_fwr(vdev, trigger);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
|
|
@ -1284,6 +1292,12 @@ void hdd_enable_arp_offload(struct hdd_adapter *adapter,
|
|||
goto put_vdev;
|
||||
}
|
||||
|
||||
if (ucfg_pmo_get_arp_ns_offload_dynamic_disable(vdev)) {
|
||||
hdd_debug("Dynamic arp ns offload disabled");
|
||||
ucfg_pmo_flush_arp_offload_req(vdev);
|
||||
goto skip_cache_arp;
|
||||
}
|
||||
|
||||
ifa = hdd_get_ipv4_local_interface(adapter);
|
||||
if (!ifa || !ifa->ifa_local) {
|
||||
hdd_info("IP Address is not assigned");
|
||||
|
|
@ -1299,6 +1313,7 @@ void hdd_enable_arp_offload(struct hdd_adapter *adapter,
|
|||
goto put_vdev;
|
||||
}
|
||||
|
||||
skip_cache_arp:
|
||||
status = ucfg_pmo_enable_arp_offload_in_fwr(vdev, trigger);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
hdd_err("failed arp offload config in fw; status:%d", status);
|
||||
|
|
|
|||
Loading…
Reference in a new issue