1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2017 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 *****************************************************************************/
15 #define _HAL_COM_C_
16
17 #include <drv_types.h>
18 #include "hal_com_h2c.h"
19
20 #include "hal_data.h"
21
22 #ifdef RTW_HALMAC
23 #include "../../hal/hal_halmac.h"
24 #endif
25
rtw_dump_fw_info(void * sel,_adapter * adapter)26 void rtw_dump_fw_info(void *sel, _adapter *adapter)
27 {
28 HAL_DATA_TYPE *hal_data = NULL;
29
30 if (!adapter)
31 return;
32
33 hal_data = GET_HAL_DATA(adapter);
34 if (hal_data->bFWReady)
35 RTW_PRINT_SEL(sel, "FW VER -%d.%d\n", hal_data->firmware_version, hal_data->firmware_sub_version);
36 else
37 RTW_PRINT_SEL(sel, "FW not ready\n");
38 }
39
rsvd_page_cache_update_all(struct rsvd_page_cache_t * cache,u8 loc,u8 txdesc_len,u32 page_size,u8 * info,u32 info_len)40 bool rsvd_page_cache_update_all(struct rsvd_page_cache_t *cache, u8 loc
41 , u8 txdesc_len, u32 page_size, u8 *info, u32 info_len)
42 {
43 u8 page_num;
44 bool modified = 0;
45 bool loc_mod = 0, size_mod = 0, page_num_mod = 0;
46
47 page_num = info_len ? (u8)PageNum(txdesc_len + info_len, page_size) : 0;
48 if (!info_len)
49 loc = 0;
50
51 if (cache->loc != loc) {
52 RTW_INFO("%s %s loc change (%u -> %u)\n"
53 , __func__, cache->name, cache->loc, loc);
54 loc_mod = 1;
55 }
56 if (cache->size != info_len) {
57 RTW_INFO("%s %s size change (%u -> %u)\n"
58 , __func__, cache->name, cache->size, info_len);
59 size_mod = 1;
60 }
61 if (cache->page_num != page_num) {
62 RTW_INFO("%s %s page_num change (%u -> %u)\n"
63 , __func__, cache->name, cache->page_num, page_num);
64 page_num_mod = 1;
65 }
66
67 if (info && info_len) {
68 if (cache->data) {
69 if (cache->size == info_len) {
70 if (_rtw_memcmp(cache->data, info, info_len) != _TRUE) {
71 RTW_INFO("%s %s data change\n", __func__, cache->name);
72 modified = 1;
73 }
74 } else
75 rsvd_page_cache_free_data(cache);
76 }
77
78 if (!cache->data) {
79 cache->data = rtw_malloc(info_len);
80 if (!cache->data) {
81 RTW_ERR("%s %s alloc data with size(%u) fail\n"
82 , __func__, cache->name, info_len);
83 rtw_warn_on(1);
84 } else {
85 RTW_INFO("%s %s alloc data with size(%u)\n"
86 , __func__, cache->name, info_len);
87 }
88 modified = 1;
89 }
90
91 if (cache->data && modified)
92 _rtw_memcpy(cache->data, info, info_len);
93 } else {
94 if (cache->data && size_mod)
95 rsvd_page_cache_free_data(cache);
96 }
97
98 cache->loc = loc;
99 cache->page_num = page_num;
100 cache->size = info_len;
101
102 return modified | loc_mod | size_mod | page_num_mod;
103 }
104
rsvd_page_cache_update_data(struct rsvd_page_cache_t * cache,u8 * info,u32 info_len)105 bool rsvd_page_cache_update_data(struct rsvd_page_cache_t *cache, u8 *info, u32 info_len)
106 {
107 bool modified = 0;
108
109 if (!info || !info_len) {
110 RTW_WARN("%s %s invalid input(info:%p, info_len:%u)\n"
111 , __func__, cache->name, info, info_len);
112 goto exit;
113 }
114
115 if (!cache->loc || !cache->page_num || !cache->size) {
116 RTW_ERR("%s %s layout not ready(loc:%u, page_num:%u, size:%u)\n"
117 , __func__, cache->name, cache->loc, cache->page_num, cache->size);
118 rtw_warn_on(1);
119 goto exit;
120 }
121
122 if (cache->size != info_len) {
123 RTW_ERR("%s %s size(%u) differ with info_len(%u)\n"
124 , __func__, cache->name, cache->size, info_len);
125 rtw_warn_on(1);
126 goto exit;
127 }
128
129 if (!cache->data) {
130 cache->data = rtw_zmalloc(cache->size);
131 if (!cache->data) {
132 RTW_ERR("%s %s alloc data with size(%u) fail\n"
133 , __func__, cache->name, cache->size);
134 rtw_warn_on(1);
135 goto exit;
136 } else {
137 RTW_INFO("%s %s alloc data with size(%u)\n"
138 , __func__, cache->name, info_len);
139 }
140 modified = 1;
141 }
142
143 if (_rtw_memcmp(cache->data, info, cache->size) == _FALSE) {
144 RTW_INFO("%s %s data change\n", __func__, cache->name);
145 _rtw_memcpy(cache->data, info, cache->size);
146 modified = 1;
147 }
148
149 exit:
150 return modified;
151 }
152
rsvd_page_cache_free_data(struct rsvd_page_cache_t * cache)153 void rsvd_page_cache_free_data(struct rsvd_page_cache_t *cache)
154 {
155 if (cache->data) {
156 rtw_mfree(cache->data, cache->size);
157 cache->data = NULL;
158 }
159 }
160
rsvd_page_cache_free(struct rsvd_page_cache_t * cache)161 void rsvd_page_cache_free(struct rsvd_page_cache_t *cache)
162 {
163 cache->loc = 0;
164 cache->page_num = 0;
165 rsvd_page_cache_free_data(cache);
166 cache->size = 0;
167 }
168
169 /* #define CONFIG_GTK_OL_DBG */
170
171 /*#define DBG_SEC_CAM_MOVE*/
172 #ifdef DBG_SEC_CAM_MOVE
rtw_hal_move_sta_gk_to_dk(_adapter * adapter)173 void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
174 {
175 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
176 int cam_id, index = 0;
177 u8 *addr = NULL;
178
179 if (!MLME_IS_STA(adapter))
180 return;
181
182 addr = get_bssid(pmlmepriv);
183
184 if (addr == NULL) {
185 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
186 return;
187 }
188
189 rtw_clean_dk_section(adapter);
190
191 do {
192 cam_id = rtw_camid_search(adapter, addr, index, 1);
193
194 if (cam_id == -1)
195 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
196 else
197 rtw_sec_cam_swap(adapter, cam_id, index);
198
199 index++;
200 } while (index < 4);
201
202 }
203
rtw_hal_read_sta_dk_key(_adapter * adapter,u8 key_id)204 void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
205 {
206 struct security_priv *psecuritypriv = &adapter->securitypriv;
207 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
208 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
209 _irqL irqL;
210 u8 get_key[16];
211
212 _rtw_memset(get_key, 0, sizeof(get_key));
213
214 if (key_id > 4) {
215 RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
216 rtw_warn_on(1);
217 return;
218 }
219 rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
220
221 /*update key into related sw variable*/
222 _enter_critical_bh(&cam_ctl->lock, &irqL);
223 if (_rtw_camid_is_gk(adapter, key_id)) {
224 RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
225 RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
226 }
227 _exit_critical_bh(&cam_ctl->lock, &irqL);
228
229 }
230 #endif
231
232
233 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
234 char rtw_phy_para_file_path[PATH_LENGTH_MAX];
235 #endif
236
dump_chip_info(HAL_VERSION ChipVersion)237 void dump_chip_info(HAL_VERSION ChipVersion)
238 {
239 int cnt = 0;
240 u8 buf[128] = {0};
241
242 if (IS_8188E(ChipVersion))
243 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
244 else if (IS_8188F(ChipVersion))
245 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
246 else if (IS_8188GTV(ChipVersion))
247 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188GTV_");
248 else if (IS_8812_SERIES(ChipVersion))
249 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
250 else if (IS_8192E(ChipVersion))
251 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
252 else if (IS_8821_SERIES(ChipVersion))
253 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
254 else if (IS_8723B_SERIES(ChipVersion))
255 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
256 else if (IS_8703B_SERIES(ChipVersion))
257 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
258 else if (IS_8723D_SERIES(ChipVersion))
259 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
260 else if (IS_8814A_SERIES(ChipVersion))
261 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
262 else if (IS_8822B_SERIES(ChipVersion))
263 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
264 else if (IS_8821C_SERIES(ChipVersion))
265 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
266 else if (IS_8710B_SERIES(ChipVersion))
267 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8710B_");
268 else if (IS_8192F_SERIES(ChipVersion))
269 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192F_");
270 else if (IS_8822C_SERIES(ChipVersion))
271 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822C_");
272 else
273 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
274
275 cnt += sprintf((buf + cnt), "%s", IS_NORMAL_CHIP(ChipVersion) ? "" : "T_");
276
277 if (IS_CHIP_VENDOR_TSMC(ChipVersion))
278 cnt += sprintf((buf + cnt), "%s", "T");
279 else if (IS_CHIP_VENDOR_UMC(ChipVersion))
280 cnt += sprintf((buf + cnt), "%s", "U");
281 else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
282 cnt += sprintf((buf + cnt), "%s", "S");
283
284 if (IS_A_CUT(ChipVersion))
285 cnt += sprintf((buf + cnt), "1_");
286 else if (IS_B_CUT(ChipVersion))
287 cnt += sprintf((buf + cnt), "2_");
288 else if (IS_C_CUT(ChipVersion))
289 cnt += sprintf((buf + cnt), "3_");
290 else if (IS_D_CUT(ChipVersion))
291 cnt += sprintf((buf + cnt), "4_");
292 else if (IS_E_CUT(ChipVersion))
293 cnt += sprintf((buf + cnt), "5_");
294 else if (IS_F_CUT(ChipVersion))
295 cnt += sprintf((buf + cnt), "6_");
296 else if (IS_I_CUT(ChipVersion))
297 cnt += sprintf((buf + cnt), "9_");
298 else if (IS_J_CUT(ChipVersion))
299 cnt += sprintf((buf + cnt), "10_");
300 else if (IS_K_CUT(ChipVersion))
301 cnt += sprintf((buf + cnt), "11_");
302 else
303 cnt += sprintf((buf + cnt), "UNKNOWN_Cv(%d)_", ChipVersion.CUTVersion);
304
305 if (IS_1T1R(ChipVersion))
306 cnt += sprintf((buf + cnt), "1T1R_");
307 else if (IS_1T2R(ChipVersion))
308 cnt += sprintf((buf + cnt), "1T2R_");
309 else if (IS_2T2R(ChipVersion))
310 cnt += sprintf((buf + cnt), "2T2R_");
311 else if (IS_3T3R(ChipVersion))
312 cnt += sprintf((buf + cnt), "3T3R_");
313 else if (IS_3T4R(ChipVersion))
314 cnt += sprintf((buf + cnt), "3T4R_");
315 else if (IS_4T4R(ChipVersion))
316 cnt += sprintf((buf + cnt), "4T4R_");
317 else
318 cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
319
320 cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
321
322 RTW_INFO("%s", buf);
323 }
324
rtw_hal_get_port(_adapter * adapter)325 u8 rtw_hal_get_port(_adapter *adapter)
326 {
327 u8 hw_port = get_hw_port(adapter);
328 #ifdef CONFIG_CLIENT_PORT_CFG
329 u8 clt_port = get_clt_port(adapter);
330
331 if (clt_port)
332 hw_port = clt_port;
333
334 #ifdef DBG_HW_PORT
335 if (MLME_IS_STA(adapter) && (adapter->client_id != MAX_CLIENT_PORT_NUM)) {
336 if(hw_port == CLT_PORT_INVALID) {
337 RTW_ERR(ADPT_FMT" @@@@@ Client port == 0 @@@@@\n", ADPT_ARG(adapter));
338 rtw_warn_on(1);
339 }
340 }
341 #ifdef CONFIG_AP_MODE
342 else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
343 if (hw_port != HW_PORT0) {
344 RTW_ERR(ADPT_FMT" @@@@@ AP / MESH port != 0 @@@@@\n", ADPT_ARG(adapter));
345 rtw_warn_on(1);
346 }
347 }
348 #endif
349 if (0)
350 RTW_INFO(ADPT_FMT" - HP:%d,CP:%d\n", ADPT_ARG(adapter), get_hw_port(adapter), get_clt_port(adapter));
351 #endif /*DBG_HW_PORT*/
352
353 #endif/*CONFIG_CLIENT_PORT_CFG*/
354
355 return hw_port;
356 }
357
358 #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
359
360 /*
361 * Description:
362 * Use hardware(efuse), driver parameter(registry) and default channel plan
363 * to decide which one should be used.
364 *
365 * Parameters:
366 * padapter pointer of adapter
367 * hw_alpha2 country code from HW (efuse/eeprom/mapfile)
368 * hw_chplan channel plan from HW (efuse/eeprom/mapfile)
369 * BIT[7] software configure mode; 0:Enable, 1:disable
370 * BIT[6:0] Channel Plan
371 * sw_alpha2 country code from HW (registry/module param)
372 * sw_chplan channel plan from SW (registry/module param)
373 * AutoLoadFail efuse autoload fail or not
374 *
375 */
hal_com_config_channel_plan(PADAPTER padapter,char * hw_alpha2,u8 hw_chplan,char * sw_alpha2,u8 sw_chplan,BOOLEAN AutoLoadFail)376 void hal_com_config_channel_plan(
377 PADAPTER padapter,
378 char *hw_alpha2,
379 u8 hw_chplan,
380 char *sw_alpha2,
381 u8 sw_chplan,
382 BOOLEAN AutoLoadFail
383 )
384 {
385 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
386 PHAL_DATA_TYPE pHalData;
387 u8 force_hw_chplan = _FALSE;
388 int chplan = -1;
389 const struct country_chplan *country_ent = NULL, *ent;
390 u8 def_chplan = 0x7F; /* Realtek define, used when HW, SW both invalid */
391
392 pHalData = GET_HAL_DATA(padapter);
393
394 /* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
395 if (hw_chplan == 0xFF)
396 goto chk_hw_country_code;
397
398 if (AutoLoadFail == _TRUE)
399 goto chk_sw_config;
400
401 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
402 if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
403 force_hw_chplan = _TRUE;
404 #endif
405
406 hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
407
408 chk_hw_country_code:
409 if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
410 ent = rtw_get_chplan_from_country(hw_alpha2);
411 if (ent) {
412 /* get chplan from hw country code, by pass hw chplan setting */
413 country_ent = ent;
414 chplan = ent->chplan;
415 goto chk_sw_config;
416 } else
417 RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
418 }
419
420 if (rtw_is_channel_plan_valid(hw_chplan))
421 chplan = hw_chplan;
422 else if (force_hw_chplan == _TRUE) {
423 RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
424 /* hw infomaton invalid, refer to sw information */
425 force_hw_chplan = _FALSE;
426 }
427
428 chk_sw_config:
429 if (force_hw_chplan == _TRUE)
430 goto done;
431
432 if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
433 ent = rtw_get_chplan_from_country(sw_alpha2);
434 if (ent) {
435 /* get chplan from sw country code, by pass sw chplan setting */
436 country_ent = ent;
437 chplan = ent->chplan;
438 goto done;
439 } else
440 RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
441 }
442
443 if (rtw_is_channel_plan_valid(sw_chplan)) {
444 /* cancel hw_alpha2 because chplan is specified by sw_chplan*/
445 country_ent = NULL;
446 chplan = sw_chplan;
447 } else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
448 RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
449
450 done:
451 if (chplan == -1) {
452 RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
453 chplan = def_chplan;
454 } else if (country_ent) {
455 RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
456 , country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
457 } else
458 RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
459
460 rfctl->country_ent = country_ent;
461 rfctl->ChannelPlan = chplan;
462 pHalData->bDisableSWChannelPlan = force_hw_chplan;
463 }
464
465 BOOLEAN
HAL_IsLegalChannel(PADAPTER Adapter,u32 Channel)466 HAL_IsLegalChannel(
467 PADAPTER Adapter,
468 u32 Channel
469 )
470 {
471 BOOLEAN bLegalChannel = _TRUE;
472
473 if (Channel > 14) {
474 if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
475 bLegalChannel = _FALSE;
476 RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
477 }
478 } else if ((Channel <= 14) && (Channel >= 1)) {
479 if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
480 bLegalChannel = _FALSE;
481 RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
482 }
483 } else {
484 bLegalChannel = _FALSE;
485 RTW_INFO("Channel is Invalid !!!\n");
486 }
487
488 return bLegalChannel;
489 }
490
MRateToHwRate(u8 rate)491 u8 MRateToHwRate(u8 rate)
492 {
493 u8 ret = DESC_RATE1M;
494
495 switch (rate) {
496 case MGN_1M:
497 ret = DESC_RATE1M;
498 break;
499 case MGN_2M:
500 ret = DESC_RATE2M;
501 break;
502 case MGN_5_5M:
503 ret = DESC_RATE5_5M;
504 break;
505 case MGN_11M:
506 ret = DESC_RATE11M;
507 break;
508 case MGN_6M:
509 ret = DESC_RATE6M;
510 break;
511 case MGN_9M:
512 ret = DESC_RATE9M;
513 break;
514 case MGN_12M:
515 ret = DESC_RATE12M;
516 break;
517 case MGN_18M:
518 ret = DESC_RATE18M;
519 break;
520 case MGN_24M:
521 ret = DESC_RATE24M;
522 break;
523 case MGN_36M:
524 ret = DESC_RATE36M;
525 break;
526 case MGN_48M:
527 ret = DESC_RATE48M;
528 break;
529 case MGN_54M:
530 ret = DESC_RATE54M;
531 break;
532
533 case MGN_MCS0:
534 ret = DESC_RATEMCS0;
535 break;
536 case MGN_MCS1:
537 ret = DESC_RATEMCS1;
538 break;
539 case MGN_MCS2:
540 ret = DESC_RATEMCS2;
541 break;
542 case MGN_MCS3:
543 ret = DESC_RATEMCS3;
544 break;
545 case MGN_MCS4:
546 ret = DESC_RATEMCS4;
547 break;
548 case MGN_MCS5:
549 ret = DESC_RATEMCS5;
550 break;
551 case MGN_MCS6:
552 ret = DESC_RATEMCS6;
553 break;
554 case MGN_MCS7:
555 ret = DESC_RATEMCS7;
556 break;
557 case MGN_MCS8:
558 ret = DESC_RATEMCS8;
559 break;
560 case MGN_MCS9:
561 ret = DESC_RATEMCS9;
562 break;
563 case MGN_MCS10:
564 ret = DESC_RATEMCS10;
565 break;
566 case MGN_MCS11:
567 ret = DESC_RATEMCS11;
568 break;
569 case MGN_MCS12:
570 ret = DESC_RATEMCS12;
571 break;
572 case MGN_MCS13:
573 ret = DESC_RATEMCS13;
574 break;
575 case MGN_MCS14:
576 ret = DESC_RATEMCS14;
577 break;
578 case MGN_MCS15:
579 ret = DESC_RATEMCS15;
580 break;
581 case MGN_MCS16:
582 ret = DESC_RATEMCS16;
583 break;
584 case MGN_MCS17:
585 ret = DESC_RATEMCS17;
586 break;
587 case MGN_MCS18:
588 ret = DESC_RATEMCS18;
589 break;
590 case MGN_MCS19:
591 ret = DESC_RATEMCS19;
592 break;
593 case MGN_MCS20:
594 ret = DESC_RATEMCS20;
595 break;
596 case MGN_MCS21:
597 ret = DESC_RATEMCS21;
598 break;
599 case MGN_MCS22:
600 ret = DESC_RATEMCS22;
601 break;
602 case MGN_MCS23:
603 ret = DESC_RATEMCS23;
604 break;
605 case MGN_MCS24:
606 ret = DESC_RATEMCS24;
607 break;
608 case MGN_MCS25:
609 ret = DESC_RATEMCS25;
610 break;
611 case MGN_MCS26:
612 ret = DESC_RATEMCS26;
613 break;
614 case MGN_MCS27:
615 ret = DESC_RATEMCS27;
616 break;
617 case MGN_MCS28:
618 ret = DESC_RATEMCS28;
619 break;
620 case MGN_MCS29:
621 ret = DESC_RATEMCS29;
622 break;
623 case MGN_MCS30:
624 ret = DESC_RATEMCS30;
625 break;
626 case MGN_MCS31:
627 ret = DESC_RATEMCS31;
628 break;
629
630 case MGN_VHT1SS_MCS0:
631 ret = DESC_RATEVHTSS1MCS0;
632 break;
633 case MGN_VHT1SS_MCS1:
634 ret = DESC_RATEVHTSS1MCS1;
635 break;
636 case MGN_VHT1SS_MCS2:
637 ret = DESC_RATEVHTSS1MCS2;
638 break;
639 case MGN_VHT1SS_MCS3:
640 ret = DESC_RATEVHTSS1MCS3;
641 break;
642 case MGN_VHT1SS_MCS4:
643 ret = DESC_RATEVHTSS1MCS4;
644 break;
645 case MGN_VHT1SS_MCS5:
646 ret = DESC_RATEVHTSS1MCS5;
647 break;
648 case MGN_VHT1SS_MCS6:
649 ret = DESC_RATEVHTSS1MCS6;
650 break;
651 case MGN_VHT1SS_MCS7:
652 ret = DESC_RATEVHTSS1MCS7;
653 break;
654 case MGN_VHT1SS_MCS8:
655 ret = DESC_RATEVHTSS1MCS8;
656 break;
657 case MGN_VHT1SS_MCS9:
658 ret = DESC_RATEVHTSS1MCS9;
659 break;
660 case MGN_VHT2SS_MCS0:
661 ret = DESC_RATEVHTSS2MCS0;
662 break;
663 case MGN_VHT2SS_MCS1:
664 ret = DESC_RATEVHTSS2MCS1;
665 break;
666 case MGN_VHT2SS_MCS2:
667 ret = DESC_RATEVHTSS2MCS2;
668 break;
669 case MGN_VHT2SS_MCS3:
670 ret = DESC_RATEVHTSS2MCS3;
671 break;
672 case MGN_VHT2SS_MCS4:
673 ret = DESC_RATEVHTSS2MCS4;
674 break;
675 case MGN_VHT2SS_MCS5:
676 ret = DESC_RATEVHTSS2MCS5;
677 break;
678 case MGN_VHT2SS_MCS6:
679 ret = DESC_RATEVHTSS2MCS6;
680 break;
681 case MGN_VHT2SS_MCS7:
682 ret = DESC_RATEVHTSS2MCS7;
683 break;
684 case MGN_VHT2SS_MCS8:
685 ret = DESC_RATEVHTSS2MCS8;
686 break;
687 case MGN_VHT2SS_MCS9:
688 ret = DESC_RATEVHTSS2MCS9;
689 break;
690 case MGN_VHT3SS_MCS0:
691 ret = DESC_RATEVHTSS3MCS0;
692 break;
693 case MGN_VHT3SS_MCS1:
694 ret = DESC_RATEVHTSS3MCS1;
695 break;
696 case MGN_VHT3SS_MCS2:
697 ret = DESC_RATEVHTSS3MCS2;
698 break;
699 case MGN_VHT3SS_MCS3:
700 ret = DESC_RATEVHTSS3MCS3;
701 break;
702 case MGN_VHT3SS_MCS4:
703 ret = DESC_RATEVHTSS3MCS4;
704 break;
705 case MGN_VHT3SS_MCS5:
706 ret = DESC_RATEVHTSS3MCS5;
707 break;
708 case MGN_VHT3SS_MCS6:
709 ret = DESC_RATEVHTSS3MCS6;
710 break;
711 case MGN_VHT3SS_MCS7:
712 ret = DESC_RATEVHTSS3MCS7;
713 break;
714 case MGN_VHT3SS_MCS8:
715 ret = DESC_RATEVHTSS3MCS8;
716 break;
717 case MGN_VHT3SS_MCS9:
718 ret = DESC_RATEVHTSS3MCS9;
719 break;
720 case MGN_VHT4SS_MCS0:
721 ret = DESC_RATEVHTSS4MCS0;
722 break;
723 case MGN_VHT4SS_MCS1:
724 ret = DESC_RATEVHTSS4MCS1;
725 break;
726 case MGN_VHT4SS_MCS2:
727 ret = DESC_RATEVHTSS4MCS2;
728 break;
729 case MGN_VHT4SS_MCS3:
730 ret = DESC_RATEVHTSS4MCS3;
731 break;
732 case MGN_VHT4SS_MCS4:
733 ret = DESC_RATEVHTSS4MCS4;
734 break;
735 case MGN_VHT4SS_MCS5:
736 ret = DESC_RATEVHTSS4MCS5;
737 break;
738 case MGN_VHT4SS_MCS6:
739 ret = DESC_RATEVHTSS4MCS6;
740 break;
741 case MGN_VHT4SS_MCS7:
742 ret = DESC_RATEVHTSS4MCS7;
743 break;
744 case MGN_VHT4SS_MCS8:
745 ret = DESC_RATEVHTSS4MCS8;
746 break;
747 case MGN_VHT4SS_MCS9:
748 ret = DESC_RATEVHTSS4MCS9;
749 break;
750 default:
751 break;
752 }
753
754 return ret;
755 }
756
hw_rate_to_m_rate(u8 rate)757 u8 hw_rate_to_m_rate(u8 rate)
758 {
759 u8 ret_rate = MGN_1M;
760
761 switch (rate) {
762
763 case DESC_RATE1M:
764 ret_rate = MGN_1M;
765 break;
766 case DESC_RATE2M:
767 ret_rate = MGN_2M;
768 break;
769 case DESC_RATE5_5M:
770 ret_rate = MGN_5_5M;
771 break;
772 case DESC_RATE11M:
773 ret_rate = MGN_11M;
774 break;
775 case DESC_RATE6M:
776 ret_rate = MGN_6M;
777 break;
778 case DESC_RATE9M:
779 ret_rate = MGN_9M;
780 break;
781 case DESC_RATE12M:
782 ret_rate = MGN_12M;
783 break;
784 case DESC_RATE18M:
785 ret_rate = MGN_18M;
786 break;
787 case DESC_RATE24M:
788 ret_rate = MGN_24M;
789 break;
790 case DESC_RATE36M:
791 ret_rate = MGN_36M;
792 break;
793 case DESC_RATE48M:
794 ret_rate = MGN_48M;
795 break;
796 case DESC_RATE54M:
797 ret_rate = MGN_54M;
798 break;
799 case DESC_RATEMCS0:
800 ret_rate = MGN_MCS0;
801 break;
802 case DESC_RATEMCS1:
803 ret_rate = MGN_MCS1;
804 break;
805 case DESC_RATEMCS2:
806 ret_rate = MGN_MCS2;
807 break;
808 case DESC_RATEMCS3:
809 ret_rate = MGN_MCS3;
810 break;
811 case DESC_RATEMCS4:
812 ret_rate = MGN_MCS4;
813 break;
814 case DESC_RATEMCS5:
815 ret_rate = MGN_MCS5;
816 break;
817 case DESC_RATEMCS6:
818 ret_rate = MGN_MCS6;
819 break;
820 case DESC_RATEMCS7:
821 ret_rate = MGN_MCS7;
822 break;
823 case DESC_RATEMCS8:
824 ret_rate = MGN_MCS8;
825 break;
826 case DESC_RATEMCS9:
827 ret_rate = MGN_MCS9;
828 break;
829 case DESC_RATEMCS10:
830 ret_rate = MGN_MCS10;
831 break;
832 case DESC_RATEMCS11:
833 ret_rate = MGN_MCS11;
834 break;
835 case DESC_RATEMCS12:
836 ret_rate = MGN_MCS12;
837 break;
838 case DESC_RATEMCS13:
839 ret_rate = MGN_MCS13;
840 break;
841 case DESC_RATEMCS14:
842 ret_rate = MGN_MCS14;
843 break;
844 case DESC_RATEMCS15:
845 ret_rate = MGN_MCS15;
846 break;
847 case DESC_RATEMCS16:
848 ret_rate = MGN_MCS16;
849 break;
850 case DESC_RATEMCS17:
851 ret_rate = MGN_MCS17;
852 break;
853 case DESC_RATEMCS18:
854 ret_rate = MGN_MCS18;
855 break;
856 case DESC_RATEMCS19:
857 ret_rate = MGN_MCS19;
858 break;
859 case DESC_RATEMCS20:
860 ret_rate = MGN_MCS20;
861 break;
862 case DESC_RATEMCS21:
863 ret_rate = MGN_MCS21;
864 break;
865 case DESC_RATEMCS22:
866 ret_rate = MGN_MCS22;
867 break;
868 case DESC_RATEMCS23:
869 ret_rate = MGN_MCS23;
870 break;
871 case DESC_RATEMCS24:
872 ret_rate = MGN_MCS24;
873 break;
874 case DESC_RATEMCS25:
875 ret_rate = MGN_MCS25;
876 break;
877 case DESC_RATEMCS26:
878 ret_rate = MGN_MCS26;
879 break;
880 case DESC_RATEMCS27:
881 ret_rate = MGN_MCS27;
882 break;
883 case DESC_RATEMCS28:
884 ret_rate = MGN_MCS28;
885 break;
886 case DESC_RATEMCS29:
887 ret_rate = MGN_MCS29;
888 break;
889 case DESC_RATEMCS30:
890 ret_rate = MGN_MCS30;
891 break;
892 case DESC_RATEMCS31:
893 ret_rate = MGN_MCS31;
894 break;
895 case DESC_RATEVHTSS1MCS0:
896 ret_rate = MGN_VHT1SS_MCS0;
897 break;
898 case DESC_RATEVHTSS1MCS1:
899 ret_rate = MGN_VHT1SS_MCS1;
900 break;
901 case DESC_RATEVHTSS1MCS2:
902 ret_rate = MGN_VHT1SS_MCS2;
903 break;
904 case DESC_RATEVHTSS1MCS3:
905 ret_rate = MGN_VHT1SS_MCS3;
906 break;
907 case DESC_RATEVHTSS1MCS4:
908 ret_rate = MGN_VHT1SS_MCS4;
909 break;
910 case DESC_RATEVHTSS1MCS5:
911 ret_rate = MGN_VHT1SS_MCS5;
912 break;
913 case DESC_RATEVHTSS1MCS6:
914 ret_rate = MGN_VHT1SS_MCS6;
915 break;
916 case DESC_RATEVHTSS1MCS7:
917 ret_rate = MGN_VHT1SS_MCS7;
918 break;
919 case DESC_RATEVHTSS1MCS8:
920 ret_rate = MGN_VHT1SS_MCS8;
921 break;
922 case DESC_RATEVHTSS1MCS9:
923 ret_rate = MGN_VHT1SS_MCS9;
924 break;
925 case DESC_RATEVHTSS2MCS0:
926 ret_rate = MGN_VHT2SS_MCS0;
927 break;
928 case DESC_RATEVHTSS2MCS1:
929 ret_rate = MGN_VHT2SS_MCS1;
930 break;
931 case DESC_RATEVHTSS2MCS2:
932 ret_rate = MGN_VHT2SS_MCS2;
933 break;
934 case DESC_RATEVHTSS2MCS3:
935 ret_rate = MGN_VHT2SS_MCS3;
936 break;
937 case DESC_RATEVHTSS2MCS4:
938 ret_rate = MGN_VHT2SS_MCS4;
939 break;
940 case DESC_RATEVHTSS2MCS5:
941 ret_rate = MGN_VHT2SS_MCS5;
942 break;
943 case DESC_RATEVHTSS2MCS6:
944 ret_rate = MGN_VHT2SS_MCS6;
945 break;
946 case DESC_RATEVHTSS2MCS7:
947 ret_rate = MGN_VHT2SS_MCS7;
948 break;
949 case DESC_RATEVHTSS2MCS8:
950 ret_rate = MGN_VHT2SS_MCS8;
951 break;
952 case DESC_RATEVHTSS2MCS9:
953 ret_rate = MGN_VHT2SS_MCS9;
954 break;
955 case DESC_RATEVHTSS3MCS0:
956 ret_rate = MGN_VHT3SS_MCS0;
957 break;
958 case DESC_RATEVHTSS3MCS1:
959 ret_rate = MGN_VHT3SS_MCS1;
960 break;
961 case DESC_RATEVHTSS3MCS2:
962 ret_rate = MGN_VHT3SS_MCS2;
963 break;
964 case DESC_RATEVHTSS3MCS3:
965 ret_rate = MGN_VHT3SS_MCS3;
966 break;
967 case DESC_RATEVHTSS3MCS4:
968 ret_rate = MGN_VHT3SS_MCS4;
969 break;
970 case DESC_RATEVHTSS3MCS5:
971 ret_rate = MGN_VHT3SS_MCS5;
972 break;
973 case DESC_RATEVHTSS3MCS6:
974 ret_rate = MGN_VHT3SS_MCS6;
975 break;
976 case DESC_RATEVHTSS3MCS7:
977 ret_rate = MGN_VHT3SS_MCS7;
978 break;
979 case DESC_RATEVHTSS3MCS8:
980 ret_rate = MGN_VHT3SS_MCS8;
981 break;
982 case DESC_RATEVHTSS3MCS9:
983 ret_rate = MGN_VHT3SS_MCS9;
984 break;
985 case DESC_RATEVHTSS4MCS0:
986 ret_rate = MGN_VHT4SS_MCS0;
987 break;
988 case DESC_RATEVHTSS4MCS1:
989 ret_rate = MGN_VHT4SS_MCS1;
990 break;
991 case DESC_RATEVHTSS4MCS2:
992 ret_rate = MGN_VHT4SS_MCS2;
993 break;
994 case DESC_RATEVHTSS4MCS3:
995 ret_rate = MGN_VHT4SS_MCS3;
996 break;
997 case DESC_RATEVHTSS4MCS4:
998 ret_rate = MGN_VHT4SS_MCS4;
999 break;
1000 case DESC_RATEVHTSS4MCS5:
1001 ret_rate = MGN_VHT4SS_MCS5;
1002 break;
1003 case DESC_RATEVHTSS4MCS6:
1004 ret_rate = MGN_VHT4SS_MCS6;
1005 break;
1006 case DESC_RATEVHTSS4MCS7:
1007 ret_rate = MGN_VHT4SS_MCS7;
1008 break;
1009 case DESC_RATEVHTSS4MCS8:
1010 ret_rate = MGN_VHT4SS_MCS8;
1011 break;
1012 case DESC_RATEVHTSS4MCS9:
1013 ret_rate = MGN_VHT4SS_MCS9;
1014 break;
1015
1016 default:
1017 RTW_INFO("hw_rate_to_m_rate(): Non supported Rate [%x]!!!\n", rate);
1018 break;
1019 }
1020
1021 return ret_rate;
1022 }
1023
HalSetBrateCfg(PADAPTER Adapter,u8 * mBratesOS,u16 * pBrateCfg)1024 void HalSetBrateCfg(
1025 PADAPTER Adapter,
1026 u8 *mBratesOS,
1027 u16 *pBrateCfg)
1028 {
1029 u8 i, is_brate, brate;
1030
1031 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
1032 is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
1033 brate = mBratesOS[i] & 0x7f;
1034
1035 if (is_brate) {
1036 switch (brate) {
1037 case IEEE80211_CCK_RATE_1MB:
1038 *pBrateCfg |= RATE_1M;
1039 break;
1040 case IEEE80211_CCK_RATE_2MB:
1041 *pBrateCfg |= RATE_2M;
1042 break;
1043 case IEEE80211_CCK_RATE_5MB:
1044 *pBrateCfg |= RATE_5_5M;
1045 break;
1046 case IEEE80211_CCK_RATE_11MB:
1047 *pBrateCfg |= RATE_11M;
1048 break;
1049 case IEEE80211_OFDM_RATE_6MB:
1050 *pBrateCfg |= RATE_6M;
1051 break;
1052 case IEEE80211_OFDM_RATE_9MB:
1053 *pBrateCfg |= RATE_9M;
1054 break;
1055 case IEEE80211_OFDM_RATE_12MB:
1056 *pBrateCfg |= RATE_12M;
1057 break;
1058 case IEEE80211_OFDM_RATE_18MB:
1059 *pBrateCfg |= RATE_18M;
1060 break;
1061 case IEEE80211_OFDM_RATE_24MB:
1062 *pBrateCfg |= RATE_24M;
1063 break;
1064 case IEEE80211_OFDM_RATE_36MB:
1065 *pBrateCfg |= RATE_36M;
1066 break;
1067 case IEEE80211_OFDM_RATE_48MB:
1068 *pBrateCfg |= RATE_48M;
1069 break;
1070 case IEEE80211_OFDM_RATE_54MB:
1071 *pBrateCfg |= RATE_54M;
1072 break;
1073 }
1074 }
1075 }
1076 }
1077
1078 static void
_OneOutPipeMapping(PADAPTER pAdapter)1079 _OneOutPipeMapping(
1080 PADAPTER pAdapter
1081 )
1082 {
1083 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1084
1085 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1086 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1087 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
1088 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
1089
1090 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1091 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1092 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1093 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1094 }
1095
1096 static void
_TwoOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)1097 _TwoOutPipeMapping(
1098 PADAPTER pAdapter,
1099 BOOLEAN bWIFICfg
1100 )
1101 {
1102 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1103
1104 if (bWIFICfg) { /* WMM */
1105
1106 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1107 /* { 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
1108 /* 0:ep_0 num, 1:ep_1 num */
1109
1110 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
1111 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1112 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
1113 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
1114
1115 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1116 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1117 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1118 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1119
1120 } else { /* typical setting */
1121
1122
1123 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1124 /* { 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
1125 /* 0:ep_0 num, 1:ep_1 num */
1126
1127 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1128 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
1129 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
1130 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1131
1132 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1133 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1134 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1135 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1136
1137 }
1138
1139 }
1140
_ThreeOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)1141 static void _ThreeOutPipeMapping(
1142 PADAPTER pAdapter,
1143 BOOLEAN bWIFICfg
1144 )
1145 {
1146 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1147
1148 if (bWIFICfg) { /* for WMM */
1149
1150 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1151 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1152 /* 0:H, 1:N, 2:L */
1153
1154 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1155 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1156 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1157 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1158
1159 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1160 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1161 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1162 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1163
1164 } else { /* typical setting */
1165
1166
1167 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1168 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1169 /* 0:H, 1:N, 2:L */
1170
1171 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1172 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1173 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1174 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1175
1176 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1177 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1178 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1179 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1180 }
1181
1182 }
1183 #if 0
1184 static void _FourOutPipeMapping(
1185 PADAPTER pAdapter,
1186 BOOLEAN bWIFICfg
1187 )
1188 {
1189 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1190
1191 if (bWIFICfg) { /* for WMM */
1192
1193 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1194 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1195 /* 0:H, 1:N, 2:L ,3:E */
1196
1197 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1198 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1199 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1200 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1201
1202 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1203 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1204 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1205 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1206
1207 } else { /* typical setting */
1208
1209
1210 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1211 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1212 /* 0:H, 1:N, 2:L */
1213
1214 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1215 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1216 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1217 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1218
1219 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1220 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1221 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1222 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1223 }
1224
1225 }
1226 #endif
1227 BOOLEAN
Hal_MappingOutPipe(PADAPTER pAdapter,u8 NumOutPipe)1228 Hal_MappingOutPipe(
1229 PADAPTER pAdapter,
1230 u8 NumOutPipe
1231 )
1232 {
1233 struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
1234
1235 BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
1236
1237 BOOLEAN result = _TRUE;
1238
1239 switch (NumOutPipe) {
1240 case 2:
1241 _TwoOutPipeMapping(pAdapter, bWIFICfg);
1242 break;
1243 case 3:
1244 case 4:
1245 case 5:
1246 case 6:
1247 _ThreeOutPipeMapping(pAdapter, bWIFICfg);
1248 break;
1249 case 1:
1250 _OneOutPipeMapping(pAdapter);
1251 break;
1252 default:
1253 result = _FALSE;
1254 break;
1255 }
1256
1257 return result;
1258
1259 }
1260
rtw_hal_reqtxrpt(_adapter * padapter,u8 macid)1261 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1262 {
1263 if (padapter->hal_func.reqtxrpt)
1264 padapter->hal_func.reqtxrpt(padapter, macid);
1265 }
1266
rtw_hal_dump_macaddr(void * sel,_adapter * adapter)1267 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1268 {
1269 int i;
1270 _adapter *iface;
1271 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1272 u8 mac_addr[ETH_ALEN];
1273
1274 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1275 rtw_mbid_cam_dump(sel, __func__, adapter);
1276 #else
1277 rtw_mi_hal_dump_macaddr(sel, adapter);
1278 #endif
1279 }
1280
1281 #ifdef RTW_HALMAC
rtw_hal_hw_port_enable(_adapter * adapter)1282 void rtw_hal_hw_port_enable(_adapter *adapter)
1283 {
1284 #if 1
1285 u8 port_enable = _TRUE;
1286
1287 rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1288 #else
1289 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1290 struct rtw_halmac_bcn_ctrl bcn_ctrl;
1291
1292 _rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
1293 bcn_ctrl.enable_bcn = 1;
1294 bcn_ctrl.rx_bssid_fit = 1;
1295 bcn_ctrl.rxbcn_rpt = 1;
1296
1297 /*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1298 struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
1299 if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
1300 RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
1301 rtw_warn_on(1);
1302 }
1303 #endif
1304 }
rtw_hal_hw_port_disable(_adapter * adapter)1305 void rtw_hal_hw_port_disable(_adapter *adapter)
1306 {
1307 u8 port_enable = _FALSE;
1308
1309 rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1310 }
1311
rtw_restore_hw_port_cfg(_adapter * adapter)1312 void rtw_restore_hw_port_cfg(_adapter *adapter)
1313 {
1314 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1315
1316 #else
1317 int i;
1318 _adapter *iface;
1319 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1320
1321 for (i = 0; i < dvobj->iface_nums; i++) {
1322 iface = dvobj->padapters[i];
1323 if (iface)
1324 rtw_hal_hw_port_enable(iface);
1325 }
1326 #endif
1327 }
1328 #endif
1329
rtw_mi_set_mac_addr(_adapter * adapter)1330 void rtw_mi_set_mac_addr(_adapter *adapter)
1331 {
1332 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1333 rtw_mi_set_mbid_cam(adapter);
1334 #else
1335 int i;
1336 _adapter *iface;
1337 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1338
1339 for (i = 0; i < dvobj->iface_nums; i++) {
1340 iface = dvobj->padapters[i];
1341 if (iface)
1342 rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
1343 }
1344 #endif
1345 if (0)
1346 rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1347 }
1348
rtw_init_hal_com_default_value(PADAPTER Adapter)1349 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1350 {
1351 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
1352 struct registry_priv *regsty = adapter_to_regsty(Adapter);
1353
1354 pHalData->AntDetection = 1;
1355 pHalData->antenna_test = _FALSE;
1356 pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
1357 pHalData->ch_switch_offload = regsty->ch_switch_offload;
1358 pHalData->multi_ch_switch_mode = 0;
1359 #ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME
1360 if (pHalData->ch_switch_offload == 0)
1361 pHalData->ch_switch_offload = 1;
1362 #endif
1363 }
1364
1365 #ifdef CONFIG_FW_C2H_REG
c2h_evt_clear(_adapter * adapter)1366 void c2h_evt_clear(_adapter *adapter)
1367 {
1368 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1369 }
1370
c2h_evt_read_88xx(_adapter * adapter,u8 * buf)1371 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1372 {
1373 s32 ret = _FAIL;
1374 int i;
1375 u8 trigger;
1376
1377 if (buf == NULL)
1378 goto exit;
1379
1380 trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1381
1382 if (trigger == C2H_EVT_HOST_CLOSE) {
1383 goto exit; /* Not ready */
1384 } else if (trigger != C2H_EVT_FW_CLOSE) {
1385 goto clear_evt; /* Not a valid value */
1386 }
1387
1388 _rtw_memset(buf, 0, C2H_REG_LEN);
1389
1390 /* Read ID, LEN, SEQ */
1391 SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
1392 SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
1393 SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
1394
1395 if (0) {
1396 RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
1397 , C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
1398 }
1399
1400 /* Read the content */
1401 for (i = 0; i < C2H_PLEN_88XX(buf); i++)
1402 *(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1403
1404 RTW_DBG_DUMP("payload: ", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
1405
1406 ret = _SUCCESS;
1407
1408 clear_evt:
1409 /*
1410 * Clear event to notify FW we have read the command.
1411 * If this field isn't clear, the FW won't update the next command message.
1412 */
1413 c2h_evt_clear(adapter);
1414
1415 exit:
1416 return ret;
1417 }
1418 #endif /* CONFIG_FW_C2H_REG */
1419
1420 #ifdef CONFIG_FW_C2H_PKT
1421 #ifndef DBG_C2H_PKT_PRE_HDL
1422 #define DBG_C2H_PKT_PRE_HDL 0
1423 #endif
1424 #ifndef DBG_C2H_PKT_HDL
1425 #define DBG_C2H_PKT_HDL 0
1426 #endif
rtw_hal_c2h_pkt_pre_hdl(_adapter * adapter,u8 * buf,u16 len)1427 void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
1428 {
1429 #ifdef RTW_HALMAC
1430 /* TODO: extract hal_mac IC's code here*/
1431 #else
1432 u8 parse_fail = 0;
1433 u8 hdl_here = 0;
1434 s32 ret = _FAIL;
1435 u8 id, seq, plen;
1436 u8 *payload;
1437
1438 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1439 parse_fail = 1;
1440 goto exit;
1441 }
1442
1443 hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
1444 if (hdl_here)
1445 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1446 else
1447 ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
1448
1449 exit:
1450 if (parse_fail)
1451 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1452 else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
1453 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1454 , hdl_here ? "handle" : "enqueue"
1455 , ret == _SUCCESS ? "ok" : "fail"
1456 );
1457 if (DBG_C2H_PKT_PRE_HDL >= 2)
1458 RTW_PRINT_DUMP("dump: ", buf, len);
1459 }
1460 #endif
1461 }
1462
rtw_hal_c2h_pkt_hdl(_adapter * adapter,u8 * buf,u16 len)1463 void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
1464 {
1465 #ifdef RTW_HALMAC
1466 adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
1467 #else
1468 u8 parse_fail = 0;
1469 u8 bypass = 0;
1470 s32 ret = _FAIL;
1471 u8 id, seq, plen;
1472 u8 *payload;
1473
1474 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1475 parse_fail = 1;
1476 goto exit;
1477 }
1478
1479 #ifdef CONFIG_WOWLAN
1480 if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
1481 bypass = 1;
1482 ret = _SUCCESS;
1483 goto exit;
1484 }
1485 #endif
1486
1487 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1488
1489 exit:
1490 if (parse_fail)
1491 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1492 else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
1493 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1494 , !bypass ? "handle" : "bypass"
1495 , ret == _SUCCESS ? "ok" : "fail"
1496 );
1497 if (DBG_C2H_PKT_HDL >= 2)
1498 RTW_PRINT_DUMP("dump: ", buf, len);
1499 }
1500 #endif
1501 }
1502 #endif /* CONFIG_FW_C2H_PKT */
1503
c2h_iqk_offload(_adapter * adapter,u8 * data,u8 len)1504 void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
1505 {
1506 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1507 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1508
1509 RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
1510 if (0)
1511 RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
1512
1513 rtw_sctx_done(&iqk_sctx);
1514 }
1515
c2h_iqk_offload_wait(_adapter * adapter,u32 timeout_ms)1516 int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
1517 {
1518 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1519 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1520
1521 iqk_sctx->submit_time = rtw_get_current_time();
1522 iqk_sctx->timeout_ms = timeout_ms;
1523 iqk_sctx->status = RTW_SCTX_SUBMITTED;
1524
1525 return rtw_sctx_wait(iqk_sctx, __func__);
1526 }
1527
1528 #ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX
c2h_txpwr_idx_offload_done(_adapter * adapter,u8 * data,u8 len)1529 void c2h_txpwr_idx_offload_done(_adapter *adapter, u8 *data, u8 len)
1530 {
1531 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1532 struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1533
1534 if (0)
1535 RTW_INFO("txpwr_idx offload finish in %dms\n", rtw_get_passing_time_ms(sctx->submit_time));
1536 rtw_sctx_done(&sctx);
1537 }
1538
c2h_txpwr_idx_offload_wait(_adapter * adapter)1539 int c2h_txpwr_idx_offload_wait(_adapter *adapter)
1540 {
1541 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1542 struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1543
1544 return rtw_sctx_wait(sctx, __func__);
1545 }
1546 #endif
1547
1548 #define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1549 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1550 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1551 #define GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1552 #define GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1553 #define GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
1554 #define GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
1555 #define GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1556 #define GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1557 #define GET_C2H_MAC_HIDDEN_RPT_BW(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1558 #define GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1559 #define GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1560 #define GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1561
1562 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1563 #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1564 #endif
1565
1566 #ifdef CONFIG_RTW_MAC_HIDDEN_RPT
c2h_mac_hidden_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1567 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1568 {
1569 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1570 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1571 enum rf_type rf_type;
1572 u8 tx_path_num, rx_path_num;
1573 int ret = _FAIL;
1574
1575 u8 uuid_x;
1576 u8 uuid_y;
1577 u8 uuid_z;
1578 u16 uuid_crc;
1579
1580 u8 hci_type;
1581 u8 package_type;
1582 u8 tr_switch;
1583 u8 wl_func;
1584 u8 hw_stype;
1585 u8 bw;
1586 u8 ss_num = 4;
1587 u8 ant_num;
1588 u8 protocol;
1589 u8 nic;
1590
1591 int i;
1592
1593 if (len < MAC_HIDDEN_RPT_LEN) {
1594 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1595 goto exit;
1596 }
1597
1598 uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1599 uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1600 uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1601 uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1602
1603 hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1604 package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1605
1606 tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
1607
1608 wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1609 hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1610
1611 bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1612 ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1613
1614 protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1615 nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1616
1617 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1618 for (i = 0; i < len; i++)
1619 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1620
1621 RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1622 RTW_PRINT("hci_type:0x%x\n", hci_type);
1623 RTW_PRINT("package_type:0x%x\n", package_type);
1624 RTW_PRINT("tr_switch:0x%x\n", tr_switch);
1625 RTW_PRINT("wl_func:0x%x\n", wl_func);
1626 RTW_PRINT("hw_stype:0x%x\n", hw_stype);
1627 RTW_PRINT("bw:0x%x\n", bw);
1628 RTW_PRINT("ant_num:0x%x\n", ant_num);
1629 RTW_PRINT("protocol:0x%x\n", protocol);
1630 RTW_PRINT("nic:0x%x\n", nic);
1631 }
1632
1633 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
1634 if (IS_8822C_SERIES(hal_data->version_id) || IS_8814B_SERIES(hal_data->version_id)) {
1635 #define GET_C2H_MAC_HIDDEN_RPT_SS_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)
1636 ss_num = GET_C2H_MAC_HIDDEN_RPT_SS_NUM(data);
1637
1638 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1639 RTW_PRINT("ss_num:0x%x\n", ss_num);
1640
1641 if (ss_num == 0x03)
1642 ss_num = 4;
1643 }
1644 #endif
1645
1646 #if defined(CONFIG_RTL8822C)
1647 if (IS_8822C_SERIES(hal_data->version_id)) {
1648 if (ant_num == 1)
1649 hal_spec->rf_reg_trx_path_bmp = 0x22; /* 1T1R pathB */
1650 if (hw_stype == 0xE)
1651 hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, 1); /* limit 1TX only */
1652 }
1653 #endif
1654 hal_data->PackageType = package_type;
1655 hal_spec->hci_type = hci_type;
1656 hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1657 hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1658 hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1659
1660 rf_type = rtw_chip_rftype_to_hal_rftype(adapter, 0);
1661 if (!RF_TYPE_VALID(rf_type)) {
1662 RTW_ERR("%s rtw_chip_rftype_to_hal_rftype failed\n", __func__);
1663 goto exit;
1664 }
1665 hal_spec->rf_reg_path_avail_num = rtw_min(hal_spec->rf_reg_path_num, ant_num);
1666 tx_path_num = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1667 rx_path_num = rtw_min(rf_type_to_rf_rx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1668 hal_spec->rf_reg_trx_path_bmp = rtw_restrict_trx_path_bmp_by_trx_num_lmt(
1669 hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num, &tx_path_num, &rx_path_num);
1670 if (!hal_spec->rf_reg_trx_path_bmp) {
1671 RTW_ERR("%s rtw_restrict_trx_path_bmp_by_trx_num_lmt(0x%x, %u, %u) failed\n"
1672 , __func__, hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num);
1673 goto exit;
1674 }
1675 hal_spec->rf_reg_path_avail_num = rtw_max(tx_path_num, rx_path_num);
1676
1677 /*
1678 * RF TX path num >= max_tx_cnt >= tx_nss_num
1679 * ex: RF TX path num(4) >= max_tx_cnt(2) >= tx_nss_num(1)
1680 * Select at most 2 out of 4 TX RF path to do 1SS 2TX
1681 */
1682 hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, tx_path_num);
1683 hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, hal_spec->max_tx_cnt);
1684 hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ss_num);
1685
1686 hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rx_path_num);
1687 hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ss_num);
1688
1689 ret = _SUCCESS;
1690
1691 exit:
1692 return ret;
1693 }
1694
c2h_mac_hidden_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1695 int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1696 {
1697 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1698 int ret = _FAIL;
1699
1700 int i;
1701
1702 if (len < MAC_HIDDEN_RPT_2_LEN) {
1703 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
1704 goto exit;
1705 }
1706
1707 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1708 for (i = 0; i < len; i++)
1709 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1710 }
1711
1712 #if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)
1713 if (IS_8188F(hal_data->version_id) || IS_8188GTV(hal_data->version_id)) {
1714 #define GET_C2H_MAC_HIDDEN_RPT_IRV(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
1715 u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
1716
1717 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1718 RTW_PRINT("irv:0x%x\n", irv);
1719
1720 if(irv != 0xf)
1721 hal_data->version_id.CUTVersion = irv;
1722 }
1723 #endif
1724
1725 ret = _SUCCESS;
1726
1727 exit:
1728 return ret;
1729 }
1730
hal_read_mac_hidden_rpt(_adapter * adapter)1731 int hal_read_mac_hidden_rpt(_adapter *adapter)
1732 {
1733 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
1734 int ret = _FAIL;
1735 int ret_fwdl;
1736 u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
1737 systime start = rtw_get_current_time();
1738 u32 cnt = 0;
1739 u32 timeout_ms = 800;
1740 u32 min_cnt = 10;
1741 u8 id = C2H_DEFEATURE_RSVD;
1742 int i;
1743
1744 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1745 u8 hci_type = rtw_get_intf_type(adapter);
1746
1747 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1748 && !rtw_is_hw_init_completed(adapter))
1749 rtw_hal_power_on(adapter);
1750 #endif
1751
1752 /* inform FW mac hidden rpt from reg is needed */
1753 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
1754
1755 /* download FW */
1756 pHalData->not_xmitframe_fw_dl = 1;
1757 ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1758 pHalData->not_xmitframe_fw_dl = 0;
1759 if (ret_fwdl != _SUCCESS)
1760 goto mac_hidden_rpt_hdl;
1761
1762 /* polling for data ready */
1763 start = rtw_get_current_time();
1764 do {
1765 cnt++;
1766 id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1767 if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1768 break;
1769 rtw_msleep_os(10);
1770 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1771
1772 if (id == C2H_MAC_HIDDEN_RPT) {
1773 /* read data */
1774 for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
1775 mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1776 }
1777
1778 /* inform FW mac hidden rpt has read */
1779 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
1780
1781 mac_hidden_rpt_hdl:
1782 c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1783 c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
1784
1785 if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1786 ret = _SUCCESS;
1787
1788 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1789 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1790 && !rtw_is_hw_init_completed(adapter))
1791 rtw_hal_power_off(adapter);
1792 #endif
1793
1794 RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1795 , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1796
1797 return ret;
1798 }
1799 #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
1800
c2h_defeature_dbg_hdl(_adapter * adapter,u8 * data,u8 len)1801 int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
1802 {
1803 int ret = _FAIL;
1804
1805 int i;
1806
1807 if (len < DEFEATURE_DBG_LEN) {
1808 RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
1809 goto exit;
1810 }
1811
1812 for (i = 0; i < len; i++)
1813 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1814
1815 ret = _SUCCESS;
1816
1817 exit:
1818 return ret;
1819 }
1820
1821 #ifndef DBG_CUSTOMER_STR_RPT_HANDLE
1822 #define DBG_CUSTOMER_STR_RPT_HANDLE 0
1823 #endif
1824
1825 #ifdef CONFIG_RTW_CUSTOMER_STR
rtw_hal_h2c_customer_str_req(_adapter * adapter)1826 s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
1827 {
1828 u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
1829
1830 SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
1831 return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
1832 }
1833
1834 #define C2H_CUSTOMER_STR_RPT_BYTE0(_data) ((u8 *)(_data))
1835 #define C2H_CUSTOMER_STR_RPT_2_BYTE8(_data) ((u8 *)(_data))
1836
c2h_customer_str_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1837 int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1838 {
1839 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1840 int ret = _FAIL;
1841 int i;
1842
1843 if (len < CUSTOMER_STR_RPT_LEN) {
1844 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
1845 goto exit;
1846 }
1847
1848 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1849 RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
1850
1851 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1852
1853 if (dvobj->customer_str_sctx != NULL) {
1854 if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
1855 RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
1856 _rtw_memcpy(dvobj->customer_str, C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
1857 dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
1858 } else
1859 RTW_WARN("%s sctx not set\n", __func__);
1860
1861 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1862
1863 ret = _SUCCESS;
1864
1865 exit:
1866 return ret;
1867 }
1868
c2h_customer_str_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1869 int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1870 {
1871 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1872 int ret = _FAIL;
1873 int i;
1874
1875 if (len < CUSTOMER_STR_RPT_2_LEN) {
1876 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
1877 goto exit;
1878 }
1879
1880 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1881 RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
1882
1883 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1884
1885 if (dvobj->customer_str_sctx != NULL) {
1886 if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
1887 RTW_WARN("%s rpt not ready\n", __func__);
1888 _rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN, C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
1889 rtw_sctx_done(&dvobj->customer_str_sctx);
1890 } else
1891 RTW_WARN("%s sctx not set\n", __func__);
1892
1893 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1894
1895 ret = _SUCCESS;
1896
1897 exit:
1898 return ret;
1899 }
1900
1901 /* read customer str */
rtw_hal_customer_str_read(_adapter * adapter,u8 * cs)1902 s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
1903 {
1904 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1905 struct submit_ctx sctx;
1906 s32 ret = _SUCCESS;
1907
1908 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1909 if (dvobj->customer_str_sctx != NULL)
1910 ret = _FAIL;
1911 else {
1912 rtw_sctx_init(&sctx, 2 * 1000);
1913 dvobj->customer_str_sctx = &sctx;
1914 }
1915 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1916
1917 if (ret == _FAIL) {
1918 RTW_WARN("%s another handle ongoing\n", __func__);
1919 goto exit;
1920 }
1921
1922 ret = rtw_customer_str_req_cmd(adapter);
1923 if (ret != _SUCCESS) {
1924 RTW_WARN("%s read cmd fail\n", __func__);
1925 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1926 dvobj->customer_str_sctx = NULL;
1927 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1928 goto exit;
1929 }
1930
1931 /* wait till rpt done or timeout */
1932 rtw_sctx_wait(&sctx, __func__);
1933
1934 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1935 dvobj->customer_str_sctx = NULL;
1936 if (sctx.status == RTW_SCTX_DONE_SUCCESS)
1937 _rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1938 else
1939 ret = _FAIL;
1940 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1941
1942 exit:
1943 return ret;
1944 }
1945
rtw_hal_h2c_customer_str_write(_adapter * adapter,const u8 * cs)1946 s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
1947 {
1948 u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
1949 u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
1950 u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
1951 s32 ret;
1952
1953 SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
1954 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
1955
1956 SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
1957 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
1958
1959 SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
1960 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
1961
1962 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
1963 if (ret != _SUCCESS) {
1964 RTW_WARN("%s w1 fail\n", __func__);
1965 goto exit;
1966 }
1967
1968 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
1969 if (ret != _SUCCESS) {
1970 RTW_WARN("%s w2 fail\n", __func__);
1971 goto exit;
1972 }
1973
1974 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
1975 if (ret != _SUCCESS) {
1976 RTW_WARN("%s w3 fail\n", __func__);
1977 goto exit;
1978 }
1979
1980 exit:
1981 return ret;
1982 }
1983
1984 /* write customer str and check if value reported is the same as requested */
rtw_hal_customer_str_write(_adapter * adapter,const u8 * cs)1985 s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
1986 {
1987 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1988 struct submit_ctx sctx;
1989 s32 ret = _SUCCESS;
1990
1991 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1992 if (dvobj->customer_str_sctx != NULL)
1993 ret = _FAIL;
1994 else {
1995 rtw_sctx_init(&sctx, 2 * 1000);
1996 dvobj->customer_str_sctx = &sctx;
1997 }
1998 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1999
2000 if (ret == _FAIL) {
2001 RTW_WARN("%s another handle ongoing\n", __func__);
2002 goto exit;
2003 }
2004
2005 ret = rtw_customer_str_write_cmd(adapter, cs);
2006 if (ret != _SUCCESS) {
2007 RTW_WARN("%s write cmd fail\n", __func__);
2008 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2009 dvobj->customer_str_sctx = NULL;
2010 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2011 goto exit;
2012 }
2013
2014 ret = rtw_customer_str_req_cmd(adapter);
2015 if (ret != _SUCCESS) {
2016 RTW_WARN("%s read cmd fail\n", __func__);
2017 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2018 dvobj->customer_str_sctx = NULL;
2019 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2020 goto exit;
2021 }
2022
2023 /* wait till rpt done or timeout */
2024 rtw_sctx_wait(&sctx, __func__);
2025
2026 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
2027 dvobj->customer_str_sctx = NULL;
2028 if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
2029 if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
2030 RTW_WARN("%s read back check fail\n", __func__);
2031 RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
2032 RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
2033 ret = _FAIL;
2034 }
2035 } else
2036 ret = _FAIL;
2037 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
2038
2039 exit:
2040 return ret;
2041 }
2042 #endif /* CONFIG_RTW_CUSTOMER_STR */
2043
2044 #ifdef RTW_PER_CMD_SUPPORT_FW
2045 #define H2C_REQ_PER_RPT_LEN 5
2046 #define SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value)
2047 #define SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value)
2048 #define SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(__pH2CCmd, __Value) SET_BITS_TO_LE_4BYTE(__pH2CCmd + 1, 0, 32, __Value)
2049
rtw_hal_set_req_per_rpt_cmd(_adapter * adapter,u8 group_macid,u8 rpt_type,u32 macid_bitmap)2050 u8 rtw_hal_set_req_per_rpt_cmd(_adapter *adapter, u8 group_macid,
2051 u8 rpt_type, u32 macid_bitmap)
2052 {
2053 u8 ret = _FAIL;
2054 u8 cmd_buf[H2C_REQ_PER_RPT_LEN] = {0};
2055
2056 SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(cmd_buf, group_macid);
2057 SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(cmd_buf, rpt_type);
2058 SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(cmd_buf, macid_bitmap);
2059
2060 ret = rtw_hal_fill_h2c_cmd(adapter,
2061 H2C_REQ_PER_RPT,
2062 H2C_REQ_PER_RPT_LEN,
2063 cmd_buf);
2064 return ret;
2065 }
2066
2067 #define GET_C2H_PER_RATE_RPT_TYPE0_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2068 #define GET_C2H_PER_RATE_RPT_TYPE0_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2069 #define GET_C2H_PER_RATE_RPT_TYPE0_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
2070 #define GET_C2H_PER_RATE_RPT_TYPE0_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
2071 #define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 4, 0, 16)
2072 #define GET_C2H_PER_RATE_RPT_TYPE0_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
2073 #define GET_C2H_PER_RATE_RPT_TYPE0_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 8)
2074 #define GET_C2H_PER_RATE_RPT_TYPE0_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
2075 #define GET_C2H_PER_RATE_RPT_TYPE0_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 2)
2076 #define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 10, 0, 16)
2077
2078 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2079 #define GET_C2H_PER_RATE_RPT_TYPE1_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2080 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
2081 #define GET_C2H_PER_RATE_RPT_TYPE1_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
2082 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 8)
2083 #define GET_C2H_PER_RATE_RPT_TYPE1_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 8)
2084 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
2085 #define GET_C2H_PER_RATE_RPT_TYPE1_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 2)
2086 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
2087 #define GET_C2H_PER_RATE_RPT_TYPE1_PER2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 8)
2088 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 10, 0, 8)
2089 #define GET_C2H_PER_RATE_RPT_TYPE1_BW2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 11, 0, 2)
2090
per_rate_rpt_update(_adapter * adapter,u8 mac_id,u8 per,u8 rate,u8 bw,u8 total_pkt)2091 static void per_rate_rpt_update(_adapter *adapter, u8 mac_id,
2092 u8 per, u8 rate,
2093 u8 bw, u8 total_pkt)
2094 {
2095 #ifdef CONFIG_RTW_MESH
2096 rtw_ieee80211s_update_metric(adapter, mac_id,
2097 per, rate,
2098 bw, total_pkt);
2099 #endif
2100 }
2101
c2h_per_rate_rpt_hdl(_adapter * adapter,u8 * data,u8 len)2102 int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
2103 {
2104 /* Now only consider type0, since it covers all params in type1
2105 * type0: mac_id, per, rate, bw, total_pkt
2106 * type1: mac_id, per, rate, bw
2107 */
2108 u8 mac_id[2] = {0}, per[2] = {0}, rate[2] = {0}, bw[2] = {0};
2109 u16 total_pkt[2] = {0};
2110 int ret = _FAIL, i, macid_cnt = 0;
2111
2112 /* type0:
2113 * 1 macid includes 6 bytes info + 1 byte 0xff
2114 * 2 macid includes 2*6 bytes info
2115 */
2116 if (!(len == 7 || len == 12)) {
2117 RTW_WARN("%s len(%u) != 7 or 12\n", __FUNCTION__, len);
2118 goto exit;
2119 }
2120
2121 macid_cnt++;
2122 mac_id[0] = GET_C2H_PER_RATE_RPT_TYPE0_MACID0(data);
2123 per[0] = GET_C2H_PER_RATE_RPT_TYPE0_PER0(data);
2124 rate[0] = GET_C2H_PER_RATE_RPT_TYPE0_RATE0(data);
2125 bw[0] = GET_C2H_PER_RATE_RPT_TYPE0_BW0(data);
2126 total_pkt[0] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(data);
2127
2128 mac_id[1] = GET_C2H_PER_RATE_RPT_TYPE0_MACID1(data);
2129 /* 0xff means no report anymore */
2130 if (mac_id[1] == 0xff)
2131 goto update_per;
2132 if (len != 12) {
2133 RTW_WARN("%s incorrect format\n", __FUNCTION__);
2134 goto exit;
2135 }
2136 macid_cnt++;
2137 per[1] = GET_C2H_PER_RATE_RPT_TYPE0_PER1(data);
2138 rate[1] = GET_C2H_PER_RATE_RPT_TYPE0_RATE1(data);
2139 bw[1] = GET_C2H_PER_RATE_RPT_TYPE0_BW1(data);
2140 total_pkt[1] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(data);
2141
2142 update_per:
2143 for (i = 0; i < macid_cnt; i++) {
2144 RTW_DBG("[%s] type0 rpt[%d]: macid = %u, per = %u, "
2145 "rate = %u, bw = %u, total_pkt = %u\n",
2146 __FUNCTION__, i, mac_id[i], per[i],
2147 rate[i], bw[i], total_pkt[i]);
2148 per_rate_rpt_update(adapter, mac_id[i],
2149 per[i], rate[i],
2150 bw[i], total_pkt[i]);
2151 }
2152 ret = _SUCCESS;
2153 exit:
2154 return ret;
2155 }
2156 #endif /* RTW_PER_CMD_SUPPORT_FW */
2157
2158 #ifdef CONFIG_LPS_ACK
2159 #define GET_C2H_LPS_STATUS_RPT_GET_ACTION(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2160 #define GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2161 #define DBG_LPS_STATUS_RPT 0
2162
c2h_lps_status_rpt(PADAPTER adapter,u8 * data,u8 len)2163 int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len)
2164 {
2165 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
2166 struct submit_ctx *lps_sctx = &pwrpriv->lps_ack_sctx;
2167 u8 action = 0;
2168 s8 status_code = 0;
2169 int ret = _FAIL;
2170
2171 if (len < LPS_STATUS_RPT_LEN) {
2172 RTW_WARN("%s len(%u) < %d\n", __func__, len, LPS_STATUS_RPT_LEN);
2173 goto exit;
2174 }
2175
2176 action = GET_C2H_LPS_STATUS_RPT_GET_ACTION(data);
2177 status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data);
2178
2179 /* action=0: report force leave null data status */
2180 /* action=1: report Rf on status when receiving a SetPwrMode H2C with PwrState = RFON */
2181 switch (action) {
2182 case 0:
2183 /* status code 0: success, 1: no ack, 2: timeout, 3: cancel */
2184 case 1:
2185 /* status code 0: FW has already turn to RFON */
2186 pwrpriv->lps_ack_status = status_code;
2187
2188 if (DBG_LPS_STATUS_RPT)
2189 RTW_INFO("=== [C2H LPS Action(%d)] LPS Status Code:%d ===\n", action, status_code);
2190
2191 break;
2192 default:
2193 RTW_INFO("UnKnown Action(%d) for C2H LPS RPT\n", action);
2194 break;
2195 }
2196
2197 rtw_sctx_done(&lps_sctx);
2198 ret = _SUCCESS;
2199
2200 exit:
2201 return ret;
2202 }
2203 #endif /* CONFIG_LPS_ACK */
2204
rtw_hal_update_sta_wset(_adapter * adapter,struct sta_info * psta)2205 void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
2206 {
2207 u8 w_set = 0;
2208
2209 if (psta->wireless_mode & WIRELESS_11B)
2210 w_set |= WIRELESS_CCK;
2211
2212 if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
2213 w_set |= WIRELESS_OFDM;
2214
2215 if (psta->wireless_mode & WIRELESS_11_24N)
2216 w_set |= WIRELESS_HT;
2217
2218 if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N))
2219 w_set |= WIRELESS_VHT;
2220
2221 psta->cmn.support_wireless_set = w_set;
2222 }
2223
rtw_hal_update_sta_mimo_type(_adapter * adapter,struct sta_info * psta)2224 void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
2225 {
2226 s8 tx_nss, rx_nss;
2227
2228 tx_nss = rtw_get_sta_tx_nss(adapter, psta);
2229 rx_nss = rtw_get_sta_rx_nss(adapter, psta);
2230 if ((tx_nss == 1) && (rx_nss == 1))
2231 psta->cmn.mimo_type = RF_1T1R;
2232 else if ((tx_nss == 1) && (rx_nss == 2))
2233 psta->cmn.mimo_type = RF_1T2R;
2234 else if ((tx_nss == 2) && (rx_nss == 2))
2235 psta->cmn.mimo_type = RF_2T2R;
2236 else if ((tx_nss == 2) && (rx_nss == 3))
2237 psta->cmn.mimo_type = RF_2T3R;
2238 else if ((tx_nss == 2) && (rx_nss == 4))
2239 psta->cmn.mimo_type = RF_2T4R;
2240 else if ((tx_nss == 3) && (rx_nss == 3))
2241 psta->cmn.mimo_type = RF_3T3R;
2242 else if ((tx_nss == 3) && (rx_nss == 4))
2243 psta->cmn.mimo_type = RF_3T4R;
2244 else if ((tx_nss == 4) && (rx_nss == 4))
2245 psta->cmn.mimo_type = RF_4T4R;
2246 else
2247 rtw_warn_on(1);
2248
2249 #ifdef CONFIG_CTRL_TXSS_BY_TP
2250 rtw_ctrl_txss_update_mimo_type(adapter, psta);
2251 #endif
2252
2253 RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
2254 psta->cmn.mac_id, tx_nss, rx_nss);
2255 }
2256
rtw_hal_update_sta_smps_cap(_adapter * adapter,struct sta_info * psta)2257 void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
2258 {
2259 /*Spatial Multiplexing Power Save*/
2260 #if 0
2261 if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2262 #ifdef CONFIG_80211N_HT
2263 if (psta->htpriv.ht_option) {
2264 if (psta->htpriv.smps_cap == 0)
2265 psta->cmn.sm_ps = SM_PS_STATIC;
2266 else if (psta->htpriv.smps_cap == 1)
2267 psta->cmn.sm_ps = SM_PS_DYNAMIC;
2268 else
2269 psta->cmn.sm_ps = SM_PS_DISABLE;
2270 }
2271 #endif /* CONFIG_80211N_HT */
2272 } else
2273 #endif
2274 psta->cmn.sm_ps = SM_PS_DISABLE;
2275
2276 RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
2277 psta->cmn.mac_id, psta->cmn.sm_ps);
2278 }
2279
rtw_get_mgntframe_raid(_adapter * adapter,unsigned char network_type)2280 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
2281 {
2282
2283 u8 raid;
2284 if (IS_NEW_GENERATION_IC(adapter)) {
2285
2286 raid = (network_type & WIRELESS_11B) ? RATEID_IDX_B
2287 : RATEID_IDX_G;
2288 } else {
2289 raid = (network_type & WIRELESS_11B) ? RATR_INX_WIRELESS_B
2290 : RATR_INX_WIRELESS_G;
2291 }
2292 return raid;
2293 }
2294
rtw_hal_update_sta_rate_mask(PADAPTER padapter,struct sta_info * psta)2295 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
2296 {
2297 u8 i, tx_nss;
2298 u64 tx_ra_bitmap = 0, tmp64=0;
2299
2300 if (psta == NULL)
2301 return;
2302
2303 /* b/g mode ra_bitmap */
2304 for (i = 0; i < sizeof(psta->bssrateset); i++) {
2305 if (psta->bssrateset[i])
2306 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
2307 }
2308
2309 #ifdef CONFIG_80211N_HT
2310 if (padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
2311 tx_nss = GET_HAL_TX_NSS(padapter);
2312 #ifdef CONFIG_80211AC_VHT
2313 if (psta->vhtpriv.vht_option) {
2314 /* AC mode ra_bitmap */
2315 tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
2316 } else
2317 #endif /* CONFIG_80211AC_VHT */
2318 if (psta->htpriv.ht_option) {
2319 /* n mode ra_bitmap */
2320
2321 /* Handling SMPS mode for AP MODE only*/
2322 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2323 /*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
2324 if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
2325 /*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
2326 tx_nss = rtw_min(tx_nss, 1);
2327 }
2328 }
2329
2330 tmp64 = rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss);
2331 tx_ra_bitmap |= (tmp64 << 12);
2332 }
2333 }
2334 #endif /* CONFIG_80211N_HT */
2335 psta->cmn.ra_info.ramask = tx_ra_bitmap;
2336 psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
2337 }
2338
rtw_hal_update_sta_ra_info(PADAPTER padapter,struct sta_info * psta)2339 void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
2340 {
2341 rtw_hal_update_sta_mimo_type(padapter, psta);
2342 rtw_hal_update_sta_smps_cap(padapter, psta);
2343 rtw_hal_update_sta_rate_mask(padapter, psta);
2344 }
2345
2346 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
hw_bcn_ctrl_addr(_adapter * adapter,u8 hw_port)2347 static u32 hw_bcn_ctrl_addr(_adapter *adapter, u8 hw_port)
2348 {
2349 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2350
2351 if (hw_port >= hal_spec->port_num) {
2352 RTW_ERR(FUNC_ADPT_FMT" HW Port(%d) invalid\n", FUNC_ADPT_ARG(adapter), hw_port);
2353 rtw_warn_on(1);
2354 return 0;
2355 }
2356
2357 switch (hw_port) {
2358 case HW_PORT0:
2359 return REG_BCN_CTRL;
2360 case HW_PORT1:
2361 return REG_BCN_CTRL_1;
2362 }
2363
2364 return 0;
2365 }
2366 #endif
2367
rtw_hal_get_msr(_adapter * adapter,u8 * net_type)2368 static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2369 {
2370 #ifdef RTW_HALMAC
2371 rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
2372 adapter->hw_port, net_type);
2373 #else /* !RTW_HALMAC */
2374 switch (adapter->hw_port) {
2375 case HW_PORT0:
2376 /*REG_CR - BIT[17:16]-Network Type for port 1*/
2377 *net_type = rtw_read8(adapter, MSR) & 0x03;
2378 break;
2379 case HW_PORT1:
2380 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2381 *net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2382 break;
2383 #if defined(CONFIG_RTL8814A)
2384 case HW_PORT2:
2385 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2386 *net_type = rtw_read8(adapter, MSR1) & 0x03;
2387 break;
2388 case HW_PORT3:
2389 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2390 *net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2391 break;
2392 case HW_PORT4:
2393 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2394 *net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2395 break;
2396 #endif /*#if defined(CONFIG_RTL8814A)*/
2397 default:
2398 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2399 ADPT_ARG(adapter), adapter->hw_port);
2400 rtw_warn_on(1);
2401 break;
2402 }
2403 #endif /* !RTW_HALMAC */
2404 }
2405
2406 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/
rtw_hal_net_type_decision(_adapter * adapter,u8 net_type)2407 static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
2408 {
2409 if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
2410 if (net_type != _HW_STATE_NOLINK_)
2411 return _HW_STATE_AP_;
2412 }
2413 return net_type;
2414 }
2415 #endif
rtw_hal_set_msr(_adapter * adapter,u8 net_type)2416 static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2417 {
2418 #ifdef RTW_HALMAC
2419 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2420 net_type = rtw_hal_net_type_decision(adapter, net_type);
2421 #endif
2422 rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
2423 adapter->hw_port, net_type);
2424 #else /* !RTW_HALMAC */
2425 u8 val8 = 0;
2426
2427 switch (adapter->hw_port) {
2428 case HW_PORT0:
2429 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2430 net_type = rtw_hal_net_type_decision(adapter, net_type);
2431 #endif
2432 /*REG_CR - BIT[17:16]-Network Type for port 0*/
2433 val8 = rtw_read8(adapter, MSR) & 0x0C;
2434 val8 |= net_type;
2435 rtw_write8(adapter, MSR, val8);
2436 break;
2437 case HW_PORT1:
2438 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2439 val8 = rtw_read8(adapter, MSR) & 0x03;
2440 val8 |= net_type << 2;
2441 rtw_write8(adapter, MSR, val8);
2442 break;
2443 #if defined(CONFIG_RTL8814A)
2444 case HW_PORT2:
2445 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2446 val8 = rtw_read8(adapter, MSR1) & 0xFC;
2447 val8 |= net_type;
2448 rtw_write8(adapter, MSR1, val8);
2449 break;
2450 case HW_PORT3:
2451 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2452 val8 = rtw_read8(adapter, MSR1) & 0xF3;
2453 val8 |= net_type << 2;
2454 rtw_write8(adapter, MSR1, val8);
2455 break;
2456 case HW_PORT4:
2457 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2458 val8 = rtw_read8(adapter, MSR1) & 0xCF;
2459 val8 |= net_type << 4;
2460 rtw_write8(adapter, MSR1, val8);
2461 break;
2462 #endif /* CONFIG_RTL8814A */
2463 default:
2464 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2465 ADPT_ARG(adapter), adapter->hw_port);
2466 rtw_warn_on(1);
2467 break;
2468 }
2469 #endif /* !RTW_HALMAC */
2470 }
2471
2472 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
2473 #define SEC_CAM_ACCESS_TIMEOUT_MS 200
2474 #endif
2475
2476 #ifndef DBG_SEC_CAM_ACCESS
2477 #define DBG_SEC_CAM_ACCESS 0
2478 #endif
2479
rtw_sec_read_cam(_adapter * adapter,u8 addr)2480 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
2481 {
2482 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2483 u32 rdata;
2484 u32 cnt = 0;
2485 systime start = 0, end = 0;
2486 u8 timeout = 0;
2487 u8 sr = 0;
2488
2489 _enter_critical_mutex(mutex, NULL);
2490
2491 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
2492
2493 start = rtw_get_current_time();
2494 while (1) {
2495 if (rtw_is_surprise_removed(adapter)) {
2496 sr = 1;
2497 break;
2498 }
2499
2500 cnt++;
2501 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2502 break;
2503
2504 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2505 timeout = 1;
2506 break;
2507 }
2508 }
2509 end = rtw_get_current_time();
2510
2511 rdata = rtw_read32(adapter, REG_CAMREAD);
2512
2513 _exit_critical_mutex(mutex, NULL);
2514
2515 if (DBG_SEC_CAM_ACCESS || timeout) {
2516 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
2517 , FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2518 }
2519
2520 return rdata;
2521 }
2522
rtw_sec_write_cam(_adapter * adapter,u8 addr,u32 wdata)2523 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
2524 {
2525 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2526 u32 cnt = 0;
2527 systime start = 0, end = 0;
2528 u8 timeout = 0;
2529 u8 sr = 0;
2530
2531 _enter_critical_mutex(mutex, NULL);
2532
2533 rtw_write32(adapter, REG_CAMWRITE, wdata);
2534 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
2535
2536 start = rtw_get_current_time();
2537 while (1) {
2538 if (rtw_is_surprise_removed(adapter)) {
2539 sr = 1;
2540 break;
2541 }
2542
2543 cnt++;
2544 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2545 break;
2546
2547 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2548 timeout = 1;
2549 break;
2550 }
2551 }
2552 end = rtw_get_current_time();
2553
2554 _exit_critical_mutex(mutex, NULL);
2555
2556 if (DBG_SEC_CAM_ACCESS || timeout) {
2557 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
2558 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2559 }
2560 }
2561
rtw_sec_read_cam_ent(_adapter * adapter,u8 id,u8 * ctrl,u8 * mac,u8 * key)2562 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
2563 {
2564 u8 i;
2565 u32 rdata;
2566 u8 begin = 0;
2567 u8 end = 5; /* TODO: consider other key length accordingly */
2568
2569 if (!ctrl && !mac && !key) {
2570 rtw_warn_on(1);
2571 goto exit;
2572 }
2573
2574 /* TODO: check id range */
2575
2576 if (!ctrl && !mac)
2577 begin = 2; /* read from key */
2578
2579 if (!key && !mac)
2580 end = 0; /* read to ctrl */
2581 else if (!key)
2582 end = 2; /* read to mac */
2583
2584 for (i = begin; i <= end; i++) {
2585 rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
2586
2587 switch (i) {
2588 case 0:
2589 if (ctrl)
2590 _rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
2591 if (mac)
2592 _rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
2593 break;
2594 case 1:
2595 if (mac)
2596 _rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
2597 break;
2598 default:
2599 if (key)
2600 _rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
2601 break;
2602 }
2603 }
2604
2605 exit:
2606 return;
2607 }
2608
2609
rtw_sec_write_cam_ent(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)2610 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
2611 {
2612 unsigned int i;
2613 int j;
2614 u8 addr, addr1 = 0;
2615 u32 wdata, wdata1 = 0;
2616
2617 /* TODO: consider other key length accordingly */
2618 #if 0
2619 switch ((ctrl & 0x1c) >> 2) {
2620 case _WEP40_:
2621 case _TKIP_:
2622 case _AES_:
2623 case _WEP104_:
2624
2625 }
2626 #else
2627 j = 7;
2628 #endif
2629
2630 for (; j >= 0; j--) {
2631 switch (j) {
2632 case 0:
2633 wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
2634 break;
2635 case 1:
2636 wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
2637 break;
2638 case 6:
2639 case 7:
2640 wdata = 0;
2641 break;
2642 default:
2643 i = (j - 2) << 2;
2644 wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
2645 break;
2646 }
2647
2648 addr = (id << 3) + j;
2649
2650 #if defined(CONFIG_RTL8192F)
2651 if(j == 1) {
2652 wdata1 = wdata;
2653 addr1 = addr;
2654 continue;
2655 }
2656 #endif
2657
2658 rtw_sec_write_cam(adapter, addr, wdata);
2659 }
2660
2661 #if defined(CONFIG_RTL8192F)
2662 rtw_sec_write_cam(adapter, addr1, wdata1);
2663 #endif
2664 }
2665
rtw_sec_clr_cam_ent(_adapter * adapter,u8 id)2666 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
2667 {
2668 u8 addr;
2669
2670 addr = (id << 3);
2671 rtw_sec_write_cam(adapter, addr, 0);
2672 }
2673
rtw_sec_read_cam_is_gk(_adapter * adapter,u8 id)2674 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
2675 {
2676 bool res;
2677 u16 ctrl;
2678
2679 rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
2680
2681 res = (ctrl & BIT6) ? _TRUE : _FALSE;
2682 return res;
2683 }
2684 #ifdef CONFIG_MBSSID_CAM
rtw_mbid_cam_init(struct dvobj_priv * dvobj)2685 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
2686 {
2687 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2688
2689 _rtw_spinlock_init(&mbid_cam_ctl->lock);
2690 mbid_cam_ctl->bitmap = 0;
2691 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2692 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2693 }
2694
rtw_mbid_cam_deinit(struct dvobj_priv * dvobj)2695 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
2696 {
2697 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2698
2699 _rtw_spinlock_free(&mbid_cam_ctl->lock);
2700 }
2701
rtw_mbid_cam_reset(_adapter * adapter)2702 void rtw_mbid_cam_reset(_adapter *adapter)
2703 {
2704 _irqL irqL;
2705 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2706 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2707
2708 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2709 mbid_cam_ctl->bitmap = 0;
2710 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2711 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2712
2713 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2714 }
_rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2715 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2716 {
2717 u8 i;
2718 u8 cam_id = INVALID_CAM_ID;
2719 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2720
2721 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2722 if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
2723 cam_id = i;
2724 break;
2725 }
2726 }
2727
2728 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2729 return cam_id;
2730 }
2731
rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2732 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2733 {
2734 _irqL irqL;
2735
2736 u8 cam_id = INVALID_CAM_ID;
2737 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2738 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2739
2740 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2741 cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
2742 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2743
2744 return cam_id;
2745 }
_rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2746 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2747 {
2748 u8 i;
2749 u8 cam_id = INVALID_CAM_ID;
2750 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2751
2752 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2753 if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
2754 cam_id = i;
2755 break;
2756 }
2757 }
2758 if (cam_id != INVALID_CAM_ID)
2759 RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
2760 __func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
2761
2762 return cam_id;
2763 }
2764
rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2765 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2766 {
2767 _irqL irqL;
2768 u8 cam_id = INVALID_CAM_ID;
2769 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2770 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2771
2772 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2773 cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
2774 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2775
2776 return cam_id;
2777 }
rtw_get_max_mbid_cam_id(_adapter * adapter)2778 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
2779 {
2780 _irqL irqL;
2781 s8 i;
2782 u8 cam_id = INVALID_CAM_ID;
2783 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2784 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2785
2786 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2787 for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
2788 if (mbid_cam_ctl->bitmap & BIT(i)) {
2789 cam_id = i;
2790 break;
2791 }
2792 }
2793 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2794 /*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
2795 return cam_id;
2796 }
2797
rtw_get_mbid_cam_entry_num(_adapter * adapter)2798 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
2799 {
2800 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2801 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2802
2803 return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2804 }
2805
mbid_cam_cache_init(_adapter * adapter,struct mbid_cam_cache * pmbid_cam,u8 * mac_addr)2806 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
2807 {
2808 if (adapter && pmbid_cam && mac_addr) {
2809 _rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
2810 pmbid_cam->iface_id = adapter->iface_id;
2811 }
2812 }
mbid_cam_cache_clr(struct mbid_cam_cache * pmbid_cam)2813 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
2814 {
2815 if (pmbid_cam) {
2816 _rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
2817 pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
2818 }
2819 }
2820
rtw_mbid_camid_alloc(_adapter * adapter,u8 * mac_addr)2821 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
2822 {
2823 _irqL irqL;
2824 u8 cam_id = INVALID_CAM_ID, i;
2825 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2826 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2827 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2828
2829 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2830 goto exit;
2831
2832 if (entry_num >= TOTAL_MBID_CAM_NUM) {
2833 RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
2834 rtw_warn_on(1);
2835 }
2836
2837 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2838 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2839 if (!(mbid_cam_ctl->bitmap & BIT(i))) {
2840 mbid_cam_ctl->bitmap |= BIT(i);
2841 cam_id = i;
2842 break;
2843 }
2844 }
2845 if ((cam_id != INVALID_CAM_ID) && (mac_addr))
2846 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
2847 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2848
2849 if (cam_id != INVALID_CAM_ID) {
2850 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2851 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2852 #ifdef DBG_MBID_CAM_DUMP
2853 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2854 #endif
2855 } else
2856 RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2857 exit:
2858 return cam_id;
2859 }
2860
rtw_mbid_cam_info_change(_adapter * adapter,u8 * mac_addr)2861 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
2862 {
2863 _irqL irqL;
2864 u8 entry_id = INVALID_CAM_ID;
2865 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2866 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2867
2868 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2869 entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
2870 if (entry_id != INVALID_CAM_ID)
2871 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
2872
2873 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2874
2875 return entry_id;
2876 }
2877
rtw_mbid_cam_assign(_adapter * adapter,u8 * mac_addr,u8 camid)2878 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
2879 {
2880 _irqL irqL;
2881 u8 ret = _FALSE;
2882 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2883 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2884
2885 if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
2886 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
2887 rtw_warn_on(1);
2888 }
2889 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2890 goto exit;
2891
2892 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2893 if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
2894 if (mac_addr) {
2895 mbid_cam_ctl->bitmap |= BIT(camid);
2896 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
2897 ret = _TRUE;
2898 }
2899 }
2900 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2901
2902 if (ret == _TRUE) {
2903 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2904 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
2905 #ifdef DBG_MBID_CAM_DUMP
2906 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2907 #endif
2908 } else
2909 RTW_INFO("%s [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
2910
2911 exit:
2912 return ret;
2913 }
2914
rtw_mbid_camid_clean(_adapter * adapter,u8 mbss_canid)2915 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
2916 {
2917 _irqL irqL;
2918 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2919 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2920
2921 if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
2922 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
2923 rtw_warn_on(1);
2924 }
2925 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2926 mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
2927 mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
2928 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2929 ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
2930 RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
2931 }
rtw_mbid_cam_cache_dump(void * sel,const char * fun_name,_adapter * adapter)2932 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
2933 {
2934 _irqL irqL;
2935 u8 i;
2936 _adapter *iface;
2937 u8 iface_id;
2938 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2939 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2940 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2941 u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2942
2943 RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
2944
2945 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2946 RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
2947 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2948 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2949
2950 if (mbid_cam_ctl->bitmap & BIT(i)) {
2951 iface_id = dvobj->mbid_cam_cache[i].iface_id;
2952 _RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
2953 _RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2954
2955 iface = dvobj->padapters[iface_id];
2956 if (iface) {
2957 if (MLME_IS_STA(iface))
2958 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
2959 else if (MLME_IS_AP(iface))
2960 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
2961 else if (MLME_IS_MESH(iface))
2962 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");
2963 else
2964 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2965 }
2966
2967 } else
2968 _RTW_PRINT_SEL(sel, "N/A\n");
2969 }
2970 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2971 return 0;
2972 }
2973
read_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2974 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2975 {
2976 u8 poll = 1;
2977 u8 cam_ready = _FALSE;
2978 u32 cam_data1 = 0;
2979 u16 cam_data2 = 0;
2980
2981 if (RTW_CANNOT_RUN(padapter))
2982 return;
2983
2984 rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2985
2986 do {
2987 if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2988 cam_ready = _TRUE;
2989 break;
2990 }
2991 poll++;
2992 } while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2993
2994 if (cam_ready) {
2995 cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2996 mac[0] = cam_data1 & 0xFF;
2997 mac[1] = (cam_data1 >> 8) & 0xFF;
2998 mac[2] = (cam_data1 >> 16) & 0xFF;
2999 mac[3] = (cam_data1 >> 24) & 0xFF;
3000
3001 cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
3002 mac[4] = cam_data2 & 0xFF;
3003 mac[5] = (cam_data2 >> 8) & 0xFF;
3004 }
3005
3006 }
rtw_mbid_cam_dump(void * sel,const char * fun_name,_adapter * adapter)3007 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
3008 {
3009 /*_irqL irqL;*/
3010 u8 i;
3011 u8 mac_addr[ETH_ALEN];
3012
3013 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3014 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
3015
3016 RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
3017
3018 /*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
3019 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
3020 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
3021 _rtw_memset(mac_addr, 0, ETH_ALEN);
3022 read_mbssid_cam(adapter, i, mac_addr);
3023 _RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
3024 }
3025 /*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
3026 return 0;
3027 }
3028
write_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)3029 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
3030 {
3031 u32 cam_val[2] = {0};
3032
3033 cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
3034 cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT) | (mac[5] << 8) | mac[4];
3035
3036 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
3037 }
3038
3039 /*
3040 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
3041 {
3042 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
3043 }
3044 */
3045
rtw_ap_set_mbid_num(_adapter * adapter,u8 ap_num)3046 void rtw_ap_set_mbid_num(_adapter *adapter, u8 ap_num)
3047 {
3048 rtw_write8(adapter, REG_MBID_NUM,
3049 ((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | ((ap_num -1) & 0x07)));
3050
3051 }
rtw_mbid_cam_enable(_adapter * adapter)3052 void rtw_mbid_cam_enable(_adapter *adapter)
3053 {
3054 /*enable MBSSID*/
3055 rtw_hal_rcr_add(adapter, RCR_ENMBID);
3056 }
rtw_mi_set_mbid_cam(_adapter * adapter)3057 void rtw_mi_set_mbid_cam(_adapter *adapter)
3058 {
3059 u8 i;
3060 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3061 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
3062
3063 #ifdef DBG_MBID_CAM_DUMP
3064 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
3065 #endif
3066
3067 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
3068 if (mbid_cam_ctl->bitmap & BIT(i)) {
3069 write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
3070 RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
3071 }
3072 }
3073 rtw_mbid_cam_enable(adapter);
3074 }
3075 #endif /*CONFIG_MBSSID_CAM*/
3076
3077 #ifdef CONFIG_FW_HANDLE_TXBCN
3078 #define H2C_BCN_OFFLOAD_LEN 1
3079
3080 #define SET_H2CCMD_BCN_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
3081 #define SET_H2CCMD_BCN_ROOT_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
3082 #define SET_H2CCMD_BCN_VAP1_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)
3083 #define SET_H2CCMD_BCN_VAP2_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)
3084 #define SET_H2CCMD_BCN_VAP3_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value)
3085 #define SET_H2CCMD_BCN_VAP4_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value)
3086
rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter * adapter,bool fw_bcn_en,u8 tbtt_rpt_map)3087 void rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter *adapter, bool fw_bcn_en, u8 tbtt_rpt_map)
3088 {
3089 u8 fw_bcn_offload[1] = {0};
3090 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3091
3092 if (fw_bcn_en)
3093 SET_H2CCMD_BCN_OFFLOAD_EN(fw_bcn_offload, 1);
3094
3095 if (tbtt_rpt_map & BIT(0))
3096 SET_H2CCMD_BCN_ROOT_TBTT_RPT(fw_bcn_offload, 1);
3097 if (tbtt_rpt_map & BIT(1))
3098 SET_H2CCMD_BCN_VAP1_TBTT_RPT(fw_bcn_offload, 1);
3099 if (tbtt_rpt_map & BIT(2))
3100 SET_H2CCMD_BCN_VAP2_TBTT_RPT(fw_bcn_offload, 1);
3101 if (tbtt_rpt_map & BIT(3))
3102 SET_H2CCMD_BCN_VAP3_TBTT_RPT(fw_bcn_offload, 1);
3103
3104 dvobj->vap_tbtt_rpt_map = tbtt_rpt_map;
3105 dvobj->fw_bcn_offload = fw_bcn_en;
3106 RTW_INFO("[FW BCN] Offload : %s\n", (dvobj->fw_bcn_offload) ? "EN" : "DIS");
3107 RTW_INFO("[FW BCN] TBTT RPT map : 0x%02x\n", dvobj->vap_tbtt_rpt_map);
3108
3109 rtw_hal_fill_h2c_cmd(adapter, H2C_FW_BCN_OFFLOAD,
3110 H2C_BCN_OFFLOAD_LEN, fw_bcn_offload);
3111 }
3112
rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter * adapter)3113 void rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter *adapter)
3114 {
3115 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3116 u8 ret, vap_id;
3117 u32 page_size = 0;
3118 u8 bcn_rsvdpage[H2C_BCN_RSVDPAGE_LEN] = {0};
3119
3120 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
3121 #if 1
3122 for (vap_id = 0; vap_id < CONFIG_LIMITED_AP_NUM; vap_id++) {
3123 if (dvobj->vap_map & BIT(vap_id))
3124 bcn_rsvdpage[vap_id] = vap_id * (MAX_BEACON_LEN / page_size);
3125 }
3126 #else
3127 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)
3128 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 8, __Value)
3129 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 8, __Value)
3130 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 8, __Value)
3131 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 8, __Value)
3132
3133 if (dvobj->vap_map & BIT(0))
3134 SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(bcn_rsvdpage, 0);
3135 if (dvobj->vap_map & BIT(1))
3136 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(bcn_rsvdpage,
3137 1 * (MAX_BEACON_LEN / page_size));
3138 if (dvobj->vap_map & BIT(2))
3139 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(bcn_rsvdpage,
3140 2 * (MAX_BEACON_LEN / page_size));
3141 if (dvobj->vap_map & BIT(3))
3142 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(bcn_rsvdpage,
3143 3 * (MAX_BEACON_LEN / page_size));
3144 if (dvobj->vap_map & BIT(4))
3145 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(bcn_rsvdpage,
3146 4 * (MAX_BEACON_LEN / page_size));
3147 #endif
3148 if (1) {
3149 RTW_INFO("[BCN_LOC] vap_map : 0x%02x\n", dvobj->vap_map);
3150 RTW_INFO("[BCN_LOC] page_size :%d, @bcn_page_num :%d\n"
3151 , page_size, (MAX_BEACON_LEN / page_size));
3152 RTW_INFO("[BCN_LOC] root ap : 0x%02x\n", *bcn_rsvdpage);
3153 RTW_INFO("[BCN_LOC] vap_1 : 0x%02x\n", *(bcn_rsvdpage + 1));
3154 RTW_INFO("[BCN_LOC] vap_2 : 0x%02x\n", *(bcn_rsvdpage + 2));
3155 RTW_INFO("[BCN_LOC] vap_3 : 0x%02x\n", *(bcn_rsvdpage + 3));
3156 RTW_INFO("[BCN_LOC] vap_4 : 0x%02x\n", *(bcn_rsvdpage + 4));
3157 }
3158 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE,
3159 H2C_BCN_RSVDPAGE_LEN, bcn_rsvdpage);
3160 }
3161
rtw_ap_multi_bcn_cfg(_adapter * adapter)3162 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3163 {
3164 u8 dft_bcn_space = DEFAULT_BCN_INTERVAL;
3165 u8 sub_bcn_space = (DEFAULT_BCN_INTERVAL / CONFIG_LIMITED_AP_NUM);
3166
3167 /*enable to rx data frame*/
3168 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3169
3170 /*Disable Port0's beacon function*/
3171 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
3172 /*Reset Port0's TSF*/
3173 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT_TSFTR_RST);
3174
3175 rtw_ap_set_mbid_num(adapter, CONFIG_LIMITED_AP_NUM);
3176
3177 /*BCN space & BCN sub-space 0x554[15:0] = 0x64,0x5BC[23:16] = 0x21*/
3178 rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), HW_PORT0, dft_bcn_space);
3179 rtw_write8(adapter, REG_MBSSID_BCN_SPACE3 + 2, sub_bcn_space);
3180
3181 #if 0 /*setting in hw_var_set_opmode_mbid - ResumeTxBeacon*/
3182 /*BCN hold time 0x540[19:8] = 0x80*/
3183 rtw_write8(adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
3184 rtw_write8(adapter, REG_TBTT_PROHIBIT + 2,
3185 (rtw_read8(adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
3186 #endif
3187
3188 /*ATIM window -0x55A = 0x32, reg 0x570 = 0x32, reg 0x5A0 = 0x32 */
3189 rtw_write8(adapter, REG_ATIMWND, 0x32);
3190 rtw_write8(adapter, REG_ATIMWND1_V1, 0x32);
3191 rtw_write8(adapter, REG_ATIMWND2, 0x32);
3192 rtw_write8(adapter, REG_ATIMWND3, 0x32);
3193 /*
3194 rtw_write8(adapter, REG_ATIMWND4, 0x32);
3195 rtw_write8(adapter, REG_ATIMWND5, 0x32);
3196 rtw_write8(adapter, REG_ATIMWND6, 0x32);
3197 rtw_write8(adapter, REG_ATIMWND7, 0x32);*/
3198
3199 /*no limit setting - 0x5A7 = 0xFF - Packet in Hi Queue Tx immediately*/
3200 rtw_write8(adapter, REG_HIQ_NO_LMT_EN, 0xFF);
3201
3202 /*Mask all beacon*/
3203 rtw_write8(adapter, REG_MBSSID_CTRL, 0);
3204
3205 /*BCN invalid bit setting 0x454[6] = 1*/
3206 /*rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);*/
3207
3208 /*Enable Port0's beacon function*/
3209 rtw_write8(adapter, REG_BCN_CTRL,
3210 rtw_read8(adapter, REG_BCN_CTRL) | BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION);
3211
3212 /* Enable HW seq for BCN
3213 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
3214 #ifdef CONFIG_RTL8822B
3215 if (IS_HARDWARE_TYPE_8822B(adapter))
3216 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3217 #endif
3218
3219 #ifdef CONFIG_RTL8822C
3220 if (IS_HARDWARE_TYPE_8822C(adapter))
3221 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3222 #endif
3223 }
_rtw_mbid_bcn_cfg(_adapter * adapter,bool mbcnq_en,u8 mbcnq_id)3224 static void _rtw_mbid_bcn_cfg(_adapter *adapter, bool mbcnq_en, u8 mbcnq_id)
3225 {
3226 if (mbcnq_id >= CONFIG_LIMITED_AP_NUM) {
3227 RTW_ERR(FUNC_ADPT_FMT"- mbid bcnq_id(%d) invalid\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3228 rtw_warn_on(1);
3229 }
3230
3231 if (mbcnq_en) {
3232 rtw_write8(adapter, REG_MBSSID_CTRL,
3233 rtw_read8(adapter, REG_MBSSID_CTRL) | BIT(mbcnq_id));
3234 RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) enabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3235 } else {
3236 rtw_write8(adapter, REG_MBSSID_CTRL,
3237 rtw_read8(adapter, REG_MBSSID_CTRL) & (~BIT(mbcnq_id)));
3238 RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) disabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3239 }
3240 }
3241 /*#define CONFIG_FW_TBTT_RPT*/
rtw_ap_mbid_bcn_en(_adapter * adapter,u8 ap_id)3242 void rtw_ap_mbid_bcn_en(_adapter *adapter, u8 ap_id)
3243 {
3244 RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3245
3246 #ifdef CONFIG_FW_TBTT_RPT
3247 if (rtw_ap_get_nums(adapter) >= 1) {
3248 u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3249
3250 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3251 tbtt_rpt_map | BIT(ap_id));/*H2C-0xBA*/
3252 }
3253 #else
3254 if (rtw_ap_get_nums(adapter) == 1)
3255 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE, 0);/*H2C-0xBA*/
3256 #endif
3257
3258 rtw_hal_set_bcn_rsvdpage_loc_cmd(adapter);/*H2C-0x09*/
3259
3260 _rtw_mbid_bcn_cfg(adapter, _TRUE, ap_id);
3261 }
rtw_ap_mbid_bcn_dis(_adapter * adapter,u8 ap_id)3262 void rtw_ap_mbid_bcn_dis(_adapter *adapter, u8 ap_id)
3263 {
3264 RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3265 _rtw_mbid_bcn_cfg(adapter, _FALSE, ap_id);
3266
3267 if (rtw_ap_get_nums(adapter) == 0)
3268 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _FALSE, 0);
3269 #ifdef CONFIG_FW_TBTT_RPT
3270 else if (rtw_ap_get_nums(adapter) >= 1) {
3271 u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3272
3273 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3274 tbtt_rpt_map & ~BIT(ap_id));/*H2C-0xBA*/
3275 }
3276 #endif
3277 }
3278 #endif
3279 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_ap_multi_bcn_cfg(_adapter * adapter)3280 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3281 {
3282 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3283 rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT);
3284 #else
3285 rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
3286 #endif
3287 /*enable to rx data frame*/
3288 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3289
3290 /*Beacon Control related register for first time*/
3291 rtw_write8(adapter, REG_BCNDMATIM, 0x02); /* 2ms */
3292
3293 /*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
3294 rtw_write8(adapter, REG_ATIMWND, 0x0c); /* 12ms */
3295
3296 #ifndef CONFIG_HW_P0_TSF_SYNC
3297 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3298 #endif
3299
3300 /*reset TSF*/
3301 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
3302
3303 /*enable BCN0 Function for if1*/
3304 /*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
3305 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3306 rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);
3307 #else
3308 rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3309 #endif
3310 #ifdef CONFIG_BCN_XMIT_PROTECT
3311 rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
3312 #endif
3313
3314 if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/
3315 rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
3316
3317 /* Enable HW seq for BCN
3318 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
3319 #ifdef CONFIG_RTL8822B
3320 if (IS_HARDWARE_TYPE_8822B(adapter))
3321 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3322 #endif
3323
3324 #ifdef CONFIG_RTL8822C
3325 if (IS_HARDWARE_TYPE_8822C(adapter))
3326 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3327 #endif
3328 }
3329 #endif
3330
3331 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3332 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3333 {
3334
3335 #if 0 /*TODO - modify for more flexible*/
3336 u8 idx = 0;
3337
3338 if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
3339 (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
3340 for (idx = 0; idx < 6; idx++)
3341 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
3342 } else {
3343 /*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
3344 u8 entry_id;
3345
3346 if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
3347 (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
3348 entry_id = 0;
3349 if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
3350 RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
3351 write_mbssid_cam(adapter, entry_id, val);
3352 }
3353 } else {
3354 entry_id = rtw_mbid_camid_alloc(adapter, val);
3355 if (entry_id != INVALID_CAM_ID)
3356 write_mbssid_cam(adapter, entry_id, val);
3357 }
3358 }
3359 #else
3360 {
3361 /*
3362 MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
3363 */
3364 u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
3365
3366
3367 if (entry_id != INVALID_CAM_ID) {
3368 write_mbssid_cam(adapter, entry_id, mac_addr);
3369 RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,
3370 ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));
3371 }
3372 }
3373 #endif
3374 }
3375
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3376 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3377 {
3378 u8 idx = 0;
3379 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3380 u8 entry_id;
3381
3382 if (!mac_addr) {
3383 rtw_warn_on(1);
3384 return;
3385 }
3386
3387
3388 entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
3389
3390 if (entry_id != INVALID_CAM_ID)
3391 write_mbssid_cam(adapter, entry_id, mac_addr);
3392 }
3393
3394 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_hal_bcn_interval_adjust(_adapter * adapter,u16 bcn_interval)3395 u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
3396 {
3397 if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
3398 return adapter_to_dvobj(adapter)->inter_bcn_space;
3399 else
3400 return bcn_interval;
3401 }
3402 #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
3403
3404 #else
3405
3406 #ifndef RTW_HALMAC
_get_macaddr_reg(enum _hw_port hwport)3407 static u32 _get_macaddr_reg(enum _hw_port hwport)
3408 {
3409 u32 reg_macaddr = REG_MACID;
3410
3411 #ifdef CONFIG_CONCURRENT_MODE
3412 if (hwport == HW_PORT1)
3413 reg_macaddr = REG_MACID1;
3414 #if defined(CONFIG_RTL8814A)
3415 else if (hwport == HW_PORT2)
3416 reg_macaddr = REG_MACID2;
3417 else if (hwport == HW_PORT3)
3418 reg_macaddr = REG_MACID3;
3419 else if (hwport == HW_PORT4)
3420 reg_macaddr = REG_MACID4;
3421 #endif /*CONFIG_RTL8814A*/
3422 #endif /*CONFIG_CONCURRENT_MODE*/
3423
3424 return reg_macaddr;
3425 }
3426 #endif /*!RTW_HALMAC*/
3427
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * mac_addr)3428 static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr)
3429 {
3430 enum _hw_port hwport;
3431
3432 if (mac_addr == NULL)
3433 return;
3434 hwport = get_hw_port(adapter);
3435
3436 RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3437 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3438
3439 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3440 rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3441 #else /* !RTW_HALMAC */
3442 {
3443 u8 idx = 0;
3444 u32 reg_macaddr = _get_macaddr_reg(hwport);
3445
3446 for (idx = 0; idx < ETH_ALEN; idx++)
3447 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx), mac_addr[idx]);
3448 }
3449 #endif /* !RTW_HALMAC */
3450 }
3451
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)3452 static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
3453 {
3454 enum _hw_port hwport;
3455
3456 if (mac_addr == NULL)
3457 return;
3458 hwport = get_hw_port(adapter);
3459
3460 _rtw_memset(mac_addr, 0, ETH_ALEN);
3461 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3462 rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3463 #else /* !RTW_HALMAC */
3464 {
3465 u8 idx = 0;
3466 u32 reg_macaddr = _get_macaddr_reg(hwport);
3467
3468 for (idx = 0; idx < ETH_ALEN; idx++)
3469 mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx));
3470 }
3471 #endif /* !RTW_HALMAC */
3472
3473 RTW_DBG("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3474 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3475 }
3476 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
3477
3478 #ifndef RTW_HALMAC
_get_bssid_reg(enum _hw_port hw_port)3479 static u32 _get_bssid_reg(enum _hw_port hw_port)
3480 {
3481 u32 reg_bssid = REG_BSSID;
3482
3483 #ifdef CONFIG_CONCURRENT_MODE
3484 if (hw_port == HW_PORT1)
3485 reg_bssid = REG_BSSID1;
3486 #if defined(CONFIG_RTL8814A)
3487 else if (hw_port == HW_PORT2)
3488 reg_bssid = REG_BSSID2;
3489 else if (hw_port == HW_PORT3)
3490 reg_bssid = REG_BSSID3;
3491 else if (hw_port == HW_PORT4)
3492 reg_bssid = REG_BSSID4;
3493 #endif /*CONFIG_RTL8814A*/
3494 #endif /*CONFIG_CONCURRENT_MODE*/
3495
3496 return reg_bssid;
3497 }
3498 #endif /*!RTW_HALMAC*/
rtw_hal_set_bssid(_adapter * adapter,u8 * val)3499 static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
3500 {
3501 enum _hw_port hw_port = rtw_hal_get_port(adapter);
3502 #ifdef RTW_HALMAC
3503
3504 rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);
3505 #else /* !RTW_HALMAC */
3506 u8 idx = 0;
3507 u32 reg_bssid = _get_bssid_reg(hw_port);
3508
3509 for (idx = 0 ; idx < ETH_ALEN; idx++)
3510 rtw_write8(adapter, (reg_bssid + idx), val[idx]);
3511 #endif /* !RTW_HALMAC */
3512
3513 RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",
3514 __func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));
3515 }
3516
3517 #ifndef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_tsf_update(_adapter * adapter,u8 en)3518 static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)
3519 {
3520 u32 addr = 0;
3521 u8 val8;
3522
3523 rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);
3524 if (addr) {
3525 rtw_enter_protsel_port(adapter, get_hw_port(adapter));
3526 val8 = rtw_read8(adapter, addr);
3527 if (en && (val8 & DIS_TSF_UDT)) {
3528 rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);
3529 #ifdef DBG_TSF_UPDATE
3530 RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3531 #endif
3532 }
3533 if (!en && !(val8 & DIS_TSF_UDT)) {
3534 rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);
3535 #ifdef DBG_TSF_UPDATE
3536 RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3537 #endif
3538 }
3539 rtw_leave_protsel_port(adapter);
3540 } else {
3541 RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"
3542 , adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");
3543 rtw_warn_on(1);
3544 }
3545 }
3546 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_set_hw_update_tsf(PADAPTER padapter)3547 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
3548 {
3549 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3550
3551 #else
3552 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3553
3554 if (!pmlmeext->en_hw_update_tsf)
3555 return;
3556
3557 /* check RCR */
3558 if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
3559 return;
3560
3561 if (pmlmeext->tsf_update_required) {
3562 pmlmeext->tsf_update_pause_stime = 0;
3563 rtw_hal_set_tsf_update(padapter, 1);
3564 }
3565
3566 pmlmeext->en_hw_update_tsf = 0;
3567 #endif
3568 }
3569
rtw_iface_enable_tsf_update(_adapter * adapter)3570 void rtw_iface_enable_tsf_update(_adapter *adapter)
3571 {
3572 adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3573 adapter->mlmeextpriv.tsf_update_required = 1;
3574 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3575
3576 #else
3577 rtw_hal_set_tsf_update(adapter, 1);
3578 #endif
3579 }
3580
rtw_iface_disable_tsf_update(_adapter * adapter)3581 void rtw_iface_disable_tsf_update(_adapter *adapter)
3582 {
3583 adapter->mlmeextpriv.tsf_update_required = 0;
3584 adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3585 adapter->mlmeextpriv.en_hw_update_tsf = 0;
3586 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3587
3588 #else
3589 rtw_hal_set_tsf_update(adapter, 0);
3590 #endif
3591 }
3592
rtw_hal_tsf_update_pause(_adapter * adapter)3593 static void rtw_hal_tsf_update_pause(_adapter *adapter)
3594 {
3595 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3596
3597 #else
3598 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3599 _adapter *iface;
3600 int i;
3601
3602 for (i = 0; i < dvobj->iface_nums; i++) {
3603 iface = dvobj->padapters[i];
3604 if (!iface)
3605 continue;
3606
3607 rtw_hal_set_tsf_update(iface, 0);
3608 if (iface->mlmeextpriv.tsf_update_required) {
3609 iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();
3610 if (!iface->mlmeextpriv.tsf_update_pause_stime)
3611 iface->mlmeextpriv.tsf_update_pause_stime++;
3612 }
3613 iface->mlmeextpriv.en_hw_update_tsf = 0;
3614 }
3615 #endif
3616 }
3617
rtw_hal_tsf_update_restore(_adapter * adapter)3618 static void rtw_hal_tsf_update_restore(_adapter *adapter)
3619 {
3620 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3621
3622 #else
3623 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3624 _adapter *iface;
3625 int i;
3626
3627 for (i = 0; i < dvobj->iface_nums; i++) {
3628 iface = dvobj->padapters[i];
3629 if (!iface)
3630 continue;
3631
3632 if (iface->mlmeextpriv.tsf_update_required) {
3633 /* enable HW TSF update when recive beacon*/
3634 iface->mlmeextpriv.en_hw_update_tsf = 1;
3635 #ifdef DBG_TSF_UPDATE
3636 RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"
3637 , iface->hw_port, ADPT_ARG(iface));
3638 #endif
3639 }
3640 }
3641 #endif
3642 }
3643
rtw_hal_periodic_tsf_update_chk(_adapter * adapter)3644 void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)
3645 {
3646 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3647
3648 #else
3649 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3650 _adapter *iface;
3651 struct mlme_ext_priv *mlmeext;
3652 int i;
3653 u32 restore_ms = 0;
3654
3655 if (dvobj->periodic_tsf_update_etime) {
3656 if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {
3657 /* end for restore status */
3658 dvobj->periodic_tsf_update_etime = 0;
3659 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3660 }
3661 return;
3662 }
3663
3664 if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)
3665 return;
3666
3667 /*
3668 * all required ifaces can switch to restore status together
3669 * loop all pause iface to get largest restore time required
3670 */
3671 for (i = 0; i < dvobj->iface_nums; i++) {
3672 iface = dvobj->padapters[i];
3673 if (!iface)
3674 continue;
3675
3676 mlmeext = &iface->mlmeextpriv;
3677
3678 if (mlmeext->tsf_update_required
3679 && mlmeext->tsf_update_pause_stime
3680 && rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)
3681 > mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor
3682 ) {
3683 if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)
3684 restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;
3685 }
3686 }
3687
3688 if (!restore_ms)
3689 return;
3690
3691 dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);
3692 if (!dvobj->periodic_tsf_update_etime)
3693 dvobj->periodic_tsf_update_etime++;
3694
3695 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3696
3697 /* set timer to end restore status */
3698 _set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);
3699 #endif
3700 }
3701
rtw_hal_periodic_tsf_update_end_timer_hdl(void * ctx)3702 void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)
3703 {
3704 struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;
3705
3706 if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
3707 return;
3708
3709 rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));
3710 }
3711
hw_var_rcr_config(_adapter * adapter,u32 rcr)3712 static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
3713 {
3714 int err;
3715
3716 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
3717 rcr = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_AMF | RCR_APP_PHYST_RXFF | RCR_APP_MIC | RCR_APP_ICV;
3718 #endif
3719 err = rtw_write32(adapter, REG_RCR, rcr);
3720 if (err == _SUCCESS)
3721 GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
3722 return err;
3723 }
3724
hw_var_rcr_get(_adapter * adapter,u32 * rcr)3725 static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
3726 {
3727 u32 v32;
3728
3729 v32 = rtw_read32(adapter, REG_RCR);
3730 if (rcr)
3731 *rcr = v32;
3732 GET_HAL_DATA(adapter)->ReceiveConfig = v32;
3733 return _SUCCESS;
3734 }
3735
3736 /* only check SW RCR variable */
rtw_hal_rcr_check(_adapter * adapter,u32 check_bit)3737 inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
3738 {
3739 PHAL_DATA_TYPE hal;
3740 u32 rcr;
3741
3742 hal = GET_HAL_DATA(adapter);
3743
3744 rcr = hal->ReceiveConfig;
3745 if ((rcr & check_bit) == check_bit)
3746 return 1;
3747
3748 return 0;
3749 }
3750
rtw_hal_rcr_add(_adapter * adapter,u32 add)3751 inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
3752 {
3753 PHAL_DATA_TYPE hal;
3754 u32 rcr;
3755 u8 ret = _SUCCESS;
3756
3757 hal = GET_HAL_DATA(adapter);
3758
3759 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3760 rcr |= add;
3761 if (rcr != hal->ReceiveConfig)
3762 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3763
3764 return ret;
3765 }
3766
rtw_hal_rcr_clear(_adapter * adapter,u32 clear)3767 inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
3768 {
3769 PHAL_DATA_TYPE hal;
3770 u32 rcr;
3771 u8 ret = _SUCCESS;
3772
3773 hal = GET_HAL_DATA(adapter);
3774
3775 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3776 rcr &= ~clear;
3777 if (rcr != hal->ReceiveConfig)
3778 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3779
3780 return ret;
3781 }
3782
rtw_hal_rcr_set_chk_bssid(_adapter * adapter,u8 self_action)3783 void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
3784 {
3785 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3786 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3787 u32 rcr, rcr_new;
3788 struct mi_state mstate, mstate_s;
3789
3790 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3791 rcr_new = rcr;
3792
3793 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)
3794 rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
3795 #else
3796 rtw_mi_status_no_self(adapter, &mstate);
3797 rtw_mi_status_no_others(adapter, &mstate_s);
3798
3799 /* only adjust parameters interested */
3800 switch (self_action) {
3801 case MLME_SCAN_ENTER:
3802 mstate_s.scan_num = 1;
3803 mstate_s.scan_enter_num = 1;
3804 break;
3805 case MLME_SCAN_DONE:
3806 mstate_s.scan_enter_num = 0;
3807 break;
3808 case MLME_STA_CONNECTING:
3809 mstate_s.lg_sta_num = 1;
3810 mstate_s.ld_sta_num = 0;
3811 break;
3812 case MLME_STA_CONNECTED:
3813 mstate_s.lg_sta_num = 0;
3814 mstate_s.ld_sta_num = 1;
3815 break;
3816 case MLME_STA_DISCONNECTED:
3817 mstate_s.lg_sta_num = 0;
3818 mstate_s.ld_sta_num = 0;
3819 break;
3820 #ifdef CONFIG_TDLS
3821 case MLME_TDLS_LINKED:
3822 mstate_s.ld_tdls_num = 1;
3823 break;
3824 case MLME_TDLS_NOLINK:
3825 mstate_s.ld_tdls_num = 0;
3826 break;
3827 #endif
3828 #ifdef CONFIG_AP_MODE
3829 case MLME_AP_STARTED:
3830 mstate_s.ap_num = 1;
3831 break;
3832 case MLME_AP_STOPPED:
3833 mstate_s.ap_num = 0;
3834 mstate_s.ld_ap_num = 0;
3835 break;
3836 #endif
3837 #ifdef CONFIG_RTW_MESH
3838 case MLME_MESH_STARTED:
3839 mstate_s.mesh_num = 1;
3840 break;
3841 case MLME_MESH_STOPPED:
3842 mstate_s.mesh_num = 0;
3843 mstate_s.ld_mesh_num = 0;
3844 break;
3845 #endif
3846 case MLME_ACTION_NONE:
3847 case MLME_ADHOC_STARTED:
3848 /* caller without effect of decision */
3849 break;
3850 default:
3851 rtw_warn_on(1);
3852 };
3853
3854 rtw_mi_status_merge(&mstate, &mstate_s);
3855
3856 if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
3857 #ifdef CONFIG_FIND_BEST_CHANNEL
3858 || MSTATE_SCAN_ENTER_NUM(&mstate)
3859 #endif
3860 || hal_data->in_cta_test
3861 )
3862 rcr_new &= ~RCR_CBSSID_DATA;
3863 else
3864 rcr_new |= RCR_CBSSID_DATA;
3865
3866 if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)
3867 rcr_new &= ~RCR_CBSSID_BCN;
3868 else if (MSTATE_STA_LG_NUM(&mstate)
3869 || adapter_to_dvobj(adapter)->periodic_tsf_update_etime
3870 )
3871 rcr_new |= RCR_CBSSID_BCN;
3872 else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
3873 || MSTATE_MESH_NUM(&mstate)
3874 )
3875 rcr_new &= ~RCR_CBSSID_BCN;
3876 else
3877 rcr_new |= RCR_CBSSID_BCN;
3878
3879 #ifdef CONFIG_CLIENT_PORT_CFG
3880 if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)
3881 rcr_new &= ~RCR_CBSSID_BCN;
3882 #endif
3883 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
3884
3885 #ifdef CONFIG_RTW_MULTI_AP
3886 if (MSTATE_AP_NUM(&mstate)
3887 && rtw_unassoc_sta_src_chk(adapter, UNASOC_STA_SRC_RX_NMY_UC)
3888 ) {
3889 rcr_new |= RCR_AAP;
3890 } else
3891 rcr_new &= ~RCR_AAP;
3892 #endif
3893
3894 if (rcr == rcr_new)
3895 return;
3896
3897 if (!hal_spec->rx_tsf_filter
3898 && (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))
3899 rtw_hal_tsf_update_pause(adapter);
3900
3901 rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
3902
3903 if (!hal_spec->rx_tsf_filter
3904 && !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)
3905 && self_action != MLME_STA_CONNECTING)
3906 rtw_hal_tsf_update_restore(adapter);
3907 }
3908
rtw_hal_rcr_set_chk_bssid_act_non(_adapter * adapter)3909 void rtw_hal_rcr_set_chk_bssid_act_non(_adapter *adapter)
3910 {
3911 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3912 }
3913
hw_var_set_rcr_am(_adapter * adapter,u8 enable)3914 static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
3915 {
3916 u32 rcr = RCR_AM;
3917
3918 if (enable)
3919 rtw_hal_rcr_add(adapter, rcr);
3920 else
3921 rtw_hal_rcr_clear(adapter, rcr);
3922 }
3923
hw_var_set_bcn_interval(_adapter * adapter,u16 interval)3924 static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)
3925 {
3926 #ifdef CONFIG_SWTIMER_BASED_TXBCN
3927 interval = rtw_hal_bcn_interval_adjust(adapter, interval);
3928 #endif
3929
3930 #ifdef RTW_HALMAC
3931 rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);
3932 #else
3933 rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);
3934 #endif
3935
3936 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3937 {
3938 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3939 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3940
3941 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3942 RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);
3943 rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);
3944 }
3945 }
3946 #endif
3947 }
3948
3949 #if CONFIG_TX_AC_LIFETIME
3950 const char *const _tx_aclt_conf_str[] = {
3951 "DEFAULT",
3952 "AP_M2U",
3953 "MESH",
3954 "INVALID",
3955 };
3956
dump_tx_aclt_force_val(void * sel,struct dvobj_priv * dvobj)3957 void dump_tx_aclt_force_val(void *sel, struct dvobj_priv *dvobj)
3958 {
3959 #define TX_ACLT_FORCE_MSG_LEN 64
3960 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3961 struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3962 char buf[TX_ACLT_FORCE_MSG_LEN];
3963 int cnt = 0;
3964
3965 RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3966 , hal_spec->tx_aclt_unit_factor * 32
3967 , 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3968
3969 RTW_PRINT_SEL(sel, "%-5s %-12s %-12s\n", "en", "vo_vi(us)", "be_bk(us)");
3970 RTW_PRINT_SEL(sel, " 0x%02x %12u %12u\n"
3971 , conf->en
3972 , conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3973 , conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3974 );
3975
3976 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "%5s", conf->en == 0xFF ? "AUTO" : "FORCE");
3977 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3978 goto exit;
3979
3980 if (conf->vo_vi)
3981 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->vo_vi);
3982 else
3983 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");
3984 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3985 goto exit;
3986
3987
3988 if (conf->be_bk)
3989 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->be_bk);
3990 else
3991 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");
3992 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3993 goto exit;
3994
3995 RTW_PRINT_SEL(sel, "%s\n", buf);
3996
3997 exit:
3998 return;
3999 }
4000
rtw_hal_set_tx_aclt_force_val(_adapter * adapter,struct tx_aclt_conf_t * input,u8 arg_num)4001 void rtw_hal_set_tx_aclt_force_val(_adapter *adapter, struct tx_aclt_conf_t *input, u8 arg_num)
4002 {
4003 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4004 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4005 struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
4006
4007 if (arg_num >= 1) {
4008 if (input->en == 0xFF)
4009 conf->en = input->en;
4010 else
4011 conf->en = input->en & 0xF;
4012 }
4013 if (arg_num >= 2) {
4014 conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
4015 if (conf->vo_vi > 0xFFFF)
4016 conf->vo_vi = 0xFFFF;
4017 }
4018 if (arg_num >= 3) {
4019 conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
4020 if (conf->be_bk > 0xFFFF)
4021 conf->be_bk = 0xFFFF;
4022 }
4023 }
4024
dump_tx_aclt_confs(void * sel,struct dvobj_priv * dvobj)4025 void dump_tx_aclt_confs(void *sel, struct dvobj_priv *dvobj)
4026 {
4027 #define TX_ACLT_CONF_MSG_LEN 32
4028 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
4029 struct tx_aclt_conf_t *conf;
4030 char buf[TX_ACLT_CONF_MSG_LEN];
4031 int cnt;
4032 int i;
4033
4034 RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
4035 , hal_spec->tx_aclt_unit_factor * 32
4036 , 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
4037
4038 RTW_PRINT_SEL(sel, "%-7s %-1s %-3s %-9s %-9s %-10s %-10s\n"
4039 , "name", "#", "en", "vo_vi(us)", "be_bk(us)", "vo_vi(reg)", "be_bk(reg)");
4040
4041 for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
4042 conf = &dvobj->tx_aclt_confs[i];
4043 cnt = 0;
4044
4045 if (conf->vo_vi)
4046 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->vo_vi);
4047 else
4048 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
4049 if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
4050 continue;
4051
4052 if (conf->be_bk)
4053 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->be_bk);
4054 else
4055 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
4056 if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
4057 continue;
4058
4059 RTW_PRINT_SEL(sel, "%7s %1u 0x%x %9u %9u%s\n"
4060 , tx_aclt_conf_str(i), i
4061 , conf->en
4062 , conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
4063 , conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
4064 , buf
4065 );
4066 }
4067 }
4068
rtw_hal_set_tx_aclt_conf(_adapter * adapter,u8 conf_idx,struct tx_aclt_conf_t * input,u8 arg_num)4069 void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_conf_t *input, u8 arg_num)
4070 {
4071 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
4072 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4073 struct tx_aclt_conf_t *conf;
4074
4075 if (conf_idx >= TX_ACLT_CONF_NUM)
4076 return;
4077
4078 conf = &dvobj->tx_aclt_confs[conf_idx];
4079
4080 if (arg_num >= 1) {
4081 if (input->en != 0xFF)
4082 conf->en = input->en & 0xF;
4083 }
4084 if (arg_num >= 2) {
4085 conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
4086 if (conf->vo_vi > 0xFFFF)
4087 conf->vo_vi = 0xFFFF;
4088 }
4089 if (arg_num >= 3) {
4090 conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
4091 if (conf->be_bk > 0xFFFF)
4092 conf->be_bk = 0xFFFF;
4093 }
4094 }
4095
rtw_hal_update_tx_aclt(_adapter * adapter)4096 void rtw_hal_update_tx_aclt(_adapter *adapter)
4097 {
4098 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4099 struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter);
4100 u8 lt_en = 0, lt_en_ori;
4101 u16 lt_vo_vi = 0xFFFF, lt_be_bk = 0xFFFF;
4102 u32 lt, lt_ori;
4103 struct tx_aclt_conf_t *conf;
4104 int i;
4105 #ifdef CONFIG_AP_MODE
4106 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
4107 _adapter *iface;
4108 u8 ap_m2u_num = 0;
4109
4110 for (i = 0; i < dvobj->iface_nums; i++) {
4111 iface = dvobj->padapters[i];
4112 if (!iface)
4113 continue;
4114
4115 if (MLME_IS_AP(iface)
4116 && ((iface->b2u_flags_ap_src & RTW_AP_B2U_IP_MCAST)
4117 || (iface->b2u_flags_ap_fwd & RTW_AP_B2U_IP_MCAST))
4118 )
4119 ap_m2u_num++;
4120 }
4121 #endif
4122 #endif /* CONFIG_AP_MODE */
4123
4124 lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN);
4125 lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME);
4126
4127 for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
4128 if (!(dvobj->tx_aclt_flags & BIT(i)))
4129 continue;
4130
4131 conf = &dvobj->tx_aclt_confs[i];
4132
4133 if (i == TX_ACLT_CONF_DEFAULT) {
4134 /* first and default status, assign directly */
4135 lt_en = conf->en;
4136 if (conf->vo_vi)
4137 lt_vo_vi = conf->vo_vi;
4138 if (conf->be_bk)
4139 lt_be_bk = conf->be_bk;
4140 }
4141 #ifdef CONFIG_AP_MODE
4142 #if CONFIG_RTW_AP_DATA_BMC_TO_UC || defined(CONFIG_RTW_MESH)
4143 else if (0
4144 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
4145 || (i == TX_ACLT_CONF_AP_M2U
4146 && ap_m2u_num
4147 && macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */)
4148 #endif
4149 #ifdef CONFIG_RTW_MESH
4150 || (i == TX_ACLT_CONF_MESH
4151 && macid_ctl->op_num[H2C_MSR_ROLE_MESH] > 1 /* implies only 1 MESH mode supported */)
4152 #endif
4153 ) {
4154 /* long term status, OR en and MIN lifetime */
4155 lt_en |= conf->en;
4156 if (conf->vo_vi && lt_vo_vi > conf->vo_vi)
4157 lt_vo_vi = conf->vo_vi;
4158 if (conf->be_bk && lt_be_bk > conf->be_bk)
4159 lt_be_bk = conf->be_bk;
4160 }
4161 #endif
4162 #endif /* CONFIG_AP_MODE */
4163 }
4164
4165 if (dvobj->tx_aclt_force_val.en != 0xFF)
4166 lt_en = dvobj->tx_aclt_force_val.en;
4167 if (dvobj->tx_aclt_force_val.vo_vi)
4168 lt_vo_vi = dvobj->tx_aclt_force_val.vo_vi;
4169 if (dvobj->tx_aclt_force_val.be_bk)
4170 lt_be_bk = dvobj->tx_aclt_force_val.be_bk;
4171
4172 lt_en = (lt_en_ori & 0xF0) | (lt_en & 0x0F);
4173 lt = (lt_be_bk << 16) | lt_vo_vi;
4174
4175 if (0)
4176 RTW_INFO("lt_en:0x%x(0x%x), lt:0x%08x(0x%08x)\n", lt_en, lt_en_ori, lt, lt_ori);
4177
4178 if (lt_en != lt_en_ori)
4179 rtw_write8(adapter, REG_LIFETIME_EN, lt_en);
4180 if (lt != lt_ori)
4181 rtw_write32(adapter, REG_PKT_LIFE_TIME, lt);
4182 }
4183 #endif /* CONFIG_TX_AC_LIFETIME */
4184
hw_var_port_switch(_adapter * adapter)4185 void hw_var_port_switch(_adapter *adapter)
4186 {
4187 #ifdef CONFIG_CONCURRENT_MODE
4188 #ifdef CONFIG_RUNTIME_PORT_SWITCH
4189 /*
4190 0x102: MSR
4191 0x550: REG_BCN_CTRL
4192 0x551: REG_BCN_CTRL_1
4193 0x55A: REG_ATIMWND
4194 0x560: REG_TSFTR
4195 0x568: REG_TSFTR1
4196 0x570: REG_ATIMWND_1
4197 0x610: REG_MACID
4198 0x618: REG_BSSID
4199 0x700: REG_MACID1
4200 0x708: REG_BSSID1
4201 */
4202
4203 int i;
4204 u8 msr;
4205 u8 bcn_ctrl;
4206 u8 bcn_ctrl_1;
4207 u8 atimwnd[2];
4208 u8 atimwnd_1[2];
4209 u8 tsftr[8];
4210 u8 tsftr_1[8];
4211 u8 macid[6];
4212 u8 bssid[6];
4213 u8 macid_1[6];
4214 u8 bssid_1[6];
4215 #if defined(CONFIG_RTL8192F)
4216 u16 wlan_act_mask_ctrl = 0;
4217 u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;
4218 #endif
4219
4220 u8 hw_port;
4221 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4222 _adapter *iface = NULL;
4223
4224 msr = rtw_read8(adapter, MSR);
4225 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4226 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4227 #if defined(CONFIG_RTL8192F)
4228 wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4229 #endif
4230
4231 for (i = 0; i < 2; i++)
4232 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4233 for (i = 0; i < 2; i++)
4234 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4235
4236 for (i = 0; i < 8; i++)
4237 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4238 for (i = 0; i < 8; i++)
4239 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4240
4241 for (i = 0; i < 6; i++)
4242 macid[i] = rtw_read8(adapter, REG_MACID + i);
4243
4244 for (i = 0; i < 6; i++)
4245 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4246
4247 for (i = 0; i < 6; i++)
4248 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4249
4250 for (i = 0; i < 6; i++)
4251 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4252
4253 #ifdef DBG_RUNTIME_PORT_SWITCH
4254 RTW_INFO(FUNC_ADPT_FMT" before switch\n"
4255 "msr:0x%02x\n"
4256 "bcn_ctrl:0x%02x\n"
4257 "bcn_ctrl_1:0x%02x\n"
4258 #if defined(CONFIG_RTL8192F)
4259 "wlan_act_mask_ctrl:0x%02x\n"
4260 #endif
4261 "atimwnd:0x%04x\n"
4262 "atimwnd_1:0x%04x\n"
4263 "tsftr:%llu\n"
4264 "tsftr1:%llu\n"
4265 "macid:"MAC_FMT"\n"
4266 "bssid:"MAC_FMT"\n"
4267 "macid_1:"MAC_FMT"\n"
4268 "bssid_1:"MAC_FMT"\n"
4269 , FUNC_ADPT_ARG(adapter)
4270 , msr
4271 , bcn_ctrl
4272 , bcn_ctrl_1
4273 #if defined(CONFIG_RTL8192F)
4274 , wlan_act_mask_ctrl
4275 #endif
4276 , *((u16 *)atimwnd)
4277 , *((u16 *)atimwnd_1)
4278 , *((u64 *)tsftr)
4279 , *((u64 *)tsftr_1)
4280 , MAC_ARG(macid)
4281 , MAC_ARG(bssid)
4282 , MAC_ARG(macid_1)
4283 , MAC_ARG(bssid_1)
4284 );
4285 #endif /* DBG_RUNTIME_PORT_SWITCH */
4286
4287 /* disable bcn function, disable update TSF */
4288 rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4289 rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4290
4291 #if defined(CONFIG_RTL8192F)
4292 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);
4293 #endif
4294
4295 /* switch msr */
4296 msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
4297 rtw_write8(adapter, MSR, msr);
4298
4299 /* write port0 */
4300 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
4301 for (i = 0; i < 2; i++)
4302 rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
4303 for (i = 0; i < 8; i++)
4304 rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
4305 for (i = 0; i < 6; i++)
4306 rtw_write8(adapter, REG_MACID + i, macid_1[i]);
4307 for (i = 0; i < 6; i++)
4308 rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
4309
4310 /* write port1 */
4311 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
4312 for (i = 0; i < 2; i++)
4313 rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
4314 for (i = 0; i < 8; i++)
4315 rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
4316 for (i = 0; i < 6; i++)
4317 rtw_write8(adapter, REG_MACID1 + i, macid[i]);
4318 for (i = 0; i < 6; i++)
4319 rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
4320
4321 /* write bcn ctl */
4322 #ifdef CONFIG_BT_COEXIST
4323 /* always enable port0 beacon function for PSTDMA */
4324 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
4325 || IS_HARDWARE_TYPE_8723D(adapter))
4326 bcn_ctrl_1 |= EN_BCN_FUNCTION;
4327 /* always disable port1 beacon function for PSTDMA */
4328 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
4329 bcn_ctrl &= ~EN_BCN_FUNCTION;
4330 #endif
4331 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
4332 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
4333
4334 #if defined(CONFIG_RTL8192F)
4335 /* if the setting of port0 and port1 are the same, it does not need to switch port setting*/
4336 if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)
4337 != (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))
4338 wlan_act_mask_ctrl ^= en_port_mask;
4339 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);
4340 #endif
4341
4342 if (adapter->iface_id == IFACE_ID0)
4343 iface = dvobj->padapters[IFACE_ID1];
4344 else if (adapter->iface_id == IFACE_ID1)
4345 iface = dvobj->padapters[IFACE_ID0];
4346
4347
4348 if (adapter->hw_port == HW_PORT0) {
4349 adapter->hw_port = HW_PORT1;
4350 iface->hw_port = HW_PORT0;
4351 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4352 ADPT_ARG(iface), ADPT_ARG(adapter));
4353 } else {
4354 adapter->hw_port = HW_PORT0;
4355 iface->hw_port = HW_PORT1;
4356 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4357 ADPT_ARG(adapter), ADPT_ARG(iface));
4358 }
4359
4360 #ifdef DBG_RUNTIME_PORT_SWITCH
4361 msr = rtw_read8(adapter, MSR);
4362 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4363 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4364 #if defined(CONFIG_RTL8192F)
4365 wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4366 #endif
4367
4368 for (i = 0; i < 2; i++)
4369 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4370 for (i = 0; i < 2; i++)
4371 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4372
4373 for (i = 0; i < 8; i++)
4374 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4375 for (i = 0; i < 8; i++)
4376 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4377
4378 for (i = 0; i < 6; i++)
4379 macid[i] = rtw_read8(adapter, REG_MACID + i);
4380
4381 for (i = 0; i < 6; i++)
4382 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4383
4384 for (i = 0; i < 6; i++)
4385 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4386
4387 for (i = 0; i < 6; i++)
4388 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4389
4390 RTW_INFO(FUNC_ADPT_FMT" after switch\n"
4391 "msr:0x%02x\n"
4392 "bcn_ctrl:0x%02x\n"
4393 "bcn_ctrl_1:0x%02x\n"
4394 #if defined(CONFIG_RTL8192F)
4395 "wlan_act_mask_ctrl:0x%02x\n"
4396 #endif
4397 "atimwnd:%u\n"
4398 "atimwnd_1:%u\n"
4399 "tsftr:%llu\n"
4400 "tsftr1:%llu\n"
4401 "macid:"MAC_FMT"\n"
4402 "bssid:"MAC_FMT"\n"
4403 "macid_1:"MAC_FMT"\n"
4404 "bssid_1:"MAC_FMT"\n"
4405 , FUNC_ADPT_ARG(adapter)
4406 , msr
4407 , bcn_ctrl
4408 , bcn_ctrl_1
4409 #if defined(CONFIG_RTL8192F)
4410 , wlan_act_mask_ctrl
4411 #endif
4412 , *((u16 *)atimwnd)
4413 , *((u16 *)atimwnd_1)
4414 , *((u64 *)tsftr)
4415 , *((u64 *)tsftr_1)
4416 , MAC_ARG(macid)
4417 , MAC_ARG(bssid)
4418 , MAC_ARG(macid_1)
4419 , MAC_ARG(bssid_1)
4420 );
4421 #endif /* DBG_RUNTIME_PORT_SWITCH */
4422
4423 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
4424 #endif /* CONFIG_CONCURRENT_MODE */
4425 }
4426
4427 const char *const _h2c_msr_role_str[] = {
4428 "RSVD",
4429 "STA",
4430 "AP",
4431 "GC",
4432 "GO",
4433 "TDLS",
4434 "ADHOC",
4435 "MESH",
4436 "INVALID",
4437 };
4438
4439 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_default_port_id_cmd(_adapter * adapter,u8 mac_id)4440 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
4441 {
4442 s32 ret = _SUCCESS;
4443 u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
4444 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4445 u8 port_id = rtw_hal_get_port(adapter);
4446
4447 if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))
4448 return ret;
4449
4450 SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);
4451 SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
4452
4453 RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
4454 RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",
4455 __func__, ADPT_ARG(adapter), port_id, mac_id);
4456
4457 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
4458 dvobj->dft.port_id = port_id;
4459 dvobj->dft.mac_id = mac_id;
4460
4461 return ret;
4462 }
rtw_set_default_port_id(_adapter * adapter)4463 s32 rtw_set_default_port_id(_adapter *adapter)
4464 {
4465 s32 ret = _SUCCESS;
4466 struct sta_info *psta;
4467 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4468
4469 if (is_client_associated_to_ap(adapter)) {
4470 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
4471 if (psta)
4472 ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
4473 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
4474
4475 } else {
4476 }
4477
4478 return ret;
4479 }
rtw_set_ps_rsvd_page(_adapter * adapter)4480 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
4481 {
4482 s32 ret = _SUCCESS;
4483 u16 media_status_rpt = RT_MEDIA_CONNECT;
4484 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4485
4486 if (adapter->iface_id == pwrctl->fw_psmode_iface_id)
4487 return ret;
4488
4489 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
4490 (u8 *)&media_status_rpt);
4491
4492 return ret;
4493 }
4494
4495 #if 0
4496 _adapter * _rtw_search_dp_iface(_adapter *adapter)
4497 {
4498 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4499 _adapter *iface;
4500 _adapter *target_iface = NULL;
4501 int i;
4502 u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;
4503 u8 p2p_go_num = 0, p2p_gc_num = 0;
4504 _adapter *sta_ifs[8];
4505 _adapter *ap_ifs[8];
4506 _adapter *mesh_ifs[8];
4507 _adapter *gc_ifs[8];
4508 _adapter *go_ifs[8];
4509
4510 for (i = 0; i < dvobj->iface_nums; i++) {
4511 iface = dvobj->padapters[i];
4512
4513 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
4514 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4515 sta_ifs[sta_num++] = iface;
4516
4517 #ifdef CONFIG_TDLS
4518 if (iface->tdlsinfo.link_established == _TRUE)
4519 tdls_num++;
4520 #endif
4521 #ifdef CONFIG_P2P
4522 if (MLME_IS_GC(iface))
4523 gc_ifs[p2p_gc_num++] = iface;
4524 #endif
4525 }
4526 #ifdef CONFIG_AP_MODE
4527 } else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
4528 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4529 ap_ifs[ap_num++] = iface;
4530 #ifdef CONFIG_P2P
4531 if (MLME_IS_GO(iface))
4532 go_ifs[p2p_go_num++] = iface;
4533 #endif
4534 }
4535 #endif
4536 } else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
4537 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4538 ) {
4539 adhoc_num++;
4540
4541 #ifdef CONFIG_RTW_MESH
4542 } else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
4543 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4544 ) {
4545 mesh_ifs[mesh_num++] = iface;
4546 #endif
4547 }
4548 }
4549
4550 if (p2p_gc_num) {
4551 target_iface = gc_ifs[0];
4552 }
4553 else if (sta_num) {
4554 if(sta_num == 1) {
4555 target_iface = sta_ifs[0];
4556 } else if (sta_num >= 2) {
4557 /*TODO get target_iface by timestamp*/
4558 target_iface = sta_ifs[0];
4559 }
4560 } else if (ap_num) {
4561 target_iface = ap_ifs[0];
4562 }
4563
4564 RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);
4565 RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);
4566 RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);
4567 RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);
4568 RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);
4569 RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);
4570 RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);
4571
4572 if (target_iface)
4573 RTW_INFO("%s => target_iface ("ADPT_FMT")\n",
4574 __func__, ADPT_ARG(target_iface));
4575 else
4576 RTW_INFO("%s => target_iface NULL\n", __func__);
4577
4578 return target_iface;
4579 }
4580
4581 void rtw_search_default_port(_adapter *adapter)
4582 {
4583 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4584 _adapter *adp_iface = NULL;
4585 #ifdef CONFIG_WOWLAN
4586 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
4587
4588 if (pwrpriv->wowlan_mode == _TRUE) {
4589 adp_iface = adapter;
4590 goto exit;
4591 }
4592 #endif
4593 adp_iface = _rtw_search_dp_iface(adapter);
4594
4595 exit :
4596 if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))
4597 rtw_set_default_port_id(adp_iface);
4598 else
4599 rtw_hal_set_default_port_id_cmd(adapter, 0);
4600
4601 if (1) {
4602 _adapter *tmp_adp;
4603
4604 tmp_adp = (adp_iface) ? adp_iface : adapter;
4605
4606 RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",
4607 __func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));
4608 }
4609 }
4610 #endif
4611 #endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/
4612
4613 #ifdef CONFIG_P2P_PS
4614 #ifdef RTW_HALMAC
rtw_set_p2p_ps_offload_cmd(_adapter * adapter,u8 p2p_ps_state)4615 void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
4616 {
4617 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4618 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4619 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4620 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4621 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
4622 struct sta_priv *pstapriv = &adapter->stapriv;
4623 struct sta_info *psta;
4624 HAL_P2P_PS_PARA p2p_ps_para;
4625 int status = -1;
4626 u8 i;
4627 u8 hw_port = rtw_hal_get_port(adapter);
4628
4629 _rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
4630 _rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
4631
4632 (&p2p_ps_para)->p2p_port_id = hw_port;
4633 (&p2p_ps_para)->p2p_group = 0;
4634 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
4635 if (psta) {
4636 (&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
4637 } else {
4638 if (p2p_ps_state != P2P_PS_DISABLE) {
4639 RTW_ERR("%s , psta was NULL\n", __func__);
4640 return;
4641 }
4642 }
4643
4644
4645 switch (p2p_ps_state) {
4646 case P2P_PS_DISABLE:
4647 RTW_INFO("P2P_PS_DISABLE\n");
4648 _rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
4649 break;
4650
4651 case P2P_PS_ENABLE:
4652 RTW_INFO("P2P_PS_ENABLE\n");
4653 /* update CTWindow value. */
4654 if (pwdinfo->ctwindow > 0) {
4655 (&p2p_ps_para)->ctwindow_en = 1;
4656 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4657 /*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
4658 }
4659
4660
4661 if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
4662 (&p2p_ps_para)->offload_en = 1;
4663 if (pwdinfo->role == P2P_ROLE_GO) {
4664 (&p2p_ps_para)->role = 1;
4665 (&p2p_ps_para)->all_sta_sleep = 0;
4666 } else
4667 (&p2p_ps_para)->role = 0;
4668
4669 (&p2p_ps_para)->discovery = 0;
4670 }
4671 /* hw only support 2 set of NoA */
4672 for (i = 0; i < pwdinfo->noa_num; i++) {
4673 /* To control the register setting for which NOA */
4674 (&p2p_ps_para)->noa_sel = i;
4675 (&p2p_ps_para)->noa_en = 1;
4676 (&p2p_ps_para)->disable_close_rf = 0;
4677 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
4678 #ifdef CONFIG_CONCURRENT_MODE
4679 if (rtw_mi_buddy_check_fwstate(adapter, WIFI_ASOC_STATE))
4680 #endif /* CONFIG_CONCURRENT_MODE */
4681 (&p2p_ps_para)->disable_close_rf = 1;
4682 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
4683 /* config P2P NoA Descriptor Register */
4684 /* config NOA duration */
4685 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
4686 /* config NOA interval */
4687 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
4688 /* config NOA start time */
4689 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
4690 /* config NOA count */
4691 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
4692 /*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
4693 (&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
4694 (&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
4695 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4696 if (status == -1)
4697 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4698 }
4699
4700 break;
4701
4702 case P2P_PS_SCAN:
4703 /*This feature FW not ready 20161116 YiWei*/
4704 return;
4705 /*
4706 RTW_INFO("P2P_PS_SCAN\n");
4707 (&p2p_ps_para)->discovery = 1;
4708 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4709 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4710 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4711 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4712 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4713 */
4714 break;
4715
4716 case P2P_PS_SCAN_DONE:
4717 /*This feature FW not ready 20161116 YiWei*/
4718 return;
4719 /*
4720 RTW_INFO("P2P_PS_SCAN_DONE\n");
4721 (&p2p_ps_para)->discovery = 0;
4722 pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
4723 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4724 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4725 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4726 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4727 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4728 */
4729 break;
4730
4731 default:
4732 break;
4733 }
4734
4735 if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
4736 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4737 if (status == -1)
4738 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4739 }
4740 _rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
4741
4742 }
4743 #endif /* RTW_HALMAC */
4744 #endif /* CONFIG_P2P */
4745
4746 /*
4747 * rtw_hal_set_FwMediaStatusRpt_cmd -
4748 *
4749 * @adapter:
4750 * @opmode: 0:disconnect, 1:connect
4751 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
4752 * @miracast_sink: 0:source. 1:sink
4753 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
4754 * @macid:
4755 * @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end
4756 * @macid_end:
4757 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)4758 s32 rtw_hal_set_FwMediaStatusRpt_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, bool macid_ind, u8 macid_end)
4759 {
4760 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
4761 u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
4762 int i;
4763 s32 ret;
4764 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4765 u8 hw_port = rtw_hal_get_port(adapter);
4766 #endif
4767 u8 op_num_change_bmp = 0;
4768
4769 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
4770 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
4771 SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
4772 SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
4773 SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
4774 SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
4775 SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
4776 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4777 SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);
4778 #endif
4779 RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
4780
4781 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
4782 if (ret != _SUCCESS)
4783 goto exit;
4784
4785 #if defined(CONFIG_RTL8188E)
4786 if (rtw_get_chip_type(adapter) == RTL8188E) {
4787 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4788
4789 /* 8188E FW doesn't set macid no link, driver does it by self */
4790 if (opmode)
4791 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
4792 else
4793 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
4794
4795 /* for 8188E RA */
4796 #if (RATE_ADAPTIVE_SUPPORT == 1)
4797 if (hal_data->fw_ractrl == _FALSE) {
4798 u8 max_macid;
4799
4800 max_macid = rtw_search_max_mac_id(adapter);
4801 rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
4802 }
4803 #endif
4804 }
4805 #endif
4806
4807 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
4808 /* TODO: this should move to IOT issue area */
4809 if (rtw_get_chip_type(adapter) == RTL8812
4810 || rtw_get_chip_type(adapter) == RTL8821
4811 ) {
4812 if (MLME_IS_STA(adapter))
4813 Hal_PatchwithJaguar_8812(adapter, opmode);
4814 }
4815 #endif
4816
4817 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
4818 if (macid_ind == 0)
4819 macid_end = macid;
4820
4821 for (i = macid; macid <= macid_end; macid++) {
4822 op_num_change_bmp |= rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
4823 if (!opmode) {
4824 rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
4825 rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
4826 rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
4827 rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
4828 }
4829 }
4830
4831 #if CONFIG_TX_AC_LIFETIME
4832 if (op_num_change_bmp)
4833 rtw_hal_update_tx_aclt(adapter);
4834 #endif
4835
4836 if (!opmode)
4837 rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
4838
4839 exit:
4840 return ret;
4841 }
4842
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)4843 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
4844 {
4845 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
4846 }
4847
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)4848 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
4849 {
4850 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
4851 }
4852
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4853 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4854 {
4855 u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
4856 u8 ret = 0;
4857
4858 RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
4859 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
4860 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
4861 rsvdpageloc->LocBTQosNull);
4862
4863 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
4864 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
4865 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
4866 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
4867 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
4868
4869 ret = rtw_hal_fill_h2c_cmd(padapter,
4870 H2C_RSVD_PAGE,
4871 H2C_RSVDPAGE_LOC_LEN,
4872 u1H2CRsvdPageParm);
4873
4874 }
4875
4876 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)4877 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
4878 {
4879 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4880
4881 if (IS_8723D_SERIES(pHalData->version_id) || IS_8192F_SERIES(pHalData->version_id)
4882 || IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id)
4883 || IS_8822C_SERIES(pHalData->version_id))
4884 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4885 /*
4886 * Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
4887 * It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
4888 * and implement HAL function.
4889 * TODO: GPIO_8 multi function?
4890 */
4891
4892 if ((index == 13 || index == 14)
4893 #if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
4894 /* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
4895 && (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
4896 #endif
4897 )
4898 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4899 }
4900
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)4901 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
4902 {
4903 #if defined(CONFIG_RTL8192F)
4904 rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&outputval));
4905 #else
4906 if (index <= 7) {
4907 /* config GPIO mode */
4908 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4909 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4910
4911 /* config GPIO Sel */
4912 /* 0: input */
4913 /* 1: output */
4914 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4915 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
4916
4917 /* set output value */
4918 if (outputval) {
4919 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4920 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
4921 } else {
4922 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4923 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
4924 }
4925 } else if (index <= 15) {
4926 /* 88C Series: */
4927 /* index: 11~8 transform to 3~0 */
4928 /* 8723 Series: */
4929 /* index: 12~8 transform to 4~0 */
4930
4931 index -= 8;
4932
4933 /* config GPIO mode */
4934 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4935 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4936
4937 /* config GPIO Sel */
4938 /* 0: input */
4939 /* 1: output */
4940 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4941 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
4942
4943 /* set output value */
4944 if (outputval) {
4945 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4946 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
4947 } else {
4948 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4949 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
4950 }
4951 } else {
4952 RTW_INFO("%s: invalid GPIO%d=%d\n",
4953 __FUNCTION__, index, outputval);
4954 }
4955 #endif
4956 }
rtw_hal_set_input_gpio(_adapter * padapter,u8 index)4957 void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
4958 {
4959 #if defined(CONFIG_RTL8192F)
4960 rtw_hal_set_hwreg(padapter, HW_VAR_WOW_INPUT_GPIO, (u8 *)(&index));
4961 #else
4962 if (index <= 7) {
4963 /* config GPIO mode */
4964 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4965 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4966
4967 /* config GPIO Sel */
4968 /* 0: input */
4969 /* 1: output */
4970 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4971 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
4972
4973 } else if (index <= 15) {
4974 /* 88C Series: */
4975 /* index: 11~8 transform to 3~0 */
4976 /* 8723 Series: */
4977 /* index: 12~8 transform to 4~0 */
4978
4979 index -= 8;
4980
4981 /* config GPIO mode */
4982 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4983 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4984
4985 /* config GPIO Sel */
4986 /* 0: input */
4987 /* 1: output */
4988 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4989 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
4990 } else
4991 RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
4992 #endif
4993 }
4994
4995 #endif
4996
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4997 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4998 {
4999 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
5000 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5001 u8 ret = 0;
5002 #ifdef CONFIG_WOWLAN
5003 u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
5004
5005 RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
5006 __func__, rsvdpageloc->LocRemoteCtrlInfo,
5007 rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
5008 rsvdpageloc->LocNDPInfo);
5009 RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
5010 __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
5011 rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
5012
5013 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
5014 SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
5015 SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
5016 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
5017 rsvdpageloc->LocNbrAdv);
5018 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
5019 rsvdpageloc->LocNDPInfo);
5020 #ifdef CONFIG_GTK_OL
5021 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
5022 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
5023 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
5024 #endif /* CONFIG_GTK_OL */
5025 ret = rtw_hal_fill_h2c_cmd(padapter,
5026 H2C_AOAC_RSVD_PAGE,
5027 H2C_AOAC_RSVDPAGE_LOC_LEN,
5028 u1H2CAoacRsvdPageParm);
5029
5030 RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
5031 _rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
5032 SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
5033 rsvdpageloc->LocAOACReport);
5034 ret = rtw_hal_fill_h2c_cmd(padapter,
5035 H2C_AOAC_RSVDPAGE3,
5036 H2C_AOAC_RSVDPAGE_LOC_LEN,
5037 u1H2CAoacRsvdPageParm);
5038 pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
5039 }
5040 #ifdef CONFIG_PNO_SUPPORT
5041 else {
5042
5043 if (!pwrpriv->wowlan_in_resume) {
5044 RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
5045 _rtw_memset(&u1H2CAoacRsvdPageParm, 0,
5046 sizeof(u1H2CAoacRsvdPageParm));
5047 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
5048 rsvdpageloc->LocPNOInfo);
5049 ret = rtw_hal_fill_h2c_cmd(padapter,
5050 H2C_AOAC_RSVDPAGE3,
5051 H2C_AOAC_RSVDPAGE_LOC_LEN,
5052 u1H2CAoacRsvdPageParm);
5053 }
5054 }
5055 #endif /* CONFIG_PNO_SUPPORT */
5056 #endif /* CONFIG_WOWLAN */
5057 }
5058
5059 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)5060 void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
5061 {
5062 struct hal_ops *pHalFunc = &padapter->hal_func;
5063 u8 u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};
5064 u8 ret = 0;
5065
5066
5067 RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);
5068
5069 SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);
5070 SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);
5071 ret = rtw_hal_fill_h2c_cmd(padapter,
5072 H2C_FW_DBG_MSG_PKT,
5073 H2C_FW_DBG_MSG_PKT_LEN,
5074 u1H2C_fw_dbg_msg_pkt_parm);
5075
5076 }
5077 #endif /*DBG_FW_DEBUG_MSG_PKT*/
5078
5079 /*#define DBG_GET_RSVD_PAGE*/
rtw_hal_get_rsvd_page(_adapter * adapter,u32 page_offset,u32 page_num,u8 * buffer,u32 buffer_size)5080 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
5081 u32 page_num, u8 *buffer, u32 buffer_size)
5082 {
5083 u32 addr = 0, size = 0, count = 0;
5084 u32 page_size = 0, data_low = 0, data_high = 0;
5085 u16 txbndy = 0, offset = 0;
5086 u8 i = 0;
5087 bool rst = _FALSE;
5088
5089 #ifdef DBG_LA_MODE
5090 struct registry_priv *registry_par = &adapter->registrypriv;
5091
5092 if(registry_par->la_mode_en == 1) {
5093 RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);
5094 return rst;
5095 }
5096 #endif
5097 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5098
5099 addr = page_offset * page_size;
5100 size = page_num * page_size;
5101
5102 if (buffer_size < size) {
5103 RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
5104 __func__, buffer_size, size);
5105 return rst;
5106 }
5107 #ifdef RTW_HALMAC
5108 if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
5109 rst = _FALSE;
5110 else
5111 rst = _TRUE;
5112 #else
5113 txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
5114
5115 offset = (txbndy + page_offset) * page_size / 8;
5116 count = (buffer_size / 8) + 1;
5117
5118 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
5119
5120 for (i = 0 ; i < count ; i++) {
5121 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
5122 data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
5123 data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
5124 _rtw_memcpy(buffer + (i * 8),
5125 &data_low, sizeof(data_low));
5126 _rtw_memcpy(buffer + ((i * 8) + 4),
5127 &data_high, sizeof(data_high));
5128 }
5129 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
5130 rst = _TRUE;
5131 #endif /*RTW_HALMAC*/
5132
5133 #ifdef DBG_GET_RSVD_PAGE
5134 RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
5135 __func__, page_offset, page_num, addr, size);
5136 RTW_INFO_DUMP("\n", buffer, size);
5137 RTW_INFO(" ==================================================\n");
5138 #endif
5139 return rst;
5140 }
5141
rtw_dump_rsvd_page(void * sel,_adapter * adapter,u8 page_offset,u8 page_num)5142 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
5143 {
5144 #if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG)
5145 u32 page_size = 0;
5146 u8 *buffer = NULL;
5147 u32 buf_size = 0;
5148
5149 if (page_num == 0)
5150 return;
5151
5152 RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");
5153 RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
5154
5155 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5156 if (page_size) {
5157 buf_size = page_size * page_num;
5158 buffer = rtw_zvmalloc(buf_size);
5159
5160 if (buffer) {
5161 rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
5162 RTW_DUMP_SEL(sel, buffer, buf_size);
5163 rtw_vmfree(buffer, buf_size);
5164 } else
5165 RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
5166 } else
5167 RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
5168
5169 RTW_PRINT_SEL(sel, "==========================\n");
5170 #endif
5171 }
5172
5173 #ifdef CONFIG_SUPPORT_FIFO_DUMP
rtw_dump_fifo(void * sel,_adapter * adapter,u8 fifo_sel,u32 fifo_addr,u32 fifo_size)5174 void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
5175 {
5176 u8 *buffer = NULL;
5177 u32 buff_size = 0;
5178 static const char * const fifo_sel_str[] = {
5179 "TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
5180 };
5181
5182 if (fifo_sel > 5) {
5183 RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
5184 return;
5185 }
5186
5187 RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
5188 RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
5189
5190 if (fifo_size) {
5191 buff_size = RND4(fifo_size);
5192 buffer = rtw_zvmalloc(buff_size);
5193 if (buffer == NULL)
5194 buff_size = 0;
5195 }
5196
5197 rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
5198
5199 if (buffer) {
5200 RTW_DUMP_SEL(sel, buffer, fifo_size);
5201 rtw_vmfree(buffer, buff_size);
5202 }
5203
5204 RTW_PRINT_SEL(sel, "==========================\n");
5205 }
5206 #endif
5207
5208 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)5209 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
5210 {
5211 RTW_INFO("%s: Set 0x690=0x00\n", __func__);
5212 rtw_write8(adapter, REG_WOW_CTRL,
5213 (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
5214 RTW_PRINT("%s: Release RXDMA\n", __func__);
5215 rtw_write32(adapter, REG_RXPKT_NUM,
5216 (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
5217 }
5218 #if defined(CONFIG_RTL8188E)
rtw_hal_disable_tx_report(_adapter * adapter)5219 static void rtw_hal_disable_tx_report(_adapter *adapter)
5220 {
5221 rtw_write8(adapter, REG_TX_RPT_CTRL,
5222 ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
5223 RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5224 }
5225
rtw_hal_enable_tx_report(_adapter * adapter)5226 static void rtw_hal_enable_tx_report(_adapter *adapter)
5227 {
5228 rtw_write8(adapter, REG_TX_RPT_CTRL,
5229 ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
5230 RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5231 }
5232 #endif
rtw_hal_release_rx_dma(_adapter * adapter)5233 static void rtw_hal_release_rx_dma(_adapter *adapter)
5234 {
5235 u32 val32 = 0;
5236
5237 val32 = rtw_read32(adapter, REG_RXPKT_NUM);
5238
5239 rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
5240
5241 RTW_INFO("%s, [0x%04x]: 0x%08x\n",
5242 __func__, REG_RXPKT_NUM, (u32)(val32 & (~RW_RELEASE_EN)));
5243 }
5244
rtw_hal_pause_rx_dma(_adapter * adapter)5245 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
5246 {
5247 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
5248 u8 ret = 0;
5249 s8 trycnt = 100;
5250 u32 tmp = 0;
5251 int res = 0;
5252 /* RX DMA stop */
5253 RTW_PRINT("Pause DMA\n");
5254 rtw_write32(adapter, REG_RXPKT_NUM,
5255 (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
5256 do {
5257 if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
5258 #ifdef CONFIG_USB_HCI
5259 /* stop interface before leave */
5260 if (_TRUE == hal->usb_intf_start) {
5261 rtw_intf_stop(adapter);
5262 RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
5263 RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
5264 }
5265 #endif /* CONFIG_USB_HCI */
5266
5267 RTW_PRINT("RX_DMA_IDLE is true\n");
5268 ret = _SUCCESS;
5269 break;
5270 }
5271 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5272 else {
5273 res = RecvOnePkt(adapter);
5274 RTW_PRINT("RecvOnePkt Result: %d\n", res);
5275 }
5276 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
5277
5278 #ifdef CONFIG_USB_HCI
5279 else {
5280 /* to avoid interface start repeatedly */
5281 if (_FALSE == hal->usb_intf_start)
5282 rtw_intf_start(adapter);
5283 }
5284 #endif /* CONFIG_USB_HCI */
5285 } while (trycnt--);
5286
5287 if (trycnt < 0) {
5288 tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
5289
5290 RTW_PRINT("Stop RX DMA failed......\n");
5291 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
5292 RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
5293 __func__, rtw_read16(adapter, REG_RXPKTNUM));
5294 #else
5295 RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
5296 __func__, ((tmp & 0xFF00) >> 8));
5297 #endif
5298 if (tmp & BIT(3))
5299 RTW_PRINT("%s, RX DMA has req\n",
5300 __func__);
5301 else
5302 RTW_PRINT("%s, RX DMA no req\n",
5303 __func__);
5304 ret = _FAIL;
5305 }
5306
5307 return ret;
5308 }
5309
5310 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5311 #ifndef RTW_HALMAC
rtw_hal_enable_cpwm2(_adapter * adapter)5312 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
5313 {
5314 u8 ret = 0;
5315 int res = 0;
5316 u32 tmp = 0;
5317 #ifdef CONFIG_GPIO_WAKEUP
5318 return _SUCCESS;
5319 #else
5320 RTW_PRINT("%s\n", __func__);
5321
5322 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5323 if (!res)
5324 RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
5325 else
5326 RTW_INFO("sdio_local_read fail\n");
5327
5328 tmp = SDIO_HIMR_CPWM2_MSK;
5329
5330 res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5331
5332 if (!res) {
5333 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5334 RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
5335 ret = _SUCCESS;
5336 } else {
5337 RTW_INFO("sdio_local_write fail\n");
5338 ret = _FAIL;
5339 }
5340 return ret;
5341 #endif /* CONFIG_CPIO_WAKEUP */
5342 }
5343 #endif
5344 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
5345 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
5346
5347 #ifdef CONFIG_WOWLAN
5348 /*
5349 * rtw_hal_check_wow_ctrl
5350 * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
5351 * If 0x1C7 == 0 (for 3081), WOW enable successful.
5352 * _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
5353 * If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
5354 */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)5355 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
5356 {
5357 u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
5358 u8 mstatus = 0;
5359 u8 reason = 0xFF;
5360 u8 trycnt = 25;
5361 u8 res = _FALSE;
5362
5363 if (IS_HARDWARE_TYPE_JAGUAR2(adapter) || IS_HARDWARE_TYPE_JAGUAR3(adapter)) {
5364 if (chk_type) {
5365 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5366 RTW_INFO("%s reason:0x%02x\n", __func__, reason);
5367
5368 while (reason && trycnt > 1) {
5369 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5370 RTW_PRINT("Loop index: %d :0x%02x\n",
5371 trycnt, reason);
5372 trycnt--;
5373 rtw_msleep_os(20);
5374 }
5375 if (!reason)
5376 res = _TRUE;
5377 else
5378 res = _FALSE;
5379 } else {
5380 /* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
5381 fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
5382 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
5383 RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
5384
5385 while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
5386 rtw_msleep_os(20);
5387 fe1_imr = rtw_read32(adapter, REG_FE1IMR);
5388 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
5389 RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
5390 trycnt, fe1_imr, rxpkt_num);
5391 trycnt--;
5392 }
5393
5394 if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
5395 res = _FALSE;
5396 else
5397 res = _TRUE;
5398 }
5399 } else {
5400 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5401 RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
5402
5403
5404 if (chk_type) {
5405 while (!(mstatus & BIT1) && trycnt > 1) {
5406 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5407 RTW_PRINT("Loop index: %d :0x%02x\n",
5408 trycnt, mstatus);
5409 trycnt--;
5410 rtw_msleep_os(20);
5411 }
5412 if (mstatus & BIT1)
5413 res = _TRUE;
5414 else
5415 res = _FALSE;
5416 } else {
5417 while (mstatus & BIT1 && trycnt > 1) {
5418 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5419 RTW_PRINT("Loop index: %d :0x%02x\n",
5420 trycnt, mstatus);
5421 trycnt--;
5422 rtw_msleep_os(20);
5423 }
5424
5425 if (mstatus & BIT1)
5426 res = _FALSE;
5427 else
5428 res = _TRUE;
5429 }
5430 }
5431
5432 RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
5433 __func__, chk_type, res, (25 - trycnt));
5434 return res;
5435 }
5436
5437 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_check_pno_enabled(_adapter * adapter)5438 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
5439 {
5440 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5441 u8 res = 0, count = 0;
5442 u8 ret = _FALSE;
5443
5444 if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
5445 res = rtw_read8(adapter, REG_PNO_STATUS);
5446 while (!(res & BIT(7)) && count < 25) {
5447 RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
5448 count, res);
5449 res = rtw_read8(adapter, REG_PNO_STATUS);
5450 count++;
5451 rtw_msleep_os(2);
5452 }
5453 if (res & BIT(7))
5454 ret = _TRUE;
5455 else
5456 ret = _FALSE;
5457 RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
5458 }
5459 return ret;
5460 }
5461 #endif
5462
rtw_hal_backup_rate(_adapter * adapter)5463 static void rtw_hal_backup_rate(_adapter *adapter)
5464 {
5465 RTW_INFO("%s\n", __func__);
5466 /* backup data rate to register 0x8b for wowlan FW */
5467 rtw_write8(adapter, 0x8d, 1);
5468 rtw_write8(adapter, 0x8c, 0);
5469 rtw_write8(adapter, 0x8f, 0x40);
5470 rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
5471 }
5472
5473 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)5474 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
5475 {
5476 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5477 int cam_id, index = 0;
5478 u8 *addr = NULL;
5479
5480 if (!MLME_IS_STA(adapter))
5481 return;
5482
5483 addr = get_bssid(pmlmepriv);
5484
5485 if (addr == NULL) {
5486 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
5487 return;
5488 }
5489
5490 rtw_clean_dk_section(adapter);
5491
5492 do {
5493 cam_id = rtw_camid_search(adapter, addr, index, 1);
5494
5495 if (cam_id == -1)
5496 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
5497 else
5498 rtw_sec_cam_swap(adapter, cam_id, index);
5499
5500 index++;
5501 } while (index < 4);
5502
5503 rtw_write8(adapter, REG_SECCFG, 0xcc);
5504 }
5505
rtw_hal_update_gtk_offload_info(_adapter * adapter)5506 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
5507 {
5508 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5509 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5510 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5511 struct security_priv *psecuritypriv = &adapter->securitypriv;
5512 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5513 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
5514 _irqL irqL;
5515 u8 get_key[16];
5516 u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;
5517 u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
5518
5519 if (!MLME_IS_STA(adapter))
5520 return;
5521
5522 _rtw_memset(get_key, 0, sizeof(get_key));
5523 _rtw_memcpy(&replay_count,
5524 paoac_rpt->replay_counter_eapol_key, 8);
5525
5526 /*read gtk key index*/
5527 gtk_id = paoac_rpt->key_index;
5528 aoac_rpt_ver = paoac_rpt->version_info;
5529
5530 if (aoac_rpt_ver == 0) {
5531 /* initial verison */
5532 if (gtk_id == 5)
5533 has_rekey = _FALSE;
5534 else
5535 has_rekey = _TRUE;
5536 } else if (aoac_rpt_ver >= 1) {
5537 /* Add krack patch */
5538 if (gtk_id == 5)
5539 RTW_WARN("%s FW check iv fail\n", __func__);
5540
5541 if (aoac_rpt_ver == 1)
5542 RTW_WARN("%s aoac report version should be update to v2\n", __func__);
5543
5544 /* Fix key id mismatch */
5545 if (aoac_rpt_ver == 2)
5546 has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;
5547 }
5548
5549 if (has_rekey == _FALSE) {
5550 RTW_INFO("%s no rekey event happened.\n", __func__);
5551 } else if (has_rekey == _TRUE) {
5552 RTW_INFO("%s update security key.\n", __func__);
5553 /*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
5554 rtw_sec_read_cam_ent(adapter, gtk_id,
5555 NULL, NULL, get_key);
5556 rtw_clean_hw_dk_cam(adapter);
5557
5558 if (_rtw_camid_is_gk(adapter, gtk_id)) {
5559 _enter_critical_bh(&cam_ctl->lock, &irqL);
5560 _rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
5561 get_key, 16);
5562 _exit_critical_bh(&cam_ctl->lock, &irqL);
5563 } else {
5564 struct setkey_parm parm_gtk;
5565
5566 parm_gtk.algorithm = paoac_rpt->security_type;
5567 parm_gtk.keyid = gtk_id;
5568 _rtw_memcpy(parm_gtk.key, get_key, 16);
5569 setkey_hdl(adapter, (u8 *)&parm_gtk);
5570 }
5571
5572 /*update key into related sw variable and sec-cam cache*/
5573 psecuritypriv->dot118021XGrpKeyid = gtk_id;
5574 _rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
5575 get_key, 16);
5576 /* update SW TKIP TX/RX MIC value */
5577 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
5578 offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
5579 _rtw_memcpy(
5580 &psecuritypriv->dot118021XGrptxmickey[gtk_id],
5581 &(paoac_rpt->group_key[offset]),
5582 RTW_TKIP_MIC_LEN);
5583
5584 offset = RTW_KEK_LEN;
5585 _rtw_memcpy(
5586 &psecuritypriv->dot118021XGrprxmickey[gtk_id],
5587 &(paoac_rpt->group_key[offset]),
5588 RTW_TKIP_MIC_LEN);
5589 }
5590 RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
5591 KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
5592 }
5593
5594 /* Update broadcast RX IV */
5595 if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
5596 sz = sizeof(psecuritypriv->iv_seq[0]);
5597 for (i = 0 ; i < 4 ; i++) {
5598 _rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
5599 tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
5600 pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
5601 _rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
5602 }
5603 }
5604
5605 rtw_clean_dk_section(adapter);
5606
5607 rtw_write8(adapter, REG_SECCFG, 0x0c);
5608
5609 #ifdef CONFIG_GTK_OL_DBG
5610 /* if (gtk_keyindex != 5) */
5611 dump_sec_cam(RTW_DBGDUMP, adapter);
5612 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
5613 #endif
5614 }
5615 #endif /*CONFIG_GTK_OL*/
5616
rtw_dump_aoac_rpt(_adapter * adapter)5617 static void rtw_dump_aoac_rpt(_adapter *adapter)
5618 {
5619 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5620 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5621 int i = 0;
5622
5623 RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
5624 RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
5625 paoac_rpt->replay_counter_eapol_key, 8);
5626 RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
5627 RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
5628 RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
5629 RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
5630 paoac_rpt->wow_pattern_idx);
5631 RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
5632 RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);
5633 RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
5634 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
5635 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
5636 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
5637 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
5638 }
5639
rtw_hal_get_aoac_rpt(_adapter * adapter)5640 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
5641 {
5642 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5643 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5644 u32 page_offset = 0, page_number = 0;
5645 u32 page_size = 0, buf_size = 0;
5646 u8 *buffer = NULL;
5647 u8 i = 0, tmp = 0;
5648 int ret = -1;
5649
5650 /* read aoac report from rsvd page */
5651 page_offset = pwrctl->wowlan_aoac_rpt_loc;
5652 page_number = 1;
5653
5654 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5655 buf_size = page_size * page_number;
5656
5657 buffer = rtw_zvmalloc(buf_size);
5658
5659 if (buffer == NULL) {
5660 RTW_ERR("%s buffer allocate failed size(%d)\n",
5661 __func__, buf_size);
5662 return;
5663 }
5664
5665 RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
5666
5667 ret = rtw_hal_get_rsvd_page(adapter, page_offset,
5668 page_number, buffer, buf_size);
5669
5670 if (ret == _FALSE) {
5671 RTW_ERR("%s get aoac report failed\n", __func__);
5672 rtw_warn_on(1);
5673 goto _exit;
5674 }
5675
5676 _rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
5677 _rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
5678
5679 for (i = 0 ; i < 4 ; i++) {
5680 tmp = paoac_rpt->replay_counter_eapol_key[i];
5681 paoac_rpt->replay_counter_eapol_key[i] =
5682 paoac_rpt->replay_counter_eapol_key[7 - i];
5683 paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
5684 }
5685
5686 rtw_dump_aoac_rpt(adapter);
5687
5688 _exit:
5689 if (buffer)
5690 rtw_vmfree(buffer, buf_size);
5691 }
5692
rtw_hal_update_tx_iv(_adapter * adapter)5693 static void rtw_hal_update_tx_iv(_adapter *adapter)
5694 {
5695 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5696 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5697 struct sta_info *psta;
5698 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
5699 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5700 struct security_priv *psecpriv = &adapter->securitypriv;
5701
5702 u16 val16 = 0;
5703 u32 val32 = 0;
5704 u64 txiv = 0;
5705 u8 *pval = NULL;
5706
5707 psta = rtw_get_stainfo(&adapter->stapriv,
5708 get_my_bssid(&pmlmeinfo->network));
5709
5710 /* Update TX iv data. */
5711 pval = (u8 *)&paoac_rpt->iv;
5712
5713 if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
5714 val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
5715 ((u16)(paoac_rpt->iv[0]) << 8);
5716 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5717 ((u32)(paoac_rpt->iv[5]) << 8) +
5718 ((u32)(paoac_rpt->iv[6]) << 16) +
5719 ((u32)(paoac_rpt->iv[7]) << 24);
5720 } else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
5721 val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
5722 ((u16)(paoac_rpt->iv[1]) << 8);
5723 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5724 ((u32)(paoac_rpt->iv[5]) << 8) +
5725 ((u32)(paoac_rpt->iv[6]) << 16) +
5726 ((u32)(paoac_rpt->iv[7]) << 24);
5727 }
5728
5729 if (psta) {
5730 txiv = val16 + ((u64)val32 << 16);
5731 if (txiv != 0)
5732 psta->dot11txpn.val = txiv;
5733 }
5734 }
5735
rtw_hal_update_sw_security_info(_adapter * adapter)5736 static void rtw_hal_update_sw_security_info(_adapter *adapter)
5737 {
5738 struct security_priv *psecpriv = &adapter->securitypriv;
5739 u8 sz = sizeof (psecpriv->iv_seq);
5740
5741 rtw_hal_update_tx_iv(adapter);
5742 #ifdef CONFIG_GTK_OL
5743 if (psecpriv->binstallKCK_KEK == _TRUE &&
5744 (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5745 rtw_hal_update_gtk_offload_info(adapter);
5746 #else
5747 _rtw_memset(psecpriv->iv_seq, 0, sz);
5748 #endif
5749 }
5750 #ifdef CONFIG_CUSTOM_PULSE
rtw_hal_set_gpio_custom_cmd(_adapter * adapter,u8 enable)5751 static u8 rtw_hal_set_gpio_custom_cmd(_adapter *adapter, u8 enable)
5752 {
5753 u8 H2CGpioCustomParm[H2C_GPIO_CUSTOM_LEN] = {0};
5754 u8 customid = 0x2, special_wakeup_reason = RX_MAGIC_PKT, custom_for_wakeup_reason=0x1;
5755 u8 ret = _FAIL;
5756
5757 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5758
5759 if(enable) {
5760 SET_H2CCMD_CUSTOMERID(H2CGpioCustomParm, customid);
5761 SET_H2CCMD_SPECIAL_WAKE_REASON(H2CGpioCustomParm, special_wakeup_reason);
5762 SET_H2CCMD_CUSTOM_WAKE_REASON(H2CGpioCustomParm, custom_for_wakeup_reason);
5763
5764 ret = rtw_hal_fill_h2c_cmd(adapter,
5765 H2C_GPIO_CUSTOM,
5766 H2C_GPIO_CUSTOM_LEN,
5767 H2CGpioCustomParm);
5768 RTW_DBG("%s(): H2C_cmd=%x, cmd=%02x, %02x, %02x\n", __func__, H2C_GPIO_CUSTOM,
5769 H2CGpioCustomParm[0], H2CGpioCustomParm[1], H2CGpioCustomParm[2]);
5770 }
5771
5772 return ret;
5773 }
5774 #endif /* CONFIG_CUSTOM_PULSE */
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)5775 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
5776 {
5777 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
5778 u8 adopt = 1, check_period = 5;
5779 u8 ret = _FAIL;
5780 u8 hw_port = rtw_hal_get_port(adapter);
5781
5782 SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
5783 SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
5784 SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
5785 SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
5786 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5787 SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);
5788 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5789 #else
5790 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5791 #endif
5792 ret = rtw_hal_fill_h2c_cmd(adapter,
5793 H2C_KEEP_ALIVE,
5794 H2C_KEEP_ALIVE_CTRL_LEN,
5795 u1H2CKeepAliveParm);
5796
5797 return ret;
5798 }
5799
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)5800 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
5801 {
5802 u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
5803 u8 adopt = 1, check_period = 100, trypkt_num = 5;
5804 u8 ret = _FAIL;
5805 struct registry_priv *pregistry = &adapter->registrypriv;
5806 u8 hw_port = rtw_hal_get_port(adapter);
5807
5808 SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
5809 SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
5810 if (!(pregistry->wakeup_event & BIT(2)))
5811 SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt);
5812 SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
5813 SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
5814 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5815 SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);
5816 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5817 #else
5818 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5819 #endif
5820
5821 ret = rtw_hal_fill_h2c_cmd(adapter,
5822 H2C_DISCON_DECISION,
5823 H2C_DISCON_DECISION_LEN,
5824 u1H2CDisconDecisionParm);
5825 return ret;
5826 }
5827
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)5828 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
5829 {
5830 struct registry_priv *registry_par = &adapter->registrypriv;
5831 struct security_priv *psecpriv = &adapter->securitypriv;
5832 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5833 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5834
5835 u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
5836 u8 discont_wake = 0, gpionum = 0, gpio_dur = 0, no_wake = 0;
5837 u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
5838 u8 sdio_wakeup_enable = 1;
5839 u8 gpio_high_active = 0;
5840 u8 magic_pkt = 0;
5841 u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
5842 u8 ret = _FAIL;
5843 #ifdef CONFIG_DIS_UPHY
5844 u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;
5845 #endif /* CONFIG_DIS_UPHY */
5846
5847 #ifdef CONFIG_GPIO_WAKEUP
5848 gpio_high_active = ppwrpriv->is_high_active;
5849 gpionum = ppwrpriv->wowlan_gpio_index;
5850 sdio_wakeup_enable = 0;
5851 #endif /* CONFIG_GPIO_WAKEUP */
5852
5853 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
5854 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5855 no_wake = 1;
5856
5857 if (!ppwrpriv->wowlan_pno_enable &&
5858 registry_par->wakeup_event & BIT(0) && !no_wake)
5859 magic_pkt = enable;
5860
5861 if ((registry_par->wakeup_event & BIT(1)) &&
5862 (psecpriv->dot11PrivacyAlgrthm == _WEP40_ ||
5863 psecpriv->dot11PrivacyAlgrthm == _WEP104_) && !no_wake)
5864 hw_unicast = 1;
5865
5866 if (registry_par->wakeup_event & BIT(2) && !no_wake)
5867 discont_wake = enable;
5868
5869 RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
5870 enable, change_unit);
5871
5872 /* time = (gpio_dur/2) * gpio_unit, default:256 ms */
5873 if (enable && change_unit) {
5874 gpio_dur = 0x40;
5875 gpio_unit = 1;
5876 gpio_pulse_en = 1;
5877 }
5878
5879 #ifdef CONFIG_PLATFORM_ARM_RK3188
5880 if (enable) {
5881 gpio_pulse_en = 1;
5882 gpio_pulse_cnt = 0x04;
5883 }
5884 #endif
5885
5886 SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
5887 if(!no_wake)
5888 SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
5889 SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
5890 SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
5891 SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
5892 SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
5893
5894 #ifdef CONFIG_GTK_OL
5895 if (psecpriv->binstallKCK_KEK == _TRUE &&
5896 (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5897 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
5898 else
5899 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
5900 #else
5901 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
5902 #endif
5903 SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
5904 SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
5905 SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
5906
5907 SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
5908 SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
5909
5910 SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
5911 SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
5912
5913 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
5914 if (enable)
5915 SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5916 #endif
5917
5918 #ifdef CONFIG_DIS_UPHY
5919 if (enable) {
5920 dis_uphy = 1;
5921 /* time unit: 0 -> ms, 1 -> 256 ms*/
5922 dis_uphy_unit = 1;
5923 dis_uphy_time = 0x4;
5924 }
5925
5926 SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
5927 SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
5928 SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
5929 if (ppwrpriv->hst2dev_high_active == 1)
5930 SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
5931 #ifdef CONFIG_RTW_ONE_PIN_GPIO
5932 SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5933 SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
5934 SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
5935 #else
5936 SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
5937 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
5938 #endif /* CONFIG_DIS_UPHY */
5939
5940
5941 ret = rtw_hal_fill_h2c_cmd(adapter,
5942 H2C_WOWLAN,
5943 H2C_WOWLAN_LEN,
5944 u1H2CWoWlanCtrlParm);
5945 return ret;
5946 }
5947
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)5948 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
5949 {
5950 struct security_priv *psecuritypriv = &(adapter->securitypriv);
5951 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5952 struct registry_priv *pregistrypriv = &adapter->registrypriv;
5953 u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
5954 u8 ret = _FAIL, count = 0, no_wake = 0;
5955 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5956
5957 RTW_INFO("%s(): enable=%d\n", __func__, enable);
5958
5959 if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&
5960 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5961 no_wake = 1;
5962 if(no_wake) {
5963 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5964 u1H2CRemoteWakeCtrlParm, enable);
5965 } else {
5966 if (!ppwrpriv->wowlan_pno_enable) {
5967 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5968 u1H2CRemoteWakeCtrlParm, enable);
5969 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5970 u1H2CRemoteWakeCtrlParm, 1);
5971 #ifdef CONFIG_GTK_OL
5972 if (psecuritypriv->binstallKCK_KEK == _TRUE &&
5973 (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) {
5974 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5975 u1H2CRemoteWakeCtrlParm, 1);
5976 } else {
5977 RTW_INFO("no kck kek\n");
5978 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5979 u1H2CRemoteWakeCtrlParm, 0);
5980 }
5981 #endif /* CONFIG_GTK_OL */
5982
5983 #ifdef CONFIG_IPV6
5984 if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
5985 RTW_INFO("enable NS offload\n");
5986 SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
5987 u1H2CRemoteWakeCtrlParm, enable);
5988 }
5989
5990 /*
5991 * filter NetBios name service pkt to avoid being waked-up
5992 * by this kind of unicast pkt this exceptional modification
5993 * is used for match competitor's behavior
5994 */
5995
5996 SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
5997 u1H2CRemoteWakeCtrlParm, enable);
5998 #endif /*CONFIG_IPV6*/
5999 #if 0 /* replaced by WOWLAN pattern match */
6000 #ifdef CONFIG_RTL8192F
6001 if (IS_HARDWARE_TYPE_8192F(adapter)){
6002 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
6003 u1H2CRemoteWakeCtrlParm, enable);
6004 }
6005 #endif /* CONFIG_RTL8192F */
6006 #endif
6007 if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
6008 (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
6009 (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
6010 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6011 u1H2CRemoteWakeCtrlParm, 0);
6012 } else {
6013 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6014 u1H2CRemoteWakeCtrlParm, 1);
6015 }
6016
6017 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
6018 #ifdef CONFIG_GTK_OL
6019 if(_rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))
6020 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
6021 u1H2CRemoteWakeCtrlParm, enable);
6022 #endif /* CONFIG_GTK_OL */
6023 if (IS_HARDWARE_TYPE_8188E(adapter) ||
6024 IS_HARDWARE_TYPE_8812(adapter)) {
6025 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
6026 u1H2CRemoteWakeCtrlParm, 0);
6027 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
6028 u1H2CRemoteWakeCtrlParm, 1);
6029 }
6030 }
6031
6032 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
6033 u1H2CRemoteWakeCtrlParm, 1);
6034 }
6035 #ifdef CONFIG_PNO_SUPPORT
6036 else {
6037 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
6038 u1H2CRemoteWakeCtrlParm, enable);
6039 SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
6040 u1H2CRemoteWakeCtrlParm, enable);
6041 }
6042 #endif
6043
6044 #ifdef CONFIG_P2P_WOWLAN
6045 if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
6046 RTW_INFO("P2P OFFLOAD ENABLE\n");
6047 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
6048 } else {
6049 RTW_INFO("P2P OFFLOAD DISABLE\n");
6050 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
6051 }
6052 #endif /* CONFIG_P2P_WOWLAN */
6053 }
6054
6055
6056 ret = rtw_hal_fill_h2c_cmd(adapter,
6057 H2C_REMOTE_WAKE_CTRL,
6058 H2C_REMOTE_WAKE_CTRL_LEN,
6059 u1H2CRemoteWakeCtrlParm);
6060 return ret;
6061 }
6062
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)6063 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
6064 {
6065 u8 ret = _FAIL;
6066 u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
6067
6068 RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
6069 __func__, group_alg, pairwise_alg);
6070 SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
6071 pairwise_alg);
6072 SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
6073 group_alg);
6074
6075 ret = rtw_hal_fill_h2c_cmd(adapter,
6076 H2C_AOAC_GLOBAL_INFO,
6077 H2C_AOAC_GLOBAL_INFO_LEN,
6078 u1H2CAOACGlobalInfoParm);
6079
6080 return ret;
6081 }
6082
6083 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)6084 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
6085 PRSVDPAGE_LOC rsvdpageloc, u8 enable)
6086 {
6087 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6088 u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
6089 u8 res = 0, count = 0, ret = _FAIL;
6090
6091 RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
6092 __func__, rsvdpageloc->LocProbePacket,
6093 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
6094
6095 SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
6096 SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
6097 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
6098 rsvdpageloc->LocScanInfo);
6099 SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
6100 rsvdpageloc->LocProbePacket);
6101 /*
6102 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
6103 rsvdpageloc->LocSSIDInfo);
6104 */
6105 ret = rtw_hal_fill_h2c_cmd(adapter,
6106 H2C_D0_SCAN_OFFLOAD_INFO,
6107 H2C_SCAN_OFFLOAD_CTRL_LEN,
6108 u1H2CScanOffloadInfoParm);
6109 return ret;
6110 }
6111 #endif /* CONFIG_PNO_SUPPORT */
6112
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)6113 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
6114 {
6115 struct security_priv *psecpriv = &padapter->securitypriv;
6116 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
6117 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6118 struct registry_priv *pregistry = &padapter->registrypriv;
6119 u8 pkt_type = 0, no_wake = 0;
6120
6121 if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&
6122 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
6123 no_wake = 1;
6124
6125 RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
6126
6127 rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
6128
6129 if (enable) {
6130 if(!no_wake)
6131 rtw_hal_set_global_info_cmd(padapter,
6132 psecpriv->dot118021XGrpPrivacy,
6133 psecpriv->dot11PrivacyAlgrthm);
6134
6135 if (!(ppwrpriv->wowlan_pno_enable)) {
6136 if (!no_wake)
6137 rtw_hal_set_disconnect_decision_cmd(padapter,
6138 enable);
6139 #ifdef CONFIG_ARP_KEEP_ALIVE
6140 if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
6141 (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
6142 pkt_type = 0;
6143 else
6144 pkt_type = 1;
6145 #else
6146 pkt_type = 0;
6147 #endif /* CONFIG_ARP_KEEP_ALIVE */
6148 if(!no_wake)
6149 rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
6150 }
6151 #ifdef CONFIG_PNO_SUPPORT
6152 rtw_hal_check_pno_enabled(padapter);
6153 #endif /* CONFIG_PNO_SUPPORT */
6154 } else {
6155 #if 0
6156 {
6157 u32 PageSize = 0;
6158 rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
6159 dump_TX_FIFO(padapter, 4, PageSize);
6160 }
6161 #endif
6162 }
6163 #ifdef CONFIG_CUSTOM_PULSE
6164 rtw_hal_set_gpio_custom_cmd(padapter, enable);
6165 #endif /* CONFIG_CUSTOM_PULSE */
6166 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
6167 RTW_PRINT("-%s()-\n", __func__);
6168 }
6169 #endif /* CONFIG_WOWLAN */
6170
6171 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)6172 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
6173 {
6174 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6175
6176 u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
6177 u8 gpionum = 0, gpio_dur = 0;
6178 u8 gpio_pulse = enable;
6179 u8 sdio_wakeup_enable = 1;
6180 u8 gpio_high_active = 0;
6181 u8 ret = _FAIL;
6182
6183 #ifdef CONFIG_GPIO_WAKEUP
6184 gpio_high_active = ppwrpriv->is_high_active;
6185 gpionum = ppwrpriv->wowlan_gpio_index;
6186 sdio_wakeup_enable = 0;
6187 #endif /*CONFIG_GPIO_WAKEUP*/
6188
6189 RTW_INFO("%s(): enable=%d\n", __func__, enable);
6190
6191 SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
6192 gpionum);
6193 SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
6194 gpio_pulse);
6195 SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
6196 gpio_high_active);
6197 SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
6198 enable);
6199 SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
6200 gpio_dur);
6201
6202 ret = rtw_hal_fill_h2c_cmd(adapter,
6203 H2C_AP_WOW_GPIO_CTRL,
6204 H2C_AP_WOW_GPIO_CTRL_LEN,
6205 u1H2CAPWoWlanCtrlParm);
6206
6207 return ret;
6208 }
6209
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)6210 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6211 {
6212 u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
6213 u8 ret = _FAIL;
6214
6215 RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
6216
6217 SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
6218
6219 ret = rtw_hal_fill_h2c_cmd(adapter,
6220 H2C_AP_OFFLOAD,
6221 H2C_AP_OFFLOAD_LEN,
6222 u1H2CAPOffloadCtrlParm);
6223
6224 return ret;
6225 }
6226
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)6227 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
6228 {
6229 u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
6230 u8 ret = _FAIL;
6231
6232 RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
6233
6234 SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
6235 #ifndef CONFIG_USB_HCI
6236 SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
6237 #endif /*CONFIG_USB_HCI*/
6238 SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
6239
6240 if (enable)
6241 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
6242 else
6243 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
6244
6245 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
6246 H2C_AP_PS_LEN, ap_ps_parm);
6247
6248 return ret;
6249 }
6250
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)6251 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
6252 PRSVDPAGE_LOC rsvdpageloc)
6253 {
6254 struct hal_ops *pHalFunc = &padapter->hal_func;
6255 u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
6256 u8 ret = _FAIL, header = 0;
6257
6258 if (pHalFunc->fill_h2c_cmd == NULL) {
6259 RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
6260 return;
6261 }
6262
6263 header = rtw_read8(padapter, REG_BCNQ_BDNY);
6264
6265 RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
6266 rsvdpageloc->LocApOffloadBCN,
6267 rsvdpageloc->LocProbeRsp,
6268 header);
6269
6270 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
6271 rsvdpageloc->LocApOffloadBCN + header);
6272
6273 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
6274 H2C_BCN_RSVDPAGE_LEN, rsvdparm);
6275
6276 if (ret == _FAIL)
6277 RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
6278
6279 rtw_msleep_os(10);
6280
6281 _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
6282
6283 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
6284 rsvdpageloc->LocProbeRsp + header);
6285
6286 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
6287 H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
6288
6289 if (ret == _FAIL)
6290 RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
6291
6292 rtw_msleep_os(10);
6293 }
6294
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)6295 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
6296 {
6297 rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
6298 rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
6299 rtw_hal_set_ap_ps_cmd(padapter, enable);
6300 }
6301
rtw_hal_ap_wow_enable(_adapter * padapter)6302 static void rtw_hal_ap_wow_enable(_adapter *padapter)
6303 {
6304 struct security_priv *psecuritypriv = &padapter->securitypriv;
6305 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6306 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6307 struct sta_info *psta = NULL;
6308 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6309 #ifdef DBG_CHECK_FW_PS_STATE
6310 struct dvobj_priv *psdpriv = padapter->dvobj;
6311 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6312 #endif /*DBG_CHECK_FW_PS_STATE*/
6313 int res;
6314 u16 media_status_rpt;
6315 #ifdef CONFIG_GPIO_WAKEUP
6316 u8 val8 = 0;
6317 #endif
6318
6319 RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
6320 #ifdef DBG_CHECK_FW_PS_STATE
6321 if (rtw_fw_ps_state(padapter) == _FAIL) {
6322 pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
6323 RTW_PRINT("wowlan enable no leave 32k\n");
6324 }
6325 #endif /*DBG_CHECK_FW_PS_STATE*/
6326
6327 /* 1. Download WOWLAN FW*/
6328 rtw_hal_fw_dl(padapter, _TRUE);
6329
6330 media_status_rpt = RT_MEDIA_CONNECT;
6331 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6332 (u8 *)&media_status_rpt);
6333
6334 issue_beacon(padapter, 0);
6335
6336 rtw_msleep_os(2);
6337 #if defined(CONFIG_RTL8188E)
6338 if (IS_HARDWARE_TYPE_8188E(padapter))
6339 rtw_hal_disable_tx_report(padapter);
6340 #endif
6341 /* RX DMA stop */
6342 res = rtw_hal_pause_rx_dma(padapter);
6343 if (res == _FAIL)
6344 RTW_PRINT("[WARNING] pause RX DMA fail\n");
6345
6346 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6347 /* Enable CPWM2 only. */
6348 res = rtw_hal_enable_cpwm2(padapter);
6349 if (res == _FAIL)
6350 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6351 #endif
6352
6353 #ifdef CONFIG_GPIO_WAKEUP
6354 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6355 rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6356 rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6357 #else
6358 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6359 if (pwrctrlpriv->is_high_active == 0)
6360 rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6361 else
6362 rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index,
6363 GPIO_OUTPUT_LOW);
6364 #else
6365 val8 = (pwrpriv->is_high_active == 0) ? 1 : 0;
6366 rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8);
6367 rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6368 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow suspend and %s_ACTIVE.\n",
6369 __func__, pwrpriv->wowlan_gpio_index,
6370 pwrpriv->wowlan_gpio_output_state ? "HIGH" : "LOW",
6371 pwrpriv->is_high_active ? "HIGI" : "LOW");
6372 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
6373 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6374 #endif /* CONFIG_GPIO_WAKEUP */
6375
6376 /* 5. Set Enable WOWLAN H2C command. */
6377 RTW_PRINT("Set Enable AP WOWLan cmd\n");
6378 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
6379
6380 rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
6381 #ifdef CONFIG_USB_HCI
6382 rtw_mi_intf_stop(padapter);
6383 #endif
6384 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
6385 /* Invoid SE0 reset signal during suspending*/
6386 rtw_write8(padapter, REG_RSV_CTRL, 0x20);
6387 if (IS_8188F(pHalData->version_id) == FALSE
6388 && IS_8188GTV(pHalData->version_id) == FALSE)
6389 rtw_write8(padapter, REG_RSV_CTRL, 0x60);
6390 #endif
6391 }
6392
rtw_hal_ap_wow_disable(_adapter * padapter)6393 static void rtw_hal_ap_wow_disable(_adapter *padapter)
6394 {
6395 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6396 #ifdef DBG_CHECK_FW_PS_STATE
6397 struct dvobj_priv *psdpriv = padapter->dvobj;
6398 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6399 #endif /*DBG_CHECK_FW_PS_STATE*/
6400 u16 media_status_rpt;
6401
6402 RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
6403 /* 1. Read wakeup reason*/
6404 pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
6405
6406 RTW_PRINT("wakeup_reason: 0x%02x\n",
6407 pwrctl->wowlan_wake_reason);
6408
6409 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
6410
6411 rtw_msleep_os(2);
6412 #ifdef DBG_CHECK_FW_PS_STATE
6413 if (rtw_fw_ps_state(padapter) == _FAIL) {
6414 pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
6415 RTW_PRINT("wowlan enable no leave 32k\n");
6416 }
6417 #endif /*DBG_CHECK_FW_PS_STATE*/
6418
6419 #if defined(CONFIG_RTL8188E)
6420 if (IS_HARDWARE_TYPE_8188E(padapter))
6421 rtw_hal_enable_tx_report(padapter);
6422 #endif
6423
6424 rtw_hal_force_enable_rxdma(padapter);
6425
6426 rtw_hal_fw_dl(padapter, _FALSE);
6427
6428 #ifdef CONFIG_GPIO_WAKEUP
6429 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6430 rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6431 #else
6432 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6433 if (pwrctl->is_high_active == 0)
6434 rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6435 else
6436 rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index
6437 , GPIO_OUTPUT_LOW);
6438 #else
6439 rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index,
6440 pwrctl->wowlan_gpio_output_state);
6441 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow resume and %s_ACTIVE.\n",
6442 __func__, pwrctl->wowlan_gpio_index,
6443 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
6444 pwrctl->is_high_active ? "HIGI" : "LOW");
6445 #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
6446 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6447 #endif /* CONFIG_GPIO_WAKEUP */
6448 media_status_rpt = RT_MEDIA_CONNECT;
6449
6450 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6451 (u8 *)&media_status_rpt);
6452
6453 issue_beacon(padapter, 0);
6454 }
6455 #endif /*CONFIG_AP_WOWLAN*/
6456
6457 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)6458 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
6459 {
6460 u8 *ssid_ie;
6461 sint ssid_len_ori;
6462 int len_diff = 0;
6463
6464 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
6465
6466 /* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
6467
6468 if (ssid_ie && ssid_len_ori > 0) {
6469 switch (hidden_ssid_mode) {
6470 case 1: {
6471 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
6472 u32 remain_len = 0;
6473
6474 remain_len = ies_len - (next_ie - ies);
6475
6476 ssid_ie[1] = 0;
6477 _rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
6478 len_diff -= ssid_len_ori;
6479
6480 break;
6481 }
6482 case 2:
6483 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
6484 break;
6485 default:
6486 break;
6487 }
6488 }
6489
6490 return len_diff;
6491 }
6492
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)6493 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
6494 {
6495 /* struct xmit_frame *pmgntframe; */
6496 /* struct pkt_attrib *pattrib; */
6497 /* unsigned char *pframe; */
6498 struct rtw_ieee80211_hdr *pwlanhdr;
6499 unsigned short *fctrl;
6500 unsigned int rate_len;
6501 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6502 u32 pktlen;
6503 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6504 /* _irqL irqL;
6505 * struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6506 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6507 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6508 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6509 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6510 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
6511 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6512 #ifdef CONFIG_P2P
6513 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6514 #endif /* CONFIG_P2P */
6515
6516 /* for debug */
6517 u8 *dbgbuf = pframe;
6518 u8 dbgbufLen = 0, index = 0;
6519
6520 RTW_INFO("%s\n", __FUNCTION__);
6521 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6522 /* _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6523 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6524
6525 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6526
6527
6528 fctrl = &(pwlanhdr->frame_ctl);
6529 *(fctrl) = 0;
6530
6531 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6532 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6533 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6534
6535 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6536 /* pmlmeext->mgnt_seq++; */
6537 set_frame_sub_type(pframe, WIFI_BEACON);
6538
6539 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6540 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6541
6542 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6543 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6544 #ifdef CONFIG_P2P
6545 /* for P2P : Primary Device Type & Device Name */
6546 u32 wpsielen = 0, insert_len = 0;
6547 u8 *wpsie = NULL;
6548 wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
6549
6550 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
6551 uint wps_offset, remainder_ielen;
6552 u8 *premainder_ie, *pframe_wscie;
6553
6554 wps_offset = (uint)(wpsie - cur_network->IEs);
6555
6556 premainder_ie = wpsie + wpsielen;
6557
6558 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6559
6560 #ifdef CONFIG_IOCTL_CFG80211
6561 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6562 if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
6563 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
6564 pframe += wps_offset;
6565 pktlen += wps_offset;
6566
6567 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6568 pframe += pmlmepriv->wps_beacon_ie_len;
6569 pktlen += pmlmepriv->wps_beacon_ie_len;
6570
6571 /* copy remainder_ie to pframe */
6572 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6573 pframe += remainder_ielen;
6574 pktlen += remainder_ielen;
6575 } else {
6576 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6577 pframe += cur_network->IELength;
6578 pktlen += cur_network->IELength;
6579 }
6580 } else
6581 #endif /* CONFIG_IOCTL_CFG80211 */
6582 {
6583 pframe_wscie = pframe + wps_offset;
6584 _rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
6585 pframe += (wps_offset + wpsielen);
6586 pktlen += (wps_offset + wpsielen);
6587
6588 /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6589 /* Primary Device Type */
6590 /* Type: */
6591 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6592 insert_len += 2;
6593
6594 /* Length: */
6595 *(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
6596 insert_len += 2;
6597
6598 /* Value: */
6599 /* Category ID */
6600 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6601 insert_len += 2;
6602
6603 /* OUI */
6604 *(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
6605 insert_len += 4;
6606
6607 /* Sub Category ID */
6608 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6609 insert_len += 2;
6610
6611
6612 /* Device Name */
6613 /* Type: */
6614 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6615 insert_len += 2;
6616
6617 /* Length: */
6618 *(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
6619 insert_len += 2;
6620
6621 /* Value: */
6622 _rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
6623 insert_len += pwdinfo->device_name_len;
6624
6625
6626 /* update wsc ie length */
6627 *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
6628
6629 /* pframe move to end */
6630 pframe += insert_len;
6631 pktlen += insert_len;
6632
6633 /* copy remainder_ie to pframe */
6634 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6635 pframe += remainder_ielen;
6636 pktlen += remainder_ielen;
6637 }
6638 } else
6639 #endif /* CONFIG_P2P */
6640 {
6641 int len_diff;
6642 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6643 len_diff = update_hidden_ssid(
6644 pframe + _BEACON_IE_OFFSET_
6645 , cur_network->IELength - _BEACON_IE_OFFSET_
6646 , pmlmeinfo->hidden_ssid_mode
6647 );
6648 pframe += (cur_network->IELength + len_diff);
6649 pktlen += (cur_network->IELength + len_diff);
6650 }
6651 #if 0
6652 {
6653 u8 *wps_ie;
6654 uint wps_ielen;
6655 u8 sr = 0;
6656 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
6657 pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
6658 if (wps_ie && wps_ielen > 0)
6659 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6660 if (sr != 0)
6661 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6662 else
6663 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6664 }
6665 #endif
6666 #ifdef CONFIG_P2P
6667 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6668 u32 len;
6669 #ifdef CONFIG_IOCTL_CFG80211
6670 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6671 len = pmlmepriv->p2p_beacon_ie_len;
6672 if (pmlmepriv->p2p_beacon_ie && len > 0)
6673 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6674 } else
6675 #endif /* CONFIG_IOCTL_CFG80211 */
6676 {
6677 len = build_beacon_p2p_ie(pwdinfo, pframe);
6678 }
6679
6680 pframe += len;
6681 pktlen += len;
6682
6683 #ifdef CONFIG_WFD
6684 len = rtw_append_beacon_wfd_ie(padapter, pframe);
6685 pframe += len;
6686 pktlen += len;
6687 #endif
6688
6689 }
6690 #endif /* CONFIG_P2P */
6691
6692 goto _issue_bcn;
6693
6694 }
6695
6696 /* below for ad-hoc mode */
6697
6698 /* timestamp will be inserted by hardware */
6699 pframe += 8;
6700 pktlen += 8;
6701
6702 /* beacon interval: 2 bytes */
6703
6704 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6705
6706 pframe += 2;
6707 pktlen += 2;
6708
6709 /* capability info: 2 bytes */
6710
6711 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6712
6713 pframe += 2;
6714 pktlen += 2;
6715
6716 /* SSID */
6717 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6718
6719 /* supported rates... */
6720 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6721 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6722
6723 /* DS parameter set */
6724 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6725
6726 /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6727 {
6728 u8 erpinfo = 0;
6729 u32 ATIMWindow;
6730 /* IBSS Parameter Set... */
6731 /* ATIMWindow = cur->Configuration.ATIMWindow; */
6732 ATIMWindow = 0;
6733 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6734
6735 /* ERP IE */
6736 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
6737 }
6738
6739
6740 /* EXTERNDED SUPPORTED RATE */
6741 if (rate_len > 8)
6742 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6743
6744
6745 /* todo:HT for adhoc */
6746
6747 _issue_bcn:
6748
6749 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6750 /* pmlmepriv->update_bcn = _FALSE;
6751 *
6752 * _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6753 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6754
6755 *pLength = pktlen;
6756 #if 0
6757 /* printf dbg msg */
6758 dbgbufLen = pktlen;
6759 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6760
6761 for (index = 0; index < dbgbufLen; index++)
6762 printk("%x ", *(dbgbuf + index));
6763
6764 printk("\n");
6765 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6766
6767 #endif
6768 }
6769
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6770 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6771 {
6772 /* struct xmit_frame *pmgntframe; */
6773 /* struct pkt_attrib *pattrib; */
6774 /* unsigned char *pframe; */
6775 struct rtw_ieee80211_hdr *pwlanhdr;
6776 unsigned short *fctrl;
6777 unsigned char *mac;
6778 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6779 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6780 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6781 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6782 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
6783 u16 beacon_interval = 100;
6784 u16 capInfo = 0;
6785 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6786 u8 wpsie[255] = { 0x00 };
6787 u32 wpsielen = 0, p2pielen = 0;
6788 u32 pktlen;
6789 #ifdef CONFIG_WFD
6790 u32 wfdielen = 0;
6791 #endif
6792
6793 /* for debug */
6794 u8 *dbgbuf = pframe;
6795 u8 dbgbufLen = 0, index = 0;
6796
6797 RTW_INFO("%s\n", __FUNCTION__);
6798 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6799
6800 mac = adapter_mac_addr(padapter);
6801
6802 fctrl = &(pwlanhdr->frame_ctl);
6803 *(fctrl) = 0;
6804
6805 /* DA filled by FW */
6806 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6807 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6808
6809 /* Use the device address for BSSID field. */
6810 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6811
6812 SetSeqNum(pwlanhdr, 0);
6813 set_frame_sub_type(fctrl, WIFI_PROBERSP);
6814
6815 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6816 pframe += pktlen;
6817
6818
6819 /* timestamp will be inserted by hardware */
6820 pframe += 8;
6821 pktlen += 8;
6822
6823 /* beacon interval: 2 bytes */
6824 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6825 pframe += 2;
6826 pktlen += 2;
6827
6828 /* capability info: 2 bytes */
6829 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6830 capInfo |= cap_ShortPremble;
6831 capInfo |= cap_ShortSlot;
6832
6833 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6834 pframe += 2;
6835 pktlen += 2;
6836
6837
6838 /* SSID */
6839 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
6840
6841 /* supported rates... */
6842 /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6843 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
6844
6845 /* DS parameter set */
6846 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
6847
6848 #ifdef CONFIG_IOCTL_CFG80211
6849 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6850 if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6851 /* WPS IE */
6852 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6853 pktlen += pmlmepriv->wps_probe_resp_ie_len;
6854 pframe += pmlmepriv->wps_probe_resp_ie_len;
6855
6856 /* P2P IE */
6857 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6858 pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6859 pframe += pmlmepriv->p2p_probe_resp_ie_len;
6860 }
6861 } else
6862 #endif /* CONFIG_IOCTL_CFG80211 */
6863 {
6864
6865 /* Todo: WPS IE */
6866 /* Noted by Albert 20100907 */
6867 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6868
6869 wpsielen = 0;
6870 /* WPS OUI */
6871 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6872 wpsielen += 4;
6873
6874 /* WPS version */
6875 /* Type: */
6876 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6877 wpsielen += 2;
6878
6879 /* Length: */
6880 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6881 wpsielen += 2;
6882
6883 /* Value: */
6884 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
6885
6886 /* WiFi Simple Config State */
6887 /* Type: */
6888 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6889 wpsielen += 2;
6890
6891 /* Length: */
6892 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6893 wpsielen += 2;
6894
6895 /* Value: */
6896 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
6897
6898 /* Response Type */
6899 /* Type: */
6900 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6901 wpsielen += 2;
6902
6903 /* Length: */
6904 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6905 wpsielen += 2;
6906
6907 /* Value: */
6908 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6909
6910 /* UUID-E */
6911 /* Type: */
6912 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6913 wpsielen += 2;
6914
6915 /* Length: */
6916 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6917 wpsielen += 2;
6918
6919 /* Value: */
6920 if (pwdinfo->external_uuid == 0) {
6921 _rtw_memset(wpsie + wpsielen, 0x0, 16);
6922 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6923 } else
6924 _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6925 wpsielen += 0x10;
6926
6927 /* Manufacturer */
6928 /* Type: */
6929 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6930 wpsielen += 2;
6931
6932 /* Length: */
6933 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6934 wpsielen += 2;
6935
6936 /* Value: */
6937 _rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6938 wpsielen += 7;
6939
6940 /* Model Name */
6941 /* Type: */
6942 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
6943 wpsielen += 2;
6944
6945 /* Length: */
6946 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
6947 wpsielen += 2;
6948
6949 /* Value: */
6950 _rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
6951 wpsielen += 6;
6952
6953 /* Model Number */
6954 /* Type: */
6955 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
6956 wpsielen += 2;
6957
6958 /* Length: */
6959 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6960 wpsielen += 2;
6961
6962 /* Value: */
6963 wpsie[wpsielen++] = 0x31; /* character 1 */
6964
6965 /* Serial Number */
6966 /* Type: */
6967 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
6968 wpsielen += 2;
6969
6970 /* Length: */
6971 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
6972 wpsielen += 2;
6973
6974 /* Value: */
6975 _rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
6976 wpsielen += ETH_ALEN;
6977
6978 /* Primary Device Type */
6979 /* Type: */
6980 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6981 wpsielen += 2;
6982
6983 /* Length: */
6984 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6985 wpsielen += 2;
6986
6987 /* Value: */
6988 /* Category ID */
6989 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6990 wpsielen += 2;
6991
6992 /* OUI */
6993 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6994 wpsielen += 4;
6995
6996 /* Sub Category ID */
6997 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6998 wpsielen += 2;
6999
7000 /* Device Name */
7001 /* Type: */
7002 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7003 wpsielen += 2;
7004
7005 /* Length: */
7006 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
7007 wpsielen += 2;
7008
7009 /* Value: */
7010 _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
7011 wpsielen += pwdinfo->device_name_len;
7012
7013 /* Config Method */
7014 /* Type: */
7015 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
7016 wpsielen += 2;
7017
7018 /* Length: */
7019 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7020 wpsielen += 2;
7021
7022 /* Value: */
7023 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7024 wpsielen += 2;
7025
7026
7027 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7028
7029
7030 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
7031 pframe += p2pielen;
7032 pktlen += p2pielen;
7033 }
7034
7035 #ifdef CONFIG_WFD
7036 wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
7037 pframe += wfdielen;
7038 pktlen += wfdielen;
7039 #endif
7040
7041 *pLength = pktlen;
7042
7043 #if 0
7044 /* printf dbg msg */
7045 dbgbufLen = pktlen;
7046 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7047
7048 for (index = 0; index < dbgbufLen; index++)
7049 printk("%x ", *(dbgbuf + index));
7050
7051 printk("\n");
7052 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7053 #endif
7054 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7055 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7056 {
7057 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7058 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7059 u8 action = P2P_PUB_ACTION_ACTION;
7060 u32 p2poui = cpu_to_be32(P2POUI);
7061 u8 oui_subtype = P2P_GO_NEGO_RESP;
7062 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
7063 u8 p2pielen = 0, i;
7064 uint wpsielen = 0;
7065 u16 wps_devicepassword_id = 0x0000;
7066 uint wps_devicepassword_id_len = 0;
7067 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
7068 u16 len_channellist_attr = 0;
7069 u32 pktlen;
7070 u8 dialogToken = 0;
7071
7072 /* struct xmit_frame *pmgntframe; */
7073 /* struct pkt_attrib *pattrib; */
7074 /* unsigned char *pframe; */
7075 struct rtw_ieee80211_hdr *pwlanhdr;
7076 unsigned short *fctrl;
7077 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7078 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7079 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7080 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7081 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
7082
7083 #ifdef CONFIG_WFD
7084 u32 wfdielen = 0;
7085 #endif
7086
7087 /* for debug */
7088 u8 *dbgbuf = pframe;
7089 u8 dbgbufLen = 0, index = 0;
7090
7091 RTW_INFO("%s\n", __FUNCTION__);
7092 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7093
7094 fctrl = &(pwlanhdr->frame_ctl);
7095 *(fctrl) = 0;
7096
7097 /* RA, filled by FW */
7098 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7099 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7100 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7101
7102 SetSeqNum(pwlanhdr, 0);
7103 set_frame_sub_type(pframe, WIFI_ACTION);
7104
7105 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7106 pframe += pktlen;
7107
7108 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7109 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7110 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7111 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7112
7113 /* dialog token, filled by FW */
7114 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7115
7116 _rtw_memset(wpsie, 0x00, 255);
7117 wpsielen = 0;
7118
7119 /* WPS Section */
7120 wpsielen = 0;
7121 /* WPS OUI */
7122 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
7123 wpsielen += 4;
7124
7125 /* WPS version */
7126 /* Type: */
7127 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7128 wpsielen += 2;
7129
7130 /* Length: */
7131 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7132 wpsielen += 2;
7133
7134 /* Value: */
7135 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7136
7137 /* Device Password ID */
7138 /* Type: */
7139 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
7140 wpsielen += 2;
7141
7142 /* Length: */
7143 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7144 wpsielen += 2;
7145
7146 /* Value: */
7147 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
7148 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
7149 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
7150 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
7151 else
7152 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
7153 wpsielen += 2;
7154
7155 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7156
7157
7158 /* P2P IE Section. */
7159
7160 /* P2P OUI */
7161 p2pielen = 0;
7162 p2pie[p2pielen++] = 0x50;
7163 p2pie[p2pielen++] = 0x6F;
7164 p2pie[p2pielen++] = 0x9A;
7165 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7166
7167 /* Commented by Albert 20100908 */
7168 /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
7169 /* 1. Status */
7170 /* 2. P2P Capability */
7171 /* 3. Group Owner Intent */
7172 /* 4. Configuration Timeout */
7173 /* 5. Operating Channel */
7174 /* 6. Intended P2P Interface Address */
7175 /* 7. Channel List */
7176 /* 8. Device Info */
7177 /* 9. Group ID ( Only GO ) */
7178
7179
7180 /* ToDo: */
7181
7182 /* P2P Status */
7183 /* Type: */
7184 p2pie[p2pielen++] = P2P_ATTR_STATUS;
7185
7186 /* Length: */
7187 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7188 p2pielen += 2;
7189
7190 /* Value, filled by FW */
7191 p2pie[p2pielen++] = 1;
7192
7193 /* P2P Capability */
7194 /* Type: */
7195 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
7196
7197 /* Length: */
7198 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7199 p2pielen += 2;
7200
7201 /* Value: */
7202 /* Device Capability Bitmap, 1 byte */
7203
7204 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
7205 /* Commented by Albert 2011/03/08 */
7206 /* According to the P2P specification */
7207 /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
7208 p2pie[p2pielen++] = 0;
7209 } else {
7210 /* Be group owner or meet the error case */
7211 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
7212 }
7213
7214 /* Group Capability Bitmap, 1 byte */
7215 if (pwdinfo->persistent_supported)
7216 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
7217 else
7218 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
7219
7220 /* Group Owner Intent */
7221 /* Type: */
7222 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
7223
7224 /* Length: */
7225 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7226 p2pielen += 2;
7227
7228 /* Value: */
7229 if (pwdinfo->peer_intent & 0x01) {
7230 /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
7231 p2pie[p2pielen++] = (pwdinfo->intent << 1);
7232 } else {
7233 /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
7234 p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
7235 }
7236
7237
7238 /* Configuration Timeout */
7239 /* Type: */
7240 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7241
7242 /* Length: */
7243 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7244 p2pielen += 2;
7245
7246 /* Value: */
7247 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7248 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7249
7250 /* Operating Channel */
7251 /* Type: */
7252 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7253
7254 /* Length: */
7255 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7256 p2pielen += 2;
7257
7258 /* Value: */
7259 /* Country String */
7260 p2pie[p2pielen++] = 'X';
7261 p2pie[p2pielen++] = 'X';
7262
7263 /* The third byte should be set to 0x04. */
7264 /* Described in the "Operating Channel Attribute" section. */
7265 p2pie[p2pielen++] = 0x04;
7266
7267 /* Operating Class */
7268 if (pwdinfo->operating_channel <= 14) {
7269 /* Operating Class */
7270 p2pie[p2pielen++] = 0x51;
7271 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
7272 /* Operating Class */
7273 p2pie[p2pielen++] = 0x73;
7274 } else {
7275 /* Operating Class */
7276 p2pie[p2pielen++] = 0x7c;
7277 }
7278
7279 /* Channel Number */
7280 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7281
7282 /* Intended P2P Interface Address */
7283 /* Type: */
7284 p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
7285
7286 /* Length: */
7287 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7288 p2pielen += 2;
7289
7290 /* Value: */
7291 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7292 p2pielen += ETH_ALEN;
7293
7294 /* Channel List */
7295 /* Type: */
7296 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7297
7298 /* Country String(3) */
7299 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7300 /* + number of channels in all classes */
7301 len_channellist_attr = 3
7302 + (1 + 1) * (u16)ch_list->reg_classes
7303 + get_reg_classes_full_count(ch_list);
7304
7305 #ifdef CONFIG_CONCURRENT_MODE
7306 if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7307 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7308 else
7309 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7310
7311 #else
7312
7313 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7314
7315 #endif
7316 p2pielen += 2;
7317
7318 /* Value: */
7319 /* Country String */
7320 p2pie[p2pielen++] = 'X';
7321 p2pie[p2pielen++] = 'X';
7322
7323 /* The third byte should be set to 0x04. */
7324 /* Described in the "Operating Channel Attribute" section. */
7325 p2pie[p2pielen++] = 0x04;
7326
7327 /* Channel Entry List */
7328
7329 #ifdef CONFIG_CONCURRENT_MODE
7330 if (rtw_mi_check_status(padapter, MI_LINKED)) {
7331 u8 union_ch = rtw_mi_get_union_chan(padapter);
7332
7333 /* Operating Class */
7334 if (union_ch > 14) {
7335 if (union_ch >= 149)
7336 p2pie[p2pielen++] = 0x7c;
7337 else
7338 p2pie[p2pielen++] = 0x73;
7339 } else
7340 p2pie[p2pielen++] = 0x51;
7341
7342
7343 /* Number of Channels */
7344 /* Just support 1 channel and this channel is AP's channel */
7345 p2pie[p2pielen++] = 1;
7346
7347 /* Channel List */
7348 p2pie[p2pielen++] = union_ch;
7349 } else
7350 #endif /* CONFIG_CONCURRENT_MODE */
7351 {
7352 int i, j;
7353 for (j = 0; j < ch_list->reg_classes; j++) {
7354 /* Operating Class */
7355 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7356
7357 /* Number of Channels */
7358 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7359
7360 /* Channel List */
7361 for (i = 0; i < ch_list->reg_class[j].channels; i++)
7362 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7363 }
7364 }
7365
7366 /* Device Info */
7367 /* Type: */
7368 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
7369
7370 /* Length: */
7371 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
7372 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7373 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
7374 p2pielen += 2;
7375
7376 /* Value: */
7377 /* P2P Device Address */
7378 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7379 p2pielen += ETH_ALEN;
7380
7381 /* Config Method */
7382 /* This field should be big endian. Noted by P2P specification. */
7383
7384 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7385
7386 p2pielen += 2;
7387
7388 /* Primary Device Type */
7389 /* Category ID */
7390 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7391 p2pielen += 2;
7392
7393 /* OUI */
7394 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
7395 p2pielen += 4;
7396
7397 /* Sub Category ID */
7398 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7399 p2pielen += 2;
7400
7401 /* Number of Secondary Device Types */
7402 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
7403
7404 /* Device Name */
7405 /* Type: */
7406 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7407 p2pielen += 2;
7408
7409 /* Length: */
7410 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
7411 p2pielen += 2;
7412
7413 /* Value: */
7414 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
7415 p2pielen += pwdinfo->device_name_len;
7416
7417 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7418 /* Group ID Attribute */
7419 /* Type: */
7420 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
7421
7422 /* Length: */
7423 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
7424 p2pielen += 2;
7425
7426 /* Value: */
7427 /* p2P Device Address */
7428 _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
7429 p2pielen += ETH_ALEN;
7430
7431 /* SSID */
7432 _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
7433 p2pielen += pwdinfo->nego_ssidlen;
7434
7435 }
7436
7437 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7438
7439 #ifdef CONFIG_WFD
7440 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
7441 pframe += wfdielen;
7442 pktlen += wfdielen;
7443 #endif
7444
7445 *pLength = pktlen;
7446 #if 0
7447 /* printf dbg msg */
7448 dbgbufLen = pktlen;
7449 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7450
7451 for (index = 0; index < dbgbufLen; index++)
7452 printk("%x ", *(dbgbuf + index));
7453
7454 printk("\n");
7455 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7456 #endif
7457 }
7458
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7459 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7460 {
7461 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7462 u8 action = P2P_PUB_ACTION_ACTION;
7463 u32 p2poui = cpu_to_be32(P2POUI);
7464 u8 oui_subtype = P2P_INVIT_RESP;
7465 u8 p2pie[255] = { 0x00 };
7466 u8 p2pielen = 0, i;
7467 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
7468 u16 len_channellist_attr = 0;
7469 u32 pktlen;
7470 u8 dialogToken = 0;
7471 #ifdef CONFIG_WFD
7472 u32 wfdielen = 0;
7473 #endif
7474
7475 /* struct xmit_frame *pmgntframe; */
7476 /* struct pkt_attrib *pattrib; */
7477 /* unsigned char *pframe; */
7478 struct rtw_ieee80211_hdr *pwlanhdr;
7479 unsigned short *fctrl;
7480 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7481 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7482 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7483 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7484
7485 /* for debug */
7486 u8 *dbgbuf = pframe;
7487 u8 dbgbufLen = 0, index = 0;
7488
7489
7490 RTW_INFO("%s\n", __FUNCTION__);
7491 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7492
7493 fctrl = &(pwlanhdr->frame_ctl);
7494 *(fctrl) = 0;
7495
7496 /* RA fill by FW */
7497 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7498 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7499
7500 /* BSSID fill by FW */
7501 _rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
7502
7503 SetSeqNum(pwlanhdr, 0);
7504 set_frame_sub_type(pframe, WIFI_ACTION);
7505
7506 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7507 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7508
7509 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7510 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7511 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7512 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7513
7514 /* dialog token, filled by FW */
7515 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7516
7517 /* P2P IE Section. */
7518
7519 /* P2P OUI */
7520 p2pielen = 0;
7521 p2pie[p2pielen++] = 0x50;
7522 p2pie[p2pielen++] = 0x6F;
7523 p2pie[p2pielen++] = 0x9A;
7524 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7525
7526 /* Commented by Albert 20101005 */
7527 /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
7528 /* 1. Status */
7529 /* 2. Configuration Timeout */
7530 /* 3. Operating Channel ( Only GO ) */
7531 /* 4. P2P Group BSSID ( Only GO ) */
7532 /* 5. Channel List */
7533
7534 /* P2P Status */
7535 /* Type: */
7536 p2pie[p2pielen++] = P2P_ATTR_STATUS;
7537
7538 /* Length: */
7539 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7540 p2pielen += 2;
7541
7542 /* Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
7543 p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7544
7545 /* Configuration Timeout */
7546 /* Type: */
7547 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7548
7549 /* Length: */
7550 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7551 p2pielen += 2;
7552
7553 /* Value: */
7554 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7555 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7556
7557 /* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
7558 #if 0
7559 if (status_code == P2P_STATUS_SUCCESS) {
7560 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7561
7562 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7563 /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
7564 /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
7565 /* First one is operating channel attribute. */
7566 /* Second one is P2P Group BSSID attribute. */
7567
7568 /* Operating Channel */
7569 /* Type: */
7570 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7571
7572 /* Length: */
7573 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7574 p2pielen += 2;
7575
7576 /* Value: */
7577 /* Country String */
7578 p2pie[p2pielen++] = 'X';
7579 p2pie[p2pielen++] = 'X';
7580
7581 /* The third byte should be set to 0x04. */
7582 /* Described in the "Operating Channel Attribute" section. */
7583 p2pie[p2pielen++] = 0x04;
7584
7585 /* Operating Class */
7586 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
7587
7588 /* Channel Number */
7589 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7590
7591
7592 /* P2P Group BSSID */
7593 /* Type: */
7594 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
7595
7596 /* Length: */
7597 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7598 p2pielen += 2;
7599
7600 /* Value: */
7601 /* P2P Device Address for GO */
7602 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7603 p2pielen += ETH_ALEN;
7604
7605 }
7606
7607 /* Channel List */
7608 /* Type: */
7609 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7610
7611 /* Length: */
7612 /* Country String(3) */
7613 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7614 /* + number of channels in all classes */
7615 len_channellist_attr = 3
7616 + (1 + 1) * (u16)ch_list->reg_classes
7617 + get_reg_classes_full_count(ch_list);
7618
7619 #ifdef CONFIG_CONCURRENT_MODE
7620 if (rtw_mi_check_status(padapter, MI_LINKED))
7621 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7622 else
7623 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7624
7625 #else
7626
7627 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7628
7629 #endif
7630 p2pielen += 2;
7631
7632 /* Value: */
7633 /* Country String */
7634 p2pie[p2pielen++] = 'X';
7635 p2pie[p2pielen++] = 'X';
7636
7637 /* The third byte should be set to 0x04. */
7638 /* Described in the "Operating Channel Attribute" section. */
7639 p2pie[p2pielen++] = 0x04;
7640
7641 /* Channel Entry List */
7642 #ifdef CONFIG_CONCURRENT_MODE
7643 if (rtw_mi_check_status(padapter, MI_LINKED)) {
7644 u8 union_ch = rtw_mi_get_union_chan(padapter);
7645
7646 /* Operating Class */
7647 if (union_ch > 14) {
7648 if (union_ch >= 149)
7649 p2pie[p2pielen++] = 0x7c;
7650 else
7651 p2pie[p2pielen++] = 0x73;
7652
7653 } else
7654 p2pie[p2pielen++] = 0x51;
7655
7656
7657 /* Number of Channels */
7658 /* Just support 1 channel and this channel is AP's channel */
7659 p2pie[p2pielen++] = 1;
7660
7661 /* Channel List */
7662 p2pie[p2pielen++] = union_ch;
7663 } else
7664 #endif /* CONFIG_CONCURRENT_MODE */
7665 {
7666 int i, j;
7667 for (j = 0; j < ch_list->reg_classes; j++) {
7668 /* Operating Class */
7669 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7670
7671 /* Number of Channels */
7672 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7673
7674 /* Channel List */
7675 for (i = 0; i < ch_list->reg_class[j].channels; i++)
7676 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7677 }
7678 }
7679 }
7680 #endif
7681
7682 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7683
7684 #ifdef CONFIG_WFD
7685 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
7686 pframe += wfdielen;
7687 pktlen += wfdielen;
7688 #endif
7689
7690 *pLength = pktlen;
7691
7692 #if 0
7693 /* printf dbg msg */
7694 dbgbufLen = pktlen;
7695 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7696
7697 for (index = 0; index < dbgbufLen; index++)
7698 printk("%x ", *(dbgbuf + index));
7699
7700 printk("\n");
7701 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7702 #endif
7703 }
7704
7705
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7706 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7707 {
7708 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7709 u8 action = P2P_PUB_ACTION_ACTION;
7710 u8 dialogToken = 0;
7711 u32 p2poui = cpu_to_be32(P2POUI);
7712 u8 oui_subtype = P2P_PROVISION_DISC_RESP;
7713 u8 wpsie[100] = { 0x00 };
7714 u8 wpsielen = 0;
7715 u32 pktlen;
7716 #ifdef CONFIG_WFD
7717 u32 wfdielen = 0;
7718 #endif
7719
7720 /* struct xmit_frame *pmgntframe; */
7721 /* struct pkt_attrib *pattrib; */
7722 /* unsigned char *pframe; */
7723 struct rtw_ieee80211_hdr *pwlanhdr;
7724 unsigned short *fctrl;
7725 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7726 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7727 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7728 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7729
7730 /* for debug */
7731 u8 *dbgbuf = pframe;
7732 u8 dbgbufLen = 0, index = 0;
7733
7734 RTW_INFO("%s\n", __FUNCTION__);
7735
7736 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7737
7738 fctrl = &(pwlanhdr->frame_ctl);
7739 *(fctrl) = 0;
7740
7741 /* RA filled by FW */
7742 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7743 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7744 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7745
7746 SetSeqNum(pwlanhdr, 0);
7747 set_frame_sub_type(pframe, WIFI_ACTION);
7748
7749 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7750 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7751
7752 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7753 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7754 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7755 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7756 /* dialog token, filled by FW */
7757 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7758
7759 wpsielen = 0;
7760 /* WPS OUI */
7761 /* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
7762 RTW_PUT_BE32(wpsie, WPSOUI);
7763 wpsielen += 4;
7764
7765 #if 0
7766 /* WPS version */
7767 /* Type: */
7768 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7769 wpsielen += 2;
7770
7771 /* Length: */
7772 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7773 wpsielen += 2;
7774
7775 /* Value: */
7776 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7777 #endif
7778
7779 /* Config Method */
7780 /* Type: */
7781 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
7782 RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
7783 wpsielen += 2;
7784
7785 /* Length: */
7786 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
7787 RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
7788 wpsielen += 2;
7789
7790 /* Value: filled by FW, default value is PBC */
7791 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
7792 RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
7793 wpsielen += 2;
7794
7795 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7796
7797 #ifdef CONFIG_WFD
7798 wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
7799 pframe += wfdielen;
7800 pktlen += wfdielen;
7801 #endif
7802
7803 *pLength = pktlen;
7804
7805 /* printf dbg msg */
7806 #if 0
7807 dbgbufLen = pktlen;
7808 RTW_INFO("======> DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7809
7810 for (index = 0; index < dbgbufLen; index++)
7811 printk("%x ", *(dbgbuf + index));
7812
7813 printk("\n");
7814 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7815 #endif
7816 }
7817
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)7818 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
7819 {
7820 u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
7821 struct hal_ops *pHalFunc = &adapter->hal_func;
7822 u8 ret = _FAIL;
7823
7824 RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
7825 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
7826 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
7827 rsvdpageloc->LocPDRsp);
7828
7829 SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
7830 SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
7831 SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
7832 SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
7833 SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
7834
7835 /* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
7836 ret = rtw_hal_fill_h2c_cmd(adapter,
7837 H2C_P2P_OFFLOAD_RSVD_PAGE,
7838 H2C_P2PRSVDPAGE_LOC_LEN,
7839 u1H2CP2PRsvdPageParm);
7840
7841 return ret;
7842 }
7843
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)7844 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
7845 {
7846
7847 u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
7848 struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
7849 struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
7850 struct hal_ops *pHalFunc = &adapter->hal_func;
7851 u8 ret = _FAIL;
7852
7853 _rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
7854 RTW_INFO("%s\n", __func__);
7855 switch (pwdinfo->role) {
7856 case P2P_ROLE_DEVICE:
7857 RTW_INFO("P2P_ROLE_DEVICE\n");
7858 p2p_wowlan_offload->role = 0;
7859 break;
7860 case P2P_ROLE_CLIENT:
7861 RTW_INFO("P2P_ROLE_CLIENT\n");
7862 p2p_wowlan_offload->role = 1;
7863 break;
7864 case P2P_ROLE_GO:
7865 RTW_INFO("P2P_ROLE_GO\n");
7866 p2p_wowlan_offload->role = 2;
7867 break;
7868 default:
7869 RTW_INFO("P2P_ROLE_DISABLE\n");
7870 break;
7871 }
7872 p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
7873 p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
7874 offload_cmd = (u8 *)p2p_wowlan_offload;
7875 RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
7876
7877 ret = rtw_hal_fill_h2c_cmd(adapter,
7878 H2C_P2P_OFFLOAD,
7879 H2C_P2P_OFFLOAD_LEN,
7880 offload_cmd);
7881 return ret;
7882
7883 /* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
7884 }
7885 #endif /* CONFIG_P2P_WOWLAN */
7886
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)7887 void rtw_hal_construct_beacon(_adapter *padapter,
7888 u8 *pframe, u32 *pLength)
7889 {
7890 struct rtw_ieee80211_hdr *pwlanhdr;
7891 u16 *fctrl;
7892 u32 pktlen;
7893 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7894 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7895 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7896 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7897
7898
7899 /* RTW_INFO("%s\n", __FUNCTION__); */
7900
7901 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7902
7903 fctrl = &(pwlanhdr->frame_ctl);
7904 *(fctrl) = 0;
7905
7906 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7907 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7908 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7909
7910 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7911 /* pmlmeext->mgnt_seq++; */
7912 set_frame_sub_type(pframe, WIFI_BEACON);
7913
7914 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7915 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7916
7917 /* timestamp will be inserted by hardware */
7918 pframe += 8;
7919 pktlen += 8;
7920
7921 /* beacon interval: 2 bytes */
7922 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7923
7924 pframe += 2;
7925 pktlen += 2;
7926
7927 #if 0
7928 /* capability info: 2 bytes */
7929 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7930
7931 pframe += 2;
7932 pktlen += 2;
7933
7934 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7935 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7936 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
7937 _rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
7938
7939 goto _ConstructBeacon;
7940 }
7941
7942 /* below for ad-hoc mode */
7943
7944 /* SSID */
7945 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
7946
7947 /* supported rates... */
7948 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7949 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
7950
7951 /* DS parameter set */
7952 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
7953
7954 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
7955 u32 ATIMWindow;
7956 /* IBSS Parameter Set... */
7957 /* ATIMWindow = cur->Configuration.ATIMWindow; */
7958 ATIMWindow = 0;
7959 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
7960 }
7961
7962
7963 /* todo: ERP IE */
7964
7965
7966 /* EXTERNDED SUPPORTED RATE */
7967 if (rate_len > 8)
7968 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
7969
7970 /* todo:HT for adhoc */
7971
7972 _ConstructBeacon:
7973 #endif
7974
7975 if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
7976 RTW_ERR("beacon frame too large ,len(%d,%d)\n",
7977 (pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
7978 rtw_warn_on(1);
7979 return;
7980 }
7981
7982 *pLength = pktlen;
7983
7984 /* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
7985
7986 }
7987
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)7988 static void rtw_hal_construct_PSPoll(_adapter *padapter,
7989 u8 *pframe, u32 *pLength)
7990 {
7991 struct rtw_ieee80211_hdr *pwlanhdr;
7992 u16 *fctrl;
7993 u32 pktlen;
7994 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7995 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7996
7997 /* RTW_INFO("%s\n", __FUNCTION__); */
7998
7999 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8000
8001 /* Frame control. */
8002 fctrl = &(pwlanhdr->frame_ctl);
8003 *(fctrl) = 0;
8004 SetPwrMgt(fctrl);
8005 set_frame_sub_type(pframe, WIFI_PSPOLL);
8006
8007 /* AID. */
8008 set_duration(pframe, (pmlmeinfo->aid | 0xc000));
8009
8010 /* BSSID. */
8011 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8012
8013 /* TA. */
8014 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8015
8016 *pLength = 16;
8017 }
8018
8019
8020 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_construct_fw_dbg_msg_pkt(PADAPTER padapter,u8 * pframe,u32 * plength)8021 void rtw_hal_construct_fw_dbg_msg_pkt(
8022 PADAPTER padapter,
8023 u8 *pframe,
8024 u32 *plength)
8025 {
8026 struct rtw_ieee80211_hdr *pwlanhdr;
8027 u16 *fctrl;
8028 u32 pktlen;
8029 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8030 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8031 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8032 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8033 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8034
8035
8036 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8037
8038 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8039
8040 fctrl = &pwlanhdr->frame_ctl;
8041 *(fctrl) = 0;
8042
8043 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8044 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8045 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8046
8047 SetSeqNum(pwlanhdr, 0);
8048
8049 set_frame_sub_type(pframe, WIFI_DATA);
8050
8051 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8052
8053 *plength = pktlen;
8054 }
8055 #endif /*DBG_FW_DEBUG_MSG_PKT*/
8056
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)8057 void rtw_hal_construct_NullFunctionData(
8058 PADAPTER padapter,
8059 u8 *pframe,
8060 u32 *pLength,
8061 u8 bQoS,
8062 u8 AC,
8063 u8 bEosp,
8064 u8 bForcePowerSave)
8065 {
8066 struct rtw_ieee80211_hdr *pwlanhdr;
8067 u16 *fctrl;
8068 u32 pktlen;
8069 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8070 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8071 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8072 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8073 u8 *sta_addr = NULL;
8074 u8 bssid[ETH_ALEN] = {0};
8075
8076 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8077
8078 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8079
8080 fctrl = &pwlanhdr->frame_ctl;
8081 *(fctrl) = 0;
8082 if (bForcePowerSave)
8083 SetPwrMgt(fctrl);
8084
8085 sta_addr = get_my_bssid(&pmlmeinfo->network);
8086 if (NULL == sta_addr) {
8087 _rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
8088 sta_addr = bssid;
8089 }
8090
8091 switch (cur_network->network.InfrastructureMode) {
8092 case Ndis802_11Infrastructure:
8093 SetToDs(fctrl);
8094 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8095 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8096 _rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);
8097 break;
8098 case Ndis802_11APMode:
8099 SetFrDs(fctrl);
8100 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8101 _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8102 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8103 break;
8104 case Ndis802_11IBSS:
8105 default:
8106 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8107 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8108 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8109 break;
8110 }
8111
8112 SetSeqNum(pwlanhdr, 0);
8113 set_duration(pwlanhdr, 0);
8114
8115 if (bQoS == _TRUE) {
8116 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
8117
8118 set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
8119
8120 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
8121 SetPriority(&pwlanqoshdr->qc, AC);
8122 SetEOSP(&pwlanqoshdr->qc, bEosp);
8123
8124 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8125 } else {
8126 set_frame_sub_type(pframe, WIFI_DATA_NULL);
8127
8128 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8129 }
8130
8131 *pLength = pktlen;
8132 }
8133
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,BOOLEAN bHideSSID)8134 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
8135 BOOLEAN bHideSSID)
8136 {
8137 struct rtw_ieee80211_hdr *pwlanhdr;
8138 u16 *fctrl;
8139 u8 *mac, *bssid, *sta_addr;
8140 u32 pktlen;
8141 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8142 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8143 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
8144
8145 /*RTW_INFO("%s\n", __FUNCTION__);*/
8146
8147 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8148
8149 mac = adapter_mac_addr(padapter);
8150 bssid = cur_network->MacAddress;
8151 sta_addr = get_my_bssid(&pmlmeinfo->network);
8152
8153 fctrl = &(pwlanhdr->frame_ctl);
8154 *(fctrl) = 0;
8155 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8156 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8157 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8158
8159 SetSeqNum(pwlanhdr, 0);
8160 set_frame_sub_type(fctrl, WIFI_PROBERSP);
8161
8162 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8163 pframe += pktlen;
8164
8165 if (cur_network->IELength > MAX_IE_SZ)
8166 return;
8167
8168 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8169 pframe += cur_network->IELength;
8170 pktlen += cur_network->IELength;
8171
8172 *pLength = pktlen;
8173 }
8174
8175 #ifdef CONFIG_WOWLAN
rtw_hal_append_tkip_mic(PADAPTER padapter,u8 * pframe,u32 offset)8176 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
8177 u8 *pframe, u32 offset)
8178 {
8179 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8180 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8181 struct rtw_ieee80211_hdr *pwlanhdr;
8182 struct mic_data micdata;
8183 struct sta_info *psta = NULL;
8184 int res = 0;
8185
8186 u8 *payload = (u8 *)(pframe + offset);
8187
8188 u8 mic[8];
8189 u8 priority[4] = {0x0};
8190 u8 null_key[16] = {0x0};
8191
8192 RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
8193
8194 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8195
8196 psta = rtw_get_stainfo(&padapter->stapriv,
8197 get_my_bssid(&(pmlmeinfo->network)));
8198 if (psta != NULL) {
8199 res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
8200 null_key, 16);
8201 if (res == _TRUE)
8202 RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
8203 rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
8204 }
8205
8206 rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); /* DA */
8207
8208 rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
8209
8210 priority[0] = 0;
8211
8212 rtw_secmicappend(&micdata, &priority[0], 4);
8213
8214 rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
8215
8216 rtw_secgetmic(&micdata, &(mic[0]));
8217
8218 payload += 36;
8219
8220 _rtw_memcpy(payload, &(mic[0]), 8);
8221 }
8222 /*
8223 * Description:
8224 * Construct the ARP response packet to support ARP offload.
8225 * */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8226 static void rtw_hal_construct_ARPRsp(
8227 PADAPTER padapter,
8228 u8 *pframe,
8229 u32 *pLength,
8230 u8 *pIPAddress
8231 )
8232 {
8233 struct rtw_ieee80211_hdr *pwlanhdr;
8234 u16 *fctrl;
8235 u32 pktlen;
8236 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8237 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8238 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8239 struct security_priv *psecuritypriv = &padapter->securitypriv;
8240 static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
8241 u8 *pARPRspPkt = pframe;
8242 /* for TKIP Cal MIC */
8243 u8 *payload = pframe;
8244 u8 EncryptionHeadOverhead = 0, arp_offset = 0;
8245 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8246
8247 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8248
8249 fctrl = &pwlanhdr->frame_ctl;
8250 *(fctrl) = 0;
8251
8252 /* ------------------------------------------------------------------------- */
8253 /* MAC Header. */
8254 /* ------------------------------------------------------------------------- */
8255 SetFrameType(fctrl, WIFI_DATA);
8256 /* set_frame_sub_type(fctrl, 0); */
8257 SetToDs(fctrl);
8258 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8259 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8260 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8261
8262 SetSeqNum(pwlanhdr, 0);
8263 set_duration(pwlanhdr, 0);
8264 /* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
8265 /* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
8266 /* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
8267 /* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
8268 /* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
8269 /* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
8270
8271 /* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
8272 /* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
8273 #ifdef CONFIG_WAPI_SUPPORT
8274 *pLength = sMacHdrLng;
8275 #else
8276 *pLength = 24;
8277 #endif
8278 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8279 case _WEP40_:
8280 case _WEP104_:
8281 EncryptionHeadOverhead = 4;
8282 break;
8283 case _TKIP_:
8284 EncryptionHeadOverhead = 8;
8285 break;
8286 case _AES_:
8287 EncryptionHeadOverhead = 8;
8288 break;
8289 #ifdef CONFIG_WAPI_SUPPORT
8290 case _SMS4_:
8291 EncryptionHeadOverhead = 18;
8292 break;
8293 #endif
8294 default:
8295 EncryptionHeadOverhead = 0;
8296 }
8297
8298 if (EncryptionHeadOverhead > 0) {
8299 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8300 *pLength += EncryptionHeadOverhead;
8301 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8302 SetPrivacy(fctrl);
8303 }
8304
8305 /* ------------------------------------------------------------------------- */
8306 /* Frame Body. */
8307 /* ------------------------------------------------------------------------- */
8308 arp_offset = *pLength;
8309 pARPRspPkt = (u8 *)(pframe + arp_offset);
8310 payload = pARPRspPkt; /* Get Payload pointer */
8311 /* LLC header */
8312 _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
8313 *pLength += 8;
8314
8315 /* ARP element */
8316 pARPRspPkt += 8;
8317 SET_ARP_HTYPE(pARPRspPkt, 1);
8318 SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP); /* IP protocol */
8319 SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);
8320 SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);
8321 SET_ARP_OPER(pARPRspPkt, 2); /* ARP response */
8322 SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
8323 SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
8324 #ifdef CONFIG_ARP_KEEP_ALIVE
8325 if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
8326 SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
8327 SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
8328 } else
8329 #endif
8330 {
8331 SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,
8332 get_my_bssid(&(pmlmeinfo->network)));
8333 SET_ARP_TARGET_IP_ADDR(pARPRspPkt,
8334 pIPAddress);
8335 RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
8336 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
8337 RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
8338 IP_ARG(pIPAddress));
8339 }
8340
8341 *pLength += 28;
8342
8343 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8344 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8345 IS_HARDWARE_TYPE_8812(padapter)) {
8346 rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
8347 }
8348 *pLength += 8;
8349 }
8350 }
8351
8352 #ifdef CONFIG_IPV6
8353 /*
8354 * Description: Neighbor Discovery Offload.
8355 */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)8356 static void rtw_hal_construct_na_message(_adapter *padapter,
8357 u8 *pframe, u32 *pLength)
8358 {
8359 struct rtw_ieee80211_hdr *pwlanhdr = NULL;
8360 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8361 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8362 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8363 struct security_priv *psecuritypriv = &padapter->securitypriv;
8364
8365 u32 pktlen = 0;
8366 u16 *fctrl = NULL;
8367
8368 u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8369 u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
8370 u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
8371 u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
8372 u8 val8 = 0;
8373
8374 u8 *p_na_msg = pframe;
8375 /* for TKIP Cal MIC */
8376 u8 *payload = pframe;
8377 u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
8378 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8379
8380 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8381
8382 fctrl = &pwlanhdr->frame_ctl;
8383 *(fctrl) = 0;
8384
8385 /* ------------------------------------------------------------------------- */
8386 /* MAC Header. */
8387 /* ------------------------------------------------------------------------- */
8388 SetFrameType(fctrl, WIFI_DATA);
8389 SetToDs(fctrl);
8390 _rtw_memcpy(pwlanhdr->addr1,
8391 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8392 _rtw_memcpy(pwlanhdr->addr2,
8393 adapter_mac_addr(padapter), ETH_ALEN);
8394 _rtw_memcpy(pwlanhdr->addr3,
8395 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8396
8397 SetSeqNum(pwlanhdr, 0);
8398 set_duration(pwlanhdr, 0);
8399
8400 #ifdef CONFIG_WAPI_SUPPORT
8401 *pLength = sMacHdrLng;
8402 #else
8403 *pLength = 24;
8404 #endif
8405 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8406 case _WEP40_:
8407 case _WEP104_:
8408 EncryptionHeadOverhead = 4;
8409 break;
8410 case _TKIP_:
8411 EncryptionHeadOverhead = 8;
8412 break;
8413 case _AES_:
8414 EncryptionHeadOverhead = 8;
8415 break;
8416 #ifdef CONFIG_WAPI_SUPPORT
8417 case _SMS4_:
8418 EncryptionHeadOverhead = 18;
8419 break;
8420 #endif
8421 default:
8422 EncryptionHeadOverhead = 0;
8423 }
8424
8425 if (EncryptionHeadOverhead > 0) {
8426 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8427 *pLength += EncryptionHeadOverhead;
8428 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8429 SetPrivacy(fctrl);
8430 }
8431
8432 /* ------------------------------------------------------------------------- */
8433 /* Frame Body. */
8434 /* ------------------------------------------------------------------------- */
8435 na_msg_offset = *pLength;
8436 p_na_msg = (u8 *)(pframe + na_msg_offset);
8437 payload = p_na_msg; /* Get Payload pointer */
8438
8439 /* LLC header */
8440 val8 = sizeof(ns_hdr);
8441 _rtw_memcpy(p_na_msg, ns_hdr, val8);
8442 *pLength += val8;
8443 p_na_msg += val8;
8444
8445 /* IPv6 Header */
8446 /* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
8447 val8 = sizeof(ipv6_info);
8448 _rtw_memcpy(p_na_msg, ipv6_info, val8);
8449 *pLength += val8;
8450 p_na_msg += val8;
8451
8452 /* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
8453 val8 = sizeof(ipv6_contx);
8454 _rtw_memcpy(p_na_msg, ipv6_contx, val8);
8455 *pLength += val8;
8456 p_na_msg += val8;
8457
8458 /* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
8459 _rtw_memset(&(p_na_msg[*pLength]), 0, 32);
8460 *pLength += 32;
8461 p_na_msg += 32;
8462
8463 /* ICMPv6 */
8464 /* 1. Type : 0x88 (NA)
8465 * 2. Code : 0x00
8466 * 3. ChechSum : 0x00 0x00 (RSvd)
8467 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
8468 */
8469 val8 = sizeof(icmpv6_hdr);
8470 _rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
8471 *pLength += val8;
8472 p_na_msg += val8;
8473
8474 /* TA: 16 bytes*/
8475 _rtw_memset(&(p_na_msg[*pLength]), 0, 16);
8476 *pLength += 16;
8477 p_na_msg += 16;
8478
8479 /* ICMPv6 Target Link Layer Address */
8480 p_na_msg[0] = 0x02; /* type */
8481 p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
8482 *pLength += 2;
8483 p_na_msg += 2;
8484
8485 _rtw_memset(&(p_na_msg[*pLength]), 0, 6);
8486 *pLength += 6;
8487 p_na_msg += 6;
8488
8489 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8490 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8491 IS_HARDWARE_TYPE_8812(padapter)) {
8492 rtw_hal_append_tkip_mic(padapter, pframe,
8493 na_msg_offset);
8494 }
8495 *pLength += 8;
8496 }
8497 }
8498 /*
8499 * Description: Neighbor Discovery Protocol Information.
8500 */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)8501 static void rtw_hal_construct_ndp_info(_adapter *padapter,
8502 u8 *pframe, u32 *pLength)
8503 {
8504 struct mlme_ext_priv *pmlmeext = NULL;
8505 struct mlme_ext_info *pmlmeinfo = NULL;
8506 struct rtw_ndp_info ndp_info;
8507 u8 *pndp_info = pframe;
8508 u8 len = sizeof(struct rtw_ndp_info);
8509
8510 RTW_INFO("%s: len: %d\n", __func__, len);
8511
8512 pmlmeext = &padapter->mlmeextpriv;
8513 pmlmeinfo = &pmlmeext->mlmext_info;
8514
8515 _rtw_memset(pframe, 0, len);
8516 _rtw_memset(&ndp_info, 0, len);
8517
8518 ndp_info.enable = 1;
8519 ndp_info.check_remote_ip = 0;
8520 ndp_info.num_of_target_ip = 1;
8521
8522 _rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
8523 ETH_ALEN);
8524 _rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
8525 RTW_IPv6_ADDR_LEN);
8526
8527 _rtw_memcpy(pndp_info, &ndp_info, len);
8528 }
8529 #endif /* CONFIG_IPV6 */
8530
8531 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)8532 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
8533 u32 *pLength, pno_ssid_t *ssid)
8534 {
8535 struct rtw_ieee80211_hdr *pwlanhdr;
8536 u16 *fctrl;
8537 u32 pktlen;
8538 unsigned char *mac;
8539 unsigned char bssrate[NumRates];
8540 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8541 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8542 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8543 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8544 int bssrate_len = 0;
8545 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8546
8547 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8548 mac = adapter_mac_addr(padapter);
8549
8550 fctrl = &(pwlanhdr->frame_ctl);
8551 *(fctrl) = 0;
8552
8553 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8554 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8555
8556 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8557
8558 SetSeqNum(pwlanhdr, 0);
8559 set_frame_sub_type(pframe, WIFI_PROBEREQ);
8560
8561 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8562 pframe += pktlen;
8563
8564 if (ssid == NULL)
8565 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
8566 else {
8567 /* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
8568 pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
8569 }
8570
8571 get_rate_set(padapter, bssrate, &bssrate_len);
8572
8573 if (bssrate_len > 8) {
8574 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
8575 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
8576 } else
8577 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
8578
8579 *pLength = pktlen;
8580 }
8581
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)8582 static void rtw_hal_construct_PNO_info(_adapter *padapter,
8583 u8 *pframe, u32 *pLength)
8584 {
8585 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8586 int i;
8587
8588 u8 *pPnoInfoPkt = pframe;
8589 pPnoInfoPkt = (u8 *)(pframe + *pLength);
8590 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
8591
8592 pPnoInfoPkt += 1;
8593 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
8594
8595 pPnoInfoPkt += 3;
8596 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
8597
8598 pPnoInfoPkt += 4;
8599 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
8600
8601 pPnoInfoPkt += 4;
8602 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
8603
8604 pPnoInfoPkt += 4;
8605 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
8606
8607 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8608 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
8609
8610 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8611 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
8612
8613 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8614 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
8615
8616 pPnoInfoPkt += MAX_HIDDEN_AP;
8617
8618 /*
8619 SSID is located at 128th Byte in NLO info Page
8620 */
8621
8622 *pLength += 128;
8623 pPnoInfoPkt = pframe + 128;
8624
8625 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8626 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8627 pwrctl->pnlo_info->ssid_length[i]);
8628 *pLength += WLAN_SSID_MAXLEN;
8629 pPnoInfoPkt += WLAN_SSID_MAXLEN;
8630 }
8631 }
8632
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)8633 static void rtw_hal_construct_ssid_list(_adapter *padapter,
8634 u8 *pframe, u32 *pLength)
8635 {
8636 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8637 u8 *pSSIDListPkt = pframe;
8638 int i;
8639
8640 pSSIDListPkt = (u8 *)(pframe + *pLength);
8641
8642 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8643 _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8644 pwrctl->pnlo_info->ssid_length[i]);
8645
8646 *pLength += WLAN_SSID_MAXLEN;
8647 pSSIDListPkt += WLAN_SSID_MAXLEN;
8648 }
8649 }
8650
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)8651 static void rtw_hal_construct_scan_info(_adapter *padapter,
8652 u8 *pframe, u32 *pLength)
8653 {
8654 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8655 u8 *pScanInfoPkt = pframe;
8656 int i;
8657
8658 pScanInfoPkt = (u8 *)(pframe + *pLength);
8659
8660 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
8661
8662 *pLength += 1;
8663 pScanInfoPkt += 1;
8664 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
8665
8666
8667 *pLength += 1;
8668 pScanInfoPkt += 1;
8669 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
8670
8671
8672 *pLength += 1;
8673 pScanInfoPkt += 1;
8674 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
8675
8676 *pLength += 1;
8677 pScanInfoPkt += 1;
8678 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
8679
8680 *pLength += 1;
8681 pScanInfoPkt += 1;
8682 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
8683
8684 *pLength += 1;
8685 pScanInfoPkt += 1;
8686 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
8687
8688 *pLength += 1;
8689 pScanInfoPkt += 1;
8690 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
8691
8692 *pLength += 1;
8693 pScanInfoPkt += 1;
8694 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
8695
8696 *pLength += 8;
8697 pScanInfoPkt += 8;
8698
8699 for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
8700 _rtw_memcpy(pScanInfoPkt,
8701 &pwrctl->pscan_info->ssid_channel_info[i], 4);
8702 *pLength += 4;
8703 pScanInfoPkt += 4;
8704 }
8705 }
8706 #endif /* CONFIG_PNO_SUPPORT */
8707
8708 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)8709 static void rtw_hal_construct_GTKRsp(
8710 PADAPTER padapter,
8711 u8 *pframe,
8712 u32 *pLength
8713 )
8714 {
8715 struct rtw_ieee80211_hdr *pwlanhdr;
8716 u16 *fctrl;
8717 u32 pktlen;
8718 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8719 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8720 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8721 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8722 struct security_priv *psecuritypriv = &padapter->securitypriv;
8723 static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
8724 static u8 GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
8725 u8 *pGTKRspPkt = pframe;
8726 u8 EncryptionHeadOverhead = 0;
8727 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8728
8729 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8730
8731 fctrl = &pwlanhdr->frame_ctl;
8732 *(fctrl) = 0;
8733
8734 /* ------------------------------------------------------------------------- */
8735 /* MAC Header. */
8736 /* ------------------------------------------------------------------------- */
8737 SetFrameType(fctrl, WIFI_DATA);
8738 /* set_frame_sub_type(fctrl, 0); */
8739 SetToDs(fctrl);
8740
8741 _rtw_memcpy(pwlanhdr->addr1,
8742 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8743
8744 _rtw_memcpy(pwlanhdr->addr2,
8745 adapter_mac_addr(padapter), ETH_ALEN);
8746
8747 _rtw_memcpy(pwlanhdr->addr3,
8748 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8749
8750 SetSeqNum(pwlanhdr, 0);
8751 set_duration(pwlanhdr, 0);
8752
8753 #ifdef CONFIG_WAPI_SUPPORT
8754 *pLength = sMacHdrLng;
8755 #else
8756 *pLength = 24;
8757 #endif /* CONFIG_WAPI_SUPPORT */
8758
8759 /* ------------------------------------------------------------------------- */
8760 /* Security Header: leave space for it if necessary. */
8761 /* ------------------------------------------------------------------------- */
8762 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8763 case _WEP40_:
8764 case _WEP104_:
8765 EncryptionHeadOverhead = 4;
8766 break;
8767 case _TKIP_:
8768 EncryptionHeadOverhead = 8;
8769 break;
8770 case _AES_:
8771 EncryptionHeadOverhead = 8;
8772 break;
8773 #ifdef CONFIG_WAPI_SUPPORT
8774 case _SMS4_:
8775 EncryptionHeadOverhead = 18;
8776 break;
8777 #endif /* CONFIG_WAPI_SUPPORT */
8778 default:
8779 EncryptionHeadOverhead = 0;
8780 }
8781
8782 if (EncryptionHeadOverhead > 0) {
8783 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8784 *pLength += EncryptionHeadOverhead;
8785 /* SET_80211_HDR_WEP(pGTKRspPkt, 1); */ /* Suggested by CCW. */
8786 /* GTK's privacy bit is done by FW */
8787 /* SetPrivacy(fctrl); */
8788 }
8789 /* ------------------------------------------------------------------------- */
8790 /* Frame Body. */
8791 /* ------------------------------------------------------------------------- */
8792 pGTKRspPkt = (u8 *)(pframe + *pLength);
8793 /* LLC header */
8794 _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
8795 *pLength += 8;
8796
8797 /* GTK element */
8798 pGTKRspPkt += 8;
8799
8800 /* GTK frame body after LLC, part 1 */
8801 /* TKIP key_length = 32, AES key_length = 16 */
8802 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8803 GTKbody_a[8] = 0x20;
8804
8805 /* GTK frame body after LLC, part 1 */
8806 _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
8807 *pLength += 11;
8808 pGTKRspPkt += 11;
8809 /* GTK frame body after LLC, part 2 */
8810 _rtw_memset(&(pframe[*pLength]), 0, 88);
8811 *pLength += 88;
8812 pGTKRspPkt += 88;
8813
8814 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
8815 *pLength += 8;
8816 }
8817 #endif /* CONFIG_GTK_OL */
8818
8819 #define PN_2_CCMPH(ch,key_id) ((ch) & 0x000000000000ffff) \
8820 | (((ch) & 0x0000ffffffff0000) << 16) \
8821 | (((key_id) << 30)) \
8822 | BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)8823 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
8824 u8 *pframe, u32 *pLength)
8825 {
8826 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8827 struct sta_priv *pstapriv = &adapter->stapriv;
8828 struct security_priv *psecuritypriv = &adapter->securitypriv;
8829 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
8830 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8831 struct sta_info *psta;
8832 struct stainfo_rxcache *prxcache;
8833 u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
8834 size_t sz = 0, total = 0;
8835 u64 ccmp_hdr = 0, tmp_key = 0;
8836
8837 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8838
8839 if (psta == NULL) {
8840 rtw_warn_on(1);
8841 return;
8842 }
8843
8844 prxcache = &psta->sta_recvpriv.rxcache;
8845 sz = sizeof(cur_dot11rxiv);
8846
8847 /* 3 SEC IV * 1 page */
8848 rtw_get_sec_iv(adapter, cur_dot11rxiv,
8849 get_my_bssid(&pmlmeinfo->network));
8850
8851 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
8852 *pLength += sz;
8853 pframe += sz;
8854
8855 _rtw_memset(&cur_dot11rxiv, 0, sz);
8856
8857 if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
8858 id = psecuritypriv->dot118021XGrpKeyid;
8859 tid_id = prxcache->last_tid;
8860 REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
8861 REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
8862 REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
8863 REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
8864 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
8865 *pLength += sz;
8866 pframe += sz;
8867
8868 _rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
8869 *pLength += sz;
8870 pframe += sz;
8871
8872 total = sizeof(psecuritypriv->iv_seq);
8873 total /= sizeof(psecuritypriv->iv_seq[0]);
8874
8875 for (i = 0 ; i < total ; i ++) {
8876 ccmp_hdr =
8877 le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
8878 _rtw_memset(&cur_dot11rxiv, 0, sz);
8879 if (ccmp_hdr != 0) {
8880 tmp_key = i;
8881 ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
8882 *(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
8883 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
8884 }
8885 *pLength += sz;
8886 pframe += sz;
8887 }
8888 }
8889 }
8890
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)8891 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
8892 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
8893 RSVDPAGE_LOC *rsvd_page_loc)
8894 {
8895 struct security_priv *psecuritypriv = &adapter->securitypriv;
8896 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8897 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
8898 struct mlme_ext_priv *pmlmeext;
8899 struct mlme_ext_info *pmlmeinfo;
8900 u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
8901 u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;
8902 u8 CurtPktPageNum = 0;
8903
8904 #ifdef CONFIG_GTK_OL
8905 struct sta_priv *pstapriv = &adapter->stapriv;
8906 struct sta_info *psta;
8907 struct security_priv *psecpriv = &adapter->securitypriv;
8908 u8 kek[RTW_KEK_LEN];
8909 u8 kck[RTW_KCK_LEN];
8910 #endif /* CONFIG_GTK_OL */
8911 #ifdef CONFIG_PNO_SUPPORT
8912 int pno_index;
8913 u8 ssid_num;
8914 #endif /* CONFIG_PNO_SUPPORT */
8915
8916 pmlmeext = &adapter->mlmeextpriv;
8917 pmlmeinfo = &pmlmeext->mlmext_info;
8918
8919 if (pwrctl->wowlan_pno_enable == _FALSE) {
8920 /* ARP RSP * 1 page */
8921
8922 rsvd_page_loc->LocArpRsp = *page_num;
8923
8924 RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
8925
8926 rtw_hal_construct_ARPRsp(adapter, &pframe[index],
8927 &ARPLength, pmlmeinfo->ip_addr);
8928
8929 rtw_hal_fill_fake_txdesc(adapter,
8930 &pframe[index - tx_desc],
8931 ARPLength, _FALSE, _FALSE, _TRUE);
8932
8933 CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
8934
8935 *page_num += CurtPktPageNum;
8936
8937 index += (CurtPktPageNum * page_size);
8938 RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
8939
8940 #ifdef CONFIG_IPV6
8941 /* 2 NS offload and NDP Info*/
8942 if (pwrctl->wowlan_ns_offload_en == _TRUE) {
8943 rsvd_page_loc->LocNbrAdv = *page_num;
8944 RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
8945 rtw_hal_construct_na_message(adapter,
8946 &pframe[index], &ns_len);
8947 rtw_hal_fill_fake_txdesc(adapter,
8948 &pframe[index - tx_desc],
8949 ns_len, _FALSE,
8950 _FALSE, _TRUE);
8951 CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
8952 page_size);
8953 *page_num += CurtPktPageNum;
8954 index += (CurtPktPageNum * page_size);
8955 RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
8956
8957 rsvd_page_loc->LocNDPInfo = *page_num;
8958 RTW_INFO("LocNDPInfo: %d\n",
8959 rsvd_page_loc->LocNDPInfo);
8960
8961 rtw_hal_construct_ndp_info(adapter,
8962 &pframe[index - tx_desc],
8963 &ns_len);
8964 CurtPktPageNum =
8965 (u8)PageNum(tx_desc + ns_len, page_size);
8966 *page_num += CurtPktPageNum;
8967 index += (CurtPktPageNum * page_size);
8968 RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
8969
8970 }
8971 #endif /*CONFIG_IPV6*/
8972 /* 3 Remote Control Info. * 1 page */
8973 rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
8974 RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
8975 rtw_hal_construct_remote_control_info(adapter,
8976 &pframe[index - tx_desc],
8977 &rc_len);
8978 CurtPktPageNum = (u8)PageNum(rc_len, page_size);
8979 *page_num += CurtPktPageNum;
8980 *total_pkt_len = index + rc_len;
8981 RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
8982 #ifdef CONFIG_GTK_OL
8983 index += (CurtPktPageNum * page_size);
8984
8985 /* if the ap staion info. exists, get the kek, kck from staion info. */
8986 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
8987 if (psta == NULL) {
8988 _rtw_memset(kek, 0, RTW_KEK_LEN);
8989 _rtw_memset(kck, 0, RTW_KCK_LEN);
8990 RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
8991 __func__);
8992 } else {
8993 _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
8994 _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
8995 }
8996
8997 /* 3 KEK, KCK */
8998 rsvd_page_loc->LocGTKInfo = *page_num;
8999 RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
9000
9001 if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
9002 struct security_priv *psecpriv = NULL;
9003
9004 psecpriv = &adapter->securitypriv;
9005 _rtw_memcpy(pframe + index - tx_desc,
9006 &psecpriv->dot11PrivacyAlgrthm, 1);
9007 _rtw_memcpy(pframe + index - tx_desc + 1,
9008 &psecpriv->dot118021XGrpPrivacy, 1);
9009 _rtw_memcpy(pframe + index - tx_desc + 2,
9010 kck, RTW_KCK_LEN);
9011 _rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
9012 kek, RTW_KEK_LEN);
9013 CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
9014 } else {
9015
9016 _rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
9017 _rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
9018 kek, RTW_KEK_LEN);
9019 GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
9020
9021 if (psta != NULL &&
9022 psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
9023 _rtw_memcpy(pframe + index - tx_desc + 56,
9024 &psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
9025 GTKLength += RTW_TKIP_MIC_LEN;
9026 }
9027 CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
9028 }
9029 #if 0
9030 {
9031 int i;
9032 printk("\ntoFW KCK: ");
9033 for (i = 0; i < 16; i++)
9034 printk(" %02x ", kck[i]);
9035 printk("\ntoFW KEK: ");
9036 for (i = 0; i < 16; i++)
9037 printk(" %02x ", kek[i]);
9038 printk("\n");
9039 }
9040
9041 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
9042 __FUNCTION__, &pframe[index - tx_desc],
9043 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
9044 #endif
9045
9046 *page_num += CurtPktPageNum;
9047
9048 index += (CurtPktPageNum * page_size);
9049 RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
9050
9051 /* 3 GTK Response */
9052 rsvd_page_loc->LocGTKRsp = *page_num;
9053 RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
9054 rtw_hal_construct_GTKRsp(adapter, &pframe[index], >KLength);
9055
9056 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
9057 GTKLength, _FALSE, _FALSE, _TRUE);
9058 #if 0
9059 {
9060 int gj;
9061 printk("123GTK pkt=>\n");
9062 for (gj = 0; gj < GTKLength + tx_desc; gj++) {
9063 printk(" %02x ", pframe[index - tx_desc + gj]);
9064 if ((gj + 1) % 16 == 0)
9065 printk("\n");
9066 }
9067 printk(" <=end\n");
9068 }
9069
9070 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
9071 __FUNCTION__, &pframe[index - tx_desc],
9072 (tx_desc + GTKLength));
9073 #endif
9074
9075 CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
9076
9077 *page_num += CurtPktPageNum;
9078
9079 index += (CurtPktPageNum * page_size);
9080 RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
9081
9082 /* below page is empty for GTK extension memory */
9083 /* 3(11) GTK EXT MEM */
9084 rsvd_page_loc->LocGTKEXTMEM = *page_num;
9085 RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
9086 CurtPktPageNum = 2;
9087
9088 if (page_size >= 256)
9089 CurtPktPageNum = 1;
9090
9091 *page_num += CurtPktPageNum;
9092 /* extension memory for FW */
9093 *total_pkt_len = index + (page_size * CurtPktPageNum);
9094 RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
9095 #endif /* CONFIG_GTK_OL */
9096
9097 index += (CurtPktPageNum * page_size);
9098
9099 /*Reserve 1 page for AOAC report*/
9100 rsvd_page_loc->LocAOACReport = *page_num;
9101 RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
9102 *page_num += 1;
9103 *total_pkt_len = index + (page_size * 1);
9104 RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
9105 } else {
9106 #ifdef CONFIG_PNO_SUPPORT
9107 if (pwrctl->wowlan_in_resume == _FALSE &&
9108 pwrctl->pno_inited == _TRUE) {
9109
9110 /* Broadcast Probe Request */
9111 rsvd_page_loc->LocProbePacket = *page_num;
9112
9113 RTW_INFO("loc_probe_req: %d\n",
9114 rsvd_page_loc->LocProbePacket);
9115
9116 rtw_hal_construct_ProbeReq(
9117 adapter,
9118 &pframe[index],
9119 &ProbeReqLength,
9120 NULL);
9121
9122 rtw_hal_fill_fake_txdesc(adapter,
9123 &pframe[index - tx_desc],
9124 ProbeReqLength, _FALSE, _FALSE, _FALSE);
9125
9126 CurtPktPageNum =
9127 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
9128
9129 *page_num += CurtPktPageNum;
9130
9131 index += (CurtPktPageNum * page_size);
9132 RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9133
9134 /* Hidden SSID Probe Request */
9135 ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
9136
9137 for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
9138 pwrctl->pnlo_info->loc_probe_req[pno_index] =
9139 *page_num;
9140
9141 rtw_hal_construct_ProbeReq(
9142 adapter,
9143 &pframe[index],
9144 &ProbeReqLength,
9145 &pwrctl->pno_ssid_list->node[pno_index]);
9146
9147 rtw_hal_fill_fake_txdesc(adapter,
9148 &pframe[index - tx_desc],
9149 ProbeReqLength, _FALSE, _FALSE, _FALSE);
9150
9151 CurtPktPageNum =
9152 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
9153
9154 *page_num += CurtPktPageNum;
9155
9156 index += (CurtPktPageNum * page_size);
9157 RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9158 }
9159
9160 /* PNO INFO Page */
9161 rsvd_page_loc->LocPNOInfo = *page_num;
9162 RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
9163 rtw_hal_construct_PNO_info(adapter,
9164 &pframe[index - tx_desc],
9165 &PNOLength);
9166
9167 CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
9168 *page_num += CurtPktPageNum;
9169 index += (CurtPktPageNum * page_size);
9170 RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
9171
9172 /* Scan Info Page */
9173 rsvd_page_loc->LocScanInfo = *page_num;
9174 RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
9175 rtw_hal_construct_scan_info(adapter,
9176 &pframe[index - tx_desc],
9177 &ScanInfoLength);
9178
9179 CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
9180 *page_num += CurtPktPageNum;
9181 *total_pkt_len = index + ScanInfoLength;
9182 index += (CurtPktPageNum * page_size);
9183 RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
9184 }
9185 #endif /* CONFIG_PNO_SUPPORT */
9186 }
9187 }
9188
rtw_hal_gate_bb(_adapter * adapter,bool stop)9189 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
9190 {
9191 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9192 u8 i = 0, val8 = 0, empty = _FAIL;
9193
9194 if (stop) {
9195 /* checking TX queue status */
9196 for (i = 0 ; i < 5 ; i++) {
9197 rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
9198 if (empty) {
9199 break;
9200 } else {
9201 RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
9202 __func__, i);
9203 rtw_mdelay_os(10);
9204 }
9205 }
9206
9207 if (val8 == 5)
9208 RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
9209
9210 /* Pause TX*/
9211 pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
9212 rtw_write8(adapter, REG_TXPAUSE, 0xff);
9213 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9214 val8 &= ~BIT(0);
9215 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9216 RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
9217 __func__,
9218 rtw_read8(adapter, REG_SYS_FUNC_EN),
9219 pwrpriv->wowlan_txpause_status);
9220 } else {
9221 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9222 val8 |= BIT(0);
9223 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9224 RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
9225 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
9226 pwrpriv->wowlan_txpause_status);
9227 /* release TX*/
9228 rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
9229 }
9230 }
9231
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)9232 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
9233 {
9234 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9235 u8 *pattern;
9236 u8 len = 0;
9237 u8 *mask;
9238
9239 u8 mask_hw[MAX_WKFM_SIZE] = {0};
9240 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9241 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9242 u8 multicast_addr1[2] = {0x33, 0x33};
9243 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9244 u8 mask_len = 0;
9245 u8 mac_addr[ETH_ALEN] = {0};
9246 u16 count = 0;
9247 int i;
9248
9249 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9250 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9251 __func__, MAX_WKFM_CAM_NUM);
9252 return _FAIL;
9253 }
9254
9255 pattern = pwrctl->patterns[idx].content;
9256 len = pwrctl->patterns[idx].len;
9257 mask = pwrctl->patterns[idx].mask;
9258
9259 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9260 _rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
9261
9262 mask_len = DIV_ROUND_UP(len, 8);
9263
9264 /* 1. setup A1 table */
9265 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9266 pwow_pattern->type = PATTERN_BROADCAST;
9267 else if (memcmp(pattern, multicast_addr1, 2) == 0)
9268 pwow_pattern->type = PATTERN_MULTICAST;
9269 else if (memcmp(pattern, multicast_addr2, 3) == 0)
9270 pwow_pattern->type = PATTERN_MULTICAST;
9271 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9272 pwow_pattern->type = PATTERN_UNICAST;
9273 else
9274 pwow_pattern->type = PATTERN_INVALID;
9275
9276 /* translate mask from os to mask for hw */
9277
9278 /******************************************************************************
9279 * pattern from OS uses 'ethenet frame', like this:
9280
9281 | 6 | 6 | 2 | 20 | Variable | 4 |
9282 |--------+--------+------+-----------+------------+-----|
9283 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
9284 | DA | SA | Type |
9285
9286 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9287
9288 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
9289 |-------------------+--------+------+-----------+------------+-----|
9290 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
9291 | Others | Tpye |
9292
9293 * Therefore, we need translate mask_from_OS to mask_to_hw.
9294 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9295 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9296 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9297 ******************************************************************************/
9298 /* Shift 6 bits */
9299 for (i = 0; i < mask_len - 1; i++) {
9300 mask_hw[i] = mask[i] >> 6;
9301 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9302 }
9303
9304 mask_hw[i] = (mask[i] >> 6) & 0x3F;
9305 /* Set bit 0-5 to zero */
9306 mask_hw[0] &= 0xC0;
9307
9308 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9309 pwow_pattern->mask[i] = mask_hw[i * 4];
9310 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
9311 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
9312 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
9313 }
9314
9315 /* To get the wake up pattern from the mask.
9316 * We do not count first 12 bits which means
9317 * DA[6] and SA[6] in the pattern to match HW design. */
9318 count = 0;
9319 for (i = 12; i < len; i++) {
9320 if ((mask[i / 8] >> (i % 8)) & 0x01) {
9321 content[count] = pattern[i];
9322 count++;
9323 }
9324 }
9325
9326 pwow_pattern->crc = rtw_calc_crc(content, count);
9327
9328 if (pwow_pattern->crc != 0) {
9329 if (pwow_pattern->type == PATTERN_INVALID)
9330 pwow_pattern->type = PATTERN_VALID;
9331 }
9332
9333 return _SUCCESS;
9334 }
9335
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)9336 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
9337 {
9338 int j;
9339
9340 RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
9341 RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
9342 RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
9343 for (j = 0; j < 4; j++)
9344 RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
9345 }
9346 /*bit definition of pattern match format*/
9347 #define WOW_VALID_BIT BIT31
9348 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
9349 #define WOW_BC_BIT BIT26
9350 #define WOW_MC_BIT BIT25
9351 #define WOW_UC_BIT BIT24
9352 #else
9353 #define WOW_BC_BIT BIT18
9354 #define WOW_UC_BIT BIT17
9355 #define WOW_MC_BIT BIT16
9356 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
9357
9358 #ifndef CONFIG_WOW_PATTERN_HW_CAM
9359 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_hal_reset_mac_rx(_adapter * adapter)9360 static void rtw_hal_reset_mac_rx(_adapter *adapter)
9361 {
9362 u8 val8 = 0;
9363 /* Set REG_CR bit1, bit3, bit7 to 0*/
9364 val8 = rtw_read8(adapter, REG_CR);
9365 val8 &= 0x75;
9366 rtw_write8(adapter, REG_CR, val8);
9367 val8 = rtw_read8(adapter, REG_CR);
9368 /* Set REG_CR bit1, bit3, bit7 to 1*/
9369 val8 |= 0x8a;
9370 rtw_write8(adapter, REG_CR, val8);
9371 RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
9372 }
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)9373 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
9374 {
9375 u8 val8 = 0;
9376 u16 rxff_bndy = 0;
9377 u32 rx_dma_buff_sz = 0;
9378
9379 val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
9380 if (val8 != 0)
9381 RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
9382 __func__, (REG_FIFOPAGE + 3));
9383
9384 rtw_hal_reset_mac_rx(adapter);
9385
9386 if (wow_mode) {
9387 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9388 (u8 *)&rx_dma_buff_sz);
9389 rxff_bndy = rx_dma_buff_sz - 1;
9390
9391 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9392 RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
9393 REG_TRXFF_BNDY + 2,
9394 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9395 } else {
9396 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
9397 (u8 *)&rx_dma_buff_sz);
9398 rxff_bndy = rx_dma_buff_sz - 1;
9399 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9400 RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
9401 REG_TRXFF_BNDY + 2,
9402 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9403 }
9404 }
9405 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO*/
9406 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9407 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9408 {
9409 u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9410 u16 offset, rx_buf_ptr = 0;
9411 u16 cam_start_offset = 0;
9412 u16 ctrl_l = 0, ctrl_h = 0;
9413 u8 count = 0, tmp = 0;
9414 int i = 0;
9415 bool res = _TRUE;
9416
9417 if (idx > MAX_WKFM_CAM_NUM) {
9418 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9419 __func__);
9420 return _FALSE;
9421 }
9422
9423 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9424 (u8 *)&rx_dma_buff_sz);
9425
9426 if (rx_dma_buff_sz == 0) {
9427 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9428 return _FALSE;
9429 }
9430
9431 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9432
9433 if (page_sz == 0) {
9434 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9435 return _FALSE;
9436 }
9437
9438 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9439 cam_start_offset = offset * page_sz;
9440
9441 ctrl_l = 0x0;
9442 ctrl_h = 0x0;
9443
9444 /* Enable RX packet buffer access */
9445 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9446
9447 /* Read the WKFM CAM */
9448 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9449 /*
9450 * Set Rx packet buffer offset.
9451 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9452 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9453 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9454 * * Index: The index of the wake up frame mask
9455 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9456 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9457 */
9458 rx_buf_ptr =
9459 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9460 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9461
9462 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9463 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9464 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9465
9466 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9467
9468 count = 0;
9469
9470 do {
9471 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9472 rtw_udelay_os(2);
9473 count++;
9474 } while (!tmp && count < 100);
9475
9476 if (count >= 100) {
9477 RTW_INFO("%s count:%d\n", __func__, count);
9478 res = _FALSE;
9479 }
9480 }
9481
9482 /* Disable RX packet buffer access */
9483 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9484 DISABLE_TRXPKT_BUF_ACCESS);
9485 return res;
9486 }
9487
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9488 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9489 struct rtl_wow_pattern *context)
9490 {
9491 u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
9492 u16 offset, rx_buf_ptr = 0;
9493 u16 cam_start_offset = 0;
9494 u16 ctrl_l = 0, ctrl_h = 0;
9495 u8 count = 0, tmp = 0;
9496 int res = 0, i = 0;
9497
9498 if (idx > MAX_WKFM_CAM_NUM) {
9499 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9500 __func__);
9501 return _FALSE;
9502 }
9503
9504 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9505 (u8 *)&rx_dma_buff_sz);
9506
9507 if (rx_dma_buff_sz == 0) {
9508 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9509 return _FALSE;
9510 }
9511
9512 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9513
9514 if (page_sz == 0) {
9515 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9516 return _FALSE;
9517 }
9518
9519 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9520
9521 cam_start_offset = offset * page_sz;
9522
9523 if (IS_HARDWARE_TYPE_8188E(adapter)) {
9524 ctrl_l = 0x0001;
9525 ctrl_h = 0x0001;
9526 } else {
9527 ctrl_l = 0x0f01;
9528 ctrl_h = 0xf001;
9529 }
9530
9531 /* Enable RX packet buffer access */
9532 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9533
9534 /* Write the WKFM CAM */
9535 for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
9536 /*
9537 * Set Rx packet buffer offset.
9538 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9539 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9540 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9541 * * Index: The index of the wake up frame mask
9542 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9543 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9544 */
9545 rx_buf_ptr =
9546 (cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
9547 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9548
9549 if (i == 0) {
9550 if (context->type == PATTERN_VALID)
9551 data = WOW_VALID_BIT;
9552 else if (context->type == PATTERN_BROADCAST)
9553 data = WOW_VALID_BIT | WOW_BC_BIT;
9554 else if (context->type == PATTERN_MULTICAST)
9555 data = WOW_VALID_BIT | WOW_MC_BIT;
9556 else if (context->type == PATTERN_UNICAST)
9557 data = WOW_VALID_BIT | WOW_UC_BIT;
9558
9559 if (context->crc != 0)
9560 data |= context->crc;
9561
9562 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9563 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9564 } else if (i == 1) {
9565 data = 0;
9566 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9567 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9568 } else if (i == 2 || i == 4) {
9569 data = context->mask[i - 2];
9570 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9571 /* write to RX packet buffer*/
9572 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9573 } else if (i == 3 || i == 5) {
9574 data = context->mask[i - 2];
9575 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9576 /* write to RX packet buffer*/
9577 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9578 }
9579
9580 count = 0;
9581 do {
9582 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9583 rtw_udelay_os(2);
9584 count++;
9585 } while (tmp && count < 100);
9586
9587 if (count >= 100)
9588 res = _FALSE;
9589 else
9590 res = _TRUE;
9591 }
9592
9593 /* Disable RX packet buffer access */
9594 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9595 DISABLE_TRXPKT_BUF_ACCESS);
9596
9597 return res;
9598 }
9599 #else /* CONFIG_WOW_PATTERN_IN_TXFIFO */
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9600 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9601 {
9602 u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9603 u16 tx_page_start, tx_buf_ptr = 0;
9604 u16 cam_start_offset = 0;
9605 u16 ctrl_l = 0, ctrl_h = 0;
9606 u8 count = 0, tmp = 0, last_entry = 0;
9607 int i = 0;
9608 bool res = _TRUE;
9609
9610 if (idx > MAX_WKFM_CAM_NUM) {
9611 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9612 __func__);
9613 return _FALSE;
9614 }
9615
9616 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9617 if (page_sz == 0) {
9618 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9619 return _FALSE;
9620 }
9621
9622 rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9623 if (last_entry == 0) {
9624 RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9625 return _FALSE;
9626 }
9627
9628 /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9629 tx_page_start = last_entry - 1;
9630 cam_start_offset = tx_page_start * page_sz / 8;
9631 ctrl_l = 0x0;
9632 ctrl_h = 0x0;
9633
9634 /* Enable TX packet buffer access */
9635 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9636
9637 /* Read the WKFM CAM */
9638 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9639 /*
9640 * Set Tx packet buffer offset.
9641 * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer.
9642 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9643 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9644 * * Index: The index of the wake up frame mask
9645 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9646 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9647 */
9648 tx_buf_ptr =
9649 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9650 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr);
9651 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9652 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9653 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9654
9655 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9656
9657 count = 0;
9658
9659 do {
9660 tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9661 rtw_udelay_os(2);
9662 count++;
9663 } while (!tmp && count < 100);
9664
9665 if (count >= 100) {
9666 RTW_INFO("%s count:%d\n", __func__, count);
9667 res = _FALSE;
9668 }
9669 }
9670
9671 /* Disable RX packet buffer access */
9672 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9673 DISABLE_TRXPKT_BUF_ACCESS);
9674 return res;
9675 }
9676
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9677 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9678 struct rtl_wow_pattern *context)
9679 {
9680 u32 tx_page_start = 0, page_sz = 0;
9681 u16 tx_buf_ptr = 0;
9682 u16 cam_start_offset = 0;
9683 u32 data_l = 0, data_h = 0;
9684 u8 count = 0, tmp = 0, last_entry = 0;
9685 int res = 0, i = 0;
9686
9687 if (idx > MAX_WKFM_CAM_NUM) {
9688 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9689 __func__);
9690 return _FALSE;
9691 }
9692
9693 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9694 if (page_sz == 0) {
9695 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9696 return _FALSE;
9697 }
9698
9699 rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9700 if (last_entry == 0) {
9701 RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9702 return _FALSE;
9703 }
9704
9705 /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9706 tx_page_start = last_entry - 1;
9707 cam_start_offset = tx_page_start * page_sz / 8;
9708
9709 /* Write the PATTERN location to BIT_TXBUF_WKCAM_OFFSET */
9710 rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET, cam_start_offset & 0xFF);
9711 rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET + 1, (cam_start_offset >> 8) & 0xFF);
9712 /* Enable TX packet buffer access */
9713 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9714
9715 /* Write the WKFM CAM */
9716 for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9717 /*
9718 * Set Tx packet buffer offset.
9719 * TxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9720 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9721 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9722 * * Index: The index of the wake up frame mask
9723 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9724 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9725 */
9726 tx_buf_ptr = cam_start_offset + ((idx * WKFMCAM_SIZE + i * 8) >> 3);
9727
9728 if (i == 0) {
9729 if (context->type == PATTERN_VALID)
9730 data_l = WOW_VALID_BIT;
9731 else if (context->type == PATTERN_BROADCAST)
9732 data_l = WOW_VALID_BIT | WOW_BC_BIT;
9733 else if (context->type == PATTERN_MULTICAST)
9734 data_l = WOW_VALID_BIT | WOW_MC_BIT;
9735 else if (context->type == PATTERN_UNICAST)
9736 data_l = WOW_VALID_BIT | WOW_UC_BIT;
9737
9738 if (context->crc != 0)
9739 data_l |= context->crc;
9740
9741 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9742 } else {
9743 data_l = context->mask[i * 2 - 2];
9744 data_h = context->mask[i * 2 - 1];
9745 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9746 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h);
9747 }
9748
9749 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0x1FFF) | BIT23 | (0xff <<24));
9750 count = 0;
9751 do {
9752 tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9753 rtw_udelay_os(2);
9754 count++;
9755 } while (tmp && count < 100);
9756
9757 if (count >= 100) {
9758 res = _FALSE;
9759 RTW_INFO("%s write failed\n", __func__);
9760 } else {
9761 res = _TRUE;
9762 RTW_INFO("%s write OK\n", __func__);
9763 }
9764 }
9765
9766 /* Disable TX packet buffer access */
9767 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
9768 return res;
9769 }
9770 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
9771
rtw_clean_pattern(_adapter * adapter)9772 void rtw_clean_pattern(_adapter *adapter)
9773 {
9774 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9775 struct rtl_wow_pattern zero_pattern;
9776 int i = 0;
9777
9778 _rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
9779
9780 zero_pattern.type = PATTERN_INVALID;
9781
9782 for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
9783 rtw_write_to_frame_mask(adapter, i, &zero_pattern);
9784
9785 rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
9786 }
9787 #if 0
9788 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
9789 u8 len, u8 *mask, u8 idx)
9790 {
9791 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9792 struct mlme_ext_priv *pmlmeext = NULL;
9793 struct mlme_ext_info *pmlmeinfo = NULL;
9794 struct rtl_wow_pattern wow_pattern;
9795 u8 mask_hw[MAX_WKFM_SIZE] = {0};
9796 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9797 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9798 u8 multicast_addr1[2] = {0x33, 0x33};
9799 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9800 u8 res = _FALSE, index = 0, mask_len = 0;
9801 u8 mac_addr[ETH_ALEN] = {0};
9802 u16 count = 0;
9803 int i, j;
9804
9805 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9806 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9807 __func__, MAX_WKFM_CAM_NUM);
9808 return _FALSE;
9809 }
9810
9811 pmlmeext = &adapter->mlmeextpriv;
9812 pmlmeinfo = &pmlmeext->mlmext_info;
9813 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9814 _rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
9815
9816 mask_len = DIV_ROUND_UP(len, 8);
9817
9818 /* 1. setup A1 table */
9819 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9820 wow_pattern.type = PATTERN_BROADCAST;
9821 else if (memcmp(pattern, multicast_addr1, 2) == 0)
9822 wow_pattern.type = PATTERN_MULTICAST;
9823 else if (memcmp(pattern, multicast_addr2, 3) == 0)
9824 wow_pattern.type = PATTERN_MULTICAST;
9825 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9826 wow_pattern.type = PATTERN_UNICAST;
9827 else
9828 wow_pattern.type = PATTERN_INVALID;
9829
9830 /* translate mask from os to mask for hw */
9831
9832 /******************************************************************************
9833 * pattern from OS uses 'ethenet frame', like this:
9834
9835 | 6 | 6 | 2 | 20 | Variable | 4 |
9836 |--------+--------+------+-----------+------------+-----|
9837 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
9838 | DA | SA | Type |
9839
9840 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9841
9842 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
9843 |-------------------+--------+------+-----------+------------+-----|
9844 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
9845 | Others | Tpye |
9846
9847 * Therefore, we need translate mask_from_OS to mask_to_hw.
9848 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9849 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9850 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9851 ******************************************************************************/
9852 /* Shift 6 bits */
9853 for (i = 0; i < mask_len - 1; i++) {
9854 mask_hw[i] = mask[i] >> 6;
9855 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9856 }
9857
9858 mask_hw[i] = (mask[i] >> 6) & 0x3F;
9859 /* Set bit 0-5 to zero */
9860 mask_hw[0] &= 0xC0;
9861
9862 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9863 wow_pattern.mask[i] = mask_hw[i * 4];
9864 wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
9865 wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
9866 wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
9867 }
9868
9869 /* To get the wake up pattern from the mask.
9870 * We do not count first 12 bits which means
9871 * DA[6] and SA[6] in the pattern to match HW design. */
9872 count = 0;
9873 for (i = 12; i < len; i++) {
9874 if ((mask[i / 8] >> (i % 8)) & 0x01) {
9875 content[count] = pattern[i];
9876 count++;
9877 }
9878 }
9879
9880 wow_pattern.crc = rtw_calc_crc(content, count);
9881
9882 if (wow_pattern.crc != 0) {
9883 if (wow_pattern.type == PATTERN_INVALID)
9884 wow_pattern.type = PATTERN_VALID;
9885 }
9886
9887 index = idx;
9888
9889 if (!pwrctl->bInSuspend)
9890 index += 2;
9891
9892 /* write pattern */
9893 res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
9894
9895 if (res == _FALSE)
9896 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
9897 __func__, idx);
9898
9899 return res;
9900 }
9901 #endif
9902
rtw_fill_pattern(_adapter * adapter)9903 void rtw_fill_pattern(_adapter *adapter)
9904 {
9905 int i = 0, total = 0, index;
9906 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9907 struct rtl_wow_pattern wow_pattern;
9908
9909 total = pwrpriv->wowlan_pattern_idx;
9910
9911 if (total > MAX_WKFM_CAM_NUM)
9912 total = MAX_WKFM_CAM_NUM;
9913
9914 for (i = 0 ; i < total ; i++) {
9915 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
9916
9917 index = i;
9918 if (!pwrpriv->bInSuspend)
9919 index += 2;
9920 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
9921 if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
9922 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
9923 }
9924
9925 }
9926 rtw_write8(adapter, REG_WKFMCAM_NUM, total);
9927
9928 }
9929
9930 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
9931
9932 #define WOW_CAM_ACCESS_TIMEOUT_MS 200
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)9933 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
9934 {
9935 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9936 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
9937
9938 u32 rdata = 0;
9939 u32 cnt = 0;
9940 systime start = 0;
9941 u8 timeout = 0;
9942 u8 rst = _FALSE;
9943
9944 _enter_critical_mutex(mutex, NULL);
9945
9946 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
9947
9948 start = rtw_get_current_time();
9949 while (1) {
9950 if (rtw_is_surprise_removed(adapter))
9951 break;
9952
9953 cnt++;
9954 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
9955 rst = _SUCCESS;
9956 break;
9957 }
9958 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
9959 timeout = 1;
9960 break;
9961 }
9962 }
9963
9964 rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
9965
9966 _exit_critical_mutex(mutex, NULL);
9967
9968 /*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
9969
9970 if (timeout)
9971 RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
9972
9973 return rdata;
9974 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)9975 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
9976 {
9977 int i;
9978 u32 rdata;
9979
9980 _rtw_memset(context, 0, sizeof(struct rtl_wow_pattern));
9981
9982 for (i = 4; i >= 0; i--) {
9983 rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
9984
9985 switch (i) {
9986 case 4:
9987 if (rdata & WOW_BC_BIT)
9988 context->type = PATTERN_BROADCAST;
9989 else if (rdata & WOW_MC_BIT)
9990 context->type = PATTERN_MULTICAST;
9991 else if (rdata & WOW_UC_BIT)
9992 context->type = PATTERN_UNICAST;
9993 else
9994 context->type = PATTERN_INVALID;
9995
9996 context->crc = rdata & 0xFFFF;
9997 break;
9998 default:
9999 _rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
10000 break;
10001 }
10002 }
10003 }
10004
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)10005 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
10006 {
10007 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10008 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10009 u32 cnt = 0;
10010 systime start = 0, end = 0;
10011 u8 timeout = 0;
10012
10013 /*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
10014 _enter_critical_mutex(mutex, NULL);
10015
10016 rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
10017 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
10018
10019 start = rtw_get_current_time();
10020 while (1) {
10021 if (rtw_is_surprise_removed(adapter))
10022 break;
10023
10024 cnt++;
10025 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
10026 break;
10027
10028 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10029 timeout = 1;
10030 break;
10031 }
10032 }
10033 end = rtw_get_current_time();
10034
10035 _exit_critical_mutex(mutex, NULL);
10036
10037 if (timeout) {
10038 RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
10039 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
10040 }
10041 }
10042
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10043 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
10044 {
10045 int j;
10046 u8 addr;
10047 u32 wdata = 0;
10048
10049 for (j = 4; j >= 0; j--) {
10050 switch (j) {
10051 case 4:
10052 wdata = context->crc;
10053
10054 if (PATTERN_BROADCAST == context->type)
10055 wdata |= WOW_BC_BIT;
10056 if (PATTERN_MULTICAST == context->type)
10057 wdata |= WOW_MC_BIT;
10058 if (PATTERN_UNICAST == context->type)
10059 wdata |= WOW_UC_BIT;
10060 if (PATTERN_INVALID != context->type)
10061 wdata |= WOW_VALID_BIT;
10062 break;
10063 default:
10064 wdata = context->mask[j];
10065 break;
10066 }
10067
10068 addr = (id << 3) + j;
10069
10070 _rtw_wow_pattern_write_cam(adapter, addr, wdata);
10071 }
10072 }
10073
_rtw_wow_pattern_clean_cam(_adapter * adapter)10074 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
10075 {
10076 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10077 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10078 u32 cnt = 0;
10079 systime start = 0;
10080 u8 timeout = 0;
10081 u8 rst = _FAIL;
10082
10083 _enter_critical_mutex(mutex, NULL);
10084 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
10085
10086 start = rtw_get_current_time();
10087 while (1) {
10088 if (rtw_is_surprise_removed(adapter))
10089 break;
10090
10091 cnt++;
10092 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10093 rst = _SUCCESS;
10094 break;
10095 }
10096 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10097 timeout = 1;
10098 break;
10099 }
10100 }
10101 _exit_critical_mutex(mutex, NULL);
10102
10103 if (timeout)
10104 RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
10105
10106 return rst;
10107 }
10108
rtw_clean_pattern(_adapter * adapter)10109 void rtw_clean_pattern(_adapter *adapter)
10110 {
10111 if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
10112 RTW_ERR("rtw_clean_pattern failed\n");
10113 }
rtw_fill_pattern(_adapter * adapter)10114 void rtw_fill_pattern(_adapter *adapter)
10115 {
10116 int i = 0, total = 0;
10117 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10118 struct rtl_wow_pattern wow_pattern;
10119
10120 total = pwrpriv->wowlan_pattern_idx;
10121
10122 if (total > MAX_WKFM_CAM_NUM)
10123 total = MAX_WKFM_CAM_NUM;
10124
10125 for (i = 0 ; i < total ; i++) {
10126 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10127 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10128 rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
10129 }
10130 }
10131 }
10132
10133 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)10134 void rtw_wow_pattern_cam_dump(_adapter *adapter)
10135 {
10136
10137 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10138 int i;
10139
10140 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10141 RTW_INFO("=======[%d]=======\n", i);
10142 rtw_read_from_frame_mask(adapter, i);
10143 }
10144 #else
10145 struct rtl_wow_pattern context;
10146 int i;
10147
10148 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10149 rtw_wow_pattern_read_cam_ent(adapter, i, &context);
10150 rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
10151 }
10152
10153 #endif
10154 }
10155
10156
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)10157 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
10158 {
10159 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10160
10161 switch (mode) {
10162 case 0:
10163 rtw_clean_pattern(adapter);
10164 RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
10165 break;
10166 case 1:
10167 rtw_set_default_pattern(adapter);
10168 rtw_fill_pattern(adapter);
10169 RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
10170 break;
10171 case 2:
10172 rtw_clean_pattern(adapter);
10173 rtw_wow_pattern_sw_reset(adapter);
10174 RTW_INFO("%s: clean patterns\n", __func__);
10175 break;
10176 default:
10177 RTW_INFO("%s: unknown mode\n", __func__);
10178 break;
10179 }
10180 }
10181
rtw_hal_wow_enable(_adapter * adapter)10182 static void rtw_hal_wow_enable(_adapter *adapter)
10183 {
10184 struct registry_priv *registry_par = &adapter->registrypriv;
10185 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10186 struct security_priv *psecuritypriv = &adapter->securitypriv;
10187 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10188 struct sta_info *psta = NULL;
10189 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
10190 int res;
10191 u16 media_status_rpt;
10192 u8 no_wake = 0, i;
10193 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10194 _adapter *iface;
10195 #ifdef CONFIG_GPIO_WAKEUP
10196 u8 val8 = 0;
10197 #endif
10198
10199 #ifdef CONFIG_LPS_PG
10200 u8 lps_pg_hdl_id = 0;
10201 #endif
10202
10203
10204
10205 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
10206 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
10207 no_wake = 1;
10208
10209 RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
10210 rtw_hal_gate_bb(adapter, _TRUE);
10211
10212 for (i = 0; i < dvobj->iface_nums; i++) {
10213 iface = dvobj->padapters[i];
10214 /* Start Usb TxDMA */
10215 if(iface) {
10216 RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface));
10217 RTW_ENABLE_FUNC(iface, DF_TX_BIT);
10218 }
10219 }
10220
10221 #ifdef CONFIG_GTK_OL
10222 if (psecuritypriv->binstallKCK_KEK == _TRUE)
10223 rtw_hal_fw_sync_cam_id(adapter);
10224 #endif
10225 if (IS_HARDWARE_TYPE_8723B(adapter))
10226 rtw_hal_backup_rate(adapter);
10227
10228 rtw_hal_fw_dl(adapter, _TRUE);
10229 if(no_wake)
10230 media_status_rpt = RT_MEDIA_DISCONNECT;
10231 else
10232 media_status_rpt = RT_MEDIA_CONNECT;
10233 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10234 (u8 *)&media_status_rpt);
10235
10236 /* RX DMA stop */
10237 #if defined(CONFIG_RTL8188E)
10238 if (IS_HARDWARE_TYPE_8188E(adapter))
10239 rtw_hal_disable_tx_report(adapter);
10240 #endif
10241
10242 res = rtw_hal_pause_rx_dma(adapter);
10243 if (res == _FAIL)
10244 RTW_PRINT("[WARNING] pause RX DMA fail\n");
10245
10246 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10247 /* Reconfig RX_FF Boundary */
10248 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10249 rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
10250 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10251 #endif
10252
10253 /* redownload wow pattern */
10254 if(!no_wake)
10255 rtw_hal_dl_pattern(adapter, 1);
10256
10257 if (!pwrctl->wowlan_pno_enable) {
10258 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10259
10260 if (psta != NULL) {
10261 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10262 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10263 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10264 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10265 #endif
10266 if(!no_wake)
10267 rtw_sta_media_status_rpt(adapter, psta, 1);
10268 }
10269 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10270 else {
10271 if(registry_par->suspend_type == FW_IPS_WRC) {
10272 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10273 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10274 rtw_hal_set_default_port_id_cmd(adapter, 0);
10275 }
10276 }
10277 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10278 }
10279
10280 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10281 /* Enable CPWM2 only. */
10282 res = rtw_hal_enable_cpwm2(adapter);
10283 if (res == _FAIL)
10284 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
10285 #endif
10286 #ifdef CONFIG_GPIO_WAKEUP
10287 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10288 rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10289 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10290 #else
10291 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10292 if (pwrctl->is_high_active == 0)
10293 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10294 else
10295 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10296 GPIO_OUTPUT_LOW);
10297 #else
10298 val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
10299 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8);
10300 rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10301 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n",
10302 __func__, pwrctl->wowlan_gpio_index,
10303 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10304 pwrctl->is_high_active ? "HIGI" : "LOW");
10305 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10306 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10307 #endif /* CONFIG_GPIO_WAKEUP */
10308 /* Set WOWLAN H2C command. */
10309 RTW_PRINT("Set WOWLan cmd\n");
10310 rtw_hal_set_fw_wow_related_cmd(adapter, 1);
10311
10312 res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
10313
10314 if (res == _FALSE)
10315 RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
10316
10317 pwrctl->wowlan_wake_reason =
10318 rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10319
10320 RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
10321 pwrctl->wowlan_wake_reason);
10322 #ifdef CONFIG_GTK_OL_DBG
10323 dump_sec_cam(RTW_DBGDUMP, adapter);
10324 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
10325 #endif
10326
10327 #ifdef CONFIG_LPS_PG
10328 if (pwrctl->lps_level == LPS_PG) {
10329 lps_pg_hdl_id = LPS_PG_INFO_CFG;
10330 rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
10331 }
10332 #endif
10333
10334 #ifdef CONFIG_USB_HCI
10335 /* free adapter's resource */
10336 rtw_mi_intf_stop(adapter);
10337
10338 #endif
10339 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
10340 /* Invoid SE0 reset signal during suspending*/
10341 rtw_write8(adapter, REG_RSV_CTRL, 0x20);
10342 if (IS_8188F(pHalData->version_id) == FALSE
10343 && IS_8188GTV(pHalData->version_id) == FALSE)
10344 rtw_write8(adapter, REG_RSV_CTRL, 0x60);
10345 #endif
10346
10347 rtw_hal_gate_bb(adapter, _FALSE);
10348 }
10349
10350 #define DBG_WAKEUP_REASON
10351 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)10352 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
10353 {
10354 RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
10355 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)10356 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
10357 {
10358 if (RX_PAIRWISEKEY == reason)
10359 _dbg_wake_up_reason_string(adapter, "Rx pairwise key");
10360 else if (RX_GTK == reason)
10361 _dbg_wake_up_reason_string(adapter, "Rx GTK");
10362 else if (RX_FOURWAY_HANDSHAKE == reason)
10363 _dbg_wake_up_reason_string(adapter, "Rx four way handshake");
10364 else if (RX_DISASSOC == reason)
10365 _dbg_wake_up_reason_string(adapter, "Rx disassoc");
10366 else if (RX_DEAUTH == reason)
10367 _dbg_wake_up_reason_string(adapter, "Rx deauth");
10368 else if (RX_ARP_REQUEST == reason)
10369 _dbg_wake_up_reason_string(adapter, "Rx ARP request");
10370 else if (FW_DECISION_DISCONNECT == reason)
10371 _dbg_wake_up_reason_string(adapter, "FW detect disconnect");
10372 else if (RX_MAGIC_PKT == reason)
10373 _dbg_wake_up_reason_string(adapter, "Rx magic packet");
10374 else if (RX_UNICAST_PKT == reason)
10375 _dbg_wake_up_reason_string(adapter, "Rx unicast packet");
10376 else if (RX_PATTERN_PKT == reason)
10377 _dbg_wake_up_reason_string(adapter, "Rx pattern packet");
10378 else if (RTD3_SSID_MATCH == reason)
10379 _dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
10380 else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
10381 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
10382 else if (RX_REALWOW_V2_ACK_LOST == reason)
10383 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
10384 else if (ENABLE_FAIL_DMA_IDLE == reason)
10385 _dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
10386 else if (ENABLE_FAIL_DMA_PAUSE == reason)
10387 _dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
10388 else if (AP_OFFLOAD_WAKEUP == reason)
10389 _dbg_wake_up_reason_string(adapter, "AP offload wakeup");
10390 else if (CLK_32K_UNLOCK == reason)
10391 _dbg_wake_up_reason_string(adapter, "clk 32k unlock");
10392 else if (RTIME_FAIL_DMA_IDLE == reason)
10393 _dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
10394 else if (CLK_32K_LOCK == reason)
10395 _dbg_wake_up_reason_string(adapter, "clk 32k lock");
10396 else
10397 _dbg_wake_up_reason_string(adapter, "unknown reasoen");
10398 }
10399 #endif
10400
rtw_hal_wow_disable(_adapter * adapter)10401 static void rtw_hal_wow_disable(_adapter *adapter)
10402 {
10403 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10404 struct security_priv *psecuritypriv = &adapter->securitypriv;
10405 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10406 struct sta_info *psta = NULL;
10407 struct registry_priv *registry_par = &adapter->registrypriv;
10408 int res;
10409 u16 media_status_rpt;
10410
10411 RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
10412
10413 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
10414 RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");
10415 return;
10416 }
10417
10418 if (!pwrctl->wowlan_pno_enable) {
10419 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10420 if (psta != NULL)
10421 rtw_sta_media_status_rpt(adapter, psta, 0);
10422 else
10423 RTW_INFO("%s: psta is null\n", __func__);
10424 }
10425
10426 if (0) {
10427 RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
10428 RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
10429 RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
10430 RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
10431 }
10432
10433 pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10434
10435 RTW_PRINT("wakeup_reason: 0x%02x\n",
10436 pwrctl->wowlan_wake_reason);
10437 #ifdef DBG_WAKEUP_REASON
10438 _dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
10439 #endif
10440
10441 rtw_hal_set_fw_wow_related_cmd(adapter, 0);
10442
10443 res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
10444
10445 #if defined(CONFIG_RTL8188E)
10446 if (IS_HARDWARE_TYPE_8188E(adapter))
10447 rtw_hal_enable_tx_report(adapter);
10448 #endif
10449
10450 if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10451 (pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
10452 (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
10453 rtw_hal_get_aoac_rpt(adapter);
10454 rtw_hal_update_sw_security_info(adapter);
10455 }
10456
10457 if (res == _FALSE) {
10458 RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
10459 rtw_hal_force_enable_rxdma(adapter);
10460 }
10461
10462 rtw_hal_gate_bb(adapter, _TRUE);
10463
10464 res = rtw_hal_pause_rx_dma(adapter);
10465 if (res == _FAIL)
10466 RTW_PRINT("[WARNING] pause RX DMA fail\n");
10467
10468 /* clean HW pattern match */
10469 rtw_hal_dl_pattern(adapter, 0);
10470
10471 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10472 /* config RXFF boundary to original */
10473 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10474 rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
10475 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10476 #endif
10477 rtw_hal_release_rx_dma(adapter);
10478
10479 rtw_hal_fw_dl(adapter, _FALSE);
10480
10481 #ifdef CONFIG_GPIO_WAKEUP
10482
10483 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10484 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10485 #else
10486 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10487 if (pwrctl->is_high_active == 0)
10488 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10489 else
10490 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10491 GPIO_OUTPUT_LOW);
10492 #else
10493 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index
10494 , pwrctl->wowlan_gpio_output_state);
10495 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n",
10496 __func__, pwrctl->wowlan_gpio_index,
10497 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10498 pwrctl->is_high_active ? "HIGI" : "LOW");
10499 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10500 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10501 #endif /* CONFIG_GPIO_WAKEUP */
10502 if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
10503 (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
10504 (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10505 (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
10506
10507 media_status_rpt = RT_MEDIA_CONNECT;
10508 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10509 (u8 *)&media_status_rpt);
10510
10511 if (psta != NULL) {
10512 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10513 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10514 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10515 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10516 #endif
10517 rtw_sta_media_status_rpt(adapter, psta, 1);
10518 }
10519 }
10520 rtw_hal_gate_bb(adapter, _FALSE);
10521 }
10522 #endif /*CONFIG_WOWLAN*/
10523
10524 #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)10525 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
10526 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
10527 RSVDPAGE_LOC *rsvd_page_loc)
10528 {
10529 u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
10530 u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
10531 u8 CurtPktPageNum = 0;
10532
10533 /* P2P Beacon */
10534 rsvd_page_loc->LocP2PBeacon = *page_num;
10535 rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
10536 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10537 P2PBCNLength, _FALSE, _FALSE, _FALSE);
10538
10539 #if 0
10540 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
10541 __FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
10542 #endif
10543
10544 CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
10545
10546 *page_num += CurtPktPageNum;
10547
10548 index += (CurtPktPageNum * page_size);
10549 RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
10550
10551 /* P2P Probe rsp */
10552 rsvd_page_loc->LocP2PProbeRsp = *page_num;
10553 rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
10554 &P2PProbeRspLength);
10555 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10556 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
10557
10558 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", */
10559 /* __FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
10560
10561 CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
10562
10563 *page_num += CurtPktPageNum;
10564
10565 index += (CurtPktPageNum * page_size);
10566 RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
10567
10568 /* P2P nego rsp */
10569 rsvd_page_loc->LocNegoRsp = *page_num;
10570 rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
10571 &P2PNegoRspLength);
10572 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10573 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
10574
10575 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
10576 /* __FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
10577
10578 CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
10579
10580 *page_num += CurtPktPageNum;
10581
10582 index += (CurtPktPageNum * page_size);
10583 RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
10584
10585 /* P2P invite rsp */
10586 rsvd_page_loc->LocInviteRsp = *page_num;
10587 rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
10588 &P2PInviteRspLength);
10589 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10590 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
10591
10592 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
10593 /* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
10594
10595 CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
10596
10597 *page_num += CurtPktPageNum;
10598
10599 index += (CurtPktPageNum * page_size);
10600 RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
10601
10602 /* P2P provision discovery rsp */
10603 rsvd_page_loc->LocPDRsp = *page_num;
10604 rtw_hal_construct_P2PProvisionDisRsp(adapter,
10605 &pframe[index], &P2PPDRspLength);
10606
10607 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10608 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
10609
10610 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
10611 /* __FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
10612
10613 CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
10614
10615 *page_num += CurtPktPageNum;
10616
10617 *total_pkt_len = index + P2PPDRspLength;
10618 RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
10619
10620 index += (CurtPktPageNum * page_size);
10621
10622
10623 }
10624 #endif /* CONFIG_P2P_WOWLAN */
10625
10626 #ifdef CONFIG_LPS_PG
10627 #ifndef DBG_LPSPG_INFO_DUMP
10628 #define DBG_LPSPG_INFO_DUMP 1
10629 #endif
10630
10631 #include "hal_halmac.h"
10632
10633 #ifdef CONFIG_RTL8822C
rtw_lps_pg_set_dpk_info_rsvd_page(_adapter * adapter)10634 static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)
10635 {
10636 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10637 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10638 struct dm_struct *dm = adapter_to_phydm(adapter);
10639 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;
10640 u8 *info = NULL;
10641 u32 info_len;
10642 int ret = _FAIL;
10643
10644 /* get length */
10645 halrf_dpk_info_rsvd_page(dm, NULL, &info_len);
10646 if (!info_len) {
10647 RTW_ERR("get %s length fail\n", cache->name);
10648 goto exit;
10649 }
10650
10651 /* allocate buf */
10652 info = rtw_zmalloc(info_len);
10653 if (!info) {
10654 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10655 goto exit;
10656 }
10657
10658 /* get content */
10659 halrf_dpk_info_rsvd_page(dm, info, NULL);
10660
10661 if (rsvd_page_cache_update_data(cache, info, info_len)) {
10662
10663 #if (DBG_LPSPG_INFO_DUMP >= 1)
10664 RTW_INFO_DUMP(cache->name, info, info_len);
10665 #endif
10666
10667 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10668 ret = !ret ? _SUCCESS : _FAIL;
10669 if (ret != _SUCCESS) {
10670 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10671 goto free_mem;
10672 }
10673
10674 #if (DBG_LPSPG_INFO_DUMP >= 2)
10675 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10676 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10677 #endif
10678 }
10679
10680 free_mem:
10681 rtw_mfree(info, info_len);
10682
10683 exit:
10684 return ret;
10685 }
10686
rtw_lps_pg_set_iqk_info_rsvd_page(_adapter * adapter)10687 static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)
10688 {
10689 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10690 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10691 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10692 struct dm_struct *dm = adapter_to_phydm(adapter);
10693 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;
10694 u8 *info = NULL;
10695 u32 info_len = 0;
10696 int ret = _FAIL;
10697
10698 if (hal_data->RegIQKFWOffload) {
10699 rsvd_page_cache_free_data(cache);
10700 ret = _SUCCESS;
10701 goto exit;
10702 }
10703
10704 /* get length */
10705 halrf_iqk_info_rsvd_page(dm, NULL, &info_len);
10706 if (!info_len) {
10707 RTW_ERR("get %s length fail\n", cache->name);
10708 goto exit;
10709 }
10710
10711 /* allocate buf */
10712 info = rtw_zmalloc(info_len);
10713 if (!info) {
10714 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10715 goto exit;
10716 }
10717
10718 /* get content */
10719 halrf_iqk_info_rsvd_page(dm, info, NULL);
10720
10721 if (rsvd_page_cache_update_data(cache, info, info_len)) {
10722
10723 #if (DBG_LPSPG_INFO_DUMP >= 1)
10724 RTW_INFO_DUMP(cache->name, info, info_len);
10725 #endif
10726
10727 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10728 ret = !ret ? _SUCCESS : _FAIL;
10729 if (ret != _SUCCESS) {
10730 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10731 goto free_mem;
10732 }
10733
10734 #if (DBG_LPSPG_INFO_DUMP >= 2)
10735 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10736 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10737 #endif
10738 }
10739
10740 free_mem:
10741 rtw_mfree(info, info_len);
10742
10743 exit:
10744 return ret;
10745 }
10746 #endif /* CONFIG_RTL8822C */
10747
rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv * dvobj,_adapter * ld_sta_iface,u8 * buf,u32 * buf_size)10748 static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size)
10749 {
10750 #define LPS_PG_INFO_RSVD_LEN 16
10751
10752 if (buf) {
10753 _adapter *adapter = dvobj_get_primary_adapter(dvobj);
10754 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10755 struct sta_info *psta;
10756 #ifdef CONFIG_MBSSID_CAM
10757 u8 cam_id = INVALID_CAM_ID;
10758 #endif
10759 u8 *psec_cam_id = buf + 8;
10760 u8 sec_cam_num = 0;
10761 u8 drv_rsvdpage_num = 0;
10762
10763 if (ld_sta_iface) {
10764 psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv));
10765 if (!psta) {
10766 RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
10767 rtw_warn_on(1);
10768 goto size_chk;
10769 }
10770 /*Byte 0 - used macid*/
10771 LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);
10772 RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
10773 }
10774
10775 #ifdef CONFIG_MBSSID_CAM
10776 /*Byte 1 - used BSSID CAM entry*/
10777 cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
10778 if (cam_id != INVALID_CAM_ID)
10779 LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);
10780 RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
10781 #endif
10782
10783 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
10784 /*Btye 2 - Max used Pattern Match CAM entry*/
10785 if (pwrpriv->wowlan_mode == _TRUE
10786 && ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
10787 LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);
10788 RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
10789 }
10790 #endif
10791 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
10792 /*Btye 3 - Max MU rate table Group ID*/
10793 LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);
10794 RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
10795 #endif
10796
10797 /*Btye 8 ~15 - used Security CAM entry */
10798 sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
10799
10800 /*Btye 4 - used Security CAM entry number*/
10801 if (sec_cam_num < 8)
10802 LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);
10803 RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
10804
10805 /*Btye 5 - Txbuf used page number for fw offload*/
10806 if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
10807 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
10808 else
10809 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
10810 LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);
10811 RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
10812 }
10813
10814 size_chk:
10815 if (buf_size)
10816 *buf_size = LPS_PG_INFO_RSVD_LEN;
10817 }
10818
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)10819 static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
10820 {
10821 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10822 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10823 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;
10824 u8 *info = NULL;
10825 u32 info_len = 0;
10826 int ret = _FAIL;
10827
10828 /* get length */
10829 rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len);
10830 if (!info_len) {
10831 RTW_ERR("get %s length fail\n", cache->name);
10832 goto exit;
10833 }
10834
10835 /* allocate buf */
10836 info = rtw_zmalloc(info_len);
10837 if (!info) {
10838 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
10839 goto exit;
10840 }
10841
10842 /* get content */
10843 rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL);
10844
10845 if (rsvd_page_cache_update_data(cache, info, info_len)) {
10846
10847 #if (DBG_LPSPG_INFO_DUMP >= 1)
10848 RTW_INFO_DUMP(cache->name, info, info_len);
10849 #endif
10850
10851 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
10852 ret = !ret ? _SUCCESS : _FAIL;
10853 if (ret != _SUCCESS) {
10854 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
10855 goto free_mem;
10856 }
10857
10858 #if (DBG_LPSPG_INFO_DUMP >= 2)
10859 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
10860 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
10861 #endif
10862 }
10863
10864 free_mem:
10865 rtw_mfree(info, info_len);
10866
10867 exit:
10868 return ret;
10869 }
10870
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)10871 static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index
10872 , u8 txdesc_size, u32 page_size, u8 *total_page_num
10873 , bool is_wow_mode, _adapter *ld_sta_iface, bool only_get_page_num)
10874 {
10875 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
10876 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10877 struct rsvd_page_cache_t *cache;
10878 bool rsvd = 1;
10879 u8 *pos;
10880 u32 len;
10881
10882 if (is_wow_mode) {
10883 /* lps_level will not change when enter wow_mode */
10884 if (pwrctl->lps_level != LPS_PG)
10885 rsvd = 0;
10886 } else {
10887 if (!only_get_page_num && !ld_sta_iface)
10888 rsvd = 0;
10889 }
10890
10891 pos = only_get_page_num ? NULL : frame + *index;
10892
10893 #ifdef CONFIG_RTL8822C
10894 if (IS_8822C_SERIES(hal_data->version_id)) {
10895 /* LPSPG_DPK_INFO */
10896 cache = &pwrctl->lpspg_dpk_info;
10897 if (rsvd) {
10898 if (pwrctl->lps_level != LPS_PG)
10899 pos = NULL;
10900 len = 0;
10901 halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10902 #if (DBG_LPSPG_INFO_DUMP >= 1)
10903 if (pos)
10904 RTW_INFO_DUMP(cache->name, pos, len);
10905 #endif
10906 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10907 *total_page_num += cache->page_num;
10908 *index += page_size * cache->page_num;
10909 pos = only_get_page_num ? NULL : frame + *index;
10910 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10911 } else
10912 rsvd_page_cache_free(cache);
10913
10914 /* LPSPG_IQK_INFO */
10915 cache = &pwrctl->lpspg_iqk_info;
10916 if (rsvd
10917 /* RegIQKFWOffload will not change when enter wow_mode */
10918 && !(is_wow_mode && hal_data->RegIQKFWOffload)
10919 ) {
10920 if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)
10921 pos = NULL;
10922 len = 0;
10923 halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
10924 #if (DBG_LPSPG_INFO_DUMP >= 1)
10925 if (pos)
10926 RTW_INFO_DUMP(cache->name, pos, len);
10927 #endif
10928 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10929 *total_page_num += cache->page_num;
10930 *index += page_size * cache->page_num;
10931 pos = only_get_page_num ? NULL : frame + *index;
10932 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10933 } else
10934 rsvd_page_cache_free(cache);
10935 }
10936 #endif
10937
10938 /* LPSPG_INFO */
10939 cache = &pwrctl->lpspg_info;
10940 if (rsvd) {
10941 if (pwrctl->lps_level != LPS_PG)
10942 pos = NULL;
10943 rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len);
10944 #if (DBG_LPSPG_INFO_DUMP >= 1)
10945 if (pos)
10946 RTW_INFO_DUMP(cache->name, pos, len);
10947 #endif
10948 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
10949 *total_page_num += cache->page_num;
10950 *index += page_size * cache->page_num;
10951 pos = only_get_page_num ? NULL : frame + *index;
10952 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
10953 } else
10954 rsvd_page_cache_free(cache);
10955 }
10956
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)10957 u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
10958 {
10959 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10960 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10961
10962 u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
10963 u8 ret = _FAIL;
10964
10965 if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
10966 SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1); /*SecurityCAM_En*/
10967
10968 #ifdef CONFIG_MBSSID_CAM
10969 SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1); /*BSSIDCAM_En*/
10970 #endif
10971
10972 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
10973 if (pwrpriv->wowlan_mode == _TRUE &&
10974 check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
10975
10976 SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/
10977 }
10978 #endif
10979
10980 #ifdef CONFIG_MACID_SEARCH
10981 SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1); /*MACIDSearch_En*/
10982 #endif
10983
10984 #ifdef CONFIG_TX_SC
10985 SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1); /*TXSC_En*/
10986 #endif
10987
10988 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
10989 SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1); /*MURateTable_En*/
10990 #endif
10991
10992 SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);
10993
10994 #ifdef CONFIG_RTL8822C
10995 if (pwrpriv->bFwCurrentInPSMode == _FALSE) {
10996 SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);
10997 if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
10998 SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);
10999 } else {
11000 SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0);
11001 if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11002 SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0);
11003 }
11004 #endif
11005
11006 #if (DBG_LPSPG_INFO_DUMP >= 1)
11007 RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);
11008 #endif
11009
11010 ret = rtw_hal_fill_h2c_cmd(adapter,
11011 H2C_LPS_PG_INFO,
11012 H2C_LPS_PG_INFO_LEN,
11013 lpspg_info);
11014 return ret;
11015 }
rtw_hal_set_lps_pg_info(_adapter * adapter)11016 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
11017 {
11018 u8 ret = _FAIL;
11019 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11020
11021 if (pwrpriv->lpspg_info.loc == 0) {
11022 RTW_ERR("%s lpspg_info.loc = 0\n", __func__);
11023 rtw_warn_on(1);
11024 return ret;
11025 }
11026 #ifdef CONFIG_RTL8822C
11027 rtw_lps_pg_set_dpk_info_rsvd_page(adapter);
11028 rtw_lps_pg_set_iqk_info_rsvd_page(adapter);
11029 #endif
11030 rtw_hal_set_lps_pg_info_rsvd_page(adapter);
11031
11032 ret = rtw_hal_set_lps_pg_info_cmd(adapter);
11033
11034 return ret;
11035 }
11036
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)11037 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
11038 {
11039 #if 0
11040 if (sta->cmn.ra_info.rssi_level >= 4)
11041 sta->lps_pg_rssi_lv = 3; /*RSSI High - 1SS_VHT_MCS7*/
11042 else if (sta->cmn.ra_info.rssi_level >= 2)
11043 sta->lps_pg_rssi_lv = 2; /*RSSI Middle - 1SS_VHT_MCS3*/
11044 else
11045 sta->lps_pg_rssi_lv = 1; /*RSSI Lower - Lowest_rate*/
11046 #else
11047 sta->lps_pg_rssi_lv = 0;
11048 #endif
11049 RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
11050 __func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
11051 }
11052
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)11053 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
11054 {
11055 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
11056 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11057 struct sta_priv *pstapriv = &adapter->stapriv;
11058 struct sta_info *sta;
11059
11060 sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
11061
11062 switch (hdl_id) {
11063 case LPS_PG_INFO_CFG:
11064 rtw_hal_set_lps_pg_info(adapter);
11065 break;
11066 case LPS_PG_REDLEMEM:
11067 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11068 break;
11069
11070 /*set xmit_block*/
11071 rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11072 if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
11073 rtw_warn_on(1);
11074 /*clearn xmit_block*/
11075 rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11076 break;
11077 case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
11078 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11079 break;
11080
11081 if (sta)
11082 rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
11083 break;
11084 case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
11085 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11086 break;
11087
11088 if (sta) {
11089 rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
11090 rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
11091 sta->lps_pg_rssi_lv = 0;
11092 }
11093 break;
11094
11095 default:
11096 break;
11097 }
11098 }
11099
11100 #endif /*CONFIG_LPS_PG*/
11101
_rtw_mi_assoc_if_num(_adapter * adapter)11102 static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
11103 {
11104 u8 mi_iface_num = 0;
11105
11106 if (0) {
11107 RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
11108 RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
11109 RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11110 RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
11111 RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
11112 /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
11113 /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
11114 }
11115
11116 mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
11117 DEV_AP_NUM(adapter_to_dvobj(adapter)) +
11118 DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11119 return mi_iface_num;
11120 }
11121 #ifdef CONFIG_CONCURRENT_MODE
_rtw_search_sta_iface(_adapter * adapter)11122 static _adapter *_rtw_search_sta_iface(_adapter *adapter)
11123 {
11124 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11125 _adapter *iface = NULL;
11126 _adapter *sta_iface = NULL;
11127 int i;
11128
11129 for (i = 0; i < dvobj->iface_nums; i++) {
11130 iface = dvobj->padapters[i];
11131 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
11132 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11133 sta_iface = iface;
11134 break;
11135 }
11136 }
11137 }
11138 return sta_iface;
11139 }
11140 #if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)
_rtw_search_ap_iface(_adapter * adapter)11141 static _adapter *_rtw_search_ap_iface(_adapter *adapter)
11142 {
11143 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11144 _adapter *iface = NULL;
11145 _adapter *ap_iface = NULL;
11146 int i;
11147
11148 for (i = 0; i < dvobj->iface_nums; i++) {
11149 iface = dvobj->padapters[i];
11150 if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
11151 ap_iface = iface;
11152 break;
11153 }
11154 }
11155 return ap_iface;
11156 }
11157 #endif/*CONFIG_AP_MODE*/
11158 #endif/*CONFIG_CONCURRENT_MODE*/
11159
11160 #ifdef CONFIG_CUSTOMER01_SMART_ANTENNA
rtw_hal_set_pathb_phase(_adapter * adapter,u8 phase_idx)11161 void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)
11162 {
11163 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
11164 struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
11165
11166 return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);
11167 }
11168 #endif
11169
11170 /*
11171 * Description: Fill the reserved packets that FW will use to RSVD page.
11172 * Now we just send 4 types packet to rsvd page.
11173 * (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
11174 * Input:
11175 * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
11176 * so we need to set the packet length to total lengh.
11177 * TRUE: At the second time, we should send the first packet (default:beacon)
11178 * to Hw again and set the lengh in descriptor to the real beacon lengh.
11179 * page_num - The amount of reserved page which driver need.
11180 * If this is not NULL, this function doesn't real download reserved
11181 * page, but just count the number of reserved page.
11182 *
11183 * 2009.10.15 by tynli.
11184 * 2017.06.20 modified by Lucas.
11185 *
11186 * Page Size = 128: 8188e, 8723a/b, 8192c/d,
11187 * Page Size = 256: 8192e, 8821a
11188 * Page Size = 512: 8812a
11189 */
11190
11191 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)11192 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
11193 {
11194 PHAL_DATA_TYPE pHalData;
11195 struct xmit_frame *pcmdframe = NULL;
11196 struct pkt_attrib *pattrib;
11197 struct xmit_priv *pxmitpriv;
11198 struct pwrctrl_priv *pwrctl;
11199 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11200 u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
11201 u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
11202 u32 ProbeReqLength = 0, NullFunctionDataLength = 0;
11203 u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
11204 u8 TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
11205 u8 *ReservedPagePacket;
11206 u16 BufIndex = 0;
11207 u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
11208 RSVDPAGE_LOC RsvdPageLoc;
11209 struct registry_priv *registry_par = &adapter->registrypriv;
11210
11211 #ifdef DBG_FW_DEBUG_MSG_PKT
11212 u32 fw_dbg_msg_pkt_len = 0;
11213 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11214
11215 #ifdef DBG_CONFIG_ERROR_DETECT
11216 struct sreset_priv *psrtpriv;
11217 #endif /* DBG_CONFIG_ERROR_DETECT */
11218
11219 #ifdef CONFIG_MCC_MODE
11220 u8 dl_mcc_page = _FAIL;
11221 #endif /* CONFIG_MCC_MODE */
11222 u8 nr_assoc_if;
11223
11224 _adapter *sta_iface = NULL;
11225 _adapter *ap_iface = NULL;
11226
11227 bool is_wow_mode = _FALSE;
11228
11229 pHalData = GET_HAL_DATA(adapter);
11230 #ifdef DBG_CONFIG_ERROR_DETECT
11231 psrtpriv = &pHalData->srestpriv;
11232 #endif
11233 pxmitpriv = &adapter->xmitpriv;
11234 pwrctl = adapter_to_pwrctl(adapter);
11235
11236 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
11237
11238 if (PageSize == 0) {
11239 RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
11240 return;
11241 }
11242 nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
11243
11244 if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
11245 pwrctl->wowlan_ap_mode == _TRUE ||
11246 pwrctl->wowlan_p2p_mode == _TRUE)
11247 is_wow_mode = _TRUE;
11248
11249 /*page_num for init time to get rsvd page number*/
11250 /* Prepare ReservedPagePacket */
11251 if (page_num) {
11252 ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
11253 if (!ReservedPagePacket) {
11254 RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11255 *page_num = 0xFF;
11256 return;
11257 }
11258 RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm ==>\n",
11259 FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11260
11261 } else {
11262 if (is_wow_mode)
11263 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11264 else
11265 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11266
11267 RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
11268 FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
11269
11270 MaxRsvdPageBufSize = RsvdPageNum * PageSize;
11271 if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
11272 RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
11273 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
11274 rtw_warn_on(1);
11275 return;
11276 }
11277
11278 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
11279 if (pcmdframe == NULL) {
11280 RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11281 return;
11282 }
11283
11284 ReservedPagePacket = pcmdframe->buf_addr;
11285 }
11286
11287 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
11288
11289 BufIndex = TxDescOffset;
11290
11291 /*======== beacon content =======*/
11292 rtw_hal_construct_beacon(adapter,
11293 &ReservedPagePacket[BufIndex], &BeaconLength);
11294
11295 /*
11296 * When we count the first page size, we need to reserve description size for the RSVD
11297 * packet, it will be filled in front of the packet in TXPKTBUF.
11298 */
11299 BeaconLength = MAX_BEACON_LEN - TxDescLen;
11300 CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
11301
11302 #if defined(CONFIG_FW_HANDLE_TXBCN) || defined(CONFIG_PORT_BASED_TXBCN)
11303 CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
11304 #endif
11305 TotalPageNum += CurtPktPageNum;
11306
11307 BufIndex += (CurtPktPageNum * PageSize);
11308
11309 RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11310
11311 /*======== probe response content ========*/
11312 if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
11313 #ifdef CONFIG_CONCURRENT_MODE
11314 if (nr_assoc_if >= 2)
11315 RTW_ERR("Not support > 2 net-interface in WOW\n");
11316 #endif
11317 /* (4) probe response*/
11318 RsvdPageLoc.LocProbeRsp = TotalPageNum;
11319 rtw_hal_construct_ProbeRsp(
11320 adapter, &ReservedPagePacket[BufIndex],
11321 &ProbeRspLength,
11322 _FALSE);
11323 rtw_hal_fill_fake_txdesc(adapter,
11324 &ReservedPagePacket[BufIndex - TxDescLen],
11325 ProbeRspLength, _FALSE, _FALSE, _FALSE);
11326
11327 CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
11328 TotalPageNum += CurtPktPageNum;
11329 TotalPacketLen = BufIndex + ProbeRspLength;
11330 BufIndex += (CurtPktPageNum * PageSize);
11331 RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11332 goto download_page;
11333 }
11334
11335 /*======== ps-poll content * 1 page ========*/
11336 sta_iface = adapter;
11337 #ifdef CONFIG_CONCURRENT_MODE
11338 if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
11339 sta_iface = _rtw_search_sta_iface(adapter);
11340 RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
11341 }
11342 #endif
11343
11344 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11345 RsvdPageLoc.LocPsPoll = TotalPageNum;
11346 RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
11347 rtw_hal_construct_PSPoll(sta_iface,
11348 &ReservedPagePacket[BufIndex], &PSPollLength);
11349 rtw_hal_fill_fake_txdesc(sta_iface,
11350 &ReservedPagePacket[BufIndex - TxDescLen],
11351 PSPollLength, _TRUE, _FALSE, _FALSE);
11352
11353 CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
11354
11355 TotalPageNum += CurtPktPageNum;
11356
11357 BufIndex += (CurtPktPageNum * PageSize);
11358 RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11359 }
11360
11361 #ifdef CONFIG_MCC_MODE
11362 /*======== MCC * n page ======== */
11363 if (MCC_EN(adapter)) {/*Normal mode*/
11364 dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
11365 &BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
11366 } else {
11367 dl_mcc_page = _FAIL;
11368 }
11369
11370 if (dl_mcc_page == _FAIL)
11371 #endif /* CONFIG_MCC_MODE */
11372 { /*======== null data * 1 page ======== */
11373 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11374 RsvdPageLoc.LocNullData = TotalPageNum;
11375 RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
11376 rtw_hal_construct_NullFunctionData(
11377 sta_iface,
11378 &ReservedPagePacket[BufIndex],
11379 &NullDataLength,
11380 _FALSE, 0, 0, _FALSE);
11381 rtw_hal_fill_fake_txdesc(sta_iface,
11382 &ReservedPagePacket[BufIndex - TxDescLen],
11383 NullDataLength, _FALSE, _FALSE, _FALSE);
11384
11385 CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
11386
11387 TotalPageNum += CurtPktPageNum;
11388
11389 BufIndex += (CurtPktPageNum * PageSize);
11390 RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11391 }
11392 }
11393
11394 /*======== Qos null data * 1 page ======== */
11395 if (pwrctl->wowlan_mode == _FALSE ||
11396 pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11397 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
11398 RsvdPageLoc.LocQosNull = TotalPageNum;
11399 RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
11400 rtw_hal_construct_NullFunctionData(sta_iface,
11401 &ReservedPagePacket[BufIndex],
11402 &QosNullLength,
11403 _TRUE, 0, 0, _FALSE);
11404 rtw_hal_fill_fake_txdesc(sta_iface,
11405 &ReservedPagePacket[BufIndex - TxDescLen],
11406 QosNullLength, _FALSE, _FALSE, _FALSE);
11407
11408 CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
11409 PageSize);
11410
11411 TotalPageNum += CurtPktPageNum;
11412
11413 BufIndex += (CurtPktPageNum * PageSize);
11414 RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11415 }
11416 }
11417
11418 #ifdef CONFIG_BT_COEXIST
11419 /*======== BT Qos null data * 1 page ======== */
11420 if (pwrctl->wowlan_mode == _FALSE ||
11421 pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
11422
11423 ap_iface = adapter;
11424 #if defined (CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
11425 if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) { /*DEV_AP_STARTING_NUM*/
11426 ap_iface = _rtw_search_ap_iface(adapter);
11427 RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
11428 }
11429 #endif
11430
11431 if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
11432 RsvdPageLoc.LocBTQosNull = TotalPageNum;
11433
11434 RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
11435
11436 rtw_hal_construct_NullFunctionData(ap_iface,
11437 &ReservedPagePacket[BufIndex],
11438 &BTQosNullLength,
11439 _TRUE, 0, 0, _FALSE);
11440
11441 rtw_hal_fill_fake_txdesc(ap_iface,
11442 &ReservedPagePacket[BufIndex - TxDescLen],
11443 BTQosNullLength, _FALSE, _TRUE, _FALSE);
11444
11445 CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
11446 PageSize);
11447
11448 TotalPageNum += CurtPktPageNum;
11449 BufIndex += (CurtPktPageNum * PageSize);
11450
11451 RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11452 }
11453 }
11454 #endif /* CONFIG_BT_COEXIT */
11455
11456 TotalPacketLen = BufIndex;
11457
11458 #ifdef DBG_FW_DEBUG_MSG_PKT
11459 /*======== FW DEBUG MSG * n page ======== */
11460 RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
11461 RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
11462 rtw_hal_construct_fw_dbg_msg_pkt(
11463 adapter,
11464 &ReservedPagePacket[BufIndex],
11465 &fw_dbg_msg_pkt_len);
11466
11467 rtw_hal_fill_fake_txdesc(adapter,
11468 &ReservedPagePacket[BufIndex - TxDescLen],
11469 fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
11470
11471 CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
11472
11473 if (CurtPktPageNum < 2)
11474 CurtPktPageNum = 2; /*Need at least 2 rsvd page*/
11475 TotalPageNum += CurtPktPageNum;
11476
11477 TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
11478 BufIndex += (CurtPktPageNum * PageSize);
11479 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11480
11481 #ifdef CONFIG_LPS_PG
11482 rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex
11483 , TxDescLen, PageSize, &TotalPageNum, is_wow_mode
11484 , (sta_iface && MLME_IS_STA(sta_iface) && MLME_IS_ASOC(sta_iface)) ? sta_iface : NULL
11485 , page_num ? 1 : 0
11486 );
11487 TotalPacketLen = BufIndex;
11488 #endif
11489
11490 #ifdef CONFIG_WOWLAN
11491 /*======== WOW * n page ======== */
11492 if (pwrctl->wowlan_mode == _TRUE &&
11493 pwrctl->wowlan_in_resume == _FALSE &&
11494 check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {/*WOW mode*/
11495 rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11496 BufIndex, TxDescLen, PageSize,
11497 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11498 }
11499 #endif /* CONFIG_WOWLAN */
11500
11501 #ifdef CONFIG_P2P_WOWLAN
11502 /*======== P2P WOW * n page ======== */
11503 if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
11504 rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
11505 BufIndex, TxDescLen, PageSize,
11506 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
11507 }
11508 #endif /* CONFIG_P2P_WOWLAN */
11509
11510 /*Note: BufIndex already add a TxDescOffset offset in first Beacon page
11511 * The "TotalPacketLen" is calculate by BufIndex.
11512 * We need to decrease TxDescOffset before doing length check. by yiwei
11513 */
11514 TotalPacketLen = TotalPacketLen - TxDescOffset;
11515
11516 download_page:
11517 if (page_num) {
11518 *page_num = TotalPageNum;
11519 rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
11520 ReservedPagePacket = NULL;
11521 RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
11522 FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11523 return;
11524 }
11525
11526 /* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
11527 RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
11528 __func__, TotalPageNum, TotalPacketLen);
11529
11530 if (TotalPacketLen > MaxRsvdPageBufSize) {
11531 RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
11532 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
11533 rtw_warn_on(1);
11534 goto error;
11535 } else {
11536 /* update attribute */
11537 pattrib = &pcmdframe->attrib;
11538 update_mgntframe_attrib(adapter, pattrib);
11539 pattrib->qsel = QSLT_BEACON;
11540 pattrib->pktlen = TotalPacketLen;
11541 pattrib->last_txcmdsz = TotalPacketLen;
11542 #ifdef CONFIG_PCI_HCI
11543 dump_mgntframe(adapter, pcmdframe);
11544 #else
11545 dump_mgntframe_and_wait(adapter, pcmdframe, 100);
11546 #endif
11547 }
11548
11549 RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
11550 __func__, TotalPacketLen, TotalPageNum);
11551 #ifdef DBG_DUMP_SET_RSVD_PAGE
11552 RTW_INFO(" ==================================================\n");
11553 RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
11554 RTW_INFO(" ==================================================\n");
11555 #endif
11556
11557
11558 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
11559 || MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
11560 rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
11561 #ifdef DBG_FW_DEBUG_MSG_PKT
11562 rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
11563 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11564 #ifdef CONFIG_WOWLAN
11565 if (pwrctl->wowlan_mode == _TRUE &&
11566 pwrctl->wowlan_in_resume == _FALSE)
11567 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11568 #endif /* CONFIG_WOWLAN */
11569 #ifdef CONFIG_AP_WOWLAN
11570 if (pwrctl->wowlan_ap_mode == _TRUE)
11571 rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
11572 #endif /* CONFIG_AP_WOWLAN */
11573 } else if (pwrctl->wowlan_pno_enable) {
11574 #ifdef CONFIG_PNO_SUPPORT
11575 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
11576 if (pwrctl->wowlan_in_resume)
11577 rtw_hal_set_scan_offload_info_cmd(adapter,
11578 &RsvdPageLoc, 0);
11579 else
11580 rtw_hal_set_scan_offload_info_cmd(adapter,
11581 &RsvdPageLoc, 1);
11582 #endif /* CONFIG_PNO_SUPPORT */
11583 }
11584
11585 #ifdef CONFIG_P2P_WOWLAN
11586 if (_TRUE == pwrctl->wowlan_p2p_mode)
11587 rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
11588 #endif /* CONFIG_P2P_WOWLAN */
11589
11590 return;
11591 error:
11592 rtw_free_xmitframe(pxmitpriv, pcmdframe);
11593 }
11594
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)11595 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
11596 {
11597 #ifdef CONFIG_AP_MODE
11598 if (finished)
11599 rtw_mi_tx_beacon_hdl(adapter);
11600 else
11601 #endif
11602 _rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
11603 }
11604
11605 /**
11606 * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
11607 * @adapter: struct _ADAPTER*
11608 *
11609 * Caculate needed reserved page number.
11610 * In different state would get different number, for example normal mode and
11611 * WOW mode would need different reserved page size.
11612 *
11613 * Return the number of reserved page which driver need.
11614 */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)11615 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
11616 {
11617 u8 num = 0;
11618
11619
11620 _rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
11621
11622 return num;
11623 }
11624
11625 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
hw_var_set_bcn_func(_adapter * adapter,u8 enable)11626 static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
11627 {
11628 u32 bcn_ctrl_reg;
11629
11630 #ifdef CONFIG_CONCURRENT_MODE
11631 if (adapter->hw_port == HW_PORT1)
11632 bcn_ctrl_reg = REG_BCN_CTRL_1;
11633 else
11634 #endif
11635 bcn_ctrl_reg = REG_BCN_CTRL;
11636
11637 if (enable)
11638 rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
11639 else {
11640 u8 val8;
11641
11642 val8 = rtw_read8(adapter, bcn_ctrl_reg);
11643 val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
11644
11645 #ifdef CONFIG_BT_COEXIST
11646 if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
11647 /* Always enable port0 beacon function for PSTDMA */
11648 if (REG_BCN_CTRL == bcn_ctrl_reg)
11649 val8 |= EN_BCN_FUNCTION;
11650 }
11651 #endif
11652
11653 rtw_write8(adapter, bcn_ctrl_reg, val8);
11654 }
11655
11656 #ifdef CONFIG_RTL8192F
11657 if (IS_HARDWARE_TYPE_8192F(adapter)) {
11658 u16 val16, val16_ori;
11659
11660 val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
11661
11662 #ifdef CONFIG_CONCURRENT_MODE
11663 if (adapter->hw_port == HW_PORT1) {
11664 if (enable)
11665 val16 |= EN_PORT_1_FUNCTION;
11666 else
11667 val16 &= ~EN_PORT_1_FUNCTION;
11668 } else
11669 #endif
11670 {
11671 if (enable)
11672 val16 |= EN_PORT_0_FUNCTION;
11673 else
11674 val16 &= ~EN_PORT_0_FUNCTION;
11675
11676 #ifdef CONFIG_BT_COEXIST
11677 if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
11678 val16 |= EN_PORT_0_FUNCTION;
11679 #endif
11680 }
11681
11682 if (val16 != val16_ori)
11683 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, val16);
11684 }
11685 #endif
11686 }
11687 #endif
11688
11689 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
hw_var_set_mlme_disconnect(_adapter * adapter)11690 static void hw_var_set_mlme_disconnect(_adapter *adapter)
11691 {
11692 u8 val8;
11693
11694 /* reject all data frames */
11695 #ifdef CONFIG_CONCURRENT_MODE
11696 if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11697 #endif
11698 rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
11699
11700 #ifdef CONFIG_CONCURRENT_MODE
11701 if (adapter->hw_port == HW_PORT1) {
11702 /* reset TSF1 */
11703 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
11704
11705 /* disable update TSF1 */
11706 rtw_iface_disable_tsf_update(adapter);
11707
11708 if (!IS_HARDWARE_TYPE_8723D(adapter)
11709 && !IS_HARDWARE_TYPE_8192F(adapter)
11710 && !IS_HARDWARE_TYPE_8710B(adapter)
11711 ) {
11712 /* disable Port1's beacon function */
11713 val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
11714 val8 &= ~EN_BCN_FUNCTION;
11715 rtw_write8(adapter, REG_BCN_CTRL_1, val8);
11716 }
11717 } else
11718 #endif
11719 {
11720 /* reset TSF */
11721 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
11722
11723 /* disable update TSF */
11724 rtw_iface_disable_tsf_update(adapter);
11725 }
11726 }
11727 #endif
11728
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 enable)11729 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
11730 {
11731 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11732 u16 value_rxfltmap2;
11733
11734 #ifdef DBG_IFACE_STATUS
11735 DBG_IFACE_STATUS_DUMP(adapter);
11736 #endif
11737
11738 #ifdef CONFIG_FIND_BEST_CHANNEL
11739 /* Receive all data frames */
11740 value_rxfltmap2 = 0xFFFF;
11741 #else
11742 /* not to receive data frame */
11743 value_rxfltmap2 = 0;
11744 #endif
11745
11746 if (enable) { /* under sitesurvey */
11747 /*
11748 * 1. configure REG_RXFLTMAP2
11749 * 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
11750 * 3. config RCR to receive different BSSID BCN or probe rsp
11751 */
11752 rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
11753
11754 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
11755
11756 /* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */
11757 #if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11758 hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);
11759 hal_data->RegRRSR &= 0x000FFFFF;
11760 #endif
11761
11762 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11763 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11764 /* set 718[1:0]=2'b00 to avoid BF scan hang */
11765 hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
11766 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
11767 }
11768 #endif
11769
11770 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11771 StopTxBeacon(adapter);
11772 } else { /* sitesurvey done */
11773 /*
11774 * 1. enable rx data frame
11775 * 2. config RCR not to receive different BSSID BCN or probe rsp
11776 * 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict
11777 * so, we enable TSF update when rx first BCN after sitesurvey done
11778 */
11779 if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) {
11780 /* enable to rx data frame */
11781 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11782 }
11783
11784 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
11785
11786 /* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */
11787 #if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
11788 rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);
11789 #endif
11790
11791 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
11792 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
11793 /* Restore orignal 0x718 setting*/
11794 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
11795 }
11796 #endif
11797
11798 #ifdef CONFIG_AP_MODE
11799 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11800 ResumeTxBeacon(adapter);
11801 rtw_mi_tx_beacon_hdl(adapter);
11802 }
11803 #endif
11804 }
11805 }
11806
11807 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
hw_var_set_mlme_join(_adapter * adapter,u8 type)11808 static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
11809 {
11810 u8 val8;
11811 u16 val16;
11812 u32 val32;
11813 u8 RetryLimit = RL_VAL_STA;
11814 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11815 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11816
11817 #ifdef CONFIG_CONCURRENT_MODE
11818 if (type == 0) {
11819 /* prepare to join */
11820 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
11821 StopTxBeacon(adapter);
11822
11823 /* enable to rx data frame.Accept all data frame */
11824 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11825
11826 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11827 RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11828 else /* Ad-hoc Mode */
11829 RetryLimit = RL_VAL_AP;
11830
11831 rtw_iface_enable_tsf_update(adapter);
11832
11833 } else if (type == 1) {
11834 /* joinbss_event call back when join res < 0 */
11835 if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
11836 rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11837
11838 rtw_iface_disable_tsf_update(adapter);
11839
11840 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11841 ResumeTxBeacon(adapter);
11842
11843 /* reset TSF 1/2 after ResumeTxBeacon */
11844 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11845 }
11846
11847 } else if (type == 2) {
11848 /* sta add event call back */
11849 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
11850 /* fixed beacon issue for 8191su........... */
11851 rtw_write8(adapter, 0x542 , 0x02);
11852 RetryLimit = RL_VAL_AP;
11853 }
11854
11855 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
11856 ResumeTxBeacon(adapter);
11857
11858 /* reset TSF 1/2 after ResumeTxBeacon */
11859 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
11860 }
11861 }
11862
11863 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11864 rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11865 #else /* !CONFIG_CONCURRENT_MODE */
11866 if (type == 0) { /* prepare to join */
11867 /* enable to rx data frame.Accept all data frame */
11868 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
11869
11870 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
11871 RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
11872 else /* Ad-hoc Mode */
11873 RetryLimit = RL_VAL_AP;
11874
11875 rtw_iface_enable_tsf_update(adapter);
11876
11877 } else if (type == 1) { /* joinbss_event call back when join res < 0 */
11878 rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
11879
11880 rtw_iface_disable_tsf_update(adapter);
11881
11882 } else if (type == 2) { /* sta add event call back */
11883 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
11884 RetryLimit = RL_VAL_AP;
11885 }
11886
11887 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
11888 rtw_write16(adapter, REG_RETRY_LIMIT, val16);
11889 #endif /* !CONFIG_CONCURRENT_MODE */
11890 }
11891 #endif
11892
11893 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)11894 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
11895 {
11896 u8 buf[2];
11897 int ret;
11898
11899 if (reset_port == HW_PORT0) {
11900 buf[0] = 0x1;
11901 buf[1] = 0;
11902 } else {
11903 buf[0] = 0x0;
11904 buf[1] = 0x1;
11905 }
11906
11907 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
11908
11909 return ret;
11910 }
11911
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)11912 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
11913 {
11914 u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
11915 u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
11916 REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
11917 int ret;
11918
11919 /* site survey will cause reset tsf fail */
11920 rtw_mi_buddy_scan_abort(adapter, _FALSE);
11921 reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
11922 ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
11923 if (ret != _SUCCESS)
11924 return ret;
11925
11926 while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
11927 rtw_msleep_os(100);
11928 loop_cnt++;
11929 reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
11930 }
11931
11932 return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
11933 }
11934 #endif /* CONFIG_TSF_RESET_OFFLOAD */
11935
11936 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
11937 #ifdef CONFIG_HW_P0_TSF_SYNC
11938 #ifdef CONFIG_CONCURRENT_MODE
hw_port0_tsf_sync_sel(_adapter * adapter,u8 benable,u8 hw_port,u16 tr_offset)11939 static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
11940 {
11941 u8 val8;
11942 u8 client_id = 0;
11943 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11944
11945 #ifdef CONFIG_MCC_MODE
11946 if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
11947 RTW_INFO("[MCC] do not set HW TSF sync\n");
11948 return;
11949 }
11950 #endif
11951 /* check if port0 is already synced */
11952 if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
11953 RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
11954 FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
11955 return;
11956 }
11957
11958 /* check if port0 already disable sync */
11959 if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
11960 RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
11961 return;
11962 }
11963
11964 /* check if port0 sync to port0 */
11965 if (benable && hw_port == HW_PORT0) {
11966 RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
11967 rtw_warn_on(1);
11968 return;
11969 }
11970
11971 /*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
11972 /* Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
11973 Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
11974
11975 val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
11976
11977 if (benable) {
11978 /*Disable Port0's beacon function*/
11979 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
11980
11981 /*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
11982 if (tr_offset)
11983 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
11984
11985 /*reg 0x577[6]=1*/ /*auto sync by tbtt*/
11986 rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
11987
11988 if (HW_PORT1 == hw_port)
11989 client_id = 0;
11990 else if (HW_PORT2 == hw_port)
11991 client_id = 1;
11992 else if (HW_PORT3 == hw_port)
11993 client_id = 2;
11994 else if (HW_PORT4 == hw_port)
11995 client_id = 3;
11996
11997 val8 &= 0x8F;
11998 val8 |= (BIT(6) | (client_id << 4));
11999
12000 dvobj->p0_tsf.sync_port = hw_port;
12001 dvobj->p0_tsf.offset = tr_offset;
12002 rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12003
12004 /*Enable Port0's beacon function*/
12005 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) | BIT_EN_BCN_FUNCTION);
12006 RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
12007 } else {
12008 val8 &= ~BIT(6);
12009
12010 dvobj->p0_tsf.sync_port = MAX_HW_PORT;
12011 dvobj->p0_tsf.offset = 0;
12012 rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12013 RTW_INFO("%s P0 TSF sync disable\n", __func__);
12014 }
12015 }
_search_ld_sta(_adapter * adapter,u8 include_self)12016 static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
12017 {
12018 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12019 u8 i;
12020 _adapter *iface = NULL;
12021
12022 if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
12023 RTW_ERR("STA_LD_NUM == 0\n");
12024 rtw_warn_on(1);
12025 }
12026
12027 for (i = 0; i < dvobj->iface_nums; i++) {
12028 iface = dvobj->padapters[i];
12029 if (!iface)
12030 continue;
12031 if (include_self == _FALSE && adapter == iface)
12032 continue;
12033 if (is_client_associated_to_ap(iface))
12034 break;
12035 }
12036 if (iface)
12037 RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
12038 return iface;
12039 }
12040 #endif /*CONFIG_CONCURRENT_MODE*/
12041 /*Correct port0's TSF*/
12042 /*#define DBG_P0_TSF_SYNC*/
hw_var_set_correct_tsf(PADAPTER adapter,u8 mlme_state)12043 void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
12044 {
12045 #ifdef CONFIG_CONCURRENT_MODE
12046 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12047 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12048 _adapter *sta_if = NULL;
12049 u8 hw_port;
12050
12051 RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
12052 #ifdef DBG_P0_TSF_SYNC
12053 RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
12054 RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
12055 RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
12056 if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12057 RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
12058 else
12059 RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12060 RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12061 #endif
12062 switch (mlme_state) {
12063 case MLME_STA_CONNECTED :
12064 {
12065 hw_port = rtw_hal_get_port(adapter);
12066
12067 if (!MLME_IS_STA(adapter)) {
12068 RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12069 rtw_warn_on(1);
12070 }
12071
12072 if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
12073 RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
12074 rtw_warn_on(1);
12075 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12076 }
12077
12078 if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12079 (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
12080 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12081 #ifdef DBG_P0_TSF_SYNC
12082 RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
12083 #endif
12084 }
12085 }
12086 break;
12087 case MLME_STA_DISCONNECTED :
12088 {
12089 hw_port = rtw_hal_get_port(adapter);
12090
12091 if (!MLME_IS_STA(adapter)) {
12092 RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12093 rtw_warn_on(1);
12094 }
12095
12096 if (dvobj->p0_tsf.sync_port == hw_port) {
12097 if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
12098 /* search next appropriate sta*/
12099 sta_if = _search_ld_sta(adapter, _FALSE);
12100 if (sta_if) {
12101 hw_port = rtw_hal_get_port(sta_if);
12102 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12103 #ifdef DBG_P0_TSF_SYNC
12104 RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
12105 #endif
12106 }
12107 } else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
12108 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12109 #ifdef DBG_P0_TSF_SYNC
12110 RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
12111 #endif
12112 }
12113 }
12114 }
12115 break;
12116 #ifdef CONFIG_AP_MODE
12117 case MLME_AP_STARTED :
12118 case MLME_MESH_STARTED :
12119 {
12120 if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12121 RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12122 rtw_warn_on(1);
12123 }
12124
12125 if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12126 rtw_mi_get_assoced_sta_num(adapter)) {
12127 /* get port of sta */
12128 sta_if = _search_ld_sta(adapter, _FALSE);
12129 if (sta_if) {
12130 hw_port = rtw_hal_get_port(sta_if);
12131 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12132 #ifdef DBG_P0_TSF_SYNC
12133 RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
12134 #endif
12135 }
12136 }
12137 }
12138 break;
12139 case MLME_AP_STOPPED :
12140 case MLME_MESH_STOPPED :
12141 {
12142 if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12143 RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12144 rtw_warn_on(1);
12145 }
12146 /*stop ap mode*/
12147 if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
12148 (dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
12149 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12150 #ifdef DBG_P0_TSF_SYNC
12151 RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
12152 #endif
12153 }
12154 }
12155 break;
12156 #endif /* CONFIG_AP_MODE */
12157 default :
12158 RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
12159 break;
12160 }
12161
12162 /*#ifdef DBG_P0_TSF_SYNC*/
12163 #if 1
12164 if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12165 RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
12166 else
12167 RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12168 RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12169 #endif
12170 #endif /*CONFIG_CONCURRENT_MODE*/
12171 }
12172
12173 #else /*! CONFIG_HW_P0_TSF_SYNC*/
12174
12175 #ifdef CONFIG_MI_WITH_MBSSID_CAM
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12176 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12177 {
12178 /*do nothing*/
12179 }
12180 #else /* !CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)12181 static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
12182 {
12183 if (hw_port == HW_PORT0) {
12184 /*disable related TSF function*/
12185 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
12186 #if defined(CONFIG_RTL8192F)
12187 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12188 REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
12189 #endif
12190
12191 rtw_write32(padapter, REG_TSFTR, tsf);
12192 rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
12193
12194 /*enable related TSF function*/
12195 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
12196 #if defined(CONFIG_RTL8192F)
12197 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12198 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
12199 #endif
12200 } else if (hw_port == HW_PORT1) {
12201 /*disable related TSF function*/
12202 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
12203 #if defined(CONFIG_RTL8192F)
12204 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12205 REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);
12206 #endif
12207
12208 rtw_write32(padapter, REG_TSFTR1, tsf);
12209 rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
12210
12211 /*enable related TSF function*/
12212 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
12213 #if defined(CONFIG_RTL8192F)
12214 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12215 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
12216 #endif
12217 } else
12218 RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
12219 }
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12220 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12221 {
12222 u64 tsf;
12223 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
12224 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
12225
12226 tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
12227
12228 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12229 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12230 StopTxBeacon(adapter);
12231
12232 rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
12233
12234 #ifdef CONFIG_CONCURRENT_MODE
12235 /* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
12236 if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
12237 && (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12238 ) {
12239 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12240 int i;
12241 _adapter *iface;
12242
12243 for (i = 0; i < dvobj->iface_nums; i++) {
12244 iface = dvobj->padapters[i];
12245 if (!iface)
12246 continue;
12247 if (iface == adapter)
12248 continue;
12249
12250 #ifdef CONFIG_AP_MODE
12251 if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
12252 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
12253 ) {
12254 rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
12255 #ifdef CONFIG_TSF_RESET_OFFLOAD
12256 if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
12257 RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
12258 , __func__, ADPT_ARG(iface), iface->hw_port);
12259 #endif /* CONFIG_TSF_RESET_OFFLOAD*/
12260 }
12261 #endif /* CONFIG_AP_MODE */
12262 }
12263 }
12264 #endif /* CONFIG_CONCURRENT_MODE */
12265 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12266 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12267 ResumeTxBeacon(adapter);
12268 }
12269 #endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
12270 #endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/
12271 #endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/
12272
rtw_hal_get_tsftr_by_port(_adapter * adapter,u8 port)12273 u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
12274 {
12275 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
12276 u64 tsftr = 0;
12277
12278 if (port >= hal_spec->port_num) {
12279 RTW_ERR("%s invalid port(%d) \n", __func__, port);
12280 goto exit;
12281 }
12282
12283 switch (rtw_get_chip_type(adapter)) {
12284 #if defined(CONFIG_RTL8814B)
12285 case RTL8814B:
12286 {
12287 u8 val8;
12288
12289 /* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */
12290 val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);
12291 val8 &= ~0x70;
12292 val8 |= port << 4;
12293 rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);
12294
12295 tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);
12296 tsftr = tsftr << 32;
12297 tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);
12298
12299 break;
12300 }
12301 #endif
12302 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
12303 case RTL8814A:
12304 case RTL8822B:
12305 case RTL8821C:
12306 case RTL8822C:
12307 {
12308 u8 val8;
12309
12310 /* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
12311 val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
12312 val8 &= 0x8F;
12313 val8 |= port << 4;
12314 rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
12315
12316 tsftr = rtw_read32(adapter, REG_TSFTR + 4);
12317 tsftr = tsftr << 32;
12318 tsftr |= rtw_read32(adapter, REG_TSFTR);
12319
12320 break;
12321 }
12322 #endif
12323 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
12324 || defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
12325 || defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
12326 || defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
12327 || defined(CONFIG_RTL8710B)
12328 case RTL8188E:
12329 case RTL8188F:
12330 case RTL8188GTV:
12331 case RTL8192E:
12332 case RTL8192F:
12333 case RTL8723B:
12334 case RTL8703B:
12335 case RTL8723D:
12336 case RTL8812:
12337 case RTL8821:
12338 case RTL8710B:
12339 {
12340 u32 addr;
12341
12342 if (port == HW_PORT0)
12343 addr = REG_TSFTR;
12344 else if (port == HW_PORT1)
12345 addr = REG_TSFTR1;
12346 else {
12347 RTW_ERR("%s unknown port(%d) \n", __func__, port);
12348 goto exit;
12349 }
12350
12351 tsftr = rtw_read32(adapter, addr + 4);
12352 tsftr = tsftr << 32;
12353 tsftr |= rtw_read32(adapter, addr);
12354
12355 break;
12356 }
12357 #endif
12358 default:
12359 RTW_ERR("%s unknow chip type\n", __func__);
12360 }
12361
12362 exit:
12363 return tsftr;
12364 }
12365
12366 #ifdef CONFIG_TDLS
12367 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)12368 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
12369 {
12370 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
12371 u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
12372
12373
12374 SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
12375 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
12376 switch (bwmode) {
12377 case CHANNEL_WIDTH_40:
12378 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
12379 break;
12380 case CHANNEL_WIDTH_80:
12381 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
12382 break;
12383 case CHANNEL_WIDTH_20:
12384 default:
12385 break;
12386 }
12387 SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
12388
12389 return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
12390 }
12391 #endif
12392 #endif
12393
12394 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)12395 void rtw_hal_update_uapsd_tid(_adapter *adapter)
12396 {
12397 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12398 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
12399
12400 /* write complement of pqospriv->uapsd_tid to mac register 0x693 because
12401 it's designed for "0" represents "enable" and "1" represents "disable" */
12402 rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
12403 }
12404 #endif /* CONFIG_WMMPS_STA */
12405
12406 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
12407 /* 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)12408 s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
12409 {
12410 u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
12411 u8 hw_port = rtw_hal_get_port(adapter);
12412
12413 SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
12414 RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
12415 return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
12416 }
12417 #endif
12418
12419 #define LPS_ACTIVE_TIMEOUT 50 /*number of times*/
rtw_lps_state_chk(_adapter * adapter,u8 ps_mode)12420 void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
12421 {
12422 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
12423 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12424 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12425 struct sta_priv *pstapriv = &adapter->stapriv;
12426 struct sta_info *psta = NULL;
12427 u8 ps_ready = _FALSE;
12428 s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
12429
12430 if (ps_mode == PS_MODE_ACTIVE) {
12431 #ifdef CONFIG_LPS_ACK
12432 if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {
12433 if (pwrpriv->lps_ack_status > 0) {
12434 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
12435 if (psta != NULL) {
12436 if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)
12437 RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));
12438 }
12439 }
12440 } else {
12441 RTW_WARN("LPS sctx query timeout, operation abort!!\n");
12442 return;
12443 }
12444 pwrpriv->lps_ack_status = -1;
12445 #else
12446 do {
12447 if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
12448 ps_ready = _TRUE;
12449 break;
12450 }
12451 rtw_msleep_os(1);
12452 } while (leave_wait_count--);
12453
12454 if (ps_ready == _FALSE) {
12455 RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));
12456 return;
12457 }
12458 #endif /* CONFIG_LPS_ACK */
12459 }
12460 }
12461
rtw_var_set_basic_rate(PADAPTER padapter,u8 * val)12462 void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {
12463
12464 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
12465 struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
12466 u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
12467 u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
12468 u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
12469 #if CONFIG_IEEE80211_BAND_5GHZ
12470 u16 rrsr_5g_force_mask = (RRSR_6M);
12471 u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);
12472 #endif
12473 u32 temp_RRSR;
12474
12475 HalSetBrateCfg(padapter, val, &BrateCfg);
12476 input_b = BrateCfg;
12477
12478 /* apply force and allow mask */
12479 #if CONFIG_IEEE80211_BAND_5GHZ
12480 if (pHalData->current_band_type != BAND_ON_2_4G) {
12481 BrateCfg |= rrsr_5g_force_mask;
12482 BrateCfg &= rrsr_5g_allow_mask;
12483 } else
12484 #endif
12485 { /* 2.4G */
12486 BrateCfg |= rrsr_2g_force_mask;
12487 BrateCfg &= rrsr_2g_allow_mask;
12488 }
12489 masked = BrateCfg;
12490
12491 #ifdef CONFIG_CMCC_TEST
12492 BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
12493 BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */
12494 #endif
12495
12496 /* IOT consideration */
12497 if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
12498 /* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
12499 if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
12500 BrateCfg |= RRSR_6M;
12501 }
12502 ioted = BrateCfg;
12503
12504 #ifdef CONFIG_NARROWBAND_SUPPORTING
12505 if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
12506 || (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {
12507 BrateCfg &= ~RRSR_CCK_RATES;
12508 BrateCfg |= RRSR_6M;
12509 }
12510 #endif
12511 pHalData->BasicRateSet = BrateCfg;
12512
12513 RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
12514
12515 /* Set RRSR rate table. */
12516 temp_RRSR = rtw_read32(padapter, REG_RRSR);
12517 temp_RRSR &=0xFFFF0000;
12518 temp_RRSR |=BrateCfg;
12519 rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);
12520
12521 rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
12522
12523 #if defined(CONFIG_RTL8188E)
12524 rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
12525 #endif
12526 }
12527
SetHwReg(_adapter * adapter,u8 variable,u8 * val)12528 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
12529 {
12530 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12531 u8 ret = _SUCCESS;
12532
12533 switch (variable) {
12534 case HW_VAR_MEDIA_STATUS: {
12535 u8 net_type = *((u8 *)val);
12536
12537 rtw_hal_set_msr(adapter, net_type);
12538 }
12539 break;
12540 case HW_VAR_DO_IQK:
12541 if (*val)
12542 hal_data->bNeedIQK = _TRUE;
12543 else
12544 hal_data->bNeedIQK = _FALSE;
12545 break;
12546 case HW_VAR_MAC_ADDR:
12547 #ifdef CONFIG_MI_WITH_MBSSID_CAM
12548 rtw_hal_set_macaddr_mbid(adapter, val);
12549 #else
12550 rtw_hal_set_macaddr_port(adapter, val);
12551 #endif
12552 break;
12553 case HW_VAR_BSSID:
12554 rtw_hal_set_bssid(adapter, val);
12555 break;
12556 case HW_VAR_RCR:
12557 ret = hw_var_rcr_config(adapter, *((u32 *)val));
12558 break;
12559 case HW_VAR_ON_RCR_AM:
12560 hw_var_set_rcr_am(adapter, 1);
12561 break;
12562 case HW_VAR_OFF_RCR_AM:
12563 hw_var_set_rcr_am(adapter, 0);
12564 break;
12565 case HW_VAR_BEACON_INTERVAL:
12566 hw_var_set_bcn_interval(adapter, *(u16 *)val);
12567 break;
12568 #ifdef CONFIG_MBSSID_CAM
12569 case HW_VAR_MBSSID_CAM_WRITE: {
12570 u32 cmd = 0;
12571 u32 *cam_val = (u32 *)val;
12572
12573 rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
12574 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
12575 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12576 }
12577 break;
12578 case HW_VAR_MBSSID_CAM_CLEAR: {
12579 u32 cmd;
12580 u8 entry_id = *(u8 *)val;
12581
12582 rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
12583
12584 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
12585 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
12586 }
12587 break;
12588 case HW_VAR_RCR_MBSSID_EN:
12589 if (*((u8 *)val))
12590 rtw_hal_rcr_add(adapter, RCR_ENMBID);
12591 else
12592 rtw_hal_rcr_clear(adapter, RCR_ENMBID);
12593 break;
12594 #endif
12595 case HW_VAR_PORT_SWITCH:
12596 hw_var_port_switch(adapter);
12597 break;
12598 case HW_VAR_INIT_RTS_RATE: {
12599 u16 brate_cfg = *((u16 *)val);
12600 u8 rate_index = 0;
12601 HAL_VERSION *hal_ver = &hal_data->version_id;
12602
12603 if (IS_8188E(*hal_ver)) {
12604
12605 while (brate_cfg > 0x1) {
12606 brate_cfg = (brate_cfg >> 1);
12607 rate_index++;
12608 }
12609 rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
12610 } else
12611 rtw_warn_on(1);
12612 }
12613 break;
12614 case HW_VAR_SEC_CFG: {
12615 u16 reg_scr_ori;
12616 u16 reg_scr;
12617
12618 reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
12619 reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
12620
12621 if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
12622 reg_scr |= SCR_CHK_BMC;
12623
12624 if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
12625 reg_scr |= SCR_NoSKMC;
12626
12627 if (reg_scr != reg_scr_ori)
12628 rtw_write16(adapter, REG_SECCFG, reg_scr);
12629 }
12630 break;
12631 case HW_VAR_SEC_DK_CFG: {
12632 struct security_priv *sec = &adapter->securitypriv;
12633 u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
12634
12635 if (val) { /* Enable default key related setting */
12636 reg_scr |= SCR_TXBCUSEDK;
12637 if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
12638 reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
12639 } else /* Disable default key related setting */
12640 reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
12641
12642 rtw_write8(adapter, REG_SECCFG, reg_scr);
12643 }
12644 break;
12645
12646 case HW_VAR_ASIX_IOT:
12647 /* enable ASIX IOT function */
12648 if (*((u8 *)val) == _TRUE) {
12649 /* 0xa2e[0]=0 (disable rake receiver) */
12650 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12651 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
12652 /* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
12653 rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
12654 } else {
12655 /* restore reg:0xa2e, reg:0xa1c */
12656 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
12657 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
12658 rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
12659 }
12660 break;
12661 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
12662 case HW_VAR_WOWLAN: {
12663 struct wowlan_ioctl_param *poidparam;
12664
12665 poidparam = (struct wowlan_ioctl_param *)val;
12666 switch (poidparam->subcode) {
12667 #ifdef CONFIG_WOWLAN
12668 case WOWLAN_PATTERN_CLEAN:
12669 rtw_hal_dl_pattern(adapter, 2);
12670 break;
12671 case WOWLAN_ENABLE:
12672 rtw_hal_wow_enable(adapter);
12673 break;
12674 case WOWLAN_DISABLE:
12675 rtw_hal_wow_disable(adapter);
12676 break;
12677 #endif /*CONFIG_WOWLAN*/
12678 #ifdef CONFIG_AP_WOWLAN
12679 case WOWLAN_AP_ENABLE:
12680 rtw_hal_ap_wow_enable(adapter);
12681 break;
12682 case WOWLAN_AP_DISABLE:
12683 rtw_hal_ap_wow_disable(adapter);
12684 break;
12685 #endif /*CONFIG_AP_WOWLAN*/
12686 default:
12687 break;
12688 }
12689 }
12690 break;
12691 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
12692
12693 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
12694 case HW_VAR_BCN_FUNC:
12695 hw_var_set_bcn_func(adapter, *val);
12696 break;
12697 #endif
12698
12699 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
12700 case HW_VAR_MLME_DISCONNECT:
12701 hw_var_set_mlme_disconnect(adapter);
12702 break;
12703 #endif
12704
12705 case HW_VAR_MLME_SITESURVEY:
12706 hw_var_set_mlme_sitesurvey(adapter, *val);
12707 #ifdef CONFIG_BT_COEXIST
12708 if (hal_data->EEPROMBluetoothCoexist == 1)
12709 rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
12710 #endif
12711 break;
12712
12713 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
12714 case HW_VAR_MLME_JOIN:
12715 hw_var_set_mlme_join(adapter, *val);
12716 break;
12717 #endif
12718
12719 case HW_VAR_EN_HW_UPDATE_TSF:
12720 rtw_hal_set_hw_update_tsf(adapter);
12721 break;
12722 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
12723 case HW_VAR_CORRECT_TSF:
12724 hw_var_set_correct_tsf(adapter, *val);
12725 break;
12726 #endif
12727
12728 #if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)
12729 case HW_VAR_TSF_AUTO_SYNC:
12730 if (*val == _TRUE)
12731 hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
12732 else
12733 hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
12734 break;
12735 #endif
12736 case HW_VAR_APFM_ON_MAC:
12737 hal_data->bMacPwrCtrlOn = *val;
12738 RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
12739 break;
12740 #ifdef CONFIG_WMMPS_STA
12741 case HW_VAR_UAPSD_TID:
12742 rtw_hal_update_uapsd_tid(adapter);
12743 break;
12744 #endif /* CONFIG_WMMPS_STA */
12745 #ifdef CONFIG_LPS_PG
12746 case HW_VAR_LPS_PG_HANDLE:
12747 rtw_hal_lps_pg_handler(adapter, *val);
12748 break;
12749 #endif
12750 #ifdef CONFIG_LPS_LCLK_WD_TIMER
12751 case HW_VAR_DM_IN_LPS_LCLK:
12752 rtw_phydm_wd_lps_lclk_hdl(adapter);
12753 break;
12754 #endif
12755 case HW_VAR_ENABLE_RX_BAR:
12756 if (*val == _TRUE) {
12757 /* enable RX BAR */
12758 u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12759
12760 val16 |= BIT(8);
12761 rtw_write16(adapter, REG_RXFLTMAP1, val16);
12762 } else {
12763 /* disable RX BAR */
12764 u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
12765
12766 val16 &= (~BIT(8));
12767 rtw_write16(adapter, REG_RXFLTMAP1, val16);
12768 }
12769 RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
12770 REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
12771 break;
12772 case HW_VAR_HCI_SUS_STATE:
12773 hal_data->hci_sus_state = *(u8 *)val;
12774 RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
12775 break;
12776 #if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
12777 case HW_VAR_BCN_HEAD_SEL:
12778 {
12779 u8 vap_id = *(u8 *)val;
12780
12781 if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
12782 RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
12783 rtw_warn_on(1);
12784 }
12785 if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
12786 u16 drv_pg_bndy = 0, bcn_addr = 0;
12787 u32 page_size = 0;
12788
12789 /*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
12790 rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
12791 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
12792
12793 if (vap_id != 0xFF)
12794 bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
12795 else
12796 bcn_addr = drv_pg_bndy;
12797 RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
12798 ADPT_ARG(adapter), vap_id, bcn_addr);
12799 rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
12800 (bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
12801 }
12802 }
12803 break;
12804 #endif
12805 case HW_VAR_LPS_STATE_CHK :
12806 rtw_lps_state_chk(adapter, *(u8 *)val);
12807 break;
12808
12809 #ifdef CONFIG_RTS_FULL_BW
12810 case HW_VAR_SET_RTS_BW:
12811 {
12812 #ifdef RTW_HALMAC
12813 rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));
12814 #else
12815 u8 temp;
12816 if(*val)
12817 temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );
12818 else
12819 temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));
12820 rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);
12821 /*RTW_INFO("HW_VAR_SET_RTS_BW val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/
12822 #endif
12823 }
12824 break;
12825 #endif/*CONFIG_RTS_FULL_BW*/
12826 #if defined(CONFIG_PCI_HCI)
12827 case HW_VAR_ENSWBCN:
12828 if (*val == _TRUE) {
12829 rtw_write8(adapter, REG_CR + 1,
12830 rtw_read8(adapter, REG_CR + 1) | BIT(0));
12831 } else
12832 rtw_write8(adapter, REG_CR + 1,
12833 rtw_read8(adapter, REG_CR + 1) & ~BIT(0));
12834 break;
12835 #endif
12836 default:
12837 if (0)
12838 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12839 FUNC_ADPT_ARG(adapter), variable);
12840 ret = _FAIL;
12841 break;
12842 }
12843
12844 return ret;
12845 }
12846
GetHwReg(_adapter * adapter,u8 variable,u8 * val)12847 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
12848 {
12849 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12850 u64 val64;
12851
12852
12853 switch (variable) {
12854 case HW_VAR_MAC_ADDR:
12855 #ifndef CONFIG_MI_WITH_MBSSID_CAM
12856 rtw_hal_get_macaddr_port(adapter, val);
12857 #endif
12858 break;
12859 case HW_VAR_BASIC_RATE:
12860 *((u16 *)val) = hal_data->BasicRateSet;
12861 break;
12862 case HW_VAR_MEDIA_STATUS:
12863 rtw_hal_get_msr(adapter, val);
12864 break;
12865 case HW_VAR_DO_IQK:
12866 *val = hal_data->bNeedIQK;
12867 break;
12868 case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
12869 if (hal_is_band_support(adapter, BAND_ON_5G))
12870 *val = _TRUE;
12871 else
12872 *val = _FALSE;
12873 break;
12874 case HW_VAR_APFM_ON_MAC:
12875 *val = hal_data->bMacPwrCtrlOn;
12876 break;
12877 case HW_VAR_RCR:
12878 hw_var_rcr_get(adapter, (u32 *)val);
12879 break;
12880 case HW_VAR_FWLPS_RF_ON:
12881 /* When we halt NIC, we should check if FW LPS is leave. */
12882 if (rtw_is_surprise_removed(adapter)
12883 || (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
12884 ) {
12885 /*
12886 * If it is in HW/SW Radio OFF or IPS state,
12887 * we do not check Fw LPS Leave,
12888 * because Fw is unload.
12889 */
12890 *val = _TRUE;
12891 } else {
12892 u32 rcr = 0;
12893
12894 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
12895 if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
12896 *val = _FALSE;
12897 else
12898 *val = _TRUE;
12899 }
12900 break;
12901
12902 case HW_VAR_HCI_SUS_STATE:
12903 *((u8 *)val) = hal_data->hci_sus_state;
12904 break;
12905
12906 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
12907 case HW_VAR_BCN_CTRL_ADDR:
12908 *((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
12909 break;
12910 #endif
12911
12912 #ifdef CONFIG_WAPI_SUPPORT
12913 case HW_VAR_CAM_EMPTY_ENTRY: {
12914 u8 ucIndex = *((u8 *)val);
12915 u8 i;
12916 u32 ulCommand = 0;
12917 u32 ulContent = 0;
12918 u32 ulEncAlgo = CAM_AES;
12919
12920 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
12921 /* filled id in CAM config 2 byte */
12922 if (i == 0)
12923 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
12924 else
12925 ulContent = 0;
12926 /* polling bit, and No Write enable, and address */
12927 ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
12928 ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
12929 /* write content 0 is equall to mark invalid */
12930 rtw_write32(adapter, REG_CAMWRITE, ulContent); /* delay_ms(40); */
12931 rtw_write32(adapter, REG_CAMCMD, ulCommand); /* delay_ms(40); */
12932 }
12933 }
12934 #endif
12935
12936 default:
12937 if (0)
12938 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
12939 FUNC_ADPT_ARG(adapter), variable);
12940 break;
12941 }
12942
12943 }
12944
_get_page_size(struct _ADAPTER * a)12945 static u32 _get_page_size(struct _ADAPTER *a)
12946 {
12947 #ifdef RTW_HALMAC
12948 struct dvobj_priv *d;
12949 u32 size = 0;
12950 int err = 0;
12951
12952
12953 d = adapter_to_dvobj(a);
12954
12955 err = rtw_halmac_get_page_size(d, &size);
12956 if (!err)
12957 return size;
12958
12959 RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
12960 FUNC_ADPT_ARG(a), err);
12961 #endif /* RTW_HALMAC */
12962
12963 return PAGE_SIZE_128;
12964 }
12965
12966 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)12967 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
12968 {
12969 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12970 u8 bResult = _SUCCESS;
12971
12972 switch (variable) {
12973
12974 case HAL_DEF_DBG_DUMP_RXPKT:
12975 hal_data->bDumpRxPkt = *((u8 *)value);
12976 break;
12977 case HAL_DEF_DBG_DUMP_TXPKT:
12978 hal_data->bDumpTxPkt = *((u8 *)value);
12979 break;
12980 case HAL_DEF_ANT_DETECT:
12981 hal_data->AntDetection = *((u8 *)value);
12982 break;
12983 default:
12984 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
12985 bResult = _FAIL;
12986 break;
12987 }
12988
12989 return bResult;
12990 }
12991
12992 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)12993 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
12994 {
12995 struct registry_priv *pregistrypriv = &adapter->registrypriv;
12996 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12997
12998 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)))
12999 return pregistrypriv->beamformer_rf_num;
13000 else if (IS_HARDWARE_TYPE_8814AE(adapter)
13001 #if 0
13002 #if defined(CONFIG_USB_HCI)
13003 || (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) /* for USB3.0 */
13004 #endif
13005 #endif
13006 ) {
13007 /*BF cap provided by Yu Chen, Sean, 2015, 01 */
13008 if (hal_data->rf_type == RF_3T3R)
13009 return 2;
13010 else if (hal_data->rf_type == RF_4T4R)
13011 return 3;
13012 else
13013 return 1;
13014 } else
13015 return 1;
13016
13017 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)13018 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
13019 {
13020 struct registry_priv *pregistrypriv = &adapter->registrypriv;
13021 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13022 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13023
13024 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13025
13026 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)))
13027 return pregistrypriv->beamformee_rf_num;
13028 else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
13029 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
13030 return 2;
13031 else
13032 return 2;/*TODO: May be 3 in the future, by ChenYu. */
13033 } else
13034 return 1;
13035
13036 }
13037 #ifdef RTW_BEAMFORMING_VERSION_2
rtw_hal_beamforming_config_csirate(PADAPTER adapter)13038 void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
13039 {
13040 struct dm_struct *p_dm_odm;
13041 struct beamforming_info *bf_info;
13042 u8 fix_rate_enable = 0;
13043 u8 new_csi_rate_idx;
13044 u8 rrsr_54_en;
13045 u32 temp_rrsr;
13046
13047 /* Acting as BFee */
13048 if (IS_BEAMFORMEE(adapter)) {
13049 #if 0
13050 /* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
13051 if (IS_HARDWARE_TYPE_8821C(Adapter))
13052 FixRateEnable = 1; /* Support after 8821C */
13053 #endif
13054
13055 p_dm_odm = adapter_to_phydm(adapter);
13056 bf_info = GET_BEAMFORM_INFO(adapter);
13057
13058 rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
13059 p_dm_odm->rssi_min,
13060 bf_info->cur_csi_rpt_rate,
13061 fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);
13062
13063 temp_rrsr = rtw_read32(adapter, REG_RRSR);
13064 if (rrsr_54_en == 1)
13065 temp_rrsr |= RRSR_54M;
13066 else if (rrsr_54_en == 0)
13067 temp_rrsr &= ~RRSR_54M;
13068 rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);
13069
13070 if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
13071 bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
13072 }
13073 }
13074 #endif
13075 #endif
13076
13077 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13078 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13079 {
13080 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13081 u8 bResult = _SUCCESS;
13082
13083 switch (variable) {
13084 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
13085 struct mlme_priv *pmlmepriv;
13086 struct sta_priv *pstapriv;
13087 struct sta_info *psta;
13088
13089 pmlmepriv = &adapter->mlmepriv;
13090 pstapriv = &adapter->stapriv;
13091 psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
13092 if (psta)
13093 *((int *)value) = psta->cmn.rssi_stat.rssi;
13094 }
13095 break;
13096 case HAL_DEF_DBG_DUMP_RXPKT:
13097 *((u8 *)value) = hal_data->bDumpRxPkt;
13098 break;
13099 case HAL_DEF_DBG_DUMP_TXPKT:
13100 *((u8 *)value) = hal_data->bDumpTxPkt;
13101 break;
13102 case HAL_DEF_ANT_DETECT:
13103 *((u8 *)value) = hal_data->AntDetection;
13104 break;
13105 case HAL_DEF_TX_PAGE_SIZE:
13106 *((u32 *)value) = _get_page_size(adapter);
13107 break;
13108 case HAL_DEF_TX_STBC:
13109 #ifdef CONFIG_ALPHA_SMART_ANTENNA
13110 *(u8 *)value = 0;
13111 #else
13112 *(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;
13113 #endif
13114 break;
13115 case HAL_DEF_EXPLICIT_BEAMFORMER:
13116 case HAL_DEF_EXPLICIT_BEAMFORMEE:
13117 case HAL_DEF_VHT_MU_BEAMFORMER:
13118 case HAL_DEF_VHT_MU_BEAMFORMEE:
13119 *(u8 *)value = _FALSE;
13120 break;
13121 #ifdef CONFIG_BEAMFORMING
13122 case HAL_DEF_BEAMFORMER_CAP:
13123 *(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
13124 break;
13125 case HAL_DEF_BEAMFORMEE_CAP:
13126 *(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
13127 break;
13128 #endif
13129 default:
13130 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
13131 bResult = _FAIL;
13132 break;
13133 }
13134
13135 return bResult;
13136 }
13137
13138 /*
13139 * Description:
13140 * Translate a character to hex digit.
13141 * */
13142 u32
MapCharToHexDigit(char chTmp)13143 MapCharToHexDigit(
13144 char chTmp
13145 )
13146 {
13147 if (chTmp >= '0' && chTmp <= '9')
13148 return chTmp - '0';
13149 else if (chTmp >= 'a' && chTmp <= 'f')
13150 return 10 + (chTmp - 'a');
13151 else if (chTmp >= 'A' && chTmp <= 'F')
13152 return 10 + (chTmp - 'A');
13153 else
13154 return 0;
13155 }
13156
13157
13158
13159 /*
13160 * Description:
13161 * Parse hex number from the string pucStr.
13162 * */
13163 BOOLEAN
GetHexValueFromString(char * szStr,u32 * pu4bVal,u32 * pu4bMove)13164 GetHexValueFromString(
13165 char *szStr,
13166 u32 *pu4bVal,
13167 u32 *pu4bMove
13168 )
13169 {
13170 char *szScan = szStr;
13171
13172 /* Check input parameter. */
13173 if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
13174 RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
13175 return _FALSE;
13176 }
13177
13178 /* Initialize output. */
13179 *pu4bMove = 0;
13180 *pu4bVal = 0;
13181
13182 /* Skip leading space. */
13183 while (*szScan != '\0' &&
13184 (*szScan == ' ' || *szScan == '\t')) {
13185 szScan++;
13186 (*pu4bMove)++;
13187 }
13188
13189 /* Skip leading '0x' or '0X'. */
13190 if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
13191 szScan += 2;
13192 (*pu4bMove) += 2;
13193 }
13194
13195 /* Check if szScan is now pointer to a character for hex digit, */
13196 /* if not, it means this is not a valid hex number. */
13197 if (!IsHexDigit(*szScan))
13198 return _FALSE;
13199
13200 /* Parse each digit. */
13201 do {
13202 (*pu4bVal) <<= 4;
13203 *pu4bVal += MapCharToHexDigit(*szScan);
13204
13205 szScan++;
13206 (*pu4bMove)++;
13207 } while (IsHexDigit(*szScan));
13208
13209 return _TRUE;
13210 }
13211
13212 BOOLEAN
GetFractionValueFromString(char * szStr,u8 * pInteger,u8 * pFraction,u32 * pu4bMove)13213 GetFractionValueFromString(
13214 char *szStr,
13215 u8 *pInteger,
13216 u8 *pFraction,
13217 u32 *pu4bMove
13218 )
13219 {
13220 char *szScan = szStr;
13221
13222 /* Initialize output. */
13223 *pu4bMove = 0;
13224 *pInteger = 0;
13225 *pFraction = 0;
13226
13227 /* Skip leading space. */
13228 while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) {
13229 ++szScan;
13230 ++(*pu4bMove);
13231 }
13232
13233 if (*szScan < '0' || *szScan > '9')
13234 return _FALSE;
13235
13236 /* Parse each digit. */
13237 do {
13238 (*pInteger) *= 10;
13239 *pInteger += (*szScan - '0');
13240
13241 ++szScan;
13242 ++(*pu4bMove);
13243
13244 if (*szScan == '.') {
13245 ++szScan;
13246 ++(*pu4bMove);
13247
13248 if (*szScan < '0' || *szScan > '9')
13249 return _FALSE;
13250
13251 *pFraction += (*szScan - '0') * 10;
13252 ++szScan;
13253 ++(*pu4bMove);
13254
13255 if (*szScan >= '0' && *szScan <= '9') {
13256 *pFraction += *szScan - '0';
13257 ++szScan;
13258 ++(*pu4bMove);
13259 }
13260 return _TRUE;
13261 }
13262 } while (*szScan >= '0' && *szScan <= '9');
13263
13264 return _TRUE;
13265 }
13266
13267 /*
13268 * Description:
13269 * Return TRUE if szStr is comment out with leading " */ /* ".
13270 * */
13271 BOOLEAN
IsCommentString(char * szStr)13272 IsCommentString(
13273 char *szStr
13274 )
13275 {
13276 if (*szStr == '/' && *(szStr + 1) == '/')
13277 return _TRUE;
13278 else
13279 return _FALSE;
13280 }
13281
13282 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(char * Str,u8 * pInt)13283 GetU1ByteIntegerFromStringInDecimal(
13284 char *Str,
13285 u8 *pInt
13286 )
13287 {
13288 u16 i = 0;
13289 *pInt = 0;
13290
13291 while (Str[i] != '\0') {
13292 if (Str[i] >= '0' && Str[i] <= '9') {
13293 *pInt *= 10;
13294 *pInt += (Str[i] - '0');
13295 } else
13296 return _FALSE;
13297 ++i;
13298 }
13299
13300 return _TRUE;
13301 }
13302
13303 /* <20121004, Kordan> For example,
13304 * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
13305 * If RightQualifier does not exist, it will hang on in the while loop */
13306 BOOLEAN
ParseQualifiedString(char * In,u32 * Start,char * Out,char LeftQualifier,char RightQualifier)13307 ParseQualifiedString(
13308 char *In,
13309 u32 *Start,
13310 char *Out,
13311 char LeftQualifier,
13312 char RightQualifier
13313 )
13314 {
13315 u32 i = 0, j = 0;
13316 char c = In[(*Start)++];
13317
13318 if (c != LeftQualifier)
13319 return _FALSE;
13320
13321 i = (*Start);
13322 c = In[(*Start)++];
13323 while (c != RightQualifier && c != '\0')
13324 c = In[(*Start)++];
13325
13326 if (c == '\0')
13327 return _FALSE;
13328
13329 j = (*Start) - 2;
13330 strncpy((char *)Out, (const char *)(In + i), j - i + 1);
13331
13332 return _TRUE;
13333 }
13334
13335 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)13336 isAllSpaceOrTab(
13337 u8 *data,
13338 u8 size
13339 )
13340 {
13341 u8 cnt = 0, NumOfSpaceAndTab = 0;
13342
13343 while (size > cnt) {
13344 if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
13345 ++NumOfSpaceAndTab;
13346
13347 ++cnt;
13348 }
13349
13350 return size == NumOfSpaceAndTab;
13351 }
13352
13353
rtw_hal_check_rxfifo_full(_adapter * adapter)13354 void rtw_hal_check_rxfifo_full(_adapter *adapter)
13355 {
13356 struct dvobj_priv *psdpriv = adapter->dvobj;
13357 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
13358 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
13359 struct registry_priv *regsty = &adapter->registrypriv;
13360 int save_cnt = _FALSE;
13361
13362 if (regsty->check_hw_status == 1) {
13363 /* switch counter to RX fifo */
13364 if (IS_8188E(pHalData->version_id) ||
13365 IS_8188F(pHalData->version_id) ||
13366 IS_8188GTV(pHalData->version_id) ||
13367 IS_8812_SERIES(pHalData->version_id) ||
13368 IS_8821_SERIES(pHalData->version_id) ||
13369 IS_8723B_SERIES(pHalData->version_id) ||
13370 IS_8192E(pHalData->version_id) ||
13371 IS_8703B_SERIES(pHalData->version_id) ||
13372 IS_8723D_SERIES(pHalData->version_id) ||
13373 IS_8192F_SERIES(pHalData->version_id)) {
13374 rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
13375 save_cnt = _TRUE;
13376 } else {
13377 /* todo: other chips */
13378 }
13379
13380
13381 if (save_cnt) {
13382 pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
13383 pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
13384 pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
13385 } else {
13386 /* special value to indicate no implementation */
13387 pdbgpriv->dbg_rx_fifo_last_overflow = 1;
13388 pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
13389 pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
13390 }
13391 }
13392 }
13393
linked_info_dump(_adapter * padapter,u8 benable)13394 void linked_info_dump(_adapter *padapter, u8 benable)
13395 {
13396 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
13397
13398 if (padapter->bLinkInfoDump == benable)
13399 return;
13400
13401 RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
13402
13403 if (benable) {
13404 #ifdef CONFIG_LPS
13405 pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
13406 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
13407 #endif
13408
13409 #ifdef CONFIG_IPS
13410 pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
13411 rtw_pm_set_ips(padapter, IPS_NONE);
13412 #endif
13413 } else {
13414 #ifdef CONFIG_IPS
13415 rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
13416 #endif /* CONFIG_IPS */
13417
13418 #ifdef CONFIG_LPS
13419 rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
13420 #endif /* CONFIG_LPS */
13421 }
13422 padapter->bLinkInfoDump = benable ;
13423 }
13424
13425 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)13426 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
13427 {
13428 u8 isCCKrate, rf_path;
13429 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13430 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13431 RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
13432 HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
13433 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13434
13435 if (isCCKrate)
13436 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13437
13438 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13439 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13440 continue;
13441 RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
13442 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13443
13444 if (!isCCKrate) {
13445 RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
13446 psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
13447 }
13448 }
13449 }
13450
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)13451 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
13452 {
13453 u8 isCCKrate, rf_path;
13454 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13455 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13456 _RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
13457 _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);
13458
13459 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13460
13461 if (isCCKrate)
13462 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
13463
13464 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13465 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13466 continue;
13467 _RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
13468 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
13469
13470 if (!isCCKrate)
13471 _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]);
13472 else
13473 _RTW_PRINT_SEL(sel , "\n");
13474
13475 }
13476 }
13477 #endif
13478
13479 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)13480 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
13481 {
13482 #define DBG_RX_DFRAME_RAW_DATA_UC 0
13483 #define DBG_RX_DFRAME_RAW_DATA_BMC 1
13484 #define DBG_RX_DFRAME_RAW_DATA_TYPES 2
13485
13486 _irqL irqL;
13487 u8 isCCKrate, rf_path;
13488 struct recv_priv *precvpriv = &(padapter->recvpriv);
13489 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13490 struct sta_priv *pstapriv = &padapter->stapriv;
13491 struct sta_info *psta;
13492 struct sta_recv_dframe_info *psta_dframe_info;
13493 int i, j;
13494 _list *plist, *phead;
13495 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13496 u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
13497
13498 if (precvpriv->store_law_data_flag) {
13499
13500 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13501
13502 for (i = 0; i < NUM_STA; i++) {
13503 phead = &(pstapriv->sta_hash[i]);
13504 plist = get_next(phead);
13505
13506 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
13507
13508 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
13509 plist = get_next(plist);
13510
13511 if (psta) {
13512 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE)
13513 && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN) != _TRUE)
13514 && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN) != _TRUE)) {
13515
13516 RTW_PRINT_SEL(sel, "==============================\n");
13517 RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
13518
13519 for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
13520 if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
13521 psta_dframe_info = &psta->sta_dframe_info;
13522 RTW_PRINT_SEL(sel, "\n");
13523 RTW_PRINT_SEL(sel, "Unicast:\n");
13524 } else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
13525 psta_dframe_info = &psta->sta_dframe_info_bmc;
13526 RTW_PRINT_SEL(sel, "\n");
13527 RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
13528 }
13529
13530 isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13531
13532 RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
13533 RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
13534
13535 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13536 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
13537 continue;
13538 if (!isCCKrate) {
13539 RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
13540 _RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
13541 } else
13542 RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
13543 }
13544 }
13545
13546 }
13547 }
13548 }
13549 }
13550 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
13551 }
13552 }
13553 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)13554 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
13555 {
13556 u8 isCCKrate, rf_path , dframe_type;
13557 u8 *ptr;
13558 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
13559 #ifdef DBG_RX_DFRAME_RAW_DATA
13560 struct sta_recv_dframe_info *psta_dframe_info;
13561 #endif
13562 struct recv_priv *precvpriv = &(padapter->recvpriv);
13563 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
13564 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
13565 struct sta_info *psta = prframe->u.hdr.psta;
13566 struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
13567 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
13568 psample_pkt_rssi->data_rate = pattrib->data_rate;
13569 ptr = prframe->u.hdr.rx_data;
13570 dframe_type = GetFrameType(ptr);
13571 /*RTW_INFO("=>%s\n", __FUNCTION__);*/
13572
13573
13574 if (precvpriv->store_law_data_flag) {
13575 isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
13576
13577 psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
13578 psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
13579
13580 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13581 psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
13582 psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
13583 if (!isCCKrate) {
13584 psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13585 psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13586 }
13587 }
13588 #ifdef DBG_RX_DFRAME_RAW_DATA
13589 if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
13590
13591 /*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
13592 if (psta) {
13593 if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
13594 psta_dframe_info = &psta->sta_dframe_info_bmc;
13595 else
13596 psta_dframe_info = &psta->sta_dframe_info;
13597 /*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
13598 __FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
13599 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
13600 psta_dframe_info->sta_data_rate = pattrib->data_rate;
13601 psta_dframe_info->sta_sgi = pattrib->sgi;
13602 psta_dframe_info->sta_bw_mode = pattrib->bw;
13603 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
13604
13605 psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
13606
13607 if (!isCCKrate) {
13608 psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
13609 psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
13610 }
13611 }
13612 }
13613 }
13614 }
13615 #endif
13616 }
13617
13618 }
13619
hal_efuse_macaddr_offset(_adapter * adapter)13620 int hal_efuse_macaddr_offset(_adapter *adapter)
13621 {
13622 u8 interface_type = 0;
13623 int addr_offset = -1;
13624
13625 interface_type = rtw_get_intf_type(adapter);
13626
13627 switch (rtw_get_chip_type(adapter)) {
13628 #ifdef CONFIG_RTL8723B
13629 case RTL8723B:
13630 if (interface_type == RTW_USB)
13631 addr_offset = EEPROM_MAC_ADDR_8723BU;
13632 else if (interface_type == RTW_SDIO)
13633 addr_offset = EEPROM_MAC_ADDR_8723BS;
13634 else if (interface_type == RTW_PCIE)
13635 addr_offset = EEPROM_MAC_ADDR_8723BE;
13636 break;
13637 #endif
13638 #ifdef CONFIG_RTL8703B
13639 case RTL8703B:
13640 if (interface_type == RTW_USB)
13641 addr_offset = EEPROM_MAC_ADDR_8703BU;
13642 else if (interface_type == RTW_SDIO)
13643 addr_offset = EEPROM_MAC_ADDR_8703BS;
13644 break;
13645 #endif
13646 #ifdef CONFIG_RTL8723D
13647 case RTL8723D:
13648 if (interface_type == RTW_USB)
13649 addr_offset = EEPROM_MAC_ADDR_8723DU;
13650 else if (interface_type == RTW_SDIO)
13651 addr_offset = EEPROM_MAC_ADDR_8723DS;
13652 else if (interface_type == RTW_PCIE)
13653 addr_offset = EEPROM_MAC_ADDR_8723DE;
13654 break;
13655 #endif
13656
13657 #ifdef CONFIG_RTL8188E
13658 case RTL8188E:
13659 if (interface_type == RTW_USB)
13660 addr_offset = EEPROM_MAC_ADDR_88EU;
13661 else if (interface_type == RTW_SDIO)
13662 addr_offset = EEPROM_MAC_ADDR_88ES;
13663 else if (interface_type == RTW_PCIE)
13664 addr_offset = EEPROM_MAC_ADDR_88EE;
13665 break;
13666 #endif
13667 #ifdef CONFIG_RTL8188F
13668 case RTL8188F:
13669 if (interface_type == RTW_USB)
13670 addr_offset = EEPROM_MAC_ADDR_8188FU;
13671 else if (interface_type == RTW_SDIO)
13672 addr_offset = EEPROM_MAC_ADDR_8188FS;
13673 break;
13674 #endif
13675 #ifdef CONFIG_RTL8188GTV
13676 case RTL8188GTV:
13677 if (interface_type == RTW_USB)
13678 addr_offset = EEPROM_MAC_ADDR_8188GTVU;
13679 else if (interface_type == RTW_SDIO)
13680 addr_offset = EEPROM_MAC_ADDR_8188GTVS;
13681 break;
13682 #endif
13683 #ifdef CONFIG_RTL8812A
13684 case RTL8812:
13685 if (interface_type == RTW_USB)
13686 addr_offset = EEPROM_MAC_ADDR_8812AU;
13687 else if (interface_type == RTW_PCIE)
13688 addr_offset = EEPROM_MAC_ADDR_8812AE;
13689 break;
13690 #endif
13691 #ifdef CONFIG_RTL8821A
13692 case RTL8821:
13693 if (interface_type == RTW_USB)
13694 addr_offset = EEPROM_MAC_ADDR_8821AU;
13695 else if (interface_type == RTW_SDIO)
13696 addr_offset = EEPROM_MAC_ADDR_8821AS;
13697 else if (interface_type == RTW_PCIE)
13698 addr_offset = EEPROM_MAC_ADDR_8821AE;
13699 break;
13700 #endif
13701 #ifdef CONFIG_RTL8192E
13702 case RTL8192E:
13703 if (interface_type == RTW_USB)
13704 addr_offset = EEPROM_MAC_ADDR_8192EU;
13705 else if (interface_type == RTW_SDIO)
13706 addr_offset = EEPROM_MAC_ADDR_8192ES;
13707 else if (interface_type == RTW_PCIE)
13708 addr_offset = EEPROM_MAC_ADDR_8192EE;
13709 break;
13710 #endif
13711 #ifdef CONFIG_RTL8814A
13712 case RTL8814A:
13713 if (interface_type == RTW_USB)
13714 addr_offset = EEPROM_MAC_ADDR_8814AU;
13715 else if (interface_type == RTW_PCIE)
13716 addr_offset = EEPROM_MAC_ADDR_8814AE;
13717 break;
13718 #endif
13719
13720 #ifdef CONFIG_RTL8822B
13721 case RTL8822B:
13722 if (interface_type == RTW_USB)
13723 addr_offset = EEPROM_MAC_ADDR_8822BU;
13724 else if (interface_type == RTW_SDIO)
13725 addr_offset = EEPROM_MAC_ADDR_8822BS;
13726 else if (interface_type == RTW_PCIE)
13727 addr_offset = EEPROM_MAC_ADDR_8822BE;
13728 break;
13729 #endif /* CONFIG_RTL8822B */
13730
13731 #ifdef CONFIG_RTL8821C
13732 case RTL8821C:
13733 if (interface_type == RTW_USB)
13734 addr_offset = EEPROM_MAC_ADDR_8821CU;
13735 else if (interface_type == RTW_SDIO)
13736 addr_offset = EEPROM_MAC_ADDR_8821CS;
13737 else if (interface_type == RTW_PCIE)
13738 addr_offset = EEPROM_MAC_ADDR_8821CE;
13739 break;
13740 #endif /* CONFIG_RTL8821C */
13741
13742 #ifdef CONFIG_RTL8710B
13743 case RTL8710B:
13744 if (interface_type == RTW_USB)
13745 addr_offset = EEPROM_MAC_ADDR_8710B;
13746 break;
13747 #endif
13748
13749 #ifdef CONFIG_RTL8192F
13750 case RTL8192F:
13751 if (interface_type == RTW_USB)
13752 addr_offset = EEPROM_MAC_ADDR_8192FU;
13753 else if (interface_type == RTW_SDIO)
13754 addr_offset = EEPROM_MAC_ADDR_8192FS;
13755 else if (interface_type == RTW_PCIE)
13756 addr_offset = EEPROM_MAC_ADDR_8192FE;
13757 break;
13758 #endif /* CONFIG_RTL8192F */
13759
13760 #ifdef CONFIG_RTL8822C
13761 case RTL8822C:
13762 if (interface_type == RTW_USB)
13763 addr_offset = EEPROM_MAC_ADDR_8822CU;
13764 else if (interface_type == RTW_SDIO)
13765 addr_offset = EEPROM_MAC_ADDR_8822CS;
13766 else if (interface_type == RTW_PCIE)
13767 addr_offset = EEPROM_MAC_ADDR_8822CE;
13768 break;
13769 #endif /* CONFIG_RTL8822C */
13770
13771 #ifdef CONFIG_RTL8814B
13772 case RTL8814B:
13773 if (interface_type == RTW_USB)
13774 addr_offset = EEPROM_MAC_ADDR_8814BU;
13775 else if (interface_type == RTW_PCIE)
13776 addr_offset = EEPROM_MAC_ADDR_8814BE;
13777 break;
13778 #endif /* CONFIG_RTL8814B */
13779 }
13780
13781 if (addr_offset == -1) {
13782 RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
13783 , __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
13784 }
13785
13786 return addr_offset;
13787 }
13788
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)13789 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
13790 {
13791 int ret = _FAIL;
13792 int addr_offset;
13793
13794 addr_offset = hal_efuse_macaddr_offset(padapter);
13795 if (addr_offset == -1)
13796 goto exit;
13797
13798 ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
13799
13800 exit:
13801 return ret;
13802 }
13803
rtw_dump_cur_efuse(PADAPTER padapter)13804 void rtw_dump_cur_efuse(PADAPTER padapter)
13805 {
13806 int mapsize =0;
13807 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13808
13809 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
13810
13811 if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
13812 RTW_ERR("wrong map size %d\n", mapsize);
13813 return;
13814 }
13815
13816 #ifdef CONFIG_RTW_DEBUG
13817 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13818 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
13819 else
13820 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
13821 #endif
13822 }
13823
13824
13825 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)13826 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
13827 {
13828 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13829 u32 ret = _FALSE;
13830 u32 maplen = 0;
13831
13832 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
13833
13834 if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
13835 RTW_ERR("eFuse length error :%d\n", maplen);
13836 return _FALSE;
13837 }
13838
13839 ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
13840
13841 hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
13842
13843 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13844 rtw_dump_cur_efuse(padapter);
13845
13846 return ret;
13847 }
13848
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)13849 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
13850 {
13851 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
13852 u32 ret = _FAIL;
13853
13854 if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
13855 && rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
13856 ) {
13857 hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
13858 ret = _SUCCESS;
13859 } else
13860 hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
13861
13862 return ret;
13863 }
13864 #endif /* CONFIG_EFUSE_CONFIG_FILE */
13865
hal_config_macaddr(_adapter * adapter,bool autoload_fail)13866 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
13867 {
13868 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13869 u8 addr[ETH_ALEN];
13870 int addr_offset = hal_efuse_macaddr_offset(adapter);
13871 u8 *hw_addr = NULL;
13872 int ret = _SUCCESS;
13873 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13874 u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
13875 #endif
13876
13877 if (autoload_fail)
13878 goto bypass_hw_pg;
13879
13880 if (addr_offset != -1)
13881 hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
13882
13883 #ifdef CONFIG_EFUSE_CONFIG_FILE
13884 /* if the hw_addr is written by efuse file, set to NULL */
13885 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
13886 hw_addr = NULL;
13887 #endif
13888
13889 if (!hw_addr) {
13890 /* try getting hw pg data */
13891 if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
13892 hw_addr = addr;
13893 }
13894
13895 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
13896 if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
13897 hw_addr[0] = 0xff;
13898 #endif
13899
13900 /* check hw pg data */
13901 if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
13902 _rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
13903 goto exit;
13904 }
13905
13906 bypass_hw_pg:
13907
13908 #ifdef CONFIG_EFUSE_CONFIG_FILE
13909 /* check wifi mac file */
13910 if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
13911 _rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
13912 goto exit;
13913 }
13914 #endif
13915
13916 _rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
13917 ret = _FAIL;
13918
13919 exit:
13920 return ret;
13921 }
13922
13923 #ifdef CONFIG_RF_POWER_TRIM
13924 u32 Array_kfreemap[] = {
13925 0x08, 0xe,
13926 0x06, 0xc,
13927 0x04, 0xa,
13928 0x02, 0x8,
13929 0x00, 0x6,
13930 0x03, 0x4,
13931 0x05, 0x2,
13932 0x07, 0x0,
13933 0x09, 0x0,
13934 0x0c, 0x0,
13935 };
13936
rtw_bb_rf_gain_offset(_adapter * padapter)13937 void rtw_bb_rf_gain_offset(_adapter *padapter)
13938 {
13939 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
13940 struct registry_priv *registry_par = &padapter->registrypriv;
13941 struct kfree_data_t *kfree_data = &pHalData->kfree_data;
13942 u8 value = pHalData->EEPROMRFGainOffset;
13943 u8 tmp = 0x3e;
13944 u32 res, i = 0;
13945 u32 ArrayLen = sizeof(Array_kfreemap) / sizeof(u32);
13946 u32 *Array = Array_kfreemap;
13947 u32 v1 = 0, v2 = 0, GainValue = 0, target = 0;
13948
13949 if (registry_par->RegPwrTrimEnable == 2) {
13950 RTW_INFO("Registry kfree default force disable.\n");
13951 return;
13952 }
13953
13954 #if defined(CONFIG_RTL8723B)
13955 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
13956 RTW_INFO("Offset RF Gain.\n");
13957 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
13958
13959 if (pHalData->EEPROMRFGainVal != 0xff) {
13960
13961 if (pHalData->ant_path == RF_PATH_A)
13962 GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
13963
13964 else
13965 GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
13966 RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
13967
13968 for (i = 0; i < ArrayLen; i += 2) {
13969 /* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
13970 v1 = Array[i];
13971 v2 = Array[i + 1];
13972 if (v1 == GainValue) {
13973 RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
13974 target = v2;
13975 break;
13976 }
13977 }
13978 RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
13979
13980 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13981 RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
13982 phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
13983 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
13984
13985 RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
13986
13987 } else
13988
13989 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
13990 } else
13991 RTW_INFO("Using the default RF gain.\n");
13992
13993 #elif defined(CONFIG_RTL8188E)
13994 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
13995 RTW_INFO("8188ES Offset RF Gain.\n");
13996 RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
13997 pHalData->EEPROMRFGainVal);
13998
13999 if (pHalData->EEPROMRFGainVal != 0xff) {
14000 res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
14001 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
14002
14003 RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
14004 res &= 0xfff87fff;
14005
14006 res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
14007 RTW_INFO("Offset RF Gain. res=0x%x\n", res);
14008
14009 rtw_hal_write_rfreg(padapter, RF_PATH_A,
14010 REG_RF_BB_GAIN_OFFSET,
14011 RF_GAIN_OFFSET_MASK, res);
14012 } else {
14013 RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
14014 pHalData->EEPROMRFGainVal);
14015 }
14016 } else
14017 RTW_INFO("Using the default RF gain.\n");
14018 #else
14019 /* TODO: call this when channel switch */
14020 if (kfree_data->flag & KFREE_FLAG_ON)
14021 rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
14022 #endif
14023
14024 }
14025 #endif /*CONFIG_RF_POWER_TRIM */
14026
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)14027 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
14028 {
14029 #ifdef CONFIG_RF_POWER_TRIM
14030 int i, j;
14031
14032 for (i = 0; i < BB_GAIN_NUM; i++)
14033 for (j = 0; j < RF_PATH_MAX; j++)
14034 if (data->bb_gain[i][j] != 0)
14035 return 0;
14036 #endif
14037 return 1;
14038 }
14039
14040 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)14041 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
14042 {
14043 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14044 if (cur_wireless_mode < WIRELESS_11_24N
14045 && cur_wireless_mode > 0) { /* ABG mode */
14046 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14047 u32 remainder = 0;
14048 u8 quotient = 0;
14049
14050 remainder = MAX_RECVBUF_SZ % (4 * 1024);
14051 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14052
14053 if (quotient > 5) {
14054 pHalData->rxagg_usb_size = 0x6;
14055 pHalData->rxagg_usb_timeout = 0x10;
14056 } else {
14057 if (remainder >= 2048) {
14058 pHalData->rxagg_usb_size = quotient;
14059 pHalData->rxagg_usb_timeout = 0x10;
14060 } else {
14061 pHalData->rxagg_usb_size = (quotient - 1);
14062 pHalData->rxagg_usb_timeout = 0x10;
14063 }
14064 }
14065 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14066 if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
14067 pHalData->rxagg_usb_size = 0x6;
14068 pHalData->rxagg_usb_timeout = 0x10;
14069 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14070 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14071 }
14072 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14073
14074 } else if (cur_wireless_mode >= WIRELESS_11_24N
14075 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14076 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14077 u32 remainder = 0;
14078 u8 quotient = 0;
14079
14080 remainder = MAX_RECVBUF_SZ % (4 * 1024);
14081 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14082
14083 if (quotient > 5) {
14084 pHalData->rxagg_usb_size = 0x5;
14085 pHalData->rxagg_usb_timeout = 0x20;
14086 } else {
14087 if (remainder >= 2048) {
14088 pHalData->rxagg_usb_size = quotient;
14089 pHalData->rxagg_usb_timeout = 0x10;
14090 } else {
14091 pHalData->rxagg_usb_size = (quotient - 1);
14092 pHalData->rxagg_usb_timeout = 0x10;
14093 }
14094 }
14095 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14096 if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
14097 pHalData->rxagg_usb_size = 0x5;
14098 pHalData->rxagg_usb_timeout = 0x20;
14099 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14100 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14101 }
14102 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14103
14104 } else {
14105 /* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14106 }
14107 }
14108
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)14109 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
14110 {
14111 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14112
14113 if (cur_wireless_mode < WIRELESS_11_24N
14114 && cur_wireless_mode > 0) { /* ABG mode */
14115 if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
14116 || 0x10 != pHalData->rxagg_usb_timeout) {
14117 pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
14118 pHalData->rxagg_usb_timeout = 0x10;
14119 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14120 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14121 }
14122 } else if (cur_wireless_mode >= WIRELESS_11_24N
14123 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14124 if (UsbDmaSize != pHalData->rxagg_usb_size
14125 || 0x20 != pHalData->rxagg_usb_timeout) {
14126 pHalData->rxagg_usb_size = UsbDmaSize;
14127 pHalData->rxagg_usb_timeout = 0x20;
14128 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14129 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14130 }
14131 } else {
14132 /* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14133 }
14134 }
14135
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)14136 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
14137 {
14138 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14139 rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
14140 return;
14141 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14142
14143 rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
14144 }
14145 #endif /* CONFIG_USB_RX_AGGREGATION */
14146
14147 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)14148 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
14149 {
14150 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
14151 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14152 struct registry_priv *registry_par = &padapter->registrypriv;
14153 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14154 u8 cur_wireless_mode = WIRELESS_INVALID;
14155
14156 #ifdef CONFIG_USB_RX_AGGREGATION
14157 if (!registry_par->dynamic_agg_enable)
14158 return;
14159
14160 #ifdef RTW_HALMAC
14161 if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter)
14162 || IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter))
14163 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
14164 #else /* !RTW_HALMAC */
14165 if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
14166 /* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
14167 if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) {
14168 if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14169 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
14170 else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14171 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
14172 else
14173 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
14174
14175 /* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
14176 }
14177 } else if (IS_HARDWARE_TYPE_8812(padapter)) {
14178 #ifdef CONFIG_CONCURRENT_MODE
14179 u8 i;
14180 _adapter *iface;
14181 u8 bassocaed = _FALSE;
14182 struct mlme_ext_priv *mlmeext;
14183
14184 for (i = 0; i < pdvobjpriv->iface_nums; i++) {
14185 iface = pdvobjpriv->padapters[i];
14186 mlmeext = &iface->mlmeextpriv;
14187 if (rtw_linked_check(iface) == _TRUE) {
14188 if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
14189 cur_wireless_mode = mlmeext->cur_wireless_mode;
14190 bassocaed = _TRUE;
14191 }
14192 }
14193 if (bassocaed)
14194 #endif
14195 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14196 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14197 } else {
14198 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14199 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14200 }
14201 #endif /* RTW_HALMAC */
14202 #endif /* CONFIG_USB_RX_AGGREGATION */
14203
14204 }
14205
14206 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)14207 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
14208 {
14209 #ifdef CONFIG_AP_MODE
14210 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14211 u8 chk_rst = _SUCCESS;
14212
14213 if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
14214 return chk_rst;
14215
14216 /* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
14217 /* return chk_rst; */
14218
14219 if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
14220 && (pre_qsel != next_qsel)) {
14221 /* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
14222 /* pre_qsel,next_qsel); */
14223 chk_rst = _FAIL;
14224 }
14225 return chk_rst;
14226 #else
14227 return _SUCCESS;
14228 #endif /* CONFIG_AP_MODE */
14229 }
14230
14231 #ifdef CONFIG_WOWLAN
14232 /*
14233 * Description:
14234 * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
14235 * contant.
14236 *
14237 * Input:
14238 * adapter: adapter pointer.
14239 * page_num: The max. page number that user want to dump.
14240 * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
14241 */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)14242 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
14243 {
14244
14245 int i;
14246 u8 val = 0;
14247 u8 base = 0;
14248 u32 addr = 0;
14249 u32 count = (page_size / 8);
14250
14251 if (page_num <= 0) {
14252 RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
14253 return;
14254 }
14255
14256 if (page_size < 128 || page_size > 512) {
14257 RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
14258 return;
14259 }
14260
14261 RTW_INFO("+%s+\n", __func__);
14262 val = rtw_read8(padapter, 0x106);
14263 rtw_write8(padapter, 0x106, 0x69);
14264 RTW_INFO("0x106: 0x%02x\n", val);
14265 base = rtw_read8(padapter, 0x209);
14266 RTW_INFO("0x209: 0x%02x\n", base);
14267
14268 addr = ((base)*page_size) / 8;
14269 for (i = 0 ; i < page_num * count ; i += 2) {
14270 rtw_write32(padapter, 0x140, addr + i);
14271 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14272 rtw_write32(padapter, 0x140, addr + i + 1);
14273 printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14274 }
14275 }
14276 #endif
14277
14278 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)14279 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
14280 {
14281 u8 value = 0;
14282 u8 direction = 0;
14283 u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
14284 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
14285 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
14286 u8 gpio_num_to_set = gpio_num;
14287 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
14288
14289 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14290 return value;
14291
14292 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14293
14294 RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
14295 LeaveAllPowerSaveModeDirect(adapter);
14296
14297 if (gpio_num > 7) {
14298 gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
14299 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
14300 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
14301 gpio_num_to_set = gpio_num - 8;
14302 }
14303
14304 /* Read GPIO Direction */
14305 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14306
14307 /* According the direction to read register value */
14308 if (direction)
14309 value = (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14310 else
14311 value = (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14312
14313 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14314 RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
14315
14316 return value;
14317 }
14318
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)14319 int rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
14320 {
14321 u8 direction = 0;
14322 u8 res = -1;
14323 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
14324 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
14325 u8 gpio_num_to_set = gpio_num;
14326
14327 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14328 return -1;
14329
14330 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14331
14332 LeaveAllPowerSaveModeDirect(adapter);
14333
14334 if (gpio_num > 7) {
14335 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
14336 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
14337 gpio_num_to_set = gpio_num - 8;
14338 }
14339
14340 /* Read GPIO direction */
14341 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
14342
14343 /* If GPIO is output direction, setting value. */
14344 if (direction) {
14345 if (isHigh)
14346 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
14347 else
14348 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
14349
14350 RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
14351 res = 0;
14352 } else {
14353 RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
14354 res = -1;
14355 }
14356
14357 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14358 return res;
14359 }
14360
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)14361 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
14362 {
14363 u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
14364 u8 gpio_num_to_set = gpio_num;
14365
14366 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
14367 return -1;
14368
14369 RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
14370
14371 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14372
14373 LeaveAllPowerSaveModeDirect(adapter);
14374
14375 rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
14376
14377 if (gpio_num > 7) {
14378 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
14379 gpio_num_to_set = gpio_num - 8;
14380 }
14381
14382 if (isOutput)
14383 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
14384 else
14385 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
14386
14387 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14388
14389 return 0;
14390 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))14391 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
14392 {
14393 u8 value;
14394 u8 direction;
14395 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14396
14397 if (IS_HARDWARE_TYPE_8188E(adapter)) {
14398 if (gpio_num > 7 || gpio_num < 4) {
14399 RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14400 return -1;
14401 }
14402 }
14403
14404 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14405
14406 LeaveAllPowerSaveModeDirect(adapter);
14407
14408 /* Read GPIO direction */
14409 direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
14410 if (direction) {
14411 RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
14412 return -1;
14413 }
14414
14415 /* Config GPIO Mode */
14416 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
14417
14418 /* Register GPIO interrupt handler*/
14419 adapter->gpiointpriv.callback[gpio_num] = callback;
14420
14421 /* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
14422 value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
14423 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
14424 rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
14425
14426 /* Enable GPIO interrupt */
14427 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
14428 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14429
14430 rtw_hal_update_hisr_hsisr_ind(adapter, 1);
14431
14432 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14433
14434 return 0;
14435 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)14436 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
14437 {
14438 u8 value;
14439 u8 direction;
14440 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
14441
14442 if (IS_HARDWARE_TYPE_8188E(adapter)) {
14443 if (gpio_num > 7 || gpio_num < 4) {
14444 RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
14445 return -1;
14446 }
14447 }
14448
14449 rtw_ps_deny(adapter, PS_DENY_IOCTL);
14450
14451 LeaveAllPowerSaveModeDirect(adapter);
14452
14453 /* Config GPIO Mode */
14454 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
14455
14456 /* Unregister GPIO interrupt handler*/
14457 adapter->gpiointpriv.callback[gpio_num] = NULL;
14458
14459 /* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
14460 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
14461 rtw_write8(adapter, REG_GPIO_INTM, 0x00);
14462
14463 /* Disable GPIO interrupt */
14464 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
14465 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
14466
14467 if (!adapter->gpiointpriv.interrupt_enable_mask)
14468 rtw_hal_update_hisr_hsisr_ind(adapter, 0);
14469
14470 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
14471
14472 return 0;
14473 }
14474 #endif
14475
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)14476 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
14477 {
14478 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14479 u8 i;
14480
14481 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14482 if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
14483 if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
14484 && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
14485 return i;
14486 }
14487 }
14488
14489 return -1;
14490 }
14491
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)14492 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
14493 {
14494 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14495 s8 res;
14496 u8 i;
14497
14498 /* If it's an existed record, overwrite it */
14499 res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
14500 if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
14501 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
14502 return;
14503 }
14504
14505 /* Search for the empty record to use */
14506 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
14507 if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
14508 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
14509 return;
14510 }
14511 }
14512
14513 /* Else, overwrite the oldest record */
14514 for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
14515 _rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
14516
14517 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
14518 }
14519
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)14520 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
14521 {
14522 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
14523 }
14524
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14525 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14526 {
14527 u32 mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
14528 u32 mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
14529 u32 mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
14530 u32 DropPacket = 0;
14531
14532 if (!rx_counter) {
14533 rtw_warn_on(1);
14534 return;
14535 }
14536 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
14537 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14538
14539 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
14540 mac_cck_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14541 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14542 mac_ofdm_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14543 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
14544 mac_ht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14545 mac_vht_ok = 0;
14546 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14547 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
14548 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14549 mac_vht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14550 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14551 }
14552
14553 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
14554 mac_cck_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14555 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14556 mac_ofdm_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14557 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
14558 mac_ht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14559 mac_vht_err = 0;
14560 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14561 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
14562 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
14563 mac_vht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
14564 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
14565 }
14566
14567 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
14568 mac_cck_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14569 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
14570 mac_ofdm_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14571 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
14572 mac_ht_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
14573
14574 /* Mac_DropPacket */
14575 rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
14576 DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
14577
14578 rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
14579 rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
14580 rx_counter->rx_cck_fa = mac_cck_fa;
14581 rx_counter->rx_ofdm_fa = mac_ofdm_fa;
14582 rx_counter->rx_ht_fa = mac_ht_fa;
14583 rx_counter->rx_pkt_drop = DropPacket;
14584 }
rtw_reset_mac_rx_counters(_adapter * padapter)14585 void rtw_reset_mac_rx_counters(_adapter *padapter)
14586 {
14587
14588 /* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
14589 if (IS_HARDWARE_TYPE_8703B(padapter) ||
14590 IS_HARDWARE_TYPE_8723D(padapter) ||
14591 IS_HARDWARE_TYPE_8188F(padapter) ||
14592 IS_HARDWARE_TYPE_8188GTV(padapter) ||
14593 IS_HARDWARE_TYPE_8192F(padapter) ||
14594 IS_HARDWARE_TYPE_8822C(padapter))
14595 phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
14596
14597 /* reset mac counter */
14598 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
14599 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
14600 }
14601
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14602 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14603 {
14604 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;
14605 if (!rx_counter) {
14606 rtw_warn_on(1);
14607 return;
14608 }
14609 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14610 cckok = phy_query_bb_reg(padapter, 0xF04, 0x3FFF); /* [13:0] */
14611 ofdmok = phy_query_bb_reg(padapter, 0xF14, 0x3FFF); /* [13:0] */
14612 htok = phy_query_bb_reg(padapter, 0xF10, 0x3FFF); /* [13:0] */
14613 vht_ok = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF); /* [13:0] */
14614 cckcrc = phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16] */
14615 ofdmcrc = phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
14616 htcrc = phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
14617 vht_err = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
14618 CCK_FA = phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
14619 OFDM_FA = phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
14620 } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){
14621 cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);
14622 ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
14623 htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
14624 vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);
14625 cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);
14626 ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
14627 htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
14628 vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);
14629 CCK_FA = phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);
14630 OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
14631
14632 } else {
14633 cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
14634 ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
14635 htok = phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
14636 vht_ok = 0;
14637 cckcrc = phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
14638 ofdmcrc = phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
14639 htcrc = phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
14640 vht_err = 0;
14641 OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
14642 phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
14643 phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
14644
14645 CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
14646 }
14647
14648 rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
14649 rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
14650 rx_counter->rx_ofdm_fa = OFDM_FA;
14651 rx_counter->rx_cck_fa = CCK_FA;
14652
14653 }
14654
rtw_reset_phy_trx_ok_counters(_adapter * padapter)14655 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
14656 {
14657 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14658 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
14659 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
14660 } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14661 phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);
14662 phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);
14663 } else {
14664 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14665 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14666 }
14667 }
14668
rtw_reset_phy_rx_counters(_adapter * padapter)14669 void rtw_reset_phy_rx_counters(_adapter *padapter)
14670 {
14671 /* reset phy counter */
14672 if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
14673 /* reset CCK FA counter */
14674 phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);
14675 phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);
14676
14677 /* reset CCK CCA counter */
14678 phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);
14679 phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);
14680 rtw_reset_phy_trx_ok_counters(padapter);
14681
14682 } else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
14683 rtw_reset_phy_trx_ok_counters(padapter);
14684
14685 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset OFDA FA counter */
14686 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
14687
14688 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
14689 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14690 } else {
14691 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
14692 rtw_msleep_os(10);
14693 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
14694
14695 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset OFDA FA counter */
14696 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset OFDA FA counter */
14697 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
14698 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
14699
14700 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
14701 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
14702 }
14703 }
14704 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)14705 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
14706 {
14707 struct recv_priv *precvpriv = &padapter->recvpriv;
14708 if (!rx_counter) {
14709 rtw_warn_on(1);
14710 return;
14711 }
14712 rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
14713 rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
14714 rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
14715 }
rtw_reset_drv_rx_counters(_adapter * padapter)14716 void rtw_reset_drv_rx_counters(_adapter *padapter)
14717 {
14718 struct recv_priv *precvpriv = &padapter->recvpriv;
14719 padapter->drv_rx_cnt_ok = 0;
14720 padapter->drv_rx_cnt_crcerror = 0;
14721 padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
14722 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)14723 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
14724 {
14725 u8 initialgain;
14726 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14727
14728 if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
14729 rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
14730 RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
14731 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14732 /*disable dynamic functions, such as high power, DIG*/
14733 rtw_phydm_ability_backup(padapter);
14734 rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
14735 } else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
14736 /* turn on phy-dynamic functions */
14737 rtw_phydm_ability_restore(padapter);
14738 initialgain = 0xff; /* restore RX GAIN */
14739 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
14740
14741 }
14742 }
14743
rtw_dump_rx_counters(_adapter * padapter)14744 void rtw_dump_rx_counters(_adapter *padapter)
14745 {
14746 struct dbg_rx_counter rx_counter;
14747
14748 if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
14749 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14750 rtw_dump_drv_rx_counters(padapter, &rx_counter);
14751 RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
14752 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
14753 rtw_reset_drv_rx_counters(padapter);
14754 }
14755
14756 if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
14757 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14758 rtw_dump_mac_rx_counters(padapter, &rx_counter);
14759 RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
14760 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
14761 rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
14762 rx_counter.rx_pkt_drop);
14763 rtw_reset_mac_rx_counters(padapter);
14764 }
14765
14766 if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
14767 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
14768 rtw_dump_phy_rx_counters(padapter, &rx_counter);
14769 /* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
14770 /* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
14771 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,
14772 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
14773 rtw_reset_phy_rx_counters(padapter);
14774 }
14775 }
14776 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)14777 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
14778 {
14779 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14780 u8 curr_tx_sgi = 0;
14781 struct ra_sta_info *ra_info;
14782
14783 if (!psta)
14784 return curr_tx_sgi;
14785
14786 if (padapter->fix_rate == 0xff) {
14787 #if defined(CONFIG_RTL8188E)
14788 #if (RATE_ADAPTIVE_SUPPORT == 1)
14789 curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
14790 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14791 #else
14792 ra_info = &psta->cmn.ra_info;
14793 curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
14794 #endif
14795 } else {
14796 curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
14797 }
14798
14799 return curr_tx_sgi;
14800 }
14801
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)14802 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
14803 {
14804 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14805 u8 rate_id = 0;
14806 struct ra_sta_info *ra_info;
14807
14808 if (!psta)
14809 return rate_id;
14810
14811 if (padapter->fix_rate == 0xff) {
14812 #if defined(CONFIG_RTL8188E)
14813 #if (RATE_ADAPTIVE_SUPPORT == 1)
14814 rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
14815 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
14816 #else
14817 ra_info = &psta->cmn.ra_info;
14818 rate_id = ra_info->curr_tx_rate & 0x7f;
14819 #endif
14820 } else {
14821 rate_id = padapter->fix_rate & 0x7f;
14822 }
14823
14824 return rate_id;
14825 }
14826
update_IOT_info(_adapter * padapter)14827 void update_IOT_info(_adapter *padapter)
14828 {
14829 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14830 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14831
14832 switch (pmlmeinfo->assoc_AP_vendor) {
14833 case HT_IOT_PEER_MARVELL:
14834 pmlmeinfo->turboMode_cts2self = 1;
14835 pmlmeinfo->turboMode_rtsen = 0;
14836 break;
14837
14838 case HT_IOT_PEER_RALINK:
14839 pmlmeinfo->turboMode_cts2self = 0;
14840 pmlmeinfo->turboMode_rtsen = 1;
14841 break;
14842 case HT_IOT_PEER_REALTEK:
14843 /* rtw_write16(padapter, 0x4cc, 0xffff); */
14844 /* rtw_write16(padapter, 0x546, 0x01c0); */
14845 break;
14846 default:
14847 pmlmeinfo->turboMode_cts2self = 0;
14848 pmlmeinfo->turboMode_rtsen = 1;
14849 break;
14850 }
14851
14852 }
14853 #ifdef CONFIG_RTS_FULL_BW
14854 /*
14855 8188E: not support full RTS BW feature(mac REG no define 480[5])
14856 */
rtw_set_rts_bw(_adapter * padapter)14857 void rtw_set_rts_bw(_adapter *padapter) {
14858 int i;
14859 u8 enable = 1;
14860 bool connect_to_8812 = _FALSE;
14861 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14862 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14863 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
14864 struct sta_info *station = NULL;
14865
14866 for (i = 0; i < macid_ctl->num; i++) {
14867 if (rtw_macid_is_used(macid_ctl, i)) {
14868
14869 station = NULL;
14870 station = macid_ctl->sta[i];
14871 if(station) {
14872
14873 _adapter *sta_adapter =station->padapter;
14874 struct mlme_ext_priv *pmlmeext = &(sta_adapter->mlmeextpriv);
14875 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14876
14877 if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {
14878 if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) {
14879 if ( macid_ctl->sta[i]->vendor_8812) {
14880 connect_to_8812 = _TRUE;
14881 enable = 0;
14882 }
14883 }
14884 }
14885 }
14886 }
14887
14888 if(connect_to_8812)
14889 break;
14890 }
14891
14892 RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);
14893 rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);
14894 }
14895 #endif/*CONFIG_RTS_FULL_BW*/
14896
hal_spec_init(_adapter * adapter)14897 int hal_spec_init(_adapter *adapter)
14898 {
14899 u8 interface_type = 0;
14900 int ret = _SUCCESS;
14901
14902 interface_type = rtw_get_intf_type(adapter);
14903
14904 switch (rtw_get_chip_type(adapter)) {
14905 #ifdef CONFIG_RTL8723B
14906 case RTL8723B:
14907 init_hal_spec_8723b(adapter);
14908 break;
14909 #endif
14910 #ifdef CONFIG_RTL8703B
14911 case RTL8703B:
14912 init_hal_spec_8703b(adapter);
14913 break;
14914 #endif
14915 #ifdef CONFIG_RTL8723D
14916 case RTL8723D:
14917 init_hal_spec_8723d(adapter);
14918 break;
14919 #endif
14920 #ifdef CONFIG_RTL8188E
14921 case RTL8188E:
14922 init_hal_spec_8188e(adapter);
14923 break;
14924 #endif
14925 #ifdef CONFIG_RTL8188F
14926 case RTL8188F:
14927 init_hal_spec_8188f(adapter);
14928 break;
14929 #endif
14930 #ifdef CONFIG_RTL8188GTV
14931 case RTL8188GTV:
14932 init_hal_spec_8188gtv(adapter);
14933 break;
14934 #endif
14935 #ifdef CONFIG_RTL8812A
14936 case RTL8812:
14937 init_hal_spec_8812a(adapter);
14938 break;
14939 #endif
14940 #ifdef CONFIG_RTL8821A
14941 case RTL8821:
14942 init_hal_spec_8821a(adapter);
14943 break;
14944 #endif
14945 #ifdef CONFIG_RTL8192E
14946 case RTL8192E:
14947 init_hal_spec_8192e(adapter);
14948 break;
14949 #endif
14950 #ifdef CONFIG_RTL8814A
14951 case RTL8814A:
14952 init_hal_spec_8814a(adapter);
14953 break;
14954 #endif
14955 #ifdef CONFIG_RTL8822B
14956 case RTL8822B:
14957 rtl8822b_init_hal_spec(adapter);
14958 break;
14959 #endif
14960 #ifdef CONFIG_RTL8821C
14961 case RTL8821C:
14962 init_hal_spec_rtl8821c(adapter);
14963 break;
14964 #endif
14965 #ifdef CONFIG_RTL8710B
14966 case RTL8710B:
14967 init_hal_spec_8710b(adapter);
14968 break;
14969 #endif
14970 #ifdef CONFIG_RTL8192F
14971 case RTL8192F:
14972 init_hal_spec_8192f(adapter);
14973 break;
14974 #endif
14975 #ifdef CONFIG_RTL8822C
14976 case RTL8822C:
14977 rtl8822c_init_hal_spec(adapter);
14978 break;
14979 #endif
14980 #ifdef CONFIG_RTL8814B
14981 case RTL8814B:
14982 rtl8814b_init_hal_spec(adapter);
14983 break;
14984 #endif
14985 default:
14986 RTW_ERR("%s: unknown chip_type:%u\n"
14987 , __func__, rtw_get_chip_type(adapter));
14988 ret = _FAIL;
14989 break;
14990 }
14991
14992 return ret;
14993 }
14994
14995 static const char *const _band_cap_str[] = {
14996 /* BIT0 */"2G",
14997 /* BIT1 */"5G",
14998 };
14999
15000 static const char *const _bw_cap_str[] = {
15001 /* BIT0 */"5M",
15002 /* BIT1 */"10M",
15003 /* BIT2 */"20M",
15004 /* BIT3 */"40M",
15005 /* BIT4 */"80M",
15006 /* BIT5 */"160M",
15007 /* BIT6 */"80_80M",
15008 };
15009
15010 static const char *const _proto_cap_str[] = {
15011 /* BIT0 */"b",
15012 /* BIT1 */"g",
15013 /* BIT2 */"n",
15014 /* BIT3 */"ac",
15015 };
15016
15017 static const char *const _wl_func_str[] = {
15018 /* BIT0 */"P2P",
15019 /* BIT1 */"MIRACAST",
15020 /* BIT2 */"TDLS",
15021 /* BIT3 */"FTM",
15022 };
15023
dump_hal_spec(void * sel,_adapter * adapter)15024 void dump_hal_spec(void *sel, _adapter *adapter)
15025 {
15026 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15027 int i;
15028
15029 RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
15030 RTW_PRINT_SEL(sel, "macid_cap:%u\n", hal_spec->macid_cap);
15031 RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
15032 RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
15033
15034 RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
15035 RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
15036 RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);
15037 RTW_PRINT_SEL(sel, "rf_reg_path_avail_num:%u\n", hal_spec->rf_reg_path_avail_num);
15038 RTW_PRINT_SEL(sel, "rf_reg_trx_path_bmp:0x%02x\n", hal_spec->rf_reg_trx_path_bmp);
15039 RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
15040
15041 RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
15042 RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
15043
15044 RTW_PRINT_SEL(sel, "band_cap:");
15045 for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
15046 if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
15047 _RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
15048 }
15049 _RTW_PRINT_SEL(sel, "\n");
15050
15051 RTW_PRINT_SEL(sel, "bw_cap:");
15052 for (i = 0; i < BW_CAP_BIT_NUM; i++) {
15053 if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
15054 _RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
15055 }
15056 _RTW_PRINT_SEL(sel, "\n");
15057
15058 RTW_PRINT_SEL(sel, "proto_cap:");
15059 for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
15060 if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
15061 _RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
15062 }
15063 _RTW_PRINT_SEL(sel, "\n");
15064
15065 RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
15066 RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
15067
15068 RTW_PRINT_SEL(sel, "wl_func:");
15069 for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
15070 if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
15071 _RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
15072 }
15073 _RTW_PRINT_SEL(sel, "\n");
15074
15075 #if CONFIG_TX_AC_LIFETIME
15076 RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"
15077 , hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);
15078 #endif
15079
15080 RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
15081
15082 RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
15083 RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
15084 }
15085
hal_chk_band_cap(_adapter * adapter,u8 cap)15086 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
15087 {
15088 return GET_HAL_SPEC(adapter)->band_cap & cap;
15089 }
15090
hal_chk_bw_cap(_adapter * adapter,u8 cap)15091 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
15092 {
15093 return GET_HAL_SPEC(adapter)->bw_cap & cap;
15094 }
15095
hal_chk_proto_cap(_adapter * adapter,u8 cap)15096 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
15097 {
15098 return GET_HAL_SPEC(adapter)->proto_cap & cap;
15099 }
15100
hal_chk_wl_func(_adapter * adapter,u8 func)15101 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
15102 {
15103 return GET_HAL_SPEC(adapter)->wl_func & func;
15104 }
15105
hal_is_band_support(_adapter * adapter,u8 band)15106 inline bool hal_is_band_support(_adapter *adapter, u8 band)
15107 {
15108 return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
15109 }
15110
hal_is_bw_support(_adapter * adapter,u8 bw)15111 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
15112 {
15113 return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
15114 }
15115
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)15116 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
15117 {
15118 u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
15119
15120 if (mode == WIRELESS_11B)
15121 if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15122 return 1;
15123
15124 if (mode == WIRELESS_11G)
15125 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15126 return 1;
15127
15128 if (mode == WIRELESS_11A)
15129 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15130 return 1;
15131
15132 if (mode == WIRELESS_11_24N)
15133 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15134 return 1;
15135
15136 if (mode == WIRELESS_11_5N)
15137 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15138 return 1;
15139
15140 if (mode == WIRELESS_11AC)
15141 if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15142 return 1;
15143
15144 return 0;
15145 }
hal_is_mimo_support(_adapter * adapter)15146 inline bool hal_is_mimo_support(_adapter *adapter)
15147 {
15148 if ((GET_HAL_TX_NSS(adapter) == 1) &&
15149 (GET_HAL_RX_NSS(adapter) == 1))
15150 return 0;
15151 return 1;
15152 }
15153
15154 /*
15155 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
15156 * @adapter:
15157 * @in_bw: starting bw, value of enum channel_width
15158 *
15159 * Returns: value of enum channel_width
15160 */
hal_largest_bw(_adapter * adapter,u8 in_bw)15161 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
15162 {
15163 for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
15164 if (hal_is_bw_support(adapter, in_bw))
15165 break;
15166 }
15167
15168 if (!hal_is_bw_support(adapter, in_bw))
15169 rtw_warn_on(1);
15170
15171 return in_bw;
15172 }
15173
15174 #ifndef CONFIG_HAS_TX_BEACON_PAUSE
ResumeTxBeacon(_adapter * padapter)15175 void ResumeTxBeacon(_adapter *padapter)
15176 {
15177 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15178 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
15179
15180 #ifdef RTW_HALMAC
15181 /* Add this for driver using HALMAC because driver doesn't have setup time init by self */
15182 /* TBTT setup time */
15183 rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
15184 #endif
15185
15186 /* TBTT hold time: 0x540[19:8] */
15187 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
15188 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15189 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
15190 }
15191
StopTxBeacon(_adapter * padapter)15192 void StopTxBeacon(_adapter *padapter)
15193 {
15194 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15195 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
15196
15197 /* TBTT hold time: 0x540[19:8] */
15198 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
15199 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15200 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
15201 }
15202 #endif /* CONFIG_HAS_TX_BEACON_PAUSE */
15203
15204 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
15205
15206 #ifdef CONFIG_CLIENT_PORT_CFG
15207 const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
15208 CLT_PORT0,
15209 CLT_PORT1,
15210 CLT_PORT2,
15211 CLT_PORT3
15212 };
15213
rtw_clt_port_init(struct clt_port_t * cltp)15214 void rtw_clt_port_init(struct clt_port_t *cltp)
15215 {
15216 cltp->bmp = 0;
15217 cltp->num = 0;
15218 _rtw_spinlock_init(&cltp->lock);
15219 }
rtw_clt_port_deinit(struct clt_port_t * cltp)15220 void rtw_clt_port_deinit(struct clt_port_t *cltp)
15221 {
15222 _rtw_spinlock_free(&cltp->lock);
15223 }
_hw_client_port_alloc(_adapter * adapter)15224 static void _hw_client_port_alloc(_adapter *adapter)
15225 {
15226 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15227 struct clt_port_t *cltp = &dvobj->clt_port;
15228 _irqL irql;
15229 int i;
15230
15231 #if 0
15232 if (cltp->num > MAX_CLIENT_PORT_NUM) {
15233 RTW_ERR(ADPT_FMT" cann't alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
15234 rtw_warn_on(1);
15235 return;
15236 }
15237 #endif
15238
15239 if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
15240 RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
15241 ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
15242 return;
15243 }
15244 _enter_critical_bh(&cltp->lock, &irql);
15245 for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
15246 if (!(cltp->bmp & BIT(i)))
15247 break;
15248 }
15249
15250 if (i < MAX_CLIENT_PORT_NUM) {
15251 adapter->client_id = i;
15252 cltp->bmp |= BIT(i);
15253 adapter->client_port = _clt_port_id[i];
15254 }
15255 cltp->num++;
15256 _exit_critical_bh(&cltp->lock, &irql);
15257 RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
15258 __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
15259 }
_hw_client_port_free(_adapter * adapter)15260 static void _hw_client_port_free(_adapter *adapter)
15261 {
15262 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15263 struct clt_port_t *cltp = &dvobj->clt_port;
15264 _irqL irql;
15265
15266 #if 0
15267 if (adapter->client_id >= MAX_CLIENT_PORT_NUM) {
15268 RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
15269 /*rtw_warn_on(1);*/
15270 }
15271 #endif
15272
15273 RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
15274 __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
15275
15276 _enter_critical_bh(&cltp->lock, &irql);
15277 if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
15278 cltp->bmp &= ~ BIT(adapter->client_id);
15279 adapter->client_id = MAX_CLIENT_PORT_NUM;
15280 adapter->client_port = CLT_PORT_INVALID;
15281 }
15282 cltp->num--;
15283 if (cltp->num < 0)
15284 cltp->num = 0;
15285 _exit_critical_bh(&cltp->lock, &irql);
15286 }
rtw_hw_client_port_allocate(_adapter * adapter)15287 void rtw_hw_client_port_allocate(_adapter *adapter)
15288 {
15289 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15290
15291 if (hal_spec->port_num != 5)
15292 return;
15293
15294 _hw_client_port_alloc(adapter);
15295 }
rtw_hw_client_port_release(_adapter * adapter)15296 void rtw_hw_client_port_release(_adapter *adapter)
15297 {
15298 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15299
15300 if (hal_spec->port_num != 5)
15301 return;
15302
15303 _hw_client_port_free(adapter);
15304 }
15305 #endif /*CONFIG_CLIENT_PORT_CFG*/
15306
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)15307 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
15308 {
15309 RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
15310
15311 rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
15312
15313 /* set net_type */
15314 Set_MSR(Adapter, mode);
15315
15316 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
15317 if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
15318 StopTxBeacon(Adapter);
15319 } else if (mode == _HW_STATE_ADHOC_)
15320 ResumeTxBeacon(Adapter);
15321 else if (mode == _HW_STATE_AP_)
15322 /* enable rx ps-poll */
15323 rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
15324
15325 /* enable rx data frame */
15326 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
15327
15328 #ifdef CONFIG_CLIENT_PORT_CFG
15329 if (mode == _HW_STATE_STATION_)
15330 rtw_hw_client_port_allocate(Adapter);
15331 else
15332 rtw_hw_client_port_release(Adapter);
15333 #endif
15334 #if defined(CONFIG_RTL8192F)
15335 rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
15336 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
15337 #endif
15338 }
15339 #endif
15340
15341 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)15342 u8 rtw_hal_antdiv_before_linked(_adapter *padapter)
15343 {
15344 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15345 u8 cur_ant, change_ant;
15346
15347 if (!pHalData->AntDivCfg)
15348 return _FALSE;
15349
15350 if (pHalData->sw_antdiv_bl_state == 0) {
15351 pHalData->sw_antdiv_bl_state = 1;
15352
15353 rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
15354 change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
15355
15356 return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
15357 }
15358
15359 pHalData->sw_antdiv_bl_state = 0;
15360 return _FALSE;
15361 }
15362
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)15363 void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
15364 {
15365 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15366
15367 if (pHalData->AntDivCfg) {
15368 /*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
15369 /*select optimum_antenna for before linked =>For antenna diversity*/
15370 if (dst->Rssi >= src->Rssi) {/*keep org parameter*/
15371 src->Rssi = dst->Rssi;
15372 src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
15373 }
15374 }
15375 }
15376 #endif
15377
15378 #ifdef CONFIG_PROC_DEBUG
15379 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)15380 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
15381 {
15382 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
15383 struct phy_spec_t *phy_spec = &pHalData->phy_spec;
15384
15385 RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
15386 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
15387 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
15388 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index [15:8]*/
15389 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index [7:0]*/
15390
15391 RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
15392 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]*/
15393 /*VHT STBC Rx [23:16]
15394 0 = not support
15395 1 = support for 1 spatial stream
15396 2 = support for 1 or 2 spatial streams
15397 3 = support for 1 or 2 or 3 spatial streams
15398 4 = support for 1 or 2 or 3 or 4 spatial streams*/
15399 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
15400 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]*/
15401 /*HT STBC Rx [7:0]
15402 0 = not support
15403 1 = support for 1 spatial stream
15404 2 = support for 1 or 2 spatial streams
15405 3 = support for 1 or 2 or 3 spatial streams*/
15406 RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
15407
15408 RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
15409 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]*/
15410 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]*/
15411 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]*/
15412 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]*/
15413 #ifdef CONFIG_BEAMFORMING
15414 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
15415 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]*/
15416 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]*/
15417 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]*/
15418 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]*/
15419 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF) ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
15420 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
15421
15422 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
15423 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
15424 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
15425 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
15426 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
15427 #endif
15428 }
15429 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)15430 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
15431 {
15432 u8 phy_cap = _FALSE;
15433
15434 /* STBC */
15435 rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
15436 RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15437
15438 phy_cap = _FALSE;
15439 rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
15440 RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15441
15442 /* LDPC support */
15443 phy_cap = _FALSE;
15444 rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
15445 RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15446
15447 phy_cap = _FALSE;
15448 rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
15449 RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15450
15451 #ifdef CONFIG_BEAMFORMING
15452 phy_cap = _FALSE;
15453 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
15454 RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15455
15456 phy_cap = _FALSE;
15457 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
15458 RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15459
15460 phy_cap = _FALSE;
15461 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
15462 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15463
15464 phy_cap = _FALSE;
15465 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
15466 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
15467 #endif
15468 }
15469 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)15470 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
15471 {
15472 RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
15473 #ifdef CONFIG_PHY_CAPABILITY_QUERY
15474 rtw_dump_phy_cap_by_phydmapi(sel, adapter);
15475 #else
15476 rtw_dump_phy_cap_by_hal(sel, adapter);
15477 #endif
15478 }
15479 #endif
15480
translate_dbm_to_percentage(s16 signal)15481 inline s16 translate_dbm_to_percentage(s16 signal)
15482 {
15483 if ((signal <= -100) || (signal >= 20))
15484 return 0;
15485 else if (signal >= 0)
15486 return 100;
15487 else
15488 return 100 + signal;
15489 }
15490
15491 #ifdef CONFIG_SWTIMER_BASED_TXBCN
15492 #ifdef CONFIG_BCN_RECOVERY
15493 #define REG_CPU_MGQ_INFO 0x041C
15494 #define BIT_BCN_POLL BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)15495 u8 rtw_ap_bcn_recovery(_adapter *padapter)
15496 {
15497 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15498
15499 if (hal_data->issue_bcn_fail >= 2) {
15500 RTW_ERR("%s ISSUE BCN Fail\n", __func__);
15501 rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
15502 hal_data->issue_bcn_fail = 0;
15503 }
15504 return _SUCCESS;
15505 }
15506 #endif /*CONFIG_BCN_RECOVERY*/
15507
15508 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)15509 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
15510 {
15511 u32 start_time = rtw_get_current_time();
15512 u8 bcn_queue_empty = _FALSE;
15513
15514 do {
15515 if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
15516 bcn_queue_empty = _TRUE;
15517 break;
15518 }
15519 } while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
15520
15521 if (bcn_queue_empty == _FALSE)
15522 RTW_ERR("%s BCN queue not empty\n", __func__);
15523
15524 return bcn_queue_empty;
15525 }
15526 #endif /*CONFIG_BCN_XMIT_PROTECT*/
15527 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
15528
15529 /**
15530 * rtw_hal_get_trx_path() - Get RF path related information
15531 * @d: struct dvobj_priv*
15532 * @type: RF type, nTnR
15533 * @tx: Tx path
15534 * @rx: Rx path
15535 *
15536 * Get RF type, TX path and RX path information.
15537 */
rtw_hal_get_trx_path(struct dvobj_priv * d,enum rf_type * type,enum bb_path * tx,enum bb_path * rx)15538 void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,
15539 enum bb_path *tx, enum bb_path *rx)
15540 {
15541 struct _ADAPTER *a = dvobj_get_primary_adapter(d);
15542 enum rf_type t = GET_HAL_RFPATH(a);
15543
15544 if (type)
15545 *type = t;
15546
15547 if (tx || rx) {
15548 u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);
15549 u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);
15550
15551 if (!tx_bmp && !rx_bmp)
15552 rf_type_to_default_trx_bmp(t, tx, rx);
15553 else {
15554 if (tx)
15555 *tx = GET_HAL_TX_PATH_BMP(a);
15556 if (rx)
15557 *rx = GET_HAL_RX_PATH_BMP(a);
15558 }
15559 }
15560 }
15561
15562 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
rtw_hal_switch_chnl_and_set_bw_offload(_adapter * adapter,u8 central_ch,u8 pri_ch_idx,u8 bw)15563 void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
15564 {
15565 u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
15566 PHAL_DATA_TYPE hal;
15567 struct submit_ctx *chsw_sctx;
15568
15569 hal = GET_HAL_DATA(adapter);
15570 chsw_sctx = &hal->chsw_sctx;
15571
15572 SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
15573 SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
15574 SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
15575
15576 rtw_sctx_init(chsw_sctx, 10);
15577 rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
15578 rtw_sctx_wait(chsw_sctx, __func__);
15579 }
15580 #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
15581
phy_get_current_tx_num(PADAPTER pAdapter,u8 Rate)15582 u8 phy_get_current_tx_num(
15583 PADAPTER pAdapter,
15584 u8 Rate
15585 )
15586 {
15587 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(pAdapter);
15588 u8 tx_num = 0;
15589
15590 if (IS_1T_RATE(Rate))
15591 tx_num = hal_data->txpath_num_nss[0];
15592 else if (IS_2T_RATE(Rate))
15593 tx_num = hal_data->txpath_num_nss[1];
15594 else if (IS_3T_RATE(Rate))
15595 tx_num = hal_data->txpath_num_nss[2];
15596 else if (IS_4T_RATE(Rate))
15597 tx_num = hal_data->txpath_num_nss[3];
15598 else
15599 rtw_warn_on(1);
15600
15601 return tx_num == 0 ? RF_1TX : tx_num - 1;
15602 }
15603
15604 #ifdef CONFIG_RTL8812A
rtw_hal_set_8812a_vendor_ie(_adapter * padapter,u8 * pframe,uint * frlen)15605 u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {
15606 int vender_len = 7;
15607 unsigned char vendor_info[vender_len];
15608 unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
15609 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15610
15611 if( !IS_HARDWARE_TYPE_8812(padapter) )
15612 return pframe;
15613
15614 _rtw_memset(vendor_info,0,vender_len);
15615 _rtw_memcpy(vendor_info, REALTEK_OUI, 3);
15616 vendor_info[4] =2;
15617 if(pHalData->version_id.CUTVersion > B_CUT_VERSION )
15618 vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;
15619 else
15620 vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;
15621 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);
15622
15623 return pframe;
15624 }
15625 #endif /*CONFIG_RTL8812A*/
15626
rtw_enter_protsel(struct protsel * protsel,u32 sel)15627 static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)
15628 {
15629 int refcnt;
15630
15631 _enter_critical_mutex(&protsel->mutex, NULL);
15632
15633 refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);
15634
15635 WARN_ON(refcnt > 1 && protsel->sel != sel);
15636
15637 protsel->sel = sel;
15638
15639 _exit_critical_mutex(&protsel->mutex, NULL);
15640 }
15641
rtw_leave_protsel(struct protsel * protsel)15642 static inline void rtw_leave_protsel(struct protsel *protsel)
15643 {
15644 int refcnt;
15645
15646 _enter_critical_mutex(&protsel->mutex, NULL);
15647
15648 refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);
15649
15650 _exit_critical_mutex(&protsel->mutex, NULL);
15651
15652 WARN_ON(refcnt < 0);
15653 }
15654
rtw_assert_protsel(struct protsel * protsel)15655 static inline bool rtw_assert_protsel(struct protsel *protsel)
15656 {
15657 int refcnt = ATOMIC_READ(&protsel->refcnt);
15658
15659 if (refcnt > 0)
15660 return true;
15661
15662 return false;
15663 }
15664
15665 #ifdef CONFIG_PROTSEL_PORT
rtw_enter_protsel_port(_adapter * padapter,u8 port_sel)15666 void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)
15667 {
15668 u8 val8;
15669
15670 rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);
15671
15672 val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);
15673 val8 &= ~BIT_MASK_PORT_CTRL_SEL;
15674 val8 |= BIT_PORT_CTRL_SEL(port_sel);
15675 rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);
15676 }
15677
rtw_assert_protsel_port(_adapter * padapter,u32 addr,u8 len)15678 bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)
15679 {
15680 if (!padapter->bup) /* don't assert before IF up */
15681 return true;
15682
15683 return rtw_assert_protsel(&padapter->dvobj->protsel_port);
15684 }
15685
rtw_leave_protsel_port(_adapter * padapter)15686 void rtw_leave_protsel_port(_adapter *padapter)
15687 {
15688 rtw_leave_protsel(&padapter->dvobj->protsel_port);
15689 }
15690 #endif
15691
15692 #ifdef CONFIG_PROTSEL_ATIMDTIM
rtw_enter_protsel_atimdtim(_adapter * padapter,u8 port_sel)15693 void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)
15694 {
15695 /* 0~15 is for port 0 MBSSID setting
15696 * 16 is for port 1 setting
15697 * 17 is for port 2 setting
15698 * 18 is for port 3 setting
15699 * 19 is for port 4 setting
15700 */
15701 u8 val8;
15702
15703 if (port_sel >= 1 && port_sel <= 4)
15704 port_sel += 15;
15705
15706 rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);
15707
15708 val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);
15709 val8 &= ~BIT_MASK_ATIM_DTIM_SEL;
15710 val8 |= BIT_ATIM_DTIM_SEL(port_sel);
15711 rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);
15712 }
15713
rtw_assert_protsel_atimdtim(_adapter * padapter,u32 addr,u8 len)15714 bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)
15715 {
15716 return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);
15717 }
15718
rtw_leave_protsel_atimdtim(_adapter * padapter)15719 void rtw_leave_protsel_atimdtim(_adapter *padapter)
15720 {
15721 rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);
15722 }
15723 #endif
15724
15725 #ifdef CONFIG_PROTSEL_MACSLEEP
rtw_enter_protsel_macsleep(_adapter * padapter,u8 sel)15726 void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)
15727 {
15728 u32 val32;
15729
15730 rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);
15731
15732 val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);
15733 val32 &= ~BIT_MASK_MACID_SLEEP_SEL;
15734 val32 |= BIT_MACID_SLEEP_SEL(sel);
15735 rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);
15736 }
15737
rtw_assert_protsel_macsleep(_adapter * padapter,u32 addr,u8 len)15738 bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)
15739 {
15740 return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);
15741 }
15742
rtw_leave_protsel_macsleep(_adapter * padapter)15743 void rtw_leave_protsel_macsleep(_adapter *padapter)
15744 {
15745 rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);
15746 }
15747 #endif
15748