qcacld-3.0: Add support for arp/ns offload in PMO component

Add support for arp/ns offload in PMO component

Change-Id: I823ba0a426cce5a5717cf2b693b49c8f8a2f7a29
CRs-Fixed: 2002639
This commit is contained in:
Mukul Sharma 2017-01-12 21:59:41 +05:30 • committed by qcabuildsw
commit 3ba26b8747
8 changed files with 272 additions and 413 deletions

View file

@ -147,9 +147,57 @@ enum suspend_resume_state {
QDF_STATUS hdd_wlan_shutdown(void);
QDF_STATUS hdd_wlan_re_init(void);
QDF_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, bool fenable);
void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, bool fenable);
/**
* hdd_enable_arp_offload() - API to enable ARP offload
* @adapter: Adapter context for which ARP offload is to be configured
* @trigger: trigger reason for request
*
* Return: None
*/
void hdd_enable_arp_offload(hdd_adapter_t *adapter,
enum pmo_offload_trigger trigger);
/**
* hdd_disable_arp_offload() - API to disable ARP offload
* @adapter: Adapter context for which ARP offload is to be configured
* @trigger: trigger reason for request
*
* Return: None
*/
void hdd_disable_arp_offload(hdd_adapter_t *adapter,
enum pmo_offload_trigger trigger);
/**
* hdd_enable_host_offloads() - Central API to enable the supported offloads
* @adapter: pointer to the adapter
* @trigger: trigger reason for request
*
* Central function to enable the supported offloads
*
* Return: nothing
*/
void hdd_enable_host_offloads(hdd_adapter_t *adapter,
enum pmo_offload_trigger trigger);
/**
* hdd_disable_host_offloads() - Central API to disable the supported offloads
* @adapter: pointer to the adapter
* @trigger: trigger reason for request
*
* Central function to disable the supported offloads
*
* Return: nothing
*/
void hdd_disable_host_offloads(hdd_adapter_t *adapter,
enum pmo_offload_trigger trigger);
/**
* hdd_conf_mc_addr_filtering_enable() - enable MC address list in FW
* @pAdapter: adapter whose MC list is being set
* @trigger: trigger reason for request
*
* Return: nothing
*/
#ifdef WLAN_FEATURE_PACKET_FILTERING
void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, uint8_t set);
#else
@ -165,10 +213,28 @@ int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy);
void hdd_ipv4_notifier_work_queue(struct work_struct *work);
#ifdef WLAN_NS_OFFLOAD
void hdd_conf_ns_offload(hdd_adapter_t *adapter, bool fenable);
/**
* hdd_enable_ns_offload() - enable NS offload
* @adapter: pointer to the adapter
*
* Return: nothing
*/
void hdd_enable_ns_offload(hdd_adapter_t *adapter,
enum pmo_offload_trigger trigger);
/**
* hdd_disable_ns_offload() - disable NS offload
* @adapter: pointer to the adapter
*
* Return: nothing
*/
void hdd_disable_ns_offload(hdd_adapter_t *adapter,
enum pmo_offload_trigger trigger);
void hdd_ipv6_notifier_work_queue(struct work_struct *work);
#endif
int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
struct wireless_dev *wdev,

View file

@ -5720,7 +5720,10 @@ __wlan_hdd_cfg80211_set_ns_offload(struct wiphy *wiphy,
nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG]);
/* update ns offload in case it is already enabled/disabled */
hdd_conf_ns_offload(adapter, pHddCtx->ns_offload_enable);
if (pHddCtx->ns_offload_enable)
hdd_enable_ns_offload(adapter, pmo_ns_offload_dynamic_update);
else
hdd_disable_ns_offload(adapter, pmo_ns_offload_dynamic_update);
return 0;
}

View file

