xref: /linux/drivers/staging/rtl8723bs/hal/hal_com.c (revision 2da68a77)
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 
8 #include <linux/kernel.h>
9 #include <drv_types.h>
10 #include <rtw_debug.h>
11 #include "hal_com_h2c.h"
12 
13 #include "odm_precomp.h"
14 
15 u8 rtw_hal_data_init(struct adapter *padapter)
16 {
17 	if (is_primary_adapter(padapter)) {	/* if (padapter->isprimary) */
18 		padapter->hal_data_sz = sizeof(struct hal_com_data);
19 		padapter->HalData = vzalloc(padapter->hal_data_sz);
20 		if (!padapter->HalData)
21 			return _FAIL;
22 	}
23 	return _SUCCESS;
24 }
25 
26 void rtw_hal_data_deinit(struct adapter *padapter)
27 {
28 	if (is_primary_adapter(padapter)) {	/* if (padapter->isprimary) */
29 		if (padapter->HalData) {
30 			vfree(padapter->HalData);
31 			padapter->HalData = NULL;
32 			padapter->hal_data_sz = 0;
33 		}
34 	}
35 }
36 
37 
38 void dump_chip_info(struct hal_version	ChipVersion)
39 {
40 	char buf[128];
41 	size_t cnt = 0;
42 
43 	cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "Chip Version Info: CHIP_8723B_%s_",
44 			IS_NORMAL_CHIP(ChipVersion) ? "Normal_Chip" : "Test_Chip");
45 
46 	if (IS_CHIP_VENDOR_TSMC(ChipVersion))
47 		cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "TSMC_");
48 	else if (IS_CHIP_VENDOR_UMC(ChipVersion))
49 		cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "UMC_");
50 	else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
51 		cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "SMIC_");
52 
53 	if (IS_A_CUT(ChipVersion))
54 		cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "A_CUT_");
55 	else if (IS_B_CUT(ChipVersion))
56 		cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "B_CUT_");
57 	else if (IS_C_CUT(ChipVersion))
58 		cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "C_CUT_");
59 	else if (IS_D_CUT(ChipVersion))
60 		cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "D_CUT_");
61 	else if (IS_E_CUT(ChipVersion))
62 		cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "E_CUT_");
63 	else if (IS_I_CUT(ChipVersion))
64 		cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "I_CUT_");
65 	else if (IS_J_CUT(ChipVersion))
66 		cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "J_CUT_");
67 	else if (IS_K_CUT(ChipVersion))
68 		cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "K_CUT_");
69 	else
70 		cnt += scnprintf(buf + cnt, sizeof(buf) - cnt,
71 				"UNKNOWN_CUT(%d)_", ChipVersion.CUTVersion);
72 
73 	cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "1T1R_");
74 
75 	cnt += scnprintf(buf + cnt, sizeof(buf) - cnt, "RomVer(%d)\n", ChipVersion.ROMVer);
76 }
77 
78 
79 #define	EEPROM_CHANNEL_PLAN_BY_HW_MASK	0x80
80 
81 /*
82  * Description:
83  *Use hardware(efuse), driver parameter(registry) and default channel plan
84  *to decide which one should be used.
85  *
86  * Parameters:
87  *padapter			pointer of adapter
88  *hw_channel_plan		channel plan from HW (efuse/eeprom)
89  *					BIT[7] software configure mode; 0:Enable, 1:disable
90  *					BIT[6:0] Channel Plan
91  *sw_channel_plan		channel plan from SW (registry/module param)
92  *def_channel_plan	channel plan used when HW/SW both invalid
93  *AutoLoadFail		efuse autoload fail or not
94  *
95  * Return:
96  *Final channel plan decision
97  *
98  */
99 u8 hal_com_config_channel_plan(
100 	struct adapter *padapter,
101 	u8 hw_channel_plan,
102 	u8 sw_channel_plan,
103 	u8 def_channel_plan,
104 	bool AutoLoadFail
105 )
106 {
107 	struct hal_com_data *pHalData;
108 	u8 chnlPlan;
109 
110 	pHalData = GET_HAL_DATA(padapter);
111 	pHalData->bDisableSWChannelPlan = false;
112 	chnlPlan = def_channel_plan;
113 
114 	if (0xFF == hw_channel_plan)
115 		AutoLoadFail = true;
116 
117 	if (!AutoLoadFail) {
118 		u8 hw_chnlPlan;
119 
120 		hw_chnlPlan = hw_channel_plan & (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
121 		if (rtw_is_channel_plan_valid(hw_chnlPlan)) {
122 			if (hw_channel_plan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
123 				pHalData->bDisableSWChannelPlan = true;
124 
125 			chnlPlan = hw_chnlPlan;
126 		}
127 	}
128 
129 	if (
130 		(false == pHalData->bDisableSWChannelPlan) &&
131 		rtw_is_channel_plan_valid(sw_channel_plan)
132 	)
133 		chnlPlan = sw_channel_plan;
134 
135 	return chnlPlan;
136 }
137 
138 bool HAL_IsLegalChannel(struct adapter *adapter, u32 Channel)
139 {
140 	bool bLegalChannel = true;
141 
142 	if ((Channel <= 14) && (Channel >= 1)) {
143 		if (is_supported_24g(adapter->registrypriv.wireless_mode) == false)
144 			bLegalChannel = false;
145 	} else {
146 		bLegalChannel = false;
147 	}
148 
149 	return bLegalChannel;
150 }
151 
152 u8 MRateToHwRate(u8 rate)
153 {
154 	u8 ret = DESC_RATE1M;
155 
156 	switch (rate) {
157 	case MGN_1M:
158 		ret = DESC_RATE1M;
159 		break;
160 	case MGN_2M:
161 		ret = DESC_RATE2M;
162 		break;
163 	case MGN_5_5M:
164 		ret = DESC_RATE5_5M;
165 		break;
166 	case MGN_11M:
167 		ret = DESC_RATE11M;
168 		break;
169 	case MGN_6M:
170 		ret = DESC_RATE6M;
171 		break;
172 	case MGN_9M:
173 		ret = DESC_RATE9M;
174 		break;
175 	case MGN_12M:
176 		ret = DESC_RATE12M;
177 		break;
178 	case MGN_18M:
179 		ret = DESC_RATE18M;
180 		break;
181 	case MGN_24M:
182 		ret = DESC_RATE24M;
183 		break;
184 	case MGN_36M:
185 		ret = DESC_RATE36M;
186 		break;
187 	case MGN_48M:
188 		ret = DESC_RATE48M;
189 		break;
190 	case MGN_54M:
191 		ret = DESC_RATE54M;
192 		break;
193 	case MGN_MCS0:
194 		ret = DESC_RATEMCS0;
195 		break;
196 	case MGN_MCS1:
197 		ret = DESC_RATEMCS1;
198 		break;
199 	case MGN_MCS2:
200 		ret = DESC_RATEMCS2;
201 		break;
202 	case MGN_MCS3:
203 		ret = DESC_RATEMCS3;
204 		break;
205 	case MGN_MCS4:
206 		ret = DESC_RATEMCS4;
207 		break;
208 	case MGN_MCS5:
209 		ret = DESC_RATEMCS5;
210 		break;
211 	case MGN_MCS6:
212 		ret = DESC_RATEMCS6;
213 		break;
214 	case MGN_MCS7:
215 		ret = DESC_RATEMCS7;
216 		break;
217 	default:
218 		break;
219 	}
220 
221 	return ret;
222 }
223 
224 u8 HwRateToMRate(u8 rate)
225 {
226 	u8 ret_rate = MGN_1M;
227 
228 	switch (rate) {
229 	case DESC_RATE1M:
230 		ret_rate = MGN_1M;
231 		break;
232 	case DESC_RATE2M:
233 		ret_rate = MGN_2M;
234 		break;
235 	case DESC_RATE5_5M:
236 		ret_rate = MGN_5_5M;
237 		break;
238 	case DESC_RATE11M:
239 		ret_rate = MGN_11M;
240 		break;
241 	case DESC_RATE6M:
242 		ret_rate = MGN_6M;
243 		break;
244 	case DESC_RATE9M:
245 		ret_rate = MGN_9M;
246 		break;
247 	case DESC_RATE12M:
248 		ret_rate = MGN_12M;
249 		break;
250 	case DESC_RATE18M:
251 		ret_rate = MGN_18M;
252 		break;
253 	case DESC_RATE24M:
254 		ret_rate = MGN_24M;
255 		break;
256 	case DESC_RATE36M:
257 		ret_rate = MGN_36M;
258 		break;
259 	case DESC_RATE48M:
260 		ret_rate = MGN_48M;
261 		break;
262 	case DESC_RATE54M:
263 		ret_rate = MGN_54M;
264 		break;
265 	case DESC_RATEMCS0:
266 		ret_rate = MGN_MCS0;
267 		break;
268 	case DESC_RATEMCS1:
269 		ret_rate = MGN_MCS1;
270 		break;
271 	case DESC_RATEMCS2:
272 		ret_rate = MGN_MCS2;
273 		break;
274 	case DESC_RATEMCS3:
275 		ret_rate = MGN_MCS3;
276 		break;
277 	case DESC_RATEMCS4:
278 		ret_rate = MGN_MCS4;
279 		break;
280 	case DESC_RATEMCS5:
281 		ret_rate = MGN_MCS5;
282 		break;
283 	case DESC_RATEMCS6:
284 		ret_rate = MGN_MCS6;
285 		break;
286 	case DESC_RATEMCS7:
287 		ret_rate = MGN_MCS7;
288 		break;
289 	default:
290 		break;
291 	}
292 
293 	return ret_rate;
294 }
295 
296 void HalSetBrateCfg(struct adapter *Adapter, u8 *mBratesOS, u16 *pBrateCfg)
297 {
298 	u8 i, is_brate, brate;
299 
300 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
301 
302 		is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
303 		brate = mBratesOS[i] & 0x7f;
304 
305 		if (is_brate) {
306 			switch (brate) {
307 			case IEEE80211_CCK_RATE_1MB:
308 				*pBrateCfg |= RATE_1M;
309 				break;
310 			case IEEE80211_CCK_RATE_2MB:
311 				*pBrateCfg |= RATE_2M;
312 				break;
313 			case IEEE80211_CCK_RATE_5MB:
314 				*pBrateCfg |= RATE_5_5M;
315 				break;
316 			case IEEE80211_CCK_RATE_11MB:
317 				*pBrateCfg |= RATE_11M;
318 				break;
319 			case IEEE80211_OFDM_RATE_6MB:
320 				*pBrateCfg |= RATE_6M;
321 				break;
322 			case IEEE80211_OFDM_RATE_9MB:
323 				*pBrateCfg |= RATE_9M;
324 				break;
325 			case IEEE80211_OFDM_RATE_12MB:
326 				*pBrateCfg |= RATE_12M;
327 				break;
328 			case IEEE80211_OFDM_RATE_18MB:
329 				*pBrateCfg |= RATE_18M;
330 				break;
331 			case IEEE80211_OFDM_RATE_24MB:
332 				*pBrateCfg |= RATE_24M;
333 				break;
334 			case IEEE80211_OFDM_RATE_36MB:
335 				*pBrateCfg |= RATE_36M;
336 				break;
337 			case IEEE80211_OFDM_RATE_48MB:
338 				*pBrateCfg |= RATE_48M;
339 				break;
340 			case IEEE80211_OFDM_RATE_54MB:
341 				*pBrateCfg |= RATE_54M;
342 				break;
343 			}
344 		}
345 	}
346 }
347 
348 static void _OneOutPipeMapping(struct adapter *padapter)
349 {
350 	struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
351 
352 	pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
353 	pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
354 	pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
355 	pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
356 
357 	pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
358 	pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
359 	pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
360 	pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
361 }
362 
363 static void _TwoOutPipeMapping(struct adapter *padapter, bool bWIFICfg)
364 {
365 	struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
366 
367 	if (bWIFICfg) { /* WMM */
368 
369 		/* 	BK,	BE,	VI,	VO,	BCN,	CMD, MGT, HIGH, HCCA */
370 		/*   0,		1,	0,	1,	0,	0,	0,	0,		0	}; */
371 		/* 0:ep_0 num, 1:ep_1 num */
372 
373 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
374 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
375 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
376 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
377 
378 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
379 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
380 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
381 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
382 
383 	} else { /* typical setting */
384 
385 
386 		/* BK,	BE,	VI,	VO,	BCN,	CMD, MGT, HIGH, HCCA */
387 		/*   1,		1,	0,	0,	0,	0,	0,	0,		0	}; */
388 		/* 0:ep_0 num, 1:ep_1 num */
389 
390 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
391 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
392 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
393 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
394 
395 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
396 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
397 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
398 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
399 
400 	}
401 
402 }
403 
404 static void _ThreeOutPipeMapping(struct adapter *padapter, bool bWIFICfg)
405 {
406 	struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
407 
408 	if (bWIFICfg) { /* for WMM */
409 
410 		/* 	BK,	BE,	VI,	VO,	BCN,	CMD, MGT, HIGH, HCCA */
411 		/*   1,		2,	1,	0,	0,	0,	0,	0,		0	}; */
412 		/* 0:H, 1:N, 2:L */
413 
414 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
415 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
416 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
417 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
418 
419 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
420 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
421 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
422 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
423 
424 	} else { /* typical setting */
425 
426 
427 		/* 	BK,	BE,	VI,	VO,	BCN,	CMD, MGT, HIGH, HCCA */
428 		/*   2,		2,	1,	0,	0,	0,	0,	0,		0	}; */
429 		/* 0:H, 1:N, 2:L */
430 
431 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
432 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
433 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
434 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
435 
436 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
437 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
438 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
439 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
440 	}
441 
442 }
443 
444 bool Hal_MappingOutPipe(struct adapter *padapter, u8 NumOutPipe)
445 {
446 	struct registry_priv *pregistrypriv = &padapter->registrypriv;
447 
448 	bool bWIFICfg = (pregistrypriv->wifi_spec) ? true : false;
449 
450 	bool result = true;
451 
452 	switch (NumOutPipe) {
453 	case 2:
454 		_TwoOutPipeMapping(padapter, bWIFICfg);
455 		break;
456 	case 3:
457 	case 4:
458 		_ThreeOutPipeMapping(padapter, bWIFICfg);
459 		break;
460 	case 1:
461 		_OneOutPipeMapping(padapter);
462 		break;
463 	default:
464 		result = false;
465 		break;
466 	}
467 
468 	return result;
469 
470 }
471 
472 void hal_init_macaddr(struct adapter *adapter)
473 {
474 	rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, adapter->eeprompriv.mac_addr);
475 }
476 
477 void rtw_init_hal_com_default_value(struct adapter *Adapter)
478 {
479 	struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
480 
481 	pHalData->AntDetection = 1;
482 }
483 
484 /*
485 * C2H event format:
486 * Field	 TRIGGER		CONTENT	   CMD_SEQ	CMD_LEN		 CMD_ID
487 * BITS	 [127:120]	[119:16]      [15:8]		  [7:4]		   [3:0]
488 */
489 
490 void c2h_evt_clear(struct adapter *adapter)
491 {
492 	rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
493 }
494 
495 /*
496 * C2H event format:
497 * Field    TRIGGER    CMD_LEN    CONTENT    CMD_SEQ    CMD_ID
498 * BITS    [127:120]   [119:112]    [111:16]	     [15:8]         [7:0]
499 */
500 s32 c2h_evt_read_88xx(struct adapter *adapter, u8 *buf)
501 {
502 	s32 ret = _FAIL;
503 	struct c2h_evt_hdr_88xx *c2h_evt;
504 	int i;
505 	u8 trigger;
506 
507 	if (!buf)
508 		goto exit;
509 
510 	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
511 
512 	if (trigger == C2H_EVT_HOST_CLOSE)
513 		goto exit; /* Not ready */
514 	else if (trigger != C2H_EVT_FW_CLOSE)
515 		goto clear_evt; /* Not a valid value */
516 
517 	c2h_evt = (struct c2h_evt_hdr_88xx *)buf;
518 
519 	memset(c2h_evt, 0, 16);
520 
521 	c2h_evt->id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
522 	c2h_evt->seq = rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX);
523 	c2h_evt->plen = rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX);
524 
525 	/* Read the content */
526 	for (i = 0; i < c2h_evt->plen; i++)
527 		c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
528 
529 	ret = _SUCCESS;
530 
531 clear_evt:
532 	/*
533 	* Clear event to notify FW we have read the command.
534 	* If this field isn't clear, the FW won't update the next command message.
535 	*/
536 	c2h_evt_clear(adapter);
537 exit:
538 	return ret;
539 }
540 
541 u8 rtw_get_mgntframe_raid(struct adapter *adapter, unsigned char network_type)
542 {
543 	return (network_type & WIRELESS_11B) ? RATEID_IDX_B : RATEID_IDX_G;
544 }
545 
546 void rtw_hal_update_sta_rate_mask(struct adapter *padapter, struct sta_info *psta)
547 {
548 	u8 i, limit;
549 	u32 tx_ra_bitmap;
550 
551 	if (!psta)
552 		return;
553 
554 	tx_ra_bitmap = 0;
555 
556 	/* b/g mode ra_bitmap */
557 	for (i = 0; i < sizeof(psta->bssrateset); i++) {
558 		if (psta->bssrateset[i])
559 			tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
560 	}
561 
562 	/* n mode ra_bitmap */
563 	if (psta->htpriv.ht_option) {
564 		limit = 8; /*   1R */
565 
566 		for (i = 0; i < limit; i++) {
567 			if (psta->htpriv.ht_cap.mcs.rx_mask[i/8] & BIT(i%8))
568 				tx_ra_bitmap |= BIT(i+12);
569 		}
570 	}
571 
572 	psta->ra_mask = tx_ra_bitmap;
573 	psta->init_rate = get_highest_rate_idx(tx_ra_bitmap)&0x3f;
574 }
575 
576 void hw_var_port_switch(struct adapter *adapter)
577 {
578 }
579 
580 void SetHwReg(struct adapter *adapter, u8 variable, u8 *val)
581 {
582 	struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
583 	struct dm_odm_t *odm = &(hal_data->odmpriv);
584 
585 	switch (variable) {
586 	case HW_VAR_PORT_SWITCH:
587 		hw_var_port_switch(adapter);
588 		break;
589 	case HW_VAR_INIT_RTS_RATE:
590 		rtw_warn_on(1);
591 		break;
592 	case HW_VAR_SEC_CFG:
593 	{
594 		u16 reg_scr;
595 
596 		reg_scr = rtw_read16(adapter, REG_SECCFG);
597 		rtw_write16(adapter, REG_SECCFG, reg_scr|SCR_CHK_KEYID|SCR_RxDecEnable|SCR_TxEncEnable);
598 	}
599 		break;
600 	case HW_VAR_SEC_DK_CFG:
601 	{
602 		struct security_priv *sec = &adapter->securitypriv;
603 		u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
604 
605 		if (val) { /* Enable default key related setting */
606 			reg_scr |= SCR_TXBCUSEDK;
607 			if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
608 				reg_scr |= (SCR_RxUseDK|SCR_TxUseDK);
609 		} else /* Disable default key related setting */
610 			reg_scr &= ~(SCR_RXBCUSEDK|SCR_TXBCUSEDK|SCR_RxUseDK|SCR_TxUseDK);
611 
612 		rtw_write8(adapter, REG_SECCFG, reg_scr);
613 	}
614 		break;
615 	case HW_VAR_DM_FLAG:
616 		odm->SupportAbility = *((u32 *)val);
617 		break;
618 	case HW_VAR_DM_FUNC_OP:
619 		if (*((u8 *)val) == true) {
620 			/* save dm flag */
621 			odm->BK_SupportAbility = odm->SupportAbility;
622 		} else {
623 			/* restore dm flag */
624 			odm->SupportAbility = odm->BK_SupportAbility;
625 		}
626 		break;
627 	case HW_VAR_DM_FUNC_SET:
628 		if (*((u32 *)val) == DYNAMIC_ALL_FUNC_ENABLE) {
629 			struct dm_priv *dm = &hal_data->dmpriv;
630 			dm->DMFlag = dm->InitDMFlag;
631 			odm->SupportAbility = dm->InitODMFlag;
632 		} else {
633 			odm->SupportAbility |= *((u32 *)val);
634 		}
635 		break;
636 	case HW_VAR_DM_FUNC_CLR:
637 		/*
638 		* input is already a mask to clear function
639 		* don't invert it again! George, Lucas@20130513
640 		*/
641 		odm->SupportAbility &= *((u32 *)val);
642 		break;
643 	case HW_VAR_AMPDU_MIN_SPACE:
644 		/* TODO - Is something needed here? */
645 		break;
646 	case HW_VAR_WIRELESS_MODE:
647 		/* TODO - Is something needed here? */
648 		break;
649 	default:
650 		netdev_dbg(adapter->pnetdev,
651 			   FUNC_ADPT_FMT " variable(%d) not defined!\n",
652 			   FUNC_ADPT_ARG(adapter), variable);
653 		break;
654 	}
655 }
656 
657 void GetHwReg(struct adapter *adapter, u8 variable, u8 *val)
658 {
659 	struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
660 	struct dm_odm_t *odm = &(hal_data->odmpriv);
661 
662 	switch (variable) {
663 	case HW_VAR_BASIC_RATE:
664 		*((u16 *)val) = hal_data->BasicRateSet;
665 		break;
666 	case HW_VAR_DM_FLAG:
667 		*((u32 *)val) = odm->SupportAbility;
668 		break;
669 	default:
670 		netdev_dbg(adapter->pnetdev,
671 			   FUNC_ADPT_FMT " variable(%d) not defined!\n",
672 			   FUNC_ADPT_ARG(adapter), variable);
673 		break;
674 	}
675 }
676 
677 
678 
679 
680 u8 SetHalDefVar(
681 	struct adapter *adapter, enum hal_def_variable variable, void *value
682 )
683 {
684 	struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
685 	struct dm_odm_t *odm = &(hal_data->odmpriv);
686 	u8 bResult = _SUCCESS;
687 
688 	switch (variable) {
689 	case HAL_DEF_DBG_RX_INFO_DUMP:
690 
691 		if (odm->bLinked) {
692 			#ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
693 			rtw_dump_raw_rssi_info(adapter);
694 			#endif
695 		}
696 		break;
697 	case HW_DEF_ODM_DBG_FLAG:
698 		ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_COMP, *((u64 *)value));
699 		break;
700 	case HW_DEF_ODM_DBG_LEVEL:
701 		ODM_CmnInfoUpdate(odm, ODM_CMNINFO_DBG_LEVEL, *((u32 *)value));
702 		break;
703 	case HAL_DEF_DBG_DM_FUNC:
704 	{
705 		u8 dm_func = *((u8 *)value);
706 		struct dm_priv *dm = &hal_data->dmpriv;
707 
708 		if (dm_func == 0) { /* disable all dynamic func */
709 			odm->SupportAbility = DYNAMIC_FUNC_DISABLE;
710 		} else if (dm_func == 1) {/* disable DIG */
711 			odm->SupportAbility  &= (~DYNAMIC_BB_DIG);
712 		} else if (dm_func == 2) {/* disable High power */
713 			odm->SupportAbility  &= (~DYNAMIC_BB_DYNAMIC_TXPWR);
714 		} else if (dm_func == 3) {/* disable tx power tracking */
715 			odm->SupportAbility  &= (~DYNAMIC_RF_CALIBRATION);
716 		} else if (dm_func == 4) {/* disable BT coexistence */
717 			dm->DMFlag &= (~DYNAMIC_FUNC_BT);
718 		} else if (dm_func == 5) {/* disable antenna diversity */
719 			odm->SupportAbility  &= (~DYNAMIC_BB_ANT_DIV);
720 		} else if (dm_func == 6) {/* turn on all dynamic func */
721 			if (!(odm->SupportAbility  & DYNAMIC_BB_DIG)) {
722 				struct dig_t	*pDigTable = &odm->DM_DigTable;
723 				pDigTable->CurIGValue = rtw_read8(adapter, 0xc50);
724 			}
725 			dm->DMFlag |= DYNAMIC_FUNC_BT;
726 			odm->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
727 		}
728 	}
729 		break;
730 	case HAL_DEF_DBG_DUMP_RXPKT:
731 		hal_data->bDumpRxPkt = *((u8 *)value);
732 		break;
733 	case HAL_DEF_DBG_DUMP_TXPKT:
734 		hal_data->bDumpTxPkt = *((u8 *)value);
735 		break;
736 	case HAL_DEF_ANT_DETECT:
737 		hal_data->AntDetection = *((u8 *)value);
738 		break;
739 	default:
740 		netdev_dbg(adapter->pnetdev,
741 			   "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n",
742 			   __func__, variable);
743 		bResult = _FAIL;
744 		break;
745 	}
746 
747 	return bResult;
748 }
749 
750 u8 GetHalDefVar(
751 	struct adapter *adapter, enum hal_def_variable variable, void *value
752 )
753 {
754 	struct hal_com_data *hal_data = GET_HAL_DATA(adapter);
755 	u8 bResult = _SUCCESS;
756 
757 	switch (variable) {
758 	case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB:
759 		{
760 			struct mlme_priv *pmlmepriv;
761 			struct sta_priv *pstapriv;
762 			struct sta_info *psta;
763 
764 			pmlmepriv = &adapter->mlmepriv;
765 			pstapriv = &adapter->stapriv;
766 			psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.mac_address);
767 			if (psta)
768 				*((int *)value) = psta->rssi_stat.UndecoratedSmoothedPWDB;
769 		}
770 		break;
771 	case HAL_DEF_DBG_DM_FUNC:
772 		*((u32 *)value) = hal_data->odmpriv.SupportAbility;
773 		break;
774 	case HAL_DEF_DBG_DUMP_RXPKT:
775 		*((u8 *)value) = hal_data->bDumpRxPkt;
776 		break;
777 	case HAL_DEF_DBG_DUMP_TXPKT:
778 		*((u8 *)value) = hal_data->bDumpTxPkt;
779 		break;
780 	case HAL_DEF_ANT_DETECT:
781 		*((u8 *)value) = hal_data->AntDetection;
782 		break;
783 	case HAL_DEF_MACID_SLEEP:
784 		*(u8 *)value = false;
785 		break;
786 	case HAL_DEF_TX_PAGE_SIZE:
787 		*((u32 *)value) = PAGE_SIZE_128;
788 		break;
789 	default:
790 		netdev_dbg(adapter->pnetdev,
791 			   "%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n",
792 			   __func__, variable);
793 		bResult = _FAIL;
794 		break;
795 	}
796 
797 	return bResult;
798 }
799 
800 void GetHalODMVar(
801 	struct adapter *Adapter,
802 	enum hal_odm_variable eVariable,
803 	void *pValue1,
804 	void *pValue2
805 )
806 {
807 	switch (eVariable) {
808 	default:
809 		break;
810 	}
811 }
812 
813 void SetHalODMVar(
814 	struct adapter *Adapter,
815 	enum hal_odm_variable eVariable,
816 	void *pValue1,
817 	bool bSet
818 )
819 {
820 	struct hal_com_data	*pHalData = GET_HAL_DATA(Adapter);
821 	struct dm_odm_t *podmpriv = &pHalData->odmpriv;
822 	/* _irqL irqL; */
823 	switch (eVariable) {
824 	case HAL_ODM_STA_INFO:
825 		{
826 			struct sta_info *psta = pValue1;
827 			if (bSet) {
828 				ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta);
829 			} else {
830 				/* spin_lock_bh(&pHalData->odm_stainfo_lock); */
831 				ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL);
832 
833 				/* spin_unlock_bh(&pHalData->odm_stainfo_lock); */
834 		    }
835 		}
836 		break;
837 	case HAL_ODM_P2P_STATE:
838 			ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet);
839 		break;
840 	case HAL_ODM_WIFI_DISPLAY_STATE:
841 			ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet);
842 		break;
843 
844 	default:
845 		break;
846 	}
847 }
848 
849 
850 bool eqNByte(u8 *str1, u8 *str2, u32 num)
851 {
852 	if (num == 0)
853 		return false;
854 	while (num > 0) {
855 		num--;
856 		if (str1[num] != str2[num])
857 			return false;
858 	}
859 	return true;
860 }
861 
862 /*  */
863 /* 	Description: */
864 /* 		Translate a character to hex digit. */
865 /*  */
866 u32 MapCharToHexDigit(char chTmp)
867 {
868 	if (chTmp >= '0' && chTmp <= '9')
869 		return chTmp - '0';
870 	else if (chTmp >= 'a' && chTmp <= 'f')
871 		return 10 + (chTmp - 'a');
872 	else if (chTmp >= 'A' && chTmp <= 'F')
873 		return 10 + (chTmp - 'A');
874 	else
875 		return 0;
876 }
877 
878 bool GetU1ByteIntegerFromStringInDecimal(char *Str, u8 *pInt)
879 {
880 	u16 i = 0;
881 	*pInt = 0;
882 
883 	while (Str[i] != '\0') {
884 		if (Str[i] >= '0' && Str[i] <= '9') {
885 			*pInt *= 10;
886 			*pInt += (Str[i] - '0');
887 		} else
888 			return false;
889 
890 		++i;
891 	}
892 
893 	return true;
894 }
895 
896 /*  <20121004, Kordan> For example,
897  *  ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from
898  *  a string "Hello [Kordan]".
899  *  If RightQualifier does not exist, it will hang in the while loop
900  */
901 bool ParseQualifiedString(
902 	char *In, u32 *Start, char *Out, char LeftQualifier, char RightQualifier
903 )
904 {
905 	u32 i = 0, j = 0;
906 	char c = In[(*Start)++];
907 
908 	if (c != LeftQualifier)
909 		return false;
910 
911 	i = (*Start);
912 	while ((c = In[(*Start)++]) != RightQualifier)
913 		; /*  find ']' */
914 	j = (*Start) - 2;
915 	strncpy((char *)Out, (const char *)(In+i), j-i+1);
916 
917 	return true;
918 }
919 
920 bool isAllSpaceOrTab(u8 *data, u8 size)
921 {
922 	u8 cnt = 0, NumOfSpaceAndTab = 0;
923 
924 	while (size > cnt) {
925 		if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
926 			++NumOfSpaceAndTab;
927 
928 		++cnt;
929 	}
930 
931 	return size == NumOfSpaceAndTab;
932 }
933 
934 
935 void rtw_hal_check_rxfifo_full(struct adapter *adapter)
936 {
937 	struct dvobj_priv *psdpriv = adapter->dvobj;
938 	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
939 	int save_cnt = false;
940 
941 	/* switch counter to RX fifo */
942 	/* printk("8723b or 8192e , MAC_667 set 0xf0\n"); */
943 	rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xf0);
944 	save_cnt = true;
945 	/* todo: other chips */
946 
947 	if (save_cnt) {
948 		/* rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xa0); */
949 		pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
950 		pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
951 		pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow-pdbgpriv->dbg_rx_fifo_last_overflow;
952 	}
953 }
954 
955 void linked_info_dump(struct adapter *padapter, u8 benable)
956 {
957 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
958 
959 	if (padapter->bLinkInfoDump == benable)
960 		return;
961 
962 	if (benable) {
963 		pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
964 		rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
965 
966 		pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
967 		rtw_pm_set_ips(padapter, IPS_NONE);
968 	} else {
969 		rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
970 
971 		rtw_pm_set_lps(padapter, pwrctrlpriv->ips_org_mode);
972 	}
973 	padapter->bLinkInfoDump = benable;
974 }
975 
976 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
977 void rtw_get_raw_rssi_info(void *sel, struct adapter *padapter)
978 {
979 	u8 isCCKrate, rf_path;
980 	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
981 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
982 
983 	netdev_dbg(padapter->pnetdev,
984 		   "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
985 		   HDATA_RATE(psample_pkt_rssi->data_rate),
986 		   psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
987 
988 	isCCKrate = psample_pkt_rssi->data_rate <= DESC_RATE11M;
989 
990 	if (isCCKrate)
991 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
992 
993 	for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
994 		netdev_dbg(padapter->pnetdev,
995 			   "RF_PATH_%d =>signal_strength:%d(%%), signal_quality:%d(%%)\n",
996 			   rf_path,
997 			   psample_pkt_rssi->mimo_signal_strength[rf_path],
998 			   psample_pkt_rssi->mimo_signal_quality[rf_path]);
999 
1000 		if (!isCCKrate) {
1001 			netdev_dbg(padapter->pnetdev,
1002 				   "\trx_ofdm_pwr:%d(dBm), rx_ofdm_snr:%d(dB)\n",
1003 				   psample_pkt_rssi->ofdm_pwr[rf_path],
1004 				   psample_pkt_rssi->ofdm_snr[rf_path]);
1005 		}
1006 	}
1007 }
1008 
1009 void rtw_dump_raw_rssi_info(struct adapter *padapter)
1010 {
1011 	u8 isCCKrate, rf_path;
1012 	struct hal_com_data *pHalData =  GET_HAL_DATA(padapter);
1013 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
1014 
1015 	isCCKrate = psample_pkt_rssi->data_rate <= DESC_RATE11M;
1016 
1017 	if (isCCKrate)
1018 		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
1019 
1020 	for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
1021 		if (!isCCKrate) {
1022 			printk(", rx_ofdm_pwr:%d(dBm), rx_ofdm_snr:%d(dB)\n",
1023 			psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
1024 		} else {
1025 			printk("\n");
1026 		}
1027 	}
1028 }
1029 
1030 void rtw_store_phy_info(struct adapter *padapter, union recv_frame *prframe)
1031 {
1032 	u8 isCCKrate, rf_path;
1033 	struct hal_com_data *pHalData =  GET_HAL_DATA(padapter);
1034 	struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
1035 
1036 	struct odm_phy_info *pPhyInfo  = (PODM_PHY_INFO_T)(&pattrib->phy_info);
1037 	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
1038 
1039 	psample_pkt_rssi->data_rate = pattrib->data_rate;
1040 	isCCKrate = pattrib->data_rate <= DESC_RATE11M;
1041 
1042 	psample_pkt_rssi->pwdball = pPhyInfo->rx_pwd_ba11;
1043 	psample_pkt_rssi->pwr_all = pPhyInfo->recv_signal_power;
1044 
1045 	for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
1046 		psample_pkt_rssi->mimo_signal_strength[rf_path] = pPhyInfo->rx_mimo_signal_strength[rf_path];
1047 		psample_pkt_rssi->mimo_signal_quality[rf_path] = pPhyInfo->rx_mimo_signal_quality[rf_path];
1048 		if (!isCCKrate) {
1049 			psample_pkt_rssi->ofdm_pwr[rf_path] = pPhyInfo->RxPwr[rf_path];
1050 			psample_pkt_rssi->ofdm_snr[rf_path] = pPhyInfo->RxSNR[rf_path];
1051 		}
1052 	}
1053 }
1054 #endif
1055 
1056 static u32 Array_kfreemap[] = {
1057 	0xf8, 0xe,
1058 	0xf6, 0xc,
1059 	0xf4, 0xa,
1060 	0xf2, 0x8,
1061 	0xf0, 0x6,
1062 	0xf3, 0x4,
1063 	0xf5, 0x2,
1064 	0xf7, 0x0,
1065 	0xf9, 0x0,
1066 	0xfc, 0x0,
1067 };
1068 
1069 void rtw_bb_rf_gain_offset(struct adapter *padapter)
1070 {
1071 	u8 value = padapter->eeprompriv.EEPROMRFGainOffset;
1072 	u32 res, i = 0;
1073 	u32 *Array = Array_kfreemap;
1074 	u32 v1 = 0, v2 = 0, target = 0;
1075 
1076 	if (value & BIT4) {
1077 		if (padapter->eeprompriv.EEPROMRFGainVal != 0xff) {
1078 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
1079 			res &= 0xfff87fff;
1080 			/* res &= 0xfff87fff; */
1081 			for (i = 0; i < ARRAY_SIZE(Array_kfreemap); i += 2) {
1082 				v1 = Array[i];
1083 				v2 = Array[i+1];
1084 				if (v1 == padapter->eeprompriv.EEPROMRFGainVal) {
1085 					target = v2;
1086 					break;
1087 				}
1088 			}
1089 			PHY_SetRFReg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18|BIT17|BIT16|BIT15, target);
1090 
1091 			/* res |= (padapter->eeprompriv.EEPROMRFGainVal & 0x0f)<< 15; */
1092 			/* rtw_hal_write_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, RF_GAIN_OFFSET_MASK, res); */
1093 			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
1094 		}
1095 	}
1096 }
1097