• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15 #include <osdep_service.h>
16 #include <drv_types.h>
17 
18 #include <hal_intf.h>
19 #include <hal_com.h>
20 #include <rtl8723a_hal.h>
21 #include <usb_ops_linux.h>
22 
23 #define _HAL_INIT_C_
24 
dump_chip_info23a(struct hal_version ChipVersion)25 void dump_chip_info23a(struct hal_version ChipVersion)
26 {
27 	int cnt = 0;
28 	u8 buf[128];
29 
30 	cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723A_");
31 
32 	cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(ChipVersion) ?
33 		       "Normal_Chip" : "Test_Chip");
34 	cnt += sprintf((buf + cnt), "%s_",
35 		       IS_CHIP_VENDOR_TSMC(ChipVersion) ? "TSMC" : "UMC");
36 	if (IS_A_CUT(ChipVersion))
37 		cnt += sprintf((buf + cnt), "A_CUT_");
38 	else if (IS_B_CUT(ChipVersion))
39 		cnt += sprintf((buf + cnt), "B_CUT_");
40 	else if (IS_C_CUT(ChipVersion))
41 		cnt += sprintf((buf + cnt), "C_CUT_");
42 	else if (IS_D_CUT(ChipVersion))
43 		cnt += sprintf((buf + cnt), "D_CUT_");
44 	else if (IS_E_CUT(ChipVersion))
45 		cnt += sprintf((buf + cnt), "E_CUT_");
46 	else
47 		cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_",
48 			       ChipVersion.CUTVersion);
49 
50 	if (IS_1T1R(ChipVersion))
51 		cnt += sprintf((buf + cnt), "1T1R_");
52 	else if (IS_1T2R(ChipVersion))
53 		cnt += sprintf((buf + cnt), "1T2R_");
54 	else if (IS_2T2R(ChipVersion))
55 		cnt += sprintf((buf + cnt), "2T2R_");
56 	else
57 		cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_",
58 			       ChipVersion.RFType);
59 
60 	cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
61 
62 	DBG_8723A("%s", buf);
63 }
64 
65 #define	EEPROM_CHANNEL_PLAN_BY_HW_MASK	0x80
66 
67 /* return the final channel plan decision */
68 /* hw_channel_plan:  channel plan from HW (efuse/eeprom) */
69 /* sw_channel_plan:  channel plan from SW (registry/module param) */
70 /* def_channel_plan: channel plan used when the former two is invalid */
hal_com_get_channel_plan23a(struct rtw_adapter * padapter,u8 hw_channel_plan,u8 sw_channel_plan,u8 def_channel_plan,bool AutoLoadFail)71 u8 hal_com_get_channel_plan23a(struct rtw_adapter *padapter, u8 hw_channel_plan,
72 			    u8 sw_channel_plan, u8 def_channel_plan,
73 			    bool AutoLoadFail)
74 {
75 	u8 swConfig;
76 	u8 chnlPlan;
77 
78 	swConfig = true;
79 	if (!AutoLoadFail) {
80 		if (!rtw_is_channel_plan_valid(sw_channel_plan))
81 			swConfig = false;
82 		if (hw_channel_plan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
83 			swConfig = false;
84 	}
85 
86 	if (swConfig == true)
87 		chnlPlan = sw_channel_plan;
88 	else
89 		chnlPlan = hw_channel_plan & (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
90 
91 	if (!rtw_is_channel_plan_valid(chnlPlan))
92 		chnlPlan = def_channel_plan;
93 
94 	return chnlPlan;
95 }
96 
MRateToHwRate23a(u8 rate)97 u8 MRateToHwRate23a(u8 rate)
98 {
99 	u8 ret = DESC_RATE1M;
100 
101 	switch (rate) {
102 		/*  CCK and OFDM non-HT rates */
103 	case IEEE80211_CCK_RATE_1MB:
104 		ret = DESC_RATE1M;
105 		break;
106 	case IEEE80211_CCK_RATE_2MB:
107 		ret = DESC_RATE2M;
108 		break;
109 	case IEEE80211_CCK_RATE_5MB:
110 		ret = DESC_RATE5_5M;
111 		break;
112 	case IEEE80211_CCK_RATE_11MB:
113 		ret = DESC_RATE11M;
114 		break;
115 	case IEEE80211_OFDM_RATE_6MB:
116 		ret = DESC_RATE6M;
117 		break;
118 	case IEEE80211_OFDM_RATE_9MB:
119 		ret = DESC_RATE9M;
120 		break;
121 	case IEEE80211_OFDM_RATE_12MB:
122 		ret = DESC_RATE12M;
123 		break;
124 	case IEEE80211_OFDM_RATE_18MB:
125 		ret = DESC_RATE18M;
126 		break;
127 	case IEEE80211_OFDM_RATE_24MB:
128 		ret = DESC_RATE24M;
129 		break;
130 	case IEEE80211_OFDM_RATE_36MB:
131 		ret = DESC_RATE36M;
132 		break;
133 	case IEEE80211_OFDM_RATE_48MB:
134 		ret = DESC_RATE48M;
135 		break;
136 	case IEEE80211_OFDM_RATE_54MB:
137 		ret = DESC_RATE54M;
138 		break;
139 
140 		/*  HT rates since here */
141 		/* case MGN_MCS0:	ret = DESC_RATEMCS0;    break; */
142 		/* case MGN_MCS1:	ret = DESC_RATEMCS1;    break; */
143 		/* case MGN_MCS2:	ret = DESC_RATEMCS2;    break; */
144 		/* case MGN_MCS3:	ret = DESC_RATEMCS3;    break; */
145 		/* case MGN_MCS4:	ret = DESC_RATEMCS4;    break; */
146 		/* case MGN_MCS5:	ret = DESC_RATEMCS5;    break; */
147 		/* case MGN_MCS6:	ret = DESC_RATEMCS6;    break; */
148 		/* case MGN_MCS7:	ret = DESC_RATEMCS7;    break; */
149 
150 	default:
151 		break;
152 	}
153 	return ret;
154 }
155 
HalSetBrateCfg23a(struct rtw_adapter * padapter,u8 * mBratesOS)156 void HalSetBrateCfg23a(struct rtw_adapter *padapter, u8 *mBratesOS)
157 {
158 	struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
159 	u8 i, is_brate, brate;
160 	u16 brate_cfg = 0;
161 	u8 rate_index;
162 
163 	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
164 		is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
165 		brate = mBratesOS[i] & 0x7f;
166 
167 		if (is_brate) {
168 			switch (brate) {
169 			case IEEE80211_CCK_RATE_1MB:
170 				brate_cfg |= RATE_1M;
171 				break;
172 			case IEEE80211_CCK_RATE_2MB:
173 				brate_cfg |= RATE_2M;
174 				break;
175 			case IEEE80211_CCK_RATE_5MB:
176 				brate_cfg |= RATE_5_5M;
177 				break;
178 			case IEEE80211_CCK_RATE_11MB:
179 				brate_cfg |= RATE_11M;
180 				break;
181 			case IEEE80211_OFDM_RATE_6MB:
182 				brate_cfg |= RATE_6M;
183 				break;
184 			case IEEE80211_OFDM_RATE_9MB:
185 				brate_cfg |= RATE_9M;
186 				break;
187 			case IEEE80211_OFDM_RATE_12MB:
188 				brate_cfg |= RATE_12M;
189 				break;
190 			case IEEE80211_OFDM_RATE_18MB:
191 				brate_cfg |= RATE_18M;
192 				break;
193 			case IEEE80211_OFDM_RATE_24MB:
194 				brate_cfg |= RATE_24M;
195 				break;
196 			case IEEE80211_OFDM_RATE_36MB:
197 				brate_cfg |= RATE_36M;
198 				break;
199 			case IEEE80211_OFDM_RATE_48MB:
200 				brate_cfg |= RATE_48M;
201 				break;
202 			case IEEE80211_OFDM_RATE_54MB:
203 				brate_cfg |= RATE_54M;
204 				break;
205 			}
206 		}
207 	}
208 
209 	/*  2007.01.16, by Emily */
210 	/*  Select RRSR (in Legacy-OFDM and CCK) */
211 	/*  For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M,
212 	    and 1M from the Basic rate. */
213 	/*  We do not use other rates. */
214 	/* 2011.03.30 add by Luke Lee */
215 	/* CCK 2M ACK should be disabled for some BCM and Atheros AP IOT */
216 	/* because CCK 2M has poor TXEVM */
217 	/* CCK 5.5M & 11M ACK should be enabled for better
218 	   performance */
219 
220 	brate_cfg = (brate_cfg | 0xd) & 0x15d;
221 	pHalData->BasicRateSet = brate_cfg;
222 	brate_cfg |= 0x01;	/*  default enable 1M ACK rate */
223 	DBG_8723A("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", brate_cfg);
224 
225 	/*  Set RRSR rate table. */
226 	rtl8723au_write8(padapter, REG_RRSR, brate_cfg & 0xff);
227 	rtl8723au_write8(padapter, REG_RRSR + 1, (brate_cfg >> 8) & 0xff);
228 	rtl8723au_write8(padapter, REG_RRSR + 2,
229 			 rtl8723au_read8(padapter, REG_RRSR + 2) & 0xf0);
230 
231 	rate_index = 0;
232 	/*  Set RTS initial rate */
233 	while (brate_cfg > 0x1) {
234 		brate_cfg = (brate_cfg >> 1);
235 		rate_index++;
236 	}
237 		/*  Ziv - Check */
238 	rtl8723au_write8(padapter, REG_INIRTS_RATE_SEL, rate_index);
239 
240 	return;
241 }
242 
_OneOutPipeMapping(struct rtw_adapter * pAdapter)243 static void _OneOutPipeMapping(struct rtw_adapter *pAdapter)
244 {
245 	struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
246 
247 	pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];	/* VO */
248 	pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];	/* VI */
249 	pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];	/* BE */
250 	pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];	/* BK */
251 
252 	pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];	/* BCN */
253 	pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];	/* MGT */
254 	pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];	/* HIGH */
255 	pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];	/* TXCMD */
256 }
257 
_TwoOutPipeMapping(struct rtw_adapter * pAdapter,bool bWIFICfg)258 static void _TwoOutPipeMapping(struct rtw_adapter *pAdapter, bool bWIFICfg)
259 {
260 	struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
261 
262 	if (bWIFICfg) {		/* WMM */
263 		/*    BK,   BE,   VI,   VO,   BCN,  CMD,  MGT, HIGH, HCCA */
264 		/*     0,    1,    0,    1,     0,    0,    0,    0,    0 }; */
265 		/* 0:H, 1:L */
266 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1]; /* VO */
267 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0]; /* VI */
268 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1]; /* BE */
269 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0]; /* BK */
270 
271 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */
272 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */
273 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */
274 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/
275 	} else {		/* typical setting */
276 		/*    BK,   BE,   VI,   VO,   BCN,  CMD,  MGT, HIGH, HCCA */
277 		/*     1,    1,    0,    0,     0,    0,    0,    0,    0 }; */
278 		/* 0:H, 1:L */
279 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */
280 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0]; /* VI */
281 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1]; /* BE */
282 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1]; /* BK */
283 
284 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */
285 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */
286 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */
287 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/
288 	}
289 }
290 
_ThreeOutPipeMapping(struct rtw_adapter * pAdapter,bool bWIFICfg)291 static void _ThreeOutPipeMapping(struct rtw_adapter *pAdapter, bool bWIFICfg)
292 {
293 	struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
294 
295 	if (bWIFICfg) {		/* for WMM */
296 		/*    BK,   BE,   VI,   VO,   BCN,  CMD,  MGT, HIGH, HCCA */
297 		/*     1,    2,    1,    0,     0,    0,    0,    0,    0 }; */
298 		/* 0:H, 1:N, 2:L */
299 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */
300 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1]; /* VI */
301 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2]; /* BE */
302 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1]; /* BK */
303 
304 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */
305 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */
306 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */
307 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/
308 	} else {		/* typical setting */
309 		/*    BK,   BE,   VI,   VO,   BCN,  CMD,  MGT, HIGH, HCCA */
310 		/*     2,    2,    1,    0,     0,    0,    0,    0,    0 }; */
311 		/* 0:H, 1:N, 2:L */
312 		pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */
313 		pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1]; /* VI */
314 		pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2]; /* BE */
315 		pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2]; /* BK */
316 
317 		pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */
318 		pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */
319 		pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */
320 		pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/
321 	}
322 }
323 
Hal_MappingOutPipe23a(struct rtw_adapter * pAdapter,u8 NumOutPipe)324 bool Hal_MappingOutPipe23a(struct rtw_adapter *pAdapter, u8 NumOutPipe)
325 {
326 	struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
327 	bool bWIFICfg = (pregistrypriv->wifi_spec) ? true : false;
328 	bool result = true;
329 
330 	switch (NumOutPipe) {
331 	case 2:
332 		_TwoOutPipeMapping(pAdapter, bWIFICfg);
333 		break;
334 	case 3:
335 		_ThreeOutPipeMapping(pAdapter, bWIFICfg);
336 		break;
337 	case 1:
338 		_OneOutPipeMapping(pAdapter);
339 		break;
340 	default:
341 		result = false;
342 		break;
343 	}
344 
345 	return result;
346 }
347 
348 /*
349 * C2H event format:
350 * Field	 TRIGGER		CONTENT	   CMD_SEQ	CMD_LEN		 CMD_ID
351 * BITS	 [127:120]	[119:16]      [15:8]		  [7:4]		   [3:0]
352 */
353 
c2h_evt_clear23a(struct rtw_adapter * adapter)354 void c2h_evt_clear23a(struct rtw_adapter *adapter)
355 {
356 	rtl8723au_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
357 }
358 
c2h_evt_read23a(struct rtw_adapter * adapter,u8 * buf)359 int c2h_evt_read23a(struct rtw_adapter *adapter, u8 *buf)
360 {
361 	int ret = _FAIL;
362 	struct c2h_evt_hdr *c2h_evt;
363 	int i;
364 	u8 trigger;
365 
366 	if (buf == NULL)
367 		goto exit;
368 
369 	trigger = rtl8723au_read8(adapter, REG_C2HEVT_CLEAR);
370 
371 	if (trigger == C2H_EVT_HOST_CLOSE)
372 		goto exit;	/* Not ready */
373 	else if (trigger != C2H_EVT_FW_CLOSE)
374 		goto clear_evt;	/* Not a valid value */
375 
376 	c2h_evt = (struct c2h_evt_hdr *)buf;
377 
378 	memset(c2h_evt, 0, 16);
379 
380 	*buf = rtl8723au_read8(adapter, REG_C2HEVT_MSG_NORMAL);
381 	*(buf + 1) = rtl8723au_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);
382 
383 	RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read23a(): ",
384 		      &c2h_evt, sizeof(c2h_evt));
385 
386 	if (0) {
387 		DBG_8723A("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n",
388 			  __func__, c2h_evt->id, c2h_evt->plen, c2h_evt->seq,
389 			  trigger);
390 	}
391 
392 	/* Read the content */
393 	for (i = 0; i < c2h_evt->plen; i++)
394 		c2h_evt->payload[i] = rtl8723au_read8(adapter,
395 						REG_C2HEVT_MSG_NORMAL +
396 						sizeof(*c2h_evt) + i);
397 
398 	RT_PRINT_DATA(_module_hal_init_c_, _drv_info_,
399 		      "c2h_evt_read23a(): Command Content:\n", c2h_evt->payload,
400 		      c2h_evt->plen);
401 
402 	ret = _SUCCESS;
403 
404 clear_evt:
405 	/*
406 	 * Clear event to notify FW we have read the command.
407 	 * If this field isn't clear, the FW won't update the
408 	 * next command message.
409 	 */
410 	c2h_evt_clear23a(adapter);
411 exit:
412 	return ret;
413 }
414 
415 void
rtl8723a_set_ampdu_min_space(struct rtw_adapter * padapter,u8 MinSpacingToSet)416 rtl8723a_set_ampdu_min_space(struct rtw_adapter *padapter, u8 MinSpacingToSet)
417 {
418 	u8 SecMinSpace;
419 
420 	if (MinSpacingToSet <= 7) {
421 		switch (padapter->securitypriv.dot11PrivacyAlgrthm) {
422 		case 0:
423 		case WLAN_CIPHER_SUITE_CCMP:
424 			SecMinSpace = 0;
425 			break;
426 
427 		case WLAN_CIPHER_SUITE_WEP40:
428 		case WLAN_CIPHER_SUITE_WEP104:
429 		case WLAN_CIPHER_SUITE_TKIP:
430 			SecMinSpace = 6;
431 			break;
432 		default:
433 			SecMinSpace = 7;
434 			break;
435 		}
436 
437 		if (MinSpacingToSet < SecMinSpace)
438 			MinSpacingToSet = SecMinSpace;
439 
440 		/* RT_TRACE(COMP_MLME, DBG_LOUD,
441 		   ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
442 		   padapter->MgntInfo.MinSpaceCfg)); */
443 		MinSpacingToSet |=
444 			rtl8723au_read8(padapter, REG_AMPDU_MIN_SPACE) & 0xf8;
445 		rtl8723au_write8(padapter, REG_AMPDU_MIN_SPACE,
446 				 MinSpacingToSet);
447 	}
448 }
449 
rtl8723a_set_ampdu_factor(struct rtw_adapter * padapter,u8 FactorToSet)450 void rtl8723a_set_ampdu_factor(struct rtw_adapter *padapter, u8 FactorToSet)
451 {
452 	u8 RegToSet_Normal[4] = { 0x41, 0xa8, 0x72, 0xb9 };
453 	u8 MaxAggNum;
454 	u8 *pRegToSet;
455 	u8 index = 0;
456 
457 	pRegToSet = RegToSet_Normal;	/*  0xb972a841; */
458 
459 	if (rtl8723a_BT_enabled(padapter) &&
460 	    rtl8723a_BT_using_antenna_1(padapter))
461 		MaxAggNum = 0x8;
462 	else
463 		MaxAggNum = 0xF;
464 
465 	if (FactorToSet <= 3) {
466 		FactorToSet = (1 << (FactorToSet + 2));
467 		if (FactorToSet > MaxAggNum)
468 			FactorToSet = MaxAggNum;
469 
470 		for (index = 0; index < 4; index++) {
471 			if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4))
472 				pRegToSet[index] = (pRegToSet[index] & 0x0f) |
473 					(FactorToSet << 4);
474 
475 			if ((pRegToSet[index] & 0x0f) > FactorToSet)
476 				pRegToSet[index] = (pRegToSet[index] & 0xf0) |
477 					FactorToSet;
478 
479 			rtl8723au_write8(padapter, REG_AGGLEN_LMT + index,
480 					 pRegToSet[index]);
481 		}
482 
483 		/* RT_TRACE(COMP_MLME, DBG_LOUD,
484 		   ("Set HW_VAR_AMPDU_FACTOR: %#x\n", FactorToSet)); */
485 	}
486 }
487 
rtl8723a_set_acm_ctrl(struct rtw_adapter * padapter,u8 ctrl)488 void rtl8723a_set_acm_ctrl(struct rtw_adapter *padapter, u8 ctrl)
489 {
490 	u8 hwctrl = 0;
491 
492 	if (ctrl != 0) {
493 		hwctrl |= AcmHw_HwEn;
494 
495 		if (ctrl & BIT(1))	/*  BE */
496 			hwctrl |= AcmHw_BeqEn;
497 
498 		if (ctrl & BIT(2))	/*  VI */
499 			hwctrl |= AcmHw_ViqEn;
500 
501 		if (ctrl & BIT(3))	/*  VO */
502 			hwctrl |= AcmHw_VoqEn;
503 	}
504 
505 	DBG_8723A("[HW_VAR_ACM_CTRL] Write 0x%02X\n", hwctrl);
506 	rtl8723au_write8(padapter, REG_ACMHWCTRL, hwctrl);
507 }
508 
rtl8723a_set_media_status(struct rtw_adapter * padapter,u8 status)509 void rtl8723a_set_media_status(struct rtw_adapter *padapter, u8 status)
510 {
511 	u8 val8;
512 
513 	val8 = rtl8723au_read8(padapter, MSR) & 0x0c;
514 	val8 |= status;
515 	rtl8723au_write8(padapter, MSR, val8);
516 }
517 
rtl8723a_set_media_status1(struct rtw_adapter * padapter,u8 status)518 void rtl8723a_set_media_status1(struct rtw_adapter *padapter, u8 status)
519 {
520 	u8 val8;
521 
522 	val8 = rtl8723au_read8(padapter, MSR) & 0x03;
523 	val8 |= status << 2;
524 	rtl8723au_write8(padapter, MSR, val8);
525 }
526 
rtl8723a_set_bcn_func(struct rtw_adapter * padapter,u8 val)527 void rtl8723a_set_bcn_func(struct rtw_adapter *padapter, u8 val)
528 {
529 	if (val)
530 		SetBcnCtrlReg23a(padapter, EN_BCN_FUNCTION | EN_TXBCN_RPT, 0);
531 	else
532 		SetBcnCtrlReg23a(padapter, 0, EN_BCN_FUNCTION | EN_TXBCN_RPT);
533 }
534 
rtl8723a_check_bssid(struct rtw_adapter * padapter,u8 val)535 void rtl8723a_check_bssid(struct rtw_adapter *padapter, u8 val)
536 {
537 	u32 val32;
538 
539 	val32 = rtl8723au_read32(padapter, REG_RCR);
540 	if (val)
541 		val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
542 	else
543 		val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
544 	rtl8723au_write32(padapter, REG_RCR, val32);
545 }
546 
rtl8723a_mlme_sitesurvey(struct rtw_adapter * padapter,u8 flag)547 void rtl8723a_mlme_sitesurvey(struct rtw_adapter *padapter, u8 flag)
548 {
549 	if (flag) {	/* under sitesurvey */
550 		u32 v32;
551 
552 		/*  config RCR to receive different BSSID & not
553 		    to receive data frame */
554 		v32 = rtl8723au_read32(padapter, REG_RCR);
555 		v32 &= ~(RCR_CBSSID_BCN);
556 		rtl8723au_write32(padapter, REG_RCR, v32);
557 		/*  reject all data frame */
558 		rtl8723au_write16(padapter, REG_RXFLTMAP2, 0);
559 
560 		/*  disable update TSF */
561 		SetBcnCtrlReg23a(padapter, DIS_TSF_UDT, 0);
562 	} else {	/* sitesurvey done */
563 
564 		struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
565 		struct mlme_ext_info *pmlmeinfo;
566 		u32 v32;
567 
568 		pmlmeinfo = &pmlmeext->mlmext_info;
569 
570 		if ((is_client_associated_to_ap23a(padapter) == true) ||
571 		    ((pmlmeinfo->state & 0x03) == MSR_ADHOC) ||
572 		    ((pmlmeinfo->state & 0x03) == MSR_AP)) {
573 			/*  enable to rx data frame */
574 			rtl8723au_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
575 
576 			/*  enable update TSF */
577 			SetBcnCtrlReg23a(padapter, 0, DIS_TSF_UDT);
578 		}
579 
580 		v32 = rtl8723au_read32(padapter, REG_RCR);
581 		v32 |= RCR_CBSSID_BCN;
582 		rtl8723au_write32(padapter, REG_RCR, v32);
583 	}
584 
585 	rtl8723a_BT_wifiscan_notify(padapter, flag ? true : false);
586 }
587 
rtl8723a_on_rcr_am(struct rtw_adapter * padapter)588 void rtl8723a_on_rcr_am(struct rtw_adapter *padapter)
589 {
590 	rtl8723au_write32(padapter, REG_RCR,
591 		    rtl8723au_read32(padapter, REG_RCR) | RCR_AM);
592 	DBG_8723A("%s, %d, RCR = %x\n", __func__, __LINE__,
593 		  rtl8723au_read32(padapter, REG_RCR));
594 }
595 
rtl8723a_off_rcr_am(struct rtw_adapter * padapter)596 void rtl8723a_off_rcr_am(struct rtw_adapter *padapter)
597 {
598 	rtl8723au_write32(padapter, REG_RCR,
599 		    rtl8723au_read32(padapter, REG_RCR) & (~RCR_AM));
600 	DBG_8723A("%s, %d, RCR = %x\n", __func__, __LINE__,
601 		  rtl8723au_read32(padapter, REG_RCR));
602 }
603 
rtl8723a_set_slot_time(struct rtw_adapter * padapter,u8 slottime)604 void rtl8723a_set_slot_time(struct rtw_adapter *padapter, u8 slottime)
605 {
606 	u8 u1bAIFS, aSifsTime;
607 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
608 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
609 
610 	rtl8723au_write8(padapter, REG_SLOT, slottime);
611 
612 	if (pmlmeinfo->WMM_enable == 0) {
613 		if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
614 			aSifsTime = 10;
615 		else
616 			aSifsTime = 16;
617 
618 		u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
619 
620 		/*  <Roger_EXP> Temporary removed, 2008.06.20. */
621 		rtl8723au_write8(padapter, REG_EDCA_VO_PARAM, u1bAIFS);
622 		rtl8723au_write8(padapter, REG_EDCA_VI_PARAM, u1bAIFS);
623 		rtl8723au_write8(padapter, REG_EDCA_BE_PARAM, u1bAIFS);
624 		rtl8723au_write8(padapter, REG_EDCA_BK_PARAM, u1bAIFS);
625 	}
626 }
627 
rtl8723a_ack_preamble(struct rtw_adapter * padapter,u8 bShortPreamble)628 void rtl8723a_ack_preamble(struct rtw_adapter *padapter, u8 bShortPreamble)
629 {
630 	struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
631 	u8 regTmp;
632 
633 	/*  Joseph marked out for Netgear 3500 TKIP
634 	    channel 7 issue.(Temporarily) */
635 	regTmp = (pHalData->nCur40MhzPrimeSC) << 5;
636 	/* regTmp = 0; */
637 	if (bShortPreamble)
638 		regTmp |= 0x80;
639 	rtl8723au_write8(padapter, REG_RRSR + 2, regTmp);
640 }
641 
rtl8723a_set_sec_cfg(struct rtw_adapter * padapter,u8 sec)642 void rtl8723a_set_sec_cfg(struct rtw_adapter *padapter, u8 sec)
643 {
644 	rtl8723au_write8(padapter, REG_SECCFG, sec);
645 }
646 
rtl8723a_cam_empty_entry(struct rtw_adapter * padapter,u8 ucIndex)647 void rtl8723a_cam_empty_entry(struct rtw_adapter *padapter, u8 ucIndex)
648 {
649 	u8 i;
650 	u32 ulCommand = 0;
651 	u32 ulContent = 0;
652 	u32 ulEncAlgo = CAM_AES;
653 
654 	for (i = 0; i < CAM_CONTENT_COUNT; i++) {
655 		/*  filled id in CAM config 2 byte */
656 		if (i == 0) {
657 			ulContent |= (ucIndex & 0x03) |
658 				((u16) (ulEncAlgo) << 2);
659 			/* ulContent |= CAM_VALID; */
660 		} else {
661 			ulContent = 0;
662 		}
663 		/*  polling bit, and No Write enable, and address */
664 		ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
665 		ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
666 		/*  write content 0 is equall to mark invalid */
667 		/* delay_ms(40); */
668 		rtl8723au_write32(padapter, WCAMI, ulContent);
669 		/* RT_TRACE(COMP_SEC, DBG_LOUD,
670 		   ("rtl8723a_cam_empty_entry(): WRITE A4: %lx\n",
671 		   ulContent));*/
672 		/* delay_ms(40); */
673 		rtl8723au_write32(padapter, REG_CAMCMD, ulCommand);
674 		/* RT_TRACE(COMP_SEC, DBG_LOUD,
675 		   ("rtl8723a_cam_empty_entry(): WRITE A0: %lx\n",
676 		   ulCommand));*/
677 	}
678 }
679 
rtl8723a_cam_invalidate_all(struct rtw_adapter * padapter)680 void rtl8723a_cam_invalidate_all(struct rtw_adapter *padapter)
681 {
682 	rtl8723au_write32(padapter, REG_CAMCMD, CAM_POLLINIG | BIT(30));
683 }
684 
rtl8723a_cam_write(struct rtw_adapter * padapter,u8 entry,u16 ctrl,const u8 * mac,const u8 * key)685 void rtl8723a_cam_write(struct rtw_adapter *padapter,
686 			u8 entry, u16 ctrl, const u8 *mac, const u8 *key)
687 {
688 	u32 cmd;
689 	unsigned int i, val, addr;
690 	int j;
691 
692 	addr = entry << 3;
693 
694 	for (j = 5; j >= 0; j--) {
695 		switch (j) {
696 		case 0:
697 			val = ctrl | (mac[0] << 16) | (mac[1] << 24);
698 			break;
699 		case 1:
700 			val = mac[2] | (mac[3] << 8) |
701 				(mac[4] << 16) | (mac[5] << 24);
702 			break;
703 		default:
704 			i = (j - 2) << 2;
705 			val = key[i] | (key[i+1] << 8) |
706 				(key[i+2] << 16) | (key[i+3] << 24);
707 			break;
708 		}
709 
710 		rtl8723au_write32(padapter, WCAMI, val);
711 		cmd = CAM_POLLINIG | CAM_WRITE | (addr + j);
712 		rtl8723au_write32(padapter, REG_CAMCMD, cmd);
713 
714 		/* DBG_8723A("%s => cam write: %x, %x\n", __func__, cmd, val);*/
715 	}
716 }
717 
rtl8723a_fifo_cleanup(struct rtw_adapter * padapter)718 void rtl8723a_fifo_cleanup(struct rtw_adapter *padapter)
719 {
720 #define RW_RELEASE_EN		BIT(18)
721 #define RXDMA_IDLE		BIT(17)
722 
723 	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
724 	u8 trycnt = 100;
725 
726 	/*  pause tx */
727 	rtl8723au_write8(padapter, REG_TXPAUSE, 0xff);
728 
729 	/*  keep sn */
730 	padapter->xmitpriv.nqos_ssn = rtl8723au_read16(padapter, REG_NQOS_SEQ);
731 
732 	if (pwrpriv->bkeepfwalive != true) {
733 		u32 v32;
734 
735 		/*  RX DMA stop */
736 		v32 = rtl8723au_read32(padapter, REG_RXPKT_NUM);
737 		v32 |= RW_RELEASE_EN;
738 		rtl8723au_write32(padapter, REG_RXPKT_NUM, v32);
739 		do {
740 			v32 = rtl8723au_read32(padapter,
741 					       REG_RXPKT_NUM) & RXDMA_IDLE;
742 			if (!v32)
743 				break;
744 		} while (trycnt--);
745 		if (trycnt == 0)
746 			DBG_8723A("Stop RX DMA failed......\n");
747 
748 		/*  RQPN Load 0 */
749 		rtl8723au_write16(padapter, REG_RQPN_NPQ, 0);
750 		rtl8723au_write32(padapter, REG_RQPN, 0x80000000);
751 		mdelay(10);
752 	}
753 }
754 
rtl8723a_bcn_valid(struct rtw_adapter * padapter)755 void rtl8723a_bcn_valid(struct rtw_adapter *padapter)
756 {
757 	/* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2,
758 	   write 1 to clear, Clear by sw */
759 	rtl8723au_write8(padapter, REG_TDECTRL + 2,
760 			 rtl8723au_read8(padapter, REG_TDECTRL + 2) | BIT(0));
761 }
762 
rtl8723a_get_bcn_valid(struct rtw_adapter * padapter)763 bool rtl8723a_get_bcn_valid(struct rtw_adapter *padapter)
764 {
765 	bool retval;
766 
767 	retval = (rtl8723au_read8(padapter, REG_TDECTRL + 2) & BIT(0)) ? true : false;
768 
769 	return retval;
770 }
771 
rtl8723a_set_beacon_interval(struct rtw_adapter * padapter,u16 interval)772 void rtl8723a_set_beacon_interval(struct rtw_adapter *padapter, u16 interval)
773 {
774 	rtl8723au_write16(padapter, REG_BCN_INTERVAL, interval);
775 }
776 
rtl8723a_set_resp_sifs(struct rtw_adapter * padapter,u8 r2t1,u8 r2t2,u8 t2t1,u8 t2t2)777 void rtl8723a_set_resp_sifs(struct rtw_adapter *padapter,
778 			    u8 r2t1, u8 r2t2, u8 t2t1, u8 t2t2)
779 {
780 	/* SIFS_Timer = 0x0a0a0808; */
781 	/* RESP_SIFS for CCK */
782 	/*  SIFS_T2T_CCK (0x08) */
783 	rtl8723au_write8(padapter, REG_R2T_SIFS, r2t1);
784 	/* SIFS_R2T_CCK(0x08) */
785 	rtl8723au_write8(padapter, REG_R2T_SIFS + 1, r2t2);
786 	/* RESP_SIFS for OFDM */
787 	/* SIFS_T2T_OFDM (0x0a) */
788 	rtl8723au_write8(padapter, REG_T2T_SIFS, t2t1);
789 	/* SIFS_R2T_OFDM(0x0a) */
790 	rtl8723au_write8(padapter, REG_T2T_SIFS + 1, t2t2);
791 }
792 
rtl8723a_set_ac_param_vo(struct rtw_adapter * padapter,u32 vo)793 void rtl8723a_set_ac_param_vo(struct rtw_adapter *padapter, u32 vo)
794 {
795 	rtl8723au_write32(padapter, REG_EDCA_VO_PARAM, vo);
796 }
797 
rtl8723a_set_ac_param_vi(struct rtw_adapter * padapter,u32 vi)798 void rtl8723a_set_ac_param_vi(struct rtw_adapter *padapter, u32 vi)
799 {
800 	rtl8723au_write32(padapter, REG_EDCA_VI_PARAM, vi);
801 }
802 
rtl8723a_set_ac_param_be(struct rtw_adapter * padapter,u32 be)803 void rtl8723a_set_ac_param_be(struct rtw_adapter *padapter, u32 be)
804 {
805 	struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
806 
807 	pHalData->AcParam_BE = be;
808 	rtl8723au_write32(padapter, REG_EDCA_BE_PARAM, be);
809 }
810 
rtl8723a_set_ac_param_bk(struct rtw_adapter * padapter,u32 bk)811 void rtl8723a_set_ac_param_bk(struct rtw_adapter *padapter, u32 bk)
812 {
813 	rtl8723au_write32(padapter, REG_EDCA_BK_PARAM, bk);
814 }
815 
rtl8723a_set_rxdma_agg_pg_th(struct rtw_adapter * padapter,u8 val)816 void rtl8723a_set_rxdma_agg_pg_th(struct rtw_adapter *padapter, u8 val)
817 {
818 	rtl8723au_write8(padapter, REG_RXDMA_AGG_PG_TH, val);
819 }
820 
rtl8723a_set_initial_gain(struct rtw_adapter * padapter,u32 rx_gain)821 void rtl8723a_set_initial_gain(struct rtw_adapter *padapter, u32 rx_gain)
822 {
823 	struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
824 	struct dig_t *pDigTable = &pHalData->odmpriv.DM_DigTable;
825 
826 	if (rx_gain == 0xff)	/* restore rx gain */
827 		ODM_Write_DIG23a(&pHalData->odmpriv, pDigTable->BackupIGValue);
828 	else {
829 		pDigTable->BackupIGValue = pDigTable->CurIGValue;
830 		ODM_Write_DIG23a(&pHalData->odmpriv, rx_gain);
831 	}
832 }
833 
rtl8723a_odm_support_ability_restore(struct rtw_adapter * padapter)834 void rtl8723a_odm_support_ability_restore(struct rtw_adapter *padapter)
835 {
836 	struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
837 
838 	pHalData->odmpriv.SupportAbility = pHalData->odmpriv.BK_SupportAbility;
839 }
840 
rtl8723a_odm_support_ability_backup(struct rtw_adapter * padapter)841 void rtl8723a_odm_support_ability_backup(struct rtw_adapter *padapter)
842 {
843 	struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
844 
845 	pHalData->odmpriv.BK_SupportAbility = pHalData->odmpriv.SupportAbility;
846 }
847 
rtl8723a_odm_support_ability_set(struct rtw_adapter * padapter,u32 val)848 void rtl8723a_odm_support_ability_set(struct rtw_adapter *padapter, u32 val)
849 {
850 	struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
851 
852 	if (val == DYNAMIC_ALL_FUNC_ENABLE)
853 		pHalData->odmpriv.SupportAbility = pHalData->dmpriv.InitODMFlag;
854 	else
855 		pHalData->odmpriv.SupportAbility |= val;
856 }
857 
rtl8723a_odm_support_ability_clr(struct rtw_adapter * padapter,u32 val)858 void rtl8723a_odm_support_ability_clr(struct rtw_adapter *padapter, u32 val)
859 {
860 	struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
861 
862 	pHalData->odmpriv.SupportAbility &= val;
863 }
864 
rtl8723a_set_rpwm(struct rtw_adapter * padapter,u8 val)865 void rtl8723a_set_rpwm(struct rtw_adapter *padapter, u8 val)
866 {
867 	rtl8723au_write8(padapter, REG_USB_HRPWM, val);
868 }
869 
rtl8723a_get_rf_type(struct rtw_adapter * padapter)870 u8 rtl8723a_get_rf_type(struct rtw_adapter *padapter)
871 {
872 	struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
873 
874 	return pHalData->rf_type;
875 }
876 
rtl8723a_get_fwlps_rf_on(struct rtw_adapter * padapter)877 bool rtl8723a_get_fwlps_rf_on(struct rtw_adapter *padapter)
878 {
879 	bool retval;
880 	u32 valRCR;
881 
882 	/*  When we halt NIC, we should check if FW LPS is leave. */
883 
884 	if ((padapter->bSurpriseRemoved == true) ||
885 	    (padapter->pwrctrlpriv.rf_pwrstate == rf_off)) {
886 		/*  If it is in HW/SW Radio OFF or IPS state, we do
887 		    not check Fw LPS Leave, because Fw is unload. */
888 		retval = true;
889 	} else {
890 		valRCR = rtl8723au_read32(padapter, REG_RCR);
891 		if (valRCR & 0x00070000)
892 			retval = false;
893 		else
894 			retval = true;
895 	}
896 
897 	return retval;
898 }
899 
rtl8723a_chk_hi_queue_empty(struct rtw_adapter * padapter)900 bool rtl8723a_chk_hi_queue_empty(struct rtw_adapter *padapter)
901 {
902 	u32 hgq;
903 
904 	hgq = rtl8723au_read32(padapter, REG_HGQ_INFORMATION);
905 
906 	return ((hgq & 0x0000ff00) == 0) ? true : false;
907 }
908