@ -80,6 +80,7 @@
#include <wlan_logging_sock_svc.h>
#include "scheduler_api.h"
#include "cds_utils.h"
#include "wlan_pmo_ucfg_api.h"
/* Preprocessor definitions and constants */
#define HDD_SSR_BRING_UP_TIME 30000
@ -215,7 +216,7 @@ static void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, bool fenable)
}
#endif /*WLAN_FEATURE_GTK_OFFLOAD */
#ifdef WLAN_NS_OFFLOAD
/**
* __wlan_hdd_ipv6_changed() - IPv6 notifier callback function
* @nb: notifier block that was registered with the kernel
@ -312,7 +313,7 @@ static int hdd_fill_ipv6_uc_addr(struct inet6_dev *idev,
read_lock_bh(&idev->lock);
list_for_each(p, &idev->addr_list) {
if (*count >= SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) {
if (*count >= PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) {
read_unlock_bh(&idev->lock);
return -EINVAL;
}
@ -325,7 +326,7 @@ static int hdd_fill_ipv6_uc_addr(struct inet6_dev *idev,
case IPV6_ADDR_SCOPE_LINKLOCAL:
qdf_mem_copy(ipv6_uc_addr[*count], &ifa->addr.s6_addr,
sizeof(ifa->addr.s6_addr));
ipv6addr_type[*count] = SIR_IPV6_ADDR_UC_TYPE;
ipv6addr_type[*count] = PMO_IPV6_ADDR_UC_TYPE;
hdd_info("Index %d scope = %s UC-Address: %pI6",
*count, (scope == IPV6_ADDR_SCOPE_LINKLOCAL) ?
"LINK LOCAL" : "GLOBAL", ipv6_uc_addr[*count]);
@ -360,7 +361,7 @@ static int hdd_fill_ipv6_ac_addr(struct inet6_dev *idev,
read_lock_bh(&idev->lock);
for (ifaca = idev->ac_list; ifaca; ifaca = ifaca->aca_next) {
if (*count >= SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) {
if (*count >= PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) {
read_unlock_bh(&idev->lock);
return -EINVAL;
}
@ -371,7 +372,7 @@ static int hdd_fill_ipv6_ac_addr(struct inet6_dev *idev,
case IPV6_ADDR_SCOPE_LINKLOCAL:
qdf_mem_copy(ipv6_ac_addr[*count], &ifaca->aca_addr,
sizeof(ifaca->aca_addr));
ipv6addr_type[*count] = SIR_IPV6_ADDR_AC_TYPE;
ipv6addr_type[*count] = PMO_IPV6_ADDR_AC_TYPE;
hdd_info("Index %d scope = %s AC-Address: %pI6",
*count, (scope == IPV6_ADDR_SCOPE_LINKLOCAL) ?
"LINK LOCAL" : "GLOBAL", ipv6_ac_addr[*count]);
@ -386,165 +387,101 @@ static int hdd_fill_ipv6_ac_addr(struct inet6_dev *idev,
return 0;
}
/**
* hdd_disable_ns_offload() - Disables IPv6 NS offload
* @adapter: ponter to the adapter
*
* Return: nothing
*/
static void hdd_disable_ns_offload(hdd_adapter_t *adapter)
{
tSirHostOffloadReq offloadReq;
QDF_STATUS status;
qdf_mem_zero((void *)&offloadReq, sizeof(tSirHostOffloadReq));
hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD, SIR_OFFLOAD_DISABLE);
offloadReq.enableOrDisable = SIR_OFFLOAD_DISABLE;
offloadReq.offloadType = SIR_IPV6_NS_OFFLOAD;
status = sme_set_host_offload(
WLAN_HDD_GET_HAL_CTX(adapter),
adapter->sessionId, &offloadReq);
if (QDF_STATUS_SUCCESS != status)
hdd_err("Failed to disable NS Offload");
}
/**
* hdd_enable_ns_offload() - Enables IPv6 NS offload
* @adapter: ponter to the adapter
*
* Return: nothing
*/
static void hdd_enable_ns_offload(hdd_adapter_t *adapter)
void hdd_enable_ns_offload(hdd_adapter_t *adapter,
enum pmo_offload_trigger trigger)
{
struct inet6_dev *in6_dev;
uint8_t ipv6_addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA]
[SIR_MAC_IPV6_ADDR_LEN] = { {0,} };
uint8_t ipv6_addr_type[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA] = { 0 };
tSirHostOffloadReq offloadReq;
QDF_STATUS status;
uint32_t count = 0;
int err, i;
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
struct pmo_ns_req *ns_req = NULL;
int err;
ENTER();
if (!psoc) {
hdd_err("psoc is NULL");
goto out;
}
in6_dev = __in6_dev_get(adapter->dev);
if (NULL == in6_dev) {
hdd_err("IPv6 dev does not exist. Failed to request NSOffload");
return;
goto out;
}
ns_req = qdf_mem_malloc(sizeof(*ns_req));
if (!ns_req) {
hdd_err("fail to allocate ns_req");
goto out;
}
ns_req->psoc = psoc;
ns_req->vdev_id = adapter->sessionId;
ns_req->trigger = trigger;
ns_req->count = 0;
/* Unicast Addresses */
err = hdd_fill_ipv6_uc_addr(in6_dev, ipv6_addr, ipv6_addr_type, &count);
err = hdd_fill_ipv6_uc_addr(in6_dev, ns_req->ipv6_addr,
ns_req->ipv6_addr_type, &ns_req->count);
if (err) {
hdd_disable_ns_offload(adapter);
hdd_disable_ns_offload(adapter, trigger);
hdd_notice("Reached max supported addresses and not enabling "
"NS offload");
return;
goto out;
}
/* Anycast Addresses */
err = hdd_fill_ipv6_ac_addr(in6_dev, ipv6_addr, ipv6_addr_type, &count);
err = hdd_fill_ipv6_ac_addr(in6_dev, ns_req->ipv6_addr,
ns_req->ipv6_addr_type, &ns_req->count);
if (err) {
hdd_disable_ns_offload(adapter);
hdd_disable_ns_offload(adapter, trigger);
hdd_notice("Reached max supported addresses and not enabling "
"NS offload");
return;
goto out;
}
qdf_mem_zero(&offloadReq, sizeof(offloadReq));
for (i = 0; i < count; i++) {
/* Filling up the request structure
* Filling the selfIPv6Addr with solicited address
* A Solicited-Node multicast address is created by
* taking the last 24 bits of a unicast or anycast
* address and appending them to the prefix
*
* FF02:0000:0000:0000:0000:0001:FFXX:XXXX
*
* here XX is the unicast/anycast bits
*/
offloadReq.nsOffloadInfo.selfIPv6Addr[i][0] = 0xFF;
offloadReq.nsOffloadInfo.selfIPv6Addr[i][1] = 0x02;
offloadReq.nsOffloadInfo.selfIPv6Addr[i][11] = 0x01;
offloadReq.nsOffloadInfo.selfIPv6Addr[i][12] = 0xFF;
offloadReq.nsOffloadInfo.selfIPv6Addr[i][13] =
ipv6_addr[i][13];
offloadReq.nsOffloadInfo.selfIPv6Addr[i][14] =
ipv6_addr[i][14];
offloadReq.nsOffloadInfo.selfIPv6Addr[i][15] =
ipv6_addr[i][15];
offloadReq.nsOffloadInfo.slotIdx = i;
qdf_mem_copy(&offloadReq.nsOffloadInfo.targetIPv6Addr[i],
&ipv6_addr[i][0], SIR_MAC_IPV6_ADDR_LEN);
offloadReq.nsOffloadInfo.targetIPv6AddrValid[i] =
SIR_IPV6_ADDR_VALID;
offloadReq.nsOffloadInfo.target_ipv6_addr_ac_type[i] =
ipv6_addr_type[i];
qdf_mem_copy(&offloadReq.params.hostIpv6Addr,
&offloadReq.nsOffloadInfo.targetIPv6Addr[i],
SIR_MAC_IPV6_ADDR_LEN);
hdd_info("Setting NSOffload with solicitedIp: "
"%pI6, targetIp: %pI6, Index %d",
&offloadReq.nsOffloadInfo.selfIPv6Addr[i],
&offloadReq.nsOffloadInfo.targetIPv6Addr[i], i);
/* cache ns request */
status = pmo_ucfg_cache_ns_offload_req(ns_req);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Failed to cache ns request status: %d", status);
goto out;
}
hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD, SIR_OFFLOAD_ENABLE);
offloadReq.offloadType = SIR_IPV6_NS_OFFLOAD;
offloadReq.enableOrDisable = SIR_OFFLOAD_ENABLE;
qdf_copy_macaddr(&offloadReq.nsOffloadInfo.self_macaddr,
&adapter->macAddressCurrent);
/* set number of ns offload address count */
offloadReq.num_ns_offload_count = count;
/* Configure the Firmware with this */
status = sme_set_host_offload(WLAN_HDD_GET_HAL_CTX(adapter),
adapter->sessionId, &offloadReq);
if (QDF_STATUS_SUCCESS != status) {
/* enable ns request */
status = pmo_ucfg_enable_ns_offload_in_fwr(adapter->hdd_vdev, trigger);
if (status != QDF_STATUS_SUCCESS)
hdd_err("Failed to enable HostOffload feature with status: %d",
status);
}
else
hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD, SIR_OFFLOAD_ENABLE);
out:
if (ns_req)
qdf_mem_free(ns_req);
EXIT();
}
/**
* hdd_conf_ns_offload() - Configure NS offload
* @adapter: pointer to the adapter
* @fenable: flag to enable or disable
* 0 - disable
* 1 - enable
*
* Return: nothing
*/
void hdd_conf_ns_offload(hdd_adapter_t *adapter, bool fenable)
void hdd_disable_ns_offload(hdd_adapter_t *adapter,
enum pmo_offload_trigger trigger)
{
hdd_context_t *hdd_ctx;
QDF_STATUS status;
ENTER();
hdd_notice(" fenable = %d", fenable);
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
/* In SAP/P2PGo mode, ARP/NS offload feature capability
* is controlled by one bit.
*/
if ((QDF_SAP_MODE == adapter->device_mode ||
QDF_P2P_GO_MODE == adapter->device_mode) &&
!hdd_ctx->ap_arpns_support) {
hdd_notice("NS Offload is not supported in SAP/P2PGO mode");
return;
status = pmo_ucfg_flush_ns_offload_req(adapter->hdd_vdev);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Failed to flush NS Offload");
goto out;
}
if (fenable)
hdd_enable_ns_offload(adapter);
status = pmo_ucfg_disable_ns_offload_in_fwr(adapter->hdd_vdev, trigger);
if (status != QDF_STATUS_SUCCESS)
hdd_err("Failed to disable NS Offload");
else
hdd_disable_ns_offload(adapter);
hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD,
SIR_OFFLOAD_DISABLE);
out:
EXIT();
return;
}
/**
@ -564,7 +501,6 @@ static void __hdd_ipv6_notifier_work_queue(struct work_struct *work)
container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue);
hdd_context_t *pHddCtx;
int status;
bool ndi_connected = false;
ENTER();
@ -573,21 +509,7 @@ static void __hdd_ipv6_notifier_work_queue(struct work_struct *work)
if (0 != status)
return;
if (!pHddCtx->config->active_mode_offload) {
hdd_err("Active mode offload is disabled");
return;
}
/* check if the device is in NAN data mode */
if (WLAN_HDD_IS_NDI(pAdapter))
ndi_connected = WLAN_HDD_IS_NDI_CONNECTED(pAdapter);
if (eConnectionState_Associated ==
(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState ||
ndi_connected)
if (pHddCtx->config->fhostNSOffload &&
pHddCtx->ns_offload_enable)
hdd_conf_ns_offload(pAdapter, true);
hdd_enable_ns_offload(pAdapter, pmo_ipv6_change_notify);
EXIT();
}
@ -604,62 +526,57 @@ void hdd_ipv6_notifier_work_queue(struct work_struct *work)
cds_ssr_unprotect(__func__);
}
/**
* hdd_conf_hostoffload() - Central function to configure the supported offloads
* @pAdapter: pointer to the adapter
* @fenable: flag set to enable (1) or disable (0)
*
* Central function to configure the supported offloads either
* enable or disable them.
*
* Return: nothing
*/
void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, bool fenable)
void hdd_enable_host_offloads(hdd_adapter_t *adapter,
enum pmo_offload_trigger trigger)
{
hdd_context_t *pHddCtx;
ENTER();
hdd_info("Configuring offloads with flag: %d", fenable);
/* Get the HDD context. */
pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
if (((QDF_STA_MODE != pAdapter->device_mode) &&
(QDF_P2P_CLIENT_MODE != pAdapter->device_mode))) {
hdd_info("Offloads not supported in mode %d",
pAdapter->device_mode);
return;
if (!pmo_ucfg_is_vdev_supports_offload(adapter->hdd_vdev)) {
hdd_info("offload is not supported on this vdev opmode: %d",
adapter->device_mode);
goto out;
}
if (eConnectionState_Associated !=
(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) {
hdd_info("Offloads not supported in state %d",
(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->
conn_info.connState);
return;
}
hdd_conf_gtk_offload(pAdapter, fenable);
/* Configure ARP/NS offload during cfg80211 suspend/resume and
* Enable MC address filtering during cfg80211 suspend
* only if active mode offload is disabled
*/
if (!pHddCtx->config->active_mode_offload) {
hdd_info("configuring unconfigured active mode offloads");
hdd_conf_arp_offload(pAdapter, fenable);
wlan_hdd_set_mc_addr_list(pAdapter, fenable);
if (pHddCtx->config->fhostNSOffload &&
pHddCtx->ns_offload_enable)
hdd_conf_ns_offload(pAdapter, fenable);
if (!pmo_ucfg_is_vdev_connected(adapter->hdd_vdev)) {
hdd_info("vdev is not connected");
goto out;
}
hdd_info("enable offloads");
hdd_conf_gtk_offload(adapter, true);
hdd_enable_arp_offload(adapter, trigger);
hdd_enable_ns_offload(adapter, trigger);
wlan_hdd_set_mc_addr_list(adapter, true);
out:
EXIT();
return;
}
void hdd_disable_host_offloads(hdd_adapter_t *adapter,
enum pmo_offload_trigger trigger)
{
ENTER();
if (!pmo_ucfg_is_vdev_supports_offload(adapter->hdd_vdev)) {
hdd_info("offload is not supported on this vdev opmode: %d",
adapter->device_mode);
goto out;
}
if (!pmo_ucfg_is_vdev_connected(adapter->hdd_vdev)) {
hdd_info("vdev is not connected");
goto out;
}
hdd_info("disable offloads");
hdd_conf_gtk_offload(adapter, false);
hdd_disable_arp_offload(adapter, trigger);
hdd_disable_ns_offload(adapter, trigger);
wlan_hdd_set_mc_addr_list(adapter, false);
out:
EXIT();
}
#endif
/**
* hdd_lookup_ifaddr() - Lookup interface address data by name
@ -806,42 +723,10 @@ static void __hdd_ipv4_notifier_work_queue(struct work_struct *work)
{
hdd_adapter_t *pAdapter =
container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue);
hdd_context_t *pHddCtx;
hdd_station_ctx_t *sta_ctx;
int status;
bool ndi_connected;
bool sta_associated;
hdd_info("Configuring ARP Offload");
pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
status = wlan_hdd_validate_context(pHddCtx);
if (status)
return;
if (!pHddCtx->config->active_mode_offload) {
hdd_err("Active mode offload is disabled");
return;
}
ndi_connected = WLAN_HDD_IS_NDI(pAdapter) &&
WLAN_HDD_IS_NDI_CONNECTED(pAdapter);
sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
sta_associated = sta_ctx->conn_info.connState ==
eConnectionState_Associated;
if (!ndi_connected && !sta_associated)
return;
/*
* This invocation being part of the IPv4 registration callback,
* we are passing second parameter as 2 to avoid registration
* of IPv4 notifier again.
*/
hdd_conf_arp_offload(pAdapter, true);
ENTER();
hdd_enable_arp_offload(pAdapter, pmo_ipv4_change_notify);
hdd_set_grat_arp_keepalive(pAdapter);
EXIT();
}
/**
@ -944,84 +829,102 @@ int wlan_hdd_ipv4_changed(struct notifier_block *nb,
}
/**
* hdd_conf_arp_offload() - Configure ARP offload
* hdd_get_ipv4_local_interface() - get ipv4 local interafce from iface list
* @pAdapter: Adapter context for which ARP offload is to be configured
* @fenable: true : enable ARP offload false : disable arp offload
*
* Return:
* QDF_STATUS_SUCCESS - on successful operation,
* QDF_STATUS_E_FAILURE - on failure of operation
* ifa - on successful operation,
* NULL - on failure of operation
*/
QDF_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, bool fenable)
static struct in_ifaddr *hdd_get_ipv4_local_interface(
hdd_adapter_t *pAdapter)
{
struct in_ifaddr *ifa;
int i = 0;
tSirHostOffloadReq offLoadRequest;
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
struct in_ifaddr **ifap = NULL;
struct in_ifaddr *ifa = NULL;
struct in_device *in_dev;
hdd_info("fenable = %d", fenable);
/* In SAP/P2P Go mode, ARP/NS Offload feature capability
* is controlled by one bit.
*/
if ((QDF_SAP_MODE == pAdapter->device_mode ||
QDF_P2P_GO_MODE == pAdapter->device_mode) &&
!pHddCtx->ap_arpns_support) {
hdd_notice("ARP Offload is not supported in SAP/P2PGO mode");
return QDF_STATUS_SUCCESS;
}
if (fenable) {
ifa = hdd_lookup_ifaddr(pAdapter);
if (ifa && ifa->ifa_local) {
offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
SIR_OFFLOAD_ENABLE);
hdd_notice("Enable ARP offload: filter programmed = %d",
offLoadRequest.enableOrDisable);
/* converting u32 to IPV4 address */
for (i = 0; i < 4; i++) {
offLoadRequest.params.hostIpv4Addr[i] =
(ifa->ifa_local >> (i * 8)) & 0xFF;
in_dev = __in_dev_get_rtnl(pAdapter->dev);
if (in_dev) {
for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
ifap = &ifa->ifa_next) {
if (!strcmp(pAdapter->dev->name, ifa->ifa_label)) {
/* if match break */
return ifa;
}
hdd_notice(" Enable SME HostOffload: %d.%d.%d.%d",
offLoadRequest.params.hostIpv4Addr[0],
offLoadRequest.params.hostIpv4Addr[1],
offLoadRequest.params.hostIpv4Addr[2],
offLoadRequest.params.hostIpv4Addr[3]);
if (QDF_STATUS_SUCCESS !=
sme_set_host_offload(WLAN_HDD_GET_HAL_CTX(pAdapter),
pAdapter->sessionId,
&offLoadRequest)) {
hdd_err("Failed to enable HostOffload feature");
return QDF_STATUS_E_FAILURE;
}
} else {
hdd_notice("IP Address is not assigned");
}
}
ifa = NULL;
return QDF_STATUS_SUCCESS;
return ifa;
}
void hdd_enable_arp_offload(hdd_adapter_t *adapter,
enum pmo_offload_trigger trigger)
{
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
QDF_STATUS status;
struct pmo_arp_req *arp_req = NULL;
struct in_ifaddr *ifa = NULL;
ENTER();
arp_req = qdf_mem_malloc(sizeof(*arp_req));
if (!arp_req) {
hdd_err("cannot allocate arp_req");
goto out;
}
hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD,
SIR_OFFLOAD_DISABLE);
qdf_mem_zero((void *)&offLoadRequest,
sizeof(tSirHostOffloadReq));
offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE;
offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD;
arp_req->psoc = psoc;
arp_req->vdev_id = adapter->sessionId;
arp_req->trigger = trigger;
if (QDF_STATUS_SUCCESS !=
sme_set_host_offload(WLAN_HDD_GET_HAL_CTX(pAdapter),
pAdapter->sessionId, &offLoadRequest)) {
hdd_err("Failure to disable host offload feature");
return QDF_STATUS_E_FAILURE;
ifa = hdd_get_ipv4_local_interface(adapter);
if (ifa && ifa->ifa_local) {
arp_req->ipv4_addr = (uint32_t)ifa->ifa_local;
status = pmo_ucfg_cache_arp_offload_req(arp_req);
if (status == QDF_STATUS_SUCCESS) {
status = pmo_ucfg_enable_arp_offload_in_fwr(
adapter->hdd_vdev, trigger);
if (status == QDF_STATUS_SUCCESS)
hdd_wlan_offload_event(
PMO_IPV4_ARP_REPLY_OFFLOAD,
PMO_OFFLOAD_ENABLE);
else
hdd_info("fail to enable arp offload in fwr");
} else
hdd_info("fail to cache arp offload request");
} else {
hdd_notice("IP Address is not assigned");
status = QDF_STATUS_NOT_INITIALIZED;
}
out:
if (arp_req)
qdf_mem_free(arp_req);
EXIT();
}
void hdd_disable_arp_offload(hdd_adapter_t *adapter,
enum pmo_offload_trigger trigger)
{
QDF_STATUS status;
ENTER();
status = pmo_ucfg_flush_arp_offload_req(adapter->hdd_vdev);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Failed to flush arp Offload");
goto out;
}
return QDF_STATUS_SUCCESS;
status = pmo_ucfg_disable_arp_offload_in_fwr(adapter->hdd_vdev, trigger);
if (status == QDF_STATUS_SUCCESS)
hdd_wlan_offload_event(PMO_IPV4_ARP_REPLY_OFFLOAD,
PMO_OFFLOAD_DISABLE);
else
hdd_info("fail to disable arp offload");
out:
EXIT();
}
#ifdef WLAN_FEATURE_PACKET_FILTERING
@ -1175,7 +1078,7 @@ static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
hdd_notice("send wlan resume indication");
/* Disable supported OffLoads */
hdd_conf_hostoffload(pAdapter, false);
hdd_disable_host_offloads(pAdapter, pmo_apps_resume);
}
/**
@ -1216,7 +1119,6 @@ hdd_suspend_wlan(void (*callback)(void *callbackContext, bool suspended),
hdd_adapter_t *pAdapter = NULL;
hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
uint32_t conn_state_mask = 0;
hdd_info("WLAN being suspended by OS");
pHddCtx = cds_get_context(QDF_MODULE_ID_HDD);
@ -1241,8 +1143,7 @@ hdd_suspend_wlan(void (*callback)(void *callbackContext, bool suspended),
WLAN_CONTROL_PATH);
/* Configure supported OffLoads */
hdd_conf_hostoffload(pAdapter, true);
hdd_enable_host_offloads(pAdapter, pmo_apps_suspend);
hdd_update_conn_state_mask(pAdapter, &conn_state_mask);
status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
@ -2130,7 +2031,6 @@ static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
hdd_context_t *pHddCtx;
QDF_STATUS qdf_status;
int status;
ENTER();
@ -2169,20 +2069,6 @@ static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
}
mutex_unlock(&pHddCtx->iface_change_lock);
if (allow_power_save &&
pHddCtx->hdd_wlan_suspended &&
pHddCtx->config->fhostArpOffload &&
(eConnectionState_Associated ==
(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)) {
hdd_notice("offload: in cfg80211_set_power_mgmt, "
"calling arp offload");
qdf_status = hdd_conf_arp_offload(pAdapter, true);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
hdd_notice("Failed to enable ARPOFFLOAD Feature %d",
qdf_status);
}
}
status = wlan_hdd_set_powersave(pAdapter, allow_power_save, timeout);
allow_power_save ? hdd_stop_dhcp_ind(pAdapter) :

