Browse Source

Merge commit '0219ae6' into wlan-cmn.driver.lnx.1.0-dev

Sync up wlan-cmn.driver.lnx.1.0-dev to CAF 5.0.0.160
from 5.0.0.149 release as baseline for subsequent win
and mcl convergence refactoring.

* commit '0219ae6': (554 commits)
  Release 5.0.0.160
  qcacld-3.0: Add wma handler for vdev delete and peer delete responses
  Release 5.0.0.159
  qcacld-3.0: Fix Compilation error on WLAN_FEATURE_11W disabled
  qcacld-3.0: Update channel width and center freq
  qcacld-3.0: Move sta state to not connected after try disconnect
  qcacld-3.0: Remove #ifdef FEATURE_WLAN_LFR from HDD
  qcacld-3.0: Remove RRM ie in Assoc Req based on AP capability
  qcacld-3.0: Fix fw statistics parsing on the host
  qcacld-3.0: Fix IPA-uc callback in NON-SMP system
  qcacld-3.0: SAP DFS-3 Feature support in DFS layer
  qcacld-3.0: SAP DFS-3 Feature support in WMA
  qcacld-3.0: correct phy_mode in hdd_chan_change_notify
  qcacld-3.0: move hif_bus_open to hif_open
  qcacld-3.0: Remove hif_claim_device
  qcacld-3.0: Remove epping context from cds
  qcacld-3.0: Enable Tx beamformee in SAP mode
  qcacld-3.0: Set the IMPS enable/disable based on INI
  qcacld-3.0: Fix memory leak in case of fw reset stats command
  qcacld-3.0: Use appropriate API to get total free descriptors
  ...
  qcacld-3.0: Enable athdiag debug support for SNOC devices
  qcacld-3.0: Remove support of power gating parameters
  qcacld-3.0: Add log in vos_mem_alloc if kzalloc takes more than 3 seconds

Change-Id: I903d2b6edfb715570daffbcfcdb46866f04737dc
CRs-Fixed: 688141
Prakash Dhavali 9 years ago
parent
commit
abcec8c47e
100 changed files with 5137 additions and 3800 deletions
  1. 24 6
      Kbuild
  2. 4 0
      Kconfig
  3. 4 6
      config/WCNSS_qcom_cfg.ini
  4. 3 4
      core/bmi/src/bmi.c
  5. 1 1
      core/bmi/src/bmi_2.c
  6. 3 3
      core/bmi/src/i_bmi.h
  7. 9 9
      core/bmi/src/ol_fw.c
  8. 15 3
      core/cdf/inc/cdf_atomic.h
  9. 5 20
      core/cdf/inc/cdf_defer.h
  10. 11 1
      core/cdf/inc/cdf_lock.h
  11. 33 5
      core/cdf/inc/cdf_types.h
  12. 1 1
      core/cdf/inc/cdf_util.h
  13. 157 1
      core/cdf/src/cdf_lock.c
  14. 1 2
      core/cdf/src/cdf_mc_timer.c
  15. 88 7
      core/cdf/src/cdf_memory.c
  16. 15 3
      core/cdf/src/i_cdf_atomic.h
  17. 3 10
      core/cdf/src/i_cdf_defer.h
  18. 131 13
      core/cds/inc/cds_api.h
  19. 53 191
      core/cds/inc/cds_concurrency.h
  20. 4 1
      core/cds/inc/cds_packet.h
  21. 141 105
      core/cds/inc/cds_reg_service.h
  22. 3 19
      core/cds/inc/cds_regdomain.h
  23. 5 13
      core/cds/inc/cds_sched.h
  24. 82 177
      core/cds/src/cds_api.c
  25. 334 116
      core/cds/src/cds_concurrency.c
  26. 3 6
      core/cds/src/cds_packet.c
  27. 156 421
      core/cds/src/cds_reg_service.c
  28. 30 18
      core/cds/src/cds_sched.c
  29. 23 1
      core/cds/src/i_cds_packet.h
  30. 4 2
      core/dp/htt/htt.c
  31. 104 5
      core/dp/htt/htt_h2t.c
  32. 2 1
      core/dp/htt/htt_internal.h
  33. 103 51
      core/dp/htt/htt_rx.c
  34. 9 0
      core/dp/htt/htt_t2h.c
  35. 158 55
      core/dp/htt/htt_tx.c
  36. 4 3
      core/dp/ol/inc/ol_txrx_dbg.h
  37. 15 3
      core/dp/txrx/ol_cfg.c
  38. 2 2
      core/dp/txrx/ol_rx.c
  39. 2 1
      core/dp/txrx/ol_tx_send.c
  40. 80 13
      core/dp/txrx/ol_txrx.c
  41. 6 0
      core/dp/txrx/ol_txrx_flow_control.c
  42. 1 1
      core/hdd/inc/qc_sap_ioctl.h
  43. 10 5
      core/hdd/inc/wlan_hdd_assoc.h
  44. 135 28
      core/hdd/inc/wlan_hdd_cfg.h
  45. 3 3
      core/hdd/inc/wlan_hdd_host_offload.h
  46. 43 58
      core/hdd/inc/wlan_hdd_main.h
  47. 9 6
      core/hdd/inc/wlan_hdd_oemdata.h
  48. 4 62
      core/hdd/inc/wlan_hdd_p2p.h
  49. 0 16
      core/hdd/inc/wlan_hdd_power.h
  50. 15 23
      core/hdd/inc/wlan_hdd_tdls.h
  51. 2 1
      core/hdd/inc/wlan_hdd_trace.h
  52. 0 17
      core/hdd/inc/wlan_hdd_tx_rx.h
  53. 1 7
      core/hdd/inc/wlan_hdd_wext.h
  54. 153 174
      core/hdd/src/wlan_hdd_assoc.c
  55. 139 73
      core/hdd/src/wlan_hdd_cfg.c
  56. 347 154
      core/hdd/src/wlan_hdd_cfg80211.c
  57. 66 12
      core/hdd/src/wlan_hdd_cfg80211.h
  58. 17 19
      core/hdd/src/wlan_hdd_conc_ut.c
  59. 357 79
      core/hdd/src/wlan_hdd_driver_ops.c
  60. 60 33
      core/hdd/src/wlan_hdd_ext_scan.c
  61. 2 2
      core/hdd/src/wlan_hdd_ftm.c
  62. 63 20
      core/hdd/src/wlan_hdd_green_ap.c
  63. 4 0
      core/hdd/src/wlan_hdd_green_ap.h
  64. 148 373
      core/hdd/src/wlan_hdd_hostapd.c
  65. 3 18
      core/hdd/src/wlan_hdd_hostapd.h
  66. 139 43
      core/hdd/src/wlan_hdd_ioctl.c
  67. 87 54
      core/hdd/src/wlan_hdd_ipa.c
  68. 5 2
      core/hdd/src/wlan_hdd_lro.c
  69. 437 290
      core/hdd/src/wlan_hdd_main.c
  70. 2 12
      core/hdd/src/wlan_hdd_memdump.c
  71. 9 10
      core/hdd/src/wlan_hdd_nan.c
  72. 2 110
      core/hdd/src/wlan_hdd_ocb.c
  73. 14 50
      core/hdd/src/wlan_hdd_oemdata.c
  74. 18 250
      core/hdd/src/wlan_hdd_p2p.c
  75. 93 114
      core/hdd/src/wlan_hdd_power.c
  76. 20 32
      core/hdd/src/wlan_hdd_scan.c
  77. 0 3
      core/hdd/src/wlan_hdd_scan.h
  78. 9 10
      core/hdd/src/wlan_hdd_softap_tx_rx.c
  79. 23 17
      core/hdd/src/wlan_hdd_stats.c
  80. 23 0
      core/hdd/src/wlan_hdd_stats.h
  81. 195 0
      core/hdd/src/wlan_hdd_subnet_detect.c
  82. 44 0
      core/hdd/src/wlan_hdd_subnet_detect.h
  83. 190 125
      core/hdd/src/wlan_hdd_tdls.c
  84. 8 4
      core/hdd/src/wlan_hdd_trace.c
  85. 18 6
      core/hdd/src/wlan_hdd_tx_rx.c
  86. 24 58
      core/hdd/src/wlan_hdd_wext.c
  87. 0 4
      core/hdd/src/wlan_hdd_wmm.c
  88. 3 3
      core/hdd/src/wlan_hdd_wowl.c
  89. 62 12
      core/hif/inc/hif.h
  90. 37 0
      core/hif/inc/platform_icnss.h
  91. 0 4
      core/hif/src/adrastea_reg_def.h
  92. 0 5
      core/hif/src/ath_procfs.c
  93. 44 0
      core/hif/src/ce/ce_internal.h
  94. 23 44
      core/hif/src/ce/ce_main.c
  95. 1 3
      core/hif/src/ce/ce_main.h
  96. 138 7
      core/hif/src/ce/ce_service.c
  97. 9 0
      core/hif/src/ce/ce_tasklet.c
  98. 17 36
      core/hif/src/hif_main.c
  99. 3 9
      core/hif/src/hif_main.h
  100. 27 0
      core/hif/src/icnss_stub/icnss_stub.c

+ 24 - 6
Kbuild

@@ -130,6 +130,9 @@ ifeq ($(KERNEL_BUILD), 0)
 			CONFIG_WLAN_LRO := n
 		endif
 	endif
+
+	# Flag to enable LFR Subnet Detection
+	CONFIG_LFR_SUBNET_DETECTION := y
 endif
 
 ifneq ($(CONFIG_MOBILE_ROUTER), y)
@@ -250,10 +253,6 @@ CONFIG_FEATURE_SECURE_FIRMWARE := 0
 #Flag to enable Stats Ext implementation
 CONFIG_FEATURE_STATS_EXT := 1
 
-#Flag to force the inclusion of the 802.11p channels because support
-#for these channels has not yet been added to the kernel.
-CONFIG_STATICALLY_ADD_11P_CHANNELS := n
-
 ifeq ($(CONFIG_CFG80211),y)
 HAVE_CFG80211 := 1
 else
@@ -338,6 +337,10 @@ ifeq ($(CONFIG_WLAN_FEATURE_MEMDUMP),y)
 HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_memdump.o
 endif
 
+ifeq ($(CONFIG_LFR_SUBNET_DETECTION), y)
+HDD_OBJS +=	$(HDD_SRC_DIR)/wlan_hdd_subnet_detect.o
+endif
+
 ########### HOST DIAG LOG ###########
 HOST_DIAG_LOG_DIR :=	core/utils/host_diag_log
 
@@ -907,6 +910,10 @@ CDEFINES += -DADRASTEA_SHADOW_REGISTERS
 CDEFINES += -DADRASTEA_RRI_ON_DDR
 endif
 
+ifneq (y,$(filter y,$(CONFIG_CNSS_EOS) $(CONFIG_ICNSS) $(CONFIG_CNSS_ADRASTEA)))
+CDEFINES += -DQCA_WIFI_2_0
+endif
+
 ifeq ($(CONFIG_WLAN_FASTPATH), y)
 CDEFINES +=	-DWLAN_FEATURE_FASTPATH
 endif
@@ -1266,6 +1273,16 @@ ifeq (y, $(filter y, $(CONFIG_CNSS_ADRASTEA) $(CONFIG_ICNSS)))
 CDEFINES += -DWLAN_FEATURE_RX_FULL_REORDER_OL
 endif
 
+# Enable athdiag procfs debug support for adrastea
+ifeq (y, $(filter y, $(CONFIG_CNSS_ADRASTEA) $(CONFIG_ICNSS)))
+CDEFINES += -DCONFIG_ATH_PROCFS_DIAG_SUPPORT
+endif
+
+# Enable 11AC TX compact feature for adrastea
+ifeq (y, $(filter y, $(CONFIG_CNSS_ADRASTEA) $(CONFIG_ICNSS)))
+CDEFINES += -DATH_11AC_TXCOMPACT
+endif
+
 # NOTE: CONFIG_64BIT_PADDR requires CONFIG_HELIUMPLUS
 ifeq (y,$(filter y,$(CONFIG_CNSS_EOS) $(CONFIG_ICNSS)))
 CONFIG_HELIUMPLUS := y
@@ -1275,6 +1292,7 @@ CONFIG_FEATURE_TSO_DEBUG := y
 ifeq ($(CONFIG_HELIUMPLUS),y)
 CDEFINES += -DHELIUMPLUS_PADDR64
 CDEFINES += -DHELIUMPLUS
+CDEFINES += -DAR900B
 ifeq ($(CONFIG_64BIT_PADDR),y)
 CDEFINES += -DHTT_PADDR64
 endif
@@ -1308,8 +1326,8 @@ ifeq ($(CONFIG_WLAN_FEATURE_MEMDUMP),y)
 CDEFINES += -DWLAN_FEATURE_MEMDUMP
 endif
 
-ifeq ($(CONFIG_STATICALLY_ADD_11P_CHANNELS),y)
-CDEFINES += -DFEATURE_STATICALLY_ADD_11P_CHANNELS
+ifeq ($(CONFIG_LFR_SUBNET_DETECTION), y)
+CDEFINES += -DFEATURE_LFR_SUBNET_DETECTION
 endif
 
 KBUILD_CPPFLAGS += $(CDEFINES)

+ 4 - 0
Kconfig

@@ -107,4 +107,8 @@ config WLAN_FEATURE_RX_WAKELOCK
 	bool "Enable RX wake lock feature"
 	default n
 
+config FEATURE_LFR_SUBNET_DETECTION
+	bool "Enable LFR Subnet Change Detection"
+	default n
+
 endif # QCA_CLD_WLAN

+ 4 - 6
config/WCNSS_qcom_cfg.ini

@@ -311,8 +311,6 @@ gEnableDFSChnlScan=1
 gAllowDFSChannelRoam=1
 
 gVhtChannelWidth=2
-gEnableLogp=1
-
 
 # Enable Automatic Tx Power control
 
@@ -369,6 +367,9 @@ gEnableRXLDPC=1
 #Enable/Disable Tx beamforming
 gTxBFEnable=1
 
+#Enable/Disable Tx beamformee in SAP mode
+gEnableTxBFeeSAP=1
+
 # Enable Tx beamforming in VHT20MHz
 # Valid values are 0,1. If commented out, the default value is 0.
 # 0=disable, 1=enable
@@ -420,9 +421,6 @@ gEnablePowerSaveOffload=2
 #Enable firmware uart print
 gEnablefwprint=0
 
-#Enable firmware log
-gEnablefwlog=1
-
 #IPA config
 gIPAConfig=0
 gIPADescSize=800
@@ -464,7 +462,7 @@ isP2pDeviceAddrAdministrated=0
 gEnableRxThread=1
 
 #Enable NAPI
-gEnableNAPI=0
+gEnableNAPI=1
 
 # Set Thermal Power limit
 TxPower2g=10

+ 3 - 4
core/bmi/src/bmi.c

@@ -1,5 +1,5 @@
 /*
- * copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -110,9 +110,8 @@ void bmi_cleanup(struct ol_softc *scn)
 CDF_STATUS bmi_done(struct ol_softc *scn)
 {
 	CDF_STATUS status = CDF_STATUS_SUCCESS;
-	hif_claim_device(scn, scn);
 
-	if (IHELIUM_NO_BMI)
+	if (NO_BMI)
 		return status;
 
 	status = bmi_done_local(scn);
@@ -175,7 +174,7 @@ CDF_STATUS bmi_download_firmware(struct ol_softc *scn)
 	uint32_t address;
 	int32_t ret;
 
-	if (IHELIUM_NO_BMI)
+	if (NO_BMI)
 		return CDF_STATUS_SUCCESS; /* no BMI for Q6 bring up */
 
 	if (!scn) {

+ 1 - 1
core/bmi/src/bmi_2.c

@@ -429,7 +429,7 @@ CDF_STATUS bmi_firmware_download(struct ol_softc *scn)
 {
 	CDF_STATUS status;
 
-	if (IHELIUM_NO_BMI)
+	if (NO_BMI)
 		return CDF_STATUS_SUCCESS;
 
 	status = bmi_init(scn);

+ 3 - 3
core/bmi/src/i_bmi.h

@@ -118,10 +118,10 @@ typedef enum _ATH_BIN_FILE {
 	ATH_SETUP_FILE,
 } ATH_BIN_FILE;
 
-#if defined(QCA_WIFI_3_0_IHELIUM) || defined(QCA_WIFI_3_0_ADRASTEA)
-#define IHELIUM_NO_BMI 1
+#if defined(QCA_WIFI_3_0_ADRASTEA)
+#define NO_BMI 1
 #else
-#define IHELIUM_NO_BMI 0
+#define NO_BMI 0
 #endif
 
 CDF_STATUS bmi_execute(uint32_t address, uint32_t *param,

+ 9 - 9
core/bmi/src/ol_fw.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -81,7 +81,7 @@ static int ol_check_fw_hash(const u8 *data, u32 fw_size, ATH_BIN_FILE file)
 		break;
 	case ATH_FIRMWARE_FILE:
 #ifdef QCA_WIFI_FTM
-		if (cds_get_conparam() == CDF_FTM_MODE) {
+		if (cds_get_conparam() == CDF_GLOBAL_FTM_MODE) {
 			hash = fw_hash.utf;
 			break;
 		}
@@ -173,7 +173,7 @@ static int __ol_transfer_bin_file(struct ol_softc *scn, ATH_BIN_FILE file,
 			break;
 		}
 #ifdef QCA_WIFI_FTM
-		if (cds_get_conparam() == CDF_FTM_MODE) {
+		if (cds_get_conparam() == CDF_GLOBAL_FTM_MODE) {
 #if defined(CONFIG_CNSS)
 			filename = scn->fw_files.utf_file;
 #else
@@ -201,7 +201,7 @@ static int __ol_transfer_bin_file(struct ol_softc *scn, ATH_BIN_FILE file,
 		return 0;
 	case ATH_BOARD_DATA_FILE:
 #ifdef QCA_WIFI_FTM
-		if (cds_get_conparam() == CDF_FTM_MODE) {
+		if (cds_get_conparam() == CDF_GLOBAL_FTM_MODE) {
 #if defined(CONFIG_CNSS)
 			filename = scn->fw_files.utf_board_data;
 #else
@@ -225,7 +225,7 @@ static int __ol_transfer_bin_file(struct ol_softc *scn, ATH_BIN_FILE file,
 #endif
 		break;
 	case ATH_SETUP_FILE:
-		if (cds_get_conparam() != CDF_FTM_MODE &&
+		if (cds_get_conparam() != CDF_GLOBAL_FTM_MODE &&
 		    !WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
 #ifdef CONFIG_CNSS
 			BMI_INFO("%s: no Setup file defined", __func__);
@@ -618,17 +618,17 @@ void ol_target_failure(void *instance, CDF_STATUS status)
 	}
 	scn->target_status = OL_TRGET_STATUS_RESET;
 
-	if (cds_is_logp_in_progress()) {
-		BMI_ERR("%s: LOGP is in progress, ignore!\n", __func__);
+	if (cds_is_driver_recovering()) {
+		BMI_ERR("%s: Recovery in progress, ignore!\n", __func__);
 		return;
 	}
 
-	if (cds_is_load_unload_in_progress()) {
+	if (cds_is_load_or_unload_in_progress()) {
 		BMI_ERR("%s: Loading/Unloading is in progress, ignore!",
 		       __func__);
 		return;
 	}
-	cds_set_logp_in_progress(true);
+	cds_set_recovery_in_progress(true);
 
 #ifdef CONFIG_CNSS
 	ret = hif_check_fw_reg(scn);

+ 15 - 3
core/cdf/inc/cdf_atomic.h

@@ -62,7 +62,7 @@ static inline void cdf_atomic_init(cdf_atomic_t *v)
  *
  * Return: The current value of the variable
  */
-static inline uint32_t cdf_atomic_read(cdf_atomic_t *v)
+static inline int32_t cdf_atomic_read(cdf_atomic_t *v)
 {
 	return __cdf_atomic_read(v);
 }
@@ -101,6 +101,18 @@ static inline void cdf_atomic_add(int i, cdf_atomic_t *v)
 	__cdf_atomic_add(i, v);
 }
 
+/**
+ * cdf_atomic_sub() - Subtract a value from an atomic variable.
+ * @i: the amount by which to decrease the atomic counter
+ * @v: a pointer to an opaque atomic variable
+ *
+ * Return: none
+ */
+static inline void cdf_atomic_sub(int i, cdf_atomic_t *v)
+{
+	__cdf_atomic_sub(i, v);
+}
+
 /**
  * cdf_atomic_dec_and_test() - decrement an atomic variable and check if the
  *				new value is zero
@@ -110,7 +122,7 @@ static inline void cdf_atomic_add(int i, cdf_atomic_t *v)
  *    true (non-zero) if the new value is zero,
  *    or false (0) if the new value is non-zero
  */
-static inline uint32_t cdf_atomic_dec_and_test(cdf_atomic_t *v)
+static inline int32_t cdf_atomic_dec_and_test(cdf_atomic_t *v)
 {
 	return __cdf_atomic_dec_and_test(v);
 }
@@ -132,7 +144,7 @@ static inline void cdf_atomic_set(cdf_atomic_t *v, int i)
  *
  * Return: The current value of the variable
  */
-static inline uint32_t cdf_atomic_inc_return(cdf_atomic_t *v)
+static inline int32_t cdf_atomic_inc_return(cdf_atomic_t *v)
 {
 	return __cdf_atomic_inc_return(v);
 }

+ 5 - 20
core/cdf/inc/cdf_defer.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -96,7 +96,6 @@ static inline void cdf_destroy_bh(cdf_handle_t hdl, cdf_bh_t *bh)
 /**
  * cdf_create_work() - create a work/task queue, This runs in non-interrupt
  *		       context, so can be preempted by H/W & S/W intr
- * @hdl:	OS handle
  * @work:	Work instance
  * @func:	Deferred function to run at bottom half non-interrupt
  *		context
@@ -105,34 +104,20 @@ static inline void cdf_destroy_bh(cdf_handle_t hdl, cdf_bh_t *bh)
  * Return: None
  */
 static inline void
-cdf_create_work(cdf_handle_t hdl, cdf_work_t *work,
+cdf_create_work(cdf_work_t *work,
 		cdf_defer_fn_t func, void *arg)
 {
-	__cdf_init_work(hdl, work, func, arg);
+	__cdf_init_work(work, func, arg);
 }
 
 /**
  * cdf_sched_work() - schedule a deferred task on non-interrupt context
- * @hdl:	OS handle
- * @work:	Work instance
- *
- * Return: None
- */
-static inline void cdf_sched_work(cdf_handle_t hdl, cdf_work_t *work)
-{
-	__cdf_sched_work(hdl, work);
-}
-
-/**
- * cdf_destroy_work() -  destroy the deferred task (synchronous)
- * @hdl:	OS handle
  * @work:	Work instance
  *
  * Return: None
  */
-static inline void cdf_destroy_work(cdf_handle_t hdl, cdf_work_t *work)
+static inline void cdf_schedule_work(cdf_work_t *work)
 {
-	__cdf_disable_work(hdl, work);
+	__cdf_schedule_work(work);
 }
-
 #endif /*__CDF_DEFER_H*/

+ 11 - 1
core/cdf/inc/cdf_lock.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -262,6 +262,16 @@ CDF_STATUS cdf_wake_lock_release(cdf_wake_lock_t *pLock, uint32_t reason);
  */
 CDF_STATUS cdf_wake_lock_destroy(cdf_wake_lock_t *pLock);
 
+struct hif_pm_runtime_lock;
+typedef struct hif_pm_runtime_lock *cdf_runtime_lock_t;
+
+CDF_STATUS cdf_runtime_pm_get(void);
+CDF_STATUS cdf_runtime_pm_put(void);
+CDF_STATUS cdf_runtime_pm_prevent_suspend(cdf_runtime_lock_t lock);
+CDF_STATUS cdf_runtime_pm_allow_suspend(cdf_runtime_lock_t lock);
+cdf_runtime_lock_t cdf_runtime_lock_init(const char *name);
+void cdf_runtime_lock_deinit(cdf_runtime_lock_t lock);
+
 /**
  * cdf_spinlock_acquire() - acquires a spin lock
  * @lock:	Spin lock to acquire

+ 33 - 5
core/cdf/inc/cdf_types.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -266,7 +266,7 @@ typedef enum {
 #define cdf_snprint       __cdf_snprint
 
 /**
- * typedef enum tCDF_CON_MODE - Concurrency role.
+ * enum tCDF_ADAPTER_MODE - adapter role.
  *
  * @CDF_STA_MODE: STA mode
  * @CDF_SAP_MODE: SAP mode
@@ -282,18 +282,35 @@ typedef enum {
  * These are generic IDs that identify the various roles
  * in the software system
  */
-typedef enum {
+enum tCDF_ADAPTER_MODE {
 	CDF_STA_MODE = 0,
 	CDF_SAP_MODE = 1,
 	CDF_P2P_CLIENT_MODE,
 	CDF_P2P_GO_MODE,
-	CDF_FTM_MODE = 5,
+	CDF_FTM_MODE,
 	CDF_IBSS_MODE,
 	CDF_P2P_DEVICE_MODE,
 	CDF_EPPING_MODE,
 	CDF_OCB_MODE,
 	CDF_MAX_NO_OF_MODE
-} tCDF_CON_MODE;
+};
+
+/**
+ * enum tCDF_GLOBAL_CON_MODE - global config mode when
+ * driver is loaded.
+ *
+ * @CDF_GLOBAL_MISSION_MODE: mission mode (STA, SAP...)
+ * @CDF_GLOBAL_FTM_MODE: FTM mode
+ * @CDF_GLOBAL_EPPING_MODE: EPPING mode
+ * @CDF_GLOBAL_MAX_MODE: Max place holder
+ */
+enum tCDF_GLOBAL_CON_MODE {
+	CDF_GLOBAL_MISSION_MODE,
+	CDF_GLOBAL_FTM_MODE = 5,
+	CDF_GLOBAL_EPPING_MODE = 8,
+	CDF_GLOBAL_MAX_MODE
+};
+
 
 #ifdef WLAN_OPEN_P2P_INTERFACE
 /* This should match with WLAN_MAX_INTERFACES */
@@ -353,6 +370,7 @@ struct cdf_mac_addr {
 #define CDF_MAC_ADDR_ZERO_INITIALIZER { { 0, 0, 0, 0, 0, 0 } }
 
 #define CDF_IPV4_ADDR_SIZE (4)
+#define CDF_IPV6_ADDR_SIZE (16)
 
 /**
  * struct cdf_tso_frag_t - fragments of a single TCP segment
@@ -490,4 +508,14 @@ struct cdf_tso_info_t {
  */
 #define CDF_CE_TX_PKT_OFFSET_BIT_M	0x0fff0000
 
+/**
+ * enum cdf_suspend_type - type of suspend
+ * CDF_SYSTEM_SUSPEND: System suspend triggered wlan suspend
+ * CDF_RUNTIME_SUSPEND: Runtime pm inactivity timer triggered wlan suspend
+ */
+enum cdf_suspend_type {
+	CDF_SYSTEM_SUSPEND,
+	CDF_RUNTIME_SUSPEND
+};
+
 #endif /* if !defined __CDF_TYPES_H */

+ 1 - 1
core/cdf/inc/cdf_util.h

@@ -140,7 +140,7 @@ CDF_INLINE_FN bool cdf_is_macaddr_equal(struct cdf_mac_addr *pMacAddr1,
  *
  *
  * Return:  true if the MacAddress is all Zeros
- *	flase if the MacAddress is not all Zeros.
+ *	false if the MacAddress is not all Zeros.
  *
  */
 CDF_INLINE_FN bool cdf_is_macaddr_zero(struct cdf_mac_addr *pMacAddr)

+ 157 - 1
core/cdf/src/cdf_lock.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -46,6 +46,7 @@
 #include "i_host_diag_core_event.h"
 #include "cds_api.h"
 #include "ani_global.h"
+#include "hif.h"
 
 /* Preprocessor Definitions and Constants */
 #define LINUX_LOCK_COOKIE 0x12345678
@@ -489,3 +490,158 @@ CDF_STATUS cdf_wake_lock_destroy(cdf_wake_lock_t *pLock)
 #endif
 	return CDF_STATUS_SUCCESS;
 }
+
+/**
+ * cdf_runtime_pm_get() - do a get opperation on the device
+ *
+ * A get opperation will prevent a runtime suspend untill a
+ * corresponding put is done.  This api should be used when sending
+ * data.
+ *
+ * CONTRARY TO THE REGULAR RUNTIME PM, WHEN THE BUS IS SUSPENDED,
+ * THIS API WILL ONLY REQUEST THE RESUME AND NOT TO A GET!!!
+ *
+ * return: success if the bus is up and a get has been issued
+ *   otherwise an error code.
+ */
+CDF_STATUS cdf_runtime_pm_get(void)
+{
+	void *ol_sc;
+	int ret;
+
+	ol_sc = cds_get_context(CDF_MODULE_ID_HIF);
+
+	if (ol_sc == NULL) {
+		CDF_ASSERT(0);
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
+				"%s: HIF context is null!", __func__);
+		return CDF_STATUS_E_INVAL;
+	}
+
+	ret = hif_pm_runtime_get(ol_sc);
+
+	if (ret)
+		return CDF_STATUS_E_FAILURE;
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * cdf_runtime_pm_put() - do a put opperation on the device
+ *
+ * A put opperation will allow a runtime suspend after a corresponding
+ * get was done.  This api should be used when sending data.
+ *
+ * This api will return a failure if the hif module hasn't been initialized
+ *
+ * return: CDF_STATUS_SUCCESS if the put is performed
+ */
+CDF_STATUS cdf_runtime_pm_put(void)
+{
+	void *ol_sc;
+	int ret;
+
+	ol_sc = cds_get_context(CDF_MODULE_ID_HIF);
+
+	if (ol_sc == NULL) {
+		CDF_ASSERT(0);
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
+				"%s: HIF context is null!", __func__);
+		return CDF_STATUS_E_INVAL;
+	}
+
+	ret = hif_pm_runtime_put(ol_sc);
+
+	if (ret)
+		return CDF_STATUS_E_FAILURE;
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * cdf_runtime_pm_prevent_suspend() - prevent a runtime bus suspend
+ * @lock: an opaque context for tracking
+ *
+ * The lock can only be acquired once per lock context and is tracked.
+ *
+ * return: CDF_STATUS_SUCCESS or failure code.
+ */
+CDF_STATUS cdf_runtime_pm_prevent_suspend(cdf_runtime_lock_t lock)
+{
+	void *ol_sc;
+	int ret;
+
+	ol_sc = cds_get_context(CDF_MODULE_ID_HIF);
+
+	if (ol_sc == NULL) {
+		CDF_ASSERT(0);
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
+				"%s: HIF context is null!", __func__);
+		return CDF_STATUS_E_INVAL;
+	}
+
+	ret = hif_pm_runtime_prevent_suspend(ol_sc, lock);
+
+	if (ret)
+		return CDF_STATUS_E_FAILURE;
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * cdf_runtime_pm_prevent_suspend() - prevent a runtime bus suspend
+ * @lock: an opaque context for tracking
+ *
+ * The lock can only be acquired once per lock context and is tracked.
+ *
+ * return: CDF_STATUS_SUCCESS or failure code.
+ */
+CDF_STATUS cdf_runtime_pm_allow_suspend(cdf_runtime_lock_t lock)
+{
+	void *ol_sc;
+	int ret;
+
+	ol_sc = cds_get_context(CDF_MODULE_ID_HIF);
+
+	if (ol_sc == NULL) {
+		CDF_ASSERT(0);
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
+				"%s: HIF context is null!", __func__);
+		return CDF_STATUS_E_INVAL;
+	}
+
+	ret = hif_pm_runtime_allow_suspend(ol_sc, lock);
+
+	if (ret)
+		return CDF_STATUS_E_FAILURE;
+
+	return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * cdf_runtime_lock_init() - initialize runtime lock
+ * @name: name of the runtime lock
+ *
+ * Initialize a runtime pm lock.  This lock can be used
+ * to prevent the runtime pm system from putting the bus
+ * to sleep.
+ *
+ * Return: runtime_pm_lock_t
+ */
+cdf_runtime_lock_t cdf_runtime_lock_init(const char *name)
+{
+	return hif_runtime_lock_init(name);
+}
+
+/**
+ * cdf_runtime_lock_deinit() - deinitialize runtime pm lock
+ * @lock: the lock to deinitialize
+ *
+ * Ensures the lock is released. Frees the runtime lock.
+ *
+ * Return: void
+ */
+void cdf_runtime_lock_deinit(cdf_runtime_lock_t lock)
+{
+	hif_runtime_lock_deinit(lock);
+}

+ 1 - 2
core/cdf/src/cdf_mc_timer.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -247,7 +247,6 @@ static void cdf_timer_clean(void);
  */
 void cdf_mc_timer_manager_init(void)
 {
-	/* Initalizing the list with maximum size of 60000 */
 	cdf_list_init(&cdf_timer_list, 1000);
 	cdf_spinlock_init(&cdf_timer_list_lock);
 	return;

+ 88 - 7
core/cdf/src/cdf_memory.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -36,6 +36,7 @@
 #include "cdf_nbuf.h"
 #include "cdf_trace.h"
 #include "cdf_lock.h"
+#include "cdf_mc_timer.h"
 
 #if defined(CONFIG_CNSS)
 #include <net/cnss.h>
@@ -47,6 +48,7 @@
 
 #ifdef MEMORY_DEBUG
 #include <cdf_list.h>
+#include <linux/stacktrace.h>
 
 cdf_list_t cdf_mem_list;
 cdf_spinlock_t cdf_mem_list_lock;
@@ -56,16 +58,23 @@ static uint8_t WLAN_MEM_HEADER[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
 static uint8_t WLAN_MEM_TAIL[] = { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85,
 					0x86, 0x87 };
 
+#define CDF_MEM_MAX_STACK_TRACE 16
+
 struct s_cdf_mem_struct {
 	cdf_list_node_t pNode;
 	char *fileName;
 	unsigned int lineNum;
 	unsigned int size;
+#ifdef WLAN_OPEN_SOURCE
+	unsigned long stack_trace[CDF_MEM_MAX_STACK_TRACE];
+	struct stack_trace trace;
+#endif
 	uint8_t header[8];
 };
 #endif
 
 /* Preprocessor Definitions and Constants */
+#define CDF_GET_MEMORY_TIME_THRESHOLD 3000
 
 /* Type Declarations */
 
@@ -73,6 +82,51 @@ struct s_cdf_mem_struct {
 
 /* External Function implementation */
 #ifdef MEMORY_DEBUG
+#ifdef WLAN_OPEN_SOURCE
+/**
+ * cdf_mem_save_stack_trace() - Save stack trace of the caller
+ * @mem_struct: Pointer to the memory structure where to save the stack trace
+ *
+ * Return: None
+ */
+static inline void cdf_mem_save_stack_trace(struct s_cdf_mem_struct *mem_struct)
+{
+	struct stack_trace *trace = &mem_struct->trace;
+
+	trace->nr_entries = 0;
+	trace->max_entries = CDF_MEM_MAX_STACK_TRACE;
+	trace->entries = mem_struct->stack_trace;
+	trace->skip = 2;
+
+	save_stack_trace(trace);
+}
+
+/**
+ * cdf_mem_print_stack_trace() - Print saved stack trace
+ * @mem_struct: Pointer to the memory structure which has the saved stack trace
+ *              to be printed
+ *
+ * Return: None
+ */
+static inline void cdf_mem_print_stack_trace(struct s_cdf_mem_struct
+					     *mem_struct)
+{
+	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
+		  "Call stack for the source of leaked memory:");
+
+	print_stack_trace(&mem_struct->trace, 1);
+}
+#else
+static inline void cdf_mem_save_stack_trace(struct s_cdf_mem_struct *mem_struct)
+{
+
+}
+static inline void cdf_mem_print_stack_trace(struct s_cdf_mem_struct
+					     *mem_struct)
+{
+
+}
+#endif
 
 /**
  * cdf_mem_init() - initialize cdf memory debug functionality
@@ -142,6 +196,7 @@ void cdf_mem_clean(void)
 					mleak_cnt = 0;
 				}
 				mleak_cnt++;
+				cdf_mem_print_stack_trace(memStruct);
 				kfree((void *)memStruct);
 			}
 		} while (cdf_status == CDF_STATUS_SUCCESS);
@@ -194,6 +249,7 @@ void *cdf_mem_malloc_debug(size_t size, char *fileName, uint32_t lineNum)
 	void *memPtr = NULL;
 	uint32_t new_size;
 	int flags = GFP_KERNEL;
+	unsigned long  time_before_kzalloc;
 
 	if (size > (1024 * 1024) || size == 0) {
 		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
@@ -217,8 +273,19 @@ void *cdf_mem_malloc_debug(size_t size, char *fileName, uint32_t lineNum)
 		flags = GFP_ATOMIC;
 
 	new_size = size + sizeof(struct s_cdf_mem_struct) + 8;
-
+	time_before_kzalloc = cdf_mc_timer_get_system_time();
 	memStruct = (struct s_cdf_mem_struct *)kzalloc(new_size, flags);
+	/**
+	 * If time taken by kmalloc is greater than
+	 * CDF_GET_MEMORY_TIME_THRESHOLD msec
+	 */
+	if (cdf_mc_timer_get_system_time() - time_before_kzalloc >=
+					  CDF_GET_MEMORY_TIME_THRESHOLD)
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
+			 "%s: kzalloc took %lu msec for size %zu called from %pS at line %d",
+			 __func__,
+			 cdf_mc_timer_get_system_time() - time_before_kzalloc,
+			 size, (void *)_RET_IP_, lineNum);
 
 	if (memStruct != NULL) {
 		CDF_STATUS cdf_status;
@@ -226,6 +293,7 @@ void *cdf_mem_malloc_debug(size_t size, char *fileName, uint32_t lineNum)
 		memStruct->fileName = fileName;
 		memStruct->lineNum = lineNum;
 		memStruct->size = size;
+		cdf_mem_save_stack_trace(memStruct);
 
 		cdf_mem_copy(&memStruct->header[0],
 			     &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER));
@@ -324,9 +392,9 @@ void cdf_mem_free(void *ptr)
 void *cdf_mem_malloc(size_t size)
 {
 	int flags = GFP_KERNEL;
-#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC
-	void *pmem;
-#endif
+	void *memPtr = NULL;
+	unsigned long  time_before_kzalloc;
+
 	if (size > (1024 * 1024) || size == 0) {
 		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 			  "%s: called with invalid arg; passed in %zu !!",
@@ -336,6 +404,7 @@ void *cdf_mem_malloc(size_t size)
 
 #if defined(CONFIG_CNSS) && defined(CONFIG_WCNSS_MEM_PRE_ALLOC)
 	if (size > WCNSS_PRE_ALLOC_GET_THRESHOLD) {
+		void *pmem;
 		pmem = wcnss_prealloc_get(size);
 		if (NULL != pmem) {
 			memset(pmem, 0, size);
@@ -346,8 +415,20 @@ void *cdf_mem_malloc(size_t size)
 
 	if (in_interrupt() || irqs_disabled() || in_atomic())
 		flags = GFP_ATOMIC;
-
-	return kzalloc(size, flags);
+	time_before_kzalloc = cdf_mc_timer_get_system_time();
+	memPtr = kzalloc(size, flags);
+	/**
+	 * If time taken by kmalloc is greater than
+	 * CDF_GET_MEMORY_TIME_THRESHOLD msec
+	 */
+	if (cdf_mc_timer_get_system_time() - time_before_kzalloc >=
+					   CDF_GET_MEMORY_TIME_THRESHOLD)
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
+			 "%s: kzalloc took %lu msec for size %zu called from %pS",
+			 __func__,
+			 cdf_mc_timer_get_system_time() - time_before_kzalloc,
+			 size, (void *)_RET_IP_);
+	return memPtr;
 }
 
 /**

+ 15 - 3
core/cdf/src/i_cdf_atomic.h

@@ -40,7 +40,7 @@ static inline CDF_STATUS __cdf_atomic_init(__cdf_atomic_t *v)
 	return CDF_STATUS_SUCCESS;
 }
 
-static inline uint32_t __cdf_atomic_read(__cdf_atomic_t *v)
+static inline int32_t __cdf_atomic_read(__cdf_atomic_t *v)
 {
 	return atomic_read(v);
 }
@@ -60,7 +60,19 @@ static inline void __cdf_atomic_add(int i, __cdf_atomic_t *v)
 	atomic_add(i, v);
 }
 
-static inline uint32_t __cdf_atomic_dec_and_test(__cdf_atomic_t *v)
+/**
+ * cdf_atomic_sub() - Subtract a value from an atomic variable
+ * @i: the amount by which to decrease the atomic counter
+ * @v: a pointer to an opaque atomic variable
+ *
+ * Return: none
+ */
+static inline void __cdf_atomic_sub(int i, __cdf_atomic_t *v)
+{
+	atomic_sub(i, v);
+}
+
+static inline int32_t __cdf_atomic_dec_and_test(__cdf_atomic_t *v)
 {
 	return atomic_dec_and_test(v);
 }
@@ -70,7 +82,7 @@ static inline void __cdf_atomic_set(__cdf_atomic_t *v, int i)
 	atomic_set(v, i);
 }
 
-static inline uint32_t __cdf_atomic_inc_return(__cdf_atomic_t *v)
+static inline int32_t __cdf_atomic_inc_return(__cdf_atomic_t *v)
 {
 	return atomic_inc_return(v);
 }

+ 3 - 10
core/cdf/src/i_cdf_defer.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -52,8 +52,7 @@ typedef struct {
 extern void __cdf_defer_func(struct work_struct *work);
 
 static inline CDF_STATUS
-__cdf_init_work(cdf_handle_t hdl,
-		__cdf_work_t *work, cdf_defer_fn_t func, void *arg)
+__cdf_init_work(__cdf_work_t *work, cdf_defer_fn_t func, void *arg)
 {
 	/*Initilize func and argument in work struct */
 	work->fn = func;
@@ -66,18 +65,12 @@ __cdf_init_work(cdf_handle_t hdl,
 	return CDF_STATUS_SUCCESS;
 }
 
-static inline CDF_STATUS __cdf_sched_work(cdf_handle_t hdl, __cdf_work_t *work)
+static inline CDF_STATUS __cdf_schedule_work(__cdf_work_t *work)
 {
 	schedule_work(&work->work);
 	return CDF_STATUS_SUCCESS;
 }
 
-static inline CDF_STATUS
-__cdf_disable_work(cdf_handle_t hdl, __cdf_work_t *work)
-{
-	return CDF_STATUS_SUCCESS;
-}
-
 static inline CDF_STATUS __cdf_init_bh(cdf_handle_t hdl,
 				       struct tasklet_struct *bh,
 				       cdf_defer_fn_t func, void *arg)

+ 131 - 13
core/cds/inc/cds_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -55,13 +55,139 @@
  */
 #define CDS_WMA_TIMEOUT  (15000)
 
-CDF_STATUS cds_alloc_global_context(v_CONTEXT_t *p_cds_context);
+/**
+ * enum cds_driver_state - Driver state
+ * @CDS_DRIVER_STATE_UNINITIALIZED: Driver is in uninitialized state.
+ * CDS_DRIVER_STATE_LOADED: Driver is loaded and functional.
+ * CDS_DRIVER_STATE_LOADING: Driver probe is in progress.
+ * CDS_DRIVER_STATE_UNLOADING: Driver remove is in progress.
+ * CDS_DRIVER_STATE_RECOVERING: Recovery in progress.
+ */
+enum cds_driver_state {
+	CDS_DRIVER_STATE_UNINITIALIZED	= 0,
+	CDS_DRIVER_STATE_LOADED		= BIT(0),
+	CDS_DRIVER_STATE_LOADING	= BIT(1),
+	CDS_DRIVER_STATE_UNLOADING	= BIT(2),
+	CDS_DRIVER_STATE_RECOVERING	= BIT(3),
+};
+
+#define __CDS_IS_DRIVER_STATE(_state, _mask) (((_state) & (_mask)) == (_mask))
+
+void cds_set_driver_state(enum cds_driver_state);
+void cds_clear_driver_state(enum cds_driver_state);
+enum cds_driver_state cds_get_driver_state(void);
+
+/**
+ * cds_is_driver_loading() - Is driver load in progress
+ *
+ * Return: true if driver is loading and false otherwise.
+ */
+static inline bool cds_is_driver_loading(void)
+{
+	enum cds_driver_state state = cds_get_driver_state();
+
+	return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_LOADING);
+}
+
+/**
+ * cds_is_driver_unloading() - Is driver unload in progress
+ *
+ * Return: true if driver is unloading and false otherwise.
+ */
+static inline bool cds_is_driver_unloading(void)
+{
+	enum cds_driver_state state = cds_get_driver_state();
+
+	return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_UNLOADING);
+}
 
-CDF_STATUS cds_free_global_context(v_CONTEXT_t *p_cds_context);
+/**
+ * cds_is_driver_recovering() - Is recovery in progress
+ *
+ * Return: true if recovery in progress  and false otherwise.
+ */
+static inline bool cds_is_driver_recovering(void)
+{
+	enum cds_driver_state state = cds_get_driver_state();
+
+	return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_RECOVERING);
+}
+
+/**
+ * cds_is_load_or_unload_in_progress() - Is driver load OR unload in progress
+ *
+ * Return: true if driver is loading OR unloading and false otherwise.
+ */
+static inline bool cds_is_load_or_unload_in_progress(void)
+{
+	enum cds_driver_state state = cds_get_driver_state();
+
+	return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_LOADING) ||
+		__CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_UNLOADING);
+}
+
+/**
+ * cds_set_recovery_in_progress() - Set recovery in progress
+ * @value: value to set
+ *
+ * Return: none
+ */
+static inline void cds_set_recovery_in_progress(uint8_t value)
+{
+	if (value)
+		cds_set_driver_state(CDS_DRIVER_STATE_RECOVERING);
+	else
+		cds_clear_driver_state(CDS_DRIVER_STATE_RECOVERING);
+}
+
+/**
+ * cds_set_load_in_progress() - Set load in progress
+ * @value: value to set
+ *
+ * Return: none
+ */
+static inline void cds_set_load_in_progress(uint8_t value)
+{
+	if (value)
+		cds_set_driver_state(CDS_DRIVER_STATE_LOADING);
+	else
+		cds_clear_driver_state(CDS_DRIVER_STATE_LOADING);
+}
+
+/**
+ * cds_set_driver_loaded() - Set load completed
+ * @value: value to set
+ *
+ * Return: none
+ */
+static inline void cds_set_driver_loaded(uint8_t value)
+{
+	if (value)
+		cds_set_driver_state(CDS_DRIVER_STATE_LOADED);
+	else
+		cds_clear_driver_state(CDS_DRIVER_STATE_LOADED);
+}
+
+/**
+ * cds_set_unload_in_progress() - Set unload in progress
+ * @value: value to set
+ *
+ * Return: none
+ */
+static inline void cds_set_unload_in_progress(uint8_t value)
+{
+	if (value)
+		cds_set_driver_state(CDS_DRIVER_STATE_UNLOADING);
+	else
+		cds_clear_driver_state(CDS_DRIVER_STATE_UNLOADING);
+}
+
+v_CONTEXT_t cds_init(void);
+void cds_deinit(void);
 
 CDF_STATUS cds_pre_enable(v_CONTEXT_t cds_context);
 
-CDF_STATUS cds_open(v_CONTEXT_t *p_cds_context, uint32_t hddContextSize);
+CDF_STATUS cds_open(void);
 
 CDF_STATUS cds_enable(v_CONTEXT_t cds_context);
 
@@ -77,21 +203,13 @@ void *cds_get_context(CDF_MODULE_ID moduleId);
 
 v_CONTEXT_t cds_get_global_context(void);
 
-uint8_t cds_is_logp_in_progress(void);
-void cds_set_logp_in_progress(uint8_t value);
-
-uint8_t cds_is_load_unload_in_progress(void);
-uint8_t cds_is_unload_in_progress(void);
-
-void cds_set_load_unload_in_progress(uint8_t value);
-
 CDF_STATUS cds_alloc_context(void *p_cds_context, CDF_MODULE_ID moduleID,
 			     void **ppModuleContext, uint32_t size);
 
 CDF_STATUS cds_free_context(void *p_cds_context, CDF_MODULE_ID moduleID,
 			    void *pModuleContext);
 
-CDF_STATUS cds_get_vdev_types(tCDF_CON_MODE mode, uint32_t *type,
+CDF_STATUS cds_get_vdev_types(enum tCDF_ADAPTER_MODE mode, uint32_t *type,
 			      uint32_t *subType);
 
 void cds_flush_work(void *work);

+ 53 - 191
core/cds/inc/cds_concurrency.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -463,138 +463,30 @@ struct cds_conc_connection_info {
 	bool          in_use;
 };
 
-bool cds_is_connection_in_progress(hdd_context_t *hdd_ctx);
-void cds_dump_concurrency_info(hdd_context_t *pHddCtx);
-void cds_set_concurrency_mode(hdd_context_t *pHddCtx, tCDF_CON_MODE mode);
-void cds_clear_concurrency_mode(hdd_context_t *pHddCtx,
-				     tCDF_CON_MODE mode);
-uint32_t cds_get_connection_count(hdd_context_t *hdd_ctx);
-/**
- * cds_is_sta_connection_pending() - This function will check if sta connection
- *                                   is pending or not.
- * @hdd_ctx: pointer to hdd context
- *
- * This function will return the status of flag is_sta_connection_pending
- *
- * Return: true or false
- */
-static inline bool
-cds_is_sta_connection_pending(hdd_context_t *hdd_ctx)
-{
-	bool status;
-	spin_lock(&hdd_ctx->sta_update_info_lock);
-	status = hdd_ctx->is_sta_connection_pending;
-	spin_unlock(&hdd_ctx->sta_update_info_lock);
-	return status;
-}
-
-/**
- * cds_change_sta_conn_pending_status() - This function will change the value
- *                                        of is_sta_connection_pending
- * @hdd_ctx: pointer to hdd context
- * @value: value to set
- *
- * This function will change the value of is_sta_connection_pending
- *
- * Return: none
- */
-static inline void
-cds_change_sta_conn_pending_status(hdd_context_t *hdd_ctx,
-		bool value)
-{
-	spin_lock(&hdd_ctx->sta_update_info_lock);
-	hdd_ctx->is_sta_connection_pending = value;
-	spin_unlock(&hdd_ctx->sta_update_info_lock);
-}
-
-/**
- * cds_is_sap_restart_required() - This function will check if sap restart
- *                                 is pending or not.
- * @hdd_ctx: pointer to hdd context.
- *
- * This function will return the status of flag is_sap_restart_required.
- *
- * Return: true or false
- */
-static inline bool
-cds_is_sap_restart_required(hdd_context_t *hdd_ctx)
-{
-	bool status;
-	spin_lock(&hdd_ctx->sap_update_info_lock);
-	status = hdd_ctx->is_sap_restart_required;
-	spin_unlock(&hdd_ctx->sap_update_info_lock);
-	return status;
-}
-
-/**
- * cds_change_sap_restart_required_status() - This function will change the
- *                                            value of is_sap_restart_required
- * @hdd_ctx: pointer to hdd context
- * @value: value to set
- *
- * This function will change the value of is_sap_restart_required
- *
- * Return: none
- */
-static inline void
-cds_change_sap_restart_required_status(hdd_context_t *hdd_ctx,
-		bool value)
-{
-	spin_lock(&hdd_ctx->sap_update_info_lock);
-	hdd_ctx->is_sap_restart_required = value;
-	spin_unlock(&hdd_ctx->sap_update_info_lock);
-}
-
-/**
- * cds_set_connection_in_progress() - to set the connection in progress flag
- * @hdd_ctx: pointer to hdd context
- * @value: value to set
- *
- * This function will set the passed value to connection in progress flag.
- * If value is previously being set to true then no need to set it again.
- *
- * Return: true if value is being set correctly and false otherwise.
- */
-static inline bool
-cds_set_connection_in_progress(hdd_context_t *hdd_ctx,
-		bool value)
-{
-	bool status = true;
-	spin_lock(&hdd_ctx->connection_status_lock);
-	/*
-	 * if the value is set to true previously and if someone is
-	 * trying to make it true again then it could be some race
-	 * condition being triggered. Avoid this situation by returning
-	 * false
-	 */
-	if (hdd_ctx->connection_in_progress && value)
-		status = false;
-	else
-		hdd_ctx->connection_in_progress = value;
-	spin_unlock(&hdd_ctx->connection_status_lock);
-	return status;
-}
-
-
+bool cds_is_connection_in_progress(void);
+void cds_dump_concurrency_info(void);
+void cds_set_concurrency_mode(enum tCDF_ADAPTER_MODE mode);
+void cds_clear_concurrency_mode(enum tCDF_ADAPTER_MODE mode);
+uint32_t cds_get_connection_count(void);
+bool cds_is_sta_connection_pending(void);
+void cds_change_sta_conn_pending_status(bool value);
+void cds_change_sap_restart_required_status(bool value);
+bool cds_set_connection_in_progress(bool value);
 int cds_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
 			struct wireless_dev *wdev,
 			const void *data,
 			int data_len);
 uint32_t cds_get_concurrency_mode(void);
-CDF_STATUS cds_check_and_restart_sap(hdd_context_t *hdd_ctx,
-		eCsrRoamResult roam_result,
+CDF_STATUS cds_check_and_restart_sap(eCsrRoamResult roam_result,
 		hdd_station_ctx_t *hdd_sta_ctx);
-void cds_handle_conc_rule1(hdd_context_t *hdd_ctx,
-		hdd_adapter_t *adapter,
+void cds_handle_conc_rule1(hdd_adapter_t *adapter,
 		tCsrRoamProfile *roam_profile);
 #ifdef FEATURE_WLAN_CH_AVOID
-bool cds_handle_conc_rule2(hdd_context_t *hdd_ctx,
-		hdd_adapter_t *adapter,
+bool cds_handle_conc_rule2(hdd_adapter_t *adapter,
 		tCsrRoamProfile *roam_profile,
 		uint32_t *roam_id);
 #else
-static inline bool cds_handle_conc_rule2(hdd_context_t *hdd_ctx,
-		hdd_adapter_t *adapter,
+static inline bool cds_handle_conc_rule2(hdd_adapter_t *adapter,
 		tCsrRoamProfile *roam_profile,
 		uint32_t *roam_id)
 {
@@ -607,10 +499,11 @@ bool cds_check_for_session_conc(uint8_t session_id, uint8_t channel);
 CDF_STATUS cds_handle_conc_multiport(uint8_t session_id, uint8_t channel);
 
 #ifdef FEATURE_WLAN_FORCE_SAP_SCC
-void cds_force_sap_on_scc(hdd_context_t *hdd_ctx, eCsrRoamResult roam_result);
+void cds_force_sap_on_scc(eCsrRoamResult roam_result,
+		uint8_t channel_id);
 #else
-static inline void cds_force_sap_on_scc(hdd_context_t *hdd_ctx,
-		eCsrRoamResult roam_result)
+static inline void cds_force_sap_on_scc(eCsrRoamResult roam_result,
+				uint8_t channel_id)
 {
 
 }
@@ -618,19 +511,17 @@ static inline void cds_force_sap_on_scc(hdd_context_t *hdd_ctx,
 
 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
 void cds_check_concurrent_intf_and_restart_sap(
-		hdd_context_t *hdd_ctx,
 		hdd_station_ctx_t *hdd_sta_ctx,
 		hdd_adapter_t *adapter);
 #else
 static inline void cds_check_concurrent_intf_and_restart_sap(
-		hdd_context_t *hdd_ctx,
 		hdd_station_ctx_t *hdd_sta_ctx,
 		hdd_adapter_t *adapter)
 {
 
 }
 #endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
-uint8_t cds_is_mcc_in_24G(hdd_context_t *hdd_ctx);
+uint8_t cds_is_mcc_in_24G(void);
 int32_t cds_set_mas(hdd_adapter_t *adapter, uint8_t mas_value);
 int cds_set_mcc_p2p_quota(hdd_adapter_t *hostapd_adapter,
 		uint32_t set_value);
@@ -651,58 +542,48 @@ static inline void cds_restart_sap(hdd_adapter_t *ap_adapter)
 	*/
 
 #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE
-void cds_check_and_restart_sap_with_non_dfs_acs(hdd_context_t *hdd_ctx);
+void cds_check_and_restart_sap_with_non_dfs_acs(void);
 #else
-static inline void cds_check_and_restart_sap_with_non_dfs_acs(
-							hdd_context_t *hdd_ctx)
+static inline void cds_check_and_restart_sap_with_non_dfs_acs(void)
 {
 
 }
 #endif /* FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE */
-void cds_incr_active_session(hdd_context_t *pHddCtx, tCDF_CON_MODE mode,
+void cds_incr_active_session(enum tCDF_ADAPTER_MODE mode,
 				uint8_t sessionId);
-void cds_decr_active_session(hdd_context_t *pHddCtx, tCDF_CON_MODE mode,
+void cds_decr_active_session(enum tCDF_ADAPTER_MODE mode,
 				uint8_t sessionId);
-void cds_decr_session_set_pcl(hdd_context_t *hdd_ctx,
-		tCDF_CON_MODE mode,
+void cds_decr_session_set_pcl(enum tCDF_ADAPTER_MODE mode,
 		uint8_t session_id);
-CDF_STATUS cds_init_policy_mgr(hdd_context_t *hdd_ctx);
-CDF_STATUS cds_get_pcl(hdd_context_t *hdd_ctx, enum cds_con_mode mode,
+CDF_STATUS cds_init_policy_mgr(void);
+CDF_STATUS cds_deinit_policy_mgr(void);
+CDF_STATUS cds_get_pcl(enum cds_con_mode mode,
 				uint8_t *pcl_Channels, uint32_t *len);
-bool cds_allow_concurrency(hdd_context_t *hdd_ctx, enum cds_con_mode mode,
+bool cds_allow_concurrency(enum cds_con_mode mode,
 				uint8_t channel, enum hw_mode_bandwidth bw);
-enum cds_conc_priority_mode cds_get_first_connection_pcl_table_index(
-				hdd_context_t *hdd_ctx);
-enum cds_one_connection_mode cds_get_second_connection_pcl_table_index(
-				hdd_context_t *hdd_ctx);
-enum cds_two_connection_mode cds_get_third_connection_pcl_table_index(
-				hdd_context_t *hdd_ctx);
-CDF_STATUS cds_mode_switch_dbs_to_mcc(hdd_context_t *hdd_ctx);
-CDF_STATUS cds_mode_switch_mcc_to_dbs(hdd_context_t *hdd_ctx);
-CDF_STATUS cds_incr_connection_count(hdd_context_t *hdd_ctx,
-					  uint32_t vdev_id);
-CDF_STATUS cds_update_connection_info(hdd_context_t *hdd_ctx,
-					   uint32_t vdev_id);
-CDF_STATUS cds_decr_connection_count(hdd_context_t *hdd_ctx,
-					  uint32_t vdev_id);
+enum cds_conc_priority_mode cds_get_first_connection_pcl_table_index(void);
+enum cds_one_connection_mode cds_get_second_connection_pcl_table_index(void);
+enum cds_two_connection_mode cds_get_third_connection_pcl_table_index(void);
+CDF_STATUS cds_incr_connection_count(uint32_t vdev_id);
+CDF_STATUS cds_update_connection_info(uint32_t vdev_id);
+CDF_STATUS cds_decr_connection_count(uint32_t vdev_id);
 CDF_STATUS cds_current_connections_update(uint32_t session_id,
 				uint8_t channel,
 				enum cds_conn_update_reason);
+bool cds_is_ibss_conn_exist(uint8_t *ibss_channel);
 #ifdef MPC_UT_FRAMEWORK
-CDF_STATUS cds_incr_connection_count_utfw(hdd_context_t *hdd_ctx,
+CDF_STATUS cds_incr_connection_count_utfw(
 		uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
 		uint32_t chain_mask, uint32_t type, uint32_t sub_type,
 		uint32_t channelid, uint32_t mac_id);
-CDF_STATUS cds_update_connection_info_utfw(hdd_context_t *hdd_ctx,
+CDF_STATUS cds_update_connection_info_utfw(
 		uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
 		uint32_t chain_mask, uint32_t type, uint32_t sub_type,
 		uint32_t channelid, uint32_t mac_id);
-CDF_STATUS cds_decr_connection_count_utfw(hdd_context_t *hdd_ctx,
+CDF_STATUS cds_decr_connection_count_utfw(
 		uint32_t del_all, uint32_t vdev_id);
-struct cds_conc_connection_info *cds_get_conn_info(hdd_context_t *hdd_ctx,
-	uint32_t *len);
-enum cds_pcl_type get_pcl_from_first_conn_table(
-		enum cds_con_mode type,
+struct cds_conc_connection_info *cds_get_conn_info(uint32_t *len);
+enum cds_pcl_type get_pcl_from_first_conn_table(enum cds_con_mode type,
 		enum cds_conc_priority_mode sys_pref);
 enum cds_pcl_type get_pcl_from_second_conn_table(
 	enum cds_one_connection_mode idx, enum cds_con_mode type,
@@ -711,39 +592,33 @@ enum cds_pcl_type get_pcl_from_third_conn_table(
 	enum cds_two_connection_mode idx, enum cds_con_mode type,
 	enum cds_conc_priority_mode sys_pref, uint8_t dbs_capable);
 #else
-static inline CDF_STATUS cds_incr_connection_count_utfw(
-		hdd_context_t *hdd_ctx, uint32_t vdev_id,
+static inline CDF_STATUS cds_incr_connection_count_utfw(uint32_t vdev_id,
 		uint32_t tx_streams, uint32_t rx_streams,
 		uint32_t chain_mask, uint32_t type, uint32_t sub_type,
 		uint32_t channelid, uint32_t mac_id)
 {
 	return CDF_STATUS_SUCCESS;
 }
-static inline CDF_STATUS cds_update_connection_info_utfw(
-		hdd_context_t *hdd_ctx, uint32_t vdev_id,
+static inline CDF_STATUS cds_update_connection_info_utfw(uint32_t vdev_id,
 		uint32_t tx_streams, uint32_t rx_streams,
 		uint32_t chain_mask, uint32_t type, uint32_t sub_type,
 		uint32_t channelid, uint32_t mac_id)
 {
 	return CDF_STATUS_SUCCESS;
 }
-static inline CDF_STATUS cds_decr_connection_count_utfw(
-		hdd_context_t *hdd_ctx,
-		uint32_t del_all, uint32_t vdev_id)
+static inline CDF_STATUS cds_decr_connection_count_utfw(uint32_t del_all,
+		uint32_t vdev_id)
 {
 	return CDF_STATUS_SUCCESS;
 }
-static inline struct cds_conc_connection_info *cds_get_conn_info(
-		hdd_context_t *hdd_ctx, uint32_t *len)
+static inline struct cds_conc_connection_info *cds_get_conn_info(uint32_t *len)
 {
 	return NULL;
 }
 #endif
 enum cds_con_mode cds_convert_device_mode_to_hdd_type(
 				device_mode_t device_mode);
-uint32_t cds_get_connection_count(hdd_context_t *hdd_ctx);
-CDF_STATUS cds_soc_set_hw_mode(hdd_context_t *hdd_ctx,
-		uint32_t session_id,
+CDF_STATUS cds_soc_set_hw_mode(uint32_t session_id,
 		enum hw_mode_ss_config mac0_ss,
 		enum hw_mode_bandwidth mac0_bw,
 		enum hw_mode_ss_config mac1_ss,
@@ -751,43 +626,30 @@ CDF_STATUS cds_soc_set_hw_mode(hdd_context_t *hdd_ctx,
 		enum hw_mode_dbs_capab dbs,
 		enum hw_mode_agile_dfs_capab dfs,
 		enum cds_conn_update_reason reason);
-enum cds_conc_next_action cds_need_opportunistic_upgrade(
-		hdd_context_t *hdd_ctx);
-CDF_STATUS cds_next_actions(
-		hdd_context_t *hdd_ctx, uint32_t session_id,
+enum cds_conc_next_action cds_need_opportunistic_upgrade(void);
+CDF_STATUS cds_next_actions(uint32_t session_id,
 		enum cds_conc_next_action action,
 		enum cds_conn_update_reason reason);
-void cds_set_dual_mac_scan_config(hdd_context_t *hdd_ctx,
-		uint8_t dbs_val,
+void cds_set_dual_mac_scan_config(uint8_t dbs_val,
 		uint8_t dbs_plus_agile_scan_val,
 		uint8_t single_mac_scan_with_dbs_val);
-void cds_set_dual_mac_fw_mode_config(hdd_context_t *hdd_ctx,
-		uint8_t dbs,
+void cds_set_dual_mac_fw_mode_config(uint8_t dbs,
 		uint8_t dfs);
 void cds_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status,
 		uint32_t scan_config,
 		uint32_t fw_mode_config);
-bool cds_map_concurrency_mode(hdd_context_t *hdd_ctx,
-		tCDF_CON_MODE *old_mode, enum cds_con_mode *new_mode);
+bool cds_map_concurrency_mode(enum tCDF_ADAPTER_MODE *old_mode,
+		enum cds_con_mode *new_mode);
 CDF_STATUS cds_get_channel_from_scan_result(hdd_adapter_t *adapter,
 		tCsrRoamProfile *roam_profile, uint8_t *channel);
 
-tCDF_CON_MODE cds_get_conparam(void);
+enum tCDF_GLOBAL_CON_MODE cds_get_conparam(void);
 bool cds_concurrent_open_sessions_running(void);
 bool cds_max_concurrent_connections_reached(void);
 void cds_clear_concurrent_session_count(void);
 bool cds_is_multiple_active_sta_sessions(void);
 bool cds_is_sta_active_connection_exists(void);
-
-#ifdef WLAN_FEATURE_MBSSID
 bool cds_concurrent_beaconing_sessions_running(void);
-#else
-static inline bool cds_concurrent_beaconing_sessions_running(void)
-{
-	return true;
-}
-#endif
-
 CDF_STATUS cdf_wait_for_connection_update(void);
 CDF_STATUS cdf_reset_connection_update(void);
 CDF_STATUS cdf_set_connection_update(void);

+ 4 - 1
core/cds/inc/cds_packet.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -109,6 +109,9 @@ void cds_pkt_proto_trace_init(void);
 
    ---------------------------------------------------------------------------*/
 void cds_pkt_proto_trace_close(void);
+#else
+static inline void cds_pkt_proto_trace_init(void) { }
+static inline void cds_pkt_proto_trace_close(void) {}
 #endif /* QCA_PKT_PROTO_TRACE */
 
 /**

+ 141 - 105
core/cds/inc/cds_reg_service.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -39,7 +39,35 @@
 #include "cdf_status.h"
 
 #define CDS_COUNTRY_CODE_LEN  2
-#define CDS_MAC_ADDRESS_LEN   6
+#define CDS_MAC_ADDRESS_LEN 6
+
+#define CDS_CHANNEL_STATE(chan_enum) reg_channels[chan_enum].state
+#define CDS_CHANNEL_NUM(chan_enum) chan_mapping[chan_enum].chan_num
+#define CDS_CHANNEL_FREQ(chan_enum) chan_mapping[chan_enum].center_freq
+#define CDS_IS_DFS_CH(chan_num) (cds_get_channel_state((chan_num)) == \
+				CHANNEL_STATE_DFS)
+
+#define CDS_IS_PASSIVE_OR_DISABLE_CH(chan_num) \
+	(cds_get_channel_state(chan_num) != CHANNEL_STATE_ENABLE)
+
+#define CDS_MIN_24GHZ_CHANNEL_NUMBER chan_mapping[MIN_24GHZ_CHANNEL].chan_num
+#define CDS_MAX_24GHZ_CHANNEL_NUMBER chan_mapping[MAX_24GHZ_CHANNEL].chan_num
+#define CDS_MIN_5GHZ_CHANNEL_NUMBER chan_mapping[MIN_5GHZ_CHANNEL].chan_num
+#define CDS_MAX_5GHZ_CHANNEL_NUMBER chan_mapping[MAX_5GHZ_CHANNEL].chan_num
+
+#define CDS_IS_CHANNEL_5GHZ(chan_num) \
+	((chan_num >= CDS_MIN_5GHZ_CHANNEL_NUMBER) && \
+	 (chan_num <= CDS_MAX_5GHZ_CHANNEL_NUMBER))
+
+#define CDS_IS_CHANNEL_24GHZ(chan_num) \
+	((chan_num >= CDS_MIN_24GHZ_CHANNEL_NUMBER) && \
+	 (chan_num <= CDS_MAX_24GHZ_CHANNEL_NUMBER))
+
+#define CDS_IS_SAME_BAND_CHANNELS(chan_num1, chan_num2) \
+	(chan_num1 && chan_num2 && \
+	(CDS_IS_CHANNEL_5GHZ(chan_num1) == CDS_IS_CHANNEL_5GHZ(chan_num2)))
+
+#define CDS_MIN_11P_CHANNEL chan_mapping[MIN_59GHZ_CHANNEL].chan_num
 
 typedef enum {
 	REGDOMAIN_FCC,
@@ -49,8 +77,7 @@ typedef enum {
 	REGDOMAIN_COUNT
 } v_REGDOMAIN_t;
 
-typedef enum {
-	/* 2.4GHz Band */
+enum channel_enum {
 	RF_CHAN_1 = 0,
 	RF_CHAN_2,
 	RF_CHAN_3,
@@ -66,16 +93,6 @@ typedef enum {
 	RF_CHAN_13,
 	RF_CHAN_14,
 
-	/* 4.9GHz Band */
-	RF_CHAN_240,
-	RF_CHAN_244,
-	RF_CHAN_248,
-	RF_CHAN_252,
-	RF_CHAN_208,
-	RF_CHAN_212,
-	RF_CHAN_216,
-
-	/* 5GHz Low & Mid U-NII Band */
 	RF_CHAN_36,
 	RF_CHAN_40,
 	RF_CHAN_44,
@@ -85,7 +102,6 @@ typedef enum {
 	RF_CHAN_60,
 	RF_CHAN_64,
 
-	/* 5GHz Mid Band - ETSI & FCC */
 	RF_CHAN_100,
 	RF_CHAN_104,
 	RF_CHAN_108,
@@ -97,17 +113,14 @@ typedef enum {
 	RF_CHAN_132,
 	RF_CHAN_136,
 	RF_CHAN_140,
-
 	RF_CHAN_144,
 
-	/* 5GHz High U-NII Band */
 	RF_CHAN_149,
 	RF_CHAN_153,
 	RF_CHAN_157,
 	RF_CHAN_161,
 	RF_CHAN_165,
 
-	/* 802.11p */
 	RF_CHAN_170,
 	RF_CHAN_171,
 	RF_CHAN_172,
@@ -134,19 +147,14 @@ typedef enum {
 	RF_CHAN_BOND_9,
 	RF_CHAN_BOND_10,
 	RF_CHAN_BOND_11,
-	RF_CHAN_BOND_242,       /* 4.9GHz Band */
-	RF_CHAN_BOND_246,
-	RF_CHAN_BOND_250,
-	RF_CHAN_BOND_210,
-	RF_CHAN_BOND_214,
-	RF_CHAN_BOND_38,        /* 5GHz Low & Mid U-NII Band */
+	RF_CHAN_BOND_38,
 	RF_CHAN_BOND_42,
 	RF_CHAN_BOND_46,
 	RF_CHAN_BOND_50,
 	RF_CHAN_BOND_54,
 	RF_CHAN_BOND_58,
 	RF_CHAN_BOND_62,
-	RF_CHAN_BOND_102,       /* 5GHz Mid Band - ETSI & FCC */
+	RF_CHAN_BOND_102,
 	RF_CHAN_BOND_106,
 	RF_CHAN_BOND_110,
 	RF_CHAN_BOND_114,
@@ -156,21 +164,19 @@ typedef enum {
 	RF_CHAN_BOND_130,
 	RF_CHAN_BOND_134,
 	RF_CHAN_BOND_138,
-
 	RF_CHAN_BOND_142,
-
-	RF_CHAN_BOND_151,       /* 5GHz High U-NII Band */
+	RF_CHAN_BOND_151,
 	RF_CHAN_BOND_155,
 	RF_CHAN_BOND_159,
 	RF_CHAN_BOND_163,
 
 	NUM_RF_CHANNELS,
 
-	MIN_2_4GHZ_CHANNEL = RF_CHAN_1,
-	MAX_2_4GHZ_CHANNEL = RF_CHAN_14,
-	NUM_24GHZ_CHANNELS = (MAX_2_4GHZ_CHANNEL - MIN_2_4GHZ_CHANNEL + 1),
+	MIN_24GHZ_CHANNEL = RF_CHAN_1,
+	MAX_24GHZ_CHANNEL = RF_CHAN_14,
+	NUM_24GHZ_CHANNELS = (MAX_24GHZ_CHANNEL - MIN_24GHZ_CHANNEL + 1),
 
-	MIN_5GHZ_CHANNEL = RF_CHAN_240,
+	MIN_5GHZ_CHANNEL = RF_CHAN_36,
 	MAX_5GHZ_CHANNEL = RF_CHAN_184,
 	NUM_5GHZ_CHANNELS = (MAX_5GHZ_CHANNEL - MIN_5GHZ_CHANNEL + 1),
 
@@ -184,49 +190,108 @@ typedef enum {
 	NUM_40MHZ_RF_CHANNELS =
 		(MAX_40MHZ_RF_CHANNEL - MIN_40MHZ_RF_CHANNEL + 1),
 
-	MIN_5_9GHZ_CHANNEL = RF_CHAN_170,
-	MAX_5_9GHZ_CHANNEL = RF_CHAN_184,
+	MIN_59GHZ_CHANNEL = RF_CHAN_170,
+	MAX_59GHZ_CHANNEL = RF_CHAN_184,
 
 	INVALID_RF_CHANNEL = 0xBAD,
 	RF_CHANNEL_INVALID_MAX_FIELD = 0x7FFFFFFF
-} eRfChannels;
+};
 
-typedef enum {
+/**
+ * enum channel_state: channel state
+ *
+ * @CHANNEL_STATE_DISABLE: channel disabled
+ * @CHANNEL_STATE_ENABLE: tx/rx enabled
+ * @CHANNEL_STATE_DFS: rx enabled, tx DFS
+ * @CHANNEL_STATE_INVALID: not a valid channel
+ */
+enum channel_state {
 	CHANNEL_STATE_DISABLE,
 	CHANNEL_STATE_ENABLE,
 	CHANNEL_STATE_DFS,
 	CHANNEL_STATE_INVALID
-} CHANNEL_STATE;
-
-typedef int8_t tPowerdBm;
+};
 
-typedef struct {
-	uint32_t enabled:4;
+/**
+ * struct regulatory_channel: regulatory channel
+ *
+ * @state: channel state
+ * @flags: channel flags
+ * @pwr_limit: channel tx power limit
+ */
+struct regulatory_channel {
+	uint32_t state:4;
 	uint32_t flags:28;
-	tPowerdBm pwrLimit;
-} sRegulatoryChannel;
+	int8_t pwr_limit;
+};
 
-typedef struct {
-	sRegulatoryChannel channels[NUM_RF_CHANNELS];
-} sRegulatoryDomain;
+/**
+ * struct chan_map: channel mapping
+ *
+ * @center_freq: channel center freq
+ * @chan_num: channel number
+ */
+struct chan_map {
+	uint16_t center_freq;
+	uint16_t chan_num;
+};
 
-typedef struct {
-	uint16_t targetFreq;
-	uint16_t channelNum;
-} tRfChannelProps;
+/**
+ * struct channel_power: channel power
+ *
+ * @chan_num: channel number
+ * @power: tx power
+ */
+struct channel_power {
+	uint8_t chan_num;
+	int8_t power;
+};
 
-typedef struct {
-	uint8_t chanId;
-	tPowerdBm pwr;
-} tChannelListWithPower;
+/**
+ * enum country_src: country source
+ *
+ * @SOURCE_QUERY: source query
+ * @SOURCE_CORE: source regulatory core
+ * @SOURCE_DRIVER: source driver
+ * @SOURCE_USERSPACE: source userspace
+ * @SOURCE_11D: source 11D
+ */
+enum country_src {
+	SOURCE_QUERY,
+	SOURCE_CORE,
+	SOURCE_DRIVER,
+	SOURCE_USERSPACE,
+	SOURCE_11D
+};
 
-typedef enum {
-	COUNTRY_INIT,
-	COUNTRY_IE,
-	COUNTRY_USER,
-	COUNTRY_QUERY,
-	COUNTRY_MAX = COUNTRY_QUERY
-} v_CountryInfoSource_t;
+/**
+ * struct regulatory: regulatory information
+ *
+ * @reg_domain: regulatory domain pair
+ * @eeprom_rd_ext: eeprom value
+ * @country_code: current country in integer
+ * @alpha2: current alpha2
+ * @def_country: default country alpha2
+ * @def_region: DFS region
+ * @ctl_2g: 2G CTL value
+ * @ctl_5g: 5G CTL value
+ * @reg_pair: pointer to regulatory pair
+ * @cc_src: country code src
+ * @reg_flags: kernel regulatory flags
+ */
+struct regulatory {
+	uint32_t reg_domain;
+	uint32_t eeprom_rd_ext;
+	uint16_t country_code;
+	uint8_t alpha2[CDS_COUNTRY_CODE_LEN + 1];
+	uint8_t def_country[CDS_COUNTRY_CODE_LEN + 1];
+	uint8_t dfs_region;
+	uint8_t ctl_2g;
+	uint8_t ctl_5g;
+	const void *regpair;
+	enum country_src cc_src;
+	uint32_t reg_flags;
+};
 
 /**
  * enum chan_width: channel width
@@ -249,62 +314,33 @@ enum channel_width {
 	CHAN_WIDTH_160MHZ
 };
 
-/**
- * @country_code_t : typedef for country code. One extra
- * char for holding null character
- */
-typedef uint8_t country_code_t[CDS_COUNTRY_CODE_LEN + 1];
-
-typedef struct {
-	sRegulatoryDomain regDomains[REGDOMAIN_COUNT];
-	country_code_t default_country;
-} t_reg_table;
 
+extern struct regulatory_channel reg_channels[NUM_RF_CHANNELS];
+extern const struct chan_map chan_mapping[NUM_RF_CHANNELS];
 
 CDF_STATUS cds_get_reg_domain_from_country_code(v_REGDOMAIN_t *pRegDomain,
-						const country_code_t countryCode,
-						v_CountryInfoSource_t source);
-
-CDF_STATUS cds_read_default_country(country_code_t default_country);
-
-CDF_STATUS cds_get_channel_list_with_power(tChannelListWithPower
-					   *pChannels20MHz,
-					   uint8_t *pNum20MHzChannelsFound,
-					   tChannelListWithPower
-					   *pChannels40MHz,
-					   uint8_t *pNum40MHzChannelsFound);
-
-CDF_STATUS cds_set_reg_domain(void *clientCtxt, v_REGDOMAIN_t regId);
-
-CHANNEL_STATE cds_get_channel_state(uint32_t rfChannel);
-
-#define CDS_IS_DFS_CH(channel) (cds_get_channel_state((channel)) == \
-				CHANNEL_STATE_DFS)
-
-#define CDS_IS_PASSIVE_OR_DISABLE_CH(channel) \
-    (cds_get_channel_state((channel)) != CHANNEL_STATE_ENABLE)
+						const uint8_t *country_alpha2,
+						enum country_src source);
 
-#define CDS_MAX_24GHz_CHANNEL_NUMBER \
-    (rf_channels[MAX_2_4GHZ_CHANNEL].channelNum)
-#define CDS_MIN_5GHz_CHANNEL_NUMBER  (rf_channels[RF_CHAN_36].channelNum)
-#define CDS_MAX_5GHz_CHANNEL_NUMBER  (rf_channels[MAX_5GHZ_CHANNEL].channelNum)
+CDF_STATUS cds_read_default_country(uint8_t *default_country);
 
-#define CDS_IS_CHANNEL_5GHZ(chnNum) \
-	(((chnNum) >= CDS_MIN_5GHz_CHANNEL_NUMBER) && ((chnNum) <= CDS_MAX_5GHz_CHANNEL_NUMBER))
+CDF_STATUS cds_get_channel_list_with_power(struct channel_power
+					   *base_channels,
+					   uint8_t *num_base_channels,
+					   struct channel_power
+					   *channel_40mhz,
+					   uint8_t *num_channels_40mhz);
 
-#define CDS_IS_CHANNEL_24GHZ(chnNum) \
-	(((chnNum) > 0) && ((chnNum) <= CDS_MAX_24GHz_CHANNEL_NUMBER))
+CDF_STATUS cds_set_reg_domain(void *client_ctxt, v_REGDOMAIN_t reg_domain);
 
-#define CDS_IS_SAME_BAND_CHANNELS(ch1, ch2) \
-	(ch1 && ch2 && \
-	(CDS_IS_CHANNEL_5GHZ(ch1) == CDS_IS_CHANNEL_5GHZ(ch2)))
+enum channel_state cds_get_channel_state(uint32_t chan_num);
 
 CDF_STATUS cds_regulatory_init(void);
 CDF_STATUS cds_get_dfs_region(uint8_t *dfs_region);
 CDF_STATUS cds_set_dfs_region(uint8_t dfs_region);
 bool cds_is_dsrc_channel(uint16_t);
-CHANNEL_STATE cds_get_bonded_channel_state(uint32_t chan_num,
-					   enum channel_width ch_width);
+enum channel_state cds_get_bonded_channel_state(uint32_t chan_num,
+					   enum channel_width chan_width);
 enum channel_width cds_get_max_channel_bw(uint32_t chan_num);
 
 #endif /* __CDS_REG_SERVICE_H */

+ 3 - 19
core/cds/inc/cds_regdomain.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -301,24 +301,6 @@ typedef struct {
 	uint8_t pwrlvl;
 } COMMON_MODE_POWER;
 
-typedef enum {
-	COUNTRY_CODE_SET_BY_CORE,
-	COUNTRY_CODE_SET_BY_DRIVER,
-	COUNTRY_CODE_SET_BY_USER
-} COUNTRY_CODE_SOURCE;
-
-struct regulatory {
-	uint32_t reg_domain;
-	uint32_t eeprom_rd_ext;
-	uint16_t country_code;
-	uint8_t alpha2[3];
-	uint8_t dfs_region;
-	uint8_t ctl_2g;
-	uint8_t ctl_5g;
-	const void *regpair;
-	COUNTRY_CODE_SOURCE cc_src;
-	uint32_t reg_flags;
-};
 /* Multi-Device RegDomain Support */
 typedef struct ath_hal_reg_dmn_tables {
 	/* regDomainPairs: Map of 8-bit regdomain values to unitary reg domain */
@@ -1094,5 +1076,7 @@ int32_t cds_get_country_from_alpha2(uint8_t *alpha2);
 void cds_fill_send_ctl_info_to_fw(struct regulatory *reg, uint32_t modesAvail,
 				  uint32_t modeSelect);
 void cds_set_wma_dfs_region(struct regulatory *reg);
+void cds_set_ch_params(uint8_t ch, uint32_t phy_mode,
+		chan_params_t *ch_params);
 
 #endif /* REGULATORY_H */

+ 5 - 13
core/cds/inc/cds_sched.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -250,14 +250,9 @@ typedef struct _cds_context_type {
 	/* MAC Module Context  */
 	void *pMACContext;
 
-#ifndef WLAN_FEATURE_MBSSID
-	/* SAP Context */
-	void *pSAPContext;
-#endif
-
 	cdf_event_t ProbeEvent;
 
-	volatile uint8_t isLogpInProgress;
+	uint32_t driver_state;
 
 	cdf_event_t wmaCompleteEvent;
 
@@ -268,7 +263,6 @@ typedef struct _cds_context_type {
 
 	void *htc_ctx;
 
-	void *epping_ctx;
 	/*
 	 * cdf_ctx will be used by cdf
 	 * while allocating dma memory
@@ -281,8 +275,6 @@ typedef struct _cds_context_type {
 	/* Configuration handle used to get system configuration */
 	void *cfg_ctx;
 
-	volatile uint8_t isLoadUnloadInProgress;
-
 	bool is_wakelock_log_enabled;
 	uint32_t wakelock_log_level;
 	uint32_t connectivity_log_level;
@@ -292,6 +284,7 @@ typedef struct _cds_context_type {
 	struct cds_log_complete log_complete;
 	cdf_spinlock_t bug_report_lock;
 	cdf_event_t connection_update_done_evt;
+	cdf_mutex_t cdf_conc_list_lock;
 
 } cds_context_type, *p_cds_contextType;
 
@@ -444,8 +437,7 @@ void cdf_timer_module_init(void);
 void cds_ssr_protect_init(void);
 void cds_ssr_protect(const char *caller_func);
 void cds_ssr_unprotect(const char *caller_func);
-bool cds_is_ssr_ready(const char *caller_func);
-
-#define cds_wait_for_work_thread_completion(func) cds_is_ssr_ready(func)
+bool cds_wait_for_external_threads_completion(const char *caller_func);
+int cds_get_gfp_flags(void);
 
 #endif /* #if !defined __CDS_SCHED_H */

+ 82 - 177
core/cds/src/cds_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -40,7 +40,6 @@
 #include "sme_api.h"
 #include "mac_init_api.h"
 #include "wlan_qct_sys.h"
-#include "wlan_hdd_misc.h"
 #include "i_cds_packet.h"
 #include "cds_reg_service.h"
 #include "wma_types.h"
@@ -80,70 +79,56 @@ static uint8_t cds_multicast_logging;
 void cds_sys_probe_thread_cback(void *pUserData);
 
 /**
- * cds_alloc_global_context() - allocate CDS global context
- * @p_cds_context: A pointer to where to store the CDS Context
+ * cds_init() - Initialize CDS
  *
- * cds_alloc_global_context() function allocates the CDS global Context,
- * but does not initialize all the members. This overal initialization will
- * happen at cds_open().
+ * This function allocates the resource required for CDS, but does not
+ * initialize all the members. This overall initialization will happen at
+ * cds_open().
  *
- * Return: CDF status
+ * Return: Global context on success and NULL on failure.
  */
-CDF_STATUS cds_alloc_global_context(v_CONTEXT_t *p_cds_context)
+v_CONTEXT_t cds_init(void)
 {
-	if (p_cds_context == NULL)
-		return CDF_STATUS_E_FAILURE;
+	cdf_mc_timer_manager_init();
+	cdf_mem_init();
 
-	/* allocate the CDS Context */
-	*p_cds_context = NULL;
 	gp_cds_context = &g_cds_context;
 
-	cdf_mem_zero(gp_cds_context, sizeof(cds_context_type));
-	*p_cds_context = gp_cds_context;
-
 	gp_cds_context->cdf_ctx = &g_cdf_ctx;
 	cdf_mem_zero(&g_cdf_ctx, sizeof(g_cdf_ctx));
 
-	/* initialize the spinlock */
 	cdf_trace_spin_lock_init();
-	/* it is the right time to initialize MTRACE structures */
+
 #if defined(TRACE_RECORD)
 	cdf_trace_init();
 #endif
-
 	cdf_dp_trace_init();
-	return CDF_STATUS_SUCCESS;
-} /* cds_alloc_global_context() */
+
+	cds_ssr_protect_init();
+
+	return gp_cds_context;
+}
 
 /**
- * cds_free_global_context() - free CDS global context
- * @p_cds_context: A pointer to where the CDS Context was stored
- *
- * cds_free_global_context() function frees the CDS Context.
+ * cds_deinit() - Deinitialize CDS
  *
- * Return: CDF status
+ * This function frees the CDS resources
  */
-CDF_STATUS cds_free_global_context(v_CONTEXT_t *p_cds_context)
+void cds_deinit(void)
 {
-	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
-		  "%s: De-allocating the CDS Context", __func__);
-
-	if ((p_cds_context == NULL) || (*p_cds_context == NULL)) {
-		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-			  "%s: vOS Context is Null", __func__);
-		return CDF_STATUS_E_FAILURE;
-	}
+	if (gp_cds_context == NULL)
+		return;
 
-	if (gp_cds_context != *p_cds_context) {
-		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-			  "%s: Context mismatch", __func__);
-		return CDF_STATUS_E_FAILURE;
-	}
 	gp_cds_context->cdf_ctx = NULL;
-	*p_cds_context = gp_cds_context = NULL;
+	gp_cds_context = NULL;
 
-	return CDF_STATUS_SUCCESS;
-} /* cds_free_global_context() */
+	cdf_mem_zero(&g_cds_context, sizeof(g_cds_context));
+
+	cdf_mc_timer_exit();
+	cdf_mem_exit();
+
+	return;
+}
 
 #ifdef WLAN_FEATURE_NAN
 /**
@@ -167,8 +152,6 @@ static void cds_set_nan_enable(tMacOpenParameters *param,
 
 /**
  * cds_open() - open the CDS Module
- * @p_cds_context: A pointer to where the CDS Context was stored
- * @hddContextSize: Size of the HDD context to allocate.
  *
  * cds_open() function opens the CDS Scheduler
  * Upon successful initialization:
@@ -181,7 +164,7 @@ static void cds_set_nan_enable(tMacOpenParameters *param,
  *
  * Return: CDF status
  */
-CDF_STATUS cds_open(v_CONTEXT_t *p_cds_context, uint32_t hddContextSize)
+CDF_STATUS cds_open(void)
 {
 	CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
 	int iter = 0;
@@ -462,8 +445,6 @@ CDF_STATUS cds_open(v_CONTEXT_t *p_cds_context, uint32_t hddContextSize)
 	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO_HIGH,
 		  "%s: CDS successfully Opened", __func__);
 
-	*p_cds_context = gp_cds_context;
-
 	return CDF_STATUS_SUCCESS;
 
 err_sme_close:
@@ -851,6 +832,9 @@ CDF_STATUS cds_close(v_CONTEXT_t cds_context)
 	}
 
 	cds_deinit_log_completion();
+
+	gp_cds_context->pHDDContext = NULL;
+
 	return CDF_STATUS_SUCCESS;
 }
 
@@ -878,14 +862,6 @@ void *cds_get_context(CDF_MODULE_ID moduleId)
 	}
 
 	switch (moduleId) {
-#ifndef WLAN_FEATURE_MBSSID
-	case CDF_MODULE_ID_SAP:
-	{
-		pModContext = gp_cds_context->pSAPContext;
-		break;
-	}
-#endif
-
 	case CDF_MODULE_ID_HDD:
 	{
 		pModContext = gp_cds_context->pHDDContext;
@@ -983,113 +959,67 @@ v_CONTEXT_t cds_get_global_context(void)
 } /* cds_get_global_context() */
 
 /**
- * cds_is_logp_in_progress() - check if ssr/self recovery is going on
+ * cds_get_driver_state() - Get current driver state
  *
- * Return: true if ssr/self recvoery is going on else false
- */
-uint8_t cds_is_logp_in_progress(void)
-{
-	if (gp_cds_context == NULL) {
-		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-			  "%s: global cds context is NULL", __func__);
-		return 1;
-	}
-
-	return gp_cds_context->isLogpInProgress;
-}
-
-/**
- * cds_set_logp_in_progress() - set ssr/self recovery in progress
- * @value: value to set
+ * This API returns current driver state stored in global context.
  *
- * Return: none
+ * Return: Driver state enum
  */
-void cds_set_logp_in_progress(uint8_t value)
+enum cds_driver_state cds_get_driver_state(void)
 {
-	hdd_context_t *pHddCtx = NULL;
-
 	if (gp_cds_context == NULL) {
 		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 			  "%s: global cds context is NULL", __func__);
-		return;
-	}
-	gp_cds_context->isLogpInProgress = value;
 
-	/* HDD uses it's own context variable to check if SSR in progress,
-	 * instead of modifying all HDD APIs set the HDD context variable
-	 * here
-	 */
-	pHddCtx = cds_get_context(CDF_MODULE_ID_HDD);
-	if (!pHddCtx) {
-		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
-			  "%s: HDD context is Null", __func__);
-		return;
+		return CDS_DRIVER_STATE_UNINITIALIZED;
 	}
-	pHddCtx->isLogpInProgress = value;
-}
 
-/**
- * cds_is_load_unload_in_progress() - check if driver load/unload in progress
- *
- * Return: true if load/unload is going on else false
- */
-uint8_t cds_is_load_unload_in_progress(void)
-{
-	if (gp_cds_context == NULL) {
-		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-			  "%s: global cds context is NULL", __func__);
-		return 0;
-	}
-
-	return gp_cds_context->isLoadUnloadInProgress;
+	return gp_cds_context->driver_state;
 }
 
 /**
- * cds_is_unload_in_progress() - check if driver unload in
- * progress
+ * cds_set_driver_state() - Set current driver state
+ * @state:	Driver state to be set to.
+ *
+ * This API sets driver state to state. This API only sets the state and doesn't
+ * clear states, please make sure to use cds_clear_driver_state to clear any
+ * state if required.
  *
- * Return: true if unload is going on else false
+ * Return: None
  */
-uint8_t cds_is_unload_in_progress(void)
+void cds_set_driver_state(enum cds_driver_state state)
 {
-	hdd_context_t *hdd_ctx = NULL;
 	if (gp_cds_context == NULL) {
 		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-			  "%s: global cds context is NULL", __func__);
-		return 0;
-	}
-	hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
+			  "%s: global cds context is NULL: %x", __func__,
+			  state);
 
-	if (hdd_ctx == NULL) {
-		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-			  "%s: HDD context is NULL", __func__);
-		return 0;
+		return;
 	}
 
-	return hdd_ctx->isUnloadInProgress;
+	gp_cds_context->driver_state |= state;
 }
 
 /**
- * cds_set_load_unload_in_progress() - set load/unload in progress
- * @value: value to set
+ * cds_clear_driver_state() - Clear current driver state
+ * @state:	Driver state to be cleared.
  *
- * Return: none
+ * This API clears driver state. This API only clears the state, please make
+ * sure to use cds_set_driver_state to set any new states.
+ *
+ * Return: None
  */
-void cds_set_load_unload_in_progress(uint8_t value)
+void cds_clear_driver_state(enum cds_driver_state state)
 {
 	if (gp_cds_context == NULL) {
 		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-			  "%s: global cds context is NULL", __func__);
+			  "%s: global cds context is NULL: %x", __func__,
+			  state);
+
 		return;
 	}
-	gp_cds_context->isLoadUnloadInProgress = value;
 
-#ifdef CONFIG_CNSS
-	if (value)
-		cnss_set_driver_status(CNSS_LOAD_UNLOAD);
-	else
-		cnss_set_driver_status(CNSS_INITIALIZED);
-#endif
+	gp_cds_context->driver_state &= ~state;
 }
 
 /**
@@ -1125,15 +1055,6 @@ CDF_STATUS cds_alloc_context(void *p_cds_context, CDF_MODULE_ID moduleID,
 	}
 
 	switch (moduleID) {
-
-#ifndef WLAN_FEATURE_MBSSID
-	case CDF_MODULE_ID_SAP:
-	{
-		pGpModContext = &(gp_cds_context->pSAPContext);
-		break;
-	}
-#endif
-
 	case CDF_MODULE_ID_WMA:
 	{
 		pGpModContext = &(gp_cds_context->pWMAContext);
@@ -1147,10 +1068,6 @@ CDF_STATUS cds_alloc_context(void *p_cds_context, CDF_MODULE_ID moduleID,
 	}
 
 	case CDF_MODULE_ID_EPPING:
-	{
-		pGpModContext = &(gp_cds_context->epping_ctx);
-		break;
-	}
 	case CDF_MODULE_ID_SME:
 	case CDF_MODULE_ID_PE:
 	case CDF_MODULE_ID_HDD:
@@ -1221,14 +1138,6 @@ CDF_STATUS cds_free_context(void *p_cds_context, CDF_MODULE_ID moduleID,
 	}
 
 	switch (moduleID) {
-#ifndef WLAN_FEATURE_MBSSID
-	case CDF_MODULE_ID_SAP:
-	{
-		pGpModContext = &(gp_cds_context->pSAPContext);
-		break;
-	}
-#endif
-
 	case CDF_MODULE_ID_WMA:
 	{
 		pGpModContext = &(gp_cds_context->pWMAContext);
@@ -1241,18 +1150,13 @@ CDF_STATUS cds_free_context(void *p_cds_context, CDF_MODULE_ID moduleID,
 		break;
 	}
 
-	case CDF_MODULE_ID_EPPING:
-	{
-		pGpModContext = &(gp_cds_context->epping_ctx);
-		break;
-	}
-
 	case CDF_MODULE_ID_TXRX:
 	{
 		pGpModContext = &(gp_cds_context->pdev_txrx_ctx);
 		break;
 	}
 
+	case CDF_MODULE_ID_EPPING:
 	case CDF_MODULE_ID_HDD:
 	case CDF_MODULE_ID_SME:
 	case CDF_MODULE_ID_PE:
@@ -1568,7 +1472,7 @@ CDF_STATUS cds_shutdown(v_CONTEXT_t cds_context)
  *
  * Return: WMI vdev type
  */
-CDF_STATUS cds_get_vdev_types(tCDF_CON_MODE mode, uint32_t *type,
+CDF_STATUS cds_get_vdev_types(enum tCDF_ADAPTER_MODE mode, uint32_t *type,
 			      uint32_t *sub_type)
 {
 	CDF_STATUS status = CDF_STATUS_SUCCESS;
@@ -1598,7 +1502,8 @@ CDF_STATUS cds_get_vdev_types(tCDF_CON_MODE mode, uint32_t *type,
 		*type = WMI_VDEV_TYPE_OCB;
 		break;
 	default:
-		hddLog(CDF_TRACE_LEVEL_ERROR, "Invalid device mode %d", mode);
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
+			  "Invalid device mode %d", mode);
 		status = CDF_STATUS_E_INVAL;
 		break;
 	}
@@ -1679,12 +1584,12 @@ void cds_trigger_recovery(void)
 		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 			"CRASH_INJECT command is timed out!");
  #ifdef CONFIG_CNSS
-		if (cds_is_logp_in_progress()) {
+		if (cds_is_driver_recovering()) {
 			CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-				"LOGP is in progress, ignore!");
+				"Recovery is in progress, ignore!");
 			return;
 		}
-		cds_set_logp_in_progress(true);
+		cds_set_recovery_in_progress(true);
 		cnss_schedule_recovery_work();
  #endif
 
@@ -1726,7 +1631,7 @@ void cds_set_wakelock_logging(bool value)
 
 	p_cds_context = cds_get_global_context();
 	if (!p_cds_context) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 				"cds context is Invald");
 		return;
 	}
@@ -1747,7 +1652,7 @@ bool cds_is_wakelock_enabled(void)
 
 	p_cds_context = cds_get_global_context();
 	if (!p_cds_context) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 				"cds context is Invald");
 		return false;
 	}
@@ -1771,7 +1676,7 @@ void cds_set_ring_log_level(uint32_t ring_id, uint32_t log_level)
 
 	p_cds_context = cds_get_global_context();
 	if (!p_cds_context) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 				"%s: cds context is Invald", __func__);
 		return;
 	}
@@ -1824,7 +1729,7 @@ enum wifi_driver_log_level cds_get_ring_log_level(uint32_t ring_id)
 
 	p_cds_context = cds_get_global_context();
 	if (!p_cds_context) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 				"%s: cds context is Invald", __func__);
 		return WLAN_LOG_LEVEL_OFF;
 	}
@@ -1886,7 +1791,7 @@ void cds_init_log_completion(void)
 
 	p_cds_context = cds_get_global_context();
 	if (!p_cds_context) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 				"%s: cds context is Invalid", __func__);
 		return;
 	}
@@ -1915,7 +1820,7 @@ void cds_deinit_log_completion(void)
 
 	p_cds_context = cds_get_global_context();
 	if (!p_cds_context) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 				"%s: cds context is Invalid", __func__);
 		return;
 	}
@@ -1942,7 +1847,7 @@ CDF_STATUS cds_set_log_completion(uint32_t is_fatal,
 
 	p_cds_context = cds_get_global_context();
 	if (!p_cds_context) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 				"%s: cds context is Invalid", __func__);
 		return CDF_STATUS_E_FAILURE;
 	}
@@ -1974,7 +1879,7 @@ void cds_get_log_completion(uint32_t *is_fatal,
 
 	p_cds_context = cds_get_global_context();
 	if (!p_cds_context) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 				"%s: cds context is Invalid", __func__);
 		return;
 	}
@@ -2000,7 +1905,7 @@ bool cds_is_log_report_in_progress(void)
 
 	p_cds_context = cds_get_global_context();
 	if (!p_cds_context) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 				"%s: cds context is Invalid", __func__);
 		return true;
 	}
@@ -2030,13 +1935,13 @@ CDF_STATUS cds_flush_logs(uint32_t is_fatal,
 
 	p_cds_context = cds_get_global_context();
 	if (!p_cds_context) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 				"%s: cds context is Invalid", __func__);
 		return CDF_STATUS_E_FAILURE;
 	}
 
 	if (cds_is_log_report_in_progress() == true) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 				"%s: Bug report already in progress - dropping! type:%d, indicator=%d reason_code=%d",
 				__func__, is_fatal, indicator, reason_code);
 		return CDF_STATUS_E_FAILURE;
@@ -2044,18 +1949,18 @@ CDF_STATUS cds_flush_logs(uint32_t is_fatal,
 
 	status = cds_set_log_completion(is_fatal, indicator, reason_code);
 	if (CDF_STATUS_SUCCESS != status) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 			"%s: Failed to set log trigger params", __func__);
 		return CDF_STATUS_E_FAILURE;
 	}
 
-	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
+	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
 			"%s: Triggering bug report: type:%d, indicator=%d reason_code=%d",
 			__func__, is_fatal, indicator, reason_code);
 
 	ret = sme_send_flush_logs_cmd_to_fw(p_cds_context->pMACContext);
 	if (0 != ret) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 				"%s: Failed to send flush FW log", __func__);
 		cds_init_log_completion();
 		return CDF_STATUS_E_FAILURE;

File diff suppressed because it is too large
+ 334 - 116
core/cds/src/cds_concurrency.c


+ 3 - 6
core/cds/src/cds_packet.c

@@ -259,12 +259,9 @@ void cds_pkt_proto_trace_init(void)
 	/* Init spin lock to protect global memory */
 	cdf_spinlock_init(&trace_buffer_lock);
 	trace_buffer_order = 0;
-	trace_buffer =
-		cdf_mem_malloc(CDS_PKT_TRAC_MAX_TRACE_BUF *
-			       sizeof(cds_pkt_proto_trace_t));
-	cdf_mem_zero((void *)trace_buffer,
-		     CDS_PKT_TRAC_MAX_TRACE_BUF *
-		     sizeof(cds_pkt_proto_trace_t));
+
+	trace_buffer = cdf_mem_malloc(CDS_PKT_TRAC_MAX_TRACE_BUF *
+				      sizeof(cds_pkt_proto_trace_t));
 
 	/* Register callback function to NBUF
 	 * Lower layer event also will be reported to here */

+ 156 - 421
core/cds/src/cds_reg_service.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -42,30 +42,20 @@
 
 #define WORLD_SKU_MASK          0x00F0
 #define WORLD_SKU_PREFIX        0x0060
-#define MAX_COUNTRY_COUNT       300
+#define REG_WAIT_TIME           50
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(WITH_BACKPORTS)
 #define IEEE80211_CHAN_PASSIVE_SCAN IEEE80211_CHAN_NO_IR
 #define IEEE80211_CHAN_NO_IBSS IEEE80211_CHAN_NO_IR
 #endif
 
-static v_REGDOMAIN_t temp_reg_domain = REGDOMAIN_COUNT;
-
-/* true if init happens thru init time driver hint */
-static bool init_by_driver = false;
-/* true if init happens thru init time  callback from regulatory core.
-   this should be set to true during driver reload */
-static bool init_by_reg_core = false;
-
-#define REG_WAIT_TIME            50
-
 #define REG_RULE_2412_2462    REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
 
 #define REG_RULE_2467_2472    REG_RULE(2467-10, 2472+10, 40, 0, 20, \
 			      NL80211_RRF_PASSIVE_SCAN)
 
 #define REG_RULE_2484         REG_RULE(2484-10, 2484+10, 40, 0, 20, \
-		       NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
+		NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
 
 #define REG_RULE_5180_5320    REG_RULE(5180-10, 5320+10, 80, 0, 20, \
 		NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
@@ -133,162 +123,7 @@ static const struct ieee80211_regdomain cds_world_regdom_67_68_6A_6C = {
 	}
 };
 
-typedef struct {
-	uint8_t regDomain;
-	country_code_t countryCode;
-} CountryInfo_t;
-
-typedef struct {
-	uint16_t countryCount;
-	CountryInfo_t countryInfo[MAX_COUNTRY_COUNT];
-} CountryInfoTable_t;
-
-static CountryInfoTable_t country_info_table = {
-	/* the first entry in the table is always the world domain */
-	138,
-	{
-		{REGDOMAIN_WORLD, {'0', '0'}}, /* WORLD DOMAIN */
-		{REGDOMAIN_FCC, {'A', 'D'}}, /* ANDORRA */
-		{REGDOMAIN_ETSI, {'A', 'E'}}, /* UAE */
-		{REGDOMAIN_ETSI, {'A', 'L'}}, /* ALBANIA */
-		{REGDOMAIN_ETSI, {'A', 'M'}}, /* ARMENIA */
-		{REGDOMAIN_ETSI, {'A', 'N'}}, /* NETHERLANDS ANTILLES */
-		{REGDOMAIN_FCC, {'A', 'R'}}, /* ARGENTINA */
-		{REGDOMAIN_FCC, {'A', 'S'}}, /* AMERICAN SOMOA */
-		{REGDOMAIN_ETSI, {'A', 'T'}}, /* AUSTRIA */
-		{REGDOMAIN_FCC, {'A', 'U'}}, /* AUSTRALIA */
-		{REGDOMAIN_ETSI, {'A', 'W'}}, /* ARUBA */
-		{REGDOMAIN_ETSI, {'A', 'Z'}}, /* AZERBAIJAN */
-		{REGDOMAIN_ETSI, {'B', 'A'}}, /* BOSNIA AND HERZEGOVINA */
-		{REGDOMAIN_FCC, {'B', 'B'}}, /* BARBADOS */
-		{REGDOMAIN_ETSI, {'B', 'D'}}, /* BANGLADESH */
-		{REGDOMAIN_ETSI, {'B', 'E'}}, /* BELGIUM */
-		{REGDOMAIN_ETSI, {'B', 'G'}}, /* BULGARIA */
-		{REGDOMAIN_ETSI, {'B', 'H'}}, /* BAHRAIN */
-		{REGDOMAIN_ETSI, {'B', 'L'}}, /* */
-		{REGDOMAIN_FCC, {'B', 'M'}}, /* BERMUDA */
-		{REGDOMAIN_ETSI, {'B', 'N'}}, /* BRUNEI DARUSSALAM */
-		{REGDOMAIN_ETSI, {'B', 'O'}}, /* BOLIVIA */
-		{REGDOMAIN_ETSI, {'B', 'R'}}, /* BRAZIL */
-		{REGDOMAIN_FCC, {'B', 'S'}}, /* BAHAMAS */
-		{REGDOMAIN_ETSI, {'B', 'Y'}}, /* BELARUS */
-		{REGDOMAIN_ETSI, {'B', 'Z'}}, /* BELIZE */
-		{REGDOMAIN_FCC, {'C', 'A'}}, /* CANADA */
-		{REGDOMAIN_ETSI, {'C', 'H'}}, /* SWITZERLAND */
-		{REGDOMAIN_ETSI, {'C', 'L'}}, /* CHILE */
-		{REGDOMAIN_FCC, {'C', 'N'}}, /* CHINA */
-		{REGDOMAIN_FCC, {'C', 'O'}}, /* COLOMBIA */
-		{REGDOMAIN_ETSI, {'C', 'R'}}, /* COSTA RICA */
-		{REGDOMAIN_ETSI, {'C', 'S'}},
-		{REGDOMAIN_ETSI, {'C', 'Y'}}, /* CYPRUS */
-		{REGDOMAIN_ETSI, {'C', 'Z'}}, /* CZECH REPUBLIC */
-		{REGDOMAIN_ETSI, {'D', 'E'}}, /* GERMANY */
-		{REGDOMAIN_ETSI, {'D', 'K'}}, /* DENMARK */
-		{REGDOMAIN_FCC, {'D', 'O'}}, /* DOMINICAN REPUBLIC */
-		{REGDOMAIN_ETSI, {'D', 'Z'}}, /* ALGERIA */
-		{REGDOMAIN_ETSI, {'E', 'C'}}, /* ECUADOR */
-		{REGDOMAIN_ETSI, {'E', 'E'}}, /* ESTONIA */
-		{REGDOMAIN_ETSI, {'E', 'G'}}, /* EGYPT */
-		{REGDOMAIN_ETSI, {'E', 'S'}}, /* SPAIN */
-		{REGDOMAIN_ETSI, {'F', 'I'}}, /* FINLAND */
-		{REGDOMAIN_ETSI, {'F', 'R'}}, /* FRANCE */
-		{REGDOMAIN_ETSI, {'G', 'B'}}, /* UNITED KINGDOM */
-		{REGDOMAIN_FCC, {'G', 'D'}}, /* GRENADA */
-		{REGDOMAIN_ETSI, {'G', 'E'}}, /* GEORGIA */
-		{REGDOMAIN_ETSI, {'G', 'F'}}, /* FRENCH GUIANA */
-		{REGDOMAIN_ETSI, {'G', 'L'}}, /* GREENLAND */
-		{REGDOMAIN_ETSI, {'G', 'P'}}, /* GUADELOUPE */
-		{REGDOMAIN_ETSI, {'G', 'R'}}, /* GREECE */
-		{REGDOMAIN_FCC, {'G', 'T'}}, /* GUATEMALA */
-		{REGDOMAIN_FCC, {'G', 'U'}}, /* GUAM */
-		{REGDOMAIN_ETSI, {'H', 'U'}}, /* HUNGARY */
-		{REGDOMAIN_FCC, {'I', 'D'}}, /* INDONESIA */
-		{REGDOMAIN_ETSI, {'I', 'E'}}, /* IRELAND */
-		{REGDOMAIN_ETSI, {'I', 'L'}}, /* ISRAEL */
-		{REGDOMAIN_ETSI, {'I', 'N'}}, /* INDIA */
-		{REGDOMAIN_ETSI, {'I', 'R'}}, /* IRAN, ISLAMIC REPUBLIC OF */
-		{REGDOMAIN_ETSI, {'I', 'S'}}, /* ICELNAD */
-		{REGDOMAIN_ETSI, {'I', 'T'}}, /* ITALY */
-		{REGDOMAIN_FCC, {'J', 'M'}}, /* JAMAICA */
-		{REGDOMAIN_JAPAN, {'J', 'P'}}, /* JAPAN */
-		{REGDOMAIN_ETSI, {'J', 'O'}}, /* JORDAN */
-		{REGDOMAIN_ETSI, {'K', 'E'}}, /* KENYA */
-		{REGDOMAIN_ETSI, {'K', 'H'}}, /* CAMBODIA */
-		{REGDOMAIN_ETSI, {'K', 'P'}}, /* KOREA, DEMOCRATIC PEOPLE's REPUBLIC OF */
-		{REGDOMAIN_ETSI, {'K', 'R'}}, /* KOREA, REPUBLIC OF */
-		{REGDOMAIN_ETSI, {'K', 'W'}}, /* KUWAIT */
-		{REGDOMAIN_ETSI, {'K', 'Z'}}, /* KAZAKHSTAN */
-		{REGDOMAIN_ETSI, {'L', 'B'}}, /* LEBANON */
-		{REGDOMAIN_ETSI, {'L', 'I'}}, /* LIECHTENSTEIN */
-		{REGDOMAIN_ETSI, {'L', 'K'}}, /* SRI-LANKA */
-		{REGDOMAIN_ETSI, {'L', 'T'}}, /* LITHUANIA */
-		{REGDOMAIN_ETSI, {'L', 'U'}}, /* LUXEMBOURG */
-		{REGDOMAIN_ETSI, {'L', 'V'}}, /* LATVIA */
-		{REGDOMAIN_ETSI, {'M', 'A'}}, /* MOROCCO */
-		{REGDOMAIN_ETSI, {'M', 'C'}}, /* MONACO */
-		{REGDOMAIN_ETSI, {'M', 'K'}}, /* MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF */
-		{REGDOMAIN_FCC, {'M', 'N'}}, /* MONGOLIA */
-		{REGDOMAIN_FCC, {'M', 'O'}}, /* MACAO */
-		{REGDOMAIN_FCC, {'M', 'P'}}, /* NORTHERN MARIANA ISLANDS */
-		{REGDOMAIN_ETSI, {'M', 'Q'}}, /* MARTINIQUE */
-		{REGDOMAIN_FCC, {'M', 'T'}}, /* MALTA */
-		{REGDOMAIN_ETSI, {'M', 'U'}}, /* MAURITIUS */
-		{REGDOMAIN_ETSI, {'M', 'W'}}, /* MALAWI */
-		{REGDOMAIN_FCC, {'M', 'X'}}, /* MEXICO */
-		{REGDOMAIN_ETSI, {'M', 'Y'}}, /* MALAYSIA */
-		{REGDOMAIN_ETSI, {'N', 'G'}}, /* NIGERIA */
-		{REGDOMAIN_FCC, {'N', 'I'}}, /* NICARAGUA */
-		{REGDOMAIN_ETSI, {'N', 'L'}}, /* NETHERLANDS */
-		{REGDOMAIN_ETSI, {'N', 'O'}}, /* NORWAY */
-		{REGDOMAIN_ETSI, {'N', 'P'}}, /* NEPAL */
-		{REGDOMAIN_FCC, {'N', 'Z'}}, /* NEW-ZEALAND */
-		{REGDOMAIN_FCC, {'O', 'M'}}, /* OMAN */
-		{REGDOMAIN_FCC, {'P', 'A'}}, /* PANAMA */
-		{REGDOMAIN_ETSI, {'P', 'E'}}, /* PERU */
-		{REGDOMAIN_ETSI, {'P', 'F'}}, /* FRENCH POLYNESIA */
-		{REGDOMAIN_ETSI, {'P', 'G'}}, /* PAPUA NEW GUINEA */
-		{REGDOMAIN_FCC, {'P', 'H'}}, /* PHILIPPINES */
-		{REGDOMAIN_ETSI, {'P', 'K'}}, /* PAKISTAN */
-		{REGDOMAIN_ETSI, {'P', 'L'}}, /* POLAND */
-		{REGDOMAIN_FCC, {'P', 'R'}}, /* PUERTO RICO */
-		{REGDOMAIN_FCC, {'P', 'S'}}, /* PALESTINIAN TERRITORY, OCCUPIED */
-		{REGDOMAIN_ETSI, {'P', 'T'}}, /* PORTUGAL */
-		{REGDOMAIN_FCC, {'P', 'Y'}}, /* PARAGUAY */
-		{REGDOMAIN_ETSI, {'Q', 'A'}}, /* QATAR */
-		{REGDOMAIN_ETSI, {'R', 'E'}}, /* REUNION */
-		{REGDOMAIN_ETSI, {'R', 'O'}}, /* ROMAINIA */
-		{REGDOMAIN_ETSI, {'R', 'S'}}, /* SERBIA */
-		{REGDOMAIN_ETSI, {'R', 'U'}}, /* RUSSIA */
-		{REGDOMAIN_FCC, {'R', 'W'}}, /* RWANDA */
-		{REGDOMAIN_ETSI, {'S', 'A'}}, /* SAUDI ARABIA */
-		{REGDOMAIN_ETSI, {'S', 'E'}}, /* SWEDEN */
-		{REGDOMAIN_ETSI, {'S', 'G'}}, /* SINGAPORE */
-		{REGDOMAIN_ETSI, {'S', 'I'}}, /* SLOVENNIA */
-		{REGDOMAIN_ETSI, {'S', 'K'}}, /* SLOVAKIA */
-		{REGDOMAIN_ETSI, {'S', 'V'}}, /* EL SALVADOR */
-		{REGDOMAIN_ETSI, {'S', 'Y'}}, /* SYRIAN ARAB REPUBLIC */
-		{REGDOMAIN_ETSI, {'T', 'H'}}, /* THAILAND */
-		{REGDOMAIN_ETSI, {'T', 'N'}}, /* TUNISIA */
-		{REGDOMAIN_ETSI, {'T', 'R'}}, /* TURKEY */
-		{REGDOMAIN_ETSI, {'T', 'T'}}, /* TRINIDAD AND TOBAGO */
-		{REGDOMAIN_FCC, {'T', 'W'}}, /* TAIWAN, PRIVINCE OF CHINA */
-		{REGDOMAIN_FCC, {'T', 'Z'}}, /* TANZANIA, UNITED REPUBLIC OF */
-		{REGDOMAIN_ETSI, {'U', 'A'}}, /* UKRAINE */
-		{REGDOMAIN_ETSI, {'U', 'G'}}, /* UGANDA */
-		{REGDOMAIN_FCC, {'U', 'S'}}, /* USA */
-		{REGDOMAIN_ETSI, {'U', 'Y'}}, /* URUGUAY */
-		{REGDOMAIN_FCC, {'U', 'Z'}}, /* UZBEKISTAN */
-		{REGDOMAIN_ETSI, {'V', 'E'}}, /* VENEZUELA */
-		{REGDOMAIN_FCC, {'V', 'I'}}, /* VIRGIN ISLANDS, US */
-		{REGDOMAIN_ETSI, {'V', 'N'}}, /* VIETNAM */
-		{REGDOMAIN_ETSI, {'Y', 'E'}}, /* YEMEN */
-		{REGDOMAIN_ETSI, {'Y', 'T'}}, /* MAYOTTE */
-		{REGDOMAIN_ETSI, {'Z', 'A'}}, /* SOUTH AFRICA */
-		{REGDOMAIN_ETSI, {'Z', 'W'}}, /* ZIMBABWE */
-	}
-};
-
-const tRfChannelProps rf_channels[NUM_RF_CHANNELS] = {
+const struct chan_map chan_mapping[NUM_RF_CHANNELS] = {
 	{2412, 1},
 	{2417, 2},
 	{2422, 3},
@@ -303,13 +138,6 @@ const tRfChannelProps rf_channels[NUM_RF_CHANNELS] = {
 	{2467, 12},
 	{2472, 13},
 	{2484, 14},
-	{4920, 240},
-	{4940, 244},
-	{4960, 248},
-	{4980, 252},
-	{5040, 208},
-	{5060, 212},
-	{5080, 216},
 	{5180, 36},
 	{5200, 40},
 	{5220, 44},
@@ -359,11 +187,6 @@ const tRfChannelProps rf_channels[NUM_RF_CHANNELS] = {
 	{2452, 9},
 	{2457, 10},
 	{2462, 11},
-	{4930, 242},
-	{4950, 246},
-	{4970, 250},
-	{5050, 210},
-	{5070, 214},
 	{5190, 38},
 	{5210, 42},
 	{5230, 46},
@@ -385,27 +208,12 @@ const tRfChannelProps rf_channels[NUM_RF_CHANNELS] = {
 	{5755, 151},
 	{5775, 155},
 	{5795, 159},
-	{5815, 163,                },
+	{5815, 163},
 };
 
-static t_reg_table reg_table;
-
-const sRegulatoryChannel *reg_channels =
-	reg_table.regDomains[0].channels;
-
-
-/**
- * cds_is_wwr_sku() - is regdomain world sku
- * @regd: integer regulatory domain
- *
- * Return: bool
- */
-static inline bool cds_is_wwr_sku(u16 regd)
-{
-	return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
-	       (((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
-		(regd == WORLD));
-}
+struct regulatory_channel reg_channels[NUM_RF_CHANNELS];
+static bool init_by_driver;
+static bool init_by_reg_core;
 
 /**
  * cds_is_world_regdomain() - whether world regdomain
@@ -413,9 +221,14 @@ static inline bool cds_is_wwr_sku(u16 regd)
  *
  * Return: bool
  */
-bool cds_is_world_regdomain(uint32_t regd)
+bool cds_is_world_regdomain(uint32_t reg_domain)
 {
-	return cds_is_wwr_sku(regd & ~WORLDWIDE_ROAMING_FLAG);
+	uint32_t temp_regd = reg_domain & ~WORLDWIDE_ROAMING_FLAG;
+
+	return ((temp_regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
+		(((temp_regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
+		 (temp_regd == WORLD));
+
 }
 
 
@@ -546,11 +359,11 @@ static void cds_update_regulatory_info(hdd_context_t *hdd_ctx)
  *
  * Return: CDF_STATUS_SUCCESS
  */
-CDF_STATUS cds_get_channel_list_with_power(tChannelListWithPower *
-					   base_channels,
+CDF_STATUS cds_get_channel_list_with_power(struct channel_power
+					   *base_channels,
 					   uint8_t *num_base_channels,
-					   tChannelListWithPower *
-					   channels_40mhz,
+					   struct channel_power
+					   *channels_40mhz,
 					   uint8_t *num_40mhz_channels)
 {
 	CDF_STATUS status = CDF_STATUS_SUCCESS;
@@ -559,19 +372,19 @@ CDF_STATUS cds_get_channel_list_with_power(tChannelListWithPower *
 	if (base_channels && num_base_channels) {
 		count = 0;
 		for (i = 0; i <= RF_CHAN_14; i++) {
-			if (reg_channels[i].enabled) {
-				base_channels[count].chanId =
-					rf_channels[i].channelNum;
-				base_channels[count++].pwr =
-					reg_channels[i].pwrLimit;
+			if (reg_channels[i].state) {
+				base_channels[count].chan_num =
+					chan_mapping[i].chan_num;
+				base_channels[count++].power =
+					reg_channels[i].pwr_limit;
 			}
 		}
 		for (i = RF_CHAN_36; i <= RF_CHAN_184; i++) {
-			if (reg_channels[i].enabled) {
-				base_channels[count].chanId =
-					rf_channels[i].channelNum;
-				base_channels[count++].pwr =
-					reg_channels[i].pwrLimit;
+			if (reg_channels[i].state) {
+				base_channels[count].chan_num =
+					chan_mapping[i].chan_num;
+				base_channels[count++].power =
+					reg_channels[i].pwr_limit;
 			}
 		}
 		*num_base_channels = count;
@@ -581,20 +394,20 @@ CDF_STATUS cds_get_channel_list_with_power(tChannelListWithPower *
 		count = 0;
 
 		for (i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++) {
-			if (reg_channels[i].enabled) {
-				channels_40mhz[count].chanId =
-					rf_channels[i].channelNum;
-				channels_40mhz[count++].pwr =
-					reg_channels[i].pwrLimit;
+			if (reg_channels[i].state) {
+				channels_40mhz[count].chan_num =
+					chan_mapping[i].chan_num;
+				channels_40mhz[count++].power =
+					reg_channels[i].pwr_limit;
 			}
 		}
 
 		for (i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++) {
-			if (reg_channels[i].enabled) {
-				channels_40mhz[count].chanId =
-					rf_channels[i].channelNum;
-				channels_40mhz[count++].pwr =
-					reg_channels[i].pwrLimit;
+			if (reg_channels[i].state) {
+				channels_40mhz[count].chan_num =
+					chan_mapping[i].chan_num;
+				channels_40mhz[count++].power =
+					reg_channels[i].pwr_limit;
 			}
 		}
 		*num_40mhz_channels = count;
@@ -609,19 +422,27 @@ CDF_STATUS cds_get_channel_list_with_power(tChannelListWithPower *
  *
  * Return: CDF_STATUS
  */
-CDF_STATUS cds_read_default_country(country_code_t default_country)
+CDF_STATUS cds_read_default_country(uint8_t *default_country)
 {
-	CDF_STATUS status = CDF_STATUS_SUCCESS;
+	hdd_context_t *hdd_ctx;
+
+	hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
+			  "invalid hdd_ctx pointer");
+		return CDF_STATUS_E_FAULT;
+	}
 
 	memcpy(default_country,
-	       reg_table.default_country,
-	       sizeof(country_code_t));
+	       hdd_ctx->reg.def_country,
+	       CDS_COUNTRY_CODE_LEN + 1);
 
-	pr_info("DefaultCountry is %c%c\n",
-		default_country[0],
-		default_country[1]);
+	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
+		  "default country is %c%c\n",
+		  default_country[0],
+		  default_country[1]);
 
-	return status;
+	return CDF_STATUS_SUCCESS;
 }
 
 /**
@@ -630,12 +451,12 @@ CDF_STATUS cds_read_default_country(country_code_t default_country)
  *
  * Return: enum for the channel
  */
-static eRfChannels cds_get_channel_enum(uint32_t chan_num)
+static enum channel_enum cds_get_channel_enum(uint32_t chan_num)
 {
 	uint32_t loop;
 
 	for (loop = 0; loop <= RF_CHAN_184; loop++)
-		if (rf_channels[loop].channelNum == chan_num)
+		if (chan_mapping[loop].chan_num == chan_num)
 			return loop;
 
 	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
@@ -647,19 +468,19 @@ static eRfChannels cds_get_channel_enum(uint32_t chan_num)
 
 /**
  * cds_get_channel_state() - get the channel state
- * @channel_num: channel number
+ * @chan_num: channel number
  *
- * Return: CHANNEL_STATE
+ * Return: channel state
  */
-CHANNEL_STATE cds_get_channel_state(uint32_t chan_num)
+enum channel_state cds_get_channel_state(uint32_t chan_num)
 {
-	eRfChannels chan_enum;
+	enum channel_enum chan_enum;
 
 	chan_enum = cds_get_channel_enum(chan_num);
 	if (INVALID_RF_CHANNEL == chan_enum)
 		return CHANNEL_STATE_INVALID;
 	else
-		return reg_channels[chan_enum].enabled;
+		return reg_channels[chan_enum].state;
 }
 
 
@@ -667,19 +488,19 @@ CHANNEL_STATE cds_get_channel_state(uint32_t chan_num)
  * cds_get_bonded_channel_state() - get the bonded channel state
  * @channel_num: channel number
  *
- * Return: CHANNEL_STATE
+ * Return: channel state
  */
-CHANNEL_STATE cds_get_bonded_channel_state(uint32_t chan_num,
+enum channel_state cds_get_bonded_channel_state(uint32_t chan_num,
 					   enum channel_width ch_width)
 {
-	eRfChannels chan_enum;
+	enum channel_enum chan_enum;
 	bool bw_enabled = false;
 
 	chan_enum = cds_get_channel_enum(chan_num);
 	if (INVALID_RF_CHANNEL == chan_enum)
 		return CHANNEL_STATE_INVALID;
 
-	if (reg_channels[chan_enum].enabled) {
+	if (reg_channels[chan_enum].state) {
 		if (CHAN_WIDTH_5MHZ == ch_width)
 			bw_enabled = 1;
 		else if (CHAN_WIDTH_10MHZ == ch_width)
@@ -700,7 +521,7 @@ CHANNEL_STATE cds_get_bonded_channel_state(uint32_t chan_num,
 	}
 
 	if (bw_enabled)
-		return reg_channels[chan_enum].enabled;
+		return reg_channels[chan_enum].state;
 	else
 		return CHANNEL_STATE_DISABLE;
 }
@@ -713,13 +534,13 @@ CHANNEL_STATE cds_get_bonded_channel_state(uint32_t chan_num,
  */
 enum channel_width cds_get_max_channel_bw(uint32_t chan_num)
 {
-	eRfChannels chan_enum;
+	enum channel_enum chan_enum;
 	enum channel_width chan_bw = CHAN_WIDTH_0MHZ;
 
 	chan_enum = cds_get_channel_enum(chan_num);
 
 	if ((INVALID_RF_CHANNEL != chan_enum) &&
-	    (CHANNEL_STATE_DISABLE != reg_channels[chan_enum].enabled)) {
+	    (CHANNEL_STATE_DISABLE != reg_channels[chan_enum].state)) {
 
 		if (!(reg_channels[chan_enum].flags &
 		      IEEE80211_CHAN_NO_160MHZ))
@@ -755,10 +576,6 @@ static int cds_bw20_ch_index_to_bw40_ch_index(int k)
 		m = k - RF_CHAN_1 + RF_CHAN_BOND_3;
 		if (m > RF_CHAN_BOND_11)
 			m = RF_CHAN_BOND_11;
-	} else if (k >= RF_CHAN_240 && k <= RF_CHAN_216) {
-		m = k - RF_CHAN_240 + RF_CHAN_BOND_242;
-		if (m > RF_CHAN_BOND_214)
-			m = RF_CHAN_BOND_214;
 	} else if (k >= RF_CHAN_36 && k <= RF_CHAN_64) {
 		m = k - RF_CHAN_36 + RF_CHAN_BOND_38;
 		if (m > RF_CHAN_BOND_62)
@@ -786,31 +603,31 @@ static int cds_bw20_ch_index_to_bw40_ch_index(int k)
  */
 CDF_STATUS cds_set_dfs_region(uint8_t dfs_region)
 {
-	hdd_context_t *hdd_ctx_ptr = NULL;
+	hdd_context_t *hdd_ctx;
 
-	hdd_ctx_ptr = cds_get_context(CDF_MODULE_ID_HDD);
+	hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
 
-	if (NULL == hdd_ctx_ptr)
+	if (NULL == hdd_ctx)
 		return CDF_STATUS_E_EXISTS;
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(WITH_BACKPORTS)
-	hdd_ctx_ptr->reg.dfs_region = dfs_region;
+	hdd_ctx->reg.dfs_region = dfs_region;
 #else
 
 	/* remap the ctl code to dfs region code */
-	switch (hdd_ctx_ptr->reg.ctl_5g) {
+	switch (hdd_ctx->reg.ctl_5g) {
 	case FCC:
-		hdd_ctx_ptr->reg.dfs_region = DFS_FCC_DOMAIN;
+		hdd_ctx->reg.dfs_region = DFS_FCC_DOMAIN;
 		break;
 	case ETSI:
-		hdd_ctx_ptr->reg.dfs_region = DFS_ETSI_DOMAIN;
+		hdd_ctx->reg.dfs_region = DFS_ETSI_DOMAIN;
 		break;
 	case MKK:
-		hdd_ctx_ptr->reg.dfs_region = DFS_MKK4_DOMAIN;
+		hdd_ctx->reg.dfs_region = DFS_MKK4_DOMAIN;
 		break;
 	default:
 		/* set default dfs_region to FCC */
-		hdd_ctx_ptr->reg.dfs_region = DFS_FCC_DOMAIN;
+		hdd_ctx->reg.dfs_region = DFS_FCC_DOMAIN;
 		break;
 	}
 #endif
@@ -826,14 +643,14 @@ CDF_STATUS cds_set_dfs_region(uint8_t dfs_region)
  */
 CDF_STATUS cds_get_dfs_region(uint8_t *dfs_region)
 {
-	hdd_context_t *hdd_ctx_ptr = NULL;
+	hdd_context_t *hdd_ctx;
 
-	hdd_ctx_ptr = cds_get_context(CDF_MODULE_ID_HDD);
+	hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
 
-	if (NULL == hdd_ctx_ptr)
+	if (NULL == hdd_ctx)
 		return CDF_STATUS_E_EXISTS;
 
-	*dfs_region = hdd_ctx_ptr->reg.dfs_region;
+	*dfs_region = hdd_ctx->reg.dfs_region;
 
 	return CDF_STATUS_SUCCESS;
 }
@@ -847,14 +664,11 @@ CDF_STATUS cds_get_dfs_region(uint8_t *dfs_region)
  *         CDF_STATUS_E_EMPTY country table empty
  */
 CDF_STATUS cds_get_reg_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
-						const country_code_t
-						country_code,
-						v_CountryInfoSource_t source)
+						const uint8_t *country_alpha2,
+						enum country_src source)
 {
-	v_CONTEXT_t cds_context = NULL;
 	hdd_context_t *hdd_ctx = NULL;
 	struct wiphy *wiphy = NULL;
-	int i;
 
 	if (NULL == reg_domain_ptr) {
 		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
@@ -862,26 +676,24 @@ CDF_STATUS cds_get_reg_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
 		return CDF_STATUS_E_FAULT;
 	}
 
-	*reg_domain_ptr = REGDOMAIN_COUNT;
+	*reg_domain_ptr = 0;
 
-	if (NULL == country_code) {
+	if (SOURCE_QUERY == source)
+		return CDF_STATUS_SUCCESS;
+
+	if (NULL == country_alpha2) {
 		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 			  ("Country code array is NULL"));
 		return CDF_STATUS_E_FAULT;
 	}
 
-	if (0 == country_info_table.countryCount) {
+	if (cds_is_driver_recovering()) {
 		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-			  ("Reg domain table is empty"));
-		return CDF_STATUS_E_EMPTY;
+			  "SSR in progress, return");
+		return CDF_STATUS_SUCCESS;
 	}
 
-	cds_context = cds_get_global_context();
-
-	if (NULL != cds_context)
-		hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
-	else
-		return CDF_STATUS_E_EXISTS;
+	hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
 
 	if (NULL == hdd_ctx) {
 		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
@@ -891,51 +703,19 @@ CDF_STATUS cds_get_reg_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
 
 	wiphy = hdd_ctx->wiphy;
 
-	if (cds_is_logp_in_progress()) {
-		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-			  "SSR in progress, return");
-		*reg_domain_ptr = temp_reg_domain;
-		return CDF_STATUS_SUCCESS;
-	}
-
-	temp_reg_domain = REGDOMAIN_COUNT;
-	for (i = 0; i < country_info_table.countryCount &&
-	     REGDOMAIN_COUNT == temp_reg_domain; i++) {
-		if (memcmp(country_code,
-			   country_info_table.countryInfo[i].countryCode,
-			    CDS_COUNTRY_CODE_LEN) == 0) {
-
-			temp_reg_domain =
-				country_info_table.countryInfo[i].regDomain;
-			break;
-		}
-	}
-
-	if (REGDOMAIN_COUNT == temp_reg_domain) {
-		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-			  ("Country does not map to any Regulatory domain"));
-		temp_reg_domain = REGDOMAIN_WORLD;
-	}
-
-	if (COUNTRY_QUERY == source) {
-		*reg_domain_ptr = temp_reg_domain;
-		return CDF_STATUS_SUCCESS;
-	}
-
-	if ((COUNTRY_INIT == source) && (false == init_by_reg_core)) {
+	if ((SOURCE_DRIVER == source) && (false == init_by_reg_core)) {
 		init_by_driver = true;
-		if (('0' != country_code[0]) || ('0' != country_code[1])) {
+		if (('0' != country_alpha2[0]) || ('0' != country_alpha2[1])) {
 			INIT_COMPLETION(hdd_ctx->reg_init);
-			regulatory_hint(wiphy, country_code);
+			regulatory_hint(wiphy, country_alpha2);
 			wait_for_completion_timeout(&hdd_ctx->reg_init,
 					       msecs_to_jiffies(REG_WAIT_TIME));
 		}
-	} else if (COUNTRY_IE == source || COUNTRY_USER == source) {
-		regulatory_hint_user(country_code,
+	} else if (SOURCE_11D == source || SOURCE_USERSPACE == source) {
+		regulatory_hint_user(country_alpha2,
 				     NL80211_USER_REG_HINT_USER);
 	}
 
-	*reg_domain_ptr = temp_reg_domain;
 	return CDF_STATUS_SUCCESS;
 }
 
@@ -948,26 +728,13 @@ CDF_STATUS cds_get_reg_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
  */
 bool cds_is_dsrc_channel(uint16_t center_freq)
 {
-	switch (center_freq) {
-	case 5852:
-	case 5860:
-	case 5870:
-	case 5880:
-	case 5890:
-	case 5900:
-	case 5910:
-	case 5920:
-	case 5875:
-	case 5905:
+	if (center_freq >= 5852 &&
+	    center_freq <= 5920)
 		return 1;
-	}
+
 	return 0;
 }
 
-#ifdef FEATURE_STATICALLY_ADD_11P_CHANNELS
-#define DEFAULT_11P_POWER (30)
-#endif
-
 /**
  * cds_process_regulatory_data() - process regulatory data
  * @wiphy: wiphy
@@ -976,16 +743,15 @@ bool cds_is_dsrc_channel(uint16_t center_freq)
  * Return: int
  */
 static int cds_process_regulatory_data(struct wiphy *wiphy,
-				       uint8_t band_capability, bool reset)
+				       uint8_t band_capability,
+				       bool reset)
 {
 	int i, j, m;
 	int k = 0, n = 0;
 	hdd_context_t *hdd_ctx;
 	const struct ieee80211_reg_rule *reg_rule;
 	struct ieee80211_channel *chan;
-	sRegulatoryChannel *temp_chan_k;
-	sRegulatoryChannel *temp_chan_n;
-	sRegulatoryChannel *temp_chan;
+	struct regulatory_channel *temp_chan_k, *temp_chan_n, *temp_chan;
 
 	hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
 	if (NULL == hdd_ctx) {
@@ -1023,13 +789,8 @@ static int cds_process_regulatory_data(struct wiphy *wiphy,
 			n = cds_bw20_ch_index_to_bw40_ch_index(k);
 
 			chan = &(wiphy->bands[i]->channels[j]);
-			temp_chan_k =
-				&(reg_table.regDomains[temp_reg_domain].
-				  channels[k]);
-
-			temp_chan_n =
-				&(reg_table.regDomains[temp_reg_domain].
-				  channels[n]);
+			temp_chan_k = &(reg_channels[k]);
+			temp_chan_n = &(reg_channels[n]);
 
 			if ((!reset) &&
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(WITH_BACKPORTS)
@@ -1086,21 +847,12 @@ static int cds_process_regulatory_data(struct wiphy *wiphy,
 				}
 			}
 
-#ifdef FEATURE_STATICALLY_ADD_11P_CHANNELS
-			if (is_dsrc_channel(chan->center_freq)) {
-				temp_chan_k->enabled =
-					CHANNEL_STATE_ENABLE;
-				temp_chan_k->pwrLimit =
-					DEFAULT_11P_POWER;
-				temp_chan_k->flags = chan->flags;
-			} else
-#endif
 			if (chan->flags & IEEE80211_CHAN_DISABLED) {
-				temp_chan_k->enabled =
+				temp_chan_k->state =
 					CHANNEL_STATE_DISABLE;
 				temp_chan_k->flags = chan->flags;
 				if (n != -1) {
-					temp_chan_n->enabled =
+					temp_chan_n->state =
 						CHANNEL_STATE_DISABLE;
 					temp_chan_n->flags = chan->flags;
 				}
@@ -1119,8 +871,8 @@ static int cds_process_regulatory_data(struct wiphy *wiphy,
 					chan->flags |=
 						IEEE80211_CHAN_PASSIVE_SCAN;
 #endif
-				temp_chan_k->enabled = CHANNEL_STATE_DFS;
-				temp_chan_k->pwrLimit =
+				temp_chan_k->state = CHANNEL_STATE_DFS;
+				temp_chan_k->pwr_limit =
 					chan->max_power;
 				temp_chan_k->flags = chan->flags;
 
@@ -1128,12 +880,12 @@ static int cds_process_regulatory_data(struct wiphy *wiphy,
 					if ((chan->flags &
 					     IEEE80211_CHAN_NO_HT40) ==
 					    IEEE80211_CHAN_NO_HT40) {
-						temp_chan_n->enabled =
+						temp_chan_n->state =
 							CHANNEL_STATE_DISABLE;
 					} else {
-						temp_chan_n->enabled =
+						temp_chan_n->state =
 							CHANNEL_STATE_DFS;
-						temp_chan_n->pwrLimit =
+						temp_chan_n->pwr_limit =
 							 chan->max_power-3;
 					}
 					temp_chan_n->flags = chan->flags;
@@ -1142,19 +894,19 @@ static int cds_process_regulatory_data(struct wiphy *wiphy,
 				     IEEE80211_CHAN_NO_80MHZ) == 0)
 					hdd_ctx->isVHT80Allowed = 1;
 			} else {
-				temp_chan_k->enabled = CHANNEL_STATE_ENABLE;
-				temp_chan_k->pwrLimit = chan->max_power;
+				temp_chan_k->state = CHANNEL_STATE_ENABLE;
+				temp_chan_k->pwr_limit = chan->max_power;
 				temp_chan_k->flags = chan->flags;
 				if (n != -1) {
 					if ((chan->flags &
 					     IEEE80211_CHAN_NO_HT40) ==
 					    IEEE80211_CHAN_NO_HT40) {
-						temp_chan_n->enabled =
+						temp_chan_n->state =
 							CHANNEL_STATE_DISABLE;
 					} else {
-						temp_chan_n->enabled =
+						temp_chan_n->state =
 							CHANNEL_STATE_ENABLE;
-						temp_chan_n->pwrLimit =
+						temp_chan_n->pwr_limit =
 							chan->max_power - 3;
 					}
 					temp_chan_n->flags = chan->flags;
@@ -1168,9 +920,8 @@ static int cds_process_regulatory_data(struct wiphy *wiphy,
 
 	if (0 == (hdd_ctx->reg.eeprom_rd_ext &
 		  (1 << WHAL_REG_EXT_FCC_CH_144))) {
-		temp_chan = &(reg_table.regDomains[temp_reg_domain].
-			      channels[RF_CHAN_144]);
-		temp_chan->enabled =
+		temp_chan = &(reg_channels[RF_CHAN_144]);
+		temp_chan->state =
 			CHANNEL_STATE_DISABLE;
 	}
 
@@ -1220,8 +971,6 @@ void __hdd_reg_notifier(struct wiphy *wiphy,
 {
 	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
 	eCsrBand band_capability = eCSR_BAND_ALL;
-	country_code_t country_code;
-	int i;
 	bool vht80_allowed;
 	bool reset = false;
 
@@ -1238,7 +987,7 @@ void __hdd_reg_notifier(struct wiphy *wiphy,
 		return;
 	}
 
-	if (hdd_ctx->isUnloadInProgress || hdd_ctx->isLogpInProgress) {
+	if (cds_is_driver_unloading() || cds_is_driver_recovering()) {
 		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 			  "%s: Unloading or SSR in Progress, Ignore!!!",
 			  __func__);
@@ -1279,17 +1028,17 @@ void __hdd_reg_notifier(struct wiphy *wiphy,
 		}
 
 		if (NL80211_REGDOM_SET_BY_CORE == request->initiator) {
-			hdd_ctx->reg.cc_src = COUNTRY_CODE_SET_BY_CORE;
+			hdd_ctx->reg.cc_src = SOURCE_CORE;
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(WITH_BACKPORTS)
 			if (wiphy->regulatory_flags & REGULATORY_CUSTOM_REG)
 #else
-				if (wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY)
+			if (wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY)
 #endif
-					reset = true;
+				reset = true;
 		} else if (NL80211_REGDOM_SET_BY_DRIVER == request->initiator)
-			hdd_ctx->reg.cc_src = COUNTRY_CODE_SET_BY_DRIVER;
+			hdd_ctx->reg.cc_src = SOURCE_DRIVER;
 		else {
-			hdd_ctx->reg.cc_src = COUNTRY_CODE_SET_BY_USER;
+			hdd_ctx->reg.cc_src = SOURCE_USERSPACE;
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) && !defined(WITH_BACKPORTS)
 			if ((request->alpha2[0] == '0') &&
 			    (request->alpha2[1] == '0') &&
@@ -1300,31 +1049,11 @@ void __hdd_reg_notifier(struct wiphy *wiphy,
 #endif
 		}
 
-		/* first lookup the country in the local database */
-		country_code[0] = request->alpha2[0];
-		country_code[1] = request->alpha2[1];
-
 		hdd_ctx->reg.alpha2[0] = request->alpha2[0];
 		hdd_ctx->reg.alpha2[1] = request->alpha2[1];
 
 		cds_update_regulatory_info(hdd_ctx);
 
-		temp_reg_domain = REGDOMAIN_COUNT;
-		for (i = 0; i < country_info_table.countryCount &&
-		     REGDOMAIN_COUNT == temp_reg_domain; i++) {
-			if (memcmp(country_code,
-				  country_info_table.countryInfo[i].countryCode,
-				  CDS_COUNTRY_CODE_LEN) == 0) {
-
-				temp_reg_domain =
-				country_info_table.countryInfo[i].regDomain;
-				break;
-			}
-		}
-
-		if (REGDOMAIN_COUNT == temp_reg_domain)
-			temp_reg_domain = REGDOMAIN_WORLD;
-
 		vht80_allowed = hdd_ctx->isVHT80Allowed;
 		if (cds_process_regulatory_data(wiphy, band_capability,
 						reset) == 0) {
@@ -1337,16 +1066,8 @@ void __hdd_reg_notifier(struct wiphy *wiphy,
 		if (NL80211_REGDOM_SET_BY_DRIVER == request->initiator)
 			complete(&hdd_ctx->reg_init);
 
-		if (request->alpha2[0] == '0'
-		    && request->alpha2[1] == '0') {
-			sme_generic_change_country_code(hdd_ctx->hHal,
-							country_code,
-							REGDOMAIN_COUNT);
-		} else {
-			sme_generic_change_country_code(hdd_ctx->hHal,
-							country_code,
-							temp_reg_domain);
-		}
+		sme_generic_change_country_code(hdd_ctx->hHal,
+						hdd_ctx->reg.alpha2);
 
 		cds_fill_and_send_ctl_to_fw(&hdd_ctx->reg);
 
@@ -1381,21 +1102,15 @@ void hdd_reg_notifier(struct wiphy *wiphy,
  */
 CDF_STATUS cds_regulatory_init(void)
 {
-	v_CONTEXT_t cds_context = NULL;
 	hdd_context_t *hdd_ctx = NULL;
 	struct wiphy *wiphy = NULL;
 	int ret_val = 0;
 	struct regulatory *reg_info;
 
-	cds_context = cds_get_global_context();
-
-	if (!cds_context)
-		return CDF_STATUS_E_FAULT;
-
 	hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
 	if (!hdd_ctx) {
 		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
-			  ("Invalid pHddCtx pointer"));
+			  "invalid hdd_ctx pointer");
 		return CDF_STATUS_E_FAULT;
 	}
 
@@ -1405,8 +1120,6 @@ CDF_STATUS cds_regulatory_init(void)
 
 	cds_regulatory_wiphy_init(hdd_ctx, reg_info, wiphy);
 
-	temp_reg_domain = REGDOMAIN_WORLD;
-
 	if (cds_process_regulatory_data(wiphy,
 					hdd_ctx->config->
 					nBandCapability, true) != 0) {
@@ -1415,7 +1128,7 @@ CDF_STATUS cds_regulatory_init(void)
 		return CDF_STATUS_E_FAULT;
 	}
 
-	reg_info->cc_src = COUNTRY_CODE_SET_BY_DRIVER;
+	reg_info->cc_src = SOURCE_DRIVER;
 
 	ret_val = cds_fill_some_regulatory_info(reg_info);
 	if (ret_val) {
@@ -1423,8 +1136,8 @@ CDF_STATUS cds_regulatory_init(void)
 		return ret_val;
 	}
 
-	reg_table.default_country[0] = reg_info->alpha2[0];
-	reg_table.default_country[1] = reg_info->alpha2[1];
+	hdd_ctx->reg.def_country[0] = reg_info->alpha2[0];
+	hdd_ctx->reg.def_country[1] = reg_info->alpha2[1];
 
 	init_completion(&hdd_ctx->reg_init);
 
@@ -1449,7 +1162,29 @@ CDF_STATUS cds_set_reg_domain(void *client_ctxt, v_REGDOMAIN_t reg_domain)
 		return CDF_STATUS_E_INVAL;
 	}
 
-	reg_channels = reg_table.regDomains[reg_domain].channels;
-
 	return CDF_STATUS_SUCCESS;
 }
+
+/**
+ * cds_set_ch_params() - set channel parameters
+ * @ch: channel
+ * @phy_mode: physical mode
+ * @ch_param: channel parameters will be returned
+ *
+ * Return: None
+ */
+void cds_set_ch_params(uint8_t ch, uint32_t phy_mode,
+		chan_params_t *ch_params)
+{
+	tHalHandle *hal_ctx = cds_get_context(CDF_MODULE_ID_PE);
+	if (!hal_ctx) {
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
+			("Invalid hal_ctx pointer"));
+		return;
+	}
+	/*
+	 * TODO: remove SME call and move the SME set channel
+	 * param functionality to CDS.
+	 */
+	sme_set_ch_params(hal_ctx, phy_mode, ch, 0, ch_params);
+}

+ 30 - 18
core/cds/src/cds_sched.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -120,7 +120,7 @@ cds_cpu_hotplug_notify(struct notifier_block *block,
 	if ((NULL == pSchedContext) || (NULL == pSchedContext->ol_rx_thread))
 		return NOTIFY_OK;
 
-	if (cds_is_load_unload_in_progress())
+	if (cds_is_load_or_unload_in_progress())
 		return NOTIFY_OK;
 
 	num_cpus = num_possible_cpus();
@@ -342,10 +342,6 @@ static int cds_mc_thread(void *Arg)
 	}
 	set_user_nice(current, -2);
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-	daemonize("MC_Thread");
-#endif
-
 	/* Ack back to the context from which the main controller thread
 	 * has been created
 	 */
@@ -357,15 +353,15 @@ static int cds_mc_thread(void *Arg)
 	/* Get the Global CDS Context */
 	p_cds_context = cds_get_global_context();
 	if (!p_cds_context) {
-		hddLog(CDF_TRACE_LEVEL_FATAL, "%s: Global CDS context is Null",
-		       __func__);
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
+			  "%s: Global CDS context is Null", __func__);
 		return 0;
 	}
 
 	pHddCtx = cds_get_context(CDF_MODULE_ID_HDD);
 	if (!pHddCtx) {
-		hddLog(CDF_TRACE_LEVEL_FATAL, "%s: HDD context is Null",
-		       __func__);
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_FATAL,
+			  "%s: HDD context is Null", __func__);
 		return 0;
 	}
 
@@ -1147,7 +1143,7 @@ static void cds_print_external_threads(void)
 
 	while (i < MAX_SSR_PROTECT_LOG) {
 		if (!ssr_protect_log[i].free) {
-			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+			CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 			"PID %d is stuck at %s", ssr_protect_log[i].pid,
 			ssr_protect_log[i].func);
 		}
@@ -1190,7 +1186,7 @@ void cds_ssr_protect(const char *caller_func)
 	spin_unlock_irqrestore(&ssr_protect_lock, irq_flags);
 
 	if (!status)
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 		"Could not track PID %d call %s: log is full",
 		current->pid, caller_func);
 }
@@ -1229,19 +1225,19 @@ void cds_ssr_unprotect(const char *caller_func)
 	spin_unlock_irqrestore(&ssr_protect_lock, irq_flags);
 
 	if (!status)
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
+		CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR,
 			"Untracked call %s", caller_func);
 }
 
 /**
- * cds_is_ssr_ready() - check if the calling execution can proceed with ssr
- *
+ * cds_wait_for_external_threads_completion() - wait for external threads
+ *					completion before proceeding further
  * @caller_func: name of calling function.
  *
  * Return: true if there is no active entry points in driver
  *	   false if there is at least one active entry in driver
  */
-bool cds_is_ssr_ready(const char *caller_func)
+bool cds_wait_for_external_threads_completion(const char *caller_func)
 {
 	int count = MAX_SSR_WAIT_ITERATIONS;
 
@@ -1263,8 +1259,24 @@ bool cds_is_ssr_ready(const char *caller_func)
 		return false;
 	}
 
-	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
-		  "Allowing SSR for %s", caller_func);
+	CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_INFO,
+		  "Allowing SSR/Driver unload for %s", caller_func);
 
 	return true;
 }
+
+/**
+ * cds_get_gfp_flags(): get GFP flags
+ *
+ * Based on the scheduled context, return GFP flags
+ * Return: gfp flags
+ */
+int cds_get_gfp_flags(void)
+{
+	int flags = GFP_KERNEL;
+
+	if (in_interrupt() || in_atomic() || irqs_disabled())
+		flags = GFP_ATOMIC;
+
+	return flags;
+}

+ 23 - 1
core/cds/src/i_cds_packet.h

@@ -42,8 +42,29 @@
    Include Files
    ------------------------------------------------------------------------*/
 #include "cdf_types.h"
-/*
+/**
  * Rx Packet Struct
+ * Buffer for the packet received from WMA has pointers to 802.11
+ * frame fields and additional information based on the type of frame.
+ * @channel: Channel number
+ * @snr: Signal to noise ratio
+ * @rssi: Received signal strength indicator, normalized to -96 dBm as
+ *        normal noise floor by adding -96 to snr. All the configured
+ *        thresholds in the driver assume that noise floor is -96 dBm.
+ * @timestamp: System timestamp when frame was received. Set to jiffies.
+ * @mpdu_hdr_ptr: Pointer to beginning of 802.11 MPDU
+ * @mpdu_data_ptr: Pointer to beginning of payload
+ * @mpdu_len: Length of 802.11 MPDU
+ * @mpdu_hdr_len: Length of 802.11 MPDU header
+ * @mpdu_data_len: Length of 802.11 MPDU payload
+ * @offloadScanLearn: Bit set to 1 for beacons received during roaming scan
+ * @roamCandidateInd: Bit set to 1 when roaming candidate is found by fw
+ * @scan: Bit set to 1 if packet received during scanning
+ * @scan_src: Source of scan
+ * @dpuFeedback: DPU feedback for frame
+ * @sessionId: PE session
+ * @tsf_delta: Delta between tsf in frame and local value of tsf
+ * @rssi_raw: rssi based on actual noise floor in hardware.
  */
 typedef struct {
 	uint8_t channel;
@@ -62,6 +83,7 @@ typedef struct {
 	uint8_t dpuFeedback;
 	uint8_t sessionId;
 	uint32_t tsf_delta;
+	uint32_t rssi_raw;
 } t_packetmeta, *tp_packetmeta;
 
 /* implementation specific cds packet type */

+ 4 - 2
core/dp/htt/htt.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -43,6 +43,7 @@
 #include <ol_htt_api.h>
 
 #include <htt_internal.h>
+#include <ol_htt_tx_api.h>
 #include "hif.h"
 
 #define HTT_HTC_PKT_POOL_INIT_SIZE 100  /* enough for a large A-MPDU */
@@ -405,6 +406,7 @@ int htt_htc_attach(struct htt_pdev_t *pdev)
 	connect.EpCallbacks.EpTxComplete = htt_h2t_send_complete;
 	connect.EpCallbacks.EpTxCompleteMultiple = NULL;
 	connect.EpCallbacks.EpRecv = htt_t2h_msg_handler;
+	connect.EpCallbacks.ep_resume_tx_queue = htt_tx_resume_handler;
 
 	/* rx buffers currently are provided by HIF, not by EpRecvRefill */
 	connect.EpCallbacks.EpRecvRefill = NULL;
@@ -424,7 +426,7 @@ int htt_htc_attach(struct htt_pdev_t *pdev)
 #endif
 
 	/* connect to control service */
-	connect.ServiceID = HTT_DATA_MSG_SVC;
+	connect.service_id = HTT_DATA_MSG_SVC;
 
 	status = htc_connect_service(pdev->htc_pdev, &connect, &response);
 

+ 104 - 5
core/dp/htt/htt_h2t.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -417,7 +417,7 @@ A_STATUS htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev)
 			       cdf_nbuf_data(msg),
 			       cdf_nbuf_len(msg),
 			       pdev->htc_endpoint,
-			       1); /* tag - not relevant here */
+			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
 
 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
 
@@ -439,6 +439,7 @@ htt_h2t_dbg_stats_get(struct htt_pdev_t *pdev,
 	struct htt_htc_pkt *pkt;
 	cdf_nbuf_t msg;
 	uint32_t *msg_word;
+	uint16_t htc_tag = 1;
 
 	pkt = htt_htc_pkt_alloc(pdev);
 	if (!pkt)
@@ -452,6 +453,9 @@ htt_h2t_dbg_stats_get(struct htt_pdev_t *pdev,
 		return -EINVAL;      /* failure */
 	}
 
+	if (stats_type_reset_mask)
+		htc_tag = HTC_TX_PACKET_TAG_RUNTIME_PUT;
+
 	/* show that this is not a tx frame download
 	 * (not required, but helpful)
 	 */
@@ -503,7 +507,7 @@ htt_h2t_dbg_stats_get(struct htt_pdev_t *pdev,
 			       cdf_nbuf_data(msg),
 			       cdf_nbuf_len(msg),
 			       pdev->htc_endpoint,
-			       1); /* tag - not relevant here */
+			       htc_tag); /* tag - not relevant here */
 
 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
 
@@ -559,7 +563,7 @@ A_STATUS htt_h2t_sync_msg(struct htt_pdev_t *pdev, uint8_t sync_cnt)
 			       cdf_nbuf_data(msg),
 			       cdf_nbuf_len(msg),
 			       pdev->htc_endpoint,
-			       1); /* tag - not relevant here */
+			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
 
 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
 
@@ -626,7 +630,7 @@ htt_h2t_aggr_cfg_msg(struct htt_pdev_t *pdev,
 			       cdf_nbuf_data(msg),
 			       cdf_nbuf_len(msg),
 			       pdev->htc_endpoint,
-			       1); /* tag - not relevant here */
+			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
 
 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
 
@@ -648,6 +652,100 @@ htt_h2t_aggr_cfg_msg(struct htt_pdev_t *pdev,
  * Return: 0 success
  *         A_NO_MEMORY No memory fail
  */
+#ifdef QCA_WIFI_2_0
+/* Rome Support only WDI 1.0 */
+int htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev)
+{
+	struct htt_htc_pkt *pkt;
+	cdf_nbuf_t msg;
+	uint32_t *msg_word;
+
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return A_NO_MEMORY;
+
+	/* show that this is not a tx frame download
+	 * (not required, but helpful)
+	 */
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+	/* reserve room for HTC header */
+	msg = cdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_WDI_IPA_CFG_SZ),
+			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
+			     false);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return A_NO_MEMORY;
+	}
+	/* set the length of the message */
+	cdf_nbuf_put_tail(msg, HTT_WDI_IPA_CFG_SZ);
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) cdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	cdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_SET(*msg_word,
+				pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt);
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_CFG);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_SET(*msg_word,
+		(unsigned int)pdev->ipa_uc_tx_rsc.tx_comp_base.paddr);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_SET(*msg_word,
+		(unsigned int)ol_cfg_ipa_uc_tx_max_buf_cnt(pdev->ctrl_pdev));
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_SET(*msg_word,
+		(unsigned int)pdev->ipa_uc_tx_rsc.tx_comp_idx_paddr);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_SET(*msg_word,
+		(unsigned int)pdev->ipa_uc_tx_rsc.tx_ce_idx.paddr);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_SET(*msg_word,
+		(unsigned int)pdev->ipa_uc_rx_rsc.rx_ind_ring_base.paddr);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_SET(*msg_word,
+		(unsigned int)ol_cfg_ipa_uc_rx_ind_ring_size(pdev->ctrl_pdev));
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_SET(*msg_word,
+		(unsigned int)pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.paddr);
+
+	msg_word++;
+	*msg_word = 0;
+	HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_SET(*msg_word,
+	       (unsigned int)pdev->ipa_uc_rx_rsc.rx_rdy_idx_paddr);
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       cdf_nbuf_data(msg),
+			       cdf_nbuf_len(msg),
+			       pdev->htc_endpoint,
+			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+
+	htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
+
+	return A_OK;
+}
+#else
 int htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev)
 {
 	struct htt_htc_pkt *pkt;
@@ -791,6 +889,7 @@ int htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev)
 
 	return A_OK;
 }
+#endif
 
 /**
  * htt_h2t_ipa_uc_set_active() - Propagate WDI path enable/disable to firmware

+ 2 - 1
core/dp/htt/htt_internal.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -413,6 +413,7 @@ static inline void htt_print_rx_desc(struct htt_host_rx_desc_base *rx_desc)
 
 #endif
 
+void htt_tx_resume_handler(void *);
 #ifdef ATH_11AC_TXCOMPACT
 #define HTT_TX_SCHED htt_tx_sched
 #else

+ 103 - 51
core/dp/htt/htt_rx.c

@@ -2288,150 +2288,202 @@ fail1:
 }
 
 #ifdef IPA_OFFLOAD
+#ifdef QCA_WIFI_3_0
 /**
- * htt_rx_ipa_uc_attach() - attach htt ipa uc rx resource
+ * htt_rx_ipa_uc_alloc_wdi2_rsc() - Allocate WDI2.0 resources
  * @pdev: htt context
- * @rx_ind_ring_size: rx ring size
+ * @rx_ind_ring_elements: rx ring elements
  *
  * Return: 0 success
  */
-int htt_rx_ipa_uc_attach(struct htt_pdev_t *pdev,
+int htt_rx_ipa_uc_alloc_wdi2_rsc(struct htt_pdev_t *pdev,
 			 unsigned int rx_ind_ring_elements)
 {
-	pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr =
+	/* Allocate RX2 indication ring */
+	/* RX2 IND ring element
+	 *   4bytes: pointer
+	 *   2bytes: VDEV ID
+	 *   2bytes: length */
+	pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.vaddr =
 		cdf_os_mem_alloc_consistent(
 			pdev->osdev,
 			rx_ind_ring_elements *
 			sizeof(struct ipa_uc_rx_ring_elem_t),
-			&pdev->ipa_uc_rx_rsc.rx_ind_ring_base.paddr,
+			&pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.paddr,
 			cdf_get_dma_mem_context((&pdev->ipa_uc_rx_rsc.
-						 rx_ind_ring_base),
+						 rx2_ind_ring_base),
 						memctx));
-	if (!pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr) {
+	if (!pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.vaddr) {
 		cdf_print("%s: RX IND RING alloc fail", __func__);
 		return -ENOBUFS;
 	}
 
 	/* RX indication ring size, by bytes */
-	pdev->ipa_uc_rx_rsc.rx_ind_ring_size =
+	pdev->ipa_uc_rx_rsc.rx2_ind_ring_size =
 		rx_ind_ring_elements * sizeof(struct ipa_uc_rx_ring_elem_t);
-	cdf_mem_zero(pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr,
-		pdev->ipa_uc_rx_rsc.rx_ind_ring_size);
+	cdf_mem_zero(pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.vaddr,
+		pdev->ipa_uc_rx_rsc.rx2_ind_ring_size);
 
 	/* Allocate RX process done index */
-	pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.vaddr =
+	pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.vaddr =
 		cdf_os_mem_alloc_consistent(
 			pdev->osdev,
 			4,
-			&pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.paddr,
+			&pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.paddr,
 			cdf_get_dma_mem_context((&pdev->ipa_uc_rx_rsc.
 						 rx_ipa_prc_done_idx),
 						memctx));
-	if (!pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.vaddr) {
+	if (!pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.vaddr) {
 		cdf_print("%s: RX PROC DONE IND alloc fail", __func__);
 		cdf_os_mem_free_consistent(
 			pdev->osdev,
-			pdev->ipa_uc_rx_rsc.rx_ind_ring_size,
-			pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr,
-			pdev->ipa_uc_rx_rsc.rx_ind_ring_base.paddr,
+			pdev->ipa_uc_rx_rsc.rx2_ind_ring_size,
+			pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.vaddr,
+			pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.paddr,
 			cdf_get_dma_mem_context((&pdev->ipa_uc_rx_rsc.
-						 rx_ind_ring_base),
+						 rx2_ind_ring_base),
 						memctx));
 		return -ENOBUFS;
 	}
-	cdf_mem_zero(pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.vaddr, 4);
+	cdf_mem_zero(pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.vaddr, 4);
+	return 0;
+}
+#else
+int htt_rx_ipa_uc_alloc_wdi2_rsc(struct htt_pdev_t *pdev,
+			 unsigned int rx_ind_ring_elements)
+{
+	return 0;
+}
+#endif
 
-	pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.vaddr =
+/**
+ * htt_rx_ipa_uc_attach() - attach htt ipa uc rx resource
+ * @pdev: htt context
+ * @rx_ind_ring_size: rx ring size
+ *
+ * Return: 0 success
+ */
+int htt_rx_ipa_uc_attach(struct htt_pdev_t *pdev,
+			 unsigned int rx_ind_ring_elements)
+{
+	int ret = 0;
+	/* Allocate RX indication ring */
+	/* RX IND ring element
+	 *   4bytes: pointer
+	 *   2bytes: VDEV ID
+	 *   2bytes: length */
+	pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr =
 		cdf_os_mem_alloc_consistent(
 			pdev->osdev,
 			rx_ind_ring_elements *
-			sizeof(cdf_dma_addr_t),
-			&pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.paddr,
+			sizeof(struct ipa_uc_rx_ring_elem_t),
+			&pdev->ipa_uc_rx_rsc.rx_ind_ring_base.paddr,
 			cdf_get_dma_mem_context((&pdev->ipa_uc_rx_rsc.
-						 rx2_ind_ring_base),
+						 rx_ind_ring_base),
 						memctx));
-	if (!pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.vaddr) {
+	if (!pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr) {
 		cdf_print("%s: RX IND RING alloc fail", __func__);
 		return -ENOBUFS;
 	}
 
 	/* RX indication ring size, by bytes */
-	pdev->ipa_uc_rx_rsc.rx2_ind_ring_size =
-		rx_ind_ring_elements * sizeof(cdf_dma_addr_t);
-	cdf_mem_zero(pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.vaddr,
-		pdev->ipa_uc_rx_rsc.rx2_ind_ring_size);
+	pdev->ipa_uc_rx_rsc.rx_ind_ring_size =
+		rx_ind_ring_elements * sizeof(struct ipa_uc_rx_ring_elem_t);
+	cdf_mem_zero(pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr,
+		pdev->ipa_uc_rx_rsc.rx_ind_ring_size);
 
 	/* Allocate RX process done index */
-	pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.vaddr =
+	pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.vaddr =
 		cdf_os_mem_alloc_consistent(
 			pdev->osdev,
 			4,
-			&pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.paddr,
+			&pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.paddr,
 			cdf_get_dma_mem_context((&pdev->ipa_uc_rx_rsc.
 						 rx_ipa_prc_done_idx),
 						memctx));
-	if (!pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.vaddr) {
+	if (!pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.vaddr) {
 		cdf_print("%s: RX PROC DONE IND alloc fail", __func__);
 		cdf_os_mem_free_consistent(
 			pdev->osdev,
-			pdev->ipa_uc_rx_rsc.rx2_ind_ring_size,
-			pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.vaddr,
-			pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.paddr,
+			pdev->ipa_uc_rx_rsc.rx_ind_ring_size,
+			pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr,
+			pdev->ipa_uc_rx_rsc.rx_ind_ring_base.paddr,
 			cdf_get_dma_mem_context((&pdev->ipa_uc_rx_rsc.
-						 rx2_ind_ring_base),
+						 rx_ind_ring_base),
 						memctx));
 		return -ENOBUFS;
 	}
-	cdf_mem_zero(pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.vaddr, 4);
-	return 0;
+	cdf_mem_zero(pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.vaddr, 4);
+
+	ret = htt_rx_ipa_uc_alloc_wdi2_rsc(pdev, rx_ind_ring_elements);
+	return ret;
 }
 
-int htt_rx_ipa_uc_detach(struct htt_pdev_t *pdev)
+#ifdef QCA_WIFI_3_0
+/**
+ * htt_rx_ipa_uc_free_wdi2_rsc() - Free WDI2.0 resources
+ * @pdev: htt context
+ *
+ * Return: None
+ */
+void htt_rx_ipa_uc_free_wdi2_rsc(struct htt_pdev_t *pdev)
 {
-	if (pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr) {
+	if (pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.vaddr) {
 		cdf_os_mem_free_consistent(
 			pdev->osdev,
-			pdev->ipa_uc_rx_rsc.rx_ind_ring_size,
-			pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr,
-			pdev->ipa_uc_rx_rsc.rx_ind_ring_base.paddr,
+			pdev->ipa_uc_rx_rsc.rx2_ind_ring_size,
+			pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.vaddr,
+			pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.paddr,
 			cdf_get_dma_mem_context((&pdev->ipa_uc_rx_rsc.
-						 rx_ind_ring_base),
+						 rx2_ind_ring_base),
 						memctx));
 	}
 
-	if (pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.vaddr) {
+	if (pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.vaddr) {
 		cdf_os_mem_free_consistent(
 			pdev->osdev,
 			4,
 			pdev->ipa_uc_rx_rsc.
 			rx_ipa_prc_done_idx.vaddr,
-			pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.paddr,
+			pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.paddr,
 			cdf_get_dma_mem_context((&pdev->ipa_uc_rx_rsc.
 						 rx_ipa_prc_done_idx),
 						memctx));
 	}
-	if (pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.vaddr) {
+}
+#else
+void htt_rx_ipa_uc_free_wdi2_rsc(struct htt_pdev_t *pdev)
+{
+	return;
+}
+#endif
+
+int htt_rx_ipa_uc_detach(struct htt_pdev_t *pdev)
+{
+	if (pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr) {
 		cdf_os_mem_free_consistent(
 			pdev->osdev,
-			pdev->ipa_uc_rx_rsc.rx2_ind_ring_size,
-			pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.vaddr,
-			pdev->ipa_uc_rx_rsc.rx2_ind_ring_base.paddr,
+			pdev->ipa_uc_rx_rsc.rx_ind_ring_size,
+			pdev->ipa_uc_rx_rsc.rx_ind_ring_base.vaddr,
+			pdev->ipa_uc_rx_rsc.rx_ind_ring_base.paddr,
 			cdf_get_dma_mem_context((&pdev->ipa_uc_rx_rsc.
-						 rx2_ind_ring_base),
+						 rx_ind_ring_base),
 						memctx));
 	}
 
-	if (pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.vaddr) {
+	if (pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.vaddr) {
 		cdf_os_mem_free_consistent(
 			pdev->osdev,
 			4,
 			pdev->ipa_uc_rx_rsc.
 			rx_ipa_prc_done_idx.vaddr,
-			pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx.paddr,
+			pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx.paddr,
 			cdf_get_dma_mem_context((&pdev->ipa_uc_rx_rsc.
 						 rx2_ipa_prc_done_idx),
 						memctx));
 	}
+
+	htt_rx_ipa_uc_free_wdi2_rsc(pdev);
 	return 0;
 }
 #endif /* IPA_OFFLOAD */

+ 9 - 0
core/dp/htt/htt_t2h.c

@@ -141,6 +141,7 @@ void htt_t2h_lp_msg_handler(void *context, cdf_nbuf_t htt_t2h_msg)
 	switch (msg_type) {
 	case HTT_T2H_MSG_TYPE_VERSION_CONF:
 	{
+		cdf_runtime_pm_put();
 		pdev->tgt_ver.major = HTT_VER_CONF_MAJOR_GET(*msg_word);
 		pdev->tgt_ver.minor = HTT_VER_CONF_MINOR_GET(*msg_word);
 		cdf_print
@@ -287,6 +288,7 @@ void htt_t2h_lp_msg_handler(void *context, cdf_nbuf_t htt_t2h_msg)
 			ol_tx_single_completion_handler(pdev->txrx_pdev,
 							compl_msg->status,
 							compl_msg->desc_id);
+			cdf_runtime_pm_put();
 			HTT_TX_SCHED(pdev);
 		} else {
 			cdf_print("Ignoring HTT_T2H_MSG_TYPE_MGMT_TX_COMPL_IND indication\n");
@@ -302,6 +304,7 @@ void htt_t2h_lp_msg_handler(void *context, cdf_nbuf_t htt_t2h_msg)
 		cookie |= ((uint64_t) (*(msg_word + 2))) << 32;
 
 		stats_info_list = (uint8_t *) (msg_word + 3);
+		cdf_runtime_pm_put();
 		ol_txrx_fw_stats_handler(pdev->txrx_pdev, cookie,
 					 stats_info_list);
 		break;
@@ -357,6 +360,7 @@ void htt_t2h_lp_msg_handler(void *context, cdf_nbuf_t htt_t2h_msg)
 		uint8_t *op_msg_buffer;
 		uint8_t *msg_start_ptr;
 
+		cdf_runtime_pm_put();
 		msg_start_ptr = (uint8_t *) msg_word;
 		op_code =
 			HTT_WDI_IPA_OP_RESPONSE_OP_CODE_GET(*msg_word);
@@ -475,6 +479,11 @@ void htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
 		peer_id = HTT_RX_IND_PEER_ID_GET(*msg_word);
 		tid = HTT_RX_IND_EXT_TID_GET(*msg_word);
 
+		if (tid >= OL_TXRX_NUM_EXT_TIDS) {
+			cdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid tid %d\n",
+				tid);
+			break;
+		}
 		num_msdu_bytes =
 			HTT_RX_IND_FW_RX_DESC_BYTES_GET(
 				*(msg_word + 2 + HTT_RX_PPDU_DESC_SIZE32));

+ 158 - 55
core/dp/htt/htt_tx.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -252,8 +252,6 @@ static inline void htt_tx_desc_get_size(struct htt_pdev_t *pdev)
 		+ (ol_cfg_netbuf_frags_max(pdev->ctrl_pdev) + 1) * 8
 		   /* 2x uint32_t */
 		+ 4; /* uint32_t fragmentation list terminator */
-	if (pdev->tx_descs.size < sizeof(uint32_t *))
-		pdev->tx_descs.size = sizeof(uint32_t *);
 }
 
 /**
@@ -320,6 +318,7 @@ int htt_tx_attach(struct htt_pdev_t *pdev, int desc_pool_elems)
 	uint16_t num_page, num_desc_per_page;
 
 	htt_tx_desc_get_size(pdev);
+
 	/*
 	 * Make sure tx_descs.size is a multiple of 4-bytes.
 	 * It should be, but round up just to be sure.
@@ -626,6 +625,24 @@ int htt_tx_send_std(htt_pdev_handle pdev, cdf_nbuf_t msdu, uint16_t msdu_id)
 
 }
 
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * htt_tx_resume_handler() - resume callback for the htt endpoint
+ * @context: a pointer to the htt context
+ *
+ * runs htt_tx_sched.
+ */
+void htt_tx_resume_handler(void *context)
+{
+	struct htt_pdev_t *pdev =  (struct htt_pdev_t *) context;
+
+	htt_tx_sched(pdev);
+}
+#else
+void
+htt_tx_resume_handler(void *context) { }
+#endif
+
 cdf_nbuf_t
 htt_tx_send_batch(htt_pdev_handle pdev, cdf_nbuf_t head_msdu, int num_msdus)
 {
@@ -833,17 +850,19 @@ void htt_tx_desc_display(void *tx_desc)
 #endif
 
 #ifdef IPA_OFFLOAD
+#ifdef QCA_WIFI_2_0
 /**
- * htt_tx_ipa_uc_attach() - attach htt ipa uc tx resource
+ * htt_tx_ipa_uc_wdi_tx_buf_alloc() - Alloc WDI TX buffers
  * @pdev: htt context
- * @uc_tx_buf_sz: single tx buffer size
- * @uc_tx_buf_cnt: total tx buffer count
- * @uc_tx_partition_base: tx buffer partition start
+ * @uc_tx_buf_sz: TX buffer size
+ * @uc_tx_buf_cnt: TX Buffer count
+ * @uc_tx_partition_base: IPA UC TX partition base value
+ *
+ * Allocate WDI TX buffers. Also note Rome supports only WDI 1.0.
  *
  * Return: 0 success
- *         ENOBUFS No memory fail
  */
-int htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev,
+int htt_tx_ipa_uc_wdi_tx_buf_alloc(struct htt_pdev_t *pdev,
 			 unsigned int uc_tx_buf_sz,
 			 unsigned int uc_tx_buf_cnt,
 			 unsigned int uc_tx_partition_base)
@@ -853,52 +872,68 @@ int htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev,
 	cdf_dma_addr_t buffer_paddr;
 	uint32_t *header_ptr;
 	uint32_t *ring_vaddr;
-	int return_code = 0;
-	unsigned int tx_comp_ring_size;
+#define IPA_UC_TX_BUF_FRAG_DESC_OFFSET 16
+#define IPA_UC_TX_BUF_FRAG_HDR_OFFSET 32
 
-	/* Allocate CE Write Index WORD */
-	pdev->ipa_uc_tx_rsc.tx_ce_idx.vaddr =
-		cdf_os_mem_alloc_consistent(
-			pdev->osdev,
-			4,
-			&pdev->ipa_uc_tx_rsc.tx_ce_idx.paddr,
-			cdf_get_dma_mem_context(
-				(&pdev->ipa_uc_tx_rsc.tx_ce_idx),
-				memctx));
-	if (!pdev->ipa_uc_tx_rsc.tx_ce_idx.vaddr) {
-		cdf_print("%s: CE Write Index WORD alloc fail", __func__);
-		return -ENOBUFS;
-	}
+	ring_vaddr = pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr;
+	/* Allocate TX buffers as many as possible */
+	for (tx_buffer_count = 0;
+	     tx_buffer_count < (uc_tx_buf_cnt - 1); tx_buffer_count++) {
+		buffer_vaddr = cdf_nbuf_alloc(pdev->osdev,
+					      uc_tx_buf_sz, 0, 4, false);
+		if (!buffer_vaddr) {
+			cdf_print("%s: TX BUF alloc fail, loop index: %d",
+				  __func__, tx_buffer_count);
+			return tx_buffer_count;
+		}
 
-	/* Allocate TX COMP Ring */
-	tx_comp_ring_size = uc_tx_buf_cnt * sizeof(cdf_nbuf_t);
-	pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr =
-		cdf_os_mem_alloc_consistent(
-			pdev->osdev,
-			tx_comp_ring_size,
-			&pdev->ipa_uc_tx_rsc.tx_comp_base.paddr,
-			cdf_get_dma_mem_context((&pdev->ipa_uc_tx_rsc.
-						 tx_comp_base),
-						memctx));
-	if (!pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr) {
-		cdf_print("%s: TX COMP ring alloc fail", __func__);
-		return_code = -ENOBUFS;
-		goto free_tx_ce_idx;
-	}
+		/* Init buffer */
+		cdf_mem_zero(cdf_nbuf_data(buffer_vaddr), uc_tx_buf_sz);
+		header_ptr = (uint32_t *) cdf_nbuf_data(buffer_vaddr);
 
-	cdf_mem_zero(pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr, tx_comp_ring_size);
+		/* HTT control header */
+		*header_ptr = HTT_IPA_UC_OFFLOAD_TX_HEADER_DEFAULT;
+		header_ptr++;
 
-	/* Allocate TX BUF vAddress Storage */
-	pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg =
-		(cdf_nbuf_t *) cdf_mem_malloc(uc_tx_buf_cnt *
-					      sizeof(cdf_nbuf_t));
-	if (!pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg) {
-		cdf_print("%s: TX BUF POOL vaddr storage alloc fail", __func__);
-		return_code = -ENOBUFS;
-		goto free_tx_comp_base;
+		/* PKT ID */
+		*header_ptr |= ((uint16_t) uc_tx_partition_base +
+				tx_buffer_count) << 16;
+
+		cdf_nbuf_map(pdev->osdev, buffer_vaddr, CDF_DMA_BIDIRECTIONAL);
+		buffer_paddr = cdf_nbuf_get_frag_paddr_lo(buffer_vaddr, 0);
+		header_ptr++;
+		*header_ptr = (uint32_t) (buffer_paddr +
+						IPA_UC_TX_BUF_FRAG_DESC_OFFSET);
+		header_ptr++;
+		*header_ptr = 0xFFFFFFFF;
+
+		/* FRAG Header */
+		header_ptr++;
+		*header_ptr = buffer_paddr + IPA_UC_TX_BUF_FRAG_HDR_OFFSET;
+
+		*ring_vaddr = buffer_paddr;
+		pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg[tx_buffer_count] =
+			buffer_vaddr;
+		/* Memory barrier to ensure actual value updated */
+
+		ring_vaddr++;
 	}
-	cdf_mem_zero(pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg,
-		     uc_tx_buf_cnt * sizeof(cdf_nbuf_t));
+	return tx_buffer_count;
+}
+#else
+int htt_tx_ipa_uc_wdi_tx_buf_alloc(struct htt_pdev_t *pdev,
+			 unsigned int uc_tx_buf_sz,
+			 unsigned int uc_tx_buf_cnt,
+			 unsigned int uc_tx_partition_base)
+{
+	unsigned int tx_buffer_count;
+	cdf_nbuf_t buffer_vaddr;
+	uint32_t buffer_paddr;
+	uint32_t *header_ptr;
+	uint32_t *ring_vaddr;
+#define IPA_UC_TX_BUF_FRAG_DESC_OFFSET 20
+#define IPA_UC_TX_BUF_FRAG_HDR_OFFSET 64
+#define IPA_UC_TX_BUF_TSO_HDR_SIZE 6
 
 	ring_vaddr = pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr;
 	/* Allocate TX buffers as many as possible */
@@ -909,7 +944,7 @@ int htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev,
 		if (!buffer_vaddr) {
 			cdf_print("%s: TX BUF alloc fail, loop index: %d",
 				  __func__, tx_buffer_count);
-			return 0;
+			return tx_buffer_count;
 		}
 
 		/* Init buffer */
@@ -930,7 +965,8 @@ int htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev,
 
 		/* Frag Desc Pointer */
 		/* 64bits descriptor, Low 32bits */
-		*header_ptr = (uint32_t) (buffer_paddr + 20);
+		*header_ptr = (uint32_t) (buffer_paddr +
+						IPA_UC_TX_BUF_FRAG_DESC_OFFSET);
 		header_ptr++;
 
 		/* 64bits descriptor, high 32bits */
@@ -943,8 +979,8 @@ int htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev,
 
 		/* FRAG Header */
 		/* 6 words TSO header */
-		header_ptr += 6;
-		*header_ptr = buffer_paddr + 64;
+		header_ptr += IPA_UC_TX_BUF_TSO_HDR_SIZE;
+		*header_ptr = buffer_paddr + IPA_UC_TX_BUF_FRAG_HDR_OFFSET;
 
 		*ring_vaddr = buffer_paddr;
 		pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg[tx_buffer_count] =
@@ -953,8 +989,75 @@ int htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev,
 
 		ring_vaddr += 2;
 	}
+	return tx_buffer_count;
+}
+#endif
+
+/**
+ * htt_tx_ipa_uc_attach() - attach htt ipa uc tx resource
+ * @pdev: htt context
+ * @uc_tx_buf_sz: single tx buffer size
+ * @uc_tx_buf_cnt: total tx buffer count
+ * @uc_tx_partition_base: tx buffer partition start
+ *
+ * Return: 0 success
+ *         ENOBUFS No memory fail
+ */
+int htt_tx_ipa_uc_attach(struct htt_pdev_t *pdev,
+			 unsigned int uc_tx_buf_sz,
+			 unsigned int uc_tx_buf_cnt,
+			 unsigned int uc_tx_partition_base)
+{
+	int return_code = 0;
+	unsigned int tx_comp_ring_size;
+
+	/* Allocate CE Write Index WORD */
+	pdev->ipa_uc_tx_rsc.tx_ce_idx.vaddr =
+		cdf_os_mem_alloc_consistent(
+			pdev->osdev,
+			4,
+			&pdev->ipa_uc_tx_rsc.tx_ce_idx.paddr,
+			cdf_get_dma_mem_context(
+				(&pdev->ipa_uc_tx_rsc.tx_ce_idx),
+				memctx));
+	if (!pdev->ipa_uc_tx_rsc.tx_ce_idx.vaddr) {
+		cdf_print("%s: CE Write Index WORD alloc fail", __func__);
+		return -ENOBUFS;
+	}
+
+	/* Allocate TX COMP Ring */
+	tx_comp_ring_size = uc_tx_buf_cnt * sizeof(cdf_nbuf_t);
+	pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr =
+		cdf_os_mem_alloc_consistent(
+			pdev->osdev,
+			tx_comp_ring_size,
+			&pdev->ipa_uc_tx_rsc.tx_comp_base.paddr,
+			cdf_get_dma_mem_context((&pdev->ipa_uc_tx_rsc.
+						 tx_comp_base),
+						memctx));
+	if (!pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr) {
+		cdf_print("%s: TX COMP ring alloc fail", __func__);
+		return_code = -ENOBUFS;
+		goto free_tx_ce_idx;
+	}
+
+	cdf_mem_zero(pdev->ipa_uc_tx_rsc.tx_comp_base.vaddr, tx_comp_ring_size);
+
+	/* Allocate TX BUF vAddress Storage */
+	pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg =
+		(cdf_nbuf_t *) cdf_mem_malloc(uc_tx_buf_cnt *
+					      sizeof(cdf_nbuf_t));
+	if (!pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg) {
+		cdf_print("%s: TX BUF POOL vaddr storage alloc fail", __func__);
+		return_code = -ENOBUFS;
+		goto free_tx_comp_base;
+	}
+	cdf_mem_zero(pdev->ipa_uc_tx_rsc.tx_buf_pool_vaddr_strg,
+		     uc_tx_buf_cnt * sizeof(cdf_nbuf_t));
+
+	pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt = htt_tx_ipa_uc_wdi_tx_buf_alloc(
+		pdev, uc_tx_buf_sz, uc_tx_buf_cnt, uc_tx_partition_base);
 
-	pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt = tx_buffer_count;
 
 	return 0;
 

+ 4 - 3
core/dp/ol/inc/ol_txrx_dbg.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -82,7 +82,7 @@ struct ol_txrx_stats_req {
 
 #define ol_txrx_debug(vdev, debug_specs) 0
 #define ol_txrx_fw_stats_cfg(vdev, type, val) 0
-#define ol_txrx_fw_stats_get(vdev, req) 0
+#define ol_txrx_fw_stats_get(vdev, req, response_expected) 0
 #define ol_txrx_aggr_cfg(vdev, max_subfrms_ampdu, max_subfrms_amsdu) 0
 
 #else /*---------------------------------------------------------------------*/
@@ -95,7 +95,8 @@ void ol_txrx_fw_stats_cfg(ol_txrx_vdev_handle vdev,
 			  uint8_t cfg_stats_type, uint32_t cfg_val);
 
 int ol_txrx_fw_stats_get(ol_txrx_vdev_handle vdev,
-			 struct ol_txrx_stats_req *req);
+			 struct ol_txrx_stats_req *req,
+			 bool response_expected);
 
 int ol_txrx_aggr_cfg(ol_txrx_vdev_handle vdev,
 		     int max_subfrms_ampdu, int max_subfrms_amsdu);

+ 15 - 3
core/dp/txrx/ol_cfg.c

@@ -56,6 +56,20 @@ void ol_tx_set_flow_control_parameters(struct txrx_pdev_cfg_t *cfg_ctx,
 }
 #endif
 
+#if CFG_TGT_DEFAULT_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK
+static inline
+uint8_t ol_defrag_timeout_check(void)
+{
+	return 1;
+}
+#else
+static inline
+uint8_t ol_defrag_timeout_check(void)
+{
+	return 0;
+}
+#endif
+
 /* FIX THIS -
  * For now, all these configuration parameters are hardcoded.
  * Many of these should actually be determined dynamically instead.
@@ -79,9 +93,7 @@ ol_pdev_handle ol_pdev_cfg_attach(cdf_device_t osdev,
 	cfg_ctx->tx_download_size = 16;
 	/* temporarily diabled PN check for Riva/Pronto */
 	cfg_ctx->rx_pn_check = 1;
-#if CFG_TGT_DEFAULT_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK
-	cfg_ctx->defrag_timeout_check = 1;
-#endif
+	cfg_ctx->defrag_timeout_check = ol_defrag_timeout_check();
 	cfg_ctx->max_peer_id = 511;
 	cfg_ctx->max_vdev = CFG_TGT_NUM_VDEV;
 	cfg_ctx->pn_rx_fwd_check = 1;

+ 2 - 2
core/dp/txrx/ol_rx.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -98,7 +98,7 @@ void ol_rx_trigger_restore(htt_pdev_handle htt_pdev, cdf_nbuf_t head_msdu,
 	}
 
 	if (!htt_pdev->rx_ring.htt_rx_restore) {
-		cds_set_logp_in_progress(true);
+		cds_set_recovery_in_progress(true);
 		htt_pdev->rx_ring.htt_rx_restore = 1;
 		schedule_work(&ol_rx_restore_work);
 	}

+ 2 - 1
core/dp/txrx/ol_tx_send.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -504,6 +504,7 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
 		tx_desc->status = status;
 		netbuf = tx_desc->netbuf;
 
+		cdf_runtime_pm_put();
 		cdf_nbuf_trace_update(netbuf, trace_str);
 		/* Per SDU update of byte count */
 		byte_cnt += cdf_nbuf_len(netbuf);

+ 80 - 13
core/dp/txrx/ol_txrx.c

@@ -313,9 +313,11 @@ void ol_tx_set_desc_global_pool_size(uint32_t num_msdu_desc)
 		cdf_print("%s: pdev is NULL\n", __func__);
 		return;
 	}
-	pdev->num_msdu_desc = num_msdu_desc + TX_FLOW_MGMT_POOL_SIZE;
-	TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Global pool size: %d = %d + %d\n",
-		pdev->num_msdu_desc, num_msdu_desc, TX_FLOW_MGMT_POOL_SIZE);
+	pdev->num_msdu_desc = num_msdu_desc;
+	if (!ol_tx_get_is_mgmt_over_wmi_enabled())
+		pdev->num_msdu_desc += TX_FLOW_MGMT_POOL_SIZE;
+	TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Global pool size: %d\n",
+		pdev->num_msdu_desc);
 	return;
 }
 
@@ -330,6 +332,32 @@ uint32_t ol_tx_get_desc_global_pool_size(struct ol_txrx_pdev_t *pdev)
 {
 	return pdev->num_msdu_desc;
 }
+
+/**
+ * ol_tx_get_total_free_desc() - get total free descriptors
+ * @pdev: pdev handle
+ *
+ * Return: total free descriptors
+ */
+static inline
+uint32_t ol_tx_get_total_free_desc(struct ol_txrx_pdev_t *pdev)
+{
+	struct ol_tx_flow_pool_t *pool = NULL;
+	uint32_t free_desc;
+
+	free_desc = pdev->tx_desc.num_free;
+	cdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
+	TAILQ_FOREACH(pool, &pdev->tx_desc.flow_pool_list,
+					 flow_pool_list_elem) {
+		cdf_spin_lock_bh(&pool->flow_pool_lock);
+		free_desc += pool->avail_desc;
+		cdf_spin_unlock_bh(&pool->flow_pool_lock);
+	}
+	cdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
+
+	return free_desc;
+}
+
 #else
 /**
  * ol_tx_get_desc_global_pool_size() - get global pool size
@@ -342,6 +370,19 @@ uint32_t ol_tx_get_desc_global_pool_size(struct ol_txrx_pdev_t *pdev)
 {
 	return ol_cfg_target_tx_credit(pdev->ctrl_pdev);
 }
+
+/**
+ * ol_tx_get_total_free_desc() - get total free descriptors
+ * @pdev: pdev handle
+ *
+ * Return: total free descriptors
+ */
+static inline
+uint32_t ol_tx_get_total_free_desc(struct ol_txrx_pdev_t *pdev)
+{
+	return pdev->tx_desc.num_free;
+}
+
 #endif
 
 /**
@@ -1642,11 +1683,6 @@ void ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer)
 
 		/* check whether the parent vdev has no peers left */
 		if (TAILQ_EMPTY(&vdev->peer_list)) {
-			/*
-			 * Now that there are no references to the peer, we can
-			 * release the peer reference lock.
-			 */
-			cdf_spin_unlock_bh(&pdev->peer_ref_mutex);
 			/*
 			 * Check if the parent vdev was waiting for its peers
 			 * to be deleted, in order for it to be deleted too.
@@ -1657,6 +1693,12 @@ void ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer)
 				void *vdev_delete_context =
 					vdev->delete.context;
 
+				/*
+				 * Now that there are no references to the peer,
+				 * we can release the peer reference lock.
+				 */
+				cdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+
 				TXRX_PRINT(TXRX_PRINT_LEVEL_INFO1,
 					   "%s: deleting vdev object %p "
 					   "(%02x:%02x:%02x:%02x:%02x:%02x)"
@@ -1672,9 +1714,12 @@ void ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer)
 				cdf_mem_free(vdev);
 				if (vdev_delete_cb)
 					vdev_delete_cb(vdev_delete_context);
+			} else {
+				cdf_spin_unlock_bh(&pdev->peer_ref_mutex);
 			}
-		} else
+		} else {
 			cdf_spin_unlock_bh(&pdev->peer_ref_mutex);
+		}
 
 		/*
 		 * 'array' is allocated in addba handler and is supposed to be
@@ -1853,7 +1898,7 @@ int ol_txrx_get_tx_pending(ol_txrx_pdev_handle pdev_handle)
 
 	total = ol_tx_get_desc_global_pool_size(pdev);
 
-	return total - pdev->tx_desc.num_free;
+	return total - ol_tx_get_total_free_desc(pdev);
 }
 
 void ol_txrx_discard_tx_pending(ol_txrx_pdev_handle pdev_handle)
@@ -1920,7 +1965,8 @@ ol_txrx_fw_stats_cfg(ol_txrx_vdev_handle vdev,
 }
 
 A_STATUS
-ol_txrx_fw_stats_get(ol_txrx_vdev_handle vdev, struct ol_txrx_stats_req *req)
+ol_txrx_fw_stats_get(ol_txrx_vdev_handle vdev, struct ol_txrx_stats_req *req,
+			bool response_expected)
 {
 	struct ol_txrx_pdev_t *pdev = vdev->pdev;
 	uint64_t cookie;
@@ -1961,6 +2007,9 @@ ol_txrx_fw_stats_get(ol_txrx_vdev_handle vdev, struct ol_txrx_stats_req *req)
 		while (cdf_semaphore_acquire(pdev->osdev, req->wait.sem_ptr))
 			;
 
+	if (response_expected == false)
+		cdf_mem_free(non_volatile_req);
+
 	return A_OK;
 }
 #endif
@@ -2728,16 +2777,20 @@ void ol_txrx_ipa_uc_fw_op_event_handler(void *context,
 	if (cdf_unlikely(!pdev)) {
 		CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_ERROR,
 			      "%s: Invalid context", __func__);
+		cdf_mem_free(rxpkt);
 		return;
 	}
 
-	if (pdev->ipa_uc_op_cb)
+	if (pdev->ipa_uc_op_cb) {
 		pdev->ipa_uc_op_cb(rxpkt, pdev->osif_dev);
-	else
+	} else {
 		CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_ERROR,
 			      "%s: ipa_uc_op_cb NULL", __func__);
+		cdf_mem_free(rxpkt);
+	}
 }
 
+#ifdef QCA_CONFIG_SMP
 /**
  * ol_txrx_ipa_uc_op_response() - Handle OP command response from firmware
  * @pdev: handle to the HTT instance
@@ -2766,6 +2819,20 @@ void ol_txrx_ipa_uc_op_response(ol_txrx_pdev_handle pdev, uint8_t *op_msg)
 	pkt->staId = 0;
 	cds_indicate_rxpkt(sched_ctx, pkt);
 }
+#else
+void ol_txrx_ipa_uc_op_response(ol_txrx_pdev_handle pdev,
+				uint8_t *op_msg)
+{
+	if (pdev->ipa_uc_op_cb) {
+		pdev->ipa_uc_op_cb(op_msg, pdev->osif_dev);
+	} else {
+		CDF_TRACE(CDF_MODULE_ID_TXRX, CDF_TRACE_LEVEL_ERROR,
+		    "%s: IPA callback function is not registered", __func__);
+		cdf_mem_free(op_msg);
+		return;
+	}
+}
+#endif
 
 /**
  * ol_txrx_ipa_uc_register_op_cb() - Register OP handler function

+ 6 - 0
core/dp/txrx/ol_txrx_flow_control.c

@@ -430,6 +430,9 @@ int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool)
 		cdf_spin_unlock_bh(&pool->flow_pool_lock);
 
 		pdev->tx_desc.num_invalid_bin++;
+		TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
+			"%s: invalid pool created %d\n",
+			 __func__, pdev->tx_desc.num_invalid_bin);
 		if (pdev->tx_desc.num_invalid_bin > MAX_INVALID_BIN)
 			ASSERT(0);
 
@@ -477,6 +480,9 @@ int ol_tx_free_invalid_flow_pool(struct ol_tx_flow_pool_t *pool)
 	cdf_spin_unlock_bh(&pool->flow_pool_lock);
 
 	pdev->tx_desc.num_invalid_bin--;
+	TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
+		"%s: invalid pool deleted %d\n",
+		 __func__, pdev->tx_desc.num_invalid_bin);
 
 	return ol_tx_delete_flow_pool(pool);
 }

+ 1 - 1
core/hdd/inc/qc_sap_ioctl.h

@@ -109,7 +109,7 @@ struct sQcSapreq_wscie {
  * Retrieve the WPS PBC Probe Request IEs.
  */
 typedef struct sQcSapreq_WPSPBCProbeReqIES {
-	uint8_t macaddr[QCSAP_ADDR_LEN];
+	struct cdf_mac_addr macaddr;
 	uint16_t probeReqIELen;
 	uint8_t probeReqIE[512];
 } sQcSapreq_WPSPBCProbeReqIES_t;

+ 10 - 5
core/hdd/inc/wlan_hdd_assoc.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -51,10 +51,6 @@
 /* Timeout (in ms) for Link to Up before Registering Station */
 #define ASSOC_LINKUP_TIMEOUT 60
 
-/* In pronto case, IBSS owns the first peer for bss peer.
-   In Rome case, IBSS uses the 2nd peer as bss peer */
-#define IBSS_BROADCAST_STAID 1
-
 /* Type Declarations */
 /**
  * typedef eConnectionState - Connection states
@@ -256,4 +252,13 @@ CDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter,
 				 uint8_t sta_id,
 				 enum ol_txrx_peer_state sta_state,
 				 bool roam_synch_in_progress);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo);
+#else
+static inline bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
+{
+	return false;
+}
+#endif
+
 #endif

+ 135 - 28
core/hdd/inc/wlan_hdd_cfg.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -138,6 +138,21 @@
 #define CFG_MAX_RX_AMPDU_FACTOR_MAX            WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMAX
 #define CFG_MAX_RX_AMPDU_FACTOR_DEFAULT        WNI_CFG_MAX_RX_AMPDU_FACTOR_STADEF
 
+/* Configuration option for HT MPDU density (Table 8-125 802.11-2012)
+ * 0 for no restriction
+ * 1 for 1/4 micro sec
+ * 2 for 1/2 micro sec
+ * 3 for 1 micro sec
+ * 4 for 2 micro sec
+ * 5 for 4 micro sec
+ * 6 for 8 micro sec
+ * 7 for 16 micro sec
+ */
+#define CFG_HT_MPDU_DENSITY_NAME               "ght_mpdu_density"
+#define CFG_HT_MPDU_DENSITY_MIN                WNI_CFG_MPDU_DENSITY_STAMIN
+#define CFG_HT_MPDU_DENSITY_MAX                WNI_CFG_MPDU_DENSITY_STAMAX
+#define CFG_HT_MPDU_DENSITY_DEFAULT            WNI_CFG_MPDU_DENSITY_STADEF
+
 /* Configuration added to enable/disable CTS2SELF in */
 /* Adaptive RX drain feature */
 #define CFG_ENABLE_ADAPT_RX_DRAIN_NAME     "gEnableAdaptRxDrain"
@@ -230,7 +245,6 @@ typedef enum {
 #define CFG_RSSI_CATEGORY_GAP_MAX              (100)
 #define CFG_RSSI_CATEGORY_GAP_DEFAULT          (5)
 
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 #define CFG_ROAM_PREFER_5GHZ                   "gRoamPrefer5GHz"
 #define CFG_ROAM_PREFER_5GHZ_MIN              (0)
 #define CFG_ROAM_PREFER_5GHZ_MAX              (1)
@@ -244,7 +258,6 @@ typedef enum {
 #define CFG_ROAM_INTRA_BAND_MIN               (0)
 #define CFG_ROAM_INTRA_BAND_MAX               (1)
 #define CFG_ROAM_INTRA_BAND_DEFAULT           (0)
-#endif
 
 #define CFG_SHORT_PREAMBLE_NAME                "gShortPreamble"
 #define CFG_SHORT_PREAMBLE_MIN                 WNI_CFG_SHORT_PREAMBLE_STAMIN
@@ -618,7 +631,6 @@ typedef enum {
 #define CFG_ESE_FEATURE_ENABLED_DEFAULT                     (0) /* disabled */
 #endif /* FEATURE_WLAN_ESE */
 
-#ifdef FEATURE_WLAN_LFR
 #define CFG_LFR_FEATURE_ENABLED_NAME                       "FastRoamEnabled"
 #define CFG_LFR_FEATURE_ENABLED_MIN                         (0)
 #define CFG_LFR_FEATURE_ENABLED_MAX                         (1)
@@ -628,9 +640,7 @@ typedef enum {
 #define CFG_LFR_MAWC_FEATURE_ENABLED_MIN                    (0)
 #define CFG_LFR_MAWC_FEATURE_ENABLED_MAX                    (1)
 #define CFG_LFR_MAWC_FEATURE_ENABLED_DEFAULT                (0) /* disabled */
-#endif /* FEATURE_WLAN_LFR */
 
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 /* This flag will control fasttransition in case of 11r and ese. */
 /* Basically with this the whole neighbor roam, pre-auth, reassoc */
 /* can be turned ON/OFF. */
@@ -670,8 +680,6 @@ typedef enum {
 #define CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT                (CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN)
 /* disabled by default */
 
-#endif /* (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) */
-
 #ifdef FEATURE_WLAN_OKC
 #define CFG_OKC_FEATURE_ENABLED_NAME                       "OkcEnabled"
 #define CFG_OKC_FEATURE_ENABLED_MIN                        (0)
@@ -832,11 +840,6 @@ typedef enum {
 #define CFG_QOS_IMPLICIT_SETUP_ENABLED_MAX                  (1)
 #define CFG_QOS_IMPLICIT_SETUP_ENABLED_DEFAULT              (1)
 
-#define CFG_ENABLE_LOGP_NAME                                "gEnableLogp"
-#define CFG_ENABLE_LOGP_MIN                                 (0)
-#define CFG_ENABLE_LOGP_MAX                                 (1)
-#define CFG_ENABLE_LOGP_DEFAULT                             (0)
-
 #if defined WLAN_FEATURE_VOWIFI_11R
 #define CFG_FT_RESOURCE_REQ_NAME                        "gFTResourceReqSupported"
 #define CFG_FT_RESOURCE_REQ_MIN                         (0)
@@ -869,7 +872,6 @@ typedef enum {
 #define CFG_BCN_EARLY_TERM_WAKE_MAX                  (255)
 #define CFG_BCN_EARLY_TERM_WAKE_DEFAULT              (3)
 
-#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
 #define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_NAME             "gNeighborScanTimerPeriod"
 #define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN              (3)
 #define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX              (300)
@@ -949,7 +951,6 @@ typedef enum {
 #define CFG_ROAM_BEACON_RSSI_WEIGHT_MIN                 (0)
 #define CFG_ROAM_BEACON_RSSI_WEIGHT_MAX                 (16)
 #define CFG_ROAM_BEACON_RSSI_WEIGHT_DEFAULT             (14)
-#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
 
 #define CFG_QOS_WMM_BURST_SIZE_DEFN_NAME                        "burstSizeDefinition"
 #define CFG_QOS_WMM_BURST_SIZE_DEFN_MIN                         (0)
@@ -1246,6 +1247,29 @@ typedef enum {
 #define CFG_ENABLE_GREEN_AP_FEATURE_MIN     (0)
 #define CFG_ENABLE_GREEN_AP_FEATURE_MAX     (1)
 #define CFG_ENABLE_GREEN_AP_FEATURE_DEFAULT (1)
+
+/* Enhanced Green AP (EGAP) flags/params */
+#define CFG_ENABLE_EGAP_ENABLE_FEATURE             "gEnableEGAP"
+#define CFG_ENABLE_EGAP_ENABLE_FEATURE_MIN         (0)
+#define CFG_ENABLE_EGAP_ENABLE_FEATURE_MAX         (1)
+#define CFG_ENABLE_EGAP_ENABLE_FEATURE_DEFAULT     (0)
+
+#define CFG_ENABLE_EGAP_INACT_TIME_FEATURE         "gEGAPInactTime"
+#define CFG_ENABLE_EGAP_INACT_TIME_FEATURE_MIN     (0)
+#define CFG_ENABLE_EGAP_INACT_TIME_FEATURE_MAX     (5000)
+#define CFG_ENABLE_EGAP_INACT_TIME_FEATURE_DEFAULT (1000)
+
+#define CFG_ENABLE_EGAP_WAIT_TIME_FEATURE          "gEGAPWaitTime"
+#define CFG_ENABLE_EGAP_WAIT_TIME_FEATURE_MIN      (0)
+#define CFG_ENABLE_EGAP_WAIT_TIME_FEATURE_MAX      (5000)
+#define CFG_ENABLE_EGAP_WAIT_TIME_FEATURE_DEFAULT  (100)
+
+#define CFG_ENABLE_EGAP_FLAGS_FEATURE              "gEGAPFeatures"
+#define CFG_ENABLE_EGAP_FLAGS_FEATURE_MIN          (0)
+#define CFG_ENABLE_EGAP_FLAGS_FEATURE_MAX          (15)
+#define CFG_ENABLE_EGAP_FLAGS_FEATURE_DEFAULT      (7)
+/* end Enhanced Green AP flags/params */
+
 #endif
 
 #ifdef FEATURE_WLAN_FORCE_SAP_SCC
@@ -1538,22 +1562,35 @@ typedef enum {
 #define CFG_TDLS_TX_STATS_PERIOD                    "gTDLSTxStatsPeriod"
 #define CFG_TDLS_TX_STATS_PERIOD_MIN                (10)
 #define CFG_TDLS_TX_STATS_PERIOD_MAX                (4294967295UL)
-#define CFG_TDLS_TX_STATS_PERIOD_DEFAULT            (5000)
+#define CFG_TDLS_TX_STATS_PERIOD_DEFAULT            (500)
 
 #define CFG_TDLS_TX_PACKET_THRESHOLD                "gTDLSTxPacketThreshold"
 #define CFG_TDLS_TX_PACKET_THRESHOLD_MIN            (0)
 #define CFG_TDLS_TX_PACKET_THRESHOLD_MAX            (4294967295UL)
-#define CFG_TDLS_TX_PACKET_THRESHOLD_DEFAULT        (100)
+#define CFG_TDLS_TX_PACKET_THRESHOLD_DEFAULT        (10)
 
 #define CFG_TDLS_MAX_DISCOVERY_ATTEMPT              "gTDLSMaxDiscoveryAttempt"
 #define CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN          (1)
 #define CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX          (100)
 #define CFG_TDLS_MAX_DISCOVERY_ATTEMPT_DEFAULT      (5)
 
+/*  teardown notification interval (gTDLSIdleTimeout) should be multiple of
+ *  setup notification (gTDLSTxStatsPeriod) interval.
+ *  e.g.
+ *       if setup notification (gTDLSTxStatsPeriod) interval = 500, then
+ *       teardown notification (gTDLSIdleTimeout) interval should be 1000,
+ *       1500, 2000, 2500...
+ */
+#define CFG_TDLS_IDLE_TIMEOUT                       "gTDLSIdleTimeout"
+#define CFG_TDLS_IDLE_TIMEOUT_MIN                   (500)
+#define CFG_TDLS_IDLE_TIMEOUT_MAX                   (40000)
+#define CFG_TDLS_IDLE_TIMEOUT_DEFAULT               (5000)
+
+
 #define CFG_TDLS_IDLE_PACKET_THRESHOLD              "gTDLSIdlePacketThreshold"
 #define CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN          (0)
 #define CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX          (40000)
-#define CFG_TDLS_IDLE_PACKET_THRESHOLD_DEFAULT      (5)
+#define CFG_TDLS_IDLE_PACKET_THRESHOLD_DEFAULT      (3)
 
 #define CFG_TDLS_RSSI_TRIGGER_THRESHOLD             "gTDLSRSSITriggerThreshold"
 #define CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN         (-120)
@@ -1641,6 +1678,20 @@ typedef enum {
 #define CFG_TDLS_SCAN_ENABLE_MIN                   (0)
 #define CFG_TDLS_SCAN_ENABLE_MAX                   (1)
 #define CFG_TDLS_SCAN_ENABLE_DEFAULT               (0)
+
+/* TDLS peer kickout threshold to fw
+ *     Firmware will use this value to determine, when to send TDLS
+ *     peer kick out event to host.
+ *     E.g.
+ *        if peer kick out threshold is 10, then firmware will wait for 10
+ *        consecutive packet failures and then send TDLS kickout
+ *        notification to host driver
+ */
+#define CFG_TDLS_PEER_KICKOUT_THRESHOLD            "gTDLSPeerKickoutThreshold"
+#define CFG_TDLS_PEER_KICKOUT_THRESHOLD_MIN        (10)
+#define CFG_TDLS_PEER_KICKOUT_THRESHOLD_MAX        (5000)
+#define CFG_TDLS_PEER_KICKOUT_THRESHOLD_DEFAULT    (96)
+
 #endif
 
 /* Enable/Disable LPWR Image(cMEM uBSP) Transition */
@@ -1681,6 +1732,15 @@ typedef enum {
 #define CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_MAX     (WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMAX)
 #define CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_DEFAULT (WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STADEF)
 
+/*
+ * Enable / Disable Tx beamformee in SAP mode
+ * Default: Disable
+ */
+#define CFG_VHT_ENABLE_TXBF_SAP_MODE         "gEnableTxBFeeSAP"
+#define CFG_VHT_ENABLE_TXBF_SAP_MODE_MIN     (0)
+#define CFG_VHT_ENABLE_TXBF_SAP_MODE_MAX     (1)
+#define CFG_VHT_ENABLE_TXBF_SAP_MODE_DEFAULT (0)
+
 #define CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED         "gTxBFCsnValue"
 #define CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_MIN     (WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMIN)
 #define CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_MAX     (WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMAX - 1)
@@ -1887,7 +1947,11 @@ typedef enum {
 #define CFG_ENABLE_FW_LOG_NAME                   "gEnablefwlog"
 #define CFG_ENABLE_FW_LOG_DISABLE                (0)
 #define CFG_ENABLE_FW_LOG_ENABLE                 (1)
+#ifdef QCA_WIFI_3_0_ADRASTEA
 #define CFG_ENABLE_FW_LOG_DEFAULT                (CFG_ENABLE_FW_LOG_DISABLE)
+#else
+#define CFG_ENABLE_FW_LOG_DEFAULT                (CFG_ENABLE_FW_LOG_ENABLE)
+#endif
 
 /*
  * Enable/Disable SSR for USB
@@ -2776,6 +2840,43 @@ enum dot11p_mode {
 #define CFG_FIRST_SCAN_BUCKET_THRESHOLD_MAX       (-30)
 #define CFG_FIRST_SCAN_BUCKET_THRESHOLD_DEFAULT   (-30)
 
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+/*
+ * Enable IP subnet detection during legacy fast roming version 3.
+ * Legacy fast roaming could roam across IP subnets without host
+ * processors' knowledge. This feature enables firmware to wake up
+ * the host processor if it successfully determines change in the IP subnet.
+ * Change in IP subnet could potentially cause disruption in IP connnectivity
+ * if IP address is not refreshed.
+ */
+#define CFG_ENABLE_LFR_SUBNET_DETECTION    "gLFRSubnetDetectionEnable"
+#define CFG_ENABLE_LFR_SUBNET_MIN          (0)
+#define CFG_ENABLE_LFR_SUBNET_MAX          (1)
+#define CFG_ENABLE_LFR_SUBNET_DEFAULT      (1)
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+/* Option to report rssi in cfg80211_inform_bss_frame()
+ * 0 = use rssi value based on noise floor = -96 dBm
+ * 1 = use rssi value based on actual noise floor in hardware
+ */
+#define CFG_INFORM_BSS_RSSI_RAW_NAME               "gInformBssRssiRaw"
+#define CFG_INFORM_BSS_RSSI_RAW_MIN                (0)
+#define CFG_INFORM_BSS_RSSI_RAW_MAX                (1)
+#define CFG_INFORM_BSS_RSSI_RAW_DEFAULT            (1)
+
+#ifdef QCA_WIFI_3_0_EMU
+/*
+ * On M2M emulation platform we have a fixed mapping between macs, hence
+ * vdev transition & MCC support is not possible on this platform. But MPR
+ * platform doesn't have these limitations. This config allows at runtime
+ * enable/disable vdev transition & MCC support depending on the platform
+ * it is running on
+ */
+#define CFG_ENABLE_M2M_LIMITATION              "gEnableM2MLimitation"
+#define CFG_ENABLE_M2M_LIMITATION_MIN          (0)
+#define CFG_ENABLE_M2M_LIMITATION_MAX          (1)
+#define CFG_ENABLE_M2M_LIMITATION_DEFAULT      (1)
+#endif /* QCA_WIFI_3_0_EMU */
+
 /*---------------------------------------------------------------------------
    Type declarations
    -------------------------------------------------------------------------*/
@@ -2794,7 +2895,6 @@ struct hdd_config {
 	bool fSupplicantCountryCodeHasPriority;
 	uint32_t HeartbeatThresh24;
 	char PowerUsageControl[4];
-	bool fIsLogpEnabled;
 	bool fIsImpsEnabled;
 	bool is_ps_enabled;
 	uint32_t nBmpsModListenInterval;
@@ -2850,7 +2950,6 @@ struct hdd_config {
 	bool fFTResourceReqSupported;
 #endif
 
-#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
 	uint16_t nNeighborScanPeriod;
 	uint8_t nNeighborLookupRssiThreshold;
 	uint8_t delay_before_vdev_stop;
@@ -2869,7 +2968,6 @@ struct hdd_config {
 	uint32_t nhi_rssi_scan_rssi_delta;
 	uint32_t nhi_rssi_scan_delay;
 	int32_t nhi_rssi_scan_rssi_ub;
-#endif
 
 	/* Additional Handoff params */
 	uint32_t nRoamingTime;
@@ -2922,19 +3020,15 @@ struct hdd_config {
 	uint32_t InfraUapsdBeSuspIntv;
 	uint32_t InfraUapsdBkSrvIntv;
 	uint32_t InfraUapsdBkSuspIntv;
-#ifdef FEATURE_WLAN_LFR
 	bool isFastRoamIniFeatureEnabled;
 	bool MAWCEnabled;
-#endif
 #ifdef FEATURE_WLAN_ESE
 	uint32_t InfraInactivityInterval;
 	bool isEseIniFeatureEnabled;
 #endif
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 	bool isFastTransitionEnabled;
 	uint8_t RoamRssiDiff;
 	bool isWESModeEnabled;
-#endif
 #ifdef FEATURE_WLAN_OKC
 	bool isOkcIniFeatureEnabled;
 #endif
@@ -3043,12 +3137,10 @@ struct hdd_config {
 	int32_t linkSpeedRssiHigh;
 	int32_t linkSpeedRssiMid;
 	int32_t linkSpeedRssiLow;
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 	bool nRoamPrefer5GHz;
 	bool nRoamIntraBand;
 	uint8_t nProbes;
 	uint16_t nRoamScanHomeAwayTime;
-#endif
 	uint8_t enableMCC;
 	uint8_t allowMCCGODiffBI;
 	bool isP2pDeviceAddrAdministrated;
@@ -3058,6 +3150,7 @@ struct hdd_config {
 	uint8_t vhtRxMCS;
 	uint8_t vhtTxMCS;
 	bool enableTxBF;
+	bool enable_txbf_sap_mode;
 	uint8_t txBFCsnValue;
 	bool enable_su_tx_bformer;
 	uint8_t vhtRxMCS2x2;
@@ -3087,6 +3180,7 @@ struct hdd_config {
 	uint32_t fTDLSTxStatsPeriod;
 	uint32_t fTDLSTxPacketThreshold;
 	uint32_t fTDLSMaxDiscoveryAttempt;
+	uint32_t tdls_idle_timeout;
 	uint32_t fTDLSIdlePacketThreshold;
 	int32_t fTDLSRSSITriggerThreshold;
 	int32_t fTDLSRSSITeardownThreshold;
@@ -3104,6 +3198,7 @@ struct hdd_config {
 	uint8_t fTDLSPrefOffChanNum;
 	uint8_t fTDLSPrefOffChanBandwidth;
 	uint8_t enable_tdls_scan;
+	uint32_t tdls_peer_kickout_threshold;
 #endif
 #ifdef WLAN_SOFTAP_VSTA_FEATURE
 	bool fEnableVSTASupport;
@@ -3247,6 +3342,10 @@ struct hdd_config {
 
 #ifdef FEATURE_GREEN_AP
 	bool enableGreenAP;
+	bool enable_egap;
+	uint32_t egap_feature_flag;
+	uint32_t egap_inact_time;
+	uint32_t egap_wait_time;
 #endif
 	uint8_t force_sap_acs;
 	uint8_t force_sap_acs_st_ch;
@@ -3355,6 +3454,14 @@ struct hdd_config {
 	int8_t early_stop_scan_min_threshold;
 	int8_t early_stop_scan_max_threshold;
 	int8_t first_scan_bucket_threshold;
+	uint8_t ht_mpdu_density;
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+	bool enable_lfr_subnet_detection;
+#endif
+	uint8_t inform_bss_rssi_raw;
+#ifdef QCA_WIFI_3_0_EMU
+	bool enable_m2m_limitation;
+#endif
 };
 
 #define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))
@@ -3444,7 +3551,7 @@ typedef enum {
 typedef struct tREG_TABLE_ENTRY {
 
 	char *RegName;          /* variable name in the qcom_cfg.ini file */
-	WLAN_PARAMETER_TYPE RegType;    /* variable type in the hdd_config_t structure */
+	WLAN_PARAMETER_TYPE RegType;    /* variable type in hdd_config struct */
 	unsigned long Flags;    /* Specify optional parms and if RangeCheck is performed */
 	unsigned short VarOffset;       /* offset to field from the base address of the structure */
 	unsigned short VarSize; /* size (in bytes) of the field */

+ 3 - 3
core/hdd/inc/wlan_hdd_host_offload.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -51,8 +51,8 @@ typedef struct {
 	uint8_t offloadType;
 	uint8_t enableOrDisable;
 	union {
-		uint8_t hostIpv4Addr[4];
-		uint8_t hostIpv6Addr[16];
+		uint8_t hostIpv4Addr[SIR_IPV4_ADDR_LEN];
+		uint8_t hostIpv6Addr[SIR_MAC_IPV6_ADDR_LEN];
 	} params;
 	struct cdf_mac_addr bssId;
 } tHostOffloadRequest, *tpHostOffloadRequest;

+ 43 - 58
core/hdd/inc/wlan_hdd_main.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -156,8 +156,9 @@
 
 #define WLAN_CHIP_VERSION   "WCNSS"
 
+#ifndef HDD_DISALLOW_LEGACY_HDDLOG
 #define hddLog(level, args ...) CDF_TRACE(CDF_MODULE_ID_HDD, level, ## args)
-
+#endif
 #define hdd_log(level, args...) CDF_TRACE(CDF_MODULE_ID_HDD, level, ## args)
 #define hdd_logfl(level, format, args...) hdd_log(level, FL(format), ## args)
 
@@ -529,14 +530,23 @@ typedef struct beacon_data_s {
 	int dtim_period;
 } beacon_data_t;
 
-/* MAINTAIN 1 - 1 CORRESPONDENCE WITH tCDF_CON_MODE */
+/**
+ * enum device_mode: Maintain one to one correspondence with tCDF_ADAPTER_MODE
+ * @WLAN_HDD_INFRA_STATION: station mode
+ * @WLAN_HDD_SOFTAP: sap mode
+ * @WLAN_HDD_P2P_CLIENT: p2p client mode
+ * @WLAN_HDD_P2P_GO: p2p go mode
+ * @WLAN_HDD_FTM: ftm mode
+ * @WLAN_HDD_IBSS: ibss mode
+ * @WLAN_HDD_P2P_DEVICE: p2p device mode
+ * @WLAN_HDD_OCB: ocb mode
+ */
 typedef enum device_mode {
 	WLAN_HDD_INFRA_STATION,
 	WLAN_HDD_SOFTAP,
 	WLAN_HDD_P2P_CLIENT,
 	WLAN_HDD_P2P_GO,
-	/* Mode 5 is reserved for FTM */
-	WLAN_HDD_FTM = 5,
+	WLAN_HDD_FTM,
 	WLAN_HDD_IBSS,
 	WLAN_HDD_P2P_DEVICE,
 	WLAN_HDD_OCB
@@ -623,12 +633,6 @@ typedef struct hdd_cfg80211_state_s {
 	eP2PActionFrameState actionFrmState;
 } hdd_cfg80211_state_t;
 
-typedef enum {
-	HDD_SSR_NOT_REQUIRED,
-	HDD_SSR_REQUIRED,
-	HDD_SSR_DISABLED,
-} e_hdd_ssr_required;
-
 struct hdd_station_ctx {
 	/** Handle to the Wireless Extension State */
 	hdd_wext_state_t WextState;
@@ -642,9 +646,7 @@ struct hdd_station_ctx {
 
 	roaming_info_t roam_info;
 
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 	int ft_carrier_on;
-#endif
 
 #ifdef WLAN_FEATURE_GTK_OFFLOAD
 	tSirGtkOffloadParams gtkOffloadReqParams;
@@ -662,6 +664,8 @@ struct hdd_station_ctx {
 
 	/* STA ctx debug variables */
 	int staDebugState;
+
+	uint8_t broadcast_ibss_staid;
 };
 
 #define BSS_STOP    0
@@ -813,13 +817,20 @@ struct hdd_netif_queue_history {
 
 
 struct hdd_adapter_s {
-	void *pHddCtx;
+	/* Magic cookie for adapter sanity verification.  Note that this
+	 * needs to be at the beginning of the private data structure so
+	 * that it will exists at the beginning of dev->priv and hence
+	 * will always be in mapped memory
+	 */
+	uint32_t magic;
 
-	device_mode_t device_mode;
+	void *pHddCtx;
 
 	/** Handle to the network device */
 	struct net_device *dev;
 
+	device_mode_t device_mode;
+
 	/** IPv4 notifier callback for handling ARP offload on change in IP */
 	struct work_struct ipv4NotifierWorkQueue;
 #ifdef WLAN_NS_OFFLOAD
@@ -939,8 +950,6 @@ struct hdd_adapter_s {
 #endif
 	uint8_t addr_filter_pattern;
 
-	/* Magic cookie for adapter sanity verification */
-	uint32_t magic;
 	bool higherDtimTransition;
 	bool survey_idx;
 
@@ -1127,12 +1136,6 @@ struct hdd_context_s {
 	bool is_ol_rx_thread_suspended;
 #endif
 
-	volatile bool isLogpInProgress;
-
-	bool isLoadInProgress;
-
-	bool isUnloadInProgress;
-
 	/* Track whether Mcast/Bcast Filter is enabled. */
 	bool hdd_mcastbcast_filter_set;
 
@@ -1142,10 +1145,6 @@ struct hdd_context_s {
 	/* Lock to avoid race condition during start/stop bss */
 	struct mutex sap_lock;
 
-#ifdef WLAN_KD_READY_NOTIFIER
-	bool kd_nl_init;
-#endif /* WLAN_KD_READY_NOTIFIER */
-
 #ifdef FEATURE_OEM_DATA_SUPPORT
 	/* OEM App registered or not */
 	bool oem_app_registered;
@@ -1203,7 +1202,7 @@ struct hdd_context_s {
 	/* Use below lock to protect access to isSchedScanUpdatePending
 	 * since it will be accessed in two different contexts.
 	 */
-	spinlock_t schedScan_lock;
+	cdf_spinlock_t sched_scan_lock;
 
 	/* Flag keeps track of wiphy suspend/resume */
 	bool isWiphySuspended;
@@ -1320,8 +1319,7 @@ struct hdd_context_s {
 
 	cdf_mc_timer_t dbs_opportunistic_timer;
 	bool connection_in_progress;
-	spinlock_t connection_status_lock;
-	cdf_mutex_t hdd_conc_list_lock;
+	cdf_spinlock_t connection_status_lock;
 
 	uint16_t hdd_txrx_hist_idx;
 	struct hdd_tx_rx_histogram hdd_txrx_hist[NUM_TX_RX_HISTOGRAM];
@@ -1336,6 +1334,9 @@ struct hdd_context_s {
 /*---------------------------------------------------------------------------
    Function declarations and documentation
    -------------------------------------------------------------------------*/
+int hdd_validate_channel_and_bandwidth(hdd_adapter_t *adapter,
+				uint32_t chan_number,
+				phy_ch_width chan_bw);
 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
 void wlan_hdd_check_sta_ap_concurrent_ch_intf(void *sta_pAdapter);
 #endif
@@ -1363,10 +1364,10 @@ CDF_STATUS hdd_add_adapter_front(hdd_context_t *pHddCtx,
 
 hdd_adapter_t *hdd_open_adapter(hdd_context_t *pHddCtx, uint8_t session_type,
 				const char *name, tSirMacAddr macAddr,
-				uint8_t rtnl_held);
+				bool rtnl_held);
 CDF_STATUS hdd_close_adapter(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
-			     uint8_t rtnl_held);
-CDF_STATUS hdd_close_all_adapters(hdd_context_t *pHddCtx);
+			     bool rtnl_held);
+CDF_STATUS hdd_close_all_adapters(hdd_context_t *pHddCtx, bool rtnl_held);
 CDF_STATUS hdd_stop_all_adapters(hdd_context_t *pHddCtx);
 CDF_STATUS hdd_reset_all_adapters(hdd_context_t *pHddCtx);
 CDF_STATUS hdd_start_all_adapters(hdd_context_t *pHddCtx);
@@ -1385,8 +1386,8 @@ uint8_t *wlan_hdd_get_intf_addr(hdd_context_t *pHddCtx);
 void wlan_hdd_release_intf_addr(hdd_context_t *pHddCtx, uint8_t *releaseAddr);
 uint8_t hdd_get_operating_channel(hdd_context_t *pHddCtx, device_mode_t mode);
 
-void hdd_set_conparam(uint32_t newParam);
-tCDF_CON_MODE hdd_get_conparam(void);
+void hdd_set_conparam(uint32_t con_param);
+enum tCDF_GLOBAL_CON_MODE hdd_get_conparam(void);
 
 void hdd_abort_mac_scan(hdd_context_t *pHddCtx, uint8_t sessionId,
 			eCsrAbortReason reason);
@@ -1397,8 +1398,6 @@ void wlan_hdd_reset_prob_rspies(hdd_adapter_t *pHostapdAdapter);
 void hdd_prevent_suspend(uint32_t reason);
 void hdd_allow_suspend(uint32_t reason);
 void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason);
-bool hdd_is_ssr_required(void);
-void hdd_set_ssr_required(e_hdd_ssr_required value);
 
 void wlan_hdd_cfg80211_update_wiphy_caps(struct wiphy *wiphy);
 CDF_STATUS hdd_set_ibss_power_save_params(hdd_adapter_t *pAdapter);
@@ -1425,6 +1424,9 @@ static inline void hdd_stop_bus_bw_computer_timer(hdd_adapter_t *pAdapter)
 }
 #endif
 
+int hdd_init(void);
+void hdd_deinit(void);
+
 int hdd_wlan_startup(struct device *dev, void *hif_sc);
 void __hdd_wlan_exit(void);
 int hdd_wlan_notify_modem_power_state(int state);
@@ -1453,23 +1455,6 @@ bool hdd_is_5g_supported(hdd_context_t *pHddCtx);
 
 int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter);
 
-#ifdef WLAN_FEATURE_STATS_EXT
-void wlan_hdd_cfg80211_stats_ext_init(hdd_context_t *pHddCtx);
-#endif
-
-#ifdef WLAN_FEATURE_LINK_LAYER_STATS
-void wlan_hdd_cfg80211_link_layer_stats_init(hdd_context_t *pHddCtx);
-static inline bool hdd_link_layer_stats_supported(void)
-{
-	return true;
-}
-#else
-static inline bool hdd_link_layer_stats_supported(void)
-{
-	return false;
-}
-#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
-
 void hdd_get_fw_version(hdd_context_t *hdd_ctx,
 			uint32_t *major_spid, uint32_t *minor_spid,
 			uint32_t *siid, uint32_t *crmid);
@@ -1496,10 +1481,8 @@ static inline bool hdd_is_memdump_supported(void)
 
 void hdd_update_macaddr(struct hdd_config *config,
 			struct cdf_mac_addr hw_macaddr);
-#if defined(FEATURE_WLAN_LFR)
 void wlan_hdd_disable_roaming(hdd_adapter_t *pAdapter);
 void wlan_hdd_enable_roaming(hdd_adapter_t *pAdapter);
-#endif
 
 CDF_STATUS hdd_post_cds_enable_config(hdd_context_t *pHddCtx);
 
@@ -1517,7 +1500,6 @@ void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter);
 static inline void wlan_hdd_stop_sap(hdd_adapter_t *ap_adapter) {}
 static inline void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter) {}
 #endif
-cdf_wake_lock_t *hdd_wlan_get_wake_lock_ptr(void);
 
 #ifdef QCA_CONFIG_SMP
 int wlan_hdd_get_cpu(void);
@@ -1537,7 +1519,10 @@ void wlan_hdd_clear_tx_rx_histogram(hdd_context_t *pHddCtx);
 void wlan_hdd_display_netif_queue_history(hdd_context_t *hdd_ctx);
 void wlan_hdd_clear_netif_queue_history(hdd_context_t *hdd_ctx);
 const char *hdd_get_fwpath(void);
-
+void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind);
+hdd_adapter_t *hdd_get_adapter_by_sme_session_id(hdd_context_t *hdd_ctx,
+						uint32_t sme_session_id);
+phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width);
 uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel,
 			uint8_t bw_offset);
 

+ 9 - 6
core/hdd/inc/wlan_hdd_oemdata.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -25,8 +25,6 @@
  * to the Linux Foundation.
  */
 
-#ifdef FEATURE_OEM_DATA_SUPPORT
-
 /**
  * DOC: wlan_hdd_oemdata.h
  *
@@ -36,6 +34,8 @@
 #ifndef __WLAN_HDD_OEM_DATA_H__
 #define __WLAN_HDD_OEM_DATA_H__
 
+#ifdef FEATURE_OEM_DATA_SUPPORT
+
 #ifndef OEM_DATA_REQ_SIZE
 #define OEM_DATA_REQ_SIZE 280
 #endif
@@ -166,7 +166,10 @@ int iw_get_oem_data_cap(struct net_device *dev, struct iw_request_info *info,
 int oem_activate_service(struct hdd_context_s *hdd_ctx);
 
 void hdd_send_oem_data_rsp_msg(int length, uint8_t *oemDataRsp);
-
-#endif /* __WLAN_HDD_OEM_DATA_H__ */
-
+#else
+static inline int oem_activate_service(struct hdd_context_s *hdd_ctx)
+{
+	return 0;
+}
 #endif /* FEATURE_OEM_DATA_SUPPORT */
+#endif /* __WLAN_HDD_OEM_DATA_H__ */

+ 4 - 62
core/hdd/inc/wlan_hdd_p2p.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -38,7 +38,6 @@
 #define WAIT_CANCEL_REM_CHAN    1000
 #define WAIT_REM_CHAN_READY     1000
 #define WAIT_CHANGE_CHANNEL_FOR_OFFCHANNEL_TX 3000
-#define ESTIMATED_ROC_DUR_REQD_FOR_ACTION_TX 20
 #define COMPLETE_EVENT_PROPOGATE_TIME 10
 
 #ifdef QCA_WIFI_3_0_EMU
@@ -61,19 +60,9 @@
 #define P2P_ROC_DURATION_MULTIPLIER_GO_ABSENT    5
 #endif
 
-#ifdef WLAN_FEATURE_11W
-#define WLAN_HDD_SET_WEP_FRM_FC(__fc__)     ((__fc__) = ((__fc__) | 0x40))
-#endif /* WLAN_FEATURE_11W */
-
 #define HDD_P2P_MAX_ROC_DURATION 1000
 #define MAX_ROC_REQ_QUEUE_ENTRY 10
 
-enum hdd_rx_flags {
-	HDD_RX_FLAG_DECRYPTED = 1 << 0,
-	HDD_RX_FLAG_MMIC_STRIPPED = 1 << 1,
-	HDD_RX_FLAG_IV_STRIPPED = 1 << 2,
-};
-
 #define P2P_POWER_SAVE_TYPE_OPPORTUNISTIC        (1 << 0)
 #define P2P_POWER_SAVE_TYPE_PERIODIC_NOA         (1 << 1)
 #define P2P_POWER_SAVE_TYPE_SINGLE_NOA           (1 << 2)
@@ -103,38 +92,23 @@ typedef struct p2p_app_setP2pPs {
 } p2p_app_setP2pPs_t;
 
 int wlan_hdd_cfg80211_remain_on_channel(struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 					struct wireless_dev *wdev,
-#else
-					struct net_device *dev,
-#endif
 					struct ieee80211_channel *chan,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-					enum nl80211_channel_type channel_type,
-#endif
 					unsigned int duration, u64 *cookie);
 
 int wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 					       struct wireless_dev *wdev,
-#else
-					       struct net_device *dev,
-#endif
 					       u64 cookie);
 
 int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 					  struct wireless_dev *wdev,
-#else
-					  struct net_device *dev,
-#endif
 					  u64 cookie);
 
 int hdd_set_p2p_ps(struct net_device *dev, void *msgData);
 int hdd_set_p2p_opps(struct net_device *dev, uint8_t *command);
 int hdd_set_p2p_noa(struct net_device *dev, uint8_t *command);
 
-void hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
+void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
 			     uint32_t nFrameLength, uint8_t *pbFrames,
 			     uint8_t frameType, uint32_t rxChan, int8_t rxRssi);
 
@@ -147,54 +121,22 @@ void wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter);
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
 int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 		     struct cfg80211_mgmt_tx_params *params, u64 *cookie);
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
+#else
 int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 		     struct ieee80211_channel *chan, bool offchan,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-		     enum nl80211_channel_type channel_type,
-		     bool channel_type_valid,
-#endif
 		     unsigned int wait,
 		     const u8 *buf, size_t len, bool no_cck,
 		     bool dont_wait_for_ack, u64 *cookie);
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
-int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
-		     struct ieee80211_channel *chan, bool offchan,
-		     enum nl80211_channel_type channel_type,
-		     bool channel_type_valid, unsigned int wait,
-		     const u8 *buf, size_t len, bool no_cck,
-		     bool dont_wait_for_ack, u64 *cookie);
-#else
-int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
-		     struct ieee80211_channel *chan, bool offchan,
-		     enum nl80211_channel_type channel_type,
-		     bool channel_type_valid, unsigned int wait,
-		     const u8 *buf, size_t len, u64 *cookie);
 #endif
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
 struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
 					       const char *name,
 					       enum nl80211_iftype type,
 					       u32 *flags,
 					       struct vif_params *params);
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
-struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy, char *name,
-					       enum nl80211_iftype type,
-					       u32 *flags,
-					       struct vif_params *params);
-#else
-struct net_device *wlan_hdd_add_virtual_intf(struct wiphy *wiphy, char *name,
-					     enum nl80211_iftype type,
-					     u32 *flags,
-					     struct vif_params *params);
-#endif
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 int wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev);
-#else
-int wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev);
-#endif
+
 
 void wlan_hdd_cleanup_remain_on_channel_ctx(hdd_adapter_t *pAdapter);
 

+ 0 - 16
core/hdd/inc/wlan_hdd_power.h

@@ -39,18 +39,6 @@
 #ifdef WLAN_FEATURE_PACKET_FILTERING
 
 #define HDD_MAX_CMP_PER_PACKET_FILTER     5
-#define HDD_FILTER_IPV6_MC_UC             1
-#define HDD_FILTER_IPV6_MC                0
-#define HDD_FILTER_ID_IPV6_MC             10
-#define HDD_FILTER_ID_IPV6_UC             11
-
-#define HDD_IPV6_MC_CMP_DATA              0x33
-#define HDD_IPV6_UC_CMP_DATA              0x01
-#define HDD_IPV6_CMP_DATA_0               0x86
-#define HDD_IPV6_CMP_DATA_1               0xDD
-
-#define HDD_WLAN_MAC_ADDR_LEN             6
-#define HDD_MAX_NUM_MULTICAST_ADDRESS     10
 
 /**
  * enum pkt_filter_protocol_layer - packet filter protocol layer
@@ -167,14 +155,10 @@ void hdd_ipv6_notifier_work_queue(struct work_struct *work);
 #endif
 
 int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
 				  struct wireless_dev *wdev,
-#endif
 				  int *dbm);
 int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
 				  struct wireless_dev *wdev,
-#endif
 				  enum nl80211_tx_power_setting type,
 				  int dbm);
 int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,

+ 15 - 23
core/hdd/inc/wlan_hdd_tdls.h

@@ -34,20 +34,6 @@
 
 #ifdef FEATURE_WLAN_TDLS
 
-#define TDLS_SUB_DISCOVERY_PERIOD   100
-
-#define TDLS_MAX_DISCOVER_REQS_PER_TIMER 1
-
-#define TDLS_DISCOVERY_PERIOD       3600000
-
-#define TDLS_TX_STATS_PERIOD        3600000
-
-#define TDLS_IMPLICIT_TRIGGER_PKT_THRESHOLD     100
-
-#define TDLS_RX_IDLE_TIMEOUT        5000
-
-#define TDLS_RSSI_TRIGGER_HYSTERESIS 50
-
 /*
  * Before UpdateTimer expires, we want to timeout discovery response
  * should not be more than 2000.
@@ -115,9 +101,6 @@ typedef struct {
  */
 typedef struct {
 	struct wiphy *wiphy;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-	struct net_device *dev;
-#endif
 	struct cfg80211_scan_request *scan_request;
 	int magic;
 	int attempt;
@@ -134,12 +117,15 @@ typedef struct {
  * @eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY: suppress implicit trigger,
  *			but respond to the peer
  * @eTDLS_SUPPORT_ENABLED: implicit trigger
+ * @eTDLS_SUPPORT_EXTERNAL_CONTROL: External control means implicit
+ *     trigger but only to a peer mac configured by user space.
  */
 typedef enum {
 	eTDLS_SUPPORT_NOT_ENABLED = 0,
 	eTDLS_SUPPORT_DISABLED,
 	eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY,
 	eTDLS_SUPPORT_ENABLED,
+	eTDLS_SUPPORT_EXTERNAL_CONTROL,
 } eTDLSSupportMode;
 
 /**
@@ -394,6 +380,9 @@ typedef struct {
  * @puapsd_mask: puapsd mask
  * @puapsd_inactivity_time: puapsd inactivity time
  * @puapsd_rx_frame_threshold: puapsd rx frame threshold
+ * @teardown_notification_ms: tdls teardown notification interval
+ * @tdls_peer_kickout_threshold: tdls packets threshold
+ *    for peer kickout operation
  */
 typedef struct {
 	uint32_t vdev_id;
@@ -409,6 +398,8 @@ typedef struct {
 	uint32_t puapsd_mask;
 	uint32_t puapsd_inactivity_time;
 	uint32_t puapsd_rx_frame_threshold;
+	uint32_t teardown_notification_ms;
+	uint32_t tdls_peer_kickout_threshold;
 } tdlsInfo_t;
 
 int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter);
@@ -492,15 +483,9 @@ hddTdlsPeer_t *wlan_hdd_tdls_is_progress(hdd_context_t *pHddCtx,
 
 int wlan_hdd_tdls_copy_scan_context(hdd_context_t *pHddCtx,
 				    struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-				    struct net_device *dev,
-#endif
 				    struct cfg80211_scan_request *request);
 
 int wlan_hdd_tdls_scan_callback(hdd_adapter_t *pAdapter, struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-				struct net_device *dev,
-#endif
 				struct cfg80211_scan_request *request);
 
 void wlan_hdd_tdls_scan_done_callback(hdd_adapter_t *pAdapter);
@@ -523,6 +508,10 @@ int wlan_hdd_tdls_set_extctrl_param(hdd_adapter_t *pAdapter,
 int wlan_hdd_tdls_set_force_peer(hdd_adapter_t *pAdapter, const uint8_t *mac,
 				 bool forcePeer);
 
+int wlan_hdd_tdls_update_peer_mac(hdd_adapter_t *adapter,
+				const uint8_t *mac,
+				uint32_t peer_state);
+
 int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
 					const uint8_t *peer);
 int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
@@ -618,6 +607,7 @@ int hdd_set_tdls_offchannel(hdd_context_t *hdd_ctx, int offchannel);
 int hdd_set_tdls_secoffchanneloffset(hdd_context_t *hdd_ctx, int offchanoffset);
 int hdd_set_tdls_offchannelmode(hdd_adapter_t *adapter, int offchanmode);
 int hdd_set_tdls_scan_type(hdd_context_t *hdd_ctx, int val);
+void hdd_tdls_pre_init(hdd_context_t *hdd_ctx);
 
 #else
 static inline void hdd_tdls_notify_mode_change(hdd_adapter_t *adapter,
@@ -631,6 +621,8 @@ wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_context_t *hddctx)
 static inline void wlan_hdd_tdls_exit(hdd_adapter_t *adapter)
 {
 }
+
+static inline void hdd_tdls_pre_init(hdd_context_t *hdd_ctx) { }
 #endif /* End of FEATURE_WLAN_TDLS */
 
 #endif /* __HDD_TDLS_H */

+ 2 - 1
core/hdd/inc/wlan_hdd_trace.h

@@ -108,7 +108,8 @@
 	ENUM(TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN) \
 	ENUM(TRACE_CODE_HDD_CFG80211_SET_MAC_ACL) \
 	ENUM(TRACE_CODE_HDD_CFG80211_TESTMODE) \
-	ENUM(TRACE_CODE_HDD_CFG80211_DUMP_SURVEY)
+	ENUM(TRACE_CODE_HDD_CFG80211_DUMP_SURVEY) \
+	ENUM(TRACE_CODE_HDD_RX_SME_MSG)
 
 enum {
 #undef ENUM

+ 0 - 17
core/hdd/inc/wlan_hdd_tx_rx.h

@@ -42,25 +42,10 @@
 
 #define HDD_ETHERTYPE_802_1_X              0x888E
 #define HDD_ETHERTYPE_802_1_X_FRAME_OFFSET 12
-#define HDD_ETHERTYPE_802_1_X_SIZE         2
 #ifdef FEATURE_WLAN_WAPI
 #define HDD_ETHERTYPE_WAI                  0x88b4
 #endif
 
-#define HDD_80211_HEADER_LEN      24
-#define HDD_80211_HEADER_QOS_CTL  2
-#define HDD_LLC_HDR_LEN           6
-#define HDD_FRAME_TYPE_MASK       0x0c
-#define HDD_FRAME_SUBTYPE_MASK    0xf0
-#define HDD_FRAME_TYPE_DATA       0x08
-#define HDD_FRAME_TYPE_MGMT       0x00
-#define HDD_FRAME_SUBTYPE_QOSDATA 0x80
-#define HDD_FRAME_SUBTYPE_DEAUTH  0xC0
-#define HDD_FRAME_SUBTYPE_DISASSOC 0xA0
-#define HDD_DEST_ADDR_OFFSET      6
-
-#define HDD_MAC_HDR_SIZE          6
-
 #define HDD_PSB_CFG_INVALID                   0xFF
 #define HDD_PSB_CHANGED                       0xFF
 #define SME_QOS_UAPSD_CFG_BK_CHANGED_MASK     0xF1
@@ -68,8 +53,6 @@
 #define SME_QOS_UAPSD_CFG_VI_CHANGED_MASK     0xF4
 #define SME_QOS_UAPSD_CFG_VO_CHANGED_MASK     0xF8
 
-#define HDD_ETH_HEADER_LEN     14
-
 int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
 void hdd_tx_timeout(struct net_device *dev);
 CDF_STATUS hdd_init_tx_rx(hdd_adapter_t *pAdapter);

+ 1 - 7
core/hdd/inc/wlan_hdd_wext.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -143,12 +143,6 @@ typedef enum {
 /** Maximum Length of WPA/RSN IE */
 #define MAX_WPA_RSN_IE_LEN 40
 
-/** Maximum Number of WEP KEYS */
-#define MAX_WEP_KEYS 4
-
-/** Ether Address Length */
-#define ETHER_ADDR_LEN 6
-
 /** Enable 11d */
 #define ENABLE_11D  1
 

+ 153 - 174
core/hdd/src/wlan_hdd_assoc.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -36,6 +36,7 @@
 #include <ani_global.h>
 #include "dot11f.h"
 #include "wlan_hdd_power.h"
+#include "wlan_hdd_trace.h"
 #include <linux/ieee80211.h>
 #include <linux/wireless.h>
 #include <linux/etherdevice.h>
@@ -729,8 +730,9 @@ static void hdd_send_association_event(struct net_device *dev,
 			return;
 		}
 
-		cds_incr_active_session(pHddCtx, pAdapter->device_mode,
-						pAdapter->sessionId);
+		if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
+			cds_incr_active_session(pAdapter->device_mode,
+					pAdapter->sessionId);
 		memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
 		       sizeof(pCsrRoamInfo->pBssDesc->bssId));
 
@@ -814,8 +816,7 @@ static void hdd_send_association_event(struct net_device *dev,
 #endif
 	} else if (eConnectionState_IbssConnected ==    /* IBss Associated */
 			pHddStaCtx->conn_info.connState) {
-		cds_incr_active_session(pHddCtx, pAdapter->device_mode,
-						pAdapter->sessionId);
+		cds_update_connection_info(pAdapter->sessionId);
 		memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId.bytes,
 		       ETH_ALEN);
 		pr_info("wlan: new IBSS connection to " MAC_ADDRESS_STR "\n",
@@ -825,11 +826,9 @@ static void hdd_send_association_event(struct net_device *dev,
 		pr_info("wlan: disconnected\n");
 		memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
 		cds_decr_session_set_pcl(
-						pHddCtx, pAdapter->device_mode,
+						pAdapter->device_mode,
 						pAdapter->sessionId);
-#if defined(FEATURE_WLAN_LFR)
 		wlan_hdd_enable_roaming(pAdapter);
-#endif
 
 #ifdef FEATURE_WLAN_AUTO_SHUTDOWN
 		wlan_hdd_auto_shutdown_enable(pHddCtx, true);
@@ -871,15 +870,14 @@ static void hdd_send_association_event(struct net_device *dev,
 		hdd_stop_bus_bw_compute_timer(pAdapter);
 #endif
 	}
-	cds_dump_concurrency_info(pHddCtx);
+	cds_dump_concurrency_info();
 	/* Send SCC/MCC Switching event to IPA */
 	hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
 
 	msg = NULL;
 	/*During the WLAN uninitialization,supplicant is stopped before the
 	   driver so not sending the status of the connection to supplicant */
-	if ((pHddCtx->isLoadInProgress != true) &&
-	    (pHddCtx->isUnloadInProgress != true)) {
+	if (cds_is_load_or_unload_in_progress()) {
 		wireless_send_event(dev, we_event, &wrqu, msg);
 #ifdef FEATURE_WLAN_ESE
 		if (eConnectionState_Associated ==
@@ -1046,15 +1044,19 @@ static CDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
 			 * To avoid wpa_supplicant sending "HANGED" CMD
 			 * to ICS UI.
 			 */
-			if (eCSR_ROAM_LOSTLINK == roamStatus)
+			if (eCSR_ROAM_LOSTLINK == roamStatus) {
+				if (pRoamInfo->reasonCode ==
+				    eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON)
+					pr_info("wlan: disconnected due to poor signal, rssi is %d dB\n", pRoamInfo->rxRssi);
 				cfg80211_disconnected(dev, pRoamInfo->
 						      reasonCode, NULL,
 						      0, GFP_KERNEL);
-			else
+			} else {
 				cfg80211_disconnected(dev,
 					      WLAN_REASON_UNSPECIFIED,
 					      NULL, 0,
 					      GFP_KERNEL);
+			}
 
 			hdd_info("sent disconnected event to nl80211, rssi: %d",
 				pAdapter->rssi);
@@ -1064,8 +1066,7 @@ static CDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
 		 * before the driver so not sending the status of the
 		 * connection to supplicant.
 		 */
-		if ((pHddCtx->isLoadInProgress != true) &&
-		    (pHddCtx->isUnloadInProgress != true)) {
+		if (cds_is_load_or_unload_in_progress()) {
 #ifdef WLAN_FEATURE_P2P_DEBUG
 			if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
 				if (global_p2p_connection_status ==
@@ -1093,12 +1094,11 @@ static CDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
 #endif
 	if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
 		uint8_t i;
-		sta_id = IBSS_BROADCAST_STAID;
+		sta_id = pHddStaCtx->broadcast_ibss_staid;
 		vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
 		if (!CDF_IS_STATUS_SUCCESS(vstatus)) {
-			hddLog(LOGE,
-				FL("hdd_roam_deregister_sta() failed for staID %d Status=%d [0x%x]"),
-				sta_id, status, status);
+			hdd_err("hdd_roam_deregister_sta() failed for staID %d Status=%d [0x%x]",
+					sta_id, status, status);
 			status = CDF_STATUS_E_FAILURE;
 		}
 		pHddCtx->sta_to_adapter[sta_id] = NULL;
@@ -1364,6 +1364,7 @@ static void hdd_send_re_assoc_event(struct net_device *dev,
 	unsigned int len = 0;
 	u8 *pFTAssocRsp = NULL;
 	uint8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
+	uint8_t *assoc_req_ies = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
 	uint32_t rspRsnLength = 0;
 	struct ieee80211_channel *chan;
 	hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
@@ -1376,9 +1377,13 @@ static void hdd_send_re_assoc_event(struct net_device *dev,
 
 	if (!rspRsnIe) {
 		hddLog(LOGE, FL("Unable to allocate RSN IE"));
-		return;
+		goto done;
 	}
 
+	if (!assoc_req_ies) {
+		hdd_err("Unable to allocate Assoc Req IE");
+		goto done;
+	}
 	if (pCsrRoamInfo == NULL) {
 		hddLog(LOGE, FL("Invalid CSR roam info"));
 		goto done;
@@ -1409,9 +1414,10 @@ static void hdd_send_re_assoc_event(struct net_device *dev,
 	 * active session count should still be the same and hence upon
 	 * successful reassoc decrement the active session count here.
 	 */
-	cds_decr_session_set_pcl(
-					pHddCtx, pAdapter->device_mode,
-					pAdapter->sessionId);
+	if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
+		cds_decr_session_set_pcl(
+				pAdapter->device_mode,
+				pAdapter->sessionId);
 
 	/* Send the Assoc Resp, the supplicant needs this for initial Auth */
 	len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
@@ -1439,8 +1445,9 @@ static void hdd_send_re_assoc_event(struct net_device *dev,
 	cdf_mem_copy(buf_ptr, &roam_profile.SSID.ssId[0],
 			roam_profile.SSID.length);
 	ssid_ie_len = 2 + roam_profile.SSID.length;
-	hddLog(LOG2, FL("SSIDIE:"));
-	hddLog(CDF_TRACE_LEVEL_DEBUG, buf_ssid_ie, ssid_ie_len);
+	hdd_notice("SSIDIE:");
+	CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_DEBUG,
+			   buf_ssid_ie, ssid_ie_len);
 	final_req_ie = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
 	if (final_req_ie == NULL)
 		goto done;
@@ -1451,37 +1458,46 @@ static void hdd_send_re_assoc_event(struct net_device *dev,
 	cdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
 	cdf_mem_zero(final_req_ie + (ssid_ie_len + reqRsnLength),
 		IW_GENERIC_IE_MAX - (ssid_ie_len + reqRsnLength));
-	hddLog(LOG2, FL("Req RSN IE:"));
-	hddLog(CDF_TRACE_LEVEL_DEBUG, final_req_ie,
-		(ssid_ie_len + reqRsnLength));
+	hdd_notice("Req RSN IE:");
+	CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_DEBUG,
+			   final_req_ie, (ssid_ie_len + reqRsnLength));
 	cfg80211_roamed_bss(dev, bss,
 			final_req_ie, (ssid_ie_len + reqRsnLength),
 			rspRsnIe, rspRsnLength, GFP_KERNEL);
 
+	cdf_mem_copy(assoc_req_ies,
+		(u8 *)pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength,
+		pCsrRoamInfo->nAssocReqLength);
+
+	hdd_notice("ReAssoc Req IE dump");
+	CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_DEBUG,
+		assoc_req_ies, pCsrRoamInfo->nAssocReqLength);
+
 	wlan_hdd_send_roam_auth_event(pHddCtx, pCsrRoamInfo->bssid.bytes,
-			reqRsnIe, reqRsnLength, rspRsnIe, rspRsnLength,
+			assoc_req_ies, pCsrRoamInfo->nAssocReqLength,
+			rspRsnIe, rspRsnLength,
 			pCsrRoamInfo);
 done:
-	sme_roam_free_connect_profile(hal_handle, &roam_profile);
+	sme_roam_free_connect_profile(&roam_profile);
 	if (final_req_ie)
 		kfree(final_req_ie);
 	kfree(rspRsnIe);
+	kfree(assoc_req_ies);
 }
 
 /**
  * hdd_is_roam_sync_in_progress()- Check if roam offloaded
+ * @roaminfo - Roaming Information
  *
  * Return: roam sync status if roaming offloaded else false
  */
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
-static inline bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
-{
-	return roaminfo->roamSynchInProgress;
-}
-#else
-static inline bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
+bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
 {
-	return false;
+	if (roaminfo)
+		return roaminfo->roamSynchInProgress;
+	else
+		return false;
 }
 #endif
 
@@ -1697,10 +1713,7 @@ static CDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
 	CDF_STATUS cdf_status = CDF_STATUS_E_FAILURE;
 	uint8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
 	uint32_t reqRsnLength = DOT11F_IE_RSN_MAX_LEN;
-#if  defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) || \
-defined(WLAN_FEATURE_VOWIFI_11R)
 	int ft_carrier_on = false;
-#endif
 	bool hddDisconInProgress = false;
 	unsigned long rc;
 
@@ -1709,13 +1722,6 @@ defined(WLAN_FEATURE_VOWIFI_11R)
 		return CDF_STATUS_E_FAILURE;
 	}
 
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-	if (pRoamInfo && pRoamInfo->roamSynchInProgress) {
-		/* change logging before release */
-		hddLog(LOG3, "LFR3:hdd_association_completion_handler");
-	}
-#endif
-
 	/* HDD has initiated disconnect, do not send connect result indication
 	 * to kernel as it will be handled by __cfg80211_disconnect.
 	 */
@@ -1753,7 +1759,7 @@ defined(WLAN_FEATURE_VOWIFI_11R)
 		/* Indicate 'connect' status to user space */
 		hdd_send_association_event(dev, pRoamInfo);
 
-		if (cds_is_mcc_in_24G(pHddCtx)) {
+		if (cds_is_mcc_in_24G()) {
 			if (pHddCtx->miracast_value)
 				cds_set_mas(pAdapter, pHddCtx->miracast_value);
 		}
@@ -1770,49 +1776,38 @@ defined(WLAN_FEATURE_VOWIFI_11R)
 		 * will come to know that the device is getting
 		 * activated properly.
 		 */
-#if  defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
-defined(FEATURE_WLAN_LFR)
 		if (pHddStaCtx->ft_carrier_on == false) {
-#endif
-		/*
-		 * Enable Linkup Event Servicing which allows the net device
-		 * notifier to set the linkup event variable.
-		 */
-		pAdapter->isLinkUpSvcNeeded = true;
-
-		/*
-		 * Enable Linkup Event Servicing which allows the net device
-		 * notifier to set the linkup event variable.
-		 */
-		pAdapter->isLinkUpSvcNeeded = true;
+			/*
+			 * Enable Linkup Event Servicing which allows the net
+			 * device notifier to set the linkup event variable.
+			 */
+			pAdapter->isLinkUpSvcNeeded = true;
 
-		/* Switch on the Carrier to activate the device */
-		wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_CARRIER_ON,
-					   WLAN_CONTROL_PATH);
+			/* Switch on the Carrier to activate the device */
+			wlan_hdd_netif_queue_control(pAdapter,
+						WLAN_NETIF_CARRIER_ON,
+						WLAN_CONTROL_PATH);
 
-		/*
-		 * Wait for the Link to up to ensure all the queues are set
-		 * properly by the kernel.
-		 */
-		rc = wait_for_completion_timeout(&pAdapter->
-						 linkup_event_var,
-						 msecs_to_jiffies
-						 (ASSOC_LINKUP_TIMEOUT));
-		if (!rc)
-			hddLog(LOGW, FL("Warning:ASSOC_LINKUP_TIMEOUT"));
+			/*
+			 * Wait for the Link to up to ensure all the queues
+			 * are set properly by the kernel.
+			 */
+			rc = wait_for_completion_timeout(
+					&pAdapter->linkup_event_var,
+					msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)
+					);
+			if (!rc)
+				hdd_warn("Warning:ASSOC_LINKUP_TIMEOUT");
 
-		/*
-		 * Disable Linkup Event Servicing - no more service required
-		 * from the net device notifier call.
-		 */
-		pAdapter->isLinkUpSvcNeeded = false;
-#if  defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
-defined(FEATURE_WLAN_LFR)
-	} else {
-		pHddStaCtx->ft_carrier_on = false;
-		ft_carrier_on = true;
-	}
-#endif
+			/*
+			 * Disable Linkup Event Servicing - no more service
+			 * required from the net device notifier call.
+			 */
+			pAdapter->isLinkUpSvcNeeded = false;
+		} else {
+			pHddStaCtx->ft_carrier_on = false;
+			ft_carrier_on = true;
+		}
 		if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId)
 			pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
 		else
@@ -1830,8 +1825,7 @@ defined(FEATURE_WLAN_LFR)
 		wlan_hdd_auto_shutdown_enable(pHddCtx, false);
 #endif
 
-		cds_check_concurrent_intf_and_restart_sap(pHddCtx,
-							  pHddStaCtx,
+		cds_check_concurrent_intf_and_restart_sap(pHddStaCtx,
 							  pAdapter);
 
 #ifdef FEATURE_WLAN_TDLS
@@ -1947,10 +1941,11 @@ defined(FEATURE_WLAN_LFR)
 						 * decrement the active session
 						 * count here.
 						 */
-						cds_decr_session_set_pcl
-							(pHddCtx,
-							pAdapter->device_mode,
-							pAdapter->sessionId);
+						if (!hdd_is_roam_sync_in_progress
+								(pRoamInfo))
+							cds_decr_session_set_pcl
+								(pAdapter->device_mode,
+								 pAdapter->sessionId);
 						hddLog(LOG1,
 						       FL("ft_carrier_on is %d, sending roamed indication"),
 						       ft_carrier_on);
@@ -1963,6 +1958,15 @@ defined(FEATURE_WLAN_LFR)
 						       "assocReqlen %d assocRsplen %d",
 						       assocReqlen,
 						       assocRsplen);
+
+						hdd_notice(
+							"Reassoc Req IE dump");
+						CDF_TRACE_HEX_DUMP(
+							CDF_MODULE_ID_HDD,
+							CDF_TRACE_LEVEL_DEBUG,
+							pFTAssocReq,
+							assocReqlen);
+
 						cfg80211_roamed(dev, chan,
 								pRoamInfo->
 								bssid.bytes,
@@ -2039,17 +2043,13 @@ defined(FEATURE_WLAN_LFR)
 							    &rspRsnLength,
 							    rspRsnIe);
 				if (!hddDisconInProgress) {
-#if  defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 					if (ft_carrier_on)
 						hdd_send_re_assoc_event(dev,
 									pAdapter,
 									pRoamInfo,
 									reqRsnIe,
 									reqRsnLength);
-					else
-#endif /* FEATURE_WLAN_ESE */
-
-					{
+					else {
 						hddLog(LOG1,
 						       FL("sending connect indication to nl80211:for bssid "
 						       MAC_ADDRESS_STR
@@ -2073,9 +2073,7 @@ defined(FEATURE_WLAN_LFR)
 			}
 			if (!hddDisconInProgress) {
 				cfg80211_put_bss(
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
 					pHddCtx->wiphy,
-#endif
 					bss);
 
 				/*
@@ -2309,11 +2307,17 @@ defined(FEATURE_WLAN_LFR)
 					   WLAN_CONTROL_PATH);
 	}
 
-	if (CDF_STATUS_SUCCESS != cds_check_and_restart_sap(pHddCtx,
+	if (CDF_STATUS_SUCCESS != cds_check_and_restart_sap(
 					roamResult, pHddStaCtx))
 		return CDF_STATUS_E_FAILURE;
 
-	cds_force_sap_on_scc(pHddCtx, roamResult);
+	if (NULL != pRoamInfo && NULL != pRoamInfo->pBssDesc) {
+		cds_force_sap_on_scc(roamResult,
+				pRoamInfo->pBssDesc->channelId);
+	} else {
+		hdd_err("pRoamInfo profile is not set properly");
+		return CDF_STATUS_E_FAILURE;
+	}
 
 	return CDF_STATUS_SUCCESS;
 }
@@ -2348,6 +2352,8 @@ static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
 	{
 		hdd_context_t *pHddCtx =
 			(hdd_context_t *) pAdapter->pHddCtx;
+		hdd_station_ctx_t *hdd_sta_ctx =
+			WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
 		struct cdf_mac_addr broadcastMacAddr =
 			CDF_MAC_ADDR_BROADCAST_INITIALIZER;
 
@@ -2367,10 +2373,13 @@ static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
 		/* notify wmm */
 		hdd_wmm_connect(pAdapter, pRoamInfo,
 				eCSR_BSS_TYPE_IBSS);
-		pHddCtx->sta_to_adapter[IBSS_BROADCAST_STAID] =
+
+		hdd_sta_ctx->broadcast_ibss_staid = pRoamInfo->staId;
+
+		pHddCtx->sta_to_adapter[pRoamInfo->staId] =
 			pAdapter;
 		hdd_roam_register_sta(pAdapter, pRoamInfo,
-				      IBSS_BROADCAST_STAID,
+				      pRoamInfo->staId,
 				      &broadcastMacAddr,
 				      pRoamInfo->pBssDesc);
 
@@ -2426,12 +2435,16 @@ static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
 					     GFP_KERNEL);
 #endif
 			cfg80211_put_bss(
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
 				pHddCtx->wiphy,
-#endif
 				bss);
 		}
-
+		if (eCSR_ROAM_RESULT_IBSS_STARTED == roamResult) {
+			cds_incr_active_session(pAdapter->device_mode,
+					pAdapter->sessionId);
+		} else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roamResult ||
+				eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) {
+			cds_update_connection_info(pAdapter->sessionId);
+		}
 		break;
 	}
 
@@ -2589,9 +2602,7 @@ static CDF_STATUS roam_ibss_connect_handler(hdd_adapter_t *pAdapter,
 		return CDF_STATUS_E_FAILURE;
 	}
 	cfg80211_put_bss(
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
 		WLAN_HDD_GET_CTX(pAdapter)->wiphy,
-#endif
 		bss);
 
 	return CDF_STATUS_SUCCESS;
@@ -2704,9 +2715,6 @@ roam_roam_connect_status_update_handler(hdd_adapter_t *pAdapter,
 
 		pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
 
-		pHddCtx->sta_to_adapter[IBSS_BROADCAST_STAID] =
-			pAdapter;
-
 		/* Register the Station with TL for the new peer. */
 		cdf_status = hdd_roam_register_sta(pAdapter,
 						   pRoamInfo,
@@ -3812,6 +3820,27 @@ hdd_indicate_ese_bcn_report_ind(const hdd_adapter_t *pAdapter,
 
 #endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
 
+/**
+ * hdd_is_8021x_sha256_auth_type() - check authentication type to 8021x_sha256
+ * @pHddStaCtx:	Station Context
+ *
+ * API to check if the connection authentication type is 8021x_sha256.
+ *
+ * Return: bool
+ */
+#ifdef WLAN_FEATURE_11W
+static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
+{
+	return eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
+				pHddStaCtx->conn_info.authType;
+}
+#else
+static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
+{
+	return false;
+}
+#endif
+
 /**
  * hdd_sme_roam_callback() - hdd sme roam callback
  * @pContext: pointer to adapter context
@@ -3846,14 +3875,15 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
 	pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
 	pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
 
+	MTRACE(cdf_trace(CDF_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG,
+				pAdapter->sessionId, roamStatus));
+
 	switch (roamStatus) {
 	case eCSR_ROAM_SESSION_OPENED:
 		set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
 		complete(&pAdapter->session_open_comp_var);
 		break;
 
-#if  defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
-defined(FEATURE_WLAN_LFR)
 	/*
 	 * We did pre-auth,then we attempted a 11r or ese reassoc.
 	 * reassoc failed due to failure, timeout, reject from ap
@@ -3894,72 +3924,32 @@ defined(FEATURE_WLAN_LFR)
 		 * doing disassoc at this time. This saves 30-60 msec
 		 * after reassoc.
 		 */
-	{
 		hddLog(LOG1, FL("Disabling queues"));
-		wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE,
-					   WLAN_CONTROL_PATH);
-		status =
-			hdd_roam_deregister_sta(pAdapter,
-						pHddStaCtx->conn_info.
-						staId[0]);
-		if (!CDF_IS_STATUS_SUCCESS(status)) {
-			hddLog(LOGW,
-				FL
-				("hdd_roam_deregister_sta() failed to for staID %d. Status=%d [0x%x]"),
-				pHddStaCtx->conn_info.staId[0],
-				status, status);
+		wlan_hdd_netif_queue_control(pAdapter,
+				WLAN_NETIF_TX_DISABLE,
+				WLAN_CONTROL_PATH);
+		status = hdd_roam_deregister_sta(pAdapter,
+					pHddStaCtx->conn_info.staId[0]);
+		if (!CDF_IS_STATUS_SUCCESS(status))
 			cdf_ret_status = CDF_STATUS_E_FAILURE;
-		}
-	}
 		pHddStaCtx->ft_carrier_on = true;
 		pHddStaCtx->hdd_ReassocScenario = true;
 		hddLog(LOG1,
 		       FL("hdd_ReassocScenario set to: %d, due to eCSR_ROAM_FT_START, session: %d"),
 		       pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
 		break;
-#endif
 
 	case eCSR_ROAM_SHOULD_ROAM:
-		/* Dont need to do anything */
-	{
-		hdd_station_ctx_t *pHddStaCtx =
-			WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
 		/* notify apps that we can't pass traffic anymore */
 		hddLog(LOG1, FL("Disabling queues"));
 		wlan_hdd_netif_queue_control(pAdapter,
 					   WLAN_NETIF_TX_DISABLE,
 					   WLAN_CONTROL_PATH);
-#if  defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
-defined(FEATURE_WLAN_LFR)
 		if (pHddStaCtx->ft_carrier_on == false) {
-#endif
 			wlan_hdd_netif_queue_control(pAdapter,
 					   WLAN_NETIF_CARRIER_OFF,
 					   WLAN_CONTROL_PATH);
-#if  defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
-defined(FEATURE_WLAN_LFR)
-	}
-#endif
-
-#if  !(defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
-defined(FEATURE_WLAN_LFR))
-		/*
-		 * We should clear all sta register with TL, for now, only one.
-		 */
-		status =
-			hdd_roam_deregister_sta(pAdapter,
-						pHddStaCtx->conn_info.
-						staId[0]);
-		if (!CDF_IS_STATUS_SUCCESS(status)) {
-			hddLog(LOGW,
-				FL
-				("hdd_roam_deregister_sta() failed to for staID %d. Status=%d [0x%x]"),
-				pHddStaCtx->conn_info.staId[0],
-				status, status);
-			cdf_ret_status = CDF_STATUS_E_FAILURE;
 		}
-#endif
-	}
 		break;
 	case eCSR_ROAM_LOSTLINK:
 		if (roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
@@ -4086,18 +4076,15 @@ defined(FEATURE_WLAN_LFR))
 		hdd_send_ft_event(pAdapter);
 		break;
 #endif
-#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
 	case eCSR_ROAM_PMK_NOTIFY:
-		if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType ||
-			eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
-					pHddStaCtx->conn_info.authType) {
+		if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType
+				|| hdd_is_8021x_sha256_auth_type(pHddStaCtx)) {
 			/* notify the supplicant of a new candidate */
 			cdf_ret_status =
 				wlan_hdd_cfg80211_pmksa_candidate_notify(
 						pAdapter, pRoamInfo, 1, false);
 		}
 		break;
-#endif
 
 #ifdef FEATURE_WLAN_LFR_METRICS
 	case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
@@ -4138,14 +4125,6 @@ defined(FEATURE_WLAN_LFR))
 		}
 		break;
 #endif
-
-	case eCSR_ROAM_INDICATE_MGMT_FRAME:
-		hdd_indicate_mgmt_frame(pAdapter,
-					pRoamInfo->nFrameLength,
-					pRoamInfo->pbFrames,
-					pRoamInfo->frameType,
-					pRoamInfo->rxChan, pRoamInfo->rxRssi);
-		break;
 	case eCSR_ROAM_REMAIN_CHAN_READY:
 		hdd_remain_chan_ready_handler(pAdapter, pRoamInfo->roc_scan_id);
 		break;
@@ -4426,7 +4405,7 @@ static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
 			 * in the bssid.
 			 */
 			cdf_mem_copy(PMKIDCache[i].BSSID.bytes,
-				     bssid, ETHER_ADDR_LEN);
+				     bssid, CDF_MAC_ADDR_SIZE);
 			cdf_mem_copy(PMKIDCache[i].PMKID,
 				     dot11RSNIE.pmkid[i], CSR_RSN_PMKID_SIZE);
 		}

+ 139 - 73
core/hdd/src/wlan_hdd_cfg.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -45,7 +45,6 @@
 #include <wlan_hdd_misc.h>
 #include <wlan_hdd_napi.h>
 
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 static void
 cb_notify_set_roam_prefer5_g_hz(hdd_context_t *pHddCtx, unsigned long notifyId)
 {
@@ -95,7 +94,6 @@ cb_notify_set_roam_scan_home_away_time(hdd_context_t *pHddCtx, unsigned long not
 					    pHddCtx->config->nRoamScanHomeAwayTime,
 					    true);
 }
-#endif
 
 #ifdef FEATURE_WLAN_OKC
 static void
@@ -106,7 +104,6 @@ cb_notify_set_okc_feature_enabled(hdd_context_t *pHddCtx, unsigned long notifyId
 }
 #endif
 
-#ifdef FEATURE_WLAN_LFR
 static void
 notify_is_fast_roam_ini_feature_enabled(hdd_context_t *pHddCtx,
 					unsigned long notifyId)
@@ -126,7 +123,6 @@ notify_is_mawc_ini_feature_enabled(hdd_context_t *pHddCtx, unsigned long notifyI
 	sme_update_is_mawc_ini_feature_enabled(pHddCtx->hHal,
 					       pHddCtx->config->MAWCEnabled);
 }
-#endif
 
 #ifdef FEATURE_WLAN_ESE
 static void
@@ -149,7 +145,6 @@ cb_notify_set_fw_rssi_monitoring(hdd_context_t *pHddCtx, unsigned long notifyId)
 					     fEnableFwRssiMonitoring);
 }
 
-#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
 static void cb_notify_set_opportunistic_scan_threshold_diff(hdd_context_t *pHddCtx,
 							    unsigned long notifyId)
 {
@@ -275,8 +270,6 @@ cb_notify_set_dfs_scan_mode(hdd_context_t *pHddCtx, unsigned long notifyId)
 				 pHddCtx->config->allowDFSChannelRoam);
 }
 
-#endif
-
 static void cb_notify_set_enable_ssr(hdd_context_t *pHddCtx,
 				     unsigned long notifyId)
 {
@@ -430,13 +423,6 @@ REG_TABLE_ENTRY g_registry_table[] = {
 			    VAR_FLAGS_OPTIONAL,
 			    (void *)CFG_POWER_USAGE_DEFAULT),
 
-	REG_VARIABLE(CFG_ENABLE_LOGP_NAME, WLAN_PARAM_Integer,
-		     struct hdd_config, fIsLogpEnabled,
-		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
-		     CFG_ENABLE_LOGP_DEFAULT,
-		     CFG_ENABLE_LOGP_MIN,
-		     CFG_ENABLE_LOGP_MAX),
-
 	REG_VARIABLE(CFG_ENABLE_IMPS_NAME, WLAN_PARAM_Integer,
 		     struct hdd_config, fIsImpsEnabled,
 		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -500,6 +486,13 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		     CFG_MAX_RX_AMPDU_FACTOR_MIN,
 		     CFG_MAX_RX_AMPDU_FACTOR_MAX),
 
+	REG_VARIABLE(CFG_HT_MPDU_DENSITY_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, ht_mpdu_density,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK ,
+		     CFG_HT_MPDU_DENSITY_DEFAULT,
+		     CFG_HT_MPDU_DENSITY_MIN,
+		     CFG_HT_MPDU_DENSITY_MAX),
+
 	REG_VARIABLE(CFG_FIXED_RATE_NAME, WLAN_PARAM_Integer,
 		     struct hdd_config, TxRate,
 		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
@@ -1021,7 +1014,6 @@ REG_TABLE_ENTRY g_registry_table[] = {
 			     cb_notify_set_ese_feature_enabled, 0),
 #endif /* FEATURE_WLAN_ESE */
 
-#ifdef FEATURE_WLAN_LFR
 	/* flag to turn ON/OFF Legacy Fast Roaming */
 	REG_DYNAMIC_VARIABLE(CFG_LFR_FEATURE_ENABLED_NAME, WLAN_PARAM_Integer,
 			     struct hdd_config, isFastRoamIniFeatureEnabled,
@@ -1043,9 +1035,6 @@ REG_TABLE_ENTRY g_registry_table[] = {
 			     CFG_LFR_MAWC_FEATURE_ENABLED_MAX,
 			     notify_is_mawc_ini_feature_enabled, 0),
 
-#endif /* FEATURE_WLAN_LFR */
-
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 	/* flag to turn ON/OFF 11r and ESE FastTransition */
 	REG_DYNAMIC_VARIABLE(CFG_FAST_TRANSITION_ENABLED_NAME,
 			     WLAN_PARAM_Integer,
@@ -1076,7 +1065,6 @@ REG_TABLE_ENTRY g_registry_table[] = {
 			     CFG_ENABLE_WES_MODE_NAME_MIN,
 			     CFG_ENABLE_WES_MODE_NAME_MAX,
 			     cb_notify_set_wes_mode, 0),
-#endif
 #ifdef FEATURE_WLAN_OKC
 	REG_DYNAMIC_VARIABLE(CFG_OKC_FEATURE_ENABLED_NAME, WLAN_PARAM_Integer,
 			     struct hdd_config, isOkcIniFeatureEnabled,
@@ -1343,7 +1331,6 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		     CFG_FT_RESOURCE_REQ_MAX),
 #endif
 
-#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
 	REG_DYNAMIC_VARIABLE(CFG_NEIGHBOR_SCAN_TIMER_PERIOD_NAME,
 			     WLAN_PARAM_Integer,
 			     struct hdd_config, nNeighborScanPeriod,
@@ -1532,8 +1519,6 @@ REG_TABLE_ENTRY g_registry_table[] = {
 			     cb_notify_set_roam_scan_hi_rssi_scan_params,
 			     eCSR_HI_RSSI_SCAN_RSSI_UB_ID),
 
-#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
-
 	REG_VARIABLE(CFG_QOS_WMM_BURST_SIZE_DEFN_NAME, WLAN_PARAM_Integer,
 		     struct hdd_config, burstSizeDefinition,
 		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -1926,7 +1911,6 @@ REG_TABLE_ENTRY g_registry_table[] = {
 			     CFG_LINK_SPEED_RSSI_LOW_MAX,
 			     NULL, 0),
 
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 	REG_DYNAMIC_VARIABLE(CFG_ROAM_PREFER_5GHZ, WLAN_PARAM_Integer,
 			     struct hdd_config, nRoamPrefer5GHz,
 			     VAR_FLAGS_OPTIONAL |
@@ -1963,8 +1947,6 @@ REG_TABLE_ENTRY g_registry_table[] = {
 			     CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX,
 			     cb_notify_set_roam_scan_home_away_time, 0),
 
-#endif
-
 	REG_VARIABLE(CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_NAME,
 		     WLAN_PARAM_Integer,
 		     struct hdd_config, isP2pDeviceAddrAdministrated,
@@ -2232,6 +2214,13 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		     CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN,
 		     CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX),
 
+	REG_VARIABLE(CFG_TDLS_IDLE_TIMEOUT, WLAN_PARAM_Integer,
+		     struct hdd_config, tdls_idle_timeout,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_TDLS_IDLE_TIMEOUT_DEFAULT,
+		     CFG_TDLS_IDLE_TIMEOUT_MIN,
+		     CFG_TDLS_IDLE_TIMEOUT_MAX),
+
 	REG_VARIABLE(CFG_TDLS_IDLE_PACKET_THRESHOLD, WLAN_PARAM_Integer,
 		     struct hdd_config, fTDLSIdlePacketThreshold,
 		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -2344,6 +2333,14 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		     CFG_TDLS_SCAN_ENABLE_DEFAULT,
 		     CFG_TDLS_SCAN_ENABLE_MIN,
 		     CFG_TDLS_SCAN_ENABLE_MAX),
+
+	REG_VARIABLE(CFG_TDLS_PEER_KICKOUT_THRESHOLD, WLAN_PARAM_Integer,
+		     struct hdd_config, tdls_peer_kickout_threshold,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_TDLS_PEER_KICKOUT_THRESHOLD_DEFAULT,
+		     CFG_TDLS_PEER_KICKOUT_THRESHOLD_MIN,
+		     CFG_TDLS_PEER_KICKOUT_THRESHOLD_MAX),
+
 #endif
 
 #ifdef WLAN_SOFTAP_VSTA_FEATURE
@@ -2418,6 +2415,13 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		     CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_MIN,
 		     CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_MAX),
 
+	REG_VARIABLE(CFG_VHT_ENABLE_TXBF_SAP_MODE, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_txbf_sap_mode,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_VHT_ENABLE_TXBF_SAP_MODE_DEFAULT,
+		     CFG_VHT_ENABLE_TXBF_SAP_MODE_MIN,
+		     CFG_VHT_ENABLE_TXBF_SAP_MODE_MAX),
+
 	REG_VARIABLE(CFG_VHT_ENABLE_TXBF_IN_20MHZ, WLAN_PARAM_Integer,
 		     struct hdd_config, enableTxBFin20MHz,
 		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -3093,6 +3097,30 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		     CFG_ENABLE_GREEN_AP_FEATURE_DEFAULT,
 		     CFG_ENABLE_GREEN_AP_FEATURE_MIN,
 		     CFG_ENABLE_GREEN_AP_FEATURE_MAX),
+	REG_VARIABLE(CFG_ENABLE_EGAP_ENABLE_FEATURE, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_egap,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_EGAP_ENABLE_FEATURE_DEFAULT,
+		     CFG_ENABLE_EGAP_ENABLE_FEATURE_MIN,
+		     CFG_ENABLE_EGAP_ENABLE_FEATURE_MAX),
+	REG_VARIABLE(CFG_ENABLE_EGAP_INACT_TIME_FEATURE, WLAN_PARAM_Integer,
+		     struct hdd_config, egap_inact_time,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_EGAP_INACT_TIME_FEATURE_DEFAULT,
+		     CFG_ENABLE_EGAP_INACT_TIME_FEATURE_MIN,
+		     CFG_ENABLE_EGAP_INACT_TIME_FEATURE_MAX),
+	REG_VARIABLE(CFG_ENABLE_EGAP_WAIT_TIME_FEATURE, WLAN_PARAM_Integer,
+		     struct hdd_config, egap_wait_time,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_EGAP_WAIT_TIME_FEATURE_DEFAULT,
+		     CFG_ENABLE_EGAP_WAIT_TIME_FEATURE_MIN,
+		     CFG_ENABLE_EGAP_WAIT_TIME_FEATURE_MAX),
+	REG_VARIABLE(CFG_ENABLE_EGAP_FLAGS_FEATURE, WLAN_PARAM_Integer,
+		     struct hdd_config, egap_feature_flag,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_EGAP_FLAGS_FEATURE_DEFAULT,
+		     CFG_ENABLE_EGAP_FLAGS_FEATURE_MIN,
+		     CFG_ENABLE_EGAP_FLAGS_FEATURE_MAX),
 #endif
 
 	REG_VARIABLE(CFG_IGNORE_CAC_NAME, WLAN_PARAM_Integer,
@@ -3618,6 +3646,31 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		     CFG_FIRST_SCAN_BUCKET_THRESHOLD_MIN,
 		     CFG_FIRST_SCAN_BUCKET_THRESHOLD_MAX),
 
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+	REG_VARIABLE(CFG_ENABLE_LFR_SUBNET_DETECTION, WLAN_PARAM_Integer,
+		     struct hdd_config, enable_lfr_subnet_detection,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ENABLE_LFR_SUBNET_DEFAULT,
+		     CFG_ENABLE_LFR_SUBNET_MIN,
+		     CFG_ENABLE_LFR_SUBNET_MAX),
+#endif
+
+	REG_VARIABLE(CFG_INFORM_BSS_RSSI_RAW_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, inform_bss_rssi_raw,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_INFORM_BSS_RSSI_RAW_DEFAULT,
+		CFG_INFORM_BSS_RSSI_RAW_MIN,
+		CFG_INFORM_BSS_RSSI_RAW_MAX),
+
+#ifdef QCA_WIFI_3_0_EMU
+	REG_VARIABLE(CFG_ENABLE_M2M_LIMITATION, WLAN_PARAM_Integer,
+		struct hdd_config, enable_m2m_limitation,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ENABLE_LFR_SUBNET_DEFAULT,
+		CFG_ENABLE_LFR_SUBNET_MIN,
+		CFG_ENABLE_LFR_SUBNET_MAX),
+#endif
+
 };
 
 
@@ -4581,22 +4634,18 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
 		  "Name = [gTxPowerCap] Value = [%u] dBm ",
 		  pHddCtx->config->nTxPowerCap);
 #endif
-#ifdef FEATURE_WLAN_LFR
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
 		  "Name = [FastRoamEnabled] Value = [%u] ",
 		  pHddCtx->config->isFastRoamIniFeatureEnabled);
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
 		  "Name = [MAWCEnabled] Value = [%u] ",
 		  pHddCtx->config->MAWCEnabled);
-#endif
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
 		  "Name = [RoamRssiDiff] Value = [%u] ",
 		  pHddCtx->config->RoamRssiDiff);
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
 		  "Name = [isWESModeEnabled] Value = [%u] ",
 		  pHddCtx->config->isWESModeEnabled);
-#endif
 #ifdef FEATURE_WLAN_OKC
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
 		  "Name = [OkcEnabled] Value = [%u] ",
@@ -4725,7 +4774,6 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
 		  pHddCtx->config->fFTResourceReqSupported);
 #endif
 
-#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
 		  "Name = [nNeighborLookupRssiThreshold] Value = [%u] ",
 		  pHddCtx->config->nNeighborLookupRssiThreshold);
@@ -4780,7 +4828,6 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
 		  "Name = [nhi_rssi_scan_rssi_ub] Value = [%u] ",
 		  pHddCtx->config->nhi_rssi_scan_rssi_ub);
-#endif
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
 		  "Name = [burstSizeDefinition] Value = [0x%x] ",
 		  pHddCtx->config->burstSizeDefinition);
@@ -5010,6 +5057,18 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
 		  "Name = [gEnableGreenAp] Value = [%u] ",
 		  pHddCtx->config->enableGreenAP);
+	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
+		  "Name = [gEenableEGAP] Value = [%u] ",
+		  pHddCtx->config->enable_egap);
+	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
+		  "Name = [gEGAPInactTime] Value = [%u] ",
+		  pHddCtx->config->egap_inact_time);
+	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
+		  "Name = [gEGAPWaitTime] Value = [%u] ",
+		  pHddCtx->config->egap_wait_time);
+	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
+		  "Name = [gEGAPFeatures] Value = [%u] ",
+		  pHddCtx->config->egap_feature_flag);
 #endif
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO_HIGH,
@@ -5167,6 +5226,16 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
 	hddLog(LOGE, "Name = [%s] Value = [%d]",
 		CFG_FIRST_SCAN_BUCKET_THRESHOLD_NAME,
 		pHddCtx->config->first_scan_bucket_threshold);
+	hddLog(LOGE, "Name = [%s] Value = [%u]",
+		CFG_HT_MPDU_DENSITY_NAME,
+		pHddCtx->config->ht_mpdu_density);
+
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+	hddLog(LOGE, "Name = [%s] Value = [%d]",
+		CFG_ENABLE_LFR_SUBNET_DETECTION,
+		pHddCtx->config->enable_lfr_subnet_detection);
+#endif
 }
 
 
@@ -5429,20 +5498,14 @@ eCsrPhyMode hdd_cfg_xlate_to_csr_phy_mode(eHddDot11Mode dot11Mode)
  */
 CDF_STATUS hdd_set_idle_ps_config(hdd_context_t *pHddCtx, uint32_t val)
 {
-	struct hdd_config *pConfig = pHddCtx->config;
 	CDF_STATUS status = CDF_STATUS_SUCCESS;
 
 	hddLog(LOG1, "hdd_set_idle_ps_config: Enter Val %d", val);
 
-	if (pConfig->fIsImpsEnabled) {
-		status = sme_set_idle_powersave_config(pHddCtx->pcds_context,
-						pHddCtx->hHal, val);
-		if (CDF_STATUS_SUCCESS != status) {
-			hddLog(LOGE, "Fail to Set Idle PS Config val %d", val);
-		}
-	} else {
-		hddLog(LOG1, "hdd_set_idle_ps_config: IMPS not enabled in ini");
-	}
+	status = sme_set_idle_powersave_config(pHddCtx->pcds_context,
+			pHddCtx->hHal, val);
+	if (CDF_STATUS_SUCCESS != status)
+		hddLog(LOGE, "Fail to Set Idle PS Config val %d", val);
 	return status;
 }
 
@@ -5465,10 +5528,11 @@ static void hdd_set_fine_time_meas_cap(hdd_context_t *hdd_ctx,
 
 	/* Make sure only supported capabilities are enabled in INI */
 	capability &= CFG_FINE_TIME_MEAS_CAPABILITY_MAX;
-	sme_config->fine_time_meas_cap = capability;
+	sme_config->csrConfig.fine_time_meas_cap = capability;
 
 	hddLog(LOG1, FL("fine time meas capability - INI: %04x Enabled: %04x"),
-		config->fine_time_meas_cap, sme_config->fine_time_meas_cap);
+		config->fine_time_meas_cap,
+		sme_config->csrConfig.fine_time_meas_cap);
 
 	return;
 }
@@ -5594,6 +5658,14 @@ bool hdd_update_config_dat(hdd_context_t *pHddCtx)
 		       "Could not pass on WNI_CFG_HT_AMPDU_PARAMS_MAX_RX_AMPDU_FACTOR to CFG");
 	}
 
+	if (sme_cfg_set_int(pHddCtx->hHal, WNI_CFG_MPDU_DENSITY,
+			    pConfig->ht_mpdu_density) ==
+			CDF_STATUS_E_FAILURE) {
+		fStatus = false;
+		hddLog(LOGE,
+		       "Could not pass on WNI_CFG_MPDU_DENSITY to CFG");
+	}
+
 	if (sme_cfg_set_int
 		    (pHddCtx->hHal, WNI_CFG_SHORT_PREAMBLE,
 		     pConfig->fIsShortPreamble) == CDF_STATUS_E_FAILURE) {
@@ -6283,14 +6355,15 @@ bool hdd_update_config_dat(hdd_context_t *pHddCtx)
 void hdd_set_pno_channel_prediction_config(
 		tpSmeConfigParams sme_config, hdd_context_t *hdd_ctx)
 {
-	sme_config->dual_mac_feature_disable =
+	sme_config->csrConfig.dual_mac_feature_disable =
 		hdd_ctx->config->dual_mac_feature_disable;
-	sme_config->pno_channel_prediction =
+	sme_config->csrConfig.pno_channel_prediction =
 		hdd_ctx->config->pno_channel_prediction;
-	sme_config->top_k_num_of_channels =
+	sme_config->csrConfig.top_k_num_of_channels =
 		hdd_ctx->config->top_k_num_of_channels;
-	sme_config->stationary_thresh = hdd_ctx->config->stationary_thresh;
-	sme_config->channel_prediction_full_scan =
+	sme_config->csrConfig.stationary_thresh =
+		hdd_ctx->config->stationary_thresh;
+	sme_config->csrConfig.channel_prediction_full_scan =
 		hdd_ctx->config->channel_prediction_full_scan;
 }
 #endif
@@ -6403,6 +6476,8 @@ CDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
 #ifdef WLAN_FEATURE_11AC
 	smeConfig->csrConfig.nVhtChannelWidth = pConfig->vhtChannelWidth;
 	smeConfig->csrConfig.enableTxBF = pConfig->enableTxBF;
+	smeConfig->csrConfig.enable_txbf_sap_mode =
+		pConfig->enable_txbf_sap_mode;
 	smeConfig->csrConfig.txBFCsnValue = pConfig->txBFCsnValue;
 	smeConfig->csrConfig.enable2x2 = pConfig->enable2x2;
 	smeConfig->csrConfig.enableVhtFor24GHz = pConfig->enableVhtFor24GHzBand;
@@ -6429,20 +6504,16 @@ CDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
 	smeConfig->csrConfig.nTxPowerCap = pConfig->nTxPowerCap;
 	smeConfig->csrConfig.fEnableBypass11d = pConfig->enableBypass11d;
 	smeConfig->csrConfig.fEnableDFSChnlScan = pConfig->enableDFSChnlScan;
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 	smeConfig->csrConfig.nRoamPrefer5GHz = pConfig->nRoamPrefer5GHz;
 	smeConfig->csrConfig.nRoamIntraBand = pConfig->nRoamIntraBand;
 	smeConfig->csrConfig.nProbes = pConfig->nProbes;
 
 	smeConfig->csrConfig.nRoamScanHomeAwayTime =
 		pConfig->nRoamScanHomeAwayTime;
-#endif
 	smeConfig->csrConfig.fFirstScanOnly2GChnl =
 		pConfig->enableFirstScan2GOnly;
 
-	/* FIXME 11d config is hardcoded */
-	if (CDF_SAP_MODE != hdd_get_conparam())
-		smeConfig->csrConfig.Csr11dinfo.Channels.numChannels = 0;
+	smeConfig->csrConfig.Csr11dinfo.Channels.numChannels = 0;
 
 	hdd_set_power_save_offload_config(pHddCtx);
 
@@ -6450,11 +6521,9 @@ CDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
 	smeConfig->csrConfig.csr11rConfig.IsFTResourceReqSupported =
 		pConfig->fFTResourceReqSupported;
 #endif
-#ifdef FEATURE_WLAN_LFR
 	smeConfig->csrConfig.isFastRoamIniFeatureEnabled =
 		pConfig->isFastRoamIniFeatureEnabled;
 	smeConfig->csrConfig.MAWCEnabled = pConfig->MAWCEnabled;
-#endif
 #ifdef FEATURE_WLAN_ESE
 	smeConfig->csrConfig.isEseIniFeatureEnabled =
 		pConfig->isEseIniFeatureEnabled;
@@ -6462,12 +6531,10 @@ CDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
 		pConfig->isFastTransitionEnabled = true;
 	}
 #endif
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 	smeConfig->csrConfig.isFastTransitionEnabled =
 		pConfig->isFastTransitionEnabled;
 	smeConfig->csrConfig.RoamRssiDiff = pConfig->RoamRssiDiff;
 	smeConfig->csrConfig.isWESModeEnabled = pConfig->isWESModeEnabled;
-#endif
 	smeConfig->csrConfig.isRoamOffloadScanEnabled =
 		pConfig->isRoamOffloadScanEnabled;
 	smeConfig->csrConfig.bFastRoamInConIniFeatureEnabled =
@@ -6477,7 +6544,6 @@ CDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
 		/* Disable roaming in concurrency if roam scan offload is disabled */
 		smeConfig->csrConfig.bFastRoamInConIniFeatureEnabled = 0;
 	}
-#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
 	smeConfig->csrConfig.neighborRoamConfig.nNeighborLookupRssiThreshold =
 		pConfig->nNeighborLookupRssiThreshold;
 	smeConfig->csrConfig.neighborRoamConfig.delay_before_vdev_stop =
@@ -6518,7 +6584,6 @@ CDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
 		pConfig->nhi_rssi_scan_delay;
 	smeConfig->csrConfig.neighborRoamConfig.nhi_rssi_scan_rssi_ub =
 		pConfig->nhi_rssi_scan_rssi_ub;
-#endif
 	smeConfig->csrConfig.addTSWhenACMIsOff = pConfig->AddTSWhenACMIsOff;
 	smeConfig->csrConfig.fValidateList = pConfig->fValidateScanList;
 	smeConfig->csrConfig.allowDFSChannelRoam = pConfig->allowDFSChannelRoam;
@@ -6553,17 +6618,18 @@ CDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
 
 #ifdef FEATURE_WLAN_SCAN_PNO
 	/* Update PNO offoad status */
-	smeConfig->pnoOffload = pHddCtx->config->PnoOffload;
+	smeConfig->csrConfig.pnoOffload = pHddCtx->config->PnoOffload;
 #endif
 
 	/* Update maximum interfaces information */
-	smeConfig->max_intf_count = pHddCtx->max_intf_count;
+	smeConfig->csrConfig.max_intf_count = pHddCtx->max_intf_count;
 
-	smeConfig->fEnableDebugLog = pHddCtx->config->gEnableDebugLog;
+	smeConfig->csrConfig.fEnableDebugLog = pHddCtx->config->gEnableDebugLog;
 
-	smeConfig->enable5gEBT = pHddCtx->config->enable5gEBT;
+	smeConfig->csrConfig.enable5gEBT = pHddCtx->config->enable5gEBT;
 
-	smeConfig->enableSelfRecovery = pHddCtx->config->enableSelfRecovery;
+	smeConfig->csrConfig.enableSelfRecovery =
+			pHddCtx->config->enableSelfRecovery;
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 	smeConfig->csrConfig.isRoamOffloadEnabled =
 		pHddCtx->config->isRoamOffloadEnabled;
@@ -6575,25 +6641,25 @@ CDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
 	smeConfig->csrConfig.is_sta_connection_in_5gz_enabled =
 		pHddCtx->config->is_sta_connection_in_5gz_enabled;
 
-	smeConfig->f_sta_miracast_mcc_rest_time_val =
+	smeConfig->csrConfig.f_sta_miracast_mcc_rest_time_val =
 		pHddCtx->config->sta_miracast_mcc_rest_time_val;
 
 #ifdef FEATURE_AP_MCC_CH_AVOIDANCE
-	smeConfig->sap_channel_avoidance =
+	smeConfig->csrConfig.sap_channel_avoidance =
 		pHddCtx->config->sap_channel_avoidance;
 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
 
-	smeConfig->f_prefer_non_dfs_on_radar =
+	smeConfig->csrConfig.f_prefer_non_dfs_on_radar =
 		pHddCtx->config->prefer_non_dfs_on_radar;
 
-	smeConfig->is_ps_enabled = pHddCtx->config->is_ps_enabled;
+	smeConfig->csrConfig.is_ps_enabled = pHddCtx->config->is_ps_enabled;
 	hdd_set_fine_time_meas_cap(pHddCtx, smeConfig);
 
 	cds_set_multicast_logging(pHddCtx->config->multicast_host_fw_msgs);
 
 	smeConfig->csrConfig.sendDeauthBeforeCon = pConfig->sendDeauthBeforeCon;
 
-	smeConfig->policy_manager_enabled =
+	smeConfig->csrConfig.policy_manager_enabled =
 			pHddCtx->config->policy_manager_enabled;
 	smeConfig->csrConfig.max_scan_count =
 			pHddCtx->config->max_scan_count;
@@ -6603,11 +6669,11 @@ CDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
 		(pHddCtx->config->dot11p_mode != WLAN_HDD_11P_DISABLED);
 	hdd_set_pno_channel_prediction_config(smeConfig, pHddCtx);
 
-	smeConfig->early_stop_scan_enable =
+	smeConfig->csrConfig.early_stop_scan_enable =
 		pHddCtx->config->early_stop_scan_enable;
-	smeConfig->early_stop_scan_min_threshold =
+	smeConfig->csrConfig.early_stop_scan_min_threshold =
 		pHddCtx->config->early_stop_scan_min_threshold;
-	smeConfig->early_stop_scan_max_threshold =
+	smeConfig->csrConfig.early_stop_scan_max_threshold =
 		pHddCtx->config->early_stop_scan_max_threshold;
 	smeConfig->csrConfig.first_scan_bucket_threshold =
 		pHddCtx->config->first_scan_bucket_threshold;

File diff suppressed because it is too large
+ 347 - 154
core/hdd/src/wlan_hdd_cfg80211.c


+ 66 - 12
core/hdd/src/wlan_hdd_cfg80211.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -249,6 +249,9 @@ typedef enum {
  * @QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN: venodr scan command
  * @QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE: vendor scan complete
  * @QCA_NL80211_VENDOR_SUBCMD_OTA_TEST: enable OTA test
+ * @QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG: set gateway parameters
+ * @QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE: set tx power by percentage
+ * @QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE_DECR_DB: reduce tx power by DB
  */
 
 enum qca_nl80211_vendor_subcmds {
@@ -350,6 +353,8 @@ enum qca_nl80211_vendor_subcmds {
 
 	/* subcommand to get link properties */
 	QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES = 101,
+	/* LFR Subnet Detection */
+	QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG = 102,
 
 	/* DBS subcommands */
 	QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST = 103,
@@ -361,6 +366,10 @@ enum qca_nl80211_vendor_subcmds {
 
 	/* OTA test subcommand */
 	QCA_NL80211_VENDOR_SUBCMD_OTA_TEST = 108,
+	/* Tx power scaling subcommands */
+	QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE = 109,
+	/* Tx power scaling in db subcommands */
+	QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE_DECR_DB = 115,
 
 };
 
@@ -420,6 +429,8 @@ enum qca_nl80211_vendor_subcmds {
  * @QCA_NL80211_VENDOR_SUBCMD_SCAN_INDEX: vendor scan index
  * @QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX:
  *	vendor scan complete event  index
+ * @QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG_INDEX:
+ *	update gateway parameters index
  */
 
 enum qca_nl80211_vendor_subcmds_index {
@@ -488,6 +499,7 @@ enum qca_nl80211_vendor_subcmds_index {
 	QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT_INDEX,
 	QCA_NL80211_VENDOR_SUBCMD_SCAN_INDEX,
 	QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX,
+	QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG_INDEX,
 };
 
 /**
@@ -1548,6 +1560,7 @@ enum qca_wlan_vendor_attr_set_no_dfs_flag {
  * @QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR: Replay Counter
  * @QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK: KCK of the PTK
  * @QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK: KEK of the PTK
+ * @QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS: subnet change status
  */
 enum qca_wlan_vendor_attr_roam_auth {
 	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_INVALID = 0,
@@ -1558,6 +1571,7 @@ enum qca_wlan_vendor_attr_roam_auth {
 	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR,
 	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK,
 	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK,
+	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS,
 	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX =
 		QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AFTER_LAST - 1
@@ -2165,6 +2179,23 @@ enum qca_vendor_attr_probable_oper_channel {
 	QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_AFTER_LAST - 1
 };
 
+/**
+ * enum qca_wlan_vendor_attr_gw_param_config - gateway param config
+ * @QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_INVALID: Invalid
+ * @QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_GW_MAC_ADDR: gateway mac addr
+ * @QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV4_ADDR: ipv4 addr
+ * @QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV6_ADDR: ipv6 addr
+ */
+enum qca_wlan_vendor_attr_gw_param_config {
+	QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_GW_MAC_ADDR,
+	QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV4_ADDR,
+	QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV6_ADDR,
+	QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_MAX =
+		QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_AFTER_LAST - 1,
+};
+
 /**
  * enum drv_dbs_capability - DBS capability
  * @DRV_DBS_CAPABILITY_DISABLED: DBS disabled
@@ -2194,14 +2225,45 @@ enum qca_vendor_attr_ota_test {
 	QCA_WLAN_VENDOR_ATTR_OTA_TEST_AFTER_LAST - 1
 };
 
+/** enum qca_vendor_attr_txpower_scale - vendor sub commands index
+ * @QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_INVALID: invalid value
+ * @QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE: scaling value
+ * @QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_AFTER_LAST: last value
+ * @QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_MAX: max value
+ */
+enum qca_vendor_attr_txpower_scale {
+	QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_INVALID,
+	/* 8-bit unsigned value to indicate the scaling of tx power */
+	QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE,
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_MAX =
+	QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_AFTER_LAST - 1
+};
+
+/**
+ * enum qca_vendor_attr_txpower_scale_decr_db - vendor sub commands index
+ * @QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_INVALID: invalid value
+ * @QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB: scaling value
+ * @QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_AFTER_LAST: last value
+ * @QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_MAX: max value
+ */
+enum qca_vendor_attr_txpower_scale_decr_db {
+	QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_INVALID,
+	/* 8-bit unsigned value to indicate the scaling of tx power */
+	QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB,
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_MAX =
+	QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_DECR_DB_AFTER_LAST - 1
+};
+
 struct cfg80211_bss *wlan_hdd_cfg80211_update_bss_db(hdd_adapter_t *pAdapter,
 						tCsrRoamInfo *pRoamInfo);
 
-#ifdef FEATURE_WLAN_LFR
 int wlan_hdd_cfg80211_pmksa_candidate_notify(hdd_adapter_t *pAdapter,
 					tCsrRoamInfo *pRoamInfo,
 					int index, bool preauth);
-#endif
 
 #ifdef FEATURE_WLAN_LFR_METRICS
 CDF_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
@@ -2222,12 +2284,9 @@ void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t *pAdapter, uint8_t key_index,
 				    const uint8_t *mac_addr, const uint8_t *key,
 				    int key_Len);
 #endif
-struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size);
+hdd_context_t *hdd_cfg80211_wiphy_alloc(int priv_size);
 
 int wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-			   struct net_device *dev,
-#endif
 			   struct cfg80211_scan_request *request);
 
 int wlan_hdd_cfg80211_init(struct device *dev,
@@ -2240,13 +2299,8 @@ void wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter);
 
 void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t *pAdapter);
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
 void hdd_reg_notifier(struct wiphy *wiphy,
 				 struct regulatory_request *request);
-#else
-int hdd_reg_notifier(struct wiphy *wiphy,
-				struct regulatory_request *request);
-#endif
 
 extern void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
 					  eConnectionState connState);

+ 17 - 19
core/hdd/src/wlan_hdd_conc_ut.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c)2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -633,7 +633,7 @@ void wlan_hdd_one_connection_scenario(hdd_context_t *hdd_ctx)
 	CDF_STATUS ret;
 
 	/* flush the entire table first */
-	ret = cds_init_policy_mgr(hdd_ctx);
+	ret = cds_init_policy_mgr();
 	if (!CDF_IS_STATUS_SUCCESS(ret)) {
 		hdd_err("Policy manager initialization failed");
 		return;
@@ -641,7 +641,7 @@ void wlan_hdd_one_connection_scenario(hdd_context_t *hdd_ctx)
 
 	for (sub_type = 0; sub_type < CDS_MAX_NUM_OF_MODE; sub_type++) {
 		/* validate one connection is created or no */
-		if (cds_get_connection_count(hdd_ctx) != 0) {
+		if (cds_get_connection_count() != 0) {
 			hddLog(LOGE,
 				FL("Test failed - No. of connection is not 0"));
 			return;
@@ -651,7 +651,7 @@ void wlan_hdd_one_connection_scenario(hdd_context_t *hdd_ctx)
 		pcl_type = get_pcl_from_first_conn_table(sub_type, system_pref);
 
 		/* check PCL value for second connection is correct or no */
-		cds_get_pcl(hdd_ctx, sub_type, pcl, &pcl_len);
+		cds_get_pcl(sub_type, pcl, &pcl_len);
 		status = wlan_hdd_validate_pcl(hdd_ctx,
 				pcl_type, pcl, pcl_len, 0, 0,
 				reason, sizeof(reason));
@@ -688,7 +688,7 @@ void wlan_hdd_two_connections_scenario(hdd_context_t *hdd_ctx,
 		type = wlan_hdd_valid_type_of_persona(sub_type);
 
 		/* flush the entire table first */
-		ret = cds_init_policy_mgr(hdd_ctx);
+		ret = cds_init_policy_mgr();
 		if (!CDF_IS_STATUS_SUCCESS(ret)) {
 			hdd_err("Policy manager initialization failed");
 			return;
@@ -697,11 +697,11 @@ void wlan_hdd_two_connections_scenario(hdd_context_t *hdd_ctx,
 		/* sub_type mapping between HDD and WMA are different */
 		wlan_hdd_map_subtypes_hdd_wma(&dummy_type, &sub_type);
 		/* add first connection as STA */
-		cds_incr_connection_count_utfw(hdd_ctx, vdevid, tx_stream,
+		cds_incr_connection_count_utfw(vdevid, tx_stream,
 				rx_stream, chain_mask, type, dummy_type,
 				channel_id, mac_id);
 		/* validate one connection is created or no */
-		if (cds_get_connection_count(hdd_ctx) != 1) {
+		if (cds_get_connection_count() != 1) {
 			hddLog(LOGE,
 				FL("Test failed - No. of connection is not 1"));
 			return;
@@ -710,8 +710,7 @@ void wlan_hdd_two_connections_scenario(hdd_context_t *hdd_ctx,
 		while (next_sub_type < CDS_MAX_NUM_OF_MODE) {
 			/* get the PCL value & check the channels accordingly */
 			second_index =
-				cds_get_second_connection_pcl_table_index(
-						hdd_ctx);
+				cds_get_second_connection_pcl_table_index();
 			if (CDS_MAX_ONE_CONNECTION_MODE == second_index) {
 				/* not valid combination*/
 				hddLog(LOGE, FL("couldn't find index for 2nd connection pcl table"));
@@ -724,7 +723,7 @@ void wlan_hdd_two_connections_scenario(hdd_context_t *hdd_ctx,
 					next_sub_type, system_pref,
 					wma_is_hw_dbs_capable());
 			/* check PCL for second connection is correct or no */
-			cds_get_pcl(hdd_ctx, next_sub_type, pcl, &pcl_len);
+			cds_get_pcl(next_sub_type, pcl, &pcl_len);
 			status = wlan_hdd_validate_pcl(hdd_ctx,
 					pcl_type, pcl, pcl_len, channel_id, 0,
 					reason, sizeof(reason));
@@ -787,7 +786,7 @@ void wlan_hdd_three_connections_scenario(hdd_context_t *hdd_ctx,
 
 		type_1 = wlan_hdd_valid_type_of_persona(sub_type_1);
 		/* flush the entire table first */
-		ret = cds_init_policy_mgr(hdd_ctx);
+		ret = cds_init_policy_mgr();
 		if (!CDF_IS_STATUS_SUCCESS(ret)) {
 			hdd_err("Policy manager initialization failed");
 			return;
@@ -796,11 +795,11 @@ void wlan_hdd_three_connections_scenario(hdd_context_t *hdd_ctx,
 		/* sub_type mapping between HDD and WMA are different */
 		wlan_hdd_map_subtypes_hdd_wma(&dummy_type_1, &sub_type_1);
 		/* add first connection as STA */
-		cds_incr_connection_count_utfw(hdd_ctx, vdevid_1,
+		cds_incr_connection_count_utfw(vdevid_1,
 			tx_stream_1, rx_stream_1, chain_mask_1, type_1,
 			dummy_type_1, channel_id_1, mac_id_1);
 		/* validate one connection is created or no */
-		if (cds_get_connection_count(hdd_ctx) != 1) {
+		if (cds_get_connection_count() != 1) {
 			hddLog(LOGE,
 				FL("Test fail - No. of connection not 1"));
 			return;
@@ -812,11 +811,11 @@ void wlan_hdd_three_connections_scenario(hdd_context_t *hdd_ctx,
 			/* sub_type mapping between HDD and WMA are different */
 			wlan_hdd_map_subtypes_hdd_wma(&dummy_type_2,
 					&sub_type_2);
-			cds_incr_connection_count_utfw(hdd_ctx, vdevid_2,
+			cds_incr_connection_count_utfw(vdevid_2,
 				tx_stream_2, rx_stream_2, chain_mask_2, type_2,
 				dummy_type_2, channel_id_2, mac_id_2);
 			/* validate two connections are created or no */
-			if (cds_get_connection_count(hdd_ctx) != 2) {
+			if (cds_get_connection_count() != 2) {
 				hddLog(LOGE,
 					FL("Test fail - No. connection not 2"));
 				return;
@@ -824,8 +823,7 @@ void wlan_hdd_three_connections_scenario(hdd_context_t *hdd_ctx,
 			next_sub_type = CDS_STA_MODE;
 			while (next_sub_type < CDS_MAX_NUM_OF_MODE) {
 				third_index =
-				  cds_get_third_connection_pcl_table_index(
-								hdd_ctx);
+				  cds_get_third_connection_pcl_table_index();
 				if (CDS_MAX_TWO_CONNECTION_MODE ==
 						third_index) {
 					/* not valid combination */
@@ -839,7 +837,7 @@ void wlan_hdd_three_connections_scenario(hdd_context_t *hdd_ctx,
 					   third_index, next_sub_type,
 					   system_pref,
 					   wma_is_hw_dbs_capable());
-				cds_get_pcl(hdd_ctx, next_sub_type,
+				cds_get_pcl(next_sub_type,
 						pcl, &pcl_len);
 				status = wlan_hdd_validate_pcl(hdd_ctx,
 						pcl_type, pcl, pcl_len,
@@ -858,7 +856,7 @@ void wlan_hdd_three_connections_scenario(hdd_context_t *hdd_ctx,
 				next_sub_type++;
 			}
 			/* remove entry to make a room for next iteration */
-			cds_decr_connection_count(hdd_ctx, vdevid_2);
+			cds_decr_connection_count(vdevid_2);
 		}
 		next_sub_type = CDS_STA_MODE;
 	}

+ 357 - 79
core/hdd/src/wlan_hdd_driver_ops.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -25,6 +25,9 @@
  * to the Linux Foundation.
  */
 
+/* denote that this file does not allow legacy hddLog */
+#define HDD_DISALLOW_LEGACY_HDDLOG 1
+
 #include <linux/platform_device.h>
 #include <linux/pci.h>
 #ifdef HIF_PCI
@@ -40,6 +43,7 @@
 #include "cds_sched.h"
 #include "osdep.h"
 #include "hif.h"
+#include "htc.h"
 #include "epping_main.h"
 #include "wlan_hdd_main.h"
 #include "wlan_hdd_power.h"
@@ -47,6 +51,7 @@
 #include "wma_api.h"
 #include "wlan_hdd_napi.h"
 #include "cds_concurrency.h"
+#include "qwlan_version.h"
 
 #ifdef MODULE
 #define WLAN_MODULE_NAME  module_name(THIS_MODULE)
@@ -72,6 +77,112 @@
 #define WLAN_HDD_UNREGISTER_DRIVER(wlan_drv_ops) \
 	icnss_unregister_driver(wlan_drv_ops)
 #endif /* HIF_PCI */
+#define DISABLE_KRAIT_IDLE_PS_VAL	1
+
+/*
+ * In BMI Phase we are only sending small chunk (256 bytes) of the FW image at
+ * a time, and wait for the completion interrupt to start the next transfer.
+ * During this phase, the KRAIT is entering IDLE/StandAlone(SA) Power Save(PS).
+ * The delay incurred for resuming from IDLE/SA PS is huge during driver load.
+ * So prevent APPS IDLE/SA PS durint driver load for reducing interrupt latency.
+ */
+#ifdef CONFIG_CNSS
+static inline void hdd_request_pm_qos(int val)
+{
+	cnss_request_pm_qos(val);
+}
+
+static inline void hdd_remove_pm_qos(void)
+{
+	cnss_remove_pm_qos();
+}
+#else
+static inline void hdd_request_pm_qos(int val)
+{
+}
+
+static inline void hdd_remove_pm_qos(void)
+{
+}
+#endif
+
+/**
+ * hdd_hif_open() - HIF open helper
+ * @dev: wlan device structure
+ * @bdev: bus device structure
+ * @bid: bus identifier for shared busses
+ * @bus_type: underlying bus type
+ * @reinit: true if we are reinitializing the driver during recovery phase
+ *
+ * This function brings-up HIF layer during load/recovery phase.
+ *
+ * Return: 0 on success and errno on failure.
+ */
+static int hdd_hif_open(struct device *dev, void *bdev, const hif_bus_id *bid,
+			enum ath_hal_bus_type bus_type, bool reinit)
+{
+	CDF_STATUS status;
+	int ret = 0;
+	void *hif_ctx;
+
+	status = hif_open(bus_type);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("hif_open error = %d", status);
+		return cdf_status_to_os_return(status);
+	}
+
+	hif_ctx = cds_get_context(CDF_MODULE_ID_HIF);
+
+	ret = hdd_napi_create();
+	if (hdd_napi_enabled(HDD_NAPI_ANY)) {
+		hdd_info("hdd_napi_create returned: %d", status);
+		if (ret <= 0) {
+			hdd_err("NAPI creation error, rc: 0x%x, reinit = %d",
+				status, reinit);
+			ret = -EFAULT;
+			goto err_hif_close;
+		}
+	}
+
+	status = hif_enable(hif_ctx, dev, bdev, bid, bus_type,
+			    (reinit == true) ?  HIF_ENABLE_TYPE_REINIT :
+			    HIF_ENABLE_TYPE_PROBE);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("hif_enable error = %d, reinit = %d",
+			status, reinit);
+		ret = cdf_status_to_os_return(status);
+		goto err_napi_destroy;
+	}
+
+	return 0;
+
+err_napi_destroy:
+	hdd_napi_destroy(true);
+
+err_hif_close:
+	hif_close(hif_ctx);
+
+	return ret;
+
+}
+
+/**
+ * hdd_hif_close() - HIF close helper
+ * @hif_ctx:	HIF context
+ *
+ * Helper function to close HIF
+ */
+static void hdd_hif_close(void *hif_ctx)
+{
+	if (hif_ctx == NULL)
+		return;
+
+	hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
+
+	hdd_napi_destroy(true);
+
+	hif_close(hif_ctx);
+}
 
 /**
  * wlan_hdd_probe() - handles probe request
@@ -91,72 +202,90 @@ static int wlan_hdd_probe(struct device *dev, void *bdev, const hif_bus_id *bid,
 {
 	void *hif_ctx;
 	CDF_STATUS status;
-	int ret;
+	int ret = 0;
+
+	pr_info("%s: %sprobing driver v%s\n", WLAN_MODULE_NAME,
+		reinit ? "re-" : "", QWLAN_VERSIONSTR);
+
+	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
+
+	/*
+	* The Krait is going to Idle/Stand Alone Power Save
+	* more aggressively which is resulting in the longer driver load time.
+	* The Fix is to not allow Krait to enter Idle Power Save during driver
+	* load.
+	*/
+	hdd_request_pm_qos(DISABLE_KRAIT_IDLE_PS_VAL);
+
+	if (reinit) {
+		cds_set_recovery_in_progress(true);
+	} else {
+		ret = hdd_init();
+
+		if (ret)
+			goto out;
+		cds_set_load_in_progress(true);
+	}
 
 	if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
 		status = epping_open();
 		if (status != CDF_STATUS_SUCCESS)
-			return status;
+			goto err_hdd_deinit;
 	}
 
-	status = hif_open();
-	if (status != CDF_STATUS_SUCCESS) {
-		hddLog(LOGE, FL("hif_open error = %d"), status);
-		return -EFAULT;
-	}
-	hif_ctx = cds_get_context(CDF_MODULE_ID_HIF);
-	if (reinit)
-		hdd_napi_destroy(true);
-	status = hdd_napi_create();
-	if (hdd_napi_enabled(HDD_NAPI_ANY)) {
-		hdd_info("hdd_napi_create returned: %d\n", status);
-		if (status <= 0) {
-			hdd_err("NAPI creation error, rc: 0x%x, reinit = %d",
-			status, reinit);
-			ret = -EFAULT;
-			goto end;
-		}
-	}
+	ret = hdd_hif_open(dev, bdev, bid, bus_type, reinit);
 
-	status = hif_enable(hif_ctx, dev, bdev, bid,
-				bus_type, (reinit == true) ?
-				HIF_ENABLE_TYPE_REINIT : HIF_ENABLE_TYPE_PROBE);
-	if (status != CDF_STATUS_SUCCESS) {
-		hdd_err("hif_enable error = %d, reinit = %d",
-			status, reinit);
-		ret = -EIO;
-		goto end;
-	}
+	if (ret)
+		goto err_epping_close;
+
+	hif_ctx = cds_get_context(CDF_MODULE_ID_HIF);
 
 	if (reinit)
 		ret = hdd_wlan_re_init(hif_ctx);
 	else
 		ret = hdd_wlan_startup(dev, hif_ctx);
 
-end:
-	if (ret) {
-		if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
-			hif_pktlogmod_exit(hif_ctx);
-			epping_disable();
-			htc_destroy(cds_get_context(CDF_MODULE_ID_HTC));
-			hif_disable(hif_ctx, (reinit == true) ?
-				HIF_ENABLE_TYPE_REINIT : HIF_ENABLE_TYPE_PROBE);
-			cds_free_context(NULL, CDF_MODULE_ID_HTC, NULL);
-			epping_close();
-		} else {
-			hif_pktlogmod_exit(hif_ctx);
-			__hdd_wlan_exit();
-			hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
-		}
-		hif_close(hif_ctx);
+	if (ret)
+		goto err_hif_close;
+
+	hif_enable_power_management(hif_ctx);
+
+	if (reinit) {
+		cds_set_recovery_in_progress(false);
+	} else {
+		cds_set_load_in_progress(false);
+		cds_set_driver_loaded(true);
 	}
 
-	if (reinit)
-		cds_set_logp_in_progress(false);
+	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
+	hdd_remove_pm_qos();
 
+	return 0;
+
+err_hif_close:
+	hdd_hif_close(hif_ctx);
+err_epping_close:
+	if (WLAN_IS_EPPING_ENABLED(cds_get_conparam()))
+		epping_close();
+err_hdd_deinit:
+	cds_set_load_in_progress(false);
+	hdd_deinit();
+out:
+	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
+	hdd_remove_pm_qos();
 	return ret;
 }
 
+#ifdef CONFIG_CNSS
+static inline void hdd_cnss_driver_unloading(void)
+{
+	cnss_set_driver_status(CNSS_LOAD_UNLOAD);
+}
+#else
+static inline void hdd_cnss_driver_unloading(void) { }
+#endif
+
+
 /**
  * wlan_hdd_remove() - wlan_hdd_remove
  *
@@ -168,38 +297,41 @@ end:
 static void wlan_hdd_remove(void)
 {
 	void *hif_ctx;
-	v_CONTEXT_t p_cds_context = NULL;
 
-	/* Get the global cds context */
-	p_cds_context = cds_get_global_context();
+	pr_info("%s: Removing driver v%s\n", WLAN_MODULE_NAME,
+		QWLAN_VERSIONSTR);
+
+	/* Wait for recovery to complete */
+	while (cds_is_driver_recovering()) {
+		hdd_alert("Recovery in progress; wait here!!!");
+		msleep(1000);
+	}
+
+	cds_set_driver_loaded(false);
+	cds_set_unload_in_progress(true);
+
+	if (!cds_wait_for_external_threads_completion(__func__))
+		hdd_err("External threads are still active attempting driver unload anyway");
+
+	hdd_cnss_driver_unloading();
 
 	hif_ctx = cds_get_context(CDF_MODULE_ID_HIF);
 
+	hif_disable_power_management(hif_ctx);
+	hif_pktlogmod_exit(hif_ctx);
+
 	if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
-		hif_pktlogmod_exit(hif_ctx);
 		epping_disable();
-		htc_destroy(cds_get_context(CDF_MODULE_ID_HTC));
-		hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
-		cds_free_context(NULL, CDF_MODULE_ID_HTC, NULL);
 		epping_close();
 	} else {
-		hif_pktlogmod_exit(hif_ctx);
 		__hdd_wlan_exit();
-		hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE);
 	}
 
-	hdd_napi_destroy(true);
-	hif_close(hif_ctx);
-
-	cds_free_global_context(&p_cds_context);
-
-#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
-	wlan_logging_sock_deinit_svc();
-#endif
+	hdd_hif_close(hif_ctx);
 
-	cdf_wake_lock_destroy(hdd_wlan_get_wake_lock_ptr());
+	hdd_deinit();
 
-	pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
+	pr_info("%s: Driver Removed\n", WLAN_MODULE_NAME);
 }
 
 /**
@@ -214,29 +346,26 @@ static void wlan_hdd_shutdown(void)
 {
 	void *hif_ctx = cds_get_context(CDF_MODULE_ID_HIF);
 
-	if (cds_is_load_unload_in_progress()) {
-		hddLog(LOGE,
-			FL("Load/unload in progress, ignore SSR shutdown"));
+	if (cds_is_load_or_unload_in_progress()) {
+		hdd_err("Load/unload in progress, ignore SSR shutdown");
 		return;
 	}
 	/* this is for cases, where shutdown invoked from CNSS */
-	cds_set_logp_in_progress(true);
+	cds_set_recovery_in_progress(true);
 
-	if (cds_get_conparam() != CDF_FTM_MODE &&
+	if (cds_get_conparam() != CDF_GLOBAL_FTM_MODE &&
 	    !WLAN_IS_EPPING_ENABLED(cds_get_conparam()))
 		hif_pktlogmod_exit(hif_ctx);
 
-	if (!cds_is_ssr_ready(__func__))
-		hddLog(LOGE,
-			FL("Host is not ready for SSR, attempting anyway"));
+	if (!cds_wait_for_external_threads_completion(__func__))
+		hdd_err("Host is not ready for SSR, attempting anyway");
 
 	if (!WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
 		hif_disable_isr(hif_ctx);
 		hdd_wlan_shutdown();
 	}
 
-	hif_disable(hif_ctx, HIF_DISABLE_TYPE_SHUTDOWN);
-	hif_close(hif_ctx);
+	hdd_hif_close(hif_ctx);
 }
 
 /**
@@ -268,7 +397,7 @@ void wlan_hdd_notify_handler(int state)
 		int ret = 0;
 		ret = hdd_wlan_notify_modem_power_state(state);
 		if (ret < 0)
-			hddLog(LOGE, FL("Fail to send notify"));
+			hdd_err("Fail to send notify");
 	}
 }
 
@@ -364,7 +493,7 @@ static int __wlan_hdd_bus_resume(void)
 	int status = wlan_hdd_validate_context(hdd_ctx);
 
 	if (0 != status) {
-		hddLog(LOGE, FL("HDD context is not valid"));
+		hdd_err("HDD context is not valid");
 		return status;
 	}
 
@@ -400,6 +529,117 @@ static int wlan_hdd_bus_resume(void)
 	return ret;
 }
 
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * __wlan_hdd_runtime_suspend() - suspend the wlan bus without apps suspend
+ *
+ * Each layer is responsible for its own suspend actions.  wma_runtime_suspend
+ * takes care of the parts of the 802.11 suspend that we want to do for runtime
+ * suspend.
+ *
+ * Return: 0 or errno
+ */
+static int __wlan_hdd_runtime_suspend(void)
+{
+	void *hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
+	int status = wlan_hdd_validate_context(hdd_ctx);
+
+	if (0 != status)
+		goto process_failure;
+
+	status = hif_pre_runtime_suspend();
+	if (status)
+		goto process_failure;
+
+	status = htc_runtime_suspend();
+	if (status)
+		goto process_failure;
+
+	status = wma_runtime_suspend();
+	if (status)
+		goto resume_htc;
+
+	status = hif_runtime_suspend();
+	if (status)
+		goto resume_wma;
+
+	status = cnss_auto_suspend();
+	if (status)
+		goto resume_hif;
+
+	hif_process_runtime_suspend_success();
+	return status;
+
+resume_hif:
+	CDF_BUG(!hif_runtime_resume());
+resume_wma:
+	CDF_BUG(!wma_runtime_resume());
+resume_htc:
+	CDF_BUG(!htc_runtime_resume());
+process_failure:
+	hif_process_runtime_suspend_failure();
+	return status;
+}
+
+
+/**
+ * wlan_hdd_runtime_suspend() - suspend the wlan bus without apps suspend
+ *
+ * This function is called by the platform driver to suspend the
+ * wlan bus separately from system suspend
+ *
+ * Return: 0 or errno
+ */
+static int wlan_hdd_runtime_suspend(void)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_runtime_suspend();
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
+/**
+ * __wlan_hdd_runtime_resume() - resume the wlan bus from runtime suspend
+ *
+ * Sets the runtime pm state and coordinates resume between hif wma and
+ * ol_txrx.
+ *
+ * Return: success since failure is a bug
+ */
+static int __wlan_hdd_runtime_resume(void)
+{
+	hif_pre_runtime_resume();
+	CDF_BUG(!cnss_auto_resume());
+	CDF_BUG(!hif_runtime_resume());
+	CDF_BUG(!wma_runtime_resume());
+	CDF_BUG(!htc_runtime_resume());
+	hif_process_runtime_resume_success();
+	return 0;
+}
+
+/**
+ * wlan_hdd_runtime_resume() - resume the wlan bus from runtime suspend
+ *
+ * This function is called by the platform driver to resume the
+ * wlan bus separately from system suspend
+ *
+ * Return: success since failure is a bug
+ */
+static int wlan_hdd_runtime_resume(void)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_runtime_resume();
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+#endif
+
 #ifdef HIF_PCI
 /**
  * wlan_hdd_pci_probe() - probe callback for pci platform driver
@@ -494,6 +734,32 @@ static int wlan_hdd_pci_resume(struct pci_dev *pdev)
 {
 	return wlan_hdd_bus_resume();
 }
+
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * wlan_hdd_pci_runtime_suspend() - wlan_hdd_pci_suspend
+ * @pdev: pdev
+ * @state: state
+ *
+ * Return: success or errno
+ */
+static int wlan_hdd_pci_runtime_suspend(struct pci_dev *pdev)
+{
+	return wlan_hdd_runtime_suspend();
+}
+
+/**
+ * wlan_hdd_pci_runtime_resume() - runtime resume callback to register with pci
+ * @pdev: pci device id
+ *
+ * Return: success or errno
+ */
+static int wlan_hdd_pci_runtime_resume(struct pci_dev *pdev)
+{
+	return wlan_hdd_runtime_resume();
+}
+#endif
+
 #else
 /**
  * wlan_hdd_snoc_probe() - wlan_hdd_snoc_probe
@@ -585,6 +851,14 @@ static struct pci_device_id wlan_hdd_pci_id_table[] = {
 };
 
 #ifdef CONFIG_CNSS
+
+#ifdef FEATURE_RUNTIME_PM
+struct cnss_wlan_runtime_ops runtime_pm_ops = {
+	.runtime_suspend = wlan_hdd_pci_runtime_suspend,
+	.runtime_resume = wlan_hdd_pci_runtime_resume,
+};
+#endif
+
 struct cnss_wlan_driver wlan_drv_ops = {
 	.name       = "wlan_hdd_pci",
 	.id_table   = wlan_hdd_pci_id_table,
@@ -598,6 +872,9 @@ struct cnss_wlan_driver wlan_drv_ops = {
 	.suspend    = wlan_hdd_pci_suspend,
 	.resume     = wlan_hdd_pci_resume,
 #endif /* ATH_BUS_PM */
+#ifdef FEATURE_RUNTIME_PM
+	.runtime_ops = &runtime_pm_ops,
+#endif
 };
 #else
 MODULE_DEVICE_TABLE(pci, wlan_hdd_pci_id_table);
@@ -610,6 +887,7 @@ struct pci_driver wlan_drv_ops = {
 	.suspend    = wlan_hdd_pci_suspend,
 	.resume     = wlan_hdd_pci_resume,
 #endif /* ATH_BUS_PM */
+
 };
 #endif /* CONFIG_CNSS */
 #else

+ 60 - 33
core/hdd/src/wlan_hdd_ext_scan.c

@@ -501,6 +501,9 @@ fail:
  * @ctx: Pointer to hdd context
  * @pData: Pointer to ext scan result event
  *
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
  * Return: none
  */
 static void
@@ -510,6 +513,7 @@ wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
 	hdd_context_t *pHddCtx = ctx;
 	struct sk_buff *skb = NULL;
 	uint32_t i, index;
+	int flags = cds_get_gfp_flags();
 
 	ENTER();
 
@@ -529,7 +533,7 @@ wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
 		  pHddCtx->wiphy,
 		  NULL,
 		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
-		  index, GFP_KERNEL);
+		  index, flags);
 
 	if (!skb) {
 		hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
@@ -618,7 +622,7 @@ wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
 			goto fail;
 	}
 
-	cfg80211_vendor_event(skb, GFP_KERNEL);
+	cfg80211_vendor_event(skb, flags);
 	EXIT();
 	return;
 
@@ -633,6 +637,9 @@ fail:
  * @ctx: Pointer to hdd context
  * @pData: Pointer to signif wifi change event
  *
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
  * Return: none
  */
 static void
@@ -645,6 +652,7 @@ wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(
 	tSirWifiSignificantChange *ap_info;
 	int32_t *rssi;
 	uint32_t i, j;
+	int flags = cds_get_gfp_flags();
 
 	ENTER();
 
@@ -660,7 +668,7 @@ wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(
 		NULL,
 		EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
 		QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
-		GFP_KERNEL);
+		flags);
 
 	if (!skb) {
 		hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
@@ -738,7 +746,7 @@ wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(
 			goto fail;
 	}
 
-	cfg80211_vendor_event(skb, GFP_KERNEL);
+	cfg80211_vendor_event(skb, flags);
 	return;
 
 fail:
@@ -752,6 +760,9 @@ fail:
  * @ctx: Pointer to hdd context
  * @pData: Pointer to full scan result event
  *
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
  * Return: none
  */
 static void
@@ -764,6 +775,7 @@ wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
 #ifdef CONFIG_CNSS
 	struct timespec ts;
 #endif
+	int flags = cds_get_gfp_flags();
 
 	ENTER();
 
@@ -784,7 +796,7 @@ wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
 		  NULL,
 		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
 		  QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
-		  GFP_KERNEL);
+		  flags);
 
 	if (!skb) {
 		hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
@@ -867,7 +879,7 @@ wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
 			goto nla_put_failure;
 	}
 
-	cfg80211_vendor_event(skb, GFP_KERNEL);
+	cfg80211_vendor_event(skb, flags);
 	EXIT();
 	return;
 
@@ -881,6 +893,9 @@ nla_put_failure:
  * @ctx: Pointer to hdd context
  * @pData: Pointer to scan results available indication param
  *
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
  * Return: none
  */
 static void
@@ -890,6 +905,7 @@ wlan_hdd_cfg80211_extscan_scan_res_available_event(
 {
 	hdd_context_t *pHddCtx = (hdd_context_t *) ctx;
 	struct sk_buff *skb = NULL;
+	int flags = cds_get_gfp_flags();
 
 	ENTER();
 
@@ -905,7 +921,7 @@ wlan_hdd_cfg80211_extscan_scan_res_available_event(
 		 NULL,
 		 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
 		 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
-		 GFP_KERNEL);
+		 flags);
 
 	if (!skb) {
 		hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
@@ -924,7 +940,7 @@ wlan_hdd_cfg80211_extscan_scan_res_available_event(
 		goto nla_put_failure;
 	}
 
-	cfg80211_vendor_event(skb, GFP_KERNEL);
+	cfg80211_vendor_event(skb, flags);
 	EXIT();
 	return;
 
@@ -938,6 +954,9 @@ nla_put_failure:
  * @ctx: Pointer to hdd context
  * @pData: Pointer to scan event indication param
  *
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
+ *
  * Return: none
  */
 static void
@@ -947,6 +966,7 @@ wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx,
 {
 	hdd_context_t *pHddCtx = (hdd_context_t *) ctx;
 	struct sk_buff *skb = NULL;
+	int flags = cds_get_gfp_flags();
 
 	ENTER();
 
@@ -962,7 +982,7 @@ wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx,
 			NULL,
 			EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
 			QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
-			GFP_KERNEL);
+			flags);
 
 	if (!skb) {
 		hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
@@ -983,7 +1003,7 @@ wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx,
 		goto nla_put_failure;
 	}
 
-	cfg80211_vendor_event(skb, GFP_KERNEL);
+	cfg80211_vendor_event(skb, flags);
 	EXIT();
 	return;
 
@@ -999,6 +1019,8 @@ nla_put_failure:
  *
  * This function reads the matched network data and fills NL vendor attributes
  * and send it to upper layer.
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
  *
  * Return: 0 on success, error number otherwise
  */
@@ -1009,6 +1031,7 @@ wlan_hdd_cfg80211_extscan_epno_match_found(void *ctx,
 	hdd_context_t *pHddCtx  = (hdd_context_t *)ctx;
 	struct sk_buff *skb     = NULL;
 	uint32_t len, i;
+	int flags = cds_get_gfp_flags();
 
 	ENTER();
 
@@ -1037,7 +1060,7 @@ wlan_hdd_cfg80211_extscan_epno_match_found(void *ctx,
 		  NULL,
 		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
 		QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_NETWORK_FOUND_INDEX,
-		  GFP_KERNEL);
+		  flags);
 
 	if (!skb) {
 		hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
@@ -1095,7 +1118,7 @@ wlan_hdd_cfg80211_extscan_epno_match_found(void *ctx,
 		nla_nest_end(skb, nla_aps);
 	}
 
-	cfg80211_vendor_event(skb, GFP_KERNEL);
+	cfg80211_vendor_event(skb, flags);
 	return;
 
 fail:
@@ -1110,6 +1133,8 @@ fail:
  *
  * This function reads the match network %data and fill in the skb with
  * NL attributes and send up the NL event
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
  *
  * Return: none
  */
@@ -1120,8 +1145,8 @@ wlan_hdd_cfg80211_passpoint_match_found(void *ctx,
 	hdd_context_t *pHddCtx  = ctx;
 	struct sk_buff *skb     = NULL;
 	uint32_t len, i, num_matches = 1, more_data = 0;
-	struct nlattr *nla_aps;
-	struct nlattr *nla_bss;
+	struct nlattr *nla_aps, *nla_bss;
+	int flags = cds_get_gfp_flags();
 
 	ENTER();
 
@@ -1142,7 +1167,7 @@ wlan_hdd_cfg80211_passpoint_match_found(void *ctx,
 		  NULL,
 		  EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
 		  QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_PASSPOINT_NETWORK_FOUND_INDEX,
-		  GFP_KERNEL);
+		  flags);
 
 	if (!skb) {
 		hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
@@ -1225,7 +1250,7 @@ wlan_hdd_cfg80211_passpoint_match_found(void *ctx,
 	}
 	nla_nest_end(skb, nla_aps);
 
-	cfg80211_vendor_event(skb, GFP_KERNEL);
+	cfg80211_vendor_event(skb, flags);
 	return;
 
 fail:
@@ -1242,6 +1267,8 @@ fail:
  * This function will take an SSID match event that was generated by
  * firmware and will convert it into a cfg80211 vendor event which is
  * sent to userspace.
+ * This callback execute in atomic context and must not invoke any
+ * blocking calls.
  *
  * Return: none
  */
@@ -1252,6 +1279,7 @@ wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
 	hdd_context_t *hdd_ctx = ctx;
 	struct sk_buff *skb;
 	uint32_t i, index;
+	int flags = cds_get_gfp_flags();
 
 	ENTER();
 
@@ -1273,8 +1301,7 @@ wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
 	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
 		NULL,
 		EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
-		index,
-		GFP_KERNEL);
+		index, flags);
 
 	if (!skb) {
 		hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
@@ -1367,7 +1394,7 @@ wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
 		}
 	}
 
-	cfg80211_vendor_event(skb, GFP_KERNEL);
+	cfg80211_vendor_event(skb, flags);
 	return;
 
 fail:
@@ -1691,7 +1718,7 @@ static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -1825,7 +1852,7 @@ static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -1973,7 +2000,7 @@ __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -2170,7 +2197,7 @@ __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -2452,7 +2479,7 @@ __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -3117,7 +3144,7 @@ __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -3327,7 +3354,7 @@ __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -3454,7 +3481,7 @@ __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -3579,7 +3606,7 @@ __wlan_hdd_cfg80211_extscan_reset_significant_change(struct wiphy
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -3795,7 +3822,7 @@ static int __wlan_hdd_cfg80211_set_epno_list(struct wiphy *wiphy,
 	if (ret_val)
 		return ret_val;
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -4001,7 +4028,7 @@ static int __wlan_hdd_cfg80211_set_passpoint_list(struct wiphy *wiphy,
 	if (ret)
 		return ret;
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -4117,7 +4144,7 @@ static int __wlan_hdd_cfg80211_reset_passpoint_list(struct wiphy *wiphy,
 	if (ret)
 		return ret;
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -4243,7 +4270,7 @@ __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -4463,7 +4490,7 @@ __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}

+ 2 - 2
core/hdd/src/wlan_hdd_ftm.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -659,7 +659,7 @@ int wlan_hdd_ftm_close(hdd_context_t *hdd_ctx)
 		wlan_ftm_stop(hdd_ctx);
 	}
 
-	hdd_close_all_adapters(hdd_ctx);
+	hdd_close_all_adapters(hdd_ctx, false);
 
 	cdf_status = cds_sched_close(cds_context);
 	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {

+ 63 - 20
core/hdd/src/wlan_hdd_green_ap.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -26,6 +26,9 @@
  *
  */
 
+/* denote that this file does not allow legacy hddLog */
+#define HDD_DISALLOW_LEGACY_HDDLOG 1
+
 /* Include Files */
 #include <wlan_hdd_main.h>
 #include <wlan_hdd_misc.h>
@@ -77,6 +80,7 @@ enum hdd_green_ap_event {
  * @ps_state: Current state
  * @ps_event: Event to trigger when timer expires
  * @ps_timer: Event timer
+ * @egap_support: Enhanced Green AP support flag
  */
 struct hdd_green_ap_ctx {
 	uint8_t ps_enable;
@@ -88,6 +92,8 @@ struct hdd_green_ap_ctx {
 	enum hdd_green_ap_event ps_event;
 
 	cdf_mc_timer_t ps_timer;
+
+	bool egap_support;
 };
 
 /**
@@ -120,7 +126,7 @@ static int hdd_wlan_green_ap_enable(hdd_adapter_t *adapter,
 {
 	int ret;
 
-	hddLog(LOG1, FL("Set Green-AP val: %d"), enable);
+	hdd_notice("Set Green-AP val: %d", enable);
 
 	ret = wma_cli_set_command(adapter->sessionId,
 				  WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID,
@@ -146,8 +152,8 @@ static void hdd_wlan_green_ap_mc(struct hdd_context_s *hdd_ctx,
 	if (green_ap == NULL)
 		return;
 
-	hddLog(LOG1, FL("Green-AP event: %d, state: %d, num_nodes: %d"),
-	       event, green_ap->ps_state, green_ap->num_nodes);
+	hdd_notice("Green-AP event: %d, state: %d, num_nodes: %d",
+		   event, green_ap->ps_state, green_ap->num_nodes);
 
 	/* handle the green ap ps event */
 	switch (event) {
@@ -174,13 +180,13 @@ static void hdd_wlan_green_ap_mc(struct hdd_context_s *hdd_ctx,
 		break;
 
 	default:
-		hddLog(LOGE, FL("invalid event %d"), event);
+		hdd_err("invalid event %d", event);
 		break;
 	}
 
 	/* Confirm that power save is enabled before doing state transitions */
 	if (!green_ap->ps_enable) {
-		hddLog(CDF_TRACE_LEVEL_INFO, FL("Green-AP is disabled"));
+		hdd_notice("Green-AP is disabled");
 		hdd_wlan_green_ap_update(hdd_ctx,
 					 GREEN_AP_PS_IDLE_STATE,
 					 GREEN_AP_PS_WAIT_EVENT);
@@ -189,7 +195,7 @@ static void hdd_wlan_green_ap_mc(struct hdd_context_s *hdd_ctx,
 
 	adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_SOFTAP);
 	if (adapter == NULL) {
-		hddLog(LOGE, FL("Green-AP no SAP adapter"));
+		hdd_err("Green-AP no SAP adapter");
 		goto done;
 	}
 
@@ -236,7 +242,7 @@ static void hdd_wlan_green_ap_mc(struct hdd_context_s *hdd_ctx,
 	case GREEN_AP_PS_ON_STATE:
 		if (green_ap->num_nodes) {
 			if (hdd_wlan_green_ap_enable(adapter, 0)) {
-				hddLog(LOGE, FL("FAILED TO SET GREEN-AP mode"));
+				hdd_err("FAILED TO SET GREEN-AP mode");
 				goto done;
 			}
 			hdd_wlan_green_ap_update(hdd_ctx,
@@ -251,7 +257,7 @@ static void hdd_wlan_green_ap_mc(struct hdd_context_s *hdd_ctx,
 						 GREEN_AP_PS_ON_EVENT);
 
 			if (hdd_wlan_green_ap_enable(adapter, 0)) {
-				hddLog(LOGE, FL("FAILED TO SET GREEN-AP mode"));
+				hdd_err("FAILED TO SET GREEN-AP mode");
 				goto done;
 			}
 
@@ -261,7 +267,7 @@ static void hdd_wlan_green_ap_mc(struct hdd_context_s *hdd_ctx,
 		break;
 
 	default:
-		hddLog(LOGE, FL("invalid state %d"), green_ap->ps_state);
+		hdd_err("invalid state %d", green_ap->ps_state);
 		hdd_wlan_green_ap_update(hdd_ctx, GREEN_AP_PS_OFF_STATE,
 					 GREEN_AP_PS_WAIT_EVENT);
 		break;
@@ -283,7 +289,7 @@ static void hdd_wlan_green_ap_timer_fn(void *ctx)
 	struct hdd_green_ap_ctx *green_ap;
 
 	if (0 != wlan_hdd_validate_context(hdd_ctx)) {
-		hddLog(CDF_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
+		hdd_err("HDD context is not valid");
 		return;
 	}
 
@@ -307,7 +313,7 @@ static CDF_STATUS hdd_wlan_green_ap_attach(struct hdd_context_s *hdd_ctx)
 
 	green_ap = cdf_mem_malloc(sizeof(*green_ap));
 	if (!green_ap) {
-		hddLog(LOGP, FL("Memory allocation for Green-AP failed!"));
+		hdd_alert("Memory allocation for Green-AP failed!");
 		status = CDF_STATUS_E_NOMEM;
 		goto error;
 	}
@@ -344,7 +350,7 @@ static CDF_STATUS hdd_wlan_green_ap_deattach(struct hdd_context_s *hdd_ctx)
 	ENTER();
 
 	if (green_ap == NULL) {
-		hddLog(LOG1, FL("Green-AP is not enabled"));
+		hdd_notice("Green-AP is not enabled");
 		status = CDF_STATUS_E_NOSUPPORT;
 		goto done;
 	}
@@ -356,7 +362,7 @@ static CDF_STATUS hdd_wlan_green_ap_deattach(struct hdd_context_s *hdd_ctx)
 
 	/* Destroy the Green AP timer */
 	if (!CDF_IS_STATUS_SUCCESS(cdf_mc_timer_destroy(&green_ap->ps_timer)))
-		hddLog(LOG1, FL("Cannot deallocate Green-AP's timer"));
+		hdd_notice("Cannot deallocate Green-AP's timer");
 
 	/* release memory */
 	cdf_mem_zero(green_ap, sizeof(*green_ap));
@@ -378,7 +384,7 @@ done:
 void hdd_wlan_green_ap_init(struct hdd_context_s *hdd_ctx)
 {
 	if (!CDF_IS_STATUS_SUCCESS(hdd_wlan_green_ap_attach(hdd_ctx)))
-		hddLog(LOGE, FL("Failed to allocate Green-AP resource"));
+		hdd_err("Failed to allocate Green-AP resource");
 }
 
 /**
@@ -390,7 +396,7 @@ void hdd_wlan_green_ap_init(struct hdd_context_s *hdd_ctx)
 void hdd_wlan_green_ap_deinit(struct hdd_context_s *hdd_ctx)
 {
 	if (!CDF_IS_STATUS_SUCCESS(hdd_wlan_green_ap_deattach(hdd_ctx)))
-		hddLog(LOGE, FL("Cannot deallocate Green-AP resource"));
+		hdd_err("Cannot deallocate Green-AP resource");
 }
 
 /**
@@ -403,16 +409,38 @@ void hdd_wlan_green_ap_start_bss(struct hdd_context_s *hdd_ctx)
 {
 	struct hdd_config *cfg = hdd_ctx->config;
 
+	/* check if the firmware and ini are both enabled the egap,
+	 * and also the feature_flag enable, then we enable the egap
+	 */
+	if (hdd_ctx->green_ap_ctx->egap_support && cfg->enable_egap &&
+	    cfg->egap_feature_flag) {
+		hdd_notice("Set EGAP - enabled: %d, flag: %x, inact_time: %d, wait_time: %d",
+			   cfg->enable_egap, cfg->egap_feature_flag,
+			   cfg->egap_inact_time, cfg->egap_wait_time);
+		if (!sme_send_egap_conf_params(cfg->enable_egap,
+					       cfg->egap_inact_time,
+					       cfg->egap_wait_time,
+					       cfg->egap_feature_flag)) {
+			/* EGAP is enabled, disable host GAP */
+			hdd_wlan_green_ap_mc(hdd_ctx, GREEN_AP_PS_STOP_EVENT);
+			goto exit;
+		}
+		/* fall through, if send_egap_conf_params() failed,
+		 * then check host GAP and enable it accordingly
+		 */
+	}
+
 	if (!(CDF_STA_MASK & hdd_ctx->concurrency_mode) &&
 	    cfg->enable2x2 && cfg->enableGreenAP) {
 		hdd_wlan_green_ap_mc(hdd_ctx, GREEN_AP_PS_START_EVENT);
 	} else {
 		hdd_wlan_green_ap_mc(hdd_ctx, GREEN_AP_PS_STOP_EVENT);
-		hddLog(LOG1,
-		       "Green-AP: is disabled, due to sta_concurrency: %d, enable2x2: %d, enableGreenAP: %d",
-		       CDF_STA_MASK & hdd_ctx->concurrency_mode,
-		       cfg->enable2x2, cfg->enableGreenAP);
+		hdd_notice("Green-AP: is disabled, due to sta_concurrency: %d, enable2x2: %d, enableGreenAP: %d",
+			   CDF_STA_MASK & hdd_ctx->concurrency_mode,
+			   cfg->enable2x2, cfg->enableGreenAP);
 	}
+exit:
+	return;
 }
 
 /**
@@ -447,3 +475,18 @@ void hdd_wlan_green_ap_del_sta(struct hdd_context_s *hdd_ctx)
 {
 	hdd_wlan_green_ap_mc(hdd_ctx, GREEN_AP_DEL_STA_EVENT);
 }
+
+/**
+ * hdd_wlan_set_egap_support() - helper function to set egap support flag
+ * @hdd_ctx:   pointer to hdd context
+ * @param:     pointer to target configuration
+ *
+ * Return:     None
+ */
+void hdd_wlan_set_egap_support(hdd_context_t *hdd_ctx, void *param)
+{
+	struct wma_tgt_cfg *cfg = (struct wma_tgt_cfg *) param;
+
+	if (hdd_ctx && cfg)
+		hdd_ctx->green_ap_ctx->egap_support = cfg->egap_support;
+}

+ 4 - 0
core/hdd/src/wlan_hdd_green_ap.h

@@ -43,6 +43,7 @@ void hdd_wlan_green_ap_start_bss(struct hdd_context_s *hdd_ctx);
 void hdd_wlan_green_ap_stop_bss(struct hdd_context_s *hdd_ctx);
 void hdd_wlan_green_ap_add_sta(struct hdd_context_s *hdd_ctx);
 void hdd_wlan_green_ap_del_sta(struct hdd_context_s *hdd_ctx);
+void hdd_wlan_set_egap_support(struct hdd_context_s *hdd_ctx, void *param);
 #else
 static inline void hdd_wlan_green_ap_init(struct hdd_context_s *hdd_ctx) {}
 static inline void hdd_wlan_green_ap_deinit(struct hdd_context_s *hdd_ctx) {}
@@ -50,5 +51,8 @@ static inline void hdd_wlan_green_ap_start_bss(struct hdd_context_s *hdd_ctx) {}
 static inline void hdd_wlan_green_ap_stop_bss(struct hdd_context_s *hdd_ctx) {}
 static inline void hdd_wlan_green_ap_add_sta(struct hdd_context_s *hdd_ctx) {}
 static inline void hdd_wlan_green_ap_del_sta(struct hdd_context_s *hdd_ctx) {}
+static inline void hdd_wlan_set_egap_support(struct hdd_context_s *hdd_ctx,
+					     void *param) {}
+
 #endif /* FEATURE_GREEN_AP */
 #endif /* __WLAN_HDD_GREEN_AP_H */

+ 148 - 373
core/hdd/src/wlan_hdd_hostapd.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -222,12 +222,12 @@ static int __hdd_hostapd_open(struct net_device *dev)
 	MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
 			 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
 
-	if (WLAN_HDD_GET_CTX(pAdapter)->isLoadInProgress ||
-		WLAN_HDD_GET_CTX(pAdapter)->isUnloadInProgress) {
-		hddLog(LOGE,
-		       FL("Driver load/unload in progress, ignore adapter open"));
+	if (cds_is_load_or_unload_in_progress()) {
+		hdd_err("Driver load/unload in progress, ignore, state: 0x%x",
+			cds_get_driver_state());
 		goto done;
 	}
+
 	/* Enable all Tx queues */
 	hddLog(LOG1, FL("Enabling queues"));
 	wlan_hdd_netif_queue_control(pAdapter,
@@ -556,8 +556,7 @@ static int hdd_stop_bss_link(hdd_adapter_t *pHostapdAdapter,
 			hddLog(LOGE, FL("Deleting SAP/P2P link!!!!!!"));
 
 		clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
-		cds_decr_session_set_pcl(pHddCtx,
-					     pHostapdAdapter->device_mode,
+		cds_decr_session_set_pcl(pHostapdAdapter->device_mode,
 					     pHostapdAdapter->sessionId);
 	}
 	EXIT();
@@ -589,7 +588,7 @@ static void hdd_issue_stored_joinreq(hdd_adapter_t *sta_adapter,
 	}
 	hal_handle = WLAN_HDD_GET_HAL_CTX(sta_adapter);
 
-	if (true ==  cds_is_sta_connection_pending(hdd_ctx)) {
+	if (true ==  cds_is_sta_connection_pending()) {
 		MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
 				TRACE_CODE_HDD_ISSUE_JOIN_REQ,
 				sta_adapter->sessionId, roam_id));
@@ -601,9 +600,95 @@ static void hdd_issue_stored_joinreq(hdd_adapter_t *sta_adapter,
 			hdd_conn_set_connection_state(sta_adapter,
 				eConnectionState_NotConnected);
 		}
-		cds_change_sta_conn_pending_status(hdd_ctx, false);
+		cds_change_sta_conn_pending_status(false);
+	}
+}
+
+#ifdef WLAN_FEATURE_MBSSID
+static eCsrPhyMode
+hdd_sap_get_phymode(hdd_adapter_t *hostapd_adapter)
+{
+	return wlansap_get_phymode(WLAN_HDD_GET_SAP_CTX_PTR(hostapd_adapter));
+}
+#else
+static eCsrPhyMode
+hdd_sap_get_phymode(hdd_adapter_t *hostapd_adapter)
+{
+	return wlansap_get_phymode(
+		(WLAN_HDD_GET_CTX(hostapd_adapter))->pcds_context);
+}
+#endif
+
+/**
+ * hdd_update_chandef() - Function to update channel width and center freq
+ * @hostapd_adapter:	hostapd adapter
+ * @chandef:		cfg80211 chan def
+ * @cb_mode:		chan offset
+ *
+ * This function will be called to update channel width and center freq
+ *
+ * Return: None
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) || defined(WITH_BACKPORTS)
+static inline void
+hdd_update_chandef(hdd_adapter_t *hostapd_adapter,
+		struct cfg80211_chan_def *chandef,
+		ePhyChanBondState cb_mode)
+{
+	uint16_t   ch_width;
+	hdd_ap_ctx_t *phdd_ap_ctx;
+	uint8_t  center_chan, chan;
+
+	phdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(hostapd_adapter);
+	ch_width = phdd_ap_ctx->sapConfig.acs_cfg.ch_width;
+
+	switch (ch_width) {
+	case eHT_CHANNEL_WIDTH_20MHZ:
+	case eHT_CHANNEL_WIDTH_40MHZ:
+		hdd_info("ch_width %d, won't update", ch_width);
+		break;
+	case eHT_CHANNEL_WIDTH_80MHZ:
+		chan = cds_freq_to_chan(chandef->chan->center_freq);
+		chandef->width = NL80211_CHAN_WIDTH_80;
+
+		switch (cb_mode) {
+		case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
+		case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
+			center_chan = chan + 2;
+			break;
+		case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
+			center_chan = chan + 6;
+			break;
+		case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
+		case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
+			center_chan = chan - 2;
+			break;
+		case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
+			center_chan = chan - 6;
+			break;
+		default:
+			center_chan = chan;
+			break;
+		}
+
+		chandef->center_freq1 = cds_chan_to_freq(center_chan);
+		break;
+	case eHT_CHANNEL_WIDTH_160MHZ:
+	default:
+		/* Todo, please add related codes if support 160MHZ or others */
+		hdd_err("unsupport ch_width %d", ch_width);
+		break;
 	}
+
 }
+#else
+static inline void
+hdd_update_chandef(hdd_adapter_t *hostapd_adapter,
+		struct cfg80211_chan_def *chandef,
+		ePhyChanBondState cb_mode)
+{
+}
+#endif
 
 /**
  * hdd_chan_change_notify() - Function to notify hostapd about channel change
@@ -642,7 +727,7 @@ CDF_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter,
 		return CDF_STATUS_E_FAILURE;
 	}
 
-	phy_mode = sme_get_phy_mode(hal);
+	phy_mode = hdd_sap_get_phymode(hostapd_adapter);
 
 	if (oper_chan <= 14)
 		cb_mode = sme_get_cb_phy_state_from_cb_ini_value(
@@ -670,8 +755,15 @@ CDF_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter,
 		break;
 	}
 
+	hdd_info("%s: phy_mode %d cb_mode %d chann_type %d oper_chan %d",
+		__func__, phy_mode, cb_mode, channel_type, oper_chan);
+
 	cfg80211_chandef_create(&chandef, chan, channel_type);
 
+	if ((phy_mode == eCSR_DOT11_MODE_11ac) ||
+	    (phy_mode == eCSR_DOT11_MODE_11ac_ONLY))
+		hdd_update_chandef(hostapd_adapter, &chandef, cb_mode);
+
 	cfg80211_ch_switch_notify(dev, &chandef);
 
 	return CDF_STATUS_SUCCESS;
@@ -999,7 +1091,7 @@ CDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 		wrqu.data.length = strlen(startBssEvent);
 		we_event = IWEVCUSTOM;
 		we_custom_event_generic = we_custom_start_event;
-		cds_dump_concurrency_info(pHddCtx);
+		cds_dump_concurrency_info();
 		/* Send SCC/MCC Switching event to IPA */
 		hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
 		break;          /* Event will be sent after Switch-Case stmt */
@@ -1309,9 +1401,7 @@ CDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 					(const u8 *)&pSapEvent->sapevt.
 					sapStationAssocReassocCompleteEvent.ies[0];
 				staInfo.assoc_req_ies_len = iesLen;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 31))
 				staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
-#endif
 				cfg80211_new_sta(dev,
 						 (const u8 *)&pSapEvent->sapevt.
 						 sapStationAssocReassocCompleteEvent.
@@ -1487,13 +1577,12 @@ CDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 			     WPSPBCProbeReq.probeReqIE,
 			     pHddApCtx->WPSPBCProbeReq.probeReqIELen);
 
-		cdf_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr,
-			     pSapEvent->sapevt.sapPBCProbeReqEvent.
-			     WPSPBCProbeReq.peerMacAddr,
-			     CDF_MAC_ADDR_SIZE);
+		cdf_copy_macaddr(&pHddApCtx->WPSPBCProbeReq.peer_macaddr,
+			     &pSapEvent->sapevt.sapPBCProbeReqEvent.
+			     WPSPBCProbeReq.peer_macaddr);
 		hddLog(LOG1, "WPS PBC probe req " MAC_ADDRESS_STR,
 		       MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.
-				      peerMacAddr));
+				      peer_macaddr.bytes));
 		memset(&wreq, 0, sizeof(wreq));
 		wreq.data.length = strlen(message);             /* This is length of message */
 		wireless_send_event(dev, IWEVCUSTOM, &wreq,
@@ -1522,17 +1611,6 @@ CDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 		cdf_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);        /* Release caller allocated memory here */
 		pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
 		return CDF_STATUS_SUCCESS;
-	case eSAP_INDICATE_MGMT_FRAME:
-		hdd_indicate_mgmt_frame(pHostapdAdapter,
-					pSapEvent->sapevt.sapManagementFrameInfo.
-					nFrameLength,
-					pSapEvent->sapevt.sapManagementFrameInfo.
-					pbFrames,
-					pSapEvent->sapevt.sapManagementFrameInfo.
-					frameType,
-					pSapEvent->sapevt.sapManagementFrameInfo.
-					rxChan, 0);
-		return CDF_STATUS_SUCCESS;
 	case eSAP_REMAIN_CHAN_READY:
 		hdd_remain_chan_ready_handler(pHostapdAdapter,
 			pSapEvent->sapevt.sap_roc_ind.scan_id);
@@ -1716,7 +1794,8 @@ CDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 		  FL("Channel change indication from peer for channel %d"),
 				pSapEvent->sapevt.sap_chan_cng_ind.new_chan);
 		if (hdd_softap_set_channel_change(dev,
-			 pSapEvent->sapevt.sap_chan_cng_ind.new_chan))
+			 pSapEvent->sapevt.sap_chan_cng_ind.new_chan,
+			 CH_WIDTH_MAX))
 			return CDF_STATUS_E_FAILURE;
 		else
 			return CDF_STATUS_SUCCESS;
@@ -1795,7 +1874,7 @@ stopbss:
 		we_custom_event_generic = we_custom_event;
 		wireless_send_event(dev, we_event, &wrqu,
 				    (char *)we_custom_event_generic);
-		cds_dump_concurrency_info(pHddCtx);
+		cds_dump_concurrency_info();
 		/* Send SCC/MCC Switching event to IPA */
 		hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
 	}
@@ -1908,10 +1987,13 @@ int hdd_softap_unpack_ie(tHalHandle halHandle,
  *
  * @dev: pointer to the net device.
  * @target_channel: target channel number.
+ * @target_bw: Target bandwidth to move.
+ * If no bandwidth is specified, the value is CH_WIDTH_MAX
  *
  * Return: 0 for success, non zero for failure
  */
-int hdd_softap_set_channel_change(struct net_device *dev, int target_channel)
+int hdd_softap_set_channel_change(struct net_device *dev, int target_channel,
+				 phy_ch_width target_bw)
 {
 	CDF_STATUS status;
 	int ret = 0;
@@ -1932,6 +2014,13 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel)
 		return ret;
 	}
 
+	ret = hdd_validate_channel_and_bandwidth(pHostapdAdapter,
+						target_channel, target_bw);
+	if (ret) {
+		hdd_err("Invalid CH and BW combo");
+		return ret;
+	}
+
 	sta_adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
 	/*
 	 * conc_custom_rule1:
@@ -1975,12 +2064,13 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel)
 		p_cds_context,
 #endif
 		(uint32_t)
-		target_channel);
+		target_channel,
+		target_bw);
 
 	if (CDF_STATUS_SUCCESS != status) {
 		hddLog(LOGE,
-		       FL("SAP set channel failed for channel = %d"),
-		       target_channel);
+		       FL("SAP set channel failed for channel = %d, bw:%d"),
+		       target_channel, target_bw);
 		/*
 		 * If channel change command fails then clear the
 		 * radar found flag and also restart the netif
@@ -2302,7 +2392,8 @@ static __iw_softap_setparam(struct net_device *dev,
 			hddLog(LOG1,
 			       "SET Channel Change to new channel= %d",
 			       set_value);
-			ret = hdd_softap_set_channel_change(dev, set_value);
+			ret = hdd_softap_set_channel_change(dev, set_value,
+								CH_WIDTH_MAX);
 		} else {
 			hddLog(LOGE,
 			       FL("Channel Change Failed, Device in test mode"));
@@ -3631,10 +3722,10 @@ static int __iw_softap_get_channel_list(struct net_device *dev,
 	       curBand, bandStartChannel, bandEndChannel);
 
 	for (i = bandStartChannel; i <= bandEndChannel; i++) {
-		if ((CHANNEL_STATE_ENABLE == reg_channels[i].enabled) ||
-		    (CHANNEL_STATE_DFS == reg_channels[i].enabled)) {
+		if ((CHANNEL_STATE_ENABLE == CDS_CHANNEL_STATE(i)) ||
+		    (CHANNEL_STATE_DFS == CDS_CHANNEL_STATE(i))) {
 			channel_list->channels[num_channels] =
-				rf_channels[i].channelNum;
+				CDS_CHANNEL_NUM(i);
 			num_channels++;
 		}
 	}
@@ -3766,9 +3857,8 @@ int __iw_get_wpspbc_probe_req_ies(struct net_device *dev,
 	cdf_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
 		     pHddApCtx->WPSPBCProbeReq.probeReqIE,
 		     WPSPBCProbeReqIEs.probeReqIELen);
-	cdf_mem_copy(&WPSPBCProbeReqIEs.macaddr,
-		     pHddApCtx->WPSPBCProbeReq.peerMacAddr,
-		     CDF_MAC_ADDR_SIZE);
+	cdf_copy_macaddr(&WPSPBCProbeReqIEs.macaddr,
+			 &pHddApCtx->WPSPBCProbeReq.peer_macaddr);
 	if (copy_to_user(wrqu->data.pointer,
 			 (void *)&WPSPBCProbeReqIEs,
 			 sizeof(WPSPBCProbeReqIEs))) {
@@ -3776,8 +3866,8 @@ int __iw_get_wpspbc_probe_req_ies(struct net_device *dev,
 		return -EFAULT;
 	}
 	wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
-	hddLog(LOG1, FL("Macaddress : " MAC_ADDRESS_STR),
-	       MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr));
+	hdd_info("Macaddress : " MAC_ADDRESS_STR,
+	       MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr.bytes));
 	up(&pHddApCtx->semWpsPBCOverlapInd);
 	EXIT();
 	return 0;
@@ -4980,8 +5070,7 @@ __iw_softap_stopbss(struct net_device *dev,
 			}
 		}
 		clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
-		cds_decr_session_set_pcl(hdd_ctx,
-					     pHostapdAdapter->device_mode,
+		cds_decr_session_set_pcl(pHostapdAdapter->device_mode,
 					     pHostapdAdapter->sessionId);
 	}
 	EXIT();
@@ -6386,10 +6475,6 @@ static int wlan_hdd_set_channel(struct wiphy *wiphy,
 					smeConfig.csrConfig.
 						channelBondingMode5GHz =
 					eCSR_INI_SINGLE_CHANNEL_CENTERED;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-				sap_config->ch_width_orig =
-						eHT_CHANNEL_WIDTH_20MHZ;
-#endif
 				sap_config->sec_ch = 0;
 				break;
 
@@ -6639,19 +6724,6 @@ static void wlan_hdd_add_extra_ie(hdd_adapter_t *pHostapdAdapter,
 	return;
 }
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
-/**
- * wlan_hdd_cfg80211_alloc_new_beacon() - alloc beacon in ap mode
- * @pAdapter: Pointer to hostapd adapter
- * @ppBeacon: Pointer to pointer to beacon data
- * @params: Pointer to beacon parameters
- *
- * Return: 0 for success non-zero for failure
- */
-int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
-				       beacon_data_t **ppBeacon,
-				       struct beacon_parameters *params)
-#else
 /**
  * wlan_hdd_cfg80211_alloc_new_beacon() - alloc beacon in ap mode
  * @pAdapter: Pointer to hostapd adapter
@@ -6665,7 +6737,6 @@ int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
 				       beacon_data_t **ppBeacon,
 				       struct cfg80211_beacon_data *params,
 				       int dtim_period)
-#endif
 {
 	int size;
 	beacon_data_t *beacon = NULL;
@@ -6729,17 +6800,10 @@ int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
 		       FL("Mem allocation for beacon failed"));
 		return -ENOMEM;
 	}
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
-	if (params->dtim_period)
-		beacon->dtim_period = params->dtim_period;
-	else if (old)
-		beacon->dtim_period = old->dtim_period;
-#else
 	if (dtim_period)
 		beacon->dtim_period = dtim_period;
 	else if (old)
 		beacon->dtim_period = old->dtim_period;
-#endif
 	/* -----------------------------------------------
 	 * | head | tail | proberesp_ies | assocresp_ies |
 	 * -----------------------------------------------
@@ -7225,17 +7289,6 @@ setup_acs_overrides:
 	return 0;
 }
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
-/**
- * wlan_hdd_cfg80211_start_bss() - start bss
- * @pHostapdAdapter: Pointer to hostapd adapter
- * @params: Pointer to start bss beacon parameters
- *
- * Return: 0 for success non-zero for failure
- */
-static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
-				       struct beacon_parameters *params)
-#else
 /**
  * wlan_hdd_cfg80211_start_bss() - start bss
  * @pHostapdAdapter: Pointer to hostapd adapter
@@ -7250,7 +7303,6 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
 				       struct cfg80211_beacon_data *params,
 				       const u8 *ssid, size_t ssid_len,
 				       enum nl80211_hidden_ssid hidden_ssid)
-#endif
 {
 	tsap_Config_t *pConfig;
 	beacon_data_t *pBeacon = NULL;
@@ -7278,7 +7330,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
 	uint16_t prev_rsn_length = 0;
 	ENTER();
 
-	if (cds_is_connection_in_progress(pHddCtx)) {
+	if (cds_is_connection_in_progress()) {
 		hdd_err("Can't start BSS: connection is in progress");
 		return -EINVAL;
 	}
@@ -7509,33 +7561,6 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
 
 	pConfig->SSIDinfo.ssidHidden = false;
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
-	if (params->ssid != NULL) {
-		cdf_mem_copy(pConfig->SSIDinfo.ssid.ssId, params->ssid,
-			     params->ssid_len);
-		pConfig->SSIDinfo.ssid.length = params->ssid_len;
-
-		switch (params->hidden_ssid) {
-		case NL80211_HIDDEN_SSID_NOT_IN_USE:
-			hddLog(LOG1, "HIDDEN_SSID_NOT_IN_USE");
-			pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE;
-			break;
-		case NL80211_HIDDEN_SSID_ZERO_LEN:
-			hddLog(LOG1, "HIDDEN_SSID_ZERO_LEN");
-			pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN;
-			break;
-		case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
-			hddLog(LOG1, "HIDDEN_SSID_ZERO_CONTENTS");
-			pConfig->SSIDinfo.ssidHidden =
-				eHIDDEN_SSID_ZERO_CONTENTS;
-			break;
-		default:
-			hddLog(LOGE, "Wrong hidden_ssid param %d",
-			       params->hidden_ssid);
-			break;
-		}
-	}
-#else
 	if (ssid != NULL) {
 		cdf_mem_copy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
 		pConfig->SSIDinfo.ssid.length = ssid_len;
@@ -7559,7 +7584,6 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
 			break;
 		}
 	}
-#endif
 
 	cdf_mem_copy(pConfig->self_macaddr.bytes,
 		     pHostapdAdapter->macAddressCurrent.bytes,
@@ -7655,16 +7679,6 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
 		sme_config.csrConfig.WMMSupportMode = eCsrRoamWmmNoQos;
 	sme_update_config(pHddCtx->hHal, &sme_config);
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-	/* Linux kernel < 3.8 does not support ch width param. So for
-	 * 11AC get from ch width from ini file only if ht40 is enabled
-	 * VHT80 depends on HT40 config.
-	 */
-	if (pConfig->SapHw_mode == eCSR_DOT11_MODE_11ac)
-		if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_40)
-			pConfig->ch_width_orig = iniConfig->vhtChannelWidth;
-#endif
-
 	if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_80P80) {
 		if (pHddCtx->isVHT80Allowed == false)
 			pConfig->ch_width_orig = CH_WIDTH_40MHZ;
@@ -7740,7 +7754,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
 		return 0;
 	}
 
-	if (!cds_allow_concurrency(pHddCtx,
+	if (!cds_allow_concurrency(
 				cds_convert_device_mode_to_hdd_type(
 				pHostapdAdapter->device_mode),
 				pConfig->channel, HW_MODE_20_MHZ)) {
@@ -7749,7 +7763,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
 		return -EINVAL;
 	}
 
-	if (!cds_set_connection_in_progress(pHddCtx, true)) {
+	if (!cds_set_connection_in_progress(true)) {
 		hdd_err("Can't start BSS: set connnection in progress failed");
 		return -EINVAL;
 	}
@@ -7772,7 +7786,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
 		pHostapdAdapter->dev);
 	if (!CDF_IS_STATUS_SUCCESS(status)) {
 		wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
-		cds_set_connection_in_progress(pHddCtx, false);
+		cds_set_connection_in_progress(false);
 		hddLog(LOGE, FL("SAP Start Bss fail"));
 		return -EINVAL;
 	}
@@ -7787,7 +7801,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
 	if (!CDF_IS_STATUS_SUCCESS(status)) {
 		hddLog(LOGE,
 			FL("ERROR: HDD cdf wait for single_event failed!!"));
-		cds_set_connection_in_progress(pHddCtx, false);
+		cds_set_connection_in_progress(false);
 		sme_get_command_q_status(hHal);
 #ifdef WLAN_FEATURE_MBSSID
 		wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
@@ -7801,7 +7815,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
 	set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
 	/* Initialize WMM configuation */
 	hdd_wmm_init(pHostapdAdapter);
-	cds_incr_active_session(pHddCtx, pHostapdAdapter->device_mode,
+	cds_incr_active_session(pHostapdAdapter->device_mode,
 					 pHostapdAdapter->sessionId);
 #ifdef DHCP_SERVER_OFFLOAD
 	if (iniConfig->enableDHCPServerOffload)
@@ -7822,216 +7836,13 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
 	}
 #endif
 
-	cds_set_connection_in_progress(pHddCtx, false);
+	cds_set_connection_in_progress(false);
 	pHostapdState->bCommit = true;
 	EXIT();
 
 	return 0;
 }
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
-/**
- * __wlan_hdd_cfg80211_add_beacon() - add beacon in soft ap mode
- * @wiphy: Pointer to wiphy structure
- * @dev: Pointer to net_device structure
- * @params: Pointer to add beacon parameters
- *
- * Return: 0 for success non-zero for failure
- */
-static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
-					struct net_device *dev,
-					struct beacon_parameters *params)
-{
-	hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
-	hdd_context_t *pHddCtx;
-	int status;
-
-	ENTER();
-
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
-		hddLog(LOGE, FL("Command not allowed in FTM mode"));
-		return -EINVAL;
-	}
-
-	MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
-			 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
-			 pAdapter->sessionId, params->interval));
-	hddLog(LOG2, FL("Device mode %s(%d)"),
-		hdd_device_mode_to_string(pAdapter->device_mode),
-		pAdapter->device_mode);
-
-	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-	status = wlan_hdd_validate_context(pHddCtx);
-
-	if (0 != status)
-		return status;
-
-	if (!cds_allow_concurrency(pHddCtx,
-				cds_convert_device_mode_to_hdd_type(
-				pAdapter->device_mode), 0, HDD_20_MHZ)) {
-		hddLog(LOGE,
-			FL("This concurrency combination is not allowed"));
-		return -EINVAL;
-	}
-
-	if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
-	    (pAdapter->device_mode == WLAN_HDD_P2P_GO)) {
-		beacon_data_t *old, *new;
-
-		old = pAdapter->sessionCtx.ap.beacon;
-
-		if (old) {
-			hddLog(LOGW,
-				FL("already beacon info added to session(%d)"),
-				pAdapter->sessionId);
-			return -EALREADY;
-		}
-
-		status =
-			wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
-							   &new, params);
-		if (status != CDF_STATUS_SUCCESS) {
-			hddLog(LOGE,
-				FL("Error!!! Allocating the new beacon"));
-			return -EINVAL;
-		}
-
-		pAdapter->sessionCtx.ap.beacon = new;
-
-		status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
-		if (0 != status) {
-			pAdapter->sessionCtx.ap.beacon = NULL;
-			kfree(new);
-		}
-	}
-
-	EXIT();
-	return status;
-}
-
-/**
- * wlan_hdd_cfg80211_add_beacon() - add beacon in sap mode
- * @wiphy: Pointer to wiphy
- * @dev: Pointer to netdev
- * @param: Pointer to beacon parameters
- *
- * Return: zero for success non-zero for failure
- */
-int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
-				struct net_device *dev,
-				struct beacon_parameters *params)
-{
-	int ret;
-
-	cds_ssr_protect(__func__);
-	ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
-	cds_ssr_unprotect(__func__);
-
-	return ret;
-}
-
-/**
- * __wlan_hdd_cfg80211_set_beacon() - set beacon in soft ap mode
- * @wiphy: Pointer to wiphy structure
- * @dev: Pointer to net_device structure
- * @params: Pointer to set beacon parameters
- *
- * Return: 0 for success non-zero for failure
- */
-static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
-					struct net_device *dev,
-					struct beacon_parameters *params)
-{
-	hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
-	hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-	hdd_context_t *pHddCtx;
-	int status;
-
-	ENTER();
-
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
-		hddLog(LOGE, FL("Command not allowed in FTM mode"));
-		return -EINVAL;
-	}
-
-	MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
-			 TRACE_CODE_HDD_CFG80211_SET_BEACON,
-			 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
-	hddLog(LOG1, FL("Device_mode %s(%d)"),
-		hdd_device_mode_to_string(pAdapter->device_mode),
-		pAdapter->device_mode);
-
-	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
-	status = wlan_hdd_validate_context(pHddCtx);
-
-	if (0 != status)
-		return status;
-
-	if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
-	    (pAdapter->device_mode == WLAN_HDD_P2P_GO)) {
-		beacon_data_t *old, *new;
-
-		old = pAdapter->sessionCtx.ap.beacon;
-
-		if (!old) {
-			hddLog(LOGE,
-				FL("session(%d) old and new heads points to NULL"),
-				pAdapter->sessionId);
-			return -ENOENT;
-		}
-
-		status =
-			wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
-							   &new, params);
-
-		if (status != CDF_STATUS_SUCCESS) {
-			hddLog(LOGE,
-				FL("Error!!! Allocating the new beacon"));
-			return -EINVAL;
-		}
-
-		pAdapter->sessionCtx.ap.beacon = new;
-		status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
-	}
-
-	EXIT();
-	return status;
-}
-
-/**
- * wlan_hdd_cfg80211_set_beacon() - set beacon in sap mode
- * @wiphy: Pointer to wiphy
- * @dev: Pointer to netdev
- * @param: Pointer to beacon parameters
- *
- * Return: zero for success non-zero for failure
- */
-int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
-				struct net_device *dev,
-				struct beacon_parameters *params)
-{
-	int ret;
-
-	cds_ssr_protect(__func__);
-	ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
-	cds_ssr_unprotect(__func__);
-
-	return ret;
-}
-
-#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) */
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
-/**
- * __wlan_hdd_cfg80211_del_beacon() - stop soft ap
- * @wiphy: Pointer to wiphy structure
- * @dev: Pointer to net_device structure
- *
- * Return: 0 for success non-zero for failure
- */
-static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
-					struct net_device *dev)
-#else
 /**
  * __wlan_hdd_cfg80211_stop_ap() - stop soft ap
  * @wiphy: Pointer to wiphy structure
@@ -8041,7 +7852,6 @@ static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
  */
 static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
 					struct net_device *dev)
-#endif
 {
 	hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	hdd_context_t *pHddCtx = NULL;
@@ -8057,7 +7867,7 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -8166,8 +7976,7 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
 		}
 		clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
 		/*BSS stopped, clear the active sessions for this device mode*/
-		cds_decr_session_set_pcl(pHddCtx,
-						pAdapter->device_mode,
+		cds_decr_session_set_pcl(pAdapter->device_mode,
 						pAdapter->sessionId);
 		pAdapter->sessionCtx.ap.beacon = NULL;
 		kfree(old);
@@ -8211,7 +8020,6 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
 	return ret;
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
 /**
  * wlan_hdd_get_channel_bw() - get channel bandwidth
  * @width: input channel width in nl80211_chan_width value
@@ -8247,28 +8055,7 @@ static enum hw_mode_bandwidth wlan_hdd_get_channel_bw(
 
 	return ch_bw;
 }
-#endif
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(WITH_BACKPORTS)
-/**
- * wlan_hdd_cfg80211_del_beacon() - delete beacon in sap mode
- * @wiphy: Pointer to wiphy
- * @dev: Pointer to netdev
- *
- * Return: zero for success non-zero for failure
- */
-int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
-				struct net_device *dev)
-{
-	int ret;
-
-	cds_ssr_protect(__func__);
-	ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
-	cds_ssr_unprotect(__func__);
-
-	return ret;
-}
-#else
 /**
  * wlan_hdd_cfg80211_stop_ap() - stop sap
  * @wiphy: Pointer to wiphy
@@ -8287,9 +8074,7 @@ int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
 
 	return ret;
 }
-#endif
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 3, 0))
 /**
  * __wlan_hdd_cfg80211_start_ap() - start soft ap mode
  * @wiphy: Pointer to wiphy structure
@@ -8310,7 +8095,7 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -8333,16 +8118,12 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
 	       hdd_device_mode_to_string(pAdapter->device_mode),
 	       pAdapter->device_mode);
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
 	channel_width = wlan_hdd_get_channel_bw(params->chandef.width);
 	channel = ieee80211_frequency_to_channel(
 				params->chandef.chan->center_freq);
-#else
-	channel_width = HW_MODE_20_MHZ;
-	channel = 0;
-#endif
+
 	/* check if concurrency is allowed */
-	if (!cds_allow_concurrency(pHddCtx,
+	if (!cds_allow_concurrency(
 				cds_convert_device_mode_to_hdd_type(
 				pAdapter->device_mode),
 				channel,
@@ -8376,9 +8157,7 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
 	    || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
 	    ) {
 		beacon_data_t *old, *new;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
 		enum nl80211_channel_type channel_type;
-#endif
 
 		old = pAdapter->sessionCtx.ap.beacon;
 
@@ -8421,10 +8200,8 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
 			pAdapter->sessionCtx.ap.sapConfig.authType =
 				eSAP_AUTO_SWITCH;
 		}
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
 		pAdapter->sessionCtx.ap.sapConfig.ch_width_orig =
 						params->chandef.width;
-#endif
 		status =
 			wlan_hdd_cfg80211_start_bss(pAdapter,
 				&params->beacon,
@@ -8476,7 +8253,7 @@ static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -8541,5 +8318,3 @@ int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
 
 	return ret;
 }
-
-#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(3, 3, 0)) */

+ 3 - 18
core/hdd/src/wlan_hdd_hostapd.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -58,7 +58,8 @@ eCsrAuthType
 hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4]);
 
 int hdd_softap_set_channel_change(struct net_device *dev,
-					  int target_channel);
+				int target_channel,
+				phy_ch_width target_bw);
 
 eCsrEncryptionType
 hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4]);
@@ -99,29 +100,13 @@ CDF_STATUS hdd_set_sap_ht2040_mode(hdd_adapter_t *pHostapdAdapter,
 				   uint8_t channel_type);
 #endif
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
-int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
-				 struct net_device *dev,
-				 struct beacon_parameters *params);
 
-int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
-				 struct net_device *dev,
-				 struct beacon_parameters *params);
-#endif
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
-int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
-				 struct net_device *dev);
-#else
 int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
 			      struct net_device *dev);
-#endif
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 3, 0))
 int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
 			       struct net_device *dev,
 			       struct cfg80211_ap_settings *params);
-#endif
 
 int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
 				    struct net_device *dev,

+ 139 - 43
core/hdd/src/wlan_hdd_ioctl.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -34,6 +34,7 @@
 #include "wlan_hdd_power.h"
 #include "wlan_hdd_driver_ops.h"
 #include "cds_concurrency.h"
+#include "wlan_hdd_hostapd.h"
 
 #include "wlan_hdd_p2p.h"
 #include <linux/ctype.h>
@@ -260,7 +261,6 @@ CDF_STATUS hdd_get_tsm_stats(hdd_adapter_t *adapter,
 }
 #endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
 
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 static void hdd_get_band_helper(hdd_context_t *hdd_ctx, int *pBand)
 {
 	eCsrBand band = -1;
@@ -520,9 +520,6 @@ static int hdd_parse_reassoc_command_v1_data(const uint8_t *pValue,
 	return 0;
 }
 
-#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
-
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 /**
  * hdd_reassoc() - perform a userspace-directed reassoc
  * @adapter:	Adapter upon which the command was received
@@ -695,9 +692,6 @@ static int hdd_parse_reassoc(hdd_adapter_t *adapter, const char *command)
 	return ret;
 }
 
-#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
-
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 /**
  * hdd_sendactionframe() - send a userspace-supplied action frame
  * @adapter:	Adapter upon which the command was received
@@ -836,15 +830,9 @@ hdd_sendactionframe(hdd_adapter_t *adapter, const uint8_t *bssid,
 	ret = wlan_hdd_mgmt_tx(NULL, &adapter->wdev, &params, &cookie);
 #else
 	ret = wlan_hdd_mgmt_tx(NULL,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 			       &(adapter->wdev),
-#else
-			       adapter->dev,
-#endif
 			       &chan, 0,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-			       NL80211_CHAN_HT20, 1,
-#endif
+
 			       dwell_time, frame, frame_len, 1, 1, &cookie);
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
 
@@ -979,9 +967,6 @@ hdd_parse_sendactionframe(hdd_adapter_t *adapter, const char *command)
 	return ret;
 }
 
-#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
-
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 /**
  * hdd_parse_channellist() - HDD Parse channel list
  * @pValue:		Pointer to input channel list
@@ -1277,7 +1262,6 @@ hdd_parse_set_roam_scan_channels(hdd_adapter_t *adapter, const char *command)
 
 	return ret;
 }
-#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
 
 #if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
 /**
@@ -1723,7 +1707,7 @@ static int hdd_set_app_type1_parser(hdd_adapter_t *adapter,
 	tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(adapter);
 	char id[20], password[20];
 	tSirAppType1Params params;
-	int rc, i;
+	int rc;
 
 	rc = wlan_hdd_validate_context(hdd_ctx);
 	if (0 != rc) {
@@ -1739,9 +1723,7 @@ static int hdd_set_app_type1_parser(hdd_adapter_t *adapter,
 
 	memset(&params, 0, sizeof(tSirAppType1Params));
 	params.vdev_id = adapter->sessionId;
-	for (i = 0; i < ETHER_ADDR_LEN; i++)
-		params.wakee_mac_addr[i] =
-			adapter->macAddressCurrent.bytes[i];
+	cdf_copy_macaddr(&params.wakee_mac_addr, &adapter->macAddressCurrent);
 
 	params.id_length = strlen(id);
 	cdf_mem_copy(params.identification_id, id, params.id_length);
@@ -1750,7 +1732,7 @@ static int hdd_set_app_type1_parser(hdd_adapter_t *adapter,
 
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
 		  "%s: %d %pM %.8s %u %.16s %u",
-		  __func__, params.vdev_id, params.wakee_mac_addr,
+		  __func__, params.vdev_id, params.wakee_mac_addr.bytes,
 		  params.identification_id, params.id_length,
 		  params.password, params.pass_length);
 
@@ -1782,7 +1764,7 @@ static int hdd_set_app_type2_parser(hdd_adapter_t *adapter,
 	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(adapter);
 	char mac_addr[20], rc4_key[20];
-	unsigned int gateway_mac[6], i;
+	unsigned int gateway_mac[CDF_MAC_ADDR_SIZE];
 	tSirAppType2Params params;
 	int ret;
 
@@ -1831,8 +1813,8 @@ static int hdd_set_app_type2_parser(hdd_adapter_t *adapter,
 		return -EINVAL;
 	}
 
-	for (i = 0; i < ETHER_ADDR_LEN; i++)
-		params.gateway_mac[i] = (uint8_t) gateway_mac[i];
+	cdf_mem_copy(&params.gateway_mac.bytes, (uint8_t *) &gateway_mac,
+			CDF_MAC_ADDR_SIZE);
 
 	params.rc4_key_len = strlen(rc4_key);
 	cdf_mem_copy(params.rc4_key, rc4_key, params.rc4_key_len);
@@ -2120,15 +2102,15 @@ static void hdd_get_link_status_cb(uint8_t status, void *context)
 static int wlan_hdd_get_link_status(hdd_adapter_t *adapter)
 {
 
-	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	hdd_station_ctx_t *pHddStaCtx =
 				WLAN_HDD_GET_STATION_CTX_PTR(adapter);
 	struct statsContext context;
 	CDF_STATUS hstatus;
 	unsigned long rc;
 
-	if (hdd_ctx->isLogpInProgress) {
-		hddLog(LOGW, FL("LOGP in Progress. Ignore!!!"));
+	if (cds_is_driver_recovering()) {
+		hdd_warn("Recovery in Progress. State: 0x%x Ignore!!!",
+			 cds_get_driver_state());
 		return 0;
 	}
 
@@ -4669,7 +4651,7 @@ static int drv_cmd_miracast(hdd_adapter_t *adapter,
 		return -EBUSY;
 	}
 
-	if (cds_is_mcc_in_24G(pHddCtx))
+	if (cds_is_mcc_in_24G())
 		return cds_set_mas(adapter, filterType);
 
 exit:
@@ -5308,6 +5290,12 @@ static int drv_cmd_tdls_off_channel(hdd_adapter_t *adapter,
 	if (ret != 1)
 		return -EINVAL;
 
+	if (CDS_IS_DFS_CH(set_value)) {
+		hdd_err("DFS channel %d is passed for hdd_set_tdls_offchannel",
+		    set_value);
+		return -EINVAL;
+	}
+
 	hddLog(LOG1, FL("Tdls offchannel num: %d"), set_value);
 
 	ret = hdd_set_tdls_offchannel(hdd_ctx, set_value);
@@ -5956,6 +5944,123 @@ static int drv_cmd_set_fcc_channel(hdd_adapter_t *adapter,
 	return ret;
 }
 
+/**
+ * hdd_parse_set_channel_switch_command() - Parse and validate CHANNEL_SWITCH
+ * command
+ * @value: Pointer to the command
+ * @chan_number: Pointer to the channel number
+ * @chan_bw: Pointer to the channel bandwidth
+ *
+ * Parses and provides the channel number and channel width from the input
+ * command which is expected to be of the format: CHANNEL_SWITCH <CH> <BW>
+ * <CH> is channel number to move (where 1 = channel 1, 149 = channel 149, ...)
+ * <BW> is bandwidth to move (where 20 = BW 20, 40 = BW 40, 80 = BW 80)
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int hdd_parse_set_channel_switch_command(uint8_t *value,
+					 uint32_t *chan_number,
+					 uint32_t *chan_bw)
+{
+	const uint8_t *in_ptr = value;
+	int ret;
+
+	in_ptr = strnchr(value, strlen(value), SPACE_ASCII_VALUE);
+
+	/* no argument after the command */
+	if (NULL == in_ptr) {
+		hdd_err("No argument after the command");
+		return -EINVAL;
+	}
+
+	/* no space after the command */
+	if (SPACE_ASCII_VALUE != *in_ptr) {
+		hdd_err("No space after the command ");
+		return -EINVAL;
+	}
+
+	/* remove empty spaces and move the next argument */
+	while ((SPACE_ASCII_VALUE == *in_ptr) && ('\0' != *in_ptr))
+		in_ptr++;
+
+	/* no argument followed by spaces */
+	if ('\0' == *in_ptr) {
+		hdd_err("No argument followed by spaces");
+		return -EINVAL;
+	}
+
+	/* get the two arguments: channel number and bandwidth */
+	ret = sscanf(in_ptr, "%u %u", chan_number, chan_bw);
+	if (ret != 2) {
+		hdd_err("Arguments retrieval from cmd string failed");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * drv_cmd_set_channel_switch() - Switch SAP/P2P-GO operating channel
+ * @adapter: HDD adapter
+ * @hdd_ctx: HDD context
+ * @command: Pointer to the input command CHANNEL_SWITCH
+ * @command_len: Command len
+ * @priv_data: Private data
+ *
+ * Handles private IOCTL CHANNEL_SWITCH command to switch the operating channel
+ * of SAP/P2P-GO
+ *
+ * Return: 0 for success, non-zero for failure
+ */
+static int drv_cmd_set_channel_switch(hdd_adapter_t *adapter,
+				   hdd_context_t *hdd_ctx,
+				   uint8_t *command,
+				   uint8_t command_len,
+				   hdd_priv_data_t *priv_data)
+{
+	struct net_device *dev = adapter->dev;
+	int status;
+	uint32_t chan_number = 0, chan_bw = 0;
+	uint8_t *value = command;
+	phy_ch_width width;
+
+	if ((adapter->device_mode != WLAN_HDD_P2P_GO) &&
+		(adapter->device_mode != WLAN_HDD_SOFTAP)) {
+		hdd_err("IOCTL CHANNEL_SWITCH not supported for mode %d",
+			adapter->device_mode);
+		return -EINVAL;
+	}
+
+	status = hdd_parse_set_channel_switch_command(value,
+							&chan_number, &chan_bw);
+	if (status) {
+		hdd_err("Invalid CHANNEL_SWITCH command");
+		return status;
+	}
+
+	if ((chan_bw != 20) && (chan_bw != 40) && (chan_bw != 80)) {
+		hdd_err("BW %d is not allowed for CHANNEL_SWITCH", chan_bw);
+		return -EINVAL;
+	}
+
+	if (chan_bw == 80)
+		width = CH_WIDTH_80MHZ;
+	else if (chan_bw == 40)
+		width = CH_WIDTH_40MHZ;
+	else
+		width = CH_WIDTH_20MHZ;
+
+	hdd_info("CH:%d BW:%d", chan_number, chan_bw);
+
+	status = hdd_softap_set_channel_change(dev, chan_number, width);
+	if (status) {
+		hdd_err("Set channel change fail");
+		return status;
+	}
+
+	return 0;
+}
+
 /*
  * The following table contains all supported WLAN HDD
  * IOCTL driver commands and the handler for each of them.
@@ -5971,23 +6076,16 @@ static const hdd_drv_cmd_t hdd_drv_cmds[] = {
 	{"SET_AP_WPS_P2P_IE",         drv_cmd_dummy},
 	{"BTCOEXSCAN",                drv_cmd_dummy},
 	{"RXFILTER",                  drv_cmd_dummy},
-#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
 	{"SETROAMTRIGGER",            drv_cmd_set_roam_trigger},
 	{"GETROAMTRIGGER",            drv_cmd_get_roam_trigger},
 	{"SETROAMSCANPERIOD",         drv_cmd_set_roam_scan_period},
 	{"GETROAMSCANPERIOD",         drv_cmd_get_roam_scan_period},
 	{"SETROAMSCANREFRESHPERIOD",  drv_cmd_set_roam_scan_refresh_period},
 	{"GETROAMSCANREFRESHPERIOD",  drv_cmd_get_roam_scan_refresh_period},
-#ifdef FEATURE_WLAN_LFR
 	{"SETROAMMODE",               drv_cmd_set_roam_mode},
 	{"GETROAMMODE",               drv_cmd_get_roam_mode},
-#endif
-#endif
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 	{"SETROAMDELTA",              drv_cmd_set_roam_delta},
 	{"GETROAMDELTA",              drv_cmd_get_roam_delta},
-#endif
-#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
 	{"GETBAND",                   drv_cmd_get_band},
 	{"SETROAMSCANCHANNELS",       drv_cmd_set_roam_scan_channels},
 	{"GETROAMSCANCHANNELS",       drv_cmd_get_roam_scan_channels},
@@ -6015,10 +6113,7 @@ static const hdd_drv_cmd_t hdd_drv_cmds[] = {
 	{"GETOPPORTUNISTICRSSIDIFF",  drv_cmd_get_opportunistic_rssi_diff},
 	{"SETROAMRESCANRSSIDIFF",     drv_cmd_set_roam_rescan_rssi_diff},
 	{"GETROAMRESCANRSSIDIFF",     drv_cmd_get_roam_rescan_rssi_diff},
-#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
-#ifdef FEATURE_WLAN_LFR
 	{"SETFASTROAM",               drv_cmd_set_fast_roam},
-#endif
 #ifdef WLAN_FEATURE_VOWIFI_11R
 	{"SETFASTTRANSITION",         drv_cmd_set_fast_transition},
 	{"FASTREASSOC",               drv_cmd_fast_reassoc},
@@ -6070,6 +6165,7 @@ static const hdd_drv_cmd_t hdd_drv_cmds[] = {
 	{"RXFILTER-REMOVE",           drv_cmd_rx_filter_remove},
 	{"RXFILTER-ADD",              drv_cmd_rx_filter_add},
 	{"SET_FCC_CHANNEL",           drv_cmd_set_fcc_channel},
+	{"CHANNEL_SWITCH",            drv_cmd_set_channel_switch},
 };
 
 /**
@@ -6141,7 +6237,7 @@ static int hdd_driver_command(hdd_adapter_t *adapter,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -6279,7 +6375,7 @@ static int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 		goto exit;
 	}
 #if  defined(QCA_WIFI_FTM) && defined(LINUX_QCMBR)
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		if (SIOCIOCTLTX99 == cmd) {
 			ret = wlan_hdd_qcmbr_unified_ioctl(adapter, ifr);
 			goto exit;

+ 87 - 54
core/hdd/src/wlan_hdd_ipa.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1237,21 +1237,11 @@ hdd_ipa_uc_rm_notify_handler(void *context, enum ipa_rm_event event)
 			hdd_ipa_uc_enable_pipes(hdd_ipa);
 		}
 		cdf_mutex_release(&hdd_ipa->ipa_lock);
-		if (hdd_ipa->pending_cons_req) {
-			ipa_rm_notify_completion(IPA_RM_RESOURCE_GRANTED,
-						 IPA_RM_RESOURCE_WLAN_CONS);
-		}
-		hdd_ipa->pending_cons_req = false;
 		break;
 
 	case IPA_RM_RESOURCE_RELEASED:
 		/* Differed RM Released */
 		hdd_ipa->resource_unloading = false;
-		if (hdd_ipa->pending_cons_req) {
-			ipa_rm_notify_completion(IPA_RM_RESOURCE_RELEASED,
-						 IPA_RM_RESOURCE_WLAN_CONS);
-		}
-		hdd_ipa->pending_cons_req = false;
 		break;
 
 	default:
@@ -1377,6 +1367,11 @@ static void hdd_ipa_uc_op_cb(struct op_msg_type *op_msg, void *usr_ctxt)
 		if (HDD_IPA_UC_NUM_WDI_PIPE == hdd_ipa->activated_fw_pipe) {
 			hdd_ipa->resource_loading = false;
 			hdd_ipa_uc_proc_pending_event(hdd_ipa);
+			if (hdd_ipa->pending_cons_req)
+				ipa_rm_notify_completion(
+						IPA_RM_RESOURCE_GRANTED,
+						IPA_RM_RESOURCE_WLAN_CONS);
+			hdd_ipa->pending_cons_req = false;
 		}
 		cdf_mutex_release(&hdd_ipa->ipa_lock);
 	}
@@ -1387,16 +1382,14 @@ static void hdd_ipa_uc_op_cb(struct op_msg_type *op_msg, void *usr_ctxt)
 		hdd_ipa->activated_fw_pipe--;
 		if (!hdd_ipa->activated_fw_pipe) {
 			hdd_ipa_uc_disable_pipes(hdd_ipa);
-			if ((hdd_ipa_is_rm_enabled(hdd_ipa->hdd_ctx)) &&
-			(!ipa_rm_release_resource(IPA_RM_RESOURCE_WLAN_PROD))) {
-				/* Sync return success from IPA
-				* Enable/resume all the PIPEs */
-				hdd_ipa->resource_unloading = false;
-				hdd_ipa_uc_proc_pending_event(hdd_ipa);
-			} else {
-				hdd_ipa->resource_unloading = false;
-				hdd_ipa_uc_proc_pending_event(hdd_ipa);
-			}
+			if (hdd_ipa_is_rm_enabled(hdd_ipa->hdd_ctx))
+				ipa_rm_release_resource(
+					IPA_RM_RESOURCE_WLAN_PROD);
+			/* Sync return success from IPA
+			* Enable/resume all the PIPEs */
+			hdd_ipa->resource_unloading = false;
+			hdd_ipa_uc_proc_pending_event(hdd_ipa);
+			hdd_ipa->pending_cons_req = false;
 		}
 		cdf_mutex_release(&hdd_ipa->ipa_lock);
 	}
@@ -1410,19 +1403,19 @@ static void hdd_ipa_uc_op_cb(struct op_msg_type *op_msg, void *usr_ctxt)
 			  "CE RING BASE: 0x%llx\n"
 			  "CE RING SIZE: %d\n"
 			  "CE REG ADDR : 0x%llx",
-			  hdd_ipa->ce_sr_base_paddr,
+			  (unsigned long long)hdd_ipa->ce_sr_base_paddr,
 			  hdd_ipa->ce_sr_ring_size,
-			  hdd_ipa->ce_reg_paddr);
+			  (unsigned long long)hdd_ipa->ce_reg_paddr);
 		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
 			  "==== IPA_UC WLAN_HOST TX ====\n"
 			  "COMP RING BASE: 0x%llx\n"
 			  "COMP RING SIZE: %d\n"
 			  "NUM ALLOC BUF: %d\n"
 			  "COMP RING DBELL : 0x%llx",
-			  hdd_ipa->tx_comp_ring_base_paddr,
+			  (unsigned long long)hdd_ipa->tx_comp_ring_base_paddr,
 			  hdd_ipa->tx_comp_ring_size,
 			  hdd_ipa->tx_num_alloc_buffer,
-			  hdd_ipa->tx_comp_doorbell_paddr);
+			  (unsigned long long)hdd_ipa->tx_comp_doorbell_paddr);
 		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
 			  "==== IPA_UC WLAN_HOST RX ====\n"
 			  "IND RING BASE: 0x%llx\n"
@@ -1432,13 +1425,13 @@ static void hdd_ipa_uc_op_cb(struct op_msg_type *op_msg, void *usr_ctxt)
 			  "NUM EXCP PKT : %llu\n"
 			  "NUM TX BCMC : %llu\n"
 			  "NUM TX BCMC ERR : %llu",
-			  hdd_ipa->rx_rdy_ring_base_paddr,
+			  (unsigned long long)hdd_ipa->rx_rdy_ring_base_paddr,
 			  hdd_ipa->rx_rdy_ring_size,
-			  hdd_ipa->rx_ready_doorbell_paddr,
-			  hdd_ipa->rx_proc_done_idx_paddr,
+			  (unsigned long long)hdd_ipa->rx_ready_doorbell_paddr,
+			  (unsigned long long)hdd_ipa->rx_proc_done_idx_paddr,
 			  hdd_ipa->stats.num_rx_excep,
 			  hdd_ipa->stats.num_tx_bcmc,
-			  hdd_ipa->stats.num_tx_bcmc_err);
+			  (unsigned long long)hdd_ipa->stats.num_tx_bcmc_err);
 		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
 			  "==== IPA_UC WLAN_HOST CONTROL ====\n"
 			  "SAP NUM STAs: %d\n"
@@ -1732,6 +1725,28 @@ end:
 	cdf_mem_free(op_msg);
 }
 
+/**
+ * hdd_ipa_init_uc_op_work - init ipa uc op work
+ * @work: struct work_struct
+ * @work_handler: work_handler
+ *
+ * Return: none
+ */
+#ifdef CONFIG_CNSS
+static void hdd_ipa_init_uc_op_work(struct work_struct *work,
+					work_func_t work_handler)
+{
+	cnss_init_work(work, work_handler);
+}
+#else
+static void hdd_ipa_init_uc_op_work(struct work_struct *work,
+					work_func_t work_handler)
+{
+	INIT_WORK(work, work_handler);
+}
+#endif
+
+
 /**
  * hdd_ipa_uc_ol_init() - Initialize IPA uC offload
  * @hdd_ctx: Global HDD context
@@ -1835,7 +1850,7 @@ static CDF_STATUS hdd_ipa_uc_ol_init(hdd_context_t *hdd_ctx)
 				  hdd_ipa_uc_op_event_handler, (void *)hdd_ctx);
 
 	for (i = 0; i < HDD_IPA_UC_OPCODE_MAX; i++) {
-		cnss_init_work(&ipa_ctxt->uc_op_work[i].work,
+		hdd_ipa_init_uc_op_work(&ipa_ctxt->uc_op_work[i].work,
 			hdd_ipa_uc_fw_op_event_handler);
 		ipa_ctxt->uc_op_work[i].msg = NULL;
 	}
@@ -2312,6 +2327,27 @@ int hdd_ipa_set_perf_level(hdd_context_t *hdd_ctx, uint64_t tx_packets,
 	return 0;
 }
 
+/**
+ * hdd_ipa_init_uc_rm_work - init ipa uc resource manager work
+ * @work: struct work_struct
+ * @work_handler: work_handler
+ *
+ * Return: none
+ */
+#ifdef CONFIG_CNSS
+static void  hdd_ipa_init_uc_rm_work(struct work_struct *work,
+					work_func_t work_handler)
+{
+	cnss_init_work(work, work_handler);
+}
+#else
+static void hdd_ipa_init_uc_rm_work(struct work_struct *work,
+					work_func_t work_handler)
+{
+	INIT_WORK(work, work_handler);
+}
+#endif
+
 /**
  * hdd_ipa_setup_rm() - Setup IPA resource management
  * @hdd_ipa: Global HDD IPA context
@@ -2326,7 +2362,8 @@ static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa)
 	if (!hdd_ipa_is_rm_enabled(hdd_ipa->hdd_ctx))
 		return 0;
 
-	cnss_init_work(&hdd_ipa->uc_rm_work.work, hdd_ipa_uc_rm_notify_defer);
+	hdd_ipa_init_uc_rm_work(&hdd_ipa->uc_rm_work.work,
+		hdd_ipa_uc_rm_notify_defer);
 	memset(&create_params, 0, sizeof(create_params));
 	create_params.name = IPA_RM_RESOURCE_WLAN_PROD;
 	create_params.reg_params.user_data = hdd_ipa;
@@ -2461,7 +2498,7 @@ static void hdd_ipa_send_skb_to_network(cdf_nbuf_t skb,
 		return;
 	}
 
-	if (hdd_ipa->hdd_ctx->isUnloadInProgress) {
+	if (cds_is_driver_unloading()) {
 		HDD_IPA_INCREASE_INTERNAL_DROP_COUNT(hdd_ipa);
 		cdf_nbuf_free(skb);
 		return;
@@ -3752,7 +3789,7 @@ int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
 		if ((!hdd_ipa->num_iface) &&
 			(HDD_IPA_UC_NUM_WDI_PIPE ==
 				hdd_ipa->activated_fw_pipe)) {
-			if (hdd_ipa->hdd_ctx->isUnloadInProgress) {
+			if (cds_is_driver_unloading()) {
 				/*
 				 * We disable WDI pipes directly here since
 				 * IPA_OPCODE_TX/RX_SUSPEND message will not be
@@ -3795,6 +3832,23 @@ int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
 			cdf_mutex_release(&hdd_ipa->event_lock);
 			return 0;
 		}
+
+		/* Enable IPA UC Data PIPEs when first STA connected */
+		if ((0 == hdd_ipa->sap_num_connected_sta) &&
+		   (!hdd_ipa_uc_sta_is_enabled(hdd_ipa->hdd_ctx) ||
+		   !hdd_ipa->sta_connected)) {
+			ret = hdd_ipa_uc_handle_first_con(hdd_ipa);
+			if (ret) {
+				cdf_mutex_release(&hdd_ipa->event_lock);
+				HDD_IPA_LOG(CDF_TRACE_LEVEL_ERROR,
+					    "%s: handle 1st con ret %d",
+					    adapter->dev->name, ret);
+				return ret;
+			}
+		}
+
+		hdd_ipa->sap_num_connected_sta++;
+
 		cdf_mutex_release(&hdd_ipa->event_lock);
 
 		meta.msg_type = type;
@@ -3830,27 +3884,6 @@ int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
 			return ret;
 		}
 		hdd_ipa->stats.num_send_msg++;
-
-		cdf_mutex_acquire(&hdd_ipa->event_lock);
-		/* Enable IPA UC Data PIPEs when first STA connected */
-		if ((0 == hdd_ipa->sap_num_connected_sta)
-			&& (!hdd_ipa_uc_sta_is_enabled(hdd_ipa->hdd_ctx)
-			|| !hdd_ipa->sta_connected)) {
-			ret = hdd_ipa_uc_handle_first_con(hdd_ipa);
-			if (ret) {
-				cdf_mutex_release(&hdd_ipa->event_lock);
-				HDD_IPA_LOG(CDF_TRACE_LEVEL_ERROR,
-					    "%s: handle 1st con ret %d",
-					    adapter->dev->name, ret);
-				return ret;
-			}
-		}
-
-		hdd_ipa->sap_num_connected_sta++;
-		hdd_ipa->pending_cons_req = false;
-
-		cdf_mutex_release(&hdd_ipa->event_lock);
-
 		return ret;
 
 	case WLAN_CLIENT_DISCONNECT:

+ 5 - 2
core/hdd/src/wlan_hdd_lro.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -30,6 +30,9 @@
  * WLAN HDD LRO interface implementation
  */
 
+/* denote that this file does not allow legacy hddLog */
+#define HDD_DISALLOW_LEGACY_HDDLOG 1
+
 #include <wlan_hdd_includes.h>
 #include <cdf_types.h>
 #include <wlan_hdd_lro.h>
@@ -458,7 +461,7 @@ int hdd_lro_init(hdd_context_t *hdd_ctx)
 	struct wma_lro_config_cmd_t lro_config;
 
 	if (!hdd_ctx->config->lro_enable) {
-		hdd_err(FL("LRO Disabled"));
+		hdd_err("LRO Disabled");
 		return 0;
 	}
 

File diff suppressed because it is too large
+ 437 - 290
core/hdd/src/wlan_hdd_main.c


+ 2 - 12
core/hdd/src/wlan_hdd_memdump.c

@@ -368,7 +368,6 @@ static struct proc_dir_entry *proc_file, *proc_dir;
  *
  * Return: void pointer to hdd_context
  */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) || defined(WITH_BACKPORTS)
 static void *memdump_get_file_data(struct file *file)
 {
 	void *hdd_ctx;
@@ -376,15 +375,6 @@ static void *memdump_get_file_data(struct file *file)
 	hdd_ctx = PDE_DATA(file_inode(file));
 	return hdd_ctx;
 }
-#else
-static void *memdump_get_file_data(struct file *file)
-{
-	void *hdd_ctx;
-
-	hdd_ctx = PDE(file->f_path.dentry->d_inode)->data;
-	return hdd_ctx;
-}
-#endif
 
 /**
  * memdump_read() - perform read operation in memory dump proc file
@@ -558,7 +548,7 @@ int memdump_init(void)
 		return -EINVAL;
 	}
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Not initializing memdump in FTM mode"));
 		return -EINVAL;
 	}
@@ -612,7 +602,7 @@ void memdump_deinit(void)
 		return;
 	}
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Not deinitializing memdump in FTM mode"));
 		return;
 	}

+ 9 - 10
core/hdd/src/wlan_hdd_nan.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -25,6 +25,9 @@
  * WLAN Host Device Driver NAN API implementation
  */
 
+/* denote that this file does not allow legacy hddLog */
+#define HDD_DISALLOW_LEGACY_HDDLOG 1
+
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -65,7 +68,7 @@ static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
 	if (ret_val)
 		return ret_val;
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -131,15 +134,13 @@ static void wlan_hdd_cfg80211_nan_callback(void *ctx, tSirNanEvent *msg)
 	int status;
 
 	if (NULL == msg) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
-			  FL("msg received here is null"));
+		hdd_err("msg received here is null");
 		return;
 	}
 
 	status = wlan_hdd_validate_context(hdd_ctx);
 	if (0 != status) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
-			  FL("HDD context is not valid"));
+		hdd_err("HDD context is not valid");
 		return;
 	}
 
@@ -151,14 +152,12 @@ static void wlan_hdd_cfg80211_nan_callback(void *ctx, tSirNanEvent *msg)
 					    GFP_KERNEL);
 
 	if (!vendor_event) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
-			  FL("cfg80211_vendor_event_alloc failed"));
+		hdd_err("cfg80211_vendor_event_alloc failed");
 		return;
 	}
 	if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
 		    msg->event_data_len, msg->event_data)) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
-			  FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
+		hdd_err("QCA_WLAN_VENDOR_ATTR_NAN put fail");
 		kfree_skb(vendor_event);
 		return;
 	}

+ 2 - 110
core/hdd/src/wlan_hdd_ocb.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -121,113 +121,6 @@ static int dot11p_validate_qos_params(struct sir_qos_params qos_params[])
 	return 0;
 }
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) || \
-				 defined(FEATURE_STATICALLY_ADD_11P_CHANNELS)
-/*
- * If FEATURE_STATICALLY_ADD_11P_CHANNELS
- * is defined, IEEE80211_CHAN_NO_10MHZ,
- * and IEEE80211_CHAN_NO_20MHZ won't
- * be defined.
- */
-#define IEEE80211_CHAN_NO_20MHZ	(1<<11)
-#define IEEE80211_CHAN_NO_10MHZ	(1<<12)
-#endif
-
-#ifdef FEATURE_STATICALLY_ADD_11P_CHANNELS
-
-#define DOT11P_TX_PWR_MAX	30
-#define DOT11P_TX_ANTENNA_MAX	6
-#define NUM_DOT11P_CHANNELS	10
-/**
- * struct chan_info - information for the channel
- * @center_freq: center frequency
- * @max_bandwidth: maximum bandwidth of the channel in MHz
- */
-struct chan_info {
-	uint32_t center_freq;
-	uint32_t max_bandwidth;
-};
-
-struct chan_info valid_dot11p_channels[NUM_DOT11P_CHANNELS] = {
-	{5860, 10},
-	{5870, 10},
-	{5880, 10},
-	{5890, 10},
-	{5900, 10},
-	{5910, 10},
-	{5920, 10},
-	{5875, 20},
-	{5905, 20},
-	{5852, 5}
-};
-
-/**
- * dot11p_validate_channel_static_channels() - validate a DSRC channel
- * @center_freq: the channel's center frequency
- * @bandwidth: the channel's bandwidth
- * @tx_power: transmit power
- * @reg_power: (output) the max tx power from the regulatory domain
- * @antenna_max: (output) the max antenna gain from the regulatory domain
- *
- * This function of the function checks the channel parameters against a
- * hardcoded list of valid channels based on the FCC rules.
- *
- * Return: 0 if the channel is valid, error code otherwise.
- */
-static int dot11p_validate_channel_static_channels(struct wiphy *wiphy,
-	uint32_t channel_freq, uint32_t bandwidth, uint32_t tx_power,
-	uint8_t *reg_power, uint8_t *antenna_max)
-{
-	int i;
-
-	for (i = 0; i < NUM_DOT11P_CHANNELS; i++) {
-		if (channel_freq == valid_dot11p_channels[i].center_freq) {
-			if (reg_power)
-				*reg_power = DOT11P_TX_PWR_MAX;
-			if (antenna_max)
-				*antenna_max = DOT11P_TX_ANTENNA_MAX;
-
-			if (bandwidth == 0)
-				bandwidth =
-					valid_dot11p_channels[i].max_bandwidth;
-			else if (bandwidth >
-				 valid_dot11p_channels[i].max_bandwidth)
-				return -EINVAL;
-
-			if (bandwidth != 5 && bandwidth != 10 &&
-			    bandwidth != 20)
-				return -EINVAL;
-			if (tx_power > DOT11P_TX_PWR_MAX)
-				return -EINVAL;
-
-			return 0;
-		}
-	}
-
-	return -EINVAL;
-}
-#else
-/**
- * dot11p_validate_channel_static_channels() - validate a DSRC channel
- * @center_freq: the channel's center frequency
- * @bandwidth: the channel's bandwidth
- * @tx_power: transmit power
- * @reg_power: (output) the max tx power from the regulatory domain
- * @antenna_max: (output) the max antenna gain from the regulatory domain
- *
- * This function of the function checks the channel parameters against a
- * hardcoded list of valid channels based on the FCC rules.
- *
- * Return: 0 if the channel is valid, error code otherwise.
- */
-static int dot11p_validate_channel_static_channels(struct wiphy *wiphy,
-	uint32_t channel_freq, uint32_t bandwidth, uint32_t tx_power,
-	uint8_t *reg_power, uint8_t *antenna_max)
-{
-	return -EINVAL;
-}
-#endif /* FEATURE_STATICALLY_ADD_11P_CHANNELS */
-
 /**
  * dot11p_validate_channel() - validates a DSRC channel
  * @center_freq: the channel's center frequency
@@ -304,8 +197,7 @@ static int dot11p_validate_channel(struct wiphy *wiphy,
 		}
 	}
 
-	return dot11p_validate_channel_static_channels(wiphy, channel_freq,
-		bandwidth, tx_power, reg_power, antenna_max);
+	return -EINVAL;
 }
 
 /**

+ 14 - 50
core/hdd/src/wlan_hdd_oemdata.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -47,52 +47,6 @@
 
 static struct hdd_context_s *p_hdd_ctx;
 
-/**
- * hdd_oem_data_req_callback() - OEM Data request callback handler
- * @hHal: MAC handle
- * @pContext: User context.  For this callback the net device was registered
- * @oemDataReqID: The ID of the request
- * @oemDataReqStatus: Status of the request
- *
- * This function reports the results of the request to user space
- *
- * Return: CDF_STATUS enumeration
- */
-static CDF_STATUS hdd_oem_data_req_callback(tHalHandle hHal,
-					    void *pContext,
-					    uint32_t oemDataReqID,
-					    eOemDataReqStatus oemDataReqStatus)
-{
-	CDF_STATUS status = CDF_STATUS_SUCCESS;
-	struct net_device *dev = (struct net_device *)pContext;
-	union iwreq_data wrqu;
-	char buffer[IW_CUSTOM_MAX + 1];
-
-	memset(&wrqu, '\0', sizeof(wrqu));
-	memset(buffer, '\0', sizeof(buffer));
-
-	if (oemDataReqStatus == eOEM_DATA_REQ_FAILURE) {
-		snprintf(buffer, IW_CUSTOM_MAX, "QCOM: OEM-DATA-REQ-FAILED");
-		hddLog(LOGW, "%s: oem data req %d failed", __func__,
-		       oemDataReqID);
-	} else if (oemDataReqStatus == eOEM_DATA_REQ_INVALID_MODE) {
-		snprintf(buffer, IW_CUSTOM_MAX,
-			 "QCOM: OEM-DATA-REQ-INVALID-MODE");
-		hddLog(LOGW,
-		       "%s: oem data req %d failed because the driver is in invalid mode (IBSS|AP)",
-		       __func__, oemDataReqID);
-	} else {
-		snprintf(buffer, IW_CUSTOM_MAX, "QCOM: OEM-DATA-REQ-SUCCESS");
-	}
-
-	wrqu.data.pointer = buffer;
-	wrqu.data.length = strlen(buffer);
-
-	wireless_send_event(dev, IWEVCUSTOM, &wrqu, buffer);
-
-	return status;
-}
-
 /**
  * iw_get_oem_data_cap() - Get OEM Data Capabilities
  * @dev: net device upon which the request was received
@@ -420,7 +374,14 @@ static CDF_STATUS oem_process_data_req_msg(int oemDataLen, char *oemData)
 
 	cdf_mem_zero(&oemDataReqConfig, sizeof(tOemDataReqConfig));
 
-	cdf_mem_copy((&oemDataReqConfig)->oemDataReq, oemData, oemDataLen);
+	oemDataReqConfig.data = cdf_mem_malloc(oemDataLen);
+	if (!oemDataReqConfig.data) {
+		hddLog(LOGE, FL("malloc failed for data req buffer"));
+		return CDF_STATUS_E_NOMEM;
+	}
+
+	oemDataReqConfig.data_len = oemDataLen;
+	cdf_mem_copy(oemDataReqConfig.data, oemData, oemDataLen);
 
 	CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO,
 		  "%s: calling sme_oem_data_req", __func__);
@@ -428,8 +389,11 @@ static CDF_STATUS oem_process_data_req_msg(int oemDataLen, char *oemData)
 	status = sme_oem_data_req(p_hdd_ctx->hHal,
 				  pAdapter->sessionId,
 				  &oemDataReqConfig,
-				  &oemDataReqID,
-				  &hdd_oem_data_req_callback, pAdapter->dev);
+				  &oemDataReqID);
+
+	cdf_mem_free(oemDataReqConfig.data);
+	oemDataReqConfig.data = NULL;
+
 	return status;
 }
 

+ 18 - 250
core/hdd/src/wlan_hdd_p2p.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -211,19 +211,11 @@ CDF_STATUS wlan_hdd_remain_on_channel_callback(tHalHandle hHal, void *pCtx,
 			       __func__);
 		}
 		cfg80211_remain_on_channel_expired(
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 			pRemainChanCtx->dev->
 			ieee80211_ptr,
-#else
-			pRemainChanCtx->dev,
-#endif
 			pRemainChanCtx->
 			cookie,
 			&pRemainChanCtx->chan,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-			pRemainChanCtx->
-			chan_type,
-#endif
 			GFP_KERNEL);
 		pAdapter->last_roc_ts = cdf_mc_timer_get_system_time();
 	}
@@ -827,10 +819,6 @@ void wlan_hdd_roc_request_dequeue(struct work_struct *work)
 static int wlan_hdd_request_remain_on_channel(struct wiphy *wiphy,
 					      struct net_device *dev,
 					      struct ieee80211_channel *chan,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-					      enum nl80211_channel_type
-					      channel_type,
-#endif
 					      unsigned int duration,
 					      u64 *cookie,
 					      rem_on_channel_request_type_t
@@ -850,21 +838,14 @@ static int wlan_hdd_request_remain_on_channel(struct wiphy *wiphy,
 	hddLog(LOG1, FL("Device_mode %s(%d)"),
 	       hdd_device_mode_to_string(pAdapter->device_mode),
 	       pAdapter->device_mode);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-	hddLog(LOG1,
-	       "chan(hw_val)0x%x chan(centerfreq) %d chan type 0x%x, duration %d",
-	       chan->hw_value, chan->center_freq, channel_type, duration);
-#else
 	hddLog(LOG1,
 	       "chan(hw_val)0x%x chan(centerfreq) %d, duration %d",
 	       chan->hw_value, chan->center_freq, duration);
-#endif
 	pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
 	ret = wlan_hdd_validate_context(pHddCtx);
 	if (0 != ret)
 		return ret;
-	if (cds_is_connection_in_progress(
-		(hdd_context_t *) pAdapter->pHddCtx)) {
+	if (cds_is_connection_in_progress()) {
 		hddLog(LOGE, FL("Connection is in progress"));
 		isBusy = true;
 	}
@@ -879,9 +860,6 @@ static int wlan_hdd_request_remain_on_channel(struct wiphy *wiphy,
 	cdf_mem_zero(pRemainChanCtx, sizeof(*pRemainChanCtx));
 	cdf_mem_copy(&pRemainChanCtx->chan, chan,
 		     sizeof(struct ieee80211_channel));
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-	pRemainChanCtx->chan_type = channel_type;
-#endif
 	pRemainChanCtx->duration = duration;
 	pRemainChanCtx->dev = dev;
 	*cookie = (uintptr_t) pRemainChanCtx;
@@ -955,21 +933,11 @@ static int wlan_hdd_request_remain_on_channel(struct wiphy *wiphy,
 }
 
 int __wlan_hdd_cfg80211_remain_on_channel(struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 					  struct wireless_dev *wdev,
-#else
-					  struct net_device *dev,
-#endif
 					  struct ieee80211_channel *chan,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-					  enum nl80211_channel_type
-					  channel_type,
-#endif
 					  unsigned int duration, u64 *cookie)
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 	struct net_device *dev = wdev->netdev;
-#endif
 	hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	hdd_context_t *hdd_ctx;
 	int ret;
@@ -981,7 +949,7 @@ int __wlan_hdd_cfg80211_remain_on_channel(struct wiphy *wiphy,
 	if (0 != ret)
 		return ret;
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -989,10 +957,8 @@ int __wlan_hdd_cfg80211_remain_on_channel(struct wiphy *wiphy,
 	MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
 			 TRACE_CODE_HDD_REMAIN_ON_CHANNEL,
 			 pAdapter->sessionId, REMAIN_ON_CHANNEL_REQUEST));
+
 	ret = wlan_hdd_request_remain_on_channel(wiphy, dev, chan,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-						  channel_type,
-#endif
 						  duration, cookie,
 						  REMAIN_ON_CHANNEL_REQUEST);
 	EXIT();
@@ -1000,30 +966,16 @@ int __wlan_hdd_cfg80211_remain_on_channel(struct wiphy *wiphy,
 }
 
 int wlan_hdd_cfg80211_remain_on_channel(struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 					struct wireless_dev *wdev,
-#else
-					struct net_device *dev,
-#endif
 					struct ieee80211_channel *chan,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-					enum nl80211_channel_type channel_type,
-#endif
 					unsigned int duration, u64 *cookie)
 {
 	int ret;
 
 	cds_ssr_protect(__func__);
 	ret = __wlan_hdd_cfg80211_remain_on_channel(wiphy,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 						    wdev,
-#else
-						    dev,
-#endif
 						    chan,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-						    channel_type,
-#endif
 						    duration, cookie);
 	cds_ssr_unprotect(__func__);
 
@@ -1073,19 +1025,11 @@ void hdd_remain_chan_ready_handler(hdd_adapter_t *pAdapter,
 		if (REMAIN_ON_CHANNEL_REQUEST ==
 		    pRemainChanCtx->rem_on_chan_request) {
 			cfg80211_ready_on_channel(
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 				pAdapter->dev->
 				ieee80211_ptr,
-#else
-				pAdapter->dev,
-#endif
 				(uintptr_t)
 				pRemainChanCtx,
 				&pRemainChanCtx->chan,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-				pRemainChanCtx->
-				chan_type,
-#endif
 				pRemainChanCtx->
 				duration, GFP_KERNEL);
 		} else if (OFF_CHANNEL_ACTION_TX ==
@@ -1109,7 +1053,7 @@ void hdd_remain_chan_ready_handler(hdd_adapter_t *pAdapter,
 				pRemainChanCtx->action_pkt_buff.frame_ptr,
 				pRemainChanCtx->action_pkt_buff.frame_length,
 				NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC);
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
+#else
 			cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr,
 					 pRemainChanCtx->action_pkt_buff.freq,
 					 0,
@@ -1117,21 +1061,6 @@ void hdd_remain_chan_ready_handler(hdd_adapter_t *pAdapter,
 					 frame_ptr,
 					 pRemainChanCtx->action_pkt_buff.
 					 frame_length, GFP_ATOMIC);
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
-			cfg80211_rx_mgmt(pAdapter->dev,
-					 pRemainChanCtx->action_pkt_buff.freq,
-					 0,
-					 pRemainChanCtx->action_pkt_buff.
-					 frame_ptr,
-					 pRemainChanCtx->action_pkt_buff.
-					 frame_length, GFP_ATOMIC);
-#else
-			cfg80211_rx_mgmt(pAdapter->dev,
-					 pRemainChanCtx->action_pkt_buff.freq,
-					 pRemainChanCtx->action_pkt_buff.
-					 frame_ptr,
-					 pRemainChanCtx->action_pkt_buff.
-					 frame_length, GFP_ATOMIC);
 #endif /* LINUX_VERSION_CODE */
 
 			cdf_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr);
@@ -1149,16 +1078,10 @@ void hdd_remain_chan_ready_handler(hdd_adapter_t *pAdapter,
 }
 
 int __wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 						 struct wireless_dev *wdev,
-#else
-						 struct net_device *dev,
-#endif
 						 u64 cookie)
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 	struct net_device *dev = wdev->netdev;
-#endif
 	hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
 	hdd_remain_on_chan_ctx_t *pRemainChanCtx;
@@ -1170,7 +1093,7 @@ int __wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -1243,9 +1166,9 @@ int __wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
 		       "%s: timeout waiting for remain on channel ready indication",
 		       __func__);
 
-		if (pHddCtx->isLogpInProgress) {
-			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
-				  "%s: LOGP in Progress. Ignore!!!", __func__);
+		if (cds_is_driver_recovering()) {
+			hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
+				 cds_get_driver_state());
 			return -EAGAIN;
 		}
 	}
@@ -1294,56 +1217,27 @@ int __wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
 }
 
 int wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 					       struct wireless_dev *wdev,
-#else
-					       struct net_device *dev,
-#endif
 					       u64 cookie)
 {
 	int ret;
 
 	cds_ssr_protect(__func__);
 	ret = __wlan_hdd_cfg80211_cancel_remain_on_channel(wiphy,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 							   wdev,
-#else
-							   dev,
-#endif
 							   cookie);
 	cds_ssr_unprotect(__func__);
 
 	return ret;
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 		       struct ieee80211_channel *chan, bool offchan,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-		       enum nl80211_channel_type channel_type,
-		       bool channel_type_valid,
-#endif
 		       unsigned int wait,
 		       const u8 *buf, size_t len, bool no_cck,
 		       bool dont_wait_for_ack, u64 *cookie)
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
-int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
-		       struct ieee80211_channel *chan, bool offchan,
-		       enum nl80211_channel_type channel_type,
-		       bool channel_type_valid, unsigned int wait,
-		       const u8 *buf, size_t len, bool no_cck,
-		       bool dont_wait_for_ack, u64 *cookie)
-#else
-int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
-		       struct ieee80211_channel *chan, bool offchan,
-		       enum nl80211_channel_type channel_type,
-		       bool channel_type_valid, unsigned int wait,
-		       const u8 *buf, size_t len, u64 *cookie)
-#endif /* LINUX_VERSION_CODE */
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 	struct net_device *dev = wdev->netdev;
-#endif
 	hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
 	hdd_remain_on_chan_ctx_t *pRemainChanCtx;
@@ -1360,7 +1254,7 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -1413,9 +1307,7 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 	}
 #endif
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
 	noack = dont_wait_for_ack;
-#endif
 
 	/* If the wait is coming as 0 with off channel set */
 	/* then set the wait to 200 ms */
@@ -1582,9 +1474,6 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 		INIT_COMPLETION(pAdapter->offchannel_tx_event);
 
 		status = wlan_hdd_request_remain_on_channel(wiphy, dev, chan,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-							    channel_type,
-#endif
 							    wait, cookie,
 							    req_type);
 		if (0 != status) {
@@ -1654,6 +1543,8 @@ send_frame:
 		current_freq = 0;
 	}
 
+	INIT_COMPLETION(pAdapter->tx_action_cnf_event);
+
 	if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
 	    (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
 	    (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
@@ -1713,11 +1604,7 @@ err:
 err_rem_channel:
 	*cookie = (uintptr_t) cfgState;
 	cfg80211_mgmt_tx_status(
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 		pAdapter->dev->ieee80211_ptr,
-#else
-		pAdapter->dev,
-#endif
 		*cookie, buf, len, false, GFP_KERNEL);
 	EXIT();
 	return 0;
@@ -1726,29 +1613,12 @@ err_rem_channel:
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
 int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 		     struct cfg80211_mgmt_tx_params *params, u64 *cookie)
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
+#else
 int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 		     struct ieee80211_channel *chan, bool offchan,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-		     enum nl80211_channel_type channel_type,
-		     bool channel_type_valid,
-#endif
 		     unsigned int wait,
 		     const u8 *buf, size_t len, bool no_cck,
 		     bool dont_wait_for_ack, u64 *cookie)
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
-int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
-		     struct ieee80211_channel *chan, bool offchan,
-		     enum nl80211_channel_type channel_type,
-		     bool channel_type_valid, unsigned int wait,
-		     const u8 *buf, size_t len, bool no_cck,
-		     bool dont_wait_for_ack, u64 *cookie)
-#else
-int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
-		     struct ieee80211_channel *chan, bool offchan,
-		     enum nl80211_channel_type channel_type,
-		     bool channel_type_valid, unsigned int wait,
-		     const u8 *buf, size_t len, u64 *cookie)
 #endif /* LINUX_VERSION_CODE */
 {
 	int ret;
@@ -1760,43 +1630,23 @@ int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 				 params->wait, params->buf, params->len,
 				 params->no_cck, params->dont_wait_for_ack,
 				 cookie);
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
+#else
 	ret = __wlan_hdd_mgmt_tx(wiphy, wdev, chan, offchan,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
-				 channel_type, channel_type_valid,
-#endif
 				 wait, buf, len, no_cck,
 				 dont_wait_for_ack, cookie);
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
-	ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan,
-				 channel_type, channel_type_valid, wait,
-				 buf, len, no_cck, dont_wait_for_ack, cookie);
-#else
-	ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan,
-				 channel_type, channel_type_valid, wait,
-				 buf, len, cookie);
 #endif /* LINUX_VERSION_CODE */
 	cds_ssr_unprotect(__func__);
 
 	return ret;
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
 					    struct wireless_dev *wdev,
 					    u64 cookie)
 {
 	return wlan_hdd_cfg80211_cancel_remain_on_channel(wiphy, wdev, cookie);
 }
-#else
-int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
-					    struct net_device *dev, u64 cookie)
-{
-	return wlan_hdd_cfg80211_cancel_remain_on_channel(wiphy, dev, cookie);
-}
-#endif
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
 					  struct wireless_dev *wdev, u64 cookie)
 {
@@ -1808,19 +1658,6 @@ int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
 
 	return ret;
 }
-#else
-int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
-					  struct net_device *dev, u64 cookie)
-{
-	int ret;
-
-	cds_ssr_protect(__func__);
-	ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, dev, cookie);
-	cds_ssr_unprotect(__func__);
-
-	return ret;
-}
-#endif
 
 void hdd_send_action_cnf(hdd_adapter_t *pAdapter, bool actionSendSuccess)
 {
@@ -1842,11 +1679,7 @@ void hdd_send_action_cnf(hdd_adapter_t *pAdapter, bool actionSendSuccess)
 	 * data while sending tx ack status.
 	 * */
 	cfg80211_mgmt_tx_status(
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 		pAdapter->dev->ieee80211_ptr,
-#else
-		pAdapter->dev,
-#endif
 		cfgState->action_cookie,
 		cfgState->buf, cfgState->len,
 		actionSendSuccess, GFP_KERNEL);
@@ -2104,24 +1937,11 @@ static uint8_t wlan_hdd_get_session_type(enum nl80211_iftype type)
 	return sessionType;
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
 struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
 						 const char *name,
 						 enum nl80211_iftype type,
 						 u32 *flags,
 						 struct vif_params *params)
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
-struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
-						 char *name,
-						 enum nl80211_iftype type,
-						 u32 *flags,
-						 struct vif_params *params)
-#else
-struct net_device *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy, char *name,
-					       enum nl80211_iftype type,
-					       u32 *flags,
-					       struct vif_params *params)
-#endif
 {
 	hdd_context_t *pHddCtx = (hdd_context_t *) wiphy_priv(wiphy);
 	hdd_adapter_t *pAdapter = NULL;
@@ -2131,7 +1951,7 @@ struct net_device *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy, char *name,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return ERR_PTR(-EINVAL);
 	}
@@ -2202,14 +2022,9 @@ struct net_device *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy, char *name,
 		return ERR_PTR(-ENOSPC);
 	}
 	EXIT();
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 	return pAdapter->dev->ieee80211_ptr;
-#else
-	return pAdapter->dev;
-#endif
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
 struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
 					       const char *name,
 					       enum nl80211_iftype type,
@@ -2223,49 +2038,16 @@ struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy,
 	cds_ssr_unprotect(__func__);
 	return wdev;
 }
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
-struct wireless_dev *wlan_hdd_add_virtual_intf(struct wiphy *wiphy, char *name,
-					       enum nl80211_iftype type,
-					       u32 *flags,
-					       struct vif_params *params)
-{
-	struct wireless_dev *wdev;
-
-	cds_ssr_protect(__func__);
-	wdev = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params);
-	cds_ssr_unprotect(__func__);
-	return wdev;
-}
-#else
-struct net_device *wlan_hdd_add_virtual_intf(struct wiphy *wiphy, char *name,
-					     enum nl80211_iftype type,
-					     u32 *flags,
-					     struct vif_params *params)
-{
-	struct net_device *ndev;
 
-	cds_ssr_protect(__func__);
-	ndev = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params);
-	cds_ssr_unprotect(__func__);
-	return ndev;
-}
-#endif
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 int __wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
-#else
-int __wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
-#endif
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 	struct net_device *dev = wdev->netdev;
-#endif
 	hdd_context_t *pHddCtx = (hdd_context_t *) wiphy_priv(wiphy);
 	hdd_adapter_t *pVirtAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	int status;
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -2291,26 +2073,18 @@ int __wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
 	return 0;
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 int wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
-#else
-int wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
-#endif
 {
 	int ret;
 
 	cds_ssr_protect(__func__);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 	ret = __wlan_hdd_del_virtual_intf(wiphy, wdev);
-#else
-	ret = __wlan_hdd_del_virtual_intf(wiphy, dev);
-#endif
 	cds_ssr_unprotect(__func__);
 
 	return ret;
 }
 
-void hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
+void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
 			     uint32_t nFrameLength,
 			     uint8_t *pbFrames,
 			     uint8_t frameType, uint32_t rxChan, int8_t rxRssi)
@@ -2614,14 +2388,8 @@ void hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter,
 	cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr, freq, 0, pbFrames,
 			 nFrameLength, NL80211_RXMGMT_FLAG_ANSWERED,
 			 GFP_ATOMIC);
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
-	cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr, freq, 0,
-			 pbFrames, nFrameLength, GFP_ATOMIC);
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
-	cfg80211_rx_mgmt(pAdapter->dev, freq, 0,
-			 pbFrames, nFrameLength, GFP_ATOMIC);
 #else
-	cfg80211_rx_mgmt(pAdapter->dev, freq,
+	cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr, freq, 0,
 			 pbFrames, nFrameLength, GFP_ATOMIC);
 #endif /* LINUX_VERSION_CODE */
 }

+ 93 - 114
core/hdd/src/wlan_hdd_power.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -387,8 +387,8 @@ static void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, bool fenable)
 			}
 			offLoadRequest.offloadType =  SIR_IPV6_NS_OFFLOAD;
 			offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE;
-			cdf_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr,
-				&pAdapter->macAddressCurrent.bytes, SIR_MAC_ADDR_LEN);
+			cdf_copy_macaddr(&offLoadRequest.nsOffloadInfo.self_macaddr,
+					 &pAdapter->macAddressCurrent);
 			/* set number of ns offload address count */
 			offLoadRequest.num_ns_offload_count = count;
 			/* Configure the Firmware with this */
@@ -511,16 +511,19 @@ void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, bool fenable)
 
 	hdd_conf_gtk_offload(pAdapter, fenable);
 
-	/* Configure ARP/NS offload during cfg80211 suspend/resume only
-	 * if active mode offload is disabled
+	/* Configure ARP/NS offload during cfg80211 suspend/resume and
+	 * Enable MC address filtering during cfg80211 suspend
+	 * only if active mode offload is disabled
 	 */
 	if (!pHddCtx->config->active_mode_offload) {
+		hdd_info("configuring unconfigured active mode offloads");
 		hdd_conf_arp_offload(pAdapter, fenable);
+		wlan_hdd_set_mc_addr_list(pAdapter, fenable);
+
 		if (pHddCtx->config->fhostNSOffload)
 			hdd_conf_ns_offload(pAdapter, fenable);
 	}
 	EXIT();
-	EXIT();
 	return;
 }
 #endif
@@ -966,6 +969,23 @@ void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, uint8_t set)
 }
 #endif
 
+/**
+ * hdd_update_mcastbcast_filter(): cache multi and broadcast filter for suspend
+ * @hdd_ctx: hdd context
+ *
+ * Cache the configured filter to be used in suspend resume.
+ */
+static void hdd_update_mcastbcast_filter(hdd_context_t *hdd_ctx)
+{
+	if (false == hdd_ctx->sus_res_mcastbcast_filter_valid) {
+		hdd_ctx->sus_res_mcastbcast_filter =
+			hdd_ctx->configuredMcastBcastFilter;
+		hdd_ctx->sus_res_mcastbcast_filter_valid = true;
+		hdd_info("configuredMCastBcastFilter saved = %d",
+			hdd_ctx->configuredMcastBcastFilter);
+	}
+}
+
 /**
  * hdd_conf_suspend_ind() - Send Suspend notification
  * @pHddCtx: HDD Global context
@@ -975,69 +995,26 @@ void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, uint8_t set)
  *
  * Return: None.
  */
-static void hdd_conf_suspend_ind(hdd_context_t *pHddCtx,
-				 hdd_adapter_t *pAdapter,
+static void hdd_send_suspend_ind(hdd_context_t *pHddCtx,
+				uint32_t conn_state_mask,
 				 void (*callback)(void *callbackContext,
 						  bool suspended),
 				 void *callbackContext)
 {
 	CDF_STATUS cdf_ret_status = CDF_STATUS_E_FAILURE;
-	tpSirWlanSuspendParam wlanSuspendParam =
-		cdf_mem_malloc(sizeof(tSirWlanSuspendParam));
 
-	if (false == pHddCtx->sus_res_mcastbcast_filter_valid) {
-		pHddCtx->sus_res_mcastbcast_filter =
-			pHddCtx->configuredMcastBcastFilter;
-		pHddCtx->sus_res_mcastbcast_filter_valid = true;
-		hddLog(CDF_TRACE_LEVEL_INFO, "offload: hdd_conf_suspend_ind");
-		hddLog(CDF_TRACE_LEVEL_INFO,
-		       "configuredMCastBcastFilter saved = %d",
-		       pHddCtx->configuredMcastBcastFilter);
+	hdd_info("%s: send wlan suspend indication", __func__);
 
-	}
-
-	if (NULL == wlanSuspendParam) {
-		hddLog(CDF_TRACE_LEVEL_FATAL,
-		       "%s: cdf_mem_alloc failed ", __func__);
-		return;
-	}
-
-	hddLog(CDF_TRACE_LEVEL_INFO,
-	       "%s: send wlan suspend indication", __func__);
-
-	/* Configure supported OffLoads */
-	hdd_conf_hostoffload(pAdapter, true);
-	wlanSuspendParam->configuredMcstBcstFilterSetting =
-		pHddCtx->configuredMcastBcastFilter;
-
-	/* Enable MC address filtering during cfg80211 suspend if active mode
-	 * mode offload is disabled in INI
-	 */
-	if (!pHddCtx->config->active_mode_offload) {
-		hdd_info("enable mc address filtering");
-		wlan_hdd_set_mc_addr_list(pAdapter, true);
-	}
-
-	if ((eConnectionState_Associated ==
-	     (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) ||
-	    (eConnectionState_IbssConnected ==
-	     (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
-		wlanSuspendParam->connectedState = true;
-	else
-		wlanSuspendParam->connectedState = false;
-
-	wlanSuspendParam->sessionId = pAdapter->sessionId;
 	cdf_ret_status =
-		sme_configure_suspend_ind(pHddCtx->hHal, wlanSuspendParam,
+		sme_configure_suspend_ind(pHddCtx->hHal, conn_state_mask,
 					  callback, callbackContext);
+
 	if (CDF_STATUS_SUCCESS == cdf_ret_status) {
 		pHddCtx->hdd_mcastbcast_filter_set = true;
 	} else {
 		hddLog(CDF_TRACE_LEVEL_ERROR,
 		       FL("sme_configure_suspend_ind returned failure %d"),
 		       cdf_ret_status);
-
-		cdf_mem_free(wlanSuspendParam);
 	}
 }
 
@@ -1077,14 +1054,27 @@ static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter)
 	       "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter");
 	hddLog(CDF_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d",
 	       pHddCtx->configuredMcastBcastFilter);
+}
 
-	/* Disable MC address filtering during cfg80211 suspend if active mode
-	 * mode offload is disabled in INI
-	 */
-	if (!pHddCtx->config->active_mode_offload) {
-		hdd_info("disable mc address filtering");
-		wlan_hdd_set_mc_addr_list(pAdapter, false);
-	}
+/**
+ * hdd_update_conn_state_mask(): record info needed by wma_suspend_req
+ * @adapter: adapter to get info from
+ * @conn_state_mask: mask of connection info
+ *
+ * currently only need to send connection info.
+ */
+static void
+hdd_update_conn_state_mask(hdd_adapter_t *adapter, uint32_t *conn_state_mask)
+{
+
+	eConnectionState connState;
+	hdd_station_ctx_t *sta_ctx;
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	connState = sta_ctx->conn_info.connState;
+
+	if (connState == eConnectionState_Associated ||
+			connState == eConnectionState_IbssConnected)
+		*conn_state_mask |= (1 << adapter->sessionId);
 }
 
 /**
@@ -1103,9 +1093,9 @@ hdd_suspend_wlan(void (*callback)(void *callbackContext, bool suspended),
 	CDF_STATUS status;
 	hdd_adapter_t *pAdapter = NULL;
 	hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
+	uint32_t conn_state_mask = 0;
 
-	hddLog(CDF_TRACE_LEVEL_INFO, "%s: WLAN being suspended by OS",
-	       __func__);
+	hdd_info("%s: WLAN being suspended by OS", __func__);
 
 	pHddCtx = cds_get_context(CDF_MODULE_ID_HDD);
 	if (!pHddCtx) {
@@ -1114,12 +1104,14 @@ hdd_suspend_wlan(void (*callback)(void *callbackContext, bool suspended),
 		return;
 	}
 
-	if (pHddCtx->isLogpInProgress) {
-		hddLog(CDF_TRACE_LEVEL_ERROR,
-		       "%s: Ignore suspend wlan, LOGP in progress!", __func__);
+	if (cds_is_driver_recovering()) {
+		hdd_err("Recovery in Progress. State: 0x%x Ignore suspend!!!",
+			 cds_get_driver_state());
 		return;
 	}
 
+	hdd_update_mcastbcast_filter(pHddCtx);
+
 	status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
 	while (NULL != pAdapterNode && CDF_STATUS_SUCCESS == status) {
 		pAdapter = pAdapterNode->pAdapter;
@@ -1129,20 +1121,19 @@ hdd_suspend_wlan(void (*callback)(void *callbackContext, bool suspended),
 		wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE,
 					   WLAN_CONTROL_PATH);
 
-		/* Send suspend notification down to firmware.
-		 *
-		 * N.B.: Keep this suspend indication at the end
-		 * (before processing next adaptor). This indication
-		 * is considered as trigger point to start WOW (if wow
-		 * is enabled).
-		 */
-		hdd_conf_suspend_ind(pHddCtx, pAdapter, callback,
-				     callbackContext);
+		/* Configure supported OffLoads */
+		hdd_conf_hostoffload(pAdapter, true);
+
+		hdd_update_conn_state_mask(pAdapter, &conn_state_mask);
 
 		status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
+
 		pAdapterNode = pNext;
 	}
 
+	hdd_send_suspend_ind(pHddCtx, conn_state_mask, callback,
+			callbackContext);
+
 	pHddCtx->hdd_wlan_suspended = true;
 
 	return;
@@ -1170,9 +1161,9 @@ static void hdd_resume_wlan(void)
 		return;
 	}
 
-	if (pHddCtx->isLogpInProgress) {
-		hddLog(CDF_TRACE_LEVEL_INFO,
-		       "%s: Ignore resume wlan, LOGP in progress!", __func__);
+	if (cds_is_driver_recovering()) {
+		hdd_warn("Recovery in Progress. State: 0x%x Ignore resume!!!",
+			 cds_get_driver_state());
 		return;
 	}
 
@@ -1304,8 +1295,7 @@ CDF_STATUS hdd_wlan_shutdown(void)
 		return CDF_STATUS_E_FAILURE;
 	}
 
-	pHddCtx->isLogpInProgress = true;
-	cds_set_logp_in_progress(true);
+	cds_set_recovery_in_progress(true);
 
 	cds_clear_concurrent_session_count();
 
@@ -1448,7 +1438,7 @@ CDF_STATUS hdd_wlan_re_init(void *hif_sc)
 	hdd_set_conparam(0);
 
 	/* Re-open CDS, it is a re-open b'se control transport was never closed. */
-	cdf_status = cds_open(&p_cds_context, 0);
+	cdf_status = cds_open();
 	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
 		hddLog(CDF_TRACE_LEVEL_FATAL, "%s: cds_open failed", __func__);
 		goto err_re_init;
@@ -1462,18 +1452,21 @@ CDF_STATUS hdd_wlan_re_init(void *hif_sc)
 		goto err_cds_close;
 	}
 
-	/* Set the SME configuration parameters. */
-	cdf_status = hdd_set_sme_config(pHddCtx);
-	if (CDF_STATUS_SUCCESS != cdf_status) {
-		hddLog(CDF_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config",
-		       __func__);
+	cdf_status = cds_pre_enable(pHddCtx->pcds_context);
+	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+		hdd_alert("cds_pre_enable failed");
 		goto err_cds_close;
 	}
 
-	cdf_status = cds_pre_enable(pHddCtx->pcds_context);
-	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
-		hddLog(CDF_TRACE_LEVEL_FATAL, "%s: cds_pre_enable failed",
-		       __func__);
+	/*
+	 * Note that the cds_pre_enable() sequence triggers the cfg download.
+	 * The cfg download must occur before we update the SME config
+	 * since the SME config operation must access the cfg database.
+	 * Set the SME configuration parameters.
+	 */
+	cdf_status = hdd_set_sme_config(pHddCtx);
+	if (CDF_STATUS_SUCCESS != cdf_status) {
+		hdd_alert("Failed hdd_set_sme_config");
 		goto err_cds_close;
 	}
 
@@ -1638,9 +1631,8 @@ err_cds_close:
 		wiphy_unregister(pHddCtx->wiphy);
 		wiphy_free(pHddCtx->wiphy);
 
-		if (!CDF_IS_STATUS_SUCCESS(cdf_mutex_destroy(
-					&pHddCtx->hdd_conc_list_lock))) {
-			hdd_err("Failed to destroy hdd_conc_list_lock");
+		if (!CDF_IS_STATUS_SUCCESS(cds_deinit_policy_mgr())) {
+			hdd_err("Failed to deinit policy manager");
 			/* Proceed and complete the clean up */
 		}
 	}
@@ -1652,7 +1644,6 @@ err_re_init:
 	return -EPERM;
 
 success:
-	pHddCtx->isLogpInProgress = false;
 	return CDF_STATUS_SUCCESS;
 }
 
@@ -1738,7 +1729,7 @@ static int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -1767,16 +1758,16 @@ static int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
 	MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
 			 TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
 			 NO_SESSION, pHddCtx->isWiphySuspended));
-	spin_lock(&pHddCtx->schedScan_lock);
+	cdf_spin_lock(&pHddCtx->sched_scan_lock);
 	pHddCtx->isWiphySuspended = false;
 	if (true != pHddCtx->isSchedScanUpdatePending) {
-		spin_unlock(&pHddCtx->schedScan_lock);
+		cdf_spin_unlock(&pHddCtx->sched_scan_lock);
 		hddLog(LOG1, FL("Return resume is not due to PNO indication"));
 		return 0;
 	}
 	/* Reset flag to avoid updatating cfg80211 data old results again */
 	pHddCtx->isSchedScanUpdatePending = false;
-	spin_unlock(&pHddCtx->schedScan_lock);
+	cdf_spin_unlock(&pHddCtx->sched_scan_lock);
 
 	status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
 
@@ -1874,7 +1865,7 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -2094,7 +2085,7 @@ static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -2175,9 +2166,7 @@ int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
  * Return: 0 for success, non-zero for failure
  */
 static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
 					   struct wireless_dev *wdev,
-#endif
 					   enum nl80211_tx_power_setting type,
 					   int dbm)
 {
@@ -2189,7 +2178,7 @@ static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -2248,18 +2237,14 @@ static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
  * Return: 0 for success, non-zero for failure
  */
 int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
 				  struct wireless_dev *wdev,
-#endif
 				  enum nl80211_tx_power_setting type,
 				  int dbm)
 {
 	int ret;
 	cds_ssr_protect(__func__);
 	ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
 					      wdev,
-#endif
 					      type, dbm);
 	cds_ssr_unprotect(__func__);
 
@@ -2275,9 +2260,7 @@ int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
  * Return: 0 for success, non-zero for failure
  */
 static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
 				  struct wireless_dev *wdev,
-#endif
 				  int *dbm)
 {
 
@@ -2287,7 +2270,7 @@ static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -2327,18 +2310,14 @@ static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
  * Return: 0 for success, error number on failure.
  */
 int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) || defined(WITH_BACKPORTS)
 					 struct wireless_dev *wdev,
-#endif
 					 int *dbm)
 {
 	int ret;
 
 	cds_ssr_protect(__func__);
 	ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) || defined(WITH_BACKPORTS)
 						wdev,
-#endif
 						dbm);
 	cds_ssr_unprotect(__func__);
 

+ 20 - 32
core/hdd/src/wlan_hdd_scan.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1014,6 +1014,7 @@ static void hdd_vendor_scan_callback(hdd_adapter_t *adapter,
 
 	if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
 		hdd_err("Invalid adapter magic");
+		cdf_mem_free(req);
 		return;
 	}
 	skb = cfg80211_vendor_event_alloc(hddctx->wiphy, NULL,
@@ -1023,6 +1024,7 @@ static void hdd_vendor_scan_callback(hdd_adapter_t *adapter,
 
 	if (!skb) {
 		hdd_err("skb alloc failed");
+		cdf_mem_free(req);
 		return;
 	}
 
@@ -1067,10 +1069,12 @@ static void hdd_vendor_scan_callback(hdd_adapter_t *adapter,
 		goto nla_put_failure;
 
 	cfg80211_vendor_event(skb, GFP_KERNEL);
+	cdf_mem_free(req);
 	return;
 
 nla_put_failure:
 	kfree_skb(skb);
+	cdf_mem_free(req);
 	return;
 }
 
@@ -1223,15 +1227,10 @@ static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
  * Return: 0 for success, non zero for failure
  */
 static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-				    struct net_device *dev,
-#endif
 				    struct cfg80211_scan_request *request,
 				    uint8_t source)
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 	struct net_device *dev = request->wdev->netdev;
-#endif
 	hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
 	hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
@@ -1246,7 +1245,7 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -1328,9 +1327,6 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
 	 * (return -EBUSY)
 	 */
 	status = wlan_hdd_tdls_scan_callback(pAdapter, wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-						dev,
-#endif
 					request);
 	if (status <= 0) {
 		if (!status)
@@ -1345,7 +1341,7 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
 #endif
 
 	/* Check if scan is allowed at this point of time */
-	if (cds_is_connection_in_progress(pHddCtx)) {
+	if (cds_is_connection_in_progress()) {
 		hddLog(LOGE, FL("Scan not allowed"));
 		return -EBUSY;
 	}
@@ -1598,17 +1594,11 @@ free_mem:
  * Return: 0 for success, non zero for failure
  */
 int wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-			   struct net_device *dev,
-#endif
 			   struct cfg80211_scan_request *request)
 {
 	int ret;
 	cds_ssr_protect(__func__);
 	ret = __wlan_hdd_cfg80211_scan(wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-				       dev,
-#endif
 				request, NL_SCAN);
 	cds_ssr_unprotect(__func__);
 	return ret;
@@ -1965,15 +1955,15 @@ hdd_sched_scan_callback(void *callbackContext,
 		return;
 	}
 
-	spin_lock(&pHddCtx->schedScan_lock);
+	cdf_spin_lock(&pHddCtx->sched_scan_lock);
 	if (true == pHddCtx->isWiphySuspended) {
 		pHddCtx->isSchedScanUpdatePending = true;
-		spin_unlock(&pHddCtx->schedScan_lock);
+		cdf_spin_unlock(&pHddCtx->sched_scan_lock);
 		hddLog(LOG1,
 		       FL("Update cfg80211 scan database after it resume"));
 		return;
 	}
-	spin_unlock(&pHddCtx->schedScan_lock);
+	cdf_spin_unlock(&pHddCtx->sched_scan_lock);
 
 	ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter, 0);
 
@@ -2041,7 +2031,7 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -2199,12 +2189,8 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
 		/*Copying list of valid channel into request */
 		memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
 		pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
 		pPnoRequest->aNetworks[i].rssiThreshold =
 			request->match_sets[i].rssi_thold;
-#else
-		pPnoRequest->aNetworks[i].rssiThreshold = 0;    /* Default value */
-#endif
 	}
 
 	for (i = 0; i < request->n_ssids; i++) {
@@ -2320,7 +2306,7 @@ static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -2332,8 +2318,8 @@ static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
 		return -ENODEV;
 	}
 
-	/* The return 0 is intentional when isLogpInProgress and
-	 * isLoadUnloadInProgress. We did observe a crash due to a return of
+	/* The return 0 is intentional when Recovery and Load/Unload in
+	 * progress. We did observe a crash due to a return of
 	 * failure in sched_scan_stop , especially for a case where the unload
 	 * of the happens at the same time. The function __cfg80211_stop_sched_scan
 	 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
@@ -2341,13 +2327,15 @@ static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
 	 * clean up of the second interface will have the dev pointer corresponding
 	 * to the first one leading to a crash.
 	 */
-	if (pHddCtx->isLogpInProgress) {
-		hddLog(LOGE, FL("LOGP in Progress. Ignore!!!"));
+	if (cds_is_driver_recovering()) {
+		hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
+			 cds_get_driver_state());
 		return ret;
 	}
 
-	if ((pHddCtx->isLoadInProgress) || (pHddCtx->isUnloadInProgress)) {
-		hddLog(LOGE, FL("Unloading/Loading in Progress. Ignore!!!"));
+	if (cds_is_load_or_unload_in_progress()) {
+		hdd_err("Unload/Load in Progress, state: 0x%x.  Ignore!!!",
+			cds_get_driver_state());
 		return ret;
 	}
 

+ 0 - 3
core/hdd/src/wlan_hdd_scan.h

@@ -51,9 +51,6 @@ int iw_set_scan(struct net_device *dev, struct iw_request_info *info,
 		union iwreq_data *wrqu, char *extra);
 
 int wlan_hdd_cfg80211_scan(struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-			   struct net_device *dev,
-#endif
 			   struct cfg80211_scan_request *request);
 
 #ifdef FEATURE_WLAN_SCAN_PNO

+ 9 - 10
core/hdd/src/wlan_hdd_softap_tx_rx.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -168,7 +168,6 @@ int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	sme_ac_enum_type ac = SME_AC_BE;
 	hdd_adapter_t *pAdapter = (hdd_adapter_t *) netdev_priv(dev);
 	hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
-	hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
 	struct cdf_mac_addr *pDestMacAddress;
 	uint8_t STAId;
 	uint8_t proto_type = 0;
@@ -181,9 +180,9 @@ int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	 * context may not be reinitialized at this time which may
 	 * lead to a crash.
 	 */
-	if (pHddCtx->isLogpInProgress) {
+	if (cds_is_driver_recovering()) {
 		CDF_TRACE(CDF_MODULE_ID_HDD_SAP_DATA, CDF_TRACE_LEVEL_INFO_HIGH,
-			  "%s: LOGP in Progress. Ignore!!!", __func__);
+			  "%s: Recovery in Progress. Ignore!!!", __func__);
 		goto drop_pkt;
 	}
 
@@ -368,9 +367,9 @@ static void __hdd_softap_tx_timeout(struct net_device *dev)
 	 * recovery here
 	 */
 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-	if (hdd_ctx->isLogpInProgress) {
+	if (cds_is_driver_recovering()) {
 		CDF_TRACE(CDF_MODULE_ID_HDD_SAP_DATA, CDF_TRACE_LEVEL_ERROR,
-			 "%s: LOGP in Progress. Ignore!!!", __func__);
+			 "%s: Recovery in Progress. Ignore!!!", __func__);
 		return;
 	}
 }
@@ -581,7 +580,7 @@ CDF_STATUS hdd_softap_rx_packet_cbk(void *cds_context,
 	 */
 	cdf_net_buf_debug_release_skb(rxBuf);
 
-	if (hdd_napi_enabled(HDD_NAPI_ANY))
+	if (hdd_napi_enabled(HDD_NAPI_ANY) && !pHddCtx->config->enableRxThread)
 		rxstat = netif_receive_skb(skb);
 	else
 		rxstat = netif_rx_ni(skb);
@@ -810,10 +809,10 @@ CDF_STATUS hdd_softap_stop_bss(hdd_adapter_t *pAdapter)
 	/* bss deregister is not allowed during wlan driver loading or
 	 * unloading
 	 */
-	if ((pHddCtx->isLoadInProgress) || (pHddCtx->isUnloadInProgress)) {
+	if (cds_is_load_or_unload_in_progress()) {
 		CDF_TRACE(CDF_MODULE_ID_HDD_SAP_DATA, CDF_TRACE_LEVEL_ERROR,
-			  "%s:Loading_unloading in Progress. Ignore!!!",
-			  __func__);
+			  "%s: Loading_unloading in Progress, state: 0x%x. Ignore!!!",
+			  __func__, cds_get_driver_state());
 		return CDF_STATUS_E_PERM;
 	}
 

+ 23 - 17
core/hdd/src/wlan_hdd_stats.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1100,12 +1100,12 @@ static void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx,
 }
 
 /**
- * wlan_hdd_cfg80211_link_layer_stats_init() - initialize link layer stats
+ * hdd_cfg80211_link_layer_stats_init() - Initialize link layer stats
  * @pHddCtx: Pointer to hdd context
  *
  * Return: None
  */
-void wlan_hdd_cfg80211_link_layer_stats_init(hdd_context_t *pHddCtx)
+void hdd_cfg80211_link_layer_stats_init(hdd_context_t *pHddCtx)
 {
 	sme_set_link_layer_stats_ind_cb(pHddCtx->hHal,
 					wlan_hdd_cfg80211_link_layer_stats_callback);
@@ -1144,7 +1144,7 @@ __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -1270,7 +1270,7 @@ __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -1401,7 +1401,7 @@ __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -1546,7 +1546,7 @@ static int __wlan_hdd_cfg80211_stats_ext_request(struct wiphy *wiphy,
 	if (ret_val)
 		return ret_val;
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -1723,7 +1723,7 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -1753,7 +1753,7 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
 #ifdef WLAN_FEATURE_LPSS
 	if (!pAdapter->rssi_send) {
 		pAdapter->rssi_send = true;
-		if (pHddCtx->isUnloadInProgress != true)
+		if (cds_is_driver_unloading())
 			wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 1);
 	}
 #endif
@@ -1779,13 +1779,12 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
 			pAdapter->hdd_stats.ClassA_stat.mcs_index = 0;
 		}
 	}
-#ifdef LINKSPEED_DEBUG_ENABLED
-	pr_info("RSSI %d, RLMS %u, rate %d, rssi high %d, rssi mid %d, rssi low %d, rate_flags 0x%x, MCS %d\n",
-		sinfo->signal, pCfg->reportMaxLinkSpeed, myRate,
-		(int)pCfg->linkSpeedRssiHigh, (int)pCfg->linkSpeedRssiMid,
-		(int)pCfg->linkSpeedRssiLow, (int)rate_flags,
-		(int)pAdapter->hdd_stats.ClassA_stat.mcs_index);
-#endif /* LINKSPEED_DEBUG_ENABLED */
+
+	hdd_info("RSSI %d, RLMS %u, rate %d, rssi high %d, rssi mid %d, rssi low %d, rate_flags 0x%x, MCS %d",
+		 sinfo->signal, pCfg->reportMaxLinkSpeed, myRate,
+		 (int)pCfg->linkSpeedRssiHigh, (int)pCfg->linkSpeedRssiMid,
+		 (int)pCfg->linkSpeedRssiLow, (int)rate_flags,
+		 (int)pAdapter->hdd_stats.ClassA_stat.mcs_index);
 
 	if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed) {
 		/* we do not want to necessarily report the current speed */
@@ -2118,6 +2117,13 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy,
 #endif /* LINKSPEED_DEBUG_ENABLED */
 		}
 	}
+
+	if (rate_flags & eHAL_TX_RATE_LEGACY)
+		hdd_info("Reporting legacy rate %d", sinfo->txrate.legacy);
+	else
+		hdd_info("Reporting MCS rate %d flags 0x%x",
+			 sinfo->txrate.mcs, sinfo->txrate.flags);
+
 	sinfo->filled |= STATION_INFO_TX_BITRATE;
 
 	sinfo->tx_bytes = pAdapter->stats.tx_bytes;
@@ -2224,7 +2230,7 @@ static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}

+ 23 - 0
core/hdd/src/wlan_hdd_stats.h

@@ -90,6 +90,8 @@ struct index_data_rate_type {
  */
 #define LL_STATS_EVENT_BUF_SIZE 4096
 
+void hdd_cfg80211_link_layer_stats_init(hdd_context_t *pHddCtx);
+
 /**
  * wlan_hdd_cfg80211_ll_stats_set() - set link layer stats
  * @wiphy: Pointer to wiphy
@@ -134,12 +136,29 @@ int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
 				     int data_len);
 
 void hdd_init_ll_stats_ctx(void);
+
+static inline bool hdd_link_layer_stats_supported(void)
+{
+	return true;
+}
+
 #else
+
+static inline void hdd_cfg80211_link_layer_stats_init(hdd_context_t *pHddCtx)
+{
+	return;
+}
+
 static inline void hdd_init_ll_stats_ctx(void)
 {
 	return;
 }
 
+static inline bool hdd_link_layer_stats_supported(void)
+{
+	return false;
+}
+
 #endif /* End of WLAN_FEATURE_LINK_LAYER_STATS */
 
 #ifdef WLAN_FEATURE_STATS_EXT
@@ -156,6 +175,10 @@ int wlan_hdd_cfg80211_stats_ext_request(struct wiphy *wiphy,
 					struct wireless_dev *wdev,
 					const void *data,
 					int data_len);
+
+void wlan_hdd_cfg80211_stats_ext_init(hdd_context_t *pHddCtx);
+#else
+static inline void wlan_hdd_cfg80211_stats_ext_init(hdd_context_t *pHddCtx) {}
 #endif /* End of WLAN_FEATURE_STATS_EXT */
 
 /**

+ 195 - 0
core/hdd/src/wlan_hdd_subnet_detect.c

@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_hdd_subnet_detect.c
+ *
+ * WLAN Host Device Driver subnet detect API implementation
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <net/cfg80211.h>
+#include <ani_global.h>
+#include "sme_api.h"
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_subnet_detect.h"
+
+/*
+ * define short names for the global vendor params
+ * used by __wlan_hdd_cfg80211_set_gateway_params()
+ */
+#define PARAM_MAC_ADDR QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_GW_MAC_ADDR
+#define PARAM_IPV4_ADDR QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV4_ADDR
+#define PARAM_IPV6_ADDR QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV6_ADDR
+
+static const struct nla_policy
+	policy[QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_MAX + 1] = {
+		[PARAM_MAC_ADDR] = {
+				.type = NLA_BINARY,
+				.len = CDF_MAC_ADDR_SIZE
+		},
+		[PARAM_IPV4_ADDR] = {
+				.type = NLA_BINARY,
+				.len = CDF_IPV4_ADDR_SIZE
+		},
+		[PARAM_IPV6_ADDR] = {
+				.type = NLA_BINARY,
+				.len = CDF_IPV6_ADDR_SIZE
+		}
+};
+
+/**
+ * __wlan_hdd_cfg80211_set_gateway_params() - set gateway params
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_set_gateway_params(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_MAX + 1];
+	struct gateway_param_update_req req = { 0 };
+	int ret;
+	CDF_STATUS status;
+
+	ENTER();
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	/* user may have disabled the feature in INI */
+	if (!hdd_ctx->config->enable_lfr_subnet_detection) {
+		hdd_info("LFR Subnet Detection disabled in INI");
+		return -ENOTSUPP;
+	}
+
+	/* The gateway parameters are only valid in the STA persona
+	 * and only in the connected state.
+	 */
+	if (WLAN_HDD_INFRA_STATION != adapter->device_mode) {
+		hdd_err("Received GW param update for non-STA mode adapter");
+		return -ENOTSUPP;
+	}
+
+	if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
+		hdd_err("Received GW param update in disconnected state!");
+		return -ENOTSUPP;
+	}
+
+	/* Extract NL parameters
+	 * mac_addr:  6 bytes
+	 * ipv4 addr: 4 bytes
+	 * ipv6 addr: 16 bytes
+	 */
+	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_MAX,
+			data, data_len, policy)) {
+		hdd_err("Invalid ATTR list");
+		return -EINVAL;
+	}
+
+	if (!tb[PARAM_MAC_ADDR]) {
+		hdd_err("request mac addr failed");
+		return -EINVAL;
+	}
+	nla_memcpy(req.gw_mac_addr.bytes, tb[PARAM_MAC_ADDR],
+			CDF_MAC_ADDR_SIZE);
+
+	/* req ipv4_addr_type and ipv6_addr_type are initially false due
+	 * to zeroing the struct
+	 */
+	if (tb[PARAM_IPV4_ADDR]) {
+		nla_memcpy(req.ipv4_addr, tb[PARAM_IPV4_ADDR],
+			CDF_IPV4_ADDR_SIZE);
+		req.ipv4_addr_type = true;
+	}
+
+	if (tb[PARAM_IPV6_ADDR]) {
+		nla_memcpy(&req.ipv6_addr, tb[PARAM_IPV6_ADDR],
+			CDF_IPV6_ADDR_SIZE);
+		req.ipv6_addr_type = true;
+	}
+
+	if (!req.ipv4_addr_type && !req.ipv6_addr_type) {
+		hdd_err("invalid ipv4 or ipv6 gateway address");
+		return -EINVAL;
+	}
+
+	req.max_retries = 3;
+	req.timeout = 100;   /* in milliseconds */
+	req.session_id = adapter->sessionId;
+
+	hdd_info("**** Gateway Parameters: ****");
+	hdd_info("session id: %d", req.session_id);
+	hdd_info("ipv4 addr type: %d", req.ipv4_addr_type);
+	hdd_info("ipv6 addr type: %d", req.ipv6_addr_type);
+	hdd_info("gw mac addr: %pM", req.gw_mac_addr.bytes);
+	hdd_info("ipv4 addr: %pI4", req.ipv4_addr);
+	hdd_info("ipv6 addr: %pI6c", req.ipv6_addr);
+
+	status = sme_gateway_param_update(hdd_ctx->hHal, &req);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_gateway_param_update failed(err=%d)", status);
+		ret = -EINVAL;
+	}
+
+	EXIT();
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_gateway_params() - set gateway parameters
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * The API is invoked by the user space to set the gateway parameters
+ * such as mac address and the IP address which is used for detecting
+ * the IP subnet change
+ *
+ * Return: 0 on success; errno on failure
+ */
+int wlan_hdd_cfg80211_set_gateway_params(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+
+	ret = __wlan_hdd_cfg80211_set_gateway_params(
+				wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+	return ret;
+}
+#undef PARAM_MAC_ADDR
+#undef PARAM_IPV4_ADDR
+#undef PARAM_IPV6_ADDR

+ 44 - 0
core/hdd/src/wlan_hdd_subnet_detect.h

@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifndef __WLAN_HDD_SUBNET_DETECT_H
+#define __WLAN_HDD_SUBNET_DETECT_H
+
+/**
+ * DOC: wlan_hdd_subnet_detect.h
+ *
+ * WLAN Host Device Driver subnet detect API specification
+ */
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+struct wiphy;
+struct wireless_dev;
+
+int wlan_hdd_cfg80211_set_gateway_params(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void *data, int data_len);
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+#endif /* __WLAN_HDD_SUBNET_DETECT_H */

+ 190 - 125
core/hdd/src/wlan_hdd_tdls.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -419,9 +419,6 @@ static void wlan_hdd_tdls_schedule_scan(struct work_struct *work)
 	scan_ctx->attempt++;
 
 	wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-			       scan_ctx->dev,
-#endif
 			       scan_ctx->scan_request);
 }
 
@@ -438,7 +435,7 @@ static void dump_tdls_state_param_setting(tdlsInfo_t *info)
 
 	hddLog(LOG1,
 		FL(
-		   "Setting tdls state and param in fw: vdev_id: %d, tdls_state: %d, notification_interval_ms: %d, tx_discovery_threshold: %d, tx_teardown_threshold: %d, rssi_teardown_threshold: %d, rssi_delta: %d, tdls_options: 0x%x, peer_traffic_ind_window: %d, peer_traffic_response_timeout: %d, puapsd_mask: 0x%x, puapsd_inactivity_time: %d, puapsd_rx_frame_threshold: %d"
+		   "Setting tdls state and param in fw: vdev_id: %d, tdls_state: %d, notification_interval_ms: %d, tx_discovery_threshold: %d, tx_teardown_threshold: %d, rssi_teardown_threshold: %d, rssi_delta: %d, tdls_options: 0x%x, peer_traffic_ind_window: %d, peer_traffic_response_timeout: %d, puapsd_mask: 0x%x, puapsd_inactivity_time: %d, puapsd_rx_frame_threshold: %d, teardown_notification_ms: %d, tdls_peer_kickout_threshold: %d"
 		),
 		info->vdev_id,
 		info->tdls_state,
@@ -452,7 +449,9 @@ static void dump_tdls_state_param_setting(tdlsInfo_t *info)
 		info->peer_traffic_response_timeout,
 		info->puapsd_mask,
 		info->puapsd_inactivity_time,
-		info->puapsd_rx_frame_threshold);
+		info->puapsd_rx_frame_threshold,
+		info->teardown_notification_ms,
+		info->tdls_peer_kickout_threshold);
 }
 
 
@@ -508,6 +507,21 @@ static void wlan_hdd_tdls_del_non_forced_peers(tdlsCtx_t *hdd_tdls_ctx)
 	}
 }
 
+/**
+ * hdd_tdls_pre_init - TDLS pre init
+ * @hdd_ctx:	HDD context
+ *
+ * tdls_lock is initialized before an hdd_open_adapter ( which is
+ * invoked by other instances also) to protect the concurrent
+ * access for the Adapters by TDLS module.
+ *
+ * Return: None
+ */
+void hdd_tdls_pre_init(hdd_context_t *hdd_ctx)
+{
+	mutex_init(&hdd_ctx->tdls_lock);
+}
+
 /**
  * wlan_hdd_tdls_init() - tdls initializaiton
  * @pAdapter: hdd adapter
@@ -638,6 +652,8 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter)
 		pHddCtx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY;
 		hddLog(CDF_TRACE_LEVEL_ERROR,
 		       "%s TDLS Implicit trigger not enabled!", __func__);
+	} else if (true == pHddCtx->config->fTDLSExternalControl) {
+		pHddCtx->tdls_mode = eTDLS_SUPPORT_EXTERNAL_CONTROL;
 	} else {
 		pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED;
 	}
@@ -700,7 +716,10 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter)
 		pHddCtx->config->fTDLSPuapsdInactivityTimer;
 	tInfo->puapsd_rx_frame_threshold =
 		pHddCtx->config->fTDLSRxFrameThreshold;
-
+	tInfo->teardown_notification_ms =
+		pHddCtx->config->tdls_idle_timeout;
+	tInfo->tdls_peer_kickout_threshold =
+		pHddCtx->config->tdls_peer_kickout_threshold;
 	dump_tdls_state_param_setting(tInfo);
 
 	cdf_ret_status = sme_update_fw_tdls_state(pHddCtx->hHal, tInfo, true);
@@ -767,7 +786,7 @@ void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter)
 
 	/* No need to post message during driver unlaod because MC thread is
 	   already shutdown */
-	if (!pHddCtx->isUnloadInProgress) {
+	if (!cds_is_driver_unloading()) {
 		tInfo = cdf_mem_malloc(sizeof(tdlsInfo_t));
 		if (NULL != tInfo) {
 			tInfo->vdev_id = pAdapter->sessionId;
@@ -799,7 +818,10 @@ void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter)
 				pHddCtx->config->fTDLSPuapsdInactivityTimer;
 			tInfo->puapsd_rx_frame_threshold =
 				pHddCtx->config->fTDLSRxFrameThreshold;
-
+			tInfo->teardown_notification_ms =
+				pHddCtx->config->tdls_idle_timeout;
+			tInfo->tdls_peer_kickout_threshold =
+				pHddCtx->config->tdls_peer_kickout_threshold;
 			dump_tdls_state_param_setting(tInfo);
 
 			cdf_ret_status =
@@ -1351,7 +1373,8 @@ int wlan_hdd_tdls_increment_pkt_count(hdd_adapter_t *pAdapter,
 	hddTdlsPeer_t *curr_peer;
 	hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
 
-	if (eTDLS_SUPPORT_ENABLED != pHddCtx->tdls_mode)
+	if (eTDLS_SUPPORT_ENABLED != pHddCtx->tdls_mode &&
+	    eTDLS_SUPPORT_EXTERNAL_CONTROL != pHddCtx->tdls_mode)
 		return -EINVAL;
 
 	curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
@@ -1532,11 +1555,11 @@ void wlan_hdd_tdls_set_mode(hdd_context_t *pHddCtx,
 		pAdapter = pAdapterNode->pAdapter;
 		pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
 		if (NULL != pHddTdlsCtx) {
-			if (eTDLS_SUPPORT_ENABLED == tdls_mode)
+			if (eTDLS_SUPPORT_ENABLED == tdls_mode ||
+			    eTDLS_SUPPORT_EXTERNAL_CONTROL == tdls_mode)
 				wlan_hdd_tdls_implicit_enable(pHddTdlsCtx);
 			else if ((eTDLS_SUPPORT_DISABLED == tdls_mode) ||
-				 (eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY ==
-				  tdls_mode))
+				 (eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == tdls_mode))
 				wlan_hdd_tdls_implicit_disable(pHddTdlsCtx);
 		}
 		status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
@@ -1587,7 +1610,8 @@ int wlan_hdd_tdls_set_params(struct net_device *dev,
 	}
 
 	/* copy the configuration only when given tdls mode is implicit trigger enable */
-	if (eTDLS_SUPPORT_ENABLED == req_tdls_mode) {
+	if (eTDLS_SUPPORT_ENABLED == req_tdls_mode ||
+	    eTDLS_SUPPORT_EXTERNAL_CONTROL == req_tdls_mode) {
 		memcpy(&pHddTdlsCtx->threshold_config, config,
 		       sizeof(tdls_config_params_t));
 	}
@@ -1634,36 +1658,12 @@ int wlan_hdd_tdls_set_params(struct net_device *dev,
 		pHddCtx->config->fTDLSPuapsdInactivityTimer;
 	tdlsParams->puapsd_rx_frame_threshold =
 		pHddCtx->config->fTDLSRxFrameThreshold;
+	tdlsParams->teardown_notification_ms =
+		pHddCtx->config->tdls_idle_timeout;
+	tdlsParams->tdls_peer_kickout_threshold =
+		pHddCtx->config->tdls_peer_kickout_threshold;
 
-	hddLog(LOG1,
-		  "%s: Setting tdls state and param in fw: "
-		  "vdev_id: %d, "
-		  "tdls_state: %d, "
-		  "notification_interval_ms: %d, "
-		  "tx_discovery_threshold: %d, "
-		  "tx_teardown_threshold: %d, "
-		  "rssi_teardown_threshold: %d, "
-		  "rssi_delta: %d, "
-		  "tdls_options: 0x%x, "
-		  "peer_traffic_ind_window: %d, "
-		  "peer_traffic_response_timeout: %d, "
-		  "puapsd_mask: 0x%x, "
-		  "puapsd_inactivity_time: %d, "
-		  "puapsd_rx_frame_threshold: %d ",
-		  __func__,
-		  tdlsParams->vdev_id,
-		  tdlsParams->tdls_state,
-		  tdlsParams->notification_interval_ms,
-		  tdlsParams->tx_discovery_threshold,
-		  tdlsParams->tx_teardown_threshold,
-		  tdlsParams->rssi_teardown_threshold,
-		  tdlsParams->rssi_delta,
-		  tdlsParams->tdls_options,
-		  tdlsParams->peer_traffic_ind_window,
-		  tdlsParams->peer_traffic_response_timeout,
-		  tdlsParams->puapsd_mask,
-		  tdlsParams->puapsd_inactivity_time,
-		  tdlsParams->puapsd_rx_frame_threshold);
+	dump_tdls_state_param_setting(tdlsParams);
 
 	cdf_ret_status = sme_update_fw_tdls_state(pHddCtx->hHal, tdlsParams, true);
 	if (CDF_STATUS_SUCCESS != cdf_ret_status) {
@@ -1716,15 +1716,14 @@ void wlan_hdd_update_tdls_info(hdd_adapter_t *adapter, bool tdls_prohibited,
 	if (tdls_prohibited) {
 		hdd_ctx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED;
 	} else {
-		if (false == hdd_ctx->config->fEnableTDLSImplicitTrigger) {
-			hdd_ctx->tdls_mode =
-				eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY;
-		} else {
+		if (false == hdd_ctx->config->fEnableTDLSImplicitTrigger)
+			hdd_ctx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY;
+		else if (true == hdd_ctx->config->fTDLSExternalControl)
+			hdd_ctx->tdls_mode = eTDLS_SUPPORT_EXTERNAL_CONTROL;
+		else
 			hdd_ctx->tdls_mode = eTDLS_SUPPORT_ENABLED;
-		}
 	}
 	mutex_unlock(&hdd_ctx->tdls_lock);
-
 	tdls_param = cdf_mem_malloc(sizeof(*tdls_param));
 	if (!tdls_param) {
 		hddLog(CDF_TRACE_LEVEL_ERROR,
@@ -1768,35 +1767,12 @@ void wlan_hdd_update_tdls_info(hdd_adapter_t *adapter, bool tdls_prohibited,
 		hdd_ctx->config->fTDLSPuapsdInactivityTimer;
 	tdls_param->puapsd_rx_frame_threshold =
 		hdd_ctx->config->fTDLSRxFrameThreshold;
+	tdls_param->teardown_notification_ms =
+		hdd_ctx->config->tdls_idle_timeout;
+	tdls_param->tdls_peer_kickout_threshold =
+		hdd_ctx->config->tdls_peer_kickout_threshold;
 
-	hddLog(CDF_TRACE_LEVEL_DEBUG,
-		FL("Setting tdls state and param in fw: "
-		"vdev_id: %d, "
-		"tdls_state: %d, "
-		"notification_interval_ms: %d, "
-		"tx_discovery_threshold: %d, "
-		"tx_teardown_threshold: %d, "
-		"rssi_teardown_threshold: %d, "
-		"rssi_delta: %d, "
-		"tdls_options: 0x%x, "
-		"peer_traffic_ind_window: %d, "
-		"peer_traffic_response_timeout: %d, "
-		"puapsd_mask: 0x%x, "
-		"puapsd_inactivity_time: %d, "
-		"puapsd_rx_frame_threshold: %d "),
-		tdls_param->vdev_id,
-		tdls_param->tdls_state,
-		tdls_param->notification_interval_ms,
-		tdls_param->tx_discovery_threshold,
-		tdls_param->tx_teardown_threshold,
-		tdls_param->rssi_teardown_threshold,
-		tdls_param->rssi_delta,
-		tdls_param->tdls_options,
-		tdls_param->peer_traffic_ind_window,
-		tdls_param->peer_traffic_response_timeout,
-		tdls_param->puapsd_mask,
-		tdls_param->puapsd_inactivity_time,
-		tdls_param->puapsd_rx_frame_threshold);
+	dump_tdls_state_param_setting(tdls_param);
 
 	cdf_ret_status = sme_update_fw_tdls_state(hdd_ctx->hHal,
 					       tdls_param,
@@ -1864,6 +1840,38 @@ int wlan_hdd_tdls_set_extctrl_param(hdd_adapter_t *pAdapter, const uint8_t *mac,
 	return 0;
 }
 
+/**
+ * wlan_hdd_tdls_update_peer_mac() - Update the peer mac information to firmware
+ * @adapter: hdd adapter to interface
+ * @mac: Mac address of the peer to be added
+ * @peerState: Current state of the peer
+ *
+ * This function updates TDLS peer state to firmware. Firmware will update
+ * connection table based on new peer state.
+ *
+ * Return:success (0) or failure (errno value)
+ */
+int wlan_hdd_tdls_update_peer_mac(hdd_adapter_t *adapter, const uint8_t *mac,
+				  uint32_t peer_state)
+{
+	tSmeTdlsPeerStateParams sme_tdls_peer_state_params = {0};
+	CDF_STATUS status = CDF_STATUS_E_FAILURE;
+	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	sme_tdls_peer_state_params.vdevId = adapter->sessionId;
+	cdf_mem_copy(&sme_tdls_peer_state_params.peerMacAddr, mac,
+		     sizeof(sme_tdls_peer_state_params.peerMacAddr));
+	sme_tdls_peer_state_params.peerState = peer_state;
+	status = sme_update_tdls_peer_state(hdd_ctx->hHal,
+					    &sme_tdls_peer_state_params);
+	if (CDF_STATUS_SUCCESS != status) {
+		hddLog(LOGE, FL("sme_UpdateTdlsPeerState failed for "MAC_ADDRESS_STR),
+				MAC_ADDR_ARRAY(mac));
+		return -EPERM;
+	}
+	return 0;
+}
+
 /**
  * wlan_hdd_tdls_set_force_peer() - set/clear isForcedPeer flag on a peer
  * @pAdapter: HDD adapter
@@ -2170,13 +2178,13 @@ void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter)
 		FL("update %d"),
 		pHddTdlsCtx->threshold_config.tx_period_t);
 
-	if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) {
+	if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode ||
+	    eTDLS_SUPPORT_EXTERNAL_CONTROL == pHddCtx->tdls_mode) {
 		wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
 		pHddTdlsCtx->discovery_sent_cnt = 0;
-		wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->
-							  pAdapter);
-
+		wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
 	}
+
 	mutex_unlock(&pHddCtx->tdls_lock);
 
 }
@@ -2464,6 +2472,15 @@ static void __wlan_hdd_tdls_pre_setup(struct work_struct *work)
 				  discovery_tries_n,
 				  MAC_ADDR_ARRAY(curr_peer->peerMac));
 			curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
+			/* Since TDLS discovery attempt reached the
+			 * maximum threshold, so we remove the peer
+			 * from the FW connection table.
+			 */
+			if (0 != wlan_hdd_tdls_update_peer_mac(pHddTdlsCtx->pAdapter,
+				curr_peer->peerMac, eSME_TDLS_PEER_REMOVE_MAC_ADDR))
+				hddLog(LOGE, FL("TDLS Peer mac update Failed "
+					   MAC_ADDRESS_STR),
+					   MAC_ADDR_ARRAY(curr_peer->peerMac));
 			goto done;
 		}
 	}
@@ -2554,9 +2571,6 @@ void wlan_hdd_tdls_pre_setup(struct work_struct *work)
  */
 int wlan_hdd_tdls_copy_scan_context(hdd_context_t *pHddCtx,
 				    struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-				    struct net_device *dev,
-#endif
 				    struct cfg80211_scan_request *request)
 {
 	tdls_scan_context_t *scan_ctx;
@@ -2569,9 +2583,6 @@ int wlan_hdd_tdls_copy_scan_context(hdd_context_t *pHddCtx,
 	scan_ctx = &pHddCtx->tdls_scan_ctxt;
 
 	scan_ctx->wiphy = wiphy;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-	scan_ctx->dev = dev;
-#endif
 
 	scan_ctx->scan_request = request;
 	EXIT();
@@ -2590,18 +2601,11 @@ int wlan_hdd_tdls_copy_scan_context(hdd_context_t *pHddCtx,
  */
 static void wlan_hdd_tdls_scan_init_work(hdd_context_t *pHddCtx,
 					 struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-					 struct net_device *dev,
-#endif
 					 struct cfg80211_scan_request *request,
 					 unsigned long delay)
 {
 	if (TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic) {
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-		wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, dev, request);
-#else
 		wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, request);
-#endif
 		pHddCtx->tdls_scan_ctxt.attempt = 0;
 		pHddCtx->tdls_scan_ctxt.magic = TDLS_CTX_MAGIC;
 	}
@@ -2620,9 +2624,6 @@ static void wlan_hdd_tdls_scan_init_work(hdd_context_t *pHddCtx,
  *         1 = caller can continue to scan
  */
 int wlan_hdd_tdls_scan_callback(hdd_adapter_t *pAdapter, struct wiphy *wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-				struct net_device *dev,
-#endif
 				struct cfg80211_scan_request *request)
 {
 	hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
@@ -2677,9 +2678,6 @@ int wlan_hdd_tdls_scan_callback(hdd_adapter_t *pAdapter, struct wiphy *wiphy,
 				  pHddCtx->tdls_scan_ctxt.attempt, delay);
 
 			wlan_hdd_tdls_scan_init_work(pHddCtx, wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-						     dev,
-#endif
 						     request,
 						     msecs_to_jiffies(delay));
 			/* scan should not continue */
@@ -2694,6 +2692,7 @@ int wlan_hdd_tdls_scan_callback(hdd_adapter_t *pAdapter, struct wiphy *wiphy,
 	}
 	/* while tdls is up, first time scan */
 	else if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode ||
+		 eTDLS_SUPPORT_EXTERNAL_CONTROL == pHddCtx->tdls_mode ||
 		 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode) {
 		/* disable implicit trigger logic & tdls operatoin */
 		wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, false);
@@ -2778,9 +2777,6 @@ int wlan_hdd_tdls_scan_callback(hdd_adapter_t *pAdapter, struct wiphy *wiphy,
 				  wlan_hdd_tdls_connected_peers(pAdapter), delay);
 
 			wlan_hdd_tdls_scan_init_work(pHddCtx, wiphy,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
-						     dev,
-#endif
 						     request,
 						     msecs_to_jiffies(delay));
 			/* scan should not continue */
@@ -2820,6 +2816,7 @@ void wlan_hdd_tdls_scan_done_callback(hdd_adapter_t *pAdapter)
 
 	/* if tdls was enabled before scan, re-enable tdls mode */
 	if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last ||
+	    eTDLS_SUPPORT_EXTERNAL_CONTROL == pHddCtx->tdls_mode_last ||
 	    eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode_last) {
 		hddLog(LOG1,
 			  ("%s: revert tdls mode %d"), __func__,
@@ -2845,7 +2842,7 @@ void wlan_hdd_tdls_timer_restart(hdd_adapter_t *pAdapter,
 	hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
 
 	/* Check whether driver load unload is in progress */
-	if (cds_is_load_unload_in_progress()) {
+	if (cds_is_load_or_unload_in_progress()) {
 		hddLog(LOGE, FL("Driver load/unload is in progress."));
 		return;
 	}
@@ -3067,7 +3064,7 @@ __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -3246,7 +3243,7 @@ __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -3365,7 +3362,7 @@ static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
 	CDF_STATUS status;
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hdd_err("Command not allowed in FTM mode");
 		return -EPERM;
 	}
@@ -3672,6 +3669,7 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
 
 	hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	hdd_context_t *pHddCtx = wiphy_priv(wiphy);
+	hdd_station_ctx_t *hdd_sta_ctx;
 	u8 peerMac[CDF_MAC_ADDR_SIZE];
 	CDF_STATUS status;
 	int max_sta_failed = 0;
@@ -3685,7 +3683,7 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
 #endif
 #endif
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -3708,6 +3706,21 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
 		return -ENOTSUPP;
 	}
 
+	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+
+	/*
+	 * STA should be connected and authenticated before sending
+	 * any TDLS frames
+	 */
+	if ((eConnectionState_Associated !=
+	     hdd_sta_ctx->conn_info.connState) ||
+	     (false == hdd_sta_ctx->conn_info.uIsAuthenticated)) {
+		hdd_err("STA is not connected or not authenticated. connState %u, uIsAuthenticated %u",
+			hdd_sta_ctx->conn_info.connState,
+			hdd_sta_ctx->conn_info.uIsAuthenticated);
+		return -EAGAIN;
+	}
+
 	/* If any concurrency is detected */
 	if (((1 << CDF_STA_MODE) != pHddCtx->concurrency_mode) ||
 	    (pHddCtx->no_of_active_sessions[CDF_STA_MODE] > 1)) {
@@ -3853,6 +3866,18 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
 		return -EINVAL;
 	}
 
+	if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
+	    (SIR_MAC_TDLS_DIS_RSP == action_code)) {
+		/* for DIS_REQ/DIS_RSP, supplicant does not consider the return
+		 * status. So no need to wait for tdls_mgmt_comp to
+		 * send ack status.
+		 */
+		hdd_info("tx done for frm %u", action_code);
+		return 0;
+	}
+	hdd_info("Wait for tdls_mgmt_comp. Timeout %u ms",
+		WAIT_TIME_TDLS_MGMT);
+
 	rc = wait_for_completion_timeout(&pAdapter->tdls_mgmt_comp,
 					 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
 
@@ -3861,22 +3886,23 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
 			  "%s: Mgmt Tx Completion timed out TxCompletion %u",
 			  __func__, pAdapter->mgmtTxCompletionStatus);
 
-		if (pHddCtx->isLogpInProgress) {
-			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
-				  "%s: LOGP in Progress. Ignore!!!", __func__);
+		if (cds_is_driver_recovering()) {
+			hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
+				cds_get_driver_state());
 			return -EAGAIN;
 		}
 
-		if (pHddCtx->isUnloadInProgress) {
-			CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
-				  "%s: Unloading/Loading in Progress. Ignore!!!",
-				  __func__);
+		if (cds_is_driver_unloading()) {
+			hdd_err("Unload in progress. State: 0x%x Ignore!!!",
+				cds_get_driver_state());
 			return -EAGAIN;
 		}
 
 		pAdapter->mgmtTxCompletionStatus = false;
 		return -EINVAL;
 	}
+	hdd_info("Mgmt Tx Completion status %ld TxCompletion %u",
+		rc, pAdapter->mgmtTxCompletionStatus);
 
 	if (max_sta_failed) {
 		return max_sta_failed;
@@ -4024,6 +4050,23 @@ int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
 			  "%s TDLS Add Force Peer Failed", __func__);
 		return -EINVAL;
 	}
+	/* Update the peer mac to firmware, so firmware
+	 * could update the connection table
+	 */
+	if (0 != wlan_hdd_tdls_update_peer_mac(pAdapter, peer,
+	    eSME_TDLS_PEER_ADD_MAC_ADDR)) {
+		hddLog(LOGE, FL("TDLS Peer mac update Failed " MAC_ADDRESS_STR),
+				MAC_ADDR_ARRAY(peer));
+		return -EINVAL;
+	}
+
+	/* validate if off channel is DFS channel */
+	if (CDS_IS_DFS_CH(chan)) {
+		hdd_err("Resetting TDLS off-channel from %d to %d",
+		       chan, CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT);
+		chan = CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT;
+	}
+
 	if (0 != wlan_hdd_tdls_set_extctrl_param(pAdapter, peer,
 						 chan, max_latency,
 						 op_class, min_bandwidth)) {
@@ -4078,6 +4121,15 @@ int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
 			  "%s Failed", __func__);
 		return -EINVAL;
 	}
+	/* Update the peer mac to firmware, so firmware
+	 * could update the connection table
+	 */
+	if (0 != wlan_hdd_tdls_update_peer_mac(pAdapter, peer,
+	    eSME_TDLS_PEER_REMOVE_MAC_ADDR)) {
+		hddLog(LOGE, FL("TDLS Peer mac update Failed " MAC_ADDRESS_STR),
+				MAC_ADDR_ARRAY(peer));
+		return -EINVAL;
+	}
 	if (0 != wlan_hdd_set_callback(pTdlsPeer, NULL)) {
 		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
 			  "%s TDLS set callback Failed", __func__);
@@ -4110,7 +4162,7 @@ static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy,
 
 	ENTER();
 
-	if (CDF_FTM_MODE == hdd_get_conparam()) {
+	if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
 		hddLog(LOGE, FL("Command not allowed in FTM mode"));
 		return -EINVAL;
 	}
@@ -4265,6 +4317,16 @@ static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy,
 						pTdlsPeer->
 						op_class_for_pref_off_chan;
 
+				if (CDS_IS_DFS_CH(smeTdlsPeerStateParams.
+					peerCap.prefOffChanNum)) {
+					hdd_err("Resetting TDLS off-channel from %d to %d",
+					       smeTdlsPeerStateParams.peerCap.
+						prefOffChanNum,
+					       CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT);
+					smeTdlsPeerStateParams.peerCap.prefOffChanNum =
+						CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT;
+				}
+
 				CDF_TRACE(CDF_MODULE_ID_HDD,
 					  CDF_TRACE_LEVEL_INFO,
 					  "%s: Peer " MAC_ADDRESS_STR
@@ -4593,8 +4655,9 @@ hddTdlsPeer_t *wlan_hdd_tdls_find_first_connected_peer(hdd_adapter_t *adapter)
 int hdd_set_tdls_offchannel(hdd_context_t *hdd_ctx, int offchannel)
 {
 	if ((true == hdd_ctx->config->fEnableTDLSOffChannel) &&
-		(eTDLS_SUPPORT_ENABLED == hdd_ctx->tdls_mode ||
-		eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == hdd_ctx->tdls_mode)) {
+	    (eTDLS_SUPPORT_ENABLED == hdd_ctx->tdls_mode ||
+	     eTDLS_SUPPORT_EXTERNAL_CONTROL == hdd_ctx->tdls_mode ||
+	     eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == hdd_ctx->tdls_mode)) {
 		if (offchannel < CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN ||
 			offchannel > CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX) {
 			hddLog(LOGE, FL("Invalid tdls off channel %u"),
@@ -4625,8 +4688,9 @@ int hdd_set_tdls_offchannel(hdd_context_t *hdd_ctx, int offchannel)
 int hdd_set_tdls_secoffchanneloffset(hdd_context_t *hdd_ctx, int offchanoffset)
 {
 	if ((true == hdd_ctx->config->fEnableTDLSOffChannel) &&
-		(eTDLS_SUPPORT_ENABLED == hdd_ctx->tdls_mode ||
-		eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == hdd_ctx->tdls_mode)) {
+	    (eTDLS_SUPPORT_ENABLED == hdd_ctx->tdls_mode ||
+	     eTDLS_SUPPORT_EXTERNAL_CONTROL == hdd_ctx->tdls_mode ||
+	     eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == hdd_ctx->tdls_mode)) {
 		hdd_ctx->tdls_channel_offset = 0;
 
 		switch (offchanoffset) {
@@ -4696,13 +4760,14 @@ int hdd_set_tdls_offchannelmode(hdd_adapter_t *adapter, int offchanmode)
 	}
 	if ((true == hdd_ctx->config->fEnableTDLSOffChannel) &&
 		(eTDLS_SUPPORT_ENABLED == hdd_ctx->tdls_mode ||
-		eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == hdd_ctx->tdls_mode)) {
-		conn_peer = wlan_hdd_tdls_find_first_connected_peer(adapter);
-		if (NULL == conn_peer) {
+		 eTDLS_SUPPORT_EXTERNAL_CONTROL == hdd_ctx->tdls_mode ||
+		 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == hdd_ctx->tdls_mode)) {
+		 conn_peer = wlan_hdd_tdls_find_first_connected_peer(adapter);
+		 if (NULL == conn_peer) {
 			hddLog(LOGP,
 				FL("No TDLS Connected Peer"));
-			return -EPERM;
-		}
+		return -EPERM;
+	}
 	} else {
 		hddLog(LOGP,
 			FL("TDLS Connection not supported"));

+ 8 - 4
core/hdd/src/wlan_hdd_trace.c

@@ -50,10 +50,14 @@
 static void
 hdd_trace_dump(void *mac, tp_cdf_trace_record record, uint16_t index)
 {
-	hddLog(LOG1, "%04d %012llu S%d %-14s %-30s(0x%x)",
-	       index, record->time, record->session,
-	       "HDD Event:", hdd_trace_event_string(record->code),
-	       record->data);
+	if (TRACE_CODE_HDD_RX_SME_MSG == record->code)
+		hddLog(LOGE, "%04d    %012llu  S%d    %-14s  %-30s(0x%x) ",
+			index, record->time, record->session, "RX SME MSG:",
+			get_e_roam_cmd_status_str(record->data), record->data);
+	else
+		hddLog(LOGE, "%04d    %012llu  S%d    %-14s  %-30s(0x%x) ",
+			index, record->time, record->session, "HDD Event:",
+			hdd_trace_event_string(record->code), record->data);
 }
 
 /**

+ 18 - 6
core/hdd/src/wlan_hdd_tx_rx.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -305,16 +305,16 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 #endif /* QCA_PKT_PROTO_TRACE */
 
 #ifdef QCA_WIFI_FTM
-	if (hdd_get_conparam() == CDF_FTM_MODE) {
+	if (hdd_get_conparam() == CDF_GLOBAL_FTM_MODE) {
 		kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
 #endif
 
 	++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;
-	if (cds_is_logp_in_progress()) {
+	if (cds_is_driver_recovering()) {
 		CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_WARN,
-			"LOPG in progress, dropping the packet");
+			"Recovery in progress, dropping the packet");
 		++pAdapter->stats.tx_dropped;
 		++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
 		kfree_skb(skb);
@@ -333,7 +333,7 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		if ((STAId == HDD_WLAN_INVALID_STA_ID) &&
 		    (cdf_is_macaddr_broadcast(pDestMacAddress) ||
 		     cdf_is_macaddr_group(pDestMacAddress))) {
-			STAId = IBSS_BROADCAST_STAID;
+			STAId = pHddStaCtx->broadcast_ibss_staid;
 			CDF_TRACE(CDF_MODULE_ID_HDD_DATA,
 				  CDF_TRACE_LEVEL_INFO_LOW, "%s: BC/MC packet",
 				  __func__);
@@ -347,6 +347,17 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			return NETDEV_TX_OK;
 		}
 	} else {
+		if (WLAN_HDD_OCB != pAdapter->device_mode &&
+			eConnectionState_Associated !=
+				pHddStaCtx->conn_info.connState) {
+			CDF_TRACE(CDF_MODULE_ID_HDD_DATA, CDF_TRACE_LEVEL_INFO,
+				FL("Tx frame in not associated state in %d context"),
+				pAdapter->device_mode);
+			++pAdapter->stats.tx_dropped;
+			++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
+			kfree_skb(skb);
+			return NETDEV_TX_OK;
+		}
 		STAId = pHddStaCtx->conn_info.staId[0];
 	}
 
@@ -733,7 +744,8 @@ CDF_STATUS hdd_rx_packet_cbk(void *cds_context, cdf_nbuf_t rxBuf, uint8_t staId)
 
 	if (HDD_LRO_NO_RX ==
 		 hdd_lro_rx(pHddCtx, pAdapter, skb)) {
-		if (hdd_napi_enabled(HDD_NAPI_ANY))
+		if (hdd_napi_enabled(HDD_NAPI_ANY) &&
+		    !pHddCtx->config->enableRxThread)
 			rxstat = netif_receive_skb(skb);
 		else
 			rxstat = netif_rx_ni(skb);

+ 24 - 58
core/hdd/src/wlan_hdd_wext.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -160,7 +160,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
 #define WE_TXRX_FWSTATS_RESET           41
 #define WE_SET_MAX_TX_POWER_2_4   42
 #define WE_SET_MAX_TX_POWER_5_0   43
-#define WE_SET_POWER_GATING       44
+/* 44 is unused */
 /* Private ioctl for packet powe save */
 #define  WE_PPS_PAID_MATCH              45
 #define  WE_PPS_GID_MATCH               46
@@ -247,7 +247,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
 #define WE_GET_AMSDU         28
 #define WE_GET_TXPOW_2G      29
 #define WE_GET_TXPOW_5G      30
-#define WE_GET_POWER_GATING  31
+/* 31 is unused */
 #define WE_GET_PPS_PAID_MATCH           32
 #define WE_GET_PPS_GID_MATCH            33
 #define WE_GET_PPS_EARLY_TIM_CLEAR      34
@@ -1109,9 +1109,9 @@ CDF_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, int8_t *rssi_value)
 		       "%s: Invalid context, pAdapter", __func__);
 		return CDF_STATUS_E_FAULT;
 	}
-	if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
-			  "%s:LOGP in Progress. Ignore!!!", __func__);
+	if (cds_is_driver_recovering()) {
+		hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
+			cds_get_driver_state());
 		/* return a cached value */
 		*rssi_value = pAdapter->rssi;
 		return CDF_STATUS_SUCCESS;
@@ -2248,9 +2248,9 @@ static int __iw_get_bitrate(struct net_device *dev,
 	if (0 != ret)
 		return ret;
 
-	if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_FATAL,
-			  "%s:LOGP in Progress. Ignore!!!", __func__);
+	if (cds_is_driver_recovering()) {
+		hdd_alert("Recovery in Progress. State: 0x%x Ignore!!!",
+			  cds_get_driver_state());
 		return status;
 	}
 
@@ -3352,9 +3352,9 @@ CDF_STATUS wlan_hdd_get_class_astats(hdd_adapter_t *pAdapter)
 		hddLog(CDF_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
 		return CDF_STATUS_E_FAULT;
 	}
-	if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
-		CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
-			  "%s:LOGP in Progress. Ignore!!!", __func__);
+	if (cds_is_driver_recovering()) {
+		hdd_err("Recovery in Progress. State: 0x%x Ignore!!!",
+			 cds_get_driver_state());
 		return CDF_STATUS_SUCCESS;
 	}
 
@@ -5698,16 +5698,6 @@ static int __iw_setint_getnone(struct net_device *dev,
 		break;
 	}
 
-	case WE_SET_POWER_GATING:
-	{
-		hddLog(LOG1, "WMI_PDEV_PARAM_POWER_GATING_SLEEP val %d",
-		       set_value);
-		ret = wma_cli_set_command(pAdapter->sessionId,
-					  WMI_PDEV_PARAM_POWER_GATING_SLEEP,
-					  (set_value) ? true : false, PDEV_CMD);
-		break;
-	}
-
 	/* Firmware debug log */
 	case WE_DBGLOG_LOG_LEVEL:
 	{
@@ -6681,15 +6671,6 @@ static int __iw_setnone_getint(struct net_device *dev,
 		break;
 	}
 
-	case WE_GET_POWER_GATING:
-	{
-		hddLog(LOG1, "GET WMI_PDEV_PARAM_POWER_GATING_SLEEP");
-		*value = wma_cli_get_command(pAdapter->sessionId,
-					     WMI_PDEV_PARAM_POWER_GATING_SLEEP,
-					     PDEV_CMD);
-		break;
-	}
-
 	case WE_GET_PPS_PAID_MATCH:
 	{
 		hddLog(LOG1, "GET WMI_VDEV_PPS_PAID_MATCH");
@@ -6894,9 +6875,7 @@ static int __iw_set_three_ints_getnone(struct net_device *dev,
 			return -EPERM;
 		}
 		hdd_debug("%d %d %d", value[1], value[2], value[3]);
-		cds_set_dual_mac_scan_config(hdd_ctx,
-				value[1], value[2],
-				value[3]);
+		cds_set_dual_mac_scan_config(value[1], value[2], value[3]);
 		break;
 	default:
 		hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd);
@@ -7712,7 +7691,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
 	{
 		hddLog(LOGE,
 			FL("<iwpriv wlan0 pm_clist> is called\n"));
-		cds_incr_connection_count_utfw(hdd_ctx, apps_args[0],
+		cds_incr_connection_count_utfw(apps_args[0],
 			apps_args[1], apps_args[2], apps_args[3],
 			apps_args[4], apps_args[5], apps_args[6],
 			apps_args[7]);
@@ -7723,7 +7702,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
 	{
 		hddLog(LOGE,
 			FL("<iwpriv wlan0 pm_dlist> is called\n"));
-		cds_decr_connection_count_utfw(hdd_ctx, apps_args[0],
+		cds_decr_connection_count_utfw(apps_args[0],
 			apps_args[1]);
 	}
 	break;
@@ -7732,7 +7711,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
 	{
 		hddLog(LOGE,
 			FL("<iwpriv wlan0 pm_ulist> is called\n"));
-		cds_update_connection_info_utfw(hdd_ctx, apps_args[0],
+		cds_update_connection_info_utfw(apps_args[0],
 			apps_args[1], apps_args[2], apps_args[3],
 			apps_args[4], apps_args[5], apps_args[6],
 			apps_args[7]);
@@ -7764,7 +7743,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
 		hddLog(LOGE,
 			FL("<iwpriv wlan0 pm_pcl> is called\n"));
 
-		cds_get_pcl(hdd_ctx, apps_args[0],
+		cds_get_pcl(apps_args[0],
 				pcl, &pcl_len);
 		pr_info("PCL list for role[%d] is {", apps_args[0]);
 		for (i = 0 ; i < pcl_len; i++)
@@ -7780,7 +7759,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
 
 		hddLog(LOGE,
 			FL("<iwpriv wlan0 pm_cinfo> is called\n"));
-		conn_info = cds_get_conn_info(hdd_ctx, &len);
+		conn_info = cds_get_conn_info(&len);
 		pr_info("+-----------------------------+\n");
 		for (i = 0; i < len; i++) {
 			pr_info("|table_index[%d]\t\t|\n", i);
@@ -7806,7 +7785,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
 		if (apps_args[0] == 0) {
 			hddLog(LOGE,
 				FL("set hw mode for single mac\n"));
-			cds_soc_set_hw_mode(hdd_ctx,
+			cds_soc_set_hw_mode(
 					pAdapter->sessionId,
 					HW_MODE_SS_2x2,
 					HW_MODE_80_MHZ,
@@ -7817,7 +7796,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
 		} else if (apps_args[0] == 1) {
 			hddLog(LOGE,
 				FL("set hw mode for dual mac\n"));
-			cds_soc_set_hw_mode(hdd_ctx,
+			cds_soc_set_hw_mode(
 					pAdapter->sessionId,
 					HW_MODE_SS_1x1,
 					HW_MODE_80_MHZ,
@@ -7845,7 +7824,7 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
 		bool allow;
 		hddLog(LOGE,
 			FL("<iwpriv wlan0 pm_query_allow> is called\n"));
-		allow = cds_allow_concurrency(hdd_ctx,
+		allow = cds_allow_concurrency(
 				apps_args[0], apps_args[1], apps_args[2]);
 		pr_info("allow %d {0 = don't allow, 1 = allow}", allow);
 	}
@@ -8604,10 +8583,8 @@ static int __iw_set_keepalive_params(struct net_device *dev,
 		       request->destIpv4Addr[0], request->destIpv4Addr[1],
 		       request->destIpv4Addr[2], request->destIpv4Addr[3]);
 
-		hdd_info("Dest MAC address: %d:%d:%d:%d:%d:%d",
-		       request->destMacAddr[0], request->destMacAddr[1],
-		       request->destMacAddr[2], request->destMacAddr[3],
-		       request->destMacAddr[4], request->destMacAddr[5]);
+		hdd_info("Dest MAC address: "MAC_ADDRESS_STR,
+		       MAC_ADDR_ARRAY(request->dest_macaddr.bytes));
 		break;
 	}
 
@@ -9534,8 +9511,7 @@ static int __iw_set_two_ints_getnone(struct net_device *dev,
 			return -EPERM;
 		}
 		hdd_debug("%d %d", value[1], value[2]);
-		cds_set_dual_mac_fw_mode_config(hdd_ctx,
-				value[1], value[2]);
+		cds_set_dual_mac_fw_mode_config(value[1], value[2]);
 		break;
 	case WE_DUMP_DP_TRACE_LEVEL:
 		hdd_info("WE_DUMP_DP_TRACE_LEVEL: %d %d",
@@ -9917,11 +9893,6 @@ static const struct iw_priv_args we_private_args[] = {
 	 0,
 	 "txpow5g"},
 
-	{WE_SET_POWER_GATING,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 0,
-	 "pwrgating"},
-
 	/* Sub-cmds DBGLOG specific commands */
 	{WE_DBGLOG_LOG_LEVEL,
 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
@@ -10275,11 +10246,6 @@ static const struct iw_priv_args we_private_args[] = {
 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 	 "get_txpow5g"},
 
-	{WE_GET_POWER_GATING,
-	 0,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 "get_pwrgating"},
-
 	{WE_GET_PPS_PAID_MATCH,
 	 0,
 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,

+ 0 - 4
core/hdd/src/wlan_hdd_wmm.c

@@ -81,10 +81,6 @@
 
 #define WLAN_HDD_MAX_DSCP 0x3f
 
-/* DHCP Port number */
-#define DHCP_SOURCE_PORT 0x4400
-#define DHCP_DESTINATION_PORT 0x4300
-
 #define HDD_WMM_UP_TO_AC_MAP_SIZE 8
 
 const uint8_t hdd_wmm_up_to_ac_map[] = {

+ 3 - 3
core/hdd/src/wlan_hdd_wowl.c

@@ -522,8 +522,8 @@ bool hdd_enter_wowl(hdd_adapter_t *pAdapter, bool enable_mp, bool enable_pbm)
 	wowParams.ucMagicPktEnable = enable_mp;
 	wowParams.sessionId = pAdapter->sessionId;
 	if (enable_mp) {
-		cdf_copy_macaddr((struct cdf_mac_addr *) &(wowParams.magicPtrn),
-				 &(pAdapter->macAddressCurrent));
+		cdf_copy_macaddr(&wowParams.magic_ptrn,
+				 &pAdapter->macAddressCurrent);
 	}
 #ifdef WLAN_WAKEUP_EVENTS
 	wowParams.ucWoWEAPIDRequestEnable = true;
@@ -533,7 +533,7 @@ bool hdd_enter_wowl(hdd_adapter_t *pAdapter, bool enable_mp, bool enable_pbm)
 	wowParams.ucWoWBSSConnLoss = true;
 #endif /* WLAN_WAKEUP_EVENTS */
 
-	/* Request to put Libra into WoWL */
+	/* Request to put FW into WoWL */
 	cdf_ret_status = sme_enter_wowl(hHal, hdd_wowl_callback, pAdapter,
 #ifdef WLAN_WAKEUP_EVENTS
 					hdd_wowl_wake_indication_callback,

+ 62 - 12
core/hif/inc/hif.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -394,14 +394,6 @@ typedef struct osdrv_callbacks {
  */
 int hif_init(OSDRV_CALLBACKS *callbacks);
 
-/*
- * This API claims the HIF device and provides a context for handling removal.
- * The device removal callback is only called when the OSDRV layer claims
- * a device.  The claimed context must be non-NULL */
-void hif_claim_device(struct ol_softc *scn, void *claimedContext);
-/* release the claimed device */
-void hif_release_device(struct ol_softc *scn);
-
 /* This API detaches the HTC layer from the HIF device */
 void hif_detach_htc(struct ol_softc *scn);
 
@@ -635,18 +627,76 @@ void hif_disable_isr(void *scn);
 void hif_reset_soc(void *scn);
 void hif_disable_aspm(void);
 void hif_save_htc_htt_config_endpoint(int htc_endpoint);
-CDF_STATUS hif_open(void);
+CDF_STATUS hif_open(enum ath_hal_bus_type bus_type);
 void hif_close(void *hif_ctx);
 CDF_STATUS hif_enable(void *hif_ctx, struct device *dev, void *bdev,
 	const hif_bus_id *bid, enum ath_hal_bus_type bus_type,
 	enum hif_enable_type type);
 void hif_disable(void *hif_ctx, enum hif_disable_type type);
 void hif_enable_power_gating(void *hif_ctx);
-int hif_bus_resume(void);
-int hif_bus_suspend(void);
+
+#ifdef FEATURE_RUNTIME_PM
+struct hif_pm_runtime_lock;
+int hif_pm_runtime_get(void *hif_ctx);
+void hif_pm_runtime_get_noresume(void *hif_ctx);
+int hif_pm_runtime_put(void *hif_ctx);
+struct hif_pm_runtime_lock *hif_runtime_lock_init(const char *name);
+void hif_runtime_lock_deinit(struct hif_pm_runtime_lock *lock);
+int hif_pm_runtime_prevent_suspend(void *ol_sc,
+		struct hif_pm_runtime_lock *lock);
+int hif_pm_runtime_allow_suspend(void *ol_sc,
+		struct hif_pm_runtime_lock *lock);
+int hif_pm_runtime_prevent_suspend_timeout(void *ol_sc,
+		struct hif_pm_runtime_lock *lock, unsigned int delay);
+#else
+struct hif_pm_runtime_lock {
+	const char *name;
+};
+
+static inline void hif_pm_runtime_get_noresume(void *hif_ctx)
+{}
+
+static inline int hif_pm_runtime_get(void *hif_ctx)
+{ return 0; }
+static inline int hif_pm_runtime_put(void *hif_ctx)
+{ return 0; }
+static inline struct hif_pm_runtime_lock *hif_runtime_lock_init(
+		const char *name)
+{ return NULL; }
+static inline void hif_runtime_lock_deinit(struct hif_pm_runtime_lock *lock)
+{}
+
+static inline int hif_pm_runtime_prevent_suspend(void *ol_sc,
+		struct hif_pm_runtime_lock *lock)
+{ return 0; }
+static inline int hif_pm_runtime_allow_suspend(void *ol_sc,
+		struct hif_pm_runtime_lock *lock)
+{ return 0; }
+static inline int hif_pm_runtime_prevent_suspend_timeout(void *ol_sc,
+		struct hif_pm_runtime_lock *lock, unsigned int delay)
+{ return 0; }
+#endif
+
+void hif_enable_power_management(void *hif_ctx);
+void hif_disable_power_management(void *hif_ctx);
+
 void hif_vote_link_down(void);
 void hif_vote_link_up(void);
 bool hif_can_suspend_link(void);
+
+int hif_bus_resume(void);
+int hif_bus_suspend(void);
+
+#ifdef FEATURE_RUNTIME_PM
+int hif_pre_runtime_suspend(void);
+void hif_pre_runtime_resume(void);
+int hif_runtime_suspend(void);
+int hif_runtime_resume(void);
+void hif_process_runtime_suspend_success(void);
+void hif_process_runtime_suspend_failure(void);
+void hif_process_runtime_resume_success(void);
+#endif
+
 int dump_ce_register(struct ol_softc *scn);
 int ol_copy_ramdump(struct ol_softc *scn);
 void hif_pktlogmod_exit(void *hif_ctx);

+ 37 - 0
core/hif/inc/platform_icnss.h

@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifndef _PLATFORM_ICNSS_H_
+#define _PLATFORM_ICNSS_H_
+
+#ifdef HIF_PCI
+#include "icnss_stub.h"
+#else
+#include <soc/qcom/icnss.h>
+#endif
+
+#endif

+ 0 - 4
core/hif/src/adrastea_reg_def.h

@@ -1812,11 +1812,7 @@
 
 #define ADRASTEA_A_WIFI_APB_1_A_WFSS_CE_TARGET_HOST_DELTA	0x08
 #define ADRASTEA_A_SOC_PCIE_PCIE_SCRATCH_2			0x0013005C
-#ifdef QCA_WIFI_3_0_IHELIUM
-#define ADRASTEA_A_SOC_CORE_PCIE_INTR_ENABLE_GRP0_Q6_MASK        0xff
-#else
 #define ADRASTEA_A_SOC_CORE_PCIE_INTR_ENABLE_GRP0_Q6_MASK        0x0
-#endif /* QCA_WIFI_3_0_IHELIUM */
 /* end: Q6 iHelium emulation registers */
 
 struct targetdef_s adrastea_targetdef = {

+ 0 - 5
core/hif/src/ath_procfs.c

@@ -56,12 +56,7 @@ static void *get_hif_hdl_from_file(struct file *file)
 {
 	struct ol_softc *scn;
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
 	scn = (struct ol_softc *)PDE_DATA(file_inode(file));
-#else
-	scn = (struct ol_softc *)(
-		PDE(file->f_path.dentry->d_inode)->data);
-#endif
 	return (void *)scn;
 }
 

+ 44 - 0
core/hif/src/ce/ce_internal.h

@@ -275,6 +275,50 @@ struct CE_dest_desc {
 
 #define CE_SENDLIST_ITEMS_MAX 12
 
+/**
+ * union ce_desc - unified data type for ce descriptors
+ *
+ * Both src and destination descriptors follow the same format.
+ * They use different data structures for different access symantics.
+ * Here we provice a unifying data type.
+ */
+union ce_desc {
+	struct CE_src_desc src_desc;
+	struct CE_dest_desc dest_desc;
+};
+
+/**
+ * enum hif_ce_event_type - HIF copy engine event type
+ * @HIF_RX_DESC_POST: event recorded before updating write index of RX ring.
+ * @HIF_RX_DESC_COMPLETION: event recorded before updating sw index of RX ring.
+ * @HIF_TX_GATHER_DESC_POST: post gather desc. (no write index update)
+ * @HIF_TX_DESC_POST: event recorded before updating write index of TX ring.
+ * @HIF_TX_DESC_COMPLETION: event recorded before updating sw index of TX ring.
+ * @HIF_IRQ_EVENT: event recorded in the irq before scheduling the bh
+ * @HIF_CE_TASKLET_ENTRY: records the start of the ce_tasklet
+ * @HIF_CE_TASKLET_RESCHEDULE: records the rescheduling of the wlan_tasklet
+ * @HIF_CE_TASKLET_EXIT: records the exit of the wlan tasklet without reschedule
+ * @HIF_CE_REAP_ENTRY: records when we process completion outside of a bh
+ * @HIF_CE_REAP_EXIT:  records when we process completion outside of a bh
+ */
+enum hif_ce_event_type {
+	HIF_RX_DESC_POST,
+	HIF_RX_DESC_COMPLETION,
+	HIF_TX_GATHER_DESC_POST,
+	HIF_TX_DESC_POST,
+	HIF_TX_DESC_COMPLETION,
+	HIF_IRQ_EVENT,
+	HIF_CE_TASKLET_ENTRY,
+	HIF_CE_TASKLET_RESCHEDULE,
+	HIF_CE_TASKLET_EXIT,
+	HIF_CE_REAP_ENTRY,
+	HIF_CE_REAP_EXIT,
+};
+
+void ce_init_ce_desc_event_log(int ce_id, int size);
+void hif_record_ce_desc_event(int ce_id, enum hif_ce_event_type type,
+		union ce_desc *descriptor, void *memory, int index);
+
 enum ce_sendlist_type_e {
 	CE_SIMPLE_BUFFER_TYPE,
 	/* TBDXXX: CE_RX_DESC_LIST, */

+ 23 - 44
core/hif/src/ce/ce_main.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -166,6 +166,9 @@ struct CE_handle *ce_init(struct ol_softc *scn,
 	else
 		CE_state->src_sz_max = attr->src_sz_max;
 
+	ce_init_ce_desc_event_log(CE_id,
+			attr->src_nentries + attr->dest_nentries);
+
 	/* source ring setup */
 	nentries = attr->src_nentries;
 	if (nentries) {
@@ -691,9 +694,9 @@ hif_pci_ce_send_done(struct CE_handle *copyeng, void *ce_context,
 		if (transfer_context != CE_SENDLIST_ITEM_CTXT) {
 			if (hif_state->scn->target_status
 					== OL_TRGET_STATUS_RESET)
-				return;
-
-			msg_callbacks->txCompletionHandler(
+				cdf_nbuf_free(transfer_context);
+			else
+				msg_callbacks->txCompletionHandler(
 					msg_callbacks->Context,
 					transfer_context, transfer_id,
 					toeplitz_hash_result);
@@ -752,6 +755,7 @@ hif_pci_ce_recv_data(struct CE_handle *copyeng, void *ce_context,
 		&hif_state->msg_callbacks_current;
 
 	do {
+		hif_pm_runtime_mark_last_busy(scn->hif_sc->dev);
 		cdf_nbuf_unmap_single(scn->cdf_dev,
 				      (cdf_nbuf_t) transfer_context,
 				      CDF_DMA_FROM_DEVICE);
@@ -759,9 +763,9 @@ hif_pci_ce_recv_data(struct CE_handle *copyeng, void *ce_context,
 		atomic_inc(&pipe_info->recv_bufs_needed);
 		hif_post_recv_buffers_for_pipe(pipe_info);
 		if (hif_state->scn->target_status == OL_TRGET_STATUS_RESET)
-			return;
-
-		hif_ce_do_recv(msg_callbacks, transfer_context,
+			cdf_nbuf_free(transfer_context);
+		else
+			hif_ce_do_recv(msg_callbacks, transfer_context,
 				nbytes, pipe_info);
 
 		/* Set up force_break flag if num of receices reaches
@@ -775,6 +779,7 @@ hif_pci_ce_recv_data(struct CE_handle *copyeng, void *ce_context,
 	} while (ce_completed_recv_next(copyeng, &ce_context, &transfer_context,
 					&CE_data, &nbytes, &transfer_id,
 					&flags) == CDF_STATUS_SUCCESS);
+
 }
 
 /* TBDXXX: Set CE High Watermark; invoke txResourceAvailHandler in response */
@@ -841,7 +846,11 @@ int hif_completion_thread_startup(struct HIF_CE_state *hif_state)
 					    hif_pci_ce_recv_data, pipe_info,
 					    attr.flags & CE_ATTR_DISABLE_INTR);
 		}
+
+		if (attr.src_nentries)
+			cdf_spinlock_init(&pipe_info->completion_freeq_lock);
 	}
+
 	A_TARGET_ACCESS_UNLIKELY(scn);
 	return 0;
 }
@@ -863,20 +872,6 @@ static void hif_msg_callbacks_install(struct ol_softc *scn)
 		 sizeof(hif_state->msg_callbacks_pending));
 }
 
-void hif_claim_device(struct ol_softc *scn, void *claimedContext)
-{
-	struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
-
-	hif_state->claimedContext = claimedContext;
-}
-
-void hif_release_device(struct ol_softc *scn)
-{
-	struct HIF_CE_state *hif_state = (struct HIF_CE_state *)scn->hif_hdl;
-
-	hif_state->claimedContext = NULL;
-}
-
 void
 hif_get_default_pipe(struct ol_softc *scn, uint8_t *ULPipe, uint8_t *DLPipe)
 {
@@ -1161,7 +1156,7 @@ void hif_send_buffer_cleanup_on_pipe(struct HIF_CE_pipe_info *pipe_info)
 			 * htt_h2t_rx_ring_cfg_msg_ll() have already been
 			 * freed in htt_htc_misc_pkt_pool_free() in
 			 * wlantl_close(), so do not free them here again
-			 * by checking whether it's the EndPoint
+			 * by checking whether it's the endpoint
 			 * which they are queued in.
 			 */
 			if (id == hif_state->scn->htc_endpoint)
@@ -1487,7 +1482,7 @@ static void hif_sleep_entry(void *arg)
 	if (scn->recovery)
 		return;
 
-	if (cds_is_unload_in_progress())
+	if (cds_is_driver_unloading())
 		return;
 
 	cdf_spin_lock_irqsave(&hif_state->keep_awake_lock);
@@ -1543,7 +1538,7 @@ int hif_set_hia(struct ol_softc *scn)
 
 	HIF_TRACE("%s: E", __func__);
 
-	if (IHELIUM_BU || ADRASTEA_BU)
+	if (ADRASTEA_BU)
 		return CDF_STATUS_SUCCESS;
 
 #ifdef QCA_WIFI_3_0
@@ -1799,26 +1794,15 @@ static int hif_wlan_enable(void)
 	cfg.num_shadow_reg_cfg = shadow_cfg_sz / sizeof(struct shadow_reg_cfg);
 	cfg.shadow_reg_cfg = (struct icnss_shadow_reg_cfg *) target_shadow_reg_cfg;
 
-	switch (con_mode) {
-	case CDF_FTM_MODE:
+	if (CDF_GLOBAL_FTM_MODE == con_mode)
 		mode = ICNSS_FTM;
-		break;
-	case CDF_EPPING_MODE:
+	else if (WLAN_IS_EPPING_ENABLED(cds_get_conparam()))
 		mode = ICNSS_EPPING;
-		break;
-	default:
+	else
 		mode = ICNSS_MISSION;
-		break;
-	}
-	return icnss_wlan_enable(&cfg, mode, QWLAN_VERSIONSTR);
-}
 
-#if ((!defined(QCA_WIFI_3_0_IHELIUM) && !defined(QCA_WIFI_3_0_ADRASTEA)) || defined(CONFIG_ICNSS))
-static inline void cnss_pcie_notify_q6(void)
-{
-	return;
+	return icnss_wlan_enable(&cfg, mode, QWLAN_VERSIONSTR);
 }
-#endif
 
 /*
  * Called from PCI layer whenever a new PCI device is probed.
@@ -1858,11 +1842,6 @@ int hif_config_ce(hif_handle_t hif_hdl)
 		HIF_ERROR("%s: hif_wlan_enable error = %d", __func__, ret);
 		return CDF_STATUS_NOT_INITIALIZED;
 	}
-	if (IHELIUM_BU) {
-		cnss_pcie_notify_q6();
-		HIF_TRACE("%s: cnss_pcie_notify_q6 done, notice_send= %d",
-			  __func__, scn->notice_send);
-	}
 
 	scn->notice_send = true;
 

+ 1 - 3
core/hif/src/ce/ce_main.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -123,8 +123,6 @@ struct HIF_CE_state {
 	/* current msg callbacks in use */
 	struct hif_msg_callbacks msg_callbacks_current;
 
-	void *claimedContext;
-
 	/* Target address used to signal a pending firmware event */
 	uint32_t fw_indicator_address;
 

+ 138 - 7
core/hif/src/ce/ce_service.c

@@ -78,6 +78,103 @@ static int war1_allow_sleep;
 /* io32 write workaround */
 static int hif_ce_war1;
 
+#ifdef CONFIG_SLUB_DEBUG_ON
+
+/**
+ * struct hif_ce_event - structure for detailing a ce event
+ * @type: what the event was
+ * @time: when it happened
+ * @descriptor: descriptor enqueued or dequeued
+ * @memory: virtual address that was used
+ * @index: location of the descriptor in the ce ring;
+ */
+struct hif_ce_desc_event {
+	uint16_t index;
+	enum hif_ce_event_type type;
+	uint64_t time;
+	union ce_desc descriptor;
+	void *memory;
+};
+
+/* max history to record per copy engine */
+#define HIF_CE_HISTORY_MAX 512
+cdf_atomic_t hif_ce_desc_history_index[CE_COUNT_MAX];
+struct hif_ce_desc_event hif_ce_desc_history[CE_COUNT_MAX][HIF_CE_HISTORY_MAX];
+
+
+/**
+ * get_next_record_index() - get the next record index
+ * @table_index: atomic index variable to increment
+ * @array_size: array size of the circular buffer
+ *
+ * Increment the atomic index and reserve the value.
+ * Takes care of buffer wrap.
+ * Guaranteed to be thread safe as long as fewer than array_size contexts
+ * try to access the array.  If there are more than array_size contexts
+ * trying to access the array, full locking of the recording process would
+ * be needed to have sane logging.
+ */
+static int get_next_record_index(cdf_atomic_t *table_index, int array_size)
+{
+	int record_index = cdf_atomic_inc_return(table_index);
+	if (record_index == array_size)
+		cdf_atomic_sub(array_size, table_index);
+
+	while (record_index >= array_size)
+		record_index -= array_size;
+	return record_index;
+}
+
+/**
+ * hif_record_ce_desc_event() - record ce descriptor events
+ * @ce_id: which ce is the event occuring on
+ * @type: what happened
+ * @descriptor: pointer to the descriptor posted/completed
+ * @memory: virtual address of buffer related to the descriptor
+ * @index: index that the descriptor was/will be at.
+ */
+void hif_record_ce_desc_event(int ce_id, enum hif_ce_event_type type,
+		union ce_desc *descriptor, void *memory, int index)
+{
+	int record_index = get_next_record_index(
+			&hif_ce_desc_history_index[ce_id], HIF_CE_HISTORY_MAX);
+
+	struct hif_ce_desc_event *event =
+		&hif_ce_desc_history[ce_id][record_index];
+	event->type = type;
+	event->time = cds_get_monotonic_boottime();
+	if (descriptor != NULL)
+		event->descriptor = *descriptor;
+	else
+		memset(&event->descriptor, 0, sizeof(union ce_desc));
+	event->memory = memory;
+	event->index = index;
+}
+
+/**
+ * ce_init_ce_desc_event_log() - initialize the ce event log
+ * @ce_id: copy engine id for which we are initializing the log
+ * @size: size of array to dedicate
+ *
+ * Currently the passed size is ignored in favor of a precompiled value.
+ */
+void ce_init_ce_desc_event_log(int ce_id, int size)
+{
+	cdf_atomic_init(&hif_ce_desc_history_index[ce_id]);
+}
+#else
+void hif_record_ce_desc_event(
+		int ce_id, enum hif_ce_event_type type,
+		union ce_desc *descriptor, void *memory,
+		int index)
+{
+}
+
+inline void ce_init_ce_desc_event_log(int ce_id, int size)
+{
+}
+#endif
+
 /*
  * Support for Copy Engine hardware, which is mainly used for
  * communication between Host and Target over a PCIe interconnect.
@@ -194,6 +291,7 @@ ce_send_nolock(struct CE_handle *copyeng,
 		return status;
 	}
 	{
+		enum hif_ce_event_type event_type = HIF_TX_GATHER_DESC_POST;
 		struct CE_src_desc *src_ring_base =
 			(struct CE_src_desc *)src_ring->base_addr_owner_space;
 		struct CE_src_desc *shadow_base =
@@ -237,10 +335,18 @@ ce_send_nolock(struct CE_handle *copyeng,
 
 		/* WORKAROUND */
 		if (!shadow_src_desc->gather) {
+			event_type = HIF_TX_DESC_POST;
 			war_ce_src_ring_write_idx_set(scn, ctrl_addr,
 						      write_index);
 		}
 
+		/* src_ring->write index hasn't been updated event though
+		 * the register has allready been written to.
+		 */
+		hif_record_ce_desc_event(CE_state->id, event_type,
+			(union ce_desc *) shadow_src_desc, per_transfer_context,
+			src_ring->write_index);
+
 		src_ring->write_index = write_index;
 		status = CDF_STATUS_SUCCESS;
 	}
@@ -442,6 +548,7 @@ int ce_send_fast(struct CE_handle *copyeng, cdf_nbuf_t *msdus,
 		struct CE_src_desc *shadow_src_desc =
 			CE_SRC_RING_TO_DESC(shadow_base, write_index);
 
+		hif_pm_runtime_get_noresume(scn);
 		msdu = msdus[i];
 
 		/*
@@ -513,10 +620,15 @@ int ce_send_fast(struct CE_handle *copyeng, cdf_nbuf_t *msdus,
 	/* Write the final index to h/w one-shot */
 	if (i) {
 		src_ring->write_index = write_index;
-		/* Don't call WAR_XXX from here
-		 * Just call XXX instead, that has the reqd. intel
-		 */
-		war_ce_src_ring_write_idx_set(scn, ctrl_addr, write_index);
+
+		if (hif_pm_runtime_get(scn) == 0) {
+			/* Don't call WAR_XXX from here
+			 * Just call XXX instead, that has the reqd. intel
+			 */
+			war_ce_src_ring_write_idx_set(scn, ctrl_addr,
+					write_index);
+			hif_pm_runtime_put(scn);
+		}
 	}
 
 	cdf_spin_unlock_bh(&ce_state->ce_index_lock);
@@ -574,6 +686,10 @@ ce_recv_buf_enqueue(struct CE_handle *copyeng,
 		dest_ring->per_transfer_context[write_index] =
 			per_recv_context;
 
+		hif_record_ce_desc_event(CE_state->id, HIF_RX_DESC_POST,
+				(union ce_desc *) dest_desc, per_recv_context,
+				write_index);
+
 		/* Update Destination Ring Write Index */
 		write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
 		CE_DEST_RING_WRITE_IDX_SET(scn, ctrl_addr, write_index);
@@ -764,6 +880,11 @@ ce_completed_recv_next_nolock(struct CE_state *CE_state,
 		goto done;
 	}
 
+	hif_record_ce_desc_event(CE_state->id, HIF_RX_DESC_COMPLETION,
+			(union ce_desc *) dest_desc,
+			dest_ring->per_transfer_context[sw_index],
+			sw_index);
+
 	dest_desc->nbytes = 0;
 
 	/* Return data from completed destination descriptor */
@@ -925,6 +1046,11 @@ ce_completed_send_next_nolock(struct CE_state *CE_state,
 		struct CE_src_desc *src_desc =
 			CE_SRC_RING_TO_DESC(src_ring_base, sw_index);
 #endif
+		hif_record_ce_desc_event(CE_state->id, HIF_TX_DESC_COMPLETION,
+				(union ce_desc *) shadow_src_desc,
+				src_ring->per_transfer_context[sw_index],
+				sw_index);
+
 		/* Return data from completed source descriptor */
 		*bufferp = HIF_CE_DESC_ADDR_TO_DMA(shadow_src_desc);
 		*nbytesp = shadow_src_desc->nbytes;
@@ -1061,7 +1187,7 @@ ce_completed_send_next(struct CE_handle *copyeng,
  * within it .
  */
 
-void ce_per_engine_servicereap(struct ol_softc *scn, unsigned int CE_id)
+void ce_per_engine_servicereap(struct ol_softc *scn, unsigned int ce_id)
 {
 	void *CE_context;
 	void *transfer_context;
@@ -1070,9 +1196,11 @@ void ce_per_engine_servicereap(struct ol_softc *scn, unsigned int CE_id)
 	unsigned int id;
 	unsigned int sw_idx, hw_idx;
 	uint32_t toeplitz_hash_result;
-	struct CE_state *CE_state = scn->ce_id_to_state[CE_id];
+	struct CE_state *CE_state = scn->ce_id_to_state[ce_id];
 
 	A_TARGET_ACCESS_BEGIN(scn);
+	hif_record_ce_desc_event(ce_id, HIF_CE_REAP_ENTRY,
+			NULL, NULL, 0);
 
 	/* Since this function is called from both user context and
 	 * tasklet context the spinlock has to lock the bottom halves.
@@ -1100,7 +1228,7 @@ void ce_per_engine_servicereap(struct ol_softc *scn, unsigned int CE_id)
 				  &nbytes, &id, &sw_idx, &hw_idx,
 				  &toeplitz_hash_result) ==
 				  CDF_STATUS_SUCCESS) {
-				if (CE_id != CE_HTT_H2T_MSG) {
+				if (ce_id != CE_HTT_H2T_MSG) {
 					cdf_spin_unlock_bh(
 						&CE_state->ce_index_lock);
 					CE_state->send_cb(
@@ -1127,6 +1255,9 @@ void ce_per_engine_servicereap(struct ol_softc *scn, unsigned int CE_id)
 	}
 
 	cdf_spin_unlock_bh(&CE_state->ce_index_lock);
+
+	hif_record_ce_desc_event(ce_id, HIF_CE_REAP_EXIT,
+			NULL, NULL, 0);
 	A_TARGET_ACCESS_END(scn);
 }
 

+ 9 - 0
core/hif/src/ce/ce_tasklet.c

@@ -203,6 +203,9 @@ static void ce_tasklet(unsigned long data)
 	struct ol_softc *scn = hif_ce_state->scn;
 	struct CE_state *CE_state = scn->ce_id_to_state[tasklet_entry->ce_id];
 
+	hif_record_ce_desc_event(tasklet_entry->ce_id, HIF_CE_TASKLET_ENTRY,
+			NULL, NULL, 0);
+
 	if (cdf_atomic_read(&scn->link_suspended)) {
 		HIF_ERROR("%s: ce %d tasklet fired after link suspend.",
 				__func__, tasklet_entry->ce_id);
@@ -221,6 +224,8 @@ static void ce_tasklet(unsigned long data)
 		 * Enable the interrupt only when there is no pending frames in
 		 * any of the Copy Engine pipes.
 		 */
+		hif_record_ce_desc_event(tasklet_entry->ce_id,
+				HIF_CE_TASKLET_RESCHEDULE, NULL, NULL, 0);
 		ce_schedule_tasklet(tasklet_entry);
 		return;
 	}
@@ -228,6 +233,9 @@ static void ce_tasklet(unsigned long data)
 	if (scn->target_status != OL_TRGET_STATUS_RESET)
 		ce_irq_enable(scn, tasklet_entry->ce_id);
 
+	hif_record_ce_desc_event(tasklet_entry->ce_id, HIF_CE_TASKLET_EXIT,
+			NULL, NULL, 0);
+
 	cdf_atomic_dec(&scn->active_tasklet_cnt);
 }
 /**
@@ -301,6 +309,7 @@ static irqreturn_t ce_irq_handler(int irq, void *context)
 	ce_irq_disable(scn, ce_id);
 	ce_irq_status(scn, ce_id, &host_status);
 	cdf_atomic_inc(&scn->active_tasklet_cnt);
+	hif_record_ce_desc_event(ce_id, HIF_IRQ_EVENT, NULL, NULL, 0);
 	if (hif_napi_enabled(scn, ce_id))
 		hif_napi_schedule(scn, ce_id);
 	else

+ 17 - 36
core/hif/src/hif_main.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -292,7 +292,7 @@ void hif_vote_link_down(void)
 
 	scn->linkstate_vote--;
 	if (scn->linkstate_vote == 0)
-		hif_bus_prevent_linkdown(false);
+		hif_bus_prevent_linkdown(scn, false);
 }
 
 /**
@@ -313,7 +313,7 @@ void hif_vote_link_up(void)
 
 	scn->linkstate_vote++;
 	if (scn->linkstate_vote == 1)
-		hif_bus_prevent_linkdown(true);
+		hif_bus_prevent_linkdown(scn, true);
 }
 
 /**
@@ -511,7 +511,7 @@ void hif_set_fw_info(void *scn, uint32_t target_fw_version)
  *
  * Return: scn
  */
-CDF_STATUS hif_open(void)
+CDF_STATUS hif_open(enum ath_hal_bus_type bus_type)
 {
 	struct ol_softc *scn;
 	v_CONTEXT_t cds_context;
@@ -536,6 +536,14 @@ CDF_STATUS hif_open(void)
 	cdf_atomic_init(&scn->tasklet_from_intr);
 	init_waitqueue_head(&scn->aps_osdev.event_queue);
 	scn->linkstate_vote = 0;
+
+	status = hif_bus_open(scn, bus_type);
+	if (status != CDF_STATUS_SUCCESS) {
+		HIF_ERROR("%s: hif_bus_open error = %d, bus_type = %d",
+				  __func__, status, bus_type);
+		cds_free_context(cds_context, CDF_MODULE_ID_HIF, scn);
+	}
+
 	return status;
 }
 
@@ -592,16 +600,8 @@ CDF_STATUS hif_enable(void *hif_ctx, struct device *dev,
 		return CDF_STATUS_E_NULL_VALUE;
 	}
 
-	status = hif_bus_open(scn, bus_type);
-	if (status != CDF_STATUS_SUCCESS) {
-		HIF_ERROR("%s: hif_bus_open error = %d, bus_type = %d",
-				  __func__, status, bus_type);
-		return status;
-	}
-
 	status = hif_enable_bus(scn, dev, bdev, bid, type);
 	if (status != CDF_STATUS_SUCCESS) {
-		hif_bus_close(scn);
 		HIF_ERROR("%s: hif_enable_bus error = %d",
 				  __func__, status);
 		return status;
@@ -613,7 +613,6 @@ CDF_STATUS hif_enable(void *hif_ctx, struct device *dev,
 	if (hif_config_ce(scn)) {
 		HIF_ERROR("%s: Target probe failed.", __func__);
 		hif_disable_bus(scn->aps_osdev.bdev);
-		hif_bus_close(scn);
 		status = CDF_STATUS_E_FAILURE;
 		return status;
 	}
@@ -652,7 +651,7 @@ void hif_pktlogmod_exit(void *hif_ctx)
 {
 	struct ol_softc *scn = hif_ctx;
 
-	if (scn && cds_get_conparam() != CDF_FTM_MODE &&
+	if (scn && cds_get_conparam() != CDF_GLOBAL_FTM_MODE &&
 	    !WLAN_IS_EPPING_ENABLED(cds_get_conparam()) && scn->pkt_log_init) {
 		pktlogmod_exit(scn);
 		scn->pkt_log_init = false;
@@ -664,13 +663,6 @@ void hif_pktlogmod_exit(void *hif_ctx)
 }
 #endif
 
-#if ((!defined(QCA_WIFI_3_0_IHELIUM) && !defined(QCA_WIFI_3_0_ADRASTEA)) || defined(CONFIG_ICNSS))
-static inline void cnss_pcie_notify_q6(void)
-{
-	return;
-}
-#endif
-
 /**
  * hif_wlan_disable(): call the platform driver to disable wlan
  *
@@ -684,17 +676,12 @@ void hif_wlan_disable(void)
 	enum icnss_driver_mode mode;
 	uint32_t con_mode = cds_get_conparam();
 
-	switch (con_mode) {
-	case CDF_FTM_MODE:
+	if (CDF_GLOBAL_FTM_MODE == con_mode)
 		mode = ICNSS_FTM;
-		break;
-	case CDF_EPPING_MODE:
+	else if (WLAN_IS_EPPING_ENABLED(cds_get_conparam()))
 		mode = ICNSS_EPPING;
-		break;
-	default:
+	else
 		mode = ICNSS_MISSION;
-		break;
-	}
 
 	icnss_wlan_disable(mode);
 }
@@ -718,12 +705,6 @@ void hif_disable(void *hif_ctx, enum hif_disable_type type)
 	if (scn->aps_osdev.bdev)
 		hif_disable_bus(scn->aps_osdev.bdev);
 
-	if (IHELIUM_BU) {
-		cnss_pcie_notify_q6();
-		HIF_TRACE("%s: cnss_pcie_notify_q6 done, notice_send= %d",
-			  __func__, scn->notice_send);
-	}
-
 	hif_wlan_disable();
 
 	scn->notice_send = false;
@@ -782,7 +763,7 @@ void hif_crash_shutdown(void *hif_ctx)
 		return;
 	}
 
-	if (cds_is_load_unload_in_progress()) {
+	if (cds_is_load_or_unload_in_progress()) {
 		HIF_ERROR("%s: Load/unload is in progress, ignore!", __func__);
 		return;
 	}

+ 3 - 9
core/hif/src/hif_main.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -73,12 +73,6 @@ bool hif_target_forced_awake(struct ol_softc *scn);
 #define MAX_NUM_OF_RECEIVES 1000
 #endif /* SLUB_DEBUG_ON / FEATURE_NAPI */
 
-#ifdef QCA_WIFI_3_0_IHELIUM
-#define IHELIUM_BU 1
-#else
-#define IHELIUM_BU 0
-#endif
-
 #ifdef QCA_WIFI_3_0_ADRASTEA
 #define ADRASTEA_BU 1
 #else
@@ -101,7 +95,7 @@ bool hif_target_forced_awake(struct ol_softc *scn);
 #define AR6320_FW_3_2  (0x32)
 #define ADRASTEA_DEVICE_ID (0xabcd)
 #define ADRASTEA_DEVICE_ID_P2_E12 (0x7021)
-#if (defined(QVIT) || defined (QCA_WIFI_3_0_IHELIUM))
+#if (defined(QVIT))
 #define QCA6180_DEVICE_ID (0xabcd)
 #else
 #define QCA6180_DEVICE_ID (0x041)
@@ -137,6 +131,6 @@ CDF_STATUS hif_bus_open(struct ol_softc *ol_sc,
 CDF_STATUS hif_enable_bus(struct ol_softc *ol_sc, struct device *dev,
 	void *bdev, const hif_bus_id *bid, enum hif_enable_type type);
 void hif_disable_bus(void *bdev);
-void hif_bus_prevent_linkdown(bool flag);
+void hif_bus_prevent_linkdown(struct ol_softc *scn, bool flag);
 
 #endif /* __HIF_MAIN_H__ */

+ 27 - 0
core/hif/src/icnss_stub/icnss_stub.c

@@ -93,6 +93,17 @@ int icnss_wlan_disable(enum icnss_driver_mode mode)
 	return 0;
 }
 
+/**
+ * icnss_set_fw_debug_mode() - icnss_set_fw_debug_mode
+ * @mode: fw debug mode, 0 for QXDM, 1 for WMI
+ *
+ * Return: int
+ */
+int icnss_set_fw_debug_mode(bool mode)
+{
+	return 0;
+}
+
 #else
 
 /**
@@ -167,6 +178,22 @@ int icnss_wlan_disable(enum icnss_driver_mode con_mode)
 	cnss_wlan_disable(mode);
 	return 0;
 }
+
+/**
+ * icnss_set_fw_debug_mode() - call the platform driver to set fw
+ * debug mode
+ * @mode: fw debug mode, 0 for QXDM, 1 for WMI
+ *
+ * This function passes the fw debug mode to platform driver.
+ * cnss_set_fw_debug_mode has been hacked to do a qmi handshake with fw.
+ * This is not needed for rome.
+ *
+ * Return: int
+ */
+int icnss_set_fw_debug_mode(bool mode)
+{
+	return cnss_set_fw_debug_mode(mode);
+}
 #endif
 
 /**

Some files were not shown because too many files changed in this diff