Browse Source

qca-wifi: Reset the agile channel after radar in primary detector

If radar is detected on the primary channel, agile DFS is restarted
after vdev start response by triggering a zero second timer.
The timer fires immediately and the existing agile precac channel
is marked as CAC done. Since the agile preCAC channel was never cleared,
it was marked as CAC done.

Reset the agile channel if radar is detected on the primary channel.
In case of radar in agile detector, the channel change will not involve
any zero second timers and the agile channel will be overwritten by a
new channel.

Also, consider the case where radar is detected on the primary
channel. HOST will now select a new primary channel and issue vdev start
to FW. After vdev response, HOST will pick a new agile channel.
Since the agile engine was never stopped, FW may issue OCAC complete
for the old agile channel at this instant. Now, since HOST has picked a
new agile channel, this new agile channel will be marked as CAC done
due to the OCAC complete event from FW, without preCAC being started.

Send OCAC ABORT command after radar detection to properly restart
the agile state machine and avoid any race conditions like above.

CRs-Fixed: 2528567
Change-Id: I455cd513ba612bf48f057583b7529c7c3ef2f6c6
Vignesh Mohan 5 years ago
parent
commit
8628ae9e72
1 changed files with 21 additions and 7 deletions
  1. 21 7
      umac/dfs/core/src/misc/dfs_zero_cac.c

+ 21 - 7
umac/dfs/core/src/misc/dfs_zero_cac.c

@@ -879,9 +879,8 @@ void dfs_mark_precac_nol(struct wlan_dfs *dfs,
 	struct wlan_objmgr_psoc *psoc;
 	uint8_t i;
 	struct dfs_soc_priv_obj *dfs_soc_obj;
-
-	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
-	dfs_soc_obj = dfs->dfs_soc_obj;
+	struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
+	struct wlan_objmgr_pdev *pdev;
 
 	dfs_debug(dfs, WLAN_DEBUG_DFS,
 		  "is_radar_found_on_secondary_seg = %u subchannel_marking = %u detector_id = %u",
@@ -922,6 +921,12 @@ void dfs_mark_precac_nol(struct wlan_dfs *dfs,
 	}
 	PRECAC_LIST_UNLOCK(dfs);
 
+	psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
+	dfs_soc_obj = dfs->dfs_soc_obj;
+
+	dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
+	pdev = dfs->dfs_pdev_obj;
+
 	/* PreCAC timer is not running, no need to restart preCAC */
 	if (!dfs_soc_obj->dfs_precac_timer_running)
 		return;
@@ -965,18 +970,27 @@ void dfs_mark_precac_nol(struct wlan_dfs *dfs,
 
 		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.
+		 * running and also reset the current Agile channel.
 		 */
-		if (detector_id == AGILE_DETECTOR_ID)
+		if (detector_id == AGILE_DETECTOR_ID) {
 			dfs_prepare_agile_precac_chan(dfs);
-		else
-			dfs_soc_obj->precac_state_started = false;
+		} else {
+			dfs->dfs_agile_precac_freq = 0;
+			dfs_soc_obj->precac_state_started = PRECAC_NOT_STARTED;
+		}
 	}
 }