Selaa lähdekoodia

qcacld-3.0: Add vdev state machine for start BSS and CSA failure

Adds vdev state machine for start bss and CSA failure.

Change-Id: I77979af192e40fe44dd9ea7ce41d7be52f40ad15
CRs-Fixed: 2316581
Abhishek Singh 6 vuotta sitten
vanhempi
sitoutus
c5a5408b00

+ 20 - 0
components/mlme/core/inc/wlan_mlme_vdev_mgr_interface.h

@@ -31,10 +31,12 @@
  * @chan_switch_in_progress: flag to indicate that channel switch is in progress
  * @hidden_ssid_restart_in_progress: flag to indicate hidden ssid restart is
  *                                   in progress
+ * @vdev_start_failed: flag to indicate that vdev start failed.
  */
 struct mlme_legacy_priv {
 	bool chan_switch_in_progress;
 	bool hidden_ssid_restart_in_progress;
+	bool vdev_start_failed;
 };
 
 /**
@@ -95,5 +97,23 @@ ap_mlme_set_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev,
  */
 bool ap_mlme_get_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev);
 
+/**
+ * ap_mlme_set_vdev_start_failed() - set mlme priv vdev restart fail flag
+ * @vdev: vdev pointer
+ * @val: value to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+ap_mlme_set_vdev_start_failed(struct wlan_objmgr_vdev *vdev, bool val);
+
+/**
+ * ap_mlme_get_vdev_start_failed() - get mlme priv vdev restart fail flag
+ * @vdev: vdev pointer
+ *
+ * Return: value of mlme priv vdev restart fail flag
+ */
+bool ap_mlme_get_vdev_start_failed(struct wlan_objmgr_vdev *vdev);
+
 #endif
 #endif

+ 53 - 8
components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c

@@ -444,18 +444,17 @@ static QDF_STATUS ap_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
 /**
  * ap_mlme_vdev_start_req_failed () - vdev start req fail callback
  * @vdev_mlme: vdev mlme object
- * @event_data_len: event data length
- * @event_data: event data
+ * @data_len: event data length
+ * @data: event data
  *
  * This function is called to handle vdev start req/rsp failure
  *
  * Return: QDF_STATUS
  */
 static QDF_STATUS ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme,
-						uint16_t event_data_len,
-						void *event_data)
+						uint16_t data_len, void *data)
 {
-	return QDF_STATUS_SUCCESS;
+	return lim_ap_mlme_vdev_start_req_failed(vdev_mlme, data_len, data);
 }
 
 /**
@@ -474,12 +473,23 @@ static QDF_STATUS ap_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
 	return lim_ap_mlme_vdev_restart_send(vdev_mlme, data_len, data);
 }
 
+/**
+ * ap_mlme_vdev_stop_start_send() - handle vdev stop during start req
+ * @vdev_mlme: vdev mlme object
+ * @type: restart req or start req
+ * @data_len: event data length
+ * @data: event data
+ *
+ * This function is called to handle vdev stop during start req
+ *
+ * Return: QDF_STATUS
+ */
 static QDF_STATUS ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme,
 					       enum vdev_cmd_type type,
-					       uint16_t event_data_len,
-					       void *event_data)
+					       uint16_t data_len, void *data)
 {
-	return QDF_STATUS_SUCCESS;
+	return wma_ap_mlme_vdev_stop_start_send(vdev_mlme, type,
+						data_len, data);
 }
 
 QDF_STATUS ap_mlme_set_chan_switch_in_progress(struct wlan_objmgr_vdev *vdev,
@@ -553,6 +563,41 @@ bool ap_mlme_get_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev)
 	return mlme_priv->hidden_ssid_restart_in_progress;
 }
 
+QDF_STATUS
+ap_mlme_set_vdev_start_failed(struct wlan_objmgr_vdev *vdev, bool val)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_err("vdev component object is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
+
+	mlme_priv->vdev_start_failed = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool ap_mlme_get_vdev_start_failed(struct wlan_objmgr_vdev *vdev)
+{
+	struct vdev_mlme_obj *vdev_mlme;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_err("vdev component object is NULL");
+		return false;
+	}
+
+	mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
+
+	return mlme_priv->vdev_start_failed;
+}
+
 /**
  * ap_mlme_vdev_legacy_hdl_create () - Create sap mlme legacy priv object
  * @vdev_mlme: vdev mlme object

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

@@ -47,7 +47,6 @@
 
 void lim_process_mlm_join_cnf(tpAniSirGlobal, uint32_t *);
 void lim_process_mlm_auth_cnf(tpAniSirGlobal, uint32_t *);
-void lim_process_mlm_start_cnf(tpAniSirGlobal, uint32_t *);
 void lim_process_mlm_assoc_ind(tpAniSirGlobal, uint32_t *);
 void lim_process_mlm_assoc_cnf(tpAniSirGlobal, uint32_t *);
 void lim_process_mlm_reassoc_ind(tpAniSirGlobal, uint32_t *);

+ 10 - 2
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -2972,9 +2972,17 @@ static void lim_delete_peers_and_send_vdev_stop(tpPESession session)
 	tpAniSirGlobal mac_ctx = session->mac_ctx;
 	QDF_STATUS status;
 
-	status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
-					       WLAN_VDEV_SM_EV_DOWN,
+	if (wlan_vdev_mlme_get_substate(session->vdev) ==
+	    WLAN_VDEV_SS_START_RESTART_PROGRESS)
+		status =
+		 wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					       WLAN_VDEV_SM_EV_RESTART_REQ_FAIL,
 					       sizeof(*session), session);
+	else
+		status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+						       WLAN_VDEV_SM_EV_DOWN,
+						       sizeof(*session),
+						       session);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		pe_err("failed to post WLAN_VDEV_SM_EV_DOWN for vdevid %d",
 		       session->smeSessionId);

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

@@ -422,6 +422,16 @@ void lim_process_mlm_req_messages(tpAniSirGlobal, struct scheduler_msg *);
 void lim_process_mlm_rsp_messages(tpAniSirGlobal, uint32_t, uint32_t *);
 void lim_process_sme_del_bss_rsp(tpAniSirGlobal, uint32_t, tpPESession);
 
+/**
+ * lim_process_mlm_start_cnf(): called to processes MLM_START_CNF message from
+ * MLM State machine.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: A pointer to the MLM message buffer
+ *
+ * Return: None
+ */
+void lim_process_mlm_start_cnf(tpAniSirGlobal mac_ctx, uint32_t *msg_buf);
+
 void lim_get_random_bssid(tpAniSirGlobal pMac, uint8_t *data);
 
 /* Function to handle HT and HT IE CFG parameter intializations */

+ 48 - 7
core/mac/src/pe/lim/lim_utils.c

@@ -8423,13 +8423,6 @@ void lim_process_ap_ecsa_timeout(void *data)
 	}
 }
 
-void lim_send_start_bss_confirm(tpAniSirGlobal mac_ctx,
-				     tLimMlmStartCnf *start_cnf)
-{
-	lim_post_sme_message(mac_ctx, LIM_MLM_START_CNF,
-			     (uint32_t *)start_cnf);
-}
-
 #ifdef CONFIG_VDEV_SM
 
 void lim_send_beacon(tpAniSirGlobal mac_ctx, tpPESession session)
@@ -8558,8 +8551,56 @@ QDF_STATUS lim_ap_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS lim_ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme,
+					     uint16_t data_len, void *data)
+{
+	tpAniSirGlobal mac_ctx;
+
+	/* store mac ctx in vdev_mlme legacy_vdev_ptr?*/
+	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac_ctx) {
+		pe_err("mac_ctx is NULL");
+		if (data)
+			qdf_mem_free(data);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	lim_process_mlm_start_cnf(mac_ctx, data);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void lim_send_start_bss_confirm(tpAniSirGlobal mac_ctx,
+				tLimMlmStartCnf *start_cnf)
+{
+	if (start_cnf->resultCode == eSIR_SME_SUCCESS) {
+		lim_post_sme_message(mac_ctx, LIM_MLM_START_CNF,
+				     (uint32_t *)start_cnf);
+	} else {
+		tpPESession session;
+
+		session = pe_find_session_by_session_id(mac_ctx,
+							start_cnf->sessionId);
+		if (!session) {
+			pe_err("session is NULL");
+			return;
+		}
+		ap_mlme_set_vdev_start_failed(session->vdev, true);
+		wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					      WLAN_VDEV_SM_EV_START_REQ_FAIL,
+					      sizeof(*start_cnf), start_cnf);
+	}
+}
+
 #else
 
+void lim_send_start_bss_confirm(tpAniSirGlobal mac_ctx,
+				tLimMlmStartCnf *start_cnf)
+{
+	lim_post_sme_message(mac_ctx, LIM_MLM_START_CNF,
+			     (uint32_t *)start_cnf);
+}
+
 void lim_send_beacon(tpAniSirGlobal mac_ctx, tpPESession session)
 {
 	lim_send_beacon_ind(mac_ctx, session);

+ 14 - 0
core/mac/src/pe/lim/lim_utils.h

@@ -1582,6 +1582,20 @@ QDF_STATUS lim_ap_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
 QDF_STATUS lim_ap_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
 					 uint16_t data_len, void *data);
 
