Merge "DHD: Fix kernel panic cause by thread is interrupted by ISR in the dbg_ring_poll_worker function" into android13-gs-pixel-5.10-udc
diff --git a/dhd_rtt.c b/dhd_rtt.c
index 73056ed..5f1e169 100644
--- a/dhd_rtt.c
+++ b/dhd_rtt.c
@@ -3467,6 +3467,7 @@
 	uint8 num_ftm = 0;
 	char *ftm_frame_types[] =  FTM_FRAME_TYPES;
 	rtt_report_t *rtt_report = &(rtt_result->report);
+	rtt_report_extra_t *rtt_report_extra = &(rtt_result->report_extra);
 
 	BCM_REFERENCE(ftm_frame_types);
 	BCM_REFERENCE(dist);
@@ -3482,6 +3483,7 @@
 	BCM_REFERENCE(ftm_session_state_value_to_logstr);
 
 	NULL_CHECK(rtt_report, "rtt_report is NULL", err);
+	NULL_CHECK(rtt_report_extra, "rtt_report_extra is NULL", err);
 	NULL_CHECK(p_data, "p_data is NULL", err);
 	DHD_RTT(("%s enter\n", __FUNCTION__));
 	p_data_info = (const wl_proxd_rtt_result_v2_t *) p_data;
@@ -3628,6 +3630,29 @@
 			ftm_tmu_value_to_logstr(ltoh16_ua(&p_data_info->u.burst_duration.tmu))));
 		DHD_RTT(("rtt_report->burst_duration : %d\n", rtt_report->burst_duration));
 	}
+
+	chanspec = ltoh32_ua(&p_sample_avg->chanspec);
+	/* rtt frequency & bw */
+	if (!wf_chspec_malformed(chanspec)) {
+		rtt_report_extra->frequency =
+			wl_channel_to_frequency(wf_chspec_ctlchan(chanspec), CHSPEC_BAND(chanspec));
+
+		if (CHSPEC_IS20(chanspec)) {
+			rtt_report_extra->packet_bw = RTT_BW_20;
+		} else if (CHSPEC_IS40(chanspec)) {
+			rtt_report_extra->packet_bw = RTT_BW_40;
+		} else if (CHSPEC_IS80(chanspec)) {
+			rtt_report_extra->packet_bw = RTT_BW_80;
+		} else if (CHSPEC_IS160(chanspec)) {
+			rtt_report_extra->packet_bw = RTT_BW_160;
+		} else {
+			rtt_report_extra->packet_bw = RTT_BW_UNSPECIFIED;
+		}
+	} else {
+		rtt_report_extra->frequency = -1;
+		rtt_report_extra->packet_bw = RTT_BW_UNSPECIFIED;
+	}
+
 	/* display detail if available */
 	num_rtt = ltoh16_ua(&p_data_info->num_rtt);
 	if (num_rtt > 0) {
@@ -3940,6 +3965,7 @@
 	rtt_result->report.type = RTT_TWO_WAY;
 	DHD_RTT(("report->ftm_num : %d\n", rtt_result->report.ftm_num));
 	rtt_result->report_len = RTT_REPORT_SIZE;
+	rtt_result->report_extra_len = sizeof(rtt_result->report_extra);
 	rtt_result->detail_len = sizeof(rtt_result->rtt_detail);
 
 exit:
@@ -3994,6 +4020,7 @@
 			list_add_tail(&rtt_result->list, &rtt_results_header->result_list);
 			rtt_results_header->result_cnt++;
 			rtt_results_header->result_tot_len += rtt_result->report_len +
+				rtt_result->report_extra_len +
 				rtt_result->detail_len;
 		} else {
 			err_at = 2;
diff --git a/dhd_rtt.h b/dhd_rtt.h
index eb3efa5..e1614ee 100644
--- a/dhd_rtt.h
+++ b/dhd_rtt.h
@@ -144,6 +144,7 @@
 };
 
 enum {
+	RTT_BW_UNSPECIFIED = 0,
 	RTT_BW_5 = BIT(0),
 	RTT_BW_10 = BIT(1),
 	RTT_BW_20 = BIT(2),
@@ -377,6 +378,16 @@
 	bcm_tlv_t *LCI; /* LCI Report */
 	bcm_tlv_t *LCR; /* Location Civic Report */
 } rtt_report_t;
+
+typedef struct rtt_report_extra {
+	int frequency; /* primary channel frequency (MHz) used for ranging measurements
+		        *  If frequency is unknown, this will be set to |UNSPECIFIED(-1)|
+			*/
+	int packet_bw; /* RTT packet bandwidth is an average BW of the BWs of RTT frames.
+	                * Cap the average close to a specific valid RttBw.
+		        */
+} rtt_report_extra_t;
+
 #define RTT_REPORT_SIZE (sizeof(rtt_report_t))
 
 /* rtt_results_header to maintain rtt result list per mac address */
@@ -395,7 +406,9 @@
 typedef struct rtt_result {
 	struct list_head list;
 	struct rtt_report report;
+	struct rtt_report_extra report_extra;
 	int32 report_len; /* total length of rtt_report */
+	int32 report_extra_len;
 	struct rtt_result_detail rtt_detail;
 	int32 detail_len;
 } rtt_result_t;
diff --git a/wl_cfgnan.c b/wl_cfgnan.c
index 1fa316d..e386f94 100644
--- a/wl_cfgnan.c
+++ b/wl_cfgnan.c
@@ -3119,7 +3119,7 @@
 
 	nan_buf_size -= nan_iov_data->nan_iov_len;
 	memset(resp_buf, 0, sizeof(resp_buf));
-	/* Reset conditon variable */
+	/* Reset condition variable */
 	ret = wl_cfgnan_execute_ioctl(ndev, cfg, nan_buf, nan_buf_size,
 			&(cmd_data->status), (void*)resp_buf, NAN_IOCTL_BUF_SIZE);
 	if (unlikely(ret) || unlikely(cmd_data->status)) {
@@ -3210,12 +3210,12 @@
 		ret = wl_cfgnan_config_control_flag(ndev, cfg, WL_NAN_CTRL2_FLAG1_NDPE_CAP,
 				0, WL_NAN_CMD_CFG_NAN_CONFIG2,
 				&(cmd_data->status), false);
+		nancfg->ndpe_enabled = false;
 		if (unlikely(ret) || unlikely(cmd_data->status)) {
 			WL_ERR((" nan ctrl2 config flags resetting failed, ret = %d status = %d \n",
 					ret, cmd_data->status));
 			goto fail;
 		}
-		nancfg->ndpe_enabled = false;
 	}
 
 	/* set CFG CTRL2 flags1 and flags2 */
@@ -3248,13 +3248,9 @@
 
 	nancfg->nan_enable = true;
 	WL_INFORM_MEM(("[NAN] Enable successfull \n"));
+	goto done;
 
 fail:
-	/* Enable back TDLS if connected interface is <= 1 */
-	wl_cfg80211_tdls_config(cfg, TDLS_STATE_IF_DELETE, false);
-
-	/* reset conditon variable */
-	nancfg->nan_event_recvd = false;
 	if (unlikely(ret) || unlikely(cmd_data->status)) {
 		mutex_lock(&cfg->if_sync);
 		ret = wl_cfg80211_delete_iface(cfg, WL_IF_TYPE_NAN);
@@ -3280,7 +3276,18 @@
 		if (ret != BCME_OK) {
 			WL_ERR(("failed to stop nan[%d]\n", ret));
 		}
+		ret = wl_cfgnan_deinit(cfg, dhdp->up);
+		if (ret != BCME_OK) {
+			WL_ERR(("failed to de-initialize NAN[%d]\n", ret));
+		}
 	}
+done:
+	/* Enable back TDLS if connected interface is <= 1 */
+	wl_cfg80211_tdls_config(cfg, TDLS_STATE_IF_DELETE, false);
+
+	/* reset condition variable */
+	nancfg->nan_event_recvd = false;
+
 	if (nan_buf) {
 		MFREE(cfg->osh, nan_buf, NAN_IOCTL_BUF_SIZE);
 	}
diff --git a/wl_cfgvendor.c b/wl_cfgvendor.c
index da59610..e116450 100644
--- a/wl_cfgvendor.c
+++ b/wl_cfgvendor.c
@@ -1811,6 +1811,12 @@
 				WL_ERR(("Failed to put RTT_ATTRIBUTE_RESULT, ret:%d\n", ret));
 				goto free_mem;
 			}
+			ret = nla_put(skb, RTT_ATTRIBUTE_RESULT_EXTRA,
+				rtt_result->report_extra_len, &rtt_result->report_extra);
+			if (ret < 0) {
+				WL_ERR(("Failed to put RTT_ATTRIBUTE_RESULT_EXTRA, ret:%d\n", ret));
+				goto free_mem;
+			}
 			ret = nla_put(skb, RTT_ATTRIBUTE_RESULT_DETAIL,
 				rtt_result->detail_len, &rtt_result->rtt_detail);
 			if (ret < 0) {
@@ -11792,6 +11798,7 @@
 	[RTT_ATTRIBUTE_RESULT] = { .type = NLA_BINARY, .len = sizeof(rtt_result_t) },
 	[RTT_ATTRIBUTE_RESULT_DETAIL] = { .type = NLA_BINARY,
 	.len = sizeof(struct rtt_result_detail) },
+	[RTT_ATTRIBUTE_RESULT_EXTRA] = { .type = NLA_BINARY, .len = sizeof(rtt_report_extra_t) },
 };
 
 #ifdef KEEP_ALIVE
diff --git a/wl_cfgvendor.h b/wl_cfgvendor.h
index f63b9c7..2f5dbd0 100755
--- a/wl_cfgvendor.h
+++ b/wl_cfgvendor.h
@@ -444,6 +444,7 @@
 	RTT_ATTRIBUTE_RESULT_CNT,
 	RTT_ATTRIBUTE_RESULT,
 	RTT_ATTRIBUTE_RESULT_DETAIL,
+	RTT_ATTRIBUTE_RESULT_EXTRA,
 	RTT_ATTRIBUTE_MAX
 };