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
rtw_dump_fw_info(void * sel,_adapter * adapter)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
rsvd_page_cache_update_all(struct rsvd_page_cache_t * cache,u8 loc,u8 txdesc_len,u32 page_size,u8 * info,u32 info_len)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;
44 bool modified = 0;
45 bool loc_mod = 0, size_mod = 0, page_num_mod = 0;
46
47 page_num = info_len ? (u8)PageNum(txdesc_len + info_len, page_size) : 0;
48 if (!info_len)
49 loc = 0;
50
51 if (cache->loc != loc) {
52 RTW_INFO("%s %s loc change (%u -> %u)\n"
53 , __func__, cache->name, cache->loc, loc);
54 loc_mod = 1;
55 }
56 if (cache->size != info_len) {
57 RTW_INFO("%s %s size change (%u -> %u)\n"
58 , __func__, cache->name, cache->size, info_len);
59 size_mod = 1;
60 }
61 if (cache->page_num != page_num) {
62 RTW_INFO("%s %s page_num change (%u -> %u)\n"
63 , __func__, cache->name, cache->page_num, page_num);
64 page_num_mod = 1;
65 }
66
67 if (info && info_len) {
68 if (cache->data) {
69 if (cache->size == info_len) {
70 if (_rtw_memcmp(cache->data, info, info_len) != _TRUE) {
71 RTW_INFO("%s %s data change\n", __func__, cache->name);
72 modified = 1;
73 }
74 } else
75 rsvd_page_cache_free_data(cache);
76 }
77
78 if (!cache->data) {
79 cache->data = rtw_malloc(info_len);
80 if (!cache->data) {
81 RTW_ERR("%s %s alloc data with size(%u) fail\n"
82 , __func__, cache->name, info_len);
83 rtw_warn_on(1);
84 } else {
85 RTW_INFO("%s %s alloc data with size(%u)\n"
86 , __func__, cache->name, info_len);
87 }
88 modified = 1;
89 }
90
91 if (cache->data && modified)
92 _rtw_memcpy(cache->data, info, info_len);
93 } else {
94 if (cache->data && size_mod)
95 rsvd_page_cache_free_data(cache);
96 }
97
98 cache->loc = loc;
99 cache->page_num = page_num;
100 cache->size = info_len;
101
102 return modified | loc_mod | size_mod | page_num_mod;
103 }
104
rsvd_page_cache_update_data(struct rsvd_page_cache_t * cache,u8 * info,u32 info_len)105 bool rsvd_page_cache_update_data(struct rsvd_page_cache_t *cache, u8 *info, u32 info_len)
106 {
107 bool modified = 0;
108
109 if (!info || !info_len) {
110 RTW_WARN("%s %s invalid input(info:%p, info_len:%u)\n"
111 , __func__, cache->name, info, info_len);
112 goto exit;
113 }
114
115 if (!cache->loc || !cache->page_num || !cache->size) {
116 RTW_ERR("%s %s layout not ready(loc:%u, page_num:%u, size:%u)\n"
117 , __func__, cache->name, cache->loc, cache->page_num, cache->size);
118 rtw_warn_on(1);
119 goto exit;
120 }
121
122 if (cache->size != info_len) {
123 RTW_ERR("%s %s size(%u) differ with info_len(%u)\n"
124 , __func__, cache->name, cache->size, info_len);
125 rtw_warn_on(1);
126 goto exit;
127 }
128
129 if (!cache->data) {
130 cache->data = rtw_zmalloc(cache->size);
131 if (!cache->data) {
132 RTW_ERR("%s %s alloc data with size(%u) fail\n"
133 , __func__, cache->name, cache->size);
134 rtw_warn_on(1);
135 goto exit;
136 } else {
137 RTW_INFO("%s %s alloc data with size(%u)\n"
138 , __func__, cache->name, info_len);
139 }
140 modified = 1;
141 }
142
143 if (_rtw_memcmp(cache->data, info, cache->size) == _FALSE) {
144 RTW_INFO("%s %s data change\n", __func__, cache->name);
145 _rtw_memcpy(cache->data, info, cache->size);
146 modified = 1;
147 }
148
149 exit:
150 return modified;
151 }
152
rsvd_page_cache_free_data(struct rsvd_page_cache_t * cache)153 void rsvd_page_cache_free_data(struct rsvd_page_cache_t *cache)
154 {
155 if (cache->data) {
156 rtw_mfree(cache->data, cache->size);
157 cache->data = NULL;
158 }
159 }
160
rsvd_page_cache_free(struct rsvd_page_cache_t * cache)161 void rsvd_page_cache_free(struct rsvd_page_cache_t *cache)
162 {
163 cache->loc = 0;
164 cache->page_num = 0;
165 rsvd_page_cache_free_data(cache);
166 cache->size = 0;
167 }
168
169 /* #define CONFIG_GTK_OL_DBG */
170
171 /*#define DBG_SEC_CAM_MOVE*/
172 #ifdef DBG_SEC_CAM_MOVE
rtw_hal_move_sta_gk_to_dk(_adapter * adapter)173 void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
174 {
175 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
176 int cam_id, index = 0;
177 u8 *addr = NULL;
178
179 if (!MLME_IS_STA(adapter))
180 return;
181
182 addr = get_bssid(pmlmepriv);
183
184 if (addr == NULL) {
185 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
186 return;
187 }
188
189 rtw_clean_dk_section(adapter);
190
191 do {
192 cam_id = rtw_camid_search(adapter, addr, index, 1);
193
194 if (cam_id == -1)
195 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
196 else
197 rtw_sec_cam_swap(adapter, cam_id, index);
198
199 index++;
200 } while (index < 4);
201
202 }
203
rtw_hal_read_sta_dk_key(_adapter * adapter,u8 key_id)204 void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
205 {
206 struct security_priv *psecuritypriv = &adapter->securitypriv;
207 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
208 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
209 _irqL irqL;
210 u8 get_key[16];
211
212 _rtw_memset(get_key, 0, sizeof(get_key));
213
214 if (key_id > 4) {
215 RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
216 rtw_warn_on(1);
217 return;
218 }
219 rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
220
221 /*update key into related sw variable*/
222 _enter_critical_bh(&cam_ctl->lock, &irqL);
223 if (_rtw_camid_is_gk(adapter, key_id)) {
224 RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
225 RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
226 }
227 _exit_critical_bh(&cam_ctl->lock, &irqL);
228
229 }
230 #endif
231
232
233 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
234 char rtw_phy_para_file_path[PATH_LENGTH_MAX];
235 #endif
236
dump_chip_info(HAL_VERSION ChipVersion)237 void dump_chip_info(HAL_VERSION ChipVersion)
238 {
239 int cnt = 0;
240 u8 buf[128] = {0};
241
242 if (IS_8188E(ChipVersion))
243 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
244 else if (IS_8188F(ChipVersion))
245 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
246 else if (IS_8188GTV(ChipVersion))
247 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188GTV_");
248 else if (IS_8812_SERIES(ChipVersion))
249 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
250 else if (IS_8192E(ChipVersion))
251 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
252 else if (IS_8821_SERIES(ChipVersion))
253 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
254 else if (IS_8723B_SERIES(ChipVersion))
255 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
256 else if (IS_8703B_SERIES(ChipVersion))
257 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
258 else if (IS_8723D_SERIES(ChipVersion))
259 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
260 else if (IS_8814A_SERIES(ChipVersion))
261 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
262 else if (IS_8822B_SERIES(ChipVersion))
263 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
264 else if (IS_8821C_SERIES(ChipVersion))
265 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
266 else if (IS_8710B_SERIES(ChipVersion))
267 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8710B_");
268 else if (IS_8192F_SERIES(ChipVersion))
269 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192F_");
270 else if (IS_8822C_SERIES(ChipVersion))
271 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822C_");
272 else
273 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
274
275 cnt += sprintf((buf + cnt), "%s", IS_NORMAL_CHIP(ChipVersion) ? "" : "T_");
276
277 if (IS_CHIP_VENDOR_TSMC(ChipVersion))
278 cnt += sprintf((buf + cnt), "%s", "T");
279 else if (IS_CHIP_VENDOR_UMC(ChipVersion))
280 cnt += sprintf((buf + cnt), "%s", "U");
281 else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
282 cnt += sprintf((buf + cnt), "%s", "S");
283
284 if (IS_A_CUT(ChipVersion))
285 cnt += sprintf((buf + cnt), "1_");
286 else if (IS_B_CUT(ChipVersion))
287 cnt += sprintf((buf + cnt), "2_");
288 else if (IS_C_CUT(ChipVersion))
289 cnt += sprintf((buf + cnt), "3_");
290 else if (IS_D_CUT(ChipVersion))
291 cnt += sprintf((buf + cnt), "4_");
292 else if (IS_E_CUT(ChipVersion))
293 cnt += sprintf((buf + cnt), "5_");
294 else if (IS_F_CUT(ChipVersion))
295 cnt += sprintf((buf + cnt), "6_");
296 else if (IS_I_CUT(ChipVersion))
297 cnt += sprintf((buf + cnt), "9_");
298 else if (IS_J_CUT(ChipVersion))
299 cnt += sprintf((buf + cnt), "10_");
300 else if (IS_K_CUT(ChipVersion))
301 cnt += sprintf((buf + cnt), "11_");
302 else
303 cnt += sprintf((buf + cnt), "UNKNOWN_Cv(%d)_", ChipVersion.CUTVersion);
304
305 if (IS_1T1R(ChipVersion))
306 cnt += sprintf((buf + cnt), "1T1R_");
307 else if (IS_1T2R(ChipVersion))
308 cnt += sprintf((buf + cnt), "1T2R_");
309 else if (IS_2T2R(ChipVersion))
310 cnt += sprintf((buf + cnt), "2T2R_");
311 else if (IS_3T3R(ChipVersion))
312 cnt += sprintf((buf + cnt), "3T3R_");
313 else if (IS_3T4R(ChipVersion))
314 cnt += sprintf((buf + cnt), "3T4R_");
315 else if (IS_4T4R(ChipVersion))
316 cnt += sprintf((buf + cnt), "4T4R_");
317 else
318 cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
319
320 cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
321
322 RTW_INFO("%s", buf);
323 }
324
rtw_hal_get_port(_adapter * adapter)325 u8 rtw_hal_get_port(_adapter *adapter)
326 {
327 u8 hw_port = get_hw_port(adapter);
328 #ifdef CONFIG_CLIENT_PORT_CFG
329 u8 clt_port = get_clt_port(adapter);
330
331 if (clt_port)
332 hw_port = clt_port;
333
334 #ifdef DBG_HW_PORT
335 if (MLME_IS_STA(adapter) && (adapter->client_id != MAX_CLIENT_PORT_NUM)) {
336 if(hw_port == CLT_PORT_INVALID) {
337 RTW_ERR(ADPT_FMT" @@@@@ Client port == 0 @@@@@\n", ADPT_ARG(adapter));
338 rtw_warn_on(1);
339 }
340 }
341 #ifdef CONFIG_AP_MODE
342 else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
343 if (hw_port != HW_PORT0) {
344 RTW_ERR(ADPT_FMT" @@@@@ AP / MESH port != 0 @@@@@\n", ADPT_ARG(adapter));
345 rtw_warn_on(1);
346 }
347 }
348 #endif
349 if (0)
350 RTW_INFO(ADPT_FMT" - HP:%d,CP:%d\n", ADPT_ARG(adapter), get_hw_port(adapter), get_clt_port(adapter));
351 #endif /*DBG_HW_PORT*/
352
353 #endif/*CONFIG_CLIENT_PORT_CFG*/
354
355 return hw_port;
356 }
357
358 #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
359
360 /*
361 * Description:
362 * Use hardware(efuse), driver parameter(registry) and default channel plan
363 * to decide which one should be used.
364 *
365 * Parameters:
366 * padapter pointer of adapter
367 * hw_alpha2 country code from HW (efuse/eeprom/mapfile)
368 * hw_chplan channel plan from HW (efuse/eeprom/mapfile)
369 * BIT[7] software configure mode; 0:Enable, 1:disable
370 * BIT[6:0] Channel Plan
371 * sw_alpha2 country code from HW (registry/module param)
372 * sw_chplan channel plan from SW (registry/module param)
373 * AutoLoadFail efuse autoload fail or not
374 *
375 */
hal_com_config_channel_plan(PADAPTER padapter,char * hw_alpha2,u8 hw_chplan,char * sw_alpha2,u8 sw_chplan,BOOLEAN AutoLoadFail)376 void hal_com_config_channel_plan(
377 PADAPTER padapter,
378 char *hw_alpha2,
379 u8 hw_chplan,
380 char *sw_alpha2,
381 u8 sw_chplan,
382 BOOLEAN AutoLoadFail
383 )
384 {
385 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
386 PHAL_DATA_TYPE pHalData;
387 u8 force_hw_chplan = _FALSE;
388 int chplan = -1;
389 const struct country_chplan *country_ent = NULL, *ent;
390 u8 def_chplan = 0x7F; /* Realtek define, used when HW, SW both invalid */
391
392 pHalData = GET_HAL_DATA(padapter);
393
394 /* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
395 if (hw_chplan == 0xFF)
396 goto chk_hw_country_code;
397
398 if (AutoLoadFail == _TRUE)
399 goto chk_sw_config;
400
401 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
402 if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
403 force_hw_chplan = _TRUE;
404 #endif
405
406 hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
407
408 chk_hw_country_code:
409 if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
410 ent = rtw_get_chplan_from_country(hw_alpha2);
411 if (ent) {
412 /* get chplan from hw country code, by pass hw chplan setting */
413 country_ent = ent;
414 chplan = ent->chplan;
415 goto chk_sw_config;
416 } else
417 RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
418 }
419
420 if (rtw_is_channel_plan_valid(hw_chplan))
421 chplan = hw_chplan;
422 else if (force_hw_chplan == _TRUE) {
423 RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
424 /* hw infomaton invalid, refer to sw information */
425 force_hw_chplan = _FALSE;
426 }
427
428 chk_sw_config:
429 if (force_hw_chplan == _TRUE)
430 goto done;
431
432 if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
433 ent = rtw_get_chplan_from_country(sw_alpha2);
434 if (ent) {
435 /* get chplan from sw country code, by pass sw chplan setting */
436 country_ent = ent;
437 chplan = ent->chplan;
438 goto done;
439 } else
440 RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
441 }
442
443 if (rtw_is_channel_plan_valid(sw_chplan)) {
444 /* cancel hw_alpha2 because chplan is specified by sw_chplan*/
445 country_ent = NULL;
446 chplan = sw_chplan;
447 } else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
448 RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
449
450 done:
451 if (chplan == -1) {
452 RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
453 chplan = def_chplan;
454 } else if (country_ent) {
455 RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
456 , country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
457 } else
458 RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
459
460 rfctl->country_ent = country_ent;
461 rfctl->ChannelPlan = chplan;
462 pHalData->bDisableSWChannelPlan = force_hw_chplan;
463 }
464
465 BOOLEAN
HAL_IsLegalChannel(PADAPTER Adapter,u32 Channel)466 HAL_IsLegalChannel(
467 PADAPTER Adapter,
468 u32 Channel
469 )
470 {
471 BOOLEAN bLegalChannel = _TRUE;
472
473 if (Channel > 14) {
474 if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
475 bLegalChannel = _FALSE;
476 RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
477 }
478 } else if ((Channel <= 14) && (Channel >= 1)) {
479 if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
480 bLegalChannel = _FALSE;
481 RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
482 }
483 } else {
484 bLegalChannel = _FALSE;
485 RTW_INFO("Channel is Invalid !!!\n");
486 }
487
488 return bLegalChannel;
489 }
490
MRateToHwRate(u8 rate)491 u8 MRateToHwRate(u8 rate)
492 {
493 u8 ret = DESC_RATE1M;
494
495 switch (rate) {
496 case MGN_1M:
497 ret = DESC_RATE1M;
498 break;
499 case MGN_2M:
500 ret = DESC_RATE2M;
501 break;
502 case MGN_5_5M:
503 ret = DESC_RATE5_5M;
504 break;
505 case MGN_11M:
506 ret = DESC_RATE11M;
507 break;
508 case MGN_6M:
509 ret = DESC_RATE6M;
510 break;
511 case MGN_9M:
512 ret = DESC_RATE9M;
513 break;
514 case MGN_12M:
515 ret = DESC_RATE12M;
516 break;
517 case MGN_18M:
518 ret = DESC_RATE18M;
519 break;
520 case MGN_24M:
521 ret = DESC_RATE24M;
522 break;
523 case MGN_36M:
524 ret = DESC_RATE36M;
525 break;
526 case MGN_48M:
527 ret = DESC_RATE48M;
528 break;
529 case MGN_54M:
530 ret = DESC_RATE54M;
531 break;
532
533 case MGN_MCS0:
534 ret = DESC_RATEMCS0;
535 break;
536 case MGN_MCS1:
537 ret = DESC_RATEMCS1;
538 break;
539 case MGN_MCS2:
540 ret = DESC_RATEMCS2;
541 break;
542 case MGN_MCS3:
543 ret = DESC_RATEMCS3;
544 break;
545 case MGN_MCS4:
546 ret = DESC_RATEMCS4;
547 break;
548 case MGN_MCS5:
549 ret = DESC_RATEMCS5;
550 break;
551 case MGN_MCS6:
552 ret = DESC_RATEMCS6;
553 break;
554 case MGN_MCS7:
555 ret = DESC_RATEMCS7;
556 break;
557 case MGN_MCS8:
558 ret = DESC_RATEMCS8;
559 break;
560 case MGN_MCS9:
561 ret = DESC_RATEMCS9;
562 break;
563 case MGN_MCS10:
564 ret = DESC_RATEMCS10;
565 break;
566 case MGN_MCS11:
567 ret = DESC_RATEMCS11;
568 break;
569 case MGN_MCS12:
570 ret = DESC_RATEMCS12;
571 break;
572 case MGN_MCS13:
573 ret = DESC_RATEMCS13;
574 break;
575 case MGN_MCS14:
576 ret = DESC_RATEMCS14;
577 break;
578 case MGN_MCS15:
579 ret = DESC_RATEMCS15;
580 break;
581 case MGN_MCS16:
582 ret = DESC_RATEMCS16;
583 break;
584 case MGN_MCS17:
585 ret = DESC_RATEMCS17;
586 break;
587 case MGN_MCS18:
588 ret = DESC_RATEMCS18;
589 break;
590 case MGN_MCS19:
591 ret = DESC_RATEMCS19;
592 break;
593 case MGN_MCS20:
594 ret = DESC_RATEMCS20;
595 break;
596 case MGN_MCS21:
597 ret = DESC_RATEMCS21;
598 break;
599 case MGN_MCS22:
600 ret = DESC_RATEMCS22;
601 break;
602 case MGN_MCS23:
603 ret = DESC_RATEMCS23;
604 break;
605 case MGN_MCS24:
606 ret = DESC_RATEMCS24;
607 break;
608 case MGN_MCS25:
609 ret = DESC_RATEMCS25;
610 break;
611 case MGN_MCS26:
612 ret = DESC_RATEMCS26;
613 break;
614 case MGN_MCS27:
615 ret = DESC_RATEMCS27;
616 break;
617 case MGN_MCS28:
618 ret = DESC_RATEMCS28;
619 break;
620 case MGN_MCS29:
621 ret = DESC_RATEMCS29;
622 break;
623 case MGN_MCS30:
624 ret = DESC_RATEMCS30;
625 break;
626 case MGN_MCS31:
627 ret = DESC_RATEMCS31;
628 break;
629
630 case MGN_VHT1SS_MCS0:
631 ret = DESC_RATEVHTSS1MCS0;
632 break;
633 case MGN_VHT1SS_MCS1:
634 ret = DESC_RATEVHTSS1MCS1;
635 break;
636 case MGN_VHT1SS_MCS2:
637 ret = DESC_RATEVHTSS1MCS2;
638 break;
639 case MGN_VHT1SS_MCS3:
640 ret = DESC_RATEVHTSS1MCS3;
641 break;
642 case MGN_VHT1SS_MCS4:
643 ret = DESC_RATEVHTSS1MCS4;
644 break;
645 case MGN_VHT1SS_MCS5:
646 ret = DESC_RATEVHTSS1MCS5;
647 break;
648 case MGN_VHT1SS_MCS6:
649 ret = DESC_RATEVHTSS1MCS6;
650 break;
651 case MGN_VHT1SS_MCS7:
652 ret = DESC_RATEVHTSS1MCS7;
653 break;
654 case MGN_VHT1SS_MCS8:
655 ret = DESC_RATEVHTSS1MCS8;
656 break;
657 case MGN_VHT1SS_MCS9:
658 ret = DESC_RATEVHTSS1MCS9;
659 break;
660 case MGN_VHT2SS_MCS0:
661 ret = DESC_RATEVHTSS2MCS0;
662 break;
663 case MGN_VHT2SS_MCS1:
664 ret = DESC_RATEVHTSS2MCS1;
665 break;
666 case MGN_VHT2SS_MCS2:
667 ret = DESC_RATEVHTSS2MCS2;
668 break;
669 case MGN_VHT2SS_MCS3:
670 ret = DESC_RATEVHTSS2MCS3;
671 break;
672 case MGN_VHT2SS_MCS4:
673 ret = DESC_RATEVHTSS2MCS4;
674 break;
675 case MGN_VHT2SS_MCS5:
676 ret = DESC_RATEVHTSS2MCS5;
677 break;
678 case MGN_VHT2SS_MCS6:
679 ret = DESC_RATEVHTSS2MCS6;
680 break;
681 case MGN_VHT2SS_MCS7:
682 ret = DESC_RATEVHTSS2MCS7;
683 break;
684 case MGN_VHT2SS_MCS8:
685 ret = DESC_RATEVHTSS2MCS8;
686 break;
687 case MGN_VHT2SS_MCS9:
688 ret = DESC_RATEVHTSS2MCS9;
689 break;
690 case MGN_VHT3SS_MCS0:
691 ret = DESC_RATEVHTSS3MCS0;
692 break;
693 case MGN_VHT3SS_MCS1:
694 ret = DESC_RATEVHTSS3MCS1;
695 break;
696 case MGN_VHT3SS_MCS2:
697 ret = DESC_RATEVHTSS3MCS2;
698 break;
699 case MGN_VHT3SS_MCS3:
700 ret = DESC_RATEVHTSS3MCS3;
701 break;
702 case MGN_VHT3SS_MCS4:
703 ret = DESC_RATEVHTSS3MCS4;
704 break;
705 case MGN_VHT3SS_MCS5:
706 ret = DESC_RATEVHTSS3MCS5;
707 break;
708 case MGN_VHT3SS_MCS6:
709 ret = DESC_RATEVHTSS3MCS6;
710 break;
711 case MGN_VHT3SS_MCS7:
712 ret = DESC_RATEVHTSS3MCS7;
713 break;
714 case MGN_VHT3SS_MCS8:
715 ret = DESC_RATEVHTSS3MCS8;
716 break;
717 case MGN_VHT3SS_MCS9:
718 ret = DESC_RATEVHTSS3MCS9;
719 break;
720 case MGN_VHT4SS_MCS0:
721 ret = DESC_RATEVHTSS4MCS0;
722 break;
723 case MGN_VHT4SS_MCS1:
724 ret = DESC_RATEVHTSS4MCS1;
725 break;
726 case MGN_VHT4SS_MCS2:
727 ret = DESC_RATEVHTSS4MCS2;
728 break;
729 case MGN_VHT4SS_MCS3:
730 ret = DESC_RATEVHTSS4MCS3;
731 break;
732 case MGN_VHT4SS_MCS4:
733 ret = DESC_RATEVHTSS4MCS4;
734 break;
735 case MGN_VHT4SS_MCS5:
736 ret = DESC_RATEVHTSS4MCS5;
737 break;
738 case MGN_VHT4SS_MCS6:
739 ret = DESC_RATEVHTSS4MCS6;
740 break;
741 case MGN_VHT4SS_MCS7:
742 ret = DESC_RATEVHTSS4MCS7;
743 break;
744 case MGN_VHT4SS_MCS8:
745 ret = DESC_RATEVHTSS4MCS8;
746 break;
747 case MGN_VHT4SS_MCS9:
748 ret = DESC_RATEVHTSS4MCS9;
749 break;
750 default:
751 break;
752 }
753
754 return ret;
755 }
756
hw_rate_to_m_rate(u8 rate)757 u8 hw_rate_to_m_rate(u8 rate)
758 {
759 u8 ret_rate = MGN_1M;
760
761 switch (rate) {
762
763 case DESC_RATE1M:
764 ret_rate = MGN_1M;
765 break;
766 case DESC_RATE2M:
767 ret_rate = MGN_2M;
768 break;
769 case DESC_RATE5_5M:
770 ret_rate = MGN_5_5M;
771 break;
772 case DESC_RATE11M:
773 ret_rate = MGN_11M;
774 break;
775 case DESC_RATE6M:
776 ret_rate = MGN_6M;
777 break;
778 case DESC_RATE9M:
779 ret_rate = MGN_9M;
780 break;
781 case DESC_RATE12M:
782 ret_rate = MGN_12M;
783 break;
784 case DESC_RATE18M:
785 ret_rate = MGN_18M;
786 break;
787 case DESC_RATE24M:
788 ret_rate = MGN_24M;
789 break;
790 case DESC_RATE36M:
791 ret_rate = MGN_36M;
792 break;
793 case DESC_RATE48M:
794 ret_rate = MGN_48M;
795 break;
796 case DESC_RATE54M:
797 ret_rate = MGN_54M;
798 break;
799 case DESC_RATEMCS0:
800 ret_rate = MGN_MCS0;
801 break;
802 case DESC_RATEMCS1:
803 ret_rate = MGN_MCS1;
804 break;
805 case DESC_RATEMCS2:
806 ret_rate = MGN_MCS2;
807 break;
808 case DESC_RATEMCS3:
809 ret_rate = MGN_MCS3;
810 break;
811 case DESC_RATEMCS4:
812 ret_rate = MGN_MCS4;
813 break;
814 case DESC_RATEMCS5:
815 ret_rate = MGN_MCS5;
816 break;
817 case DESC_RATEMCS6:
818 ret_rate = MGN_MCS6;
819 break;
820 case DESC_RATEMCS7:
821 ret_rate = MGN_MCS7;
822 break;
823 case DESC_RATEMCS8:
824 ret_rate = MGN_MCS8;
825 break;
826 case DESC_RATEMCS9:
827 ret_rate = MGN_MCS9;
828 break;
829 case DESC_RATEMCS10:
830 ret_rate = MGN_MCS10;
831 break;
832 case DESC_RATEMCS11:
833 ret_rate = MGN_MCS11;
834 break;
835 case DESC_RATEMCS12:
836 ret_rate = MGN_MCS12;
837 break;
838 case DESC_RATEMCS13:
839 ret_rate = MGN_MCS13;
840 break;
841 case DESC_RATEMCS14:
842 ret_rate = MGN_MCS14;
843 break;
844 case DESC_RATEMCS15:
845 ret_rate = MGN_MCS15;
846 break;
847 case DESC_RATEMCS16:
848 ret_rate = MGN_MCS16;
849 break;
850 case DESC_RATEMCS17:
851 ret_rate = MGN_MCS17;
852 break;
853 case DESC_RATEMCS18:
854 ret_rate = MGN_MCS18;
855 break;
856 case DESC_RATEMCS19:
857 ret_rate = MGN_MCS19;
858 break;
859 case DESC_RATEMCS20:
860 ret_rate = MGN_MCS20;
861 break;
862 case DESC_RATEMCS21:
863 ret_rate = MGN_MCS21;
864 break;
865 case DESC_RATEMCS22:
866 ret_rate = MGN_MCS22;
867 break;
868 case DESC_RATEMCS23:
869 ret_rate = MGN_MCS23;
870 break;
871 case DESC_RATEMCS24:
872 ret_rate = MGN_MCS24;
873 break;
874 case DESC_RATEMCS25:
875 ret_rate = MGN_MCS25;
876 break;
877 case DESC_RATEMCS26:
878 ret_rate = MGN_MCS26;
879 break;
880 case DESC_RATEMCS27:
881 ret_rate = MGN_MCS27;
882 break;
883 case DESC_RATEMCS28:
884 ret_rate = MGN_MCS28;
885 break;
886 case DESC_RATEMCS29:
887 ret_rate = MGN_MCS29;
888 break;
889 case DESC_RATEMCS30:
890 ret_rate = MGN_MCS30;
891 break;
892 case DESC_RATEMCS31:
893 ret_rate = MGN_MCS31;
894 break;
895 case DESC_RATEVHTSS1MCS0:
896 ret_rate = MGN_VHT1SS_MCS0;
897 break;
898 case DESC_RATEVHTSS1MCS1:
899 ret_rate = MGN_VHT1SS_MCS1;
900 break;
901 case DESC_RATEVHTSS1MCS2:
902 ret_rate = MGN_VHT1SS_MCS2;
903 break;
904 case DESC_RATEVHTSS1MCS3:
905 ret_rate = MGN_VHT1SS_MCS3;
906 break;
907 case DESC_RATEVHTSS1MCS4:
908 ret_rate = MGN_VHT1SS_MCS4;
909 break;
910 case DESC_RATEVHTSS1MCS5:
911 ret_rate = MGN_VHT1SS_MCS5;
912 break;
913 case DESC_RATEVHTSS1MCS6:
914 ret_rate = MGN_VHT1SS_MCS6;
915 break;
916 case DESC_RATEVHTSS1MCS7:
917 ret_rate = MGN_VHT1SS_MCS7;
918 break;
919 case DESC_RATEVHTSS1MCS8:
920 ret_rate = MGN_VHT1SS_MCS8;
921 break;
922 case DESC_RATEVHTSS1MCS9:
923 ret_rate = MGN_VHT1SS_MCS9;
924 break;
925 case DESC_RATEVHTSS2MCS0:
926 ret_rate = MGN_VHT2SS_MCS0;
927 break;
928 case DESC_RATEVHTSS2MCS1:
929 ret_rate = MGN_VHT2SS_MCS1;
930 break;
931 case DESC_RATEVHTSS2MCS2:
932 ret_rate = MGN_VHT2SS_MCS2;
933 break;
934 case DESC_RATEVHTSS2MCS3:
935 ret_rate = MGN_VHT2SS_MCS3;
936 break;
937 case DESC_RATEVHTSS2MCS4:
938 ret_rate = MGN_VHT2SS_MCS4;
939 break;
940 case DESC_RATEVHTSS2MCS5:
941 ret_rate = MGN_VHT2SS_MCS5;
942 break;
943 case DESC_RATEVHTSS2MCS6:
944 ret_rate = MGN_VHT2SS_MCS6;
945 break;
946 case DESC_RATEVHTSS2MCS7:
947 ret_rate = MGN_VHT2SS_MCS7;
948 break;
949 case DESC_RATEVHTSS2MCS8:
950 ret_rate = MGN_VHT2SS_MCS8;
951 break;
952 case DESC_RATEVHTSS2MCS9:
953 ret_rate = MGN_VHT2SS_MCS9;
954 break;
955 case DESC_RATEVHTSS3MCS0:
956 ret_rate = MGN_VHT3SS_MCS0;
957 break;
958 case DESC_RATEVHTSS3MCS1:
959 ret_rate = MGN_VHT3SS_MCS1;
960 break;
961 case DESC_RATEVHTSS3MCS2:
962 ret_rate = MGN_VHT3SS_MCS2;
963 break;
964 case DESC_RATEVHTSS3MCS3:
965 ret_rate = MGN_VHT3SS_MCS3;
966 break;
967 case DESC_RATEVHTSS3MCS4:
968 ret_rate = MGN_VHT3SS_MCS4;
969 break;
970 case DESC_RATEVHTSS3MCS5:
971 ret_rate = MGN_VHT3SS_MCS5;
972 break;
973 case DESC_RATEVHTSS3MCS6:
974 ret_rate = MGN_VHT3SS_MCS6;
975 break;
976 case DESC_RATEVHTSS3MCS7:
977 ret_rate = MGN_VHT3SS_MCS7;
978 break;
979 case DESC_RATEVHTSS3MCS8:
980 ret_rate = MGN_VHT3SS_MCS8;
981 break;
982 case DESC_RATEVHTSS3MCS9:
983 ret_rate = MGN_VHT3SS_MCS9;
984 break;
985 case DESC_RATEVHTSS4MCS0:
986 ret_rate = MGN_VHT4SS_MCS0;
987 break;
988 case DESC_RATEVHTSS4MCS1:
989 ret_rate = MGN_VHT4SS_MCS1;
990 break;
991 case DESC_RATEVHTSS4MCS2:
992 ret_rate = MGN_VHT4SS_MCS2;
993 break;
994 case DESC_RATEVHTSS4MCS3:
995 ret_rate = MGN_VHT4SS_MCS3;
996 break;
997 case DESC_RATEVHTSS4MCS4:
998 ret_rate = MGN_VHT4SS_MCS4;
999 break;
1000 case DESC_RATEVHTSS4MCS5:
1001 ret_rate = MGN_VHT4SS_MCS5;
1002 break;
1003 case DESC_RATEVHTSS4MCS6:
1004 ret_rate = MGN_VHT4SS_MCS6;
1005 break;
1006 case DESC_RATEVHTSS4MCS7:
1007 ret_rate = MGN_VHT4SS_MCS7;
1008 break;
1009 case DESC_RATEVHTSS4MCS8:
1010 ret_rate = MGN_VHT4SS_MCS8;
1011 break;
1012 case DESC_RATEVHTSS4MCS9:
1013 ret_rate = MGN_VHT4SS_MCS9;
1014 break;
1015
1016 default:
1017 RTW_INFO("hw_rate_to_m_rate(): Non supported Rate [%x]!!!\n", rate);
1018 break;
1019 }
1020
1021 return ret_rate;
1022 }
1023
HalSetBrateCfg(PADAPTER Adapter,u8 * mBratesOS,u16 * pBrateCfg)1024 void HalSetBrateCfg(
1025 PADAPTER Adapter,
1026 u8 *mBratesOS,
1027 u16 *pBrateCfg)
1028 {
1029 u8 i, is_brate, brate;
1030
1031 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
1032 is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
1033 brate = mBratesOS[i] & 0x7f;
1034
1035 if (is_brate) {
1036 switch (brate) {
1037 case IEEE80211_CCK_RATE_1MB:
1038 *pBrateCfg |= RATE_1M;
1039 break;
1040 case IEEE80211_CCK_RATE_2MB:
1041 *pBrateCfg |= RATE_2M;
1042 break;
1043 case IEEE80211_CCK_RATE_5MB:
1044 *pBrateCfg |= RATE_5_5M;
1045 break;
1046 case IEEE80211_CCK_RATE_11MB:
1047 *pBrateCfg |= RATE_11M;
1048 break;
1049 case IEEE80211_OFDM_RATE_6MB:
1050 *pBrateCfg |= RATE_6M;
1051 break;
1052 case IEEE80211_OFDM_RATE_9MB:
1053 *pBrateCfg |= RATE_9M;
1054 break;
1055 case IEEE80211_OFDM_RATE_12MB:
1056 *pBrateCfg |= RATE_12M;
1057 break;
1058 case IEEE80211_OFDM_RATE_18MB:
1059 *pBrateCfg |= RATE_18M;
1060 break;
1061 case IEEE80211_OFDM_RATE_24MB:
1062 *pBrateCfg |= RATE_24M;
1063 break;
1064 case IEEE80211_OFDM_RATE_36MB:
1065 *pBrateCfg |= RATE_36M;
1066 break;
1067 case IEEE80211_OFDM_RATE_48MB:
1068 *pBrateCfg |= RATE_48M;
1069 break;
1070 case IEEE80211_OFDM_RATE_54MB:
1071 *pBrateCfg |= RATE_54M;
1072 break;
1073 }
1074 }
1075 }
1076 }
1077
1078 static void
_OneOutPipeMapping(PADAPTER pAdapter)1079 _OneOutPipeMapping(
1080 PADAPTER pAdapter
1081 )
1082 {
1083 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1084
1085 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1086 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1087 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
1088 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
1089
1090 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1091 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1092 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1093 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1094 }
1095
1096 static void
_TwoOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)1097 _TwoOutPipeMapping(
1098 PADAPTER pAdapter,
1099 BOOLEAN bWIFICfg
1100 )
1101 {
1102 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1103
1104 if (bWIFICfg) { /* WMM */
1105
1106 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1107 /* { 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
1108 /* 0:ep_0 num, 1:ep_1 num */
1109
1110 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
1111 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1112 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
1113 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
1114
1115 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1116 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1117 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1118 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1119
1120 } else { /* typical setting */
1121
1122
1123 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1124 /* { 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
1125 /* 0:ep_0 num, 1:ep_1 num */
1126
1127 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1128 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1129 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
1130 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1131
1132 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1133 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1134 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1135 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1136
1137 }
1138
1139 }
1140
_ThreeOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)1141 static void _ThreeOutPipeMapping(
1142 PADAPTER pAdapter,
1143 BOOLEAN bWIFICfg
1144 )
1145 {
1146 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1147
1148 if (bWIFICfg) { /* for WMM */
1149
1150 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1151 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1152 /* 0:H, 1:N, 2:L */
1153
1154 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1155 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1156 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1157 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1158
1159 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1160 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1161 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1162 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1163
1164 } else { /* typical setting */
1165
1166
1167 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1168 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1169 /* 0:H, 1:N, 2:L */
1170
1171 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1172 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1173 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1174 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1175
1176 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1177 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1178 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1179 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1180 }
1181
1182 }
1183 #if 0
1184 static void _FourOutPipeMapping(
1185 PADAPTER pAdapter,
1186 BOOLEAN bWIFICfg
1187 )
1188 {
1189 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1190
1191 if (bWIFICfg) { /* for WMM */
1192
1193 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1194 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1195 /* 0:H, 1:N, 2:L ,3:E */
1196
1197 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1198 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1199 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1200 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1201
1202 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1203 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1204 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1205 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1206
1207 } else { /* typical setting */
1208
1209
1210 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1211 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1212 /* 0:H, 1:N, 2:L */
1213
1214 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1215 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1216 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1217 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1218
1219 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1220 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1221 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1222 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1223 }
1224
1225 }
1226 #endif
1227 BOOLEAN
Hal_MappingOutPipe(PADAPTER pAdapter,u8 NumOutPipe)1228 Hal_MappingOutPipe(
1229 PADAPTER pAdapter,
1230 u8 NumOutPipe
1231 )
1232 {
1233 struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
1234
1235 BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
1236
1237 BOOLEAN result = _TRUE;
1238
1239 switch (NumOutPipe) {
1240 case 2:
1241 _TwoOutPipeMapping(pAdapter, bWIFICfg);
1242 break;
1243 case 3:
1244 case 4:
1245 case 5:
1246 case 6:
1247 _ThreeOutPipeMapping(pAdapter, bWIFICfg);
1248 break;
1249 case 1:
1250 _OneOutPipeMapping(pAdapter);
1251 break;
1252 default:
1253 result = _FALSE;
1254 break;
1255 }
1256
1257 return result;
1258
1259 }
1260
rtw_hal_reqtxrpt(_adapter * padapter,u8 macid)1261 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1262 {
1263 if (padapter->hal_func.reqtxrpt)
1264 padapter->hal_func.reqtxrpt(padapter, macid);
1265 }
1266
rtw_hal_dump_macaddr(void * sel,_adapter * adapter)1267 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1268 {
1269 int i;
1270 _adapter *iface;
1271 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1272 u8 mac_addr[ETH_ALEN];
1273
1274 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1275 rtw_mbid_cam_dump(sel, __func__, adapter);
1276 #else
1277 rtw_mi_hal_dump_macaddr(sel, adapter);
1278 #endif
1279 }
1280
1281 #ifdef RTW_HALMAC
rtw_hal_hw_port_enable(_adapter * adapter)1282 void rtw_hal_hw_port_enable(_adapter *adapter)
1283 {
1284 #if 1
1285 u8 port_enable = _TRUE;
1286
1287 rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1288 #else
1289 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1290 struct rtw_halmac_bcn_ctrl bcn_ctrl;
1291
1292 _rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
1293 bcn_ctrl.enable_bcn = 1;
1294 bcn_ctrl.rx_bssid_fit = 1;
1295 bcn_ctrl.rxbcn_rpt = 1;
1296
1297 /*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1298 struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
1299 if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
1300 RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
1301 rtw_warn_on(1);
1302 }
1303 #endif
1304 }
rtw_hal_hw_port_disable(_adapter * adapter)1305 void rtw_hal_hw_port_disable(_adapter *adapter)
1306 {
1307 u8 port_enable = _FALSE;
1308
1309 rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1310 }
1311
rtw_restore_hw_port_cfg(_adapter * adapter)1312 void rtw_restore_hw_port_cfg(_adapter *adapter)
1313 {
1314 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1315
1316 #else
1317 int i;
1318 _adapter *iface;
1319 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1320
1321 for (i = 0; i < dvobj->iface_nums; i++) {
1322 iface = dvobj->padapters[i];
1323 if (iface)
1324 rtw_hal_hw_port_enable(iface);
1325 }
1326 #endif
1327 }
1328 #endif
1329
rtw_mi_set_mac_addr(_adapter * adapter)1330 void rtw_mi_set_mac_addr(_adapter *adapter)
1331 {
1332 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1333 rtw_mi_set_mbid_cam(adapter);
1334 #else
1335 int i;
1336 _adapter *iface;
1337 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1338
1339 for (i = 0; i < dvobj->iface_nums; i++) {
1340 iface = dvobj->padapters[i];
1341 if (iface)
1342 rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
1343 }
1344 #endif
1345 if (0)
1346 rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1347 }
1348
rtw_init_hal_com_default_value(PADAPTER Adapter)1349 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1350 {
1351 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
1352 struct registry_priv *regsty = adapter_to_regsty(Adapter);
1353
1354 pHalData->AntDetection = 1;
1355 pHalData->antenna_test = _FALSE;
1356 pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
1357 pHalData->ch_switch_offload = regsty->ch_switch_offload;
1358 pHalData->multi_ch_switch_mode = 0;
1359 #ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME
1360 if (pHalData->ch_switch_offload == 0)
1361 pHalData->ch_switch_offload = 1;
1362 #endif
1363 }
1364
1365 #ifdef CONFIG_FW_C2H_REG
c2h_evt_clear(_adapter * adapter)1366 void c2h_evt_clear(_adapter *adapter)
1367 {
1368 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1369 }
1370
c2h_evt_read_88xx(_adapter * adapter,u8 * buf)1371 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1372 {
1373 s32 ret = _FAIL;
1374 int i;
1375 u8 trigger;
1376
1377 if (buf == NULL)
1378 goto exit;
1379
1380 trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1381
1382 if (trigger == C2H_EVT_HOST_CLOSE) {
1383 goto exit; /* Not ready */
1384 } else if (trigger != C2H_EVT_FW_CLOSE) {
1385 goto clear_evt; /* Not a valid value */
1386 }
1387
1388 _rtw_memset(buf, 0, C2H_REG_LEN);
1389
1390 /* Read ID, LEN, SEQ */
1391 SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
1392 SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
1393 SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
1394
1395 if (0) {
1396 RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
1397 , C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
1398 }
1399
1400 /* Read the content */
1401 for (i = 0; i < C2H_PLEN_88XX(buf); i++)
1402 *(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1403
1404 RTW_DBG_DUMP("payload: ", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
1405
1406 ret = _SUCCESS;
1407
1408 clear_evt:
1409 /*
1410 * Clear event to notify FW we have read the command.
1411 * If this field isn't clear, the FW won't update the next command message.
1412 */
1413 c2h_evt_clear(adapter);
1414
1415 exit:
1416 return ret;
1417 }
1418 #endif /* CONFIG_FW_C2H_REG */
1419
1420 #ifdef CONFIG_FW_C2H_PKT
1421 #ifndef DBG_C2H_PKT_PRE_HDL
1422 #define DBG_C2H_PKT_PRE_HDL 0
1423 #endif
1424 #ifndef DBG_C2H_PKT_HDL
1425 #define DBG_C2H_PKT_HDL 0
1426 #endif
rtw_hal_c2h_pkt_pre_hdl(_adapter * adapter,u8 * buf,u16 len)1427 void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
1428 {
1429 #ifdef RTW_HALMAC
1430 /* TODO: extract hal_mac IC's code here*/
1431 #else
1432 u8 parse_fail = 0;
1433 u8 hdl_here = 0;
1434 s32 ret = _FAIL;
1435 u8 id, seq, plen;
1436 u8 *payload;
1437
1438 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1439 parse_fail = 1;
1440 goto exit;
1441 }
1442
1443 hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
1444 if (hdl_here)
1445 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1446 else
1447 ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
1448
1449 exit:
1450 if (parse_fail)
1451 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1452 else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
1453 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1454 , hdl_here ? "handle" : "enqueue"
1455 , ret == _SUCCESS ? "ok" : "fail"
1456 );
1457 if (DBG_C2H_PKT_PRE_HDL >= 2)
1458 RTW_PRINT_DUMP("dump: ", buf, len);
1459 }
1460 #endif
1461 }
1462
rtw_hal_c2h_pkt_hdl(_adapter * adapter,u8 * buf,u16 len)1463 void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
1464 {
1465 #ifdef RTW_HALMAC
1466 adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
1467 #else
1468 u8 parse_fail = 0;
1469 u8 bypass = 0;
1470 s32 ret = _FAIL;
1471 u8 id, seq, plen;
1472 u8 *payload;
1473
1474 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1475 parse_fail = 1;
1476 goto exit;
1477 }
1478
1479 #ifdef CONFIG_WOWLAN
1480 if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
1481 bypass = 1;
1482 ret = _SUCCESS;
1483 goto exit;
1484 }
1485 #endif
1486
1487 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1488
1489 exit:
1490 if (parse_fail)
1491 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1492 else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
1493 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1494 , !bypass ? "handle" : "bypass"
1495 , ret == _SUCCESS ? "ok" : "fail"
1496 );
1497 if (DBG_C2H_PKT_HDL >= 2)
1498 RTW_PRINT_DUMP("dump: ", buf, len);
1499 }
1500 #endif
1501 }
1502 #endif /* CONFIG_FW_C2H_PKT */
1503
c2h_iqk_offload(_adapter * adapter,u8 * data,u8 len)1504 void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
1505 {
1506 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1507 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1508
1509 RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
1510 if (0)
1511 RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
1512
1513 rtw_sctx_done(&iqk_sctx);
1514 }
1515
c2h_iqk_offload_wait(_adapter * adapter,u32 timeout_ms)1516 int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
1517 {
1518 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1519 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1520
1521 iqk_sctx->submit_time = rtw_get_current_time();
1522 iqk_sctx->timeout_ms = timeout_ms;
1523 iqk_sctx->status = RTW_SCTX_SUBMITTED;
1524
1525 return rtw_sctx_wait(iqk_sctx, __func__);
1526 }
1527
1528 #ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX
c2h_txpwr_idx_offload_done(_adapter * adapter,u8 * data,u8 len)1529 void c2h_txpwr_idx_offload_done(_adapter *adapter, u8 *data, u8 len)
1530 {
1531 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1532 struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1533
1534 if (0)
1535 RTW_INFO("txpwr_idx offload finish in %dms\n", rtw_get_passing_time_ms(sctx->submit_time));
1536 rtw_sctx_done(&sctx);
1537 }
1538
c2h_txpwr_idx_offload_wait(_adapter * adapter)1539 int c2h_txpwr_idx_offload_wait(_adapter *adapter)
1540 {
1541 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1542 struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1543
1544 return rtw_sctx_wait(sctx, __func__);
1545 }
1546 #endif
1547
1548 #define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1549 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1550 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1551 #define GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1552 #define GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1553 #define GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
1554 #define GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
1555 #define GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1556 #define GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1557 #define GET_C2H_MAC_HIDDEN_RPT_BW(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1558 #define GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1559 #define GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1560 #define GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1561
1562 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1563 #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1564 #endif
1565
1566 #ifdef CONFIG_RTW_MAC_HIDDEN_RPT
c2h_mac_hidden_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1567 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1568 {
1569 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1570 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1571 enum rf_type rf_type;
1572 u8 tx_path_num, rx_path_num;
1573 int ret = _FAIL;
1574
1575 u8 uuid_x;
1576 u8 uuid_y;
1577 u8 uuid_z;
1578 u16 uuid_crc;
1579
1580 u8 hci_type;
1581 u8 package_type;
1582 u8 tr_switch;
1583 u8 wl_func;
1584 u8 hw_stype;
1585 u8 bw;
1586 u8 ss_num = 4;
1587 u8 ant_num;
1588 u8 protocol;
1589 u8 nic;
1590
1591 int i;
1592
1593 if (len < MAC_HIDDEN_RPT_LEN) {
1594 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1595 goto exit;
1596 }
1597
1598 uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1599 uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1600 uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1601 uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1602
1603 hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1604 package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1605
1606 tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
1607
1608 wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1609 hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1610
1611 bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1612 ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1613
1614 protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1615 nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1616
1617 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1618 for (i = 0; i < len; i++)
1619 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1620
1621 RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1622 RTW_PRINT("hci_type:0x%x\n", hci_type);
1623 RTW_PRINT("package_type:0x%x\n", package_type);
1624 RTW_PRINT("tr_switch:0x%x\n", tr_switch);
1625 RTW_PRINT("wl_func:0x%x\n", wl_func);
1626 RTW_PRINT("hw_stype:0x%x\n", hw_stype);
1627 RTW_PRINT("bw:0x%x\n", bw);
1628 RTW_PRINT("ant_num:0x%x\n", ant_num);
1629 RTW_PRINT("protocol:0x%x\n", protocol);
1630 RTW_PRINT("nic:0x%x\n", nic);
1631 }
1632
1633 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
1634 if (IS_8822C_SERIES(hal_data->version_id) || IS_8814B_SERIES(hal_data->version_id)) {
1635 #define GET_C2H_MAC_HIDDEN_RPT_SS_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)
1636 ss_num = GET_C2H_MAC_HIDDEN_RPT_SS_NUM(data);
1637
1638 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1639 RTW_PRINT("ss_num:0x%x\n", ss_num);
1640
1641 if (ss_num == 0x03)
1642 ss_num = 4;
1643 }
1644 #endif
1645
1646 #if defined(CONFIG_RTL8822C)
1647 if (IS_8822C_SERIES(hal_data->version_id)) {
1648 if (ant_num == 1)
1649 hal_spec->rf_reg_trx_path_bmp = 0x22; /* 1T1R pathB */
1650 if (hw_stype == 0xE)
1651 hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, 1); /* limit 1TX only */
1652 }
1653 #endif
1654 hal_data->PackageType = package_type;
1655 hal_spec->hci_type = hci_type;
1656 hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1657 hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1658 hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1659
1660 rf_type = rtw_chip_rftype_to_hal_rftype(adapter, 0);
1661 if (!RF_TYPE_VALID(rf_type)) {
1662 RTW_ERR("%s rtw_chip_rftype_to_hal_rftype failed\n", __func__);
1663 goto exit;
1664 }
1665 hal_spec->rf_reg_path_avail_num = rtw_min(hal_spec->rf_reg_path_num, ant_num);
1666 tx_path_num = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1667 rx_path_num = rtw_min(rf_type_to_rf_rx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1668 hal_spec->rf_reg_trx_path_bmp = rtw_restrict_trx_path_bmp_by_trx_num_lmt(
1669 hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num, &tx_path_num, &rx_path_num);
1670 if (!hal_spec->rf_reg_trx_path_bmp) {
1671 RTW_ERR("%s rtw_restrict_trx_path_bmp_by_trx_num_lmt(0x%x, %u, %u) failed\n"
1672 , __func__, hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num);
1673 goto exit;
1674 }
1675 hal_spec->rf_reg_path_avail_num = rtw_max(tx_path_num, rx_path_num);
1676
1677 /*
1678 * RF TX path num >= max_tx_cnt >= tx_nss_num
1679 * ex: RF TX path num(4) >= max_tx_cnt(2) >= tx_nss_num(1)
1680 * Select at most 2 out of 4 TX RF path to do 1SS 2TX
1681 */
1682 hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, tx_path_num);
1683 hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, hal_spec->max_tx_cnt);
1684 hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ss_num);
1685
1686 hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rx_path_num);
1687 hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ss_num);
1688
1689 ret = _SUCCESS;
1690
1691 exit:
1692 return ret;
1693 }
1694
c2h_mac_hidden_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1695 int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1696 {
1697 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1698 int ret = _FAIL;
1699
1700 int i;
1701
1702 if (len < MAC_HIDDEN_RPT_2_LEN) {
1703 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
1704 goto exit;
1705 }
1706
1707 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1708 for (i = 0; i < len; i++)
1709 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1710 }
1711
1712 #if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)
1713 if (IS_8188F(hal_data->version_id) || IS_8188GTV(hal_data->version_id)) {
1714 #define GET_C2H_MAC_HIDDEN_RPT_IRV(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
1715 u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
1716
1717 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1718 RTW_PRINT("irv:0x%x\n", irv);
1719
1720 if(irv != 0xf)
1721 hal_data->version_id.CUTVersion = irv;
1722 }
1723 #endif
1724
1725 ret = _SUCCESS;
1726
1727 exit:
1728 return ret;
1729 }
1730
hal_read_mac_hidden_rpt(_adapter * adapter)1731 int hal_read_mac_hidden_rpt(_adapter *adapter)
1732 {
1733 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
1734 int ret = _FAIL;
1735 int ret_fwdl;
1736 u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
1737 systime start = rtw_get_current_time();
1738 u32 cnt = 0;
1739 u32 timeout_ms = 800;
1740 u32 min_cnt = 10;
1741 u8 id = C2H_DEFEATURE_RSVD;
1742 int i;
1743
1744 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1745 u8 hci_type = rtw_get_intf_type(adapter);
1746
1747 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1748 && !rtw_is_hw_init_completed(adapter))
1749 rtw_hal_power_on(adapter);
1750 #endif
1751
1752 /* inform FW mac hidden rpt from reg is needed */
1753 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
1754
1755 /* download FW */
1756 pHalData->not_xmitframe_fw_dl = 1;
1757 ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1758 pHalData->not_xmitframe_fw_dl = 0;
1759 if (ret_fwdl != _SUCCESS)
1760 goto mac_hidden_rpt_hdl;
1761
1762 /* polling for data ready */
1763 start = rtw_get_current_time();
1764 do {
1765 cnt++;
1766 id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1767 if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1768 break;
1769 rtw_msleep_os(10);
1770 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1771
1772 if (id == C2H_MAC_HIDDEN_RPT) {
1773 /* read data */
1774 for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
1775 mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1776 }
1777
1778 /* inform FW mac hidden rpt has read */
1779 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
1780
1781 mac_hidden_rpt_hdl:
1782 c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1783 c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
1784
1785 if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1786 ret = _SUCCESS;
1787
1788 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1789 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1790 && !rtw_is_hw_init_completed(adapter))
1791 rtw_hal_power_off(adapter);
1792 #endif
1793
1794 RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1795 , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1796
1797 return ret;
1798 }
1799 #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
1800
c2h_defeature_dbg_hdl(_adapter * adapter,u8 * data,u8 len)1801 int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
1802 {
1803 int ret = _FAIL;
1804
1805 int i;
1806
1807 if (len < DEFEATURE_DBG_LEN) {
1808 RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
1809 goto exit;
1810 }
1811
1812 for (i = 0; i < len; i++)
1813 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1814
1815 ret = _SUCCESS;
1816
1817 exit:
1818 return ret;
1819 }
1820
1821 #ifndef DBG_CUSTOMER_STR_RPT_HANDLE
1822 #define DBG_CUSTOMER_STR_RPT_HANDLE 0
1823 #endif
1824
1825 #ifdef CONFIG_RTW_CUSTOMER_STR
rtw_hal_h2c_customer_str_req(_adapter * adapter)1826 s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
1827 {
1828 u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
1829
1830 SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
1831 return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
1832 }
1833
1834 #define C2H_CUSTOMER_STR_RPT_BYTE0(_data) ((u8 *)(_data))
1835 #define C2H_CUSTOMER_STR_RPT_2_BYTE8(_data) ((u8 *)(_data))
1836
c2h_customer_str_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1837 int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1838 {
1839 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1840 int ret = _FAIL;
1841 int i;
1842
1843 if (len < CUSTOMER_STR_RPT_LEN) {
1844 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
1845 goto exit;
1846 }
1847
1848 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1849 RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
1850
1851 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1852
1853 if (dvobj->customer_str_sctx != NULL) {
1854 if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
1855 RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
1856 _rtw_memcpy(dvobj->customer_str, C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
1857 dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
1858 } else
1859 RTW_WARN("%s sctx not set\n", __func__);
1860
1861 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1862
1863 ret = _SUCCESS;
1864
1865 exit:
1866 return ret;
1867 }
1868
c2h_customer_str_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1869 int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1870 {
1871 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1872 int ret = _FAIL;
1873 int i;
1874
1875 if (len < CUSTOMER_STR_RPT_2_LEN) {
1876 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
1877 goto exit;
1878 }
1879
1880 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1881 RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
1882
1883 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1884
1885 if (dvobj->customer_str_sctx != NULL) {
1886 if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
1887 RTW_WARN("%s rpt not ready\n", __func__);
1888 _rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN, C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
1889 rtw_sctx_done(&dvobj->customer_str_sctx);
1890 } else
1891 RTW_WARN("%s sctx not set\n", __func__);
1892
1893 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1894
1895 ret = _SUCCESS;
1896
1897 exit:
1898 return ret;
1899 }
1900
1901 /* read customer str */
rtw_hal_customer_str_read(_adapter * adapter,u8 * cs)1902 s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
1903 {
1904 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1905 struct submit_ctx sctx;
1906 s32 ret = _SUCCESS;
1907
1908 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1909 if (dvobj->customer_str_sctx != NULL)
1910 ret = _FAIL;
1911 else {
1912 rtw_sctx_init(&sctx, 2 * 1000);
1913 dvobj->customer_str_sctx = &sctx;
1914 }
1915 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1916
1917 if (ret == _FAIL) {
1918 RTW_WARN("%s another handle ongoing\n", __func__);
1919 goto exit;
1920 }
1921
1922 ret = rtw_customer_str_req_cmd(adapter);
1923 if (ret != _SUCCESS) {
1924 RTW_WARN("%s read cmd fail\n", __func__);
1925 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1926 dvobj->customer_str_sctx = NULL;
1927 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1928 goto exit;
1929 }
1930
1931 /* wait till rpt done or timeout */
1932 rtw_sctx_wait(&sctx, __func__);
1933
1934 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1935 dvobj->customer_str_sctx = NULL;
1936 if (sctx.status == RTW_SCTX_DONE_SUCCESS)
1937 _rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1938 else
1939 ret = _FAIL;
1940 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1941
1942 exit:
1943 return ret;
1944 }
1945
rtw_hal_h2c_customer_str_write(_adapter * adapter,const u8 * cs)1946 s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
1947 {
1948 u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
1949 u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
1950 u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
1951 s32 ret;
1952
1953 SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
1954 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
1955
1956 SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
1957 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
1958
1959 SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
1960 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
1961
1962 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
1963 if (ret != _SUCCESS) {
1964 RTW_WARN("%s w1 fail\n", __func__);
1965 goto exit;
1966 }
1967
1968 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
1969 if (ret != _SUCCESS) {
1970 RTW_WARN("%s w2 fail\n", __func__);
1971 goto exit;
1972 }
1973
1974 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
1975 if (ret != _SUCCESS) {
1976 RTW_WARN("%s w3 fail\n", __func__);
1977 goto exit;
1978 }
1979
1980 exit:
1981 return ret;
1982 }
1983
1984 /* write customer str and check if value reported is the same as requested */
rtw_hal_customer_str_write(_adapter * adapter,const u8 * cs)1985 s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
1986 {
1987 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1988 struct submit_ctx sctx;
1989 s32 ret = _SUCCESS;
1990
1991 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1992 if (dvobj->customer_str_sctx != NULL)
1993 ret = _FAIL;
1994 else {
1995 rtw_sctx_init(&sctx, 2 * 1000);
1996 dvobj->customer_str_sctx = &sctx;
1997 }
1998 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1999
2000 if (ret == _FAIL) {
2001 RTW_WARN("%s another handle ongoing\n", __func__);
2002 goto exit;
2003 }
2004
2005 ret = rtw_customer_str_write_cmd(adapter, cs);
2006 if (ret != _SUCCESS) {
2007 RTW_WARN("%s write cmd fail\n", __func__);
2008 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2009 dvobj->customer_str_sctx = NULL;
2010 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2011 goto exit;
2012 }
2013
2014 ret = rtw_customer_str_req_cmd(adapter);
2015 if (ret != _SUCCESS) {
2016 RTW_WARN("%s read cmd fail\n", __func__);
2017 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2018 dvobj->customer_str_sctx = NULL;
2019 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2020 goto exit;
2021 }
2022
2023 /* wait till rpt done or timeout */
2024 rtw_sctx_wait(&sctx, __func__);
2025
2026 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2027 dvobj->customer_str_sctx = NULL;
2028 if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
2029 if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
2030 RTW_WARN("%s read back check fail\n", __func__);
2031 RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
2032 RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
2033 ret = _FAIL;
2034 }
2035 } else
2036 ret = _FAIL;
2037 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2038
2039 exit:
2040 return ret;
2041 }
2042 #endif /* CONFIG_RTW_CUSTOMER_STR */
2043
2044 #ifdef RTW_PER_CMD_SUPPORT_FW
2045 #define H2C_REQ_PER_RPT_LEN 5
2046 #define SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value)
2047 #define SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value)
2048 #define SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(__pH2CCmd, __Value) SET_BITS_TO_LE_4BYTE(__pH2CCmd + 1, 0, 32, __Value)
2049
rtw_hal_set_req_per_rpt_cmd(_adapter * adapter,u8 group_macid,u8 rpt_type,u32 macid_bitmap)2050 u8 rtw_hal_set_req_per_rpt_cmd(_adapter *adapter, u8 group_macid,
2051 u8 rpt_type, u32 macid_bitmap)
2052 {
2053 u8 ret = _FAIL;
2054 u8 cmd_buf[H2C_REQ_PER_RPT_LEN] = {0};
2055
2056 SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(cmd_buf, group_macid);
2057 SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(cmd_buf, rpt_type);
2058 SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(cmd_buf, macid_bitmap);
2059
2060 ret = rtw_hal_fill_h2c_cmd(adapter,
2061 H2C_REQ_PER_RPT,
2062 H2C_REQ_PER_RPT_LEN,
2063 cmd_buf);
2064 return ret;
2065 }
2066
2067 #define GET_C2H_PER_RATE_RPT_TYPE0_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2068 #define GET_C2H_PER_RATE_RPT_TYPE0_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2069 #define GET_C2H_PER_RATE_RPT_TYPE0_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
2070 #define GET_C2H_PER_RATE_RPT_TYPE0_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
2071 #define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 4, 0, 16)
2072 #define GET_C2H_PER_RATE_RPT_TYPE0_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
2073 #define GET_C2H_PER_RATE_RPT_TYPE0_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 8)
2074 #define GET_C2H_PER_RATE_RPT_TYPE0_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
2075 #define GET_C2H_PER_RATE_RPT_TYPE0_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 2)
2076 #define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 10, 0, 16)
2077
2078 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2079 #define GET_C2H_PER_RATE_RPT_TYPE1_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2080 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
2081 #define GET_C2H_PER_RATE_RPT_TYPE1_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
2082 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 8)
2083 #define GET_C2H_PER_RATE_RPT_TYPE1_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 8)
2084 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
2085 #define GET_C2H_PER_RATE_RPT_TYPE1_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 2)
2086 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
2087 #define GET_C2H_PER_RATE_RPT_TYPE1_PER2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 8)
2088 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 10, 0, 8)
2089 #define GET_C2H_PER_RATE_RPT_TYPE1_BW2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 11, 0, 2)
2090
per_rate_rpt_update(_adapter * adapter,u8 mac_id,u8 per,u8 rate,u8 bw,u8 total_pkt)2091 static void per_rate_rpt_update(_adapter *adapter, u8 mac_id,
2092 u8 per, u8 rate,
2093 u8 bw, u8 total_pkt)
2094 {
2095 #ifdef CONFIG_RTW_MESH
2096 rtw_ieee80211s_update_metric(adapter, mac_id,
2097 per, rate,
2098 bw, total_pkt);
2099 #endif
2100 }
2101
c2h_per_rate_rpt_hdl(_adapter * adapter,u8 * data,u8 len)2102 int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
2103 {
2104 /* Now only consider type0, since it covers all params in type1
2105 * type0: mac_id, per, rate, bw, total_pkt
2106 * type1: mac_id, per, rate, bw
2107 */
2108 u8 mac_id[2] = {0}, per[2] = {0}, rate[2] = {0}, bw[2] = {0};
2109 u16 total_pkt[2] = {0};
2110 int ret = _FAIL, i, macid_cnt = 0;
2111
2112 /* type0:
2113 * 1 macid includes 6 bytes info + 1 byte 0xff
2114 * 2 macid includes 2*6 bytes info
2115 */
2116 if (!(len == 7 || len == 12)) {
2117 RTW_WARN("%s len(%u) != 7 or 12\n", __FUNCTION__, len);
2118 goto exit;
2119 }
2120
2121 macid_cnt++;
2122 mac_id[0] = GET_C2H_PER_RATE_RPT_TYPE0_MACID0(data);
2123 per[0] = GET_C2H_PER_RATE_RPT_TYPE0_PER0(data);
2124 rate[0] = GET_C2H_PER_RATE_RPT_TYPE0_RATE0(data);
2125 bw[0] = GET_C2H_PER_RATE_RPT_TYPE0_BW0(data);
2126 total_pkt[0] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(data);
2127
2128 mac_id[1] = GET_C2H_PER_RATE_RPT_TYPE0_MACID1(data);
2129 /* 0xff means no report anymore */
2130 if (mac_id[1] == 0xff)
2131 goto update_per;
2132 if (len != 12) {
2133 RTW_WARN("%s incorrect format\n", __FUNCTION__);
2134 goto exit;
2135 }
2136 macid_cnt++;
2137 per[1] = GET_C2H_PER_RATE_RPT_TYPE0_PER1(data);
2138 rate[1] = GET_C2H_PER_RATE_RPT_TYPE0_RATE1(data);
2139 bw[1] = GET_C2H_PER_RATE_RPT_TYPE0_BW1(data);
2140 total_pkt[1] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(data);
2141
2142 update_per:
2143 for (i = 0; i < macid_cnt; i++) {
2144 RTW_DBG("[%s] type0 rpt[%d]: macid = %u, per = %u, "
2145 "rate = %u, bw = %u, total_pkt = %u\n",
2146 __FUNCTION__, i, mac_id[i], per[i],
2147 rate[i], bw[i], total_pkt[i]);
2148 per_rate_rpt_update(adapter, mac_id[i],
2149 per[i], rate[i],
2150 bw[i], total_pkt[i]);
2151 }
2152 ret = _SUCCESS;
2153 exit:
2154 return ret;
2155 }
2156 #endif /* RTW_PER_CMD_SUPPORT_FW */
2157
2158 #ifdef CONFIG_LPS_ACK
2159 #define GET_C2H_LPS_STATUS_RPT_GET_ACTION(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2160 #define GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2161 #define DBG_LPS_STATUS_RPT 0
2162
c2h_lps_status_rpt(PADAPTER adapter,u8 * data,u8 len)2163 int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len)
2164 {
2165 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
2166 struct submit_ctx *lps_sctx = &pwrpriv->lps_ack_sctx;
2167 u8 action = 0;
2168 s8 status_code = 0;
2169 int ret = _FAIL;
2170
2171 if (len < LPS_STATUS_RPT_LEN) {
2172 RTW_WARN("%s len(%u) < %d\n", __func__, len, LPS_STATUS_RPT_LEN);
2173 goto exit;
2174 }
2175
2176 action = GET_C2H_LPS_STATUS_RPT_GET_ACTION(data);
2177 status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data);
2178
2179 /* action=0: report force leave null data status */
2180 /* action=1: report Rf on status when receiving a SetPwrMode H2C with PwrState = RFON */
2181 switch (action) {
2182 case 0:
2183 /* status code 0: success, 1: no ack, 2: timeout, 3: cancel */
2184 case 1:
2185 /* status code 0: FW has already turn to RFON */
2186 pwrpriv->lps_ack_status = status_code;
2187
2188 if (DBG_LPS_STATUS_RPT)
2189 RTW_INFO("=== [C2H LPS Action(%d)] LPS Status Code:%d ===\n", action, status_code);
2190
2191 break;
2192 default:
2193 RTW_INFO("UnKnown Action(%d) for C2H LPS RPT\n", action);
2194 break;
2195 }
2196
2197 rtw_sctx_done(&lps_sctx);
2198 ret = _SUCCESS;
2199
2200 exit:
2201 return ret;
2202 }
2203 #endif /* CONFIG_LPS_ACK */
2204
rtw_hal_update_sta_wset(_adapter * adapter,struct sta_info * psta)2205 void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
2206 {
2207 u8 w_set = 0;
2208
2209 if (psta->wireless_mode & WIRELESS_11B)
2210 w_set |= WIRELESS_CCK;
2211
2212 if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
2213 w_set |= WIRELESS_OFDM;
2214
2215 if (psta->wireless_mode & WIRELESS_11_24N)
2216 w_set |= WIRELESS_HT;
2217
2218 if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N))
2219 w_set |= WIRELESS_VHT;
2220
2221 psta->cmn.support_wireless_set = w_set;
2222 }
2223
rtw_hal_update_sta_mimo_type(_adapter * adapter,struct sta_info * psta)2224 void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
2225 {
2226 s8 tx_nss, rx_nss;
2227
2228 tx_nss = rtw_get_sta_tx_nss(adapter, psta);
2229 rx_nss = rtw_get_sta_rx_nss(adapter, psta);
2230 if ((tx_nss == 1) && (rx_nss == 1))
2231 psta->cmn.mimo_type = RF_1T1R;
2232 else if ((tx_nss == 1) && (rx_nss == 2))
2233 psta->cmn.mimo_type = RF_1T2R;
2234 else if ((tx_nss == 2) && (rx_nss == 2))
2235 psta->cmn.mimo_type = RF_2T2R;
2236 else if ((tx_nss == 2) && (rx_nss == 3))
2237 psta->cmn.mimo_type = RF_2T3R;
2238 else if ((tx_nss == 2) && (rx_nss == 4))
2239 psta->cmn.mimo_type = RF_2T4R;
2240 else if ((tx_nss == 3) && (rx_nss == 3))
2241 psta->cmn.mimo_type = RF_3T3R;
2242 else if ((tx_nss == 3) && (rx_nss == 4))
2243 psta->cmn.mimo_type = RF_3T4R;
2244 else if ((tx_nss == 4) && (rx_nss == 4))
2245 psta->cmn.mimo_type = RF_4T4R;
2246 else
2247 rtw_warn_on(1);
2248
2249 #ifdef CONFIG_CTRL_TXSS_BY_TP
2250 rtw_ctrl_txss_update_mimo_type(adapter, psta);
2251 #endif
2252
2253 RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
2254 psta->cmn.mac_id, tx_nss, rx_nss);
2255 }
2256
rtw_hal_update_sta_smps_cap(_adapter * adapter,struct sta_info * psta)2257 void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
2258 {
2259 /*Spatial Multiplexing Power Save*/
2260 #if 0
2261 if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2262 #ifdef CONFIG_80211N_HT
2263 if (psta->htpriv.ht_option) {
2264 if (psta->htpriv.smps_cap == 0)
2265 psta->cmn.sm_ps = SM_PS_STATIC;
2266 else if (psta->htpriv.smps_cap == 1)
2267 psta->cmn.sm_ps = SM_PS_DYNAMIC;
2268 else
2269 psta->cmn.sm_ps = SM_PS_DISABLE;
2270 }
2271 #endif /* CONFIG_80211N_HT */
2272 } else
2273 #endif
2274 psta->cmn.sm_ps = SM_PS_DISABLE;
2275
2276 RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
2277 psta->cmn.mac_id, psta->cmn.sm_ps);
2278 }
2279
rtw_get_mgntframe_raid(_adapter * adapter,unsigned char network_type)2280 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
2281 {
2282
2283 u8 raid;
2284 if (IS_NEW_GENERATION_IC(adapter)) {
2285
2286 raid = (network_type & WIRELESS_11B) ? RATEID_IDX_B
2287 : RATEID_IDX_G;
2288 } else {
2289 raid = (network_type & WIRELESS_11B) ? RATR_INX_WIRELESS_B
2290 : RATR_INX_WIRELESS_G;
2291 }
2292 return raid;
2293 }
2294
rtw_hal_update_sta_rate_mask(PADAPTER padapter,struct sta_info * psta)2295 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
2296 {
2297 u8 i, tx_nss;
2298 u64 tx_ra_bitmap = 0, tmp64=0;
2299
2300 if (psta == NULL)
2301 return;
2302
2303 /* b/g mode ra_bitmap */
2304 for (i = 0; i < sizeof(psta->bssrateset); i++) {
2305 if (psta->bssrateset[i])
2306 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
2307 }
2308
2309 #ifdef CONFIG_80211N_HT
2310 if (padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
2311 tx_nss = GET_HAL_TX_NSS(padapter);
2312 #ifdef CONFIG_80211AC_VHT
2313 if (psta->vhtpriv.vht_option) {
2314 /* AC mode ra_bitmap */
2315 tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
2316 } else
2317 #endif /* CONFIG_80211AC_VHT */
2318 if (psta->htpriv.ht_option) {
2319 /* n mode ra_bitmap */
2320
2321 /* Handling SMPS mode for AP MODE only*/
2322 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2323 /*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
2324 if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
2325 /*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
2326 tx_nss = rtw_min(tx_nss, 1);
2327 }
2328 }
2329
2330 tmp64 = rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss);
2331 tx_ra_bitmap |= (tmp64 << 12);
2332 }
2333 }
2334 #endif /* CONFIG_80211N_HT */
2335 psta->cmn.ra_info.ramask = tx_ra_bitmap;
2336 psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
2337 }
2338
rtw_hal_update_sta_ra_info(PADAPTER padapter,struct sta_info * psta)2339 void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
2340 {
2341 rtw_hal_update_sta_mimo_type(padapter, psta);
2342 rtw_hal_update_sta_smps_cap(padapter, psta);
2343 rtw_hal_update_sta_rate_mask(padapter, psta);
2344 }
2345
2346 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
hw_bcn_ctrl_addr(_adapter * adapter,u8 hw_port)2347 static u32 hw_bcn_ctrl_addr(_adapter *adapter, u8 hw_port)
2348 {
2349 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2350
2351 if (hw_port >= hal_spec->port_num) {
2352 RTW_ERR(FUNC_ADPT_FMT" HW Port(%d) invalid\n", FUNC_ADPT_ARG(adapter), hw_port);
2353 rtw_warn_on(1);
2354 return 0;
2355 }
2356
2357 switch (hw_port) {
2358 case HW_PORT0:
2359 return REG_BCN_CTRL;
2360 case HW_PORT1:
2361 return REG_BCN_CTRL_1;
2362 }
2363
2364 return 0;
2365 }
2366 #endif
2367
rtw_hal_get_msr(_adapter * adapter,u8 * net_type)2368 static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2369 {
2370 #ifdef RTW_HALMAC
2371 rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
2372 adapter->hw_port, net_type);
2373 #else /* !RTW_HALMAC */
2374 switch (adapter->hw_port) {
2375 case HW_PORT0:
2376 /*REG_CR - BIT[17:16]-Network Type for port 1*/
2377 *net_type = rtw_read8(adapter, MSR) & 0x03;
2378 break;
2379 case HW_PORT1:
2380 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2381 *net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2382 break;
2383 #if defined(CONFIG_RTL8814A)
2384 case HW_PORT2:
2385 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2386 *net_type = rtw_read8(adapter, MSR1) & 0x03;
2387 break;
2388 case HW_PORT3:
2389 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2390 *net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2391 break;
2392 case HW_PORT4:
2393 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2394 *net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2395 break;
2396 #endif /*#if defined(CONFIG_RTL8814A)*/
2397 default:
2398 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2399 ADPT_ARG(adapter), adapter->hw_port);
2400 rtw_warn_on(1);
2401 break;
2402 }
2403 #endif /* !RTW_HALMAC */
2404 }
2405
2406 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/
rtw_hal_net_type_decision(_adapter * adapter,u8 net_type)2407 static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
2408 {
2409 if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
2410 if (net_type != _HW_STATE_NOLINK_)
2411 return _HW_STATE_AP_;
2412 }
2413 return net_type;
2414 }
2415 #endif
rtw_hal_set_msr(_adapter * adapter,u8 net_type)2416 static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2417 {
2418 #ifdef RTW_HALMAC
2419 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2420 net_type = rtw_hal_net_type_decision(adapter, net_type);
2421 #endif
2422 rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
2423 adapter->hw_port, net_type);
2424 #else /* !RTW_HALMAC */
2425 u8 val8 = 0;
2426
2427 switch (adapter->hw_port) {
2428 case HW_PORT0:
2429 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2430 net_type = rtw_hal_net_type_decision(adapter, net_type);
2431 #endif
2432 /*REG_CR - BIT[17:16]-Network Type for port 0*/
2433 val8 = rtw_read8(adapter, MSR) & 0x0C;
2434 val8 |= net_type;
2435 rtw_write8(adapter, MSR, val8);
2436 break;
2437 case HW_PORT1:
2438 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2439 val8 = rtw_read8(adapter, MSR) & 0x03;
2440 val8 |= net_type << 2;
2441 rtw_write8(adapter, MSR, val8);
2442 break;
2443 #if defined(CONFIG_RTL8814A)
2444 case HW_PORT2:
2445 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2446 val8 = rtw_read8(adapter, MSR1) & 0xFC;
2447 val8 |= net_type;
2448 rtw_write8(adapter, MSR1, val8);
2449 break;
2450 case HW_PORT3:
2451 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2452 val8 = rtw_read8(adapter, MSR1) & 0xF3;
2453 val8 |= net_type << 2;
2454 rtw_write8(adapter, MSR1, val8);
2455 break;
2456 case HW_PORT4:
2457 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2458 val8 = rtw_read8(adapter, MSR1) & 0xCF;
2459 val8 |= net_type << 4;
2460 rtw_write8(adapter, MSR1, val8);
2461 break;
2462 #endif /* CONFIG_RTL8814A */
2463 default:
2464 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2465 ADPT_ARG(adapter), adapter->hw_port);
2466 rtw_warn_on(1);
2467 break;
2468 }
2469 #endif /* !RTW_HALMAC */
2470 }
2471
2472 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
2473 #define SEC_CAM_ACCESS_TIMEOUT_MS 200
2474 #endif
2475
2476 #ifndef DBG_SEC_CAM_ACCESS
2477 #define DBG_SEC_CAM_ACCESS 0
2478 #endif
2479
rtw_sec_read_cam(_adapter * adapter,u8 addr)2480 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
2481 {
2482 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2483 u32 rdata;
2484 u32 cnt = 0;
2485 systime start = 0, end = 0;
2486 u8 timeout = 0;
2487 u8 sr = 0;
2488
2489 _enter_critical_mutex(mutex, NULL);
2490
2491 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
2492
2493 start = rtw_get_current_time();
2494 while (1) {
2495 if (rtw_is_surprise_removed(adapter)) {
2496 sr = 1;
2497 break;
2498 }
2499
2500 cnt++;
2501 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2502 break;
2503
2504 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2505 timeout = 1;
2506 break;
2507 }
2508 }
2509 end = rtw_get_current_time();
2510
2511 rdata = rtw_read32(adapter, REG_CAMREAD);
2512
2513 _exit_critical_mutex(mutex, NULL);
2514
2515 if (DBG_SEC_CAM_ACCESS || timeout) {
2516 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
2517 , FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2518 }
2519
2520 return rdata;
2521 }
2522
rtw_sec_write_cam(_adapter * adapter,u8 addr,u32 wdata)2523 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
2524 {
2525 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2526 u32 cnt = 0;
2527 systime start = 0, end = 0;
2528 u8 timeout = 0;
2529 u8 sr = 0;
2530
2531 _enter_critical_mutex(mutex, NULL);
2532
2533 rtw_write32(adapter, REG_CAMWRITE, wdata);
2534 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
2535
2536 start = rtw_get_current_time();
2537 while (1) {
2538 if (rtw_is_surprise_removed(adapter)) {
2539 sr = 1;
2540 break;
2541 }
2542
2543 cnt++;
2544 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2545 break;
2546
2547 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2548 timeout = 1;
2549 break;
2550 }
2551 }
2552 end = rtw_get_current_time();
2553
2554 _exit_critical_mutex(mutex, NULL);
2555
2556 if (DBG_SEC_CAM_ACCESS || timeout) {
2557 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
2558 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2559 }
2560 }
2561
rtw_sec_read_cam_ent(_adapter * adapter,u8 id,u8 * ctrl,u8 * mac,u8 * key)2562 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
2563 {
2564 u8 i;
2565 u32 rdata;
2566 u8 begin = 0;
2567 u8 end = 5; /* TODO: consider other key length accordingly */
2568
2569 if (!ctrl && !mac && !key) {
2570 rtw_warn_on(1);
2571 goto exit;
2572 }
2573
2574 /* TODO: check id range */
2575
2576 if (!ctrl && !mac)
2577 begin = 2; /* read from key */
2578
2579 if (!key && !mac)
2580 end = 0; /* read to ctrl */
2581 else if (!key)
2582 end = 2; /* read to mac */
2583
2584 for (i = begin; i <= end; i++) {
2585 rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
2586
2587 switch (i) {
2588 case 0:
2589 if (ctrl)
2590 _rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
2591 if (mac)
2592 _rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
2593 break;
2594 case 1:
2595 if (mac)
2596 _rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
2597 break;
2598 default:
2599 if (key)
2600 _rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
2601 break;
2602 }
2603 }
2604
2605 exit:
2606 return;
2607 }
2608
2609
rtw_sec_write_cam_ent(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)2610 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
2611 {
2612 unsigned int i;
2613 int j;
2614 u8 addr, addr1 = 0;
2615 u32 wdata, wdata1 = 0;
2616
2617 /* TODO: consider other key length accordingly */
2618 #if 0
2619 switch ((ctrl & 0x1c) >> 2) {
2620 case _WEP40_:
2621 case _TKIP_:
2622 case _AES_:
2623 case _WEP104_:
2624
2625 }
2626 #else
2627 j = 7;
2628 #endif
2629
2630 for (; j >= 0; j--) {
2631 switch (j) {
2632 case 0:
2633 wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
2634 break;
2635 case 1:
2636 wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
2637 break;
2638 case 6:
2639 case 7:
2640 wdata = 0;
2641 break;
2642 default:
2643 i = (j - 2) << 2;
2644 wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
2645 break;
2646 }
2647
2648 addr = (id << 3) + j;
2649
2650 #if defined(CONFIG_RTL8192F)
2651 if(j == 1) {
2652 wdata1 = wdata;
2653 addr1 = addr;
2654 continue;
2655 }
2656 #endif
2657
2658 rtw_sec_write_cam(adapter, addr, wdata);
2659 }
2660
2661 #if defined(CONFIG_RTL8192F)
2662 rtw_sec_write_cam(adapter, addr1, wdata1);
2663 #endif
2664 }
2665
rtw_sec_clr_cam_ent(_adapter * adapter,u8 id)2666 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
2667 {
2668 u8 addr;
2669
2670 addr = (id << 3);
2671 rtw_sec_write_cam(adapter, addr, 0);
2672 }
2673
rtw_sec_read_cam_is_gk(_adapter * adapter,u8 id)2674 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
2675 {
2676 bool res;
2677 u16 ctrl;
2678
2679 rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
2680
2681 res = (ctrl & BIT6) ? _TRUE : _FALSE;
2682 return res;
2683 }
2684 #ifdef CONFIG_MBSSID_CAM
rtw_mbid_cam_init(struct dvobj_priv * dvobj)2685 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
2686 {
2687 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2688
2689 _rtw_spinlock_init(&mbid_cam_ctl->lock);
2690 mbid_cam_ctl->bitmap = 0;
2691 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2692 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2693 }
2694
rtw_mbid_cam_deinit(struct dvobj_priv * dvobj)2695 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
2696 {
2697 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2698
2699 _rtw_spinlock_free(&mbid_cam_ctl->lock);
2700 }
2701
rtw_mbid_cam_reset(_adapter * adapter)2702 void rtw_mbid_cam_reset(_adapter *adapter)
2703 {
2704 _irqL irqL;
2705 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2706 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2707
2708 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2709 mbid_cam_ctl->bitmap = 0;
2710 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2711 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2712
2713 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2714 }
_rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2715 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2716 {
2717 u8 i;
2718 u8 cam_id = INVALID_CAM_ID;
2719 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2720
2721 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2722 if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
2723 cam_id = i;
2724 break;
2725 }
2726 }
2727
2728 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2729 return cam_id;
2730 }
2731
rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2732 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2733 {
2734 _irqL irqL;
2735
2736 u8 cam_id = INVALID_CAM_ID;
2737 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2738 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2739
2740 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2741 cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
2742 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2743
2744 return cam_id;
2745 }
_rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2746 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2747 {
2748 u8 i;
2749 u8 cam_id = INVALID_CAM_ID;
2750 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2751
2752 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2753 if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
2754 cam_id = i;
2755 break;
2756 }
2757 }
2758 if (cam_id != INVALID_CAM_ID)
2759 RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
2760 __func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
2761
2762 return cam_id;
2763 }
2764
rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2765 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2766 {
2767 _irqL irqL;
2768 u8 cam_id = INVALID_CAM_ID;
2769 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2770 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2771
2772 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2773 cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
2774 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2775
2776 return cam_id;
2777 }
rtw_get_max_mbid_cam_id(_adapter * adapter)2778 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
2779 {
2780 _irqL irqL;
2781 s8 i;
2782 u8 cam_id = INVALID_CAM_ID;
2783 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2784 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2785
2786 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2787 for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
2788 if (mbid_cam_ctl->bitmap & BIT(i)) {
2789 cam_id = i;
2790 break;
2791 }
2792 }
2793 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2794 /*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
2795 return cam_id;
2796 }
2797
rtw_get_mbid_cam_entry_num(_adapter * adapter)2798 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
2799 {
2800 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2801 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2802
2803 return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2804 }
2805
mbid_cam_cache_init(_adapter * adapter,struct mbid_cam_cache * pmbid_cam,u8 * mac_addr)2806 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
2807 {
2808 if (adapter && pmbid_cam && mac_addr) {
2809 _rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
2810 pmbid_cam->iface_id = adapter->iface_id;
2811 }
2812 }
mbid_cam_cache_clr(struct mbid_cam_cache * pmbid_cam)2813 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
2814 {
2815 if (pmbid_cam) {
2816 _rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
2817 pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
2818 }
2819 }
2820
rtw_mbid_camid_alloc(_adapter * adapter,u8 * mac_addr)2821 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
2822 {
2823 _irqL irqL;
2824 u8 cam_id = INVALID_CAM_ID, i;
2825 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2826 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2827 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2828
2829 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2830 goto exit;
2831
2832 if (entry_num >= TOTAL_MBID_CAM_NUM) {
2833 RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
2834 rtw_warn_on(1);
2835 }
2836
2837 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2838 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2839 if (!(mbid_cam_ctl->bitmap & BIT(i))) {
2840 mbid_cam_ctl->bitmap |= BIT(i);
2841 cam_id = i;
2842 break;
2843 }
2844 }
2845 if ((cam_id != INVALID_CAM_ID) && (mac_addr))
2846 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
2847 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2848
2849 if (cam_id != INVALID_CAM_ID) {
2850 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2851 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2852 #ifdef DBG_MBID_CAM_DUMP
2853 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2854 #endif
2855 } else
2856 RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2857 exit:
2858 return cam_id;
2859 }
2860
rtw_mbid_cam_info_change(_adapter * adapter,u8 * mac_addr)2861 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
2862 {
2863 _irqL irqL;
2864 u8 entry_id = INVALID_CAM_ID;
2865 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2866 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2867
2868 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2869 entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
2870 if (entry_id != INVALID_CAM_ID)
2871 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
2872
2873 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2874
2875 return entry_id;
2876 }
2877
rtw_mbid_cam_assign(_adapter * adapter,u8 * mac_addr,u8 camid)2878 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
2879 {
2880 _irqL irqL;
2881 u8 ret = _FALSE;
2882 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2883 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2884
2885 if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
2886 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
2887 rtw_warn_on(1);
2888 }
2889 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2890 goto exit;
2891
2892 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2893 if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
2894 if (mac_addr) {
2895 mbid_cam_ctl->bitmap |= BIT(camid);
2896 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
2897 ret = _TRUE;
2898 }
2899 }
2900 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2901
2902 if (ret == _TRUE) {
2903 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2904 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
2905 #ifdef DBG_MBID_CAM_DUMP
2906 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2907 #endif
2908 } else
2909 RTW_INFO("%s [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
2910
2911 exit:
2912 return ret;
2913 }
2914
rtw_mbid_camid_clean(_adapter * adapter,u8 mbss_canid)2915 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
2916 {
2917 _irqL irqL;
2918 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2919 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2920
2921 if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
2922 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
2923 rtw_warn_on(1);
2924 }
2925 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2926 mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
2927 mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
2928 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2929 ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
2930 RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
2931 }
rtw_mbid_cam_cache_dump(void * sel,const char * fun_name,_adapter * adapter)2932 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
2933 {
2934 _irqL irqL;
2935 u8 i;
2936 _adapter *iface;
2937 u8 iface_id;
2938 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2939 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2940 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2941 u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2942
2943 RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
2944
2945 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2946 RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
2947 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2948 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2949
2950 if (mbid_cam_ctl->bitmap & BIT(i)) {
2951 iface_id = dvobj->mbid_cam_cache[i].iface_id;
2952 _RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
2953 _RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2954
2955 iface = dvobj->padapters[iface_id];
2956 if (iface) {
2957 if (MLME_IS_STA(iface))
2958 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
2959 else if (MLME_IS_AP(iface))
2960 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
2961 else if (MLME_IS_MESH(iface))
2962 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");
2963 else
2964 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2965 }
2966
2967 } else
2968 _RTW_PRINT_SEL(sel, "N/A\n");
2969 }
2970 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2971 return 0;
2972 }
2973
read_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2974 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2975 {
2976 u8 poll = 1;
2977 u8 cam_ready = _FALSE;
2978 u32 cam_data1 = 0;
2979 u16 cam_data2 = 0;
2980
2981 if (RTW_CANNOT_RUN(padapter))
2982 return;
2983
2984 rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2985
2986 do {
2987 if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2988 cam_ready = _TRUE;
2989 break;
2990 }
2991 poll++;
2992 } while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2993
2994 if (cam_ready) {
2995 cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2996 mac[0] = cam_data1 & 0xFF;
2997 mac[1] = (cam_data1 >> 8) & 0xFF;
2998 mac[2] = (cam_data1 >> 16) & 0xFF;
2999 mac[3] = (cam_data1 >> 24) & 0xFF;
3000
3001 cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
3002 mac[4] = cam_data2 & 0xFF;
3003 mac[5] = (cam_data2 >> 8) & 0xFF;
3004 }
3005
3006 }
rtw_mbid_cam_dump(void * sel,const char * fun_name,_adapter * adapter)3007 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
3008 {
3009 /*_irqL irqL;*/
3010 u8 i;
3011 u8 mac_addr[ETH_ALEN];
3012
3013 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3014 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
3015
3016 RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
3017
3018 /*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
3019 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
3020 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
3021 _rtw_memset(mac_addr, 0, ETH_ALEN);
3022 read_mbssid_cam(adapter, i, mac_addr);
3023 _RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
3024 }
3025 /*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
3026 return 0;
3027 }
3028
write_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)3029 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
3030 {
3031 u32 cam_val[2] = {0};
3032
3033 cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
3034 cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT) | (mac[5] << 8) | mac[4];
3035
3036 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
3037 }
3038
3039 /*
3040 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
3041 {
3042 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
3043 }
3044 */
3045
rtw_ap_set_mbid_num(_adapter * adapter,u8 ap_num)3046 void rtw_ap_set_mbid_num(_adapter *adapter, u8 ap_num)
3047 {
3048 rtw_write8(adapter, REG_MBID_NUM,
3049 ((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | ((ap_num -1) & 0x07)));
3050
3051 }
rtw_mbid_cam_enable(_adapter * adapter)3052 void rtw_mbid_cam_enable(_adapter *adapter)
3053 {
3054 /*enable MBSSID*/
3055 rtw_hal_rcr_add(adapter, RCR_ENMBID);
3056 }
rtw_mi_set_mbid_cam(_adapter * adapter)3057 void rtw_mi_set_mbid_cam(_adapter *adapter)
3058 {
3059 u8 i;
3060 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3061 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
3062
3063 #ifdef DBG_MBID_CAM_DUMP
3064 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
3065 #endif
3066
3067 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
3068 if (mbid_cam_ctl->bitmap & BIT(i)) {
3069 write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
3070 RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
3071 }
3072 }
3073 rtw_mbid_cam_enable(adapter);
3074 }
3075 #endif /*CONFIG_MBSSID_CAM*/
3076
3077 #ifdef CONFIG_FW_HANDLE_TXBCN
3078 #define H2C_BCN_OFFLOAD_LEN 1
3079
3080 #define SET_H2CCMD_BCN_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
3081 #define SET_H2CCMD_BCN_ROOT_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
3082 #define SET_H2CCMD_BCN_VAP1_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)
3083 #define SET_H2CCMD_BCN_VAP2_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)
3084 #define SET_H2CCMD_BCN_VAP3_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value)
3085 #define SET_H2CCMD_BCN_VAP4_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value)
3086
rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter * adapter,bool fw_bcn_en,u8 tbtt_rpt_map)3087 void rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter *adapter, bool fw_bcn_en, u8 tbtt_rpt_map)
3088 {
3089 u8 fw_bcn_offload[1] = {0};
3090 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3091
3092 if (fw_bcn_en)
3093 SET_H2CCMD_BCN_OFFLOAD_EN(fw_bcn_offload, 1);
3094
3095 if (tbtt_rpt_map & BIT(0))
3096 SET_H2CCMD_BCN_ROOT_TBTT_RPT(fw_bcn_offload, 1);
3097 if (tbtt_rpt_map & BIT(1))
3098 SET_H2CCMD_BCN_VAP1_TBTT_RPT(fw_bcn_offload, 1);
3099 if (tbtt_rpt_map & BIT(2))
3100 SET_H2CCMD_BCN_VAP2_TBTT_RPT(fw_bcn_offload, 1);
3101 if (tbtt_rpt_map & BIT(3))
3102 SET_H2CCMD_BCN_VAP3_TBTT_RPT(fw_bcn_offload, 1);
3103
3104 dvobj->vap_tbtt_rpt_map = tbtt_rpt_map;
3105 dvobj->fw_bcn_offload = fw_bcn_en;
3106 RTW_INFO("[FW BCN] Offload : %s\n", (dvobj->fw_bcn_offload) ? "EN" : "DIS");
3107 RTW_INFO("[FW BCN] TBTT RPT map : 0x%02x\n", dvobj->vap_tbtt_rpt_map);
3108
3109 rtw_hal_fill_h2c_cmd(adapter, H2C_FW_BCN_OFFLOAD,
3110 H2C_BCN_OFFLOAD_LEN, fw_bcn_offload);
3111 }
3112
rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter * adapter)3113 void rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter *adapter)
3114 {
3115 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3116 u8 ret, vap_id;
3117 u32 page_size = 0;
3118 u8 bcn_rsvdpage[H2C_BCN_RSVDPAGE_LEN] = {0};
3119
3120 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
3121 #if 1
3122 for (vap_id = 0; vap_id < CONFIG_LIMITED_AP_NUM; vap_id++) {
3123 if (dvobj->vap_map & BIT(vap_id))
3124 bcn_rsvdpage[vap_id] = vap_id * (MAX_BEACON_LEN / page_size);
3125 }
3126 #else
3127 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)
3128 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 8, __Value)
3129 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 8, __Value)
3130 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 8, __Value)
3131 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 8, __Value)
3132
3133 if (dvobj->vap_map & BIT(0))
3134 SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(bcn_rsvdpage, 0);
3135 if (dvobj->vap_map & BIT(1))
3136 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(bcn_rsvdpage,
3137 1 * (MAX_BEACON_LEN / page_size));
3138 if (dvobj->vap_map & BIT(2))
3139 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(bcn_rsvdpage,
3140 2 * (MAX_BEACON_LEN / page_size));
3141 if (dvobj->vap_map & BIT(3))
3142 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(bcn_rsvdpage,
3143 3 * (MAX_BEACON_LEN / page_size));
3144 if (dvobj->vap_map & BIT(4))
3145 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(bcn_rsvdpage,
3146 4 * (MAX_BEACON_LEN / page_size));
3147 #endif
3148 if (1) {
3149 RTW_INFO("[BCN_LOC] vap_map : 0x%02x\n", dvobj->vap_map);
3150 RTW_INFO("[BCN_LOC] page_size :%d, @bcn_page_num :%d\n"
3151 , page_size, (MAX_BEACON_LEN / page_size));
3152 RTW_INFO("[BCN_LOC] root ap : 0x%02x\n", *bcn_rsvdpage);
3153 RTW_INFO("[BCN_LOC] vap_1 : 0x%02x\n", *(bcn_rsvdpage + 1));
3154 RTW_INFO("[BCN_LOC] vap_2 : 0x%02x\n", *(bcn_rsvdpage + 2));
3155 RTW_INFO("[BCN_LOC] vap_3 : 0x%02x\n", *(bcn_rsvdpage + 3));
3156 RTW_INFO("[BCN_LOC] vap_4 : 0x%02x\n", *(bcn_rsvdpage + 4));
3157 }
3158 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE,
3159 H2C_BCN_RSVDPAGE_LEN, bcn_rsvdpage);
3160 }
3161
rtw_ap_multi_bcn_cfg(_adapter * adapter)3162 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3163 {
3164 u8 dft_bcn_space = DEFAULT_BCN_INTERVAL;
3165 u8 sub_bcn_space = (DEFAULT_BCN_INTERVAL / CONFIG_LIMITED_AP_NUM);
3166
3167 /*enable to rx data frame*/
3168 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3169
3170 /*Disable Port0's beacon function*/
3171 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
3172 /*Reset Port0's TSF*/
3173 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT_TSFTR_RST);
3174
3175 rtw_ap_set_mbid_num(adapter, CONFIG_LIMITED_AP_NUM);
3176
3177 /*BCN space & BCN sub-space 0x554[15:0] = 0x64,0x5BC[23:16] = 0x21*/
3178 rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), HW_PORT0, dft_bcn_space);
3179 rtw_write8(adapter, REG_MBSSID_BCN_SPACE3 + 2, sub_bcn_space);
3180
3181 #if 0 /*setting in hw_var_set_opmode_mbid - ResumeTxBeacon*/
3182 /*BCN hold time 0x540[19:8] = 0x80*/
3183 rtw_write8(adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
3184 rtw_write8(adapter, REG_TBTT_PROHIBIT + 2,
3185 (rtw_read8(adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
3186 #endif
3187
3188 /*ATIM window -0x55A = 0x32, reg 0x570 = 0x32, reg 0x5A0 = 0x32 */
3189 rtw_write8(adapter, REG_ATIMWND, 0x32);
3190 rtw_write8(adapter, REG_ATIMWND1_V1, 0x32);
3191 rtw_write8(adapter, REG_ATIMWND2, 0x32);
3192 rtw_write8(adapter, REG_ATIMWND3, 0x32);
3193 /*
3194 rtw_write8(adapter, REG_ATIMWND4, 0x32);
3195 rtw_write8(adapter, REG_ATIMWND5, 0x32);
3196 rtw_write8(adapter, REG_ATIMWND6, 0x32);
3197 rtw_write8(adapter, REG_ATIMWND7, 0x32);*/
3198
3199 /*no limit setting - 0x5A7 = 0xFF - Packet in Hi Queue Tx immediately*/
3200 rtw_write8(adapter, REG_HIQ_NO_LMT_EN, 0xFF);
3201
3202 /*Mask all beacon*/
3203 rtw_write8(adapter, REG_MBSSID_CTRL, 0);
3204
3205 /*BCN invalid bit setting 0x454[6] = 1*/
3206 /*rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);*/
3207
3208 /*Enable Port0's beacon function*/
3209 rtw_write8(adapter, REG_BCN_CTRL,
3210 rtw_read8(adapter, REG_BCN_CTRL) | BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION);
3211
3212 /* Enable HW seq for BCN
3213 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
3214 #ifdef CONFIG_RTL8822B
3215 if (IS_HARDWARE_TYPE_8822B(adapter))
3216 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3217 #endif
3218
3219 #ifdef CONFIG_RTL8822C
3220 if (IS_HARDWARE_TYPE_8822C(adapter))
3221 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3222 #endif
3223 }
_rtw_mbid_bcn_cfg(_adapter * adapter,bool mbcnq_en,u8 mbcnq_id)3224 static void _rtw_mbid_bcn_cfg(_adapter *adapter, bool mbcnq_en, u8 mbcnq_id)
3225 {
3226 if (mbcnq_id >= CONFIG_LIMITED_AP_NUM) {
3227 RTW_ERR(FUNC_ADPT_FMT"- mbid bcnq_id(%d) invalid\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3228 rtw_warn_on(1);
3229 }
3230
3231 if (mbcnq_en) {
3232 rtw_write8(adapter, REG_MBSSID_CTRL,
3233 rtw_read8(adapter, REG_MBSSID_CTRL) | BIT(mbcnq_id));
3234 RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) enabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3235 } else {
3236 rtw_write8(adapter, REG_MBSSID_CTRL,
3237 rtw_read8(adapter, REG_MBSSID_CTRL) & (~BIT(mbcnq_id)));
3238 RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) disabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3239 }
3240 }
3241 /*#define CONFIG_FW_TBTT_RPT*/
rtw_ap_mbid_bcn_en(_adapter * adapter,u8 ap_id)3242 void rtw_ap_mbid_bcn_en(_adapter *adapter, u8 ap_id)
3243 {
3244 RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3245
3246 #ifdef CONFIG_FW_TBTT_RPT
3247 if (rtw_ap_get_nums(adapter) >= 1) {
3248 u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3249
3250 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3251 tbtt_rpt_map | BIT(ap_id));/*H2C-0xBA*/
3252 }
3253 #else
3254 if (rtw_ap_get_nums(adapter) == 1)
3255 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE, 0);/*H2C-0xBA*/
3256 #endif
3257
3258 rtw_hal_set_bcn_rsvdpage_loc_cmd(adapter);/*H2C-0x09*/
3259
3260 _rtw_mbid_bcn_cfg(adapter, _TRUE, ap_id);
3261 }
rtw_ap_mbid_bcn_dis(_adapter * adapter,u8 ap_id)3262 void rtw_ap_mbid_bcn_dis(_adapter *adapter, u8 ap_id)
3263 {
3264 RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3265 _rtw_mbid_bcn_cfg(adapter, _FALSE, ap_id);
3266
3267 if (rtw_ap_get_nums(adapter) == 0)
3268 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _FALSE, 0);
3269 #ifdef CONFIG_FW_TBTT_RPT
3270 else if (rtw_ap_get_nums(adapter) >= 1) {
3271 u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3272
3273 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3274 tbtt_rpt_map & ~BIT(ap_id));/*H2C-0xBA*/
3275 }
3276 #endif
3277 }
3278 #endif
3279 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_ap_multi_bcn_cfg(_adapter * adapter)3280 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3281 {
3282 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3283 rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT);
3284 #else
3285 rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
3286 #endif
3287 /*enable to rx data frame*/
3288 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3289
3290 /*Beacon Control related register for first time*/
3291 rtw_write8(adapter, REG_BCNDMATIM, 0x02); /* 2ms */
3292
3293 /*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
3294 rtw_write8(adapter, REG_ATIMWND, 0x0c); /* 12ms */
3295
3296 #ifndef CONFIG_HW_P0_TSF_SYNC
3297 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3298 #endif
3299
3300 /*reset TSF*/
3301 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
3302
3303 /*enable BCN0 Function for if1*/
3304 /*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
3305 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3306 rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);
3307 #else
3308 rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3309 #endif
3310 #ifdef CONFIG_BCN_XMIT_PROTECT
3311 rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
3312 #endif
3313
3314 if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/
3315 rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
3316
3317 /* Enable HW seq for BCN
3318 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
3319 #ifdef CONFIG_RTL8822B
3320 if (IS_HARDWARE_TYPE_8822B(adapter))
3321 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3322 #endif
3323
3324 #ifdef CONFIG_RTL8822C
3325 if (IS_HARDWARE_TYPE_8822C(adapter))
3326 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3327 #endif
3328 }
3329 #endif
3330
3331 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3332 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3333 {
3334
3335 #if 0 /*TODO - modify for more flexible*/
3336 u8 idx = 0;
3337
3338 if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
3339 (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
3340 for (idx = 0; idx < 6; idx++)
3341 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
3342 } else {
3343 /*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
3344 u8 entry_id;
3345
3346 if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
3347 (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
3348 entry_id = 0;
3349 if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
3350 RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
3351 write_mbssid_cam(adapter, entry_id, val);
3352 }
3353 } else {
3354 entry_id = rtw_mbid_camid_alloc(adapter, val);
3355 if (entry_id != INVALID_CAM_ID)
3356 write_mbssid_cam(adapter, entry_id, val);
3357 }
3358 }
3359 #else
3360 {
3361 /*
3362 MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
3363 */
3364 u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
3365
3366
3367 if (entry_id != INVALID_CAM_ID) {
3368 write_mbssid_cam(adapter, entry_id, mac_addr);
3369 RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,
3370 ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));
3371 }
3372 }
3373 #endif
3374 }
3375
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3376 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3377 {
3378 u8 idx = 0;
3379 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3380 u8 entry_id;
3381
3382 if (!mac_addr) {
3383 rtw_warn_on(1);
3384 return;
3385 }
3386
3387
3388 entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
3389
3390 if (entry_id != INVALID_CAM_ID)
3391 write_mbssid_cam(adapter, entry_id, mac_addr);
3392 }
3393
3394 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_hal_bcn_interval_adjust(_adapter * adapter,u16 bcn_interval)3395 u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
3396 {
3397 if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
3398 return adapter_to_dvobj(adapter)->inter_bcn_space;
3399 else
3400 return bcn_interval;
3401 }
3402 #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
3403
3404 #else
3405
3406 #ifndef RTW_HALMAC
_get_macaddr_reg(enum _hw_port hwport)3407 static u32 _get_macaddr_reg(enum _hw_port hwport)
3408 {
3409 u32 reg_macaddr = REG_MACID;
3410
3411 #ifdef CONFIG_CONCURRENT_MODE
3412 if (hwport == HW_PORT1)
3413 reg_macaddr = REG_MACID1;
3414 #if defined(CONFIG_RTL8814A)
3415 else if (hwport == HW_PORT2)
3416 reg_macaddr = REG_MACID2;
3417 else if (hwport == HW_PORT3)
3418 reg_macaddr = REG_MACID3;
3419 else if (hwport == HW_PORT4)
3420 reg_macaddr = REG_MACID4;
3421 #endif /*CONFIG_RTL8814A*/
3422 #endif /*CONFIG_CONCURRENT_MODE*/
3423
3424 return reg_macaddr;
3425 }
3426 #endif /*!RTW_HALMAC*/
3427
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * mac_addr)3428 static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr)
3429 {
3430 enum _hw_port hwport;
3431
3432 if (mac_addr == NULL)
3433 return;
3434 hwport = get_hw_port(adapter);
3435
3436 RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3437 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3438
3439 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3440 rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3441 #else /* !RTW_HALMAC */
3442 {
3443 u8 idx = 0;
3444 u32 reg_macaddr = _get_macaddr_reg(hwport);
3445
3446 for (idx = 0; idx < ETH_ALEN; idx++)
3447 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx), mac_addr[idx]);
3448 }
3449 #endif /* !RTW_HALMAC */
3450 }
3451
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)3452 static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
3453 {
3454 enum _hw_port hwport;
3455
3456 if (mac_addr == NULL)
3457 return;
3458 hwport = get_hw_port(adapter);
3459
3460 _rtw_memset(mac_addr, 0, ETH_ALEN);
3461 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3462 rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3463 #else /* !RTW_HALMAC */
3464 {
3465 u8 idx = 0;
3466 u32 reg_macaddr = _get_macaddr_reg(hwport);
3467
3468 for (idx = 0; idx < ETH_ALEN; idx++)
3469 mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx));
3470 }
3471 #endif /* !RTW_HALMAC */
3472
3473 RTW_DBG("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3474 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3475 }
3476 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
3477
3478 #ifndef RTW_HALMAC
_get_bssid_reg(enum _hw_port hw_port)3479 static u32 _get_bssid_reg(enum _hw_port hw_port)
3480 {
3481 u32 reg_bssid = REG_BSSID;
3482
3483 #ifdef CONFIG_CONCURRENT_MODE
3484 if (hw_port == HW_PORT1)
3485 reg_bssid = REG_BSSID1;
3486 #if defined(CONFIG_RTL8814A)
3487 else if (hw_port == HW_PORT2)
3488 reg_bssid = REG_BSSID2;
3489 else if (hw_port == HW_PORT3)
3490 reg_bssid = REG_BSSID3;
3491 else if (hw_port == HW_PORT4)
3492 reg_bssid = REG_BSSID4;
3493 #endif /*CONFIG_RTL8814A*/
3494 #endif /*CONFIG_CONCURRENT_MODE*/
3495
3496 return reg_bssid;
3497 }
3498 #endif /*!RTW_HALMAC*/
rtw_hal_set_bssid(_adapter * adapter,u8 * val)3499 static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
3500 {
3501 enum _hw_port hw_port = rtw_hal_get_port(adapter);
3502 #ifdef RTW_HALMAC
3503
3504 rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);
3505 #else /* !RTW_HALMAC */
3506 u8 idx = 0;
3507 u32 reg_bssid = _get_bssid_reg(hw_port);
3508
3509 for (idx = 0 ; idx < ETH_ALEN; idx++)
3510 rtw_write8(adapter, (reg_bssid + idx), val[idx]);
3511 #endif /* !RTW_HALMAC */
3512
3513 RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",
3514 __func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));
3515 }
3516
3517 #ifndef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_tsf_update(_adapter * adapter,u8 en)3518 static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)
3519 {
3520 u32 addr = 0;
3521 u8 val8;
3522
3523 rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);
3524 if (addr) {
3525 rtw_enter_protsel_port(adapter, get_hw_port(adapter));
3526 val8 = rtw_read8(adapter, addr);
3527 if (en && (val8 & DIS_TSF_UDT)) {
3528 rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);
3529 #ifdef DBG_TSF_UPDATE
3530 RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3531 #endif
3532 }
3533 if (!en && !(val8 & DIS_TSF_UDT)) {
3534 rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);
3535 #ifdef DBG_TSF_UPDATE
3536 RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3537 #endif
3538 }
3539 rtw_leave_protsel_port(adapter);
3540 } else {
3541 RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"
3542 , adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");
3543 rtw_warn_on(1);
3544 }
3545 }
3546 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_set_hw_update_tsf(PADAPTER padapter)3547 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
3548 {
3549 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3550
3551 #else
3552 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3553
3554 if (!pmlmeext->en_hw_update_tsf)
3555 return;
3556
3557 /* check RCR */
3558 if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
3559 return;
3560
3561 if (pmlmeext->tsf_update_required) {
3562 pmlmeext->tsf_update_pause_stime = 0;
3563 rtw_hal_set_tsf_update(padapter, 1);
3564 }
3565
3566 pmlmeext->en_hw_update_tsf = 0;
3567 #endif
3568 }
3569
rtw_iface_enable_tsf_update(_adapter * adapter)3570 void rtw_iface_enable_tsf_update(_adapter *adapter)
3571 {
3572 adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3573 adapter->mlmeextpriv.tsf_update_required = 1;
3574 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3575
3576 #else
3577 rtw_hal_set_tsf_update(adapter, 1);
3578 #endif
3579 }
3580
rtw_iface_disable_tsf_update(_adapter * adapter)3581 void rtw_iface_disable_tsf_update(_adapter *adapter)
3582 {
3583 adapter->mlmeextpriv.tsf_update_required = 0;
3584 adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3585 adapter->mlmeextpriv.en_hw_update_tsf = 0;
3586 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3587
3588 #else
3589 rtw_hal_set_tsf_update(adapter, 0);
3590 #endif
3591 }
3592
rtw_hal_tsf_update_pause(_adapter * adapter)3593 static void rtw_hal_tsf_update_pause(_adapter *adapter)
3594 {
3595 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3596
3597 #else
3598 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3599 _adapter *iface;
3600 int i;
3601
3602 for (i = 0; i < dvobj->iface_nums; i++) {
3603 iface = dvobj->padapters[i];
3604 if (!iface)
3605 continue;
3606
3607 rtw_hal_set_tsf_update(iface, 0);
3608 if (iface->mlmeextpriv.tsf_update_required) {
3609 iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();
3610 if (!iface->mlmeextpriv.tsf_update_pause_stime)
3611 iface->mlmeextpriv.tsf_update_pause_stime++;
3612 }
3613 iface->mlmeextpriv.en_hw_update_tsf = 0;
3614 }
3615 #endif
3616 }
3617
rtw_hal_tsf_update_restore(_adapter * adapter)3618 static void rtw_hal_tsf_update_restore(_adapter *adapter)
3619 {
3620 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3621
3622 #else
3623 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3624 _adapter *iface;
3625 int i;
3626
3627 for (i = 0; i < dvobj->iface_nums; i++) {
3628 iface = dvobj->padapters[i];
3629 if (!iface)
3630 continue;
3631
3632 if (iface->mlmeextpriv.tsf_update_required) {
3633 /* enable HW TSF update when recive beacon*/
3634 iface->mlmeextpriv.en_hw_update_tsf = 1;
3635 #ifdef DBG_TSF_UPDATE
3636 RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"
3637 , iface->hw_port, ADPT_ARG(iface));
3638 #endif
3639 }
3640 }
3641 #endif
3642 }
3643
rtw_hal_periodic_tsf_update_chk(_adapter * adapter)3644 void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)
3645 {
3646 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3647
3648 #else
3649 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3650 _adapter *iface;
3651 struct mlme_ext_priv *mlmeext;
3652 int i;
3653 u32 restore_ms = 0;
3654
3655 if (dvobj->periodic_tsf_update_etime) {
3656 if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {
3657 /* end for restore status */
3658 dvobj->periodic_tsf_update_etime = 0;
3659 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3660 }
3661 return;
3662 }
3663
3664 if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)
3665 return;
3666
3667 /*
3668 * all required ifaces can switch to restore status together
3669 * loop all pause iface to get largest restore time required
3670 */
3671 for (i = 0; i < dvobj->iface_nums; i++) {
3672 iface = dvobj->padapters[i];
3673 if (!iface)
3674 continue;
3675
3676 mlmeext = &iface->mlmeextpriv;
3677
3678 if (mlmeext->tsf_update_required
3679 && mlmeext->tsf_update_pause_stime
3680 && rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)
3681 > mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor
3682 ) {
3683 if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)
3684 restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;
3685 }
3686 }
3687
3688 if (!restore_ms)
3689 return;
3690
3691 dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);
3692 if (!dvobj->periodic_tsf_update_etime)
3693 dvobj->periodic_tsf_update_etime++;
3694
3695 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3696
3697 /* set timer to end restore status */
3698 _set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);
3699 #endif
3700 }
3701
rtw_hal_periodic_tsf_update_end_timer_hdl(void * ctx)3702 void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)
3703 {
3704 struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;
3705
3706 if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
3707 return;
3708
3709 rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));
3710 }
3711
hw_var_rcr_config(_adapter * adapter,u32 rcr)3712 static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
3713 {
3714 int err;
3715
3716 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
3717 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;
3718 #endif
3719 err = rtw_write32(adapter, REG_RCR, rcr);
3720 if (err == _SUCCESS)
3721 GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
3722 return err;
3723 }
3724
hw_var_rcr_get(_adapter * adapter,u32 * rcr)3725 static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
3726 {
3727 u32 v32;
3728
3729 v32 = rtw_read32(adapter, REG_RCR);
3730 if (rcr)
3731 *rcr = v32;
3732 GET_HAL_DATA(adapter)->ReceiveConfig = v32;
3733 return _SUCCESS;
3734 }
3735
3736 /* only check SW RCR variable */
rtw_hal_rcr_check(_adapter * adapter,u32 check_bit)3737 inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
3738 {
3739 PHAL_DATA_TYPE hal;
3740 u32 rcr;
3741
3742 hal = GET_HAL_DATA(adapter);
3743
3744 rcr = hal->ReceiveConfig;
3745 if ((rcr & check_bit) == check_bit)
3746 return 1;
3747
3748 return 0;
3749 }
3750
rtw_hal_rcr_add(_adapter * adapter,u32 add)3751 inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
3752 {
3753 PHAL_DATA_TYPE hal;
3754 u32 rcr;
3755 u8 ret = _SUCCESS;
3756
3757 hal = GET_HAL_DATA(adapter);
3758
3759 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3760 rcr |= add;
3761 if (rcr != hal->ReceiveConfig)
3762 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3763
3764 return ret;
3765 }
3766
rtw_hal_rcr_clear(_adapter * adapter,u32 clear)3767 inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
3768 {
3769 PHAL_DATA_TYPE hal;
3770 u32 rcr;
3771 u8 ret = _SUCCESS;
3772
3773 hal = GET_HAL_DATA(adapter);
3774
3775 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3776 rcr &= ~clear;
3777 if (rcr != hal->ReceiveConfig)
3778 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3779
3780 return ret;
3781 }
3782
rtw_hal_rcr_set_chk_bssid(_adapter * adapter,u8 self_action)3783 void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
3784 {
3785 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3786 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3787 u32 rcr, rcr_new;
3788 struct mi_state mstate, mstate_s;
3789
3790 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3791 rcr_new = rcr;
3792
3793 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)
3794 rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
3795 #else
3796 rtw_mi_status_no_self(adapter, &mstate);
3797 rtw_mi_status_no_others(adapter, &mstate_s);
3798
3799 /* only adjust parameters interested */
3800 switch (self_action) {
3801 case MLME_SCAN_ENTER:
3802 mstate_s.scan_num = 1;
3803 mstate_s.scan_enter_num = 1;
3804 break;
3805 case MLME_SCAN_DONE:
3806 mstate_s.scan_enter_num = 0;
3807 break;
3808 case MLME_STA_CONNECTING:
3809 mstate_s.lg_sta_num = 1;
3810 mstate_s.ld_sta_num = 0;
3811 break;
3812 case MLME_STA_CONNECTED:
3813 mstate_s.lg_sta_num = 0;
3814 mstate_s.ld_sta_num = 1;
3815 break;
3816 case MLME_STA_DISCONNECTED:
3817 mstate_s.lg_sta_num = 0;
3818 mstate_s.ld_sta_num = 0;
3819 break;
3820 #ifdef CONFIG_TDLS
3821 case MLME_TDLS_LINKED:
3822 mstate_s.ld_tdls_num = 1;
3823 break;
3824 case MLME_TDLS_NOLINK:
3825 mstate_s.ld_tdls_num = 0;
3826 break;
3827 #endif
3828 #ifdef CONFIG_AP_MODE
3829 case MLME_AP_STARTED:
3830 mstate_s.ap_num = 1;
3831 break;
3832 case MLME_AP_STOPPED:
3833 mstate_s.ap_num = 0;
3834 mstate_s.ld_ap_num = 0;
3835 break;
3836 #endif
3837 #ifdef CONFIG_RTW_MESH
3838 case MLME_MESH_STARTED:
3839 mstate_s.mesh_num = 1;
3840 break;
3841 case MLME_MESH_STOPPED:
3842 mstate_s.mesh_num = 0;
3843 mstate_s.ld_mesh_num = 0;
3844 break;
3845 #endif
3846 case MLME_ACTION_NONE:
3847 case MLME_ADHOC_STARTED:
3848 /* caller without effect of decision */
3849 break;
3850 default:
3851 rtw_warn_on(1);
3852 };
3853
3854 rtw_mi_status_merge(&mstate, &mstate_s);
3855
3856 if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
3857 #ifdef CONFIG_FIND_BEST_CHANNEL
3858 || MSTATE_SCAN_ENTER_NUM(&mstate)
3859 #endif
3860 || hal_data->in_cta_test
3861 )
3862 rcr_new &= ~RCR_CBSSID_DATA;
3863 else
3864 rcr_new |= RCR_CBSSID_DATA;
3865
3866 if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)
3867 rcr_new &= ~RCR_CBSSID_BCN;
3868 else if (MSTATE_STA_LG_NUM(&mstate)
3869 || adapter_to_dvobj(adapter)->periodic_tsf_update_etime
3870 )
3871 rcr_new |= RCR_CBSSID_BCN;
3872 else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
3873 || MSTATE_MESH_NUM(&mstate)
3874 )
3875 rcr_new &= ~RCR_CBSSID_BCN;
3876 else
3877 rcr_new |= RCR_CBSSID_BCN;
3878
3879 #ifdef CONFIG_CLIENT_PORT_CFG
3880 if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)
3881 rcr_new &= ~RCR_CBSSID_BCN;
3882 #endif
3883 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
3884
3885 #ifdef CONFIG_RTW_MULTI_AP
3886 if (MSTATE_AP_NUM(&mstate)
3887 && rtw_unassoc_sta_src_chk(adapter, UNASOC_STA_SRC_RX_NMY_UC)
3888 ) {
3889 rcr_new |= RCR_AAP;
3890 } else
3891 rcr_new &= ~RCR_AAP;
3892 #endif
3893
3894 if (rcr == rcr_new)
3895 return;
3896
3897 if (!hal_spec->rx_tsf_filter
3898 && (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))
3899 rtw_hal_tsf_update_pause(adapter);
3900
3901 rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
3902
3903 if (!hal_spec->rx_tsf_filter
3904 && !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)
3905 && self_action != MLME_STA_CONNECTING)
3906 rtw_hal_tsf_update_restore(adapter);
3907 }
3908
rtw_hal_rcr_set_chk_bssid_act_non(_adapter * adapter)3909 void rtw_hal_rcr_set_chk_bssid_act_non(_adapter *adapter)
3910 {
3911 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3912 }
3913
hw_var_set_rcr_am(_adapter * adapter,u8 enable)3914 static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
3915 {
3916 u32 rcr = RCR_AM;
3917
3918 if (enable)
3919 rtw_hal_rcr_add(adapter, rcr);
3920 else
3921 rtw_hal_rcr_clear(adapter, rcr);
3922 }
3923
hw_var_set_bcn_interval(_adapter * adapter,u16 interval)3924 static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)
3925 {
3926 #ifdef CONFIG_SWTIMER_BASED_TXBCN
3927 interval = rtw_hal_bcn_interval_adjust(adapter, interval);
3928 #endif
3929
3930 #ifdef RTW_HALMAC
3931 rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);
3932 #else
3933 rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);
3934 #endif
3935
3936 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3937 {
3938 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3939 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3940
3941 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3942 RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);
3943 rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);
3944 }
3945 }
3946 #endif
3947 }
3948
3949 #if CONFIG_TX_AC_LIFETIME
3950 const char *const _tx_aclt_conf_str[] = {
3951 "DEFAULT",
3952 "AP_M2U",
3953 "MESH",
3954 "INVALID",
3955 };
3956
dump_tx_aclt_force_val(void * sel,struct dvobj_priv * dvobj)3957 void dump_tx_aclt_force_val(void *sel, struct dvobj_priv *dvobj)
3958 {
3959 #define TX_ACLT_FORCE_MSG_LEN 64
3960 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3961 struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3962 char buf[TX_ACLT_FORCE_MSG_LEN];
3963 int cnt = 0;
3964
3965 RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3966 , hal_spec->tx_aclt_unit_factor * 32
3967 , 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3968
3969 RTW_PRINT_SEL(sel, "%-5s %-12s %-12s\n", "en", "vo_vi(us)", "be_bk(us)");
3970 RTW_PRINT_SEL(sel, " 0x%02x %12u %12u\n"
3971 , conf->en
3972 , conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3973 , conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3974 );
3975
3976 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "%5s", conf->en == 0xFF ? "AUTO" : "FORCE");
3977 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3978 goto exit;
3979
3980 if (conf->vo_vi)
3981 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->vo_vi);
3982 else
3983 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");
3984 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3985 goto exit;
3986
3987
3988 if (conf->be_bk)
3989 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->be_bk);
3990 else
3991 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");
3992 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3993 goto exit;
3994
3995 RTW_PRINT_SEL(sel, "%s\n", buf);
3996
3997 exit:
3998 return;
3999 }
4000
rtw_hal_set_tx_aclt_force_val(_adapter * adapter,struct tx_aclt_conf_t * input,u8 arg_num)4001 void rtw_hal_set_tx_aclt_force_val(_adapter *adapter, struct tx_aclt_conf_t *input, u8 arg_num)
4002 {
4003 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4004 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4005 struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
4006
4007 if (arg_num >= 1) {
4008 if (input->en == 0xFF)
4009 conf->en = input->en;
4010 else
4011 conf->en = input->en & 0xF;
4012 }
4013 if (arg_num >= 2) {
4014 conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
4015 if (conf->vo_vi > 0xFFFF)
4016 conf->vo_vi = 0xFFFF;
4017 }
4018 if (arg_num >= 3) {
4019 conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
4020 if (conf->be_bk > 0xFFFF)
4021 conf->be_bk = 0xFFFF;
4022 }
4023 }
4024
dump_tx_aclt_confs(void * sel,struct dvobj_priv * dvobj)4025 void dump_tx_aclt_confs(void *sel, struct dvobj_priv *dvobj)
4026 {
4027 #define TX_ACLT_CONF_MSG_LEN 32
4028 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
4029 struct tx_aclt_conf_t *conf;
4030 char buf[TX_ACLT_CONF_MSG_LEN];
4031 int cnt;
4032 int i;
4033
4034 RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
4035 , hal_spec->tx_aclt_unit_factor * 32
4036 , 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
4037
4038 RTW_PRINT_SEL(sel, "%-7s %-1s %-3s %-9s %-9s %-10s %-10s\n"
4039 , "name", "#", "en", "vo_vi(us)", "be_bk(us)", "vo_vi(reg)", "be_bk(reg)");
4040
4041 for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
4042 conf = &dvobj->tx_aclt_confs[i];
4043 cnt = 0;
4044
4045 if (conf->vo_vi)
4046 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->vo_vi);
4047 else
4048 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
4049 if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
4050 continue;
4051
4052 if (conf->be_bk)
4053 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->be_bk);
4054 else
4055 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
4056 if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
4057 continue;
4058
4059 RTW_PRINT_SEL(sel, "%7s %1u 0x%x %9u %9u%s\n"
4060 , tx_aclt_conf_str(i), i
4061 , conf->en
4062 , conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
4063 , conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
4064 , buf
4065 );
4066 }
4067 }
4068
rtw_hal_set_tx_aclt_conf(_adapter * adapter,u8 conf_idx,struct tx_aclt_conf_t * input,u8 arg_num)4069 void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_conf_t *input, u8 arg_num)
4070 {
4071 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4072 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4073 struct tx_aclt_conf_t *conf;
4074
4075 if (conf_idx >= TX_ACLT_CONF_NUM)
4076 return;
4077
4078 conf = &dvobj->tx_aclt_confs[conf_idx];
4079
4080 if (arg_num >= 1) {
4081 if (input->en != 0xFF)
4082 conf->en = input->en & 0xF;
4083 }
4084 if (arg_num >= 2) {
4085 conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
4086 if (conf->vo_vi > 0xFFFF)
4087 conf->vo_vi = 0xFFFF;
4088 }
4089 if (arg_num >= 3) {
4090 conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
4091 if (conf->be_bk > 0xFFFF)
4092 conf->be_bk = 0xFFFF;
4093 }
4094 }
4095
rtw_hal_update_tx_aclt(_adapter * adapter)4096 void rtw_hal_update_tx_aclt(_adapter *adapter)
4097 {
4098 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4099 struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter);
4100 u8 lt_en = 0, lt_en_ori;
4101 u16 lt_vo_vi = 0xFFFF, lt_be_bk = 0xFFFF;
4102 u32 lt, lt_ori;
4103 struct tx_aclt_conf_t *conf;
4104 int i;
4105 #ifdef CONFIG_AP_MODE
4106 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
4107 _adapter *iface;
4108 u8 ap_m2u_num = 0;
4109
4110 for (i = 0; i < dvobj->iface_nums; i++) {
4111 iface = dvobj->padapters[i];
4112 if (!iface)
4113 continue;
4114
4115 if (MLME_IS_AP(iface)
4116 && ((iface->b2u_flags_ap_src & RTW_AP_B2U_IP_MCAST)
4117 || (iface->b2u_flags_ap_fwd & RTW_AP_B2U_IP_MCAST))
4118 )
4119 ap_m2u_num++;
4120 }
4121 #endif
4122 #endif /* CONFIG_AP_MODE */
4123
4124 lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN);
4125 lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME);
4126
4127 for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
4128 if (!(dvobj->tx_aclt_flags & BIT(i)))
4129 continue;
4130
4131 conf = &dvobj->tx_aclt_confs[i];
4132
4133 if (i == TX_ACLT_CONF_DEFAULT) {
4134 /* first and default status, assign directly */
4135 lt_en = conf->en;
4136 if (conf->vo_vi)
4137 lt_vo_vi = conf->vo_vi;
4138 if (conf->be_bk)
4139 lt_be_bk = conf->be_bk;
4140 }
4141 #ifdef CONFIG_AP_MODE
4142 #if CONFIG_RTW_AP_DATA_BMC_TO_UC || defined(CONFIG_RTW_MESH)
4143 else if (0
4144 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
4145 || (i == TX_ACLT_CONF_AP_M2U
4146 && ap_m2u_num
4147 && macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */)
4148 #endif
4149 #ifdef CONFIG_RTW_MESH
4150 || (i == TX_ACLT_CONF_MESH
4151 && macid_ctl->op_num[H2C_MSR_ROLE_MESH] > 1 /* implies only 1 MESH mode supported */)
4152 #endif
4153 ) {
4154 /* long term status, OR en and MIN lifetime */
4155 lt_en |= conf->en;
4156 if (conf->vo_vi && lt_vo_vi > conf->vo_vi)
4157 lt_vo_vi = conf->vo_vi;
4158 if (conf->be_bk && lt_be_bk > conf->be_bk)
4159 lt_be_bk = conf->be_bk;
4160 }
4161 #endif
4162 #endif /* CONFIG_AP_MODE */
4163 }
4164
4165 if (dvobj->tx_aclt_force_val.en != 0xFF)
4166 lt_en = dvobj->tx_aclt_force_val.en;
4167 if (dvobj->tx_aclt_force_val.vo_vi)
4168 lt_vo_vi = dvobj->tx_aclt_force_val.vo_vi;
4169 if (dvobj->tx_aclt_force_val.be_bk)
4170 lt_be_bk = dvobj->tx_aclt_force_val.be_bk;
4171
4172 lt_en = (lt_en_ori & 0xF0) | (lt_en & 0x0F);
4173 lt = (lt_be_bk << 16) | lt_vo_vi;
4174
4175 if (0)
4176 RTW_INFO("lt_en:0x%x(0x%x), lt:0x%08x(0x%08x)\n", lt_en, lt_en_ori, lt, lt_ori);
4177
4178 if (lt_en != lt_en_ori)
4179 rtw_write8(adapter, REG_LIFETIME_EN, lt_en);
4180 if (lt != lt_ori)
4181 rtw_write32(adapter, REG_PKT_LIFE_TIME, lt);
4182 }
4183 #endif /* CONFIG_TX_AC_LIFETIME */
4184
hw_var_port_switch(_adapter * adapter)4185 void hw_var_port_switch(_adapter *adapter)
4186 {
4187 #ifdef CONFIG_CONCURRENT_MODE
4188 #ifdef CONFIG_RUNTIME_PORT_SWITCH
4189 /*
4190 0x102: MSR
4191 0x550: REG_BCN_CTRL
4192 0x551: REG_BCN_CTRL_1
4193 0x55A: REG_ATIMWND
4194 0x560: REG_TSFTR
4195 0x568: REG_TSFTR1
4196 0x570: REG_ATIMWND_1
4197 0x610: REG_MACID
4198 0x618: REG_BSSID
4199 0x700: REG_MACID1
4200 0x708: REG_BSSID1
4201 */
4202
4203 int i;
4204 u8 msr;
4205 u8 bcn_ctrl;
4206 u8 bcn_ctrl_1;
4207 u8 atimwnd[2];
4208 u8 atimwnd_1[2];
4209 u8 tsftr[8];
4210 u8 tsftr_1[8];
4211 u8 macid[6];
4212 u8 bssid[6];
4213 u8 macid_1[6];
4214 u8 bssid_1[6];
4215 #if defined(CONFIG_RTL8192F)
4216 u16 wlan_act_mask_ctrl = 0;
4217 u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;
4218 #endif
4219
4220 u8 hw_port;
4221 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4222 _adapter *iface = NULL;
4223
4224 msr = rtw_read8(adapter, MSR);
4225 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4226 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4227 #if defined(CONFIG_RTL8192F)
4228 wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4229 #endif
4230
4231 for (i = 0; i < 2; i++)
4232 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4233 for (i = 0; i < 2; i++)
4234 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4235
4236 for (i = 0; i < 8; i++)
4237 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4238 for (i = 0; i < 8; i++)
4239 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4240
4241 for (i = 0; i < 6; i++)
4242 macid[i] = rtw_read8(adapter, REG_MACID + i);
4243
4244 for (i = 0; i < 6; i++)
4245 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4246
4247 for (i = 0; i < 6; i++)
4248 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4249
4250 for (i = 0; i < 6; i++)
4251 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4252
4253 #ifdef DBG_RUNTIME_PORT_SWITCH
4254 RTW_INFO(FUNC_ADPT_FMT" before switch\n"
4255 "msr:0x%02x\n"
4256 "bcn_ctrl:0x%02x\n"
4257 "bcn_ctrl_1:0x%02x\n"
4258 #if defined(CONFIG_RTL8192F)
4259 "wlan_act_mask_ctrl:0x%02x\n"
4260 #endif
4261 "atimwnd:0x%04x\n"
4262 "atimwnd_1:0x%04x\n"
4263 "tsftr:%llu\n"
4264 "tsftr1:%llu\n"
4265 "macid:"MAC_FMT"\n"
4266 "bssid:"MAC_FMT"\n"
4267 "macid_1:"MAC_FMT"\n"
4268 "bssid_1:"MAC_FMT"\n"
4269 , FUNC_ADPT_ARG(adapter)
4270 , msr
4271 , bcn_ctrl
4272 , bcn_ctrl_1
4273 #if defined(CONFIG_RTL8192F)
4274 , wlan_act_mask_ctrl
4275 #endif
4276 , *((u16 *)atimwnd)
4277 , *((u16 *)atimwnd_1)
4278 , *((u64 *)tsftr)
4279 , *((u64 *)tsftr_1)
4280 , MAC_ARG(macid)
4281 , MAC_ARG(bssid)
4282 , MAC_ARG(macid_1)
4283 , MAC_ARG(bssid_1)
4284 );
4285 #endif /* DBG_RUNTIME_PORT_SWITCH */
4286
4287 /* disable bcn function, disable update TSF */
4288 rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4289 rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4290
4291 #if defined(CONFIG_RTL8192F)
4292 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);
4293 #endif
4294
4295 /* switch msr */
4296 msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
4297 rtw_write8(adapter, MSR, msr);
4298
4299 /* write port0 */
4300 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
4301 for (i = 0; i < 2; i++)
4302 rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
4303 for (i = 0; i < 8; i++)
4304 rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
4305 for (i = 0; i < 6; i++)
4306 rtw_write8(adapter, REG_MACID + i, macid_1[i]);
4307 for (i = 0; i < 6; i++)
4308 rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
4309
4310 /* write port1 */
4311 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
4312 for (i = 0; i < 2; i++)
4313 rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
4314 for (i = 0; i < 8; i++)
4315 rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
4316 for (i = 0; i < 6; i++)
4317 rtw_write8(adapter, REG_MACID1 + i, macid[i]);
4318 for (i = 0; i < 6; i++)
4319 rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
4320
4321 /* write bcn ctl */
4322 #ifdef CONFIG_BT_COEXIST
4323 /* always enable port0 beacon function for PSTDMA */
4324 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
4325 || IS_HARDWARE_TYPE_8723D(adapter))
4326 bcn_ctrl_1 |= EN_BCN_FUNCTION;
4327 /* always disable port1 beacon function for PSTDMA */
4328 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
4329 bcn_ctrl &= ~EN_BCN_FUNCTION;
4330 #endif
4331 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
4332 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
4333
4334 #if defined(CONFIG_RTL8192F)
4335 /* if the setting of port0 and port1 are the same, it does not need to switch port setting*/
4336 if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)
4337 != (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))
4338 wlan_act_mask_ctrl ^= en_port_mask;
4339 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);
4340 #endif
4341
4342 if (adapter->iface_id == IFACE_ID0)
4343 iface = dvobj->padapters[IFACE_ID1];
4344 else if (adapter->iface_id == IFACE_ID1)
4345 iface = dvobj->padapters[IFACE_ID0];
4346
4347
4348 if (adapter->hw_port == HW_PORT0) {
4349 adapter->hw_port = HW_PORT1;
4350 iface->hw_port = HW_PORT0;
4351 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4352 ADPT_ARG(iface), ADPT_ARG(adapter));
4353 } else {
4354 adapter->hw_port = HW_PORT0;
4355 iface->hw_port = HW_PORT1;
4356 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4357 ADPT_ARG(adapter), ADPT_ARG(iface));
4358 }
4359
4360 #ifdef DBG_RUNTIME_PORT_SWITCH
4361 msr = rtw_read8(adapter, MSR);
4362 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4363 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4364 #if defined(CONFIG_RTL8192F)
4365 wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4366 #endif
4367
4368 for (i = 0; i < 2; i++)
4369 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4370 for (i = 0; i < 2; i++)
4371 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4372
4373 for (i = 0; i < 8; i++)
4374 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4375 for (i = 0; i < 8; i++)
4376 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4377
4378 for (i = 0; i < 6; i++)
4379 macid[i] = rtw_read8(adapter, REG_MACID + i);
4380
4381 for (i = 0; i < 6; i++)
4382 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4383
4384 for (i = 0; i < 6; i++)
4385 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4386
4387 for (i = 0; i < 6; i++)
4388 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4389
4390 RTW_INFO(FUNC_ADPT_FMT" after switch\n"
4391 "msr:0x%02x\n"
4392 "bcn_ctrl:0x%02x\n"
4393 "bcn_ctrl_1:0x%02x\n"
4394 #if defined(CONFIG_RTL8192F)
4395 "wlan_act_mask_ctrl:0x%02x\n"
4396 #endif
4397 "atimwnd:%u\n"
4398 "atimwnd_1:%u\n"
4399 "tsftr:%llu\n"
4400 "tsftr1:%llu\n"
4401 "macid:"MAC_FMT"\n"
4402 "bssid:"MAC_FMT"\n"
4403 "macid_1:"MAC_FMT"\n"
4404 "bssid_1:"MAC_FMT"\n"
4405 , FUNC_ADPT_ARG(adapter)
4406 , msr
4407 , bcn_ctrl
4408 , bcn_ctrl_1
4409 #if defined(CONFIG_RTL8192F)
4410 , wlan_act_mask_ctrl
4411 #endif
4412 , *((u16 *)atimwnd)
4413 , *((u16 *)atimwnd_1)
4414 , *((u64 *)tsftr)
4415 , *((u64 *)tsftr_1)
4416 , MAC_ARG(macid)
4417 , MAC_ARG(bssid)
4418 , MAC_ARG(macid_1)
4419 , MAC_ARG(bssid_1)
4420 );
4421 #endif /* DBG_RUNTIME_PORT_SWITCH */
4422
4423 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
4424 #endif /* CONFIG_CONCURRENT_MODE */
4425 }
4426
4427 const char *const _h2c_msr_role_str[] = {
4428 "RSVD",
4429 "STA",
4430 "AP",
4431 "GC",
4432 "GO",
4433 "TDLS",
4434 "ADHOC",
4435 "MESH",
4436 "INVALID",
4437 };
4438
4439 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_default_port_id_cmd(_adapter * adapter,u8 mac_id)4440 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
4441 {
4442 s32 ret = _SUCCESS;
4443 u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
4444 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4445 u8 port_id = rtw_hal_get_port(adapter);
4446
4447 if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))
4448 return ret;
4449
4450 SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);
4451 SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
4452
4453 RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
4454 RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",
4455 __func__, ADPT_ARG(adapter), port_id, mac_id);
4456
4457 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
4458 dvobj->dft.port_id = port_id;
4459 dvobj->dft.mac_id = mac_id;
4460
4461 return ret;
4462 }
rtw_set_default_port_id(_adapter * adapter)4463 s32 rtw_set_default_port_id(_adapter *adapter)
4464 {
4465 s32 ret = _SUCCESS;
4466 struct sta_info *psta;
4467 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4468
4469 if (is_client_associated_to_ap(adapter)) {
4470 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
4471 if (psta)
4472 ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
4473 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
4474
4475 } else {
4476 }
4477
4478 return ret;
4479 }
rtw_set_ps_rsvd_page(_adapter * adapter)4480 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
4481 {
4482 s32 ret = _SUCCESS;
4483 u16 media_status_rpt = RT_MEDIA_CONNECT;
4484 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4485
4486 if (adapter->iface_id == pwrctl->fw_psmode_iface_id)
4487 return ret;
4488
4489 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
4490 (u8 *)&media_status_rpt);
4491
4492 return ret;
4493 }
4494
4495 #if 0
4496 _adapter * _rtw_search_dp_iface(_adapter *adapter)
4497 {
4498 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4499 _adapter *iface;
4500 _adapter *target_iface = NULL;
4501 int i;
4502 u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;
4503 u8 p2p_go_num = 0, p2p_gc_num = 0;
4504 _adapter *sta_ifs[8];
4505 _adapter *ap_ifs[8];
4506 _adapter *mesh_ifs[8];
4507 _adapter *gc_ifs[8];
4508 _adapter *go_ifs[8];
4509
4510 for (i = 0; i < dvobj->iface_nums; i++) {
4511 iface = dvobj->padapters[i];
4512
4513 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
4514 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4515 sta_ifs[sta_num++] = iface;
4516
4517 #ifdef CONFIG_TDLS
4518 if (iface->tdlsinfo.link_established == _TRUE)
4519 tdls_num++;
4520 #endif
4521 #ifdef CONFIG_P2P
4522 if (MLME_IS_GC(iface))
4523 gc_ifs[p2p_gc_num++] = iface;
4524 #endif
4525 }
4526 #ifdef CONFIG_AP_MODE
4527 } else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
4528 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4529 ap_ifs[ap_num++] = iface;
4530 #ifdef CONFIG_P2P
4531 if (MLME_IS_GO(iface))
4532 go_ifs[p2p_go_num++] = iface;
4533 #endif
4534 }
4535 #endif
4536 } else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
4537 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4538 ) {
4539 adhoc_num++;
4540
4541 #ifdef CONFIG_RTW_MESH
4542 } else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
4543 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4544 ) {
4545 mesh_ifs[mesh_num++] = iface;
4546 #endif
4547 }
4548 }
4549
4550 if (p2p_gc_num) {
4551 target_iface = gc_ifs[0];
4552 }
4553 else if (sta_num) {
4554 if(sta_num == 1) {
4555 target_iface = sta_ifs[0];
4556 } else if (sta_num >= 2) {
4557 /*TODO get target_iface by timestamp*/
4558 target_iface = sta_ifs[0];
4559 }
4560 } else if (ap_num) {
4561 target_iface = ap_ifs[0];
4562 }
4563
4564 RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);
4565 RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);
4566 RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);
4567 RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);
4568 RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);
4569 RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);
4570 RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);
4571
4572 if (target_iface)
4573 RTW_INFO("%s => target_iface ("ADPT_FMT")\n",
4574 __func__, ADPT_ARG(target_iface));
4575 else
4576 RTW_INFO("%s => target_iface NULL\n", __func__);
4577
4578 return target_iface;
4579 }
4580
4581 void rtw_search_default_port(_adapter *adapter)
4582 {
4583 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4584 _adapter *adp_iface = NULL;
4585 #ifdef CONFIG_WOWLAN
4586 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
4587
4588 if (pwrpriv->wowlan_mode == _TRUE) {
4589 adp_iface = adapter;
4590 goto exit;
4591 }
4592 #endif
4593 adp_iface = _rtw_search_dp_iface(adapter);
4594
4595 exit :
4596 if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))
4597 rtw_set_default_port_id(adp_iface);
4598 else
4599 rtw_hal_set_default_port_id_cmd(adapter, 0);
4600
4601 if (1) {
4602 _adapter *tmp_adp;
4603
4604 tmp_adp = (adp_iface) ? adp_iface : adapter;
4605
4606 RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",
4607 __func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));
4608 }
4609 }
4610 #endif
4611 #endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/
4612
4613 #ifdef CONFIG_P2P_PS
4614 #ifdef RTW_HALMAC
rtw_set_p2p_ps_offload_cmd(_adapter * adapter,u8 p2p_ps_state)4615 void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
4616 {
4617 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4618 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4619 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4620 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4621 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
4622 struct sta_priv *pstapriv = &adapter->stapriv;
4623 struct sta_info *psta;
4624 HAL_P2P_PS_PARA p2p_ps_para;
4625 int status = -1;
4626 u8 i;
4627 u8 hw_port = rtw_hal_get_port(adapter);
4628
4629 _rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
4630 _rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
4631
4632 (&p2p_ps_para)->p2p_port_id = hw_port;
4633 (&p2p_ps_para)->p2p_group = 0;
4634 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
4635 if (psta) {
4636 (&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
4637 } else {
4638 if (p2p_ps_state != P2P_PS_DISABLE) {
4639 RTW_ERR("%s , psta was NULL\n", __func__);
4640 return;
4641 }
4642 }
4643
4644
4645 switch (p2p_ps_state) {
4646 case P2P_PS_DISABLE:
4647 RTW_INFO("P2P_PS_DISABLE\n");
4648 _rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
4649 break;
4650
4651 case P2P_PS_ENABLE:
4652 RTW_INFO("P2P_PS_ENABLE\n");
4653 /* update CTWindow value. */
4654 if (pwdinfo->ctwindow > 0) {
4655 (&p2p_ps_para)->ctwindow_en = 1;
4656 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4657 /*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
4658 }
4659
4660
4661 if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
4662 (&p2p_ps_para)->offload_en = 1;
4663 if (pwdinfo->role == P2P_ROLE_GO) {
4664 (&p2p_ps_para)->role = 1;
4665 (&p2p_ps_para)->all_sta_sleep = 0;
4666 } else
4667 (&p2p_ps_para)->role = 0;
4668
4669 (&p2p_ps_para)->discovery = 0;
4670 }
4671 /* hw only support 2 set of NoA */
4672 for (i = 0; i < pwdinfo->noa_num; i++) {
4673 /* To control the register setting for which NOA */
4674 (&p2p_ps_para)->noa_sel = i;
4675 (&p2p_ps_para)->noa_en = 1;
4676 (&p2p_ps_para)->disable_close_rf = 0;
4677 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
4678 #ifdef CONFIG_CONCURRENT_MODE
4679 if (rtw_mi_buddy_check_fwstate(adapter, WIFI_ASOC_STATE))
4680 #endif /* CONFIG_CONCURRENT_MODE */
4681 (&p2p_ps_para)->disable_close_rf = 1;
4682 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
4683 /* config P2P NoA Descriptor Register */
4684 /* config NOA duration */
4685 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
4686 /* config NOA interval */
4687 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
4688 /* config NOA start time */
4689 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
4690 /* config NOA count */
4691 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
4692 /*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
4693 (&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
4694 (&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
4695 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4696 if (status == -1)
4697 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4698 }
4699
4700 break;
4701
4702 case P2P_PS_SCAN:
4703 /*This feature FW not ready 20161116 YiWei*/
4704 return;
4705 /*
4706 RTW_INFO("P2P_PS_SCAN\n");
4707 (&p2p_ps_para)->discovery = 1;
4708 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4709 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4710 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4711 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4712 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4713 */
4714 break;
4715
4716 case P2P_PS_SCAN_DONE:
4717 /*This feature FW not ready 20161116 YiWei*/
4718 return;
4719 /*
4720 RTW_INFO("P2P_PS_SCAN_DONE\n");
4721 (&p2p_ps_para)->discovery = 0;
4722 pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
4723 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4724 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4725 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4726 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4727 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4728 */
4729 break;
4730
4731 default:
4732 break;
4733 }
4734
4735 if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
4736 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4737 if (status == -1)
4738 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4739 }
4740 _rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
4741
4742 }
4743 #endif /* RTW_HALMAC */
4744 #endif /* CONFIG_P2P */
4745
4746 /*
4747 * rtw_hal_set_FwMediaStatusRpt_cmd -
4748 *
4749 * @adapter:
4750 * @opmode: 0:disconnect, 1:connect
4751 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
4752 * @miracast_sink: 0:source. 1:sink
4753 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
4754 * @macid:
4755 * @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end
4756 * @macid_end:
4757 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)4758 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)
4759 {
4760 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
4761 u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
4762 int i;
4763 s32 ret;
4764 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4765 u8 hw_port = rtw_hal_get_port(adapter);
4766 #endif
4767 u8 op_num_change_bmp = 0;
4768
4769 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
4770 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
4771 SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
4772 SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
4773 SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
4774 SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
4775 SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
4776 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4777 SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);
4778 #endif
4779 RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
4780
4781 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
4782 if (ret != _SUCCESS)
4783 goto exit;
4784
4785 #if defined(CONFIG_RTL8188E)
4786 if (rtw_get_chip_type(adapter) == RTL8188E) {
4787 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4788
4789 /* 8188E FW doesn't set macid no link, driver does it by self */
4790 if (opmode)
4791 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
4792 else
4793 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
4794
4795 /* for 8188E RA */
4796 #if (RATE_ADAPTIVE_SUPPORT == 1)
4797 if (hal_data->fw_ractrl == _FALSE) {
4798 u8 max_macid;
4799
4800 max_macid = rtw_search_max_mac_id(adapter);
4801 rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
4802 }
4803 #endif
4804 }
4805 #endif
4806
4807 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
4808 /* TODO: this should move to IOT issue area */
4809 if (rtw_get_chip_type(adapter) == RTL8812
4810 || rtw_get_chip_type(adapter) == RTL8821
4811 ) {
4812 if (MLME_IS_STA(adapter))
4813 Hal_PatchwithJaguar_8812(adapter, opmode);
4814 }
4815 #endif
4816
4817 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
4818 if (macid_ind == 0)
4819 macid_end = macid;
4820
4821 for (i = macid; macid <= macid_end; macid++) {
4822 op_num_change_bmp |= rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
4823 if (!opmode) {
4824 rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
4825 rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
4826 rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
4827 rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
4828 }
4829 }
4830
4831 #if CONFIG_TX_AC_LIFETIME
4832 if (op_num_change_bmp)
4833 rtw_hal_update_tx_aclt(adapter);
4834 #endif
4835
4836 if (!opmode)
4837 rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
4838
4839 exit:
4840 return ret;
4841 }
4842
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)4843 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
4844 {
4845 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
4846 }
4847
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)4848 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
4849 {
4850 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
4851 }
4852
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4853 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4854 {
4855 u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
4856 u8 ret = 0;
4857
4858 RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
4859 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
4860 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
4861 rsvdpageloc->LocBTQosNull);
4862
4863 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
4864 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
4865 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
4866 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
4867 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
4868
4869 ret = rtw_hal_fill_h2c_cmd(padapter,
4870 H2C_RSVD_PAGE,
4871 H2C_RSVDPAGE_LOC_LEN,
4872 u1H2CRsvdPageParm);
4873
4874 }
4875
4876 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)4877 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
4878 {
4879 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4880
4881 if (IS_8723D_SERIES(pHalData->version_id) || IS_8192F_SERIES(pHalData->version_id)
4882 || IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id)
4883 || IS_8822C_SERIES(pHalData->version_id))
4884 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4885 /*
4886 * Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
4887 * It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
4888 * and implement HAL function.
4889 * TODO: GPIO_8 multi function?
4890 */
4891
4892 if ((index == 13 || index == 14)
4893 #if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
4894 /* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
4895 && (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
4896 #endif
4897 )
4898 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4899 }
4900
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)4901 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
4902 {
4903 #if defined(CONFIG_RTL8192F)
4904 rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&outputval));
4905 #else
4906 if (index <= 7) {
4907 /* config GPIO mode */
4908 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4909 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4910
4911 /* config GPIO Sel */
4912 /* 0: input */
4913 /* 1: output */
4914 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4915 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
4916
4917 /* set output value */
4918 if (outputval) {
4919 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4920 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
4921 } else {
4922 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4923 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
4924 }
4925 } else if (index <= 15) {
4926 /* 88C Series: */
4927 /* index: 11~8 transform to 3~0 */
4928 /* 8723 Series: */
4929 /* index: 12~8 transform to 4~0 */
4930
4931 index -= 8;
4932
4933 /* config GPIO mode */
4934 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4935 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4936
4937 /* config GPIO Sel */
4938 /* 0: input */
4939 /* 1: output */
4940 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4941 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
4942
4943 /* set output value */
4944 if (outputval) {
4945 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4946 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
4947 } else {
4948 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4949 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
4950 }
4951 } else {
4952 RTW_INFO("%s: invalid GPIO%d=%d\n",
4953 __FUNCTION__, index, outputval);
4954 }
4955 #endif
4956 }
rtw_hal_set_input_gpio(_adapter * padapter,u8 index)4957 void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
4958 {
4959 #if defined(CONFIG_RTL8192F)
4960 rtw_hal_set_hwreg(padapter, HW_VAR_WOW_INPUT_GPIO, (u8 *)(&index));
4961 #else
4962 if (index <= 7) {
4963 /* config GPIO mode */
4964 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4965 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4966
4967 /* config GPIO Sel */
4968 /* 0: input */
4969 /* 1: output */
4970 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4971 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
4972
4973 } else if (index <= 15) {
4974 /* 88C Series: */
4975 /* index: 11~8 transform to 3~0 */
4976 /* 8723 Series: */
4977 /* index: 12~8 transform to 4~0 */
4978
4979 index -= 8;
4980
4981 /* config GPIO mode */
4982 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4983 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4984
4985 /* config GPIO Sel */
4986 /* 0: input */
4987 /* 1: output */
4988 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4989 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
4990 } else
4991 RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
4992 #endif
4993 }
4994
4995 #endif
4996
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4997 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4998 {
4999 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
5000 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5001 u8 ret = 0;
5002 #ifdef CONFIG_WOWLAN
5003 u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
5004
5005 RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
5006 __func__, rsvdpageloc->LocRemoteCtrlInfo,
5007 rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
5008 rsvdpageloc->LocNDPInfo);
5009 RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
5010 __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
5011 rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
5012
5013 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
5014 SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
5015 SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
5016 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
5017 rsvdpageloc->LocNbrAdv);
5018 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
5019 rsvdpageloc->LocNDPInfo);
5020 #ifdef CONFIG_GTK_OL
5021 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
5022 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
5023 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
5024 #endif /* CONFIG_GTK_OL */
5025 ret = rtw_hal_fill_h2c_cmd(padapter,
5026 H2C_AOAC_RSVD_PAGE,
5027 H2C_AOAC_RSVDPAGE_LOC_LEN,
5028 u1H2CAoacRsvdPageParm);
5029
5030 RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
5031 _rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
5032 SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
5033 rsvdpageloc->LocAOACReport);
5034 ret = rtw_hal_fill_h2c_cmd(padapter,
5035 H2C_AOAC_RSVDPAGE3,
5036 H2C_AOAC_RSVDPAGE_LOC_LEN,
5037 u1H2CAoacRsvdPageParm);
5038 pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
5039 }
5040 #ifdef CONFIG_PNO_SUPPORT
5041 else {
5042
5043 if (!pwrpriv->wowlan_in_resume) {
5044 RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
5045 _rtw_memset(&u1H2CAoacRsvdPageParm, 0,
5046 sizeof(u1H2CAoacRsvdPageParm));
5047 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
5048 rsvdpageloc->LocPNOInfo);
5049 ret = rtw_hal_fill_h2c_cmd(padapter,
5050 H2C_AOAC_RSVDPAGE3,
5051 H2C_AOAC_RSVDPAGE_LOC_LEN,
5052 u1H2CAoacRsvdPageParm);
5053 }
5054 }
5055 #endif /* CONFIG_PNO_SUPPORT */
5056 #endif /* CONFIG_WOWLAN */
5057 }
5058
5059 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)5060 void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
5061 {
5062 struct hal_ops *pHalFunc = &padapter->hal_func;
5063 u8 u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};
5064 u8 ret = 0;
5065
5066
5067 RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);
5068
5069 SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);
5070 SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);
5071 ret = rtw_hal_fill_h2c_cmd(padapter,
5072 H2C_FW_DBG_MSG_PKT,
5073 H2C_FW_DBG_MSG_PKT_LEN,
5074 u1H2C_fw_dbg_msg_pkt_parm);
5075
5076 }
5077 #endif /*DBG_FW_DEBUG_MSG_PKT*/
5078
5079 /*#define DBG_GET_RSVD_PAGE*/
rtw_hal_get_rsvd_page(_adapter * adapter,u32 page_offset,u32 page_num,u8 * buffer,u32 buffer_size)5080 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
5081 u32 page_num, u8 *buffer, u32 buffer_size)
5082 {
5083 u32 addr = 0, size = 0, count = 0;
5084 u32 page_size = 0, data_low = 0, data_high = 0;
5085 u16 txbndy = 0, offset = 0;
5086 u8 i = 0;
5087 bool rst = _FALSE;
5088
5089 #ifdef DBG_LA_MODE
5090 struct registry_priv *registry_par = &adapter->registrypriv;
5091
5092 if(registry_par->la_mode_en == 1) {
5093 RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);
5094 return rst;
5095 }
5096 #endif
5097 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5098
5099 addr = page_offset * page_size;
5100 size = page_num * page_size;
5101
5102 if (buffer_size < size) {
5103 RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
5104 __func__, buffer_size, size);
5105 return rst;
5106 }
5107 #ifdef RTW_HALMAC
5108 if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
5109 rst = _FALSE;
5110 else
5111 rst = _TRUE;
5112 #else
5113 txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
5114
5115 offset = (txbndy + page_offset) * page_size / 8;
5116 count = (buffer_size / 8) + 1;
5117
5118 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
5119
5120 for (i = 0 ; i < count ; i++) {
5121 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
5122 data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
5123 data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
5124 _rtw_memcpy(buffer + (i * 8),
5125 &data_low, sizeof(data_low));
5126 _rtw_memcpy(buffer + ((i * 8) + 4),
5127 &data_high, sizeof(data_high));
5128 }
5129 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
5130 rst = _TRUE;
5131 #endif /*RTW_HALMAC*/
5132
5133 #ifdef DBG_GET_RSVD_PAGE
5134 RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
5135 __func__, page_offset, page_num, addr, size);
5136 RTW_INFO_DUMP("\n", buffer, size);
5137 RTW_INFO(" ==================================================\n");
5138 #endif
5139 return rst;
5140 }
5141
rtw_dump_rsvd_page(void * sel,_adapter * adapter,u8 page_offset,u8 page_num)5142 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
5143 {
5144 #if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG)
5145 u32 page_size = 0;
5146 u8 *buffer = NULL;
5147 u32 buf_size = 0;
5148
5149 if (page_num == 0)
5150 return;
5151
5152 RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");
5153 RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
5154
5155 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5156 if (page_size) {
5157 buf_size = page_size * page_num;
5158 buffer = rtw_zvmalloc(buf_size);
5159
5160 if (buffer) {
5161 rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
5162 RTW_DUMP_SEL(sel, buffer, buf_size);
5163 rtw_vmfree(buffer, buf_size);
5164 } else
5165 RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
5166 } else
5167 RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
5168
5169 RTW_PRINT_SEL(sel, "==========================\n");
5170 #endif
5171 }
5172
5173 #ifdef CONFIG_SUPPORT_FIFO_DUMP
rtw_dump_fifo(void * sel,_adapter * adapter,u8 fifo_sel,u32 fifo_addr,u32 fifo_size)5174 void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
5175 {
5176 u8 *buffer = NULL;
5177 u32 buff_size = 0;
5178 static const char * const fifo_sel_str[] = {
5179 "TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
5180 };
5181
5182 if (fifo_sel > 5) {
5183 RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
5184 return;
5185 }
5186
5187 RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
5188 RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
5189
5190 if (fifo_size) {
5191 buff_size = RND4(fifo_size);
5192 buffer = rtw_zvmalloc(buff_size);
5193 if (buffer == NULL)
5194 buff_size = 0;
5195 }
5196
5197 rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
5198
5199 if (buffer) {
5200 RTW_DUMP_SEL(sel, buffer, fifo_size);
5201 rtw_vmfree(buffer, buff_size);
5202 }
5203
5204 RTW_PRINT_SEL(sel, "==========================\n");
5205 }
5206 #endif
5207
5208 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)5209 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
5210 {
5211 RTW_INFO("%s: Set 0x690=0x00\n", __func__);
5212 rtw_write8(adapter, REG_WOW_CTRL,
5213 (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
5214 RTW_PRINT("%s: Release RXDMA\n", __func__);
5215 rtw_write32(adapter, REG_RXPKT_NUM,
5216 (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
5217 }
5218 #if defined(CONFIG_RTL8188E)
rtw_hal_disable_tx_report(_adapter * adapter)5219 static void rtw_hal_disable_tx_report(_adapter *adapter)
5220 {
5221 rtw_write8(adapter, REG_TX_RPT_CTRL,
5222 ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
5223 RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5224 }
5225
rtw_hal_enable_tx_report(_adapter * adapter)5226 static void rtw_hal_enable_tx_report(_adapter *adapter)
5227 {
5228 rtw_write8(adapter, REG_TX_RPT_CTRL,
5229 ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
5230 RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5231 }
5232 #endif
rtw_hal_release_rx_dma(_adapter * adapter)5233 static void rtw_hal_release_rx_dma(_adapter *adapter)
5234 {
5235 u32 val32 = 0;
5236
5237 val32 = rtw_read32(adapter, REG_RXPKT_NUM);
5238
5239 rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
5240
5241 RTW_INFO("%s, [0x%04x]: 0x%08x\n",
5242 __func__, REG_RXPKT_NUM, (u32)(val32 & (~RW_RELEASE_EN)));
5243 }
5244
rtw_hal_pause_rx_dma(_adapter * adapter)5245 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
5246 {
5247 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
5248 u8 ret = 0;
5249 s8 trycnt = 100;
5250 u32 tmp = 0;
5251 int res = 0;
5252 /* RX DMA stop */
5253 RTW_PRINT("Pause DMA\n");
5254 rtw_write32(adapter, REG_RXPKT_NUM,
5255 (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
5256 do {
5257 if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
5258 #ifdef CONFIG_USB_HCI
5259 /* stop interface before leave */
5260 if (_TRUE == hal->usb_intf_start) {
5261 rtw_intf_stop(adapter);
5262 RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
5263 RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
5264 }
5265 #endif /* CONFIG_USB_HCI */
5266
5267 RTW_PRINT("RX_DMA_IDLE is true\n");
5268 ret = _SUCCESS;
5269 break;
5270 }
5271 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5272 else {
5273 res = RecvOnePkt(adapter);
5274 RTW_PRINT("RecvOnePkt Result: %d\n", res);
5275 }
5276 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
5277
5278 #ifdef CONFIG_USB_HCI
5279 else {
5280 /* to avoid interface start repeatedly */
5281 if (_FALSE == hal->usb_intf_start)
5282 rtw_intf_start(adapter);
5283 }
5284 #endif /* CONFIG_USB_HCI */
5285 } while (trycnt--);
5286
5287 if (trycnt < 0) {
5288 tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
5289
5290 RTW_PRINT("Stop RX DMA failed......\n");
5291 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
5292 RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
5293 __func__, rtw_read16(adapter, REG_RXPKTNUM));
5294 #else
5295 RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
5296 __func__, ((tmp & 0xFF00) >> 8));
5297 #endif
5298 if (tmp & BIT(3))
5299 RTW_PRINT("%s, RX DMA has req\n",
5300 __func__);
5301 else
5302 RTW_PRINT("%s, RX DMA no req\n",
5303 __func__);
5304 ret = _FAIL;
5305 }
5306
5307 return ret;
5308 }
5309
5310 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5311 #ifndef RTW_HALMAC
rtw_hal_enable_cpwm2(_adapter * adapter)5312 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
5313 {
5314 u8 ret = 0;
5315 int res = 0;
5316 u32 tmp = 0;
5317 #ifdef CONFIG_GPIO_WAKEUP
5318 return _SUCCESS;
5319 #else
5320 RTW_PRINT("%s\n", __func__);
5321
5322 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5323 if (!res)
5324 RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
5325 else
5326 RTW_INFO("sdio_local_read fail\n");
5327
5328 tmp = SDIO_HIMR_CPWM2_MSK;
5329
5330 res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5331
5332 if (!res) {
5333 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5334 RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
5335 ret = _SUCCESS;
5336 } else {
5337 RTW_INFO("sdio_local_write fail\n");
5338 ret = _FAIL;
5339 }
5340 return ret;
5341 #endif /* CONFIG_CPIO_WAKEUP */
5342 }
5343 #endif
5344 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
5345 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
5346
5347 #ifdef CONFIG_WOWLAN
5348 /*
5349 * rtw_hal_check_wow_ctrl
5350 * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
5351 * If 0x1C7 == 0 (for 3081), WOW enable successful.
5352 * _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
5353 * If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
5354 */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)5355 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
5356 {
5357 u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
5358 u8 mstatus = 0;
5359 u8 reason = 0xFF;
5360 u8 trycnt = 25;
5361 u8 res = _FALSE;
5362
5363 if (IS_HARDWARE_TYPE_JAGUAR2(adapter) || IS_HARDWARE_TYPE_JAGUAR3(adapter)) {
5364 if (chk_type) {
5365 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5366 RTW_INFO("%s reason:0x%02x\n", __func__, reason);
5367
5368 while (reason && trycnt > 1) {
5369 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5370 RTW_PRINT("Loop index: %d :0x%02x\n",
5371 trycnt, reason);
5372 trycnt--;
5373 rtw_msleep_os(20);
5374 }
5375 if (!reason)
5376 res = _TRUE;
5377 else
5378 res = _FALSE;
5379 } else {
5380 /* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
5381 fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
5382 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
5383 RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
5384
5385 while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
5386 rtw_msleep_os(20);
5387 fe1_imr = rtw_read32(adapter, REG_FE1IMR);
5388 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
5389 RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
5390 trycnt, fe1_imr, rxpkt_num);
5391 trycnt--;
5392 }
5393
5394 if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
5395 res = _FALSE;
5396 else
5397 res = _TRUE;
5398 }
5399 } else {
5400 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5401 RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
5402
5403
5404 if (chk_type) {
5405 while (!(mstatus & BIT1) && trycnt > 1) {
5406 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5407 RTW_PRINT("Loop index: %d :0x%02x\n",
5408 trycnt, mstatus);
5409 trycnt--;
5410 rtw_msleep_os(20);
5411 }
5412 if (mstatus & BIT1)
5413 res = _TRUE;
5414 else
5415 res = _FALSE;
5416 } else {
5417 while (mstatus & BIT1 && trycnt > 1) {
5418 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5419 RTW_PRINT("Loop index: %d :0x%02x\n",
5420 trycnt, mstatus);
5421 trycnt--;
5422 rtw_msleep_os(20);
5423 }
5424
5425 if (mstatus & BIT1)
5426 res = _FALSE;
5427 else
5428 res = _TRUE;
5429 }
5430 }
5431
5432 RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
5433 __func__, chk_type, res, (25 - trycnt));
5434 return res;
5435 }
5436
5437 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_check_pno_enabled(_adapter * adapter)5438 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
5439 {
5440 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5441 u8 res = 0, count = 0;
5442 u8 ret = _FALSE;
5443
5444 if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
5445 res = rtw_read8(adapter, REG_PNO_STATUS);
5446 while (!(res & BIT(7)) && count < 25) {
5447 RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
5448 count, res);
5449 res = rtw_read8(adapter, REG_PNO_STATUS);
5450 count++;
5451 rtw_msleep_os(2);
5452 }
5453 if (res & BIT(7))
5454 ret = _TRUE;
5455 else
5456 ret = _FALSE;
5457 RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
5458 }
5459 return ret;
5460 }
5461 #endif
5462
rtw_hal_backup_rate(_adapter * adapter)5463 static void rtw_hal_backup_rate(_adapter *adapter)
5464 {
5465 RTW_INFO("%s\n", __func__);
5466 /* backup data rate to register 0x8b for wowlan FW */
5467 rtw_write8(adapter, 0x8d, 1);
5468 rtw_write8(adapter, 0x8c, 0);
5469 rtw_write8(adapter, 0x8f, 0x40);
5470 rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
5471 }
5472
5473 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)5474 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
5475 {
5476 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5477 int cam_id, index = 0;
5478 u8 *addr = NULL;
5479
5480 if (!MLME_IS_STA(adapter))
5481 return;
5482
5483 addr = get_bssid(pmlmepriv);
5484
5485 if (addr == NULL) {
5486 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
5487 return;
5488 }
5489
5490 rtw_clean_dk_section(adapter);
5491
5492 do {
5493 cam_id = rtw_camid_search(adapter, addr, index, 1);
5494
5495 if (cam_id == -1)
5496 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
5497 else
5498 rtw_sec_cam_swap(adapter, cam_id, index);
5499
5500 index++;
5501 } while (index < 4);
5502
5503 rtw_write8(adapter, REG_SECCFG, 0xcc);
5504 }
5505
rtw_hal_update_gtk_offload_info(_adapter * adapter)5506 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
5507 {
5508 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5509 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5510 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5511 struct security_priv *psecuritypriv = &adapter->securitypriv;
5512 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5513 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
5514 _irqL irqL;
5515 u8 get_key[16];
5516 u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;
5517 u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
5518
5519 if (!MLME_IS_STA(adapter))
5520 return;
5521
5522 _rtw_memset(get_key, 0, sizeof(get_key));
5523 _rtw_memcpy(&replay_count,
5524 paoac_rpt->replay_counter_eapol_key, 8);
5525
5526 /*read gtk key index*/
5527 gtk_id = paoac_rpt->key_index;
5528 aoac_rpt_ver = paoac_rpt->version_info;
5529
5530 if (aoac_rpt_ver == 0) {
5531 /* initial verison */
5532 if (gtk_id == 5)
5533 has_rekey = _FALSE;
5534 else
5535 has_rekey = _TRUE;
5536 } else if (aoac_rpt_ver >= 1) {
5537 /* Add krack patch */
5538 if (gtk_id == 5)
5539 RTW_WARN("%s FW check iv fail\n", __func__);
5540
5541 if (aoac_rpt_ver == 1)
5542 RTW_WARN("%s aoac report version should be update to v2\n", __func__);
5543
5544 /* Fix key id mismatch */
5545 if (aoac_rpt_ver == 2)
5546 has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;
5547 }
5548
5549 if (has_rekey == _FALSE) {
5550 RTW_INFO("%s no rekey event happened.\n", __func__);
5551 } else if (has_rekey == _TRUE) {
5552 RTW_INFO("%s update security key.\n", __func__);
5553 /*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
5554 rtw_sec_read_cam_ent(adapter, gtk_id,
5555 NULL, NULL, get_key);
5556 rtw_clean_hw_dk_cam(adapter);
5557
5558 if (_rtw_camid_is_gk(adapter, gtk_id)) {
5559 _enter_critical_bh(&cam_ctl->lock, &irqL);
5560 _rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
5561 get_key, 16);
5562 _exit_critical_bh(&cam_ctl->lock, &irqL);
5563 } else {
5564 struct setkey_parm parm_gtk;
5565
5566 parm_gtk.algorithm = paoac_rpt->security_type;
5567 parm_gtk.keyid = gtk_id;
5568 _rtw_memcpy(parm_gtk.key, get_key, 16);
5569 setkey_hdl(adapter, (u8 *)&parm_gtk);
5570 }
5571
5572 /*update key into related sw variable and sec-cam cache*/
5573 psecuritypriv->dot118021XGrpKeyid = gtk_id;
5574 _rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
5575 get_key, 16);
5576 /* update SW TKIP TX/RX MIC value */
5577 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
5578 offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
5579 _rtw_memcpy(
5580 &psecuritypriv->dot118021XGrptxmickey[gtk_id],
5581 &(paoac_rpt->group_key[offset]),
5582 RTW_TKIP_MIC_LEN);
5583
5584 offset = RTW_KEK_LEN;
5585 _rtw_memcpy(
5586 &psecuritypriv->dot118021XGrprxmickey[gtk_id],
5587 &(paoac_rpt->group_key[offset]),
5588 RTW_TKIP_MIC_LEN);
5589 }
5590 RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
5591 KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
5592 }
5593
5594 /* Update broadcast RX IV */
5595 if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
5596 sz = sizeof(psecuritypriv->iv_seq[0]);
5597 for (i = 0 ; i < 4 ; i++) {
5598 _rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
5599 tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
5600 pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
5601 _rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
5602 }
5603 }
5604
5605 rtw_clean_dk_section(adapter);
5606
5607 rtw_write8(adapter, REG_SECCFG, 0x0c);
5608
5609 #ifdef CONFIG_GTK_OL_DBG
5610 /* if (gtk_keyindex != 5) */
5611 dump_sec_cam(RTW_DBGDUMP, adapter);
5612 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
5613 #endif
5614 }
5615 #endif /*CONFIG_GTK_OL*/
5616
rtw_dump_aoac_rpt(_adapter * adapter)5617 static void rtw_dump_aoac_rpt(_adapter *adapter)
5618 {
5619 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5620 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5621 int i = 0;
5622
5623 RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
5624 RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
5625 paoac_rpt->replay_counter_eapol_key, 8);
5626 RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
5627 RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
5628 RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
5629 RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
5630 paoac_rpt->wow_pattern_idx);
5631 RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
5632 RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);
5633 RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
5634 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
5635 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
5636 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
5637 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
5638 }
5639
rtw_hal_get_aoac_rpt(_adapter * adapter)5640 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
5641 {
5642 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5643 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5644 u32 page_offset = 0, page_number = 0;
5645 u32 page_size = 0, buf_size = 0;
5646 u8 *buffer = NULL;
5647 u8 i = 0, tmp = 0;
5648 int ret = -1;
5649
5650 /* read aoac report from rsvd page */
5651 page_offset = pwrctl->wowlan_aoac_rpt_loc;
5652 page_number = 1;
5653
5654 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5655 buf_size = page_size * page_number;
5656
5657 buffer = rtw_zvmalloc(buf_size);
5658
5659 if (buffer == NULL) {
5660 RTW_ERR("%s buffer allocate failed size(%d)\n",
5661 __func__, buf_size);
5662 return;
5663 }
5664
5665 RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
5666
5667 ret = rtw_hal_get_rsvd_page(adapter, page_offset,
5668 page_number, buffer, buf_size);
5669
5670 if (ret == _FALSE) {
5671 RTW_ERR("%s get aoac report failed\n", __func__);
5672 rtw_warn_on(1);
5673 goto _exit;
5674 }
5675
5676 _rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
5677 _rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
5678
5679 for (i = 0 ; i < 4 ; i++) {
5680 tmp = paoac_rpt->replay_counter_eapol_key[i];
5681 paoac_rpt->replay_counter_eapol_key[i] =
5682 paoac_rpt->replay_counter_eapol_key[7 - i];
5683 paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
5684 }
5685
5686 rtw_dump_aoac_rpt(adapter);
5687
5688 _exit:
5689 if (buffer)
5690 rtw_vmfree(buffer, buf_size);
5691 }
5692
rtw_hal_update_tx_iv(_adapter * adapter)5693 static void rtw_hal_update_tx_iv(_adapter *adapter)
5694 {
5695 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5696 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5697 struct sta_info *psta;
5698 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
5699 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5700 struct security_priv *psecpriv = &adapter->securitypriv;
5701
5702 u16 val16 = 0;
5703 u32 val32 = 0;
5704 u64 txiv = 0;
5705 u8 *pval = NULL;
5706
5707 psta = rtw_get_stainfo(&adapter->stapriv,
5708 get_my_bssid(&pmlmeinfo->network));
5709
5710 /* Update TX iv data. */
5711 pval = (u8 *)&paoac_rpt->iv;
5712
5713 if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
5714 val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
5715 ((u16)(paoac_rpt->iv[0]) << 8);
5716 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5717 ((u32)(paoac_rpt->iv[5]) << 8) +
5718 ((u32)(paoac_rpt->iv[6]) << 16) +
5719 ((u32)(paoac_rpt->iv[7]) << 24);
5720 } else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
5721 val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
5722 ((u16)(paoac_rpt->iv[1]) << 8);
5723 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5724 ((u32)(paoac_rpt->iv[5]) << 8) +
5725 ((u32)(paoac_rpt->iv[6]) << 16) +
5726 ((u32)(paoac_rpt->iv[7]) << 24);
5727 }
5728
5729 if (psta) {
5730 txiv = val16 + ((u64)val32 << 16);
5731 if (txiv != 0)
5732 psta->dot11txpn.val = txiv;
5733 }
5734 }
5735
rtw_hal_update_sw_security_info(_adapter * adapter)5736 static void rtw_hal_update_sw_security_info(_adapter *adapter)
5737 {
5738 struct security_priv *psecpriv = &adapter->securitypriv;
5739 u8 sz = sizeof (psecpriv->iv_seq);
5740
5741 rtw_hal_update_tx_iv(adapter);
5742 #ifdef CONFIG_GTK_OL
5743 if (psecpriv->binstallKCK_KEK == _TRUE &&
5744 (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5745 rtw_hal_update_gtk_offload_info(adapter);
5746 #else
5747 _rtw_memset(psecpriv->iv_seq, 0, sz);
5748 #endif
5749 }
5750 #ifdef CONFIG_CUSTOM_PULSE
rtw_hal_set_gpio_custom_cmd(_adapter * adapter,u8 enable)5751 static u8 rtw_hal_set_gpio_custom_cmd(_adapter *adapter, u8 enable)
5752 {
5753 u8 H2CGpioCustomParm[H2C_GPIO_CUSTOM_LEN] = {0};
5754 u8 customid = 0x2, special_wakeup_reason = RX_MAGIC_PKT, custom_for_wakeup_reason=0x1;
5755 u8 ret = _FAIL;
5756
5757 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5758
5759 if(enable) {
5760 SET_H2CCMD_CUSTOMERID(H2CGpioCustomParm, customid);
5761 SET_H2CCMD_SPECIAL_WAKE_REASON(H2CGpioCustomParm, special_wakeup_reason);
5762 SET_H2CCMD_CUSTOM_WAKE_REASON(H2CGpioCustomParm, custom_for_wakeup_reason);
5763
5764 ret = rtw_hal_fill_h2c_cmd(adapter,
5765 H2C_GPIO_CUSTOM,
5766 H2C_GPIO_CUSTOM_LEN,
5767 H2CGpioCustomParm);
5768 RTW_DBG("%s(): H2C_cmd=%x, cmd=%02x, %02x, %02x\n", __func__, H2C_GPIO_CUSTOM,
5769 H2CGpioCustomParm[0], H2CGpioCustomParm[1], H2CGpioCustomParm[2]);
5770 }
5771
5772 return ret;
5773 }
5774 #endif /* CONFIG_CUSTOM_PULSE */
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)5775 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
5776 {
5777 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
5778 u8 adopt = 1, check_period = 5;
5779 u8 ret = _FAIL;
5780 u8 hw_port = rtw_hal_get_port(adapter);
5781
5782 SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
5783 SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
5784 SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
5785 SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
5786 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5787 SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);
5788 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5789 #else
5790 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5791 #endif
5792 ret = rtw_hal_fill_h2c_cmd(adapter,
5793 H2C_KEEP_ALIVE,
5794 H2C_KEEP_ALIVE_CTRL_LEN,
5795 u1H2CKeepAliveParm);
5796
5797 return ret;
5798 }
5799
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)5800 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
5801 {
5802 u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
5803 u8 adopt = 1, check_period = 100, trypkt_num = 5;
5804 u8 ret = _FAIL;
5805 struct registry_priv *pregistry = &adapter->registrypriv;
5806 u8 hw_port = rtw_hal_get_port(adapter);
5807
5808 SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
5809 SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
5810 if (!(pregistry->wakeup_event & BIT(2)))
5811 SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt);
5812 SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
5813 SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
5814 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5815 SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);
5816 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5817 #else
5818 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5819 #endif
5820
5821 ret = rtw_hal_fill_h2c_cmd(adapter,
5822 H2C_DISCON_DECISION,
5823 H2C_DISCON_DECISION_LEN,
5824 u1H2CDisconDecisionParm);
5825 return ret;
5826 }
5827
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)5828 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
5829 {
5830 struct registry_priv *registry_par = &adapter->registrypriv;
5831 struct security_priv *psecpriv = &adapter->securitypriv;
5832 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5833 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5834
5835 u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
5836 u8 discont_wake = 0, gpionum = 0, gpio_dur = 0, no_wake = 0;
5837 u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
5838 u8 sdio_wakeup_enable = 1;
5839 u8 gpio_high_active = 0;
5840 u8 magic_pkt = 0;
5841 u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
5842 u8 ret = _FAIL;
5843 #ifdef CONFIG_DIS_UPHY
5844 u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;
5845 #endif /* CONFIG_DIS_UPHY */
5846
5847 #ifdef CONFIG_GPIO_WAKEUP
5848 gpio_high_active = ppwrpriv->is_high_active;
5849 gpionum = ppwrpriv->wowlan_gpio_index;
5850 sdio_wakeup_enable = 0;
5851 #endif /* CONFIG_GPIO_WAKEUP */
5852
5853 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
5854 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5855 no_wake = 1;
5856
5857 if (!ppwrpriv->wowlan_pno_enable &&
5858 registry_par->wakeup_event & BIT(0) && !no_wake)
5859 magic_pkt = enable;
5860
5861 if (registry_par->wakeup_event & BIT(2) && !no_wake)
5862 discont_wake = enable;
5863
5864 RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
5865 enable, change_unit);
5866
5867 /* time = (gpio_dur/2) * gpio_unit, default:256 ms */
5868 if (enable && change_unit) {
5869 gpio_dur = 0x40;
5870 gpio_unit = 1;
5871 gpio_pulse_en = 1;
5872 }
5873
5874 #ifdef CONFIG_PLATFORM_ARM_RK3188
5875 if (enable) {
5876 gpio_pulse_en = 1;
5877 gpio_pulse_cnt = 0x04;
5878 }
5879 #endif
5880
5881 SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
5882 if(!no_wake)
5883 SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
5884 SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
5885 SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
5886 SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
5887 SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
5888
5889 #ifdef CONFIG_GTK_OL
5890 if (psecpriv->binstallKCK_KEK == _TRUE &&
5891 (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5892 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
5893 else
5894 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
5895 #else
5896 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
5897 #endif
5898 SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
5899 SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
5900 SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
5901
5902 SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
5903 SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
5904
5905 SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
5906 SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
5907
5908 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
5909 if (enable)
5910 SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5911 #endif
5912
5913 #ifdef CONFIG_DIS_UPHY
5914 if (enable) {
5915 dis_uphy = 1;
5916 /* time unit: 0 -> ms, 1 -> 256 ms*/
5917 dis_uphy_unit = 1;
5918 dis_uphy_time = 0x4;
5919 }
5920
5921 SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
5922 SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
5923 SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
5924 if (ppwrpriv->hst2dev_high_active == 1)
5925 SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
5926 #ifdef CONFIG_RTW_ONE_PIN_GPIO
5927 SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5928 SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
5929 SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
5930 #else
5931 SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
5932 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
5933 #endif /* CONFIG_DIS_UPHY */
5934
5935
5936 ret = rtw_hal_fill_h2c_cmd(adapter,
5937 H2C_WOWLAN,
5938 H2C_WOWLAN_LEN,
5939 u1H2CWoWlanCtrlParm);
5940 return ret;
5941 }
5942
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)5943 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
5944 {
5945 struct security_priv *psecuritypriv = &(adapter->securitypriv);
5946 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5947 struct registry_priv *pregistrypriv = &adapter->registrypriv;
5948 u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
5949 u8 ret = _FAIL, count = 0, no_wake = 0;
5950 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5951
5952 RTW_INFO("%s(): enable=%d\n", __func__, enable);
5953
5954 if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&
5955 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5956 no_wake = 1;
5957 if(no_wake) {
5958 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5959 u1H2CRemoteWakeCtrlParm, enable);
5960 } else {
5961 if (!ppwrpriv->wowlan_pno_enable) {
5962 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5963 u1H2CRemoteWakeCtrlParm, enable);
5964 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5965 u1H2CRemoteWakeCtrlParm, 1);
5966 #ifdef CONFIG_GTK_OL
5967 if (psecuritypriv->binstallKCK_KEK == _TRUE &&
5968 (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) {
5969 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5970 u1H2CRemoteWakeCtrlParm, 1);
5971 } else {
5972 RTW_INFO("no kck kek\n");
5973 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5974 u1H2CRemoteWakeCtrlParm, 0);
5975 }
5976 #endif /* CONFIG_GTK_OL */
5977
5978 #ifdef CONFIG_IPV6
5979 if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
5980 RTW_INFO("enable NS offload\n");
5981 SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
5982 u1H2CRemoteWakeCtrlParm, enable);
5983 }
5984
5985 /*
5986 * filter NetBios name service pkt to avoid being waked-up
5987 * by this kind of unicast pkt this exceptional modification
5988 * is used for match competitor's behavior
5989 */
5990
5991 SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
5992 u1H2CRemoteWakeCtrlParm, enable);
5993 #endif /*CONFIG_IPV6*/
5994 #if 0 /* replaced by WOWLAN pattern match */
5995 #ifdef CONFIG_RTL8192F
5996 if (IS_HARDWARE_TYPE_8192F(adapter)){
5997 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
5998 u1H2CRemoteWakeCtrlParm, enable);
5999 }
6000 #endif /* CONFIG_RTL8192F */
6001 #endif
6002 if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
6003 (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
6004 (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
6005 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6006 u1H2CRemoteWakeCtrlParm, 0);
6007 } else {
6008 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6009 u1H2CRemoteWakeCtrlParm, 1);
6010 }
6011
6012 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
6013 #ifdef CONFIG_GTK_OL
6014 if(_rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))
6015 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
6016 u1H2CRemoteWakeCtrlParm, enable);
6017 #endif /* CONFIG_GTK_OL */
6018 if (IS_HARDWARE_TYPE_8188E(adapter) ||
6019 IS_HARDWARE_TYPE_8812(adapter)) {
6020 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
6021 u1H2CRemoteWakeCtrlParm, 0);
6022 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6023 u1H2CRemoteWakeCtrlParm, 1);
6024 }
6025 }
6026
6027 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
6028 u1H2CRemoteWakeCtrlParm, 1);
6029 }
6030 #ifdef CONFIG_PNO_SUPPORT
6031 else {
6032 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
6033 u1H2CRemoteWakeCtrlParm, enable);
6034 SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
6035 u1H2CRemoteWakeCtrlParm, enable);
6036 }
6037 #endif
6038
6039 #ifdef CONFIG_P2P_WOWLAN
6040 if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
6041 RTW_INFO("P2P OFFLOAD ENABLE\n");
6042 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
6043 } else {
6044 RTW_INFO("P2P OFFLOAD DISABLE\n");
6045 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
6046 }
6047 #endif /* CONFIG_P2P_WOWLAN */
6048 }
6049
6050
6051 ret = rtw_hal_fill_h2c_cmd(adapter,
6052 H2C_REMOTE_WAKE_CTRL,
6053 H2C_REMOTE_WAKE_CTRL_LEN,
6054 u1H2CRemoteWakeCtrlParm);
6055 return ret;
6056 }
6057
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)6058 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
6059 {
6060 u8 ret = _FAIL;
6061 u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
6062
6063 RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
6064 __func__, group_alg, pairwise_alg);
6065 SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
6066 pairwise_alg);
6067 SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
6068 group_alg);
6069
6070 ret = rtw_hal_fill_h2c_cmd(adapter,
6071 H2C_AOAC_GLOBAL_INFO,
6072 H2C_AOAC_GLOBAL_INFO_LEN,
6073 u1H2CAOACGlobalInfoParm);
6074
6075 return ret;
6076 }
6077
6078 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)6079 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
6080 PRSVDPAGE_LOC rsvdpageloc, u8 enable)
6081 {
6082 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6083 u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
6084 u8 res = 0, count = 0, ret = _FAIL;
6085
6086 RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
6087 __func__, rsvdpageloc->LocProbePacket,
6088 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
6089
6090 SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
6091 SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
6092 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
6093 rsvdpageloc->LocScanInfo);
6094 SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
6095 rsvdpageloc->LocProbePacket);
6096 /*
6097 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
6098 rsvdpageloc->LocSSIDInfo);
6099 */
6100 ret = rtw_hal_fill_h2c_cmd(adapter,
6101 H2C_D0_SCAN_OFFLOAD_INFO,
6102 H2C_SCAN_OFFLOAD_CTRL_LEN,
6103 u1H2CScanOffloadInfoParm);
6104 return ret;
6105 }
6106 #endif /* CONFIG_PNO_SUPPORT */
6107
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)6108 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
6109 {
6110 struct security_priv *psecpriv = &padapter->securitypriv;
6111 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
6112 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6113 struct registry_priv *pregistry = &padapter->registrypriv;
6114 u8 pkt_type = 0, no_wake = 0;
6115
6116 if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&
6117 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
6118 no_wake = 1;
6119
6120 RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
6121
6122 rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
6123
6124 if (enable) {
6125 if(!no_wake)
6126 rtw_hal_set_global_info_cmd(padapter,
6127 psecpriv->dot118021XGrpPrivacy,
6128 psecpriv->dot11PrivacyAlgrthm);
6129
6130 if (!(ppwrpriv->wowlan_pno_enable)) {
6131 if (!no_wake)
6132 rtw_hal_set_disconnect_decision_cmd(padapter,
6133 enable);
6134 #ifdef CONFIG_ARP_KEEP_ALIVE
6135 if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
6136 (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
6137 pkt_type = 0;
6138 else
6139 pkt_type = 1;
6140 #else
6141 pkt_type = 0;
6142 #endif /* CONFIG_ARP_KEEP_ALIVE */
6143 if(!no_wake)
6144 rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
6145 }
6146 #ifdef CONFIG_PNO_SUPPORT
6147 rtw_hal_check_pno_enabled(padapter);
6148 #endif /* CONFIG_PNO_SUPPORT */
6149 } else {
6150 #if 0
6151 {
6152 u32 PageSize = 0;
6153 rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
6154 dump_TX_FIFO(padapter, 4, PageSize);
6155 }
6156 #endif
6157 }
6158 #ifdef CONFIG_CUSTOM_PULSE
6159 rtw_hal_set_gpio_custom_cmd(padapter, enable);
6160 #endif /* CONFIG_CUSTOM_PULSE */
6161 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
6162 RTW_PRINT("-%s()-\n", __func__);
6163 }
6164 #endif /* CONFIG_WOWLAN */
6165
6166 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)6167 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
6168 {
6169 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6170
6171 u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
6172 u8 gpionum = 0, gpio_dur = 0;
6173 u8 gpio_pulse = enable;
6174 u8 sdio_wakeup_enable = 1;
6175 u8 gpio_high_active = 0;
6176 u8 ret = _FAIL;
6177
6178 #ifdef CONFIG_GPIO_WAKEUP
6179 gpio_high_active = ppwrpriv->is_high_active;
6180 gpionum = ppwrpriv->wowlan_gpio_index;
6181 sdio_wakeup_enable = 0;
6182 #endif /*CONFIG_GPIO_WAKEUP*/
6183
6184 RTW_INFO("%s(): enable=%d\n", __func__, enable);
6185
6186 SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
6187 gpionum);
6188 SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
6189 gpio_pulse);
6190 SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
6191 gpio_high_active);
6192 SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
6193 enable);
6194 SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
6195 gpio_dur);
6196
6197 ret = rtw_hal_fill_h2c_cmd(adapter,
6198 H2C_AP_WOW_GPIO_CTRL,
6199 H2C_AP_WOW_GPIO_CTRL_LEN,
6200 u1H2CAPWoWlanCtrlParm);
6201
6202 return ret;
6203 }
6204
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)6205 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6206 {
6207 u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
6208 u8 ret = _FAIL;
6209
6210 RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
6211
6212 SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
6213
6214 ret = rtw_hal_fill_h2c_cmd(adapter,
6215 H2C_AP_OFFLOAD,
6216 H2C_AP_OFFLOAD_LEN,
6217 u1H2CAPOffloadCtrlParm);
6218
6219 return ret;
6220 }
6221
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)6222 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
6223 {
6224 u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
6225 u8 ret = _FAIL;
6226
6227 RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
6228
6229 SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
6230 #ifndef CONFIG_USB_HCI
6231 SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
6232 #endif /*CONFIG_USB_HCI*/
6233 SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
6234
6235 if (enable)
6236 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
6237 else
6238 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
6239
6240 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
6241 H2C_AP_PS_LEN, ap_ps_parm);
6242
6243 return ret;
6244 }
6245
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)6246 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
6247 PRSVDPAGE_LOC rsvdpageloc)
6248 {
6249 struct hal_ops *pHalFunc = &padapter->hal_func;
6250 u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
6251 u8 ret = _FAIL, header = 0;
6252
6253 if (pHalFunc->fill_h2c_cmd == NULL) {
6254 RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
6255 return;
6256 }
6257
6258 header = rtw_read8(padapter, REG_BCNQ_BDNY);
6259
6260 RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
6261 rsvdpageloc->LocApOffloadBCN,
6262 rsvdpageloc->LocProbeRsp,
6263 header);
6264
6265 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
6266 rsvdpageloc->LocApOffloadBCN + header);
6267
6268 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
6269 H2C_BCN_RSVDPAGE_LEN, rsvdparm);
6270
6271 if (ret == _FAIL)
6272 RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
6273
6274 rtw_msleep_os(10);
6275
6276 _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
6277
6278 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
6279 rsvdpageloc->LocProbeRsp + header);
6280
6281 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
6282 H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
6283
6284 if (ret == _FAIL)
6285 RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
6286
6287 rtw_msleep_os(10);
6288 }
6289
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)6290 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
6291 {
6292 rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
6293 rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
6294 rtw_hal_set_ap_ps_cmd(padapter, enable);
6295 }
6296
rtw_hal_ap_wow_enable(_adapter * padapter)6297 static void rtw_hal_ap_wow_enable(_adapter *padapter)
6298 {
6299 struct security_priv *psecuritypriv = &padapter->securitypriv;
6300 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6301 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6302 struct sta_info *psta = NULL;
6303 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6304 #ifdef DBG_CHECK_FW_PS_STATE
6305 struct dvobj_priv *psdpriv = padapter->dvobj;
6306 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6307 #endif /*DBG_CHECK_FW_PS_STATE*/
6308 int res;
6309 u16 media_status_rpt;
6310 #ifdef CONFIG_GPIO_WAKEUP
6311 u8 val8 = 0;
6312 #endif
6313
6314 RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
6315 #ifdef DBG_CHECK_FW_PS_STATE
6316 if (rtw_fw_ps_state(padapter) == _FAIL) {
6317 pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
6318 RTW_PRINT("wowlan enable no leave 32k\n");
6319 }
6320 #endif /*DBG_CHECK_FW_PS_STATE*/
6321
6322 /* 1. Download WOWLAN FW*/
6323 rtw_hal_fw_dl(padapter, _TRUE);
6324
6325 media_status_rpt = RT_MEDIA_CONNECT;
6326 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6327 (u8 *)&media_status_rpt);
6328
6329 issue_beacon(padapter, 0);
6330
6331 rtw_msleep_os(2);
6332 #if defined(CONFIG_RTL8188E)
6333 if (IS_HARDWARE_TYPE_8188E(padapter))
6334 rtw_hal_disable_tx_report(padapter);
6335 #endif
6336 /* RX DMA stop */
6337 res = rtw_hal_pause_rx_dma(padapter);
6338 if (res == _FAIL)
6339 RTW_PRINT("[WARNING] pause RX DMA fail\n");
6340
6341 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6342 /* Enable CPWM2 only. */
6343 res = rtw_hal_enable_cpwm2(padapter);
6344 if (res == _FAIL)
6345 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6346 #endif
6347
6348 #ifdef CONFIG_GPIO_WAKEUP
6349 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6350 rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6351 rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6352 #else
6353 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6354 if (pwrctrlpriv->is_high_active == 0)
6355 rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6356 else
6357 rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index,
6358 GPIO_OUTPUT_LOW);
6359 #else
6360 val8 = (pwrpriv->is_high_active == 0) ? 1 : 0;
6361 rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8);
6362 rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6363 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow suspend and %s_ACTIVE.\n",
6364 __func__, pwrpriv->wowlan_gpio_index,
6365 pwrpriv->wowlan_gpio_output_state ? "HIGH" : "LOW",
6366 pwrpriv->is_high_active ? "HIGI" : "LOW");
6367 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
6368 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6369 #endif /* CONFIG_GPIO_WAKEUP */
6370
6371 /* 5. Set Enable WOWLAN H2C command. */
6372 RTW_PRINT("Set Enable AP WOWLan cmd\n");
6373 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
6374
6375 rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
6376 #ifdef CONFIG_USB_HCI
6377 rtw_mi_intf_stop(padapter);
6378 #endif
6379 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
6380 /* Invoid SE0 reset signal during suspending*/
6381 rtw_write8(padapter, REG_RSV_CTRL, 0x20);
6382 if (IS_8188F(pHalData->version_id) == FALSE
6383 && IS_8188GTV(pHalData->version_id) == FALSE)
6384 rtw_write8(padapter, REG_RSV_CTRL, 0x60);
6385 #endif
6386 }
6387
rtw_hal_ap_wow_disable(_adapter * padapter)6388 static void rtw_hal_ap_wow_disable(_adapter *padapter)
6389 {
6390 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6391 #ifdef DBG_CHECK_FW_PS_STATE
6392 struct dvobj_priv *psdpriv = padapter->dvobj;
6393 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6394 #endif /*DBG_CHECK_FW_PS_STATE*/
6395 u16 media_status_rpt;
6396
6397 RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
6398 /* 1. Read wakeup reason*/
6399 pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
6400
6401 RTW_PRINT("wakeup_reason: 0x%02x\n",
6402 pwrctl->wowlan_wake_reason);
6403
6404 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
6405
6406 rtw_msleep_os(2);
6407 #ifdef DBG_CHECK_FW_PS_STATE
6408 if (rtw_fw_ps_state(padapter) == _FAIL) {
6409 pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
6410 RTW_PRINT("wowlan enable no leave 32k\n");
6411 }
6412 #endif /*DBG_CHECK_FW_PS_STATE*/
6413
6414 #if defined(CONFIG_RTL8188E)
6415 if (IS_HARDWARE_TYPE_8188E(padapter))
6416 rtw_hal_enable_tx_report(padapter);
6417 #endif
6418
6419 rtw_hal_force_enable_rxdma(padapter);
6420
6421 rtw_hal_fw_dl(padapter, _FALSE);
6422
6423 #ifdef CONFIG_GPIO_WAKEUP
6424 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6425 rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6426 #else
6427 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6428 if (pwrctl->is_high_active == 0)
6429 rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6430 else
6431 rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index
6432 , GPIO_OUTPUT_LOW);
6433 #else
6434 rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index,
6435 pwrctl->wowlan_gpio_output_state);
6436 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow resume and %s_ACTIVE.\n",
6437 __func__, pwrctl->wowlan_gpio_index,
6438 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
6439 pwrctl->is_high_active ? "HIGI" : "LOW");
6440 #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
6441 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6442 #endif /* CONFIG_GPIO_WAKEUP */
6443 media_status_rpt = RT_MEDIA_CONNECT;
6444
6445 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6446 (u8 *)&media_status_rpt);
6447
6448 issue_beacon(padapter, 0);
6449 }
6450 #endif /*CONFIG_AP_WOWLAN*/
6451
6452 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)6453 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
6454 {
6455 u8 *ssid_ie;
6456 sint ssid_len_ori;
6457 int len_diff = 0;
6458
6459 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
6460
6461 /* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
6462
6463 if (ssid_ie && ssid_len_ori > 0) {
6464 switch (hidden_ssid_mode) {
6465 case 1: {
6466 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
6467 u32 remain_len = 0;
6468
6469 remain_len = ies_len - (next_ie - ies);
6470
6471 ssid_ie[1] = 0;
6472 _rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
6473 len_diff -= ssid_len_ori;
6474
6475 break;
6476 }
6477 case 2:
6478 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
6479 break;
6480 default:
6481 break;
6482 }
6483 }
6484
6485 return len_diff;
6486 }
6487
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)6488 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
6489 {
6490 /* struct xmit_frame *pmgntframe; */
6491 /* struct pkt_attrib *pattrib; */
6492 /* unsigned char *pframe; */
6493 struct rtw_ieee80211_hdr *pwlanhdr;
6494 unsigned short *fctrl;
6495 unsigned int rate_len;
6496 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6497 u32 pktlen;
6498 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6499 /* _irqL irqL;
6500 * struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6501 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6502 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6503 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6504 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6505 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
6506 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6507 #ifdef CONFIG_P2P
6508 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6509 #endif /* CONFIG_P2P */
6510
6511 /* for debug */
6512 u8 *dbgbuf = pframe;
6513 u8 dbgbufLen = 0, index = 0;
6514
6515 RTW_INFO("%s\n", __FUNCTION__);
6516 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6517 /* _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6518 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6519
6520 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6521
6522
6523 fctrl = &(pwlanhdr->frame_ctl);
6524 *(fctrl) = 0;
6525
6526 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6527 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6528 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6529
6530 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6531 /* pmlmeext->mgnt_seq++; */
6532 set_frame_sub_type(pframe, WIFI_BEACON);
6533
6534 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6535 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6536
6537 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6538 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6539 #ifdef CONFIG_P2P
6540 /* for P2P : Primary Device Type & Device Name */
6541 u32 wpsielen = 0, insert_len = 0;
6542 u8 *wpsie = NULL;
6543 wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
6544
6545 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
6546 uint wps_offset, remainder_ielen;
6547 u8 *premainder_ie, *pframe_wscie;
6548
6549 wps_offset = (uint)(wpsie - cur_network->IEs);
6550
6551 premainder_ie = wpsie + wpsielen;
6552
6553 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6554
6555 #ifdef CONFIG_IOCTL_CFG80211
6556 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6557 if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
6558 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
6559 pframe += wps_offset;
6560 pktlen += wps_offset;
6561
6562 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6563 pframe += pmlmepriv->wps_beacon_ie_len;
6564 pktlen += pmlmepriv->wps_beacon_ie_len;
6565
6566 /* copy remainder_ie to pframe */
6567 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6568 pframe += remainder_ielen;
6569 pktlen += remainder_ielen;
6570 } else {
6571 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6572 pframe += cur_network->IELength;
6573 pktlen += cur_network->IELength;
6574 }
6575 } else
6576 #endif /* CONFIG_IOCTL_CFG80211 */
6577 {
6578 pframe_wscie = pframe + wps_offset;
6579 _rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
6580 pframe += (wps_offset + wpsielen);
6581 pktlen += (wps_offset + wpsielen);
6582
6583 /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6584 /* Primary Device Type */
6585 /* Type: */
6586 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6587 insert_len += 2;
6588
6589 /* Length: */
6590 *(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
6591 insert_len += 2;
6592
6593 /* Value: */
6594 /* Category ID */
6595 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6596 insert_len += 2;
6597
6598 /* OUI */
6599 *(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
6600 insert_len += 4;
6601
6602 /* Sub Category ID */
6603 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6604 insert_len += 2;
6605
6606
6607 /* Device Name */
6608 /* Type: */
6609 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6610 insert_len += 2;
6611
6612 /* Length: */
6613 *(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
6614 insert_len += 2;
6615
6616 /* Value: */
6617 _rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
6618 insert_len += pwdinfo->device_name_len;
6619
6620
6621 /* update wsc ie length */
6622 *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
6623
6624 /* pframe move to end */
6625 pframe += insert_len;
6626 pktlen += insert_len;
6627
6628 /* copy remainder_ie to pframe */
6629 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6630 pframe += remainder_ielen;
6631 pktlen += remainder_ielen;
6632 }
6633 } else
6634 #endif /* CONFIG_P2P */
6635 {
6636 int len_diff;
6637 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6638 len_diff = update_hidden_ssid(
6639 pframe + _BEACON_IE_OFFSET_
6640 , cur_network->IELength - _BEACON_IE_OFFSET_
6641 , pmlmeinfo->hidden_ssid_mode
6642 );
6643 pframe += (cur_network->IELength + len_diff);
6644 pktlen += (cur_network->IELength + len_diff);
6645 }
6646 #if 0
6647 {
6648 u8 *wps_ie;
6649 uint wps_ielen;
6650 u8 sr = 0;
6651 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
6652 pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
6653 if (wps_ie && wps_ielen > 0)
6654 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6655 if (sr != 0)
6656 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6657 else
6658 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6659 }
6660 #endif
6661 #ifdef CONFIG_P2P
6662 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6663 u32 len;
6664 #ifdef CONFIG_IOCTL_CFG80211
6665 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6666 len = pmlmepriv->p2p_beacon_ie_len;
6667 if (pmlmepriv->p2p_beacon_ie && len > 0)
6668 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6669 } else
6670 #endif /* CONFIG_IOCTL_CFG80211 */
6671 {
6672 len = build_beacon_p2p_ie(pwdinfo, pframe);
6673 }
6674
6675 pframe += len;
6676 pktlen += len;
6677
6678 #ifdef CONFIG_WFD
6679 len = rtw_append_beacon_wfd_ie(padapter, pframe);
6680 pframe += len;
6681 pktlen += len;
6682 #endif
6683
6684 }
6685 #endif /* CONFIG_P2P */
6686
6687 goto _issue_bcn;
6688
6689 }
6690
6691 /* below for ad-hoc mode */
6692
6693 /* timestamp will be inserted by hardware */
6694 pframe += 8;
6695 pktlen += 8;
6696
6697 /* beacon interval: 2 bytes */
6698
6699 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6700
6701 pframe += 2;
6702 pktlen += 2;
6703
6704 /* capability info: 2 bytes */
6705
6706 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6707
6708 pframe += 2;
6709 pktlen += 2;
6710
6711 /* SSID */
6712 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6713
6714 /* supported rates... */
6715 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6716 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6717
6718 /* DS parameter set */
6719 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6720
6721 /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6722 {
6723 u8 erpinfo = 0;
6724 u32 ATIMWindow;
6725 /* IBSS Parameter Set... */
6726 /* ATIMWindow = cur->Configuration.ATIMWindow; */
6727 ATIMWindow = 0;
6728 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6729
6730 /* ERP IE */
6731 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
6732 }
6733
6734
6735 /* EXTERNDED SUPPORTED RATE */
6736 if (rate_len > 8)
6737 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6738
6739
6740 /* todo:HT for adhoc */
6741
6742 _issue_bcn:
6743
6744 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6745 /* pmlmepriv->update_bcn = _FALSE;
6746 *
6747 * _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6748 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6749
6750 *pLength = pktlen;
6751 #if 0
6752 /* printf dbg msg */
6753 dbgbufLen = pktlen;
6754 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6755
6756 for (index = 0; index < dbgbufLen; index++)
6757 printk("%x ", *(dbgbuf + index));
6758
6759 printk("\n");
6760 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6761
6762 #endif
6763 }
6764
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6765 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6766 {
6767 /* struct xmit_frame *pmgntframe; */
6768 /* struct pkt_attrib *pattrib; */
6769 /* unsigned char *pframe; */
6770 struct rtw_ieee80211_hdr *pwlanhdr;
6771 unsigned short *fctrl;
6772 unsigned char *mac;
6773 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6774 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6775 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6776 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6777 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
6778 u16 beacon_interval = 100;
6779 u16 capInfo = 0;
6780 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6781 u8 wpsie[255] = { 0x00 };
6782 u32 wpsielen = 0, p2pielen = 0;
6783 u32 pktlen;
6784 #ifdef CONFIG_WFD
6785 u32 wfdielen = 0;
6786 #endif
6787
6788 /* for debug */
6789 u8 *dbgbuf = pframe;
6790 u8 dbgbufLen = 0, index = 0;
6791
6792 RTW_INFO("%s\n", __FUNCTION__);
6793 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6794
6795 mac = adapter_mac_addr(padapter);
6796
6797 fctrl = &(pwlanhdr->frame_ctl);
6798 *(fctrl) = 0;
6799
6800 /* DA filled by FW */
6801 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6802 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6803
6804 /* Use the device address for BSSID field. */
6805 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6806
6807 SetSeqNum(pwlanhdr, 0);
6808 set_frame_sub_type(fctrl, WIFI_PROBERSP);
6809
6810 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6811 pframe += pktlen;
6812
6813
6814 /* timestamp will be inserted by hardware */
6815 pframe += 8;
6816 pktlen += 8;
6817
6818 /* beacon interval: 2 bytes */
6819 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6820 pframe += 2;
6821 pktlen += 2;
6822
6823 /* capability info: 2 bytes */
6824 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6825 capInfo |= cap_ShortPremble;
6826 capInfo |= cap_ShortSlot;
6827
6828 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6829 pframe += 2;
6830 pktlen += 2;
6831
6832
6833 /* SSID */
6834 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
6835
6836 /* supported rates... */
6837 /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6838 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
6839
6840 /* DS parameter set */
6841 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
6842
6843 #ifdef CONFIG_IOCTL_CFG80211
6844 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6845 if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6846 /* WPS IE */
6847 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6848 pktlen += pmlmepriv->wps_probe_resp_ie_len;
6849 pframe += pmlmepriv->wps_probe_resp_ie_len;
6850
6851 /* P2P IE */
6852 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6853 pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6854 pframe += pmlmepriv->p2p_probe_resp_ie_len;
6855 }
6856 } else
6857 #endif /* CONFIG_IOCTL_CFG80211 */
6858 {
6859
6860 /* Todo: WPS IE */
6861 /* Noted by Albert 20100907 */
6862 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6863
6864 wpsielen = 0;
6865 /* WPS OUI */
6866 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6867 wpsielen += 4;
6868
6869 /* WPS version */
6870 /* Type: */
6871 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6872 wpsielen += 2;
6873
6874 /* Length: */
6875 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6876 wpsielen += 2;
6877
6878 /* Value: */
6879 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
6880
6881 /* WiFi Simple Config State */
6882 /* Type: */
6883 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6884 wpsielen += 2;
6885
6886 /* Length: */
6887 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6888 wpsielen += 2;
6889
6890 /* Value: */
6891 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
6892
6893 /* Response Type */
6894 /* Type: */
6895 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6896 wpsielen += 2;
6897
6898 /* Length: */
6899 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6900 wpsielen += 2;
6901
6902 /* Value: */
6903 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6904
6905 /* UUID-E */
6906 /* Type: */
6907 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6908 wpsielen += 2;
6909
6910 /* Length: */
6911 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6912 wpsielen += 2;
6913
6914 /* Value: */
6915 if (pwdinfo->external_uuid == 0) {
6916 _rtw_memset(wpsie + wpsielen, 0x0, 16);
6917 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6918 } else
6919 _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6920 wpsielen += 0x10;
6921
6922 /* Manufacturer */
6923 /* Type: */
6924 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6925 wpsielen += 2;
6926
6927 /* Length: */
6928 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6929 wpsielen += 2;
6930
6931 /* Value: */
6932 _rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6933 wpsielen += 7;
6934
6935 /* Model Name */
6936 /* Type: */
6937 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
6938 wpsielen += 2;
6939
6940 /* Length: */
6941 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
6942 wpsielen += 2;
6943
6944 /* Value: */
6945 _rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
6946 wpsielen += 6;
6947
6948 /* Model Number */
6949 /* Type: */
6950 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
6951 wpsielen += 2;
6952
6953 /* Length: */
6954 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6955 wpsielen += 2;
6956
6957 /* Value: */
6958 wpsie[wpsielen++] = 0x31; /* character 1 */
6959
6960 /* Serial Number */
6961 /* Type: */
6962 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
6963 wpsielen += 2;
6964
6965 /* Length: */
6966 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
6967 wpsielen += 2;
6968
6969 /* Value: */
6970 _rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
6971 wpsielen += ETH_ALEN;
6972
6973 /* Primary Device Type */
6974 /* Type: */
6975 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6976 wpsielen += 2;
6977
6978 /* Length: */
6979 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6980 wpsielen += 2;
6981
6982 /* Value: */
6983 /* Category ID */
6984 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6985 wpsielen += 2;
6986
6987 /* OUI */
6988 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6989 wpsielen += 4;
6990
6991 /* Sub Category ID */
6992 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6993 wpsielen += 2;
6994
6995 /* Device Name */
6996 /* Type: */
6997 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6998 wpsielen += 2;
6999
7000 /* Length: */
7001 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
7002 wpsielen += 2;
7003
7004 /* Value: */
7005 _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
7006 wpsielen += pwdinfo->device_name_len;
7007
7008 /* Config Method */
7009 /* Type: */
7010 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
7011 wpsielen += 2;
7012
7013 /* Length: */
7014 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7015 wpsielen += 2;
7016
7017 /* Value: */
7018 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7019 wpsielen += 2;
7020
7021
7022 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7023
7024
7025 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
7026 pframe += p2pielen;
7027 pktlen += p2pielen;
7028 }
7029
7030 #ifdef CONFIG_WFD
7031 wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
7032 pframe += wfdielen;
7033 pktlen += wfdielen;
7034 #endif
7035
7036 *pLength = pktlen;
7037
7038 #if 0
7039 /* printf dbg msg */
7040 dbgbufLen = pktlen;
7041 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7042
7043 for (index = 0; index < dbgbufLen; index++)
7044 printk("%x ", *(dbgbuf + index));
7045
7046 printk("\n");
7047 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7048 #endif
7049 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7050 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7051 {
7052 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7053 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7054 u8 action = P2P_PUB_ACTION_ACTION;
7055 u32 p2poui = cpu_to_be32(P2POUI);
7056 u8 oui_subtype = P2P_GO_NEGO_RESP;
7057 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
7058 u8 p2pielen = 0, i;
7059 uint wpsielen = 0;
7060 u16 wps_devicepassword_id = 0x0000;
7061 uint wps_devicepassword_id_len = 0;
7062 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
7063 u16 len_channellist_attr = 0;
7064 u32 pktlen;
7065 u8 dialogToken = 0;
7066
7067 /* struct xmit_frame *pmgntframe; */
7068 /* struct pkt_attrib *pattrib; */
7069 /* unsigned char *pframe; */
7070 struct rtw_ieee80211_hdr *pwlanhdr;
7071 unsigned short *fctrl;
7072 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7073 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7074 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7075 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7076 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
7077
7078 #ifdef CONFIG_WFD
7079 u32 wfdielen = 0;
7080 #endif
7081
7082 /* for debug */
7083 u8 *dbgbuf = pframe;
7084 u8 dbgbufLen = 0, index = 0;
7085
7086 RTW_INFO("%s\n", __FUNCTION__);
7087 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7088
7089 fctrl = &(pwlanhdr->frame_ctl);
7090 *(fctrl) = 0;
7091
7092 /* RA, filled by FW */
7093 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7094 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7095 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7096
7097 SetSeqNum(pwlanhdr, 0);
7098 set_frame_sub_type(pframe, WIFI_ACTION);
7099
7100 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7101 pframe += pktlen;
7102
7103 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7104 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7105 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7106 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7107
7108 /* dialog token, filled by FW */
7109 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7110
7111 _rtw_memset(wpsie, 0x00, 255);
7112 wpsielen = 0;
7113
7114 /* WPS Section */
7115 wpsielen = 0;
7116 /* WPS OUI */
7117 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
7118 wpsielen += 4;
7119
7120 /* WPS version */
7121 /* Type: */
7122 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7123 wpsielen += 2;
7124
7125 /* Length: */
7126 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7127 wpsielen += 2;
7128
7129 /* Value: */
7130 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7131
7132 /* Device Password ID */
7133 /* Type: */
7134 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
7135 wpsielen += 2;
7136
7137 /* Length: */
7138 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7139 wpsielen += 2;
7140
7141 /* Value: */
7142 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
7143 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
7144 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
7145 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
7146 else
7147 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
7148 wpsielen += 2;
7149
7150 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7151
7152
7153 /* P2P IE Section. */
7154
7155 /* P2P OUI */
7156 p2pielen = 0;
7157 p2pie[p2pielen++] = 0x50;
7158 p2pie[p2pielen++] = 0x6F;
7159 p2pie[p2pielen++] = 0x9A;
7160 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7161
7162 /* Commented by Albert 20100908 */
7163 /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
7164 /* 1. Status */
7165 /* 2. P2P Capability */
7166 /* 3. Group Owner Intent */
7167 /* 4. Configuration Timeout */
7168 /* 5. Operating Channel */
7169 /* 6. Intended P2P Interface Address */
7170 /* 7. Channel List */
7171 /* 8. Device Info */
7172 /* 9. Group ID ( Only GO ) */
7173
7174
7175 /* ToDo: */
7176
7177 /* P2P Status */
7178 /* Type: */
7179 p2pie[p2pielen++] = P2P_ATTR_STATUS;
7180
7181 /* Length: */
7182 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7183 p2pielen += 2;
7184
7185 /* Value, filled by FW */
7186 p2pie[p2pielen++] = 1;
7187
7188 /* P2P Capability */
7189 /* Type: */
7190 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
7191
7192 /* Length: */
7193 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7194 p2pielen += 2;
7195
7196 /* Value: */
7197 /* Device Capability Bitmap, 1 byte */
7198
7199 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
7200 /* Commented by Albert 2011/03/08 */
7201 /* According to the P2P specification */
7202 /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
7203 p2pie[p2pielen++] = 0;
7204 } else {
7205 /* Be group owner or meet the error case */
7206 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
7207 }
7208
7209 /* Group Capability Bitmap, 1 byte */
7210 if (pwdinfo->persistent_supported)
7211 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
7212 else
7213 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
7214
7215 /* Group Owner Intent */
7216 /* Type: */
7217 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
7218
7219 /* Length: */
7220 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7221 p2pielen += 2;
7222
7223 /* Value: */
7224 if (pwdinfo->peer_intent & 0x01) {
7225 /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
7226 p2pie[p2pielen++] = (pwdinfo->intent << 1);
7227 } else {
7228 /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
7229 p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
7230 }
7231
7232
7233 /* Configuration Timeout */
7234 /* Type: */
7235 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7236
7237 /* Length: */
7238 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7239 p2pielen += 2;
7240
7241 /* Value: */
7242 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7243 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7244
7245 /* Operating Channel */
7246 /* Type: */
7247 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7248
7249 /* Length: */
7250 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7251 p2pielen += 2;
7252
7253 /* Value: */
7254 /* Country String */
7255 p2pie[p2pielen++] = 'X';
7256 p2pie[p2pielen++] = 'X';
7257
7258 /* The third byte should be set to 0x04. */
7259 /* Described in the "Operating Channel Attribute" section. */
7260 p2pie[p2pielen++] = 0x04;
7261
7262 /* Operating Class */
7263 if (pwdinfo->operating_channel <= 14) {
7264 /* Operating Class */
7265 p2pie[p2pielen++] = 0x51;
7266 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
7267 /* Operating Class */
7268 p2pie[p2pielen++] = 0x73;
7269 } else {
7270 /* Operating Class */
7271 p2pie[p2pielen++] = 0x7c;
7272 }
7273
7274 /* Channel Number */
7275 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7276
7277 /* Intended P2P Interface Address */
7278 /* Type: */
7279 p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
7280
7281 /* Length: */
7282 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7283 p2pielen += 2;
7284
7285 /* Value: */
7286 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7287 p2pielen += ETH_ALEN;
7288
7289 /* Channel List */
7290 /* Type: */
7291 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7292
7293 /* Country String(3) */
7294 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7295 /* + number of channels in all classes */
7296 len_channellist_attr = 3
7297 + (1 + 1) * (u16)ch_list->reg_classes
7298 + get_reg_classes_full_count(ch_list);
7299
7300 #ifdef CONFIG_CONCURRENT_MODE
7301 if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7302 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7303 else
7304 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7305
7306 #else
7307
7308 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7309
7310 #endif
7311 p2pielen += 2;
7312
7313 /* Value: */
7314 /* Country String */
7315 p2pie[p2pielen++] = 'X';
7316 p2pie[p2pielen++] = 'X';
7317
7318 /* The third byte should be set to 0x04. */
7319 /* Described in the "Operating Channel Attribute" section. */
7320 p2pie[p2pielen++] = 0x04;
7321
7322 /* Channel Entry List */
7323
7324 #ifdef CONFIG_CONCURRENT_MODE
7325 if (rtw_mi_check_status(padapter, MI_LINKED)) {
7326 u8 union_ch = rtw_mi_get_union_chan(padapter);
7327
7328 /* Operating Class */
7329 if (union_ch > 14) {
7330 if (union_ch >= 149)
7331 p2pie[p2pielen++] = 0x7c;
7332 else
7333 p2pie[p2pielen++] = 0x73;
7334 } else
7335 p2pie[p2pielen++] = 0x51;
7336
7337
7338 /* Number of Channels */
7339 /* Just support 1 channel and this channel is AP's channel */
7340 p2pie[p2pielen++] = 1;
7341
7342 /* Channel List */
7343 p2pie[p2pielen++] = union_ch;
7344 } else
7345 #endif /* CONFIG_CONCURRENT_MODE */
7346 {
7347 int i, j;
7348 for (j = 0; j < ch_list->reg_classes; j++) {
7349 /* Operating Class */
7350 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7351
7352 /* Number of Channels */
7353 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7354
7355 /* Channel List */
7356 for (i = 0; i < ch_list->reg_class[j].channels; i++)
7357 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7358 }
7359 }
7360
7361 /* Device Info */
7362 /* Type: */
7363 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
7364
7365 /* Length: */
7366 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
7367 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7368 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
7369 p2pielen += 2;
7370
7371 /* Value: */
7372 /* P2P Device Address */
7373 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7374 p2pielen += ETH_ALEN;
7375
7376 /* Config Method */
7377 /* This field should be big endian. Noted by P2P specification. */
7378
7379 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7380
7381 p2pielen += 2;
7382
7383 /* Primary Device Type */
7384 /* Category ID */
7385 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7386 p2pielen += 2;
7387
7388 /* OUI */
7389 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
7390 p2pielen += 4;
7391
7392 /* Sub Category ID */
7393 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7394 p2pielen += 2;
7395
7396 /* Number of Secondary Device Types */
7397 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
7398
7399 /* Device Name */
7400 /* Type: */
7401 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7402 p2pielen += 2;
7403
7404 /* Length: */
7405 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
7406 p2pielen += 2;
7407
7408 /* Value: */
7409 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
7410 p2pielen += pwdinfo->device_name_len;
7411
7412 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7413 /* Group ID Attribute */
7414 /* Type: */
7415 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
7416
7417 /* Length: */
7418 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
7419 p2pielen += 2;
7420
7421 /* Value: */
7422 /* p2P Device Address */
7423 _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
7424 p2pielen += ETH_ALEN;
7425
7426 /* SSID */
7427 _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
7428 p2pielen += pwdinfo->nego_ssidlen;
7429
7430 }
7431
7432 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7433
7434 #ifdef CONFIG_WFD
7435 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
7436 pframe += wfdielen;
7437 pktlen += wfdielen;
7438 #endif
7439
7440 *pLength = pktlen;
7441 #if 0
7442 /* printf dbg msg */
7443 dbgbufLen = pktlen;
7444 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7445
7446 for (index = 0; index < dbgbufLen; index++)
7447 printk("%x ", *(dbgbuf + index));
7448
7449 printk("\n");
7450 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7451 #endif
7452 }
7453
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7454 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7455 {
7456 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7457 u8 action = P2P_PUB_ACTION_ACTION;
7458 u32 p2poui = cpu_to_be32(P2POUI);
7459 u8 oui_subtype = P2P_INVIT_RESP;
7460 u8 p2pie[255] = { 0x00 };
7461 u8 p2pielen = 0, i;
7462 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
7463 u16 len_channellist_attr = 0;
7464 u32 pktlen;
7465 u8 dialogToken = 0;
7466 #ifdef CONFIG_WFD
7467 u32 wfdielen = 0;
7468 #endif
7469
7470 /* struct xmit_frame *pmgntframe; */
7471 /* struct pkt_attrib *pattrib; */
7472 /* unsigned char *pframe; */
7473 struct rtw_ieee80211_hdr *pwlanhdr;
7474 unsigned short *fctrl;
7475 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7476 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7477 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7478 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7479
7480 /* for debug */
7481 u8 *dbgbuf = pframe;
7482 u8 dbgbufLen = 0, index = 0;
7483
7484
7485 RTW_INFO("%s\n", __FUNCTION__);
7486 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7487
7488 fctrl = &(pwlanhdr->frame_ctl);
7489 *(fctrl) = 0;
7490
7491 /* RA fill by FW */
7492 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7493 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7494
7495 /* BSSID fill by FW */
7496 _rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
7497
7498 SetSeqNum(pwlanhdr, 0);
7499 set_frame_sub_type(pframe, WIFI_ACTION);
7500
7501 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7502 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7503
7504 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7505 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7506 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7507 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7508
7509 /* dialog token, filled by FW */
7510 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7511
7512 /* P2P IE Section. */
7513
7514 /* P2P OUI */
7515 p2pielen = 0;
7516 p2pie[p2pielen++] = 0x50;
7517 p2pie[p2pielen++] = 0x6F;
7518 p2pie[p2pielen++] = 0x9A;
7519 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7520
7521 /* Commented by Albert 20101005 */
7522 /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
7523 /* 1. Status */
7524 /* 2. Configuration Timeout */
7525 /* 3. Operating Channel ( Only GO ) */
7526 /* 4. P2P Group BSSID ( Only GO ) */
7527 /* 5. Channel List */
7528
7529 /* P2P Status */
7530 /* Type: */
7531 p2pie[p2pielen++] = P2P_ATTR_STATUS;
7532
7533 /* Length: */
7534 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7535 p2pielen += 2;
7536
7537 /* Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
7538 p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7539
7540 /* Configuration Timeout */
7541 /* Type: */
7542 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7543
7544 /* Length: */
7545 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7546 p2pielen += 2;
7547
7548 /* Value: */
7549 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7550 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7551
7552 /* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
7553 #if 0
7554 if (status_code == P2P_STATUS_SUCCESS) {
7555 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7556
7557 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7558 /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
7559 /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
7560 /* First one is operating channel attribute. */
7561 /* Second one is P2P Group BSSID attribute. */
7562
7563 /* Operating Channel */
7564 /* Type: */
7565 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7566
7567 /* Length: */
7568 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7569 p2pielen += 2;
7570
7571 /* Value: */
7572 /* Country String */
7573 p2pie[p2pielen++] = 'X';
7574 p2pie[p2pielen++] = 'X';
7575
7576 /* The third byte should be set to 0x04. */
7577 /* Described in the "Operating Channel Attribute" section. */
7578 p2pie[p2pielen++] = 0x04;
7579
7580 /* Operating Class */
7581 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
7582
7583 /* Channel Number */
7584 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7585
7586
7587 /* P2P Group BSSID */
7588 /* Type: */
7589 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
7590
7591 /* Length: */
7592 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7593 p2pielen += 2;
7594
7595 /* Value: */
7596 /* P2P Device Address for GO */
7597 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7598 p2pielen += ETH_ALEN;
7599
7600 }
7601
7602 /* Channel List */
7603 /* Type: */
7604 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7605
7606 /* Length: */
7607 /* Country String(3) */
7608 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7609 /* + number of channels in all classes */
7610 len_channellist_attr = 3
7611 + (1 + 1) * (u16)ch_list->reg_classes
7612 + get_reg_classes_full_count(ch_list);
7613
7614 #ifdef CONFIG_CONCURRENT_MODE
7615 if (rtw_mi_check_status(padapter, MI_LINKED))
7616 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7617 else
7618 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7619
7620 #else
7621
7622 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7623
7624 #endif
7625 p2pielen += 2;
7626
7627 /* Value: */
7628 /* Country String */
7629 p2pie[p2pielen++] = 'X';
7630 p2pie[p2pielen++] = 'X';
7631
7632 /* The third byte should be set to 0x04. */
7633 /* Described in the "Operating Channel Attribute" section. */
7634 p2pie[p2pielen++] = 0x04;
7635
7636 /* Channel Entry List */
7637 #ifdef CONFIG_CONCURRENT_MODE
7638 if (rtw_mi_check_status(padapter, MI_LINKED)) {
7639 u8 union_ch = rtw_mi_get_union_chan(padapter);
7640
7641 /* Operating Class */
7642 if (union_ch > 14) {
7643 if (union_ch >= 149)
7644 p2pie[p2pielen++] = 0x7c;
7645 else
7646 p2pie[p2pielen++] = 0x73;
7647
7648 } else
7649 p2pie[p2pielen++] = 0x51;
7650
7651
7652 /* Number of Channels */
7653 /* Just support 1 channel and this channel is AP's channel */
7654 p2pie[p2pielen++] = 1;
7655
7656 /* Channel List */
7657 p2pie[p2pielen++] = union_ch;
7658 } else
7659 #endif /* CONFIG_CONCURRENT_MODE */
7660 {
7661 int i, j;
7662 for (j = 0; j < ch_list->reg_classes; j++) {
7663 /* Operating Class */
7664 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7665
7666 /* Number of Channels */
7667 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7668
7669 /* Channel List */
7670 for (i = 0; i < ch_list->reg_class[j].channels; i++)
7671 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7672 }
7673 }
7674 }
7675 #endif
7676
7677 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7678
7679 #ifdef CONFIG_WFD
7680 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
7681 pframe += wfdielen;
7682 pktlen += wfdielen;
7683 #endif
7684
7685 *pLength = pktlen;
7686
7687 #if 0
7688 /* printf dbg msg */
7689 dbgbufLen = pktlen;
7690 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7691
7692 for (index = 0; index < dbgbufLen; index++)
7693 printk("%x ", *(dbgbuf + index));
7694
7695 printk("\n");
7696 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7697 #endif
7698 }
7699
7700
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7701 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7702 {
7703 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7704 u8 action = P2P_PUB_ACTION_ACTION;
7705 u8 dialogToken = 0;
7706 u32 p2poui = cpu_to_be32(P2POUI);
7707 u8 oui_subtype = P2P_PROVISION_DISC_RESP;
7708 u8 wpsie[100] = { 0x00 };
7709 u8 wpsielen = 0;
7710 u32 pktlen;
7711 #ifdef CONFIG_WFD
7712 u32 wfdielen = 0;
7713 #endif
7714
7715 /* struct xmit_frame *pmgntframe; */
7716 /* struct pkt_attrib *pattrib; */
7717 /* unsigned char *pframe; */
7718 struct rtw_ieee80211_hdr *pwlanhdr;
7719 unsigned short *fctrl;
7720 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7721 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7722 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7723 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7724
7725 /* for debug */
7726 u8 *dbgbuf = pframe;
7727 u8 dbgbufLen = 0, index = 0;
7728
7729 RTW_INFO("%s\n", __FUNCTION__);
7730
7731 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7732
7733 fctrl = &(pwlanhdr->frame_ctl);
7734 *(fctrl) = 0;
7735
7736 /* RA filled by FW */
7737 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7738 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7739 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7740
7741 SetSeqNum(pwlanhdr, 0);
7742 set_frame_sub_type(pframe, WIFI_ACTION);
7743
7744 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7745 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7746
7747 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7748 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7749 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7750 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7751 /* dialog token, filled by FW */
7752 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7753
7754 wpsielen = 0;
7755 /* WPS OUI */
7756 /* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
7757 RTW_PUT_BE32(wpsie, WPSOUI);
7758 wpsielen += 4;
7759
7760 #if 0
7761 /* WPS version */
7762 /* Type: */
7763 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7764 wpsielen += 2;
7765
7766 /* Length: */
7767 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7768 wpsielen += 2;
7769
7770 /* Value: */
7771 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7772 #endif
7773
7774 /* Config Method */
7775 /* Type: */
7776 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
7777 RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
7778 wpsielen += 2;
7779
7780 /* Length: */
7781 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
7782 RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
7783 wpsielen += 2;
7784
7785 /* Value: filled by FW, default value is PBC */
7786 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
7787 RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
7788 wpsielen += 2;
7789
7790 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7791
7792 #ifdef CONFIG_WFD
7793 wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
7794 pframe += wfdielen;
7795 pktlen += wfdielen;
7796 #endif
7797
7798 *pLength = pktlen;
7799
7800 /* printf dbg msg */
7801 #if 0
7802 dbgbufLen = pktlen;
7803 RTW_INFO("======> DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7804
7805 for (index = 0; index < dbgbufLen; index++)
7806 printk("%x ", *(dbgbuf + index));
7807
7808 printk("\n");
7809 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7810 #endif
7811 }
7812
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)7813 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
7814 {
7815 u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
7816 struct hal_ops *pHalFunc = &adapter->hal_func;
7817 u8 ret = _FAIL;
7818
7819 RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
7820 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
7821 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
7822 rsvdpageloc->LocPDRsp);
7823
7824 SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
7825 SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
7826 SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
7827 SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
7828 SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
7829
7830 /* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
7831 ret = rtw_hal_fill_h2c_cmd(adapter,
7832 H2C_P2P_OFFLOAD_RSVD_PAGE,
7833 H2C_P2PRSVDPAGE_LOC_LEN,
7834 u1H2CP2PRsvdPageParm);
7835
7836 return ret;
7837 }
7838
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)7839 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
7840 {
7841
7842 u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
7843 struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
7844 struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
7845 struct hal_ops *pHalFunc = &adapter->hal_func;
7846 u8 ret = _FAIL;
7847
7848 _rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
7849 RTW_INFO("%s\n", __func__);
7850 switch (pwdinfo->role) {
7851 case P2P_ROLE_DEVICE:
7852 RTW_INFO("P2P_ROLE_DEVICE\n");
7853 p2p_wowlan_offload->role = 0;
7854 break;
7855 case P2P_ROLE_CLIENT:
7856 RTW_INFO("P2P_ROLE_CLIENT\n");
7857 p2p_wowlan_offload->role = 1;
7858 break;
7859 case P2P_ROLE_GO:
7860 RTW_INFO("P2P_ROLE_GO\n");
7861 p2p_wowlan_offload->role = 2;
7862 break;
7863 default:
7864 RTW_INFO("P2P_ROLE_DISABLE\n");
7865 break;
7866 }
7867 p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
7868 p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
7869 offload_cmd = (u8 *)p2p_wowlan_offload;
7870 RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
7871
7872 ret = rtw_hal_fill_h2c_cmd(adapter,
7873 H2C_P2P_OFFLOAD,
7874 H2C_P2P_OFFLOAD_LEN,
7875 offload_cmd);
7876 return ret;
7877
7878 /* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
7879 }
7880 #endif /* CONFIG_P2P_WOWLAN */
7881
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)7882 void rtw_hal_construct_beacon(_adapter *padapter,
7883 u8 *pframe, u32 *pLength)
7884 {
7885 struct rtw_ieee80211_hdr *pwlanhdr;
7886 u16 *fctrl;
7887 u32 pktlen;
7888 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7889 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7890 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7891 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7892
7893
7894 /* RTW_INFO("%s\n", __FUNCTION__); */
7895
7896 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7897
7898 fctrl = &(pwlanhdr->frame_ctl);
7899 *(fctrl) = 0;
7900
7901 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7902 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7903 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7904
7905 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7906 /* pmlmeext->mgnt_seq++; */
7907 set_frame_sub_type(pframe, WIFI_BEACON);
7908
7909 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7910 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7911
7912 /* timestamp will be inserted by hardware */
7913 pframe += 8;
7914 pktlen += 8;
7915
7916 /* beacon interval: 2 bytes */
7917 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7918
7919 pframe += 2;
7920 pktlen += 2;
7921
7922 #if 0
7923 /* capability info: 2 bytes */
7924 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7925
7926 pframe += 2;
7927 pktlen += 2;
7928
7929 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7930 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7931 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
7932 _rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
7933
7934 goto _ConstructBeacon;
7935 }
7936
7937 /* below for ad-hoc mode */
7938
7939 /* SSID */
7940 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
7941
7942 /* supported rates... */
7943 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7944 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
7945
7946 /* DS parameter set */
7947 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
7948
7949 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
7950 u32 ATIMWindow;
7951 /* IBSS Parameter Set... */
7952 /* ATIMWindow = cur->Configuration.ATIMWindow; */
7953 ATIMWindow = 0;
7954 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
7955 }
7956
7957
7958 /* todo: ERP IE */
7959
7960
7961 /* EXTERNDED SUPPORTED RATE */
7962 if (rate_len > 8)
7963 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
7964
7965 /* todo:HT for adhoc */
7966
7967 _ConstructBeacon:
7968 #endif
7969
7970 if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
7971 RTW_ERR("beacon frame too large ,len(%d,%d)\n",
7972 (pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
7973 rtw_warn_on(1);
7974 return;
7975 }
7976
7977 *pLength = pktlen;
7978
7979 /* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
7980
7981 }
7982
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)7983 static void rtw_hal_construct_PSPoll(_adapter *padapter,
7984 u8 *pframe, u32 *pLength)
7985 {
7986 struct rtw_ieee80211_hdr *pwlanhdr;
7987 u16 *fctrl;
7988 u32 pktlen;
7989 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7990 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7991
7992 /* RTW_INFO("%s\n", __FUNCTION__); */
7993
7994 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7995
7996 /* Frame control. */
7997 fctrl = &(pwlanhdr->frame_ctl);
7998 *(fctrl) = 0;
7999 SetPwrMgt(fctrl);
8000 set_frame_sub_type(pframe, WIFI_PSPOLL);
8001
8002 /* AID. */
8003 set_duration(pframe, (pmlmeinfo->aid | 0xc000));
8004
8005 /* BSSID. */
8006 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8007
8008 /* TA. */
8009 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8010
8011 *pLength = 16;
8012 }
8013
8014
8015 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_construct_fw_dbg_msg_pkt(PADAPTER padapter,u8 * pframe,u32 * plength)8016 void rtw_hal_construct_fw_dbg_msg_pkt(
8017 PADAPTER padapter,
8018 u8 *pframe,
8019 u32 *plength)
8020 {
8021 struct rtw_ieee80211_hdr *pwlanhdr;
8022 u16 *fctrl;
8023 u32 pktlen;
8024 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8025 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8026 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8027 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8028 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8029
8030
8031 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8032
8033 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8034
8035 fctrl = &pwlanhdr->frame_ctl;
8036 *(fctrl) = 0;
8037
8038 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8039 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8040 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8041
8042 SetSeqNum(pwlanhdr, 0);
8043
8044 set_frame_sub_type(pframe, WIFI_DATA);
8045
8046 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8047
8048 *plength = pktlen;
8049 }
8050 #endif /*DBG_FW_DEBUG_MSG_PKT*/
8051
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)8052 void rtw_hal_construct_NullFunctionData(
8053 PADAPTER padapter,
8054 u8 *pframe,
8055 u32 *pLength,
8056 u8 bQoS,
8057 u8 AC,
8058 u8 bEosp,
8059 u8 bForcePowerSave)
8060 {
8061 struct rtw_ieee80211_hdr *pwlanhdr;
8062 u16 *fctrl;
8063 u32 pktlen;
8064 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8065 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8066 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8067 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8068 u8 *sta_addr = NULL;
8069 u8 bssid[ETH_ALEN] = {0};
8070
8071 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8072
8073 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8074
8075 fctrl = &pwlanhdr->frame_ctl;
8076 *(fctrl) = 0;
8077 if (bForcePowerSave)
8078 SetPwrMgt(fctrl);
8079
8080 sta_addr = get_my_bssid(&pmlmeinfo->network);
8081 if (NULL == sta_addr) {
8082 _rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
8083 sta_addr = bssid;
8084 }
8085
8086 switch (cur_network->network.InfrastructureMode) {
8087 case Ndis802_11Infrastructure:
8088 SetToDs(fctrl);
8089 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8090 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8091 _rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);
8092 break;
8093 case Ndis802_11APMode:
8094 SetFrDs(fctrl);
8095 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8096 _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8097 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8098 break;
8099 case Ndis802_11IBSS:
8100 default:
8101 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8102 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8103 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8104 break;
8105 }
8106
8107 SetSeqNum(pwlanhdr, 0);
8108 set_duration(pwlanhdr, 0);
8109
8110 if (bQoS == _TRUE) {
8111 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
8112
8113 set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
8114
8115 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
8116 SetPriority(&pwlanqoshdr->qc, AC);
8117 SetEOSP(&pwlanqoshdr->qc, bEosp);
8118
8119 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8120 } else {
8121 set_frame_sub_type(pframe, WIFI_DATA_NULL);
8122
8123 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8124 }
8125
8126 *pLength = pktlen;
8127 }
8128
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,BOOLEAN bHideSSID)8129 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
8130 BOOLEAN bHideSSID)
8131 {
8132 struct rtw_ieee80211_hdr *pwlanhdr;
8133 u16 *fctrl;
8134 u8 *mac, *bssid, *sta_addr;
8135 u32 pktlen;
8136 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8137 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8138 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
8139
8140 /*RTW_INFO("%s\n", __FUNCTION__);*/
8141
8142 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8143
8144 mac = adapter_mac_addr(padapter);
8145 bssid = cur_network->MacAddress;
8146 sta_addr = get_my_bssid(&pmlmeinfo->network);
8147
8148 fctrl = &(pwlanhdr->frame_ctl);
8149 *(fctrl) = 0;
8150 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8151 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8152 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8153
8154 SetSeqNum(pwlanhdr, 0);
8155 set_frame_sub_type(fctrl, WIFI_PROBERSP);
8156
8157 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8158 pframe += pktlen;
8159
8160 if (cur_network->IELength > MAX_IE_SZ)
8161 return;
8162
8163 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8164 pframe += cur_network->IELength;
8165 pktlen += cur_network->IELength;
8166
8167 *pLength = pktlen;
8168 }
8169
8170 #ifdef CONFIG_WOWLAN
rtw_hal_append_tkip_mic(PADAPTER padapter,u8 * pframe,u32 offset)8171 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
8172 u8 *pframe, u32 offset)
8173 {
8174 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8175 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8176 struct rtw_ieee80211_hdr *pwlanhdr;
8177 struct mic_data micdata;
8178 struct sta_info *psta = NULL;
8179 int res = 0;
8180
8181 u8 *payload = (u8 *)(pframe + offset);
8182
8183 u8 mic[8];
8184 u8 priority[4] = {0x0};
8185 u8 null_key[16] = {0x0};
8186
8187 RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
8188
8189 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8190
8191 psta = rtw_get_stainfo(&padapter->stapriv,
8192 get_my_bssid(&(pmlmeinfo->network)));
8193 if (psta != NULL) {
8194 res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
8195 null_key, 16);
8196 if (res == _TRUE)
8197 RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
8198 rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
8199 }
8200
8201 rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); /* DA */
8202
8203 rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
8204
8205 priority[0] = 0;
8206
8207 rtw_secmicappend(&micdata, &priority[0], 4);
8208
8209 rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
8210
8211 rtw_secgetmic(&micdata, &(mic[0]));
8212
8213 payload += 36;
8214
8215 _rtw_memcpy(payload, &(mic[0]), 8);
8216 }
8217 /*
8218 * Description:
8219 * Construct the ARP response packet to support ARP offload.
8220 * */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8221 static void rtw_hal_construct_ARPRsp(
8222 PADAPTER padapter,
8223 u8 *pframe,
8224 u32 *pLength,
8225 u8 *pIPAddress
8226 )
8227 {
8228 struct rtw_ieee80211_hdr *pwlanhdr;
8229 u16 *fctrl;
8230 u32 pktlen;
8231 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8232 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8233 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8234 struct security_priv *psecuritypriv = &padapter->securitypriv;
8235 static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
8236 u8 *pARPRspPkt = pframe;
8237 /* for TKIP Cal MIC */
8238 u8 *payload = pframe;
8239 u8 EncryptionHeadOverhead = 0, arp_offset = 0;
8240 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8241
8242 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8243
8244 fctrl = &pwlanhdr->frame_ctl;
8245 *(fctrl) = 0;
8246
8247 /* ------------------------------------------------------------------------- */
8248 /* MAC Header. */
8249 /* ------------------------------------------------------------------------- */
8250 SetFrameType(fctrl, WIFI_DATA);
8251 /* set_frame_sub_type(fctrl, 0); */
8252 SetToDs(fctrl);
8253 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8254 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8255 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8256
8257 SetSeqNum(pwlanhdr, 0);
8258 set_duration(pwlanhdr, 0);
8259 /* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
8260 /* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
8261 /* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
8262 /* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
8263 /* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
8264 /* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
8265
8266 /* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
8267 /* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
8268 #ifdef CONFIG_WAPI_SUPPORT
8269 *pLength = sMacHdrLng;
8270 #else
8271 *pLength = 24;
8272 #endif
8273 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8274 case _WEP40_:
8275 case _WEP104_:
8276 EncryptionHeadOverhead = 4;
8277 break;
8278 case _TKIP_:
8279 EncryptionHeadOverhead = 8;
8280 break;
8281 case _AES_:
8282 EncryptionHeadOverhead = 8;
8283 break;
8284 #ifdef CONFIG_WAPI_SUPPORT
8285 case _SMS4_:
8286 EncryptionHeadOverhead = 18;
8287 break;
8288 #endif
8289 default:
8290 EncryptionHeadOverhead = 0;
8291 }
8292
8293 if (EncryptionHeadOverhead > 0) {
8294 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8295 *pLength += EncryptionHeadOverhead;
8296 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8297 SetPrivacy(fctrl);
8298 }
8299
8300 /* ------------------------------------------------------------------------- */
8301 /* Frame Body. */
8302 /* ------------------------------------------------------------------------- */
8303 arp_offset = *pLength;
8304 pARPRspPkt = (u8 *)(pframe + arp_offset);
8305 payload = pARPRspPkt; /* Get Payload pointer */
8306 /* LLC header */
8307 _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
8308 *pLength += 8;
8309
8310 /* ARP element */
8311 pARPRspPkt += 8;
8312 SET_ARP_HTYPE(pARPRspPkt, 1);
8313 SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP); /* IP protocol */
8314 SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);
8315 SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);
8316 SET_ARP_OPER(pARPRspPkt, 2); /* ARP response */
8317 SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
8318 SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
8319 #ifdef CONFIG_ARP_KEEP_ALIVE
8320 if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
8321 SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
8322 SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
8323 } else
8324 #endif
8325 {
8326 SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,
8327 get_my_bssid(&(pmlmeinfo->network)));
8328 SET_ARP_TARGET_IP_ADDR(pARPRspPkt,
8329 pIPAddress);
8330 RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
8331 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
8332 RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
8333 IP_ARG(pIPAddress));
8334 }
8335
8336 *pLength += 28;
8337
8338 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8339 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8340 IS_HARDWARE_TYPE_8812(padapter)) {
8341 rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
8342 }
8343 *pLength += 8;
8344 }
8345 }
8346
8347 #ifdef CONFIG_IPV6
8348 /*
8349 * Description: Neighbor Discovery Offload.
8350 */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)8351 static void rtw_hal_construct_na_message(_adapter *padapter,
8352 u8 *pframe, u32 *pLength)
8353 {
8354 struct rtw_ieee80211_hdr *pwlanhdr = NULL;
8355 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8356 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8357 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8358 struct security_priv *psecuritypriv = &padapter->securitypriv;
8359
8360 u32 pktlen = 0;
8361 u16 *fctrl = NULL;
8362
8363 u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8364 u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
8365 u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
8366 u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
8367 u8 val8 = 0;
8368
8369 u8 *p_na_msg = pframe;
8370 /* for TKIP Cal MIC */
8371 u8 *payload = pframe;
8372 u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
8373 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8374
8375 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8376
8377 fctrl = &pwlanhdr->frame_ctl;
8378 *(fctrl) = 0;
8379
8380 /* ------------------------------------------------------------------------- */
8381 /* MAC Header. */
8382 /* ------------------------------------------------------------------------- */
8383 SetFrameType(fctrl, WIFI_DATA);
8384 SetToDs(fctrl);
8385 _rtw_memcpy(pwlanhdr->addr1,
8386 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8387 _rtw_memcpy(pwlanhdr->addr2,
8388 adapter_mac_addr(padapter), ETH_ALEN);
8389 _rtw_memcpy(pwlanhdr->addr3,
8390 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8391
8392 SetSeqNum(pwlanhdr, 0);
8393 set_duration(pwlanhdr, 0);
8394
8395 #ifdef CONFIG_WAPI_SUPPORT
8396 *pLength = sMacHdrLng;
8397 #else
8398 *pLength = 24;
8399 #endif
8400 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8401 case _WEP40_:
8402 case _WEP104_:
8403 EncryptionHeadOverhead = 4;
8404 break;
8405 case _TKIP_:
8406 EncryptionHeadOverhead = 8;
8407 break;
8408 case _AES_:
8409 EncryptionHeadOverhead = 8;
8410 break;
8411 #ifdef CONFIG_WAPI_SUPPORT
8412 case _SMS4_:
8413 EncryptionHeadOverhead = 18;
8414 break;
8415 #endif
8416 default:
8417 EncryptionHeadOverhead = 0;
8418 }
8419
8420 if (EncryptionHeadOverhead > 0) {
8421 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8422 *pLength += EncryptionHeadOverhead;
8423 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8424 SetPrivacy(fctrl);
8425 }
8426
8427 /* ------------------------------------------------------------------------- */
8428 /* Frame Body. */
8429 /* ------------------------------------------------------------------------- */
8430 na_msg_offset = *pLength;
8431 p_na_msg = (u8 *)(pframe + na_msg_offset);
8432 payload = p_na_msg; /* Get Payload pointer */
8433
8434 /* LLC header */
8435 val8 = sizeof(ns_hdr);
8436 _rtw_memcpy(p_na_msg, ns_hdr, val8);
8437 *pLength += val8;
8438 p_na_msg += val8;
8439
8440 /* IPv6 Header */
8441 /* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
8442 val8 = sizeof(ipv6_info);
8443 _rtw_memcpy(p_na_msg, ipv6_info, val8);
8444 *pLength += val8;
8445 p_na_msg += val8;
8446
8447 /* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
8448 val8 = sizeof(ipv6_contx);
8449 _rtw_memcpy(p_na_msg, ipv6_contx, val8);
8450 *pLength += val8;
8451 p_na_msg += val8;
8452
8453 /* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
8454 _rtw_memset(&(p_na_msg[*pLength]), 0, 32);
8455 *pLength += 32;
8456 p_na_msg += 32;
8457
8458 /* ICMPv6 */
8459 /* 1. Type : 0x88 (NA)
8460 * 2. Code : 0x00
8461 * 3. ChechSum : 0x00 0x00 (RSvd)
8462 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
8463 */
8464 val8 = sizeof(icmpv6_hdr);
8465 _rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
8466 *pLength += val8;
8467 p_na_msg += val8;
8468
8469 /* TA: 16 bytes*/
8470 _rtw_memset(&(p_na_msg[*pLength]), 0, 16);
8471 *pLength += 16;
8472 p_na_msg += 16;
8473
8474 /* ICMPv6 Target Link Layer Address */
8475 p_na_msg[0] = 0x02; /* type */
8476 p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
8477 *pLength += 2;
8478 p_na_msg += 2;
8479
8480 _rtw_memset(&(p_na_msg[*pLength]), 0, 6);
8481 *pLength += 6;
8482 p_na_msg += 6;
8483
8484 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8485 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8486 IS_HARDWARE_TYPE_8812(padapter)) {
8487 rtw_hal_append_tkip_mic(padapter, pframe,
8488 na_msg_offset);
8489 }
8490 *pLength += 8;
8491 }
8492 }
8493 /*
8494 * Description: Neighbor Discovery Protocol Information.
8495 */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)8496 static void rtw_hal_construct_ndp_info(_adapter *padapter,
8497 u8 *pframe, u32 *pLength)
8498 {
8499 struct mlme_ext_priv *pmlmeext = NULL;
8500 struct mlme_ext_info *pmlmeinfo = NULL;
8501 struct rtw_ndp_info ndp_info;
8502 u8 *pndp_info = pframe;
8503 u8 len = sizeof(struct rtw_ndp_info);
8504
8505 RTW_INFO("%s: len: %d\n", __func__, len);
8506
8507 pmlmeext = &padapter->mlmeextpriv;
8508 pmlmeinfo = &pmlmeext->mlmext_info;
8509
8510 _rtw_memset(pframe, 0, len);
8511 _rtw_memset(&ndp_info, 0, len);
8512
8513 ndp_info.enable = 1;
8514 ndp_info.check_remote_ip = 0;
8515 ndp_info.num_of_target_ip = 1;
8516
8517 _rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
8518 ETH_ALEN);
8519 _rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
8520 RTW_IPv6_ADDR_LEN);
8521
8522 _rtw_memcpy(pndp_info, &ndp_info, len);
8523 }
8524 #endif /* CONFIG_IPV6 */
8525
8526 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)8527 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
8528 u32 *pLength, pno_ssid_t *ssid)
8529 {
8530 struct rtw_ieee80211_hdr *pwlanhdr;
8531 u16 *fctrl;
8532 u32 pktlen;
8533 unsigned char *mac;
8534 unsigned char bssrate[NumRates];
8535 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8536 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8537 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8538 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8539 int bssrate_len = 0;
8540 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8541
8542 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8543 mac = adapter_mac_addr(padapter);
8544
8545 fctrl = &(pwlanhdr->frame_ctl);
8546 *(fctrl) = 0;
8547
8548 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8549 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8550
8551 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8552
8553 SetSeqNum(pwlanhdr, 0);
8554 set_frame_sub_type(pframe, WIFI_PROBEREQ);
8555
8556 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8557 pframe += pktlen;
8558
8559 if (ssid == NULL)
8560 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
8561 else {
8562 /* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
8563 pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
8564 }
8565
8566 get_rate_set(padapter, bssrate, &bssrate_len);
8567
8568 if (bssrate_len > 8) {
8569 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
8570 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
8571 } else
8572 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
8573
8574 *pLength = pktlen;
8575 }
8576
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)8577 static void rtw_hal_construct_PNO_info(_adapter *padapter,
8578 u8 *pframe, u32 *pLength)
8579 {
8580 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8581 int i;
8582
8583 u8 *pPnoInfoPkt = pframe;
8584 pPnoInfoPkt = (u8 *)(pframe + *pLength);
8585 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
8586
8587 pPnoInfoPkt += 1;
8588 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
8589
8590 pPnoInfoPkt += 3;
8591 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
8592
8593 pPnoInfoPkt += 4;
8594 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
8595
8596 pPnoInfoPkt += 4;
8597 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
8598
8599 pPnoInfoPkt += 4;
8600 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
8601
8602 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8603 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
8604
8605 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8606 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
8607
8608 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8609 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
8610
8611 pPnoInfoPkt += MAX_HIDDEN_AP;
8612
8613 /*
8614 SSID is located at 128th Byte in NLO info Page
8615 */
8616
8617 *pLength += 128;
8618 pPnoInfoPkt = pframe + 128;
8619
8620 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8621 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8622 pwrctl->pnlo_info->ssid_length[i]);
8623 *pLength += WLAN_SSID_MAXLEN;
8624 pPnoInfoPkt += WLAN_SSID_MAXLEN;
8625 }
8626 }
8627
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)8628 static void rtw_hal_construct_ssid_list(_adapter *padapter,
8629 u8 *pframe, u32 *pLength)
8630 {
8631 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8632 u8 *pSSIDListPkt = pframe;
8633 int i;
8634
8635 pSSIDListPkt = (u8 *)(pframe + *pLength);
8636
8637 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8638 _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8639 pwrctl->pnlo_info->ssid_length[i]);
8640
8641 *pLength += WLAN_SSID_MAXLEN;
8642 pSSIDListPkt += WLAN_SSID_MAXLEN;
8643 }
8644 }
8645
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)8646 static void rtw_hal_construct_scan_info(_adapter *padapter,
8647 u8 *pframe, u32 *pLength)
8648 {
8649 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8650 u8 *pScanInfoPkt = pframe;
8651 int i;
8652
8653 pScanInfoPkt = (u8 *)(pframe + *pLength);
8654
8655 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
8656
8657 *pLength += 1;
8658 pScanInfoPkt += 1;
8659 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
8660
8661
8662 *pLength += 1;
8663 pScanInfoPkt += 1;
8664 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
8665
8666
8667 *pLength += 1;
8668 pScanInfoPkt += 1;
8669 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
8670
8671 *pLength += 1;
8672 pScanInfoPkt += 1;
8673 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
8674
8675 *pLength += 1;
8676 pScanInfoPkt += 1;
8677 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
8678
8679 *pLength += 1;
8680 pScanInfoPkt += 1;
8681 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
8682
8683 *pLength += 1;
8684 pScanInfoPkt += 1;
8685 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
8686
8687 *pLength += 1;
8688 pScanInfoPkt += 1;
8689 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
8690
8691 *pLength += 8;
8692 pScanInfoPkt += 8;
8693
8694 for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
8695 _rtw_memcpy(pScanInfoPkt,
8696 &pwrctl->pscan_info->ssid_channel_info[i], 4);
8697 *pLength += 4;
8698 pScanInfoPkt += 4;
8699 }
8700 }
8701 #endif /* CONFIG_PNO_SUPPORT */
8702
8703 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)8704 static void rtw_hal_construct_GTKRsp(
8705 PADAPTER padapter,
8706 u8 *pframe,
8707 u32 *pLength
8708 )
8709 {
8710 struct rtw_ieee80211_hdr *pwlanhdr;
8711 u16 *fctrl;
8712 u32 pktlen;
8713 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8714 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8715 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8716 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8717 struct security_priv *psecuritypriv = &padapter->securitypriv;
8718 static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
8719 static u8 GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
8720 u8 *pGTKRspPkt = pframe;
8721 u8 EncryptionHeadOverhead = 0;
8722 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8723
8724 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8725
8726 fctrl = &pwlanhdr->frame_ctl;
8727 *(fctrl) = 0;
8728
8729 /* ------------------------------------------------------------------------- */
8730 /* MAC Header. */
8731 /* ------------------------------------------------------------------------- */
8732 SetFrameType(fctrl, WIFI_DATA);
8733 /* set_frame_sub_type(fctrl, 0); */
8734 SetToDs(fctrl);
8735
8736 _rtw_memcpy(pwlanhdr->addr1,
8737 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8738
8739 _rtw_memcpy(pwlanhdr->addr2,
8740 adapter_mac_addr(padapter), ETH_ALEN);
8741
8742 _rtw_memcpy(pwlanhdr->addr3,
8743 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8744
8745 SetSeqNum(pwlanhdr, 0);
8746 set_duration(pwlanhdr, 0);
8747
8748 #ifdef CONFIG_WAPI_SUPPORT
8749 *pLength = sMacHdrLng;
8750 #else
8751 *pLength = 24;
8752 #endif /* CONFIG_WAPI_SUPPORT */
8753
8754 /* ------------------------------------------------------------------------- */
8755 /* Security Header: leave space for it if necessary. */
8756 /* ------------------------------------------------------------------------- */
8757 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8758 case _WEP40_:
8759 case _WEP104_:
8760 EncryptionHeadOverhead = 4;
8761 break;
8762 case _TKIP_:
8763 EncryptionHeadOverhead = 8;
8764 break;
8765 case _AES_:
8766 EncryptionHeadOverhead = 8;
8767 break;
8768 #ifdef CONFIG_WAPI_SUPPORT
8769 case _SMS4_:
8770 EncryptionHeadOverhead = 18;
8771 break;
8772 #endif /* CONFIG_WAPI_SUPPORT */
8773 default:
8774 EncryptionHeadOverhead = 0;
8775 }
8776
8777 if (EncryptionHeadOverhead > 0) {
8778 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8779 *pLength += EncryptionHeadOverhead;
8780 /* SET_80211_HDR_WEP(pGTKRspPkt, 1); */ /* Suggested by CCW. */
8781 /* GTK's privacy bit is done by FW */
8782 /* SetPrivacy(fctrl); */
8783 }
8784 /* ------------------------------------------------------------------------- */
8785 /* Frame Body. */
8786 /* ------------------------------------------------------------------------- */
8787 pGTKRspPkt = (u8 *)(pframe + *pLength);
8788 /* LLC header */
8789 _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
8790 *pLength += 8;
8791
8792 /* GTK element */
8793 pGTKRspPkt += 8;
8794
8795 /* GTK frame body after LLC, part 1 */
8796 /* TKIP key_length = 32, AES key_length = 16 */
8797 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8798 GTKbody_a[8] = 0x20;
8799
8800 /* GTK frame body after LLC, part 1 */
8801 _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
8802 *pLength += 11;
8803 pGTKRspPkt += 11;
8804 /* GTK frame body after LLC, part 2 */
8805 _rtw_memset(&(pframe[*pLength]), 0, 88);
8806 *pLength += 88;
8807 pGTKRspPkt += 88;
8808
8809 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8810 *pLength += 8;
8811 }
8812 #endif /* CONFIG_GTK_OL */
8813
8814 #define PN_2_CCMPH(ch,key_id) ((ch) & 0x000000000000ffff) \
8815 | (((ch) & 0x0000ffffffff0000) << 16) \
8816 | (((key_id) << 30)) \
8817 | BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)8818 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
8819 u8 *pframe, u32 *pLength)
8820 {
8821 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8822 struct sta_priv *pstapriv = &adapter->stapriv;
8823 struct security_priv *psecuritypriv = &adapter->securitypriv;
8824 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
8825 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8826 struct sta_info *psta;
8827 struct stainfo_rxcache *prxcache;
8828 u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
8829 size_t sz = 0, total = 0;
8830 u64 ccmp_hdr = 0, tmp_key = 0;
8831
8832 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8833
8834 if (psta == NULL) {
8835 rtw_warn_on(1);
8836 return;
8837 }
8838
8839 prxcache = &psta->sta_recvpriv.rxcache;
8840 sz = sizeof(cur_dot11rxiv);
8841
8842 /* 3 SEC IV * 1 page */
8843 rtw_get_sec_iv(adapter, cur_dot11rxiv,
8844 get_my_bssid(&pmlmeinfo->network));
8845
8846 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
8847 *pLength += sz;
8848 pframe += sz;
8849
8850 _rtw_memset(&cur_dot11rxiv, 0, sz);
8851
8852 if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
8853 id = psecuritypriv->dot118021XGrpKeyid;
8854 tid_id = prxcache->last_tid;
8855 REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
8856 REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
8857 REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
8858 REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
8859 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
8860 *pLength += sz;
8861 pframe += sz;
8862
8863 _rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
8864 *pLength += sz;
8865 pframe += sz;
8866
8867 total = sizeof(psecuritypriv->iv_seq);
8868 total /= sizeof(psecuritypriv->iv_seq[0]);
8869
8870 for (i = 0 ; i < total ; i ++) {
8871 ccmp_hdr =
8872 le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
8873 _rtw_memset(&cur_dot11rxiv, 0, sz);
8874 if (ccmp_hdr != 0) {
8875 tmp_key = i;
8876 ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
8877 *(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
8878 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
8879 }
8880 *pLength += sz;
8881 pframe += sz;
8882 }
8883 }
8884 }
8885
rtw_hal_set_wow_fw_rsvd_page(_adapter * adapter,u8 * pframe,u16 index,u8 tx_desc,u32 page_size,u8 * page_num,u32 * total_pkt_len,RSVDPAGE_LOC * rsvd_page_loc)8886 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
8887 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
8888 RSVDPAGE_LOC *rsvd_page_loc)
8889 {
8890 struct security_priv *psecuritypriv = &adapter->securitypriv;
8891 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8892 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8893 struct mlme_ext_priv *pmlmeext;
8894 struct mlme_ext_info *pmlmeinfo;
8895 u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
8896 u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;
8897 u8 CurtPktPageNum = 0;
8898
8899 #ifdef CONFIG_GTK_OL
8900 struct sta_priv *pstapriv = &adapter->stapriv;
8901 struct sta_info *psta;
8902 struct security_priv *psecpriv = &adapter->securitypriv;
8903 u8 kek[RTW_KEK_LEN];
8904 u8 kck[RTW_KCK_LEN];
8905 #endif /* CONFIG_GTK_OL */
8906 #ifdef CONFIG_PNO_SUPPORT
8907 int pno_index;
8908 u8 ssid_num;
8909 #endif /* CONFIG_PNO_SUPPORT */
8910
8911 pmlmeext = &adapter->mlmeextpriv;
8912 pmlmeinfo = &pmlmeext->mlmext_info;
8913
8914 if (pwrctl->wowlan_pno_enable == _FALSE) {
8915 /* ARP RSP * 1 page */
8916
8917 rsvd_page_loc->LocArpRsp = *page_num;
8918
8919 RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
8920
8921 rtw_hal_construct_ARPRsp(adapter, &pframe[index],
8922 &ARPLength, pmlmeinfo->ip_addr);
8923
8924 rtw_hal_fill_fake_txdesc(adapter,
8925 &pframe[index - tx_desc],
8926 ARPLength, _FALSE, _FALSE, _TRUE);
8927
8928 CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
8929
8930 *page_num += CurtPktPageNum;
8931
8932 index += (CurtPktPageNum * page_size);
8933 RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
8934
8935 #ifdef CONFIG_IPV6
8936 /* 2 NS offload and NDP Info*/
8937 if (pwrctl->wowlan_ns_offload_en == _TRUE) {
8938 rsvd_page_loc->LocNbrAdv = *page_num;
8939 RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
8940 rtw_hal_construct_na_message(adapter,
8941 &pframe[index], &ns_len);
8942 rtw_hal_fill_fake_txdesc(adapter,
8943 &pframe[index - tx_desc],
8944 ns_len, _FALSE,
8945 _FALSE, _TRUE);
8946 CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
8947 page_size);
8948 *page_num += CurtPktPageNum;
8949 index += (CurtPktPageNum * page_size);
8950 RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
8951
8952 rsvd_page_loc->LocNDPInfo = *page_num;
8953 RTW_INFO("LocNDPInfo: %d\n",
8954 rsvd_page_loc->LocNDPInfo);
8955
8956 rtw_hal_construct_ndp_info(adapter,
8957 &pframe[index - tx_desc],
8958 &ns_len);
8959 CurtPktPageNum =
8960 (u8)PageNum(tx_desc + ns_len, page_size);
8961 *page_num += CurtPktPageNum;
8962 index += (CurtPktPageNum * page_size);
8963 RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
8964
8965 }
8966 #endif /*CONFIG_IPV6*/
8967 /* 3 Remote Control Info. * 1 page */
8968 rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
8969 RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
8970 rtw_hal_construct_remote_control_info(adapter,
8971 &pframe[index - tx_desc],
8972 &rc_len);
8973 CurtPktPageNum = (u8)PageNum(rc_len, page_size);
8974 *page_num += CurtPktPageNum;
8975 *total_pkt_len = index + rc_len;
8976 RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
8977 #ifdef CONFIG_GTK_OL
8978 index += (CurtPktPageNum * page_size);
8979
8980 /* if the ap staion info. exists, get the kek, kck from staion info. */
8981 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8982 if (psta == NULL) {
8983 _rtw_memset(kek, 0, RTW_KEK_LEN);
8984 _rtw_memset(kck, 0, RTW_KCK_LEN);
8985 RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
8986 __func__);
8987 } else {
8988 _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
8989 _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
8990 }
8991
8992 /* 3 KEK, KCK */
8993 rsvd_page_loc->LocGTKInfo = *page_num;
8994 RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
8995
8996 if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
8997 struct security_priv *psecpriv = NULL;
8998
8999 psecpriv = &adapter->securitypriv;
9000 _rtw_memcpy(pframe + index - tx_desc,
9001 &psecpriv->dot11PrivacyAlgrthm, 1);
9002 _rtw_memcpy(pframe + index - tx_desc + 1,
9003 &psecpriv->dot118021XGrpPrivacy, 1);
9004 _rtw_memcpy(pframe + index - tx_desc + 2,
9005 kck, RTW_KCK_LEN);
9006 _rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
9007 kek, RTW_KEK_LEN);
9008 CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
9009 } else {
9010
9011 _rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
9012 _rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
9013 kek, RTW_KEK_LEN);
9014 GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
9015
9016 if (psta != NULL &&
9017 psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
9018 _rtw_memcpy(pframe + index - tx_desc + 56,
9019 &psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
9020 GTKLength += RTW_TKIP_MIC_LEN;
9021 }
9022 CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
9023 }
9024 #if 0
9025 {
9026 int i;
9027 printk("\ntoFW KCK: ");
9028 for (i = 0; i < 16; i++)
9029 printk(" %02x ", kck[i]);
9030 printk("\ntoFW KEK: ");
9031 for (i = 0; i < 16; i++)
9032 printk(" %02x ", kek[i]);
9033 printk("\n");
9034 }
9035
9036 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
9037 __FUNCTION__, &pframe[index - tx_desc],
9038 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
9039 #endif
9040
9041 *page_num += CurtPktPageNum;
9042
9043 index += (CurtPktPageNum * page_size);
9044 RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
9045
9046 /* 3 GTK Response */
9047 rsvd_page_loc->LocGTKRsp = *page_num;
9048 RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
9049 rtw_hal_construct_GTKRsp(adapter, &pframe[index], >KLength);
9050
9051 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
9052 GTKLength, _FALSE, _FALSE, _TRUE);
9053 #if 0
9054 {
9055 int gj;
9056 printk("123GTK pkt=>\n");
9057 for (gj = 0; gj < GTKLength + tx_desc; gj++) {
9058 printk(" %02x ", pframe[index - tx_desc + gj]);
9059 if ((gj + 1) % 16 == 0)
9060 printk("\n");
9061 }
9062 printk(" <=end\n");
9063 }
9064
9065 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
9066 __FUNCTION__, &pframe[index - tx_desc],
9067 (tx_desc + GTKLength));
9068 #endif
9069
9070 CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
9071
9072 *page_num += CurtPktPageNum;
9073
9074 index += (CurtPktPageNum * page_size);
9075 RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
9076
9077 /* below page is empty for GTK extension memory */
9078 /* 3(11) GTK EXT MEM */
9079 rsvd_page_loc->LocGTKEXTMEM = *page_num;
9080 RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
9081 CurtPktPageNum = 2;
9082
9083 if (page_size >= 256)
9084 CurtPktPageNum = 1;
9085
9086 *page_num += CurtPktPageNum;
9087 /* extension memory for FW */
9088 *total_pkt_len = index + (page_size * CurtPktPageNum);
9089 RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
9090 #endif /* CONFIG_GTK_OL */
9091
9092 index += (CurtPktPageNum * page_size);
9093
9094 /*Reserve 1 page for AOAC report*/
9095 rsvd_page_loc->LocAOACReport = *page_num;
9096 RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
9097 *page_num += 1;
9098 *total_pkt_len = index + (page_size * 1);
9099 RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
9100 } else {
9101 #ifdef CONFIG_PNO_SUPPORT
9102 if (pwrctl->wowlan_in_resume == _FALSE &&
9103 pwrctl->pno_inited == _TRUE) {
9104
9105 /* Broadcast Probe Request */
9106 rsvd_page_loc->LocProbePacket = *page_num;
9107
9108 RTW_INFO("loc_probe_req: %d\n",
9109 rsvd_page_loc->LocProbePacket);
9110
9111 rtw_hal_construct_ProbeReq(
9112 adapter,
9113 &pframe[index],
9114 &ProbeReqLength,
9115 NULL);
9116
9117 rtw_hal_fill_fake_txdesc(adapter,
9118 &pframe[index - tx_desc],
9119 ProbeReqLength, _FALSE, _FALSE, _FALSE);
9120
9121 CurtPktPageNum =
9122 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
9123
9124 *page_num += CurtPktPageNum;
9125
9126 index += (CurtPktPageNum * page_size);
9127 RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9128
9129 /* Hidden SSID Probe Request */
9130 ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
9131
9132 for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
9133 pwrctl->pnlo_info->loc_probe_req[pno_index] =
9134 *page_num;
9135
9136 rtw_hal_construct_ProbeReq(
9137 adapter,
9138 &pframe[index],
9139 &ProbeReqLength,
9140 &pwrctl->pno_ssid_list->node[pno_index]);
9141
9142 rtw_hal_fill_fake_txdesc(adapter,
9143 &pframe[index - tx_desc],
9144 ProbeReqLength, _FALSE, _FALSE, _FALSE);
9145
9146 CurtPktPageNum =
9147 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
9148
9149 *page_num += CurtPktPageNum;
9150
9151 index += (CurtPktPageNum * page_size);
9152 RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9153 }
9154
9155 /* PNO INFO Page */
9156 rsvd_page_loc->LocPNOInfo = *page_num;
9157 RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
9158 rtw_hal_construct_PNO_info(adapter,
9159 &pframe[index - tx_desc],
9160 &PNOLength);
9161
9162 CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
9163 *page_num += CurtPktPageNum;
9164 index += (CurtPktPageNum * page_size);
9165 RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
9166
9167 /* Scan Info Page */
9168 rsvd_page_loc->LocScanInfo = *page_num;
9169 RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
9170 rtw_hal_construct_scan_info(adapter,
9171 &pframe[index - tx_desc],
9172 &ScanInfoLength);
9173
9174 CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
9175 *page_num += CurtPktPageNum;
9176 *total_pkt_len = index + ScanInfoLength;
9177 index += (CurtPktPageNum * page_size);
9178 RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
9179 }
9180 #endif /* CONFIG_PNO_SUPPORT */
9181 }
9182 }
9183
rtw_hal_gate_bb(_adapter * adapter,bool stop)9184 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
9185 {
9186 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9187 u8 i = 0, val8 = 0, empty = _FAIL;
9188
9189 if (stop) {
9190 /* checking TX queue status */
9191 for (i = 0 ; i < 5 ; i++) {
9192 rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
9193 if (empty) {
9194 break;
9195 } else {
9196 RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
9197 __func__, i);
9198 rtw_mdelay_os(10);
9199 }
9200 }
9201
9202 if (val8 == 5)
9203 RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
9204
9205 /* Pause TX*/
9206 pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
9207 rtw_write8(adapter, REG_TXPAUSE, 0xff);
9208 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9209 val8 &= ~BIT(0);
9210 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9211 RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
9212 __func__,
9213 rtw_read8(adapter, REG_SYS_FUNC_EN),
9214 pwrpriv->wowlan_txpause_status);
9215 } else {
9216 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9217 val8 |= BIT(0);
9218 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9219 RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
9220 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
9221 pwrpriv->wowlan_txpause_status);
9222 /* release TX*/
9223 rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
9224 }
9225 }
9226
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)9227 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
9228 {
9229 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9230 u8 *pattern;
9231 u8 len = 0;
9232 u8 *mask;
9233
9234 u8 mask_hw[MAX_WKFM_SIZE] = {0};
9235 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9236 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9237 u8 multicast_addr1[2] = {0x33, 0x33};
9238 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9239 u8 mask_len = 0;
9240 u8 mac_addr[ETH_ALEN] = {0};
9241 u16 count = 0;
9242 int i;
9243
9244 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9245 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9246 __func__, MAX_WKFM_CAM_NUM);
9247 return _FAIL;
9248 }
9249
9250 pattern = pwrctl->patterns[idx].content;
9251 len = pwrctl->patterns[idx].len;
9252 mask = pwrctl->patterns[idx].mask;
9253
9254 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9255 _rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
9256
9257 mask_len = DIV_ROUND_UP(len, 8);
9258
9259 /* 1. setup A1 table */
9260 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9261 pwow_pattern->type = PATTERN_BROADCAST;
9262 else if (memcmp(pattern, multicast_addr1, 2) == 0)
9263 pwow_pattern->type = PATTERN_MULTICAST;
9264 else if (memcmp(pattern, multicast_addr2, 3) == 0)
9265 pwow_pattern->type = PATTERN_MULTICAST;
9266 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9267 pwow_pattern->type = PATTERN_UNICAST;
9268 else
9269 pwow_pattern->type = PATTERN_INVALID;
9270
9271 /* translate mask from os to mask for hw */
9272
9273 /******************************************************************************
9274 * pattern from OS uses 'ethenet frame', like this:
9275
9276 | 6 | 6 | 2 | 20 | Variable | 4 |
9277 |--------+--------+------+-----------+------------+-----|
9278 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
9279 | DA | SA | Type |
9280
9281 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9282
9283 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
9284 |-------------------+--------+------+-----------+------------+-----|
9285 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
9286 | Others | Tpye |
9287
9288 * Therefore, we need translate mask_from_OS to mask_to_hw.
9289 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9290 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9291 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9292 ******************************************************************************/
9293 /* Shift 6 bits */
9294 for (i = 0; i < mask_len - 1; i++) {
9295 mask_hw[i] = mask[i] >> 6;
9296 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9297 }
9298
9299 mask_hw[i] = (mask[i] >> 6) & 0x3F;
9300 /* Set bit 0-5 to zero */
9301 mask_hw[0] &= 0xC0;
9302
9303 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9304 pwow_pattern->mask[i] = mask_hw[i * 4];
9305 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
9306 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
9307 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
9308 }
9309
9310 /* To get the wake up pattern from the mask.
9311 * We do not count first 12 bits which means
9312 * DA[6] and SA[6] in the pattern to match HW design. */
9313 count = 0;
9314 for (i = 12; i < len; i++) {
9315 if ((mask[i / 8] >> (i % 8)) & 0x01) {
9316 content[count] = pattern[i];
9317 count++;
9318 }
9319 }
9320
9321 pwow_pattern->crc = rtw_calc_crc(content, count);
9322
9323 if (pwow_pattern->crc != 0) {
9324 if (pwow_pattern->type == PATTERN_INVALID)
9325 pwow_pattern->type = PATTERN_VALID;
9326 }
9327
9328 return _SUCCESS;
9329 }
9330
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)9331 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
9332 {
9333 int j;
9334
9335 RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
9336 RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
9337 RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
9338 for (j = 0; j < 4; j++)
9339 RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
9340 }
9341 /*bit definition of pattern match format*/
9342 #define WOW_VALID_BIT BIT31
9343 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
9344 #define WOW_BC_BIT BIT26
9345 #define WOW_MC_BIT BIT25
9346 #define WOW_UC_BIT BIT24
9347 #else
9348 #define WOW_BC_BIT BIT18
9349 #define WOW_UC_BIT BIT17
9350 #define WOW_MC_BIT BIT16
9351 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
9352
9353 #ifndef CONFIG_WOW_PATTERN_HW_CAM
9354 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_hal_reset_mac_rx(_adapter * adapter)9355 static void rtw_hal_reset_mac_rx(_adapter *adapter)
9356 {
9357 u8 val8 = 0;
9358 /* Set REG_CR bit1, bit3, bit7 to 0*/
9359 val8 = rtw_read8(adapter, REG_CR);
9360 val8 &= 0x75;
9361 rtw_write8(adapter, REG_CR, val8);
9362 val8 = rtw_read8(adapter, REG_CR);
9363 /* Set REG_CR bit1, bit3, bit7 to 1*/
9364 val8 |= 0x8a;
9365 rtw_write8(adapter, REG_CR, val8);
9366 RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
9367 }
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)9368 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
9369 {
9370 u8 val8 = 0;
9371 u16 rxff_bndy = 0;
9372 u32 rx_dma_buff_sz = 0;
9373
9374 val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
9375 if (val8 != 0)
9376 RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
9377 __func__, (REG_FIFOPAGE + 3));
9378
9379 rtw_hal_reset_mac_rx(adapter);
9380
9381 if (wow_mode) {
9382 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9383 (u8 *)&rx_dma_buff_sz);
9384 rxff_bndy = rx_dma_buff_sz - 1;
9385
9386 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9387 RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
9388 REG_TRXFF_BNDY + 2,
9389 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9390 } else {
9391 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
9392 (u8 *)&rx_dma_buff_sz);
9393 rxff_bndy = rx_dma_buff_sz - 1;
9394 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9395 RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
9396 REG_TRXFF_BNDY + 2,
9397 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9398 }
9399 }
9400 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO*/
9401 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9402 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9403 {
9404 u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9405 u16 offset, rx_buf_ptr = 0;
9406 u16 cam_start_offset = 0;
9407 u16 ctrl_l = 0, ctrl_h = 0;
9408 u8 count = 0, tmp = 0;
9409 int i = 0;
9410 bool res = _TRUE;
9411
9412 if (idx > MAX_WKFM_CAM_NUM) {
9413 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9414 __func__);
9415 return _FALSE;
9416 }
9417
9418 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9419 (u8 *)&rx_dma_buff_sz);
9420
9421 if (rx_dma_buff_sz == 0) {
9422 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9423 return _FALSE;
9424 }
9425
9426 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9427
9428 if (page_sz == 0) {
9429 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9430 return _FALSE;
9431 }
9432
9433 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9434 cam_start_offset = offset * page_sz;
9435
9436 ctrl_l = 0x0;
9437 ctrl_h = 0x0;
9438
9439 /* Enable RX packet buffer access */
9440 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9441
9442 /* Read the WKFM CAM */
9443 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9444 /*
9445 * Set Rx packet buffer offset.
9446 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9447 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9448 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9449 * * Index: The index of the wake up frame mask
9450 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9451 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9452 */
9453 rx_buf_ptr =
9454 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9455 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9456
9457 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9458 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9459 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9460
9461 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9462
9463 count = 0;
9464
9465 do {
9466 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9467 rtw_udelay_os(2);
9468 count++;
9469 } while (!tmp && count < 100);
9470
9471 if (count >= 100) {
9472 RTW_INFO("%s count:%d\n", __func__, count);
9473 res = _FALSE;
9474 }
9475 }
9476
9477 /* Disable RX packet buffer access */
9478 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9479 DISABLE_TRXPKT_BUF_ACCESS);
9480 return res;
9481 }
9482
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9483 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9484 struct rtl_wow_pattern *context)
9485 {
9486 u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
9487 u16 offset, rx_buf_ptr = 0;
9488 u16 cam_start_offset = 0;
9489 u16 ctrl_l = 0, ctrl_h = 0;
9490 u8 count = 0, tmp = 0;
9491 int res = 0, i = 0;
9492
9493 if (idx > MAX_WKFM_CAM_NUM) {
9494 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9495 __func__);
9496 return _FALSE;
9497 }
9498
9499 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9500 (u8 *)&rx_dma_buff_sz);
9501
9502 if (rx_dma_buff_sz == 0) {
9503 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9504 return _FALSE;
9505 }
9506
9507 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9508
9509 if (page_sz == 0) {
9510 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9511 return _FALSE;
9512 }
9513
9514 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9515
9516 cam_start_offset = offset * page_sz;
9517
9518 if (IS_HARDWARE_TYPE_8188E(adapter)) {
9519 ctrl_l = 0x0001;
9520 ctrl_h = 0x0001;
9521 } else {
9522 ctrl_l = 0x0f01;
9523 ctrl_h = 0xf001;
9524 }
9525
9526 /* Enable RX packet buffer access */
9527 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9528
9529 /* Write the WKFM CAM */
9530 for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
9531 /*
9532 * Set Rx packet buffer offset.
9533 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9534 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9535 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9536 * * Index: The index of the wake up frame mask
9537 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9538 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9539 */
9540 rx_buf_ptr =
9541 (cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
9542 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9543
9544 if (i == 0) {
9545 if (context->type == PATTERN_VALID)
9546 data = WOW_VALID_BIT;
9547 else if (context->type == PATTERN_BROADCAST)
9548 data = WOW_VALID_BIT | WOW_BC_BIT;
9549 else if (context->type == PATTERN_MULTICAST)
9550 data = WOW_VALID_BIT | WOW_MC_BIT;
9551 else if (context->type == PATTERN_UNICAST)
9552 data = WOW_VALID_BIT | WOW_UC_BIT;
9553
9554 if (context->crc != 0)
9555 data |= context->crc;
9556
9557 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9558 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9559 } else if (i == 1) {
9560 data = 0;
9561 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9562 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9563 } else if (i == 2 || i == 4) {
9564 data = context->mask[i - 2];
9565 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9566 /* write to RX packet buffer*/
9567 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9568 } else if (i == 3 || i == 5) {
9569 data = context->mask[i - 2];
9570 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9571 /* write to RX packet buffer*/
9572 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9573 }
9574
9575 count = 0;
9576 do {
9577 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9578 rtw_udelay_os(2);
9579 count++;
9580 } while (tmp && count < 100);
9581
9582 if (count >= 100)
9583 res = _FALSE;
9584 else
9585 res = _TRUE;
9586 }
9587
9588 /* Disable RX packet buffer access */
9589 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9590 DISABLE_TRXPKT_BUF_ACCESS);
9591
9592 return res;
9593 }
9594 #else /* CONFIG_WOW_PATTERN_IN_TXFIFO */
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9595 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9596 {
9597 u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9598 u16 tx_page_start, tx_buf_ptr = 0;
9599 u16 cam_start_offset = 0;
9600 u16 ctrl_l = 0, ctrl_h = 0;
9601 u8 count = 0, tmp = 0, last_entry = 0;
9602 int i = 0;
9603 bool res = _TRUE;
9604
9605 if (idx > MAX_WKFM_CAM_NUM) {
9606 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9607 __func__);
9608 return _FALSE;
9609 }
9610
9611 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9612 if (page_sz == 0) {
9613 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9614 return _FALSE;
9615 }
9616
9617 rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9618 if (last_entry == 0) {
9619 RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9620 return _FALSE;
9621 }
9622
9623 /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9624 tx_page_start = last_entry - 1;
9625 cam_start_offset = tx_page_start * page_sz / 8;
9626 ctrl_l = 0x0;
9627 ctrl_h = 0x0;
9628
9629 /* Enable TX packet buffer access */
9630 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9631
9632 /* Read the WKFM CAM */
9633 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9634 /*
9635 * Set Tx packet buffer offset.
9636 * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer.
9637 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9638 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9639 * * Index: The index of the wake up frame mask
9640 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9641 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9642 */
9643 tx_buf_ptr =
9644 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9645 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr);
9646 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9647 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9648 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9649
9650 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9651
9652 count = 0;
9653
9654 do {
9655 tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9656 rtw_udelay_os(2);
9657 count++;
9658 } while (!tmp && count < 100);
9659
9660 if (count >= 100) {
9661 RTW_INFO("%s count:%d\n", __func__, count);
9662 res = _FALSE;
9663 }
9664 }
9665
9666 /* Disable RX packet buffer access */
9667 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9668 DISABLE_TRXPKT_BUF_ACCESS);
9669 return res;
9670 }
9671
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9672 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9673 struct rtl_wow_pattern *context)
9674 {
9675 u32 tx_page_start = 0, page_sz = 0;
9676 u16 tx_buf_ptr = 0;
9677 u16 cam_start_offset = 0;
9678 u32 data_l = 0, data_h = 0;
9679 u8 count = 0, tmp = 0, last_entry = 0;
9680 int res = 0, i = 0;
9681
9682 if (idx > MAX_WKFM_CAM_NUM) {
9683 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9684 __func__);
9685 return _FALSE;
9686 }
9687
9688 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9689 if (page_sz == 0) {
9690 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9691 return _FALSE;
9692 }
9693
9694 rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9695 if (last_entry == 0) {
9696 RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9697 return _FALSE;
9698 }
9699
9700 /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9701 tx_page_start = last_entry - 1;
9702 cam_start_offset = tx_page_start * page_sz / 8;
9703
9704 /* Write the PATTERN location to BIT_TXBUF_WKCAM_OFFSET */
9705 rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET, cam_start_offset & 0xFF);
9706 rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET + 1, (cam_start_offset >> 8) & 0xFF);
9707 /* Enable TX packet buffer access */
9708 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9709
9710 /* Write the WKFM CAM */
9711 for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9712 /*
9713 * Set Tx packet buffer offset.
9714 * TxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9715 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9716 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9717 * * Index: The index of the wake up frame mask
9718 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9719 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9720 */
9721 tx_buf_ptr = cam_start_offset + ((idx * WKFMCAM_SIZE + i * 8) >> 3);
9722
9723 if (i == 0) {
9724 if (context->type == PATTERN_VALID)
9725 data_l = WOW_VALID_BIT;
9726 else if (context->type == PATTERN_BROADCAST)
9727 data_l = WOW_VALID_BIT | WOW_BC_BIT;
9728 else if (context->type == PATTERN_MULTICAST)
9729 data_l = WOW_VALID_BIT | WOW_MC_BIT;
9730 else if (context->type == PATTERN_UNICAST)
9731 data_l = WOW_VALID_BIT | WOW_UC_BIT;
9732
9733 if (context->crc != 0)
9734 data_l |= context->crc;
9735
9736 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9737 } else {
9738 data_l = context->mask[i * 2 - 2];
9739 data_h = context->mask[i * 2 - 1];
9740 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9741 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h);
9742 }
9743
9744 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0x1FFF) | BIT23 | (0xff <<24));
9745 count = 0;
9746 do {
9747 tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9748 rtw_udelay_os(2);
9749 count++;
9750 } while (tmp && count < 100);
9751
9752 if (count >= 100) {
9753 res = _FALSE;
9754 RTW_INFO("%s write failed\n", __func__);
9755 } else {
9756 res = _TRUE;
9757 RTW_INFO("%s write OK\n", __func__);
9758 }
9759 }
9760
9761 /* Disable TX packet buffer access */
9762 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
9763 return res;
9764 }
9765 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
9766
rtw_clean_pattern(_adapter * adapter)9767 void rtw_clean_pattern(_adapter *adapter)
9768 {
9769 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9770 struct rtl_wow_pattern zero_pattern;
9771 int i = 0;
9772
9773 _rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
9774
9775 zero_pattern.type = PATTERN_INVALID;
9776
9777 for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
9778 rtw_write_to_frame_mask(adapter, i, &zero_pattern);
9779
9780 rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
9781 }
9782 #if 0
9783 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
9784 u8 len, u8 *mask, u8 idx)
9785 {
9786 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9787 struct mlme_ext_priv *pmlmeext = NULL;
9788 struct mlme_ext_info *pmlmeinfo = NULL;
9789 struct rtl_wow_pattern wow_pattern;
9790 u8 mask_hw[MAX_WKFM_SIZE] = {0};
9791 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9792 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9793 u8 multicast_addr1[2] = {0x33, 0x33};
9794 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9795 u8 res = _FALSE, index = 0, mask_len = 0;
9796 u8 mac_addr[ETH_ALEN] = {0};
9797 u16 count = 0;
9798 int i, j;
9799
9800 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9801 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9802 __func__, MAX_WKFM_CAM_NUM);
9803 return _FALSE;
9804 }
9805
9806 pmlmeext = &adapter->mlmeextpriv;
9807 pmlmeinfo = &pmlmeext->mlmext_info;
9808 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9809 _rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
9810
9811 mask_len = DIV_ROUND_UP(len, 8);
9812
9813 /* 1. setup A1 table */
9814 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9815 wow_pattern.type = PATTERN_BROADCAST;
9816 else if (memcmp(pattern, multicast_addr1, 2) == 0)
9817 wow_pattern.type = PATTERN_MULTICAST;
9818 else if (memcmp(pattern, multicast_addr2, 3) == 0)
9819 wow_pattern.type = PATTERN_MULTICAST;
9820 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9821 wow_pattern.type = PATTERN_UNICAST;
9822 else
9823 wow_pattern.type = PATTERN_INVALID;
9824
9825 /* translate mask from os to mask for hw */
9826
9827 /******************************************************************************
9828 * pattern from OS uses 'ethenet frame', like this:
9829
9830 | 6 | 6 | 2 | 20 | Variable | 4 |
9831 |--------+--------+------+-----------+------------+-----|
9832 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
9833 | DA | SA | Type |
9834
9835 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9836
9837 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
9838 |-------------------+--------+------+-----------+------------+-----|
9839 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
9840 | Others | Tpye |
9841
9842 * Therefore, we need translate mask_from_OS to mask_to_hw.
9843 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9844 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9845 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9846 ******************************************************************************/
9847 /* Shift 6 bits */
9848 for (i = 0; i < mask_len - 1; i++) {
9849 mask_hw[i] = mask[i] >> 6;
9850 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9851 }
9852
9853 mask_hw[i] = (mask[i] >> 6) & 0x3F;
9854 /* Set bit 0-5 to zero */
9855 mask_hw[0] &= 0xC0;
9856
9857 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9858 wow_pattern.mask[i] = mask_hw[i * 4];
9859 wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
9860 wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
9861 wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
9862 }
9863
9864 /* To get the wake up pattern from the mask.
9865 * We do not count first 12 bits which means
9866 * DA[6] and SA[6] in the pattern to match HW design. */
9867 count = 0;
9868 for (i = 12; i < len; i++) {
9869 if ((mask[i / 8] >> (i % 8)) & 0x01) {
9870 content[count] = pattern[i];
9871 count++;
9872 }
9873 }
9874
9875 wow_pattern.crc = rtw_calc_crc(content, count);
9876
9877 if (wow_pattern.crc != 0) {
9878 if (wow_pattern.type == PATTERN_INVALID)
9879 wow_pattern.type = PATTERN_VALID;
9880 }
9881
9882 index = idx;
9883
9884 if (!pwrctl->bInSuspend)
9885 index += 2;
9886
9887 /* write pattern */
9888 res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
9889
9890 if (res == _FALSE)
9891 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
9892 __func__, idx);
9893
9894 return res;
9895 }
9896 #endif
9897
rtw_fill_pattern(_adapter * adapter)9898 void rtw_fill_pattern(_adapter *adapter)
9899 {
9900 int i = 0, total = 0, index;
9901 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9902 struct rtl_wow_pattern wow_pattern;
9903
9904 total = pwrpriv->wowlan_pattern_idx;
9905
9906 if (total > MAX_WKFM_CAM_NUM)
9907 total = MAX_WKFM_CAM_NUM;
9908
9909 for (i = 0 ; i < total ; i++) {
9910 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
9911
9912 index = i;
9913 if (!pwrpriv->bInSuspend)
9914 index += 2;
9915 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
9916 if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
9917 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
9918 }
9919
9920 }
9921 rtw_write8(adapter, REG_WKFMCAM_NUM, total);
9922
9923 }
9924
9925 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
9926
9927 #define WOW_CAM_ACCESS_TIMEOUT_MS 200
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)9928 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
9929 {
9930 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9931 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
9932
9933 u32 rdata = 0;
9934 u32 cnt = 0;
9935 systime start = 0;
9936 u8 timeout = 0;
9937 u8 rst = _FALSE;
9938
9939 _enter_critical_mutex(mutex, NULL);
9940
9941 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
9942
9943 start = rtw_get_current_time();
9944 while (1) {
9945 if (rtw_is_surprise_removed(adapter))
9946 break;
9947
9948 cnt++;
9949 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
9950 rst = _SUCCESS;
9951 break;
9952 }
9953 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
9954 timeout = 1;
9955 break;
9956 }
9957 }
9958
9959 rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
9960
9961 _exit_critical_mutex(mutex, NULL);
9962
9963 /*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
9964
9965 if (timeout)
9966 RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
9967
9968 return rdata;
9969 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)9970 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
9971 {
9972 int i;
9973 u32 rdata;
9974
9975 _rtw_memset(context, 0, sizeof(struct rtl_wow_pattern));
9976
9977 for (i = 4; i >= 0; i--) {
9978 rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
9979
9980 switch (i) {
9981 case 4:
9982 if (rdata & WOW_BC_BIT)
9983 context->type = PATTERN_BROADCAST;
9984 else if (rdata & WOW_MC_BIT)
9985 context->type = PATTERN_MULTICAST;
9986 else if (rdata & WOW_UC_BIT)
9987 context->type = PATTERN_UNICAST;
9988 else
9989 context->type = PATTERN_INVALID;
9990
9991 context->crc = rdata & 0xFFFF;
9992 break;
9993 default:
9994 _rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
9995 break;
9996 }
9997 }
9998 }
9999
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)10000 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
10001 {
10002 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10003 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10004 u32 cnt = 0;
10005 systime start = 0, end = 0;
10006 u8 timeout = 0;
10007
10008 /*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
10009 _enter_critical_mutex(mutex, NULL);
10010
10011 rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
10012 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
10013
10014 start = rtw_get_current_time();
10015 while (1) {
10016 if (rtw_is_surprise_removed(adapter))
10017 break;
10018
10019 cnt++;
10020 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
10021 break;
10022
10023 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10024 timeout = 1;
10025 break;
10026 }
10027 }
10028 end = rtw_get_current_time();
10029
10030 _exit_critical_mutex(mutex, NULL);
10031
10032 if (timeout) {
10033 RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
10034 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
10035 }
10036 }
10037
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10038 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
10039 {
10040 int j;
10041 u8 addr;
10042 u32 wdata = 0;
10043
10044 for (j = 4; j >= 0; j--) {
10045 switch (j) {
10046 case 4:
10047 wdata = context->crc;
10048
10049 if (PATTERN_BROADCAST == context->type)
10050 wdata |= WOW_BC_BIT;
10051 if (PATTERN_MULTICAST == context->type)
10052 wdata |= WOW_MC_BIT;
10053 if (PATTERN_UNICAST == context->type)
10054 wdata |= WOW_UC_BIT;
10055 if (PATTERN_INVALID != context->type)
10056 wdata |= WOW_VALID_BIT;
10057 break;
10058 default:
10059 wdata = context->mask[j];
10060 break;
10061 }
10062
10063 addr = (id << 3) + j;
10064
10065 _rtw_wow_pattern_write_cam(adapter, addr, wdata);
10066 }
10067 }
10068
_rtw_wow_pattern_clean_cam(_adapter * adapter)10069 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
10070 {
10071 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10072 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10073 u32 cnt = 0;
10074 systime start = 0;
10075 u8 timeout = 0;
10076 u8 rst = _FAIL;
10077
10078 _enter_critical_mutex(mutex, NULL);
10079 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
10080
10081 start = rtw_get_current_time();
10082 while (1) {
10083 if (rtw_is_surprise_removed(adapter))
10084 break;
10085
10086 cnt++;
10087 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10088 rst = _SUCCESS;
10089 break;
10090 }
10091 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10092 timeout = 1;
10093 break;
10094 }
10095 }
10096 _exit_critical_mutex(mutex, NULL);
10097
10098 if (timeout)
10099 RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
10100
10101 return rst;
10102 }
10103
rtw_clean_pattern(_adapter * adapter)10104 void rtw_clean_pattern(_adapter *adapter)
10105 {
10106 if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
10107 RTW_ERR("rtw_clean_pattern failed\n");
10108 }
rtw_fill_pattern(_adapter * adapter)10109 void rtw_fill_pattern(_adapter *adapter)
10110 {
10111 int i = 0, total = 0;
10112 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10113 struct rtl_wow_pattern wow_pattern;
10114
10115 total = pwrpriv->wowlan_pattern_idx;
10116
10117 if (total > MAX_WKFM_CAM_NUM)
10118 total = MAX_WKFM_CAM_NUM;
10119
10120 for (i = 0 ; i < total ; i++) {
10121 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10122 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10123 rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
10124 }
10125 }
10126 }
10127
10128 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)10129 void rtw_wow_pattern_cam_dump(_adapter *adapter)
10130 {
10131
10132 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10133 int i;
10134
10135 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10136 RTW_INFO("=======[%d]=======\n", i);
10137 rtw_read_from_frame_mask(adapter, i);
10138 }
10139 #else
10140 struct rtl_wow_pattern context;
10141 int i;
10142
10143 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10144 rtw_wow_pattern_read_cam_ent(adapter, i, &context);
10145 rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
10146 }
10147
10148 #endif
10149 }
10150
10151
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)10152 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
10153 {
10154 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10155
10156 switch (mode) {
10157 case 0:
10158 rtw_clean_pattern(adapter);
10159 RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
10160 break;
10161 case 1:
10162 rtw_set_default_pattern(adapter);
10163 rtw_fill_pattern(adapter);
10164 RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
10165 break;
10166 case 2:
10167 rtw_clean_pattern(adapter);
10168 rtw_wow_pattern_sw_reset(adapter);
10169 RTW_INFO("%s: clean patterns\n", __func__);
10170 break;
10171 default:
10172 RTW_INFO("%s: unknown mode\n", __func__);
10173 break;
10174 }
10175 }
10176
rtw_hal_wow_enable(_adapter * adapter)10177 static void rtw_hal_wow_enable(_adapter *adapter)
10178 {
10179 struct registry_priv *registry_par = &adapter->registrypriv;
10180 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10181 struct security_priv *psecuritypriv = &adapter->securitypriv;
10182 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10183 struct sta_info *psta = NULL;
10184 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
10185 int res;
10186 u16 media_status_rpt;
10187 u8 no_wake = 0, i;
10188 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10189 _adapter *iface;
10190 #ifdef CONFIG_GPIO_WAKEUP
10191 u8 val8 = 0;
10192 #endif
10193
10194 #ifdef CONFIG_LPS_PG
10195 u8 lps_pg_hdl_id = 0;
10196 #endif
10197
10198
10199
10200 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
10201 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
10202 no_wake = 1;
10203
10204 RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
10205 rtw_hal_gate_bb(adapter, _TRUE);
10206
10207 for (i = 0; i < dvobj->iface_nums; i++) {
10208 iface = dvobj->padapters[i];
10209 /* Start Usb TxDMA */
10210 if(iface) {
10211 RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface));
10212 RTW_ENABLE_FUNC(iface, DF_TX_BIT);
10213 }
10214 }
10215
10216 #ifdef CONFIG_GTK_OL
10217 if (psecuritypriv->binstallKCK_KEK == _TRUE)
10218 rtw_hal_fw_sync_cam_id(adapter);
10219 #endif
10220 if (IS_HARDWARE_TYPE_8723B(adapter))
10221 rtw_hal_backup_rate(adapter);
10222
10223 rtw_hal_fw_dl(adapter, _TRUE);
10224 if(no_wake)
10225 media_status_rpt = RT_MEDIA_DISCONNECT;
10226 else
10227 media_status_rpt = RT_MEDIA_CONNECT;
10228 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10229 (u8 *)&media_status_rpt);
10230
10231 /* RX DMA stop */
10232 #if defined(CONFIG_RTL8188E)
10233 if (IS_HARDWARE_TYPE_8188E(adapter))
10234 rtw_hal_disable_tx_report(adapter);
10235 #endif
10236
10237 res = rtw_hal_pause_rx_dma(adapter);
10238 if (res == _FAIL)
10239 RTW_PRINT("[WARNING] pause RX DMA fail\n");
10240
10241 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10242 /* Reconfig RX_FF Boundary */
10243 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10244 rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
10245 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10246 #endif
10247
10248 /* redownload wow pattern */
10249 if(!no_wake)
10250 rtw_hal_dl_pattern(adapter, 1);
10251
10252 if (!pwrctl->wowlan_pno_enable) {
10253 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10254
10255 if (psta != NULL) {
10256 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10257 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10258 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10259 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10260 #endif
10261 if(!no_wake)
10262 rtw_sta_media_status_rpt(adapter, psta, 1);
10263 }
10264 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10265 else {
10266 if(registry_par->suspend_type == FW_IPS_WRC) {
10267 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10268 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10269 rtw_hal_set_default_port_id_cmd(adapter, 0);
10270 }
10271 }
10272 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10273 }
10274
10275 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10276 /* Enable CPWM2 only. */
10277 res = rtw_hal_enable_cpwm2(adapter);
10278 if (res == _FAIL)
10279 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
10280 #endif
10281 #ifdef CONFIG_GPIO_WAKEUP
10282 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10283 rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10284 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10285 #else
10286 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10287 if (pwrctl->is_high_active == 0)
10288 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10289 else
10290 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10291 GPIO_OUTPUT_LOW);
10292 #else
10293 val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
10294 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8);
10295 rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10296 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n",
10297 __func__, pwrctl->wowlan_gpio_index,
10298 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10299 pwrctl->is_high_active ? "HIGI" : "LOW");
10300 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10301 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10302 #endif /* CONFIG_GPIO_WAKEUP */
10303 /* Set WOWLAN H2C command. */
10304 RTW_PRINT("Set WOWLan cmd\n");
10305 rtw_hal_set_fw_wow_related_cmd(adapter, 1);
10306
10307 res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
10308
10309 if (res == _FALSE)
10310 RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
10311
10312 pwrctl->wowlan_wake_reason =
10313 rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10314
10315 RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
10316 pwrctl->wowlan_wake_reason);
10317 #ifdef CONFIG_GTK_OL_DBG
10318 dump_sec_cam(RTW_DBGDUMP, adapter);
10319 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
10320 #endif
10321
10322 #ifdef CONFIG_LPS_PG
10323 if (pwrctl->lps_level == LPS_PG) {
10324 lps_pg_hdl_id = LPS_PG_INFO_CFG;
10325 rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
10326 }
10327 #endif
10328
10329 #ifdef CONFIG_USB_HCI
10330 /* free adapter's resource */
10331 rtw_mi_intf_stop(adapter);
10332
10333 #endif
10334 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
10335 /* Invoid SE0 reset signal during suspending*/
10336 rtw_write8(adapter, REG_RSV_CTRL, 0x20);
10337 if (IS_8188F(pHalData->version_id) == FALSE
10338 && IS_8188GTV(pHalData->version_id) == FALSE)
10339 rtw_write8(adapter, REG_RSV_CTRL, 0x60);
10340 #endif
10341
10342 rtw_hal_gate_bb(adapter, _FALSE);
10343 }
10344
10345 #define DBG_WAKEUP_REASON
10346 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)10347 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
10348 {
10349 RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
10350 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)10351 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
10352 {
10353 if (RX_PAIRWISEKEY == reason)
10354 _dbg_wake_up_reason_string(adapter, "Rx pairwise key");
10355 else if (RX_GTK == reason)
10356 _dbg_wake_up_reason_string(adapter, "Rx GTK");
10357 else if (RX_FOURWAY_HANDSHAKE == reason)
10358 _dbg_wake_up_reason_string(adapter, "Rx four way handshake");
10359 else if (RX_DISASSOC == reason)
10360 _dbg_wake_up_reason_string(adapter, "Rx disassoc");
10361 else if (RX_DEAUTH == reason)
10362 _dbg_wake_up_reason_string(adapter, "Rx deauth");
10363 else if (RX_ARP_REQUEST == reason)
10364 _dbg_wake_up_reason_string(adapter, "Rx ARP request");
10365 else if (FW_DECISION_DISCONNECT == reason)
10366 _dbg_wake_up_reason_string(adapter, "FW detect disconnect");
10367 else if (RX_MAGIC_PKT == reason)
10368 _dbg_wake_up_reason_string(adapter, "Rx magic packet");
10369 else if (RX_UNICAST_PKT == reason)
10370 _dbg_wake_up_reason_string(adapter, "Rx unicast packet");
10371 else if (RX_PATTERN_PKT == reason)
10372 _dbg_wake_up_reason_string(adapter, "Rx pattern packet");
10373 else if (RTD3_SSID_MATCH == reason)
10374 _dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
10375 else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
10376 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
10377 else if (RX_REALWOW_V2_ACK_LOST == reason)
10378 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
10379 else if (ENABLE_FAIL_DMA_IDLE == reason)
10380 _dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
10381 else if (ENABLE_FAIL_DMA_PAUSE == reason)
10382 _dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
10383 else if (AP_OFFLOAD_WAKEUP == reason)
10384 _dbg_wake_up_reason_string(adapter, "AP offload wakeup");
10385 else if (CLK_32K_UNLOCK == reason)
10386 _dbg_wake_up_reason_string(adapter, "clk 32k unlock");
10387 else if (RTIME_FAIL_DMA_IDLE == reason)
10388 _dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
10389 else if (CLK_32K_LOCK == reason)
10390 _dbg_wake_up_reason_string(adapter, "clk 32k lock");
10391 else
10392 _dbg_wake_up_reason_string(adapter, "unknown reasoen");
10393 }
10394 #endif
10395
rtw_hal_wow_disable(_adapter * adapter)10396 static void rtw_hal_wow_disable(_adapter *adapter)
10397 {
10398 int i;
10399 struct recv_reorder_ctrl *preorder_ctrl;
10400 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10401 struct security_priv *psecuritypriv = &adapter->securitypriv;
10402 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10403 struct sta_info *psta = NULL;
10404 struct registry_priv *registry_par = &adapter->registrypriv;
10405 int res;
10406 u16 media_status_rpt;
10407
10408 RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
10409
10410 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
10411 RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");
10412 return;
10413 }
10414
10415 if (!pwrctl->wowlan_pno_enable) {
10416 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10417 if (psta != NULL)
10418 rtw_sta_media_status_rpt(adapter, psta, 0);
10419 else
10420 RTW_INFO("%s: psta is null\n", __func__);
10421 }
10422
10423 if (0) {
10424 RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
10425 RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
10426 RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
10427 RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
10428 }
10429
10430 pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10431
10432 RTW_PRINT("wakeup_reason: 0x%02x\n",
10433 pwrctl->wowlan_wake_reason);
10434 #ifdef DBG_WAKEUP_REASON
10435 _dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
10436 #endif
10437
10438 rtw_hal_set_fw_wow_related_cmd(adapter, 0);
10439
10440 res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
10441
10442 #if defined(CONFIG_RTL8188E)
10443 if (IS_HARDWARE_TYPE_8188E(adapter))
10444 rtw_hal_enable_tx_report(adapter);
10445 #endif
10446
10447 if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10448 (pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
10449 (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
10450 rtw_hal_get_aoac_rpt(adapter);
10451 rtw_hal_update_sw_security_info(adapter);
10452 }
10453
10454 if (res == _FALSE) {
10455 RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
10456 rtw_hal_force_enable_rxdma(adapter);
10457 }
10458
10459 rtw_hal_gate_bb(adapter, _TRUE);
10460
10461 res = rtw_hal_pause_rx_dma(adapter);
10462 if (res == _FAIL)
10463 RTW_PRINT("[WARNING] pause RX DMA fail\n");
10464
10465 /* clean HW pattern match */
10466 rtw_hal_dl_pattern(adapter, 0);
10467
10468 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10469 /* config RXFF boundary to original */
10470 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10471 rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
10472 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10473 #endif
10474 rtw_hal_release_rx_dma(adapter);
10475
10476 rtw_hal_fw_dl(adapter, _FALSE);
10477
10478 #ifdef CONFIG_GPIO_WAKEUP
10479
10480 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10481 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10482 #else
10483 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10484 if (pwrctl->is_high_active == 0)
10485 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10486 else
10487 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10488 GPIO_OUTPUT_LOW);
10489 #else
10490 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index
10491 , pwrctl->wowlan_gpio_output_state);
10492 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n",
10493 __func__, pwrctl->wowlan_gpio_index,
10494 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10495 pwrctl->is_high_active ? "HIGI" : "LOW");
10496 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10497 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10498 #endif /* CONFIG_GPIO_WAKEUP */
10499 if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
10500 (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
10501 (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10502 (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
10503
10504 media_status_rpt = RT_MEDIA_CONNECT;
10505 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10506 (u8 *)&media_status_rpt);
10507
10508 if (psta != NULL) {
10509 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10510 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10511 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10512 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10513 #endif
10514 rtw_sta_media_status_rpt(adapter, psta, 1);
10515 }
10516 }
10517
10518 if (psta != NULL) {
10519 RTW_PRINT("rtw_set_bit RTW_RECV_REORDER_WOW\n");
10520 for (i = 0; i < TID_NUM; i++) {
10521 preorder_ctrl = &psta->recvreorder_ctrl[i];
10522 rtw_set_bit(RTW_RECV_REORDER_WOW,
10523 &preorder_ctrl->rec_abba_rsp_ack);
10524 }
10525 }
10526
10527 rtw_hal_gate_bb(adapter, _FALSE);
10528 }
10529 #endif /*CONFIG_WOWLAN*/
10530
10531 #ifdef CONFIG_P2P_WOWLAN
rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter * adapter,u8 * pframe,u16 index,u8 tx_desc,u32 page_size,u8 * page_num,u32 * total_pkt_len,RSVDPAGE_LOC * rsvd_page_loc)10532 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
10533 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
10534 RSVDPAGE_LOC *rsvd_page_loc)
10535 {
10536 u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
10537 u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
10538 u8 CurtPktPageNum = 0;
10539
10540 /* P2P Beacon */
10541 rsvd_page_loc->LocP2PBeacon = *page_num;
10542 rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
10543 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10544 P2PBCNLength, _FALSE, _FALSE, _FALSE);
10545
10546 #if 0
10547 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
10548 __FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
10549 #endif
10550
10551 CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
10552
10553 *page_num += CurtPktPageNum;
10554
10555 index += (CurtPktPageNum * page_size);
10556 RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
10557
10558 /* P2P Probe rsp */
10559 rsvd_page_loc->LocP2PProbeRsp = *page_num;
10560 rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
10561 &P2PProbeRspLength);
10562 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10563 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
10564
10565 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", */
10566 /* __FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
10567
10568 CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
10569
10570 *page_num += CurtPktPageNum;
10571
10572 index += (CurtPktPageNum * page_size);
10573 RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
10574
10575 /* P2P nego rsp */
10576 rsvd_page_loc->LocNegoRsp = *page_num;
10577 rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
10578 &P2PNegoRspLength);
10579 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10580 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
10581
10582 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
10583 /* __FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
10584
10585 CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
10586
10587 *page_num += CurtPktPageNum;
10588
10589 index += (CurtPktPageNum * page_size);
10590 RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
10591
10592 /* P2P invite rsp */
10593 rsvd_page_loc->LocInviteRsp = *page_num;
10594 rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
10595 &P2PInviteRspLength);
10596 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10597 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
10598
10599 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
10600 /* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
10601
10602 CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
10603
10604 *page_num += CurtPktPageNum;
10605
10606 index += (CurtPktPageNum * page_size);
10607 RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
10608
10609 /* P2P provision discovery rsp */
10610 rsvd_page_loc->LocPDRsp = *page_num;
10611 rtw_hal_construct_P2PProvisionDisRsp(adapter,
10612 &pframe[index], &P2PPDRspLength);
10613
10614 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10615 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
10616
10617 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
10618 /* __FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
10619
10620 CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
10621
10622 *page_num += CurtPktPageNum;
10623
10624 *total_pkt_len = index + P2PPDRspLength;
10625 RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
10626
10627 index += (CurtPktPageNum * page_size);
10628
10629
10630 }
10631 #endif /* CONFIG_P2P_WOWLAN */
10632
10633 #ifdef CONFIG_LPS_PG
10634 #ifndef DBG_LPSPG_INFO_DUMP
10635 #define DBG_LPSPG_INFO_DUMP 1
10636 #endif
10637
10638 #include "hal_halmac.h"
10639
10640 #ifdef CONFIG_RTL8822C
rtw_lps_pg_set_dpk_info_rsvd_page(_adapter * adapter)10641 static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)
10642 {
10643 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10644 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10645 struct dm_struct *dm = adapter_to_phydm(adapter);
10646 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;
10647 u8 *info = NULL;
10648 u32 info_len;
10649 int ret = _FAIL;
10650
10651 /* get length */
10652 halrf_dpk_info_rsvd_page(dm, NULL, &info_len);
10653 if (!info_len) {
10654 RTW_ERR("get %s length fail\n", cache->name);
10655 goto exit;
10656 }
10657
10658 /* allocate buf */
10659 info = rtw_zmalloc(info_len);
10660 if (!info) {
10661 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10662 goto exit;
10663 }
10664
10665 /* get content */
10666 halrf_dpk_info_rsvd_page(dm, info, NULL);
10667
10668 if (rsvd_page_cache_update_data(cache, info, info_len)) {
10669
10670 #if (DBG_LPSPG_INFO_DUMP >= 1)
10671 RTW_INFO_DUMP(cache->name, info, info_len);
10672 #endif
10673
10674 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10675 ret = !ret ? _SUCCESS : _FAIL;
10676 if (ret != _SUCCESS) {
10677 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10678 goto free_mem;
10679 }
10680
10681 #if (DBG_LPSPG_INFO_DUMP >= 2)
10682 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10683 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10684 #endif
10685 }
10686
10687 free_mem:
10688 rtw_mfree(info, info_len);
10689
10690 exit:
10691 return ret;
10692 }
10693
rtw_lps_pg_set_iqk_info_rsvd_page(_adapter * adapter)10694 static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)
10695 {
10696 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10697 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10698 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10699 struct dm_struct *dm = adapter_to_phydm(adapter);
10700 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;
10701 u8 *info = NULL;
10702 u32 info_len = 0;
10703 int ret = _FAIL;
10704
10705 if (hal_data->RegIQKFWOffload) {
10706 rsvd_page_cache_free_data(cache);
10707 ret = _SUCCESS;
10708 goto exit;
10709 }
10710
10711 /* get length */
10712 halrf_iqk_info_rsvd_page(dm, NULL, &info_len);
10713 if (!info_len) {
10714 RTW_ERR("get %s length fail\n", cache->name);
10715 goto exit;
10716 }
10717
10718 /* allocate buf */
10719 info = rtw_zmalloc(info_len);
10720 if (!info) {
10721 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10722 goto exit;
10723 }
10724
10725 /* get content */
10726 halrf_iqk_info_rsvd_page(dm, info, NULL);
10727
10728 if (rsvd_page_cache_update_data(cache, info, info_len)) {
10729
10730 #if (DBG_LPSPG_INFO_DUMP >= 1)
10731 RTW_INFO_DUMP(cache->name, info, info_len);
10732 #endif
10733
10734 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10735 ret = !ret ? _SUCCESS : _FAIL;
10736 if (ret != _SUCCESS) {
10737 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10738 goto free_mem;
10739 }
10740
10741 #if (DBG_LPSPG_INFO_DUMP >= 2)
10742 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10743 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10744 #endif
10745 }
10746
10747 free_mem:
10748 rtw_mfree(info, info_len);
10749
10750 exit:
10751 return ret;
10752 }
10753 #endif /* CONFIG_RTL8822C */
10754
rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv * dvobj,_adapter * ld_sta_iface,u8 * buf,u32 * buf_size)10755 static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size)
10756 {
10757 #define LPS_PG_INFO_RSVD_LEN 16
10758
10759 if (buf) {
10760 _adapter *adapter = dvobj_get_primary_adapter(dvobj);
10761 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10762 struct sta_info *psta;
10763 #ifdef CONFIG_MBSSID_CAM
10764 u8 cam_id = INVALID_CAM_ID;
10765 #endif
10766 u8 *psec_cam_id = buf + 8;
10767 u8 sec_cam_num = 0;
10768 u8 drv_rsvdpage_num = 0;
10769
10770 if (ld_sta_iface) {
10771 psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv));
10772 if (!psta) {
10773 RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
10774 rtw_warn_on(1);
10775 goto size_chk;
10776 }
10777 /*Byte 0 - used macid*/
10778 LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);
10779 RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
10780 }
10781
10782 #ifdef CONFIG_MBSSID_CAM
10783 /*Byte 1 - used BSSID CAM entry*/
10784 cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
10785 if (cam_id != INVALID_CAM_ID)
10786 LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);
10787 RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
10788 #endif
10789
10790 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
10791 /*Btye 2 - Max used Pattern Match CAM entry*/
10792 if (pwrpriv->wowlan_mode == _TRUE
10793 && ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
10794 LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);
10795 RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
10796 }
10797 #endif
10798 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
10799 /*Btye 3 - Max MU rate table Group ID*/
10800 LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);
10801 RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
10802 #endif
10803
10804 /*Btye 8 ~15 - used Security CAM entry */
10805 sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
10806
10807 /*Btye 4 - used Security CAM entry number*/
10808 if (sec_cam_num < 8)
10809 LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);
10810 RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
10811
10812 /*Btye 5 - Txbuf used page number for fw offload*/
10813 if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
10814 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
10815 else
10816 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
10817 LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);
10818 RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
10819 }
10820
10821 size_chk:
10822 if (buf_size)
10823 *buf_size = LPS_PG_INFO_RSVD_LEN;
10824 }
10825
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)10826 static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
10827 {
10828 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10829 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10830 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;
10831 u8 *info = NULL;
10832 u32 info_len = 0;
10833 int ret = _FAIL;
10834
10835 /* get length */
10836 rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len);
10837 if (!info_len) {
10838 RTW_ERR("get %s length fail\n", cache->name);
10839 goto exit;
10840 }
10841
10842 /* allocate buf */
10843 info = rtw_zmalloc(info_len);
10844 if (!info) {
10845 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10846 goto exit;
10847 }
10848
10849 /* get content */
10850 rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL);
10851
10852 if (rsvd_page_cache_update_data(cache, info, info_len)) {
10853
10854 #if (DBG_LPSPG_INFO_DUMP >= 1)
10855 RTW_INFO_DUMP(cache->name, info, info_len);
10856 #endif
10857
10858 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10859 ret = !ret ? _SUCCESS : _FAIL;
10860 if (ret != _SUCCESS) {
10861 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10862 goto free_mem;
10863 }
10864
10865 #if (DBG_LPSPG_INFO_DUMP >= 2)
10866 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10867 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10868 #endif
10869 }
10870
10871 free_mem:
10872 rtw_mfree(info, info_len);
10873
10874 exit:
10875 return ret;
10876 }
10877
rtw_lps_pg_set_rsvd_page(_adapter * adapter,u8 * frame,u16 * index,u8 txdesc_size,u32 page_size,u8 * total_page_num,bool is_wow_mode,_adapter * ld_sta_iface,bool only_get_page_num)10878 static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index
10879 , u8 txdesc_size, u32 page_size, u8 *total_page_num
10880 , bool is_wow_mode, _adapter *ld_sta_iface, bool only_get_page_num)
10881 {
10882 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10883 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10884 struct rsvd_page_cache_t *cache;
10885 bool rsvd = 1;
10886 u8 *pos;
10887 u32 len;
10888
10889 if (is_wow_mode) {
10890 /* lps_level will not change when enter wow_mode */
10891 if (pwrctl->lps_level != LPS_PG)
10892 rsvd = 0;
10893 } else {
10894 if (!only_get_page_num && !ld_sta_iface)
10895 rsvd = 0;
10896 }
10897
10898 pos = only_get_page_num ? NULL : frame + *index;
10899
10900 #ifdef CONFIG_RTL8822C
10901 if (IS_8822C_SERIES(hal_data->version_id)) {
10902 /* LPSPG_DPK_INFO */
10903 cache = &pwrctl->lpspg_dpk_info;
10904 if (rsvd) {
10905 if (pwrctl->lps_level != LPS_PG)
10906 pos = NULL;
10907 len = 0;
10908 halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10909 #if (DBG_LPSPG_INFO_DUMP >= 1)
10910 if (pos)
10911 RTW_INFO_DUMP(cache->name, pos, len);
10912 #endif
10913 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10914 *total_page_num += cache->page_num;
10915 *index += page_size * cache->page_num;
10916 pos = only_get_page_num ? NULL : frame + *index;
10917 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10918 } else
10919 rsvd_page_cache_free(cache);
10920
10921 /* LPSPG_IQK_INFO */
10922 cache = &pwrctl->lpspg_iqk_info;
10923 if (rsvd
10924 /* RegIQKFWOffload will not change when enter wow_mode */
10925 && !(is_wow_mode && hal_data->RegIQKFWOffload)
10926 ) {
10927 if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)
10928 pos = NULL;
10929 len = 0;
10930 halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10931 #if (DBG_LPSPG_INFO_DUMP >= 1)
10932 if (pos)
10933 RTW_INFO_DUMP(cache->name, pos, len);
10934 #endif
10935 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10936 *total_page_num += cache->page_num;
10937 *index += page_size * cache->page_num;
10938 pos = only_get_page_num ? NULL : frame + *index;
10939 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10940 } else
10941 rsvd_page_cache_free(cache);
10942 }
10943 #endif
10944
10945 /* LPSPG_INFO */
10946 cache = &pwrctl->lpspg_info;
10947 if (rsvd) {
10948 if (pwrctl->lps_level != LPS_PG)
10949 pos = NULL;
10950 rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len);
10951 #if (DBG_LPSPG_INFO_DUMP >= 1)
10952 if (pos)
10953 RTW_INFO_DUMP(cache->name, pos, len);
10954 #endif
10955 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10956 *total_page_num += cache->page_num;
10957 *index += page_size * cache->page_num;
10958 pos = only_get_page_num ? NULL : frame + *index;
10959 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10960 } else
10961 rsvd_page_cache_free(cache);
10962 }
10963
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)10964 u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
10965 {
10966 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10967 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10968
10969 u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
10970 u8 ret = _FAIL;
10971
10972 if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
10973 SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1); /*SecurityCAM_En*/
10974
10975 #ifdef CONFIG_MBSSID_CAM
10976 SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1); /*BSSIDCAM_En*/
10977 #endif
10978
10979 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
10980 if (pwrpriv->wowlan_mode == _TRUE &&
10981 check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
10982
10983 SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/
10984 }
10985 #endif
10986
10987 #ifdef CONFIG_MACID_SEARCH
10988 SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1); /*MACIDSearch_En*/
10989 #endif
10990
10991 #ifdef CONFIG_TX_SC
10992 SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1); /*TXSC_En*/
10993 #endif
10994
10995 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
10996 SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1); /*MURateTable_En*/
10997 #endif
10998
10999 SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);
11000
11001 #ifdef CONFIG_RTL8822C
11002 if (pwrpriv->bFwCurrentInPSMode == _FALSE) {
11003 SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);
11004 if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11005 SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);
11006 } else {
11007 SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0);
11008 if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11009 SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0);
11010 }
11011 #endif
11012
11013 #if (DBG_LPSPG_INFO_DUMP >= 1)
11014 RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);
11015 #endif
11016
11017 ret = rtw_hal_fill_h2c_cmd(adapter,
11018 H2C_LPS_PG_INFO,
11019 H2C_LPS_PG_INFO_LEN,
11020 lpspg_info);
11021 return ret;
11022 }
rtw_hal_set_lps_pg_info(_adapter * adapter)11023 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
11024 {
11025 u8 ret = _FAIL;
11026 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11027
11028 if (pwrpriv->lpspg_info.loc == 0) {
11029 RTW_ERR("%s lpspg_info.loc = 0\n", __func__);
11030 rtw_warn_on(1);
11031 return ret;
11032 }
11033 #ifdef CONFIG_RTL8822C
11034 rtw_lps_pg_set_dpk_info_rsvd_page(adapter);
11035 rtw_lps_pg_set_iqk_info_rsvd_page(adapter);
11036 #endif
11037 rtw_hal_set_lps_pg_info_rsvd_page(adapter);
11038
11039 ret = rtw_hal_set_lps_pg_info_cmd(adapter);
11040
11041 return ret;
11042 }
11043
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)11044 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
11045 {
11046 #if 0
11047 if (sta->cmn.ra_info.rssi_level >= 4)
11048 sta->lps_pg_rssi_lv = 3; /*RSSI High - 1SS_VHT_MCS7*/
11049 else if (sta->cmn.ra_info.rssi_level >= 2)
11050 sta->lps_pg_rssi_lv = 2; /*RSSI Middle - 1SS_VHT_MCS3*/
11051 else
11052 sta->lps_pg_rssi_lv = 1; /*RSSI Lower - Lowest_rate*/
11053 #else
11054 sta->lps_pg_rssi_lv = 0;
11055 #endif
11056 RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
11057 __func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
11058 }
11059
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)11060 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
11061 {
11062 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
11063 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11064 struct sta_priv *pstapriv = &adapter->stapriv;
11065 struct sta_info *sta;
11066
11067 sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
11068
11069 switch (hdl_id) {
11070 case LPS_PG_INFO_CFG:
11071 rtw_hal_set_lps_pg_info(adapter);
11072 break;
11073 case LPS_PG_REDLEMEM:
11074 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11075 break;
11076
11077 /*set xmit_block*/
11078 rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11079 if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
11080 rtw_warn_on(1);
11081 /*clearn xmit_block*/
11082 rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11083 break;
11084 case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
11085 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11086 break;
11087
11088 if (sta)
11089 rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
11090 break;
11091 case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
11092 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11093 break;
11094
11095 if (sta) {
11096 rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
11097 rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
11098 sta->lps_pg_rssi_lv = 0;
11099 }
11100 break;
11101
11102 default:
11103 break;
11104 }
11105 }
11106
11107 #endif /*CONFIG_LPS_PG*/
11108
_rtw_mi_assoc_if_num(_adapter * adapter)11109 static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
11110 {
11111 u8 mi_iface_num = 0;
11112
11113 if (0) {
11114 RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
11115 RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
11116 RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11117 RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
11118 RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
11119 /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
11120 /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
11121 }
11122
11123 mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
11124 DEV_AP_NUM(adapter_to_dvobj(adapter)) +
11125 DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11126 return mi_iface_num;
11127 }
11128 #ifdef CONFIG_CONCURRENT_MODE
_rtw_search_sta_iface(_adapter * adapter)11129 static _adapter *_rtw_search_sta_iface(_adapter *adapter)
11130 {
11131 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11132 _adapter *iface = NULL;
11133 _adapter *sta_iface = NULL;
11134 int i;
11135
11136 for (i = 0; i < dvobj->iface_nums; i++) {
11137 iface = dvobj->padapters[i];
11138 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
11139 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11140 sta_iface = iface;
11141 break;
11142 }
11143 }
11144 }
11145 return sta_iface;
11146 }
11147 #if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)
_rtw_search_ap_iface(_adapter * adapter)11148 static _adapter *_rtw_search_ap_iface(_adapter *adapter)
11149 {
11150 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11151 _adapter *iface = NULL;
11152 _adapter *ap_iface = NULL;
11153 int i;
11154
11155 for (i = 0; i < dvobj->iface_nums; i++) {
11156 iface = dvobj->padapters[i];
11157 if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
11158 ap_iface = iface;
11159 break;
11160 }
11161 }
11162 return ap_iface;
11163 }
11164 #endif/*CONFIG_AP_MODE*/
11165 #endif/*CONFIG_CONCURRENT_MODE*/
11166
11167 #ifdef CONFIG_CUSTOMER01_SMART_ANTENNA
rtw_hal_set_pathb_phase(_adapter * adapter,u8 phase_idx)11168 void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)
11169 {
11170 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
11171 struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
11172
11173 return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);
11174 }
11175 #endif
11176
11177 /*
11178 * Description: Fill the reserved packets that FW will use to RSVD page.
11179 * Now we just send 4 types packet to rsvd page.
11180 * (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
11181 * Input:
11182 * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
11183 * so we need to set the packet length to total lengh.
11184 * TRUE: At the second time, we should send the first packet (default:beacon)
11185 * to Hw again and set the lengh in descriptor to the real beacon lengh.
11186 * page_num - The amount of reserved page which driver need.
11187 * If this is not NULL, this function doesn't real download reserved
11188 * page, but just count the number of reserved page.
11189 *
11190 * 2009.10.15 by tynli.
11191 * 2017.06.20 modified by Lucas.
11192 *
11193 * Page Size = 128: 8188e, 8723a/b, 8192c/d,
11194 * Page Size = 256: 8192e, 8821a
11195 * Page Size = 512: 8812a
11196 */
11197
11198 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)11199 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
11200 {
11201 PHAL_DATA_TYPE pHalData;
11202 struct xmit_frame *pcmdframe = NULL;
11203 struct pkt_attrib *pattrib;
11204 struct xmit_priv *pxmitpriv;
11205 struct pwrctrl_priv *pwrctl;
11206 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11207 u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
11208 u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
11209 u32 ProbeReqLength = 0, NullFunctionDataLength = 0;
11210 u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
11211 u8 TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
11212 u8 *ReservedPagePacket;
11213 u16 BufIndex = 0;
11214 u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
11215 RSVDPAGE_LOC RsvdPageLoc;
11216 struct registry_priv *registry_par = &adapter->registrypriv;
11217
11218 #ifdef DBG_FW_DEBUG_MSG_PKT
11219 u32 fw_dbg_msg_pkt_len = 0;
11220 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11221
11222 #ifdef DBG_CONFIG_ERROR_DETECT
11223 struct sreset_priv *psrtpriv;
11224 #endif /* DBG_CONFIG_ERROR_DETECT */
11225
11226 #ifdef CONFIG_MCC_MODE
11227 u8 dl_mcc_page = _FAIL;
11228 #endif /* CONFIG_MCC_MODE */
11229 u8 nr_assoc_if;
11230
11231 _adapter *sta_iface = NULL;
11232 _adapter *ap_iface = NULL;
11233
11234 bool is_wow_mode = _FALSE;
11235
11236 pHalData = GET_HAL_DATA(adapter);
11237 #ifdef DBG_CONFIG_ERROR_DETECT
11238 psrtpriv = &pHalData->srestpriv;
11239 #endif
11240 pxmitpriv = &adapter->xmitpriv;
11241 pwrctl = adapter_to_pwrctl(adapter);
11242
11243 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
11244
11245 if (PageSize == 0) {
11246 RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
11247 return;
11248 }
11249 nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
11250
11251 if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
11252 pwrctl->wowlan_ap_mode == _TRUE ||
11253 pwrctl->wowlan_p2p_mode == _TRUE)
11254 is_wow_mode = _TRUE;
11255
11256 /*page_num for init time to get rsvd page number*/
11257 /* Prepare ReservedPagePacket */
11258 if (page_num) {
11259 ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
11260 if (!ReservedPagePacket) {
11261 RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11262 *page_num = 0xFF;
11263 return;
11264 }
11265 RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm ==>\n",
11266 FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11267
11268 } else {
11269 if (is_wow_mode)
11270 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11271 else
11272 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11273
11274 RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
11275 FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
11276
11277 MaxRsvdPageBufSize = RsvdPageNum * PageSize;
11278 if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
11279 RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
11280 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
11281 rtw_warn_on(1);
11282 return;
11283 }
11284
11285 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
11286 if (pcmdframe == NULL) {
11287 RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11288 return;
11289 }
11290
11291 ReservedPagePacket = pcmdframe->buf_addr;
11292 }
11293
11294 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
11295
11296 BufIndex = TxDescOffset;
11297
11298 /*======== beacon content =======*/
11299 rtw_hal_construct_beacon(adapter,
11300 &ReservedPagePacket[BufIndex], &BeaconLength);
11301
11302 /*
11303 * When we count the first page size, we need to reserve description size for the RSVD
11304 * packet, it will be filled in front of the packet in TXPKTBUF.
11305 */
11306 BeaconLength = MAX_BEACON_LEN - TxDescLen;
11307 CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
11308
11309 #if defined(CONFIG_FW_HANDLE_TXBCN) || defined(CONFIG_PORT_BASED_TXBCN)
11310 CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
11311 #endif
11312 TotalPageNum += CurtPktPageNum;
11313
11314 BufIndex += (CurtPktPageNum * PageSize);
11315
11316 RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11317
11318 /*======== probe response content ========*/
11319 if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
11320 #ifdef CONFIG_CONCURRENT_MODE
11321 if (nr_assoc_if >= 2)
11322 RTW_ERR("Not support > 2 net-interface in WOW\n");
11323 #endif
11324 /* (4) probe response*/
11325 RsvdPageLoc.LocProbeRsp = TotalPageNum;
11326 rtw_hal_construct_ProbeRsp(
11327 adapter, &ReservedPagePacket[BufIndex],
11328 &ProbeRspLength,
11329 _FALSE);
11330 rtw_hal_fill_fake_txdesc(adapter,
11331 &ReservedPagePacket[BufIndex - TxDescLen],
11332 ProbeRspLength, _FALSE, _FALSE, _FALSE);
11333
11334 CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
11335 TotalPageNum += CurtPktPageNum;
11336 TotalPacketLen = BufIndex + ProbeRspLength;
11337 BufIndex += (CurtPktPageNum * PageSize);
11338 RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11339 goto download_page;
11340 }
11341
11342 /*======== ps-poll content * 1 page ========*/
11343 sta_iface = adapter;
11344 #ifdef CONFIG_CONCURRENT_MODE
11345 if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
11346 sta_iface = _rtw_search_sta_iface(adapter);
11347 RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
11348 }
11349 #endif
11350
11351 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11352 RsvdPageLoc.LocPsPoll = TotalPageNum;
11353 RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
11354 rtw_hal_construct_PSPoll(sta_iface,
11355 &ReservedPagePacket[BufIndex], &PSPollLength);
11356 rtw_hal_fill_fake_txdesc(sta_iface,
11357 &ReservedPagePacket[BufIndex - TxDescLen],
11358 PSPollLength, _TRUE, _FALSE, _FALSE);
11359
11360 CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
11361
11362 TotalPageNum += CurtPktPageNum;
11363
11364 BufIndex += (CurtPktPageNum * PageSize);
11365 RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11366 }
11367
11368 #ifdef CONFIG_MCC_MODE
11369 /*======== MCC * n page ======== */
11370 if (MCC_EN(adapter)) {/*Normal mode*/
11371 dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
11372 &BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
11373 } else {
11374 dl_mcc_page = _FAIL;
11375 }
11376
11377 if (dl_mcc_page == _FAIL)
11378 #endif /* CONFIG_MCC_MODE */
11379 { /*======== null data * 1 page ======== */
11380 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11381 RsvdPageLoc.LocNullData = TotalPageNum;
11382 RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
11383 rtw_hal_construct_NullFunctionData(
11384 sta_iface,
11385 &ReservedPagePacket[BufIndex],
11386 &NullDataLength,
11387 _FALSE, 0, 0, _FALSE);
11388 rtw_hal_fill_fake_txdesc(sta_iface,
11389 &ReservedPagePacket[BufIndex - TxDescLen],
11390 NullDataLength, _FALSE, _FALSE, _FALSE);
11391
11392 CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
11393
11394 TotalPageNum += CurtPktPageNum;
11395
11396 BufIndex += (CurtPktPageNum * PageSize);
11397 RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11398 }
11399 }
11400
11401 /*======== Qos null data * 1 page ======== */
11402 if (pwrctl->wowlan_mode == _FALSE ||
11403 pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11404 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11405 RsvdPageLoc.LocQosNull = TotalPageNum;
11406 RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
11407 rtw_hal_construct_NullFunctionData(sta_iface,
11408 &ReservedPagePacket[BufIndex],
11409 &QosNullLength,
11410 _TRUE, 0, 0, _FALSE);
11411 rtw_hal_fill_fake_txdesc(sta_iface,
11412 &ReservedPagePacket[BufIndex - TxDescLen],
11413 QosNullLength, _FALSE, _FALSE, _FALSE);
11414
11415 CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
11416 PageSize);
11417
11418 TotalPageNum += CurtPktPageNum;
11419
11420 BufIndex += (CurtPktPageNum * PageSize);
11421 RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11422 }
11423 }
11424
11425 #ifdef CONFIG_BT_COEXIST
11426 /*======== BT Qos null data * 1 page ======== */
11427 if (pwrctl->wowlan_mode == _FALSE ||
11428 pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11429
11430 ap_iface = adapter;
11431 #if defined (CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
11432 if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) { /*DEV_AP_STARTING_NUM*/
11433 ap_iface = _rtw_search_ap_iface(adapter);
11434 RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
11435 }
11436 #endif
11437
11438 if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
11439 RsvdPageLoc.LocBTQosNull = TotalPageNum;
11440
11441 RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
11442
11443 rtw_hal_construct_NullFunctionData(ap_iface,
11444 &ReservedPagePacket[BufIndex],
11445 &BTQosNullLength,
11446 _TRUE, 0, 0, _FALSE);
11447
11448 rtw_hal_fill_fake_txdesc(ap_iface,
11449 &ReservedPagePacket[BufIndex - TxDescLen],
11450 BTQosNullLength, _FALSE, _TRUE, _FALSE);
11451
11452 CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
11453 PageSize);
11454
11455 TotalPageNum += CurtPktPageNum;
11456 BufIndex += (CurtPktPageNum * PageSize);
11457
11458 RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11459 }
11460 }
11461 #endif /* CONFIG_BT_COEXIT */
11462
11463 TotalPacketLen = BufIndex;
11464
11465 #ifdef DBG_FW_DEBUG_MSG_PKT
11466 /*======== FW DEBUG MSG * n page ======== */
11467 RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
11468 RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
11469 rtw_hal_construct_fw_dbg_msg_pkt(
11470 adapter,
11471 &ReservedPagePacket[BufIndex],
11472 &fw_dbg_msg_pkt_len);
11473
11474 rtw_hal_fill_fake_txdesc(adapter,
11475 &ReservedPagePacket[BufIndex - TxDescLen],
11476 fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
11477
11478 CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
11479
11480 if (CurtPktPageNum < 2)
11481 CurtPktPageNum = 2; /*Need at least 2 rsvd page*/
11482 TotalPageNum += CurtPktPageNum;
11483
11484 TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
11485 BufIndex += (CurtPktPageNum * PageSize);
11486 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11487
11488 #ifdef CONFIG_LPS_PG
11489 rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex
11490 , TxDescLen, PageSize, &TotalPageNum, is_wow_mode
11491 , (sta_iface && MLME_IS_STA(sta_iface) && MLME_IS_ASOC(sta_iface)) ? sta_iface : NULL
11492 , page_num ? 1 : 0
11493 );
11494 TotalPacketLen = BufIndex;
11495 #endif
11496
11497 #ifdef CONFIG_WOWLAN
11498 /*======== WOW * n page ======== */
11499 if (pwrctl->wowlan_mode == _TRUE &&
11500 pwrctl->wowlan_in_resume == _FALSE &&
11501 check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {/*WOW mode*/
11502 rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11503 BufIndex, TxDescLen, PageSize,
11504 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11505 }
11506 #endif /* CONFIG_WOWLAN */
11507
11508 #ifdef CONFIG_P2P_WOWLAN
11509 /*======== P2P WOW * n page ======== */
11510 if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
11511 rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11512 BufIndex, TxDescLen, PageSize,
11513 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11514 }
11515 #endif /* CONFIG_P2P_WOWLAN */
11516
11517 /*Note: BufIndex already add a TxDescOffset offset in first Beacon page
11518 * The "TotalPacketLen" is calculate by BufIndex.
11519 * We need to decrease TxDescOffset before doing length check. by yiwei
11520 */
11521 TotalPacketLen = TotalPacketLen - TxDescOffset;
11522
11523 download_page:
11524 if (page_num) {
11525 *page_num = TotalPageNum;
11526 rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
11527 ReservedPagePacket = NULL;
11528 RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
11529 FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11530 return;
11531 }
11532
11533 /* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
11534 RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
11535 __func__, TotalPageNum, TotalPacketLen);
11536
11537 if (TotalPacketLen > MaxRsvdPageBufSize) {
11538 RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
11539 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
11540 rtw_warn_on(1);
11541 goto error;
11542 } else {
11543 /* update attribute */
11544 pattrib = &pcmdframe->attrib;
11545 update_mgntframe_attrib(adapter, pattrib);
11546 pattrib->qsel = QSLT_BEACON;
11547 pattrib->pktlen = TotalPacketLen;
11548 pattrib->last_txcmdsz = TotalPacketLen;
11549 #ifdef CONFIG_PCI_HCI
11550 dump_mgntframe(adapter, pcmdframe);
11551 #else
11552 dump_mgntframe_and_wait(adapter, pcmdframe, 100);
11553 #endif
11554 }
11555
11556 RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
11557 __func__, TotalPacketLen, TotalPageNum);
11558 #ifdef DBG_DUMP_SET_RSVD_PAGE
11559 RTW_INFO(" ==================================================\n");
11560 RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
11561 RTW_INFO(" ==================================================\n");
11562 #endif
11563
11564
11565 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
11566 || MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
11567 rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
11568 #ifdef DBG_FW_DEBUG_MSG_PKT
11569 rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
11570 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11571 #ifdef CONFIG_WOWLAN
11572 if (pwrctl->wowlan_mode == _TRUE &&
11573 pwrctl->wowlan_in_resume == _FALSE)
11574 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11575 #endif /* CONFIG_WOWLAN */
11576 #ifdef CONFIG_AP_WOWLAN
11577 if (pwrctl->wowlan_ap_mode == _TRUE)
11578 rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
11579 #endif /* CONFIG_AP_WOWLAN */
11580 } else if (pwrctl->wowlan_pno_enable) {
11581 #ifdef CONFIG_PNO_SUPPORT
11582 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11583 if (pwrctl->wowlan_in_resume)
11584 rtw_hal_set_scan_offload_info_cmd(adapter,
11585 &RsvdPageLoc, 0);
11586 else
11587 rtw_hal_set_scan_offload_info_cmd(adapter,
11588 &RsvdPageLoc, 1);
11589 #endif /* CONFIG_PNO_SUPPORT */
11590 }
11591
11592 #ifdef CONFIG_P2P_WOWLAN
11593 if (_TRUE == pwrctl->wowlan_p2p_mode)
11594 rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
11595 #endif /* CONFIG_P2P_WOWLAN */
11596
11597 return;
11598 error:
11599 rtw_free_xmitframe(pxmitpriv, pcmdframe);
11600 }
11601
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)11602 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
11603 {
11604 #ifdef CONFIG_AP_MODE
11605 if (finished)
11606 rtw_mi_tx_beacon_hdl(adapter);
11607 else
11608 #endif
11609 _rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
11610 }
11611
11612 /**
11613 * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
11614 * @adapter: struct _ADAPTER*
11615 *
11616 * Caculate needed reserved page number.
11617 * In different state would get different number, for example normal mode and
11618 * WOW mode would need different reserved page size.
11619 *
11620 * Return the number of reserved page which driver need.
11621 */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)11622 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
11623 {
11624 u8 num = 0;
11625
11626
11627 _rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
11628
11629 return num;
11630 }
11631
11632 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
hw_var_set_bcn_func(_adapter * adapter,u8 enable)11633 static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
11634 {
11635 u32 bcn_ctrl_reg;
11636
11637 #ifdef CONFIG_CONCURRENT_MODE
11638 if (adapter->hw_port == HW_PORT1)
11639 bcn_ctrl_reg = REG_BCN_CTRL_1;
11640 else
11641 #endif
11642 bcn_ctrl_reg = REG_BCN_CTRL;
11643
11644 if (enable)
11645 rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
11646 else {
11647 u8 val8;
11648
11649 val8 = rtw_read8(adapter, bcn_ctrl_reg);
11650 val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
11651
11652 #ifdef CONFIG_BT_COEXIST
11653 if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
11654 /* Always enable port0 beacon function for PSTDMA */
11655 if (REG_BCN_CTRL == bcn_ctrl_reg)
11656 val8 |= EN_BCN_FUNCTION;
11657 }
11658 #endif
11659
11660 rtw_write8(adapter, bcn_ctrl_reg, val8);
11661 }
11662
11663 #ifdef CONFIG_RTL8192F
11664 if (IS_HARDWARE_TYPE_8192F(adapter)) {
11665 u16 val16, val16_ori;
11666
11667 val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
11668
11669 #ifdef CONFIG_CONCURRENT_MODE
11670 if (adapter->hw_port == HW_PORT1) {
11671 if (enable)
11672 val16 |= EN_PORT_1_FUNCTION;
11673 else
11674 val16 &= ~EN_PORT_1_FUNCTION;
11675 } else
11676 #endif
11677 {
11678 if (enable)
11679 val16 |= EN_PORT_0_FUNCTION;
11680 else
11681 val16 &= ~EN_PORT_0_FUNCTION;
11682
11683 #ifdef CONFIG_BT_COEXIST
11684 if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
11685 val16 |= EN_PORT_0_FUNCTION;
11686 #endif
11687 }
11688
11689 if (val16 != val16_ori)
11690 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, val16);
11691 }
11692 #endif
11693 }
11694 #endif
11695
11696 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
hw_var_set_mlme_disconnect(_adapter * adapter)11697 static void hw_var_set_mlme_disconnect(_adapter *adapter)
11698 {
11699 u8 val8;
11700
11701 /* reject all data frames */
11702 #ifdef CONFIG_CONCURRENT_MODE
11703 if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11704 #endif
11705 rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
11706
11707 #ifdef CONFIG_CONCURRENT_MODE
11708 if (adapter->hw_port == HW_PORT1) {
11709 /* reset TSF1 */
11710 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
11711
11712 /* disable update TSF1 */
11713 rtw_iface_disable_tsf_update(adapter);
11714
11715 if (!IS_HARDWARE_TYPE_8723D(adapter)
11716 && !IS_HARDWARE_TYPE_8192F(adapter)
11717 && !IS_HARDWARE_TYPE_8710B(adapter)
11718 ) {
11719 /* disable Port1's beacon function */
11720 val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
11721 val8 &= ~EN_BCN_FUNCTION;
11722 rtw_write8(adapter, REG_BCN_CTRL_1, val8);
11723 }
11724 } else
11725 #endif
11726 {
11727 /* reset TSF */
11728 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
11729
11730 /* disable update TSF */
11731 rtw_iface_disable_tsf_update(adapter);
11732 }
11733 }
11734 #endif
11735
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 enable)11736 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
11737 {
11738 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11739 u16 value_rxfltmap2;
11740
11741 #ifdef DBG_IFACE_STATUS
11742 DBG_IFACE_STATUS_DUMP(adapter);
11743 #endif
11744
11745 #ifdef CONFIG_FIND_BEST_CHANNEL
11746 /* Receive all data frames */
11747 value_rxfltmap2 = 0xFFFF;
11748 #else
11749 /* not to receive data frame */
11750 value_rxfltmap2 = 0;
11751 #endif
11752
11753 if (enable) { /* under sitesurvey */
11754 /*
11755 * 1. configure REG_RXFLTMAP2
11756 * 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
11757 * 3. config RCR to receive different BSSID BCN or probe rsp
11758 */
11759 rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
11760
11761 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
11762
11763 /* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */
11764 #if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11765 hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);
11766 hal_data->RegRRSR &= 0x000FFFFF;
11767 #endif
11768
11769 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11770 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11771 /* set 718[1:0]=2'b00 to avoid BF scan hang */
11772 hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
11773 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
11774 }
11775 #endif
11776
11777 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11778 StopTxBeacon(adapter);
11779 } else { /* sitesurvey done */
11780 /*
11781 * 1. enable rx data frame
11782 * 2. config RCR not to receive different BSSID BCN or probe rsp
11783 * 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict
11784 * so, we enable TSF update when rx first BCN after sitesurvey done
11785 */
11786 if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) {
11787 /* enable to rx data frame */
11788 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11789 }
11790
11791 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
11792
11793 /* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */
11794 #if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11795 rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);
11796 #endif
11797
11798 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11799 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11800 /* Restore orignal 0x718 setting*/
11801 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
11802 }
11803 #endif
11804
11805 #ifdef CONFIG_AP_MODE
11806 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11807 ResumeTxBeacon(adapter);
11808 rtw_mi_tx_beacon_hdl(adapter);
11809 }
11810 #endif
11811 }
11812 }
11813
11814 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
hw_var_set_mlme_join(_adapter * adapter,u8 type)11815 static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
11816 {
11817 u8 val8;
11818 u16 val16;
11819 u32 val32;
11820 u8 RetryLimit = RL_VAL_STA;
11821 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11822 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11823
11824 #ifdef CONFIG_CONCURRENT_MODE
11825 if (type == 0) {
11826 /* prepare to join */
11827 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11828 StopTxBeacon(adapter);
11829
11830 /* enable to rx data frame.Accept all data frame */
11831 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11832
11833 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11834 RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11835 else /* Ad-hoc Mode */
11836 RetryLimit = RL_VAL_AP;
11837
11838 rtw_iface_enable_tsf_update(adapter);
11839
11840 } else if (type == 1) {
11841 /* joinbss_event call back when join res < 0 */
11842 if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11843 rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11844
11845 rtw_iface_disable_tsf_update(adapter);
11846
11847 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11848 ResumeTxBeacon(adapter);
11849
11850 /* reset TSF 1/2 after ResumeTxBeacon */
11851 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11852 }
11853
11854 } else if (type == 2) {
11855 /* sta add event call back */
11856 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
11857 /* fixed beacon issue for 8191su........... */
11858 rtw_write8(adapter, 0x542 , 0x02);
11859 RetryLimit = RL_VAL_AP;
11860 }
11861
11862 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11863 ResumeTxBeacon(adapter);
11864
11865 /* reset TSF 1/2 after ResumeTxBeacon */
11866 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11867 }
11868 }
11869
11870 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11871 rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11872 #else /* !CONFIG_CONCURRENT_MODE */
11873 if (type == 0) { /* prepare to join */
11874 /* enable to rx data frame.Accept all data frame */
11875 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11876
11877 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11878 RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11879 else /* Ad-hoc Mode */
11880 RetryLimit = RL_VAL_AP;
11881
11882 rtw_iface_enable_tsf_update(adapter);
11883
11884 } else if (type == 1) { /* joinbss_event call back when join res < 0 */
11885 rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11886
11887 rtw_iface_disable_tsf_update(adapter);
11888
11889 } else if (type == 2) { /* sta add event call back */
11890 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
11891 RetryLimit = RL_VAL_AP;
11892 }
11893
11894 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11895 rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11896 #endif /* !CONFIG_CONCURRENT_MODE */
11897 }
11898 #endif
11899
11900 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)11901 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
11902 {
11903 u8 buf[2];
11904 int ret;
11905
11906 if (reset_port == HW_PORT0) {
11907 buf[0] = 0x1;
11908 buf[1] = 0;
11909 } else {
11910 buf[0] = 0x0;
11911 buf[1] = 0x1;
11912 }
11913
11914 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
11915
11916 return ret;
11917 }
11918
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)11919 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
11920 {
11921 u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
11922 u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
11923 REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
11924 int ret;
11925
11926 /* site survey will cause reset tsf fail */
11927 rtw_mi_buddy_scan_abort(adapter, _FALSE);
11928 reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
11929 ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
11930 if (ret != _SUCCESS)
11931 return ret;
11932
11933 while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
11934 rtw_msleep_os(100);
11935 loop_cnt++;
11936 reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
11937 }
11938
11939 return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
11940 }
11941 #endif /* CONFIG_TSF_RESET_OFFLOAD */
11942
11943 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
11944 #ifdef CONFIG_HW_P0_TSF_SYNC
11945 #ifdef CONFIG_CONCURRENT_MODE
hw_port0_tsf_sync_sel(_adapter * adapter,u8 benable,u8 hw_port,u16 tr_offset)11946 static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
11947 {
11948 u8 val8;
11949 u8 client_id = 0;
11950 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11951
11952 #ifdef CONFIG_MCC_MODE
11953 if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
11954 RTW_INFO("[MCC] do not set HW TSF sync\n");
11955 return;
11956 }
11957 #endif
11958 /* check if port0 is already synced */
11959 if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
11960 RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
11961 FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
11962 return;
11963 }
11964
11965 /* check if port0 already disable sync */
11966 if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
11967 RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
11968 return;
11969 }
11970
11971 /* check if port0 sync to port0 */
11972 if (benable && hw_port == HW_PORT0) {
11973 RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
11974 rtw_warn_on(1);
11975 return;
11976 }
11977
11978 /*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
11979 /* Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
11980 Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
11981
11982 val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
11983
11984 if (benable) {
11985 /*Disable Port0's beacon function*/
11986 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
11987
11988 /*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
11989 if (tr_offset)
11990 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
11991
11992 /*reg 0x577[6]=1*/ /*auto sync by tbtt*/
11993 rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
11994
11995 if (HW_PORT1 == hw_port)
11996 client_id = 0;
11997 else if (HW_PORT2 == hw_port)
11998 client_id = 1;
11999 else if (HW_PORT3 == hw_port)
12000 client_id = 2;
12001 else if (HW_PORT4 == hw_port)
12002 client_id = 3;
12003
12004 val8 &= 0x8F;
12005 val8 |= (BIT(6) | (client_id << 4));
12006
12007 dvobj->p0_tsf.sync_port = hw_port;
12008 dvobj->p0_tsf.offset = tr_offset;
12009 rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12010
12011 /*Enable Port0's beacon function*/
12012 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) | BIT_EN_BCN_FUNCTION);
12013 RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
12014 } else {
12015 val8 &= ~BIT(6);
12016
12017 dvobj->p0_tsf.sync_port = MAX_HW_PORT;
12018 dvobj->p0_tsf.offset = 0;
12019 rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12020 RTW_INFO("%s P0 TSF sync disable\n", __func__);
12021 }
12022 }
_search_ld_sta(_adapter * adapter,u8 include_self)12023 static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
12024 {
12025 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12026 u8 i;
12027 _adapter *iface = NULL;
12028
12029 if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
12030 RTW_ERR("STA_LD_NUM == 0\n");
12031 rtw_warn_on(1);
12032 }
12033
12034 for (i = 0; i < dvobj->iface_nums; i++) {
12035 iface = dvobj->padapters[i];
12036 if (!iface)
12037 continue;
12038 if (include_self == _FALSE && adapter == iface)
12039 continue;
12040 if (is_client_associated_to_ap(iface))
12041 break;
12042 }
12043 if (iface)
12044 RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
12045 return iface;
12046 }
12047 #endif /*CONFIG_CONCURRENT_MODE*/
12048 /*Correct port0's TSF*/
12049 /*#define DBG_P0_TSF_SYNC*/
hw_var_set_correct_tsf(PADAPTER adapter,u8 mlme_state)12050 void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
12051 {
12052 #ifdef CONFIG_CONCURRENT_MODE
12053 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12054 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12055 _adapter *sta_if = NULL;
12056 u8 hw_port;
12057
12058 RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
12059 #ifdef DBG_P0_TSF_SYNC
12060 RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
12061 RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
12062 RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
12063 if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12064 RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
12065 else
12066 RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12067 RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12068 #endif
12069 switch (mlme_state) {
12070 case MLME_STA_CONNECTED :
12071 {
12072 hw_port = rtw_hal_get_port(adapter);
12073
12074 if (!MLME_IS_STA(adapter)) {
12075 RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12076 rtw_warn_on(1);
12077 }
12078
12079 if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
12080 RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
12081 rtw_warn_on(1);
12082 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12083 }
12084
12085 if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12086 (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
12087 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12088 #ifdef DBG_P0_TSF_SYNC
12089 RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
12090 #endif
12091 }
12092 }
12093 break;
12094 case MLME_STA_DISCONNECTED :
12095 {
12096 hw_port = rtw_hal_get_port(adapter);
12097
12098 if (!MLME_IS_STA(adapter)) {
12099 RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12100 rtw_warn_on(1);
12101 }
12102
12103 if (dvobj->p0_tsf.sync_port == hw_port) {
12104 if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
12105 /* search next appropriate sta*/
12106 sta_if = _search_ld_sta(adapter, _FALSE);
12107 if (sta_if) {
12108 hw_port = rtw_hal_get_port(sta_if);
12109 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12110 #ifdef DBG_P0_TSF_SYNC
12111 RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
12112 #endif
12113 }
12114 } else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
12115 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12116 #ifdef DBG_P0_TSF_SYNC
12117 RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
12118 #endif
12119 }
12120 }
12121 }
12122 break;
12123 #ifdef CONFIG_AP_MODE
12124 case MLME_AP_STARTED :
12125 case MLME_MESH_STARTED :
12126 {
12127 if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12128 RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12129 rtw_warn_on(1);
12130 }
12131
12132 if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12133 rtw_mi_get_assoced_sta_num(adapter)) {
12134 /* get port of sta */
12135 sta_if = _search_ld_sta(adapter, _FALSE);
12136 if (sta_if) {
12137 hw_port = rtw_hal_get_port(sta_if);
12138 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12139 #ifdef DBG_P0_TSF_SYNC
12140 RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
12141 #endif
12142 }
12143 }
12144 }
12145 break;
12146 case MLME_AP_STOPPED :
12147 case MLME_MESH_STOPPED :
12148 {
12149 if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12150 RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12151 rtw_warn_on(1);
12152 }
12153 /*stop ap mode*/
12154 if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
12155 (dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
12156 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12157 #ifdef DBG_P0_TSF_SYNC
12158 RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
12159 #endif
12160 }
12161 }
12162 break;
12163 #endif /* CONFIG_AP_MODE */
12164 default :
12165 RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
12166 break;
12167 }
12168
12169 /*#ifdef DBG_P0_TSF_SYNC*/
12170 #if 1
12171 if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12172 RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
12173 else
12174 RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12175 RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12176 #endif
12177 #endif /*CONFIG_CONCURRENT_MODE*/
12178 }
12179
12180 #else /*! CONFIG_HW_P0_TSF_SYNC*/
12181
12182 #ifdef CONFIG_MI_WITH_MBSSID_CAM
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12183 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12184 {
12185 /*do nothing*/
12186 }
12187 #else /* !CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)12188 static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
12189 {
12190 if (hw_port == HW_PORT0) {
12191 /*disable related TSF function*/
12192 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
12193 #if defined(CONFIG_RTL8192F)
12194 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12195 REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
12196 #endif
12197
12198 rtw_write32(padapter, REG_TSFTR, tsf);
12199 rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
12200
12201 /*enable related TSF function*/
12202 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
12203 #if defined(CONFIG_RTL8192F)
12204 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12205 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
12206 #endif
12207 } else if (hw_port == HW_PORT1) {
12208 /*disable related TSF function*/
12209 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
12210 #if defined(CONFIG_RTL8192F)
12211 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12212 REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);
12213 #endif
12214
12215 rtw_write32(padapter, REG_TSFTR1, tsf);
12216 rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
12217
12218 /*enable related TSF function*/
12219 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
12220 #if defined(CONFIG_RTL8192F)
12221 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12222 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
12223 #endif
12224 } else
12225 RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
12226 }
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12227 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12228 {
12229 u64 tsf;
12230 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
12231 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
12232
12233 tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
12234
12235 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12236 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12237 StopTxBeacon(adapter);
12238
12239 rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
12240
12241 #ifdef CONFIG_CONCURRENT_MODE
12242 /* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
12243 if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
12244 && (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12245 ) {
12246 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12247 int i;
12248 _adapter *iface;
12249
12250 for (i = 0; i < dvobj->iface_nums; i++) {
12251 iface = dvobj->padapters[i];
12252 if (!iface)
12253 continue;
12254 if (iface == adapter)
12255 continue;
12256
12257 #ifdef CONFIG_AP_MODE
12258 if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
12259 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
12260 ) {
12261 rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
12262 #ifdef CONFIG_TSF_RESET_OFFLOAD
12263 if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
12264 RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
12265 , __func__, ADPT_ARG(iface), iface->hw_port);
12266 #endif /* CONFIG_TSF_RESET_OFFLOAD*/
12267 }
12268 #endif /* CONFIG_AP_MODE */
12269 }
12270 }
12271 #endif /* CONFIG_CONCURRENT_MODE */
12272 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12273 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12274 ResumeTxBeacon(adapter);
12275 }
12276 #endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
12277 #endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/
12278 #endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/
12279
rtw_hal_get_tsftr_by_port(_adapter * adapter,u8 port)12280 u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
12281 {
12282 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
12283 u64 tsftr = 0;
12284
12285 if (port >= hal_spec->port_num) {
12286 RTW_ERR("%s invalid port(%d) \n", __func__, port);
12287 goto exit;
12288 }
12289
12290 switch (rtw_get_chip_type(adapter)) {
12291 #if defined(CONFIG_RTL8814B)
12292 case RTL8814B:
12293 {
12294 u8 val8;
12295
12296 /* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */
12297 val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);
12298 val8 &= ~0x70;
12299 val8 |= port << 4;
12300 rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);
12301
12302 tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);
12303 tsftr = tsftr << 32;
12304 tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);
12305
12306 break;
12307 }
12308 #endif
12309 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
12310 case RTL8814A:
12311 case RTL8822B:
12312 case RTL8821C:
12313 case RTL8822C:
12314 {
12315 u8 val8;
12316
12317 /* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
12318 val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
12319 val8 &= 0x8F;
12320 val8 |= port << 4;
12321 rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
12322
12323 tsftr = rtw_read32(adapter, REG_TSFTR + 4);
12324 tsftr = tsftr << 32;
12325 tsftr |= rtw_read32(adapter, REG_TSFTR);
12326
12327 break;
12328 }
12329 #endif
12330 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
12331 || defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
12332 || defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
12333 || defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
12334 || defined(CONFIG_RTL8710B)
12335 case RTL8188E:
12336 case RTL8188F:
12337 case RTL8188GTV:
12338 case RTL8192E:
12339 case RTL8192F:
12340 case RTL8723B:
12341 case RTL8703B:
12342 case RTL8723D:
12343 case RTL8812:
12344 case RTL8821:
12345 case RTL8710B:
12346 {
12347 u32 addr;
12348
12349 if (port == HW_PORT0)
12350 addr = REG_TSFTR;
12351 else if (port == HW_PORT1)
12352 addr = REG_TSFTR1;
12353 else {
12354 RTW_ERR("%s unknown port(%d) \n", __func__, port);
12355 goto exit;
12356 }
12357
12358 tsftr = rtw_read32(adapter, addr + 4);
12359 tsftr = tsftr << 32;
12360 tsftr |= rtw_read32(adapter, addr);
12361
12362 break;
12363 }
12364 #endif
12365 default:
12366 RTW_ERR("%s unknow chip type\n", __func__);
12367 }
12368
12369 exit:
12370 return tsftr;
12371 }
12372
12373 #ifdef CONFIG_TDLS
12374 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)12375 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
12376 {
12377 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
12378 u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
12379
12380
12381 SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
12382 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
12383 switch (bwmode) {
12384 case CHANNEL_WIDTH_40:
12385 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
12386 break;
12387 case CHANNEL_WIDTH_80:
12388 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
12389 break;
12390 case CHANNEL_WIDTH_20:
12391 default:
12392 break;
12393 }
12394 SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
12395
12396 return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
12397 }
12398 #endif
12399 #endif
12400
12401 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)12402 void rtw_hal_update_uapsd_tid(_adapter *adapter)
12403 {
12404 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12405 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
12406
12407 /* write complement of pqospriv->uapsd_tid to mac register 0x693 because
12408 it's designed for "0" represents "enable" and "1" represents "disable" */
12409 rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
12410 }
12411 #endif /* CONFIG_WMMPS_STA */
12412
12413 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
12414 /* For multi-port support, driver needs to inform the port ID to FW for btc operations */
rtw_hal_set_wifi_btc_port_id_cmd(_adapter * adapter)12415 s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
12416 {
12417 u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
12418 u8 hw_port = rtw_hal_get_port(adapter);
12419
12420 SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
12421 RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
12422 return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
12423 }
12424 #endif
12425
12426 #define LPS_ACTIVE_TIMEOUT 50 /*number of times*/
rtw_lps_state_chk(_adapter * adapter,u8 ps_mode)12427 void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
12428 {
12429 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
12430 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12431 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12432 struct sta_priv *pstapriv = &adapter->stapriv;
12433 struct sta_info *psta = NULL;
12434 u8 ps_ready = _FALSE;
12435 s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
12436
12437 if (ps_mode == PS_MODE_ACTIVE) {
12438 #ifdef CONFIG_LPS_ACK
12439 if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {
12440 if (pwrpriv->lps_ack_status > 0) {
12441 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
12442 if (psta != NULL) {
12443 if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)
12444 RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));
12445 }
12446 }
12447 } else {
12448 RTW_WARN("LPS sctx query timeout, operation abort!!\n");
12449 return;
12450 }
12451 pwrpriv->lps_ack_status = -1;
12452 #else
12453 do {
12454 if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
12455 ps_ready = _TRUE;
12456 break;
12457 }
12458 rtw_msleep_os(1);
12459 } while (leave_wait_count--);
12460
12461 if (ps_ready == _FALSE) {
12462 RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));
12463 return;
12464 }
12465 #endif /* CONFIG_LPS_ACK */
12466 }
12467 }
12468
rtw_var_set_basic_rate(PADAPTER padapter,u8 * val)12469 void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {
12470
12471 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
12472 struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
12473 u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
12474 u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
12475 u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
12476 #if CONFIG_IEEE80211_BAND_5GHZ
12477 u16 rrsr_5g_force_mask = (RRSR_6M);
12478 u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);
12479 #endif
12480 u32 temp_RRSR;
12481
12482 HalSetBrateCfg(padapter, val, &BrateCfg);
12483 input_b = BrateCfg;
12484
12485 /* apply force and allow mask */
12486 #if CONFIG_IEEE80211_BAND_5GHZ
12487 if (pHalData->current_band_type != BAND_ON_2_4G) {
12488 BrateCfg |= rrsr_5g_force_mask;
12489 BrateCfg &= rrsr_5g_allow_mask;
12490 } else
12491 #endif
12492 { /* 2.4G */
12493 BrateCfg |= rrsr_2g_force_mask;
12494 BrateCfg &= rrsr_2g_allow_mask;
12495 }
12496 masked = BrateCfg;
12497
12498 #ifdef CONFIG_CMCC_TEST
12499 BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
12500 BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */
12501 #endif
12502
12503 /* IOT consideration */
12504 if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
12505 /* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
12506 if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
12507 BrateCfg |= RRSR_6M;
12508 }
12509 ioted = BrateCfg;
12510
12511 #ifdef CONFIG_NARROWBAND_SUPPORTING
12512 if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
12513 || (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {
12514 BrateCfg &= ~RRSR_CCK_RATES;
12515 BrateCfg |= RRSR_6M;
12516 }
12517 #endif
12518 pHalData->BasicRateSet = BrateCfg;
12519
12520 RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
12521
12522 /* Set RRSR rate table. */
12523 temp_RRSR = rtw_read32(padapter, REG_RRSR);
12524 temp_RRSR &=0xFFFF0000;
12525 temp_RRSR |=BrateCfg;
12526 rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);
12527
12528 rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
12529
12530 #if defined(CONFIG_RTL8188E)
12531 rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
12532 #endif
12533 }
12534
SetHwReg(_adapter * adapter,u8 variable,u8 * val)12535 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
12536 {
12537 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12538 u8 ret = _SUCCESS;
12539
12540 switch (variable) {
12541 case HW_VAR_MEDIA_STATUS: {
12542 u8 net_type = *((u8 *)val);
12543
12544 rtw_hal_set_msr(adapter, net_type);
12545 }
12546 break;
12547 case HW_VAR_DO_IQK:
12548 if (*val)
12549 hal_data->bNeedIQK = _TRUE;
12550 else
12551 hal_data->bNeedIQK = _FALSE;
12552 break;
12553 case HW_VAR_MAC_ADDR:
12554 #ifdef CONFIG_MI_WITH_MBSSID_CAM
12555 rtw_hal_set_macaddr_mbid(adapter, val);
12556 #else
12557 rtw_hal_set_macaddr_port(adapter, val);
12558 #endif
12559 break;
12560 case HW_VAR_BSSID:
12561 rtw_hal_set_bssid(adapter, val);
12562 break;
12563 case HW_VAR_RCR:
12564 ret = hw_var_rcr_config(adapter, *((u32 *)val));
12565 break;
12566 case HW_VAR_ON_RCR_AM:
12567 hw_var_set_rcr_am(adapter, 1);
12568 break;
12569 case HW_VAR_OFF_RCR_AM:
12570 hw_var_set_rcr_am(adapter, 0);
12571 break;
12572 case HW_VAR_BEACON_INTERVAL:
12573 hw_var_set_bcn_interval(adapter, *(u16 *)val);
12574 break;
12575 #ifdef CONFIG_MBSSID_CAM
12576 case HW_VAR_MBSSID_CAM_WRITE: {
12577 u32 cmd = 0;
12578 u32 *cam_val = (u32 *)val;
12579
12580 rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
12581 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
12582 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12583 }
12584 break;
12585 case HW_VAR_MBSSID_CAM_CLEAR: {
12586 u32 cmd;
12587 u8 entry_id = *(u8 *)val;
12588
12589 rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
12590
12591 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
12592 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12593 }
12594 break;
12595 case HW_VAR_RCR_MBSSID_EN:
12596 if (*((u8 *)val))
12597 rtw_hal_rcr_add(adapter, RCR_ENMBID);
12598 else
12599 rtw_hal_rcr_clear(adapter, RCR_ENMBID);
12600 break;
12601 #endif
12602 case HW_VAR_PORT_SWITCH:
12603 hw_var_port_switch(adapter);
12604 break;
12605 case HW_VAR_INIT_RTS_RATE: {
12606 u16 brate_cfg = *((u16 *)val);
12607 u8 rate_index = 0;
12608 HAL_VERSION *hal_ver = &hal_data->version_id;
12609
12610 if (IS_8188E(*hal_ver)) {
12611
12612 while (brate_cfg > 0x1) {
12613 brate_cfg = (brate_cfg >> 1);
12614 rate_index++;
12615 }
12616 rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
12617 } else
12618 rtw_warn_on(1);
12619 }
12620 break;
12621 case HW_VAR_SEC_CFG: {
12622 u16 reg_scr_ori;
12623 u16 reg_scr;
12624
12625 reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
12626 reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
12627
12628 if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
12629 reg_scr |= SCR_CHK_BMC;
12630
12631 if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
12632 reg_scr |= SCR_NoSKMC;
12633
12634 if (reg_scr != reg_scr_ori)
12635 rtw_write16(adapter, REG_SECCFG, reg_scr);
12636 }
12637 break;
12638 case HW_VAR_SEC_DK_CFG: {
12639 struct security_priv *sec = &adapter->securitypriv;
12640 u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
12641
12642 if (val) { /* Enable default key related setting */
12643 reg_scr |= SCR_TXBCUSEDK;
12644 if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
12645 reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
12646 } else /* Disable default key related setting */
12647 reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
12648
12649 rtw_write8(adapter, REG_SECCFG, reg_scr);
12650 }
12651 break;
12652
12653 case HW_VAR_ASIX_IOT:
12654 /* enable ASIX IOT function */
12655 if (*((u8 *)val) == _TRUE) {
12656 /* 0xa2e[0]=0 (disable rake receiver) */
12657 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12658 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
12659 /* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
12660 rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
12661 } else {
12662 /* restore reg:0xa2e, reg:0xa1c */
12663 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12664 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
12665 rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
12666 }
12667 break;
12668 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
12669 case HW_VAR_WOWLAN: {
12670 struct wowlan_ioctl_param *poidparam;
12671
12672 poidparam = (struct wowlan_ioctl_param *)val;
12673 switch (poidparam->subcode) {
12674 #ifdef CONFIG_WOWLAN
12675 case WOWLAN_PATTERN_CLEAN:
12676 rtw_hal_dl_pattern(adapter, 2);
12677 break;
12678 case WOWLAN_ENABLE:
12679 rtw_hal_wow_enable(adapter);
12680 break;
12681 case WOWLAN_DISABLE:
12682 rtw_hal_wow_disable(adapter);
12683 break;
12684 #endif /*CONFIG_WOWLAN*/
12685 #ifdef CONFIG_AP_WOWLAN
12686 case WOWLAN_AP_ENABLE:
12687 rtw_hal_ap_wow_enable(adapter);
12688 break;
12689 case WOWLAN_AP_DISABLE:
12690 rtw_hal_ap_wow_disable(adapter);
12691 break;
12692 #endif /*CONFIG_AP_WOWLAN*/
12693 default:
12694 break;
12695 }
12696 }
12697 break;
12698 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
12699
12700 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
12701 case HW_VAR_BCN_FUNC:
12702 hw_var_set_bcn_func(adapter, *val);
12703 break;
12704 #endif
12705
12706 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
12707 case HW_VAR_MLME_DISCONNECT:
12708 hw_var_set_mlme_disconnect(adapter);
12709 break;
12710 #endif
12711
12712 case HW_VAR_MLME_SITESURVEY:
12713 hw_var_set_mlme_sitesurvey(adapter, *val);
12714 #ifdef CONFIG_BT_COEXIST
12715 if (hal_data->EEPROMBluetoothCoexist == 1)
12716 rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
12717 #endif
12718 break;
12719
12720 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
12721 case HW_VAR_MLME_JOIN:
12722 hw_var_set_mlme_join(adapter, *val);
12723 break;
12724 #endif
12725
12726 case HW_VAR_EN_HW_UPDATE_TSF:
12727 rtw_hal_set_hw_update_tsf(adapter);
12728 break;
12729 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
12730 case HW_VAR_CORRECT_TSF:
12731 hw_var_set_correct_tsf(adapter, *val);
12732 break;
12733 #endif
12734
12735 #if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)
12736 case HW_VAR_TSF_AUTO_SYNC:
12737 if (*val == _TRUE)
12738 hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
12739 else
12740 hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
12741 break;
12742 #endif
12743 case HW_VAR_APFM_ON_MAC:
12744 hal_data->bMacPwrCtrlOn = *val;
12745 RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
12746 break;
12747 #ifdef CONFIG_WMMPS_STA
12748 case HW_VAR_UAPSD_TID:
12749 rtw_hal_update_uapsd_tid(adapter);
12750 break;
12751 #endif /* CONFIG_WMMPS_STA */
12752 #ifdef CONFIG_LPS_PG
12753 case HW_VAR_LPS_PG_HANDLE:
12754 rtw_hal_lps_pg_handler(adapter, *val);
12755 break;
12756 #endif
12757 #ifdef CONFIG_LPS_LCLK_WD_TIMER
12758 case HW_VAR_DM_IN_LPS_LCLK:
12759 rtw_phydm_wd_lps_lclk_hdl(adapter);
12760 break;
12761 #endif
12762 case HW_VAR_ENABLE_RX_BAR:
12763 if (*val == _TRUE) {
12764 /* enable RX BAR */
12765 u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12766
12767 val16 |= BIT(8);
12768 rtw_write16(adapter, REG_RXFLTMAP1, val16);
12769 } else {
12770 /* disable RX BAR */
12771 u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12772
12773 val16 &= (~BIT(8));
12774 rtw_write16(adapter, REG_RXFLTMAP1, val16);
12775 }
12776 RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
12777 REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
12778 break;
12779 case HW_VAR_HCI_SUS_STATE:
12780 hal_data->hci_sus_state = *(u8 *)val;
12781 RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
12782 break;
12783 #if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
12784 case HW_VAR_BCN_HEAD_SEL:
12785 {
12786 u8 vap_id = *(u8 *)val;
12787
12788 if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
12789 RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
12790 rtw_warn_on(1);
12791 }
12792 if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
12793 u16 drv_pg_bndy = 0, bcn_addr = 0;
12794 u32 page_size = 0;
12795
12796 /*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
12797 rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
12798 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
12799
12800 if (vap_id != 0xFF)
12801 bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
12802 else
12803 bcn_addr = drv_pg_bndy;
12804 RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
12805 ADPT_ARG(adapter), vap_id, bcn_addr);
12806 rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
12807 (bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
12808 }
12809 }
12810 break;
12811 #endif
12812 case HW_VAR_LPS_STATE_CHK :
12813 rtw_lps_state_chk(adapter, *(u8 *)val);
12814 break;
12815
12816 #ifdef CONFIG_RTS_FULL_BW
12817 case HW_VAR_SET_RTS_BW:
12818 {
12819 #ifdef RTW_HALMAC
12820 rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));
12821 #else
12822 u8 temp;
12823 if(*val)
12824 temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );
12825 else
12826 temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));
12827 rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);
12828 /*RTW_INFO("HW_VAR_SET_RTS_BW val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/
12829 #endif
12830 }
12831 break;
12832 #endif/*CONFIG_RTS_FULL_BW*/
12833 #if defined(CONFIG_PCI_HCI)
12834 case HW_VAR_ENSWBCN:
12835 if (*val == _TRUE) {
12836 rtw_write8(adapter, REG_CR + 1,
12837 rtw_read8(adapter, REG_CR + 1) | BIT(0));
12838 } else
12839 rtw_write8(adapter, REG_CR + 1,
12840 rtw_read8(adapter, REG_CR + 1) & ~BIT(0));
12841 break;
12842 #endif
12843 default:
12844 if (0)
12845 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12846 FUNC_ADPT_ARG(adapter), variable);
12847 ret = _FAIL;
12848 break;
12849 }
12850
12851 return ret;
12852 }
12853
GetHwReg(_adapter * adapter,u8 variable,u8 * val)12854 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
12855 {
12856 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12857 u64 val64;
12858
12859
12860 switch (variable) {
12861 case HW_VAR_MAC_ADDR:
12862 #ifndef CONFIG_MI_WITH_MBSSID_CAM
12863 rtw_hal_get_macaddr_port(adapter, val);
12864 #endif
12865 break;
12866 case HW_VAR_BASIC_RATE:
12867 *((u16 *)val) = hal_data->BasicRateSet;
12868 break;
12869 case HW_VAR_MEDIA_STATUS:
12870 rtw_hal_get_msr(adapter, val);
12871 break;
12872 case HW_VAR_DO_IQK:
12873 *val = hal_data->bNeedIQK;
12874 break;
12875 case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
12876 if (hal_is_band_support(adapter, BAND_ON_5G))
12877 *val = _TRUE;
12878 else
12879 *val = _FALSE;
12880 break;
12881 case HW_VAR_APFM_ON_MAC:
12882 *val = hal_data->bMacPwrCtrlOn;
12883 break;
12884 case HW_VAR_RCR:
12885 hw_var_rcr_get(adapter, (u32 *)val);
12886 break;
12887 case HW_VAR_FWLPS_RF_ON:
12888 /* When we halt NIC, we should check if FW LPS is leave. */
12889 if (rtw_is_surprise_removed(adapter)
12890 || (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
12891 ) {
12892 /*
12893 * If it is in HW/SW Radio OFF or IPS state,
12894 * we do not check Fw LPS Leave,
12895 * because Fw is unload.
12896 */
12897 *val = _TRUE;
12898 } else {
12899 u32 rcr = 0;
12900
12901 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
12902 if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
12903 *val = _FALSE;
12904 else
12905 *val = _TRUE;
12906 }
12907 break;
12908
12909 case HW_VAR_HCI_SUS_STATE:
12910 *((u8 *)val) = hal_data->hci_sus_state;
12911 break;
12912
12913 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
12914 case HW_VAR_BCN_CTRL_ADDR:
12915 *((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
12916 break;
12917 #endif
12918
12919 #ifdef CONFIG_WAPI_SUPPORT
12920 case HW_VAR_CAM_EMPTY_ENTRY: {
12921 u8 ucIndex = *((u8 *)val);
12922 u8 i;
12923 u32 ulCommand = 0;
12924 u32 ulContent = 0;
12925 u32 ulEncAlgo = CAM_AES;
12926
12927 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
12928 /* filled id in CAM config 2 byte */
12929 if (i == 0)
12930 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
12931 else
12932 ulContent = 0;
12933 /* polling bit, and No Write enable, and address */
12934 ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
12935 ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
12936 /* write content 0 is equall to mark invalid */
12937 rtw_write32(adapter, REG_CAMWRITE, ulContent); /* delay_ms(40); */
12938 rtw_write32(adapter, REG_CAMCMD, ulCommand); /* delay_ms(40); */
12939 }
12940 }
12941 #endif
12942
12943 default:
12944 if (0)
12945 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12946 FUNC_ADPT_ARG(adapter), variable);
12947 break;
12948 }
12949
12950 }
12951
_get_page_size(struct _ADAPTER * a)12952 static u32 _get_page_size(struct _ADAPTER *a)
12953 {
12954 #ifdef RTW_HALMAC
12955 struct dvobj_priv *d;
12956 u32 size = 0;
12957 int err = 0;
12958
12959
12960 d = adapter_to_dvobj(a);
12961
12962 err = rtw_halmac_get_page_size(d, &size);
12963 if (!err)
12964 return size;
12965
12966 RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
12967 FUNC_ADPT_ARG(a), err);
12968 #endif /* RTW_HALMAC */
12969
12970 return PAGE_SIZE_128;
12971 }
12972
12973 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)12974 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
12975 {
12976 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12977 u8 bResult = _SUCCESS;
12978
12979 switch (variable) {
12980
12981 case HAL_DEF_DBG_DUMP_RXPKT:
12982 hal_data->bDumpRxPkt = *((u8 *)value);
12983 break;
12984 case HAL_DEF_DBG_DUMP_TXPKT:
12985 hal_data->bDumpTxPkt = *((u8 *)value);
12986 break;
12987 case HAL_DEF_ANT_DETECT:
12988 hal_data->AntDetection = *((u8 *)value);
12989 break;
12990 default:
12991 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
12992 bResult = _FAIL;
12993 break;
12994 }
12995
12996 return bResult;
12997 }
12998
12999 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)13000 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
13001 {
13002 struct registry_priv *pregistrypriv = &adapter->registrypriv;
13003 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13004
13005 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)))
13006 return pregistrypriv->beamformer_rf_num;
13007 else if (IS_HARDWARE_TYPE_8814AE(adapter)
13008 #if 0
13009 #if defined(CONFIG_USB_HCI)
13010 || (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) /* for USB3.0 */
13011 #endif
13012 #endif
13013 ) {
13014 /*BF cap provided by Yu Chen, Sean, 2015, 01 */
13015 if (hal_data->rf_type == RF_3T3R)
13016 return 2;
13017 else if (hal_data->rf_type == RF_4T4R)
13018 return 3;
13019 else
13020 return 1;
13021 } else
13022 return 1;
13023
13024 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)13025 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
13026 {
13027 struct registry_priv *pregistrypriv = &adapter->registrypriv;
13028 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13029 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13030
13031 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13032
13033 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)))
13034 return pregistrypriv->beamformee_rf_num;
13035 else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
13036 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
13037 return 2;
13038 else
13039 return 2;/*TODO: May be 3 in the future, by ChenYu. */
13040 } else
13041 return 1;
13042
13043 }
13044 #ifdef RTW_BEAMFORMING_VERSION_2
rtw_hal_beamforming_config_csirate(PADAPTER adapter)13045 void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
13046 {
13047 struct dm_struct *p_dm_odm;
13048 struct beamforming_info *bf_info;
13049 u8 fix_rate_enable = 0;
13050 u8 new_csi_rate_idx;
13051 u8 rrsr_54_en;
13052 u32 temp_rrsr;
13053
13054 /* Acting as BFee */
13055 if (IS_BEAMFORMEE(adapter)) {
13056 #if 0
13057 /* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
13058 if (IS_HARDWARE_TYPE_8821C(Adapter))
13059 FixRateEnable = 1; /* Support after 8821C */
13060 #endif
13061
13062 p_dm_odm = adapter_to_phydm(adapter);
13063 bf_info = GET_BEAMFORM_INFO(adapter);
13064
13065 rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
13066 p_dm_odm->rssi_min,
13067 bf_info->cur_csi_rpt_rate,
13068 fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);
13069
13070 temp_rrsr = rtw_read32(adapter, REG_RRSR);
13071 if (rrsr_54_en == 1)
13072 temp_rrsr |= RRSR_54M;
13073 else if (rrsr_54_en == 0)
13074 temp_rrsr &= ~RRSR_54M;
13075 rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);
13076
13077 if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
13078 bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
13079 }
13080 }
13081 #endif
13082 #endif
13083
13084 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13085 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13086 {
13087 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13088 u8 bResult = _SUCCESS;
13089
13090 switch (variable) {
13091 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
13092 struct mlme_priv *pmlmepriv;
13093 struct sta_priv *pstapriv;
13094 struct sta_info *psta;
13095
13096 pmlmepriv = &adapter->mlmepriv;
13097 pstapriv = &adapter->stapriv;
13098 psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
13099 if (psta)
13100 *((int *)value) = psta->cmn.rssi_stat.rssi;
13101 }
13102 break;
13103 case HAL_DEF_DBG_DUMP_RXPKT:
13104 *((u8 *)value) = hal_data->bDumpRxPkt;
13105 break;
13106 case HAL_DEF_DBG_DUMP_TXPKT:
13107 *((u8 *)value) = hal_data->bDumpTxPkt;
13108 break;
13109 case HAL_DEF_ANT_DETECT:
13110 *((u8 *)value) = hal_data->AntDetection;
13111 break;
13112 case HAL_DEF_TX_PAGE_SIZE:
13113 *((u32 *)value) = _get_page_size(adapter);
13114 break;
13115 case HAL_DEF_TX_STBC:
13116 #ifdef CONFIG_ALPHA_SMART_ANTENNA
13117 *(u8 *)value = 0;
13118 #else
13119 *(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;
13120 #endif
13121 break;
13122 case HAL_DEF_EXPLICIT_BEAMFORMER:
13123 case HAL_DEF_EXPLICIT_BEAMFORMEE:
13124 case HAL_DEF_VHT_MU_BEAMFORMER:
13125 case HAL_DEF_VHT_MU_BEAMFORMEE:
13126 *(u8 *)value = _FALSE;
13127 break;
13128 #ifdef CONFIG_BEAMFORMING
13129 case HAL_DEF_BEAMFORMER_CAP:
13130 *(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
13131 break;
13132 case HAL_DEF_BEAMFORMEE_CAP:
13133 *(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
13134 break;
13135 #endif
13136 default:
13137 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
13138 bResult = _FAIL;
13139 break;
13140 }
13141
13142 return bResult;
13143 }
13144
13145 /*
13146 * Description:
13147 * Translate a character to hex digit.
13148 * */
13149 u32
MapCharToHexDigit(char chTmp)13150 MapCharToHexDigit(
13151 char chTmp
13152 )
13153 {
13154 if (chTmp >= '0' && chTmp <= '9')
13155 return chTmp - '0';
13156 else if (chTmp >= 'a' && chTmp <= 'f')
13157 return 10 + (chTmp - 'a');
13158 else if (chTmp >= 'A' && chTmp <= 'F')
13159 return 10 + (chTmp - 'A');
13160 else
13161 return 0;
13162 }
13163
13164
13165
13166 /*
13167 * Description:
13168 * Parse hex number from the string pucStr.
13169 * */
13170 BOOLEAN
GetHexValueFromString(char * szStr,u32 * pu4bVal,u32 * pu4bMove)13171 GetHexValueFromString(
13172 char *szStr,
13173 u32 *pu4bVal,
13174 u32 *pu4bMove
13175 )
13176 {
13177 char *szScan = szStr;
13178
13179 /* Check input parameter. */
13180 if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
13181 RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
13182 return _FALSE;
13183 }
13184
13185 /* Initialize output. */
13186 *pu4bMove = 0;
13187 *pu4bVal = 0;
13188
13189 /* Skip leading space. */
13190 while (*szScan != '\0' &&
13191 (*szScan == ' ' || *szScan == '\t')) {
13192 szScan++;
13193 (*pu4bMove)++;
13194 }
13195
13196 /* Skip leading '0x' or '0X'. */
13197 if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
13198 szScan += 2;
13199 (*pu4bMove) += 2;
13200 }
13201
13202 /* Check if szScan is now pointer to a character for hex digit, */
13203 /* if not, it means this is not a valid hex number. */
13204 if (!IsHexDigit(*szScan))
13205 return _FALSE;
13206
13207 /* Parse each digit. */
13208 do {
13209 (*pu4bVal) <<= 4;
13210 *pu4bVal += MapCharToHexDigit(*szScan);
13211
13212 szScan++;
13213 (*pu4bMove)++;
13214 } while (IsHexDigit(*szScan));
13215
13216 return _TRUE;
13217 }
13218
13219 BOOLEAN
GetFractionValueFromString(char * szStr,u8 * pInteger,u8 * pFraction,u32 * pu4bMove)13220 GetFractionValueFromString(
13221 char *szStr,
13222 u8 *pInteger,
13223 u8 *pFraction,
13224 u32 *pu4bMove
13225 )
13226 {
13227 char *szScan = szStr;
13228
13229 /* Initialize output. */
13230 *pu4bMove = 0;
13231 *pInteger = 0;
13232 *pFraction = 0;
13233
13234 /* Skip leading space. */
13235 while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) {
13236 ++szScan;
13237 ++(*pu4bMove);
13238 }
13239
13240 if (*szScan < '0' || *szScan > '9')
13241 return _FALSE;
13242
13243 /* Parse each digit. */
13244 do {
13245 (*pInteger) *= 10;
13246 *pInteger += (*szScan - '0');
13247
13248 ++szScan;
13249 ++(*pu4bMove);
13250
13251 if (*szScan == '.') {
13252 ++szScan;
13253 ++(*pu4bMove);
13254
13255 if (*szScan < '0' || *szScan > '9')
13256 return _FALSE;
13257
13258 *pFraction += (*szScan - '0') * 10;
13259 ++szScan;
13260 ++(*pu4bMove);
13261
13262 if (*szScan >= '0' && *szScan <= '9') {
13263 *pFraction += *szScan - '0';
13264 ++szScan;
13265 ++(*pu4bMove);
13266 }
13267 return _TRUE;
13268 }
13269 } while (*szScan >= '0' && *szScan <= '9');
13270
13271 return _TRUE;
13272 }
13273
13274 /*
13275 * Description:
13276 * Return TRUE if szStr is comment out with leading " */ /* ".
13277 * */
13278 BOOLEAN
IsCommentString(char * szStr)13279 IsCommentString(
13280 char *szStr
13281 )
13282 {
13283 if (*szStr == '/' && *(szStr + 1) == '/')
13284 return _TRUE;
13285 else
13286 return _FALSE;
13287 }
13288
13289 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(char * Str,u8 * pInt)13290 GetU1ByteIntegerFromStringInDecimal(
13291 char *Str,
13292 u8 *pInt
13293 )
13294 {
13295 u16 i = 0;
13296 *pInt = 0;
13297
13298 while (Str[i] != '\0') {
13299 if (Str[i] >= '0' && Str[i] <= '9') {
13300 *pInt *= 10;
13301 *pInt += (Str[i] - '0');
13302 } else
13303 return _FALSE;
13304 ++i;
13305 }
13306
13307 return _TRUE;
13308 }
13309
13310 /* <20121004, Kordan> For example,
13311 * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
13312 * If RightQualifier does not exist, it will hang on in the while loop */
13313 BOOLEAN
ParseQualifiedString(char * In,u32 * Start,char * Out,char LeftQualifier,char RightQualifier)13314 ParseQualifiedString(
13315 char *In,
13316 u32 *Start,
13317 char *Out,
13318 char LeftQualifier,
13319 char RightQualifier
13320 )
13321 {
13322 u32 i = 0, j = 0;
13323 char c = In[(*Start)++];
13324
13325 if (c != LeftQualifier)
13326 return _FALSE;
13327
13328 i = (*Start);
13329 c = In[(*Start)++];
13330 while (c != RightQualifier && c != '\0')
13331 c = In[(*Start)++];
13332
13333 if (c == '\0')
13334 return _FALSE;
13335
13336 j = (*Start) - 2;
13337 strncpy((char *)Out, (const char *)(In + i), j - i + 1);
13338
13339 return _TRUE;
13340 }
13341
13342 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)13343 isAllSpaceOrTab(
13344 u8 *data,
13345 u8 size
13346 )
13347 {
13348 u8 cnt = 0, NumOfSpaceAndTab = 0;
13349
13350 while (size > cnt) {
13351 if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
13352 ++NumOfSpaceAndTab;
13353
13354 ++cnt;
13355 }
13356
13357 return size == NumOfSpaceAndTab;
13358 }
13359
13360
rtw_hal_check_rxfifo_full(_adapter * adapter)13361 void rtw_hal_check_rxfifo_full(_adapter *adapter)
13362 {
13363 struct dvobj_priv *psdpriv = adapter->dvobj;
13364 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
13365 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
13366 struct registry_priv *regsty = &adapter->registrypriv;
13367 int save_cnt = _FALSE;
13368
13369 if (regsty->check_hw_status == 1) {
13370 /* switch counter to RX fifo */
13371 if (IS_8188E(pHalData->version_id) ||
13372 IS_8188F(pHalData->version_id) ||
13373 IS_8188GTV(pHalData->version_id) ||
13374 IS_8812_SERIES(pHalData->version_id) ||
13375 IS_8821_SERIES(pHalData->version_id) ||
13376 IS_8723B_SERIES(pHalData->version_id) ||
13377 IS_8192E(pHalData->version_id) ||
13378 IS_8703B_SERIES(pHalData->version_id) ||
13379 IS_8723D_SERIES(pHalData->version_id) ||
13380 IS_8192F_SERIES(pHalData->version_id)) {
13381 rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
13382 save_cnt = _TRUE;
13383 } else {
13384 /* todo: other chips */
13385 }
13386
13387
13388 if (save_cnt) {
13389 pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
13390 pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
13391 pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
13392 } else {
13393 /* special value to indicate no implementation */
13394 pdbgpriv->dbg_rx_fifo_last_overflow = 1;
13395 pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
13396 pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
13397 }
13398 }
13399 }
13400
linked_info_dump(_adapter * padapter,u8 benable)13401 void linked_info_dump(_adapter *padapter, u8 benable)
13402 {
13403 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
13404
13405 if (padapter->bLinkInfoDump == benable)
13406 return;
13407
13408 RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
13409
13410 if (benable) {
13411 #ifdef CONFIG_LPS
13412 pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
13413 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
13414 #endif
13415
13416 #ifdef CONFIG_IPS
13417 pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
13418 rtw_pm_set_ips(padapter, IPS_NONE);
13419 #endif
13420 } else {
13421 #ifdef CONFIG_IPS
13422 rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
13423 #endif /* CONFIG_IPS */
13424
13425 #ifdef CONFIG_LPS
13426 rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
13427 #endif /* CONFIG_LPS */
13428 }
13429 padapter->bLinkInfoDump = benable ;
13430 }
13431
13432 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)13433 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
13434 {
13435 u8 isCCKrate, rf_path;
13436 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13437 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13438 RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
13439 HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
13440 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13441
13442 if (isCCKrate)
13443 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13444
13445 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13446 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13447 continue;
13448 RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
13449 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13450
13451 if (!isCCKrate) {
13452 RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
13453 psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
13454 }
13455 }
13456 }
13457
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)13458 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
13459 {
13460 u8 isCCKrate, rf_path;
13461 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13462 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13463 _RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
13464 _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);
13465
13466 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13467
13468 if (isCCKrate)
13469 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13470
13471 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13472 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13473 continue;
13474 _RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
13475 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13476
13477 if (!isCCKrate)
13478 _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]);
13479 else
13480 _RTW_PRINT_SEL(sel , "\n");
13481
13482 }
13483 }
13484 #endif
13485
13486 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)13487 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
13488 {
13489 #define DBG_RX_DFRAME_RAW_DATA_UC 0
13490 #define DBG_RX_DFRAME_RAW_DATA_BMC 1
13491 #define DBG_RX_DFRAME_RAW_DATA_TYPES 2
13492
13493 _irqL irqL;
13494 u8 isCCKrate, rf_path;
13495 struct recv_priv *precvpriv = &(padapter->recvpriv);
13496 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13497 struct sta_priv *pstapriv = &padapter->stapriv;
13498 struct sta_info *psta;
13499 struct sta_recv_dframe_info *psta_dframe_info;
13500 int i, j;
13501 _list *plist, *phead;
13502 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13503 u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
13504
13505 if (precvpriv->store_law_data_flag) {
13506
13507 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13508
13509 for (i = 0; i < NUM_STA; i++) {
13510 phead = &(pstapriv->sta_hash[i]);
13511 plist = get_next(phead);
13512
13513 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
13514
13515 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
13516 plist = get_next(plist);
13517
13518 if (psta) {
13519 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE)
13520 && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN) != _TRUE)
13521 && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN) != _TRUE)) {
13522
13523 RTW_PRINT_SEL(sel, "==============================\n");
13524 RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
13525
13526 for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
13527 if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
13528 psta_dframe_info = &psta->sta_dframe_info;
13529 RTW_PRINT_SEL(sel, "\n");
13530 RTW_PRINT_SEL(sel, "Unicast:\n");
13531 } else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
13532 psta_dframe_info = &psta->sta_dframe_info_bmc;
13533 RTW_PRINT_SEL(sel, "\n");
13534 RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
13535 }
13536
13537 isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13538
13539 RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
13540 RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
13541
13542 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13543 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13544 continue;
13545 if (!isCCKrate) {
13546 RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
13547 _RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
13548 } else
13549 RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
13550 }
13551 }
13552
13553 }
13554 }
13555 }
13556 }
13557 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13558 }
13559 }
13560 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)13561 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
13562 {
13563 u8 isCCKrate, rf_path , dframe_type;
13564 u8 *ptr;
13565 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13566 #ifdef DBG_RX_DFRAME_RAW_DATA
13567 struct sta_recv_dframe_info *psta_dframe_info;
13568 #endif
13569 struct recv_priv *precvpriv = &(padapter->recvpriv);
13570 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13571 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
13572 struct sta_info *psta = prframe->u.hdr.psta;
13573 struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
13574 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13575 psample_pkt_rssi->data_rate = pattrib->data_rate;
13576 ptr = prframe->u.hdr.rx_data;
13577 dframe_type = GetFrameType(ptr);
13578 /*RTW_INFO("=>%s\n", __FUNCTION__);*/
13579
13580
13581 if (precvpriv->store_law_data_flag) {
13582 isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13583
13584 psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
13585 psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
13586
13587 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13588 psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
13589 psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
13590 if (!isCCKrate) {
13591 psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13592 psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13593 }
13594 }
13595 #ifdef DBG_RX_DFRAME_RAW_DATA
13596 if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
13597
13598 /*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
13599 if (psta) {
13600 if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
13601 psta_dframe_info = &psta->sta_dframe_info_bmc;
13602 else
13603 psta_dframe_info = &psta->sta_dframe_info;
13604 /*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
13605 __FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
13606 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
13607 psta_dframe_info->sta_data_rate = pattrib->data_rate;
13608 psta_dframe_info->sta_sgi = pattrib->sgi;
13609 psta_dframe_info->sta_bw_mode = pattrib->bw;
13610 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13611
13612 psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
13613
13614 if (!isCCKrate) {
13615 psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13616 psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13617 }
13618 }
13619 }
13620 }
13621 }
13622 #endif
13623 }
13624
13625 }
13626
hal_efuse_macaddr_offset(_adapter * adapter)13627 int hal_efuse_macaddr_offset(_adapter *adapter)
13628 {
13629 u8 interface_type = 0;
13630 int addr_offset = -1;
13631
13632 interface_type = rtw_get_intf_type(adapter);
13633
13634 switch (rtw_get_chip_type(adapter)) {
13635 #ifdef CONFIG_RTL8723B
13636 case RTL8723B:
13637 if (interface_type == RTW_USB)
13638 addr_offset = EEPROM_MAC_ADDR_8723BU;
13639 else if (interface_type == RTW_SDIO)
13640 addr_offset = EEPROM_MAC_ADDR_8723BS;
13641 else if (interface_type == RTW_PCIE)
13642 addr_offset = EEPROM_MAC_ADDR_8723BE;
13643 break;
13644 #endif
13645 #ifdef CONFIG_RTL8703B
13646 case RTL8703B:
13647 if (interface_type == RTW_USB)
13648 addr_offset = EEPROM_MAC_ADDR_8703BU;
13649 else if (interface_type == RTW_SDIO)
13650 addr_offset = EEPROM_MAC_ADDR_8703BS;
13651 break;
13652 #endif
13653 #ifdef CONFIG_RTL8723D
13654 case RTL8723D:
13655 if (interface_type == RTW_USB)
13656 addr_offset = EEPROM_MAC_ADDR_8723DU;
13657 else if (interface_type == RTW_SDIO)
13658 addr_offset = EEPROM_MAC_ADDR_8723DS;
13659 else if (interface_type == RTW_PCIE)
13660 addr_offset = EEPROM_MAC_ADDR_8723DE;
13661 break;
13662 #endif
13663
13664 #ifdef CONFIG_RTL8188E
13665 case RTL8188E:
13666 if (interface_type == RTW_USB)
13667 addr_offset = EEPROM_MAC_ADDR_88EU;
13668 else if (interface_type == RTW_SDIO)
13669 addr_offset = EEPROM_MAC_ADDR_88ES;
13670 else if (interface_type == RTW_PCIE)
13671 addr_offset = EEPROM_MAC_ADDR_88EE;
13672 break;
13673 #endif
13674 #ifdef CONFIG_RTL8188F
13675 case RTL8188F:
13676 if (interface_type == RTW_USB)
13677 addr_offset = EEPROM_MAC_ADDR_8188FU;
13678 else if (interface_type == RTW_SDIO)
13679 addr_offset = EEPROM_MAC_ADDR_8188FS;
13680 break;
13681 #endif
13682 #ifdef CONFIG_RTL8188GTV
13683 case RTL8188GTV:
13684 if (interface_type == RTW_USB)
13685 addr_offset = EEPROM_MAC_ADDR_8188GTVU;
13686 else if (interface_type == RTW_SDIO)
13687 addr_offset = EEPROM_MAC_ADDR_8188GTVS;
13688 break;
13689 #endif
13690 #ifdef CONFIG_RTL8812A
13691 case RTL8812:
13692 if (interface_type == RTW_USB)
13693 addr_offset = EEPROM_MAC_ADDR_8812AU;
13694 else if (interface_type == RTW_PCIE)
13695 addr_offset = EEPROM_MAC_ADDR_8812AE;
13696 break;
13697 #endif
13698 #ifdef CONFIG_RTL8821A
13699 case RTL8821:
13700 if (interface_type == RTW_USB)
13701 addr_offset = EEPROM_MAC_ADDR_8821AU;
13702 else if (interface_type == RTW_SDIO)
13703 addr_offset = EEPROM_MAC_ADDR_8821AS;
13704 else if (interface_type == RTW_PCIE)
13705 addr_offset = EEPROM_MAC_ADDR_8821AE;
13706 break;
13707 #endif
13708 #ifdef CONFIG_RTL8192E
13709 case RTL8192E:
13710 if (interface_type == RTW_USB)
13711 addr_offset = EEPROM_MAC_ADDR_8192EU;
13712 else if (interface_type == RTW_SDIO)
13713 addr_offset = EEPROM_MAC_ADDR_8192ES;
13714 else if (interface_type == RTW_PCIE)
13715 addr_offset = EEPROM_MAC_ADDR_8192EE;
13716 break;
13717 #endif
13718 #ifdef CONFIG_RTL8814A
13719 case RTL8814A:
13720 if (interface_type == RTW_USB)
13721 addr_offset = EEPROM_MAC_ADDR_8814AU;
13722 else if (interface_type == RTW_PCIE)
13723 addr_offset = EEPROM_MAC_ADDR_8814AE;
13724 break;
13725 #endif
13726
13727 #ifdef CONFIG_RTL8822B
13728 case RTL8822B:
13729 if (interface_type == RTW_USB)
13730 addr_offset = EEPROM_MAC_ADDR_8822BU;
13731 else if (interface_type == RTW_SDIO)
13732 addr_offset = EEPROM_MAC_ADDR_8822BS;
13733 else if (interface_type == RTW_PCIE)
13734 addr_offset = EEPROM_MAC_ADDR_8822BE;
13735 break;
13736 #endif /* CONFIG_RTL8822B */
13737
13738 #ifdef CONFIG_RTL8821C
13739 case RTL8821C:
13740 if (interface_type == RTW_USB)
13741 addr_offset = EEPROM_MAC_ADDR_8821CU;
13742 else if (interface_type == RTW_SDIO)
13743 addr_offset = EEPROM_MAC_ADDR_8821CS;
13744 else if (interface_type == RTW_PCIE)
13745 addr_offset = EEPROM_MAC_ADDR_8821CE;
13746 break;
13747 #endif /* CONFIG_RTL8821C */
13748
13749 #ifdef CONFIG_RTL8710B
13750 case RTL8710B:
13751 if (interface_type == RTW_USB)
13752 addr_offset = EEPROM_MAC_ADDR_8710B;
13753 break;
13754 #endif
13755
13756 #ifdef CONFIG_RTL8192F
13757 case RTL8192F:
13758 if (interface_type == RTW_USB)
13759 addr_offset = EEPROM_MAC_ADDR_8192FU;
13760 else if (interface_type == RTW_SDIO)
13761 addr_offset = EEPROM_MAC_ADDR_8192FS;
13762 else if (interface_type == RTW_PCIE)
13763 addr_offset = EEPROM_MAC_ADDR_8192FE;
13764 break;
13765 #endif /* CONFIG_RTL8192F */
13766
13767 #ifdef CONFIG_RTL8822C
13768 case RTL8822C:
13769 if (interface_type == RTW_USB)
13770 addr_offset = EEPROM_MAC_ADDR_8822CU;
13771 else if (interface_type == RTW_SDIO)
13772 addr_offset = EEPROM_MAC_ADDR_8822CS;
13773 else if (interface_type == RTW_PCIE)
13774 addr_offset = EEPROM_MAC_ADDR_8822CE;
13775 break;
13776 #endif /* CONFIG_RTL8822C */
13777
13778 #ifdef CONFIG_RTL8814B
13779 case RTL8814B:
13780 if (interface_type == RTW_USB)
13781 addr_offset = EEPROM_MAC_ADDR_8814BU;
13782 else if (interface_type == RTW_PCIE)
13783 addr_offset = EEPROM_MAC_ADDR_8814BE;
13784 break;
13785 #endif /* CONFIG_RTL8814B */
13786 }
13787
13788 if (addr_offset == -1) {
13789 RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
13790 , __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
13791 }
13792
13793 return addr_offset;
13794 }
13795
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)13796 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
13797 {
13798 int ret = _FAIL;
13799 int addr_offset;
13800
13801 addr_offset = hal_efuse_macaddr_offset(padapter);
13802 if (addr_offset == -1)
13803 goto exit;
13804
13805 ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
13806
13807 exit:
13808 return ret;
13809 }
13810
rtw_dump_cur_efuse(PADAPTER padapter)13811 void rtw_dump_cur_efuse(PADAPTER padapter)
13812 {
13813 int mapsize =0;
13814 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13815
13816 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
13817
13818 if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
13819 RTW_ERR("wrong map size %d\n", mapsize);
13820 return;
13821 }
13822
13823 #ifdef CONFIG_RTW_DEBUG
13824 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13825 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
13826 else
13827 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
13828 #endif
13829 }
13830
13831
13832 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)13833 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
13834 {
13835 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13836 u32 ret = _FALSE;
13837 u32 maplen = 0;
13838
13839 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
13840
13841 if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
13842 RTW_ERR("eFuse length error :%d\n", maplen);
13843 return _FALSE;
13844 }
13845
13846 ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
13847
13848 hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
13849
13850 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13851 rtw_dump_cur_efuse(padapter);
13852
13853 return ret;
13854 }
13855
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)13856 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
13857 {
13858 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13859 u32 ret = _FAIL;
13860
13861 if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
13862 && rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
13863 ) {
13864 hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
13865 ret = _SUCCESS;
13866 } else
13867 hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
13868
13869 return ret;
13870 }
13871 #endif /* CONFIG_EFUSE_CONFIG_FILE */
13872
hal_config_macaddr(_adapter * adapter,bool autoload_fail)13873 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
13874 {
13875 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13876 u8 addr[ETH_ALEN];
13877 int addr_offset = hal_efuse_macaddr_offset(adapter);
13878 u8 *hw_addr = NULL;
13879 int ret = _SUCCESS;
13880 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13881 u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
13882 #endif
13883
13884 if (autoload_fail)
13885 goto bypass_hw_pg;
13886
13887 if (addr_offset != -1)
13888 hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
13889
13890 #ifdef CONFIG_EFUSE_CONFIG_FILE
13891 /* if the hw_addr is written by efuse file, set to NULL */
13892 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13893 hw_addr = NULL;
13894 #endif
13895
13896 if (!hw_addr) {
13897 /* try getting hw pg data */
13898 if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
13899 hw_addr = addr;
13900 }
13901
13902 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13903 if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
13904 hw_addr[0] = 0xff;
13905 #endif
13906
13907 /* check hw pg data */
13908 if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
13909 _rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
13910 goto exit;
13911 }
13912
13913 bypass_hw_pg:
13914
13915 #ifdef CONFIG_EFUSE_CONFIG_FILE
13916 /* check wifi mac file */
13917 if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
13918 _rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
13919 goto exit;
13920 }
13921 #endif
13922
13923 _rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
13924 ret = _FAIL;
13925
13926 exit:
13927 return ret;
13928 }
13929
13930 #ifdef CONFIG_RF_POWER_TRIM
13931 u32 Array_kfreemap[] = {
13932 0x08, 0xe,
13933 0x06, 0xc,
13934 0x04, 0xa,
13935 0x02, 0x8,
13936 0x00, 0x6,
13937 0x03, 0x4,
13938 0x05, 0x2,
13939 0x07, 0x0,
13940 0x09, 0x0,
13941 0x0c, 0x0,
13942 };
13943
rtw_bb_rf_gain_offset(_adapter * padapter)13944 void rtw_bb_rf_gain_offset(_adapter *padapter)
13945 {
13946 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
13947 struct registry_priv *registry_par = &padapter->registrypriv;
13948 struct kfree_data_t *kfree_data = &pHalData->kfree_data;
13949 u8 value = pHalData->EEPROMRFGainOffset;
13950 u8 tmp = 0x3e;
13951 u32 res, i = 0;
13952 u32 ArrayLen = sizeof(Array_kfreemap) / sizeof(u32);
13953 u32 *Array = Array_kfreemap;
13954 u32 v1 = 0, v2 = 0, GainValue = 0, target = 0;
13955
13956 if (registry_par->RegPwrTrimEnable == 2) {
13957 RTW_INFO("Registry kfree default force disable.\n");
13958 return;
13959 }
13960
13961 #if defined(CONFIG_RTL8723B)
13962 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
13963 RTW_INFO("Offset RF Gain.\n");
13964 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
13965
13966 if (pHalData->EEPROMRFGainVal != 0xff) {
13967
13968 if (pHalData->ant_path == RF_PATH_A)
13969 GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
13970
13971 else
13972 GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
13973 RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
13974
13975 for (i = 0; i < ArrayLen; i += 2) {
13976 /* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
13977 v1 = Array[i];
13978 v2 = Array[i + 1];
13979 if (v1 == GainValue) {
13980 RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
13981 target = v2;
13982 break;
13983 }
13984 }
13985 RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
13986
13987 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13988 RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
13989 phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
13990 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13991
13992 RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
13993
13994 } else
13995
13996 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
13997 } else
13998 RTW_INFO("Using the default RF gain.\n");
13999
14000 #elif defined(CONFIG_RTL8188E)
14001 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
14002 RTW_INFO("8188ES Offset RF Gain.\n");
14003 RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
14004 pHalData->EEPROMRFGainVal);
14005
14006 if (pHalData->EEPROMRFGainVal != 0xff) {
14007 res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
14008 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
14009
14010 RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
14011 res &= 0xfff87fff;
14012
14013 res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
14014 RTW_INFO("Offset RF Gain. res=0x%x\n", res);
14015
14016 rtw_hal_write_rfreg(padapter, RF_PATH_A,
14017 REG_RF_BB_GAIN_OFFSET,
14018 RF_GAIN_OFFSET_MASK, res);
14019 } else {
14020 RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
14021 pHalData->EEPROMRFGainVal);
14022 }
14023 } else
14024 RTW_INFO("Using the default RF gain.\n");
14025 #else
14026 /* TODO: call this when channel switch */
14027 if (kfree_data->flag & KFREE_FLAG_ON)
14028 rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
14029 #endif
14030
14031 }
14032 #endif /*CONFIG_RF_POWER_TRIM */
14033
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)14034 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
14035 {
14036 #ifdef CONFIG_RF_POWER_TRIM
14037 int i, j;
14038
14039 for (i = 0; i < BB_GAIN_NUM; i++)
14040 for (j = 0; j < RF_PATH_MAX; j++)
14041 if (data->bb_gain[i][j] != 0)
14042 return 0;
14043 #endif
14044 return 1;
14045 }
14046
14047 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)14048 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
14049 {
14050 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14051 if (cur_wireless_mode < WIRELESS_11_24N
14052 && cur_wireless_mode > 0) { /* ABG mode */
14053 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14054 u32 remainder = 0;
14055 u8 quotient = 0;
14056
14057 remainder = MAX_RECVBUF_SZ % (4 * 1024);
14058 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14059
14060 if (quotient > 5) {
14061 pHalData->rxagg_usb_size = 0x6;
14062 pHalData->rxagg_usb_timeout = 0x10;
14063 } else {
14064 if (remainder >= 2048) {
14065 pHalData->rxagg_usb_size = quotient;
14066 pHalData->rxagg_usb_timeout = 0x10;
14067 } else {
14068 pHalData->rxagg_usb_size = (quotient - 1);
14069 pHalData->rxagg_usb_timeout = 0x10;
14070 }
14071 }
14072 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14073 if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
14074 pHalData->rxagg_usb_size = 0x6;
14075 pHalData->rxagg_usb_timeout = 0x10;
14076 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14077 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14078 }
14079 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14080
14081 } else if (cur_wireless_mode >= WIRELESS_11_24N
14082 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14083 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14084 u32 remainder = 0;
14085 u8 quotient = 0;
14086
14087 remainder = MAX_RECVBUF_SZ % (4 * 1024);
14088 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14089
14090 if (quotient > 5) {
14091 pHalData->rxagg_usb_size = 0x5;
14092 pHalData->rxagg_usb_timeout = 0x20;
14093 } else {
14094 if (remainder >= 2048) {
14095 pHalData->rxagg_usb_size = quotient;
14096 pHalData->rxagg_usb_timeout = 0x10;
14097 } else {
14098 pHalData->rxagg_usb_size = (quotient - 1);
14099 pHalData->rxagg_usb_timeout = 0x10;
14100 }
14101 }
14102 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14103 if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
14104 pHalData->rxagg_usb_size = 0x5;
14105 pHalData->rxagg_usb_timeout = 0x20;
14106 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14107 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14108 }
14109 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14110
14111 } else {
14112 /* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14113 }
14114 }
14115
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)14116 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
14117 {
14118 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14119
14120 if (cur_wireless_mode < WIRELESS_11_24N
14121 && cur_wireless_mode > 0) { /* ABG mode */
14122 if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
14123 || 0x10 != pHalData->rxagg_usb_timeout) {
14124 pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
14125 pHalData->rxagg_usb_timeout = 0x10;
14126 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14127 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14128 }
14129 } else if (cur_wireless_mode >= WIRELESS_11_24N
14130 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14131 if (UsbDmaSize != pHalData->rxagg_usb_size
14132 || 0x20 != pHalData->rxagg_usb_timeout) {
14133 pHalData->rxagg_usb_size = UsbDmaSize;
14134 pHalData->rxagg_usb_timeout = 0x20;
14135 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14136 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14137 }
14138 } else {
14139 /* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14140 }
14141 }
14142
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)14143 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
14144 {
14145 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14146 rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
14147 return;
14148 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14149
14150 rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
14151 }
14152 #endif /* CONFIG_USB_RX_AGGREGATION */
14153
14154 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)14155 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
14156 {
14157 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
14158 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14159 struct registry_priv *registry_par = &padapter->registrypriv;
14160 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14161 u8 cur_wireless_mode = WIRELESS_INVALID;
14162
14163 #ifdef CONFIG_USB_RX_AGGREGATION
14164 if (!registry_par->dynamic_agg_enable)
14165 return;
14166
14167 #ifdef RTW_HALMAC
14168 if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter)
14169 || IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter))
14170 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
14171 #else /* !RTW_HALMAC */
14172 if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
14173 /* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
14174 if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) {
14175 if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14176 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
14177 else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14178 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
14179 else
14180 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
14181
14182 /* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
14183 }
14184 } else if (IS_HARDWARE_TYPE_8812(padapter)) {
14185 #ifdef CONFIG_CONCURRENT_MODE
14186 u8 i;
14187 _adapter *iface;
14188 u8 bassocaed = _FALSE;
14189 struct mlme_ext_priv *mlmeext;
14190
14191 for (i = 0; i < pdvobjpriv->iface_nums; i++) {
14192 iface = pdvobjpriv->padapters[i];
14193 mlmeext = &iface->mlmeextpriv;
14194 if (rtw_linked_check(iface) == _TRUE) {
14195 if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
14196 cur_wireless_mode = mlmeext->cur_wireless_mode;
14197 bassocaed = _TRUE;
14198 }
14199 }
14200 if (bassocaed)
14201 #endif
14202 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14203 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14204 } else {
14205 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14206 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14207 }
14208 #endif /* RTW_HALMAC */
14209 #endif /* CONFIG_USB_RX_AGGREGATION */
14210
14211 }
14212
14213 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)14214 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
14215 {
14216 #ifdef CONFIG_AP_MODE
14217 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14218 u8 chk_rst = _SUCCESS;
14219
14220 if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
14221 return chk_rst;
14222
14223 /* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
14224 /* return chk_rst; */
14225
14226 if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
14227 && (pre_qsel != next_qsel)) {
14228 /* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
14229 /* pre_qsel,next_qsel); */
14230 chk_rst = _FAIL;
14231 }
14232 return chk_rst;
14233 #else
14234 return _SUCCESS;
14235 #endif /* CONFIG_AP_MODE */
14236 }
14237
14238 #ifdef CONFIG_WOWLAN
14239 /*
14240 * Description:
14241 * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
14242 * contant.
14243 *
14244 * Input:
14245 * adapter: adapter pointer.
14246 * page_num: The max. page number that user want to dump.
14247 * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
14248 */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)14249 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
14250 {
14251
14252 int i;
14253 u8 val = 0;
14254 u8 base = 0;
14255 u32 addr = 0;
14256 u32 count = (page_size / 8);
14257
14258 if (page_num <= 0) {
14259 RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
14260 return;
14261 }
14262
14263 if (page_size < 128 || page_size > 512) {
14264 RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
14265 return;
14266 }
14267
14268 RTW_INFO("+%s+\n", __func__);
14269 val = rtw_read8(padapter, 0x106);
14270 rtw_write8(padapter, 0x106, 0x69);
14271 RTW_INFO("0x106: 0x%02x\n", val);
14272 base = rtw_read8(padapter, 0x209);
14273 RTW_INFO("0x209: 0x%02x\n", base);
14274
14275 addr = ((base)*page_size) / 8;
14276 for (i = 0 ; i < page_num * count ; i += 2) {
14277 rtw_write32(padapter, 0x140, addr + i);
14278 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14279 rtw_write32(padapter, 0x140, addr + i + 1);
14280 printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14281 }
14282 }
14283 #endif
14284
14285 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)14286 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
14287 {
14288 u8 value = 0;
14289 u8 direction = 0;
14290 u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
14291 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
14292 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
14293 u8 gpio_num_to_set = gpio_num;
14294 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
14295
14296 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14297 return value;
14298
14299 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14300
14301 RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
14302 LeaveAllPowerSaveModeDirect(adapter);
14303
14304 if (gpio_num > 7) {
14305 gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
14306 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
14307 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
14308 gpio_num_to_set = gpio_num - 8;
14309 }
14310
14311 /* Read GPIO Direction */
14312 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14313
14314 /* According the direction to read register value */
14315 if (direction)
14316 value = (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14317 else
14318 value = (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14319
14320 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14321 RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
14322
14323 return value;
14324 }
14325
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)14326 int rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
14327 {
14328 u8 direction = 0;
14329 u8 res = -1;
14330 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
14331 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
14332 u8 gpio_num_to_set = gpio_num;
14333
14334 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14335 return -1;
14336
14337 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14338
14339 LeaveAllPowerSaveModeDirect(adapter);
14340
14341 if (gpio_num > 7) {
14342 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
14343 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
14344 gpio_num_to_set = gpio_num - 8;
14345 }
14346
14347 /* Read GPIO direction */
14348 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14349
14350 /* If GPIO is output direction, setting value. */
14351 if (direction) {
14352 if (isHigh)
14353 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
14354 else
14355 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
14356
14357 RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
14358 res = 0;
14359 } else {
14360 RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
14361 res = -1;
14362 }
14363
14364 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14365 return res;
14366 }
14367
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)14368 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
14369 {
14370 u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
14371 u8 gpio_num_to_set = gpio_num;
14372
14373 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14374 return -1;
14375
14376 RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
14377
14378 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14379
14380 LeaveAllPowerSaveModeDirect(adapter);
14381
14382 rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
14383
14384 if (gpio_num > 7) {
14385 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
14386 gpio_num_to_set = gpio_num - 8;
14387 }
14388
14389 if (isOutput)
14390 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
14391 else
14392 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
14393
14394 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14395
14396 return 0;
14397 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))14398 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
14399 {
14400 u8 value;
14401 u8 direction;
14402 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14403
14404 if (IS_HARDWARE_TYPE_8188E(adapter)) {
14405 if (gpio_num > 7 || gpio_num < 4) {
14406 RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14407 return -1;
14408 }
14409 }
14410
14411 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14412
14413 LeaveAllPowerSaveModeDirect(adapter);
14414
14415 /* Read GPIO direction */
14416 direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
14417 if (direction) {
14418 RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
14419 return -1;
14420 }
14421
14422 /* Config GPIO Mode */
14423 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
14424
14425 /* Register GPIO interrupt handler*/
14426 adapter->gpiointpriv.callback[gpio_num] = callback;
14427
14428 /* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
14429 value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
14430 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
14431 rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
14432
14433 /* Enable GPIO interrupt */
14434 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
14435 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14436
14437 rtw_hal_update_hisr_hsisr_ind(adapter, 1);
14438
14439 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14440
14441 return 0;
14442 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)14443 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
14444 {
14445 u8 value;
14446 u8 direction;
14447 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14448
14449 if (IS_HARDWARE_TYPE_8188E(adapter)) {
14450 if (gpio_num > 7 || gpio_num < 4) {
14451 RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14452 return -1;
14453 }
14454 }
14455
14456 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14457
14458 LeaveAllPowerSaveModeDirect(adapter);
14459
14460 /* Config GPIO Mode */
14461 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
14462
14463 /* Unregister GPIO interrupt handler*/
14464 adapter->gpiointpriv.callback[gpio_num] = NULL;
14465
14466 /* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
14467 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
14468 rtw_write8(adapter, REG_GPIO_INTM, 0x00);
14469
14470 /* Disable GPIO interrupt */
14471 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
14472 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14473
14474 if (!adapter->gpiointpriv.interrupt_enable_mask)
14475 rtw_hal_update_hisr_hsisr_ind(adapter, 0);
14476
14477 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14478
14479 return 0;
14480 }
14481 #endif
14482
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)14483 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
14484 {
14485 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14486 u8 i;
14487
14488 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14489 if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
14490 if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
14491 && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
14492 return i;
14493 }
14494 }
14495
14496 return -1;
14497 }
14498
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)14499 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
14500 {
14501 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14502 s8 res;
14503 u8 i;
14504
14505 /* If it's an existed record, overwrite it */
14506 res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
14507 if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
14508 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
14509 return;
14510 }
14511
14512 /* Search for the empty record to use */
14513 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14514 if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
14515 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
14516 return;
14517 }
14518 }
14519
14520 /* Else, overwrite the oldest record */
14521 for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
14522 _rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
14523
14524 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
14525 }
14526
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)14527 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
14528 {
14529 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
14530 }
14531
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14532 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14533 {
14534 u32 mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
14535 u32 mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
14536 u32 mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
14537 u32 DropPacket = 0;
14538
14539 if (!rx_counter) {
14540 rtw_warn_on(1);
14541 return;
14542 }
14543 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
14544 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14545
14546 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
14547 mac_cck_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14548 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14549 mac_ofdm_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14550 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
14551 mac_ht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14552 mac_vht_ok = 0;
14553 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14554 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14555 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14556 mac_vht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14557 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14558 }
14559
14560 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
14561 mac_cck_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14562 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14563 mac_ofdm_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14564 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
14565 mac_ht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14566 mac_vht_err = 0;
14567 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14568 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14569 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14570 mac_vht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14571 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14572 }
14573
14574 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
14575 mac_cck_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14576 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
14577 mac_ofdm_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14578 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
14579 mac_ht_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14580
14581 /* Mac_DropPacket */
14582 rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
14583 DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
14584
14585 rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
14586 rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
14587 rx_counter->rx_cck_fa = mac_cck_fa;
14588 rx_counter->rx_ofdm_fa = mac_ofdm_fa;
14589 rx_counter->rx_ht_fa = mac_ht_fa;
14590 rx_counter->rx_pkt_drop = DropPacket;
14591 }
rtw_reset_mac_rx_counters(_adapter * padapter)14592 void rtw_reset_mac_rx_counters(_adapter *padapter)
14593 {
14594
14595 /* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
14596 if (IS_HARDWARE_TYPE_8703B(padapter) ||
14597 IS_HARDWARE_TYPE_8723D(padapter) ||
14598 IS_HARDWARE_TYPE_8188F(padapter) ||
14599 IS_HARDWARE_TYPE_8188GTV(padapter) ||
14600 IS_HARDWARE_TYPE_8192F(padapter) ||
14601 IS_HARDWARE_TYPE_8822C(padapter))
14602 phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
14603
14604 /* reset mac counter */
14605 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
14606 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
14607 }
14608
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14609 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14610 {
14611 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;
14612 if (!rx_counter) {
14613 rtw_warn_on(1);
14614 return;
14615 }
14616 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14617 cckok = phy_query_bb_reg(padapter, 0xF04, 0x3FFF); /* [13:0] */
14618 ofdmok = phy_query_bb_reg(padapter, 0xF14, 0x3FFF); /* [13:0] */
14619 htok = phy_query_bb_reg(padapter, 0xF10, 0x3FFF); /* [13:0] */
14620 vht_ok = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF); /* [13:0] */
14621 cckcrc = phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16] */
14622 ofdmcrc = phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
14623 htcrc = phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
14624 vht_err = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
14625 CCK_FA = phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
14626 OFDM_FA = phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
14627 } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){
14628 cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);
14629 ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
14630 htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
14631 vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);
14632 cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);
14633 ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
14634 htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
14635 vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);
14636 CCK_FA = phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);
14637 OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
14638
14639 } else {
14640 cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
14641 ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
14642 htok = phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
14643 vht_ok = 0;
14644 cckcrc = phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
14645 ofdmcrc = phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
14646 htcrc = phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
14647 vht_err = 0;
14648 OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
14649 phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
14650 phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
14651
14652 CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
14653 }
14654
14655 rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
14656 rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
14657 rx_counter->rx_ofdm_fa = OFDM_FA;
14658 rx_counter->rx_cck_fa = CCK_FA;
14659
14660 }
14661
rtw_reset_phy_trx_ok_counters(_adapter * padapter)14662 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
14663 {
14664 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14665 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
14666 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
14667 } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14668 phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);
14669 phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);
14670 } else {
14671 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14672 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14673 }
14674 }
14675
rtw_reset_phy_rx_counters(_adapter * padapter)14676 void rtw_reset_phy_rx_counters(_adapter *padapter)
14677 {
14678 /* reset phy counter */
14679 if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14680 /* reset CCK FA counter */
14681 phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);
14682 phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);
14683
14684 /* reset CCK CCA counter */
14685 phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);
14686 phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);
14687 rtw_reset_phy_trx_ok_counters(padapter);
14688
14689 } else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14690 rtw_reset_phy_trx_ok_counters(padapter);
14691
14692 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset OFDA FA counter */
14693 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
14694
14695 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
14696 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14697 } else {
14698 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14699 rtw_msleep_os(10);
14700 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14701
14702 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset OFDA FA counter */
14703 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset OFDA FA counter */
14704 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
14705 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
14706
14707 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
14708 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14709 }
14710 }
14711 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14712 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14713 {
14714 struct recv_priv *precvpriv = &padapter->recvpriv;
14715 if (!rx_counter) {
14716 rtw_warn_on(1);
14717 return;
14718 }
14719 rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
14720 rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
14721 rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
14722 }
rtw_reset_drv_rx_counters(_adapter * padapter)14723 void rtw_reset_drv_rx_counters(_adapter *padapter)
14724 {
14725 struct recv_priv *precvpriv = &padapter->recvpriv;
14726 padapter->drv_rx_cnt_ok = 0;
14727 padapter->drv_rx_cnt_crcerror = 0;
14728 padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
14729 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)14730 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
14731 {
14732 u8 initialgain;
14733 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14734
14735 if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
14736 rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
14737 RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
14738 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14739 /*disable dynamic functions, such as high power, DIG*/
14740 rtw_phydm_ability_backup(padapter);
14741 rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
14742 } else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
14743 /* turn on phy-dynamic functions */
14744 rtw_phydm_ability_restore(padapter);
14745 initialgain = 0xff; /* restore RX GAIN */
14746 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14747
14748 }
14749 }
14750
rtw_dump_rx_counters(_adapter * padapter)14751 void rtw_dump_rx_counters(_adapter *padapter)
14752 {
14753 struct dbg_rx_counter rx_counter;
14754
14755 if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
14756 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14757 rtw_dump_drv_rx_counters(padapter, &rx_counter);
14758 RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
14759 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
14760 rtw_reset_drv_rx_counters(padapter);
14761 }
14762
14763 if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
14764 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14765 rtw_dump_mac_rx_counters(padapter, &rx_counter);
14766 RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
14767 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
14768 rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
14769 rx_counter.rx_pkt_drop);
14770 rtw_reset_mac_rx_counters(padapter);
14771 }
14772
14773 if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
14774 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14775 rtw_dump_phy_rx_counters(padapter, &rx_counter);
14776 /* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
14777 /* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
14778 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,
14779 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
14780 rtw_reset_phy_rx_counters(padapter);
14781 }
14782 }
14783 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)14784 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
14785 {
14786 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14787 u8 curr_tx_sgi = 0;
14788 struct ra_sta_info *ra_info;
14789
14790 if (!psta)
14791 return curr_tx_sgi;
14792
14793 if (padapter->fix_rate == 0xff) {
14794 #if defined(CONFIG_RTL8188E)
14795 #if (RATE_ADAPTIVE_SUPPORT == 1)
14796 curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
14797 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14798 #else
14799 ra_info = &psta->cmn.ra_info;
14800 curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
14801 #endif
14802 } else {
14803 curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
14804 }
14805
14806 return curr_tx_sgi;
14807 }
14808
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)14809 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
14810 {
14811 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14812 u8 rate_id = 0;
14813 struct ra_sta_info *ra_info;
14814
14815 if (!psta)
14816 return rate_id;
14817
14818 if (padapter->fix_rate == 0xff) {
14819 #if defined(CONFIG_RTL8188E)
14820 #if (RATE_ADAPTIVE_SUPPORT == 1)
14821 rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
14822 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14823 #else
14824 ra_info = &psta->cmn.ra_info;
14825 rate_id = ra_info->curr_tx_rate & 0x7f;
14826 #endif
14827 } else {
14828 rate_id = padapter->fix_rate & 0x7f;
14829 }
14830
14831 return rate_id;
14832 }
14833
update_IOT_info(_adapter * padapter)14834 void update_IOT_info(_adapter *padapter)
14835 {
14836 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14837 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14838
14839 switch (pmlmeinfo->assoc_AP_vendor) {
14840 case HT_IOT_PEER_MARVELL:
14841 pmlmeinfo->turboMode_cts2self = 1;
14842 pmlmeinfo->turboMode_rtsen = 0;
14843 break;
14844
14845 case HT_IOT_PEER_RALINK:
14846 pmlmeinfo->turboMode_cts2self = 0;
14847 pmlmeinfo->turboMode_rtsen = 1;
14848 break;
14849 case HT_IOT_PEER_REALTEK:
14850 /* rtw_write16(padapter, 0x4cc, 0xffff); */
14851 /* rtw_write16(padapter, 0x546, 0x01c0); */
14852 break;
14853 default:
14854 pmlmeinfo->turboMode_cts2self = 0;
14855 pmlmeinfo->turboMode_rtsen = 1;
14856 break;
14857 }
14858
14859 }
14860 #ifdef CONFIG_RTS_FULL_BW
14861 /*
14862 8188E: not support full RTS BW feature(mac REG no define 480[5])
14863 */
rtw_set_rts_bw(_adapter * padapter)14864 void rtw_set_rts_bw(_adapter *padapter) {
14865 int i;
14866 u8 enable = 1;
14867 bool connect_to_8812 = _FALSE;
14868 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14869 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14870 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
14871 struct sta_info *station = NULL;
14872
14873 for (i = 0; i < macid_ctl->num; i++) {
14874 if (rtw_macid_is_used(macid_ctl, i)) {
14875
14876 station = NULL;
14877 station = macid_ctl->sta[i];
14878 if(station) {
14879
14880 _adapter *sta_adapter =station->padapter;
14881 struct mlme_ext_priv *pmlmeext = &(sta_adapter->mlmeextpriv);
14882 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14883
14884 if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {
14885 if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) {
14886 if ( macid_ctl->sta[i]->vendor_8812) {
14887 connect_to_8812 = _TRUE;
14888 enable = 0;
14889 }
14890 }
14891 }
14892 }
14893 }
14894
14895 if(connect_to_8812)
14896 break;
14897 }
14898
14899 RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);
14900 rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);
14901 }
14902 #endif/*CONFIG_RTS_FULL_BW*/
14903
hal_spec_init(_adapter * adapter)14904 int hal_spec_init(_adapter *adapter)
14905 {
14906 u8 interface_type = 0;
14907 int ret = _SUCCESS;
14908
14909 interface_type = rtw_get_intf_type(adapter);
14910
14911 switch (rtw_get_chip_type(adapter)) {
14912 #ifdef CONFIG_RTL8723B
14913 case RTL8723B:
14914 init_hal_spec_8723b(adapter);
14915 break;
14916 #endif
14917 #ifdef CONFIG_RTL8703B
14918 case RTL8703B:
14919 init_hal_spec_8703b(adapter);
14920 break;
14921 #endif
14922 #ifdef CONFIG_RTL8723D
14923 case RTL8723D:
14924 init_hal_spec_8723d(adapter);
14925 break;
14926 #endif
14927 #ifdef CONFIG_RTL8188E
14928 case RTL8188E:
14929 init_hal_spec_8188e(adapter);
14930 break;
14931 #endif
14932 #ifdef CONFIG_RTL8188F
14933 case RTL8188F:
14934 init_hal_spec_8188f(adapter);
14935 break;
14936 #endif
14937 #ifdef CONFIG_RTL8188GTV
14938 case RTL8188GTV:
14939 init_hal_spec_8188gtv(adapter);
14940 break;
14941 #endif
14942 #ifdef CONFIG_RTL8812A
14943 case RTL8812:
14944 init_hal_spec_8812a(adapter);
14945 break;
14946 #endif
14947 #ifdef CONFIG_RTL8821A
14948 case RTL8821:
14949 init_hal_spec_8821a(adapter);
14950 break;
14951 #endif
14952 #ifdef CONFIG_RTL8192E
14953 case RTL8192E:
14954 init_hal_spec_8192e(adapter);
14955 break;
14956 #endif
14957 #ifdef CONFIG_RTL8814A
14958 case RTL8814A:
14959 init_hal_spec_8814a(adapter);
14960 break;
14961 #endif
14962 #ifdef CONFIG_RTL8822B
14963 case RTL8822B:
14964 rtl8822b_init_hal_spec(adapter);
14965 break;
14966 #endif
14967 #ifdef CONFIG_RTL8821C
14968 case RTL8821C:
14969 init_hal_spec_rtl8821c(adapter);
14970 break;
14971 #endif
14972 #ifdef CONFIG_RTL8710B
14973 case RTL8710B:
14974 init_hal_spec_8710b(adapter);
14975 break;
14976 #endif
14977 #ifdef CONFIG_RTL8192F
14978 case RTL8192F:
14979 init_hal_spec_8192f(adapter);
14980 break;
14981 #endif
14982 #ifdef CONFIG_RTL8822C
14983 case RTL8822C:
14984 rtl8822c_init_hal_spec(adapter);
14985 break;
14986 #endif
14987 #ifdef CONFIG_RTL8814B
14988 case RTL8814B:
14989 rtl8814b_init_hal_spec(adapter);
14990 break;
14991 #endif
14992 default:
14993 RTW_ERR("%s: unknown chip_type:%u\n"
14994 , __func__, rtw_get_chip_type(adapter));
14995 ret = _FAIL;
14996 break;
14997 }
14998
14999 return ret;
15000 }
15001
15002 static const char *const _band_cap_str[] = {
15003 /* BIT0 */"2G",
15004 /* BIT1 */"5G",
15005 };
15006
15007 static const char *const _bw_cap_str[] = {
15008 /* BIT0 */"5M",
15009 /* BIT1 */"10M",
15010 /* BIT2 */"20M",
15011 /* BIT3 */"40M",
15012 /* BIT4 */"80M",
15013 /* BIT5 */"160M",
15014 /* BIT6 */"80_80M",
15015 };
15016
15017 static const char *const _proto_cap_str[] = {
15018 /* BIT0 */"b",
15019 /* BIT1 */"g",
15020 /* BIT2 */"n",
15021 /* BIT3 */"ac",
15022 };
15023
15024 static const char *const _wl_func_str[] = {
15025 /* BIT0 */"P2P",
15026 /* BIT1 */"MIRACAST",
15027 /* BIT2 */"TDLS",
15028 /* BIT3 */"FTM",
15029 };
15030
dump_hal_spec(void * sel,_adapter * adapter)15031 void dump_hal_spec(void *sel, _adapter *adapter)
15032 {
15033 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15034 int i;
15035
15036 RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
15037 RTW_PRINT_SEL(sel, "macid_cap:%u\n", hal_spec->macid_cap);
15038 RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
15039 RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
15040
15041 RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
15042 RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
15043 RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);
15044 RTW_PRINT_SEL(sel, "rf_reg_path_avail_num:%u\n", hal_spec->rf_reg_path_avail_num);
15045 RTW_PRINT_SEL(sel, "rf_reg_trx_path_bmp:0x%02x\n", hal_spec->rf_reg_trx_path_bmp);
15046 RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
15047
15048 RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
15049 RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
15050
15051 RTW_PRINT_SEL(sel, "band_cap:");
15052 for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
15053 if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
15054 _RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
15055 }
15056 _RTW_PRINT_SEL(sel, "\n");
15057
15058 RTW_PRINT_SEL(sel, "bw_cap:");
15059 for (i = 0; i < BW_CAP_BIT_NUM; i++) {
15060 if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
15061 _RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
15062 }
15063 _RTW_PRINT_SEL(sel, "\n");
15064
15065 RTW_PRINT_SEL(sel, "proto_cap:");
15066 for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
15067 if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
15068 _RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
15069 }
15070 _RTW_PRINT_SEL(sel, "\n");
15071
15072 RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
15073 RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
15074
15075 RTW_PRINT_SEL(sel, "wl_func:");
15076 for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
15077 if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
15078 _RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
15079 }
15080 _RTW_PRINT_SEL(sel, "\n");
15081
15082 #if CONFIG_TX_AC_LIFETIME
15083 RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"
15084 , hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);
15085 #endif
15086
15087 RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
15088
15089 RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
15090 RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
15091 }
15092
hal_chk_band_cap(_adapter * adapter,u8 cap)15093 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
15094 {
15095 return GET_HAL_SPEC(adapter)->band_cap & cap;
15096 }
15097
hal_chk_bw_cap(_adapter * adapter,u8 cap)15098 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
15099 {
15100 return GET_HAL_SPEC(adapter)->bw_cap & cap;
15101 }
15102
hal_chk_proto_cap(_adapter * adapter,u8 cap)15103 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
15104 {
15105 return GET_HAL_SPEC(adapter)->proto_cap & cap;
15106 }
15107
hal_chk_wl_func(_adapter * adapter,u8 func)15108 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
15109 {
15110 return GET_HAL_SPEC(adapter)->wl_func & func;
15111 }
15112
hal_is_band_support(_adapter * adapter,u8 band)15113 inline bool hal_is_band_support(_adapter *adapter, u8 band)
15114 {
15115 return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
15116 }
15117
hal_is_bw_support(_adapter * adapter,u8 bw)15118 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
15119 {
15120 return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
15121 }
15122
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)15123 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
15124 {
15125 u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
15126
15127 if (mode == WIRELESS_11B)
15128 if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15129 return 1;
15130
15131 if (mode == WIRELESS_11G)
15132 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15133 return 1;
15134
15135 if (mode == WIRELESS_11A)
15136 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15137 return 1;
15138
15139 if (mode == WIRELESS_11_24N)
15140 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15141 return 1;
15142
15143 if (mode == WIRELESS_11_5N)
15144 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15145 return 1;
15146
15147 if (mode == WIRELESS_11AC)
15148 if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15149 return 1;
15150
15151 return 0;
15152 }
hal_is_mimo_support(_adapter * adapter)15153 inline bool hal_is_mimo_support(_adapter *adapter)
15154 {
15155 if ((GET_HAL_TX_NSS(adapter) == 1) &&
15156 (GET_HAL_RX_NSS(adapter) == 1))
15157 return 0;
15158 return 1;
15159 }
15160
15161 /*
15162 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
15163 * @adapter:
15164 * @in_bw: starting bw, value of enum channel_width
15165 *
15166 * Returns: value of enum channel_width
15167 */
hal_largest_bw(_adapter * adapter,u8 in_bw)15168 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
15169 {
15170 for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
15171 if (hal_is_bw_support(adapter, in_bw))
15172 break;
15173 }
15174
15175 if (!hal_is_bw_support(adapter, in_bw))
15176 rtw_warn_on(1);
15177
15178 return in_bw;
15179 }
15180
15181 #ifndef CONFIG_HAS_TX_BEACON_PAUSE
ResumeTxBeacon(_adapter * padapter)15182 void ResumeTxBeacon(_adapter *padapter)
15183 {
15184 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15185 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
15186
15187 #ifdef RTW_HALMAC
15188 /* Add this for driver using HALMAC because driver doesn't have setup time init by self */
15189 /* TBTT setup time */
15190 rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
15191 #endif
15192
15193 /* TBTT hold time: 0x540[19:8] */
15194 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
15195 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15196 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
15197 }
15198
StopTxBeacon(_adapter * padapter)15199 void StopTxBeacon(_adapter *padapter)
15200 {
15201 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15202 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
15203
15204 /* TBTT hold time: 0x540[19:8] */
15205 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
15206 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15207 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
15208 }
15209 #endif /* CONFIG_HAS_TX_BEACON_PAUSE */
15210
15211 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
15212
15213 #ifdef CONFIG_CLIENT_PORT_CFG
15214 const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
15215 CLT_PORT0,
15216 CLT_PORT1,
15217 CLT_PORT2,
15218 CLT_PORT3
15219 };
15220
rtw_clt_port_init(struct clt_port_t * cltp)15221 void rtw_clt_port_init(struct clt_port_t *cltp)
15222 {
15223 cltp->bmp = 0;
15224 cltp->num = 0;
15225 _rtw_spinlock_init(&cltp->lock);
15226 }
rtw_clt_port_deinit(struct clt_port_t * cltp)15227 void rtw_clt_port_deinit(struct clt_port_t *cltp)
15228 {
15229 _rtw_spinlock_free(&cltp->lock);
15230 }
_hw_client_port_alloc(_adapter * adapter)15231 static void _hw_client_port_alloc(_adapter *adapter)
15232 {
15233 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15234 struct clt_port_t *cltp = &dvobj->clt_port;
15235 _irqL irql;
15236 int i;
15237
15238 #if 0
15239 if (cltp->num > MAX_CLIENT_PORT_NUM) {
15240 RTW_ERR(ADPT_FMT" cann't alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
15241 rtw_warn_on(1);
15242 return;
15243 }
15244 #endif
15245
15246 if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
15247 RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
15248 ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
15249 return;
15250 }
15251 _enter_critical_bh(&cltp->lock, &irql);
15252 for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
15253 if (!(cltp->bmp & BIT(i)))
15254 break;
15255 }
15256
15257 if (i < MAX_CLIENT_PORT_NUM) {
15258 adapter->client_id = i;
15259 cltp->bmp |= BIT(i);
15260 adapter->client_port = _clt_port_id[i];
15261 }
15262 cltp->num++;
15263 _exit_critical_bh(&cltp->lock, &irql);
15264 RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
15265 __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
15266 }
_hw_client_port_free(_adapter * adapter)15267 static void _hw_client_port_free(_adapter *adapter)
15268 {
15269 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15270 struct clt_port_t *cltp = &dvobj->clt_port;
15271 _irqL irql;
15272
15273 #if 0
15274 if (adapter->client_id >= MAX_CLIENT_PORT_NUM) {
15275 RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
15276 /*rtw_warn_on(1);*/
15277 }
15278 #endif
15279
15280 RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
15281 __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
15282
15283 _enter_critical_bh(&cltp->lock, &irql);
15284 if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
15285 cltp->bmp &= ~ BIT(adapter->client_id);
15286 adapter->client_id = MAX_CLIENT_PORT_NUM;
15287 adapter->client_port = CLT_PORT_INVALID;
15288 }
15289 cltp->num--;
15290 if (cltp->num < 0)
15291 cltp->num = 0;
15292 _exit_critical_bh(&cltp->lock, &irql);
15293 }
rtw_hw_client_port_allocate(_adapter * adapter)15294 void rtw_hw_client_port_allocate(_adapter *adapter)
15295 {
15296 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15297
15298 if (hal_spec->port_num != 5)
15299 return;
15300
15301 _hw_client_port_alloc(adapter);
15302 }
rtw_hw_client_port_release(_adapter * adapter)15303 void rtw_hw_client_port_release(_adapter *adapter)
15304 {
15305 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15306
15307 if (hal_spec->port_num != 5)
15308 return;
15309
15310 _hw_client_port_free(adapter);
15311 }
15312 #endif /*CONFIG_CLIENT_PORT_CFG*/
15313
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)15314 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
15315 {
15316 RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
15317
15318 rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
15319
15320 /* set net_type */
15321 Set_MSR(Adapter, mode);
15322
15323 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
15324 if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
15325 StopTxBeacon(Adapter);
15326 } else if (mode == _HW_STATE_ADHOC_)
15327 ResumeTxBeacon(Adapter);
15328 else if (mode == _HW_STATE_AP_)
15329 /* enable rx ps-poll */
15330 rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
15331
15332 /* enable rx data frame */
15333 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
15334
15335 #ifdef CONFIG_CLIENT_PORT_CFG
15336 if (mode == _HW_STATE_STATION_)
15337 rtw_hw_client_port_allocate(Adapter);
15338 else
15339 rtw_hw_client_port_release(Adapter);
15340 #endif
15341 #if defined(CONFIG_RTL8192F)
15342 rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
15343 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
15344 #endif
15345 }
15346 #endif
15347
15348 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)15349 u8 rtw_hal_antdiv_before_linked(_adapter *padapter)
15350 {
15351 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15352 u8 cur_ant, change_ant;
15353
15354 if (!pHalData->AntDivCfg)
15355 return _FALSE;
15356
15357 if (pHalData->sw_antdiv_bl_state == 0) {
15358 pHalData->sw_antdiv_bl_state = 1;
15359
15360 rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
15361 change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
15362
15363 return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
15364 }
15365
15366 pHalData->sw_antdiv_bl_state = 0;
15367 return _FALSE;
15368 }
15369
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)15370 void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
15371 {
15372 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15373
15374 if (pHalData->AntDivCfg) {
15375 /*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
15376 /*select optimum_antenna for before linked =>For antenna diversity*/
15377 if (dst->Rssi >= src->Rssi) {/*keep org parameter*/
15378 src->Rssi = dst->Rssi;
15379 src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
15380 }
15381 }
15382 }
15383 #endif
15384
15385 #ifdef CONFIG_PROC_DEBUG
15386 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)15387 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
15388 {
15389 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
15390 struct phy_spec_t *phy_spec = &pHalData->phy_spec;
15391
15392 RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
15393 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
15394 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
15395 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index [15:8]*/
15396 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index [7:0]*/
15397
15398 RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
15399 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]*/
15400 /*VHT STBC Rx [23:16]
15401 0 = not support
15402 1 = support for 1 spatial stream
15403 2 = support for 1 or 2 spatial streams
15404 3 = support for 1 or 2 or 3 spatial streams
15405 4 = support for 1 or 2 or 3 or 4 spatial streams*/
15406 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
15407 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]*/
15408 /*HT STBC Rx [7:0]
15409 0 = not support
15410 1 = support for 1 spatial stream
15411 2 = support for 1 or 2 spatial streams
15412 3 = support for 1 or 2 or 3 spatial streams*/
15413 RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
15414
15415 RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
15416 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]*/
15417 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]*/
15418 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]*/
15419 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]*/
15420 #ifdef CONFIG_BEAMFORMING
15421 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
15422 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]*/
15423 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]*/
15424 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]*/
15425 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]*/
15426 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF) ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
15427 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
15428
15429 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
15430 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
15431 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
15432 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
15433 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
15434 #endif
15435 }
15436 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)15437 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
15438 {
15439 u8 phy_cap = _FALSE;
15440
15441 /* STBC */
15442 rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
15443 RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15444
15445 phy_cap = _FALSE;
15446 rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
15447 RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15448
15449 /* LDPC support */
15450 phy_cap = _FALSE;
15451 rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
15452 RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15453
15454 phy_cap = _FALSE;
15455 rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
15456 RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15457
15458 #ifdef CONFIG_BEAMFORMING
15459 phy_cap = _FALSE;
15460 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
15461 RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15462
15463 phy_cap = _FALSE;
15464 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
15465 RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15466
15467 phy_cap = _FALSE;
15468 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
15469 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15470
15471 phy_cap = _FALSE;
15472 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
15473 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15474 #endif
15475 }
15476 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)15477 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
15478 {
15479 RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
15480 #ifdef CONFIG_PHY_CAPABILITY_QUERY
15481 rtw_dump_phy_cap_by_phydmapi(sel, adapter);
15482 #else
15483 rtw_dump_phy_cap_by_hal(sel, adapter);
15484 #endif
15485 }
15486 #endif
15487
translate_dbm_to_percentage(s16 signal)15488 inline s16 translate_dbm_to_percentage(s16 signal)
15489 {
15490 if ((signal <= -100) || (signal >= 20))
15491 return 0;
15492 else if (signal >= 0)
15493 return 100;
15494 else
15495 return 100 + signal;
15496 }
15497
15498 #ifdef CONFIG_SWTIMER_BASED_TXBCN
15499 #ifdef CONFIG_BCN_RECOVERY
15500 #define REG_CPU_MGQ_INFO 0x041C
15501 #define BIT_BCN_POLL BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)15502 u8 rtw_ap_bcn_recovery(_adapter *padapter)
15503 {
15504 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15505
15506 if (hal_data->issue_bcn_fail >= 2) {
15507 RTW_ERR("%s ISSUE BCN Fail\n", __func__);
15508 rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
15509 hal_data->issue_bcn_fail = 0;
15510 }
15511 return _SUCCESS;
15512 }
15513 #endif /*CONFIG_BCN_RECOVERY*/
15514
15515 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)15516 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
15517 {
15518 u32 start_time = rtw_get_current_time();
15519 u8 bcn_queue_empty = _FALSE;
15520
15521 do {
15522 if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
15523 bcn_queue_empty = _TRUE;
15524 break;
15525 }
15526 } while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
15527
15528 if (bcn_queue_empty == _FALSE)
15529 RTW_ERR("%s BCN queue not empty\n", __func__);
15530
15531 return bcn_queue_empty;
15532 }
15533 #endif /*CONFIG_BCN_XMIT_PROTECT*/
15534 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
15535
15536 /**
15537 * rtw_hal_get_trx_path() - Get RF path related information
15538 * @d: struct dvobj_priv*
15539 * @type: RF type, nTnR
15540 * @tx: Tx path
15541 * @rx: Rx path
15542 *
15543 * Get RF type, TX path and RX path information.
15544 */
rtw_hal_get_trx_path(struct dvobj_priv * d,enum rf_type * type,enum bb_path * tx,enum bb_path * rx)15545 void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,
15546 enum bb_path *tx, enum bb_path *rx)
15547 {
15548 struct _ADAPTER *a = dvobj_get_primary_adapter(d);
15549 enum rf_type t = GET_HAL_RFPATH(a);
15550
15551 if (type)
15552 *type = t;
15553
15554 if (tx || rx) {
15555 u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);
15556 u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);
15557
15558 if (!tx_bmp && !rx_bmp)
15559 rf_type_to_default_trx_bmp(t, tx, rx);
15560 else {
15561 if (tx)
15562 *tx = GET_HAL_TX_PATH_BMP(a);
15563 if (rx)
15564 *rx = GET_HAL_RX_PATH_BMP(a);
15565 }
15566 }
15567 }
15568
15569 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
rtw_hal_switch_chnl_and_set_bw_offload(_adapter * adapter,u8 central_ch,u8 pri_ch_idx,u8 bw)15570 void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
15571 {
15572 u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
15573 PHAL_DATA_TYPE hal;
15574 struct submit_ctx *chsw_sctx;
15575
15576 hal = GET_HAL_DATA(adapter);
15577 chsw_sctx = &hal->chsw_sctx;
15578
15579 SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
15580 SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
15581 SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
15582
15583 rtw_sctx_init(chsw_sctx, 10);
15584 rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
15585 rtw_sctx_wait(chsw_sctx, __func__);
15586 }
15587 #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
15588
phy_get_current_tx_num(PADAPTER pAdapter,u8 Rate)15589 u8 phy_get_current_tx_num(
15590 PADAPTER pAdapter,
15591 u8 Rate
15592 )
15593 {
15594 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(pAdapter);
15595 u8 tx_num = 0;
15596
15597 if (IS_1T_RATE(Rate))
15598 tx_num = hal_data->txpath_num_nss[0];
15599 else if (IS_2T_RATE(Rate))
15600 tx_num = hal_data->txpath_num_nss[1];
15601 else if (IS_3T_RATE(Rate))
15602 tx_num = hal_data->txpath_num_nss[2];
15603 else if (IS_4T_RATE(Rate))
15604 tx_num = hal_data->txpath_num_nss[3];
15605 else
15606 rtw_warn_on(1);
15607
15608 return tx_num == 0 ? RF_1TX : tx_num - 1;
15609 }
15610
15611 #ifdef CONFIG_RTL8812A
rtw_hal_set_8812a_vendor_ie(_adapter * padapter,u8 * pframe,uint * frlen)15612 u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {
15613 int vender_len = 7;
15614 unsigned char vendor_info[vender_len];
15615 unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
15616 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15617
15618 if( !IS_HARDWARE_TYPE_8812(padapter) )
15619 return pframe;
15620
15621 _rtw_memset(vendor_info,0,vender_len);
15622 _rtw_memcpy(vendor_info, REALTEK_OUI, 3);
15623 vendor_info[4] =2;
15624 if(pHalData->version_id.CUTVersion > B_CUT_VERSION )
15625 vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;
15626 else
15627 vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;
15628 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);
15629
15630 return pframe;
15631 }
15632 #endif /*CONFIG_RTL8812A*/
15633
rtw_enter_protsel(struct protsel * protsel,u32 sel)15634 static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)
15635 {
15636 int refcnt;
15637
15638 _enter_critical_mutex(&protsel->mutex, NULL);
15639
15640 refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);
15641
15642 WARN_ON(refcnt > 1 && protsel->sel != sel);
15643
15644 protsel->sel = sel;
15645
15646 _exit_critical_mutex(&protsel->mutex, NULL);
15647 }
15648
rtw_leave_protsel(struct protsel * protsel)15649 static inline void rtw_leave_protsel(struct protsel *protsel)
15650 {
15651 int refcnt;
15652
15653 _enter_critical_mutex(&protsel->mutex, NULL);
15654
15655 refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);
15656
15657 _exit_critical_mutex(&protsel->mutex, NULL);
15658
15659 WARN_ON(refcnt < 0);
15660 }
15661
rtw_assert_protsel(struct protsel * protsel)15662 static inline bool rtw_assert_protsel(struct protsel *protsel)
15663 {
15664 int refcnt = ATOMIC_READ(&protsel->refcnt);
15665
15666 if (refcnt > 0)
15667 return true;
15668
15669 return false;
15670 }
15671
15672 #ifdef CONFIG_PROTSEL_PORT
rtw_enter_protsel_port(_adapter * padapter,u8 port_sel)15673 void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)
15674 {
15675 u8 val8;
15676
15677 rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);
15678
15679 val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);
15680 val8 &= ~BIT_MASK_PORT_CTRL_SEL;
15681 val8 |= BIT_PORT_CTRL_SEL(port_sel);
15682 rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);
15683 }
15684
rtw_assert_protsel_port(_adapter * padapter,u32 addr,u8 len)15685 bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)
15686 {
15687 if (!padapter->bup) /* don't assert before IF up */
15688 return true;
15689
15690 return rtw_assert_protsel(&padapter->dvobj->protsel_port);
15691 }
15692
rtw_leave_protsel_port(_adapter * padapter)15693 void rtw_leave_protsel_port(_adapter *padapter)
15694 {
15695 rtw_leave_protsel(&padapter->dvobj->protsel_port);
15696 }
15697 #endif
15698
15699 #ifdef CONFIG_PROTSEL_ATIMDTIM
rtw_enter_protsel_atimdtim(_adapter * padapter,u8 port_sel)15700 void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)
15701 {
15702 /* 0~15 is for port 0 MBSSID setting
15703 * 16 is for port 1 setting
15704 * 17 is for port 2 setting
15705 * 18 is for port 3 setting
15706 * 19 is for port 4 setting
15707 */
15708 u8 val8;
15709
15710 if (port_sel >= 1 && port_sel <= 4)
15711 port_sel += 15;
15712
15713 rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);
15714
15715 val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);
15716 val8 &= ~BIT_MASK_ATIM_DTIM_SEL;
15717 val8 |= BIT_ATIM_DTIM_SEL(port_sel);
15718 rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);
15719 }
15720
rtw_assert_protsel_atimdtim(_adapter * padapter,u32 addr,u8 len)15721 bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)
15722 {
15723 return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);
15724 }
15725
rtw_leave_protsel_atimdtim(_adapter * padapter)15726 void rtw_leave_protsel_atimdtim(_adapter *padapter)
15727 {
15728 rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);
15729 }
15730 #endif
15731
15732 #ifdef CONFIG_PROTSEL_MACSLEEP
rtw_enter_protsel_macsleep(_adapter * padapter,u8 sel)15733 void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)
15734 {
15735 u32 val32;
15736
15737 rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);
15738
15739 val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);
15740 val32 &= ~BIT_MASK_MACID_SLEEP_SEL;
15741 val32 |= BIT_MACID_SLEEP_SEL(sel);
15742 rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);
15743 }
15744
rtw_assert_protsel_macsleep(_adapter * padapter,u32 addr,u8 len)15745 bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)
15746 {
15747 return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);
15748 }
15749
rtw_leave_protsel_macsleep(_adapter * padapter)15750 void rtw_leave_protsel_macsleep(_adapter *padapter)
15751 {
15752 rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);
15753 }
15754 #endif
15755
15756 #ifndef RTW_HALMAC
rtw_hal_init_sifs_backup(_adapter * adapter)15757 void rtw_hal_init_sifs_backup(_adapter *adapter)
15758 {
15759 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
15760
15761 hal_data->init_reg_0x428 = rtw_read16(adapter, 0x428);
15762 hal_data->init_reg_0x514 = rtw_read32(adapter, 0x514);
15763 hal_data->init_reg_0x63a = rtw_read16(adapter, 0x63a);
15764 hal_data->init_reg_0x63c = rtw_read32(adapter, 0x63c);
15765
15766 #ifndef RTW_SIFS_INIT_CHK
15767 #define RTW_SIFS_INIT_CHK 1
15768 #endif
15769
15770 #if RTW_SIFS_INIT_CHK
15771 /*
15772 the expected initial values:
15773 0x428[15:0]=0x100A
15774 0x514[31:0]=0x0E0A0E0A
15775 0x63A[15:0]=0x100A
15776 0x63C[31:0]=0x0E0E0A0A
15777 */
15778 #define INIT_REG_0x428 0x100A
15779 #define INIT_REG_0x514 0x0E0A0E0A
15780 #define INIT_REG_0x63A 0x100A
15781 #define INIT_REG_0x63C 0x0E0E0A0A
15782
15783 if (hal_data->init_reg_0x428 != INIT_REG_0x428) {
15784 RTW_WARN("init_reg_0x428:0x%04x != 0x%04x\n", hal_data->init_reg_0x428, INIT_REG_0x428);
15785 #if RTW_SIFS_INIT_CHK > 1
15786 hal_data->init_reg_0x428 = INIT_REG_0x428;
15787 rtw_write16(adapter, 0x428, hal_data->init_reg_0x428);
15788 #endif
15789 }
15790 if (hal_data->init_reg_0x514 != INIT_REG_0x514) {
15791 RTW_WARN("init_reg_0x514:0x%08x != 0x%08x\n", hal_data->init_reg_0x514, INIT_REG_0x514);
15792 #if RTW_SIFS_INIT_CHK > 1
15793 hal_data->init_reg_0x514 = INIT_REG_0x514;
15794 rtw_write32(adapter, 0x514, hal_data->init_reg_0x514);
15795 #endif
15796 }
15797 if (hal_data->init_reg_0x63a != INIT_REG_0x63A) {
15798 RTW_WARN("init_reg_0x63a:0x%04x != 0x%04x\n", hal_data->init_reg_0x63a, INIT_REG_0x63A);
15799 #if RTW_SIFS_INIT_CHK > 1
15800 hal_data->init_reg_0x63a = INIT_REG_0x63A;
15801 rtw_write16(adapter, 0x63a, hal_data->init_reg_0x63a);
15802 #endif
15803 }
15804 if (hal_data->init_reg_0x63c != INIT_REG_0x63C) {
15805 RTW_WARN("init_reg_0x63c:0x%08x != 0x%08x\n", hal_data->init_reg_0x63c, INIT_REG_0x63C);
15806 #if RTW_SIFS_INIT_CHK > 1
15807 hal_data->init_reg_0x63c = INIT_REG_0x63C;
15808 rtw_write32(adapter, 0x63c, hal_data->init_reg_0x63c);
15809 #endif
15810 }
15811 #endif
15812 }
15813 #endif
15814