From 3ba26b87472bfb83da167868dcf651cea5ac2a89 Mon Sep 17 00:00:00 2001 From: Mukul Sharma Date: Thu, 12 Jan 2017 21:59:41 +0530 Subject: [PATCH] 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 --- core/hdd/inc/wlan_hdd_power.h | 76 ++++- core/hdd/src/wlan_hdd_cfg80211.c | 5 +- core/hdd/src/wlan_hdd_power.c | 508 ++++++++++++------------------- core/hdd/src/wlan_hdd_wext.c | 3 +- core/wma/inc/wma.h | 1 + core/wma/inc/wma_internal.h | 4 - core/wma/src/wma_features.c | 80 ----- core/wma/src/wma_main.c | 12 - 8 files changed, 274 insertions(+), 415 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_power.h b/core/hdd/inc/wlan_hdd_power.h index 0fb18a322a94..5a45179ee966 100644 --- a/core/hdd/inc/wlan_hdd_power.h +++ b/core/hdd/inc/wlan_hdd_power.h @@ -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, diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 18663bb28077..bfc4c15157b7 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -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; } diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index f8268d3c992b..e8f73ef94d06 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -80,6 +80,7 @@ #include #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) : diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index 279b0c920c98..484ed86137b9 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -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; } /** diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index cadb2b54b8bd..6958b66db231 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -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); diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 880655e93a82..96f32ccfa301 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -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 diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 09311445a541..de37e8437b73 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -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 diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 646d5c2284bb..e386dbd5bcc3 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -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.