Explorar el Código

Merge "Release 5.2.0.35I"

Linux Build Service Account hace 7 años
padre
commit
6c1da11513
Se han modificado 100 ficheros con 835 adiciones y 175 borrados
  1. 2 2
      Kbuild
  2. 1 1
      Kconfig
  3. 0 0
      components/pmo/core/inc/wlan_pmo_arp.h
  4. 0 0
      components/pmo/core/inc/wlan_pmo_gtk.h
  5. 0 0
      components/pmo/core/inc/wlan_pmo_hw_filter.h
  6. 0 0
      components/pmo/core/inc/wlan_pmo_lphb.h
  7. 0 0
      components/pmo/core/inc/wlan_pmo_main.h
  8. 0 0
      components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h
  9. 0 0
      components/pmo/core/inc/wlan_pmo_ns.h
  10. 0 0
      components/pmo/core/inc/wlan_pmo_objmgr.h
  11. 0 0
      components/pmo/core/inc/wlan_pmo_pkt_filter.h
  12. 0 0
      components/pmo/core/inc/wlan_pmo_priv.h
  13. 0 0
      components/pmo/core/inc/wlan_pmo_static_config.h
  14. 0 0
      components/pmo/core/inc/wlan_pmo_suspend_resume.h
  15. 0 0
      components/pmo/core/inc/wlan_pmo_wow.h
  16. 0 0
      components/pmo/core/src/wlan_pmo_arp.c
  17. 0 0
      components/pmo/core/src/wlan_pmo_gtk.c
  18. 0 0
      components/pmo/core/src/wlan_pmo_hw_filter.c
  19. 0 0
      components/pmo/core/src/wlan_pmo_lphb.c
  20. 0 0
      components/pmo/core/src/wlan_pmo_main.c
  21. 0 0
      components/pmo/core/src/wlan_pmo_mc_addr_filtering.c
  22. 0 0
      components/pmo/core/src/wlan_pmo_ns.c
  23. 0 0
      components/pmo/core/src/wlan_pmo_pkt_filter.c
  24. 0 0
      components/pmo/core/src/wlan_pmo_static_config.c
  25. 0 0
      components/pmo/core/src/wlan_pmo_suspend_resume.c
  26. 0 0
      components/pmo/core/src/wlan_pmo_wow.c
  27. 0 0
      components/pmo/dispatcher/inc/wlan_pmo_arp_public_struct.h
  28. 0 0
      components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h
  29. 0 0
      components/pmo/dispatcher/inc/wlan_pmo_gtk_public_struct.h
  30. 0 0
      components/pmo/dispatcher/inc/wlan_pmo_hw_filter_public_struct.h
  31. 0 0
      components/pmo/dispatcher/inc/wlan_pmo_lphb_public_struct.h
  32. 0 0
      components/pmo/dispatcher/inc/wlan_pmo_mc_addr_filtering_public_struct.h
  33. 0 0
      components/pmo/dispatcher/inc/wlan_pmo_ns_public_struct.h
  34. 0 0
      components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h
  35. 0 0
      components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h
  36. 0 0
      components/pmo/dispatcher/inc/wlan_pmo_pkt_filter_public_struct.h
  37. 0 0
      components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h
  38. 0 0
      components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h
  39. 0 0
      components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h
  40. 0 0
      components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c
  41. 0 0
      components/pmo/dispatcher/src/wlan_pmo_tgt_arp.c
  42. 0 0
      components/pmo/dispatcher/src/wlan_pmo_tgt_gtk.c
  43. 0 0
      components/pmo/dispatcher/src/wlan_pmo_tgt_hw_filter.c
  44. 0 0
      components/pmo/dispatcher/src/wlan_pmo_tgt_lphb.c
  45. 0 0
      components/pmo/dispatcher/src/wlan_pmo_tgt_mc_addr_filtering.c
  46. 0 0
      components/pmo/dispatcher/src/wlan_pmo_tgt_ns.c
  47. 0 0
      components/pmo/dispatcher/src/wlan_pmo_tgt_pkt_filter.c
  48. 0 0
      components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c
  49. 0 0
      components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c
  50. 0 0
      components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c
  51. 0 0
      components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c
  52. 0 0
      components/target_if/pmo/inc/target_if_pmo.h
  53. 0 0
      components/target_if/pmo/src/target_if_pmo_arp.c
  54. 0 0
      components/target_if/pmo/src/target_if_pmo_gtk.c
  55. 0 0
      components/target_if/pmo/src/target_if_pmo_hw_filter.c
  56. 0 0
      components/target_if/pmo/src/target_if_pmo_lphb.c
  57. 0 0
      components/target_if/pmo/src/target_if_pmo_main.c
  58. 0 0
      components/target_if/pmo/src/target_if_pmo_mc_addr_filtering.c
  59. 0 0
      components/target_if/pmo/src/target_if_pmo_ns.c
  60. 0 0
      components/target_if/pmo/src/target_if_pmo_pkt_filter.c
  61. 0 0
      components/target_if/pmo/src/target_if_pmo_static_config.c
  62. 0 0
      components/target_if/pmo/src/target_if_pmo_suspend_resume.c
  63. 0 0
      components/target_if/pmo/src/target_if_pmo_wow.c
  64. 24 5
      core/dp/txrx/ol_txrx.c
  65. 1 0
      core/dp/txrx/ol_txrx.h
  66. 1 0
      core/dp/txrx/ol_txrx_types.h
  67. 93 0
      core/hdd/inc/wlan_hdd_cfg.h
  68. 8 0
      core/hdd/inc/wlan_hdd_main.h
  69. 21 20
      core/hdd/src/wlan_hdd_assoc.c
  70. 44 0
      core/hdd/src/wlan_hdd_cfg.c
  71. 75 35
      core/hdd/src/wlan_hdd_cfg80211.c
  72. 3 0
      core/hdd/src/wlan_hdd_driver_ops.c
  73. 2 1
      core/hdd/src/wlan_hdd_ftm.c
  74. 13 12
      core/hdd/src/wlan_hdd_main.c
  75. 2 3
      core/hdd/src/wlan_hdd_nan_datapath.c
  76. 2 2
      core/hdd/src/wlan_hdd_regulatory.c
  77. 17 4
      core/hdd/src/wlan_hdd_stats.c
  78. 2 2
      core/hdd/src/wlan_hdd_wext.c
  79. 3 3
      core/mac/inc/qwlan_version.h
  80. 39 0
      core/mac/inc/sir_api.h
  81. 5 4
      core/mac/src/dph/dph_hash_table.c
  82. 1 1
      core/mac/src/pe/include/lim_session.h
  83. 1 1
      core/mac/src/pe/lim/lim_link_monitoring_algo.c
  84. 96 0
      core/mac/src/pe/lim/lim_process_assoc_req_frame.c
  85. 1 1
      core/mac/src/pe/lim/lim_process_mlm_req_messages.c
  86. 11 0
      core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
  87. 15 28
      core/mac/src/pe/lim/lim_process_sme_req_messages.c
  88. 0 4
      core/mac/src/pe/lim/lim_process_tdls.c
  89. 11 0
      core/mac/src/pe/lim/lim_types.h
  90. 2 0
      core/mac/src/sys/legacy/src/utils/src/mac_trace.c
  91. 23 0
      core/sap/inc/sap_api.h
  92. 11 0
      core/sap/src/sap_fsm.c
  93. 23 0
      core/sap/src/sap_module.c
  94. 25 0
      core/sme/inc/csr_api.h
  95. 3 0
      core/sme/inc/csr_internal.h
  96. 33 0
      core/sme/inc/sme_api.h
  97. 8 0
      core/sme/inc/sme_internal.h
  98. 0 11
      core/sme/inc/sme_qos_internal.h
  99. 106 0
      core/sme/src/common/sme_api.c
  100. 107 35
      core/sme/src/csr/csr_api_roam.c

+ 2 - 2
Kbuild

@@ -883,7 +883,7 @@ UMAC_MGMT_TXRX_OBJS := $(UMAC_MGMT_TXRX_DIR)/core/src/wlan_mgmt_txrx_main.o \
 	$(UMAC_MGMT_TXRX_DIR)/dispatcher/src/wlan_mgmt_txrx_tgt_api.o
 
 ########## POWER MANAGEMENT OFFLOADS (PMO) ##########
-PMO_DIR :=	core/components/pmo
+PMO_DIR :=	components/pmo
 PMO_INC :=	-I$(WLAN_ROOT)/$(PMO_DIR)/core/inc \
 			-I$(WLAN_ROOT)/$(PMO_DIR)/core/src \
 			-I$(WLAN_ROOT)/$(PMO_DIR)/dispatcher/inc \
@@ -914,7 +914,7 @@ PMO_OBJS :=     $(PMO_DIR)/core/src/wlan_pmo_main.o \
 		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_pkt_filter.o
 
 ########## CLD TARGET_IF #######
-CLD_TARGET_IF_DIR := core/components/target_if
+CLD_TARGET_IF_DIR := components/target_if
 
 CLD_TARGET_IF_INC := -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/pmo/inc \
 					 -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/pmo/src \

+ 1 - 1
Kconfig

@@ -105,7 +105,7 @@ config WLAN_TX_FLOW_CONTROL_V2
 config WLAN_LRO
 	bool "Enable Large Receive Offload"
 	depends on HELIUMPLUS
-	depends on CONFIG_INET_LRO
+	depends on INET_LRO
 	default n
 
 config WLAN_SYNC_TSF

+ 0 - 0
core/components/pmo/core/inc/wlan_pmo_arp.h → components/pmo/core/inc/wlan_pmo_arp.h


+ 0 - 0
core/components/pmo/core/inc/wlan_pmo_gtk.h → components/pmo/core/inc/wlan_pmo_gtk.h


+ 0 - 0
core/components/pmo/core/inc/wlan_pmo_hw_filter.h → components/pmo/core/inc/wlan_pmo_hw_filter.h


+ 0 - 0
core/components/pmo/core/inc/wlan_pmo_lphb.h → components/pmo/core/inc/wlan_pmo_lphb.h


+ 0 - 0
core/components/pmo/core/inc/wlan_pmo_main.h → components/pmo/core/inc/wlan_pmo_main.h


+ 0 - 0
core/components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h → components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h


+ 0 - 0
core/components/pmo/core/inc/wlan_pmo_ns.h → components/pmo/core/inc/wlan_pmo_ns.h


+ 0 - 0
core/components/pmo/core/inc/wlan_pmo_objmgr.h → components/pmo/core/inc/wlan_pmo_objmgr.h


+ 0 - 0
core/components/pmo/core/inc/wlan_pmo_pkt_filter.h → components/pmo/core/inc/wlan_pmo_pkt_filter.h


+ 0 - 0
core/components/pmo/core/inc/wlan_pmo_priv.h → components/pmo/core/inc/wlan_pmo_priv.h


+ 0 - 0
core/components/pmo/core/inc/wlan_pmo_static_config.h → components/pmo/core/inc/wlan_pmo_static_config.h


+ 0 - 0
core/components/pmo/core/inc/wlan_pmo_suspend_resume.h → components/pmo/core/inc/wlan_pmo_suspend_resume.h


+ 0 - 0
core/components/pmo/core/inc/wlan_pmo_wow.h → components/pmo/core/inc/wlan_pmo_wow.h


+ 0 - 0
core/components/pmo/core/src/wlan_pmo_arp.c → components/pmo/core/src/wlan_pmo_arp.c


+ 0 - 0
core/components/pmo/core/src/wlan_pmo_gtk.c → components/pmo/core/src/wlan_pmo_gtk.c


+ 0 - 0
core/components/pmo/core/src/wlan_pmo_hw_filter.c → components/pmo/core/src/wlan_pmo_hw_filter.c


+ 0 - 0
core/components/pmo/core/src/wlan_pmo_lphb.c → components/pmo/core/src/wlan_pmo_lphb.c


+ 0 - 0
core/components/pmo/core/src/wlan_pmo_main.c → components/pmo/core/src/wlan_pmo_main.c


+ 0 - 0
core/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c → components/pmo/core/src/wlan_pmo_mc_addr_filtering.c


+ 0 - 0
core/components/pmo/core/src/wlan_pmo_ns.c → components/pmo/core/src/wlan_pmo_ns.c


+ 0 - 0
core/components/pmo/core/src/wlan_pmo_pkt_filter.c → components/pmo/core/src/wlan_pmo_pkt_filter.c


