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