• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright(c) 2014 - 2017 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #include <drv_types.h>
16 #include <hal_data.h>
17 
18 
19 #if defined(CONFIG_RTW_ACS) || defined(CONFIG_BACKGROUND_NOISE_MONITOR)
_rtw_bss_nums_count(_adapter * adapter,u8 * pbss_nums)20 static void _rtw_bss_nums_count(_adapter *adapter, u8 *pbss_nums)
21 {
22 	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
23 	_queue *queue = &(pmlmepriv->scanned_queue);
24 	struct wlan_network *pnetwork = NULL;
25 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
26 
27 	_list	*plist, *phead;
28 	_irqL irqL;
29 	int chan_idx = -1;
30 
31 	if (pbss_nums == NULL) {
32 		RTW_ERR("%s pbss_nums is null pointer\n", __func__);
33 		return;
34 	}
35 	_rtw_memset(pbss_nums, 0, MAX_CHANNEL_NUM);
36 
37 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
38 	phead = get_list_head(queue);
39 	plist = get_next(phead);
40 	while (1) {
41 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
42 			break;
43 
44 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
45 		if (!pnetwork)
46 			break;
47 		chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), pnetwork->network.Configuration.DSConfig);
48 		if ((chan_idx == -1) || (chan_idx >= MAX_CHANNEL_NUM)) {
49 			RTW_ERR("%s can't get chan_idx(CH:%d)\n",
50 				__func__, pnetwork->network.Configuration.DSConfig);
51 			chan_idx = 0;
52 		}
53 		/*if (pnetwork->network.Reserved[0] != BSS_TYPE_PROB_REQ)*/
54 
55 		pbss_nums[chan_idx]++;
56 
57 		plist = get_next(plist);
58 	}
59 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
60 }
61 
rtw_get_ch_num_by_idx(_adapter * adapter,u8 idx)62 u8 rtw_get_ch_num_by_idx(_adapter *adapter, u8 idx)
63 {
64 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
65 	RT_CHANNEL_INFO *pch_set = rfctl->channel_set;
66 	u8 max_chan_nums = rfctl->max_chan_nums;
67 
68 	if (idx >= max_chan_nums)
69 		return 0;
70 	return pch_set[idx].ChannelNum;
71 }
72 #endif /*defined(CONFIG_RTW_ACS) || defined(CONFIG_BACKGROUND_NOISE_MONITOR)*/
73 
74 
75 #ifdef CONFIG_RTW_ACS
rtw_acs_version_dump(void * sel,_adapter * adapter)76 void rtw_acs_version_dump(void *sel, _adapter *adapter)
77 {
78 	_RTW_PRINT_SEL(sel, "RTK_ACS VER_%d\n", RTK_ACS_VERSION);
79 }
rtw_phydm_clm_ratio(_adapter * adapter)80 u8 rtw_phydm_clm_ratio(_adapter *adapter)
81 {
82 	struct dm_struct *phydm = adapter_to_phydm(adapter);
83 
84 	return phydm_cmn_info_query(phydm, (enum phydm_info_query) PHYDM_INFO_CLM_RATIO);
85 }
rtw_phydm_nhm_ratio(_adapter * adapter)86 u8 rtw_phydm_nhm_ratio(_adapter *adapter)
87 {
88 	struct dm_struct *phydm = adapter_to_phydm(adapter);
89 
90 	return phydm_cmn_info_query(phydm, (enum phydm_info_query) PHYDM_INFO_NHM_ENV_RATIO);
91 }
92 
rtw_phydm_nhm_noise_pwr(_adapter * adapter)93 u8 rtw_phydm_nhm_noise_pwr(_adapter *adapter)
94 {
95 	struct dm_struct *phydm = adapter_to_phydm(adapter);
96 
97 	return phydm_cmn_info_query(phydm, (enum phydm_info_query) PHYDM_INFO_NHM_PWR);
98 }
99 
rtw_acs_reset(_adapter * adapter)100 void rtw_acs_reset(_adapter *adapter)
101 {
102 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
103 	struct auto_chan_sel *pacs = &hal_data->acs;
104 
105 	_rtw_memset(pacs, 0, sizeof(struct auto_chan_sel));
106 	#ifdef CONFIG_RTW_ACS_DBG
107 	rtw_acs_adv_reset(adapter);
108 	#endif /*CONFIG_RTW_ACS_DBG*/
109 }
110 
111 #ifdef CONFIG_RTW_ACS_DBG
rtw_is_acs_igi_valid(_adapter * adapter)112 u8 rtw_is_acs_igi_valid(_adapter *adapter)
113 {
114 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
115 	struct auto_chan_sel *pacs = &hal_data->acs;
116 
117 	if ((pacs->igi) && ((pacs->igi >= 0x1E) || (pacs->igi < 0x60)))
118 		return _TRUE;
119 
120 	return _FALSE;
121 }
rtw_acs_adv_setting(_adapter * adapter,RT_SCAN_TYPE scan_type,u16 scan_time,u8 igi,u8 bw)122 void rtw_acs_adv_setting(_adapter *adapter, RT_SCAN_TYPE scan_type, u16 scan_time, u8 igi, u8 bw)
123 {
124 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
125 	struct auto_chan_sel *pacs = &hal_data->acs;
126 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
127 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
128 
129 	pacs->scan_type = scan_type;
130 	pacs->scan_time = scan_time;
131 	pacs->igi = igi;
132 	pacs->bw = bw;
133 	RTW_INFO("[ACS] ADV setting - scan_type:%c, ch_ms:%d(ms), igi:0x%02x, bw:%d\n",
134 		pacs->scan_type ? 'A' : 'P', pacs->scan_time, pacs->igi, pacs->bw);
135 }
rtw_acs_adv_reset(_adapter * adapter)136 void rtw_acs_adv_reset(_adapter *adapter)
137 {
138 	rtw_acs_adv_setting(adapter, SCAN_ACTIVE, 0, 0, 0);
139 }
140 #endif /*CONFIG_RTW_ACS_DBG*/
141 
rtw_acs_trigger(_adapter * adapter,u16 scan_time_ms,u8 scan_chan,enum NHM_PID pid)142 void rtw_acs_trigger(_adapter *adapter, u16 scan_time_ms, u8 scan_chan, enum NHM_PID pid)
143 {
144 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
145 	struct dm_struct *phydm = adapter_to_phydm(adapter);
146 #if (RTK_ACS_VERSION == 3)
147 	struct clm_para_info clm_para;
148 	struct nhm_para_info nhm_para;
149 	struct env_trig_rpt trig_rpt;
150 
151 	scan_time_ms -= 10;
152 
153 	init_acs_clm(clm_para, scan_time_ms);
154 
155 	if (pid == NHM_PID_IEEE_11K_HIGH)
156 		init_11K_high_nhm(nhm_para, scan_time_ms);
157 	else if (pid == NHM_PID_IEEE_11K_LOW)
158 		init_11K_low_nhm(nhm_para, scan_time_ms);
159 	else
160 		init_acs_nhm(nhm_para, scan_time_ms);
161 
162 	hal_data->acs.trig_rst = phydm_env_mntr_trigger(phydm, &nhm_para, &clm_para, &trig_rpt);
163 	if (hal_data->acs.trig_rst == (NHM_SUCCESS | CLM_SUCCESS)) {
164 		hal_data->acs.trig_rpt.clm_rpt_stamp = trig_rpt.clm_rpt_stamp;
165 		hal_data->acs.trig_rpt.nhm_rpt_stamp = trig_rpt.nhm_rpt_stamp;
166 		/*RTW_INFO("[ACS] trigger success (rst = 0x%02x, clm_stamp:%d, nhm_stamp:%d)\n",
167 			hal_data->acs.trig_rst, hal_data->acs.trig_rpt.clm_rpt_stamp, hal_data->acs.trig_rpt.nhm_rpt_stamp);*/
168 	} else
169 		RTW_ERR("[ACS] trigger failed (rst = 0x%02x)\n", hal_data->acs.trig_rst);
170 #else
171 	phydm_ccx_monitor_trigger(phydm, scan_time_ms);
172 #endif
173 
174 	hal_data->acs.trigger_ch = scan_chan;
175 	hal_data->acs.triggered = _TRUE;
176 
177 	#ifdef CONFIG_RTW_ACS_DBG
178 	RTW_INFO("[ACS] Trigger CH:%d, Times:%d\n", hal_data->acs.trigger_ch, scan_time_ms);
179 	#endif
180 }
rtw_acs_get_rst(_adapter * adapter)181 void rtw_acs_get_rst(_adapter *adapter)
182 {
183 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
184 	struct dm_struct *phydm = adapter_to_phydm(adapter);
185 	int chan_idx = -1;
186 	u8 cur_chan = hal_data->acs.trigger_ch;
187 
188 	if (cur_chan == 0)
189 		return;
190 
191 	if (!hal_data->acs.triggered)
192 		return;
193 
194 	chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), cur_chan);
195 	if ((chan_idx == -1) || (chan_idx >= MAX_CHANNEL_NUM)) {
196 		RTW_ERR("[ACS] %s can't get chan_idx(CH:%d)\n", __func__, cur_chan);
197 		return;
198 	}
199 #if (RTK_ACS_VERSION == 3)
200 	if (!(hal_data->acs.trig_rst == (NHM_SUCCESS | CLM_SUCCESS))) {
201 		RTW_ERR("[ACS] get_rst return, due to acs trigger failed\n");
202 		return;
203 	}
204 
205 	{
206 		struct env_mntr_rpt rpt = {0};
207 		u8 rst;
208 
209 		rst = phydm_env_mntr_result(phydm, &rpt);
210 		if ((rst == (NHM_SUCCESS | CLM_SUCCESS)) &&
211 			(rpt.clm_rpt_stamp == hal_data->acs.trig_rpt.clm_rpt_stamp) &&
212 			(rpt.nhm_rpt_stamp == hal_data->acs.trig_rpt.nhm_rpt_stamp)){
213 			hal_data->acs.clm_ratio[chan_idx] = rpt.clm_ratio;
214 			hal_data->acs.nhm_ratio[chan_idx] =  rpt.nhm_env_ratio;
215 			hal_data->acs.env_mntr_rpt[chan_idx] = (rpt.nhm_noise_pwr -100);
216 			_rtw_memcpy(&hal_data->acs.nhm[chan_idx][0], rpt.nhm_result, NHM_RPT_NUM);
217 
218 			/*RTW_INFO("[ACS] get_rst success (rst = 0x%02x, clm_stamp:%d:%d, nhm_stamp:%d:%d)\n",
219 			rst,
220 			hal_data->acs.trig_rpt.clm_rpt_stamp, rpt.clm_rpt_stamp,
221 			hal_data->acs.trig_rpt.nhm_rpt_stamp, rpt.nhm_rpt_stamp);*/
222 		} else {
223 			RTW_ERR("[ACS] get_rst failed (rst = 0x%02x, clm_stamp:%d:%d, nhm_stamp:%d:%d)\n",
224 			rst,
225 			hal_data->acs.trig_rpt.clm_rpt_stamp, rpt.clm_rpt_stamp,
226 			hal_data->acs.trig_rpt.nhm_rpt_stamp, rpt.nhm_rpt_stamp);
227 		}
228 	}
229 
230 #else
231 	phydm_ccx_monitor_result(phydm);
232 
233 	hal_data->acs.clm_ratio[chan_idx] = rtw_phydm_clm_ratio(adapter);
234 	hal_data->acs.nhm_ratio[chan_idx] = rtw_phydm_nhm_ratio(adapter);
235 #endif
236 	hal_data->acs.triggered = _FALSE;
237 	#ifdef CONFIG_RTW_ACS_DBG
238 	RTW_INFO("[ACS] Result CH:%d, CLM:%d NHM:%d\n",
239 		cur_chan, hal_data->acs.clm_ratio[chan_idx], hal_data->acs.nhm_ratio[chan_idx]);
240 	RTW_INFO("[ACS] Result NHM(dBm):%d\n",
241 		hal_data->acs.env_mntr_rpt[chan_idx] );
242 	#endif
243 }
244 
_rtw_phydm_acs_select_best_chan(_adapter * adapter)245 void _rtw_phydm_acs_select_best_chan(_adapter *adapter)
246 {
247 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
248 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
249 	u8 ch_idx;
250 	u8 ch_idx_24g = 0xFF, ch_idx_5g = 0xFF;
251 	u8 min_itf_24g = 0xFF,  min_itf_5g = 0xFF;
252 	u8 *pbss_nums = hal_data->acs.bss_nums;
253 	u8 *pclm_ratio = hal_data->acs.clm_ratio;
254 	u8 *pnhm_ratio = hal_data->acs.nhm_ratio;
255 	u8 *pinterference_time = hal_data->acs.interference_time;
256 	u8 max_chan_nums = rfctl->max_chan_nums;
257 
258 	for (ch_idx = 0; ch_idx < max_chan_nums; ch_idx++) {
259 		if (pbss_nums[ch_idx])
260 			pinterference_time[ch_idx] = (pclm_ratio[ch_idx] / 2) + (pnhm_ratio[ch_idx] / 2);
261 		else
262 			pinterference_time[ch_idx] = (pclm_ratio[ch_idx] / 3) + ((pnhm_ratio[ch_idx] * 2) / 3);
263 
264 		if (rtw_get_ch_num_by_idx(adapter, ch_idx) < 14) {
265 			if (pinterference_time[ch_idx] < min_itf_24g) {
266 				min_itf_24g = pinterference_time[ch_idx];
267 				ch_idx_24g = ch_idx;
268 			}
269 		} else {
270 			if (pinterference_time[ch_idx] < min_itf_5g) {
271 				min_itf_5g = pinterference_time[ch_idx];
272 				ch_idx_5g = ch_idx;
273 			}
274 		}
275 	}
276 	if (ch_idx_24g != 0xFF)
277 		hal_data->acs.best_chan_24g = rtw_get_ch_num_by_idx(adapter, ch_idx_24g);
278 
279 	if (ch_idx_5g != 0xFF)
280 		hal_data->acs.best_chan_5g = rtw_get_ch_num_by_idx(adapter, ch_idx_5g);
281 
282 	hal_data->acs.trigger_ch = 0;
283 }
284 
rtw_acs_info_dump(void * sel,_adapter * adapter)285 void rtw_acs_info_dump(void *sel, _adapter *adapter)
286 {
287 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
288 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
289 	u8 max_chan_nums = rfctl->max_chan_nums;
290 	u8 ch_idx, ch_num;
291 
292 	_RTW_PRINT_SEL(sel, "========== ACS (VER-%d) ==========\n", RTK_ACS_VERSION);
293 	_RTW_PRINT_SEL(sel, "Best 24G Channel:%d\n", hal_data->acs.best_chan_24g);
294 	_RTW_PRINT_SEL(sel, "Best 5G Channel:%d\n\n", hal_data->acs.best_chan_5g);
295 
296 	#ifdef CONFIG_RTW_ACS_DBG
297 	_RTW_PRINT_SEL(sel, "Advanced setting - scan_type:%c, ch_ms:%d(ms), igi:0x%02x, bw:%d\n",
298 		hal_data->acs.scan_type ? 'A' : 'P', hal_data->acs.scan_time, hal_data->acs.igi, hal_data->acs.bw);
299 
300 	_RTW_PRINT_SEL(sel, "BW  20MHz\n");
301 	_RTW_PRINT_SEL(sel, "%5s  %3s  %3s  %3s(%%)  %3s(%%)  %3s\n",
302 						"Index", "CH", "BSS", "CLM", "NHM", "ITF");
303 
304 	for (ch_idx = 0; ch_idx < max_chan_nums; ch_idx++) {
305 		ch_num = rtw_get_ch_num_by_idx(adapter, ch_idx);
306 		_RTW_PRINT_SEL(sel, "%5d  %3d  %3d  %6d  %6d  %3d\n",
307 						ch_idx, ch_num, hal_data->acs.bss_nums[ch_idx],
308 						hal_data->acs.clm_ratio[ch_idx],
309 						hal_data->acs.nhm_ratio[ch_idx],
310 						hal_data->acs.interference_time[ch_idx]);
311 	}
312 	#endif
313 }
rtw_acs_select_best_chan(_adapter * adapter)314 void rtw_acs_select_best_chan(_adapter *adapter)
315 {
316 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
317 
318 	_rtw_bss_nums_count(adapter, hal_data->acs.bss_nums);
319 	_rtw_phydm_acs_select_best_chan(adapter);
320 	rtw_acs_info_dump(RTW_DBGDUMP, adapter);
321 }
322 
rtw_acs_start(_adapter * adapter)323 void rtw_acs_start(_adapter *adapter)
324 {
325 	rtw_acs_reset(adapter);
326 	if (GET_ACS_STATE(adapter) != ACS_ENABLE)
327 		SET_ACS_STATE(adapter, ACS_ENABLE);
328 }
rtw_acs_stop(_adapter * adapter)329 void rtw_acs_stop(_adapter *adapter)
330 {
331 	SET_ACS_STATE(adapter, ACS_DISABLE);
332 }
333 
334 
rtw_acs_get_clm_ratio_by_ch_num(_adapter * adapter,u8 chan)335 u8 rtw_acs_get_clm_ratio_by_ch_num(_adapter *adapter, u8 chan)
336 {
337 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
338 	int chan_idx = -1;
339 
340 	chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), chan);
341 	if ((chan_idx == -1) || (chan_idx >= MAX_CHANNEL_NUM)) {
342 		RTW_ERR("[ACS] Get CLM fail, can't get chan_idx(CH:%d)\n", chan);
343 		return 0;
344 	}
345 
346 	return hal_data->acs.clm_ratio[chan_idx];
347 }
rtw_acs_get_clm_ratio_by_ch_idx(_adapter * adapter,u8 ch_idx)348 u8 rtw_acs_get_clm_ratio_by_ch_idx(_adapter *adapter, u8 ch_idx)
349 {
350 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
351 
352 	if (ch_idx >= MAX_CHANNEL_NUM) {
353 		RTW_ERR("%s [ACS] ch_idx(%d) is invalid\n", __func__, ch_idx);
354 		return 0;
355 	}
356 
357 	return hal_data->acs.clm_ratio[ch_idx];
358 }
rtw_acs_get_nhm_ratio_by_ch_num(_adapter * adapter,u8 chan)359 u8 rtw_acs_get_nhm_ratio_by_ch_num(_adapter *adapter, u8 chan)
360 {
361 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
362 	int chan_idx = -1;
363 
364 	chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), chan);
365 	if ((chan_idx == -1) || (chan_idx >= MAX_CHANNEL_NUM)) {
366 		RTW_ERR("[ACS] Get NHM fail, can't get chan_idx(CH:%d)\n", chan);
367 		return 0;
368 	}
369 
370 	return hal_data->acs.nhm_ratio[chan_idx];
371 }
rtw_acs_get_nhm_noise_pwr_by_ch_idx(_adapter * adapter,u8 ch_idx)372 u8 rtw_acs_get_nhm_noise_pwr_by_ch_idx(_adapter *adapter, u8 ch_idx)
373 {
374 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
375 
376 	if (ch_idx >= MAX_CHANNEL_NUM) {
377 		RTW_ERR("%s [ACS] ch_idx(%d) is invalid\n", __func__, ch_idx);
378 		return 0;
379 	}
380 
381 	return hal_data->acs.env_mntr_rpt[ch_idx];
382 }
383 
rtw_acs_get_num_ratio_by_ch_idx(_adapter * adapter,u8 ch_idx)384 u8 rtw_acs_get_num_ratio_by_ch_idx(_adapter *adapter, u8 ch_idx)
385 {
386 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
387 
388 	if (ch_idx >= MAX_CHANNEL_NUM) {
389 		RTW_ERR("%s [ACS] ch_idx(%d) is invalid\n", __func__, ch_idx);
390 		return 0;
391 	}
392 
393 	return hal_data->acs.nhm_ratio[ch_idx];
394 }
rtw_acs_chan_info_dump(void * sel,_adapter * adapter)395 void rtw_acs_chan_info_dump(void *sel, _adapter *adapter)
396 {
397 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
398 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
399 	u8 max_chan_nums = rfctl->max_chan_nums;
400 	u8 ch_idx, ch_num;
401 	u8 utilization;
402 
403 	_RTW_PRINT_SEL(sel, "BW  20MHz\n");
404 	_RTW_PRINT_SEL(sel, "%5s  %3s  %7s(%%)  %12s(%%)  %11s(%%)  %9s(%%)  %8s(%%)\n",
405 						"Index", "CH", "Quality", "Availability", "Utilization",
406 						"WIFI Util", "Interference Util");
407 
408 	for (ch_idx = 0; ch_idx < max_chan_nums; ch_idx++) {
409 		ch_num = rtw_get_ch_num_by_idx(adapter, ch_idx);
410 		utilization = hal_data->acs.clm_ratio[ch_idx] + hal_data->acs.nhm_ratio[ch_idx];
411 		_RTW_PRINT_SEL(sel, "%5d  %3d  %7d   %12d   %12d   %12d   %12d\n",
412 						ch_idx, ch_num,
413 						(100-hal_data->acs.interference_time[ch_idx]),
414 						(100-utilization),
415 						utilization,
416 						hal_data->acs.clm_ratio[ch_idx],
417 						hal_data->acs.nhm_ratio[ch_idx]);
418 	}
419 }
rtw_acs_current_info_dump(void * sel,_adapter * adapter)420 void rtw_acs_current_info_dump(void *sel, _adapter *adapter)
421 {
422 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
423 	u8 ch, cen_ch, bw, offset;
424 
425 	_RTW_PRINT_SEL(sel, "========== ACS (VER-%d) ==========\n", RTK_ACS_VERSION);
426 
427 	ch = rtw_get_oper_ch(adapter);
428 	bw = rtw_get_oper_bw(adapter);
429 	offset = rtw_get_oper_choffset(adapter);
430 
431 	_RTW_PRINT_SEL(sel, "Current Channel:%d\n", ch);
432 	if ((bw == CHANNEL_WIDTH_80) ||(bw == CHANNEL_WIDTH_40)) {
433 		cen_ch = rtw_get_center_ch(ch, bw, offset);
434 		_RTW_PRINT_SEL(sel, "Center Channel:%d\n", cen_ch);
435 	}
436 
437 	_RTW_PRINT_SEL(sel, "Current BW %s\n", ch_width_str(bw));
438 	if (0)
439 		_RTW_PRINT_SEL(sel, "Current IGI 0x%02x\n", rtw_phydm_get_cur_igi(adapter));
440 	_RTW_PRINT_SEL(sel, "CLM:%d, NHM:%d\n\n",
441 		hal_data->acs.cur_ch_clm_ratio, hal_data->acs.cur_ch_nhm_ratio);
442 }
443 
rtw_acs_update_current_info(_adapter * adapter)444 void rtw_acs_update_current_info(_adapter *adapter)
445 {
446 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
447 
448 	hal_data->acs.cur_ch_clm_ratio = rtw_phydm_clm_ratio(adapter);
449 	hal_data->acs.cur_ch_nhm_ratio = rtw_phydm_nhm_ratio(adapter);
450 
451 	#ifdef CONFIG_RTW_ACS_DBG
452 	rtw_acs_current_info_dump(RTW_DBGDUMP, adapter);
453 	#endif
454 }
455 /*
456 rsni
457 para1:rcpi=>RSSI in dbm
458 para2:anpi=>nhm in dbm
459 range:0~255
460 255: is not available (defined by 802.11k spec)
461 
462 */
rtw_acs_get_rsni(_adapter * adapter,s8 rcpi,u8 ch)463 u8 rtw_acs_get_rsni(_adapter *adapter, s8 rcpi, u8 ch)
464 {
465 	struct dm_struct *phydm = adapter_to_phydm(adapter);
466 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
467 	u8 rsni = 255;
468 	s8 anpi = 0;
469 	int chan_idx = -1;
470 
471 	if(ch == 0)
472 		goto exit;
473 
474 	chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), ch);
475 	if(chan_idx == -1)
476 		goto exit;
477 
478 	anpi = rtw_acs_get_nhm_noise_pwr_by_ch_idx(adapter, chan_idx);
479 	if((rcpi != 0) && (anpi != 0))
480 	 	rsni = phydm_env_mntr_get_802_11_k_rsni(phydm, rcpi, anpi);
481 	RTW_DBG("[ACS][RSNI]ch=%d chan_idx=%d RSNI=%u RSSI=%d NHM=%d\n", ch, chan_idx, rsni,rcpi, anpi);
482 exit:
483 	return rsni;
484 }
485 #endif /*CONFIG_RTW_ACS*/
486 
487 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
rtw_noise_monitor_version_dump(void * sel,_adapter * adapter)488 void rtw_noise_monitor_version_dump(void *sel, _adapter *adapter)
489 {
490 	_RTW_PRINT_SEL(sel, "RTK_NOISE_MONITOR VER_%d\n", RTK_NOISE_MONITOR_VERSION);
491 }
rtw_nm_enable(_adapter * adapter)492 void rtw_nm_enable(_adapter *adapter)
493 {
494 	SET_NM_STATE(adapter, NM_ENABLE);
495 }
rtw_nm_disable(_adapter * adapter)496 void rtw_nm_disable(_adapter *adapter)
497 {
498 	SET_NM_STATE(adapter, NM_DISABLE);
499 }
rtw_noise_info_dump(void * sel,_adapter * adapter)500 void rtw_noise_info_dump(void *sel, _adapter *adapter)
501 {
502 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
503 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
504 	u8 max_chan_nums = rfctl->max_chan_nums;
505 	u8 ch_idx, ch_num;
506 
507 	_RTW_PRINT_SEL(sel, "========== NM (VER-%d) ==========\n", RTK_NOISE_MONITOR_VERSION);
508 
509 	_RTW_PRINT_SEL(sel, "%5s  %3s  %3s  %10s", "Index", "CH", "BSS", "Noise(dBm)\n");
510 
511 	_rtw_bss_nums_count(adapter, hal_data->nm.bss_nums);
512 
513 	for (ch_idx = 0; ch_idx < max_chan_nums; ch_idx++) {
514 		ch_num = rtw_get_ch_num_by_idx(adapter, ch_idx);
515 		_RTW_PRINT_SEL(sel, "%5d  %3d  %3d  %10d\n",
516 						ch_idx, ch_num, hal_data->nm.bss_nums[ch_idx],
517 						hal_data->nm.noise[ch_idx]);
518 	}
519 }
520 
rtw_noise_measure(_adapter * adapter,u8 chan,u8 is_pause_dig,u8 igi_value,u32 max_time)521 void rtw_noise_measure(_adapter *adapter, u8 chan, u8 is_pause_dig, u8 igi_value, u32 max_time)
522 {
523 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
524 	struct dm_struct *phydm = &hal_data->odmpriv;
525 	int chan_idx = -1;
526 	s16 noise = 0;
527 
528 	#ifdef DBG_NOISE_MONITOR
529 	RTW_INFO("[NM] chan(%d)-PauseDIG:%s,  IGIValue:0x%02x, max_time:%d (ms)\n",
530 		chan, (is_pause_dig) ? "Y" : "N", igi_value, max_time);
531 	#endif
532 
533 	chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), chan);
534 	if ((chan_idx == -1) || (chan_idx >= MAX_CHANNEL_NUM)) {
535 		RTW_ERR("[NM] Get noise fail, can't get chan_idx(CH:%d)\n", chan);
536 		return;
537 	}
538 	noise = odm_inband_noise_monitor(phydm, is_pause_dig, igi_value, max_time); /*dBm*/
539 
540 	hal_data->nm.noise[chan_idx] = noise;
541 
542 	#ifdef DBG_NOISE_MONITOR
543 	RTW_INFO("[NM] %s chan_%d, noise = %d (dBm)\n", __func__, chan, hal_data->nm.noise[chan_idx]);
544 
545 	RTW_INFO("[NM] noise_a = %d, noise_b = %d  noise_all:%d\n",
546 			 phydm->noise_level.noise[RF_PATH_A],
547 			 phydm->noise_level.noise[RF_PATH_B],
548 			 phydm->noise_level.noise_all);
549 	#endif /*DBG_NOISE_MONITOR*/
550 }
551 
rtw_noise_query_by_chan_num(_adapter * adapter,u8 chan)552 s16 rtw_noise_query_by_chan_num(_adapter *adapter, u8 chan)
553 {
554 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
555 	s16 noise = 0;
556 	int chan_idx = -1;
557 
558 	chan_idx = rtw_chset_search_ch(adapter_to_chset(adapter), chan);
559 	if ((chan_idx == -1) || (chan_idx >= MAX_CHANNEL_NUM)) {
560 		RTW_ERR("[NM] Get noise fail, can't get chan_idx(CH:%d)\n", chan);
561 		return noise;
562 	}
563 	noise = hal_data->nm.noise[chan_idx];
564 
565 	#ifdef DBG_NOISE_MONITOR
566 	RTW_INFO("[NM] %s chan_%d, noise = %d (dBm)\n", __func__, chan, noise);
567 	#endif/*DBG_NOISE_MONITOR*/
568 	return noise;
569 }
rtw_noise_query_by_chan_idx(_adapter * adapter,u8 ch_idx)570 s16 rtw_noise_query_by_chan_idx(_adapter *adapter, u8 ch_idx)
571 {
572 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
573 	s16 noise = 0;
574 
575 	if (ch_idx >= MAX_CHANNEL_NUM) {
576 		RTW_ERR("[NM] %s ch_idx(%d) is invalid\n", __func__, ch_idx);
577 		return noise;
578 	}
579 	noise = hal_data->nm.noise[ch_idx];
580 
581 	#ifdef DBG_NOISE_MONITOR
582 	RTW_INFO("[NM] %s ch_idx %d, noise = %d (dBm)\n", __func__, ch_idx, noise);
583 	#endif/*DBG_NOISE_MONITOR*/
584 	return noise;
585 }
586 
rtw_noise_measure_curchan(_adapter * padapter)587 s16 rtw_noise_measure_curchan(_adapter *padapter)
588 {
589 	s16 noise = 0;
590 	u8 igi_value = 0x1E;
591 	u32 max_time = 100;/* ms */
592 	u8 is_pause_dig = _TRUE;
593 	u8 cur_chan = rtw_get_oper_ch(padapter);
594 
595 	if (rtw_linked_check(padapter) == _FALSE)
596 		return noise;
597 
598 	rtw_ps_deny(padapter, PS_DENY_IOCTL);
599 	LeaveAllPowerSaveModeDirect(padapter);
600 	rtw_noise_measure(padapter, cur_chan, is_pause_dig, igi_value, max_time);
601 	noise = rtw_noise_query_by_chan_num(padapter, cur_chan);
602 	rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
603 
604 	return noise;
605 }
606 #endif /*CONFIG_BACKGROUND_NOISE_MONITOR*/
607 
608