+ 0 - 0
core/components/pmo/core/src/wlan_pmo_static_config.c → components/pmo/core/src/wlan_pmo_static_config.c


+ 0 - 0
core/components/pmo/core/src/wlan_pmo_suspend_resume.c → components/pmo/core/src/wlan_pmo_suspend_resume.c


+ 0 - 0
core/components/pmo/core/src/wlan_pmo_wow.c → components/pmo/core/src/wlan_pmo_wow.c


+ 0 - 0
core/components/pmo/dispatcher/inc/wlan_pmo_arp_public_struct.h → components/pmo/dispatcher/inc/wlan_pmo_arp_public_struct.h


+ 0 - 0
core/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h → components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h


+ 0 - 0
core/components/pmo/dispatcher/inc/wlan_pmo_gtk_public_struct.h → components/pmo/dispatcher/inc/wlan_pmo_gtk_public_struct.h


+ 0 - 0
core/components/pmo/dispatcher/inc/wlan_pmo_hw_filter_public_struct.h → components/pmo/dispatcher/inc/wlan_pmo_hw_filter_public_struct.h


+ 0 - 0
core/components/pmo/dispatcher/inc/wlan_pmo_lphb_public_struct.h → components/pmo/dispatcher/inc/wlan_pmo_lphb_public_struct.h


+ 0 - 0
core/components/pmo/dispatcher/inc/wlan_pmo_mc_addr_filtering_public_struct.h → components/pmo/dispatcher/inc/wlan_pmo_mc_addr_filtering_public_struct.h


+ 0 - 0
core/components/pmo/dispatcher/inc/wlan_pmo_ns_public_struct.h → components/pmo/dispatcher/inc/wlan_pmo_ns_public_struct.h


+ 0 - 0
core/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h → components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h


+ 0 - 0
core/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h → components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h


+ 0 - 0
core/components/pmo/dispatcher/inc/wlan_pmo_pkt_filter_public_struct.h → components/pmo/dispatcher/inc/wlan_pmo_pkt_filter_public_struct.h


+ 0 - 0
core/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h → components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h


+ 0 - 0
core/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h → components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h


+ 0 - 0
core/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h → components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h


+ 0 - 0
core/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c → components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c


+ 0 - 0
core/components/pmo/dispatcher/src/wlan_pmo_tgt_arp.c → components/pmo/dispatcher/src/wlan_pmo_tgt_arp.c


+ 0 - 0
core/components/pmo/dispatcher/src/wlan_pmo_tgt_gtk.c → components/pmo/dispatcher/src/wlan_pmo_tgt_gtk.c


+ 0 - 0
core/components/pmo/dispatcher/src/wlan_pmo_tgt_hw_filter.c → components/pmo/dispatcher/src/wlan_pmo_tgt_hw_filter.c


+ 0 - 0
core/components/pmo/dispatcher/src/wlan_pmo_tgt_lphb.c → components/pmo/dispatcher/src/wlan_pmo_tgt_lphb.c


+ 0 - 0
core/components/pmo/dispatcher/src/wlan_pmo_tgt_mc_addr_filtering.c → components/pmo/dispatcher/src/wlan_pmo_tgt_mc_addr_filtering.c


+ 0 - 0
core/components/pmo/dispatcher/src/wlan_pmo_tgt_ns.c → components/pmo/dispatcher/src/wlan_pmo_tgt_ns.c


+ 0 - 0
core/components/pmo/dispatcher/src/wlan_pmo_tgt_pkt_filter.c → components/pmo/dispatcher/src/wlan_pmo_tgt_pkt_filter.c


+ 0 - 0
core/components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c → components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c


+ 0 - 0
core/components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c → components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c


+ 0 - 0
core/components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c → components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c


+ 0 - 0
core/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c → components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c


+ 0 - 0
core/components/target_if/pmo/inc/target_if_pmo.h → components/target_if/pmo/inc/target_if_pmo.h


+ 0 - 0
core/components/target_if/pmo/src/target_if_pmo_arp.c → components/target_if/pmo/src/target_if_pmo_arp.c


+ 0 - 0
core/components/target_if/pmo/src/target_if_pmo_gtk.c → components/target_if/pmo/src/target_if_pmo_gtk.c


+ 0 - 0
core/components/target_if/pmo/src/target_if_pmo_hw_filter.c → components/target_if/pmo/src/target_if_pmo_hw_filter.c


+ 0 - 0
core/components/target_if/pmo/src/target_if_pmo_lphb.c → components/target_if/pmo/src/target_if_pmo_lphb.c


+ 0 - 0
core/components/target_if/pmo/src/target_if_pmo_main.c → components/target_if/pmo/src/target_if_pmo_main.c


+ 0 - 0
core/components/target_if/pmo/src/target_if_pmo_mc_addr_filtering.c → components/target_if/pmo/src/target_if_pmo_mc_addr_filtering.c


+ 0 - 0
core/components/target_if/pmo/src/target_if_pmo_ns.c → components/target_if/pmo/src/target_if_pmo_ns.c


+ 0 - 0
core/components/target_if/pmo/src/target_if_pmo_pkt_filter.c → components/target_if/pmo/src/target_if_pmo_pkt_filter.c


+ 0 - 0
core/components/target_if/pmo/src/target_if_pmo_static_config.c → components/target_if/pmo/src/target_if_pmo_static_config.c


+ 0 - 0
core/components/target_if/pmo/src/target_if_pmo_suspend_resume.c → components/target_if/pmo/src/target_if_pmo_suspend_resume.c


+ 0 - 0
core/components/target_if/pmo/src/target_if_pmo_wow.c → components/target_if/pmo/src/target_if_pmo_wow.c


+ 24 - 5
core/dp/txrx/ol_txrx.c

@@ -3333,8 +3333,26 @@ static QDF_STATUS ol_txrx_clear_peer(struct cdp_pdev *ppdev, uint8_t sta_id)
 
 }
 
+void peer_unmap_timer_work_function(void *param)
+{
+	WMA_LOGE("Enter: %s", __func__);
+	/*
+	 * wma_peer_debug_dump() will be replaced with a new routine.
+	 * Add the equivalent of wma_peer_debug_dump() when available.
+	 */
+	if (cds_is_self_recovery_enabled()) {
+		if (!cds_is_driver_recovering())
+			cds_trigger_recovery(false);
+		else
+			WMA_LOGE("%s: Recovery is in progress, ignore!",
+					__func__);
+	} else {
+		QDF_BUG(0);
+	}
+}
+
 /**
- * peer_unmap_timer() - peer unmap timer function
+ * peer_unmap_timer_handler() - peer unmap timer function
  * @data: peer object pointer
  *
  * Return: none
@@ -3342,6 +3360,7 @@ static QDF_STATUS ol_txrx_clear_peer(struct cdp_pdev *ppdev, uint8_t sta_id)
 void peer_unmap_timer_handler(void *data)
 {
 	ol_txrx_peer_handle peer = (ol_txrx_peer_handle)data;
+	ol_txrx_pdev_handle txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
 
 	ol_txrx_err("all unmap events not received for peer %p, ref_cnt %d",
 		    peer, qdf_atomic_read(&peer->ref_cnt));
@@ -3351,10 +3370,10 @@ void peer_unmap_timer_handler(void *data)
 		    peer->mac_addr.raw[2], peer->mac_addr.raw[3],
 		    peer->mac_addr.raw[4], peer->mac_addr.raw[5]);
 	if (!cds_is_driver_recovering()) {
-		/*
-		 * Add the equivalent of wma_peer_debug_dump() when available.
-		 */
-		QDF_BUG(0);
+		qdf_create_work(0, &txrx_pdev->peer_unmap_timer_work,
+				peer_unmap_timer_work_function,
+				NULL);
+		qdf_sched_work(0, &txrx_pdev->peer_unmap_timer_work);
 	} else {
 		ol_txrx_err("Recovery is in progress, ignore!");
 	}

+ 1 - 0
core/dp/txrx/ol_txrx.h

@@ -128,6 +128,7 @@ void *ol_txrx_find_peer_by_addr(struct cdp_pdev *pdev,
 				uint8_t *peer_id);
 
 void htt_pkt_log_init(struct cdp_pdev *pdev_handle, void *scn);
+void peer_unmap_timer_work_function(void *);
 void peer_unmap_timer_handler(void *data);
 
 #endif /* _OL_TXRX__H_ */

+ 1 - 0
core/dp/txrx/ol_txrx_types.h

@@ -974,6 +974,7 @@ struct ol_txrx_pdev_t {
 		qdf_atomic_t lro_dev_cnt;
 	} lro_info;
 	struct ol_txrx_peer_t *self_peer;
