xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/phl/hal_g6/phy/bb/halbb.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2020  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  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25 #include "halbb_precomp.h"
26 
halbb_supportability_dbg(struct bb_info * bb,char input[][16],u32 * _used,char * output,u32 * _out_len)27 void halbb_supportability_dbg(struct bb_info *bb, char input[][16], u32 *_used,
28 			     char *output, u32 *_out_len)
29 {
30 	u32 val[10] = {0};
31 	u64 pre_support_ability, one = 1;
32 	u64 comp = 0;
33 	u32 used = *_used;
34 	u32 out_len = *_out_len;
35 	u8 i;
36 
37 	for (i = 0; i < 5; i++) {
38 		if (input[i + 1])
39 			HALBB_SCAN(input[i + 1], DCMD_DECIMAL, &val[i]);
40 	}
41 
42 	pre_support_ability = bb->support_ability;
43 	comp = bb->support_ability;
44 
45 	BB_DBG_CNSL(out_len, used, output + used, out_len - used,
46 		 "\n================================\n");
47 
48 	if (val[0] == 100) {
49 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
50 			 "[Supportability] Selection\n");
51 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
52 			 "================================\n");
53 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
54 			 "00. (( %s ))RA\n",
55 			 ((comp & BB_RA) ? ("V") : (".")));
56 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
57 			 "01. (( %s ))FA_CNT\n",
58 			 ((comp & BB_FA_CNT) ? ("V") : (".")));
59 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
60 			 "02. (( %s ))RSSI_MNTR\n",
61 			 ((comp & HALBB_FUN_RSVD_2) ? ("V") : (".")));
62 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
63 			 "03. (( %s ))DFS\n",
64 			 ((comp & BB_DFS) ? ("V") : (".")));
65 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
66 			 "04. (( %s ))EDCCA\n",
67 			 ((comp & BB_EDCCA) ? ("V") : (".")));
68 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
69 			 "05. (( %s ))ENV_MNTR\n",
70 			 ((comp & BB_ENVMNTR) ? ("V") : (".")));
71 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
72 			 "06. (( %s ))CFO_TRK\n",
73 			 ((comp & BB_CFO_TRK) ? ("V") : (".")));
74 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
75 			 "07. (( %s ))PWR_CTRL\n",
76 			 ((comp & BB_PWR_CTRL) ? ("V") : (".")));
77 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
78 			 "10. (( %s ))ANT_DIV\n",
79 			 ((comp & DBG_ANT_DIV) ? ("V") : (".")));
80 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
81 			 "11. (( %s ))DIG\n",
82 			 ((comp & BB_DIG) ? ("V") : (".")));
83 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
84 			 "13. (( %s ))UL_TB_CTRL\n",
85 			 ((comp & BB_UL_TB_CTRL) ? ("V") : (".")));
86 
87 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
88 			 "31. (( %s ))Dyn CSI RSP\n",
89 			 ((comp & BB_DCR) ? ("V") : (".")));
90 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
91 			 "================================\n");
92 
93 	} else if (val[0] == 101) {
94 		bb->support_ability = 0;
95 		BB_DBG_CNSL(out_len, used, output + used, out_len - used,
96 			 "Disable all support_ability components\n");
97 	} else {
98 		if (val[1] == 1) { /* @enable */
99 			bb->support_ability |= (one << val[0]);
100 		} else if (val[1] == 2) {/* @disable */
101 			bb->support_ability &= ~(one << val[0]);
102 		} else {
103 			BB_DBG_CNSL(out_len, used, output + used, out_len - used,
104 				 "[Warning!!!]  1:enable,  2:disable\n");
105 		}
106 	}
107 	BB_DBG_CNSL(out_len, used, output + used, out_len - used,
108 		 "pre-supportability = 0x%llx\n", pre_support_ability);
109 	BB_DBG_CNSL(out_len, used, output + used, out_len - used,
110 		 "Cur-supportability = 0x%llx\n", bb->support_ability);
111 	BB_DBG_CNSL(out_len, used, output + used, out_len - used,
112 		 "================================\n");
113 
114 	*_used = used;
115 	*_out_len = out_len;
116 }
117 
halbb_sta_info_init(struct bb_info * bb,struct rtw_phl_stainfo_t * phl_sta_info)118 bool halbb_sta_info_init(struct bb_info *bb,
119 			 struct rtw_phl_stainfo_t *phl_sta_info)
120 {
121 	struct bb_sta_info *bb_sta;
122 
123 	if (!bb) {
124 		BB_WARNING("[%s]*bb = NULL\n", __func__);
125 		return false;
126 	}
127 
128 	if (!phl_sta_info)
129 		return false;
130 
131 	if (!phl_sta_info->hal_sta)
132 		return false;
133 
134 	bb_sta = halbb_mem_alloc(bb, sizeof(struct bb_sta_info));
135 
136 	if (!bb_sta) {
137 		BB_WARNING("*bb_sta = NULL\n");
138 		return RTW_HAL_STATUS_BB_INIT_FAILURE;
139 	}
140 	phl_sta_info->hal_sta->bb_sta = (void *)bb_sta;
141 
142 	return true;
143 }
144 
halbb_sta_info_deinit(struct bb_info * bb,struct rtw_phl_stainfo_t * phl_sta_info)145 bool halbb_sta_info_deinit(struct bb_info *bb,
146 			   struct rtw_phl_stainfo_t *phl_sta_info)
147 {
148 	if (!bb) {
149 		BB_WARNING("*bb = NULL\n");
150 		return false;
151 	}
152 
153 	if (!phl_sta_info)
154 		return false;
155 
156 	if (!phl_sta_info->hal_sta)
157 		return false;
158 
159 	if (!phl_sta_info->hal_sta->bb_sta)
160 		return false;
161 
162 	halbb_mem_free(bb, phl_sta_info->hal_sta->bb_sta, sizeof(struct bb_sta_info));
163 	return true;
164 }
165 
halbb_sta_info_add_entry(struct bb_info * bb,struct rtw_phl_stainfo_t * phl_sta_info)166 bool halbb_sta_info_add_entry(struct bb_info *bb,
167 				      struct rtw_phl_stainfo_t *phl_sta_info)
168 {
169 	if (!bb) {
170 		BB_WARNING("[%s]*bb = NULL\n", __func__);
171 		return false;
172 	}
173 
174 	if (!phl_sta_info)
175 		return false;
176 
177 	if ((phl_sta_info->macid) >= PHL_MAX_STA_NUM)
178 		return false;
179 
180 	bb->phl2bb_macid_table[phl_sta_info->macid] = (u8)phl_sta_info->macid;
181 	bb->phl_sta_info[phl_sta_info->macid] = phl_sta_info;
182 
183 	return true;
184 }
185 
halbb_sta_info_delete_entry(struct bb_info * bb,struct rtw_phl_stainfo_t * phl_sta_info)186 bool halbb_sta_info_delete_entry(struct bb_info *bb,
187 					struct rtw_phl_stainfo_t *phl_sta_info)
188 {
189 	if (!bb) {
190 		BB_WARNING("*bb = NULL\n");
191 		return false;
192 	}
193 
194 	if (!phl_sta_info)
195 		return false;
196 
197 	if ((phl_sta_info->macid) >= PHL_MAX_STA_NUM)
198 		return false;
199 
200 	if (!phl_sta_info->hal_sta)
201 			return false;
202 
203 	if (!phl_sta_info->hal_sta->bb_sta)
204 		return false;
205 
206 	bb->sta_exist[phl_sta_info->macid] = false;
207 	bb->phl_sta_info[phl_sta_info->macid] = NULL;
208 
209 	return true;
210 }
211 
halbb_media_status_update(struct bb_info * bb,struct rtw_phl_stainfo_t * phl_sta_info,bool is_connected)212 void halbb_media_status_update(struct bb_info *bb,
213 			       struct rtw_phl_stainfo_t *phl_sta_info,
214 			       bool is_connected)
215 {
216 	bb->sta_exist[phl_sta_info->macid] = is_connected;
217 
218 	/*Reset MA RSSI*/
219 	if (!is_connected) {
220 		phl_sta_info->hal_sta->rssi_stat.rssi = 0;
221 		phl_sta_info->hal_sta->rssi_stat.rssi_ma = 0;
222 		phl_sta_info->hal_sta->rssi_stat.rssi_ma_path[0] = 0;
223 		phl_sta_info->hal_sta->rssi_stat.rssi_ma_path[1] = 0;
224 		phl_sta_info->hal_sta->rssi_stat.rssi_ma_path[2] = 0;
225 		phl_sta_info->hal_sta->rssi_stat.rssi_ma_path[3] = 0;
226 		phl_sta_info->hal_sta->rssi_stat.pkt_cnt_data = 0;
227 		phl_sta_info->hal_sta->rssi_stat.rssi_bcn = 0;
228 		phl_sta_info->hal_sta->rssi_stat.rssi_bcn_ma = 0;
229 		phl_sta_info->hal_sta->rssi_stat.rssi_bcn_ma_path[0] = 0;
230 		phl_sta_info->hal_sta->rssi_stat.rssi_bcn_ma_path[1] = 0;
231 		phl_sta_info->hal_sta->rssi_stat.rssi_bcn_ma_path[2] = 0;
232 		phl_sta_info->hal_sta->rssi_stat.rssi_bcn_ma_path[3] = 0;
233 		phl_sta_info->hal_sta->rssi_stat.pkt_cnt_bcn = 0;
234 		phl_sta_info->hal_sta->rssi_stat.rssi_ofdm = 0;
235 		phl_sta_info->hal_sta->rssi_stat.rssi_cck = 0;
236 		phl_sta_info->hal_sta->rssi_stat.snr_ma = 0;
237 	} else {
238 		phl_sta_info->hal_sta->rssi_stat.ma_factor = RSSI_MA_L;
239 		phl_sta_info->hal_sta->rssi_stat.ma_factor_bcn = RSSI_MA_L;
240 	}
241 }
242 
halbb_sta_info_dbg(struct bb_info * bb,char input[][16],u32 * _used,char * output,u32 * _out_len)243 void halbb_sta_info_dbg(struct bb_info *bb, char input[][16], u32 *_used,
244 			char *output, u32 *_out_len)
245 {
246 	struct rtw_hal_com_t *hal = bb->hal_com;
247 	struct rtw_phl_stainfo_t *phl_sta;
248 	struct rtw_rssi_info *rssi_t = NULL;
249 	struct rtw_ra_sta_info	*ra;
250 	char dbg_buf[HALBB_SNPRINT_SIZE] = {0};
251 	u32 val[10] = {0};
252 	u32 tmp = 0;
253 	u16 curr_tx_rt = 0;
254 	u8 i = 0, j = 0;
255 
256 	if (_os_strcmp(input[1], "-h") == 0) {
257 		BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
258 			 "all\n");
259 		return;
260 	}
261 
262 	if (_os_strcmp(input[1], "all") == 0) {
263 
264 		BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
265 			 " Assoc_sta_cnt=%d\n\n", hal->assoc_sta_cnt);
266 		for (i = 0; i < PHL_MAX_STA_NUM; i++) {
267 			if (!bb->sta_exist[i])
268 				continue;
269 
270 			phl_sta = bb->phl_sta_info[i];
271 
272 			if (!is_sta_active(phl_sta))
273 				continue;
274 
275 			BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
276 				    "[%d][active=%d] PHL_macid=%d =====================\n",
277 				    i, phl_sta->active, phl_sta->macid);
278 
279 			rssi_t = &phl_sta->hal_sta->rssi_stat;
280 
281 			halbb_print_sign_frac_digit(bb, rssi_t->rssi_ma, 16, 5, dbg_buf, HALBB_SNPRINT_SIZE_S);
282 			BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
283 				    "[Data] rssi_avg=%s, MA=1/%02d\n",
284 				    dbg_buf, 1 << rssi_t->ma_factor);
285 
286 			for (j = 0; j < HALBB_MAX_PATH; j++) {
287 				halbb_print_sign_frac_digit(bb, rssi_t->rssi_ma_path[j], 16, 5, dbg_buf, HALBB_SNPRINT_SIZE_S);
288 				BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
289 					    "       rssi[%d]= %s\n", j, dbg_buf);
290 			}
291 
292 			halbb_print_sign_frac_digit(bb, rssi_t->rssi_bcn_ma, 16, 5, dbg_buf, HALBB_SNPRINT_SIZE_S);
293 			BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
294 				    "[Bcn]  rssi_avg=%s, MA=1/%02d\n",
295 				    dbg_buf, 1 << rssi_t->ma_factor_bcn);
296 
297 
298 			for (j = 0; j < HALBB_MAX_PATH; j++) {
299 				halbb_print_sign_frac_digit(bb, rssi_t->rssi_bcn_ma_path[j], 16, 5, dbg_buf, HALBB_SNPRINT_SIZE_S);
300 				BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
301 					    "       rssi[%d]= %s\n", j, dbg_buf);
302 			}
303 
304 			BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
305 				    "rssi_cck=%02d.%d, rssi_ofdm=%02d.%d\n",
306 				    rssi_t->rssi_cck >> 1, (rssi_t->rssi_cck & 1) * 5,
307 				    rssi_t->rssi_ofdm >> 1, (rssi_t->rssi_ofdm & 1) * 5);
308 
309 			halbb_print_sign_frac_digit(bb, rssi_t->snr_ma, 16, 4, dbg_buf, HALBB_SNPRINT_SIZE_S);
310 			BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
311 				    "SNR_avg=%s dB\n", dbg_buf);
312 
313 			ra = &phl_sta->hal_sta->ra_info;
314 			curr_tx_rt = (u16)(ra->rpt_rt_i.mcs_ss_idx) | ((u16)(ra->rpt_rt_i.mode) << 7);
315 
316 			halbb_print_rate_2_buff(bb, curr_tx_rt, ra->rpt_rt_i.gi_ltf, bb->dbg_buf, HALBB_SNPRINT_SIZE);
317 			BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
318 				    "Tx_Rate=%s (0x%x-%d), PER=(%d), TXBW=(%d)\n",
319 				    bb->dbg_buf, curr_tx_rt, ra->rpt_rt_i.gi_ltf,
320 				    ra->curr_retry_ratio, (20 << ra->rpt_rt_i.bw));
321 
322 			BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
323 				    "======================================\n");
324 
325 		}
326 	}
327 }
328 
halbb_traffic_load_decision(struct bb_info * bb)329 void halbb_traffic_load_decision(struct bb_info *bb)
330 {
331 	struct rtw_stats *stat = &bb->phl_com->phl_stats;
332 	struct bb_link_info *link = &bb->bb_link_i;
333 	u32 max_tp; /*Mbps*/
334 
335 	/*@---TP & Trafic-load caln---*/
336 	link->tx_tp = KB_2_MB(stat->tx_tp_kbits);
337 	link->rx_tp = KB_2_MB(stat->rx_tp_kbits);
338 	link->total_tp = link->tx_tp + link->rx_tp;
339 	max_tp = MAX_2(link->tx_tp, link->rx_tp); /*Mbps*/
340 
341 	BB_DBG(bb, DBG_COMMON_FLOW,
342 		"byte_uni{tx,rx}={%llu,%llu}, byte_total{tx,rx}={%llu,%llu}\n",
343 		stat->tx_byte_uni, stat->rx_byte_uni,
344 		stat->tx_byte_total, stat->rx_byte_total);
345 
346 	BB_DBG(bb, DBG_COMMON_FLOW,
347 		"TP_kbit{tx,rx}={%d,%d}, TP_MA{tx,rx}={%d,%d}\n",
348 		stat->tx_tp_kbits, stat->rx_tp_kbits,
349 		stat->tx_moving_average_tp, stat->rx_moving_average_tp);
350 
351 	/*@[Calculate TX/RX state]*/
352 	if (link->tx_tp > (link->rx_tp << 1))
353 		link->txrx_state_all = BB_TX_STATE;
354 	else if (link->rx_tp > (link->tx_tp << 1))
355 		link->txrx_state_all = BB_RX_STATE;
356 	else
357 		link->txrx_state_all = BB_BI_DIR_STATE;
358 
359 	/*@[Traffic load decision]*/
360 	link->traffic_load_pre = link->traffic_load;
361 
362 	if (max_tp > 20) {
363 		link->traffic_load = TRAFFIC_HIGH;
364 	} else if (max_tp > 5) {
365 		link->traffic_load = TRAFFIC_MID;
366 	} else if (max_tp > 1) {
367 		link->traffic_load = TRAFFIC_LOW;
368 	} else if (stat->tx_tp_kbits > 100 || stat->rx_tp_kbits > 100) { /*100Kb*/
369 		link->traffic_load = TRAFFIC_ULTRA_LOW;
370 	} else {
371 		link->traffic_load = TRAFFIC_NO_TP;
372 	}
373 
374 	/*@[Calculate consecutive idlel time]*/
375 	if (link->traffic_load == TRAFFIC_NO_TP)
376 		link->consecutive_idle_time = 0;
377 	else
378 		link->consecutive_idle_time += HALBB_WATCHDOG_PERIOD;
379 }
380 
halbb_cmn_info_self_reset(struct bb_info * bb)381 void halbb_cmn_info_self_reset(struct bb_info *bb) {
382 
383 	struct bb_link_info *link = &bb->bb_link_i;
384 
385 	bb->bb_ch_i.rssi_max = 0;
386 	bb->bb_ch_i.rssi_min = 0;
387 
388 	link->is_one_entry_only = false;
389 	link->one_entry_macid = 0;
390 	link->one_entry_tp = 0;
391 	link->one_entry_tp_active_occur = false;
392 	link->one_entry_tp_pre = 0;
393 	link->num_linked_client_pre = 0;
394 	link->num_active_client_pre = 0;
395 	link->num_linked_client = 0;
396 	link->num_active_client = 0;
397 }
398 
halbb_get_rssi_min(struct bb_info * bb)399 u8 halbb_get_rssi_min(struct bb_info *bb)
400 {
401 	struct rtw_hal_com_t *hal = bb->hal_com;
402 	struct rtw_phl_stainfo_t *sta;
403 	struct rtw_rssi_info *sta_rssi = NULL;
404 	u8 sta_cnt = 0;
405 	u8 rssi_min = 0xff, rssi_curr = 0;
406 	u32 i = 0;
407 
408 	if (hal->assoc_sta_cnt == 0) {
409 		BB_WARNING("[%s] assoc_sta_cnt=0\n", __func__);
410 		return 0;
411 	}
412 
413 	for (i = 0; i < PHL_MAX_STA_NUM; i++) {
414 		if (!bb->sta_exist[i])
415 			continue;
416 
417 		sta = bb->phl_sta_info[i];
418 
419 		if (!is_sta_active(sta))
420 			continue;
421 
422 		BB_DBG(bb, DBG_COMMON_FLOW, "[%d] macid=%d\n", i, sta->macid);
423 
424 		sta_cnt++;
425 
426 		sta_rssi = &sta->hal_sta->rssi_stat;
427 
428 		if (sta_rssi->rssi != 0)
429 			rssi_curr = sta_rssi->rssi;
430 		else
431 			rssi_curr = sta_rssi->rssi_bcn;
432 
433 		/*[RSSI min]*/
434 		if (rssi_curr <= rssi_min) {
435 			rssi_min = rssi_curr;
436 		}
437 
438 		BB_DBG(bb, DBG_COMMON_FLOW,
439 		       "rssi_min = %d", rssi_min);
440 
441 		if (sta_cnt >= hal->assoc_sta_cnt)
442 			break;
443 	}
444 
445 	if (sta_cnt == 0) {
446 		BB_WARNING("[%s] sta_cnt=0\n", __func__);
447 		return 0;
448 	}
449 
450 	return rssi_min;
451 }
452 
halbb_cmn_info_self_update(struct bb_info * bb)453 void halbb_cmn_info_self_update(struct bb_info *bb)
454 {
455 	struct rtw_hal_com_t *hal = bb->hal_com;
456 	struct bb_link_info *link = &bb->bb_link_i;
457 	struct rtw_phl_com_t *phl = bb->phl_com;
458 	struct dev_cap_t *dev = &phl->dev_cap;
459 	struct rtw_phl_stainfo_t *sta;
460 	struct rtw_rssi_info *sta_rssi = NULL;
461 	struct halbb_mcc_dm *mcc_dm = &bb->mcc_dm;
462 	u8 sta_cnt = 0, num_active_client = 0;
463 	u8 rssi_min = 0xff, rssi_max = 0, rssi_curr = 0;
464 	u8 mcc_rssi_min[MCC_BAND_NUM], mcc_sta_cnt[MCC_BAND_NUM];
465 	u8 j = 0, band_idx = MCC_BAND_NUM, role_ch = 0;
466 	u32 i = 0, one_entry_macid_tmp = 0;
467 	u32 trx_tp = 0;
468 	u32 tp_diff = 0;
469 
470 	/*[Link Status Check]*/
471 	link->is_linked = (hal->assoc_sta_cnt != 0) ? true : false;
472 	link->first_connect = link->is_linked && !link->is_linked_pre;
473 	link->first_disconnect = !link->is_linked && link->is_linked_pre;
474 	link->is_linked_pre = link->is_linked;
475 
476 	BB_DBG(bb, DBG_COMMON_FLOW, "is_linked = %d, 1st_connect=%d, 1st_disconnect=%d, assoc_sta_cnt=%d\n",
477 	       link->is_linked, link->first_connect,
478 	       link->first_disconnect, hal->assoc_sta_cnt);
479 
480 	/*[Traffic load information]*/
481 	halbb_traffic_load_decision(bb);
482 
483 	link->rx_rate_plurality = halbb_get_plurality_rx_rate_su(bb);
484 	link->rx_rate_plurality_mu = halbb_get_plurality_rx_rate_mu(bb);
485 
486 	if (!link->is_linked) {
487 		if (link->first_disconnect)
488 			halbb_cmn_info_self_reset(bb);
489 
490 		return;
491 	}
492 
493 	if (mcc_dm->mcc_status_en) {
494 		for (i = 0; i < MCC_BAND_NUM; i++) {
495 			mcc_rssi_min[i] = rssi_min;
496 			mcc_sta_cnt[i] = 0;
497 		}
498 	}
499 
500 	bb->bb_ch_i.pre_rssi_min = bb->bb_ch_i.rssi_min;
501 
502 	for (i = 0; i < PHL_MAX_STA_NUM; i++) {
503 		if (!bb->sta_exist[i])
504 			continue;
505 
506 		sta = bb->phl_sta_info[i];
507 
508 		if (!is_sta_active(sta))
509 			continue;
510 
511 		if ((dev->rfe_type >= 50) && (sta->macid == 0))
512 			continue;
513 
514 		BB_DBG(bb, DBG_COMMON_FLOW, "[%d] macid=%d\n", i, sta->macid);
515 
516 		sta_cnt++;
517 
518 		if (sta_cnt == 1)
519 			one_entry_macid_tmp = i;
520 
521 		trx_tp = KB_2_MB(sta->stats.tx_tp_kbits +
522 				 sta->stats.rx_tp_kbits); /*Mbit*/
523 
524 		sta_rssi = &sta->hal_sta->rssi_stat;
525 
526 		if (bb->bb_watchdog_mode != BB_WATCHDOG_NORMAL) {
527 			rssi_curr = sta_rssi->rssi_bcn;
528 		} else {
529 			if (sta_rssi->rssi == 0 && sta_rssi->rssi_bcn != 0)
530 				rssi_curr = sta_rssi->rssi_bcn;
531 			else
532 				rssi_curr = sta_rssi->rssi;
533 		}
534 
535 		if (sta_rssi->pkt_cnt_data > 100)
536 			sta_rssi->ma_factor = RSSI_MA_H;
537 		else if (sta_rssi->pkt_cnt_data > 20)
538 			sta_rssi->ma_factor = RSSI_MA_M;
539 		else if (sta_rssi->pkt_cnt_data > 5)
540 			sta_rssi->ma_factor = RSSI_MA_L;
541 		else
542 			sta_rssi->ma_factor = RSSI_MA_UL;
543 
544 		if (sta_rssi->pkt_cnt_bcn > 5)
545 			sta_rssi->ma_factor_bcn = RSSI_MA_L;
546 		else
547 			sta_rssi->ma_factor_bcn = RSSI_MA_UL;
548 
549 		BB_DBG(bb, DBG_COMMON_FLOW,
550 		       "pkt_cnt_data=%d, pkt_cnt_bcn=%d, ma_factor=%d, ma_factor_bcn=%d\n",
551 		       sta_rssi->pkt_cnt_data, sta_rssi->pkt_cnt_bcn,
552 		       sta_rssi->ma_factor, sta_rssi->ma_factor_bcn);
553 
554 		sta_rssi->pkt_cnt_data = 0;
555 		sta_rssi->pkt_cnt_bcn = 0;
556 
557 		BB_DBG(bb, DBG_COMMON_FLOW,
558 		       "rssi = %d, rssi_ma = %d",
559 		       sta->hal_sta->rssi_stat.rssi,
560 		       sta->hal_sta->rssi_stat.rssi_ma);
561 
562 		/*[RSSI min]*/
563 		if (rssi_curr <= rssi_min) {
564 			bb->bb_ch_i.rssi_min = rssi_curr;
565 			bb->bb_ch_i.rssi_min_macid = sta->macid;
566 			rssi_min = rssi_curr;
567 		}
568 		/*[RSSI max]*/
569 		if (rssi_curr >= rssi_max) {
570 			bb->bb_ch_i.rssi_max = rssi_curr;
571 			bb->bb_ch_i.rssi_max_macid = sta->macid;
572 			rssi_max = rssi_curr;
573 		}
574 
575 		//BB_DBG(bb, DBG_COMMON_FLOW, "TP: TRX=%d Mb/sec\n", trx_tp);
576 
577 		//BB_DBG(bb, DBG_COMMON_FLOW, "TP: TX=%d, RX=%d, kb/sec\n",
578 		//       sta->stats.tx_tp_kbits, sta->stats.rx_tp_kbits);
579 
580 		BB_DBG(bb, DBG_COMMON_FLOW,
581 		       "rssi_min = %d, rssi_max = %d", rssi_min, rssi_max);
582 
583 		if (mcc_dm->mcc_status_en) {
584 			if (i == mcc_dm->softap_macid)
585 				continue;
586 
587 			band_idx = MCC_BAND_NUM;
588 			role_ch = sta->wrole->chandef.center_ch;
589 
590 			for (j = 0; j < MCC_BAND_NUM; j++) {
591 				if (mcc_dm->mcc_rf_ch[j].center_ch == role_ch) {
592 					band_idx = j;
593 					break;
594 				}
595 			}
596 
597 			if (band_idx == MCC_BAND_NUM) {
598 				BB_WARNING("%s, band_idx = %d", __func__,
599 					   band_idx);
600 				continue;
601 			}
602 
603 			if (rssi_curr <= mcc_rssi_min[band_idx])
604 				mcc_rssi_min[band_idx] = rssi_curr;
605 
606 			mcc_sta_cnt[band_idx]++;
607 		}
608 
609 		if (trx_tp > ACTIVE_TP_THRESHOLD)
610 			num_active_client++;
611 
612 		if (sta_cnt >= bb->hal_com->assoc_sta_cnt)
613 			break;
614 	}
615 
616 	if (mcc_dm->mcc_status_en) {
617 		for (i = 0; i < MCC_BAND_NUM; i++) {
618 			mcc_dm->rssi_min[i] = mcc_rssi_min[i];
619 			mcc_dm->sta_cnt[i] = mcc_sta_cnt[i];
620 		}
621 	}
622 
623 
624 	link->is_one_entry_only = (hal->assoc_sta_cnt == 1) ? true : false;
625 
626 	if (link->is_one_entry_only) {
627 		link->one_entry_macid = one_entry_macid_tmp;
628 		link->one_entry_tp = trx_tp;
629 		link->one_entry_tp_active_occur = false;
630 
631 		//BB_DBG(bb, DBG_COMMON_FLOW, "one_entry_tp=((%d)), one_entry_tp_pre=((%d))\n",
632 		//	  link->one_entry_tp, link->one_entry_tp_pre);
633 
634 		if (link->one_entry_tp > link->one_entry_tp_pre &&
635 		    link->one_entry_tp_pre <= 2) {
636 			tp_diff = link->one_entry_tp - link->one_entry_tp_pre;
637 
638 			if (tp_diff > link->tp_active_th)
639 				link->one_entry_tp_active_occur = true;
640 		}
641 
642 		link->one_entry_tp_pre = link->one_entry_tp;
643 	}
644 
645 	link->num_linked_client_pre = link->num_linked_client;
646 	link->num_active_client_pre = link->num_active_client;
647 	link->num_linked_client = sta_cnt;
648 	link->num_active_client = num_active_client;
649 }
650 
halbb_watchdog_reset(struct bb_info * bb)651 void halbb_watchdog_reset(struct bb_info *bb)
652 {
653 
654 }
655 
halbb_update_hal_info(struct bb_info * bb)656 void halbb_update_hal_info(struct bb_info *bb)
657 {
658 	struct rtw_hal_com_t *hal = bb->hal_com;
659 
660 	hal->trx_stat.rx_rate_plurality = bb->bb_link_i.rx_rate_plurality;
661 }
662 
halbb_store_data(struct bb_info * bb)663 void halbb_store_data(struct bb_info *bb)
664 {
665 	halbb_cmn_info_rpt_store_data(bb);
666 }
667 
halbb_reset(struct bb_info * bb)668 void halbb_reset(struct bb_info *bb)
669 {
670 	halbb_store_data(bb);
671 	#ifdef HALBB_STATISTICS_SUPPORT
672 	halbb_statistics_reset(bb);
673 	#endif
674 	halbb_cmn_info_rpt_reset(bb);
675 }
676 
halbb_watchdog_normal(struct bb_info * bb,enum phl_phy_idx phy_idx)677 void halbb_watchdog_normal(struct bb_info *bb, enum phl_phy_idx phy_idx)
678 {
679 	halbb_cmn_info_self_update(bb);
680 	halbb_ic_hw_setting(bb);
681 	#ifdef HALBB_ENV_MNTR_SUPPORT
682 	halbb_env_mntr(bb);
683 	#endif
684 	#ifdef HALBB_DIG_SUPPORT
685 	halbb_dig(bb);
686 	#endif
687 	#ifdef HALBB_STATISTICS_SUPPORT
688 	halbb_statistics(bb);
689 	#endif
690 	halbb_basic_dbg_message(bb);
691 	halbb_physts_watchdog(bb);
692 
693 	if (!bb->adv_bb_dm_en) {
694 		BB_DBG(bb, DBG_COMMON_FLOW, "Disable adv halbb dm\n");
695 		halbb_reset(bb);
696 		return;
697 	}
698 
699 	#ifdef HALBB_EDCCA_SUPPORT
700 	halbb_edcca(bb);
701 	#endif
702 	#ifdef HALBB_DFS_SUPPORT
703 	halbb_dfs(bb);
704 	#endif
705 	#ifdef HALBB_CFO_TRK_SUPPORT
706 	halbb_cfo_watchdog(bb);
707 	#endif
708 	#ifdef HALBB_UL_TB_CTRL_SUPPORT
709 	halbb_ul_tb_ctrl(bb);
710 	#endif
711 	#ifdef HALBB_RA_SUPPORT
712 	halbb_ra_watchdog(bb);
713 	#endif
714 	#ifdef HALBB_PWR_CTRL_SUPPORT
715 	halbb_pwr_ctrl(bb);
716 	#endif
717 	#ifdef HALBB_LA_MODE_SUPPORT
718 	halbb_la_re_trig_watchdog(bb);
719 	#endif
720 	#ifdef HALBB_ANT_DIV_SUPPORT
721 	halbb_antenna_diversity(bb);
722 	#endif
723 	halbb_update_hal_info(bb);
724 	#ifdef HALBB_DIG_MCC_SUPPORT
725 	halbb_mccdm_switch(bb);
726 	#endif
727 	/*[Rest all counter]*/
728 	halbb_reset(bb);
729 }
730 
halbb_watchdog_low_io(struct bb_info * bb,enum phl_phy_idx phy_idx)731 void halbb_watchdog_low_io(struct bb_info *bb, enum phl_phy_idx phy_idx)
732 {
733 	halbb_cmn_info_self_update(bb);
734 	halbb_ic_hw_setting_low_io(bb);
735 	halbb_basic_dbg_message(bb);
736 	#ifdef HALBB_DIG_SUPPORT
737 	halbb_dig_lps(bb);
738 	#endif
739 
740 	#ifdef HALBB_RA_SUPPORT
741 	halbb_ra_watchdog(bb);
742 	#endif
743 
744 	#if 0//def HALBB_EDCCA_SUPPORT
745 	halbb_edcca(bb);
746 	#endif
747 
748 	#if 0//def HALBB_DFS_SUPPORT
749 	halbb_dfs(bb);
750 	#endif
751 	/*[Rest all counter]*/
752 	halbb_reset(bb);
753 }
754 
halbb_watchdog_non_io(struct bb_info * bb,enum phl_phy_idx phy_idx)755 void halbb_watchdog_non_io(struct bb_info *bb, enum phl_phy_idx phy_idx)
756 {
757 	halbb_cmn_info_self_update(bb);
758 	halbb_ic_hw_setting_non_io(bb);
759 	halbb_basic_dbg_message(bb);
760 	/*[Rest all counter]*/
761 	halbb_reset(bb);
762 }
763 
halbb_watchdog(struct bb_info * bb,enum bb_watchdog_mode_t mode,enum phl_phy_idx phy_idx)764 void halbb_watchdog(struct bb_info *bb, enum bb_watchdog_mode_t mode, enum phl_phy_idx phy_idx)
765 {
766 
767 #ifdef HALBB_DBCC_SUPPORT
768 	#ifdef HALBB_DBCC_DVLP_FLAG
769 	if (phy_idx == HW_PHY_1)
770 		return;
771 	#endif
772 	bb = halbb_get_curr_bb_pointer(bb, phy_idx);
773 	BB_DBG(bb, DBG_COMMON_FLOW, "[%s] phy_idx=%d\n", __func__, bb->bb_phy_idx);
774 #endif
775 
776 	bb->bb_sys_up_time += BB_WATCH_DOG_PERIOD;
777 
778 	if ((bb->bb_sys_up_time % bb->bb_watchdog_period) != 0)
779 		return;
780 
781 	if (bb->bb_dbg_i.cr_recorder_en)
782 		BB_TRACE("[%s] up_time:%d \n", __func__, bb->bb_sys_up_time);
783 
784 	bb->bb_watchdog_mode = mode;
785 	BB_DBG(bb, DBG_COMMON_FLOW, "mode=%s\n",
786 	       ((mode == BB_WATCHDOG_NORMAL) ? "Normal" :
787 	       ((mode == BB_WATCHDOG_LOW_IO) ? "LowIO" : "NonIO")));
788 
789 	/*=== [HALBB Watchdog] ===============================================*/
790 
791 	if (mode == BB_WATCHDOG_NORMAL) {
792 		if(phl_is_mp_mode(bb->phl_com)) {
793 			BB_WARNING("[%s] mode=%d", __func__,
794 				   bb->phl_com->drv_mode);
795 			return;
796 		}
797 		halbb_watchdog_normal(bb, phy_idx);
798 	} else if (mode == BB_WATCHDOG_LOW_IO) {
799 		halbb_watchdog_low_io(bb, phy_idx);
800 	} else { /*if (mode == BB_WATCHDOG_NON_IO)*/
801 		halbb_watchdog_non_io(bb, phy_idx);
802 	}
803 
804 	if (bb->bb_dbg_i.cr_recorder_en)
805 		BB_TRACE("[%s] end\n", __func__);
806 }
807 
halbb_bb_cmd_notify(struct bb_info * bb,void * bb_cmd,enum phl_phy_idx phy_idx)808 void halbb_bb_cmd_notify(struct bb_info *bb, void *bb_cmd, enum phl_phy_idx phy_idx)
809 {
810 	enum halbb_event_idx_t event_idx = *((enum halbb_event_idx_t *)bb_cmd);
811 
812 	BB_DBG(bb, DBG_COMMON_FLOW, "[%s][phy_idx=%d] event_idx=%d\n", __func__, phy_idx, event_idx);
813 
814 	if (event_idx == BB_EVENT_TIMER_DIG) {
815 		#ifdef HALBB_DIG_TDMA_SUPPORT
816 		halbb_tdmadig_io_en(bb);
817 		#endif
818 	} else if (event_idx == BB_EVENT_TIMER_CFO) {
819 		#ifdef HALBB_CFO_TRK_SUPPORT
820 		halbb_cfo_acc_io_en(bb);
821 		#endif
822 	} else if (event_idx == BB_EVENT_TIMER_ANTDIV) {
823 		#ifdef HALBB_ANT_DIV_SUPPORT
824 		halbb_antdiv_io_en(bb);
825 		#endif
826 	} else if (event_idx == BB_EVENT_TIMER_TDMA_CR) {
827 		#ifdef HALBB_TDMA_CR_SUPPORT
828 		halbb_tdma_cr_sel_io_en(bb);
829 		#endif
830 	} else if (event_idx == BB_EVENT_TIMER_LA) {
831 		#ifdef HALBB_LA_MODE_SUPPORT
832 		halbb_la_io_en(bb);
833 		#endif
834 	} else {
835 		BB_WARNING("[%s] event_idx=%d\n", __func__, event_idx);
836 	}
837 }
838 
halbb_pause_func(struct bb_info * bb,enum habb_fun_t pause_func,enum halbb_pause_type pause_type,enum halbb_pause_lv_type lv,u8 val_lehgth,u32 * val_buf)839 u8 halbb_pause_func(struct bb_info *bb, enum habb_fun_t pause_func,
840 		    enum halbb_pause_type pause_type,
841 		    enum halbb_pause_lv_type lv,
842 		    u8 val_lehgth,
843 		    u32 *val_buf)
844 {
845 	struct bb_func_hooker_info *func_t = &bb->bb_cmn_hooker->bb_func_hooker_i;
846 	s8 *pause_lv_pre = &bb->u8_dummy;
847 	u32 *bkp_val = &bb->u32_dummy;
848 	u32 ori_val[5] = {0};
849 	u64 pause_func_bitmap = (u64)BIT(pause_func);
850 	u8 i = 0;
851 	u8 pause_result = PAUSE_FAIL;
852 
853 	BB_DBG(bb, DBG_DBG_API, "[%s][%s] LV=%d, Len=%d\n", __func__,
854 		((pause_type == HALBB_PAUSE) ? "Pause" :
855 		((pause_type == HALBB_RESUME) ? "Resume" :
856 		((pause_type == HALBB_PAUSE_NO_SET) ? "Pause no_set" : "Resume_no_recovery"))),
857 		lv, val_lehgth);
858 
859 	if (lv >= HALBB_PAUSE_MAX_NUM) {
860 		BB_WARNING("[%s] LV=%d\n", __func__, lv);
861 		return PAUSE_FAIL;
862 	}
863 	if (pause_func == F_CFO_TRK) {
864 		BB_DBG(bb, DBG_DBG_API, "[CFO]\n");
865 
866 		if (val_lehgth > 1) {
867 			BB_WARNING("CFO length > 1\n");
868 			return PAUSE_FAIL;
869 		}
870 
871 		ori_val[0] = (u32)(bb->bb_cfo_trk_i.crystal_cap); //which value?
872 		pause_lv_pre = &bb->pause_lv_table.lv_cfo;
873 		bkp_val = (u32 *)(&bb->bb_cfo_trk_i.rvrt_val);
874 		/*@function pointer hook*/
875 		func_t->pause_bb_dm_handler = halbb_set_cfo_pause_val;
876 	}
877 #ifdef HALBB_DIG_SUPPORT
878 	else if (pause_func == F_DIG) {
879 		BB_DBG(bb, DBG_DBG_API, "[DIG]\n");
880 
881 		if (val_lehgth > DIG_PAUSE_INFO_SIZE) {
882 			BB_WARNING("DIG length > %d\n", DIG_PAUSE_INFO_SIZE);
883 			return PAUSE_FAIL;
884 		}
885 		/* {equivalent_rssi, en_pause_by_igi, en_pause_by_pd_low} */
886 		ori_val[0] = (u32)(RSSI_MAX - bb->bb_dig_i.p_cur_dig_unit->igi_fa_rssi);
887 		ori_val[1] = val_buf[1];
888 		pause_lv_pre = &bb->pause_lv_table.lv_dig;
889 		bkp_val = (u32 *)(&bb->bb_dig_i.rvrt_val);
890 		/*@function pointer hook*/
891 		func_t->pause_bb_dm_handler = halbb_set_dig_pause_val;
892 	}
893 #endif
894 #ifdef HALBB_EDCCA_SUPPORT
895 	else if (pause_func == F_EDCCA) {
896 		BB_DBG(bb, DBG_DBG_API, "[EDCCA]\n");
897 
898 		if (val_lehgth > 1) {
899 			BB_WARNING("EDCCA length > 1\n");
900 			return PAUSE_FAIL;
901 		}
902 		ori_val[0] = (u32)(bb->bb_edcca_i.th_h);
903 		pause_lv_pre = &bb->pause_lv_table.lv_edcca;
904 		bkp_val = (u32 *)(&bb->bb_edcca_i.rvrt_val);
905 		/*@function pointer hook*/
906 		func_t->pause_bb_dm_handler = halbb_set_edcca_pause_val;
907 	}
908 #endif
909 	else {
910 		BB_WARNING("Error func idx\n");
911 		return PAUSE_FAIL;
912 	}
913 
914 	BB_DBG(bb, DBG_DBG_API, "Pause_LV{new , pre} = {%d ,%d}\n",
915 	       lv, *pause_lv_pre);
916 
917 	if (pause_type == HALBB_PAUSE || pause_type == HALBB_PAUSE_NO_SET) {
918 		if (lv <= *pause_lv_pre) {
919 			BB_DBG(bb, DBG_DBG_API, "[PAUSE FAIL] Pre_LV >= Curr_LV\n");
920 			return PAUSE_FAIL;
921 		}
922 
923 		if (!(bb->pause_ability & pause_func_bitmap)) {
924 			for (i = 0; i < val_lehgth; i++)
925 				bkp_val[i] = ori_val[i];
926 		}
927 
928 		bb->pause_ability |= pause_func_bitmap;
929 		BB_DBG(bb, DBG_DBG_API, "pause_ability=0x%llx\n", bb->pause_ability);
930 
931 		if (pause_type == HALBB_PAUSE) {
932 			for (i = 0; i < val_lehgth; i++)
933 				BB_DBG(bb, DBG_DBG_API,
934 				       "[PAUSE SUCCESS] val_idx[%d]{New, Ori}={0x%x, 0x%x}\n",
935 				       i, val_buf[i], bkp_val[i]);
936 
937 			func_t->pause_bb_dm_handler(bb, val_buf, val_lehgth);
938 		} else {
939 			for (i = 0; i < val_lehgth; i++)
940 				BB_DBG(bb, DBG_DBG_API,
941 				       "[PAUSE NO Set: SUCCESS] val_idx[%d]{Ori}={0x%x}\n",
942 				       i, bkp_val[i]);
943 		}
944 
945 		*pause_lv_pre = lv;
946 		pause_result = PAUSE_SUCCESS;
947 	} else if (pause_type == HALBB_RESUME) {
948 		if (lv < *pause_lv_pre) {
949 			BB_DBG(bb, DBG_DBG_API, "[Resume FAIL] Pre_LV >= Curr_LV\n");
950 			return PAUSE_FAIL;
951 		}
952 
953 		if ((bb->pause_ability & pause_func_bitmap) == 0) {
954 			BB_DBG(bb, DBG_DBG_API, "[RESUME] No Need to Revert\n");
955 			return PAUSE_SUCCESS;
956 		}
957 
958 		bb->pause_ability &= ~pause_func_bitmap;
959 		BB_DBG(bb, DBG_DBG_API, "pause_ability=0x%llx\n", bb->pause_ability);
960 
961 		*pause_lv_pre = HALBB_PAUSE_RELEASE;
962 
963 		for (i = 0; i < val_lehgth; i++) {
964 			BB_DBG(bb, DBG_DBG_API,
965 			       "[RESUME] val_idx[%d]={0x%x}\n", i, bkp_val[i]);
966 		}
967 
968 		func_t->pause_bb_dm_handler(bb, bkp_val, val_lehgth);
969 
970 		pause_result = PAUSE_SUCCESS;
971 	} else if (pause_type == HALBB_RESUME_NO_RECOVERY) {
972 		if (lv < *pause_lv_pre) {
973 			BB_DBG(bb, DBG_DBG_API, "[Resume FAIL] Pre_LV >= Curr_LV\n");
974 			return PAUSE_FAIL;
975 		}
976 
977 		if ((bb->pause_ability & pause_func_bitmap) == 0) {
978 			BB_DBG(bb, DBG_DBG_API, "[RESUME] No Need to Revert\n");
979 			return PAUSE_SUCCESS;
980 		}
981 
982 		bb->pause_ability &= ~pause_func_bitmap;
983 		BB_DBG(bb, DBG_DBG_API, "pause_ability=0x%llx\n", bb->pause_ability);
984 
985 		*pause_lv_pre = HALBB_PAUSE_RELEASE;
986 
987 		pause_result = PAUSE_SUCCESS;
988 	} else {
989 		BB_WARNING("error pause_type\n");
990 		pause_result = PAUSE_FAIL;
991 	}
992 
993 	return pause_result;
994 }
995 
halbb_pause_func_dbg(struct bb_info * bb,char input[][16],u32 * _used,char * output,u32 * _out_len)996 void halbb_pause_func_dbg(struct bb_info *bb, char input[][16], u32 *_used,
997 			  char *output, u32 *_out_len)
998 {
999 	u32 val[10] = {0};
1000 	u32 i;
1001 	u8 len = 0;
1002 	u32 buf[5] = {0};
1003 	u8 pause_result = 0;
1004 	enum halbb_pause_type type = 0;
1005 	enum halbb_pause_lv_type lv = 0;
1006 	u8 halbb_ary_size = bb->bb_cmn_hooker->bb_dm_number;
1007 	enum habb_fun_t id = F_DEFAULT;
1008 
1009 	/* ==== [Help] ====]*/
1010 	if (_os_strcmp(input[1], "-h") == 0) {
1011 		BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
1012 			    "{Func} {p:pause, pn:pause_no_set, r:Resume, rnc: Resume_no_recov} {lv:0~3} Val[0],...,Val[5]\n");
1013 		BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
1014 			    "{dig} {p/pn/r} {lv} {Pwr(|dBm|),hex} {0:apply to ofdm, 1:apply to cck and ofdm}\n");
1015 		for (i = 0; i < halbb_ary_size; i++)
1016 			BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
1017 				    "*%s\n", halbb_func_i[i].name);
1018 		return;
1019 	}
1020 	/* ==== [Function] ====]*/
1021 	for (i = 0; i < halbb_ary_size; i++) {
1022 		if (_os_strcmp(halbb_func_i[i].name, input[1]) == 0) {
1023 			id = halbb_func_i[i].id;
1024 
1025 			BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
1026 				    "[%s]===>\n", halbb_func_i[i].name);
1027 			break;
1028 		}
1029 	}
1030 
1031 	if (i == halbb_ary_size) {
1032 		BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
1033 			    "Func not found!\n");
1034 		return;
1035 	}
1036 	/* ==== [Type] ====]*/
1037 	if (_os_strcmp(input[2], "p") == 0) {
1038 		type = HALBB_PAUSE;
1039 	} else if (_os_strcmp(input[2], "pn") == 0) {
1040 		type = HALBB_PAUSE_NO_SET;
1041 	} else if (_os_strcmp(input[2], "r") == 0) {
1042 		type = HALBB_RESUME;
1043 	} else if (_os_strcmp(input[2], "rnc") == 0) {
1044 		type = HALBB_RESUME_NO_RECOVERY;
1045 	} else {
1046 		BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
1047 			    "Set Err\n");
1048 		return;
1049 	}
1050 
1051 	for (i = 1; i < 10; i++) {
1052 		HALBB_SCAN(input[i + 1], DCMD_HEX, &val[i]);
1053 	}
1054 
1055 	lv = (enum halbb_pause_lv_type)val[2];
1056 
1057 	for (i = 0; i < 5; i++)
1058 		buf[i] = val[3 + i];
1059 
1060 	if (id == F_CFO_TRK) {
1061 		len = 1;
1062 	} else if (id == F_DIG) {
1063 		len = DIG_PAUSE_INFO_SIZE;
1064 	} else if (id == F_EDCCA) {
1065 		len = 1;
1066 	} else {
1067 		return;
1068 	}
1069 
1070 	if (len) {
1071 		BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
1072 			    "{%s in lv=%d}, pause_val = {%d, %d}\n",
1073 			   ((type == HALBB_PAUSE) ? "Pause" :
1074 			   ((type == HALBB_RESUME) ? "Resume" : "Pause no set")),
1075 			   lv, val[3], val[4]);
1076 
1077 		pause_result = halbb_pause_func(bb, id, type, lv, len, buf);
1078 	}
1079 
1080 	BB_DBG_CNSL(*_out_len, *_used, output + *_used, *_out_len - *_used,
1081 		    "Set %s\n", (pause_result) ? "Success" : "Fail");
1082 }
1083