From 6fb45e6707b231dcbe96ab33239d594b0635c7bd Mon Sep 17 00:00:00 2001 From: Sanjay Devnani Date: Wed, 5 Feb 2014 14:55:11 -0800 Subject: wlan: make BAP module 64 bit clean fixing compiler warning for the BAP module by using a more generic type for a pointer holder. Change-Id: Id2503b2dab3119a7f2ad27d35e61be3df452bc18 CRs-fixed: 604777 --- CORE/BAP/src/bapApiData.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CORE/BAP/src/bapApiData.c b/CORE/BAP/src/bapApiData.c index 44225547b46c..f9249a4a0f70 100644 --- a/CORE/BAP/src/bapApiData.c +++ b/CORE/BAP/src/bapApiData.c @@ -310,7 +310,7 @@ WLANBAP_XlateTxDataPkt v_PVOID_t pHddHdl; /* Handle to return BSL context in */ v_U16_t headerLength; /* The 802.3 frame length*/ v_U16_t protoType = WLANBAP_BT_AMP_TYPE_DATA; /* The protocol type bytes*/ - v_U32_t value = 0; + uintptr_t value = 0; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ @@ -443,7 +443,7 @@ WLANBAP_XlateTxDataPkt /*Set the logical link handle as user data so that we can retrieve it on Tx Complete */ - value = (v_U32_t)hciACLHeader.logLinkHandle; + value = (uintptr_t)hciACLHeader.logLinkHandle; vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_BAP, (v_VOID_t *)value); @@ -980,12 +980,12 @@ WLANBAP_TxCompCB VOS_STATUS wTxSTAtus ) { - VOS_STATUS vosStatus; - ptBtampHandle bapHdl; /* holds ptBtampHandle value returned */ + VOS_STATUS vosStatus; + ptBtampHandle bapHdl; /* holds ptBtampHandle value returned */ ptBtampContext bapContext; /* Holds the btampContext value returned */ - v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ v_PVOID_t pvlogLinkHandle = NULL; - v_U32_t value; + uintptr_t value; WLANBAP_HCIACLHeaderType hciACLHeader; @@ -1038,7 +1038,7 @@ WLANBAP_TxCompCB vos_pkt_get_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_BAP, &pvlogLinkHandle); - value = (v_U32_t)pvlogLinkHandle; + value = (uintptr_t)pvlogLinkHandle; hciACLHeader.logLinkHandle = value; #ifdef BAP_DEBUG -- cgit v1.2.3 From ca220fab78f3c75cb3f2d8e85daccb7c173dfadb Mon Sep 17 00:00:00 2001 From: Rajesh Chauhan Date: Thu, 6 Feb 2014 10:58:49 -0800 Subject: qcacld: CL 835222 - update fw common interface files Changes in WMI header files for NaN. Change-Id: I7732927d0f36885cda09807706aaae034dbbad55 CRs-Fixed: 612510 --- CORE/SERVICES/COMMON/wmi_services.h | 3 ++- CORE/SERVICES/COMMON/wmi_tlv_defs.h | 18 ++++++++++++++++-- CORE/SERVICES/COMMON/wmi_unified.h | 27 +++++++++++++++++++++++++++ CORE/SERVICES/COMMON/wmi_version.h | 4 ++-- CORE/SERVICES/WMI/wmi_unified.c | 2 ++ 5 files changed, 49 insertions(+), 5 deletions(-) diff --git a/CORE/SERVICES/COMMON/wmi_services.h b/CORE/SERVICES/COMMON/wmi_services.h index e97d2e04a613..e8b41bd2ff6d 100644 --- a/CORE/SERVICES/COMMON/wmi_services.h +++ b/CORE/SERVICES/COMMON/wmi_services.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -97,6 +97,7 @@ typedef enum { WMI_SERVICE_MHF_OFFLOAD, /* multi-hop forwarding offload */ WMI_SERVICE_COEX_SAR, /* target support SAR tx limit from WMI_PDEV_PARAM_TXPOWER_LIMITxG */ WMI_SERVICE_BCN_TXRATE_OVERRIDE, /* Will support the bcn/prb rsp rate override */ + WMI_SERVICE_NAN, /* Neighbor Awareness Network */ WMI_MAX_SERVICE=64 /* max service */ } WMI_SERVICE; diff --git a/CORE/SERVICES/COMMON/wmi_tlv_defs.h b/CORE/SERVICES/COMMON/wmi_tlv_defs.h index 067c9ffd74e1..8ffd0582ac16 100644 --- a/CORE/SERVICES/COMMON/wmi_tlv_defs.h +++ b/CORE/SERVICES/COMMON/wmi_tlv_defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -418,6 +418,8 @@ typedef enum { WMITLV_TAG_STRUC_wmi_mhf_offload_plumb_routing_table_cmd_fixed_param, WMITLV_TAG_STRUC_WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, + WMITLV_TAG_STRUC_wmi_nan_cmd_param, + WMITLV_TAG_STRUC_wmi_nan_event_hdr, WMITLV_TAG_STRUC_wmi_diag_data_container_event_fixed_param, } WMITLV_TAG_ID; @@ -568,7 +570,8 @@ typedef enum { OP(WMI_BATCH_SCAN_TRIGGER_RESULT_CMDID) \ OP(WMI_THERMAL_MGMT_CMDID) \ OP(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID) \ - OP(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID) + OP(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID) \ + OP(WMI_NAN_CMDID) /* * IMPORTANT: Please add _ALL_ WMI Events Here. @@ -630,6 +633,7 @@ typedef enum { OP(WMI_BATCH_SCAN_ENABLED_EVENTID) \ OP(WMI_BATCH_SCAN_RESULT_EVENTID) \ OP(WMI_THERMAL_MGMT_EVENTID) \ + OP(WMI_NAN_EVENTID) \ OP(WMI_DIAG_DATA_CONTAINER_EVENTID) /* TLV definitions of WMI commands */ @@ -1511,6 +1515,11 @@ WMITLV_CREATE_PARAM_STRUC(WMI_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD_fixed_param, fixed_param, WMITLV_SIZE_FIX) WMITLV_CREATE_PARAM_STRUC(WMI_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID); +/* NaN Request */ +#define WMITLV_TABLE_WMI_NAN_CMDID(id,op,buf,len) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_nan_cmd_param, wmi_nan_cmd_param, fixed_param, WMITLV_SIZE_FIX) \ + WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) +WMITLV_CREATE_PARAM_STRUC(WMI_NAN_CMDID); /************************** TLV definitions of WMI events *******************************/ @@ -1812,6 +1821,11 @@ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_dfs_radar_event_fixed_param, wmi WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_thermal_mgmt_event_fixed_param, wmi_thermal_mgmt_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) WMITLV_CREATE_PARAM_STRUC(WMI_THERMAL_MGMT_EVENTID); +/* NAN Response/Indication Event */ +#define WMITLV_TABLE_WMI_NAN_EVENTID(id,op,buf,len) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_nan_event_hdr, wmi_nan_event_hdr, fixed_param, WMITLV_SIZE_FIX) \ +WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_BYTE, A_UINT8, data, WMITLV_SIZE_VAR) + WMITLV_CREATE_PARAM_STRUC(WMI_NAN_EVENTID); #define WMITLV_TABLE_WMI_DIAG_DATA_CONTAINER_EVENTID(id,op,buf,len) \ WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_STRUC_wmi_diag_data_container_event_fixed_param, wmi_diag_data_container_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) \ diff --git a/CORE/SERVICES/COMMON/wmi_unified.h b/CORE/SERVICES/COMMON/wmi_unified.h index b4e1f179539a..3d487815450f 100644 --- a/CORE/SERVICES/COMMON/wmi_unified.h +++ b/CORE/SERVICES/COMMON/wmi_unified.h @@ -170,6 +170,7 @@ typedef enum { WMI_GRP_MHF_OFL, WMI_GRP_LOCATION_SCAN, WMI_GRP_OEM, + WMI_GRP_NAN, } WMI_GRP_ID; #define WMI_CMD_GRP_START_ID(grp_id) (((grp_id) << 12) | 0x1) @@ -585,6 +586,9 @@ typedef enum { WMI_BATCH_SCAN_TRIGGER_RESULT_CMDID, /* OEM related cmd */ WMI_OEM_REQ_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_OEM), + + /** Nan Request */ + WMI_NAN_CMDID=WMI_CMD_GRP_START_ID(WMI_GRP_NAN), } WMI_CMD_ID; typedef enum { @@ -772,6 +776,9 @@ typedef enum { WMI_OEM_CAPABILITY_EVENTID=WMI_EVT_GRP_START_ID(WMI_GRP_OEM), WMI_OEM_MEASUREMENT_REPORT_EVENTID, WMI_OEM_ERROR_REPORT_EVENTID, + + /* NAN Event */ + WMI_NAN_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_NAN), } WMI_EVT_ID; /* defines for OEM message sub-types */ @@ -6305,6 +6312,26 @@ typedef struct { A_UINT32 temperature_degreeC;/* temperature in degree C*/ } wmi_thermal_mgmt_event_fixed_param; +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_nan_cmd_param */ + A_UINT32 data_len; /** length in byte of data[]. */ + /* This structure is used to send REQ binary blobs + * from application/service to firmware where Host drv is pass through . + * Following this structure is the TLV: + * A_UINT8 data[]; // length in byte given by field data_len. + */ +} wmi_nan_cmd_param; + +typedef struct { + A_UINT32 tlv_header; /** TLV tag and len; tag equals WMITLV_TAG_STRUC_wmi_nan_event_hdr */ + A_UINT32 data_len; /** length in byte of data[]. */ + /* This structure is used to send REQ binary blobs + * from firmware to application/service where Host drv is pass through . + * Following this structure is the TLV: + * A_UINT8 data[]; // length in byte given by field data_len. + */ +} wmi_nan_event_hdr; + typedef struct { A_UINT32 tlv_header; A_UINT32 num_data; diff --git a/CORE/SERVICES/COMMON/wmi_version.h b/CORE/SERVICES/COMMON/wmi_version.h index fbc3636b9e73..55446bd96c06 100644 --- a/CORE/SERVICES/COMMON/wmi_version.h +++ b/CORE/SERVICES/COMMON/wmi_version.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -36,7 +36,7 @@ #define __WMI_VER_MINOR_ 0 /** WMI revision number has to be incremented when there is a * change that may or may not break compatibility. */ -#define __WMI_REVISION_ 33 +#define __WMI_REVISION_ 34 /** The Version Namespace should not be normally changed. Only * host and firmware of the same WMI namespace will work diff --git a/CORE/SERVICES/WMI/wmi_unified.c b/CORE/SERVICES/WMI/wmi_unified.c index 8d681fa4ff5e..28830972dee1 100644 --- a/CORE/SERVICES/WMI/wmi_unified.c +++ b/CORE/SERVICES/WMI/wmi_unified.c @@ -478,6 +478,8 @@ static u_int8_t* get_wmi_cmd_string(WMI_CMD_ID wmi_command) CASE_RETURN_STRING(WMI_BATCH_SCAN_TRIGGER_RESULT_CMDID); /* OEM related cmd */ CASE_RETURN_STRING(WMI_OEM_REQ_CMDID); + /* NAN request cmd */ + CASE_RETURN_STRING(WMI_NAN_CMDID); } return "Invalid WMI cmd"; } -- cgit v1.2.3 From 61cd4b514283a70f85641ea54a089b3c9b71607e Mon Sep 17 00:00:00 2001 From: Prashanth Bhatta Date: Tue, 28 Jan 2014 14:16:54 -0800 Subject: qcacld: Define open source flag based on license Kbuild file enables WLAN_OPEN_SOURCE flag based on the directory path but this doesn't work for all the platform as path may be different. This change passes the WLAN_OPEN_SOURCE flag from Android.mk or Makefile. Makefile determines whether the driver is open source or proprietary and accordingly WLAN_OPEN_SOURCE is set to 1 or 0. Change-Id: Id0149f71ceb3e94bd1a67868565cd3b8151bdd7d --- Android.mk | 3 +++ Kbuild | 15 ++++++--------- Makefile | 10 +++++++++- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Android.mk b/Android.mk index de83532a4213..d3dfafce1fe0 100644 --- a/Android.mk +++ b/Android.mk @@ -22,8 +22,10 @@ ifneq ($(findstring vendor,$(LOCAL_PATH)),) # Determine if we are Proprietary or Open Source ifneq ($(findstring opensource,$(LOCAL_PATH)),) WLAN_PROPRIETARY := 0 + WLAN_OPEN_SOURCE := 1 else WLAN_PROPRIETARY := 1 + WLAN_OPEN_SOURCE := 0 endif ifeq ($(WLAN_PROPRIETARY),1) @@ -52,6 +54,7 @@ KBUILD_OPTIONS += MODNAME=wlan KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) KBUILD_OPTIONS += $(WLAN_SELECT) KBUILD_OPTIONS += $(WLAN_ISOC_SELECT) +KBUILD_OPTIONS += WLAN_OPEN_SOURCE=$(WLAN_OPEN_SOURCE) include $(CLEAR_VARS) LOCAL_MODULE := $(WLAN_CHIPSET)_wlan.ko diff --git a/Kbuild b/Kbuild index 7742ef25a445..1bc81b1042b4 100644 --- a/Kbuild +++ b/Kbuild @@ -1,5 +1,5 @@ -# We can build either as part of a standalone Kernel build or part -# of an Android build. Determine which mechanism is being used +# We can build either as part of a standalone Kernel build or as +# an external module. Determine which mechanism is being used ifeq ($(MODNAME),) KERNEL_BUILD := 1 else @@ -7,10 +7,11 @@ else endif ifeq ($(KERNEL_BUILD),1) - # These are provided in Android-based builds + # These are provided in external module based builds # Need to explicitly define for Kernel-based builds MODNAME := wlan - WLAN_ROOT := drivers/staging/prima + WLAN_ROOT := drivers/staging/qcacld-2.0 + WLAN_OPEN_SOURCE := 1 endif ifeq ($(KERNEL_BUILD), 0) @@ -972,11 +973,7 @@ ifeq ($(RE_ENABLE_WIFI_ON_WDI_TIMEOUT),1) CDEFINES += -DWDI_RE_ENABLE_WIFI_ON_WDI_TIMEOUT endif -ifeq ($(KERNEL_BUILD),1) -CDEFINES += -DWLAN_OPEN_SOURCE -endif - -ifeq ($(findstring opensource, $(WLAN_ROOT)), opensource) +ifeq ($(WLAN_OPEN_SOURCE), 1) CDEFINES += -DWLAN_OPEN_SOURCE endif diff --git a/Makefile b/Makefile index e63cab248f48..c05b00f26c57 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,21 @@ KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build -KBUILD_OPTIONS := WLAN_ROOT=$(shell pwd) +KBUILD_OPTIONS := WLAN_ROOT=$(PWD) KBUILD_OPTIONS += MODNAME=wlan +# Determine if the driver license is Open source or proprietary +# This is determined under the assumption that LICENSE doesn't change. +# Please change here if driver license text changes. +LICENSE_FILE ?= $(PWD)/$(WLAN_ROOT)/CORE/HDD/src/wlan_hdd_main.c +WLAN_OPEN_SOURCE = $(shell if grep -q "MODULE_LICENSE(\"Dual BSD/GPL\")" \ + $(LICENSE_FILE); then echo 1; else echo 0; fi) + #By default build for CLD WLAN_SELECT := CONFIG_QCA_CLD_WLAN=m KBUILD_OPTIONS += CONFIG_QCA_WIFI_ISOC=0 KBUILD_OPTIONS += CONFIG_QCA_WIFI_2_0=1 KBUILD_OPTIONS += $(WLAN_SELECT) +KBUILD_OPTIONS += WLAN_OPEN_SOURCE=$(WLAN_OPEN_SOURCE) KBUILD_OPTIONS += $(KBUILD_EXTRA) # Extra config if any all: -- cgit v1.2.3 From a10789eb9eea428842b95ffeeb444813d12682db Mon Sep 17 00:00:00 2001 From: Xiaochang Duan Date: Wed, 5 Feb 2014 16:42:49 -0800 Subject: wlan:qcacld:rome_ibss: Added Rome IBSS WEP Security support 1. Added WEP security support on Rome IBSS: Uses the 1st WEP key as both BSS key and peer key; Also blocks all subsequent WEP keys from reaching PE and WMA to reduce overhead. 2. Added IBSS condition check so a STA mode specific message does not show in kmsg when peers join the IBSS Change-Id: Iba52d69221f1a14d87e0cd24e599ce8110fa6a8f CRs-Fixed: 606074 --- CORE/HDD/inc/wlan_hdd_main.h | 3 +++ CORE/HDD/src/wlan_hdd_cfg80211.c | 12 ++++++++++++ CORE/HDD/src/wlan_hdd_main.c | 2 ++ CORE/SERVICES/WMA/wma.c | 4 ++-- CORE/SME/src/csr/csrApiRoam.c | 10 +++++++++- 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index 5883fa0ad236..4ae0aa107893 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -641,6 +641,9 @@ struct hdd_station_ctx /*Increment whenever ibss New peer joins and departs the network */ int ibss_sta_generation; + /* Indication of wep/wpa-none keys installation */ + v_BOOL_t ibss_enc_key_installed; + /*Save the wep/wpa-none keys*/ tCsrRoamSetKey ibss_enc_key; v_BOOL_t hdd_ReassocScenario; diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 3e295220689d..216bec3d2d25 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -3781,6 +3781,13 @@ static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy, } if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise) { + /* if a key is already installed, block all subsequent ones */ + if (pAdapter->sessionCtx.station.ibss_enc_key_installed) { + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: IBSS key installed already", __func__); + return 0; + } + setKey.keyDirection = eSIR_TX_RX; /*Set the group key*/ status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), @@ -3796,6 +3803,10 @@ static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy, the PTK after peer joins the IBSS network*/ vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key, &setKey, sizeof(tCsrRoamSetKey)); + +#if defined (QCA_WIFI_2_0) && !defined (QCA_WIFI_ISOC) + pAdapter->sessionCtx.station.ibss_enc_key_installed = 1; +#endif return status; } if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) || @@ -6704,6 +6715,7 @@ static int wlan_hdd_cfg80211_set_privacy_ibss( pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED; vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey)); + pHddStaCtx->ibss_enc_key_installed = 0; if (params->ie_len && ( NULL != params->ie) ) { diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index c744b22fc977..8ed80d01c045 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -7701,6 +7701,8 @@ void hdd_dump_concurrency_info(hdd_context_t *pHddCtx) memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid)); } break; + case WLAN_HDD_IBSS: + return; /* skip printing station message below */ default: break; } diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index a661cdf8ef44..2e04c299a9fb 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -8700,11 +8700,11 @@ static void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info) ** So cache the BSS key in the wma_handle and re-use it when the STA key is been setup for a peer */ if (wlan_op_mode_ibss == txrx_vdev->opmode) { - WMA_LOGD("Caching IBSS Key"); - vos_mem_copy(&wma_handle->ibsskey_info, key_info, sizeof(tSetBssKeyParams)); key_info->status = eHAL_STATUS_SUCCESS; if (wma_handle->ibss_started > 0) goto out; + WMA_LOGD("Caching IBSS Key"); + vos_mem_copy(&wma_handle->ibsskey_info, key_info, sizeof(tSetBssKeyParams)); } adf_os_mem_set(&key_params, 0, sizeof(key_params)); diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index e14333b2c197..97d7a6312f27 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -5620,10 +5620,18 @@ static tANI_BOOLEAN csrRoamProcessResults( tpAniSirGlobal pMac, tSmeCmd *pComman if( CSR_IS_ENC_TYPE_STATIC( pProfile->negotiatedUCEncryptionType ) && !CSR_IS_INFRA_AP( pSession->pCurRoamProfile )) { // Issue the set Context request to LIM to establish the Broadcast STA context for the Ibss. - csrRoamIssueSetContextReq( pMac, sessionId, +#if defined (QCA_WIFI_2_0) && !defined (QCA_WIFI_ISOC) + // In Rome IBSS case, dummy key installation will break + // proper BSS key installation, so skip it. + if (!CSR_IS_IBSS( pSession->pCurRoamProfile )) +#endif + { + csrRoamIssueSetContextReq( pMac, sessionId, pProfile->negotiatedMCEncryptionType, pSirBssDesc, &BroadcastMac, FALSE, FALSE, eSIR_TX_RX, 0, 0, NULL, 0 ); // NO keys... these key parameters don't matter. + } + } } else -- cgit v1.2.3 From 84681c9150f591bdfda1f5ce7348b1cea5a29966 Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Wed, 5 Feb 2014 20:37:49 -0800 Subject: qcacld: Integrating batch scan fixes from pronto Integrating batch scan fixes from pronto to QCACLD_NEW Change-Id: I7b1a1fda2b54907a2ff182cb57ea87f75cc05139 CRs-Fixed: 611028 --- CORE/HDD/inc/wlan_hdd_main.h | 41 +++ CORE/HDD/src/wlan_hdd_hostapd.c | 7 + CORE/HDD/src/wlan_hdd_main.c | 553 +++++++++++++++++++++++----------------- CORE/SERVICES/WMA/wma.c | 22 +- 4 files changed, 382 insertions(+), 241 deletions(-) diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index 4ae0aa107893..7213c73da511 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -1379,4 +1379,45 @@ void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx); #endif int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr); + +#ifdef FEATURE_WLAN_BATCH_SCAN +/**--------------------------------------------------------------------------- + + \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING + IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled: + WLS_BATCHING VERSION + WLS_BATCHING SET + WLS_BATCHING GET + WLS_BATCHING STOP + + \param - pAdapter Pointer to HDD adapter + \param - pPrivdata Pointer to priv_data + \param - command Pointer to command + + \return - 0 for success -EFAULT for failure + + --------------------------------------------------------------------------*/ + +int hdd_handle_batch_scan_ioctl +( + hdd_adapter_t *pAdapter, + hdd_priv_data_t *pPrivdata, + tANI_U8 *command +); + +/**--------------------------------------------------------------------------- + + \brief hdd_deinit_batch_scan () - This function cleans up batch scan data + structures + + \param - pAdapter Pointer to HDD adapter + + \return - None + + --------------------------------------------------------------------------*/ + +void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter); + +#endif /*End of FEATURE_WLAN_BATCH_SCAN*/ + #endif // end #if !defined( WLAN_HDD_MAIN_H ) diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c index 1037154ac026..5dafbabe316f 100644 --- a/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/CORE/HDD/src/wlan_hdd_hostapd.c @@ -271,6 +271,12 @@ int hdd_hostapd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { hdd_setP2pOpps(dev, command); } +#ifdef FEATURE_WLAN_BATCH_SCAN + else if( strncmp(command, "WLS_BATCHING", 12) == 0 ) + { + ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command); + } +#endif /* command should be a string having format @@ -283,6 +289,7 @@ int hdd_hostapd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ret = sapSetPreferredChannel(command); } + } exit: if (command) diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 8ed80d01c045..b050ec8bc3b2 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -677,6 +677,7 @@ void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code) } + #ifdef FEATURE_WLAN_BATCH_SCAN /**--------------------------------------------------------------------------- @@ -733,7 +734,6 @@ hdd_extract_assigned_int_from_str { return NULL; } - if (tempInt < 0) { tempInt = 0; @@ -1142,6 +1142,7 @@ static void hdd_batch_scan_result_ind_callback { v_BOOL_t isLastAp; tANI_U32 numApMetaInfo; + tANI_U32 numNetworkInScanList; tANI_U32 numberScanList; tANI_U32 nextScanListOffset; tANI_U32 nextApMetaInfoOffset; @@ -1166,6 +1167,7 @@ static void hdd_batch_scan_result_ind_callback pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp; isLastAp = FALSE; numApMetaInfo = 0; + numNetworkInScanList = 0; numberScanList = 0; nextScanListOffset = 0; nextApMetaInfoOffset = 0; @@ -1195,7 +1197,7 @@ static void hdd_batch_scan_result_ind_callback while (numberScanList) { - pScanList = (tpSirBatchScanList)(pBatchScanRsp->scanResults + + pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults + nextScanListOffset); if (NULL == pScanList) { @@ -1204,9 +1206,10 @@ static void hdd_batch_scan_result_ind_callback isLastAp = TRUE; goto done; } - numApMetaInfo = pScanList->numNetworksInScanList; + numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList; VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "Batch scan rsp: numApMetaInfo %d", numApMetaInfo); + "Batch scan rsp: numApMetaInfo %d scanId %d", + numApMetaInfo, pScanList->scanId); if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork)) { @@ -1216,6 +1219,9 @@ static void hdd_batch_scan_result_ind_callback goto done; } + /*Initialize next AP meta info offset for next scan list*/ + nextApMetaInfoOffset = 0; + while (numApMetaInfo) { pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList + @@ -1232,13 +1238,11 @@ static void hdd_batch_scan_result_ind_callback pBatchScanRsp->timestamp - pApMetaInfo->timestamp; VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, - "%s: bssId 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x " - "ch %d rssi %d timestamp %d", __func__, - pApMetaInfo->bssid[0],pApMetaInfo->bssid[1], - pApMetaInfo->bssid[2],pApMetaInfo->bssid[3], - pApMetaInfo->bssid[4],pApMetaInfo->bssid[5], - pApMetaInfo->ch, pApMetaInfo->rssi, - pApMetaInfo->timestamp); + "%s: bssId "MAC_ADDRESS_STR + " ch %d rssi %d timestamp %d", __func__, + MAC_ADDR_ARRAY(pApMetaInfo->bssid), + pApMetaInfo->ch, pApMetaInfo->rssi, + pApMetaInfo->timestamp); /*mark last AP in batch scan response*/ if ((TRUE == pBatchScanRsp->isLastResult) && @@ -1257,7 +1261,9 @@ static void hdd_batch_scan_result_ind_callback numApMetaInfo--; } - nextScanListOffset += (sizeof(tSirBatchScanList) - (sizeof(tANI_U8))); + nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8)) + + (sizeof(tSirBatchScanNetworkInfo) + * numNetworkInScanList)); numberScanList--; } @@ -1490,6 +1496,7 @@ tANI_U32 hdd_populate_user_batch_scan_rsp pAdapter->prev_batch_id = pPrev->ApInfo.batchId; } vos_mem_free(pPrev); + pPrev = NULL; } return cur_len; @@ -1572,11 +1579,11 @@ int hdd_return_batch_scan_rsp_to_user rc = wait_for_completion_timeout( &pAdapter->hdd_get_batch_scan_req_var, msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT)); - if (0 == rc) + if (0 >= rc) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s: Timeout waiting to fetch batch scan rsp from fw", - __func__); + "%s: wait on hdd_get_batch_scan_req_var failed %ld", + __func__, rc); return -EFAULT; } } @@ -1643,6 +1650,242 @@ int hdd_return_batch_scan_rsp_to_user return 0; } /*End of hdd_return_batch_scan_rsp_to_user*/ +/**--------------------------------------------------------------------------- + + \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING + IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled: + WLS_BATCHING VERSION + WLS_BATCHING SET + WLS_BATCHING GET + WLS_BATCHING STOP + + \param - pAdapter Pointer to HDD adapter + \param - pPrivdata Pointer to priv_data + \param - command Pointer to command + + \return - 0 for success -EFAULT for failure + + --------------------------------------------------------------------------*/ + +int hdd_handle_batch_scan_ioctl +( + hdd_adapter_t *pAdapter, + hdd_priv_data_t *pPrivdata, + tANI_U8 *command +) +{ + int ret = 0; + + if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0) + { + char extra[32]; + tANI_U8 len = 0; + tANI_U8 version = HDD_BATCH_SCAN_VERSION; + + if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Batch scan feature is not supported by FW", __func__); + ret = -EINVAL; + goto exit; + } + + len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d", + version); + if (copy_to_user(pPrivdata->buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + ret = HDD_BATCH_SCAN_VERSION; + } + else if (strncmp(command, "WLS_BATCHING SET", 16) == 0) + { + int status; + tANI_U8 *value = (command + 16); + eHalStatus halStatus; + unsigned long rc; + tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq; + tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp; + + if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Batch scan feature is not supported by FW", __func__); + ret = -EINVAL; + goto exit; + } + + if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) && + (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) && + (WLAN_HDD_P2P_GO != pAdapter->device_mode) && + (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Received WLS_BATCHING SET command in invalid mode %d " + "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode", + pAdapter->device_mode); + ret = -EINVAL; + goto exit; + } + + status = hdd_parse_set_batchscan_command(value, pReq); + if (status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid WLS_BATCHING SET command"); + ret = -EINVAL; + goto exit; + } + + + pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE; + halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq, + pAdapter->sessionId, hdd_set_batch_scan_req_callback, + pAdapter); + + if ( eHAL_STATUS_SUCCESS == halStatus ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "sme_SetBatchScanReq returned success halStatus %d", + halStatus); + if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp) + { + INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var); + rc = wait_for_completion_timeout( + &pAdapter->hdd_set_batch_scan_req_var, + msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT)); + if (0 == rc) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout waiting for set batch scan to complete", + __func__); + ret = -EINVAL; + goto exit; + } + } + if ( !pRsp->nScansToBatch ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Received set batch scan failure response from FW", + __func__); + ret = -EINVAL; + goto exit; + } + /*As per the Batch Scan Framework API we should return the MIN of + either MSCAN or the max # of scans firmware can cache*/ + ret = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch); + + pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: request MSCAN %d response MSCAN %d ret %d", + __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, ret); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_SetBatchScanReq returned failure halStatus %d", + halStatus); + ret = -EINVAL; + goto exit; + } + } + else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0) + { + eHalStatus halStatus; + tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd; + pInd->param = 0; + + if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Batch scan feature is not supported by FW", __func__); + ret = -EINVAL; + goto exit; + } + + if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Batch scan is not yet enabled batch scan state %d", + pAdapter->batchScanState); + ret = -EINVAL; + goto exit; + } + + mutex_lock(&pAdapter->hdd_batch_scan_lock); + hdd_deinit_batch_scan(pAdapter); + mutex_unlock(&pAdapter->hdd_batch_scan_lock); + + pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED; + + halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd, + pAdapter->sessionId); + if ( eHAL_STATUS_SUCCESS == halStatus ) + { + ret = 0; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "sme_StopBatchScanInd returned success halStatus %d", + halStatus); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_StopBatchScanInd returned failure halStatus %d", + halStatus); + ret = -EINVAL; + goto exit; + } + } + else if (strncmp(command, "WLS_BATCHING GET", 16) == 0) + { + tANI_U32 remain_len; + + if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Batch scan feature is not supported by FW", __func__); + ret = -EINVAL; + goto exit; + } + + if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Batch scan is not yet enabled could not return results" + "Batch Scan state %d", + pAdapter->batchScanState); + ret = -EINVAL; + goto exit; + } + + pPrivdata->used_len = 16; + remain_len = pPrivdata->total_len - pPrivdata->used_len; + if (remain_len < pPrivdata->total_len) + { + /*Clear previous batch scan response data if any*/ + vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid total length from user space can't fetch batch" + " scan response total_len %d used_len %d remain len %d", + pPrivdata->total_len, pPrivdata->used_len, remain_len); + ret = -EINVAL; + goto exit; + } + ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command); + } + +exit: + + return ret; +} + #endif/*End of FEATURE_WLAN_BATCH_SCAN*/ /**--------------------------------------------------------------------------- @@ -3801,218 +4044,14 @@ int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams); } -#ifdef FEATURE_WLAN_BATCH_SCAN - else if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0) - { - char extra[32]; - tANI_U8 len = 0; - tANI_U8 version = HDD_BATCH_SCAN_VERSION; - - if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s: Batch scan feature is not supported by FW", __func__); - ret = -EINVAL; - goto exit; - } - - if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) && - (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) && - (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode)) - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "Received WLS_BATCHING_VERSION command in invalid mode %d " - "WLS_BATCHING_VERSION is only allowed in infra STA/P2P client" - " mode", - pAdapter->device_mode); - ret = -EINVAL; - goto exit; - } - - len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d", - version); - if (copy_to_user(priv_data.buf, &extra, len + 1)) - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s: failed to copy data to user buffer", __func__); - ret = -EFAULT; - goto exit; - } - ret = HDD_BATCH_SCAN_VERSION; - } - else if (strncmp(command, "WLS_BATCHING SET", 16) == 0) - { - int status; - tANI_U8 *value = (command + 16); - eHalStatus halStatus; - unsigned long rc; - tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq; - tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp; - - if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s: Batch scan feature is not supported by FW", __func__); - ret = -EINVAL; - goto exit; - } - - if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) && - (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) && - (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode)) - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "Received WLS_BATCHING SET command in invalid mode %d " - "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode", - pAdapter->device_mode); - ret = -EINVAL; - goto exit; - } - - status = hdd_parse_set_batchscan_command(value, pReq); - if (status) - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "Invalid WLS_BATCHING SET command"); - ret = -EINVAL; - goto exit; - } - pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE; - halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq, - pAdapter->sessionId, hdd_set_batch_scan_req_callback, - pAdapter); - - if ( eHAL_STATUS_SUCCESS == halStatus ) - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, - "sme_SetBatchScanReq returned success halStatus %d", - halStatus); - if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp) - { - INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var); - rc = wait_for_completion_timeout( - &pAdapter->hdd_set_batch_scan_req_var, - msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT)); - if (0 == rc) - { - VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s: Timeout waiting for set batch scan to complete", - __func__); - ret = -EINVAL; - goto exit; - } - } - if ( !pRsp->nScansToBatch ) - { - VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s: Received set batch scan failure response from FW", - __func__); - ret = -EINVAL; - goto exit; - } - /*As per the Batch Scan Framework API we should return the MIN of - either MSCAN or the max # of scans firmware can cache*/ - ret = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch); - - pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED; - - VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s: request MSCAN %d response MSCAN %d ret %d", - __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, ret); - } - else - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "sme_SetBatchScanReq returned failure halStatus %d", - halStatus); - ret = -EINVAL; - goto exit; - } - } - else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0) - { - eHalStatus halStatus; - tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd; - pInd->param = 0; - - if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s: Batch scan feature is not supported by FW", __func__); - ret = -EINVAL; - goto exit; - } - - if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState) - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "Batch scan is not yet enabled batch scan state %d", - pAdapter->batchScanState); - ret = -EINVAL; - goto exit; - } - pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED; - - halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd, - pAdapter->sessionId); - if ( eHAL_STATUS_SUCCESS == halStatus ) - { - ret = 0; - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, - "sme_StopBatchScanInd returned success halStatus %d", - halStatus); - } - else - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "sme_StopBatchScanInd returned failure halStatus %d", - halStatus); - ret = -EINVAL; - goto exit; - } - } - else if (strncmp(command, "WLS_BATCHING GET", 16) == 0) +#ifdef FEATURE_WLAN_BATCH_SCAN + else if (strncmp(command, "WLS_BATCHING", 12) == 0) { - tANI_U32 remain_len; - - if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "%s: Batch scan feature is not supported by FW", __func__); - ret = -EINVAL; - goto exit; - } - - if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState) - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "Batch scan is not yet enabled could not return results" - "Batch Scan state %d", - pAdapter->batchScanState); - ret = -EINVAL; - goto exit; - } - - priv_data.used_len = 16; - remain_len = priv_data.total_len - priv_data.used_len; - if (remain_len < priv_data.total_len) - { - /*Clear previous batch scan response data if any*/ - vos_mem_zero((tANI_U8 *)(command + priv_data.used_len), remain_len); - } - else - { - VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, - "Invalid total length from user space can't fetch batch" - " scan response total_len %d used_len %d remain len %d", - priv_data.total_len, priv_data.used_len, remain_len); - ret = -EINVAL; - goto exit; - } - ret = hdd_return_batch_scan_rsp_to_user(pAdapter, &priv_data, command); + ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command); } #endif + #if defined(FEATURE_WLAN_CCX) && defined(FEATURE_WLAN_CCX_UPLOAD) else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0) { @@ -6690,11 +6729,6 @@ void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_ { struct net_device *pWlanDev = NULL; -#ifdef FEATURE_WLAN_BATCH_SCAN - tHddBatchScanRsp *pNode; - tHddBatchScanRsp *pPrev; -#endif - if (pAdapter) pWlanDev = pAdapter->dev; else { @@ -6704,14 +6738,20 @@ void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_ } #ifdef FEATURE_WLAN_BATCH_SCAN - pNode = pAdapter->pBatchScanRsp; - while (pNode) + if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) + || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) + ) + { + if (pAdapter) { - pPrev = pNode; - pNode = pNode->pNext; - vos_mem_free((v_VOID_t * )pPrev); + if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState) + { + hdd_deinit_batch_scan(pAdapter); + } } - pAdapter->pBatchScanRsp = NULL; + } #endif if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) { @@ -7473,6 +7513,44 @@ VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx ) return VOS_STATUS_SUCCESS; } +#ifdef FEATURE_WLAN_BATCH_SCAN +/**--------------------------------------------------------------------------- + + \brief hdd_deinit_batch_scan () - This function cleans up batch scan data + structures + + \param - pAdapter Pointer to HDD adapter + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter) +{ + tHddBatchScanRsp *pNode; + tHddBatchScanRsp *pPrev; + + if (pAdapter) + { + pNode = pAdapter->pBatchScanRsp; + while (pNode) + { + pPrev = pNode; + pNode = pNode->pNext; + vos_mem_free((v_VOID_t * )pPrev); + } + pAdapter->pBatchScanRsp = NULL; + } + + pAdapter->pBatchScanRsp = NULL; + pAdapter->numScanList = 0; + pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED; + pAdapter->prev_batch_id = 0; + + return; +} +#endif + + VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx ) { hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; @@ -7498,6 +7576,13 @@ VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx ) clear_bit(WMM_INIT_DONE, &pAdapter->event_flags); } +#ifdef FEATURE_WLAN_BATCH_SCAN + if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState) + { + hdd_deinit_batch_scan(pAdapter); + } +#endif + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); pAdapterNode = pNext; } diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 2e04c299a9fb..765254829b51 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -15114,13 +15114,13 @@ wma_batch_scan_result_event_handler tSirBatchScanResultIndParam *pHddResult; tSirBatchScanNetworkInfo *pHddApMetaInfo; tp_wma_handle wma = (tp_wma_handle) handle; - u_int32_t nextScanListOffset, nextApMetaInfoOffset; - u_int8_t bssid[IEEE80211_ADDR_LEN], ssid[33], *ssid_temp; - u_int32_t temp, count1, count2, scan_num, netinfo_num, total_size; - WMI_BATCH_SCAN_RESULT_EVENTID_param_tlvs *param_tlvs; - wmi_batch_scan_result_event_fixed_param *fix_param; wmi_batch_scan_result_scan_list *scan_list; wmi_batch_scan_result_network_info *network_info; + wmi_batch_scan_result_event_fixed_param *fix_param; + WMI_BATCH_SCAN_RESULT_EVENTID_param_tlvs *param_tlvs; + u_int8_t bssid[IEEE80211_ADDR_LEN], ssid[33], *ssid_temp; + u_int32_t temp, count1, count2, scan_num, netinfo_num, total_size; + u_int32_t nextScanListOffset, nextApMetaInfoOffset, numNetworkInScanList; tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE, wma->vos_context); @@ -15192,12 +15192,18 @@ wma_batch_scan_result_event_handler network_info = param_tlvs->network_list; nextScanListOffset = 0; nextApMetaInfoOffset = 0; + numNetworkInScanList = 0; + for(count1 = 0; count1 < scan_num; count1++) { - pHddScanList = (tSirBatchScanList *)(pHddResult->scanResults + + pHddScanList = (tSirBatchScanList *)((tANI_U8 *)pHddResult->scanResults + nextScanListOffset); pHddScanList->scanId = scan_list->scanId; pHddScanList->numNetworksInScanList = scan_list->numNetworksInScanList; + numNetworkInScanList = pHddScanList->numNetworksInScanList; + + /*Initialize next AP meta info offset for next scan list*/ + nextApMetaInfoOffset = 0; for (count2 = 0; count2 < scan_list->numNetworksInScanList; count2++) { @@ -15242,7 +15248,9 @@ wma_batch_scan_result_event_handler network_info++; } - nextScanListOffset += (sizeof(tSirBatchScanList) - (sizeof(tANI_U8))); + nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8)) + + (sizeof(tSirBatchScanNetworkInfo) + * numNetworkInScanList)); scan_list++; } -- cgit v1.2.3 From ded58968277eea8bcdcf2eafb11198c6b7deb538 Mon Sep 17 00:00:00 2001 From: Sameer Thalappil Date: Wed, 5 Feb 2014 20:42:02 -0800 Subject: qcacld: Silent recovery on FW dump failure When host fails to collect dump on FW assert, there is no reason to put device to download mode when SSR level is set to system. So instead of going thru SSR framework, silently recover from this assert. Change-Id: Ib8af1d25b3d0a66004984e1ffdbedfa19c71f175 CRs-Fixed: 612268 --- CORE/SERVICES/BMI/ol_fw.c | 39 +++++++++++++++++++++++++++------------ CORE/SERVICES/BMI/ol_fw.h | 4 ++-- CORE/SERVICES/HIF/PCIe/if_pci.c | 9 +++++---- CORE/SERVICES/HIF/PCIe/if_pci.h | 2 +- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/CORE/SERVICES/BMI/ol_fw.c b/CORE/SERVICES/BMI/ol_fw.c index 29e55d563dc5..515bdc81a3bf 100644 --- a/CORE/SERVICES/BMI/ol_fw.c +++ b/CORE/SERVICES/BMI/ol_fw.c @@ -492,7 +492,7 @@ u_int32_t host_interest_item_address(u_int32_t target_type, u_int32_t item_offse } #if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) -void dump_CE_register(struct ol_softc *scn) +int dump_CE_register(struct ol_softc *scn) { A_UINT32 CE_reg_address = CE7_LOCATION; A_UINT32 CE_reg_values[CE_USEFUL_SIZE>>2]; @@ -504,13 +504,14 @@ void dump_CE_register(struct ol_softc *scn) CE_reg_word_size * sizeof(A_UINT32)) != A_OK) { printk(KERN_ERR "Dumping CE register failed!\n"); - return; + return -EACCES; } printk("CE7 Register Dump:\n"); for (i = 0; i < CE_reg_word_size; i++) { printk("[%02d] : 0x%08X\n", i, CE_reg_values[i]); } + return EOK; } #endif @@ -522,15 +523,21 @@ static void ramdump_work_handler(struct work_struct *ramdump) void __iomem *ramdump_base; unsigned long address; unsigned long size; + int ret; u_int32_t host_interest_address; if (!ramdump_scn) { printk("No RAM dump will be collected since ramdump_scn is NULL!\n"); - goto out; + goto out_fail; } - hif_pci_check_soc_status(ramdump_scn->hif_sc); - dump_CE_register(ramdump_scn); + ret = hif_pci_check_soc_status(ramdump_scn->hif_sc); + if (ret) + goto out_fail; + + ret = dump_CE_register(ramdump_scn); + if (ret) + goto out_fail; if (HIFDiagReadMem(ramdump_scn->hif_hdl, host_interest_item_address(ramdump_scn->target_type, @@ -539,7 +546,7 @@ static void ramdump_work_handler(struct work_struct *ramdump) printk(KERN_ERR "HifDiagReadiMem FW Dump Area Pointer failed!\n"); dump_CE_register(ramdump_scn); - goto out; + goto out_fail; } printk("Host interest item address: 0x%08X\n", host_interest_address); @@ -547,25 +554,30 @@ static void ramdump_work_handler(struct work_struct *ramdump) if (cnss_get_ramdump_mem(&address, &size)) { printk("No RAM dump will be collected since failed to get " "memory address or size!\n"); - goto out; + goto out_fail; } ramdump_base = ioremap(address, size); if (!ramdump_base) { printk("No RAM dump will be collected since ramdump_base is NULL!\n"); - goto out; + goto out_fail; } - ol_target_coredump(ramdump_scn, ramdump_base, TOTAL_DUMP_SIZE); + ret = ol_target_coredump(ramdump_scn, ramdump_base, TOTAL_DUMP_SIZE); iounmap(ramdump_base); + if (ret) + goto out_fail; printk("%s: RAM dump collecting completed!\n", __func__); msleep(250); - -out: /* Notify SSR framework the target has crashed. */ cnss_device_crashed(); return; + +out_fail: + /* silent SSR on dump failure */ + cnss_device_self_recovery(); + return; } static DECLARE_WORK(ramdump_work, ramdump_work_handler); @@ -1003,11 +1015,12 @@ int ol_diag_read(struct ol_softc *scn, u_int8_t *buffer, * * \return: None * --------------------------------------------------------------------------*/ -void ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength) +int ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength) { struct ol_softc *scn = (struct ol_softc *)inst; char *bufferLoc = memoryBlock; int result = 0; + int ret = 0; u_int32_t amountRead = 0; u_int32_t sectionCount = 0; u_int32_t pos = 0; @@ -1055,6 +1068,7 @@ void ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength) } else { printk(KERN_ERR "Could not read dump section!\n"); dump_CE_register(scn); + ret = -EACCES; break; /* Could not read the section */ } } else { @@ -1062,6 +1076,7 @@ void ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength) break; /* Insufficient room in buffer */ } } + return ret; } #endif diff --git a/CORE/SERVICES/BMI/ol_fw.h b/CORE/SERVICES/BMI/ol_fw.h index 1b5f9f296269..f15e2d3b501f 100644 --- a/CORE/SERVICES/BMI/ol_fw.h +++ b/CORE/SERVICES/BMI/ol_fw.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -68,7 +68,7 @@ #define TOTAL_DUMP_SIZE 0x00200000 #define PCIE_READ_LIMIT 0x00005000 -void ol_target_coredump(void *instance, void* memoryBlock, +int ol_target_coredump(void *instance, void* memoryBlock, u_int32_t blockLength); int ol_diag_read(struct ol_softc *scn, u_int8_t* buffer, u_int32_t pos, size_t count); diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c index 4b5e32bd863d..90b4ccab0b28 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.c +++ b/CORE/SERVICES/HIF/PCIe/if_pci.c @@ -331,8 +331,8 @@ hif_pci_device_warm_reset(struct hif_pci_softc *sc) } -void -hif_pci_check_soc_status(struct hif_pci_softc *sc) + +int hif_pci_check_soc_status(struct hif_pci_softc *sc) { u_int16_t device_id; u_int32_t val; @@ -342,7 +342,7 @@ hif_pci_check_soc_status(struct hif_pci_softc *sc) pci_read_config_word(sc->pdev, PCI_DEVICE_ID, &device_id); if(device_id != sc->devid) { printk(KERN_ERR "PCIe link is down!\n"); - return; + return -EACCES; } /* Check PCIe local register for bar/memory access */ @@ -365,7 +365,7 @@ hif_pci_check_soc_status(struct hif_pci_softc *sc) A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + RTC_STATE_ADDRESS), A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS)); - return; + return -EACCES; } A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + @@ -378,6 +378,7 @@ hif_pci_check_soc_status(struct hif_pci_softc *sc) /* Check BAR + 0x10c register for SoC internal bus issues */ val = A_PCI_READ32(sc->mem + 0x10c); printk("BAR + 0x10c is %08x\n", val); + return EOK; } /* diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.h b/CORE/SERVICES/HIF/PCIe/if_pci.h index ee3fb120c040..d3955f7f0e5a 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.h +++ b/CORE/SERVICES/HIF/PCIe/if_pci.h @@ -121,7 +121,7 @@ extern int pktlogmod_init(void *context); extern void pktlogmod_exit(void *context); #endif -void hif_pci_check_soc_status(struct hif_pci_softc *sc); +int hif_pci_check_soc_status(struct hif_pci_softc *sc); /* * A firmware interrupt to the Host is indicated by the -- cgit v1.2.3 From eeefa49ffef6ce19df389631a753469e09b514c5 Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Tue, 28 Jan 2014 13:55:55 -0800 Subject: qcacld: Add function of updating macaddress from wlan_mac.bin In FTM mode, user defined macaddresses might be provided. The new macaddress will be written into /persist/wlan_mac.bin. Add function of updating macaddress from wlan_mac.bin. Overwrite default ini macaddress if wlan_mac.bin exist. Change-Id: I78ab0104fc5cae456c8fd8dc3df2029cdecf7214 CRs-Fixed: 605901 --- Android.mk | 1 + CORE/HDD/inc/wlan_hdd_cfg.h | 1 + CORE/HDD/src/wlan_hdd_cfg.c | 110 ++++++++++++++++++++++++++++++++++++++++++ CORE/HDD/src/wlan_hdd_main.c | 11 ++++- CORE/VOSS/inc/wlan_hdd_misc.h | 3 +- 5 files changed, 123 insertions(+), 3 deletions(-) diff --git a/Android.mk b/Android.mk index d3dfafce1fe0..f86c223bcb1e 100644 --- a/Android.mk +++ b/Android.mk @@ -72,6 +72,7 @@ include $(DLKM_DIR)/AndroidKernelModule.mk $(shell mkdir -p $(TARGET_OUT)/lib/modules; \ ln -sf /system/lib/modules/$(WLAN_CHIPSET)/$(WLAN_CHIPSET)_wlan.ko \ $(TARGET_OUT)/lib/modules/wlan.ko) +$(shell ln -sf /persist/wlan_mac.bin $(TARGET_OUT_ETC)/firmware/wlan/qca_cld/wlan_mac.bin) endif # DLKM check diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index a3ffb79c0d78..b030c4bc3eb8 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -2675,6 +2675,7 @@ typedef struct Function declarations and documenation -------------------------------------------------------------------------*/ VOS_STATUS hdd_parse_config_ini(hdd_context_t *pHddCtx); +VOS_STATUS hdd_update_mac_config(hdd_context_t *pHddCtx); VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx ); VOS_STATUS hdd_set_sme_chan_list(hdd_context_t *hdd_ctx); v_BOOL_t hdd_update_config_dat ( hdd_context_t *pHddCtx ); diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c index 229efded8ef8..4d71b707cb41 100644 --- a/CORE/HDD/src/wlan_hdd_cfg.c +++ b/CORE/HDD/src/wlan_hdd_cfg.c @@ -3633,6 +3633,116 @@ static int parseHexDigit(char c) return 0; } +/* convert string to 6 bytes mac address + * 00AA00BB00CC -> 0x00 0xAA 0x00 0xBB 0x00 0xCC + */ +static void update_mac_from_string(hdd_context_t *pHddCtx, tCfgIniEntry *macTable, int num) +{ + int i = 0, j = 0, res = 0; + char *candidate = NULL; + v_MACADDR_t macaddr[VOS_MAX_CONCURRENCY_PERSONA]; + + memset(macaddr, 0, sizeof(macaddr)); + + for (i = 0; i < num; i++) + { + candidate = macTable[i].value; + for (j = 0; j < VOS_MAC_ADDR_SIZE; j++) { + res = hex2bin(&macaddr[i].bytes[j], &candidate[(j<<1)], 1); + if (res < 0) + break; + } + if (res == 0 && !vos_is_macaddr_zero(&macaddr[i])) { + vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], + (v_U8_t *)&macaddr[i].bytes[0], VOS_MAC_ADDR_SIZE); + } + } +} + +/* + * This function tries to update macaddress from cfg file. + * It overwrites the MAC address if config file exist. + */ +VOS_STATUS hdd_update_mac_config(hdd_context_t *pHddCtx) +{ + int status, i = 0; + const struct firmware *fw = NULL; + char *line, *buffer = NULL; + char *name, *value; + tCfgIniEntry macTable[VOS_MAX_CONCURRENCY_PERSONA]; + + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + memset(macTable, 0, sizeof(macTable)); + status = request_firmware(&fw, WLAN_MAC_FILE, pHddCtx->parent_dev); + + if (status) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: request_firmware failed %d\n", + __func__, status); + vos_status = VOS_STATUS_E_FAILURE; + goto config_exit; + } + if (!fw || !fw->data || !fw->size) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: invalid firmware\n", __func__); + vos_status = VOS_STATUS_E_INVAL; + goto config_exit; + } + + buffer = (char *)fw->data; + + /* data format: + * Intf0MacAddress=00AA00BB00CC + * Intf1MacAddress=00AA00BB00CD + * END + */ + while (buffer != NULL) + { + line = get_next_line(buffer); + buffer = i_trim(buffer); + + if (strlen((char *)buffer) == 0 || *buffer == '#') { + buffer = line; + continue; + } + if (strncmp(buffer, "END", 3) == 0) + break; + + name = buffer; + buffer = strchr(buffer, '='); + if (buffer) { + *buffer++ = '\0'; + i_trim(name); + if (strlen(name) != 0) { + buffer = i_trim(buffer); + if (strlen(buffer) == 12) { + value = buffer; + macTable[i].name = name; + macTable[i++].value = value; + if (i >= VOS_MAX_CONCURRENCY_PERSONA) + break; + } + } + } + buffer = line; + } + if (i <= VOS_MAX_CONCURRENCY_PERSONA) { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: %d Mac addresses provided\n", __func__, i); + } + else { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: invalid number of Mac address provided, nMac = %d\n", + __func__, i); + vos_status = VOS_STATUS_E_INVAL; + goto config_exit; + } + + update_mac_from_string(pHddCtx, &macTable[0], i); + +config_exit: + release_firmware(fw); + return vos_status; +} static VOS_STATUS hdd_apply_cfg_ini( hdd_context_t *pHddCtx, tCfgIniEntry* iniTable, unsigned long entries) { diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index b050ec8bc3b2..7beee7f9d478 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -9108,8 +9108,15 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) goto err_config; } - pHddCtx->current_intf_count=0; - pHddCtx->max_intf_count = WLAN_MAX_INTERFACES; + if ( VOS_STATUS_SUCCESS != hdd_update_mac_config( pHddCtx ) ) + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: can't update mac config, using MAC from ini file", + __func__); + } + + pHddCtx->current_intf_count=0; + pHddCtx->max_intf_count = WLAN_MAX_INTERFACES; #ifndef QCA_WIFI_2_0 pHddCtx->cfg_ini->maxWoWFilters = WOWL_MAX_PTRNS_ALLOWED; diff --git a/CORE/VOSS/inc/wlan_hdd_misc.h b/CORE/VOSS/inc/wlan_hdd_misc.h index ec623a153be9..232161f64c5b 100644 --- a/CORE/VOSS/inc/wlan_hdd_misc.h +++ b/CORE/VOSS/inc/wlan_hdd_misc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -38,6 +38,7 @@ #define WLAN_DICT_FILE "wlan/qca_cld/WCNSS_qcom_wlan_dictionary.dat" #define WLAN_COUNTRY_INFO_FILE "wlan/qca_cld/WCNSS_wlan_country_info.dat" #define WLAN_HO_CFG_FILE "wlan/qca_cld/WCNSS_wlan_ho_config" +#define WLAN_MAC_FILE "wlan/qca_cld/wlan_mac.bin" #else #define WLAN_INI_FILE "wlan/prima/WCNSS_qcom_cfg.ini" #define WLAN_CFG_FILE "wlan/prima/WCNSS_cfg.dat" -- cgit v1.2.3 From 0f41098d4e100728d0bae03392f4cbb227e71473 Mon Sep 17 00:00:00 2001 From: Prashanth Bhatta Date: Thu, 6 Feb 2014 12:05:58 -0800 Subject: qcacld: ipa: Remove IPA_RM_RESOURCE_A2_CONS usage Per IPA team, IPA_RM_RESOURCE_A2_CONS constant is not required any more. Removing it from WLAN IPA code. Change-Id: Ia737a0253bc04184bf5e5e9e80b6eb0eb29b3644 --- CORE/HDD/src/wlan_hdd_ipa.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c index 77a7b818f86a..5965f7892afc 100644 --- a/CORE/HDD/src/wlan_hdd_ipa.c +++ b/CORE/HDD/src/wlan_hdd_ipa.c @@ -386,8 +386,6 @@ static void hdd_ipa_destory_rm_resource(struct hdd_ipa_priv *hdd_ipa) if (!hdd_ipa_is_rm_enabled(hdd_ipa)) return; - ipa_rm_delete_dependency(IPA_RM_RESOURCE_WLAN_PROD, - IPA_RM_RESOURCE_A2_CONS); #ifdef HDD_IPA_USE_IPA_RM_TIMER ipa_rm_inactivity_timer_destroy(IPA_RM_RESOURCE_WLAN_PROD); #endif -- cgit v1.2.3 From 6470743622fefeab82e630b99d083087dd4cfedd Mon Sep 17 00:00:00 2001 From: Prashanth Bhatta Date: Thu, 30 Jan 2014 11:32:40 -0800 Subject: qcacld: ipa: Add interface specific changes IPA implementation was added for pipe based implementation but lately design got changed due to various throughput optimization to achieve high throughput. But the optimization did not account interface based implementation and hence concurrency cases like STA-AP mode wasn't working. Now the implementation is interface based and concurrency of STA-AP, AP-AP and STA-AP-AP can be supported with none or minimum changes to IPA. Also fixed issues related to IPA header installation. Change-Id: I1c77fd2f46218aed6dfb898e3cdc28d1f7987a19 CRs-fixed: 606551 --- CORE/CLD_TXRX/TLSHIM/tl_shim.c | 50 ++ CORE/CLD_TXRX/TLSHIM/tl_shim.h | 5 + CORE/HDD/inc/wlan_hdd_ipa.h | 12 +- CORE/HDD/inc/wlan_hdd_main.h | 3 + CORE/HDD/src/wlan_hdd_assoc.c | 10 +- CORE/HDD/src/wlan_hdd_hostapd.c | 8 +- CORE/HDD/src/wlan_hdd_ipa.c | 1215 +++++++++++++++++++-------------------- CORE/VOSS/src/vos_trace.c | 7 +- 8 files changed, 685 insertions(+), 625 deletions(-) diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c index ef00f2d6fe26..b3df3a7f9f5c 100644 --- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c +++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c @@ -1575,3 +1575,53 @@ VOS_STATUS tl_shim_get_vdevid(struct ol_txrx_peer_t *peer, u_int8_t *vdev_id) *vdev_id = peer->vdev->vdev_id; return VOS_STATUS_SUCCESS; } + +/* + * Function to get vdev(tl_context) given the MAC address. + */ +void *tl_shim_get_vdev_by_addr(void *vos_context, uint8_t *mac_addr) +{ + struct ol_txrx_peer_t *peer = NULL; + ol_txrx_pdev_handle pdev = NULL; + uint8_t peer_id; + + if (vos_context == NULL || mac_addr == NULL) { + TLSHIM_LOGE("Invalid argument %p, %p", vos_context, mac_addr); + return NULL; + } + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos_context); + peer = ol_txrx_find_peer_by_addr(pdev, mac_addr, &peer_id); + + if (!peer) { + TLSHIM_LOGE("PEER [%pM] not found", mac_addr); + return NULL; + } + + return peer->vdev; +} + +/* + * Function to get vdev(tl_context) given the TL station ID. + */ +void *tl_shim_get_vdev_by_sta_id(void *vos_context, uint8_t sta_id) +{ + struct ol_txrx_peer_t *peer = NULL; + ol_txrx_pdev_handle pdev = NULL; + + if (sta_id >= WLAN_MAX_STA_COUNT) { + TLSHIM_LOGE("Invalid sta id passed"); + return NULL; + } + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos_context); + + peer = ol_txrx_peer_find_by_local_id(pdev, sta_id); + + if (!peer) { + TLSHIM_LOGE("PEER [%d] not found", sta_id); + return NULL; + } + + return peer->vdev; +} diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.h b/CORE/CLD_TXRX/TLSHIM/tl_shim.h index a5d8fa836a3c..31084662b82b 100644 --- a/CORE/CLD_TXRX/TLSHIM/tl_shim.h +++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.h @@ -28,6 +28,9 @@ #ifndef TXRX_TL_SHIM_H #define TXRX_TL_SHIM_H +#include +#include + #ifdef FEATURE_WLAN_CCX typedef struct deferred_iapp_work { pVosContextType pVosGCtx; @@ -86,5 +89,7 @@ VOS_STATUS tl_shim_get_vdevid(struct ol_txrx_peer_t *peer, u_int8_t *vdev_id); * BETTER_AP_FOUND event is received from roam engine. */ int tlshim_mgmt_roam_event_ind(void *context, u_int32_t vdev_id); +void *tl_shim_get_vdev_by_addr(void *vos_context, uint8_t *mac_addr); +void *tl_shim_get_vdev_by_sta_id(void *vos_context, uint8_t sta_id); #endif diff --git a/CORE/HDD/inc/wlan_hdd_ipa.h b/CORE/HDD/inc/wlan_hdd_ipa.h index d0c532f945e0..aaac547e70ce 100644 --- a/CORE/HDD/inc/wlan_hdd_ipa.h +++ b/CORE/HDD/inc/wlan_hdd_ipa.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -44,12 +44,12 @@ #ifdef IPA_OFFLOAD #include -VOS_STATUS hdd_ipa_init(hdd_context_t *pHddCtx); -VOS_STATUS hdd_ipa_cleanup(hdd_context_t *pHddCtx); -int hdd_ipa_wlan_evt(void *pAdapter, uint8_t sta_id, - enum ipa_wlan_event type, uint8_t *mac_addr); +VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx); +VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx); +int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, + enum ipa_wlan_event type, uint8_t *mac_addr); VOS_STATUS hdd_ipa_process_rxt(v_VOID_t *vosContext, adf_nbuf_t rxBuf, - v_U8_t staId); + v_U8_t sta_id); bool hdd_ipa_is_enabled(hdd_context_t *pHddCtx); #endif diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index 7213c73da511..0f741496f550 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -1026,6 +1026,9 @@ struct hdd_adapter_s #ifdef QCA_WIFI_2_0 v_BOOL_t internalCancelRemainOnChReq; #endif +#ifdef IPA_OFFLOAD + void *ipa_context; +#endif }; #define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station) diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index f07a5df4674c..30dc08dd1d77 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -813,8 +813,8 @@ static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo * #ifdef IPA_OFFLOAD if (hdd_ipa_is_enabled(pHddCtx)) - hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0], - WLAN_STA_DISCONNECT, pAdapter->dev->dev_addr); + hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0], + WLAN_STA_DISCONNECT, pHddStaCtx->conn_info.bssId); #endif if(pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting) @@ -1299,9 +1299,9 @@ static eHalStatus hdd_AssociationCompletionHandler( hdd_adapter_t *pAdapter, tCs pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter; #ifdef IPA_OFFLOAD - if (hdd_ipa_is_enabled(pHddCtx)) - hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId, WLAN_STA_CONNECT, - pAdapter->dev->dev_addr); + if (hdd_ipa_is_enabled(pHddCtx)) + hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId, WLAN_STA_CONNECT, + pRoamInfo->bssid); #endif #ifdef FEATURE_WLAN_TDLS diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c index 5dafbabe316f..3518e8f62882 100644 --- a/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/CORE/HDD/src/wlan_hdd_hostapd.c @@ -511,8 +511,8 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa } #ifdef IPA_OFFLOAD if (hdd_ipa_is_enabled(pHddCtx)) - hdd_ipa_wlan_evt(pHostapdAdapter, WLAN_RX_SAP_SELF_STA_ID, - WLAN_AP_CONNECT, pHostapdAdapter->dev->dev_addr); + hdd_ipa_wlan_evt(pHostapdAdapter, pHddApCtx->uBCStaId, + WLAN_AP_CONNECT, pHostapdAdapter->dev->dev_addr); #endif if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff) @@ -596,8 +596,8 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa pHddApCtx->operatingChannel = 0; //Invalidate the channel info. #ifdef IPA_OFFLOAD if (hdd_ipa_is_enabled(pHddCtx)) - hdd_ipa_wlan_evt(pHostapdAdapter, WLAN_RX_SAP_SELF_STA_ID, - WLAN_AP_DISCONNECT, pHostapdAdapter->dev->dev_addr); + hdd_ipa_wlan_evt(pHostapdAdapter, pHddApCtx->uBCStaId, + WLAN_AP_DISCONNECT, pHostapdAdapter->dev->dev_addr); #endif goto stopbss; case eSAP_STA_SET_KEY_EVENT: diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c index 5965f7892afc..88da1e7337b0 100644 --- a/CORE/HDD/src/wlan_hdd_ipa.c +++ b/CORE/HDD/src/wlan_hdd_ipa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -24,7 +24,6 @@ * under proprietary terms before Copyright ownership was assigned * to the Linux Foundation. */ - /*======================================================================== \file wlan_hdd_ipa.c @@ -50,18 +49,14 @@ Include Files #include #include "vos_sched.h" -#include "wlan_qct_tl.h" -#include "ol_txrx_peer_find.h" #include "tl_shim.h" +#include "wlan_qct_tl.h" #define HDD_IPA_DESC_BUFFER_RATIO 4 #define HDD_IPA_IPV4_NAME_EXT "_ipv4" #define HDD_IPA_IPV6_NAME_EXT "_ipv6" #define HDD_IPA_RX_INACTIVITY_MSEC_DELAY 2000 -#define HDD_IPA_WLAN_HDR_ONLY_LEN 4 -#define HDD_IPA_WLAN_HDR_STA_ID_OFFSET 3 -#define HDD_IPA_WLAN_HDR_DES_MAC_OFFSET 0 struct llc_snap_hdr { uint8_t dsap; @@ -70,49 +65,60 @@ struct llc_snap_hdr { __be16 eth_type; } __packed; -struct ipa_tx_hdr { +struct hdd_ipa_tx_hdr { struct ethhdr eth; struct llc_snap_hdr llc_snap; } __packed; /* For Tx pipes, use 802.3 Header format */ -struct ipa_tx_hdr ipa_set_tx_hdr = { +static struct hdd_ipa_tx_hdr ipa_tx_hdr = { { - {0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc}, /* Des_MAC filled by IPA */ - {0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff}, /* Src. MAC filled by IPA */ - 0x00 /* length can be zero */ + {0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0xFF}, + {0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0xFF}, + 0x00 /* length can be zero */ }, { - /* LLC SNAP header 8 bytes */ - 0xaa, 0xaa, - {0x03, 0x00, 0x00, 0x00}, - 0x0008 /* type value(2 bytes) ,filled by wlan */ - /* 0x0800 - IPV4, 0x86dd - IPV6 */ + /* LLC SNAP header 8 bytes */ + 0xaa, 0xaa, + {0x03, 0x00, 0x00, 0x00}, + 0x0008 /* type value(2 bytes) ,filled by wlan */ + /* 0x0800 - IPV4, 0x86dd - IPV6 */ } }; -struct ipa_rx_hdr { - uint8_t hdr[HDD_IPA_WLAN_HDR_ONLY_LEN]; +/* + +----------+----------+--------------+--------+ + | Reserved | QCMAP ID | interface id | STA ID | + +----------+----------+--------------+--------+ + */ +struct hdd_ipa_cld_hdr { + uint8_t reserved[2]; + uint8_t iface_id; + uint8_t sta_id; +} __packed; + +struct hdd_ipa_rx_hdr { + struct hdd_ipa_cld_hdr cld_hdr; struct ethhdr eth; } __packed; -/* For Rx pipe, use Ethernet-II Header format */ -struct ipa_rx_hdr ipa_set_rx_hdr = { - {0x00, 0x00, 0x00, 0x00}, /* 4 bytes header */ - { - {0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc}, /* Des_MAC filled by IPA */ - {0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff}, /* Src. MAC filled by IPA */ - 0x0008 /* type value(2 bytes) ,filled by wlan */ - /* 0x0800 - IPV4, 0x86dd - IPV6 */ - } -}; +#define HDD_IPA_WLAN_CLD_HDR_LEN sizeof(struct hdd_ipa_cld_hdr) +#define HDD_IPA_WLAN_TX_HDR_LEN sizeof(ipa_tx_hdr) +#define HDD_IPA_WLAN_RX_HDR_LEN sizeof(struct hdd_ipa_rx_hdr) +#define HDD_IPA_WLAN_HDR_DES_MAC_OFFSET 0 + +#define HDD_IPA_GET_IFACE_ID(_data) \ + (((struct hdd_ipa_cld_hdr *) (_data))->iface_id) -#define HDD_IPA_WLAN_TX_HDR_LEN sizeof(ipa_set_tx_hdr) -#define HDD_IPA_WLAN_RX_HDR_LEN sizeof(ipa_set_rx_hdr) -#define HDD_IPA_WLAN_HDR_PARTIAL 1 #define HDD_IPA_LOG(LVL, fmt, args...) VOS_TRACE(VOS_MODULE_ID_HDD, LVL, \ - "%s:%d "fmt"\n", __func__, __LINE__, ## args) + "%s:%d: "fmt, __func__, __LINE__, ## args) + +#define HDD_IPA_DBG_DUMP(_lvl, _prefix, _buf, _len) \ + do {\ + VOS_TRACE(VOS_MODULE_ID_HDD, _lvl, "%s:", _prefix); \ + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, _lvl, _buf, _len); \ + } while(0) enum hdd_ipa_rm_state { HDD_IPA_RM_RELEASED, @@ -121,101 +127,106 @@ enum hdd_ipa_rm_state { HDD_IPA_RM_RELEASE_PENDING, }; -enum hdd_ipa_pipe_index { - HDD_IPA_TX_WLAN0_PIPE, - HDD_IPA_TX_WLAN1_PIPE, - HDD_IPA_TX_WLAN2_PIPE, - HDD_IPA_RX_PIPE, - HDD_IPA_MAX_PIPE +#define HDD_IPA_MAX_IFACE 3 +#define HDD_IPA_MAX_SYSBAM_PIPE 4 +#define HDD_IPA_RX_PIPE HDD_IPA_MAX_IFACE + +static struct hdd_ipa_adapter_2_client { + enum ipa_client_type cons_client; + enum ipa_client_type prod_client; +} hdd_ipa_adapter_2_client[HDD_IPA_MAX_IFACE] = { + {IPA_CLIENT_WLAN1_CONS, IPA_CLIENT_WLAN1_PROD}, + {IPA_CLIENT_WLAN2_CONS, IPA_CLIENT_WLAN1_PROD}, + {IPA_CLIENT_WLAN3_CONS, IPA_CLIENT_WLAN1_PROD}, }; -enum hdd_ipa_ip_ver { - HDD_IPA_IPV4 = 1, - HDD_IPA_IPV6 = 2 +struct hdd_ipa_sys_pipe { + uint32_t conn_hdl; + uint8_t conn_hdl_valid; + struct ipa_sys_connect_params ipa_sys_params; }; -#define HDD_IPA_WLAN_MAX_STA_ID 255 +struct hdd_ipa_priv; -uint8_t wlan_sta_id_2_hdd_pipe_id[HDD_IPA_WLAN_MAX_STA_ID] = {0xFF}; +struct hdd_ipa_iface_context { + struct hdd_ipa_priv *hdd_ipa; + hdd_adapter_t *adapter; + void *tl_context; -uint8_t hdd_pipe_id_2_ipa_client_id[HDD_IPA_MAX_PIPE] = { - IPA_CLIENT_WLAN1_CONS, - IPA_CLIENT_WLAN2_CONS, - IPA_CLIENT_WLAN3_CONS, - IPA_CLIENT_WLAN1_PROD -}; + enum ipa_client_type cons_client; + enum ipa_client_type prod_client; -uint8_t ipa_client_id_2_hdd_pipe_id[IPA_CLIENT_MAX] = { - [IPA_CLIENT_WLAN1_CONS] = HDD_IPA_TX_WLAN0_PIPE, - [IPA_CLIENT_WLAN2_CONS] = HDD_IPA_TX_WLAN1_PIPE, - [IPA_CLIENT_WLAN3_CONS] = HDD_IPA_TX_WLAN2_PIPE, - [IPA_CLIENT_WLAN1_PROD] = HDD_IPA_RX_PIPE + uint8_t iface_id; /* This iface ID */ + uint8_t sta_id; /* This iface station ID */ }; -struct hdd_ipa_sys_pipe { - uint32_t conn_hdl; - uint8_t conn_hdl_valid; - struct ipa_sys_connect_params ipa_sys_params; + +struct hdd_ipa_stats { + uint32_t event[IPA_WLAN_EVENT_MAX]; + uint32_t send_msg; + uint32_t free_msg; + + uint64_t prefilter; + uint64_t rm_grant; + uint64_t rm_release; +#ifdef HDD_IPA_EXTRA_DP_COUNTERS + uint64_t rx_ipa_rm_qued; +#endif + uint64_t rx_ipa_sent_desc_cnt; + uint64_t rx_ipa_write_done; + uint64_t rx_ipa_excep; + + uint64_t rx_ipa_hw_maxed_out; + + uint64_t freeq_empty; + uint64_t freeq_cnt; + +#ifdef HDD_IPA_EXTRA_DP_COUNTERS + uint64_t rxt_drop; + uint64_t rxt_recv; + uint64_t rx_ipa_hw_max_qued; + uint64_t rxt_d_drop; + uint64_t rxt_dh_drop; + uint64_t rxt_0; + uint64_t rxt_1; + uint64_t rxt_2; + uint64_t rxt_3; + uint64_t rxt_4; + uint64_t rxt_5; + uint64_t rxt_6; + uint64_t freeq_use; + uint64_t freeq_reclaim; + uint64_t rx_ipa_dh_sent; + uint64_t rx_ipa_dh_reclaim; + uint64_t rx_ipa_dh_not_used; +#endif + uint64_t ipa_lb_cnt; + uint64_t tx_ipa_recv; + uint64_t tx_comp_cnt; + uint64_t tx_dp_err_cnt; }; struct hdd_ipa_priv { - struct hdd_ipa_sys_pipe sys_pipe[HDD_IPA_MAX_PIPE]; + struct hdd_ipa_sys_pipe sys_pipe[HDD_IPA_MAX_SYSBAM_PIPE]; + struct hdd_ipa_iface_context iface_context[HDD_IPA_MAX_IFACE]; atomic_t rm_state; #ifndef HDD_IPA_USE_IPA_RM_TIMER struct timer_list rm_timer; uint8_t rm_timer_on; #endif + enum ipa_client_type prod_client; + uint32_t pending_desc_cnt; uint32_t hw_desc_cnt; spinlock_t q_lock; struct list_head free_desc_head; struct list_head pend_desc_head; - struct ol_txrx_vdev_t *pipe_to_vdev[HDD_IPA_MAX_PIPE]; - hdd_context_t *hdd_ctx; struct dentry *debugfs_dir; - struct { - uint64_t prefilter; - uint64_t rm_grant; - uint64_t rm_release; -#ifdef HDD_IPA_EXTRA_DP_COUNTERS - uint64_t rx_ipa_rm_qued; -#endif - uint64_t rx_ipa_sent_desc_cnt; - uint64_t rx_ipa_write_done; - uint64_t rx_ipa_excep; - - uint64_t rx_ipa_hw_maxed_out; - - uint64_t freeq_empty; - uint64_t freeq_cnt; + struct hdd_ipa_stats stats; -#ifdef HDD_IPA_EXTRA_DP_COUNTERS - uint64_t rxt_drop; - uint64_t rxt_recv; - uint64_t rx_ipa_hw_max_qued; - uint64_t rxt_d_drop; - uint64_t rxt_dh_drop; - uint64_t rxt_0; - uint64_t rxt_1; - uint64_t rxt_2; - uint64_t rxt_3; - uint64_t rxt_4; - uint64_t rxt_5; - uint64_t rxt_6; - uint64_t freeq_use; - uint64_t freeq_reclaim; - uint64_t rx_ipa_dh_sent; - uint64_t rx_ipa_dh_reclaim; - uint64_t rx_ipa_dh_not_used; -#endif - uint64_t ipa_lb_cnt; - uint64_t tx_ipa_recv; - uint64_t tx_comp_cnt; - uint64_t tx_dp_err_cnt; - } stats; }; enum hdd_ipa_evt { @@ -239,12 +250,22 @@ bool hdd_ipa_is_enabled(hdd_context_t *hdd_ctx) return hdd_ctx->cfg_ini->IpaEnable; } -static inline void *hdd_ipa_kzalloc(uint32_t size) +static inline bool hdd_ipa_is_pre_filter_enabled(struct hdd_ipa_priv *hdd_ipa) +{ + hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx; + return hdd_ctx->cfg_ini->IpaPreFilterEnable; +} + +static inline bool hdd_ipa_is_ipv6_enabled(struct hdd_ipa_priv *hdd_ipa) { - void *data = NULL; + hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx; + return hdd_ctx->cfg_ini->IpaIPv6Enable; +} - data = adf_os_mem_alloc(NULL, size); - return data; +static inline bool hdd_ipa_is_rm_enabled(struct hdd_ipa_priv *hdd_ipa) +{ + hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx; + return hdd_ctx->cfg_ini->IpaRMEnable; } static inline struct ipa_tx_data_desc *hdd_ipa_get_desc_from_freeq(void) @@ -254,7 +275,8 @@ static inline struct ipa_tx_data_desc *hdd_ipa_get_desc_from_freeq(void) spin_lock_bh(&ghdd_ipa->q_lock); if (!list_empty(&ghdd_ipa->free_desc_head)) { - desc = list_first_entry(&ghdd_ipa->free_desc_head, struct ipa_tx_data_desc, link); + desc = list_first_entry(&ghdd_ipa->free_desc_head, + struct ipa_tx_data_desc, link); list_del(&desc->link); hdd_ipa->stats.freeq_cnt--; #ifdef HDD_IPA_EXTRA_DP_COUNTERS @@ -267,22 +289,33 @@ static inline struct ipa_tx_data_desc *hdd_ipa_get_desc_from_freeq(void) return desc; } -static inline bool hdd_ipa_can_pre_filter(struct hdd_ipa_priv *hdd_ipa) +static bool hdd_ipa_can_send_to_ipa(struct hdd_ipa_priv *hdd_ipa, void *data) { - hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx; - return hdd_ctx->cfg_ini->IpaPreFilterEnable; -} + struct ethhdr *eth = (struct ethhdr *)data; + struct llc_snap_hdr *ls_hdr; + uint16_t eth_type; -static inline bool hdd_ipa_is_ipv6_enabled(struct hdd_ipa_priv *hdd_ipa) -{ - hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx; - return hdd_ctx->cfg_ini->IpaIPv6Enable; -} + if (!hdd_ipa_is_pre_filter_enabled(hdd_ipa)) + return true; -static inline bool hdd_ipa_is_rm_enabled(struct hdd_ipa_priv *hdd_ipa) -{ - hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx; - return hdd_ctx->cfg_ini->IpaRMEnable; + eth_type = be16_to_cpu(eth->h_proto); + if (eth_type < 0x600) { + /* Non Ethernet II framing format */ + ls_hdr = (struct llc_snap_hdr *)((uint8_t *)data + + sizeof(struct ethhdr)); + + if (((ls_hdr->dsap == 0xAA) && (ls_hdr->ssap == 0xAA)) || + ((ls_hdr->dsap == 0xAB) && (ls_hdr->ssap == 0xAB))) + eth_type = be16_to_cpu(ls_hdr->eth_type); + } + + if (eth_type == ETH_P_IP) + return true; + + if (hdd_ipa_is_ipv6_enabled(hdd_ipa) && eth_type == ETH_P_IPV6) + return true; + + return false; } static int hdd_ipa_rm_request(struct hdd_ipa_priv *hdd_ipa) @@ -362,7 +395,7 @@ static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa) ret = ipa_rm_create_resource(&create_params); if (ret) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "create resource fail"); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Create RM resource failed"); goto setup_rm_fail; } @@ -370,11 +403,13 @@ static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa) ret = ipa_rm_inactivity_timer_init(IPA_RM_RESOURCE_WLAN_PROD, HDD_IPA_RX_INACTIVITY_MSEC_DELAY); if (ret) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "timer fail"); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Timer init failed"); goto setup_rm_fail; } #endif + atomic_set(&hdd_ipa->rm_state, HDD_IPA_RM_RELEASED); + setup_rm_fail: return ret; } @@ -391,10 +426,10 @@ static void hdd_ipa_destory_rm_resource(struct hdd_ipa_priv *hdd_ipa) #endif ret = ipa_rm_delete_resource(IPA_RM_RESOURCE_WLAN_PROD); if (ret) - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "fail"); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "RM resource delete failed"); } -void hdd_ipa_rm_timer_handler(unsigned long ptr) +static void hdd_ipa_rm_timer_handler(unsigned long ptr) { struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; atomic_set(&hdd_ipa->rm_state, @@ -402,27 +437,26 @@ void hdd_ipa_rm_timer_handler(unsigned long ptr) hdd_ipa_rm_release(hdd_ipa); } -void hdd_ipa_send_skb_to_network(adf_nbuf_t skb, hdd_adapter_t *adap_dev) +static void hdd_ipa_send_skb_to_network(adf_nbuf_t skb, hdd_adapter_t *adapter) { - if (!adap_dev || (adap_dev && - adap_dev->magic != WLAN_HDD_ADAPTER_MAGIC)) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid adapter: adap=0x%x", - adap_dev); + if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid adapter: 0x%p", + adapter); - adf_nbuf_free(skb); - return; - } - skb->dev = adap_dev->dev; - skb->protocol = eth_type_trans(skb, skb->dev); - skb->ip_summed = CHECKSUM_NONE; - ++adap_dev->hdd_stats.hddTxRxStats.rxPackets; - ++adap_dev->stats.rx_packets; - adap_dev->stats.rx_bytes += skb->len; - if (netif_rx_ni(skb) == NET_RX_SUCCESS) - ++adap_dev->hdd_stats.hddTxRxStats.rxDelivered; - else - ++adap_dev->hdd_stats.hddTxRxStats.rxRefused; - adap_dev->dev->last_rx = jiffies; + adf_nbuf_free(skb); + return; + } + skb->dev = adapter->dev; + skb->protocol = eth_type_trans(skb, skb->dev); + skb->ip_summed = CHECKSUM_NONE; + ++adapter->hdd_stats.hddTxRxStats.rxPackets; + ++adapter->stats.rx_packets; + adapter->stats.rx_bytes += skb->len; + if (netif_rx_ni(skb) == NET_RX_SUCCESS) + ++adapter->hdd_stats.hddTxRxStats.rxDelivered; + else + ++adapter->hdd_stats.hddTxRxStats.rxRefused; + adapter->dev->last_rx = jiffies; } static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head, @@ -478,21 +512,25 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head, hdd_ipa->stats.rx_ipa_dh_sent++; /* for desc head */ #endif spin_unlock_bh(&hdd_ipa->q_lock); - if (ipa_tx_dp_mul(hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE], + if (ipa_tx_dp_mul(hdd_ipa->prod_client, send_desc_head) != 0) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ipa_tx_dp_mul failed!!! (cur_send_cnt=%d)", cur_send_cnt); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "ipa_tx_dp_mul failed!!!" + " (cur_send_cnt=%d)", + cur_send_cnt); hdd_ipa->stats.tx_dp_err_cnt++; spin_lock_bh(&hdd_ipa->q_lock); list_for_each_entry_safe(desc, tmp, - &send_desc_head->link, link) { + &send_desc_head->link, link) { list_del(&desc->link); buf = desc->priv; adf_nbuf_free(buf); desc->priv = NULL; desc->pyld_buffer = NULL; desc->pyld_len = 0; - list_add_tail(&desc->link, &hdd_ipa->free_desc_head); + list_add_tail(&desc->link, + &hdd_ipa->free_desc_head); hdd_ipa->stats.freeq_cnt++; #ifdef HDD_IPA_EXTRA_DP_COUNTERS hdd_ipa->stats.freeq_reclaim++; @@ -501,7 +539,8 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head, } /* return anchor node */ - list_add_tail(&send_desc_head->link, &hdd_ipa->free_desc_head); + list_add_tail(&send_desc_head->link, + &hdd_ipa->free_desc_head); hdd_ipa->stats.freeq_cnt++; #ifdef HDD_IPA_EXTRA_DP_COUNTERS hdd_ipa->stats.rx_ipa_dh_reclaim++; @@ -517,7 +556,8 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head, hdd_ipa->stats.rx_ipa_hw_maxed_out++; list_splice_tail_init(&send_desc_head->link, &hdd_ipa->pend_desc_head); - list_add_tail(&send_desc_head->link, &hdd_ipa->free_desc_head); + list_add_tail(&send_desc_head->link, + &hdd_ipa->free_desc_head); hdd_ipa->stats.freeq_cnt++; #ifdef HDD_IPA_EXTRA_DP_COUNTERS hdd_ipa->stats.rx_ipa_dh_not_used++; @@ -528,52 +568,25 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head, } -static int hdd_ipa_is_ip_pkt(void *data, uint8_t ip_ver) -{ - struct ethhdr *eth = (struct ethhdr *)data; - struct llc_snap_hdr *ls_hdr; - uint16_t eth_type; - int ret = 0; - - eth_type = be16_to_cpu(eth->h_proto); - if (eth_type < 0x600) { - /* Non Ethernet II framing format */ - ls_hdr = (struct llc_snap_hdr *)((uint8_t *)data + - sizeof(struct ethhdr)); - - if (((ls_hdr->dsap == 0xAA) && (ls_hdr->ssap == 0xAA)) || - ((ls_hdr->dsap == 0xAB) && (ls_hdr->ssap == 0xAB))) - eth_type = be16_to_cpu(ls_hdr->eth_type); - } - - if (((eth_type == ETH_P_IP) && (ip_ver == HDD_IPA_IPV4)) || - ((eth_type == ETH_P_IPV6) && (ip_ver == HDD_IPA_IPV6))) - ret = 1; - - if (ret != 1) - HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "NOT IP Packet!!! (eth_type=0x%x, ip_ver=%d)", eth_type, ip_ver); - - return ret; -} - - static void hdd_ipa_process_evt(int evt, void *priv) { struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; struct hdd_ipa_rxt *rxt; struct ipa_tx_data_desc *send_desc_head = NULL, *send_desc, *done_desc_head, *done_desc, *tmp; - hdd_adapter_t *adap_dev = NULL; + hdd_adapter_t *adapter = NULL; + struct hdd_ipa_iface_context *iface_context = NULL; adf_nbuf_t buf, next_buf; uint8_t cur_cnt = 0; + struct hdd_ipa_cld_hdr *cld_hdr; switch (evt) { case HDD_IPA_RXT_EVT: rxt = priv; - adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[rxt->sta_id]; - if (!adap_dev || - (adap_dev && adap_dev->magic != WLAN_HDD_ADAPTER_MAGIC)) { + adapter = hdd_ipa->hdd_ctx->sta_to_adapter[rxt->sta_id]; + if (!adapter || + (adapter && adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) { HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid sta_id"); buf = rxt->rx_buf_list; while (buf) { @@ -586,10 +599,14 @@ static void hdd_ipa_process_evt(int evt, void *priv) } return; } + + iface_context = + (struct hdd_ipa_iface_context *) adapter->ipa_context; /* send_desc_head is a anchor node */ send_desc_head = hdd_ipa_get_desc_from_freeq(); if (!send_desc_head) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "send_desc_head=Null. FreeQ Empty"); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "send_desc_head=Null. FreeQ Empty"); buf = rxt->rx_buf_list; while (buf) { next_buf = adf_nbuf_queue_next(buf); @@ -612,34 +629,28 @@ static void hdd_ipa_process_evt(int evt, void *priv) INIT_LIST_HEAD(&send_desc_head->link); buf = rxt->rx_buf_list; while (buf) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "RX data:\n \ - %02x %02x %02x %02x %02x %02x %02x %02x\n \ - %02x %02x %02x %02x %02x %02x %02x %02x\n \ - %02x %02x %02x %02x %02x %02x %02x %02x\n", - buf->data[0], buf->data[1], buf->data[2], buf->data[3], - buf->data[4], buf->data[5], buf->data[6], buf->data[7], - buf->data[8], buf->data[9], buf->data[10], buf->data[11], - buf->data[12], buf->data[13], buf->data[14], buf->data[15], - buf->data[16], buf->data[17], buf->data[18], buf->data[19], - buf->data[20], buf->data[21], buf->data[22], buf->data[23]); + HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "RX data", + buf->data, 24); next_buf = adf_nbuf_queue_next(buf); - /* we want to send Rx packets to IPA only when it is IPV4 or IPV6i(if IPV6 - is enabled). All other packets will be sent to network stack directly. */ - if (hdd_ipa_can_pre_filter(hdd_ipa) && - (!hdd_ipa_is_ip_pkt(buf->data, HDD_IPA_IPV4) && - (!hdd_ipa_is_ipv6_enabled(hdd_ipa) || - !hdd_ipa_is_ip_pkt(buf->data, HDD_IPA_IPV6)))) { + /* + * we want to send Rx packets to IPA only when it is + * IPV4 or IPV6i(if IPV6 is enabled). All other packets + * will be sent to network stack directly. + */ + if (!hdd_ipa_can_send_to_ipa(hdd_ipa, buf->data)) { hdd_ipa->stats.prefilter++; - hdd_ipa_send_skb_to_network(buf, adap_dev); + hdd_ipa_send_skb_to_network(buf, adapter); buf = next_buf; continue; } - skb_push(buf, HDD_IPA_WLAN_HDR_ONLY_LEN); - /* vos_mem_zero(((struct ipa_rx_hdr *)(buf->data))->hdr, HDD_IPA_WLAN_HDR_ONLY_LEN); */ - ((struct ipa_rx_hdr *)(buf->data))->hdr[HDD_IPA_WLAN_HDR_STA_ID_OFFSET] = rxt->sta_id; + cld_hdr = (struct hdd_ipa_cld_hdr *) skb_push(buf, + HDD_IPA_WLAN_CLD_HDR_LEN); + cld_hdr->sta_id = rxt->sta_id; + cld_hdr->iface_id = iface_context->iface_id; + send_desc = hdd_ipa_get_desc_from_freeq(); if (send_desc) { send_desc->priv = buf; @@ -680,7 +691,8 @@ static void hdd_ipa_process_evt(int evt, void *priv) if(cur_cnt == 0){ spin_lock_bh(&hdd_ipa->q_lock); - list_add_tail(&send_desc_head->link, &hdd_ipa->free_desc_head); + list_add_tail(&send_desc_head->link, + &hdd_ipa->free_desc_head); hdd_ipa->stats.freeq_cnt++; #ifdef HDD_IPA_EXTRA_DP_COUNTERS hdd_ipa->stats.rx_ipa_dh_not_used++; @@ -699,7 +711,8 @@ static void hdd_ipa_process_evt(int evt, void *priv) HDD_IPA_RM_GRANT_PENDING); hdd_ipa_rm_request(hdd_ipa); } - /* hdd_ipa_rm_request can immediately grant so check again. */ + /* hdd_ipa_rm_request can immediately grant so check + again. */ if (atomic_read(&hdd_ipa->rm_state) == HDD_IPA_RM_GRANT_PENDING) { spin_lock_bh(&hdd_ipa->q_lock); @@ -740,7 +753,8 @@ rxt_end: done_desc->priv = NULL; done_desc->pyld_buffer = NULL; done_desc->pyld_len = 0; - list_add_tail(&done_desc->link, &hdd_ipa->free_desc_head); + list_add_tail(&done_desc->link, + &hdd_ipa->free_desc_head); hdd_ipa->stats.freeq_cnt++; #ifdef HDD_IPA_EXTRA_DP_COUNTERS hdd_ipa->stats.freeq_reclaim++; @@ -781,12 +795,6 @@ rxt_end: } } -static void hdd_ipa_w2i_write_done_handler( - struct ipa_tx_data_desc *done_desc_head) -{ - hdd_ipa_process_evt(HDD_IPA_WRITE_DONE_EVT, done_desc_head); -} - VOS_STATUS hdd_ipa_process_rxt(v_VOID_t *vosContext, adf_nbuf_t rx_buf_list, v_U8_t sta_id) { @@ -804,50 +812,43 @@ VOS_STATUS hdd_ipa_process_rxt(v_VOID_t *vosContext, adf_nbuf_t rx_buf_list, return VOS_STATUS_SUCCESS; } - - -void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) +static void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, + unsigned long data) { - struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; - uint8_t client; + struct hdd_ipa_priv *hdd_ipa = NULL; + hdd_adapter_t *adapter = NULL; struct ipa_tx_data_desc *done_desc_head; adf_nbuf_t skb; - uint8_t sta_id; - hdd_adapter_t *adap_dev=NULL; + uint8_t iface_id; - client = *((uint8_t *)priv); - if (client != hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, - "w2i cb wrong pipe: %d %x %x", - client, priv, - &hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]); - return; - } + hdd_ipa = (struct hdd_ipa_priv *)priv; switch (evt) { case IPA_RECEIVE: skb = (adf_nbuf_t) data; - sta_id = ((struct ipa_rx_hdr *)(skb->data))->hdr[HDD_IPA_WLAN_HDR_STA_ID_OFFSET]; - - HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "w2i -- skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb, - skb->data[0], skb->data[1], skb->data[2], skb->data[3], - skb->data[4], skb->data[5], skb->data[6], skb->data[7]); - skb_pull(skb, HDD_IPA_WLAN_HDR_ONLY_LEN); - - if (sta_id < ARRAY_SIZE(hdd_ipa->hdd_ctx->sta_to_adapter)) { - adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[sta_id]; - } else { + iface_id = HDD_IPA_GET_IFACE_ID(skb->data); + if (iface_id >= HDD_IPA_MAX_IFACE) { HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, - "w2i cb: wrong sta_id: %d", sta_id); + "IPA_RECEIVE: Invalid iface_id: %u\n", + iface_id); + adf_nbuf_free(skb); + return; } + adapter = hdd_ipa->iface_context[iface_id].adapter; + + HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "w2i -- skb", skb->data, + 8); + + skb_pull(skb, HDD_IPA_WLAN_CLD_HDR_LEN); + hdd_ipa->stats.rx_ipa_excep++; - hdd_ipa_send_skb_to_network(skb, adap_dev); + hdd_ipa_send_skb_to_network(skb, adapter); break; case IPA_WRITE_DONE: done_desc_head = (struct ipa_tx_data_desc *)data; - hdd_ipa_w2i_write_done_handler(done_desc_head); + hdd_ipa_process_evt(HDD_IPA_WRITE_DONE_EVT, done_desc_head); break; default: HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, @@ -856,93 +857,33 @@ void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) } } -void hdd_ipa_nbuf_cb(adf_nbuf_t skb) +static void hdd_ipa_nbuf_cb(adf_nbuf_t skb) { struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; /* TX COMP counter at frame free location. */ hdd_ipa->stats.tx_comp_cnt++; - HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "0x%p", NBUF_OWNER_PRIV_DATA(skb)); + HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "%lx", NBUF_OWNER_PRIV_DATA(skb)); ipa_free_skb((struct ipa_rx_data *) NBUF_OWNER_PRIV_DATA(skb)); } -#ifdef WLAN_TX_MUL -void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) +static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, + unsigned long data) { - struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; - struct ipa_rx_data_mul *ipa_tx_desc; - adf_nbuf_t skb; - uint8_t client, pipe_id; - - if (evt == IPA_RECEIVE) { - client = *((uint8_t *)priv); - struct list_head *head = (struct list_head *)data; - - pipe_id = ipa_client_id_2_hdd_pipe_id[client]; - - if (hdd_ipa->pipe_to_vdev[pipe_id] == NULL) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail (vdev=NULL)"); - /* TODO: need to free ipa_desc and skb here */ - return; - } - - list_for_each_entry(ipa_tx_desc, head, link) { - if (ipa_tx_desc->dd == NULL) - break; - - /* TX frame Counter at HDD CB function called by IPA loopback, to push lower layer.*/ - hdd_ipa->stats.tx_ipa_recv++; - - skb = ipa_tx_desc->dd->skb; - - /* skb->dev = ipa_client_id_2_hdd_pipe_id[client]; */ - adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); - NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID; - NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb; - NBUF_MAPPED_PADDR_LO(skb) = ipa_tx_desc->dd->dma_addr; - - NBUF_OWNER_PRIV_DATA(skb) = (unsigned long)ipa_tx_desc->dd; - - HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb, - skb->data[0], skb->data[1], skb->data[2], skb->data[3], - skb->data[4], skb->data[5], skb->data[6], skb->data[7]); - - skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, hdd_ipa->pipe_to_vdev[pipe_id], - ipa_tx_desc->dd->skb); - if (skb) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail"); - ipa_free_skb(ipa_tx_desc->dd); - continue; - } - } - ipa_free_desc(data); - - } else { - /* HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "i2w cb wrong evt: %d", evt); - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Testing hack code data path"); */ - skb = (adf_nbuf_t) data; - dev_kfree_skb_any(skb); - } -} - -#else - -void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) -{ - struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + struct hdd_ipa_priv *hdd_ipa = NULL; struct ipa_rx_data *ipa_tx_desc; + struct hdd_ipa_iface_context *iface_context; adf_nbuf_t skb; - uint8_t client, pipe_id; if (evt == IPA_RECEIVE) { - /* TX frame Counter at HDD CB function called by IPA loopback, to push lower layer */ - hdd_ipa->stats.tx_ipa_recv++; - client = *((uint8_t *)priv); + iface_context = (struct hdd_ipa_iface_context *) priv; ipa_tx_desc = (struct ipa_rx_data *)data; skb = ipa_tx_desc->skb; + hdd_ipa = iface_context->hdd_ipa; + adf_os_mem_set(skb->cb, 0, sizeof(skb->cb)); NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID; NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb; @@ -950,36 +891,22 @@ void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) NBUF_OWNER_PRIV_DATA(skb) = data; - HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "0x%p", NBUF_OWNER_PRIV_DATA(skb)); - HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb, - skb->data[0], skb->data[1], skb->data[2], skb->data[3], - skb->data[4], skb->data[5], skb->data[6], skb->data[7]); - - pipe_id = ipa_client_id_2_hdd_pipe_id[client]; + HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "i2w", skb->data, 8); - HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "client=%d, pipe_to_vdev[%d]=0x%x", client, pipe_id, hdd_ipa->pipe_to_vdev[pipe_id]); - - if (hdd_ipa->pipe_to_vdev[pipe_id] == NULL) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail (pipe_to_vdev[%d]=NULL)", pipe_id); - ipa_free_skb(ipa_tx_desc); - return; - } + hdd_ipa->stats.tx_ipa_recv++; - skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, hdd_ipa->pipe_to_vdev[pipe_id], - ipa_tx_desc->skb); + skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, + iface_context->tl_context, ipa_tx_desc->skb); if (skb) { HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail"); ipa_free_skb(ipa_tx_desc); return; } } else { - /* HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "i2w cb wrong evt: %d", evt); - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Testing hack code data path"); */ skb = (adf_nbuf_t) data; dev_kfree_skb_any(skb); } } -#endif static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa) { @@ -987,12 +914,12 @@ static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa) struct ipa_sys_connect_params *ipa; /*setup TX pipes */ - for (i = 0; i < HDD_IPA_RX_PIPE; i++) { + for (i = 0; i < HDD_IPA_MAX_IFACE; i++) { ipa = &hdd_ipa->sys_pipe[i].ipa_sys_params; - ipa->client = hdd_pipe_id_2_ipa_client_id[i]; + ipa->client = hdd_ipa_adapter_2_client[i].cons_client; ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize; - ipa->priv = &hdd_pipe_id_2_ipa_client_id[i]; + ipa->priv = &hdd_ipa->iface_context[i]; ipa->notify = hdd_ipa_i2w_cb; ipa->ipa_ep_cfg.hdr.hdr_len = HDD_IPA_WLAN_TX_HDR_LEN; @@ -1000,17 +927,35 @@ static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa) ret = ipa_setup_sys_pipe(ipa, &(hdd_ipa->sys_pipe[i].conn_hdl)); if (ret) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Fail: %d", ret); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Failed for pipe %d" + " ret: %d", i, ret); goto setup_sys_pipe_fail; } hdd_ipa->sys_pipe[i].conn_hdl_valid = 1; } + /* + * Hard code it here, this can be extended if in case PROD pipe is also + * per interface. Right now there is no advantage of doing this. + */ + hdd_ipa->prod_client = IPA_CLIENT_WLAN1_PROD; + ipa = &hdd_ipa->sys_pipe[HDD_IPA_RX_PIPE].ipa_sys_params; - ipa->client = hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]; - ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize + sizeof(struct sps_iovec); /* To make sure total # of desc is 1 less than the desc FIFO size */ - ipa->priv = &hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]; + ipa->client = hdd_ipa->prod_client; + + /* The maximum number of descriptors that can be provided to a BAM at + * once is one less than the total number of descriptors that the buffer + * can contain. + * If max_num_of_descriptors = (BAM_PIPE_DESCRIPTOR_FIFO_SIZE / sizeof + * (SPS_DESCRIPTOR)), then (max_num_of_descriptors - 1) descriptors can + * be provided at once. + * Because of above requirement, one extra descriptor will be added to + * make sure hardware always has one descriptor. + */ + ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize + + sizeof(struct sps_iovec); + ipa->priv = hdd_ipa; ipa->notify = hdd_ipa_w2i_cb; ipa->ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT; @@ -1020,59 +965,73 @@ static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa) ret = ipa_setup_sys_pipe(ipa, &(hdd_ipa->sys_pipe[i].conn_hdl)); if (ret) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Fail: %d", ret); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Failed for RX pipe: %d", + ret); goto setup_sys_pipe_fail; } hdd_ipa->sys_pipe[HDD_IPA_RX_PIPE].conn_hdl_valid = 1; + return ret; + setup_sys_pipe_fail: + + while (--i >= 0) { + ipa_teardown_sys_pipe(hdd_ipa->sys_pipe[i].conn_hdl); + vos_mem_zero(&hdd_ipa->sys_pipe[i], + sizeof(struct hdd_ipa_sys_pipe )); + } + return ret; } /* Disconnect all the Sys pipes */ -void hdd_ipa_teardown_sys_pipe(struct hdd_ipa_priv *hdd_ipa) +static void hdd_ipa_teardown_sys_pipe(struct hdd_ipa_priv *hdd_ipa) { int ret = 0, i; - for (i = 0; i < HDD_IPA_MAX_PIPE; i++) { + for (i = 0; i < HDD_IPA_MAX_SYSBAM_PIPE; i++) { if (hdd_ipa->sys_pipe[i].conn_hdl_valid) { ret = ipa_teardown_sys_pipe( hdd_ipa->sys_pipe[i].conn_hdl); if (ret) - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "fail: %d", - ret); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Failed: %d", + ret); hdd_ipa->sys_pipe[i].conn_hdl_valid = 0; } } } -int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t sta_id, const char *ifname) +static int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, + struct hdd_ipa_iface_context *iface_context) { struct ipa_tx_intf tx_intf; struct ipa_rx_intf rx_intf; struct ipa_ioc_tx_intf_prop *tx_prop = NULL; struct ipa_ioc_rx_intf_prop *rx_prop = NULL; + char *ifname = iface_context->adapter->dev->name; char ipv4_hdr_name[IPA_RESOURCE_NAME_MAX]; char ipv6_hdr_name[IPA_RESOURCE_NAME_MAX]; - int ip_max = HDD_IPA_IPV4; + int num_prop = 1; int ret = 0; if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) - ip_max = HDD_IPA_IPV6; + num_prop++; /* Allocate TX properties for TOS categories, 1 each for IPv4 & IPv6 */ - tx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_tx_intf_prop) * ip_max); + tx_prop = vos_mem_malloc(sizeof(struct ipa_ioc_tx_intf_prop) * + num_prop); if (!tx_prop) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ENOMEM"); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "tx_prop allocation failed"); goto register_interface_fail; } /* Allocate RX properties, 1 each for IPv4 & IPv6 */ - rx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_rx_intf_prop) * ip_max); + rx_prop = vos_mem_malloc(sizeof(struct ipa_ioc_rx_intf_prop) * + num_prop); if (!rx_prop) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ENOMEM"); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "rx_prop allocation failed"); goto register_interface_fail; } vos_mem_zero(&tx_intf, sizeof(tx_intf)); @@ -1084,23 +1043,42 @@ int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t sta_id, con ifname, HDD_IPA_IPV6_NAME_EXT); rx_prop[IPA_IP_v4].ip = IPA_IP_v4; - rx_prop[IPA_IP_v4].src_pipe = IPA_CLIENT_WLAN1_PROD; + rx_prop[IPA_IP_v4].src_pipe = iface_context->prod_client; + + rx_prop[IPA_IP_v4].attrib.attrib_mask = IPA_FLT_META_DATA; + + /* + * Interface ID is 3rd byte in the CLD header. Add the meta data and + * mask to identify the interface in IPA hardware + */ + rx_prop[IPA_IP_v4].attrib.meta_data = + htonl(iface_context->iface_id << 16); + rx_prop[IPA_IP_v4].attrib.meta_data_mask = htonl(0x00FF0000); + rx_intf.num_props++; if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) { rx_prop[IPA_IP_v6].ip = IPA_IP_v6; - rx_prop[IPA_IP_v6].src_pipe = IPA_CLIENT_WLAN1_PROD; + rx_prop[IPA_IP_v6].src_pipe = iface_context->prod_client; + + rx_prop[IPA_IP_v4].attrib.attrib_mask = IPA_FLT_META_DATA; + rx_prop[IPA_IP_v4].attrib.meta_data = + htonl(iface_context->iface_id << 16); + rx_prop[IPA_IP_v4].attrib.meta_data_mask = htonl(0x00FF0000); + rx_intf.num_props++; } tx_prop[IPA_IP_v4].ip = IPA_IP_v4; - tx_prop[IPA_IP_v4].dst_pipe = hdd_pipe_id_2_ipa_client_id[wlan_sta_id_2_hdd_pipe_id[sta_id]]; - strlcpy(tx_prop[IPA_IP_v4].hdr_name, ipv4_hdr_name, IPA_RESOURCE_NAME_MAX); + tx_prop[IPA_IP_v4].dst_pipe = iface_context->cons_client; + strlcpy(tx_prop[IPA_IP_v4].hdr_name, ipv4_hdr_name, + IPA_RESOURCE_NAME_MAX); tx_intf.num_props++; + if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) { tx_prop[IPA_IP_v6].ip = IPA_IP_v6; - tx_prop[IPA_IP_v6].dst_pipe = hdd_pipe_id_2_ipa_client_id[wlan_sta_id_2_hdd_pipe_id[sta_id]]; + tx_prop[IPA_IP_v6].dst_pipe = iface_context->cons_client; strlcpy(tx_prop[IPA_IP_v6].hdr_name, ipv6_hdr_name, - IPA_RESOURCE_NAME_MAX); + IPA_RESOURCE_NAME_MAX); tx_intf.num_props++; } @@ -1111,201 +1089,248 @@ int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t sta_id, con ret = ipa_register_intf(ifname, &tx_intf, &rx_intf); register_interface_fail: - adf_os_mem_free(tx_prop); - adf_os_mem_free(rx_prop); + vos_mem_free(tx_prop); + vos_mem_free(rx_prop); return ret; } -static int hdd_ipa_add_header_info(enum ipa_wlan_event type, uint8_t sta_id, uint8_t *mac_addr) +static void hdd_remove_ipa_header(char *name) { - struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; - char *ifname; - struct ipa_ioc_add_hdr *ipahdr = NULL; - int i, ret = -EINVAL; - hdd_adapter_t *adap_dev; - struct ol_txrx_pdev_t *pdev; - struct ol_txrx_vdev_t *vdev; - - adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[sta_id]; - if (!adap_dev) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "adap_dev NULL"); - goto add_header_info_ctx_fail; + struct ipa_ioc_get_hdr hdrlookup; + int ret = 0, len; + struct ipa_ioc_del_hdr *ipa_hdr; + + vos_mem_zero(&hdrlookup, sizeof(hdrlookup)); + strlcpy(hdrlookup.name, name, sizeof(hdrlookup.name)); + ret = ipa_get_hdr(&hdrlookup); + if (ret) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Hdr deleted already %s, %d", + name, ret); + return; } - ifname = adap_dev->dev->name; - for (i = 0; i < HDD_IPA_MAX_PIPE; i++) - hdd_ipa->pipe_to_vdev[i] = NULL; + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "hdl: 0x%x", hdrlookup.hdl); + len = sizeof(struct ipa_ioc_del_hdr) + sizeof(struct ipa_hdr_del)*1; + ipa_hdr = (struct ipa_ioc_del_hdr *) vos_mem_malloc(len); + if (ipa_hdr == NULL) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ipa_hdr allocation failed"); + return; + } + ipa_hdr->num_hdls = 1; + ipa_hdr->commit = 0; + ipa_hdr->hdl[0].hdl = hdrlookup.hdl; + ipa_hdr->hdl[0].status = -1; + ret = ipa_del_hdr(ipa_hdr); + if (ret != 0) + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Delete header failed: %d", + ret); - if (wlan_sta_id_2_hdd_pipe_id[sta_id] == 0xFF) { - switch (type) { - case WLAN_AP_CONNECT: - wlan_sta_id_2_hdd_pipe_id[sta_id] = HDD_IPA_TX_WLAN0_PIPE; /* TODO: need to expand to AP+AP */ - break; - case WLAN_STA_CONNECT: - /* Register pipe_to_vdev for STA mode */ - pdev = ((pVosContextType)(WLAN_HDD_GET_CTX(adap_dev)->pvosContext))->pdev_txrx_ctx; - /* find the "vdev" this STA interface belongs to */ - TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { - if (adf_os_mem_cmp(mac_addr, vdev->mac_addr.raw, IEEE80211_ADDR_LEN) == 0) { - hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN2_PIPE] = vdev; - break; - } - } + vos_mem_free(ipa_hdr); +} - wlan_sta_id_2_hdd_pipe_id[sta_id] = HDD_IPA_TX_WLAN2_PIPE; /* STA Mode */ - break; - default: - break; - } - } - HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, " wlan_sta_id_2_hdd_pipe_id[%d]: %d", - sta_id, wlan_sta_id_2_hdd_pipe_id[sta_id]); +static int hdd_ipa_add_header_info(struct hdd_ipa_priv *hdd_ipa, + struct hdd_ipa_iface_context *iface_context, uint8_t *mac_addr) +{ + hdd_adapter_t *adapter = iface_context->adapter; + char *ifname; + struct ipa_ioc_add_hdr *ipa_hdr = NULL; + int ret = -EINVAL; + struct hdd_ipa_tx_hdr *tx_hdr = NULL; + ifname = adapter->dev->name; - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ifindex: %d Add Partial hdr: %s, %p\n", - sta_id, ifname, mac_addr); - if (ifname == NULL) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ifname NULL"); - goto add_header_info_ctx_fail; - } + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Add Partial hdr: %s, %pM", + ifname, mac_addr); /* dynamically allocate the memory to add the hdrs */ - ipahdr = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_add_hdr) + - sizeof(struct ipa_hdr_add)); - if (!ipahdr) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "%s: ENOMEM", ifname); - return -ENOMEM; + ipa_hdr = vos_mem_malloc(sizeof(struct ipa_ioc_add_hdr) + + sizeof(struct ipa_hdr_add)); + if (!ipa_hdr) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: ipa_hdr allocation failed", ifname); + ret = -ENOMEM; + goto end; } - ipahdr->commit = 0; - ipahdr->num_hdrs = 1; + ipa_hdr->commit = 0; + ipa_hdr->num_hdrs = 1; + + tx_hdr = (struct hdd_ipa_tx_hdr *)ipa_hdr->hdr[0].hdr; + /* Set the Source MAC */ - memcpy(ipahdr->hdr[0].hdr, (uint8_t *)&ipa_set_tx_hdr, HDD_IPA_WLAN_TX_HDR_LEN); - memcpy((uint8_t *)(((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->eth.h_source), mac_addr, - ETH_ALEN); + memcpy(tx_hdr, &ipa_tx_hdr, HDD_IPA_WLAN_TX_HDR_LEN); + memcpy(tx_hdr->eth.h_source, mac_addr, ETH_ALEN); - snprintf(ipahdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s", - ifname, HDD_IPA_IPV4_NAME_EXT); - ipahdr->hdr[0].hdr_len = HDD_IPA_WLAN_TX_HDR_LEN; - ipahdr->hdr[0].is_partial = HDD_IPA_WLAN_HDR_PARTIAL; - ipahdr->hdr[0].hdr_hdl = 0; + snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s", + ifname, HDD_IPA_IPV4_NAME_EXT); + ipa_hdr->hdr[0].hdr_len = HDD_IPA_WLAN_TX_HDR_LEN; + ipa_hdr->hdr[0].is_partial = 1; + ipa_hdr->hdr[0].hdr_hdl = 0; /* Set the type to IPV4 in the header*/ - ((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->llc_snap.eth_type = cpu_to_be16(ETH_P_IP); + tx_hdr->llc_snap.eth_type = cpu_to_be16(ETH_P_IP); - ret = ipa_add_hdr(ipahdr); + ret = ipa_add_hdr(ipa_hdr); if (ret) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "%s IPv4 fail: %d", ifname - , ret); - goto add_header_info_fail; + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "%s IPv4 add hdr failed: %d", + ifname, ret); + goto end; } - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv4 hdr_hdl: %x", - ipahdr->hdr[0].name, ipahdr->hdr[0].hdr_hdl); + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv4 hdr_hdl: 0x%x", + ipa_hdr->hdr[0].name, ipa_hdr->hdr[0].hdr_hdl); + if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) { - snprintf(ipahdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s", - ifname, HDD_IPA_IPV6_NAME_EXT); + snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s", + ifname, HDD_IPA_IPV6_NAME_EXT); + /* Set the type to IPV6 in the header*/ - ((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->llc_snap.eth_type = cpu_to_be16(ETH_P_IPV6); + tx_hdr->llc_snap.eth_type = cpu_to_be16(ETH_P_IPV6); + + ret = ipa_add_hdr(ipa_hdr); - ret = ipa_add_hdr(ipahdr); if (ret) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, - "%s: IPv6 hdr fail: %d", ifname, ret); - goto add_header_info_fail; + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "%s: IPv6 add hdr failed: %d", + ifname, ret); + goto clean_ipv4_hdr; } - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv6 hdr_hdl: %x", - ipahdr->hdr[0].name, ipahdr->hdr[0].hdr_hdl); + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv6 hdr_hdl: 0x%x", + ipa_hdr->hdr[0].name, ipa_hdr->hdr[0].hdr_hdl); } - /* Configure the TX and RX pipes filter rules */ - ret = hdd_ipa_register_interface(hdd_ipa, sta_id, ifname); -add_header_info_fail: - adf_os_mem_free(ipahdr); -add_header_info_ctx_fail: - return ret; -} - -void hdd_remove_ipa_header(char *name) -{ - struct ipa_ioc_get_hdr hdrlookup; - int ret = 0, len; - struct ipa_ioc_del_hdr *ipahdr; - - vos_mem_zero(&hdrlookup, sizeof(hdrlookup)); - strlcpy(hdrlookup.name, name, sizeof(hdrlookup.name)); - ret = ipa_get_hdr(&hdrlookup); - if (ret) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Hdr deleted already %s, %d", - name, ret); - return; - } + vos_mem_free(ipa_hdr); + return ret; - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "hdl: %x", hdrlookup.hdl); - len = sizeof(struct ipa_ioc_del_hdr) + sizeof(struct ipa_hdr_del)*1; - ipahdr = (struct ipa_ioc_del_hdr *) hdd_ipa_kzalloc(len); - if (ipahdr == NULL) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ENOMEM"); - return; - } - ipahdr->num_hdls = 1; - ipahdr->commit = 0; - ipahdr->hdl[0].hdl = hdrlookup.hdl; - ipahdr->hdl[0].status = -1; - ret = ipa_del_hdr(ipahdr); - if (ret != 0) - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Fail: %d", ret); +clean_ipv4_hdr: + snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s", + ifname, HDD_IPA_IPV4_NAME_EXT); + hdd_remove_ipa_header(ipa_hdr->hdr[0].name); +end: + if(ipa_hdr) + vos_mem_free(ipa_hdr); - adf_os_mem_free(ipahdr); + return ret; } -void hdd_ipa_clean_hdr(hdd_adapter_t *adap_dev, uint8_t sta_id) +static void hdd_ipa_clean_hdr(hdd_adapter_t *adapter) { struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; int ret; char name_ipa[IPA_RESOURCE_NAME_MAX]; - wlan_sta_id_2_hdd_pipe_id[sta_id] = 0xFF; - /* Remove the headers */ snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s", - adap_dev->dev->name, HDD_IPA_IPV4_NAME_EXT); + adapter->dev->name, HDD_IPA_IPV4_NAME_EXT); hdd_remove_ipa_header(name_ipa); if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) { snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s", - adap_dev->dev->name, HDD_IPA_IPV6_NAME_EXT); + adapter->dev->name, HDD_IPA_IPV6_NAME_EXT); hdd_remove_ipa_header(name_ipa); } /* unregister the interface with IPA */ - ret = ipa_deregister_intf(adap_dev->dev->name); + ret = ipa_deregister_intf(adapter->dev->name); if (ret) HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, - "%s: ipa_deregister_intf fail: %d", adap_dev->dev->name, ret); + "%s: ipa_deregister_intf fail: %d", + adapter->dev->name, ret); +} + +static void hdd_ipa_cleanup_iface(struct hdd_ipa_priv *hdd_ipa, + struct hdd_ipa_iface_context *iface_context) +{ + hdd_ipa_clean_hdr(iface_context->adapter); + + iface_context->adapter->ipa_context = NULL; + iface_context->adapter = NULL; + iface_context->tl_context = NULL; +} + + +static int hdd_ipa_setup_iface(struct hdd_ipa_priv *hdd_ipa, + hdd_adapter_t *adapter, uint8_t sta_id) +{ + struct hdd_ipa_iface_context *iface_context = NULL; + void *tl_context = NULL; + int i, ret = 0; + + for (i = 0; i < HDD_IPA_MAX_IFACE; i++) { + if (hdd_ipa->iface_context[i].adapter == NULL) { + iface_context = &hdd_ipa->iface_context[i]; + break; + } + } + + if (iface_context == NULL) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "All the IPA interfaces are in use"); + ret = -ENOMEM; + goto end; + } + + + adapter->ipa_context = iface_context; + iface_context->adapter = adapter; + iface_context->sta_id = sta_id; + tl_context = tl_shim_get_vdev_by_sta_id(hdd_ipa->hdd_ctx->pvosContext, + sta_id); + + if (tl_context == NULL) { + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "Not able to get TL context sta_id: %d", + sta_id); + ret = -EINVAL; + goto end; + } + + iface_context->tl_context = tl_context; + + ret = hdd_ipa_add_header_info(hdd_ipa, iface_context, + adapter->dev->dev_addr); + + if (ret) + goto end; + + /* Configure the TX and RX pipes filter rules */ + ret = hdd_ipa_register_interface(hdd_ipa, iface_context); + if (ret) + goto cleanup_header; + + return ret; + +cleanup_header: + + hdd_ipa_clean_hdr(adapter); +end: + if (iface_context) + hdd_ipa_cleanup_iface(hdd_ipa, iface_context); + return ret; } static void hdd_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "msg type:%d, len:%d\n", type, len); - adf_os_mem_free(buff); + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "msg type:%d, len:%d", type, len); + ghdd_ipa->stats.free_msg++; + vos_mem_free(buff); } -int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id, +int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, enum ipa_wlan_event type, uint8_t *mac_addr) { struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; - hdd_adapter_t *adap_dev = Adapter; struct ipa_msg_meta meta; struct ipa_wlan_msg *msg; struct ipa_wlan_msg_ex *msg_ex = NULL; int ret; - const char *hdd_ipa_event_name[IPA_EVENT_MAX] = { + const char *hdd_ipa_event_name[IPA_WLAN_EVENT_MAX] = { __stringify(WLAN_CLIENT_CONNECT), __stringify(WLAN_CLIENT_DISCONNECT), __stringify(WLAN_CLIENT_POWER_SAVE_MODE), @@ -1318,69 +1343,67 @@ int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id, __stringify(WLAN_STA_DISCONNECT), __stringify(WLAN_CLIENT_CONNECT_EX), }; - struct ol_txrx_peer_t *peer; HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: %s evt, MAC: %pM sta_id: %d", - adap_dev->dev->name, hdd_ipa_event_name[type], - mac_addr, sta_id); - if (type >= IPA_EVENT_MAX) + adapter->dev->name, hdd_ipa_event_name[type], mac_addr, + sta_id); + + if (type >= IPA_WLAN_EVENT_MAX) return -EINVAL; if (WARN_ON(is_zero_ether_addr(mac_addr))) return -EINVAL; + hdd_ipa->stats.event[type]++; + switch (type) { case WLAN_STA_CONNECT: case WLAN_AP_CONNECT: - hdd_ipa_add_header_info(type, sta_id, mac_addr); + ret = hdd_ipa_setup_iface(hdd_ipa, adapter, sta_id); + if (ret) + goto end; break; case WLAN_STA_DISCONNECT: - hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN2_PIPE] = NULL; case WLAN_AP_DISCONNECT: - hdd_ipa_clean_hdr(adap_dev, sta_id); + hdd_ipa_cleanup_iface(hdd_ipa, + adapter->ipa_context); break; case WLAN_CLIENT_CONNECT_EX: - /* Register pipe map to txrx_vdev into hdd_ipa */ - peer = ol_txrx_peer_find_by_local_id(((pVosContextType)(WLAN_HDD_GET_CTX(adap_dev))->pvosContext)->pdev_txrx_ctx, sta_id); - if (!peer) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid peer"); - return -EINVAL; - } - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%d %d", adap_dev->dev->ifindex, sta_id); - if (hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] == NULL) { - hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] = peer->vdev; /* TODO: need to expand to AP+AP */ - } + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%d %d", + adapter->dev->ifindex, sta_id); meta.msg_type = type; meta.msg_len = (sizeof(struct ipa_wlan_msg_ex) + sizeof(struct ipa_wlan_hdr_attrib_val)); - msg_ex = hdd_ipa_kzalloc (meta.msg_len); + msg_ex = vos_mem_malloc (meta.msg_len); + if (msg_ex == NULL) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ENOMEM"); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "msg_ex allocation failed"); return -ENOMEM; } - strlcpy(msg_ex->name, adap_dev->dev->name, IPA_RESOURCE_NAME_MAX); + strlcpy(msg_ex->name, adapter->dev->name, + IPA_RESOURCE_NAME_MAX); msg_ex->num_of_attribs = 1; msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR; msg_ex->attribs[0].offset = HDD_IPA_WLAN_HDR_DES_MAC_OFFSET; memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr, - IPA_MAC_ADDR_SIZE); + IPA_MAC_ADDR_SIZE); ret = ipa_send_msg(&meta, msg_ex, hdd_ipa_msg_free_fn); if (ret) { HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d : %d", msg_ex->name, meta.msg_type, ret); - adf_os_mem_free(msg_ex); + vos_mem_free(msg_ex); return ret; } + hdd_ipa->stats.send_msg++; + return 0; case WLAN_CLIENT_DISCONNECT: - /* TODO: need to expand to AP+AP */ - /* This will remove the vdev for rest of the connected clients */ - //hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] = NULL; break; default: @@ -1388,30 +1411,59 @@ int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id, } meta.msg_len = sizeof(struct ipa_wlan_msg); - msg = hdd_ipa_kzalloc(meta.msg_len); + msg = vos_mem_malloc(meta.msg_len); if (msg == NULL) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ENOMEM"); + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "msg allocation failed"); return -ENOMEM; } meta.msg_type = type; - strlcpy(msg->name, adap_dev->dev->name, IPA_RESOURCE_NAME_MAX); + strlcpy(msg->name, adapter->dev->name, IPA_RESOURCE_NAME_MAX); memcpy(msg->mac_addr, mac_addr, ETH_ALEN); + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d", msg->name, meta.msg_type); + ret = ipa_send_msg(&meta, msg, hdd_ipa_msg_free_fn); if (ret) { HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d fail:%d", msg->name, meta.msg_type, ret); - adf_os_mem_free(msg); + vos_mem_free(msg); return ret; } + hdd_ipa->stats.send_msg++; + +end: return ret; } +static void hdd_ipa_rx_pipe_desc_free(void) +{ + struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; + uint32_t i = 0, max_desc_cnt; + struct ipa_tx_data_desc *desc, *tmp; + + max_desc_cnt = hdd_ipa->hw_desc_cnt * HDD_IPA_DESC_BUFFER_RATIO; + + spin_lock_bh(&hdd_ipa->q_lock); + list_for_each_entry_safe(desc, tmp, &hdd_ipa->free_desc_head, link) { + list_del(&desc->link); + spin_unlock_bh(&hdd_ipa->q_lock); + vos_mem_free(desc); + spin_lock_bh(&hdd_ipa->q_lock); + i++; + } + spin_unlock_bh(&hdd_ipa->q_lock); + + if (i != max_desc_cnt) + HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "free desc leak"); + +} + + static int hdd_ipa_rx_pipe_desc_alloc(void) { struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; @@ -1424,46 +1476,34 @@ static int hdd_ipa_rx_pipe_desc_alloc(void) max_desc_cnt = hdd_ipa->hw_desc_cnt * HDD_IPA_DESC_BUFFER_RATIO; spin_lock_init(&hdd_ipa->q_lock); - spin_lock_bh(&hdd_ipa->q_lock); + INIT_LIST_HEAD(&hdd_ipa->free_desc_head); INIT_LIST_HEAD(&hdd_ipa->pend_desc_head); hdd_ipa->stats.freeq_cnt = max_desc_cnt; for (i = 0; i < max_desc_cnt; i++) { - tmp_desc = hdd_ipa_kzalloc(sizeof(struct + tmp_desc = vos_mem_malloc(sizeof(struct ipa_tx_data_desc)); if (!tmp_desc) { - ret = -1; - break; + ret = -ENOMEM; + + HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, + "Descriptor allocation failed\n"); + goto fail; } + spin_lock_bh(&hdd_ipa->q_lock); list_add_tail(&tmp_desc->link, &hdd_ipa->free_desc_head); + spin_unlock_bh(&hdd_ipa->q_lock); } - spin_unlock_bh(&hdd_ipa->q_lock); + + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Desc sz:%d h_desc_cnt:%d freeq_cnt:%llu", hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize, hdd_ipa->hw_desc_cnt, hdd_ipa->stats.freeq_cnt); return ret; -} - -static void hdd_ipa_rx_pipe_desc_free(void) -{ - struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; - uint32_t i = 0, max_desc_cnt; - struct ipa_tx_data_desc *desc, *tmp; - - max_desc_cnt = hdd_ipa->hw_desc_cnt * HDD_IPA_DESC_BUFFER_RATIO; - - spin_lock_bh(&hdd_ipa->q_lock); - list_for_each_entry_safe(desc, tmp, &hdd_ipa->free_desc_head, link) { - list_del(&desc->link); - adf_os_mem_free(desc); - i++; - } - spin_unlock_bh(&hdd_ipa->q_lock); - - if (i != max_desc_cnt) - HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "free mem leak"); - +fail: + hdd_ipa_rx_pipe_desc_free(); + return ret; } static ssize_t hdd_ipa_debugfs_read_ipa_stats(struct file *file, @@ -1573,7 +1613,7 @@ static const struct file_operations fops_ipa_stats = { }; -int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa) +static int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa) { #ifdef WLAN_OPEN_SOURCE hdd_ipa->debugfs_dir = debugfs_create_dir("cld", @@ -1587,6 +1627,13 @@ int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa) return 0; } +static void hdd_ipa_debugfs_remove(struct hdd_ipa_priv *hdd_ipa) +{ +#ifdef WLAN_OPEN_SOURCE + debugfs_remove_recursive(hdd_ipa->debugfs_dir); +#endif +} + /** * hdd_ipa_init() - Allocate hdd_ipa resources, ipa pipe resource and register * wlan interface with IPA module. @@ -1599,21 +1646,31 @@ VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx) { struct hdd_ipa_priv *hdd_ipa = NULL; int ret, i; - if (!hdd_ipa_is_enabled(hdd_ctx)) - return 0; + struct hdd_ipa_iface_context *iface_context = NULL; - for (i = 0; i < HDD_IPA_WLAN_MAX_STA_ID; i++) - wlan_sta_id_2_hdd_pipe_id[i] = 0xFF; + if (!hdd_ipa_is_enabled(hdd_ctx)) + return VOS_STATUS_SUCCESS; - hdd_ipa = hdd_ipa_kzalloc(sizeof(struct hdd_ipa_priv)); + hdd_ipa = vos_mem_malloc(sizeof(struct hdd_ipa_priv)); if (!hdd_ipa) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "ENOMEM"); + HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "hdd_ipa allocation failed"); goto fail_setup_rm; } hdd_ctx->hdd_ipa = hdd_ipa; ghdd_ipa = hdd_ipa; hdd_ipa->hdd_ctx = hdd_ctx; + /* Create the interface context */ + for (i = 0; i < HDD_IPA_MAX_IFACE; i++) { + iface_context = &hdd_ipa->iface_context[i]; + iface_context->hdd_ipa = hdd_ipa; + iface_context->cons_client = + hdd_ipa_adapter_2_client[i].cons_client; + iface_context->prod_client = + hdd_ipa_adapter_2_client[i].prod_client; + iface_context->iface_id = i; + } + ret = hdd_ipa_setup_rm(hdd_ipa); if (ret) goto fail_setup_rm; @@ -1622,8 +1679,6 @@ VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx) if (ret) goto fail_create_sys_pipe; - atomic_set(&hdd_ipa->rm_state, HDD_IPA_RM_RELEASED); - ret = hdd_ipa_rx_pipe_desc_alloc(); if (ret) goto fail_alloc_rx_pipe_desc; @@ -1632,17 +1687,21 @@ VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx) if (ret) goto fail_alloc_rx_pipe_desc; - HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "IPA Init Done"); #ifndef HDD_IPA_USE_IPA_RM_TIMER setup_timer(&hdd_ipa->rm_timer, hdd_ipa_rm_timer_handler, (unsigned long) &hdd_ipa); #endif + HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "IPA Init Done"); + return VOS_STATUS_SUCCESS; fail_alloc_rx_pipe_desc: hdd_ipa_rx_pipe_desc_free(); fail_create_sys_pipe: hdd_ipa_destory_rm_resource(hdd_ipa); fail_setup_rm: + if (hdd_ipa) + vos_mem_free(hdd_ipa); + return VOS_STATUS_E_FAILURE; } @@ -1653,6 +1712,8 @@ VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx) if (!hdd_ipa_is_enabled(hdd_ctx)) return VOS_STATUS_SUCCESS; + hdd_ipa_debugfs_remove(hdd_ipa); + #ifndef HDD_IPA_USE_IPA_RM_TIMER del_timer(&hdd_ipa->rm_timer); #endif @@ -1664,73 +1725,9 @@ VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx) hdd_ipa_teardown_sys_pipe(hdd_ipa); hdd_ipa_destory_rm_resource(hdd_ipa); - adf_os_mem_free(hdd_ctx->hdd_ipa); + vos_mem_free(hdd_ipa); + hdd_ctx->hdd_ipa = NULL; return VOS_STATUS_SUCCESS; } - -#if 0 -/** -* hdd_ipa_start_xmit() - This is a hack code for IPA loopback test -*/ -int hdd_ipa_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev); - hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); - uint8_t sta_id; - struct hdd_ipa_priv *hdd_ipa = ghdd_ipa; - - v_MACADDR_t *pDestMacAddress = (v_MACADDR_t *)skb->data; - - if (vos_is_macaddr_broadcast(pDestMacAddress) || - vos_is_macaddr_group(pDestMacAddress)) { - /* The BC/MC station ID is assigned during BSS starting phase. - SAP will return the station ID used for BC/MC traffic. */ - sta_id = pHddApCtx->uBCStaId; - hdd_softap_hard_start_xmit(skb, dev); - return NETDEV_TX_OK; - } else { - sta_id = *(uint8_t *)(((uint8_t *)(skb->data)) - 1); - if (sta_id == HDD_WLAN_INVALID_STA_ID) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN, - "Failed to find right station"); - goto drop_pkt; - } else if (FALSE == pAdapter->aStaInfo[sta_id].isUsed) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN, - "STA %d is unregistered", sta_id); - goto drop_pkt; - } - - if ((WLANTL_STA_CONNECTED != - pAdapter->aStaInfo[sta_id].tlSTAState) && - (WLANTL_STA_AUTHENTICATED != - pAdapter->aStaInfo[sta_id].tlSTAState)) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN, - "Station not connected yet"); - goto drop_pkt; - } else if (WLANTL_STA_CONNECTED == - pAdapter->aStaInfo[sta_id].tlSTAState) { - if (ntohs(skb->protocol) != - HDD_ETHERTYPE_802_1_X) { - HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN, - "NON-EAPOL packet in no-Auth state"); - goto drop_pkt; - } - } - } - if (hdd_ipa_is_ip_pkt(skb->data, HDD_IPA_IPV4)) { - /* TX frame Counter at HDD entry from kernel network stack, before give frame to IPA Loopback */ - hdd_ipa->stats.ipa_lb_cnt++; - ipa_tx_dp(IPA_CLIENT_WLAN1_CONS, skb, NULL); - } else { - hdd_softap_hard_start_xmit(skb, dev); - } - - return NETDEV_TX_OK; -drop_pkt: - kfree_skb(skb); - return NETDEV_TX_OK; -} -#endif - #endif diff --git a/CORE/VOSS/src/vos_trace.c b/CORE/VOSS/src/vos_trace.c index 5b5f33562506..ea81ece70c25 100644 --- a/CORE/VOSS/src/vos_trace.c +++ b/CORE/VOSS/src/vos_trace.c @@ -388,10 +388,15 @@ void vos_trace_hex_dump( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, { char *buf = (char *)data; int i; + + if (!(gVosTraceInfo[module].moduleTraceLevel & + VOS_TRACE_LEVEL_TO_MODULE_BITMASK(level))) + return; + for (i=0; (i+7) Date: Fri, 7 Feb 2014 12:11:25 -0800 Subject: Cafstaging Release 1.0.0.31 Cafstaging Release 1.0.0.31 Change-Id: I6a3fd1c03241023c59bf165606ca83dbea141d13 --- CORE/MAC/inc/qwlan_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h index cdf522fde2e2..275ed7c67ac8 100644 --- a/CORE/MAC/inc/qwlan_version.h +++ b/CORE/MAC/inc/qwlan_version.h @@ -42,9 +42,9 @@ BRIEF DESCRIPTION: #define QWLAN_VERSION_MINOR 0 #define QWLAN_VERSION_PATCH 0 #define QWLAN_VERSION_EXTRA "" -#define QWLAN_VERSION_BUILD 30 +#define QWLAN_VERSION_BUILD 31 -#define QWLAN_VERSIONSTR "1.0.0.30" +#define QWLAN_VERSIONSTR "1.0.0.31" #ifdef QCA_WIFI_2_0 -- cgit v1.2.3