Преглед на файлове

qcacmn: Fix TDLS set state cmd sequence in concurrent TDLS connections

TDLS set state cmd to firmware is going out of sequence, if STA
is disconnected, when concurrent TDLS connections are active.
This out of sequence causes crash in the firmware.
Fix the out of sequence issue, by grouping all the TDLS delete
peer commands into one single command.

Change-Id: Idd315d544c46bcf063881bff5be70cb5d9ad0ea2
CRs-Fixed: 2123838
Kabilan Kannan преди 7 години
родител
ревизия
52a3a3ad05

+ 3 - 0
os_if/linux/tdls/inc/wlan_cfg80211_tdls.h

@@ -224,6 +224,7 @@ hdd_notify_sta_connect(uint8_t session_id,
  * hdd_notify_sta_disconnect() - notify sta disconnect to TDLS
  * @session_id: pointer to soc object
  * @lfr_roam: indicate, whether disconnect due to lfr roam
+ * @bool user_disconnect: disconnect from user space
  * @vdev: vdev object manager
  *
  * Notify sta disconnect event to TDLS component
@@ -232,6 +233,7 @@ hdd_notify_sta_connect(uint8_t session_id,
  */
 void hdd_notify_sta_disconnect(uint8_t session_id,
 			       bool lfr_roam,
+			       bool user_disconnect,
 			       struct wlan_objmgr_vdev *vdev);
 
 /**
@@ -262,6 +264,7 @@ hdd_notify_sta_connect(uint8_t session_id,
 static inline
 void hdd_notify_sta_disconnect(uint8_t session_id,
 			       bool lfr_roam,
+			       bool user_disconnect,
 			       struct wlan_objmgr_vdev *vdev)
 {
 

+ 2 - 0
os_if/linux/tdls/src/wlan_cfg80211_tdls.c

@@ -140,6 +140,7 @@ hdd_notify_sta_connect(uint8_t session_id,
 
 void hdd_notify_sta_disconnect(uint8_t session_id,
 			       bool lfr_roam,
+			       bool user_disconnect,
 			       struct wlan_objmgr_vdev *vdev)
 {
 	struct tdls_sta_notify_params notify_info;
@@ -147,6 +148,7 @@ void hdd_notify_sta_disconnect(uint8_t session_id,
 	notify_info.session_id = session_id;
 	notify_info.lfr_roam = lfr_roam;
 	notify_info.vdev = vdev;
+	notify_info.user_disconnect = user_disconnect;
 	ucfg_tdls_notify_sta_disconnect(&notify_info);
 
 }

+ 0 - 1
umac/tdls/core/src/wlan_tdls_ct.c

@@ -1157,7 +1157,6 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev,
  *
  * Return: QDF_STATUS
  */
-static
 QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev,
 					  struct tdls_soc_priv_obj *tdls_soc)
 {

+ 12 - 0
umac/tdls/core/src/wlan_tdls_ct.h

@@ -194,4 +194,16 @@ void tdls_teardown_connections(struct wlan_objmgr_vdev *vdev);
 void tdls_disable_offchan_and_teardown_links(
 				struct wlan_objmgr_vdev *vdev);
 
+/**
+ * tdls_delete_all_tdls_peers(): send request to delete tdls peers
+ * @vdev: vdev object
+ * @tdls_soc: tdls soc object
+ *
+ * This function sends request to lim to delete tdls peers
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev,
+					  struct tdls_soc_priv_obj *tdls_soc);
+
 #endif

+ 7 - 0
umac/tdls/core/src/wlan_tdls_main.c

@@ -915,6 +915,12 @@ tdls_process_sta_disconnect(struct tdls_sta_notify_params *notify)
 							&tdls_soc_obj))
 		return QDF_STATUS_E_INVAL;
 
+	/* if the disconnect comes from user space, we have to delete all the
+	 * tdls peers before sending the set state cmd.
+	 */
+	if (notify->user_disconnect)
+		return tdls_delete_all_tdls_peers(notify->vdev, tdls_soc_obj);
+
 	tdls_debug("Check and update TDLS state");
 
 	curr_tdls_vdev = tdls_vdev_obj;
@@ -1026,6 +1032,7 @@ void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev,
 	notify->tdls_prohibited = false;
 	notify->session_id = session_id;
 	notify->vdev = vdev;
+	notify->user_disconnect = false;
 
 	tdls_notify_sta_disconnect(notify);
 }

+ 1 - 0
umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h

@@ -1012,6 +1012,7 @@ struct tdls_sta_notify_params {
 	bool tdls_prohibited;
 	bool tdls_chan_swit_prohibited;
 	bool lfr_roam;
+	bool user_disconnect;
 	uint8_t session_id;
 };
 

+ 1 - 0
umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c

@@ -642,6 +642,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect(
 	notify->tdls_prohibited = false;
 	notify->vdev = notify_info->vdev;
 	notify->lfr_roam = notify_info->lfr_roam;
+	notify->user_disconnect = notify_info->user_disconnect;
 
 	msg.bodyptr = notify;
 	msg.callback = tdls_process_cmd;