+/**
+ * lim_ap_mlme_vdev_start_req_failed - handle vdev start req failure
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes on START fail response
+ *
+ * Return: SUCCESS on successful invocation of callback
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS lim_ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme,
+					     uint16_t data_len, void *data);
+
 #endif
 
 #endif /* __LIM_UTILS_H */

+ 16 - 0
core/wma/inc/wma_api.h

@@ -468,6 +468,22 @@ QDF_STATUS wma_ap_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
 QDF_STATUS
 wma_ap_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
 				      uint16_t data_len, void *data);
+
+/**
+ * wma_ap_mlme_vdev_stop_start_send - handle vdev stop during start req
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @type: restart req or start req
+ * @data_len: data size
+ * @data: event data
+ *
+ * API handle vdev stop during start req
+ *
+ * Return: SUCCESS alsways
+ */
+QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme,
+					    enum vdev_cmd_type type,
+					    uint16_t data_len, void *data);
+
 #endif
 
 #endif

+ 12 - 8
core/wma/src/wma_dev_if.c

@@ -909,21 +909,25 @@ static void wma_send_start_resp(tp_wma_handle wma,
 				wmi_vdev_start_response_event_fixed_param *
 				resp_event)
 {
+	struct wma_txrx_node *iface = &wma->interfaces[resp_event->vdev_id];
+
 	if (!resp_event->status && QDF_IS_STATUS_SUCCESS(add_bss->status)) {
-		add_bss->status = wlan_vdev_mlme_sm_deliver_evt(
-				      wma->interfaces[resp_event->vdev_id].vdev,
-				      WLAN_VDEV_SM_EV_START_RESP,
-				      sizeof(*add_bss),
-				      add_bss);
+		add_bss->status =
+		  wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+						WLAN_VDEV_SM_EV_START_RESP,
+						sizeof(*add_bss), add_bss);
 		if (QDF_IS_STATUS_SUCCESS(add_bss->status))
 			return;
 	}
 
 	/* Send vdev stop if vdev start was success */
 	if (QDF_IS_STATUS_ERROR(add_bss->status) &&
-	    !resp_event->status)
-		if (wma_send_vdev_stop_to_fw(wma, resp_event->vdev_id))
-			WMA_LOGE(FL("Failed to send vdev stop"));
+	    !resp_event->status) {
+		wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+					      WLAN_VDEV_SM_EV_DOWN,
+					      sizeof(*add_bss),	add_bss);
+		return;
+	}
 
 	WMA_LOGD(FL("Sending add bss rsp to umac(vdev %d status %d)"),
 		 resp_event->vdev_id, add_bss->status);

+ 20 - 6
core/wma/src/wma_utils.c

@@ -4800,11 +4800,8 @@ QDF_STATUS wma_get_roam_scan_stats(WMA_HANDLE handle,
 #ifdef CONFIG_VDEV_SM
 
 static QDF_STATUS
-wma_ap_vdev_send_start_resp(struct vdev_mlme_obj *vdev_mlme,
-			    tpAddBssParams add_bss)
+wma_ap_vdev_send_start_resp(tp_wma_handle wma, tpAddBssParams add_bss)
 {
-	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
-
 	WMA_LOGD(FL("Sending add bss rsp to umac(vdev %d status %d)"),
 		 add_bss->bssIdx, add_bss->status);
 	wma_send_msg_high_priority(wma, WMA_ADD_BSS_RSP, (void *)add_bss, 0);
@@ -4827,7 +4824,7 @@ QDF_STATUS wma_ap_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme,
 		wma_send_msg(wma, WMA_HIDDEN_SSID_RESTART_RSP, data, 0);
 		ap_mlme_set_hidden_ssid_restart_in_progress(vdev, false);
 	} else {
-		status = wma_ap_vdev_send_start_resp(vdev_mlme, data);
+		status = wma_ap_vdev_send_start_resp(wma, (tpAddBssParams)data);
 	}
 
 	return status;
@@ -4856,9 +4853,26 @@ wma_ap_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
 {
 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
 
-	wma_send_del_bss_response(wma, (struct wma_target_req *)data);
+	if (!ap_mlme_get_vdev_start_failed(vdev_mlme->vdev))
+		wma_send_del_bss_response(wma, (struct wma_target_req *)data);
+	else
+		ap_mlme_set_vdev_start_failed(vdev_mlme->vdev, false);
 
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme,
+					    enum vdev_cmd_type type,
+					    uint16_t data_len, void *data)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	tpAddBssParams bss_params = (tpAddBssParams)data;
+
+	if (wma_send_vdev_stop_to_fw(wma, bss_params->bssIdx))
+		WMA_LOGE(FL("Failed to send vdev stop for vdev id %d"),
+			 bss_params->bssIdx);
+
+	return wma_ap_vdev_send_start_resp(wma, bss_params);
+}
+
 #endif