Преглед изворни кода

qcacld-3.0: Enable CSA of STA mode for VDEV SM

After receive F/W wmi_csa_handling_event
1. Send WLAN_VDEV_SM_EV_FW_VDEV_RESTART before switch channel
	when gLimChannelSwitchTimer timeout.
2. Call __lim_process_channel_switch_timeout in
	mlme_vdev_restart_send.
3. Send WLAN_VDEV_SM_EV_RESTART_RESP in
	wma_vdev_start_resp_handler.
4. Send WMA_SWITCH_CHANNEL_RSP in mlme_vdev_start_continue.
5. Send WLAN_VDEV_SM_EV_START_SUCCESS in
	lim_switch_channel_cback.

Change-Id: I18e64ddf4ca898189cd22a3c8102a67702a025cc
CRs-Fixed: 2355762
Jianmin Zhu пре 6 година
родитељ
комит
69e7bf332c

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

@@ -124,7 +124,8 @@ static QDF_STATUS sta_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
 					     uint16_t event_data_len,
 					     void *event_data)
 {
-	return QDF_STATUS_SUCCESS;
+	return lim_sta_mlme_vdev_restart_send(vdev_mlme, event_data_len,
+					    event_data);
 }
 
 /**

+ 64 - 2
core/mac/src/pe/lim/lim_utils.c

@@ -1943,7 +1943,7 @@ lim_decide_sta_protection(tpAniSirGlobal mac_ctx,
 }
 
 /**
- * lim_process_channel_switch_timeout()
+ * __lim_process_channel_switch_timeout()
  *
  ***FUNCTION:
  * This function is invoked when Channel Switch Timer expires at
@@ -1955,7 +1955,7 @@ lim_decide_sta_protection(tpAniSirGlobal mac_ctx,
  * @param  mac           - Pointer to Global MAC structure
  * @return None
  */
-void lim_process_channel_switch_timeout(tpAniSirGlobal mac)
+static void __lim_process_channel_switch_timeout(tpAniSirGlobal mac)
 {
 	struct pe_session *psessionEntry = NULL;
 	uint8_t channel; /* This is received and stored from channelSwitch Action frame */
@@ -2051,6 +2051,34 @@ void lim_process_channel_switch_timeout(tpAniSirGlobal mac)
 	}
 }
 
+#ifdef CONFIG_VDEV_SM
+void lim_process_channel_switch_timeout(tpAniSirGlobal mac_ctx)
+{
+	tpPESession session_entry = NULL;
+	QDF_STATUS status;
+
+	session_entry = pe_find_session_by_session_id(
+		mac_ctx,
+		mac_ctx->lim.limTimers.gLimChannelSwitchTimer.sessionId);
+	mlme_set_chan_switch_in_progress(session_entry->vdev, true);
+	status = wlan_vdev_mlme_sm_deliver_evt(
+					session_entry->vdev,
+					WLAN_VDEV_SM_EV_FW_VDEV_RESTART,
+					sizeof(*mac_ctx),
+					mac_ctx);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("Failed to post WLAN_VDEV_SM_EV_FW_VDEV_RESTART for vdevid %d",
+		       session_entry->smeSessionId);
+		mlme_set_chan_switch_in_progress(session_entry->vdev, false);
+	}
+}
+#else
+void lim_process_channel_switch_timeout(tpAniSirGlobal mac)
+{
+	__lim_process_channel_switch_timeout(mac);
+}
+#endif
+
 /**
  * lim_update_channel_switch() - This Function updates channel switch
  * @mac_ctx: pointer to Global MAC structure
@@ -2261,6 +2289,9 @@ void lim_switch_channel_cback(tpAniSirGlobal mac, QDF_STATUS status,
 {
 	struct scheduler_msg mmhMsg = { 0 };
 	tSirSmeSwitchChannelInd *pSirSmeSwitchChInd;
+#ifdef CONFIG_VDEV_SM
+	QDF_STATUS evt_status;
+#endif
 
 	psessionEntry->currentOperChannel = psessionEntry->currentReqChannel;
 
@@ -2307,6 +2338,16 @@ void lim_switch_channel_cback(tpAniSirGlobal mac, QDF_STATUS status,
 			 psessionEntry->peSessionId, mmhMsg.type));
 
 	sys_process_mmh_msg(mac, &mmhMsg);
+#ifdef CONFIG_VDEV_SM
+	evt_status = wlan_vdev_mlme_sm_deliver_evt(
+				psessionEntry->vdev,
+				WLAN_VDEV_SM_EV_START_SUCCESS,
+				sizeof(*psessionEntry), psessionEntry);
+	if (QDF_IS_STATUS_ERROR(evt_status)) {
+		pe_err("Failed to post WLAN_VDEV_SM_EV_START_SUCCESS for vdevid %d",
+		       psessionEntry->smeSessionId);
+	}
+#endif
 }
 
 /**
@@ -7977,12 +8018,33 @@ QDF_STATUS lim_sta_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS lim_sta_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
+					  uint16_t data_len, void *data)
+{
+	if (!vdev_mlme) {
+		pe_err("vdev_mlme is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	if (!data) {
+		pe_err("event_data is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	if (mlme_is_chan_switch_in_progress(vdev_mlme->vdev))
+		__lim_process_channel_switch_timeout((tpAniSirGlobal)data);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS lim_sta_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
 				       uint16_t data_len, void *data)
 {
 	QDF_STATUS status;
 	bool connection_fail;
 
+	if (!vdev_mlme) {
+		pe_err("vdev_mlme is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
 	if (!data) {
 		pe_err("event_data is NULL");
 		return QDF_STATUS_E_INVAL;

+ 22 - 9
core/mac/src/pe/lim/lim_utils.h

@@ -1535,21 +1535,35 @@ QDF_STATUS lim_sta_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
 				       uint16_t data_len, void *data);
 
 /**
- * lim_ap_mlme_vdev_start_send() - Invokes VDEV start operation
+ * lim_sta_mlme_vdev_start_send() - send VDEV start
  * @vdev_mlme_obj:  VDEV MLME comp object
  * @data_len: data size
  * @data: event data
  *
- * API invokes VDEV start operation
+ * API invokes vdev start
  *
- * Return: SUCCESS on successful completion of start operation
+ * Return: SUCCESS on successful completion of vdev start
  *         FAILURE, if it fails due to any
  */
