summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrakash Dhavali <pdhavali@codeaurora.org>2014-02-08 11:11:53 -0800
committerPrakash Dhavali <pdhavali@codeaurora.org>2014-02-08 11:15:10 -0800
commite71909cd0077c2a5d3118cb415aa8a351a7dbb6d (patch)
tree53fa194004fad9ee6e26429e48a6b90eb364e651
parent5af3ed16d9d7ff1b7e7d3baea2492e6d44209f18 (diff)
parentf69dd0f17872aeb162c48241adf3b7321b09c8ee (diff)
Merge remote-tracking branch 'origin/caf/caf-wlan/master'
Release 1.0.0.31 QCA CLD WLAN Host Driver * origin/caf/caf-wlan/master: Cafstaging Release 1.0.0.31 qcacld: ipa: Add interface specific changes qcacld: ipa: Remove IPA_RM_RESOURCE_A2_CONS usage qcacld: Add function of updating macaddress from wlan_mac.bin qcacld: Silent recovery on FW dump failure qcacld: Integrating batch scan fixes from pronto wlan:qcacld:rome_ibss: Added Rome IBSS WEP Security support qcacld: Define open source flag based on license qcacld: CL 835222 - update fw common interface files wlan: make BAP module 64 bit clean
-rw-r--r--Android.mk4
-rw-r--r--CORE/BAP/src/bapApiData.c14
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.c50
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.h5
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg.h1
-rw-r--r--CORE/HDD/inc/wlan_hdd_ipa.h12
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h47
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c10
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg.c110
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c12
-rw-r--r--CORE/HDD/src/wlan_hdd_hostapd.c15
-rw-r--r--CORE/HDD/src/wlan_hdd_ipa.c1217
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c566
-rw-r--r--CORE/MAC/inc/qwlan_version.h4
-rw-r--r--CORE/SERVICES/BMI/ol_fw.c39
-rw-r--r--CORE/SERVICES/BMI/ol_fw.h4
-rw-r--r--CORE/SERVICES/COMMON/wmi_services.h3
-rw-r--r--CORE/SERVICES/COMMON/wmi_tlv_defs.h18
-rw-r--r--CORE/SERVICES/COMMON/wmi_unified.h27
-rw-r--r--CORE/SERVICES/COMMON/wmi_version.h4
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.c9
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.h2
-rw-r--r--CORE/SERVICES/WMA/wma.c26
-rw-r--r--CORE/SERVICES/WMI/wmi_unified.c2
-rw-r--r--CORE/SME/src/csr/csrApiRoam.c10
-rw-r--r--CORE/VOSS/inc/wlan_hdd_misc.h3
-rw-r--r--CORE/VOSS/src/vos_trace.c7
-rw-r--r--Kbuild15
-rw-r--r--Makefile10
29 files changed, 1329 insertions, 917 deletions
diff --git a/Android.mk b/Android.mk
index de83532a4213..f86c223bcb1e 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
@@ -69,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/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
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 <ol_txrx_osif_api.h>
+#include <adf_os_lock.h>
+
#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_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/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 <mach/ipa.h>
-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 5883fa0ad236..0f741496f550 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;
@@ -1023,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)
@@ -1376,4 +1382,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_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_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_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_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 1037154ac026..3518e8f62882 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)
@@ -504,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)
@@ -589,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 77a7b818f86a..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 <wlan_hdd_softap_tx_rx.h>
#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;
}
@@ -386,17 +421,15 @@ 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
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,
@@ -404,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,
@@ -480,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++;
@@ -503,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++;
@@ -519,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++;
@@ -530,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) {
@@ -588,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);
@@ -614,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;
@@ -682,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++;
@@ -701,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);
@@ -742,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++;
@@ -783,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)
{
@@ -806,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,
@@ -858,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;
@@ -952,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)
{
@@ -989,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;
@@ -1002,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;
@@ -1022,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));
@@ -1086,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++;
}
@@ -1113,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),
@@ -1320,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:
@@ -1390,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;
@@ -1426,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,
@@ -1575,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",
@@ -1589,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.
@@ -1601,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;
@@ -1624,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;
@@ -1634,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;
}
@@ -1655,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
@@ -1666,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/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index c744b22fc977..7beee7f9d478 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;
}
@@ -7701,6 +7786,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;
}
@@ -9021,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/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
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/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 */
@@ -6306,6 +6313,26 @@ typedef struct {
} 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;
/* followed by WMITLV_TAG_ARRAY_BYTE */
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/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
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index a661cdf8ef44..765254829b51 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));
@@ -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++;
}
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";
}
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
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"
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)<buf_len; i+=8)
{
vos_trace_msg( module, level,
- "%02x %02x %02x %02x %02x %02x %02x %02x \n",
+ "%02x %02x %02x %02x %02x %02x %02x %02x",
buf[i],
buf[i+1],
buf[i+2],
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: