Bläddra i källkod

qcacmn: Do not cancel hrtimer without initializing the timer

When the dfs_puncture feature is enabled and if the punctured subchannels
are not part of the current channel, dfs_punc_sm_stop() is invoked
from dfs_handle_dfs_puncture_unpuncture() API.
dfs_punc_sm_stop() does a hrtimer_cancel of dfs_punc_cac_timer though
hrtimer_init of dfs_punc_cac_timer is not done.
This causes kernel panic.
hrtimer_init() is done only when punctured channels are a subset of the
current channel.

Do a hrtimer_init() during dfs_attach to avoid the crash.

Change-Id: Ib9214ffe0b9605850885ca09c8d638dccecc7f00
CRs-Fixed: 3491078
Priyadarshnee Srinivasan 2 år sedan
förälder
incheckning
cfc9355364

+ 19 - 0
umac/dfs/core/src/dfs.h

@@ -2389,6 +2389,19 @@ void dfs_cac_timer_reset(struct wlan_dfs *dfs);
  */
 void dfs_cac_timer_detach(struct wlan_dfs *dfs);
 
+/**
+ * dfs_puncture_cac_timer_detach() - Free puncture cac timers.
+ * @dfs: Pointer to wlan_dfs structure.
+ */
+#if defined(QCA_DFS_BW_PUNCTURE) && !defined(CONFIG_REG_CLIENT)
+void dfs_puncture_cac_timer_detach(struct wlan_dfs *dfs);
+#else
+static inline
+void dfs_puncture_cac_timer_detach(struct wlan_dfs *dfs)
+{
+}
+#endif
+
 /**
  * dfs_deliver_cac_state_events() - Deliver the DFS CAC events namely
  * WLAN_EV_CAC_STARTED on cac started channel(current channel) and
@@ -2498,6 +2511,12 @@ static inline
 void dfs_deliver_cac_state_events(struct wlan_dfs *dfs)
 {
 }
+
+static inline
+void dfs_puncture_cac_timer_detach(struct wlan_dfs *dfs)
+{
+}
+
 #endif
 /**
  * dfs_set_update_nol_flag() - Sets update_nol flag.

+ 0 - 19
umac/dfs/core/src/dfs_zero_cac.h

@@ -1350,18 +1350,6 @@ void dfs_create_punc_sm(struct wlan_dfs *dfs);
  */
 void dfs_destroy_punc_sm(struct wlan_dfs *dfs);
 
-/**
- * dfs_punc_sm_start() - Start DFS puncture state machine.
- * @dfs:           Pointer to wlan_dfs.
- * @indx:          Index of DFS puncture state machine.
- * @dfs_punc_arr:  Pointer to DFS puncture state machine object.
- *
- * Return: Nothing.
- */
-void dfs_punc_sm_start(struct wlan_dfs *dfs,
-		       uint8_t indx,
-		       struct dfs_punc_obj *dfs_punc_arr);
-
 /**
  * dfs_punc_sm_stop() - Stop DFS puncture state machine.
  * @dfs:           Pointer to wlan_dfs.
@@ -1504,13 +1492,6 @@ void dfs_destroy_punc_sm(struct wlan_dfs *dfs)
 {
 }
 
-static inline
-void dfs_punc_sm_start(struct wlan_dfs *dfs,
-		       uint8_t indx,
-		       struct dfs_punc_obj *dfs_punc_arr)
-{
-}
-
 static inline
 void dfs_punc_sm_stop(struct wlan_dfs *dfs,
 		      uint8_t indx,

+ 15 - 1
umac/dfs/core/src/misc/dfs.c

@@ -187,7 +187,8 @@ int dfs_create_object(struct wlan_dfs **dfs)
 	return 0;
 }
 
-#if defined(QCA_DFS_BW_PUNCTURE) && defined(CONFIG_REG_CLIENT)
+#if defined(QCA_DFS_BW_PUNCTURE)
+#if defined(CONFIG_REG_CLIENT)
 static void dfs_puncture_init(struct wlan_dfs *dfs)
 {
 	/*
@@ -199,6 +200,18 @@ static void dfs_puncture_init(struct wlan_dfs *dfs)
 	dfs->dfs_use_puncture = true;
 }
 #else
+static void dfs_puncture_init(struct wlan_dfs *dfs)
+{
+	uint8_t i;
+	struct dfs_punc_obj *dfs_punc_obj;
+
+	for (i = 0 ; i < N_MAX_PUNC_SM; i++) {
+		dfs_punc_obj = &dfs->dfs_punc_lst.dfs_punc_arr[i];
+		dfs_punc_cac_timer_attach(dfs, dfs_punc_obj);
+	}
+}
+#endif
+#else
 static inline void dfs_puncture_init(struct wlan_dfs *dfs)
 {
 }
@@ -281,6 +294,7 @@ void dfs_reset(struct wlan_dfs *dfs)
 void dfs_timer_detach(struct wlan_dfs *dfs)
 {
 	dfs_cac_timer_detach(dfs);
+	dfs_puncture_cac_timer_detach(dfs);
 	dfs_zero_cac_timer_detach(dfs->dfs_soc_obj);
 
 	if (!dfs->dfs_is_offload_enabled) {

+ 13 - 0
umac/dfs/core/src/misc/dfs_cac.c

@@ -223,6 +223,19 @@ void dfs_cac_timer_detach(struct wlan_dfs *dfs)
 	dfs->dfs_cac_valid = 0;
 }
 
+#if defined(QCA_DFS_BW_PUNCTURE) && !defined(CONFIG_REG_CLIENT)
+void dfs_puncture_cac_timer_detach(struct wlan_dfs *dfs)
+{
+	uint8_t i;
+	struct dfs_punc_obj *dfs_punc_obj;
+
+	for (i = 0 ; i < N_MAX_PUNC_SM; i++) {
+		dfs_punc_obj = &dfs->dfs_punc_lst.dfs_punc_arr[i];
+		dfs_punc_cac_timer_detach(dfs_punc_obj);
+	}
+}
+#endif
+
 int dfs_is_ap_cac_timer_running(struct wlan_dfs *dfs)
 {
 	return dfs->dfs_cac_timer_running;