]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/staging/rtl8723au/hal/hal_com.c
staging: rtl8723au: Remove RegBcnCtrlVal
[mirror_ubuntu-bionic-kernel.git] / drivers / staging / rtl8723au / hal / hal_com.c
CommitLineData
f7c92d2c
LF
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>
050abc45 21#include <usb_ops_linux.h>
f7c92d2c
LF
22
23#define _HAL_INIT_C_
24
25void 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 */
71u8 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
97u8 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
156void 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. */
edbfd672
JS
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);
f7c92d2c
LF
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 */
edbfd672 238 rtl8723au_write8(padapter, REG_INIRTS_RATE_SEL, rate_index);
f7c92d2c
LF
239
240 return;
241}
242
243static 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
258static 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
291static 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
324bool 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
f7c92d2c
LF
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
354void c2h_evt_clear23a(struct rtw_adapter *adapter)
355{
edbfd672 356 rtl8723au_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
f7c92d2c
LF
357}
358
18bd6df2 359int c2h_evt_read23a(struct rtw_adapter *adapter, u8 *buf)
f7c92d2c 360{
18bd6df2 361 int ret = _FAIL;
f7c92d2c
LF
362 struct c2h_evt_hdr *c2h_evt;
363 int i;
364 u8 trigger;
365
366 if (buf == NULL)
367 goto exit;
368
050abc45 369 trigger = rtl8723au_read8(adapter, REG_C2HEVT_CLEAR);
f7c92d2c
LF
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
050abc45
JS
380 *buf = rtl8723au_read8(adapter, REG_C2HEVT_MSG_NORMAL);
381 *(buf + 1) = rtl8723au_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);
f7c92d2c
LF
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++)
050abc45 394 c2h_evt->payload[i] = rtl8723au_read8(adapter,
f7c92d2c
LF
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
404clear_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);
411exit:
412 return ret;
413}
414
415void
416rtl8723a_set_ampdu_min_space(struct rtw_adapter *padapter, u8 MinSpacingToSet)
417{
418 u8 SecMinSpace;
419
420 if (MinSpacingToSet <= 7) {
421 switch (padapter->securitypriv.dot11PrivacyAlgrthm) {
9e3d6df2
JS
422 case 0:
423 case WLAN_CIPHER_SUITE_CCMP:
f7c92d2c
LF
424 SecMinSpace = 0;
425 break;
426
9e3d6df2
JS
427 case WLAN_CIPHER_SUITE_WEP40:
428 case WLAN_CIPHER_SUITE_WEP104:
429 case WLAN_CIPHER_SUITE_TKIP:
f7c92d2c
LF
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 |=
050abc45 444 rtl8723au_read8(padapter, REG_AMPDU_MIN_SPACE) & 0xf8;
edbfd672
JS
445 rtl8723au_write8(padapter, REG_AMPDU_MIN_SPACE,
446 MinSpacingToSet);
f7c92d2c
LF
447 }
448}
449
450void 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; */
bf2a7b99
JS
458
459 if (rtl8723a_BT_enabled(padapter) &&
460 rtl8723a_BT_using_antenna_1(padapter))
f7c92d2c 461 MaxAggNum = 0x8;
bf2a7b99 462 else
f7c92d2c 463 MaxAggNum = 0xF;
f7c92d2c
LF
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
edbfd672
JS
479 rtl8723au_write8(padapter, REG_AGGLEN_LMT + index,
480 pRegToSet[index]);
f7c92d2c
LF
481 }
482
483 /* RT_TRACE(COMP_MLME, DBG_LOUD,
484 ("Set HW_VAR_AMPDU_FACTOR: %#x\n", FactorToSet)); */
485 }
486}
487
488void 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);
edbfd672 506 rtl8723au_write8(padapter, REG_ACMHWCTRL, hwctrl);
f7c92d2c
LF
507}
508
509void rtl8723a_set_media_status(struct rtw_adapter *padapter, u8 status)
510{
511 u8 val8;
512
050abc45 513 val8 = rtl8723au_read8(padapter, MSR) & 0x0c;
f7c92d2c 514 val8 |= status;
edbfd672 515 rtl8723au_write8(padapter, MSR, val8);
f7c92d2c
LF
516}
517
518void rtl8723a_set_media_status1(struct rtw_adapter *padapter, u8 status)
519{
520 u8 val8;
521
050abc45 522 val8 = rtl8723au_read8(padapter, MSR) & 0x03;
f7c92d2c 523 val8 |= status << 2;
edbfd672 524 rtl8723au_write8(padapter, MSR, val8);
f7c92d2c
LF
525}
526
527void 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
535void rtl8723a_check_bssid(struct rtw_adapter *padapter, u8 val)
536{
537 u32 val32;
050abc45 538 val32 = rtl8723au_read32(padapter, REG_RCR);
f7c92d2c
LF
539 if (val)
540 val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
541 else
542 val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
edbfd672 543 rtl8723au_write32(padapter, REG_RCR, val32);
f7c92d2c
LF
544}
545
546void rtl8723a_mlme_sitesurvey(struct rtw_adapter *padapter, u8 flag)
547{
548 if (flag) { /* under sitesurvey */
549 u32 v32;
550
551 /* config RCR to receive different BSSID & not
552 to receive data frame */
050abc45 553 v32 = rtl8723au_read32(padapter, REG_RCR);
f7c92d2c 554 v32 &= ~(RCR_CBSSID_BCN);
edbfd672 555 rtl8723au_write32(padapter, REG_RCR, v32);
f7c92d2c 556 /* reject all data frame */
edbfd672 557 rtl8723au_write16(padapter, REG_RXFLTMAP2, 0);
f7c92d2c
LF
558
559 /* disable update TSF */
560 SetBcnCtrlReg23a(padapter, DIS_TSF_UDT, 0);
561 } else { /* sitesurvey done */
562
563 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
564 struct mlme_ext_info *pmlmeinfo;
565 u32 v32;
566
567 pmlmeinfo = &pmlmeext->mlmext_info;
568
569 if ((is_client_associated_to_ap23a(padapter) == true) ||
6ec26273
JS
570 ((pmlmeinfo->state & 0x03) == MSR_ADHOC) ||
571 ((pmlmeinfo->state & 0x03) == MSR_AP)) {
f7c92d2c 572 /* enable to rx data frame */
edbfd672 573 rtl8723au_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
f7c92d2c
LF
574
575 /* enable update TSF */
576 SetBcnCtrlReg23a(padapter, 0, DIS_TSF_UDT);
577 }
578
050abc45 579 v32 = rtl8723au_read32(padapter, REG_RCR);
f7c92d2c 580 v32 |= RCR_CBSSID_BCN;
edbfd672 581 rtl8723au_write32(padapter, REG_RCR, v32);
f7c92d2c
LF
582 }
583
d952e4c4 584 rtl8723a_BT_wifiscan_notify(padapter, flag ? true : false);
f7c92d2c
LF
585}
586
587void rtl8723a_on_rcr_am(struct rtw_adapter *padapter)
588{
edbfd672 589 rtl8723au_write32(padapter, REG_RCR,
050abc45 590 rtl8723au_read32(padapter, REG_RCR) | RCR_AM);
f8628a47 591 DBG_8723A("%s, %d, RCR = %x \n", __func__, __LINE__,
050abc45 592 rtl8723au_read32(padapter, REG_RCR));
f7c92d2c
LF
593}
594
595void rtl8723a_off_rcr_am(struct rtw_adapter *padapter)
596{
edbfd672 597 rtl8723au_write32(padapter, REG_RCR,
050abc45 598 rtl8723au_read32(padapter, REG_RCR) & (~RCR_AM));
f8628a47 599 DBG_8723A("%s, %d, RCR = %x \n", __func__, __LINE__,
050abc45 600 rtl8723au_read32(padapter, REG_RCR));
f7c92d2c
LF
601}
602
603void rtl8723a_set_slot_time(struct rtw_adapter *padapter, u8 slottime)
604{
605 u8 u1bAIFS, aSifsTime;
606 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
607 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
608
edbfd672 609 rtl8723au_write8(padapter, REG_SLOT, slottime);
f7c92d2c
LF
610
611 if (pmlmeinfo->WMM_enable == 0) {
612 if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
613 aSifsTime = 10;
614 else
615 aSifsTime = 16;
616
617 u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
618
619 /* <Roger_EXP> Temporary removed, 2008.06.20. */
edbfd672
JS
620 rtl8723au_write8(padapter, REG_EDCA_VO_PARAM, u1bAIFS);
621 rtl8723au_write8(padapter, REG_EDCA_VI_PARAM, u1bAIFS);
622 rtl8723au_write8(padapter, REG_EDCA_BE_PARAM, u1bAIFS);
623 rtl8723au_write8(padapter, REG_EDCA_BK_PARAM, u1bAIFS);
f7c92d2c
LF
624 }
625}
626
627void rtl8723a_ack_preamble(struct rtw_adapter *padapter, u8 bShortPreamble)
628{
629 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
630 u8 regTmp;
631
632 /* Joseph marked out for Netgear 3500 TKIP
633 channel 7 issue.(Temporarily) */
634 regTmp = (pHalData->nCur40MhzPrimeSC) << 5;
635 /* regTmp = 0; */
636 if (bShortPreamble)
637 regTmp |= 0x80;
edbfd672 638 rtl8723au_write8(padapter, REG_RRSR + 2, regTmp);
f7c92d2c
LF
639}
640
641void rtl8723a_set_sec_cfg(struct rtw_adapter *padapter, u8 sec)
642{
edbfd672 643 rtl8723au_write8(padapter, REG_SECCFG, sec);
f7c92d2c
LF
644}
645
646void rtl8723a_cam_empty_entry(struct rtw_adapter *padapter, u8 ucIndex)
647{
648 u8 i;
649 u32 ulCommand = 0;
650 u32 ulContent = 0;
651 u32 ulEncAlgo = CAM_AES;
652
653 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
654 /* filled id in CAM config 2 byte */
655 if (i == 0) {
656 ulContent |= (ucIndex & 0x03) |
657 ((u16) (ulEncAlgo) << 2);
658 /* ulContent |= CAM_VALID; */
659 } else {
660 ulContent = 0;
661 }
662 /* polling bit, and No Write enable, and address */
663 ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
664 ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
665 /* write content 0 is equall to mark invalid */
666 /* delay_ms(40); */
edbfd672 667 rtl8723au_write32(padapter, WCAMI, ulContent);
f7c92d2c 668 /* RT_TRACE(COMP_SEC, DBG_LOUD,
a15a46a7
JS
669 ("rtl8723a_cam_empty_entry(): WRITE A4: %lx \n",
670 ulContent));*/
f7c92d2c 671 /* delay_ms(40); */
edbfd672 672 rtl8723au_write32(padapter, RWCAM, ulCommand);
f7c92d2c 673 /* RT_TRACE(COMP_SEC, DBG_LOUD,
a15a46a7
JS
674 ("rtl8723a_cam_empty_entry(): WRITE A0: %lx \n",
675 ulCommand));*/
f7c92d2c
LF
676 }
677}
678
679void rtl8723a_cam_invalid_all(struct rtw_adapter *padapter)
680{
edbfd672 681 rtl8723au_write32(padapter, RWCAM, BIT(31) | BIT(30));
f7c92d2c
LF
682}
683
dc0d16a1 684void rtl8723a_cam_write(struct rtw_adapter *padapter,
0348dc74 685 u8 entry, u16 ctrl, const u8 *mac, const u8 *key)
f7c92d2c
LF
686{
687 u32 cmd;
dc0d16a1
JS
688 unsigned int i, val, addr;
689 int j;
f7c92d2c 690
dc0d16a1 691 addr = entry << 3;
f7c92d2c 692
dc0d16a1
JS
693 for (j = 5; j >= 0; j--) {
694 switch (j) {
695 case 0:
696 val = ctrl | (mac[0] << 16) | (mac[1] << 24);
697 break;
698 case 1:
699 val = mac[2] | (mac[3] << 8) |
700 (mac[4] << 16) | (mac[5] << 24);
701 break;
702 default:
703 i = (j - 2) << 2;
704 val = key[i] | (key[i+1] << 8) |
705 (key[i+2] << 16) | (key[i+3] << 24);
706 break;
707 }
708
edbfd672 709 rtl8723au_write32(padapter, WCAMI, val);
dc0d16a1 710 cmd = CAM_POLLINIG | CAM_WRITE | (addr + j);
edbfd672 711 rtl8723au_write32(padapter, RWCAM, cmd);
dc0d16a1
JS
712
713 /* DBG_8723A("%s => cam write: %x, %x\n", __func__, cmd, val);*/
714 }
f7c92d2c
LF
715}
716
717void rtl8723a_fifo_cleanup(struct rtw_adapter *padapter)
718{
719#define RW_RELEASE_EN BIT(18)
720#define RXDMA_IDLE BIT(17)
721
722 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
723 u8 trycnt = 100;
724
725 /* pause tx */
edbfd672 726 rtl8723au_write8(padapter, REG_TXPAUSE, 0xff);
f7c92d2c
LF
727
728 /* keep sn */
050abc45 729 padapter->xmitpriv.nqos_ssn = rtl8723au_read16(padapter, REG_NQOS_SEQ);
f7c92d2c
LF
730
731 if (pwrpriv->bkeepfwalive != true) {
732 u32 v32;
733
734 /* RX DMA stop */
050abc45 735 v32 = rtl8723au_read32(padapter, REG_RXPKT_NUM);
f7c92d2c 736 v32 |= RW_RELEASE_EN;
edbfd672 737 rtl8723au_write32(padapter, REG_RXPKT_NUM, v32);
f7c92d2c 738 do {
050abc45
JS
739 v32 = rtl8723au_read32(padapter,
740 REG_RXPKT_NUM) & RXDMA_IDLE;
f7c92d2c
LF
741 if (!v32)
742 break;
743 } while (trycnt--);
744 if (trycnt == 0) {
745 DBG_8723A("Stop RX DMA failed......\n");
746 }
747
748 /* RQPN Load 0 */
edbfd672
JS
749 rtl8723au_write16(padapter, REG_RQPN_NPQ, 0);
750 rtl8723au_write32(padapter, REG_RQPN, 0x80000000);
f7c92d2c
LF
751 mdelay(10);
752 }
753}
754
f7c92d2c
LF
755void 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 */
edbfd672
JS
759 rtl8723au_write8(padapter, REG_TDECTRL + 2,
760 rtl8723au_read8(padapter, REG_TDECTRL + 2) | BIT(0));
f7c92d2c
LF
761}
762
ff5d82e4
JS
763bool rtl8723a_get_bcn_valid(struct rtw_adapter *padapter)
764{
765 bool retval;
766
050abc45 767 retval = (rtl8723au_read8(padapter, REG_TDECTRL + 2) & BIT(0)) ? true : false;
ff5d82e4
JS
768
769 return retval;
770}
771
f7c92d2c
LF
772void rtl8723a_set_beacon_interval(struct rtw_adapter *padapter, u16 interval)
773{
edbfd672 774 rtl8723au_write16(padapter, REG_BCN_INTERVAL, interval);
f7c92d2c
LF
775}
776
777void 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) */
edbfd672 783 rtl8723au_write8(padapter, REG_R2T_SIFS, r2t1);
f7c92d2c 784 /* SIFS_R2T_CCK(0x08) */
edbfd672 785 rtl8723au_write8(padapter, REG_R2T_SIFS + 1, r2t2);
f7c92d2c
LF
786 /* RESP_SIFS for OFDM */
787 /* SIFS_T2T_OFDM (0x0a) */
edbfd672 788 rtl8723au_write8(padapter, REG_T2T_SIFS, t2t1);
f7c92d2c 789 /* SIFS_R2T_OFDM(0x0a) */
edbfd672 790 rtl8723au_write8(padapter, REG_T2T_SIFS + 1, t2t2);
f7c92d2c
LF
791}
792
793void rtl8723a_set_ac_param_vo(struct rtw_adapter *padapter, u32 vo)
794{
edbfd672 795 rtl8723au_write32(padapter, REG_EDCA_VO_PARAM, vo);
f7c92d2c
LF
796}
797
798void rtl8723a_set_ac_param_vi(struct rtw_adapter *padapter, u32 vi)
799{
edbfd672 800 rtl8723au_write32(padapter, REG_EDCA_VI_PARAM, vi);
f7c92d2c
LF
801}
802
803void 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;
edbfd672 808 rtl8723au_write32(padapter, REG_EDCA_BE_PARAM, be);
f7c92d2c
LF
809}
810
811void rtl8723a_set_ac_param_bk(struct rtw_adapter *padapter, u32 bk)
812{
edbfd672 813 rtl8723au_write32(padapter, REG_EDCA_BK_PARAM, bk);
f7c92d2c
LF
814}
815
816void rtl8723a_set_rxdma_agg_pg_th(struct rtw_adapter *padapter, u8 val)
817{
edbfd672 818 rtl8723au_write8(padapter, REG_RXDMA_AGG_PG_TH, val);
f7c92d2c
LF
819}
820
821void rtl8723a_set_nav_upper(struct rtw_adapter *padapter, u32 usNavUpper)
822{
823 if (usNavUpper > HAL_8723A_NAV_UPPER_UNIT * 0xFF) {
824 RT_TRACE(_module_hal_init_c_, _drv_notice_,
825 ("The setting value (0x%08X us) of NAV_UPPER "
826 "is larger than (%d * 0xFF)!!!\n",
827 usNavUpper, HAL_8723A_NAV_UPPER_UNIT));
828 return;
829 }
830
831 /* The value of ((usNavUpper + HAL_8723A_NAV_UPPER_UNIT - 1) /
832 HAL_8723A_NAV_UPPER_UNIT) */
833 /* is getting the upper integer. */
834 usNavUpper = (usNavUpper + HAL_8723A_NAV_UPPER_UNIT - 1) /
835 HAL_8723A_NAV_UPPER_UNIT;
edbfd672 836 rtl8723au_write8(padapter, REG_NAV_UPPER, (u8) usNavUpper);
f7c92d2c
LF
837}
838
839void rtl8723a_set_initial_gain(struct rtw_adapter *padapter, u32 rx_gain)
840{
841 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
842 struct dig_t *pDigTable = &pHalData->odmpriv.DM_DigTable;
843
844 if (rx_gain == 0xff) /* restore rx gain */
845 ODM_Write_DIG23a(&pHalData->odmpriv, pDigTable->BackupIGValue);
846 else {
847 pDigTable->BackupIGValue = pDigTable->CurIGValue;
848 ODM_Write_DIG23a(&pHalData->odmpriv, rx_gain);
849 }
850}
851
a945bf30 852void rtl8723a_odm_support_ability_restore(struct rtw_adapter *padapter)
f7c92d2c
LF
853{
854 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
855
a945bf30
JS
856 pHalData->odmpriv.SupportAbility = pHalData->odmpriv.BK_SupportAbility;
857}
858
859void rtl8723a_odm_support_ability_backup(struct rtw_adapter *padapter)
860{
861 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
862
863 pHalData->odmpriv.BK_SupportAbility = pHalData->odmpriv.SupportAbility;
f7c92d2c
LF
864}
865
866void rtl8723a_odm_support_ability_set(struct rtw_adapter *padapter, u32 val)
867{
868 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
869
870 if (val == DYNAMIC_ALL_FUNC_ENABLE) {
871 pHalData->dmpriv.DMFlag = pHalData->dmpriv.InitDMFlag;
872 pHalData->odmpriv.SupportAbility = pHalData->dmpriv.InitODMFlag;
873 } else {
874 pHalData->odmpriv.SupportAbility |= val;
875 }
876}
877
878void rtl8723a_odm_support_ability_clr(struct rtw_adapter *padapter, u32 val)
879{
880 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
881
882 pHalData->odmpriv.SupportAbility &= val;
883}
884
885void rtl8723a_set_rpwm(struct rtw_adapter *padapter, u8 val)
886{
edbfd672 887 rtl8723au_write8(padapter, REG_USB_HRPWM, val);
f7c92d2c 888}
c2370e83
JS
889
890u8 rtl8723a_get_rf_type(struct rtw_adapter *padapter)
891{
892 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
893
894 return pHalData->rf_type;
895}
0cee8101
JS
896
897bool rtl8723a_get_fwlps_rf_on(struct rtw_adapter *padapter)
898{
899 bool retval;
900 u32 valRCR;
901
902 /* When we halt NIC, we should check if FW LPS is leave. */
903
904 if ((padapter->bSurpriseRemoved == true) ||
905 (padapter->pwrctrlpriv.rf_pwrstate == rf_off)) {
906 /* If it is in HW/SW Radio OFF or IPS state, we do
907 not check Fw LPS Leave, because Fw is unload. */
908 retval = true;
909 } else {
050abc45 910 valRCR = rtl8723au_read32(padapter, REG_RCR);
0cee8101
JS
911 if (valRCR & 0x00070000)
912 retval = false;
913 else
914 retval = true;
915 }
916
917 return retval;
918}
8d3fd614
JS
919
920bool rtl8723a_chk_hi_queue_empty(struct rtw_adapter *padapter)
921{
922 u32 hgq;
923
050abc45 924 hgq = rtl8723au_read32(padapter, REG_HGQ_INFORMATION);
8d3fd614
JS
925
926 return ((hgq & 0x0000ff00) == 0) ? true : false;
927}