1 /* SPDX-License-Identifier: GPL-2.0 */
2 /******************************************************************************
3 *
4 * Copyright(c) 2007 - 2017 Realtek Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 *****************************************************************************/
16 #define _HAL_COM_C_
17
18 #include <drv_types.h>
19 #include "hal_com_h2c.h"
20
21 #include "hal_data.h"
22
23 #ifdef RTW_HALMAC
24 #include "../../hal/hal_halmac.h"
25 #endif
26
rtw_dump_fw_info(void * sel,_adapter * adapter)27 void rtw_dump_fw_info(void *sel, _adapter *adapter)
28 {
29 HAL_DATA_TYPE *hal_data = NULL;
30
31 if (!adapter)
32 return;
33
34 hal_data = GET_HAL_DATA(adapter);
35 if (hal_data->bFWReady)
36 RTW_PRINT_SEL(sel, "FW VER -%d.%d\n", hal_data->firmware_version, hal_data->firmware_sub_version);
37 else
38 RTW_PRINT_SEL(sel, "FW not ready\n");
39 }
40
rsvd_page_cache_update_all(struct rsvd_page_cache_t * cache,u8 loc,u8 txdesc_len,u32 page_size,u8 * info,u32 info_len)41 bool rsvd_page_cache_update_all(struct rsvd_page_cache_t *cache, u8 loc
42 , u8 txdesc_len, u32 page_size, u8 *info, u32 info_len)
43 {
44 u8 page_num;
45 bool modified = 0;
46 bool loc_mod = 0, size_mod = 0, page_num_mod = 0;
47
48 page_num = info_len ? (u8)PageNum(txdesc_len + info_len, page_size) : 0;
49 if (!info_len)
50 loc = 0;
51
52 if (cache->loc != loc) {
53 RTW_INFO("%s %s loc change (%u -> %u)\n"
54 , __func__, cache->name, cache->loc, loc);
55 loc_mod = 1;
56 }
57 if (cache->size != info_len) {
58 RTW_INFO("%s %s size change (%u -> %u)\n"
59 , __func__, cache->name, cache->size, info_len);
60 size_mod = 1;
61 }
62 if (cache->page_num != page_num) {
63 RTW_INFO("%s %s page_num change (%u -> %u)\n"
64 , __func__, cache->name, cache->page_num, page_num);
65 page_num_mod = 1;
66 }
67
68 if (info && info_len) {
69 if (cache->data) {
70 if (cache->size == info_len) {
71 if (_rtw_memcmp(cache->data, info, info_len) != _TRUE) {
72 RTW_INFO("%s %s data change\n", __func__, cache->name);
73 modified = 1;
74 }
75 } else
76 rsvd_page_cache_free_data(cache);
77 }
78
79 if (!cache->data) {
80 cache->data = rtw_malloc(info_len);
81 if (!cache->data) {
82 RTW_ERR("%s %s alloc data with size(%u) fail\n"
83 , __func__, cache->name, info_len);
84 rtw_warn_on(1);
85 } else {
86 RTW_INFO("%s %s alloc data with size(%u)\n"
87 , __func__, cache->name, info_len);
88 }
89 modified = 1;
90 }
91
92 if (cache->data && modified)
93 _rtw_memcpy(cache->data, info, info_len);
94 } else {
95 if (cache->data && size_mod)
96 rsvd_page_cache_free_data(cache);
97 }
98
99 cache->loc = loc;
100 cache->page_num = page_num;
101 cache->size = info_len;
102
103 return modified | loc_mod | size_mod | page_num_mod;
104 }
105
rsvd_page_cache_update_data(struct rsvd_page_cache_t * cache,u8 * info,u32 info_len)106 bool rsvd_page_cache_update_data(struct rsvd_page_cache_t *cache, u8 *info, u32 info_len)
107 {
108 bool modified = 0;
109
110 if (!info || !info_len) {
111 RTW_WARN("%s %s invalid input(info:%p, info_len:%u)\n"
112 , __func__, cache->name, info, info_len);
113 goto exit;
114 }
115
116 if (!cache->loc || !cache->page_num || !cache->size) {
117 RTW_ERR("%s %s layout not ready(loc:%u, page_num:%u, size:%u)\n"
118 , __func__, cache->name, cache->loc, cache->page_num, cache->size);
119 rtw_warn_on(1);
120 goto exit;
121 }
122
123 if (cache->size != info_len) {
124 RTW_ERR("%s %s size(%u) differ with info_len(%u)\n"
125 , __func__, cache->name, cache->size, info_len);
126 rtw_warn_on(1);
127 goto exit;
128 }
129
130 if (!cache->data) {
131 cache->data = rtw_zmalloc(cache->size);
132 if (!cache->data) {
133 RTW_ERR("%s %s alloc data with size(%u) fail\n"
134 , __func__, cache->name, cache->size);
135 rtw_warn_on(1);
136 goto exit;
137 } else {
138 RTW_INFO("%s %s alloc data with size(%u)\n"
139 , __func__, cache->name, info_len);
140 }
141 modified = 1;
142 }
143
144 if (_rtw_memcmp(cache->data, info, cache->size) == _FALSE) {
145 RTW_INFO("%s %s data change\n", __func__, cache->name);
146 _rtw_memcpy(cache->data, info, cache->size);
147 modified = 1;
148 }
149
150 exit:
151 return modified;
152 }
153
rsvd_page_cache_free_data(struct rsvd_page_cache_t * cache)154 void rsvd_page_cache_free_data(struct rsvd_page_cache_t *cache)
155 {
156 if (cache->data) {
157 rtw_mfree(cache->data, cache->size);
158 cache->data = NULL;
159 }
160 }
161
rsvd_page_cache_free(struct rsvd_page_cache_t * cache)162 void rsvd_page_cache_free(struct rsvd_page_cache_t *cache)
163 {
164 cache->loc = 0;
165 cache->page_num = 0;
166 rsvd_page_cache_free_data(cache);
167 cache->size = 0;
168 }
169
170 /* #define CONFIG_GTK_OL_DBG */
171
172 /*#define DBG_SEC_CAM_MOVE*/
173 #ifdef DBG_SEC_CAM_MOVE
rtw_hal_move_sta_gk_to_dk(_adapter * adapter)174 void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
175 {
176 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
177 int cam_id, index = 0;
178 u8 *addr = NULL;
179
180 if (!MLME_IS_STA(adapter))
181 return;
182
183 addr = get_bssid(pmlmepriv);
184
185 if (addr == NULL) {
186 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
187 return;
188 }
189
190 rtw_clean_dk_section(adapter);
191
192 do {
193 cam_id = rtw_camid_search(adapter, addr, index, 1);
194
195 if (cam_id == -1)
196 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
197 else
198 rtw_sec_cam_swap(adapter, cam_id, index);
199
200 index++;
201 } while (index < 4);
202
203 }
204
rtw_hal_read_sta_dk_key(_adapter * adapter,u8 key_id)205 void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
206 {
207 struct security_priv *psecuritypriv = &adapter->securitypriv;
208 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
209 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
210 _irqL irqL;
211 u8 get_key[16];
212
213 _rtw_memset(get_key, 0, sizeof(get_key));
214
215 if (key_id > 4) {
216 RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
217 rtw_warn_on(1);
218 return;
219 }
220 rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
221
222 /*update key into related sw variable*/
223 _enter_critical_bh(&cam_ctl->lock, &irqL);
224 if (_rtw_camid_is_gk(adapter, key_id)) {
225 RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
226 RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
227 }
228 _exit_critical_bh(&cam_ctl->lock, &irqL);
229
230 }
231 #endif
232
233
234 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
235 char rtw_phy_para_file_path[PATH_LENGTH_MAX];
236 #endif
237
dump_chip_info(HAL_VERSION ChipVersion)238 void dump_chip_info(HAL_VERSION ChipVersion)
239 {
240 int cnt = 0;
241 u8 buf[128] = {0};
242
243 if (IS_8188E(ChipVersion))
244 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
245 else if (IS_8188F(ChipVersion))
246 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
247 else if (IS_8188GTV(ChipVersion))
248 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188GTV_");
249 else if (IS_8812_SERIES(ChipVersion))
250 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
251 else if (IS_8192E(ChipVersion))
252 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
253 else if (IS_8821_SERIES(ChipVersion))
254 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
255 else if (IS_8723B_SERIES(ChipVersion))
256 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
257 else if (IS_8703B_SERIES(ChipVersion))
258 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
259 else if (IS_8723D_SERIES(ChipVersion))
260 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
261 else if (IS_8814A_SERIES(ChipVersion))
262 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
263 else if (IS_8822B_SERIES(ChipVersion))
264 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
265 else if (IS_8821C_SERIES(ChipVersion))
266 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
267 else if (IS_8710B_SERIES(ChipVersion))
268 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8710B_");
269 else if (IS_8192F_SERIES(ChipVersion))
270 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192F_");
271 else if (IS_8822C_SERIES(ChipVersion))
272 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822C_");
273 else
274 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
275
276 cnt += sprintf((buf + cnt), "%s", IS_NORMAL_CHIP(ChipVersion) ? "" : "T_");
277
278 if (IS_CHIP_VENDOR_TSMC(ChipVersion))
279 cnt += sprintf((buf + cnt), "%s", "T");
280 else if (IS_CHIP_VENDOR_UMC(ChipVersion))
281 cnt += sprintf((buf + cnt), "%s", "U");
282 else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
283 cnt += sprintf((buf + cnt), "%s", "S");
284
285 if (IS_A_CUT(ChipVersion))
286 cnt += sprintf((buf + cnt), "1_");
287 else if (IS_B_CUT(ChipVersion))
288 cnt += sprintf((buf + cnt), "2_");
289 else if (IS_C_CUT(ChipVersion))
290 cnt += sprintf((buf + cnt), "3_");
291 else if (IS_D_CUT(ChipVersion))
292 cnt += sprintf((buf + cnt), "4_");
293 else if (IS_E_CUT(ChipVersion))
294 cnt += sprintf((buf + cnt), "5_");
295 else if (IS_F_CUT(ChipVersion))
296 cnt += sprintf((buf + cnt), "6_");
297 else if (IS_I_CUT(ChipVersion))
298 cnt += sprintf((buf + cnt), "9_");
299 else if (IS_J_CUT(ChipVersion))
300 cnt += sprintf((buf + cnt), "10_");
301 else if (IS_K_CUT(ChipVersion))
302 cnt += sprintf((buf + cnt), "11_");
303 else
304 cnt += sprintf((buf + cnt), "UNKNOWN_Cv(%d)_", ChipVersion.CUTVersion);
305
306 if (IS_1T1R(ChipVersion))
307 cnt += sprintf((buf + cnt), "1T1R_");
308 else if (IS_1T2R(ChipVersion))
309 cnt += sprintf((buf + cnt), "1T2R_");
310 else if (IS_2T2R(ChipVersion))
311 cnt += sprintf((buf + cnt), "2T2R_");
312 else if (IS_3T3R(ChipVersion))
313 cnt += sprintf((buf + cnt), "3T3R_");
314 else if (IS_3T4R(ChipVersion))
315 cnt += sprintf((buf + cnt), "3T4R_");
316 else if (IS_4T4R(ChipVersion))
317 cnt += sprintf((buf + cnt), "4T4R_");
318 else
319 cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
320
321 cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
322
323 RTW_INFO("%s", buf);
324 }
325
rtw_hal_get_port(_adapter * adapter)326 u8 rtw_hal_get_port(_adapter *adapter)
327 {
328 u8 hw_port = get_hw_port(adapter);
329 #ifdef CONFIG_CLIENT_PORT_CFG
330 u8 clt_port = get_clt_port(adapter);
331
332 if (clt_port)
333 hw_port = clt_port;
334
335 #ifdef DBG_HW_PORT
336 if (MLME_IS_STA(adapter) && (adapter->client_id != MAX_CLIENT_PORT_NUM)) {
337 if(hw_port == CLT_PORT_INVALID) {
338 RTW_ERR(ADPT_FMT" @@@@@ Client port == 0 @@@@@\n", ADPT_ARG(adapter));
339 rtw_warn_on(1);
340 }
341 }
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 if (0)
349 RTW_INFO(ADPT_FMT" - HP:%d,CP:%d\n", ADPT_ARG(adapter), get_hw_port(adapter), get_clt_port(adapter));
350 #endif /*DBG_HW_PORT*/
351
352 #endif/*CONFIG_CLIENT_PORT_CFG*/
353
354 return hw_port;
355 }
356
357 #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
358
359 /*
360 * Description:
361 * Use hardware(efuse), driver parameter(registry) and default channel plan
362 * to decide which one should be used.
363 *
364 * Parameters:
365 * padapter pointer of adapter
366 * hw_alpha2 country code from HW (efuse/eeprom/mapfile)
367 * hw_chplan channel plan from HW (efuse/eeprom/mapfile)
368 * BIT[7] software configure mode; 0:Enable, 1:disable
369 * BIT[6:0] Channel Plan
370 * sw_alpha2 country code from HW (registry/module param)
371 * sw_chplan channel plan from SW (registry/module param)
372 * AutoLoadFail efuse autoload fail or not
373 *
374 */
hal_com_config_channel_plan(PADAPTER padapter,char * hw_alpha2,u8 hw_chplan,char * sw_alpha2,u8 sw_chplan,BOOLEAN AutoLoadFail)375 void hal_com_config_channel_plan(
376 PADAPTER padapter,
377 char *hw_alpha2,
378 u8 hw_chplan,
379 char *sw_alpha2,
380 u8 sw_chplan,
381 BOOLEAN AutoLoadFail
382 )
383 {
384 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
385 PHAL_DATA_TYPE pHalData;
386 u8 force_hw_chplan = _FALSE;
387 int chplan = -1;
388 const struct country_chplan *country_ent = NULL, *ent;
389 u8 def_chplan = 0x7F; /* Realtek define, used when HW, SW both invalid */
390
391 pHalData = GET_HAL_DATA(padapter);
392
393 /* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
394 if (hw_chplan == 0xFF)
395 goto chk_hw_country_code;
396
397 if (AutoLoadFail == _TRUE)
398 goto chk_sw_config;
399
400 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
401 if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
402 force_hw_chplan = _TRUE;
403 #endif
404
405 hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
406
407 chk_hw_country_code:
408 if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
409 ent = rtw_get_chplan_from_country(hw_alpha2);
410 if (ent) {
411 /* get chplan from hw country code, by pass hw chplan setting */
412 country_ent = ent;
413 chplan = ent->chplan;
414 goto chk_sw_config;
415 } else
416 RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
417 }
418
419 if (rtw_is_channel_plan_valid(hw_chplan))
420 chplan = hw_chplan;
421 else if (force_hw_chplan == _TRUE) {
422 RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
423 /* hw infomaton invalid, refer to sw information */
424 force_hw_chplan = _FALSE;
425 }
426
427 chk_sw_config:
428 if (force_hw_chplan == _TRUE)
429 goto done;
430
431 if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
432 ent = rtw_get_chplan_from_country(sw_alpha2);
433 if (ent) {
434 /* get chplan from sw country code, by pass sw chplan setting */
435 country_ent = ent;
436 chplan = ent->chplan;
437 goto done;
438 } else
439 RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
440 }
441
442 if (rtw_is_channel_plan_valid(sw_chplan)) {
443 /* cancel hw_alpha2 because chplan is specified by sw_chplan*/
444 country_ent = NULL;
445 chplan = sw_chplan;
446 } else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
447 RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
448
449 done:
450 if (chplan == -1) {
451 RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
452 chplan = def_chplan;
453 } else if (country_ent) {
454 RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
455 , country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
456 } else
457 RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
458
459 rfctl->country_ent = country_ent;
460 rfctl->ChannelPlan = chplan;
461 pHalData->bDisableSWChannelPlan = force_hw_chplan;
462 }
463
464 BOOLEAN
HAL_IsLegalChannel(PADAPTER Adapter,u32 Channel)465 HAL_IsLegalChannel(
466 PADAPTER Adapter,
467 u32 Channel
468 )
469 {
470 BOOLEAN bLegalChannel = _TRUE;
471
472 if (Channel > 14) {
473 if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
474 bLegalChannel = _FALSE;
475 RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
476 }
477 } else if ((Channel <= 14) && (Channel >= 1)) {
478 if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
479 bLegalChannel = _FALSE;
480 RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
481 }
482 } else {
483 bLegalChannel = _FALSE;
484 RTW_INFO("Channel is Invalid !!!\n");
485 }
486
487 return bLegalChannel;
488 }
489
MRateToHwRate(u8 rate)490 u8 MRateToHwRate(u8 rate)
491 {
492 u8 ret = DESC_RATE1M;
493
494 switch (rate) {
495 case MGN_1M:
496 ret = DESC_RATE1M;
497 break;
498 case MGN_2M:
499 ret = DESC_RATE2M;
500 break;
501 case MGN_5_5M:
502 ret = DESC_RATE5_5M;
503 break;
504 case MGN_11M:
505 ret = DESC_RATE11M;
506 break;
507 case MGN_6M:
508 ret = DESC_RATE6M;
509 break;
510 case MGN_9M:
511 ret = DESC_RATE9M;
512 break;
513 case MGN_12M:
514 ret = DESC_RATE12M;
515 break;
516 case MGN_18M:
517 ret = DESC_RATE18M;
518 break;
519 case MGN_24M:
520 ret = DESC_RATE24M;
521 break;
522 case MGN_36M:
523 ret = DESC_RATE36M;
524 break;
525 case MGN_48M:
526 ret = DESC_RATE48M;
527 break;
528 case MGN_54M:
529 ret = DESC_RATE54M;
530 break;
531
532 case MGN_MCS0:
533 ret = DESC_RATEMCS0;
534 break;
535 case MGN_MCS1:
536 ret = DESC_RATEMCS1;
537 break;
538 case MGN_MCS2:
539 ret = DESC_RATEMCS2;
540 break;
541 case MGN_MCS3:
542 ret = DESC_RATEMCS3;
543 break;
544 case MGN_MCS4:
545 ret = DESC_RATEMCS4;
546 break;
547 case MGN_MCS5:
548 ret = DESC_RATEMCS5;
549 break;
550 case MGN_MCS6:
551 ret = DESC_RATEMCS6;
552 break;
553 case MGN_MCS7:
554 ret = DESC_RATEMCS7;
555 break;
556 case MGN_MCS8:
557 ret = DESC_RATEMCS8;
558 break;
559 case MGN_MCS9:
560 ret = DESC_RATEMCS9;
561 break;
562 case MGN_MCS10:
563 ret = DESC_RATEMCS10;
564 break;
565 case MGN_MCS11:
566 ret = DESC_RATEMCS11;
567 break;
568 case MGN_MCS12:
569 ret = DESC_RATEMCS12;
570 break;
571 case MGN_MCS13:
572 ret = DESC_RATEMCS13;
573 break;
574 case MGN_MCS14:
575 ret = DESC_RATEMCS14;
576 break;
577 case MGN_MCS15:
578 ret = DESC_RATEMCS15;
579 break;
580 case MGN_MCS16:
581 ret = DESC_RATEMCS16;
582 break;
583 case MGN_MCS17:
584 ret = DESC_RATEMCS17;
585 break;
586 case MGN_MCS18:
587 ret = DESC_RATEMCS18;
588 break;
589 case MGN_MCS19:
590 ret = DESC_RATEMCS19;
591 break;
592 case MGN_MCS20:
593 ret = DESC_RATEMCS20;
594 break;
595 case MGN_MCS21:
596 ret = DESC_RATEMCS21;
597 break;
598 case MGN_MCS22:
599 ret = DESC_RATEMCS22;
600 break;
601 case MGN_MCS23:
602 ret = DESC_RATEMCS23;
603 break;
604 case MGN_MCS24:
605 ret = DESC_RATEMCS24;
606 break;
607 case MGN_MCS25:
608 ret = DESC_RATEMCS25;
609 break;
610 case MGN_MCS26:
611 ret = DESC_RATEMCS26;
612 break;
613 case MGN_MCS27:
614 ret = DESC_RATEMCS27;
615 break;
616 case MGN_MCS28:
617 ret = DESC_RATEMCS28;
618 break;
619 case MGN_MCS29:
620 ret = DESC_RATEMCS29;
621 break;
622 case MGN_MCS30:
623 ret = DESC_RATEMCS30;
624 break;
625 case MGN_MCS31:
626 ret = DESC_RATEMCS31;
627 break;
628
629 case MGN_VHT1SS_MCS0:
630 ret = DESC_RATEVHTSS1MCS0;
631 break;
632 case MGN_VHT1SS_MCS1:
633 ret = DESC_RATEVHTSS1MCS1;
634 break;
635 case MGN_VHT1SS_MCS2:
636 ret = DESC_RATEVHTSS1MCS2;
637 break;
638 case MGN_VHT1SS_MCS3:
639 ret = DESC_RATEVHTSS1MCS3;
640 break;
641 case MGN_VHT1SS_MCS4:
642 ret = DESC_RATEVHTSS1MCS4;
643 break;
644 case MGN_VHT1SS_MCS5:
645 ret = DESC_RATEVHTSS1MCS5;
646 break;
647 case MGN_VHT1SS_MCS6:
648 ret = DESC_RATEVHTSS1MCS6;
649 break;
650 case MGN_VHT1SS_MCS7:
651 ret = DESC_RATEVHTSS1MCS7;
652 break;
653 case MGN_VHT1SS_MCS8:
654 ret = DESC_RATEVHTSS1MCS8;
655 break;
656 case MGN_VHT1SS_MCS9:
657 ret = DESC_RATEVHTSS1MCS9;
658 break;
659 case MGN_VHT2SS_MCS0:
660 ret = DESC_RATEVHTSS2MCS0;
661 break;
662 case MGN_VHT2SS_MCS1:
663 ret = DESC_RATEVHTSS2MCS1;
664 break;
665 case MGN_VHT2SS_MCS2:
666 ret = DESC_RATEVHTSS2MCS2;
667 break;
668 case MGN_VHT2SS_MCS3:
669 ret = DESC_RATEVHTSS2MCS3;
670 break;
671 case MGN_VHT2SS_MCS4:
672 ret = DESC_RATEVHTSS2MCS4;
673 break;
674 case MGN_VHT2SS_MCS5:
675 ret = DESC_RATEVHTSS2MCS5;
676 break;
677 case MGN_VHT2SS_MCS6:
678 ret = DESC_RATEVHTSS2MCS6;
679 break;
680 case MGN_VHT2SS_MCS7:
681 ret = DESC_RATEVHTSS2MCS7;
682 break;
683 case MGN_VHT2SS_MCS8:
684 ret = DESC_RATEVHTSS2MCS8;
685 break;
686 case MGN_VHT2SS_MCS9:
687 ret = DESC_RATEVHTSS2MCS9;
688 break;
689 case MGN_VHT3SS_MCS0:
690 ret = DESC_RATEVHTSS3MCS0;
691 break;
692 case MGN_VHT3SS_MCS1:
693 ret = DESC_RATEVHTSS3MCS1;
694 break;
695 case MGN_VHT3SS_MCS2:
696 ret = DESC_RATEVHTSS3MCS2;
697 break;
698 case MGN_VHT3SS_MCS3:
699 ret = DESC_RATEVHTSS3MCS3;
700 break;
701 case MGN_VHT3SS_MCS4:
702 ret = DESC_RATEVHTSS3MCS4;
703 break;
704 case MGN_VHT3SS_MCS5:
705 ret = DESC_RATEVHTSS3MCS5;
706 break;
707 case MGN_VHT3SS_MCS6:
708 ret = DESC_RATEVHTSS3MCS6;
709 break;
710 case MGN_VHT3SS_MCS7:
711 ret = DESC_RATEVHTSS3MCS7;
712 break;
713 case MGN_VHT3SS_MCS8:
714 ret = DESC_RATEVHTSS3MCS8;
715 break;
716 case MGN_VHT3SS_MCS9:
717 ret = DESC_RATEVHTSS3MCS9;
718 break;
719 case MGN_VHT4SS_MCS0:
720 ret = DESC_RATEVHTSS4MCS0;
721 break;
722 case MGN_VHT4SS_MCS1:
723 ret = DESC_RATEVHTSS4MCS1;
724 break;
725 case MGN_VHT4SS_MCS2:
726 ret = DESC_RATEVHTSS4MCS2;
727 break;
728 case MGN_VHT4SS_MCS3:
729 ret = DESC_RATEVHTSS4MCS3;
730 break;
731 case MGN_VHT4SS_MCS4:
732 ret = DESC_RATEVHTSS4MCS4;
733 break;
734 case MGN_VHT4SS_MCS5:
735 ret = DESC_RATEVHTSS4MCS5;
736 break;
737 case MGN_VHT4SS_MCS6:
738 ret = DESC_RATEVHTSS4MCS6;
739 break;
740 case MGN_VHT4SS_MCS7:
741 ret = DESC_RATEVHTSS4MCS7;
742 break;
743 case MGN_VHT4SS_MCS8:
744 ret = DESC_RATEVHTSS4MCS8;
745 break;
746 case MGN_VHT4SS_MCS9:
747 ret = DESC_RATEVHTSS4MCS9;
748 break;
749 default:
750 break;
751 }
752
753 return ret;
754 }
755
hw_rate_to_m_rate(u8 rate)756 u8 hw_rate_to_m_rate(u8 rate)
757 {
758 u8 ret_rate = MGN_1M;
759
760 switch (rate) {
761
762 case DESC_RATE1M:
763 ret_rate = MGN_1M;
764 break;
765 case DESC_RATE2M:
766 ret_rate = MGN_2M;
767 break;
768 case DESC_RATE5_5M:
769 ret_rate = MGN_5_5M;
770 break;
771 case DESC_RATE11M:
772 ret_rate = MGN_11M;
773 break;
774 case DESC_RATE6M:
775 ret_rate = MGN_6M;
776 break;
777 case DESC_RATE9M:
778 ret_rate = MGN_9M;
779 break;
780 case DESC_RATE12M:
781 ret_rate = MGN_12M;
782 break;
783 case DESC_RATE18M:
784 ret_rate = MGN_18M;
785 break;
786 case DESC_RATE24M:
787 ret_rate = MGN_24M;
788 break;
789 case DESC_RATE36M:
790 ret_rate = MGN_36M;
791 break;
792 case DESC_RATE48M:
793 ret_rate = MGN_48M;
794 break;
795 case DESC_RATE54M:
796 ret_rate = MGN_54M;
797 break;
798 case DESC_RATEMCS0:
799 ret_rate = MGN_MCS0;
800 break;
801 case DESC_RATEMCS1:
802 ret_rate = MGN_MCS1;
803 break;
804 case DESC_RATEMCS2:
805 ret_rate = MGN_MCS2;
806 break;
807 case DESC_RATEMCS3:
808 ret_rate = MGN_MCS3;
809 break;
810 case DESC_RATEMCS4:
811 ret_rate = MGN_MCS4;
812 break;
813 case DESC_RATEMCS5:
814 ret_rate = MGN_MCS5;
815 break;
816 case DESC_RATEMCS6:
817 ret_rate = MGN_MCS6;
818 break;
819 case DESC_RATEMCS7:
820 ret_rate = MGN_MCS7;
821 break;
822 case DESC_RATEMCS8:
823 ret_rate = MGN_MCS8;
824 break;
825 case DESC_RATEMCS9:
826 ret_rate = MGN_MCS9;
827 break;
828 case DESC_RATEMCS10:
829 ret_rate = MGN_MCS10;
830 break;
831 case DESC_RATEMCS11:
832 ret_rate = MGN_MCS11;
833 break;
834 case DESC_RATEMCS12:
835 ret_rate = MGN_MCS12;
836 break;
837 case DESC_RATEMCS13:
838 ret_rate = MGN_MCS13;
839 break;
840 case DESC_RATEMCS14:
841 ret_rate = MGN_MCS14;
842 break;
843 case DESC_RATEMCS15:
844 ret_rate = MGN_MCS15;
845 break;
846 case DESC_RATEMCS16:
847 ret_rate = MGN_MCS16;
848 break;
849 case DESC_RATEMCS17:
850 ret_rate = MGN_MCS17;
851 break;
852 case DESC_RATEMCS18:
853 ret_rate = MGN_MCS18;
854 break;
855 case DESC_RATEMCS19:
856 ret_rate = MGN_MCS19;
857 break;
858 case DESC_RATEMCS20:
859 ret_rate = MGN_MCS20;
860 break;
861 case DESC_RATEMCS21:
862 ret_rate = MGN_MCS21;
863 break;
864 case DESC_RATEMCS22:
865 ret_rate = MGN_MCS22;
866 break;
867 case DESC_RATEMCS23:
868 ret_rate = MGN_MCS23;
869 break;
870 case DESC_RATEMCS24:
871 ret_rate = MGN_MCS24;
872 break;
873 case DESC_RATEMCS25:
874 ret_rate = MGN_MCS25;
875 break;
876 case DESC_RATEMCS26:
877 ret_rate = MGN_MCS26;
878 break;
879 case DESC_RATEMCS27:
880 ret_rate = MGN_MCS27;
881 break;
882 case DESC_RATEMCS28:
883 ret_rate = MGN_MCS28;
884 break;
885 case DESC_RATEMCS29:
886 ret_rate = MGN_MCS29;
887 break;
888 case DESC_RATEMCS30:
889 ret_rate = MGN_MCS30;
890 break;
891 case DESC_RATEMCS31:
892 ret_rate = MGN_MCS31;
893 break;
894 case DESC_RATEVHTSS1MCS0:
895 ret_rate = MGN_VHT1SS_MCS0;
896 break;
897 case DESC_RATEVHTSS1MCS1:
898 ret_rate = MGN_VHT1SS_MCS1;
899 break;
900 case DESC_RATEVHTSS1MCS2:
901 ret_rate = MGN_VHT1SS_MCS2;
902 break;
903 case DESC_RATEVHTSS1MCS3:
904 ret_rate = MGN_VHT1SS_MCS3;
905 break;
906 case DESC_RATEVHTSS1MCS4:
907 ret_rate = MGN_VHT1SS_MCS4;
908 break;
909 case DESC_RATEVHTSS1MCS5:
910 ret_rate = MGN_VHT1SS_MCS5;
911 break;
912 case DESC_RATEVHTSS1MCS6:
913 ret_rate = MGN_VHT1SS_MCS6;
914 break;
915 case DESC_RATEVHTSS1MCS7:
916 ret_rate = MGN_VHT1SS_MCS7;
917 break;
918 case DESC_RATEVHTSS1MCS8:
919 ret_rate = MGN_VHT1SS_MCS8;
920 break;
921 case DESC_RATEVHTSS1MCS9:
922 ret_rate = MGN_VHT1SS_MCS9;
923 break;
924 case DESC_RATEVHTSS2MCS0:
925 ret_rate = MGN_VHT2SS_MCS0;
926 break;
927 case DESC_RATEVHTSS2MCS1:
928 ret_rate = MGN_VHT2SS_MCS1;
929 break;
930 case DESC_RATEVHTSS2MCS2:
931 ret_rate = MGN_VHT2SS_MCS2;
932 break;
933 case DESC_RATEVHTSS2MCS3:
934 ret_rate = MGN_VHT2SS_MCS3;
935 break;
936 case DESC_RATEVHTSS2MCS4:
937 ret_rate = MGN_VHT2SS_MCS4;
938 break;
939 case DESC_RATEVHTSS2MCS5:
940 ret_rate = MGN_VHT2SS_MCS5;
941 break;
942 case DESC_RATEVHTSS2MCS6:
943 ret_rate = MGN_VHT2SS_MCS6;
944 break;
945 case DESC_RATEVHTSS2MCS7:
946 ret_rate = MGN_VHT2SS_MCS7;
947 break;
948 case DESC_RATEVHTSS2MCS8:
949 ret_rate = MGN_VHT2SS_MCS8;
950 break;
951 case DESC_RATEVHTSS2MCS9:
952 ret_rate = MGN_VHT2SS_MCS9;
953 break;
954 case DESC_RATEVHTSS3MCS0:
955 ret_rate = MGN_VHT3SS_MCS0;
956 break;
957 case DESC_RATEVHTSS3MCS1:
958 ret_rate = MGN_VHT3SS_MCS1;
959 break;
960 case DESC_RATEVHTSS3MCS2:
961 ret_rate = MGN_VHT3SS_MCS2;
962 break;
963 case DESC_RATEVHTSS3MCS3:
964 ret_rate = MGN_VHT3SS_MCS3;
965 break;
966 case DESC_RATEVHTSS3MCS4:
967 ret_rate = MGN_VHT3SS_MCS4;
968 break;
969 case DESC_RATEVHTSS3MCS5:
970 ret_rate = MGN_VHT3SS_MCS5;
971 break;
972 case DESC_RATEVHTSS3MCS6:
973 ret_rate = MGN_VHT3SS_MCS6;
974 break;
975 case DESC_RATEVHTSS3MCS7:
976 ret_rate = MGN_VHT3SS_MCS7;
977 break;
978 case DESC_RATEVHTSS3MCS8:
979 ret_rate = MGN_VHT3SS_MCS8;
980 break;
981 case DESC_RATEVHTSS3MCS9:
982 ret_rate = MGN_VHT3SS_MCS9;
983 break;
984 case DESC_RATEVHTSS4MCS0:
985 ret_rate = MGN_VHT4SS_MCS0;
986 break;
987 case DESC_RATEVHTSS4MCS1:
988 ret_rate = MGN_VHT4SS_MCS1;
989 break;
990 case DESC_RATEVHTSS4MCS2:
991 ret_rate = MGN_VHT4SS_MCS2;
992 break;
993 case DESC_RATEVHTSS4MCS3:
994 ret_rate = MGN_VHT4SS_MCS3;
995 break;
996 case DESC_RATEVHTSS4MCS4:
997 ret_rate = MGN_VHT4SS_MCS4;
998 break;
999 case DESC_RATEVHTSS4MCS5:
1000 ret_rate = MGN_VHT4SS_MCS5;
1001 break;
1002 case DESC_RATEVHTSS4MCS6:
1003 ret_rate = MGN_VHT4SS_MCS6;
1004 break;
1005 case DESC_RATEVHTSS4MCS7:
1006 ret_rate = MGN_VHT4SS_MCS7;
1007 break;
1008 case DESC_RATEVHTSS4MCS8:
1009 ret_rate = MGN_VHT4SS_MCS8;
1010 break;
1011 case DESC_RATEVHTSS4MCS9:
1012 ret_rate = MGN_VHT4SS_MCS9;
1013 break;
1014
1015 default:
1016 RTW_INFO("hw_rate_to_m_rate(): Non supported Rate [%x]!!!\n", rate);
1017 break;
1018 }
1019
1020 return ret_rate;
1021 }
1022
HalSetBrateCfg(PADAPTER Adapter,u8 * mBratesOS,u16 * pBrateCfg)1023 void HalSetBrateCfg(
1024 PADAPTER Adapter,
1025 u8 *mBratesOS,
1026 u16 *pBrateCfg)
1027 {
1028 u8 i, is_brate, brate;
1029
1030 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
1031 is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
1032 brate = mBratesOS[i] & 0x7f;
1033
1034 if (is_brate) {
1035 switch (brate) {
1036 case IEEE80211_CCK_RATE_1MB:
1037 *pBrateCfg |= RATE_1M;
1038 break;
1039 case IEEE80211_CCK_RATE_2MB:
1040 *pBrateCfg |= RATE_2M;
1041 break;
1042 case IEEE80211_CCK_RATE_5MB:
1043 *pBrateCfg |= RATE_5_5M;
1044 break;
1045 case IEEE80211_CCK_RATE_11MB:
1046 *pBrateCfg |= RATE_11M;
1047 break;
1048 case IEEE80211_OFDM_RATE_6MB:
1049 *pBrateCfg |= RATE_6M;
1050 break;
1051 case IEEE80211_OFDM_RATE_9MB:
1052 *pBrateCfg |= RATE_9M;
1053 break;
1054 case IEEE80211_OFDM_RATE_12MB:
1055 *pBrateCfg |= RATE_12M;
1056 break;
1057 case IEEE80211_OFDM_RATE_18MB:
1058 *pBrateCfg |= RATE_18M;
1059 break;
1060 case IEEE80211_OFDM_RATE_24MB:
1061 *pBrateCfg |= RATE_24M;
1062 break;
1063 case IEEE80211_OFDM_RATE_36MB:
1064 *pBrateCfg |= RATE_36M;
1065 break;
1066 case IEEE80211_OFDM_RATE_48MB:
1067 *pBrateCfg |= RATE_48M;
1068 break;
1069 case IEEE80211_OFDM_RATE_54MB:
1070 *pBrateCfg |= RATE_54M;
1071 break;
1072 }
1073 }
1074 }
1075 }
1076
1077 static void
_OneOutPipeMapping(PADAPTER pAdapter)1078 _OneOutPipeMapping(
1079 PADAPTER pAdapter
1080 )
1081 {
1082 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1083
1084 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1085 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1086 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
1087 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
1088
1089 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1090 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1091 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1092 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1093 }
1094
1095 static void
_TwoOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)1096 _TwoOutPipeMapping(
1097 PADAPTER pAdapter,
1098 BOOLEAN bWIFICfg
1099 )
1100 {
1101 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1102
1103 if (bWIFICfg) { /* WMM */
1104
1105 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1106 /* { 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
1107 /* 0:ep_0 num, 1:ep_1 num */
1108
1109 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
1110 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1111 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
1112 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
1113
1114 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1115 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1116 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1117 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1118
1119 } else { /* typical setting */
1120
1121
1122 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1123 /* { 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
1124 /* 0:ep_0 num, 1:ep_1 num */
1125
1126 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1127 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1128 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
1129 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1130
1131 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1132 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1133 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1134 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1135
1136 }
1137
1138 }
1139
_ThreeOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)1140 static void _ThreeOutPipeMapping(
1141 PADAPTER pAdapter,
1142 BOOLEAN bWIFICfg
1143 )
1144 {
1145 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1146
1147 if (bWIFICfg) { /* for WMM */
1148
1149 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1150 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1151 /* 0:H, 1:N, 2:L */
1152
1153 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1154 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1155 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1156 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1157
1158 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1159 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1160 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1161 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1162
1163 } else { /* typical setting */
1164
1165
1166 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1167 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1168 /* 0:H, 1:N, 2:L */
1169
1170 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1171 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1172 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1173 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1174
1175 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1176 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1177 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1178 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1179 }
1180
1181 }
1182 #if 0
1183 static void _FourOutPipeMapping(
1184 PADAPTER pAdapter,
1185 BOOLEAN bWIFICfg
1186 )
1187 {
1188 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1189
1190 if (bWIFICfg) { /* for WMM */
1191
1192 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1193 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1194 /* 0:H, 1:N, 2:L ,3:E */
1195
1196 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1197 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1198 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1199 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1200
1201 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1202 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1203 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1204 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1205
1206 } else { /* typical setting */
1207
1208
1209 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1210 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1211 /* 0:H, 1:N, 2:L */
1212
1213 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1214 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1215 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1216 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1217
1218 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1219 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1220 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1221 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1222 }
1223
1224 }
1225 #endif
1226 BOOLEAN
Hal_MappingOutPipe(PADAPTER pAdapter,u8 NumOutPipe)1227 Hal_MappingOutPipe(
1228 PADAPTER pAdapter,
1229 u8 NumOutPipe
1230 )
1231 {
1232 struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
1233
1234 BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
1235
1236 BOOLEAN result = _TRUE;
1237
1238 switch (NumOutPipe) {
1239 case 2:
1240 _TwoOutPipeMapping(pAdapter, bWIFICfg);
1241 break;
1242 case 3:
1243 case 4:
1244 case 5:
1245 case 6:
1246 _ThreeOutPipeMapping(pAdapter, bWIFICfg);
1247 break;
1248 case 1:
1249 _OneOutPipeMapping(pAdapter);
1250 break;
1251 default:
1252 result = _FALSE;
1253 break;
1254 }
1255
1256 return result;
1257
1258 }
1259
rtw_hal_reqtxrpt(_adapter * padapter,u8 macid)1260 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1261 {
1262 if (padapter->hal_func.reqtxrpt)
1263 padapter->hal_func.reqtxrpt(padapter, macid);
1264 }
1265
rtw_hal_dump_macaddr(void * sel,_adapter * adapter)1266 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1267 {
1268 int i;
1269 _adapter *iface;
1270 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1271 u8 mac_addr[ETH_ALEN];
1272
1273 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1274 rtw_mbid_cam_dump(sel, __func__, adapter);
1275 #else
1276 rtw_mi_hal_dump_macaddr(sel, adapter);
1277 #endif
1278 }
1279
1280 #ifdef RTW_HALMAC
rtw_hal_hw_port_enable(_adapter * adapter)1281 void rtw_hal_hw_port_enable(_adapter *adapter)
1282 {
1283 #if 1
1284 u8 port_enable = _TRUE;
1285
1286 rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1287 #else
1288 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1289 struct rtw_halmac_bcn_ctrl bcn_ctrl;
1290
1291 _rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
1292 bcn_ctrl.enable_bcn = 1;
1293 bcn_ctrl.rx_bssid_fit = 1;
1294 bcn_ctrl.rxbcn_rpt = 1;
1295
1296 /*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1297 struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
1298 if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
1299 RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
1300 rtw_warn_on(1);
1301 }
1302 #endif
1303 }
rtw_hal_hw_port_disable(_adapter * adapter)1304 void rtw_hal_hw_port_disable(_adapter *adapter)
1305 {
1306 u8 port_enable = _FALSE;
1307
1308 rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1309 }
1310
rtw_restore_hw_port_cfg(_adapter * adapter)1311 void rtw_restore_hw_port_cfg(_adapter *adapter)
1312 {
1313 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1314
1315 #else
1316 int i;
1317 _adapter *iface;
1318 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1319
1320 for (i = 0; i < dvobj->iface_nums; i++) {
1321 iface = dvobj->padapters[i];
1322 if (iface)
1323 rtw_hal_hw_port_enable(iface);
1324 }
1325 #endif
1326 }
1327 #endif
1328
rtw_mi_set_mac_addr(_adapter * adapter)1329 void rtw_mi_set_mac_addr(_adapter *adapter)
1330 {
1331 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1332 rtw_mi_set_mbid_cam(adapter);
1333 #else
1334 int i;
1335 _adapter *iface;
1336 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1337
1338 for (i = 0; i < dvobj->iface_nums; i++) {
1339 iface = dvobj->padapters[i];
1340 if (iface)
1341 rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
1342 }
1343 #endif
1344 if (0)
1345 rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1346 }
1347
rtw_init_hal_com_default_value(PADAPTER Adapter)1348 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1349 {
1350 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
1351 struct registry_priv *regsty = adapter_to_regsty(Adapter);
1352
1353 pHalData->AntDetection = 1;
1354 pHalData->antenna_test = _FALSE;
1355 pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
1356 pHalData->ch_switch_offload = regsty->ch_switch_offload;
1357 pHalData->multi_ch_switch_mode = 0;
1358 #ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME
1359 if (pHalData->ch_switch_offload == 0)
1360 pHalData->ch_switch_offload = 1;
1361 #endif
1362 }
1363
1364 #ifdef CONFIG_FW_C2H_REG
c2h_evt_clear(_adapter * adapter)1365 void c2h_evt_clear(_adapter *adapter)
1366 {
1367 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1368 }
1369
c2h_evt_read_88xx(_adapter * adapter,u8 * buf)1370 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1371 {
1372 s32 ret = _FAIL;
1373 int i;
1374 u8 trigger;
1375
1376 if (buf == NULL)
1377 goto exit;
1378
1379 trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1380
1381 if (trigger == C2H_EVT_HOST_CLOSE) {
1382 goto exit; /* Not ready */
1383 } else if (trigger != C2H_EVT_FW_CLOSE) {
1384 goto clear_evt; /* Not a valid value */
1385 }
1386
1387 _rtw_memset(buf, 0, C2H_REG_LEN);
1388
1389 /* Read ID, LEN, SEQ */
1390 SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
1391 SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
1392 SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
1393
1394 if (0) {
1395 RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
1396 , C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
1397 }
1398
1399 /* Read the content */
1400 for (i = 0; i < C2H_PLEN_88XX(buf); i++)
1401 *(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1402
1403 RTW_DBG_DUMP("payload: ", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
1404
1405 ret = _SUCCESS;
1406
1407 clear_evt:
1408 /*
1409 * Clear event to notify FW we have read the command.
1410 * If this field isn't clear, the FW won't update the next command message.
1411 */
1412 c2h_evt_clear(adapter);
1413
1414 exit:
1415 return ret;
1416 }
1417 #endif /* CONFIG_FW_C2H_REG */
1418
1419 #ifdef CONFIG_FW_C2H_PKT
1420 #ifndef DBG_C2H_PKT_PRE_HDL
1421 #define DBG_C2H_PKT_PRE_HDL 0
1422 #endif
1423 #ifndef DBG_C2H_PKT_HDL
1424 #define DBG_C2H_PKT_HDL 0
1425 #endif
rtw_hal_c2h_pkt_pre_hdl(_adapter * adapter,u8 * buf,u16 len)1426 void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
1427 {
1428 #ifdef RTW_HALMAC
1429 /* TODO: extract hal_mac IC's code here*/
1430 #else
1431 u8 parse_fail = 0;
1432 u8 hdl_here = 0;
1433 s32 ret = _FAIL;
1434 u8 id, seq, plen;
1435 u8 *payload;
1436
1437 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1438 parse_fail = 1;
1439 goto exit;
1440 }
1441
1442 hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
1443 if (hdl_here)
1444 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1445 else
1446 ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
1447
1448 exit:
1449 if (parse_fail)
1450 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1451 else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
1452 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1453 , hdl_here ? "handle" : "enqueue"
1454 , ret == _SUCCESS ? "ok" : "fail"
1455 );
1456 if (DBG_C2H_PKT_PRE_HDL >= 2)
1457 RTW_PRINT_DUMP("dump: ", buf, len);
1458 }
1459 #endif
1460 }
1461
rtw_hal_c2h_pkt_hdl(_adapter * adapter,u8 * buf,u16 len)1462 void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
1463 {
1464 #ifdef RTW_HALMAC
1465 adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
1466 #else
1467 u8 parse_fail = 0;
1468 u8 bypass = 0;
1469 s32 ret = _FAIL;
1470 u8 id, seq, plen;
1471 u8 *payload;
1472
1473 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1474 parse_fail = 1;
1475 goto exit;
1476 }
1477
1478 #ifdef CONFIG_WOWLAN
1479 if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
1480 bypass = 1;
1481 ret = _SUCCESS;
1482 goto exit;
1483 }
1484 #endif
1485
1486 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1487
1488 exit:
1489 if (parse_fail)
1490 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1491 else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
1492 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1493 , !bypass ? "handle" : "bypass"
1494 , ret == _SUCCESS ? "ok" : "fail"
1495 );
1496 if (DBG_C2H_PKT_HDL >= 2)
1497 RTW_PRINT_DUMP("dump: ", buf, len);
1498 }
1499 #endif
1500 }
1501 #endif /* CONFIG_FW_C2H_PKT */
1502
c2h_iqk_offload(_adapter * adapter,u8 * data,u8 len)1503 void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
1504 {
1505 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1506 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1507
1508 RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
1509 if (0)
1510 RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
1511
1512 rtw_sctx_done(&iqk_sctx);
1513 }
1514
c2h_iqk_offload_wait(_adapter * adapter,u32 timeout_ms)1515 int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
1516 {
1517 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1518 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1519
1520 iqk_sctx->submit_time = rtw_get_current_time();
1521 iqk_sctx->timeout_ms = timeout_ms;
1522 iqk_sctx->status = RTW_SCTX_SUBMITTED;
1523
1524 return rtw_sctx_wait(iqk_sctx, __func__);
1525 }
1526
1527 #ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX
c2h_txpwr_idx_offload_done(_adapter * adapter,u8 * data,u8 len)1528 void c2h_txpwr_idx_offload_done(_adapter *adapter, u8 *data, u8 len)
1529 {
1530 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1531 struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1532
1533 if (0)
1534 RTW_INFO("txpwr_idx offload finish in %dms\n", rtw_get_passing_time_ms(sctx->submit_time));
1535 rtw_sctx_done(&sctx);
1536 }
1537
c2h_txpwr_idx_offload_wait(_adapter * adapter)1538 int c2h_txpwr_idx_offload_wait(_adapter *adapter)
1539 {
1540 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1541 struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1542
1543 return rtw_sctx_wait(sctx, __func__);
1544 }
1545 #endif
1546
1547 #define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1548 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1549 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1550 #define GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1551 #define GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1552 #define GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
1553 #define GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
1554 #define GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1555 #define GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1556 #define GET_C2H_MAC_HIDDEN_RPT_BW(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1557 #define GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1558 #define GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1559 #define GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1560
1561 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1562 #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1563 #endif
1564
1565 #ifdef CONFIG_RTW_MAC_HIDDEN_RPT
c2h_mac_hidden_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1566 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1567 {
1568 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1569 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1570 enum rf_type rf_type;
1571 u8 tx_path_num, rx_path_num;
1572 int ret = _FAIL;
1573
1574 u8 uuid_x;
1575 u8 uuid_y;
1576 u8 uuid_z;
1577 u16 uuid_crc;
1578
1579 u8 hci_type;
1580 u8 package_type;
1581 u8 tr_switch;
1582 u8 wl_func;
1583 u8 hw_stype;
1584 u8 bw;
1585 u8 ss_num = 4;
1586 u8 ant_num;
1587 u8 protocol;
1588 u8 nic;
1589
1590 int i;
1591
1592 if (len < MAC_HIDDEN_RPT_LEN) {
1593 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1594 goto exit;
1595 }
1596
1597 uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1598 uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1599 uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1600 uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1601
1602 hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1603 package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1604
1605 tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
1606
1607 wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1608 hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1609
1610 bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1611 ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1612
1613 protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1614 nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1615
1616 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1617 for (i = 0; i < len; i++)
1618 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1619
1620 RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1621 RTW_PRINT("hci_type:0x%x\n", hci_type);
1622 RTW_PRINT("package_type:0x%x\n", package_type);
1623 RTW_PRINT("tr_switch:0x%x\n", tr_switch);
1624 RTW_PRINT("wl_func:0x%x\n", wl_func);
1625 RTW_PRINT("hw_stype:0x%x\n", hw_stype);
1626 RTW_PRINT("bw:0x%x\n", bw);
1627 RTW_PRINT("ant_num:0x%x\n", ant_num);
1628 RTW_PRINT("protocol:0x%x\n", protocol);
1629 RTW_PRINT("nic:0x%x\n", nic);
1630 }
1631
1632 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
1633 if (IS_8822C_SERIES(hal_data->version_id) || IS_8814B_SERIES(hal_data->version_id)) {
1634 #define GET_C2H_MAC_HIDDEN_RPT_SS_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)
1635 ss_num = GET_C2H_MAC_HIDDEN_RPT_SS_NUM(data);
1636
1637 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1638 RTW_PRINT("ss_num:0x%x\n", ss_num);
1639
1640 if (ss_num == 0x03)
1641 ss_num = 4;
1642 }
1643 #endif
1644
1645 #if defined(CONFIG_RTL8822C)
1646 if (IS_8822C_SERIES(hal_data->version_id)) {
1647 if (ant_num == 1)
1648 hal_spec->rf_reg_trx_path_bmp = 0x22; /* 1T1R pathB */
1649 if (hw_stype == 0xE)
1650 hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, 1); /* limit 1TX only */
1651 }
1652 #endif
1653 hal_data->PackageType = package_type;
1654 hal_spec->hci_type = hci_type;
1655 hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1656 hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1657 hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1658
1659 rf_type = rtw_chip_rftype_to_hal_rftype(adapter, 0);
1660 if (!RF_TYPE_VALID(rf_type)) {
1661 RTW_ERR("%s rtw_chip_rftype_to_hal_rftype failed\n", __func__);
1662 goto exit;
1663 }
1664 hal_spec->rf_reg_path_avail_num = rtw_min(hal_spec->rf_reg_path_num, ant_num);
1665 tx_path_num = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1666 rx_path_num = rtw_min(rf_type_to_rf_rx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1667 hal_spec->rf_reg_trx_path_bmp = rtw_restrict_trx_path_bmp_by_trx_num_lmt(
1668 hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num, &tx_path_num, &rx_path_num);
1669 if (!hal_spec->rf_reg_trx_path_bmp) {
1670 RTW_ERR("%s rtw_restrict_trx_path_bmp_by_trx_num_lmt(0x%x, %u, %u) failed\n"
1671 , __func__, hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num);
1672 goto exit;
1673 }
1674 hal_spec->rf_reg_path_avail_num = rtw_max(tx_path_num, rx_path_num);
1675
1676 /*
1677 * RF TX path num >= max_tx_cnt >= tx_nss_num
1678 * ex: RF TX path num(4) >= max_tx_cnt(2) >= tx_nss_num(1)
1679 * Select at most 2 out of 4 TX RF path to do 1SS 2TX
1680 */
1681 hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, tx_path_num);
1682 hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, hal_spec->max_tx_cnt);
1683 hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ss_num);
1684
1685 hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rx_path_num);
1686 hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ss_num);
1687
1688 ret = _SUCCESS;
1689
1690 exit:
1691 return ret;
1692 }
1693
c2h_mac_hidden_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1694 int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1695 {
1696 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1697 int ret = _FAIL;
1698
1699 int i;
1700
1701 if (len < MAC_HIDDEN_RPT_2_LEN) {
1702 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
1703 goto exit;
1704 }
1705
1706 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1707 for (i = 0; i < len; i++)
1708 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1709 }
1710
1711 #if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)
1712 if (IS_8188F(hal_data->version_id) || IS_8188GTV(hal_data->version_id)) {
1713 #define GET_C2H_MAC_HIDDEN_RPT_IRV(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
1714 u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
1715
1716 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1717 RTW_PRINT("irv:0x%x\n", irv);
1718
1719 if(irv != 0xf)
1720 hal_data->version_id.CUTVersion = irv;
1721 }
1722 #endif
1723
1724 ret = _SUCCESS;
1725
1726 exit:
1727 return ret;
1728 }
1729
hal_read_mac_hidden_rpt(_adapter * adapter)1730 int hal_read_mac_hidden_rpt(_adapter *adapter)
1731 {
1732 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
1733 int ret = _FAIL;
1734 int ret_fwdl;
1735 u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
1736 systime start = rtw_get_current_time();
1737 u32 cnt = 0;
1738 u32 timeout_ms = 800;
1739 u32 min_cnt = 10;
1740 u8 id = C2H_DEFEATURE_RSVD;
1741 int i;
1742
1743 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1744 u8 hci_type = rtw_get_intf_type(adapter);
1745
1746 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1747 && !rtw_is_hw_init_completed(adapter))
1748 rtw_hal_power_on(adapter);
1749 #endif
1750
1751 /* inform FW mac hidden rpt from reg is needed */
1752 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
1753
1754 /* download FW */
1755 pHalData->not_xmitframe_fw_dl = 1;
1756 ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1757 pHalData->not_xmitframe_fw_dl = 0;
1758 if (ret_fwdl != _SUCCESS)
1759 goto mac_hidden_rpt_hdl;
1760
1761 /* polling for data ready */
1762 start = rtw_get_current_time();
1763 do {
1764 cnt++;
1765 id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1766 if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1767 break;
1768 rtw_msleep_os(10);
1769 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1770
1771 if (id == C2H_MAC_HIDDEN_RPT) {
1772 /* read data */
1773 for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
1774 mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1775 }
1776
1777 /* inform FW mac hidden rpt has read */
1778 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
1779
1780 mac_hidden_rpt_hdl:
1781 c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1782 c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
1783
1784 if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1785 ret = _SUCCESS;
1786
1787 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1788 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1789 && !rtw_is_hw_init_completed(adapter))
1790 rtw_hal_power_off(adapter);
1791 #endif
1792
1793 RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1794 , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1795
1796 return ret;
1797 }
1798 #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
1799
c2h_defeature_dbg_hdl(_adapter * adapter,u8 * data,u8 len)1800 int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
1801 {
1802 int ret = _FAIL;
1803
1804 int i;
1805
1806 if (len < DEFEATURE_DBG_LEN) {
1807 RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
1808 goto exit;
1809 }
1810
1811 for (i = 0; i < len; i++)
1812 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1813
1814 ret = _SUCCESS;
1815
1816 exit:
1817 return ret;
1818 }
1819
1820 #ifndef DBG_CUSTOMER_STR_RPT_HANDLE
1821 #define DBG_CUSTOMER_STR_RPT_HANDLE 0
1822 #endif
1823
1824 #ifdef CONFIG_RTW_CUSTOMER_STR
rtw_hal_h2c_customer_str_req(_adapter * adapter)1825 s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
1826 {
1827 u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
1828
1829 SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
1830 return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
1831 }
1832
1833 #define C2H_CUSTOMER_STR_RPT_BYTE0(_data) ((u8 *)(_data))
1834 #define C2H_CUSTOMER_STR_RPT_2_BYTE8(_data) ((u8 *)(_data))
1835
c2h_customer_str_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1836 int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1837 {
1838 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1839 int ret = _FAIL;
1840 int i;
1841
1842 if (len < CUSTOMER_STR_RPT_LEN) {
1843 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
1844 goto exit;
1845 }
1846
1847 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1848 RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
1849
1850 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1851
1852 if (dvobj->customer_str_sctx != NULL) {
1853 if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
1854 RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
1855 _rtw_memcpy(dvobj->customer_str, C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
1856 dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
1857 } else
1858 RTW_WARN("%s sctx not set\n", __func__);
1859
1860 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1861
1862 ret = _SUCCESS;
1863
1864 exit:
1865 return ret;
1866 }
1867
c2h_customer_str_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1868 int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1869 {
1870 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1871 int ret = _FAIL;
1872 int i;
1873
1874 if (len < CUSTOMER_STR_RPT_2_LEN) {
1875 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
1876 goto exit;
1877 }
1878
1879 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1880 RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
1881
1882 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1883
1884 if (dvobj->customer_str_sctx != NULL) {
1885 if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
1886 RTW_WARN("%s rpt not ready\n", __func__);
1887 _rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN, C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
1888 rtw_sctx_done(&dvobj->customer_str_sctx);
1889 } else
1890 RTW_WARN("%s sctx not set\n", __func__);
1891
1892 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1893
1894 ret = _SUCCESS;
1895
1896 exit:
1897 return ret;
1898 }
1899
1900 /* read customer str */
rtw_hal_customer_str_read(_adapter * adapter,u8 * cs)1901 s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
1902 {
1903 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1904 struct submit_ctx sctx;
1905 s32 ret = _SUCCESS;
1906
1907 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1908 if (dvobj->customer_str_sctx != NULL)
1909 ret = _FAIL;
1910 else {
1911 rtw_sctx_init(&sctx, 2 * 1000);
1912 dvobj->customer_str_sctx = &sctx;
1913 }
1914 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1915
1916 if (ret == _FAIL) {
1917 RTW_WARN("%s another handle ongoing\n", __func__);
1918 goto exit;
1919 }
1920
1921 ret = rtw_customer_str_req_cmd(adapter);
1922 if (ret != _SUCCESS) {
1923 RTW_WARN("%s read cmd fail\n", __func__);
1924 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1925 dvobj->customer_str_sctx = NULL;
1926 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1927 goto exit;
1928 }
1929
1930 /* wait till rpt done or timeout */
1931 rtw_sctx_wait(&sctx, __func__);
1932
1933 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1934 dvobj->customer_str_sctx = NULL;
1935 if (sctx.status == RTW_SCTX_DONE_SUCCESS)
1936 _rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1937 else
1938 ret = _FAIL;
1939 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1940
1941 exit:
1942 return ret;
1943 }
1944
rtw_hal_h2c_customer_str_write(_adapter * adapter,const u8 * cs)1945 s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
1946 {
1947 u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
1948 u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
1949 u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
1950 s32 ret;
1951
1952 SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
1953 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
1954
1955 SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
1956 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
1957
1958 SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
1959 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
1960
1961 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
1962 if (ret != _SUCCESS) {
1963 RTW_WARN("%s w1 fail\n", __func__);
1964 goto exit;
1965 }
1966
1967 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
1968 if (ret != _SUCCESS) {
1969 RTW_WARN("%s w2 fail\n", __func__);
1970 goto exit;
1971 }
1972
1973 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
1974 if (ret != _SUCCESS) {
1975 RTW_WARN("%s w3 fail\n", __func__);
1976 goto exit;
1977 }
1978
1979 exit:
1980 return ret;
1981 }
1982
1983 /* write customer str and check if value reported is the same as requested */
rtw_hal_customer_str_write(_adapter * adapter,const u8 * cs)1984 s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
1985 {
1986 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1987 struct submit_ctx sctx;
1988 s32 ret = _SUCCESS;
1989
1990 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1991 if (dvobj->customer_str_sctx != NULL)
1992 ret = _FAIL;
1993 else {
1994 rtw_sctx_init(&sctx, 2 * 1000);
1995 dvobj->customer_str_sctx = &sctx;
1996 }
1997 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1998
1999 if (ret == _FAIL) {
2000 RTW_WARN("%s another handle ongoing\n", __func__);
2001 goto exit;
2002 }
2003
2004 ret = rtw_customer_str_write_cmd(adapter, cs);
2005 if (ret != _SUCCESS) {
2006 RTW_WARN("%s write cmd fail\n", __func__);
2007 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2008 dvobj->customer_str_sctx = NULL;
2009 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2010 goto exit;
2011 }
2012
2013 ret = rtw_customer_str_req_cmd(adapter);
2014 if (ret != _SUCCESS) {
2015 RTW_WARN("%s read cmd fail\n", __func__);
2016 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2017 dvobj->customer_str_sctx = NULL;
2018 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2019 goto exit;
2020 }
2021
2022 /* wait till rpt done or timeout */
2023 rtw_sctx_wait(&sctx, __func__);
2024
2025 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2026 dvobj->customer_str_sctx = NULL;
2027 if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
2028 if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
2029 RTW_WARN("%s read back check fail\n", __func__);
2030 RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
2031 RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
2032 ret = _FAIL;
2033 }
2034 } else
2035 ret = _FAIL;
2036 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2037
2038 exit:
2039 return ret;
2040 }
2041 #endif /* CONFIG_RTW_CUSTOMER_STR */
2042
2043 #ifdef RTW_PER_CMD_SUPPORT_FW
2044 #define H2C_REQ_PER_RPT_LEN 5
2045 #define SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value)
2046 #define SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value)
2047 #define SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(__pH2CCmd, __Value) SET_BITS_TO_LE_4BYTE(__pH2CCmd + 1, 0, 32, __Value)
2048
rtw_hal_set_req_per_rpt_cmd(_adapter * adapter,u8 group_macid,u8 rpt_type,u32 macid_bitmap)2049 u8 rtw_hal_set_req_per_rpt_cmd(_adapter *adapter, u8 group_macid,
2050 u8 rpt_type, u32 macid_bitmap)
2051 {
2052 u8 ret = _FAIL;
2053 u8 cmd_buf[H2C_REQ_PER_RPT_LEN] = {0};
2054
2055 SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(cmd_buf, group_macid);
2056 SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(cmd_buf, rpt_type);
2057 SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(cmd_buf, macid_bitmap);
2058
2059 ret = rtw_hal_fill_h2c_cmd(adapter,
2060 H2C_REQ_PER_RPT,
2061 H2C_REQ_PER_RPT_LEN,
2062 cmd_buf);
2063 return ret;
2064 }
2065
2066 #define GET_C2H_PER_RATE_RPT_TYPE0_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2067 #define GET_C2H_PER_RATE_RPT_TYPE0_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2068 #define GET_C2H_PER_RATE_RPT_TYPE0_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
2069 #define GET_C2H_PER_RATE_RPT_TYPE0_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
2070 #define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 4, 0, 16)
2071 #define GET_C2H_PER_RATE_RPT_TYPE0_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
2072 #define GET_C2H_PER_RATE_RPT_TYPE0_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 8)
2073 #define GET_C2H_PER_RATE_RPT_TYPE0_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
2074 #define GET_C2H_PER_RATE_RPT_TYPE0_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 2)
2075 #define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 10, 0, 16)
2076
2077 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2078 #define GET_C2H_PER_RATE_RPT_TYPE1_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2079 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
2080 #define GET_C2H_PER_RATE_RPT_TYPE1_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
2081 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 8)
2082 #define GET_C2H_PER_RATE_RPT_TYPE1_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 8)
2083 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
2084 #define GET_C2H_PER_RATE_RPT_TYPE1_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 2)
2085 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
2086 #define GET_C2H_PER_RATE_RPT_TYPE1_PER2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 8)
2087 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 10, 0, 8)
2088 #define GET_C2H_PER_RATE_RPT_TYPE1_BW2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 11, 0, 2)
2089
per_rate_rpt_update(_adapter * adapter,u8 mac_id,u8 per,u8 rate,u8 bw,u8 total_pkt)2090 static void per_rate_rpt_update(_adapter *adapter, u8 mac_id,
2091 u8 per, u8 rate,
2092 u8 bw, u8 total_pkt)
2093 {
2094 #ifdef CONFIG_RTW_MESH
2095 rtw_ieee80211s_update_metric(adapter, mac_id,
2096 per, rate,
2097 bw, total_pkt);
2098 #endif
2099 }
2100
c2h_per_rate_rpt_hdl(_adapter * adapter,u8 * data,u8 len)2101 int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
2102 {
2103 /* Now only consider type0, since it covers all params in type1
2104 * type0: mac_id, per, rate, bw, total_pkt
2105 * type1: mac_id, per, rate, bw
2106 */
2107 u8 mac_id[2] = {0}, per[2] = {0}, rate[2] = {0}, bw[2] = {0};
2108 u16 total_pkt[2] = {0};
2109 int ret = _FAIL, i, macid_cnt = 0;
2110
2111 /* type0:
2112 * 1 macid includes 6 bytes info + 1 byte 0xff
2113 * 2 macid includes 2*6 bytes info
2114 */
2115 if (!(len == 7 || len == 12)) {
2116 RTW_WARN("%s len(%u) != 7 or 12\n", __FUNCTION__, len);
2117 goto exit;
2118 }
2119
2120 macid_cnt++;
2121 mac_id[0] = GET_C2H_PER_RATE_RPT_TYPE0_MACID0(data);
2122 per[0] = GET_C2H_PER_RATE_RPT_TYPE0_PER0(data);
2123 rate[0] = GET_C2H_PER_RATE_RPT_TYPE0_RATE0(data);
2124 bw[0] = GET_C2H_PER_RATE_RPT_TYPE0_BW0(data);
2125 total_pkt[0] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(data);
2126
2127 mac_id[1] = GET_C2H_PER_RATE_RPT_TYPE0_MACID1(data);
2128 /* 0xff means no report anymore */
2129 if (mac_id[1] == 0xff)
2130 goto update_per;
2131 if (len != 12) {
2132 RTW_WARN("%s incorrect format\n", __FUNCTION__);
2133 goto exit;
2134 }
2135 macid_cnt++;
2136 per[1] = GET_C2H_PER_RATE_RPT_TYPE0_PER1(data);
2137 rate[1] = GET_C2H_PER_RATE_RPT_TYPE0_RATE1(data);
2138 bw[1] = GET_C2H_PER_RATE_RPT_TYPE0_BW1(data);
2139 total_pkt[1] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(data);
2140
2141 update_per:
2142 for (i = 0; i < macid_cnt; i++) {
2143 RTW_DBG("[%s] type0 rpt[%d]: macid = %u, per = %u, "
2144 "rate = %u, bw = %u, total_pkt = %u\n",
2145 __FUNCTION__, i, mac_id[i], per[i],
2146 rate[i], bw[i], total_pkt[i]);
2147 per_rate_rpt_update(adapter, mac_id[i],
2148 per[i], rate[i],
2149 bw[i], total_pkt[i]);
2150 }
2151 ret = _SUCCESS;
2152 exit:
2153 return ret;
2154 }
2155 #endif /* RTW_PER_CMD_SUPPORT_FW */
2156
2157 #ifdef CONFIG_LPS_ACK
2158 #define GET_C2H_LPS_STATUS_RPT_GET_ACTION(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2159 #define GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2160 #define DBG_LPS_STATUS_RPT 0
2161
c2h_lps_status_rpt(PADAPTER adapter,u8 * data,u8 len)2162 int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len)
2163 {
2164 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
2165 struct submit_ctx *lps_sctx = &pwrpriv->lps_ack_sctx;
2166 u8 action = 0;
2167 s8 status_code = 0;
2168 int ret = _FAIL;
2169
2170 if (len < LPS_STATUS_RPT_LEN) {
2171 RTW_WARN("%s len(%u) < %d\n", __func__, len, LPS_STATUS_RPT_LEN);
2172 goto exit;
2173 }
2174
2175 action = GET_C2H_LPS_STATUS_RPT_GET_ACTION(data);
2176 status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data);
2177
2178 /* action=0: report force leave null data status */
2179 /* action=1: report Rf on status when receiving a SetPwrMode H2C with PwrState = RFON */
2180 switch (action) {
2181 case 0:
2182 /* status code 0: success, 1: no ack, 2: timeout, 3: cancel */
2183 case 1:
2184 /* status code 0: FW has already turn to RFON */
2185 pwrpriv->lps_ack_status = status_code;
2186
2187 if (DBG_LPS_STATUS_RPT)
2188 RTW_INFO("=== [C2H LPS Action(%d)] LPS Status Code:%d ===\n", action, status_code);
2189
2190 break;
2191 default:
2192 RTW_INFO("UnKnown Action(%d) for C2H LPS RPT\n", action);
2193 break;
2194 }
2195
2196 rtw_sctx_done(&lps_sctx);
2197 ret = _SUCCESS;
2198
2199 exit:
2200 return ret;
2201 }
2202 #endif /* CONFIG_LPS_ACK */
2203
rtw_hal_update_sta_wset(_adapter * adapter,struct sta_info * psta)2204 void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
2205 {
2206 u8 w_set = 0;
2207
2208 if (psta->wireless_mode & WIRELESS_11B)
2209 w_set |= WIRELESS_CCK;
2210
2211 if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
2212 w_set |= WIRELESS_OFDM;
2213
2214 if (psta->wireless_mode & WIRELESS_11_24N)
2215 w_set |= WIRELESS_HT;
2216
2217 if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N))
2218 w_set |= WIRELESS_VHT;
2219
2220 psta->cmn.support_wireless_set = w_set;
2221 }
2222
rtw_hal_update_sta_mimo_type(_adapter * adapter,struct sta_info * psta)2223 void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
2224 {
2225 s8 tx_nss, rx_nss;
2226
2227 tx_nss = rtw_get_sta_tx_nss(adapter, psta);
2228 rx_nss = rtw_get_sta_rx_nss(adapter, psta);
2229 if ((tx_nss == 1) && (rx_nss == 1))
2230 psta->cmn.mimo_type = RF_1T1R;
2231 else if ((tx_nss == 1) && (rx_nss == 2))
2232 psta->cmn.mimo_type = RF_1T2R;
2233 else if ((tx_nss == 2) && (rx_nss == 2))
2234 psta->cmn.mimo_type = RF_2T2R;
2235 else if ((tx_nss == 2) && (rx_nss == 3))
2236 psta->cmn.mimo_type = RF_2T3R;
2237 else if ((tx_nss == 2) && (rx_nss == 4))
2238 psta->cmn.mimo_type = RF_2T4R;
2239 else if ((tx_nss == 3) && (rx_nss == 3))
2240 psta->cmn.mimo_type = RF_3T3R;
2241 else if ((tx_nss == 3) && (rx_nss == 4))
2242 psta->cmn.mimo_type = RF_3T4R;
2243 else if ((tx_nss == 4) && (rx_nss == 4))
2244 psta->cmn.mimo_type = RF_4T4R;
2245 else
2246 rtw_warn_on(1);
2247
2248 #ifdef CONFIG_CTRL_TXSS_BY_TP
2249 rtw_ctrl_txss_update_mimo_type(adapter, psta);
2250 #endif
2251
2252 RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
2253 psta->cmn.mac_id, tx_nss, rx_nss);
2254 }
2255
rtw_hal_update_sta_smps_cap(_adapter * adapter,struct sta_info * psta)2256 void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
2257 {
2258 /*Spatial Multiplexing Power Save*/
2259 #if 0
2260 if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2261 #ifdef CONFIG_80211N_HT
2262 if (psta->htpriv.ht_option) {
2263 if (psta->htpriv.smps_cap == 0)
2264 psta->cmn.sm_ps = SM_PS_STATIC;
2265 else if (psta->htpriv.smps_cap == 1)
2266 psta->cmn.sm_ps = SM_PS_DYNAMIC;
2267 else
2268 psta->cmn.sm_ps = SM_PS_DISABLE;
2269 }
2270 #endif /* CONFIG_80211N_HT */
2271 } else
2272 #endif
2273 psta->cmn.sm_ps = SM_PS_DISABLE;
2274
2275 RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
2276 psta->cmn.mac_id, psta->cmn.sm_ps);
2277 }
2278
rtw_get_mgntframe_raid(_adapter * adapter,unsigned char network_type)2279 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
2280 {
2281
2282 u8 raid;
2283 if (IS_NEW_GENERATION_IC(adapter)) {
2284
2285 raid = (network_type & WIRELESS_11B) ? RATEID_IDX_B
2286 : RATEID_IDX_G;
2287 } else {
2288 raid = (network_type & WIRELESS_11B) ? RATR_INX_WIRELESS_B
2289 : RATR_INX_WIRELESS_G;
2290 }
2291 return raid;
2292 }
2293
rtw_hal_update_sta_rate_mask(PADAPTER padapter,struct sta_info * psta)2294 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
2295 {
2296 u8 i, tx_nss;
2297 u64 tx_ra_bitmap = 0, tmp64=0;
2298
2299 if (psta == NULL)
2300 return;
2301
2302 /* b/g mode ra_bitmap */
2303 for (i = 0; i < sizeof(psta->bssrateset); i++) {
2304 if (psta->bssrateset[i])
2305 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
2306 }
2307
2308 #ifdef CONFIG_80211N_HT
2309 if (padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
2310 tx_nss = GET_HAL_TX_NSS(padapter);
2311 #ifdef CONFIG_80211AC_VHT
2312 if (psta->vhtpriv.vht_option) {
2313 /* AC mode ra_bitmap */
2314 tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
2315 } else
2316 #endif /* CONFIG_80211AC_VHT */
2317 if (psta->htpriv.ht_option) {
2318 /* n mode ra_bitmap */
2319
2320 /* Handling SMPS mode for AP MODE only*/
2321 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2322 /*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
2323 if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
2324 /*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
2325 tx_nss = rtw_min(tx_nss, 1);
2326 }
2327 }
2328
2329 tmp64 = rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss);
2330 tx_ra_bitmap |= (tmp64 << 12);
2331 }
2332 }
2333 #endif /* CONFIG_80211N_HT */
2334 psta->cmn.ra_info.ramask = tx_ra_bitmap;
2335 psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
2336 }
2337
rtw_hal_update_sta_ra_info(PADAPTER padapter,struct sta_info * psta)2338 void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
2339 {
2340 rtw_hal_update_sta_mimo_type(padapter, psta);
2341 rtw_hal_update_sta_smps_cap(padapter, psta);
2342 rtw_hal_update_sta_rate_mask(padapter, psta);
2343 }
2344
2345 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
hw_bcn_ctrl_addr(_adapter * adapter,u8 hw_port)2346 static u32 hw_bcn_ctrl_addr(_adapter *adapter, u8 hw_port)
2347 {
2348 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2349
2350 if (hw_port >= hal_spec->port_num) {
2351 RTW_ERR(FUNC_ADPT_FMT" HW Port(%d) invalid\n", FUNC_ADPT_ARG(adapter), hw_port);
2352 rtw_warn_on(1);
2353 return 0;
2354 }
2355
2356 switch (hw_port) {
2357 case HW_PORT0:
2358 return REG_BCN_CTRL;
2359 case HW_PORT1:
2360 return REG_BCN_CTRL_1;
2361 }
2362
2363 return 0;
2364 }
2365 #endif
2366
rtw_hal_get_msr(_adapter * adapter,u8 * net_type)2367 static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2368 {
2369 #ifdef RTW_HALMAC
2370 rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
2371 adapter->hw_port, net_type);
2372 #else /* !RTW_HALMAC */
2373 switch (adapter->hw_port) {
2374 case HW_PORT0:
2375 /*REG_CR - BIT[17:16]-Network Type for port 1*/
2376 *net_type = rtw_read8(adapter, MSR) & 0x03;
2377 break;
2378 case HW_PORT1:
2379 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2380 *net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2381 break;
2382 #if defined(CONFIG_RTL8814A)
2383 case HW_PORT2:
2384 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2385 *net_type = rtw_read8(adapter, MSR1) & 0x03;
2386 break;
2387 case HW_PORT3:
2388 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2389 *net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2390 break;
2391 case HW_PORT4:
2392 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2393 *net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2394 break;
2395 #endif /*#if defined(CONFIG_RTL8814A)*/
2396 default:
2397 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2398 ADPT_ARG(adapter), adapter->hw_port);
2399 rtw_warn_on(1);
2400 break;
2401 }
2402 #endif /* !RTW_HALMAC */
2403 }
2404
2405 #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)2406 static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
2407 {
2408 if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
2409 if (net_type != _HW_STATE_NOLINK_)
2410 return _HW_STATE_AP_;
2411 }
2412 return net_type;
2413 }
2414 #endif
rtw_hal_set_msr(_adapter * adapter,u8 net_type)2415 static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2416 {
2417 #ifdef RTW_HALMAC
2418 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2419 net_type = rtw_hal_net_type_decision(adapter, net_type);
2420 #endif
2421 rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
2422 adapter->hw_port, net_type);
2423 #else /* !RTW_HALMAC */
2424 u8 val8 = 0;
2425
2426 switch (adapter->hw_port) {
2427 case HW_PORT0:
2428 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2429 net_type = rtw_hal_net_type_decision(adapter, net_type);
2430 #endif
2431 /*REG_CR - BIT[17:16]-Network Type for port 0*/
2432 val8 = rtw_read8(adapter, MSR) & 0x0C;
2433 val8 |= net_type;
2434 rtw_write8(adapter, MSR, val8);
2435 break;
2436 case HW_PORT1:
2437 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2438 val8 = rtw_read8(adapter, MSR) & 0x03;
2439 val8 |= net_type << 2;
2440 rtw_write8(adapter, MSR, val8);
2441 break;
2442 #if defined(CONFIG_RTL8814A)
2443 case HW_PORT2:
2444 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2445 val8 = rtw_read8(adapter, MSR1) & 0xFC;
2446 val8 |= net_type;
2447 rtw_write8(adapter, MSR1, val8);
2448 break;
2449 case HW_PORT3:
2450 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2451 val8 = rtw_read8(adapter, MSR1) & 0xF3;
2452 val8 |= net_type << 2;
2453 rtw_write8(adapter, MSR1, val8);
2454 break;
2455 case HW_PORT4:
2456 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2457 val8 = rtw_read8(adapter, MSR1) & 0xCF;
2458 val8 |= net_type << 4;
2459 rtw_write8(adapter, MSR1, val8);
2460 break;
2461 #endif /* CONFIG_RTL8814A */
2462 default:
2463 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2464 ADPT_ARG(adapter), adapter->hw_port);
2465 rtw_warn_on(1);
2466 break;
2467 }
2468 #endif /* !RTW_HALMAC */
2469 }
2470
2471 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
2472 #define SEC_CAM_ACCESS_TIMEOUT_MS 200
2473 #endif
2474
2475 #ifndef DBG_SEC_CAM_ACCESS
2476 #define DBG_SEC_CAM_ACCESS 0
2477 #endif
2478
rtw_sec_read_cam(_adapter * adapter,u8 addr)2479 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
2480 {
2481 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2482 u32 rdata;
2483 u32 cnt = 0;
2484 systime start = 0, end = 0;
2485 u8 timeout = 0;
2486 u8 sr = 0;
2487
2488 _enter_critical_mutex(mutex, NULL);
2489
2490 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
2491
2492 start = rtw_get_current_time();
2493 while (1) {
2494 if (rtw_is_surprise_removed(adapter)) {
2495 sr = 1;
2496 break;
2497 }
2498
2499 cnt++;
2500 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2501 break;
2502
2503 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2504 timeout = 1;
2505 break;
2506 }
2507 }
2508 end = rtw_get_current_time();
2509
2510 rdata = rtw_read32(adapter, REG_CAMREAD);
2511
2512 _exit_critical_mutex(mutex, NULL);
2513
2514 if (DBG_SEC_CAM_ACCESS || timeout) {
2515 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
2516 , FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2517 }
2518
2519 return rdata;
2520 }
2521
rtw_sec_write_cam(_adapter * adapter,u8 addr,u32 wdata)2522 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
2523 {
2524 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2525 u32 cnt = 0;
2526 systime start = 0, end = 0;
2527 u8 timeout = 0;
2528 u8 sr = 0;
2529
2530 _enter_critical_mutex(mutex, NULL);
2531
2532 rtw_write32(adapter, REG_CAMWRITE, wdata);
2533 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
2534
2535 start = rtw_get_current_time();
2536 while (1) {
2537 if (rtw_is_surprise_removed(adapter)) {
2538 sr = 1;
2539 break;
2540 }
2541
2542 cnt++;
2543 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2544 break;
2545
2546 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2547 timeout = 1;
2548 break;
2549 }
2550 }
2551 end = rtw_get_current_time();
2552
2553 _exit_critical_mutex(mutex, NULL);
2554
2555 if (DBG_SEC_CAM_ACCESS || timeout) {
2556 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
2557 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2558 }
2559 }
2560
rtw_sec_read_cam_ent(_adapter * adapter,u8 id,u8 * ctrl,u8 * mac,u8 * key)2561 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
2562 {
2563 u8 i;
2564 u32 rdata;
2565 u8 begin = 0;
2566 u8 end = 5; /* TODO: consider other key length accordingly */
2567
2568 if (!ctrl && !mac && !key) {
2569 rtw_warn_on(1);
2570 goto exit;
2571 }
2572
2573 /* TODO: check id range */
2574
2575 if (!ctrl && !mac)
2576 begin = 2; /* read from key */
2577
2578 if (!key && !mac)
2579 end = 0; /* read to ctrl */
2580 else if (!key)
2581 end = 2; /* read to mac */
2582
2583 for (i = begin; i <= end; i++) {
2584 rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
2585
2586 switch (i) {
2587 case 0:
2588 if (ctrl)
2589 _rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
2590 if (mac)
2591 _rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
2592 break;
2593 case 1:
2594 if (mac)
2595 _rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
2596 break;
2597 default:
2598 if (key)
2599 _rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
2600 break;
2601 }
2602 }
2603
2604 exit:
2605 return;
2606 }
2607
2608
rtw_sec_write_cam_ent(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)2609 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
2610 {
2611 unsigned int i;
2612 int j;
2613 u8 addr, addr1 = 0;
2614 u32 wdata, wdata1 = 0;
2615
2616 /* TODO: consider other key length accordingly */
2617 #if 0
2618 switch ((ctrl & 0x1c) >> 2) {
2619 case _WEP40_:
2620 case _TKIP_:
2621 case _AES_:
2622 case _WEP104_:
2623
2624 }
2625 #else
2626 j = 7;
2627 #endif
2628
2629 for (; j >= 0; j--) {
2630 switch (j) {
2631 case 0:
2632 wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
2633 break;
2634 case 1:
2635 wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
2636 break;
2637 case 6:
2638 case 7:
2639 wdata = 0;
2640 break;
2641 default:
2642 i = (j - 2) << 2;
2643 wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
2644 break;
2645 }
2646
2647 addr = (id << 3) + j;
2648
2649 #if defined(CONFIG_RTL8192F)
2650 if(j == 1) {
2651 wdata1 = wdata;
2652 addr1 = addr;
2653 continue;
2654 }
2655 #endif
2656
2657 rtw_sec_write_cam(adapter, addr, wdata);
2658 }
2659
2660 #if defined(CONFIG_RTL8192F)
2661 rtw_sec_write_cam(adapter, addr1, wdata1);
2662 #endif
2663 }
2664
rtw_sec_clr_cam_ent(_adapter * adapter,u8 id)2665 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
2666 {
2667 u8 addr;
2668
2669 addr = (id << 3);
2670 rtw_sec_write_cam(adapter, addr, 0);
2671 }
2672
rtw_sec_read_cam_is_gk(_adapter * adapter,u8 id)2673 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
2674 {
2675 bool res;
2676 u16 ctrl;
2677
2678 rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
2679
2680 res = (ctrl & BIT6) ? _TRUE : _FALSE;
2681 return res;
2682 }
2683 #ifdef CONFIG_MBSSID_CAM
rtw_mbid_cam_init(struct dvobj_priv * dvobj)2684 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
2685 {
2686 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2687
2688 _rtw_spinlock_init(&mbid_cam_ctl->lock);
2689 mbid_cam_ctl->bitmap = 0;
2690 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2691 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2692 }
2693
rtw_mbid_cam_deinit(struct dvobj_priv * dvobj)2694 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
2695 {
2696 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2697
2698 _rtw_spinlock_free(&mbid_cam_ctl->lock);
2699 }
2700
rtw_mbid_cam_reset(_adapter * adapter)2701 void rtw_mbid_cam_reset(_adapter *adapter)
2702 {
2703 _irqL irqL;
2704 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2705 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2706
2707 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2708 mbid_cam_ctl->bitmap = 0;
2709 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2710 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2711
2712 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2713 }
_rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2714 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2715 {
2716 u8 i;
2717 u8 cam_id = INVALID_CAM_ID;
2718 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2719
2720 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2721 if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
2722 cam_id = i;
2723 break;
2724 }
2725 }
2726
2727 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2728 return cam_id;
2729 }
2730
rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2731 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2732 {
2733 _irqL irqL;
2734
2735 u8 cam_id = INVALID_CAM_ID;
2736 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2737 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2738
2739 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2740 cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
2741 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2742
2743 return cam_id;
2744 }
_rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2745 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2746 {
2747 u8 i;
2748 u8 cam_id = INVALID_CAM_ID;
2749 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2750
2751 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2752 if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
2753 cam_id = i;
2754 break;
2755 }
2756 }
2757 if (cam_id != INVALID_CAM_ID)
2758 RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
2759 __func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
2760
2761 return cam_id;
2762 }
2763
rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2764 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2765 {
2766 _irqL irqL;
2767 u8 cam_id = INVALID_CAM_ID;
2768 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2769 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2770
2771 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2772 cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
2773 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2774
2775 return cam_id;
2776 }
rtw_get_max_mbid_cam_id(_adapter * adapter)2777 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
2778 {
2779 _irqL irqL;
2780 s8 i;
2781 u8 cam_id = INVALID_CAM_ID;
2782 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2783 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2784
2785 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2786 for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
2787 if (mbid_cam_ctl->bitmap & BIT(i)) {
2788 cam_id = i;
2789 break;
2790 }
2791 }
2792 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2793 /*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
2794 return cam_id;
2795 }
2796
rtw_get_mbid_cam_entry_num(_adapter * adapter)2797 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
2798 {
2799 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2800 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2801
2802 return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2803 }
2804
mbid_cam_cache_init(_adapter * adapter,struct mbid_cam_cache * pmbid_cam,u8 * mac_addr)2805 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
2806 {
2807 if (adapter && pmbid_cam && mac_addr) {
2808 _rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
2809 pmbid_cam->iface_id = adapter->iface_id;
2810 }
2811 }
mbid_cam_cache_clr(struct mbid_cam_cache * pmbid_cam)2812 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
2813 {
2814 if (pmbid_cam) {
2815 _rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
2816 pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
2817 }
2818 }
2819
rtw_mbid_camid_alloc(_adapter * adapter,u8 * mac_addr)2820 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
2821 {
2822 _irqL irqL;
2823 u8 cam_id = INVALID_CAM_ID, i;
2824 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2825 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2826 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2827
2828 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2829 goto exit;
2830
2831 if (entry_num >= TOTAL_MBID_CAM_NUM) {
2832 RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
2833 rtw_warn_on(1);
2834 }
2835
2836 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2837 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2838 if (!(mbid_cam_ctl->bitmap & BIT(i))) {
2839 mbid_cam_ctl->bitmap |= BIT(i);
2840 cam_id = i;
2841 break;
2842 }
2843 }
2844 if ((cam_id != INVALID_CAM_ID) && (mac_addr))
2845 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
2846 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2847
2848 if (cam_id != INVALID_CAM_ID) {
2849 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2850 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2851 #ifdef DBG_MBID_CAM_DUMP
2852 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2853 #endif
2854 } else
2855 RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2856 exit:
2857 return cam_id;
2858 }
2859
rtw_mbid_cam_info_change(_adapter * adapter,u8 * mac_addr)2860 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
2861 {
2862 _irqL irqL;
2863 u8 entry_id = INVALID_CAM_ID;
2864 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2865 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2866
2867 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2868 entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
2869 if (entry_id != INVALID_CAM_ID)
2870 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
2871
2872 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2873
2874 return entry_id;
2875 }
2876
rtw_mbid_cam_assign(_adapter * adapter,u8 * mac_addr,u8 camid)2877 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
2878 {
2879 _irqL irqL;
2880 u8 ret = _FALSE;
2881 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2882 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2883
2884 if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
2885 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
2886 rtw_warn_on(1);
2887 }
2888 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2889 goto exit;
2890
2891 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2892 if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
2893 if (mac_addr) {
2894 mbid_cam_ctl->bitmap |= BIT(camid);
2895 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
2896 ret = _TRUE;
2897 }
2898 }
2899 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2900
2901 if (ret == _TRUE) {
2902 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2903 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
2904 #ifdef DBG_MBID_CAM_DUMP
2905 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2906 #endif
2907 } else
2908 RTW_INFO("%s [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
2909
2910 exit:
2911 return ret;
2912 }
2913
rtw_mbid_camid_clean(_adapter * adapter,u8 mbss_canid)2914 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
2915 {
2916 _irqL irqL;
2917 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2918 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2919
2920 if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
2921 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
2922 rtw_warn_on(1);
2923 }
2924 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2925 mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
2926 mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
2927 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2928 ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
2929 RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
2930 }
rtw_mbid_cam_cache_dump(void * sel,const char * fun_name,_adapter * adapter)2931 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
2932 {
2933 _irqL irqL;
2934 u8 i;
2935 _adapter *iface;
2936 u8 iface_id;
2937 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2938 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2939 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2940 u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2941
2942 RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
2943
2944 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2945 RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
2946 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2947 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2948
2949 if (mbid_cam_ctl->bitmap & BIT(i)) {
2950 iface_id = dvobj->mbid_cam_cache[i].iface_id;
2951 _RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
2952 _RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2953
2954 iface = dvobj->padapters[iface_id];
2955 if (iface) {
2956 if (MLME_IS_STA(iface))
2957 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
2958 else if (MLME_IS_AP(iface))
2959 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
2960 else if (MLME_IS_MESH(iface))
2961 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");
2962 else
2963 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2964 }
2965
2966 } else
2967 _RTW_PRINT_SEL(sel, "N/A\n");
2968 }
2969 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2970 return 0;
2971 }
2972
read_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2973 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2974 {
2975 u8 poll = 1;
2976 u8 cam_ready = _FALSE;
2977 u32 cam_data1 = 0;
2978 u16 cam_data2 = 0;
2979
2980 if (RTW_CANNOT_RUN(padapter))
2981 return;
2982
2983 rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2984
2985 do {
2986 if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2987 cam_ready = _TRUE;
2988 break;
2989 }
2990 poll++;
2991 } while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2992
2993 if (cam_ready) {
2994 cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2995 mac[0] = cam_data1 & 0xFF;
2996 mac[1] = (cam_data1 >> 8) & 0xFF;
2997 mac[2] = (cam_data1 >> 16) & 0xFF;
2998 mac[3] = (cam_data1 >> 24) & 0xFF;
2999
3000 cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
3001 mac[4] = cam_data2 & 0xFF;
3002 mac[5] = (cam_data2 >> 8) & 0xFF;
3003 }
3004
3005 }
rtw_mbid_cam_dump(void * sel,const char * fun_name,_adapter * adapter)3006 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
3007 {
3008 /*_irqL irqL;*/
3009 u8 i;
3010 u8 mac_addr[ETH_ALEN];
3011
3012 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3013 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
3014
3015 RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
3016
3017 /*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
3018 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
3019 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
3020 _rtw_memset(mac_addr, 0, ETH_ALEN);
3021 read_mbssid_cam(adapter, i, mac_addr);
3022 _RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
3023 }
3024 /*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
3025 return 0;
3026 }
3027
write_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)3028 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
3029 {
3030 u32 cam_val[2] = {0};
3031
3032 cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
3033 cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT) | (mac[5] << 8) | mac[4];
3034
3035 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
3036 }
3037
3038 /*
3039 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
3040 {
3041 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
3042 }
3043 */
3044
rtw_ap_set_mbid_num(_adapter * adapter,u8 ap_num)3045 void rtw_ap_set_mbid_num(_adapter *adapter, u8 ap_num)
3046 {
3047 rtw_write8(adapter, REG_MBID_NUM,
3048 ((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | ((ap_num -1) & 0x07)));
3049
3050 }
rtw_mbid_cam_enable(_adapter * adapter)3051 void rtw_mbid_cam_enable(_adapter *adapter)
3052 {
3053 /*enable MBSSID*/
3054 rtw_hal_rcr_add(adapter, RCR_ENMBID);
3055 }
rtw_mi_set_mbid_cam(_adapter * adapter)3056 void rtw_mi_set_mbid_cam(_adapter *adapter)
3057 {
3058 u8 i;
3059 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3060 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
3061
3062 #ifdef DBG_MBID_CAM_DUMP
3063 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
3064 #endif
3065
3066 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
3067 if (mbid_cam_ctl->bitmap & BIT(i)) {
3068 write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
3069 RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
3070 }
3071 }
3072 rtw_mbid_cam_enable(adapter);
3073 }
3074 #endif /*CONFIG_MBSSID_CAM*/
3075
3076 #ifdef CONFIG_FW_HANDLE_TXBCN
3077 #define H2C_BCN_OFFLOAD_LEN 1
3078
3079 #define SET_H2CCMD_BCN_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
3080 #define SET_H2CCMD_BCN_ROOT_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
3081 #define SET_H2CCMD_BCN_VAP1_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)
3082 #define SET_H2CCMD_BCN_VAP2_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)
3083 #define SET_H2CCMD_BCN_VAP3_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value)
3084 #define SET_H2CCMD_BCN_VAP4_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value)
3085
rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter * adapter,bool fw_bcn_en,u8 tbtt_rpt_map)3086 void rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter *adapter, bool fw_bcn_en, u8 tbtt_rpt_map)
3087 {
3088 u8 fw_bcn_offload[1] = {0};
3089 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3090
3091 if (fw_bcn_en)
3092 SET_H2CCMD_BCN_OFFLOAD_EN(fw_bcn_offload, 1);
3093
3094 if (tbtt_rpt_map & BIT(0))
3095 SET_H2CCMD_BCN_ROOT_TBTT_RPT(fw_bcn_offload, 1);
3096 if (tbtt_rpt_map & BIT(1))
3097 SET_H2CCMD_BCN_VAP1_TBTT_RPT(fw_bcn_offload, 1);
3098 if (tbtt_rpt_map & BIT(2))
3099 SET_H2CCMD_BCN_VAP2_TBTT_RPT(fw_bcn_offload, 1);
3100 if (tbtt_rpt_map & BIT(3))
3101 SET_H2CCMD_BCN_VAP3_TBTT_RPT(fw_bcn_offload, 1);
3102
3103 dvobj->vap_tbtt_rpt_map = tbtt_rpt_map;
3104 dvobj->fw_bcn_offload = fw_bcn_en;
3105 RTW_INFO("[FW BCN] Offload : %s\n", (dvobj->fw_bcn_offload) ? "EN" : "DIS");
3106 RTW_INFO("[FW BCN] TBTT RPT map : 0x%02x\n", dvobj->vap_tbtt_rpt_map);
3107
3108 rtw_hal_fill_h2c_cmd(adapter, H2C_FW_BCN_OFFLOAD,
3109 H2C_BCN_OFFLOAD_LEN, fw_bcn_offload);
3110 }
3111
rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter * adapter)3112 void rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter *adapter)
3113 {
3114 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3115 u8 ret, vap_id;
3116 u32 page_size = 0;
3117 u8 bcn_rsvdpage[H2C_BCN_RSVDPAGE_LEN] = {0};
3118
3119 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
3120 #if 1
3121 for (vap_id = 0; vap_id < CONFIG_LIMITED_AP_NUM; vap_id++) {
3122 if (dvobj->vap_map & BIT(vap_id))
3123 bcn_rsvdpage[vap_id] = vap_id * (MAX_BEACON_LEN / page_size);
3124 }
3125 #else
3126 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)
3127 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 8, __Value)
3128 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 8, __Value)
3129 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 8, __Value)
3130 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 8, __Value)
3131
3132 if (dvobj->vap_map & BIT(0))
3133 SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(bcn_rsvdpage, 0);
3134 if (dvobj->vap_map & BIT(1))
3135 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(bcn_rsvdpage,
3136 1 * (MAX_BEACON_LEN / page_size));
3137 if (dvobj->vap_map & BIT(2))
3138 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(bcn_rsvdpage,
3139 2 * (MAX_BEACON_LEN / page_size));
3140 if (dvobj->vap_map & BIT(3))
3141 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(bcn_rsvdpage,
3142 3 * (MAX_BEACON_LEN / page_size));
3143 if (dvobj->vap_map & BIT(4))
3144 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(bcn_rsvdpage,
3145 4 * (MAX_BEACON_LEN / page_size));
3146 #endif
3147 if (1) {
3148 RTW_INFO("[BCN_LOC] vap_map : 0x%02x\n", dvobj->vap_map);
3149 RTW_INFO("[BCN_LOC] page_size :%d, @bcn_page_num :%d\n"
3150 , page_size, (MAX_BEACON_LEN / page_size));
3151 RTW_INFO("[BCN_LOC] root ap : 0x%02x\n", *bcn_rsvdpage);
3152 RTW_INFO("[BCN_LOC] vap_1 : 0x%02x\n", *(bcn_rsvdpage + 1));
3153 RTW_INFO("[BCN_LOC] vap_2 : 0x%02x\n", *(bcn_rsvdpage + 2));
3154 RTW_INFO("[BCN_LOC] vap_3 : 0x%02x\n", *(bcn_rsvdpage + 3));
3155 RTW_INFO("[BCN_LOC] vap_4 : 0x%02x\n", *(bcn_rsvdpage + 4));
3156 }
3157 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE,
3158 H2C_BCN_RSVDPAGE_LEN, bcn_rsvdpage);
3159 }
3160
rtw_ap_multi_bcn_cfg(_adapter * adapter)3161 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3162 {
3163 u8 dft_bcn_space = DEFAULT_BCN_INTERVAL;
3164 u8 sub_bcn_space = (DEFAULT_BCN_INTERVAL / CONFIG_LIMITED_AP_NUM);
3165
3166 /*enable to rx data frame*/
3167 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3168
3169 /*Disable Port0's beacon function*/
3170 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
3171 /*Reset Port0's TSF*/
3172 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT_TSFTR_RST);
3173
3174 rtw_ap_set_mbid_num(adapter, CONFIG_LIMITED_AP_NUM);
3175
3176 /*BCN space & BCN sub-space 0x554[15:0] = 0x64,0x5BC[23:16] = 0x21*/
3177 rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), HW_PORT0, dft_bcn_space);
3178 rtw_write8(adapter, REG_MBSSID_BCN_SPACE3 + 2, sub_bcn_space);
3179
3180 #if 0 /*setting in hw_var_set_opmode_mbid - ResumeTxBeacon*/
3181 /*BCN hold time 0x540[19:8] = 0x80*/
3182 rtw_write8(adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
3183 rtw_write8(adapter, REG_TBTT_PROHIBIT + 2,
3184 (rtw_read8(adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
3185 #endif
3186
3187 /*ATIM window -0x55A = 0x32, reg 0x570 = 0x32, reg 0x5A0 = 0x32 */
3188 rtw_write8(adapter, REG_ATIMWND, 0x32);
3189 rtw_write8(adapter, REG_ATIMWND1_V1, 0x32);
3190 rtw_write8(adapter, REG_ATIMWND2, 0x32);
3191 rtw_write8(adapter, REG_ATIMWND3, 0x32);
3192 /*
3193 rtw_write8(adapter, REG_ATIMWND4, 0x32);
3194 rtw_write8(adapter, REG_ATIMWND5, 0x32);
3195 rtw_write8(adapter, REG_ATIMWND6, 0x32);
3196 rtw_write8(adapter, REG_ATIMWND7, 0x32);*/
3197
3198 /*no limit setting - 0x5A7 = 0xFF - Packet in Hi Queue Tx immediately*/
3199 rtw_write8(adapter, REG_HIQ_NO_LMT_EN, 0xFF);
3200
3201 /*Mask all beacon*/
3202 rtw_write8(adapter, REG_MBSSID_CTRL, 0);
3203
3204 /*BCN invalid bit setting 0x454[6] = 1*/
3205 /*rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);*/
3206
3207 /*Enable Port0's beacon function*/
3208 rtw_write8(adapter, REG_BCN_CTRL,
3209 rtw_read8(adapter, REG_BCN_CTRL) | BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION);
3210
3211 /* Enable HW seq for BCN
3212 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
3213 #ifdef CONFIG_RTL8822B
3214 if (IS_HARDWARE_TYPE_8822B(adapter))
3215 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3216 #endif
3217
3218 #ifdef CONFIG_RTL8822C
3219 if (IS_HARDWARE_TYPE_8822C(adapter))
3220 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3221 #endif
3222 }
_rtw_mbid_bcn_cfg(_adapter * adapter,bool mbcnq_en,u8 mbcnq_id)3223 static void _rtw_mbid_bcn_cfg(_adapter *adapter, bool mbcnq_en, u8 mbcnq_id)
3224 {
3225 if (mbcnq_id >= CONFIG_LIMITED_AP_NUM) {
3226 RTW_ERR(FUNC_ADPT_FMT"- mbid bcnq_id(%d) invalid\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3227 rtw_warn_on(1);
3228 }
3229
3230 if (mbcnq_en) {
3231 rtw_write8(adapter, REG_MBSSID_CTRL,
3232 rtw_read8(adapter, REG_MBSSID_CTRL) | BIT(mbcnq_id));
3233 RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) enabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3234 } else {
3235 rtw_write8(adapter, REG_MBSSID_CTRL,
3236 rtw_read8(adapter, REG_MBSSID_CTRL) & (~BIT(mbcnq_id)));
3237 RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) disabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3238 }
3239 }
3240 /*#define CONFIG_FW_TBTT_RPT*/
rtw_ap_mbid_bcn_en(_adapter * adapter,u8 ap_id)3241 void rtw_ap_mbid_bcn_en(_adapter *adapter, u8 ap_id)
3242 {
3243 RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3244
3245 #ifdef CONFIG_FW_TBTT_RPT
3246 if (rtw_ap_get_nums(adapter) >= 1) {
3247 u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3248
3249 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3250 tbtt_rpt_map | BIT(ap_id));/*H2C-0xBA*/
3251 }
3252 #else
3253 if (rtw_ap_get_nums(adapter) == 1)
3254 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE, 0);/*H2C-0xBA*/
3255 #endif
3256
3257 rtw_hal_set_bcn_rsvdpage_loc_cmd(adapter);/*H2C-0x09*/
3258
3259 _rtw_mbid_bcn_cfg(adapter, _TRUE, ap_id);
3260 }
rtw_ap_mbid_bcn_dis(_adapter * adapter,u8 ap_id)3261 void rtw_ap_mbid_bcn_dis(_adapter *adapter, u8 ap_id)
3262 {
3263 RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3264 _rtw_mbid_bcn_cfg(adapter, _FALSE, ap_id);
3265
3266 if (rtw_ap_get_nums(adapter) == 0)
3267 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _FALSE, 0);
3268 #ifdef CONFIG_FW_TBTT_RPT
3269 else if (rtw_ap_get_nums(adapter) >= 1) {
3270 u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3271
3272 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3273 tbtt_rpt_map & ~BIT(ap_id));/*H2C-0xBA*/
3274 }
3275 #endif
3276 }
3277 #endif
3278 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_ap_multi_bcn_cfg(_adapter * adapter)3279 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3280 {
3281 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3282 rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT);
3283 #else
3284 rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
3285 #endif
3286 /*enable to rx data frame*/
3287 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3288
3289 /*Beacon Control related register for first time*/
3290 rtw_write8(adapter, REG_BCNDMATIM, 0x02); /* 2ms */
3291
3292 /*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
3293 rtw_write8(adapter, REG_ATIMWND, 0x0c); /* 12ms */
3294
3295 #ifndef CONFIG_HW_P0_TSF_SYNC
3296 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3297 #endif
3298
3299 /*reset TSF*/
3300 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
3301
3302 /*enable BCN0 Function for if1*/
3303 /*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
3304 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3305 rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);
3306 #else
3307 rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3308 #endif
3309 #ifdef CONFIG_BCN_XMIT_PROTECT
3310 rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
3311 #endif
3312
3313 if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/
3314 rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
3315
3316 /* Enable HW seq for BCN
3317 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
3318 #ifdef CONFIG_RTL8822B
3319 if (IS_HARDWARE_TYPE_8822B(adapter))
3320 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3321 #endif
3322
3323 #ifdef CONFIG_RTL8822C
3324 if (IS_HARDWARE_TYPE_8822C(adapter))
3325 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3326 #endif
3327 }
3328 #endif
3329
3330 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3331 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3332 {
3333
3334 #if 0 /*TODO - modify for more flexible*/
3335 u8 idx = 0;
3336
3337 if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
3338 (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
3339 for (idx = 0; idx < 6; idx++)
3340 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
3341 } else {
3342 /*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
3343 u8 entry_id;
3344
3345 if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
3346 (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
3347 entry_id = 0;
3348 if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
3349 RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
3350 write_mbssid_cam(adapter, entry_id, val);
3351 }
3352 } else {
3353 entry_id = rtw_mbid_camid_alloc(adapter, val);
3354 if (entry_id != INVALID_CAM_ID)
3355 write_mbssid_cam(adapter, entry_id, val);
3356 }
3357 }
3358 #else
3359 {
3360 /*
3361 MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
3362 */
3363 u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
3364
3365
3366 if (entry_id != INVALID_CAM_ID) {
3367 write_mbssid_cam(adapter, entry_id, mac_addr);
3368 RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,
3369 ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));
3370 }
3371 }
3372 #endif
3373 }
3374
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3375 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3376 {
3377 u8 idx = 0;
3378 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3379 u8 entry_id;
3380
3381 if (!mac_addr) {
3382 rtw_warn_on(1);
3383 return;
3384 }
3385
3386
3387 entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
3388
3389 if (entry_id != INVALID_CAM_ID)
3390 write_mbssid_cam(adapter, entry_id, mac_addr);
3391 }
3392
3393 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_hal_bcn_interval_adjust(_adapter * adapter,u16 bcn_interval)3394 u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
3395 {
3396 if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
3397 return adapter_to_dvobj(adapter)->inter_bcn_space;
3398 else
3399 return bcn_interval;
3400 }
3401 #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
3402
3403 #else
3404
3405 #ifndef RTW_HALMAC
_get_macaddr_reg(enum _hw_port hwport)3406 static u32 _get_macaddr_reg(enum _hw_port hwport)
3407 {
3408 u32 reg_macaddr = REG_MACID;
3409
3410 #ifdef CONFIG_CONCURRENT_MODE
3411 if (hwport == HW_PORT1)
3412 reg_macaddr = REG_MACID1;
3413 #if defined(CONFIG_RTL8814A)
3414 else if (hwport == HW_PORT2)
3415 reg_macaddr = REG_MACID2;
3416 else if (hwport == HW_PORT3)
3417 reg_macaddr = REG_MACID3;
3418 else if (hwport == HW_PORT4)
3419 reg_macaddr = REG_MACID4;
3420 #endif /*CONFIG_RTL8814A*/
3421 #endif /*CONFIG_CONCURRENT_MODE*/
3422
3423 return reg_macaddr;
3424 }
3425 #endif /*!RTW_HALMAC*/
3426
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * mac_addr)3427 static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr)
3428 {
3429 enum _hw_port hwport;
3430
3431 if (mac_addr == NULL)
3432 return;
3433 hwport = get_hw_port(adapter);
3434
3435 RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3436 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3437
3438 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3439 rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3440 #else /* !RTW_HALMAC */
3441 {
3442 u8 idx = 0;
3443 u32 reg_macaddr = _get_macaddr_reg(hwport);
3444
3445 for (idx = 0; idx < ETH_ALEN; idx++)
3446 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx), mac_addr[idx]);
3447 }
3448 #endif /* !RTW_HALMAC */
3449 }
3450
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)3451 static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
3452 {
3453 enum _hw_port hwport;
3454
3455 if (mac_addr == NULL)
3456 return;
3457 hwport = get_hw_port(adapter);
3458
3459 _rtw_memset(mac_addr, 0, ETH_ALEN);
3460 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3461 rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3462 #else /* !RTW_HALMAC */
3463 {
3464 u8 idx = 0;
3465 u32 reg_macaddr = _get_macaddr_reg(hwport);
3466
3467 for (idx = 0; idx < ETH_ALEN; idx++)
3468 mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx));
3469 }
3470 #endif /* !RTW_HALMAC */
3471
3472 RTW_DBG("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3473 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3474 }
3475 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
3476
3477 #ifndef RTW_HALMAC
_get_bssid_reg(enum _hw_port hw_port)3478 static u32 _get_bssid_reg(enum _hw_port hw_port)
3479 {
3480 u32 reg_bssid = REG_BSSID;
3481
3482 #ifdef CONFIG_CONCURRENT_MODE
3483 if (hw_port == HW_PORT1)
3484 reg_bssid = REG_BSSID1;
3485 #if defined(CONFIG_RTL8814A)
3486 else if (hw_port == HW_PORT2)
3487 reg_bssid = REG_BSSID2;
3488 else if (hw_port == HW_PORT3)
3489 reg_bssid = REG_BSSID3;
3490 else if (hw_port == HW_PORT4)
3491 reg_bssid = REG_BSSID4;
3492 #endif /*CONFIG_RTL8814A*/
3493 #endif /*CONFIG_CONCURRENT_MODE*/
3494
3495 return reg_bssid;
3496 }
3497 #endif /*!RTW_HALMAC*/
rtw_hal_set_bssid(_adapter * adapter,u8 * val)3498 static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
3499 {
3500 enum _hw_port hw_port = rtw_hal_get_port(adapter);
3501 #ifdef RTW_HALMAC
3502
3503 rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);
3504 #else /* !RTW_HALMAC */
3505 u8 idx = 0;
3506 u32 reg_bssid = _get_bssid_reg(hw_port);
3507
3508 for (idx = 0 ; idx < ETH_ALEN; idx++)
3509 rtw_write8(adapter, (reg_bssid + idx), val[idx]);
3510 #endif /* !RTW_HALMAC */
3511
3512 RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",
3513 __func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));
3514 }
3515
3516 #ifndef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_tsf_update(_adapter * adapter,u8 en)3517 static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)
3518 {
3519 u32 addr = 0;
3520 u8 val8;
3521
3522 rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);
3523 if (addr) {
3524 rtw_enter_protsel_port(adapter, get_hw_port(adapter));
3525 val8 = rtw_read8(adapter, addr);
3526 if (en && (val8 & DIS_TSF_UDT)) {
3527 rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);
3528 #ifdef DBG_TSF_UPDATE
3529 RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3530 #endif
3531 }
3532 if (!en && !(val8 & DIS_TSF_UDT)) {
3533 rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);
3534 #ifdef DBG_TSF_UPDATE
3535 RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3536 #endif
3537 }
3538 rtw_leave_protsel_port(adapter);
3539 } else {
3540 RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"
3541 , adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");
3542 rtw_warn_on(1);
3543 }
3544 }
3545 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_set_hw_update_tsf(PADAPTER padapter)3546 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
3547 {
3548 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3549
3550 #else
3551 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3552
3553 if (!pmlmeext->en_hw_update_tsf)
3554 return;
3555
3556 /* check RCR */
3557 if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
3558 return;
3559
3560 if (pmlmeext->tsf_update_required) {
3561 pmlmeext->tsf_update_pause_stime = 0;
3562 rtw_hal_set_tsf_update(padapter, 1);
3563 }
3564
3565 pmlmeext->en_hw_update_tsf = 0;
3566 #endif
3567 }
3568
rtw_iface_enable_tsf_update(_adapter * adapter)3569 void rtw_iface_enable_tsf_update(_adapter *adapter)
3570 {
3571 adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3572 adapter->mlmeextpriv.tsf_update_required = 1;
3573 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3574
3575 #else
3576 rtw_hal_set_tsf_update(adapter, 1);
3577 #endif
3578 }
3579
rtw_iface_disable_tsf_update(_adapter * adapter)3580 void rtw_iface_disable_tsf_update(_adapter *adapter)
3581 {
3582 adapter->mlmeextpriv.tsf_update_required = 0;
3583 adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3584 adapter->mlmeextpriv.en_hw_update_tsf = 0;
3585 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3586
3587 #else
3588 rtw_hal_set_tsf_update(adapter, 0);
3589 #endif
3590 }
3591
rtw_hal_tsf_update_pause(_adapter * adapter)3592 static void rtw_hal_tsf_update_pause(_adapter *adapter)
3593 {
3594 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3595
3596 #else
3597 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3598 _adapter *iface;
3599 int i;
3600
3601 for (i = 0; i < dvobj->iface_nums; i++) {
3602 iface = dvobj->padapters[i];
3603 if (!iface)
3604 continue;
3605
3606 rtw_hal_set_tsf_update(iface, 0);
3607 if (iface->mlmeextpriv.tsf_update_required) {
3608 iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();
3609 if (!iface->mlmeextpriv.tsf_update_pause_stime)
3610 iface->mlmeextpriv.tsf_update_pause_stime++;
3611 }
3612 iface->mlmeextpriv.en_hw_update_tsf = 0;
3613 }
3614 #endif
3615 }
3616
rtw_hal_tsf_update_restore(_adapter * adapter)3617 static void rtw_hal_tsf_update_restore(_adapter *adapter)
3618 {
3619 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3620
3621 #else
3622 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3623 _adapter *iface;
3624 int i;
3625
3626 for (i = 0; i < dvobj->iface_nums; i++) {
3627 iface = dvobj->padapters[i];
3628 if (!iface)
3629 continue;
3630
3631 if (iface->mlmeextpriv.tsf_update_required) {
3632 /* enable HW TSF update when recive beacon*/
3633 iface->mlmeextpriv.en_hw_update_tsf = 1;
3634 #ifdef DBG_TSF_UPDATE
3635 RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"
3636 , iface->hw_port, ADPT_ARG(iface));
3637 #endif
3638 }
3639 }
3640 #endif
3641 }
3642
rtw_hal_periodic_tsf_update_chk(_adapter * adapter)3643 void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)
3644 {
3645 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3646
3647 #else
3648 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3649 _adapter *iface;
3650 struct mlme_ext_priv *mlmeext;
3651 int i;
3652 u32 restore_ms = 0;
3653
3654 if (dvobj->periodic_tsf_update_etime) {
3655 if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {
3656 /* end for restore status */
3657 dvobj->periodic_tsf_update_etime = 0;
3658 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3659 }
3660 return;
3661 }
3662
3663 if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)
3664 return;
3665
3666 /*
3667 * all required ifaces can switch to restore status together
3668 * loop all pause iface to get largest restore time required
3669 */
3670 for (i = 0; i < dvobj->iface_nums; i++) {
3671 iface = dvobj->padapters[i];
3672 if (!iface)
3673 continue;
3674
3675 mlmeext = &iface->mlmeextpriv;
3676
3677 if (mlmeext->tsf_update_required
3678 && mlmeext->tsf_update_pause_stime
3679 && rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)
3680 > mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor
3681 ) {
3682 if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)
3683 restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;
3684 }
3685 }
3686
3687 if (!restore_ms)
3688 return;
3689
3690 dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);
3691 if (!dvobj->periodic_tsf_update_etime)
3692 dvobj->periodic_tsf_update_etime++;
3693
3694 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3695
3696 /* set timer to end restore status */
3697 _set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);
3698 #endif
3699 }
3700
rtw_hal_periodic_tsf_update_end_timer_hdl(void * ctx)3701 void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)
3702 {
3703 struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;
3704
3705 if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
3706 return;
3707
3708 rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));
3709 }
3710
hw_var_rcr_config(_adapter * adapter,u32 rcr)3711 static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
3712 {
3713 int err;
3714
3715 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
3716 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;
3717 #endif
3718 err = rtw_write32(adapter, REG_RCR, rcr);
3719 if (err == _SUCCESS)
3720 GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
3721 return err;
3722 }
3723
hw_var_rcr_get(_adapter * adapter,u32 * rcr)3724 static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
3725 {
3726 u32 v32;
3727
3728 v32 = rtw_read32(adapter, REG_RCR);
3729 if (rcr)
3730 *rcr = v32;
3731 GET_HAL_DATA(adapter)->ReceiveConfig = v32;
3732 return _SUCCESS;
3733 }
3734
3735 /* only check SW RCR variable */
rtw_hal_rcr_check(_adapter * adapter,u32 check_bit)3736 inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
3737 {
3738 PHAL_DATA_TYPE hal;
3739 u32 rcr;
3740
3741 hal = GET_HAL_DATA(adapter);
3742
3743 rcr = hal->ReceiveConfig;
3744 if ((rcr & check_bit) == check_bit)
3745 return 1;
3746
3747 return 0;
3748 }
3749
rtw_hal_rcr_add(_adapter * adapter,u32 add)3750 inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
3751 {
3752 PHAL_DATA_TYPE hal;
3753 u32 rcr;
3754 u8 ret = _SUCCESS;
3755
3756 hal = GET_HAL_DATA(adapter);
3757
3758 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3759 rcr |= add;
3760 if (rcr != hal->ReceiveConfig)
3761 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3762
3763 return ret;
3764 }
3765
rtw_hal_rcr_clear(_adapter * adapter,u32 clear)3766 inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
3767 {
3768 PHAL_DATA_TYPE hal;
3769 u32 rcr;
3770 u8 ret = _SUCCESS;
3771
3772 hal = GET_HAL_DATA(adapter);
3773
3774 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3775 rcr &= ~clear;
3776 if (rcr != hal->ReceiveConfig)
3777 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3778
3779 return ret;
3780 }
3781
rtw_hal_rcr_set_chk_bssid(_adapter * adapter,u8 self_action)3782 void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
3783 {
3784 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3785 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3786 u32 rcr, rcr_new;
3787 struct mi_state mstate, mstate_s;
3788
3789 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3790 rcr_new = rcr;
3791
3792 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)
3793 rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
3794 #else
3795 rtw_mi_status_no_self(adapter, &mstate);
3796 rtw_mi_status_no_others(adapter, &mstate_s);
3797
3798 /* only adjust parameters interested */
3799 switch (self_action) {
3800 case MLME_SCAN_ENTER:
3801 mstate_s.scan_num = 1;
3802 mstate_s.scan_enter_num = 1;
3803 break;
3804 case MLME_SCAN_DONE:
3805 mstate_s.scan_enter_num = 0;
3806 break;
3807 case MLME_STA_CONNECTING:
3808 mstate_s.lg_sta_num = 1;
3809 mstate_s.ld_sta_num = 0;
3810 break;
3811 case MLME_STA_CONNECTED:
3812 mstate_s.lg_sta_num = 0;
3813 mstate_s.ld_sta_num = 1;
3814 break;
3815 case MLME_STA_DISCONNECTED:
3816 mstate_s.lg_sta_num = 0;
3817 mstate_s.ld_sta_num = 0;
3818 break;
3819 #ifdef CONFIG_TDLS
3820 case MLME_TDLS_LINKED:
3821 mstate_s.ld_tdls_num = 1;
3822 break;
3823 case MLME_TDLS_NOLINK:
3824 mstate_s.ld_tdls_num = 0;
3825 break;
3826 #endif
3827 #ifdef CONFIG_AP_MODE
3828 case MLME_AP_STARTED:
3829 mstate_s.ap_num = 1;
3830 break;
3831 case MLME_AP_STOPPED:
3832 mstate_s.ap_num = 0;
3833 mstate_s.ld_ap_num = 0;
3834 break;
3835 #endif
3836 #ifdef CONFIG_RTW_MESH
3837 case MLME_MESH_STARTED:
3838 mstate_s.mesh_num = 1;
3839 break;
3840 case MLME_MESH_STOPPED:
3841 mstate_s.mesh_num = 0;
3842 mstate_s.ld_mesh_num = 0;
3843 break;
3844 #endif
3845 case MLME_ACTION_NONE:
3846 case MLME_ADHOC_STARTED:
3847 /* caller without effect of decision */
3848 break;
3849 default:
3850 rtw_warn_on(1);
3851 };
3852
3853 rtw_mi_status_merge(&mstate, &mstate_s);
3854
3855 if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
3856 #ifdef CONFIG_FIND_BEST_CHANNEL
3857 || MSTATE_SCAN_ENTER_NUM(&mstate)
3858 #endif
3859 || hal_data->in_cta_test
3860 )
3861 rcr_new &= ~RCR_CBSSID_DATA;
3862 else
3863 rcr_new |= RCR_CBSSID_DATA;
3864
3865 if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)
3866 rcr_new &= ~RCR_CBSSID_BCN;
3867 else if (MSTATE_STA_LG_NUM(&mstate)
3868 || adapter_to_dvobj(adapter)->periodic_tsf_update_etime
3869 )
3870 rcr_new |= RCR_CBSSID_BCN;
3871 else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
3872 || MSTATE_MESH_NUM(&mstate)
3873 )
3874 rcr_new &= ~RCR_CBSSID_BCN;
3875 else
3876 rcr_new |= RCR_CBSSID_BCN;
3877
3878 #ifdef CONFIG_CLIENT_PORT_CFG
3879 if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)
3880 rcr_new &= ~RCR_CBSSID_BCN;
3881 #endif
3882 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
3883
3884 if (rcr == rcr_new)
3885 return;
3886
3887 if (!hal_spec->rx_tsf_filter
3888 && (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))
3889 rtw_hal_tsf_update_pause(adapter);
3890
3891 rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
3892
3893 if (!hal_spec->rx_tsf_filter
3894 && !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)
3895 && self_action != MLME_STA_CONNECTING)
3896 rtw_hal_tsf_update_restore(adapter);
3897 }
3898
hw_var_set_rcr_am(_adapter * adapter,u8 enable)3899 static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
3900 {
3901 u32 rcr = RCR_AM;
3902
3903 if (enable)
3904 rtw_hal_rcr_add(adapter, rcr);
3905 else
3906 rtw_hal_rcr_clear(adapter, rcr);
3907 }
3908
hw_var_set_bcn_interval(_adapter * adapter,u16 interval)3909 static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)
3910 {
3911 #ifdef CONFIG_SWTIMER_BASED_TXBCN
3912 interval = rtw_hal_bcn_interval_adjust(adapter, interval);
3913 #endif
3914
3915 #ifdef RTW_HALMAC
3916 rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);
3917 #else
3918 rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);
3919 #endif
3920
3921 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3922 {
3923 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3924 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3925
3926 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3927 RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);
3928 rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);
3929 }
3930 }
3931 #endif
3932 }
3933
3934 #if CONFIG_TX_AC_LIFETIME
3935 const char *const _tx_aclt_conf_str[] = {
3936 "DEFAULT",
3937 "AP_M2U",
3938 "MESH",
3939 "INVALID",
3940 };
3941
dump_tx_aclt_force_val(void * sel,struct dvobj_priv * dvobj)3942 void dump_tx_aclt_force_val(void *sel, struct dvobj_priv *dvobj)
3943 {
3944 #define TX_ACLT_FORCE_MSG_LEN 64
3945 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3946 struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3947 char buf[TX_ACLT_FORCE_MSG_LEN];
3948 int cnt = 0;
3949
3950 RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3951 , hal_spec->tx_aclt_unit_factor * 32
3952 , 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3953
3954 RTW_PRINT_SEL(sel, "%-5s %-12s %-12s\n", "en", "vo_vi(us)", "be_bk(us)");
3955 RTW_PRINT_SEL(sel, " 0x%02x %12u %12u\n"
3956 , conf->en
3957 , conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3958 , conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3959 );
3960
3961 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "%5s", conf->en == 0xFF ? "AUTO" : "FORCE");
3962 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3963 goto exit;
3964
3965 if (conf->vo_vi)
3966 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->vo_vi);
3967 else
3968 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");
3969 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3970 goto exit;
3971
3972
3973 if (conf->be_bk)
3974 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->be_bk);
3975 else
3976 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");
3977 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3978 goto exit;
3979
3980 RTW_PRINT_SEL(sel, "%s\n", buf);
3981
3982 exit:
3983 return;
3984 }
3985
rtw_hal_set_tx_aclt_force_val(_adapter * adapter,struct tx_aclt_conf_t * input,u8 arg_num)3986 void rtw_hal_set_tx_aclt_force_val(_adapter *adapter, struct tx_aclt_conf_t *input, u8 arg_num)
3987 {
3988 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3989 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3990 struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3991
3992 if (arg_num >= 1) {
3993 if (input->en == 0xFF)
3994 conf->en = input->en;
3995 else
3996 conf->en = input->en & 0xF;
3997 }
3998 if (arg_num >= 2) {
3999 conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
4000 if (conf->vo_vi > 0xFFFF)
4001 conf->vo_vi = 0xFFFF;
4002 }
4003 if (arg_num >= 3) {
4004 conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
4005 if (conf->be_bk > 0xFFFF)
4006 conf->be_bk = 0xFFFF;
4007 }
4008 }
4009
dump_tx_aclt_confs(void * sel,struct dvobj_priv * dvobj)4010 void dump_tx_aclt_confs(void *sel, struct dvobj_priv *dvobj)
4011 {
4012 #define TX_ACLT_CONF_MSG_LEN 32
4013 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
4014 struct tx_aclt_conf_t *conf;
4015 char buf[TX_ACLT_CONF_MSG_LEN];
4016 int cnt;
4017 int i;
4018
4019 RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
4020 , hal_spec->tx_aclt_unit_factor * 32
4021 , 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
4022
4023 RTW_PRINT_SEL(sel, "%-7s %-1s %-3s %-9s %-9s %-10s %-10s\n"
4024 , "name", "#", "en", "vo_vi(us)", "be_bk(us)", "vo_vi(reg)", "be_bk(reg)");
4025
4026 for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
4027 conf = &dvobj->tx_aclt_confs[i];
4028 cnt = 0;
4029
4030 if (conf->vo_vi)
4031 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->vo_vi);
4032 else
4033 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
4034 if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
4035 continue;
4036
4037 if (conf->be_bk)
4038 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->be_bk);
4039 else
4040 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
4041 if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
4042 continue;
4043
4044 RTW_PRINT_SEL(sel, "%7s %1u 0x%x %9u %9u%s\n"
4045 , tx_aclt_conf_str(i), i
4046 , conf->en
4047 , conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
4048 , conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
4049 , buf
4050 );
4051 }
4052 }
4053
rtw_hal_set_tx_aclt_conf(_adapter * adapter,u8 conf_idx,struct tx_aclt_conf_t * input,u8 arg_num)4054 void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_conf_t *input, u8 arg_num)
4055 {
4056 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4057 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4058 struct tx_aclt_conf_t *conf;
4059
4060 if (conf_idx >= TX_ACLT_CONF_NUM)
4061 return;
4062
4063 conf = &dvobj->tx_aclt_confs[conf_idx];
4064
4065 if (arg_num >= 1) {
4066 if (input->en != 0xFF)
4067 conf->en = input->en & 0xF;
4068 }
4069 if (arg_num >= 2) {
4070 conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
4071 if (conf->vo_vi > 0xFFFF)
4072 conf->vo_vi = 0xFFFF;
4073 }
4074 if (arg_num >= 3) {
4075 conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
4076 if (conf->be_bk > 0xFFFF)
4077 conf->be_bk = 0xFFFF;
4078 }
4079 }
4080
rtw_hal_update_tx_aclt(_adapter * adapter)4081 void rtw_hal_update_tx_aclt(_adapter *adapter)
4082 {
4083 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4084 struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter);
4085 u8 lt_en = 0, lt_en_ori;
4086 u16 lt_vo_vi = 0xFFFF, lt_be_bk = 0xFFFF;
4087 u32 lt, lt_ori;
4088 struct tx_aclt_conf_t *conf;
4089 int i;
4090 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
4091 _adapter *iface;
4092 u8 ap_m2u_num = 0;
4093
4094 for (i = 0; i < dvobj->iface_nums; i++) {
4095 iface = dvobj->padapters[i];
4096 if (!iface)
4097 continue;
4098
4099 if (MLME_IS_AP(iface)
4100 && ((iface->b2u_flags_ap_src & RTW_AP_B2U_IP_MCAST)
4101 || (iface->b2u_flags_ap_fwd & RTW_AP_B2U_IP_MCAST))
4102 )
4103 ap_m2u_num++;
4104 }
4105 #endif
4106
4107 lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN);
4108 lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME);
4109
4110 for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
4111 if (!(dvobj->tx_aclt_flags & BIT(i)))
4112 continue;
4113
4114 conf = &dvobj->tx_aclt_confs[i];
4115
4116 if (i == TX_ACLT_CONF_DEFAULT) {
4117 /* first and default status, assign directly */
4118 lt_en = conf->en;
4119 if (conf->vo_vi)
4120 lt_vo_vi = conf->vo_vi;
4121 if (conf->be_bk)
4122 lt_be_bk = conf->be_bk;
4123 }
4124 #if CONFIG_RTW_AP_DATA_BMC_TO_UC || defined(CONFIG_RTW_MESH)
4125 else if (0
4126 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
4127 || (i == TX_ACLT_CONF_AP_M2U
4128 && ap_m2u_num
4129 && macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */)
4130 #endif
4131 #ifdef CONFIG_RTW_MESH
4132 || (i == TX_ACLT_CONF_MESH
4133 && macid_ctl->op_num[H2C_MSR_ROLE_MESH] > 1 /* implies only 1 MESH mode supported */)
4134 #endif
4135 ) {
4136 /* long term status, OR en and MIN lifetime */
4137 lt_en |= conf->en;
4138 if (conf->vo_vi && lt_vo_vi > conf->vo_vi)
4139 lt_vo_vi = conf->vo_vi;
4140 if (conf->be_bk && lt_be_bk > conf->be_bk)
4141 lt_be_bk = conf->be_bk;
4142 }
4143 #endif
4144 }
4145
4146 if (dvobj->tx_aclt_force_val.en != 0xFF)
4147 lt_en = dvobj->tx_aclt_force_val.en;
4148 if (dvobj->tx_aclt_force_val.vo_vi)
4149 lt_vo_vi = dvobj->tx_aclt_force_val.vo_vi;
4150 if (dvobj->tx_aclt_force_val.be_bk)
4151 lt_be_bk = dvobj->tx_aclt_force_val.be_bk;
4152
4153 lt_en = (lt_en_ori & 0xF0) | (lt_en & 0x0F);
4154 lt = (lt_be_bk << 16) | lt_vo_vi;
4155
4156 if (0)
4157 RTW_INFO("lt_en:0x%x(0x%x), lt:0x%08x(0x%08x)\n", lt_en, lt_en_ori, lt, lt_ori);
4158
4159 if (lt_en != lt_en_ori)
4160 rtw_write8(adapter, REG_LIFETIME_EN, lt_en);
4161 if (lt != lt_ori)
4162 rtw_write32(adapter, REG_PKT_LIFE_TIME, lt);
4163 }
4164 #endif /* CONFIG_TX_AC_LIFETIME */
4165
hw_var_port_switch(_adapter * adapter)4166 void hw_var_port_switch(_adapter *adapter)
4167 {
4168 #ifdef CONFIG_CONCURRENT_MODE
4169 #ifdef CONFIG_RUNTIME_PORT_SWITCH
4170 /*
4171 0x102: MSR
4172 0x550: REG_BCN_CTRL
4173 0x551: REG_BCN_CTRL_1
4174 0x55A: REG_ATIMWND
4175 0x560: REG_TSFTR
4176 0x568: REG_TSFTR1
4177 0x570: REG_ATIMWND_1
4178 0x610: REG_MACID
4179 0x618: REG_BSSID
4180 0x700: REG_MACID1
4181 0x708: REG_BSSID1
4182 */
4183
4184 int i;
4185 u8 msr;
4186 u8 bcn_ctrl;
4187 u8 bcn_ctrl_1;
4188 u8 atimwnd[2];
4189 u8 atimwnd_1[2];
4190 u8 tsftr[8];
4191 u8 tsftr_1[8];
4192 u8 macid[6];
4193 u8 bssid[6];
4194 u8 macid_1[6];
4195 u8 bssid_1[6];
4196 #if defined(CONFIG_RTL8192F)
4197 u16 wlan_act_mask_ctrl = 0;
4198 u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;
4199 #endif
4200
4201 u8 hw_port;
4202 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4203 _adapter *iface = NULL;
4204
4205 msr = rtw_read8(adapter, MSR);
4206 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4207 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4208 #if defined(CONFIG_RTL8192F)
4209 wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4210 #endif
4211
4212 for (i = 0; i < 2; i++)
4213 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4214 for (i = 0; i < 2; i++)
4215 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4216
4217 for (i = 0; i < 8; i++)
4218 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4219 for (i = 0; i < 8; i++)
4220 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4221
4222 for (i = 0; i < 6; i++)
4223 macid[i] = rtw_read8(adapter, REG_MACID + i);
4224
4225 for (i = 0; i < 6; i++)
4226 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4227
4228 for (i = 0; i < 6; i++)
4229 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4230
4231 for (i = 0; i < 6; i++)
4232 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4233
4234 #ifdef DBG_RUNTIME_PORT_SWITCH
4235 RTW_INFO(FUNC_ADPT_FMT" before switch\n"
4236 "msr:0x%02x\n"
4237 "bcn_ctrl:0x%02x\n"
4238 "bcn_ctrl_1:0x%02x\n"
4239 #if defined(CONFIG_RTL8192F)
4240 "wlan_act_mask_ctrl:0x%02x\n"
4241 #endif
4242 "atimwnd:0x%04x\n"
4243 "atimwnd_1:0x%04x\n"
4244 "tsftr:%llu\n"
4245 "tsftr1:%llu\n"
4246 "macid:"MAC_FMT"\n"
4247 "bssid:"MAC_FMT"\n"
4248 "macid_1:"MAC_FMT"\n"
4249 "bssid_1:"MAC_FMT"\n"
4250 , FUNC_ADPT_ARG(adapter)
4251 , msr
4252 , bcn_ctrl
4253 , bcn_ctrl_1
4254 #if defined(CONFIG_RTL8192F)
4255 , wlan_act_mask_ctrl
4256 #endif
4257 , *((u16 *)atimwnd)
4258 , *((u16 *)atimwnd_1)
4259 , *((u64 *)tsftr)
4260 , *((u64 *)tsftr_1)
4261 , MAC_ARG(macid)
4262 , MAC_ARG(bssid)
4263 , MAC_ARG(macid_1)
4264 , MAC_ARG(bssid_1)
4265 );
4266 #endif /* DBG_RUNTIME_PORT_SWITCH */
4267
4268 /* disable bcn function, disable update TSF */
4269 rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4270 rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4271
4272 #if defined(CONFIG_RTL8192F)
4273 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);
4274 #endif
4275
4276 /* switch msr */
4277 msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
4278 rtw_write8(adapter, MSR, msr);
4279
4280 /* write port0 */
4281 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
4282 for (i = 0; i < 2; i++)
4283 rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
4284 for (i = 0; i < 8; i++)
4285 rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
4286 for (i = 0; i < 6; i++)
4287 rtw_write8(adapter, REG_MACID + i, macid_1[i]);
4288 for (i = 0; i < 6; i++)
4289 rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
4290
4291 /* write port1 */
4292 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
4293 for (i = 0; i < 2; i++)
4294 rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
4295 for (i = 0; i < 8; i++)
4296 rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
4297 for (i = 0; i < 6; i++)
4298 rtw_write8(adapter, REG_MACID1 + i, macid[i]);
4299 for (i = 0; i < 6; i++)
4300 rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
4301
4302 /* write bcn ctl */
4303 #ifdef CONFIG_BT_COEXIST
4304 /* always enable port0 beacon function for PSTDMA */
4305 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
4306 || IS_HARDWARE_TYPE_8723D(adapter))
4307 bcn_ctrl_1 |= EN_BCN_FUNCTION;
4308 /* always disable port1 beacon function for PSTDMA */
4309 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
4310 bcn_ctrl &= ~EN_BCN_FUNCTION;
4311 #endif
4312 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
4313 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
4314
4315 #if defined(CONFIG_RTL8192F)
4316 /* if the setting of port0 and port1 are the same, it does not need to switch port setting*/
4317 if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)
4318 != (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))
4319 wlan_act_mask_ctrl ^= en_port_mask;
4320 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);
4321 #endif
4322
4323 if (adapter->iface_id == IFACE_ID0)
4324 iface = dvobj->padapters[IFACE_ID1];
4325 else if (adapter->iface_id == IFACE_ID1)
4326 iface = dvobj->padapters[IFACE_ID0];
4327
4328
4329 if (adapter->hw_port == HW_PORT0) {
4330 adapter->hw_port = HW_PORT1;
4331 iface->hw_port = HW_PORT0;
4332 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4333 ADPT_ARG(iface), ADPT_ARG(adapter));
4334 } else {
4335 adapter->hw_port = HW_PORT0;
4336 iface->hw_port = HW_PORT1;
4337 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4338 ADPT_ARG(adapter), ADPT_ARG(iface));
4339 }
4340
4341 #ifdef DBG_RUNTIME_PORT_SWITCH
4342 msr = rtw_read8(adapter, MSR);
4343 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4344 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4345 #if defined(CONFIG_RTL8192F)
4346 wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4347 #endif
4348
4349 for (i = 0; i < 2; i++)
4350 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4351 for (i = 0; i < 2; i++)
4352 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4353
4354 for (i = 0; i < 8; i++)
4355 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4356 for (i = 0; i < 8; i++)
4357 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4358
4359 for (i = 0; i < 6; i++)
4360 macid[i] = rtw_read8(adapter, REG_MACID + i);
4361
4362 for (i = 0; i < 6; i++)
4363 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4364
4365 for (i = 0; i < 6; i++)
4366 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4367
4368 for (i = 0; i < 6; i++)
4369 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4370
4371 RTW_INFO(FUNC_ADPT_FMT" after switch\n"
4372 "msr:0x%02x\n"
4373 "bcn_ctrl:0x%02x\n"
4374 "bcn_ctrl_1:0x%02x\n"
4375 #if defined(CONFIG_RTL8192F)
4376 "wlan_act_mask_ctrl:0x%02x\n"
4377 #endif
4378 "atimwnd:%u\n"
4379 "atimwnd_1:%u\n"
4380 "tsftr:%llu\n"
4381 "tsftr1:%llu\n"
4382 "macid:"MAC_FMT"\n"
4383 "bssid:"MAC_FMT"\n"
4384 "macid_1:"MAC_FMT"\n"
4385 "bssid_1:"MAC_FMT"\n"
4386 , FUNC_ADPT_ARG(adapter)
4387 , msr
4388 , bcn_ctrl
4389 , bcn_ctrl_1
4390 #if defined(CONFIG_RTL8192F)
4391 , wlan_act_mask_ctrl
4392 #endif
4393 , *((u16 *)atimwnd)
4394 , *((u16 *)atimwnd_1)
4395 , *((u64 *)tsftr)
4396 , *((u64 *)tsftr_1)
4397 , MAC_ARG(macid)
4398 , MAC_ARG(bssid)
4399 , MAC_ARG(macid_1)
4400 , MAC_ARG(bssid_1)
4401 );
4402 #endif /* DBG_RUNTIME_PORT_SWITCH */
4403
4404 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
4405 #endif /* CONFIG_CONCURRENT_MODE */
4406 }
4407
4408 const char *const _h2c_msr_role_str[] = {
4409 "RSVD",
4410 "STA",
4411 "AP",
4412 "GC",
4413 "GO",
4414 "TDLS",
4415 "ADHOC",
4416 "MESH",
4417 "INVALID",
4418 };
4419
4420 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_default_port_id_cmd(_adapter * adapter,u8 mac_id)4421 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
4422 {
4423 s32 ret = _SUCCESS;
4424 u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
4425 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4426 u8 port_id = rtw_hal_get_port(adapter);
4427
4428 if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))
4429 return ret;
4430
4431 SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);
4432 SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
4433
4434 RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
4435 RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",
4436 __func__, ADPT_ARG(adapter), port_id, mac_id);
4437
4438 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
4439 dvobj->dft.port_id = port_id;
4440 dvobj->dft.mac_id = mac_id;
4441
4442 return ret;
4443 }
rtw_set_default_port_id(_adapter * adapter)4444 s32 rtw_set_default_port_id(_adapter *adapter)
4445 {
4446 s32 ret = _SUCCESS;
4447 struct sta_info *psta;
4448 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4449
4450 if (is_client_associated_to_ap(adapter)) {
4451 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
4452 if (psta)
4453 ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
4454 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
4455
4456 } else {
4457 }
4458
4459 return ret;
4460 }
rtw_set_ps_rsvd_page(_adapter * adapter)4461 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
4462 {
4463 s32 ret = _SUCCESS;
4464 u16 media_status_rpt = RT_MEDIA_CONNECT;
4465 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4466
4467 if (adapter->iface_id == pwrctl->fw_psmode_iface_id)
4468 return ret;
4469
4470 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
4471 (u8 *)&media_status_rpt);
4472
4473 return ret;
4474 }
4475
4476 #if 0
4477 _adapter * _rtw_search_dp_iface(_adapter *adapter)
4478 {
4479 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4480 _adapter *iface;
4481 _adapter *target_iface = NULL;
4482 int i;
4483 u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;
4484 u8 p2p_go_num = 0, p2p_gc_num = 0;
4485 _adapter *sta_ifs[8];
4486 _adapter *ap_ifs[8];
4487 _adapter *mesh_ifs[8];
4488 _adapter *gc_ifs[8];
4489 _adapter *go_ifs[8];
4490
4491 for (i = 0; i < dvobj->iface_nums; i++) {
4492 iface = dvobj->padapters[i];
4493
4494 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
4495 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4496 sta_ifs[sta_num++] = iface;
4497
4498 #ifdef CONFIG_TDLS
4499 if (iface->tdlsinfo.link_established == _TRUE)
4500 tdls_num++;
4501 #endif
4502 #ifdef CONFIG_P2P
4503 if (MLME_IS_GC(iface))
4504 gc_ifs[p2p_gc_num++] = iface;
4505 #endif
4506 }
4507 #ifdef CONFIG_AP_MODE
4508 } else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
4509 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4510 ap_ifs[ap_num++] = iface;
4511 #ifdef CONFIG_P2P
4512 if (MLME_IS_GO(iface))
4513 go_ifs[p2p_go_num++] = iface;
4514 #endif
4515 }
4516 #endif
4517 } else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
4518 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4519 ) {
4520 adhoc_num++;
4521
4522 #ifdef CONFIG_RTW_MESH
4523 } else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
4524 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4525 ) {
4526 mesh_ifs[mesh_num++] = iface;
4527 #endif
4528 }
4529 }
4530
4531 if (p2p_gc_num) {
4532 target_iface = gc_ifs[0];
4533 }
4534 else if (sta_num) {
4535 if(sta_num == 1) {
4536 target_iface = sta_ifs[0];
4537 } else if (sta_num >= 2) {
4538 /*TODO get target_iface by timestamp*/
4539 target_iface = sta_ifs[0];
4540 }
4541 } else if (ap_num) {
4542 target_iface = ap_ifs[0];
4543 }
4544
4545 RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);
4546 RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);
4547 RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);
4548 RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);
4549 RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);
4550 RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);
4551 RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);
4552
4553 if (target_iface)
4554 RTW_INFO("%s => target_iface ("ADPT_FMT")\n",
4555 __func__, ADPT_ARG(target_iface));
4556 else
4557 RTW_INFO("%s => target_iface NULL\n", __func__);
4558
4559 return target_iface;
4560 }
4561
4562 void rtw_search_default_port(_adapter *adapter)
4563 {
4564 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4565 _adapter *adp_iface = NULL;
4566 #ifdef CONFIG_WOWLAN
4567 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
4568
4569 if (pwrpriv->wowlan_mode == _TRUE) {
4570 adp_iface = adapter;
4571 goto exit;
4572 }
4573 #endif
4574 adp_iface = _rtw_search_dp_iface(adapter);
4575
4576 exit :
4577 if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))
4578 rtw_set_default_port_id(adp_iface);
4579 else
4580 rtw_hal_set_default_port_id_cmd(adapter, 0);
4581
4582 if (1) {
4583 _adapter *tmp_adp;
4584
4585 tmp_adp = (adp_iface) ? adp_iface : adapter;
4586
4587 RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",
4588 __func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));
4589 }
4590 }
4591 #endif
4592 #endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/
4593
4594 #ifdef CONFIG_P2P_PS
4595 #ifdef RTW_HALMAC
rtw_set_p2p_ps_offload_cmd(_adapter * adapter,u8 p2p_ps_state)4596 void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
4597 {
4598 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4599 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4600 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4601 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4602 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
4603 struct sta_priv *pstapriv = &adapter->stapriv;
4604 struct sta_info *psta;
4605 HAL_P2P_PS_PARA p2p_ps_para;
4606 int status = -1;
4607 u8 i;
4608 u8 hw_port = rtw_hal_get_port(adapter);
4609
4610 _rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
4611 _rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
4612
4613 (&p2p_ps_para)->p2p_port_id = hw_port;
4614 (&p2p_ps_para)->p2p_group = 0;
4615 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
4616 if (psta) {
4617 (&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
4618 } else {
4619 if (p2p_ps_state != P2P_PS_DISABLE) {
4620 RTW_ERR("%s , psta was NULL\n", __func__);
4621 return;
4622 }
4623 }
4624
4625
4626 switch (p2p_ps_state) {
4627 case P2P_PS_DISABLE:
4628 RTW_INFO("P2P_PS_DISABLE\n");
4629 _rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
4630 break;
4631
4632 case P2P_PS_ENABLE:
4633 RTW_INFO("P2P_PS_ENABLE\n");
4634 /* update CTWindow value. */
4635 if (pwdinfo->ctwindow > 0) {
4636 (&p2p_ps_para)->ctwindow_en = 1;
4637 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4638 /*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
4639 }
4640
4641
4642 if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
4643 (&p2p_ps_para)->offload_en = 1;
4644 if (pwdinfo->role == P2P_ROLE_GO) {
4645 (&p2p_ps_para)->role = 1;
4646 (&p2p_ps_para)->all_sta_sleep = 0;
4647 } else
4648 (&p2p_ps_para)->role = 0;
4649
4650 (&p2p_ps_para)->discovery = 0;
4651 }
4652 /* hw only support 2 set of NoA */
4653 for (i = 0; i < pwdinfo->noa_num; i++) {
4654 /* To control the register setting for which NOA */
4655 (&p2p_ps_para)->noa_sel = i;
4656 (&p2p_ps_para)->noa_en = 1;
4657 (&p2p_ps_para)->disable_close_rf = 0;
4658 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
4659 #ifdef CONFIG_CONCURRENT_MODE
4660 if (rtw_mi_buddy_check_fwstate(adapter, WIFI_ASOC_STATE))
4661 #endif /* CONFIG_CONCURRENT_MODE */
4662 (&p2p_ps_para)->disable_close_rf = 1;
4663 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
4664 /* config P2P NoA Descriptor Register */
4665 /* config NOA duration */
4666 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
4667 /* config NOA interval */
4668 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
4669 /* config NOA start time */
4670 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
4671 /* config NOA count */
4672 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
4673 /*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
4674 (&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
4675 (&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
4676 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4677 if (status == -1)
4678 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4679 }
4680
4681 break;
4682
4683 case P2P_PS_SCAN:
4684 /*This feature FW not ready 20161116 YiWei*/
4685 return;
4686 /*
4687 RTW_INFO("P2P_PS_SCAN\n");
4688 (&p2p_ps_para)->discovery = 1;
4689 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4690 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4691 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4692 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4693 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4694 */
4695 break;
4696
4697 case P2P_PS_SCAN_DONE:
4698 /*This feature FW not ready 20161116 YiWei*/
4699 return;
4700 /*
4701 RTW_INFO("P2P_PS_SCAN_DONE\n");
4702 (&p2p_ps_para)->discovery = 0;
4703 pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
4704 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4705 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4706 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4707 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4708 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4709 */
4710 break;
4711
4712 default:
4713 break;
4714 }
4715
4716 if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
4717 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4718 if (status == -1)
4719 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4720 }
4721 _rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
4722
4723 }
4724 #endif /* RTW_HALMAC */
4725 #endif /* CONFIG_P2P */
4726
4727 /*
4728 * rtw_hal_set_FwMediaStatusRpt_cmd -
4729 *
4730 * @adapter:
4731 * @opmode: 0:disconnect, 1:connect
4732 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
4733 * @miracast_sink: 0:source. 1:sink
4734 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
4735 * @macid:
4736 * @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end
4737 * @macid_end:
4738 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)4739 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)
4740 {
4741 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
4742 u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
4743 int i;
4744 s32 ret;
4745 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4746 u8 hw_port = rtw_hal_get_port(adapter);
4747 #endif
4748 u8 op_num_change_bmp = 0;
4749
4750 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
4751 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
4752 SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
4753 SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
4754 SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
4755 SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
4756 SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
4757 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4758 SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);
4759 #endif
4760 RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
4761
4762 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
4763 if (ret != _SUCCESS)
4764 goto exit;
4765
4766 #if defined(CONFIG_RTL8188E)
4767 if (rtw_get_chip_type(adapter) == RTL8188E) {
4768 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4769
4770 /* 8188E FW doesn't set macid no link, driver does it by self */
4771 if (opmode)
4772 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
4773 else
4774 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
4775
4776 /* for 8188E RA */
4777 #if (RATE_ADAPTIVE_SUPPORT == 1)
4778 if (hal_data->fw_ractrl == _FALSE) {
4779 u8 max_macid;
4780
4781 max_macid = rtw_search_max_mac_id(adapter);
4782 rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
4783 }
4784 #endif
4785 }
4786 #endif
4787
4788 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
4789 /* TODO: this should move to IOT issue area */
4790 if (rtw_get_chip_type(adapter) == RTL8812
4791 || rtw_get_chip_type(adapter) == RTL8821
4792 ) {
4793 if (MLME_IS_STA(adapter))
4794 Hal_PatchwithJaguar_8812(adapter, opmode);
4795 }
4796 #endif
4797
4798 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
4799 if (macid_ind == 0)
4800 macid_end = macid;
4801
4802 for (i = macid; macid <= macid_end; macid++) {
4803 op_num_change_bmp |= rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
4804 if (!opmode) {
4805 rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
4806 rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
4807 rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
4808 rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
4809 }
4810 }
4811
4812 #if CONFIG_TX_AC_LIFETIME
4813 if (op_num_change_bmp)
4814 rtw_hal_update_tx_aclt(adapter);
4815 #endif
4816
4817 if (!opmode)
4818 rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
4819
4820 exit:
4821 return ret;
4822 }
4823
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)4824 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
4825 {
4826 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
4827 }
4828
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)4829 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
4830 {
4831 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
4832 }
4833
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4834 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4835 {
4836 u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
4837 u8 ret = 0;
4838
4839 RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
4840 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
4841 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
4842 rsvdpageloc->LocBTQosNull);
4843
4844 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
4845 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
4846 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
4847 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
4848 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
4849
4850 ret = rtw_hal_fill_h2c_cmd(padapter,
4851 H2C_RSVD_PAGE,
4852 H2C_RSVDPAGE_LOC_LEN,
4853 u1H2CRsvdPageParm);
4854
4855 }
4856
4857 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)4858 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
4859 {
4860 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4861
4862 if (IS_8723D_SERIES(pHalData->version_id) || IS_8192F_SERIES(pHalData->version_id)
4863 || IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id)
4864 || IS_8822C_SERIES(pHalData->version_id))
4865 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4866 /*
4867 * Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
4868 * It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
4869 * and implement HAL function.
4870 * TODO: GPIO_8 multi function?
4871 */
4872
4873 if ((index == 13 || index == 14)
4874 #if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
4875 /* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
4876 && (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
4877 #endif
4878 )
4879 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4880 }
4881
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)4882 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
4883 {
4884 #if defined(CONFIG_RTL8192F)
4885 rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&outputval));
4886 #else
4887 if (index <= 7) {
4888 /* config GPIO mode */
4889 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4890 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4891
4892 /* config GPIO Sel */
4893 /* 0: input */
4894 /* 1: output */
4895 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4896 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
4897
4898 /* set output value */
4899 if (outputval) {
4900 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4901 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
4902 } else {
4903 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4904 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
4905 }
4906 } else if (index <= 15) {
4907 /* 88C Series: */
4908 /* index: 11~8 transform to 3~0 */
4909 /* 8723 Series: */
4910 /* index: 12~8 transform to 4~0 */
4911
4912 index -= 8;
4913
4914 /* config GPIO mode */
4915 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4916 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4917
4918 /* config GPIO Sel */
4919 /* 0: input */
4920 /* 1: output */
4921 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4922 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
4923
4924 /* set output value */
4925 if (outputval) {
4926 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4927 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
4928 } else {
4929 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4930 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
4931 }
4932 } else {
4933 RTW_INFO("%s: invalid GPIO%d=%d\n",
4934 __FUNCTION__, index, outputval);
4935 }
4936 #endif
4937 }
rtw_hal_set_input_gpio(_adapter * padapter,u8 index)4938 void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
4939 {
4940 #if defined(CONFIG_RTL8192F)
4941 rtw_hal_set_hwreg(padapter, HW_VAR_WOW_INPUT_GPIO, (u8 *)(&index));
4942 #else
4943 if (index <= 7) {
4944 /* config GPIO mode */
4945 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4946 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4947
4948 /* config GPIO Sel */
4949 /* 0: input */
4950 /* 1: output */
4951 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4952 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
4953
4954 } else if (index <= 15) {
4955 /* 88C Series: */
4956 /* index: 11~8 transform to 3~0 */
4957 /* 8723 Series: */
4958 /* index: 12~8 transform to 4~0 */
4959
4960 index -= 8;
4961
4962 /* config GPIO mode */
4963 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4964 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4965
4966 /* config GPIO Sel */
4967 /* 0: input */
4968 /* 1: output */
4969 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4970 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
4971 } else
4972 RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
4973 #endif
4974 }
4975
4976 #endif
4977
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4978 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4979 {
4980 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
4981 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4982 u8 ret = 0;
4983 #ifdef CONFIG_WOWLAN
4984 u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
4985
4986 RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
4987 __func__, rsvdpageloc->LocRemoteCtrlInfo,
4988 rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
4989 rsvdpageloc->LocNDPInfo);
4990 RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
4991 __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
4992 rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
4993
4994 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
4995 SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
4996 SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
4997 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
4998 rsvdpageloc->LocNbrAdv);
4999 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
5000 rsvdpageloc->LocNDPInfo);
5001 #ifdef CONFIG_GTK_OL
5002 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
5003 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
5004 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
5005 #endif /* CONFIG_GTK_OL */
5006 ret = rtw_hal_fill_h2c_cmd(padapter,
5007 H2C_AOAC_RSVD_PAGE,
5008 H2C_AOAC_RSVDPAGE_LOC_LEN,
5009 u1H2CAoacRsvdPageParm);
5010
5011 RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
5012 _rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
5013 SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
5014 rsvdpageloc->LocAOACReport);
5015 ret = rtw_hal_fill_h2c_cmd(padapter,
5016 H2C_AOAC_RSVDPAGE3,
5017 H2C_AOAC_RSVDPAGE_LOC_LEN,
5018 u1H2CAoacRsvdPageParm);
5019 pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
5020 }
5021 #ifdef CONFIG_PNO_SUPPORT
5022 else {
5023
5024 if (!pwrpriv->wowlan_in_resume) {
5025 RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
5026 _rtw_memset(&u1H2CAoacRsvdPageParm, 0,
5027 sizeof(u1H2CAoacRsvdPageParm));
5028 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
5029 rsvdpageloc->LocPNOInfo);
5030 ret = rtw_hal_fill_h2c_cmd(padapter,
5031 H2C_AOAC_RSVDPAGE3,
5032 H2C_AOAC_RSVDPAGE_LOC_LEN,
5033 u1H2CAoacRsvdPageParm);
5034 }
5035 }
5036 #endif /* CONFIG_PNO_SUPPORT */
5037 #endif /* CONFIG_WOWLAN */
5038 }
5039
5040 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)5041 void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
5042 {
5043 struct hal_ops *pHalFunc = &padapter->hal_func;
5044 u8 u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};
5045 u8 ret = 0;
5046
5047
5048 RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);
5049
5050 SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);
5051 SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);
5052 ret = rtw_hal_fill_h2c_cmd(padapter,
5053 H2C_FW_DBG_MSG_PKT,
5054 H2C_FW_DBG_MSG_PKT_LEN,
5055 u1H2C_fw_dbg_msg_pkt_parm);
5056
5057 }
5058 #endif /*DBG_FW_DEBUG_MSG_PKT*/
5059
5060 /*#define DBG_GET_RSVD_PAGE*/
rtw_hal_get_rsvd_page(_adapter * adapter,u32 page_offset,u32 page_num,u8 * buffer,u32 buffer_size)5061 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
5062 u32 page_num, u8 *buffer, u32 buffer_size)
5063 {
5064 u32 addr = 0, size = 0, count = 0;
5065 u32 page_size = 0, data_low = 0, data_high = 0;
5066 u16 txbndy = 0, offset = 0;
5067 u8 i = 0;
5068 bool rst = _FALSE;
5069
5070 #ifdef DBG_LA_MODE
5071 struct registry_priv *registry_par = &adapter->registrypriv;
5072
5073 if(registry_par->la_mode_en == 1) {
5074 RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);
5075 return rst;
5076 }
5077 #endif
5078 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5079
5080 addr = page_offset * page_size;
5081 size = page_num * page_size;
5082
5083 if (buffer_size < size) {
5084 RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
5085 __func__, buffer_size, size);
5086 return rst;
5087 }
5088 #ifdef RTW_HALMAC
5089 if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
5090 rst = _FALSE;
5091 else
5092 rst = _TRUE;
5093 #else
5094 txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
5095
5096 offset = (txbndy + page_offset) * page_size / 8;
5097 count = (buffer_size / 8) + 1;
5098
5099 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
5100
5101 for (i = 0 ; i < count ; i++) {
5102 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
5103 data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
5104 data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
5105 _rtw_memcpy(buffer + (i * 8),
5106 &data_low, sizeof(data_low));
5107 _rtw_memcpy(buffer + ((i * 8) + 4),
5108 &data_high, sizeof(data_high));
5109 }
5110 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
5111 rst = _TRUE;
5112 #endif /*RTW_HALMAC*/
5113
5114 #ifdef DBG_GET_RSVD_PAGE
5115 RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
5116 __func__, page_offset, page_num, addr, size);
5117 RTW_INFO_DUMP("\n", buffer, size);
5118 RTW_INFO(" ==================================================\n");
5119 #endif
5120 return rst;
5121 }
5122
rtw_dump_rsvd_page(void * sel,_adapter * adapter,u8 page_offset,u8 page_num)5123 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
5124 {
5125 u32 page_size = 0;
5126 u8 *buffer = NULL;
5127 u32 buf_size = 0;
5128
5129 if (page_num == 0)
5130 return;
5131
5132 RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");
5133 RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
5134
5135 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5136 if (page_size) {
5137 buf_size = page_size * page_num;
5138 buffer = rtw_zvmalloc(buf_size);
5139
5140 if (buffer) {
5141 rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
5142 RTW_DUMP_SEL(sel, buffer, buf_size);
5143 rtw_vmfree(buffer, buf_size);
5144 } else
5145 RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
5146 } else
5147 RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
5148
5149 RTW_PRINT_SEL(sel, "==========================\n");
5150 }
5151
5152 #ifdef CONFIG_SUPPORT_FIFO_DUMP
rtw_dump_fifo(void * sel,_adapter * adapter,u8 fifo_sel,u32 fifo_addr,u32 fifo_size)5153 void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
5154 {
5155 u8 *buffer = NULL;
5156 u32 buff_size = 0;
5157 static const char * const fifo_sel_str[] = {
5158 "TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
5159 };
5160
5161 if (fifo_sel > 5) {
5162 RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
5163 return;
5164 }
5165
5166 RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
5167 RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
5168
5169 if (fifo_size) {
5170 buff_size = RND4(fifo_size);
5171 buffer = rtw_zvmalloc(buff_size);
5172 if (buffer == NULL)
5173 buff_size = 0;
5174 }
5175
5176 rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
5177
5178 if (buffer) {
5179 RTW_DUMP_SEL(sel, buffer, fifo_size);
5180 rtw_vmfree(buffer, buff_size);
5181 }
5182
5183 RTW_PRINT_SEL(sel, "==========================\n");
5184 }
5185 #endif
5186
5187 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)5188 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
5189 {
5190 RTW_INFO("%s: Set 0x690=0x00\n", __func__);
5191 rtw_write8(adapter, REG_WOW_CTRL,
5192 (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
5193 RTW_PRINT("%s: Release RXDMA\n", __func__);
5194 rtw_write32(adapter, REG_RXPKT_NUM,
5195 (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
5196 }
5197 #if defined(CONFIG_RTL8188E)
rtw_hal_disable_tx_report(_adapter * adapter)5198 static void rtw_hal_disable_tx_report(_adapter *adapter)
5199 {
5200 rtw_write8(adapter, REG_TX_RPT_CTRL,
5201 ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
5202 RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5203 }
5204
rtw_hal_enable_tx_report(_adapter * adapter)5205 static void rtw_hal_enable_tx_report(_adapter *adapter)
5206 {
5207 rtw_write8(adapter, REG_TX_RPT_CTRL,
5208 ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
5209 RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5210 }
5211 #endif
rtw_hal_release_rx_dma(_adapter * adapter)5212 static void rtw_hal_release_rx_dma(_adapter *adapter)
5213 {
5214 u32 val32 = 0;
5215
5216 val32 = rtw_read32(adapter, REG_RXPKT_NUM);
5217
5218 rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
5219
5220 RTW_INFO("%s, [0x%04x]: 0x%08x\n",
5221 __func__, REG_RXPKT_NUM, (u32)(val32 & (~RW_RELEASE_EN)));
5222 }
5223
rtw_hal_pause_rx_dma(_adapter * adapter)5224 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
5225 {
5226 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
5227 u8 ret = 0;
5228 s8 trycnt = 100;
5229 u32 tmp = 0;
5230 int res = 0;
5231 /* RX DMA stop */
5232 RTW_PRINT("Pause DMA\n");
5233 rtw_write32(adapter, REG_RXPKT_NUM,
5234 (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
5235 do {
5236 if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
5237 #ifdef CONFIG_USB_HCI
5238 /* stop interface before leave */
5239 if (_TRUE == hal->usb_intf_start) {
5240 rtw_intf_stop(adapter);
5241 RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
5242 RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
5243 }
5244 #endif /* CONFIG_USB_HCI */
5245
5246 RTW_PRINT("RX_DMA_IDLE is true\n");
5247 ret = _SUCCESS;
5248 break;
5249 }
5250 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5251 else {
5252 res = RecvOnePkt(adapter);
5253 RTW_PRINT("RecvOnePkt Result: %d\n", res);
5254 }
5255 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
5256
5257 #ifdef CONFIG_USB_HCI
5258 else {
5259 /* to avoid interface start repeatedly */
5260 if (_FALSE == hal->usb_intf_start)
5261 rtw_intf_start(adapter);
5262 }
5263 #endif /* CONFIG_USB_HCI */
5264 } while (trycnt--);
5265
5266 if (trycnt < 0) {
5267 tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
5268
5269 RTW_PRINT("Stop RX DMA failed......\n");
5270 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
5271 RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
5272 __func__, rtw_read16(adapter, REG_RXPKTNUM));
5273 #else
5274 RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
5275 __func__, ((tmp & 0xFF00) >> 8));
5276 #endif
5277 if (tmp & BIT(3))
5278 RTW_PRINT("%s, RX DMA has req\n",
5279 __func__);
5280 else
5281 RTW_PRINT("%s, RX DMA no req\n",
5282 __func__);
5283 ret = _FAIL;
5284 }
5285
5286 return ret;
5287 }
5288
5289 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5290 #ifndef RTW_HALMAC
rtw_hal_enable_cpwm2(_adapter * adapter)5291 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
5292 {
5293 u8 ret = 0;
5294 int res = 0;
5295 u32 tmp = 0;
5296 #ifdef CONFIG_GPIO_WAKEUP
5297 return _SUCCESS;
5298 #else
5299 RTW_PRINT("%s\n", __func__);
5300
5301 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5302 if (!res)
5303 RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
5304 else
5305 RTW_INFO("sdio_local_read fail\n");
5306
5307 tmp = SDIO_HIMR_CPWM2_MSK;
5308
5309 res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5310
5311 if (!res) {
5312 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5313 RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
5314 ret = _SUCCESS;
5315 } else {
5316 RTW_INFO("sdio_local_write fail\n");
5317 ret = _FAIL;
5318 }
5319 return ret;
5320 #endif /* CONFIG_CPIO_WAKEUP */
5321 }
5322 #endif
5323 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
5324 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
5325
5326 #ifdef CONFIG_WOWLAN
5327 /*
5328 * rtw_hal_check_wow_ctrl
5329 * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
5330 * If 0x1C7 == 0 (for 3081), WOW enable successful.
5331 * _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
5332 * If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
5333 */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)5334 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
5335 {
5336 u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
5337 u8 mstatus = 0;
5338 u8 reason = 0xFF;
5339 u8 trycnt = 25;
5340 u8 res = _FALSE;
5341
5342 if (IS_HARDWARE_TYPE_JAGUAR2(adapter) || IS_HARDWARE_TYPE_JAGUAR3(adapter)) {
5343 if (chk_type) {
5344 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5345 RTW_INFO("%s reason:0x%02x\n", __func__, reason);
5346
5347 while (reason && trycnt > 1) {
5348 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5349 RTW_PRINT("Loop index: %d :0x%02x\n",
5350 trycnt, reason);
5351 trycnt--;
5352 rtw_msleep_os(20);
5353 }
5354 if (!reason)
5355 res = _TRUE;
5356 else
5357 res = _FALSE;
5358 } else {
5359 /* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
5360 fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
5361 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
5362 RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
5363
5364 while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
5365 rtw_msleep_os(20);
5366 fe1_imr = rtw_read32(adapter, REG_FE1IMR);
5367 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
5368 RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
5369 trycnt, fe1_imr, rxpkt_num);
5370 trycnt--;
5371 }
5372
5373 if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
5374 res = _FALSE;
5375 else
5376 res = _TRUE;
5377 }
5378 } else {
5379 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5380 RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
5381
5382
5383 if (chk_type) {
5384 while (!(mstatus & BIT1) && trycnt > 1) {
5385 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5386 RTW_PRINT("Loop index: %d :0x%02x\n",
5387 trycnt, mstatus);
5388 trycnt--;
5389 rtw_msleep_os(20);
5390 }
5391 if (mstatus & BIT1)
5392 res = _TRUE;
5393 else
5394 res = _FALSE;
5395 } else {
5396 while (mstatus & BIT1 && trycnt > 1) {
5397 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5398 RTW_PRINT("Loop index: %d :0x%02x\n",
5399 trycnt, mstatus);
5400 trycnt--;
5401 rtw_msleep_os(20);
5402 }
5403
5404 if (mstatus & BIT1)
5405 res = _FALSE;
5406 else
5407 res = _TRUE;
5408 }
5409 }
5410
5411 RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
5412 __func__, chk_type, res, (25 - trycnt));
5413 return res;
5414 }
5415
5416 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_check_pno_enabled(_adapter * adapter)5417 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
5418 {
5419 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5420 u8 res = 0, count = 0;
5421 u8 ret = _FALSE;
5422
5423 if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
5424 res = rtw_read8(adapter, REG_PNO_STATUS);
5425 while (!(res & BIT(7)) && count < 25) {
5426 RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
5427 count, res);
5428 res = rtw_read8(adapter, REG_PNO_STATUS);
5429 count++;
5430 rtw_msleep_os(2);
5431 }
5432 if (res & BIT(7))
5433 ret = _TRUE;
5434 else
5435 ret = _FALSE;
5436 RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
5437 }
5438 return ret;
5439 }
5440 #endif
5441
rtw_hal_backup_rate(_adapter * adapter)5442 static void rtw_hal_backup_rate(_adapter *adapter)
5443 {
5444 RTW_INFO("%s\n", __func__);
5445 /* backup data rate to register 0x8b for wowlan FW */
5446 rtw_write8(adapter, 0x8d, 1);
5447 rtw_write8(adapter, 0x8c, 0);
5448 rtw_write8(adapter, 0x8f, 0x40);
5449 rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
5450 }
5451
5452 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)5453 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
5454 {
5455 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5456 int cam_id, index = 0;
5457 u8 *addr = NULL;
5458
5459 if (!MLME_IS_STA(adapter))
5460 return;
5461
5462 addr = get_bssid(pmlmepriv);
5463
5464 if (addr == NULL) {
5465 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
5466 return;
5467 }
5468
5469 rtw_clean_dk_section(adapter);
5470
5471 do {
5472 cam_id = rtw_camid_search(adapter, addr, index, 1);
5473
5474 if (cam_id == -1)
5475 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
5476 else
5477 rtw_sec_cam_swap(adapter, cam_id, index);
5478
5479 index++;
5480 } while (index < 4);
5481
5482 rtw_write8(adapter, REG_SECCFG, 0xcc);
5483 }
5484
rtw_hal_update_gtk_offload_info(_adapter * adapter)5485 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
5486 {
5487 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5488 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5489 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5490 struct security_priv *psecuritypriv = &adapter->securitypriv;
5491 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5492 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
5493 _irqL irqL;
5494 u8 get_key[16];
5495 u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;
5496 u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
5497
5498 if (!MLME_IS_STA(adapter))
5499 return;
5500
5501 _rtw_memset(get_key, 0, sizeof(get_key));
5502 _rtw_memcpy(&replay_count,
5503 paoac_rpt->replay_counter_eapol_key, 8);
5504
5505 /*read gtk key index*/
5506 gtk_id = paoac_rpt->key_index;
5507 aoac_rpt_ver = paoac_rpt->version_info;
5508
5509 if (aoac_rpt_ver == 0) {
5510 /* initial verison */
5511 if (gtk_id == 5)
5512 has_rekey = _FALSE;
5513 else
5514 has_rekey = _TRUE;
5515 } else if (aoac_rpt_ver >= 1) {
5516 /* Add krack patch */
5517 if (gtk_id == 5)
5518 RTW_WARN("%s FW check iv fail\n", __func__);
5519
5520 if (aoac_rpt_ver == 1)
5521 RTW_WARN("%s aoac report version should be update to v2\n", __func__);
5522
5523 /* Fix key id mismatch */
5524 if (aoac_rpt_ver == 2)
5525 has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;
5526 }
5527
5528 if (has_rekey == _FALSE) {
5529 RTW_INFO("%s no rekey event happened.\n", __func__);
5530 } else if (has_rekey == _TRUE) {
5531 RTW_INFO("%s update security key.\n", __func__);
5532 /*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
5533 rtw_sec_read_cam_ent(adapter, gtk_id,
5534 NULL, NULL, get_key);
5535 rtw_clean_hw_dk_cam(adapter);
5536
5537 if (_rtw_camid_is_gk(adapter, gtk_id)) {
5538 _enter_critical_bh(&cam_ctl->lock, &irqL);
5539 _rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
5540 get_key, 16);
5541 _exit_critical_bh(&cam_ctl->lock, &irqL);
5542 } else {
5543 struct setkey_parm parm_gtk;
5544
5545 parm_gtk.algorithm = paoac_rpt->security_type;
5546 parm_gtk.keyid = gtk_id;
5547 _rtw_memcpy(parm_gtk.key, get_key, 16);
5548 setkey_hdl(adapter, (u8 *)&parm_gtk);
5549 }
5550
5551 /*update key into related sw variable and sec-cam cache*/
5552 psecuritypriv->dot118021XGrpKeyid = gtk_id;
5553 _rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
5554 get_key, 16);
5555 /* update SW TKIP TX/RX MIC value */
5556 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
5557 offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
5558 _rtw_memcpy(
5559 &psecuritypriv->dot118021XGrptxmickey[gtk_id],
5560 &(paoac_rpt->group_key[offset]),
5561 RTW_TKIP_MIC_LEN);
5562
5563 offset = RTW_KEK_LEN;
5564 _rtw_memcpy(
5565 &psecuritypriv->dot118021XGrprxmickey[gtk_id],
5566 &(paoac_rpt->group_key[offset]),
5567 RTW_TKIP_MIC_LEN);
5568 }
5569 RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
5570 KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
5571 }
5572
5573 /* Update broadcast RX IV */
5574 if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
5575 sz = sizeof(psecuritypriv->iv_seq[0]);
5576 for (i = 0 ; i < 4 ; i++) {
5577 _rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
5578 tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
5579 pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
5580 _rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
5581 }
5582 }
5583
5584 rtw_clean_dk_section(adapter);
5585
5586 rtw_write8(adapter, REG_SECCFG, 0x0c);
5587
5588 #ifdef CONFIG_GTK_OL_DBG
5589 /* if (gtk_keyindex != 5) */
5590 dump_sec_cam(RTW_DBGDUMP, adapter);
5591 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
5592 #endif
5593 }
5594 #endif /*CONFIG_GTK_OL*/
5595
rtw_dump_aoac_rpt(_adapter * adapter)5596 static void rtw_dump_aoac_rpt(_adapter *adapter)
5597 {
5598 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5599 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5600 int i = 0;
5601
5602 RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
5603 RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
5604 paoac_rpt->replay_counter_eapol_key, 8);
5605 RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
5606 RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
5607 RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
5608 RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
5609 paoac_rpt->wow_pattern_idx);
5610 RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
5611 RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);
5612 RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
5613 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
5614 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
5615 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
5616 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
5617 }
5618
rtw_hal_get_aoac_rpt(_adapter * adapter)5619 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
5620 {
5621 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5622 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5623 u32 page_offset = 0, page_number = 0;
5624 u32 page_size = 0, buf_size = 0;
5625 u8 *buffer = NULL;
5626 u8 i = 0, tmp = 0;
5627 int ret = -1;
5628
5629 /* read aoac report from rsvd page */
5630 page_offset = pwrctl->wowlan_aoac_rpt_loc;
5631 page_number = 1;
5632
5633 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5634 buf_size = page_size * page_number;
5635
5636 buffer = rtw_zvmalloc(buf_size);
5637
5638 if (buffer == NULL) {
5639 RTW_ERR("%s buffer allocate failed size(%d)\n",
5640 __func__, buf_size);
5641 return;
5642 }
5643
5644 RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
5645
5646 ret = rtw_hal_get_rsvd_page(adapter, page_offset,
5647 page_number, buffer, buf_size);
5648
5649 if (ret == _FALSE) {
5650 RTW_ERR("%s get aoac report failed\n", __func__);
5651 rtw_warn_on(1);
5652 goto _exit;
5653 }
5654
5655 _rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
5656 _rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
5657
5658 for (i = 0 ; i < 4 ; i++) {
5659 tmp = paoac_rpt->replay_counter_eapol_key[i];
5660 paoac_rpt->replay_counter_eapol_key[i] =
5661 paoac_rpt->replay_counter_eapol_key[7 - i];
5662 paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
5663 }
5664
5665 rtw_dump_aoac_rpt(adapter);
5666
5667 _exit:
5668 if (buffer)
5669 rtw_vmfree(buffer, buf_size);
5670 }
5671
rtw_hal_update_tx_iv(_adapter * adapter)5672 static void rtw_hal_update_tx_iv(_adapter *adapter)
5673 {
5674 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5675 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5676 struct sta_info *psta;
5677 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
5678 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5679 struct security_priv *psecpriv = &adapter->securitypriv;
5680
5681 u16 val16 = 0;
5682 u32 val32 = 0;
5683 u64 txiv = 0;
5684 u8 *pval = NULL;
5685
5686 psta = rtw_get_stainfo(&adapter->stapriv,
5687 get_my_bssid(&pmlmeinfo->network));
5688
5689 /* Update TX iv data. */
5690 pval = (u8 *)&paoac_rpt->iv;
5691
5692 if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
5693 val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
5694 ((u16)(paoac_rpt->iv[0]) << 8);
5695 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5696 ((u32)(paoac_rpt->iv[5]) << 8) +
5697 ((u32)(paoac_rpt->iv[6]) << 16) +
5698 ((u32)(paoac_rpt->iv[7]) << 24);
5699 } else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
5700 val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
5701 ((u16)(paoac_rpt->iv[1]) << 8);
5702 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5703 ((u32)(paoac_rpt->iv[5]) << 8) +
5704 ((u32)(paoac_rpt->iv[6]) << 16) +
5705 ((u32)(paoac_rpt->iv[7]) << 24);
5706 }
5707
5708 if (psta) {
5709 txiv = val16 + ((u64)val32 << 16);
5710 if (txiv != 0)
5711 psta->dot11txpn.val = txiv;
5712 }
5713 }
5714
rtw_hal_update_sw_security_info(_adapter * adapter)5715 static void rtw_hal_update_sw_security_info(_adapter *adapter)
5716 {
5717 struct security_priv *psecpriv = &adapter->securitypriv;
5718 u8 sz = sizeof (psecpriv->iv_seq);
5719
5720 rtw_hal_update_tx_iv(adapter);
5721 #ifdef CONFIG_GTK_OL
5722 if (psecpriv->binstallKCK_KEK == _TRUE &&
5723 (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5724 rtw_hal_update_gtk_offload_info(adapter);
5725 #else
5726 _rtw_memset(psecpriv->iv_seq, 0, sz);
5727 #endif
5728 }
5729
5730 #if 0 //define but not use
5731 static u8 rtw_hal_set_gpio_custom_cmd(_adapter *adapter, u8 enable)
5732 {
5733 u8 H2CGpioCustomParm[H2C_GPIO_CUSTOM_LEN] = {0};
5734 u8 customid = 0x2, special_wakeup_reason = RX_MAGIC_PKT, custom_for_wakeup_reason=0x1;
5735 u8 ret = _FAIL;
5736
5737 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5738
5739 if(enable) {
5740 SET_H2CCMD_CUSTOMERID(H2CGpioCustomParm, customid);
5741 SET_H2CCMD_SPECIAL_WAKE_REASON(H2CGpioCustomParm, special_wakeup_reason);
5742 SET_H2CCMD_CUSTOM_WAKE_REASON(H2CGpioCustomParm, custom_for_wakeup_reason);
5743
5744 ret = rtw_hal_fill_h2c_cmd(adapter,
5745 H2C_GPIO_CUSTOM,
5746 H2C_GPIO_CUSTOM_LEN,
5747 H2CGpioCustomParm);
5748 RTW_DBG("%s(): H2C_cmd=%x, cmd=%02x, %02x, %02x\n", __func__, H2C_GPIO_CUSTOM,
5749 H2CGpioCustomParm[0], H2CGpioCustomParm[1], H2CGpioCustomParm[2]);
5750 }
5751
5752 return ret;
5753 }
5754 #endif
5755
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)5756 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
5757 {
5758 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
5759 u8 adopt = 1, check_period = 5;
5760 u8 ret = _FAIL;
5761 u8 hw_port = rtw_hal_get_port(adapter);
5762
5763 SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
5764 SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
5765 SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
5766 SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
5767 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5768 SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);
5769 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5770 #else
5771 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5772 #endif
5773 ret = rtw_hal_fill_h2c_cmd(adapter,
5774 H2C_KEEP_ALIVE,
5775 H2C_KEEP_ALIVE_CTRL_LEN,
5776 u1H2CKeepAliveParm);
5777
5778 return ret;
5779 }
5780
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)5781 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
5782 {
5783 u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
5784 u8 adopt = 1, check_period = 100, trypkt_num = 5;
5785 u8 ret = _FAIL;
5786 struct registry_priv *pregistry = &adapter->registrypriv;
5787 u8 hw_port = rtw_hal_get_port(adapter);
5788
5789 SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
5790 SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
5791 if (!(pregistry->wakeup_event & BIT(2)))
5792 SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt);
5793 SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
5794 SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
5795 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5796 SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);
5797 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5798 #else
5799 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5800 #endif
5801
5802 ret = rtw_hal_fill_h2c_cmd(adapter,
5803 H2C_DISCON_DECISION,
5804 H2C_DISCON_DECISION_LEN,
5805 u1H2CDisconDecisionParm);
5806 return ret;
5807 }
5808
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)5809 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
5810 {
5811 struct registry_priv *registry_par = &adapter->registrypriv;
5812 struct security_priv *psecpriv = &adapter->securitypriv;
5813 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5814 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5815
5816 u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
5817 u8 discont_wake = 0, gpionum = 0, gpio_dur = 0, no_wake = 0;
5818 u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
5819 u8 sdio_wakeup_enable = 1;
5820 u8 gpio_high_active = 0;
5821 u8 magic_pkt = 0;
5822 u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
5823 u8 ret = _FAIL;
5824 #ifdef CONFIG_DIS_UPHY
5825 u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;
5826 #endif /* CONFIG_DIS_UPHY */
5827
5828 #ifdef CONFIG_GPIO_WAKEUP
5829 gpio_high_active = ppwrpriv->is_high_active;
5830 gpionum = ppwrpriv->wowlan_gpio_index;
5831 sdio_wakeup_enable = 0;
5832 #endif /* CONFIG_GPIO_WAKEUP */
5833
5834 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
5835 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5836 no_wake = 1;
5837
5838 if (!ppwrpriv->wowlan_pno_enable &&
5839 registry_par->wakeup_event & BIT(0) && !no_wake)
5840 magic_pkt = enable;
5841
5842 if ((registry_par->wakeup_event & BIT(1)) &&
5843 (psecpriv->dot11PrivacyAlgrthm == _WEP40_ ||
5844 psecpriv->dot11PrivacyAlgrthm == _WEP104_) && !no_wake)
5845 hw_unicast = 1;
5846
5847 if (registry_par->wakeup_event & BIT(2) && !no_wake)
5848 discont_wake = enable;
5849
5850 RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
5851 enable, change_unit);
5852
5853 /* time = (gpio_dur/2) * gpio_unit, default:256 ms */
5854 if (enable && change_unit) {
5855 gpio_dur = 0x40;
5856 gpio_unit = 1;
5857 gpio_pulse_en = 1;
5858 }
5859
5860 #ifdef CONFIG_PLATFORM_ARM_RK3188
5861 if (enable) {
5862 gpio_pulse_en = 1;
5863 gpio_pulse_cnt = 0x04;
5864 }
5865 #endif
5866
5867 SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
5868 if(!no_wake)
5869 SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
5870 SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
5871 SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
5872 SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
5873 SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
5874
5875 #ifdef CONFIG_GTK_OL
5876 if (psecpriv->binstallKCK_KEK == _TRUE &&
5877 (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5878 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
5879 else
5880 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
5881 #else
5882 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
5883 #endif
5884 SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
5885 SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
5886 SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
5887
5888 SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
5889 SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
5890
5891 SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
5892 SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
5893
5894 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
5895 if (enable)
5896 SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5897 #endif
5898
5899 #ifdef CONFIG_DIS_UPHY
5900 if (enable) {
5901 dis_uphy = 1;
5902 /* time unit: 0 -> ms, 1 -> 256 ms*/
5903 dis_uphy_unit = 1;
5904 dis_uphy_time = 0x4;
5905 }
5906
5907 SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
5908 SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
5909 SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
5910 if (ppwrpriv->hst2dev_high_active == 1)
5911 SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
5912 #ifdef CONFIG_RTW_ONE_PIN_GPIO
5913 SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5914 SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
5915 SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
5916 #else
5917 SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
5918 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
5919 #endif /* CONFIG_DIS_UPHY */
5920
5921
5922 ret = rtw_hal_fill_h2c_cmd(adapter,
5923 H2C_WOWLAN,
5924 H2C_WOWLAN_LEN,
5925 u1H2CWoWlanCtrlParm);
5926 return ret;
5927 }
5928
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)5929 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
5930 {
5931 struct security_priv *psecuritypriv = &(adapter->securitypriv);
5932 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5933 struct registry_priv *pregistrypriv = &adapter->registrypriv;
5934 u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
5935 u8 ret = _FAIL, count = 0, no_wake = 0;
5936 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5937
5938 RTW_INFO("%s(): enable=%d\n", __func__, enable);
5939
5940 if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&
5941 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5942 no_wake = 1;
5943 if(no_wake) {
5944 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5945 u1H2CRemoteWakeCtrlParm, enable);
5946 } else {
5947 if (!ppwrpriv->wowlan_pno_enable) {
5948 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5949 u1H2CRemoteWakeCtrlParm, enable);
5950 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5951 u1H2CRemoteWakeCtrlParm, 1);
5952 #ifdef CONFIG_GTK_OL
5953 if (psecuritypriv->binstallKCK_KEK == _TRUE &&
5954 (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) {
5955 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5956 u1H2CRemoteWakeCtrlParm, 1);
5957 } else {
5958 RTW_INFO("no kck kek\n");
5959 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5960 u1H2CRemoteWakeCtrlParm, 0);
5961 }
5962 #endif /* CONFIG_GTK_OL */
5963
5964 #ifdef CONFIG_IPV6
5965 if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
5966 RTW_INFO("enable NS offload\n");
5967 SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
5968 u1H2CRemoteWakeCtrlParm, enable);
5969 }
5970
5971 /*
5972 * filter NetBios name service pkt to avoid being waked-up
5973 * by this kind of unicast pkt this exceptional modification
5974 * is used for match competitor's behavior
5975 */
5976
5977 SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
5978 u1H2CRemoteWakeCtrlParm, enable);
5979 #endif /*CONFIG_IPV6*/
5980 #if 0 /* replaced by WOWLAN pattern match */
5981 #ifdef CONFIG_RTL8192F
5982 if (IS_HARDWARE_TYPE_8192F(adapter)){
5983 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
5984 u1H2CRemoteWakeCtrlParm, enable);
5985 }
5986 #endif /* CONFIG_RTL8192F */
5987 #endif
5988 if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
5989 (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
5990 (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
5991 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5992 u1H2CRemoteWakeCtrlParm, 0);
5993 } else {
5994 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5995 u1H2CRemoteWakeCtrlParm, 1);
5996 }
5997
5998 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
5999 #ifdef CONFIG_GTK_OL
6000 if(_rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))
6001 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
6002 u1H2CRemoteWakeCtrlParm, enable);
6003 #endif /* CONFIG_GTK_OL */
6004 if (IS_HARDWARE_TYPE_8188E(adapter) ||
6005 IS_HARDWARE_TYPE_8812(adapter)) {
6006 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
6007 u1H2CRemoteWakeCtrlParm, 0);
6008 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6009 u1H2CRemoteWakeCtrlParm, 1);
6010 }
6011 }
6012
6013 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
6014 u1H2CRemoteWakeCtrlParm, 1);
6015 }
6016 #ifdef CONFIG_PNO_SUPPORT
6017 else {
6018 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
6019 u1H2CRemoteWakeCtrlParm, enable);
6020 SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
6021 u1H2CRemoteWakeCtrlParm, enable);
6022 }
6023 #endif
6024
6025 #ifdef CONFIG_P2P_WOWLAN
6026 if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
6027 RTW_INFO("P2P OFFLOAD ENABLE\n");
6028 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
6029 } else {
6030 RTW_INFO("P2P OFFLOAD DISABLE\n");
6031 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
6032 }
6033 #endif /* CONFIG_P2P_WOWLAN */
6034 }
6035
6036
6037 ret = rtw_hal_fill_h2c_cmd(adapter,
6038 H2C_REMOTE_WAKE_CTRL,
6039 H2C_REMOTE_WAKE_CTRL_LEN,
6040 u1H2CRemoteWakeCtrlParm);
6041 return ret;
6042 }
6043
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)6044 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
6045 {
6046 u8 ret = _FAIL;
6047 u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
6048
6049 RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
6050 __func__, group_alg, pairwise_alg);
6051 SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
6052 pairwise_alg);
6053 SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
6054 group_alg);
6055
6056 ret = rtw_hal_fill_h2c_cmd(adapter,
6057 H2C_AOAC_GLOBAL_INFO,
6058 H2C_AOAC_GLOBAL_INFO_LEN,
6059 u1H2CAOACGlobalInfoParm);
6060
6061 return ret;
6062 }
6063
6064 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)6065 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
6066 PRSVDPAGE_LOC rsvdpageloc, u8 enable)
6067 {
6068 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6069 u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
6070 u8 res = 0, count = 0, ret = _FAIL;
6071
6072 RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
6073 __func__, rsvdpageloc->LocProbePacket,
6074 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
6075
6076 SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
6077 SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
6078 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
6079 rsvdpageloc->LocScanInfo);
6080 SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
6081 rsvdpageloc->LocProbePacket);
6082 /*
6083 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
6084 rsvdpageloc->LocSSIDInfo);
6085 */
6086 ret = rtw_hal_fill_h2c_cmd(adapter,
6087 H2C_D0_SCAN_OFFLOAD_INFO,
6088 H2C_SCAN_OFFLOAD_CTRL_LEN,
6089 u1H2CScanOffloadInfoParm);
6090 return ret;
6091 }
6092 #endif /* CONFIG_PNO_SUPPORT */
6093
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)6094 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
6095 {
6096 struct security_priv *psecpriv = &padapter->securitypriv;
6097 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
6098 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6099 struct registry_priv *pregistry = &padapter->registrypriv;
6100 u8 pkt_type = 0, no_wake = 0;
6101
6102 if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&
6103 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
6104 no_wake = 1;
6105
6106 RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
6107
6108 rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
6109
6110 if (enable) {
6111 if(!no_wake)
6112 rtw_hal_set_global_info_cmd(padapter,
6113 psecpriv->dot118021XGrpPrivacy,
6114 psecpriv->dot11PrivacyAlgrthm);
6115
6116 if (!(ppwrpriv->wowlan_pno_enable)) {
6117 if (!no_wake)
6118 rtw_hal_set_disconnect_decision_cmd(padapter,
6119 enable);
6120 #ifdef CONFIG_ARP_KEEP_ALIVE
6121 if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
6122 (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
6123 pkt_type = 0;
6124 else
6125 pkt_type = 1;
6126 #else
6127 pkt_type = 0;
6128 #endif /* CONFIG_ARP_KEEP_ALIVE */
6129 if(!no_wake)
6130 rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
6131 }
6132 #ifdef CONFIG_PNO_SUPPORT
6133 rtw_hal_check_pno_enabled(padapter);
6134 #endif /* CONFIG_PNO_SUPPORT */
6135 } else {
6136 #if 0
6137 {
6138 u32 PageSize = 0;
6139 rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
6140 dump_TX_FIFO(padapter, 4, PageSize);
6141 }
6142 #endif
6143 }
6144 #ifdef CONFIG_CUSTOM_PULSE
6145 rtw_hal_set_gpio_custom_cmd(padapter, enable);
6146 #endif /* CONFIG_CUSTOM_PULSE */
6147 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
6148 RTW_PRINT("-%s()-\n", __func__);
6149 }
6150 #endif /* CONFIG_WOWLAN */
6151
6152 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)6153 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
6154 {
6155 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6156
6157 u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
6158 u8 gpionum = 0, gpio_dur = 0;
6159 u8 gpio_pulse = enable;
6160 u8 sdio_wakeup_enable = 1;
6161 u8 gpio_high_active = 0;
6162 u8 ret = _FAIL;
6163
6164 #ifdef CONFIG_GPIO_WAKEUP
6165 gpio_high_active = ppwrpriv->is_high_active;
6166 gpionum = ppwrpriv->wowlan_gpio_index;
6167 sdio_wakeup_enable = 0;
6168 #endif /*CONFIG_GPIO_WAKEUP*/
6169
6170 RTW_INFO("%s(): enable=%d\n", __func__, enable);
6171
6172 SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
6173 gpionum);
6174 SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
6175 gpio_pulse);
6176 SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
6177 gpio_high_active);
6178 SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
6179 enable);
6180 SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
6181 gpio_dur);
6182
6183 ret = rtw_hal_fill_h2c_cmd(adapter,
6184 H2C_AP_WOW_GPIO_CTRL,
6185 H2C_AP_WOW_GPIO_CTRL_LEN,
6186 u1H2CAPWoWlanCtrlParm);
6187
6188 return ret;
6189 }
6190
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)6191 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6192 {
6193 u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
6194 u8 ret = _FAIL;
6195
6196 RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
6197
6198 SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
6199
6200 ret = rtw_hal_fill_h2c_cmd(adapter,
6201 H2C_AP_OFFLOAD,
6202 H2C_AP_OFFLOAD_LEN,
6203 u1H2CAPOffloadCtrlParm);
6204
6205 return ret;
6206 }
6207
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)6208 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
6209 {
6210 u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
6211 u8 ret = _FAIL;
6212
6213 RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
6214
6215 SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
6216 #ifndef CONFIG_USB_HCI
6217 SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
6218 #endif /*CONFIG_USB_HCI*/
6219 SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
6220
6221 if (enable)
6222 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
6223 else
6224 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
6225
6226 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
6227 H2C_AP_PS_LEN, ap_ps_parm);
6228
6229 return ret;
6230 }
6231
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)6232 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
6233 PRSVDPAGE_LOC rsvdpageloc)
6234 {
6235 struct hal_ops *pHalFunc = &padapter->hal_func;
6236 u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
6237 u8 ret = _FAIL, header = 0;
6238
6239 if (pHalFunc->fill_h2c_cmd == NULL) {
6240 RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
6241 return;
6242 }
6243
6244 header = rtw_read8(padapter, REG_BCNQ_BDNY);
6245
6246 RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
6247 rsvdpageloc->LocApOffloadBCN,
6248 rsvdpageloc->LocProbeRsp,
6249 header);
6250
6251 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
6252 rsvdpageloc->LocApOffloadBCN + header);
6253
6254 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
6255 H2C_BCN_RSVDPAGE_LEN, rsvdparm);
6256
6257 if (ret == _FAIL)
6258 RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
6259
6260 rtw_msleep_os(10);
6261
6262 _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
6263
6264 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
6265 rsvdpageloc->LocProbeRsp + header);
6266
6267 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
6268 H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
6269
6270 if (ret == _FAIL)
6271 RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
6272
6273 rtw_msleep_os(10);
6274 }
6275
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)6276 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
6277 {
6278 rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
6279 rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
6280 rtw_hal_set_ap_ps_cmd(padapter, enable);
6281 }
6282
rtw_hal_ap_wow_enable(_adapter * padapter)6283 static void rtw_hal_ap_wow_enable(_adapter *padapter)
6284 {
6285 struct security_priv *psecuritypriv = &padapter->securitypriv;
6286 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6287 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6288 struct sta_info *psta = NULL;
6289 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6290 #ifdef DBG_CHECK_FW_PS_STATE
6291 struct dvobj_priv *psdpriv = padapter->dvobj;
6292 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6293 #endif /*DBG_CHECK_FW_PS_STATE*/
6294 int res;
6295 u16 media_status_rpt;
6296 #ifdef CONFIG_GPIO_WAKEUP
6297 u8 val8 = 0;
6298 #endif
6299
6300 RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
6301 #ifdef DBG_CHECK_FW_PS_STATE
6302 if (rtw_fw_ps_state(padapter) == _FAIL) {
6303 pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
6304 RTW_PRINT("wowlan enable no leave 32k\n");
6305 }
6306 #endif /*DBG_CHECK_FW_PS_STATE*/
6307
6308 /* 1. Download WOWLAN FW*/
6309 rtw_hal_fw_dl(padapter, _TRUE);
6310
6311 media_status_rpt = RT_MEDIA_CONNECT;
6312 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6313 (u8 *)&media_status_rpt);
6314
6315 issue_beacon(padapter, 0);
6316
6317 rtw_msleep_os(2);
6318 #if defined(CONFIG_RTL8188E)
6319 if (IS_HARDWARE_TYPE_8188E(padapter))
6320 rtw_hal_disable_tx_report(padapter);
6321 #endif
6322 /* RX DMA stop */
6323 res = rtw_hal_pause_rx_dma(padapter);
6324 if (res == _FAIL)
6325 RTW_PRINT("[WARNING] pause RX DMA fail\n");
6326
6327 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6328 /* Enable CPWM2 only. */
6329 res = rtw_hal_enable_cpwm2(padapter);
6330 if (res == _FAIL)
6331 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6332 #endif
6333
6334 #ifdef CONFIG_GPIO_WAKEUP
6335 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6336 rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6337 rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6338 #else
6339 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6340 if (pwrctrlpriv->is_high_active == 0)
6341 rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6342 else
6343 rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index,
6344 GPIO_OUTPUT_LOW);
6345 #else
6346 val8 = (pwrpriv->is_high_active == 0) ? 1 : 0;
6347 rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8);
6348 rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6349 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow suspend and %s_ACTIVE.\n",
6350 __func__, pwrpriv->wowlan_gpio_index,
6351 pwrpriv->wowlan_gpio_output_state ? "HIGH" : "LOW",
6352 pwrpriv->is_high_active ? "HIGI" : "LOW");
6353 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
6354 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6355 #endif /* CONFIG_GPIO_WAKEUP */
6356
6357 /* 5. Set Enable WOWLAN H2C command. */
6358 RTW_PRINT("Set Enable AP WOWLan cmd\n");
6359 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
6360
6361 rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
6362 #ifdef CONFIG_USB_HCI
6363 rtw_mi_intf_stop(padapter);
6364 #endif
6365 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
6366 /* Invoid SE0 reset signal during suspending*/
6367 rtw_write8(padapter, REG_RSV_CTRL, 0x20);
6368 if (IS_8188F(pHalData->version_id) == FALSE
6369 && IS_8188GTV(pHalData->version_id) == FALSE)
6370 rtw_write8(padapter, REG_RSV_CTRL, 0x60);
6371 #endif
6372 }
6373
rtw_hal_ap_wow_disable(_adapter * padapter)6374 static void rtw_hal_ap_wow_disable(_adapter *padapter)
6375 {
6376 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6377 #ifdef DBG_CHECK_FW_PS_STATE
6378 struct dvobj_priv *psdpriv = padapter->dvobj;
6379 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6380 #endif /*DBG_CHECK_FW_PS_STATE*/
6381 u16 media_status_rpt;
6382
6383 RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
6384 /* 1. Read wakeup reason*/
6385 pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
6386
6387 RTW_PRINT("wakeup_reason: 0x%02x\n",
6388 pwrctl->wowlan_wake_reason);
6389
6390 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
6391
6392 rtw_msleep_os(2);
6393 #ifdef DBG_CHECK_FW_PS_STATE
6394 if (rtw_fw_ps_state(padapter) == _FAIL) {
6395 pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
6396 RTW_PRINT("wowlan enable no leave 32k\n");
6397 }
6398 #endif /*DBG_CHECK_FW_PS_STATE*/
6399
6400 #if defined(CONFIG_RTL8188E)
6401 if (IS_HARDWARE_TYPE_8188E(padapter))
6402 rtw_hal_enable_tx_report(padapter);
6403 #endif
6404
6405 rtw_hal_force_enable_rxdma(padapter);
6406
6407 rtw_hal_fw_dl(padapter, _FALSE);
6408
6409 #ifdef CONFIG_GPIO_WAKEUP
6410 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6411 rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6412 #else
6413 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6414 if (pwrctl->is_high_active == 0)
6415 rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6416 else
6417 rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index
6418 , GPIO_OUTPUT_LOW);
6419 #else
6420 rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index,
6421 pwrctl->wowlan_gpio_output_state);
6422 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow resume and %s_ACTIVE.\n",
6423 __func__, pwrctl->wowlan_gpio_index,
6424 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
6425 pwrctl->is_high_active ? "HIGI" : "LOW");
6426 #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
6427 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6428 #endif /* CONFIG_GPIO_WAKEUP */
6429 media_status_rpt = RT_MEDIA_CONNECT;
6430
6431 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6432 (u8 *)&media_status_rpt);
6433
6434 issue_beacon(padapter, 0);
6435 }
6436 #endif /*CONFIG_AP_WOWLAN*/
6437
6438 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)6439 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
6440 {
6441 u8 *ssid_ie;
6442 sint ssid_len_ori;
6443 int len_diff = 0;
6444
6445 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
6446
6447 /* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
6448
6449 if (ssid_ie && ssid_len_ori > 0) {
6450 switch (hidden_ssid_mode) {
6451 case 1: {
6452 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
6453 u32 remain_len = 0;
6454
6455 remain_len = ies_len - (next_ie - ies);
6456
6457 ssid_ie[1] = 0;
6458 _rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
6459 len_diff -= ssid_len_ori;
6460
6461 break;
6462 }
6463 case 2:
6464 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
6465 break;
6466 default:
6467 break;
6468 }
6469 }
6470
6471 return len_diff;
6472 }
6473
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)6474 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
6475 {
6476 /* struct xmit_frame *pmgntframe; */
6477 /* struct pkt_attrib *pattrib; */
6478 /* unsigned char *pframe; */
6479 struct rtw_ieee80211_hdr *pwlanhdr;
6480 unsigned short *fctrl;
6481 unsigned int rate_len;
6482 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6483 u32 pktlen;
6484 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6485 /* _irqL irqL;
6486 * struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6487 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6488 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6489 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6490 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6491 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
6492 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6493 #ifdef CONFIG_P2P
6494 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6495 #endif /* CONFIG_P2P */
6496
6497 /* for debug */
6498 u8 *dbgbuf = pframe;
6499 u8 dbgbufLen = 0, index = 0;
6500
6501 RTW_INFO("%s\n", __FUNCTION__);
6502 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6503 /* _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6504 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6505
6506 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6507
6508
6509 fctrl = &(pwlanhdr->frame_ctl);
6510 *(fctrl) = 0;
6511
6512 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6513 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6514 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6515
6516 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6517 /* pmlmeext->mgnt_seq++; */
6518 set_frame_sub_type(pframe, WIFI_BEACON);
6519
6520 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6521 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6522
6523 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6524 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6525 #ifdef CONFIG_P2P
6526 /* for P2P : Primary Device Type & Device Name */
6527 u32 wpsielen = 0, insert_len = 0;
6528 u8 *wpsie = NULL;
6529 wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
6530
6531 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
6532 uint wps_offset, remainder_ielen;
6533 u8 *premainder_ie, *pframe_wscie;
6534
6535 wps_offset = (uint)(wpsie - cur_network->IEs);
6536
6537 premainder_ie = wpsie + wpsielen;
6538
6539 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6540
6541 #ifdef CONFIG_IOCTL_CFG80211
6542 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6543 if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
6544 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
6545 pframe += wps_offset;
6546 pktlen += wps_offset;
6547
6548 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6549 pframe += pmlmepriv->wps_beacon_ie_len;
6550 pktlen += pmlmepriv->wps_beacon_ie_len;
6551
6552 /* copy remainder_ie to pframe */
6553 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6554 pframe += remainder_ielen;
6555 pktlen += remainder_ielen;
6556 } else {
6557 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6558 pframe += cur_network->IELength;
6559 pktlen += cur_network->IELength;
6560 }
6561 } else
6562 #endif /* CONFIG_IOCTL_CFG80211 */
6563 {
6564 pframe_wscie = pframe + wps_offset;
6565 _rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
6566 pframe += (wps_offset + wpsielen);
6567 pktlen += (wps_offset + wpsielen);
6568
6569 /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6570 /* Primary Device Type */
6571 /* Type: */
6572 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6573 insert_len += 2;
6574
6575 /* Length: */
6576 *(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
6577 insert_len += 2;
6578
6579 /* Value: */
6580 /* Category ID */
6581 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6582 insert_len += 2;
6583
6584 /* OUI */
6585 *(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
6586 insert_len += 4;
6587
6588 /* Sub Category ID */
6589 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6590 insert_len += 2;
6591
6592
6593 /* Device Name */
6594 /* Type: */
6595 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6596 insert_len += 2;
6597
6598 /* Length: */
6599 *(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
6600 insert_len += 2;
6601
6602 /* Value: */
6603 _rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
6604 insert_len += pwdinfo->device_name_len;
6605
6606
6607 /* update wsc ie length */
6608 *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
6609
6610 /* pframe move to end */
6611 pframe += insert_len;
6612 pktlen += insert_len;
6613
6614 /* copy remainder_ie to pframe */
6615 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6616 pframe += remainder_ielen;
6617 pktlen += remainder_ielen;
6618 }
6619 } else
6620 #endif /* CONFIG_P2P */
6621 {
6622 int len_diff;
6623 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6624 len_diff = update_hidden_ssid(
6625 pframe + _BEACON_IE_OFFSET_
6626 , cur_network->IELength - _BEACON_IE_OFFSET_
6627 , pmlmeinfo->hidden_ssid_mode
6628 );
6629 pframe += (cur_network->IELength + len_diff);
6630 pktlen += (cur_network->IELength + len_diff);
6631 }
6632 #if 0
6633 {
6634 u8 *wps_ie;
6635 uint wps_ielen;
6636 u8 sr = 0;
6637 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
6638 pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
6639 if (wps_ie && wps_ielen > 0)
6640 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6641 if (sr != 0)
6642 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6643 else
6644 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6645 }
6646 #endif
6647 #ifdef CONFIG_P2P
6648 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6649 u32 len;
6650 #ifdef CONFIG_IOCTL_CFG80211
6651 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6652 len = pmlmepriv->p2p_beacon_ie_len;
6653 if (pmlmepriv->p2p_beacon_ie && len > 0)
6654 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6655 } else
6656 #endif /* CONFIG_IOCTL_CFG80211 */
6657 {
6658 len = build_beacon_p2p_ie(pwdinfo, pframe);
6659 }
6660
6661 pframe += len;
6662 pktlen += len;
6663
6664 #ifdef CONFIG_WFD
6665 len = rtw_append_beacon_wfd_ie(padapter, pframe);
6666 pframe += len;
6667 pktlen += len;
6668 #endif
6669
6670 }
6671 #endif /* CONFIG_P2P */
6672
6673 goto _issue_bcn;
6674
6675 }
6676
6677 /* below for ad-hoc mode */
6678
6679 /* timestamp will be inserted by hardware */
6680 pframe += 8;
6681 pktlen += 8;
6682
6683 /* beacon interval: 2 bytes */
6684
6685 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6686
6687 pframe += 2;
6688 pktlen += 2;
6689
6690 /* capability info: 2 bytes */
6691
6692 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6693
6694 pframe += 2;
6695 pktlen += 2;
6696
6697 /* SSID */
6698 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6699
6700 /* supported rates... */
6701 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6702 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6703
6704 /* DS parameter set */
6705 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6706
6707 /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6708 {
6709 u8 erpinfo = 0;
6710 u32 ATIMWindow;
6711 /* IBSS Parameter Set... */
6712 /* ATIMWindow = cur->Configuration.ATIMWindow; */
6713 ATIMWindow = 0;
6714 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6715
6716 /* ERP IE */
6717 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
6718 }
6719
6720
6721 /* EXTERNDED SUPPORTED RATE */
6722 if (rate_len > 8)
6723 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6724
6725
6726 /* todo:HT for adhoc */
6727
6728 _issue_bcn:
6729
6730 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6731 /* pmlmepriv->update_bcn = _FALSE;
6732 *
6733 * _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6734 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6735
6736 *pLength = pktlen;
6737 #if 0
6738 /* printf dbg msg */
6739 dbgbufLen = pktlen;
6740 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6741
6742 for (index = 0; index < dbgbufLen; index++)
6743 printk("%x ", *(dbgbuf + index));
6744
6745 printk("\n");
6746 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6747
6748 #endif
6749 }
6750
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6751 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6752 {
6753 /* struct xmit_frame *pmgntframe; */
6754 /* struct pkt_attrib *pattrib; */
6755 /* unsigned char *pframe; */
6756 struct rtw_ieee80211_hdr *pwlanhdr;
6757 unsigned short *fctrl;
6758 unsigned char *mac;
6759 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6760 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6761 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6762 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6763 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
6764 u16 beacon_interval = 100;
6765 u16 capInfo = 0;
6766 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6767 u8 wpsie[255] = { 0x00 };
6768 u32 wpsielen = 0, p2pielen = 0;
6769 u32 pktlen;
6770 #ifdef CONFIG_WFD
6771 u32 wfdielen = 0;
6772 #endif
6773
6774 /* for debug */
6775 u8 *dbgbuf = pframe;
6776 u8 dbgbufLen = 0, index = 0;
6777
6778 RTW_INFO("%s\n", __FUNCTION__);
6779 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6780
6781 mac = adapter_mac_addr(padapter);
6782
6783 fctrl = &(pwlanhdr->frame_ctl);
6784 *(fctrl) = 0;
6785
6786 /* DA filled by FW */
6787 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6788 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6789
6790 /* Use the device address for BSSID field. */
6791 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6792
6793 SetSeqNum(pwlanhdr, 0);
6794 set_frame_sub_type(fctrl, WIFI_PROBERSP);
6795
6796 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6797 pframe += pktlen;
6798
6799
6800 /* timestamp will be inserted by hardware */
6801 pframe += 8;
6802 pktlen += 8;
6803
6804 /* beacon interval: 2 bytes */
6805 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6806 pframe += 2;
6807 pktlen += 2;
6808
6809 /* capability info: 2 bytes */
6810 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6811 capInfo |= cap_ShortPremble;
6812 capInfo |= cap_ShortSlot;
6813
6814 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6815 pframe += 2;
6816 pktlen += 2;
6817
6818
6819 /* SSID */
6820 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
6821
6822 /* supported rates... */
6823 /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6824 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
6825
6826 /* DS parameter set */
6827 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
6828
6829 #ifdef CONFIG_IOCTL_CFG80211
6830 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6831 if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6832 /* WPS IE */
6833 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6834 pktlen += pmlmepriv->wps_probe_resp_ie_len;
6835 pframe += pmlmepriv->wps_probe_resp_ie_len;
6836
6837 /* P2P IE */
6838 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6839 pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6840 pframe += pmlmepriv->p2p_probe_resp_ie_len;
6841 }
6842 } else
6843 #endif /* CONFIG_IOCTL_CFG80211 */
6844 {
6845
6846 /* Todo: WPS IE */
6847 /* Noted by Albert 20100907 */
6848 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6849
6850 wpsielen = 0;
6851 /* WPS OUI */
6852 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6853 wpsielen += 4;
6854
6855 /* WPS version */
6856 /* Type: */
6857 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6858 wpsielen += 2;
6859
6860 /* Length: */
6861 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6862 wpsielen += 2;
6863
6864 /* Value: */
6865 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
6866
6867 /* WiFi Simple Config State */
6868 /* Type: */
6869 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6870 wpsielen += 2;
6871
6872 /* Length: */
6873 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6874 wpsielen += 2;
6875
6876 /* Value: */
6877 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
6878
6879 /* Response Type */
6880 /* Type: */
6881 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6882 wpsielen += 2;
6883
6884 /* Length: */
6885 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6886 wpsielen += 2;
6887
6888 /* Value: */
6889 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6890
6891 /* UUID-E */
6892 /* Type: */
6893 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6894 wpsielen += 2;
6895
6896 /* Length: */
6897 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6898 wpsielen += 2;
6899
6900 /* Value: */
6901 if (pwdinfo->external_uuid == 0) {
6902 _rtw_memset(wpsie + wpsielen, 0x0, 16);
6903 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6904 } else
6905 _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6906 wpsielen += 0x10;
6907
6908 /* Manufacturer */
6909 /* Type: */
6910 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6911 wpsielen += 2;
6912
6913 /* Length: */
6914 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6915 wpsielen += 2;
6916
6917 /* Value: */
6918 _rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6919 wpsielen += 7;
6920
6921 /* Model Name */
6922 /* Type: */
6923 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
6924 wpsielen += 2;
6925
6926 /* Length: */
6927 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
6928 wpsielen += 2;
6929
6930 /* Value: */
6931 _rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
6932 wpsielen += 6;
6933
6934 /* Model Number */
6935 /* Type: */
6936 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
6937 wpsielen += 2;
6938
6939 /* Length: */
6940 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6941 wpsielen += 2;
6942
6943 /* Value: */
6944 wpsie[wpsielen++] = 0x31; /* character 1 */
6945
6946 /* Serial Number */
6947 /* Type: */
6948 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
6949 wpsielen += 2;
6950
6951 /* Length: */
6952 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
6953 wpsielen += 2;
6954
6955 /* Value: */
6956 _rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
6957 wpsielen += ETH_ALEN;
6958
6959 /* Primary Device Type */
6960 /* Type: */
6961 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6962 wpsielen += 2;
6963
6964 /* Length: */
6965 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6966 wpsielen += 2;
6967
6968 /* Value: */
6969 /* Category ID */
6970 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6971 wpsielen += 2;
6972
6973 /* OUI */
6974 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6975 wpsielen += 4;
6976
6977 /* Sub Category ID */
6978 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6979 wpsielen += 2;
6980
6981 /* Device Name */
6982 /* Type: */
6983 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6984 wpsielen += 2;
6985
6986 /* Length: */
6987 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
6988 wpsielen += 2;
6989
6990 /* Value: */
6991 _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
6992 wpsielen += pwdinfo->device_name_len;
6993
6994 /* Config Method */
6995 /* Type: */
6996 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
6997 wpsielen += 2;
6998
6999 /* Length: */
7000 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7001 wpsielen += 2;
7002
7003 /* Value: */
7004 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7005 wpsielen += 2;
7006
7007
7008 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7009
7010
7011 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
7012 pframe += p2pielen;
7013 pktlen += p2pielen;
7014 }
7015
7016 #ifdef CONFIG_WFD
7017 wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
7018 pframe += wfdielen;
7019 pktlen += wfdielen;
7020 #endif
7021
7022 *pLength = pktlen;
7023
7024 #if 0
7025 /* printf dbg msg */
7026 dbgbufLen = pktlen;
7027 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7028
7029 for (index = 0; index < dbgbufLen; index++)
7030 printk("%x ", *(dbgbuf + index));
7031
7032 printk("\n");
7033 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7034 #endif
7035 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7036 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7037 {
7038 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7039 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7040 u8 action = P2P_PUB_ACTION_ACTION;
7041 u32 p2poui = cpu_to_be32(P2POUI);
7042 u8 oui_subtype = P2P_GO_NEGO_RESP;
7043 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
7044 u8 p2pielen = 0, i;
7045 uint wpsielen = 0;
7046 u16 wps_devicepassword_id = 0x0000;
7047 uint wps_devicepassword_id_len = 0;
7048 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
7049 u16 len_channellist_attr = 0;
7050 u32 pktlen;
7051 u8 dialogToken = 0;
7052
7053 /* struct xmit_frame *pmgntframe; */
7054 /* struct pkt_attrib *pattrib; */
7055 /* unsigned char *pframe; */
7056 struct rtw_ieee80211_hdr *pwlanhdr;
7057 unsigned short *fctrl;
7058 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7059 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7060 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7061 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7062 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
7063
7064 #ifdef CONFIG_WFD
7065 u32 wfdielen = 0;
7066 #endif
7067
7068 /* for debug */
7069 u8 *dbgbuf = pframe;
7070 u8 dbgbufLen = 0, index = 0;
7071
7072 RTW_INFO("%s\n", __FUNCTION__);
7073 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7074
7075 fctrl = &(pwlanhdr->frame_ctl);
7076 *(fctrl) = 0;
7077
7078 /* RA, filled by FW */
7079 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7080 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7081 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7082
7083 SetSeqNum(pwlanhdr, 0);
7084 set_frame_sub_type(pframe, WIFI_ACTION);
7085
7086 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7087 pframe += pktlen;
7088
7089 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7090 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7091 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7092 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7093
7094 /* dialog token, filled by FW */
7095 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7096
7097 _rtw_memset(wpsie, 0x00, 255);
7098 wpsielen = 0;
7099
7100 /* WPS Section */
7101 wpsielen = 0;
7102 /* WPS OUI */
7103 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
7104 wpsielen += 4;
7105
7106 /* WPS version */
7107 /* Type: */
7108 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7109 wpsielen += 2;
7110
7111 /* Length: */
7112 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7113 wpsielen += 2;
7114
7115 /* Value: */
7116 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7117
7118 /* Device Password ID */
7119 /* Type: */
7120 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
7121 wpsielen += 2;
7122
7123 /* Length: */
7124 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7125 wpsielen += 2;
7126
7127 /* Value: */
7128 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
7129 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
7130 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
7131 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
7132 else
7133 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
7134 wpsielen += 2;
7135
7136 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7137
7138
7139 /* P2P IE Section. */
7140
7141 /* P2P OUI */
7142 p2pielen = 0;
7143 p2pie[p2pielen++] = 0x50;
7144 p2pie[p2pielen++] = 0x6F;
7145 p2pie[p2pielen++] = 0x9A;
7146 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7147
7148 /* Commented by Albert 20100908 */
7149 /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
7150 /* 1. Status */
7151 /* 2. P2P Capability */
7152 /* 3. Group Owner Intent */
7153 /* 4. Configuration Timeout */
7154 /* 5. Operating Channel */
7155 /* 6. Intended P2P Interface Address */
7156 /* 7. Channel List */
7157 /* 8. Device Info */
7158 /* 9. Group ID ( Only GO ) */
7159
7160
7161 /* ToDo: */
7162
7163 /* P2P Status */
7164 /* Type: */
7165 p2pie[p2pielen++] = P2P_ATTR_STATUS;
7166
7167 /* Length: */
7168 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7169 p2pielen += 2;
7170
7171 /* Value, filled by FW */
7172 p2pie[p2pielen++] = 1;
7173
7174 /* P2P Capability */
7175 /* Type: */
7176 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
7177
7178 /* Length: */
7179 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7180 p2pielen += 2;
7181
7182 /* Value: */
7183 /* Device Capability Bitmap, 1 byte */
7184
7185 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
7186 /* Commented by Albert 2011/03/08 */
7187 /* According to the P2P specification */
7188 /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
7189 p2pie[p2pielen++] = 0;
7190 } else {
7191 /* Be group owner or meet the error case */
7192 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
7193 }
7194
7195 /* Group Capability Bitmap, 1 byte */
7196 if (pwdinfo->persistent_supported)
7197 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
7198 else
7199 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
7200
7201 /* Group Owner Intent */
7202 /* Type: */
7203 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
7204
7205 /* Length: */
7206 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7207 p2pielen += 2;
7208
7209 /* Value: */
7210 if (pwdinfo->peer_intent & 0x01) {
7211 /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
7212 p2pie[p2pielen++] = (pwdinfo->intent << 1);
7213 } else {
7214 /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
7215 p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
7216 }
7217
7218
7219 /* Configuration Timeout */
7220 /* Type: */
7221 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7222
7223 /* Length: */
7224 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7225 p2pielen += 2;
7226
7227 /* Value: */
7228 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7229 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7230
7231 /* Operating Channel */
7232 /* Type: */
7233 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7234
7235 /* Length: */
7236 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7237 p2pielen += 2;
7238
7239 /* Value: */
7240 /* Country String */
7241 p2pie[p2pielen++] = 'X';
7242 p2pie[p2pielen++] = 'X';
7243
7244 /* The third byte should be set to 0x04. */
7245 /* Described in the "Operating Channel Attribute" section. */
7246 p2pie[p2pielen++] = 0x04;
7247
7248 /* Operating Class */
7249 if (pwdinfo->operating_channel <= 14) {
7250 /* Operating Class */
7251 p2pie[p2pielen++] = 0x51;
7252 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
7253 /* Operating Class */
7254 p2pie[p2pielen++] = 0x73;
7255 } else {
7256 /* Operating Class */
7257 p2pie[p2pielen++] = 0x7c;
7258 }
7259
7260 /* Channel Number */
7261 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7262
7263 /* Intended P2P Interface Address */
7264 /* Type: */
7265 p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
7266
7267 /* Length: */
7268 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7269 p2pielen += 2;
7270
7271 /* Value: */
7272 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7273 p2pielen += ETH_ALEN;
7274
7275 /* Channel List */
7276 /* Type: */
7277 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7278
7279 /* Country String(3) */
7280 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7281 /* + number of channels in all classes */
7282 len_channellist_attr = 3
7283 + (1 + 1) * (u16)ch_list->reg_classes
7284 + get_reg_classes_full_count(ch_list);
7285
7286 #ifdef CONFIG_CONCURRENT_MODE
7287 if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7288 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7289 else
7290 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7291
7292 #else
7293
7294 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7295
7296 #endif
7297 p2pielen += 2;
7298
7299 /* Value: */
7300 /* Country String */
7301 p2pie[p2pielen++] = 'X';
7302 p2pie[p2pielen++] = 'X';
7303
7304 /* The third byte should be set to 0x04. */
7305 /* Described in the "Operating Channel Attribute" section. */
7306 p2pie[p2pielen++] = 0x04;
7307
7308 /* Channel Entry List */
7309
7310 #ifdef CONFIG_CONCURRENT_MODE
7311 if (rtw_mi_check_status(padapter, MI_LINKED)) {
7312 u8 union_ch = rtw_mi_get_union_chan(padapter);
7313
7314 /* Operating Class */
7315 if (union_ch > 14) {
7316 if (union_ch >= 149)
7317 p2pie[p2pielen++] = 0x7c;
7318 else
7319 p2pie[p2pielen++] = 0x73;
7320 } else
7321 p2pie[p2pielen++] = 0x51;
7322
7323
7324 /* Number of Channels */
7325 /* Just support 1 channel and this channel is AP's channel */
7326 p2pie[p2pielen++] = 1;
7327
7328 /* Channel List */
7329 p2pie[p2pielen++] = union_ch;
7330 } else
7331 #endif /* CONFIG_CONCURRENT_MODE */
7332 {
7333 int i, j;
7334 for (j = 0; j < ch_list->reg_classes; j++) {
7335 /* Operating Class */
7336 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7337
7338 /* Number of Channels */
7339 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7340
7341 /* Channel List */
7342 for (i = 0; i < ch_list->reg_class[j].channels; i++)
7343 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7344 }
7345 }
7346
7347 /* Device Info */
7348 /* Type: */
7349 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
7350
7351 /* Length: */
7352 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
7353 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7354 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
7355 p2pielen += 2;
7356
7357 /* Value: */
7358 /* P2P Device Address */
7359 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7360 p2pielen += ETH_ALEN;
7361
7362 /* Config Method */
7363 /* This field should be big endian. Noted by P2P specification. */
7364
7365 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7366
7367 p2pielen += 2;
7368
7369 /* Primary Device Type */
7370 /* Category ID */
7371 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7372 p2pielen += 2;
7373
7374 /* OUI */
7375 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
7376 p2pielen += 4;
7377
7378 /* Sub Category ID */
7379 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7380 p2pielen += 2;
7381
7382 /* Number of Secondary Device Types */
7383 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
7384
7385 /* Device Name */
7386 /* Type: */
7387 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7388 p2pielen += 2;
7389
7390 /* Length: */
7391 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
7392 p2pielen += 2;
7393
7394 /* Value: */
7395 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
7396 p2pielen += pwdinfo->device_name_len;
7397
7398 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7399 /* Group ID Attribute */
7400 /* Type: */
7401 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
7402
7403 /* Length: */
7404 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
7405 p2pielen += 2;
7406
7407 /* Value: */
7408 /* p2P Device Address */
7409 _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
7410 p2pielen += ETH_ALEN;
7411
7412 /* SSID */
7413 _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
7414 p2pielen += pwdinfo->nego_ssidlen;
7415
7416 }
7417
7418 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7419
7420 #ifdef CONFIG_WFD
7421 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
7422 pframe += wfdielen;
7423 pktlen += wfdielen;
7424 #endif
7425
7426 *pLength = pktlen;
7427 #if 0
7428 /* printf dbg msg */
7429 dbgbufLen = pktlen;
7430 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7431
7432 for (index = 0; index < dbgbufLen; index++)
7433 printk("%x ", *(dbgbuf + index));
7434
7435 printk("\n");
7436 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7437 #endif
7438 }
7439
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7440 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7441 {
7442 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7443 u8 action = P2P_PUB_ACTION_ACTION;
7444 u32 p2poui = cpu_to_be32(P2POUI);
7445 u8 oui_subtype = P2P_INVIT_RESP;
7446 u8 p2pie[255] = { 0x00 };
7447 u8 p2pielen = 0, i;
7448 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
7449 u16 len_channellist_attr = 0;
7450 u32 pktlen;
7451 u8 dialogToken = 0;
7452 #ifdef CONFIG_WFD
7453 u32 wfdielen = 0;
7454 #endif
7455
7456 /* struct xmit_frame *pmgntframe; */
7457 /* struct pkt_attrib *pattrib; */
7458 /* unsigned char *pframe; */
7459 struct rtw_ieee80211_hdr *pwlanhdr;
7460 unsigned short *fctrl;
7461 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7462 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7463 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7464 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7465
7466 /* for debug */
7467 u8 *dbgbuf = pframe;
7468 u8 dbgbufLen = 0, index = 0;
7469
7470
7471 RTW_INFO("%s\n", __FUNCTION__);
7472 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7473
7474 fctrl = &(pwlanhdr->frame_ctl);
7475 *(fctrl) = 0;
7476
7477 /* RA fill by FW */
7478 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7479 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7480
7481 /* BSSID fill by FW */
7482 _rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
7483
7484 SetSeqNum(pwlanhdr, 0);
7485 set_frame_sub_type(pframe, WIFI_ACTION);
7486
7487 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7488 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7489
7490 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7491 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7492 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7493 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7494
7495 /* dialog token, filled by FW */
7496 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7497
7498 /* P2P IE Section. */
7499
7500 /* P2P OUI */
7501 p2pielen = 0;
7502 p2pie[p2pielen++] = 0x50;
7503 p2pie[p2pielen++] = 0x6F;
7504 p2pie[p2pielen++] = 0x9A;
7505 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7506
7507 /* Commented by Albert 20101005 */
7508 /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
7509 /* 1. Status */
7510 /* 2. Configuration Timeout */
7511 /* 3. Operating Channel ( Only GO ) */
7512 /* 4. P2P Group BSSID ( Only GO ) */
7513 /* 5. Channel List */
7514
7515 /* P2P Status */
7516 /* Type: */
7517 p2pie[p2pielen++] = P2P_ATTR_STATUS;
7518
7519 /* Length: */
7520 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7521 p2pielen += 2;
7522
7523 /* Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
7524 p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7525
7526 /* Configuration Timeout */
7527 /* Type: */
7528 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7529
7530 /* Length: */
7531 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7532 p2pielen += 2;
7533
7534 /* Value: */
7535 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7536 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7537
7538 /* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
7539 #if 0
7540 if (status_code == P2P_STATUS_SUCCESS) {
7541 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7542
7543 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7544 /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
7545 /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
7546 /* First one is operating channel attribute. */
7547 /* Second one is P2P Group BSSID attribute. */
7548
7549 /* Operating Channel */
7550 /* Type: */
7551 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7552
7553 /* Length: */
7554 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7555 p2pielen += 2;
7556
7557 /* Value: */
7558 /* Country String */
7559 p2pie[p2pielen++] = 'X';
7560 p2pie[p2pielen++] = 'X';
7561
7562 /* The third byte should be set to 0x04. */
7563 /* Described in the "Operating Channel Attribute" section. */
7564 p2pie[p2pielen++] = 0x04;
7565
7566 /* Operating Class */
7567 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
7568
7569 /* Channel Number */
7570 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7571
7572
7573 /* P2P Group BSSID */
7574 /* Type: */
7575 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
7576
7577 /* Length: */
7578 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7579 p2pielen += 2;
7580
7581 /* Value: */
7582 /* P2P Device Address for GO */
7583 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7584 p2pielen += ETH_ALEN;
7585
7586 }
7587
7588 /* Channel List */
7589 /* Type: */
7590 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7591
7592 /* Length: */
7593 /* Country String(3) */
7594 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7595 /* + number of channels in all classes */
7596 len_channellist_attr = 3
7597 + (1 + 1) * (u16)ch_list->reg_classes
7598 + get_reg_classes_full_count(ch_list);
7599
7600 #ifdef CONFIG_CONCURRENT_MODE
7601 if (rtw_mi_check_status(padapter, MI_LINKED))
7602 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7603 else
7604 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7605
7606 #else
7607
7608 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7609
7610 #endif
7611 p2pielen += 2;
7612
7613 /* Value: */
7614 /* Country String */
7615 p2pie[p2pielen++] = 'X';
7616 p2pie[p2pielen++] = 'X';
7617
7618 /* The third byte should be set to 0x04. */
7619 /* Described in the "Operating Channel Attribute" section. */
7620 p2pie[p2pielen++] = 0x04;
7621
7622 /* Channel Entry List */
7623 #ifdef CONFIG_CONCURRENT_MODE
7624 if (rtw_mi_check_status(padapter, MI_LINKED)) {
7625 u8 union_ch = rtw_mi_get_union_chan(padapter);
7626
7627 /* Operating Class */
7628 if (union_ch > 14) {
7629 if (union_ch >= 149)
7630 p2pie[p2pielen++] = 0x7c;
7631 else
7632 p2pie[p2pielen++] = 0x73;
7633
7634 } else
7635 p2pie[p2pielen++] = 0x51;
7636
7637
7638 /* Number of Channels */
7639 /* Just support 1 channel and this channel is AP's channel */
7640 p2pie[p2pielen++] = 1;
7641
7642 /* Channel List */
7643 p2pie[p2pielen++] = union_ch;
7644 } else
7645 #endif /* CONFIG_CONCURRENT_MODE */
7646 {
7647 int i, j;
7648 for (j = 0; j < ch_list->reg_classes; j++) {
7649 /* Operating Class */
7650 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7651
7652 /* Number of Channels */
7653 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7654
7655 /* Channel List */
7656 for (i = 0; i < ch_list->reg_class[j].channels; i++)
7657 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7658 }
7659 }
7660 }
7661 #endif
7662
7663 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7664
7665 #ifdef CONFIG_WFD
7666 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
7667 pframe += wfdielen;
7668 pktlen += wfdielen;
7669 #endif
7670
7671 *pLength = pktlen;
7672
7673 #if 0
7674 /* printf dbg msg */
7675 dbgbufLen = pktlen;
7676 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7677
7678 for (index = 0; index < dbgbufLen; index++)
7679 printk("%x ", *(dbgbuf + index));
7680
7681 printk("\n");
7682 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7683 #endif
7684 }
7685
7686
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7687 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7688 {
7689 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7690 u8 action = P2P_PUB_ACTION_ACTION;
7691 u8 dialogToken = 0;
7692 u32 p2poui = cpu_to_be32(P2POUI);
7693 u8 oui_subtype = P2P_PROVISION_DISC_RESP;
7694 u8 wpsie[100] = { 0x00 };
7695 u8 wpsielen = 0;
7696 u32 pktlen;
7697 #ifdef CONFIG_WFD
7698 u32 wfdielen = 0;
7699 #endif
7700
7701 /* struct xmit_frame *pmgntframe; */
7702 /* struct pkt_attrib *pattrib; */
7703 /* unsigned char *pframe; */
7704 struct rtw_ieee80211_hdr *pwlanhdr;
7705 unsigned short *fctrl;
7706 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7707 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7708 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7709 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7710
7711 /* for debug */
7712 u8 *dbgbuf = pframe;
7713 u8 dbgbufLen = 0, index = 0;
7714
7715 RTW_INFO("%s\n", __FUNCTION__);
7716
7717 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7718
7719 fctrl = &(pwlanhdr->frame_ctl);
7720 *(fctrl) = 0;
7721
7722 /* RA filled by FW */
7723 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7724 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7725 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7726
7727 SetSeqNum(pwlanhdr, 0);
7728 set_frame_sub_type(pframe, WIFI_ACTION);
7729
7730 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7731 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7732
7733 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7734 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7735 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7736 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7737 /* dialog token, filled by FW */
7738 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7739
7740 wpsielen = 0;
7741 /* WPS OUI */
7742 /* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
7743 RTW_PUT_BE32(wpsie, WPSOUI);
7744 wpsielen += 4;
7745
7746 #if 0
7747 /* WPS version */
7748 /* Type: */
7749 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7750 wpsielen += 2;
7751
7752 /* Length: */
7753 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7754 wpsielen += 2;
7755
7756 /* Value: */
7757 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7758 #endif
7759
7760 /* Config Method */
7761 /* Type: */
7762 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
7763 RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
7764 wpsielen += 2;
7765
7766 /* Length: */
7767 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
7768 RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
7769 wpsielen += 2;
7770
7771 /* Value: filled by FW, default value is PBC */
7772 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
7773 RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
7774 wpsielen += 2;
7775
7776 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7777
7778 #ifdef CONFIG_WFD
7779 wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
7780 pframe += wfdielen;
7781 pktlen += wfdielen;
7782 #endif
7783
7784 *pLength = pktlen;
7785
7786 /* printf dbg msg */
7787 #if 0
7788 dbgbufLen = pktlen;
7789 RTW_INFO("======> DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7790
7791 for (index = 0; index < dbgbufLen; index++)
7792 printk("%x ", *(dbgbuf + index));
7793
7794 printk("\n");
7795 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7796 #endif
7797 }
7798
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)7799 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
7800 {
7801 u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
7802 struct hal_ops *pHalFunc = &adapter->hal_func;
7803 u8 ret = _FAIL;
7804
7805 RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
7806 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
7807 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
7808 rsvdpageloc->LocPDRsp);
7809
7810 SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
7811 SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
7812 SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
7813 SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
7814 SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
7815
7816 /* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
7817 ret = rtw_hal_fill_h2c_cmd(adapter,
7818 H2C_P2P_OFFLOAD_RSVD_PAGE,
7819 H2C_P2PRSVDPAGE_LOC_LEN,
7820 u1H2CP2PRsvdPageParm);
7821
7822 return ret;
7823 }
7824
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)7825 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
7826 {
7827
7828 u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
7829 struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
7830 struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
7831 struct hal_ops *pHalFunc = &adapter->hal_func;
7832 u8 ret = _FAIL;
7833
7834 _rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
7835 RTW_INFO("%s\n", __func__);
7836 switch (pwdinfo->role) {
7837 case P2P_ROLE_DEVICE:
7838 RTW_INFO("P2P_ROLE_DEVICE\n");
7839 p2p_wowlan_offload->role = 0;
7840 break;
7841 case P2P_ROLE_CLIENT:
7842 RTW_INFO("P2P_ROLE_CLIENT\n");
7843 p2p_wowlan_offload->role = 1;
7844 break;
7845 case P2P_ROLE_GO:
7846 RTW_INFO("P2P_ROLE_GO\n");
7847 p2p_wowlan_offload->role = 2;
7848 break;
7849 default:
7850 RTW_INFO("P2P_ROLE_DISABLE\n");
7851 break;
7852 }
7853 p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
7854 p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
7855 offload_cmd = (u8 *)p2p_wowlan_offload;
7856 RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
7857
7858 ret = rtw_hal_fill_h2c_cmd(adapter,
7859 H2C_P2P_OFFLOAD,
7860 H2C_P2P_OFFLOAD_LEN,
7861 offload_cmd);
7862 return ret;
7863
7864 /* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
7865 }
7866 #endif /* CONFIG_P2P_WOWLAN */
7867
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)7868 void rtw_hal_construct_beacon(_adapter *padapter,
7869 u8 *pframe, u32 *pLength)
7870 {
7871 struct rtw_ieee80211_hdr *pwlanhdr;
7872 u16 *fctrl;
7873 u32 pktlen;
7874 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7875 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7876 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7877 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7878
7879
7880 /* RTW_INFO("%s\n", __FUNCTION__); */
7881
7882 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7883
7884 fctrl = &(pwlanhdr->frame_ctl);
7885 *(fctrl) = 0;
7886
7887 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7888 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7889 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7890
7891 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7892 /* pmlmeext->mgnt_seq++; */
7893 set_frame_sub_type(pframe, WIFI_BEACON);
7894
7895 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7896 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7897
7898 /* timestamp will be inserted by hardware */
7899 pframe += 8;
7900 pktlen += 8;
7901
7902 /* beacon interval: 2 bytes */
7903 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7904
7905 pframe += 2;
7906 pktlen += 2;
7907
7908 #if 0
7909 /* capability info: 2 bytes */
7910 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7911
7912 pframe += 2;
7913 pktlen += 2;
7914
7915 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7916 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7917 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
7918 _rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
7919
7920 goto _ConstructBeacon;
7921 }
7922
7923 /* below for ad-hoc mode */
7924
7925 /* SSID */
7926 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
7927
7928 /* supported rates... */
7929 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7930 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
7931
7932 /* DS parameter set */
7933 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
7934
7935 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
7936 u32 ATIMWindow;
7937 /* IBSS Parameter Set... */
7938 /* ATIMWindow = cur->Configuration.ATIMWindow; */
7939 ATIMWindow = 0;
7940 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
7941 }
7942
7943
7944 /* todo: ERP IE */
7945
7946
7947 /* EXTERNDED SUPPORTED RATE */
7948 if (rate_len > 8)
7949 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
7950
7951 /* todo:HT for adhoc */
7952
7953 _ConstructBeacon:
7954 #endif
7955
7956 if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
7957 RTW_ERR("beacon frame too large ,len(%d,%d)\n",
7958 (pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
7959 rtw_warn_on(1);
7960 return;
7961 }
7962
7963 *pLength = pktlen;
7964
7965 /* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
7966
7967 }
7968
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)7969 static void rtw_hal_construct_PSPoll(_adapter *padapter,
7970 u8 *pframe, u32 *pLength)
7971 {
7972 struct rtw_ieee80211_hdr *pwlanhdr;
7973 u16 *fctrl;
7974 u32 pktlen;
7975 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7976 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7977
7978 /* RTW_INFO("%s\n", __FUNCTION__); */
7979
7980 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7981
7982 /* Frame control. */
7983 fctrl = &(pwlanhdr->frame_ctl);
7984 *(fctrl) = 0;
7985 SetPwrMgt(fctrl);
7986 set_frame_sub_type(pframe, WIFI_PSPOLL);
7987
7988 /* AID. */
7989 set_duration(pframe, (pmlmeinfo->aid | 0xc000));
7990
7991 /* BSSID. */
7992 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7993
7994 /* TA. */
7995 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7996
7997 *pLength = 16;
7998 }
7999
8000
8001 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_construct_fw_dbg_msg_pkt(PADAPTER padapter,u8 * pframe,u32 * plength)8002 void rtw_hal_construct_fw_dbg_msg_pkt(
8003 PADAPTER padapter,
8004 u8 *pframe,
8005 u32 *plength)
8006 {
8007 struct rtw_ieee80211_hdr *pwlanhdr;
8008 u16 *fctrl;
8009 u32 pktlen;
8010 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8011 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8012 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8013 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8014 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8015
8016
8017 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8018
8019 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8020
8021 fctrl = &pwlanhdr->frame_ctl;
8022 *(fctrl) = 0;
8023
8024 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8025 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8026 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8027
8028 SetSeqNum(pwlanhdr, 0);
8029
8030 set_frame_sub_type(pframe, WIFI_DATA);
8031
8032 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8033
8034 *plength = pktlen;
8035 }
8036 #endif /*DBG_FW_DEBUG_MSG_PKT*/
8037
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)8038 void rtw_hal_construct_NullFunctionData(
8039 PADAPTER padapter,
8040 u8 *pframe,
8041 u32 *pLength,
8042 u8 bQoS,
8043 u8 AC,
8044 u8 bEosp,
8045 u8 bForcePowerSave)
8046 {
8047 struct rtw_ieee80211_hdr *pwlanhdr;
8048 u16 *fctrl;
8049 u32 pktlen;
8050 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8051 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8052 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8053 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8054 u8 *sta_addr = NULL;
8055 u8 bssid[ETH_ALEN] = {0};
8056
8057 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8058
8059 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8060
8061 fctrl = &pwlanhdr->frame_ctl;
8062 *(fctrl) = 0;
8063 if (bForcePowerSave)
8064 SetPwrMgt(fctrl);
8065
8066 sta_addr = get_my_bssid(&pmlmeinfo->network);
8067 if (NULL == sta_addr) {
8068 _rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
8069 sta_addr = bssid;
8070 }
8071
8072 switch (cur_network->network.InfrastructureMode) {
8073 case Ndis802_11Infrastructure:
8074 SetToDs(fctrl);
8075 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8076 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8077 _rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);
8078 break;
8079 case Ndis802_11APMode:
8080 SetFrDs(fctrl);
8081 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8082 _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8083 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8084 break;
8085 case Ndis802_11IBSS:
8086 default:
8087 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8088 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8089 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8090 break;
8091 }
8092
8093 SetSeqNum(pwlanhdr, 0);
8094 set_duration(pwlanhdr, 0);
8095
8096 if (bQoS == _TRUE) {
8097 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
8098
8099 set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
8100
8101 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
8102 SetPriority(&pwlanqoshdr->qc, AC);
8103 SetEOSP(&pwlanqoshdr->qc, bEosp);
8104
8105 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8106 } else {
8107 set_frame_sub_type(pframe, WIFI_DATA_NULL);
8108
8109 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8110 }
8111
8112 *pLength = pktlen;
8113 }
8114
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,BOOLEAN bHideSSID)8115 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
8116 BOOLEAN bHideSSID)
8117 {
8118 struct rtw_ieee80211_hdr *pwlanhdr;
8119 u16 *fctrl;
8120 u8 *mac, *bssid, *sta_addr;
8121 u32 pktlen;
8122 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8123 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8124 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
8125
8126 /*RTW_INFO("%s\n", __FUNCTION__);*/
8127
8128 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8129
8130 mac = adapter_mac_addr(padapter);
8131 bssid = cur_network->MacAddress;
8132 sta_addr = get_my_bssid(&pmlmeinfo->network);
8133
8134 fctrl = &(pwlanhdr->frame_ctl);
8135 *(fctrl) = 0;
8136 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8137 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8138 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8139
8140 SetSeqNum(pwlanhdr, 0);
8141 set_frame_sub_type(fctrl, WIFI_PROBERSP);
8142
8143 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8144 pframe += pktlen;
8145
8146 if (cur_network->IELength > MAX_IE_SZ)
8147 return;
8148
8149 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8150 pframe += cur_network->IELength;
8151 pktlen += cur_network->IELength;
8152
8153 *pLength = pktlen;
8154 }
8155
8156 #ifdef CONFIG_WOWLAN
rtw_hal_append_tkip_mic(PADAPTER padapter,u8 * pframe,u32 offset)8157 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
8158 u8 *pframe, u32 offset)
8159 {
8160 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8161 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8162 struct rtw_ieee80211_hdr *pwlanhdr;
8163 struct mic_data micdata;
8164 struct sta_info *psta = NULL;
8165 int res = 0;
8166
8167 u8 *payload = (u8 *)(pframe + offset);
8168
8169 u8 mic[8];
8170 u8 priority[4] = {0x0};
8171 u8 null_key[16] = {0x0};
8172
8173 RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
8174
8175 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8176
8177 psta = rtw_get_stainfo(&padapter->stapriv,
8178 get_my_bssid(&(pmlmeinfo->network)));
8179 if (psta != NULL) {
8180 res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
8181 null_key, 16);
8182 if (res == _TRUE)
8183 RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
8184 rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
8185 }
8186
8187 rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); /* DA */
8188
8189 rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
8190
8191 priority[0] = 0;
8192
8193 rtw_secmicappend(&micdata, &priority[0], 4);
8194
8195 rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
8196
8197 rtw_secgetmic(&micdata, &(mic[0]));
8198
8199 payload += 36;
8200
8201 _rtw_memcpy(payload, &(mic[0]), 8);
8202 }
8203 /*
8204 * Description:
8205 * Construct the ARP response packet to support ARP offload.
8206 * */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8207 static void rtw_hal_construct_ARPRsp(
8208 PADAPTER padapter,
8209 u8 *pframe,
8210 u32 *pLength,
8211 u8 *pIPAddress
8212 )
8213 {
8214 struct rtw_ieee80211_hdr *pwlanhdr;
8215 u16 *fctrl;
8216 u32 pktlen;
8217 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8218 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8219 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8220 struct security_priv *psecuritypriv = &padapter->securitypriv;
8221 static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
8222 u8 *pARPRspPkt = pframe;
8223 /* for TKIP Cal MIC */
8224 u8 *payload = pframe;
8225 u8 EncryptionHeadOverhead = 0, arp_offset = 0;
8226 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8227
8228 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8229
8230 fctrl = &pwlanhdr->frame_ctl;
8231 *(fctrl) = 0;
8232
8233 /* ------------------------------------------------------------------------- */
8234 /* MAC Header. */
8235 /* ------------------------------------------------------------------------- */
8236 SetFrameType(fctrl, WIFI_DATA);
8237 /* set_frame_sub_type(fctrl, 0); */
8238 SetToDs(fctrl);
8239 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8240 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8241 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8242
8243 SetSeqNum(pwlanhdr, 0);
8244 set_duration(pwlanhdr, 0);
8245 /* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
8246 /* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
8247 /* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
8248 /* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
8249 /* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
8250 /* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
8251
8252 /* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
8253 /* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
8254 #ifdef CONFIG_WAPI_SUPPORT
8255 *pLength = sMacHdrLng;
8256 #else
8257 *pLength = 24;
8258 #endif
8259 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8260 case _WEP40_:
8261 case _WEP104_:
8262 EncryptionHeadOverhead = 4;
8263 break;
8264 case _TKIP_:
8265 EncryptionHeadOverhead = 8;
8266 break;
8267 case _AES_:
8268 EncryptionHeadOverhead = 8;
8269 break;
8270 #ifdef CONFIG_WAPI_SUPPORT
8271 case _SMS4_:
8272 EncryptionHeadOverhead = 18;
8273 break;
8274 #endif
8275 default:
8276 EncryptionHeadOverhead = 0;
8277 }
8278
8279 if (EncryptionHeadOverhead > 0) {
8280 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8281 *pLength += EncryptionHeadOverhead;
8282 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8283 SetPrivacy(fctrl);
8284 }
8285
8286 /* ------------------------------------------------------------------------- */
8287 /* Frame Body. */
8288 /* ------------------------------------------------------------------------- */
8289 arp_offset = *pLength;
8290 pARPRspPkt = (u8 *)(pframe + arp_offset);
8291 payload = pARPRspPkt; /* Get Payload pointer */
8292 /* LLC header */
8293 _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
8294 *pLength += 8;
8295
8296 /* ARP element */
8297 pARPRspPkt += 8;
8298 SET_ARP_HTYPE(pARPRspPkt, 1);
8299 SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP); /* IP protocol */
8300 SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);
8301 SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);
8302 SET_ARP_OPER(pARPRspPkt, 2); /* ARP response */
8303 SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
8304 SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
8305 #ifdef CONFIG_ARP_KEEP_ALIVE
8306 if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
8307 SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
8308 SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
8309 } else
8310 #endif
8311 {
8312 SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,
8313 get_my_bssid(&(pmlmeinfo->network)));
8314 SET_ARP_TARGET_IP_ADDR(pARPRspPkt,
8315 pIPAddress);
8316 RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
8317 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
8318 RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
8319 IP_ARG(pIPAddress));
8320 }
8321
8322 *pLength += 28;
8323
8324 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8325 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8326 IS_HARDWARE_TYPE_8812(padapter)) {
8327 rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
8328 }
8329 *pLength += 8;
8330 }
8331 }
8332
8333 #ifdef CONFIG_IPV6
8334 /*
8335 * Description: Neighbor Discovery Offload.
8336 */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)8337 static void rtw_hal_construct_na_message(_adapter *padapter,
8338 u8 *pframe, u32 *pLength)
8339 {
8340 struct rtw_ieee80211_hdr *pwlanhdr = NULL;
8341 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8342 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8343 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8344 struct security_priv *psecuritypriv = &padapter->securitypriv;
8345
8346 u32 pktlen = 0;
8347 u16 *fctrl = NULL;
8348
8349 u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8350 u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
8351 u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
8352 u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
8353 u8 val8 = 0;
8354
8355 u8 *p_na_msg = pframe;
8356 /* for TKIP Cal MIC */
8357 u8 *payload = pframe;
8358 u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
8359 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8360
8361 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8362
8363 fctrl = &pwlanhdr->frame_ctl;
8364 *(fctrl) = 0;
8365
8366 /* ------------------------------------------------------------------------- */
8367 /* MAC Header. */
8368 /* ------------------------------------------------------------------------- */
8369 SetFrameType(fctrl, WIFI_DATA);
8370 SetToDs(fctrl);
8371 _rtw_memcpy(pwlanhdr->addr1,
8372 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8373 _rtw_memcpy(pwlanhdr->addr2,
8374 adapter_mac_addr(padapter), ETH_ALEN);
8375 _rtw_memcpy(pwlanhdr->addr3,
8376 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8377
8378 SetSeqNum(pwlanhdr, 0);
8379 set_duration(pwlanhdr, 0);
8380
8381 #ifdef CONFIG_WAPI_SUPPORT
8382 *pLength = sMacHdrLng;
8383 #else
8384 *pLength = 24;
8385 #endif
8386 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8387 case _WEP40_:
8388 case _WEP104_:
8389 EncryptionHeadOverhead = 4;
8390 break;
8391 case _TKIP_:
8392 EncryptionHeadOverhead = 8;
8393 break;
8394 case _AES_:
8395 EncryptionHeadOverhead = 8;
8396 break;
8397 #ifdef CONFIG_WAPI_SUPPORT
8398 case _SMS4_:
8399 EncryptionHeadOverhead = 18;
8400 break;
8401 #endif
8402 default:
8403 EncryptionHeadOverhead = 0;
8404 }
8405
8406 if (EncryptionHeadOverhead > 0) {
8407 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8408 *pLength += EncryptionHeadOverhead;
8409 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8410 SetPrivacy(fctrl);
8411 }
8412
8413 /* ------------------------------------------------------------------------- */
8414 /* Frame Body. */
8415 /* ------------------------------------------------------------------------- */
8416 na_msg_offset = *pLength;
8417 p_na_msg = (u8 *)(pframe + na_msg_offset);
8418 payload = p_na_msg; /* Get Payload pointer */
8419
8420 /* LLC header */
8421 val8 = sizeof(ns_hdr);
8422 _rtw_memcpy(p_na_msg, ns_hdr, val8);
8423 *pLength += val8;
8424 p_na_msg += val8;
8425
8426 /* IPv6 Header */
8427 /* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
8428 val8 = sizeof(ipv6_info);
8429 _rtw_memcpy(p_na_msg, ipv6_info, val8);
8430 *pLength += val8;
8431 p_na_msg += val8;
8432
8433 /* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
8434 val8 = sizeof(ipv6_contx);
8435 _rtw_memcpy(p_na_msg, ipv6_contx, val8);
8436 *pLength += val8;
8437 p_na_msg += val8;
8438
8439 /* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
8440 _rtw_memset(&(p_na_msg[*pLength]), 0, 32);
8441 *pLength += 32;
8442 p_na_msg += 32;
8443
8444 /* ICMPv6 */
8445 /* 1. Type : 0x88 (NA)
8446 * 2. Code : 0x00
8447 * 3. ChechSum : 0x00 0x00 (RSvd)
8448 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
8449 */
8450 val8 = sizeof(icmpv6_hdr);
8451 _rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
8452 *pLength += val8;
8453 p_na_msg += val8;
8454
8455 /* TA: 16 bytes*/
8456 _rtw_memset(&(p_na_msg[*pLength]), 0, 16);
8457 *pLength += 16;
8458 p_na_msg += 16;
8459
8460 /* ICMPv6 Target Link Layer Address */
8461 p_na_msg[0] = 0x02; /* type */
8462 p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
8463 *pLength += 2;
8464 p_na_msg += 2;
8465
8466 _rtw_memset(&(p_na_msg[*pLength]), 0, 6);
8467 *pLength += 6;
8468 p_na_msg += 6;
8469
8470 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8471 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8472 IS_HARDWARE_TYPE_8812(padapter)) {
8473 rtw_hal_append_tkip_mic(padapter, pframe,
8474 na_msg_offset);
8475 }
8476 *pLength += 8;
8477 }
8478 }
8479 /*
8480 * Description: Neighbor Discovery Protocol Information.
8481 */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)8482 static void rtw_hal_construct_ndp_info(_adapter *padapter,
8483 u8 *pframe, u32 *pLength)
8484 {
8485 struct mlme_ext_priv *pmlmeext = NULL;
8486 struct mlme_ext_info *pmlmeinfo = NULL;
8487 struct rtw_ndp_info ndp_info;
8488 u8 *pndp_info = pframe;
8489 u8 len = sizeof(struct rtw_ndp_info);
8490
8491 RTW_INFO("%s: len: %d\n", __func__, len);
8492
8493 pmlmeext = &padapter->mlmeextpriv;
8494 pmlmeinfo = &pmlmeext->mlmext_info;
8495
8496 _rtw_memset(pframe, 0, len);
8497 _rtw_memset(&ndp_info, 0, len);
8498
8499 ndp_info.enable = 1;
8500 ndp_info.check_remote_ip = 0;
8501 ndp_info.num_of_target_ip = 1;
8502
8503 _rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
8504 ETH_ALEN);
8505 _rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
8506 RTW_IPv6_ADDR_LEN);
8507
8508 _rtw_memcpy(pndp_info, &ndp_info, len);
8509 }
8510 #endif /* CONFIG_IPV6 */
8511
8512 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)8513 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
8514 u32 *pLength, pno_ssid_t *ssid)
8515 {
8516 struct rtw_ieee80211_hdr *pwlanhdr;
8517 u16 *fctrl;
8518 u32 pktlen;
8519 unsigned char *mac;
8520 unsigned char bssrate[NumRates];
8521 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8522 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8523 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8524 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8525 int bssrate_len = 0;
8526 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8527
8528 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8529 mac = adapter_mac_addr(padapter);
8530
8531 fctrl = &(pwlanhdr->frame_ctl);
8532 *(fctrl) = 0;
8533
8534 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8535 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8536
8537 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8538
8539 SetSeqNum(pwlanhdr, 0);
8540 set_frame_sub_type(pframe, WIFI_PROBEREQ);
8541
8542 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8543 pframe += pktlen;
8544
8545 if (ssid == NULL)
8546 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
8547 else {
8548 /* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
8549 pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
8550 }
8551
8552 get_rate_set(padapter, bssrate, &bssrate_len);
8553
8554 if (bssrate_len > 8) {
8555 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
8556 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
8557 } else
8558 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
8559
8560 *pLength = pktlen;
8561 }
8562
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)8563 static void rtw_hal_construct_PNO_info(_adapter *padapter,
8564 u8 *pframe, u32 *pLength)
8565 {
8566 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8567 int i;
8568
8569 u8 *pPnoInfoPkt = pframe;
8570 pPnoInfoPkt = (u8 *)(pframe + *pLength);
8571 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
8572
8573 pPnoInfoPkt += 1;
8574 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
8575
8576 pPnoInfoPkt += 3;
8577 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
8578
8579 pPnoInfoPkt += 4;
8580 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
8581
8582 pPnoInfoPkt += 4;
8583 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
8584
8585 pPnoInfoPkt += 4;
8586 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
8587
8588 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8589 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
8590
8591 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8592 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
8593
8594 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8595 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
8596
8597 pPnoInfoPkt += MAX_HIDDEN_AP;
8598
8599 /*
8600 SSID is located at 128th Byte in NLO info Page
8601 */
8602
8603 *pLength += 128;
8604 pPnoInfoPkt = pframe + 128;
8605
8606 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8607 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8608 pwrctl->pnlo_info->ssid_length[i]);
8609 *pLength += WLAN_SSID_MAXLEN;
8610 pPnoInfoPkt += WLAN_SSID_MAXLEN;
8611 }
8612 }
8613
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)8614 static void rtw_hal_construct_ssid_list(_adapter *padapter,
8615 u8 *pframe, u32 *pLength)
8616 {
8617 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8618 u8 *pSSIDListPkt = pframe;
8619 int i;
8620
8621 pSSIDListPkt = (u8 *)(pframe + *pLength);
8622
8623 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8624 _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8625 pwrctl->pnlo_info->ssid_length[i]);
8626
8627 *pLength += WLAN_SSID_MAXLEN;
8628 pSSIDListPkt += WLAN_SSID_MAXLEN;
8629 }
8630 }
8631
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)8632 static void rtw_hal_construct_scan_info(_adapter *padapter,
8633 u8 *pframe, u32 *pLength)
8634 {
8635 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8636 u8 *pScanInfoPkt = pframe;
8637 int i;
8638
8639 pScanInfoPkt = (u8 *)(pframe + *pLength);
8640
8641 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
8642
8643 *pLength += 1;
8644 pScanInfoPkt += 1;
8645 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
8646
8647
8648 *pLength += 1;
8649 pScanInfoPkt += 1;
8650 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
8651
8652
8653 *pLength += 1;
8654 pScanInfoPkt += 1;
8655 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
8656
8657 *pLength += 1;
8658 pScanInfoPkt += 1;
8659 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
8660
8661 *pLength += 1;
8662 pScanInfoPkt += 1;
8663 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
8664
8665 *pLength += 1;
8666 pScanInfoPkt += 1;
8667 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
8668
8669 *pLength += 1;
8670 pScanInfoPkt += 1;
8671 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
8672
8673 *pLength += 1;
8674 pScanInfoPkt += 1;
8675 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
8676
8677 *pLength += 8;
8678 pScanInfoPkt += 8;
8679
8680 for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
8681 _rtw_memcpy(pScanInfoPkt,
8682 &pwrctl->pscan_info->ssid_channel_info[i], 4);
8683 *pLength += 4;
8684 pScanInfoPkt += 4;
8685 }
8686 }
8687 #endif /* CONFIG_PNO_SUPPORT */
8688
8689 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)8690 static void rtw_hal_construct_GTKRsp(
8691 PADAPTER padapter,
8692 u8 *pframe,
8693 u32 *pLength
8694 )
8695 {
8696 struct rtw_ieee80211_hdr *pwlanhdr;
8697 u16 *fctrl;
8698 u32 pktlen;
8699 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8700 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8701 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8702 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8703 struct security_priv *psecuritypriv = &padapter->securitypriv;
8704 static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
8705 static u8 GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
8706 u8 *pGTKRspPkt = pframe;
8707 u8 EncryptionHeadOverhead = 0;
8708 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8709
8710 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8711
8712 fctrl = &pwlanhdr->frame_ctl;
8713 *(fctrl) = 0;
8714
8715 /* ------------------------------------------------------------------------- */
8716 /* MAC Header. */
8717 /* ------------------------------------------------------------------------- */
8718 SetFrameType(fctrl, WIFI_DATA);
8719 /* set_frame_sub_type(fctrl, 0); */
8720 SetToDs(fctrl);
8721
8722 _rtw_memcpy(pwlanhdr->addr1,
8723 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8724
8725 _rtw_memcpy(pwlanhdr->addr2,
8726 adapter_mac_addr(padapter), ETH_ALEN);
8727
8728 _rtw_memcpy(pwlanhdr->addr3,
8729 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8730
8731 SetSeqNum(pwlanhdr, 0);
8732 set_duration(pwlanhdr, 0);
8733
8734 #ifdef CONFIG_WAPI_SUPPORT
8735 *pLength = sMacHdrLng;
8736 #else
8737 *pLength = 24;
8738 #endif /* CONFIG_WAPI_SUPPORT */
8739
8740 /* ------------------------------------------------------------------------- */
8741 /* Security Header: leave space for it if necessary. */
8742 /* ------------------------------------------------------------------------- */
8743 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8744 case _WEP40_:
8745 case _WEP104_:
8746 EncryptionHeadOverhead = 4;
8747 break;
8748 case _TKIP_:
8749 EncryptionHeadOverhead = 8;
8750 break;
8751 case _AES_:
8752 EncryptionHeadOverhead = 8;
8753 break;
8754 #ifdef CONFIG_WAPI_SUPPORT
8755 case _SMS4_:
8756 EncryptionHeadOverhead = 18;
8757 break;
8758 #endif /* CONFIG_WAPI_SUPPORT */
8759 default:
8760 EncryptionHeadOverhead = 0;
8761 }
8762
8763 if (EncryptionHeadOverhead > 0) {
8764 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8765 *pLength += EncryptionHeadOverhead;
8766 /* SET_80211_HDR_WEP(pGTKRspPkt, 1); */ /* Suggested by CCW. */
8767 /* GTK's privacy bit is done by FW */
8768 /* SetPrivacy(fctrl); */
8769 }
8770 /* ------------------------------------------------------------------------- */
8771 /* Frame Body. */
8772 /* ------------------------------------------------------------------------- */
8773 pGTKRspPkt = (u8 *)(pframe + *pLength);
8774 /* LLC header */
8775 _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
8776 *pLength += 8;
8777
8778 /* GTK element */
8779 pGTKRspPkt += 8;
8780
8781 /* GTK frame body after LLC, part 1 */
8782 /* TKIP key_length = 32, AES key_length = 16 */
8783 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8784 GTKbody_a[8] = 0x20;
8785
8786 /* GTK frame body after LLC, part 1 */
8787 _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
8788 *pLength += 11;
8789 pGTKRspPkt += 11;
8790 /* GTK frame body after LLC, part 2 */
8791 _rtw_memset(&(pframe[*pLength]), 0, 88);
8792 *pLength += 88;
8793 pGTKRspPkt += 88;
8794
8795 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8796 *pLength += 8;
8797 }
8798 #endif /* CONFIG_GTK_OL */
8799
8800 #define PN_2_CCMPH(ch,key_id) ((ch) & 0x000000000000ffff) \
8801 | (((ch) & 0x0000ffffffff0000) << 16) \
8802 | (((key_id) << 30)) \
8803 | BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)8804 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
8805 u8 *pframe, u32 *pLength)
8806 {
8807 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8808 struct sta_priv *pstapriv = &adapter->stapriv;
8809 struct security_priv *psecuritypriv = &adapter->securitypriv;
8810 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
8811 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8812 struct sta_info *psta;
8813 struct stainfo_rxcache *prxcache;
8814 u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
8815 size_t sz = 0, total = 0;
8816 u64 ccmp_hdr = 0, tmp_key = 0;
8817
8818 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8819
8820 if (psta == NULL) {
8821 rtw_warn_on(1);
8822 return;
8823 }
8824
8825 prxcache = &psta->sta_recvpriv.rxcache;
8826 sz = sizeof(cur_dot11rxiv);
8827
8828 /* 3 SEC IV * 1 page */
8829 rtw_get_sec_iv(adapter, cur_dot11rxiv,
8830 get_my_bssid(&pmlmeinfo->network));
8831
8832 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
8833 *pLength += sz;
8834 pframe += sz;
8835
8836 _rtw_memset(&cur_dot11rxiv, 0, sz);
8837
8838 if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
8839 id = psecuritypriv->dot118021XGrpKeyid;
8840 tid_id = prxcache->last_tid;
8841 REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
8842 REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
8843 REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
8844 REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
8845 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
8846 *pLength += sz;
8847 pframe += sz;
8848
8849 _rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
8850 *pLength += sz;
8851 pframe += sz;
8852
8853 total = sizeof(psecuritypriv->iv_seq);
8854 total /= sizeof(psecuritypriv->iv_seq[0]);
8855
8856 for (i = 0 ; i < total ; i ++) {
8857 ccmp_hdr =
8858 le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
8859 _rtw_memset(&cur_dot11rxiv, 0, sz);
8860 if (ccmp_hdr != 0) {
8861 tmp_key = i;
8862 ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
8863 *(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
8864 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
8865 }
8866 *pLength += sz;
8867 pframe += sz;
8868 }
8869 }
8870 }
8871
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)8872 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
8873 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
8874 RSVDPAGE_LOC *rsvd_page_loc)
8875 {
8876 struct security_priv *psecuritypriv = &adapter->securitypriv;
8877 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8878 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8879 struct mlme_ext_priv *pmlmeext;
8880 struct mlme_ext_info *pmlmeinfo;
8881 u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
8882 u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;
8883 u8 CurtPktPageNum = 0;
8884
8885 #ifdef CONFIG_GTK_OL
8886 struct sta_priv *pstapriv = &adapter->stapriv;
8887 struct sta_info *psta;
8888 struct security_priv *psecpriv = &adapter->securitypriv;
8889 u8 kek[RTW_KEK_LEN];
8890 u8 kck[RTW_KCK_LEN];
8891 #endif /* CONFIG_GTK_OL */
8892 #ifdef CONFIG_PNO_SUPPORT
8893 int pno_index;
8894 u8 ssid_num;
8895 #endif /* CONFIG_PNO_SUPPORT */
8896
8897 pmlmeext = &adapter->mlmeextpriv;
8898 pmlmeinfo = &pmlmeext->mlmext_info;
8899
8900 if (pwrctl->wowlan_pno_enable == _FALSE) {
8901 /* ARP RSP * 1 page */
8902
8903 rsvd_page_loc->LocArpRsp = *page_num;
8904
8905 RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
8906
8907 rtw_hal_construct_ARPRsp(adapter, &pframe[index],
8908 &ARPLength, pmlmeinfo->ip_addr);
8909
8910 rtw_hal_fill_fake_txdesc(adapter,
8911 &pframe[index - tx_desc],
8912 ARPLength, _FALSE, _FALSE, _TRUE);
8913
8914 CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
8915
8916 *page_num += CurtPktPageNum;
8917
8918 index += (CurtPktPageNum * page_size);
8919 RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
8920
8921 #ifdef CONFIG_IPV6
8922 /* 2 NS offload and NDP Info*/
8923 if (pwrctl->wowlan_ns_offload_en == _TRUE) {
8924 rsvd_page_loc->LocNbrAdv = *page_num;
8925 RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
8926 rtw_hal_construct_na_message(adapter,
8927 &pframe[index], &ns_len);
8928 rtw_hal_fill_fake_txdesc(adapter,
8929 &pframe[index - tx_desc],
8930 ns_len, _FALSE,
8931 _FALSE, _TRUE);
8932 CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
8933 page_size);
8934 *page_num += CurtPktPageNum;
8935 index += (CurtPktPageNum * page_size);
8936 RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
8937
8938 rsvd_page_loc->LocNDPInfo = *page_num;
8939 RTW_INFO("LocNDPInfo: %d\n",
8940 rsvd_page_loc->LocNDPInfo);
8941
8942 rtw_hal_construct_ndp_info(adapter,
8943 &pframe[index - tx_desc],
8944 &ns_len);
8945 CurtPktPageNum =
8946 (u8)PageNum(tx_desc + ns_len, page_size);
8947 *page_num += CurtPktPageNum;
8948 index += (CurtPktPageNum * page_size);
8949 RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
8950
8951 }
8952 #endif /*CONFIG_IPV6*/
8953 /* 3 Remote Control Info. * 1 page */
8954 rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
8955 RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
8956 rtw_hal_construct_remote_control_info(adapter,
8957 &pframe[index - tx_desc],
8958 &rc_len);
8959 CurtPktPageNum = (u8)PageNum(rc_len, page_size);
8960 *page_num += CurtPktPageNum;
8961 *total_pkt_len = index + rc_len;
8962 RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
8963 #ifdef CONFIG_GTK_OL
8964 index += (CurtPktPageNum * page_size);
8965
8966 /* if the ap staion info. exists, get the kek, kck from staion info. */
8967 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8968 if (psta == NULL) {
8969 _rtw_memset(kek, 0, RTW_KEK_LEN);
8970 _rtw_memset(kck, 0, RTW_KCK_LEN);
8971 RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
8972 __func__);
8973 } else {
8974 _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
8975 _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
8976 }
8977
8978 /* 3 KEK, KCK */
8979 rsvd_page_loc->LocGTKInfo = *page_num;
8980 RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
8981
8982 if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
8983 struct security_priv *psecpriv = NULL;
8984
8985 psecpriv = &adapter->securitypriv;
8986 _rtw_memcpy(pframe + index - tx_desc,
8987 &psecpriv->dot11PrivacyAlgrthm, 1);
8988 _rtw_memcpy(pframe + index - tx_desc + 1,
8989 &psecpriv->dot118021XGrpPrivacy, 1);
8990 _rtw_memcpy(pframe + index - tx_desc + 2,
8991 kck, RTW_KCK_LEN);
8992 _rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
8993 kek, RTW_KEK_LEN);
8994 CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
8995 } else {
8996
8997 _rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
8998 _rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
8999 kek, RTW_KEK_LEN);
9000 GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
9001
9002 if (psta != NULL &&
9003 psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
9004 _rtw_memcpy(pframe + index - tx_desc + 56,
9005 &psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
9006 GTKLength += RTW_TKIP_MIC_LEN;
9007 }
9008 CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
9009 }
9010 #if 0
9011 {
9012 int i;
9013 printk("\ntoFW KCK: ");
9014 for (i = 0; i < 16; i++)
9015 printk(" %02x ", kck[i]);
9016 printk("\ntoFW KEK: ");
9017 for (i = 0; i < 16; i++)
9018 printk(" %02x ", kek[i]);
9019 printk("\n");
9020 }
9021
9022 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
9023 __FUNCTION__, &pframe[index - tx_desc],
9024 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
9025 #endif
9026
9027 *page_num += CurtPktPageNum;
9028
9029 index += (CurtPktPageNum * page_size);
9030 RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
9031
9032 /* 3 GTK Response */
9033 rsvd_page_loc->LocGTKRsp = *page_num;
9034 RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
9035 rtw_hal_construct_GTKRsp(adapter, &pframe[index], >KLength);
9036
9037 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
9038 GTKLength, _FALSE, _FALSE, _TRUE);
9039 #if 0
9040 {
9041 int gj;
9042 printk("123GTK pkt=>\n");
9043 for (gj = 0; gj < GTKLength + tx_desc; gj++) {
9044 printk(" %02x ", pframe[index - tx_desc + gj]);
9045 if ((gj + 1) % 16 == 0)
9046 printk("\n");
9047 }
9048 printk(" <=end\n");
9049 }
9050
9051 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
9052 __FUNCTION__, &pframe[index - tx_desc],
9053 (tx_desc + GTKLength));
9054 #endif
9055
9056 CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
9057
9058 *page_num += CurtPktPageNum;
9059
9060 index += (CurtPktPageNum * page_size);
9061 RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
9062
9063 /* below page is empty for GTK extension memory */
9064 /* 3(11) GTK EXT MEM */
9065 rsvd_page_loc->LocGTKEXTMEM = *page_num;
9066 RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
9067 CurtPktPageNum = 2;
9068
9069 if (page_size >= 256)
9070 CurtPktPageNum = 1;
9071
9072 *page_num += CurtPktPageNum;
9073 /* extension memory for FW */
9074 *total_pkt_len = index + (page_size * CurtPktPageNum);
9075 RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
9076 #endif /* CONFIG_GTK_OL */
9077
9078 index += (CurtPktPageNum * page_size);
9079
9080 /*Reserve 1 page for AOAC report*/
9081 rsvd_page_loc->LocAOACReport = *page_num;
9082 RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
9083 *page_num += 1;
9084 *total_pkt_len = index + (page_size * 1);
9085 RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
9086 } else {
9087 #ifdef CONFIG_PNO_SUPPORT
9088 if (pwrctl->wowlan_in_resume == _FALSE &&
9089 pwrctl->pno_inited == _TRUE) {
9090
9091 /* Broadcast Probe Request */
9092 rsvd_page_loc->LocProbePacket = *page_num;
9093
9094 RTW_INFO("loc_probe_req: %d\n",
9095 rsvd_page_loc->LocProbePacket);
9096
9097 rtw_hal_construct_ProbeReq(
9098 adapter,
9099 &pframe[index],
9100 &ProbeReqLength,
9101 NULL);
9102
9103 rtw_hal_fill_fake_txdesc(adapter,
9104 &pframe[index - tx_desc],
9105 ProbeReqLength, _FALSE, _FALSE, _FALSE);
9106
9107 CurtPktPageNum =
9108 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
9109
9110 *page_num += CurtPktPageNum;
9111
9112 index += (CurtPktPageNum * page_size);
9113 RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9114
9115 /* Hidden SSID Probe Request */
9116 ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
9117
9118 for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
9119 pwrctl->pnlo_info->loc_probe_req[pno_index] =
9120 *page_num;
9121
9122 rtw_hal_construct_ProbeReq(
9123 adapter,
9124 &pframe[index],
9125 &ProbeReqLength,
9126 &pwrctl->pno_ssid_list->node[pno_index]);
9127
9128 rtw_hal_fill_fake_txdesc(adapter,
9129 &pframe[index - tx_desc],
9130 ProbeReqLength, _FALSE, _FALSE, _FALSE);
9131
9132 CurtPktPageNum =
9133 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
9134
9135 *page_num += CurtPktPageNum;
9136
9137 index += (CurtPktPageNum * page_size);
9138 RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9139 }
9140
9141 /* PNO INFO Page */
9142 rsvd_page_loc->LocPNOInfo = *page_num;
9143 RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
9144 rtw_hal_construct_PNO_info(adapter,
9145 &pframe[index - tx_desc],
9146 &PNOLength);
9147
9148 CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
9149 *page_num += CurtPktPageNum;
9150 index += (CurtPktPageNum * page_size);
9151 RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
9152
9153 /* Scan Info Page */
9154 rsvd_page_loc->LocScanInfo = *page_num;
9155 RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
9156 rtw_hal_construct_scan_info(adapter,
9157 &pframe[index - tx_desc],
9158 &ScanInfoLength);
9159
9160 CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
9161 *page_num += CurtPktPageNum;
9162 *total_pkt_len = index + ScanInfoLength;
9163 index += (CurtPktPageNum * page_size);
9164 RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
9165 }
9166 #endif /* CONFIG_PNO_SUPPORT */
9167 }
9168 }
9169
rtw_hal_gate_bb(_adapter * adapter,bool stop)9170 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
9171 {
9172 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9173 u8 i = 0, val8 = 0, empty = _FAIL;
9174
9175 if (stop) {
9176 /* checking TX queue status */
9177 for (i = 0 ; i < 5 ; i++) {
9178 rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
9179 if (empty) {
9180 break;
9181 } else {
9182 RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
9183 __func__, i);
9184 rtw_mdelay_os(10);
9185 }
9186 }
9187
9188 if (val8 == 5)
9189 RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
9190
9191 /* Pause TX*/
9192 pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
9193 rtw_write8(adapter, REG_TXPAUSE, 0xff);
9194 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9195 val8 &= ~BIT(0);
9196 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9197 RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
9198 __func__,
9199 rtw_read8(adapter, REG_SYS_FUNC_EN),
9200 pwrpriv->wowlan_txpause_status);
9201 } else {
9202 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9203 val8 |= BIT(0);
9204 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9205 RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
9206 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
9207 pwrpriv->wowlan_txpause_status);
9208 /* release TX*/
9209 rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
9210 }
9211 }
9212
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)9213 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
9214 {
9215 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9216 u8 *pattern;
9217 u8 len = 0;
9218 u8 *mask;
9219
9220 u8 mask_hw[MAX_WKFM_SIZE] = {0};
9221 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9222 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9223 u8 multicast_addr1[2] = {0x33, 0x33};
9224 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9225 u8 mask_len = 0;
9226 u8 mac_addr[ETH_ALEN] = {0};
9227 u16 count = 0;
9228 int i;
9229
9230 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9231 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9232 __func__, MAX_WKFM_CAM_NUM);
9233 return _FAIL;
9234 }
9235
9236 pattern = pwrctl->patterns[idx].content;
9237 len = pwrctl->patterns[idx].len;
9238 mask = pwrctl->patterns[idx].mask;
9239
9240 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9241 _rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
9242
9243 mask_len = DIV_ROUND_UP(len, 8);
9244
9245 /* 1. setup A1 table */
9246 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9247 pwow_pattern->type = PATTERN_BROADCAST;
9248 else if (memcmp(pattern, multicast_addr1, 2) == 0)
9249 pwow_pattern->type = PATTERN_MULTICAST;
9250 else if (memcmp(pattern, multicast_addr2, 3) == 0)
9251 pwow_pattern->type = PATTERN_MULTICAST;
9252 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9253 pwow_pattern->type = PATTERN_UNICAST;
9254 else
9255 pwow_pattern->type = PATTERN_INVALID;
9256
9257 /* translate mask from os to mask for hw */
9258
9259 /******************************************************************************
9260 * pattern from OS uses 'ethenet frame', like this:
9261
9262 | 6 | 6 | 2 | 20 | Variable | 4 |
9263 |--------+--------+------+-----------+------------+-----|
9264 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
9265 | DA | SA | Type |
9266
9267 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9268
9269 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
9270 |-------------------+--------+------+-----------+------------+-----|
9271 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
9272 | Others | Tpye |
9273
9274 * Therefore, we need translate mask_from_OS to mask_to_hw.
9275 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9276 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9277 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9278 ******************************************************************************/
9279 /* Shift 6 bits */
9280 for (i = 0; i < mask_len - 1; i++) {
9281 mask_hw[i] = mask[i] >> 6;
9282 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9283 }
9284
9285 mask_hw[i] = (mask[i] >> 6) & 0x3F;
9286 /* Set bit 0-5 to zero */
9287 mask_hw[0] &= 0xC0;
9288
9289 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9290 pwow_pattern->mask[i] = mask_hw[i * 4];
9291 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
9292 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
9293 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
9294 }
9295
9296 /* To get the wake up pattern from the mask.
9297 * We do not count first 12 bits which means
9298 * DA[6] and SA[6] in the pattern to match HW design. */
9299 count = 0;
9300 for (i = 12; i < len; i++) {
9301 if ((mask[i / 8] >> (i % 8)) & 0x01) {
9302 content[count] = pattern[i];
9303 count++;
9304 }
9305 }
9306
9307 pwow_pattern->crc = rtw_calc_crc(content, count);
9308
9309 if (pwow_pattern->crc != 0) {
9310 if (pwow_pattern->type == PATTERN_INVALID)
9311 pwow_pattern->type = PATTERN_VALID;
9312 }
9313
9314 return _SUCCESS;
9315 }
9316
9317 #ifndef CONFIG_WOW_PATTERN_HW_CAM
rtw_hal_reset_mac_rx(_adapter * adapter)9318 static void rtw_hal_reset_mac_rx(_adapter *adapter)
9319 {
9320 u8 val8 = 0;
9321 /* Set REG_CR bit1, bit3, bit7 to 0*/
9322 val8 = rtw_read8(adapter, REG_CR);
9323 val8 &= 0x75;
9324 rtw_write8(adapter, REG_CR, val8);
9325 val8 = rtw_read8(adapter, REG_CR);
9326 /* Set REG_CR bit1, bit3, bit7 to 1*/
9327 val8 |= 0x8a;
9328 rtw_write8(adapter, REG_CR, val8);
9329 RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
9330 }
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)9331 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
9332 {
9333 u8 val8 = 0;
9334 u16 rxff_bndy = 0;
9335 u32 rx_dma_buff_sz = 0;
9336
9337 val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
9338 if (val8 != 0)
9339 RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
9340 __func__, (REG_FIFOPAGE + 3));
9341
9342 rtw_hal_reset_mac_rx(adapter);
9343
9344 if (wow_mode) {
9345 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9346 (u8 *)&rx_dma_buff_sz);
9347 rxff_bndy = rx_dma_buff_sz - 1;
9348
9349 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9350 RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
9351 REG_TRXFF_BNDY + 2,
9352 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9353 } else {
9354 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
9355 (u8 *)&rx_dma_buff_sz);
9356 rxff_bndy = rx_dma_buff_sz - 1;
9357 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9358 RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
9359 REG_TRXFF_BNDY + 2,
9360 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9361 }
9362 }
9363
9364 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9365 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9366 {
9367 u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9368 u16 offset, rx_buf_ptr = 0;
9369 u16 cam_start_offset = 0;
9370 u16 ctrl_l = 0, ctrl_h = 0;
9371 u8 count = 0, tmp = 0;
9372 int i = 0;
9373 bool res = _TRUE;
9374
9375 if (idx > MAX_WKFM_CAM_NUM) {
9376 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9377 __func__);
9378 return _FALSE;
9379 }
9380
9381 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9382 (u8 *)&rx_dma_buff_sz);
9383
9384 if (rx_dma_buff_sz == 0) {
9385 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9386 return _FALSE;
9387 }
9388
9389 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9390
9391 if (page_sz == 0) {
9392 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9393 return _FALSE;
9394 }
9395
9396 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9397 cam_start_offset = offset * page_sz;
9398
9399 ctrl_l = 0x0;
9400 ctrl_h = 0x0;
9401
9402 /* Enable RX packet buffer access */
9403 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9404
9405 /* Read the WKFM CAM */
9406 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9407 /*
9408 * Set Rx packet buffer offset.
9409 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9410 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9411 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9412 * * Index: The index of the wake up frame mask
9413 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9414 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9415 */
9416 rx_buf_ptr =
9417 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9418 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9419
9420 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9421 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9422 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9423
9424 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9425
9426 count = 0;
9427
9428 do {
9429 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9430 rtw_udelay_os(2);
9431 count++;
9432 } while (!tmp && count < 100);
9433
9434 if (count >= 100) {
9435 RTW_INFO("%s count:%d\n", __func__, count);
9436 res = _FALSE;
9437 }
9438 }
9439
9440 /* Disable RX packet buffer access */
9441 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9442 DISABLE_TRXPKT_BUF_ACCESS);
9443 return res;
9444 }
9445
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9446 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9447 struct rtl_wow_pattern *context)
9448 {
9449 u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
9450 u16 offset, rx_buf_ptr = 0;
9451 u16 cam_start_offset = 0;
9452 u16 ctrl_l = 0, ctrl_h = 0;
9453 u8 count = 0, tmp = 0;
9454 int res = 0, i = 0;
9455
9456 if (idx > MAX_WKFM_CAM_NUM) {
9457 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9458 __func__);
9459 return _FALSE;
9460 }
9461
9462 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9463 (u8 *)&rx_dma_buff_sz);
9464
9465 if (rx_dma_buff_sz == 0) {
9466 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9467 return _FALSE;
9468 }
9469
9470 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9471
9472 if (page_sz == 0) {
9473 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9474 return _FALSE;
9475 }
9476
9477 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9478
9479 cam_start_offset = offset * page_sz;
9480
9481 if (IS_HARDWARE_TYPE_8188E(adapter)) {
9482 ctrl_l = 0x0001;
9483 ctrl_h = 0x0001;
9484 } else {
9485 ctrl_l = 0x0f01;
9486 ctrl_h = 0xf001;
9487 }
9488
9489 /* Enable RX packet buffer access */
9490 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9491
9492 /* Write the WKFM CAM */
9493 for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
9494 /*
9495 * Set Rx packet buffer offset.
9496 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9497 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9498 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9499 * * Index: The index of the wake up frame mask
9500 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9501 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9502 */
9503 rx_buf_ptr =
9504 (cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
9505 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9506
9507 if (i == 0) {
9508 if (context->type == PATTERN_VALID)
9509 data = BIT(31);
9510 else if (context->type == PATTERN_BROADCAST)
9511 data = BIT(31) | BIT(26);
9512 else if (context->type == PATTERN_MULTICAST)
9513 data = BIT(31) | BIT(25);
9514 else if (context->type == PATTERN_UNICAST)
9515 data = BIT(31) | BIT(24);
9516
9517 if (context->crc != 0)
9518 data |= context->crc;
9519
9520 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9521 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9522 } else if (i == 1) {
9523 data = 0;
9524 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9525 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9526 } else if (i == 2 || i == 4) {
9527 data = context->mask[i - 2];
9528 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9529 /* write to RX packet buffer*/
9530 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9531 } else if (i == 3 || i == 5) {
9532 data = context->mask[i - 2];
9533 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9534 /* write to RX packet buffer*/
9535 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9536 }
9537
9538 count = 0;
9539 do {
9540 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9541 rtw_udelay_os(2);
9542 count++;
9543 } while (tmp && count < 100);
9544
9545 if (count >= 100)
9546 res = _FALSE;
9547 else
9548 res = _TRUE;
9549 }
9550
9551 /* Disable RX packet buffer access */
9552 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9553 DISABLE_TRXPKT_BUF_ACCESS);
9554
9555 return res;
9556 }
9557 #else /* CONFIG_WOW_PATTERN_IN_TXFIFO */
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9558 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9559 {
9560 u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9561 u16 tx_page_start, tx_buf_ptr = 0;
9562 u16 cam_start_offset = 0;
9563 u16 ctrl_l = 0, ctrl_h = 0;
9564 u8 count = 0, tmp = 0, last_entry = 0;
9565 int i = 0;
9566 bool res = _TRUE;
9567
9568 if (idx > MAX_WKFM_CAM_NUM) {
9569 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9570 __func__);
9571 return _FALSE;
9572 }
9573
9574 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9575 if (page_sz == 0) {
9576 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9577 return _FALSE;
9578 }
9579
9580 rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9581 if (last_entry == 0) {
9582 RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9583 return _FALSE;
9584 }
9585
9586 /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9587 tx_page_start = last_entry - 1;
9588 cam_start_offset = tx_page_start * page_sz / 8;
9589 ctrl_l = 0x0;
9590 ctrl_h = 0x0;
9591
9592 /* Enable TX packet buffer access */
9593 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9594
9595 /* Read the WKFM CAM */
9596 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9597 /*
9598 * Set Tx packet buffer offset.
9599 * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer.
9600 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9601 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9602 * * Index: The index of the wake up frame mask
9603 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9604 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9605 */
9606 tx_buf_ptr =
9607 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9608 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr);
9609 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9610 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9611 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9612
9613 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9614
9615 count = 0;
9616
9617 do {
9618 tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9619 rtw_udelay_os(2);
9620 count++;
9621 } while (!tmp && count < 100);
9622
9623 if (count >= 100) {
9624 RTW_INFO("%s count:%d\n", __func__, count);
9625 res = _FALSE;
9626 }
9627 }
9628
9629 /* Disable RX packet buffer access */
9630 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9631 DISABLE_TRXPKT_BUF_ACCESS);
9632 return res;
9633 }
9634
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9635 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9636 struct rtl_wow_pattern *context)
9637 {
9638 u32 tx_page_start = 0, page_sz = 0;
9639 u16 tx_buf_ptr = 0;
9640 u16 cam_start_offset = 0;
9641 u32 data_l = 0, data_h = 0;
9642 u8 count = 0, tmp = 0, last_entry = 0;
9643 int res = 0, i = 0;
9644
9645 if (idx > MAX_WKFM_CAM_NUM) {
9646 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9647 __func__);
9648 return _FALSE;
9649 }
9650
9651 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9652 if (page_sz == 0) {
9653 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9654 return _FALSE;
9655 }
9656
9657 rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9658 if (last_entry == 0) {
9659 RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9660 return _FALSE;
9661 }
9662
9663 /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9664 tx_page_start = last_entry - 1;
9665 cam_start_offset = tx_page_start * page_sz / 8;
9666
9667 /* Write the PATTERN location to BIT_TXBUF_WKCAM_OFFSET */
9668 rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET, cam_start_offset & 0xFF);
9669 rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET + 1, (cam_start_offset >> 8) & 0xFF);
9670 /* Enable TX packet buffer access */
9671 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9672
9673 /* Write the WKFM CAM */
9674 for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9675 /*
9676 * Set Tx packet buffer offset.
9677 * TxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9678 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9679 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9680 * * Index: The index of the wake up frame mask
9681 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9682 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9683 */
9684 tx_buf_ptr = cam_start_offset + ((idx * WKFMCAM_SIZE + i * 8) >> 3);
9685
9686 if (i == 0) {
9687 if (context->type == PATTERN_VALID)
9688 data_l = BIT(31);
9689 else if (context->type == PATTERN_BROADCAST)
9690 data_l = BIT(31) | BIT(26);
9691 else if (context->type == PATTERN_MULTICAST)
9692 data_l = BIT(31) | BIT(25);
9693 else if (context->type == PATTERN_UNICAST)
9694 data_l = BIT(31) | BIT(24);
9695
9696 if (context->crc != 0)
9697 data_l |= context->crc;
9698
9699 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9700 } else {
9701 data_l = context->mask[i * 2 - 2];
9702 data_h = context->mask[i * 2 - 1];
9703 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9704 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h);
9705 }
9706
9707 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0xFFFF) | BIT23 | (0xff <<24));
9708 count = 0;
9709 do {
9710 tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9711 rtw_udelay_os(2);
9712 count++;
9713 } while (tmp && count < 100);
9714
9715 if (count >= 100) {
9716 res = _FALSE;
9717 RTW_INFO("%s write failed\n", __func__);
9718 } else {
9719 res = _TRUE;
9720 RTW_INFO("%s write OK\n", __func__);
9721 }
9722 }
9723
9724 /* Disable TX packet buffer access */
9725 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
9726 return res;
9727 }
9728 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
9729
rtw_clean_pattern(_adapter * adapter)9730 void rtw_clean_pattern(_adapter *adapter)
9731 {
9732 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9733 struct rtl_wow_pattern zero_pattern;
9734 int i = 0;
9735
9736 _rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
9737
9738 zero_pattern.type = PATTERN_INVALID;
9739
9740 for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
9741 rtw_write_to_frame_mask(adapter, i, &zero_pattern);
9742
9743 rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
9744 }
9745 #if 0
9746 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
9747 u8 len, u8 *mask, u8 idx)
9748 {
9749 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9750 struct mlme_ext_priv *pmlmeext = NULL;
9751 struct mlme_ext_info *pmlmeinfo = NULL;
9752 struct rtl_wow_pattern wow_pattern;
9753 u8 mask_hw[MAX_WKFM_SIZE] = {0};
9754 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9755 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9756 u8 multicast_addr1[2] = {0x33, 0x33};
9757 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9758 u8 res = _FALSE, index = 0, mask_len = 0;
9759 u8 mac_addr[ETH_ALEN] = {0};
9760 u16 count = 0;
9761 int i, j;
9762
9763 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9764 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9765 __func__, MAX_WKFM_CAM_NUM);
9766 return _FALSE;
9767 }
9768
9769 pmlmeext = &adapter->mlmeextpriv;
9770 pmlmeinfo = &pmlmeext->mlmext_info;
9771 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9772 _rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
9773
9774 mask_len = DIV_ROUND_UP(len, 8);
9775
9776 /* 1. setup A1 table */
9777 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9778 wow_pattern.type = PATTERN_BROADCAST;
9779 else if (memcmp(pattern, multicast_addr1, 2) == 0)
9780 wow_pattern.type = PATTERN_MULTICAST;
9781 else if (memcmp(pattern, multicast_addr2, 3) == 0)
9782 wow_pattern.type = PATTERN_MULTICAST;
9783 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9784 wow_pattern.type = PATTERN_UNICAST;
9785 else
9786 wow_pattern.type = PATTERN_INVALID;
9787
9788 /* translate mask from os to mask for hw */
9789
9790 /******************************************************************************
9791 * pattern from OS uses 'ethenet frame', like this:
9792
9793 | 6 | 6 | 2 | 20 | Variable | 4 |
9794 |--------+--------+------+-----------+------------+-----|
9795 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
9796 | DA | SA | Type |
9797
9798 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9799
9800 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
9801 |-------------------+--------+------+-----------+------------+-----|
9802 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
9803 | Others | Tpye |
9804
9805 * Therefore, we need translate mask_from_OS to mask_to_hw.
9806 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9807 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9808 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9809 ******************************************************************************/
9810 /* Shift 6 bits */
9811 for (i = 0; i < mask_len - 1; i++) {
9812 mask_hw[i] = mask[i] >> 6;
9813 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9814 }
9815
9816 mask_hw[i] = (mask[i] >> 6) & 0x3F;
9817 /* Set bit 0-5 to zero */
9818 mask_hw[0] &= 0xC0;
9819
9820 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9821 wow_pattern.mask[i] = mask_hw[i * 4];
9822 wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
9823 wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
9824 wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
9825 }
9826
9827 /* To get the wake up pattern from the mask.
9828 * We do not count first 12 bits which means
9829 * DA[6] and SA[6] in the pattern to match HW design. */
9830 count = 0;
9831 for (i = 12; i < len; i++) {
9832 if ((mask[i / 8] >> (i % 8)) & 0x01) {
9833 content[count] = pattern[i];
9834 count++;
9835 }
9836 }
9837
9838 wow_pattern.crc = rtw_calc_crc(content, count);
9839
9840 if (wow_pattern.crc != 0) {
9841 if (wow_pattern.type == PATTERN_INVALID)
9842 wow_pattern.type = PATTERN_VALID;
9843 }
9844
9845 index = idx;
9846
9847 if (!pwrctl->bInSuspend)
9848 index += 2;
9849
9850 /* write pattern */
9851 res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
9852
9853 if (res == _FALSE)
9854 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
9855 __func__, idx);
9856
9857 return res;
9858 }
9859 #endif
9860
rtw_fill_pattern(_adapter * adapter)9861 void rtw_fill_pattern(_adapter *adapter)
9862 {
9863 int i = 0, total = 0, index;
9864 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9865 struct rtl_wow_pattern wow_pattern;
9866
9867 total = pwrpriv->wowlan_pattern_idx;
9868
9869 if (total > MAX_WKFM_CAM_NUM)
9870 total = MAX_WKFM_CAM_NUM;
9871
9872 for (i = 0 ; i < total ; i++) {
9873 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
9874
9875 index = i;
9876 if (!pwrpriv->bInSuspend)
9877 index += 2;
9878
9879 if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
9880 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
9881 }
9882
9883 }
9884 rtw_write8(adapter, REG_WKFMCAM_NUM, total);
9885
9886 }
9887
9888 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
9889
9890 #define WOW_CAM_ACCESS_TIMEOUT_MS 200
9891 #define WOW_VALID_BIT BIT31
9892 #define WOW_BC_BIT BIT26
9893 #define WOW_MC_BIT BIT25
9894 #define WOW_UC_BIT BIT24
9895
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)9896 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
9897 {
9898 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9899 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
9900
9901 u32 rdata = 0;
9902 u32 cnt = 0;
9903 systime start = 0;
9904 u8 timeout = 0;
9905 u8 rst = _FALSE;
9906
9907 _enter_critical_mutex(mutex, NULL);
9908
9909 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
9910
9911 start = rtw_get_current_time();
9912 while (1) {
9913 if (rtw_is_surprise_removed(adapter))
9914 break;
9915
9916 cnt++;
9917 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
9918 rst = _SUCCESS;
9919 break;
9920 }
9921 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
9922 timeout = 1;
9923 break;
9924 }
9925 }
9926
9927 rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
9928
9929 _exit_critical_mutex(mutex, NULL);
9930
9931 /*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
9932
9933 if (timeout)
9934 RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
9935
9936 return rdata;
9937 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)9938 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
9939 {
9940 int i;
9941 u32 rdata;
9942
9943 _rtw_memset(context, 0, sizeof(struct rtl_wow_pattern));
9944
9945 for (i = 4; i >= 0; i--) {
9946 rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
9947
9948 switch (i) {
9949 case 4:
9950 if (rdata & WOW_BC_BIT)
9951 context->type = PATTERN_BROADCAST;
9952 else if (rdata & WOW_MC_BIT)
9953 context->type = PATTERN_MULTICAST;
9954 else if (rdata & WOW_UC_BIT)
9955 context->type = PATTERN_UNICAST;
9956 else
9957 context->type = PATTERN_INVALID;
9958
9959 context->crc = rdata & 0xFFFF;
9960 break;
9961 default:
9962 _rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
9963 break;
9964 }
9965 }
9966 }
9967
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)9968 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
9969 {
9970 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9971 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
9972 u32 cnt = 0;
9973 systime start = 0, end = 0;
9974 u8 timeout = 0;
9975
9976 /*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
9977 _enter_critical_mutex(mutex, NULL);
9978
9979 rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
9980 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
9981
9982 start = rtw_get_current_time();
9983 while (1) {
9984 if (rtw_is_surprise_removed(adapter))
9985 break;
9986
9987 cnt++;
9988 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
9989 break;
9990
9991 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
9992 timeout = 1;
9993 break;
9994 }
9995 }
9996 end = rtw_get_current_time();
9997
9998 _exit_critical_mutex(mutex, NULL);
9999
10000 if (timeout) {
10001 RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
10002 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
10003 }
10004 }
10005
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10006 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
10007 {
10008 int j;
10009 u8 addr;
10010 u32 wdata = 0;
10011
10012 for (j = 4; j >= 0; j--) {
10013 switch (j) {
10014 case 4:
10015 wdata = context->crc;
10016
10017 if (PATTERN_BROADCAST == context->type)
10018 wdata |= WOW_BC_BIT;
10019 if (PATTERN_MULTICAST == context->type)
10020 wdata |= WOW_MC_BIT;
10021 if (PATTERN_UNICAST == context->type)
10022 wdata |= WOW_UC_BIT;
10023 if (PATTERN_INVALID != context->type)
10024 wdata |= WOW_VALID_BIT;
10025 break;
10026 default:
10027 wdata = context->mask[j];
10028 break;
10029 }
10030
10031 addr = (id << 3) + j;
10032
10033 _rtw_wow_pattern_write_cam(adapter, addr, wdata);
10034 }
10035 }
10036
_rtw_wow_pattern_clean_cam(_adapter * adapter)10037 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
10038 {
10039 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10040 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10041 u32 cnt = 0;
10042 systime start = 0;
10043 u8 timeout = 0;
10044 u8 rst = _FAIL;
10045
10046 _enter_critical_mutex(mutex, NULL);
10047 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
10048
10049 start = rtw_get_current_time();
10050 while (1) {
10051 if (rtw_is_surprise_removed(adapter))
10052 break;
10053
10054 cnt++;
10055 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10056 rst = _SUCCESS;
10057 break;
10058 }
10059 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10060 timeout = 1;
10061 break;
10062 }
10063 }
10064 _exit_critical_mutex(mutex, NULL);
10065
10066 if (timeout)
10067 RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
10068
10069 return rst;
10070 }
10071
rtw_clean_pattern(_adapter * adapter)10072 void rtw_clean_pattern(_adapter *adapter)
10073 {
10074 if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
10075 RTW_ERR("rtw_clean_pattern failed\n");
10076 }
10077
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)10078 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
10079 {
10080 int j;
10081
10082 RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
10083 RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
10084 RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
10085 for (j = 0; j < 4; j++)
10086 RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
10087 }
10088
rtw_fill_pattern(_adapter * adapter)10089 void rtw_fill_pattern(_adapter *adapter)
10090 {
10091 int i = 0, total = 0;
10092 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10093 struct rtl_wow_pattern wow_pattern;
10094
10095 total = pwrpriv->wowlan_pattern_idx;
10096
10097 if (total > MAX_WKFM_CAM_NUM)
10098 total = MAX_WKFM_CAM_NUM;
10099
10100 for (i = 0 ; i < total ; i++) {
10101 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10102 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10103 rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
10104 }
10105 }
10106 }
10107
10108 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)10109 void rtw_wow_pattern_cam_dump(_adapter *adapter)
10110 {
10111
10112 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10113 int i;
10114
10115 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10116 RTW_INFO("=======[%d]=======\n", i);
10117 rtw_read_from_frame_mask(adapter, i);
10118 }
10119 #else
10120 struct rtl_wow_pattern context;
10121 int i;
10122
10123 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10124 rtw_wow_pattern_read_cam_ent(adapter, i, &context);
10125 rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
10126 }
10127
10128 #endif
10129 }
10130
10131
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)10132 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
10133 {
10134 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10135
10136 switch (mode) {
10137 case 0:
10138 rtw_clean_pattern(adapter);
10139 RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
10140 break;
10141 case 1:
10142 rtw_set_default_pattern(adapter);
10143 rtw_fill_pattern(adapter);
10144 RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
10145 break;
10146 case 2:
10147 rtw_clean_pattern(adapter);
10148 rtw_wow_pattern_sw_reset(adapter);
10149 RTW_INFO("%s: clean patterns\n", __func__);
10150 break;
10151 default:
10152 RTW_INFO("%s: unknown mode\n", __func__);
10153 break;
10154 }
10155 }
10156
rtw_hal_wow_enable(_adapter * adapter)10157 static void rtw_hal_wow_enable(_adapter *adapter)
10158 {
10159 struct registry_priv *registry_par = &adapter->registrypriv;
10160 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10161 struct security_priv *psecuritypriv = &adapter->securitypriv;
10162 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10163 struct sta_info *psta = NULL;
10164 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
10165 int res;
10166 u16 media_status_rpt;
10167 u8 no_wake = 0, i;
10168 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10169 _adapter *iface;
10170 #ifdef CONFIG_GPIO_WAKEUP
10171 u8 val8 = 0;
10172 #endif
10173
10174 #ifdef CONFIG_LPS_PG
10175 u8 lps_pg_hdl_id = 0;
10176 #endif
10177
10178
10179
10180 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
10181 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
10182 no_wake = 1;
10183
10184 RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
10185 rtw_hal_gate_bb(adapter, _TRUE);
10186
10187 for (i = 0; i < dvobj->iface_nums; i++) {
10188 iface = dvobj->padapters[i];
10189 /* Start Usb TxDMA */
10190 if(iface) {
10191 RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface));
10192 RTW_ENABLE_FUNC(iface, DF_TX_BIT);
10193 }
10194 }
10195
10196 #ifdef CONFIG_GTK_OL
10197 if (psecuritypriv->binstallKCK_KEK == _TRUE)
10198 rtw_hal_fw_sync_cam_id(adapter);
10199 #endif
10200 if (IS_HARDWARE_TYPE_8723B(adapter))
10201 rtw_hal_backup_rate(adapter);
10202
10203 rtw_hal_fw_dl(adapter, _TRUE);
10204 if(no_wake)
10205 media_status_rpt = RT_MEDIA_DISCONNECT;
10206 else
10207 media_status_rpt = RT_MEDIA_CONNECT;
10208 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10209 (u8 *)&media_status_rpt);
10210
10211 /* RX DMA stop */
10212 #if defined(CONFIG_RTL8188E)
10213 if (IS_HARDWARE_TYPE_8188E(adapter))
10214 rtw_hal_disable_tx_report(adapter);
10215 #endif
10216
10217 res = rtw_hal_pause_rx_dma(adapter);
10218 if (res == _FAIL)
10219 RTW_PRINT("[WARNING] pause RX DMA fail\n");
10220
10221 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10222 /* Reconfig RX_FF Boundary */
10223 rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
10224 #endif
10225
10226 /* redownload wow pattern */
10227 if(!no_wake)
10228 rtw_hal_dl_pattern(adapter, 1);
10229
10230 if (!pwrctl->wowlan_pno_enable) {
10231 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10232
10233 if (psta != NULL) {
10234 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10235 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10236 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10237 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10238 #endif
10239 if(!no_wake)
10240 rtw_sta_media_status_rpt(adapter, psta, 1);
10241 }
10242 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10243 else {
10244 if(registry_par->suspend_type == FW_IPS_WRC) {
10245 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10246 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10247 rtw_hal_set_default_port_id_cmd(adapter, 0);
10248 }
10249 }
10250 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10251 }
10252
10253 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10254 /* Enable CPWM2 only. */
10255 res = rtw_hal_enable_cpwm2(adapter);
10256 if (res == _FAIL)
10257 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
10258 #endif
10259 #ifdef CONFIG_GPIO_WAKEUP
10260 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10261 rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10262 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10263 #else
10264 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10265 if (pwrctl->is_high_active == 0)
10266 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10267 else
10268 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10269 GPIO_OUTPUT_LOW);
10270 #else
10271 val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
10272 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8);
10273 rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10274 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n",
10275 __func__, pwrctl->wowlan_gpio_index,
10276 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10277 pwrctl->is_high_active ? "HIGI" : "LOW");
10278 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10279 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10280 #endif /* CONFIG_GPIO_WAKEUP */
10281 /* Set WOWLAN H2C command. */
10282 RTW_PRINT("Set WOWLan cmd\n");
10283 rtw_hal_set_fw_wow_related_cmd(adapter, 1);
10284
10285 res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
10286
10287 if (res == _FALSE)
10288 RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
10289
10290 pwrctl->wowlan_wake_reason =
10291 rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10292
10293 RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
10294 pwrctl->wowlan_wake_reason);
10295 #ifdef CONFIG_GTK_OL_DBG
10296 dump_sec_cam(RTW_DBGDUMP, adapter);
10297 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
10298 #endif
10299
10300 #ifdef CONFIG_LPS_PG
10301 if (pwrctl->lps_level == LPS_PG) {
10302 lps_pg_hdl_id = LPS_PG_INFO_CFG;
10303 rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
10304 }
10305 #endif
10306
10307 #ifdef CONFIG_USB_HCI
10308 /* free adapter's resource */
10309 rtw_mi_intf_stop(adapter);
10310
10311 #endif
10312 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
10313 /* Invoid SE0 reset signal during suspending*/
10314 rtw_write8(adapter, REG_RSV_CTRL, 0x20);
10315 if (IS_8188F(pHalData->version_id) == FALSE
10316 && IS_8188GTV(pHalData->version_id) == FALSE)
10317 rtw_write8(adapter, REG_RSV_CTRL, 0x60);
10318 #endif
10319
10320 rtw_hal_gate_bb(adapter, _FALSE);
10321 }
10322
10323 #define DBG_WAKEUP_REASON
10324 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)10325 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
10326 {
10327 RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
10328 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)10329 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
10330 {
10331 if (RX_PAIRWISEKEY == reason)
10332 _dbg_wake_up_reason_string(adapter, "Rx pairwise key");
10333 else if (RX_GTK == reason)
10334 _dbg_wake_up_reason_string(adapter, "Rx GTK");
10335 else if (RX_FOURWAY_HANDSHAKE == reason)
10336 _dbg_wake_up_reason_string(adapter, "Rx four way handshake");
10337 else if (RX_DISASSOC == reason)
10338 _dbg_wake_up_reason_string(adapter, "Rx disassoc");
10339 else if (RX_DEAUTH == reason)
10340 _dbg_wake_up_reason_string(adapter, "Rx deauth");
10341 else if (RX_ARP_REQUEST == reason)
10342 _dbg_wake_up_reason_string(adapter, "Rx ARP request");
10343 else if (FW_DECISION_DISCONNECT == reason)
10344 _dbg_wake_up_reason_string(adapter, "FW detect disconnect");
10345 else if (RX_MAGIC_PKT == reason)
10346 _dbg_wake_up_reason_string(adapter, "Rx magic packet");
10347 else if (RX_UNICAST_PKT == reason)
10348 _dbg_wake_up_reason_string(adapter, "Rx unicast packet");
10349 else if (RX_PATTERN_PKT == reason)
10350 _dbg_wake_up_reason_string(adapter, "Rx pattern packet");
10351 else if (RTD3_SSID_MATCH == reason)
10352 _dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
10353 else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
10354 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
10355 else if (RX_REALWOW_V2_ACK_LOST == reason)
10356 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
10357 else if (ENABLE_FAIL_DMA_IDLE == reason)
10358 _dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
10359 else if (ENABLE_FAIL_DMA_PAUSE == reason)
10360 _dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
10361 else if (AP_OFFLOAD_WAKEUP == reason)
10362 _dbg_wake_up_reason_string(adapter, "AP offload wakeup");
10363 else if (CLK_32K_UNLOCK == reason)
10364 _dbg_wake_up_reason_string(adapter, "clk 32k unlock");
10365 else if (RTIME_FAIL_DMA_IDLE == reason)
10366 _dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
10367 else if (CLK_32K_LOCK == reason)
10368 _dbg_wake_up_reason_string(adapter, "clk 32k lock");
10369 else
10370 _dbg_wake_up_reason_string(adapter, "unknown reasoen");
10371 }
10372 #endif
10373
rtw_hal_wow_disable(_adapter * adapter)10374 static void rtw_hal_wow_disable(_adapter *adapter)
10375 {
10376 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10377 struct security_priv *psecuritypriv = &adapter->securitypriv;
10378 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10379 struct sta_info *psta = NULL;
10380 struct registry_priv *registry_par = &adapter->registrypriv;
10381 int res;
10382 u16 media_status_rpt;
10383
10384 RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
10385
10386 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
10387 RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");
10388 return;
10389 }
10390
10391 if (!pwrctl->wowlan_pno_enable) {
10392 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10393 if (psta != NULL)
10394 rtw_sta_media_status_rpt(adapter, psta, 0);
10395 else
10396 RTW_INFO("%s: psta is null\n", __func__);
10397 }
10398
10399 if (0) {
10400 RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
10401 RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
10402 RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
10403 RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
10404 }
10405
10406 pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10407
10408 RTW_PRINT("wakeup_reason: 0x%02x\n",
10409 pwrctl->wowlan_wake_reason);
10410 #ifdef DBG_WAKEUP_REASON
10411 _dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
10412 #endif
10413
10414 rtw_hal_set_fw_wow_related_cmd(adapter, 0);
10415
10416 res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
10417
10418 if (res == _FALSE) {
10419 RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
10420 rtw_hal_force_enable_rxdma(adapter);
10421 }
10422
10423 rtw_hal_gate_bb(adapter, _TRUE);
10424
10425 res = rtw_hal_pause_rx_dma(adapter);
10426 if (res == _FAIL)
10427 RTW_PRINT("[WARNING] pause RX DMA fail\n");
10428
10429 /* clean HW pattern match */
10430 rtw_hal_dl_pattern(adapter, 0);
10431
10432 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10433 /* config RXFF boundary to original */
10434 rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
10435 #endif
10436 rtw_hal_release_rx_dma(adapter);
10437
10438 #if defined(CONFIG_RTL8188E)
10439 if (IS_HARDWARE_TYPE_8188E(adapter))
10440 rtw_hal_enable_tx_report(adapter);
10441 #endif
10442
10443 if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10444 (pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
10445 (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
10446 rtw_hal_get_aoac_rpt(adapter);
10447 rtw_hal_update_sw_security_info(adapter);
10448 }
10449
10450 rtw_hal_fw_dl(adapter, _FALSE);
10451
10452 #ifdef CONFIG_GPIO_WAKEUP
10453
10454 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10455 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10456 #else
10457 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10458 if (pwrctl->is_high_active == 0)
10459 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10460 else
10461 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10462 GPIO_OUTPUT_LOW);
10463 #else
10464 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index
10465 , pwrctl->wowlan_gpio_output_state);
10466 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n",
10467 __func__, pwrctl->wowlan_gpio_index,
10468 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10469 pwrctl->is_high_active ? "HIGI" : "LOW");
10470 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10471 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10472 #endif /* CONFIG_GPIO_WAKEUP */
10473 if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
10474 (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
10475 (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10476 (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
10477
10478 media_status_rpt = RT_MEDIA_CONNECT;
10479 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10480 (u8 *)&media_status_rpt);
10481
10482 if (psta != NULL) {
10483 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10484 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10485 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10486 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10487 #endif
10488 rtw_sta_media_status_rpt(adapter, psta, 1);
10489 }
10490 }
10491 rtw_hal_gate_bb(adapter, _FALSE);
10492 }
10493 #endif /*CONFIG_WOWLAN*/
10494
10495 #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)10496 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
10497 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
10498 RSVDPAGE_LOC *rsvd_page_loc)
10499 {
10500 u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
10501 u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
10502 u8 CurtPktPageNum = 0;
10503
10504 /* P2P Beacon */
10505 rsvd_page_loc->LocP2PBeacon = *page_num;
10506 rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
10507 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10508 P2PBCNLength, _FALSE, _FALSE, _FALSE);
10509
10510 #if 0
10511 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
10512 __FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
10513 #endif
10514
10515 CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
10516
10517 *page_num += CurtPktPageNum;
10518
10519 index += (CurtPktPageNum * page_size);
10520 RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
10521
10522 /* P2P Probe rsp */
10523 rsvd_page_loc->LocP2PProbeRsp = *page_num;
10524 rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
10525 &P2PProbeRspLength);
10526 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10527 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
10528
10529 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", */
10530 /* __FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
10531
10532 CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
10533
10534 *page_num += CurtPktPageNum;
10535
10536 index += (CurtPktPageNum * page_size);
10537 RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
10538
10539 /* P2P nego rsp */
10540 rsvd_page_loc->LocNegoRsp = *page_num;
10541 rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
10542 &P2PNegoRspLength);
10543 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10544 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
10545
10546 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
10547 /* __FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
10548
10549 CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
10550
10551 *page_num += CurtPktPageNum;
10552
10553 index += (CurtPktPageNum * page_size);
10554 RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
10555
10556 /* P2P invite rsp */
10557 rsvd_page_loc->LocInviteRsp = *page_num;
10558 rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
10559 &P2PInviteRspLength);
10560 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10561 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
10562
10563 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
10564 /* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
10565
10566 CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
10567
10568 *page_num += CurtPktPageNum;
10569
10570 index += (CurtPktPageNum * page_size);
10571 RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
10572
10573 /* P2P provision discovery rsp */
10574 rsvd_page_loc->LocPDRsp = *page_num;
10575 rtw_hal_construct_P2PProvisionDisRsp(adapter,
10576 &pframe[index], &P2PPDRspLength);
10577
10578 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10579 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
10580
10581 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
10582 /* __FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
10583
10584 CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
10585
10586 *page_num += CurtPktPageNum;
10587
10588 *total_pkt_len = index + P2PPDRspLength;
10589 RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
10590
10591 index += (CurtPktPageNum * page_size);
10592
10593
10594 }
10595 #endif /* CONFIG_P2P_WOWLAN */
10596
10597 #ifdef CONFIG_LPS_PG
10598 #ifndef DBG_LPSPG_INFO_DUMP
10599 #define DBG_LPSPG_INFO_DUMP 1
10600 #endif
10601
10602 #include "hal_halmac.h"
10603
10604 #ifdef CONFIG_RTL8822C
rtw_lps_pg_set_dpk_info_rsvd_page(_adapter * adapter)10605 static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)
10606 {
10607 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10608 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10609 struct dm_struct *dm = adapter_to_phydm(adapter);
10610 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;
10611 u8 *info = NULL;
10612 u32 info_len;
10613 int ret = _FAIL;
10614
10615 /* get length */
10616 halrf_dpk_info_rsvd_page(dm, NULL, &info_len);
10617 if (!info_len) {
10618 RTW_ERR("get %s length fail\n", cache->name);
10619 goto exit;
10620 }
10621
10622 /* allocate buf */
10623 info = rtw_zmalloc(info_len);
10624 if (!info) {
10625 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10626 goto exit;
10627 }
10628
10629 /* get content */
10630 halrf_dpk_info_rsvd_page(dm, info, NULL);
10631
10632 if (rsvd_page_cache_update_data(cache, info, info_len)) {
10633
10634 #if (DBG_LPSPG_INFO_DUMP >= 1)
10635 RTW_INFO_DUMP(cache->name, info, info_len);
10636 #endif
10637
10638 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10639 ret = !ret ? _SUCCESS : _FAIL;
10640 if (ret != _SUCCESS) {
10641 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10642 goto free_mem;
10643 }
10644
10645 #if (DBG_LPSPG_INFO_DUMP >= 2)
10646 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10647 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10648 #endif
10649 }
10650
10651 free_mem:
10652 rtw_mfree(info, info_len);
10653
10654 exit:
10655 return ret;
10656 }
10657
rtw_lps_pg_set_iqk_info_rsvd_page(_adapter * adapter)10658 static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)
10659 {
10660 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10661 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10662 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10663 struct dm_struct *dm = adapter_to_phydm(adapter);
10664 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;
10665 u8 *info = NULL;
10666 u32 info_len = 0;
10667 int ret = _FAIL;
10668
10669 if (hal_data->RegIQKFWOffload) {
10670 rsvd_page_cache_free_data(cache);
10671 ret = _SUCCESS;
10672 goto exit;
10673 }
10674
10675 /* get length */
10676 halrf_iqk_info_rsvd_page(dm, NULL, &info_len);
10677 if (!info_len) {
10678 RTW_ERR("get %s length fail\n", cache->name);
10679 goto exit;
10680 }
10681
10682 /* allocate buf */
10683 info = rtw_zmalloc(info_len);
10684 if (!info) {
10685 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10686 goto exit;
10687 }
10688
10689 /* get content */
10690 halrf_iqk_info_rsvd_page(dm, info, NULL);
10691
10692 if (rsvd_page_cache_update_data(cache, info, info_len)) {
10693
10694 #if (DBG_LPSPG_INFO_DUMP >= 1)
10695 RTW_INFO_DUMP(cache->name, info, info_len);
10696 #endif
10697
10698 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10699 ret = !ret ? _SUCCESS : _FAIL;
10700 if (ret != _SUCCESS) {
10701 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10702 goto free_mem;
10703 }
10704
10705 #if (DBG_LPSPG_INFO_DUMP >= 2)
10706 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10707 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10708 #endif
10709 }
10710
10711 free_mem:
10712 rtw_mfree(info, info_len);
10713
10714 exit:
10715 return ret;
10716 }
10717 #endif /* CONFIG_RTL8822C */
10718
rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv * dvobj,_adapter * ld_sta_iface,u8 * buf,u32 * buf_size)10719 static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size)
10720 {
10721 #define LPS_PG_INFO_RSVD_LEN 16
10722
10723 if (buf) {
10724 _adapter *adapter = dvobj_get_primary_adapter(dvobj);
10725 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10726 struct sta_info *psta;
10727 #ifdef CONFIG_MBSSID_CAM
10728 u8 cam_id = INVALID_CAM_ID;
10729 #endif
10730 u8 *psec_cam_id = buf + 8;
10731 u8 sec_cam_num = 0;
10732 u8 drv_rsvdpage_num = 0;
10733
10734 if (ld_sta_iface) {
10735 psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv));
10736 if (!psta) {
10737 RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
10738 rtw_warn_on(1);
10739 goto size_chk;
10740 }
10741 /*Byte 0 - used macid*/
10742 LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);
10743 RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
10744 }
10745
10746 #ifdef CONFIG_MBSSID_CAM
10747 /*Byte 1 - used BSSID CAM entry*/
10748 cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
10749 if (cam_id != INVALID_CAM_ID)
10750 LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);
10751 RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
10752 #endif
10753
10754 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
10755 /*Btye 2 - Max used Pattern Match CAM entry*/
10756 if (pwrpriv->wowlan_mode == _TRUE
10757 && ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
10758 LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);
10759 RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
10760 }
10761 #endif
10762 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
10763 /*Btye 3 - Max MU rate table Group ID*/
10764 LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);
10765 RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
10766 #endif
10767
10768 /*Btye 8 ~15 - used Security CAM entry */
10769 sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
10770
10771 /*Btye 4 - used Security CAM entry number*/
10772 if (sec_cam_num < 8)
10773 LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);
10774 RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
10775
10776 /*Btye 5 - Txbuf used page number for fw offload*/
10777 if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
10778 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
10779 else
10780 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
10781 LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);
10782 RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
10783 }
10784
10785 size_chk:
10786 if (buf_size)
10787 *buf_size = LPS_PG_INFO_RSVD_LEN;
10788 }
10789
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)10790 static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
10791 {
10792 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10793 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10794 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;
10795 u8 *info = NULL;
10796 u32 info_len = 0;
10797 int ret = _FAIL;
10798
10799 /* get length */
10800 rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len);
10801 if (!info_len) {
10802 RTW_ERR("get %s length fail\n", cache->name);
10803 goto exit;
10804 }
10805
10806 /* allocate buf */
10807 info = rtw_zmalloc(info_len);
10808 if (!info) {
10809 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10810 goto exit;
10811 }
10812
10813 /* get content */
10814 rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL);
10815
10816 if (rsvd_page_cache_update_data(cache, info, info_len)) {
10817
10818 #if (DBG_LPSPG_INFO_DUMP >= 1)
10819 RTW_INFO_DUMP(cache->name, info, info_len);
10820 #endif
10821
10822 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10823 ret = !ret ? _SUCCESS : _FAIL;
10824 if (ret != _SUCCESS) {
10825 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10826 goto free_mem;
10827 }
10828
10829 #if (DBG_LPSPG_INFO_DUMP >= 2)
10830 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10831 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10832 #endif
10833 }
10834
10835 free_mem:
10836 rtw_mfree(info, info_len);
10837
10838 exit:
10839 return ret;
10840 }
10841
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)10842 static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index
10843 , u8 txdesc_size, u32 page_size, u8 *total_page_num
10844 , bool is_wow_mode, _adapter *ld_sta_iface, bool only_get_page_num)
10845 {
10846 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10847 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10848 struct rsvd_page_cache_t *cache;
10849 bool rsvd = 1;
10850 u8 *pos;
10851 u32 len;
10852
10853 if (is_wow_mode) {
10854 /* lps_level will not change when enter wow_mode */
10855 if (pwrctl->lps_level != LPS_PG)
10856 rsvd = 0;
10857 } else {
10858 if (!only_get_page_num && !ld_sta_iface)
10859 rsvd = 0;
10860 }
10861
10862 pos = only_get_page_num ? NULL : frame + *index;
10863
10864 #ifdef CONFIG_RTL8822C
10865 if (IS_8822C_SERIES(hal_data->version_id)) {
10866 /* LPSPG_DPK_INFO */
10867 cache = &pwrctl->lpspg_dpk_info;
10868 if (rsvd) {
10869 if (pwrctl->lps_level != LPS_PG)
10870 pos = NULL;
10871 len = 0;
10872 halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10873 #if (DBG_LPSPG_INFO_DUMP >= 1)
10874 if (pos)
10875 RTW_INFO_DUMP(cache->name, pos, len);
10876 #endif
10877 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10878 *total_page_num += cache->page_num;
10879 *index += page_size * cache->page_num;
10880 pos = only_get_page_num ? NULL : frame + *index;
10881 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10882 } else
10883 rsvd_page_cache_free(cache);
10884
10885 /* LPSPG_IQK_INFO */
10886 cache = &pwrctl->lpspg_iqk_info;
10887 if (rsvd
10888 /* RegIQKFWOffload will not change when enter wow_mode */
10889 && !(is_wow_mode && hal_data->RegIQKFWOffload)
10890 ) {
10891 if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)
10892 pos = NULL;
10893 len = 0;
10894 halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10895 #if (DBG_LPSPG_INFO_DUMP >= 1)
10896 if (pos)
10897 RTW_INFO_DUMP(cache->name, pos, len);
10898 #endif
10899 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10900 *total_page_num += cache->page_num;
10901 *index += page_size * cache->page_num;
10902 pos = only_get_page_num ? NULL : frame + *index;
10903 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10904 } else
10905 rsvd_page_cache_free(cache);
10906 }
10907 #endif
10908
10909 /* LPSPG_INFO */
10910 cache = &pwrctl->lpspg_info;
10911 if (rsvd) {
10912 if (pwrctl->lps_level != LPS_PG)
10913 pos = NULL;
10914 rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len);
10915 #if (DBG_LPSPG_INFO_DUMP >= 1)
10916 if (pos)
10917 RTW_INFO_DUMP(cache->name, pos, len);
10918 #endif
10919 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10920 *total_page_num += cache->page_num;
10921 *index += page_size * cache->page_num;
10922 pos = only_get_page_num ? NULL : frame + *index;
10923 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10924 } else
10925 rsvd_page_cache_free(cache);
10926 }
10927
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)10928 u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
10929 {
10930 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10931 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10932
10933 u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
10934 u8 ret = _FAIL;
10935
10936 if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
10937 SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1); /*SecurityCAM_En*/
10938
10939 #ifdef CONFIG_MBSSID_CAM
10940 SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1); /*BSSIDCAM_En*/
10941 #endif
10942
10943 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
10944 if (pwrpriv->wowlan_mode == _TRUE &&
10945 check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
10946
10947 SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/
10948 }
10949 #endif
10950
10951 #ifdef CONFIG_MACID_SEARCH
10952 SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1); /*MACIDSearch_En*/
10953 #endif
10954
10955 #ifdef CONFIG_TX_SC
10956 SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1); /*TXSC_En*/
10957 #endif
10958
10959 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
10960 SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1); /*MURateTable_En*/
10961 #endif
10962
10963 SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);
10964
10965 #ifdef CONFIG_RTL8822C
10966 if (pwrpriv->bFwCurrentInPSMode == _FALSE) {
10967 SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);
10968 if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
10969 SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);
10970 } else {
10971 SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0);
10972 if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
10973 SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0);
10974 }
10975 #endif
10976
10977 #if (DBG_LPSPG_INFO_DUMP >= 1)
10978 RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);
10979 #endif
10980
10981 ret = rtw_hal_fill_h2c_cmd(adapter,
10982 H2C_LPS_PG_INFO,
10983 H2C_LPS_PG_INFO_LEN,
10984 lpspg_info);
10985 return ret;
10986 }
rtw_hal_set_lps_pg_info(_adapter * adapter)10987 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
10988 {
10989 u8 ret = _FAIL;
10990 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10991
10992 if (pwrpriv->lpspg_info.loc == 0) {
10993 RTW_ERR("%s lpspg_info.loc = 0\n", __func__);
10994 rtw_warn_on(1);
10995 return ret;
10996 }
10997 #ifdef CONFIG_RTL8822C
10998 rtw_lps_pg_set_dpk_info_rsvd_page(adapter);
10999 rtw_lps_pg_set_iqk_info_rsvd_page(adapter);
11000 #endif
11001 rtw_hal_set_lps_pg_info_rsvd_page(adapter);
11002
11003 ret = rtw_hal_set_lps_pg_info_cmd(adapter);
11004
11005 return ret;
11006 }
11007
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)11008 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
11009 {
11010 #if 0
11011 if (sta->cmn.ra_info.rssi_level >= 4)
11012 sta->lps_pg_rssi_lv = 3; /*RSSI High - 1SS_VHT_MCS7*/
11013 else if (sta->cmn.ra_info.rssi_level >= 2)
11014 sta->lps_pg_rssi_lv = 2; /*RSSI Middle - 1SS_VHT_MCS3*/
11015 else
11016 sta->lps_pg_rssi_lv = 1; /*RSSI Lower - Lowest_rate*/
11017 #else
11018 sta->lps_pg_rssi_lv = 0;
11019 #endif
11020 RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
11021 __func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
11022 }
11023
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)11024 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
11025 {
11026 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
11027 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11028 struct sta_priv *pstapriv = &adapter->stapriv;
11029 struct sta_info *sta;
11030
11031 sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
11032
11033 switch (hdl_id) {
11034 case LPS_PG_INFO_CFG:
11035 rtw_hal_set_lps_pg_info(adapter);
11036 break;
11037 case LPS_PG_REDLEMEM:
11038 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11039 break;
11040
11041 /*set xmit_block*/
11042 rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11043 if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
11044 rtw_warn_on(1);
11045 /*clearn xmit_block*/
11046 rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11047 break;
11048 case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
11049 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11050 break;
11051
11052 if (sta)
11053 rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
11054 break;
11055 case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
11056 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11057 break;
11058
11059 if (sta) {
11060 rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
11061 rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
11062 sta->lps_pg_rssi_lv = 0;
11063 }
11064 break;
11065
11066 default:
11067 break;
11068 }
11069 }
11070
11071 #endif /*CONFIG_LPS_PG*/
11072
_rtw_mi_assoc_if_num(_adapter * adapter)11073 static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
11074 {
11075 u8 mi_iface_num = 0;
11076
11077 if (0) {
11078 RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
11079 RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
11080 RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11081 RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
11082 RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
11083 /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
11084 /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
11085 }
11086
11087 mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
11088 DEV_AP_NUM(adapter_to_dvobj(adapter)) +
11089 DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11090 return mi_iface_num;
11091 }
11092 #ifdef CONFIG_CONCURRENT_MODE
_rtw_search_sta_iface(_adapter * adapter)11093 static _adapter *_rtw_search_sta_iface(_adapter *adapter)
11094 {
11095 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11096 _adapter *iface = NULL;
11097 _adapter *sta_iface = NULL;
11098 int i;
11099
11100 for (i = 0; i < dvobj->iface_nums; i++) {
11101 iface = dvobj->padapters[i];
11102 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
11103 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11104 sta_iface = iface;
11105 break;
11106 }
11107 }
11108 }
11109 return sta_iface;
11110 }
11111 #if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)
_rtw_search_ap_iface(_adapter * adapter)11112 static _adapter *_rtw_search_ap_iface(_adapter *adapter)
11113 {
11114 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11115 _adapter *iface = NULL;
11116 _adapter *ap_iface = NULL;
11117 int i;
11118
11119 for (i = 0; i < dvobj->iface_nums; i++) {
11120 iface = dvobj->padapters[i];
11121 if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
11122 ap_iface = iface;
11123 break;
11124 }
11125 }
11126 return ap_iface;
11127 }
11128 #endif/*CONFIG_AP_MODE*/
11129 #endif/*CONFIG_CONCURRENT_MODE*/
11130
11131 #ifdef CONFIG_CUSTOMER01_SMART_ANTENNA
rtw_hal_set_pathb_phase(_adapter * adapter,u8 phase_idx)11132 void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)
11133 {
11134 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
11135 struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
11136
11137 return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);
11138 }
11139 #endif
11140
11141 /*
11142 * Description: Fill the reserved packets that FW will use to RSVD page.
11143 * Now we just send 4 types packet to rsvd page.
11144 * (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
11145 * Input:
11146 * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
11147 * so we need to set the packet length to total lengh.
11148 * TRUE: At the second time, we should send the first packet (default:beacon)
11149 * to Hw again and set the lengh in descriptor to the real beacon lengh.
11150 * page_num - The amount of reserved page which driver need.
11151 * If this is not NULL, this function doesn't real download reserved
11152 * page, but just count the number of reserved page.
11153 *
11154 * 2009.10.15 by tynli.
11155 * 2017.06.20 modified by Lucas.
11156 *
11157 * Page Size = 128: 8188e, 8723a/b, 8192c/d,
11158 * Page Size = 256: 8192e, 8821a
11159 * Page Size = 512: 8812a
11160 */
11161
11162 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)11163 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
11164 {
11165 PHAL_DATA_TYPE pHalData;
11166 struct xmit_frame *pcmdframe = NULL;
11167 struct pkt_attrib *pattrib;
11168 struct xmit_priv *pxmitpriv;
11169 struct pwrctrl_priv *pwrctl;
11170 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11171 u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
11172 u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
11173 u32 ProbeReqLength = 0, NullFunctionDataLength = 0;
11174 u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
11175 u8 TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
11176 u8 *ReservedPagePacket;
11177 u16 BufIndex = 0;
11178 u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
11179 RSVDPAGE_LOC RsvdPageLoc;
11180 struct registry_priv *registry_par = &adapter->registrypriv;
11181
11182 #ifdef DBG_FW_DEBUG_MSG_PKT
11183 u32 fw_dbg_msg_pkt_len = 0;
11184 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11185
11186 #ifdef DBG_CONFIG_ERROR_DETECT
11187 struct sreset_priv *psrtpriv;
11188 #endif /* DBG_CONFIG_ERROR_DETECT */
11189
11190 #ifdef CONFIG_MCC_MODE
11191 u8 dl_mcc_page = _FAIL;
11192 #endif /* CONFIG_MCC_MODE */
11193 u8 nr_assoc_if;
11194
11195 _adapter *sta_iface = NULL;
11196 _adapter *ap_iface = NULL;
11197
11198 bool is_wow_mode = _FALSE;
11199
11200 pHalData = GET_HAL_DATA(adapter);
11201 #ifdef DBG_CONFIG_ERROR_DETECT
11202 psrtpriv = &pHalData->srestpriv;
11203 #endif
11204 pxmitpriv = &adapter->xmitpriv;
11205 pwrctl = adapter_to_pwrctl(adapter);
11206
11207 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
11208
11209 if (PageSize == 0) {
11210 RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
11211 return;
11212 }
11213 nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
11214
11215 if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
11216 pwrctl->wowlan_ap_mode == _TRUE ||
11217 pwrctl->wowlan_p2p_mode == _TRUE)
11218 is_wow_mode = _TRUE;
11219
11220 /*page_num for init time to get rsvd page number*/
11221 /* Prepare ReservedPagePacket */
11222 if (page_num) {
11223 ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
11224 if (!ReservedPagePacket) {
11225 RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11226 *page_num = 0xFF;
11227 return;
11228 }
11229 RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm ==>\n",
11230 FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11231
11232 } else {
11233 if (is_wow_mode)
11234 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11235 else
11236 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11237
11238 RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
11239 FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
11240
11241 MaxRsvdPageBufSize = RsvdPageNum * PageSize;
11242 if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
11243 RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
11244 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
11245 rtw_warn_on(1);
11246 return;
11247 }
11248
11249 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
11250 if (pcmdframe == NULL) {
11251 RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11252 return;
11253 }
11254
11255 ReservedPagePacket = pcmdframe->buf_addr;
11256 }
11257
11258 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
11259
11260 BufIndex = TxDescOffset;
11261
11262 /*======== beacon content =======*/
11263 rtw_hal_construct_beacon(adapter,
11264 &ReservedPagePacket[BufIndex], &BeaconLength);
11265
11266 /*
11267 * When we count the first page size, we need to reserve description size for the RSVD
11268 * packet, it will be filled in front of the packet in TXPKTBUF.
11269 */
11270 BeaconLength = MAX_BEACON_LEN - TxDescLen;
11271 CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
11272
11273 #ifdef CONFIG_FW_HANDLE_TXBCN
11274 CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
11275 #endif
11276 TotalPageNum += CurtPktPageNum;
11277
11278 BufIndex += (CurtPktPageNum * PageSize);
11279
11280 RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11281
11282 /*======== probe response content ========*/
11283 if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
11284 #ifdef CONFIG_CONCURRENT_MODE
11285 if (nr_assoc_if >= 2)
11286 RTW_ERR("Not support > 2 net-interface in WOW\n");
11287 #endif
11288 /* (4) probe response*/
11289 RsvdPageLoc.LocProbeRsp = TotalPageNum;
11290 rtw_hal_construct_ProbeRsp(
11291 adapter, &ReservedPagePacket[BufIndex],
11292 &ProbeRspLength,
11293 _FALSE);
11294 rtw_hal_fill_fake_txdesc(adapter,
11295 &ReservedPagePacket[BufIndex - TxDescLen],
11296 ProbeRspLength, _FALSE, _FALSE, _FALSE);
11297
11298 CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
11299 TotalPageNum += CurtPktPageNum;
11300 TotalPacketLen = BufIndex + ProbeRspLength;
11301 BufIndex += (CurtPktPageNum * PageSize);
11302 RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11303 goto download_page;
11304 }
11305
11306 /*======== ps-poll content * 1 page ========*/
11307 sta_iface = adapter;
11308 #ifdef CONFIG_CONCURRENT_MODE
11309 if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
11310 sta_iface = _rtw_search_sta_iface(adapter);
11311 RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
11312 }
11313 #endif
11314
11315 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11316 RsvdPageLoc.LocPsPoll = TotalPageNum;
11317 RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
11318 rtw_hal_construct_PSPoll(sta_iface,
11319 &ReservedPagePacket[BufIndex], &PSPollLength);
11320 rtw_hal_fill_fake_txdesc(sta_iface,
11321 &ReservedPagePacket[BufIndex - TxDescLen],
11322 PSPollLength, _TRUE, _FALSE, _FALSE);
11323
11324 CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
11325
11326 TotalPageNum += CurtPktPageNum;
11327
11328 BufIndex += (CurtPktPageNum * PageSize);
11329 RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11330 }
11331
11332 #ifdef CONFIG_MCC_MODE
11333 /*======== MCC * n page ======== */
11334 if (MCC_EN(adapter)) {/*Normal mode*/
11335 dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
11336 &BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
11337 } else {
11338 dl_mcc_page = _FAIL;
11339 }
11340
11341 if (dl_mcc_page == _FAIL)
11342 #endif /* CONFIG_MCC_MODE */
11343 { /*======== null data * 1 page ======== */
11344 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11345 RsvdPageLoc.LocNullData = TotalPageNum;
11346 RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
11347 rtw_hal_construct_NullFunctionData(
11348 sta_iface,
11349 &ReservedPagePacket[BufIndex],
11350 &NullDataLength,
11351 _FALSE, 0, 0, _FALSE);
11352 rtw_hal_fill_fake_txdesc(sta_iface,
11353 &ReservedPagePacket[BufIndex - TxDescLen],
11354 NullDataLength, _FALSE, _FALSE, _FALSE);
11355
11356 CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
11357
11358 TotalPageNum += CurtPktPageNum;
11359
11360 BufIndex += (CurtPktPageNum * PageSize);
11361 RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11362 }
11363 }
11364
11365 /*======== Qos null data * 1 page ======== */
11366 if (pwrctl->wowlan_mode == _FALSE ||
11367 pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11368 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11369 RsvdPageLoc.LocQosNull = TotalPageNum;
11370 RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
11371 rtw_hal_construct_NullFunctionData(sta_iface,
11372 &ReservedPagePacket[BufIndex],
11373 &QosNullLength,
11374 _TRUE, 0, 0, _FALSE);
11375 rtw_hal_fill_fake_txdesc(sta_iface,
11376 &ReservedPagePacket[BufIndex - TxDescLen],
11377 QosNullLength, _FALSE, _FALSE, _FALSE);
11378
11379 CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
11380 PageSize);
11381
11382 TotalPageNum += CurtPktPageNum;
11383
11384 BufIndex += (CurtPktPageNum * PageSize);
11385 RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11386 }
11387 }
11388
11389 #ifdef CONFIG_BT_COEXIST
11390 /*======== BT Qos null data * 1 page ======== */
11391 if (pwrctl->wowlan_mode == _FALSE ||
11392 pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11393
11394 ap_iface = adapter;
11395 #ifdef CONFIG_CONCURRENT_MODE
11396 if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) { /*DEV_AP_STARTING_NUM*/
11397 ap_iface = _rtw_search_ap_iface(adapter);
11398 RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
11399 }
11400 #endif
11401
11402 if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
11403 RsvdPageLoc.LocBTQosNull = TotalPageNum;
11404
11405 RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
11406
11407 rtw_hal_construct_NullFunctionData(ap_iface,
11408 &ReservedPagePacket[BufIndex],
11409 &BTQosNullLength,
11410 _TRUE, 0, 0, _FALSE);
11411
11412 rtw_hal_fill_fake_txdesc(ap_iface,
11413 &ReservedPagePacket[BufIndex - TxDescLen],
11414 BTQosNullLength, _FALSE, _TRUE, _FALSE);
11415
11416 CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
11417 PageSize);
11418
11419 TotalPageNum += CurtPktPageNum;
11420 BufIndex += (CurtPktPageNum * PageSize);
11421
11422 RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11423 }
11424 }
11425 #endif /* CONFIG_BT_COEXIT */
11426
11427 TotalPacketLen = BufIndex;
11428
11429 #ifdef DBG_FW_DEBUG_MSG_PKT
11430 /*======== FW DEBUG MSG * n page ======== */
11431 RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
11432 RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
11433 rtw_hal_construct_fw_dbg_msg_pkt(
11434 adapter,
11435 &ReservedPagePacket[BufIndex],
11436 &fw_dbg_msg_pkt_len);
11437
11438 rtw_hal_fill_fake_txdesc(adapter,
11439 &ReservedPagePacket[BufIndex - TxDescLen],
11440 fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
11441
11442 CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
11443
11444 if (CurtPktPageNum < 2)
11445 CurtPktPageNum = 2; /*Need at least 2 rsvd page*/
11446 TotalPageNum += CurtPktPageNum;
11447
11448 TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
11449 BufIndex += (CurtPktPageNum * PageSize);
11450 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11451
11452 #ifdef CONFIG_LPS_PG
11453 rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex
11454 , TxDescLen, PageSize, &TotalPageNum, is_wow_mode
11455 , (sta_iface && MLME_IS_STA(sta_iface) && MLME_IS_ASOC(sta_iface)) ? sta_iface : NULL
11456 , page_num ? 1 : 0
11457 );
11458 TotalPacketLen = BufIndex;
11459 #endif
11460
11461 #ifdef CONFIG_WOWLAN
11462 /*======== WOW * n page ======== */
11463 if (pwrctl->wowlan_mode == _TRUE &&
11464 pwrctl->wowlan_in_resume == _FALSE &&
11465 check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {/*WOW mode*/
11466 rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11467 BufIndex, TxDescLen, PageSize,
11468 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11469 }
11470 #endif /* CONFIG_WOWLAN */
11471
11472 #ifdef CONFIG_P2P_WOWLAN
11473 /*======== P2P WOW * n page ======== */
11474 if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
11475 rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11476 BufIndex, TxDescLen, PageSize,
11477 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11478 }
11479 #endif /* CONFIG_P2P_WOWLAN */
11480
11481 /*Note: BufIndex already add a TxDescOffset offset in first Beacon page
11482 * The "TotalPacketLen" is calculate by BufIndex.
11483 * We need to decrease TxDescOffset before doing length check. by yiwei
11484 */
11485 TotalPacketLen = TotalPacketLen - TxDescOffset;
11486
11487 download_page:
11488 if (page_num) {
11489 *page_num = TotalPageNum;
11490 rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
11491 ReservedPagePacket = NULL;
11492 RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
11493 FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11494 return;
11495 }
11496
11497 /* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
11498 RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
11499 __func__, TotalPageNum, TotalPacketLen);
11500
11501 if (TotalPacketLen > MaxRsvdPageBufSize) {
11502 RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
11503 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
11504 rtw_warn_on(1);
11505 goto error;
11506 } else {
11507 /* update attribute */
11508 pattrib = &pcmdframe->attrib;
11509 update_mgntframe_attrib(adapter, pattrib);
11510 pattrib->qsel = QSLT_BEACON;
11511 pattrib->pktlen = TotalPacketLen;
11512 pattrib->last_txcmdsz = TotalPacketLen;
11513 #ifdef CONFIG_PCI_HCI
11514 dump_mgntframe(adapter, pcmdframe);
11515 #else
11516 dump_mgntframe_and_wait(adapter, pcmdframe, 100);
11517 #endif
11518 }
11519
11520 RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
11521 __func__, TotalPacketLen, TotalPageNum);
11522 #ifdef DBG_DUMP_SET_RSVD_PAGE
11523 RTW_INFO(" ==================================================\n");
11524 RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
11525 RTW_INFO(" ==================================================\n");
11526 #endif
11527
11528
11529 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
11530 || MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
11531 rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
11532 #ifdef DBG_FW_DEBUG_MSG_PKT
11533 rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
11534 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11535 #ifdef CONFIG_WOWLAN
11536 if (pwrctl->wowlan_mode == _TRUE &&
11537 pwrctl->wowlan_in_resume == _FALSE)
11538 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11539 #endif /* CONFIG_WOWLAN */
11540 #ifdef CONFIG_AP_WOWLAN
11541 if (pwrctl->wowlan_ap_mode == _TRUE)
11542 rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
11543 #endif /* CONFIG_AP_WOWLAN */
11544 } else if (pwrctl->wowlan_pno_enable) {
11545 #ifdef CONFIG_PNO_SUPPORT
11546 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11547 if (pwrctl->wowlan_in_resume)
11548 rtw_hal_set_scan_offload_info_cmd(adapter,
11549 &RsvdPageLoc, 0);
11550 else
11551 rtw_hal_set_scan_offload_info_cmd(adapter,
11552 &RsvdPageLoc, 1);
11553 #endif /* CONFIG_PNO_SUPPORT */
11554 }
11555
11556 #ifdef CONFIG_P2P_WOWLAN
11557 if (_TRUE == pwrctl->wowlan_p2p_mode)
11558 rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
11559 #endif /* CONFIG_P2P_WOWLAN */
11560
11561 return;
11562 error:
11563 rtw_free_xmitframe(pxmitpriv, pcmdframe);
11564 }
11565
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)11566 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
11567 {
11568 if (finished)
11569 rtw_mi_tx_beacon_hdl(adapter);
11570 else
11571 _rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
11572 }
11573
11574 /**
11575 * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
11576 * @adapter: struct _ADAPTER*
11577 *
11578 * Caculate needed reserved page number.
11579 * In different state would get different number, for example normal mode and
11580 * WOW mode would need different reserved page size.
11581 *
11582 * Return the number of reserved page which driver need.
11583 */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)11584 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
11585 {
11586 u8 num = 0;
11587
11588
11589 _rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
11590
11591 return num;
11592 }
11593
11594 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
hw_var_set_bcn_func(_adapter * adapter,u8 enable)11595 static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
11596 {
11597 u32 bcn_ctrl_reg;
11598
11599 #ifdef CONFIG_CONCURRENT_MODE
11600 if (adapter->hw_port == HW_PORT1)
11601 bcn_ctrl_reg = REG_BCN_CTRL_1;
11602 else
11603 #endif
11604 bcn_ctrl_reg = REG_BCN_CTRL;
11605
11606 if (enable)
11607 rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
11608 else {
11609 u8 val8;
11610
11611 val8 = rtw_read8(adapter, bcn_ctrl_reg);
11612 val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
11613
11614 #ifdef CONFIG_BT_COEXIST
11615 if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
11616 /* Always enable port0 beacon function for PSTDMA */
11617 if (REG_BCN_CTRL == bcn_ctrl_reg)
11618 val8 |= EN_BCN_FUNCTION;
11619 }
11620 #endif
11621
11622 rtw_write8(adapter, bcn_ctrl_reg, val8);
11623 }
11624
11625 #ifdef CONFIG_RTL8192F
11626 if (IS_HARDWARE_TYPE_8192F(adapter)) {
11627 u16 val16, val16_ori;
11628
11629 val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
11630
11631 #ifdef CONFIG_CONCURRENT_MODE
11632 if (adapter->hw_port == HW_PORT1) {
11633 if (enable)
11634 val16 |= EN_PORT_1_FUNCTION;
11635 else
11636 val16 &= ~EN_PORT_1_FUNCTION;
11637 } else
11638 #endif
11639 {
11640 if (enable)
11641 val16 |= EN_PORT_0_FUNCTION;
11642 else
11643 val16 &= ~EN_PORT_0_FUNCTION;
11644
11645 #ifdef CONFIG_BT_COEXIST
11646 if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
11647 val16 |= EN_PORT_0_FUNCTION;
11648 #endif
11649 }
11650
11651 if (val16 != val16_ori)
11652 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, val16);
11653 }
11654 #endif
11655 }
11656 #endif
11657
11658 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
hw_var_set_mlme_disconnect(_adapter * adapter)11659 static void hw_var_set_mlme_disconnect(_adapter *adapter)
11660 {
11661 u8 val8;
11662
11663 /* reject all data frames */
11664 #ifdef CONFIG_CONCURRENT_MODE
11665 if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11666 #endif
11667 rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
11668
11669 #ifdef CONFIG_CONCURRENT_MODE
11670 if (adapter->hw_port == HW_PORT1) {
11671 /* reset TSF1 */
11672 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
11673
11674 /* disable update TSF1 */
11675 rtw_iface_disable_tsf_update(adapter);
11676
11677 if (!IS_HARDWARE_TYPE_8723D(adapter)
11678 && !IS_HARDWARE_TYPE_8192F(adapter)
11679 && !IS_HARDWARE_TYPE_8710B(adapter)
11680 ) {
11681 /* disable Port1's beacon function */
11682 val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
11683 val8 &= ~EN_BCN_FUNCTION;
11684 rtw_write8(adapter, REG_BCN_CTRL_1, val8);
11685 }
11686 } else
11687 #endif
11688 {
11689 /* reset TSF */
11690 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
11691
11692 /* disable update TSF */
11693 rtw_iface_disable_tsf_update(adapter);
11694 }
11695 }
11696 #endif
11697
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 enable)11698 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
11699 {
11700 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11701 u16 value_rxfltmap2;
11702
11703 #ifdef DBG_IFACE_STATUS
11704 DBG_IFACE_STATUS_DUMP(adapter);
11705 #endif
11706
11707 #ifdef CONFIG_FIND_BEST_CHANNEL
11708 /* Receive all data frames */
11709 value_rxfltmap2 = 0xFFFF;
11710 #else
11711 /* not to receive data frame */
11712 value_rxfltmap2 = 0;
11713 #endif
11714
11715 if (enable) { /* under sitesurvey */
11716 /*
11717 * 1. configure REG_RXFLTMAP2
11718 * 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
11719 * 3. config RCR to receive different BSSID BCN or probe rsp
11720 */
11721 rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
11722
11723 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
11724
11725 /* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */
11726 #if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11727 hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);
11728 hal_data->RegRRSR &= 0x000FFFFF;
11729 #endif
11730
11731 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11732 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11733 /* set 718[1:0]=2'b00 to avoid BF scan hang */
11734 hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
11735 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
11736 }
11737 #endif
11738
11739 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11740 StopTxBeacon(adapter);
11741 } else { /* sitesurvey done */
11742 /*
11743 * 1. enable rx data frame
11744 * 2. config RCR not to receive different BSSID BCN or probe rsp
11745 * 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict
11746 * so, we enable TSF update when rx first BCN after sitesurvey done
11747 */
11748 if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) {
11749 /* enable to rx data frame */
11750 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11751 }
11752
11753 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
11754
11755 /* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */
11756 #if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11757 rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);
11758 #endif
11759
11760 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11761 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11762 /* Restore orignal 0x718 setting*/
11763 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
11764 }
11765 #endif
11766
11767 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11768 ResumeTxBeacon(adapter);
11769 rtw_mi_tx_beacon_hdl(adapter);
11770 }
11771 }
11772 }
11773
11774 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
hw_var_set_mlme_join(_adapter * adapter,u8 type)11775 static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
11776 {
11777 u8 val8;
11778 u16 val16;
11779 u32 val32;
11780 u8 RetryLimit = RL_VAL_STA;
11781 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11782 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11783
11784 #ifdef CONFIG_CONCURRENT_MODE
11785 if (type == 0) {
11786 /* prepare to join */
11787 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11788 StopTxBeacon(adapter);
11789
11790 /* enable to rx data frame.Accept all data frame */
11791 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11792
11793 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11794 RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11795 else /* Ad-hoc Mode */
11796 RetryLimit = RL_VAL_AP;
11797
11798 rtw_iface_enable_tsf_update(adapter);
11799
11800 } else if (type == 1) {
11801 /* joinbss_event call back when join res < 0 */
11802 if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11803 rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11804
11805 rtw_iface_disable_tsf_update(adapter);
11806
11807 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11808 ResumeTxBeacon(adapter);
11809
11810 /* reset TSF 1/2 after ResumeTxBeacon */
11811 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11812 }
11813
11814 } else if (type == 2) {
11815 /* sta add event call back */
11816 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
11817 /* fixed beacon issue for 8191su........... */
11818 rtw_write8(adapter, 0x542 , 0x02);
11819 RetryLimit = RL_VAL_AP;
11820 }
11821
11822 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11823 ResumeTxBeacon(adapter);
11824
11825 /* reset TSF 1/2 after ResumeTxBeacon */
11826 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11827 }
11828 }
11829
11830 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11831 rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11832 #else /* !CONFIG_CONCURRENT_MODE */
11833 if (type == 0) { /* prepare to join */
11834 /* enable to rx data frame.Accept all data frame */
11835 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11836
11837 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11838 RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11839 else /* Ad-hoc Mode */
11840 RetryLimit = RL_VAL_AP;
11841
11842 rtw_iface_enable_tsf_update(adapter);
11843
11844 } else if (type == 1) { /* joinbss_event call back when join res < 0 */
11845 rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11846
11847 rtw_iface_disable_tsf_update(adapter);
11848
11849 } else if (type == 2) { /* sta add event call back */
11850 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
11851 RetryLimit = RL_VAL_AP;
11852 }
11853
11854 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11855 rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11856 #endif /* !CONFIG_CONCURRENT_MODE */
11857 }
11858 #endif
11859
11860 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)11861 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
11862 {
11863 u8 buf[2];
11864 int ret;
11865
11866 if (reset_port == HW_PORT0) {
11867 buf[0] = 0x1;
11868 buf[1] = 0;
11869 } else {
11870 buf[0] = 0x0;
11871 buf[1] = 0x1;
11872 }
11873
11874 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
11875
11876 return ret;
11877 }
11878
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)11879 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
11880 {
11881 u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
11882 u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
11883 REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
11884 int ret;
11885
11886 /* site survey will cause reset tsf fail */
11887 rtw_mi_buddy_scan_abort(adapter, _FALSE);
11888 reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
11889 ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
11890 if (ret != _SUCCESS)
11891 return ret;
11892
11893 while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
11894 rtw_msleep_os(100);
11895 loop_cnt++;
11896 reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
11897 }
11898
11899 return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
11900 }
11901 #endif /* CONFIG_TSF_RESET_OFFLOAD */
11902
11903 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
11904 #ifdef CONFIG_HW_P0_TSF_SYNC
11905 #ifdef CONFIG_CONCURRENT_MODE
hw_port0_tsf_sync_sel(_adapter * adapter,u8 benable,u8 hw_port,u16 tr_offset)11906 static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
11907 {
11908 u8 val8;
11909 u8 client_id = 0;
11910 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11911
11912 #ifdef CONFIG_MCC_MODE
11913 if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
11914 RTW_INFO("[MCC] do not set HW TSF sync\n");
11915 return;
11916 }
11917 #endif
11918 /* check if port0 is already synced */
11919 if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
11920 RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
11921 FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
11922 return;
11923 }
11924
11925 /* check if port0 already disable sync */
11926 if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
11927 RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
11928 return;
11929 }
11930
11931 /* check if port0 sync to port0 */
11932 if (benable && hw_port == HW_PORT0) {
11933 RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
11934 rtw_warn_on(1);
11935 return;
11936 }
11937
11938 /*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
11939 /* Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
11940 Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
11941
11942 val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
11943
11944 if (benable) {
11945 /*Disable Port0's beacon function*/
11946 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
11947
11948 /*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
11949 if (tr_offset)
11950 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
11951
11952 /*reg 0x577[6]=1*/ /*auto sync by tbtt*/
11953 rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
11954
11955 if (HW_PORT1 == hw_port)
11956 client_id = 0;
11957 else if (HW_PORT2 == hw_port)
11958 client_id = 1;
11959 else if (HW_PORT3 == hw_port)
11960 client_id = 2;
11961 else if (HW_PORT4 == hw_port)
11962 client_id = 3;
11963
11964 val8 &= 0x8F;
11965 val8 |= (BIT(6) | (client_id << 4));
11966
11967 dvobj->p0_tsf.sync_port = hw_port;
11968 dvobj->p0_tsf.offset = tr_offset;
11969 rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
11970
11971 /*Enable Port0's beacon function*/
11972 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) | BIT_EN_BCN_FUNCTION);
11973 RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
11974 } else {
11975 val8 &= ~BIT(6);
11976
11977 dvobj->p0_tsf.sync_port = MAX_HW_PORT;
11978 dvobj->p0_tsf.offset = 0;
11979 rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
11980 RTW_INFO("%s P0 TSF sync disable\n", __func__);
11981 }
11982 }
_search_ld_sta(_adapter * adapter,u8 include_self)11983 static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
11984 {
11985 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11986 u8 i;
11987 _adapter *iface = NULL;
11988
11989 if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
11990 RTW_ERR("STA_LD_NUM == 0\n");
11991 rtw_warn_on(1);
11992 }
11993
11994 for (i = 0; i < dvobj->iface_nums; i++) {
11995 iface = dvobj->padapters[i];
11996 if (!iface)
11997 continue;
11998 if (include_self == _FALSE && adapter == iface)
11999 continue;
12000 if (is_client_associated_to_ap(iface))
12001 break;
12002 }
12003 if (iface)
12004 RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
12005 return iface;
12006 }
12007 #endif /*CONFIG_CONCURRENT_MODE*/
12008 /*Correct port0's TSF*/
12009 /*#define DBG_P0_TSF_SYNC*/
hw_var_set_correct_tsf(PADAPTER adapter,u8 mlme_state)12010 void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
12011 {
12012 #ifdef CONFIG_CONCURRENT_MODE
12013 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12014 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12015 _adapter *sta_if = NULL;
12016 u8 hw_port;
12017
12018 RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
12019 #ifdef DBG_P0_TSF_SYNC
12020 RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
12021 RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
12022 RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
12023 if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12024 RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
12025 else
12026 RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12027 RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12028 #endif
12029 switch (mlme_state) {
12030 case MLME_STA_CONNECTED :
12031 {
12032 hw_port = rtw_hal_get_port(adapter);
12033
12034 if (!MLME_IS_STA(adapter)) {
12035 RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12036 rtw_warn_on(1);
12037 }
12038
12039 if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
12040 RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
12041 rtw_warn_on(1);
12042 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12043 }
12044
12045 if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12046 (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
12047 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12048 #ifdef DBG_P0_TSF_SYNC
12049 RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
12050 #endif
12051 }
12052 }
12053 break;
12054 case MLME_STA_DISCONNECTED :
12055 {
12056 hw_port = rtw_hal_get_port(adapter);
12057
12058 if (!MLME_IS_STA(adapter)) {
12059 RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12060 rtw_warn_on(1);
12061 }
12062
12063 if (dvobj->p0_tsf.sync_port == hw_port) {
12064 if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
12065 /* search next appropriate sta*/
12066 sta_if = _search_ld_sta(adapter, _FALSE);
12067 if (sta_if) {
12068 hw_port = rtw_hal_get_port(sta_if);
12069 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12070 #ifdef DBG_P0_TSF_SYNC
12071 RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
12072 #endif
12073 }
12074 } else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
12075 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12076 #ifdef DBG_P0_TSF_SYNC
12077 RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
12078 #endif
12079 }
12080 }
12081 }
12082 break;
12083 case MLME_AP_STARTED :
12084 case MLME_MESH_STARTED :
12085 {
12086 if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12087 RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12088 rtw_warn_on(1);
12089 }
12090
12091 if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12092 rtw_mi_get_assoced_sta_num(adapter)) {
12093 /* get port of sta */
12094 sta_if = _search_ld_sta(adapter, _FALSE);
12095 if (sta_if) {
12096 hw_port = rtw_hal_get_port(sta_if);
12097 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12098 #ifdef DBG_P0_TSF_SYNC
12099 RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
12100 #endif
12101 }
12102 }
12103 }
12104 break;
12105 case MLME_AP_STOPPED :
12106 case MLME_MESH_STOPPED :
12107 {
12108 if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12109 RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12110 rtw_warn_on(1);
12111 }
12112 /*stop ap mode*/
12113 if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
12114 (dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
12115 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12116 #ifdef DBG_P0_TSF_SYNC
12117 RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
12118 #endif
12119 }
12120 }
12121 break;
12122 default :
12123 RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
12124 break;
12125 }
12126
12127 /*#ifdef DBG_P0_TSF_SYNC*/
12128 #if 1
12129 if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12130 RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
12131 else
12132 RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12133 RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12134 #endif
12135 #endif /*CONFIG_CONCURRENT_MODE*/
12136 }
12137
12138 #else /*! CONFIG_HW_P0_TSF_SYNC*/
12139
12140 #ifdef CONFIG_MI_WITH_MBSSID_CAM
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12141 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12142 {
12143 /*do nothing*/
12144 }
12145 #else /* !CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)12146 static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
12147 {
12148 if (hw_port == HW_PORT0) {
12149 /*disable related TSF function*/
12150 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
12151 #if defined(CONFIG_RTL8192F)
12152 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12153 REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
12154 #endif
12155
12156 rtw_write32(padapter, REG_TSFTR, tsf);
12157 rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
12158
12159 /*enable related TSF function*/
12160 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
12161 #if defined(CONFIG_RTL8192F)
12162 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12163 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
12164 #endif
12165 } else if (hw_port == HW_PORT1) {
12166 /*disable related TSF function*/
12167 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
12168 #if defined(CONFIG_RTL8192F)
12169 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12170 REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);
12171 #endif
12172
12173 rtw_write32(padapter, REG_TSFTR1, tsf);
12174 rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
12175
12176 /*enable related TSF function*/
12177 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
12178 #if defined(CONFIG_RTL8192F)
12179 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12180 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
12181 #endif
12182 } else
12183 RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
12184 }
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12185 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12186 {
12187 u64 tsf;
12188 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
12189 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
12190
12191 tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
12192
12193 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12194 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12195 StopTxBeacon(adapter);
12196
12197 rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
12198
12199 #ifdef CONFIG_CONCURRENT_MODE
12200 /* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
12201 if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
12202 && (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12203 ) {
12204 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12205 int i;
12206 _adapter *iface;
12207
12208 for (i = 0; i < dvobj->iface_nums; i++) {
12209 iface = dvobj->padapters[i];
12210 if (!iface)
12211 continue;
12212 if (iface == adapter)
12213 continue;
12214
12215 if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
12216 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
12217 ) {
12218 rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
12219 #ifdef CONFIG_TSF_RESET_OFFLOAD
12220 if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
12221 RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
12222 , __func__, ADPT_ARG(iface), iface->hw_port);
12223 #endif /* CONFIG_TSF_RESET_OFFLOAD*/
12224 }
12225 }
12226 }
12227 #endif /* CONFIG_CONCURRENT_MODE */
12228 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12229 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12230 ResumeTxBeacon(adapter);
12231 }
12232 #endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
12233 #endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/
12234 #endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/
12235
rtw_hal_get_tsftr_by_port(_adapter * adapter,u8 port)12236 u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
12237 {
12238 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
12239 u64 tsftr = 0;
12240
12241 if (port >= hal_spec->port_num) {
12242 RTW_ERR("%s invalid port(%d) \n", __func__, port);
12243 goto exit;
12244 }
12245
12246 switch (rtw_get_chip_type(adapter)) {
12247 #if defined(CONFIG_RTL8814B)
12248 case RTL8814B:
12249 {
12250 u8 val8;
12251
12252 /* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */
12253 val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);
12254 val8 &= ~0x70;
12255 val8 |= port << 4;
12256 rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);
12257
12258 tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);
12259 tsftr = tsftr << 32;
12260 tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);
12261
12262 break;
12263 }
12264 #endif
12265 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
12266 case RTL8814A:
12267 case RTL8822B:
12268 case RTL8821C:
12269 case RTL8822C:
12270 {
12271 u8 val8;
12272
12273 /* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
12274 val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
12275 val8 &= 0x8F;
12276 val8 |= port << 4;
12277 rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
12278
12279 tsftr = rtw_read32(adapter, REG_TSFTR + 4);
12280 tsftr = tsftr << 32;
12281 tsftr |= rtw_read32(adapter, REG_TSFTR);
12282
12283 break;
12284 }
12285 #endif
12286 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
12287 || defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
12288 || defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
12289 || defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
12290 || defined(CONFIG_RTL8710B)
12291 case RTL8188E:
12292 case RTL8188F:
12293 case RTL8188GTV:
12294 case RTL8192E:
12295 case RTL8192F:
12296 case RTL8723B:
12297 case RTL8703B:
12298 case RTL8723D:
12299 case RTL8812:
12300 case RTL8821:
12301 case RTL8710B:
12302 {
12303 u32 addr;
12304
12305 if (port == HW_PORT0)
12306 addr = REG_TSFTR;
12307 else if (port == HW_PORT1)
12308 addr = REG_TSFTR1;
12309 else {
12310 RTW_ERR("%s unknown port(%d) \n", __func__, port);
12311 goto exit;
12312 }
12313
12314 tsftr = rtw_read32(adapter, addr + 4);
12315 tsftr = tsftr << 32;
12316 tsftr |= rtw_read32(adapter, addr);
12317
12318 break;
12319 }
12320 #endif
12321 default:
12322 RTW_ERR("%s unknow chip type\n", __func__);
12323 }
12324
12325 exit:
12326 return tsftr;
12327 }
12328
12329 #ifdef CONFIG_TDLS
12330 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)12331 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
12332 {
12333 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
12334 u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
12335
12336
12337 SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
12338 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
12339 switch (bwmode) {
12340 case CHANNEL_WIDTH_40:
12341 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
12342 break;
12343 case CHANNEL_WIDTH_80:
12344 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
12345 break;
12346 case CHANNEL_WIDTH_20:
12347 default:
12348 break;
12349 }
12350 SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
12351
12352 return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
12353 }
12354 #endif
12355 #endif
12356
12357 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)12358 void rtw_hal_update_uapsd_tid(_adapter *adapter)
12359 {
12360 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12361 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
12362
12363 /* write complement of pqospriv->uapsd_tid to mac register 0x693 because
12364 it's designed for "0" represents "enable" and "1" represents "disable" */
12365 rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
12366 }
12367 #endif /* CONFIG_WMMPS_STA */
12368
12369 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
12370 /* 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)12371 s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
12372 {
12373 u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
12374 u8 hw_port = rtw_hal_get_port(adapter);
12375
12376 SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
12377 RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
12378 return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
12379 }
12380 #endif
12381
12382 #define LPS_ACTIVE_TIMEOUT 50 /*number of times*/
rtw_lps_state_chk(_adapter * adapter,u8 ps_mode)12383 void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
12384 {
12385 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
12386 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12387 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12388 struct sta_priv *pstapriv = &adapter->stapriv;
12389 struct sta_info *psta = NULL;
12390 u8 ps_ready = _FALSE;
12391 s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
12392
12393 if (ps_mode == PS_MODE_ACTIVE) {
12394 #ifdef CONFIG_LPS_ACK
12395 if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {
12396 if (pwrpriv->lps_ack_status > 0) {
12397 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
12398 if (psta != NULL) {
12399 if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)
12400 RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));
12401 }
12402 }
12403 } else {
12404 RTW_WARN("LPS sctx query timeout, operation abort!!\n");
12405 return;
12406 }
12407 pwrpriv->lps_ack_status = -1;
12408 #else
12409 do {
12410 if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
12411 ps_ready = _TRUE;
12412 break;
12413 }
12414 rtw_msleep_os(1);
12415 } while (leave_wait_count--);
12416
12417 if (ps_ready == _FALSE) {
12418 RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));
12419 return;
12420 }
12421 #endif /* CONFIG_LPS_ACK */
12422 }
12423 }
12424
rtw_var_set_basic_rate(PADAPTER padapter,u8 * val)12425 void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {
12426
12427 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
12428 struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
12429 u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
12430 u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
12431 u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
12432 #if CONFIG_IEEE80211_BAND_5GHZ
12433 u16 rrsr_5g_force_mask = (RRSR_6M);
12434 u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);
12435 #endif
12436 u32 temp_RRSR;
12437
12438 HalSetBrateCfg(padapter, val, &BrateCfg);
12439 input_b = BrateCfg;
12440
12441 /* apply force and allow mask */
12442 #if CONFIG_IEEE80211_BAND_5GHZ
12443 if (pHalData->current_band_type != BAND_ON_2_4G) {
12444 BrateCfg |= rrsr_5g_force_mask;
12445 BrateCfg &= rrsr_5g_allow_mask;
12446 } else
12447 #endif
12448 { /* 2.4G */
12449 BrateCfg |= rrsr_2g_force_mask;
12450 BrateCfg &= rrsr_2g_allow_mask;
12451 }
12452 masked = BrateCfg;
12453
12454 #ifdef CONFIG_CMCC_TEST
12455 BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
12456 BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */
12457 #endif
12458
12459 /* IOT consideration */
12460 if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
12461 /* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
12462 if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
12463 BrateCfg |= RRSR_6M;
12464 }
12465 ioted = BrateCfg;
12466
12467 #ifdef CONFIG_NARROWBAND_SUPPORTING
12468 if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
12469 || (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {
12470 BrateCfg &= ~RRSR_CCK_RATES;
12471 BrateCfg |= RRSR_6M;
12472 }
12473 #endif
12474 pHalData->BasicRateSet = BrateCfg;
12475
12476 RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
12477
12478 /* Set RRSR rate table. */
12479 temp_RRSR = rtw_read32(padapter, REG_RRSR);
12480 temp_RRSR &=0xFFFF0000;
12481 temp_RRSR |=BrateCfg;
12482 rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);
12483
12484 rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
12485
12486 #if defined(CONFIG_RTL8188E)
12487 rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
12488 #endif
12489 }
12490
SetHwReg(_adapter * adapter,u8 variable,u8 * val)12491 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
12492 {
12493 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12494 u8 ret = _SUCCESS;
12495
12496 switch (variable) {
12497 case HW_VAR_MEDIA_STATUS: {
12498 u8 net_type = *((u8 *)val);
12499
12500 rtw_hal_set_msr(adapter, net_type);
12501 }
12502 break;
12503 case HW_VAR_DO_IQK:
12504 if (*val)
12505 hal_data->bNeedIQK = _TRUE;
12506 else
12507 hal_data->bNeedIQK = _FALSE;
12508 break;
12509 case HW_VAR_MAC_ADDR:
12510 #ifdef CONFIG_MI_WITH_MBSSID_CAM
12511 rtw_hal_set_macaddr_mbid(adapter, val);
12512 #else
12513 rtw_hal_set_macaddr_port(adapter, val);
12514 #endif
12515 break;
12516 case HW_VAR_BSSID:
12517 rtw_hal_set_bssid(adapter, val);
12518 break;
12519 case HW_VAR_RCR:
12520 ret = hw_var_rcr_config(adapter, *((u32 *)val));
12521 break;
12522 case HW_VAR_ON_RCR_AM:
12523 hw_var_set_rcr_am(adapter, 1);
12524 break;
12525 case HW_VAR_OFF_RCR_AM:
12526 hw_var_set_rcr_am(adapter, 0);
12527 break;
12528 case HW_VAR_BEACON_INTERVAL:
12529 hw_var_set_bcn_interval(adapter, *(u16 *)val);
12530 break;
12531 #ifdef CONFIG_MBSSID_CAM
12532 case HW_VAR_MBSSID_CAM_WRITE: {
12533 u32 cmd = 0;
12534 u32 *cam_val = (u32 *)val;
12535
12536 rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
12537 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
12538 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12539 }
12540 break;
12541 case HW_VAR_MBSSID_CAM_CLEAR: {
12542 u32 cmd;
12543 u8 entry_id = *(u8 *)val;
12544
12545 rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
12546
12547 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
12548 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12549 }
12550 break;
12551 case HW_VAR_RCR_MBSSID_EN:
12552 if (*((u8 *)val))
12553 rtw_hal_rcr_add(adapter, RCR_ENMBID);
12554 else
12555 rtw_hal_rcr_clear(adapter, RCR_ENMBID);
12556 break;
12557 #endif
12558 case HW_VAR_PORT_SWITCH:
12559 hw_var_port_switch(adapter);
12560 break;
12561 case HW_VAR_INIT_RTS_RATE: {
12562 u16 brate_cfg = *((u16 *)val);
12563 u8 rate_index = 0;
12564 HAL_VERSION *hal_ver = &hal_data->version_id;
12565
12566 if (IS_8188E(*hal_ver)) {
12567
12568 while (brate_cfg > 0x1) {
12569 brate_cfg = (brate_cfg >> 1);
12570 rate_index++;
12571 }
12572 rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
12573 } else
12574 rtw_warn_on(1);
12575 }
12576 break;
12577 case HW_VAR_SEC_CFG: {
12578 u16 reg_scr_ori;
12579 u16 reg_scr;
12580
12581 reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
12582 reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
12583
12584 if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
12585 reg_scr |= SCR_CHK_BMC;
12586
12587 if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
12588 reg_scr |= SCR_NoSKMC;
12589
12590 if (reg_scr != reg_scr_ori)
12591 rtw_write16(adapter, REG_SECCFG, reg_scr);
12592 }
12593 break;
12594 case HW_VAR_SEC_DK_CFG: {
12595 struct security_priv *sec = &adapter->securitypriv;
12596 u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
12597
12598 if (val) { /* Enable default key related setting */
12599 reg_scr |= SCR_TXBCUSEDK;
12600 if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
12601 reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
12602 } else /* Disable default key related setting */
12603 reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
12604
12605 rtw_write8(adapter, REG_SECCFG, reg_scr);
12606 }
12607 break;
12608
12609 case HW_VAR_ASIX_IOT:
12610 /* enable ASIX IOT function */
12611 if (*((u8 *)val) == _TRUE) {
12612 /* 0xa2e[0]=0 (disable rake receiver) */
12613 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12614 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
12615 /* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
12616 rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
12617 } else {
12618 /* restore reg:0xa2e, reg:0xa1c */
12619 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12620 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
12621 rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
12622 }
12623 break;
12624 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
12625 case HW_VAR_WOWLAN: {
12626 struct wowlan_ioctl_param *poidparam;
12627
12628 poidparam = (struct wowlan_ioctl_param *)val;
12629 switch (poidparam->subcode) {
12630 #ifdef CONFIG_WOWLAN
12631 case WOWLAN_PATTERN_CLEAN:
12632 rtw_hal_dl_pattern(adapter, 2);
12633 break;
12634 case WOWLAN_ENABLE:
12635 rtw_hal_wow_enable(adapter);
12636 break;
12637 case WOWLAN_DISABLE:
12638 rtw_hal_wow_disable(adapter);
12639 break;
12640 #endif /*CONFIG_WOWLAN*/
12641 #ifdef CONFIG_AP_WOWLAN
12642 case WOWLAN_AP_ENABLE:
12643 rtw_hal_ap_wow_enable(adapter);
12644 break;
12645 case WOWLAN_AP_DISABLE:
12646 rtw_hal_ap_wow_disable(adapter);
12647 break;
12648 #endif /*CONFIG_AP_WOWLAN*/
12649 default:
12650 break;
12651 }
12652 }
12653 break;
12654 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
12655
12656 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
12657 case HW_VAR_BCN_FUNC:
12658 hw_var_set_bcn_func(adapter, *val);
12659 break;
12660 #endif
12661
12662 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
12663 case HW_VAR_MLME_DISCONNECT:
12664 hw_var_set_mlme_disconnect(adapter);
12665 break;
12666 #endif
12667
12668 case HW_VAR_MLME_SITESURVEY:
12669 hw_var_set_mlme_sitesurvey(adapter, *val);
12670 #ifdef CONFIG_BT_COEXIST
12671 if (hal_data->EEPROMBluetoothCoexist == 1)
12672 rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
12673 #endif
12674 break;
12675
12676 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
12677 case HW_VAR_MLME_JOIN:
12678 hw_var_set_mlme_join(adapter, *val);
12679 break;
12680 #endif
12681
12682 case HW_VAR_EN_HW_UPDATE_TSF:
12683 rtw_hal_set_hw_update_tsf(adapter);
12684 break;
12685 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
12686 case HW_VAR_CORRECT_TSF:
12687 hw_var_set_correct_tsf(adapter, *val);
12688 break;
12689 #endif
12690
12691 #if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)
12692 case HW_VAR_TSF_AUTO_SYNC:
12693 if (*val == _TRUE)
12694 hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
12695 else
12696 hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
12697 break;
12698 #endif
12699 case HW_VAR_APFM_ON_MAC:
12700 hal_data->bMacPwrCtrlOn = *val;
12701 RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
12702 break;
12703 #ifdef CONFIG_WMMPS_STA
12704 case HW_VAR_UAPSD_TID:
12705 rtw_hal_update_uapsd_tid(adapter);
12706 break;
12707 #endif /* CONFIG_WMMPS_STA */
12708 #ifdef CONFIG_LPS_PG
12709 case HW_VAR_LPS_PG_HANDLE:
12710 rtw_hal_lps_pg_handler(adapter, *val);
12711 break;
12712 #endif
12713 #ifdef CONFIG_LPS_LCLK_WD_TIMER
12714 case HW_VAR_DM_IN_LPS_LCLK:
12715 rtw_phydm_wd_lps_lclk_hdl(adapter);
12716 break;
12717 #endif
12718 case HW_VAR_ENABLE_RX_BAR:
12719 if (*val == _TRUE) {
12720 /* enable RX BAR */
12721 u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12722
12723 val16 |= BIT(8);
12724 rtw_write16(adapter, REG_RXFLTMAP1, val16);
12725 } else {
12726 /* disable RX BAR */
12727 u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12728
12729 val16 &= (~BIT(8));
12730 rtw_write16(adapter, REG_RXFLTMAP1, val16);
12731 }
12732 RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
12733 REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
12734 break;
12735 case HW_VAR_HCI_SUS_STATE:
12736 hal_data->hci_sus_state = *(u8 *)val;
12737 RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
12738 break;
12739 #if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
12740 case HW_VAR_BCN_HEAD_SEL:
12741 {
12742 u8 vap_id = *(u8 *)val;
12743
12744 if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
12745 RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
12746 rtw_warn_on(1);
12747 }
12748 if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
12749 u16 drv_pg_bndy = 0, bcn_addr = 0;
12750 u32 page_size = 0;
12751
12752 /*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
12753 rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
12754 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
12755
12756 if (vap_id != 0xFF)
12757 bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
12758 else
12759 bcn_addr = drv_pg_bndy;
12760 RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
12761 ADPT_ARG(adapter), vap_id, bcn_addr);
12762 rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
12763 (bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
12764 }
12765 }
12766 break;
12767 #endif
12768 case HW_VAR_LPS_STATE_CHK :
12769 rtw_lps_state_chk(adapter, *(u8 *)val);
12770 break;
12771
12772 #ifdef CONFIG_RTS_FULL_BW
12773 case HW_VAR_SET_RTS_BW:
12774 {
12775 #ifdef RTW_HALMAC
12776 rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));
12777 #else
12778 u8 temp;
12779 if(*val)
12780 temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );
12781 else
12782 temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));
12783 rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);
12784 /*RTW_INFO("HW_VAR_SET_RTS_BW val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/
12785 #endif
12786 }
12787 break;
12788 #endif/*CONFIG_RTS_FULL_BW*/
12789 #if defined(CONFIG_PCI_HCI)
12790 case HW_VAR_ENSWBCN:
12791 if (*val == _TRUE) {
12792 rtw_write8(adapter, REG_CR + 1,
12793 rtw_read8(adapter, REG_CR + 1) | BIT(0));
12794 } else
12795 rtw_write8(adapter, REG_CR + 1,
12796 rtw_read8(adapter, REG_CR + 1) & ~BIT(0));
12797 break;
12798 #endif
12799 default:
12800 if (0)
12801 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12802 FUNC_ADPT_ARG(adapter), variable);
12803 ret = _FAIL;
12804 break;
12805 }
12806
12807 return ret;
12808 }
12809
GetHwReg(_adapter * adapter,u8 variable,u8 * val)12810 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
12811 {
12812 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12813 u64 val64;
12814
12815
12816 switch (variable) {
12817 case HW_VAR_MAC_ADDR:
12818 #ifndef CONFIG_MI_WITH_MBSSID_CAM
12819 rtw_hal_get_macaddr_port(adapter, val);
12820 #endif
12821 break;
12822 case HW_VAR_BASIC_RATE:
12823 *((u16 *)val) = hal_data->BasicRateSet;
12824 break;
12825 case HW_VAR_MEDIA_STATUS:
12826 rtw_hal_get_msr(adapter, val);
12827 break;
12828 case HW_VAR_DO_IQK:
12829 *val = hal_data->bNeedIQK;
12830 break;
12831 case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
12832 if (hal_is_band_support(adapter, BAND_ON_5G))
12833 *val = _TRUE;
12834 else
12835 *val = _FALSE;
12836 break;
12837 case HW_VAR_APFM_ON_MAC:
12838 *val = hal_data->bMacPwrCtrlOn;
12839 break;
12840 case HW_VAR_RCR:
12841 hw_var_rcr_get(adapter, (u32 *)val);
12842 break;
12843 case HW_VAR_FWLPS_RF_ON:
12844 /* When we halt NIC, we should check if FW LPS is leave. */
12845 if (rtw_is_surprise_removed(adapter)
12846 || (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
12847 ) {
12848 /*
12849 * If it is in HW/SW Radio OFF or IPS state,
12850 * we do not check Fw LPS Leave,
12851 * because Fw is unload.
12852 */
12853 *val = _TRUE;
12854 } else {
12855 u32 rcr = 0;
12856
12857 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
12858 if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
12859 *val = _FALSE;
12860 else
12861 *val = _TRUE;
12862 }
12863 break;
12864
12865 case HW_VAR_HCI_SUS_STATE:
12866 *((u8 *)val) = hal_data->hci_sus_state;
12867 break;
12868
12869 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
12870 case HW_VAR_BCN_CTRL_ADDR:
12871 *((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
12872 break;
12873 #endif
12874
12875 #ifdef CONFIG_WAPI_SUPPORT
12876 case HW_VAR_CAM_EMPTY_ENTRY: {
12877 u8 ucIndex = *((u8 *)val);
12878 u8 i;
12879 u32 ulCommand = 0;
12880 u32 ulContent = 0;
12881 u32 ulEncAlgo = CAM_AES;
12882
12883 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
12884 /* filled id in CAM config 2 byte */
12885 if (i == 0)
12886 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
12887 else
12888 ulContent = 0;
12889 /* polling bit, and No Write enable, and address */
12890 ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
12891 ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
12892 /* write content 0 is equall to mark invalid */
12893 rtw_write32(adapter, REG_CAMWRITE, ulContent); /* delay_ms(40); */
12894 rtw_write32(adapter, REG_CAMCMD, ulCommand); /* delay_ms(40); */
12895 }
12896 }
12897 #endif
12898
12899 default:
12900 if (0)
12901 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12902 FUNC_ADPT_ARG(adapter), variable);
12903 break;
12904 }
12905
12906 }
12907
_get_page_size(struct _ADAPTER * a)12908 static u32 _get_page_size(struct _ADAPTER *a)
12909 {
12910 #ifdef RTW_HALMAC
12911 struct dvobj_priv *d;
12912 u32 size = 0;
12913 int err = 0;
12914
12915
12916 d = adapter_to_dvobj(a);
12917
12918 err = rtw_halmac_get_page_size(d, &size);
12919 if (!err)
12920 return size;
12921
12922 RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
12923 FUNC_ADPT_ARG(a), err);
12924 #endif /* RTW_HALMAC */
12925
12926 return PAGE_SIZE_128;
12927 }
12928
12929 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)12930 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
12931 {
12932 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12933 u8 bResult = _SUCCESS;
12934
12935 switch (variable) {
12936
12937 case HAL_DEF_DBG_DUMP_RXPKT:
12938 hal_data->bDumpRxPkt = *((u8 *)value);
12939 break;
12940 case HAL_DEF_DBG_DUMP_TXPKT:
12941 hal_data->bDumpTxPkt = *((u8 *)value);
12942 break;
12943 case HAL_DEF_ANT_DETECT:
12944 hal_data->AntDetection = *((u8 *)value);
12945 break;
12946 default:
12947 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
12948 bResult = _FAIL;
12949 break;
12950 }
12951
12952 return bResult;
12953 }
12954
12955 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)12956 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
12957 {
12958 struct registry_priv *pregistrypriv = &adapter->registrypriv;
12959 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12960
12961 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)))
12962 return pregistrypriv->beamformer_rf_num;
12963 else if (IS_HARDWARE_TYPE_8814AE(adapter)
12964 #if 0
12965 #if defined(CONFIG_USB_HCI)
12966 || (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) /* for USB3.0 */
12967 #endif
12968 #endif
12969 ) {
12970 /*BF cap provided by Yu Chen, Sean, 2015, 01 */
12971 if (hal_data->rf_type == RF_3T3R)
12972 return 2;
12973 else if (hal_data->rf_type == RF_4T4R)
12974 return 3;
12975 else
12976 return 1;
12977 } else
12978 return 1;
12979
12980 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)12981 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
12982 {
12983 struct registry_priv *pregistrypriv = &adapter->registrypriv;
12984 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12985 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12986
12987 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12988
12989 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)))
12990 return pregistrypriv->beamformee_rf_num;
12991 else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
12992 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
12993 return 2;
12994 else
12995 return 2;/*TODO: May be 3 in the future, by ChenYu. */
12996 } else
12997 return 1;
12998
12999 }
13000 #ifdef RTW_BEAMFORMING_VERSION_2
rtw_hal_beamforming_config_csirate(PADAPTER adapter)13001 void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
13002 {
13003 struct dm_struct *p_dm_odm;
13004 struct beamforming_info *bf_info;
13005 u8 fix_rate_enable = 0;
13006 u8 new_csi_rate_idx;
13007 u8 rrsr_54_en;
13008 u32 temp_rrsr;
13009
13010 /* Acting as BFee */
13011 if (IS_BEAMFORMEE(adapter)) {
13012 #if 0
13013 /* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
13014 if (IS_HARDWARE_TYPE_8821C(Adapter))
13015 FixRateEnable = 1; /* Support after 8821C */
13016 #endif
13017
13018 p_dm_odm = adapter_to_phydm(adapter);
13019 bf_info = GET_BEAMFORM_INFO(adapter);
13020
13021 rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
13022 p_dm_odm->rssi_min,
13023 bf_info->cur_csi_rpt_rate,
13024 fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);
13025
13026 temp_rrsr = rtw_read32(adapter, REG_RRSR);
13027 if (rrsr_54_en == 1)
13028 temp_rrsr |= RRSR_54M;
13029 else if (rrsr_54_en == 0)
13030 temp_rrsr &= ~RRSR_54M;
13031 rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);
13032
13033 if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
13034 bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
13035 }
13036 }
13037 #endif
13038 #endif
13039
13040 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13041 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13042 {
13043 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13044 u8 bResult = _SUCCESS;
13045
13046 switch (variable) {
13047 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
13048 struct mlme_priv *pmlmepriv;
13049 struct sta_priv *pstapriv;
13050 struct sta_info *psta;
13051
13052 pmlmepriv = &adapter->mlmepriv;
13053 pstapriv = &adapter->stapriv;
13054 psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
13055 if (psta)
13056 *((int *)value) = psta->cmn.rssi_stat.rssi;
13057 }
13058 break;
13059 case HAL_DEF_DBG_DUMP_RXPKT:
13060 *((u8 *)value) = hal_data->bDumpRxPkt;
13061 break;
13062 case HAL_DEF_DBG_DUMP_TXPKT:
13063 *((u8 *)value) = hal_data->bDumpTxPkt;
13064 break;
13065 case HAL_DEF_ANT_DETECT:
13066 *((u8 *)value) = hal_data->AntDetection;
13067 break;
13068 case HAL_DEF_TX_PAGE_SIZE:
13069 *((u32 *)value) = _get_page_size(adapter);
13070 break;
13071 case HAL_DEF_TX_STBC:
13072 #ifdef CONFIG_ALPHA_SMART_ANTENNA
13073 *(u8 *)value = 0;
13074 #else
13075 *(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;
13076 #endif
13077 break;
13078 case HAL_DEF_EXPLICIT_BEAMFORMER:
13079 case HAL_DEF_EXPLICIT_BEAMFORMEE:
13080 case HAL_DEF_VHT_MU_BEAMFORMER:
13081 case HAL_DEF_VHT_MU_BEAMFORMEE:
13082 *(u8 *)value = _FALSE;
13083 break;
13084 #ifdef CONFIG_BEAMFORMING
13085 case HAL_DEF_BEAMFORMER_CAP:
13086 *(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
13087 break;
13088 case HAL_DEF_BEAMFORMEE_CAP:
13089 *(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
13090 break;
13091 #endif
13092 default:
13093 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
13094 bResult = _FAIL;
13095 break;
13096 }
13097
13098 return bResult;
13099 }
13100
13101 /*
13102 * Description:
13103 * Translate a character to hex digit.
13104 * */
13105 u32
MapCharToHexDigit(char chTmp)13106 MapCharToHexDigit(
13107 char chTmp
13108 )
13109 {
13110 if (chTmp >= '0' && chTmp <= '9')
13111 return chTmp - '0';
13112 else if (chTmp >= 'a' && chTmp <= 'f')
13113 return 10 + (chTmp - 'a');
13114 else if (chTmp >= 'A' && chTmp <= 'F')
13115 return 10 + (chTmp - 'A');
13116 else
13117 return 0;
13118 }
13119
13120
13121
13122 /*
13123 * Description:
13124 * Parse hex number from the string pucStr.
13125 * */
13126 BOOLEAN
GetHexValueFromString(char * szStr,u32 * pu4bVal,u32 * pu4bMove)13127 GetHexValueFromString(
13128 char *szStr,
13129 u32 *pu4bVal,
13130 u32 *pu4bMove
13131 )
13132 {
13133 char *szScan = szStr;
13134
13135 /* Check input parameter. */
13136 if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
13137 RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
13138 return _FALSE;
13139 }
13140
13141 /* Initialize output. */
13142 *pu4bMove = 0;
13143 *pu4bVal = 0;
13144
13145 /* Skip leading space. */
13146 while (*szScan != '\0' &&
13147 (*szScan == ' ' || *szScan == '\t')) {
13148 szScan++;
13149 (*pu4bMove)++;
13150 }
13151
13152 /* Skip leading '0x' or '0X'. */
13153 if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
13154 szScan += 2;
13155 (*pu4bMove) += 2;
13156 }
13157
13158 /* Check if szScan is now pointer to a character for hex digit, */
13159 /* if not, it means this is not a valid hex number. */
13160 if (!IsHexDigit(*szScan))
13161 return _FALSE;
13162
13163 /* Parse each digit. */
13164 do {
13165 (*pu4bVal) <<= 4;
13166 *pu4bVal += MapCharToHexDigit(*szScan);
13167
13168 szScan++;
13169 (*pu4bMove)++;
13170 } while (IsHexDigit(*szScan));
13171
13172 return _TRUE;
13173 }
13174
13175 BOOLEAN
GetFractionValueFromString(char * szStr,u8 * pInteger,u8 * pFraction,u32 * pu4bMove)13176 GetFractionValueFromString(
13177 char *szStr,
13178 u8 *pInteger,
13179 u8 *pFraction,
13180 u32 *pu4bMove
13181 )
13182 {
13183 char *szScan = szStr;
13184
13185 /* Initialize output. */
13186 *pu4bMove = 0;
13187 *pInteger = 0;
13188 *pFraction = 0;
13189
13190 /* Skip leading space. */
13191 while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) {
13192 ++szScan;
13193 ++(*pu4bMove);
13194 }
13195
13196 if (*szScan < '0' || *szScan > '9')
13197 return _FALSE;
13198
13199 /* Parse each digit. */
13200 do {
13201 (*pInteger) *= 10;
13202 *pInteger += (*szScan - '0');
13203
13204 ++szScan;
13205 ++(*pu4bMove);
13206
13207 if (*szScan == '.') {
13208 ++szScan;
13209 ++(*pu4bMove);
13210
13211 if (*szScan < '0' || *szScan > '9')
13212 return _FALSE;
13213
13214 *pFraction += (*szScan - '0') * 10;
13215 ++szScan;
13216 ++(*pu4bMove);
13217
13218 if (*szScan >= '0' && *szScan <= '9') {
13219 *pFraction += *szScan - '0';
13220 ++szScan;
13221 ++(*pu4bMove);
13222 }
13223 return _TRUE;
13224 }
13225 } while (*szScan >= '0' && *szScan <= '9');
13226
13227 return _TRUE;
13228 }
13229
13230 /*
13231 * Description:
13232 * Return TRUE if szStr is comment out with leading " */ /* ".
13233 * */
13234 BOOLEAN
IsCommentString(char * szStr)13235 IsCommentString(
13236 char *szStr
13237 )
13238 {
13239 if (*szStr == '/' && *(szStr + 1) == '/')
13240 return _TRUE;
13241 else
13242 return _FALSE;
13243 }
13244
13245 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(char * Str,u8 * pInt)13246 GetU1ByteIntegerFromStringInDecimal(
13247 char *Str,
13248 u8 *pInt
13249 )
13250 {
13251 u16 i = 0;
13252 *pInt = 0;
13253
13254 while (Str[i] != '\0') {
13255 if (Str[i] >= '0' && Str[i] <= '9') {
13256 *pInt *= 10;
13257 *pInt += (Str[i] - '0');
13258 } else
13259 return _FALSE;
13260 ++i;
13261 }
13262
13263 return _TRUE;
13264 }
13265
13266 /* <20121004, Kordan> For example,
13267 * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
13268 * If RightQualifier does not exist, it will hang on in the while loop */
13269 BOOLEAN
ParseQualifiedString(char * In,u32 * Start,char * Out,char LeftQualifier,char RightQualifier)13270 ParseQualifiedString(
13271 char *In,
13272 u32 *Start,
13273 char *Out,
13274 char LeftQualifier,
13275 char RightQualifier
13276 )
13277 {
13278 u32 i = 0, j = 0;
13279 char c = In[(*Start)++];
13280
13281 if (c != LeftQualifier)
13282 return _FALSE;
13283
13284 i = (*Start);
13285 c = In[(*Start)++];
13286 while (c != RightQualifier && c != '\0')
13287 c = In[(*Start)++];
13288
13289 if (c == '\0')
13290 return _FALSE;
13291
13292 j = (*Start) - 2;
13293 strncpy((char *)Out, (const char *)(In + i), j - i + 1);
13294
13295 return _TRUE;
13296 }
13297
13298 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)13299 isAllSpaceOrTab(
13300 u8 *data,
13301 u8 size
13302 )
13303 {
13304 u8 cnt = 0, NumOfSpaceAndTab = 0;
13305
13306 while (size > cnt) {
13307 if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
13308 ++NumOfSpaceAndTab;
13309
13310 ++cnt;
13311 }
13312
13313 return size == NumOfSpaceAndTab;
13314 }
13315
13316
rtw_hal_check_rxfifo_full(_adapter * adapter)13317 void rtw_hal_check_rxfifo_full(_adapter *adapter)
13318 {
13319 struct dvobj_priv *psdpriv = adapter->dvobj;
13320 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
13321 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
13322 struct registry_priv *regsty = &adapter->registrypriv;
13323 int save_cnt = _FALSE;
13324
13325 if (regsty->check_hw_status == 1) {
13326 /* switch counter to RX fifo */
13327 if (IS_8188E(pHalData->version_id) ||
13328 IS_8188F(pHalData->version_id) ||
13329 IS_8188GTV(pHalData->version_id) ||
13330 IS_8812_SERIES(pHalData->version_id) ||
13331 IS_8821_SERIES(pHalData->version_id) ||
13332 IS_8723B_SERIES(pHalData->version_id) ||
13333 IS_8192E(pHalData->version_id) ||
13334 IS_8703B_SERIES(pHalData->version_id) ||
13335 IS_8723D_SERIES(pHalData->version_id) ||
13336 IS_8192F_SERIES(pHalData->version_id)) {
13337 rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
13338 save_cnt = _TRUE;
13339 } else {
13340 /* todo: other chips */
13341 }
13342
13343
13344 if (save_cnt) {
13345 pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
13346 pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
13347 pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
13348 } else {
13349 /* special value to indicate no implementation */
13350 pdbgpriv->dbg_rx_fifo_last_overflow = 1;
13351 pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
13352 pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
13353 }
13354 }
13355 }
13356
linked_info_dump(_adapter * padapter,u8 benable)13357 void linked_info_dump(_adapter *padapter, u8 benable)
13358 {
13359 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
13360
13361 if (padapter->bLinkInfoDump == benable)
13362 return;
13363
13364 RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
13365
13366 if (benable) {
13367 #ifdef CONFIG_LPS
13368 pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
13369 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
13370 #endif
13371
13372 #ifdef CONFIG_IPS
13373 pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
13374 rtw_pm_set_ips(padapter, IPS_NONE);
13375 #endif
13376 } else {
13377 #ifdef CONFIG_IPS
13378 rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
13379 #endif /* CONFIG_IPS */
13380
13381 #ifdef CONFIG_LPS
13382 rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
13383 #endif /* CONFIG_LPS */
13384 }
13385 padapter->bLinkInfoDump = benable ;
13386 }
13387
13388 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)13389 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
13390 {
13391 u8 isCCKrate, rf_path;
13392 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13393 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13394 RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
13395 HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
13396 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13397
13398 if (isCCKrate)
13399 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13400
13401 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13402 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13403 continue;
13404 RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
13405 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13406
13407 if (!isCCKrate) {
13408 RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
13409 psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
13410 }
13411 }
13412 }
13413
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)13414 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
13415 {
13416 u8 isCCKrate, rf_path;
13417 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13418 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13419 _RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
13420 _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);
13421
13422 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13423
13424 if (isCCKrate)
13425 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13426
13427 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13428 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13429 continue;
13430 _RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
13431 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13432
13433 if (!isCCKrate)
13434 _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]);
13435 else
13436 _RTW_PRINT_SEL(sel , "\n");
13437
13438 }
13439 }
13440 #endif
13441
13442 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)13443 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
13444 {
13445 #define DBG_RX_DFRAME_RAW_DATA_UC 0
13446 #define DBG_RX_DFRAME_RAW_DATA_BMC 1
13447 #define DBG_RX_DFRAME_RAW_DATA_TYPES 2
13448
13449 _irqL irqL;
13450 u8 isCCKrate, rf_path;
13451 struct recv_priv *precvpriv = &(padapter->recvpriv);
13452 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13453 struct sta_priv *pstapriv = &padapter->stapriv;
13454 struct sta_info *psta;
13455 struct sta_recv_dframe_info *psta_dframe_info;
13456 int i, j;
13457 _list *plist, *phead;
13458 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13459 u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
13460
13461 if (precvpriv->store_law_data_flag) {
13462
13463 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13464
13465 for (i = 0; i < NUM_STA; i++) {
13466 phead = &(pstapriv->sta_hash[i]);
13467 plist = get_next(phead);
13468
13469 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
13470
13471 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
13472 plist = get_next(plist);
13473
13474 if (psta) {
13475 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE)
13476 && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN) != _TRUE)
13477 && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN) != _TRUE)) {
13478
13479 RTW_PRINT_SEL(sel, "==============================\n");
13480 RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
13481
13482 for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
13483 if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
13484 psta_dframe_info = &psta->sta_dframe_info;
13485 RTW_PRINT_SEL(sel, "\n");
13486 RTW_PRINT_SEL(sel, "Unicast:\n");
13487 } else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
13488 psta_dframe_info = &psta->sta_dframe_info_bmc;
13489 RTW_PRINT_SEL(sel, "\n");
13490 RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
13491 }
13492
13493 isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13494
13495 RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
13496 RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
13497
13498 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13499 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13500 continue;
13501 if (!isCCKrate) {
13502 RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
13503 _RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
13504 } else
13505 RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
13506 }
13507 }
13508
13509 }
13510 }
13511 }
13512 }
13513 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13514 }
13515 }
13516 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)13517 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
13518 {
13519 u8 isCCKrate, rf_path , dframe_type;
13520 u8 *ptr;
13521 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13522 #ifdef DBG_RX_DFRAME_RAW_DATA
13523 struct sta_recv_dframe_info *psta_dframe_info;
13524 #endif
13525 struct recv_priv *precvpriv = &(padapter->recvpriv);
13526 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13527 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
13528 struct sta_info *psta = prframe->u.hdr.psta;
13529 struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
13530 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13531 psample_pkt_rssi->data_rate = pattrib->data_rate;
13532 ptr = prframe->u.hdr.rx_data;
13533 dframe_type = GetFrameType(ptr);
13534 /*RTW_INFO("=>%s\n", __FUNCTION__);*/
13535
13536
13537 if (precvpriv->store_law_data_flag) {
13538 isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13539
13540 psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
13541 psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
13542
13543 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13544 psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
13545 psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
13546 if (!isCCKrate) {
13547 psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13548 psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13549 }
13550 }
13551 #ifdef DBG_RX_DFRAME_RAW_DATA
13552 if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
13553
13554 /*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
13555 if (psta) {
13556 if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
13557 psta_dframe_info = &psta->sta_dframe_info_bmc;
13558 else
13559 psta_dframe_info = &psta->sta_dframe_info;
13560 /*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
13561 __FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
13562 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
13563 psta_dframe_info->sta_data_rate = pattrib->data_rate;
13564 psta_dframe_info->sta_sgi = pattrib->sgi;
13565 psta_dframe_info->sta_bw_mode = pattrib->bw;
13566 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13567
13568 psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
13569
13570 if (!isCCKrate) {
13571 psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13572 psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13573 }
13574 }
13575 }
13576 }
13577 }
13578 #endif
13579 }
13580
13581 }
13582
hal_efuse_macaddr_offset(_adapter * adapter)13583 int hal_efuse_macaddr_offset(_adapter *adapter)
13584 {
13585 u8 interface_type = 0;
13586 int addr_offset = -1;
13587
13588 interface_type = rtw_get_intf_type(adapter);
13589
13590 switch (rtw_get_chip_type(adapter)) {
13591 #ifdef CONFIG_RTL8723B
13592 case RTL8723B:
13593 if (interface_type == RTW_USB)
13594 addr_offset = EEPROM_MAC_ADDR_8723BU;
13595 else if (interface_type == RTW_SDIO)
13596 addr_offset = EEPROM_MAC_ADDR_8723BS;
13597 else if (interface_type == RTW_PCIE)
13598 addr_offset = EEPROM_MAC_ADDR_8723BE;
13599 break;
13600 #endif
13601 #ifdef CONFIG_RTL8703B
13602 case RTL8703B:
13603 if (interface_type == RTW_USB)
13604 addr_offset = EEPROM_MAC_ADDR_8703BU;
13605 else if (interface_type == RTW_SDIO)
13606 addr_offset = EEPROM_MAC_ADDR_8703BS;
13607 break;
13608 #endif
13609 #ifdef CONFIG_RTL8723D
13610 case RTL8723D:
13611 if (interface_type == RTW_USB)
13612 addr_offset = EEPROM_MAC_ADDR_8723DU;
13613 else if (interface_type == RTW_SDIO)
13614 addr_offset = EEPROM_MAC_ADDR_8723DS;
13615 else if (interface_type == RTW_PCIE)
13616 addr_offset = EEPROM_MAC_ADDR_8723DE;
13617 break;
13618 #endif
13619
13620 #ifdef CONFIG_RTL8188E
13621 case RTL8188E:
13622 if (interface_type == RTW_USB)
13623 addr_offset = EEPROM_MAC_ADDR_88EU;
13624 else if (interface_type == RTW_SDIO)
13625 addr_offset = EEPROM_MAC_ADDR_88ES;
13626 else if (interface_type == RTW_PCIE)
13627 addr_offset = EEPROM_MAC_ADDR_88EE;
13628 break;
13629 #endif
13630 #ifdef CONFIG_RTL8188F
13631 case RTL8188F:
13632 if (interface_type == RTW_USB)
13633 addr_offset = EEPROM_MAC_ADDR_8188FU;
13634 else if (interface_type == RTW_SDIO)
13635 addr_offset = EEPROM_MAC_ADDR_8188FS;
13636 break;
13637 #endif
13638 #ifdef CONFIG_RTL8188GTV
13639 case RTL8188GTV:
13640 if (interface_type == RTW_USB)
13641 addr_offset = EEPROM_MAC_ADDR_8188GTVU;
13642 else if (interface_type == RTW_SDIO)
13643 addr_offset = EEPROM_MAC_ADDR_8188GTVS;
13644 break;
13645 #endif
13646 #ifdef CONFIG_RTL8812A
13647 case RTL8812:
13648 if (interface_type == RTW_USB)
13649 addr_offset = EEPROM_MAC_ADDR_8812AU;
13650 else if (interface_type == RTW_PCIE)
13651 addr_offset = EEPROM_MAC_ADDR_8812AE;
13652 break;
13653 #endif
13654 #ifdef CONFIG_RTL8821A
13655 case RTL8821:
13656 if (interface_type == RTW_USB)
13657 addr_offset = EEPROM_MAC_ADDR_8821AU;
13658 else if (interface_type == RTW_SDIO)
13659 addr_offset = EEPROM_MAC_ADDR_8821AS;
13660 else if (interface_type == RTW_PCIE)
13661 addr_offset = EEPROM_MAC_ADDR_8821AE;
13662 break;
13663 #endif
13664 #ifdef CONFIG_RTL8192E
13665 case RTL8192E:
13666 if (interface_type == RTW_USB)
13667 addr_offset = EEPROM_MAC_ADDR_8192EU;
13668 else if (interface_type == RTW_SDIO)
13669 addr_offset = EEPROM_MAC_ADDR_8192ES;
13670 else if (interface_type == RTW_PCIE)
13671 addr_offset = EEPROM_MAC_ADDR_8192EE;
13672 break;
13673 #endif
13674 #ifdef CONFIG_RTL8814A
13675 case RTL8814A:
13676 if (interface_type == RTW_USB)
13677 addr_offset = EEPROM_MAC_ADDR_8814AU;
13678 else if (interface_type == RTW_PCIE)
13679 addr_offset = EEPROM_MAC_ADDR_8814AE;
13680 break;
13681 #endif
13682
13683 #ifdef CONFIG_RTL8822B
13684 case RTL8822B:
13685 if (interface_type == RTW_USB)
13686 addr_offset = EEPROM_MAC_ADDR_8822BU;
13687 else if (interface_type == RTW_SDIO)
13688 addr_offset = EEPROM_MAC_ADDR_8822BS;
13689 else if (interface_type == RTW_PCIE)
13690 addr_offset = EEPROM_MAC_ADDR_8822BE;
13691 break;
13692 #endif /* CONFIG_RTL8822B */
13693
13694 #ifdef CONFIG_RTL8821C
13695 case RTL8821C:
13696 if (interface_type == RTW_USB)
13697 addr_offset = EEPROM_MAC_ADDR_8821CU;
13698 else if (interface_type == RTW_SDIO)
13699 addr_offset = EEPROM_MAC_ADDR_8821CS;
13700 else if (interface_type == RTW_PCIE)
13701 addr_offset = EEPROM_MAC_ADDR_8821CE;
13702 break;
13703 #endif /* CONFIG_RTL8821C */
13704
13705 #ifdef CONFIG_RTL8710B
13706 case RTL8710B:
13707 if (interface_type == RTW_USB)
13708 addr_offset = EEPROM_MAC_ADDR_8710B;
13709 break;
13710 #endif
13711
13712 #ifdef CONFIG_RTL8192F
13713 case RTL8192F:
13714 if (interface_type == RTW_USB)
13715 addr_offset = EEPROM_MAC_ADDR_8192FU;
13716 else if (interface_type == RTW_SDIO)
13717 addr_offset = EEPROM_MAC_ADDR_8192FS;
13718 else if (interface_type == RTW_PCIE)
13719 addr_offset = EEPROM_MAC_ADDR_8192FE;
13720 break;
13721 #endif /* CONFIG_RTL8192F */
13722
13723 #ifdef CONFIG_RTL8822C
13724 case RTL8822C:
13725 if (interface_type == RTW_USB)
13726 addr_offset = EEPROM_MAC_ADDR_8822CU;
13727 else if (interface_type == RTW_SDIO)
13728 addr_offset = EEPROM_MAC_ADDR_8822CS;
13729 else if (interface_type == RTW_PCIE)
13730 addr_offset = EEPROM_MAC_ADDR_8822CE;
13731 break;
13732 #endif /* CONFIG_RTL8822C */
13733
13734 #ifdef CONFIG_RTL8814B
13735 case RTL8814B:
13736 if (interface_type == RTW_USB)
13737 addr_offset = EEPROM_MAC_ADDR_8814BU;
13738 else if (interface_type == RTW_PCIE)
13739 addr_offset = EEPROM_MAC_ADDR_8814BE;
13740 break;
13741 #endif /* CONFIG_RTL8814B */
13742 }
13743
13744 if (addr_offset == -1) {
13745 RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
13746 , __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
13747 }
13748
13749 return addr_offset;
13750 }
13751
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)13752 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
13753 {
13754 int ret = _FAIL;
13755 int addr_offset;
13756
13757 addr_offset = hal_efuse_macaddr_offset(padapter);
13758 if (addr_offset == -1)
13759 goto exit;
13760
13761 ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
13762
13763 exit:
13764 return ret;
13765 }
13766
rtw_dump_cur_efuse(PADAPTER padapter)13767 void rtw_dump_cur_efuse(PADAPTER padapter)
13768 {
13769 int mapsize =0;
13770 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13771
13772 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
13773
13774 if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
13775 RTW_ERR("wrong map size %d\n", mapsize);
13776 return;
13777 }
13778
13779 #ifdef CONFIG_RTW_DEBUG
13780 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13781 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
13782 else
13783 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
13784 #endif
13785 }
13786
13787
13788 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)13789 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
13790 {
13791 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13792 u32 ret = _FALSE;
13793 u32 maplen = 0;
13794
13795 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
13796
13797 if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
13798 RTW_ERR("eFuse length error :%d\n", maplen);
13799 return _FALSE;
13800 }
13801
13802 ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
13803
13804 hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
13805
13806 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13807 rtw_dump_cur_efuse(padapter);
13808
13809 return ret;
13810 }
13811
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)13812 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
13813 {
13814 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13815 u32 ret = _FAIL;
13816
13817 if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
13818 && rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
13819 ) {
13820 hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
13821 ret = _SUCCESS;
13822 } else
13823 hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
13824
13825 return ret;
13826 }
13827 #endif /* CONFIG_EFUSE_CONFIG_FILE */
13828
hal_config_macaddr(_adapter * adapter,bool autoload_fail)13829 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
13830 {
13831 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13832 u8 addr[ETH_ALEN];
13833 int addr_offset = hal_efuse_macaddr_offset(adapter);
13834 u8 *hw_addr = NULL;
13835 int ret = _SUCCESS;
13836 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13837 u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
13838 #endif
13839
13840 if (autoload_fail)
13841 goto bypass_hw_pg;
13842
13843 if (addr_offset != -1)
13844 hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
13845
13846 #ifdef CONFIG_EFUSE_CONFIG_FILE
13847 /* if the hw_addr is written by efuse file, set to NULL */
13848 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13849 hw_addr = NULL;
13850 #endif
13851
13852 if (!hw_addr) {
13853 /* try getting hw pg data */
13854 if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
13855 hw_addr = addr;
13856 }
13857
13858 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13859 if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
13860 hw_addr[0] = 0xff;
13861 #endif
13862
13863 /* check hw pg data */
13864 if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
13865 _rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
13866 goto exit;
13867 }
13868
13869 bypass_hw_pg:
13870
13871 #ifdef CONFIG_EFUSE_CONFIG_FILE
13872 /* check wifi mac file */
13873 if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
13874 _rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
13875 goto exit;
13876 }
13877 #endif
13878
13879 _rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
13880 ret = _FAIL;
13881
13882 exit:
13883 return ret;
13884 }
13885
13886 #ifdef CONFIG_RF_POWER_TRIM
13887 u32 Array_kfreemap[] = {
13888 0x08, 0xe,
13889 0x06, 0xc,
13890 0x04, 0xa,
13891 0x02, 0x8,
13892 0x00, 0x6,
13893 0x03, 0x4,
13894 0x05, 0x2,
13895 0x07, 0x0,
13896 0x09, 0x0,
13897 0x0c, 0x0,
13898 };
13899
rtw_bb_rf_gain_offset(_adapter * padapter)13900 void rtw_bb_rf_gain_offset(_adapter *padapter)
13901 {
13902 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
13903 struct registry_priv *registry_par = &padapter->registrypriv;
13904 struct kfree_data_t *kfree_data = &pHalData->kfree_data;
13905 u8 value = pHalData->EEPROMRFGainOffset;
13906 u8 tmp = 0x3e;
13907 u32 res, i = 0;
13908 u32 ArrayLen = sizeof(Array_kfreemap) / sizeof(u32);
13909 u32 *Array = Array_kfreemap;
13910 u32 v1 = 0, v2 = 0, GainValue = 0, target = 0;
13911
13912 if (registry_par->RegPwrTrimEnable == 2) {
13913 RTW_INFO("Registry kfree default force disable.\n");
13914 return;
13915 }
13916
13917 #if defined(CONFIG_RTL8723B)
13918 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
13919 RTW_INFO("Offset RF Gain.\n");
13920 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
13921
13922 if (pHalData->EEPROMRFGainVal != 0xff) {
13923
13924 if (pHalData->ant_path == RF_PATH_A)
13925 GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
13926
13927 else
13928 GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
13929 RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
13930
13931 for (i = 0; i < ArrayLen; i += 2) {
13932 /* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
13933 v1 = Array[i];
13934 v2 = Array[i + 1];
13935 if (v1 == GainValue) {
13936 RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
13937 target = v2;
13938 break;
13939 }
13940 }
13941 RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
13942
13943 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13944 RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
13945 phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
13946 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13947
13948 RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
13949
13950 } else
13951
13952 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
13953 } else
13954 RTW_INFO("Using the default RF gain.\n");
13955
13956 #elif defined(CONFIG_RTL8188E)
13957 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
13958 RTW_INFO("8188ES Offset RF Gain.\n");
13959 RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
13960 pHalData->EEPROMRFGainVal);
13961
13962 if (pHalData->EEPROMRFGainVal != 0xff) {
13963 res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
13964 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
13965
13966 RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
13967 res &= 0xfff87fff;
13968
13969 res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
13970 RTW_INFO("Offset RF Gain. res=0x%x\n", res);
13971
13972 rtw_hal_write_rfreg(padapter, RF_PATH_A,
13973 REG_RF_BB_GAIN_OFFSET,
13974 RF_GAIN_OFFSET_MASK, res);
13975 } else {
13976 RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
13977 pHalData->EEPROMRFGainVal);
13978 }
13979 } else
13980 RTW_INFO("Using the default RF gain.\n");
13981 #else
13982 /* TODO: call this when channel switch */
13983 if (kfree_data->flag & KFREE_FLAG_ON)
13984 rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
13985 #endif
13986
13987 }
13988 #endif /*CONFIG_RF_POWER_TRIM */
13989
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)13990 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
13991 {
13992 #ifdef CONFIG_RF_POWER_TRIM
13993 int i, j;
13994
13995 for (i = 0; i < BB_GAIN_NUM; i++)
13996 for (j = 0; j < RF_PATH_MAX; j++)
13997 if (data->bb_gain[i][j] != 0)
13998 return 0;
13999 #endif
14000 return 1;
14001 }
14002
14003 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)14004 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
14005 {
14006 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14007 if (cur_wireless_mode < WIRELESS_11_24N
14008 && cur_wireless_mode > 0) { /* ABG mode */
14009 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14010 u32 remainder = 0;
14011 u8 quotient = 0;
14012
14013 remainder = MAX_RECVBUF_SZ % (4 * 1024);
14014 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14015
14016 if (quotient > 5) {
14017 pHalData->rxagg_usb_size = 0x6;
14018 pHalData->rxagg_usb_timeout = 0x10;
14019 } else {
14020 if (remainder >= 2048) {
14021 pHalData->rxagg_usb_size = quotient;
14022 pHalData->rxagg_usb_timeout = 0x10;
14023 } else {
14024 pHalData->rxagg_usb_size = (quotient - 1);
14025 pHalData->rxagg_usb_timeout = 0x10;
14026 }
14027 }
14028 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14029 if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
14030 pHalData->rxagg_usb_size = 0x6;
14031 pHalData->rxagg_usb_timeout = 0x10;
14032 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14033 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14034 }
14035 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14036
14037 } else if (cur_wireless_mode >= WIRELESS_11_24N
14038 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14039 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14040 u32 remainder = 0;
14041 u8 quotient = 0;
14042
14043 remainder = MAX_RECVBUF_SZ % (4 * 1024);
14044 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14045
14046 if (quotient > 5) {
14047 pHalData->rxagg_usb_size = 0x5;
14048 pHalData->rxagg_usb_timeout = 0x20;
14049 } else {
14050 if (remainder >= 2048) {
14051 pHalData->rxagg_usb_size = quotient;
14052 pHalData->rxagg_usb_timeout = 0x10;
14053 } else {
14054 pHalData->rxagg_usb_size = (quotient - 1);
14055 pHalData->rxagg_usb_timeout = 0x10;
14056 }
14057 }
14058 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14059 if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
14060 pHalData->rxagg_usb_size = 0x5;
14061 pHalData->rxagg_usb_timeout = 0x20;
14062 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14063 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14064 }
14065 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14066
14067 } else {
14068 /* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14069 }
14070 }
14071
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)14072 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
14073 {
14074 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14075
14076 if (cur_wireless_mode < WIRELESS_11_24N
14077 && cur_wireless_mode > 0) { /* ABG mode */
14078 if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
14079 || 0x10 != pHalData->rxagg_usb_timeout) {
14080 pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
14081 pHalData->rxagg_usb_timeout = 0x10;
14082 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14083 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14084 }
14085 } else if (cur_wireless_mode >= WIRELESS_11_24N
14086 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14087 if (UsbDmaSize != pHalData->rxagg_usb_size
14088 || 0x20 != pHalData->rxagg_usb_timeout) {
14089 pHalData->rxagg_usb_size = UsbDmaSize;
14090 pHalData->rxagg_usb_timeout = 0x20;
14091 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14092 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14093 }
14094 } else {
14095 /* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14096 }
14097 }
14098
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)14099 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
14100 {
14101 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14102 rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
14103 return;
14104 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14105
14106 rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
14107 }
14108 #endif /* CONFIG_USB_RX_AGGREGATION */
14109
14110 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)14111 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
14112 {
14113 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
14114 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14115 struct registry_priv *registry_par = &padapter->registrypriv;
14116 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14117 u8 cur_wireless_mode = WIRELESS_INVALID;
14118
14119 #ifdef CONFIG_USB_RX_AGGREGATION
14120 if (!registry_par->dynamic_agg_enable)
14121 return;
14122
14123 #ifdef RTW_HALMAC
14124 if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter)
14125 || IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter))
14126 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
14127 #else /* !RTW_HALMAC */
14128 if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
14129 /* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
14130 if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) {
14131 if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14132 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
14133 else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14134 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
14135 else
14136 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
14137
14138 /* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
14139 }
14140 } else if (IS_HARDWARE_TYPE_8812(padapter)) {
14141 #ifdef CONFIG_CONCURRENT_MODE
14142 u8 i;
14143 _adapter *iface;
14144 u8 bassocaed = _FALSE;
14145 struct mlme_ext_priv *mlmeext;
14146
14147 for (i = 0; i < pdvobjpriv->iface_nums; i++) {
14148 iface = pdvobjpriv->padapters[i];
14149 mlmeext = &iface->mlmeextpriv;
14150 if (rtw_linked_check(iface) == _TRUE) {
14151 if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
14152 cur_wireless_mode = mlmeext->cur_wireless_mode;
14153 bassocaed = _TRUE;
14154 }
14155 }
14156 if (bassocaed)
14157 #endif
14158 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14159 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14160 } else {
14161 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14162 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14163 }
14164 #endif /* RTW_HALMAC */
14165 #endif /* CONFIG_USB_RX_AGGREGATION */
14166
14167 }
14168
14169 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)14170 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
14171 {
14172 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14173 u8 chk_rst = _SUCCESS;
14174
14175 if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
14176 return chk_rst;
14177
14178 /* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
14179 /* return chk_rst; */
14180
14181 if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
14182 && (pre_qsel != next_qsel)) {
14183 /* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
14184 /* pre_qsel,next_qsel); */
14185 chk_rst = _FAIL;
14186 }
14187 return chk_rst;
14188 }
14189
14190 /*
14191 * Description:
14192 * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
14193 * contant.
14194 *
14195 * Input:
14196 * adapter: adapter pointer.
14197 * page_num: The max. page number that user want to dump.
14198 * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
14199 */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)14200 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
14201 {
14202
14203 int i;
14204 u8 val = 0;
14205 u8 base = 0;
14206 u32 addr = 0;
14207 u32 count = (page_size / 8);
14208
14209 if (page_num <= 0) {
14210 RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
14211 return;
14212 }
14213
14214 if (page_size < 128 || page_size > 512) {
14215 RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
14216 return;
14217 }
14218
14219 RTW_INFO("+%s+\n", __func__);
14220 val = rtw_read8(padapter, 0x106);
14221 rtw_write8(padapter, 0x106, 0x69);
14222 RTW_INFO("0x106: 0x%02x\n", val);
14223 base = rtw_read8(padapter, 0x209);
14224 RTW_INFO("0x209: 0x%02x\n", base);
14225
14226 addr = ((base)*page_size) / 8;
14227 for (i = 0 ; i < page_num * count ; i += 2) {
14228 rtw_write32(padapter, 0x140, addr + i);
14229 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14230 rtw_write32(padapter, 0x140, addr + i + 1);
14231 printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14232 }
14233 }
14234
14235 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)14236 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
14237 {
14238 u8 value = 0;
14239 u8 direction = 0;
14240 u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
14241 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
14242 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
14243 u8 gpio_num_to_set = gpio_num;
14244 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
14245
14246 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14247 return value;
14248
14249 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14250
14251 RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
14252 LeaveAllPowerSaveModeDirect(adapter);
14253
14254 if (gpio_num > 7) {
14255 gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
14256 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
14257 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
14258 gpio_num_to_set = gpio_num - 8;
14259 }
14260
14261 /* Read GPIO Direction */
14262 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14263
14264 /* According the direction to read register value */
14265 if (direction)
14266 value = (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14267 else
14268 value = (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14269
14270 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14271 RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
14272
14273 return value;
14274 }
14275
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)14276 int rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
14277 {
14278 u8 direction = 0;
14279 u8 res = -1;
14280 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
14281 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
14282 u8 gpio_num_to_set = gpio_num;
14283
14284 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14285 return -1;
14286
14287 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14288
14289 LeaveAllPowerSaveModeDirect(adapter);
14290
14291 if (gpio_num > 7) {
14292 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
14293 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
14294 gpio_num_to_set = gpio_num - 8;
14295 }
14296
14297 /* Read GPIO direction */
14298 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14299
14300 /* If GPIO is output direction, setting value. */
14301 if (direction) {
14302 if (isHigh)
14303 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
14304 else
14305 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
14306
14307 RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
14308 res = 0;
14309 } else {
14310 RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
14311 res = -1;
14312 }
14313
14314 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14315 return res;
14316 }
14317
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)14318 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
14319 {
14320 u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
14321 u8 gpio_num_to_set = gpio_num;
14322
14323 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14324 return -1;
14325
14326 RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
14327
14328 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14329
14330 LeaveAllPowerSaveModeDirect(adapter);
14331
14332 rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
14333
14334 if (gpio_num > 7) {
14335 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
14336 gpio_num_to_set = gpio_num - 8;
14337 }
14338
14339 if (isOutput)
14340 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
14341 else
14342 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
14343
14344 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14345
14346 return 0;
14347 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))14348 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
14349 {
14350 u8 value;
14351 u8 direction;
14352 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14353
14354 if (IS_HARDWARE_TYPE_8188E(adapter)) {
14355 if (gpio_num > 7 || gpio_num < 4) {
14356 RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14357 return -1;
14358 }
14359 }
14360
14361 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14362
14363 LeaveAllPowerSaveModeDirect(adapter);
14364
14365 /* Read GPIO direction */
14366 direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
14367 if (direction) {
14368 RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
14369 return -1;
14370 }
14371
14372 /* Config GPIO Mode */
14373 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
14374
14375 /* Register GPIO interrupt handler*/
14376 adapter->gpiointpriv.callback[gpio_num] = callback;
14377
14378 /* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
14379 value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
14380 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
14381 rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
14382
14383 /* Enable GPIO interrupt */
14384 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
14385 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14386
14387 rtw_hal_update_hisr_hsisr_ind(adapter, 1);
14388
14389 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14390
14391 return 0;
14392 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)14393 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
14394 {
14395 u8 value;
14396 u8 direction;
14397 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14398
14399 if (IS_HARDWARE_TYPE_8188E(adapter)) {
14400 if (gpio_num > 7 || gpio_num < 4) {
14401 RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14402 return -1;
14403 }
14404 }
14405
14406 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14407
14408 LeaveAllPowerSaveModeDirect(adapter);
14409
14410 /* Config GPIO Mode */
14411 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
14412
14413 /* Unregister GPIO interrupt handler*/
14414 adapter->gpiointpriv.callback[gpio_num] = NULL;
14415
14416 /* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
14417 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
14418 rtw_write8(adapter, REG_GPIO_INTM, 0x00);
14419
14420 /* Disable GPIO interrupt */
14421 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
14422 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14423
14424 if (!adapter->gpiointpriv.interrupt_enable_mask)
14425 rtw_hal_update_hisr_hsisr_ind(adapter, 0);
14426
14427 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14428
14429 return 0;
14430 }
14431 #endif
14432
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)14433 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
14434 {
14435 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14436 u8 i;
14437
14438 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14439 if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
14440 if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
14441 && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
14442 return i;
14443 }
14444 }
14445
14446 return -1;
14447 }
14448
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)14449 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
14450 {
14451 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14452 s8 res;
14453 u8 i;
14454
14455 /* If it's an existed record, overwrite it */
14456 res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
14457 if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
14458 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
14459 return;
14460 }
14461
14462 /* Search for the empty record to use */
14463 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14464 if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
14465 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
14466 return;
14467 }
14468 }
14469
14470 /* Else, overwrite the oldest record */
14471 for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
14472 _rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
14473
14474 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
14475 }
14476
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)14477 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
14478 {
14479 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
14480 }
14481
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14482 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14483 {
14484 u32 mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
14485 u32 mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
14486 u32 mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
14487 u32 DropPacket = 0;
14488
14489 if (!rx_counter) {
14490 rtw_warn_on(1);
14491 return;
14492 }
14493 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
14494 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14495
14496 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
14497 mac_cck_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14498 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14499 mac_ofdm_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14500 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
14501 mac_ht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14502 mac_vht_ok = 0;
14503 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14504 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14505 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14506 mac_vht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14507 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14508 }
14509
14510 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
14511 mac_cck_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14512 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14513 mac_ofdm_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14514 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
14515 mac_ht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14516 mac_vht_err = 0;
14517 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14518 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14519 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14520 mac_vht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14521 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14522 }
14523
14524 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
14525 mac_cck_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14526 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
14527 mac_ofdm_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14528 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
14529 mac_ht_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14530
14531 /* Mac_DropPacket */
14532 rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
14533 DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
14534
14535 rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
14536 rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
14537 rx_counter->rx_cck_fa = mac_cck_fa;
14538 rx_counter->rx_ofdm_fa = mac_ofdm_fa;
14539 rx_counter->rx_ht_fa = mac_ht_fa;
14540 rx_counter->rx_pkt_drop = DropPacket;
14541 }
rtw_reset_mac_rx_counters(_adapter * padapter)14542 void rtw_reset_mac_rx_counters(_adapter *padapter)
14543 {
14544
14545 /* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
14546 if (IS_HARDWARE_TYPE_8703B(padapter) ||
14547 IS_HARDWARE_TYPE_8723D(padapter) ||
14548 IS_HARDWARE_TYPE_8188F(padapter) ||
14549 IS_HARDWARE_TYPE_8188GTV(padapter) ||
14550 IS_HARDWARE_TYPE_8192F(padapter) ||
14551 IS_HARDWARE_TYPE_8822C(padapter))
14552 phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
14553
14554 /* reset mac counter */
14555 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
14556 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
14557 }
14558
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14559 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14560 {
14561 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;
14562 if (!rx_counter) {
14563 rtw_warn_on(1);
14564 return;
14565 }
14566 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14567 cckok = phy_query_bb_reg(padapter, 0xF04, 0x3FFF); /* [13:0] */
14568 ofdmok = phy_query_bb_reg(padapter, 0xF14, 0x3FFF); /* [13:0] */
14569 htok = phy_query_bb_reg(padapter, 0xF10, 0x3FFF); /* [13:0] */
14570 vht_ok = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF); /* [13:0] */
14571 cckcrc = phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16] */
14572 ofdmcrc = phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
14573 htcrc = phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
14574 vht_err = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
14575 CCK_FA = phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
14576 OFDM_FA = phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
14577 } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){
14578 cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);
14579 ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
14580 htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
14581 vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);
14582 cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);
14583 ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
14584 htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
14585 vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);
14586 CCK_FA = phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);
14587 OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
14588
14589 } else {
14590 cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
14591 ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
14592 htok = phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
14593 vht_ok = 0;
14594 cckcrc = phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
14595 ofdmcrc = phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
14596 htcrc = phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
14597 vht_err = 0;
14598 OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
14599 phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
14600 phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
14601
14602 CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
14603 }
14604
14605 rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
14606 rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
14607 rx_counter->rx_ofdm_fa = OFDM_FA;
14608 rx_counter->rx_cck_fa = CCK_FA;
14609
14610 }
14611
rtw_reset_phy_trx_ok_counters(_adapter * padapter)14612 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
14613 {
14614 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14615 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
14616 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
14617 } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14618 phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);
14619 phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);
14620 } else {
14621 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14622 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14623 }
14624 }
14625
rtw_reset_phy_rx_counters(_adapter * padapter)14626 void rtw_reset_phy_rx_counters(_adapter *padapter)
14627 {
14628 /* reset phy counter */
14629 if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14630 /* reset CCK FA counter */
14631 phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);
14632 phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);
14633
14634 /* reset CCK CCA counter */
14635 phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);
14636 phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);
14637 rtw_reset_phy_trx_ok_counters(padapter);
14638
14639 } else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14640 rtw_reset_phy_trx_ok_counters(padapter);
14641
14642 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset OFDA FA counter */
14643 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
14644
14645 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
14646 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14647 } else {
14648 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14649 rtw_msleep_os(10);
14650 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14651
14652 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset OFDA FA counter */
14653 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset OFDA FA counter */
14654 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
14655 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
14656
14657 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
14658 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14659 }
14660 }
14661 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14662 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14663 {
14664 struct recv_priv *precvpriv = &padapter->recvpriv;
14665 if (!rx_counter) {
14666 rtw_warn_on(1);
14667 return;
14668 }
14669 rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
14670 rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
14671 rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
14672 }
rtw_reset_drv_rx_counters(_adapter * padapter)14673 void rtw_reset_drv_rx_counters(_adapter *padapter)
14674 {
14675 struct recv_priv *precvpriv = &padapter->recvpriv;
14676 padapter->drv_rx_cnt_ok = 0;
14677 padapter->drv_rx_cnt_crcerror = 0;
14678 padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
14679 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)14680 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
14681 {
14682 u8 initialgain;
14683 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14684
14685 if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
14686 rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
14687 RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
14688 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14689 /*disable dynamic functions, such as high power, DIG*/
14690 rtw_phydm_ability_backup(padapter);
14691 rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
14692 } else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
14693 /* turn on phy-dynamic functions */
14694 rtw_phydm_ability_restore(padapter);
14695 initialgain = 0xff; /* restore RX GAIN */
14696 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14697
14698 }
14699 }
14700
rtw_dump_rx_counters(_adapter * padapter)14701 void rtw_dump_rx_counters(_adapter *padapter)
14702 {
14703 struct dbg_rx_counter rx_counter;
14704
14705 if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
14706 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14707 rtw_dump_drv_rx_counters(padapter, &rx_counter);
14708 RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
14709 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
14710 rtw_reset_drv_rx_counters(padapter);
14711 }
14712
14713 if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
14714 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14715 rtw_dump_mac_rx_counters(padapter, &rx_counter);
14716 RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
14717 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
14718 rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
14719 rx_counter.rx_pkt_drop);
14720 rtw_reset_mac_rx_counters(padapter);
14721 }
14722
14723 if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
14724 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14725 rtw_dump_phy_rx_counters(padapter, &rx_counter);
14726 /* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
14727 /* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
14728 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,
14729 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
14730 rtw_reset_phy_rx_counters(padapter);
14731 }
14732 }
14733 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)14734 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
14735 {
14736 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14737 u8 curr_tx_sgi = 0;
14738 struct ra_sta_info *ra_info;
14739
14740 if (!psta)
14741 return curr_tx_sgi;
14742
14743 if (padapter->fix_rate == 0xff) {
14744 #if defined(CONFIG_RTL8188E)
14745 #if (RATE_ADAPTIVE_SUPPORT == 1)
14746 curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
14747 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14748 #else
14749 ra_info = &psta->cmn.ra_info;
14750 curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
14751 #endif
14752 } else {
14753 curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
14754 }
14755
14756 return curr_tx_sgi;
14757 }
14758
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)14759 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
14760 {
14761 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14762 u8 rate_id = 0;
14763 struct ra_sta_info *ra_info;
14764
14765 if (!psta)
14766 return rate_id;
14767
14768 if (padapter->fix_rate == 0xff) {
14769 #if defined(CONFIG_RTL8188E)
14770 #if (RATE_ADAPTIVE_SUPPORT == 1)
14771 rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
14772 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14773 #else
14774 ra_info = &psta->cmn.ra_info;
14775 rate_id = ra_info->curr_tx_rate & 0x7f;
14776 #endif
14777 } else {
14778 rate_id = padapter->fix_rate & 0x7f;
14779 }
14780
14781 return rate_id;
14782 }
14783
update_IOT_info(_adapter * padapter)14784 void update_IOT_info(_adapter *padapter)
14785 {
14786 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14787 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14788
14789 switch (pmlmeinfo->assoc_AP_vendor) {
14790 case HT_IOT_PEER_MARVELL:
14791 pmlmeinfo->turboMode_cts2self = 1;
14792 pmlmeinfo->turboMode_rtsen = 0;
14793 break;
14794
14795 case HT_IOT_PEER_RALINK:
14796 pmlmeinfo->turboMode_cts2self = 0;
14797 pmlmeinfo->turboMode_rtsen = 1;
14798 break;
14799 case HT_IOT_PEER_REALTEK:
14800 /* rtw_write16(padapter, 0x4cc, 0xffff); */
14801 /* rtw_write16(padapter, 0x546, 0x01c0); */
14802 break;
14803 default:
14804 pmlmeinfo->turboMode_cts2self = 0;
14805 pmlmeinfo->turboMode_rtsen = 1;
14806 break;
14807 }
14808
14809 }
14810 #ifdef CONFIG_RTS_FULL_BW
14811 /*
14812 8188E: not support full RTS BW feature(mac REG no define 480[5])
14813 */
rtw_set_rts_bw(_adapter * padapter)14814 void rtw_set_rts_bw(_adapter *padapter) {
14815 int i;
14816 u8 enable = 1;
14817 bool connect_to_8812 = _FALSE;
14818 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14819 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14820 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
14821 struct sta_info *station = NULL;
14822
14823 for (i = 0; i < macid_ctl->num; i++) {
14824 if (rtw_macid_is_used(macid_ctl, i)) {
14825
14826 station = NULL;
14827 station = macid_ctl->sta[i];
14828 if(station) {
14829
14830 _adapter *sta_adapter =station->padapter;
14831 struct mlme_ext_priv *pmlmeext = &(sta_adapter->mlmeextpriv);
14832 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14833
14834 if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {
14835 if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) {
14836 if ( macid_ctl->sta[i]->vendor_8812) {
14837 connect_to_8812 = _TRUE;
14838 enable = 0;
14839 }
14840 }
14841 }
14842 }
14843 }
14844
14845 if(connect_to_8812)
14846 break;
14847 }
14848
14849 RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);
14850 rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);
14851 }
14852 #endif/*CONFIG_RTS_FULL_BW*/
14853
hal_spec_init(_adapter * adapter)14854 int hal_spec_init(_adapter *adapter)
14855 {
14856 u8 interface_type = 0;
14857 int ret = _SUCCESS;
14858
14859 interface_type = rtw_get_intf_type(adapter);
14860
14861 switch (rtw_get_chip_type(adapter)) {
14862 #ifdef CONFIG_RTL8723B
14863 case RTL8723B:
14864 init_hal_spec_8723b(adapter);
14865 break;
14866 #endif
14867 #ifdef CONFIG_RTL8703B
14868 case RTL8703B:
14869 init_hal_spec_8703b(adapter);
14870 break;
14871 #endif
14872 #ifdef CONFIG_RTL8723D
14873 case RTL8723D:
14874 init_hal_spec_8723d(adapter);
14875 break;
14876 #endif
14877 #ifdef CONFIG_RTL8188E
14878 case RTL8188E:
14879 init_hal_spec_8188e(adapter);
14880 break;
14881 #endif
14882 #ifdef CONFIG_RTL8188F
14883 case RTL8188F:
14884 init_hal_spec_8188f(adapter);
14885 break;
14886 #endif
14887 #ifdef CONFIG_RTL8188GTV
14888 case RTL8188GTV:
14889 init_hal_spec_8188gtv(adapter);
14890 break;
14891 #endif
14892 #ifdef CONFIG_RTL8812A
14893 case RTL8812:
14894 init_hal_spec_8812a(adapter);
14895 break;
14896 #endif
14897 #ifdef CONFIG_RTL8821A
14898 case RTL8821:
14899 init_hal_spec_8821a(adapter);
14900 break;
14901 #endif
14902 #ifdef CONFIG_RTL8192E
14903 case RTL8192E:
14904 init_hal_spec_8192e(adapter);
14905 break;
14906 #endif
14907 #ifdef CONFIG_RTL8814A
14908 case RTL8814A:
14909 init_hal_spec_8814a(adapter);
14910 break;
14911 #endif
14912 #ifdef CONFIG_RTL8822B
14913 case RTL8822B:
14914 rtl8822b_init_hal_spec(adapter);
14915 break;
14916 #endif
14917 #ifdef CONFIG_RTL8821C
14918 case RTL8821C:
14919 init_hal_spec_rtl8821c(adapter);
14920 break;
14921 #endif
14922 #ifdef CONFIG_RTL8710B
14923 case RTL8710B:
14924 init_hal_spec_8710b(adapter);
14925 break;
14926 #endif
14927 #ifdef CONFIG_RTL8192F
14928 case RTL8192F:
14929 init_hal_spec_8192f(adapter);
14930 break;
14931 #endif
14932 #ifdef CONFIG_RTL8822C
14933 case RTL8822C:
14934 rtl8822c_init_hal_spec(adapter);
14935 break;
14936 #endif
14937 #ifdef CONFIG_RTL8814B
14938 case RTL8814B:
14939 rtl8814b_init_hal_spec(adapter);
14940 break;
14941 #endif
14942 default:
14943 RTW_ERR("%s: unknown chip_type:%u\n"
14944 , __func__, rtw_get_chip_type(adapter));
14945 ret = _FAIL;
14946 break;
14947 }
14948
14949 return ret;
14950 }
14951
14952 static const char *const _band_cap_str[] = {
14953 /* BIT0 */"2G",
14954 /* BIT1 */"5G",
14955 };
14956
14957 static const char *const _bw_cap_str[] = {
14958 /* BIT0 */"5M",
14959 /* BIT1 */"10M",
14960 /* BIT2 */"20M",
14961 /* BIT3 */"40M",
14962 /* BIT4 */"80M",
14963 /* BIT5 */"160M",
14964 /* BIT6 */"80_80M",
14965 };
14966
14967 static const char *const _proto_cap_str[] = {
14968 /* BIT0 */"b",
14969 /* BIT1 */"g",
14970 /* BIT2 */"n",
14971 /* BIT3 */"ac",
14972 };
14973
14974 static const char *const _wl_func_str[] = {
14975 /* BIT0 */"P2P",
14976 /* BIT1 */"MIRACAST",
14977 /* BIT2 */"TDLS",
14978 /* BIT3 */"FTM",
14979 };
14980
dump_hal_spec(void * sel,_adapter * adapter)14981 void dump_hal_spec(void *sel, _adapter *adapter)
14982 {
14983 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
14984 int i;
14985
14986 RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
14987 RTW_PRINT_SEL(sel, "macid_cap:%u\n", hal_spec->macid_cap);
14988 RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
14989 RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
14990
14991 RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
14992 RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
14993 RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);
14994 RTW_PRINT_SEL(sel, "rf_reg_path_avail_num:%u\n", hal_spec->rf_reg_path_avail_num);
14995 RTW_PRINT_SEL(sel, "rf_reg_trx_path_bmp:0x%02x\n", hal_spec->rf_reg_trx_path_bmp);
14996 RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
14997
14998 RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
14999 RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
15000
15001 RTW_PRINT_SEL(sel, "band_cap:");
15002 for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
15003 if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
15004 _RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
15005 }
15006 _RTW_PRINT_SEL(sel, "\n");
15007
15008 RTW_PRINT_SEL(sel, "bw_cap:");
15009 for (i = 0; i < BW_CAP_BIT_NUM; i++) {
15010 if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
15011 _RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
15012 }
15013 _RTW_PRINT_SEL(sel, "\n");
15014
15015 RTW_PRINT_SEL(sel, "proto_cap:");
15016 for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
15017 if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
15018 _RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
15019 }
15020 _RTW_PRINT_SEL(sel, "\n");
15021
15022 RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
15023 RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
15024
15025 RTW_PRINT_SEL(sel, "wl_func:");
15026 for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
15027 if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
15028 _RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
15029 }
15030 _RTW_PRINT_SEL(sel, "\n");
15031
15032 #if CONFIG_TX_AC_LIFETIME
15033 RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"
15034 , hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);
15035 #endif
15036
15037 RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
15038
15039 RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
15040 RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
15041 }
15042
hal_chk_band_cap(_adapter * adapter,u8 cap)15043 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
15044 {
15045 return GET_HAL_SPEC(adapter)->band_cap & cap;
15046 }
15047
hal_chk_bw_cap(_adapter * adapter,u8 cap)15048 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
15049 {
15050 return GET_HAL_SPEC(adapter)->bw_cap & cap;
15051 }
15052
hal_chk_proto_cap(_adapter * adapter,u8 cap)15053 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
15054 {
15055 return GET_HAL_SPEC(adapter)->proto_cap & cap;
15056 }
15057
hal_chk_wl_func(_adapter * adapter,u8 func)15058 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
15059 {
15060 return GET_HAL_SPEC(adapter)->wl_func & func;
15061 }
15062
hal_is_band_support(_adapter * adapter,u8 band)15063 inline bool hal_is_band_support(_adapter *adapter, u8 band)
15064 {
15065 return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
15066 }
15067
hal_is_bw_support(_adapter * adapter,u8 bw)15068 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
15069 {
15070 return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
15071 }
15072
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)15073 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
15074 {
15075 u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
15076
15077 if (mode == WIRELESS_11B)
15078 if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15079 return 1;
15080
15081 if (mode == WIRELESS_11G)
15082 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15083 return 1;
15084
15085 if (mode == WIRELESS_11A)
15086 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15087 return 1;
15088
15089 if (mode == WIRELESS_11_24N)
15090 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15091 return 1;
15092
15093 if (mode == WIRELESS_11_5N)
15094 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15095 return 1;
15096
15097 if (mode == WIRELESS_11AC)
15098 if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15099 return 1;
15100
15101 return 0;
15102 }
hal_is_mimo_support(_adapter * adapter)15103 inline bool hal_is_mimo_support(_adapter *adapter)
15104 {
15105 if ((GET_HAL_TX_NSS(adapter) == 1) &&
15106 (GET_HAL_RX_NSS(adapter) == 1))
15107 return 0;
15108 return 1;
15109 }
15110
15111 /*
15112 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
15113 * @adapter:
15114 * @in_bw: starting bw, value of enum channel_width
15115 *
15116 * Returns: value of enum channel_width
15117 */
hal_largest_bw(_adapter * adapter,u8 in_bw)15118 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
15119 {
15120 for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
15121 if (hal_is_bw_support(adapter, in_bw))
15122 break;
15123 }
15124
15125 if (!hal_is_bw_support(adapter, in_bw))
15126 rtw_warn_on(1);
15127
15128 return in_bw;
15129 }
15130
15131 #ifndef CONFIG_HAS_TX_BEACON_PAUSE
ResumeTxBeacon(_adapter * padapter)15132 void ResumeTxBeacon(_adapter *padapter)
15133 {
15134 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15135 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
15136
15137 #ifdef RTW_HALMAC
15138 /* Add this for driver using HALMAC because driver doesn't have setup time init by self */
15139 /* TBTT setup time */
15140 rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
15141 #endif
15142
15143 /* TBTT hold time: 0x540[19:8] */
15144 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
15145 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15146 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
15147 }
15148
StopTxBeacon(_adapter * padapter)15149 void StopTxBeacon(_adapter *padapter)
15150 {
15151 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15152 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
15153
15154 /* TBTT hold time: 0x540[19:8] */
15155 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
15156 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15157 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
15158 }
15159 #endif /* CONFIG_HAS_TX_BEACON_PAUSE */
15160
15161 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
15162
15163 #ifdef CONFIG_CLIENT_PORT_CFG
15164 const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
15165 CLT_PORT0,
15166 CLT_PORT1,
15167 CLT_PORT2,
15168 CLT_PORT3
15169 };
15170
rtw_clt_port_init(struct clt_port_t * cltp)15171 void rtw_clt_port_init(struct clt_port_t *cltp)
15172 {
15173 cltp->bmp = 0;
15174 cltp->num = 0;
15175 _rtw_spinlock_init(&cltp->lock);
15176 }
rtw_clt_port_deinit(struct clt_port_t * cltp)15177 void rtw_clt_port_deinit(struct clt_port_t *cltp)
15178 {
15179 _rtw_spinlock_free(&cltp->lock);
15180 }
_hw_client_port_alloc(_adapter * adapter)15181 static void _hw_client_port_alloc(_adapter *adapter)
15182 {
15183 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15184 struct clt_port_t *cltp = &dvobj->clt_port;
15185 _irqL irql;
15186 int i;
15187
15188 #if 0
15189 if (cltp->num > MAX_CLIENT_PORT_NUM) {
15190 RTW_ERR(ADPT_FMT" cann't alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
15191 rtw_warn_on(1);
15192 return;
15193 }
15194 #endif
15195
15196 if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
15197 RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
15198 ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
15199 return;
15200 }
15201 _enter_critical_bh(&cltp->lock, &irql);
15202 for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
15203 if (!(cltp->bmp & BIT(i)))
15204 break;
15205 }
15206
15207 if (i < MAX_CLIENT_PORT_NUM) {
15208 adapter->client_id = i;
15209 cltp->bmp |= BIT(i);
15210 adapter->client_port = _clt_port_id[i];
15211 }
15212 cltp->num++;
15213 _exit_critical_bh(&cltp->lock, &irql);
15214 RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
15215 __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
15216 }
_hw_client_port_free(_adapter * adapter)15217 static void _hw_client_port_free(_adapter *adapter)
15218 {
15219 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15220 struct clt_port_t *cltp = &dvobj->clt_port;
15221 _irqL irql;
15222
15223 #if 0
15224 if (adapter->client_id >= MAX_CLIENT_PORT_NUM) {
15225 RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
15226 /*rtw_warn_on(1);*/
15227 }
15228 #endif
15229
15230 RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
15231 __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
15232
15233 _enter_critical_bh(&cltp->lock, &irql);
15234 if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
15235 cltp->bmp &= ~ BIT(adapter->client_id);
15236 adapter->client_id = MAX_CLIENT_PORT_NUM;
15237 adapter->client_port = CLT_PORT_INVALID;
15238 }
15239 cltp->num--;
15240 if (cltp->num < 0)
15241 cltp->num = 0;
15242 _exit_critical_bh(&cltp->lock, &irql);
15243 }
rtw_hw_client_port_allocate(_adapter * adapter)15244 void rtw_hw_client_port_allocate(_adapter *adapter)
15245 {
15246 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15247
15248 if (hal_spec->port_num != 5)
15249 return;
15250
15251 _hw_client_port_alloc(adapter);
15252 }
rtw_hw_client_port_release(_adapter * adapter)15253 void rtw_hw_client_port_release(_adapter *adapter)
15254 {
15255 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15256
15257 if (hal_spec->port_num != 5)
15258 return;
15259
15260 _hw_client_port_free(adapter);
15261 }
15262 #endif /*CONFIG_CLIENT_PORT_CFG*/
15263
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)15264 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
15265 {
15266 RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
15267
15268 rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
15269
15270 /* set net_type */
15271 Set_MSR(Adapter, mode);
15272
15273 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
15274 if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
15275 StopTxBeacon(Adapter);
15276 } else if (mode == _HW_STATE_ADHOC_)
15277 ResumeTxBeacon(Adapter);
15278 else if (mode == _HW_STATE_AP_)
15279 /* enable rx ps-poll */
15280 rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
15281
15282 /* enable rx data frame */
15283 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
15284
15285 #ifdef CONFIG_CLIENT_PORT_CFG
15286 if (mode == _HW_STATE_STATION_)
15287 rtw_hw_client_port_allocate(Adapter);
15288 else
15289 rtw_hw_client_port_release(Adapter);
15290 #endif
15291 #if defined(CONFIG_RTL8192F)
15292 rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
15293 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
15294 #endif
15295 }
15296 #endif
15297
15298 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)15299 u8 rtw_hal_antdiv_before_linked(_adapter *padapter)
15300 {
15301 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15302 u8 cur_ant, change_ant;
15303
15304 if (!pHalData->AntDivCfg)
15305 return _FALSE;
15306
15307 if (pHalData->sw_antdiv_bl_state == 0) {
15308 pHalData->sw_antdiv_bl_state = 1;
15309
15310 rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
15311 change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
15312
15313 return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
15314 }
15315
15316 pHalData->sw_antdiv_bl_state = 0;
15317 return _FALSE;
15318 }
15319
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)15320 void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
15321 {
15322 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15323
15324 if (pHalData->AntDivCfg) {
15325 /*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
15326 /*select optimum_antenna for before linked =>For antenna diversity*/
15327 if (dst->Rssi >= src->Rssi) {/*keep org parameter*/
15328 src->Rssi = dst->Rssi;
15329 src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
15330 }
15331 }
15332 }
15333 #endif
15334
15335 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)15336 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
15337 {
15338 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
15339 struct phy_spec_t *phy_spec = &pHalData->phy_spec;
15340
15341 RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
15342 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
15343 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
15344 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index [15:8]*/
15345 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index [7:0]*/
15346
15347 RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
15348 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]*/
15349 /*VHT STBC Rx [23:16]
15350 0 = not support
15351 1 = support for 1 spatial stream
15352 2 = support for 1 or 2 spatial streams
15353 3 = support for 1 or 2 or 3 spatial streams
15354 4 = support for 1 or 2 or 3 or 4 spatial streams*/
15355 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
15356 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]*/
15357 /*HT STBC Rx [7:0]
15358 0 = not support
15359 1 = support for 1 spatial stream
15360 2 = support for 1 or 2 spatial streams
15361 3 = support for 1 or 2 or 3 spatial streams*/
15362 RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
15363
15364 RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
15365 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]*/
15366 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]*/
15367 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]*/
15368 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]*/
15369 #ifdef CONFIG_BEAMFORMING
15370 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
15371 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]*/
15372 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]*/
15373 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]*/
15374 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]*/
15375 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF) ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
15376 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
15377
15378 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
15379 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
15380 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
15381 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
15382 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
15383 #endif
15384 }
15385 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)15386 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
15387 {
15388 u8 phy_cap = _FALSE;
15389
15390 /* STBC */
15391 rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
15392 RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15393
15394 phy_cap = _FALSE;
15395 rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
15396 RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15397
15398 /* LDPC support */
15399 phy_cap = _FALSE;
15400 rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
15401 RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15402
15403 phy_cap = _FALSE;
15404 rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
15405 RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15406
15407 #ifdef CONFIG_BEAMFORMING
15408 phy_cap = _FALSE;
15409 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
15410 RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15411
15412 phy_cap = _FALSE;
15413 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
15414 RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15415
15416 phy_cap = _FALSE;
15417 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
15418 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15419
15420 phy_cap = _FALSE;
15421 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
15422 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15423 #endif
15424 }
15425 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)15426 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
15427 {
15428 RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
15429 #ifdef CONFIG_PHY_CAPABILITY_QUERY
15430 rtw_dump_phy_cap_by_phydmapi(sel, adapter);
15431 #else
15432 rtw_dump_phy_cap_by_hal(sel, adapter);
15433 #endif
15434 }
15435
translate_dbm_to_percentage(s16 signal)15436 inline s16 translate_dbm_to_percentage(s16 signal)
15437 {
15438 if ((signal <= -100) || (signal >= 20))
15439 return 0;
15440 else if (signal >= 0)
15441 return 100;
15442 else
15443 return 100 + signal;
15444 }
15445
15446 #ifdef CONFIG_SWTIMER_BASED_TXBCN
15447 #ifdef CONFIG_BCN_RECOVERY
15448 #define REG_CPU_MGQ_INFO 0x041C
15449 #define BIT_BCN_POLL BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)15450 u8 rtw_ap_bcn_recovery(_adapter *padapter)
15451 {
15452 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15453
15454 if (hal_data->issue_bcn_fail >= 2) {
15455 RTW_ERR("%s ISSUE BCN Fail\n", __func__);
15456 rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
15457 hal_data->issue_bcn_fail = 0;
15458 }
15459 return _SUCCESS;
15460 }
15461 #endif /*CONFIG_BCN_RECOVERY*/
15462
15463 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)15464 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
15465 {
15466 u32 start_time = rtw_get_current_time();
15467 u8 bcn_queue_empty = _FALSE;
15468
15469 do {
15470 if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
15471 bcn_queue_empty = _TRUE;
15472 break;
15473 }
15474 } while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
15475
15476 if (bcn_queue_empty == _FALSE)
15477 RTW_ERR("%s BCN queue not empty\n", __func__);
15478
15479 return bcn_queue_empty;
15480 }
15481 #endif /*CONFIG_BCN_XMIT_PROTECT*/
15482 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
15483
15484 /**
15485 * rtw_hal_get_trx_path() - Get RF path related information
15486 * @d: struct dvobj_priv*
15487 * @type: RF type, nTnR
15488 * @tx: Tx path
15489 * @rx: Rx path
15490 *
15491 * Get RF type, TX path and RX path information.
15492 */
rtw_hal_get_trx_path(struct dvobj_priv * d,enum rf_type * type,enum bb_path * tx,enum bb_path * rx)15493 void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,
15494 enum bb_path *tx, enum bb_path *rx)
15495 {
15496 struct _ADAPTER *a = dvobj_get_primary_adapter(d);
15497 enum rf_type t = GET_HAL_RFPATH(a);
15498
15499 if (type)
15500 *type = t;
15501
15502 if (tx || rx) {
15503 u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);
15504 u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);
15505
15506 if (!tx_bmp && !rx_bmp)
15507 rf_type_to_default_trx_bmp(t, tx, rx);
15508 else {
15509 if (tx)
15510 *tx = GET_HAL_TX_PATH_BMP(a);
15511 if (rx)
15512 *rx = GET_HAL_RX_PATH_BMP(a);
15513 }
15514 }
15515 }
15516
15517 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
rtw_hal_switch_chnl_and_set_bw_offload(_adapter * adapter,u8 central_ch,u8 pri_ch_idx,u8 bw)15518 void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
15519 {
15520 u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
15521 PHAL_DATA_TYPE hal;
15522 struct submit_ctx *chsw_sctx;
15523
15524 hal = GET_HAL_DATA(adapter);
15525 chsw_sctx = &hal->chsw_sctx;
15526
15527 SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
15528 SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
15529 SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
15530
15531 rtw_sctx_init(chsw_sctx, 10);
15532 rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
15533 rtw_sctx_wait(chsw_sctx, __func__);
15534 }
15535 #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
15536
phy_get_current_tx_num(PADAPTER pAdapter,u8 Rate)15537 u8 phy_get_current_tx_num(
15538 PADAPTER pAdapter,
15539 u8 Rate
15540 )
15541 {
15542 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(pAdapter);
15543 u8 tx_num = 0;
15544
15545 if (IS_1T_RATE(Rate))
15546 tx_num = hal_data->txpath_num_nss[0];
15547 else if (IS_2T_RATE(Rate))
15548 tx_num = hal_data->txpath_num_nss[1];
15549 else if (IS_3T_RATE(Rate))
15550 tx_num = hal_data->txpath_num_nss[2];
15551 else if (IS_4T_RATE(Rate))
15552 tx_num = hal_data->txpath_num_nss[3];
15553 else
15554 rtw_warn_on(1);
15555
15556 return tx_num == 0 ? RF_1TX : tx_num - 1;
15557 }
15558
15559 #ifdef CONFIG_RTL8812A
rtw_hal_set_8812a_vendor_ie(_adapter * padapter,u8 * pframe,uint * frlen)15560 u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {
15561 int vender_len = 7;
15562 unsigned char vendor_info[vender_len];
15563 unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
15564 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15565
15566 if( !IS_HARDWARE_TYPE_8812(padapter) )
15567 return pframe;
15568
15569 _rtw_memset(vendor_info,0,vender_len);
15570 _rtw_memcpy(vendor_info, REALTEK_OUI, 3);
15571 vendor_info[4] =2;
15572 if(pHalData->version_id.CUTVersion > B_CUT_VERSION )
15573 vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;
15574 else
15575 vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;
15576 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);
15577
15578 return pframe;
15579 }
15580 #endif /*CONFIG_RTL8812A*/
15581
rtw_enter_protsel(struct protsel * protsel,u32 sel)15582 static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)
15583 {
15584 int refcnt;
15585
15586 _enter_critical_mutex(&protsel->mutex, NULL);
15587
15588 refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);
15589
15590 WARN_ON(refcnt > 1 && protsel->sel != sel);
15591
15592 protsel->sel = sel;
15593
15594 _exit_critical_mutex(&protsel->mutex, NULL);
15595 }
15596
rtw_leave_protsel(struct protsel * protsel)15597 static inline void rtw_leave_protsel(struct protsel *protsel)
15598 {
15599 int refcnt;
15600
15601 _enter_critical_mutex(&protsel->mutex, NULL);
15602
15603 refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);
15604
15605 _exit_critical_mutex(&protsel->mutex, NULL);
15606
15607 WARN_ON(refcnt < 0);
15608 }
15609
rtw_assert_protsel(struct protsel * protsel)15610 static inline bool rtw_assert_protsel(struct protsel *protsel)
15611 {
15612 int refcnt = ATOMIC_READ(&protsel->refcnt);
15613
15614 if (refcnt > 0)
15615 return true;
15616
15617 return false;
15618 }
15619
15620 #ifdef CONFIG_PROTSEL_PORT
rtw_enter_protsel_port(_adapter * padapter,u8 port_sel)15621 void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)
15622 {
15623 u8 val8;
15624
15625 rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);
15626
15627 val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);
15628 val8 &= ~BIT_MASK_PORT_CTRL_SEL;
15629 val8 |= BIT_PORT_CTRL_SEL(port_sel);
15630 rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);
15631 }
15632
rtw_assert_protsel_port(_adapter * padapter,u32 addr,u8 len)15633 bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)
15634 {
15635 if (!padapter->bup) /* don't assert before IF up */
15636 return true;
15637
15638 return rtw_assert_protsel(&padapter->dvobj->protsel_port);
15639 }
15640
rtw_leave_protsel_port(_adapter * padapter)15641 void rtw_leave_protsel_port(_adapter *padapter)
15642 {
15643 rtw_leave_protsel(&padapter->dvobj->protsel_port);
15644 }
15645 #endif
15646
15647 #ifdef CONFIG_PROTSEL_ATIMDTIM
rtw_enter_protsel_atimdtim(_adapter * padapter,u8 port_sel)15648 void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)
15649 {
15650 /* 0~15 is for port 0 MBSSID setting
15651 * 16 is for port 1 setting
15652 * 17 is for port 2 setting
15653 * 18 is for port 3 setting
15654 * 19 is for port 4 setting
15655 */
15656 u8 val8;
15657
15658 if (port_sel >= 1 && port_sel <= 4)
15659 port_sel += 15;
15660
15661 rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);
15662
15663 val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);
15664 val8 &= ~BIT_MASK_ATIM_DTIM_SEL;
15665 val8 |= BIT_ATIM_DTIM_SEL(port_sel);
15666 rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);
15667 }
15668
rtw_assert_protsel_atimdtim(_adapter * padapter,u32 addr,u8 len)15669 bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)
15670 {
15671 return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);
15672 }
15673
rtw_leave_protsel_atimdtim(_adapter * padapter)15674 void rtw_leave_protsel_atimdtim(_adapter *padapter)
15675 {
15676 rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);
15677 }
15678 #endif
15679
15680 #ifdef CONFIG_PROTSEL_MACSLEEP
rtw_enter_protsel_macsleep(_adapter * padapter,u8 sel)15681 void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)
15682 {
15683 u32 val32;
15684
15685 rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);
15686
15687 val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);
15688 val32 &= ~BIT_MASK_MACID_SLEEP_SEL;
15689 val32 |= BIT_MACID_SLEEP_SEL(sel);
15690 rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);
15691 }
15692
rtw_assert_protsel_macsleep(_adapter * padapter,u32 addr,u8 len)15693 bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)
15694 {
15695 return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);
15696 }
15697
rtw_leave_protsel_macsleep(_adapter * padapter)15698 void rtw_leave_protsel_macsleep(_adapter *padapter)
15699 {
15700 rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);
15701 }
15702 #endif
15703