Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nu11secur1ty
GitHub Repository: nu11secur1ty/Kali-Linux
Path: blob/master/ALFA-W1F1/RTL8814AU/hal/hal_com.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 _HAL_COM_C_
16
17
#include <drv_types.h>
18
#include "hal_com_h2c.h"
19
20
#include "hal_data.h"
21
22
#ifdef RTW_HALMAC
23
#include "../../hal/hal_halmac.h"
24
#endif
25
26
void rtw_dump_fw_info(void *sel, _adapter *adapter)
27
{
28
HAL_DATA_TYPE *hal_data = NULL;
29
30
if (!adapter)
31
return;
32
33
hal_data = GET_HAL_DATA(adapter);
34
if (hal_data->bFWReady)
35
RTW_PRINT_SEL(sel, "FW VER -%d.%d\n", hal_data->firmware_version, hal_data->firmware_sub_version);
36
else
37
RTW_PRINT_SEL(sel, "FW not ready\n");
38
}
39
40
bool rsvd_page_cache_update_all(struct rsvd_page_cache_t *cache, u8 loc
41
, u8 txdesc_len, u32 page_size, u8 *info, u32 info_len)
42
{
43
u8 page_num = (u8)PageNum(txdesc_len + info_len, page_size);
44
bool modified = 0;
45
bool loc_mod = 0, size_mod = 0, page_num_mod = 0;
46
47
if (cache->loc != loc) {
48
RTW_INFO("%s %s loc change (%u -> %u)\n"
49
, __func__, cache->name, cache->loc, loc);
50
loc_mod = 1;
51
}
52
if (cache->size != info_len) {
53
RTW_INFO("%s %s size change (%u -> %u)\n"
54
, __func__, cache->name, cache->size, info_len);
55
size_mod = 1;
56
}
57
if (cache->page_num != page_num) {
58
RTW_INFO("%s %s page_num change (%u -> %u)\n"
59
, __func__, cache->name, cache->page_num, page_num);
60
page_num_mod = 1;
61
}
62
63
if (info) {
64
if (cache->data) {
65
if (cache->size == info_len) {
66
if (_rtw_memcmp(cache->data, info, info_len) != _TRUE) {
67
RTW_INFO("%s %s data change\n", __func__, cache->name);
68
modified = 1;
69
}
70
} else
71
rsvd_page_cache_free_data(cache);
72
}
73
74
if (!cache->data) {
75
cache->data = rtw_malloc(info_len);
76
if (!cache->data) {
77
RTW_ERR("%s %s alloc data with size(%u) fail\n"
78
, __func__, cache->name, info_len);
79
rtw_warn_on(1);
80
} else {
81
RTW_INFO("%s %s alloc data with size(%u)\n"
82
, __func__, cache->name, info_len);
83
}
84
modified = 1;
85
}
86
87
if (cache->data && modified)
88
_rtw_memcpy(cache->data, info, info_len);
89
} else {
90
if (cache->data && size_mod)
91
rsvd_page_cache_free_data(cache);
92
}
93
94
cache->loc = loc;
95
cache->page_num = page_num;
96
cache->size = info_len;
97
98
return modified | loc_mod | size_mod | page_num_mod;
99
}
100
101
bool rsvd_page_cache_update_data(struct rsvd_page_cache_t *cache, u8 *info, u32 info_len)
102
{
103
bool modified = 0;
104
105
if (!info || !info_len) {
106
RTW_WARN("%s %s invalid input(info:%p, info_len:%u)\n"
107
, __func__, cache->name, info, info_len);
108
goto exit;
109
}
110
111
if (!cache->loc || !cache->page_num || !cache->size) {
112
RTW_ERR("%s %s layout not ready(loc:%u, page_num:%u, size:%u)\n"
113
, __func__, cache->name, cache->loc, cache->page_num, cache->size);
114
rtw_warn_on(1);
115
goto exit;
116
}
117
118
if (cache->size != info_len) {
119
RTW_ERR("%s %s size(%u) differ with info_len(%u)\n"
120
, __func__, cache->name, cache->size, info_len);
121
rtw_warn_on(1);
122
goto exit;
123
}
124
125
if (!cache->data) {
126
cache->data = rtw_zmalloc(cache->size);
127
if (!cache->data) {
128
RTW_ERR("%s %s alloc data with size(%u) fail\n"
129
, __func__, cache->name, cache->size);
130
rtw_warn_on(1);
131
goto exit;
132
} else {
133
RTW_INFO("%s %s alloc data with size(%u)\n"
134
, __func__, cache->name, info_len);
135
}
136
modified = 1;
137
}
138
139
if (_rtw_memcmp(cache->data, info, cache->size) == _FALSE) {
140
RTW_INFO("%s %s data change\n", __func__, cache->name);
141
_rtw_memcpy(cache->data, info, cache->size);
142
modified = 1;
143
}
144
145
exit:
146
return modified;
147
}
148
149
void rsvd_page_cache_free_data(struct rsvd_page_cache_t *cache)
150
{
151
if (cache->data) {
152
rtw_mfree(cache->data, cache->size);
153
cache->data = NULL;
154
}
155
}
156
157
void rsvd_page_cache_free(struct rsvd_page_cache_t *cache)
158
{
159
cache->loc = 0;
160
cache->page_num = 0;
161
rsvd_page_cache_free_data(cache);
162
cache->size = 0;
163
}
164
165
/* #define CONFIG_GTK_OL_DBG */
166
167
/*#define DBG_SEC_CAM_MOVE*/
168
#ifdef DBG_SEC_CAM_MOVE
169
void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
170
{
171
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
172
int cam_id, index = 0;
173
u8 *addr = NULL;
174
175
if (!MLME_IS_STA(adapter))
176
return;
177
178
addr = get_bssid(pmlmepriv);
179
180
if (addr == NULL) {
181
RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
182
return;
183
}
184
185
rtw_clean_dk_section(adapter);
186
187
do {
188
cam_id = rtw_camid_search(adapter, addr, index, 1);
189
190
if (cam_id == -1)
191
RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
192
else
193
rtw_sec_cam_swap(adapter, cam_id, index);
194
195
index++;
196
} while (index < 4);
197
198
}
199
200
void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
201
{
202
struct security_priv *psecuritypriv = &adapter->securitypriv;
203
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
204
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
205
_irqL irqL;
206
u8 get_key[16];
207
208
_rtw_memset(get_key, 0, sizeof(get_key));
209
210
if (key_id > 4) {
211
RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
212
rtw_warn_on(1);
213
return;
214
}
215
rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
216
217
/*update key into related sw variable*/
218
_enter_critical_bh(&cam_ctl->lock, &irqL);
219
if (_rtw_camid_is_gk(adapter, key_id)) {
220
RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
221
RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
222
}
223
_exit_critical_bh(&cam_ctl->lock, &irqL);
224
225
}
226
#endif
227
228
229
#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
230
char rtw_phy_para_file_path[PATH_LENGTH_MAX];
231
#endif
232
233
void dump_chip_info(HAL_VERSION ChipVersion)
234
{
235
int cnt = 0;
236
u8 buf[128] = {0};
237
238
if (IS_8188E(ChipVersion))
239
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
240
else if (IS_8188F(ChipVersion))
241
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
242
else if (IS_8188GTV(ChipVersion))
243
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188GTV_");
244
else if (IS_8812_SERIES(ChipVersion))
245
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
246
else if (IS_8192E(ChipVersion))
247
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
248
else if (IS_8821_SERIES(ChipVersion))
249
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
250
else if (IS_8723B_SERIES(ChipVersion))
251
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
252
else if (IS_8703B_SERIES(ChipVersion))
253
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
254
else if (IS_8723D_SERIES(ChipVersion))
255
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
256
else if (IS_8814A_SERIES(ChipVersion))
257
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
258
else if (IS_8822B_SERIES(ChipVersion))
259
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
260
else if (IS_8821C_SERIES(ChipVersion))
261
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
262
else if (IS_8710B_SERIES(ChipVersion))
263
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8710B_");
264
else if (IS_8192F_SERIES(ChipVersion))
265
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192F_");
266
else if (IS_8822C_SERIES(ChipVersion))
267
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822C_");
268
else
269
cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
270
271
cnt += sprintf((buf + cnt), "%s", IS_NORMAL_CHIP(ChipVersion) ? "" : "T_");
272
273
if (IS_CHIP_VENDOR_TSMC(ChipVersion))
274
cnt += sprintf((buf + cnt), "%s", "T");
275
else if (IS_CHIP_VENDOR_UMC(ChipVersion))
276
cnt += sprintf((buf + cnt), "%s", "U");
277
else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
278
cnt += sprintf((buf + cnt), "%s", "S");
279
280
if (IS_A_CUT(ChipVersion))
281
cnt += sprintf((buf + cnt), "1_");
282
else if (IS_B_CUT(ChipVersion))
283
cnt += sprintf((buf + cnt), "2_");
284
else if (IS_C_CUT(ChipVersion))
285
cnt += sprintf((buf + cnt), "3_");
286
else if (IS_D_CUT(ChipVersion))
287
cnt += sprintf((buf + cnt), "4_");
288
else if (IS_E_CUT(ChipVersion))
289
cnt += sprintf((buf + cnt), "5_");
290
else if (IS_F_CUT(ChipVersion))
291
cnt += sprintf((buf + cnt), "6_");
292
else if (IS_I_CUT(ChipVersion))
293
cnt += sprintf((buf + cnt), "9_");
294
else if (IS_J_CUT(ChipVersion))
295
cnt += sprintf((buf + cnt), "10_");
296
else if (IS_K_CUT(ChipVersion))
297
cnt += sprintf((buf + cnt), "11_");
298
else
299
cnt += sprintf((buf + cnt), "UNKNOWN_Cv(%d)_", ChipVersion.CUTVersion);
300
301
if (IS_1T1R(ChipVersion))
302
cnt += sprintf((buf + cnt), "1T1R_");
303
else if (IS_1T2R(ChipVersion))
304
cnt += sprintf((buf + cnt), "1T2R_");
305
else if (IS_2T2R(ChipVersion))
306
cnt += sprintf((buf + cnt), "2T2R_");
307
else if (IS_3T3R(ChipVersion))
308
cnt += sprintf((buf + cnt), "3T3R_");
309
else if (IS_3T4R(ChipVersion))
310
cnt += sprintf((buf + cnt), "3T4R_");
311
else if (IS_4T4R(ChipVersion))
312
cnt += sprintf((buf + cnt), "4T4R_");
313
else
314
cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
315
316
cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
317
318
RTW_INFO("%s", buf);
319
}
320
321
u8 rtw_hal_get_port(_adapter *adapter)
322
{
323
u8 hw_port = get_hw_port(adapter);
324
#ifdef CONFIG_CLIENT_PORT_CFG
325
u8 clt_port = get_clt_port(adapter);
326
327
if (clt_port)
328
hw_port = clt_port;
329
330
#ifdef DBG_HW_PORT
331
if (MLME_IS_STA(adapter) && (adapter->client_id != MAX_CLIENT_PORT_NUM)) {
332
if(hw_port == CLT_PORT_INVALID) {
333
RTW_ERR(ADPT_FMT" @@@@@ Client port == 0 @@@@@\n", ADPT_ARG(adapter));
334
rtw_warn_on(1);
335
}
336
}
337
else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
338
if (hw_port != HW_PORT0) {
339
RTW_ERR(ADPT_FMT" @@@@@ AP / MESH port != 0 @@@@@\n", ADPT_ARG(adapter));
340
rtw_warn_on(1);
341
}
342
}
343
if (0)
344
RTW_INFO(ADPT_FMT" - HP:%d,CP:%d\n", ADPT_ARG(adapter), get_hw_port(adapter), get_clt_port(adapter));
345
#endif /*DBG_HW_PORT*/
346
347
#endif/*CONFIG_CLIENT_PORT_CFG*/
348
349
return hw_port;
350
}
351
352
#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
353
354
/*
355
* Description:
356
* Use hardware(efuse), driver parameter(registry) and default channel plan
357
* to decide which one should be used.
358
*
359
* Parameters:
360
* padapter pointer of adapter
361
* hw_alpha2 country code from HW (efuse/eeprom/mapfile)
362
* hw_chplan channel plan from HW (efuse/eeprom/mapfile)
363
* BIT[7] software configure mode; 0:Enable, 1:disable
364
* BIT[6:0] Channel Plan
365
* sw_alpha2 country code from HW (registry/module param)
366
* sw_chplan channel plan from SW (registry/module param)
367
* def_chplan channel plan used when HW/SW both invalid
368
* AutoLoadFail efuse autoload fail or not
369
*
370
*/
371
void hal_com_config_channel_plan(
372
PADAPTER padapter,
373
char *hw_alpha2,
374
u8 hw_chplan,
375
char *sw_alpha2,
376
u8 sw_chplan,
377
u8 def_chplan,
378
BOOLEAN AutoLoadFail
379
)
380
{
381
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
382
PHAL_DATA_TYPE pHalData;
383
u8 force_hw_chplan = _FALSE;
384
int chplan = -1;
385
const struct country_chplan *country_ent = NULL, *ent;
386
387
pHalData = GET_HAL_DATA(padapter);
388
389
/* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
390
if (hw_chplan == 0xFF)
391
goto chk_hw_country_code;
392
393
if (AutoLoadFail == _TRUE)
394
goto chk_sw_config;
395
396
#ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
397
if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
398
force_hw_chplan = _TRUE;
399
#endif
400
401
hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
402
403
chk_hw_country_code:
404
if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
405
ent = rtw_get_chplan_from_country(hw_alpha2);
406
if (ent) {
407
/* get chplan from hw country code, by pass hw chplan setting */
408
country_ent = ent;
409
chplan = ent->chplan;
410
goto chk_sw_config;
411
} else
412
RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
413
}
414
415
if (rtw_is_channel_plan_valid(hw_chplan))
416
chplan = hw_chplan;
417
else if (force_hw_chplan == _TRUE) {
418
RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
419
/* hw infomaton invalid, refer to sw information */
420
force_hw_chplan = _FALSE;
421
}
422
423
chk_sw_config:
424
if (force_hw_chplan == _TRUE)
425
goto done;
426
427
if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
428
ent = rtw_get_chplan_from_country(sw_alpha2);
429
if (ent) {
430
/* get chplan from sw country code, by pass sw chplan setting */
431
country_ent = ent;
432
chplan = ent->chplan;
433
goto done;
434
} else
435
RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
436
}
437
438
if (rtw_is_channel_plan_valid(sw_chplan)) {
439
/* cancel hw_alpha2 because chplan is specified by sw_chplan*/
440
country_ent = NULL;
441
chplan = sw_chplan;
442
} else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
443
RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
444
445
done:
446
if (chplan == -1) {
447
RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
448
chplan = def_chplan;
449
} else if (country_ent) {
450
RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
451
, country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
452
} else
453
RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
454
455
rfctl->country_ent = country_ent;
456
rfctl->ChannelPlan = chplan;
457
pHalData->bDisableSWChannelPlan = force_hw_chplan;
458
}
459
460
BOOLEAN
461
HAL_IsLegalChannel(
462
PADAPTER Adapter,
463
u32 Channel
464
)
465
{
466
BOOLEAN bLegalChannel = _TRUE;
467
468
if (Channel > 14) {
469
if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
470
bLegalChannel = _FALSE;
471
RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
472
}
473
} else if ((Channel <= 14) && (Channel >= 1)) {
474
if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
475
bLegalChannel = _FALSE;
476
RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
477
}
478
} else {
479
bLegalChannel = _FALSE;
480
RTW_INFO("Channel is Invalid !!!\n");
481
}
482
483
return bLegalChannel;
484
}
485
486
u8 MRateToHwRate(u8 rate)
487
{
488
u8 ret = DESC_RATE1M;
489
490
switch (rate) {
491
case MGN_1M:
492
ret = DESC_RATE1M;
493
break;
494
case MGN_2M:
495
ret = DESC_RATE2M;
496
break;
497
case MGN_5_5M:
498
ret = DESC_RATE5_5M;
499
break;
500
case MGN_11M:
501
ret = DESC_RATE11M;
502
break;
503
case MGN_6M:
504
ret = DESC_RATE6M;
505
break;
506
case MGN_9M:
507
ret = DESC_RATE9M;
508
break;
509
case MGN_12M:
510
ret = DESC_RATE12M;
511
break;
512
case MGN_18M:
513
ret = DESC_RATE18M;
514
break;
515
case MGN_24M:
516
ret = DESC_RATE24M;
517
break;
518
case MGN_36M:
519
ret = DESC_RATE36M;
520
break;
521
case MGN_48M:
522
ret = DESC_RATE48M;
523
break;
524
case MGN_54M:
525
ret = DESC_RATE54M;
526
break;
527
528
case MGN_MCS0:
529
ret = DESC_RATEMCS0;
530
break;
531
case MGN_MCS1:
532
ret = DESC_RATEMCS1;
533
break;
534
case MGN_MCS2:
535
ret = DESC_RATEMCS2;
536
break;
537
case MGN_MCS3:
538
ret = DESC_RATEMCS3;
539
break;
540
case MGN_MCS4:
541
ret = DESC_RATEMCS4;
542
break;
543
case MGN_MCS5:
544
ret = DESC_RATEMCS5;
545
break;
546
case MGN_MCS6:
547
ret = DESC_RATEMCS6;
548
break;
549
case MGN_MCS7:
550
ret = DESC_RATEMCS7;
551
break;
552
case MGN_MCS8:
553
ret = DESC_RATEMCS8;
554
break;
555
case MGN_MCS9:
556
ret = DESC_RATEMCS9;
557
break;
558
case MGN_MCS10:
559
ret = DESC_RATEMCS10;
560
break;
561
case MGN_MCS11:
562
ret = DESC_RATEMCS11;
563
break;
564
case MGN_MCS12:
565
ret = DESC_RATEMCS12;
566
break;
567
case MGN_MCS13:
568
ret = DESC_RATEMCS13;
569
break;
570
case MGN_MCS14:
571
ret = DESC_RATEMCS14;
572
break;
573
case MGN_MCS15:
574
ret = DESC_RATEMCS15;
575
break;
576
case MGN_MCS16:
577
ret = DESC_RATEMCS16;
578
break;
579
case MGN_MCS17:
580
ret = DESC_RATEMCS17;
581
break;
582
case MGN_MCS18:
583
ret = DESC_RATEMCS18;
584
break;
585
case MGN_MCS19:
586
ret = DESC_RATEMCS19;
587
break;
588
case MGN_MCS20:
589
ret = DESC_RATEMCS20;
590
break;
591
case MGN_MCS21:
592
ret = DESC_RATEMCS21;
593
break;
594
case MGN_MCS22:
595
ret = DESC_RATEMCS22;
596
break;
597
case MGN_MCS23:
598
ret = DESC_RATEMCS23;
599
break;
600
case MGN_MCS24:
601
ret = DESC_RATEMCS24;
602
break;
603
case MGN_MCS25:
604
ret = DESC_RATEMCS25;
605
break;
606
case MGN_MCS26:
607
ret = DESC_RATEMCS26;
608
break;
609
case MGN_MCS27:
610
ret = DESC_RATEMCS27;
611
break;
612
case MGN_MCS28:
613
ret = DESC_RATEMCS28;
614
break;
615
case MGN_MCS29:
616
ret = DESC_RATEMCS29;
617
break;
618
case MGN_MCS30:
619
ret = DESC_RATEMCS30;
620
break;
621
case MGN_MCS31:
622
ret = DESC_RATEMCS31;
623
break;
624
625
case MGN_VHT1SS_MCS0:
626
ret = DESC_RATEVHTSS1MCS0;
627
break;
628
case MGN_VHT1SS_MCS1:
629
ret = DESC_RATEVHTSS1MCS1;
630
break;
631
case MGN_VHT1SS_MCS2:
632
ret = DESC_RATEVHTSS1MCS2;
633
break;
634
case MGN_VHT1SS_MCS3:
635
ret = DESC_RATEVHTSS1MCS3;
636
break;
637
case MGN_VHT1SS_MCS4:
638
ret = DESC_RATEVHTSS1MCS4;
639
break;
640
case MGN_VHT1SS_MCS5:
641
ret = DESC_RATEVHTSS1MCS5;
642
break;
643
case MGN_VHT1SS_MCS6:
644
ret = DESC_RATEVHTSS1MCS6;
645
break;
646
case MGN_VHT1SS_MCS7:
647
ret = DESC_RATEVHTSS1MCS7;
648
break;
649
case MGN_VHT1SS_MCS8:
650
ret = DESC_RATEVHTSS1MCS8;
651
break;
652
case MGN_VHT1SS_MCS9:
653
ret = DESC_RATEVHTSS1MCS9;
654
break;
655
case MGN_VHT2SS_MCS0:
656
ret = DESC_RATEVHTSS2MCS0;
657
break;
658
case MGN_VHT2SS_MCS1:
659
ret = DESC_RATEVHTSS2MCS1;
660
break;
661
case MGN_VHT2SS_MCS2:
662
ret = DESC_RATEVHTSS2MCS2;
663
break;
664
case MGN_VHT2SS_MCS3:
665
ret = DESC_RATEVHTSS2MCS3;
666
break;
667
case MGN_VHT2SS_MCS4:
668
ret = DESC_RATEVHTSS2MCS4;
669
break;
670
case MGN_VHT2SS_MCS5:
671
ret = DESC_RATEVHTSS2MCS5;
672
break;
673
case MGN_VHT2SS_MCS6:
674
ret = DESC_RATEVHTSS2MCS6;
675
break;
676
case MGN_VHT2SS_MCS7:
677
ret = DESC_RATEVHTSS2MCS7;
678
break;
679
case MGN_VHT2SS_MCS8:
680
ret = DESC_RATEVHTSS2MCS8;
681
break;
682
case MGN_VHT2SS_MCS9:
683
ret = DESC_RATEVHTSS2MCS9;
684
break;
685
case MGN_VHT3SS_MCS0:
686
ret = DESC_RATEVHTSS3MCS0;
687
break;
688
case MGN_VHT3SS_MCS1:
689
ret = DESC_RATEVHTSS3MCS1;
690
break;
691
case MGN_VHT3SS_MCS2:
692
ret = DESC_RATEVHTSS3MCS2;
693
break;
694
case MGN_VHT3SS_MCS3:
695
ret = DESC_RATEVHTSS3MCS3;
696
break;
697
case MGN_VHT3SS_MCS4:
698
ret = DESC_RATEVHTSS3MCS4;
699
break;
700
case MGN_VHT3SS_MCS5:
701
ret = DESC_RATEVHTSS3MCS5;
702
break;
703
case MGN_VHT3SS_MCS6:
704
ret = DESC_RATEVHTSS3MCS6;
705
break;
706
case MGN_VHT3SS_MCS7:
707
ret = DESC_RATEVHTSS3MCS7;
708
break;
709
case MGN_VHT3SS_MCS8:
710
ret = DESC_RATEVHTSS3MCS8;
711
break;
712
case MGN_VHT3SS_MCS9:
713
ret = DESC_RATEVHTSS3MCS9;
714
break;
715
case MGN_VHT4SS_MCS0:
716
ret = DESC_RATEVHTSS4MCS0;
717
break;
718
case MGN_VHT4SS_MCS1:
719
ret = DESC_RATEVHTSS4MCS1;
720
break;
721
case MGN_VHT4SS_MCS2:
722
ret = DESC_RATEVHTSS4MCS2;
723
break;
724
case MGN_VHT4SS_MCS3:
725
ret = DESC_RATEVHTSS4MCS3;
726
break;
727
case MGN_VHT4SS_MCS4:
728
ret = DESC_RATEVHTSS4MCS4;
729
break;
730
case MGN_VHT4SS_MCS5:
731
ret = DESC_RATEVHTSS4MCS5;
732
break;
733
case MGN_VHT4SS_MCS6:
734
ret = DESC_RATEVHTSS4MCS6;
735
break;
736
case MGN_VHT4SS_MCS7:
737
ret = DESC_RATEVHTSS4MCS7;
738
break;
739
case MGN_VHT4SS_MCS8:
740
ret = DESC_RATEVHTSS4MCS8;
741
break;
742
case MGN_VHT4SS_MCS9:
743
ret = DESC_RATEVHTSS4MCS9;
744
break;
745
default:
746
break;
747
}
748
749
return ret;
750
}
751
752
u8 hw_rate_to_m_rate(u8 rate)
753
{
754
u8 ret_rate = MGN_1M;
755
756
switch (rate) {
757
758
case DESC_RATE1M:
759
ret_rate = MGN_1M;
760
break;
761
case DESC_RATE2M:
762
ret_rate = MGN_2M;
763
break;
764
case DESC_RATE5_5M:
765
ret_rate = MGN_5_5M;
766
break;
767
case DESC_RATE11M:
768
ret_rate = MGN_11M;
769
break;
770
case DESC_RATE6M:
771
ret_rate = MGN_6M;
772
break;
773
case DESC_RATE9M:
774
ret_rate = MGN_9M;
775
break;
776
case DESC_RATE12M:
777
ret_rate = MGN_12M;
778
break;
779
case DESC_RATE18M:
780
ret_rate = MGN_18M;
781
break;
782
case DESC_RATE24M:
783
ret_rate = MGN_24M;
784
break;
785
case DESC_RATE36M:
786
ret_rate = MGN_36M;
787
break;
788
case DESC_RATE48M:
789
ret_rate = MGN_48M;
790
break;
791
case DESC_RATE54M:
792
ret_rate = MGN_54M;
793
break;
794
case DESC_RATEMCS0:
795
ret_rate = MGN_MCS0;
796
break;
797
case DESC_RATEMCS1:
798
ret_rate = MGN_MCS1;
799
break;
800
case DESC_RATEMCS2:
801
ret_rate = MGN_MCS2;
802
break;
803
case DESC_RATEMCS3:
804
ret_rate = MGN_MCS3;
805
break;
806
case DESC_RATEMCS4:
807
ret_rate = MGN_MCS4;
808
break;
809
case DESC_RATEMCS5:
810
ret_rate = MGN_MCS5;
811
break;
812
case DESC_RATEMCS6:
813
ret_rate = MGN_MCS6;
814
break;
815
case DESC_RATEMCS7:
816
ret_rate = MGN_MCS7;
817
break;
818
case DESC_RATEMCS8:
819
ret_rate = MGN_MCS8;
820
break;
821
case DESC_RATEMCS9:
822
ret_rate = MGN_MCS9;
823
break;
824
case DESC_RATEMCS10:
825
ret_rate = MGN_MCS10;
826
break;
827
case DESC_RATEMCS11:
828
ret_rate = MGN_MCS11;
829
break;
830
case DESC_RATEMCS12:
831
ret_rate = MGN_MCS12;
832
break;
833
case DESC_RATEMCS13:
834
ret_rate = MGN_MCS13;
835
break;
836
case DESC_RATEMCS14:
837
ret_rate = MGN_MCS14;
838
break;
839
case DESC_RATEMCS15:
840
ret_rate = MGN_MCS15;
841
break;
842
case DESC_RATEMCS16:
843
ret_rate = MGN_MCS16;
844
break;
845
case DESC_RATEMCS17:
846
ret_rate = MGN_MCS17;
847
break;
848
case DESC_RATEMCS18:
849
ret_rate = MGN_MCS18;
850
break;
851
case DESC_RATEMCS19:
852
ret_rate = MGN_MCS19;
853
break;
854
case DESC_RATEMCS20:
855
ret_rate = MGN_MCS20;
856
break;
857
case DESC_RATEMCS21:
858
ret_rate = MGN_MCS21;
859
break;
860
case DESC_RATEMCS22:
861
ret_rate = MGN_MCS22;
862
break;
863
case DESC_RATEMCS23:
864
ret_rate = MGN_MCS23;
865
break;
866
case DESC_RATEMCS24:
867
ret_rate = MGN_MCS24;
868
break;
869
case DESC_RATEMCS25:
870
ret_rate = MGN_MCS25;
871
break;
872
case DESC_RATEMCS26:
873
ret_rate = MGN_MCS26;
874
break;
875
case DESC_RATEMCS27:
876
ret_rate = MGN_MCS27;
877
break;
878
case DESC_RATEMCS28:
879
ret_rate = MGN_MCS28;
880
break;
881
case DESC_RATEMCS29:
882
ret_rate = MGN_MCS29;
883
break;
884
case DESC_RATEMCS30:
885
ret_rate = MGN_MCS30;
886
break;
887
case DESC_RATEMCS31:
888
ret_rate = MGN_MCS31;
889
break;
890
case DESC_RATEVHTSS1MCS0:
891
ret_rate = MGN_VHT1SS_MCS0;
892
break;
893
case DESC_RATEVHTSS1MCS1:
894
ret_rate = MGN_VHT1SS_MCS1;
895
break;
896
case DESC_RATEVHTSS1MCS2:
897
ret_rate = MGN_VHT1SS_MCS2;
898
break;
899
case DESC_RATEVHTSS1MCS3:
900
ret_rate = MGN_VHT1SS_MCS3;
901
break;
902
case DESC_RATEVHTSS1MCS4:
903
ret_rate = MGN_VHT1SS_MCS4;
904
break;
905
case DESC_RATEVHTSS1MCS5:
906
ret_rate = MGN_VHT1SS_MCS5;
907
break;
908
case DESC_RATEVHTSS1MCS6:
909
ret_rate = MGN_VHT1SS_MCS6;
910
break;
911
case DESC_RATEVHTSS1MCS7:
912
ret_rate = MGN_VHT1SS_MCS7;
913
break;
914
case DESC_RATEVHTSS1MCS8:
915
ret_rate = MGN_VHT1SS_MCS8;
916
break;
917
case DESC_RATEVHTSS1MCS9:
918
ret_rate = MGN_VHT1SS_MCS9;
919
break;
920
case DESC_RATEVHTSS2MCS0:
921
ret_rate = MGN_VHT2SS_MCS0;
922
break;
923
case DESC_RATEVHTSS2MCS1:
924
ret_rate = MGN_VHT2SS_MCS1;
925
break;
926
case DESC_RATEVHTSS2MCS2:
927
ret_rate = MGN_VHT2SS_MCS2;
928
break;
929
case DESC_RATEVHTSS2MCS3:
930
ret_rate = MGN_VHT2SS_MCS3;
931
break;
932
case DESC_RATEVHTSS2MCS4:
933
ret_rate = MGN_VHT2SS_MCS4;
934
break;
935
case DESC_RATEVHTSS2MCS5:
936
ret_rate = MGN_VHT2SS_MCS5;
937
break;
938
case DESC_RATEVHTSS2MCS6:
939
ret_rate = MGN_VHT2SS_MCS6;
940
break;
941
case DESC_RATEVHTSS2MCS7:
942
ret_rate = MGN_VHT2SS_MCS7;
943
break;
944
case DESC_RATEVHTSS2MCS8:
945
ret_rate = MGN_VHT2SS_MCS8;
946
break;
947
case DESC_RATEVHTSS2MCS9:
948
ret_rate = MGN_VHT2SS_MCS9;
949
break;
950
case DESC_RATEVHTSS3MCS0:
951
ret_rate = MGN_VHT3SS_MCS0;
952
break;
953
case DESC_RATEVHTSS3MCS1:
954
ret_rate = MGN_VHT3SS_MCS1;
955
break;
956
case DESC_RATEVHTSS3MCS2:
957
ret_rate = MGN_VHT3SS_MCS2;
958
break;
959
case DESC_RATEVHTSS3MCS3:
960
ret_rate = MGN_VHT3SS_MCS3;
961
break;
962
case DESC_RATEVHTSS3MCS4:
963
ret_rate = MGN_VHT3SS_MCS4;
964
break;
965
case DESC_RATEVHTSS3MCS5:
966
ret_rate = MGN_VHT3SS_MCS5;
967
break;
968
case DESC_RATEVHTSS3MCS6:
969
ret_rate = MGN_VHT3SS_MCS6;
970
break;
971
case DESC_RATEVHTSS3MCS7:
972
ret_rate = MGN_VHT3SS_MCS7;
973
break;
974
case DESC_RATEVHTSS3MCS8:
975
ret_rate = MGN_VHT3SS_MCS8;
976
break;
977
case DESC_RATEVHTSS3MCS9:
978
ret_rate = MGN_VHT3SS_MCS9;
979
break;
980
case DESC_RATEVHTSS4MCS0:
981
ret_rate = MGN_VHT4SS_MCS0;
982
break;
983
case DESC_RATEVHTSS4MCS1:
984
ret_rate = MGN_VHT4SS_MCS1;
985
break;
986
case DESC_RATEVHTSS4MCS2:
987
ret_rate = MGN_VHT4SS_MCS2;
988
break;
989
case DESC_RATEVHTSS4MCS3:
990
ret_rate = MGN_VHT4SS_MCS3;
991
break;
992
case DESC_RATEVHTSS4MCS4:
993
ret_rate = MGN_VHT4SS_MCS4;
994
break;
995
case DESC_RATEVHTSS4MCS5:
996
ret_rate = MGN_VHT4SS_MCS5;
997
break;
998
case DESC_RATEVHTSS4MCS6:
999
ret_rate = MGN_VHT4SS_MCS6;
1000
break;
1001
case DESC_RATEVHTSS4MCS7:
1002
ret_rate = MGN_VHT4SS_MCS7;
1003
break;
1004
case DESC_RATEVHTSS4MCS8:
1005
ret_rate = MGN_VHT4SS_MCS8;
1006
break;
1007
case DESC_RATEVHTSS4MCS9:
1008
ret_rate = MGN_VHT4SS_MCS9;
1009
break;
1010
1011
default:
1012
RTW_INFO("hw_rate_to_m_rate(): Non supported Rate [%x]!!!\n", rate);
1013
break;
1014
}
1015
1016
return ret_rate;
1017
}
1018
1019
void HalSetBrateCfg(
1020
PADAPTER Adapter,
1021
u8 *mBratesOS,
1022
u16 *pBrateCfg)
1023
{
1024
u8 i, is_brate, brate;
1025
1026
for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
1027
is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
1028
brate = mBratesOS[i] & 0x7f;
1029
1030
if (is_brate) {
1031
switch (brate) {
1032
case IEEE80211_CCK_RATE_1MB:
1033
*pBrateCfg |= RATE_1M;
1034
break;
1035
case IEEE80211_CCK_RATE_2MB:
1036
*pBrateCfg |= RATE_2M;
1037
break;
1038
case IEEE80211_CCK_RATE_5MB:
1039
*pBrateCfg |= RATE_5_5M;
1040
break;
1041
case IEEE80211_CCK_RATE_11MB:
1042
*pBrateCfg |= RATE_11M;
1043
break;
1044
case IEEE80211_OFDM_RATE_6MB:
1045
*pBrateCfg |= RATE_6M;
1046
break;
1047
case IEEE80211_OFDM_RATE_9MB:
1048
*pBrateCfg |= RATE_9M;
1049
break;
1050
case IEEE80211_OFDM_RATE_12MB:
1051
*pBrateCfg |= RATE_12M;
1052
break;
1053
case IEEE80211_OFDM_RATE_18MB:
1054
*pBrateCfg |= RATE_18M;
1055
break;
1056
case IEEE80211_OFDM_RATE_24MB:
1057
*pBrateCfg |= RATE_24M;
1058
break;
1059
case IEEE80211_OFDM_RATE_36MB:
1060
*pBrateCfg |= RATE_36M;
1061
break;
1062
case IEEE80211_OFDM_RATE_48MB:
1063
*pBrateCfg |= RATE_48M;
1064
break;
1065
case IEEE80211_OFDM_RATE_54MB:
1066
*pBrateCfg |= RATE_54M;
1067
break;
1068
}
1069
}
1070
}
1071
}
1072
1073
static void
1074
_OneOutPipeMapping(
1075
PADAPTER pAdapter
1076
)
1077
{
1078
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1079
1080
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1081
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1082
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
1083
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
1084
1085
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1086
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1087
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1088
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1089
}
1090
1091
static void
1092
_TwoOutPipeMapping(
1093
PADAPTER pAdapter,
1094
BOOLEAN bWIFICfg
1095
)
1096
{
1097
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1098
1099
if (bWIFICfg) { /* WMM */
1100
1101
/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1102
/* { 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
1103
/* 0:ep_0 num, 1:ep_1 num */
1104
1105
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
1106
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1107
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
1108
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
1109
1110
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1111
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1112
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1113
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1114
1115
} else { /* typical setting */
1116
1117
1118
/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1119
/* { 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
1120
/* 0:ep_0 num, 1:ep_1 num */
1121
1122
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1123
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1124
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
1125
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1126
1127
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1128
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1129
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1130
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1131
1132
}
1133
1134
}
1135
1136
static void _ThreeOutPipeMapping(
1137
PADAPTER pAdapter,
1138
BOOLEAN bWIFICfg
1139
)
1140
{
1141
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1142
1143
if (bWIFICfg) { /* for WMM */
1144
1145
/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1146
/* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1147
/* 0:H, 1:N, 2:L */
1148
1149
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1150
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1151
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1152
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1153
1154
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1155
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1156
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1157
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1158
1159
} else { /* typical setting */
1160
1161
1162
/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1163
/* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1164
/* 0:H, 1:N, 2:L */
1165
1166
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1167
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1168
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1169
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1170
1171
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1172
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1173
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1174
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1175
}
1176
1177
}
1178
#if 0
1179
static void _FourOutPipeMapping(
1180
PADAPTER pAdapter,
1181
BOOLEAN bWIFICfg
1182
)
1183
{
1184
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1185
1186
if (bWIFICfg) { /* for WMM */
1187
1188
/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1189
/* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1190
/* 0:H, 1:N, 2:L ,3:E */
1191
1192
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1193
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1194
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1195
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1196
1197
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1198
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1199
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1200
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1201
1202
} else { /* typical setting */
1203
1204
1205
/* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1206
/* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1207
/* 0:H, 1:N, 2:L */
1208
1209
pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1210
pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1211
pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1212
pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1213
1214
pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1215
pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1216
pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1217
pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1218
}
1219
1220
}
1221
#endif
1222
BOOLEAN
1223
Hal_MappingOutPipe(
1224
PADAPTER pAdapter,
1225
u8 NumOutPipe
1226
)
1227
{
1228
struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
1229
1230
BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
1231
1232
BOOLEAN result = _TRUE;
1233
1234
switch (NumOutPipe) {
1235
case 2:
1236
_TwoOutPipeMapping(pAdapter, bWIFICfg);
1237
break;
1238
case 3:
1239
case 4:
1240
case 5:
1241
case 6:
1242
_ThreeOutPipeMapping(pAdapter, bWIFICfg);
1243
break;
1244
case 1:
1245
_OneOutPipeMapping(pAdapter);
1246
break;
1247
default:
1248
result = _FALSE;
1249
break;
1250
}
1251
1252
return result;
1253
1254
}
1255
1256
void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1257
{
1258
if (padapter->hal_func.reqtxrpt)
1259
padapter->hal_func.reqtxrpt(padapter, macid);
1260
}
1261
1262
void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1263
{
1264
int i;
1265
_adapter *iface;
1266
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1267
u8 mac_addr[ETH_ALEN];
1268
1269
#ifdef CONFIG_MI_WITH_MBSSID_CAM
1270
rtw_mbid_cam_dump(sel, __func__, adapter);
1271
#else
1272
for (i = 0; i < dvobj->iface_nums; i++) {
1273
iface = dvobj->padapters[i];
1274
if (iface) {
1275
rtw_hal_get_hwreg(iface, HW_VAR_MAC_ADDR, mac_addr);
1276
RTW_PRINT_SEL(sel, ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",
1277
ADPT_ARG(iface), iface->hw_port, MAC_ARG(mac_addr));
1278
}
1279
}
1280
#endif
1281
}
1282
1283
#ifdef RTW_HALMAC
1284
void rtw_hal_hw_port_enable(_adapter *adapter)
1285
{
1286
#if 1
1287
u8 port_enable = _TRUE;
1288
1289
rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1290
#else
1291
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1292
struct rtw_halmac_bcn_ctrl bcn_ctrl;
1293
1294
_rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
1295
bcn_ctrl.enable_bcn = 1;
1296
bcn_ctrl.rx_bssid_fit = 1;
1297
bcn_ctrl.rxbcn_rpt = 1;
1298
1299
/*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1300
struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
1301
if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
1302
RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
1303
rtw_warn_on(1);
1304
}
1305
#endif
1306
}
1307
void rtw_hal_hw_port_disable(_adapter *adapter)
1308
{
1309
u8 port_enable = _FALSE;
1310
1311
rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1312
}
1313
1314
void rtw_restore_hw_port_cfg(_adapter *adapter)
1315
{
1316
#ifdef CONFIG_MI_WITH_MBSSID_CAM
1317
1318
#else
1319
int i;
1320
_adapter *iface;
1321
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1322
1323
for (i = 0; i < dvobj->iface_nums; i++) {
1324
iface = dvobj->padapters[i];
1325
if (iface)
1326
rtw_hal_hw_port_enable(iface);
1327
}
1328
#endif
1329
}
1330
#endif
1331
1332
void rtw_mi_set_mac_addr(_adapter *adapter)
1333
{
1334
#ifdef CONFIG_MI_WITH_MBSSID_CAM
1335
rtw_mi_set_mbid_cam(adapter);
1336
#else
1337
int i;
1338
_adapter *iface;
1339
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1340
1341
for (i = 0; i < dvobj->iface_nums; i++) {
1342
iface = dvobj->padapters[i];
1343
if (iface)
1344
rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
1345
}
1346
#endif
1347
if (1)
1348
rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1349
}
1350
1351
void rtw_init_hal_com_default_value(PADAPTER Adapter)
1352
{
1353
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
1354
struct registry_priv *regsty = adapter_to_regsty(Adapter);
1355
1356
pHalData->AntDetection = 1;
1357
pHalData->antenna_test = _FALSE;
1358
pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
1359
pHalData->ch_switch_offload = regsty->ch_switch_offload;
1360
pHalData->multi_ch_switch_mode = 0;
1361
#ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME
1362
if (pHalData->ch_switch_offload == 0)
1363
pHalData->ch_switch_offload = 1;
1364
#endif
1365
}
1366
1367
#ifdef CONFIG_FW_C2H_REG
1368
void c2h_evt_clear(_adapter *adapter)
1369
{
1370
rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1371
}
1372
1373
s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1374
{
1375
s32 ret = _FAIL;
1376
int i;
1377
u8 trigger;
1378
1379
if (buf == NULL)
1380
goto exit;
1381
1382
trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1383
1384
if (trigger == C2H_EVT_HOST_CLOSE) {
1385
goto exit; /* Not ready */
1386
} else if (trigger != C2H_EVT_FW_CLOSE) {
1387
goto clear_evt; /* Not a valid value */
1388
}
1389
1390
_rtw_memset(buf, 0, C2H_REG_LEN);
1391
1392
/* Read ID, LEN, SEQ */
1393
SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
1394
SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
1395
SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
1396
1397
if (0) {
1398
RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
1399
, C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
1400
}
1401
1402
/* Read the content */
1403
for (i = 0; i < C2H_PLEN_88XX(buf); i++)
1404
*(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1405
1406
RTW_DBG_DUMP("payload: ", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
1407
1408
ret = _SUCCESS;
1409
1410
clear_evt:
1411
/*
1412
* Clear event to notify FW we have read the command.
1413
* If this field isn't clear, the FW won't update the next command message.
1414
*/
1415
c2h_evt_clear(adapter);
1416
1417
exit:
1418
return ret;
1419
}
1420
#endif /* CONFIG_FW_C2H_REG */
1421
1422
#ifdef CONFIG_FW_C2H_PKT
1423
#ifndef DBG_C2H_PKT_PRE_HDL
1424
#define DBG_C2H_PKT_PRE_HDL 0
1425
#endif
1426
#ifndef DBG_C2H_PKT_HDL
1427
#define DBG_C2H_PKT_HDL 0
1428
#endif
1429
void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
1430
{
1431
#ifdef RTW_HALMAC
1432
/* TODO: extract hal_mac IC's code here*/
1433
#else
1434
u8 parse_fail = 0;
1435
u8 hdl_here = 0;
1436
s32 ret = _FAIL;
1437
u8 id, seq, plen;
1438
u8 *payload;
1439
1440
if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1441
parse_fail = 1;
1442
goto exit;
1443
}
1444
1445
hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
1446
if (hdl_here)
1447
ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1448
else
1449
ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
1450
1451
exit:
1452
if (parse_fail)
1453
RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1454
else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
1455
RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1456
, hdl_here ? "handle" : "enqueue"
1457
, ret == _SUCCESS ? "ok" : "fail"
1458
);
1459
if (DBG_C2H_PKT_PRE_HDL >= 2)
1460
RTW_PRINT_DUMP("dump: ", buf, len);
1461
}
1462
#endif
1463
}
1464
1465
void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
1466
{
1467
#ifdef RTW_HALMAC
1468
adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
1469
#else
1470
u8 parse_fail = 0;
1471
u8 bypass = 0;
1472
s32 ret = _FAIL;
1473
u8 id, seq, plen;
1474
u8 *payload;
1475
1476
if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1477
parse_fail = 1;
1478
goto exit;
1479
}
1480
1481
#ifdef CONFIG_WOWLAN
1482
if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
1483
bypass = 1;
1484
ret = _SUCCESS;
1485
goto exit;
1486
}
1487
#endif
1488
1489
ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1490
1491
exit:
1492
if (parse_fail)
1493
RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1494
else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
1495
RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1496
, !bypass ? "handle" : "bypass"
1497
, ret == _SUCCESS ? "ok" : "fail"
1498
);
1499
if (DBG_C2H_PKT_HDL >= 2)
1500
RTW_PRINT_DUMP("dump: ", buf, len);
1501
}
1502
#endif
1503
}
1504
#endif /* CONFIG_FW_C2H_PKT */
1505
1506
void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
1507
{
1508
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1509
struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1510
1511
RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
1512
if (0)
1513
RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
1514
1515
rtw_sctx_done(&iqk_sctx);
1516
}
1517
1518
int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
1519
{
1520
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1521
struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1522
1523
iqk_sctx->submit_time = rtw_get_current_time();
1524
iqk_sctx->timeout_ms = timeout_ms;
1525
iqk_sctx->status = RTW_SCTX_SUBMITTED;
1526
1527
return rtw_sctx_wait(iqk_sctx, __func__);
1528
}
1529
1530
#define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1531
#define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1532
#define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1533
#define GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1534
#define GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1535
#define GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
1536
#define GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
1537
#define GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1538
#define GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1539
#define GET_C2H_MAC_HIDDEN_RPT_BW(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1540
#define GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1541
#define GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1542
#define GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1543
1544
#ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1545
#define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1546
#endif
1547
1548
#ifdef CONFIG_RTW_MAC_HIDDEN_RPT
1549
int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1550
{
1551
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1552
struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1553
enum rf_type rf_type;
1554
int ret = _FAIL;
1555
1556
u8 uuid_x;
1557
u8 uuid_y;
1558
u8 uuid_z;
1559
u16 uuid_crc;
1560
1561
u8 hci_type;
1562
u8 package_type;
1563
u8 tr_switch;
1564
u8 wl_func;
1565
u8 hw_stype;
1566
u8 bw;
1567
u8 ss_num = 4;
1568
u8 ant_num;
1569
u8 protocol;
1570
u8 nic;
1571
1572
int i;
1573
1574
if (len < MAC_HIDDEN_RPT_LEN) {
1575
RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1576
goto exit;
1577
}
1578
1579
uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1580
uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1581
uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1582
uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1583
1584
hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1585
package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1586
1587
tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
1588
1589
wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1590
hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1591
1592
bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1593
ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1594
1595
protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1596
nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1597
1598
if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1599
for (i = 0; i < len; i++)
1600
RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1601
1602
RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1603
RTW_PRINT("hci_type:0x%x\n", hci_type);
1604
RTW_PRINT("package_type:0x%x\n", package_type);
1605
RTW_PRINT("tr_switch:0x%x\n", tr_switch);
1606
RTW_PRINT("wl_func:0x%x\n", wl_func);
1607
RTW_PRINT("hw_stype:0x%x\n", hw_stype);
1608
RTW_PRINT("bw:0x%x\n", bw);
1609
RTW_PRINT("ant_num:0x%x\n", ant_num);
1610
RTW_PRINT("protocol:0x%x\n", protocol);
1611
RTW_PRINT("nic:0x%x\n", nic);
1612
}
1613
1614
#if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
1615
if (IS_8822C_SERIES(hal_data->version_id) || IS_8814B_SERIES(hal_data->version_id)) {
1616
#define GET_C2H_MAC_HIDDEN_RPT_SS_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)
1617
ss_num = GET_C2H_MAC_HIDDEN_RPT_SS_NUM(data);
1618
1619
if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1620
RTW_PRINT("ss_num:0x%x\n", ss_num);
1621
1622
if (ss_num == 0x03)
1623
ss_num = 4;
1624
}
1625
#endif
1626
1627
#if defined(CONFIG_RTL8822C)
1628
if (IS_8822C_SERIES(hal_data->version_id)) {
1629
if (hw_stype == 0xE)
1630
hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, 1); /* limit 1TX only */
1631
}
1632
#endif
1633
hal_data->PackageType = package_type;
1634
hal_spec->hci_type = hci_type;
1635
hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1636
hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1637
hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1638
1639
rf_type = rtw_chip_rftype_to_rfpath(adapter);
1640
if (!RF_TYPE_VALID(rf_type)) {
1641
RTW_ERR("%s rtw_chip_rftype_to_rfpath failed\n", __func__);
1642
goto exit;
1643
}
1644
1645
/*
1646
* RF TX path num >= max_tx_cnt >= tx_nss_num
1647
* ex: RF TX path num(4) >= max_tx_cnt(2) >= tx_nss_num(1)
1648
* Select at most 2 out of 4 TX RF path to do 1SS 2TX
1649
*/
1650
hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, rf_type_to_rf_tx_cnt(rf_type));
1651
hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, ant_num);
1652
hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, hal_spec->max_tx_cnt);
1653
hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ss_num);
1654
1655
hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rf_type_to_rf_rx_cnt(rf_type));
1656
hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ant_num);
1657
hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ss_num);
1658
1659
ret = _SUCCESS;
1660
1661
exit:
1662
return ret;
1663
}
1664
1665
int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1666
{
1667
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1668
int ret = _FAIL;
1669
1670
int i;
1671
1672
if (len < MAC_HIDDEN_RPT_2_LEN) {
1673
RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
1674
goto exit;
1675
}
1676
1677
if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1678
for (i = 0; i < len; i++)
1679
RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1680
}
1681
1682
#if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)
1683
if (IS_8188F(hal_data->version_id) || IS_8188GTV(hal_data->version_id)) {
1684
#define GET_C2H_MAC_HIDDEN_RPT_IRV(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
1685
u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
1686
1687
if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1688
RTW_PRINT("irv:0x%x\n", irv);
1689
1690
if(irv != 0xf)
1691
hal_data->version_id.CUTVersion = irv;
1692
}
1693
#endif
1694
1695
ret = _SUCCESS;
1696
1697
exit:
1698
return ret;
1699
}
1700
1701
int hal_read_mac_hidden_rpt(_adapter *adapter)
1702
{
1703
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
1704
int ret = _FAIL;
1705
int ret_fwdl;
1706
u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
1707
systime start = rtw_get_current_time();
1708
u32 cnt = 0;
1709
u32 timeout_ms = 800;
1710
u32 min_cnt = 10;
1711
u8 id = C2H_DEFEATURE_RSVD;
1712
int i;
1713
1714
#if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1715
u8 hci_type = rtw_get_intf_type(adapter);
1716
1717
if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1718
&& !rtw_is_hw_init_completed(adapter))
1719
rtw_hal_power_on(adapter);
1720
#endif
1721
1722
/* inform FW mac hidden rpt from reg is needed */
1723
rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
1724
1725
/* download FW */
1726
pHalData->not_xmitframe_fw_dl = 1;
1727
ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1728
pHalData->not_xmitframe_fw_dl = 0;
1729
if (ret_fwdl != _SUCCESS)
1730
goto mac_hidden_rpt_hdl;
1731
1732
/* polling for data ready */
1733
start = rtw_get_current_time();
1734
do {
1735
cnt++;
1736
id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1737
if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1738
break;
1739
rtw_msleep_os(10);
1740
} while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1741
1742
if (id == C2H_MAC_HIDDEN_RPT) {
1743
/* read data */
1744
for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
1745
mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1746
}
1747
1748
/* inform FW mac hidden rpt has read */
1749
rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
1750
1751
mac_hidden_rpt_hdl:
1752
c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1753
c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
1754
1755
if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1756
ret = _SUCCESS;
1757
1758
#if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1759
if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1760
&& !rtw_is_hw_init_completed(adapter))
1761
rtw_hal_power_off(adapter);
1762
#endif
1763
1764
RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1765
, (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1766
1767
return ret;
1768
}
1769
#endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
1770
1771
int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
1772
{
1773
int ret = _FAIL;
1774
1775
int i;
1776
1777
if (len < DEFEATURE_DBG_LEN) {
1778
RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
1779
goto exit;
1780
}
1781
1782
for (i = 0; i < len; i++)
1783
RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1784
1785
ret = _SUCCESS;
1786
1787
exit:
1788
return ret;
1789
}
1790
1791
#ifndef DBG_CUSTOMER_STR_RPT_HANDLE
1792
#define DBG_CUSTOMER_STR_RPT_HANDLE 0
1793
#endif
1794
1795
#ifdef CONFIG_RTW_CUSTOMER_STR
1796
s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
1797
{
1798
u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
1799
1800
SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
1801
return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
1802
}
1803
1804
#define C2H_CUSTOMER_STR_RPT_BYTE0(_data) ((u8 *)(_data))
1805
#define C2H_CUSTOMER_STR_RPT_2_BYTE8(_data) ((u8 *)(_data))
1806
1807
int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1808
{
1809
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1810
int ret = _FAIL;
1811
int i;
1812
1813
if (len < CUSTOMER_STR_RPT_LEN) {
1814
RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
1815
goto exit;
1816
}
1817
1818
if (DBG_CUSTOMER_STR_RPT_HANDLE)
1819
RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
1820
1821
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1822
1823
if (dvobj->customer_str_sctx != NULL) {
1824
if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
1825
RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
1826
_rtw_memcpy(dvobj->customer_str, C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
1827
dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
1828
} else
1829
RTW_WARN("%s sctx not set\n", __func__);
1830
1831
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1832
1833
ret = _SUCCESS;
1834
1835
exit:
1836
return ret;
1837
}
1838
1839
int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1840
{
1841
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1842
int ret = _FAIL;
1843
int i;
1844
1845
if (len < CUSTOMER_STR_RPT_2_LEN) {
1846
RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
1847
goto exit;
1848
}
1849
1850
if (DBG_CUSTOMER_STR_RPT_HANDLE)
1851
RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
1852
1853
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1854
1855
if (dvobj->customer_str_sctx != NULL) {
1856
if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
1857
RTW_WARN("%s rpt not ready\n", __func__);
1858
_rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN, C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
1859
rtw_sctx_done(&dvobj->customer_str_sctx);
1860
} else
1861
RTW_WARN("%s sctx not set\n", __func__);
1862
1863
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1864
1865
ret = _SUCCESS;
1866
1867
exit:
1868
return ret;
1869
}
1870
1871
/* read customer str */
1872
s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
1873
{
1874
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1875
struct submit_ctx sctx;
1876
s32 ret = _SUCCESS;
1877
1878
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1879
if (dvobj->customer_str_sctx != NULL)
1880
ret = _FAIL;
1881
else {
1882
rtw_sctx_init(&sctx, 2 * 1000);
1883
dvobj->customer_str_sctx = &sctx;
1884
}
1885
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1886
1887
if (ret == _FAIL) {
1888
RTW_WARN("%s another handle ongoing\n", __func__);
1889
goto exit;
1890
}
1891
1892
ret = rtw_customer_str_req_cmd(adapter);
1893
if (ret != _SUCCESS) {
1894
RTW_WARN("%s read cmd fail\n", __func__);
1895
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1896
dvobj->customer_str_sctx = NULL;
1897
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1898
goto exit;
1899
}
1900
1901
/* wait till rpt done or timeout */
1902
rtw_sctx_wait(&sctx, __func__);
1903
1904
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1905
dvobj->customer_str_sctx = NULL;
1906
if (sctx.status == RTW_SCTX_DONE_SUCCESS)
1907
_rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1908
else
1909
ret = _FAIL;
1910
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1911
1912
exit:
1913
return ret;
1914
}
1915
1916
s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
1917
{
1918
u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
1919
u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
1920
u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
1921
s32 ret;
1922
1923
SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
1924
_rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
1925
1926
SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
1927
_rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
1928
1929
SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
1930
_rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
1931
1932
ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
1933
if (ret != _SUCCESS) {
1934
RTW_WARN("%s w1 fail\n", __func__);
1935
goto exit;
1936
}
1937
1938
ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
1939
if (ret != _SUCCESS) {
1940
RTW_WARN("%s w2 fail\n", __func__);
1941
goto exit;
1942
}
1943
1944
ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
1945
if (ret != _SUCCESS) {
1946
RTW_WARN("%s w3 fail\n", __func__);
1947
goto exit;
1948
}
1949
1950
exit:
1951
return ret;
1952
}
1953
1954
/* write customer str and check if value reported is the same as requested */
1955
s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
1956
{
1957
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1958
struct submit_ctx sctx;
1959
s32 ret = _SUCCESS;
1960
1961
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1962
if (dvobj->customer_str_sctx != NULL)
1963
ret = _FAIL;
1964
else {
1965
rtw_sctx_init(&sctx, 2 * 1000);
1966
dvobj->customer_str_sctx = &sctx;
1967
}
1968
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1969
1970
if (ret == _FAIL) {
1971
RTW_WARN("%s another handle ongoing\n", __func__);
1972
goto exit;
1973
}
1974
1975
ret = rtw_customer_str_write_cmd(adapter, cs);
1976
if (ret != _SUCCESS) {
1977
RTW_WARN("%s write cmd fail\n", __func__);
1978
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1979
dvobj->customer_str_sctx = NULL;
1980
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1981
goto exit;
1982
}
1983
1984
ret = rtw_customer_str_req_cmd(adapter);
1985
if (ret != _SUCCESS) {
1986
RTW_WARN("%s read cmd fail\n", __func__);
1987
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1988
dvobj->customer_str_sctx = NULL;
1989
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1990
goto exit;
1991
}
1992
1993
/* wait till rpt done or timeout */
1994
rtw_sctx_wait(&sctx, __func__);
1995
1996
_enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1997
dvobj->customer_str_sctx = NULL;
1998
if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
1999
if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
2000
RTW_WARN("%s read back check fail\n", __func__);
2001
RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
2002
RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
2003
ret = _FAIL;
2004
}
2005
} else
2006
ret = _FAIL;
2007
_exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2008
2009
exit:
2010
return ret;
2011
}
2012
#endif /* CONFIG_RTW_CUSTOMER_STR */
2013
2014
#ifdef RTW_PER_CMD_SUPPORT_FW
2015
#define H2C_REQ_PER_RPT_LEN 5
2016
#define SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value)
2017
#define SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value)
2018
#define SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(__pH2CCmd, __Value) SET_BITS_TO_LE_4BYTE(__pH2CCmd + 1, 0, 32, __Value)
2019
2020
u8 rtw_hal_set_req_per_rpt_cmd(_adapter *adapter, u8 group_macid,
2021
u8 rpt_type, u32 macid_bitmap)
2022
{
2023
u8 ret = _FAIL;
2024
u8 cmd_buf[H2C_REQ_PER_RPT_LEN] = {0};
2025
2026
SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(cmd_buf, group_macid);
2027
SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(cmd_buf, rpt_type);
2028
SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(cmd_buf, macid_bitmap);
2029
2030
ret = rtw_hal_fill_h2c_cmd(adapter,
2031
H2C_REQ_PER_RPT,
2032
H2C_REQ_PER_RPT_LEN,
2033
cmd_buf);
2034
return ret;
2035
}
2036
2037
#define GET_C2H_PER_RATE_RPT_TYPE0_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2038
#define GET_C2H_PER_RATE_RPT_TYPE0_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2039
#define GET_C2H_PER_RATE_RPT_TYPE0_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
2040
#define GET_C2H_PER_RATE_RPT_TYPE0_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
2041
#define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 4, 0, 16)
2042
#define GET_C2H_PER_RATE_RPT_TYPE0_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
2043
#define GET_C2H_PER_RATE_RPT_TYPE0_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 8)
2044
#define GET_C2H_PER_RATE_RPT_TYPE0_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
2045
#define GET_C2H_PER_RATE_RPT_TYPE0_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 2)
2046
#define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 10, 0, 16)
2047
2048
#define GET_C2H_PER_RATE_RPT_TYPE1_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2049
#define GET_C2H_PER_RATE_RPT_TYPE1_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2050
#define GET_C2H_PER_RATE_RPT_TYPE1_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
2051
#define GET_C2H_PER_RATE_RPT_TYPE1_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
2052
#define GET_C2H_PER_RATE_RPT_TYPE1_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 8)
2053
#define GET_C2H_PER_RATE_RPT_TYPE1_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 8)
2054
#define GET_C2H_PER_RATE_RPT_TYPE1_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
2055
#define GET_C2H_PER_RATE_RPT_TYPE1_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 2)
2056
#define GET_C2H_PER_RATE_RPT_TYPE1_MACID2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
2057
#define GET_C2H_PER_RATE_RPT_TYPE1_PER2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 8)
2058
#define GET_C2H_PER_RATE_RPT_TYPE1_RATE2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 10, 0, 8)
2059
#define GET_C2H_PER_RATE_RPT_TYPE1_BW2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 11, 0, 2)
2060
2061
static void per_rate_rpt_update(_adapter *adapter, u8 mac_id,
2062
u8 per, u8 rate,
2063
u8 bw, u8 total_pkt)
2064
{
2065
#ifdef CONFIG_RTW_MESH
2066
rtw_ieee80211s_update_metric(adapter, mac_id,
2067
per, rate,
2068
bw, total_pkt);
2069
#endif
2070
}
2071
2072
int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
2073
{
2074
/* Now only consider type0, since it covers all params in type1
2075
* type0: mac_id, per, rate, bw, total_pkt
2076
* type1: mac_id, per, rate, bw
2077
*/
2078
u8 mac_id[2] = {0}, per[2] = {0}, rate[2] = {0}, bw[2] = {0};
2079
u16 total_pkt[2] = {0};
2080
int ret = _FAIL, i, macid_cnt = 0;
2081
2082
/* type0:
2083
* 1 macid includes 6 bytes info + 1 byte 0xff
2084
* 2 macid includes 2*6 bytes info
2085
*/
2086
if (!(len == 7 || len == 12)) {
2087
RTW_WARN("%s len(%u) != 7 or 12\n", __FUNCTION__, len);
2088
goto exit;
2089
}
2090
2091
macid_cnt++;
2092
mac_id[0] = GET_C2H_PER_RATE_RPT_TYPE0_MACID0(data);
2093
per[0] = GET_C2H_PER_RATE_RPT_TYPE0_PER0(data);
2094
rate[0] = GET_C2H_PER_RATE_RPT_TYPE0_RATE0(data);
2095
bw[0] = GET_C2H_PER_RATE_RPT_TYPE0_BW0(data);
2096
total_pkt[0] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(data);
2097
2098
mac_id[1] = GET_C2H_PER_RATE_RPT_TYPE0_MACID1(data);
2099
/* 0xff means no report anymore */
2100
if (mac_id[1] == 0xff)
2101
goto update_per;
2102
if (len != 12) {
2103
RTW_WARN("%s incorrect format\n", __FUNCTION__);
2104
goto exit;
2105
}
2106
macid_cnt++;
2107
per[1] = GET_C2H_PER_RATE_RPT_TYPE0_PER1(data);
2108
rate[1] = GET_C2H_PER_RATE_RPT_TYPE0_RATE1(data);
2109
bw[1] = GET_C2H_PER_RATE_RPT_TYPE0_BW1(data);
2110
total_pkt[1] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(data);
2111
2112
update_per:
2113
for (i = 0; i < macid_cnt; i++) {
2114
RTW_DBG("[%s] type0 rpt[%d]: macid = %u, per = %u, "
2115
"rate = %u, bw = %u, total_pkt = %u\n",
2116
__FUNCTION__, i, mac_id[i], per[i],
2117
rate[i], bw[i], total_pkt[i]);
2118
per_rate_rpt_update(adapter, mac_id[i],
2119
per[i], rate[i],
2120
bw[i], total_pkt[i]);
2121
}
2122
ret = _SUCCESS;
2123
exit:
2124
return ret;
2125
}
2126
#endif /* RTW_PER_CMD_SUPPORT_FW */
2127
2128
#ifdef CONFIG_LPS_ACK
2129
#define GET_C2H_LPS_STATUS_RPT_GET_ACTION(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2130
#define GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2131
#define DBG_LPS_STATUS_RPT 0
2132
2133
int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len)
2134
{
2135
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
2136
struct submit_ctx *lps_sctx = &pwrpriv->lps_ack_sctx;
2137
u8 action = 0;
2138
s8 status_code = 0;
2139
int ret = _FAIL;
2140
2141
if (len < LPS_STATUS_RPT_LEN) {
2142
RTW_WARN("%s len(%u) < %d\n", __func__, len, LPS_STATUS_RPT_LEN);
2143
goto exit;
2144
}
2145
2146
action = GET_C2H_LPS_STATUS_RPT_GET_ACTION(data);
2147
status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data);
2148
2149
/* action=0: report force leave null data status */
2150
switch (action) {
2151
case 0:
2152
pwrpriv->lps_ack_status = status_code;
2153
2154
if (DBG_LPS_STATUS_RPT)
2155
RTW_INFO("=== [C2H LPS Action(%d)] LPS Status Code:%d ===\n", action, status_code);
2156
2157
break;
2158
default:
2159
RTW_INFO("UnKnown Action(%d) for C2H LPS RPT\n", action);
2160
break;
2161
}
2162
2163
rtw_sctx_done(&lps_sctx);
2164
ret = _SUCCESS;
2165
2166
exit:
2167
return ret;
2168
}
2169
#endif /* CONFIG_LPS_ACK */
2170
2171
void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
2172
{
2173
u8 w_set = 0;
2174
2175
if (psta->wireless_mode & WIRELESS_11B)
2176
w_set |= WIRELESS_CCK;
2177
2178
if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
2179
w_set |= WIRELESS_OFDM;
2180
2181
if (psta->wireless_mode & WIRELESS_11_24N)
2182
w_set |= WIRELESS_HT;
2183
2184
if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N))
2185
w_set |= WIRELESS_VHT;
2186
2187
psta->cmn.support_wireless_set = w_set;
2188
}
2189
2190
void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
2191
{
2192
s8 tx_nss, rx_nss;
2193
2194
tx_nss = rtw_get_sta_tx_nss(adapter, psta);
2195
rx_nss = rtw_get_sta_rx_nss(adapter, psta);
2196
if ((tx_nss == 1) && (rx_nss == 1))
2197
psta->cmn.mimo_type = RF_1T1R;
2198
else if ((tx_nss == 1) && (rx_nss == 2))
2199
psta->cmn.mimo_type = RF_1T2R;
2200
else if ((tx_nss == 2) && (rx_nss == 2))
2201
psta->cmn.mimo_type = RF_2T2R;
2202
else if ((tx_nss == 2) && (rx_nss == 3))
2203
psta->cmn.mimo_type = RF_2T3R;
2204
else if ((tx_nss == 2) && (rx_nss == 4))
2205
psta->cmn.mimo_type = RF_2T4R;
2206
else if ((tx_nss == 3) && (rx_nss == 3))
2207
psta->cmn.mimo_type = RF_3T3R;
2208
else if ((tx_nss == 3) && (rx_nss == 4))
2209
psta->cmn.mimo_type = RF_3T4R;
2210
else if ((tx_nss == 4) && (rx_nss == 4))
2211
psta->cmn.mimo_type = RF_4T4R;
2212
else
2213
rtw_warn_on(1);
2214
2215
#ifdef CONFIG_CTRL_TXSS_BY_TP
2216
rtw_ctrl_txss_update_mimo_type(adapter, psta);
2217
#endif
2218
2219
RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
2220
psta->cmn.mac_id, tx_nss, rx_nss);
2221
}
2222
2223
void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
2224
{
2225
/*Spatial Multiplexing Power Save*/
2226
#if 0
2227
if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2228
#ifdef CONFIG_80211N_HT
2229
if (psta->htpriv.ht_option) {
2230
if (psta->htpriv.smps_cap == 0)
2231
psta->cmn.sm_ps = SM_PS_STATIC;
2232
else if (psta->htpriv.smps_cap == 1)
2233
psta->cmn.sm_ps = SM_PS_DYNAMIC;
2234
else
2235
psta->cmn.sm_ps = SM_PS_DISABLE;
2236
}
2237
#endif /* CONFIG_80211N_HT */
2238
} else
2239
#endif
2240
psta->cmn.sm_ps = SM_PS_DISABLE;
2241
2242
RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
2243
psta->cmn.mac_id, psta->cmn.sm_ps);
2244
}
2245
2246
u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
2247
{
2248
2249
u8 raid;
2250
if (IS_NEW_GENERATION_IC(adapter)) {
2251
2252
raid = (network_type & WIRELESS_11B) ? RATEID_IDX_B
2253
: RATEID_IDX_G;
2254
} else {
2255
raid = (network_type & WIRELESS_11B) ? RATR_INX_WIRELESS_B
2256
: RATR_INX_WIRELESS_G;
2257
}
2258
return raid;
2259
}
2260
2261
void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
2262
{
2263
u8 i, tx_nss;
2264
u64 tx_ra_bitmap = 0, tmp64=0;
2265
2266
if (psta == NULL)
2267
return;
2268
2269
/* b/g mode ra_bitmap */
2270
for (i = 0; i < sizeof(psta->bssrateset); i++) {
2271
if (psta->bssrateset[i])
2272
tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
2273
}
2274
2275
#ifdef CONFIG_80211N_HT
2276
if (padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
2277
tx_nss = GET_HAL_TX_NSS(padapter);
2278
#ifdef CONFIG_80211AC_VHT
2279
if (psta->vhtpriv.vht_option) {
2280
/* AC mode ra_bitmap */
2281
tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
2282
} else
2283
#endif /* CONFIG_80211AC_VHT */
2284
if (psta->htpriv.ht_option) {
2285
/* n mode ra_bitmap */
2286
2287
/* Handling SMPS mode for AP MODE only*/
2288
if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2289
/*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
2290
if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
2291
/*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
2292
tx_nss = rtw_min(tx_nss, 1);
2293
}
2294
}
2295
2296
tmp64 = rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss);
2297
tx_ra_bitmap |= (tmp64 << 12);
2298
}
2299
}
2300
#endif /* CONFIG_80211N_HT */
2301
psta->cmn.ra_info.ramask = tx_ra_bitmap;
2302
psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
2303
}
2304
2305
void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
2306
{
2307
rtw_hal_update_sta_mimo_type(padapter, psta);
2308
rtw_hal_update_sta_smps_cap(padapter, psta);
2309
rtw_hal_update_sta_rate_mask(padapter, psta);
2310
}
2311
2312
#ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
2313
static u32 hw_bcn_ctrl_addr(_adapter *adapter, u8 hw_port)
2314
{
2315
struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2316
2317
if (hw_port >= hal_spec->port_num) {
2318
RTW_ERR(FUNC_ADPT_FMT" HW Port(%d) invalid\n", FUNC_ADPT_ARG(adapter), hw_port);
2319
rtw_warn_on(1);
2320
return 0;
2321
}
2322
2323
switch (hw_port) {
2324
case HW_PORT0:
2325
return REG_BCN_CTRL;
2326
case HW_PORT1:
2327
return REG_BCN_CTRL_1;
2328
}
2329
2330
return 0;
2331
}
2332
#endif
2333
2334
static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2335
{
2336
#ifdef RTW_HALMAC
2337
rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
2338
adapter->hw_port, net_type);
2339
#else /* !RTW_HALMAC */
2340
switch (adapter->hw_port) {
2341
case HW_PORT0:
2342
/*REG_CR - BIT[17:16]-Network Type for port 1*/
2343
*net_type = rtw_read8(adapter, MSR) & 0x03;
2344
break;
2345
case HW_PORT1:
2346
/*REG_CR - BIT[19:18]-Network Type for port 1*/
2347
*net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2348
break;
2349
#if defined(CONFIG_RTL8814A)
2350
case HW_PORT2:
2351
/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2352
*net_type = rtw_read8(adapter, MSR1) & 0x03;
2353
break;
2354
case HW_PORT3:
2355
/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2356
*net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2357
break;
2358
case HW_PORT4:
2359
/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2360
*net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2361
break;
2362
#endif /*#if defined(CONFIG_RTL8814A)*/
2363
default:
2364
RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2365
ADPT_ARG(adapter), adapter->hw_port);
2366
rtw_warn_on(1);
2367
break;
2368
}
2369
#endif /* !RTW_HALMAC */
2370
}
2371
2372
#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/
2373
static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
2374
{
2375
if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
2376
if (net_type != _HW_STATE_NOLINK_)
2377
return _HW_STATE_AP_;
2378
}
2379
return net_type;
2380
}
2381
#endif
2382
static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2383
{
2384
#ifdef RTW_HALMAC
2385
#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2386
net_type = rtw_hal_net_type_decision(adapter, net_type);
2387
#endif
2388
rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
2389
adapter->hw_port, net_type);
2390
#else /* !RTW_HALMAC */
2391
u8 val8 = 0;
2392
2393
switch (adapter->hw_port) {
2394
case HW_PORT0:
2395
#if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2396
net_type = rtw_hal_net_type_decision(adapter, net_type);
2397
#endif
2398
/*REG_CR - BIT[17:16]-Network Type for port 0*/
2399
val8 = rtw_read8(adapter, MSR) & 0x0C;
2400
val8 |= net_type;
2401
rtw_write8(adapter, MSR, val8);
2402
break;
2403
case HW_PORT1:
2404
/*REG_CR - BIT[19:18]-Network Type for port 1*/
2405
val8 = rtw_read8(adapter, MSR) & 0x03;
2406
val8 |= net_type << 2;
2407
rtw_write8(adapter, MSR, val8);
2408
break;
2409
#if defined(CONFIG_RTL8814A)
2410
case HW_PORT2:
2411
/*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2412
val8 = rtw_read8(adapter, MSR1) & 0xFC;
2413
val8 |= net_type;
2414
rtw_write8(adapter, MSR1, val8);
2415
break;
2416
case HW_PORT3:
2417
/*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2418
val8 = rtw_read8(adapter, MSR1) & 0xF3;
2419
val8 |= net_type << 2;
2420
rtw_write8(adapter, MSR1, val8);
2421
break;
2422
case HW_PORT4:
2423
/*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2424
val8 = rtw_read8(adapter, MSR1) & 0xCF;
2425
val8 |= net_type << 4;
2426
rtw_write8(adapter, MSR1, val8);
2427
break;
2428
#endif /* CONFIG_RTL8814A */
2429
default:
2430
RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2431
ADPT_ARG(adapter), adapter->hw_port);
2432
rtw_warn_on(1);
2433
break;
2434
}
2435
#endif /* !RTW_HALMAC */
2436
}
2437
2438
#ifndef SEC_CAM_ACCESS_TIMEOUT_MS
2439
#define SEC_CAM_ACCESS_TIMEOUT_MS 200
2440
#endif
2441
2442
#ifndef DBG_SEC_CAM_ACCESS
2443
#define DBG_SEC_CAM_ACCESS 0
2444
#endif
2445
2446
u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
2447
{
2448
_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2449
u32 rdata;
2450
u32 cnt = 0;
2451
systime start = 0, end = 0;
2452
u8 timeout = 0;
2453
u8 sr = 0;
2454
2455
_enter_critical_mutex(mutex, NULL);
2456
2457
rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
2458
2459
start = rtw_get_current_time();
2460
while (1) {
2461
if (rtw_is_surprise_removed(adapter)) {
2462
sr = 1;
2463
break;
2464
}
2465
2466
cnt++;
2467
if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2468
break;
2469
2470
if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2471
timeout = 1;
2472
break;
2473
}
2474
}
2475
end = rtw_get_current_time();
2476
2477
rdata = rtw_read32(adapter, REG_CAMREAD);
2478
2479
_exit_critical_mutex(mutex, NULL);
2480
2481
if (DBG_SEC_CAM_ACCESS || timeout) {
2482
RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
2483
, FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2484
}
2485
2486
return rdata;
2487
}
2488
2489
void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
2490
{
2491
_mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2492
u32 cnt = 0;
2493
systime start = 0, end = 0;
2494
u8 timeout = 0;
2495
u8 sr = 0;
2496
2497
_enter_critical_mutex(mutex, NULL);
2498
2499
rtw_write32(adapter, REG_CAMWRITE, wdata);
2500
rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
2501
2502
start = rtw_get_current_time();
2503
while (1) {
2504
if (rtw_is_surprise_removed(adapter)) {
2505
sr = 1;
2506
break;
2507
}
2508
2509
cnt++;
2510
if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2511
break;
2512
2513
if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2514
timeout = 1;
2515
break;
2516
}
2517
}
2518
end = rtw_get_current_time();
2519
2520
_exit_critical_mutex(mutex, NULL);
2521
2522
if (DBG_SEC_CAM_ACCESS || timeout) {
2523
RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
2524
, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2525
}
2526
}
2527
2528
void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
2529
{
2530
u8 i;
2531
u32 rdata;
2532
u8 begin = 0;
2533
u8 end = 5; /* TODO: consider other key length accordingly */
2534
2535
if (!ctrl && !mac && !key) {
2536
rtw_warn_on(1);
2537
goto exit;
2538
}
2539
2540
/* TODO: check id range */
2541
2542
if (!ctrl && !mac)
2543
begin = 2; /* read from key */
2544
2545
if (!key && !mac)
2546
end = 0; /* read to ctrl */
2547
else if (!key)
2548
end = 2; /* read to mac */
2549
2550
for (i = begin; i <= end; i++) {
2551
rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
2552
2553
switch (i) {
2554
case 0:
2555
if (ctrl)
2556
_rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
2557
if (mac)
2558
_rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
2559
break;
2560
case 1:
2561
if (mac)
2562
_rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
2563
break;
2564
default:
2565
if (key)
2566
_rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
2567
break;
2568
}
2569
}
2570
2571
exit:
2572
return;
2573
}
2574
2575
2576
void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
2577
{
2578
unsigned int i;
2579
int j;
2580
u8 addr, addr1 = 0;
2581
u32 wdata, wdata1 = 0;
2582
2583
/* TODO: consider other key length accordingly */
2584
#if 0
2585
switch ((ctrl & 0x1c) >> 2) {
2586
case _WEP40_:
2587
case _TKIP_:
2588
case _AES_:
2589
case _WEP104_:
2590
2591
}
2592
#else
2593
j = 7;
2594
#endif
2595
2596
for (; j >= 0; j--) {
2597
switch (j) {
2598
case 0:
2599
wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
2600
break;
2601
case 1:
2602
wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
2603
break;
2604
case 6:
2605
case 7:
2606
wdata = 0;
2607
break;
2608
default:
2609
i = (j - 2) << 2;
2610
wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
2611
break;
2612
}
2613
2614
addr = (id << 3) + j;
2615
2616
#if defined(CONFIG_RTL8192F)
2617
if(j == 1) {
2618
wdata1 = wdata;
2619
addr1 = addr;
2620
continue;
2621
}
2622
#endif
2623
2624
rtw_sec_write_cam(adapter, addr, wdata);
2625
}
2626
2627
#if defined(CONFIG_RTL8192F)
2628
rtw_sec_write_cam(adapter, addr1, wdata1);
2629
#endif
2630
}
2631
2632
void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
2633
{
2634
u8 addr;
2635
2636
addr = (id << 3);
2637
rtw_sec_write_cam(adapter, addr, 0);
2638
}
2639
2640
bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
2641
{
2642
bool res;
2643
u16 ctrl;
2644
2645
rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
2646
2647
res = (ctrl & BIT6) ? _TRUE : _FALSE;
2648
return res;
2649
}
2650
#ifdef CONFIG_MBSSID_CAM
2651
void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
2652
{
2653
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2654
2655
_rtw_spinlock_init(&mbid_cam_ctl->lock);
2656
mbid_cam_ctl->bitmap = 0;
2657
ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2658
_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2659
}
2660
2661
void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
2662
{
2663
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2664
2665
_rtw_spinlock_free(&mbid_cam_ctl->lock);
2666
}
2667
2668
void rtw_mbid_cam_reset(_adapter *adapter)
2669
{
2670
_irqL irqL;
2671
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2672
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2673
2674
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2675
mbid_cam_ctl->bitmap = 0;
2676
_rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2677
_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2678
2679
ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2680
}
2681
static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2682
{
2683
u8 i;
2684
u8 cam_id = INVALID_CAM_ID;
2685
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2686
2687
for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2688
if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
2689
cam_id = i;
2690
break;
2691
}
2692
}
2693
2694
RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2695
return cam_id;
2696
}
2697
2698
u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2699
{
2700
_irqL irqL;
2701
2702
u8 cam_id = INVALID_CAM_ID;
2703
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2704
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2705
2706
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2707
cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
2708
_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2709
2710
return cam_id;
2711
}
2712
static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2713
{
2714
u8 i;
2715
u8 cam_id = INVALID_CAM_ID;
2716
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2717
2718
for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2719
if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
2720
cam_id = i;
2721
break;
2722
}
2723
}
2724
if (cam_id != INVALID_CAM_ID)
2725
RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
2726
__func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
2727
2728
return cam_id;
2729
}
2730
2731
u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2732
{
2733
_irqL irqL;
2734
u8 cam_id = INVALID_CAM_ID;
2735
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2736
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2737
2738
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2739
cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
2740
_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2741
2742
return cam_id;
2743
}
2744
u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
2745
{
2746
_irqL irqL;
2747
s8 i;
2748
u8 cam_id = INVALID_CAM_ID;
2749
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2750
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2751
2752
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2753
for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
2754
if (mbid_cam_ctl->bitmap & BIT(i)) {
2755
cam_id = i;
2756
break;
2757
}
2758
}
2759
_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2760
/*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
2761
return cam_id;
2762
}
2763
2764
inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
2765
{
2766
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2767
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2768
2769
return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2770
}
2771
2772
static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
2773
{
2774
if (adapter && pmbid_cam && mac_addr) {
2775
_rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
2776
pmbid_cam->iface_id = adapter->iface_id;
2777
}
2778
}
2779
static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
2780
{
2781
if (pmbid_cam) {
2782
_rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
2783
pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
2784
}
2785
}
2786
2787
u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
2788
{
2789
_irqL irqL;
2790
u8 cam_id = INVALID_CAM_ID, i;
2791
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2792
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2793
u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2794
2795
if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2796
goto exit;
2797
2798
if (entry_num >= TOTAL_MBID_CAM_NUM) {
2799
RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
2800
rtw_warn_on(1);
2801
}
2802
2803
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2804
for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2805
if (!(mbid_cam_ctl->bitmap & BIT(i))) {
2806
mbid_cam_ctl->bitmap |= BIT(i);
2807
cam_id = i;
2808
break;
2809
}
2810
}
2811
if ((cam_id != INVALID_CAM_ID) && (mac_addr))
2812
mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
2813
_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2814
2815
if (cam_id != INVALID_CAM_ID) {
2816
ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2817
RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2818
#ifdef DBG_MBID_CAM_DUMP
2819
rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2820
#endif
2821
} else
2822
RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2823
exit:
2824
return cam_id;
2825
}
2826
2827
u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
2828
{
2829
_irqL irqL;
2830
u8 entry_id = INVALID_CAM_ID;
2831
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2832
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2833
2834
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2835
entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
2836
if (entry_id != INVALID_CAM_ID)
2837
mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
2838
2839
_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2840
2841
return entry_id;
2842
}
2843
2844
u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
2845
{
2846
_irqL irqL;
2847
u8 ret = _FALSE;
2848
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2849
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2850
2851
if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
2852
RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
2853
rtw_warn_on(1);
2854
}
2855
if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2856
goto exit;
2857
2858
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2859
if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
2860
if (mac_addr) {
2861
mbid_cam_ctl->bitmap |= BIT(camid);
2862
mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
2863
ret = _TRUE;
2864
}
2865
}
2866
_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2867
2868
if (ret == _TRUE) {
2869
ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2870
RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
2871
#ifdef DBG_MBID_CAM_DUMP
2872
rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2873
#endif
2874
} else
2875
RTW_INFO("%s [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
2876
2877
exit:
2878
return ret;
2879
}
2880
2881
void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
2882
{
2883
_irqL irqL;
2884
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2885
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2886
2887
if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
2888
RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
2889
rtw_warn_on(1);
2890
}
2891
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2892
mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
2893
mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
2894
_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2895
ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
2896
RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
2897
}
2898
int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
2899
{
2900
_irqL irqL;
2901
u8 i;
2902
_adapter *iface;
2903
u8 iface_id;
2904
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2905
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2906
u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2907
u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2908
2909
RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
2910
2911
_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2912
RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
2913
for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2914
RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2915
2916
if (mbid_cam_ctl->bitmap & BIT(i)) {
2917
iface_id = dvobj->mbid_cam_cache[i].iface_id;
2918
_RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
2919
_RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2920
2921
iface = dvobj->padapters[iface_id];
2922
if (iface) {
2923
if (MLME_IS_STA(iface))
2924
_RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
2925
else if (MLME_IS_AP(iface))
2926
_RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
2927
else if (MLME_IS_MESH(iface))
2928
_RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");
2929
else
2930
_RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2931
}
2932
2933
} else
2934
_RTW_PRINT_SEL(sel, "N/A\n");
2935
}
2936
_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2937
return 0;
2938
}
2939
2940
static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2941
{
2942
u8 poll = 1;
2943
u8 cam_ready = _FALSE;
2944
u32 cam_data1 = 0;
2945
u16 cam_data2 = 0;
2946
2947
if (RTW_CANNOT_RUN(padapter))
2948
return;
2949
2950
rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2951
2952
do {
2953
if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2954
cam_ready = _TRUE;
2955
break;
2956
}
2957
poll++;
2958
} while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2959
2960
if (cam_ready) {
2961
cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2962
mac[0] = cam_data1 & 0xFF;
2963
mac[1] = (cam_data1 >> 8) & 0xFF;
2964
mac[2] = (cam_data1 >> 16) & 0xFF;
2965
mac[3] = (cam_data1 >> 24) & 0xFF;
2966
2967
cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
2968
mac[4] = cam_data2 & 0xFF;
2969
mac[5] = (cam_data2 >> 8) & 0xFF;
2970
}
2971
2972
}
2973
int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
2974
{
2975
/*_irqL irqL;*/
2976
u8 i;
2977
u8 mac_addr[ETH_ALEN];
2978
2979
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2980
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2981
2982
RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
2983
2984
/*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2985
for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2986
RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2987
_rtw_memset(mac_addr, 0, ETH_ALEN);
2988
read_mbssid_cam(adapter, i, mac_addr);
2989
_RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
2990
}
2991
/*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2992
return 0;
2993
}
2994
2995
static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2996
{
2997
u32 cam_val[2] = {0};
2998
2999
cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
3000
cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT) | (mac[5] << 8) | mac[4];
3001
3002
rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
3003
}
3004
3005
/*
3006
static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
3007
{
3008
rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
3009
}
3010
*/
3011
3012
void rtw_ap_set_mbid_num(_adapter *adapter, u8 ap_num)
3013
{
3014
rtw_write8(adapter, REG_MBID_NUM,
3015
((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | ((ap_num -1) & 0x07)));
3016
3017
}
3018
void rtw_mbid_cam_enable(_adapter *adapter)
3019
{
3020
/*enable MBSSID*/
3021
rtw_hal_rcr_add(adapter, RCR_ENMBID);
3022
}
3023
void rtw_mi_set_mbid_cam(_adapter *adapter)
3024
{
3025
u8 i;
3026
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3027
struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
3028
3029
#ifdef DBG_MBID_CAM_DUMP
3030
rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
3031
#endif
3032
3033
for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
3034
if (mbid_cam_ctl->bitmap & BIT(i)) {
3035
write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
3036
RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
3037
}
3038
}
3039
rtw_mbid_cam_enable(adapter);
3040
}
3041
#endif /*CONFIG_MBSSID_CAM*/
3042
3043
#ifdef CONFIG_FW_HANDLE_TXBCN
3044
#define H2C_BCN_OFFLOAD_LEN 1
3045
3046
#define SET_H2CCMD_BCN_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
3047
#define SET_H2CCMD_BCN_ROOT_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
3048
#define SET_H2CCMD_BCN_VAP1_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)
3049
#define SET_H2CCMD_BCN_VAP2_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)
3050
#define SET_H2CCMD_BCN_VAP3_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value)
3051
#define SET_H2CCMD_BCN_VAP4_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value)
3052
3053
void rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter *adapter, bool fw_bcn_en, u8 tbtt_rpt_map)
3054
{
3055
u8 fw_bcn_offload[1] = {0};
3056
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3057
3058
if (fw_bcn_en)
3059
SET_H2CCMD_BCN_OFFLOAD_EN(fw_bcn_offload, 1);
3060
3061
if (tbtt_rpt_map & BIT(0))
3062
SET_H2CCMD_BCN_ROOT_TBTT_RPT(fw_bcn_offload, 1);
3063
if (tbtt_rpt_map & BIT(1))
3064
SET_H2CCMD_BCN_VAP1_TBTT_RPT(fw_bcn_offload, 1);
3065
if (tbtt_rpt_map & BIT(2))
3066
SET_H2CCMD_BCN_VAP2_TBTT_RPT(fw_bcn_offload, 1);
3067
if (tbtt_rpt_map & BIT(3))
3068
SET_H2CCMD_BCN_VAP3_TBTT_RPT(fw_bcn_offload, 1);
3069
3070
dvobj->vap_tbtt_rpt_map = tbtt_rpt_map;
3071
dvobj->fw_bcn_offload = fw_bcn_en;
3072
RTW_INFO("[FW BCN] Offload : %s\n", (dvobj->fw_bcn_offload) ? "EN" : "DIS");
3073
RTW_INFO("[FW BCN] TBTT RPT map : 0x%02x\n", dvobj->vap_tbtt_rpt_map);
3074
3075
rtw_hal_fill_h2c_cmd(adapter, H2C_FW_BCN_OFFLOAD,
3076
H2C_BCN_OFFLOAD_LEN, fw_bcn_offload);
3077
}
3078
3079
void rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter *adapter)
3080
{
3081
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3082
u8 ret, vap_id;
3083
u32 page_size = 0;
3084
u8 bcn_rsvdpage[H2C_BCN_RSVDPAGE_LEN] = {0};
3085
3086
rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
3087
#if 1
3088
for (vap_id = 0; vap_id < CONFIG_LIMITED_AP_NUM; vap_id++) {
3089
if (dvobj->vap_map & BIT(vap_id))
3090
bcn_rsvdpage[vap_id] = vap_id * (MAX_BEACON_LEN / page_size);
3091
}
3092
#else
3093
#define SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)
3094
#define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 8, __Value)
3095
#define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 8, __Value)
3096
#define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 8, __Value)
3097
#define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 8, __Value)
3098
3099
if (dvobj->vap_map & BIT(0))
3100
SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(bcn_rsvdpage, 0);
3101
if (dvobj->vap_map & BIT(1))
3102
SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(bcn_rsvdpage,
3103
1 * (MAX_BEACON_LEN / page_size));
3104
if (dvobj->vap_map & BIT(2))
3105
SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(bcn_rsvdpage,
3106
2 * (MAX_BEACON_LEN / page_size));
3107
if (dvobj->vap_map & BIT(3))
3108
SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(bcn_rsvdpage,
3109
3 * (MAX_BEACON_LEN / page_size));
3110
if (dvobj->vap_map & BIT(4))
3111
SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(bcn_rsvdpage,
3112
4 * (MAX_BEACON_LEN / page_size));
3113
#endif
3114
if (1) {
3115
RTW_INFO("[BCN_LOC] vap_map : 0x%02x\n", dvobj->vap_map);
3116
RTW_INFO("[BCN_LOC] page_size :%d, @bcn_page_num :%d\n"
3117
, page_size, (MAX_BEACON_LEN / page_size));
3118
RTW_INFO("[BCN_LOC] root ap : 0x%02x\n", *bcn_rsvdpage);
3119
RTW_INFO("[BCN_LOC] vap_1 : 0x%02x\n", *(bcn_rsvdpage + 1));
3120
RTW_INFO("[BCN_LOC] vap_2 : 0x%02x\n", *(bcn_rsvdpage + 2));
3121
RTW_INFO("[BCN_LOC] vap_3 : 0x%02x\n", *(bcn_rsvdpage + 3));
3122
RTW_INFO("[BCN_LOC] vap_4 : 0x%02x\n", *(bcn_rsvdpage + 4));
3123
}
3124
ret = rtw_hal_fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE,
3125
H2C_BCN_RSVDPAGE_LEN, bcn_rsvdpage);
3126
}
3127
3128
void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3129
{
3130
u8 dft_bcn_space = DEFAULT_BCN_INTERVAL;
3131
u8 sub_bcn_space = (DEFAULT_BCN_INTERVAL / CONFIG_LIMITED_AP_NUM);
3132
3133
/*enable to rx data frame*/
3134
rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3135
3136
/*Disable Port0's beacon function*/
3137
rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
3138
/*Reset Port0's TSF*/
3139
rtw_write8(adapter, REG_DUAL_TSF_RST, BIT_TSFTR_RST);
3140
3141
rtw_ap_set_mbid_num(adapter, CONFIG_LIMITED_AP_NUM);
3142
3143
/*BCN space & BCN sub-space 0x554[15:0] = 0x64,0x5BC[23:16] = 0x21*/
3144
rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), HW_PORT0, dft_bcn_space);
3145
rtw_write8(adapter, REG_MBSSID_BCN_SPACE3 + 2, sub_bcn_space);
3146
3147
#if 0 /*setting in hw_var_set_opmode_mbid - ResumeTxBeacon*/
3148
/*BCN hold time 0x540[19:8] = 0x80*/
3149
rtw_write8(adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
3150
rtw_write8(adapter, REG_TBTT_PROHIBIT + 2,
3151
(rtw_read8(adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
3152
#endif
3153
3154
/*ATIM window -0x55A = 0x32, reg 0x570 = 0x32, reg 0x5A0 = 0x32 */
3155
rtw_write8(adapter, REG_ATIMWND, 0x32);
3156
rtw_write8(adapter, REG_ATIMWND1_V1, 0x32);
3157
rtw_write8(adapter, REG_ATIMWND2, 0x32);
3158
rtw_write8(adapter, REG_ATIMWND3, 0x32);
3159
/*
3160
rtw_write8(adapter, REG_ATIMWND4, 0x32);
3161
rtw_write8(adapter, REG_ATIMWND5, 0x32);
3162
rtw_write8(adapter, REG_ATIMWND6, 0x32);
3163
rtw_write8(adapter, REG_ATIMWND7, 0x32);*/
3164
3165
/*no limit setting - 0x5A7 = 0xFF - Packet in Hi Queue Tx immediately*/
3166
rtw_write8(adapter, REG_HIQ_NO_LMT_EN, 0xFF);
3167
3168
/*Mask all beacon*/
3169
rtw_write8(adapter, REG_MBSSID_CTRL, 0);
3170
3171
/*BCN invalid bit setting 0x454[6] = 1*/
3172
/*rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);*/
3173
3174
/*Enable Port0's beacon function*/
3175
rtw_write8(adapter, REG_BCN_CTRL,
3176
rtw_read8(adapter, REG_BCN_CTRL) | BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION);
3177
3178
/* Enable HW seq for BCN
3179
* 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
3180
#ifdef CONFIG_RTL8822B
3181
if (IS_HARDWARE_TYPE_8822B(adapter))
3182
rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3183
#endif
3184
3185
#ifdef CONFIG_RTL8822C
3186
if (IS_HARDWARE_TYPE_8822C(adapter))
3187
rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3188
#endif
3189
}
3190
static void _rtw_mbid_bcn_cfg(_adapter *adapter, bool mbcnq_en, u8 mbcnq_id)
3191
{
3192
if (mbcnq_id >= CONFIG_LIMITED_AP_NUM) {
3193
RTW_ERR(FUNC_ADPT_FMT"- mbid bcnq_id(%d) invalid\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3194
rtw_warn_on(1);
3195
}
3196
3197
if (mbcnq_en) {
3198
rtw_write8(adapter, REG_MBSSID_CTRL,
3199
rtw_read8(adapter, REG_MBSSID_CTRL) | BIT(mbcnq_id));
3200
RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) enabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3201
} else {
3202
rtw_write8(adapter, REG_MBSSID_CTRL,
3203
rtw_read8(adapter, REG_MBSSID_CTRL) & (~BIT(mbcnq_id)));
3204
RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) disabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3205
}
3206
}
3207
/*#define CONFIG_FW_TBTT_RPT*/
3208
void rtw_ap_mbid_bcn_en(_adapter *adapter, u8 ap_id)
3209
{
3210
RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3211
3212
#ifdef CONFIG_FW_TBTT_RPT
3213
if (rtw_ap_get_nums(adapter) >= 1) {
3214
u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3215
3216
rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3217
tbtt_rpt_map | BIT(ap_id));/*H2C-0xBA*/
3218
}
3219
#else
3220
if (rtw_ap_get_nums(adapter) == 1)
3221
rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE, 0);/*H2C-0xBA*/
3222
#endif
3223
3224
rtw_hal_set_bcn_rsvdpage_loc_cmd(adapter);/*H2C-0x09*/
3225
3226
_rtw_mbid_bcn_cfg(adapter, _TRUE, ap_id);
3227
}
3228
void rtw_ap_mbid_bcn_dis(_adapter *adapter, u8 ap_id)
3229
{
3230
RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3231
_rtw_mbid_bcn_cfg(adapter, _FALSE, ap_id);
3232
3233
if (rtw_ap_get_nums(adapter) == 0)
3234
rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _FALSE, 0);
3235
#ifdef CONFIG_FW_TBTT_RPT
3236
else if (rtw_ap_get_nums(adapter) >= 1) {
3237
u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3238
3239
rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3240
tbtt_rpt_map & ~BIT(ap_id));/*H2C-0xBA*/
3241
}
3242
#endif
3243
}
3244
#endif
3245
#ifdef CONFIG_SWTIMER_BASED_TXBCN
3246
void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3247
{
3248
#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3249
rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT);
3250
#else
3251
rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
3252
#endif
3253
/*enable to rx data frame*/
3254
rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3255
3256
/*Beacon Control related register for first time*/
3257
rtw_write8(adapter, REG_BCNDMATIM, 0x02); /* 2ms */
3258
3259
/*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
3260
rtw_write8(adapter, REG_ATIMWND, 0x0c); /* 12ms */
3261
3262
#ifndef CONFIG_HW_P0_TSF_SYNC
3263
rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3264
#endif
3265
3266
/*reset TSF*/
3267
rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
3268
3269
/*enable BCN0 Function for if1*/
3270
/*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
3271
#if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3272
rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);
3273
#else
3274
rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3275
#endif
3276
#ifdef CONFIG_BCN_XMIT_PROTECT
3277
rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
3278
#endif
3279
3280
if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/
3281
rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
3282
3283
/* Enable HW seq for BCN
3284
* 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
3285
#ifdef CONFIG_RTL8822B
3286
if (IS_HARDWARE_TYPE_8822B(adapter))
3287
rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3288
#endif
3289
3290
#ifdef CONFIG_RTL8822C
3291
if (IS_HARDWARE_TYPE_8822C(adapter))
3292
rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3293
#endif
3294
}
3295
#endif
3296
3297
#ifdef CONFIG_MI_WITH_MBSSID_CAM
3298
void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3299
{
3300
3301
#if 0 /*TODO - modify for more flexible*/
3302
u8 idx = 0;
3303
3304
if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
3305
(DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
3306
for (idx = 0; idx < 6; idx++)
3307
rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
3308
} else {
3309
/*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
3310
u8 entry_id;
3311
3312
if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
3313
(DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
3314
entry_id = 0;
3315
if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
3316
RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
3317
write_mbssid_cam(adapter, entry_id, val);
3318
}
3319
} else {
3320
entry_id = rtw_mbid_camid_alloc(adapter, val);
3321
if (entry_id != INVALID_CAM_ID)
3322
write_mbssid_cam(adapter, entry_id, val);
3323
}
3324
}
3325
#else
3326
{
3327
/*
3328
MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
3329
*/
3330
u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
3331
3332
3333
if (entry_id != INVALID_CAM_ID) {
3334
write_mbssid_cam(adapter, entry_id, mac_addr);
3335
RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,
3336
ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));
3337
}
3338
}
3339
#endif
3340
}
3341
3342
void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3343
{
3344
u8 idx = 0;
3345
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3346
u8 entry_id;
3347
3348
if (!mac_addr) {
3349
rtw_warn_on(1);
3350
return;
3351
}
3352
3353
3354
entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
3355
3356
if (entry_id != INVALID_CAM_ID)
3357
write_mbssid_cam(adapter, entry_id, mac_addr);
3358
}
3359
3360
#ifdef CONFIG_SWTIMER_BASED_TXBCN
3361
u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
3362
{
3363
if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
3364
return adapter_to_dvobj(adapter)->inter_bcn_space;
3365
else
3366
return bcn_interval;
3367
}
3368
#endif/*CONFIG_SWTIMER_BASED_TXBCN*/
3369
3370
#else
3371
3372
#ifndef RTW_HALMAC
3373
static u32 _get_macaddr_reg(enum _hw_port hwport)
3374
{
3375
u32 reg_macaddr = REG_MACID;
3376
3377
#ifdef CONFIG_CONCURRENT_MODE
3378
if (hwport == HW_PORT1)
3379
reg_macaddr = REG_MACID1;
3380
#if defined(CONFIG_RTL8814A)
3381
else if (hwport == HW_PORT2)
3382
reg_macaddr = REG_MACID2;
3383
else if (hwport == HW_PORT3)
3384
reg_macaddr = REG_MACID3;
3385
else if (hwport == HW_PORT4)
3386
reg_macaddr = REG_MACID4;
3387
#endif /*CONFIG_RTL8814A*/
3388
#endif /*CONFIG_CONCURRENT_MODE*/
3389
3390
return reg_macaddr;
3391
}
3392
#endif /*!RTW_HALMAC*/
3393
3394
static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr)
3395
{
3396
enum _hw_port hwport;
3397
3398
if (mac_addr == NULL)
3399
return;
3400
hwport = get_hw_port(adapter);
3401
3402
RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3403
ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3404
3405
#ifdef RTW_HALMAC /*8822B ~ 8814B*/
3406
rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3407
#else /* !RTW_HALMAC */
3408
{
3409
u8 idx = 0;
3410
u32 reg_macaddr = _get_macaddr_reg(hwport);
3411
3412
for (idx = 0; idx < ETH_ALEN; idx++)
3413
rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx), mac_addr[idx]);
3414
}
3415
#endif /* !RTW_HALMAC */
3416
}
3417
#endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
3418
3419
static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
3420
{
3421
enum _hw_port hwport;
3422
3423
if (mac_addr == NULL)
3424
return;
3425
hwport = get_hw_port(adapter);
3426
3427
_rtw_memset(mac_addr, 0, ETH_ALEN);
3428
#ifdef RTW_HALMAC /*8822B ~ 8814B*/
3429
rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3430
#else /* !RTW_HALMAC */
3431
{
3432
u8 idx = 0;
3433
u32 reg_macaddr = _get_macaddr_reg(hwport);
3434
3435
for (idx = 0; idx < ETH_ALEN; idx++)
3436
mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx));
3437
}
3438
#endif /* !RTW_HALMAC */
3439
3440
RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3441
ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3442
}
3443
3444
#ifndef RTW_HALMAC
3445
static u32 _get_bssid_reg(enum _hw_port hw_port)
3446
{
3447
u32 reg_bssid = REG_BSSID;
3448
3449
#ifdef CONFIG_CONCURRENT_MODE
3450
if (hw_port == HW_PORT1)
3451
reg_bssid = REG_BSSID1;
3452
#if defined(CONFIG_RTL8814A)
3453
else if (hw_port == HW_PORT2)
3454
reg_bssid = REG_BSSID2;
3455
else if (hw_port == HW_PORT3)
3456
reg_bssid = REG_BSSID3;
3457
else if (hw_port == HW_PORT4)
3458
reg_bssid = REG_BSSID4;
3459
#endif /*CONFIG_RTL8814A*/
3460
#endif /*CONFIG_CONCURRENT_MODE*/
3461
3462
return reg_bssid;
3463
}
3464
#endif /*!RTW_HALMAC*/
3465
static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
3466
{
3467
enum _hw_port hw_port = rtw_hal_get_port(adapter);
3468
#ifdef RTW_HALMAC
3469
3470
rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);
3471
#else /* !RTW_HALMAC */
3472
u8 idx = 0;
3473
u32 reg_bssid = _get_bssid_reg(hw_port);
3474
3475
for (idx = 0 ; idx < ETH_ALEN; idx++)
3476
rtw_write8(adapter, (reg_bssid + idx), val[idx]);
3477
#endif /* !RTW_HALMAC */
3478
3479
RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",
3480
__func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));
3481
}
3482
3483
static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)
3484
{
3485
u32 addr = 0;
3486
u8 val8;
3487
3488
rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);
3489
if (addr) {
3490
rtw_enter_protsel_port(adapter, get_hw_port(adapter));
3491
val8 = rtw_read8(adapter, addr);
3492
if (en && (val8 & DIS_TSF_UDT)) {
3493
rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);
3494
#ifdef DBG_TSF_UPDATE
3495
RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3496
#endif
3497
}
3498
if (!en && !(val8 & DIS_TSF_UDT)) {
3499
rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);
3500
#ifdef DBG_TSF_UPDATE
3501
RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3502
#endif
3503
}
3504
rtw_leave_protsel_port(adapter);
3505
} else {
3506
RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"
3507
, adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");
3508
rtw_warn_on(1);
3509
}
3510
}
3511
3512
static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
3513
{
3514
#ifdef CONFIG_MI_WITH_MBSSID_CAM
3515
3516
#else
3517
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3518
3519
if (!pmlmeext->en_hw_update_tsf)
3520
return;
3521
3522
/* check RCR */
3523
if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
3524
return;
3525
3526
if (pmlmeext->tsf_update_required) {
3527
pmlmeext->tsf_update_pause_stime = 0;
3528
rtw_hal_set_tsf_update(padapter, 1);
3529
}
3530
3531
pmlmeext->en_hw_update_tsf = 0;
3532
#endif
3533
}
3534
3535
void rtw_iface_enable_tsf_update(_adapter *adapter)
3536
{
3537
adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3538
adapter->mlmeextpriv.tsf_update_required = 1;
3539
#ifdef CONFIG_MI_WITH_MBSSID_CAM
3540
3541
#else
3542
rtw_hal_set_tsf_update(adapter, 1);
3543
#endif
3544
}
3545
3546
void rtw_iface_disable_tsf_update(_adapter *adapter)
3547
{
3548
adapter->mlmeextpriv.tsf_update_required = 0;
3549
adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3550
adapter->mlmeextpriv.en_hw_update_tsf = 0;
3551
#ifdef CONFIG_MI_WITH_MBSSID_CAM
3552
3553
#else
3554
rtw_hal_set_tsf_update(adapter, 0);
3555
#endif
3556
}
3557
3558
static void rtw_hal_tsf_update_pause(_adapter *adapter)
3559
{
3560
#ifdef CONFIG_MI_WITH_MBSSID_CAM
3561
3562
#else
3563
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3564
_adapter *iface;
3565
int i;
3566
3567
for (i = 0; i < dvobj->iface_nums; i++) {
3568
iface = dvobj->padapters[i];
3569
if (!iface)
3570
continue;
3571
3572
rtw_hal_set_tsf_update(iface, 0);
3573
if (iface->mlmeextpriv.tsf_update_required) {
3574
iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();
3575
if (!iface->mlmeextpriv.tsf_update_pause_stime)
3576
iface->mlmeextpriv.tsf_update_pause_stime++;
3577
}
3578
iface->mlmeextpriv.en_hw_update_tsf = 0;
3579
}
3580
#endif
3581
}
3582
3583
static void rtw_hal_tsf_update_restore(_adapter *adapter)
3584
{
3585
#ifdef CONFIG_MI_WITH_MBSSID_CAM
3586
3587
#else
3588
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3589
_adapter *iface;
3590
int i;
3591
3592
for (i = 0; i < dvobj->iface_nums; i++) {
3593
iface = dvobj->padapters[i];
3594
if (!iface)
3595
continue;
3596
3597
if (iface->mlmeextpriv.tsf_update_required) {
3598
/* enable HW TSF update when recive beacon*/
3599
iface->mlmeextpriv.en_hw_update_tsf = 1;
3600
#ifdef DBG_TSF_UPDATE
3601
RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"
3602
, iface->hw_port, ADPT_ARG(iface));
3603
#endif
3604
}
3605
}
3606
#endif
3607
}
3608
3609
void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)
3610
{
3611
#ifdef CONFIG_MI_WITH_MBSSID_CAM
3612
3613
#else
3614
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3615
_adapter *iface;
3616
struct mlme_ext_priv *mlmeext;
3617
int i;
3618
u32 restore_ms = 0;
3619
3620
if (dvobj->periodic_tsf_update_etime) {
3621
if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {
3622
/* end for restore status */
3623
dvobj->periodic_tsf_update_etime = 0;
3624
rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3625
}
3626
return;
3627
}
3628
3629
if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)
3630
return;
3631
3632
/*
3633
* all required ifaces can switch to restore status together
3634
* loop all pause iface to get largest restore time required
3635
*/
3636
for (i = 0; i < dvobj->iface_nums; i++) {
3637
iface = dvobj->padapters[i];
3638
if (!iface)
3639
continue;
3640
3641
mlmeext = &iface->mlmeextpriv;
3642
3643
if (mlmeext->tsf_update_required
3644
&& mlmeext->tsf_update_pause_stime
3645
&& rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)
3646
> mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor
3647
) {
3648
if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)
3649
restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;
3650
}
3651
}
3652
3653
if (!restore_ms)
3654
return;
3655
3656
dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);
3657
if (!dvobj->periodic_tsf_update_etime)
3658
dvobj->periodic_tsf_update_etime++;
3659
3660
rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3661
3662
/* set timer to end restore status */
3663
_set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);
3664
#endif
3665
}
3666
3667
void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)
3668
{
3669
struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;
3670
3671
if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
3672
return;
3673
3674
rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));
3675
}
3676
3677
static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
3678
{
3679
int err;
3680
3681
#ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
3682
rcr = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_AMF | RCR_APP_PHYST_RXFF | RCR_APP_MIC | RCR_APP_ICV;
3683
#endif
3684
err = rtw_write32(adapter, REG_RCR, rcr);
3685
if (err == _SUCCESS)
3686
GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
3687
return err;
3688
}
3689
3690
static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
3691
{
3692
u32 v32;
3693
3694
v32 = rtw_read32(adapter, REG_RCR);
3695
if (rcr)
3696
*rcr = v32;
3697
GET_HAL_DATA(adapter)->ReceiveConfig = v32;
3698
return _SUCCESS;
3699
}
3700
3701
/* only check SW RCR variable */
3702
inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
3703
{
3704
PHAL_DATA_TYPE hal;
3705
u32 rcr;
3706
3707
hal = GET_HAL_DATA(adapter);
3708
3709
rcr = hal->ReceiveConfig;
3710
if ((rcr & check_bit) == check_bit)
3711
return 1;
3712
3713
return 0;
3714
}
3715
3716
inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
3717
{
3718
PHAL_DATA_TYPE hal;
3719
u32 rcr;
3720
u8 ret = _SUCCESS;
3721
3722
hal = GET_HAL_DATA(adapter);
3723
3724
rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3725
rcr |= add;
3726
if (rcr != hal->ReceiveConfig)
3727
ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3728
3729
return ret;
3730
}
3731
3732
inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
3733
{
3734
PHAL_DATA_TYPE hal;
3735
u32 rcr;
3736
u8 ret = _SUCCESS;
3737
3738
hal = GET_HAL_DATA(adapter);
3739
3740
rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3741
rcr &= ~clear;
3742
if (rcr != hal->ReceiveConfig)
3743
ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3744
3745
return ret;
3746
}
3747
3748
void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
3749
{
3750
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3751
struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3752
u32 rcr, rcr_new;
3753
struct mi_state mstate, mstate_s;
3754
3755
rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3756
rcr_new = rcr;
3757
3758
#if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)
3759
rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
3760
#else
3761
rtw_mi_status_no_self(adapter, &mstate);
3762
rtw_mi_status_no_others(adapter, &mstate_s);
3763
3764
/* only adjust parameters interested */
3765
switch (self_action) {
3766
case MLME_SCAN_ENTER:
3767
mstate_s.scan_num = 1;
3768
mstate_s.scan_enter_num = 1;
3769
break;
3770
case MLME_SCAN_DONE:
3771
mstate_s.scan_enter_num = 0;
3772
break;
3773
case MLME_STA_CONNECTING:
3774
mstate_s.lg_sta_num = 1;
3775
mstate_s.ld_sta_num = 0;
3776
break;
3777
case MLME_STA_CONNECTED:
3778
mstate_s.lg_sta_num = 0;
3779
mstate_s.ld_sta_num = 1;
3780
break;
3781
case MLME_STA_DISCONNECTED:
3782
mstate_s.lg_sta_num = 0;
3783
mstate_s.ld_sta_num = 0;
3784
break;
3785
#ifdef CONFIG_TDLS
3786
case MLME_TDLS_LINKED:
3787
mstate_s.ld_tdls_num = 1;
3788
break;
3789
case MLME_TDLS_NOLINK:
3790
mstate_s.ld_tdls_num = 0;
3791
break;
3792
#endif
3793
#ifdef CONFIG_AP_MODE
3794
case MLME_AP_STARTED:
3795
mstate_s.ap_num = 1;
3796
break;
3797
case MLME_AP_STOPPED:
3798
mstate_s.ap_num = 0;
3799
mstate_s.ld_ap_num = 0;
3800
break;
3801
#endif
3802
#ifdef CONFIG_RTW_MESH
3803
case MLME_MESH_STARTED:
3804
mstate_s.mesh_num = 1;
3805
break;
3806
case MLME_MESH_STOPPED:
3807
mstate_s.mesh_num = 0;
3808
mstate_s.ld_mesh_num = 0;
3809
break;
3810
#endif
3811
case MLME_ACTION_NONE:
3812
case MLME_ADHOC_STARTED:
3813
/* caller without effect of decision */
3814
break;
3815
default:
3816
rtw_warn_on(1);
3817
};
3818
3819
rtw_mi_status_merge(&mstate, &mstate_s);
3820
3821
if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
3822
#ifdef CONFIG_FIND_BEST_CHANNEL
3823
|| MSTATE_SCAN_ENTER_NUM(&mstate)
3824
#endif
3825
|| hal_data->in_cta_test
3826
)
3827
rcr_new &= ~RCR_CBSSID_DATA;
3828
else
3829
rcr_new |= RCR_CBSSID_DATA;
3830
3831
if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)
3832
rcr_new &= ~RCR_CBSSID_BCN;
3833
else if (MSTATE_STA_LG_NUM(&mstate)
3834
|| adapter_to_dvobj(adapter)->periodic_tsf_update_etime
3835
)
3836
rcr_new |= RCR_CBSSID_BCN;
3837
else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
3838
|| MSTATE_MESH_NUM(&mstate)
3839
)
3840
rcr_new &= ~RCR_CBSSID_BCN;
3841
else
3842
rcr_new |= RCR_CBSSID_BCN;
3843
3844
#ifdef CONFIG_CLIENT_PORT_CFG
3845
if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)
3846
rcr_new &= ~RCR_CBSSID_BCN;
3847
#endif
3848
#endif /* CONFIG_MI_WITH_MBSSID_CAM */
3849
3850
if (rcr == rcr_new)
3851
return;
3852
3853
if (!hal_spec->rx_tsf_filter
3854
&& (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))
3855
rtw_hal_tsf_update_pause(adapter);
3856
3857
rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
3858
3859
if (!hal_spec->rx_tsf_filter
3860
&& !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)
3861
&& self_action != MLME_STA_CONNECTING)
3862
rtw_hal_tsf_update_restore(adapter);
3863
}
3864
3865
static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
3866
{
3867
u32 rcr = RCR_AM;
3868
3869
if (enable)
3870
rtw_hal_rcr_add(adapter, rcr);
3871
else
3872
rtw_hal_rcr_clear(adapter, rcr);
3873
}
3874
3875
static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)
3876
{
3877
#ifdef CONFIG_SWTIMER_BASED_TXBCN
3878
interval = rtw_hal_bcn_interval_adjust(adapter, interval);
3879
#endif
3880
3881
#ifdef RTW_HALMAC
3882
rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);
3883
#else
3884
rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);
3885
#endif
3886
3887
#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3888
{
3889
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3890
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3891
3892
if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3893
RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);
3894
rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);
3895
}
3896
}
3897
#endif
3898
}
3899
3900
#if CONFIG_TX_AC_LIFETIME
3901
const char *const _tx_aclt_conf_str[] = {
3902
"DEFAULT",
3903
"AP_M2U",
3904
"MESH",
3905
"INVALID",
3906
};
3907
3908
void dump_tx_aclt_force_val(void *sel, struct dvobj_priv *dvobj)
3909
{
3910
#define TX_ACLT_FORCE_MSG_LEN 64
3911
struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3912
struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3913
char buf[TX_ACLT_FORCE_MSG_LEN];
3914
int cnt = 0;
3915
3916
RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3917
, hal_spec->tx_aclt_unit_factor * 32
3918
, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3919
3920
RTW_PRINT_SEL(sel, "%-5s %-12s %-12s\n", "en", "vo_vi(us)", "be_bk(us)");
3921
RTW_PRINT_SEL(sel, " 0x%02x %12u %12u\n"
3922
, conf->en
3923
, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3924
, conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3925
);
3926
3927
cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "%5s", conf->en == 0xFF ? "AUTO" : "FORCE");
3928
if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3929
goto exit;
3930
3931
if (conf->vo_vi)
3932
cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->vo_vi);
3933
else
3934
cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");
3935
if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3936
goto exit;
3937
3938
3939
if (conf->be_bk)
3940
cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->be_bk);
3941
else
3942
cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");
3943
if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3944
goto exit;
3945
3946
RTW_PRINT_SEL(sel, "%s\n", buf);
3947
3948
exit:
3949
return;
3950
}
3951
3952
void rtw_hal_set_tx_aclt_force_val(_adapter *adapter, struct tx_aclt_conf_t *input, u8 arg_num)
3953
{
3954
struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3955
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3956
struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3957
3958
if (arg_num >= 1) {
3959
if (input->en == 0xFF)
3960
conf->en = input->en;
3961
else
3962
conf->en = input->en & 0xF;
3963
}
3964
if (arg_num >= 2) {
3965
conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
3966
if (conf->vo_vi > 0xFFFF)
3967
conf->vo_vi = 0xFFFF;
3968
}
3969
if (arg_num >= 3) {
3970
conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
3971
if (conf->be_bk > 0xFFFF)
3972
conf->be_bk = 0xFFFF;
3973
}
3974
}
3975
3976
void dump_tx_aclt_confs(void *sel, struct dvobj_priv *dvobj)
3977
{
3978
#define TX_ACLT_CONF_MSG_LEN 32
3979
struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3980
struct tx_aclt_conf_t *conf;
3981
char buf[TX_ACLT_CONF_MSG_LEN];
3982
int cnt;
3983
int i;
3984
3985
RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3986
, hal_spec->tx_aclt_unit_factor * 32
3987
, 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3988
3989
RTW_PRINT_SEL(sel, "%-7s %-1s %-3s %-9s %-9s %-10s %-10s\n"
3990
, "name", "#", "en", "vo_vi(us)", "be_bk(us)", "vo_vi(reg)", "be_bk(reg)");
3991
3992
for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
3993
conf = &dvobj->tx_aclt_confs[i];
3994
cnt = 0;
3995
3996
if (conf->vo_vi)
3997
cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->vo_vi);
3998
else
3999
cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
4000
if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
4001
continue;
4002
4003
if (conf->be_bk)
4004
cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->be_bk);
4005
else
4006
cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
4007
if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
4008
continue;
4009
4010
RTW_PRINT_SEL(sel, "%7s %1u 0x%x %9u %9u%s\n"
4011
, tx_aclt_conf_str(i), i
4012
, conf->en
4013
, conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
4014
, conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
4015
, buf
4016
);
4017
}
4018
}
4019
4020
void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_conf_t *input, u8 arg_num)
4021
{
4022
struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4023
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4024
struct tx_aclt_conf_t *conf;
4025
4026
if (conf_idx >= TX_ACLT_CONF_NUM)
4027
return;
4028
4029
conf = &dvobj->tx_aclt_confs[conf_idx];
4030
4031
if (arg_num >= 1) {
4032
if (input->en != 0xFF)
4033
conf->en = input->en & 0xF;
4034
}
4035
if (arg_num >= 2) {
4036
conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
4037
if (conf->vo_vi > 0xFFFF)
4038
conf->vo_vi = 0xFFFF;
4039
}
4040
if (arg_num >= 3) {
4041
conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
4042
if (conf->be_bk > 0xFFFF)
4043
conf->be_bk = 0xFFFF;
4044
}
4045
}
4046
4047
void rtw_hal_update_tx_aclt(_adapter *adapter)
4048
{
4049
#ifdef CONFIG_TX_MCAST2UNI
4050
extern int rtw_mc2u_disable;
4051
#endif
4052
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4053
struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter);
4054
u8 lt_en = 0, lt_en_ori;
4055
u16 lt_vo_vi = 0xFFFF, lt_be_bk = 0xFFFF;
4056
u32 lt, lt_ori;
4057
struct tx_aclt_conf_t *conf;
4058
int i;
4059
4060
lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN);
4061
lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME);
4062
4063
for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
4064
if (!(dvobj->tx_aclt_flags & BIT(i)))
4065
continue;
4066
4067
conf = &dvobj->tx_aclt_confs[i];
4068
4069
if (i == TX_ACLT_CONF_DEFAULT) {
4070
/* first and default status, assign directly */
4071
lt_en = conf->en;
4072
if (conf->vo_vi)
4073
lt_vo_vi = conf->vo_vi;
4074
if (conf->be_bk)
4075
lt_be_bk = conf->be_bk;
4076
}
4077
#if defined(CONFIG_TX_MCAST2UNI) || defined(CONFIG_RTW_MESH)
4078
else if (0
4079
#ifdef CONFIG_TX_MCAST2UNI
4080
|| (i == TX_ACLT_CONF_AP_M2U
4081
&& !rtw_mc2u_disable
4082
&& macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */)
4083
#endif
4084
#ifdef CONFIG_RTW_MESH
4085
|| (i == TX_ACLT_CONF_MESH
4086
&& macid_ctl->op_num[H2C_MSR_ROLE_MESH] > 1 /* implies only 1 MESH mode supported */)
4087
#endif
4088
) {
4089
/* long term status, OR en and MIN lifetime */
4090
lt_en |= conf->en;
4091
if (conf->vo_vi && lt_vo_vi > conf->vo_vi)
4092
lt_vo_vi = conf->vo_vi;
4093
if (conf->be_bk && lt_be_bk > conf->be_bk)
4094
lt_be_bk = conf->be_bk;
4095
}
4096
#endif
4097
}
4098
4099
if (dvobj->tx_aclt_force_val.en != 0xFF)
4100
lt_en = dvobj->tx_aclt_force_val.en;
4101
if (dvobj->tx_aclt_force_val.vo_vi)
4102
lt_vo_vi = dvobj->tx_aclt_force_val.vo_vi;
4103
if (dvobj->tx_aclt_force_val.be_bk)
4104
lt_be_bk = dvobj->tx_aclt_force_val.be_bk;
4105
4106
lt_en = (lt_en_ori & 0xF0) | (lt_en & 0x0F);
4107
lt = (lt_be_bk << 16) | lt_vo_vi;
4108
4109
if (0)
4110
RTW_INFO("lt_en:0x%x(0x%x), lt:0x%08x(0x%08x)\n", lt_en, lt_en_ori, lt, lt_ori);
4111
4112
if (lt_en != lt_en_ori)
4113
rtw_write8(adapter, REG_LIFETIME_EN, lt_en);
4114
if (lt != lt_ori)
4115
rtw_write32(adapter, REG_PKT_LIFE_TIME, lt);
4116
}
4117
#endif /* CONFIG_TX_AC_LIFETIME */
4118
4119
void hw_var_port_switch(_adapter *adapter)
4120
{
4121
#ifdef CONFIG_CONCURRENT_MODE
4122
#ifdef CONFIG_RUNTIME_PORT_SWITCH
4123
/*
4124
0x102: MSR
4125
0x550: REG_BCN_CTRL
4126
0x551: REG_BCN_CTRL_1
4127
0x55A: REG_ATIMWND
4128
0x560: REG_TSFTR
4129
0x568: REG_TSFTR1
4130
0x570: REG_ATIMWND_1
4131
0x610: REG_MACID
4132
0x618: REG_BSSID
4133
0x700: REG_MACID1
4134
0x708: REG_BSSID1
4135
*/
4136
4137
int i;
4138
u8 msr;
4139
u8 bcn_ctrl;
4140
u8 bcn_ctrl_1;
4141
u8 atimwnd[2];
4142
u8 atimwnd_1[2];
4143
u8 tsftr[8];
4144
u8 tsftr_1[8];
4145
u8 macid[6];
4146
u8 bssid[6];
4147
u8 macid_1[6];
4148
u8 bssid_1[6];
4149
#if defined(CONFIG_RTL8192F)
4150
u16 wlan_act_mask_ctrl = 0;
4151
u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;
4152
#endif
4153
4154
u8 hw_port;
4155
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4156
_adapter *iface = NULL;
4157
4158
msr = rtw_read8(adapter, MSR);
4159
bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4160
bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4161
#if defined(CONFIG_RTL8192F)
4162
wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4163
#endif
4164
4165
for (i = 0; i < 2; i++)
4166
atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4167
for (i = 0; i < 2; i++)
4168
atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4169
4170
for (i = 0; i < 8; i++)
4171
tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4172
for (i = 0; i < 8; i++)
4173
tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4174
4175
for (i = 0; i < 6; i++)
4176
macid[i] = rtw_read8(adapter, REG_MACID + i);
4177
4178
for (i = 0; i < 6; i++)
4179
bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4180
4181
for (i = 0; i < 6; i++)
4182
macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4183
4184
for (i = 0; i < 6; i++)
4185
bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4186
4187
#ifdef DBG_RUNTIME_PORT_SWITCH
4188
RTW_INFO(FUNC_ADPT_FMT" before switch\n"
4189
"msr:0x%02x\n"
4190
"bcn_ctrl:0x%02x\n"
4191
"bcn_ctrl_1:0x%02x\n"
4192
#if defined(CONFIG_RTL8192F)
4193
"wlan_act_mask_ctrl:0x%02x\n"
4194
#endif
4195
"atimwnd:0x%04x\n"
4196
"atimwnd_1:0x%04x\n"
4197
"tsftr:%llu\n"
4198
"tsftr1:%llu\n"
4199
"macid:"MAC_FMT"\n"
4200
"bssid:"MAC_FMT"\n"
4201
"macid_1:"MAC_FMT"\n"
4202
"bssid_1:"MAC_FMT"\n"
4203
, FUNC_ADPT_ARG(adapter)
4204
, msr
4205
, bcn_ctrl
4206
, bcn_ctrl_1
4207
#if defined(CONFIG_RTL8192F)
4208
, wlan_act_mask_ctrl
4209
#endif
4210
, *((u16 *)atimwnd)
4211
, *((u16 *)atimwnd_1)
4212
, *((u64 *)tsftr)
4213
, *((u64 *)tsftr_1)
4214
, MAC_ARG(macid)
4215
, MAC_ARG(bssid)
4216
, MAC_ARG(macid_1)
4217
, MAC_ARG(bssid_1)
4218
);
4219
#endif /* DBG_RUNTIME_PORT_SWITCH */
4220
4221
/* disable bcn function, disable update TSF */
4222
rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4223
rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4224
4225
#if defined(CONFIG_RTL8192F)
4226
rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);
4227
#endif
4228
4229
/* switch msr */
4230
msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
4231
rtw_write8(adapter, MSR, msr);
4232
4233
/* write port0 */
4234
rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
4235
for (i = 0; i < 2; i++)
4236
rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
4237
for (i = 0; i < 8; i++)
4238
rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
4239
for (i = 0; i < 6; i++)
4240
rtw_write8(adapter, REG_MACID + i, macid_1[i]);
4241
for (i = 0; i < 6; i++)
4242
rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
4243
4244
/* write port1 */
4245
rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
4246
for (i = 0; i < 2; i++)
4247
rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
4248
for (i = 0; i < 8; i++)
4249
rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
4250
for (i = 0; i < 6; i++)
4251
rtw_write8(adapter, REG_MACID1 + i, macid[i]);
4252
for (i = 0; i < 6; i++)
4253
rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
4254
4255
/* write bcn ctl */
4256
#ifdef CONFIG_BT_COEXIST
4257
/* always enable port0 beacon function for PSTDMA */
4258
if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
4259
|| IS_HARDWARE_TYPE_8723D(adapter))
4260
bcn_ctrl_1 |= EN_BCN_FUNCTION;
4261
/* always disable port1 beacon function for PSTDMA */
4262
if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
4263
bcn_ctrl &= ~EN_BCN_FUNCTION;
4264
#endif
4265
rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
4266
rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
4267
4268
#if defined(CONFIG_RTL8192F)
4269
/* if the setting of port0 and port1 are the same, it does not need to switch port setting*/
4270
if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)
4271
!= (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))
4272
wlan_act_mask_ctrl ^= en_port_mask;
4273
rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);
4274
#endif
4275
4276
if (adapter->iface_id == IFACE_ID0)
4277
iface = dvobj->padapters[IFACE_ID1];
4278
else if (adapter->iface_id == IFACE_ID1)
4279
iface = dvobj->padapters[IFACE_ID0];
4280
4281
4282
if (adapter->hw_port == HW_PORT0) {
4283
adapter->hw_port = HW_PORT1;
4284
iface->hw_port = HW_PORT0;
4285
RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4286
ADPT_ARG(iface), ADPT_ARG(adapter));
4287
} else {
4288
adapter->hw_port = HW_PORT0;
4289
iface->hw_port = HW_PORT1;
4290
RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4291
ADPT_ARG(adapter), ADPT_ARG(iface));
4292
}
4293
4294
#ifdef DBG_RUNTIME_PORT_SWITCH
4295
msr = rtw_read8(adapter, MSR);
4296
bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4297
bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4298
#if defined(CONFIG_RTL8192F)
4299
wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4300
#endif
4301
4302
for (i = 0; i < 2; i++)
4303
atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4304
for (i = 0; i < 2; i++)
4305
atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4306
4307
for (i = 0; i < 8; i++)
4308
tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4309
for (i = 0; i < 8; i++)
4310
tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4311
4312
for (i = 0; i < 6; i++)
4313
macid[i] = rtw_read8(adapter, REG_MACID + i);
4314
4315
for (i = 0; i < 6; i++)
4316
bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4317
4318
for (i = 0; i < 6; i++)
4319
macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4320
4321
for (i = 0; i < 6; i++)
4322
bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4323
4324
RTW_INFO(FUNC_ADPT_FMT" after switch\n"
4325
"msr:0x%02x\n"
4326
"bcn_ctrl:0x%02x\n"
4327
"bcn_ctrl_1:0x%02x\n"
4328
#if defined(CONFIG_RTL8192F)
4329
"wlan_act_mask_ctrl:0x%02x\n"
4330
#endif
4331
"atimwnd:%u\n"
4332
"atimwnd_1:%u\n"
4333
"tsftr:%llu\n"
4334
"tsftr1:%llu\n"
4335
"macid:"MAC_FMT"\n"
4336
"bssid:"MAC_FMT"\n"
4337
"macid_1:"MAC_FMT"\n"
4338
"bssid_1:"MAC_FMT"\n"
4339
, FUNC_ADPT_ARG(adapter)
4340
, msr
4341
, bcn_ctrl
4342
, bcn_ctrl_1
4343
#if defined(CONFIG_RTL8192F)
4344
, wlan_act_mask_ctrl
4345
#endif
4346
, *((u16 *)atimwnd)
4347
, *((u16 *)atimwnd_1)
4348
, *((u64 *)tsftr)
4349
, *((u64 *)tsftr_1)
4350
, MAC_ARG(macid)
4351
, MAC_ARG(bssid)
4352
, MAC_ARG(macid_1)
4353
, MAC_ARG(bssid_1)
4354
);
4355
#endif /* DBG_RUNTIME_PORT_SWITCH */
4356
4357
#endif /* CONFIG_RUNTIME_PORT_SWITCH */
4358
#endif /* CONFIG_CONCURRENT_MODE */
4359
}
4360
4361
const char *const _h2c_msr_role_str[] = {
4362
"RSVD",
4363
"STA",
4364
"AP",
4365
"GC",
4366
"GO",
4367
"TDLS",
4368
"ADHOC",
4369
"MESH",
4370
"INVALID",
4371
};
4372
4373
#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4374
s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
4375
{
4376
s32 ret = _SUCCESS;
4377
u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
4378
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4379
u8 port_id = rtw_hal_get_port(adapter);
4380
4381
if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))
4382
return ret;
4383
4384
SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);
4385
SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
4386
4387
RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
4388
RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",
4389
__func__, ADPT_ARG(adapter), port_id, mac_id);
4390
4391
ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
4392
dvobj->dft.port_id = port_id;
4393
dvobj->dft.mac_id = mac_id;
4394
4395
return ret;
4396
}
4397
s32 rtw_set_default_port_id(_adapter *adapter)
4398
{
4399
s32 ret = _SUCCESS;
4400
struct sta_info *psta;
4401
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4402
4403
if (is_client_associated_to_ap(adapter)) {
4404
psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
4405
if (psta)
4406
ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
4407
} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
4408
4409
} else {
4410
}
4411
4412
return ret;
4413
}
4414
s32 rtw_set_ps_rsvd_page(_adapter *adapter)
4415
{
4416
s32 ret = _SUCCESS;
4417
u16 media_status_rpt = RT_MEDIA_CONNECT;
4418
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4419
4420
if (adapter->iface_id == pwrctl->fw_psmode_iface_id)
4421
return ret;
4422
4423
rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
4424
(u8 *)&media_status_rpt);
4425
4426
return ret;
4427
}
4428
4429
#if 0
4430
_adapter * _rtw_search_dp_iface(_adapter *adapter)
4431
{
4432
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4433
_adapter *iface;
4434
_adapter *target_iface = NULL;
4435
int i;
4436
u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;
4437
u8 p2p_go_num = 0, p2p_gc_num = 0;
4438
_adapter *sta_ifs[8];
4439
_adapter *ap_ifs[8];
4440
_adapter *mesh_ifs[8];
4441
_adapter *gc_ifs[8];
4442
_adapter *go_ifs[8];
4443
4444
for (i = 0; i < dvobj->iface_nums; i++) {
4445
iface = dvobj->padapters[i];
4446
4447
if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
4448
if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) {
4449
sta_ifs[sta_num++] = iface;
4450
4451
#ifdef CONFIG_TDLS
4452
if (iface->tdlsinfo.link_established == _TRUE)
4453
tdls_num++;
4454
#endif
4455
#ifdef CONFIG_P2P
4456
if (MLME_IS_GC(iface))
4457
gc_ifs[p2p_gc_num++] = iface;
4458
#endif
4459
}
4460
#ifdef CONFIG_AP_MODE
4461
} else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
4462
if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) {
4463
ap_ifs[ap_num++] = iface;
4464
#ifdef CONFIG_P2P
4465
if (MLME_IS_GO(iface))
4466
go_ifs[p2p_go_num++] = iface;
4467
#endif
4468
}
4469
#endif
4470
} else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
4471
&& check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
4472
) {
4473
adhoc_num++;
4474
4475
#ifdef CONFIG_RTW_MESH
4476
} else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
4477
&& check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
4478
) {
4479
mesh_ifs[mesh_num++] = iface;
4480
#endif
4481
}
4482
}
4483
4484
if (p2p_gc_num) {
4485
target_iface = gc_ifs[0];
4486
}
4487
else if (sta_num) {
4488
if(sta_num == 1) {
4489
target_iface = sta_ifs[0];
4490
} else if (sta_num >= 2) {
4491
/*TODO get target_iface by timestamp*/
4492
target_iface = sta_ifs[0];
4493
}
4494
} else if (ap_num) {
4495
target_iface = ap_ifs[0];
4496
}
4497
4498
RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);
4499
RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);
4500
RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);
4501
RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);
4502
RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);
4503
RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);
4504
RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);
4505
4506
if (target_iface)
4507
RTW_INFO("%s => target_iface ("ADPT_FMT")\n",
4508
__func__, ADPT_ARG(target_iface));
4509
else
4510
RTW_INFO("%s => target_iface NULL\n", __func__);
4511
4512
return target_iface;
4513
}
4514
4515
void rtw_search_default_port(_adapter *adapter)
4516
{
4517
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4518
_adapter *adp_iface = NULL;
4519
#ifdef CONFIG_WOWLAN
4520
struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
4521
4522
if (pwrpriv->wowlan_mode == _TRUE) {
4523
adp_iface = adapter;
4524
goto exit;
4525
}
4526
#endif
4527
adp_iface = _rtw_search_dp_iface(adapter);
4528
4529
exit :
4530
if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))
4531
rtw_set_default_port_id(adp_iface);
4532
else
4533
rtw_hal_set_default_port_id_cmd(adapter, 0);
4534
4535
if (1) {
4536
_adapter *tmp_adp;
4537
4538
tmp_adp = (adp_iface) ? adp_iface : adapter;
4539
4540
RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",
4541
__func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));
4542
}
4543
}
4544
#endif
4545
#endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/
4546
4547
#ifdef CONFIG_P2P_PS
4548
#ifdef RTW_HALMAC
4549
void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
4550
{
4551
PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4552
struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4553
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4554
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4555
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
4556
struct sta_priv *pstapriv = &adapter->stapriv;
4557
struct sta_info *psta;
4558
HAL_P2P_PS_PARA p2p_ps_para;
4559
int status = -1;
4560
u8 i;
4561
u8 hw_port = rtw_hal_get_port(adapter);
4562
4563
_rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
4564
_rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
4565
4566
(&p2p_ps_para)->p2p_port_id = hw_port;
4567
(&p2p_ps_para)->p2p_group = 0;
4568
psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
4569
if (psta) {
4570
(&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
4571
} else {
4572
if (p2p_ps_state != P2P_PS_DISABLE) {
4573
RTW_ERR("%s , psta was NULL\n", __func__);
4574
return;
4575
}
4576
}
4577
4578
4579
switch (p2p_ps_state) {
4580
case P2P_PS_DISABLE:
4581
RTW_INFO("P2P_PS_DISABLE\n");
4582
_rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
4583
break;
4584
4585
case P2P_PS_ENABLE:
4586
RTW_INFO("P2P_PS_ENABLE\n");
4587
/* update CTWindow value. */
4588
if (pwdinfo->ctwindow > 0) {
4589
(&p2p_ps_para)->ctwindow_en = 1;
4590
(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4591
/*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
4592
}
4593
4594
4595
if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
4596
(&p2p_ps_para)->offload_en = 1;
4597
if (pwdinfo->role == P2P_ROLE_GO) {
4598
(&p2p_ps_para)->role = 1;
4599
(&p2p_ps_para)->all_sta_sleep = 0;
4600
} else
4601
(&p2p_ps_para)->role = 0;
4602
4603
(&p2p_ps_para)->discovery = 0;
4604
}
4605
/* hw only support 2 set of NoA */
4606
for (i = 0; i < pwdinfo->noa_num; i++) {
4607
/* To control the register setting for which NOA */
4608
(&p2p_ps_para)->noa_sel = i;
4609
(&p2p_ps_para)->noa_en = 1;
4610
(&p2p_ps_para)->disable_close_rf = 0;
4611
#ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
4612
#ifdef CONFIG_CONCURRENT_MODE
4613
if (rtw_mi_buddy_check_fwstate(adapter, WIFI_ASOC_STATE))
4614
#endif /* CONFIG_CONCURRENT_MODE */
4615
(&p2p_ps_para)->disable_close_rf = 1;
4616
#endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
4617
/* config P2P NoA Descriptor Register */
4618
/* config NOA duration */
4619
(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
4620
/* config NOA interval */
4621
(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
4622
/* config NOA start time */
4623
(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
4624
/* config NOA count */
4625
(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
4626
/*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
4627
(&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
4628
(&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
4629
status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4630
if (status == -1)
4631
RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4632
}
4633
4634
break;
4635
4636
case P2P_PS_SCAN:
4637
/*This feature FW not ready 20161116 YiWei*/
4638
return;
4639
/*
4640
RTW_INFO("P2P_PS_SCAN\n");
4641
(&p2p_ps_para)->discovery = 1;
4642
(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4643
(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4644
(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4645
(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4646
(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4647
*/
4648
break;
4649
4650
case P2P_PS_SCAN_DONE:
4651
/*This feature FW not ready 20161116 YiWei*/
4652
return;
4653
/*
4654
RTW_INFO("P2P_PS_SCAN_DONE\n");
4655
(&p2p_ps_para)->discovery = 0;
4656
pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
4657
(&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4658
(&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4659
(&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4660
(&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4661
(&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4662
*/
4663
break;
4664
4665
default:
4666
break;
4667
}
4668
4669
if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
4670
status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4671
if (status == -1)
4672
RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4673
}
4674
_rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
4675
4676
}
4677
#endif /* RTW_HALMAC */
4678
#endif /* CONFIG_P2P */
4679
4680
/*
4681
* rtw_hal_set_FwMediaStatusRpt_cmd -
4682
*
4683
* @adapter:
4684
* @opmode: 0:disconnect, 1:connect
4685
* @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
4686
* @miracast_sink: 0:source. 1:sink
4687
* @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
4688
* @macid:
4689
* @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end
4690
* @macid_end:
4691
*/
4692
s32 rtw_hal_set_FwMediaStatusRpt_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, bool macid_ind, u8 macid_end)
4693
{
4694
struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
4695
u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
4696
int i;
4697
s32 ret;
4698
#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4699
u8 hw_port = rtw_hal_get_port(adapter);
4700
#endif
4701
u8 op_num_change_bmp = 0;
4702
4703
SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
4704
SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
4705
SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
4706
SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
4707
SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
4708
SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
4709
SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
4710
#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4711
SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);
4712
#endif
4713
RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
4714
4715
ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
4716
if (ret != _SUCCESS)
4717
goto exit;
4718
4719
#if defined(CONFIG_RTL8188E)
4720
if (rtw_get_chip_type(adapter) == RTL8188E) {
4721
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4722
4723
/* 8188E FW doesn't set macid no link, driver does it by self */
4724
if (opmode)
4725
rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
4726
else
4727
rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
4728
4729
/* for 8188E RA */
4730
#if (RATE_ADAPTIVE_SUPPORT == 1)
4731
if (hal_data->fw_ractrl == _FALSE) {
4732
u8 max_macid;
4733
4734
max_macid = rtw_search_max_mac_id(adapter);
4735
rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
4736
}
4737
#endif
4738
}
4739
#endif
4740
4741
#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
4742
/* TODO: this should move to IOT issue area */
4743
if (rtw_get_chip_type(adapter) == RTL8812
4744
|| rtw_get_chip_type(adapter) == RTL8821
4745
) {
4746
if (MLME_IS_STA(adapter))
4747
Hal_PatchwithJaguar_8812(adapter, opmode);
4748
}
4749
#endif
4750
4751
SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
4752
if (macid_ind == 0)
4753
macid_end = macid;
4754
4755
for (i = macid; macid <= macid_end; macid++) {
4756
op_num_change_bmp |= rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
4757
if (!opmode) {
4758
rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
4759
rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
4760
rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
4761
rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
4762
}
4763
}
4764
4765
#if CONFIG_TX_AC_LIFETIME
4766
if (op_num_change_bmp)
4767
rtw_hal_update_tx_aclt(adapter);
4768
#endif
4769
4770
if (!opmode)
4771
rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
4772
4773
exit:
4774
return ret;
4775
}
4776
4777
inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
4778
{
4779
return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
4780
}
4781
4782
inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
4783
{
4784
return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
4785
}
4786
4787
void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4788
{
4789
u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
4790
u8 ret = 0;
4791
4792
RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
4793
rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
4794
rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
4795
rsvdpageloc->LocBTQosNull);
4796
4797
SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
4798
SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
4799
SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
4800
SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
4801
SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
4802
4803
ret = rtw_hal_fill_h2c_cmd(padapter,
4804
H2C_RSVD_PAGE,
4805
H2C_RSVDPAGE_LOC_LEN,
4806
u1H2CRsvdPageParm);
4807
4808
}
4809
4810
#ifdef CONFIG_GPIO_WAKEUP
4811
void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
4812
{
4813
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4814
4815
if (IS_8723D_SERIES(pHalData->version_id) || IS_8192F_SERIES(pHalData->version_id)
4816
|| IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id)
4817
|| IS_8822C_SERIES(pHalData->version_id))
4818
rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4819
/*
4820
* Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
4821
* It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
4822
* and implement HAL function.
4823
* TODO: GPIO_8 multi function?
4824
*/
4825
4826
if ((index == 13 || index == 14)
4827
#if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
4828
/* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
4829
&& (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
4830
#endif
4831
)
4832
rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4833
}
4834
4835
void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
4836
{
4837
#if defined(CONFIG_RTL8192F)
4838
rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&index));
4839
#else
4840
if (index <= 7) {
4841
/* config GPIO mode */
4842
rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4843
rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4844
4845
/* config GPIO Sel */
4846
/* 0: input */
4847
/* 1: output */
4848
rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4849
rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
4850
4851
/* set output value */
4852
if (outputval) {
4853
rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4854
rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
4855
} else {
4856
rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4857
rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
4858
}
4859
} else if (index <= 15) {
4860
/* 88C Series: */
4861
/* index: 11~8 transform to 3~0 */
4862
/* 8723 Series: */
4863
/* index: 12~8 transform to 4~0 */
4864
4865
index -= 8;
4866
4867
/* config GPIO mode */
4868
rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4869
rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4870
4871
/* config GPIO Sel */
4872
/* 0: input */
4873
/* 1: output */
4874
rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4875
rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
4876
4877
/* set output value */
4878
if (outputval) {
4879
rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4880
rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
4881
} else {
4882
rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4883
rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
4884
}
4885
} else {
4886
RTW_INFO("%s: invalid GPIO%d=%d\n",
4887
__FUNCTION__, index, outputval);
4888
}
4889
#endif
4890
}
4891
void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
4892
{
4893
#if defined(CONFIG_RTL8192F)
4894
rtw_hal_set_hwreg(padapter, HW_VAR_WOW_INPUT_GPIO, (u8 *)(&index));
4895
#else
4896
if (index <= 7) {
4897
/* config GPIO mode */
4898
rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4899
rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4900
4901
/* config GPIO Sel */
4902
/* 0: input */
4903
/* 1: output */
4904
rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4905
rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
4906
4907
} else if (index <= 15) {
4908
/* 88C Series: */
4909
/* index: 11~8 transform to 3~0 */
4910
/* 8723 Series: */
4911
/* index: 12~8 transform to 4~0 */
4912
4913
index -= 8;
4914
4915
/* config GPIO mode */
4916
rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4917
rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4918
4919
/* config GPIO Sel */
4920
/* 0: input */
4921
/* 1: output */
4922
rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4923
rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
4924
} else
4925
RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
4926
#endif
4927
}
4928
4929
#endif
4930
4931
void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4932
{
4933
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
4934
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4935
u8 ret = 0;
4936
#ifdef CONFIG_WOWLAN
4937
u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
4938
4939
RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
4940
__func__, rsvdpageloc->LocRemoteCtrlInfo,
4941
rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
4942
rsvdpageloc->LocNDPInfo);
4943
RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
4944
__func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
4945
rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
4946
4947
if (check_fwstate(pmlmepriv, _FW_LINKED)) {
4948
SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
4949
SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
4950
SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
4951
rsvdpageloc->LocNbrAdv);
4952
SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
4953
rsvdpageloc->LocNDPInfo);
4954
#ifdef CONFIG_GTK_OL
4955
SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
4956
SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
4957
SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
4958
#endif /* CONFIG_GTK_OL */
4959
ret = rtw_hal_fill_h2c_cmd(padapter,
4960
H2C_AOAC_RSVD_PAGE,
4961
H2C_AOAC_RSVDPAGE_LOC_LEN,
4962
u1H2CAoacRsvdPageParm);
4963
4964
RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
4965
_rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
4966
SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
4967
rsvdpageloc->LocAOACReport);
4968
ret = rtw_hal_fill_h2c_cmd(padapter,
4969
H2C_AOAC_RSVDPAGE3,
4970
H2C_AOAC_RSVDPAGE_LOC_LEN,
4971
u1H2CAoacRsvdPageParm);
4972
pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
4973
}
4974
#ifdef CONFIG_PNO_SUPPORT
4975
else {
4976
4977
if (!pwrpriv->wowlan_in_resume) {
4978
RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
4979
_rtw_memset(&u1H2CAoacRsvdPageParm, 0,
4980
sizeof(u1H2CAoacRsvdPageParm));
4981
SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
4982
rsvdpageloc->LocPNOInfo);
4983
ret = rtw_hal_fill_h2c_cmd(padapter,
4984
H2C_AOAC_RSVDPAGE3,
4985
H2C_AOAC_RSVDPAGE_LOC_LEN,
4986
u1H2CAoacRsvdPageParm);
4987
}
4988
}
4989
#endif /* CONFIG_PNO_SUPPORT */
4990
#endif /* CONFIG_WOWLAN */
4991
}
4992
4993
#ifdef DBG_FW_DEBUG_MSG_PKT
4994
void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4995
{
4996
struct hal_ops *pHalFunc = &padapter->hal_func;
4997
u8 u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};
4998
u8 ret = 0;
4999
5000
5001
RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);
5002
5003
SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);
5004
SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);
5005
ret = rtw_hal_fill_h2c_cmd(padapter,
5006
H2C_FW_DBG_MSG_PKT,
5007
H2C_FW_DBG_MSG_PKT_LEN,
5008
u1H2C_fw_dbg_msg_pkt_parm);
5009
5010
}
5011
#endif /*DBG_FW_DEBUG_MSG_PKT*/
5012
5013
/*#define DBG_GET_RSVD_PAGE*/
5014
int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
5015
u32 page_num, u8 *buffer, u32 buffer_size)
5016
{
5017
u32 addr = 0, size = 0, count = 0;
5018
u32 page_size = 0, data_low = 0, data_high = 0;
5019
u16 txbndy = 0, offset = 0;
5020
u8 i = 0;
5021
bool rst = _FALSE;
5022
5023
#ifdef DBG_LA_MODE
5024
struct registry_priv *registry_par = &adapter->registrypriv;
5025
5026
if(registry_par->la_mode_en == 1) {
5027
RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);
5028
return rst;
5029
}
5030
#endif
5031
rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5032
5033
addr = page_offset * page_size;
5034
size = page_num * page_size;
5035
5036
if (buffer_size < size) {
5037
RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
5038
__func__, buffer_size, size);
5039
return rst;
5040
}
5041
#ifdef RTW_HALMAC
5042
if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
5043
rst = _FALSE;
5044
else
5045
rst = _TRUE;
5046
#else
5047
txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
5048
5049
offset = (txbndy + page_offset) * page_size / 8;
5050
count = (buffer_size / 8) + 1;
5051
5052
rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
5053
5054
for (i = 0 ; i < count ; i++) {
5055
rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
5056
data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
5057
data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
5058
_rtw_memcpy(buffer + (i * 8),
5059
&data_low, sizeof(data_low));
5060
_rtw_memcpy(buffer + ((i * 8) + 4),
5061
&data_high, sizeof(data_high));
5062
}
5063
rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
5064
rst = _TRUE;
5065
#endif /*RTW_HALMAC*/
5066
5067
#ifdef DBG_GET_RSVD_PAGE
5068
RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
5069
__func__, page_offset, page_num, addr, size);
5070
RTW_INFO_DUMP("\n", buffer, size);
5071
RTW_INFO(" ==================================================\n");
5072
#endif
5073
return rst;
5074
}
5075
5076
void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
5077
{
5078
u32 page_size = 0;
5079
u8 *buffer = NULL;
5080
u32 buf_size = 0;
5081
5082
if (page_num == 0)
5083
return;
5084
5085
RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");
5086
RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
5087
5088
rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5089
if (page_size) {
5090
buf_size = page_size * page_num;
5091
buffer = rtw_zvmalloc(buf_size);
5092
5093
if (buffer) {
5094
rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
5095
RTW_DUMP_SEL(sel, buffer, buf_size);
5096
rtw_vmfree(buffer, buf_size);
5097
} else
5098
RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
5099
} else
5100
RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
5101
5102
RTW_PRINT_SEL(sel, "==========================\n");
5103
}
5104
5105
#ifdef CONFIG_SUPPORT_FIFO_DUMP
5106
void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
5107
{
5108
u8 *buffer = NULL;
5109
u32 buff_size = 0;
5110
static const char * const fifo_sel_str[] = {
5111
"TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
5112
};
5113
5114
if (fifo_sel > 5) {
5115
RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
5116
return;
5117
}
5118
5119
RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
5120
RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
5121
5122
if (fifo_size) {
5123
buff_size = RND4(fifo_size);
5124
buffer = rtw_zvmalloc(buff_size);
5125
if (buffer == NULL)
5126
buff_size = 0;
5127
}
5128
5129
rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
5130
5131
if (buffer) {
5132
RTW_DUMP_SEL(sel, buffer, fifo_size);
5133
rtw_vmfree(buffer, buff_size);
5134
}
5135
5136
RTW_PRINT_SEL(sel, "==========================\n");
5137
}
5138
#endif
5139
5140
#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
5141
static void rtw_hal_force_enable_rxdma(_adapter *adapter)
5142
{
5143
RTW_INFO("%s: Set 0x690=0x00\n", __func__);
5144
rtw_write8(adapter, REG_WOW_CTRL,
5145
(rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
5146
RTW_PRINT("%s: Release RXDMA\n", __func__);
5147
rtw_write32(adapter, REG_RXPKT_NUM,
5148
(rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
5149
}
5150
#if defined(CONFIG_RTL8188E)
5151
static void rtw_hal_disable_tx_report(_adapter *adapter)
5152
{
5153
rtw_write8(adapter, REG_TX_RPT_CTRL,
5154
((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
5155
RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5156
}
5157
5158
static void rtw_hal_enable_tx_report(_adapter *adapter)
5159
{
5160
rtw_write8(adapter, REG_TX_RPT_CTRL,
5161
((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
5162
RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5163
}
5164
#endif
5165
static void rtw_hal_release_rx_dma(_adapter *adapter)
5166
{
5167
u32 val32 = 0;
5168
5169
val32 = rtw_read32(adapter, REG_RXPKT_NUM);
5170
5171
rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
5172
5173
RTW_INFO("%s, [0x%04x]: 0x%08x\n",
5174
__func__, REG_RXPKT_NUM, (u32)(val32 & (~RW_RELEASE_EN)));
5175
}
5176
5177
static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
5178
{
5179
PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
5180
u8 ret = 0;
5181
s8 trycnt = 100;
5182
u32 tmp = 0;
5183
int res = 0;
5184
/* RX DMA stop */
5185
RTW_PRINT("Pause DMA\n");
5186
rtw_write32(adapter, REG_RXPKT_NUM,
5187
(rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
5188
do {
5189
if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
5190
#ifdef CONFIG_USB_HCI
5191
/* stop interface before leave */
5192
if (_TRUE == hal->usb_intf_start) {
5193
rtw_intf_stop(adapter);
5194
RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
5195
RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
5196
}
5197
#endif /* CONFIG_USB_HCI */
5198
5199
RTW_PRINT("RX_DMA_IDLE is true\n");
5200
ret = _SUCCESS;
5201
break;
5202
}
5203
#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5204
else {
5205
res = RecvOnePkt(adapter);
5206
RTW_PRINT("RecvOnePkt Result: %d\n", res);
5207
}
5208
#endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
5209
5210
#ifdef CONFIG_USB_HCI
5211
else {
5212
/* to avoid interface start repeatedly */
5213
if (_FALSE == hal->usb_intf_start)
5214
rtw_intf_start(adapter);
5215
}
5216
#endif /* CONFIG_USB_HCI */
5217
} while (trycnt--);
5218
5219
if (trycnt < 0) {
5220
tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
5221
5222
RTW_PRINT("Stop RX DMA failed......\n");
5223
#if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
5224
RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
5225
__func__, rtw_read16(adapter, REG_RXPKTNUM));
5226
#else
5227
RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
5228
__func__, ((tmp & 0xFF00) >> 8));
5229
#endif
5230
if (tmp & BIT(3))
5231
RTW_PRINT("%s, RX DMA has req\n",
5232
__func__);
5233
else
5234
RTW_PRINT("%s, RX DMA no req\n",
5235
__func__);
5236
ret = _FAIL;
5237
}
5238
5239
return ret;
5240
}
5241
5242
#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5243
#ifndef RTW_HALMAC
5244
static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
5245
{
5246
u8 ret = 0;
5247
int res = 0;
5248
u32 tmp = 0;
5249
#ifdef CONFIG_GPIO_WAKEUP
5250
return _SUCCESS;
5251
#else
5252
RTW_PRINT("%s\n", __func__);
5253
5254
res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5255
if (!res)
5256
RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
5257
else
5258
RTW_INFO("sdio_local_read fail\n");
5259
5260
tmp = SDIO_HIMR_CPWM2_MSK;
5261
5262
res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5263
5264
if (!res) {
5265
res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5266
RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
5267
ret = _SUCCESS;
5268
} else {
5269
RTW_INFO("sdio_local_write fail\n");
5270
ret = _FAIL;
5271
}
5272
return ret;
5273
#endif /* CONFIG_CPIO_WAKEUP */
5274
}
5275
#endif
5276
#endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
5277
#endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
5278
5279
#ifdef CONFIG_WOWLAN
5280
/*
5281
* rtw_hal_check_wow_ctrl
5282
* chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
5283
* If 0x1C7 == 0 (for 3081), WOW enable successful.
5284
* _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
5285
* If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
5286
*/
5287
static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
5288
{
5289
u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
5290
u8 mstatus = 0;
5291
u8 reason = 0xFF;
5292
u8 trycnt = 25;
5293
u8 res = _FALSE;
5294
5295
if (IS_HARDWARE_TYPE_JAGUAR2(adapter) || IS_HARDWARE_TYPE_JAGUAR3(adapter)) {
5296
if (chk_type) {
5297
reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5298
RTW_INFO("%s reason:0x%02x\n", __func__, reason);
5299
5300
while (reason && trycnt > 1) {
5301
reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5302
RTW_PRINT("Loop index: %d :0x%02x\n",
5303
trycnt, reason);
5304
trycnt--;
5305
rtw_msleep_os(20);
5306
}
5307
if (!reason)
5308
res = _TRUE;
5309
else
5310
res = _FALSE;
5311
} else {
5312
/* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
5313
fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
5314
rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
5315
RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
5316
5317
while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
5318
rtw_msleep_os(20);
5319
fe1_imr = rtw_read32(adapter, REG_FE1IMR);
5320
rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
5321
RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
5322
trycnt, fe1_imr, rxpkt_num);
5323
trycnt--;
5324
}
5325
5326
if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
5327
res = _FALSE;
5328
else
5329
res = _TRUE;
5330
}
5331
} else {
5332
mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5333
RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
5334
5335
5336
if (chk_type) {
5337
while (!(mstatus & BIT1) && trycnt > 1) {
5338
mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5339
RTW_PRINT("Loop index: %d :0x%02x\n",
5340
trycnt, mstatus);
5341
trycnt--;
5342
rtw_msleep_os(20);
5343
}
5344
if (mstatus & BIT1)
5345
res = _TRUE;
5346
else
5347
res = _FALSE;
5348
} else {
5349
while (mstatus & BIT1 && trycnt > 1) {
5350
mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5351
RTW_PRINT("Loop index: %d :0x%02x\n",
5352
trycnt, mstatus);
5353
trycnt--;
5354
rtw_msleep_os(20);
5355
}
5356
5357
if (mstatus & BIT1)
5358
res = _FALSE;
5359
else
5360
res = _TRUE;
5361
}
5362
}
5363
5364
RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
5365
__func__, chk_type, res, (25 - trycnt));
5366
return res;
5367
}
5368
5369
#ifdef CONFIG_PNO_SUPPORT
5370
static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
5371
{
5372
struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5373
u8 res = 0, count = 0;
5374
u8 ret = _FALSE;
5375
5376
if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
5377
res = rtw_read8(adapter, REG_PNO_STATUS);
5378
while (!(res & BIT(7)) && count < 25) {
5379
RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
5380
count, res);
5381
res = rtw_read8(adapter, REG_PNO_STATUS);
5382
count++;
5383
rtw_msleep_os(2);
5384
}
5385
if (res & BIT(7))
5386
ret = _TRUE;
5387
else
5388
ret = _FALSE;
5389
RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
5390
}
5391
return ret;
5392
}
5393
#endif
5394
5395
static void rtw_hal_backup_rate(_adapter *adapter)
5396
{
5397
RTW_INFO("%s\n", __func__);
5398
/* backup data rate to register 0x8b for wowlan FW */
5399
rtw_write8(adapter, 0x8d, 1);
5400
rtw_write8(adapter, 0x8c, 0);
5401
rtw_write8(adapter, 0x8f, 0x40);
5402
rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
5403
}
5404
5405
#ifdef CONFIG_GTK_OL
5406
static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
5407
{
5408
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5409
int cam_id, index = 0;
5410
u8 *addr = NULL;
5411
5412
if (!MLME_IS_STA(adapter))
5413
return;
5414
5415
addr = get_bssid(pmlmepriv);
5416
5417
if (addr == NULL) {
5418
RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
5419
return;
5420
}
5421
5422
rtw_clean_dk_section(adapter);
5423
5424
do {
5425
cam_id = rtw_camid_search(adapter, addr, index, 1);
5426
5427
if (cam_id == -1)
5428
RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
5429
else
5430
rtw_sec_cam_swap(adapter, cam_id, index);
5431
5432
index++;
5433
} while (index < 4);
5434
5435
rtw_write8(adapter, REG_SECCFG, 0xcc);
5436
}
5437
5438
static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
5439
{
5440
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5441
struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5442
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5443
struct security_priv *psecuritypriv = &adapter->securitypriv;
5444
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5445
struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
5446
_irqL irqL;
5447
u8 get_key[16];
5448
u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;
5449
u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
5450
5451
if (!MLME_IS_STA(adapter))
5452
return;
5453
5454
_rtw_memset(get_key, 0, sizeof(get_key));
5455
_rtw_memcpy(&replay_count,
5456
paoac_rpt->replay_counter_eapol_key, 8);
5457
5458
/*read gtk key index*/
5459
gtk_id = paoac_rpt->key_index;
5460
aoac_rpt_ver = paoac_rpt->version_info;
5461
5462
if (aoac_rpt_ver == 0) {
5463
/* initial verison */
5464
if (gtk_id == 5)
5465
has_rekey = _FALSE;
5466
else
5467
has_rekey = _TRUE;
5468
} else if (aoac_rpt_ver >= 1) {
5469
/* Add krack patch */
5470
if (gtk_id == 5)
5471
RTW_WARN("%s FW check iv fail\n", __func__);
5472
5473
if (aoac_rpt_ver == 1)
5474
RTW_WARN("%s aoac report version should be update to v2\n", __func__);
5475
5476
/* Fix key id mismatch */
5477
if (aoac_rpt_ver == 2)
5478
has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;
5479
}
5480
5481
if (has_rekey == _FALSE) {
5482
RTW_INFO("%s no rekey event happened.\n", __func__);
5483
} else if (has_rekey == _TRUE) {
5484
RTW_INFO("%s update security key.\n", __func__);
5485
/*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
5486
rtw_sec_read_cam_ent(adapter, gtk_id,
5487
NULL, NULL, get_key);
5488
rtw_clean_hw_dk_cam(adapter);
5489
5490
if (_rtw_camid_is_gk(adapter, gtk_id)) {
5491
_enter_critical_bh(&cam_ctl->lock, &irqL);
5492
_rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
5493
get_key, 16);
5494
_exit_critical_bh(&cam_ctl->lock, &irqL);
5495
} else {
5496
struct setkey_parm parm_gtk;
5497
5498
parm_gtk.algorithm = paoac_rpt->security_type;
5499
parm_gtk.keyid = gtk_id;
5500
_rtw_memcpy(parm_gtk.key, get_key, 16);
5501
setkey_hdl(adapter, (u8 *)&parm_gtk);
5502
}
5503
5504
/*update key into related sw variable and sec-cam cache*/
5505
psecuritypriv->dot118021XGrpKeyid = gtk_id;
5506
_rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
5507
get_key, 16);
5508
/* update SW TKIP TX/RX MIC value */
5509
if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
5510
offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
5511
_rtw_memcpy(
5512
&psecuritypriv->dot118021XGrptxmickey[gtk_id],
5513
&(paoac_rpt->group_key[offset]),
5514
RTW_TKIP_MIC_LEN);
5515
5516
offset = RTW_KEK_LEN;
5517
_rtw_memcpy(
5518
&psecuritypriv->dot118021XGrprxmickey[gtk_id],
5519
&(paoac_rpt->group_key[offset]),
5520
RTW_TKIP_MIC_LEN);
5521
}
5522
RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
5523
KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
5524
}
5525
5526
/* Update broadcast RX IV */
5527
if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
5528
sz = sizeof(psecuritypriv->iv_seq[0]);
5529
for (i = 0 ; i < 4 ; i++) {
5530
_rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
5531
tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
5532
pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
5533
_rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
5534
}
5535
}
5536
5537
rtw_clean_dk_section(adapter);
5538
5539
rtw_write8(adapter, REG_SECCFG, 0x0c);
5540
5541
#ifdef CONFIG_GTK_OL_DBG
5542
/* if (gtk_keyindex != 5) */
5543
dump_sec_cam(RTW_DBGDUMP, adapter);
5544
dump_sec_cam_cache(RTW_DBGDUMP, adapter);
5545
#endif
5546
}
5547
#endif /*CONFIG_GTK_OL*/
5548
5549
static void rtw_dump_aoac_rpt(_adapter *adapter)
5550
{
5551
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5552
struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5553
int i = 0;
5554
5555
RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
5556
RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
5557
paoac_rpt->replay_counter_eapol_key, 8);
5558
RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
5559
RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
5560
RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
5561
RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
5562
paoac_rpt->wow_pattern_idx);
5563
RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
5564
RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);
5565
RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
5566
RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
5567
RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
5568
RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
5569
RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
5570
}
5571
5572
static void rtw_hal_get_aoac_rpt(_adapter *adapter)
5573
{
5574
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5575
struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5576
u32 page_offset = 0, page_number = 0;
5577
u32 page_size = 0, buf_size = 0;
5578
u8 *buffer = NULL;
5579
u8 i = 0, tmp = 0;
5580
int ret = -1;
5581
5582
/* read aoac report from rsvd page */
5583
page_offset = pwrctl->wowlan_aoac_rpt_loc;
5584
page_number = 1;
5585
5586
rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5587
buf_size = page_size * page_number;
5588
5589
buffer = rtw_zvmalloc(buf_size);
5590
5591
if (buffer == NULL) {
5592
RTW_ERR("%s buffer allocate failed size(%d)\n",
5593
__func__, buf_size);
5594
return;
5595
}
5596
5597
RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
5598
5599
ret = rtw_hal_get_rsvd_page(adapter, page_offset,
5600
page_number, buffer, buf_size);
5601
5602
if (ret == _FALSE) {
5603
RTW_ERR("%s get aoac report failed\n", __func__);
5604
rtw_warn_on(1);
5605
goto _exit;
5606
}
5607
5608
_rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
5609
_rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
5610
5611
for (i = 0 ; i < 4 ; i++) {
5612
tmp = paoac_rpt->replay_counter_eapol_key[i];
5613
paoac_rpt->replay_counter_eapol_key[i] =
5614
paoac_rpt->replay_counter_eapol_key[7 - i];
5615
paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
5616
}
5617
5618
rtw_dump_aoac_rpt(adapter);
5619
5620
_exit:
5621
if (buffer)
5622
rtw_vmfree(buffer, buf_size);
5623
}
5624
5625
static void rtw_hal_update_tx_iv(_adapter *adapter)
5626
{
5627
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5628
struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5629
struct sta_info *psta;
5630
struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
5631
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5632
struct security_priv *psecpriv = &adapter->securitypriv;
5633
5634
u16 val16 = 0;
5635
u32 val32 = 0;
5636
u64 txiv = 0;
5637
u8 *pval = NULL;
5638
5639
psta = rtw_get_stainfo(&adapter->stapriv,
5640
get_my_bssid(&pmlmeinfo->network));
5641
5642
/* Update TX iv data. */
5643
pval = (u8 *)&paoac_rpt->iv;
5644
5645
if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
5646
val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
5647
((u16)(paoac_rpt->iv[0]) << 8);
5648
val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5649
((u32)(paoac_rpt->iv[5]) << 8) +
5650
((u32)(paoac_rpt->iv[6]) << 16) +
5651
((u32)(paoac_rpt->iv[7]) << 24);
5652
} else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
5653
val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
5654
((u16)(paoac_rpt->iv[1]) << 8);
5655
val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5656
((u32)(paoac_rpt->iv[5]) << 8) +
5657
((u32)(paoac_rpt->iv[6]) << 16) +
5658
((u32)(paoac_rpt->iv[7]) << 24);
5659
}
5660
5661
if (psta) {
5662
txiv = val16 + ((u64)val32 << 16);
5663
if (txiv != 0)
5664
psta->dot11txpn.val = txiv;
5665
}
5666
}
5667
5668
static void rtw_hal_update_sw_security_info(_adapter *adapter)
5669
{
5670
struct security_priv *psecpriv = &adapter->securitypriv;
5671
u8 sz = sizeof (psecpriv->iv_seq);
5672
5673
rtw_hal_update_tx_iv(adapter);
5674
#ifdef CONFIG_GTK_OL
5675
if (psecpriv->binstallKCK_KEK == _TRUE &&
5676
psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)
5677
rtw_hal_update_gtk_offload_info(adapter);
5678
#else
5679
_rtw_memset(psecpriv->iv_seq, 0, sz);
5680
#endif
5681
}
5682
5683
static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
5684
{
5685
u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
5686
u8 adopt = 1, check_period = 5;
5687
u8 ret = _FAIL;
5688
u8 hw_port = rtw_hal_get_port(adapter);
5689
5690
SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
5691
SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
5692
SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
5693
SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
5694
#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5695
SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);
5696
RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5697
#else
5698
RTW_INFO("%s(): enable = %d\n", __func__, enable);
5699
#endif
5700
ret = rtw_hal_fill_h2c_cmd(adapter,
5701
H2C_KEEP_ALIVE,
5702
H2C_KEEP_ALIVE_CTRL_LEN,
5703
u1H2CKeepAliveParm);
5704
5705
return ret;
5706
}
5707
5708
static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
5709
{
5710
u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
5711
u8 adopt = 1, check_period = 30, trypkt_num = 5;
5712
u8 ret = _FAIL;
5713
u8 hw_port = rtw_hal_get_port(adapter);
5714
5715
SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
5716
SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
5717
/* SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt); */
5718
SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
5719
SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
5720
#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5721
SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);
5722
RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5723
#else
5724
RTW_INFO("%s(): enable = %d\n", __func__, enable);
5725
#endif
5726
5727
ret = rtw_hal_fill_h2c_cmd(adapter,
5728
H2C_DISCON_DECISION,
5729
H2C_DISCON_DECISION_LEN,
5730
u1H2CDisconDecisionParm);
5731
return ret;
5732
}
5733
5734
static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
5735
{
5736
struct registry_priv *registry_par = &adapter->registrypriv;
5737
struct security_priv *psecpriv = &adapter->securitypriv;
5738
struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5739
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5740
5741
u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
5742
u8 discont_wake = 0, gpionum = 0, gpio_dur = 0, no_wake = 0;
5743
u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
5744
u8 sdio_wakeup_enable = 1;
5745
u8 gpio_high_active = 0;
5746
u8 magic_pkt = 0;
5747
u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
5748
u8 ret = _FAIL;
5749
#ifdef CONFIG_DIS_UPHY
5750
u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;
5751
#endif /* CONFIG_DIS_UPHY */
5752
5753
#ifdef CONFIG_GPIO_WAKEUP
5754
gpio_high_active = ppwrpriv->is_high_active;
5755
gpionum = WAKEUP_GPIO_IDX;
5756
sdio_wakeup_enable = 0;
5757
#endif /* CONFIG_GPIO_WAKEUP */
5758
5759
if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
5760
!check_fwstate(pmlmepriv, _FW_LINKED))
5761
no_wake = 1;
5762
5763
if (!ppwrpriv->wowlan_pno_enable &&
5764
registry_par->wakeup_event & BIT(0) && !no_wake)
5765
magic_pkt = enable;
5766
5767
if ((registry_par->wakeup_event & BIT(1)) &&
5768
(psecpriv->dot11PrivacyAlgrthm == _WEP40_ ||
5769
psecpriv->dot11PrivacyAlgrthm == _WEP104_) && !no_wake)
5770
hw_unicast = 1;
5771
5772
if (registry_par->wakeup_event & BIT(2) && !no_wake)
5773
discont_wake = enable;
5774
5775
RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
5776
enable, change_unit);
5777
5778
/* time = (gpio_dur/2) * gpio_unit, default:256 ms */
5779
if (enable && change_unit) {
5780
gpio_dur = 0x40;
5781
gpio_unit = 1;
5782
gpio_pulse_en = 1;
5783
}
5784
5785
#ifdef CONFIG_PLATFORM_ARM_RK3188
5786
if (enable) {
5787
gpio_pulse_en = 1;
5788
gpio_pulse_cnt = 0x04;
5789
}
5790
#endif
5791
5792
SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
5793
if(!no_wake)
5794
SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
5795
SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
5796
SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
5797
SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
5798
SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
5799
5800
#ifdef CONFIG_GTK_OL
5801
if (psecpriv->binstallKCK_KEK == _TRUE &&
5802
psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)
5803
SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
5804
else
5805
SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
5806
#else
5807
SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
5808
#endif
5809
SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
5810
SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
5811
SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
5812
5813
SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
5814
SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
5815
5816
SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
5817
SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
5818
5819
#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
5820
if (enable)
5821
SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5822
#endif
5823
5824
#ifdef CONFIG_DIS_UPHY
5825
if (enable) {
5826
dis_uphy = 1;
5827
/* time unit: 0 -> ms, 1 -> 256 ms*/
5828
dis_uphy_unit = 1;
5829
dis_uphy_time = 0x4;
5830
}
5831
5832
SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
5833
SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
5834
SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
5835
if (ppwrpriv->hst2dev_high_active == 1)
5836
SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
5837
#ifdef CONFIG_RTW_ONE_PIN_GPIO
5838
SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5839
SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
5840
SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
5841
#else
5842
SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
5843
#endif /* CONFIG_RTW_ONE_PIN_GPIO */
5844
#endif /* CONFIG_DIS_UPHY */
5845
5846
5847
ret = rtw_hal_fill_h2c_cmd(adapter,
5848
H2C_WOWLAN,
5849
H2C_WOWLAN_LEN,
5850
u1H2CWoWlanCtrlParm);
5851
return ret;
5852
}
5853
5854
static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
5855
{
5856
struct security_priv *psecuritypriv = &(adapter->securitypriv);
5857
struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5858
struct registry_priv *pregistrypriv = &adapter->registrypriv;
5859
u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
5860
u8 ret = _FAIL, count = 0, no_wake = 0;
5861
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5862
5863
RTW_INFO("%s(): enable=%d\n", __func__, enable);
5864
5865
if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&
5866
!check_fwstate(pmlmepriv, _FW_LINKED))
5867
no_wake = 1;
5868
if(no_wake) {
5869
SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5870
u1H2CRemoteWakeCtrlParm, enable);
5871
} else {
5872
if (!ppwrpriv->wowlan_pno_enable) {
5873
SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5874
u1H2CRemoteWakeCtrlParm, enable);
5875
SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5876
u1H2CRemoteWakeCtrlParm, 1);
5877
#ifdef CONFIG_GTK_OL
5878
if (psecuritypriv->binstallKCK_KEK == _TRUE &&
5879
psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
5880
SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5881
u1H2CRemoteWakeCtrlParm, 1);
5882
} else {
5883
RTW_INFO("no kck kek\n");
5884
SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5885
u1H2CRemoteWakeCtrlParm, 0);
5886
}
5887
#endif /* CONFIG_GTK_OL */
5888
5889
#ifdef CONFIG_IPV6
5890
if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
5891
RTW_INFO("enable NS offload\n");
5892
SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
5893
u1H2CRemoteWakeCtrlParm, enable);
5894
}
5895
5896
/*
5897
* filter NetBios name service pkt to avoid being waked-up
5898
* by this kind of unicast pkt this exceptional modification
5899
* is used for match competitor's behavior
5900
*/
5901
5902
SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
5903
u1H2CRemoteWakeCtrlParm, enable);
5904
#endif /*CONFIG_IPV6*/
5905
5906
#ifdef CONFIG_RTL8192F
5907
if (IS_HARDWARE_TYPE_8192F(adapter)){
5908
SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
5909
u1H2CRemoteWakeCtrlParm, enable);
5910
}
5911
#endif /* CONFIG_RTL8192F */
5912
5913
if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
5914
(psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
5915
(psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
5916
SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5917
u1H2CRemoteWakeCtrlParm, 0);
5918
} else {
5919
SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5920
u1H2CRemoteWakeCtrlParm, 1);
5921
}
5922
5923
if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_ &&
5924
psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
5925
SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5926
u1H2CRemoteWakeCtrlParm, enable);
5927
5928
if (IS_HARDWARE_TYPE_8188E(adapter) ||
5929
IS_HARDWARE_TYPE_8812(adapter)) {
5930
SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5931
u1H2CRemoteWakeCtrlParm, 0);
5932
SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5933
u1H2CRemoteWakeCtrlParm, 1);
5934
}
5935
}
5936
5937
SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
5938
u1H2CRemoteWakeCtrlParm, 1);
5939
}
5940
#ifdef CONFIG_PNO_SUPPORT
5941
else {
5942
SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5943
u1H2CRemoteWakeCtrlParm, enable);
5944
SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
5945
u1H2CRemoteWakeCtrlParm, enable);
5946
}
5947
#endif
5948
5949
#ifdef CONFIG_P2P_WOWLAN
5950
if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
5951
RTW_INFO("P2P OFFLOAD ENABLE\n");
5952
SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
5953
} else {
5954
RTW_INFO("P2P OFFLOAD DISABLE\n");
5955
SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
5956
}
5957
#endif /* CONFIG_P2P_WOWLAN */
5958
}
5959
5960
5961
ret = rtw_hal_fill_h2c_cmd(adapter,
5962
H2C_REMOTE_WAKE_CTRL,
5963
H2C_REMOTE_WAKE_CTRL_LEN,
5964
u1H2CRemoteWakeCtrlParm);
5965
return ret;
5966
}
5967
5968
static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
5969
{
5970
u8 ret = _FAIL;
5971
u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
5972
5973
RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
5974
__func__, group_alg, pairwise_alg);
5975
SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
5976
pairwise_alg);
5977
SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
5978
group_alg);
5979
5980
ret = rtw_hal_fill_h2c_cmd(adapter,
5981
H2C_AOAC_GLOBAL_INFO,
5982
H2C_AOAC_GLOBAL_INFO_LEN,
5983
u1H2CAOACGlobalInfoParm);
5984
5985
return ret;
5986
}
5987
5988
#ifdef CONFIG_PNO_SUPPORT
5989
static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
5990
PRSVDPAGE_LOC rsvdpageloc, u8 enable)
5991
{
5992
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
5993
u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
5994
u8 res = 0, count = 0, ret = _FAIL;
5995
5996
RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
5997
__func__, rsvdpageloc->LocProbePacket,
5998
rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
5999
6000
SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
6001
SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
6002
SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
6003
rsvdpageloc->LocScanInfo);
6004
SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
6005
rsvdpageloc->LocProbePacket);
6006
/*
6007
SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
6008
rsvdpageloc->LocSSIDInfo);
6009
*/
6010
ret = rtw_hal_fill_h2c_cmd(adapter,
6011
H2C_D0_SCAN_OFFLOAD_INFO,
6012
H2C_SCAN_OFFLOAD_CTRL_LEN,
6013
u1H2CScanOffloadInfoParm);
6014
return ret;
6015
}
6016
#endif /* CONFIG_PNO_SUPPORT */
6017
6018
void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
6019
{
6020
struct security_priv *psecpriv = &padapter->securitypriv;
6021
struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
6022
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6023
struct registry_priv *pregistry = &padapter->registrypriv;
6024
u8 pkt_type = 0, no_wake = 0;
6025
6026
if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&
6027
!check_fwstate(pmlmepriv, _FW_LINKED))
6028
no_wake = 1;
6029
6030
RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
6031
6032
rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
6033
6034
if (enable) {
6035
if(!no_wake)
6036
rtw_hal_set_global_info_cmd(padapter,
6037
psecpriv->dot118021XGrpPrivacy,
6038
psecpriv->dot11PrivacyAlgrthm);
6039
6040
if (!(ppwrpriv->wowlan_pno_enable)) {
6041
if (pregistry->wakeup_event & BIT(2) && !no_wake)
6042
rtw_hal_set_disconnect_decision_cmd(padapter,
6043
enable);
6044
#ifdef CONFIG_ARP_KEEP_ALIVE
6045
if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
6046
(psecpriv->dot11PrivacyAlgrthm == _WEP104_))
6047
pkt_type = 0;
6048
else
6049
pkt_type = 1;
6050
#else
6051
pkt_type = 0;
6052
#endif /* CONFIG_ARP_KEEP_ALIVE */
6053
if(!no_wake)
6054
rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
6055
}
6056
rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
6057
#ifdef CONFIG_PNO_SUPPORT
6058
rtw_hal_check_pno_enabled(padapter);
6059
#endif /* CONFIG_PNO_SUPPORT */
6060
} else {
6061
#if 0
6062
{
6063
u32 PageSize = 0;
6064
rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
6065
dump_TX_FIFO(padapter, 4, PageSize);
6066
}
6067
#endif
6068
6069
rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
6070
}
6071
RTW_PRINT("-%s()-\n", __func__);
6072
}
6073
#endif /* CONFIG_WOWLAN */
6074
6075
#ifdef CONFIG_AP_WOWLAN
6076
static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
6077
{
6078
struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6079
6080
u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
6081
u8 gpionum = 0, gpio_dur = 0;
6082
u8 gpio_pulse = enable;
6083
u8 sdio_wakeup_enable = 1;
6084
u8 gpio_high_active = 0;
6085
u8 ret = _FAIL;
6086
6087
#ifdef CONFIG_GPIO_WAKEUP
6088
gpio_high_active = ppwrpriv->is_high_active;
6089
gpionum = WAKEUP_GPIO_IDX;
6090
sdio_wakeup_enable = 0;
6091
#endif /*CONFIG_GPIO_WAKEUP*/
6092
6093
RTW_INFO("%s(): enable=%d\n", __func__, enable);
6094
6095
SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
6096
gpionum);
6097
SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
6098
gpio_pulse);
6099
SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
6100
gpio_high_active);
6101
SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
6102
enable);
6103
SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
6104
gpio_dur);
6105
6106
ret = rtw_hal_fill_h2c_cmd(adapter,
6107
H2C_AP_WOW_GPIO_CTRL,
6108
H2C_AP_WOW_GPIO_CTRL_LEN,
6109
u1H2CAPWoWlanCtrlParm);
6110
6111
return ret;
6112
}
6113
6114
static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6115
{
6116
u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
6117
u8 ret = _FAIL;
6118
6119
RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
6120
6121
SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
6122
6123
ret = rtw_hal_fill_h2c_cmd(adapter,
6124
H2C_AP_OFFLOAD,
6125
H2C_AP_OFFLOAD_LEN,
6126
u1H2CAPOffloadCtrlParm);
6127
6128
return ret;
6129
}
6130
6131
static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
6132
{
6133
u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
6134
u8 ret = _FAIL;
6135
6136
RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
6137
6138
SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
6139
#ifndef CONFIG_USB_HCI
6140
SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
6141
#endif /*CONFIG_USB_HCI*/
6142
SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
6143
6144
if (enable)
6145
SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
6146
else
6147
SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
6148
6149
ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
6150
H2C_AP_PS_LEN, ap_ps_parm);
6151
6152
return ret;
6153
}
6154
6155
static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
6156
PRSVDPAGE_LOC rsvdpageloc)
6157
{
6158
struct hal_ops *pHalFunc = &padapter->hal_func;
6159
u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
6160
u8 ret = _FAIL, header = 0;
6161
6162
if (pHalFunc->fill_h2c_cmd == NULL) {
6163
RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
6164
return;
6165
}
6166
6167
header = rtw_read8(padapter, REG_BCNQ_BDNY);
6168
6169
RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
6170
rsvdpageloc->LocApOffloadBCN,
6171
rsvdpageloc->LocProbeRsp,
6172
header);
6173
6174
SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
6175
rsvdpageloc->LocApOffloadBCN + header);
6176
6177
ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
6178
H2C_BCN_RSVDPAGE_LEN, rsvdparm);
6179
6180
if (ret == _FAIL)
6181
RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
6182
6183
rtw_msleep_os(10);
6184
6185
_rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
6186
6187
SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
6188
rsvdpageloc->LocProbeRsp + header);
6189
6190
ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
6191
H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
6192
6193
if (ret == _FAIL)
6194
RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
6195
6196
rtw_msleep_os(10);
6197
}
6198
6199
static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
6200
{
6201
rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
6202
rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
6203
rtw_hal_set_ap_ps_cmd(padapter, enable);
6204
}
6205
6206
static void rtw_hal_ap_wow_enable(_adapter *padapter)
6207
{
6208
struct security_priv *psecuritypriv = &padapter->securitypriv;
6209
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6210
struct sta_info *psta = NULL;
6211
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6212
#ifdef DBG_CHECK_FW_PS_STATE
6213
struct dvobj_priv *psdpriv = padapter->dvobj;
6214
struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6215
#endif /*DBG_CHECK_FW_PS_STATE*/
6216
int res;
6217
u16 media_status_rpt;
6218
6219
RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
6220
#ifdef DBG_CHECK_FW_PS_STATE
6221
if (rtw_fw_ps_state(padapter) == _FAIL) {
6222
pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
6223
RTW_PRINT("wowlan enable no leave 32k\n");
6224
}
6225
#endif /*DBG_CHECK_FW_PS_STATE*/
6226
6227
/* 1. Download WOWLAN FW*/
6228
rtw_hal_fw_dl(padapter, _TRUE);
6229
6230
media_status_rpt = RT_MEDIA_CONNECT;
6231
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6232
(u8 *)&media_status_rpt);
6233
6234
issue_beacon(padapter, 0);
6235
6236
rtw_msleep_os(2);
6237
#if defined(CONFIG_RTL8188E)
6238
if (IS_HARDWARE_TYPE_8188E(padapter))
6239
rtw_hal_disable_tx_report(padapter);
6240
#endif
6241
/* RX DMA stop */
6242
res = rtw_hal_pause_rx_dma(padapter);
6243
if (res == _FAIL)
6244
RTW_PRINT("[WARNING] pause RX DMA fail\n");
6245
6246
#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6247
/* Enable CPWM2 only. */
6248
res = rtw_hal_enable_cpwm2(padapter);
6249
if (res == _FAIL)
6250
RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6251
#endif
6252
6253
#ifdef CONFIG_GPIO_WAKEUP
6254
rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE);
6255
#endif
6256
/* 5. Set Enable WOWLAN H2C command. */
6257
RTW_PRINT("Set Enable AP WOWLan cmd\n");
6258
rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
6259
6260
rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
6261
#ifdef CONFIG_USB_HCI
6262
rtw_mi_intf_stop(padapter);
6263
#endif
6264
#if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
6265
/* Invoid SE0 reset signal during suspending*/
6266
rtw_write8(padapter, REG_RSV_CTRL, 0x20);
6267
if (IS_8188F(pHalData->version_id) == FALSE
6268
&& IS_8188GTV(pHalData->version_id) == FALSE)
6269
rtw_write8(padapter, REG_RSV_CTRL, 0x60);
6270
#endif
6271
}
6272
6273
static void rtw_hal_ap_wow_disable(_adapter *padapter)
6274
{
6275
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6276
#ifdef DBG_CHECK_FW_PS_STATE
6277
struct dvobj_priv *psdpriv = padapter->dvobj;
6278
struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6279
#endif /*DBG_CHECK_FW_PS_STATE*/
6280
u16 media_status_rpt;
6281
u8 val8;
6282
6283
RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
6284
/* 1. Read wakeup reason*/
6285
pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
6286
6287
RTW_PRINT("wakeup_reason: 0x%02x\n",
6288
pwrctl->wowlan_wake_reason);
6289
6290
rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
6291
6292
rtw_msleep_os(2);
6293
#ifdef DBG_CHECK_FW_PS_STATE
6294
if (rtw_fw_ps_state(padapter) == _FAIL) {
6295
pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
6296
RTW_PRINT("wowlan enable no leave 32k\n");
6297
}
6298
#endif /*DBG_CHECK_FW_PS_STATE*/
6299
6300
#if defined(CONFIG_RTL8188E)
6301
if (IS_HARDWARE_TYPE_8188E(padapter))
6302
rtw_hal_enable_tx_report(padapter);
6303
#endif
6304
6305
rtw_hal_force_enable_rxdma(padapter);
6306
6307
rtw_hal_fw_dl(padapter, _FALSE);
6308
6309
#ifdef CONFIG_GPIO_WAKEUP
6310
#ifdef CONFIG_RTW_ONE_PIN_GPIO
6311
rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX);
6312
#else
6313
#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6314
if (pwrctl->is_high_active == 0)
6315
rtw_hal_set_input_gpio(padapter, WAKEUP_GPIO_IDX);
6316
else
6317
rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, 0);
6318
#else
6319
val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
6320
RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
6321
rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8);
6322
6323
rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _FALSE);
6324
#endif/*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
6325
#endif /* CONFIG_RTW_ONE_PIN_GPIO */
6326
#endif
6327
media_status_rpt = RT_MEDIA_CONNECT;
6328
6329
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6330
(u8 *)&media_status_rpt);
6331
6332
issue_beacon(padapter, 0);
6333
}
6334
#endif /*CONFIG_AP_WOWLAN*/
6335
6336
#ifdef CONFIG_P2P_WOWLAN
6337
static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
6338
{
6339
u8 *ssid_ie;
6340
sint ssid_len_ori;
6341
int len_diff = 0;
6342
6343
ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
6344
6345
/* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
6346
6347
if (ssid_ie && ssid_len_ori > 0) {
6348
switch (hidden_ssid_mode) {
6349
case 1: {
6350
u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
6351
u32 remain_len = 0;
6352
6353
remain_len = ies_len - (next_ie - ies);
6354
6355
ssid_ie[1] = 0;
6356
_rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
6357
len_diff -= ssid_len_ori;
6358
6359
break;
6360
}
6361
case 2:
6362
_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
6363
break;
6364
default:
6365
break;
6366
}
6367
}
6368
6369
return len_diff;
6370
}
6371
6372
static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
6373
{
6374
/* struct xmit_frame *pmgntframe; */
6375
/* struct pkt_attrib *pattrib; */
6376
/* unsigned char *pframe; */
6377
struct rtw_ieee80211_hdr *pwlanhdr;
6378
unsigned short *fctrl;
6379
unsigned int rate_len;
6380
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6381
u32 pktlen;
6382
/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6383
/* _irqL irqL;
6384
* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6385
* #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6386
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6387
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6388
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6389
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
6390
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6391
#ifdef CONFIG_P2P
6392
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6393
#endif /* CONFIG_P2P */
6394
6395
/* for debug */
6396
u8 *dbgbuf = pframe;
6397
u8 dbgbufLen = 0, index = 0;
6398
6399
RTW_INFO("%s\n", __FUNCTION__);
6400
/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6401
/* _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6402
* #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6403
6404
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6405
6406
6407
fctrl = &(pwlanhdr->frame_ctl);
6408
*(fctrl) = 0;
6409
6410
_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6411
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6412
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6413
6414
SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6415
/* pmlmeext->mgnt_seq++; */
6416
set_frame_sub_type(pframe, WIFI_BEACON);
6417
6418
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6419
pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6420
6421
if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6422
/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6423
#ifdef CONFIG_P2P
6424
/* for P2P : Primary Device Type & Device Name */
6425
u32 wpsielen = 0, insert_len = 0;
6426
u8 *wpsie = NULL;
6427
wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
6428
6429
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
6430
uint wps_offset, remainder_ielen;
6431
u8 *premainder_ie, *pframe_wscie;
6432
6433
wps_offset = (uint)(wpsie - cur_network->IEs);
6434
6435
premainder_ie = wpsie + wpsielen;
6436
6437
remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6438
6439
#ifdef CONFIG_IOCTL_CFG80211
6440
if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6441
if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
6442
_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
6443
pframe += wps_offset;
6444
pktlen += wps_offset;
6445
6446
_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6447
pframe += pmlmepriv->wps_beacon_ie_len;
6448
pktlen += pmlmepriv->wps_beacon_ie_len;
6449
6450
/* copy remainder_ie to pframe */
6451
_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6452
pframe += remainder_ielen;
6453
pktlen += remainder_ielen;
6454
} else {
6455
_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6456
pframe += cur_network->IELength;
6457
pktlen += cur_network->IELength;
6458
}
6459
} else
6460
#endif /* CONFIG_IOCTL_CFG80211 */
6461
{
6462
pframe_wscie = pframe + wps_offset;
6463
_rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
6464
pframe += (wps_offset + wpsielen);
6465
pktlen += (wps_offset + wpsielen);
6466
6467
/* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6468
/* Primary Device Type */
6469
/* Type: */
6470
*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6471
insert_len += 2;
6472
6473
/* Length: */
6474
*(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
6475
insert_len += 2;
6476
6477
/* Value: */
6478
/* Category ID */
6479
*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6480
insert_len += 2;
6481
6482
/* OUI */
6483
*(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
6484
insert_len += 4;
6485
6486
/* Sub Category ID */
6487
*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6488
insert_len += 2;
6489
6490
6491
/* Device Name */
6492
/* Type: */
6493
*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6494
insert_len += 2;
6495
6496
/* Length: */
6497
*(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
6498
insert_len += 2;
6499
6500
/* Value: */
6501
_rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
6502
insert_len += pwdinfo->device_name_len;
6503
6504
6505
/* update wsc ie length */
6506
*(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
6507
6508
/* pframe move to end */
6509
pframe += insert_len;
6510
pktlen += insert_len;
6511
6512
/* copy remainder_ie to pframe */
6513
_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6514
pframe += remainder_ielen;
6515
pktlen += remainder_ielen;
6516
}
6517
} else
6518
#endif /* CONFIG_P2P */
6519
{
6520
int len_diff;
6521
_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6522
len_diff = update_hidden_ssid(
6523
pframe + _BEACON_IE_OFFSET_
6524
, cur_network->IELength - _BEACON_IE_OFFSET_
6525
, pmlmeinfo->hidden_ssid_mode
6526
);
6527
pframe += (cur_network->IELength + len_diff);
6528
pktlen += (cur_network->IELength + len_diff);
6529
}
6530
#if 0
6531
{
6532
u8 *wps_ie;
6533
uint wps_ielen;
6534
u8 sr = 0;
6535
wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
6536
pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
6537
if (wps_ie && wps_ielen > 0)
6538
rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6539
if (sr != 0)
6540
set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6541
else
6542
_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6543
}
6544
#endif
6545
#ifdef CONFIG_P2P
6546
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6547
u32 len;
6548
#ifdef CONFIG_IOCTL_CFG80211
6549
if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6550
len = pmlmepriv->p2p_beacon_ie_len;
6551
if (pmlmepriv->p2p_beacon_ie && len > 0)
6552
_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6553
} else
6554
#endif /* CONFIG_IOCTL_CFG80211 */
6555
{
6556
len = build_beacon_p2p_ie(pwdinfo, pframe);
6557
}
6558
6559
pframe += len;
6560
pktlen += len;
6561
6562
#ifdef CONFIG_WFD
6563
len = rtw_append_beacon_wfd_ie(padapter, pframe);
6564
pframe += len;
6565
pktlen += len;
6566
#endif
6567
6568
}
6569
#endif /* CONFIG_P2P */
6570
6571
goto _issue_bcn;
6572
6573
}
6574
6575
/* below for ad-hoc mode */
6576
6577
/* timestamp will be inserted by hardware */
6578
pframe += 8;
6579
pktlen += 8;
6580
6581
/* beacon interval: 2 bytes */
6582
6583
_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6584
6585
pframe += 2;
6586
pktlen += 2;
6587
6588
/* capability info: 2 bytes */
6589
6590
_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6591
6592
pframe += 2;
6593
pktlen += 2;
6594
6595
/* SSID */
6596
pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6597
6598
/* supported rates... */
6599
rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6600
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6601
6602
/* DS parameter set */
6603
pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6604
6605
/* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6606
{
6607
u8 erpinfo = 0;
6608
u32 ATIMWindow;
6609
/* IBSS Parameter Set... */
6610
/* ATIMWindow = cur->Configuration.ATIMWindow; */
6611
ATIMWindow = 0;
6612
pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6613
6614
/* ERP IE */
6615
pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
6616
}
6617
6618
6619
/* EXTERNDED SUPPORTED RATE */
6620
if (rate_len > 8)
6621
pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6622
6623
6624
/* todo:HT for adhoc */
6625
6626
_issue_bcn:
6627
6628
/* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6629
/* pmlmepriv->update_bcn = _FALSE;
6630
*
6631
* _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6632
* #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6633
6634
*pLength = pktlen;
6635
#if 0
6636
/* printf dbg msg */
6637
dbgbufLen = pktlen;
6638
RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6639
6640
for (index = 0; index < dbgbufLen; index++)
6641
printk("%x ", *(dbgbuf + index));
6642
6643
printk("\n");
6644
RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6645
6646
#endif
6647
}
6648
6649
static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6650
{
6651
/* struct xmit_frame *pmgntframe; */
6652
/* struct pkt_attrib *pattrib; */
6653
/* unsigned char *pframe; */
6654
struct rtw_ieee80211_hdr *pwlanhdr;
6655
unsigned short *fctrl;
6656
unsigned char *mac;
6657
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6658
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6659
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6660
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6661
/* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
6662
u16 beacon_interval = 100;
6663
u16 capInfo = 0;
6664
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6665
u8 wpsie[255] = { 0x00 };
6666
u32 wpsielen = 0, p2pielen = 0;
6667
u32 pktlen;
6668
#ifdef CONFIG_WFD
6669
u32 wfdielen = 0;
6670
#endif
6671
6672
/* for debug */
6673
u8 *dbgbuf = pframe;
6674
u8 dbgbufLen = 0, index = 0;
6675
6676
RTW_INFO("%s\n", __FUNCTION__);
6677
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6678
6679
mac = adapter_mac_addr(padapter);
6680
6681
fctrl = &(pwlanhdr->frame_ctl);
6682
*(fctrl) = 0;
6683
6684
/* DA filled by FW */
6685
_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6686
_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6687
6688
/* Use the device address for BSSID field. */
6689
_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6690
6691
SetSeqNum(pwlanhdr, 0);
6692
set_frame_sub_type(fctrl, WIFI_PROBERSP);
6693
6694
pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6695
pframe += pktlen;
6696
6697
6698
/* timestamp will be inserted by hardware */
6699
pframe += 8;
6700
pktlen += 8;
6701
6702
/* beacon interval: 2 bytes */
6703
_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6704
pframe += 2;
6705
pktlen += 2;
6706
6707
/* capability info: 2 bytes */
6708
/* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6709
capInfo |= cap_ShortPremble;
6710
capInfo |= cap_ShortSlot;
6711
6712
_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6713
pframe += 2;
6714
pktlen += 2;
6715
6716
6717
/* SSID */
6718
pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
6719
6720
/* supported rates... */
6721
/* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6722
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
6723
6724
/* DS parameter set */
6725
pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
6726
6727
#ifdef CONFIG_IOCTL_CFG80211
6728
if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6729
if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6730
/* WPS IE */
6731
_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6732
pktlen += pmlmepriv->wps_probe_resp_ie_len;
6733
pframe += pmlmepriv->wps_probe_resp_ie_len;
6734
6735
/* P2P IE */
6736
_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6737
pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6738
pframe += pmlmepriv->p2p_probe_resp_ie_len;
6739
}
6740
} else
6741
#endif /* CONFIG_IOCTL_CFG80211 */
6742
{
6743
6744
/* Todo: WPS IE */
6745
/* Noted by Albert 20100907 */
6746
/* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6747
6748
wpsielen = 0;
6749
/* WPS OUI */
6750
*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6751
wpsielen += 4;
6752
6753
/* WPS version */
6754
/* Type: */
6755
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6756
wpsielen += 2;
6757
6758
/* Length: */
6759
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6760
wpsielen += 2;
6761
6762
/* Value: */
6763
wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
6764
6765
/* WiFi Simple Config State */
6766
/* Type: */
6767
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6768
wpsielen += 2;
6769
6770
/* Length: */
6771
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6772
wpsielen += 2;
6773
6774
/* Value: */
6775
wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
6776
6777
/* Response Type */
6778
/* Type: */
6779
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6780
wpsielen += 2;
6781
6782
/* Length: */
6783
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6784
wpsielen += 2;
6785
6786
/* Value: */
6787
wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6788
6789
/* UUID-E */
6790
/* Type: */
6791
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6792
wpsielen += 2;
6793
6794
/* Length: */
6795
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6796
wpsielen += 2;
6797
6798
/* Value: */
6799
if (pwdinfo->external_uuid == 0) {
6800
_rtw_memset(wpsie + wpsielen, 0x0, 16);
6801
_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6802
} else
6803
_rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6804
wpsielen += 0x10;
6805
6806
/* Manufacturer */
6807
/* Type: */
6808
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6809
wpsielen += 2;
6810
6811
/* Length: */
6812
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6813
wpsielen += 2;
6814
6815
/* Value: */
6816
_rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6817
wpsielen += 7;
6818
6819
/* Model Name */
6820
/* Type: */
6821
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
6822
wpsielen += 2;
6823
6824
/* Length: */
6825
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
6826
wpsielen += 2;
6827
6828
/* Value: */
6829
_rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
6830
wpsielen += 6;
6831
6832
/* Model Number */
6833
/* Type: */
6834
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
6835
wpsielen += 2;
6836
6837
/* Length: */
6838
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6839
wpsielen += 2;
6840
6841
/* Value: */
6842
wpsie[wpsielen++] = 0x31; /* character 1 */
6843
6844
/* Serial Number */
6845
/* Type: */
6846
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
6847
wpsielen += 2;
6848
6849
/* Length: */
6850
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
6851
wpsielen += 2;
6852
6853
/* Value: */
6854
_rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
6855
wpsielen += ETH_ALEN;
6856
6857
/* Primary Device Type */
6858
/* Type: */
6859
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6860
wpsielen += 2;
6861
6862
/* Length: */
6863
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6864
wpsielen += 2;
6865
6866
/* Value: */
6867
/* Category ID */
6868
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6869
wpsielen += 2;
6870
6871
/* OUI */
6872
*(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6873
wpsielen += 4;
6874
6875
/* Sub Category ID */
6876
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6877
wpsielen += 2;
6878
6879
/* Device Name */
6880
/* Type: */
6881
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6882
wpsielen += 2;
6883
6884
/* Length: */
6885
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
6886
wpsielen += 2;
6887
6888
/* Value: */
6889
_rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
6890
wpsielen += pwdinfo->device_name_len;
6891
6892
/* Config Method */
6893
/* Type: */
6894
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
6895
wpsielen += 2;
6896
6897
/* Length: */
6898
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
6899
wpsielen += 2;
6900
6901
/* Value: */
6902
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
6903
wpsielen += 2;
6904
6905
6906
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
6907
6908
6909
p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
6910
pframe += p2pielen;
6911
pktlen += p2pielen;
6912
}
6913
6914
#ifdef CONFIG_WFD
6915
wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
6916
pframe += wfdielen;
6917
pktlen += wfdielen;
6918
#endif
6919
6920
*pLength = pktlen;
6921
6922
#if 0
6923
/* printf dbg msg */
6924
dbgbufLen = pktlen;
6925
RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
6926
6927
for (index = 0; index < dbgbufLen; index++)
6928
printk("%x ", *(dbgbuf + index));
6929
6930
printk("\n");
6931
RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
6932
#endif
6933
}
6934
static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6935
{
6936
struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
6937
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
6938
u8 action = P2P_PUB_ACTION_ACTION;
6939
u32 p2poui = cpu_to_be32(P2POUI);
6940
u8 oui_subtype = P2P_GO_NEGO_RESP;
6941
u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
6942
u8 p2pielen = 0, i;
6943
uint wpsielen = 0;
6944
u16 wps_devicepassword_id = 0x0000;
6945
uint wps_devicepassword_id_len = 0;
6946
u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
6947
u16 len_channellist_attr = 0;
6948
u32 pktlen;
6949
u8 dialogToken = 0;
6950
6951
/* struct xmit_frame *pmgntframe; */
6952
/* struct pkt_attrib *pattrib; */
6953
/* unsigned char *pframe; */
6954
struct rtw_ieee80211_hdr *pwlanhdr;
6955
unsigned short *fctrl;
6956
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6957
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6958
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6959
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6960
/* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
6961
6962
#ifdef CONFIG_WFD
6963
u32 wfdielen = 0;
6964
#endif
6965
6966
/* for debug */
6967
u8 *dbgbuf = pframe;
6968
u8 dbgbufLen = 0, index = 0;
6969
6970
RTW_INFO("%s\n", __FUNCTION__);
6971
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6972
6973
fctrl = &(pwlanhdr->frame_ctl);
6974
*(fctrl) = 0;
6975
6976
/* RA, filled by FW */
6977
_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6978
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6979
_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
6980
6981
SetSeqNum(pwlanhdr, 0);
6982
set_frame_sub_type(pframe, WIFI_ACTION);
6983
6984
pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6985
pframe += pktlen;
6986
6987
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
6988
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
6989
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
6990
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
6991
6992
/* dialog token, filled by FW */
6993
pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
6994
6995
_rtw_memset(wpsie, 0x00, 255);
6996
wpsielen = 0;
6997
6998
/* WPS Section */
6999
wpsielen = 0;
7000
/* WPS OUI */
7001
*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
7002
wpsielen += 4;
7003
7004
/* WPS version */
7005
/* Type: */
7006
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7007
wpsielen += 2;
7008
7009
/* Length: */
7010
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7011
wpsielen += 2;
7012
7013
/* Value: */
7014
wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7015
7016
/* Device Password ID */
7017
/* Type: */
7018
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
7019
wpsielen += 2;
7020
7021
/* Length: */
7022
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7023
wpsielen += 2;
7024
7025
/* Value: */
7026
if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
7027
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
7028
else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
7029
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
7030
else
7031
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
7032
wpsielen += 2;
7033
7034
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7035
7036
7037
/* P2P IE Section. */
7038
7039
/* P2P OUI */
7040
p2pielen = 0;
7041
p2pie[p2pielen++] = 0x50;
7042
p2pie[p2pielen++] = 0x6F;
7043
p2pie[p2pielen++] = 0x9A;
7044
p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7045
7046
/* Commented by Albert 20100908 */
7047
/* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
7048
/* 1. Status */
7049
/* 2. P2P Capability */
7050
/* 3. Group Owner Intent */
7051
/* 4. Configuration Timeout */
7052
/* 5. Operating Channel */
7053
/* 6. Intended P2P Interface Address */
7054
/* 7. Channel List */
7055
/* 8. Device Info */
7056
/* 9. Group ID ( Only GO ) */
7057
7058
7059
/* ToDo: */
7060
7061
/* P2P Status */
7062
/* Type: */
7063
p2pie[p2pielen++] = P2P_ATTR_STATUS;
7064
7065
/* Length: */
7066
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7067
p2pielen += 2;
7068
7069
/* Value, filled by FW */
7070
p2pie[p2pielen++] = 1;
7071
7072
/* P2P Capability */
7073
/* Type: */
7074
p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
7075
7076
/* Length: */
7077
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7078
p2pielen += 2;
7079
7080
/* Value: */
7081
/* Device Capability Bitmap, 1 byte */
7082
7083
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
7084
/* Commented by Albert 2011/03/08 */
7085
/* According to the P2P specification */
7086
/* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
7087
p2pie[p2pielen++] = 0;
7088
} else {
7089
/* Be group owner or meet the error case */
7090
p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
7091
}
7092
7093
/* Group Capability Bitmap, 1 byte */
7094
if (pwdinfo->persistent_supported)
7095
p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
7096
else
7097
p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
7098
7099
/* Group Owner Intent */
7100
/* Type: */
7101
p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
7102
7103
/* Length: */
7104
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7105
p2pielen += 2;
7106
7107
/* Value: */
7108
if (pwdinfo->peer_intent & 0x01) {
7109
/* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
7110
p2pie[p2pielen++] = (pwdinfo->intent << 1);
7111
} else {
7112
/* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
7113
p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
7114
}
7115
7116
7117
/* Configuration Timeout */
7118
/* Type: */
7119
p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7120
7121
/* Length: */
7122
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7123
p2pielen += 2;
7124
7125
/* Value: */
7126
p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7127
p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7128
7129
/* Operating Channel */
7130
/* Type: */
7131
p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7132
7133
/* Length: */
7134
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7135
p2pielen += 2;
7136
7137
/* Value: */
7138
/* Country String */
7139
p2pie[p2pielen++] = 'X';
7140
p2pie[p2pielen++] = 'X';
7141
7142
/* The third byte should be set to 0x04. */
7143
/* Described in the "Operating Channel Attribute" section. */
7144
p2pie[p2pielen++] = 0x04;
7145
7146
/* Operating Class */
7147
if (pwdinfo->operating_channel <= 14) {
7148
/* Operating Class */
7149
p2pie[p2pielen++] = 0x51;
7150
} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
7151
/* Operating Class */
7152
p2pie[p2pielen++] = 0x73;
7153
} else {
7154
/* Operating Class */
7155
p2pie[p2pielen++] = 0x7c;
7156
}
7157
7158
/* Channel Number */
7159
p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7160
7161
/* Intended P2P Interface Address */
7162
/* Type: */
7163
p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
7164
7165
/* Length: */
7166
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7167
p2pielen += 2;
7168
7169
/* Value: */
7170
_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7171
p2pielen += ETH_ALEN;
7172
7173
/* Channel List */
7174
/* Type: */
7175
p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7176
7177
/* Country String(3) */
7178
/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7179
/* + number of channels in all classes */
7180
len_channellist_attr = 3
7181
+ (1 + 1) * (u16)ch_list->reg_classes
7182
+ get_reg_classes_full_count(ch_list);
7183
7184
#ifdef CONFIG_CONCURRENT_MODE
7185
if (rtw_mi_buddy_check_fwstate(padapter, _FW_LINKED))
7186
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7187
else
7188
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7189
7190
#else
7191
7192
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7193
7194
#endif
7195
p2pielen += 2;
7196
7197
/* Value: */
7198
/* Country String */
7199
p2pie[p2pielen++] = 'X';
7200
p2pie[p2pielen++] = 'X';
7201
7202
/* The third byte should be set to 0x04. */
7203
/* Described in the "Operating Channel Attribute" section. */
7204
p2pie[p2pielen++] = 0x04;
7205
7206
/* Channel Entry List */
7207
7208
#ifdef CONFIG_CONCURRENT_MODE
7209
if (rtw_mi_check_status(padapter, MI_LINKED)) {
7210
u8 union_ch = rtw_mi_get_union_chan(padapter);
7211
7212
/* Operating Class */
7213
if (union_ch > 14) {
7214
if (union_ch >= 149)
7215
p2pie[p2pielen++] = 0x7c;
7216
else
7217
p2pie[p2pielen++] = 0x73;
7218
} else
7219
p2pie[p2pielen++] = 0x51;
7220
7221
7222
/* Number of Channels */
7223
/* Just support 1 channel and this channel is AP's channel */
7224
p2pie[p2pielen++] = 1;
7225
7226
/* Channel List */
7227
p2pie[p2pielen++] = union_ch;
7228
} else
7229
#endif /* CONFIG_CONCURRENT_MODE */
7230
{
7231
int i, j;
7232
for (j = 0; j < ch_list->reg_classes; j++) {
7233
/* Operating Class */
7234
p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7235
7236
/* Number of Channels */
7237
p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7238
7239
/* Channel List */
7240
for (i = 0; i < ch_list->reg_class[j].channels; i++)
7241
p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7242
}
7243
}
7244
7245
/* Device Info */
7246
/* Type: */
7247
p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
7248
7249
/* Length: */
7250
/* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
7251
/* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7252
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
7253
p2pielen += 2;
7254
7255
/* Value: */
7256
/* P2P Device Address */
7257
_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7258
p2pielen += ETH_ALEN;
7259
7260
/* Config Method */
7261
/* This field should be big endian. Noted by P2P specification. */
7262
7263
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7264
7265
p2pielen += 2;
7266
7267
/* Primary Device Type */
7268
/* Category ID */
7269
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7270
p2pielen += 2;
7271
7272
/* OUI */
7273
*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
7274
p2pielen += 4;
7275
7276
/* Sub Category ID */
7277
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7278
p2pielen += 2;
7279
7280
/* Number of Secondary Device Types */
7281
p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
7282
7283
/* Device Name */
7284
/* Type: */
7285
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7286
p2pielen += 2;
7287
7288
/* Length: */
7289
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
7290
p2pielen += 2;
7291
7292
/* Value: */
7293
_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
7294
p2pielen += pwdinfo->device_name_len;
7295
7296
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7297
/* Group ID Attribute */
7298
/* Type: */
7299
p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
7300
7301
/* Length: */
7302
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
7303
p2pielen += 2;
7304
7305
/* Value: */
7306
/* p2P Device Address */
7307
_rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
7308
p2pielen += ETH_ALEN;
7309
7310
/* SSID */
7311
_rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
7312
p2pielen += pwdinfo->nego_ssidlen;
7313
7314
}
7315
7316
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7317
7318
#ifdef CONFIG_WFD
7319
wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
7320
pframe += wfdielen;
7321
pktlen += wfdielen;
7322
#endif
7323
7324
*pLength = pktlen;
7325
#if 0
7326
/* printf dbg msg */
7327
dbgbufLen = pktlen;
7328
RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7329
7330
for (index = 0; index < dbgbufLen; index++)
7331
printk("%x ", *(dbgbuf + index));
7332
7333
printk("\n");
7334
RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7335
#endif
7336
}
7337
7338
static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7339
{
7340
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7341
u8 action = P2P_PUB_ACTION_ACTION;
7342
u32 p2poui = cpu_to_be32(P2POUI);
7343
u8 oui_subtype = P2P_INVIT_RESP;
7344
u8 p2pie[255] = { 0x00 };
7345
u8 p2pielen = 0, i;
7346
u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
7347
u16 len_channellist_attr = 0;
7348
u32 pktlen;
7349
u8 dialogToken = 0;
7350
#ifdef CONFIG_WFD
7351
u32 wfdielen = 0;
7352
#endif
7353
7354
/* struct xmit_frame *pmgntframe; */
7355
/* struct pkt_attrib *pattrib; */
7356
/* unsigned char *pframe; */
7357
struct rtw_ieee80211_hdr *pwlanhdr;
7358
unsigned short *fctrl;
7359
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7360
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7361
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7362
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7363
7364
/* for debug */
7365
u8 *dbgbuf = pframe;
7366
u8 dbgbufLen = 0, index = 0;
7367
7368
7369
RTW_INFO("%s\n", __FUNCTION__);
7370
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7371
7372
fctrl = &(pwlanhdr->frame_ctl);
7373
*(fctrl) = 0;
7374
7375
/* RA fill by FW */
7376
_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7377
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7378
7379
/* BSSID fill by FW */
7380
_rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
7381
7382
SetSeqNum(pwlanhdr, 0);
7383
set_frame_sub_type(pframe, WIFI_ACTION);
7384
7385
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7386
pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7387
7388
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7389
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7390
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7391
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7392
7393
/* dialog token, filled by FW */
7394
pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7395
7396
/* P2P IE Section. */
7397
7398
/* P2P OUI */
7399
p2pielen = 0;
7400
p2pie[p2pielen++] = 0x50;
7401
p2pie[p2pielen++] = 0x6F;
7402
p2pie[p2pielen++] = 0x9A;
7403
p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7404
7405
/* Commented by Albert 20101005 */
7406
/* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
7407
/* 1. Status */
7408
/* 2. Configuration Timeout */
7409
/* 3. Operating Channel ( Only GO ) */
7410
/* 4. P2P Group BSSID ( Only GO ) */
7411
/* 5. Channel List */
7412
7413
/* P2P Status */
7414
/* Type: */
7415
p2pie[p2pielen++] = P2P_ATTR_STATUS;
7416
7417
/* Length: */
7418
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7419
p2pielen += 2;
7420
7421
/* Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
7422
p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7423
7424
/* Configuration Timeout */
7425
/* Type: */
7426
p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7427
7428
/* Length: */
7429
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7430
p2pielen += 2;
7431
7432
/* Value: */
7433
p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7434
p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7435
7436
/* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
7437
#if 0
7438
if (status_code == P2P_STATUS_SUCCESS) {
7439
struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7440
7441
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7442
/* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
7443
/* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
7444
/* First one is operating channel attribute. */
7445
/* Second one is P2P Group BSSID attribute. */
7446
7447
/* Operating Channel */
7448
/* Type: */
7449
p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7450
7451
/* Length: */
7452
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7453
p2pielen += 2;
7454
7455
/* Value: */
7456
/* Country String */
7457
p2pie[p2pielen++] = 'X';
7458
p2pie[p2pielen++] = 'X';
7459
7460
/* The third byte should be set to 0x04. */
7461
/* Described in the "Operating Channel Attribute" section. */
7462
p2pie[p2pielen++] = 0x04;
7463
7464
/* Operating Class */
7465
p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
7466
7467
/* Channel Number */
7468
p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7469
7470
7471
/* P2P Group BSSID */
7472
/* Type: */
7473
p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
7474
7475
/* Length: */
7476
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7477
p2pielen += 2;
7478
7479
/* Value: */
7480
/* P2P Device Address for GO */
7481
_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7482
p2pielen += ETH_ALEN;
7483
7484
}
7485
7486
/* Channel List */
7487
/* Type: */
7488
p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7489
7490
/* Length: */
7491
/* Country String(3) */
7492
/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7493
/* + number of channels in all classes */
7494
len_channellist_attr = 3
7495
+ (1 + 1) * (u16)ch_list->reg_classes
7496
+ get_reg_classes_full_count(ch_list);
7497
7498
#ifdef CONFIG_CONCURRENT_MODE
7499
if (rtw_mi_check_status(padapter, MI_LINKED))
7500
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7501
else
7502
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7503
7504
#else
7505
7506
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7507
7508
#endif
7509
p2pielen += 2;
7510
7511
/* Value: */
7512
/* Country String */
7513
p2pie[p2pielen++] = 'X';
7514
p2pie[p2pielen++] = 'X';
7515
7516
/* The third byte should be set to 0x04. */
7517
/* Described in the "Operating Channel Attribute" section. */
7518
p2pie[p2pielen++] = 0x04;
7519
7520
/* Channel Entry List */
7521
#ifdef CONFIG_CONCURRENT_MODE
7522
if (rtw_mi_check_status(padapter, MI_LINKED)) {
7523
u8 union_ch = rtw_mi_get_union_chan(padapter);
7524
7525
/* Operating Class */
7526
if (union_ch > 14) {
7527
if (union_ch >= 149)
7528
p2pie[p2pielen++] = 0x7c;
7529
else
7530
p2pie[p2pielen++] = 0x73;
7531
7532
} else
7533
p2pie[p2pielen++] = 0x51;
7534
7535
7536
/* Number of Channels */
7537
/* Just support 1 channel and this channel is AP's channel */
7538
p2pie[p2pielen++] = 1;
7539
7540
/* Channel List */
7541
p2pie[p2pielen++] = union_ch;
7542
} else
7543
#endif /* CONFIG_CONCURRENT_MODE */
7544
{
7545
int i, j;
7546
for (j = 0; j < ch_list->reg_classes; j++) {
7547
/* Operating Class */
7548
p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7549
7550
/* Number of Channels */
7551
p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7552
7553
/* Channel List */
7554
for (i = 0; i < ch_list->reg_class[j].channels; i++)
7555
p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7556
}
7557
}
7558
}
7559
#endif
7560
7561
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7562
7563
#ifdef CONFIG_WFD
7564
wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
7565
pframe += wfdielen;
7566
pktlen += wfdielen;
7567
#endif
7568
7569
*pLength = pktlen;
7570
7571
#if 0
7572
/* printf dbg msg */
7573
dbgbufLen = pktlen;
7574
RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7575
7576
for (index = 0; index < dbgbufLen; index++)
7577
printk("%x ", *(dbgbuf + index));
7578
7579
printk("\n");
7580
RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7581
#endif
7582
}
7583
7584
7585
static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7586
{
7587
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7588
u8 action = P2P_PUB_ACTION_ACTION;
7589
u8 dialogToken = 0;
7590
u32 p2poui = cpu_to_be32(P2POUI);
7591
u8 oui_subtype = P2P_PROVISION_DISC_RESP;
7592
u8 wpsie[100] = { 0x00 };
7593
u8 wpsielen = 0;
7594
u32 pktlen;
7595
#ifdef CONFIG_WFD
7596
u32 wfdielen = 0;
7597
#endif
7598
7599
/* struct xmit_frame *pmgntframe; */
7600
/* struct pkt_attrib *pattrib; */
7601
/* unsigned char *pframe; */
7602
struct rtw_ieee80211_hdr *pwlanhdr;
7603
unsigned short *fctrl;
7604
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7605
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7606
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7607
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7608
7609
/* for debug */
7610
u8 *dbgbuf = pframe;
7611
u8 dbgbufLen = 0, index = 0;
7612
7613
RTW_INFO("%s\n", __FUNCTION__);
7614
7615
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7616
7617
fctrl = &(pwlanhdr->frame_ctl);
7618
*(fctrl) = 0;
7619
7620
/* RA filled by FW */
7621
_rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7622
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7623
_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7624
7625
SetSeqNum(pwlanhdr, 0);
7626
set_frame_sub_type(pframe, WIFI_ACTION);
7627
7628
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7629
pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7630
7631
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7632
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7633
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7634
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7635
/* dialog token, filled by FW */
7636
pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7637
7638
wpsielen = 0;
7639
/* WPS OUI */
7640
/* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
7641
RTW_PUT_BE32(wpsie, WPSOUI);
7642
wpsielen += 4;
7643
7644
#if 0
7645
/* WPS version */
7646
/* Type: */
7647
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7648
wpsielen += 2;
7649
7650
/* Length: */
7651
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7652
wpsielen += 2;
7653
7654
/* Value: */
7655
wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7656
#endif
7657
7658
/* Config Method */
7659
/* Type: */
7660
/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
7661
RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
7662
wpsielen += 2;
7663
7664
/* Length: */
7665
/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
7666
RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
7667
wpsielen += 2;
7668
7669
/* Value: filled by FW, default value is PBC */
7670
/* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
7671
RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
7672
wpsielen += 2;
7673
7674
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7675
7676
#ifdef CONFIG_WFD
7677
wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
7678
pframe += wfdielen;
7679
pktlen += wfdielen;
7680
#endif
7681
7682
*pLength = pktlen;
7683
7684
/* printf dbg msg */
7685
#if 0
7686
dbgbufLen = pktlen;
7687
RTW_INFO("======> DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7688
7689
for (index = 0; index < dbgbufLen; index++)
7690
printk("%x ", *(dbgbuf + index));
7691
7692
printk("\n");
7693
RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7694
#endif
7695
}
7696
7697
u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
7698
{
7699
u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
7700
struct hal_ops *pHalFunc = &adapter->hal_func;
7701
u8 ret = _FAIL;
7702
7703
RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
7704
rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
7705
rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
7706
rsvdpageloc->LocPDRsp);
7707
7708
SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
7709
SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
7710
SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
7711
SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
7712
SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
7713
7714
/* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
7715
ret = rtw_hal_fill_h2c_cmd(adapter,
7716
H2C_P2P_OFFLOAD_RSVD_PAGE,
7717
H2C_P2PRSVDPAGE_LOC_LEN,
7718
u1H2CP2PRsvdPageParm);
7719
7720
return ret;
7721
}
7722
7723
u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
7724
{
7725
7726
u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
7727
struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
7728
struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
7729
struct hal_ops *pHalFunc = &adapter->hal_func;
7730
u8 ret = _FAIL;
7731
7732
_rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
7733
RTW_INFO("%s\n", __func__);
7734
switch (pwdinfo->role) {
7735
case P2P_ROLE_DEVICE:
7736
RTW_INFO("P2P_ROLE_DEVICE\n");
7737
p2p_wowlan_offload->role = 0;
7738
break;
7739
case P2P_ROLE_CLIENT:
7740
RTW_INFO("P2P_ROLE_CLIENT\n");
7741
p2p_wowlan_offload->role = 1;
7742
break;
7743
case P2P_ROLE_GO:
7744
RTW_INFO("P2P_ROLE_GO\n");
7745
p2p_wowlan_offload->role = 2;
7746
break;
7747
default:
7748
RTW_INFO("P2P_ROLE_DISABLE\n");
7749
break;
7750
}
7751
p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
7752
p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
7753
offload_cmd = (u8 *)p2p_wowlan_offload;
7754
RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
7755
7756
ret = rtw_hal_fill_h2c_cmd(adapter,
7757
H2C_P2P_OFFLOAD,
7758
H2C_P2P_OFFLOAD_LEN,
7759
offload_cmd);
7760
return ret;
7761
7762
/* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
7763
}
7764
#endif /* CONFIG_P2P_WOWLAN */
7765
7766
void rtw_hal_construct_beacon(_adapter *padapter,
7767
u8 *pframe, u32 *pLength)
7768
{
7769
struct rtw_ieee80211_hdr *pwlanhdr;
7770
u16 *fctrl;
7771
u32 pktlen;
7772
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7773
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7774
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7775
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7776
7777
7778
/* RTW_INFO("%s\n", __FUNCTION__); */
7779
7780
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7781
7782
fctrl = &(pwlanhdr->frame_ctl);
7783
*(fctrl) = 0;
7784
7785
_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7786
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7787
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7788
7789
SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7790
/* pmlmeext->mgnt_seq++; */
7791
set_frame_sub_type(pframe, WIFI_BEACON);
7792
7793
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7794
pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7795
7796
/* timestamp will be inserted by hardware */
7797
pframe += 8;
7798
pktlen += 8;
7799
7800
/* beacon interval: 2 bytes */
7801
_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7802
7803
pframe += 2;
7804
pktlen += 2;
7805
7806
#if 0
7807
/* capability info: 2 bytes */
7808
_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7809
7810
pframe += 2;
7811
pktlen += 2;
7812
7813
if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7814
/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7815
pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
7816
_rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
7817
7818
goto _ConstructBeacon;
7819
}
7820
7821
/* below for ad-hoc mode */
7822
7823
/* SSID */
7824
pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
7825
7826
/* supported rates... */
7827
rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7828
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
7829
7830
/* DS parameter set */
7831
pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
7832
7833
if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
7834
u32 ATIMWindow;
7835
/* IBSS Parameter Set... */
7836
/* ATIMWindow = cur->Configuration.ATIMWindow; */
7837
ATIMWindow = 0;
7838
pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
7839
}
7840
7841
7842
/* todo: ERP IE */
7843
7844
7845
/* EXTERNDED SUPPORTED RATE */
7846
if (rate_len > 8)
7847
pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
7848
7849
/* todo:HT for adhoc */
7850
7851
_ConstructBeacon:
7852
#endif
7853
7854
if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
7855
RTW_ERR("beacon frame too large ,len(%d,%d)\n",
7856
(pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
7857
rtw_warn_on(1);
7858
return;
7859
}
7860
7861
*pLength = pktlen;
7862
7863
/* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
7864
7865
}
7866
7867
static void rtw_hal_construct_PSPoll(_adapter *padapter,
7868
u8 *pframe, u32 *pLength)
7869
{
7870
struct rtw_ieee80211_hdr *pwlanhdr;
7871
u16 *fctrl;
7872
u32 pktlen;
7873
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7874
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7875
7876
/* RTW_INFO("%s\n", __FUNCTION__); */
7877
7878
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7879
7880
/* Frame control. */
7881
fctrl = &(pwlanhdr->frame_ctl);
7882
*(fctrl) = 0;
7883
SetPwrMgt(fctrl);
7884
set_frame_sub_type(pframe, WIFI_PSPOLL);
7885
7886
/* AID. */
7887
set_duration(pframe, (pmlmeinfo->aid | 0xc000));
7888
7889
/* BSSID. */
7890
_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7891
7892
/* TA. */
7893
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7894
7895
*pLength = 16;
7896
}
7897
7898
7899
#ifdef DBG_FW_DEBUG_MSG_PKT
7900
void rtw_hal_construct_fw_dbg_msg_pkt(
7901
PADAPTER padapter,
7902
u8 *pframe,
7903
u32 *plength)
7904
{
7905
struct rtw_ieee80211_hdr *pwlanhdr;
7906
u16 *fctrl;
7907
u32 pktlen;
7908
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7909
struct wlan_network *cur_network = &pmlmepriv->cur_network;
7910
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7911
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7912
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7913
7914
7915
/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
7916
7917
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7918
7919
fctrl = &pwlanhdr->frame_ctl;
7920
*(fctrl) = 0;
7921
7922
_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7923
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7924
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7925
7926
SetSeqNum(pwlanhdr, 0);
7927
7928
set_frame_sub_type(pframe, WIFI_DATA);
7929
7930
pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7931
7932
*plength = pktlen;
7933
}
7934
#endif /*DBG_FW_DEBUG_MSG_PKT*/
7935
7936
void rtw_hal_construct_NullFunctionData(
7937
PADAPTER padapter,
7938
u8 *pframe,
7939
u32 *pLength,
7940
u8 bQoS,
7941
u8 AC,
7942
u8 bEosp,
7943
u8 bForcePowerSave)
7944
{
7945
struct rtw_ieee80211_hdr *pwlanhdr;
7946
u16 *fctrl;
7947
u32 pktlen;
7948
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7949
struct wlan_network *cur_network = &pmlmepriv->cur_network;
7950
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7951
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7952
u8 *sta_addr = NULL;
7953
u8 bssid[ETH_ALEN] = {0};
7954
7955
/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
7956
7957
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7958
7959
fctrl = &pwlanhdr->frame_ctl;
7960
*(fctrl) = 0;
7961
if (bForcePowerSave)
7962
SetPwrMgt(fctrl);
7963
7964
sta_addr = get_my_bssid(&pmlmeinfo->network);
7965
if (NULL == sta_addr) {
7966
_rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
7967
sta_addr = bssid;
7968
}
7969
7970
switch (cur_network->network.InfrastructureMode) {
7971
case Ndis802_11Infrastructure:
7972
SetToDs(fctrl);
7973
_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7974
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7975
_rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);
7976
break;
7977
case Ndis802_11APMode:
7978
SetFrDs(fctrl);
7979
_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
7980
_rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7981
_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7982
break;
7983
case Ndis802_11IBSS:
7984
default:
7985
_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
7986
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7987
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7988
break;
7989
}
7990
7991
SetSeqNum(pwlanhdr, 0);
7992
set_duration(pwlanhdr, 0);
7993
7994
if (bQoS == _TRUE) {
7995
struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
7996
7997
set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
7998
7999
pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
8000
SetPriority(&pwlanqoshdr->qc, AC);
8001
SetEOSP(&pwlanqoshdr->qc, bEosp);
8002
8003
pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8004
} else {
8005
set_frame_sub_type(pframe, WIFI_DATA_NULL);
8006
8007
pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8008
}
8009
8010
*pLength = pktlen;
8011
}
8012
8013
void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
8014
BOOLEAN bHideSSID)
8015
{
8016
struct rtw_ieee80211_hdr *pwlanhdr;
8017
u16 *fctrl;
8018
u8 *mac, *bssid, *sta_addr;
8019
u32 pktlen;
8020
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8021
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8022
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
8023
8024
/*RTW_INFO("%s\n", __FUNCTION__);*/
8025
8026
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8027
8028
mac = adapter_mac_addr(padapter);
8029
bssid = cur_network->MacAddress;
8030
sta_addr = get_my_bssid(&pmlmeinfo->network);
8031
8032
fctrl = &(pwlanhdr->frame_ctl);
8033
*(fctrl) = 0;
8034
_rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8035
_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8036
_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8037
8038
SetSeqNum(pwlanhdr, 0);
8039
set_frame_sub_type(fctrl, WIFI_PROBERSP);
8040
8041
pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8042
pframe += pktlen;
8043
8044
if (cur_network->IELength > MAX_IE_SZ)
8045
return;
8046
8047
_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8048
pframe += cur_network->IELength;
8049
pktlen += cur_network->IELength;
8050
8051
*pLength = pktlen;
8052
}
8053
8054
#ifdef CONFIG_WOWLAN
8055
static void rtw_hal_append_tkip_mic(PADAPTER padapter,
8056
u8 *pframe, u32 offset)
8057
{
8058
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8059
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8060
struct rtw_ieee80211_hdr *pwlanhdr;
8061
struct mic_data micdata;
8062
struct sta_info *psta = NULL;
8063
int res = 0;
8064
8065
u8 *payload = (u8 *)(pframe + offset);
8066
8067
u8 mic[8];
8068
u8 priority[4] = {0x0};
8069
u8 null_key[16] = {0x0};
8070
8071
RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
8072
8073
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8074
8075
psta = rtw_get_stainfo(&padapter->stapriv,
8076
get_my_bssid(&(pmlmeinfo->network)));
8077
if (psta != NULL) {
8078
res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
8079
null_key, 16);
8080
if (res == _TRUE)
8081
RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
8082
rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
8083
}
8084
8085
rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); /* DA */
8086
8087
rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
8088
8089
priority[0] = 0;
8090
8091
rtw_secmicappend(&micdata, &priority[0], 4);
8092
8093
rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
8094
8095
rtw_secgetmic(&micdata, &(mic[0]));
8096
8097
payload += 36;
8098
8099
_rtw_memcpy(payload, &(mic[0]), 8);
8100
}
8101
/*
8102
* Description:
8103
* Construct the ARP response packet to support ARP offload.
8104
* */
8105
static void rtw_hal_construct_ARPRsp(
8106
PADAPTER padapter,
8107
u8 *pframe,
8108
u32 *pLength,
8109
u8 *pIPAddress
8110
)
8111
{
8112
struct rtw_ieee80211_hdr *pwlanhdr;
8113
u16 *fctrl;
8114
u32 pktlen;
8115
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8116
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8117
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8118
struct security_priv *psecuritypriv = &padapter->securitypriv;
8119
static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
8120
u8 *pARPRspPkt = pframe;
8121
/* for TKIP Cal MIC */
8122
u8 *payload = pframe;
8123
u8 EncryptionHeadOverhead = 0, arp_offset = 0;
8124
/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8125
8126
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8127
8128
fctrl = &pwlanhdr->frame_ctl;
8129
*(fctrl) = 0;
8130
8131
/* ------------------------------------------------------------------------- */
8132
/* MAC Header. */
8133
/* ------------------------------------------------------------------------- */
8134
SetFrameType(fctrl, WIFI_DATA);
8135
/* set_frame_sub_type(fctrl, 0); */
8136
SetToDs(fctrl);
8137
_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8138
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8139
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8140
8141
SetSeqNum(pwlanhdr, 0);
8142
set_duration(pwlanhdr, 0);
8143
/* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
8144
/* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
8145
/* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
8146
/* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
8147
/* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
8148
/* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
8149
8150
/* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
8151
/* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
8152
#ifdef CONFIG_WAPI_SUPPORT
8153
*pLength = sMacHdrLng;
8154
#else
8155
*pLength = 24;
8156
#endif
8157
switch (psecuritypriv->dot11PrivacyAlgrthm) {
8158
case _WEP40_:
8159
case _WEP104_:
8160
EncryptionHeadOverhead = 4;
8161
break;
8162
case _TKIP_:
8163
EncryptionHeadOverhead = 8;
8164
break;
8165
case _AES_:
8166
EncryptionHeadOverhead = 8;
8167
break;
8168
#ifdef CONFIG_WAPI_SUPPORT
8169
case _SMS4_:
8170
EncryptionHeadOverhead = 18;
8171
break;
8172
#endif
8173
default:
8174
EncryptionHeadOverhead = 0;
8175
}
8176
8177
if (EncryptionHeadOverhead > 0) {
8178
_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8179
*pLength += EncryptionHeadOverhead;
8180
/* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8181
SetPrivacy(fctrl);
8182
}
8183
8184
/* ------------------------------------------------------------------------- */
8185
/* Frame Body. */
8186
/* ------------------------------------------------------------------------- */
8187
arp_offset = *pLength;
8188
pARPRspPkt = (u8 *)(pframe + arp_offset);
8189
payload = pARPRspPkt; /* Get Payload pointer */
8190
/* LLC header */
8191
_rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
8192
*pLength += 8;
8193
8194
/* ARP element */
8195
pARPRspPkt += 8;
8196
SET_ARP_HTYPE(pARPRspPkt, 1);
8197
SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP); /* IP protocol */
8198
SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);
8199
SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);
8200
SET_ARP_OPER(pARPRspPkt, 2); /* ARP response */
8201
SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
8202
SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
8203
#ifdef CONFIG_ARP_KEEP_ALIVE
8204
if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
8205
SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
8206
SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
8207
} else
8208
#endif
8209
{
8210
SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,
8211
get_my_bssid(&(pmlmeinfo->network)));
8212
SET_ARP_TARGET_IP_ADDR(pARPRspPkt,
8213
pIPAddress);
8214
RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
8215
MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
8216
RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
8217
IP_ARG(pIPAddress));
8218
}
8219
8220
*pLength += 28;
8221
8222
if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8223
if (IS_HARDWARE_TYPE_8188E(padapter) ||
8224
IS_HARDWARE_TYPE_8812(padapter)) {
8225
rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
8226
}
8227
*pLength += 8;
8228
}
8229
}
8230
8231
#ifdef CONFIG_IPV6
8232
/*
8233
* Description: Neighbor Discovery Offload.
8234
*/
8235
static void rtw_hal_construct_na_message(_adapter *padapter,
8236
u8 *pframe, u32 *pLength)
8237
{
8238
struct rtw_ieee80211_hdr *pwlanhdr = NULL;
8239
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8240
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8241
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8242
struct security_priv *psecuritypriv = &padapter->securitypriv;
8243
8244
u32 pktlen = 0;
8245
u16 *fctrl = NULL;
8246
8247
u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8248
u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
8249
u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
8250
u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
8251
u8 val8 = 0;
8252
8253
u8 *p_na_msg = pframe;
8254
/* for TKIP Cal MIC */
8255
u8 *payload = pframe;
8256
u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
8257
/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8258
8259
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8260
8261
fctrl = &pwlanhdr->frame_ctl;
8262
*(fctrl) = 0;
8263
8264
/* ------------------------------------------------------------------------- */
8265
/* MAC Header. */
8266
/* ------------------------------------------------------------------------- */
8267
SetFrameType(fctrl, WIFI_DATA);
8268
SetToDs(fctrl);
8269
_rtw_memcpy(pwlanhdr->addr1,
8270
get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8271
_rtw_memcpy(pwlanhdr->addr2,
8272
adapter_mac_addr(padapter), ETH_ALEN);
8273
_rtw_memcpy(pwlanhdr->addr3,
8274
get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8275
8276
SetSeqNum(pwlanhdr, 0);
8277
set_duration(pwlanhdr, 0);
8278
8279
#ifdef CONFIG_WAPI_SUPPORT
8280
*pLength = sMacHdrLng;
8281
#else
8282
*pLength = 24;
8283
#endif
8284
switch (psecuritypriv->dot11PrivacyAlgrthm) {
8285
case _WEP40_:
8286
case _WEP104_:
8287
EncryptionHeadOverhead = 4;
8288
break;
8289
case _TKIP_:
8290
EncryptionHeadOverhead = 8;
8291
break;
8292
case _AES_:
8293
EncryptionHeadOverhead = 8;
8294
break;
8295
#ifdef CONFIG_WAPI_SUPPORT
8296
case _SMS4_:
8297
EncryptionHeadOverhead = 18;
8298
break;
8299
#endif
8300
default:
8301
EncryptionHeadOverhead = 0;
8302
}
8303
8304
if (EncryptionHeadOverhead > 0) {
8305
_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8306
*pLength += EncryptionHeadOverhead;
8307
/* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8308
SetPrivacy(fctrl);
8309
}
8310
8311
/* ------------------------------------------------------------------------- */
8312
/* Frame Body. */
8313
/* ------------------------------------------------------------------------- */
8314
na_msg_offset = *pLength;
8315
p_na_msg = (u8 *)(pframe + na_msg_offset);
8316
payload = p_na_msg; /* Get Payload pointer */
8317
8318
/* LLC header */
8319
val8 = sizeof(ns_hdr);
8320
_rtw_memcpy(p_na_msg, ns_hdr, val8);
8321
*pLength += val8;
8322
p_na_msg += val8;
8323
8324
/* IPv6 Header */
8325
/* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
8326
val8 = sizeof(ipv6_info);
8327
_rtw_memcpy(p_na_msg, ipv6_info, val8);
8328
*pLength += val8;
8329
p_na_msg += val8;
8330
8331
/* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
8332
val8 = sizeof(ipv6_contx);
8333
_rtw_memcpy(p_na_msg, ipv6_contx, val8);
8334
*pLength += val8;
8335
p_na_msg += val8;
8336
8337
/* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
8338
_rtw_memset(&(p_na_msg[*pLength]), 0, 32);
8339
*pLength += 32;
8340
p_na_msg += 32;
8341
8342
/* ICMPv6 */
8343
/* 1. Type : 0x88 (NA)
8344
* 2. Code : 0x00
8345
* 3. ChechSum : 0x00 0x00 (RSvd)
8346
* 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
8347
*/
8348
val8 = sizeof(icmpv6_hdr);
8349
_rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
8350
*pLength += val8;
8351
p_na_msg += val8;
8352
8353
/* TA: 16 bytes*/
8354
_rtw_memset(&(p_na_msg[*pLength]), 0, 16);
8355
*pLength += 16;
8356
p_na_msg += 16;
8357
8358
/* ICMPv6 Target Link Layer Address */
8359
p_na_msg[0] = 0x02; /* type */
8360
p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
8361
*pLength += 2;
8362
p_na_msg += 2;
8363
8364
_rtw_memset(&(p_na_msg[*pLength]), 0, 6);
8365
*pLength += 6;
8366
p_na_msg += 6;
8367
8368
if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8369
if (IS_HARDWARE_TYPE_8188E(padapter) ||
8370
IS_HARDWARE_TYPE_8812(padapter)) {
8371
rtw_hal_append_tkip_mic(padapter, pframe,
8372
na_msg_offset);
8373
}
8374
*pLength += 8;
8375
}
8376
}
8377
/*
8378
* Description: Neighbor Discovery Protocol Information.
8379
*/
8380
static void rtw_hal_construct_ndp_info(_adapter *padapter,
8381
u8 *pframe, u32 *pLength)
8382
{
8383
struct mlme_ext_priv *pmlmeext = NULL;
8384
struct mlme_ext_info *pmlmeinfo = NULL;
8385
struct rtw_ndp_info ndp_info;
8386
u8 *pndp_info = pframe;
8387
u8 len = sizeof(struct rtw_ndp_info);
8388
8389
RTW_INFO("%s: len: %d\n", __func__, len);
8390
8391
pmlmeext = &padapter->mlmeextpriv;
8392
pmlmeinfo = &pmlmeext->mlmext_info;
8393
8394
_rtw_memset(pframe, 0, len);
8395
_rtw_memset(&ndp_info, 0, len);
8396
8397
ndp_info.enable = 1;
8398
ndp_info.check_remote_ip = 0;
8399
ndp_info.num_of_target_ip = 1;
8400
8401
_rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
8402
ETH_ALEN);
8403
_rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
8404
RTW_IPv6_ADDR_LEN);
8405
8406
_rtw_memcpy(pndp_info, &ndp_info, len);
8407
}
8408
#endif /* CONFIG_IPV6 */
8409
8410
#ifdef CONFIG_PNO_SUPPORT
8411
static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
8412
u32 *pLength, pno_ssid_t *ssid)
8413
{
8414
struct rtw_ieee80211_hdr *pwlanhdr;
8415
u16 *fctrl;
8416
u32 pktlen;
8417
unsigned char *mac;
8418
unsigned char bssrate[NumRates];
8419
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8420
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8421
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8422
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8423
int bssrate_len = 0;
8424
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8425
8426
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8427
mac = adapter_mac_addr(padapter);
8428
8429
fctrl = &(pwlanhdr->frame_ctl);
8430
*(fctrl) = 0;
8431
8432
_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8433
_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8434
8435
_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8436
8437
SetSeqNum(pwlanhdr, 0);
8438
set_frame_sub_type(pframe, WIFI_PROBEREQ);
8439
8440
pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8441
pframe += pktlen;
8442
8443
if (ssid == NULL)
8444
pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
8445
else {
8446
/* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
8447
pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
8448
}
8449
8450
get_rate_set(padapter, bssrate, &bssrate_len);
8451
8452
if (bssrate_len > 8) {
8453
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
8454
pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
8455
} else
8456
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
8457
8458
*pLength = pktlen;
8459
}
8460
8461
static void rtw_hal_construct_PNO_info(_adapter *padapter,
8462
u8 *pframe, u32 *pLength)
8463
{
8464
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8465
int i;
8466
8467
u8 *pPnoInfoPkt = pframe;
8468
pPnoInfoPkt = (u8 *)(pframe + *pLength);
8469
_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
8470
8471
pPnoInfoPkt += 1;
8472
_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
8473
8474
pPnoInfoPkt += 3;
8475
_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
8476
8477
pPnoInfoPkt += 4;
8478
_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
8479
8480
pPnoInfoPkt += 4;
8481
_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
8482
8483
pPnoInfoPkt += 4;
8484
_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
8485
8486
pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8487
_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
8488
8489
pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8490
_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
8491
8492
pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8493
_rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
8494
8495
pPnoInfoPkt += MAX_HIDDEN_AP;
8496
8497
/*
8498
SSID is located at 128th Byte in NLO info Page
8499
*/
8500
8501
*pLength += 128;
8502
pPnoInfoPkt = pframe + 128;
8503
8504
for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8505
_rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8506
pwrctl->pnlo_info->ssid_length[i]);
8507
*pLength += WLAN_SSID_MAXLEN;
8508
pPnoInfoPkt += WLAN_SSID_MAXLEN;
8509
}
8510
}
8511
8512
static void rtw_hal_construct_ssid_list(_adapter *padapter,
8513
u8 *pframe, u32 *pLength)
8514
{
8515
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8516
u8 *pSSIDListPkt = pframe;
8517
int i;
8518
8519
pSSIDListPkt = (u8 *)(pframe + *pLength);
8520
8521
for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8522
_rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8523
pwrctl->pnlo_info->ssid_length[i]);
8524
8525
*pLength += WLAN_SSID_MAXLEN;
8526
pSSIDListPkt += WLAN_SSID_MAXLEN;
8527
}
8528
}
8529
8530
static void rtw_hal_construct_scan_info(_adapter *padapter,
8531
u8 *pframe, u32 *pLength)
8532
{
8533
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8534
u8 *pScanInfoPkt = pframe;
8535
int i;
8536
8537
pScanInfoPkt = (u8 *)(pframe + *pLength);
8538
8539
_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
8540
8541
*pLength += 1;
8542
pScanInfoPkt += 1;
8543
_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
8544
8545
8546
*pLength += 1;
8547
pScanInfoPkt += 1;
8548
_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
8549
8550
8551
*pLength += 1;
8552
pScanInfoPkt += 1;
8553
_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
8554
8555
*pLength += 1;
8556
pScanInfoPkt += 1;
8557
_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
8558
8559
*pLength += 1;
8560
pScanInfoPkt += 1;
8561
_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
8562
8563
*pLength += 1;
8564
pScanInfoPkt += 1;
8565
_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
8566
8567
*pLength += 1;
8568
pScanInfoPkt += 1;
8569
_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
8570
8571
*pLength += 1;
8572
pScanInfoPkt += 1;
8573
_rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
8574
8575
*pLength += 8;
8576
pScanInfoPkt += 8;
8577
8578
for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
8579
_rtw_memcpy(pScanInfoPkt,
8580
&pwrctl->pscan_info->ssid_channel_info[i], 4);
8581
*pLength += 4;
8582
pScanInfoPkt += 4;
8583
}
8584
}
8585
#endif /* CONFIG_PNO_SUPPORT */
8586
8587
#ifdef CONFIG_GTK_OL
8588
static void rtw_hal_construct_GTKRsp(
8589
PADAPTER padapter,
8590
u8 *pframe,
8591
u32 *pLength
8592
)
8593
{
8594
struct rtw_ieee80211_hdr *pwlanhdr;
8595
u16 *fctrl;
8596
u32 pktlen;
8597
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8598
struct wlan_network *cur_network = &pmlmepriv->cur_network;
8599
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8600
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8601
struct security_priv *psecuritypriv = &padapter->securitypriv;
8602
static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
8603
static u8 GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
8604
u8 *pGTKRspPkt = pframe;
8605
u8 EncryptionHeadOverhead = 0;
8606
/* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8607
8608
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8609
8610
fctrl = &pwlanhdr->frame_ctl;
8611
*(fctrl) = 0;
8612
8613
/* ------------------------------------------------------------------------- */
8614
/* MAC Header. */
8615
/* ------------------------------------------------------------------------- */
8616
SetFrameType(fctrl, WIFI_DATA);
8617
/* set_frame_sub_type(fctrl, 0); */
8618
SetToDs(fctrl);
8619
8620
_rtw_memcpy(pwlanhdr->addr1,
8621
get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8622
8623
_rtw_memcpy(pwlanhdr->addr2,
8624
adapter_mac_addr(padapter), ETH_ALEN);
8625
8626
_rtw_memcpy(pwlanhdr->addr3,
8627
get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8628
8629
SetSeqNum(pwlanhdr, 0);
8630
set_duration(pwlanhdr, 0);
8631
8632
#ifdef CONFIG_WAPI_SUPPORT
8633
*pLength = sMacHdrLng;
8634
#else
8635
*pLength = 24;
8636
#endif /* CONFIG_WAPI_SUPPORT */
8637
8638
/* ------------------------------------------------------------------------- */
8639
/* Security Header: leave space for it if necessary. */
8640
/* ------------------------------------------------------------------------- */
8641
switch (psecuritypriv->dot11PrivacyAlgrthm) {
8642
case _WEP40_:
8643
case _WEP104_:
8644
EncryptionHeadOverhead = 4;
8645
break;
8646
case _TKIP_:
8647
EncryptionHeadOverhead = 8;
8648
break;
8649
case _AES_:
8650
EncryptionHeadOverhead = 8;
8651
break;
8652
#ifdef CONFIG_WAPI_SUPPORT
8653
case _SMS4_:
8654
EncryptionHeadOverhead = 18;
8655
break;
8656
#endif /* CONFIG_WAPI_SUPPORT */
8657
default:
8658
EncryptionHeadOverhead = 0;
8659
}
8660
8661
if (EncryptionHeadOverhead > 0) {
8662
_rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8663
*pLength += EncryptionHeadOverhead;
8664
/* SET_80211_HDR_WEP(pGTKRspPkt, 1); */ /* Suggested by CCW. */
8665
/* GTK's privacy bit is done by FW */
8666
/* SetPrivacy(fctrl); */
8667
}
8668
/* ------------------------------------------------------------------------- */
8669
/* Frame Body. */
8670
/* ------------------------------------------------------------------------- */
8671
pGTKRspPkt = (u8 *)(pframe + *pLength);
8672
/* LLC header */
8673
_rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
8674
*pLength += 8;
8675
8676
/* GTK element */
8677
pGTKRspPkt += 8;
8678
8679
/* GTK frame body after LLC, part 1 */
8680
/* TKIP key_length = 32, AES key_length = 16 */
8681
if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8682
GTKbody_a[8] = 0x20;
8683
8684
/* GTK frame body after LLC, part 1 */
8685
_rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
8686
*pLength += 11;
8687
pGTKRspPkt += 11;
8688
/* GTK frame body after LLC, part 2 */
8689
_rtw_memset(&(pframe[*pLength]), 0, 88);
8690
*pLength += 88;
8691
pGTKRspPkt += 88;
8692
8693
if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8694
*pLength += 8;
8695
}
8696
#endif /* CONFIG_GTK_OL */
8697
8698
#define PN_2_CCMPH(ch,key_id) ((ch) & 0x000000000000ffff) \
8699
| (((ch) & 0x0000ffffffff0000) << 16) \
8700
| (((key_id) << 30)) \
8701
| BIT(29)
8702
static void rtw_hal_construct_remote_control_info(_adapter *adapter,
8703
u8 *pframe, u32 *pLength)
8704
{
8705
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8706
struct sta_priv *pstapriv = &adapter->stapriv;
8707
struct security_priv *psecuritypriv = &adapter->securitypriv;
8708
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
8709
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8710
struct sta_info *psta;
8711
struct stainfo_rxcache *prxcache;
8712
u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
8713
size_t sz = 0, total = 0;
8714
u64 ccmp_hdr = 0, tmp_key = 0;
8715
8716
psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8717
8718
if (psta == NULL) {
8719
rtw_warn_on(1);
8720
return;
8721
}
8722
8723
prxcache = &psta->sta_recvpriv.rxcache;
8724
sz = sizeof(cur_dot11rxiv);
8725
8726
/* 3 SEC IV * 1 page */
8727
rtw_get_sec_iv(adapter, cur_dot11rxiv,
8728
get_my_bssid(&pmlmeinfo->network));
8729
8730
_rtw_memcpy(pframe, cur_dot11rxiv, sz);
8731
*pLength += sz;
8732
pframe += sz;
8733
8734
_rtw_memset(&cur_dot11rxiv, 0, sz);
8735
8736
if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
8737
id = psecuritypriv->dot118021XGrpKeyid;
8738
tid_id = prxcache->last_tid;
8739
REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
8740
REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
8741
REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
8742
REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
8743
_rtw_memcpy(pframe, cur_dot11rxiv, sz);
8744
*pLength += sz;
8745
pframe += sz;
8746
8747
_rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
8748
*pLength += sz;
8749
pframe += sz;
8750
8751
total = sizeof(psecuritypriv->iv_seq);
8752
total /= sizeof(psecuritypriv->iv_seq[0]);
8753
8754
for (i = 0 ; i < total ; i ++) {
8755
ccmp_hdr =
8756
le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
8757
_rtw_memset(&cur_dot11rxiv, 0, sz);
8758
if (ccmp_hdr != 0) {
8759
tmp_key = i;
8760
ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
8761
*(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
8762
_rtw_memcpy(pframe, cur_dot11rxiv, sz);
8763
}
8764
*pLength += sz;
8765
pframe += sz;
8766
}
8767
}
8768
}
8769
8770
void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
8771
u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
8772
RSVDPAGE_LOC *rsvd_page_loc)
8773
{
8774
struct security_priv *psecuritypriv = &adapter->securitypriv;
8775
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8776
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8777
struct mlme_ext_priv *pmlmeext;
8778
struct mlme_ext_info *pmlmeinfo;
8779
u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
8780
u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;
8781
u8 CurtPktPageNum = 0;
8782
8783
#ifdef CONFIG_GTK_OL
8784
struct sta_priv *pstapriv = &adapter->stapriv;
8785
struct sta_info *psta;
8786
struct security_priv *psecpriv = &adapter->securitypriv;
8787
u8 kek[RTW_KEK_LEN];
8788
u8 kck[RTW_KCK_LEN];
8789
#endif /* CONFIG_GTK_OL */
8790
#ifdef CONFIG_PNO_SUPPORT
8791
int pno_index;
8792
u8 ssid_num;
8793
#endif /* CONFIG_PNO_SUPPORT */
8794
8795
pmlmeext = &adapter->mlmeextpriv;
8796
pmlmeinfo = &pmlmeext->mlmext_info;
8797
8798
if (pwrctl->wowlan_pno_enable == _FALSE) {
8799
/* ARP RSP * 1 page */
8800
8801
rsvd_page_loc->LocArpRsp = *page_num;
8802
8803
RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
8804
8805
rtw_hal_construct_ARPRsp(adapter, &pframe[index],
8806
&ARPLength, pmlmeinfo->ip_addr);
8807
8808
rtw_hal_fill_fake_txdesc(adapter,
8809
&pframe[index - tx_desc],
8810
ARPLength, _FALSE, _FALSE, _TRUE);
8811
8812
CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
8813
8814
*page_num += CurtPktPageNum;
8815
8816
index += (CurtPktPageNum * page_size);
8817
RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
8818
8819
#ifdef CONFIG_IPV6
8820
/* 2 NS offload and NDP Info*/
8821
if (pwrctl->wowlan_ns_offload_en == _TRUE) {
8822
rsvd_page_loc->LocNbrAdv = *page_num;
8823
RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
8824
rtw_hal_construct_na_message(adapter,
8825
&pframe[index], &ns_len);
8826
rtw_hal_fill_fake_txdesc(adapter,
8827
&pframe[index - tx_desc],
8828
ns_len, _FALSE,
8829
_FALSE, _TRUE);
8830
CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
8831
page_size);
8832
*page_num += CurtPktPageNum;
8833
index += (CurtPktPageNum * page_size);
8834
RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
8835
8836
rsvd_page_loc->LocNDPInfo = *page_num;
8837
RTW_INFO("LocNDPInfo: %d\n",
8838
rsvd_page_loc->LocNDPInfo);
8839
8840
rtw_hal_construct_ndp_info(adapter,
8841
&pframe[index - tx_desc],
8842
&ns_len);
8843
CurtPktPageNum =
8844
(u8)PageNum(tx_desc + ns_len, page_size);
8845
*page_num += CurtPktPageNum;
8846
index += (CurtPktPageNum * page_size);
8847
RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
8848
8849
}
8850
#endif /*CONFIG_IPV6*/
8851
/* 3 Remote Control Info. * 1 page */
8852
rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
8853
RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
8854
rtw_hal_construct_remote_control_info(adapter,
8855
&pframe[index - tx_desc],
8856
&rc_len);
8857
CurtPktPageNum = (u8)PageNum(rc_len, page_size);
8858
*page_num += CurtPktPageNum;
8859
*total_pkt_len = index + rc_len;
8860
RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
8861
#ifdef CONFIG_GTK_OL
8862
index += (CurtPktPageNum * page_size);
8863
8864
/* if the ap staion info. exists, get the kek, kck from staion info. */
8865
psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8866
if (psta == NULL) {
8867
_rtw_memset(kek, 0, RTW_KEK_LEN);
8868
_rtw_memset(kck, 0, RTW_KCK_LEN);
8869
RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
8870
__func__);
8871
} else {
8872
_rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
8873
_rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
8874
}
8875
8876
/* 3 KEK, KCK */
8877
rsvd_page_loc->LocGTKInfo = *page_num;
8878
RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
8879
8880
if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
8881
struct security_priv *psecpriv = NULL;
8882
8883
psecpriv = &adapter->securitypriv;
8884
_rtw_memcpy(pframe + index - tx_desc,
8885
&psecpriv->dot11PrivacyAlgrthm, 1);
8886
_rtw_memcpy(pframe + index - tx_desc + 1,
8887
&psecpriv->dot118021XGrpPrivacy, 1);
8888
_rtw_memcpy(pframe + index - tx_desc + 2,
8889
kck, RTW_KCK_LEN);
8890
_rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
8891
kek, RTW_KEK_LEN);
8892
CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
8893
} else {
8894
8895
_rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
8896
_rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
8897
kek, RTW_KEK_LEN);
8898
GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
8899
8900
if (psta != NULL &&
8901
psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
8902
_rtw_memcpy(pframe + index - tx_desc + 56,
8903
&psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
8904
GTKLength += RTW_TKIP_MIC_LEN;
8905
}
8906
CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
8907
}
8908
#if 0
8909
{
8910
int i;
8911
printk("\ntoFW KCK: ");
8912
for (i = 0; i < 16; i++)
8913
printk(" %02x ", kck[i]);
8914
printk("\ntoFW KEK: ");
8915
for (i = 0; i < 16; i++)
8916
printk(" %02x ", kek[i]);
8917
printk("\n");
8918
}
8919
8920
RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
8921
__FUNCTION__, &pframe[index - tx_desc],
8922
(tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
8923
#endif
8924
8925
*page_num += CurtPktPageNum;
8926
8927
index += (CurtPktPageNum * page_size);
8928
RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
8929
8930
/* 3 GTK Response */
8931
rsvd_page_loc->LocGTKRsp = *page_num;
8932
RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
8933
rtw_hal_construct_GTKRsp(adapter, &pframe[index], &GTKLength);
8934
8935
rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
8936
GTKLength, _FALSE, _FALSE, _TRUE);
8937
#if 0
8938
{
8939
int gj;
8940
printk("123GTK pkt=>\n");
8941
for (gj = 0; gj < GTKLength + tx_desc; gj++) {
8942
printk(" %02x ", pframe[index - tx_desc + gj]);
8943
if ((gj + 1) % 16 == 0)
8944
printk("\n");
8945
}
8946
printk(" <=end\n");
8947
}
8948
8949
RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
8950
__FUNCTION__, &pframe[index - tx_desc],
8951
(tx_desc + GTKLength));
8952
#endif
8953
8954
CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
8955
8956
*page_num += CurtPktPageNum;
8957
8958
index += (CurtPktPageNum * page_size);
8959
RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
8960
8961
/* below page is empty for GTK extension memory */
8962
/* 3(11) GTK EXT MEM */
8963
rsvd_page_loc->LocGTKEXTMEM = *page_num;
8964
RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
8965
CurtPktPageNum = 2;
8966
8967
if (page_size >= 256)
8968
CurtPktPageNum = 1;
8969
8970
*page_num += CurtPktPageNum;
8971
/* extension memory for FW */
8972
*total_pkt_len = index + (page_size * CurtPktPageNum);
8973
RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
8974
#endif /* CONFIG_GTK_OL */
8975
8976
index += (CurtPktPageNum * page_size);
8977
8978
/*Reserve 1 page for AOAC report*/
8979
rsvd_page_loc->LocAOACReport = *page_num;
8980
RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
8981
*page_num += 1;
8982
*total_pkt_len = index + (page_size * 1);
8983
RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
8984
} else {
8985
#ifdef CONFIG_PNO_SUPPORT
8986
if (pwrctl->wowlan_in_resume == _FALSE &&
8987
pwrctl->pno_inited == _TRUE) {
8988
8989
/* Broadcast Probe Request */
8990
rsvd_page_loc->LocProbePacket = *page_num;
8991
8992
RTW_INFO("loc_probe_req: %d\n",
8993
rsvd_page_loc->LocProbePacket);
8994
8995
rtw_hal_construct_ProbeReq(
8996
adapter,
8997
&pframe[index],
8998
&ProbeReqLength,
8999
NULL);
9000
9001
rtw_hal_fill_fake_txdesc(adapter,
9002
&pframe[index - tx_desc],
9003
ProbeReqLength, _FALSE, _FALSE, _FALSE);
9004
9005
CurtPktPageNum =
9006
(u8)PageNum(tx_desc + ProbeReqLength, page_size);
9007
9008
*page_num += CurtPktPageNum;
9009
9010
index += (CurtPktPageNum * page_size);
9011
RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9012
9013
/* Hidden SSID Probe Request */
9014
ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
9015
9016
for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
9017
pwrctl->pnlo_info->loc_probe_req[pno_index] =
9018
*page_num;
9019
9020
rtw_hal_construct_ProbeReq(
9021
adapter,
9022
&pframe[index],
9023
&ProbeReqLength,
9024
&pwrctl->pno_ssid_list->node[pno_index]);
9025
9026
rtw_hal_fill_fake_txdesc(adapter,
9027
&pframe[index - tx_desc],
9028
ProbeReqLength, _FALSE, _FALSE, _FALSE);
9029
9030
CurtPktPageNum =
9031
(u8)PageNum(tx_desc + ProbeReqLength, page_size);
9032
9033
*page_num += CurtPktPageNum;
9034
9035
index += (CurtPktPageNum * page_size);
9036
RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9037
}
9038
9039
/* PNO INFO Page */
9040
rsvd_page_loc->LocPNOInfo = *page_num;
9041
RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
9042
rtw_hal_construct_PNO_info(adapter,
9043
&pframe[index - tx_desc],
9044
&PNOLength);
9045
9046
CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
9047
*page_num += CurtPktPageNum;
9048
index += (CurtPktPageNum * page_size);
9049
RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
9050
9051
/* Scan Info Page */
9052
rsvd_page_loc->LocScanInfo = *page_num;
9053
RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
9054
rtw_hal_construct_scan_info(adapter,
9055
&pframe[index - tx_desc],
9056
&ScanInfoLength);
9057
9058
CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
9059
*page_num += CurtPktPageNum;
9060
*total_pkt_len = index + ScanInfoLength;
9061
index += (CurtPktPageNum * page_size);
9062
RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
9063
}
9064
#endif /* CONFIG_PNO_SUPPORT */
9065
}
9066
}
9067
9068
static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
9069
{
9070
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9071
u8 i = 0, val8 = 0, empty = _FAIL;
9072
9073
if (stop) {
9074
/* checking TX queue status */
9075
for (i = 0 ; i < 5 ; i++) {
9076
rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
9077
if (empty) {
9078
break;
9079
} else {
9080
RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
9081
__func__, i);
9082
rtw_mdelay_os(10);
9083
}
9084
}
9085
9086
if (val8 == 5)
9087
RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
9088
9089
/* Pause TX*/
9090
pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
9091
rtw_write8(adapter, REG_TXPAUSE, 0xff);
9092
val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9093
val8 &= ~BIT(0);
9094
rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9095
RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
9096
__func__,
9097
rtw_read8(adapter, REG_SYS_FUNC_EN),
9098
pwrpriv->wowlan_txpause_status);
9099
} else {
9100
val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9101
val8 |= BIT(0);
9102
rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9103
RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
9104
__func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
9105
pwrpriv->wowlan_txpause_status);
9106
/* release TX*/
9107
rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
9108
}
9109
}
9110
9111
static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
9112
{
9113
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9114
u8 *pattern;
9115
u8 len = 0;
9116
u8 *mask;
9117
9118
u8 mask_hw[MAX_WKFM_SIZE] = {0};
9119
u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9120
u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9121
u8 multicast_addr1[2] = {0x33, 0x33};
9122
u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9123
u8 mask_len = 0;
9124
u8 mac_addr[ETH_ALEN] = {0};
9125
u16 count = 0;
9126
int i;
9127
9128
if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9129
RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9130
__func__, MAX_WKFM_CAM_NUM);
9131
return _FAIL;
9132
}
9133
9134
pattern = pwrctl->patterns[idx].content;
9135
len = pwrctl->patterns[idx].len;
9136
mask = pwrctl->patterns[idx].mask;
9137
9138
_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9139
_rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
9140
9141
mask_len = DIV_ROUND_UP(len, 8);
9142
9143
/* 1. setup A1 table */
9144
if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9145
pwow_pattern->type = PATTERN_BROADCAST;
9146
else if (memcmp(pattern, multicast_addr1, 2) == 0)
9147
pwow_pattern->type = PATTERN_MULTICAST;
9148
else if (memcmp(pattern, multicast_addr2, 3) == 0)
9149
pwow_pattern->type = PATTERN_MULTICAST;
9150
else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9151
pwow_pattern->type = PATTERN_UNICAST;
9152
else
9153
pwow_pattern->type = PATTERN_INVALID;
9154
9155
/* translate mask from os to mask for hw */
9156
9157
/******************************************************************************
9158
* pattern from OS uses 'ethenet frame', like this:
9159
9160
| 6 | 6 | 2 | 20 | Variable | 4 |
9161
|--------+--------+------+-----------+------------+-----|
9162
| 802.3 Mac Header | IP Header | TCP Packet | FCS |
9163
| DA | SA | Type |
9164
9165
* BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9166
9167
| 24 or 30 | 6 | 2 | 20 | Variable | 4 |
9168
|-------------------+--------+------+-----------+------------+-----|
9169
| 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
9170
| Others | Tpye |
9171
9172
* Therefore, we need translate mask_from_OS to mask_to_hw.
9173
* We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9174
* because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9175
* bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9176
******************************************************************************/
9177
/* Shift 6 bits */
9178
for (i = 0; i < mask_len - 1; i++) {
9179
mask_hw[i] = mask[i] >> 6;
9180
mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9181
}
9182
9183
mask_hw[i] = (mask[i] >> 6) & 0x3F;
9184
/* Set bit 0-5 to zero */
9185
mask_hw[0] &= 0xC0;
9186
9187
for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9188
pwow_pattern->mask[i] = mask_hw[i * 4];
9189
pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
9190
pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
9191
pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
9192
}
9193
9194
/* To get the wake up pattern from the mask.
9195
* We do not count first 12 bits which means
9196
* DA[6] and SA[6] in the pattern to match HW design. */
9197
count = 0;
9198
for (i = 12; i < len; i++) {
9199
if ((mask[i / 8] >> (i % 8)) & 0x01) {
9200
content[count] = pattern[i];
9201
count++;
9202
}
9203
}
9204
9205
pwow_pattern->crc = rtw_calc_crc(content, count);
9206
9207
if (pwow_pattern->crc != 0) {
9208
if (pwow_pattern->type == PATTERN_INVALID)
9209
pwow_pattern->type = PATTERN_VALID;
9210
}
9211
9212
return _SUCCESS;
9213
}
9214
9215
#ifndef CONFIG_WOW_PATTERN_HW_CAM
9216
static void rtw_hal_reset_mac_rx(_adapter *adapter)
9217
{
9218
u8 val8 = 0;
9219
/* Set REG_CR bit1, bit3, bit7 to 0*/
9220
val8 = rtw_read8(adapter, REG_CR);
9221
val8 &= 0x75;
9222
rtw_write8(adapter, REG_CR, val8);
9223
val8 = rtw_read8(adapter, REG_CR);
9224
/* Set REG_CR bit1, bit3, bit7 to 1*/
9225
val8 |= 0x8a;
9226
rtw_write8(adapter, REG_CR, val8);
9227
RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
9228
}
9229
static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
9230
{
9231
u8 val8 = 0;
9232
u16 rxff_bndy = 0;
9233
u32 rx_dma_buff_sz = 0;
9234
9235
val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
9236
if (val8 != 0)
9237
RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
9238
__func__, (REG_FIFOPAGE + 3));
9239
9240
rtw_hal_reset_mac_rx(adapter);
9241
9242
if (wow_mode) {
9243
rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9244
(u8 *)&rx_dma_buff_sz);
9245
rxff_bndy = rx_dma_buff_sz - 1;
9246
9247
rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9248
RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
9249
REG_TRXFF_BNDY + 2,
9250
rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9251
} else {
9252
rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
9253
(u8 *)&rx_dma_buff_sz);
9254
rxff_bndy = rx_dma_buff_sz - 1;
9255
rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9256
RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
9257
REG_TRXFF_BNDY + 2,
9258
rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9259
}
9260
}
9261
9262
bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9263
{
9264
u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9265
u16 offset, rx_buf_ptr = 0;
9266
u16 cam_start_offset = 0;
9267
u16 ctrl_l = 0, ctrl_h = 0;
9268
u8 count = 0, tmp = 0;
9269
int i = 0;
9270
bool res = _TRUE;
9271
9272
if (idx > MAX_WKFM_CAM_NUM) {
9273
RTW_INFO("[Error]: %s, pattern index is out of range\n",
9274
__func__);
9275
return _FALSE;
9276
}
9277
9278
rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9279
(u8 *)&rx_dma_buff_sz);
9280
9281
if (rx_dma_buff_sz == 0) {
9282
RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9283
return _FALSE;
9284
}
9285
9286
rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9287
9288
if (page_sz == 0) {
9289
RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9290
return _FALSE;
9291
}
9292
9293
offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9294
cam_start_offset = offset * page_sz;
9295
9296
ctrl_l = 0x0;
9297
ctrl_h = 0x0;
9298
9299
/* Enable RX packet buffer access */
9300
rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9301
9302
/* Read the WKFM CAM */
9303
for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9304
/*
9305
* Set Rx packet buffer offset.
9306
* RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9307
* CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9308
* RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9309
* * Index: The index of the wake up frame mask
9310
* * WKFMCAM_SIZE: the total size of one WKFM CAM
9311
* * per entry offset of a WKFM CAM: Addr i * 4 bytes
9312
*/
9313
rx_buf_ptr =
9314
(cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9315
rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9316
9317
rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9318
data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9319
data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9320
9321
RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9322
9323
count = 0;
9324
9325
do {
9326
tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9327
rtw_udelay_os(2);
9328
count++;
9329
} while (!tmp && count < 100);
9330
9331
if (count >= 100) {
9332
RTW_INFO("%s count:%d\n", __func__, count);
9333
res = _FALSE;
9334
}
9335
}
9336
9337
/* Disable RX packet buffer access */
9338
rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9339
DISABLE_TRXPKT_BUF_ACCESS);
9340
return res;
9341
}
9342
9343
bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9344
struct rtl_wow_pattern *context)
9345
{
9346
u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
9347
u16 offset, rx_buf_ptr = 0;
9348
u16 cam_start_offset = 0;
9349
u16 ctrl_l = 0, ctrl_h = 0;
9350
u8 count = 0, tmp = 0;
9351
int res = 0, i = 0;
9352
9353
if (idx > MAX_WKFM_CAM_NUM) {
9354
RTW_INFO("[Error]: %s, pattern index is out of range\n",
9355
__func__);
9356
return _FALSE;
9357
}
9358
9359
rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9360
(u8 *)&rx_dma_buff_sz);
9361
9362
if (rx_dma_buff_sz == 0) {
9363
RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9364
return _FALSE;
9365
}
9366
9367
rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9368
9369
if (page_sz == 0) {
9370
RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9371
return _FALSE;
9372
}
9373
9374
offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9375
9376
cam_start_offset = offset * page_sz;
9377
9378
if (IS_HARDWARE_TYPE_8188E(adapter)) {
9379
ctrl_l = 0x0001;
9380
ctrl_h = 0x0001;
9381
} else {
9382
ctrl_l = 0x0f01;
9383
ctrl_h = 0xf001;
9384
}
9385
9386
/* Enable RX packet buffer access */
9387
rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9388
9389
/* Write the WKFM CAM */
9390
for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
9391
/*
9392
* Set Rx packet buffer offset.
9393
* RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9394
* CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9395
* RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9396
* * Index: The index of the wake up frame mask
9397
* * WKFMCAM_SIZE: the total size of one WKFM CAM
9398
* * per entry offset of a WKFM CAM: Addr i * 4 bytes
9399
*/
9400
rx_buf_ptr =
9401
(cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
9402
rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9403
9404
if (i == 0) {
9405
if (context->type == PATTERN_VALID)
9406
data = BIT(31);
9407
else if (context->type == PATTERN_BROADCAST)
9408
data = BIT(31) | BIT(26);
9409
else if (context->type == PATTERN_MULTICAST)
9410
data = BIT(31) | BIT(25);
9411
else if (context->type == PATTERN_UNICAST)
9412
data = BIT(31) | BIT(24);
9413
9414
if (context->crc != 0)
9415
data |= context->crc;
9416
9417
rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9418
rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9419
} else if (i == 1) {
9420
data = 0;
9421
rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9422
rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9423
} else if (i == 2 || i == 4) {
9424
data = context->mask[i - 2];
9425
rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9426
/* write to RX packet buffer*/
9427
rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9428
} else if (i == 3 || i == 5) {
9429
data = context->mask[i - 2];
9430
rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9431
/* write to RX packet buffer*/
9432
rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9433
}
9434
9435
count = 0;
9436
do {
9437
tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9438
rtw_udelay_os(2);
9439
count++;
9440
} while (tmp && count < 100);
9441
9442
if (count >= 100)
9443
res = _FALSE;
9444
else
9445
res = _TRUE;
9446
}
9447
9448
/* Disable RX packet buffer access */
9449
rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9450
DISABLE_TRXPKT_BUF_ACCESS);
9451
9452
return res;
9453
}
9454
void rtw_clean_pattern(_adapter *adapter)
9455
{
9456
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9457
struct rtl_wow_pattern zero_pattern;
9458
int i = 0;
9459
9460
_rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
9461
9462
zero_pattern.type = PATTERN_INVALID;
9463
9464
for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
9465
rtw_write_to_frame_mask(adapter, i, &zero_pattern);
9466
9467
rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
9468
}
9469
#if 0
9470
static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
9471
u8 len, u8 *mask, u8 idx)
9472
{
9473
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9474
struct mlme_ext_priv *pmlmeext = NULL;
9475
struct mlme_ext_info *pmlmeinfo = NULL;
9476
struct rtl_wow_pattern wow_pattern;
9477
u8 mask_hw[MAX_WKFM_SIZE] = {0};
9478
u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9479
u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9480
u8 multicast_addr1[2] = {0x33, 0x33};
9481
u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9482
u8 res = _FALSE, index = 0, mask_len = 0;
9483
u8 mac_addr[ETH_ALEN] = {0};
9484
u16 count = 0;
9485
int i, j;
9486
9487
if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9488
RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9489
__func__, MAX_WKFM_CAM_NUM);
9490
return _FALSE;
9491
}
9492
9493
pmlmeext = &adapter->mlmeextpriv;
9494
pmlmeinfo = &pmlmeext->mlmext_info;
9495
_rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9496
_rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
9497
9498
mask_len = DIV_ROUND_UP(len, 8);
9499
9500
/* 1. setup A1 table */
9501
if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9502
wow_pattern.type = PATTERN_BROADCAST;
9503
else if (memcmp(pattern, multicast_addr1, 2) == 0)
9504
wow_pattern.type = PATTERN_MULTICAST;
9505
else if (memcmp(pattern, multicast_addr2, 3) == 0)
9506
wow_pattern.type = PATTERN_MULTICAST;
9507
else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9508
wow_pattern.type = PATTERN_UNICAST;
9509
else
9510
wow_pattern.type = PATTERN_INVALID;
9511
9512
/* translate mask from os to mask for hw */
9513
9514
/******************************************************************************
9515
* pattern from OS uses 'ethenet frame', like this:
9516
9517
| 6 | 6 | 2 | 20 | Variable | 4 |
9518
|--------+--------+------+-----------+------------+-----|
9519
| 802.3 Mac Header | IP Header | TCP Packet | FCS |
9520
| DA | SA | Type |
9521
9522
* BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9523
9524
| 24 or 30 | 6 | 2 | 20 | Variable | 4 |
9525
|-------------------+--------+------+-----------+------------+-----|
9526
| 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
9527
| Others | Tpye |
9528
9529
* Therefore, we need translate mask_from_OS to mask_to_hw.
9530
* We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9531
* because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9532
* bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9533
******************************************************************************/
9534
/* Shift 6 bits */
9535
for (i = 0; i < mask_len - 1; i++) {
9536
mask_hw[i] = mask[i] >> 6;
9537
mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9538
}
9539
9540
mask_hw[i] = (mask[i] >> 6) & 0x3F;
9541
/* Set bit 0-5 to zero */
9542
mask_hw[0] &= 0xC0;
9543
9544
for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9545
wow_pattern.mask[i] = mask_hw[i * 4];
9546
wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
9547
wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
9548
wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
9549
}
9550
9551
/* To get the wake up pattern from the mask.
9552
* We do not count first 12 bits which means
9553
* DA[6] and SA[6] in the pattern to match HW design. */
9554
count = 0;
9555
for (i = 12; i < len; i++) {
9556
if ((mask[i / 8] >> (i % 8)) & 0x01) {
9557
content[count] = pattern[i];
9558
count++;
9559
}
9560
}
9561
9562
wow_pattern.crc = rtw_calc_crc(content, count);
9563
9564
if (wow_pattern.crc != 0) {
9565
if (wow_pattern.type == PATTERN_INVALID)
9566
wow_pattern.type = PATTERN_VALID;
9567
}
9568
9569
index = idx;
9570
9571
if (!pwrctl->bInSuspend)
9572
index += 2;
9573
9574
/* write pattern */
9575
res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
9576
9577
if (res == _FALSE)
9578
RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
9579
__func__, idx);
9580
9581
return res;
9582
}
9583
#endif
9584
9585
void rtw_fill_pattern(_adapter *adapter)
9586
{
9587
int i = 0, total = 0, index;
9588
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9589
struct rtl_wow_pattern wow_pattern;
9590
9591
total = pwrpriv->wowlan_pattern_idx;
9592
9593
if (total > MAX_WKFM_CAM_NUM)
9594
total = MAX_WKFM_CAM_NUM;
9595
9596
for (i = 0 ; i < total ; i++) {
9597
if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
9598
9599
index = i;
9600
if (!pwrpriv->bInSuspend)
9601
index += 2;
9602
9603
if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
9604
RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
9605
}
9606
9607
}
9608
rtw_write8(adapter, REG_WKFMCAM_NUM, total);
9609
9610
}
9611
9612
#else /*CONFIG_WOW_PATTERN_HW_CAM*/
9613
9614
#define WOW_CAM_ACCESS_TIMEOUT_MS 200
9615
#define WOW_VALID_BIT BIT31
9616
#define WOW_BC_BIT BIT26
9617
#define WOW_MC_BIT BIT25
9618
#define WOW_UC_BIT BIT24
9619
9620
static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
9621
{
9622
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9623
_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
9624
9625
u32 rdata = 0;
9626
u32 cnt = 0;
9627
systime start = 0;
9628
u8 timeout = 0;
9629
u8 rst = _FALSE;
9630
9631
_enter_critical_mutex(mutex, NULL);
9632
9633
rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
9634
9635
start = rtw_get_current_time();
9636
while (1) {
9637
if (rtw_is_surprise_removed(adapter))
9638
break;
9639
9640
cnt++;
9641
if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
9642
rst = _SUCCESS;
9643
break;
9644
}
9645
if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
9646
timeout = 1;
9647
break;
9648
}
9649
}
9650
9651
rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
9652
9653
_exit_critical_mutex(mutex, NULL);
9654
9655
/*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
9656
9657
if (timeout)
9658
RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
9659
9660
return rdata;
9661
}
9662
void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
9663
{
9664
int i;
9665
u32 rdata;
9666
9667
_rtw_memset(context, 0, sizeof(struct rtl_wow_pattern));
9668
9669
for (i = 4; i >= 0; i--) {
9670
rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
9671
9672
switch (i) {
9673
case 4:
9674
if (rdata & WOW_BC_BIT)
9675
context->type = PATTERN_BROADCAST;
9676
else if (rdata & WOW_MC_BIT)
9677
context->type = PATTERN_MULTICAST;
9678
else if (rdata & WOW_UC_BIT)
9679
context->type = PATTERN_UNICAST;
9680
else
9681
context->type = PATTERN_INVALID;
9682
9683
context->crc = rdata & 0xFFFF;
9684
break;
9685
default:
9686
_rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
9687
break;
9688
}
9689
}
9690
}
9691
9692
static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
9693
{
9694
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9695
_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
9696
u32 cnt = 0;
9697
systime start = 0, end = 0;
9698
u8 timeout = 0;
9699
9700
/*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
9701
_enter_critical_mutex(mutex, NULL);
9702
9703
rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
9704
rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
9705
9706
start = rtw_get_current_time();
9707
while (1) {
9708
if (rtw_is_surprise_removed(adapter))
9709
break;
9710
9711
cnt++;
9712
if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
9713
break;
9714
9715
if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
9716
timeout = 1;
9717
break;
9718
}
9719
}
9720
end = rtw_get_current_time();
9721
9722
_exit_critical_mutex(mutex, NULL);
9723
9724
if (timeout) {
9725
RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
9726
, FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
9727
}
9728
}
9729
9730
void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
9731
{
9732
int j;
9733
u8 addr;
9734
u32 wdata = 0;
9735
9736
for (j = 4; j >= 0; j--) {
9737
switch (j) {
9738
case 4:
9739
wdata = context->crc;
9740
9741
if (PATTERN_BROADCAST == context->type)
9742
wdata |= WOW_BC_BIT;
9743
if (PATTERN_MULTICAST == context->type)
9744
wdata |= WOW_MC_BIT;
9745
if (PATTERN_UNICAST == context->type)
9746
wdata |= WOW_UC_BIT;
9747
if (PATTERN_INVALID != context->type)
9748
wdata |= WOW_VALID_BIT;
9749
break;
9750
default:
9751
wdata = context->mask[j];
9752
break;
9753
}
9754
9755
addr = (id << 3) + j;
9756
9757
_rtw_wow_pattern_write_cam(adapter, addr, wdata);
9758
}
9759
}
9760
9761
static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
9762
{
9763
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9764
_mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
9765
u32 cnt = 0;
9766
systime start = 0;
9767
u8 timeout = 0;
9768
u8 rst = _FAIL;
9769
9770
_enter_critical_mutex(mutex, NULL);
9771
rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
9772
9773
start = rtw_get_current_time();
9774
while (1) {
9775
if (rtw_is_surprise_removed(adapter))
9776
break;
9777
9778
cnt++;
9779
if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
9780
rst = _SUCCESS;
9781
break;
9782
}
9783
if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
9784
timeout = 1;
9785
break;
9786
}
9787
}
9788
_exit_critical_mutex(mutex, NULL);
9789
9790
if (timeout)
9791
RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
9792
9793
return rst;
9794
}
9795
9796
void rtw_clean_pattern(_adapter *adapter)
9797
{
9798
if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
9799
RTW_ERR("rtw_clean_pattern failed\n");
9800
}
9801
9802
void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
9803
{
9804
int j;
9805
9806
RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
9807
RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
9808
RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
9809
for (j = 0; j < 4; j++)
9810
RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
9811
}
9812
9813
void rtw_fill_pattern(_adapter *adapter)
9814
{
9815
int i = 0, total = 0;
9816
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9817
struct rtl_wow_pattern wow_pattern;
9818
9819
total = pwrpriv->wowlan_pattern_idx;
9820
9821
if (total > MAX_WKFM_CAM_NUM)
9822
total = MAX_WKFM_CAM_NUM;
9823
9824
for (i = 0 ; i < total ; i++) {
9825
if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
9826
rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
9827
rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
9828
}
9829
}
9830
}
9831
9832
#endif
9833
void rtw_wow_pattern_cam_dump(_adapter *adapter)
9834
{
9835
9836
#ifndef CONFIG_WOW_PATTERN_HW_CAM
9837
int i;
9838
9839
for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
9840
RTW_INFO("=======[%d]=======\n", i);
9841
rtw_read_from_frame_mask(adapter, i);
9842
}
9843
#else
9844
struct rtl_wow_pattern context;
9845
int i;
9846
9847
for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
9848
rtw_wow_pattern_read_cam_ent(adapter, i, &context);
9849
rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
9850
}
9851
9852
#endif
9853
}
9854
9855
9856
static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
9857
{
9858
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9859
9860
switch (mode) {
9861
case 0:
9862
rtw_clean_pattern(adapter);
9863
RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
9864
break;
9865
case 1:
9866
rtw_set_default_pattern(adapter);
9867
rtw_fill_pattern(adapter);
9868
RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
9869
break;
9870
case 2:
9871
rtw_clean_pattern(adapter);
9872
rtw_wow_pattern_sw_reset(adapter);
9873
RTW_INFO("%s: clean patterns\n", __func__);
9874
break;
9875
default:
9876
RTW_INFO("%s: unknown mode\n", __func__);
9877
break;
9878
}
9879
}
9880
9881
static void rtw_hal_wow_enable(_adapter *adapter)
9882
{
9883
struct registry_priv *registry_par = &adapter->registrypriv;
9884
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9885
struct security_priv *psecuritypriv = &adapter->securitypriv;
9886
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
9887
struct sta_info *psta = NULL;
9888
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
9889
int res;
9890
u16 media_status_rpt;
9891
u8 no_wake = 0;
9892
9893
#ifdef CONFIG_LPS_PG
9894
u8 lps_pg_hdl_id = 0;
9895
#endif
9896
9897
9898
9899
if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
9900
!check_fwstate(pmlmepriv, _FW_LINKED))
9901
no_wake = 1;
9902
9903
RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
9904
rtw_hal_gate_bb(adapter, _TRUE);
9905
#ifdef CONFIG_GTK_OL
9906
if (psecuritypriv->binstallKCK_KEK == _TRUE)
9907
rtw_hal_fw_sync_cam_id(adapter);
9908
#endif
9909
if (IS_HARDWARE_TYPE_8723B(adapter))
9910
rtw_hal_backup_rate(adapter);
9911
9912
rtw_hal_fw_dl(adapter, _TRUE);
9913
if(no_wake)
9914
media_status_rpt = RT_MEDIA_DISCONNECT;
9915
else
9916
media_status_rpt = RT_MEDIA_CONNECT;
9917
rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
9918
(u8 *)&media_status_rpt);
9919
9920
/* RX DMA stop */
9921
#if defined(CONFIG_RTL8188E)
9922
if (IS_HARDWARE_TYPE_8188E(adapter))
9923
rtw_hal_disable_tx_report(adapter);
9924
#endif
9925
9926
res = rtw_hal_pause_rx_dma(adapter);
9927
if (res == _FAIL)
9928
RTW_PRINT("[WARNING] pause RX DMA fail\n");
9929
9930
#ifndef CONFIG_WOW_PATTERN_HW_CAM
9931
/* Reconfig RX_FF Boundary */
9932
rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
9933
#endif
9934
9935
/* redownload wow pattern */
9936
if(!no_wake)
9937
rtw_hal_dl_pattern(adapter, 1);
9938
9939
if (!pwrctl->wowlan_pno_enable) {
9940
psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
9941
9942
if (psta != NULL) {
9943
#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
9944
adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
9945
adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
9946
rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
9947
#endif
9948
if(!no_wake)
9949
rtw_sta_media_status_rpt(adapter, psta, 1);
9950
}
9951
}
9952
9953
#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
9954
/* Enable CPWM2 only. */
9955
res = rtw_hal_enable_cpwm2(adapter);
9956
if (res == _FAIL)
9957
RTW_PRINT("[WARNING] enable cpwm2 fail\n");
9958
#endif
9959
#ifdef CONFIG_GPIO_WAKEUP
9960
rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _TRUE);
9961
#endif
9962
/* Set WOWLAN H2C command. */
9963
RTW_PRINT("Set WOWLan cmd\n");
9964
rtw_hal_set_fw_wow_related_cmd(adapter, 1);
9965
9966
res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
9967
9968
if (res == _FALSE)
9969
RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
9970
9971
pwrctl->wowlan_wake_reason =
9972
rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
9973
9974
RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
9975
pwrctl->wowlan_wake_reason);
9976
#ifdef CONFIG_GTK_OL_DBG
9977
dump_sec_cam(RTW_DBGDUMP, adapter);
9978
dump_sec_cam_cache(RTW_DBGDUMP, adapter);
9979
#endif
9980
9981
#ifdef CONFIG_LPS_PG
9982
if (pwrctl->lps_level == LPS_PG) {
9983
lps_pg_hdl_id = LPS_PG_INFO_CFG;
9984
rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
9985
}
9986
#endif
9987
9988
#ifdef CONFIG_USB_HCI
9989
/* free adapter's resource */
9990
rtw_mi_intf_stop(adapter);
9991
9992
#endif
9993
#if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
9994
/* Invoid SE0 reset signal during suspending*/
9995
rtw_write8(adapter, REG_RSV_CTRL, 0x20);
9996
if (IS_8188F(pHalData->version_id) == FALSE
9997
&& IS_8188GTV(pHalData->version_id) == FALSE)
9998
rtw_write8(adapter, REG_RSV_CTRL, 0x60);
9999
#endif
10000
10001
rtw_hal_gate_bb(adapter, _FALSE);
10002
}
10003
10004
#define DBG_WAKEUP_REASON
10005
#ifdef DBG_WAKEUP_REASON
10006
void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
10007
{
10008
RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
10009
}
10010
void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
10011
{
10012
if (RX_PAIRWISEKEY == reason)
10013
_dbg_wake_up_reason_string(adapter, "Rx pairwise key");
10014
else if (RX_GTK == reason)
10015
_dbg_wake_up_reason_string(adapter, "Rx GTK");
10016
else if (RX_FOURWAY_HANDSHAKE == reason)
10017
_dbg_wake_up_reason_string(adapter, "Rx four way handshake");
10018
else if (RX_DISASSOC == reason)
10019
_dbg_wake_up_reason_string(adapter, "Rx disassoc");
10020
else if (RX_DEAUTH == reason)
10021
_dbg_wake_up_reason_string(adapter, "Rx deauth");
10022
else if (RX_ARP_REQUEST == reason)
10023
_dbg_wake_up_reason_string(adapter, "Rx ARP request");
10024
else if (FW_DECISION_DISCONNECT == reason)
10025
_dbg_wake_up_reason_string(adapter, "FW detect disconnect");
10026
else if (RX_MAGIC_PKT == reason)
10027
_dbg_wake_up_reason_string(adapter, "Rx magic packet");
10028
else if (RX_UNICAST_PKT == reason)
10029
_dbg_wake_up_reason_string(adapter, "Rx unicast packet");
10030
else if (RX_PATTERN_PKT == reason)
10031
_dbg_wake_up_reason_string(adapter, "Rx pattern packet");
10032
else if (RTD3_SSID_MATCH == reason)
10033
_dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
10034
else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
10035
_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
10036
else if (RX_REALWOW_V2_ACK_LOST == reason)
10037
_dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
10038
else if (ENABLE_FAIL_DMA_IDLE == reason)
10039
_dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
10040
else if (ENABLE_FAIL_DMA_PAUSE == reason)
10041
_dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
10042
else if (AP_OFFLOAD_WAKEUP == reason)
10043
_dbg_wake_up_reason_string(adapter, "AP offload wakeup");
10044
else if (CLK_32K_UNLOCK == reason)
10045
_dbg_wake_up_reason_string(adapter, "clk 32k unlock");
10046
else if (RTIME_FAIL_DMA_IDLE == reason)
10047
_dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
10048
else if (CLK_32K_LOCK == reason)
10049
_dbg_wake_up_reason_string(adapter, "clk 32k lock");
10050
else
10051
_dbg_wake_up_reason_string(adapter, "unknown reasoen");
10052
}
10053
#endif
10054
10055
static void rtw_hal_wow_disable(_adapter *adapter)
10056
{
10057
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10058
struct security_priv *psecuritypriv = &adapter->securitypriv;
10059
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10060
struct sta_info *psta = NULL;
10061
struct registry_priv *registry_par = &adapter->registrypriv;
10062
int res;
10063
u16 media_status_rpt;
10064
u8 val8;
10065
10066
RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
10067
10068
if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, _FW_LINKED)) {
10069
RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");
10070
return;
10071
}
10072
10073
if (!pwrctl->wowlan_pno_enable) {
10074
psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10075
if (psta != NULL)
10076
rtw_sta_media_status_rpt(adapter, psta, 0);
10077
else
10078
RTW_INFO("%s: psta is null\n", __func__);
10079
}
10080
10081
if (0) {
10082
RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
10083
RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
10084
RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
10085
RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
10086
}
10087
10088
pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10089
10090
RTW_PRINT("wakeup_reason: 0x%02x\n",
10091
pwrctl->wowlan_wake_reason);
10092
#ifdef DBG_WAKEUP_REASON
10093
_dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
10094
#endif
10095
10096
rtw_hal_set_fw_wow_related_cmd(adapter, 0);
10097
10098
res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
10099
10100
if (res == _FALSE) {
10101
RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
10102
rtw_hal_force_enable_rxdma(adapter);
10103
}
10104
10105
rtw_hal_gate_bb(adapter, _TRUE);
10106
10107
res = rtw_hal_pause_rx_dma(adapter);
10108
if (res == _FAIL)
10109
RTW_PRINT("[WARNING] pause RX DMA fail\n");
10110
10111
/* clean HW pattern match */
10112
rtw_hal_dl_pattern(adapter, 0);
10113
10114
#ifndef CONFIG_WOW_PATTERN_HW_CAM
10115
/* config RXFF boundary to original */
10116
rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
10117
#endif
10118
rtw_hal_release_rx_dma(adapter);
10119
10120
#if defined(CONFIG_RTL8188E)
10121
if (IS_HARDWARE_TYPE_8188E(adapter))
10122
rtw_hal_enable_tx_report(adapter);
10123
#endif
10124
10125
if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10126
(pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
10127
(pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
10128
rtw_hal_get_aoac_rpt(adapter);
10129
rtw_hal_update_sw_security_info(adapter);
10130
}
10131
10132
rtw_hal_fw_dl(adapter, _FALSE);
10133
10134
#ifdef CONFIG_GPIO_WAKEUP
10135
10136
#ifdef CONFIG_RTW_ONE_PIN_GPIO
10137
rtw_hal_set_input_gpio(adapter, WAKEUP_GPIO_IDX);
10138
#else
10139
#ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10140
if (pwrctl->is_high_active == 0)
10141
rtw_hal_set_input_gpio(adapter, WAKEUP_GPIO_IDX);
10142
else
10143
rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, 0);
10144
#else
10145
val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
10146
RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
10147
10148
rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, val8);
10149
rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _FALSE);
10150
#endif
10151
#endif /* CONFIG_RTW_ONE_PIN_GPIO */
10152
#endif
10153
if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
10154
(pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
10155
(pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10156
(pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
10157
10158
media_status_rpt = RT_MEDIA_CONNECT;
10159
rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10160
(u8 *)&media_status_rpt);
10161
10162
if (psta != NULL) {
10163
#ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10164
adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10165
adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10166
rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10167
#endif
10168
rtw_sta_media_status_rpt(adapter, psta, 1);
10169
}
10170
}
10171
rtw_hal_gate_bb(adapter, _FALSE);
10172
}
10173
#endif /*CONFIG_WOWLAN*/
10174
10175
#ifdef CONFIG_P2P_WOWLAN
10176
void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
10177
u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
10178
RSVDPAGE_LOC *rsvd_page_loc)
10179
{
10180
u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
10181
u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
10182
u8 CurtPktPageNum = 0;
10183
10184
/* P2P Beacon */
10185
rsvd_page_loc->LocP2PBeacon = *page_num;
10186
rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
10187
rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10188
P2PBCNLength, _FALSE, _FALSE, _FALSE);
10189
10190
#if 0
10191
RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
10192
__FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
10193
#endif
10194
10195
CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
10196
10197
*page_num += CurtPktPageNum;
10198
10199
index += (CurtPktPageNum * page_size);
10200
RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
10201
10202
/* P2P Probe rsp */
10203
rsvd_page_loc->LocP2PProbeRsp = *page_num;
10204
rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
10205
&P2PProbeRspLength);
10206
rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10207
P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
10208
10209
/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", */
10210
/* __FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
10211
10212
CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
10213
10214
*page_num += CurtPktPageNum;
10215
10216
index += (CurtPktPageNum * page_size);
10217
RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
10218
10219
/* P2P nego rsp */
10220
rsvd_page_loc->LocNegoRsp = *page_num;
10221
rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
10222
&P2PNegoRspLength);
10223
rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10224
P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
10225
10226
/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
10227
/* __FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
10228
10229
CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
10230
10231
*page_num += CurtPktPageNum;
10232
10233
index += (CurtPktPageNum * page_size);
10234
RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
10235
10236
/* P2P invite rsp */
10237
rsvd_page_loc->LocInviteRsp = *page_num;
10238
rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
10239
&P2PInviteRspLength);
10240
rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10241
P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
10242
10243
/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
10244
/* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
10245
10246
CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
10247
10248
*page_num += CurtPktPageNum;
10249
10250
index += (CurtPktPageNum * page_size);
10251
RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
10252
10253
/* P2P provision discovery rsp */
10254
rsvd_page_loc->LocPDRsp = *page_num;
10255
rtw_hal_construct_P2PProvisionDisRsp(adapter,
10256
&pframe[index], &P2PPDRspLength);
10257
10258
rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10259
P2PPDRspLength, _FALSE, _FALSE, _FALSE);
10260
10261
/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
10262
/* __FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
10263
10264
CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
10265
10266
*page_num += CurtPktPageNum;
10267
10268
*total_pkt_len = index + P2PPDRspLength;
10269
RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
10270
10271
index += (CurtPktPageNum * page_size);
10272
10273
10274
}
10275
#endif /* CONFIG_P2P_WOWLAN */
10276
10277
#ifdef CONFIG_LPS_PG
10278
#ifndef DBG_LPSPG_INFO_DUMP
10279
#define DBG_LPSPG_INFO_DUMP 1
10280
#endif
10281
10282
#include "hal_halmac.h"
10283
10284
#ifdef CONFIG_RTL8822C
10285
static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)
10286
{
10287
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10288
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10289
struct dm_struct *dm = adapter_to_phydm(adapter);
10290
struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;
10291
u8 *info = NULL;
10292
u32 info_len;
10293
int ret = _FAIL;
10294
10295
/* get length */
10296
halrf_dpk_info_rsvd_page(dm, NULL, &info_len);
10297
if (!info_len) {
10298
RTW_ERR("get %s length fail\n", cache->name);
10299
goto exit;
10300
}
10301
10302
/* allocate buf */
10303
info = rtw_zmalloc(info_len);
10304
if (!info) {
10305
RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10306
goto exit;
10307
}
10308
10309
/* get content */
10310
halrf_dpk_info_rsvd_page(dm, info, NULL);
10311
10312
if (rsvd_page_cache_update_data(cache, info, info_len)) {
10313
10314
#if (DBG_LPSPG_INFO_DUMP >= 1)
10315
RTW_INFO_DUMP(cache->name, info, info_len);
10316
#endif
10317
10318
ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10319
ret = !ret ? _SUCCESS : _FAIL;
10320
if (ret != _SUCCESS) {
10321
RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10322
goto free_mem;
10323
}
10324
10325
#if (DBG_LPSPG_INFO_DUMP >= 2)
10326
RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10327
rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10328
#endif
10329
}
10330
10331
free_mem:
10332
rtw_mfree(info, info_len);
10333
10334
exit:
10335
return ret;
10336
}
10337
10338
static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)
10339
{
10340
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10341
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10342
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10343
struct dm_struct *dm = adapter_to_phydm(adapter);
10344
struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;
10345
u8 *info = NULL;
10346
u32 info_len = 0;
10347
int ret = _FAIL;
10348
10349
if (hal_data->RegIQKFWOffload) {
10350
rsvd_page_cache_free_data(cache);
10351
ret = _SUCCESS;
10352
goto exit;
10353
}
10354
10355
/* get length */
10356
halrf_iqk_info_rsvd_page(dm, NULL, &info_len);
10357
if (!info_len) {
10358
RTW_ERR("get %s length fail\n", cache->name);
10359
goto exit;
10360
}
10361
10362
/* allocate buf */
10363
info = rtw_zmalloc(info_len);
10364
if (!info) {
10365
RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10366
goto exit;
10367
}
10368
10369
/* get content */
10370
halrf_iqk_info_rsvd_page(dm, info, NULL);
10371
10372
if (rsvd_page_cache_update_data(cache, info, info_len)) {
10373
10374
#if (DBG_LPSPG_INFO_DUMP >= 1)
10375
RTW_INFO_DUMP(cache->name, info, info_len);
10376
#endif
10377
10378
ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10379
ret = !ret ? _SUCCESS : _FAIL;
10380
if (ret != _SUCCESS) {
10381
RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10382
goto free_mem;
10383
}
10384
10385
#if (DBG_LPSPG_INFO_DUMP >= 2)
10386
RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10387
rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10388
#endif
10389
}
10390
10391
free_mem:
10392
rtw_mfree(info, info_len);
10393
10394
exit:
10395
return ret;
10396
}
10397
#endif /* CONFIG_RTL8822C */
10398
10399
static void rtw_hal_build_lps_pg_info_rsvd_page(_adapter *adapter, u8 *buf, u32 *buf_size)
10400
{
10401
#define LPS_PG_INFO_RSVD_LEN 16
10402
10403
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10404
struct sta_info *psta;
10405
#ifdef CONFIG_MBSSID_CAM
10406
u8 cam_id = INVALID_CAM_ID;
10407
#endif
10408
u8 *psec_cam_id = buf + 8;
10409
u8 sec_cam_num = 0;
10410
u8 drv_rsvdpage_num = 0;
10411
10412
if (buf) {
10413
psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
10414
if (!psta) {
10415
RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
10416
rtw_warn_on(1);
10417
return;
10418
}
10419
10420
/*Byte 0 - used macid*/
10421
LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);
10422
RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
10423
10424
#ifdef CONFIG_MBSSID_CAM
10425
/*Byte 1 - used BSSID CAM entry*/
10426
cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
10427
if (cam_id != INVALID_CAM_ID)
10428
LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);
10429
RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
10430
#endif
10431
10432
#ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
10433
/*Btye 2 - Max used Pattern Match CAM entry*/
10434
if (pwrpriv->wowlan_mode == _TRUE &&
10435
check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _TRUE) {
10436
LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);
10437
RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
10438
}
10439
#endif
10440
#ifdef CONFIG_BEAMFORMING /*&& MU BF*/
10441
/*Btye 3 - Max MU rate table Group ID*/
10442
LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);
10443
RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
10444
#endif
10445
10446
/*Btye 8 ~15 - used Security CAM entry */
10447
sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
10448
10449
/*Btye 4 - used Security CAM entry number*/
10450
if (sec_cam_num < 8)
10451
LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);
10452
RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
10453
10454
/*Btye 5 - Txbuf used page number for fw offload*/
10455
if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
10456
drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
10457
else
10458
drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
10459
LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);
10460
RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
10461
}
10462
10463
if (buf_size)
10464
*buf_size = LPS_PG_INFO_RSVD_LEN;
10465
}
10466
10467
static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
10468
{
10469
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10470
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10471
struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;
10472
u8 *info = NULL;
10473
u32 info_len = 0;
10474
int ret = _FAIL;
10475
10476
/* get length */
10477
rtw_hal_build_lps_pg_info_rsvd_page(adapter, NULL, &info_len);
10478
if (!info_len) {
10479
RTW_ERR("get %s length fail\n", cache->name);
10480
goto exit;
10481
}
10482
10483
/* allocate buf */
10484
info = rtw_zmalloc(info_len);
10485
if (!info) {
10486
RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10487
goto exit;
10488
}
10489
10490
/* get content */
10491
rtw_hal_build_lps_pg_info_rsvd_page(adapter, info, NULL);
10492
10493
if (rsvd_page_cache_update_data(cache, info, info_len)) {
10494
10495
#if (DBG_LPSPG_INFO_DUMP >= 1)
10496
RTW_INFO_DUMP(cache->name, info, info_len);
10497
#endif
10498
10499
ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10500
ret = !ret ? _SUCCESS : _FAIL;
10501
if (ret != _SUCCESS) {
10502
RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10503
goto free_mem;
10504
}
10505
10506
#if (DBG_LPSPG_INFO_DUMP >= 2)
10507
RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10508
rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10509
#endif
10510
}
10511
10512
free_mem:
10513
rtw_mfree(info, info_len);
10514
10515
exit:
10516
return ret;
10517
}
10518
10519
static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index
10520
, u8 txdesc_size, u32 page_size, u8 *total_page_num, bool is_wow_mode, bool only_get_page_num)
10521
{
10522
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10523
struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10524
struct rsvd_page_cache_t *cache;
10525
u8 *pos;
10526
u32 len;
10527
10528
/* lps_level will not change when enter wow_mode */
10529
if (is_wow_mode && pwrctl->lps_level != LPS_PG)
10530
return;
10531
10532
pos = only_get_page_num ? NULL : frame + *index;
10533
10534
#ifdef CONFIG_RTL8822C
10535
if (IS_8822C_SERIES(hal_data->version_id)) {
10536
/* LPSPG_DPK_INFO */
10537
cache = &pwrctl->lpspg_dpk_info;
10538
if (pwrctl->lps_level != LPS_PG)
10539
pos = NULL;
10540
halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10541
if (pos) {
10542
#if (DBG_LPSPG_INFO_DUMP >= 1)
10543
RTW_INFO_DUMP(cache->name, pos, len);
10544
#endif
10545
}
10546
rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10547
*total_page_num += cache->page_num;
10548
*index += page_size * cache->page_num;
10549
pos = only_get_page_num ? NULL : frame + *index;
10550
RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10551
10552
/* LPSPG_IQK_INFO */
10553
cache = &pwrctl->lpspg_iqk_info;
10554
if (!(is_wow_mode && hal_data->RegIQKFWOffload)) { /* RegIQKFWOffload will not change when enter wow_mode */
10555
if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)
10556
pos = NULL;
10557
halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10558
if (pos) {
10559
#if (DBG_LPSPG_INFO_DUMP >= 1)
10560
RTW_INFO_DUMP(cache->name, pos, len);
10561
#endif
10562
}
10563
rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10564
*total_page_num += cache->page_num;
10565
*index += page_size * cache->page_num;
10566
pos = only_get_page_num ? NULL : frame + *index;
10567
RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10568
} else
10569
rsvd_page_cache_free_data(cache);
10570
}
10571
#endif
10572
10573
/* LPSPG_INFO */
10574
cache = &pwrctl->lpspg_info;
10575
if (pwrctl->lps_level != LPS_PG)
10576
pos = NULL;
10577
rtw_hal_build_lps_pg_info_rsvd_page(adapter, pos, &len);
10578
if (pos) {
10579
#if (DBG_LPSPG_INFO_DUMP >= 1)
10580
RTW_INFO_DUMP(cache->name, pos, len);
10581
#endif
10582
}
10583
rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10584
*total_page_num += cache->page_num;
10585
*index += page_size * cache->page_num;
10586
pos = only_get_page_num ? NULL : frame + *index;
10587
RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10588
}
10589
10590
static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
10591
{
10592
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10593
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10594
10595
u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
10596
u8 ret = _FAIL;
10597
10598
if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
10599
SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1); /*SecurityCAM_En*/
10600
10601
#ifdef CONFIG_MBSSID_CAM
10602
SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1); /*BSSIDCAM_En*/
10603
#endif
10604
10605
#if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
10606
if (pwrpriv->wowlan_mode == _TRUE &&
10607
check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
10608
10609
SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/
10610
}
10611
#endif
10612
10613
#ifdef CONFIG_MACID_SEARCH
10614
SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1); /*MACIDSearch_En*/
10615
#endif
10616
10617
#ifdef CONFIG_TX_SC
10618
SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1); /*TXSC_En*/
10619
#endif
10620
10621
#ifdef CONFIG_BEAMFORMING /*&& MU BF*/
10622
SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1); /*MURateTable_En*/
10623
#endif
10624
10625
SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);
10626
10627
#ifdef CONFIG_RTL8822C
10628
SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);
10629
if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
10630
SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);
10631
#endif
10632
10633
#if (DBG_LPSPG_INFO_DUMP >= 1)
10634
RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);
10635
#endif
10636
10637
ret = rtw_hal_fill_h2c_cmd(adapter,
10638
H2C_LPS_PG_INFO,
10639
H2C_LPS_PG_INFO_LEN,
10640
lpspg_info);
10641
return ret;
10642
}
10643
u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
10644
{
10645
u8 ret = _FAIL;
10646
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10647
10648
if (pwrpriv->lpspg_info.loc == 0) {
10649
RTW_ERR("%s lpspg_info.loc = 0\n", __func__);
10650
rtw_warn_on(1);
10651
return ret;
10652
}
10653
#ifdef CONFIG_RTL8822C
10654
rtw_lps_pg_set_dpk_info_rsvd_page(adapter);
10655
rtw_lps_pg_set_iqk_info_rsvd_page(adapter);
10656
#endif
10657
rtw_hal_set_lps_pg_info_rsvd_page(adapter);
10658
10659
ret = rtw_hal_set_lps_pg_info_cmd(adapter);
10660
10661
return ret;
10662
}
10663
10664
void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
10665
{
10666
#if 0
10667
if (sta->cmn.ra_info.rssi_level >= 4)
10668
sta->lps_pg_rssi_lv = 3; /*RSSI High - 1SS_VHT_MCS7*/
10669
else if (sta->cmn.ra_info.rssi_level >= 2)
10670
sta->lps_pg_rssi_lv = 2; /*RSSI Middle - 1SS_VHT_MCS3*/
10671
else
10672
sta->lps_pg_rssi_lv = 1; /*RSSI Lower - Lowest_rate*/
10673
#else
10674
sta->lps_pg_rssi_lv = 0;
10675
#endif
10676
RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
10677
__func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
10678
}
10679
10680
void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
10681
{
10682
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
10683
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10684
struct sta_priv *pstapriv = &adapter->stapriv;
10685
struct sta_info *sta;
10686
10687
sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
10688
10689
switch (hdl_id) {
10690
case LPS_PG_INFO_CFG:
10691
rtw_hal_set_lps_pg_info(adapter);
10692
break;
10693
case LPS_PG_REDLEMEM:
10694
if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
10695
break;
10696
10697
/*set xmit_block*/
10698
rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
10699
if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
10700
rtw_warn_on(1);
10701
/*clearn xmit_block*/
10702
rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
10703
break;
10704
case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
10705
if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
10706
break;
10707
10708
if (sta)
10709
rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
10710
break;
10711
case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
10712
if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
10713
break;
10714
10715
if (sta) {
10716
rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
10717
rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
10718
sta->lps_pg_rssi_lv = 0;
10719
}
10720
break;
10721
10722
default:
10723
break;
10724
}
10725
}
10726
10727
#endif /*CONFIG_LPS_PG*/
10728
10729
static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
10730
{
10731
u8 mi_iface_num = 0;
10732
10733
if (0) {
10734
RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
10735
RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
10736
RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
10737
RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
10738
RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
10739
/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
10740
/*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
10741
}
10742
10743
mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
10744
DEV_AP_NUM(adapter_to_dvobj(adapter)) +
10745
DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
10746
return mi_iface_num;
10747
}
10748
#ifdef CONFIG_CONCURRENT_MODE
10749
static _adapter *_rtw_search_sta_iface(_adapter *adapter)
10750
{
10751
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10752
_adapter *iface = NULL;
10753
_adapter *sta_iface = NULL;
10754
int i;
10755
10756
for (i = 0; i < dvobj->iface_nums; i++) {
10757
iface = dvobj->padapters[i];
10758
if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
10759
if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) {
10760
sta_iface = iface;
10761
break;
10762
}
10763
}
10764
}
10765
return sta_iface;
10766
}
10767
#if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)
10768
static _adapter *_rtw_search_ap_iface(_adapter *adapter)
10769
{
10770
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10771
_adapter *iface = NULL;
10772
_adapter *ap_iface = NULL;
10773
int i;
10774
10775
for (i = 0; i < dvobj->iface_nums; i++) {
10776
iface = dvobj->padapters[i];
10777
if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
10778
ap_iface = iface;
10779
break;
10780
}
10781
}
10782
return ap_iface;
10783
}
10784
#endif/*CONFIG_AP_MODE*/
10785
#endif/*CONFIG_CONCURRENT_MODE*/
10786
10787
#ifdef CONFIG_CUSTOMER01_SMART_ANTENNA
10788
void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)
10789
{
10790
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
10791
struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
10792
10793
return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);
10794
}
10795
#endif
10796
10797
/*
10798
* Description: Fill the reserved packets that FW will use to RSVD page.
10799
* Now we just send 4 types packet to rsvd page.
10800
* (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
10801
* Input:
10802
* finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
10803
* so we need to set the packet length to total lengh.
10804
* TRUE: At the second time, we should send the first packet (default:beacon)
10805
* to Hw again and set the lengh in descriptor to the real beacon lengh.
10806
* page_num - The amount of reserved page which driver need.
10807
* If this is not NULL, this function doesn't real download reserved
10808
* page, but just count the number of reserved page.
10809
*
10810
* 2009.10.15 by tynli.
10811
* 2017.06.20 modified by Lucas.
10812
*
10813
* Page Size = 128: 8188e, 8723a/b, 8192c/d,
10814
* Page Size = 256: 8192e, 8821a
10815
* Page Size = 512: 8812a
10816
*/
10817
10818
/*#define DBG_DUMP_SET_RSVD_PAGE*/
10819
static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
10820
{
10821
PHAL_DATA_TYPE pHalData;
10822
struct xmit_frame *pcmdframe = NULL;
10823
struct pkt_attrib *pattrib;
10824
struct xmit_priv *pxmitpriv;
10825
struct pwrctrl_priv *pwrctl;
10826
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10827
u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
10828
u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
10829
u32 ProbeReqLength = 0, NullFunctionDataLength = 0;
10830
u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
10831
u8 TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
10832
u8 *ReservedPagePacket;
10833
u16 BufIndex = 0;
10834
u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
10835
RSVDPAGE_LOC RsvdPageLoc;
10836
struct registry_priv *registry_par = &adapter->registrypriv;
10837
10838
#ifdef DBG_FW_DEBUG_MSG_PKT
10839
u32 fw_dbg_msg_pkt_len = 0;
10840
#endif /*DBG_FW_DEBUG_MSG_PKT*/
10841
10842
#ifdef DBG_CONFIG_ERROR_DETECT
10843
struct sreset_priv *psrtpriv;
10844
#endif /* DBG_CONFIG_ERROR_DETECT */
10845
10846
#ifdef CONFIG_MCC_MODE
10847
u8 dl_mcc_page = _FAIL;
10848
#endif /* CONFIG_MCC_MODE */
10849
u8 nr_assoc_if;
10850
10851
_adapter *sta_iface = NULL;
10852
_adapter *ap_iface = NULL;
10853
10854
bool is_wow_mode = _FALSE;
10855
10856
pHalData = GET_HAL_DATA(adapter);
10857
#ifdef DBG_CONFIG_ERROR_DETECT
10858
psrtpriv = &pHalData->srestpriv;
10859
#endif
10860
pxmitpriv = &adapter->xmitpriv;
10861
pwrctl = adapter_to_pwrctl(adapter);
10862
10863
rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
10864
10865
if (PageSize == 0) {
10866
RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
10867
return;
10868
}
10869
nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
10870
10871
if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
10872
pwrctl->wowlan_ap_mode == _TRUE ||
10873
pwrctl->wowlan_p2p_mode == _TRUE)
10874
is_wow_mode = _TRUE;
10875
10876
/*page_num for init time to get rsvd page number*/
10877
/* Prepare ReservedPagePacket */
10878
if (page_num) {
10879
ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
10880
if (!ReservedPagePacket) {
10881
RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
10882
*page_num = 0xFF;
10883
return;
10884
}
10885
RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm ==>\n",
10886
FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
10887
10888
} else {
10889
if (is_wow_mode)
10890
RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
10891
else
10892
RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
10893
10894
RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
10895
FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
10896
10897
MaxRsvdPageBufSize = RsvdPageNum * PageSize;
10898
if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
10899
RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
10900
__func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
10901
rtw_warn_on(1);
10902
return;
10903
}
10904
10905
pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
10906
if (pcmdframe == NULL) {
10907
RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
10908
return;
10909
}
10910
10911
ReservedPagePacket = pcmdframe->buf_addr;
10912
}
10913
10914
_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
10915
10916
BufIndex = TxDescOffset;
10917
10918
/*======== beacon content =======*/
10919
rtw_hal_construct_beacon(adapter,
10920
&ReservedPagePacket[BufIndex], &BeaconLength);
10921
10922
/*
10923
* When we count the first page size, we need to reserve description size for the RSVD
10924
* packet, it will be filled in front of the packet in TXPKTBUF.
10925
*/
10926
BeaconLength = MAX_BEACON_LEN - TxDescLen;
10927
CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
10928
10929
#ifdef CONFIG_FW_HANDLE_TXBCN
10930
CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
10931
#endif
10932
TotalPageNum += CurtPktPageNum;
10933
10934
BufIndex += (CurtPktPageNum * PageSize);
10935
10936
RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
10937
10938
/*======== probe response content ========*/
10939
if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
10940
#ifdef CONFIG_CONCURRENT_MODE
10941
if (nr_assoc_if >= 2)
10942
RTW_ERR("Not support > 2 net-interface in WOW\n");
10943
#endif
10944
/* (4) probe response*/
10945
RsvdPageLoc.LocProbeRsp = TotalPageNum;
10946
rtw_hal_construct_ProbeRsp(
10947
adapter, &ReservedPagePacket[BufIndex],
10948
&ProbeRspLength,
10949
_FALSE);
10950
rtw_hal_fill_fake_txdesc(adapter,
10951
&ReservedPagePacket[BufIndex - TxDescLen],
10952
ProbeRspLength, _FALSE, _FALSE, _FALSE);
10953
10954
CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
10955
TotalPageNum += CurtPktPageNum;
10956
TotalPacketLen = BufIndex + ProbeRspLength;
10957
BufIndex += (CurtPktPageNum * PageSize);
10958
RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
10959
goto download_page;
10960
}
10961
10962
/*======== ps-poll content * 1 page ========*/
10963
sta_iface = adapter;
10964
#ifdef CONFIG_CONCURRENT_MODE
10965
if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
10966
sta_iface = _rtw_search_sta_iface(adapter);
10967
RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
10968
}
10969
#endif
10970
10971
if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
10972
RsvdPageLoc.LocPsPoll = TotalPageNum;
10973
RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
10974
rtw_hal_construct_PSPoll(sta_iface,
10975
&ReservedPagePacket[BufIndex], &PSPollLength);
10976
rtw_hal_fill_fake_txdesc(sta_iface,
10977
&ReservedPagePacket[BufIndex - TxDescLen],
10978
PSPollLength, _TRUE, _FALSE, _FALSE);
10979
10980
CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
10981
10982
TotalPageNum += CurtPktPageNum;
10983
10984
BufIndex += (CurtPktPageNum * PageSize);
10985
RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
10986
}
10987
10988
#ifdef CONFIG_MCC_MODE
10989
/*======== MCC * n page ======== */
10990
if (MCC_EN(adapter)) {/*Normal mode*/
10991
dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
10992
&BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
10993
} else {
10994
dl_mcc_page = _FAIL;
10995
}
10996
10997
if (dl_mcc_page == _FAIL)
10998
#endif /* CONFIG_MCC_MODE */
10999
{ /*======== null data * 1 page ======== */
11000
if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11001
RsvdPageLoc.LocNullData = TotalPageNum;
11002
RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
11003
rtw_hal_construct_NullFunctionData(
11004
sta_iface,
11005
&ReservedPagePacket[BufIndex],
11006
&NullDataLength,
11007
_FALSE, 0, 0, _FALSE);
11008
rtw_hal_fill_fake_txdesc(sta_iface,
11009
&ReservedPagePacket[BufIndex - TxDescLen],
11010
NullDataLength, _FALSE, _FALSE, _FALSE);
11011
11012
CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
11013
11014
TotalPageNum += CurtPktPageNum;
11015
11016
BufIndex += (CurtPktPageNum * PageSize);
11017
RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11018
}
11019
}
11020
11021
/*======== Qos null data * 1 page ======== */
11022
if (pwrctl->wowlan_mode == _FALSE ||
11023
pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11024
if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11025
RsvdPageLoc.LocQosNull = TotalPageNum;
11026
RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
11027
rtw_hal_construct_NullFunctionData(sta_iface,
11028
&ReservedPagePacket[BufIndex],
11029
&QosNullLength,
11030
_TRUE, 0, 0, _FALSE);
11031
rtw_hal_fill_fake_txdesc(sta_iface,
11032
&ReservedPagePacket[BufIndex - TxDescLen],
11033
QosNullLength, _FALSE, _FALSE, _FALSE);
11034
11035
CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
11036
PageSize);
11037
11038
TotalPageNum += CurtPktPageNum;
11039
11040
BufIndex += (CurtPktPageNum * PageSize);
11041
RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11042
}
11043
}
11044
11045
#ifdef CONFIG_BT_COEXIST
11046
/*======== BT Qos null data * 1 page ======== */
11047
if (pwrctl->wowlan_mode == _FALSE ||
11048
pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11049
11050
ap_iface = adapter;
11051
#ifdef CONFIG_CONCURRENT_MODE
11052
if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) { /*DEV_AP_STARTING_NUM*/
11053
ap_iface = _rtw_search_ap_iface(adapter);
11054
RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
11055
}
11056
#endif
11057
11058
if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
11059
RsvdPageLoc.LocBTQosNull = TotalPageNum;
11060
11061
RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
11062
11063
rtw_hal_construct_NullFunctionData(ap_iface,
11064
&ReservedPagePacket[BufIndex],
11065
&BTQosNullLength,
11066
_TRUE, 0, 0, _FALSE);
11067
11068
rtw_hal_fill_fake_txdesc(ap_iface,
11069
&ReservedPagePacket[BufIndex - TxDescLen],
11070
BTQosNullLength, _FALSE, _TRUE, _FALSE);
11071
11072
CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
11073
PageSize);
11074
11075
TotalPageNum += CurtPktPageNum;
11076
BufIndex += (CurtPktPageNum * PageSize);
11077
11078
RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11079
}
11080
}
11081
#endif /* CONFIG_BT_COEXIT */
11082
11083
TotalPacketLen = BufIndex;
11084
11085
#ifdef DBG_FW_DEBUG_MSG_PKT
11086
/*======== FW DEBUG MSG * n page ======== */
11087
RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
11088
RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
11089
rtw_hal_construct_fw_dbg_msg_pkt(
11090
adapter,
11091
&ReservedPagePacket[BufIndex],
11092
&fw_dbg_msg_pkt_len);
11093
11094
rtw_hal_fill_fake_txdesc(adapter,
11095
&ReservedPagePacket[BufIndex - TxDescLen],
11096
fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
11097
11098
CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
11099
11100
TotalPageNum += CurtPktPageNum;
11101
11102
TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
11103
BufIndex += (CurtPktPageNum * PageSize);
11104
#endif /*DBG_FW_DEBUG_MSG_PKT*/
11105
11106
#ifdef CONFIG_LPS_PG
11107
rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex
11108
, TxDescLen, PageSize, &TotalPageNum, is_wow_mode, page_num ? 1 : 0);
11109
TotalPacketLen = BufIndex;
11110
#endif
11111
11112
#ifdef CONFIG_WOWLAN
11113
/*======== WOW * n page ======== */
11114
if (pwrctl->wowlan_mode == _TRUE &&
11115
pwrctl->wowlan_in_resume == _FALSE &&
11116
!(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, _FW_LINKED))) {/*WOW mode*/
11117
rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11118
BufIndex, TxDescLen, PageSize,
11119
&TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11120
}
11121
#endif /* CONFIG_WOWLAN */
11122
11123
#ifdef CONFIG_P2P_WOWLAN
11124
/*======== P2P WOW * n page ======== */
11125
if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
11126
rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11127
BufIndex, TxDescLen, PageSize,
11128
&TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11129
}
11130
#endif /* CONFIG_P2P_WOWLAN */
11131
11132
/*Note: BufIndex already add a TxDescOffset offset in first Beacon page
11133
* The "TotalPacketLen" is calculate by BufIndex.
11134
* We need to decrease TxDescOffset before doing length check. by yiwei
11135
*/
11136
TotalPacketLen = TotalPacketLen - TxDescOffset;
11137
11138
download_page:
11139
if (page_num) {
11140
*page_num = TotalPageNum;
11141
rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
11142
ReservedPagePacket = NULL;
11143
RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
11144
FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11145
return;
11146
}
11147
11148
/* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
11149
RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
11150
__func__, TotalPageNum, TotalPacketLen);
11151
11152
if (TotalPacketLen > MaxRsvdPageBufSize) {
11153
RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
11154
__FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
11155
rtw_warn_on(1);
11156
goto error;
11157
} else {
11158
/* update attribute */
11159
pattrib = &pcmdframe->attrib;
11160
update_mgntframe_attrib(adapter, pattrib);
11161
pattrib->qsel = QSLT_BEACON;
11162
pattrib->pktlen = TotalPacketLen;
11163
pattrib->last_txcmdsz = TotalPacketLen;
11164
#ifdef CONFIG_PCI_HCI
11165
dump_mgntframe(adapter, pcmdframe);
11166
#else
11167
dump_mgntframe_and_wait(adapter, pcmdframe, 100);
11168
#endif
11169
}
11170
11171
RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
11172
__func__, TotalPacketLen, TotalPageNum);
11173
#ifdef DBG_DUMP_SET_RSVD_PAGE
11174
RTW_INFO(" ==================================================\n");
11175
RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
11176
RTW_INFO(" ==================================================\n");
11177
#endif
11178
11179
11180
if (check_fwstate(pmlmepriv, _FW_LINKED)
11181
|| MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
11182
rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
11183
#ifdef DBG_FW_DEBUG_MSG_PKT
11184
rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
11185
#endif /*DBG_FW_DEBUG_MSG_PKT*/
11186
#ifdef CONFIG_WOWLAN
11187
if (pwrctl->wowlan_mode == _TRUE &&
11188
pwrctl->wowlan_in_resume == _FALSE)
11189
rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11190
#endif /* CONFIG_WOWLAN */
11191
#ifdef CONFIG_AP_WOWLAN
11192
if (pwrctl->wowlan_ap_mode == _TRUE)
11193
rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
11194
#endif /* CONFIG_AP_WOWLAN */
11195
} else if (pwrctl->wowlan_pno_enable) {
11196
#ifdef CONFIG_PNO_SUPPORT
11197
rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11198
if (pwrctl->wowlan_in_resume)
11199
rtw_hal_set_scan_offload_info_cmd(adapter,
11200
&RsvdPageLoc, 0);
11201
else
11202
rtw_hal_set_scan_offload_info_cmd(adapter,
11203
&RsvdPageLoc, 1);
11204
#endif /* CONFIG_PNO_SUPPORT */
11205
}
11206
11207
#ifdef CONFIG_P2P_WOWLAN
11208
if (_TRUE == pwrctl->wowlan_p2p_mode)
11209
rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
11210
#endif /* CONFIG_P2P_WOWLAN */
11211
11212
return;
11213
error:
11214
rtw_free_xmitframe(pxmitpriv, pcmdframe);
11215
}
11216
11217
void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
11218
{
11219
if (finished)
11220
rtw_mi_tx_beacon_hdl(adapter);
11221
else
11222
_rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
11223
}
11224
11225
/**
11226
* rtw_hal_get_rsvd_page_num() - Get needed reserved page number
11227
* @adapter: struct _ADAPTER*
11228
*
11229
* Caculate needed reserved page number.
11230
* In different state would get different number, for example normal mode and
11231
* WOW mode would need different reserved page size.
11232
*
11233
* Return the number of reserved page which driver need.
11234
*/
11235
u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
11236
{
11237
u8 num = 0;
11238
11239
11240
_rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
11241
11242
return num;
11243
}
11244
11245
#ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
11246
static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
11247
{
11248
u32 bcn_ctrl_reg;
11249
11250
#ifdef CONFIG_CONCURRENT_MODE
11251
if (adapter->hw_port == HW_PORT1)
11252
bcn_ctrl_reg = REG_BCN_CTRL_1;
11253
else
11254
#endif
11255
bcn_ctrl_reg = REG_BCN_CTRL;
11256
11257
if (enable)
11258
rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
11259
else {
11260
u8 val8;
11261
11262
val8 = rtw_read8(adapter, bcn_ctrl_reg);
11263
val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
11264
11265
#ifdef CONFIG_BT_COEXIST
11266
if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
11267
/* Always enable port0 beacon function for PSTDMA */
11268
if (REG_BCN_CTRL == bcn_ctrl_reg)
11269
val8 |= EN_BCN_FUNCTION;
11270
}
11271
#endif
11272
11273
rtw_write8(adapter, bcn_ctrl_reg, val8);
11274
}
11275
11276
#ifdef CONFIG_RTL8192F
11277
if (IS_HARDWARE_TYPE_8192F(adapter)) {
11278
u16 val16, val16_ori;
11279
11280
val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
11281
11282
#ifdef CONFIG_CONCURRENT_MODE
11283
if (adapter->hw_port == HW_PORT1) {
11284
if (enable)
11285
val16 |= EN_PORT_1_FUNCTION;
11286
else
11287
val16 &= ~EN_PORT_1_FUNCTION;
11288
} else
11289
#endif
11290
{
11291
if (enable)
11292
val16 |= EN_PORT_0_FUNCTION;
11293
else
11294
val16 &= ~EN_PORT_0_FUNCTION;
11295
11296
#ifdef CONFIG_BT_COEXIST
11297
if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
11298
val16 |= EN_PORT_0_FUNCTION;
11299
#endif
11300
}
11301
11302
if (val16 != val16_ori)
11303
rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, val16);
11304
}
11305
#endif
11306
}
11307
#endif
11308
11309
#ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
11310
static void hw_var_set_mlme_disconnect(_adapter *adapter)
11311
{
11312
u8 val8;
11313
11314
/* reject all data frames */
11315
#ifdef CONFIG_CONCURRENT_MODE
11316
if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11317
#endif
11318
rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
11319
11320
#ifdef CONFIG_CONCURRENT_MODE
11321
if (adapter->hw_port == HW_PORT1) {
11322
/* reset TSF1 */
11323
rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
11324
11325
/* disable update TSF1 */
11326
rtw_iface_disable_tsf_update(adapter);
11327
11328
if (!IS_HARDWARE_TYPE_8723D(adapter)
11329
&& !IS_HARDWARE_TYPE_8192F(adapter)
11330
&& !IS_HARDWARE_TYPE_8710B(adapter)
11331
) {
11332
/* disable Port1's beacon function */
11333
val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
11334
val8 &= ~EN_BCN_FUNCTION;
11335
rtw_write8(adapter, REG_BCN_CTRL_1, val8);
11336
}
11337
} else
11338
#endif
11339
{
11340
/* reset TSF */
11341
rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
11342
11343
/* disable update TSF */
11344
rtw_iface_disable_tsf_update(adapter);
11345
}
11346
}
11347
#endif
11348
11349
static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
11350
{
11351
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11352
u16 value_rxfltmap2;
11353
11354
#ifdef DBG_IFACE_STATUS
11355
DBG_IFACE_STATUS_DUMP(adapter);
11356
#endif
11357
11358
#ifdef CONFIG_FIND_BEST_CHANNEL
11359
/* Receive all data frames */
11360
value_rxfltmap2 = 0xFFFF;
11361
#else
11362
/* not to receive data frame */
11363
value_rxfltmap2 = 0;
11364
#endif
11365
11366
if (enable) { /* under sitesurvey */
11367
/*
11368
* 1. configure REG_RXFLTMAP2
11369
* 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
11370
* 3. config RCR to receive different BSSID BCN or probe rsp
11371
*/
11372
rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
11373
11374
rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
11375
11376
/* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */
11377
#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11378
hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);
11379
hal_data->RegRRSR &= 0x000FFFFF;
11380
#endif
11381
11382
#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11383
if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11384
/* set 718[1:0]=2'b00 to avoid BF scan hang */
11385
hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
11386
rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
11387
}
11388
#endif
11389
11390
if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11391
StopTxBeacon(adapter);
11392
} else { /* sitesurvey done */
11393
/*
11394
* 1. enable rx data frame
11395
* 2. config RCR not to receive different BSSID BCN or probe rsp
11396
* 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict
11397
* so, we enable TSF update when rx first BCN after sitesurvey done
11398
*/
11399
if (rtw_mi_check_fwstate(adapter, _FW_LINKED | WIFI_AP_STATE | WIFI_MESH_STATE)) {
11400
/* enable to rx data frame */
11401
rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11402
}
11403
11404
rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
11405
11406
/* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */
11407
#if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11408
rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);
11409
#endif
11410
11411
#if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11412
if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11413
/* Restore orignal 0x718 setting*/
11414
rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
11415
}
11416
#endif
11417
11418
if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11419
ResumeTxBeacon(adapter);
11420
rtw_mi_tx_beacon_hdl(adapter);
11421
}
11422
}
11423
}
11424
11425
#ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
11426
static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
11427
{
11428
u8 val8;
11429
u16 val16;
11430
u32 val32;
11431
u8 RetryLimit = RL_VAL_STA;
11432
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11433
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11434
11435
#ifdef CONFIG_CONCURRENT_MODE
11436
if (type == 0) {
11437
/* prepare to join */
11438
if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11439
StopTxBeacon(adapter);
11440
11441
/* enable to rx data frame.Accept all data frame */
11442
rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11443
11444
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11445
RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11446
else /* Ad-hoc Mode */
11447
RetryLimit = RL_VAL_AP;
11448
11449
rtw_iface_enable_tsf_update(adapter);
11450
11451
} else if (type == 1) {
11452
/* joinbss_event call back when join res < 0 */
11453
if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11454
rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11455
11456
rtw_iface_disable_tsf_update(adapter);
11457
11458
if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11459
ResumeTxBeacon(adapter);
11460
11461
/* reset TSF 1/2 after ResumeTxBeacon */
11462
rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11463
}
11464
11465
} else if (type == 2) {
11466
/* sta add event call back */
11467
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
11468
/* fixed beacon issue for 8191su........... */
11469
rtw_write8(adapter, 0x542 , 0x02);
11470
RetryLimit = RL_VAL_AP;
11471
}
11472
11473
if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11474
ResumeTxBeacon(adapter);
11475
11476
/* reset TSF 1/2 after ResumeTxBeacon */
11477
rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11478
}
11479
}
11480
11481
val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11482
rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11483
#else /* !CONFIG_CONCURRENT_MODE */
11484
if (type == 0) { /* prepare to join */
11485
/* enable to rx data frame.Accept all data frame */
11486
rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11487
11488
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11489
RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11490
else /* Ad-hoc Mode */
11491
RetryLimit = RL_VAL_AP;
11492
11493
rtw_iface_enable_tsf_update(adapter);
11494
11495
} else if (type == 1) { /* joinbss_event call back when join res < 0 */
11496
rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11497
11498
rtw_iface_disable_tsf_update(adapter);
11499
11500
} else if (type == 2) { /* sta add event call back */
11501
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
11502
RetryLimit = RL_VAL_AP;
11503
}
11504
11505
val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11506
rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11507
#endif /* !CONFIG_CONCURRENT_MODE */
11508
}
11509
#endif
11510
11511
#ifdef CONFIG_TSF_RESET_OFFLOAD
11512
static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
11513
{
11514
u8 buf[2];
11515
int ret;
11516
11517
if (reset_port == HW_PORT0) {
11518
buf[0] = 0x1;
11519
buf[1] = 0;
11520
} else {
11521
buf[0] = 0x0;
11522
buf[1] = 0x1;
11523
}
11524
11525
ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
11526
11527
return ret;
11528
}
11529
11530
int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
11531
{
11532
u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
11533
u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
11534
REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
11535
int ret;
11536
11537
/* site survey will cause reset tsf fail */
11538
rtw_mi_buddy_scan_abort(adapter, _FALSE);
11539
reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
11540
ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
11541
if (ret != _SUCCESS)
11542
return ret;
11543
11544
while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
11545
rtw_msleep_os(100);
11546
loop_cnt++;
11547
reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
11548
}
11549
11550
return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
11551
}
11552
#endif /* CONFIG_TSF_RESET_OFFLOAD */
11553
11554
#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
11555
#ifdef CONFIG_HW_P0_TSF_SYNC
11556
#ifdef CONFIG_CONCURRENT_MODE
11557
static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
11558
{
11559
u8 val8;
11560
u8 client_id = 0;
11561
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11562
11563
#ifdef CONFIG_MCC_MODE
11564
if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
11565
RTW_INFO("[MCC] do not set HW TSF sync\n");
11566
return;
11567
}
11568
#endif
11569
/* check if port0 is already synced */
11570
if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
11571
RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
11572
FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
11573
return;
11574
}
11575
11576
/* check if port0 already disable sync */
11577
if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
11578
RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
11579
return;
11580
}
11581
11582
/* check if port0 sync to port0 */
11583
if (benable && hw_port == HW_PORT0) {
11584
RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
11585
rtw_warn_on(1);
11586
return;
11587
}
11588
11589
/*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
11590
/* Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
11591
Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
11592
11593
val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
11594
11595
if (benable) {
11596
/*Disable Port0's beacon function*/
11597
rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
11598
11599
/*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
11600
if (tr_offset)
11601
rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
11602
11603
/*reg 0x577[6]=1*/ /*auto sync by tbtt*/
11604
rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
11605
11606
if (HW_PORT1 == hw_port)
11607
client_id = 0;
11608
else if (HW_PORT2 == hw_port)
11609
client_id = 1;
11610
else if (HW_PORT3 == hw_port)
11611
client_id = 2;
11612
else if (HW_PORT4 == hw_port)
11613
client_id = 3;
11614
11615
val8 &= 0x8F;
11616
val8 |= (BIT(6) | (client_id << 4));
11617
11618
dvobj->p0_tsf.sync_port = hw_port;
11619
dvobj->p0_tsf.offset = tr_offset;
11620
rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
11621
11622
/*Enable Port0's beacon function*/
11623
rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) | BIT_EN_BCN_FUNCTION);
11624
RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
11625
} else {
11626
val8 &= ~BIT(6);
11627
11628
dvobj->p0_tsf.sync_port = MAX_HW_PORT;
11629
dvobj->p0_tsf.offset = 0;
11630
rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
11631
RTW_INFO("%s P0 TSF sync disable\n", __func__);
11632
}
11633
}
11634
static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
11635
{
11636
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11637
u8 i;
11638
_adapter *iface = NULL;
11639
11640
if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
11641
RTW_ERR("STA_LD_NUM == 0\n");
11642
rtw_warn_on(1);
11643
}
11644
11645
for (i = 0; i < dvobj->iface_nums; i++) {
11646
iface = dvobj->padapters[i];
11647
if (!iface)
11648
continue;
11649
if (include_self == _FALSE && adapter == iface)
11650
continue;
11651
if (is_client_associated_to_ap(iface))
11652
break;
11653
}
11654
if (iface)
11655
RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
11656
return iface;
11657
}
11658
#endif /*CONFIG_CONCURRENT_MODE*/
11659
/*Correct port0's TSF*/
11660
/*#define DBG_P0_TSF_SYNC*/
11661
void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
11662
{
11663
#ifdef CONFIG_CONCURRENT_MODE
11664
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11665
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
11666
_adapter *sta_if = NULL;
11667
u8 hw_port;
11668
11669
RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
11670
#ifdef DBG_P0_TSF_SYNC
11671
RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
11672
RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
11673
RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
11674
if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
11675
RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
11676
else
11677
RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
11678
RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
11679
#endif
11680
switch (mlme_state) {
11681
case MLME_STA_CONNECTED :
11682
{
11683
hw_port = rtw_hal_get_port(adapter);
11684
11685
if (!MLME_IS_STA(adapter)) {
11686
RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
11687
rtw_warn_on(1);
11688
}
11689
11690
if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
11691
RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
11692
rtw_warn_on(1);
11693
hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
11694
}
11695
11696
if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
11697
(rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
11698
hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
11699
#ifdef DBG_P0_TSF_SYNC
11700
RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
11701
#endif
11702
}
11703
}
11704
break;
11705
case MLME_STA_DISCONNECTED :
11706
{
11707
hw_port = rtw_hal_get_port(adapter);
11708
11709
if (!MLME_IS_STA(adapter)) {
11710
RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
11711
rtw_warn_on(1);
11712
}
11713
11714
if (dvobj->p0_tsf.sync_port == hw_port) {
11715
if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
11716
/* search next appropriate sta*/
11717
sta_if = _search_ld_sta(adapter, _FALSE);
11718
if (sta_if) {
11719
hw_port = rtw_hal_get_port(sta_if);
11720
hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
11721
#ifdef DBG_P0_TSF_SYNC
11722
RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
11723
#endif
11724
}
11725
} else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
11726
hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
11727
#ifdef DBG_P0_TSF_SYNC
11728
RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
11729
#endif
11730
}
11731
}
11732
}
11733
break;
11734
case MLME_AP_STARTED :
11735
case MLME_MESH_STARTED :
11736
{
11737
if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
11738
RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
11739
rtw_warn_on(1);
11740
}
11741
11742
if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
11743
rtw_mi_get_assoced_sta_num(adapter)) {
11744
/* get port of sta */
11745
sta_if = _search_ld_sta(adapter, _FALSE);
11746
if (sta_if) {
11747
hw_port = rtw_hal_get_port(sta_if);
11748
hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
11749
#ifdef DBG_P0_TSF_SYNC
11750
RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
11751
#endif
11752
}
11753
}
11754
}
11755
break;
11756
case MLME_AP_STOPPED :
11757
case MLME_MESH_STOPPED :
11758
{
11759
if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
11760
RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
11761
rtw_warn_on(1);
11762
}
11763
/*stop ap mode*/
11764
if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
11765
(dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
11766
hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
11767
#ifdef DBG_P0_TSF_SYNC
11768
RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
11769
#endif
11770
}
11771
}
11772
break;
11773
default :
11774
RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
11775
break;
11776
}
11777
11778
/*#ifdef DBG_P0_TSF_SYNC*/
11779
#if 1
11780
if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
11781
RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
11782
else
11783
RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
11784
RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
11785
#endif
11786
#endif /*CONFIG_CONCURRENT_MODE*/
11787
}
11788
11789
#else /*! CONFIG_HW_P0_TSF_SYNC*/
11790
11791
#ifdef CONFIG_MI_WITH_MBSSID_CAM
11792
static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
11793
{
11794
/*do nothing*/
11795
}
11796
#else /* !CONFIG_MI_WITH_MBSSID_CAM*/
11797
static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
11798
{
11799
if (hw_port == HW_PORT0) {
11800
/*disable related TSF function*/
11801
rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
11802
#if defined(CONFIG_RTL8192F)
11803
rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
11804
REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
11805
#endif
11806
11807
rtw_write32(padapter, REG_TSFTR, tsf);
11808
rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
11809
11810
/*enable related TSF function*/
11811
rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
11812
#if defined(CONFIG_RTL8192F)
11813
rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
11814
REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
11815
#endif
11816
} else if (hw_port == HW_PORT1) {
11817
/*disable related TSF function*/
11818
rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
11819
#if defined(CONFIG_RTL8192F)
11820
rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
11821
REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);
11822
#endif
11823
11824
rtw_write32(padapter, REG_TSFTR1, tsf);
11825
rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
11826
11827
/*enable related TSF function*/
11828
rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
11829
#if defined(CONFIG_RTL8192F)
11830
rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
11831
REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
11832
#endif
11833
} else
11834
RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
11835
}
11836
static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
11837
{
11838
u64 tsf;
11839
struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
11840
struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
11841
11842
tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
11843
11844
if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
11845
|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
11846
StopTxBeacon(adapter);
11847
11848
rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
11849
11850
#ifdef CONFIG_CONCURRENT_MODE
11851
/* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
11852
if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
11853
&& (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11854
) {
11855
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11856
int i;
11857
_adapter *iface;
11858
11859
for (i = 0; i < dvobj->iface_nums; i++) {
11860
iface = dvobj->padapters[i];
11861
if (!iface)
11862
continue;
11863
if (iface == adapter)
11864
continue;
11865
11866
if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
11867
&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
11868
) {
11869
rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
11870
#ifdef CONFIG_TSF_RESET_OFFLOAD
11871
if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
11872
RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
11873
, __func__, ADPT_ARG(iface), iface->hw_port);
11874
#endif /* CONFIG_TSF_RESET_OFFLOAD*/
11875
}
11876
}
11877
}
11878
#endif /* CONFIG_CONCURRENT_MODE */
11879
if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
11880
|| (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
11881
ResumeTxBeacon(adapter);
11882
}
11883
#endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
11884
#endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/
11885
#endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/
11886
11887
u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
11888
{
11889
struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
11890
u64 tsftr = 0;
11891
11892
if (port >= hal_spec->port_num) {
11893
RTW_ERR("%s invalid port(%d) \n", __func__, port);
11894
goto exit;
11895
}
11896
11897
switch (rtw_get_chip_type(adapter)) {
11898
#if defined(CONFIG_RTL8814B)
11899
case RTL8814B:
11900
{
11901
u8 val8;
11902
11903
/* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */
11904
val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);
11905
val8 &= ~0x70;
11906
val8 |= port << 4;
11907
rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);
11908
11909
tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);
11910
tsftr = tsftr << 32;
11911
tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);
11912
11913
break;
11914
}
11915
#endif
11916
#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
11917
case RTL8814A:
11918
case RTL8822B:
11919
case RTL8821C:
11920
case RTL8822C:
11921
{
11922
u8 val8;
11923
11924
/* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
11925
val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
11926
val8 &= 0x8F;
11927
val8 |= port << 4;
11928
rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
11929
11930
tsftr = rtw_read32(adapter, REG_TSFTR + 4);
11931
tsftr = tsftr << 32;
11932
tsftr |= rtw_read32(adapter, REG_TSFTR);
11933
11934
break;
11935
}
11936
#endif
11937
#if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
11938
|| defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
11939
|| defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
11940
|| defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
11941
|| defined(CONFIG_RTL8710B)
11942
case RTL8188E:
11943
case RTL8188F:
11944
case RTL8188GTV:
11945
case RTL8192E:
11946
case RTL8192F:
11947
case RTL8723B:
11948
case RTL8703B:
11949
case RTL8723D:
11950
case RTL8812:
11951
case RTL8821:
11952
case RTL8710B:
11953
{
11954
u32 addr;
11955
11956
if (port == HW_PORT0)
11957
addr = REG_TSFTR;
11958
else if (port == HW_PORT1)
11959
addr = REG_TSFTR1;
11960
else {
11961
RTW_ERR("%s unknown port(%d) \n", __func__, port);
11962
goto exit;
11963
}
11964
11965
tsftr = rtw_read32(adapter, addr + 4);
11966
tsftr = tsftr << 32;
11967
tsftr |= rtw_read32(adapter, addr);
11968
11969
break;
11970
}
11971
#endif
11972
default:
11973
RTW_ERR("%s unknow chip type\n", __func__);
11974
}
11975
11976
exit:
11977
return tsftr;
11978
}
11979
11980
#ifdef CONFIG_TDLS
11981
#ifdef CONFIG_TDLS_CH_SW
11982
s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
11983
{
11984
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
11985
u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
11986
11987
11988
SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
11989
SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
11990
switch (bwmode) {
11991
case CHANNEL_WIDTH_40:
11992
SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
11993
break;
11994
case CHANNEL_WIDTH_80:
11995
SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
11996
break;
11997
case CHANNEL_WIDTH_20:
11998
default:
11999
break;
12000
}
12001
SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
12002
12003
return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
12004
}
12005
#endif
12006
#endif
12007
12008
#ifdef CONFIG_WMMPS_STA
12009
void rtw_hal_update_uapsd_tid(_adapter *adapter)
12010
{
12011
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12012
struct qos_priv *pqospriv = &pmlmepriv->qospriv;
12013
12014
/* write complement of pqospriv->uapsd_tid to mac register 0x693 because
12015
it's designed for "0" represents "enable" and "1" represents "disable" */
12016
rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
12017
}
12018
#endif /* CONFIG_WMMPS_STA */
12019
12020
#if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
12021
/* For multi-port support, driver needs to inform the port ID to FW for btc operations */
12022
s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
12023
{
12024
u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
12025
u8 hw_port = rtw_hal_get_port(adapter);
12026
12027
SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
12028
RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
12029
return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
12030
}
12031
#endif
12032
12033
#define LPS_ACTIVE_TIMEOUT 50 /*number of times*/
12034
void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
12035
{
12036
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
12037
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12038
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12039
struct sta_priv *pstapriv = &adapter->stapriv;
12040
struct sta_info *psta = NULL;
12041
u8 ps_ready = _FALSE;
12042
s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
12043
12044
if (ps_mode == PS_MODE_ACTIVE) {
12045
#ifdef CONFIG_LPS_ACK
12046
if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {
12047
if (pwrpriv->lps_ack_status > 0) {
12048
psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
12049
if (psta != NULL) {
12050
if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)
12051
RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));
12052
}
12053
}
12054
} else {
12055
RTW_WARN("LPS sctx query timeout, operation abort!!\n");
12056
return;
12057
}
12058
pwrpriv->lps_ack_status = -1;
12059
#else
12060
do {
12061
if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
12062
ps_ready = _TRUE;
12063
break;
12064
}
12065
rtw_msleep_os(1);
12066
} while (leave_wait_count--);
12067
12068
if (ps_ready == _FALSE) {
12069
RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));
12070
return;
12071
}
12072
#endif /* CONFIG_LPS_ACK */
12073
}
12074
}
12075
12076
void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {
12077
12078
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
12079
struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
12080
u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
12081
u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
12082
u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
12083
#ifdef CONFIG_IEEE80211_BAND_5GHZ
12084
u16 rrsr_5g_force_mask = (RRSR_6M);
12085
u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);
12086
#endif
12087
u32 temp_RRSR;
12088
12089
HalSetBrateCfg(padapter, val, &BrateCfg);
12090
input_b = BrateCfg;
12091
12092
/* apply force and allow mask */
12093
#ifdef CONFIG_IEEE80211_BAND_5GHZ
12094
if (pHalData->current_band_type != BAND_ON_2_4G) {
12095
BrateCfg |= rrsr_5g_force_mask;
12096
BrateCfg &= rrsr_5g_allow_mask;
12097
} else
12098
#endif
12099
{ /* 2.4G */
12100
BrateCfg |= rrsr_2g_force_mask;
12101
BrateCfg &= rrsr_2g_allow_mask;
12102
}
12103
masked = BrateCfg;
12104
12105
#ifdef CONFIG_CMCC_TEST
12106
BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
12107
BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */
12108
#endif
12109
12110
/* IOT consideration */
12111
if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
12112
/* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
12113
if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
12114
BrateCfg |= RRSR_6M;
12115
}
12116
ioted = BrateCfg;
12117
12118
#ifdef CONFIG_NARROWBAND_SUPPORTING
12119
if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
12120
|| (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {
12121
BrateCfg &= ~RRSR_CCK_RATES;
12122
BrateCfg |= RRSR_6M;
12123
}
12124
#endif
12125
pHalData->BasicRateSet = BrateCfg;
12126
12127
RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
12128
12129
/* Set RRSR rate table. */
12130
temp_RRSR = rtw_read32(padapter, REG_RRSR);
12131
temp_RRSR &=0xFFFF0000;
12132
temp_RRSR |=BrateCfg;
12133
rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);
12134
12135
rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
12136
12137
#if defined(CONFIG_RTL8188E)
12138
rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
12139
#endif
12140
}
12141
12142
u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
12143
{
12144
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12145
u8 ret = _SUCCESS;
12146
12147
switch (variable) {
12148
case HW_VAR_MEDIA_STATUS: {
12149
u8 net_type = *((u8 *)val);
12150
12151
rtw_hal_set_msr(adapter, net_type);
12152
}
12153
break;
12154
case HW_VAR_DO_IQK:
12155
if (*val)
12156
hal_data->bNeedIQK = _TRUE;
12157
else
12158
hal_data->bNeedIQK = _FALSE;
12159
break;
12160
case HW_VAR_MAC_ADDR:
12161
#ifdef CONFIG_MI_WITH_MBSSID_CAM
12162
rtw_hal_set_macaddr_mbid(adapter, val);
12163
#else
12164
rtw_hal_set_macaddr_port(adapter, val);
12165
#endif
12166
break;
12167
case HW_VAR_BSSID:
12168
rtw_hal_set_bssid(adapter, val);
12169
break;
12170
case HW_VAR_RCR:
12171
ret = hw_var_rcr_config(adapter, *((u32 *)val));
12172
break;
12173
case HW_VAR_ON_RCR_AM:
12174
hw_var_set_rcr_am(adapter, 1);
12175
break;
12176
case HW_VAR_OFF_RCR_AM:
12177
hw_var_set_rcr_am(adapter, 0);
12178
break;
12179
case HW_VAR_BEACON_INTERVAL:
12180
hw_var_set_bcn_interval(adapter, *(u16 *)val);
12181
break;
12182
#ifdef CONFIG_MBSSID_CAM
12183
case HW_VAR_MBSSID_CAM_WRITE: {
12184
u32 cmd = 0;
12185
u32 *cam_val = (u32 *)val;
12186
12187
rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
12188
cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
12189
rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12190
}
12191
break;
12192
case HW_VAR_MBSSID_CAM_CLEAR: {
12193
u32 cmd;
12194
u8 entry_id = *(u8 *)val;
12195
12196
rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
12197
12198
cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
12199
rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12200
}
12201
break;
12202
case HW_VAR_RCR_MBSSID_EN:
12203
if (*((u8 *)val))
12204
rtw_hal_rcr_add(adapter, RCR_ENMBID);
12205
else
12206
rtw_hal_rcr_clear(adapter, RCR_ENMBID);
12207
break;
12208
#endif
12209
case HW_VAR_PORT_SWITCH:
12210
hw_var_port_switch(adapter);
12211
break;
12212
case HW_VAR_INIT_RTS_RATE: {
12213
u16 brate_cfg = *((u16 *)val);
12214
u8 rate_index = 0;
12215
HAL_VERSION *hal_ver = &hal_data->version_id;
12216
12217
if (IS_8188E(*hal_ver)) {
12218
12219
while (brate_cfg > 0x1) {
12220
brate_cfg = (brate_cfg >> 1);
12221
rate_index++;
12222
}
12223
rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
12224
} else
12225
rtw_warn_on(1);
12226
}
12227
break;
12228
case HW_VAR_SEC_CFG: {
12229
u16 reg_scr_ori;
12230
u16 reg_scr;
12231
12232
reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
12233
reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
12234
12235
if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
12236
reg_scr |= SCR_CHK_BMC;
12237
12238
if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
12239
reg_scr |= SCR_NoSKMC;
12240
12241
if (reg_scr != reg_scr_ori)
12242
rtw_write16(adapter, REG_SECCFG, reg_scr);
12243
}
12244
break;
12245
case HW_VAR_SEC_DK_CFG: {
12246
struct security_priv *sec = &adapter->securitypriv;
12247
u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
12248
12249
if (val) { /* Enable default key related setting */
12250
reg_scr |= SCR_TXBCUSEDK;
12251
if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
12252
reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
12253
} else /* Disable default key related setting */
12254
reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
12255
12256
rtw_write8(adapter, REG_SECCFG, reg_scr);
12257
}
12258
break;
12259
12260
case HW_VAR_ASIX_IOT:
12261
/* enable ASIX IOT function */
12262
if (*((u8 *)val) == _TRUE) {
12263
/* 0xa2e[0]=0 (disable rake receiver) */
12264
rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12265
rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
12266
/* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
12267
rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
12268
} else {
12269
/* restore reg:0xa2e, reg:0xa1c */
12270
rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12271
rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
12272
rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
12273
}
12274
break;
12275
#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
12276
case HW_VAR_WOWLAN: {
12277
struct wowlan_ioctl_param *poidparam;
12278
12279
poidparam = (struct wowlan_ioctl_param *)val;
12280
switch (poidparam->subcode) {
12281
#ifdef CONFIG_WOWLAN
12282
case WOWLAN_PATTERN_CLEAN:
12283
rtw_hal_dl_pattern(adapter, 2);
12284
break;
12285
case WOWLAN_ENABLE:
12286
rtw_hal_wow_enable(adapter);
12287
break;
12288
case WOWLAN_DISABLE:
12289
rtw_hal_wow_disable(adapter);
12290
break;
12291
#endif /*CONFIG_WOWLAN*/
12292
#ifdef CONFIG_AP_WOWLAN
12293
case WOWLAN_AP_ENABLE:
12294
rtw_hal_ap_wow_enable(adapter);
12295
break;
12296
case WOWLAN_AP_DISABLE:
12297
rtw_hal_ap_wow_disable(adapter);
12298
break;
12299
#endif /*CONFIG_AP_WOWLAN*/
12300
default:
12301
break;
12302
}
12303
}
12304
break;
12305
#endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
12306
12307
#ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
12308
case HW_VAR_BCN_FUNC:
12309
hw_var_set_bcn_func(adapter, *val);
12310
break;
12311
#endif
12312
12313
#ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
12314
case HW_VAR_MLME_DISCONNECT:
12315
hw_var_set_mlme_disconnect(adapter);
12316
break;
12317
#endif
12318
12319
case HW_VAR_MLME_SITESURVEY:
12320
hw_var_set_mlme_sitesurvey(adapter, *val);
12321
#ifdef CONFIG_BT_COEXIST
12322
if (hal_data->EEPROMBluetoothCoexist == 1)
12323
rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
12324
#endif
12325
break;
12326
12327
#ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
12328
case HW_VAR_MLME_JOIN:
12329
hw_var_set_mlme_join(adapter, *val);
12330
#ifdef CONFIG_BT_COEXIST
12331
if (hal_data->EEPROMBluetoothCoexist == 1) {
12332
switch (*val) {
12333
case 0:
12334
/* Notify coex. mechanism before join */
12335
rtw_btcoex_ConnectNotify(adapter, _TRUE);
12336
break;
12337
case 1:
12338
case 2:
12339
/* Notify coex. mechanism after join, whether successful or failed */
12340
rtw_btcoex_ConnectNotify(adapter, _FALSE);
12341
break;
12342
}
12343
}
12344
#endif /* CONFIG_BT_COEXIST */
12345
break;
12346
#endif
12347
12348
case HW_VAR_EN_HW_UPDATE_TSF:
12349
rtw_hal_set_hw_update_tsf(adapter);
12350
break;
12351
#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
12352
case HW_VAR_CORRECT_TSF:
12353
hw_var_set_correct_tsf(adapter, *val);
12354
break;
12355
#endif
12356
12357
#if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)
12358
case HW_VAR_TSF_AUTO_SYNC:
12359
if (*val == _TRUE)
12360
hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
12361
else
12362
hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
12363
break;
12364
#endif
12365
case HW_VAR_APFM_ON_MAC:
12366
hal_data->bMacPwrCtrlOn = *val;
12367
RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
12368
break;
12369
#ifdef CONFIG_WMMPS_STA
12370
case HW_VAR_UAPSD_TID:
12371
rtw_hal_update_uapsd_tid(adapter);
12372
break;
12373
#endif /* CONFIG_WMMPS_STA */
12374
#ifdef CONFIG_LPS_PG
12375
case HW_VAR_LPS_PG_HANDLE:
12376
rtw_hal_lps_pg_handler(adapter, *val);
12377
break;
12378
#endif
12379
#ifdef CONFIG_LPS_LCLK_WD_TIMER
12380
case HW_VAR_DM_IN_LPS_LCLK:
12381
rtw_phydm_wd_lps_lclk_hdl(adapter);
12382
break;
12383
#endif
12384
case HW_VAR_ENABLE_RX_BAR:
12385
if (*val == _TRUE) {
12386
/* enable RX BAR */
12387
u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12388
12389
val16 |= BIT(8);
12390
rtw_write16(adapter, REG_RXFLTMAP1, val16);
12391
} else {
12392
/* disable RX BAR */
12393
u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12394
12395
val16 &= (~BIT(8));
12396
rtw_write16(adapter, REG_RXFLTMAP1, val16);
12397
}
12398
RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
12399
REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
12400
break;
12401
case HW_VAR_HCI_SUS_STATE:
12402
hal_data->hci_sus_state = *(u8 *)val;
12403
RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
12404
break;
12405
#if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
12406
case HW_VAR_BCN_HEAD_SEL:
12407
{
12408
u8 vap_id = *(u8 *)val;
12409
12410
if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
12411
RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
12412
rtw_warn_on(1);
12413
}
12414
if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
12415
u16 drv_pg_bndy = 0, bcn_addr = 0;
12416
u32 page_size = 0;
12417
12418
/*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
12419
rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
12420
rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
12421
12422
if (vap_id != 0xFF)
12423
bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
12424
else
12425
bcn_addr = drv_pg_bndy;
12426
RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
12427
ADPT_ARG(adapter), vap_id, bcn_addr);
12428
rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
12429
(bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
12430
}
12431
}
12432
break;
12433
#endif
12434
case HW_VAR_LPS_STATE_CHK :
12435
rtw_lps_state_chk(adapter, *(u8 *)val);
12436
break;
12437
12438
#ifdef CONFIG_RTS_FULL_BW
12439
case HW_VAR_SET_RTS_BW:
12440
{
12441
#ifdef RTW_HALMAC
12442
rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));
12443
#else
12444
u8 temp;
12445
if(*val)
12446
temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );
12447
else
12448
temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));
12449
rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);
12450
/*RTW_INFO("HW_VAR_SET_RTS_BW val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/
12451
#endif
12452
}
12453
break;
12454
#endif/*CONFIG_RTS_FULL_BW*/
12455
#if defined(CONFIG_PCI_HCI)
12456
case HW_VAR_ENSWBCN:
12457
if (*val == _TRUE) {
12458
rtw_write8(adapter, REG_CR + 1,
12459
rtw_read8(adapter, REG_CR + 1) | BIT(0));
12460
} else
12461
rtw_write8(adapter, REG_CR + 1,
12462
rtw_read8(adapter, REG_CR + 1) & ~BIT(0));
12463
break;
12464
#endif
12465
default:
12466
if (0)
12467
RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12468
FUNC_ADPT_ARG(adapter), variable);
12469
ret = _FAIL;
12470
break;
12471
}
12472
12473
return ret;
12474
}
12475
12476
void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
12477
{
12478
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12479
u64 val64;
12480
12481
12482
switch (variable) {
12483
case HW_VAR_MAC_ADDR:
12484
rtw_hal_get_macaddr_port(adapter, val);
12485
break;
12486
case HW_VAR_BASIC_RATE:
12487
*((u16 *)val) = hal_data->BasicRateSet;
12488
break;
12489
case HW_VAR_MEDIA_STATUS:
12490
rtw_hal_get_msr(adapter, val);
12491
break;
12492
case HW_VAR_DO_IQK:
12493
*val = hal_data->bNeedIQK;
12494
break;
12495
case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
12496
if (hal_is_band_support(adapter, BAND_ON_5G))
12497
*val = _TRUE;
12498
else
12499
*val = _FALSE;
12500
break;
12501
case HW_VAR_APFM_ON_MAC:
12502
*val = hal_data->bMacPwrCtrlOn;
12503
break;
12504
case HW_VAR_RCR:
12505
hw_var_rcr_get(adapter, (u32 *)val);
12506
break;
12507
case HW_VAR_FWLPS_RF_ON:
12508
/* When we halt NIC, we should check if FW LPS is leave. */
12509
if (rtw_is_surprise_removed(adapter)
12510
|| (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
12511
) {
12512
/*
12513
* If it is in HW/SW Radio OFF or IPS state,
12514
* we do not check Fw LPS Leave,
12515
* because Fw is unload.
12516
*/
12517
*val = _TRUE;
12518
} else {
12519
u32 rcr = 0;
12520
12521
rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
12522
if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
12523
*val = _FALSE;
12524
else
12525
*val = _TRUE;
12526
}
12527
break;
12528
12529
case HW_VAR_HCI_SUS_STATE:
12530
*((u8 *)val) = hal_data->hci_sus_state;
12531
break;
12532
12533
#ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
12534
case HW_VAR_BCN_CTRL_ADDR:
12535
*((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
12536
break;
12537
#endif
12538
12539
#ifdef CONFIG_WAPI_SUPPORT
12540
case HW_VAR_CAM_EMPTY_ENTRY: {
12541
u8 ucIndex = *((u8 *)val);
12542
u8 i;
12543
u32 ulCommand = 0;
12544
u32 ulContent = 0;
12545
u32 ulEncAlgo = CAM_AES;
12546
12547
for (i = 0; i < CAM_CONTENT_COUNT; i++) {
12548
/* filled id in CAM config 2 byte */
12549
if (i == 0)
12550
ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
12551
else
12552
ulContent = 0;
12553
/* polling bit, and No Write enable, and address */
12554
ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
12555
ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
12556
/* write content 0 is equall to mark invalid */
12557
rtw_write32(adapter, REG_CAMWRITE, ulContent); /* delay_ms(40); */
12558
rtw_write32(adapter, REG_CAMCMD, ulCommand); /* delay_ms(40); */
12559
}
12560
}
12561
#endif
12562
12563
default:
12564
if (0)
12565
RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12566
FUNC_ADPT_ARG(adapter), variable);
12567
break;
12568
}
12569
12570
}
12571
12572
static u32 _get_page_size(struct _ADAPTER *a)
12573
{
12574
#ifdef RTW_HALMAC
12575
struct dvobj_priv *d;
12576
u32 size = 0;
12577
int err = 0;
12578
12579
12580
d = adapter_to_dvobj(a);
12581
12582
err = rtw_halmac_get_page_size(d, &size);
12583
if (!err)
12584
return size;
12585
12586
RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
12587
FUNC_ADPT_ARG(a), err);
12588
#endif /* RTW_HALMAC */
12589
12590
return PAGE_SIZE_128;
12591
}
12592
12593
u8
12594
SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
12595
{
12596
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12597
u8 bResult = _SUCCESS;
12598
12599
switch (variable) {
12600
12601
case HAL_DEF_DBG_DUMP_RXPKT:
12602
hal_data->bDumpRxPkt = *((u8 *)value);
12603
break;
12604
case HAL_DEF_DBG_DUMP_TXPKT:
12605
hal_data->bDumpTxPkt = *((u8 *)value);
12606
break;
12607
case HAL_DEF_ANT_DETECT:
12608
hal_data->AntDetection = *((u8 *)value);
12609
break;
12610
default:
12611
RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
12612
bResult = _FAIL;
12613
break;
12614
}
12615
12616
return bResult;
12617
}
12618
12619
#ifdef CONFIG_BEAMFORMING
12620
u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
12621
{
12622
struct registry_priv *pregistrypriv = &adapter->registrypriv;
12623
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12624
12625
if ((pregistrypriv->beamformer_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter) || IS_HARDWARE_TYPE_8821C(adapter)))
12626
return pregistrypriv->beamformer_rf_num;
12627
else if (IS_HARDWARE_TYPE_8814AE(adapter)
12628
#if 0
12629
#if defined(CONFIG_USB_HCI)
12630
|| (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) /* for USB3.0 */
12631
#endif
12632
#endif
12633
) {
12634
/*BF cap provided by Yu Chen, Sean, 2015, 01 */
12635
if (hal_data->rf_type == RF_3T3R)
12636
return 2;
12637
else if (hal_data->rf_type == RF_4T4R)
12638
return 3;
12639
else
12640
return 1;
12641
} else
12642
return 1;
12643
12644
}
12645
u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
12646
{
12647
struct registry_priv *pregistrypriv = &adapter->registrypriv;
12648
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12649
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12650
12651
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12652
12653
if ((pregistrypriv->beamformee_rf_num) && (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter) || IS_HARDWARE_TYPE_8822BU(adapter) || IS_HARDWARE_TYPE_8821C(adapter)))
12654
return pregistrypriv->beamformee_rf_num;
12655
else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
12656
if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
12657
return 2;
12658
else
12659
return 2;/*TODO: May be 3 in the future, by ChenYu. */
12660
} else
12661
return 1;
12662
12663
}
12664
#ifdef RTW_BEAMFORMING_VERSION_2
12665
void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
12666
{
12667
struct dm_struct *p_dm_odm;
12668
struct beamforming_info *bf_info;
12669
u8 fix_rate_enable = 0;
12670
u8 new_csi_rate_idx;
12671
u8 rrsr_54_en;
12672
u32 temp_rrsr;
12673
12674
/* Acting as BFee */
12675
if (IS_BEAMFORMEE(adapter)) {
12676
#if 0
12677
/* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
12678
if (IS_HARDWARE_TYPE_8821C(Adapter))
12679
FixRateEnable = 1; /* Support after 8821C */
12680
#endif
12681
12682
p_dm_odm = adapter_to_phydm(adapter);
12683
bf_info = GET_BEAMFORM_INFO(adapter);
12684
12685
rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
12686
p_dm_odm->rssi_min,
12687
bf_info->cur_csi_rpt_rate,
12688
fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);
12689
12690
temp_rrsr = rtw_read32(adapter, REG_RRSR);
12691
if (rrsr_54_en == 1)
12692
temp_rrsr |= RRSR_54M;
12693
else if (rrsr_54_en == 0)
12694
temp_rrsr &= ~RRSR_54M;
12695
rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);
12696
12697
if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
12698
bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
12699
}
12700
}
12701
#endif
12702
#endif
12703
12704
u8
12705
GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
12706
{
12707
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12708
u8 bResult = _SUCCESS;
12709
12710
switch (variable) {
12711
case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
12712
struct mlme_priv *pmlmepriv;
12713
struct sta_priv *pstapriv;
12714
struct sta_info *psta;
12715
12716
pmlmepriv = &adapter->mlmepriv;
12717
pstapriv = &adapter->stapriv;
12718
psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
12719
if (psta)
12720
*((int *)value) = psta->cmn.rssi_stat.rssi;
12721
}
12722
break;
12723
case HAL_DEF_DBG_DUMP_RXPKT:
12724
*((u8 *)value) = hal_data->bDumpRxPkt;
12725
break;
12726
case HAL_DEF_DBG_DUMP_TXPKT:
12727
*((u8 *)value) = hal_data->bDumpTxPkt;
12728
break;
12729
case HAL_DEF_ANT_DETECT:
12730
*((u8 *)value) = hal_data->AntDetection;
12731
break;
12732
case HAL_DEF_TX_PAGE_SIZE:
12733
*((u32 *)value) = _get_page_size(adapter);
12734
break;
12735
case HAL_DEF_TX_STBC:
12736
#ifdef CONFIG_ALPHA_SMART_ANTENNA
12737
*(u8 *)value = 0;
12738
#else
12739
*(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;
12740
#endif
12741
break;
12742
case HAL_DEF_EXPLICIT_BEAMFORMER:
12743
case HAL_DEF_EXPLICIT_BEAMFORMEE:
12744
case HAL_DEF_VHT_MU_BEAMFORMER:
12745
case HAL_DEF_VHT_MU_BEAMFORMEE:
12746
*(u8 *)value = _FALSE;
12747
break;
12748
#ifdef CONFIG_BEAMFORMING
12749
case HAL_DEF_BEAMFORMER_CAP:
12750
*(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
12751
break;
12752
case HAL_DEF_BEAMFORMEE_CAP:
12753
*(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
12754
break;
12755
#endif
12756
default:
12757
RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
12758
bResult = _FAIL;
12759
break;
12760
}
12761
12762
return bResult;
12763
}
12764
12765
12766
BOOLEAN
12767
eqNByte(
12768
u8 *str1,
12769
u8 *str2,
12770
u32 num
12771
)
12772
{
12773
if (num == 0)
12774
return _FALSE;
12775
while (num > 0) {
12776
num--;
12777
if (str1[num] != str2[num])
12778
return _FALSE;
12779
}
12780
return _TRUE;
12781
}
12782
12783
/*
12784
* Description:
12785
* Translate a character to hex digit.
12786
* */
12787
u32
12788
MapCharToHexDigit(
12789
char chTmp
12790
)
12791
{
12792
if (chTmp >= '0' && chTmp <= '9')
12793
return chTmp - '0';
12794
else if (chTmp >= 'a' && chTmp <= 'f')
12795
return 10 + (chTmp - 'a');
12796
else if (chTmp >= 'A' && chTmp <= 'F')
12797
return 10 + (chTmp - 'A');
12798
else
12799
return 0;
12800
}
12801
12802
12803
12804
/*
12805
* Description:
12806
* Parse hex number from the string pucStr.
12807
* */
12808
BOOLEAN
12809
GetHexValueFromString(
12810
char *szStr,
12811
u32 *pu4bVal,
12812
u32 *pu4bMove
12813
)
12814
{
12815
char *szScan = szStr;
12816
12817
/* Check input parameter. */
12818
if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
12819
RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
12820
return _FALSE;
12821
}
12822
12823
/* Initialize output. */
12824
*pu4bMove = 0;
12825
*pu4bVal = 0;
12826
12827
/* Skip leading space. */
12828
while (*szScan != '\0' &&
12829
(*szScan == ' ' || *szScan == '\t')) {
12830
szScan++;
12831
(*pu4bMove)++;
12832
}
12833
12834
/* Skip leading '0x' or '0X'. */
12835
if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
12836
szScan += 2;
12837
(*pu4bMove) += 2;
12838
}
12839
12840
/* Check if szScan is now pointer to a character for hex digit, */
12841
/* if not, it means this is not a valid hex number. */
12842
if (!IsHexDigit(*szScan))
12843
return _FALSE;
12844
12845
/* Parse each digit. */
12846
do {
12847
(*pu4bVal) <<= 4;
12848
*pu4bVal += MapCharToHexDigit(*szScan);
12849
12850
szScan++;
12851
(*pu4bMove)++;
12852
} while (IsHexDigit(*szScan));
12853
12854
return _TRUE;
12855
}
12856
12857
BOOLEAN
12858
GetFractionValueFromString(
12859
char *szStr,
12860
u8 *pInteger,
12861
u8 *pFraction,
12862
u32 *pu4bMove
12863
)
12864
{
12865
char *szScan = szStr;
12866
12867
/* Initialize output. */
12868
*pu4bMove = 0;
12869
*pInteger = 0;
12870
*pFraction = 0;
12871
12872
/* Skip leading space. */
12873
while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) {
12874
++szScan;
12875
++(*pu4bMove);
12876
}
12877
12878
if (*szScan < '0' || *szScan > '9')
12879
return _FALSE;
12880
12881
/* Parse each digit. */
12882
do {
12883
(*pInteger) *= 10;
12884
*pInteger += (*szScan - '0');
12885
12886
++szScan;
12887
++(*pu4bMove);
12888
12889
if (*szScan == '.') {
12890
++szScan;
12891
++(*pu4bMove);
12892
12893
if (*szScan < '0' || *szScan > '9')
12894
return _FALSE;
12895
12896
*pFraction += (*szScan - '0') * 10;
12897
++szScan;
12898
++(*pu4bMove);
12899
12900
if (*szScan >= '0' && *szScan <= '9') {
12901
*pFraction += *szScan - '0';
12902
++szScan;
12903
++(*pu4bMove);
12904
}
12905
return _TRUE;
12906
}
12907
} while (*szScan >= '0' && *szScan <= '9');
12908
12909
return _TRUE;
12910
}
12911
12912
/*
12913
* Description:
12914
* Return TRUE if szStr is comment out with leading " */ /* ".
12915
* */
12916
BOOLEAN
12917
IsCommentString(
12918
char *szStr
12919
)
12920
{
12921
if (*szStr == '/' && *(szStr + 1) == '/')
12922
return _TRUE;
12923
else
12924
return _FALSE;
12925
}
12926
12927
BOOLEAN
12928
GetU1ByteIntegerFromStringInDecimal(
12929
char *Str,
12930
u8 *pInt
12931
)
12932
{
12933
u16 i = 0;
12934
*pInt = 0;
12935
12936
while (Str[i] != '\0') {
12937
if (Str[i] >= '0' && Str[i] <= '9') {
12938
*pInt *= 10;
12939
*pInt += (Str[i] - '0');
12940
} else
12941
return _FALSE;
12942
++i;
12943
}
12944
12945
return _TRUE;
12946
}
12947
12948
/* <20121004, Kordan> For example,
12949
* ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
12950
* If RightQualifier does not exist, it will hang on in the while loop */
12951
BOOLEAN
12952
ParseQualifiedString(
12953
char *In,
12954
u32 *Start,
12955
char *Out,
12956
char LeftQualifier,
12957
char RightQualifier
12958
)
12959
{
12960
u32 i = 0, j = 0;
12961
char c = In[(*Start)++];
12962
12963
if (c != LeftQualifier)
12964
return _FALSE;
12965
12966
i = (*Start);
12967
c = In[(*Start)++];
12968
while (c != RightQualifier && c != '\0')
12969
c = In[(*Start)++];
12970
12971
if (c == '\0')
12972
return _FALSE;
12973
12974
j = (*Start) - 2;
12975
strncpy((char *)Out, (const char *)(In + i), j - i + 1);
12976
12977
return _TRUE;
12978
}
12979
12980
BOOLEAN
12981
isAllSpaceOrTab(
12982
u8 *data,
12983
u8 size
12984
)
12985
{
12986
u8 cnt = 0, NumOfSpaceAndTab = 0;
12987
12988
while (size > cnt) {
12989
if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
12990
++NumOfSpaceAndTab;
12991
12992
++cnt;
12993
}
12994
12995
return size == NumOfSpaceAndTab;
12996
}
12997
12998
12999
void rtw_hal_check_rxfifo_full(_adapter *adapter)
13000
{
13001
struct dvobj_priv *psdpriv = adapter->dvobj;
13002
struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
13003
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
13004
struct registry_priv *regsty = &adapter->registrypriv;
13005
int save_cnt = _FALSE;
13006
13007
if (regsty->check_hw_status == 1) {
13008
/* switch counter to RX fifo */
13009
if (IS_8188E(pHalData->version_id) ||
13010
IS_8188F(pHalData->version_id) ||
13011
IS_8188GTV(pHalData->version_id) ||
13012
IS_8812_SERIES(pHalData->version_id) ||
13013
IS_8821_SERIES(pHalData->version_id) ||
13014
IS_8723B_SERIES(pHalData->version_id) ||
13015
IS_8192E(pHalData->version_id) ||
13016
IS_8703B_SERIES(pHalData->version_id) ||
13017
IS_8723D_SERIES(pHalData->version_id) ||
13018
IS_8192F_SERIES(pHalData->version_id)) {
13019
rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
13020
save_cnt = _TRUE;
13021
} else {
13022
/* todo: other chips */
13023
}
13024
13025
13026
if (save_cnt) {
13027
pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
13028
pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
13029
pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
13030
} else {
13031
/* special value to indicate no implementation */
13032
pdbgpriv->dbg_rx_fifo_last_overflow = 1;
13033
pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
13034
pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
13035
}
13036
}
13037
}
13038
13039
void linked_info_dump(_adapter *padapter, u8 benable)
13040
{
13041
struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
13042
13043
if (padapter->bLinkInfoDump == benable)
13044
return;
13045
13046
RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
13047
13048
if (benable) {
13049
#ifdef CONFIG_LPS
13050
pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
13051
rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
13052
#endif
13053
13054
#ifdef CONFIG_IPS
13055
pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
13056
rtw_pm_set_ips(padapter, IPS_NONE);
13057
#endif
13058
} else {
13059
#ifdef CONFIG_IPS
13060
rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
13061
#endif /* CONFIG_IPS */
13062
13063
#ifdef CONFIG_LPS
13064
rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
13065
#endif /* CONFIG_LPS */
13066
}
13067
padapter->bLinkInfoDump = benable ;
13068
}
13069
13070
#ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
13071
void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
13072
{
13073
u8 isCCKrate, rf_path;
13074
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
13075
struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13076
RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
13077
HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
13078
isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13079
13080
if (isCCKrate)
13081
psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13082
13083
for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
13084
RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
13085
, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13086
13087
if (!isCCKrate) {
13088
RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
13089
psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
13090
}
13091
}
13092
}
13093
13094
void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
13095
{
13096
u8 isCCKrate, rf_path;
13097
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
13098
struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13099
_RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
13100
_RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n", HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
13101
13102
isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13103
13104
if (isCCKrate)
13105
psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13106
13107
for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
13108
_RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
13109
, rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13110
13111
if (!isCCKrate)
13112
_RTW_PRINT_SEL(sel , ",rx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n", psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
13113
else
13114
_RTW_PRINT_SEL(sel , "\n");
13115
13116
}
13117
}
13118
#endif
13119
13120
#ifdef DBG_RX_DFRAME_RAW_DATA
13121
void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
13122
{
13123
#define DBG_RX_DFRAME_RAW_DATA_UC 0
13124
#define DBG_RX_DFRAME_RAW_DATA_BMC 1
13125
#define DBG_RX_DFRAME_RAW_DATA_TYPES 2
13126
13127
_irqL irqL;
13128
u8 isCCKrate, rf_path;
13129
struct recv_priv *precvpriv = &(padapter->recvpriv);
13130
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
13131
struct sta_priv *pstapriv = &padapter->stapriv;
13132
struct sta_info *psta;
13133
struct sta_recv_dframe_info *psta_dframe_info;
13134
int i, j;
13135
_list *plist, *phead;
13136
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13137
u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
13138
13139
if (precvpriv->store_law_data_flag) {
13140
13141
_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13142
13143
for (i = 0; i < NUM_STA; i++) {
13144
phead = &(pstapriv->sta_hash[i]);
13145
plist = get_next(phead);
13146
13147
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
13148
13149
psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
13150
plist = get_next(plist);
13151
13152
if (psta) {
13153
if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE)
13154
&& (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN) != _TRUE)
13155
&& (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN) != _TRUE)) {
13156
13157
RTW_PRINT_SEL(sel, "==============================\n");
13158
RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
13159
13160
for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
13161
if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
13162
psta_dframe_info = &psta->sta_dframe_info;
13163
RTW_PRINT_SEL(sel, "\n");
13164
RTW_PRINT_SEL(sel, "Unicast:\n");
13165
} else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
13166
psta_dframe_info = &psta->sta_dframe_info_bmc;
13167
RTW_PRINT_SEL(sel, "\n");
13168
RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
13169
}
13170
13171
isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13172
13173
RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
13174
RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
13175
13176
for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
13177
if (!isCCKrate) {
13178
RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
13179
_RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
13180
} else
13181
RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
13182
}
13183
}
13184
13185
}
13186
}
13187
}
13188
}
13189
_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13190
}
13191
}
13192
#endif
13193
void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
13194
{
13195
u8 isCCKrate, rf_path , dframe_type;
13196
u8 *ptr;
13197
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13198
#ifdef DBG_RX_DFRAME_RAW_DATA
13199
struct sta_recv_dframe_info *psta_dframe_info;
13200
#endif
13201
struct recv_priv *precvpriv = &(padapter->recvpriv);
13202
PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
13203
struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
13204
struct sta_info *psta = prframe->u.hdr.psta;
13205
struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
13206
struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13207
psample_pkt_rssi->data_rate = pattrib->data_rate;
13208
ptr = prframe->u.hdr.rx_data;
13209
dframe_type = GetFrameType(ptr);
13210
/*RTW_INFO("=>%s\n", __FUNCTION__);*/
13211
13212
13213
if (precvpriv->store_law_data_flag) {
13214
isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13215
13216
psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
13217
psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
13218
13219
for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
13220
psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
13221
psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
13222
if (!isCCKrate) {
13223
psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13224
psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13225
}
13226
}
13227
#ifdef DBG_RX_DFRAME_RAW_DATA
13228
if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
13229
13230
/*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
13231
if (psta) {
13232
if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
13233
psta_dframe_info = &psta->sta_dframe_info_bmc;
13234
else
13235
psta_dframe_info = &psta->sta_dframe_info;
13236
/*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
13237
__FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
13238
if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
13239
psta_dframe_info->sta_data_rate = pattrib->data_rate;
13240
psta_dframe_info->sta_sgi = pattrib->sgi;
13241
psta_dframe_info->sta_bw_mode = pattrib->bw;
13242
for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
13243
13244
psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
13245
13246
if (!isCCKrate) {
13247
psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13248
psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13249
}
13250
}
13251
}
13252
}
13253
}
13254
#endif
13255
}
13256
13257
}
13258
13259
int hal_efuse_macaddr_offset(_adapter *adapter)
13260
{
13261
u8 interface_type = 0;
13262
int addr_offset = -1;
13263
13264
interface_type = rtw_get_intf_type(adapter);
13265
13266
switch (rtw_get_chip_type(adapter)) {
13267
#ifdef CONFIG_RTL8723B
13268
case RTL8723B:
13269
if (interface_type == RTW_USB)
13270
addr_offset = EEPROM_MAC_ADDR_8723BU;
13271
else if (interface_type == RTW_SDIO)
13272
addr_offset = EEPROM_MAC_ADDR_8723BS;
13273
else if (interface_type == RTW_PCIE)
13274
addr_offset = EEPROM_MAC_ADDR_8723BE;
13275
break;
13276
#endif
13277
#ifdef CONFIG_RTL8703B
13278
case RTL8703B:
13279
if (interface_type == RTW_USB)
13280
addr_offset = EEPROM_MAC_ADDR_8703BU;
13281
else if (interface_type == RTW_SDIO)
13282
addr_offset = EEPROM_MAC_ADDR_8703BS;
13283
break;
13284
#endif
13285
#ifdef CONFIG_RTL8723D
13286
case RTL8723D:
13287
if (interface_type == RTW_USB)
13288
addr_offset = EEPROM_MAC_ADDR_8723DU;
13289
else if (interface_type == RTW_SDIO)
13290
addr_offset = EEPROM_MAC_ADDR_8723DS;
13291
else if (interface_type == RTW_PCIE)
13292
addr_offset = EEPROM_MAC_ADDR_8723DE;
13293
break;
13294
#endif
13295
13296
#ifdef CONFIG_RTL8188E
13297
case RTL8188E:
13298
if (interface_type == RTW_USB)
13299
addr_offset = EEPROM_MAC_ADDR_88EU;
13300
else if (interface_type == RTW_SDIO)
13301
addr_offset = EEPROM_MAC_ADDR_88ES;
13302
else if (interface_type == RTW_PCIE)
13303
addr_offset = EEPROM_MAC_ADDR_88EE;
13304
break;
13305
#endif
13306
#ifdef CONFIG_RTL8188F
13307
case RTL8188F:
13308
if (interface_type == RTW_USB)
13309
addr_offset = EEPROM_MAC_ADDR_8188FU;
13310
else if (interface_type == RTW_SDIO)
13311
addr_offset = EEPROM_MAC_ADDR_8188FS;
13312
break;
13313
#endif
13314
#ifdef CONFIG_RTL8188GTV
13315
case RTL8188GTV:
13316
if (interface_type == RTW_USB)
13317
addr_offset = EEPROM_MAC_ADDR_8188GTVU;
13318
else if (interface_type == RTW_SDIO)
13319
addr_offset = EEPROM_MAC_ADDR_8188GTVS;
13320
break;
13321
#endif
13322
#ifdef CONFIG_RTL8812A
13323
case RTL8812:
13324
if (interface_type == RTW_USB)
13325
addr_offset = EEPROM_MAC_ADDR_8812AU;
13326
else if (interface_type == RTW_PCIE)
13327
addr_offset = EEPROM_MAC_ADDR_8812AE;
13328
break;
13329
#endif
13330
#ifdef CONFIG_RTL8821A
13331
case RTL8821:
13332
if (interface_type == RTW_USB)
13333
addr_offset = EEPROM_MAC_ADDR_8821AU;
13334
else if (interface_type == RTW_SDIO)
13335
addr_offset = EEPROM_MAC_ADDR_8821AS;
13336
else if (interface_type == RTW_PCIE)
13337
addr_offset = EEPROM_MAC_ADDR_8821AE;
13338
break;
13339
#endif
13340
#ifdef CONFIG_RTL8192E
13341
case RTL8192E:
13342
if (interface_type == RTW_USB)
13343
addr_offset = EEPROM_MAC_ADDR_8192EU;
13344
else if (interface_type == RTW_SDIO)
13345
addr_offset = EEPROM_MAC_ADDR_8192ES;
13346
else if (interface_type == RTW_PCIE)
13347
addr_offset = EEPROM_MAC_ADDR_8192EE;
13348
break;
13349
#endif
13350
#ifdef CONFIG_RTL8814A
13351
case RTL8814A:
13352
if (interface_type == RTW_USB)
13353
addr_offset = EEPROM_MAC_ADDR_8814AU;
13354
else if (interface_type == RTW_PCIE)
13355
addr_offset = EEPROM_MAC_ADDR_8814AE;
13356
break;
13357
#endif
13358
13359
#ifdef CONFIG_RTL8822B
13360
case RTL8822B:
13361
if (interface_type == RTW_USB)
13362
addr_offset = EEPROM_MAC_ADDR_8822BU;
13363
else if (interface_type == RTW_SDIO)
13364
addr_offset = EEPROM_MAC_ADDR_8822BS;
13365
else if (interface_type == RTW_PCIE)
13366
addr_offset = EEPROM_MAC_ADDR_8822BE;
13367
break;
13368
#endif /* CONFIG_RTL8822B */
13369
13370
#ifdef CONFIG_RTL8821C
13371
case RTL8821C:
13372
if (interface_type == RTW_USB)
13373
addr_offset = EEPROM_MAC_ADDR_8821CU;
13374
else if (interface_type == RTW_SDIO)
13375
addr_offset = EEPROM_MAC_ADDR_8821CS;
13376
else if (interface_type == RTW_PCIE)
13377
addr_offset = EEPROM_MAC_ADDR_8821CE;
13378
break;
13379
#endif /* CONFIG_RTL8821C */
13380
13381
#ifdef CONFIG_RTL8710B
13382
case RTL8710B:
13383
if (interface_type == RTW_USB)
13384
addr_offset = EEPROM_MAC_ADDR_8710B;
13385
break;
13386
#endif
13387
13388
#ifdef CONFIG_RTL8192F
13389
case RTL8192F:
13390
if (interface_type == RTW_USB)
13391
addr_offset = EEPROM_MAC_ADDR_8192FU;
13392
else if (interface_type == RTW_SDIO)
13393
addr_offset = EEPROM_MAC_ADDR_8192FS;
13394
else if (interface_type == RTW_PCIE)
13395
addr_offset = EEPROM_MAC_ADDR_8192FE;
13396
break;
13397
#endif /* CONFIG_RTL8192F */
13398
13399
#ifdef CONFIG_RTL8822C
13400
case RTL8822C:
13401
if (interface_type == RTW_USB)
13402
addr_offset = EEPROM_MAC_ADDR_8822CU;
13403
else if (interface_type == RTW_SDIO)
13404
addr_offset = EEPROM_MAC_ADDR_8822CS;
13405
else if (interface_type == RTW_PCIE)
13406
addr_offset = EEPROM_MAC_ADDR_8822CE;
13407
break;
13408
#endif /* CONFIG_RTL8822C */
13409
13410
#ifdef CONFIG_RTL8814B
13411
case RTL8814B:
13412
if (interface_type == RTW_USB)
13413
addr_offset = EEPROM_MAC_ADDR_8814BU;
13414
else if (interface_type == RTW_PCIE)
13415
addr_offset = EEPROM_MAC_ADDR_8814BE;
13416
break;
13417
#endif /* CONFIG_RTL8814B */
13418
}
13419
13420
if (addr_offset == -1) {
13421
RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
13422
, __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
13423
}
13424
13425
return addr_offset;
13426
}
13427
13428
int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
13429
{
13430
int ret = _FAIL;
13431
int addr_offset;
13432
13433
addr_offset = hal_efuse_macaddr_offset(padapter);
13434
if (addr_offset == -1)
13435
goto exit;
13436
13437
ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
13438
13439
exit:
13440
return ret;
13441
}
13442
13443
void rtw_dump_cur_efuse(PADAPTER padapter)
13444
{
13445
int mapsize =0;
13446
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13447
13448
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
13449
13450
if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
13451
RTW_ERR("wrong map size %d\n", mapsize);
13452
return;
13453
}
13454
13455
#ifdef CONFIG_RTW_DEBUG
13456
if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13457
RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
13458
else
13459
RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
13460
#endif
13461
}
13462
13463
13464
#ifdef CONFIG_EFUSE_CONFIG_FILE
13465
u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
13466
{
13467
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13468
u32 ret = _FALSE;
13469
u32 maplen = 0;
13470
13471
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
13472
13473
if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
13474
RTW_ERR("eFuse length error :%d\n", maplen);
13475
return _FALSE;
13476
}
13477
13478
ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
13479
13480
hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
13481
13482
if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13483
rtw_dump_cur_efuse(padapter);
13484
13485
return ret;
13486
}
13487
13488
u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
13489
{
13490
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13491
u32 ret = _FAIL;
13492
13493
if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
13494
&& rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
13495
) {
13496
hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
13497
ret = _SUCCESS;
13498
} else
13499
hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
13500
13501
return ret;
13502
}
13503
#endif /* CONFIG_EFUSE_CONFIG_FILE */
13504
13505
int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
13506
{
13507
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13508
u8 addr[ETH_ALEN];
13509
int addr_offset = hal_efuse_macaddr_offset(adapter);
13510
u8 *hw_addr = NULL;
13511
int ret = _SUCCESS;
13512
#if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13513
u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
13514
#endif
13515
13516
if (autoload_fail)
13517
goto bypass_hw_pg;
13518
13519
if (addr_offset != -1)
13520
hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
13521
13522
#ifdef CONFIG_EFUSE_CONFIG_FILE
13523
/* if the hw_addr is written by efuse file, set to NULL */
13524
if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13525
hw_addr = NULL;
13526
#endif
13527
13528
if (!hw_addr) {
13529
/* try getting hw pg data */
13530
if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
13531
hw_addr = addr;
13532
}
13533
13534
#if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13535
if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
13536
hw_addr[0] = 0xff;
13537
#endif
13538
13539
/* check hw pg data */
13540
if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
13541
_rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
13542
goto exit;
13543
}
13544
13545
bypass_hw_pg:
13546
13547
#ifdef CONFIG_EFUSE_CONFIG_FILE
13548
/* check wifi mac file */
13549
if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
13550
_rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
13551
goto exit;
13552
}
13553
#endif
13554
13555
_rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
13556
ret = _FAIL;
13557
13558
exit:
13559
return ret;
13560
}
13561
13562
#ifdef CONFIG_RF_POWER_TRIM
13563
u32 Array_kfreemap[] = {
13564
0x08, 0xe,
13565
0x06, 0xc,
13566
0x04, 0xa,
13567
0x02, 0x8,
13568
0x00, 0x6,
13569
0x03, 0x4,
13570
0x05, 0x2,
13571
0x07, 0x0,
13572
0x09, 0x0,
13573
0x0c, 0x0,
13574
};
13575
13576
void rtw_bb_rf_gain_offset(_adapter *padapter)
13577
{
13578
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
13579
struct registry_priv *registry_par = &padapter->registrypriv;
13580
struct kfree_data_t *kfree_data = &pHalData->kfree_data;
13581
u8 value = pHalData->EEPROMRFGainOffset;
13582
u8 tmp = 0x3e;
13583
u32 res, i = 0;
13584
u32 ArrayLen = sizeof(Array_kfreemap) / sizeof(u32);
13585
u32 *Array = Array_kfreemap;
13586
u32 v1 = 0, v2 = 0, GainValue = 0, target = 0;
13587
13588
if (registry_par->RegPwrTrimEnable == 2) {
13589
RTW_INFO("Registry kfree default force disable.\n");
13590
return;
13591
}
13592
13593
#if defined(CONFIG_RTL8723B)
13594
if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
13595
RTW_INFO("Offset RF Gain.\n");
13596
RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
13597
13598
if (pHalData->EEPROMRFGainVal != 0xff) {
13599
13600
if (pHalData->ant_path == RF_PATH_A)
13601
GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
13602
13603
else
13604
GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
13605
RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
13606
13607
for (i = 0; i < ArrayLen; i += 2) {
13608
/* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
13609
v1 = Array[i];
13610
v2 = Array[i + 1];
13611
if (v1 == GainValue) {
13612
RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
13613
target = v2;
13614
break;
13615
}
13616
}
13617
RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
13618
13619
res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13620
RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
13621
phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
13622
res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13623
13624
RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
13625
13626
} else
13627
13628
RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
13629
} else
13630
RTW_INFO("Using the default RF gain.\n");
13631
13632
#elif defined(CONFIG_RTL8188E)
13633
if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
13634
RTW_INFO("8188ES Offset RF Gain.\n");
13635
RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
13636
pHalData->EEPROMRFGainVal);
13637
13638
if (pHalData->EEPROMRFGainVal != 0xff) {
13639
res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
13640
REG_RF_BB_GAIN_OFFSET, 0xffffffff);
13641
13642
RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
13643
res &= 0xfff87fff;
13644
13645
res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
13646
RTW_INFO("Offset RF Gain. res=0x%x\n", res);
13647
13648
rtw_hal_write_rfreg(padapter, RF_PATH_A,
13649
REG_RF_BB_GAIN_OFFSET,
13650
RF_GAIN_OFFSET_MASK, res);
13651
} else {
13652
RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
13653
pHalData->EEPROMRFGainVal);
13654
}
13655
} else
13656
RTW_INFO("Using the default RF gain.\n");
13657
#else
13658
/* TODO: call this when channel switch */
13659
if (kfree_data->flag & KFREE_FLAG_ON)
13660
rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
13661
#endif
13662
13663
}
13664
#endif /*CONFIG_RF_POWER_TRIM */
13665
13666
bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
13667
{
13668
#ifdef CONFIG_RF_POWER_TRIM
13669
int i, j;
13670
13671
for (i = 0; i < BB_GAIN_NUM; i++)
13672
for (j = 0; j < RF_PATH_MAX; j++)
13673
if (data->bb_gain[i][j] != 0)
13674
return 0;
13675
#endif
13676
return 1;
13677
}
13678
13679
#ifdef CONFIG_USB_RX_AGGREGATION
13680
void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
13681
{
13682
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
13683
if (cur_wireless_mode < WIRELESS_11_24N
13684
&& cur_wireless_mode > 0) { /* ABG mode */
13685
#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
13686
u32 remainder = 0;
13687
u8 quotient = 0;
13688
13689
remainder = MAX_RECVBUF_SZ % (4 * 1024);
13690
quotient = (u8)(MAX_RECVBUF_SZ >> 12);
13691
13692
if (quotient > 5) {
13693
pHalData->rxagg_usb_size = 0x6;
13694
pHalData->rxagg_usb_timeout = 0x10;
13695
} else {
13696
if (remainder >= 2048) {
13697
pHalData->rxagg_usb_size = quotient;
13698
pHalData->rxagg_usb_timeout = 0x10;
13699
} else {
13700
pHalData->rxagg_usb_size = (quotient - 1);
13701
pHalData->rxagg_usb_timeout = 0x10;
13702
}
13703
}
13704
#else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
13705
if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
13706
pHalData->rxagg_usb_size = 0x6;
13707
pHalData->rxagg_usb_timeout = 0x10;
13708
rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
13709
pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
13710
}
13711
#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
13712
13713
} else if (cur_wireless_mode >= WIRELESS_11_24N
13714
&& cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
13715
#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
13716
u32 remainder = 0;
13717
u8 quotient = 0;
13718
13719
remainder = MAX_RECVBUF_SZ % (4 * 1024);
13720
quotient = (u8)(MAX_RECVBUF_SZ >> 12);
13721
13722
if (quotient > 5) {
13723
pHalData->rxagg_usb_size = 0x5;
13724
pHalData->rxagg_usb_timeout = 0x20;
13725
} else {
13726
if (remainder >= 2048) {
13727
pHalData->rxagg_usb_size = quotient;
13728
pHalData->rxagg_usb_timeout = 0x10;
13729
} else {
13730
pHalData->rxagg_usb_size = (quotient - 1);
13731
pHalData->rxagg_usb_timeout = 0x10;
13732
}
13733
}
13734
#else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
13735
if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
13736
pHalData->rxagg_usb_size = 0x5;
13737
pHalData->rxagg_usb_timeout = 0x20;
13738
rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
13739
pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
13740
}
13741
#endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
13742
13743
} else {
13744
/* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
13745
}
13746
}
13747
13748
void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
13749
{
13750
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
13751
13752
if (cur_wireless_mode < WIRELESS_11_24N
13753
&& cur_wireless_mode > 0) { /* ABG mode */
13754
if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
13755
|| 0x10 != pHalData->rxagg_usb_timeout) {
13756
pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
13757
pHalData->rxagg_usb_timeout = 0x10;
13758
rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
13759
pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
13760
}
13761
} else if (cur_wireless_mode >= WIRELESS_11_24N
13762
&& cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
13763
if (UsbDmaSize != pHalData->rxagg_usb_size
13764
|| 0x20 != pHalData->rxagg_usb_timeout) {
13765
pHalData->rxagg_usb_size = UsbDmaSize;
13766
pHalData->rxagg_usb_timeout = 0x20;
13767
rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
13768
pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
13769
}
13770
} else {
13771
/* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
13772
}
13773
}
13774
13775
void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
13776
{
13777
#ifdef CONFIG_PLATFORM_NOVATEK_NT72668
13778
rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
13779
return;
13780
#endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
13781
13782
rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
13783
}
13784
#endif /* CONFIG_USB_RX_AGGREGATION */
13785
13786
/* To avoid RX affect TX throughput */
13787
void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
13788
{
13789
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
13790
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
13791
struct registry_priv *registry_par = &padapter->registrypriv;
13792
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
13793
u8 cur_wireless_mode = WIRELESS_INVALID;
13794
13795
#ifdef CONFIG_USB_RX_AGGREGATION
13796
if (!registry_par->dynamic_agg_enable)
13797
return;
13798
13799
#ifdef RTW_HALMAC
13800
if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter) || IS_HARDWARE_TYPE_8822CU(padapter))
13801
rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
13802
#else /* !RTW_HALMAC */
13803
if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
13804
/* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
13805
if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {
13806
if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
13807
rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
13808
else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
13809
rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
13810
else
13811
rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
13812
13813
/* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
13814
}
13815
} else if (IS_HARDWARE_TYPE_8812(padapter)) {
13816
#ifdef CONFIG_CONCURRENT_MODE
13817
u8 i;
13818
_adapter *iface;
13819
u8 bassocaed = _FALSE;
13820
struct mlme_ext_priv *mlmeext;
13821
13822
for (i = 0; i < pdvobjpriv->iface_nums; i++) {
13823
iface = pdvobjpriv->padapters[i];
13824
mlmeext = &iface->mlmeextpriv;
13825
if (rtw_linked_check(iface) == _TRUE) {
13826
if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
13827
cur_wireless_mode = mlmeext->cur_wireless_mode;
13828
bassocaed = _TRUE;
13829
}
13830
}
13831
if (bassocaed)
13832
#endif
13833
rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
13834
#ifdef CONFIG_PLATFORM_NOVATEK_NT72668
13835
} else {
13836
rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
13837
#endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
13838
}
13839
#endif /* RTW_HALMAC */
13840
#endif /* CONFIG_USB_RX_AGGREGATION */
13841
13842
}
13843
13844
/* bus-agg check for SoftAP mode */
13845
inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
13846
{
13847
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
13848
u8 chk_rst = _SUCCESS;
13849
13850
if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
13851
return chk_rst;
13852
13853
/* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
13854
/* return chk_rst; */
13855
13856
if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
13857
&& (pre_qsel != next_qsel)) {
13858
/* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
13859
/* pre_qsel,next_qsel); */
13860
chk_rst = _FAIL;
13861
}
13862
return chk_rst;
13863
}
13864
13865
/*
13866
* Description:
13867
* dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
13868
* contant.
13869
*
13870
* Input:
13871
* adapter: adapter pointer.
13872
* page_num: The max. page number that user want to dump.
13873
* page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
13874
*/
13875
void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
13876
{
13877
13878
int i;
13879
u8 val = 0;
13880
u8 base = 0;
13881
u32 addr = 0;
13882
u32 count = (page_size / 8);
13883
13884
if (page_num <= 0) {
13885
RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
13886
return;
13887
}
13888
13889
if (page_size < 128 || page_size > 512) {
13890
RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
13891
return;
13892
}
13893
13894
RTW_INFO("+%s+\n", __func__);
13895
val = rtw_read8(padapter, 0x106);
13896
rtw_write8(padapter, 0x106, 0x69);
13897
RTW_INFO("0x106: 0x%02x\n", val);
13898
base = rtw_read8(padapter, 0x209);
13899
RTW_INFO("0x209: 0x%02x\n", base);
13900
13901
addr = ((base)*page_size) / 8;
13902
for (i = 0 ; i < page_num * count ; i += 2) {
13903
rtw_write32(padapter, 0x140, addr + i);
13904
printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
13905
rtw_write32(padapter, 0x140, addr + i + 1);
13906
printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
13907
}
13908
}
13909
13910
#ifdef CONFIG_GPIO_API
13911
u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
13912
{
13913
u8 value = 0;
13914
u8 direction = 0;
13915
u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
13916
u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
13917
u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
13918
u8 gpio_num_to_set = gpio_num;
13919
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
13920
13921
if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
13922
return value;
13923
13924
rtw_ps_deny(adapter, PS_DENY_IOCTL);
13925
13926
RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
13927
LeaveAllPowerSaveModeDirect(adapter);
13928
13929
if (gpio_num > 7) {
13930
gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
13931
gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
13932
gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
13933
gpio_num_to_set = gpio_num - 8;
13934
}
13935
13936
/* Read GPIO Direction */
13937
direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
13938
13939
/* According the direction to read register value */
13940
if (direction)
13941
value = (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
13942
else
13943
value = (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
13944
13945
rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
13946
RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
13947
13948
return value;
13949
}
13950
13951
int rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
13952
{
13953
u8 direction = 0;
13954
u8 res = -1;
13955
u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
13956
u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
13957
u8 gpio_num_to_set = gpio_num;
13958
13959
if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
13960
return -1;
13961
13962
rtw_ps_deny(adapter, PS_DENY_IOCTL);
13963
13964
LeaveAllPowerSaveModeDirect(adapter);
13965
13966
if (gpio_num > 7) {
13967
gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
13968
gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
13969
gpio_num_to_set = gpio_num - 8;
13970
}
13971
13972
/* Read GPIO direction */
13973
direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
13974
13975
/* If GPIO is output direction, setting value. */
13976
if (direction) {
13977
if (isHigh)
13978
rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
13979
else
13980
rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
13981
13982
RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
13983
res = 0;
13984
} else {
13985
RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
13986
res = -1;
13987
}
13988
13989
rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
13990
return res;
13991
}
13992
13993
int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
13994
{
13995
u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
13996
u8 gpio_num_to_set = gpio_num;
13997
13998
if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
13999
return -1;
14000
14001
RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
14002
14003
rtw_ps_deny(adapter, PS_DENY_IOCTL);
14004
14005
LeaveAllPowerSaveModeDirect(adapter);
14006
14007
rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
14008
14009
if (gpio_num > 7) {
14010
gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
14011
gpio_num_to_set = gpio_num - 8;
14012
}
14013
14014
if (isOutput)
14015
rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
14016
else
14017
rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
14018
14019
rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14020
14021
return 0;
14022
}
14023
int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
14024
{
14025
u8 value;
14026
u8 direction;
14027
PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14028
14029
if (IS_HARDWARE_TYPE_8188E(adapter)) {
14030
if (gpio_num > 7 || gpio_num < 4) {
14031
RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14032
return -1;
14033
}
14034
}
14035
14036
rtw_ps_deny(adapter, PS_DENY_IOCTL);
14037
14038
LeaveAllPowerSaveModeDirect(adapter);
14039
14040
/* Read GPIO direction */
14041
direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
14042
if (direction) {
14043
RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
14044
return -1;
14045
}
14046
14047
/* Config GPIO Mode */
14048
rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
14049
14050
/* Register GPIO interrupt handler*/
14051
adapter->gpiointpriv.callback[gpio_num] = callback;
14052
14053
/* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
14054
value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
14055
adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
14056
rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
14057
14058
/* Enable GPIO interrupt */
14059
adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
14060
rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14061
14062
rtw_hal_update_hisr_hsisr_ind(adapter, 1);
14063
14064
rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14065
14066
return 0;
14067
}
14068
int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
14069
{
14070
u8 value;
14071
u8 direction;
14072
PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14073
14074
if (IS_HARDWARE_TYPE_8188E(adapter)) {
14075
if (gpio_num > 7 || gpio_num < 4) {
14076
RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14077
return -1;
14078
}
14079
}
14080
14081
rtw_ps_deny(adapter, PS_DENY_IOCTL);
14082
14083
LeaveAllPowerSaveModeDirect(adapter);
14084
14085
/* Config GPIO Mode */
14086
rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
14087
14088
/* Unregister GPIO interrupt handler*/
14089
adapter->gpiointpriv.callback[gpio_num] = NULL;
14090
14091
/* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
14092
adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
14093
rtw_write8(adapter, REG_GPIO_INTM, 0x00);
14094
14095
/* Disable GPIO interrupt */
14096
adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
14097
rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14098
14099
if (!adapter->gpiointpriv.interrupt_enable_mask)
14100
rtw_hal_update_hisr_hsisr_ind(adapter, 0);
14101
14102
rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14103
14104
return 0;
14105
}
14106
#endif
14107
14108
s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
14109
{
14110
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14111
u8 i;
14112
14113
for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14114
if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
14115
if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
14116
&& (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
14117
return i;
14118
}
14119
}
14120
14121
return -1;
14122
}
14123
14124
void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
14125
{
14126
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14127
s8 res;
14128
u8 i;
14129
14130
/* If it's an existed record, overwrite it */
14131
res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
14132
if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
14133
rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
14134
return;
14135
}
14136
14137
/* Search for the empty record to use */
14138
for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14139
if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
14140
rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
14141
return;
14142
}
14143
}
14144
14145
/* Else, overwrite the oldest record */
14146
for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
14147
_rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
14148
14149
rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
14150
}
14151
14152
void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
14153
{
14154
rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
14155
}
14156
14157
void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14158
{
14159
u32 mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
14160
u32 mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
14161
u32 mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
14162
u32 DropPacket = 0;
14163
14164
if (!rx_counter) {
14165
rtw_warn_on(1);
14166
return;
14167
}
14168
if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
14169
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14170
14171
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
14172
mac_cck_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14173
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14174
mac_ofdm_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14175
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
14176
mac_ht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14177
mac_vht_ok = 0;
14178
if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14179
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14180
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14181
mac_vht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14182
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14183
}
14184
14185
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
14186
mac_cck_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14187
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14188
mac_ofdm_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14189
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
14190
mac_ht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14191
mac_vht_err = 0;
14192
if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14193
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14194
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14195
mac_vht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14196
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14197
}
14198
14199
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
14200
mac_cck_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14201
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
14202
mac_ofdm_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14203
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
14204
mac_ht_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14205
14206
/* Mac_DropPacket */
14207
rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
14208
DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
14209
14210
rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
14211
rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
14212
rx_counter->rx_cck_fa = mac_cck_fa;
14213
rx_counter->rx_ofdm_fa = mac_ofdm_fa;
14214
rx_counter->rx_ht_fa = mac_ht_fa;
14215
rx_counter->rx_pkt_drop = DropPacket;
14216
}
14217
void rtw_reset_mac_rx_counters(_adapter *padapter)
14218
{
14219
14220
/* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
14221
if (IS_HARDWARE_TYPE_8703B(padapter) ||
14222
IS_HARDWARE_TYPE_8723D(padapter) ||
14223
IS_HARDWARE_TYPE_8188F(padapter) ||
14224
IS_HARDWARE_TYPE_8188GTV(padapter) ||
14225
IS_HARDWARE_TYPE_8192F(padapter) ||
14226
IS_HARDWARE_TYPE_8822C(padapter))
14227
phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
14228
14229
/* reset mac counter */
14230
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
14231
phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
14232
}
14233
14234
void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14235
{
14236
u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0, vht_ok = 0, vht_err = 0;
14237
if (!rx_counter) {
14238
rtw_warn_on(1);
14239
return;
14240
}
14241
if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14242
cckok = phy_query_bb_reg(padapter, 0xF04, 0x3FFF); /* [13:0] */
14243
ofdmok = phy_query_bb_reg(padapter, 0xF14, 0x3FFF); /* [13:0] */
14244
htok = phy_query_bb_reg(padapter, 0xF10, 0x3FFF); /* [13:0] */
14245
vht_ok = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF); /* [13:0] */
14246
cckcrc = phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16] */
14247
ofdmcrc = phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
14248
htcrc = phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
14249
vht_err = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
14250
CCK_FA = phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
14251
OFDM_FA = phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
14252
} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){
14253
cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);
14254
ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
14255
htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
14256
vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);
14257
cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);
14258
ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
14259
htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
14260
vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);
14261
CCK_FA = phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);
14262
OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
14263
14264
} else {
14265
cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
14266
ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
14267
htok = phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
14268
vht_ok = 0;
14269
cckcrc = phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
14270
ofdmcrc = phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
14271
htcrc = phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
14272
vht_err = 0;
14273
OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
14274
phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
14275
phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
14276
14277
CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
14278
}
14279
14280
rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
14281
rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
14282
rx_counter->rx_ofdm_fa = OFDM_FA;
14283
rx_counter->rx_cck_fa = CCK_FA;
14284
14285
}
14286
14287
void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
14288
{
14289
if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14290
phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
14291
phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
14292
} else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14293
phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);
14294
phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);
14295
} else {
14296
phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14297
phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14298
}
14299
}
14300
14301
void rtw_reset_phy_rx_counters(_adapter *padapter)
14302
{
14303
/* reset phy counter */
14304
if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14305
/* reset CCK FA counter */
14306
phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);
14307
phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);
14308
14309
/* reset CCK CCA counter */
14310
phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);
14311
phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);
14312
rtw_reset_phy_trx_ok_counters(padapter);
14313
14314
} else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14315
rtw_reset_phy_trx_ok_counters(padapter);
14316
14317
phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset OFDA FA counter */
14318
phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
14319
14320
phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
14321
phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14322
} else {
14323
phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14324
rtw_msleep_os(10);
14325
phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14326
14327
phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset OFDA FA counter */
14328
phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset OFDA FA counter */
14329
phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
14330
phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
14331
14332
phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
14333
phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14334
}
14335
}
14336
#ifdef DBG_RX_COUNTER_DUMP
14337
void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14338
{
14339
struct recv_priv *precvpriv = &padapter->recvpriv;
14340
if (!rx_counter) {
14341
rtw_warn_on(1);
14342
return;
14343
}
14344
rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
14345
rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
14346
rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
14347
}
14348
void rtw_reset_drv_rx_counters(_adapter *padapter)
14349
{
14350
struct recv_priv *precvpriv = &padapter->recvpriv;
14351
padapter->drv_rx_cnt_ok = 0;
14352
padapter->drv_rx_cnt_crcerror = 0;
14353
padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
14354
}
14355
void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
14356
{
14357
u8 initialgain;
14358
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14359
14360
if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
14361
rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
14362
RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
14363
rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14364
/*disable dynamic functions, such as high power, DIG*/
14365
rtw_phydm_ability_backup(padapter);
14366
rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
14367
} else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
14368
/* turn on phy-dynamic functions */
14369
rtw_phydm_ability_restore(padapter);
14370
initialgain = 0xff; /* restore RX GAIN */
14371
rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14372
14373
}
14374
}
14375
14376
void rtw_dump_rx_counters(_adapter *padapter)
14377
{
14378
struct dbg_rx_counter rx_counter;
14379
14380
if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
14381
_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14382
rtw_dump_drv_rx_counters(padapter, &rx_counter);
14383
RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
14384
rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
14385
rtw_reset_drv_rx_counters(padapter);
14386
}
14387
14388
if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
14389
_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14390
rtw_dump_mac_rx_counters(padapter, &rx_counter);
14391
RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
14392
rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
14393
rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
14394
rx_counter.rx_pkt_drop);
14395
rtw_reset_mac_rx_counters(padapter);
14396
}
14397
14398
if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
14399
_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14400
rtw_dump_phy_rx_counters(padapter, &rx_counter);
14401
/* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
14402
/* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
14403
RTW_INFO("Phy Received packet OK:%d CRC error:%d FA Counter: %d\n", rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
14404
rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
14405
rtw_reset_phy_rx_counters(padapter);
14406
}
14407
}
14408
#endif
14409
u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
14410
{
14411
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14412
u8 curr_tx_sgi = 0;
14413
struct ra_sta_info *ra_info;
14414
14415
if (!psta)
14416
return curr_tx_sgi;
14417
14418
if (padapter->fix_rate == 0xff) {
14419
#if defined(CONFIG_RTL8188E)
14420
#if (RATE_ADAPTIVE_SUPPORT == 1)
14421
curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
14422
#endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14423
#else
14424
ra_info = &psta->cmn.ra_info;
14425
curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
14426
#endif
14427
} else {
14428
curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
14429
}
14430
14431
return curr_tx_sgi;
14432
}
14433
14434
u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
14435
{
14436
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14437
u8 rate_id = 0;
14438
struct ra_sta_info *ra_info;
14439
14440
if (!psta)
14441
return rate_id;
14442
14443
if (padapter->fix_rate == 0xff) {
14444
#if defined(CONFIG_RTL8188E)
14445
#if (RATE_ADAPTIVE_SUPPORT == 1)
14446
rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
14447
#endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14448
#else
14449
ra_info = &psta->cmn.ra_info;
14450
rate_id = ra_info->curr_tx_rate & 0x7f;
14451
#endif
14452
} else {
14453
rate_id = padapter->fix_rate & 0x7f;
14454
}
14455
14456
return rate_id;
14457
}
14458
14459
void update_IOT_info(_adapter *padapter)
14460
{
14461
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14462
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14463
14464
switch (pmlmeinfo->assoc_AP_vendor) {
14465
case HT_IOT_PEER_MARVELL:
14466
pmlmeinfo->turboMode_cts2self = 1;
14467
pmlmeinfo->turboMode_rtsen = 0;
14468
break;
14469
14470
case HT_IOT_PEER_RALINK:
14471
pmlmeinfo->turboMode_cts2self = 0;
14472
pmlmeinfo->turboMode_rtsen = 1;
14473
break;
14474
case HT_IOT_PEER_REALTEK:
14475
/* rtw_write16(padapter, 0x4cc, 0xffff); */
14476
/* rtw_write16(padapter, 0x546, 0x01c0); */
14477
break;
14478
default:
14479
pmlmeinfo->turboMode_cts2self = 0;
14480
pmlmeinfo->turboMode_rtsen = 1;
14481
break;
14482
}
14483
14484
}
14485
#ifdef CONFIG_RTS_FULL_BW
14486
/*
14487
8188E: not support full RTS BW feature(mac REG no define 480[5])
14488
*/
14489
void rtw_set_rts_bw(_adapter *padapter) {
14490
int i;
14491
u8 enable = 1;
14492
bool connect_to_8812 = _FALSE;
14493
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14494
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14495
struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
14496
struct sta_info *station = NULL;
14497
14498
for (i = 0; i < macid_ctl->num; i++) {
14499
if (rtw_macid_is_used(macid_ctl, i)) {
14500
14501
station = NULL;
14502
station = macid_ctl->sta[i];
14503
if(station) {
14504
14505
_adapter *sta_adapter =station->padapter;
14506
struct mlme_ext_priv *pmlmeext = &(sta_adapter->mlmeextpriv);
14507
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14508
14509
if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {
14510
if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) {
14511
if ( macid_ctl->sta[i]->vendor_8812) {
14512
connect_to_8812 = _TRUE;
14513
enable = 0;
14514
}
14515
}
14516
}
14517
}
14518
}
14519
14520
if(connect_to_8812)
14521
break;
14522
}
14523
14524
RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);
14525
rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);
14526
}
14527
#endif/*CONFIG_RTS_FULL_BW*/
14528
14529
int hal_spec_init(_adapter *adapter)
14530
{
14531
u8 interface_type = 0;
14532
int ret = _SUCCESS;
14533
14534
interface_type = rtw_get_intf_type(adapter);
14535
14536
switch (rtw_get_chip_type(adapter)) {
14537
#ifdef CONFIG_RTL8723B
14538
case RTL8723B:
14539
init_hal_spec_8723b(adapter);
14540
break;
14541
#endif
14542
#ifdef CONFIG_RTL8703B
14543
case RTL8703B:
14544
init_hal_spec_8703b(adapter);
14545
break;
14546
#endif
14547
#ifdef CONFIG_RTL8723D
14548
case RTL8723D:
14549
init_hal_spec_8723d(adapter);
14550
break;
14551
#endif
14552
#ifdef CONFIG_RTL8188E
14553
case RTL8188E:
14554
init_hal_spec_8188e(adapter);
14555
break;
14556
#endif
14557
#ifdef CONFIG_RTL8188F
14558
case RTL8188F:
14559
init_hal_spec_8188f(adapter);
14560
break;
14561
#endif
14562
#ifdef CONFIG_RTL8188GTV
14563
case RTL8188GTV:
14564
init_hal_spec_8188gtv(adapter);
14565
break;
14566
#endif
14567
#ifdef CONFIG_RTL8812A
14568
case RTL8812:
14569
init_hal_spec_8812a(adapter);
14570
break;
14571
#endif
14572
#ifdef CONFIG_RTL8821A
14573
case RTL8821:
14574
init_hal_spec_8821a(adapter);
14575
break;
14576
#endif
14577
#ifdef CONFIG_RTL8192E
14578
case RTL8192E:
14579
init_hal_spec_8192e(adapter);
14580
break;
14581
#endif
14582
#ifdef CONFIG_RTL8814A
14583
case RTL8814A:
14584
init_hal_spec_8814a(adapter);
14585
break;
14586
#endif
14587
#ifdef CONFIG_RTL8822B
14588
case RTL8822B:
14589
rtl8822b_init_hal_spec(adapter);
14590
break;
14591
#endif
14592
#ifdef CONFIG_RTL8821C
14593
case RTL8821C:
14594
init_hal_spec_rtl8821c(adapter);
14595
break;
14596
#endif
14597
#ifdef CONFIG_RTL8710B
14598
case RTL8710B:
14599
init_hal_spec_8710b(adapter);
14600
break;
14601
#endif
14602
#ifdef CONFIG_RTL8192F
14603
case RTL8192F:
14604
init_hal_spec_8192f(adapter);
14605
break;
14606
#endif
14607
#ifdef CONFIG_RTL8822C
14608
case RTL8822C:
14609
rtl8822c_init_hal_spec(adapter);
14610
break;
14611
#endif
14612
#ifdef CONFIG_RTL8814B
14613
case RTL8814B:
14614
rtl8814b_init_hal_spec(adapter);
14615
break;
14616
#endif
14617
default:
14618
RTW_ERR("%s: unknown chip_type:%u\n"
14619
, __func__, rtw_get_chip_type(adapter));
14620
ret = _FAIL;
14621
break;
14622
}
14623
14624
return ret;
14625
}
14626
14627
static const char *const _band_cap_str[] = {
14628
/* BIT0 */"2G",
14629
/* BIT1 */"5G",
14630
};
14631
14632
static const char *const _bw_cap_str[] = {
14633
/* BIT0 */"5M",
14634
/* BIT1 */"10M",
14635
/* BIT2 */"20M",
14636
/* BIT3 */"40M",
14637
/* BIT4 */"80M",
14638
/* BIT5 */"160M",
14639
/* BIT6 */"80_80M",
14640
};
14641
14642
static const char *const _proto_cap_str[] = {
14643
/* BIT0 */"b",
14644
/* BIT1 */"g",
14645
/* BIT2 */"n",
14646
/* BIT3 */"ac",
14647
};
14648
14649
static const char *const _wl_func_str[] = {
14650
/* BIT0 */"P2P",
14651
/* BIT1 */"MIRACAST",
14652
/* BIT2 */"TDLS",
14653
/* BIT3 */"FTM",
14654
};
14655
14656
void dump_hal_spec(void *sel, _adapter *adapter)
14657
{
14658
struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
14659
int i;
14660
14661
RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
14662
RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
14663
RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
14664
14665
RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
14666
RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
14667
RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);
14668
RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
14669
14670
RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
14671
RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
14672
14673
RTW_PRINT_SEL(sel, "band_cap:");
14674
for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
14675
if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
14676
_RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
14677
}
14678
_RTW_PRINT_SEL(sel, "\n");
14679
14680
RTW_PRINT_SEL(sel, "bw_cap:");
14681
for (i = 0; i < BW_CAP_BIT_NUM; i++) {
14682
if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
14683
_RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
14684
}
14685
_RTW_PRINT_SEL(sel, "\n");
14686
14687
RTW_PRINT_SEL(sel, "proto_cap:");
14688
for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
14689
if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
14690
_RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
14691
}
14692
_RTW_PRINT_SEL(sel, "\n");
14693
14694
RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
14695
RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
14696
14697
RTW_PRINT_SEL(sel, "wl_func:");
14698
for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
14699
if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
14700
_RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
14701
}
14702
_RTW_PRINT_SEL(sel, "\n");
14703
14704
#if CONFIG_TX_AC_LIFETIME
14705
RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"
14706
, hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);
14707
#endif
14708
14709
RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
14710
14711
RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
14712
RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
14713
}
14714
14715
inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
14716
{
14717
return GET_HAL_SPEC(adapter)->band_cap & cap;
14718
}
14719
14720
inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
14721
{
14722
return GET_HAL_SPEC(adapter)->bw_cap & cap;
14723
}
14724
14725
inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
14726
{
14727
return GET_HAL_SPEC(adapter)->proto_cap & cap;
14728
}
14729
14730
inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
14731
{
14732
return GET_HAL_SPEC(adapter)->wl_func & func;
14733
}
14734
14735
inline bool hal_is_band_support(_adapter *adapter, u8 band)
14736
{
14737
return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
14738
}
14739
14740
inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
14741
{
14742
return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
14743
}
14744
14745
inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
14746
{
14747
u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
14748
14749
if (mode == WIRELESS_11B)
14750
if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
14751
return 1;
14752
14753
if (mode == WIRELESS_11G)
14754
if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
14755
return 1;
14756
14757
if (mode == WIRELESS_11A)
14758
if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
14759
return 1;
14760
14761
if (mode == WIRELESS_11_24N)
14762
if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
14763
return 1;
14764
14765
if (mode == WIRELESS_11_5N)
14766
if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
14767
return 1;
14768
14769
if (mode == WIRELESS_11AC)
14770
if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
14771
return 1;
14772
14773
return 0;
14774
}
14775
inline bool hal_is_mimo_support(_adapter *adapter)
14776
{
14777
if ((GET_HAL_TX_NSS(adapter) == 1) &&
14778
(GET_HAL_RX_NSS(adapter) == 1))
14779
return 0;
14780
return 1;
14781
}
14782
14783
/*
14784
* hal_largest_bw - starting from in_bw, get largest bw supported by HAL
14785
* @adapter:
14786
* @in_bw: starting bw, value of enum channel_width
14787
*
14788
* Returns: value of enum channel_width
14789
*/
14790
u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
14791
{
14792
for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
14793
if (hal_is_bw_support(adapter, in_bw))
14794
break;
14795
}
14796
14797
if (!hal_is_bw_support(adapter, in_bw))
14798
rtw_warn_on(1);
14799
14800
return in_bw;
14801
}
14802
14803
#ifndef CONFIG_HAS_TX_BEACON_PAUSE
14804
void ResumeTxBeacon(_adapter *padapter)
14805
{
14806
rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
14807
rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
14808
14809
#ifdef RTW_HALMAC
14810
/* Add this for driver using HALMAC because driver doesn't have setup time init by self */
14811
/* TBTT setup time */
14812
rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
14813
#endif
14814
14815
/* TBTT hold time: 0x540[19:8] */
14816
rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
14817
rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
14818
(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
14819
}
14820
14821
void StopTxBeacon(_adapter *padapter)
14822
{
14823
rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
14824
rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
14825
14826
/* TBTT hold time: 0x540[19:8] */
14827
rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
14828
rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
14829
(rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
14830
}
14831
#endif /* CONFIG_HAS_TX_BEACON_PAUSE */
14832
14833
#ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
14834
14835
#ifdef CONFIG_CLIENT_PORT_CFG
14836
const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
14837
CLT_PORT0,
14838
CLT_PORT1,
14839
CLT_PORT2,
14840
CLT_PORT3
14841
};
14842
14843
void rtw_clt_port_init(struct clt_port_t *cltp)
14844
{
14845
cltp->bmp = 0;
14846
cltp->num = 0;
14847
_rtw_spinlock_init(&cltp->lock);
14848
}
14849
void rtw_clt_port_deinit(struct clt_port_t *cltp)
14850
{
14851
_rtw_spinlock_free(&cltp->lock);
14852
}
14853
static void _hw_client_port_alloc(_adapter *adapter)
14854
{
14855
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
14856
struct clt_port_t *cltp = &dvobj->clt_port;
14857
_irqL irql;
14858
int i;
14859
14860
#if 0
14861
if (cltp->num > MAX_CLIENT_PORT_NUM) {
14862
RTW_ERR(ADPT_FMT" cann't alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
14863
rtw_warn_on(1);
14864
return;
14865
}
14866
#endif
14867
14868
if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
14869
RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
14870
ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
14871
return;
14872
}
14873
_enter_critical_bh(&cltp->lock, &irql);
14874
for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
14875
if (!(cltp->bmp & BIT(i)))
14876
break;
14877
}
14878
14879
if (i < MAX_CLIENT_PORT_NUM) {
14880
adapter->client_id = i;
14881
cltp->bmp |= BIT(i);
14882
adapter->client_port = _clt_port_id[i];
14883
}
14884
cltp->num++;
14885
_exit_critical_bh(&cltp->lock, &irql);
14886
RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
14887
__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
14888
}
14889
static void _hw_client_port_free(_adapter *adapter)
14890
{
14891
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
14892
struct clt_port_t *cltp = &dvobj->clt_port;
14893
_irqL irql;
14894
14895
#if 0
14896
if (adapter->client_id >= MAX_CLIENT_PORT_NUM) {
14897
RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
14898
/*rtw_warn_on(1);*/
14899
}
14900
#endif
14901
14902
RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
14903
__func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
14904
14905
_enter_critical_bh(&cltp->lock, &irql);
14906
if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
14907
cltp->bmp &= ~ BIT(adapter->client_id);
14908
adapter->client_id = MAX_CLIENT_PORT_NUM;
14909
adapter->client_port = CLT_PORT_INVALID;
14910
}
14911
cltp->num--;
14912
if (cltp->num < 0)
14913
cltp->num = 0;
14914
_exit_critical_bh(&cltp->lock, &irql);
14915
}
14916
void rtw_hw_client_port_allocate(_adapter *adapter)
14917
{
14918
struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
14919
14920
if (hal_spec->port_num != 5)
14921
return;
14922
14923
_hw_client_port_alloc(adapter);
14924
}
14925
void rtw_hw_client_port_release(_adapter *adapter)
14926
{
14927
struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
14928
14929
if (hal_spec->port_num != 5)
14930
return;
14931
14932
_hw_client_port_free(adapter);
14933
}
14934
#endif /*CONFIG_CLIENT_PORT_CFG*/
14935
14936
void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
14937
{
14938
RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
14939
14940
rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
14941
14942
/* set net_type */
14943
Set_MSR(Adapter, mode);
14944
14945
if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
14946
if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
14947
StopTxBeacon(Adapter);
14948
} else if (mode == _HW_STATE_ADHOC_)
14949
ResumeTxBeacon(Adapter);
14950
else if (mode == _HW_STATE_AP_)
14951
/* enable rx ps-poll */
14952
rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
14953
14954
/* enable rx data frame */
14955
rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
14956
14957
#ifdef CONFIG_CLIENT_PORT_CFG
14958
if (mode == _HW_STATE_STATION_)
14959
rtw_hw_client_port_allocate(Adapter);
14960
else
14961
rtw_hw_client_port_release(Adapter);
14962
#endif
14963
#if defined(CONFIG_RTL8192F)
14964
rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
14965
REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
14966
#endif
14967
}
14968
#endif
14969
14970
#ifdef CONFIG_ANTENNA_DIVERSITY
14971
u8 rtw_hal_antdiv_before_linked(_adapter *padapter)
14972
{
14973
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14974
u8 cur_ant, change_ant;
14975
14976
if (!pHalData->AntDivCfg)
14977
return _FALSE;
14978
14979
if (pHalData->sw_antdiv_bl_state == 0) {
14980
pHalData->sw_antdiv_bl_state = 1;
14981
14982
rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
14983
change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
14984
14985
return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
14986
}
14987
14988
pHalData->sw_antdiv_bl_state = 0;
14989
return _FALSE;
14990
}
14991
14992
void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
14993
{
14994
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14995
14996
if (pHalData->AntDivCfg) {
14997
/*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
14998
/*select optimum_antenna for before linked =>For antenna diversity*/
14999
if (dst->Rssi >= src->Rssi) {/*keep org parameter*/
15000
src->Rssi = dst->Rssi;
15001
src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
15002
}
15003
}
15004
}
15005
#endif
15006
15007
#ifdef CONFIG_PHY_CAPABILITY_QUERY
15008
void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
15009
{
15010
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
15011
struct phy_spec_t *phy_spec = &pHalData->phy_spec;
15012
15013
RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
15014
RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
15015
RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
15016
RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index [15:8]*/
15017
RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index [7:0]*/
15018
15019
RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
15020
RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT STBC Tx [31:24]*/
15021
/*VHT STBC Rx [23:16]
15022
0 = not support
15023
1 = support for 1 spatial stream
15024
2 = support for 1 or 2 spatial streams
15025
3 = support for 1 or 2 or 3 spatial streams
15026
4 = support for 1 or 2 or 3 or 4 spatial streams*/
15027
RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
15028
RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Tx : %s\n", ((phy_spec->stbc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT STBC Tx [15:8]*/
15029
/*HT STBC Rx [7:0]
15030
0 = not support
15031
1 = support for 1 spatial stream
15032
2 = support for 1 or 2 spatial streams
15033
3 = support for 1 or 2 or 3 spatial streams*/
15034
RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
15035
15036
RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
15037
RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 24) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Tx [31:24]*/
15038
RTW_PRINT_SEL(sel, "[PHY SPEC] VHT LDPC Rx : %s\n", ((phy_spec->ldpc_cap >> 16) & 0xFF) ? "Supported" : "N/A"); /*VHT LDPC Rx [23:16]*/
15039
RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Tx : %s\n", ((phy_spec->ldpc_cap >> 8) & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Tx [15:8]*/
15040
RTW_PRINT_SEL(sel, "[PHY SPEC] HT LDPC Rx : %s\n\n", (phy_spec->ldpc_cap & 0xFF) ? "Supported" : "N/A"); /*HT LDPC Rx [7:0]*/
15041
#ifdef CONFIG_BEAMFORMING
15042
RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
15043
RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfer : %s\n", ((phy_spec->txbf_cap >> 28) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfer [31:28]*/
15044
RTW_PRINT_SEL(sel, "[PHY SPEC] VHT MU Bfee : %s\n", ((phy_spec->txbf_cap >> 24) & 0xF) ? "Supported" : "N/A"); /*VHT MU Bfee [27:24]*/
15045
RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfer : %s\n", ((phy_spec->txbf_cap >> 20) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfer [23:20]*/
15046
RTW_PRINT_SEL(sel, "[PHY SPEC] VHT SU Bfee : %s\n", ((phy_spec->txbf_cap >> 16) & 0xF) ? "Supported" : "N/A"); /*VHT SU Bfee [19:16]*/
15047
RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF) ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
15048
RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
15049
15050
RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
15051
RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
15052
RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
15053
RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
15054
RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
15055
#endif
15056
}
15057
#else
15058
void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
15059
{
15060
u8 phy_cap = _FALSE;
15061
15062
/* STBC */
15063
rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
15064
RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15065
15066
phy_cap = _FALSE;
15067
rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
15068
RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15069
15070
/* LDPC support */
15071
phy_cap = _FALSE;
15072
rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
15073
RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15074
15075
phy_cap = _FALSE;
15076
rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
15077
RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15078
15079
#ifdef CONFIG_BEAMFORMING
15080
phy_cap = _FALSE;
15081
rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
15082
RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15083
15084
phy_cap = _FALSE;
15085
rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
15086
RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15087
15088
phy_cap = _FALSE;
15089
rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
15090
RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15091
15092
phy_cap = _FALSE;
15093
rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
15094
RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15095
#endif
15096
}
15097
#endif
15098
void rtw_dump_phy_cap(void *sel, _adapter *adapter)
15099
{
15100
RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
15101
#ifdef CONFIG_PHY_CAPABILITY_QUERY
15102
rtw_dump_phy_cap_by_phydmapi(sel, adapter);
15103
#else
15104
rtw_dump_phy_cap_by_hal(sel, adapter);
15105
#endif
15106
}
15107
15108
inline s16 translate_dbm_to_percentage(s16 signal)
15109
{
15110
if ((signal <= -100) || (signal >= 20))
15111
return 0;
15112
else if (signal >= 0)
15113
return 100;
15114
else
15115
return 100 + signal;
15116
}
15117
15118
#ifdef CONFIG_SWTIMER_BASED_TXBCN
15119
#ifdef CONFIG_BCN_RECOVERY
15120
#define REG_CPU_MGQ_INFO 0x041C
15121
#define BIT_BCN_POLL BIT(28)
15122
u8 rtw_ap_bcn_recovery(_adapter *padapter)
15123
{
15124
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15125
15126
if (hal_data->issue_bcn_fail >= 2) {
15127
RTW_ERR("%s ISSUE BCN Fail\n", __func__);
15128
rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
15129
hal_data->issue_bcn_fail = 0;
15130
}
15131
return _SUCCESS;
15132
}
15133
#endif /*CONFIG_BCN_RECOVERY*/
15134
15135
#ifdef CONFIG_BCN_XMIT_PROTECT
15136
u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
15137
{
15138
u32 start_time = rtw_get_current_time();
15139
u8 bcn_queue_empty = _FALSE;
15140
15141
do {
15142
if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
15143
bcn_queue_empty = _TRUE;
15144
break;
15145
}
15146
} while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
15147
15148
if (bcn_queue_empty == _FALSE)
15149
RTW_ERR("%s BCN queue not empty\n", __func__);
15150
15151
return bcn_queue_empty;
15152
}
15153
#endif /*CONFIG_BCN_XMIT_PROTECT*/
15154
#endif /*CONFIG_SWTIMER_BASED_TXBCN*/
15155
15156
/**
15157
* rtw_hal_get_trx_path() - Get RF path related information
15158
* @d: struct dvobj_priv*
15159
* @type: RF type, nTnR
15160
* @tx: Tx path
15161
* @rx: Rx path
15162
*
15163
* Get RF type, TX path and RX path information.
15164
*/
15165
void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,
15166
enum bb_path *tx, enum bb_path *rx)
15167
{
15168
struct _ADAPTER *a = dvobj_get_primary_adapter(d);
15169
enum rf_type t = GET_HAL_RFPATH(a);
15170
15171
if (type)
15172
*type = t;
15173
15174
if (tx || rx) {
15175
u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);
15176
u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);
15177
15178
if (!tx_bmp && !rx_bmp)
15179
rf_type_to_default_trx_bmp(t, tx, rx);
15180
else {
15181
if (tx)
15182
*tx = GET_HAL_TX_PATH_BMP(a);
15183
if (rx)
15184
*rx = GET_HAL_RX_PATH_BMP(a);
15185
}
15186
}
15187
}
15188
15189
#ifdef RTW_CHANNEL_SWITCH_OFFLOAD
15190
void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
15191
{
15192
u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
15193
PHAL_DATA_TYPE hal;
15194
struct submit_ctx *chsw_sctx;
15195
15196
hal = GET_HAL_DATA(adapter);
15197
chsw_sctx = &hal->chsw_sctx;
15198
15199
SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
15200
SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
15201
SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
15202
15203
rtw_sctx_init(chsw_sctx, 10);
15204
rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
15205
rtw_sctx_wait(chsw_sctx, __func__);
15206
}
15207
#endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
15208
15209
#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8812A) ||\
15210
defined(CONFIG_RTL8192F) || defined(CONFIG_RTL8192E) ||\
15211
defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821A) ||\
15212
defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
15213
u8 phy_get_current_tx_num(
15214
PADAPTER pAdapter,
15215
u8 Rate
15216
)
15217
{
15218
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(pAdapter);
15219
u8 tx_num = 0;
15220
15221
if (IS_1T_RATE(Rate))
15222
tx_num = hal_data->txpath_num_nss[0];
15223
else if (IS_2T_RATE(Rate))
15224
tx_num = hal_data->txpath_num_nss[1];
15225
else if (IS_3T_RATE(Rate))
15226
tx_num = hal_data->txpath_num_nss[2];
15227
else if (IS_4T_RATE(Rate))
15228
tx_num = hal_data->txpath_num_nss[3];
15229
else
15230
rtw_warn_on(1);
15231
15232
return tx_num == 0 ? RF_1TX : tx_num - 1;
15233
}
15234
#endif
15235
#ifdef CONFIG_RTL8812A
15236
u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {
15237
int vender_len = 7;
15238
unsigned char vendor_info[vender_len];
15239
unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
15240
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15241
15242
if( !IS_HARDWARE_TYPE_8812(padapter) )
15243
return pframe;
15244
15245
_rtw_memset(vendor_info,0,vender_len);
15246
_rtw_memcpy(vendor_info, REALTEK_OUI, 3);
15247
vendor_info[4] =2;
15248
if(pHalData->version_id.CUTVersion > B_CUT_VERSION )
15249
vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;
15250
else
15251
vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;
15252
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);
15253
15254
return pframe;
15255
}
15256
#endif /*CONFIG_RTL8812A*/
15257
15258
static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)
15259
{
15260
int refcnt;
15261
15262
_enter_critical_mutex(&protsel->mutex, NULL);
15263
15264
refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);
15265
15266
WARN_ON(refcnt > 1 && protsel->sel != sel);
15267
15268
protsel->sel = sel;
15269
15270
_exit_critical_mutex(&protsel->mutex, NULL);
15271
}
15272
15273
static inline void rtw_leave_protsel(struct protsel *protsel)
15274
{
15275
int refcnt;
15276
15277
_enter_critical_mutex(&protsel->mutex, NULL);
15278
15279
refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);
15280
15281
_exit_critical_mutex(&protsel->mutex, NULL);
15282
15283
WARN_ON(refcnt < 0);
15284
}
15285
15286
static inline bool rtw_assert_protsel(struct protsel *protsel)
15287
{
15288
int refcnt = ATOMIC_READ(&protsel->refcnt);
15289
15290
if (refcnt > 0)
15291
return true;
15292
15293
return false;
15294
}
15295
15296
#ifdef CONFIG_PROTSEL_PORT
15297
void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)
15298
{
15299
u8 val8;
15300
15301
rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);
15302
15303
val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);
15304
val8 &= ~BIT_MASK_PORT_CTRL_SEL;
15305
val8 |= BIT_PORT_CTRL_SEL(port_sel);
15306
rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);
15307
}
15308
15309
bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)
15310
{
15311
if (!padapter->bup) /* don't assert before IF up */
15312
return true;
15313
15314
return rtw_assert_protsel(&padapter->dvobj->protsel_port);
15315
}
15316
15317
void rtw_leave_protsel_port(_adapter *padapter)
15318
{
15319
rtw_leave_protsel(&padapter->dvobj->protsel_port);
15320
}
15321
#endif
15322
15323
#ifdef CONFIG_PROTSEL_ATIMDTIM
15324
void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)
15325
{
15326
/* 0~15 is for port 0 MBSSID setting
15327
* 16 is for port 1 setting
15328
* 17 is for port 2 setting
15329
* 18 is for port 3 setting
15330
* 19 is for port 4 setting
15331
*/
15332
u8 val8;
15333
15334
if (port_sel >= 1 && port_sel <= 4)
15335
port_sel += 15;
15336
15337
rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);
15338
15339
val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);
15340
val8 &= ~BIT_MASK_ATIM_DTIM_SEL;
15341
val8 |= BIT_ATIM_DTIM_SEL(port_sel);
15342
rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);
15343
}
15344
15345
bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)
15346
{
15347
return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);
15348
}
15349
15350
void rtw_leave_protsel_atimdtim(_adapter *padapter)
15351
{
15352
rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);
15353
}
15354
#endif
15355
15356
#ifdef CONFIG_PROTSEL_MACSLEEP
15357
void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)
15358
{
15359
u32 val32;
15360
15361
rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);
15362
15363
val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);
15364
val32 &= ~BIT_MASK_MACID_SLEEP_SEL;
15365
val32 |= BIT_MACID_SLEEP_SEL(sel);
15366
rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);
15367
}
15368
15369
bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)
15370
{
15371
return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);
15372
}
15373
15374
void rtw_leave_protsel_macsleep(_adapter *padapter)
15375
{
15376
rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);
15377
}
15378
#endif
15379
15380