View file

@ -10836,8 +10836,7 @@ static int iw_set_dynamic_mcbc_filter(struct net_device *dev,
"Configure broadcast filtering via ini item, 'g_enable_non_arp_bc_hw_filter.'\n"
"\tg_enable_non_arp_bc_hw_filter=1 # drop all non-ARP broadcast traffic\n"
"\tg_enable_non_arp_bc_hw_filter=0 # allow all broadcast traffic");
return -EINVAL;
return -EINVAL;
}
/**

View file

@ -2254,6 +2254,7 @@ void wma_process_set_pdev_ht_ie_req(tp_wma_handle wma,
struct set_ie_param *ie_params);
void wma_process_set_pdev_vht_ie_req(tp_wma_handle wma,
struct set_ie_param *ie_params);
void wma_remove_peer(tp_wma_handle wma, u_int8_t *bssid,
u_int8_t vdev_id, void *peer,
bool roam_synch_in_progress);

View file

@ -1031,10 +1031,6 @@ QDF_STATUS wma_process_gtk_offload_getinfo_req(tp_wma_handle wma,
params);
#endif
QDF_STATUS wma_enable_arp_ns_offload(tp_wma_handle wma,
tpSirHostOffloadReq pHostOffloadParams,
bool bArpOnly);
QDF_STATUS wma_process_cesium_enable_ind(tp_wma_handle wma);
QDF_STATUS wma_process_get_peer_info_req

View file

@ -4697,86 +4697,6 @@ out:
}
#endif /* WLAN_FEATURE_GTK_OFFLOAD */
/**
* wma_enable_arp_ns_offload() - enable ARP NS offload
* @wma: wma handle
* @tpSirHostOffloadReq: offload request
* @config_arp: config arp flag
*
* To configure ARP NS off load data to firmware
* when target goes to wow mode.
*
* Return: QDF Status
*/
QDF_STATUS wma_enable_arp_ns_offload(tp_wma_handle wma,
tpSirHostOffloadReq
offload_req, bool config_arp)
{
int32_t res;
uint8_t vdev_id;
tpSirHostOffloadReq ns_offload_req;
tpSirHostOffloadReq arp_offload_req;
/* Get the vdev id */
if (!wma_find_vdev_by_bssid(wma, offload_req->bssid.bytes,
&vdev_id)) {
WMA_LOGE("vdev handle is invalid for %pM",
offload_req->bssid.bytes);
qdf_mem_free(offload_req);
return QDF_STATUS_E_INVAL;
}
if (!wma->interfaces[vdev_id].vdev_up) {
WMA_LOGE("vdev %d is not up skipping arp/ns offload", vdev_id);
qdf_mem_free(offload_req);
return QDF_STATUS_E_FAILURE;
}
/*
* config_arp is true means arp request comes from upper layer
* Hence ns request need to used from wma cached request.
*/
if (config_arp) {
arp_offload_req = offload_req;
ns_offload_req = &wma->interfaces[vdev_id].ns_offload_req;
WMA_LOGD(" %s: ARP Offload vdev_id: %d enable: %d",
__func__, vdev_id,
offload_req->enableOrDisable);
} else {
ns_offload_req = offload_req;
arp_offload_req = &wma->interfaces[vdev_id].arp_offload_req;
WMA_LOGD(" %s: NS Offload vdev_id: %d enable: %d ns_count: %u",
__func__, vdev_id,
offload_req->enableOrDisable,
offload_req->num_ns_offload_count);
}
res = wmi_unified_enable_arp_ns_offload_cmd(wma->wmi_handle,
(struct host_offload_req_param *)arp_offload_req,
(struct host_offload_req_param *)ns_offload_req,
config_arp,
vdev_id);
if (res) {
WMA_LOGE("Failed to enable ARP NDP/NSffload");
qdf_mem_free(offload_req);
return QDF_STATUS_E_FAILURE;
}
if (config_arp) {
qdf_mem_copy(&wma->interfaces[vdev_id].arp_offload_req,
offload_req,
sizeof(wma->interfaces[vdev_id].arp_offload_req));
} else {
qdf_mem_copy(&wma->interfaces[vdev_id].ns_offload_req,
offload_req,
sizeof(wma->interfaces[vdev_id].ns_offload_req));
}
qdf_mem_free(offload_req);
return QDF_STATUS_SUCCESS;
}
/**
* wma_process_cesium_enable_ind() - enables cesium functionality in target
* @wma: wma handle

View file

@ -6573,18 +6573,6 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, struct scheduler_msg *msg)
(tpSirGtkOffloadGetInfoRspParams)msg->bodyptr);
break;
#endif /* WLAN_FEATURE_GTK_OFFLOAD */
case WMA_SET_HOST_OFFLOAD:
wma_enable_arp_ns_offload(wma_handle,
(tpSirHostOffloadReq) msg->bodyptr,
true);
break;
#ifdef WLAN_NS_OFFLOAD
case WMA_SET_NS_OFFLOAD:
wma_enable_arp_ns_offload(wma_handle,
(tpSirHostOffloadReq) msg->bodyptr,
false);
break;
#endif /*WLAN_NS_OFFLOAD */
case WMA_ROAM_SCAN_OFFLOAD_REQ:
/*
* Main entry point or roaming directives from CSR.