|
@@ -579,11 +579,30 @@ static void dfs_fill_adfs_chan_params(struct wlan_dfs *dfs,
|
|
adfs_param->precac_chwidth = dfs->dfs_precac_chwidth;
|
|
adfs_param->precac_chwidth = dfs->dfs_precac_chwidth;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* dfs_agile_precac_cleanup() - Reset parameters of wlan_dfs.
|
|
|
|
+ *
|
|
|
|
+ * @dfs: Pointer to struct wlan_dfs.
|
|
|
|
+ */
|
|
|
|
+static void dfs_agile_precac_cleanup(struct wlan_dfs *dfs)
|
|
|
|
+{
|
|
|
|
+ struct dfs_soc_priv_obj *dfs_soc_obj;
|
|
|
|
+
|
|
|
|
+ dfs_soc_obj = dfs->dfs_soc_obj;
|
|
|
|
+ qdf_timer_sync_cancel(&dfs_soc_obj->dfs_precac_timer);
|
|
|
|
+ dfs_soc_obj->dfs_precac_timer_running = 0;
|
|
|
|
+ dfs_soc_obj->precac_state_started = 0;
|
|
|
|
+ dfs->dfs_agile_precac_freq_mhz = 0;
|
|
|
|
+ dfs->dfs_precac_chwidth = CH_WIDTH_INVALID;
|
|
|
|
+ dfs_soc_obj->cur_agile_dfs_index = DFS_PSOC_NO_IDX;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* dfs_prepare_agile_precac_chan() - Prepare an agile channel for preCAC.
|
|
* dfs_prepare_agile_precac_chan() - Prepare an agile channel for preCAC.
|
|
* @dfs: Pointer to wlan_dfs.
|
|
* @dfs: Pointer to wlan_dfs.
|
|
|
|
+ *
|
|
|
|
+ * Return Type: void
|
|
*/
|
|
*/
|
|
-void dfs_prepare_agile_precac_chan(struct wlan_dfs *dfs)
|
|
|
|
|
|
+void dfs_prepare_agile_precac_chan(struct wlan_dfs *dfs, bool *is_chan_found)
|
|
{
|
|
{
|
|
struct wlan_objmgr_psoc *psoc;
|
|
struct wlan_objmgr_psoc *psoc;
|
|
struct wlan_objmgr_pdev *pdev;
|
|
struct wlan_objmgr_pdev *pdev;
|
|
@@ -651,9 +670,10 @@ void dfs_prepare_agile_precac_chan(struct wlan_dfs *dfs)
|
|
else
|
|
else
|
|
dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
|
|
dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
|
|
"dfs_tx_ops=%pK", dfs_tx_ops);
|
|
"dfs_tx_ops=%pK", dfs_tx_ops);
|
|
|
|
+ *is_chan_found = true;
|
|
} else {
|
|
} else {
|
|
- dfs->dfs_soc_obj->precac_state_started = false;
|
|
|
|
- qdf_info("No channels in preCAC required list");
|
|
|
|
|
|
+ dfs_agile_precac_cleanup(dfs);
|
|
|
|
+ *is_chan_found = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
@@ -872,6 +892,10 @@ static void dfs_unmark_rcac_done(struct wlan_dfs *dfs)
|
|
}
|
|
}
|
|
PRECAC_LIST_UNLOCK(dfs);
|
|
PRECAC_LIST_UNLOCK(dfs);
|
|
}
|
|
}
|
|
|
|
+#else
|
|
|
|
+static inline void dfs_unmark_rcac_done(struct wlan_dfs *dfs)
|
|
|
|
+{
|
|
|
|
+}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1051,14 +1075,6 @@ void dfs_unmark_precac_nol_for_freq(struct wlan_dfs *dfs, uint16_t chan_freq)
|
|
dfs_mlme_channel_change_by_precac(
|
|
dfs_mlme_channel_change_by_precac(
|
|
dfs->dfs_pdev_obj);
|
|
dfs->dfs_pdev_obj);
|
|
}
|
|
}
|
|
- } else if (dfs_is_agile_precac_enabled(dfs) &&
|
|
|
|
- !dfs->dfs_soc_obj->precac_state_started) {
|
|
|
|
- /* precac_state_started will be set to false if
|
|
|
|
- * agile CAC is not begun for any channels or
|
|
|
|
- * all channels were CACed. If it's not set, defer
|
|
|
|
- * changing the current Agile CAC channel.
|
|
|
|
- */
|
|
|
|
- dfs_prepare_agile_precac_chan(dfs);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1157,41 +1173,6 @@ void dfs_mark_precac_nol_for_freq(struct wlan_dfs *dfs,
|
|
dfs->dfs_pdev_obj);
|
|
dfs->dfs_pdev_obj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- } else if (dfs_is_agile_precac_enabled(dfs)) {
|
|
|
|
- /* If preCAC is not running on the DFS where radar is detected,
|
|
|
|
- * no need to configure agile channel.
|
|
|
|
- * Return from this function.
|
|
|
|
- */
|
|
|
|
- if (!(dfs_soc_obj->cur_agile_dfs_index == dfs->dfs_psoc_idx)) {
|
|
|
|
- dfs_debug(dfs, WLAN_DEBUG_DFS,
|
|
|
|
- "preCAC not running on radarfound DFS idx=%d",
|
|
|
|
- dfs->dfs_psoc_idx);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- qdf_timer_sync_cancel(&dfs_soc_obj->dfs_precac_timer);
|
|
|
|
- dfs_soc_obj->dfs_precac_timer_running = 0;
|
|
|
|
-
|
|
|
|
- /* Since Agile DFS is interrupted due to radar, send
|
|
|
|
- * OCAC abort event to FW for a proper restart of the Agile
|
|
|
|
- * state machine.
|
|
|
|
- */
|
|
|
|
- if (dfs_tx_ops && dfs_tx_ops->dfs_ocac_abort_cmd)
|
|
|
|
- dfs_tx_ops->dfs_ocac_abort_cmd(pdev);
|
|
|
|
- /*
|
|
|
|
- * If radar is found on agile engine, change the channel here
|
|
|
|
- * since primary channel change will not be triggered.
|
|
|
|
- * If radar is found on primary detector, let agile
|
|
|
|
- * channel change be triggered after start response.
|
|
|
|
- * Set precac_state_started to false to indicate preCAC is not
|
|
|
|
- * running and also reset the current Agile channel.
|
|
|
|
- */
|
|
|
|
- if (detector_id == dfs_get_agile_detector_id(dfs)) {
|
|
|
|
- dfs_prepare_agile_precac_chan(dfs);
|
|
|
|
- } else {
|
|
|
|
- dfs->dfs_agile_precac_freq_mhz = 0;
|
|
|
|
- dfs_soc_obj->precac_state_started = PRECAC_NOT_STARTED;
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1266,9 +1247,10 @@ void dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev,
|
|
enum phy_ch_width chwidth)
|
|
enum phy_ch_width chwidth)
|
|
{
|
|
{
|
|
struct wlan_dfs *dfs = NULL;
|
|
struct wlan_dfs *dfs = NULL;
|
|
- struct dfs_agile_cac_params adfs_param;
|
|
|
|
|
|
+ struct dfs_soc_priv_obj *dfs_soc_obj;
|
|
|
|
|
|
dfs = wlan_pdev_get_dfs_obj(pdev);
|
|
dfs = wlan_pdev_get_dfs_obj(pdev);
|
|
|
|
+ dfs_soc_obj = dfs->dfs_soc_obj;
|
|
|
|
|
|
/* When the FW sends a delayed OCAC completion status, Host might
|
|
/* When the FW sends a delayed OCAC completion status, Host might
|
|
* have changed the precac channel already before an OCAC
|
|
* have changed the precac channel already before an OCAC
|
|
@@ -1294,12 +1276,9 @@ void dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev,
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- /* STOP TIMER irrespective of status */
|
|
|
|
- utils_dfs_cancel_precac_timer(pdev);
|
|
|
|
if (ocac_status == OCAC_RESET) {
|
|
if (ocac_status == OCAC_RESET) {
|
|
dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS,
|
|
dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS,
|
|
"PreCAC timer reset, Sending Agile chan set command");
|
|
"PreCAC timer reset, Sending Agile chan set command");
|
|
- dfs_prepare_agile_precac_chan(dfs);
|
|
|
|
} else if (ocac_status == OCAC_CANCEL) {
|
|
} else if (ocac_status == OCAC_CANCEL) {
|
|
dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS,
|
|
dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS,
|
|
"PreCAC timer abort, agile precac stopped");
|
|
"PreCAC timer abort, agile precac stopped");
|
|
@@ -1308,19 +1287,14 @@ void dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev,
|
|
"PreCAC timer Completed for agile freq: %d %d",
|
|
"PreCAC timer Completed for agile freq: %d %d",
|
|
center_freq_mhz1,
|
|
center_freq_mhz1,
|
|
center_freq_mhz2);
|
|
center_freq_mhz2);
|
|
- /*
|
|
|
|
- * TRIGGER agile precac timer with 0sec timeout
|
|
|
|
- * with ocac_status 0 for old pdev
|
|
|
|
- */
|
|
|
|
- adfs_param.precac_center_freq_1 = center_freq_mhz1;
|
|
|
|
- adfs_param.precac_center_freq_2 = center_freq_mhz2;
|
|
|
|
- adfs_param.precac_chwidth = dfs->dfs_precac_chwidth;
|
|
|
|
- dfs_start_agile_precac_timer(dfs,
|
|
|
|
- ocac_status,
|
|
|
|
- &adfs_param);
|
|
|
|
} else {
|
|
} else {
|
|
dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, "Error Unknown");
|
|
dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, "Error Unknown");
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ dfs_soc_obj->ocac_status = ocac_status;
|
|
|
|
+ dfs_agile_sm_deliver_evt(dfs_soc_obj,
|
|
|
|
+ DFS_AGILE_SM_EV_AGILE_DONE,
|
|
|
|
+ 0, (void *)dfs);
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
@@ -1494,22 +1468,9 @@ static os_timer_func(dfs_precac_timeout)
|
|
"Pre-cac expired, Agile Precac chan %u curr time %d",
|
|
"Pre-cac expired, Agile Precac chan %u curr time %d",
|
|
dfs->dfs_agile_precac_freq_mhz,
|
|
dfs->dfs_agile_precac_freq_mhz,
|
|
current_time / 1000);
|
|
current_time / 1000);
|
|
- if (dfs_soc_obj->ocac_status == OCAC_SUCCESS) {
|
|
|
|
- dfs_soc_obj->ocac_status = OCAC_RESET;
|
|
|
|
- dfs_mark_adfs_chan_as_cac_done(dfs);
|
|
|
|
- }
|
|
|
|
- /* check if CAC done on home channel */
|
|
|
|
- is_cac_done_on_des_chan = dfs_precac_check_home_chan_change(dfs);
|
|
|
|
- if (!is_cac_done_on_des_chan) {
|
|
|
|
- /*
|
|
|
|
- * Use same home channel, only change preCAC channel.
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * TO BE DONE xxx : Need to lock the channel change.
|
|
|
|
- */
|
|
|
|
- dfs_prepare_agile_precac_chan(dfs);
|
|
|
|
- }
|
|
|
|
|
|
+ dfs_agile_sm_deliver_evt(dfs_soc_obj,
|
|
|
|
+ DFS_AGILE_SM_EV_AGILE_DONE,
|
|
|
|
+ 0, (void *)dfs);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2681,24 +2642,18 @@ void dfs_start_agile_precac_timer(struct wlan_dfs *dfs,
|
|
dfs_soc_obj = dfs->dfs_soc_obj;
|
|
dfs_soc_obj = dfs->dfs_soc_obj;
|
|
dfs_soc_obj->dfs_precac_timer_running = 1;
|
|
dfs_soc_obj->dfs_precac_timer_running = 1;
|
|
|
|
|
|
- if (ocac_status == OCAC_SUCCESS) {
|
|
|
|
- dfs_soc_obj->ocac_status = OCAC_SUCCESS;
|
|
|
|
- min_precac_timeout = 0;
|
|
|
|
- max_precac_timeout = 0;
|
|
|
|
|
|
+ /* Find the minimum and maximum precac timeout. */
|
|
|
|
+ max_precac_timeout = MAX_PRECAC_DURATION;
|
|
|
|
+ if (dfs->dfs_precac_timeout_override != -1) {
|
|
|
|
+ min_precac_timeout =
|
|
|
|
+ dfs->dfs_precac_timeout_override * 1000;
|
|
|
|
+ } else if (dfs_is_pcac_on_weather_channel_for_freq(dfs,
|
|
|
|
+ chwidth,
|
|
|
|
+ pcacfreq)) {
|
|
|
|
+ min_precac_timeout = MIN_WEATHER_PRECAC_DURATION;
|
|
|
|
+ max_precac_timeout = MAX_WEATHER_PRECAC_DURATION;
|
|
} else {
|
|
} else {
|
|
- /* Find the minimum and maximum precac timeout. */
|
|
|
|
- max_precac_timeout = MAX_PRECAC_DURATION;
|
|
|
|
- if (dfs->dfs_precac_timeout_override != -1) {
|
|
|
|
- min_precac_timeout =
|
|
|
|
- dfs->dfs_precac_timeout_override * 1000;
|
|
|
|
- } else if (dfs_is_pcac_on_weather_channel_for_freq(dfs,
|
|
|
|
- chwidth,
|
|
|
|
- pcacfreq)) {
|
|
|
|
- min_precac_timeout = MIN_WEATHER_PRECAC_DURATION;
|
|
|
|
- max_precac_timeout = MAX_WEATHER_PRECAC_DURATION;
|
|
|
|
- } else {
|
|
|
|
- min_precac_timeout = MIN_PRECAC_DURATION;
|
|
|
|
- }
|
|
|
|
|
|
+ min_precac_timeout = MIN_PRECAC_DURATION;
|
|
}
|
|
}
|
|
|
|
|
|
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
|
|
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
|
|
@@ -3271,9 +3226,8 @@ static void dfs_fill_des_rcac_chan_params(struct wlan_dfs *dfs,
|
|
ch_params->mhz_freq_seg0 = chan->dfs_ch_mhz_freq_seg1;
|
|
ch_params->mhz_freq_seg0 = chan->dfs_ch_mhz_freq_seg1;
|
|
ch_params->mhz_freq_seg1 = chan->dfs_ch_mhz_freq_seg2;
|
|
ch_params->mhz_freq_seg1 = chan->dfs_ch_mhz_freq_seg2;
|
|
}
|
|
}
|
|
-#endif
|
|
|
|
|
|
|
|
-#ifdef QCA_SUPPORT_ADFS_RCAC
|
|
|
|
|
|
+
|
|
bool dfs_is_agile_rcac_enabled(struct wlan_dfs *dfs)
|
|
bool dfs_is_agile_rcac_enabled(struct wlan_dfs *dfs)
|
|
{
|
|
{
|
|
enum dfs_reg dfsdomain;
|
|
enum dfs_reg dfsdomain;
|
|
@@ -3290,6 +3244,14 @@ bool dfs_is_agile_rcac_enabled(struct wlan_dfs *dfs)
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+#ifdef QCA_SUPPORT_AGILE_DFS
|
|
|
|
+bool dfs_is_agile_cac_enabled(struct wlan_dfs *dfs)
|
|
|
|
+{
|
|
|
|
+ return (dfs_is_agile_precac_enabled(dfs) ||
|
|
|
|
+ dfs_is_agile_rcac_enabled(dfs));
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
/* dfs_convert_chwidth_to_wlan_phymode() - Given a channel width, find out the
|
|
/* dfs_convert_chwidth_to_wlan_phymode() - Given a channel width, find out the
|
|
* 11AXA channel mode.
|
|
* 11AXA channel mode.
|
|
* @chwidth: Channel width of type enum phy_ch_width.
|
|
* @chwidth: Channel width of type enum phy_ch_width.
|
|
@@ -3928,8 +3890,16 @@ void dfs_set_precac_enable(struct wlan_dfs *dfs, uint32_t value)
|
|
if (dfs_is_precac_timer_running(dfs)) {
|
|
if (dfs_is_precac_timer_running(dfs)) {
|
|
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
|
|
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
|
|
"Precac flag changed. Cancel the precac timer");
|
|
"Precac flag changed. Cancel the precac timer");
|
|
- dfs_cancel_precac_timer(dfs);
|
|
|
|
- dfs->dfs_soc_obj->precac_state_started = 0;
|
|
|
|
|
|
+ if (tgt_tx_ops->tgt_is_tgt_type_qca9984(target_type)) {
|
|
|
|
+ dfs_cancel_precac_timer(dfs);
|
|
|
|
+ dfs->dfs_soc_obj->precac_state_started = 0;
|
|
|
|
+ } else {
|
|
|
|
+#ifdef QCA_SUPPORT_AGILE_DFS
|
|
|
|
+ dfs_agile_sm_deliver_evt(dfs->dfs_soc_obj,
|
|
|
|
+ DFS_AGILE_SM_EV_AGILE_STOP,
|
|
|
|
+ 0, (void *)dfs);
|
|
|
|
+#endif
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -4091,7 +4061,7 @@ void dfs_reinit_precac_lists(struct wlan_dfs *src_dfs,
|
|
PRECAC_LIST_UNLOCK(dest_dfs);
|
|
PRECAC_LIST_UNLOCK(dest_dfs);
|
|
}
|
|
}
|
|
|
|
|
|
-#ifdef QCA_SUPPORT_ADFS_RCAC
|
|
|
|
|
|
+#ifdef QCA_SUPPORT_AGILE_DFS
|
|
/* dfs_start_agile_engine() - Prepare ADFS params and program the agile
|
|
/* dfs_start_agile_engine() - Prepare ADFS params and program the agile
|
|
* engine sending agile config cmd to FW.
|
|
* engine sending agile config cmd to FW.
|
|
* @dfs: Pointer to struct wlan_dfs.
|
|
* @dfs: Pointer to struct wlan_dfs.
|
|
@@ -4330,6 +4300,7 @@ QDF_STATUS dfs_agile_sm_deliver_event(struct dfs_soc_priv_obj *dfs_soc_obj,
|
|
event_data);
|
|
event_data);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef QCA_SUPPORT_ADFS_RCAC
|
|
/* dfs_start_agile_rcac_timer() - Start host agile RCAC timer.
|
|
/* dfs_start_agile_rcac_timer() - Start host agile RCAC timer.
|
|
*
|
|
*
|
|
* @dfs: Pointer to struct wlan_dfs.
|
|
* @dfs: Pointer to struct wlan_dfs.
|
|
@@ -4359,6 +4330,11 @@ void dfs_stop_agile_rcac_timer(struct wlan_dfs *dfs)
|
|
qdf_timer_sync_cancel(&dfs_soc_obj->dfs_rcac_timer);
|
|
qdf_timer_sync_cancel(&dfs_soc_obj->dfs_rcac_timer);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * dfs_abort_agile_rcac() - Send abort Agile RCAC to F/W.
|
|
|
|
+ * @dfs: Pointer to struct wlan_dfs.
|
|
|
|
+ */
|
|
static void dfs_abort_agile_rcac(struct wlan_dfs *dfs)
|
|
static void dfs_abort_agile_rcac(struct wlan_dfs *dfs)
|
|
{
|
|
{
|
|
|
|
|
|
@@ -4376,6 +4352,29 @@ static void dfs_abort_agile_rcac(struct wlan_dfs *dfs)
|
|
dfs->dfs_precac_chwidth = CH_WIDTH_INVALID;
|
|
dfs->dfs_precac_chwidth = CH_WIDTH_INVALID;
|
|
dfs->dfs_soc_obj->cur_agile_dfs_index = DFS_PSOC_NO_IDX;
|
|
dfs->dfs_soc_obj->cur_agile_dfs_index = DFS_PSOC_NO_IDX;
|
|
}
|
|
}
|
|
|
|
+#else
|
|
|
|
+static inline void dfs_abort_agile_rcac(struct wlan_dfs *dfs)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+/* dfs_abort_agile_precac() - Reset parameters of wlan_dfs and send abort
|
|
|
|
+ * to F/W.
|
|
|
|
+ * @dfs: Pointer to struct wlan_dfs.
|
|
|
|
+ */
|
|
|
|
+static void dfs_abort_agile_precac(struct wlan_dfs *dfs)
|
|
|
|
+{
|
|
|
|
+ struct wlan_objmgr_psoc *psoc;
|
|
|
|
+ struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
|
|
|
|
+
|
|
|
|
+ psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
|
|
|
|
+ dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
|
|
|
|
+
|
|
|
|
+ dfs_agile_precac_cleanup(dfs);
|
|
|
|
+ /*Send the abort to F/W as well */
|
|
|
|
+ if (dfs_tx_ops && dfs_tx_ops->dfs_ocac_abort_cmd)
|
|
|
|
+ dfs_tx_ops->dfs_ocac_abort_cmd(dfs->dfs_pdev_obj);
|
|
|
|
+}
|
|
|
|
|
|
/**
|
|
/**
|
|
* dfs_agile_state_init_entry() - Entry API for INIT state
|
|
* dfs_agile_state_init_entry() - Entry API for INIT state
|
|
@@ -4405,6 +4404,40 @@ static void dfs_agile_state_init_exit(void *ctx)
|
|
/* NO OPS */
|
|
/* NO OPS */
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * dfs_init_agile_start_evt_handler() - Init state start event handler.
|
|
|
|
+ * @dfs: Instance of wlan_dfs structure.
|
|
|
|
+ * @dfs_soc: DFS SoC private object
|
|
|
|
+ *
|
|
|
|
+ * Return : True if PreCAC/RCAC chan is found.
|
|
|
|
+ */
|
|
|
|
+static bool dfs_init_agile_start_evt_handler(struct wlan_dfs *dfs,
|
|
|
|
+ struct dfs_soc_priv_obj *dfs_soc)
|
|
|
|
+{
|
|
|
|
+ bool is_chan_found = false;
|
|
|
|
+
|
|
|
|
+ /*For RCAC */
|
|
|
|
+ if (dfs_is_agile_rcac_enabled(dfs)) {
|
|
|
|
+ /* Check if feature is enabled for this DFS and if RCAC channel
|
|
|
|
+ * is valid, if those are true, send appropriate WMIs to FW
|
|
|
|
+ * and only then transition to the state as follows.
|
|
|
|
+ */
|
|
|
|
+ dfs_prepare_agile_rcac_channel(dfs, &is_chan_found);
|
|
|
|
+ }
|
|
|
|
+ /*For PreCAC */
|
|
|
|
+ else if (dfs_is_agile_precac_enabled(dfs)) {
|
|
|
|
+ dfs_soc->dfs_priv[dfs->dfs_psoc_idx].agile_precac_active
|
|
|
|
+ = true;
|
|
|
|
+ if (!dfs_soc->precac_state_started &&
|
|
|
|
+ !dfs_soc->dfs_precac_timer_running) {
|
|
|
|
+ dfs_soc->precac_state_started = true;
|
|
|
|
+ dfs_prepare_agile_precac_chan(dfs, &is_chan_found);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return is_chan_found;
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* dfs_agile_state_init_event() - INIT State event handler
|
|
* dfs_agile_state_init_event() - INIT State event handler
|
|
* @ctx: DFS SoC private object
|
|
* @ctx: DFS SoC private object
|
|
@@ -4425,7 +4458,7 @@ static bool dfs_agile_state_init_event(void *ctx,
|
|
struct dfs_soc_priv_obj *dfs_soc = (struct dfs_soc_priv_obj *)ctx;
|
|
struct dfs_soc_priv_obj *dfs_soc = (struct dfs_soc_priv_obj *)ctx;
|
|
bool status;
|
|
bool status;
|
|
struct wlan_dfs *dfs;
|
|
struct wlan_dfs *dfs;
|
|
- bool is_rcac_chan_available = false;
|
|
|
|
|
|
+ bool is_chan_found;
|
|
|
|
|
|
if (!event_data)
|
|
if (!event_data)
|
|
return false;
|
|
return false;
|
|
@@ -4434,18 +4467,24 @@ static bool dfs_agile_state_init_event(void *ctx,
|
|
|
|
|
|
switch (event) {
|
|
switch (event) {
|
|
case DFS_AGILE_SM_EV_AGILE_START:
|
|
case DFS_AGILE_SM_EV_AGILE_START:
|
|
- /* Check if feature is enabled for this DFS and if RCAC channel
|
|
|
|
- * is valid, if those are true, send appropriate WMIs to FW
|
|
|
|
- * and only then transition to the state as follows.
|
|
|
|
- */
|
|
|
|
|
|
|
|
if (dfs_soc->cur_agile_dfs_index != DFS_PSOC_NO_IDX)
|
|
if (dfs_soc->cur_agile_dfs_index != DFS_PSOC_NO_IDX)
|
|
return true;
|
|
return true;
|
|
- dfs_prepare_agile_rcac_channel(dfs, &is_rcac_chan_available);
|
|
|
|
- if (is_rcac_chan_available) {
|
|
|
|
|
|
+
|
|
|
|
+ is_chan_found = dfs_init_agile_start_evt_handler(dfs,
|
|
|
|
+ dfs_soc);
|
|
|
|
+ if (is_chan_found) {
|
|
dfs_soc->cur_agile_dfs_index = dfs->dfs_psoc_idx;
|
|
dfs_soc->cur_agile_dfs_index = dfs->dfs_psoc_idx;
|
|
dfs_agile_sm_transition_to(dfs_soc, DFS_AGILE_S_RUNNING);
|
|
dfs_agile_sm_transition_to(dfs_soc, DFS_AGILE_S_RUNNING);
|
|
|
|
+ } else {
|
|
|
|
+ /*
|
|
|
|
+ * This happens when there is no preCAC chan
|
|
|
|
+ * in any of the radios
|
|
|
|
+ */
|
|
|
|
+ dfs_agile_precac_cleanup(dfs);
|
|
|
|
+ /* Cleanup and wait */
|
|
}
|
|
}
|
|
|
|
+
|
|
status = true;
|
|
status = true;
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
@@ -4471,8 +4510,12 @@ static void dfs_agile_state_running_entry(void *ctx)
|
|
dfs_soc->dfs_priv[dfs_soc->cur_agile_dfs_index].dfs;
|
|
dfs_soc->dfs_priv[dfs_soc->cur_agile_dfs_index].dfs;
|
|
|
|
|
|
dfs_agile_set_curr_state(dfs_soc, DFS_AGILE_S_RUNNING);
|
|
dfs_agile_set_curr_state(dfs_soc, DFS_AGILE_S_RUNNING);
|
|
- dfs_start_agile_rcac_timer(dfs);
|
|
|
|
- dfs_start_agile_engine(dfs);
|
|
|
|
|
|
+
|
|
|
|
+ /* RCAC */
|
|
|
|
+ if (dfs_is_agile_rcac_enabled(dfs)) {
|
|
|
|
+ dfs_start_agile_rcac_timer(dfs);
|
|
|
|
+ dfs_start_agile_engine(dfs);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -4508,6 +4551,7 @@ static bool dfs_agile_state_running_event(void *ctx,
|
|
struct dfs_soc_priv_obj *dfs_soc = (struct dfs_soc_priv_obj *)ctx;
|
|
struct dfs_soc_priv_obj *dfs_soc = (struct dfs_soc_priv_obj *)ctx;
|
|
bool status;
|
|
bool status;
|
|
struct wlan_dfs *dfs;
|
|
struct wlan_dfs *dfs;
|
|
|
|
+ bool is_cac_done_on_des_chan;
|
|
|
|
|
|
if (!event_data)
|
|
if (!event_data)
|
|
return false;
|
|
return false;
|
|
@@ -4530,21 +4574,48 @@ static bool dfs_agile_state_running_event(void *ctx,
|
|
* channel not found and stay in that state.
|
|
* channel not found and stay in that state.
|
|
* Abort the existing RCAC and restart from INIT state.
|
|
* Abort the existing RCAC and restart from INIT state.
|
|
*/
|
|
*/
|
|
- dfs_abort_agile_rcac(dfs);
|
|
|
|
|
|
+ if (dfs_is_agile_rcac_enabled(dfs))
|
|
|
|
+ dfs_abort_agile_rcac(dfs);
|
|
|
|
+ else if (dfs_is_agile_precac_enabled(dfs))
|
|
|
|
+ dfs_abort_agile_precac(dfs);
|
|
|
|
+
|
|
dfs_agile_sm_transition_to(dfs_soc, DFS_AGILE_S_INIT);
|
|
dfs_agile_sm_transition_to(dfs_soc, DFS_AGILE_S_INIT);
|
|
dfs_agile_sm_deliver_event(dfs_soc,
|
|
dfs_agile_sm_deliver_event(dfs_soc,
|
|
- DFS_AGILE_SM_EV_AGILE_START,
|
|
|
|
- event_data_len,
|
|
|
|
- event_data);
|
|
|
|
|
|
+ DFS_AGILE_SM_EV_AGILE_START,
|
|
|
|
+ event_data_len,
|
|
|
|
+ event_data);
|
|
|
|
+
|
|
status = true;
|
|
status = true;
|
|
break;
|
|
break;
|
|
case DFS_AGILE_SM_EV_AGILE_STOP:
|
|
case DFS_AGILE_SM_EV_AGILE_STOP:
|
|
- dfs_abort_agile_rcac(dfs);
|
|
|
|
|
|
+ if (dfs_is_agile_rcac_enabled(dfs))
|
|
|
|
+ dfs_abort_agile_rcac(dfs);
|
|
|
|
+ else if (dfs_is_agile_precac_enabled(dfs))
|
|
|
|
+ dfs_abort_agile_precac(dfs);
|
|
|
|
+
|
|
dfs_agile_sm_transition_to(dfs_soc, DFS_AGILE_S_INIT);
|
|
dfs_agile_sm_transition_to(dfs_soc, DFS_AGILE_S_INIT);
|
|
status = true;
|
|
status = true;
|
|
break;
|
|
break;
|
|
case DFS_AGILE_SM_EV_AGILE_DONE:
|
|
case DFS_AGILE_SM_EV_AGILE_DONE:
|
|
- dfs_agile_sm_transition_to(dfs_soc, DFS_AGILE_S_COMPLETE);
|
|
|
|
|
|
+ if (dfs_is_agile_precac_enabled(dfs)) {
|
|
|
|
+ if (dfs_soc->ocac_status == OCAC_SUCCESS) {
|
|
|
|
+ dfs_soc->ocac_status = OCAC_RESET;
|
|
|
|
+ dfs_mark_adfs_chan_as_cac_done(dfs);
|
|
|
|
+ }
|
|
|
|
+ dfs_agile_sm_transition_to(dfs_soc, DFS_AGILE_S_INIT);
|
|
|
|
+ dfs_agile_precac_cleanup(dfs);
|
|
|
|
+ is_cac_done_on_des_chan =
|
|
|
|
+ dfs_precac_check_home_chan_change(dfs);
|
|
|
|
+ if (!is_cac_done_on_des_chan) {
|
|
|
|
+ dfs_agile_sm_deliver_event(dfs_soc,
|
|
|
|
+ DFS_AGILE_SM_EV_AGILE_START,
|
|
|
|
+ event_data_len,
|
|
|
|
+ event_data);
|
|
|
|
+ }
|
|
|
|
+ } else if (dfs_is_agile_rcac_enabled(dfs)) {
|
|
|
|
+ dfs_agile_sm_transition_to(dfs_soc,
|
|
|
|
+ DFS_AGILE_S_COMPLETE);
|
|
|
|
+ }
|
|
status = true;
|
|
status = true;
|
|
default:
|
|
default:
|
|
status = false;
|
|
status = false;
|
|
@@ -4737,9 +4808,9 @@ static void dfs_agile_sm_print_state_event(struct dfs_soc_priv_obj *dfs_soc_obj,
|
|
}
|
|
}
|
|
|
|
|
|
QDF_STATUS dfs_agile_sm_deliver_evt(struct dfs_soc_priv_obj *dfs_soc_obj,
|
|
QDF_STATUS dfs_agile_sm_deliver_evt(struct dfs_soc_priv_obj *dfs_soc_obj,
|
|
- enum dfs_agile_sm_evt event,
|
|
|
|
- uint16_t event_data_len,
|
|
|
|
- void *event_data)
|
|
|
|
|
|
+ enum dfs_agile_sm_evt event,
|
|
|
|
+ uint16_t event_data_len,
|
|
|
|
+ void *event_data)
|
|
{
|
|
{
|
|
enum dfs_agile_sm_state old_state, new_state;
|
|
enum dfs_agile_sm_state old_state, new_state;
|
|
QDF_STATUS status;
|
|
QDF_STATUS status;
|
|
@@ -4794,6 +4865,7 @@ QDF_STATUS dfs_agile_sm_destroy(struct dfs_soc_priv_obj *dfs_soc_obj)
|
|
return QDF_STATUS_SUCCESS;
|
|
return QDF_STATUS_SUCCESS;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef QCA_SUPPORT_ADFS_RCAC
|
|
QDF_STATUS dfs_set_rcac_enable(struct wlan_dfs *dfs, bool rcac_en)
|
|
QDF_STATUS dfs_set_rcac_enable(struct wlan_dfs *dfs, bool rcac_en)
|
|
{
|
|
{
|
|
if (rcac_en == dfs->dfs_agile_rcac_ucfg) {
|
|
if (rcac_en == dfs->dfs_agile_rcac_ucfg) {
|
|
@@ -4904,3 +4976,4 @@ void dfs_prepare_agile_rcac_channel(struct wlan_dfs *dfs,
|
|
rcac_ch_freq);
|
|
rcac_ch_freq);
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
+#endif
|