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