Browse Source

qcacld-3.0: Add support for connection failure

Add vdev manager support for connection failure

Change-Id: I996e2bd14c7693793178edffa83d704a57580d93
CRs-Fixed: 2326164
Sandeep Puligilla 6 years ago
parent
commit
2a7fa8478b

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

@@ -32,11 +32,13 @@
  * @hidden_ssid_restart_in_progress: flag to indicate hidden ssid restart is
  *                                   in progress
  * @vdev_start_failed: flag to indicate that vdev start failed.
+ * @connection_fail: flag to indicate connection failed
  */
 struct mlme_legacy_priv {
 	bool chan_switch_in_progress;
 	bool hidden_ssid_restart_in_progress;
 	bool vdev_start_failed;
+	bool connection_fail;
 };
 
 /**
@@ -107,6 +109,24 @@ bool ap_mlme_is_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev);
 QDF_STATUS
 mlme_set_vdev_start_failed(struct wlan_objmgr_vdev *vdev, bool val);
 
+/**
+ * mlme_is_connection_fail() - get connection fail flag
+ * @vdev: vdev pointer
+ *
+ * Return: value of vdev connection failure flag
+ */
+bool mlme_is_connection_fail(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * mlme_set_connection_fail() - set connection failure flag
+ * @vdev: vdev pointer
+ * @val: value to be set
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+mlme_set_connection_fail(struct wlan_objmgr_vdev *vdev, bool val);
+
 /**
  * mlme_get_vdev_start_failed() - get mlme priv vdev restart fail flag
  * @vdev: vdev pointer

+ 35 - 1
components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c

@@ -382,7 +382,7 @@ static QDF_STATUS vdevmgr_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
 static QDF_STATUS vdevmgr_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
 					       uint16_t data_len, void *data)
 {
-	return wma_ap_mlme_vdev_notify_down_complete(vdev_mlme, data_len, data);
+	return wma_mlme_vdev_notify_down_complete(vdev_mlme, data_len, data);
 }
 
 /**
@@ -507,6 +507,40 @@ bool ap_mlme_is_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev)
 	return mlme_priv->hidden_ssid_restart_in_progress;
 }
 
+QDF_STATUS mlme_set_connection_fail(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->connection_fail = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool mlme_is_connection_fail(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->connection_fail;
+}
+
 QDF_STATUS
 mlme_set_vdev_start_failed(struct wlan_objmgr_vdev *vdev, bool val)
 {

+ 126 - 4
core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c

@@ -1277,6 +1277,96 @@ static void lim_join_result_callback(tpAniSirGlobal mac, void *param,
 	qdf_mem_free(link_state_params);
 }
 
+#ifdef CONFIG_VDEV_SM
+QDF_STATUS lim_sta_send_down_link(join_params *param)
+{
+	tpPESession session;
+	tpAniSirGlobal mac_ctx;
+	tpDphHashNode sta_ds = NULL;
+
+	if (!param) {
+		pe_err("param is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+	if (!mac_ctx) {
+		pe_err("Mac context is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	session = pe_find_session_by_session_id(mac_ctx, param->pe_session_id);
+	if (!session) {
+		pe_err("session is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	sta_ds = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+				    &session->dph.dphHashTable);
+	if (sta_ds) {
+		sta_ds->mlmStaContext.disassocReason =
+			eSIR_MAC_UNSPEC_FAILURE_REASON;
+		sta_ds->mlmStaContext.cleanupTrigger =
+			eLIM_JOIN_FAILURE;
+		sta_ds->mlmStaContext.resultCode = param->result_code;
+		sta_ds->mlmStaContext.protStatusCode = param->prot_status_code;
+		/*
+		 * FIX_ME: at the end of lim_cleanup_rx_path,
+		 * make sure PE is sending eWNI_SME_JOIN_RSP
+		 * to SME
+		 */
+		lim_cleanup_rx_path(mac_ctx, sta_ds, session);
+		qdf_mem_free(session->pLimJoinReq);
+		session->pLimJoinReq = NULL;
+		/* Cleanup if add bss failed */
+		if (session->add_bss_failed) {
+			dph_delete_hash_entry(mac_ctx,
+				 sta_ds->staAddr, sta_ds->assocId,
+				 &session->dph.dphHashTable);
+			goto error;
+		}
+		return QDF_STATUS_SUCCESS;
+	}
+	qdf_mem_free(session->pLimJoinReq);
+	session->pLimJoinReq = NULL;
+
+error:
+	/*
+	 * Delete the session if JOIN failure occurred.
+	 * if the peer is not created, then there is no
+	 * need to send down the set link state which will
+	 * try to delete the peer. Instead a join response
+	 * failure should be sent to the upper layers.
+	 */
+	if (param->result_code != eSIR_SME_PEER_CREATE_FAILED) {
+		join_params *link_state_arg;
+
+		link_state_arg = qdf_mem_malloc(sizeof(*link_state_arg));
+		if (link_state_arg) {
+			link_state_arg->result_code = param->result_code;
+			link_state_arg->prot_status_code =
+							param->prot_status_code;
+			link_state_arg->pe_session_id = session->peSessionId;
+		}
+		if (lim_set_link_state(mac_ctx, eSIR_LINK_DOWN_STATE,
+				       session->bssId,
+				       session->selfMacAddr,
+				       lim_join_result_callback,
+				       link_state_arg) != QDF_STATUS_SUCCESS) {
+			qdf_mem_free(link_state_arg);
+			pe_err("Failed to set the LinkState");
+		}
+		return QDF_STATUS_SUCCESS;
+	}
+
+
+	lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP,
+				      param->result_code,
+				      param->prot_status_code,
+				      session, session->smeSessionId,
+				      session->transactionId);
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * lim_handle_sme_join_result() - Handles sme join result
  * @mac_ctx:  Pointer to Global MAC structure