+	qdf_work_t peer_unmap_timer_work;
 };
 
 struct ol_txrx_vdev_t {

+ 93 - 0
core/hdd/inc/wlan_hdd_cfg.h

@@ -5798,6 +5798,29 @@ enum hdd_link_speed_rpt_type {
 #define CFG_RATE_FOR_TX_MGMT_5G_MAX        (WNI_CFG_RATE_FOR_TX_MGMT_5G_STAMAX)
 #define CFG_RATE_FOR_TX_MGMT_5G_DEFAULT    (WNI_CFG_RATE_FOR_TX_MGMT_5G_STADEF)
 
+/*
+ * <ini>
+ * gPreventLinkDown - Enable to prevent bus link from going down
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Enable to prevent bus link from going down. Useful for platforms that do not
+ * (yet) support link down suspend cases.
+ *
+ * Related: N/A
+ *
+ * Supported Feature: Suspend/Resume
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_PREVENT_LINK_DOWN_NAME		"gPreventLinkDown"
+#define CFG_PREVENT_LINK_DOWN_MIN		(0)
+#define CFG_PREVENT_LINK_DOWN_MAX		(1)
+#define CFG_PREVENT_LINK_DOWN_DEFAULT		(0)
+
 #ifdef FEATURE_WLAN_TDLS
 /*
  * <ini>
@@ -10456,6 +10479,70 @@ enum hdd_external_acs_freq_band {
 #define CFG_ITO_REPEAT_COUNT_MIN        (0)
 #define CFG_ITO_REPEAT_COUNT_MAX        (5)
 #define CFG_ITO_REPEAT_COUNT_DEFAULT    (0)
+/*
+ * <ini>
+ * groam_disallow_duration -disallow duration before roaming
+ * @Min: 0
+ * @Max: 3600
+ * @Default: 30
+ *
+ * This ini is used to configure how long LCA[Last Connected AP] AP will
+ * be disallowed before it can be a roaming candidate again, in units of
+ * seconds.
+ *
+ * Related: LFR
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_ROAM_DISALLOW_DURATION_NAME    "groam_disallow_duration"
+#define CFG_ROAM_DISALLOW_DURATION_MIN     (0)
+#define CFG_ROAM_DISALLOW_DURATION_MAX     (3600)
+#define CFG_ROAM_DISALLOW_DURATION_DEFAULT (30)
+
+/*
+ * <ini>
+ * grssi_channel_penalization - RSSI penalization
+ * @Min: 0
+ * @Max: 15
+ * @Default: 5
+ *
+ * This ini is used to configure RSSI that will be penalized if candidate(s)
+ * are found to be in the same channel as disallowed AP's, in units of db.
+ *
+ * Related: LFR
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_ROAM_RSSI_CHANNEL_PENALIZATION_NAME    "grssi_channel_penalization"
+#define CFG_ROAM_RSSI_CHANNEL_PENALIZATION_MIN     (0)
+#define CFG_ROAM_RSSI_CHANNEL_PENALIZATION_MAX     (15)
+#define CFG_ROAM_RSSI_CHANNEL_PENALIZATION_DEFAULT (5)
+
+/*
+ * <ini>
+ * groam_num_disallowed_aps - Max number of AP's to maintain in LCA list
+ * @Min: 0
+ * @Max: 8
+ * @Default: 3
+ *
+ * This ini is used to set the maximum number of AP's to be maintained
+ * in LCA [Last Connected AP] list.
+ *
+ * Related: LFR
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_ROAM_NUM_DISALLOWED_APS_NAME    "groam_num_disallowed_aps"
+#define CFG_ROAM_NUM_DISALLOWED_APS_MIN     (0)
+#define CFG_ROAM_NUM_DISALLOWED_APS_MAX     (8)
+#define CFG_ROAM_NUM_DISALLOWED_APS_DEFAULT (3)
+
 /*
  * Type declarations
  */
@@ -10784,6 +10871,7 @@ struct hdd_config {
 	uint8_t enable_tx_ldpc;
 	uint8_t enable_rx_ldpc;
 	bool enable5gEBT;
+	bool prevent_link_down;
 #ifdef FEATURE_WLAN_TDLS
 	bool fEnableTDLSSupport;
 	bool fEnableTDLSImplicitTrigger;
@@ -11200,6 +11288,11 @@ struct hdd_config {
 	uint16_t num_11b_tx_chains;
 	uint16_t num_11ag_tx_chains;
 	uint8_t ito_repeat_count;
+
+	/* LCA(Last connected AP) disallow configs */
+	uint32_t disallow_duration;
+	uint32_t rssi_channel_penalization;
+	uint32_t num_disallowed_aps;
 };
 
 #define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))

+ 8 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -92,6 +92,14 @@
 #define NUM_TX_QUEUES 4
 #endif
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
+#define HDD_NL80211_BAND_2GHZ   NL80211_BAND_2GHZ
+#define HDD_NL80211_BAND_5GHZ   NL80211_BAND_5GHZ
+#else
+#define HDD_NL80211_BAND_2GHZ   IEEE80211_BAND_2GHZ
+#define HDD_NL80211_BAND_5GHZ   IEEE80211_BAND_5GHZ
+#endif
+
 /** Length of the TX queue for the netdev */
 #define HDD_NETDEV_TX_QUEUE_LEN (3000)
 

+ 21 - 20
core/hdd/src/wlan_hdd_assoc.c

@@ -165,31 +165,30 @@ hdd_conn_set_authenticated(hdd_adapter_t *pAdapter, uint8_t authState)
 
 /**
  * hdd_conn_set_connection_state() - set connection state
- * @pAdapter: pointer to the adapter
- * @connState: connection state
+ * @adapter: pointer to the adapter
+ * @conn_state: connection state
  *
  * This function updates the global HDD station context connection state.
  *
  * Return: none
  */
-void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
-				   eConnectionState connState)
+void hdd_conn_set_connection_state(hdd_adapter_t *adapter,
+				   eConnectionState conn_state)
 {
-	hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-	hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+	hdd_station_ctx_t *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 
 	/* save the new connection state */
-	hdd_debug("%pS Changed connectionState Changed from oldState:%d to State:%d",
-		(void *)_RET_IP_, pHddStaCtx->conn_info.connState,
-		connState);
+	hdd_debug("%pS Changed conn state from old:%d to new:%d for dev %s",
+		(void *)_RET_IP_, hdd_sta_ctx->conn_info.connState,
+		conn_state, adapter->dev->name);
 
-	hdd_tsf_notify_wlan_state_change(pAdapter,
-					 pHddStaCtx->conn_info.connState,
-					 connState);
-	pHddStaCtx->conn_info.connState = connState;
+	hdd_tsf_notify_wlan_state_change(adapter,
+					 hdd_sta_ctx->conn_info.connState,
+					 conn_state);
+	hdd_sta_ctx->conn_info.connState = conn_state;
 
-	/* Check is pending ROC request or not when connection state changed */
-	schedule_delayed_work(&pHddCtx->roc_req_work, 0);
+	schedule_delayed_work(&hdd_ctx->roc_req_work, 0);
 }
 
 /**
@@ -2474,7 +2473,9 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
 	    pHddStaCtx->conn_info.connState)) &&
 	    ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult) ||
 	    (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
-		hdd_info("Disconnect from HDD in progress");
+		hdd_info("hddDisconInProgress state=%d, result=%d, status=%d",
+				pHddStaCtx->conn_info.connState,
+				roamResult, roamStatus);
 		hddDisconInProgress = true;
 	}
 
@@ -3207,10 +3208,10 @@ static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
 
 			if (chan_no <= 14)
 				freq = ieee80211_channel_to_frequency(chan_no,
-					  NL80211_BAND_2GHZ);
+					  HDD_NL80211_BAND_2GHZ);
 			else
 				freq = ieee80211_channel_to_frequency(chan_no,
-					  NL80211_BAND_5GHZ);
+					  HDD_NL80211_BAND_5GHZ);
 
 			chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
 
@@ -3350,8 +3351,8 @@ static bool roam_remove_ibss_station(hdd_adapter_t *pAdapter, uint8_t staId)
 
 	if (MAX_PEERS == empty_slots) {
 		/* Last peer departed, set the IBSS state appropriately */
-		pHddStaCtx->conn_info.connState =
-			eConnectionState_IbssDisconnected;
+		hdd_conn_set_connection_state(pAdapter,
+				eConnectionState_IbssDisconnected);
 		hdd_debug("Last IBSS Peer Departed!!!");
 	}
 	/* Find next active staId, to have a valid sta trigger for TL. */

+ 44 - 0
core/hdd/src/wlan_hdd_cfg.c

@@ -2197,6 +2197,13 @@ struct reg_table_entry g_registry_table[] = {
 		     CFG_PPS_ENABLE_5G_EBT_FEATURE_MIN,
 		     CFG_PPS_ENABLE_5G_EBT_FEATURE_MAX),
 
+	REG_VARIABLE(CFG_PREVENT_LINK_DOWN_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, prevent_link_down,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_PREVENT_LINK_DOWN_DEFAULT,
+		     CFG_PREVENT_LINK_DOWN_MIN,
+		     CFG_PREVENT_LINK_DOWN_MAX),
+
 #ifdef FEATURE_WLAN_TDLS
 	REG_VARIABLE(CFG_TDLS_SUPPORT_ENABLE, WLAN_PARAM_Integer,
 		     struct hdd_config, fEnableTDLSSupport,
@@ -4463,6 +4470,27 @@ struct reg_table_entry g_registry_table[] = {
 		CFG_ITO_REPEAT_COUNT_MIN,
 		CFG_ITO_REPEAT_COUNT_MAX),
 
+	REG_VARIABLE(CFG_ROAM_DISALLOW_DURATION_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, disallow_duration,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ROAM_DISALLOW_DURATION_DEFAULT,
+		CFG_ROAM_DISALLOW_DURATION_MIN,
+		CFG_ROAM_DISALLOW_DURATION_MAX),
+
+	REG_VARIABLE(CFG_ROAM_RSSI_CHANNEL_PENALIZATION_NAME,
+		WLAN_PARAM_Integer, struct hdd_config,
+		rssi_channel_penalization,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ROAM_RSSI_CHANNEL_PENALIZATION_DEFAULT,
+		CFG_ROAM_RSSI_CHANNEL_PENALIZATION_MIN,
+		CFG_ROAM_RSSI_CHANNEL_PENALIZATION_MAX),
+
+	REG_VARIABLE(CFG_ROAM_NUM_DISALLOWED_APS_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, num_disallowed_aps,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ROAM_NUM_DISALLOWED_APS_DEFAULT,
+		CFG_ROAM_NUM_DISALLOWED_APS_MIN,
+		CFG_ROAM_NUM_DISALLOWED_APS_MAX),
 };
 
 
@@ -6004,6 +6032,15 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
 	hdd_debug("Name = [%s] value = [%u]",
 		CFG_ITO_REPEAT_COUNT_NAME,
 		pHddCtx->config->ito_repeat_count);
+	hdd_debug("Name = [%s] Value = [%u]",
+		CFG_ROAM_DISALLOW_DURATION_NAME,
+		pHddCtx->config->disallow_duration);
+	hdd_debug("Name = [%s] Value = [%u]",
+		CFG_ROAM_RSSI_CHANNEL_PENALIZATION_NAME,
+		pHddCtx->config->rssi_channel_penalization);
+	hdd_debug("Name = [%s] Value = [%u]",
+		CFG_ROAM_NUM_DISALLOWED_APS_NAME,
+		pHddCtx->config->num_disallowed_aps);
 }
 
 
@@ -7626,6 +7663,13 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
 
 	smeConfig->csrConfig.pkt_err_disconn_th =
 			pHddCtx->config->pkt_err_disconn_th;
+	smeConfig->csrConfig.disallow_duration =
+			pHddCtx->config->disallow_duration;
+	smeConfig->csrConfig.rssi_channel_penalization =
+			pHddCtx->config->rssi_channel_penalization;
+	smeConfig->csrConfig.num_disallowed_aps =
+			pHddCtx->config->num_disallowed_aps;
+
 	smeConfig->csrConfig.is_force_1x1 =
 			pHddCtx->config->is_force_1x1;
 	smeConfig->csrConfig.num_11b_tx_chains =

+ 75 - 35
core/hdd/src/wlan_hdd_cfg80211.c

@@ -112,6 +112,44 @@
 #include "wlan_utility.h"
 #include "wlan_reg_ucfg_api.h"
 
+/* define short names for get station info attributes */
+#ifndef LINK_INFO_STANDARD_NL80211_ATTR
+#define LINK_INFO_STANDARD_NL80211_ATTR \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR
+#endif
+#ifndef AP_INFO_STANDARD_NL80211_ATTR
+#define AP_INFO_STANDARD_NL80211_ATTR \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_STANDARD_NL80211_ATTR
+#endif
+#ifndef INFO_ROAM_COUNT
+#define INFO_ROAM_COUNT \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT
+#endif
+#ifndef INFO_AKM
+#define INFO_AKM \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM
+#endif
+#ifndef WLAN802_11_MODE
+#define WLAN802_11_MODE \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_802_11_MODE
+#endif
+#ifndef AP_INFO_HS20_INDICATION
+#define AP_INFO_HS20_INDICATION \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_HS20_INDICATION
+#endif
+#ifndef HT_OPERATION
+#define HT_OPERATION \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION
+#endif
+#ifndef VHT_OPERATION
+#define VHT_OPERATION \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION
+#endif
+#ifndef INFO_ASSOC_FAIL_REASON
+#define INFO_ASSOC_FAIL_REASON \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_FAIL_REASON
+#endif
+
 #define g_mode_rates_size (12)
 #define a_mode_rates_size (8)
 #define GET_IE_LEN_IN_BSS_DESC(lenInBss) (lenInBss + sizeof(lenInBss) - \
@@ -130,7 +168,7 @@
 #define IBSS_CFG_PROTECTION_ENABLE_MASK 0x8282
 
 #define HDD2GHZCHAN(freq, chan, flag)   {     \
-		.band =  NL80211_BAND_2GHZ, \
+		.band = HDD_NL80211_BAND_2GHZ, \
 		.center_freq = (freq), \
 		.hw_value = (chan), \
 		.flags = (flag), \
@@ -139,7 +177,7 @@
 }
 
 #define HDD5GHZCHAN(freq, chan, flag)   {     \
-		.band =  NL80211_BAND_5GHZ, \
+		.band =  HDD_NL80211_BAND_5GHZ, \
 		.center_freq = (freq), \
 		.hw_value = (chan), \
 		.flags = (flag), \
@@ -277,7 +315,7 @@ static struct ieee80211_rate a_mode_rates[] = {
 static struct ieee80211_supported_band wlan_hdd_band_2_4_ghz = {
 	.channels = NULL,
 	.n_channels = ARRAY_SIZE(hdd_channels_2_4_ghz),
-	.band = NL80211_BAND_2GHZ,
+	.band = HDD_NL80211_BAND_2GHZ,
 	.bitrates = g_mode_rates,
 	.n_bitrates = g_mode_rates_size,
 	.ht_cap.ht_supported = 1,
@@ -296,7 +334,7 @@ static struct ieee80211_supported_band wlan_hdd_band_2_4_ghz = {
 static struct ieee80211_supported_band wlan_hdd_band_5_ghz = {
 	.channels = NULL,
 	.n_channels = ARRAY_SIZE(hdd_channels_5_ghz),
-	.band = NL80211_BAND_5GHZ,
+	.band = HDD_NL80211_BAND_5GHZ,
 	.bitrates = a_mode_rates,
 	.n_bitrates = a_mode_rates_size,
 	.ht_cap.ht_supported = 1,
@@ -6656,11 +6694,11 @@ static int __wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy,
 		if (pcl[i] <= ARRAY_SIZE(hdd_channels_2_4_ghz))
 			freq_list[i] =
 				ieee80211_channel_to_frequency(pcl[i],
-							NL80211_BAND_2GHZ);
+							HDD_NL80211_BAND_2GHZ);
 		else
 			freq_list[i] =
 				ieee80211_channel_to_frequency(pcl[i],
-							NL80211_BAND_5GHZ);
+							HDD_NL80211_BAND_5GHZ);
 	}
 
 	/* send the freq_list back to supplicant */
@@ -9878,10 +9916,10 @@ static int wlan_hdd_cfg80211_sar_convert_band(u32 nl80211_value, u32 *wmi_value)
 	int ret = 0;
 
 	switch (nl80211_value) {
-	case NL80211_BAND_2GHZ:
+	case HDD_NL80211_BAND_2GHZ:
 		*wmi_value = WMI_SAR_2G_ID;
 		break;
-	case NL80211_BAND_5GHZ:
+	case HDD_NL80211_BAND_5GHZ:
 		*wmi_value = WMI_SAR_5G_ID;
 		break;
 	default:
@@ -11179,7 +11217,8 @@ int wlan_hdd_cfg80211_update_band(hdd_context_t *hdd_ctx, struct wiphy *wiphy,
 					hdd_ctx->hdd_pdev,
 					band->channels[j].hw_value);
 
-			if (NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) {
+			if (HDD_NL80211_BAND_2GHZ == i &&
+				eCSR_BAND_5G == eBand) {
 				/* 5G only */
 #ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
 				/* Enable Social channels for P2P */
@@ -11194,7 +11233,7 @@ int wlan_hdd_cfg80211_update_band(hdd_context_t *hdd_ctx, struct wiphy *wiphy,
 				band->channels[j].flags |=
 					IEEE80211_CHAN_DISABLED;
 				continue;
-			} else if (NL80211_BAND_5GHZ == i &&
+			} else if (HDD_NL80211_BAND_5GHZ == i &&
 					eCSR_BAND_24 == eBand) {
 				/* 2G only */
 				band->channels[j].flags |=
@@ -11337,14 +11376,14 @@ int wlan_hdd_cfg80211_init(struct device *dev,
 	 * wiphy flags don't get reset because of static memory.
 	 * It's better not to store channel in static memory.
 	 */
-	wiphy->bands[NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_ghz;
-	wiphy->bands[NL80211_BAND_2GHZ]->channels =
+	wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_ghz;
+	wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
 		qdf_mem_malloc(sizeof(hdd_channels_2_4_ghz));
-	if (wiphy->bands[NL80211_BAND_2GHZ]->channels == NULL) {
+	if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL) {
 		hdd_err("Not enough memory to allocate channels");
 		return -ENOMEM;
 	}
-	qdf_mem_copy(wiphy->bands[NL80211_BAND_2GHZ]->channels,
+	qdf_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
 			&hdd_channels_2_4_ghz[0],
 			sizeof(hdd_channels_2_4_ghz));
 	if ((hdd_is_5g_supported(pHddCtx)) &&
@@ -11352,17 +11391,17 @@ int wlan_hdd_cfg80211_init(struct device *dev,
 		 (eHDD_DOT11_MODE_11g != pCfg->dot11Mode) &&
 		 (eHDD_DOT11_MODE_11b_ONLY != pCfg->dot11Mode) &&
 		 (eHDD_DOT11_MODE_11g_ONLY != pCfg->dot11Mode))) {
-		wiphy->bands[NL80211_BAND_5GHZ] = &wlan_hdd_band_5_ghz;
-		wiphy->bands[NL80211_BAND_5GHZ]->channels =
+		wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_ghz;
+		wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
 			qdf_mem_malloc(sizeof(hdd_channels_5_ghz));
-		if (wiphy->bands[NL80211_BAND_5GHZ]->channels == NULL) {
+		if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL) {
 			hdd_err("Not enough memory to allocate channels");
 			qdf_mem_free(wiphy->
-				bands[NL80211_BAND_2GHZ]->channels);
-			wiphy->bands[NL80211_BAND_2GHZ]->channels = NULL;
+				bands[HDD_NL80211_BAND_2GHZ]->channels);
+			wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
 			return -ENOMEM;
 		}
-		qdf_mem_copy(wiphy->bands[NL80211_BAND_5GHZ]->channels,
+		qdf_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
 			&hdd_channels_5_ghz[0],
 			sizeof(hdd_channels_5_ghz));
 	}
@@ -11375,7 +11414,7 @@ int wlan_hdd_cfg80211_init(struct device *dev,
 		for (j = 0; j < wiphy->bands[i]->n_channels; j++) {
 			struct ieee80211_supported_band *band = wiphy->bands[i];
 
-			if (NL80211_BAND_2GHZ == i &&
+			if (HDD_NL80211_BAND_2GHZ == i &&
 				eCSR_BAND_5G == pCfg->nBandCapability) {
 				/* 5G only */
 #ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
@@ -11389,7 +11428,7 @@ int wlan_hdd_cfg80211_init(struct device *dev,
 				band->channels[j].flags |=
 					IEEE80211_CHAN_DISABLED;
 				continue;
-			} else if (NL80211_BAND_5GHZ == i &&
+			} else if (HDD_NL80211_BAND_5GHZ == i &&
 					eCSR_BAND_24 == pCfg->nBandCapability) {
 				/* 2G only */
 				band->channels[j].flags |=
@@ -11490,21 +11529,21 @@ static void wlan_hdd_update_band_cap(hdd_context_t *hdd_ctx)
 	ht_cap_info = (tSirMacHTCapabilityInfo *)&val16;
 
 	if (ht_cap_info->txSTBC == true) {
-		if (NULL != hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ])
-			hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap |=
+		if (NULL != hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ])
+			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]->ht_cap.cap |=
 						IEEE80211_HT_CAP_TX_STBC;
-		if (NULL != hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ])
-			hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ]->ht_cap.cap |=
+		if (NULL != hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ])
+			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->ht_cap.cap |=
 						IEEE80211_HT_CAP_TX_STBC;
 	}
 
 	if (!sme_is_feature_supported_by_fw(DOT11AC)) {
-		hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ]->
+		hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]->
 						vht_cap.vht_supported = 0;
-		hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ]->vht_cap.cap = 0;
-		hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ]->
+		hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]->vht_cap.cap = 0;
+		hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->
 						vht_cap.vht_supported = 0;
-		hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.cap = 0;
+		hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->vht_cap.cap = 0;
 	}
 }
 
@@ -13426,15 +13465,15 @@ struct cfg80211_bss *wlan_hdd_cfg80211_inform_bss_frame(hdd_adapter_t *pAdapter,
 	}
 
 	if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_ghz) &&
-	    (wiphy->bands[NL80211_BAND_2GHZ] != NULL)) {
+	    (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL)) {
 		freq =
 			ieee80211_channel_to_frequency(chan_no,
-						       NL80211_BAND_2GHZ);
+						       HDD_NL80211_BAND_2GHZ);
 	} else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_ghz))
-		   && (wiphy->bands[NL80211_BAND_5GHZ] != NULL)) {
+		   && (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL)) {
 		freq =
 			ieee80211_channel_to_frequency(chan_no,
-						       NL80211_BAND_5GHZ);
+						       HDD_NL80211_BAND_5GHZ);
 	} else {
 		hdd_err("Invalid channel: %d", chan_no);
 		qdf_mem_free(mgmt);
@@ -15453,7 +15492,8 @@ static int wlan_hdd_disconnect(hdd_adapter_t *pAdapter, u16 reason)
 	wlan_hdd_netif_queue_control(pAdapter,
 		WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH);
 	hdd_debug("Set HDD connState to eConnectionState_Disconnecting");
-	pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
+	hdd_conn_set_connection_state(pAdapter, eConnectionState_Disconnecting);
+
 	INIT_COMPLETION(pAdapter->disconnect_comp_var);
 
 	/* issue disconnect */

+ 3 - 0
core/hdd/src/wlan_hdd_driver_ops.c

@@ -230,6 +230,9 @@ int hdd_hif_open(struct device *dev, void *bdev, const struct hif_bus_id *bid,
 		goto err_hif_close;
 	}
 
+	if (hdd_ctx->config->prevent_link_down)
+		hif_vote_link_up(hif_ctx);
+
 	status = hif_enable(hif_ctx, dev, bdev, bid, bus_type,
 			    (reinit == true) ?  HIF_ENABLE_TYPE_REINIT :
 			    HIF_ENABLE_TYPE_PROBE);

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

@@ -186,7 +186,8 @@ static int wlan_hdd_qcmbr_command(hdd_adapter_t *adapter,
 	switch (pqcmbr_data->cmd) {
 	case ATH_XIOCTL_UNIFIED_UTF_CMD: {
 		pqcmbr_data->copy_to_user = 0;
-		if (pqcmbr_data->length) {
+		if (pqcmbr_data->length &&
+			pqcmbr_data->length <= sizeof(pqcmbr_data->buf)) {
 			if (wlan_hdd_ftm_testmode_cmd(pqcmbr_data->buf,
 						      pqcmbr_data->
 						      length)

+ 13 - 12
core/hdd/src/wlan_hdd_main.c

@@ -1061,7 +1061,7 @@ static void hdd_update_tgt_vht_cap(hdd_context_t *hdd_ctx,
 	struct hdd_config *pconfig = hdd_ctx->config;
 	struct wiphy *wiphy = hdd_ctx->wiphy;
 	struct ieee80211_supported_band *band_5g =
-		wiphy->bands[NL80211_BAND_5GHZ];
+		wiphy->bands[HDD_NL80211_BAND_5GHZ];
 	uint32_t temp = 0;
 	uint32_t ch_width = eHT_CHANNEL_WIDTH_80MHZ;
 
@@ -3196,10 +3196,7 @@ QDF_STATUS hdd_init_station_mode(hdd_adapter_t *adapter)
 		hdd_err("failed to register wireless extensions: %d", status);
 		goto error_register_wext;
 	}
-
-	/* Set the Connection State to Not Connected */
-	hdd_debug("Set HDD connState to eConnectionState_NotConnected");
-	pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
+	hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
 
 	qdf_mem_set(pHddStaCtx->conn_info.staId,
 		sizeof(pHddStaCtx->conn_info.staId), HDD_WLAN_INVALID_STA_ID);
@@ -4316,14 +4313,18 @@ QDF_STATUS hdd_reset_all_adapters(hdd_context_t *hdd_ctx)
 			clear_bit(WMM_INIT_DONE, &adapter->event_flags);
 		}
 
-		/*
-		 * If adapter is SAP, set session ID to invalid since SAP
-		 * session will be cleanup during SSR.
-		 */
-		if (adapter->device_mode == QDF_SAP_MODE)
+		if (adapter->device_mode == QDF_SAP_MODE) {
+			/*
+			 * If adapter is SAP, set session ID to invalid
+			 * since SAP session will be cleanup during SSR.
+			 */
 			wlansap_set_invalid_session(
 				WLAN_HDD_GET_SAP_CTX_PTR(adapter));
 
+			wlansap_cleanup_cac_timer(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter));
+		}
+
 		/* Delete peers if any for STA and P2P client modes */
 		if (adapter->device_mode == QDF_STA_MODE ||
 		    adapter->device_mode == QDF_P2P_CLIENT_MODE) {
@@ -4588,10 +4589,10 @@ void hdd_connect_result(struct net_device *dev, const u8 *bssid,
 
 		if (chan_no <= 14)
 			freq = ieee80211_channel_to_frequency(chan_no,
-			NL80211_BAND_2GHZ);
+				HDD_NL80211_BAND_2GHZ);
 		else
 			freq = ieee80211_channel_to_frequency(chan_no,
-			NL80211_BAND_5GHZ);
+				HDD_NL80211_BAND_5GHZ);
 
 		chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
 		bss = hdd_cfg80211_get_bss(padapter->wdev.wiphy, chan, bssid,

+ 2 - 3
core/hdd/src/wlan_hdd_nan_datapath.c

@@ -1251,8 +1251,8 @@ static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter,
 	hdd_ctx->sta_to_adapter[new_peer_ind->sta_id] = adapter;
 	/* perform following steps for first new peer ind */
 	if (ndp_ctx->active_ndp_peers == 1) {
-		hdd_info("Set ctx connection state to connected");
-		sta_ctx->conn_info.connState = eConnectionState_NdiConnected;
+		hdd_conn_set_connection_state(adapter,
+				eConnectionState_NdiConnected);
 		hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
 		wlan_hdd_netif_queue_control(adapter,
 				WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
@@ -1281,7 +1281,6 @@ static void hdd_ndp_peer_departed_ind_handler(hdd_adapter_t *adapter,
 
 	if (--ndp_ctx->active_ndp_peers == 0) {
 		hdd_info("No more ndp peers.");
-		sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected;
 		hdd_conn_set_connection_state(adapter,
 			eConnectionState_NdiDisconnected);
 		hdd_info("Stop netif tx queues.");

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

@@ -259,9 +259,9 @@ static void hdd_regulatory_wiphy_init(hdd_context_t *hdd_ctx,
 	 * disable 2.4 Ghz channels that dont have 20 mhz bw
 	 */
 	for (chan_num = 0;
-	     chan_num < wiphy->bands[NL80211_BAND_2GHZ]->n_channels;
+	     chan_num < wiphy->bands[HDD_NL80211_BAND_2GHZ]->n_channels;
 	     chan_num++) {
-		chan = &(wiphy->bands[NL80211_BAND_2GHZ]->channels[chan_num]);
+		chan = &(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels[chan_num]);
 		if (chan->flags & IEEE80211_CHAN_NO_20MHZ)
 			chan->flags |= IEEE80211_CHAN_DISABLED;
 	}

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

@@ -1855,16 +1855,18 @@ static int
 hdd_populate_wifi_signal_info(struct sir_wifi_peer_signal_stats *peer_signal,
 			      struct sk_buff *skb)
 {
-	uint32_t i;
+	uint32_t i, chain_count;
 	struct nlattr *chains, *att;
 
 	/* There might be no signal info for a peer */
 	if (!peer_signal)
 		return 0;
 
+	chain_count = peer_signal->num_chain < WIFI_MAX_CHAINS ?
+		      peer_signal->num_chain : WIFI_MAX_CHAINS;
 	if (nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ANT_NUM,
-			WIFI_MAX_CHAINS)) {
+			chain_count)) {
 		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
 		return -EINVAL;
 	}
@@ -1876,7 +1878,7 @@ hdd_populate_wifi_signal_info(struct sir_wifi_peer_signal_stats *peer_signal,
 		return -EINVAL;
 	}
 
-	for (i = 0; i < WIFI_MAX_CHAINS; i++) {
+	for (i = 0; i < chain_count; i++) {
 		chains = nla_nest_start(skb, i);
 
 		if (!chains) {
@@ -1884,12 +1886,23 @@ hdd_populate_wifi_signal_info(struct sir_wifi_peer_signal_stats *peer_signal,
 			return -EINVAL;
 		}
 
+		hdd_debug("SNR=%d, NF=%d, Rx=%d, Tx=%d",
+			  peer_signal->per_ant_snr[i],
+			  peer_signal->nf[i],
+			  peer_signal->per_ant_rx_mpdus[i],
+			  peer_signal->per_ant_tx_mpdus[i]);
 		if (nla_put_u32(skb,
 				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR,
 				peer_signal->per_ant_snr[i]) ||
 		    nla_put_u32(skb,
 				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF,
-				peer_signal->nf[i])) {
+				peer_signal->nf[i]) ||
+		    nla_put_u32(skb,
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU,
+				peer_signal->per_ant_rx_mpdus[i]) ||
+		    nla_put_u32(skb,
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU,
+				peer_signal->per_ant_tx_mpdus[i])) {
 			hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
 			return -EINVAL;
 		}

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

@@ -7569,10 +7569,10 @@ int wlan_hdd_update_phymode(struct net_device *net, tHalHandle hal,
 			return -EIO;
 		}
 		if (phddctx->config->nChannelBondingMode5GHz)
-			phddctx->wiphy->bands[NL80211_BAND_5GHZ]->ht_cap.cap
+			phddctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->ht_cap.cap
 				|= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 		else
-			phddctx->wiphy->bands[NL80211_BAND_5GHZ]->ht_cap.cap
+			phddctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->ht_cap.cap
 				&= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 
 		hdd_debug("New_Phymode= %d ch_bonding=%d band=%d VHT_ch_width=%u",

+ 3 - 3
core/mac/inc/qwlan_version.h

@@ -41,9 +41,9 @@
 #define QWLAN_VERSION_MAJOR            5
 #define QWLAN_VERSION_MINOR            2
 #define QWLAN_VERSION_PATCH            0
-#define QWLAN_VERSION_EXTRA            "Z"
-#define QWLAN_VERSION_BUILD            34
+#define QWLAN_VERSION_EXTRA            "I"
+#define QWLAN_VERSION_BUILD            35
 
-#define QWLAN_VERSIONSTR               "5.2.0.34Z"
+#define QWLAN_VERSIONSTR               "5.2.0.35I"
 
 #endif /* QWLAN_VERSION_H */

+ 39 - 0
core/mac/inc/sir_api.h

@@ -1287,6 +1287,12 @@ typedef struct sSirSmeChanInfo {
 	enum phy_ch_width ch_width;
 } tSirSmeChanInfo, *tpSirSmeChanInfo;
 
+enum sir_sme_phy_mode {
+	SIR_SME_PHY_MODE_LEGACY = 0,
+	SIR_SME_PHY_MODE_HT = 1,
+	SIR_SME_PHY_MODE_VHT = 2
+};
+
 /* / Definition for Association indication from peer */
 /* / MAC ---> */
 typedef struct sSirSmeAssocInd {
@@ -1324,6 +1330,17 @@ typedef struct sSirSmeAssocInd {
 	/* Timing measurement capability */
 	uint8_t timingMeasCap;
 	tSirSmeChanInfo chan_info;
+	bool ampdu;
+	bool sgi_enable;
+	bool tx_stbc;
+	bool rx_stbc;
+	tSirMacHTChannelWidth ch_width;
+	enum sir_sme_phy_mode mode;
+	uint8_t max_supp_idx;
+	uint8_t max_ext_idx;
+	uint8_t max_mcs_idx;
+	uint8_t rx_mcs_map;
+	uint8_t tx_mcs_map;
 } tSirSmeAssocInd, *tpSirSmeAssocInd;
 
 /* / Definition for Association confirm */
@@ -2983,6 +3000,20 @@ struct pmkid_mode_bits {
 	uint32_t unused:30;
 };
 
+/**
+ * struct lca_disallow_config_params - LCA[Last Connected AP]
+ *                                     disallow config params
+ * @disallow_duration: LCA AP disallowed duration
+ * @rssi_channel_penalization: RSSI channel Penalization
+ * @num_disallowed_aps: Maximum number of AP's in LCA list
+ *
+ */
+struct lca_disallow_config_params{
+    uint32_t disallow_duration;
+    uint32_t rssi_channel_penalization;
+    uint32_t num_disallowed_aps;
+};
+
 typedef struct sSirRoamOffloadScanReq {
 	uint16_t message_type;
 	uint16_t length;
@@ -3040,6 +3071,7 @@ typedef struct sSirRoamOffloadScanReq {
 	int8_t early_stop_scan_max_threshold;
 	enum wmi_dwelltime_adaptive_mode roamscan_adaptive_dwell_mode;
 	tSirAddie assoc_ie;
+	struct lca_disallow_config_params lca_config_params;
 } tSirRoamOffloadScanReq, *tpSirRoamOffloadScanReq;
 
 typedef struct sSirRoamOffloadScanRsp {
@@ -5225,6 +5257,9 @@ struct sir_wifi_chan_cca_stats {
  * @peer_id: peer ID
  * @per_ant_snr: per antenna SNR
  * @nf: peer background noise
+ * @per_ant_rx_mpdus: MPDUs received per antenna
+ * @per_ant_tx_mpdus: MPDUs transferred per antenna
+ * @num_chain: valid chain count
  */
 struct sir_wifi_peer_signal_stats {
 	uint32_t vdev_id;
@@ -5235,6 +5270,10 @@ struct sir_wifi_peer_signal_stats {
 
 	/* Background noise */
 	int32_t nf[WIFI_MAX_CHAINS];
+
+	int32_t per_ant_rx_mpdus[WIFI_MAX_CHAINS];
+	int32_t per_ant_tx_mpdus[WIFI_MAX_CHAINS];
+	int32_t num_chain;
 };
 
 #define WIFI_VDEV_NUM           4

+ 5 - 4
core/mac/src/dph/dph_hash_table.c

@@ -240,7 +240,7 @@ tpDphHashNode dph_init_sta_state(tpAniSirGlobal pMac, tSirMacAddr staAddr,
 {
 	uint32_t val;
 
-	tpDphHashNode pStaDs;
+	tpDphHashNode pStaDs, pnext;
 	uint16_t staIdx = STA_INVALID_IDX;
 
 	if (assocId >= pDphHashTable->size) {
@@ -250,10 +250,11 @@ tpDphHashNode dph_init_sta_state(tpAniSirGlobal pMac, tSirMacAddr staAddr,
 
 	pStaDs = get_node(pMac, (uint8_t) assocId, pDphHashTable);
 	staIdx = pStaDs->staIndex;
+	pnext = pStaDs->next;
 
-	/* Clear the STA node except for the next pointer (last 4 bytes) */
-	qdf_mem_set((uint8_t *) pStaDs,
-		    sizeof(tDphHashNode) - sizeof(tpDphHashNode), 0);
+	/* Clear the STA node except for the next pointer */
+	qdf_mem_set((uint8_t *)pStaDs, sizeof(tDphHashNode), 0);
+	pStaDs->next = pnext;
 
 	/* Initialize the assocId */
 	pStaDs->assocId = assocId;

+ 1 - 1
core/mac/src/pe/include/lim_session.h

@@ -55,7 +55,7 @@ typedef struct tagComebackTimerInfo {
 	tpAniSirGlobal pMac;
 	uint8_t sessionID;
 	tLimMlmStates limPrevMlmState;  /* Previous MLM State */
-	tLimSmeStates limMlmState;      /* MLM State */
+	tLimMlmStates limMlmState;      /* MLM State */
 } tComebackTimerInfo;
 #endif /* WLAN_FEATURE_11W */
 /*--------------------------------------------------------------------------

+ 1 - 1
core/mac/src/pe/lim/lim_link_monitoring_algo.c

@@ -231,7 +231,7 @@ void lim_delete_sta_context(tpAniSirGlobal mac_ctx,
 				pe_err("Do not process in limMlmState %s(%x) limSmeState %s(%x)",
 				  lim_mlm_state_str(session_entry->limMlmState),
 				  session_entry->limMlmState,
-				  lim_mlm_state_str(session_entry->limSmeState),
+				  lim_sme_state_str(session_entry->limSmeState),
 				  session_entry->limSmeState);
 				qdf_mem_free(msg);
 				return;

+ 96 - 0
core/mac/src/pe/lim/lim_process_assoc_req_frame.c

@@ -2110,6 +2110,50 @@ static void lim_fill_assoc_ind_vht_info(tpAniSirGlobal mac_ctx,
 	return;
 }
 
+static uint8_t lim_get_max_rate_idx(tSirMacRateSet *rateset)
+{
+	uint8_t maxidx;
+	int i;
+
+	maxidx = rateset->rate[0] & 0x7f;
+	for (i = 1; i < rateset->numRates; i++) {
+		if ((rateset->rate[i] & 0x7f) > maxidx)
+			maxidx = rateset->rate[i] & 0x7f;
+	}
+
+	return maxidx;
+}
+
+static void fill_mlm_assoc_ind_vht(tpSirAssocReq assocreq,
+		tpDphHashNode stads,
+		tpLimMlmAssocInd assocind)
+{
+	if (stads->mlmStaContext.vhtCapability) {
+		/* ampdu */
+		assocind->ampdu = true;
+
+		/* sgi */
+		if (assocreq->VHTCaps.shortGI80MHz ||
+		    assocreq->VHTCaps.shortGI160and80plus80MHz)
+			assocind->sgi_enable = true;
+
+		/* stbc */
+		assocind->tx_stbc = assocreq->VHTCaps.txSTBC;
+		assocind->rx_stbc = assocreq->VHTCaps.rxSTBC;
+
+		/* ch width */
+		assocind->ch_width = stads->vhtSupportedChannelWidthSet ?
+			eHT_CHANNEL_WIDTH_80MHZ :
+			stads->htSupportedChannelWidthSet ?
+			eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ;
+
+		/* mode */
+		assocind->mode = SIR_SME_PHY_MODE_VHT;
+		assocind->rx_mcs_map = assocreq->VHTCaps.rxMCSMap & 0xff;
+		assocind->tx_mcs_map = assocreq->VHTCaps.txMCSMap & 0xff;
+	}
+}
+
 /**
  * lim_send_mlm_assoc_ind() - Sends assoc indication to SME
  * @mac_ctx: Global Mac context
@@ -2130,6 +2174,7 @@ void lim_send_mlm_assoc_ind(tpAniSirGlobal mac_ctx,
 	uint32_t phy_mode;
 	uint8_t sub_type;
 	uint8_t *wpsie = NULL;
+	uint8_t maxidx, i;
 	uint32_t tmp;
 
 	/* Get a copy of the already parsed Assoc Request */
@@ -2295,6 +2340,57 @@ void lim_send_mlm_assoc_ind(tpAniSirGlobal mac_ctx,
 		assoc_ind->chan_info.nss = sta_ds->nss;
 		assoc_ind->chan_info.rate_flags =
 			lim_get_max_rate_flags(mac_ctx, sta_ds);
+		assoc_ind->ampdu = false;
+		assoc_ind->sgi_enable = false;
+		assoc_ind->tx_stbc = false;
+		assoc_ind->rx_stbc = false;
+		assoc_ind->ch_width = eHT_CHANNEL_WIDTH_20MHZ;
+		assoc_ind->mode = SIR_SME_PHY_MODE_LEGACY;
+		assoc_ind->max_supp_idx = 0xff;
+		assoc_ind->max_ext_idx = 0xff;
+		assoc_ind->max_mcs_idx = 0xff;
+		assoc_ind->rx_mcs_map = 0xff;
+		assoc_ind->tx_mcs_map = 0xff;
+
+		if (assoc_req->supportedRates.numRates)
+			assoc_ind->max_supp_idx =
+				lim_get_max_rate_idx(
+					&assoc_req->supportedRates);
+		if (assoc_req->extendedRates.numRates)
+			assoc_ind->max_ext_idx =
+				lim_get_max_rate_idx(
+					&assoc_req->extendedRates);
+
+		if (sta_ds->mlmStaContext.htCapability) {
+			/* ampdu */
+			assoc_ind->ampdu = true;
+
+			/* sgi */
+			if (sta_ds->htShortGI20Mhz || sta_ds->htShortGI40Mhz)
+				assoc_ind->sgi_enable = true;
+
+			/* stbc */
+			assoc_ind->tx_stbc = assoc_req->HTCaps.txSTBC;
+			assoc_ind->rx_stbc = assoc_req->HTCaps.rxSTBC;
+
+			/* ch width */
+			assoc_ind->ch_width =
+				sta_ds->htSupportedChannelWidthSet ?
+				eHT_CHANNEL_WIDTH_40MHZ :
+				eHT_CHANNEL_WIDTH_20MHZ;
+
+			/* mode */
+			assoc_ind->mode = SIR_SME_PHY_MODE_HT;
+			maxidx = 0;
+			for (i = 0; i < 8; i++) {
+				if (assoc_req->HTCaps.supportedMCSSet[0] &
+					(1 << i))
+					maxidx = i;
+			}
+			assoc_ind->max_mcs_idx = maxidx;
+		}
+		fill_mlm_assoc_ind_vht(assoc_req, sta_ds, assoc_ind);
+
 		/* updates VHT information in assoc indication */
 		lim_fill_assoc_ind_vht_info(mac_ctx, session_entry, assoc_req,
 			assoc_ind);

+ 1 - 1
core/mac/src/pe/lim/lim_process_mlm_req_messages.c

@@ -489,7 +489,7 @@ lim_mlm_add_bss(tpAniSirGlobal mac_ctx,
 	if (NULL == addbss_param) {
 		pe_err("Unable to allocate memory during ADD_BSS");
 		/* Respond to SME with LIM_MLM_START_CNF */
-		return eSIR_MEM_ALLOC_FAILED;
+		return eSIR_SME_RESOURCES_UNAVAILABLE;
 	}
 
 	/* Fill in tAddBssParams members */

+ 11 - 0
core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c

@@ -772,6 +772,17 @@ lim_fill_assoc_ind_params(tpAniSirGlobal mac_ctx,
 		sizeof(tSirSmeChanInfo));
 	/* Fill in WmmInfo */
 	sme_assoc_ind->wmmEnabledSta = assoc_ind->WmmStaInfoPresent;
+	sme_assoc_ind->ampdu = assoc_ind->ampdu;
+	sme_assoc_ind->sgi_enable = assoc_ind->sgi_enable;
+	sme_assoc_ind->tx_stbc = assoc_ind->tx_stbc;
+	sme_assoc_ind->rx_stbc = assoc_ind->rx_stbc;
+	sme_assoc_ind->ch_width = assoc_ind->ch_width;
+	sme_assoc_ind->mode = assoc_ind->mode;
+	sme_assoc_ind->max_supp_idx = assoc_ind->max_supp_idx;
+	sme_assoc_ind->max_ext_idx = assoc_ind->max_ext_idx;
+	sme_assoc_ind->max_mcs_idx = assoc_ind->max_mcs_idx;
+	sme_assoc_ind->rx_mcs_map = assoc_ind->rx_mcs_map;
+	sme_assoc_ind->tx_mcs_map = assoc_ind->tx_mcs_map;
 }
 
 /**

+ 15 - 28
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -3569,10 +3569,7 @@ static void __lim_process_sme_addts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
 
 	if (!LIM_IS_STA_ROLE(psessionEntry)) {
 		pe_err("AddTs received on AP - ignoring");
-		lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
-				       psessionEntry, pSirAddts->req.tspec,
-				       smesessionId, smetransactionId);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	pStaDs =
@@ -3581,19 +3578,13 @@ static void __lim_process_sme_addts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
 
 	if (pStaDs == NULL) {
 		pe_err("Cannot find AP context for addts req");
-		lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
-				       psessionEntry, pSirAddts->req.tspec,
-				       smesessionId, smetransactionId);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	if ((!pStaDs->valid) || (pStaDs->mlmStaContext.mlmState !=
 	    eLIM_MLM_LINK_ESTABLISHED_STATE)) {
 		pe_err("AddTs received in invalid MLM state");
-		lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
-				       psessionEntry, pSirAddts->req.tspec,
-				       smesessionId, smetransactionId);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	pSirAddts->req.wsmTspecPresent = 0;
@@ -3610,20 +3601,14 @@ static void __lim_process_sme_addts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
 		pSirAddts->req.lleTspecPresent = 1;
 	else {
 		pe_warn("ADDTS_REQ ignore - qos is disabled");
-		lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
-				       psessionEntry, pSirAddts->req.tspec,
-				       smesessionId, smetransactionId);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
 	    (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
 		pe_err("AddTs received in invalid LIMsme state (%d)",
 			psessionEntry->limSmeState);
-		lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
-				       psessionEntry, pSirAddts->req.tspec,
-				       smesessionId, smetransactionId);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	if (pMac->lim.gLimAddtsSent) {
@@ -3632,10 +3617,7 @@ static void __lim_process_sme_addts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
 			pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.tsid,
 			pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.
 			userPrio);
-		lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
-				       psessionEntry, pSirAddts->req.tspec,
-				       smesessionId, smetransactionId);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	sir_copy_mac_addr(peerMac, psessionEntry->bssId);
@@ -3656,21 +3638,21 @@ static void __lim_process_sme_addts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
 		 eSIR_SUCCESS) {
 		pe_err("Unable to get Cfg param %d (Addts Rsp Timeout)",
 			WNI_CFG_ADDTS_RSP_TIMEOUT);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	timeout = SYS_MS_TO_TICKS(timeout);
 	if (tx_timer_change(&pMac->lim.limTimers.gLimAddtsRspTimer, timeout, 0)
 	    != TX_SUCCESS) {
 		pe_err("AddtsRsp timer change failed!");
-		return;
+		goto send_failure_addts_rsp;
 	}
 	pMac->lim.gLimAddtsRspTimerCount++;
 	if (tx_timer_change_context(&pMac->lim.limTimers.gLimAddtsRspTimer,
 				    pMac->lim.gLimAddtsRspTimerCount) !=
 	    TX_SUCCESS) {
 		pe_err("AddtsRsp timer change failed!");
-		return;
+		goto send_failure_addts_rsp;
 	}
 	MTRACE(mac_trace
 		       (pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId,
@@ -3681,9 +3663,14 @@ static void __lim_process_sme_addts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
 	if (tx_timer_activate(&pMac->lim.limTimers.gLimAddtsRspTimer) !=
 	    TX_SUCCESS) {
 		pe_err("AddtsRsp timer activation failed!");
-		return;
+		goto send_failure_addts_rsp;
 	}
 	return;
+
+send_failure_addts_rsp:
+	lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
+			       psessionEntry, pSirAddts->req.tspec,
+			       smesessionId, smetransactionId);
 }
 
 static void __lim_process_sme_delts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)

+ 0 - 4
core/mac/src/pe/lim/lim_process_tdls.c

@@ -2416,8 +2416,6 @@ static void lim_tdls_update_hash_node_info(tpAniSirGlobal pMac,
 	tDot11fIEVHTCaps *pVhtCaps_txbf = NULL;
 	tDot11fIEVHTCaps vhtCap;
 	uint8_t cbMode;
-	tpDphHashNode pSessStaDs = NULL;
-	uint16_t aid;
 
 	if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_ADD) {
 		populate_dot11f_ht_caps(pMac, psessionEntry, &htCap);
@@ -2516,8 +2514,6 @@ static void lim_tdls_update_hash_node_info(tpAniSirGlobal pMac,
 		else
 			pStaDs->htSecondaryChannelOffset = cbMode;
 	}
-	pSessStaDs = dph_lookup_hash_entry(pMac, psessionEntry->bssId, &aid,
-					   &psessionEntry->dph.dphHashTable);
 	/* Lets enable QOS parameter */
 	pStaDs->qosMode = (pTdlsAddStaReq->capability & CAPABILITIES_QOS_OFFSET)
 				|| pTdlsAddStaReq->htcap_present;

+ 11 - 0
core/mac/src/pe/lim/lim_types.h

@@ -266,6 +266,17 @@ typedef struct sLimMlmAssocInd {
 	uint32_t assocReqLength;
 	uint8_t *assocReqPtr;
 	tSirSmeChanInfo chan_info;
+	bool ampdu;
+	bool sgi_enable;
+	bool tx_stbc;
+	bool rx_stbc;
+	tSirMacHTChannelWidth ch_width;
+	enum sir_sme_phy_mode mode;
+	uint8_t max_supp_idx;
+	uint8_t max_ext_idx;
+	uint8_t max_mcs_idx;
+	uint8_t rx_mcs_map;
+	uint8_t tx_mcs_map;
 } tLimMlmAssocInd, *tpLimMlmAssocInd;
 
 typedef struct sLimMlmReassocReq {

+ 2 - 0
core/mac/src/sys/legacy/src/utils/src/mac_trace.c

@@ -414,6 +414,8 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg)
 		CASE_RETURN_STRING(eWNI_SME_DEFAULT_SCAN_IE);
 		CASE_RETURN_STRING(eWNI_SME_ROAM_SCAN_OFFLOAD_REQ);
 		CASE_RETURN_STRING(eWNI_SME_LOST_LINK_INFO_IND);
+		CASE_RETURN_STRING(eWNI_SME_GET_PEER_INFO_IND);
+		CASE_RETURN_STRING(eWNI_SME_GET_PEER_INFO_EXT_IND);
 		CASE_RETURN_STRING(eWNI_SME_RSO_CMD_STATUS_IND);
 		CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END);
 	default:

+ 23 - 0
core/sap/inc/sap_api.h

@@ -287,6 +287,17 @@ typedef struct sap_StationAssocReassocCompleteEvent_s {
 	uint8_t *assocRespPtr;
 	uint8_t timingMeasCap;
 	tSirSmeChanInfo chan_info;
+	bool ampdu;
+	bool sgi_enable;
+	bool tx_stbc;
+	bool rx_stbc;
+	tSirMacHTChannelWidth ch_width;
+	enum sir_sme_phy_mode mode;
+	uint8_t max_supp_idx;
+	uint8_t max_ext_idx;
+	uint8_t max_mcs_idx;
+	uint8_t rx_mcs_map;
+	uint8_t tx_mcs_map;
 } tSap_StationAssocReassocCompleteEvent;
 
 typedef struct sap_StationDisassocCompleteEvent_s {
@@ -1055,6 +1066,18 @@ QDF_STATUS wlansap_set_invalid_session(void *cds_ctx);
  * Return: None
  */
 void sap_dfs_set_current_channel(void *sap_ctx);
+
+/**
+ * wlansap_cleanup_cac_timer() - Force cleanup DFS CAC timer
+ * @sap_ctx: sap context
+ *
+ * Force cleanup DFS CAC timer when reset all adapters. It will not
+ * check concurrency SAP since just called when reset all adapters.
+ *
+ * Return: None
+ */
+void wlansap_cleanup_cac_timer(void *sap_ctx);
+
 #ifdef __cplusplus
 }
 #endif

+ 11 - 0
core/sap/src/sap_fsm.c

@@ -2451,6 +2451,17 @@ QDF_STATUS sap_signal_hdd_event(ptSapContext sap_ctx,
 		reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta;
 		reassoc_complete->status = (eSapStatus) context;
 		reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap;
+		reassoc_complete->ampdu = csr_roaminfo->ampdu;
+		reassoc_complete->sgi_enable = csr_roaminfo->sgi_enable;
+		reassoc_complete->tx_stbc = csr_roaminfo->tx_stbc;
+		reassoc_complete->rx_stbc = csr_roaminfo->rx_stbc;
+		reassoc_complete->ch_width = csr_roaminfo->ch_width;
+		reassoc_complete->mode = csr_roaminfo->mode;
+		reassoc_complete->max_supp_idx = csr_roaminfo->max_supp_idx;
+		reassoc_complete->max_ext_idx = csr_roaminfo->max_ext_idx;
+		reassoc_complete->max_mcs_idx = csr_roaminfo->max_mcs_idx;
+		reassoc_complete->rx_mcs_map = csr_roaminfo->rx_mcs_map;
+		reassoc_complete->tx_mcs_map = csr_roaminfo->tx_mcs_map;
 		break;
 
 	case eSAP_STA_DISASSOC_EVENT:

+ 23 - 0
core/sap/src/sap_module.c

@@ -3745,3 +3745,26 @@ wlansap_set_invalid_session(void *cds_ctx)
 
 	return QDF_STATUS_SUCCESS;
 }
+
+void wlansap_cleanup_cac_timer(void *sap_ctx)
+{
+	tHalHandle hal;
+	ptSapContext psap_ctx;
+	tpAniSirGlobal pmac;
+
+	if (!sap_ctx)
+		return;
+
+	psap_ctx = CDS_GET_SAP_CB(sap_ctx);
+	hal = CDS_GET_HAL_CB(psap_ctx->p_cds_gctx);
+	pmac = PMAC_STRUCT(hal);
+	if (pmac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+		qdf_mc_timer_stop(&pmac->sap.SapDfsInfo.
+				  sap_dfs_cac_timer);
+		pmac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
+		qdf_mc_timer_destroy(
+			&pmac->sap.SapDfsInfo.sap_dfs_cac_timer);
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("sapdfs, force cleanup running dfs cac timer"));
+	}
+}

+ 25 - 0
core/sme/inc/csr_api.h

@@ -1319,6 +1319,9 @@ typedef struct tagCsrConfigParam {
 	bool is_force_1x1;
 	uint16_t num_11b_tx_chains;
 	uint16_t num_11ag_tx_chains;
+	uint32_t disallow_duration;
+	uint32_t rssi_channel_penalization;
+	uint32_t num_disallowed_aps;
 } tCsrConfigParam;
 
 /* Tush */
@@ -1447,6 +1450,17 @@ typedef struct tagCsrRoamInfo {
 	tDot11fIEVHTOperation vht_operation;
 	tDot11fIEHTInfo ht_operation;
 	bool reassoc;
+	bool ampdu;
+	bool sgi_enable;
+	bool tx_stbc;
+	bool rx_stbc;
+	tSirMacHTChannelWidth ch_width;
+	enum sir_sme_phy_mode mode;
+	uint8_t max_supp_idx;
+	uint8_t max_ext_idx;
+	uint8_t max_mcs_idx;
+	uint8_t rx_mcs_map;
+	uint8_t tx_mcs_map;
 } tCsrRoamInfo;
 
 typedef struct tagCsrFreqScanInfo {
@@ -1474,6 +1488,17 @@ typedef struct sSirSmeAssocIndToUpperLayerCnf {
 	uint8_t timingMeasCap;
 	tSirSmeChanInfo chan_info;
 	uint8_t target_channel;
+	bool ampdu;
+	bool sgi_enable;
+	bool tx_stbc;
+	tSirMacHTChannelWidth ch_width;
+	enum sir_sme_phy_mode mode;
+	bool rx_stbc;
+	uint8_t max_supp_idx;
+	uint8_t max_ext_idx;
+	uint8_t max_mcs_idx;
+	uint8_t rx_mcs_map;
+	uint8_t tx_mcs_map;
 } tSirSmeAssocIndToUpperLayerCnf, *tpSirSmeAssocIndToUpperLayerCnf;
 
 typedef struct tagCsrSummaryStatsInfo {

+ 3 - 0
core/sme/inc/csr_internal.h

@@ -624,6 +624,9 @@ typedef struct tagCsrConfig {
 	bool is_force_1x1;
 	uint16_t num_11b_tx_chains;
 	uint16_t num_11ag_tx_chains;
+	uint32_t disallow_duration;
+	uint32_t rssi_channel_penalization;
+	uint32_t num_disallowed_aps;
 } tCsrConfig;
 
 typedef struct tagCsrChannelPowerInfo {

+ 33 - 0
core/sme/inc/sme_api.h

@@ -1627,4 +1627,37 @@ int sme_cli_set_command(int vdev_id, int param_id, int sval, int vpdev);
 QDF_STATUS sme_set_bt_activity_info_cb(tHalHandle hal,
 				void (*cb)(void *, uint32_t profile_info));
 
+/**
+ * sme_get_peer_info() - sme api to get peer info
+ * @hal: hal handle for getting global mac struct
+ * @req: peer info request struct send to wma
+ * @context: context of callback function
+ * @callbackfn: hdd callback function when receive response
+ *
+ * This function will send WMA_GET_PEER_INFO to WMA
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+QDF_STATUS sme_get_peer_info(tHalHandle hal,
+		struct sir_peer_info_req req,
+		void *context,
+		void (*callbackfn)(struct sir_peer_info_resp *param,
+			void *pcontext));
+
+/**
+ * sme_get_peer_info_ext() - sme api to get peer ext info
+ * @hal: hal handle for getting global mac struct
+ * @req: peer ext info request struct send to wma
+ * @context: context of callback function
+ * @callbackfn: hdd callback function when receive response
+ *
+ * This function will send WMA_GET_PEER_INFO_EXT to WMA
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+QDF_STATUS sme_get_peer_info_ext(tHalHandle hal,
+		struct sir_peer_info_ext_req *req,
+		void *context,
+		void (*callbackfn)(struct sir_peer_info_ext_resp *param,
+			void *pcontext));
 #endif /* #if !defined( __SME_API_H ) */

+ 8 - 0
core/sme/inc/sme_internal.h

@@ -197,6 +197,14 @@ typedef struct tagSmeStruct {
 	void (*pLinkSpeedIndCb)(tSirLinkSpeedInfo *indParam,
 			void *pDevContext);
 	void *pLinkSpeedCbContext;
+	/* get peer info callback */
+	void (*pget_peer_info_ind_cb)(struct sir_peer_info_resp *param,
+		void *pcontext);
+	void *pget_peer_info_cb_context;
+	/* get extended peer info callback */
+	void (*pget_peer_info_ext_ind_cb)(struct sir_peer_info_ext_resp *param,
+		void *pcontext);
+	void *pget_peer_info_ext_cb_context;
 #ifdef FEATURE_WLAN_EXTSCAN
 	void (*pExtScanIndCb)(void *, const uint16_t, void *);
 #endif /* FEATURE_WLAN_EXTSCAN */

+ 0 - 11
core/sme/inc/sme_qos_internal.h

@@ -123,17 +123,6 @@ QDF_STATUS sme_qos_msg_processor(tpAniSirGlobal pMac, uint16_t msg_type,
   ------------------------------------------------------------------------*/
 QDF_STATUS sme_qos_validate_params(tpAniSirGlobal pMac,
 		tSirBssDescription *pBssDesc);
-/**
- * sme_qos_remove_addts_delts_cmd - Remove addts/delts command
- * @mac_ctx: Pointer to the global MAC structure.
- * @session_id: Session id
- *
- * This function is used to remove addts/delts command
- * during csr roam sync callback.
- *
- * Return: void
- */
-void sme_qos_remove_addts_delts_cmd(tpAniSirGlobal mac_ctx, uint8_t session_id);
 QDF_STATUS sme_qos_csr_event_ind(tpAniSirGlobal pMac,
 		uint8_t sessionId,
 		sme_qos_csr_event_indType ind, void *pEvent_info);

+ 106 - 0
core/sme/src/common/sme_api.c

@@ -2413,6 +2413,18 @@ QDF_STATUS sme_process_msg(tHalHandle hHal, struct scheduler_msg *pMsg)
 		}
 		break;
 #endif
+	case eWNI_SME_GET_PEER_INFO_IND:
+		if (pMac->sme.pget_peer_info_ind_cb)
+			pMac->sme.pget_peer_info_ind_cb(pMsg->bodyptr,
+				pMac->sme.pget_peer_info_cb_context);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_GET_PEER_INFO_EXT_IND:
+		if (pMac->sme.pget_peer_info_ext_ind_cb)
+			pMac->sme.pget_peer_info_ext_ind_cb(pMsg->bodyptr,
+				pMac->sme.pget_peer_info_ext_cb_context);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
 	case eWNI_SME_CSA_OFFLOAD_EVENT:
 		if (pMsg->bodyptr) {
 			csr_scan_flush_bss_entry(pMac, pMsg->bodyptr);
@@ -9686,6 +9698,100 @@ QDF_STATUS sme_get_link_speed(tHalHandle hHal, tSirLinkSpeedInfo *lsReq,
 	return status;
 }
 
+QDF_STATUS sme_get_peer_info(tHalHandle hal, struct sir_peer_info_req req,
+			void *context,
+			void (*callbackfn)(struct sir_peer_info_resp *param,
+						void *pcontext))
+{
+
+	QDF_STATUS status;
+	QDF_STATUS qdf_status;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct scheduler_msg message;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		if (NULL == callbackfn) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Indication Call back is NULL",
+				__func__);
+			sme_release_global_lock(&mac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		mac->sme.pget_peer_info_ind_cb = callbackfn;
+		mac->sme.pget_peer_info_cb_context = context;
+
+		/* serialize the req through MC thread */
+		message.bodyptr = qdf_mem_malloc(sizeof(req));
+		if (NULL == message.bodyptr) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Memory allocation failed.", __func__);
+			sme_release_global_lock(&mac->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+		qdf_mem_copy(message.bodyptr, &req, sizeof(req));
+		message.type = WMA_GET_PEER_INFO;
+		qdf_status = scheduler_post_msg(QDF_MODULE_ID_WMA, &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Post get peer info msg fail", __func__);
+			qdf_mem_free(message.bodyptr);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&mac->sme);
+	}
+	return status;
+}
+
+QDF_STATUS sme_get_peer_info_ext(tHalHandle hal,
+		struct sir_peer_info_ext_req *req,
+		void *context,
+		void (*callbackfn)(struct sir_peer_info_ext_resp *param,
+			void *pcontext))
+{
+	QDF_STATUS status;
+	QDF_STATUS qdf_status;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct scheduler_msg message;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		if (NULL == callbackfn) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Indication Call back is NULL",
+				__func__);
+			sme_release_global_lock(&mac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		mac->sme.pget_peer_info_ext_ind_cb = callbackfn;
+		mac->sme.pget_peer_info_ext_cb_context = context;
+
+		/* serialize the req through MC thread */
+		message.bodyptr =
+			qdf_mem_malloc(sizeof(struct sir_peer_info_ext_req));
+		if (NULL == message.bodyptr) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Memory allocation failed.", __func__);
+			sme_release_global_lock(&mac->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+		qdf_mem_copy(message.bodyptr,
+				req,
+				sizeof(struct sir_peer_info_ext_req));
+		message.type = WMA_GET_PEER_INFO_EXT;
+		qdf_status = scheduler_post_msg(QDF_MODULE_ID_WMA, &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Post get rssi msg fail", __func__);
+			qdf_mem_free(message.bodyptr);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&mac->sme);
+	}
+	return status;
+}
 
 /*
  * SME API to enable/disable WLAN driver initiated SSR

+ 107 - 35
core/sme/src/csr/csr_api_roam.c

@@ -2775,6 +2775,8 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
 			pParam->sta_roam_policy_params.dfs_mode;
 		pMac->roam.configParam.sta_roam_policy.skip_unsafe_channels =
 			pParam->sta_roam_policy_params.skip_unsafe_channels;
+		pMac->roam.configParam.sta_roam_policy.sap_operating_band =
+			pParam->sta_roam_policy_params.sap_operating_band;
 
 		pMac->roam.configParam.tx_aggregation_size =
 			pParam->tx_aggregation_size;
@@ -2786,6 +2788,12 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
 			pParam->qcn_ie_support;
 		pMac->roam.configParam.fils_max_chan_guard_time =
 			pParam->fils_max_chan_guard_time;
+		pMac->roam.configParam.disallow_duration =
+			pParam->disallow_duration;
+		pMac->roam.configParam.rssi_channel_penalization =
+			pParam->rssi_channel_penalization;
+		pMac->roam.configParam.num_disallowed_aps =
+			pParam->num_disallowed_aps;
 
 		csr_update_he_config_param(pMac, pParam);
 	}
@@ -3025,6 +3033,12 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
 		pMac->roam.configParam.qcn_ie_support;
 	pParam->fils_max_chan_guard_time =
 		pMac->roam.configParam.fils_max_chan_guard_time;
+	pParam->disallow_duration =
+		pMac->roam.configParam.disallow_duration;
+	pParam->rssi_channel_penalization =
+		pMac->roam.configParam.rssi_channel_penalization;
+	pParam->num_disallowed_aps =
+		pMac->roam.configParam.num_disallowed_aps;
 
 	csr_get_he_config_param(pParam, pMac);
 
@@ -9838,6 +9852,17 @@ void csr_roam_joined_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf)
 		qdf_mem_copy(&pRoamInfo->chan_info,
 			     &pUpperLayerAssocCnf->chan_info,
 			     sizeof(tSirSmeChanInfo));
+		pRoamInfo->ampdu = pUpperLayerAssocCnf->ampdu;
+		pRoamInfo->sgi_enable = pUpperLayerAssocCnf->sgi_enable;
+		pRoamInfo->tx_stbc = pUpperLayerAssocCnf->tx_stbc;
+		pRoamInfo->tx_stbc = pUpperLayerAssocCnf->rx_stbc;
+		pRoamInfo->ch_width = pUpperLayerAssocCnf->ch_width;
+		pRoamInfo->mode = pUpperLayerAssocCnf->mode;
+		pRoamInfo->max_supp_idx = pUpperLayerAssocCnf->max_supp_idx;
+		pRoamInfo->max_ext_idx = pUpperLayerAssocCnf->max_ext_idx;
+		pRoamInfo->max_mcs_idx = pUpperLayerAssocCnf->max_mcs_idx;
+		pRoamInfo->rx_mcs_map = pUpperLayerAssocCnf->rx_mcs_map;
+		pRoamInfo->tx_mcs_map = pUpperLayerAssocCnf->tx_mcs_map;
 		if (CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile)) {
 			pMac->roam.roamSession[sessionId].connectState =
 				eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED;
@@ -15157,54 +15182,90 @@ QDF_STATUS csr_send_assoc_ind_to_upper_layer_cnf_msg(tpAniSirGlobal pMac,
 		else
 			statusCode = eSIR_SME_ASSOC_REFUSED;
 		qdf_mem_copy(pBuf, &statusCode, sizeof(tSirResultCodes));
-		pBuf += sizeof(tSirResultCodes);
 		/* bssId */
-		qdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->bssId,
-			     sizeof(tSirMacAddr));
-		pBuf += sizeof(tSirMacAddr);
+		pBuf = (uint8_t *)&pMsg->bssId;
+		qdf_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId,
+			sizeof(tSirMacAddr));
 		/* peerMacAddr */
-		qdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->peerMacAddr,
-			     sizeof(tSirMacAddr));
-		pBuf += sizeof(tSirMacAddr);
+		pBuf = (uint8_t *)&pMsg->peerMacAddr;
+		qdf_mem_copy((tSirMacAddr *)pBuf, pAssocInd->peerMacAddr,
+			sizeof(tSirMacAddr));
 		/* StaId */
+		pBuf = (uint8_t *)&pMsg->aid;
 		wTmp = pAssocInd->staId;
 		qdf_mem_copy(pBuf, &wTmp, sizeof(uint16_t));
-		pBuf += sizeof(uint16_t);
 		/* alternateBssId */
-		qdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->bssId,
-			     sizeof(tSirMacAddr));
-		pBuf += sizeof(tSirMacAddr);
+		pBuf = (uint8_t *)&pMsg->alternateBssId;
+		qdf_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId,
+			sizeof(tSirMacAddr));
 		/* alternateChannelId */
+		pBuf = (uint8_t *)&pMsg->alternateChannelId;
 		*pBuf = 11;
-		pBuf += sizeof(uint8_t);
-		/* Instead of copying roam Info, we just copy only WmmEnabled,
-		 * RsnIE information
+		/*
+		 * Instead of copying roam Info,just copy WmmEnabled,
+		 * RsnIE information.
+		 * Wmm
 		 */
-		/* Wmm */
+		pBuf = (uint8_t *)&pMsg->wmmEnabledSta;
 		*pBuf = pAssocInd->wmmEnabledSta;
-		pBuf += sizeof(uint8_t);
 		/* RSN IE */
-		qdf_mem_copy((tSirRSNie *) pBuf, &pAssocInd->rsnIE,
-			     sizeof(tSirRSNie));
-		pBuf += sizeof(tSirRSNie);
+		pBuf = (uint8_t *)&pMsg->rsnIE;
+		qdf_mem_copy((tSirRSNie *)pBuf, &pAssocInd->rsnIE,
+			sizeof(tSirRSNie));
 #ifdef FEATURE_WLAN_WAPI
 		/* WAPI IE */
-		qdf_mem_copy((tSirWAPIie *) pBuf, &pAssocInd->wapiIE,
-			     sizeof(tSirWAPIie));
-		pBuf += sizeof(tSirWAPIie);
+		pBuf = (uint8_t *)&pMsg->wapiIE;
+		qdf_mem_copy((tSirWAPIie *)pBuf, &pAssocInd->wapiIE,
+			sizeof(tSirWAPIie));
 #endif
 		/* Additional IE */
-		qdf_mem_copy((void *)pBuf, &pAssocInd->addIE,
-			     sizeof(tSirAddie));
-		pBuf += sizeof(tSirAddie);
+		pBuf = (uint8_t *)&pMsg->addIE;
+		qdf_mem_copy((tSirAddie *)pBuf, &pAssocInd->addIE,
+			sizeof(tSirAddie));
 		/* reassocReq */
+		pBuf = (uint8_t *)&pMsg->reassocReq;
 		*pBuf = pAssocInd->reassocReq;
-		pBuf += sizeof(uint8_t);
 		/* timingMeasCap */
+		pBuf = (uint8_t *)&pMsg->timingMeasCap;
 		*pBuf = pAssocInd->timingMeasCap;
-		pBuf += sizeof(uint8_t);
+		/* chan_info */
+		pBuf = (uint8_t *)&pMsg->chan_info;
 		qdf_mem_copy((void *)pBuf, &pAssocInd->chan_info,
-			     sizeof(tSirSmeChanInfo));
+			sizeof(tSirSmeChanInfo));
+		/* ampdu */
+		pBuf = (uint8_t *)&pMsg->ampdu;
+		*((bool *)pBuf) = pAssocInd->ampdu;
+		/* sgi_enable */
+		pBuf = (uint8_t *)&pMsg->sgi_enable;
+		*((bool *)pBuf) = pAssocInd->sgi_enable;
+		/* tx stbc */
+		pBuf = (uint8_t *)&pMsg->tx_stbc;
+		*((bool *)pBuf) = pAssocInd->tx_stbc;
+		/* ch_width */
+		pBuf = (uint8_t *)&pMsg->ch_width;
+		*((tSirMacHTChannelWidth *)pBuf) = pAssocInd->ch_width;
+		/* mode */
+		pBuf = (uint8_t *)&pMsg->mode;
+		*((enum sir_sme_phy_mode *)pBuf) = pAssocInd->mode;
+		/* rx stbc */
+		pBuf = (uint8_t *)&pMsg->rx_stbc;
+		*((bool *)pBuf) = pAssocInd->rx_stbc;
+		/* max supported idx */
+		pBuf = (uint8_t *)&pMsg->max_supp_idx;
+		*pBuf = pAssocInd->max_supp_idx;
+		/* max extended idx */
+		pBuf = (uint8_t *)&pMsg->max_ext_idx;
+		*pBuf = pAssocInd->max_ext_idx;
+		/* max ht mcs idx */
+		pBuf = (uint8_t *)&pMsg->max_mcs_idx;
+		*pBuf = pAssocInd->max_mcs_idx;
+		/* vht rx mcs map */
+		pBuf = (uint8_t *)&pMsg->rx_mcs_map;
+		*pBuf = pAssocInd->rx_mcs_map;
+		/* vht tx mcs map */
+		pBuf = (uint8_t *)&pMsg->tx_mcs_map;
+		*pBuf = pAssocInd->tx_mcs_map;
+
 		msgQ.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF;
 		msgQ.bodyptr = pMsg;
 		msgQ.bodyval = 0;
@@ -16459,6 +16520,7 @@ QDF_STATUS csr_get_snr(tpAniSirGlobal pMac,
 
 	status = csr_roam_get_session_id_from_bssid(pMac, &bssId, &sessionId);
 	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		qdf_mem_free(pMsg);
 		sme_err("Couldn't find session_id for given BSSID");
 		return status;
 	}
@@ -17208,15 +17270,26 @@ csr_create_roam_scan_offload_request(tpAniSirGlobal mac_ctx,
 		mac_ctx->roam.configParam.early_stop_scan_min_threshold;
 	req_buf->early_stop_scan_max_threshold =
 		mac_ctx->roam.configParam.early_stop_scan_max_threshold;
-	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
-		  FL("HomeAwayTime=%d EarlyStopFeature Enable=%d, MinThresh=%d, MaxThresh=%d PMK len=%d"),
-		  req_buf->HomeAwayTime, req_buf->early_stop_scan_enable,
-		  req_buf->early_stop_scan_min_threshold,
-		  req_buf->early_stop_scan_max_threshold,
-		  req_buf->pmk_len);
 	req_buf->roamscan_adaptive_dwell_mode =
 		mac_ctx->roam.configParam.roamscan_adaptive_dwell_mode;
+	req_buf->lca_config_params.disallow_duration =
+		mac_ctx->roam.configParam.disallow_duration;
+	req_buf->lca_config_params.rssi_channel_penalization =
+		mac_ctx->roam.configParam.rssi_channel_penalization;
+	req_buf->lca_config_params.num_disallowed_aps =
+		mac_ctx->roam.configParam.num_disallowed_aps;
+
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
+	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+		  FL("HomeAwayTime=%d EarlyStopFeature Enable=%d, MinThresh=%d, MaxThresh=%d PMK len=%d disallow_dur=%d rssi_chan_pen=%d num_disallowed_aps=%d"),
+		  req_buf->HomeAwayTime,
+		  req_buf->early_stop_scan_enable,
+		  req_buf->early_stop_scan_min_threshold,
+		  req_buf->early_stop_scan_max_threshold,
+		  req_buf->pmk_len,
+		  req_buf->lca_config_params.disallow_duration,
+		  req_buf->lca_config_params.rssi_channel_penalization,
+		  req_buf->lca_config_params.num_disallowed_aps);
 	req_buf->RoamOffloadEnabled = csr_roamIsRoamOffloadEnabled(mac_ctx);
 	req_buf->RoamKeyMgmtOffloadEnabled = session->RoamKeyMgmtOffloadEnabled;
 	req_buf->pmkid_modes = session->pmkid_modes;
@@ -19984,7 +20057,6 @@ static QDF_STATUS csr_process_roam_sync_callback(tpAniSirGlobal mac_ctx,
 		eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
 	sme_qos_csr_event_ind(mac_ctx, session_id,
 		SME_QOS_CSR_REASSOC_COMPLETE, &assoc_info);
-	sme_qos_remove_addts_delts_cmd(mac_ctx, session_id);
 	roam_info->pBssDesc = bss_desc;
 	conn_profile->acm_mask = sme_qos_get_acm_mask(mac_ctx,
 			bss_desc, NULL);

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio