Browse Source

qcacmn: Do not access reg private if destroyed

When SAP off and psoc idle shutdown happens before NOL timeout,
DFS pdev obj is destroyed, NOL timer is cleared, since regulatory
pdev private obj is destroyed before DFS, psoc master channel list
nol flag isn't cleared for regulatory pdev private obj is NULL.
When pdev current channel list is populated from psoc master channel
list, nol channel becomes disabled,  can't be used any more.

To fix it, when DFS private pdev obj is destroyed, don't access
regulatory pdev private if destroyed, but still clear psoc
mas_chan_list nol flag.

Change-Id: I79dad84631179d78d05c2738ce0aa4f863def7d4
CRs-Fixed: 3158675
Jianmin Zhu 3 năm trước cách đây
mục cha
commit
ba015feedc
1 tập tin đã thay đổi với 12 bổ sung8 xóa
  1. 12 8
      umac/regulatory/core/src/reg_services_common.c

+ 12 - 8
umac/regulatory/core/src/reg_services_common.c

@@ -6035,7 +6035,7 @@ void reg_update_nol_ch_for_freq(struct wlan_objmgr_pdev *pdev,
 				bool nol_chan)
 {
 	enum channel_enum chan_enum;
-	struct regulatory_channel *mas_chan_list, *psoc_mas_chan_list;
+	struct regulatory_channel *mas_chan_list = NULL, *psoc_mas_chan_list;
 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
 	struct wlan_objmgr_psoc *psoc;
 	uint16_t i;
@@ -6047,15 +6047,13 @@ void reg_update_nol_ch_for_freq(struct wlan_objmgr_pdev *pdev,
 
 	psoc = wlan_pdev_get_psoc(pdev);
 
-	pdev_priv_obj = reg_get_pdev_obj(pdev);
-	if (!pdev_priv_obj) {
-		reg_err("reg pdev private obj is NULL");
-		return;
-	}
 
 	psoc_mas_chan_list = reg_get_psoc_mas_chan_list(pdev, psoc);
+	pdev_priv_obj = reg_get_pdev_obj(pdev);
+
+	if (pdev_priv_obj)
+		mas_chan_list = pdev_priv_obj->mas_chan_list;
 
-	mas_chan_list = pdev_priv_obj->mas_chan_list;
 	for (i = 0; i < num_chan; i++) {
 		chan_enum = reg_get_chan_enum_for_freq(chan_freq_list[i]);
 		if (chan_enum == INVALID_CHANNEL) {
@@ -6063,11 +6061,17 @@ void reg_update_nol_ch_for_freq(struct wlan_objmgr_pdev *pdev,
 				chan_freq_list[i]);
 			continue;
 		}
-		mas_chan_list[chan_enum].nol_chan = nol_chan;
+		if (mas_chan_list)
+			mas_chan_list[chan_enum].nol_chan = nol_chan;
 		if (psoc_mas_chan_list)
 			psoc_mas_chan_list[chan_enum].nol_chan = nol_chan;
 	}
 
+	if (!pdev_priv_obj) {
+		reg_err("reg pdev private obj is NULL");
+		return;
+	}
+
 	reg_compute_pdev_current_chan_list(pdev_priv_obj);
 
 	reg_send_scheduler_msg_sb(psoc, pdev);