@@ -1291,6 +1381,35 @@ static void lim_join_result_callback(tpAniSirGlobal mac, void *param,
  *
  * Return: None
  */
+void lim_handle_sme_join_result(tpAniSirGlobal mac_ctx,
+	tSirResultCodes result_code, uint16_t prot_status_code,
+	tpPESession session)
+{
+	join_params param;
+	QDF_STATUS status;
+
+	if (!session) {
+		pe_err("session is NULL");
+		return;
+	}
+	if (result_code == eSIR_SME_SUCCESS)
+		return lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP,
+						     result_code,
+						     prot_status_code, session,
+						     session->smeSessionId,
+						     session->transactionId);
+
+	param.result_code = result_code;
+	param.prot_status_code = prot_status_code;
+	param.pe_session_id = session->peSessionId;
+
+	mlme_set_connection_fail(session->vdev, true);
+	status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
+					       WLAN_VDEV_SM_EV_CONNECTION_FAIL,
+					       sizeof(param), &param);
+	return;
+}
+#else
 void lim_handle_sme_join_result(tpAniSirGlobal mac_ctx,
 	tSirResultCodes result_code, uint16_t prot_status_code,
 	tpPESession session_entry)
@@ -1356,10 +1475,11 @@ error:
 			param->prot_status_code = prot_status_code;
 			param->pe_session_id = session_entry->peSessionId;
 		}
-		if (lim_set_link_state
-			(mac_ctx, eSIR_LINK_DOWN_STATE, session_entry->bssId,
-			 session_entry->selfMacAddr, lim_join_result_callback,
-			 param) != QDF_STATUS_SUCCESS) {
+		if (lim_set_link_state(mac_ctx, eSIR_LINK_DOWN_STATE,
+				       session_entry->bssId,
+				       session_entry->selfMacAddr,
+				       lim_join_result_callback,
+				       param) != QDF_STATUS_SUCCESS) {
 			qdf_mem_free(param);
 			pe_err("Failed to set the LinkState");
 		}
@@ -1369,6 +1489,8 @@ error:
 	lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP, result_code,
 		prot_status_code, session_entry, sme_session_id, sme_trans_id);
 }
+#endif
+
 
 /**
  * lim_process_mlm_add_sta_rsp()

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

@@ -775,6 +775,7 @@ void lim_covert_channel_scan_type(tpAniSirGlobal pMac, uint8_t channelNum,
 void lim_set_dfs_channel_list(tpAniSirGlobal pMac, uint8_t channelNum,
 			      tSirDFSChannelList *dfsChannelList);
 void limContinueChannelLearn(tpAniSirGlobal);
+QDF_STATUS lim_sta_send_down_link(join_params *param);
 
 #ifdef WLAN_FEATURE_11W
 /* 11w send SA query request action frame */

+ 18 - 1
core/mac/src/pe/lim/lim_utils.c

