Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nu11secur1ty
GitHub Repository: nu11secur1ty/Kali-Linux
Path: blob/master/ALFA-W1F1/RTL8814AU/hal/rtl8814a/rtl8814a_cmd.c
1307 views
1
/******************************************************************************
2
*
3
* Copyright(c) 2007 - 2017 Realtek Corporation.
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
#define _RTL8814A_CMD_C_
16
17
/* #include <drv_types.h> */
18
#include <rtl8814a_hal.h>
19
20
#define CONFIG_H2C_EF
21
22
#define RTL8814_MAX_H2C_BOX_NUMS 4
23
#define RTL8814_MAX_CMD_LEN 7
24
#define RTL8814_MESSAGE_BOX_SIZE 4
25
#define RTL8814_EX_MESSAGE_BOX_SIZE 4
26
27
28
static u8 _is_fw_read_cmd_down(_adapter *padapter, u8 msgbox_num)
29
{
30
u8 read_down = _FALSE;
31
int retry_cnts = 100;
32
33
u8 valid;
34
35
/* RTW_INFO(" _is_fw_read_cmd_down ,reg_1cc(%x),msg_box(%d)...\n",rtw_read8(padapter,REG_HMETFR),msgbox_num); */
36
37
do {
38
valid = rtw_read8(padapter, REG_HMETFR) & BIT(msgbox_num);
39
if (0 == valid)
40
read_down = _TRUE;
41
else
42
rtw_msleep_os(1);
43
} while ((!read_down) && (retry_cnts--));
44
45
return read_down;
46
47
}
48
49
50
/*****************************************
51
* H2C Msg format :
52
* 0x1DF - 0x1D0
53
*| 31 - 8 | 7-5 4 - 0 |
54
*| h2c_msg |Class_ID CMD_ID |
55
*
56
* Extend 0x1FF - 0x1F0
57
*|31 - 0 |
58
*|ext_msg|
59
******************************************/
60
s32 FillH2CCmd_8814(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)
61
{
62
u8 h2c_box_num;
63
u32 msgbox_addr;
64
u32 msgbox_ex_addr = 0;
65
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
66
u8 cmd_idx ;
67
u32 h2c_cmd = 0;
68
u32 h2c_cmd_ex = 0;
69
s32 ret = _FAIL;
70
71
72
padapter = GET_PRIMARY_ADAPTER(padapter);
73
pHalData = GET_HAL_DATA(padapter);
74
75
76
if (pHalData->bFWReady == _FALSE) {
77
/* RTW_INFO("FillH2CCmd_8814(): return H2C cmd because fw is not ready\n"); */
78
return ret;
79
}
80
81
_enter_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);
82
83
84
if (!pCmdBuffer)
85
goto exit;
86
87
if (CmdLen > RTL8814_MAX_CMD_LEN) {
88
RTW_WARN("%s, CmdLen: %d > %d, return!\n", __func__, CmdLen, RTL8814_MAX_CMD_LEN);
89
goto exit;
90
}
91
92
if (rtw_is_surprise_removed(padapter))
93
goto exit;
94
95
/* pay attention to if race condition happened in H2C cmd setting. */
96
do {
97
h2c_box_num = pHalData->LastHMEBoxNum;
98
99
if (!_is_fw_read_cmd_down(padapter, h2c_box_num)) {
100
RTW_INFO(" fw read cmd failed...\n");
101
goto exit;
102
}
103
104
*(u8 *)(&h2c_cmd) = ElementID;
105
106
if (CmdLen <= 3) {
107
_rtw_memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, CmdLen);
108
h2c_cmd_ex = 0;
109
} else {
110
_rtw_memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, 3);
111
_rtw_memcpy((u8 *)(&h2c_cmd_ex), pCmdBuffer + 3, CmdLen - 3);
112
}
113
114
/* Write Ext command */
115
msgbox_ex_addr = REG_HMEBOX_EXT0_8814A + (h2c_box_num * RTL8814_EX_MESSAGE_BOX_SIZE);
116
#ifdef CONFIG_H2C_EF
117
for (cmd_idx = 0; cmd_idx < RTL8814_MESSAGE_BOX_SIZE; cmd_idx++)
118
rtw_write8(padapter, msgbox_ex_addr + cmd_idx, *((u8 *)(&h2c_cmd_ex) + cmd_idx));
119
#else
120
h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex);
121
rtw_write32(padapter, msgbox_ex_addr, h2c_cmd_ex);
122
#endif
123
124
/* Write command */
125
msgbox_addr = REG_HMEBOX_0 + (h2c_box_num * RTL8814_MESSAGE_BOX_SIZE);
126
#ifdef CONFIG_H2C_EF
127
for (cmd_idx = 0; cmd_idx < RTL8814_MESSAGE_BOX_SIZE; cmd_idx++)
128
rtw_write8(padapter, msgbox_addr + cmd_idx, *((u8 *)(&h2c_cmd) + cmd_idx));
129
#else
130
h2c_cmd = le32_to_cpu(h2c_cmd);
131
rtw_write32(padapter, msgbox_addr, h2c_cmd);
132
#endif
133
134
/* RTW_INFO("MSG_BOX:%d,CmdLen(%d), reg:0x%x =>h2c_cmd:0x%x, reg:0x%x =>h2c_cmd_ex:0x%x ..\n" */
135
/* ,pHalData->LastHMEBoxNum ,CmdLen,msgbox_addr,h2c_cmd,msgbox_ex_addr,h2c_cmd_ex); */
136
137
pHalData->LastHMEBoxNum = (h2c_box_num + 1) % RTL8814_MAX_H2C_BOX_NUMS;
138
139
} while (0);
140
141
ret = _SUCCESS;
142
143
exit:
144
145
_exit_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);
146
147
148
return ret;
149
}
150
#ifdef CONFIG_FW_CORRECT_BCN
151
void rtl8814_fw_update_beacon_cmd(_adapter *padapter)
152
{
153
u8 param[2] = {0};
154
u16 txpktbuf_bndy;
155
156
157
158
SET_8814A_H2CCMD_BCNHWSEQ_EN(param, 1);
159
SET_8814A_H2CCMD_BCNHWSEQ_BCN_NUMBER(param, 0);
160
SET_8814A_H2CCMD_BCNHWSEQ_HWSEQ(param, 1);
161
SET_8814A_H2CCMD_BCNHWSEQ_EXHWSEQ(param, 0);
162
SET_8814A_H2CCMD_BCNHWSEQ_PAGE(param, 0);
163
if (GET_HAL_DATA(padapter)->firmware_version < 23)
164
/* FW v21, v22 use H2C_BCNHWSEQ = 0xC2 */
165
FillH2CCmd_8814(padapter, 0xC2, 2, param);
166
else
167
FillH2CCmd_8814(padapter, H2C_BCNHWSEQ, 2, param);
168
169
/*RTW_INFO("%s, %d, correct beacon HW sequence, FirmwareVersion=%d, H2C_BCNHWSEQ=%d\n", __func__, __LINE__, GET_HAL_DATA(padapter)->firmware_version, H2C_BCNHWSEQ);*/
170
171
}
172
#endif
173
u8 Get_VHT_ENI(
174
u32 IOTAction,
175
u32 WirelessMode,
176
u32 ratr_bitmap
177
)
178
{
179
u8 Ret = 0;
180
181
if (WirelessMode == WIRELESS_11_24AC) {
182
if (ratr_bitmap & 0xfff00000) /* Mix , 2SS */
183
Ret = 3;
184
else /* Mix, 1SS */
185
Ret = 2;
186
} else if (WirelessMode == WIRELESS_11_5AC) {
187
Ret = 1; /* VHT */
188
}
189
190
return Ret << 4;
191
}
192
193
BOOLEAN
194
Get_RA_ShortGI_8814(
195
PADAPTER Adapter,
196
struct sta_info *psta,
197
u8 shortGIrate,
198
u32 ratr_bitmap
199
)
200
{
201
BOOLEAN bShortGI;
202
struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
203
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
204
205
bShortGI = shortGIrate;
206
207
#ifdef CONFIG_80211AC_VHT
208
if (bShortGI &&
209
is_supported_vht(psta->wireless_mode) &&
210
(pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK_JAGUAR_CCUTAP) &&
211
TEST_FLAG(psta->vhtpriv.ldpc_cap, LDPC_VHT_ENABLE_TX)
212
) {
213
if (ratr_bitmap & 0xC0000000)
214
bShortGI = _FALSE;
215
}
216
#endif /* CONFIG_80211AC_VHT */
217
218
return bShortGI;
219
}
220
221
222
void
223
Set_RA_LDPC_8814(
224
struct sta_info *psta,
225
BOOLEAN bLDPC
226
)
227
{
228
if (psta == NULL)
229
return;
230
#ifdef CONFIG_80211AC_VHT
231
if (psta->wireless_mode == WIRELESS_11_5AC) {
232
if (bLDPC && TEST_FLAG(psta->vhtpriv.ldpc_cap, LDPC_VHT_CAP_TX))
233
SET_FLAG(psta->vhtpriv.ldpc_cap, LDPC_VHT_ENABLE_TX);
234
else
235
CLEAR_FLAG(psta->vhtpriv.ldpc_cap, LDPC_VHT_ENABLE_TX);
236
} else if (is_supported_ht(psta->wireless_mode) || is_supported_vht(psta->wireless_mode)) {
237
if (bLDPC && TEST_FLAG(psta->htpriv.ldpc_cap, LDPC_HT_CAP_TX))
238
SET_FLAG(psta->htpriv.ldpc_cap, LDPC_HT_ENABLE_TX);
239
else
240
CLEAR_FLAG(psta->htpriv.ldpc_cap, LDPC_HT_ENABLE_TX);
241
}
242
243
update_ldpc_stbc_cap(psta);
244
#endif /* CONFIG_80211AC_VHT */
245
246
/* RTW_INFO("MacId %d bLDPC %d\n", psta->cmn.mac_id, bLDPC); */
247
}
248
249
void rtl8814_req_txrpt_cmd(PADAPTER padapter, u8 macid)
250
{
251
u8 u1H2CApReqRptParm[H2C_AP_REQ_TXRPT_LEN] = {0};
252
253
SET_8814A_H2CCMD_TXREP_PARM_STA1(u1H2CApReqRptParm, macid);
254
SET_8814A_H2CCMD_TXREP_PARM_STA2(u1H2CApReqRptParm, 0xff);
255
SET_8814A_H2CCMD_TXREP_PARM_RTY(u1H2CApReqRptParm, 0x00);
256
FillH2CCmd_8814(padapter, H2C_AP_REQ_TXRPT, H2C_AP_REQ_TXRPT_LEN, u1H2CApReqRptParm);
257
SET_8814A_H2CCMD_TXREP_PARM_RTY(u1H2CApReqRptParm, 0x02);
258
FillH2CCmd_8814(padapter, H2C_AP_REQ_TXRPT, H2C_AP_REQ_TXRPT_LEN, u1H2CApReqRptParm);
259
}
260
261
void rtl8814_set_FwPwrMode_cmd(PADAPTER padapter, u8 PSMode)
262
{
263
u8 u1H2CSetPwrMode[H2C_PWRMODE_LEN] = {0};
264
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
265
u8 Mode = 0, RLBM = 0, PowerState = 0, LPSAwakeIntvl = 2;
266
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
267
u8 allQueueUAPSD = 0;
268
269
RTW_INFO("%s: Mode=%d SmartPS=%d\n", __FUNCTION__, PSMode, pwrpriv->smart_ps);
270
271
switch (PSMode) {
272
case PS_MODE_ACTIVE:
273
Mode = 0;
274
break;
275
case PS_MODE_MIN:
276
Mode = 1;
277
break;
278
case PS_MODE_MAX:
279
RLBM = 1;
280
Mode = 1;
281
break;
282
case PS_MODE_DTIM:
283
RLBM = 2;
284
Mode = 1;
285
break;
286
case PS_MODE_UAPSD_WMM:
287
Mode = 2;
288
break;
289
default:
290
Mode = 0;
291
break;
292
}
293
294
if (Mode > PS_MODE_ACTIVE) {
295
#ifdef CONFIG_BT_COEXIST
296
if ((rtw_btcoex_IsBtControlLps(padapter) == _TRUE) && (_TRUE == pHalData->EEPROMBluetoothCoexist))
297
PowerState = rtw_btcoex_RpwmVal(padapter);
298
else
299
#endif /* CONFIG_BT_COEXIST */
300
PowerState = 0x00;/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */
301
302
#ifdef CONFIG_EXT_CLK
303
Mode |= BIT(7);/* supporting 26M XTAL CLK_Request feature. */
304
#endif /* CONFIG_EXT_CLK */
305
} else
306
PowerState = 0x0C;/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */
307
308
/* 0: Active, 1: LPS, 2: WMMPS */
309
SET_8814A_H2CCMD_PWRMODE_PARM_MODE(u1H2CSetPwrMode, Mode);
310
311
/* 0:Min, 1:Max , 2:User define */
312
SET_8814A_H2CCMD_PWRMODE_PARM_RLBM(u1H2CSetPwrMode, RLBM);
313
314
/* (LPS) smart_ps: 0: PS_Poll, 1: PS_Poll , 2: NullData */
315
/* (WMM)smart_ps: 0:PS_Poll, 1:NullData */
316
SET_8814A_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CSetPwrMode, pwrpriv->smart_ps);
317
318
/* AwakeInterval: Unit is beacon interval, this field is only valid in PS_DTIM mode */
319
SET_8814A_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1H2CSetPwrMode, LPSAwakeIntvl);
320
321
/* (WMM only)bAllQueueUAPSD */
322
SET_8814A_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1H2CSetPwrMode, allQueueUAPSD);
323
324
/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */
325
SET_8814A_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CSetPwrMode, PowerState);
326
327
#ifdef CONFIG_BT_COEXIST
328
if (_TRUE == pHalData->EEPROMBluetoothCoexist)
329
rtw_btcoex_RecordPwrMode(padapter, u1H2CSetPwrMode, sizeof(u1H2CSetPwrMode));
330
#endif /* CONFIG_BT_COEXIST */
331
/* RTW_INFO("u1H2CSetPwrMode="MAC_FMT"\n", MAC_ARG(u1H2CSetPwrMode)); */
332
FillH2CCmd_8814(padapter, H2C_SET_PWR_MODE, sizeof(u1H2CSetPwrMode), u1H2CSetPwrMode);
333
334
}
335
336
#ifdef CONFIG_TDLS
337
#ifdef CONFIG_TDLS_CH_SW
338
void rtl8814_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable)
339
{
340
u8 u1H2CSetPwrMode[H2C_PWRMODE_LEN] = {0};
341
342
SET_8814A_H2CCMD_PWRMODE_PARM_MODE(u1H2CSetPwrMode, 1);
343
SET_8814A_H2CCMD_PWRMODE_PARM_RLBM(u1H2CSetPwrMode, 1);
344
SET_8814A_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CSetPwrMode, 0);
345
SET_8814A_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1H2CSetPwrMode, 0);
346
SET_8814A_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1H2CSetPwrMode, 0);
347
SET_8814A_H2CCMD_PWRMODE_PARM_BCN_EARLY_C2H_RPT(u1H2CSetPwrMode, enable);
348
SET_8814A_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CSetPwrMode, 0x0C);
349
FillH2CCmd_8814(padapter, H2C_SET_PWR_MODE, sizeof(u1H2CSetPwrMode), u1H2CSetPwrMode);
350
}
351
#endif
352
#endif
353
354
void rtl8814a_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param)
355
{
356
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
357
u8 parm[H2C_INACTIVE_PS_LEN] = {0};
358
359
/* u8 cmd_param; */ /* BIT0:enable, BIT1:NoConnect32k */
360
if (cmd_param) {
361
362
#ifdef CONFIG_BT_COEXIST
363
rtw_btcoex_IpsNotify(padapter, pwrpriv->ips_mode_req);
364
#endif
365
/* Enter IPS */
366
RTW_INFO("%s: issue H2C to FW when entering IPS\n", __func__);
367
368
parm[0] = 0x1;/* suggest by Isaac.Hsu*/
369
370
rtw_hal_fill_h2c_cmd(padapter, /* H2C_FWLPS_IN_IPS_, */
371
H2C_INACTIVE_PS_,
372
H2C_INACTIVE_PS_LEN, parm);
373
} else {
374
/* Leave IPS */
375
RTW_INFO("%s: Leaving IPS in FWLPS state\n", __func__);
376
377
parm[0] = 0x0;
378
parm[1] = 0x0;
379
parm[2] = 0x0;
380
rtw_hal_fill_h2c_cmd(padapter, H2C_INACTIVE_PS_,
381
H2C_INACTIVE_PS_LEN, parm);
382
#ifdef CONFIG_BT_COEXIST
383
rtw_btcoex_IpsNotify(padapter, IPS_NONE);
384
#endif
385
}
386
}
387
388
/*
389
* Description: Get the reserved page number in Tx packet buffer.
390
* Retrun value: the page number.
391
* 2012.08.09, by tynli.
392
* */
393
u8
394
GetTxBufferRsvdPageNum8814(_adapter *Adapter, bool bWoWLANBoundary)
395
{
396
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
397
u8 RsvdPageNum = 0;
398
u16 TxPageBndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8814A; /* default reseved 1 page for the IC type which is undefined. */
399
400
if (bWoWLANBoundary)
401
rtw_hal_get_def_var(Adapter, HAL_DEF_TX_PAGE_BOUNDARY_WOWLAN, (u8 *)&TxPageBndy);
402
else
403
rtw_hal_get_def_var(Adapter, HAL_DEF_TX_PAGE_BOUNDARY, (u8 *)&TxPageBndy);
404
405
RsvdPageNum = LAST_ENTRY_OF_TX_PKT_BUFFER_8814A - TxPageBndy + 1;
406
407
return RsvdPageNum;
408
}
409
410
void rtl8814_download_rsvd_page(PADAPTER padapter, u8 mstatus)
411
{
412
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
413
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
414
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
415
BOOLEAN bSendBeacon = _FALSE;
416
BOOLEAN bcn_valid = _FALSE;
417
u8 DLBcnCount = 0;
418
u32 poll = 0;
419
u8 RegFwHwTxQCtrl;
420
421
RTW_INFO("%s mstatus(%x)\n", __FUNCTION__, mstatus);
422
423
if (mstatus == 1) {
424
u8 bcn_ctrl = rtw_read8(padapter, REG_BCN_CTRL);
425
426
/* We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C. */
427
/* Suggested by filen. Added by tynli. */
428
rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000 | pmlmeinfo->aid));
429
/* Hw sequende enable by dedault. 2010.06.23. by tynli. */
430
/* rtw_write16(padapter, REG_NQOS_SEQ, ((pmlmeext->mgnt_seq+100)&0xFFF)); */
431
/* rtw_write8(padapter, REG_HWSEQ_CTRL, 0xFF); */
432
433
/* Set REG_CR bit 8. DMA beacon by SW. */
434
rtw_write8(padapter, REG_CR + 1,
435
rtw_read8(padapter, REG_CR + 1) | BIT0);
436
437
/*RTW_INFO("%s-%d: enable SW BCN, REG_CR=0x%x\n", __func__, __LINE__, rtw_read32(padapter, REG_CR));*/
438
439
/* Disable Hw protection for a time which revserd for Hw sending beacon. */
440
/* Fix download reserved page packet fail that access collision with the protection time. */
441
/* 2010.05.11. Added by tynli. */
442
rtw_write8(padapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
443
444
RegFwHwTxQCtrl = rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2);
445
if (RegFwHwTxQCtrl & BIT6) {
446
RTW_INFO("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n");
447
bSendBeacon = _TRUE;
448
}
449
450
/* Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame. */
451
RegFwHwTxQCtrl &= (~BIT6);
452
rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, RegFwHwTxQCtrl);
453
454
/* Clear beacon valid check bit. */
455
rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
456
DLBcnCount = 0;
457
poll = 0;
458
do {
459
/* download rsvd page. */
460
rtw_hal_set_fw_rsvd_page(padapter, _FALSE);
461
DLBcnCount++;
462
do {
463
rtw_yield_os();
464
/* rtw_mdelay_os(10); */
465
/* check rsvd page download OK. */
466
rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bcn_valid));
467
poll++;
468
} while (!bcn_valid && (poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
469
470
} while (!bcn_valid && DLBcnCount <= 100 && !RTW_CANNOT_RUN(padapter));
471
472
/* RT_ASSERT(bcn_valid, ("HalDownloadRSVDPage88ES(): 1 Download RSVD page failed!\n")); */
473
if (RTW_CANNOT_RUN(padapter))
474
;
475
else if (!bcn_valid)
476
RTW_ERR(ADPT_FMT": 1 DL RSVD page failed! DLBcnCount:%u, poll:%u\n",
477
ADPT_ARG(padapter) , DLBcnCount, poll);
478
else {
479
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
480
481
pwrctl->fw_psmode_iface_id = padapter->iface_id;
482
rtw_hal_set_fw_rsvd_page(padapter, _TRUE);
483
RTW_INFO(ADPT_FMT": 1 DL RSVD page success! DLBcnCount:%u, poll:%u\n",
484
ADPT_ARG(padapter), DLBcnCount, poll);
485
}
486
487
/* restore bcn_ctrl */
488
rtw_write8(padapter, REG_BCN_CTRL, bcn_ctrl);
489
490
/* To make sure that if there exists an adapter which would like to send beacon. */
491
/* If exists, the origianl value of 0x422[6] will be 1, we should check this to */
492
/* prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */
493
/* the beacon cannot be sent by HW. */
494
/* 2010.06.23. Added by tynli. */
495
if (bSendBeacon) {
496
RegFwHwTxQCtrl |= BIT6;
497
rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, RegFwHwTxQCtrl);
498
}
499
500
/* */
501
/* Update RSVD page location H2C to Fw. */
502
/* */
503
if (bcn_valid) {
504
rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
505
RTW_INFO("Set RSVD page location to Fw.\n");
506
/* FillH2CCmd88E(Adapter, H2C_88E_RSVDPAGE, H2C_RSVDPAGE_LOC_LENGTH, pMgntInfo->u1RsvdPageLoc); */
507
}
508
509
/* Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli. */
510
/* if(!padapter->bEnterPnpSleep) */
511
#ifndef CONFIG_PCI_HCI
512
{
513
#ifndef RTL8814AE_SW_BCN
514
/* Clear CR[8] or beacon packet will not be send to TxBuf anymore. */
515
rtw_write8(padapter, REG_CR + 1,
516
rtw_read8(padapter, REG_CR + 1) & (~BIT0));
517
518
/*RTW_INFO("%s-%d: disable SW BCN, REG_CR=0x%x\n", __func__, __LINE__, rtw_read32(padapter, REG_CR));*/
519
#endif
520
}
521
#endif /* !CONFIG_PCI_HCI */
522
}
523
}
524
525
void rtl8814_set_FwJoinBssReport_cmd(PADAPTER padapter, u8 mstatus)
526
{
527
if (mstatus == 1)
528
rtl8814_download_rsvd_page(padapter, RT_MEDIA_CONNECT);
529
}
530
531
#ifdef CONFIG_P2P_PS
532
void rtl8814_set_p2p_ps_offload_cmd(_adapter *padapter, u8 p2p_ps_state)
533
{
534
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
535
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
536
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
537
u8 *p2p_ps_offload = (u8 *)&pHalData->p2p_ps_offload;
538
u8 i;
539
540
541
#if 1
542
switch (p2p_ps_state) {
543
case P2P_PS_DISABLE:
544
RTW_INFO("P2P_PS_DISABLE\n");
545
_rtw_memset(p2p_ps_offload, 0, 1);
546
break;
547
case P2P_PS_ENABLE:
548
RTW_INFO("P2P_PS_ENABLE\n");
549
/* update CTWindow value. */
550
if (pwdinfo->ctwindow > 0) {
551
SET_8814A_H2CCMD_P2P_PS_OFFLOAD_CTWINDOW_EN(p2p_ps_offload, 1);
552
rtw_write8(padapter, REG_P2P_CTWIN, pwdinfo->ctwindow);
553
}
554
555
/* hw only support 2 set of NoA */
556
for (i = 0 ; i < pwdinfo->noa_num ; i++) {
557
/* To control the register setting for which NOA */
558
rtw_write8(padapter, REG_NOA_DESC_SEL, (i << 4));
559
if (i == 0)
560
SET_8814A_H2CCMD_P2P_PS_OFFLOAD_NOA0_EN(p2p_ps_offload, 1);
561
else
562
SET_8814A_H2CCMD_P2P_PS_OFFLOAD_NOA1_EN(p2p_ps_offload, 1);
563
564
/* config P2P NoA Descriptor Register */
565
/* RTW_INFO("%s(): noa_duration = %x\n",__FUNCTION__,pwdinfo->noa_duration[i]); */
566
rtw_write32(padapter, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]);
567
568
/* RTW_INFO("%s(): noa_interval = %x\n",__FUNCTION__,pwdinfo->noa_interval[i]); */
569
rtw_write32(padapter, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]);
570
571
/* RTW_INFO("%s(): start_time = %x\n",__FUNCTION__,pwdinfo->noa_start_time[i]); */
572
rtw_write32(padapter, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]);
573
574
/* RTW_INFO("%s(): noa_count = %x\n",__FUNCTION__,pwdinfo->noa_count[i]); */
575
rtw_write8(padapter, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]);
576
}
577
578
if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
579
/* rst p2p circuit: reg 0x5F0 */
580
rtw_write8(padapter, REG_P2P_RST_8814A, BIT(0)); /* rst p2p 0 circuit NOA 0 */
581
582
SET_8814A_H2CCMD_P2P_PS_OFFLOAD_ENABLE(p2p_ps_offload, 1);
583
584
if (pwdinfo->role == P2P_ROLE_GO) {
585
/* 1: Owner, 0: Client */
586
SET_8814A_H2CCMD_P2P_PS_OFFLOAD_ROLE(p2p_ps_offload, 1);
587
SET_8814A_H2CCMD_P2P_PS_OFFLOAD_ALLSTASLEEP(p2p_ps_offload, 0);
588
} else {
589
/* 1: Owner, 0: Client */
590
SET_8814A_H2CCMD_P2P_PS_OFFLOAD_ROLE(p2p_ps_offload, 0);
591
}
592
593
SET_8814A_H2CCMD_P2P_PS_OFFLOAD_DISCOVERY(p2p_ps_offload, 0);
594
}
595
break;
596
case P2P_PS_SCAN:
597
RTW_INFO("P2P_PS_SCAN\n");
598
SET_8814A_H2CCMD_P2P_PS_OFFLOAD_DISCOVERY(p2p_ps_offload, 1);
599
break;
600
case P2P_PS_SCAN_DONE:
601
RTW_INFO("P2P_PS_SCAN_DONE\n");
602
SET_8814A_H2CCMD_P2P_PS_OFFLOAD_DISCOVERY(p2p_ps_offload, 0);
603
pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
604
break;
605
default:
606
break;
607
}
608
609
RTW_INFO("P2P_PS_OFFLOAD : %x\n", p2p_ps_offload[0]);
610
FillH2CCmd_8814(padapter, H2C_P2P_PS_OFFLOAD, 1, p2p_ps_offload);
611
#endif
612
613
614
}
615
#endif /* CONFIG_P2P */
616
617
618
619
static void
620
C2HTxBeamformingHandler_8814(
621
PADAPTER Adapter,
622
u8 *CmdBuf,
623
u8 CmdLen
624
)
625
{
626
#ifdef CONFIG_BEAMFORMING /*PHYDM_BF - (BEAMFORMING_SUPPORT == 1)*/
627
u8 status = CmdBuf[0] & BIT0;
628
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
629
struct dm_struct *pDM_Odm = &pHalData->odmpriv;
630
/*beamforming_check_sounding_success(Adapter, status);*/
631
phydm_beamforming_end_sw(pDM_Odm, status);
632
#endif /*CONFIG_BEAMFORMING*/
633
}
634
635
static void
636
C2HTxFeedbackHandler_8814(
637
PADAPTER Adapter,
638
u8 *CmdBuf,
639
u8 CmdLen
640
)
641
{
642
#ifdef CONFIG_XMIT_ACK
643
if (GET_8814A_C2H_TX_RPT_RETRY_OVER(CmdBuf) | GET_8814A_C2H_TX_RPT_LIFE_TIME_OVER(CmdBuf))
644
rtw_ack_tx_done(&Adapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
645
else
646
rtw_ack_tx_done(&Adapter->xmitpriv, RTW_SCTX_DONE_SUCCESS);
647
#endif
648
}
649
650
static void
651
C2HTxRPTHandler_8814(
652
PADAPTER Adapter,
653
u8 *CmdBuf,
654
u8 CmdLen
655
)
656
{
657
_irqL irqL;
658
u8 macid = 0, IniRate = 0;
659
u16 TxOK = 0, TxFail = 0;
660
struct sta_priv *pstapriv = &(GET_PRIMARY_ADAPTER(Adapter))->stapriv, *pstapriv_original = NULL;
661
struct sta_info *psta = NULL;
662
struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(Adapter);
663
_list *plist, *phead;
664
PADAPTER adapter_ognl = NULL;
665
666
if(!pstapriv->gotc2h) {
667
RTW_WARN("%s,%d: No gotc2h!\n", __FUNCTION__, __LINE__);
668
return;
669
}
670
671
adapter_ognl = rtw_get_iface_by_id(GET_PRIMARY_ADAPTER(Adapter), pstapriv->c2h_adapter_id);
672
if(!adapter_ognl) {
673
RTW_WARN("%s: No adapter!\n", __FUNCTION__);
674
return;
675
}
676
677
psta = rtw_get_stainfo(&adapter_ognl->stapriv, pstapriv->c2h_sta_mac);
678
if (!psta) {
679
RTW_WARN("%s: No corresponding sta_info!\n", __FUNCTION__);
680
return;
681
}
682
683
macid = GET_8814A_C2H_TC2H_APREQ_TXRPT_MACID1(CmdBuf);
684
TxOK = GET_8814A_C2H_TC2H_APREQ_TXRPT_TXOK1(CmdBuf);
685
TxFail = GET_8814A_C2H_TC2H_APREQ_TXRPT_TXFAIL1(CmdBuf);
686
IniRate = GET_8814A_C2H_TC2H_APREQ_TXRPT_INIRATE1(CmdBuf);
687
psta->sta_stats.tx_ok_cnt = TxOK;
688
psta->sta_stats.tx_fail_cnt = TxFail;
689
690
}
691
692
static void
693
C2HSPC_STAT_8814(
694
PADAPTER Adapter,
695
u8 *CmdBuf,
696
u8 CmdLen
697
)
698
{
699
_irqL irqL;
700
struct sta_priv *pstapriv = &(GET_PRIMARY_ADAPTER(Adapter))->stapriv;
701
struct sta_info *psta = NULL;
702
_list *plist, *phead;
703
PADAPTER adapter_ognl = NULL;
704
705
if(!pstapriv->gotc2h) {
706
RTW_WARN("%s, %d: No gotc2h!\n", __FUNCTION__, __LINE__);
707
return;
708
}
709
710
adapter_ognl = rtw_get_iface_by_id(GET_PRIMARY_ADAPTER(Adapter), pstapriv->c2h_adapter_id);
711
if(!adapter_ognl) {
712
RTW_WARN("%s: No adapter!\n", __FUNCTION__);
713
return;
714
}
715
716
psta = rtw_get_stainfo(&adapter_ognl->stapriv, pstapriv->c2h_sta_mac);
717
if (!psta) {
718
RTW_WARN("%s: No corresponding sta_info!\n", __FUNCTION__);
719
return;
720
}
721
psta->sta_stats.tx_retry_cnt = GET_8814A_C2H_SPC_STAT_TYPEB_RETRY1(CmdBuf);
722
rtw_sctx_done(&pstapriv->gotc2h);
723
}
724
725
s32 c2h_handler_8814a(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 *payload)
726
{
727
s32 ret = _SUCCESS;
728
729
switch (id) {
730
case C2H_TXBF:
731
RTW_INFO("[C2H], C2H_TXBF!!\n");
732
C2HTxBeamformingHandler_8814(adapter, payload, plen);
733
break;
734
case C2H_CCX_TX_RPT:
735
C2HTxFeedbackHandler_8814(adapter, payload, plen);
736
break;
737
case C2H_AP_REQ_TXRPT:
738
C2HTxRPTHandler_8814(adapter, payload, plen);
739
break;
740
case C2H_SPC_STAT:
741
C2HSPC_STAT_8814(adapter, payload, plen);
742
break;
743
default:
744
ret = _FAIL;
745
break;
746
}
747
748
return ret;
749
}
750
751
#ifdef CONFIG_BT_COEXIST
752
#if 0
753
static void rtl8814_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
754
{
755
u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
756
757
RTW_INFO("8812au/8821/8811 RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
758
rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
759
rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
760
rsvdpageloc->LocBTQosNull);
761
762
SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
763
SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
764
SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
765
SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
766
SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
767
768
RTW_DBG_DUMP("u1H2CRsvdPageParm:", u1H2CRsvdPageParm, H2C_RSVDPAGE_LOC_LEN);
769
FillH2CCmd_8814(padapter, H2C_RSVD_PAGE, H2C_RSVDPAGE_LOC_LEN, u1H2CRsvdPageParm);
770
}
771
772
#ifdef CONFIG_WOWLAN
773
static void rtl8814_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
774
{
775
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
776
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
777
u8 res = 0, count = 0;
778
#ifdef CONFIG_WOWLAN
779
u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
780
781
RTW_INFO("rtl8814_set_FwAoacRsvdPage_cmd: RWC=%d ArpRsp=%d NbrAdv=%d GtkRsp=%d GtkInfo=%d ProbeReq=%d NetworkList=%d\n",
782
rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp,
783
rsvdpageloc->LocNbrAdv, rsvdpageloc->LocGTKRsp,
784
rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq,
785
rsvdpageloc->LocNetList);
786
787
#ifdef CONFIG_PNO_SUPPORT
788
RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
789
#endif
790
if (check_fwstate(pmlmepriv, _FW_LINKED)) {
791
SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
792
SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
793
/* SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, rsvdpageloc->LocNbrAdv); */
794
SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
795
SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
796
#ifdef CONFIG_GTK_OL
797
SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
798
#endif /* CONFIG_GTK_OL */
799
} else {
800
#ifdef CONFIG_PNO_SUPPORT
801
if (!pwrpriv->wowlan_in_resume)
802
SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocPNOInfo);
803
#endif
804
}
805
806
RTW_DBG_DUMP("u1H2CAoacRsvdPageParm:", u1H2CAoacRsvdPageParm, H2C_AOAC_RSVDPAGE_LOC_LEN);
807
FillH2CCmd_8814(padapter, H2C_AOAC_RSVD_PAGE, H2C_AOAC_RSVDPAGE_LOC_LEN, u1H2CAoacRsvdPageParm);
808
809
#ifdef CONFIG_PNO_SUPPORT
810
if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter) &&
811
!check_fwstate(pmlmepriv, _FW_LINKED) &&
812
pwrpriv->wowlan_in_resume == _FALSE) {
813
814
res = rtw_read8(padapter, 0x1b8);
815
while (res == 0 && count < 25) {
816
RTW_INFO("[%d] FW loc_NLOInfo: %d\n", count, res);
817
res = rtw_read8(padapter, 0x1b8);
818
count++;
819
rtw_msleep_os(2);
820
}
821
}
822
#endif /* CONFIG_PNO_SUPPORT */
823
#endif /* CONFIG_WOWLAN */
824
}
825
#endif
826
827
static void SetFwRsvdPagePkt_BTCoex(PADAPTER padapter)
828
{
829
PHAL_DATA_TYPE pHalData;
830
struct xmit_frame *pcmdframe;
831
struct pkt_attrib *pattrib;
832
struct xmit_priv *pxmitpriv;
833
struct pwrctrl_priv *pwrctl;
834
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
835
u32 BeaconLength = 0;
836
u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
837
u32 ProbeReqLength = 0;
838
u8 *ReservedPagePacket;
839
u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
840
u8 TotalPageNum = 0, CurtPktPageNum = 0, RsvdPageNum = 0;
841
u16 BufIndex, PageSize = PAGE_SIZE_TX_8814;
842
u32 TotalPacketLen, MaxRsvdPageBufSize = 0;
843
RSVDPAGE_LOC RsvdPageLoc;
844
845
pHalData = GET_HAL_DATA(padapter);
846
847
pxmitpriv = &padapter->xmitpriv;
848
pwrctl = adapter_to_pwrctl(padapter);
849
850
/* RsvdPageNum = BCNQ_PAGE_NUM_8723B + WOWLAN_PAGE_NUM_8723B; */
851
852
RsvdPageNum = BCNQ_PAGE_NUM_8814;
853
MaxRsvdPageBufSize = RsvdPageNum * PageSize;
854
855
pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
856
if (pcmdframe == NULL) {
857
RTW_INFO("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
858
return;
859
}
860
861
ReservedPagePacket = pcmdframe->buf_addr;
862
_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
863
864
/* 3 (1) beacon */
865
BufIndex = TxDescOffset;
866
rtw_hal_construct_beacon(padapter,
867
&ReservedPagePacket[BufIndex], &BeaconLength);
868
869
/* When we count the first page size, we need to reserve description size for the RSVD */
870
/* packet, it will be filled in front of the packet in TXPKTBUF. */
871
CurtPktPageNum = (u8)PageNum(TxDescLen + BeaconLength, PageSize);
872
873
/* If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware */
874
if (CurtPktPageNum == 1)
875
CurtPktPageNum += 1;
876
TotalPageNum += CurtPktPageNum;
877
878
BufIndex += (CurtPktPageNum * PageSize);
879
880
/* Jump to lastest page */
881
if (BufIndex < (MaxRsvdPageBufSize - PageSize)) {
882
BufIndex = TxDescOffset + (MaxRsvdPageBufSize - PageSize);
883
TotalPageNum = BCNQ_PAGE_NUM_8814 - 1;
884
885
}
886
887
/* 3 (6) BT Qos null data */
888
RsvdPageLoc.LocBTQosNull = TotalPageNum;
889
rtw_hal_construct_NullFunctionData(
890
padapter,
891
&ReservedPagePacket[BufIndex],
892
&BTQosNullLength,
893
_TRUE, 0, 0, _FALSE);
894
rtl8814a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex - TxDescLen], BTQosNullLength, _FALSE, _TRUE, _FALSE);
895
896
/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: BT QOS NULL DATA %p %d\n", */
897
/* __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (BTQosNullLength+TxDescLen)); */
898
899
CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength, PageSize);
900
901
TotalPageNum += CurtPktPageNum;
902
903
TotalPacketLen = BufIndex + BTQosNullLength;
904
if (TotalPacketLen > MaxRsvdPageBufSize) {
905
RTW_INFO("%s(): ERROR: The rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n", __FUNCTION__,
906
TotalPacketLen, MaxRsvdPageBufSize);
907
goto error;
908
} else {
909
/* update attribute */
910
pattrib = &pcmdframe->attrib;
911
update_mgntframe_attrib(padapter, pattrib);
912
pattrib->qsel = QSLT_BEACON;
913
pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
914
#ifdef CONFIG_PCI_HCI
915
dump_mgntframe(padapter, pcmdframe);
916
#else
917
dump_mgntframe_and_wait(padapter, pcmdframe, 100);
918
#endif
919
}
920
921
RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n", __FUNCTION__, TotalPacketLen, TotalPageNum);
922
if (check_fwstate(pmlmepriv, _FW_LINKED)) {
923
rtl8814_set_FwRsvdPage_cmd(padapter, &RsvdPageLoc);
924
#ifdef CONFIG_WOWLAN
925
rtl8814_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc);
926
#endif
927
}
928
929
return;
930
931
error:
932
933
rtw_free_xmitframe(pxmitpriv, pcmdframe);
934
}
935
#endif
936
937
void rtl8814a_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter)
938
{
939
rtl8814_download_rsvd_page(padapter, RT_MEDIA_CONNECT);
940
}
941
942
#endif /* CONFIG_BT_COEXIST */
943
944