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
15u8 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
26void 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
38void 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 */
99u8 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
138bool 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
152u8 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
224u8 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
296void 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
348static 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
363static 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
404static 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
444bool 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
472void hal_init_macaddr(struct adapter *adapter)
473{
474	rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, adapter->eeprompriv.mac_addr);
475}
476
477void 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
490void 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*/
500s32 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
531clear_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);
537exit:
538	return ret;
539}
540
541u8 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
546void 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
576void hw_var_port_switch(struct adapter *adapter)
577{
578}
579
580void 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
657void 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
680u8 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
750u8 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
800void 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
813void 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
850bool 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
862bool GetU1ByteIntegerFromStringInDecimal(char *Str, u8 *pInt)
863{
864	u16 i = 0;
865	*pInt = 0;
866
867	while (Str[i] != '\0') {
868		if (Str[i] >= '0' && Str[i] <= '9') {
869			*pInt *= 10;
870			*pInt += (Str[i] - '0');
871		} else
872			return false;
873
874		++i;
875	}
876
877	return true;
878}
879
880void rtw_hal_check_rxfifo_full(struct adapter *adapter)
881{
882	struct dvobj_priv *psdpriv = adapter->dvobj;
883	struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
884	int save_cnt = false;
885
886	/* switch counter to RX fifo */
887	/* printk("8723b or 8192e , MAC_667 set 0xf0\n"); */
888	rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xf0);
889	save_cnt = true;
890	/* todo: other chips */
891
892	if (save_cnt) {
893		/* rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xa0); */
894		pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
895		pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
896		pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow-pdbgpriv->dbg_rx_fifo_last_overflow;
897	}
898}
899
900#ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
901void rtw_dump_raw_rssi_info(struct adapter *padapter)
902{
903	u8 isCCKrate, rf_path;
904	struct hal_com_data *pHalData =  GET_HAL_DATA(padapter);
905	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
906
907	isCCKrate = psample_pkt_rssi->data_rate <= DESC_RATE11M;
908
909	if (isCCKrate)
910		psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
911
912	for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
913		if (!isCCKrate) {
914			printk(", rx_ofdm_pwr:%d(dBm), rx_ofdm_snr:%d(dB)\n",
915			psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
916		} else {
917			printk("\n");
918		}
919	}
920}
921
922void rtw_store_phy_info(struct adapter *padapter, union recv_frame *prframe)
923{
924	u8 isCCKrate, rf_path;
925	struct hal_com_data *pHalData =  GET_HAL_DATA(padapter);
926	struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
927
928	struct odm_phy_info *pPhyInfo  = (PODM_PHY_INFO_T)(&pattrib->phy_info);
929	struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
930
931	psample_pkt_rssi->data_rate = pattrib->data_rate;
932	isCCKrate = pattrib->data_rate <= DESC_RATE11M;
933
934	psample_pkt_rssi->pwdball = pPhyInfo->rx_pwd_ba11;
935	psample_pkt_rssi->pwr_all = pPhyInfo->recv_signal_power;
936
937	for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
938		psample_pkt_rssi->mimo_signal_strength[rf_path] = pPhyInfo->rx_mimo_signal_strength[rf_path];
939		psample_pkt_rssi->mimo_signal_quality[rf_path] = pPhyInfo->rx_mimo_signal_quality[rf_path];
940		if (!isCCKrate) {
941			psample_pkt_rssi->ofdm_pwr[rf_path] = pPhyInfo->RxPwr[rf_path];
942			psample_pkt_rssi->ofdm_snr[rf_path] = pPhyInfo->RxSNR[rf_path];
943		}
944	}
945}
946#endif
947
948static u32 Array_kfreemap[] = {
949	0xf8, 0xe,
950	0xf6, 0xc,
951	0xf4, 0xa,
952	0xf2, 0x8,
953	0xf0, 0x6,
954	0xf3, 0x4,
955	0xf5, 0x2,
956	0xf7, 0x0,
957	0xf9, 0x0,
958	0xfc, 0x0,
959};
960
961void rtw_bb_rf_gain_offset(struct adapter *padapter)
962{
963	u8 value = padapter->eeprompriv.EEPROMRFGainOffset;
964	u32 res, i = 0;
965	u32 *Array = Array_kfreemap;
966	u32 v1 = 0, v2 = 0, target = 0;
967
968	if (value & BIT4) {
969		if (padapter->eeprompriv.EEPROMRFGainVal != 0xff) {
970			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
971			res &= 0xfff87fff;
972			/* res &= 0xfff87fff; */
973			for (i = 0; i < ARRAY_SIZE(Array_kfreemap); i += 2) {
974				v1 = Array[i];
975				v2 = Array[i+1];
976				if (v1 == padapter->eeprompriv.EEPROMRFGainVal) {
977					target = v2;
978					break;
979				}
980			}
981			PHY_SetRFReg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18|BIT17|BIT16|BIT15, target);
982
983			/* res |= (padapter->eeprompriv.EEPROMRFGainVal & 0x0f)<< 15; */
984			/* rtw_hal_write_rfreg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, RF_GAIN_OFFSET_MASK, res); */
985			res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
986		}
987	}
988}
989