@@ -8435,7 +8435,24 @@ QDF_STATUS lim_sta_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
 QDF_STATUS lim_sta_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
 				       uint16_t data_len, void *data)
 {
-	return lim_sta_send_del_bss((tpPESession)data);
+	QDF_STATUS status;
+	bool connection_fail;
+
+	if (!data) {
+		pe_err("event_data is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	connection_fail = mlme_is_connection_fail(vdev_mlme->vdev);
+	pe_info("Send vdev stop, connection_fail %d", connection_fail);
+	if (connection_fail) {
+		status = lim_sta_send_down_link((join_params *)data);
+		mlme_set_connection_fail(vdev_mlme->vdev, false);
+	} else {
+		status = lim_sta_send_del_bss((tpPESession)data);
+	}
+
+	return status;
 }
 
 void lim_send_beacon(tpAniSirGlobal mac_ctx, tpPESession session)

+ 3 - 3
core/wma/inc/wma_api.h

@@ -504,7 +504,7 @@ QDF_STATUS wma_ap_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
 				      uint16_t data_len, void *data);
 
 /**
- * wma_ap_mlme_vdev_notify_down_complete - VDEV init state transition
+ * wma_mlme_vdev_notify_down_complete - VDEV init state transition
  * notification
  * @vdev_mlme_obj:  VDEV MLME comp object
  * @data_len: data size
@@ -516,8 +516,8 @@ QDF_STATUS wma_ap_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
  *         FAILURE, if it fails due to any
  */
 QDF_STATUS
-wma_ap_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
-				      uint16_t data_len, void *data);
+wma_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

+ 9 - 0
core/wma/inc/wma_internal.h

@@ -549,6 +549,15 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev,
  */
 void wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req);
 
+/**
+ * wma_send_set_link_response() - send set link response
+ * @wma: wma handle
+ * @req: target request
+ *
+ * Return: none
+ */
+void wma_send_set_link_response(tp_wma_handle wma, struct wma_target_req *req);
+
 /**
  * __wma_vdev_stop_resp_handler() - vdev stop response handler
  * @handle: wma handle

+ 24 - 4
core/wma/src/wma_dev_if.c

@@ -2026,6 +2026,13 @@ wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id)
 {}
 #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
 
+void wma_send_set_link_response(tp_wma_handle wma, struct wma_target_req *req)
+{
+	tpLinkStateParams params = (tpLinkStateParams) req->user_data;
+
+	wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
+}
+
 void wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req)
 {
 	struct wma_txrx_node *iface;
@@ -2248,12 +2255,18 @@ __wma_vdev_stop_resp_handler(wmi_vdev_stopped_event_fixed_param *resp_event)
 				}
 			}
 		}
+#ifdef CONFIG_VDEV_SM
+		wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+					      WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
+					      sizeof(*req_msg), req_msg);
+#else
 		if (wma_send_vdev_down_to_fw(wma, req_msg->vdev_id) !=
 		    QDF_STATUS_SUCCESS) {
 			WMA_LOGE("Failed to send vdev down cmd: vdev %d",
 				req_msg->vdev_id);
 		}
-		wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
+		wma_send_set_link_response(wma, req_msg);
+#endif
 	}
 
 free_req_msg:
@@ -3207,14 +3220,21 @@ int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info,
 				data->generate_rsp);
 		qdf_mem_free(data);
 	} else if (req_msg->type == WMA_SET_LINK_PEER_RSP) {
-		tpLinkStateParams params =
-			(tpLinkStateParams) req_msg->user_data;
+#ifdef CONFIG_VDEV_SM
+		struct wma_txrx_node *iface =
+					&wma->interfaces[req_msg->vdev_id];
+
+		wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
+					      WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
+					      sizeof(*req_msg), req_msg);
+#else
 		if (wma_send_vdev_down_to_fw(wma, req_msg->vdev_id) !=
 		    QDF_STATUS_SUCCESS) {
 			WMA_LOGE("Failed to send vdev down cmd: vdev %d",
 					req_msg->vdev_id);
 		}
-		wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
+		wma_send_set_link_response(wma, req_msg);
+#endif
 	} else if (req_msg->type == WMA_DELETE_PEER_RSP) {
 #ifdef CONFIG_VDEV_SM
 		struct wma_txrx_node *iface =

+ 8 - 3
core/wma/src/wma_utils.c

@@ -4880,13 +4880,18 @@ 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_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
+				   uint16_t data_len, void *data)
 {
 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	struct wma_target_req *req = (struct wma_target_req *)data;
 
 	if (!mlme_get_vdev_start_failed(vdev_mlme->vdev))
-		wma_send_del_bss_response(wma, (struct wma_target_req *)data);
+		if (req->msg_type == WMA_SET_LINK_STATE ||
+			req->type == WMA_SET_LINK_PEER_RSP)
+			wma_send_set_link_response(wma, req);
+		else
+			wma_send_del_bss_response(wma, req);
 	else
 		mlme_set_vdev_start_failed(vdev_mlme->vdev, false);