-QDF_STATUS lim_ap_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
-				       uint16_t data_len, void *event);
+QDF_STATUS lim_sta_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
+					uint16_t data_len, void *data);
 
 /**
- * lim_sta_mlme_vdev_start_send() - Invokes VDEV start operation
+ * lim_sta_mlme_vdev_restart_send() - send VDEV restart
+ * @vdev_mlme_obj:  VDEV MLME comp object
+ * @data_len: data size
+ * @data: event data
+ *
+ * API invokes vdev restart
+ *
+ * Return: SUCCESS on successful completion of vdev restart
+ *         FAILURE, if it fails due to any
+ */
+QDF_STATUS lim_sta_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
+					  uint16_t data_len, void *data);
+
+/**
+ * lim_ap_mlme_vdev_start_send() - Invokes VDEV start operation
  * @vdev_mlme_obj:  VDEV MLME comp object
  * @data_len: data size
  * @data: event data
@@ -1559,9 +1573,8 @@ QDF_STATUS lim_ap_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
  * Return: SUCCESS on successful completion of start operation
  *         FAILURE, if it fails due to any
  */
-QDF_STATUS lim_sta_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
-					uint16_t data_len, void *data);
-
+QDF_STATUS lim_ap_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
+				       uint16_t data_len, void *event);
 /*
  * lim_ap_mlme_vdev_update_beacon() - Updates beacon
  * @vdev_mlme_obj:  VDEV MLME comp object

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

@@ -1250,7 +1250,6 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
 	struct wma_target_req *req_msg;
 	struct wma_txrx_node *iface;
 	struct vdev_up_params param = {0};
-	QDF_STATUS status;
 	int err;
 	wmi_host_channel_width chanwidth;
 	target_resource_config *wlan_res_cfg;
@@ -1260,6 +1259,8 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
 #endif
 #ifdef CONFIG_VDEV_SM
 	enum wlan_vdev_sm_evt  event;
+#else
+	QDF_STATUS status;
 #endif
 	if (!psoc) {
 		WMA_LOGE("%s: psoc is NULL", __func__);
@@ -1425,7 +1426,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
 			WMA_LOGD("%s:vdev_id %d chanwidth %d status %d",
 				__func__, resp_event->vdev_id,
 				chanwidth, err);
-
+#ifndef CONFIG_VDEV_SM
 			param.vdev_id = resp_event->vdev_id;
 			param.assoc_id = iface->aid;
 			status = wma_send_vdev_up_to_fw(wma, &param,
@@ -1433,24 +1434,24 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
 			if (QDF_IS_STATUS_ERROR(status)) {
 				WMA_LOGE("%s:vdev_up failed vdev_id %d",
 					 __func__, resp_event->vdev_id);
-#ifndef CONFIG_VDEV_SM
+
 				wma_vdev_set_mlme_state(wma,
 					resp_event->vdev_id, WLAN_VDEV_S_STOP);
-#endif
+
 				policy_mgr_set_do_hw_mode_change_flag(
 					wma->psoc, false);
 			} else {
-#ifndef CONFIG_VDEV_SM
 				wma_vdev_set_mlme_state(wma,
 					resp_event->vdev_id, WLAN_VDEV_S_RUN);
-#endif
 				if (iface->beacon_filter_enabled)
 					wma_add_beacon_filter(wma,
 							&iface->beacon_filter);
 			}
+#endif
 		}
 #ifdef CONFIG_VDEV_SM
-		if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id))
+		if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id) ||
+		    mlme_is_chan_switch_in_progress(iface->vdev))
 			event = WLAN_VDEV_SM_EV_RESTART_RESP;
 		else
 			event = WLAN_VDEV_SM_EV_START_RESP;
@@ -5370,10 +5371,9 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
 #ifdef CONFIG_VDEV_SM
 	status = wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
 					       WLAN_VDEV_SM_EV_START_SUCCESS,
-					       sizeof(param), (void *)&param);
+					       0, NULL);
 #else
 	status = wma_send_vdev_up_to_fw(wma, &param, params->bssId);
-#endif
 	if (QDF_IS_STATUS_ERROR(status)) {
 		WMA_LOGE("%s: Failed to send vdev up cmd: vdev %d bssid %pM",
 			 __func__, params->smesessionId, params->bssId);
@@ -5382,12 +5382,10 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params)
 		status = QDF_STATUS_E_FAILURE;
 	} else {
 		wma_set_vdev_mgmt_rate(wma, params->smesessionId);
-#ifndef CONFIG_VDEV_SM
 		wma_vdev_set_mlme_state(wma, params->smesessionId,
 				WLAN_VDEV_S_RUN);
-#endif
 	}
-
+#endif
 	qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED);
 	WMA_LOGD("%s: STA mode (type %d subtype %d) BSS is started",
 		 __func__, iface->type, iface->sub_type);

+ 35 - 4
core/wma/src/wma_utils.c

@@ -4826,12 +4826,36 @@ void wma_remove_peer_on_add_bss_failure(tpAddBssParams add_bss_params)
 QDF_STATUS wma_sta_vdev_up_send(struct vdev_mlme_obj *vdev_mlme,
 				uint16_t data_len, void *data)
 {
-	struct vdev_up_params *param;
+	struct vdev_up_params param;
+	uint8_t vdev_id;
 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	QDF_STATUS status;
+	struct wma_txrx_node *iface;
 
-	param = (struct vdev_up_params *)data;
-	wma_send_vdev_up_to_fw(wma, param,
-			       wma->interfaces[param->vdev_id].bssid);
+	if (!wma) {
+		WMA_LOGE("%s wma handle is NULL", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+	vdev_id = wlan_vdev_get_id(vdev_mlme->vdev);
+	param.vdev_id = vdev_id;
+	iface = &wma->interfaces[vdev_id];
+	param.assoc_id = iface->aid;
+
+	status = wma_send_vdev_up_to_fw(wma, &param, iface->bssid);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE("%s: Failed to send vdev up cmd: vdev %d bssid %pM",
+			 __func__, vdev_id, iface->bssid);
+		policy_mgr_set_do_hw_mode_change_flag(
+			wma->psoc, false);
+		status = QDF_STATUS_E_FAILURE;
+	} else {
+		wma_set_vdev_mgmt_rate(wma, vdev_id);
+		if (iface->beacon_filter_enabled)
+			wma_add_beacon_filter(
+					wma,
+					&iface->beacon_filter);
+	}
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -4860,6 +4884,13 @@ QDF_STATUS wma_sta_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme,
 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
 	enum vdev_assoc_type assoc_type;
 
+	if (mlme_is_chan_switch_in_progress(vdev_mlme->vdev)) {
+		wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP,
+					   data, 0);
+		mlme_set_chan_switch_in_progress(vdev_mlme->vdev, false);
+		return QDF_STATUS_SUCCESS;
+	}
+
 	assoc_type = mlme_get_assoc_type(vdev_mlme->vdev);
 	switch (assoc_type) {
 	case VDEV_ASSOC: