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 if (IS_8814B_SERIES(ChipVersion))
273 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814B_");
274 else if (IS_8723F_SERIES(ChipVersion))
275 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723F_");
276 else
277 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
278
279 cnt += sprintf((buf + cnt), "%s", IS_NORMAL_CHIP(ChipVersion) ? "" : "T_");
280
281 if (IS_CHIP_VENDOR_TSMC(ChipVersion))
282 cnt += sprintf((buf + cnt), "%s", "T");
283 else if (IS_CHIP_VENDOR_UMC(ChipVersion))
284 cnt += sprintf((buf + cnt), "%s", "U");
285 else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
286 cnt += sprintf((buf + cnt), "%s", "S");
287
288 if (IS_A_CUT(ChipVersion))
289 cnt += sprintf((buf + cnt), "1_");
290 else if (IS_B_CUT(ChipVersion))
291 cnt += sprintf((buf + cnt), "2_");
292 else if (IS_C_CUT(ChipVersion))
293 cnt += sprintf((buf + cnt), "3_");
294 else if (IS_D_CUT(ChipVersion))
295 cnt += sprintf((buf + cnt), "4_");
296 else if (IS_E_CUT(ChipVersion))
297 cnt += sprintf((buf + cnt), "5_");
298 else if (IS_F_CUT(ChipVersion))
299 cnt += sprintf((buf + cnt), "6_");
300 else if (IS_I_CUT(ChipVersion))
301 cnt += sprintf((buf + cnt), "9_");
302 else if (IS_J_CUT(ChipVersion))
303 cnt += sprintf((buf + cnt), "10_");
304 else if (IS_K_CUT(ChipVersion))
305 cnt += sprintf((buf + cnt), "11_");
306 else
307 cnt += sprintf((buf + cnt), "UNKNOWN_Cv(%d)_", ChipVersion.CUTVersion);
308
309 if (IS_1T1R(ChipVersion))
310 cnt += sprintf((buf + cnt), "1T1R_");
311 else if (IS_1T2R(ChipVersion))
312 cnt += sprintf((buf + cnt), "1T2R_");
313 else if (IS_2T2R(ChipVersion))
314 cnt += sprintf((buf + cnt), "2T2R_");
315 else if (IS_3T3R(ChipVersion))
316 cnt += sprintf((buf + cnt), "3T3R_");
317 else if (IS_3T4R(ChipVersion))
318 cnt += sprintf((buf + cnt), "3T4R_");
319 else if (IS_4T4R(ChipVersion))
320 cnt += sprintf((buf + cnt), "4T4R_");
321 else
322 cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
323
324 cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
325
326 RTW_INFO("%s", buf);
327 }
328
rtw_hal_get_port(_adapter * adapter)329 u8 rtw_hal_get_port(_adapter *adapter)
330 {
331 u8 hw_port = get_hw_port(adapter);
332 #ifdef CONFIG_CLIENT_PORT_CFG
333 u8 clt_port = get_clt_port(adapter);
334
335 if (clt_port)
336 hw_port = clt_port;
337
338 #ifdef DBG_HW_PORT
339 if (MLME_IS_STA(adapter) && (adapter->client_id != MAX_CLIENT_PORT_NUM)) {
340 if(hw_port == CLT_PORT_INVALID) {
341 RTW_ERR(ADPT_FMT" @@@@@ Client port == 0 @@@@@\n", ADPT_ARG(adapter));
342 rtw_warn_on(1);
343 }
344 }
345 #ifdef CONFIG_AP_MODE
346 else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
347 if (hw_port != HW_PORT0) {
348 RTW_ERR(ADPT_FMT" @@@@@ AP / MESH port != 0 @@@@@\n", ADPT_ARG(adapter));
349 rtw_warn_on(1);
350 }
351 }
352 #endif
353 if (0)
354 RTW_INFO(ADPT_FMT" - HP:%d,CP:%d\n", ADPT_ARG(adapter), get_hw_port(adapter), get_clt_port(adapter));
355 #endif /*DBG_HW_PORT*/
356
357 #endif/*CONFIG_CLIENT_PORT_CFG*/
358
359 return hw_port;
360 }
361
362 #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
363
364 /*
365 * Description:
366 * Use hardware(efuse), driver parameter(registry) and default channel plan
367 * to decide which one should be used.
368 *
369 * Parameters:
370 * padapter pointer of adapter
371 * hw_alpha2 country code from HW (efuse/eeprom/mapfile)
372 * hw_chplan channel plan from HW (efuse/eeprom/mapfile)
373 * BIT[7] software configure mode; 0:Enable, 1:disable
374 * BIT[6:0] Channel Plan
375 * sw_alpha2 country code from HW (registry/module param)
376 * sw_chplan channel plan from SW (registry/module param)
377 * AutoLoadFail efuse autoload fail or not
378 *
379 */
hal_com_config_channel_plan(PADAPTER padapter,char * hw_alpha2,u8 hw_chplan,char * sw_alpha2,u8 sw_chplan,BOOLEAN AutoLoadFail)380 void hal_com_config_channel_plan(
381 PADAPTER padapter,
382 char *hw_alpha2,
383 u8 hw_chplan,
384 char *sw_alpha2,
385 u8 sw_chplan,
386 BOOLEAN AutoLoadFail
387 )
388 {
389 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
390 PHAL_DATA_TYPE pHalData;
391 u8 force_hw_chplan = _FALSE;
392 int chplan = -1;
393 const struct country_chplan *country_ent = NULL, *ent;
394 u8 def_chplan = 0x7F; /* Realtek define, used when HW, SW both invalid */
395
396 pHalData = GET_HAL_DATA(padapter);
397
398 /* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
399 if (hw_chplan == 0xFF)
400 goto chk_hw_country_code;
401
402 if (AutoLoadFail == _TRUE)
403 goto chk_sw_config;
404
405 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
406 if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
407 force_hw_chplan = _TRUE;
408 #endif
409
410 hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
411
412 chk_hw_country_code:
413 if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
414 ent = rtw_get_chplan_from_country(hw_alpha2);
415 if (ent) {
416 /* get chplan from hw country code, by pass hw chplan setting */
417 country_ent = ent;
418 chplan = ent->chplan;
419 goto chk_sw_config;
420 } else
421 RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
422 }
423
424 if (rtw_is_channel_plan_valid(hw_chplan))
425 chplan = hw_chplan;
426 else if (force_hw_chplan == _TRUE) {
427 RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
428 /* hw infomaton invalid, refer to sw information */
429 force_hw_chplan = _FALSE;
430 }
431
432 chk_sw_config:
433 if (force_hw_chplan == _TRUE)
434 goto done;
435
436 if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
437 ent = rtw_get_chplan_from_country(sw_alpha2);
438 if (ent) {
439 /* get chplan from sw country code, by pass sw chplan setting */
440 country_ent = ent;
441 chplan = ent->chplan;
442 goto done;
443 } else
444 RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
445 }
446
447 if (rtw_is_channel_plan_valid(sw_chplan)) {
448 /* cancel hw_alpha2 because chplan is specified by sw_chplan*/
449 country_ent = NULL;
450 chplan = sw_chplan;
451 } else if (sw_chplan != RTW_CHPLAN_UNSPECIFIED)
452 RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
453
454 done:
455 if (chplan == -1) {
456 RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
457 chplan = def_chplan;
458 } else if (country_ent) {
459 RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
460 , country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
461 } else
462 RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
463
464 rfctl->country_ent = country_ent;
465 rfctl->ChannelPlan = chplan;
466 pHalData->bDisableSWChannelPlan = force_hw_chplan;
467 }
468
469 BOOLEAN
HAL_IsLegalChannel(PADAPTER Adapter,u32 Channel)470 HAL_IsLegalChannel(
471 PADAPTER Adapter,
472 u32 Channel
473 )
474 {
475 BOOLEAN bLegalChannel = _TRUE;
476
477 if (Channel > 14) {
478 if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
479 bLegalChannel = _FALSE;
480 RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
481 }
482 } else if ((Channel <= 14) && (Channel >= 1)) {
483 if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
484 bLegalChannel = _FALSE;
485 RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
486 }
487 } else {
488 bLegalChannel = _FALSE;
489 RTW_INFO("Channel is Invalid !!!\n");
490 }
491
492 return bLegalChannel;
493 }
494
495 static const u8 _MRateToHwRate[MGN_UNKNOWN] = {
496 [MGN_1M] = DESC_RATE1M,
497 [MGN_2M] = DESC_RATE2M,
498 [MGN_5_5M] = DESC_RATE5_5M,
499 [MGN_11M] = DESC_RATE11M,
500 [MGN_6M] = DESC_RATE6M,
501 [MGN_9M] = DESC_RATE9M,
502 [MGN_12M] = DESC_RATE12M,
503 [MGN_18M] = DESC_RATE18M,
504 [MGN_24M] = DESC_RATE24M,
505 [MGN_36M] = DESC_RATE36M,
506 [MGN_48M] = DESC_RATE48M,
507 [MGN_54M] = DESC_RATE54M,
508 [MGN_MCS0] = DESC_RATEMCS0,
509 [MGN_MCS1] = DESC_RATEMCS1,
510 [MGN_MCS2] = DESC_RATEMCS2,
511 [MGN_MCS3] = DESC_RATEMCS3,
512 [MGN_MCS4] = DESC_RATEMCS4,
513 [MGN_MCS5] = DESC_RATEMCS5,
514 [MGN_MCS6] = DESC_RATEMCS6,
515 [MGN_MCS7] = DESC_RATEMCS7,
516 [MGN_MCS8] = DESC_RATEMCS8,
517 [MGN_MCS9] = DESC_RATEMCS9,
518 [MGN_MCS10] = DESC_RATEMCS10,
519 [MGN_MCS11] = DESC_RATEMCS11,
520 [MGN_MCS12] = DESC_RATEMCS12,
521 [MGN_MCS13] = DESC_RATEMCS13,
522 [MGN_MCS14] = DESC_RATEMCS14,
523 [MGN_MCS15] = DESC_RATEMCS15,
524 [MGN_MCS16] = DESC_RATEMCS16,
525 [MGN_MCS17] = DESC_RATEMCS17,
526 [MGN_MCS18] = DESC_RATEMCS18,
527 [MGN_MCS19] = DESC_RATEMCS19,
528 [MGN_MCS20] = DESC_RATEMCS20,
529 [MGN_MCS21] = DESC_RATEMCS21,
530 [MGN_MCS22] = DESC_RATEMCS22,
531 [MGN_MCS23] = DESC_RATEMCS23,
532 [MGN_MCS24] = DESC_RATEMCS24,
533 [MGN_MCS25] = DESC_RATEMCS25,
534 [MGN_MCS26] = DESC_RATEMCS26,
535 [MGN_MCS27] = DESC_RATEMCS27,
536 [MGN_MCS28] = DESC_RATEMCS28,
537 [MGN_MCS29] = DESC_RATEMCS29,
538 [MGN_MCS30] = DESC_RATEMCS30,
539 [MGN_MCS31] = DESC_RATEMCS31,
540 [MGN_VHT1SS_MCS0] = DESC_RATEVHTSS1MCS0,
541 [MGN_VHT1SS_MCS1] = DESC_RATEVHTSS1MCS1,
542 [MGN_VHT1SS_MCS2] = DESC_RATEVHTSS1MCS2,
543 [MGN_VHT1SS_MCS3] = DESC_RATEVHTSS1MCS3,
544 [MGN_VHT1SS_MCS4] = DESC_RATEVHTSS1MCS4,
545 [MGN_VHT1SS_MCS5] = DESC_RATEVHTSS1MCS5,
546 [MGN_VHT1SS_MCS6] = DESC_RATEVHTSS1MCS6,
547 [MGN_VHT1SS_MCS7] = DESC_RATEVHTSS1MCS7,
548 [MGN_VHT1SS_MCS8] = DESC_RATEVHTSS1MCS8,
549 [MGN_VHT1SS_MCS9] = DESC_RATEVHTSS1MCS9,
550 [MGN_VHT2SS_MCS0] = DESC_RATEVHTSS2MCS0,
551 [MGN_VHT2SS_MCS1] = DESC_RATEVHTSS2MCS1,
552 [MGN_VHT2SS_MCS2] = DESC_RATEVHTSS2MCS2,
553 [MGN_VHT2SS_MCS3] = DESC_RATEVHTSS2MCS3,
554 [MGN_VHT2SS_MCS4] = DESC_RATEVHTSS2MCS4,
555 [MGN_VHT2SS_MCS5] = DESC_RATEVHTSS2MCS5,
556 [MGN_VHT2SS_MCS6] = DESC_RATEVHTSS2MCS6,
557 [MGN_VHT2SS_MCS7] = DESC_RATEVHTSS2MCS7,
558 [MGN_VHT2SS_MCS8] = DESC_RATEVHTSS2MCS8,
559 [MGN_VHT2SS_MCS9] = DESC_RATEVHTSS2MCS9,
560 [MGN_VHT3SS_MCS0] = DESC_RATEVHTSS3MCS0,
561 [MGN_VHT3SS_MCS1] = DESC_RATEVHTSS3MCS1,
562 [MGN_VHT3SS_MCS2] = DESC_RATEVHTSS3MCS2,
563 [MGN_VHT3SS_MCS3] = DESC_RATEVHTSS3MCS3,
564 [MGN_VHT3SS_MCS4] = DESC_RATEVHTSS3MCS4,
565 [MGN_VHT3SS_MCS5] = DESC_RATEVHTSS3MCS5,
566 [MGN_VHT3SS_MCS6] = DESC_RATEVHTSS3MCS6,
567 [MGN_VHT3SS_MCS7] = DESC_RATEVHTSS3MCS7,
568 [MGN_VHT3SS_MCS8] = DESC_RATEVHTSS3MCS8,
569 [MGN_VHT3SS_MCS9] = DESC_RATEVHTSS3MCS9,
570 [MGN_VHT4SS_MCS0] = DESC_RATEVHTSS4MCS0,
571 [MGN_VHT4SS_MCS1] = DESC_RATEVHTSS4MCS1,
572 [MGN_VHT4SS_MCS2] = DESC_RATEVHTSS4MCS2,
573 [MGN_VHT4SS_MCS3] = DESC_RATEVHTSS4MCS3,
574 [MGN_VHT4SS_MCS4] = DESC_RATEVHTSS4MCS4,
575 [MGN_VHT4SS_MCS5] = DESC_RATEVHTSS4MCS5,
576 [MGN_VHT4SS_MCS6] = DESC_RATEVHTSS4MCS6,
577 [MGN_VHT4SS_MCS7] = DESC_RATEVHTSS4MCS7,
578 [MGN_VHT4SS_MCS8] = DESC_RATEVHTSS4MCS8,
579 [MGN_VHT4SS_MCS9] = DESC_RATEVHTSS4MCS9,
580 };
581
MRateToHwRate(enum MGN_RATE rate)582 u8 MRateToHwRate(enum MGN_RATE rate)
583 {
584 u8 hw_rate = DESC_RATE1M; /* default value, also is zero */
585
586 if (rate < MGN_UNKNOWN)
587 hw_rate = _MRateToHwRate[rate];
588
589 if (rate != MGN_1M && hw_rate == DESC_RATE1M)
590 RTW_WARN("Invalid rate 0x%x in %s\n", rate, __FUNCTION__);
591
592 return hw_rate;
593 }
594
595 const char * const _HDATA_RATE[DESC_RATE_NUM + 1] = {
596 [DESC_RATE1M] = "CCK_1M",
597 [DESC_RATE2M] = "CCK_2M",
598 [DESC_RATE5_5M] = "CCK5_5M",
599 [DESC_RATE11M] = "CCK_11M",
600 [DESC_RATE6M] = "OFDM_6M",
601 [DESC_RATE9M] = "OFDM_9M",
602 [DESC_RATE12M] = "OFDM_12M",
603 [DESC_RATE18M] = "OFDM_18M",
604 [DESC_RATE24M] = "OFDM_24M",
605 [DESC_RATE36M] = "OFDM_36M",
606 [DESC_RATE48M] = "OFDM_48M",
607 [DESC_RATE54M] = "OFDM_54M",
608 [DESC_RATEMCS0] = "MCS0",
609 [DESC_RATEMCS1] = "MCS1",
610 [DESC_RATEMCS2] = "MCS2",
611 [DESC_RATEMCS3] = "MCS3",
612 [DESC_RATEMCS4] = "MCS4",
613 [DESC_RATEMCS5] = "MCS5",
614 [DESC_RATEMCS6] = "MCS6",
615 [DESC_RATEMCS7] = "MCS7",
616 [DESC_RATEMCS8] = "MCS8",
617 [DESC_RATEMCS9] = "MCS9",
618 [DESC_RATEMCS10] = "MCS10",
619 [DESC_RATEMCS11] = "MCS11",
620 [DESC_RATEMCS12] = "MCS12",
621 [DESC_RATEMCS13] = "MCS13",
622 [DESC_RATEMCS14] = "MCS14",
623 [DESC_RATEMCS15] = "MCS15",
624 [DESC_RATEMCS16] = "MCS16",
625 [DESC_RATEMCS17] = "MCS17",
626 [DESC_RATEMCS18] = "MCS18",
627 [DESC_RATEMCS19] = "MCS19",
628 [DESC_RATEMCS20] = "MCS20",
629 [DESC_RATEMCS21] = "MCS21",
630 [DESC_RATEMCS22] = "MCS22",
631 [DESC_RATEMCS23] = "MCS23",
632 [DESC_RATEMCS24] = "MCS24",
633 [DESC_RATEMCS25] = "MCS25",
634 [DESC_RATEMCS26] = "MCS26",
635 [DESC_RATEMCS27] = "MCS27",
636 [DESC_RATEMCS28] = "MCS28",
637 [DESC_RATEMCS29] = "MCS29",
638 [DESC_RATEMCS30] = "MCS30",
639 [DESC_RATEMCS31] = "MCS31",
640 [DESC_RATEVHTSS1MCS0] = "VHT1SMCS0",
641 [DESC_RATEVHTSS1MCS1] = "VHT1SMCS1",
642 [DESC_RATEVHTSS1MCS2] = "VHT1SMCS2",
643 [DESC_RATEVHTSS1MCS3] = "VHT1SMCS3",
644 [DESC_RATEVHTSS1MCS4] = "VHT1SMCS4",
645 [DESC_RATEVHTSS1MCS5] = "VHT1SMCS5",
646 [DESC_RATEVHTSS1MCS6] = "VHT1SMCS6",
647 [DESC_RATEVHTSS1MCS7] = "VHT1SMCS7",
648 [DESC_RATEVHTSS1MCS8] = "VHT1SMCS8",
649 [DESC_RATEVHTSS1MCS9] = "VHT1SMCS9",
650 [DESC_RATEVHTSS2MCS0] = "VHT2SMCS0",
651 [DESC_RATEVHTSS2MCS1] = "VHT2SMCS1",
652 [DESC_RATEVHTSS2MCS2] = "VHT2SMCS2",
653 [DESC_RATEVHTSS2MCS3] = "VHT2SMCS3",
654 [DESC_RATEVHTSS2MCS4] = "VHT2SMCS4",
655 [DESC_RATEVHTSS2MCS5] = "VHT2SMCS5",
656 [DESC_RATEVHTSS2MCS6] = "VHT2SMCS6",
657 [DESC_RATEVHTSS2MCS7] = "VHT2SMCS7",
658 [DESC_RATEVHTSS2MCS8] = "VHT2SMCS8",
659 [DESC_RATEVHTSS2MCS9] = "VHT2SMCS9",
660 [DESC_RATEVHTSS3MCS0] = "VHT3SMCS0",
661 [DESC_RATEVHTSS3MCS1] = "VHT3SMCS1",
662 [DESC_RATEVHTSS3MCS2] = "VHT3SMCS2",
663 [DESC_RATEVHTSS3MCS3] = "VHT3SMCS3",
664 [DESC_RATEVHTSS3MCS4] = "VHT3SMCS4",
665 [DESC_RATEVHTSS3MCS5] = "VHT3SMCS5",
666 [DESC_RATEVHTSS3MCS6] = "VHT3SMCS6",
667 [DESC_RATEVHTSS3MCS7] = "VHT3SMCS7",
668 [DESC_RATEVHTSS3MCS8] = "VHT3SMCS8",
669 [DESC_RATEVHTSS3MCS9] = "VHT3SMCS9",
670 [DESC_RATEVHTSS4MCS0] = "VHT4SMCS0",
671 [DESC_RATEVHTSS4MCS1] = "VHT4SMCS1",
672 [DESC_RATEVHTSS4MCS2] = "VHT4SMCS2",
673 [DESC_RATEVHTSS4MCS3] = "VHT4SMCS3",
674 [DESC_RATEVHTSS4MCS4] = "VHT4SMCS4",
675 [DESC_RATEVHTSS4MCS5] = "VHT4SMCS5",
676 [DESC_RATEVHTSS4MCS6] = "VHT4SMCS6",
677 [DESC_RATEVHTSS4MCS7] = "VHT4SMCS7",
678 [DESC_RATEVHTSS4MCS8] = "VHT4SMCS8",
679 [DESC_RATEVHTSS4MCS9] = "VHT4SMCS9",
680 [DESC_RATE_NUM] = "UNKNOWN",
681 };
682
683 static const u8 _hw_rate_to_m_rate[DESC_RATE_NUM] = {
684 [DESC_RATE1M] = MGN_1M,
685 [DESC_RATE2M] = MGN_2M,
686 [DESC_RATE5_5M] = MGN_5_5M,
687 [DESC_RATE11M] = MGN_11M,
688 [DESC_RATE6M] = MGN_6M,
689 [DESC_RATE9M] = MGN_9M,
690 [DESC_RATE12M] = MGN_12M,
691 [DESC_RATE18M] = MGN_18M,
692 [DESC_RATE24M] = MGN_24M,
693 [DESC_RATE36M] = MGN_36M,
694 [DESC_RATE48M] = MGN_48M,
695 [DESC_RATE54M] = MGN_54M,
696 [DESC_RATEMCS0] = MGN_MCS0,
697 [DESC_RATEMCS1] = MGN_MCS1,
698 [DESC_RATEMCS2] = MGN_MCS2,
699 [DESC_RATEMCS3] = MGN_MCS3,
700 [DESC_RATEMCS4] = MGN_MCS4,
701 [DESC_RATEMCS5] = MGN_MCS5,
702 [DESC_RATEMCS6] = MGN_MCS6,
703 [DESC_RATEMCS7] = MGN_MCS7,
704 [DESC_RATEMCS8] = MGN_MCS8,
705 [DESC_RATEMCS9] = MGN_MCS9,
706 [DESC_RATEMCS10] = MGN_MCS10,
707 [DESC_RATEMCS11] = MGN_MCS11,
708 [DESC_RATEMCS12] = MGN_MCS12,
709 [DESC_RATEMCS13] = MGN_MCS13,
710 [DESC_RATEMCS14] = MGN_MCS14,
711 [DESC_RATEMCS15] = MGN_MCS15,
712 [DESC_RATEMCS16] = MGN_MCS16,
713 [DESC_RATEMCS17] = MGN_MCS17,
714 [DESC_RATEMCS18] = MGN_MCS18,
715 [DESC_RATEMCS19] = MGN_MCS19,
716 [DESC_RATEMCS20] = MGN_MCS20,
717 [DESC_RATEMCS21] = MGN_MCS21,
718 [DESC_RATEMCS22] = MGN_MCS22,
719 [DESC_RATEMCS23] = MGN_MCS23,
720 [DESC_RATEMCS24] = MGN_MCS24,
721 [DESC_RATEMCS25] = MGN_MCS25,
722 [DESC_RATEMCS26] = MGN_MCS26,
723 [DESC_RATEMCS27] = MGN_MCS27,
724 [DESC_RATEMCS28] = MGN_MCS28,
725 [DESC_RATEMCS29] = MGN_MCS29,
726 [DESC_RATEMCS30] = MGN_MCS30,
727 [DESC_RATEMCS31] = MGN_MCS31,
728 [DESC_RATEVHTSS1MCS0] = MGN_VHT1SS_MCS0,
729 [DESC_RATEVHTSS1MCS1] = MGN_VHT1SS_MCS1,
730 [DESC_RATEVHTSS1MCS2] = MGN_VHT1SS_MCS2,
731 [DESC_RATEVHTSS1MCS3] = MGN_VHT1SS_MCS3,
732 [DESC_RATEVHTSS1MCS4] = MGN_VHT1SS_MCS4,
733 [DESC_RATEVHTSS1MCS5] = MGN_VHT1SS_MCS5,
734 [DESC_RATEVHTSS1MCS6] = MGN_VHT1SS_MCS6,
735 [DESC_RATEVHTSS1MCS7] = MGN_VHT1SS_MCS7,
736 [DESC_RATEVHTSS1MCS8] = MGN_VHT1SS_MCS8,
737 [DESC_RATEVHTSS1MCS9] = MGN_VHT1SS_MCS9,
738 [DESC_RATEVHTSS2MCS0] = MGN_VHT2SS_MCS0,
739 [DESC_RATEVHTSS2MCS1] = MGN_VHT2SS_MCS1,
740 [DESC_RATEVHTSS2MCS2] = MGN_VHT2SS_MCS2,
741 [DESC_RATEVHTSS2MCS3] = MGN_VHT2SS_MCS3,
742 [DESC_RATEVHTSS2MCS4] = MGN_VHT2SS_MCS4,
743 [DESC_RATEVHTSS2MCS5] = MGN_VHT2SS_MCS5,
744 [DESC_RATEVHTSS2MCS6] = MGN_VHT2SS_MCS6,
745 [DESC_RATEVHTSS2MCS7] = MGN_VHT2SS_MCS7,
746 [DESC_RATEVHTSS2MCS8] = MGN_VHT2SS_MCS8,
747 [DESC_RATEVHTSS2MCS9] = MGN_VHT2SS_MCS9,
748 [DESC_RATEVHTSS3MCS0] = MGN_VHT3SS_MCS0,
749 [DESC_RATEVHTSS3MCS1] = MGN_VHT3SS_MCS1,
750 [DESC_RATEVHTSS3MCS2] = MGN_VHT3SS_MCS2,
751 [DESC_RATEVHTSS3MCS3] = MGN_VHT3SS_MCS3,
752 [DESC_RATEVHTSS3MCS4] = MGN_VHT3SS_MCS4,
753 [DESC_RATEVHTSS3MCS5] = MGN_VHT3SS_MCS5,
754 [DESC_RATEVHTSS3MCS6] = MGN_VHT3SS_MCS6,
755 [DESC_RATEVHTSS3MCS7] = MGN_VHT3SS_MCS7,
756 [DESC_RATEVHTSS3MCS8] = MGN_VHT3SS_MCS8,
757 [DESC_RATEVHTSS3MCS9] = MGN_VHT3SS_MCS9,
758 [DESC_RATEVHTSS4MCS0] = MGN_VHT4SS_MCS0,
759 [DESC_RATEVHTSS4MCS1] = MGN_VHT4SS_MCS1,
760 [DESC_RATEVHTSS4MCS2] = MGN_VHT4SS_MCS2,
761 [DESC_RATEVHTSS4MCS3] = MGN_VHT4SS_MCS3,
762 [DESC_RATEVHTSS4MCS4] = MGN_VHT4SS_MCS4,
763 [DESC_RATEVHTSS4MCS5] = MGN_VHT4SS_MCS5,
764 [DESC_RATEVHTSS4MCS6] = MGN_VHT4SS_MCS6,
765 [DESC_RATEVHTSS4MCS7] = MGN_VHT4SS_MCS7,
766 [DESC_RATEVHTSS4MCS8] = MGN_VHT4SS_MCS8,
767 [DESC_RATEVHTSS4MCS9] = MGN_VHT4SS_MCS9,
768 };
769
hw_rate_to_m_rate(u8 hw_rate)770 u8 hw_rate_to_m_rate(u8 hw_rate)
771 {
772 u8 rate = MGN_1M; /* default value */
773
774 if (hw_rate < DESC_RATE_NUM)
775 rate = _hw_rate_to_m_rate[hw_rate];
776 else
777 RTW_WARN("Invalid hw_rate 0x%x in %s\n", hw_rate, __FUNCTION__);
778
779 return rate;
780 }
781
782 #ifdef CONFIG_RTW_DEBUG
dump_hw_rate_map_test(void * sel)783 void dump_hw_rate_map_test(void *sel)
784 {
785 RATE_SECTION rs;
786 u8 hw_rate;
787 enum MGN_RATE m_rate;
788 int i;
789
790 for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
791 for (i = 0; i < rates_by_sections[rs].rate_num; i++) {
792 hw_rate = MRateToHwRate(rates_by_sections[rs].rates[i]);
793 RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
794 , MGN_RATE_STR(rates_by_sections[rs].rates[i]), rates_by_sections[rs].rates[i]
795 , HDATA_RATE(hw_rate), hw_rate
796 );
797 }
798 if (rs == HT_4SS) { /* show MCS32 after MCS31 */
799 hw_rate = MRateToHwRate(MGN_MCS32);
800 RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
801 , MGN_RATE_STR(MGN_MCS32), MGN_MCS32
802 , HDATA_RATE(hw_rate), hw_rate
803 );
804 }
805 }
806 hw_rate = MRateToHwRate(MGN_UNKNOWN);
807 RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
808 , MGN_RATE_STR(MGN_UNKNOWN), MGN_UNKNOWN
809 , HDATA_RATE(hw_rate), hw_rate
810 );
811
812 for (i = DESC_RATE1M; i <= DESC_RATE_NUM; i++) {
813 m_rate = hw_rate_to_m_rate(i);
814 RTW_PRINT_SEL(sel, "hw_rate:%s(%d) to m_rate:%s(%d)\n"
815 , HDATA_RATE(i), i
816 , MGN_RATE_STR(m_rate), m_rate
817 );
818 }
819 }
820 #endif /* CONFIG_RTW_DEBUG */
821
HalSetBrateCfg(PADAPTER Adapter,u8 * mBratesOS,u16 * pBrateCfg)822 void HalSetBrateCfg(
823 PADAPTER Adapter,
824 u8 *mBratesOS,
825 u16 *pBrateCfg)
826 {
827 u8 i, is_brate, brate;
828
829 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
830 is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
831 brate = mBratesOS[i] & 0x7f;
832
833 if (is_brate) {
834 switch (brate) {
835 case IEEE80211_CCK_RATE_1MB:
836 *pBrateCfg |= RATE_1M;
837 break;
838 case IEEE80211_CCK_RATE_2MB:
839 *pBrateCfg |= RATE_2M;
840 break;
841 case IEEE80211_CCK_RATE_5MB:
842 *pBrateCfg |= RATE_5_5M;
843 break;
844 case IEEE80211_CCK_RATE_11MB:
845 *pBrateCfg |= RATE_11M;
846 break;
847 case IEEE80211_OFDM_RATE_6MB:
848 *pBrateCfg |= RATE_6M;
849 break;
850 case IEEE80211_OFDM_RATE_9MB:
851 *pBrateCfg |= RATE_9M;
852 break;
853 case IEEE80211_OFDM_RATE_12MB:
854 *pBrateCfg |= RATE_12M;
855 break;
856 case IEEE80211_OFDM_RATE_18MB:
857 *pBrateCfg |= RATE_18M;
858 break;
859 case IEEE80211_OFDM_RATE_24MB:
860 *pBrateCfg |= RATE_24M;
861 break;
862 case IEEE80211_OFDM_RATE_36MB:
863 *pBrateCfg |= RATE_36M;
864 break;
865 case IEEE80211_OFDM_RATE_48MB:
866 *pBrateCfg |= RATE_48M;
867 break;
868 case IEEE80211_OFDM_RATE_54MB:
869 *pBrateCfg |= RATE_54M;
870 break;
871 }
872 }
873 }
874 }
875
876 static void
_OneOutPipeMapping(PADAPTER pAdapter)877 _OneOutPipeMapping(
878 PADAPTER pAdapter
879 )
880 {
881 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
882
883 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
884 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
885 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
886 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
887
888 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
889 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
890 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
891 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
892 }
893
894 static void
_TwoOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)895 _TwoOutPipeMapping(
896 PADAPTER pAdapter,
897 BOOLEAN bWIFICfg
898 )
899 {
900 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
901
902 if (bWIFICfg) { /* WMM */
903
904 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
905 /* { 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
906 /* 0:ep_0 num, 1:ep_1 num */
907
908 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
909 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
910 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
911 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
912
913 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
914 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
915 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
916 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
917
918 } else { /* typical setting */
919
920
921 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
922 /* { 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
923 /* 0:ep_0 num, 1:ep_1 num */
924
925 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
926 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
927 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
928 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
929
930 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
931 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
932 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
933 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
934
935 }
936
937 }
938
_ThreeOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)939 static void _ThreeOutPipeMapping(
940 PADAPTER pAdapter,
941 BOOLEAN bWIFICfg
942 )
943 {
944 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
945
946 if (bWIFICfg) { /* for WMM */
947
948 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
949 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
950 /* 0:H, 1:N, 2:L */
951
952 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
953 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
954 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
955 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
956
957 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
958 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
959 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
960 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
961
962 } else { /* typical setting */
963
964
965 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
966 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
967 /* 0:H, 1:N, 2:L */
968
969 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
970 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
971 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
972 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
973
974 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
975 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
976 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
977 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
978 }
979
980 }
981 #if 0
982 static void _FourOutPipeMapping(
983 PADAPTER pAdapter,
984 BOOLEAN bWIFICfg
985 )
986 {
987 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
988
989 if (bWIFICfg) { /* for WMM */
990
991 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
992 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
993 /* 0:H, 1:N, 2:L ,3:E */
994
995 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
996 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
997 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
998 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
999
1000 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1001 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1002 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1003 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1004
1005 } else { /* typical setting */
1006
1007
1008 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1009 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1010 /* 0:H, 1:N, 2:L */
1011
1012 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1013 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1014 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1015 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1016
1017 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1018 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1019 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1020 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1021 }
1022
1023 }
1024 #endif
1025 BOOLEAN
Hal_MappingOutPipe(PADAPTER pAdapter,u8 NumOutPipe)1026 Hal_MappingOutPipe(
1027 PADAPTER pAdapter,
1028 u8 NumOutPipe
1029 )
1030 {
1031 struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
1032
1033 BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
1034
1035 BOOLEAN result = _TRUE;
1036
1037 switch (NumOutPipe) {
1038 case 2:
1039 _TwoOutPipeMapping(pAdapter, bWIFICfg);
1040 break;
1041 case 3:
1042 case 4:
1043 case 5:
1044 case 6:
1045 _ThreeOutPipeMapping(pAdapter, bWIFICfg);
1046 break;
1047 case 1:
1048 _OneOutPipeMapping(pAdapter);
1049 break;
1050 default:
1051 result = _FALSE;
1052 break;
1053 }
1054
1055 return result;
1056
1057 }
1058
rtw_hal_reqtxrpt(_adapter * padapter,u8 macid)1059 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1060 {
1061 if (padapter->hal_func.reqtxrpt)
1062 padapter->hal_func.reqtxrpt(padapter, macid);
1063 }
1064
rtw_hal_dump_macaddr(void * sel,_adapter * adapter)1065 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1066 {
1067 int i;
1068 _adapter *iface;
1069 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1070 u8 mac_addr[ETH_ALEN];
1071
1072 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1073 rtw_mbid_cam_dump(sel, __func__, adapter);
1074 #else
1075 rtw_mi_hal_dump_macaddr(sel, adapter);
1076 #endif
1077 }
1078
1079 #ifdef RTW_HALMAC
rtw_hal_hw_port_enable(_adapter * adapter)1080 void rtw_hal_hw_port_enable(_adapter *adapter)
1081 {
1082 #if 1
1083 u8 port_enable = _TRUE;
1084
1085 rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1086 #else
1087 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1088 struct rtw_halmac_bcn_ctrl bcn_ctrl;
1089
1090 _rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
1091 bcn_ctrl.enable_bcn = 1;
1092 bcn_ctrl.rx_bssid_fit = 1;
1093 bcn_ctrl.rxbcn_rpt = 1;
1094
1095 /*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1096 struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
1097 if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
1098 RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
1099 rtw_warn_on(1);
1100 }
1101 #endif
1102 }
rtw_hal_hw_port_disable(_adapter * adapter)1103 void rtw_hal_hw_port_disable(_adapter *adapter)
1104 {
1105 u8 port_enable = _FALSE;
1106
1107 rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1108 }
1109
rtw_restore_hw_port_cfg(_adapter * adapter)1110 void rtw_restore_hw_port_cfg(_adapter *adapter)
1111 {
1112 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1113
1114 #else
1115 int i;
1116 _adapter *iface;
1117 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1118
1119 for (i = 0; i < dvobj->iface_nums; i++) {
1120 iface = dvobj->padapters[i];
1121 if (iface)
1122 rtw_hal_hw_port_enable(iface);
1123 }
1124 #endif
1125 }
1126 #endif
1127
rtw_mi_set_mac_addr(_adapter * adapter)1128 void rtw_mi_set_mac_addr(_adapter *adapter)
1129 {
1130 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1131 rtw_mi_set_mbid_cam(adapter);
1132 #else
1133 int i;
1134 _adapter *iface;
1135 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1136
1137 for (i = 0; i < dvobj->iface_nums; i++) {
1138 iface = dvobj->padapters[i];
1139 if (iface)
1140 rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
1141 }
1142 #endif
1143 if (0)
1144 rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1145 }
1146
rtw_init_hal_com_default_value(PADAPTER Adapter)1147 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1148 {
1149 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
1150 struct registry_priv *regsty = adapter_to_regsty(Adapter);
1151
1152 pHalData->AntDetection = 1;
1153 pHalData->antenna_test = _FALSE;
1154 pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
1155 pHalData->ch_switch_offload = regsty->ch_switch_offload;
1156 pHalData->multi_ch_switch_mode = 0;
1157 #ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME
1158 if (pHalData->ch_switch_offload == 0)
1159 pHalData->ch_switch_offload = 1;
1160 #endif
1161 }
1162
1163 #ifdef CONFIG_FW_C2H_REG
c2h_evt_clear(_adapter * adapter)1164 void c2h_evt_clear(_adapter *adapter)
1165 {
1166 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1167 }
1168
c2h_evt_read_88xx(_adapter * adapter,u8 * buf)1169 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1170 {
1171 s32 ret = _FAIL;
1172 int i;
1173 u8 trigger;
1174
1175 if (buf == NULL)
1176 goto exit;
1177
1178 trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1179
1180 if (trigger == C2H_EVT_HOST_CLOSE) {
1181 goto exit; /* Not ready */
1182 } else if (trigger != C2H_EVT_FW_CLOSE) {
1183 goto clear_evt; /* Not a valid value */
1184 }
1185
1186 _rtw_memset(buf, 0, C2H_REG_LEN);
1187
1188 /* Read ID, LEN, SEQ */
1189 SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
1190 SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
1191 SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
1192
1193 if (0) {
1194 RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
1195 , C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
1196 }
1197
1198 /* Read the content */
1199 for (i = 0; i < C2H_PLEN_88XX(buf); i++)
1200 *(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1201
1202 RTW_DBG_DUMP("payload: ", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
1203
1204 ret = _SUCCESS;
1205
1206 clear_evt:
1207 /*
1208 * Clear event to notify FW we have read the command.
1209 * If this field isn't clear, the FW won't update the next command message.
1210 */
1211 c2h_evt_clear(adapter);
1212
1213 exit:
1214 return ret;
1215 }
1216 #endif /* CONFIG_FW_C2H_REG */
1217
1218 #ifdef CONFIG_FW_C2H_PKT
1219 #ifndef DBG_C2H_PKT_PRE_HDL
1220 #define DBG_C2H_PKT_PRE_HDL 0
1221 #endif
1222 #ifndef DBG_C2H_PKT_HDL
1223 #define DBG_C2H_PKT_HDL 0
1224 #endif
rtw_hal_c2h_pkt_pre_hdl(_adapter * adapter,u8 * buf,u16 len)1225 void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
1226 {
1227 #ifdef RTW_HALMAC
1228 /* TODO: extract hal_mac IC's code here*/
1229 #else
1230 u8 parse_fail = 0;
1231 u8 hdl_here = 0;
1232 s32 ret = _FAIL;
1233 u8 id, seq, plen;
1234 u8 *payload;
1235
1236 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1237 parse_fail = 1;
1238 goto exit;
1239 }
1240
1241 hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
1242 if (hdl_here)
1243 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1244 else
1245 ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
1246
1247 exit:
1248 if (parse_fail)
1249 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1250 else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
1251 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1252 , hdl_here ? "handle" : "enqueue"
1253 , ret == _SUCCESS ? "ok" : "fail"
1254 );
1255 if (DBG_C2H_PKT_PRE_HDL >= 2)
1256 RTW_PRINT_DUMP("dump: ", buf, len);
1257 }
1258 #endif
1259 }
1260
rtw_hal_c2h_pkt_hdl(_adapter * adapter,u8 * buf,u16 len)1261 void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
1262 {
1263 #ifdef RTW_HALMAC
1264 adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
1265 #else
1266 u8 parse_fail = 0;
1267 u8 bypass = 0;
1268 s32 ret = _FAIL;
1269 u8 id, seq, plen;
1270 u8 *payload;
1271
1272 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1273 parse_fail = 1;
1274 goto exit;
1275 }
1276
1277 #ifdef CONFIG_WOWLAN
1278 if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
1279 bypass = 1;
1280 ret = _SUCCESS;
1281 goto exit;
1282 }
1283 #endif
1284
1285 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1286
1287 exit:
1288 if (parse_fail)
1289 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1290 else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
1291 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1292 , !bypass ? "handle" : "bypass"
1293 , ret == _SUCCESS ? "ok" : "fail"
1294 );
1295 if (DBG_C2H_PKT_HDL >= 2)
1296 RTW_PRINT_DUMP("dump: ", buf, len);
1297 }
1298 #endif
1299 }
1300 #endif /* CONFIG_FW_C2H_PKT */
1301
c2h_iqk_offload(_adapter * adapter,u8 * data,u8 len)1302 void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
1303 {
1304 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1305 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1306
1307 RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
1308 if (0)
1309 RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
1310
1311 rtw_sctx_done(&iqk_sctx);
1312 }
1313
c2h_iqk_offload_wait(_adapter * adapter,u32 timeout_ms)1314 int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
1315 {
1316 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1317 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1318
1319 iqk_sctx->submit_time = rtw_get_current_time();
1320 iqk_sctx->timeout_ms = timeout_ms;
1321 iqk_sctx->status = RTW_SCTX_SUBMITTED;
1322
1323 return rtw_sctx_wait(iqk_sctx, __func__);
1324 }
1325
1326 #ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX
c2h_txpwr_idx_offload_done(_adapter * adapter,u8 * data,u8 len)1327 void c2h_txpwr_idx_offload_done(_adapter *adapter, u8 *data, u8 len)
1328 {
1329 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1330 struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1331
1332 if (0)
1333 RTW_INFO("txpwr_idx offload finish in %dms\n", rtw_get_passing_time_ms(sctx->submit_time));
1334 rtw_sctx_done(&sctx);
1335 }
1336
c2h_txpwr_idx_offload_wait(_adapter * adapter)1337 int c2h_txpwr_idx_offload_wait(_adapter *adapter)
1338 {
1339 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1340 struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1341
1342 return rtw_sctx_wait(sctx, __func__);
1343 }
1344 #endif
1345
1346 #define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1347 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1348 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1349 #define GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1350 #define GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1351 #define GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
1352 #define GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
1353 #define GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1354 #define GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1355 #define GET_C2H_MAC_HIDDEN_RPT_BW(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1356 #define GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1357 #define GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1358 #define GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1359
1360 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1361 #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1362 #endif
1363
1364 #ifdef CONFIG_RTW_MAC_HIDDEN_RPT
c2h_mac_hidden_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1365 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1366 {
1367 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1368 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1369 enum rf_type rf_type;
1370 u8 tx_path_num, rx_path_num;
1371 int ret = _FAIL;
1372
1373 u8 uuid_x;
1374 u8 uuid_y;
1375 u8 uuid_z;
1376 u16 uuid_crc;
1377
1378 u8 hci_type;
1379 u8 package_type;
1380 u8 tr_switch;
1381 u8 wl_func;
1382 u8 hw_stype;
1383 u8 bw;
1384 u8 ss_num = 4;
1385 u8 ant_num;
1386 u8 protocol;
1387 u8 nic;
1388
1389 int i;
1390
1391 if (len < MAC_HIDDEN_RPT_LEN) {
1392 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1393 goto exit;
1394 }
1395
1396 uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1397 uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1398 uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1399 uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1400
1401 hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1402 package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1403
1404 tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
1405
1406 wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1407 hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1408
1409 bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1410 ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1411
1412 protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1413 nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1414
1415 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1416 for (i = 0; i < len; i++)
1417 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1418
1419 RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1420 RTW_PRINT("hci_type:0x%x\n", hci_type);
1421 RTW_PRINT("package_type:0x%x\n", package_type);
1422 RTW_PRINT("tr_switch:0x%x\n", tr_switch);
1423 RTW_PRINT("wl_func:0x%x\n", wl_func);
1424 RTW_PRINT("hw_stype:0x%x\n", hw_stype);
1425 RTW_PRINT("bw:0x%x\n", bw);
1426 RTW_PRINT("ant_num:0x%x\n", ant_num);
1427 RTW_PRINT("protocol:0x%x\n", protocol);
1428 RTW_PRINT("nic:0x%x\n", nic);
1429 }
1430
1431 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
1432 if (IS_8822C_SERIES(hal_data->version_id) || IS_8814B_SERIES(hal_data->version_id)) {
1433 #define GET_C2H_MAC_HIDDEN_RPT_SS_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)
1434 ss_num = GET_C2H_MAC_HIDDEN_RPT_SS_NUM(data);
1435
1436 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1437 RTW_PRINT("ss_num:0x%x\n", ss_num);
1438
1439 if (ss_num == 0x03)
1440 ss_num = 4;
1441 }
1442 #endif
1443
1444 #if defined(CONFIG_RTL8822C)
1445 if (IS_8822C_SERIES(hal_data->version_id)) {
1446 if (ant_num == 1)
1447 hal_spec->rf_reg_trx_path_bmp = 0x22; /* 1T1R pathB */
1448 if (hw_stype == 0xE)
1449 hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, 1); /* limit 1TX only */
1450 }
1451 #endif
1452 hal_data->PackageType = package_type;
1453 hal_spec->hci_type = hci_type;
1454 hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1455 hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1456 hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1457
1458 rf_type = rtw_chip_rftype_to_hal_rftype(adapter, 0);
1459 if (!RF_TYPE_VALID(rf_type)) {
1460 RTW_ERR("%s rtw_chip_rftype_to_hal_rftype failed\n", __func__);
1461 goto exit;
1462 }
1463 hal_spec->rf_reg_path_avail_num = rtw_min(hal_spec->rf_reg_path_num, ant_num);
1464 tx_path_num = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1465 rx_path_num = rtw_min(rf_type_to_rf_rx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1466 hal_spec->rf_reg_trx_path_bmp = rtw_restrict_trx_path_bmp_by_trx_num_lmt(
1467 hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num, &tx_path_num, &rx_path_num);
1468 if (!hal_spec->rf_reg_trx_path_bmp) {
1469 RTW_ERR("%s rtw_restrict_trx_path_bmp_by_trx_num_lmt(0x%x, %u, %u) failed\n"
1470 , __func__, hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num);
1471 goto exit;
1472 }
1473 hal_spec->rf_reg_path_avail_num = rtw_max(tx_path_num, rx_path_num);
1474
1475 /*
1476 * RF TX path num >= max_tx_cnt >= tx_nss_num
1477 * ex: RF TX path num(4) >= max_tx_cnt(2) >= tx_nss_num(1)
1478 * Select at most 2 out of 4 TX RF path to do 1SS 2TX
1479 */
1480 hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, tx_path_num);
1481 hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, hal_spec->max_tx_cnt);
1482 hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ss_num);
1483
1484 hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rx_path_num);
1485 hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ss_num);
1486
1487 ret = _SUCCESS;
1488
1489 exit:
1490 return ret;
1491 }
1492
c2h_mac_hidden_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1493 int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1494 {
1495 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1496 int ret = _FAIL;
1497
1498 int i;
1499
1500 if (len < MAC_HIDDEN_RPT_2_LEN) {
1501 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
1502 goto exit;
1503 }
1504
1505 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1506 for (i = 0; i < len; i++)
1507 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1508 }
1509
1510 #if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)
1511 if (IS_8188F(hal_data->version_id) || IS_8188GTV(hal_data->version_id)) {
1512 #define GET_C2H_MAC_HIDDEN_RPT_IRV(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
1513 u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
1514
1515 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1516 RTW_PRINT("irv:0x%x\n", irv);
1517
1518 if(irv != 0xf)
1519 hal_data->version_id.CUTVersion = irv;
1520 }
1521 #endif
1522
1523 ret = _SUCCESS;
1524
1525 exit:
1526 return ret;
1527 }
1528
hal_read_mac_hidden_rpt(_adapter * adapter)1529 int hal_read_mac_hidden_rpt(_adapter *adapter)
1530 {
1531 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
1532 int ret = _FAIL;
1533 int ret_fwdl;
1534 u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
1535 systime start = rtw_get_current_time();
1536 u32 cnt = 0;
1537 u32 timeout_ms = 800;
1538 u32 min_cnt = 10;
1539 u8 id = C2H_DEFEATURE_RSVD;
1540 int i;
1541
1542 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1543 u8 hci_type = rtw_get_intf_type(adapter);
1544
1545 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1546 && !rtw_is_hw_init_completed(adapter))
1547 rtw_hal_power_on(adapter);
1548 #endif
1549
1550 /* inform FW mac hidden rpt from reg is needed */
1551 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
1552
1553 /* download FW */
1554 pHalData->not_xmitframe_fw_dl = 1;
1555 ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1556 pHalData->not_xmitframe_fw_dl = 0;
1557 if (ret_fwdl != _SUCCESS)
1558 goto mac_hidden_rpt_hdl;
1559
1560 /* polling for data ready */
1561 start = rtw_get_current_time();
1562 do {
1563 cnt++;
1564 id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1565 if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1566 break;
1567 rtw_msleep_os(10);
1568 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1569
1570 if (id == C2H_MAC_HIDDEN_RPT) {
1571 /* read data */
1572 for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
1573 mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1574 }
1575
1576 /* inform FW mac hidden rpt has read */
1577 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
1578
1579 mac_hidden_rpt_hdl:
1580 c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1581 c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
1582
1583 if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1584 ret = _SUCCESS;
1585
1586 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1587 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1588 && !rtw_is_hw_init_completed(adapter))
1589 rtw_hal_power_off(adapter);
1590 #endif
1591
1592 RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1593 , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1594
1595 return ret;
1596 }
1597 #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
1598
c2h_defeature_dbg_hdl(_adapter * adapter,u8 * data,u8 len)1599 int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
1600 {
1601 int ret = _FAIL;
1602
1603 int i;
1604
1605 if (len < DEFEATURE_DBG_LEN) {
1606 RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
1607 goto exit;
1608 }
1609
1610 for (i = 0; i < len; i++)
1611 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1612
1613 ret = _SUCCESS;
1614
1615 exit:
1616 return ret;
1617 }
1618
1619 #ifndef DBG_CUSTOMER_STR_RPT_HANDLE
1620 #define DBG_CUSTOMER_STR_RPT_HANDLE 0
1621 #endif
1622
1623 #ifdef CONFIG_RTW_CUSTOMER_STR
rtw_hal_h2c_customer_str_req(_adapter * adapter)1624 s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
1625 {
1626 u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
1627
1628 SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
1629 return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
1630 }
1631
1632 #define C2H_CUSTOMER_STR_RPT_BYTE0(_data) ((u8 *)(_data))
1633 #define C2H_CUSTOMER_STR_RPT_2_BYTE8(_data) ((u8 *)(_data))
1634
c2h_customer_str_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1635 int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1636 {
1637 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1638 int ret = _FAIL;
1639 int i;
1640
1641 if (len < CUSTOMER_STR_RPT_LEN) {
1642 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
1643 goto exit;
1644 }
1645
1646 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1647 RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
1648
1649 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1650
1651 if (dvobj->customer_str_sctx != NULL) {
1652 if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
1653 RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
1654 _rtw_memcpy(dvobj->customer_str, C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
1655 dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
1656 } else
1657 RTW_WARN("%s sctx not set\n", __func__);
1658
1659 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1660
1661 ret = _SUCCESS;
1662
1663 exit:
1664 return ret;
1665 }
1666
c2h_customer_str_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1667 int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1668 {
1669 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1670 int ret = _FAIL;
1671 int i;
1672
1673 if (len < CUSTOMER_STR_RPT_2_LEN) {
1674 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
1675 goto exit;
1676 }
1677
1678 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1679 RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
1680
1681 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1682
1683 if (dvobj->customer_str_sctx != NULL) {
1684 if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
1685 RTW_WARN("%s rpt not ready\n", __func__);
1686 _rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN, C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
1687 rtw_sctx_done(&dvobj->customer_str_sctx);
1688 } else
1689 RTW_WARN("%s sctx not set\n", __func__);
1690
1691 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1692
1693 ret = _SUCCESS;
1694
1695 exit:
1696 return ret;
1697 }
1698
1699 /* read customer str */
rtw_hal_customer_str_read(_adapter * adapter,u8 * cs)1700 s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
1701 {
1702 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1703 struct submit_ctx sctx;
1704 s32 ret = _SUCCESS;
1705
1706 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1707 if (dvobj->customer_str_sctx != NULL)
1708 ret = _FAIL;
1709 else {
1710 rtw_sctx_init(&sctx, 2 * 1000);
1711 dvobj->customer_str_sctx = &sctx;
1712 }
1713 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1714
1715 if (ret == _FAIL) {
1716 RTW_WARN("%s another handle ongoing\n", __func__);
1717 goto exit;
1718 }
1719
1720 ret = rtw_customer_str_req_cmd(adapter);
1721 if (ret != _SUCCESS) {
1722 RTW_WARN("%s read cmd fail\n", __func__);
1723 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1724 dvobj->customer_str_sctx = NULL;
1725 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1726 goto exit;
1727 }
1728
1729 /* wait till rpt done or timeout */
1730 rtw_sctx_wait(&sctx, __func__);
1731
1732 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1733 dvobj->customer_str_sctx = NULL;
1734 if (sctx.status == RTW_SCTX_DONE_SUCCESS)
1735 _rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1736 else
1737 ret = _FAIL;
1738 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1739
1740 exit:
1741 return ret;
1742 }
1743
rtw_hal_h2c_customer_str_write(_adapter * adapter,const u8 * cs)1744 s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
1745 {
1746 u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
1747 u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
1748 u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
1749 s32 ret;
1750
1751 SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
1752 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
1753
1754 SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
1755 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
1756
1757 SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
1758 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
1759
1760 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
1761 if (ret != _SUCCESS) {
1762 RTW_WARN("%s w1 fail\n", __func__);
1763 goto exit;
1764 }
1765
1766 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
1767 if (ret != _SUCCESS) {
1768 RTW_WARN("%s w2 fail\n", __func__);
1769 goto exit;
1770 }
1771
1772 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
1773 if (ret != _SUCCESS) {
1774 RTW_WARN("%s w3 fail\n", __func__);
1775 goto exit;
1776 }
1777
1778 exit:
1779 return ret;
1780 }
1781
1782 /* write customer str and check if value reported is the same as requested */
rtw_hal_customer_str_write(_adapter * adapter,const u8 * cs)1783 s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
1784 {
1785 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1786 struct submit_ctx sctx;
1787 s32 ret = _SUCCESS;
1788
1789 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1790 if (dvobj->customer_str_sctx != NULL)
1791 ret = _FAIL;
1792 else {
1793 rtw_sctx_init(&sctx, 2 * 1000);
1794 dvobj->customer_str_sctx = &sctx;
1795 }
1796 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1797
1798 if (ret == _FAIL) {
1799 RTW_WARN("%s another handle ongoing\n", __func__);
1800 goto exit;
1801 }
1802
1803 ret = rtw_customer_str_write_cmd(adapter, cs);
1804 if (ret != _SUCCESS) {
1805 RTW_WARN("%s write cmd fail\n", __func__);
1806 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1807 dvobj->customer_str_sctx = NULL;
1808 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1809 goto exit;
1810 }
1811
1812 ret = rtw_customer_str_req_cmd(adapter);
1813 if (ret != _SUCCESS) {
1814 RTW_WARN("%s read cmd fail\n", __func__);
1815 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1816 dvobj->customer_str_sctx = NULL;
1817 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1818 goto exit;
1819 }
1820
1821 /* wait till rpt done or timeout */
1822 rtw_sctx_wait(&sctx, __func__);
1823
1824 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1825 dvobj->customer_str_sctx = NULL;
1826 if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
1827 if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
1828 RTW_WARN("%s read back check fail\n", __func__);
1829 RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
1830 RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1831 ret = _FAIL;
1832 }
1833 } else
1834 ret = _FAIL;
1835 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1836
1837 exit:
1838 return ret;
1839 }
1840 #endif /* CONFIG_RTW_CUSTOMER_STR */
1841
1842 #ifdef RTW_PER_CMD_SUPPORT_FW
1843 #define H2C_REQ_PER_RPT_LEN 5
1844 #define SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value)
1845 #define SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value)
1846 #define SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(__pH2CCmd, __Value) SET_BITS_TO_LE_4BYTE(__pH2CCmd + 1, 0, 32, __Value)
1847
rtw_hal_set_req_per_rpt_cmd(_adapter * adapter,u8 group_macid,u8 rpt_type,u32 macid_bitmap)1848 u8 rtw_hal_set_req_per_rpt_cmd(_adapter *adapter, u8 group_macid,
1849 u8 rpt_type, u32 macid_bitmap)
1850 {
1851 u8 ret = _FAIL;
1852 u8 cmd_buf[H2C_REQ_PER_RPT_LEN] = {0};
1853
1854 SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(cmd_buf, group_macid);
1855 SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(cmd_buf, rpt_type);
1856 SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(cmd_buf, macid_bitmap);
1857
1858 ret = rtw_hal_fill_h2c_cmd(adapter,
1859 H2C_REQ_PER_RPT,
1860 H2C_REQ_PER_RPT_LEN,
1861 cmd_buf);
1862 return ret;
1863 }
1864
1865 #define GET_C2H_PER_RATE_RPT_TYPE0_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
1866 #define GET_C2H_PER_RATE_RPT_TYPE0_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1867 #define GET_C2H_PER_RATE_RPT_TYPE0_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
1868 #define GET_C2H_PER_RATE_RPT_TYPE0_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
1869 #define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 4, 0, 16)
1870 #define GET_C2H_PER_RATE_RPT_TYPE0_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
1871 #define GET_C2H_PER_RATE_RPT_TYPE0_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 8)
1872 #define GET_C2H_PER_RATE_RPT_TYPE0_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
1873 #define GET_C2H_PER_RATE_RPT_TYPE0_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 2)
1874 #define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 10, 0, 16)
1875
1876 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
1877 #define GET_C2H_PER_RATE_RPT_TYPE1_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1878 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
1879 #define GET_C2H_PER_RATE_RPT_TYPE1_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
1880 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 8)
1881 #define GET_C2H_PER_RATE_RPT_TYPE1_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 8)
1882 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
1883 #define GET_C2H_PER_RATE_RPT_TYPE1_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 2)
1884 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
1885 #define GET_C2H_PER_RATE_RPT_TYPE1_PER2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 8)
1886 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 10, 0, 8)
1887 #define GET_C2H_PER_RATE_RPT_TYPE1_BW2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 11, 0, 2)
1888
per_rate_rpt_update(_adapter * adapter,u8 mac_id,u8 per,u8 rate,u8 bw,u8 total_pkt)1889 static void per_rate_rpt_update(_adapter *adapter, u8 mac_id,
1890 u8 per, u8 rate,
1891 u8 bw, u8 total_pkt)
1892 {
1893 #ifdef CONFIG_RTW_MESH
1894 rtw_ieee80211s_update_metric(adapter, mac_id,
1895 per, rate,
1896 bw, total_pkt);
1897 #endif
1898 }
1899
c2h_per_rate_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1900 int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1901 {
1902 /* Now only consider type0, since it covers all params in type1
1903 * type0: mac_id, per, rate, bw, total_pkt
1904 * type1: mac_id, per, rate, bw
1905 */
1906 u8 mac_id[2] = {0}, per[2] = {0}, rate[2] = {0}, bw[2] = {0};
1907 u16 total_pkt[2] = {0};
1908 int ret = _FAIL, i, macid_cnt = 0;
1909
1910 /* type0:
1911 * 1 macid includes 6 bytes info + 1 byte 0xff
1912 * 2 macid includes 2*6 bytes info
1913 */
1914 if (!(len == 7 || len == 12)) {
1915 RTW_WARN("%s len(%u) != 7 or 12\n", __FUNCTION__, len);
1916 goto exit;
1917 }
1918
1919 macid_cnt++;
1920 mac_id[0] = GET_C2H_PER_RATE_RPT_TYPE0_MACID0(data);
1921 per[0] = GET_C2H_PER_RATE_RPT_TYPE0_PER0(data);
1922 rate[0] = GET_C2H_PER_RATE_RPT_TYPE0_RATE0(data);
1923 bw[0] = GET_C2H_PER_RATE_RPT_TYPE0_BW0(data);
1924 total_pkt[0] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(data);
1925
1926 mac_id[1] = GET_C2H_PER_RATE_RPT_TYPE0_MACID1(data);
1927 /* 0xff means no report anymore */
1928 if (mac_id[1] == 0xff)
1929 goto update_per;
1930 if (len != 12) {
1931 RTW_WARN("%s incorrect format\n", __FUNCTION__);
1932 goto exit;
1933 }
1934 macid_cnt++;
1935 per[1] = GET_C2H_PER_RATE_RPT_TYPE0_PER1(data);
1936 rate[1] = GET_C2H_PER_RATE_RPT_TYPE0_RATE1(data);
1937 bw[1] = GET_C2H_PER_RATE_RPT_TYPE0_BW1(data);
1938 total_pkt[1] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(data);
1939
1940 update_per:
1941 for (i = 0; i < macid_cnt; i++) {
1942 RTW_DBG("[%s] type0 rpt[%d]: macid = %u, per = %u, "
1943 "rate = %u, bw = %u, total_pkt = %u\n",
1944 __FUNCTION__, i, mac_id[i], per[i],
1945 rate[i], bw[i], total_pkt[i]);
1946 per_rate_rpt_update(adapter, mac_id[i],
1947 per[i], rate[i],
1948 bw[i], total_pkt[i]);
1949 }
1950 ret = _SUCCESS;
1951 exit:
1952 return ret;
1953 }
1954 #endif /* RTW_PER_CMD_SUPPORT_FW */
1955
1956 #ifdef CONFIG_LPS_ACK
1957 #define GET_C2H_LPS_STATUS_RPT_GET_ACTION(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
1958 #define GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1959 #define DBG_LPS_STATUS_RPT 0
1960
c2h_lps_status_rpt(PADAPTER adapter,u8 * data,u8 len)1961 int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len)
1962 {
1963 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
1964 struct submit_ctx *lps_sctx = &pwrpriv->lps_ack_sctx;
1965 u8 action = 0;
1966 s8 status_code = 0;
1967 int ret = _FAIL;
1968
1969 if (len < LPS_STATUS_RPT_LEN) {
1970 RTW_WARN("%s len(%u) < %d\n", __func__, len, LPS_STATUS_RPT_LEN);
1971 goto exit;
1972 }
1973
1974 action = GET_C2H_LPS_STATUS_RPT_GET_ACTION(data);
1975 status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data);
1976
1977 /* action=0: report force leave null data status */
1978 /* action=1: report Rf on status when receiving a SetPwrMode H2C with PwrState = RFON */
1979 switch (action) {
1980 case 0:
1981 /* status code 0: success, 1: no ack, 2: timeout, 3: cancel */
1982 case 1:
1983 /* status code 0: FW has already turn to RFON */
1984 pwrpriv->lps_ack_status = status_code;
1985
1986 if (DBG_LPS_STATUS_RPT)
1987 RTW_INFO("=== [C2H LPS Action(%d)] LPS Status Code:%d ===\n", action, status_code);
1988
1989 break;
1990 default:
1991 RTW_INFO("UnKnown Action(%d) for C2H LPS RPT\n", action);
1992 break;
1993 }
1994
1995 rtw_sctx_done(&lps_sctx);
1996 ret = _SUCCESS;
1997
1998 exit:
1999 return ret;
2000 }
2001 #endif /* CONFIG_LPS_ACK */
2002
rtw_hal_update_sta_wset(_adapter * adapter,struct sta_info * psta)2003 void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
2004 {
2005 u8 w_set = 0;
2006
2007 if (psta->wireless_mode & WIRELESS_11B)
2008 w_set |= WIRELESS_CCK;
2009
2010 if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
2011 w_set |= WIRELESS_OFDM;
2012
2013 if ((psta->wireless_mode & WIRELESS_11_24N) || (psta->wireless_mode & WIRELESS_11_5N))
2014 w_set |= WIRELESS_HT;
2015
2016 if (psta->wireless_mode & WIRELESS_11AC)
2017 w_set |= WIRELESS_VHT;
2018
2019 psta->cmn.support_wireless_set = w_set;
2020 }
2021
rtw_hal_update_sta_mimo_type(_adapter * adapter,struct sta_info * psta)2022 void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
2023 {
2024 s8 tx_nss, rx_nss;
2025
2026 tx_nss = rtw_get_sta_tx_nss(adapter, psta);
2027 rx_nss = rtw_get_sta_rx_nss(adapter, psta);
2028 if ((tx_nss == 1) && (rx_nss == 1))
2029 psta->cmn.mimo_type = RF_1T1R;
2030 else if ((tx_nss == 1) && (rx_nss == 2))
2031 psta->cmn.mimo_type = RF_1T2R;
2032 else if ((tx_nss == 2) && (rx_nss == 2))
2033 psta->cmn.mimo_type = RF_2T2R;
2034 else if ((tx_nss == 2) && (rx_nss == 3))
2035 psta->cmn.mimo_type = RF_2T3R;
2036 else if ((tx_nss == 2) && (rx_nss == 4))
2037 psta->cmn.mimo_type = RF_2T4R;
2038 else if ((tx_nss == 3) && (rx_nss == 3))
2039 psta->cmn.mimo_type = RF_3T3R;
2040 else if ((tx_nss == 3) && (rx_nss == 4))
2041 psta->cmn.mimo_type = RF_3T4R;
2042 else if ((tx_nss == 4) && (rx_nss == 4))
2043 psta->cmn.mimo_type = RF_4T4R;
2044 else
2045 rtw_warn_on(1);
2046
2047 #ifdef CONFIG_CTRL_TXSS_BY_TP
2048 rtw_ctrl_txss_update_mimo_type(adapter, psta);
2049 #endif
2050
2051 RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
2052 psta->cmn.mac_id, tx_nss, rx_nss);
2053 }
2054
rtw_hal_update_sta_smps_cap(_adapter * adapter,struct sta_info * psta)2055 void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
2056 {
2057 /*Spatial Multiplexing Power Save*/
2058 #if 0
2059 if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2060 #ifdef CONFIG_80211N_HT
2061 if (psta->htpriv.ht_option) {
2062 if (psta->htpriv.smps_cap == 0)
2063 psta->cmn.sm_ps = SM_PS_STATIC;
2064 else if (psta->htpriv.smps_cap == 1)
2065 psta->cmn.sm_ps = SM_PS_DYNAMIC;
2066 else
2067 psta->cmn.sm_ps = SM_PS_DISABLE;
2068 }
2069 #endif /* CONFIG_80211N_HT */
2070 } else
2071 #endif
2072 psta->cmn.sm_ps = SM_PS_DISABLE;
2073
2074 RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
2075 psta->cmn.mac_id, psta->cmn.sm_ps);
2076 }
2077
rtw_get_mgntframe_raid(_adapter * adapter,unsigned char network_type)2078 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
2079 {
2080
2081 u8 raid;
2082 if (IS_NEW_GENERATION_IC(adapter)) {
2083
2084 raid = (network_type & WIRELESS_11B) ? RATEID_IDX_B
2085 : RATEID_IDX_G;
2086 } else {
2087 raid = (network_type & WIRELESS_11B) ? RATR_INX_WIRELESS_B
2088 : RATR_INX_WIRELESS_G;
2089 }
2090 return raid;
2091 }
2092
rtw_hal_update_sta_rate_mask(PADAPTER padapter,struct sta_info * psta)2093 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
2094 {
2095 u8 i, tx_nss;
2096 u64 tx_ra_bitmap = 0, tmp64=0;
2097
2098 if (psta == NULL)
2099 return;
2100
2101 /* b/g mode ra_bitmap */
2102 for (i = 0; i < sizeof(psta->bssrateset); i++) {
2103 if (psta->bssrateset[i])
2104 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
2105 }
2106
2107 #ifdef CONFIG_80211N_HT
2108 if (padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
2109 tx_nss = GET_HAL_TX_NSS(padapter);
2110 #ifdef CONFIG_80211AC_VHT
2111 if (psta->vhtpriv.vht_option) {
2112 /* AC mode ra_bitmap */
2113 tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
2114 } else
2115 #endif /* CONFIG_80211AC_VHT */
2116 if (psta->htpriv.ht_option) {
2117 /* n mode ra_bitmap */
2118
2119 /* Handling SMPS mode for AP MODE only*/
2120 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2121 /*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
2122 if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
2123 /*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
2124 tx_nss = rtw_min(tx_nss, 1);
2125 }
2126 }
2127
2128 tmp64 = rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss);
2129 tx_ra_bitmap |= (tmp64 << 12);
2130 }
2131 }
2132 #endif /* CONFIG_80211N_HT */
2133 psta->cmn.ra_info.ramask = tx_ra_bitmap;
2134 psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
2135 }
2136
rtw_hal_update_sta_ra_info(PADAPTER padapter,struct sta_info * psta)2137 void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
2138 {
2139 rtw_hal_update_sta_mimo_type(padapter, psta);
2140 rtw_hal_update_sta_smps_cap(padapter, psta);
2141 rtw_hal_update_sta_rate_mask(padapter, psta);
2142 }
2143
2144 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
hw_bcn_ctrl_addr(_adapter * adapter,u8 hw_port)2145 static u32 hw_bcn_ctrl_addr(_adapter *adapter, u8 hw_port)
2146 {
2147 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2148
2149 if (hw_port >= hal_spec->port_num) {
2150 RTW_ERR(FUNC_ADPT_FMT" HW Port(%d) invalid\n", FUNC_ADPT_ARG(adapter), hw_port);
2151 rtw_warn_on(1);
2152 return 0;
2153 }
2154
2155 switch (hw_port) {
2156 case HW_PORT0:
2157 return REG_BCN_CTRL;
2158 case HW_PORT1:
2159 return REG_BCN_CTRL_1;
2160 }
2161
2162 return 0;
2163 }
2164 #endif
2165
rtw_hal_get_msr(_adapter * adapter,u8 * net_type)2166 static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2167 {
2168 #ifdef RTW_HALMAC
2169 rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
2170 adapter->hw_port, net_type);
2171 #else /* !RTW_HALMAC */
2172 switch (adapter->hw_port) {
2173 case HW_PORT0:
2174 /*REG_CR - BIT[17:16]-Network Type for port 1*/
2175 *net_type = rtw_read8(adapter, MSR) & 0x03;
2176 break;
2177 case HW_PORT1:
2178 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2179 *net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2180 break;
2181 #if defined(CONFIG_RTL8814A)
2182 case HW_PORT2:
2183 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2184 *net_type = rtw_read8(adapter, MSR1) & 0x03;
2185 break;
2186 case HW_PORT3:
2187 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2188 *net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2189 break;
2190 case HW_PORT4:
2191 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2192 *net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2193 break;
2194 #endif /*#if defined(CONFIG_RTL8814A)*/
2195 default:
2196 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2197 ADPT_ARG(adapter), adapter->hw_port);
2198 rtw_warn_on(1);
2199 break;
2200 }
2201 #endif /* !RTW_HALMAC */
2202 }
2203
2204 #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)2205 static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
2206 {
2207 if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
2208 if (net_type != _HW_STATE_NOLINK_)
2209 return _HW_STATE_AP_;
2210 }
2211 return net_type;
2212 }
2213 #endif
rtw_hal_set_msr(_adapter * adapter,u8 net_type)2214 static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2215 {
2216 #ifdef RTW_HALMAC
2217 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2218 net_type = rtw_hal_net_type_decision(adapter, net_type);
2219 #endif
2220 rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
2221 adapter->hw_port, net_type);
2222 #else /* !RTW_HALMAC */
2223 u8 val8 = 0;
2224
2225 switch (adapter->hw_port) {
2226 case HW_PORT0:
2227 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2228 net_type = rtw_hal_net_type_decision(adapter, net_type);
2229 #endif
2230 /*REG_CR - BIT[17:16]-Network Type for port 0*/
2231 val8 = rtw_read8(adapter, MSR) & 0x0C;
2232 val8 |= net_type;
2233 rtw_write8(adapter, MSR, val8);
2234 break;
2235 case HW_PORT1:
2236 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2237 val8 = rtw_read8(adapter, MSR) & 0x03;
2238 val8 |= net_type << 2;
2239 rtw_write8(adapter, MSR, val8);
2240 break;
2241 #if defined(CONFIG_RTL8814A)
2242 case HW_PORT2:
2243 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2244 val8 = rtw_read8(adapter, MSR1) & 0xFC;
2245 val8 |= net_type;
2246 rtw_write8(adapter, MSR1, val8);
2247 break;
2248 case HW_PORT3:
2249 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2250 val8 = rtw_read8(adapter, MSR1) & 0xF3;
2251 val8 |= net_type << 2;
2252 rtw_write8(adapter, MSR1, val8);
2253 break;
2254 case HW_PORT4:
2255 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2256 val8 = rtw_read8(adapter, MSR1) & 0xCF;
2257 val8 |= net_type << 4;
2258 rtw_write8(adapter, MSR1, val8);
2259 break;
2260 #endif /* CONFIG_RTL8814A */
2261 default:
2262 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2263 ADPT_ARG(adapter), adapter->hw_port);
2264 rtw_warn_on(1);
2265 break;
2266 }
2267 #endif /* !RTW_HALMAC */
2268 }
2269
2270 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
2271 #define SEC_CAM_ACCESS_TIMEOUT_MS 200
2272 #endif
2273
2274 #ifndef DBG_SEC_CAM_ACCESS
2275 #define DBG_SEC_CAM_ACCESS 0
2276 #endif
2277
rtw_sec_read_cam(_adapter * adapter,u8 addr)2278 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
2279 {
2280 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2281 u32 rdata;
2282 u32 cnt = 0;
2283 systime start = 0, end = 0;
2284 u8 timeout = 0;
2285 u8 sr = 0;
2286
2287 _enter_critical_mutex(mutex, NULL);
2288
2289 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
2290
2291 start = rtw_get_current_time();
2292 while (1) {
2293 if (rtw_is_surprise_removed(adapter)) {
2294 sr = 1;
2295 break;
2296 }
2297
2298 cnt++;
2299 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2300 break;
2301
2302 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2303 timeout = 1;
2304 break;
2305 }
2306 }
2307 end = rtw_get_current_time();
2308
2309 rdata = rtw_read32(adapter, REG_CAMREAD);
2310
2311 _exit_critical_mutex(mutex, NULL);
2312
2313 if (DBG_SEC_CAM_ACCESS || timeout) {
2314 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
2315 , FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2316 }
2317
2318 return rdata;
2319 }
2320
rtw_sec_write_cam(_adapter * adapter,u8 addr,u32 wdata)2321 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
2322 {
2323 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2324 u32 cnt = 0;
2325 systime start = 0, end = 0;
2326 u8 timeout = 0;
2327 u8 sr = 0;
2328
2329 _enter_critical_mutex(mutex, NULL);
2330
2331 rtw_write32(adapter, REG_CAMWRITE, wdata);
2332 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
2333
2334 start = rtw_get_current_time();
2335 while (1) {
2336 if (rtw_is_surprise_removed(adapter)) {
2337 sr = 1;
2338 break;
2339 }
2340
2341 cnt++;
2342 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2343 break;
2344
2345 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2346 timeout = 1;
2347 break;
2348 }
2349 }
2350 end = rtw_get_current_time();
2351
2352 _exit_critical_mutex(mutex, NULL);
2353
2354 if (DBG_SEC_CAM_ACCESS || timeout) {
2355 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
2356 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2357 }
2358 }
2359
rtw_sec_read_cam_ent(_adapter * adapter,u8 id,u8 * ctrl,u8 * mac,u8 * key)2360 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
2361 {
2362 u8 i;
2363 u32 rdata;
2364 u8 begin = 0;
2365 u8 end = 5; /* TODO: consider other key length accordingly */
2366
2367 if (!ctrl && !mac && !key) {
2368 rtw_warn_on(1);
2369 goto exit;
2370 }
2371
2372 /* TODO: check id range */
2373
2374 if (!ctrl && !mac)
2375 begin = 2; /* read from key */
2376
2377 if (!key && !mac)
2378 end = 0; /* read to ctrl */
2379 else if (!key)
2380 end = 2; /* read to mac */
2381
2382 for (i = begin; i <= end; i++) {
2383 rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
2384
2385 switch (i) {
2386 case 0:
2387 if (ctrl)
2388 _rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
2389 if (mac)
2390 _rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
2391 break;
2392 case 1:
2393 if (mac)
2394 _rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
2395 break;
2396 default:
2397 if (key)
2398 _rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
2399 break;
2400 }
2401 }
2402
2403 exit:
2404 return;
2405 }
2406
2407
rtw_sec_write_cam_ent(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)2408 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
2409 {
2410 unsigned int i;
2411 int j;
2412 u8 addr, addr1 = 0;
2413 u32 wdata, wdata1 = 0;
2414
2415 /* TODO: consider other key length accordingly */
2416 #if 0
2417 switch ((ctrl & 0x1c) >> 2) {
2418 case _WEP40_:
2419 case _TKIP_:
2420 case _AES_:
2421 case _WEP104_:
2422
2423 }
2424 #else
2425 j = 7;
2426 #endif
2427
2428 for (; j >= 0; j--) {
2429 switch (j) {
2430 case 0:
2431 wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
2432 break;
2433 case 1:
2434 wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
2435 break;
2436 case 6:
2437 case 7:
2438 wdata = 0;
2439 break;
2440 default:
2441 i = (j - 2) << 2;
2442 wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
2443 break;
2444 }
2445
2446 addr = (id << 3) + j;
2447
2448 #if defined(CONFIG_RTL8192F)
2449 if(j == 1) {
2450 wdata1 = wdata;
2451 addr1 = addr;
2452 continue;
2453 }
2454 #endif
2455
2456 rtw_sec_write_cam(adapter, addr, wdata);
2457 }
2458
2459 #if defined(CONFIG_RTL8192F)
2460 rtw_sec_write_cam(adapter, addr1, wdata1);
2461 #endif
2462 }
2463
rtw_sec_clr_cam_ent(_adapter * adapter,u8 id)2464 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
2465 {
2466 u8 addr;
2467
2468 addr = (id << 3);
2469 rtw_sec_write_cam(adapter, addr, 0);
2470 }
2471
rtw_sec_read_cam_is_gk(_adapter * adapter,u8 id)2472 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
2473 {
2474 bool res;
2475 u16 ctrl;
2476
2477 rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
2478
2479 res = (ctrl & BIT6) ? _TRUE : _FALSE;
2480 return res;
2481 }
2482 #ifdef CONFIG_MBSSID_CAM
rtw_mbid_cam_init(struct dvobj_priv * dvobj)2483 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
2484 {
2485 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2486
2487 _rtw_spinlock_init(&mbid_cam_ctl->lock);
2488 mbid_cam_ctl->bitmap = 0;
2489 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2490 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2491 }
2492
rtw_mbid_cam_deinit(struct dvobj_priv * dvobj)2493 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
2494 {
2495 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2496
2497 _rtw_spinlock_free(&mbid_cam_ctl->lock);
2498 }
2499
rtw_mbid_cam_reset(_adapter * adapter)2500 void rtw_mbid_cam_reset(_adapter *adapter)
2501 {
2502 _irqL irqL;
2503 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2504 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2505
2506 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2507 mbid_cam_ctl->bitmap = 0;
2508 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2509 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2510
2511 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2512 }
_rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2513 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2514 {
2515 u8 i;
2516 u8 cam_id = INVALID_CAM_ID;
2517 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2518
2519 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2520 if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
2521 cam_id = i;
2522 break;
2523 }
2524 }
2525
2526 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2527 return cam_id;
2528 }
2529
rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2530 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2531 {
2532 _irqL irqL;
2533
2534 u8 cam_id = INVALID_CAM_ID;
2535 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2536 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2537
2538 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2539 cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
2540 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2541
2542 return cam_id;
2543 }
_rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2544 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2545 {
2546 u8 i;
2547 u8 cam_id = INVALID_CAM_ID;
2548 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2549
2550 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2551 if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
2552 cam_id = i;
2553 break;
2554 }
2555 }
2556 if (cam_id != INVALID_CAM_ID)
2557 RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
2558 __func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
2559
2560 return cam_id;
2561 }
2562
rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2563 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2564 {
2565 _irqL irqL;
2566 u8 cam_id = INVALID_CAM_ID;
2567 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2568 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2569
2570 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2571 cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
2572 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2573
2574 return cam_id;
2575 }
rtw_get_max_mbid_cam_id(_adapter * adapter)2576 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
2577 {
2578 _irqL irqL;
2579 s8 i;
2580 u8 cam_id = INVALID_CAM_ID;
2581 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2582 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2583
2584 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2585 for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
2586 if (mbid_cam_ctl->bitmap & BIT(i)) {
2587 cam_id = i;
2588 break;
2589 }
2590 }
2591 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2592 /*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
2593 return cam_id;
2594 }
2595
rtw_get_mbid_cam_entry_num(_adapter * adapter)2596 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
2597 {
2598 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2599 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2600
2601 return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2602 }
2603
mbid_cam_cache_init(_adapter * adapter,struct mbid_cam_cache * pmbid_cam,u8 * mac_addr)2604 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
2605 {
2606 if (adapter && pmbid_cam && mac_addr) {
2607 _rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
2608 pmbid_cam->iface_id = adapter->iface_id;
2609 }
2610 }
mbid_cam_cache_clr(struct mbid_cam_cache * pmbid_cam)2611 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
2612 {
2613 if (pmbid_cam) {
2614 _rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
2615 pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
2616 }
2617 }
2618
rtw_mbid_camid_alloc(_adapter * adapter,u8 * mac_addr)2619 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
2620 {
2621 _irqL irqL;
2622 u8 cam_id = INVALID_CAM_ID, i;
2623 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2624 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2625 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2626
2627 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2628 goto exit;
2629
2630 if (entry_num >= TOTAL_MBID_CAM_NUM) {
2631 RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
2632 rtw_warn_on(1);
2633 }
2634
2635 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2636 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2637 if (!(mbid_cam_ctl->bitmap & BIT(i))) {
2638 mbid_cam_ctl->bitmap |= BIT(i);
2639 cam_id = i;
2640 break;
2641 }
2642 }
2643 if ((cam_id != INVALID_CAM_ID) && (mac_addr))
2644 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
2645 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2646
2647 if (cam_id != INVALID_CAM_ID) {
2648 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2649 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2650 #ifdef DBG_MBID_CAM_DUMP
2651 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2652 #endif
2653 } else
2654 RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2655 exit:
2656 return cam_id;
2657 }
2658
rtw_mbid_cam_info_change(_adapter * adapter,u8 * mac_addr)2659 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
2660 {
2661 _irqL irqL;
2662 u8 entry_id = INVALID_CAM_ID;
2663 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2664 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2665
2666 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2667 entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
2668 if (entry_id != INVALID_CAM_ID)
2669 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
2670
2671 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2672
2673 return entry_id;
2674 }
2675
rtw_mbid_cam_assign(_adapter * adapter,u8 * mac_addr,u8 camid)2676 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
2677 {
2678 _irqL irqL;
2679 u8 ret = _FALSE;
2680 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2681 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2682
2683 if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
2684 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
2685 rtw_warn_on(1);
2686 }
2687 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2688 goto exit;
2689
2690 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2691 if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
2692 if (mac_addr) {
2693 mbid_cam_ctl->bitmap |= BIT(camid);
2694 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
2695 ret = _TRUE;
2696 }
2697 }
2698 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2699
2700 if (ret == _TRUE) {
2701 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2702 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
2703 #ifdef DBG_MBID_CAM_DUMP
2704 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2705 #endif
2706 } else
2707 RTW_INFO("%s [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
2708
2709 exit:
2710 return ret;
2711 }
2712
rtw_mbid_camid_clean(_adapter * adapter,u8 mbss_canid)2713 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
2714 {
2715 _irqL irqL;
2716 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2717 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2718
2719 if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
2720 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
2721 rtw_warn_on(1);
2722 }
2723 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2724 mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
2725 mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
2726 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2727 ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
2728 RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
2729 }
rtw_mbid_cam_cache_dump(void * sel,const char * fun_name,_adapter * adapter)2730 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
2731 {
2732 _irqL irqL;
2733 u8 i;
2734 _adapter *iface;
2735 u8 iface_id;
2736 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2737 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2738 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2739 u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2740
2741 RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
2742
2743 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2744 RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
2745 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2746 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2747
2748 if (mbid_cam_ctl->bitmap & BIT(i)) {
2749 iface_id = dvobj->mbid_cam_cache[i].iface_id;
2750 _RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
2751 _RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2752
2753 iface = dvobj->padapters[iface_id];
2754 if (iface) {
2755 if (MLME_IS_STA(iface))
2756 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
2757 else if (MLME_IS_AP(iface))
2758 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
2759 else if (MLME_IS_MESH(iface))
2760 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");
2761 else
2762 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2763 }
2764
2765 } else
2766 _RTW_PRINT_SEL(sel, "N/A\n");
2767 }
2768 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2769 return 0;
2770 }
2771
read_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2772 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2773 {
2774 u8 poll = 1;
2775 u8 cam_ready = _FALSE;
2776 u32 cam_data1 = 0;
2777 u16 cam_data2 = 0;
2778
2779 if (RTW_CANNOT_RUN(padapter))
2780 return;
2781
2782 rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2783
2784 do {
2785 if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2786 cam_ready = _TRUE;
2787 break;
2788 }
2789 poll++;
2790 } while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2791
2792 if (cam_ready) {
2793 cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2794 mac[0] = cam_data1 & 0xFF;
2795 mac[1] = (cam_data1 >> 8) & 0xFF;
2796 mac[2] = (cam_data1 >> 16) & 0xFF;
2797 mac[3] = (cam_data1 >> 24) & 0xFF;
2798
2799 cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
2800 mac[4] = cam_data2 & 0xFF;
2801 mac[5] = (cam_data2 >> 8) & 0xFF;
2802 }
2803
2804 }
rtw_mbid_cam_dump(void * sel,const char * fun_name,_adapter * adapter)2805 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
2806 {
2807 /*_irqL irqL;*/
2808 u8 i;
2809 u8 mac_addr[ETH_ALEN];
2810
2811 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2812 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2813
2814 RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
2815
2816 /*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2817 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2818 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2819 _rtw_memset(mac_addr, 0, ETH_ALEN);
2820 read_mbssid_cam(adapter, i, mac_addr);
2821 _RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
2822 }
2823 /*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2824 return 0;
2825 }
2826
write_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2827 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2828 {
2829 u32 cam_val[2] = {0};
2830
2831 cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
2832 cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT) | (mac[5] << 8) | mac[4];
2833
2834 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
2835 }
2836
2837 /*
2838 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
2839 {
2840 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
2841 }
2842 */
2843
rtw_ap_set_mbid_num(_adapter * adapter,u8 ap_num)2844 void rtw_ap_set_mbid_num(_adapter *adapter, u8 ap_num)
2845 {
2846 rtw_write8(adapter, REG_MBID_NUM,
2847 ((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | ((ap_num -1) & 0x07)));
2848
2849 }
rtw_mbid_cam_enable(_adapter * adapter)2850 void rtw_mbid_cam_enable(_adapter *adapter)
2851 {
2852 /*enable MBSSID*/
2853 rtw_hal_rcr_add(adapter, RCR_ENMBID);
2854 }
rtw_mi_set_mbid_cam(_adapter * adapter)2855 void rtw_mi_set_mbid_cam(_adapter *adapter)
2856 {
2857 u8 i;
2858 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2859 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2860
2861 #ifdef DBG_MBID_CAM_DUMP
2862 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2863 #endif
2864
2865 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2866 if (mbid_cam_ctl->bitmap & BIT(i)) {
2867 write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
2868 RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2869 }
2870 }
2871 rtw_mbid_cam_enable(adapter);
2872 }
2873 #endif /*CONFIG_MBSSID_CAM*/
2874
2875 #ifdef CONFIG_FW_HANDLE_TXBCN
2876 #define H2C_BCN_OFFLOAD_LEN 1
2877
2878 #define SET_H2CCMD_BCN_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
2879 #define SET_H2CCMD_BCN_ROOT_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
2880 #define SET_H2CCMD_BCN_VAP1_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)
2881 #define SET_H2CCMD_BCN_VAP2_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)
2882 #define SET_H2CCMD_BCN_VAP3_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value)
2883 #define SET_H2CCMD_BCN_VAP4_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value)
2884
rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter * adapter,bool fw_bcn_en,u8 tbtt_rpt_map)2885 void rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter *adapter, bool fw_bcn_en, u8 tbtt_rpt_map)
2886 {
2887 u8 fw_bcn_offload[1] = {0};
2888 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2889
2890 if (fw_bcn_en)
2891 SET_H2CCMD_BCN_OFFLOAD_EN(fw_bcn_offload, 1);
2892
2893 if (tbtt_rpt_map & BIT(0))
2894 SET_H2CCMD_BCN_ROOT_TBTT_RPT(fw_bcn_offload, 1);
2895 if (tbtt_rpt_map & BIT(1))
2896 SET_H2CCMD_BCN_VAP1_TBTT_RPT(fw_bcn_offload, 1);
2897 if (tbtt_rpt_map & BIT(2))
2898 SET_H2CCMD_BCN_VAP2_TBTT_RPT(fw_bcn_offload, 1);
2899 if (tbtt_rpt_map & BIT(3))
2900 SET_H2CCMD_BCN_VAP3_TBTT_RPT(fw_bcn_offload, 1);
2901
2902 dvobj->vap_tbtt_rpt_map = tbtt_rpt_map;
2903 dvobj->fw_bcn_offload = fw_bcn_en;
2904 RTW_INFO("[FW BCN] Offload : %s\n", (dvobj->fw_bcn_offload) ? "EN" : "DIS");
2905 RTW_INFO("[FW BCN] TBTT RPT map : 0x%02x\n", dvobj->vap_tbtt_rpt_map);
2906
2907 rtw_hal_fill_h2c_cmd(adapter, H2C_FW_BCN_OFFLOAD,
2908 H2C_BCN_OFFLOAD_LEN, fw_bcn_offload);
2909 }
2910
rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter * adapter)2911 void rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter *adapter)
2912 {
2913 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2914 u8 ret, vap_id;
2915 u32 page_size = 0;
2916 u8 bcn_rsvdpage[H2C_BCN_RSVDPAGE_LEN] = {0};
2917
2918 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
2919 #if 1
2920 for (vap_id = 0; vap_id < CONFIG_LIMITED_AP_NUM; vap_id++) {
2921 if (dvobj->vap_map & BIT(vap_id))
2922 bcn_rsvdpage[vap_id] = vap_id * (MAX_BEACON_LEN / page_size);
2923 }
2924 #else
2925 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)
2926 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 8, __Value)
2927 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 8, __Value)
2928 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 8, __Value)
2929 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 8, __Value)
2930
2931 if (dvobj->vap_map & BIT(0))
2932 SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(bcn_rsvdpage, 0);
2933 if (dvobj->vap_map & BIT(1))
2934 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(bcn_rsvdpage,
2935 1 * (MAX_BEACON_LEN / page_size));
2936 if (dvobj->vap_map & BIT(2))
2937 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(bcn_rsvdpage,
2938 2 * (MAX_BEACON_LEN / page_size));
2939 if (dvobj->vap_map & BIT(3))
2940 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(bcn_rsvdpage,
2941 3 * (MAX_BEACON_LEN / page_size));
2942 if (dvobj->vap_map & BIT(4))
2943 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(bcn_rsvdpage,
2944 4 * (MAX_BEACON_LEN / page_size));
2945 #endif
2946 if (1) {
2947 RTW_INFO("[BCN_LOC] vap_map : 0x%02x\n", dvobj->vap_map);
2948 RTW_INFO("[BCN_LOC] page_size :%d, @bcn_page_num :%d\n"
2949 , page_size, (MAX_BEACON_LEN / page_size));
2950 RTW_INFO("[BCN_LOC] root ap : 0x%02x\n", *bcn_rsvdpage);
2951 RTW_INFO("[BCN_LOC] vap_1 : 0x%02x\n", *(bcn_rsvdpage + 1));
2952 RTW_INFO("[BCN_LOC] vap_2 : 0x%02x\n", *(bcn_rsvdpage + 2));
2953 RTW_INFO("[BCN_LOC] vap_3 : 0x%02x\n", *(bcn_rsvdpage + 3));
2954 RTW_INFO("[BCN_LOC] vap_4 : 0x%02x\n", *(bcn_rsvdpage + 4));
2955 }
2956 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE,
2957 H2C_BCN_RSVDPAGE_LEN, bcn_rsvdpage);
2958 }
2959
rtw_ap_multi_bcn_cfg(_adapter * adapter)2960 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
2961 {
2962 u8 dft_bcn_space = DEFAULT_BCN_INTERVAL;
2963 u8 sub_bcn_space = (DEFAULT_BCN_INTERVAL / CONFIG_LIMITED_AP_NUM);
2964
2965 /*enable to rx data frame*/
2966 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
2967
2968 /*Disable Port0's beacon function*/
2969 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
2970 /*Reset Port0's TSF*/
2971 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT_TSFTR_RST);
2972
2973 rtw_ap_set_mbid_num(adapter, CONFIG_LIMITED_AP_NUM);
2974
2975 /*BCN space & BCN sub-space 0x554[15:0] = 0x64,0x5BC[23:16] = 0x21*/
2976 rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), HW_PORT0, dft_bcn_space);
2977 rtw_write8(adapter, REG_MBSSID_BCN_SPACE3 + 2, sub_bcn_space);
2978
2979 #if 0 /*setting in hw_var_set_opmode_mbid - ResumeTxBeacon*/
2980 /*BCN hold time 0x540[19:8] = 0x80*/
2981 rtw_write8(adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
2982 rtw_write8(adapter, REG_TBTT_PROHIBIT + 2,
2983 (rtw_read8(adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
2984 #endif
2985
2986 /*ATIM window -0x55A = 0x32, reg 0x570 = 0x32, reg 0x5A0 = 0x32 */
2987 rtw_write8(adapter, REG_ATIMWND, 0x32);
2988 rtw_write8(adapter, REG_ATIMWND1_V1, 0x32);
2989 rtw_write8(adapter, REG_ATIMWND2, 0x32);
2990 rtw_write8(adapter, REG_ATIMWND3, 0x32);
2991 /*
2992 rtw_write8(adapter, REG_ATIMWND4, 0x32);
2993 rtw_write8(adapter, REG_ATIMWND5, 0x32);
2994 rtw_write8(adapter, REG_ATIMWND6, 0x32);
2995 rtw_write8(adapter, REG_ATIMWND7, 0x32);*/
2996
2997 /*no limit setting - 0x5A7 = 0xFF - Packet in Hi Queue Tx immediately*/
2998 rtw_write8(adapter, REG_HIQ_NO_LMT_EN, 0xFF);
2999
3000 /*Mask all beacon*/
3001 rtw_write8(adapter, REG_MBSSID_CTRL, 0);
3002
3003 /*BCN invalid bit setting 0x454[6] = 1*/
3004 /*rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);*/
3005
3006 /*Enable Port0's beacon function*/
3007 rtw_write8(adapter, REG_BCN_CTRL,
3008 rtw_read8(adapter, REG_BCN_CTRL) | BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION);
3009
3010 /* Enable HW seq for BCN
3011 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
3012 #ifdef CONFIG_RTL8822B
3013 if (IS_HARDWARE_TYPE_8822B(adapter))
3014 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3015 #endif
3016
3017 #ifdef CONFIG_RTL8822C
3018 if (IS_HARDWARE_TYPE_8822C(adapter))
3019 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3020 #endif
3021 }
_rtw_mbid_bcn_cfg(_adapter * adapter,bool mbcnq_en,u8 mbcnq_id)3022 static void _rtw_mbid_bcn_cfg(_adapter *adapter, bool mbcnq_en, u8 mbcnq_id)
3023 {
3024 if (mbcnq_id >= CONFIG_LIMITED_AP_NUM) {
3025 RTW_ERR(FUNC_ADPT_FMT"- mbid bcnq_id(%d) invalid\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3026 rtw_warn_on(1);
3027 }
3028
3029 if (mbcnq_en) {
3030 rtw_write8(adapter, REG_MBSSID_CTRL,
3031 rtw_read8(adapter, REG_MBSSID_CTRL) | BIT(mbcnq_id));
3032 RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) enabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3033 } else {
3034 rtw_write8(adapter, REG_MBSSID_CTRL,
3035 rtw_read8(adapter, REG_MBSSID_CTRL) & (~BIT(mbcnq_id)));
3036 RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) disabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3037 }
3038 }
3039 /*#define CONFIG_FW_TBTT_RPT*/
rtw_ap_mbid_bcn_en(_adapter * adapter,u8 ap_id)3040 void rtw_ap_mbid_bcn_en(_adapter *adapter, u8 ap_id)
3041 {
3042 RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3043
3044 #ifdef CONFIG_FW_TBTT_RPT
3045 if (rtw_ap_get_nums(adapter) >= 1) {
3046 u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3047
3048 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3049 tbtt_rpt_map | BIT(ap_id));/*H2C-0xBA*/
3050 }
3051 #else
3052 if (rtw_ap_get_nums(adapter) == 1)
3053 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE, 0);/*H2C-0xBA*/
3054 #endif
3055
3056 rtw_hal_set_bcn_rsvdpage_loc_cmd(adapter);/*H2C-0x09*/
3057
3058 _rtw_mbid_bcn_cfg(adapter, _TRUE, ap_id);
3059 }
rtw_ap_mbid_bcn_dis(_adapter * adapter,u8 ap_id)3060 void rtw_ap_mbid_bcn_dis(_adapter *adapter, u8 ap_id)
3061 {
3062 RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3063 _rtw_mbid_bcn_cfg(adapter, _FALSE, ap_id);
3064
3065 if (rtw_ap_get_nums(adapter) == 0)
3066 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _FALSE, 0);
3067 #ifdef CONFIG_FW_TBTT_RPT
3068 else if (rtw_ap_get_nums(adapter) >= 1) {
3069 u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3070
3071 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3072 tbtt_rpt_map & ~BIT(ap_id));/*H2C-0xBA*/
3073 }
3074 #endif
3075 }
3076 #endif
3077 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_ap_multi_bcn_cfg(_adapter * adapter)3078 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3079 {
3080 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3081 rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT);
3082 #else
3083 rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
3084 #endif
3085 /*enable to rx data frame*/
3086 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3087
3088 /*Beacon Control related register for first time*/
3089 rtw_write8(adapter, REG_BCNDMATIM, 0x02); /* 2ms */
3090
3091 /*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
3092 rtw_write8(adapter, REG_ATIMWND, 0x0c); /* 12ms */
3093
3094 #ifndef CONFIG_HW_P0_TSF_SYNC
3095 #ifdef CONFIG_RTL8192F
3096 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x640);/*unit:32us*/
3097 #else/*not CONFIG_RTL8192F*/
3098 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3099 #endif
3100 #endif
3101
3102 /*reset TSF*/
3103 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
3104
3105 /*enable BCN0 Function for if1*/
3106 /*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
3107 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3108 rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);
3109 #else
3110 rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3111 #endif
3112 #ifdef CONFIG_BCN_XMIT_PROTECT
3113 rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
3114 #endif
3115
3116 if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/
3117 rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
3118
3119 /* Enable HW seq for BCN
3120 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
3121 #ifdef CONFIG_RTL8822B
3122 if (IS_HARDWARE_TYPE_8822B(adapter))
3123 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3124 #endif
3125
3126 #ifdef CONFIG_RTL8822C
3127 if (IS_HARDWARE_TYPE_8822C(adapter))
3128 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3129 #endif
3130 }
3131 #endif
3132
3133 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3134 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3135 {
3136
3137 #if 0 /*TODO - modify for more flexible*/
3138 u8 idx = 0;
3139
3140 if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
3141 (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
3142 for (idx = 0; idx < 6; idx++)
3143 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
3144 } else {
3145 /*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
3146 u8 entry_id;
3147
3148 if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
3149 (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
3150 entry_id = 0;
3151 if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
3152 RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
3153 write_mbssid_cam(adapter, entry_id, val);
3154 }
3155 } else {
3156 entry_id = rtw_mbid_camid_alloc(adapter, val);
3157 if (entry_id != INVALID_CAM_ID)
3158 write_mbssid_cam(adapter, entry_id, val);
3159 }
3160 }
3161 #else
3162 {
3163 /*
3164 MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
3165 */
3166 u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
3167
3168
3169 if (entry_id != INVALID_CAM_ID) {
3170 write_mbssid_cam(adapter, entry_id, mac_addr);
3171 RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,
3172 ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));
3173 }
3174 }
3175 #endif
3176 }
3177
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3178 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3179 {
3180 u8 idx = 0;
3181 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3182 u8 entry_id;
3183
3184 if (!mac_addr) {
3185 rtw_warn_on(1);
3186 return;
3187 }
3188
3189
3190 entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
3191
3192 if (entry_id != INVALID_CAM_ID)
3193 write_mbssid_cam(adapter, entry_id, mac_addr);
3194 }
3195
3196 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_hal_bcn_interval_adjust(_adapter * adapter,u16 bcn_interval)3197 u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
3198 {
3199 if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
3200 return adapter_to_dvobj(adapter)->inter_bcn_space;
3201 else
3202 return bcn_interval;
3203 }
3204 #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
3205
3206 #else
3207
3208 #ifndef RTW_HALMAC
_get_macaddr_reg(enum _hw_port hwport)3209 static u32 _get_macaddr_reg(enum _hw_port hwport)
3210 {
3211 u32 reg_macaddr = REG_MACID;
3212
3213 #ifdef CONFIG_CONCURRENT_MODE
3214 if (hwport == HW_PORT1)
3215 reg_macaddr = REG_MACID1;
3216 #if defined(CONFIG_RTL8814A)
3217 else if (hwport == HW_PORT2)
3218 reg_macaddr = REG_MACID2;
3219 else if (hwport == HW_PORT3)
3220 reg_macaddr = REG_MACID3;
3221 else if (hwport == HW_PORT4)
3222 reg_macaddr = REG_MACID4;
3223 #endif /*CONFIG_RTL8814A*/
3224 #endif /*CONFIG_CONCURRENT_MODE*/
3225
3226 return reg_macaddr;
3227 }
3228 #endif /*!RTW_HALMAC*/
3229
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * mac_addr)3230 static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr)
3231 {
3232 enum _hw_port hwport;
3233
3234 if (mac_addr == NULL)
3235 return;
3236 hwport = get_hw_port(adapter);
3237
3238 RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3239 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3240
3241 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3242 rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3243 #else /* !RTW_HALMAC */
3244 {
3245 u8 idx = 0;
3246 u32 reg_macaddr = _get_macaddr_reg(hwport);
3247
3248 for (idx = 0; idx < ETH_ALEN; idx++)
3249 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx), mac_addr[idx]);
3250 }
3251 #endif /* !RTW_HALMAC */
3252 }
3253
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)3254 static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
3255 {
3256 enum _hw_port hwport;
3257
3258 if (mac_addr == NULL)
3259 return;
3260 hwport = get_hw_port(adapter);
3261
3262 _rtw_memset(mac_addr, 0, ETH_ALEN);
3263 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3264 rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3265 #else /* !RTW_HALMAC */
3266 {
3267 u8 idx = 0;
3268 u32 reg_macaddr = _get_macaddr_reg(hwport);
3269
3270 for (idx = 0; idx < ETH_ALEN; idx++)
3271 mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx));
3272 }
3273 #endif /* !RTW_HALMAC */
3274
3275 RTW_DBG("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3276 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3277 }
3278 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
3279
3280 #ifndef RTW_HALMAC
_get_bssid_reg(enum _hw_port hw_port)3281 static u32 _get_bssid_reg(enum _hw_port hw_port)
3282 {
3283 u32 reg_bssid = REG_BSSID;
3284
3285 #ifdef CONFIG_CONCURRENT_MODE
3286 if (hw_port == HW_PORT1)
3287 reg_bssid = REG_BSSID1;
3288 #if defined(CONFIG_RTL8814A)
3289 else if (hw_port == HW_PORT2)
3290 reg_bssid = REG_BSSID2;
3291 else if (hw_port == HW_PORT3)
3292 reg_bssid = REG_BSSID3;
3293 else if (hw_port == HW_PORT4)
3294 reg_bssid = REG_BSSID4;
3295 #endif /*CONFIG_RTL8814A*/
3296 #endif /*CONFIG_CONCURRENT_MODE*/
3297
3298 return reg_bssid;
3299 }
3300 #endif /*!RTW_HALMAC*/
rtw_hal_set_bssid(_adapter * adapter,u8 * val)3301 static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
3302 {
3303 enum _hw_port hw_port = rtw_hal_get_port(adapter);
3304 #ifdef RTW_HALMAC
3305
3306 rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);
3307 #else /* !RTW_HALMAC */
3308 u8 idx = 0;
3309 u32 reg_bssid = _get_bssid_reg(hw_port);
3310
3311 for (idx = 0 ; idx < ETH_ALEN; idx++)
3312 rtw_write8(adapter, (reg_bssid + idx), val[idx]);
3313 #endif /* !RTW_HALMAC */
3314
3315 RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",
3316 __func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));
3317 }
3318
3319 #ifndef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_tsf_update(_adapter * adapter,u8 en)3320 static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)
3321 {
3322 u32 addr = 0;
3323 u8 val8;
3324
3325 rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);
3326 if (addr) {
3327 rtw_enter_protsel_port(adapter, get_hw_port(adapter));
3328 val8 = rtw_read8(adapter, addr);
3329 if (en && (val8 & DIS_TSF_UDT)) {
3330 rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);
3331 #ifdef DBG_TSF_UPDATE
3332 RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3333 #endif
3334 }
3335 if (!en && !(val8 & DIS_TSF_UDT)) {
3336 rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);
3337 #ifdef DBG_TSF_UPDATE
3338 RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3339 #endif
3340 }
3341 rtw_leave_protsel_port(adapter);
3342 } else {
3343 RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"
3344 , adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");
3345 rtw_warn_on(1);
3346 }
3347 }
3348 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_set_hw_update_tsf(PADAPTER padapter)3349 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
3350 {
3351 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3352
3353 #else
3354 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3355
3356 if (!pmlmeext->en_hw_update_tsf)
3357 return;
3358
3359 /* check RCR */
3360 if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
3361 return;
3362
3363 if (pmlmeext->tsf_update_required) {
3364 pmlmeext->tsf_update_pause_stime = 0;
3365 rtw_hal_set_tsf_update(padapter, 1);
3366 }
3367
3368 pmlmeext->en_hw_update_tsf = 0;
3369 #endif
3370 }
3371
rtw_iface_enable_tsf_update(_adapter * adapter)3372 void rtw_iface_enable_tsf_update(_adapter *adapter)
3373 {
3374 adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3375 adapter->mlmeextpriv.tsf_update_required = 1;
3376 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3377
3378 #else
3379 rtw_hal_set_tsf_update(adapter, 1);
3380 #endif
3381 }
3382
rtw_iface_disable_tsf_update(_adapter * adapter)3383 void rtw_iface_disable_tsf_update(_adapter *adapter)
3384 {
3385 adapter->mlmeextpriv.tsf_update_required = 0;
3386 adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3387 adapter->mlmeextpriv.en_hw_update_tsf = 0;
3388 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3389
3390 #else
3391 rtw_hal_set_tsf_update(adapter, 0);
3392 #endif
3393 }
3394
rtw_hal_tsf_update_pause(_adapter * adapter)3395 static void rtw_hal_tsf_update_pause(_adapter *adapter)
3396 {
3397 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3398
3399 #else
3400 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3401 _adapter *iface;
3402 int i;
3403
3404 for (i = 0; i < dvobj->iface_nums; i++) {
3405 iface = dvobj->padapters[i];
3406 if (!iface)
3407 continue;
3408
3409 rtw_hal_set_tsf_update(iface, 0);
3410 if (iface->mlmeextpriv.tsf_update_required) {
3411 iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();
3412 if (!iface->mlmeextpriv.tsf_update_pause_stime)
3413 iface->mlmeextpriv.tsf_update_pause_stime++;
3414 }
3415 iface->mlmeextpriv.en_hw_update_tsf = 0;
3416 }
3417 #endif
3418 }
3419
rtw_hal_tsf_update_restore(_adapter * adapter)3420 static void rtw_hal_tsf_update_restore(_adapter *adapter)
3421 {
3422 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3423
3424 #else
3425 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3426 _adapter *iface;
3427 int i;
3428
3429 for (i = 0; i < dvobj->iface_nums; i++) {
3430 iface = dvobj->padapters[i];
3431 if (!iface)
3432 continue;
3433
3434 if (iface->mlmeextpriv.tsf_update_required) {
3435 /* enable HW TSF update when recive beacon*/
3436 iface->mlmeextpriv.en_hw_update_tsf = 1;
3437 #ifdef DBG_TSF_UPDATE
3438 RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"
3439 , iface->hw_port, ADPT_ARG(iface));
3440 #endif
3441 }
3442 }
3443 #endif
3444 }
3445
rtw_hal_periodic_tsf_update_chk(_adapter * adapter)3446 void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)
3447 {
3448 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3449
3450 #else
3451 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3452 _adapter *iface;
3453 struct mlme_ext_priv *mlmeext;
3454 int i;
3455 u32 restore_ms = 0;
3456
3457 if (dvobj->periodic_tsf_update_etime) {
3458 if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {
3459 /* end for restore status */
3460 dvobj->periodic_tsf_update_etime = 0;
3461 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3462 }
3463 return;
3464 }
3465
3466 if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)
3467 return;
3468
3469 /*
3470 * all required ifaces can switch to restore status together
3471 * loop all pause iface to get largest restore time required
3472 */
3473 for (i = 0; i < dvobj->iface_nums; i++) {
3474 iface = dvobj->padapters[i];
3475 if (!iface)
3476 continue;
3477
3478 mlmeext = &iface->mlmeextpriv;
3479
3480 if (mlmeext->tsf_update_required
3481 && mlmeext->tsf_update_pause_stime
3482 && rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)
3483 > mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor
3484 ) {
3485 if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)
3486 restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;
3487 }
3488 }
3489
3490 if (!restore_ms)
3491 return;
3492
3493 dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);
3494 if (!dvobj->periodic_tsf_update_etime)
3495 dvobj->periodic_tsf_update_etime++;
3496
3497 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3498
3499 /* set timer to end restore status */
3500 _set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);
3501 #endif
3502 }
3503
rtw_hal_periodic_tsf_update_end_timer_hdl(void * ctx)3504 void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)
3505 {
3506 struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;
3507
3508 if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
3509 return;
3510
3511 rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));
3512 }
3513
hw_var_rcr_config(_adapter * adapter,u32 rcr)3514 static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
3515 {
3516 int err;
3517
3518 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
3519 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;
3520 #endif
3521 err = rtw_write32(adapter, REG_RCR, rcr);
3522 if (err == _SUCCESS)
3523 GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
3524 return err;
3525 }
3526
hw_var_rcr_get(_adapter * adapter,u32 * rcr)3527 static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
3528 {
3529 u32 v32;
3530
3531 v32 = rtw_read32(adapter, REG_RCR);
3532 if (rcr)
3533 *rcr = v32;
3534 GET_HAL_DATA(adapter)->ReceiveConfig = v32;
3535 return _SUCCESS;
3536 }
3537
3538 /* only check SW RCR variable */
rtw_hal_rcr_check(_adapter * adapter,u32 check_bit)3539 inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
3540 {
3541 PHAL_DATA_TYPE hal;
3542 u32 rcr;
3543
3544 hal = GET_HAL_DATA(adapter);
3545
3546 rcr = hal->ReceiveConfig;
3547 if ((rcr & check_bit) == check_bit)
3548 return 1;
3549
3550 return 0;
3551 }
3552
rtw_hal_rcr_add(_adapter * adapter,u32 add)3553 inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
3554 {
3555 PHAL_DATA_TYPE hal;
3556 u32 rcr;
3557 u8 ret = _SUCCESS;
3558
3559 hal = GET_HAL_DATA(adapter);
3560
3561 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3562 rcr |= add;
3563 if (rcr != hal->ReceiveConfig)
3564 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3565
3566 return ret;
3567 }
3568
rtw_hal_rcr_clear(_adapter * adapter,u32 clear)3569 inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
3570 {
3571 PHAL_DATA_TYPE hal;
3572 u32 rcr;
3573 u8 ret = _SUCCESS;
3574
3575 hal = GET_HAL_DATA(adapter);
3576
3577 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3578 rcr &= ~clear;
3579 if (rcr != hal->ReceiveConfig)
3580 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3581
3582 return ret;
3583 }
3584
rtw_hal_rcr_set_chk_bssid(_adapter * adapter,u8 self_action)3585 void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
3586 {
3587 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3588 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3589 u32 rcr, rcr_new;
3590 #if !defined(CONFIG_MI_WITH_MBSSID_CAM) || defined(CONFIG_CLIENT_PORT_CFG) || defined(CONFIG_RTW_MULTI_AP)
3591 struct mi_state mstate, mstate_s;
3592 #endif
3593
3594 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3595 rcr_new = rcr;
3596
3597 #if !defined(CONFIG_MI_WITH_MBSSID_CAM) || defined(CONFIG_CLIENT_PORT_CFG) || defined(CONFIG_RTW_MULTI_AP)
3598 rtw_mi_status_no_self(adapter, &mstate);
3599 rtw_mi_status_no_others(adapter, &mstate_s);
3600
3601 /* only adjust parameters interested */
3602 switch (self_action) {
3603 case MLME_SCAN_ENTER:
3604 mstate_s.scan_num = 1;
3605 mstate_s.scan_enter_num = 1;
3606 break;
3607 case MLME_SCAN_DONE:
3608 mstate_s.scan_enter_num = 0;
3609 break;
3610 case MLME_STA_CONNECTING:
3611 mstate_s.lg_sta_num = 1;
3612 mstate_s.ld_sta_num = 0;
3613 break;
3614 case MLME_STA_CONNECTED:
3615 mstate_s.lg_sta_num = 0;
3616 mstate_s.ld_sta_num = 1;
3617 break;
3618 case MLME_STA_DISCONNECTED:
3619 mstate_s.lg_sta_num = 0;
3620 mstate_s.ld_sta_num = 0;
3621 break;
3622 #ifdef CONFIG_TDLS
3623 case MLME_TDLS_LINKED:
3624 mstate_s.ld_tdls_num = 1;
3625 break;
3626 case MLME_TDLS_NOLINK:
3627 mstate_s.ld_tdls_num = 0;
3628 break;
3629 #endif
3630 #ifdef CONFIG_AP_MODE
3631 case MLME_AP_STARTED:
3632 mstate_s.ap_num = 1;
3633 break;
3634 case MLME_AP_STOPPED:
3635 mstate_s.ap_num = 0;
3636 mstate_s.ld_ap_num = 0;
3637 break;
3638 #endif
3639 #ifdef CONFIG_RTW_MESH
3640 case MLME_MESH_STARTED:
3641 mstate_s.mesh_num = 1;
3642 break;
3643 case MLME_MESH_STOPPED:
3644 mstate_s.mesh_num = 0;
3645 mstate_s.ld_mesh_num = 0;
3646 break;
3647 #endif
3648 case MLME_ACTION_NONE:
3649 case MLME_ADHOC_STARTED:
3650 /* caller without effect of decision */
3651 break;
3652 default:
3653 rtw_warn_on(1);
3654 };
3655
3656 rtw_mi_status_merge(&mstate, &mstate_s);
3657 #endif /* !defined(CONFIG_MI_WITH_MBSSID_CAM) || defined(CONFIG_CLIENT_PORT_CFG) || defined(CONFIG_RTW_MULTI_AP) */
3658
3659 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)
3660 rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
3661 #else
3662 if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
3663 #ifdef CONFIG_FIND_BEST_CHANNEL
3664 || MSTATE_SCAN_ENTER_NUM(&mstate)
3665 #endif
3666 || hal_data->in_cta_test
3667 )
3668 rcr_new &= ~RCR_CBSSID_DATA;
3669 else
3670 rcr_new |= RCR_CBSSID_DATA;
3671
3672 if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)
3673 rcr_new &= ~RCR_CBSSID_BCN;
3674 else if (MSTATE_STA_LG_NUM(&mstate)
3675 || adapter_to_dvobj(adapter)->periodic_tsf_update_etime
3676 )
3677 rcr_new |= RCR_CBSSID_BCN;
3678 else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
3679 || MSTATE_MESH_NUM(&mstate)
3680 )
3681 rcr_new &= ~RCR_CBSSID_BCN;
3682 else
3683 rcr_new |= RCR_CBSSID_BCN;
3684
3685 #ifdef CONFIG_CLIENT_PORT_CFG
3686 if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)
3687 rcr_new &= ~RCR_CBSSID_BCN;
3688 #endif
3689 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
3690
3691 #ifdef CONFIG_RTW_MULTI_AP
3692 if (MSTATE_AP_NUM(&mstate)
3693 && rtw_unassoc_sta_src_chk(adapter, UNASOC_STA_SRC_RX_NMY_UC)
3694 ) {
3695 rcr_new |= RCR_AAP;
3696 } else
3697 rcr_new &= ~RCR_AAP;
3698 #endif
3699
3700 if (rcr == rcr_new)
3701 return;
3702
3703 if (!hal_spec->rx_tsf_filter
3704 && (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))
3705 rtw_hal_tsf_update_pause(adapter);
3706
3707 rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
3708
3709 if (!hal_spec->rx_tsf_filter
3710 && !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)
3711 && self_action != MLME_STA_CONNECTING)
3712 rtw_hal_tsf_update_restore(adapter);
3713 }
3714
rtw_hal_rcr_set_chk_bssid_act_non(_adapter * adapter)3715 void rtw_hal_rcr_set_chk_bssid_act_non(_adapter *adapter)
3716 {
3717 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3718 }
3719
hw_var_set_rcr_am(_adapter * adapter,u8 enable)3720 static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
3721 {
3722 u32 rcr = RCR_AM;
3723
3724 if (enable)
3725 rtw_hal_rcr_add(adapter, rcr);
3726 else
3727 rtw_hal_rcr_clear(adapter, rcr);
3728 }
3729
hw_var_set_bcn_interval(_adapter * adapter,u16 interval)3730 static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)
3731 {
3732 #ifdef CONFIG_SWTIMER_BASED_TXBCN
3733 interval = rtw_hal_bcn_interval_adjust(adapter, interval);
3734 #endif
3735
3736 #ifdef RTW_HALMAC
3737 rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);
3738 #else
3739 rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);
3740 #endif
3741
3742 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3743 {
3744 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3745 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3746
3747 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3748 RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);
3749 rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);
3750 }
3751 }
3752 #endif
3753 }
3754
3755 #if CONFIG_TX_AC_LIFETIME
3756 const char *const _tx_aclt_conf_str[] = {
3757 "DEFAULT",
3758 "AP_M2U",
3759 "MESH",
3760 "INVALID",
3761 };
3762
dump_tx_aclt_force_val(void * sel,struct dvobj_priv * dvobj)3763 void dump_tx_aclt_force_val(void *sel, struct dvobj_priv *dvobj)
3764 {
3765 #define TX_ACLT_FORCE_MSG_LEN 64
3766 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3767 struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3768 char buf[TX_ACLT_FORCE_MSG_LEN];
3769 int cnt = 0;
3770
3771 RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3772 , hal_spec->tx_aclt_unit_factor * 32
3773 , 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3774
3775 RTW_PRINT_SEL(sel, "%-5s %-12s %-12s\n", "en", "vo_vi(us)", "be_bk(us)");
3776 RTW_PRINT_SEL(sel, " 0x%02x %12u %12u\n"
3777 , conf->en
3778 , conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3779 , conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3780 );
3781
3782 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "%5s", conf->en == 0xFF ? "AUTO" : "FORCE");
3783 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3784 goto exit;
3785
3786 if (conf->vo_vi)
3787 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->vo_vi);
3788 else
3789 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");
3790 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3791 goto exit;
3792
3793
3794 if (conf->be_bk)
3795 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->be_bk);
3796 else
3797 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");
3798 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3799 goto exit;
3800
3801 RTW_PRINT_SEL(sel, "%s\n", buf);
3802
3803 exit:
3804 return;
3805 }
3806
rtw_hal_set_tx_aclt_force_val(_adapter * adapter,struct tx_aclt_conf_t * input,u8 arg_num)3807 void rtw_hal_set_tx_aclt_force_val(_adapter *adapter, struct tx_aclt_conf_t *input, u8 arg_num)
3808 {
3809 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3810 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3811 struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3812
3813 if (arg_num >= 1) {
3814 if (input->en == 0xFF)
3815 conf->en = input->en;
3816 else
3817 conf->en = input->en & 0xF;
3818 }
3819 if (arg_num >= 2) {
3820 conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
3821 if (conf->vo_vi > 0xFFFF)
3822 conf->vo_vi = 0xFFFF;
3823 }
3824 if (arg_num >= 3) {
3825 conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
3826 if (conf->be_bk > 0xFFFF)
3827 conf->be_bk = 0xFFFF;
3828 }
3829 }
3830
dump_tx_aclt_confs(void * sel,struct dvobj_priv * dvobj)3831 void dump_tx_aclt_confs(void *sel, struct dvobj_priv *dvobj)
3832 {
3833 #define TX_ACLT_CONF_MSG_LEN 32
3834 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3835 struct tx_aclt_conf_t *conf;
3836 char buf[TX_ACLT_CONF_MSG_LEN];
3837 int cnt;
3838 int i;
3839
3840 RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3841 , hal_spec->tx_aclt_unit_factor * 32
3842 , 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3843
3844 RTW_PRINT_SEL(sel, "%-7s %-1s %-3s %-9s %-9s %-10s %-10s\n"
3845 , "name", "#", "en", "vo_vi(us)", "be_bk(us)", "vo_vi(reg)", "be_bk(reg)");
3846
3847 for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
3848 conf = &dvobj->tx_aclt_confs[i];
3849 cnt = 0;
3850
3851 if (conf->vo_vi)
3852 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->vo_vi);
3853 else
3854 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
3855 if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
3856 continue;
3857
3858 if (conf->be_bk)
3859 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->be_bk);
3860 else
3861 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
3862 if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
3863 continue;
3864
3865 RTW_PRINT_SEL(sel, "%7s %1u 0x%x %9u %9u%s\n"
3866 , tx_aclt_conf_str(i), i
3867 , conf->en
3868 , conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3869 , conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3870 , buf
3871 );
3872 }
3873 }
3874
rtw_hal_set_tx_aclt_conf(_adapter * adapter,u8 conf_idx,struct tx_aclt_conf_t * input,u8 arg_num)3875 void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_conf_t *input, u8 arg_num)
3876 {
3877 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3878 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3879 struct tx_aclt_conf_t *conf;
3880
3881 if (conf_idx >= TX_ACLT_CONF_NUM)
3882 return;
3883
3884 conf = &dvobj->tx_aclt_confs[conf_idx];
3885
3886 if (arg_num >= 1) {
3887 if (input->en != 0xFF)
3888 conf->en = input->en & 0xF;
3889 }
3890 if (arg_num >= 2) {
3891 conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
3892 if (conf->vo_vi > 0xFFFF)
3893 conf->vo_vi = 0xFFFF;
3894 }
3895 if (arg_num >= 3) {
3896 conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
3897 if (conf->be_bk > 0xFFFF)
3898 conf->be_bk = 0xFFFF;
3899 }
3900 }
3901
rtw_hal_update_tx_aclt(_adapter * adapter)3902 void rtw_hal_update_tx_aclt(_adapter *adapter)
3903 {
3904 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3905 struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter);
3906 u8 lt_en = 0, lt_en_ori;
3907 u16 lt_vo_vi = 0xFFFF, lt_be_bk = 0xFFFF;
3908 u32 lt, lt_ori;
3909 struct tx_aclt_conf_t *conf;
3910 int i;
3911 #ifdef CONFIG_AP_MODE
3912 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
3913 _adapter *iface;
3914 u8 ap_m2u_num = 0;
3915
3916 for (i = 0; i < dvobj->iface_nums; i++) {
3917 iface = dvobj->padapters[i];
3918 if (!iface)
3919 continue;
3920
3921 if (MLME_IS_AP(iface)
3922 && ((iface->b2u_flags_ap_src & RTW_AP_B2U_IP_MCAST)
3923 || (iface->b2u_flags_ap_fwd & RTW_AP_B2U_IP_MCAST))
3924 )
3925 ap_m2u_num++;
3926 }
3927 #endif
3928 #endif /* CONFIG_AP_MODE */
3929
3930 lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN);
3931 lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME);
3932
3933 for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
3934 if (!(dvobj->tx_aclt_flags & BIT(i)))
3935 continue;
3936
3937 conf = &dvobj->tx_aclt_confs[i];
3938
3939 if (i == TX_ACLT_CONF_DEFAULT) {
3940 /* first and default status, assign directly */
3941 lt_en = conf->en;
3942 if (conf->vo_vi)
3943 lt_vo_vi = conf->vo_vi;
3944 if (conf->be_bk)
3945 lt_be_bk = conf->be_bk;
3946 }
3947 #ifdef CONFIG_AP_MODE
3948 #if CONFIG_RTW_AP_DATA_BMC_TO_UC || defined(CONFIG_RTW_MESH)
3949 else if (0
3950 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
3951 || (i == TX_ACLT_CONF_AP_M2U
3952 && ap_m2u_num
3953 && macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */)
3954 #endif
3955 #ifdef CONFIG_RTW_MESH
3956 || (i == TX_ACLT_CONF_MESH
3957 && macid_ctl->op_num[H2C_MSR_ROLE_MESH] > 1 /* implies only 1 MESH mode supported */)
3958 #endif
3959 ) {
3960 /* long term status, OR en and MIN lifetime */
3961 lt_en |= conf->en;
3962 if (conf->vo_vi && lt_vo_vi > conf->vo_vi)
3963 lt_vo_vi = conf->vo_vi;
3964 if (conf->be_bk && lt_be_bk > conf->be_bk)
3965 lt_be_bk = conf->be_bk;
3966 }
3967 #endif
3968 #endif /* CONFIG_AP_MODE */
3969 }
3970
3971 if (dvobj->tx_aclt_force_val.en != 0xFF)
3972 lt_en = dvobj->tx_aclt_force_val.en;
3973 if (dvobj->tx_aclt_force_val.vo_vi)
3974 lt_vo_vi = dvobj->tx_aclt_force_val.vo_vi;
3975 if (dvobj->tx_aclt_force_val.be_bk)
3976 lt_be_bk = dvobj->tx_aclt_force_val.be_bk;
3977
3978 lt_en = (lt_en_ori & 0xF0) | (lt_en & 0x0F);
3979 lt = (lt_be_bk << 16) | lt_vo_vi;
3980
3981 if (0)
3982 RTW_INFO("lt_en:0x%x(0x%x), lt:0x%08x(0x%08x)\n", lt_en, lt_en_ori, lt, lt_ori);
3983
3984 if (lt_en != lt_en_ori)
3985 rtw_write8(adapter, REG_LIFETIME_EN, lt_en);
3986 if (lt != lt_ori)
3987 rtw_write32(adapter, REG_PKT_LIFE_TIME, lt);
3988 }
3989 #endif /* CONFIG_TX_AC_LIFETIME */
3990
hw_var_port_switch(_adapter * adapter)3991 void hw_var_port_switch(_adapter *adapter)
3992 {
3993 #ifdef CONFIG_CONCURRENT_MODE
3994 #ifdef CONFIG_RUNTIME_PORT_SWITCH
3995 /*
3996 0x102: MSR
3997 0x550: REG_BCN_CTRL
3998 0x551: REG_BCN_CTRL_1
3999 0x55A: REG_ATIMWND
4000 0x560: REG_TSFTR
4001 0x568: REG_TSFTR1
4002 0x570: REG_ATIMWND_1
4003 0x610: REG_MACID
4004 0x618: REG_BSSID
4005 0x700: REG_MACID1
4006 0x708: REG_BSSID1
4007 */
4008
4009 int i;
4010 u8 msr;
4011 u8 bcn_ctrl;
4012 u8 bcn_ctrl_1;
4013 u8 atimwnd[2];
4014 u8 atimwnd_1[2];
4015 u8 tsftr[8];
4016 u8 tsftr_1[8];
4017 u8 macid[6];
4018 u8 bssid[6];
4019 u8 macid_1[6];
4020 u8 bssid_1[6];
4021 #if defined(CONFIG_RTL8192F)
4022 u16 wlan_act_mask_ctrl = 0;
4023 u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;
4024 #endif
4025
4026 u8 hw_port;
4027 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4028 _adapter *iface = NULL;
4029
4030 msr = rtw_read8(adapter, MSR);
4031 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4032 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4033 #if defined(CONFIG_RTL8192F)
4034 wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4035 #endif
4036
4037 for (i = 0; i < 2; i++)
4038 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4039 for (i = 0; i < 2; i++)
4040 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4041
4042 for (i = 0; i < 8; i++)
4043 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4044 for (i = 0; i < 8; i++)
4045 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4046
4047 for (i = 0; i < 6; i++)
4048 macid[i] = rtw_read8(adapter, REG_MACID + i);
4049
4050 for (i = 0; i < 6; i++)
4051 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4052
4053 for (i = 0; i < 6; i++)
4054 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4055
4056 for (i = 0; i < 6; i++)
4057 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4058
4059 #ifdef DBG_RUNTIME_PORT_SWITCH
4060 RTW_INFO(FUNC_ADPT_FMT" before switch\n"
4061 "msr:0x%02x\n"
4062 "bcn_ctrl:0x%02x\n"
4063 "bcn_ctrl_1:0x%02x\n"
4064 #if defined(CONFIG_RTL8192F)
4065 "wlan_act_mask_ctrl:0x%02x\n"
4066 #endif
4067 "atimwnd:0x%04x\n"
4068 "atimwnd_1:0x%04x\n"
4069 "tsftr:%llu\n"
4070 "tsftr1:%llu\n"
4071 "macid:"MAC_FMT"\n"
4072 "bssid:"MAC_FMT"\n"
4073 "macid_1:"MAC_FMT"\n"
4074 "bssid_1:"MAC_FMT"\n"
4075 , FUNC_ADPT_ARG(adapter)
4076 , msr
4077 , bcn_ctrl
4078 , bcn_ctrl_1
4079 #if defined(CONFIG_RTL8192F)
4080 , wlan_act_mask_ctrl
4081 #endif
4082 , *((u16 *)atimwnd)
4083 , *((u16 *)atimwnd_1)
4084 , *((u64 *)tsftr)
4085 , *((u64 *)tsftr_1)
4086 , MAC_ARG(macid)
4087 , MAC_ARG(bssid)
4088 , MAC_ARG(macid_1)
4089 , MAC_ARG(bssid_1)
4090 );
4091 #endif /* DBG_RUNTIME_PORT_SWITCH */
4092
4093 /* disable bcn function, disable update TSF */
4094 rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4095 rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4096
4097 #if defined(CONFIG_RTL8192F)
4098 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);
4099 #endif
4100
4101 /* switch msr */
4102 msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
4103 rtw_write8(adapter, MSR, msr);
4104
4105 /* write port0 */
4106 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
4107 for (i = 0; i < 2; i++)
4108 rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
4109 for (i = 0; i < 8; i++)
4110 rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
4111 for (i = 0; i < 6; i++)
4112 rtw_write8(adapter, REG_MACID + i, macid_1[i]);
4113 for (i = 0; i < 6; i++)
4114 rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
4115
4116 /* write port1 */
4117 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
4118 for (i = 0; i < 2; i++)
4119 rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
4120 for (i = 0; i < 8; i++)
4121 rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
4122 for (i = 0; i < 6; i++)
4123 rtw_write8(adapter, REG_MACID1 + i, macid[i]);
4124 for (i = 0; i < 6; i++)
4125 rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
4126
4127 /* write bcn ctl */
4128 #ifdef CONFIG_BT_COEXIST
4129 /* always enable port0 beacon function for PSTDMA */
4130 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
4131 || IS_HARDWARE_TYPE_8723D(adapter))
4132 bcn_ctrl_1 |= EN_BCN_FUNCTION;
4133 /* always disable port1 beacon function for PSTDMA */
4134 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
4135 bcn_ctrl &= ~EN_BCN_FUNCTION;
4136 #endif
4137 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
4138 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
4139
4140 #if defined(CONFIG_RTL8192F)
4141 /* if the setting of port0 and port1 are the same, it does not need to switch port setting*/
4142 if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)
4143 != (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))
4144 wlan_act_mask_ctrl ^= en_port_mask;
4145 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);
4146 #endif
4147
4148 if (adapter->iface_id == IFACE_ID0)
4149 iface = dvobj->padapters[IFACE_ID1];
4150 else if (adapter->iface_id == IFACE_ID1)
4151 iface = dvobj->padapters[IFACE_ID0];
4152
4153
4154 if (adapter->hw_port == HW_PORT0) {
4155 adapter->hw_port = HW_PORT1;
4156 iface->hw_port = HW_PORT0;
4157 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4158 ADPT_ARG(iface), ADPT_ARG(adapter));
4159 } else {
4160 adapter->hw_port = HW_PORT0;
4161 iface->hw_port = HW_PORT1;
4162 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4163 ADPT_ARG(adapter), ADPT_ARG(iface));
4164 }
4165
4166 #ifdef DBG_RUNTIME_PORT_SWITCH
4167 msr = rtw_read8(adapter, MSR);
4168 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4169 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4170 #if defined(CONFIG_RTL8192F)
4171 wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4172 #endif
4173
4174 for (i = 0; i < 2; i++)
4175 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4176 for (i = 0; i < 2; i++)
4177 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4178
4179 for (i = 0; i < 8; i++)
4180 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4181 for (i = 0; i < 8; i++)
4182 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4183
4184 for (i = 0; i < 6; i++)
4185 macid[i] = rtw_read8(adapter, REG_MACID + i);
4186
4187 for (i = 0; i < 6; i++)
4188 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4189
4190 for (i = 0; i < 6; i++)
4191 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4192
4193 for (i = 0; i < 6; i++)
4194 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4195
4196 RTW_INFO(FUNC_ADPT_FMT" after switch\n"
4197 "msr:0x%02x\n"
4198 "bcn_ctrl:0x%02x\n"
4199 "bcn_ctrl_1:0x%02x\n"
4200 #if defined(CONFIG_RTL8192F)
4201 "wlan_act_mask_ctrl:0x%02x\n"
4202 #endif
4203 "atimwnd:%u\n"
4204 "atimwnd_1:%u\n"
4205 "tsftr:%llu\n"
4206 "tsftr1:%llu\n"
4207 "macid:"MAC_FMT"\n"
4208 "bssid:"MAC_FMT"\n"
4209 "macid_1:"MAC_FMT"\n"
4210 "bssid_1:"MAC_FMT"\n"
4211 , FUNC_ADPT_ARG(adapter)
4212 , msr
4213 , bcn_ctrl
4214 , bcn_ctrl_1
4215 #if defined(CONFIG_RTL8192F)
4216 , wlan_act_mask_ctrl
4217 #endif
4218 , *((u16 *)atimwnd)
4219 , *((u16 *)atimwnd_1)
4220 , *((u64 *)tsftr)
4221 , *((u64 *)tsftr_1)
4222 , MAC_ARG(macid)
4223 , MAC_ARG(bssid)
4224 , MAC_ARG(macid_1)
4225 , MAC_ARG(bssid_1)
4226 );
4227 #endif /* DBG_RUNTIME_PORT_SWITCH */
4228
4229 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
4230 #endif /* CONFIG_CONCURRENT_MODE */
4231 }
4232
4233 const char *const _h2c_msr_role_str[] = {
4234 "RSVD",
4235 "STA",
4236 "AP",
4237 "GC",
4238 "GO",
4239 "TDLS",
4240 "ADHOC",
4241 "MESH",
4242 "INVALID",
4243 };
4244
4245 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_default_port_id_cmd(_adapter * adapter,u8 mac_id)4246 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
4247 {
4248 s32 ret = _SUCCESS;
4249 u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
4250 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4251 u8 port_id = rtw_hal_get_port(adapter);
4252
4253 if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))
4254 return ret;
4255
4256 SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);
4257 SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
4258
4259 RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
4260 RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",
4261 __func__, ADPT_ARG(adapter), port_id, mac_id);
4262
4263 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
4264 dvobj->dft.port_id = port_id;
4265 dvobj->dft.mac_id = mac_id;
4266
4267 return ret;
4268 }
rtw_set_default_port_id(_adapter * adapter)4269 s32 rtw_set_default_port_id(_adapter *adapter)
4270 {
4271 s32 ret = _SUCCESS;
4272 struct sta_info *psta;
4273 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4274
4275 if (is_client_associated_to_ap(adapter)) {
4276 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
4277 if (psta)
4278 ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
4279 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
4280
4281 } else {
4282 }
4283
4284 return ret;
4285 }
rtw_set_ps_rsvd_page(_adapter * adapter)4286 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
4287 {
4288 s32 ret = _SUCCESS;
4289 u16 media_status_rpt = RT_MEDIA_CONNECT;
4290 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4291
4292 if (adapter->iface_id == pwrctl->fw_psmode_iface_id)
4293 return ret;
4294
4295 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
4296 (u8 *)&media_status_rpt);
4297
4298 return ret;
4299 }
4300
4301 #if 0
4302 _adapter * _rtw_search_dp_iface(_adapter *adapter)
4303 {
4304 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4305 _adapter *iface;
4306 _adapter *target_iface = NULL;
4307 int i;
4308 u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;
4309 u8 p2p_go_num = 0, p2p_gc_num = 0;
4310 _adapter *sta_ifs[8];
4311 _adapter *ap_ifs[8];
4312 _adapter *mesh_ifs[8];
4313 _adapter *gc_ifs[8];
4314 _adapter *go_ifs[8];
4315
4316 for (i = 0; i < dvobj->iface_nums; i++) {
4317 iface = dvobj->padapters[i];
4318
4319 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
4320 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4321 sta_ifs[sta_num++] = iface;
4322
4323 #ifdef CONFIG_TDLS
4324 if (iface->tdlsinfo.link_established == _TRUE)
4325 tdls_num++;
4326 #endif
4327 #ifdef CONFIG_P2P
4328 if (MLME_IS_GC(iface))
4329 gc_ifs[p2p_gc_num++] = iface;
4330 #endif
4331 }
4332 #ifdef CONFIG_AP_MODE
4333 } else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
4334 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4335 ap_ifs[ap_num++] = iface;
4336 #ifdef CONFIG_P2P
4337 if (MLME_IS_GO(iface))
4338 go_ifs[p2p_go_num++] = iface;
4339 #endif
4340 }
4341 #endif
4342 } else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
4343 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4344 ) {
4345 adhoc_num++;
4346
4347 #ifdef CONFIG_RTW_MESH
4348 } else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
4349 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4350 ) {
4351 mesh_ifs[mesh_num++] = iface;
4352 #endif
4353 }
4354 }
4355
4356 if (p2p_gc_num) {
4357 target_iface = gc_ifs[0];
4358 }
4359 else if (sta_num) {
4360 if(sta_num == 1) {
4361 target_iface = sta_ifs[0];
4362 } else if (sta_num >= 2) {
4363 /*TODO get target_iface by timestamp*/
4364 target_iface = sta_ifs[0];
4365 }
4366 } else if (ap_num) {
4367 target_iface = ap_ifs[0];
4368 }
4369
4370 RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);
4371 RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);
4372 RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);
4373 RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);
4374 RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);
4375 RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);
4376 RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);
4377
4378 if (target_iface)
4379 RTW_INFO("%s => target_iface ("ADPT_FMT")\n",
4380 __func__, ADPT_ARG(target_iface));
4381 else
4382 RTW_INFO("%s => target_iface NULL\n", __func__);
4383
4384 return target_iface;
4385 }
4386
4387 void rtw_search_default_port(_adapter *adapter)
4388 {
4389 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4390 _adapter *adp_iface = NULL;
4391 #ifdef CONFIG_WOWLAN
4392 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
4393
4394 if (pwrpriv->wowlan_mode == _TRUE) {
4395 adp_iface = adapter;
4396 goto exit;
4397 }
4398 #endif
4399 adp_iface = _rtw_search_dp_iface(adapter);
4400
4401 exit :
4402 if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))
4403 rtw_set_default_port_id(adp_iface);
4404 else
4405 rtw_hal_set_default_port_id_cmd(adapter, 0);
4406
4407 if (1) {
4408 _adapter *tmp_adp;
4409
4410 tmp_adp = (adp_iface) ? adp_iface : adapter;
4411
4412 RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",
4413 __func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));
4414 }
4415 }
4416 #endif
4417 #endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/
4418
4419 #ifdef CONFIG_P2P_PS
4420 #ifdef RTW_HALMAC
rtw_set_p2p_ps_offload_cmd(_adapter * adapter,u8 p2p_ps_state)4421 void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
4422 {
4423 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4424 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4425 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4426 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4427 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
4428 struct sta_priv *pstapriv = &adapter->stapriv;
4429 struct sta_info *psta;
4430 HAL_P2P_PS_PARA p2p_ps_para;
4431 int status = -1;
4432 u8 i;
4433 u8 hw_port = rtw_hal_get_port(adapter);
4434
4435 _rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
4436 _rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
4437
4438 (&p2p_ps_para)->p2p_port_id = hw_port;
4439 (&p2p_ps_para)->p2p_group = 0;
4440 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
4441 if (psta) {
4442 (&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
4443 } else {
4444 if (p2p_ps_state != P2P_PS_DISABLE) {
4445 RTW_ERR("%s , psta was NULL\n", __func__);
4446 return;
4447 }
4448 }
4449
4450
4451 switch (p2p_ps_state) {
4452 case P2P_PS_DISABLE:
4453 RTW_INFO("P2P_PS_DISABLE\n");
4454 _rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
4455 break;
4456
4457 case P2P_PS_ENABLE:
4458 RTW_INFO("P2P_PS_ENABLE\n");
4459 /* update CTWindow value. */
4460 if (pwdinfo->ctwindow > 0) {
4461 (&p2p_ps_para)->ctwindow_en = 1;
4462 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4463 /*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
4464 }
4465
4466
4467 if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
4468 (&p2p_ps_para)->offload_en = 1;
4469 if (pwdinfo->role == P2P_ROLE_GO) {
4470 (&p2p_ps_para)->role = 1;
4471 (&p2p_ps_para)->all_sta_sleep = 0;
4472 } else
4473 (&p2p_ps_para)->role = 0;
4474
4475 (&p2p_ps_para)->discovery = 0;
4476 }
4477 /* hw only support 2 set of NoA */
4478 for (i = 0; i < pwdinfo->noa_num; i++) {
4479 /* To control the register setting for which NOA */
4480 (&p2p_ps_para)->noa_sel = i;
4481 (&p2p_ps_para)->noa_en = 1;
4482 (&p2p_ps_para)->disable_close_rf = 0;
4483 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
4484 #ifdef CONFIG_CONCURRENT_MODE
4485 if (rtw_mi_buddy_check_fwstate(adapter, WIFI_ASOC_STATE))
4486 #endif /* CONFIG_CONCURRENT_MODE */
4487 (&p2p_ps_para)->disable_close_rf = 1;
4488 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
4489 /* config P2P NoA Descriptor Register */
4490 /* config NOA duration */
4491 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
4492 /* config NOA interval */
4493 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
4494 /* config NOA start time */
4495 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
4496 /* config NOA count */
4497 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
4498 /*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
4499 (&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
4500 (&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
4501 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4502 if (status == -1)
4503 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4504 }
4505
4506 break;
4507
4508 case P2P_PS_SCAN:
4509 /*This feature FW not ready 20161116 YiWei*/
4510 return;
4511 /*
4512 RTW_INFO("P2P_PS_SCAN\n");
4513 (&p2p_ps_para)->discovery = 1;
4514 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4515 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4516 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4517 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4518 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4519 */
4520 break;
4521
4522 case P2P_PS_SCAN_DONE:
4523 /*This feature FW not ready 20161116 YiWei*/
4524 return;
4525 /*
4526 RTW_INFO("P2P_PS_SCAN_DONE\n");
4527 (&p2p_ps_para)->discovery = 0;
4528 pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
4529 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4530 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4531 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4532 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4533 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4534 */
4535 break;
4536
4537 default:
4538 break;
4539 }
4540
4541 if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
4542 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4543 if (status == -1)
4544 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4545 }
4546 _rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
4547
4548 }
4549 #endif /* RTW_HALMAC */
4550 #endif /* CONFIG_P2P */
4551
4552 #if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR)
_rtw_hal_dtp_macid_set(_adapter * padapter,u8 opmode,u8 mac_id)4553 static void _rtw_hal_dtp_macid_set(
4554 _adapter *padapter, u8 opmode, u8 mac_id)
4555 {
4556 struct macid_ctl_t *macid_ctl = &(padapter->dvobj->macid_ctl);
4557 struct sta_info *psta;
4558 u8 h2c_cmd[H2C_FW_CRC5_SEARCH_LEN] = {0};
4559 u8 mac_addr[ETH_ALEN] = {0};
4560
4561 if (opmode) {
4562 psta = macid_ctl->sta[mac_id];
4563 if (psta)
4564 _rtw_memcpy(mac_addr, psta->cmn.mac_addr, ETH_ALEN);
4565
4566 if (rtw_check_invalid_mac_address(mac_addr, _FALSE))
4567 return;
4568 }
4569 /* else DON'T CARE H2C_FW_CRC5_SEARCH mac addr in disconnected case */
4570
4571 if (rtw_get_chip_type(padapter) == RTL8822C) {
4572 SET_H2CCMD_FW_CRC5_SEARCH_EN(h2c_cmd, opmode);
4573 SET_H2CCMD_FW_CRC5_SEARCH_MACID(h2c_cmd, mac_id);
4574 SET_H2CCMD_FW_CRC5_SEARCH_MAC(&h2c_cmd[1], mac_addr);
4575 if (rtw_hal_fill_h2c_cmd(padapter, H2C_FW_CRC5_SEARCH,
4576 H2C_FW_CRC5_SEARCH_LEN, h2c_cmd) != _SUCCESS)
4577 RTW_WARN("%s : set h2c - 0x%02x fail!\n", __func__, H2C_FW_CRC5_SEARCH);
4578 }
4579 }
4580
rtw_hal_dtp_macid_set(_adapter * padapter,u8 opmode,bool macid_ind,u8 mac_id,u8 macid_end)4581 static void rtw_hal_dtp_macid_set(_adapter *padapter, u8 opmode,
4582 bool macid_ind, u8 mac_id, u8 macid_end)
4583 {
4584 int i;
4585
4586 if (macid_ind == 0) {
4587 _rtw_hal_dtp_macid_set(padapter, opmode, mac_id);
4588 } else {
4589 for (i = mac_id; i <= macid_end; i++)
4590 _rtw_hal_dtp_macid_set(padapter, opmode, i);
4591 }
4592 }
4593 #endif
4594
4595 /*
4596 * rtw_hal_set_FwMediaStatusRpt_cmd -
4597 *
4598 * @adapter:
4599 * @opmode: 0:disconnect, 1:connect
4600 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
4601 * @miracast_sink: 0:source. 1:sink
4602 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
4603 * @macid:
4604 * @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end
4605 * @macid_end:
4606 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)4607 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)
4608 {
4609 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
4610 u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
4611 int i;
4612 s32 ret;
4613 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4614 u8 hw_port = rtw_hal_get_port(adapter);
4615 #endif
4616 u8 op_num_change_bmp = 0;
4617
4618 #if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR)
4619 rtw_hal_dtp_macid_set(adapter, opmode, macid_ind, macid, macid_end);
4620 #endif
4621
4622 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
4623 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
4624 SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
4625 SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
4626 SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
4627 SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
4628 SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
4629 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4630 SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);
4631 #endif
4632 RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
4633
4634 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
4635 if (ret != _SUCCESS)
4636 goto exit;
4637
4638 #if defined(CONFIG_RTL8188E)
4639 if (rtw_get_chip_type(adapter) == RTL8188E) {
4640 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4641
4642 /* 8188E FW doesn't set macid no link, driver does it by self */
4643 if (opmode)
4644 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
4645 else
4646 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
4647
4648 /* for 8188E RA */
4649 #if (RATE_ADAPTIVE_SUPPORT == 1)
4650 if (hal_data->fw_ractrl == _FALSE) {
4651 u8 max_macid;
4652
4653 max_macid = rtw_search_max_mac_id(adapter);
4654 rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
4655 }
4656 #endif
4657 }
4658 #endif
4659
4660 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
4661 /* TODO: this should move to IOT issue area */
4662 if (rtw_get_chip_type(adapter) == RTL8812
4663 || rtw_get_chip_type(adapter) == RTL8821
4664 ) {
4665 if (MLME_IS_STA(adapter))
4666 Hal_PatchwithJaguar_8812(adapter, opmode);
4667 }
4668 #endif
4669
4670 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
4671 if (macid_ind == 0)
4672 macid_end = macid;
4673
4674 for (i = macid; macid <= macid_end; macid++) {
4675 op_num_change_bmp |= rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
4676 if (!opmode) {
4677 rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
4678 rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
4679 rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
4680 rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
4681 }
4682 }
4683
4684 #if CONFIG_TX_AC_LIFETIME
4685 if (op_num_change_bmp)
4686 rtw_hal_update_tx_aclt(adapter);
4687 #endif
4688
4689 if (!opmode)
4690 rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
4691
4692 exit:
4693 return ret;
4694 }
4695
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)4696 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
4697 {
4698 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
4699 }
4700
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)4701 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
4702 {
4703 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
4704 }
4705
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4706 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4707 {
4708 u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
4709 u8 ret = 0;
4710
4711 RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
4712 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
4713 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
4714 rsvdpageloc->LocBTQosNull);
4715
4716 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
4717 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
4718 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
4719 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
4720 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
4721
4722 ret = rtw_hal_fill_h2c_cmd(padapter,
4723 H2C_RSVD_PAGE,
4724 H2C_RSVDPAGE_LOC_LEN,
4725 u1H2CRsvdPageParm);
4726
4727 }
4728
4729 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)4730 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
4731 {
4732 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4733
4734 if (IS_8723D_SERIES(pHalData->version_id) || IS_8192F_SERIES(pHalData->version_id)
4735 || IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id)
4736 || IS_8822C_SERIES(pHalData->version_id))
4737 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4738 /*
4739 * Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
4740 * It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
4741 * and implement HAL function.
4742 * TODO: GPIO_8 multi function?
4743 */
4744
4745 if ((index == 13 || index == 14)
4746 #if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
4747 /* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
4748 && (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
4749 #endif
4750 )
4751 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4752 }
4753
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)4754 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
4755 {
4756 #if defined(CONFIG_RTL8192F)
4757 rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&outputval));
4758 #else
4759 if (index <= 7) {
4760 /* config GPIO mode */
4761 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4762 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4763
4764 /* config GPIO Sel */
4765 /* 0: input */
4766 /* 1: output */
4767 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4768 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
4769
4770 /* set output value */
4771 if (outputval) {
4772 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4773 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
4774 } else {
4775 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4776 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
4777 }
4778 } else if (index <= 15) {
4779 /* 88C Series: */
4780 /* index: 11~8 transform to 3~0 */
4781 /* 8723 Series: */
4782 /* index: 12~8 transform to 4~0 */
4783
4784 index -= 8;
4785
4786 /* config GPIO mode */
4787 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4788 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4789
4790 /* config GPIO Sel */
4791 /* 0: input */
4792 /* 1: output */
4793 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4794 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
4795
4796 /* set output value */
4797 if (outputval) {
4798 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4799 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
4800 } else {
4801 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4802 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
4803 }
4804 } else {
4805 RTW_INFO("%s: invalid GPIO%d=%d\n",
4806 __FUNCTION__, index, outputval);
4807 }
4808 #endif
4809 }
rtw_hal_set_input_gpio(_adapter * padapter,u8 index)4810 void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
4811 {
4812 #if defined(CONFIG_RTL8192F)
4813 rtw_hal_set_hwreg(padapter, HW_VAR_WOW_INPUT_GPIO, (u8 *)(&index));
4814 #else
4815 if (index <= 7) {
4816 /* config GPIO mode */
4817 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4818 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4819
4820 /* config GPIO Sel */
4821 /* 0: input */
4822 /* 1: output */
4823 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4824 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
4825
4826 } else if (index <= 15) {
4827 /* 88C Series: */
4828 /* index: 11~8 transform to 3~0 */
4829 /* 8723 Series: */
4830 /* index: 12~8 transform to 4~0 */
4831
4832 index -= 8;
4833
4834 /* config GPIO mode */
4835 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4836 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4837
4838 /* config GPIO Sel */
4839 /* 0: input */
4840 /* 1: output */
4841 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4842 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
4843 } else
4844 RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
4845 #endif
4846 }
4847
4848 #endif
4849
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4850 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4851 {
4852 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
4853 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4854 u8 ret = 0;
4855 #ifdef CONFIG_WOWLAN
4856 u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
4857
4858 RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
4859 __func__, rsvdpageloc->LocRemoteCtrlInfo,
4860 rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
4861 rsvdpageloc->LocNDPInfo);
4862 RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
4863 __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
4864 rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
4865
4866 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
4867 SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
4868 SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
4869 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
4870 rsvdpageloc->LocNbrAdv);
4871 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
4872 rsvdpageloc->LocNDPInfo);
4873 #ifdef CONFIG_GTK_OL
4874 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
4875 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
4876 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
4877 #endif /* CONFIG_GTK_OL */
4878 ret = rtw_hal_fill_h2c_cmd(padapter,
4879 H2C_AOAC_RSVD_PAGE,
4880 H2C_AOAC_RSVDPAGE_LOC_LEN,
4881 u1H2CAoacRsvdPageParm);
4882
4883 RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
4884 _rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
4885 SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
4886 rsvdpageloc->LocAOACReport);
4887 ret = rtw_hal_fill_h2c_cmd(padapter,
4888 H2C_AOAC_RSVDPAGE3,
4889 H2C_AOAC_RSVDPAGE_LOC_LEN,
4890 u1H2CAoacRsvdPageParm);
4891 pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
4892 }
4893 #ifdef CONFIG_PNO_SUPPORT
4894 else {
4895
4896 if (!pwrpriv->wowlan_in_resume) {
4897 RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
4898 _rtw_memset(&u1H2CAoacRsvdPageParm, 0,
4899 sizeof(u1H2CAoacRsvdPageParm));
4900 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
4901 rsvdpageloc->LocPNOInfo);
4902 ret = rtw_hal_fill_h2c_cmd(padapter,
4903 H2C_AOAC_RSVDPAGE3,
4904 H2C_AOAC_RSVDPAGE_LOC_LEN,
4905 u1H2CAoacRsvdPageParm);
4906 }
4907 }
4908 #endif /* CONFIG_PNO_SUPPORT */
4909 #endif /* CONFIG_WOWLAN */
4910 }
4911
4912 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4913 void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4914 {
4915 struct hal_ops *pHalFunc = &padapter->hal_func;
4916 u8 u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};
4917 u8 ret = 0;
4918
4919
4920 RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);
4921
4922 SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);
4923 SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);
4924 ret = rtw_hal_fill_h2c_cmd(padapter,
4925 H2C_FW_DBG_MSG_PKT,
4926 H2C_FW_DBG_MSG_PKT_LEN,
4927 u1H2C_fw_dbg_msg_pkt_parm);
4928
4929 }
4930 #endif /*DBG_FW_DEBUG_MSG_PKT*/
4931
4932 /*#define DBG_GET_RSVD_PAGE*/
rtw_hal_get_rsvd_page(_adapter * adapter,u32 page_offset,u32 page_num,u8 * buffer,u32 buffer_size)4933 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
4934 u32 page_num, u8 *buffer, u32 buffer_size)
4935 {
4936 u32 addr = 0, size = 0, count = 0;
4937 u32 page_size = 0, data_low = 0, data_high = 0;
4938 u16 txbndy = 0, offset = 0;
4939 u8 i = 0;
4940 bool rst = _FALSE;
4941
4942 #ifdef DBG_LA_MODE
4943 struct registry_priv *registry_par = &adapter->registrypriv;
4944
4945 if(registry_par->la_mode_en == 1) {
4946 RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);
4947 return rst;
4948 }
4949 #endif
4950 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
4951
4952 addr = page_offset * page_size;
4953 size = page_num * page_size;
4954
4955 if (buffer_size < size) {
4956 RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
4957 __func__, buffer_size, size);
4958 return rst;
4959 }
4960 #ifdef RTW_HALMAC
4961 if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
4962 rst = _FALSE;
4963 else
4964 rst = _TRUE;
4965 #else
4966 txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
4967
4968 offset = (txbndy + page_offset) * page_size / 8;
4969 count = (buffer_size / 8) + 1;
4970
4971 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
4972
4973 for (i = 0 ; i < count ; i++) {
4974 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
4975 data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
4976 data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
4977 _rtw_memcpy(buffer + (i * 8),
4978 &data_low, sizeof(data_low));
4979 _rtw_memcpy(buffer + ((i * 8) + 4),
4980 &data_high, sizeof(data_high));
4981 }
4982 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
4983 rst = _TRUE;
4984 #endif /*RTW_HALMAC*/
4985
4986 #ifdef DBG_GET_RSVD_PAGE
4987 RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
4988 __func__, page_offset, page_num, addr, size);
4989 RTW_INFO_DUMP("\n", buffer, size);
4990 RTW_INFO(" ==================================================\n");
4991 #endif
4992 return rst;
4993 }
4994
rtw_dump_rsvd_page(void * sel,_adapter * adapter,u8 page_offset,u8 page_num)4995 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
4996 {
4997 #if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG)
4998 u32 page_size = 0;
4999 u8 *buffer = NULL;
5000 u32 buf_size = 0;
5001
5002 if (page_num == 0)
5003 return;
5004
5005 RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");
5006 RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
5007
5008 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5009 if (page_size) {
5010 buf_size = page_size * page_num;
5011 buffer = rtw_zvmalloc(buf_size);
5012
5013 if (buffer) {
5014 rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
5015 RTW_DUMP_SEL(sel, buffer, buf_size);
5016 rtw_vmfree(buffer, buf_size);
5017 } else
5018 RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
5019 } else
5020 RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
5021
5022 RTW_PRINT_SEL(sel, "==========================\n");
5023 #endif
5024 }
5025
5026 #ifdef CONFIG_SUPPORT_FIFO_DUMP
rtw_dump_fifo(void * sel,_adapter * adapter,u8 fifo_sel,u32 fifo_addr,u32 fifo_size)5027 void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
5028 {
5029 u8 *buffer = NULL;
5030 u32 buff_size = 0;
5031 static const char * const fifo_sel_str[] = {
5032 "TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
5033 };
5034
5035 if (fifo_sel > 5) {
5036 RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
5037 return;
5038 }
5039
5040 RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
5041 RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
5042
5043 if (fifo_size) {
5044 buff_size = RND4(fifo_size);
5045 buffer = rtw_zvmalloc(buff_size);
5046 if (buffer == NULL)
5047 buff_size = 0;
5048 }
5049
5050 rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
5051
5052 if (buffer) {
5053 RTW_DUMP_SEL(sel, buffer, fifo_size);
5054 rtw_vmfree(buffer, buff_size);
5055 }
5056
5057 RTW_PRINT_SEL(sel, "==========================\n");
5058 }
5059 #endif
5060
5061 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)5062 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
5063 {
5064 RTW_INFO("%s: Set 0x690=0x00\n", __func__);
5065 rtw_write8(adapter, REG_WOW_CTRL,
5066 (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
5067 RTW_PRINT("%s: Release RXDMA\n", __func__);
5068 rtw_write32(adapter, REG_RXPKT_NUM,
5069 (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
5070 }
5071 #if defined(CONFIG_RTL8188E)
rtw_hal_disable_tx_report(_adapter * adapter)5072 static void rtw_hal_disable_tx_report(_adapter *adapter)
5073 {
5074 rtw_write8(adapter, REG_TX_RPT_CTRL,
5075 ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
5076 RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5077 }
5078
rtw_hal_enable_tx_report(_adapter * adapter)5079 static void rtw_hal_enable_tx_report(_adapter *adapter)
5080 {
5081 rtw_write8(adapter, REG_TX_RPT_CTRL,
5082 ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
5083 RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5084 }
5085 #endif
rtw_hal_release_rx_dma(_adapter * adapter)5086 static void rtw_hal_release_rx_dma(_adapter *adapter)
5087 {
5088 u32 val32 = 0;
5089
5090 val32 = rtw_read32(adapter, REG_RXPKT_NUM);
5091
5092 rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
5093
5094 RTW_INFO("%s, [0x%04x]: 0x%08x\n",
5095 __func__, REG_RXPKT_NUM, (u32)(val32 & (~RW_RELEASE_EN)));
5096 }
5097
rtw_hal_pause_rx_dma(_adapter * adapter)5098 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
5099 {
5100 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
5101 u8 ret = 0;
5102 s8 trycnt = 100;
5103 u32 tmp = 0;
5104 int res = 0;
5105 /* RX DMA stop */
5106 RTW_PRINT("Pause DMA\n");
5107 rtw_write32(adapter, REG_RXPKT_NUM,
5108 (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
5109 do {
5110 if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
5111 #ifdef CONFIG_USB_HCI
5112 /* stop interface before leave */
5113 if (_TRUE == hal->usb_intf_start) {
5114 rtw_intf_stop(adapter);
5115 RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
5116 RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
5117 }
5118 #endif /* CONFIG_USB_HCI */
5119
5120 RTW_PRINT("RX_DMA_IDLE is true\n");
5121 ret = _SUCCESS;
5122 break;
5123 }
5124 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5125 else {
5126 res = RecvOnePkt(adapter);
5127 RTW_PRINT("RecvOnePkt Result: %d\n", res);
5128 }
5129 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
5130
5131 #ifdef CONFIG_USB_HCI
5132 else {
5133 /* to avoid interface start repeatedly */
5134 if (_FALSE == hal->usb_intf_start)
5135 rtw_intf_start(adapter);
5136 }
5137 #endif /* CONFIG_USB_HCI */
5138 } while (trycnt--);
5139
5140 if (trycnt < 0) {
5141 tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
5142
5143 RTW_PRINT("Stop RX DMA failed......\n");
5144 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
5145 RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
5146 __func__, rtw_read16(adapter, REG_RXPKTNUM));
5147 #else
5148 RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
5149 __func__, ((tmp & 0xFF00) >> 8));
5150 #endif
5151 if (tmp & BIT(3))
5152 RTW_PRINT("%s, RX DMA has req\n",
5153 __func__);
5154 else
5155 RTW_PRINT("%s, RX DMA no req\n",
5156 __func__);
5157 ret = _FAIL;
5158 }
5159
5160 return ret;
5161 }
5162
5163 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5164 #ifndef RTW_HALMAC
rtw_hal_enable_cpwm2(_adapter * adapter)5165 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
5166 {
5167 u8 ret = 0;
5168 int res = 0;
5169 u32 tmp = 0;
5170 #ifdef CONFIG_GPIO_WAKEUP
5171 return _SUCCESS;
5172 #else
5173 RTW_PRINT("%s\n", __func__);
5174
5175 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5176 if (!res)
5177 RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
5178 else
5179 RTW_INFO("sdio_local_read fail\n");
5180
5181 tmp = SDIO_HIMR_CPWM2_MSK;
5182
5183 res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5184
5185 if (!res) {
5186 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5187 RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
5188 ret = _SUCCESS;
5189 } else {
5190 RTW_INFO("sdio_local_write fail\n");
5191 ret = _FAIL;
5192 }
5193 return ret;
5194 #endif /* CONFIG_CPIO_WAKEUP */
5195 }
5196 #endif
5197 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
5198 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
5199
5200 #ifdef CONFIG_WOWLAN
5201 /*
5202 * rtw_hal_check_wow_ctrl
5203 * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
5204 * If 0x1C7 == 0 (for 3081), WOW enable successful.
5205 * _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
5206 * If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
5207 */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)5208 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
5209 {
5210 u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
5211 u8 mstatus = 0;
5212 u8 reason = 0xFF;
5213 u8 trycnt = 25;
5214 u8 res = _FALSE;
5215
5216 if (IS_HARDWARE_TYPE_JAGUAR2(adapter) || IS_HARDWARE_TYPE_JAGUAR3(adapter)) {
5217 if (chk_type) {
5218 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5219 RTW_INFO("%s reason:0x%02x\n", __func__, reason);
5220
5221 while (reason && trycnt > 1) {
5222 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5223 RTW_PRINT("Loop index: %d :0x%02x\n",
5224 trycnt, reason);
5225 trycnt--;
5226 rtw_msleep_os(20);
5227 }
5228 if (!reason)
5229 res = _TRUE;
5230 else
5231 res = _FALSE;
5232 } else {
5233 /* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
5234 fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
5235 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
5236 RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
5237
5238 while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
5239 rtw_msleep_os(20);
5240 fe1_imr = rtw_read32(adapter, REG_FE1IMR);
5241 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
5242 RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
5243 trycnt, fe1_imr, rxpkt_num);
5244 trycnt--;
5245 }
5246
5247 if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
5248 res = _FALSE;
5249 else
5250 res = _TRUE;
5251 }
5252 } else {
5253 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5254 RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
5255
5256
5257 if (chk_type) {
5258 while (!(mstatus & BIT1) && trycnt > 1) {
5259 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5260 RTW_PRINT("Loop index: %d :0x%02x\n",
5261 trycnt, mstatus);
5262 trycnt--;
5263 rtw_msleep_os(20);
5264 }
5265 if (mstatus & BIT1)
5266 res = _TRUE;
5267 else
5268 res = _FALSE;
5269 } else {
5270 while (mstatus & BIT1 && trycnt > 1) {
5271 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5272 RTW_PRINT("Loop index: %d :0x%02x\n",
5273 trycnt, mstatus);
5274 trycnt--;
5275 rtw_msleep_os(20);
5276 }
5277
5278 if (mstatus & BIT1)
5279 res = _FALSE;
5280 else
5281 res = _TRUE;
5282 }
5283 }
5284
5285 RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
5286 __func__, chk_type, res, (25 - trycnt));
5287 return res;
5288 }
5289
5290 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_check_pno_enabled(_adapter * adapter)5291 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
5292 {
5293 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5294 u8 res = 0, count = 0;
5295 u8 ret = _FALSE;
5296
5297 if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
5298 res = rtw_read8(adapter, REG_PNO_STATUS);
5299 while (!(res & BIT(7)) && count < 25) {
5300 RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
5301 count, res);
5302 res = rtw_read8(adapter, REG_PNO_STATUS);
5303 count++;
5304 rtw_msleep_os(2);
5305 }
5306 if (res & BIT(7))
5307 ret = _TRUE;
5308 else
5309 ret = _FALSE;
5310 RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
5311 }
5312 return ret;
5313 }
5314 #endif
5315
rtw_hal_backup_rate(_adapter * adapter)5316 static void rtw_hal_backup_rate(_adapter *adapter)
5317 {
5318 RTW_INFO("%s\n", __func__);
5319 /* backup data rate to register 0x8b for wowlan FW */
5320 rtw_write8(adapter, 0x8d, 1);
5321 rtw_write8(adapter, 0x8c, 0);
5322 rtw_write8(adapter, 0x8f, 0x40);
5323 rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
5324 }
5325
5326 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)5327 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
5328 {
5329 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5330 int cam_id, index = 0;
5331 u8 *addr = NULL;
5332
5333 if (!MLME_IS_STA(adapter))
5334 return;
5335
5336 addr = get_bssid(pmlmepriv);
5337
5338 if (addr == NULL) {
5339 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
5340 return;
5341 }
5342
5343 rtw_clean_dk_section(adapter);
5344
5345 do {
5346 cam_id = rtw_camid_search(adapter, addr, index, 1);
5347
5348 if (cam_id == -1)
5349 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
5350 else
5351 rtw_sec_cam_swap(adapter, cam_id, index);
5352
5353 index++;
5354 } while (index < 4);
5355
5356 rtw_write8(adapter, REG_SECCFG, 0xcc);
5357 }
5358
rtw_hal_update_gtk_offload_info(_adapter * adapter)5359 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
5360 {
5361 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5362 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5363 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5364 struct security_priv *psecuritypriv = &adapter->securitypriv;
5365 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5366 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
5367 _irqL irqL;
5368 u8 get_key[16];
5369 u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;
5370 u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
5371
5372 if (!MLME_IS_STA(adapter))
5373 return;
5374
5375 _rtw_memset(get_key, 0, sizeof(get_key));
5376 _rtw_memcpy(&replay_count,
5377 paoac_rpt->replay_counter_eapol_key, 8);
5378
5379 /*read gtk key index*/
5380 gtk_id = paoac_rpt->key_index;
5381 aoac_rpt_ver = paoac_rpt->version_info;
5382
5383 if (aoac_rpt_ver == 0) {
5384 /* initial verison */
5385 if (gtk_id == 5)
5386 has_rekey = _FALSE;
5387 else
5388 has_rekey = _TRUE;
5389 } else if (aoac_rpt_ver >= 1) {
5390 /* Add krack patch */
5391 if (gtk_id == 5)
5392 RTW_WARN("%s FW check iv fail\n", __func__);
5393
5394 if (aoac_rpt_ver == 1)
5395 RTW_WARN("%s aoac report version should be update to v2\n", __func__);
5396
5397 /* Fix key id mismatch */
5398 if (aoac_rpt_ver == 2)
5399 has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;
5400 }
5401
5402 if (has_rekey == _FALSE) {
5403 RTW_INFO("%s no rekey event happened.\n", __func__);
5404 } else if (has_rekey == _TRUE) {
5405 RTW_INFO("%s update security key.\n", __func__);
5406 /*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
5407 rtw_sec_read_cam_ent(adapter, gtk_id,
5408 NULL, NULL, get_key);
5409 rtw_clean_hw_dk_cam(adapter);
5410
5411 if (_rtw_camid_is_gk(adapter, gtk_id)) {
5412 _enter_critical_bh(&cam_ctl->lock, &irqL);
5413 _rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
5414 get_key, 16);
5415 _exit_critical_bh(&cam_ctl->lock, &irqL);
5416 } else {
5417 struct setkey_parm parm_gtk;
5418
5419 parm_gtk.algorithm = paoac_rpt->security_type;
5420 parm_gtk.keyid = gtk_id;
5421 _rtw_memcpy(parm_gtk.key, get_key, 16);
5422 setkey_hdl(adapter, (u8 *)&parm_gtk);
5423 }
5424
5425 /*update key into related sw variable and sec-cam cache*/
5426 psecuritypriv->dot118021XGrpKeyid = gtk_id;
5427 _rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
5428 get_key, 16);
5429 /* update SW TKIP TX/RX MIC value */
5430 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
5431 offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
5432 _rtw_memcpy(
5433 &psecuritypriv->dot118021XGrptxmickey[gtk_id],
5434 &(paoac_rpt->group_key[offset]),
5435 RTW_TKIP_MIC_LEN);
5436
5437 offset = RTW_KEK_LEN;
5438 _rtw_memcpy(
5439 &psecuritypriv->dot118021XGrprxmickey[gtk_id],
5440 &(paoac_rpt->group_key[offset]),
5441 RTW_TKIP_MIC_LEN);
5442 }
5443 RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
5444 KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
5445 }
5446
5447 /* Update broadcast RX IV */
5448 if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
5449 sz = sizeof(psecuritypriv->iv_seq[0]);
5450 for (i = 0 ; i < 4 ; i++) {
5451 _rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
5452 tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
5453 pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
5454 _rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
5455 }
5456 }
5457
5458 rtw_clean_dk_section(adapter);
5459
5460 rtw_write8(adapter, REG_SECCFG, 0x0c);
5461
5462 #ifdef CONFIG_GTK_OL_DBG
5463 /* if (gtk_keyindex != 5) */
5464 dump_sec_cam(RTW_DBGDUMP, adapter);
5465 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
5466 #endif
5467 }
5468 #endif /*CONFIG_GTK_OL*/
5469
rtw_dump_aoac_rpt(_adapter * adapter)5470 static void rtw_dump_aoac_rpt(_adapter *adapter)
5471 {
5472 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5473 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5474 int i = 0;
5475
5476 RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
5477 RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
5478 paoac_rpt->replay_counter_eapol_key, 8);
5479 RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
5480 RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
5481 RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
5482 RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
5483 paoac_rpt->wow_pattern_idx);
5484 RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
5485 RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);
5486 RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
5487 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
5488 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
5489 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
5490 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
5491 }
5492
rtw_hal_get_aoac_rpt(_adapter * adapter)5493 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
5494 {
5495 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5496 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5497 u32 page_offset = 0, page_number = 0;
5498 u32 page_size = 0, buf_size = 0;
5499 u8 *buffer = NULL;
5500 u8 i = 0, tmp = 0;
5501 int ret = -1;
5502
5503 /* read aoac report from rsvd page */
5504 page_offset = pwrctl->wowlan_aoac_rpt_loc;
5505 page_number = 1;
5506
5507 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5508 buf_size = page_size * page_number;
5509
5510 buffer = rtw_zvmalloc(buf_size);
5511
5512 if (buffer == NULL) {
5513 RTW_ERR("%s buffer allocate failed size(%d)\n",
5514 __func__, buf_size);
5515 return;
5516 }
5517
5518 RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
5519
5520 ret = rtw_hal_get_rsvd_page(adapter, page_offset,
5521 page_number, buffer, buf_size);
5522
5523 if (ret == _FALSE) {
5524 RTW_ERR("%s get aoac report failed\n", __func__);
5525 rtw_warn_on(1);
5526 goto _exit;
5527 }
5528
5529 _rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
5530 _rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
5531
5532 for (i = 0 ; i < 4 ; i++) {
5533 tmp = paoac_rpt->replay_counter_eapol_key[i];
5534 paoac_rpt->replay_counter_eapol_key[i] =
5535 paoac_rpt->replay_counter_eapol_key[7 - i];
5536 paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
5537 }
5538
5539 rtw_dump_aoac_rpt(adapter);
5540
5541 _exit:
5542 if (buffer)
5543 rtw_vmfree(buffer, buf_size);
5544 }
5545
rtw_hal_update_tx_iv(_adapter * adapter)5546 static void rtw_hal_update_tx_iv(_adapter *adapter)
5547 {
5548 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5549 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5550 struct sta_info *psta;
5551 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
5552 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5553 struct security_priv *psecpriv = &adapter->securitypriv;
5554
5555 u16 val16 = 0;
5556 u32 val32 = 0;
5557 u64 txiv = 0;
5558 u8 *pval = NULL;
5559
5560 psta = rtw_get_stainfo(&adapter->stapriv,
5561 get_my_bssid(&pmlmeinfo->network));
5562
5563 /* Update TX iv data. */
5564 pval = (u8 *)&paoac_rpt->iv;
5565
5566 if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
5567 val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
5568 ((u16)(paoac_rpt->iv[0]) << 8);
5569 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5570 ((u32)(paoac_rpt->iv[5]) << 8) +
5571 ((u32)(paoac_rpt->iv[6]) << 16) +
5572 ((u32)(paoac_rpt->iv[7]) << 24);
5573 } else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
5574 val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
5575 ((u16)(paoac_rpt->iv[1]) << 8);
5576 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5577 ((u32)(paoac_rpt->iv[5]) << 8) +
5578 ((u32)(paoac_rpt->iv[6]) << 16) +
5579 ((u32)(paoac_rpt->iv[7]) << 24);
5580 }
5581
5582 if (psta) {
5583 txiv = val16 + ((u64)val32 << 16);
5584 if (txiv != 0)
5585 psta->dot11txpn.val = txiv;
5586 }
5587 }
5588
rtw_hal_update_sw_security_info(_adapter * adapter)5589 static void rtw_hal_update_sw_security_info(_adapter *adapter)
5590 {
5591 struct security_priv *psecpriv = &adapter->securitypriv;
5592 u8 sz = sizeof (psecpriv->iv_seq);
5593
5594 rtw_hal_update_tx_iv(adapter);
5595 #ifdef CONFIG_GTK_OL
5596 if (psecpriv->binstallKCK_KEK == _TRUE &&
5597 (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5598 rtw_hal_update_gtk_offload_info(adapter);
5599 #else
5600 _rtw_memset(psecpriv->iv_seq, 0, sz);
5601 #endif
5602 }
5603 #ifdef CONFIG_CUSTOM_PULSE
rtw_hal_set_gpio_custom_cmd(_adapter * adapter,u8 enable)5604 static u8 rtw_hal_set_gpio_custom_cmd(_adapter *adapter, u8 enable)
5605 {
5606 u8 H2CGpioCustomParm[H2C_GPIO_CUSTOM_LEN] = {0};
5607 u8 customid = 0x2, special_wakeup_reason = RX_MAGIC_PKT, custom_for_wakeup_reason=0x1;
5608 u8 ret = _FAIL;
5609
5610 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5611
5612 if(enable) {
5613 SET_H2CCMD_CUSTOMERID(H2CGpioCustomParm, customid);
5614 SET_H2CCMD_SPECIAL_WAKE_REASON(H2CGpioCustomParm, special_wakeup_reason);
5615 SET_H2CCMD_CUSTOM_WAKE_REASON(H2CGpioCustomParm, custom_for_wakeup_reason);
5616
5617 ret = rtw_hal_fill_h2c_cmd(adapter,
5618 H2C_GPIO_CUSTOM,
5619 H2C_GPIO_CUSTOM_LEN,
5620 H2CGpioCustomParm);
5621 RTW_DBG("%s(): H2C_cmd=%x, cmd=%02x, %02x, %02x\n", __func__, H2C_GPIO_CUSTOM,
5622 H2CGpioCustomParm[0], H2CGpioCustomParm[1], H2CGpioCustomParm[2]);
5623 }
5624
5625 return ret;
5626 }
5627 #endif /* CONFIG_CUSTOM_PULSE */
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)5628 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
5629 {
5630 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
5631 u8 adopt = 1, check_period = 5;
5632 u8 ret = _FAIL;
5633 u8 hw_port = rtw_hal_get_port(adapter);
5634
5635 SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
5636 SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
5637 SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
5638 SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
5639 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5640 SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);
5641 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5642 #else
5643 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5644 #endif
5645 ret = rtw_hal_fill_h2c_cmd(adapter,
5646 H2C_KEEP_ALIVE,
5647 H2C_KEEP_ALIVE_CTRL_LEN,
5648 u1H2CKeepAliveParm);
5649
5650 return ret;
5651 }
5652
5653 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter,u8 enable)5654 static u8 rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter, u8 enable)
5655 {
5656 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5657 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_PATTERN_LEN] = {0};
5658 u8 ret = _FAIL;
5659 int i;
5660
5661 /* If keep alive pattern is set, FW will use pattern for keep alive action */
5662 if(enable == 0 || (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_disable)) {
5663 SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _FALSE);
5664 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE);
5665 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5666 return ret;
5667 }
5668 /*step1:set keep alive period*/
5669 SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_LOW_BIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_period & 0x00FF);
5670 SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_HI_BIT(u1H2CKeepAliveParm, ((pwrctl->wowlan_keep_alive_period & 0xFF00)>> 8));
5671
5672 if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_tx) {
5673 SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5674 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE);
5675 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5676 SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5677 goto exit;
5678 }
5679 if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx) {
5680 SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5681 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE);
5682 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5683 SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5684 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index);
5685 SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval);
5686 SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter);
5687 goto exit;
5688 }
5689 if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx_with_ack) {
5690 SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5691 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE);
5692 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _TRUE);
5693 SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5694 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index);
5695 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_wake_pattern_index);
5696 SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval);
5697 SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter);
5698 goto exit;
5699 }
5700 exit:
5701 for(i=0; i<H2C_KEEP_ALIVE_PATTERN_LEN; i++) {
5702 RTW_INFO("u1H2CKeepAliveParm[%d]= x%0x\n", i, u1H2CKeepAliveParm[i]);
5703 }
5704 ret = rtw_hal_fill_h2c_cmd(adapter,
5705 H2C_UDP_KEEPALIVE,
5706 H2C_KEEP_ALIVE_PATTERN_LEN,
5707 u1H2CKeepAliveParm);
5708
5709 return ret;
5710 }
5711 #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
5712
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)5713 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
5714 {
5715 u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
5716 u8 adopt = 1, check_period = 100, trypkt_num = 5;
5717 u8 ret = _FAIL;
5718 struct registry_priv *pregistry = &adapter->registrypriv;
5719 u8 hw_port = rtw_hal_get_port(adapter);
5720
5721 SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
5722 SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
5723 if (!(pregistry->wakeup_event & BIT(2)))
5724 SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt);
5725 SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
5726 SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
5727 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5728 SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);
5729 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5730 #else
5731 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5732 #endif
5733
5734 ret = rtw_hal_fill_h2c_cmd(adapter,
5735 H2C_DISCON_DECISION,
5736 H2C_DISCON_DECISION_LEN,
5737 u1H2CDisconDecisionParm);
5738 return ret;
5739 }
5740
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)5741 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
5742 {
5743 struct registry_priv *registry_par = &adapter->registrypriv;
5744 struct security_priv *psecpriv = &adapter->securitypriv;
5745 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5746 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5747
5748 u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
5749 u8 discont_wake = 0, gpionum = 0, gpio_dur = 0, no_wake = 0;
5750 u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
5751 u8 sdio_wakeup_enable = 1;
5752 u8 gpio_high_active = 0;
5753 u8 magic_pkt = 0;
5754 u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
5755 u8 ret = _FAIL;
5756 #ifdef CONFIG_DIS_UPHY
5757 u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;
5758 #endif /* CONFIG_DIS_UPHY */
5759
5760 #ifdef CONFIG_GPIO_WAKEUP
5761 gpio_high_active = ppwrpriv->is_high_active;
5762 gpionum = ppwrpriv->wowlan_gpio_index;
5763 sdio_wakeup_enable = 0;
5764 #endif /* CONFIG_GPIO_WAKEUP */
5765
5766 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
5767 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5768 no_wake = 1;
5769
5770 if (!ppwrpriv->wowlan_pno_enable &&
5771 registry_par->wakeup_event & BIT(0) && !no_wake)
5772 magic_pkt = enable;
5773
5774 if (registry_par->wakeup_event & BIT(2) && !no_wake)
5775 discont_wake = enable;
5776
5777 RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
5778 enable, change_unit);
5779
5780 /* time = (gpio_dur/2) * gpio_unit, default:256 ms */
5781 if (enable && change_unit) {
5782 gpio_dur = 0x40;
5783 gpio_unit = 1;
5784 gpio_pulse_en = 1;
5785 }
5786
5787 #ifdef CONFIG_PLATFORM_ARM_RK3188
5788 if (enable) {
5789 gpio_pulse_en = 1;
5790 gpio_pulse_cnt = 0x04;
5791 }
5792 #endif
5793
5794 SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
5795 if(!no_wake)
5796 SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
5797 SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
5798 SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
5799 SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
5800 SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
5801
5802 #ifdef CONFIG_GTK_OL
5803 if (psecpriv->binstallKCK_KEK == _TRUE &&
5804 (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5805 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
5806 else
5807 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
5808 #else
5809 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
5810 #endif
5811 SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
5812 SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
5813 SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
5814
5815 SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
5816 SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
5817
5818 SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
5819 SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
5820
5821 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
5822 if (enable)
5823 SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5824 #endif
5825
5826 #ifdef CONFIG_DIS_UPHY
5827 if (enable) {
5828 dis_uphy = 1;
5829 /* time unit: 0 -> ms, 1 -> 256 ms*/
5830 dis_uphy_unit = 1;
5831 dis_uphy_time = 0x4;
5832 }
5833
5834 SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
5835 SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
5836 SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
5837 if (ppwrpriv->hst2dev_high_active == 1)
5838 SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
5839 #ifdef CONFIG_RTW_ONE_PIN_GPIO
5840 SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5841 SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
5842 SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
5843 #else
5844 SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
5845 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
5846 #endif /* CONFIG_DIS_UPHY */
5847
5848
5849 ret = rtw_hal_fill_h2c_cmd(adapter,
5850 H2C_WOWLAN,
5851 H2C_WOWLAN_LEN,
5852 u1H2CWoWlanCtrlParm);
5853 return ret;
5854 }
5855
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)5856 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
5857 {
5858 struct security_priv *psecuritypriv = &(adapter->securitypriv);
5859 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5860 struct registry_priv *pregistrypriv = &adapter->registrypriv;
5861 u8 arp_en = pregistrypriv->wakeup_event & BIT(3);
5862 u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
5863 u8 ret = _FAIL, count = 0, no_wake = 0;
5864 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5865
5866 RTW_INFO("%s(): enable=%d\n", __func__, enable);
5867
5868 if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&
5869 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5870 no_wake = 1;
5871 if(no_wake) {
5872 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5873 u1H2CRemoteWakeCtrlParm, enable);
5874 } else {
5875 if (!ppwrpriv->wowlan_pno_enable) {
5876 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5877 u1H2CRemoteWakeCtrlParm, enable);
5878 if (arp_en)
5879 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5880 u1H2CRemoteWakeCtrlParm, 1);
5881 else
5882 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5883 u1H2CRemoteWakeCtrlParm, 0);
5884 #ifdef CONFIG_GTK_OL
5885 if (psecuritypriv->binstallKCK_KEK == _TRUE &&
5886 (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) {
5887 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5888 u1H2CRemoteWakeCtrlParm, 1);
5889 } else {
5890 RTW_INFO("no kck kek\n");
5891 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5892 u1H2CRemoteWakeCtrlParm, 0);
5893 }
5894 #endif /* CONFIG_GTK_OL */
5895
5896 #ifdef CONFIG_IPV6
5897 if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
5898 RTW_INFO("enable NS offload\n");
5899 SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
5900 u1H2CRemoteWakeCtrlParm, enable);
5901 }
5902
5903 /*
5904 * filter NetBios name service pkt to avoid being waked-up
5905 * by this kind of unicast pkt this exceptional modification
5906 * is used for match competitor's behavior
5907 */
5908
5909 SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
5910 u1H2CRemoteWakeCtrlParm, enable);
5911 #endif /*CONFIG_IPV6*/
5912 #if 0 /* replaced by WOWLAN pattern match */
5913 #ifdef CONFIG_RTL8192F
5914 if (IS_HARDWARE_TYPE_8192F(adapter)){
5915 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
5916 u1H2CRemoteWakeCtrlParm, enable);
5917 }
5918 #endif /* CONFIG_RTL8192F */
5919 #endif
5920 if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
5921 (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
5922 (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
5923 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5924 u1H2CRemoteWakeCtrlParm, 0);
5925 } else { /* WEP etc. */
5926 if (arp_en)
5927 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5928 u1H2CRemoteWakeCtrlParm, 1);
5929 }
5930
5931 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
5932 #ifdef CONFIG_GTK_OL
5933 if(_rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))
5934 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5935 u1H2CRemoteWakeCtrlParm, enable);
5936 #endif /* CONFIG_GTK_OL */
5937 if (IS_HARDWARE_TYPE_8188E(adapter) ||
5938 IS_HARDWARE_TYPE_8812(adapter)) {
5939 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5940 u1H2CRemoteWakeCtrlParm, 0);
5941 if (arp_en)
5942 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5943 u1H2CRemoteWakeCtrlParm, 1);
5944 }
5945 }
5946
5947 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
5948 u1H2CRemoteWakeCtrlParm, 1);
5949 }
5950 #ifdef CONFIG_PNO_SUPPORT
5951 else {
5952 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5953 u1H2CRemoteWakeCtrlParm, enable);
5954 SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
5955 u1H2CRemoteWakeCtrlParm, enable);
5956 }
5957 #endif
5958
5959 #ifdef CONFIG_P2P_WOWLAN
5960 if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
5961 RTW_INFO("P2P OFFLOAD ENABLE\n");
5962 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
5963 } else {
5964 RTW_INFO("P2P OFFLOAD DISABLE\n");
5965 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
5966 }
5967 #endif /* CONFIG_P2P_WOWLAN */
5968 }
5969
5970
5971 ret = rtw_hal_fill_h2c_cmd(adapter,
5972 H2C_REMOTE_WAKE_CTRL,
5973 H2C_REMOTE_WAKE_CTRL_LEN,
5974 u1H2CRemoteWakeCtrlParm);
5975 return ret;
5976 }
5977
5978 #ifdef CONFIG_WAR_OFFLOAD
rtw_hal_set_war_offload_ctrl_cmd(_adapter * adapter,u8 enable)5979 static u8 rtw_hal_set_war_offload_ctrl_cmd(_adapter *adapter, u8 enable)
5980 {
5981 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5982 u8 u1H2CWarOffloadParm[H2C_WAR_OFFLOAD_LEN] = {0};
5983 u8 ret = _FAIL;
5984
5985 RTW_INFO("%s(): enable=%d\n", __func__, enable);
5986
5987 if (_TRUE == ppwrpriv->wowlan_war_offload_mode) {
5988 SET_H2CCMD_WAR_CFG_EN(u1H2CWarOffloadParm, enable);
5989 SET_H2CCMD_WAR_CFG_ARP_RSP_EN(u1H2CWarOffloadParm, 1);
5990
5991 #ifdef CONFIG_OFFLOAD_MDNS_V4
5992 if (WAR_MDNS_V4_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
5993 SET_H2CCMD_WAR_CFG_MDNSV4_RSP_EN(u1H2CWarOffloadParm, 1);
5994 }
5995 if (WAR_MDNS_V4_WAKEUP_EN& ppwrpriv->wowlan_war_offload_ctrl) {
5996 SET_H2CCMD_WAR_CFG_MDNSV4_WAKE_EN(u1H2CWarOffloadParm, 1);
5997 }
5998 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
5999
6000 #ifdef CONFIG_OFFLOAD_MDNS_V6
6001 if (WAR_MDNS_V6_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
6002 SET_H2CCMD_WAR_CFG_MDNSV6_RSP_EN(u1H2CWarOffloadParm, 1);
6003 }
6004 if (WAR_MDNS_V6_WAKEUP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
6005 SET_H2CCMD_WAR_CFG_MDNSV6_WAKE_EN(u1H2CWarOffloadParm, 1);
6006 }
6007 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
6008
6009 }
6010
6011 ret = rtw_hal_fill_h2c_cmd(adapter,
6012 H2C_WAR_OFFLOAD,
6013 H2C_WAR_OFFLOAD_LEN,
6014 u1H2CWarOffloadParm);
6015 return ret;
6016 }
6017
rtw_hal_set_war_offload_parm(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)6018 static u8 rtw_hal_set_war_offload_parm(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
6019 {
6020 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6021 u8 u1H2CWarOfldParm[H2C_WAROFLD_RSVDPAGE1_LEN] = {0};
6022 u8 ret = _FAIL;
6023
6024 SET_H2CCMD_WAROFLD_RSVDPAGE1_LOC_PARM(u1H2CWarOfldParm, rsvdpageloc->LocIpParm);
6025 RTW_INFO("%s(): LocIpParm = %d\n", __func__, rsvdpageloc->LocIpParm);
6026
6027
6028 ret = rtw_hal_fill_h2c_cmd(adapter,
6029 H2C_WAROFLD_RSVDPAGE1,
6030 H2C_WAROFLD_RSVDPAGE1_LEN,
6031 u1H2CWarOfldParm);
6032
6033 return ret;
6034 }
6035 #endif /* CONFIG_WAR_OFFLOAD */
6036
6037
6038
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)6039 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
6040 {
6041 u8 ret = _FAIL;
6042 u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
6043
6044 RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
6045 __func__, group_alg, pairwise_alg);
6046 SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
6047 pairwise_alg);
6048 SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
6049 group_alg);
6050
6051 ret = rtw_hal_fill_h2c_cmd(adapter,
6052 H2C_AOAC_GLOBAL_INFO,
6053 H2C_AOAC_GLOBAL_INFO_LEN,
6054 u1H2CAOACGlobalInfoParm);
6055
6056 return ret;
6057 }
6058
6059 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)6060 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
6061 PRSVDPAGE_LOC rsvdpageloc, u8 enable)
6062 {
6063 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6064 u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
6065 u8 res = 0, count = 0, ret = _FAIL;
6066
6067 RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
6068 __func__, rsvdpageloc->LocProbePacket,
6069 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
6070
6071 SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
6072 SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
6073 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
6074 rsvdpageloc->LocScanInfo);
6075 SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
6076 rsvdpageloc->LocProbePacket);
6077 /*
6078 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
6079 rsvdpageloc->LocSSIDInfo);
6080 */
6081 ret = rtw_hal_fill_h2c_cmd(adapter,
6082 H2C_D0_SCAN_OFFLOAD_INFO,
6083 H2C_SCAN_OFFLOAD_CTRL_LEN,
6084 u1H2CScanOffloadInfoParm);
6085 return ret;
6086 }
6087 #endif /* CONFIG_PNO_SUPPORT */
6088
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)6089 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
6090 {
6091 struct security_priv *psecpriv = &padapter->securitypriv;
6092 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
6093 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6094 struct registry_priv *pregistry = &padapter->registrypriv;
6095 u8 pkt_type = 0, no_wake = 0;
6096
6097 if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&
6098 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
6099 no_wake = 1;
6100
6101 RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
6102
6103 rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
6104
6105 if (enable) {
6106 if(!no_wake)
6107 rtw_hal_set_global_info_cmd(padapter,
6108 psecpriv->dot118021XGrpPrivacy,
6109 psecpriv->dot11PrivacyAlgrthm);
6110
6111 if (!(ppwrpriv->wowlan_pno_enable)) {
6112 if (!no_wake)
6113 rtw_hal_set_disconnect_decision_cmd(padapter,
6114 enable);
6115 #ifdef CONFIG_ARP_KEEP_ALIVE
6116 if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
6117 (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
6118 pkt_type = 0;
6119 else
6120 pkt_type = 1;
6121 #else
6122 pkt_type = 0;
6123 #endif /* CONFIG_ARP_KEEP_ALIVE */
6124 if(!no_wake) {
6125 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
6126 rtw_hal_set_keep_alive_pattern_cmd(padapter,enable);
6127 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
6128 rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
6129 }
6130 }
6131 #ifdef CONFIG_PNO_SUPPORT
6132 rtw_hal_check_pno_enabled(padapter);
6133 #endif /* CONFIG_PNO_SUPPORT */
6134 #ifdef CONFIG_WAR_OFFLOAD
6135 rtw_hal_set_war_offload_ctrl_cmd(padapter, enable);
6136 #endif /* CONFIG_WAR_OFFLOAD */
6137
6138 } else {
6139 #if 0
6140 {
6141 u32 PageSize = 0;
6142 rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
6143 dump_TX_FIFO(padapter, 4, PageSize);
6144 }
6145 #endif
6146 }
6147 #ifdef CONFIG_CUSTOM_PULSE
6148 rtw_hal_set_gpio_custom_cmd(padapter, enable);
6149 #endif /* CONFIG_CUSTOM_PULSE */
6150 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
6151 RTW_PRINT("-%s()-\n", __func__);
6152 }
6153 #endif /* CONFIG_WOWLAN */
6154
6155 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)6156 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
6157 {
6158 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6159
6160 u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
6161 u8 gpionum = 0, gpio_dur = 0;
6162 u8 gpio_pulse = enable;
6163 u8 sdio_wakeup_enable = 1;
6164 u8 gpio_high_active = 0;
6165 u8 ret = _FAIL;
6166
6167 #ifdef CONFIG_GPIO_WAKEUP
6168 gpio_high_active = ppwrpriv->is_high_active;
6169 gpionum = ppwrpriv->wowlan_gpio_index;
6170 sdio_wakeup_enable = 0;
6171 #endif /*CONFIG_GPIO_WAKEUP*/
6172
6173 RTW_INFO("%s(): enable=%d\n", __func__, enable);
6174
6175 SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
6176 gpionum);
6177 SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
6178 gpio_pulse);
6179 SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
6180 gpio_high_active);
6181 SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
6182 enable);
6183 SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
6184 gpio_dur);
6185
6186 ret = rtw_hal_fill_h2c_cmd(adapter,
6187 H2C_AP_WOW_GPIO_CTRL,
6188 H2C_AP_WOW_GPIO_CTRL_LEN,
6189 u1H2CAPWoWlanCtrlParm);
6190
6191 return ret;
6192 }
6193
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)6194 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6195 {
6196 u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
6197 u8 ret = _FAIL;
6198
6199 RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
6200
6201 SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
6202
6203 ret = rtw_hal_fill_h2c_cmd(adapter,
6204 H2C_AP_OFFLOAD,
6205 H2C_AP_OFFLOAD_LEN,
6206 u1H2CAPOffloadCtrlParm);
6207
6208 return ret;
6209 }
6210
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)6211 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
6212 {
6213 u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
6214 u8 ret = _FAIL;
6215
6216 RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
6217
6218 SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
6219 #ifndef CONFIG_USB_HCI
6220 SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
6221 #endif /*CONFIG_USB_HCI*/
6222 SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
6223
6224 if (enable)
6225 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
6226 else
6227 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
6228
6229 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
6230 H2C_AP_PS_LEN, ap_ps_parm);
6231
6232 return ret;
6233 }
6234
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)6235 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
6236 PRSVDPAGE_LOC rsvdpageloc)
6237 {
6238 struct hal_ops *pHalFunc = &padapter->hal_func;
6239 u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
6240 u8 ret = _FAIL, header = 0;
6241
6242 if (pHalFunc->fill_h2c_cmd == NULL) {
6243 RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
6244 return;
6245 }
6246
6247 header = rtw_read8(padapter, REG_BCNQ_BDNY);
6248
6249 RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
6250 rsvdpageloc->LocApOffloadBCN,
6251 rsvdpageloc->LocProbeRsp,
6252 header);
6253
6254 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
6255 rsvdpageloc->LocApOffloadBCN + header);
6256
6257 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
6258 H2C_BCN_RSVDPAGE_LEN, rsvdparm);
6259
6260 if (ret == _FAIL)
6261 RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
6262
6263 rtw_msleep_os(10);
6264
6265 _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
6266
6267 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
6268 rsvdpageloc->LocProbeRsp + header);
6269
6270 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
6271 H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
6272
6273 if (ret == _FAIL)
6274 RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
6275
6276 rtw_msleep_os(10);
6277 }
6278
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)6279 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
6280 {
6281 rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
6282 rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
6283 rtw_hal_set_ap_ps_cmd(padapter, enable);
6284 }
6285
rtw_hal_ap_wow_enable(_adapter * padapter)6286 static void rtw_hal_ap_wow_enable(_adapter *padapter)
6287 {
6288 struct security_priv *psecuritypriv = &padapter->securitypriv;
6289 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6290 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6291 struct sta_info *psta = NULL;
6292 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6293 #ifdef DBG_CHECK_FW_PS_STATE
6294 struct dvobj_priv *psdpriv = padapter->dvobj;
6295 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6296 #endif /*DBG_CHECK_FW_PS_STATE*/
6297 int res;
6298 u16 media_status_rpt;
6299 #ifdef CONFIG_GPIO_WAKEUP
6300 u8 val8 = 0;
6301 #endif
6302
6303 RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
6304 #ifdef DBG_CHECK_FW_PS_STATE
6305 if (rtw_fw_ps_state(padapter) == _FAIL) {
6306 pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
6307 RTW_PRINT("wowlan enable no leave 32k\n");
6308 }
6309 #endif /*DBG_CHECK_FW_PS_STATE*/
6310
6311 /* 1. Download WOWLAN FW*/
6312 rtw_hal_fw_dl(padapter, _TRUE);
6313
6314 media_status_rpt = RT_MEDIA_CONNECT;
6315 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6316 (u8 *)&media_status_rpt);
6317
6318 issue_beacon(padapter, 0);
6319
6320 rtw_msleep_os(2);
6321 #if defined(CONFIG_RTL8188E)
6322 if (IS_HARDWARE_TYPE_8188E(padapter))
6323 rtw_hal_disable_tx_report(padapter);
6324 #endif
6325 /* RX DMA stop */
6326 res = rtw_hal_pause_rx_dma(padapter);
6327 if (res == _FAIL)
6328 RTW_PRINT("[WARNING] pause RX DMA fail\n");
6329
6330 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6331 /* Enable CPWM2 only. */
6332 res = rtw_hal_enable_cpwm2(padapter);
6333 if (res == _FAIL)
6334 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6335 #endif
6336
6337 #ifdef CONFIG_GPIO_WAKEUP
6338 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6339 rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6340 rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6341 #else
6342 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6343 if (pwrctrlpriv->is_high_active == 0)
6344 rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6345 else
6346 rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index,
6347 GPIO_OUTPUT_LOW);
6348 #else
6349 val8 = (pwrpriv->is_high_active == 0) ? 1 : 0;
6350 rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8);
6351 rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6352 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow suspend and %s_ACTIVE.\n",
6353 __func__, pwrpriv->wowlan_gpio_index,
6354 pwrpriv->wowlan_gpio_output_state ? "HIGH" : "LOW",
6355 pwrpriv->is_high_active ? "HIGI" : "LOW");
6356 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
6357 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6358 #endif /* CONFIG_GPIO_WAKEUP */
6359
6360 /* 5. Set Enable WOWLAN H2C command. */
6361 RTW_PRINT("Set Enable AP WOWLan cmd\n");
6362 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
6363
6364 rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
6365 #ifdef CONFIG_USB_HCI
6366 rtw_mi_intf_stop(padapter);
6367 #endif
6368 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
6369 /* Invoid SE0 reset signal during suspending*/
6370 rtw_write8(padapter, REG_RSV_CTRL, 0x20);
6371 if (IS_8188F(pHalData->version_id) == FALSE
6372 && IS_8188GTV(pHalData->version_id) == FALSE)
6373 rtw_write8(padapter, REG_RSV_CTRL, 0x60);
6374 #endif
6375 }
6376
rtw_hal_ap_wow_disable(_adapter * padapter)6377 static void rtw_hal_ap_wow_disable(_adapter *padapter)
6378 {
6379 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6380 #ifdef DBG_CHECK_FW_PS_STATE
6381 struct dvobj_priv *psdpriv = padapter->dvobj;
6382 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6383 #endif /*DBG_CHECK_FW_PS_STATE*/
6384 u16 media_status_rpt;
6385
6386 RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
6387 /* 1. Read wakeup reason*/
6388 pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
6389
6390 RTW_PRINT("wakeup_reason: 0x%02x\n",
6391 pwrctl->wowlan_wake_reason);
6392
6393 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
6394
6395 rtw_msleep_os(2);
6396 #ifdef DBG_CHECK_FW_PS_STATE
6397 if (rtw_fw_ps_state(padapter) == _FAIL) {
6398 pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
6399 RTW_PRINT("wowlan enable no leave 32k\n");
6400 }
6401 #endif /*DBG_CHECK_FW_PS_STATE*/
6402
6403 #if defined(CONFIG_RTL8188E)
6404 if (IS_HARDWARE_TYPE_8188E(padapter))
6405 rtw_hal_enable_tx_report(padapter);
6406 #endif
6407
6408 rtw_hal_force_enable_rxdma(padapter);
6409
6410 rtw_hal_fw_dl(padapter, _FALSE);
6411
6412 #ifdef CONFIG_GPIO_WAKEUP
6413 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6414 rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6415 #else
6416 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6417 if (pwrctl->is_high_active == 0)
6418 rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6419 else
6420 rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index
6421 , GPIO_OUTPUT_LOW);
6422 #else
6423 rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index,
6424 pwrctl->wowlan_gpio_output_state);
6425 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow resume and %s_ACTIVE.\n",
6426 __func__, pwrctl->wowlan_gpio_index,
6427 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
6428 pwrctl->is_high_active ? "HIGI" : "LOW");
6429 #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
6430 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6431 #endif /* CONFIG_GPIO_WAKEUP */
6432 media_status_rpt = RT_MEDIA_CONNECT;
6433
6434 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6435 (u8 *)&media_status_rpt);
6436
6437 issue_beacon(padapter, 0);
6438 }
6439 #endif /*CONFIG_AP_WOWLAN*/
6440
6441 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)6442 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
6443 {
6444 u8 *ssid_ie;
6445 sint ssid_len_ori;
6446 int len_diff = 0;
6447
6448 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
6449
6450 /* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
6451
6452 if (ssid_ie && ssid_len_ori > 0) {
6453 switch (hidden_ssid_mode) {
6454 case 1: {
6455 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
6456 u32 remain_len = 0;
6457
6458 remain_len = ies_len - (next_ie - ies);
6459
6460 ssid_ie[1] = 0;
6461 _rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
6462 len_diff -= ssid_len_ori;
6463
6464 break;
6465 }
6466 case 2:
6467 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
6468 break;
6469 default:
6470 break;
6471 }
6472 }
6473
6474 return len_diff;
6475 }
6476
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)6477 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
6478 {
6479 /* struct xmit_frame *pmgntframe; */
6480 /* struct pkt_attrib *pattrib; */
6481 /* unsigned char *pframe; */
6482 struct rtw_ieee80211_hdr *pwlanhdr;
6483 unsigned short *fctrl;
6484 unsigned int rate_len;
6485 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6486 u32 pktlen;
6487 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6488 /* _irqL irqL;
6489 * struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6490 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6491 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6492 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6493 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6494 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
6495 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6496 #ifdef CONFIG_P2P
6497 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6498 #endif /* CONFIG_P2P */
6499
6500 /* for debug */
6501 u8 *dbgbuf = pframe;
6502 u8 dbgbufLen = 0, index = 0;
6503
6504 RTW_INFO("%s\n", __FUNCTION__);
6505 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6506 /* _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6507 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6508
6509 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6510
6511
6512 fctrl = &(pwlanhdr->frame_ctl);
6513 *(fctrl) = 0;
6514
6515 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6516 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6517 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6518
6519 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6520 /* pmlmeext->mgnt_seq++; */
6521 set_frame_sub_type(pframe, WIFI_BEACON);
6522
6523 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6524 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6525
6526 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6527 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6528 #ifdef CONFIG_P2P
6529 /* for P2P : Primary Device Type & Device Name */
6530 u32 wpsielen = 0, insert_len = 0;
6531 u8 *wpsie = NULL;
6532 wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
6533
6534 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
6535 uint wps_offset, remainder_ielen;
6536 u8 *premainder_ie, *pframe_wscie;
6537
6538 wps_offset = (uint)(wpsie - cur_network->IEs);
6539
6540 premainder_ie = wpsie + wpsielen;
6541
6542 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6543
6544 #ifdef CONFIG_IOCTL_CFG80211
6545 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6546 if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
6547 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
6548 pframe += wps_offset;
6549 pktlen += wps_offset;
6550
6551 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6552 pframe += pmlmepriv->wps_beacon_ie_len;
6553 pktlen += pmlmepriv->wps_beacon_ie_len;
6554
6555 /* copy remainder_ie to pframe */
6556 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6557 pframe += remainder_ielen;
6558 pktlen += remainder_ielen;
6559 } else {
6560 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6561 pframe += cur_network->IELength;
6562 pktlen += cur_network->IELength;
6563 }
6564 } else
6565 #endif /* CONFIG_IOCTL_CFG80211 */
6566 {
6567 pframe_wscie = pframe + wps_offset;
6568 _rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
6569 pframe += (wps_offset + wpsielen);
6570 pktlen += (wps_offset + wpsielen);
6571
6572 /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6573 /* Primary Device Type */
6574 /* Type: */
6575 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6576 insert_len += 2;
6577
6578 /* Length: */
6579 *(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
6580 insert_len += 2;
6581
6582 /* Value: */
6583 /* Category ID */
6584 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6585 insert_len += 2;
6586
6587 /* OUI */
6588 *(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
6589 insert_len += 4;
6590
6591 /* Sub Category ID */
6592 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6593 insert_len += 2;
6594
6595
6596 /* Device Name */
6597 /* Type: */
6598 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6599 insert_len += 2;
6600
6601 /* Length: */
6602 *(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
6603 insert_len += 2;
6604
6605 /* Value: */
6606 _rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
6607 insert_len += pwdinfo->device_name_len;
6608
6609
6610 /* update wsc ie length */
6611 *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
6612
6613 /* pframe move to end */
6614 pframe += insert_len;
6615 pktlen += insert_len;
6616
6617 /* copy remainder_ie to pframe */
6618 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6619 pframe += remainder_ielen;
6620 pktlen += remainder_ielen;
6621 }
6622 } else
6623 #endif /* CONFIG_P2P */
6624 {
6625 int len_diff;
6626 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6627 len_diff = update_hidden_ssid(
6628 pframe + _BEACON_IE_OFFSET_
6629 , cur_network->IELength - _BEACON_IE_OFFSET_
6630 , pmlmeinfo->hidden_ssid_mode
6631 );
6632 pframe += (cur_network->IELength + len_diff);
6633 pktlen += (cur_network->IELength + len_diff);
6634 }
6635 #if 0
6636 {
6637 u8 *wps_ie;
6638 uint wps_ielen;
6639 u8 sr = 0;
6640 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
6641 pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
6642 if (wps_ie && wps_ielen > 0)
6643 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6644 if (sr != 0)
6645 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6646 else
6647 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6648 }
6649 #endif
6650 #ifdef CONFIG_P2P
6651 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6652 u32 len;
6653 #ifdef CONFIG_IOCTL_CFG80211
6654 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6655 len = pmlmepriv->p2p_beacon_ie_len;
6656 if (pmlmepriv->p2p_beacon_ie && len > 0)
6657 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6658 } else
6659 #endif /* CONFIG_IOCTL_CFG80211 */
6660 {
6661 len = build_beacon_p2p_ie(pwdinfo, pframe);
6662 }
6663
6664 pframe += len;
6665 pktlen += len;
6666
6667 #ifdef CONFIG_WFD
6668 len = rtw_append_beacon_wfd_ie(padapter, pframe);
6669 pframe += len;
6670 pktlen += len;
6671 #endif
6672
6673 }
6674 #endif /* CONFIG_P2P */
6675
6676 goto _issue_bcn;
6677
6678 }
6679
6680 /* below for ad-hoc mode */
6681
6682 /* timestamp will be inserted by hardware */
6683 pframe += 8;
6684 pktlen += 8;
6685
6686 /* beacon interval: 2 bytes */
6687
6688 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6689
6690 pframe += 2;
6691 pktlen += 2;
6692
6693 /* capability info: 2 bytes */
6694
6695 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6696
6697 pframe += 2;
6698 pktlen += 2;
6699
6700 /* SSID */
6701 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6702
6703 /* supported rates... */
6704 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6705 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6706
6707 /* DS parameter set */
6708 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6709
6710 /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6711 {
6712 u8 erpinfo = 0;
6713 u32 ATIMWindow;
6714 /* IBSS Parameter Set... */
6715 /* ATIMWindow = cur->Configuration.ATIMWindow; */
6716 ATIMWindow = 0;
6717 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6718
6719 /* ERP IE */
6720 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
6721 }
6722
6723
6724 /* EXTERNDED SUPPORTED RATE */
6725 if (rate_len > 8)
6726 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6727
6728
6729 /* todo:HT for adhoc */
6730
6731 _issue_bcn:
6732
6733 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6734 /* pmlmepriv->update_bcn = _FALSE;
6735 *
6736 * _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6737 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6738
6739 *pLength = pktlen;
6740 #if 0
6741 /* printf dbg msg */
6742 dbgbufLen = pktlen;
6743 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6744
6745 for (index = 0; index < dbgbufLen; index++)
6746 printk("%x ", *(dbgbuf + index));
6747
6748 printk("\n");
6749 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6750
6751 #endif
6752 }
6753
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6754 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6755 {
6756 /* struct xmit_frame *pmgntframe; */
6757 /* struct pkt_attrib *pattrib; */
6758 /* unsigned char *pframe; */
6759 struct rtw_ieee80211_hdr *pwlanhdr;
6760 unsigned short *fctrl;
6761 unsigned char *mac;
6762 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6763 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6764 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6765 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6766 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
6767 u16 beacon_interval = 100;
6768 u16 capInfo = 0;
6769 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6770 u8 wpsie[255] = { 0x00 };
6771 u32 wpsielen = 0, p2pielen = 0;
6772 u32 pktlen;
6773 #ifdef CONFIG_WFD
6774 u32 wfdielen = 0;
6775 #endif
6776
6777 /* for debug */
6778 u8 *dbgbuf = pframe;
6779 u8 dbgbufLen = 0, index = 0;
6780
6781 RTW_INFO("%s\n", __FUNCTION__);
6782 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6783
6784 mac = adapter_mac_addr(padapter);
6785
6786 fctrl = &(pwlanhdr->frame_ctl);
6787 *(fctrl) = 0;
6788
6789 /* DA filled by FW */
6790 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6791 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6792
6793 /* Use the device address for BSSID field. */
6794 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6795
6796 SetSeqNum(pwlanhdr, 0);
6797 set_frame_sub_type(fctrl, WIFI_PROBERSP);
6798
6799 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6800 pframe += pktlen;
6801
6802
6803 /* timestamp will be inserted by hardware */
6804 pframe += 8;
6805 pktlen += 8;
6806
6807 /* beacon interval: 2 bytes */
6808 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6809 pframe += 2;
6810 pktlen += 2;
6811
6812 /* capability info: 2 bytes */
6813 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6814 capInfo |= cap_ShortPremble;
6815 capInfo |= cap_ShortSlot;
6816
6817 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6818 pframe += 2;
6819 pktlen += 2;
6820
6821
6822 /* SSID */
6823 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
6824
6825 /* supported rates... */
6826 /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6827 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
6828
6829 /* DS parameter set */
6830 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
6831
6832 #ifdef CONFIG_IOCTL_CFG80211
6833 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6834 if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6835 /* WPS IE */
6836 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6837 pktlen += pmlmepriv->wps_probe_resp_ie_len;
6838 pframe += pmlmepriv->wps_probe_resp_ie_len;
6839
6840 /* P2P IE */
6841 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6842 pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6843 pframe += pmlmepriv->p2p_probe_resp_ie_len;
6844 }
6845 } else
6846 #endif /* CONFIG_IOCTL_CFG80211 */
6847 {
6848
6849 /* Todo: WPS IE */
6850 /* Noted by Albert 20100907 */
6851 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6852
6853 wpsielen = 0;
6854 /* WPS OUI */
6855 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6856 wpsielen += 4;
6857
6858 /* WPS version */
6859 /* Type: */
6860 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6861 wpsielen += 2;
6862
6863 /* Length: */
6864 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6865 wpsielen += 2;
6866
6867 /* Value: */
6868 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
6869
6870 /* WiFi Simple Config State */
6871 /* Type: */
6872 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6873 wpsielen += 2;
6874
6875 /* Length: */
6876 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6877 wpsielen += 2;
6878
6879 /* Value: */
6880 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
6881
6882 /* Response Type */
6883 /* Type: */
6884 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6885 wpsielen += 2;
6886
6887 /* Length: */
6888 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6889 wpsielen += 2;
6890
6891 /* Value: */
6892 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6893
6894 /* UUID-E */
6895 /* Type: */
6896 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6897 wpsielen += 2;
6898
6899 /* Length: */
6900 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6901 wpsielen += 2;
6902
6903 /* Value: */
6904 if (pwdinfo->external_uuid == 0) {
6905 _rtw_memset(wpsie + wpsielen, 0x0, 16);
6906 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6907 } else
6908 _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6909 wpsielen += 0x10;
6910
6911 /* Manufacturer */
6912 /* Type: */
6913 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6914 wpsielen += 2;
6915
6916 /* Length: */
6917 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6918 wpsielen += 2;
6919
6920 /* Value: */
6921 _rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6922 wpsielen += 7;
6923
6924 /* Model Name */
6925 /* Type: */
6926 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
6927 wpsielen += 2;
6928
6929 /* Length: */
6930 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
6931 wpsielen += 2;
6932
6933 /* Value: */
6934 _rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
6935 wpsielen += 6;
6936
6937 /* Model Number */
6938 /* Type: */
6939 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
6940 wpsielen += 2;
6941
6942 /* Length: */
6943 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6944 wpsielen += 2;
6945
6946 /* Value: */
6947 wpsie[wpsielen++] = 0x31; /* character 1 */
6948
6949 /* Serial Number */
6950 /* Type: */
6951 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
6952 wpsielen += 2;
6953
6954 /* Length: */
6955 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
6956 wpsielen += 2;
6957
6958 /* Value: */
6959 _rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
6960 wpsielen += ETH_ALEN;
6961
6962 /* Primary Device Type */
6963 /* Type: */
6964 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6965 wpsielen += 2;
6966
6967 /* Length: */
6968 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6969 wpsielen += 2;
6970
6971 /* Value: */
6972 /* Category ID */
6973 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6974 wpsielen += 2;
6975
6976 /* OUI */
6977 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6978 wpsielen += 4;
6979
6980 /* Sub Category ID */
6981 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6982 wpsielen += 2;
6983
6984 /* Device Name */
6985 /* Type: */
6986 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6987 wpsielen += 2;
6988
6989 /* Length: */
6990 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
6991 wpsielen += 2;
6992
6993 /* Value: */
6994 _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
6995 wpsielen += pwdinfo->device_name_len;
6996
6997 /* Config Method */
6998 /* Type: */
6999 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
7000 wpsielen += 2;
7001
7002 /* Length: */
7003 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7004 wpsielen += 2;
7005
7006 /* Value: */
7007 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7008 wpsielen += 2;
7009
7010
7011 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7012
7013
7014 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
7015 pframe += p2pielen;
7016 pktlen += p2pielen;
7017 }
7018
7019 #ifdef CONFIG_WFD
7020 wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
7021 pframe += wfdielen;
7022 pktlen += wfdielen;
7023 #endif
7024
7025 *pLength = pktlen;
7026
7027 #if 0
7028 /* printf dbg msg */
7029 dbgbufLen = pktlen;
7030 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7031
7032 for (index = 0; index < dbgbufLen; index++)
7033 printk("%x ", *(dbgbuf + index));
7034
7035 printk("\n");
7036 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7037 #endif
7038 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7039 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7040 {
7041 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7042 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7043 u8 action = P2P_PUB_ACTION_ACTION;
7044 u32 p2poui = cpu_to_be32(P2POUI);
7045 u8 oui_subtype = P2P_GO_NEGO_RESP;
7046 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
7047 u8 p2pielen = 0, i;
7048 uint wpsielen = 0;
7049 u16 wps_devicepassword_id = 0x0000;
7050 uint wps_devicepassword_id_len = 0;
7051 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
7052 u16 len_channellist_attr = 0;
7053 u32 pktlen;
7054 u8 dialogToken = 0;
7055
7056 /* struct xmit_frame *pmgntframe; */
7057 /* struct pkt_attrib *pattrib; */
7058 /* unsigned char *pframe; */
7059 struct rtw_ieee80211_hdr *pwlanhdr;
7060 unsigned short *fctrl;
7061 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7062 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7063 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7064 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7065 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
7066
7067 #ifdef CONFIG_WFD
7068 u32 wfdielen = 0;
7069 #endif
7070
7071 /* for debug */
7072 u8 *dbgbuf = pframe;
7073 u8 dbgbufLen = 0, index = 0;
7074
7075 RTW_INFO("%s\n", __FUNCTION__);
7076 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7077
7078 fctrl = &(pwlanhdr->frame_ctl);
7079 *(fctrl) = 0;
7080
7081 /* RA, filled by FW */
7082 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7083 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7084 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7085
7086 SetSeqNum(pwlanhdr, 0);
7087 set_frame_sub_type(pframe, WIFI_ACTION);
7088
7089 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7090 pframe += pktlen;
7091
7092 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7093 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7094 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7095 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7096
7097 /* dialog token, filled by FW */
7098 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7099
7100 _rtw_memset(wpsie, 0x00, 255);
7101 wpsielen = 0;
7102
7103 /* WPS Section */
7104 wpsielen = 0;
7105 /* WPS OUI */
7106 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
7107 wpsielen += 4;
7108
7109 /* WPS version */
7110 /* Type: */
7111 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7112 wpsielen += 2;
7113
7114 /* Length: */
7115 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7116 wpsielen += 2;
7117
7118 /* Value: */
7119 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7120
7121 /* Device Password ID */
7122 /* Type: */
7123 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
7124 wpsielen += 2;
7125
7126 /* Length: */
7127 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7128 wpsielen += 2;
7129
7130 /* Value: */
7131 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
7132 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
7133 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
7134 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
7135 else
7136 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
7137 wpsielen += 2;
7138
7139 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7140
7141
7142 /* P2P IE Section. */
7143
7144 /* P2P OUI */
7145 p2pielen = 0;
7146 p2pie[p2pielen++] = 0x50;
7147 p2pie[p2pielen++] = 0x6F;
7148 p2pie[p2pielen++] = 0x9A;
7149 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7150
7151 /* Commented by Albert 20100908 */
7152 /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
7153 /* 1. Status */
7154 /* 2. P2P Capability */
7155 /* 3. Group Owner Intent */
7156 /* 4. Configuration Timeout */
7157 /* 5. Operating Channel */
7158 /* 6. Intended P2P Interface Address */
7159 /* 7. Channel List */
7160 /* 8. Device Info */
7161 /* 9. Group ID ( Only GO ) */
7162
7163
7164 /* ToDo: */
7165
7166 /* P2P Status */
7167 /* Type: */
7168 p2pie[p2pielen++] = P2P_ATTR_STATUS;
7169
7170 /* Length: */
7171 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7172 p2pielen += 2;
7173
7174 /* Value, filled by FW */
7175 p2pie[p2pielen++] = 1;
7176
7177 /* P2P Capability */
7178 /* Type: */
7179 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
7180
7181 /* Length: */
7182 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7183 p2pielen += 2;
7184
7185 /* Value: */
7186 /* Device Capability Bitmap, 1 byte */
7187
7188 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
7189 /* Commented by Albert 2011/03/08 */
7190 /* According to the P2P specification */
7191 /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
7192 p2pie[p2pielen++] = 0;
7193 } else {
7194 /* Be group owner or meet the error case */
7195 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
7196 }
7197
7198 /* Group Capability Bitmap, 1 byte */
7199 if (pwdinfo->persistent_supported)
7200 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
7201 else
7202 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
7203
7204 /* Group Owner Intent */
7205 /* Type: */
7206 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
7207
7208 /* Length: */
7209 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7210 p2pielen += 2;
7211
7212 /* Value: */
7213 if (pwdinfo->peer_intent & 0x01) {
7214 /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
7215 p2pie[p2pielen++] = (pwdinfo->intent << 1);
7216 } else {
7217 /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
7218 p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
7219 }
7220
7221
7222 /* Configuration Timeout */
7223 /* Type: */
7224 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7225
7226 /* Length: */
7227 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7228 p2pielen += 2;
7229
7230 /* Value: */
7231 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7232 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7233
7234 /* Operating Channel */
7235 /* Type: */
7236 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7237
7238 /* Length: */
7239 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7240 p2pielen += 2;
7241
7242 /* Value: */
7243 /* Country String */
7244 p2pie[p2pielen++] = 'X';
7245 p2pie[p2pielen++] = 'X';
7246
7247 /* The third byte should be set to 0x04. */
7248 /* Described in the "Operating Channel Attribute" section. */
7249 p2pie[p2pielen++] = 0x04;
7250
7251 /* Operating Class */
7252 if (pwdinfo->operating_channel <= 14) {
7253 /* Operating Class */
7254 p2pie[p2pielen++] = 0x51;
7255 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
7256 /* Operating Class */
7257 p2pie[p2pielen++] = 0x73;
7258 } else {
7259 /* Operating Class */
7260 p2pie[p2pielen++] = 0x7c;
7261 }
7262
7263 /* Channel Number */
7264 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7265
7266 /* Intended P2P Interface Address */
7267 /* Type: */
7268 p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
7269
7270 /* Length: */
7271 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7272 p2pielen += 2;
7273
7274 /* Value: */
7275 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7276 p2pielen += ETH_ALEN;
7277
7278 /* Channel List */
7279 /* Type: */
7280 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7281
7282 /* Country String(3) */
7283 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7284 /* + number of channels in all classes */
7285 len_channellist_attr = 3
7286 + (1 + 1) * (u16)ch_list->reg_classes
7287 + get_reg_classes_full_count(ch_list);
7288
7289 #ifdef CONFIG_CONCURRENT_MODE
7290 if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7291 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7292 else
7293 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7294
7295 #else
7296
7297 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7298
7299 #endif
7300 p2pielen += 2;
7301
7302 /* Value: */
7303 /* Country String */
7304 p2pie[p2pielen++] = 'X';
7305 p2pie[p2pielen++] = 'X';
7306
7307 /* The third byte should be set to 0x04. */
7308 /* Described in the "Operating Channel Attribute" section. */
7309 p2pie[p2pielen++] = 0x04;
7310
7311 /* Channel Entry List */
7312
7313 #ifdef CONFIG_CONCURRENT_MODE
7314 if (rtw_mi_check_status(padapter, MI_LINKED)) {
7315 u8 union_ch = rtw_mi_get_union_chan(padapter);
7316
7317 /* Operating Class */
7318 if (union_ch > 14) {
7319 if (union_ch >= 149)
7320 p2pie[p2pielen++] = 0x7c;
7321 else
7322 p2pie[p2pielen++] = 0x73;
7323 } else
7324 p2pie[p2pielen++] = 0x51;
7325
7326
7327 /* Number of Channels */
7328 /* Just support 1 channel and this channel is AP's channel */
7329 p2pie[p2pielen++] = 1;
7330
7331 /* Channel List */
7332 p2pie[p2pielen++] = union_ch;
7333 } else
7334 #endif /* CONFIG_CONCURRENT_MODE */
7335 {
7336 int i, j;
7337 for (j = 0; j < ch_list->reg_classes; j++) {
7338 /* Operating Class */
7339 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7340
7341 /* Number of Channels */
7342 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7343
7344 /* Channel List */
7345 for (i = 0; i < ch_list->reg_class[j].channels; i++)
7346 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7347 }
7348 }
7349
7350 /* Device Info */
7351 /* Type: */
7352 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
7353
7354 /* Length: */
7355 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
7356 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7357 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
7358 p2pielen += 2;
7359
7360 /* Value: */
7361 /* P2P Device Address */
7362 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7363 p2pielen += ETH_ALEN;
7364
7365 /* Config Method */
7366 /* This field should be big endian. Noted by P2P specification. */
7367
7368 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7369
7370 p2pielen += 2;
7371
7372 /* Primary Device Type */
7373 /* Category ID */
7374 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7375 p2pielen += 2;
7376
7377 /* OUI */
7378 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
7379 p2pielen += 4;
7380
7381 /* Sub Category ID */
7382 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7383 p2pielen += 2;
7384
7385 /* Number of Secondary Device Types */
7386 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
7387
7388 /* Device Name */
7389 /* Type: */
7390 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7391 p2pielen += 2;
7392
7393 /* Length: */
7394 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
7395 p2pielen += 2;
7396
7397 /* Value: */
7398 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
7399 p2pielen += pwdinfo->device_name_len;
7400
7401 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7402 /* Group ID Attribute */
7403 /* Type: */
7404 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
7405
7406 /* Length: */
7407 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
7408 p2pielen += 2;
7409
7410 /* Value: */
7411 /* p2P Device Address */
7412 _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
7413 p2pielen += ETH_ALEN;
7414
7415 /* SSID */
7416 _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
7417 p2pielen += pwdinfo->nego_ssidlen;
7418
7419 }
7420
7421 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7422
7423 #ifdef CONFIG_WFD
7424 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
7425 pframe += wfdielen;
7426 pktlen += wfdielen;
7427 #endif
7428
7429 *pLength = pktlen;
7430 #if 0
7431 /* printf dbg msg */
7432 dbgbufLen = pktlen;
7433 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7434
7435 for (index = 0; index < dbgbufLen; index++)
7436 printk("%x ", *(dbgbuf + index));
7437
7438 printk("\n");
7439 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7440 #endif
7441 }
7442
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7443 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7444 {
7445 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7446 u8 action = P2P_PUB_ACTION_ACTION;
7447 u32 p2poui = cpu_to_be32(P2POUI);
7448 u8 oui_subtype = P2P_INVIT_RESP;
7449 u8 p2pie[255] = { 0x00 };
7450 u8 p2pielen = 0, i;
7451 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
7452 u16 len_channellist_attr = 0;
7453 u32 pktlen;
7454 u8 dialogToken = 0;
7455 #ifdef CONFIG_WFD
7456 u32 wfdielen = 0;
7457 #endif
7458
7459 /* struct xmit_frame *pmgntframe; */
7460 /* struct pkt_attrib *pattrib; */
7461 /* unsigned char *pframe; */
7462 struct rtw_ieee80211_hdr *pwlanhdr;
7463 unsigned short *fctrl;
7464 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7465 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7466 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7467 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7468
7469 /* for debug */
7470 u8 *dbgbuf = pframe;
7471 u8 dbgbufLen = 0, index = 0;
7472
7473
7474 RTW_INFO("%s\n", __FUNCTION__);
7475 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7476
7477 fctrl = &(pwlanhdr->frame_ctl);
7478 *(fctrl) = 0;
7479
7480 /* RA fill by FW */
7481 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7482 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7483
7484 /* BSSID fill by FW */
7485 _rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
7486
7487 SetSeqNum(pwlanhdr, 0);
7488 set_frame_sub_type(pframe, WIFI_ACTION);
7489
7490 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7491 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7492
7493 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7494 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7495 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7496 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7497
7498 /* dialog token, filled by FW */
7499 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7500
7501 /* P2P IE Section. */
7502
7503 /* P2P OUI */
7504 p2pielen = 0;
7505 p2pie[p2pielen++] = 0x50;
7506 p2pie[p2pielen++] = 0x6F;
7507 p2pie[p2pielen++] = 0x9A;
7508 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7509
7510 /* Commented by Albert 20101005 */
7511 /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
7512 /* 1. Status */
7513 /* 2. Configuration Timeout */
7514 /* 3. Operating Channel ( Only GO ) */
7515 /* 4. P2P Group BSSID ( Only GO ) */
7516 /* 5. Channel List */
7517
7518 /* P2P Status */
7519 /* Type: */
7520 p2pie[p2pielen++] = P2P_ATTR_STATUS;
7521
7522 /* Length: */
7523 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7524 p2pielen += 2;
7525
7526 /* Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
7527 p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7528
7529 /* Configuration Timeout */
7530 /* Type: */
7531 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7532
7533 /* Length: */
7534 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7535 p2pielen += 2;
7536
7537 /* Value: */
7538 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7539 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7540
7541 /* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
7542 #if 0
7543 if (status_code == P2P_STATUS_SUCCESS) {
7544 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7545
7546 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7547 /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
7548 /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
7549 /* First one is operating channel attribute. */
7550 /* Second one is P2P Group BSSID attribute. */
7551
7552 /* Operating Channel */
7553 /* Type: */
7554 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7555
7556 /* Length: */
7557 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7558 p2pielen += 2;
7559
7560 /* Value: */
7561 /* Country String */
7562 p2pie[p2pielen++] = 'X';
7563 p2pie[p2pielen++] = 'X';
7564
7565 /* The third byte should be set to 0x04. */
7566 /* Described in the "Operating Channel Attribute" section. */
7567 p2pie[p2pielen++] = 0x04;
7568
7569 /* Operating Class */
7570 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
7571
7572 /* Channel Number */
7573 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7574
7575
7576 /* P2P Group BSSID */
7577 /* Type: */
7578 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
7579
7580 /* Length: */
7581 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7582 p2pielen += 2;
7583
7584 /* Value: */
7585 /* P2P Device Address for GO */
7586 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7587 p2pielen += ETH_ALEN;
7588
7589 }
7590
7591 /* Channel List */
7592 /* Type: */
7593 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7594
7595 /* Length: */
7596 /* Country String(3) */
7597 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7598 /* + number of channels in all classes */
7599 len_channellist_attr = 3
7600 + (1 + 1) * (u16)ch_list->reg_classes
7601 + get_reg_classes_full_count(ch_list);
7602
7603 #ifdef CONFIG_CONCURRENT_MODE
7604 if (rtw_mi_check_status(padapter, MI_LINKED))
7605 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7606 else
7607 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7608
7609 #else
7610
7611 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7612
7613 #endif
7614 p2pielen += 2;
7615
7616 /* Value: */
7617 /* Country String */
7618 p2pie[p2pielen++] = 'X';
7619 p2pie[p2pielen++] = 'X';
7620
7621 /* The third byte should be set to 0x04. */
7622 /* Described in the "Operating Channel Attribute" section. */
7623 p2pie[p2pielen++] = 0x04;
7624
7625 /* Channel Entry List */
7626 #ifdef CONFIG_CONCURRENT_MODE
7627 if (rtw_mi_check_status(padapter, MI_LINKED)) {
7628 u8 union_ch = rtw_mi_get_union_chan(padapter);
7629
7630 /* Operating Class */
7631 if (union_ch > 14) {
7632 if (union_ch >= 149)
7633 p2pie[p2pielen++] = 0x7c;
7634 else
7635 p2pie[p2pielen++] = 0x73;
7636
7637 } else
7638 p2pie[p2pielen++] = 0x51;
7639
7640
7641 /* Number of Channels */
7642 /* Just support 1 channel and this channel is AP's channel */
7643 p2pie[p2pielen++] = 1;
7644
7645 /* Channel List */
7646 p2pie[p2pielen++] = union_ch;
7647 } else
7648 #endif /* CONFIG_CONCURRENT_MODE */
7649 {
7650 int i, j;
7651 for (j = 0; j < ch_list->reg_classes; j++) {
7652 /* Operating Class */
7653 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7654
7655 /* Number of Channels */
7656 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7657
7658 /* Channel List */
7659 for (i = 0; i < ch_list->reg_class[j].channels; i++)
7660 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7661 }
7662 }
7663 }
7664 #endif
7665
7666 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7667
7668 #ifdef CONFIG_WFD
7669 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
7670 pframe += wfdielen;
7671 pktlen += wfdielen;
7672 #endif
7673
7674 *pLength = pktlen;
7675
7676 #if 0
7677 /* printf dbg msg */
7678 dbgbufLen = pktlen;
7679 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7680
7681 for (index = 0; index < dbgbufLen; index++)
7682 printk("%x ", *(dbgbuf + index));
7683
7684 printk("\n");
7685 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7686 #endif
7687 }
7688
7689
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7690 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7691 {
7692 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7693 u8 action = P2P_PUB_ACTION_ACTION;
7694 u8 dialogToken = 0;
7695 u32 p2poui = cpu_to_be32(P2POUI);
7696 u8 oui_subtype = P2P_PROVISION_DISC_RESP;
7697 u8 wpsie[100] = { 0x00 };
7698 u8 wpsielen = 0;
7699 u32 pktlen;
7700 #ifdef CONFIG_WFD
7701 u32 wfdielen = 0;
7702 #endif
7703
7704 /* struct xmit_frame *pmgntframe; */
7705 /* struct pkt_attrib *pattrib; */
7706 /* unsigned char *pframe; */
7707 struct rtw_ieee80211_hdr *pwlanhdr;
7708 unsigned short *fctrl;
7709 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7710 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7711 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7712 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7713
7714 /* for debug */
7715 u8 *dbgbuf = pframe;
7716 u8 dbgbufLen = 0, index = 0;
7717
7718 RTW_INFO("%s\n", __FUNCTION__);
7719
7720 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7721
7722 fctrl = &(pwlanhdr->frame_ctl);
7723 *(fctrl) = 0;
7724
7725 /* RA filled by FW */
7726 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7727 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7728 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7729
7730 SetSeqNum(pwlanhdr, 0);
7731 set_frame_sub_type(pframe, WIFI_ACTION);
7732
7733 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7734 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7735
7736 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7737 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7738 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7739 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7740 /* dialog token, filled by FW */
7741 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7742
7743 wpsielen = 0;
7744 /* WPS OUI */
7745 /* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
7746 RTW_PUT_BE32(wpsie, WPSOUI);
7747 wpsielen += 4;
7748
7749 #if 0
7750 /* WPS version */
7751 /* Type: */
7752 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7753 wpsielen += 2;
7754
7755 /* Length: */
7756 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7757 wpsielen += 2;
7758
7759 /* Value: */
7760 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7761 #endif
7762
7763 /* Config Method */
7764 /* Type: */
7765 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
7766 RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
7767 wpsielen += 2;
7768
7769 /* Length: */
7770 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
7771 RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
7772 wpsielen += 2;
7773
7774 /* Value: filled by FW, default value is PBC */
7775 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
7776 RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
7777 wpsielen += 2;
7778
7779 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7780
7781 #ifdef CONFIG_WFD
7782 wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
7783 pframe += wfdielen;
7784 pktlen += wfdielen;
7785 #endif
7786
7787 *pLength = pktlen;
7788
7789 /* printf dbg msg */
7790 #if 0
7791 dbgbufLen = pktlen;
7792 RTW_INFO("======> DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7793
7794 for (index = 0; index < dbgbufLen; index++)
7795 printk("%x ", *(dbgbuf + index));
7796
7797 printk("\n");
7798 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7799 #endif
7800 }
7801
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)7802 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
7803 {
7804 u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
7805 struct hal_ops *pHalFunc = &adapter->hal_func;
7806 u8 ret = _FAIL;
7807
7808 RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
7809 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
7810 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
7811 rsvdpageloc->LocPDRsp);
7812
7813 SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
7814 SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
7815 SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
7816 SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
7817 SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
7818
7819 /* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
7820 ret = rtw_hal_fill_h2c_cmd(adapter,
7821 H2C_P2P_OFFLOAD_RSVD_PAGE,
7822 H2C_P2PRSVDPAGE_LOC_LEN,
7823 u1H2CP2PRsvdPageParm);
7824
7825 return ret;
7826 }
7827
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)7828 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
7829 {
7830
7831 u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
7832 struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
7833 struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
7834 struct hal_ops *pHalFunc = &adapter->hal_func;
7835 u8 ret = _FAIL;
7836
7837 _rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
7838 RTW_INFO("%s\n", __func__);
7839 switch (pwdinfo->role) {
7840 case P2P_ROLE_DEVICE:
7841 RTW_INFO("P2P_ROLE_DEVICE\n");
7842 p2p_wowlan_offload->role = 0;
7843 break;
7844 case P2P_ROLE_CLIENT:
7845 RTW_INFO("P2P_ROLE_CLIENT\n");
7846 p2p_wowlan_offload->role = 1;
7847 break;
7848 case P2P_ROLE_GO:
7849 RTW_INFO("P2P_ROLE_GO\n");
7850 p2p_wowlan_offload->role = 2;
7851 break;
7852 default:
7853 RTW_INFO("P2P_ROLE_DISABLE\n");
7854 break;
7855 }
7856 p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
7857 p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
7858 offload_cmd = (u8 *)p2p_wowlan_offload;
7859 RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
7860
7861 ret = rtw_hal_fill_h2c_cmd(adapter,
7862 H2C_P2P_OFFLOAD,
7863 H2C_P2P_OFFLOAD_LEN,
7864 offload_cmd);
7865 return ret;
7866
7867 /* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
7868 }
7869 #endif /* CONFIG_P2P_WOWLAN */
7870
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)7871 void rtw_hal_construct_beacon(_adapter *padapter,
7872 u8 *pframe, u32 *pLength)
7873 {
7874 struct rtw_ieee80211_hdr *pwlanhdr;
7875 u16 *fctrl;
7876 u32 pktlen;
7877 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7878 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7879 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7880 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7881
7882
7883 /* RTW_INFO("%s\n", __FUNCTION__); */
7884
7885 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7886
7887 fctrl = &(pwlanhdr->frame_ctl);
7888 *(fctrl) = 0;
7889
7890 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7891 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7892 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7893
7894 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7895 /* pmlmeext->mgnt_seq++; */
7896 set_frame_sub_type(pframe, WIFI_BEACON);
7897
7898 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7899 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7900
7901 /* timestamp will be inserted by hardware */
7902 pframe += 8;
7903 pktlen += 8;
7904
7905 /* beacon interval: 2 bytes */
7906 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7907
7908 pframe += 2;
7909 pktlen += 2;
7910
7911 #if 0
7912 /* capability info: 2 bytes */
7913 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7914
7915 pframe += 2;
7916 pktlen += 2;
7917
7918 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7919 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7920 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
7921 _rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
7922
7923 goto _ConstructBeacon;
7924 }
7925
7926 /* below for ad-hoc mode */
7927
7928 /* SSID */
7929 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
7930
7931 /* supported rates... */
7932 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7933 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
7934
7935 /* DS parameter set */
7936 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
7937
7938 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
7939 u32 ATIMWindow;
7940 /* IBSS Parameter Set... */
7941 /* ATIMWindow = cur->Configuration.ATIMWindow; */
7942 ATIMWindow = 0;
7943 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
7944 }
7945
7946
7947 /* todo: ERP IE */
7948
7949
7950 /* EXTERNDED SUPPORTED RATE */
7951 if (rate_len > 8)
7952 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
7953
7954 /* todo:HT for adhoc */
7955
7956 _ConstructBeacon:
7957 #endif
7958
7959 if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
7960 RTW_ERR("beacon frame too large ,len(%d,%d)\n",
7961 (pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
7962 rtw_warn_on(1);
7963 return;
7964 }
7965
7966 *pLength = pktlen;
7967
7968 /* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
7969
7970 }
7971
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)7972 static void rtw_hal_construct_PSPoll(_adapter *padapter,
7973 u8 *pframe, u32 *pLength)
7974 {
7975 struct rtw_ieee80211_hdr *pwlanhdr;
7976 u16 *fctrl;
7977 u32 pktlen;
7978 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7979 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7980
7981 /* RTW_INFO("%s\n", __FUNCTION__); */
7982
7983 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7984
7985 /* Frame control. */
7986 fctrl = &(pwlanhdr->frame_ctl);
7987 *(fctrl) = 0;
7988 SetPwrMgt(fctrl);
7989 set_frame_sub_type(pframe, WIFI_PSPOLL);
7990
7991 /* AID. */
7992 set_duration(pframe, (pmlmeinfo->aid | 0xc000));
7993
7994 /* BSSID. */
7995 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7996
7997 /* TA. */
7998 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7999
8000 *pLength = 16;
8001 }
8002
8003
8004 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_construct_fw_dbg_msg_pkt(PADAPTER padapter,u8 * pframe,u32 * plength)8005 void rtw_hal_construct_fw_dbg_msg_pkt(
8006 PADAPTER padapter,
8007 u8 *pframe,
8008 u32 *plength)
8009 {
8010 struct rtw_ieee80211_hdr *pwlanhdr;
8011 u16 *fctrl;
8012 u32 pktlen;
8013 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8014 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8015 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8016 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8017 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8018
8019
8020 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8021
8022 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8023
8024 fctrl = &pwlanhdr->frame_ctl;
8025 *(fctrl) = 0;
8026
8027 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8028 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8029 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8030
8031 SetSeqNum(pwlanhdr, 0);
8032
8033 set_frame_sub_type(pframe, WIFI_DATA);
8034
8035 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8036
8037 *plength = pktlen;
8038 }
8039 #endif /*DBG_FW_DEBUG_MSG_PKT*/
8040
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)8041 void rtw_hal_construct_NullFunctionData(
8042 PADAPTER padapter,
8043 u8 *pframe,
8044 u32 *pLength,
8045 u8 bQoS,
8046 u8 AC,
8047 u8 bEosp,
8048 u8 bForcePowerSave)
8049 {
8050 struct rtw_ieee80211_hdr *pwlanhdr;
8051 u16 *fctrl;
8052 u32 pktlen;
8053 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8054 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8055 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8056 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8057 u8 *sta_addr = NULL;
8058 u8 bssid[ETH_ALEN] = {0};
8059
8060 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8061
8062 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8063
8064 fctrl = &pwlanhdr->frame_ctl;
8065 *(fctrl) = 0;
8066 if (bForcePowerSave)
8067 SetPwrMgt(fctrl);
8068
8069 sta_addr = get_my_bssid(&pmlmeinfo->network);
8070 if (NULL == sta_addr) {
8071 _rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
8072 sta_addr = bssid;
8073 }
8074
8075 switch (cur_network->network.InfrastructureMode) {
8076 case Ndis802_11Infrastructure:
8077 SetToDs(fctrl);
8078 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8079 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8080 _rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);
8081 break;
8082 case Ndis802_11APMode:
8083 SetFrDs(fctrl);
8084 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8085 _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8086 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8087 break;
8088 case Ndis802_11IBSS:
8089 default:
8090 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8091 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8092 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8093 break;
8094 }
8095
8096 SetSeqNum(pwlanhdr, 0);
8097 set_duration(pwlanhdr, 0);
8098
8099 if (bQoS == _TRUE) {
8100 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
8101
8102 set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
8103
8104 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
8105 SetPriority(&pwlanqoshdr->qc, AC);
8106 SetEOSP(&pwlanqoshdr->qc, bEosp);
8107
8108 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8109 } else {
8110 set_frame_sub_type(pframe, WIFI_DATA_NULL);
8111
8112 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8113 }
8114
8115 *pLength = pktlen;
8116 }
8117
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,BOOLEAN bHideSSID)8118 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
8119 BOOLEAN bHideSSID)
8120 {
8121 struct rtw_ieee80211_hdr *pwlanhdr;
8122 u16 *fctrl;
8123 u8 *mac, *bssid, *sta_addr;
8124 u32 pktlen;
8125 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8126 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8127 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
8128
8129 /*RTW_INFO("%s\n", __FUNCTION__);*/
8130
8131 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8132
8133 mac = adapter_mac_addr(padapter);
8134 bssid = cur_network->MacAddress;
8135 sta_addr = get_my_bssid(&pmlmeinfo->network);
8136
8137 fctrl = &(pwlanhdr->frame_ctl);
8138 *(fctrl) = 0;
8139 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8140 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8141 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8142
8143 SetSeqNum(pwlanhdr, 0);
8144 set_frame_sub_type(fctrl, WIFI_PROBERSP);
8145
8146 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8147 pframe += pktlen;
8148
8149 if (cur_network->IELength > MAX_IE_SZ)
8150 return;
8151
8152 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8153 pframe += cur_network->IELength;
8154 pktlen += cur_network->IELength;
8155
8156 *pLength = pktlen;
8157 }
8158
8159 #ifdef CONFIG_WOWLAN
rtw_hal_append_tkip_mic(PADAPTER padapter,u8 * pframe,u32 offset)8160 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
8161 u8 *pframe, u32 offset)
8162 {
8163 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8164 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8165 struct rtw_ieee80211_hdr *pwlanhdr;
8166 struct mic_data micdata;
8167 struct sta_info *psta = NULL;
8168 int res = 0;
8169
8170 u8 *payload = (u8 *)(pframe + offset);
8171
8172 u8 mic[8];
8173 u8 priority[4] = {0x0};
8174 u8 null_key[16] = {0x0};
8175
8176 RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
8177
8178 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8179
8180 psta = rtw_get_stainfo(&padapter->stapriv,
8181 get_my_bssid(&(pmlmeinfo->network)));
8182 if (psta != NULL) {
8183 res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
8184 null_key, 16);
8185 if (res == _TRUE)
8186 RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
8187 rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
8188 }
8189
8190 rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); /* DA */
8191
8192 rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
8193
8194 priority[0] = 0;
8195
8196 rtw_secmicappend(&micdata, &priority[0], 4);
8197
8198 rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
8199
8200 rtw_secgetmic(&micdata, &(mic[0]));
8201
8202 payload += 36;
8203
8204 _rtw_memcpy(payload, &(mic[0]), 8);
8205 }
8206 /*
8207 * Description:
8208 * Construct the ARP response packet to support ARP offload.
8209 * */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8210 static void rtw_hal_construct_ARPRsp(
8211 PADAPTER padapter,
8212 u8 *pframe,
8213 u32 *pLength,
8214 u8 *pIPAddress
8215 )
8216 {
8217 struct rtw_ieee80211_hdr *pwlanhdr;
8218 u16 *fctrl;
8219 u32 pktlen;
8220 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8221 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8222 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8223 struct security_priv *psecuritypriv = &padapter->securitypriv;
8224 static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
8225 u8 *pARPRspPkt = pframe;
8226 /* for TKIP Cal MIC */
8227 u8 *payload = pframe;
8228 u8 EncryptionHeadOverhead = 0, arp_offset = 0;
8229 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8230
8231 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8232
8233 fctrl = &pwlanhdr->frame_ctl;
8234 *(fctrl) = 0;
8235
8236 /* ------------------------------------------------------------------------- */
8237 /* MAC Header. */
8238 /* ------------------------------------------------------------------------- */
8239 SetFrameType(fctrl, WIFI_DATA);
8240 /* set_frame_sub_type(fctrl, 0); */
8241 SetToDs(fctrl);
8242 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8243 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8244 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8245
8246 SetSeqNum(pwlanhdr, 0);
8247 set_duration(pwlanhdr, 0);
8248 /* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
8249 /* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
8250 /* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
8251 /* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
8252 /* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
8253 /* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
8254
8255 /* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
8256 /* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
8257 #ifdef CONFIG_WAPI_SUPPORT
8258 *pLength = sMacHdrLng;
8259 #else
8260 *pLength = 24;
8261 #endif
8262 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8263 case _WEP40_:
8264 case _WEP104_:
8265 EncryptionHeadOverhead = 4;
8266 break;
8267 case _TKIP_:
8268 EncryptionHeadOverhead = 8;
8269 break;
8270 case _AES_:
8271 EncryptionHeadOverhead = 8;
8272 break;
8273 #ifdef CONFIG_WAPI_SUPPORT
8274 case _SMS4_:
8275 EncryptionHeadOverhead = 18;
8276 break;
8277 #endif
8278 default:
8279 EncryptionHeadOverhead = 0;
8280 }
8281
8282 if (EncryptionHeadOverhead > 0) {
8283 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8284 *pLength += EncryptionHeadOverhead;
8285 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8286 SetPrivacy(fctrl);
8287 }
8288
8289 /* ------------------------------------------------------------------------- */
8290 /* Frame Body. */
8291 /* ------------------------------------------------------------------------- */
8292 arp_offset = *pLength;
8293 pARPRspPkt = (u8 *)(pframe + arp_offset);
8294 payload = pARPRspPkt; /* Get Payload pointer */
8295 /* LLC header */
8296 _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
8297 *pLength += 8;
8298
8299 /* ARP element */
8300 pARPRspPkt += 8;
8301 SET_ARP_HTYPE(pARPRspPkt, 1);
8302 SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP); /* IP protocol */
8303 SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);
8304 SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);
8305 SET_ARP_OPER(pARPRspPkt, 2); /* ARP response */
8306 SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
8307 SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
8308 #ifdef CONFIG_ARP_KEEP_ALIVE
8309 if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
8310 SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
8311 SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
8312 } else
8313 #endif
8314 {
8315 SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,
8316 get_my_bssid(&(pmlmeinfo->network)));
8317 SET_ARP_TARGET_IP_ADDR(pARPRspPkt,
8318 pIPAddress);
8319 RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
8320 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
8321 RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
8322 IP_ARG(pIPAddress));
8323 }
8324
8325 *pLength += 28;
8326
8327 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8328 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8329 IS_HARDWARE_TYPE_8812(padapter)) {
8330 rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
8331 }
8332 *pLength += 8;
8333 }
8334 }
8335 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
8336 /*
8337 * Description:
8338 * Construct the Keep Alive packet to support specific Keep Alive packet.
8339 * */
rtw_hal_construct_keepalive(PADAPTER padapter,u8 * pframe,u32 * pLength)8340 static void rtw_hal_construct_keepalive( PADAPTER padapter,
8341 u8 *pframe,
8342 u32 *pLength
8343 ){
8344 struct rtw_ieee80211_hdr *pwlanhdr;
8345 u16 *fctrl;
8346 u32 pktlen;
8347 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8348 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8349 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8350 struct security_priv *psecuritypriv = &padapter->securitypriv;
8351 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
8352 static u8 LLCHeader[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
8353 u8 *pKeepAlivePkt = pframe;
8354 /* for TKIP Cal MIC */
8355 u8 *payload = pframe;
8356 u8 EncryptionHeadOverhead = 0, frame_offset = 0;
8357 int i;
8358
8359 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8360
8361 fctrl = &pwlanhdr->frame_ctl;
8362 *(fctrl) = 0;
8363
8364 RTW_INFO("%s======>\n", __func__);
8365
8366
8367 /* ------------------------------------------------------------------------- */
8368 /* MAC Header. */
8369 /* ------------------------------------------------------------------------- */
8370 SetFrameType(fctrl, WIFI_DATA);
8371 /* set_frame_sub_type(fctrl, 0); */
8372 SetToDs(fctrl);
8373 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8374 _rtw_memcpy(pwlanhdr->addr2, pwrpriv->keep_alive_pattern+6, ETH_ALEN);
8375 _rtw_memcpy(pwlanhdr->addr3,pwrpriv->keep_alive_pattern, ETH_ALEN);
8376
8377 SetSeqNum(pwlanhdr, 0);
8378 set_duration(pwlanhdr, 0);
8379
8380 #ifdef CONFIG_WAPI_SUPPORT
8381 *pLength = sMacHdrLng;
8382 #else
8383 *pLength = 24;
8384 #endif
8385 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8386 case _WEP40_:
8387 case _WEP104_:
8388 EncryptionHeadOverhead = 4;
8389 break;
8390 case _TKIP_:
8391 EncryptionHeadOverhead = 8;
8392 break;
8393 case _AES_:
8394 EncryptionHeadOverhead = 8;
8395 break;
8396 #ifdef CONFIG_WAPI_SUPPORT
8397 case _SMS4_:
8398 EncryptionHeadOverhead = 18;
8399 break;
8400 #endif
8401 default:
8402 EncryptionHeadOverhead = 0;
8403 }
8404
8405 if (EncryptionHeadOverhead > 0) {
8406 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8407 *pLength += EncryptionHeadOverhead;
8408 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8409 SetPrivacy(fctrl);
8410 }
8411
8412 /* ------------------------------------------------------------------------- */
8413 /* Frame Body. */
8414 /* ------------------------------------------------------------------------- */
8415 frame_offset = *pLength;
8416 pKeepAlivePkt = (u8 *)(pframe + frame_offset);
8417 payload = pKeepAlivePkt; /* Get Payload pointer */
8418 /* LLC header */
8419 _rtw_memcpy(pKeepAlivePkt, LLCHeader, 6);
8420 *pLength += 6;
8421
8422 /*From protocol type*/
8423 pKeepAlivePkt+=6;
8424
8425 _rtw_memcpy(pKeepAlivePkt,pwrpriv->keep_alive_pattern+12,pwrpriv->keep_alive_pattern_len-12);
8426
8427 *pLength+=pwrpriv->keep_alive_pattern_len-12;
8428
8429 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8430 *pLength += 8;
8431 }
8432
8433 /* for debug
8434 for (i=0; i< (*pLength) ;i++) {
8435 RTW_INFO("KA_Pkt[0x%x]=x%0x", i,pKeepAlivePkt[i]);
8436 if((i%8) == 7)
8437 RTW_INFO("\n");
8438 }
8439 */
8440
8441 RTW_INFO("%s <======\n", __func__);
8442 }
8443
8444 #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
8445
8446 #ifdef CONFIG_IPV6
8447 /*
8448 * Description: Neighbor Discovery Offload.
8449 */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)8450 static void rtw_hal_construct_na_message(_adapter *padapter,
8451 u8 *pframe, u32 *pLength)
8452 {
8453 struct rtw_ieee80211_hdr *pwlanhdr = NULL;
8454 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8455 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8456 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8457 struct security_priv *psecuritypriv = &padapter->securitypriv;
8458
8459 u32 pktlen = 0;
8460 u16 *fctrl = NULL;
8461
8462 u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8463 u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
8464 u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
8465 u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
8466 u8 val8 = 0;
8467
8468 u8 *p_na_msg = pframe;
8469 /* for TKIP Cal MIC */
8470 u8 *payload = pframe;
8471 u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
8472 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8473
8474 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8475
8476 fctrl = &pwlanhdr->frame_ctl;
8477 *(fctrl) = 0;
8478
8479 /* ------------------------------------------------------------------------- */
8480 /* MAC Header. */
8481 /* ------------------------------------------------------------------------- */
8482 SetFrameType(fctrl, WIFI_DATA);
8483 SetToDs(fctrl);
8484 _rtw_memcpy(pwlanhdr->addr1,
8485 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8486 _rtw_memcpy(pwlanhdr->addr2,
8487 adapter_mac_addr(padapter), ETH_ALEN);
8488 _rtw_memcpy(pwlanhdr->addr3,
8489 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8490
8491 SetSeqNum(pwlanhdr, 0);
8492 set_duration(pwlanhdr, 0);
8493
8494 #ifdef CONFIG_WAPI_SUPPORT
8495 *pLength = sMacHdrLng;
8496 #else
8497 *pLength = 24;
8498 #endif
8499 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8500 case _WEP40_:
8501 case _WEP104_:
8502 EncryptionHeadOverhead = 4;
8503 break;
8504 case _TKIP_:
8505 EncryptionHeadOverhead = 8;
8506 break;
8507 case _AES_:
8508 EncryptionHeadOverhead = 8;
8509 break;
8510 #ifdef CONFIG_WAPI_SUPPORT
8511 case _SMS4_:
8512 EncryptionHeadOverhead = 18;
8513 break;
8514 #endif
8515 default:
8516 EncryptionHeadOverhead = 0;
8517 }
8518
8519 if (EncryptionHeadOverhead > 0) {
8520 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8521 *pLength += EncryptionHeadOverhead;
8522 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8523 SetPrivacy(fctrl);
8524 }
8525
8526 /* ------------------------------------------------------------------------- */
8527 /* Frame Body. */
8528 /* ------------------------------------------------------------------------- */
8529 na_msg_offset = *pLength;
8530 p_na_msg = (u8 *)(pframe + na_msg_offset);
8531 payload = p_na_msg; /* Get Payload pointer */
8532
8533 /* LLC header */
8534 val8 = sizeof(ns_hdr);
8535 _rtw_memcpy(p_na_msg, ns_hdr, val8);
8536 *pLength += val8;
8537 p_na_msg += val8;
8538
8539 /* IPv6 Header */
8540 /* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
8541 val8 = sizeof(ipv6_info);
8542 _rtw_memcpy(p_na_msg, ipv6_info, val8);
8543 *pLength += val8;
8544 p_na_msg += val8;
8545
8546 /* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
8547 val8 = sizeof(ipv6_contx);
8548 _rtw_memcpy(p_na_msg, ipv6_contx, val8);
8549 *pLength += val8;
8550 p_na_msg += val8;
8551
8552 /* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
8553 _rtw_memset(&(p_na_msg[*pLength]), 0, 32);
8554 *pLength += 32;
8555 p_na_msg += 32;
8556
8557 /* ICMPv6 */
8558 /* 1. Type : 0x88 (NA)
8559 * 2. Code : 0x00
8560 * 3. ChechSum : 0x00 0x00 (RSvd)
8561 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
8562 */
8563 val8 = sizeof(icmpv6_hdr);
8564 _rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
8565 *pLength += val8;
8566 p_na_msg += val8;
8567
8568 /* TA: 16 bytes*/
8569 _rtw_memset(&(p_na_msg[*pLength]), 0, 16);
8570 *pLength += 16;
8571 p_na_msg += 16;
8572
8573 /* ICMPv6 Target Link Layer Address */
8574 p_na_msg[0] = 0x02; /* type */
8575 p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
8576 *pLength += 2;
8577 p_na_msg += 2;
8578
8579 _rtw_memset(&(p_na_msg[*pLength]), 0, 6);
8580 *pLength += 6;
8581 p_na_msg += 6;
8582
8583 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8584 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8585 IS_HARDWARE_TYPE_8812(padapter)) {
8586 rtw_hal_append_tkip_mic(padapter, pframe,
8587 na_msg_offset);
8588 }
8589 *pLength += 8;
8590 }
8591 }
8592 /*
8593 * Description: Neighbor Discovery Protocol Information.
8594 */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)8595 static void rtw_hal_construct_ndp_info(_adapter *padapter,
8596 u8 *pframe, u32 *pLength)
8597 {
8598 struct mlme_ext_priv *pmlmeext = NULL;
8599 struct mlme_ext_info *pmlmeinfo = NULL;
8600 struct rtw_ndp_info ndp_info;
8601 u8 *pndp_info = pframe;
8602 u8 len = sizeof(struct rtw_ndp_info);
8603
8604 RTW_INFO("%s: len: %d\n", __func__, len);
8605
8606 pmlmeext = &padapter->mlmeextpriv;
8607 pmlmeinfo = &pmlmeext->mlmext_info;
8608
8609 _rtw_memset(pframe, 0, len);
8610 _rtw_memset(&ndp_info, 0, len);
8611
8612 ndp_info.enable = 1;
8613 ndp_info.check_remote_ip = 0;
8614 ndp_info.num_of_target_ip = 1;
8615
8616 _rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
8617 ETH_ALEN);
8618 _rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
8619 RTW_IPv6_ADDR_LEN);
8620
8621 _rtw_memcpy(pndp_info, &ndp_info, len);
8622 }
8623 #endif /* CONFIG_IPV6 */
8624
8625 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)8626 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
8627 u32 *pLength, pno_ssid_t *ssid)
8628 {
8629 struct rtw_ieee80211_hdr *pwlanhdr;
8630 u16 *fctrl;
8631 u32 pktlen;
8632 unsigned char *mac;
8633 unsigned char bssrate[NumRates];
8634 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8635 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8636 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8637 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8638 int bssrate_len = 0;
8639 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8640
8641 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8642 mac = adapter_mac_addr(padapter);
8643
8644 fctrl = &(pwlanhdr->frame_ctl);
8645 *(fctrl) = 0;
8646
8647 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8648 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8649
8650 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8651
8652 SetSeqNum(pwlanhdr, 0);
8653 set_frame_sub_type(pframe, WIFI_PROBEREQ);
8654
8655 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8656 pframe += pktlen;
8657
8658 if (ssid == NULL)
8659 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
8660 else {
8661 /* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
8662 pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
8663 }
8664
8665 get_rate_set(padapter, bssrate, &bssrate_len);
8666
8667 if (bssrate_len > 8) {
8668 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
8669 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
8670 } else
8671 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
8672
8673 *pLength = pktlen;
8674 }
8675
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)8676 static void rtw_hal_construct_PNO_info(_adapter *padapter,
8677 u8 *pframe, u32 *pLength)
8678 {
8679 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8680 int i;
8681
8682 u8 *pPnoInfoPkt = pframe;
8683 pPnoInfoPkt = (u8 *)(pframe + *pLength);
8684 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
8685
8686 pPnoInfoPkt += 1;
8687 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
8688
8689 pPnoInfoPkt += 3;
8690 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
8691
8692 pPnoInfoPkt += 4;
8693 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
8694
8695 pPnoInfoPkt += 4;
8696 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
8697
8698 pPnoInfoPkt += 4;
8699 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
8700
8701 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8702 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
8703
8704 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8705 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
8706
8707 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8708 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
8709
8710 pPnoInfoPkt += MAX_HIDDEN_AP;
8711
8712 /*
8713 SSID is located at 128th Byte in NLO info Page
8714 */
8715
8716 *pLength += 128;
8717 pPnoInfoPkt = pframe + 128;
8718
8719 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8720 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8721 pwrctl->pnlo_info->ssid_length[i]);
8722 *pLength += WLAN_SSID_MAXLEN;
8723 pPnoInfoPkt += WLAN_SSID_MAXLEN;
8724 }
8725 }
8726
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)8727 static void rtw_hal_construct_ssid_list(_adapter *padapter,
8728 u8 *pframe, u32 *pLength)
8729 {
8730 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8731 u8 *pSSIDListPkt = pframe;
8732 int i;
8733
8734 pSSIDListPkt = (u8 *)(pframe + *pLength);
8735
8736 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8737 _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8738 pwrctl->pnlo_info->ssid_length[i]);
8739
8740 *pLength += WLAN_SSID_MAXLEN;
8741 pSSIDListPkt += WLAN_SSID_MAXLEN;
8742 }
8743 }
8744
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)8745 static void rtw_hal_construct_scan_info(_adapter *padapter,
8746 u8 *pframe, u32 *pLength)
8747 {
8748 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8749 u8 *pScanInfoPkt = pframe;
8750 int i;
8751
8752 pScanInfoPkt = (u8 *)(pframe + *pLength);
8753
8754 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
8755
8756 *pLength += 1;
8757 pScanInfoPkt += 1;
8758 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
8759
8760
8761 *pLength += 1;
8762 pScanInfoPkt += 1;
8763 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
8764
8765
8766 *pLength += 1;
8767 pScanInfoPkt += 1;
8768 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
8769
8770 *pLength += 1;
8771 pScanInfoPkt += 1;
8772 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
8773
8774 *pLength += 1;
8775 pScanInfoPkt += 1;
8776 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
8777
8778 *pLength += 1;
8779 pScanInfoPkt += 1;
8780 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
8781
8782 *pLength += 1;
8783 pScanInfoPkt += 1;
8784 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
8785
8786 *pLength += 1;
8787 pScanInfoPkt += 1;
8788 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
8789
8790 *pLength += 8;
8791 pScanInfoPkt += 8;
8792
8793 for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
8794 _rtw_memcpy(pScanInfoPkt,
8795 &pwrctl->pscan_info->ssid_channel_info[i], 4);
8796 *pLength += 4;
8797 pScanInfoPkt += 4;
8798 }
8799 }
8800 #endif /* CONFIG_PNO_SUPPORT */
8801
8802 #ifdef CONFIG_WAR_OFFLOAD
8803 #ifdef CONFIG_OFFLOAD_MDNS_V4
8804
8805 /*
8806 * Description:
8807 * Construct the MDNS V4 response packet to support MDNS offload.
8808 *
8809 */
rtw_hal_construct_mdns_rsp_v4(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8810 static void rtw_hal_construct_mdns_rsp_v4(
8811 PADAPTER padapter,
8812 u8 *pframe,
8813 u32 *pLength,
8814 u8 *pIPAddress
8815 )
8816 {
8817 struct rtw_ieee80211_hdr *pwlanhdr;
8818 u16 *fctrl;
8819 u32 pktlen;
8820 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8821 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8822 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8823 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8824 struct security_priv *psecuritypriv = &padapter->securitypriv;
8825 static u8 ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00};
8826 u8 mulicast_ipv4_addr[4] = {0xe0, 0x00, 0x00, 0xfb};
8827 u8 mulicast_mac_addr_for_mdns[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb};
8828 u8 *pMdnsRspPkt = pframe;
8829 /* for TKIP Cal MIC */
8830 u8 EncryptionHeadOverhead = 0, mdns_offset = 0;
8831
8832 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
8833 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
8834
8835 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8836
8837 fctrl = &pwlanhdr->frame_ctl;
8838 *(fctrl) = 0;
8839
8840 /* ------------------------------------------------------------------------- */
8841 /* MAC Header. */
8842 /* ------------------------------------------------------------------------- */
8843 SetFrameType(fctrl, WIFI_DATA);
8844 /* set_frame_sub_type(fctrl, 0); */
8845 SetToDs(fctrl);
8846 //_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8847 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8848 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8849 _rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN );
8850
8851 SetSeqNum(pwlanhdr, 0);
8852 set_duration(pwlanhdr, 0);
8853
8854 #ifdef CONFIG_WAPI_SUPPORT
8855 *pLength = sMacHdrLng;
8856 #else
8857 *pLength = 24;
8858 #endif
8859 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8860 case _WEP40_:
8861 case _WEP104_:
8862 EncryptionHeadOverhead = 4;
8863 break;
8864 case _TKIP_:
8865 EncryptionHeadOverhead = 8;
8866 break;
8867 case _AES_:
8868 EncryptionHeadOverhead = 8;
8869 break;
8870 #ifdef CONFIG_WAPI_SUPPORT
8871 case _SMS4_:
8872 EncryptionHeadOverhead = 18;
8873 break;
8874 #endif
8875 default:
8876 EncryptionHeadOverhead = 0;
8877 }
8878
8879 if (EncryptionHeadOverhead > 0) {
8880 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8881 *pLength += EncryptionHeadOverhead;
8882 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8883 SetPrivacy(fctrl);
8884 }
8885
8886 /* ------------------------------------------------------------------------- */
8887 /* Frame Body. */
8888 /* ------------------------------------------------------------------------- */
8889 mdns_offset = *pLength;
8890 pMdnsRspPkt = (u8 *)(pframe + mdns_offset);
8891 /* LLC header */
8892 _rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8);
8893 *pLength += 8;
8894
8895 /* IP element */
8896 pMdnsRspPkt += 8;
8897 SET_IPHDR_VERSION(pMdnsRspPkt, 0x45);
8898 SET_IPHDR_DSCP(pMdnsRspPkt, 0);
8899 SET_IPHDR_TOTAL_LEN(pMdnsRspPkt, 0); // filled by fw
8900 SET_IPHDR_IDENTIFIER(pMdnsRspPkt, 0); // filled by fw
8901 SET_IPHDR_FLAGS(pMdnsRspPkt, 0x40);
8902 SET_IPHDR_FRAG_OFFSET(pMdnsRspPkt, 0);
8903 SET_IPHDR_TTL(pMdnsRspPkt, 0x40);
8904 SET_IPHDR_PROTOCOL(pMdnsRspPkt, 0x11); // ICMP-UDP
8905 SET_IPHDR_HDR_CHECKSUM(pMdnsRspPkt, 0); // filled by fw
8906 SET_IPHDR_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress);
8907 SET_IPHDR_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv4_addr); // filled by fw
8908
8909 *pLength += 20;
8910
8911 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8912 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8913 IS_HARDWARE_TYPE_8812(padapter)) {
8914 rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset);
8915 }
8916 *pLength += 8;
8917 }
8918
8919 /* UDP element */
8920 pMdnsRspPkt += 20;
8921 SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // MDNS
8922 SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // MDNS
8923 SET_UDP_LEN(pMdnsRspPkt, 0); // filled by fw
8924 SET_UDP_CHECKSUM(pMdnsRspPkt, 0); // filled by fw
8925 *pLength += 8;
8926
8927 /* MDNS Header */
8928 pMdnsRspPkt += 8;
8929 SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84);
8930 *pLength += 12;
8931
8932 }
8933
8934 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
8935
8936 #ifdef CONFIG_OFFLOAD_MDNS_V6
8937
8938 /*
8939 * Description:
8940 * Construct the MDNS response V6 packet to support MDNS offload.
8941 *
8942 */
rtw_hal_construct_mdns_rsp_v6(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8943 static void rtw_hal_construct_mdns_rsp_v6(
8944 PADAPTER padapter,
8945 u8 *pframe,
8946 u32 *pLength,
8947 u8 *pIPAddress
8948 )
8949 {
8950 struct rtw_ieee80211_hdr *pwlanhdr;
8951 u16 *fctrl;
8952 u32 pktlen;
8953 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8954 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8955 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8956 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8957 struct security_priv *psecuritypriv = &padapter->securitypriv;
8958 static u8 ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8959 u8 mulicast_ipv6_addr[16] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
8960 u8 mulicast_mac_addr_for_mdns[6] = {0x33, 0x33, 0x00, 0x00, 0x00, 0xfb}; /* could be revise by fw */
8961 u8 *pMdnsRspPkt = pframe;
8962 /* for TKIP Cal MIC */
8963 u8 EncryptionHeadOverhead = 0, mdns_offset = 0;
8964 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8965
8966 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
8967 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
8968
8969 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8970
8971 fctrl = &pwlanhdr->frame_ctl;
8972 *(fctrl) = 0;
8973
8974 /* ------------------------------------------------------------------------- */
8975 /* MAC Header. */
8976 /* ------------------------------------------------------------------------- */
8977 SetFrameType(fctrl, WIFI_DATA);
8978 /* set_frame_sub_type(fctrl, 0); */
8979 SetToDs(fctrl);
8980 //_rtw_memcpy(pwlanhdr->addr1, mulicast_mac_addr_for_mdns, ETH_ALEN);
8981 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8982 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8983 //_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8984 _rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN);
8985
8986 SetSeqNum(pwlanhdr, 0);
8987 set_duration(pwlanhdr, 0);
8988
8989 #ifdef CONFIG_WAPI_SUPPORT
8990 *pLength = sMacHdrLng;
8991 #else
8992 *pLength = 24;
8993 #endif
8994 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8995 case _WEP40_:
8996 case _WEP104_:
8997 EncryptionHeadOverhead = 4;
8998 break;
8999 case _TKIP_:
9000 EncryptionHeadOverhead = 8;
9001 break;
9002 case _AES_:
9003 EncryptionHeadOverhead = 8;
9004 break;
9005 #ifdef CONFIG_WAPI_SUPPORT
9006 case _SMS4_:
9007 EncryptionHeadOverhead = 18;
9008 break;
9009 #endif
9010 default:
9011 EncryptionHeadOverhead = 0;
9012 }
9013
9014 if (EncryptionHeadOverhead > 0) {
9015 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
9016 *pLength += EncryptionHeadOverhead;
9017 SetPrivacy(fctrl);
9018 }
9019
9020 /* ------------------------------------------------------------------------- */
9021 /* Frame Body. */
9022 /* ------------------------------------------------------------------------- */
9023 mdns_offset = *pLength;
9024 pMdnsRspPkt = (u8 *)(pframe + mdns_offset);
9025 /* LLC header */
9026 _rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8);
9027 *pLength += 8;
9028
9029 /* ICMP element */
9030 pMdnsRspPkt += 8;
9031 SET_IPHDRV6_VERSION(pMdnsRspPkt, 0x06);
9032 SET_IPHDRV6_PAYLOAD_LENGTH(pMdnsRspPkt, 0); // filled by fw
9033 SET_IPHDRV6_NEXT_HEADER(pMdnsRspPkt, 0x3A);
9034 SET_IPHDRV6_HOP_LIMIT(pMdnsRspPkt, 0xFF);
9035 SET_IPHDRV6_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress); // filled by fw
9036 SET_IPHDRV6_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv6_addr); // filled by fw
9037
9038 *pLength += 40;
9039
9040 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
9041 if (IS_HARDWARE_TYPE_8188E(padapter) ||
9042 IS_HARDWARE_TYPE_8812(padapter)) {
9043 rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset);
9044 }
9045 *pLength += 8;
9046 }
9047
9048 /* UDP element */
9049 pMdnsRspPkt += 40;
9050 SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // SNMP
9051 SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // SNMP
9052 SET_UDP_LEN(pMdnsRspPkt, 0); // filled by fw
9053 SET_UDP_CHECKSUM(pMdnsRspPkt, 0); // filled by fw
9054 *pLength += 8;
9055
9056 /* MDNS Header */
9057 pMdnsRspPkt += 8;
9058 SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84);
9059 *pLength += 12;
9060
9061 }
9062
9063 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
9064 #endif
9065
9066 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)9067 static void rtw_hal_construct_GTKRsp(
9068 PADAPTER padapter,
9069 u8 *pframe,
9070 u32 *pLength
9071 )
9072 {
9073 struct rtw_ieee80211_hdr *pwlanhdr;
9074 u16 *fctrl;
9075 u32 pktlen;
9076 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9077 struct wlan_network *cur_network = &pmlmepriv->cur_network;
9078 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9079 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9080 struct security_priv *psecuritypriv = &padapter->securitypriv;
9081 static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
9082 static u8 GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
9083 u8 *pGTKRspPkt = pframe;
9084 u8 EncryptionHeadOverhead = 0;
9085 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
9086
9087 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9088
9089 fctrl = &pwlanhdr->frame_ctl;
9090 *(fctrl) = 0;
9091
9092 /* ------------------------------------------------------------------------- */
9093 /* MAC Header. */
9094 /* ------------------------------------------------------------------------- */
9095 SetFrameType(fctrl, WIFI_DATA);
9096 /* set_frame_sub_type(fctrl, 0); */
9097 SetToDs(fctrl);
9098
9099 _rtw_memcpy(pwlanhdr->addr1,
9100 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9101
9102 _rtw_memcpy(pwlanhdr->addr2,
9103 adapter_mac_addr(padapter), ETH_ALEN);
9104
9105 _rtw_memcpy(pwlanhdr->addr3,
9106 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9107
9108 SetSeqNum(pwlanhdr, 0);
9109 set_duration(pwlanhdr, 0);
9110
9111 #ifdef CONFIG_WAPI_SUPPORT
9112 *pLength = sMacHdrLng;
9113 #else
9114 *pLength = 24;
9115 #endif /* CONFIG_WAPI_SUPPORT */
9116
9117 /* ------------------------------------------------------------------------- */
9118 /* Security Header: leave space for it if necessary. */
9119 /* ------------------------------------------------------------------------- */
9120 switch (psecuritypriv->dot11PrivacyAlgrthm) {
9121 case _WEP40_:
9122 case _WEP104_:
9123 EncryptionHeadOverhead = 4;
9124 break;
9125 case _TKIP_:
9126 EncryptionHeadOverhead = 8;
9127 break;
9128 case _AES_:
9129 EncryptionHeadOverhead = 8;
9130 break;
9131 #ifdef CONFIG_WAPI_SUPPORT
9132 case _SMS4_:
9133 EncryptionHeadOverhead = 18;
9134 break;
9135 #endif /* CONFIG_WAPI_SUPPORT */
9136 default:
9137 EncryptionHeadOverhead = 0;
9138 }
9139
9140 if (EncryptionHeadOverhead > 0) {
9141 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
9142 *pLength += EncryptionHeadOverhead;
9143 /* SET_80211_HDR_WEP(pGTKRspPkt, 1); */ /* Suggested by CCW. */
9144 /* GTK's privacy bit is done by FW */
9145 /* SetPrivacy(fctrl); */
9146 }
9147 /* ------------------------------------------------------------------------- */
9148 /* Frame Body. */
9149 /* ------------------------------------------------------------------------- */
9150 pGTKRspPkt = (u8 *)(pframe + *pLength);
9151 /* LLC header */
9152 _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
9153 *pLength += 8;
9154
9155 /* GTK element */
9156 pGTKRspPkt += 8;
9157
9158 /* GTK frame body after LLC, part 1 */
9159 /* TKIP key_length = 32, AES key_length = 16 */
9160 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
9161 GTKbody_a[8] = 0x20;
9162
9163 /* GTK frame body after LLC, part 1 */
9164 _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
9165 *pLength += 11;
9166 pGTKRspPkt += 11;
9167 /* GTK frame body after LLC, part 2 */
9168 _rtw_memset(&(pframe[*pLength]), 0, 88);
9169 *pLength += 88;
9170 pGTKRspPkt += 88;
9171
9172 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
9173 *pLength += 8;
9174 }
9175 #endif /* CONFIG_GTK_OL */
9176
9177 #define PN_2_CCMPH(ch,key_id) ((ch) & 0x000000000000ffff) \
9178 | (((ch) & 0x0000ffffffff0000) << 16) \
9179 | (((key_id) << 30)) \
9180 | BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)9181 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
9182 u8 *pframe, u32 *pLength)
9183 {
9184 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
9185 struct sta_priv *pstapriv = &adapter->stapriv;
9186 struct security_priv *psecuritypriv = &adapter->securitypriv;
9187 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
9188 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9189 struct sta_info *psta;
9190 struct stainfo_rxcache *prxcache;
9191 u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
9192 size_t sz = 0, total = 0;
9193 u64 ccmp_hdr = 0, tmp_key = 0;
9194
9195 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
9196
9197 if (psta == NULL) {
9198 rtw_warn_on(1);
9199 return;
9200 }
9201
9202 prxcache = &psta->sta_recvpriv.rxcache;
9203 sz = sizeof(cur_dot11rxiv);
9204
9205 /* 3 SEC IV * 1 page */
9206 rtw_get_sec_iv(adapter, cur_dot11rxiv,
9207 get_my_bssid(&pmlmeinfo->network));
9208
9209 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
9210 *pLength += sz;
9211 pframe += sz;
9212
9213 _rtw_memset(&cur_dot11rxiv, 0, sz);
9214
9215 if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
9216 id = psecuritypriv->dot118021XGrpKeyid;
9217 tid_id = prxcache->last_tid;
9218 REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
9219 REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
9220 REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
9221 REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
9222 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
9223 *pLength += sz;
9224 pframe += sz;
9225
9226 _rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
9227 *pLength += sz;
9228 pframe += sz;
9229
9230 total = sizeof(psecuritypriv->iv_seq);
9231 total /= sizeof(psecuritypriv->iv_seq[0]);
9232
9233 for (i = 0 ; i < total ; i ++) {
9234 ccmp_hdr =
9235 le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
9236 _rtw_memset(&cur_dot11rxiv, 0, sz);
9237 if (ccmp_hdr != 0) {
9238 tmp_key = i;
9239 ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
9240 *(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
9241 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
9242 }
9243 *pLength += sz;
9244 pframe += sz;
9245 }
9246 }
9247 }
9248
rtw_hal_gate_bb(_adapter * adapter,bool stop)9249 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
9250 {
9251 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9252 u8 i = 0, val8 = 0, empty = _FAIL;
9253
9254 if (stop) {
9255 /* checking TX queue status */
9256 for (i = 0 ; i < 5 ; i++) {
9257 rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
9258 if (empty) {
9259 break;
9260 } else {
9261 RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
9262 __func__, i);
9263 rtw_mdelay_os(10);
9264 }
9265 }
9266
9267 if (val8 == 5)
9268 RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
9269
9270 /* Pause TX*/
9271 pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
9272 rtw_write8(adapter, REG_TXPAUSE, 0xff);
9273 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9274 val8 &= ~BIT(0);
9275 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9276 RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
9277 __func__,
9278 rtw_read8(adapter, REG_SYS_FUNC_EN),
9279 pwrpriv->wowlan_txpause_status);
9280 } else {
9281 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9282 val8 |= BIT(0);
9283 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9284 RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
9285 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
9286 pwrpriv->wowlan_txpause_status);
9287 /* release TX*/
9288 rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
9289 }
9290 }
9291
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)9292 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
9293 {
9294 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9295 u8 *pattern;
9296 u8 len = 0;
9297 u8 *mask;
9298
9299 u8 mask_hw[MAX_WKFM_SIZE] = {0};
9300 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9301 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9302 u8 multicast_addr1[2] = {0x33, 0x33};
9303 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9304 u8 mask_len = 0;
9305 u8 mac_addr[ETH_ALEN] = {0};
9306 u16 count = 0;
9307 int i;
9308
9309 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9310 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9311 __func__, MAX_WKFM_CAM_NUM);
9312 return _FAIL;
9313 }
9314
9315 pattern = pwrctl->patterns[idx].content;
9316 len = pwrctl->patterns[idx].len;
9317 mask = pwrctl->patterns[idx].mask;
9318
9319 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9320 _rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
9321
9322 mask_len = DIV_ROUND_UP(len, 8);
9323
9324 /* 1. setup A1 table */
9325 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9326 pwow_pattern->type = PATTERN_BROADCAST;
9327 else if (memcmp(pattern, multicast_addr1, 2) == 0)
9328 pwow_pattern->type = PATTERN_MULTICAST;
9329 else if (memcmp(pattern, multicast_addr2, 3) == 0)
9330 pwow_pattern->type = PATTERN_MULTICAST;
9331 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9332 pwow_pattern->type = PATTERN_UNICAST;
9333 else
9334 pwow_pattern->type = PATTERN_INVALID;
9335
9336 /* translate mask from os to mask for hw */
9337
9338 /******************************************************************************
9339 * pattern from OS uses 'ethenet frame', like this:
9340
9341 | 6 | 6 | 2 | 20 | Variable | 4 |
9342 |--------+--------+------+-----------+------------+-----|
9343 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
9344 | DA | SA | Type |
9345
9346 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9347
9348 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
9349 |-------------------+--------+------+-----------+------------+-----|
9350 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
9351 | Others | Tpye |
9352
9353 * Therefore, we need translate mask_from_OS to mask_to_hw.
9354 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9355 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9356 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9357 ******************************************************************************/
9358 /* Shift 6 bits */
9359 for (i = 0; i < mask_len - 1; i++) {
9360 mask_hw[i] = mask[i] >> 6;
9361 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9362 }
9363
9364 mask_hw[i] = (mask[i] >> 6) & 0x3F;
9365 /* Set bit 0-5 to zero */
9366 mask_hw[0] &= 0xC0;
9367
9368 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9369 pwow_pattern->mask[i] = mask_hw[i * 4];
9370 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
9371 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
9372 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
9373 }
9374
9375 /* To get the wake up pattern from the mask.
9376 * We do not count first 12 bits which means
9377 * DA[6] and SA[6] in the pattern to match HW design. */
9378 count = 0;
9379 for (i = 12; i < len; i++) {
9380 if ((mask[i / 8] >> (i % 8)) & 0x01) {
9381 content[count] = pattern[i];
9382 count++;
9383 }
9384 }
9385
9386 pwow_pattern->crc = rtw_calc_crc(content, count);
9387
9388 if (pwow_pattern->crc != 0) {
9389 if (pwow_pattern->type == PATTERN_INVALID)
9390 pwow_pattern->type = PATTERN_VALID;
9391 }
9392
9393 return _SUCCESS;
9394 }
9395
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)9396 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
9397 {
9398 int j;
9399
9400 RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
9401 RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
9402 RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
9403 for (j = 0; j < 4; j++)
9404 RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
9405 }
9406 /*bit definition of pattern match format*/
9407 #define WOW_VALID_BIT BIT31
9408 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
9409 #define WOW_BC_BIT BIT26
9410 #define WOW_MC_BIT BIT25
9411 #define WOW_UC_BIT BIT24
9412 #else
9413 #define WOW_BC_BIT BIT18
9414 #define WOW_UC_BIT BIT17
9415 #define WOW_MC_BIT BIT16
9416 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
9417
9418 #ifndef CONFIG_WOW_PATTERN_HW_CAM
9419 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_hal_reset_mac_rx(_adapter * adapter)9420 static void rtw_hal_reset_mac_rx(_adapter *adapter)
9421 {
9422 u8 val8 = 0;
9423 /* Set REG_CR bit1, bit3, bit7 to 0*/
9424 val8 = rtw_read8(adapter, REG_CR);
9425 val8 &= 0x75;
9426 rtw_write8(adapter, REG_CR, val8);
9427 val8 = rtw_read8(adapter, REG_CR);
9428 /* Set REG_CR bit1, bit3, bit7 to 1*/
9429 val8 |= 0x8a;
9430 rtw_write8(adapter, REG_CR, val8);
9431 RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
9432 }
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)9433 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
9434 {
9435 u8 val8 = 0;
9436 u16 rxff_bndy = 0;
9437 u32 rx_dma_buff_sz = 0;
9438
9439 val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
9440 if (val8 != 0)
9441 RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
9442 __func__, (REG_FIFOPAGE + 3));
9443
9444 rtw_hal_reset_mac_rx(adapter);
9445
9446 if (wow_mode) {
9447 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9448 (u8 *)&rx_dma_buff_sz);
9449 rxff_bndy = rx_dma_buff_sz - 1;
9450
9451 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9452 RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
9453 REG_TRXFF_BNDY + 2,
9454 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9455 } else {
9456 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
9457 (u8 *)&rx_dma_buff_sz);
9458 rxff_bndy = rx_dma_buff_sz - 1;
9459 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9460 RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
9461 REG_TRXFF_BNDY + 2,
9462 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9463 }
9464 }
9465 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO*/
9466 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9467 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9468 {
9469 u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9470 u16 offset, rx_buf_ptr = 0;
9471 u16 cam_start_offset = 0;
9472 u16 ctrl_l = 0, ctrl_h = 0;
9473 u8 count = 0, tmp = 0;
9474 int i = 0;
9475 bool res = _TRUE;
9476
9477 if (idx > MAX_WKFM_CAM_NUM) {
9478 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9479 __func__);
9480 return _FALSE;
9481 }
9482
9483 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9484 (u8 *)&rx_dma_buff_sz);
9485
9486 if (rx_dma_buff_sz == 0) {
9487 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9488 return _FALSE;
9489 }
9490
9491 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9492
9493 if (page_sz == 0) {
9494 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9495 return _FALSE;
9496 }
9497
9498 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9499 cam_start_offset = offset * page_sz;
9500
9501 ctrl_l = 0x0;
9502 ctrl_h = 0x0;
9503
9504 /* Enable RX packet buffer access */
9505 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9506
9507 /* Read the WKFM CAM */
9508 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9509 /*
9510 * Set Rx packet buffer offset.
9511 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9512 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9513 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9514 * * Index: The index of the wake up frame mask
9515 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9516 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9517 */
9518 rx_buf_ptr =
9519 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9520 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9521
9522 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9523 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9524 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9525
9526 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9527
9528 count = 0;
9529
9530 do {
9531 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9532 rtw_udelay_os(2);
9533 count++;
9534 } while (!tmp && count < 100);
9535
9536 if (count >= 100) {
9537 RTW_INFO("%s count:%d\n", __func__, count);
9538 res = _FALSE;
9539 }
9540 }
9541
9542 /* Disable RX packet buffer access */
9543 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9544 DISABLE_TRXPKT_BUF_ACCESS);
9545 return res;
9546 }
9547
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9548 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9549 struct rtl_wow_pattern *context)
9550 {
9551 u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
9552 u16 offset, rx_buf_ptr = 0;
9553 u16 cam_start_offset = 0;
9554 u16 ctrl_l = 0, ctrl_h = 0;
9555 u8 count = 0, tmp = 0;
9556 int res = 0, i = 0;
9557
9558 if (idx > MAX_WKFM_CAM_NUM) {
9559 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9560 __func__);
9561 return _FALSE;
9562 }
9563
9564 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9565 (u8 *)&rx_dma_buff_sz);
9566
9567 if (rx_dma_buff_sz == 0) {
9568 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9569 return _FALSE;
9570 }
9571
9572 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9573
9574 if (page_sz == 0) {
9575 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9576 return _FALSE;
9577 }
9578
9579 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9580
9581 cam_start_offset = offset * page_sz;
9582
9583 if (IS_HARDWARE_TYPE_8188E(adapter)) {
9584 ctrl_l = 0x0001;
9585 ctrl_h = 0x0001;
9586 } else {
9587 ctrl_l = 0x0f01;
9588 ctrl_h = 0xf001;
9589 }
9590
9591 /* Enable RX packet buffer access */
9592 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9593
9594 /* Write the WKFM CAM */
9595 for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
9596 /*
9597 * Set Rx packet buffer offset.
9598 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9599 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9600 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9601 * * Index: The index of the wake up frame mask
9602 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9603 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9604 */
9605 rx_buf_ptr =
9606 (cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
9607 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9608
9609 if (i == 0) {
9610 if (context->type == PATTERN_VALID)
9611 data = WOW_VALID_BIT;
9612 else if (context->type == PATTERN_BROADCAST)
9613 data = WOW_VALID_BIT | WOW_BC_BIT;
9614 else if (context->type == PATTERN_MULTICAST)
9615 data = WOW_VALID_BIT | WOW_MC_BIT;
9616 else if (context->type == PATTERN_UNICAST)
9617 data = WOW_VALID_BIT | WOW_UC_BIT;
9618
9619 if (context->crc != 0)
9620 data |= context->crc;
9621
9622 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9623 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9624 } else if (i == 1) {
9625 data = 0;
9626 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9627 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9628 } else if (i == 2 || i == 4) {
9629 data = context->mask[i - 2];
9630 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9631 /* write to RX packet buffer*/
9632 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9633 } else if (i == 3 || i == 5) {
9634 data = context->mask[i - 2];
9635 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9636 /* write to RX packet buffer*/
9637 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9638 }
9639
9640 count = 0;
9641 do {
9642 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9643 rtw_udelay_os(2);
9644 count++;
9645 } while (tmp && count < 100);
9646
9647 if (count >= 100)
9648 res = _FALSE;
9649 else
9650 res = _TRUE;
9651 }
9652
9653 /* Disable RX packet buffer access */
9654 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9655 DISABLE_TRXPKT_BUF_ACCESS);
9656
9657 return res;
9658 }
rtw_fill_pattern(_adapter * adapter)9659 void rtw_fill_pattern(_adapter *adapter)
9660 {
9661 int i = 0, total = 0, index;
9662 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9663 struct rtl_wow_pattern wow_pattern;
9664
9665 total = pwrpriv->wowlan_pattern_idx;
9666
9667 if (total > MAX_WKFM_CAM_NUM)
9668 total = MAX_WKFM_CAM_NUM;
9669
9670 for (i = 0 ; i < total ; i++) {
9671 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
9672
9673 index = i;
9674 if (!pwrpriv->bInSuspend)
9675 index += 2;
9676 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
9677 if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
9678 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
9679 }
9680
9681 }
9682 rtw_write8(adapter, REG_WKFMCAM_NUM, total);
9683
9684 }
9685 #else /* CONFIG_WOW_PATTERN_IN_TXFIFO */
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9686 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9687 {
9688 u32 data_l = 0, data_h = 0, page_sz = 0;
9689 u16 tx_page_start, tx_buf_ptr = 0;
9690 u16 cam_start_offset = 0;
9691 u16 ctrl_l = 0, ctrl_h = 0;
9692 u8 count = 0, tmp = 0, last_entry = 0;
9693 int i = 0;
9694 bool res = _TRUE;
9695 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9696 u32 buffer[WKFMCAM_ADDR_NUM];
9697
9698
9699 if (idx > MAX_WKFM_CAM_NUM) {
9700 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9701 __func__);
9702 return _FALSE;
9703 }
9704
9705 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9706 if (page_sz == 0) {
9707 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9708 return _FALSE;
9709 }
9710
9711 rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9712 if (last_entry == 0) {
9713 RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9714 return _FALSE;
9715 }
9716
9717
9718 if(_rtw_wow_chk_cap(adapter, WOW_CAP_HALMAC_ACCESS_PATTERN_IN_TXFIFO)) {
9719 /* 8723F cannot indirect access tx fifo
9720 * rtw_halmac_dump_fifo(dvobj, fifo_sel, fifo_addr, buf_sz, buf)
9721 */
9722 #ifdef RTW_HALMAC
9723 rtw_halmac_dump_fifo(adapter_to_dvobj(adapter),
9724 2,
9725 (pwrctl->pattern_rsvd_page_loc * page_sz) + (idx * WKFMCAM_ADDR_NUM * 4),
9726 WKFMCAM_ADDR_NUM*4, (u8*)buffer);
9727 #endif
9728
9729 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9730 RTW_INFO("[%d]: %08x %08x\n", i, *(buffer + i*2), *(buffer + i*2 + 1));
9731 }
9732 } else {
9733 /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9734 tx_page_start = last_entry - 1;
9735 cam_start_offset = tx_page_start * page_sz / 8;
9736 ctrl_l = 0x0;
9737 ctrl_h = 0x0;
9738
9739 /* Enable TX packet buffer access */
9740 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9741
9742 /* Read the WKFM CAM */
9743 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9744 /*
9745 * Set Tx packet buffer offset.
9746 * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer.
9747 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9748 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9749 * * Index: The index of the wake up frame mask
9750 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9751 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9752 */
9753 tx_buf_ptr =
9754 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9755 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr);
9756 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9757 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9758 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9759
9760 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9761
9762 count = 0;
9763
9764 do {
9765 tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9766 rtw_udelay_os(2);
9767 count++;
9768 } while (!tmp && count < 100);
9769
9770 if (count >= 100) {
9771 RTW_INFO("%s count:%d\n", __func__, count);
9772 res = _FALSE;
9773 }
9774 }
9775
9776 /* Disable RX packet buffer access */
9777 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9778 DISABLE_TRXPKT_BUF_ACCESS);
9779 }
9780
9781 return res;
9782 }
9783
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9784 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9785 struct rtl_wow_pattern *context)
9786 {
9787 u32 tx_page_start = 0, page_sz = 0;
9788 u16 tx_buf_ptr = 0;
9789 u16 cam_start_offset = 0;
9790 u32 data_l = 0, data_h = 0;
9791 u8 count = 0, tmp = 0, last_entry = 0;
9792 int res = 0, i = 0;
9793
9794 if (idx > MAX_WKFM_CAM_NUM) {
9795 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9796 __func__);
9797 return _FALSE;
9798 }
9799
9800 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9801 if (page_sz == 0) {
9802 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9803 return _FALSE;
9804 }
9805
9806 rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9807 if (last_entry == 0) {
9808 RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9809 return _FALSE;
9810 }
9811
9812 /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9813 tx_page_start = last_entry - 1;
9814 cam_start_offset = tx_page_start * page_sz / 8;
9815
9816 /* Write the PATTERN location to BIT_TXBUF_WKCAM_OFFSET */
9817 rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET, cam_start_offset & 0xFF);
9818 rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET + 1, (cam_start_offset >> 8) & 0xFF);
9819 /* Enable TX packet buffer access */
9820 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9821
9822 /* Write the WKFM CAM */
9823 for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9824 /*
9825 * Set Tx packet buffer offset.
9826 * TxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9827 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9828 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9829 * * Index: The index of the wake up frame mask
9830 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9831 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9832 */
9833 tx_buf_ptr = cam_start_offset + ((idx * WKFMCAM_SIZE + i * 8) >> 3);
9834
9835 if (i == 0) {
9836 if (context->type == PATTERN_VALID)
9837 data_l = WOW_VALID_BIT;
9838 else if (context->type == PATTERN_BROADCAST)
9839 data_l = WOW_VALID_BIT | WOW_BC_BIT;
9840 else if (context->type == PATTERN_MULTICAST)
9841 data_l = WOW_VALID_BIT | WOW_MC_BIT;
9842 else if (context->type == PATTERN_UNICAST)
9843 data_l = WOW_VALID_BIT | WOW_UC_BIT;
9844
9845 if (context->crc != 0)
9846 data_l |= context->crc;
9847
9848 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9849 } else {
9850 data_l = context->mask[i * 2 - 2];
9851 data_h = context->mask[i * 2 - 1];
9852 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9853 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h);
9854 }
9855
9856 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0x1FFF) | BIT23 | (0xff <<24));
9857 count = 0;
9858 do {
9859 tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9860 rtw_udelay_os(2);
9861 count++;
9862 } while (tmp && count < 100);
9863
9864 if (count >= 100) {
9865 res = _FALSE;
9866 RTW_INFO("%s write failed\n", __func__);
9867 } else {
9868 res = _TRUE;
9869 RTW_INFO("%s write OK\n", __func__);
9870 }
9871 }
9872
9873 /* Disable TX packet buffer access */
9874 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
9875 return res;
9876 }
rtw_write_to_frame_mask_buf(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context,char * pattern_info,u32 * ppattern_info_len)9877 bool rtw_write_to_frame_mask_buf(_adapter *adapter, u8 idx,
9878 struct rtl_wow_pattern *context, char *pattern_info, u32 *ppattern_info_len)
9879 {
9880
9881 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9882 u32 page_sz = 0;
9883 int res = _FALSE, i = 0;
9884 u32 tmp_pattern_buf[6] = {0};
9885
9886 if (pattern_info == NULL) {
9887 RTW_ERR("[Error]: %s, pattern info is NULL\n", __func__);
9888 }
9889 if (idx > MAX_WKFM_CAM_NUM) {
9890 RTW_ERR("[Error]: %s, pattern index is out of range\n",
9891 __func__);
9892 return _FALSE;
9893 }
9894
9895 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9896 if (page_sz == 0) {
9897 RTW_ERR("[Error]: %s, page_sz is 0!!\n", __func__);
9898 return _FALSE;
9899 }
9900
9901 /* Fill WKFM */
9902 for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9903 if (i == 0) {
9904 if (context->type == PATTERN_VALID)
9905 tmp_pattern_buf[0] = WOW_VALID_BIT;
9906 else if (context->type == PATTERN_BROADCAST)
9907 tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_BC_BIT;
9908 else if (context->type == PATTERN_MULTICAST)
9909 tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_MC_BIT;
9910 else if (context->type == PATTERN_UNICAST)
9911 tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_UC_BIT;
9912
9913 if (context->crc != 0)
9914 tmp_pattern_buf[0] |= context->crc;
9915 /* pattern[1] is reserved in pattern format, dont care. */
9916
9917 } else {
9918 tmp_pattern_buf[i * 2] = context->mask[i * 2 - 2];
9919 tmp_pattern_buf[i * 2 + 1] = context->mask[i * 2 - 1];
9920 }
9921 }
9922
9923
9924 /* put pattern to pattern_buf */
9925 _rtw_memcpy((pattern_info + idx * WKFMCAM_SIZE) , tmp_pattern_buf, WKFMCAM_SIZE);
9926 *ppattern_info_len += WKFMCAM_SIZE;
9927 #ifdef CONFIG_WOW_PATTERN_IN_TXFIFO_DBG
9928 RTW_INFO("\nidx : %u pattern_info_len : %u\n", idx, *ppattern_info_len);
9929 RTW_INFO_DUMP("", (pattern_info + idx * WKFMCAM_SIZE), WKFMCAM_SIZE);
9930 #endif
9931 res = _TRUE;
9932
9933
9934 return res;
9935 }
9936 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
9937
rtw_clean_pattern(_adapter * adapter)9938 void rtw_clean_pattern(_adapter *adapter)
9939 {
9940 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9941 struct rtl_wow_pattern zero_pattern;
9942 int i = 0;
9943
9944 _rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
9945
9946 zero_pattern.type = PATTERN_INVALID;
9947 /* pattern in tx fifo do not need clear to zero*/
9948
9949 rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
9950 }
9951 #if 0
9952 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
9953 u8 len, u8 *mask, u8 idx)
9954 {
9955 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9956 struct mlme_ext_priv *pmlmeext = NULL;
9957 struct mlme_ext_info *pmlmeinfo = NULL;
9958 struct rtl_wow_pattern wow_pattern;
9959 u8 mask_hw[MAX_WKFM_SIZE] = {0};
9960 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9961 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9962 u8 multicast_addr1[2] = {0x33, 0x33};
9963 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9964 u8 res = _FALSE, index = 0, mask_len = 0;
9965 u8 mac_addr[ETH_ALEN] = {0};
9966 u16 count = 0;
9967 int i, j;
9968
9969 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9970 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9971 __func__, MAX_WKFM_CAM_NUM);
9972 return _FALSE;
9973 }
9974
9975 pmlmeext = &adapter->mlmeextpriv;
9976 pmlmeinfo = &pmlmeext->mlmext_info;
9977 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9978 _rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
9979
9980 mask_len = DIV_ROUND_UP(len, 8);
9981
9982 /* 1. setup A1 table */
9983 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9984 wow_pattern.type = PATTERN_BROADCAST;
9985 else if (memcmp(pattern, multicast_addr1, 2) == 0)
9986 wow_pattern.type = PATTERN_MULTICAST;
9987 else if (memcmp(pattern, multicast_addr2, 3) == 0)
9988 wow_pattern.type = PATTERN_MULTICAST;
9989 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9990 wow_pattern.type = PATTERN_UNICAST;
9991 else
9992 wow_pattern.type = PATTERN_INVALID;
9993
9994 /* translate mask from os to mask for hw */
9995
9996 /******************************************************************************
9997 * pattern from OS uses 'ethenet frame', like this:
9998
9999 | 6 | 6 | 2 | 20 | Variable | 4 |
10000 |--------+--------+------+-----------+------------+-----|
10001 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
10002 | DA | SA | Type |
10003
10004 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
10005
10006 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
10007 |-------------------+--------+------+-----------+------------+-----|
10008 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
10009 | Others | Tpye |
10010
10011 * Therefore, we need translate mask_from_OS to mask_to_hw.
10012 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
10013 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
10014 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
10015 ******************************************************************************/
10016 /* Shift 6 bits */
10017 for (i = 0; i < mask_len - 1; i++) {
10018 mask_hw[i] = mask[i] >> 6;
10019 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
10020 }
10021
10022 mask_hw[i] = (mask[i] >> 6) & 0x3F;
10023 /* Set bit 0-5 to zero */
10024 mask_hw[0] &= 0xC0;
10025
10026 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
10027 wow_pattern.mask[i] = mask_hw[i * 4];
10028 wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
10029 wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
10030 wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
10031 }
10032
10033 /* To get the wake up pattern from the mask.
10034 * We do not count first 12 bits which means
10035 * DA[6] and SA[6] in the pattern to match HW design. */
10036 count = 0;
10037 for (i = 12; i < len; i++) {
10038 if ((mask[i / 8] >> (i % 8)) & 0x01) {
10039 content[count] = pattern[i];
10040 count++;
10041 }
10042 }
10043
10044 wow_pattern.crc = rtw_calc_crc(content, count);
10045
10046 if (wow_pattern.crc != 0) {
10047 if (wow_pattern.type == PATTERN_INVALID)
10048 wow_pattern.type = PATTERN_VALID;
10049 }
10050
10051 index = idx;
10052
10053 if (!pwrctl->bInSuspend)
10054 index += 2;
10055
10056 /* write pattern */
10057 res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
10058
10059 if (res == _FALSE)
10060 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
10061 __func__, idx);
10062
10063 return res;
10064 }
10065 #endif
10066 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
10067
10068 #define WOW_CAM_ACCESS_TIMEOUT_MS 200
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)10069 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
10070 {
10071 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10072 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10073
10074 u32 rdata = 0;
10075 u32 cnt = 0;
10076 systime start = 0;
10077 u8 timeout = 0;
10078 u8 rst = _FALSE;
10079
10080 _enter_critical_mutex(mutex, NULL);
10081
10082 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
10083
10084 start = rtw_get_current_time();
10085 while (1) {
10086 if (rtw_is_surprise_removed(adapter))
10087 break;
10088
10089 cnt++;
10090 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10091 rst = _SUCCESS;
10092 break;
10093 }
10094 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10095 timeout = 1;
10096 break;
10097 }
10098 }
10099
10100 rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
10101
10102 _exit_critical_mutex(mutex, NULL);
10103
10104 /*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
10105
10106 if (timeout)
10107 RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
10108
10109 return rdata;
10110 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10111 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
10112 {
10113 int i;
10114 u32 rdata;
10115
10116 _rtw_memset(context, 0, sizeof(struct rtl_wow_pattern));
10117
10118 for (i = 4; i >= 0; i--) {
10119 rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
10120
10121 switch (i) {
10122 case 4:
10123 if (rdata & WOW_BC_BIT)
10124 context->type = PATTERN_BROADCAST;
10125 else if (rdata & WOW_MC_BIT)
10126 context->type = PATTERN_MULTICAST;
10127 else if (rdata & WOW_UC_BIT)
10128 context->type = PATTERN_UNICAST;
10129 else
10130 context->type = PATTERN_INVALID;
10131
10132 context->crc = rdata & 0xFFFF;
10133 break;
10134 default:
10135 _rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
10136 break;
10137 }
10138 }
10139 }
10140
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)10141 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
10142 {
10143 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10144 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10145 u32 cnt = 0;
10146 systime start = 0, end = 0;
10147 u8 timeout = 0;
10148
10149 /*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
10150 _enter_critical_mutex(mutex, NULL);
10151
10152 rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
10153 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
10154
10155 start = rtw_get_current_time();
10156 while (1) {
10157 if (rtw_is_surprise_removed(adapter))
10158 break;
10159
10160 cnt++;
10161 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
10162 break;
10163
10164 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10165 timeout = 1;
10166 break;
10167 }
10168 }
10169 end = rtw_get_current_time();
10170
10171 _exit_critical_mutex(mutex, NULL);
10172
10173 if (timeout) {
10174 RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
10175 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
10176 }
10177 }
10178
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10179 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
10180 {
10181 int j;
10182 u8 addr;
10183 u32 wdata = 0;
10184
10185 for (j = 4; j >= 0; j--) {
10186 switch (j) {
10187 case 4:
10188 wdata = context->crc;
10189
10190 if (PATTERN_BROADCAST == context->type)
10191 wdata |= WOW_BC_BIT;
10192 if (PATTERN_MULTICAST == context->type)
10193 wdata |= WOW_MC_BIT;
10194 if (PATTERN_UNICAST == context->type)
10195 wdata |= WOW_UC_BIT;
10196 if (PATTERN_INVALID != context->type)
10197 wdata |= WOW_VALID_BIT;
10198 break;
10199 default:
10200 wdata = context->mask[j];
10201 break;
10202 }
10203
10204 addr = (id << 3) + j;
10205
10206 _rtw_wow_pattern_write_cam(adapter, addr, wdata);
10207 }
10208 }
10209
_rtw_wow_pattern_clean_cam(_adapter * adapter)10210 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
10211 {
10212 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10213 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10214 u32 cnt = 0;
10215 systime start = 0;
10216 u8 timeout = 0;
10217 u8 rst = _FAIL;
10218
10219 _enter_critical_mutex(mutex, NULL);
10220 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
10221
10222 start = rtw_get_current_time();
10223 while (1) {
10224 if (rtw_is_surprise_removed(adapter))
10225 break;
10226
10227 cnt++;
10228 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10229 rst = _SUCCESS;
10230 break;
10231 }
10232 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10233 timeout = 1;
10234 break;
10235 }
10236 }
10237 _exit_critical_mutex(mutex, NULL);
10238
10239 if (timeout)
10240 RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
10241
10242 return rst;
10243 }
10244
rtw_clean_pattern(_adapter * adapter)10245 void rtw_clean_pattern(_adapter *adapter)
10246 {
10247 if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
10248 RTW_ERR("rtw_clean_pattern failed\n");
10249 }
rtw_fill_pattern(_adapter * adapter)10250 void rtw_fill_pattern(_adapter *adapter)
10251 {
10252 int i = 0, total = 0;
10253 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10254 struct rtl_wow_pattern wow_pattern;
10255
10256 total = pwrpriv->wowlan_pattern_idx;
10257
10258 if (total > MAX_WKFM_CAM_NUM)
10259 total = MAX_WKFM_CAM_NUM;
10260
10261 for (i = 0 ; i < total ; i++) {
10262 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10263 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10264 rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
10265 }
10266 }
10267 }
10268
10269 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)10270 void rtw_wow_pattern_cam_dump(_adapter *adapter)
10271 {
10272
10273 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10274 int i = 0, total = 0;
10275 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10276 total = pwrpriv->wowlan_pattern_idx;
10277
10278 if (total > MAX_WKFM_CAM_NUM)
10279 total = MAX_WKFM_CAM_NUM;
10280
10281 for (i = 0 ; i < total; i++) {
10282 RTW_INFO("=======[%d]=======\n", i);
10283 rtw_read_from_frame_mask(adapter, i);
10284 }
10285 #else
10286 struct rtl_wow_pattern context;
10287 int i;
10288
10289 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10290 rtw_wow_pattern_read_cam_ent(adapter, i, &context);
10291 rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
10292 }
10293
10294 #endif
10295 }
10296
10297
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)10298 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
10299 {
10300 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10301
10302 switch (mode) {
10303 case 0:
10304 rtw_clean_pattern(adapter);
10305 RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
10306 break;
10307 case 1:
10308 #if defined(CONFIG_WOW_PATTERN_IN_TXFIFO)
10309 RTW_INFO("%s Patterns have been downloaded in rsvd pages\n", __func__);
10310 #else
10311 rtw_set_default_pattern(adapter);
10312 rtw_fill_pattern(adapter);
10313 RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
10314 #endif
10315 break;
10316 case 2:
10317 rtw_clean_pattern(adapter);
10318 rtw_wow_pattern_sw_reset(adapter);
10319 RTW_INFO("%s: clean patterns\n", __func__);
10320 break;
10321 default:
10322 RTW_INFO("%s: unknown mode\n", __func__);
10323 break;
10324 }
10325 }
10326
rtw_hal_wow_enable(_adapter * adapter)10327 static void rtw_hal_wow_enable(_adapter *adapter)
10328 {
10329 struct registry_priv *registry_par = &adapter->registrypriv;
10330 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10331 struct security_priv *psecuritypriv = &adapter->securitypriv;
10332 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10333 struct sta_info *psta = NULL;
10334 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
10335 int res;
10336 u16 media_status_rpt;
10337 u8 no_wake = 0, i;
10338 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10339 _adapter *iface;
10340 #ifdef CONFIG_GPIO_WAKEUP
10341 u8 val8 = 0;
10342 #endif
10343
10344 #ifdef CONFIG_LPS_PG
10345 u8 lps_pg_hdl_id = 0;
10346 #endif
10347
10348
10349
10350 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
10351 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
10352 no_wake = 1;
10353
10354 RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
10355 rtw_hal_gate_bb(adapter, _TRUE);
10356
10357 for (i = 0; i < dvobj->iface_nums; i++) {
10358 iface = dvobj->padapters[i];
10359 /* Start Usb TxDMA */
10360 if(iface) {
10361 RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface));
10362 RTW_ENABLE_FUNC(iface, DF_TX_BIT);
10363 }
10364 }
10365
10366 #ifdef CONFIG_GTK_OL
10367 if (psecuritypriv->binstallKCK_KEK == _TRUE)
10368 rtw_hal_fw_sync_cam_id(adapter);
10369 #endif
10370 if (IS_HARDWARE_TYPE_8723B(adapter))
10371 rtw_hal_backup_rate(adapter);
10372
10373 rtw_hal_fw_dl(adapter, _TRUE);
10374 if(no_wake)
10375 media_status_rpt = RT_MEDIA_DISCONNECT;
10376 else
10377 media_status_rpt = RT_MEDIA_CONNECT;
10378 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10379 (u8 *)&media_status_rpt);
10380
10381 /* RX DMA stop */
10382 #if defined(CONFIG_RTL8188E)
10383 if (IS_HARDWARE_TYPE_8188E(adapter))
10384 rtw_hal_disable_tx_report(adapter);
10385 #endif
10386
10387 res = rtw_hal_pause_rx_dma(adapter);
10388 if (res == _FAIL)
10389 RTW_PRINT("[WARNING] pause RX DMA fail\n");
10390
10391 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10392 /* Reconfig RX_FF Boundary */
10393 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10394 rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
10395 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10396 #endif
10397
10398 /* redownload wow pattern */
10399 if(!no_wake)
10400 rtw_hal_dl_pattern(adapter, 1);
10401
10402 if (!pwrctl->wowlan_pno_enable) {
10403 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10404
10405 if (psta != NULL) {
10406 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10407 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10408 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10409 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10410 #endif
10411 if(!no_wake)
10412 rtw_sta_media_status_rpt(adapter, psta, 1);
10413 }
10414 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10415 else {
10416 if(registry_par->suspend_type == FW_IPS_WRC) {
10417 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10418 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10419 rtw_hal_set_default_port_id_cmd(adapter, 0);
10420 }
10421 }
10422 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10423 }
10424
10425 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10426 /* Enable CPWM2 only. */
10427 res = rtw_hal_enable_cpwm2(adapter);
10428 if (res == _FAIL)
10429 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
10430 #endif
10431 #ifdef CONFIG_GPIO_WAKEUP
10432 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10433 rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10434 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10435 #else
10436 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10437 if (pwrctl->is_high_active == 0)
10438 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10439 else
10440 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10441 GPIO_OUTPUT_LOW);
10442 #else
10443 val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
10444 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8);
10445 rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10446 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n",
10447 __func__, pwrctl->wowlan_gpio_index,
10448 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10449 pwrctl->is_high_active ? "HIGI" : "LOW");
10450 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10451 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10452 #endif /* CONFIG_GPIO_WAKEUP */
10453 /* Set WOWLAN H2C command. */
10454 RTW_PRINT("Set WOWLan cmd\n");
10455 rtw_hal_set_fw_wow_related_cmd(adapter, 1);
10456
10457 res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
10458
10459 if (res == _FALSE)
10460 RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
10461
10462 pwrctl->wowlan_wake_reason =
10463 rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10464
10465 RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
10466 pwrctl->wowlan_wake_reason);
10467 #ifdef CONFIG_GTK_OL_DBG
10468 dump_sec_cam(RTW_DBGDUMP, adapter);
10469 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
10470 #endif
10471
10472 #ifdef CONFIG_LPS_PG
10473 if (pwrctl->lps_level == LPS_PG) {
10474 lps_pg_hdl_id = LPS_PG_INFO_CFG;
10475 rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
10476 }
10477 #endif
10478
10479 #ifdef CONFIG_USB_HCI
10480 /* free adapter's resource */
10481 rtw_mi_intf_stop(adapter);
10482
10483 #endif
10484 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
10485 /* Invoid SE0 reset signal during suspending*/
10486 rtw_write8(adapter, REG_RSV_CTRL, 0x20);
10487 if (IS_8188F(pHalData->version_id) == FALSE
10488 && IS_8188GTV(pHalData->version_id) == FALSE)
10489 rtw_write8(adapter, REG_RSV_CTRL, 0x60);
10490 #endif
10491
10492 rtw_hal_gate_bb(adapter, _FALSE);
10493 }
10494
10495 #define DBG_WAKEUP_REASON
10496 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)10497 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
10498 {
10499 RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
10500 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)10501 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
10502 {
10503 if (RX_PAIRWISEKEY == reason)
10504 _dbg_wake_up_reason_string(adapter, "Rx pairwise key");
10505 else if (RX_GTK == reason)
10506 _dbg_wake_up_reason_string(adapter, "Rx GTK");
10507 else if (RX_FOURWAY_HANDSHAKE == reason)
10508 _dbg_wake_up_reason_string(adapter, "Rx four way handshake");
10509 else if (RX_DISASSOC == reason)
10510 _dbg_wake_up_reason_string(adapter, "Rx disassoc");
10511 else if (RX_DEAUTH == reason)
10512 _dbg_wake_up_reason_string(adapter, "Rx deauth");
10513 else if (RX_ARP_REQUEST == reason)
10514 _dbg_wake_up_reason_string(adapter, "Rx ARP request");
10515 else if (FW_DECISION_DISCONNECT == reason)
10516 _dbg_wake_up_reason_string(adapter, "FW detect disconnect");
10517 else if (RX_MAGIC_PKT == reason)
10518 _dbg_wake_up_reason_string(adapter, "Rx magic packet");
10519 else if (RX_UNICAST_PKT == reason)
10520 _dbg_wake_up_reason_string(adapter, "Rx unicast packet");
10521 else if (RX_PATTERN_PKT == reason)
10522 _dbg_wake_up_reason_string(adapter, "Rx pattern packet");
10523 else if (RTD3_SSID_MATCH == reason)
10524 _dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
10525 else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
10526 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
10527 else if (RX_REALWOW_V2_ACK_LOST == reason)
10528 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
10529 else if (ENABLE_FAIL_DMA_IDLE == reason)
10530 _dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
10531 else if (ENABLE_FAIL_DMA_PAUSE == reason)
10532 _dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
10533 else if (AP_OFFLOAD_WAKEUP == reason)
10534 _dbg_wake_up_reason_string(adapter, "AP offload wakeup");
10535 else if (CLK_32K_UNLOCK == reason)
10536 _dbg_wake_up_reason_string(adapter, "clk 32k unlock");
10537 else if (RTIME_FAIL_DMA_IDLE == reason)
10538 _dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
10539 else if (CLK_32K_LOCK == reason)
10540 _dbg_wake_up_reason_string(adapter, "clk 32k lock");
10541 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10542 else if (WOW_KEEPALIVE_ACK_TIMEOUT == reason)
10543 _dbg_wake_up_reason_string(adapter, "rx keep alive ack timeout");
10544 else if (WOW_KEEPALIVE_WAKE == reason)
10545 _dbg_wake_up_reason_string(adapter, "rx keep alive wake pattern");
10546 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
10547 else
10548 _dbg_wake_up_reason_string(adapter, "unknown reasoen");
10549 }
10550 #endif
10551
rtw_hal_wow_disable(_adapter * adapter)10552 static void rtw_hal_wow_disable(_adapter *adapter)
10553 {
10554 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10555 struct security_priv *psecuritypriv = &adapter->securitypriv;
10556 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10557 struct sta_info *psta = NULL;
10558 struct registry_priv *registry_par = &adapter->registrypriv;
10559 int res;
10560 u16 media_status_rpt;
10561
10562 RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
10563
10564 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
10565 RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");
10566 return;
10567 }
10568
10569 if (!pwrctl->wowlan_pno_enable) {
10570 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10571 if (psta != NULL)
10572 rtw_sta_media_status_rpt(adapter, psta, 0);
10573 else
10574 RTW_INFO("%s: psta is null\n", __func__);
10575 }
10576
10577 if (0) {
10578 RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
10579 RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
10580 RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
10581 RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
10582 }
10583
10584 pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10585
10586 RTW_PRINT("wakeup_reason: 0x%02x\n",
10587 pwrctl->wowlan_wake_reason);
10588 #ifdef DBG_WAKEUP_REASON
10589 _dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
10590 #endif
10591
10592 rtw_hal_set_fw_wow_related_cmd(adapter, 0);
10593
10594 res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
10595
10596 #if defined(CONFIG_RTL8188E)
10597 if (IS_HARDWARE_TYPE_8188E(adapter))
10598 rtw_hal_enable_tx_report(adapter);
10599 #endif
10600
10601 if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10602 (pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
10603 (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
10604 rtw_hal_get_aoac_rpt(adapter);
10605 rtw_hal_update_sw_security_info(adapter);
10606 }
10607
10608 if (res == _FALSE) {
10609 RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
10610 rtw_hal_force_enable_rxdma(adapter);
10611 }
10612
10613 rtw_hal_gate_bb(adapter, _TRUE);
10614
10615 res = rtw_hal_pause_rx_dma(adapter);
10616 if (res == _FAIL)
10617 RTW_PRINT("[WARNING] pause RX DMA fail\n");
10618
10619 /* clean HW pattern match */
10620 rtw_hal_dl_pattern(adapter, 0);
10621
10622 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10623 /* config RXFF boundary to original */
10624 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10625 rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
10626 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10627 #endif
10628 rtw_hal_release_rx_dma(adapter);
10629
10630 rtw_hal_fw_dl(adapter, _FALSE);
10631
10632 #ifdef CONFIG_GPIO_WAKEUP
10633
10634 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10635 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10636 #else
10637 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10638 if (pwrctl->is_high_active == 0)
10639 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10640 else
10641 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10642 GPIO_OUTPUT_LOW);
10643 #else
10644 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index
10645 , pwrctl->wowlan_gpio_output_state);
10646 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n",
10647 __func__, pwrctl->wowlan_gpio_index,
10648 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10649 pwrctl->is_high_active ? "HIGI" : "LOW");
10650 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10651 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10652 #endif /* CONFIG_GPIO_WAKEUP */
10653 if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
10654 (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
10655 (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10656 (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
10657
10658 media_status_rpt = RT_MEDIA_CONNECT;
10659 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10660 (u8 *)&media_status_rpt);
10661
10662 if (psta != NULL) {
10663 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10664 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10665 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10666 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10667 #endif
10668 rtw_sta_media_status_rpt(adapter, psta, 1);
10669 }
10670 }
10671 rtw_hal_gate_bb(adapter, _FALSE);
10672 }
10673 #if defined(CONFIG_WOW_PATTERN_IN_TXFIFO)
rtw_hal_construct_pattern_info(PADAPTER padapter,u8 * pframe,u32 * pLength)10674 static void rtw_hal_construct_pattern_info(
10675 PADAPTER padapter,
10676 u8 *pframe,
10677 u32 *pLength
10678 )
10679 {
10680
10681 u32 pattern_info_len = 0;
10682 int i = 0, total = 0, index;
10683 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
10684 struct rtl_wow_pattern wow_pattern;
10685 u32 page_sz = 0;
10686
10687 total = pwrpriv->wowlan_pattern_idx;
10688
10689 if (total > MAX_WKFM_CAM_NUM)
10690 total = MAX_WKFM_CAM_NUM;
10691
10692 /* Generate default pattern */
10693 rtw_set_default_pattern(padapter);
10694
10695 /* Convert pattern to WKFM_CAM pattern */
10696 for (i = 0 ; i < total ; i++) {
10697 if (_SUCCESS == rtw_hal_wow_pattern_generate(padapter, i, &wow_pattern)) {
10698
10699 index = i;
10700 if (!pwrpriv->bInSuspend)
10701 index += 2;
10702 #ifdef CONFIG_WOW_PATTERN_IN_TXFIFO_DBG
10703 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10704 #endif
10705
10706 if (rtw_write_to_frame_mask_buf(padapter, index, &wow_pattern,
10707 pframe, &pattern_info_len) == _FALSE)
10708 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
10709 }
10710 }
10711 *pLength = pattern_info_len;
10712
10713
10714 }
10715 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
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)10716 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
10717 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
10718 RSVDPAGE_LOC *rsvd_page_loc)
10719 {
10720 struct security_priv *psecuritypriv = &adapter->securitypriv;
10721 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10722 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10723 struct mlme_ext_priv *pmlmeext;
10724 struct mlme_ext_info *pmlmeinfo;
10725 u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
10726 u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;
10727 u8 CurtPktPageNum = 0;
10728 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10729 u32 keep_alive_len=0;
10730 int i;
10731 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN */
10732 #ifdef CONFIG_WAR_OFFLOAD
10733 u16 tmp_idx = 0;
10734 u32 buf_len = 0;
10735 #endif
10736
10737 #ifdef CONFIG_GTK_OL
10738 struct sta_priv *pstapriv = &adapter->stapriv;
10739 struct sta_info *psta;
10740 struct security_priv *psecpriv = &adapter->securitypriv;
10741 u8 kek[RTW_KEK_LEN];
10742 u8 kck[RTW_KCK_LEN];
10743 #endif /* CONFIG_GTK_OL */
10744 #ifdef CONFIG_PNO_SUPPORT
10745 int pno_index;
10746 u8 ssid_num;
10747 #endif /* CONFIG_PNO_SUPPORT */
10748 #ifdef CONFIG_WOW_PATTERN_IN_TXFIFO
10749 u32 PatternLen = 0;
10750 u32 cam_start_offset = 0;
10751 u32 reg_cam_start_offset_val = 0;
10752 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
10753
10754 pmlmeext = &adapter->mlmeextpriv;
10755 pmlmeinfo = &pmlmeext->mlmext_info;
10756
10757 if (pwrctl->wowlan_pno_enable == _FALSE) {
10758 /* ARP RSP * 1 page */
10759
10760 rsvd_page_loc->LocArpRsp = *page_num;
10761
10762 RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
10763
10764 #ifdef CONFIG_WAR_OFFLOAD
10765 if ((0 != pwrctl->wowlan_war_offload_ipv4.ip_addr[0]) &&
10766 (_FALSE == _rtw_memcmp(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4))) {
10767 _rtw_memcpy(pmlmeinfo->ip_addr, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4);
10768 RTW_INFO("Update IP(%d.%d.%d.%d) to arp rsvd page\n",
10769 pmlmeinfo->ip_addr[0], pmlmeinfo->ip_addr[1],
10770 pmlmeinfo->ip_addr[2], pmlmeinfo->ip_addr[3]);
10771 }
10772 #endif /* CONFIG_WAR_OFFLOAD */
10773
10774
10775 rtw_hal_construct_ARPRsp(adapter, &pframe[index],
10776 &ARPLength, pmlmeinfo->ip_addr);
10777
10778 rtw_hal_fill_fake_txdesc(adapter,
10779 &pframe[index - tx_desc],
10780 ARPLength, _FALSE, _FALSE, _TRUE);
10781
10782 CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
10783
10784 *page_num += CurtPktPageNum;
10785
10786 index += (CurtPktPageNum * page_size);
10787 RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
10788 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10789 /* Keep Alive * ? page*/
10790 if(pwrctl->keep_alive_pattern_len){
10791 rsvd_page_loc->LocKeepAlive = *page_num;
10792 pwrctl->keep_alive_pattern_loc = rsvd_page_loc->LocKeepAlive;
10793 RTW_INFO("pwrctl->keep_alive_pattern_loc: %d\n", pwrctl->keep_alive_pattern_loc);
10794 rtw_hal_construct_keepalive(adapter,&pframe[index],&keep_alive_len);
10795 rtw_hal_fill_fake_txdesc(adapter,
10796 &pframe[index - tx_desc],
10797 keep_alive_len, _FALSE, _FALSE, _TRUE);
10798 CurtPktPageNum = (u8)PageNum(tx_desc + keep_alive_len, page_size);
10799 *page_num += CurtPktPageNum;
10800 index += (CurtPktPageNum * page_size);
10801 RSVD_PAGE_CFG("WOW-KeepAlive:", CurtPktPageNum, *page_num, 0);
10802 }
10803 #endif /* CONFIG_WOW_KEEP_ALIVE_PATTERN*/
10804
10805 #ifdef CONFIG_IPV6
10806 /* 2 NS offload and NDP Info*/
10807 if (pwrctl->wowlan_ns_offload_en == _TRUE) {
10808 rsvd_page_loc->LocNbrAdv = *page_num;
10809 RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
10810 rtw_hal_construct_na_message(adapter,
10811 &pframe[index], &ns_len);
10812 rtw_hal_fill_fake_txdesc(adapter,
10813 &pframe[index - tx_desc],
10814 ns_len, _FALSE,
10815 _FALSE, _TRUE);
10816 CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
10817 page_size);
10818 *page_num += CurtPktPageNum;
10819 index += (CurtPktPageNum * page_size);
10820 RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
10821
10822 rsvd_page_loc->LocNDPInfo = *page_num;
10823 RTW_INFO("LocNDPInfo: %d\n",
10824 rsvd_page_loc->LocNDPInfo);
10825
10826 rtw_hal_construct_ndp_info(adapter,
10827 &pframe[index - tx_desc],
10828 &ns_len);
10829 CurtPktPageNum =
10830 (u8)PageNum(tx_desc + ns_len, page_size);
10831 *page_num += CurtPktPageNum;
10832 index += (CurtPktPageNum * page_size);
10833 RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
10834
10835 }
10836 #endif /*CONFIG_IPV6*/
10837 /* 3 Remote Control Info. * 1 page */
10838 rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
10839 RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
10840 rtw_hal_construct_remote_control_info(adapter,
10841 &pframe[index - tx_desc],
10842 &rc_len);
10843 CurtPktPageNum = (u8)PageNum(rc_len, page_size);
10844 *page_num += CurtPktPageNum;
10845 *total_pkt_len = index + rc_len;
10846 RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
10847 #ifdef CONFIG_GTK_OL
10848 index += (CurtPktPageNum * page_size);
10849
10850 /* if the ap staion info. exists, get the kek, kck from staion info. */
10851 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
10852 if (psta == NULL) {
10853 _rtw_memset(kek, 0, RTW_KEK_LEN);
10854 _rtw_memset(kck, 0, RTW_KCK_LEN);
10855 RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
10856 __func__);
10857 } else {
10858 _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
10859 _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
10860 }
10861
10862 /* 3 KEK, KCK */
10863 rsvd_page_loc->LocGTKInfo = *page_num;
10864 RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
10865
10866 if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
10867 struct security_priv *psecpriv = NULL;
10868
10869 psecpriv = &adapter->securitypriv;
10870 _rtw_memcpy(pframe + index - tx_desc,
10871 &psecpriv->dot11PrivacyAlgrthm, 1);
10872 _rtw_memcpy(pframe + index - tx_desc + 1,
10873 &psecpriv->dot118021XGrpPrivacy, 1);
10874 _rtw_memcpy(pframe + index - tx_desc + 2,
10875 kck, RTW_KCK_LEN);
10876 _rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
10877 kek, RTW_KEK_LEN);
10878 CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
10879 } else {
10880
10881 _rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
10882 _rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
10883 kek, RTW_KEK_LEN);
10884 GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
10885
10886 if (psta != NULL &&
10887 psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
10888 _rtw_memcpy(pframe + index - tx_desc + 56,
10889 &psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
10890 GTKLength += RTW_TKIP_MIC_LEN;
10891 }
10892 CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
10893 }
10894 #if 0
10895 {
10896 int i;
10897 printk("\ntoFW KCK: ");
10898 for (i = 0; i < 16; i++)
10899 printk(" %02x ", kck[i]);
10900 printk("\ntoFW KEK: ");
10901 for (i = 0; i < 16; i++)
10902 printk(" %02x ", kek[i]);
10903 printk("\n");
10904 }
10905
10906 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
10907 __FUNCTION__, &pframe[index - tx_desc],
10908 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
10909 #endif
10910
10911 *page_num += CurtPktPageNum;
10912
10913 index += (CurtPktPageNum * page_size);
10914 RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
10915
10916 /* 3 GTK Response */
10917 rsvd_page_loc->LocGTKRsp = *page_num;
10918 RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
10919 rtw_hal_construct_GTKRsp(adapter, &pframe[index], >KLength);
10920
10921 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
10922 GTKLength, _FALSE, _FALSE, _TRUE);
10923 #if 0
10924 {
10925 int gj;
10926 printk("123GTK pkt=>\n");
10927 for (gj = 0; gj < GTKLength + tx_desc; gj++) {
10928 printk(" %02x ", pframe[index - tx_desc + gj]);
10929 if ((gj + 1) % 16 == 0)
10930 printk("\n");
10931 }
10932 printk(" <=end\n");
10933 }
10934
10935 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
10936 __FUNCTION__, &pframe[index - tx_desc],
10937 (tx_desc + GTKLength));
10938 #endif
10939
10940 CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
10941
10942 *page_num += CurtPktPageNum;
10943
10944 index += (CurtPktPageNum * page_size);
10945 RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
10946
10947 /* below page is empty for GTK extension memory */
10948 /* 3(11) GTK EXT MEM */
10949 rsvd_page_loc->LocGTKEXTMEM = *page_num;
10950 RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
10951 CurtPktPageNum = 2;
10952
10953 if (page_size >= 256)
10954 CurtPktPageNum = 1;
10955
10956 *page_num += CurtPktPageNum;
10957 /* extension memory for FW */
10958 *total_pkt_len = index + (page_size * CurtPktPageNum);
10959 RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
10960 #endif /* CONFIG_GTK_OL */
10961
10962 index += (CurtPktPageNum * page_size);
10963
10964 #ifdef CONFIG_WAR_OFFLOAD
10965 if(_TRUE == pwrctl->wowlan_war_offload_mode) {
10966 u8 zero_ary[16] = {0x00};
10967 u8 war_tmp_cnt = 0;
10968
10969 /* Reserve 2 page for Ip parameters */
10970 /* First page
10971 | Byte 15 -----------Byte 0 |
10972 | IP-4 | IP-3 | IP-2 | IP-1 |
10973 | location of each feature | mac addr |
10974 | NetBIOS name |
10975 | location of each feature |
10976 Second page
10977 | IPv6 - 1 |
10978 | IPv6 - 2 |
10979 | IPv6 - 3 |
10980 | IPv6 - 4 |
10981 | IPv6 - 5 |
10982 | IPv6 - 6 |
10983 | IPv6 - 7 |
10984 | IPv6 - 8 |
10985 */
10986
10987 /* location of each feature : Byte 22 ~ Byte 31
10988 * Byte22 : location of SNMP RX
10989 * Byte23 : location of SNMP V4
10990 * Byte24 : location of SNMP V6
10991 * Byte25 : location of MDNS Param
10992 * Byte26 : location of MDNS V4
10993 * Byte27 : location of MDNS V6
10994 * Byte28 : location of SSDP pattern
10995 * Byte29 : location of WSD pattern
10996 * Byte30 : location of SLP pattern
10997 * Byte31 : location of LLMNR
10998 */
10999
11000 /* ipv4 : 4 */
11001 if (0 == pwrctl->wowlan_war_offload_ipv4.ip_addr[0])
11002 _rtw_memcpy(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4);
11003 for(war_tmp_cnt=0; war_tmp_cnt<4 ;war_tmp_cnt++)
11004 _rtw_memcpy(pframe + index - tx_desc + (war_tmp_cnt*4), &pwrctl->wowlan_war_offload_ipv4.ip_addr[war_tmp_cnt], 4);
11005
11006 if (is_zero_mac_addr(pwrctl->wowlan_war_offload_mac)) {
11007 _rtw_memcpy(pwrctl->wowlan_war_offload_mac, adapter_mac_addr(adapter), 6);
11008 }
11009 _rtw_memcpy(pframe + index + 16 - tx_desc, pwrctl->wowlan_war_offload_mac, 6);
11010
11011
11012 /* ipv6 : 8 */
11013 if (_TRUE == _rtw_memcmp(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], zero_ary, RTW_IPv6_ADDR_LEN))
11014 _rtw_memcpy(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], pmlmeinfo->ip6_addr, RTW_IPv6_ADDR_LEN);
11015
11016 for(war_tmp_cnt=0; war_tmp_cnt<8 ;war_tmp_cnt++)
11017 _rtw_memcpy(pframe + index + page_size - tx_desc + (war_tmp_cnt*16), pwrctl->wowlan_war_offload_ipv6.ipv6_addr[war_tmp_cnt], 16);
11018
11019 rsvd_page_loc->LocIpParm = *page_num;
11020
11021 tmp_idx = index;
11022 CurtPktPageNum = 2;
11023 *page_num += CurtPktPageNum;
11024 *total_pkt_len = index + (page_size * CurtPktPageNum);
11025 index += (CurtPktPageNum * page_size);
11026
11027
11028 #if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6)
11029 if ( (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) ||
11030 (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) ||
11031 (WAR_MDNS_V4_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl) ||
11032 (WAR_MDNS_V6_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl)) {
11033
11034 struct war_mdns_service_info *psinfo = pwrctl->wowlan_war_offload_mdns_service;
11035 u8 txt_in_ptr[31]={ 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
11036 0x00, 0x13, 0x09, 0x74, 0x78, 0x74, 0x76, 0x65, 0x72, 0x73,
11037 0x3d, 0x31, 0x08, 0x71, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x3d, 0x31};
11038 u16 mdns_offset = index - tx_desc;
11039 u8 i = 0;
11040
11041 rsvd_page_loc->LocMdnsPara = *page_num;
11042 RTW_INFO("LocMdnsPara : %d\n", rsvd_page_loc->LocMdnsPara);
11043
11044 /* 1. service info */
11045 pframe[mdns_offset] = 0x01; // TLV(T)
11046 mdns_offset += 1;
11047 _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_service_info_num, 1);
11048 mdns_offset += 1;
11049
11050 for(i=0; i<pwrctl->wowlan_war_offload_mdns_service_info_num ;i++)
11051 {
11052 u16 srv_rsp_len = 0;
11053
11054 // 1.1 : construct service name string
11055 // : length of total service name string (service+transport+domain)
11056 pframe[mdns_offset] = psinfo[i].service_len + psinfo[i].transport_len + psinfo[i].domain_len + 4;
11057 mdns_offset += 1;
11058
11059 // : service name
11060 pframe[mdns_offset] = psinfo[i].service_len;
11061 mdns_offset += 1;
11062 _rtw_memcpy(pframe + mdns_offset, &psinfo[i].service, psinfo[i].service_len);
11063 mdns_offset += psinfo[i].service_len;
11064
11065 // : transport name
11066 pframe[mdns_offset] = psinfo[i].transport_len;
11067 mdns_offset += 1;
11068 _rtw_memcpy(pframe + mdns_offset, &psinfo[i].transport, psinfo[i].transport_len);
11069 mdns_offset += psinfo[i].transport_len;
11070
11071 // : domain name
11072 pframe[mdns_offset] = psinfo[i].domain_len;
11073 mdns_offset += 1;
11074 _rtw_memcpy(pframe + mdns_offset, &psinfo[i].domain, psinfo[i].domain_len);
11075 mdns_offset += psinfo[i].domain_len;
11076
11077 // : delimiter
11078 mdns_offset += 1;
11079
11080 // 1.2 : construct type srv rsp
11081 pframe[mdns_offset] = psinfo[i].target_len + 19; // length
11082 pframe[mdns_offset + 2] = 0x21; // rsp type (srv)
11083 pframe[mdns_offset + 4] = 0x01; // cache flush + class
11084 _rtw_memcpy(pframe + mdns_offset + 5, &psinfo[i].ttl, 4); // ttl
11085 pframe[mdns_offset + 5] = (u8) ( (psinfo[i].ttl & 0xff000000) >> 24); // ttl - byte0
11086 pframe[mdns_offset + 6] = (u8) ( (psinfo[i].ttl & 0x00ff0000) >> 16); // ttl - byte1
11087 pframe[mdns_offset + 7] = (u8) ( (psinfo[i].ttl & 0x0000ff00) >> 8 ); // ttl - byte2
11088 pframe[mdns_offset + 8] = (u8) (psinfo[i].ttl & 0x000000ff); // ttl - byte3
11089 pframe[mdns_offset + 10] = psinfo[i].target_len + 9; // data length
11090 _rtw_memcpy(pframe + mdns_offset + 15, &psinfo[i].port, 2); // port
11091 _rtw_memcpy(pframe + mdns_offset + 17, &psinfo[i].target_len, 1); // target len
11092 _rtw_memcpy(pframe + mdns_offset + 18, &psinfo[i].target, psinfo[i].target_len); // target
11093 pframe[mdns_offset + 18 + psinfo[i].target_len] = 0xc0; // message compresion, offset will be filled by fw.
11094 mdns_offset += (1 + psinfo[i].target_len + 19);
11095
11096 // 1.3 : set the idx of txt rsp
11097 pframe[mdns_offset] = psinfo[i].txt_rsp_idx;
11098 mdns_offset += 1;
11099 }
11100
11101 /* 2. machine name */
11102 pframe[mdns_offset] = 0x02; // TLV(T)
11103 mdns_offset += 1;
11104 _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_mnane_num, 1); // NUM
11105 mdns_offset += 1;
11106
11107 for(i=0; i<pwrctl->wowlan_war_offload_mdns_mnane_num; i++)
11108 {
11109 pframe[mdns_offset] = pwrctl->wowlan_war_offload_mdns_mnane[i].name_len;
11110 _rtw_memcpy(pframe + mdns_offset + 1, pwrctl->wowlan_war_offload_mdns_mnane[i].name,
11111 pwrctl->wowlan_war_offload_mdns_mnane[i].name_len); // machine name
11112 mdns_offset += (1+pwrctl->wowlan_war_offload_mdns_mnane[i].name_len);
11113 }
11114
11115 /* 3. A rsp */
11116 pframe[mdns_offset] = 0x03; // TLV(T)
11117 pframe[mdns_offset + 1] = 14; // TLV(L)
11118 pframe[mdns_offset + 3] = 0x01; // rsp type (a)
11119 pframe[mdns_offset + 5] = 0x01; // cache flush + class
11120 pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec)
11121 pframe[mdns_offset + 11] = 4; // length of ipv4 addr.
11122 _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4);
11123 mdns_offset += (2 + 14);
11124
11125 /* 4. AAAA rsp */
11126 pframe[mdns_offset] = 0x04; // TLV(T)
11127 pframe[mdns_offset + 1] = 26; // TLV(L)
11128 pframe[mdns_offset + 3] = 0x1c; // rsp type (aaaa)
11129 pframe[mdns_offset + 5] = 0x01; // cache flush + class
11130 pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec)
11131 pframe[mdns_offset + 11] = 16; // length of ipv6 addr.
11132 _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], 16);
11133 mdns_offset += (2 + 26);
11134
11135 /* 5. PTR rsp */
11136 pframe[mdns_offset] = 0x05; // TLV(T)
11137 pframe[mdns_offset + 1] = 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // TLV(L)
11138 pframe[mdns_offset + 3] = 0x0c; // rsp type (aaaa)
11139 pframe[mdns_offset + 5] = 0x01; // cache flush + class
11140 pframe[mdns_offset + 8] = 0x1c; // ttl
11141 pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec)
11142 pframe[mdns_offset + 11] = 3 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // data length
11143 pframe[mdns_offset + 12] = pwrctl->wowlan_war_offload_mdns_domain_name_len; // domain name length
11144 _rtw_memcpy(pframe + mdns_offset + 13, &pwrctl->wowlan_war_offload_mdns_domain_name,
11145 pwrctl->wowlan_war_offload_mdns_domain_name_len);
11146 pframe[mdns_offset + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len] = 0xc0; // message compression
11147 mdns_offset += (2 + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len);
11148
11149 /* 6. TXT in PTR rsp */
11150 pframe[mdns_offset] = 0x06; // TLV(T)
11151 pframe[mdns_offset + 1] = 31; // TLV(L)
11152 _rtw_memcpy(pframe + mdns_offset + 2, &txt_in_ptr, 31);
11153 mdns_offset += (2 + 31);
11154
11155 /* 7. TXT rsp */
11156 pframe[mdns_offset] = 0x07; // TLV(T)
11157 mdns_offset += 1;
11158 _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_txt_rsp_num, 1); // NUM
11159 mdns_offset += 1;
11160
11161 for(i=0; i<pwrctl->wowlan_war_offload_mdns_txt_rsp_num; i++)
11162 {
11163 u16 txt_rsp_len = pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len;
11164
11165 if(pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len==0)
11166 {
11167 _rtw_memcpy(pframe + mdns_offset, &txt_rsp_len, 2);
11168 mdns_offset += ( 2 + txt_rsp_len );
11169 continue;
11170 }
11171
11172 txt_rsp_len += 10;
11173 _rtw_memcpy(pframe + mdns_offset, &txt_rsp_len, 2);
11174 pframe[mdns_offset + 3] = 0x10; // rsp type (txt)
11175 pframe[mdns_offset + 5] = 0x01; // cache flush + class
11176 pframe[mdns_offset + 8] = 0x1c; // ttl
11177 pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec)
11178 pframe[mdns_offset + 10] = (u8) ((pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0xff00) >> 8);
11179 pframe[mdns_offset + 11] = (u8) (pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0x00ff);
11180 _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt,
11181 pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len);
11182 mdns_offset += ( 2 + txt_rsp_len );
11183 }
11184
11185 CurtPktPageNum = (u8)PageNum(mdns_offset - index, page_size)+1;
11186 *page_num += CurtPktPageNum;
11187 *total_pkt_len = index + (page_size * CurtPktPageNum);
11188 index += (CurtPktPageNum * page_size);
11189 }
11190 #endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */
11191
11192 #ifdef CONFIG_OFFLOAD_MDNS_V4
11193 if (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) {
11194 rsvd_page_loc->LocMdnsv4 = *page_num;
11195 RTW_INFO("LocMdnsv4: %d\n", rsvd_page_loc->LocMdnsv4);
11196
11197 rtw_hal_construct_mdns_rsp_v4(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr);
11198 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE);
11199 CurtPktPageNum = 16;
11200 *page_num += CurtPktPageNum;
11201 index += (CurtPktPageNum * page_size);
11202 }
11203 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
11204
11205 #ifdef CONFIG_OFFLOAD_MDNS_V6
11206 if (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) {
11207 rsvd_page_loc->LocMdnsv6 = *page_num;
11208 RTW_INFO("LocMdnsv6: %d\n", rsvd_page_loc->LocMdnsv6);
11209
11210 rtw_hal_construct_mdns_rsp_v6(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr);
11211 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE);
11212 CurtPktPageNum = 16;
11213 *page_num += CurtPktPageNum;
11214 index += (CurtPktPageNum * page_size);
11215 }
11216 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
11217
11218 #if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6)
11219 *(pframe+tmp_idx+25-tx_desc) = rsvd_page_loc->LocMdnsPara;
11220 *(pframe+tmp_idx+26-tx_desc) = rsvd_page_loc->LocMdnsv4;
11221 *(pframe+tmp_idx+27-tx_desc) = rsvd_page_loc->LocMdnsv6;
11222 #endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */
11223
11224 }
11225 //rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, rsvd_page_loc->LocIpParm, 46);
11226 #endif /* CONFIG_WAR_OFFLOAD */
11227
11228 #if defined(CONFIG_WOW_PATTERN_IN_TXFIFO)
11229 /* pattern_rsvd_page_loc will be used by rtw_read_from_frame_mask() */
11230 pwrctl->pattern_rsvd_page_loc = *page_num;
11231 RTW_INFO("LocPatternInfo: %d\n", pwrctl->pattern_rsvd_page_loc);
11232 rtw_hal_construct_pattern_info(adapter,
11233 &pframe[index - tx_desc],
11234 &PatternLen);
11235
11236 /* Set cam_start_offset to REG_TXBUF_WKCAM_OFFSET
11237 * Cam address(TxBufer pointer) access 8 bytes at a time
11238 */
11239
11240 // Get rsvd page start page number + pattern located page
11241 cam_start_offset = rtw_read8(adapter, REG_BCNQ_BDNY) + *page_num;
11242 cam_start_offset *= page_size;
11243 cam_start_offset /= 8;
11244
11245 reg_cam_start_offset_val = rtw_read32(adapter, REG_TXBUF_WKCAM_OFFSET);
11246 reg_cam_start_offset_val &= ~(WKCAM_OFFSET_BIT_MASK << WKCAM_OFFSET_BIT_MASK_OFFSET);
11247 reg_cam_start_offset_val |= (cam_start_offset << WKCAM_OFFSET_BIT_MASK_OFFSET);
11248 rtw_write32(adapter, REG_TXBUF_WKCAM_OFFSET, reg_cam_start_offset_val);
11249
11250 /* Set pattern number to REG_WKFMCAM_NUM */
11251 rtw_write8(adapter, REG_WKFMCAM_NUM, PatternLen / WKFMCAM_SIZE);
11252
11253 CurtPktPageNum = (u8)PageNum(PatternLen, page_size);
11254 *page_num += CurtPktPageNum;
11255 index += (CurtPktPageNum * page_size);
11256 RSVD_PAGE_CFG("WOW-PatternInfo", CurtPktPageNum, *page_num, index);
11257
11258 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
11259
11260 /*Reserve 1 page for AOAC report*/
11261 rsvd_page_loc->LocAOACReport = *page_num;
11262 RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
11263 *page_num += 1;
11264 *total_pkt_len = index + (page_size * 1);
11265 RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
11266
11267
11268 } else {
11269 #ifdef CONFIG_PNO_SUPPORT
11270 if (pwrctl->wowlan_in_resume == _FALSE &&
11271 pwrctl->pno_inited == _TRUE) {
11272
11273 /* Broadcast Probe Request */
11274 rsvd_page_loc->LocProbePacket = *page_num;
11275
11276 RTW_INFO("loc_probe_req: %d\n",
11277 rsvd_page_loc->LocProbePacket);
11278
11279 rtw_hal_construct_ProbeReq(
11280 adapter,
11281 &pframe[index],
11282 &ProbeReqLength,
11283 NULL);
11284
11285 rtw_hal_fill_fake_txdesc(adapter,
11286 &pframe[index - tx_desc],
11287 ProbeReqLength, _FALSE, _FALSE, _FALSE);
11288
11289 CurtPktPageNum =
11290 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
11291
11292 *page_num += CurtPktPageNum;
11293
11294 index += (CurtPktPageNum * page_size);
11295 RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
11296
11297 /* Hidden SSID Probe Request */
11298 ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
11299
11300 for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
11301 pwrctl->pnlo_info->loc_probe_req[pno_index] =
11302 *page_num;
11303
11304 rtw_hal_construct_ProbeReq(
11305 adapter,
11306 &pframe[index],
11307 &ProbeReqLength,
11308 &pwrctl->pno_ssid_list->node[pno_index]);
11309
11310 rtw_hal_fill_fake_txdesc(adapter,
11311 &pframe[index - tx_desc],
11312 ProbeReqLength, _FALSE, _FALSE, _FALSE);
11313
11314 CurtPktPageNum =
11315 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
11316
11317 *page_num += CurtPktPageNum;
11318
11319 index += (CurtPktPageNum * page_size);
11320 RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
11321 }
11322
11323 /* PNO INFO Page */
11324 rsvd_page_loc->LocPNOInfo = *page_num;
11325 RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
11326 rtw_hal_construct_PNO_info(adapter,
11327 &pframe[index - tx_desc],
11328 &PNOLength);
11329
11330 CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
11331 *page_num += CurtPktPageNum;
11332 index += (CurtPktPageNum * page_size);
11333 RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
11334
11335 /* Scan Info Page */
11336 rsvd_page_loc->LocScanInfo = *page_num;
11337 RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
11338 rtw_hal_construct_scan_info(adapter,
11339 &pframe[index - tx_desc],
11340 &ScanInfoLength);
11341
11342 CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
11343 *page_num += CurtPktPageNum;
11344 *total_pkt_len = index + ScanInfoLength;
11345 index += (CurtPktPageNum * page_size);
11346 RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
11347 }
11348 #endif /* CONFIG_PNO_SUPPORT */
11349 }
11350 }
11351 #endif /*CONFIG_WOWLAN*/
11352
11353 #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)11354 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
11355 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
11356 RSVDPAGE_LOC *rsvd_page_loc)
11357 {
11358 u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
11359 u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
11360 u8 CurtPktPageNum = 0;
11361
11362 /* P2P Beacon */
11363 rsvd_page_loc->LocP2PBeacon = *page_num;
11364 rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
11365 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11366 P2PBCNLength, _FALSE, _FALSE, _FALSE);
11367
11368 #if 0
11369 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
11370 __FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
11371 #endif
11372
11373 CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
11374
11375 *page_num += CurtPktPageNum;
11376
11377 index += (CurtPktPageNum * page_size);
11378 RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
11379
11380 /* P2P Probe rsp */
11381 rsvd_page_loc->LocP2PProbeRsp = *page_num;
11382 rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
11383 &P2PProbeRspLength);
11384 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11385 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
11386
11387 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", */
11388 /* __FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
11389
11390 CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
11391
11392 *page_num += CurtPktPageNum;
11393
11394 index += (CurtPktPageNum * page_size);
11395 RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
11396
11397 /* P2P nego rsp */
11398 rsvd_page_loc->LocNegoRsp = *page_num;
11399 rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
11400 &P2PNegoRspLength);
11401 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11402 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
11403
11404 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
11405 /* __FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
11406
11407 CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
11408
11409 *page_num += CurtPktPageNum;
11410
11411 index += (CurtPktPageNum * page_size);
11412 RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
11413
11414 /* P2P invite rsp */
11415 rsvd_page_loc->LocInviteRsp = *page_num;
11416 rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
11417 &P2PInviteRspLength);
11418 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11419 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
11420
11421 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
11422 /* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
11423
11424 CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
11425
11426 *page_num += CurtPktPageNum;
11427
11428 index += (CurtPktPageNum * page_size);
11429 RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
11430
11431 /* P2P provision discovery rsp */
11432 rsvd_page_loc->LocPDRsp = *page_num;
11433 rtw_hal_construct_P2PProvisionDisRsp(adapter,
11434 &pframe[index], &P2PPDRspLength);
11435
11436 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11437 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
11438
11439 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
11440 /* __FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
11441
11442 CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
11443
11444 *page_num += CurtPktPageNum;
11445
11446 *total_pkt_len = index + P2PPDRspLength;
11447 RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
11448
11449 index += (CurtPktPageNum * page_size);
11450
11451
11452 }
11453 #endif /* CONFIG_P2P_WOWLAN */
11454
11455 #ifdef CONFIG_LPS_PG
11456 #ifndef DBG_LPSPG_INFO_DUMP
11457 #define DBG_LPSPG_INFO_DUMP 1
11458 #endif
11459
11460 #include "hal_halmac.h"
11461
11462 #ifdef CONFIG_RTL8822C
rtw_lps_pg_set_dpk_info_rsvd_page(_adapter * adapter)11463 static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)
11464 {
11465 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11466 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11467 struct dm_struct *dm = adapter_to_phydm(adapter);
11468 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;
11469 u8 *info = NULL;
11470 u32 info_len;
11471 int ret = _FAIL;
11472
11473 /* get length */
11474 halrf_dpk_info_rsvd_page(dm, NULL, &info_len);
11475 if (!info_len) {
11476 RTW_ERR("get %s length fail\n", cache->name);
11477 goto exit;
11478 }
11479
11480 /* allocate buf */
11481 info = rtw_zmalloc(info_len);
11482 if (!info) {
11483 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11484 goto exit;
11485 }
11486
11487 /* get content */
11488 halrf_dpk_info_rsvd_page(dm, info, NULL);
11489
11490 if (rsvd_page_cache_update_data(cache, info, info_len)) {
11491
11492 #if (DBG_LPSPG_INFO_DUMP >= 1)
11493 RTW_INFO_DUMP(cache->name, info, info_len);
11494 #endif
11495
11496 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11497 ret = !ret ? _SUCCESS : _FAIL;
11498 if (ret != _SUCCESS) {
11499 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11500 goto free_mem;
11501 }
11502
11503 #if (DBG_LPSPG_INFO_DUMP >= 2)
11504 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11505 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11506 #endif
11507 }
11508
11509 free_mem:
11510 rtw_mfree(info, info_len);
11511
11512 exit:
11513 return ret;
11514 }
11515
rtw_lps_pg_set_iqk_info_rsvd_page(_adapter * adapter)11516 static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)
11517 {
11518 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11519 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11520 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11521 struct dm_struct *dm = adapter_to_phydm(adapter);
11522 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;
11523 u8 *info = NULL;
11524 u32 info_len = 0;
11525 int ret = _FAIL;
11526
11527 if (hal_data->RegIQKFWOffload) {
11528 rsvd_page_cache_free_data(cache);
11529 ret = _SUCCESS;
11530 goto exit;
11531 }
11532
11533 /* get length */
11534 halrf_iqk_info_rsvd_page(dm, NULL, &info_len);
11535 if (!info_len) {
11536 RTW_ERR("get %s length fail\n", cache->name);
11537 goto exit;
11538 }
11539
11540 /* allocate buf */
11541 info = rtw_zmalloc(info_len);
11542 if (!info) {
11543 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11544 goto exit;
11545 }
11546
11547 /* get content */
11548 halrf_iqk_info_rsvd_page(dm, info, NULL);
11549
11550 if (rsvd_page_cache_update_data(cache, info, info_len)) {
11551
11552 #if (DBG_LPSPG_INFO_DUMP >= 1)
11553 RTW_INFO_DUMP(cache->name, info, info_len);
11554 #endif
11555
11556 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11557 ret = !ret ? _SUCCESS : _FAIL;
11558 if (ret != _SUCCESS) {
11559 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11560 goto free_mem;
11561 }
11562
11563 #if (DBG_LPSPG_INFO_DUMP >= 2)
11564 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11565 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11566 #endif
11567 }
11568
11569 free_mem:
11570 rtw_mfree(info, info_len);
11571
11572 exit:
11573 return ret;
11574 }
11575 #endif /* CONFIG_RTL8822C */
11576
rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv * dvobj,_adapter * ld_sta_iface,u8 * buf,u32 * buf_size)11577 static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size)
11578 {
11579 #define LPS_PG_INFO_RSVD_LEN 16
11580
11581 if (buf) {
11582 _adapter *adapter = dvobj_get_primary_adapter(dvobj);
11583 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11584 struct sta_info *psta;
11585 #ifdef CONFIG_MBSSID_CAM
11586 u8 cam_id = INVALID_CAM_ID;
11587 #endif
11588 u8 *psec_cam_id = buf + 8;
11589 u8 sec_cam_num = 0;
11590 u8 drv_rsvdpage_num = 0;
11591
11592 if (ld_sta_iface) {
11593 psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv));
11594 if (!psta) {
11595 RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
11596 rtw_warn_on(1);
11597 goto size_chk;
11598 }
11599 /*Byte 0 - used macid*/
11600 LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);
11601 RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
11602 }
11603
11604 #ifdef CONFIG_MBSSID_CAM
11605 /*Byte 1 - used BSSID CAM entry*/
11606 cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
11607 if (cam_id != INVALID_CAM_ID)
11608 LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);
11609 RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
11610 #endif
11611
11612 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
11613 /*Btye 2 - Max used Pattern Match CAM entry*/
11614 if (pwrpriv->wowlan_mode == _TRUE
11615 && ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11616 LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);
11617 RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
11618 }
11619 #endif
11620 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
11621 /*Btye 3 - Max MU rate table Group ID*/
11622 LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);
11623 RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
11624 #endif
11625
11626 /*Btye 8 ~15 - used Security CAM entry */
11627 sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
11628
11629 /*Btye 4 - used Security CAM entry number*/
11630 if (sec_cam_num < 8)
11631 LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);
11632 RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
11633
11634 /*Btye 5 - Txbuf used page number for fw offload*/
11635 if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
11636 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11637 else
11638 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11639 LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);
11640 RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
11641 }
11642
11643 size_chk:
11644 if (buf_size)
11645 *buf_size = LPS_PG_INFO_RSVD_LEN;
11646 }
11647
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)11648 static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
11649 {
11650 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11651 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11652 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;
11653 u8 *info = NULL;
11654 u32 info_len = 0;
11655 int ret = _FAIL;
11656
11657 /* get length */
11658 rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len);
11659 if (!info_len) {
11660 RTW_ERR("get %s length fail\n", cache->name);
11661 goto exit;
11662 }
11663
11664 /* allocate buf */
11665 info = rtw_zmalloc(info_len);
11666 if (!info) {
11667 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11668 goto exit;
11669 }
11670
11671 /* get content */
11672 rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL);
11673
11674 if (rsvd_page_cache_update_data(cache, info, info_len)) {
11675
11676 #if (DBG_LPSPG_INFO_DUMP >= 1)
11677 RTW_INFO_DUMP(cache->name, info, info_len);
11678 #endif
11679
11680 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11681 ret = !ret ? _SUCCESS : _FAIL;
11682 if (ret != _SUCCESS) {
11683 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11684 goto free_mem;
11685 }
11686
11687 #if (DBG_LPSPG_INFO_DUMP >= 2)
11688 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11689 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11690 #endif
11691 }
11692
11693 free_mem:
11694 rtw_mfree(info, info_len);
11695
11696 exit:
11697 return ret;
11698 }
11699
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)11700 static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index
11701 , u8 txdesc_size, u32 page_size, u8 *total_page_num
11702 , bool is_wow_mode, _adapter *ld_sta_iface, bool only_get_page_num)
11703 {
11704 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11705 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
11706 struct rsvd_page_cache_t *cache;
11707 bool rsvd = 1;
11708 u8 *pos;
11709 u32 len;
11710
11711 if (is_wow_mode) {
11712 /* lps_level will not change when enter wow_mode */
11713 if (pwrctl->lps_level != LPS_PG)
11714 rsvd = 0;
11715 } else {
11716 if (!only_get_page_num && !ld_sta_iface)
11717 rsvd = 0;
11718 }
11719
11720 pos = only_get_page_num ? NULL : frame + *index;
11721
11722 #ifdef CONFIG_RTL8822C
11723 if (IS_8822C_SERIES(hal_data->version_id)) {
11724 /* LPSPG_DPK_INFO */
11725 cache = &pwrctl->lpspg_dpk_info;
11726 if (rsvd) {
11727 if (pwrctl->lps_level != LPS_PG)
11728 pos = NULL;
11729 len = 0;
11730 halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
11731 #if (DBG_LPSPG_INFO_DUMP >= 1)
11732 if (pos)
11733 RTW_INFO_DUMP(cache->name, pos, len);
11734 #endif
11735 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11736 *total_page_num += cache->page_num;
11737 *index += page_size * cache->page_num;
11738 pos = only_get_page_num ? NULL : frame + *index;
11739 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11740 } else
11741 rsvd_page_cache_free(cache);
11742
11743 /* LPSPG_IQK_INFO */
11744 cache = &pwrctl->lpspg_iqk_info;
11745 if (rsvd
11746 /* RegIQKFWOffload will not change when enter wow_mode */
11747 && !(is_wow_mode && hal_data->RegIQKFWOffload)
11748 ) {
11749 if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)
11750 pos = NULL;
11751 len = 0;
11752 halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
11753 #if (DBG_LPSPG_INFO_DUMP >= 1)
11754 if (pos)
11755 RTW_INFO_DUMP(cache->name, pos, len);
11756 #endif
11757 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11758 *total_page_num += cache->page_num;
11759 *index += page_size * cache->page_num;
11760 pos = only_get_page_num ? NULL : frame + *index;
11761 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11762 } else
11763 rsvd_page_cache_free(cache);
11764 }
11765 #endif
11766
11767 /* LPSPG_INFO */
11768 cache = &pwrctl->lpspg_info;
11769 if (rsvd) {
11770 if (pwrctl->lps_level != LPS_PG)
11771 pos = NULL;
11772 rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len);
11773 #if (DBG_LPSPG_INFO_DUMP >= 1)
11774 if (pos)
11775 RTW_INFO_DUMP(cache->name, pos, len);
11776 #endif
11777 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11778 *total_page_num += cache->page_num;
11779 *index += page_size * cache->page_num;
11780 pos = only_get_page_num ? NULL : frame + *index;
11781 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11782 } else
11783 rsvd_page_cache_free(cache);
11784 }
11785
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)11786 u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
11787 {
11788 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11789 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11790
11791 u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
11792 u8 ret = _FAIL;
11793
11794 if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
11795 SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1); /*SecurityCAM_En*/
11796
11797 #ifdef CONFIG_MBSSID_CAM
11798 SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1); /*BSSIDCAM_En*/
11799 #endif
11800
11801 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
11802 if (pwrpriv->wowlan_mode == _TRUE &&
11803 check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11804
11805 SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/
11806 }
11807 #endif
11808
11809 #ifdef CONFIG_MACID_SEARCH
11810 SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1); /*MACIDSearch_En*/
11811 #endif
11812
11813 #ifdef CONFIG_TX_SC
11814 SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1); /*TXSC_En*/
11815 #endif
11816
11817 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
11818 SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1); /*MURateTable_En*/
11819 #endif
11820
11821 SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);
11822
11823 #ifdef CONFIG_RTL8822C
11824 if (pwrpriv->bFwCurrentInPSMode == _FALSE) {
11825 SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);
11826 if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11827 SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);
11828 } else {
11829 SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0);
11830 if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11831 SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0);
11832 }
11833 #endif
11834
11835 #if (DBG_LPSPG_INFO_DUMP >= 1)
11836 RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);
11837 #endif
11838
11839 ret = rtw_hal_fill_h2c_cmd(adapter,
11840 H2C_LPS_PG_INFO,
11841 H2C_LPS_PG_INFO_LEN,
11842 lpspg_info);
11843 return ret;
11844 }
rtw_hal_set_lps_pg_info(_adapter * adapter)11845 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
11846 {
11847 u8 ret = _FAIL;
11848 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11849
11850 if (pwrpriv->lpspg_info.loc == 0) {
11851 RTW_ERR("%s lpspg_info.loc = 0\n", __func__);
11852 rtw_warn_on(1);
11853 return ret;
11854 }
11855 #ifdef CONFIG_RTL8822C
11856 rtw_lps_pg_set_dpk_info_rsvd_page(adapter);
11857 rtw_lps_pg_set_iqk_info_rsvd_page(adapter);
11858 #endif
11859 rtw_hal_set_lps_pg_info_rsvd_page(adapter);
11860
11861 ret = rtw_hal_set_lps_pg_info_cmd(adapter);
11862
11863 return ret;
11864 }
11865
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)11866 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
11867 {
11868 #if 0
11869 if (sta->cmn.ra_info.rssi_level >= 4)
11870 sta->lps_pg_rssi_lv = 3; /*RSSI High - 1SS_VHT_MCS7*/
11871 else if (sta->cmn.ra_info.rssi_level >= 2)
11872 sta->lps_pg_rssi_lv = 2; /*RSSI Middle - 1SS_VHT_MCS3*/
11873 else
11874 sta->lps_pg_rssi_lv = 1; /*RSSI Lower - Lowest_rate*/
11875 #else
11876 sta->lps_pg_rssi_lv = 0;
11877 #endif
11878 RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
11879 __func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
11880 }
11881
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)11882 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
11883 {
11884 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
11885 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11886 struct sta_priv *pstapriv = &adapter->stapriv;
11887 struct sta_info *sta;
11888
11889 sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
11890
11891 switch (hdl_id) {
11892 case LPS_PG_INFO_CFG:
11893 rtw_hal_set_lps_pg_info(adapter);
11894 break;
11895 case LPS_PG_REDLEMEM:
11896 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11897 break;
11898
11899 /*set xmit_block*/
11900 rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11901 if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
11902 rtw_warn_on(1);
11903 /*clearn xmit_block*/
11904 rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11905 break;
11906 case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
11907 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11908 break;
11909
11910 if (sta)
11911 rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
11912 break;
11913 case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
11914 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11915 break;
11916
11917 if (sta) {
11918 rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
11919 rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
11920 sta->lps_pg_rssi_lv = 0;
11921 }
11922 break;
11923
11924 default:
11925 break;
11926 }
11927 }
11928
11929 #endif /*CONFIG_LPS_PG*/
11930
_rtw_mi_assoc_if_num(_adapter * adapter)11931 static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
11932 {
11933 u8 mi_iface_num = 0;
11934
11935 if (0) {
11936 RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
11937 RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
11938 RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11939 RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
11940 RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
11941 /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
11942 /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
11943 }
11944
11945 mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
11946 DEV_AP_NUM(adapter_to_dvobj(adapter)) +
11947 DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11948 return mi_iface_num;
11949 }
11950 #ifdef CONFIG_CONCURRENT_MODE
_rtw_search_sta_iface(_adapter * adapter)11951 static _adapter *_rtw_search_sta_iface(_adapter *adapter)
11952 {
11953 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11954 _adapter *iface = NULL;
11955 _adapter *sta_iface = NULL;
11956 int i;
11957
11958 for (i = 0; i < dvobj->iface_nums; i++) {
11959 iface = dvobj->padapters[i];
11960 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
11961 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11962 sta_iface = iface;
11963 break;
11964 }
11965 }
11966 }
11967 return sta_iface;
11968 }
11969 #if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)
_rtw_search_ap_iface(_adapter * adapter)11970 static _adapter *_rtw_search_ap_iface(_adapter *adapter)
11971 {
11972 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11973 _adapter *iface = NULL;
11974 _adapter *ap_iface = NULL;
11975 int i;
11976
11977 for (i = 0; i < dvobj->iface_nums; i++) {
11978 iface = dvobj->padapters[i];
11979 if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
11980 ap_iface = iface;
11981 break;
11982 }
11983 }
11984 return ap_iface;
11985 }
11986 #endif/*CONFIG_AP_MODE*/
11987 #endif/*CONFIG_CONCURRENT_MODE*/
11988
11989 #ifdef CONFIG_CUSTOMER01_SMART_ANTENNA
rtw_hal_set_pathb_phase(_adapter * adapter,u8 phase_idx)11990 void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)
11991 {
11992 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
11993 struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
11994
11995 return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);
11996 }
11997 #endif
11998
11999 /*
12000 * Description: Fill the reserved packets that FW will use to RSVD page.
12001 * Now we just send 4 types packet to rsvd page.
12002 * (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
12003 * Input:
12004 * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
12005 * so we need to set the packet length to total lengh.
12006 * TRUE: At the second time, we should send the first packet (default:beacon)
12007 * to Hw again and set the lengh in descriptor to the real beacon lengh.
12008 * page_num - The amount of reserved page which driver need.
12009 * If this is not NULL, this function doesn't real download reserved
12010 * page, but just count the number of reserved page.
12011 *
12012 * 2009.10.15 by tynli.
12013 * 2017.06.20 modified by Lucas.
12014 *
12015 * Page Size = 128: 8188e, 8723a/b, 8192c/d,
12016 * Page Size = 256: 8192e, 8821a
12017 * Page Size = 512: 8812a
12018 */
12019
12020 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)12021 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
12022 {
12023 PHAL_DATA_TYPE pHalData;
12024 struct xmit_frame *pcmdframe = NULL;
12025 struct pkt_attrib *pattrib;
12026 struct xmit_priv *pxmitpriv;
12027 struct pwrctrl_priv *pwrctl;
12028 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12029 u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
12030 u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
12031 u32 ProbeReqLength = 0, NullFunctionDataLength = 0;
12032 u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
12033 u8 TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
12034 u8 *ReservedPagePacket;
12035 u16 BufIndex = 0;
12036 u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
12037 RSVDPAGE_LOC RsvdPageLoc;
12038 struct registry_priv *registry_par = &adapter->registrypriv;
12039
12040 #ifdef DBG_FW_DEBUG_MSG_PKT
12041 u32 fw_dbg_msg_pkt_len = 0;
12042 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12043
12044 #ifdef DBG_CONFIG_ERROR_DETECT
12045 struct sreset_priv *psrtpriv;
12046 #endif /* DBG_CONFIG_ERROR_DETECT */
12047
12048 #ifdef CONFIG_MCC_MODE
12049 u8 dl_mcc_page = _FAIL;
12050 #endif /* CONFIG_MCC_MODE */
12051 u8 nr_assoc_if;
12052
12053 _adapter *sta_iface = NULL;
12054 _adapter *ap_iface = NULL;
12055
12056 bool is_wow_mode = _FALSE;
12057
12058 pHalData = GET_HAL_DATA(adapter);
12059 #ifdef DBG_CONFIG_ERROR_DETECT
12060 psrtpriv = &pHalData->srestpriv;
12061 #endif
12062 pxmitpriv = &adapter->xmitpriv;
12063 pwrctl = adapter_to_pwrctl(adapter);
12064
12065 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
12066
12067 if (PageSize == 0) {
12068 RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
12069 return;
12070 }
12071 nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
12072
12073 if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
12074 pwrctl->wowlan_ap_mode == _TRUE ||
12075 pwrctl->wowlan_p2p_mode == _TRUE)
12076 is_wow_mode = _TRUE;
12077
12078 /*page_num for init time to get rsvd page number*/
12079 /* Prepare ReservedPagePacket */
12080 if (page_num) {
12081 ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
12082 if (!ReservedPagePacket) {
12083 RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
12084 *page_num = 0xFF;
12085 return;
12086 }
12087 RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm ==>\n",
12088 FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
12089
12090 } else {
12091 if (is_wow_mode)
12092 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
12093 else
12094 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
12095
12096 RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
12097 FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
12098
12099 MaxRsvdPageBufSize = RsvdPageNum * PageSize;
12100 if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
12101 RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
12102 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
12103 rtw_warn_on(1);
12104 return;
12105 }
12106
12107 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
12108 if (pcmdframe == NULL) {
12109 RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
12110 return;
12111 }
12112
12113 ReservedPagePacket = pcmdframe->buf_addr;
12114 }
12115
12116 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
12117
12118 BufIndex = TxDescOffset;
12119
12120 /*======== beacon content =======*/
12121 rtw_hal_construct_beacon(adapter,
12122 &ReservedPagePacket[BufIndex], &BeaconLength);
12123
12124 /*
12125 * When we count the first page size, we need to reserve description size for the RSVD
12126 * packet, it will be filled in front of the packet in TXPKTBUF.
12127 */
12128 BeaconLength = MAX_BEACON_LEN - TxDescLen;
12129 CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
12130
12131 #if defined(CONFIG_FW_HANDLE_TXBCN) || defined(CONFIG_PORT_BASED_TXBCN)
12132 CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
12133 #endif
12134 TotalPageNum += CurtPktPageNum;
12135
12136 BufIndex += (CurtPktPageNum * PageSize);
12137
12138 RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12139
12140 /*======== probe response content ========*/
12141 if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
12142 #ifdef CONFIG_CONCURRENT_MODE
12143 if (nr_assoc_if >= 2)
12144 RTW_ERR("Not support > 2 net-interface in WOW\n");
12145 #endif
12146 /* (4) probe response*/
12147 RsvdPageLoc.LocProbeRsp = TotalPageNum;
12148 rtw_hal_construct_ProbeRsp(
12149 adapter, &ReservedPagePacket[BufIndex],
12150 &ProbeRspLength,
12151 _FALSE);
12152 rtw_hal_fill_fake_txdesc(adapter,
12153 &ReservedPagePacket[BufIndex - TxDescLen],
12154 ProbeRspLength, _FALSE, _FALSE, _FALSE);
12155
12156 CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
12157 TotalPageNum += CurtPktPageNum;
12158 TotalPacketLen = BufIndex + ProbeRspLength;
12159 BufIndex += (CurtPktPageNum * PageSize);
12160 RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12161 goto download_page;
12162 }
12163
12164 /*======== ps-poll content * 1 page ========*/
12165 sta_iface = adapter;
12166 #ifdef CONFIG_CONCURRENT_MODE
12167 if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
12168 sta_iface = _rtw_search_sta_iface(adapter);
12169 RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
12170 }
12171 #endif
12172
12173 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12174 RsvdPageLoc.LocPsPoll = TotalPageNum;
12175 RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
12176 rtw_hal_construct_PSPoll(sta_iface,
12177 &ReservedPagePacket[BufIndex], &PSPollLength);
12178 rtw_hal_fill_fake_txdesc(sta_iface,
12179 &ReservedPagePacket[BufIndex - TxDescLen],
12180 PSPollLength, _TRUE, _FALSE, _FALSE);
12181
12182 CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
12183
12184 TotalPageNum += CurtPktPageNum;
12185
12186 BufIndex += (CurtPktPageNum * PageSize);
12187 RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12188 }
12189
12190 #ifdef CONFIG_MCC_MODE
12191 /*======== MCC * n page ======== */
12192 if (MCC_EN(adapter)) {/*Normal mode*/
12193 dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
12194 &BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
12195 } else {
12196 dl_mcc_page = _FAIL;
12197 }
12198
12199 if (dl_mcc_page == _FAIL)
12200 #endif /* CONFIG_MCC_MODE */
12201 { /*======== null data * 1 page ======== */
12202 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12203 RsvdPageLoc.LocNullData = TotalPageNum;
12204 RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
12205 rtw_hal_construct_NullFunctionData(
12206 sta_iface,
12207 &ReservedPagePacket[BufIndex],
12208 &NullDataLength,
12209 _FALSE, 0, 0, _FALSE);
12210 rtw_hal_fill_fake_txdesc(sta_iface,
12211 &ReservedPagePacket[BufIndex - TxDescLen],
12212 NullDataLength, _FALSE, _FALSE, _FALSE);
12213
12214 CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
12215
12216 TotalPageNum += CurtPktPageNum;
12217
12218 BufIndex += (CurtPktPageNum * PageSize);
12219 RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12220 }
12221 }
12222
12223 /*======== Qos null data * 1 page ======== */
12224 if (pwrctl->wowlan_mode == _FALSE ||
12225 pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
12226 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12227 RsvdPageLoc.LocQosNull = TotalPageNum;
12228 RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
12229 rtw_hal_construct_NullFunctionData(sta_iface,
12230 &ReservedPagePacket[BufIndex],
12231 &QosNullLength,
12232 _TRUE, 0, 0, _FALSE);
12233 rtw_hal_fill_fake_txdesc(sta_iface,
12234 &ReservedPagePacket[BufIndex - TxDescLen],
12235 QosNullLength, _FALSE, _FALSE, _FALSE);
12236
12237 CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
12238 PageSize);
12239
12240 TotalPageNum += CurtPktPageNum;
12241
12242 BufIndex += (CurtPktPageNum * PageSize);
12243 RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12244 }
12245 }
12246
12247 #ifdef CONFIG_BT_COEXIST
12248 /*======== BT Qos null data * 1 page ======== */
12249 if (pwrctl->wowlan_mode == _FALSE ||
12250 pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
12251
12252 ap_iface = adapter;
12253 #if defined (CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
12254 if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) { /*DEV_AP_STARTING_NUM*/
12255 ap_iface = _rtw_search_ap_iface(adapter);
12256 RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
12257 }
12258 #endif
12259
12260 if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
12261 RsvdPageLoc.LocBTQosNull = TotalPageNum;
12262
12263 RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
12264
12265 rtw_hal_construct_NullFunctionData(ap_iface,
12266 &ReservedPagePacket[BufIndex],
12267 &BTQosNullLength,
12268 _TRUE, 0, 0, _FALSE);
12269
12270 rtw_hal_fill_fake_txdesc(ap_iface,
12271 &ReservedPagePacket[BufIndex - TxDescLen],
12272 BTQosNullLength, _FALSE, _TRUE, _FALSE);
12273
12274 CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
12275 PageSize);
12276
12277 TotalPageNum += CurtPktPageNum;
12278 BufIndex += (CurtPktPageNum * PageSize);
12279
12280 RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12281 }
12282 }
12283 #endif /* CONFIG_BT_COEXIT */
12284
12285 TotalPacketLen = BufIndex;
12286
12287 #ifdef DBG_FW_DEBUG_MSG_PKT
12288 /*======== FW DEBUG MSG * n page ======== */
12289 RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
12290 RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
12291 rtw_hal_construct_fw_dbg_msg_pkt(
12292 adapter,
12293 &ReservedPagePacket[BufIndex],
12294 &fw_dbg_msg_pkt_len);
12295
12296 rtw_hal_fill_fake_txdesc(adapter,
12297 &ReservedPagePacket[BufIndex - TxDescLen],
12298 fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
12299
12300 CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
12301
12302 if (CurtPktPageNum < 2)
12303 CurtPktPageNum = 2; /*Need at least 2 rsvd page*/
12304 TotalPageNum += CurtPktPageNum;
12305
12306 TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
12307 BufIndex += (CurtPktPageNum * PageSize);
12308 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12309
12310 #ifdef CONFIG_LPS_PG
12311 rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex
12312 , TxDescLen, PageSize, &TotalPageNum, is_wow_mode
12313 , (sta_iface && MLME_IS_STA(sta_iface) && MLME_IS_ASOC(sta_iface)) ? sta_iface : NULL
12314 , page_num ? 1 : 0
12315 );
12316 TotalPacketLen = BufIndex;
12317 #endif
12318
12319 #ifdef CONFIG_WOWLAN
12320 /*======== WOW * n page ======== */
12321 if (pwrctl->wowlan_mode == _TRUE &&
12322 pwrctl->wowlan_in_resume == _FALSE &&
12323 check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {/*WOW mode*/
12324 rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
12325 BufIndex, TxDescLen, PageSize,
12326 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
12327 #ifdef CONFIG_WAR_OFFLOAD
12328 rtw_hal_set_war_offload_parm(adapter, &RsvdPageLoc);
12329 #endif /* CONFIG_WAR_OFFLOAD */
12330 }
12331 #endif /* CONFIG_WOWLAN */
12332
12333 #ifdef CONFIG_P2P_WOWLAN
12334 /*======== P2P WOW * n page ======== */
12335 if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
12336 rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
12337 BufIndex, TxDescLen, PageSize,
12338 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
12339 }
12340 #endif /* CONFIG_P2P_WOWLAN */
12341
12342 /*Note: BufIndex already add a TxDescOffset offset in first Beacon page
12343 * The "TotalPacketLen" is calculate by BufIndex.
12344 * We need to decrease TxDescOffset before doing length check. by yiwei
12345 */
12346 TotalPacketLen = TotalPacketLen - TxDescOffset;
12347
12348 download_page:
12349 if (page_num) {
12350 *page_num = TotalPageNum;
12351 rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
12352 ReservedPagePacket = NULL;
12353 RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
12354 FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
12355 return;
12356 }
12357
12358 /* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
12359 RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
12360 __func__, TotalPageNum, TotalPacketLen);
12361
12362 if (TotalPacketLen > MaxRsvdPageBufSize) {
12363 RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
12364 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
12365 rtw_warn_on(1);
12366 goto error;
12367 } else {
12368 /* update attribute */
12369 pattrib = &pcmdframe->attrib;
12370 update_mgntframe_attrib(adapter, pattrib);
12371 pattrib->qsel = QSLT_BEACON;
12372 pattrib->pktlen = TotalPacketLen;
12373 pattrib->last_txcmdsz = TotalPacketLen;
12374 #ifdef CONFIG_PCI_HCI
12375 dump_mgntframe(adapter, pcmdframe);
12376 #else
12377 dump_mgntframe_and_wait(adapter, pcmdframe, 100);
12378 #endif
12379 }
12380
12381 RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
12382 __func__, TotalPacketLen, TotalPageNum);
12383 #ifdef DBG_DUMP_SET_RSVD_PAGE
12384 RTW_INFO(" ==================================================\n");
12385 RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
12386 RTW_INFO(" ==================================================\n");
12387 #endif
12388
12389
12390 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
12391 || MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
12392 rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
12393 #ifdef DBG_FW_DEBUG_MSG_PKT
12394 rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
12395 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12396 #ifdef CONFIG_WOWLAN
12397 if (pwrctl->wowlan_mode == _TRUE &&
12398 pwrctl->wowlan_in_resume == _FALSE)
12399 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
12400 #endif /* CONFIG_WOWLAN */
12401 #ifdef CONFIG_AP_WOWLAN
12402 if (pwrctl->wowlan_ap_mode == _TRUE)
12403 rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
12404 #endif /* CONFIG_AP_WOWLAN */
12405 } else if (pwrctl->wowlan_pno_enable) {
12406 #ifdef CONFIG_PNO_SUPPORT
12407 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
12408 if (pwrctl->wowlan_in_resume)
12409 rtw_hal_set_scan_offload_info_cmd(adapter,
12410 &RsvdPageLoc, 0);
12411 else
12412 rtw_hal_set_scan_offload_info_cmd(adapter,
12413 &RsvdPageLoc, 1);
12414 #endif /* CONFIG_PNO_SUPPORT */
12415 }
12416
12417 #ifdef CONFIG_P2P_WOWLAN
12418 if (_TRUE == pwrctl->wowlan_p2p_mode)
12419 rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
12420 #endif /* CONFIG_P2P_WOWLAN */
12421
12422 return;
12423 error:
12424 rtw_free_xmitframe(pxmitpriv, pcmdframe);
12425 }
12426
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)12427 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
12428 {
12429 #ifdef CONFIG_AP_MODE
12430 if (finished)
12431 rtw_mi_tx_beacon_hdl(adapter);
12432 else
12433 #endif
12434 _rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
12435 }
12436
rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER * adapter,u8 enable)12437 static u8 rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER *adapter, u8 enable)
12438 {
12439 u8 u1H2CSetPwrMode[H2C_PWRMODE_LEN] = {0};
12440 u8 ret = _FAIL;
12441
12442 #ifdef CONFIG_TDLS
12443 #ifdef CONFIG_TDLS_CH_SW
12444 if (ATOMIC_READ(&adapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12445 {
12446 SET_H2CCMD_PWRMODE_PARM_RLBM(u1H2CSetPwrMode, 1);
12447 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CSetPwrMode, 0);
12448 }
12449 #endif
12450 #endif
12451
12452 SET_H2CCMD_PWRMODE_PARM_MODE(u1H2CSetPwrMode, 0);
12453 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CSetPwrMode, 0x0C);
12454 SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_C2H_RPT(u1H2CSetPwrMode, enable);
12455
12456 ret = rtw_hal_fill_h2c_cmd(adapter,
12457 H2C_SET_PWR_MODE,
12458 H2C_PWRMODE_LEN,
12459 u1H2CSetPwrMode);
12460
12461 RTW_PRINT("-%s()-\n", __func__);
12462
12463 return ret;
12464 }
12465
12466 /**
12467 * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
12468 * @adapter: struct _ADAPTER*
12469 *
12470 * Caculate needed reserved page number.
12471 * In different state would get different number, for example normal mode and
12472 * WOW mode would need different reserved page size.
12473 *
12474 * Return the number of reserved page which driver need.
12475 */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)12476 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
12477 {
12478 u8 num = 0;
12479
12480
12481 _rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
12482
12483 return num;
12484 }
12485
12486 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
hw_var_set_bcn_func(_adapter * adapter,u8 enable)12487 static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
12488 {
12489 u32 bcn_ctrl_reg;
12490
12491 #ifdef CONFIG_CONCURRENT_MODE
12492 if (adapter->hw_port == HW_PORT1)
12493 bcn_ctrl_reg = REG_BCN_CTRL_1;
12494 else
12495 #endif
12496 bcn_ctrl_reg = REG_BCN_CTRL;
12497
12498 if (enable)
12499 rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
12500 else {
12501 u8 val8;
12502
12503 val8 = rtw_read8(adapter, bcn_ctrl_reg);
12504 val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
12505
12506 #ifdef CONFIG_BT_COEXIST
12507 if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
12508 /* Always enable port0 beacon function for PSTDMA */
12509 if (REG_BCN_CTRL == bcn_ctrl_reg)
12510 val8 |= EN_BCN_FUNCTION;
12511 }
12512 #endif
12513
12514 rtw_write8(adapter, bcn_ctrl_reg, val8);
12515 }
12516
12517 #ifdef CONFIG_RTL8192F
12518 if (IS_HARDWARE_TYPE_8192F(adapter)) {
12519 u16 val16, val16_ori;
12520
12521 val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
12522
12523 #ifdef CONFIG_CONCURRENT_MODE
12524 if (adapter->hw_port == HW_PORT1) {
12525 if (enable)
12526 val16 |= EN_PORT_1_FUNCTION;
12527 else
12528 val16 &= ~EN_PORT_1_FUNCTION;
12529 } else
12530 #endif
12531 {
12532 if (enable)
12533 val16 |= EN_PORT_0_FUNCTION;
12534 else
12535 val16 &= ~EN_PORT_0_FUNCTION;
12536
12537 #ifdef CONFIG_BT_COEXIST
12538 if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
12539 val16 |= EN_PORT_0_FUNCTION;
12540 #endif
12541 }
12542
12543 if (val16 != val16_ori)
12544 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, val16);
12545 }
12546 #endif
12547 }
12548 #endif
12549
12550 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
hw_var_set_mlme_disconnect(_adapter * adapter)12551 static void hw_var_set_mlme_disconnect(_adapter *adapter)
12552 {
12553 u8 val8;
12554
12555 /* reject all data frames */
12556 #ifdef CONFIG_CONCURRENT_MODE
12557 if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
12558 #endif
12559 rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
12560
12561 #ifdef CONFIG_CONCURRENT_MODE
12562 if (adapter->hw_port == HW_PORT1) {
12563 /* reset TSF1 */
12564 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
12565
12566 /* disable update TSF1 */
12567 rtw_iface_disable_tsf_update(adapter);
12568
12569 if (!IS_HARDWARE_TYPE_8723D(adapter)
12570 && !IS_HARDWARE_TYPE_8192F(adapter)
12571 && !IS_HARDWARE_TYPE_8710B(adapter)
12572 ) {
12573 /* disable Port1's beacon function */
12574 val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
12575 val8 &= ~EN_BCN_FUNCTION;
12576 rtw_write8(adapter, REG_BCN_CTRL_1, val8);
12577 }
12578 } else
12579 #endif
12580 {
12581 /* reset TSF */
12582 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
12583
12584 /* disable update TSF */
12585 rtw_iface_disable_tsf_update(adapter);
12586 }
12587 }
12588 #endif
12589
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 enable)12590 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
12591 {
12592 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12593 u16 value_rxfltmap2;
12594
12595 #ifdef DBG_IFACE_STATUS
12596 DBG_IFACE_STATUS_DUMP(adapter);
12597 #endif
12598
12599 #ifdef CONFIG_FIND_BEST_CHANNEL
12600 /* Receive all data frames */
12601 value_rxfltmap2 = 0xFFFF;
12602 #else
12603 /* not to receive data frame */
12604 value_rxfltmap2 = 0;
12605 #endif
12606
12607 if (enable) { /* under sitesurvey */
12608 /*
12609 * 1. configure REG_RXFLTMAP2
12610 * 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
12611 * 3. config RCR to receive different BSSID BCN or probe rsp
12612 */
12613 rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
12614
12615 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
12616
12617 /* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */
12618 #if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
12619 hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);
12620 hal_data->RegRRSR &= 0x000FFFFF;
12621 #endif
12622
12623 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
12624 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
12625 /* set 718[1:0]=2'b00 to avoid BF scan hang */
12626 hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
12627 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
12628 }
12629 #endif
12630
12631 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12632 StopTxBeacon(adapter);
12633 } else { /* sitesurvey done */
12634 /*
12635 * 1. enable rx data frame
12636 * 2. config RCR not to receive different BSSID BCN or probe rsp
12637 * 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict
12638 * so, we enable TSF update when rx first BCN after sitesurvey done
12639 */
12640 if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) {
12641 /* enable to rx data frame */
12642 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12643 }
12644
12645 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
12646
12647 /* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */
12648 #if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
12649 rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);
12650 #endif
12651
12652 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
12653 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
12654 /* Restore orignal 0x718 setting*/
12655 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
12656 }
12657 #endif
12658
12659 #ifdef CONFIG_AP_MODE
12660 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12661 ResumeTxBeacon(adapter);
12662 rtw_mi_tx_beacon_hdl(adapter);
12663 }
12664 #endif
12665 }
12666 }
12667
12668 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
hw_var_set_mlme_join(_adapter * adapter,u8 type)12669 static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
12670 {
12671 u8 val8;
12672 u16 val16;
12673 u32 val32;
12674 u8 RetryLimit = RL_VAL_STA;
12675 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12676 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12677
12678 #ifdef CONFIG_CONCURRENT_MODE
12679 if (type == 0) {
12680 /* prepare to join */
12681 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12682 StopTxBeacon(adapter);
12683
12684 /* enable to rx data frame.Accept all data frame */
12685 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12686
12687 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
12688 RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
12689 else /* Ad-hoc Mode */
12690 RetryLimit = RL_VAL_AP;
12691
12692 rtw_iface_enable_tsf_update(adapter);
12693
12694 } else if (type == 1) {
12695 /* joinbss_event call back when join res < 0 */
12696 if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
12697 rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
12698
12699 rtw_iface_disable_tsf_update(adapter);
12700
12701 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12702 ResumeTxBeacon(adapter);
12703
12704 /* reset TSF 1/2 after ResumeTxBeacon */
12705 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
12706 }
12707
12708 } else if (type == 2) {
12709 /* sta add event call back */
12710 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
12711 /* fixed beacon issue for 8191su........... */
12712 rtw_write8(adapter, 0x542 , 0x02);
12713 RetryLimit = RL_VAL_AP;
12714 }
12715
12716 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12717 ResumeTxBeacon(adapter);
12718
12719 /* reset TSF 1/2 after ResumeTxBeacon */
12720 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
12721 }
12722 }
12723
12724 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
12725 rtw_write16(adapter, REG_RETRY_LIMIT, val16);
12726 #else /* !CONFIG_CONCURRENT_MODE */
12727 if (type == 0) { /* prepare to join */
12728 /* enable to rx data frame.Accept all data frame */
12729 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12730
12731 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
12732 RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
12733 else /* Ad-hoc Mode */
12734 RetryLimit = RL_VAL_AP;
12735
12736 rtw_iface_enable_tsf_update(adapter);
12737
12738 } else if (type == 1) { /* joinbss_event call back when join res < 0 */
12739 rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
12740
12741 rtw_iface_disable_tsf_update(adapter);
12742
12743 } else if (type == 2) { /* sta add event call back */
12744 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
12745 RetryLimit = RL_VAL_AP;
12746 }
12747
12748 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
12749 rtw_write16(adapter, REG_RETRY_LIMIT, val16);
12750 #endif /* !CONFIG_CONCURRENT_MODE */
12751 }
12752 #endif
12753
12754 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)12755 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
12756 {
12757 u8 buf[2];
12758 int ret;
12759
12760 if (reset_port == HW_PORT0) {
12761 buf[0] = 0x1;
12762 buf[1] = 0;
12763 } else {
12764 buf[0] = 0x0;
12765 buf[1] = 0x1;
12766 }
12767
12768 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
12769
12770 return ret;
12771 }
12772
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)12773 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
12774 {
12775 u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
12776 u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
12777 REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
12778 int ret;
12779
12780 /* site survey will cause reset tsf fail */
12781 rtw_mi_buddy_scan_abort(adapter, _FALSE);
12782 reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
12783 ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
12784 if (ret != _SUCCESS)
12785 return ret;
12786
12787 while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
12788 rtw_msleep_os(100);
12789 loop_cnt++;
12790 reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
12791 }
12792
12793 return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
12794 }
12795 #endif /* CONFIG_TSF_RESET_OFFLOAD */
12796
12797 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
12798 #ifdef CONFIG_HW_P0_TSF_SYNC
12799 #ifdef CONFIG_CONCURRENT_MODE
hw_port0_tsf_sync_sel(_adapter * adapter,u8 benable,u8 hw_port,u16 tr_offset)12800 static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
12801 {
12802 u8 val8;
12803 u8 client_id = 0;
12804 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12805
12806 #ifdef CONFIG_MCC_MODE
12807 if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
12808 RTW_INFO("[MCC] do not set HW TSF sync\n");
12809 return;
12810 }
12811 #endif
12812 /* check if port0 is already synced */
12813 if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
12814 RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
12815 FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
12816 return;
12817 }
12818
12819 /* check if port0 already disable sync */
12820 if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
12821 RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
12822 return;
12823 }
12824
12825 /* check if port0 sync to port0 */
12826 if (benable && hw_port == HW_PORT0) {
12827 RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
12828 rtw_warn_on(1);
12829 return;
12830 }
12831
12832 /*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
12833 /* Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
12834 Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
12835
12836 val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
12837
12838 if (benable) {
12839 /*Disable Port0's beacon function*/
12840 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
12841
12842 /*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
12843 if (tr_offset)
12844 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
12845
12846 /*reg 0x577[6]=1*/ /*auto sync by tbtt*/
12847 rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
12848
12849 if (HW_PORT1 == hw_port)
12850 client_id = 0;
12851 else if (HW_PORT2 == hw_port)
12852 client_id = 1;
12853 else if (HW_PORT3 == hw_port)
12854 client_id = 2;
12855 else if (HW_PORT4 == hw_port)
12856 client_id = 3;
12857
12858 val8 &= 0x8F;
12859 val8 |= (BIT(6) | (client_id << 4));
12860
12861 dvobj->p0_tsf.sync_port = hw_port;
12862 dvobj->p0_tsf.offset = tr_offset;
12863 rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12864
12865 /*Enable Port0's beacon function*/
12866 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) | BIT_EN_BCN_FUNCTION);
12867 RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
12868 } else {
12869 val8 &= ~BIT(6);
12870
12871 dvobj->p0_tsf.sync_port = MAX_HW_PORT;
12872 dvobj->p0_tsf.offset = 0;
12873 rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12874 RTW_INFO("%s P0 TSF sync disable\n", __func__);
12875 }
12876 }
_search_ld_sta(_adapter * adapter,u8 include_self)12877 static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
12878 {
12879 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12880 u8 i;
12881 _adapter *iface = NULL;
12882
12883 if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
12884 RTW_ERR("STA_LD_NUM == 0\n");
12885 rtw_warn_on(1);
12886 }
12887
12888 for (i = 0; i < dvobj->iface_nums; i++) {
12889 iface = dvobj->padapters[i];
12890 if (!iface)
12891 continue;
12892 if (include_self == _FALSE && adapter == iface)
12893 continue;
12894 if (is_client_associated_to_ap(iface))
12895 break;
12896 }
12897 if (iface)
12898 RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
12899 return iface;
12900 }
12901 #endif /*CONFIG_CONCURRENT_MODE*/
12902 /*Correct port0's TSF*/
12903 /*#define DBG_P0_TSF_SYNC*/
hw_var_set_correct_tsf(PADAPTER adapter,u8 mlme_state)12904 void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
12905 {
12906 #ifdef CONFIG_CONCURRENT_MODE
12907 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12908 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12909 _adapter *sta_if = NULL;
12910 u8 hw_port;
12911
12912 RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
12913 #ifdef DBG_P0_TSF_SYNC
12914 RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
12915 RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
12916 RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
12917 if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12918 RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
12919 else
12920 RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12921 RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12922 #endif
12923 switch (mlme_state) {
12924 case MLME_STA_CONNECTED :
12925 {
12926 hw_port = rtw_hal_get_port(adapter);
12927
12928 if (!MLME_IS_STA(adapter)) {
12929 RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12930 rtw_warn_on(1);
12931 }
12932
12933 if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
12934 RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
12935 rtw_warn_on(1);
12936 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12937 }
12938
12939 if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12940 (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
12941 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12942 #ifdef DBG_P0_TSF_SYNC
12943 RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
12944 #endif
12945 }
12946 }
12947 break;
12948 case MLME_STA_DISCONNECTED :
12949 {
12950 hw_port = rtw_hal_get_port(adapter);
12951
12952 if (!MLME_IS_STA(adapter)) {
12953 RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12954 rtw_warn_on(1);
12955 }
12956
12957 if (dvobj->p0_tsf.sync_port == hw_port) {
12958 if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
12959 /* search next appropriate sta*/
12960 sta_if = _search_ld_sta(adapter, _FALSE);
12961 if (sta_if) {
12962 hw_port = rtw_hal_get_port(sta_if);
12963 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12964 #ifdef DBG_P0_TSF_SYNC
12965 RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
12966 #endif
12967 }
12968 } else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
12969 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12970 #ifdef DBG_P0_TSF_SYNC
12971 RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
12972 #endif
12973 }
12974 }
12975 }
12976 break;
12977 #ifdef CONFIG_AP_MODE
12978 case MLME_AP_STARTED :
12979 case MLME_MESH_STARTED :
12980 {
12981 if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12982 RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12983 rtw_warn_on(1);
12984 }
12985
12986 if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12987 rtw_mi_get_assoced_sta_num(adapter)) {
12988 /* get port of sta */
12989 sta_if = _search_ld_sta(adapter, _FALSE);
12990 if (sta_if) {
12991 hw_port = rtw_hal_get_port(sta_if);
12992 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12993 #ifdef DBG_P0_TSF_SYNC
12994 RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
12995 #endif
12996 }
12997 }
12998 }
12999 break;
13000 case MLME_AP_STOPPED :
13001 case MLME_MESH_STOPPED :
13002 {
13003 if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
13004 RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
13005 rtw_warn_on(1);
13006 }
13007 /*stop ap mode*/
13008 if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
13009 (dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
13010 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
13011 #ifdef DBG_P0_TSF_SYNC
13012 RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
13013 #endif
13014 }
13015 }
13016 break;
13017 #endif /* CONFIG_AP_MODE */
13018 default :
13019 RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
13020 break;
13021 }
13022
13023 /*#ifdef DBG_P0_TSF_SYNC*/
13024 #if 1
13025 if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
13026 RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
13027 else
13028 RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
13029 RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
13030 #endif
13031 #endif /*CONFIG_CONCURRENT_MODE*/
13032 }
13033
13034 #else /*! CONFIG_HW_P0_TSF_SYNC*/
13035
13036 #ifdef CONFIG_MI_WITH_MBSSID_CAM
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)13037 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
13038 {
13039 /*do nothing*/
13040 }
13041 #else /* !CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)13042 static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
13043 {
13044 if (hw_port == HW_PORT0) {
13045 /*disable related TSF function*/
13046 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
13047 #if defined(CONFIG_RTL8192F)
13048 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13049 REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
13050 #endif
13051
13052 rtw_write32(padapter, REG_TSFTR, tsf);
13053 rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
13054
13055 /*enable related TSF function*/
13056 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
13057 #if defined(CONFIG_RTL8192F)
13058 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13059 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
13060 #endif
13061 } else if (hw_port == HW_PORT1) {
13062 /*disable related TSF function*/
13063 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
13064 #if defined(CONFIG_RTL8192F)
13065 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13066 REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);
13067 #endif
13068
13069 rtw_write32(padapter, REG_TSFTR1, tsf);
13070 rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
13071
13072 /*enable related TSF function*/
13073 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
13074 #if defined(CONFIG_RTL8192F)
13075 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13076 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
13077 #endif
13078 } else
13079 RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
13080 }
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)13081 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
13082 {
13083 u64 tsf;
13084 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
13085 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
13086
13087 tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
13088
13089 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
13090 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
13091 StopTxBeacon(adapter);
13092
13093 rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
13094
13095 #ifdef CONFIG_CONCURRENT_MODE
13096 /* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
13097 if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
13098 && (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
13099 ) {
13100 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
13101 int i;
13102 _adapter *iface;
13103
13104 for (i = 0; i < dvobj->iface_nums; i++) {
13105 iface = dvobj->padapters[i];
13106 if (!iface)
13107 continue;
13108 if (iface == adapter)
13109 continue;
13110
13111 #ifdef CONFIG_AP_MODE
13112 if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
13113 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
13114 ) {
13115 rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
13116 #ifdef CONFIG_TSF_RESET_OFFLOAD
13117 if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
13118 RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
13119 , __func__, ADPT_ARG(iface), iface->hw_port);
13120 #endif /* CONFIG_TSF_RESET_OFFLOAD*/
13121 #ifdef CONFIG_TSF_SYNC
13122 if(iface->hw_port == HW_PORT0)
13123 rtw_write8(iface, REG_DUAL_TSF_RST, rtw_read8(iface, REG_DUAL_TSF_RST) | BIT(2));
13124 else if(iface->hw_port == HW_PORT1)
13125 rtw_write8(iface, REG_DUAL_TSF_RST, rtw_read8(iface, REG_DUAL_TSF_RST) | BIT(3));
13126 #endif
13127 }
13128 #endif /* CONFIG_AP_MODE */
13129 }
13130 }
13131 #endif /* CONFIG_CONCURRENT_MODE */
13132 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
13133 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
13134 ResumeTxBeacon(adapter);
13135 }
13136 #endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
13137 #endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/
13138 #endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/
13139
rtw_hal_get_tsftr_by_port(_adapter * adapter,u8 port)13140 u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
13141 {
13142 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
13143 u64 tsftr = 0;
13144
13145 if (port >= hal_spec->port_num) {
13146 RTW_ERR("%s invalid port(%d) \n", __func__, port);
13147 goto exit;
13148 }
13149
13150 switch (rtw_get_chip_type(adapter)) {
13151 #if defined(CONFIG_RTL8814B)
13152 case RTL8814B:
13153 {
13154 u8 val8;
13155
13156 /* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */
13157 val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);
13158 val8 &= ~0x70;
13159 val8 |= port << 4;
13160 rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);
13161
13162 tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);
13163 tsftr = tsftr << 32;
13164 tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);
13165
13166 break;
13167 }
13168 #endif
13169 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
13170 case RTL8814A:
13171 case RTL8822B:
13172 case RTL8821C:
13173 case RTL8822C:
13174 {
13175 u8 val8;
13176
13177 /* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
13178 val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
13179 val8 &= 0x8F;
13180 val8 |= port << 4;
13181 rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
13182
13183 tsftr = rtw_read32(adapter, REG_TSFTR + 4);
13184 tsftr = tsftr << 32;
13185 tsftr |= rtw_read32(adapter, REG_TSFTR);
13186
13187 break;
13188 }
13189 #endif
13190 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
13191 || defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
13192 || defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
13193 || defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
13194 || defined(CONFIG_RTL8710B)
13195 case RTL8188E:
13196 case RTL8188F:
13197 case RTL8188GTV:
13198 case RTL8192E:
13199 case RTL8192F:
13200 case RTL8723B:
13201 case RTL8703B:
13202 case RTL8723D:
13203 case RTL8812:
13204 case RTL8821:
13205 case RTL8710B:
13206 {
13207 u32 addr;
13208
13209 if (port == HW_PORT0)
13210 addr = REG_TSFTR;
13211 else if (port == HW_PORT1)
13212 addr = REG_TSFTR1;
13213 else {
13214 RTW_ERR("%s unknown port(%d) \n", __func__, port);
13215 goto exit;
13216 }
13217
13218 tsftr = rtw_read32(adapter, addr + 4);
13219 tsftr = tsftr << 32;
13220 tsftr |= rtw_read32(adapter, addr);
13221
13222 break;
13223 }
13224 #endif
13225 default:
13226 RTW_ERR("%s unknow chip type\n", __func__);
13227 }
13228
13229 exit:
13230 return tsftr;
13231 }
13232
13233 #ifdef CONFIG_TDLS
13234 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)13235 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
13236 {
13237 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
13238 u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
13239
13240
13241 SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
13242 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
13243 switch (bwmode) {
13244 case CHANNEL_WIDTH_40:
13245 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
13246 break;
13247 case CHANNEL_WIDTH_80:
13248 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
13249 break;
13250 case CHANNEL_WIDTH_20:
13251 default:
13252 break;
13253 }
13254 SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
13255
13256 return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
13257 }
13258 #endif
13259 #endif
13260
13261 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)13262 void rtw_hal_update_uapsd_tid(_adapter *adapter)
13263 {
13264 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
13265 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
13266
13267 /* write complement of pqospriv->uapsd_tid to mac register 0x693 because
13268 it's designed for "0" represents "enable" and "1" represents "disable" */
13269 rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
13270 }
13271 #endif /* CONFIG_WMMPS_STA */
13272
13273 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
13274 /* 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)13275 s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
13276 {
13277 u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
13278 u8 hw_port = rtw_hal_get_port(adapter);
13279
13280 SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
13281 RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
13282 return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
13283 }
13284 #endif
13285
13286 #define LPS_ACTIVE_TIMEOUT 50 /*number of times*/
rtw_lps_state_chk(_adapter * adapter,u8 ps_mode)13287 void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
13288 {
13289 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
13290 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13291 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13292 struct sta_priv *pstapriv = &adapter->stapriv;
13293 struct sta_info *psta = NULL;
13294 u8 ps_ready = _FALSE;
13295 s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
13296
13297 if (ps_mode == PS_MODE_ACTIVE) {
13298 #ifdef CONFIG_LPS_ACK
13299 if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {
13300 if (pwrpriv->lps_ack_status > 0) {
13301 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
13302 if (psta != NULL) {
13303 if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)
13304 RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));
13305 }
13306 }
13307 } else {
13308 RTW_WARN("LPS sctx query timeout, operation abort!!\n");
13309 return;
13310 }
13311 pwrpriv->lps_ack_status = -1;
13312 #else
13313 do {
13314 if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
13315 ps_ready = _TRUE;
13316 break;
13317 }
13318 rtw_msleep_os(1);
13319 } while (leave_wait_count--);
13320
13321 if (ps_ready == _FALSE) {
13322 RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));
13323 return;
13324 }
13325 #endif /* CONFIG_LPS_ACK */
13326 }
13327 }
13328
rtw_var_set_basic_rate(PADAPTER padapter,u8 * val)13329 void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {
13330
13331 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
13332 struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
13333 u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
13334 u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
13335 u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
13336 #if CONFIG_IEEE80211_BAND_5GHZ
13337 u16 rrsr_5g_force_mask = (RRSR_6M);
13338 u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);
13339 #endif
13340 u32 temp_RRSR;
13341
13342 HalSetBrateCfg(padapter, val, &BrateCfg);
13343 input_b = BrateCfg;
13344
13345 /* apply force and allow mask */
13346 #if CONFIG_IEEE80211_BAND_5GHZ
13347 if (pHalData->current_band_type != BAND_ON_2_4G) {
13348 BrateCfg |= rrsr_5g_force_mask;
13349 BrateCfg &= rrsr_5g_allow_mask;
13350 } else
13351 #endif
13352 { /* 2.4G */
13353 BrateCfg |= rrsr_2g_force_mask;
13354 BrateCfg &= rrsr_2g_allow_mask;
13355 }
13356 masked = BrateCfg;
13357
13358 #ifdef CONFIG_CMCC_TEST
13359 BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
13360 BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */
13361 #endif
13362
13363 /* IOT consideration */
13364 if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
13365 /* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
13366 if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
13367 BrateCfg |= RRSR_6M;
13368 }
13369 ioted = BrateCfg;
13370
13371 #ifdef CONFIG_NARROWBAND_SUPPORTING
13372 if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
13373 || (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {
13374 BrateCfg &= ~RRSR_CCK_RATES;
13375 BrateCfg |= RRSR_6M;
13376 }
13377 #endif
13378 pHalData->BasicRateSet = BrateCfg;
13379
13380 RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
13381
13382 /* Set RRSR rate table. */
13383 temp_RRSR = rtw_read32(padapter, REG_RRSR);
13384 temp_RRSR &=0xFFFF0000;
13385 temp_RRSR |=BrateCfg;
13386 rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);
13387
13388 rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
13389
13390 #if defined(CONFIG_RTL8188E)
13391 rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
13392 #endif
13393 }
13394
SetHwReg(_adapter * adapter,u8 variable,u8 * val)13395 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
13396 {
13397 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13398 u8 ret = _SUCCESS;
13399
13400 switch (variable) {
13401 case HW_VAR_MEDIA_STATUS: {
13402 u8 net_type = *((u8 *)val);
13403
13404 rtw_hal_set_msr(adapter, net_type);
13405 }
13406 break;
13407 case HW_VAR_DO_IQK:
13408 if (*val)
13409 hal_data->bNeedIQK = _TRUE;
13410 else
13411 hal_data->bNeedIQK = _FALSE;
13412 break;
13413 case HW_VAR_MAC_ADDR:
13414 #ifdef CONFIG_MI_WITH_MBSSID_CAM
13415 rtw_hal_set_macaddr_mbid(adapter, val);
13416 #else
13417 rtw_hal_set_macaddr_port(adapter, val);
13418 #endif
13419 break;
13420 case HW_VAR_BSSID:
13421 rtw_hal_set_bssid(adapter, val);
13422 break;
13423 case HW_VAR_RCR:
13424 ret = hw_var_rcr_config(adapter, *((u32 *)val));
13425 break;
13426 case HW_VAR_ON_RCR_AM:
13427 hw_var_set_rcr_am(adapter, 1);
13428 break;
13429 case HW_VAR_OFF_RCR_AM:
13430 hw_var_set_rcr_am(adapter, 0);
13431 break;
13432 case HW_VAR_BEACON_INTERVAL:
13433 hw_var_set_bcn_interval(adapter, *(u16 *)val);
13434 break;
13435 #ifdef CONFIG_MBSSID_CAM
13436 case HW_VAR_MBSSID_CAM_WRITE: {
13437 u32 cmd = 0;
13438 u32 *cam_val = (u32 *)val;
13439
13440 rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
13441 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
13442 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
13443 }
13444 break;
13445 case HW_VAR_MBSSID_CAM_CLEAR: {
13446 u32 cmd;
13447 u8 entry_id = *(u8 *)val;
13448
13449 rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
13450
13451 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
13452 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
13453 }
13454 break;
13455 case HW_VAR_RCR_MBSSID_EN:
13456 if (*((u8 *)val))
13457 rtw_hal_rcr_add(adapter, RCR_ENMBID);
13458 else
13459 rtw_hal_rcr_clear(adapter, RCR_ENMBID);
13460 break;
13461 #endif
13462 case HW_VAR_PORT_SWITCH:
13463 hw_var_port_switch(adapter);
13464 break;
13465 case HW_VAR_INIT_RTS_RATE: {
13466 u16 brate_cfg = *((u16 *)val);
13467 u8 rate_index = 0;
13468 HAL_VERSION *hal_ver = &hal_data->version_id;
13469
13470 if (IS_8188E(*hal_ver)) {
13471
13472 while (brate_cfg > 0x1) {
13473 brate_cfg = (brate_cfg >> 1);
13474 rate_index++;
13475 }
13476 rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
13477 } else
13478 rtw_warn_on(1);
13479 }
13480 break;
13481 case HW_VAR_SEC_CFG: {
13482 u16 reg_scr_ori;
13483 u16 reg_scr;
13484
13485 reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
13486 reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
13487
13488 if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
13489 reg_scr |= SCR_CHK_BMC;
13490
13491 if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
13492 reg_scr |= SCR_NoSKMC;
13493
13494 if (reg_scr != reg_scr_ori)
13495 rtw_write16(adapter, REG_SECCFG, reg_scr);
13496 }
13497 break;
13498 case HW_VAR_SEC_DK_CFG: {
13499 struct security_priv *sec = &adapter->securitypriv;
13500 u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
13501
13502 if (val) { /* Enable default key related setting */
13503 reg_scr |= SCR_TXBCUSEDK;
13504 if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
13505 reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
13506 } else /* Disable default key related setting */
13507 reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
13508
13509 rtw_write8(adapter, REG_SECCFG, reg_scr);
13510 }
13511 break;
13512
13513 case HW_VAR_ASIX_IOT:
13514 /* enable ASIX IOT function */
13515 if (*((u8 *)val) == _TRUE) {
13516 /* 0xa2e[0]=0 (disable rake receiver) */
13517 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
13518 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
13519 /* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
13520 rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
13521 } else {
13522 /* restore reg:0xa2e, reg:0xa1c */
13523 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
13524 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
13525 rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
13526 }
13527 break;
13528 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
13529 case HW_VAR_WOWLAN: {
13530 struct wowlan_ioctl_param *poidparam;
13531
13532 poidparam = (struct wowlan_ioctl_param *)val;
13533 switch (poidparam->subcode) {
13534 #ifdef CONFIG_WOWLAN
13535 case WOWLAN_PATTERN_CLEAN:
13536 rtw_hal_dl_pattern(adapter, 2);
13537 break;
13538 case WOWLAN_ENABLE:
13539 rtw_hal_wow_enable(adapter);
13540 break;
13541 case WOWLAN_DISABLE:
13542 rtw_hal_wow_disable(adapter);
13543 break;
13544 #endif /*CONFIG_WOWLAN*/
13545 #ifdef CONFIG_AP_WOWLAN
13546 case WOWLAN_AP_ENABLE:
13547 rtw_hal_ap_wow_enable(adapter);
13548 break;
13549 case WOWLAN_AP_DISABLE:
13550 rtw_hal_ap_wow_disable(adapter);
13551 break;
13552 #endif /*CONFIG_AP_WOWLAN*/
13553 default:
13554 break;
13555 }
13556 }
13557 break;
13558 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
13559
13560 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
13561 case HW_VAR_BCN_FUNC:
13562 hw_var_set_bcn_func(adapter, *val);
13563 break;
13564 #endif
13565
13566 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
13567 case HW_VAR_MLME_DISCONNECT:
13568 hw_var_set_mlme_disconnect(adapter);
13569 break;
13570 #endif
13571
13572 case HW_VAR_MLME_SITESURVEY:
13573 hw_var_set_mlme_sitesurvey(adapter, *val);
13574 #ifdef CONFIG_BT_COEXIST
13575 if (hal_data->EEPROMBluetoothCoexist == 1)
13576 rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
13577 #endif
13578 break;
13579
13580 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
13581 case HW_VAR_MLME_JOIN:
13582 hw_var_set_mlme_join(adapter, *val);
13583 break;
13584 #endif
13585
13586 case HW_VAR_EN_HW_UPDATE_TSF:
13587 rtw_hal_set_hw_update_tsf(adapter);
13588 break;
13589 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
13590 case HW_VAR_CORRECT_TSF:
13591 hw_var_set_correct_tsf(adapter, *val);
13592 break;
13593 #endif
13594
13595 #if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)
13596 case HW_VAR_TSF_AUTO_SYNC:
13597 if (*val == _TRUE)
13598 hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
13599 else
13600 hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
13601 break;
13602 #endif
13603 case HW_VAR_APFM_ON_MAC:
13604 hal_data->bMacPwrCtrlOn = *val;
13605 RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
13606 break;
13607 #ifdef CONFIG_WMMPS_STA
13608 case HW_VAR_UAPSD_TID:
13609 rtw_hal_update_uapsd_tid(adapter);
13610 break;
13611 #endif /* CONFIG_WMMPS_STA */
13612 #ifdef CONFIG_LPS_PG
13613 case HW_VAR_LPS_PG_HANDLE:
13614 rtw_hal_lps_pg_handler(adapter, *val);
13615 break;
13616 #endif
13617 #ifdef CONFIG_LPS_LCLK_WD_TIMER
13618 case HW_VAR_DM_IN_LPS_LCLK:
13619 rtw_phydm_wd_lps_lclk_hdl(adapter);
13620 break;
13621 #endif
13622 case HW_VAR_ENABLE_RX_BAR:
13623 if (*val == _TRUE) {
13624 /* enable RX BAR */
13625 u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
13626
13627 val16 |= BIT(8);
13628 rtw_write16(adapter, REG_RXFLTMAP1, val16);
13629 } else {
13630 /* disable RX BAR */
13631 u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
13632
13633 val16 &= (~BIT(8));
13634 rtw_write16(adapter, REG_RXFLTMAP1, val16);
13635 }
13636 RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
13637 REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
13638 break;
13639 case HW_VAR_HCI_SUS_STATE:
13640 hal_data->hci_sus_state = *(u8 *)val;
13641 RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
13642 break;
13643 #if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
13644 case HW_VAR_BCN_HEAD_SEL:
13645 {
13646 u8 vap_id = *(u8 *)val;
13647
13648 if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
13649 RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
13650 rtw_warn_on(1);
13651 }
13652 if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
13653 u16 drv_pg_bndy = 0, bcn_addr = 0;
13654 u32 page_size = 0;
13655
13656 /*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
13657 rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
13658 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
13659
13660 if (vap_id != 0xFF)
13661 bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
13662 else
13663 bcn_addr = drv_pg_bndy;
13664 RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
13665 ADPT_ARG(adapter), vap_id, bcn_addr);
13666 rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
13667 (bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
13668 }
13669 }
13670 break;
13671 #endif
13672 case HW_VAR_LPS_STATE_CHK :
13673 rtw_lps_state_chk(adapter, *(u8 *)val);
13674 break;
13675
13676 #ifdef CONFIG_RTS_FULL_BW
13677 case HW_VAR_SET_RTS_BW:
13678 {
13679 #ifdef RTW_HALMAC
13680 rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));
13681 #else
13682 u8 temp;
13683 if(*val)
13684 temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );
13685 else
13686 temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));
13687 rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);
13688 /*RTW_INFO("HW_VAR_SET_RTS_BW val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/
13689 #endif
13690 }
13691 break;
13692 #endif/*CONFIG_RTS_FULL_BW*/
13693 #if defined(CONFIG_PCI_HCI)
13694 case HW_VAR_ENSWBCN:
13695 if (*val == _TRUE) {
13696 rtw_write8(adapter, REG_CR + 1,
13697 rtw_read8(adapter, REG_CR + 1) | BIT(0));
13698 } else
13699 rtw_write8(adapter, REG_CR + 1,
13700 rtw_read8(adapter, REG_CR + 1) & ~BIT(0));
13701 break;
13702 #endif
13703 case HW_VAR_BCN_EARLY_C2H_RPT:
13704 rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(adapter, *(u8 *)val);
13705 break;
13706 default:
13707 if (0)
13708 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
13709 FUNC_ADPT_ARG(adapter), variable);
13710 ret = _FAIL;
13711 break;
13712 }
13713
13714 return ret;
13715 }
13716
GetHwReg(_adapter * adapter,u8 variable,u8 * val)13717 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
13718 {
13719 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13720 u64 val64;
13721
13722
13723 switch (variable) {
13724 case HW_VAR_MAC_ADDR:
13725 #ifndef CONFIG_MI_WITH_MBSSID_CAM
13726 rtw_hal_get_macaddr_port(adapter, val);
13727 #endif
13728 break;
13729 case HW_VAR_BASIC_RATE:
13730 *((u16 *)val) = hal_data->BasicRateSet;
13731 break;
13732 case HW_VAR_MEDIA_STATUS:
13733 rtw_hal_get_msr(adapter, val);
13734 break;
13735 case HW_VAR_DO_IQK:
13736 *val = hal_data->bNeedIQK;
13737 break;
13738 case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
13739 if (hal_is_band_support(adapter, BAND_ON_5G))
13740 *val = _TRUE;
13741 else
13742 *val = _FALSE;
13743 break;
13744 case HW_VAR_APFM_ON_MAC:
13745 *val = hal_data->bMacPwrCtrlOn;
13746 break;
13747 case HW_VAR_RCR:
13748 hw_var_rcr_get(adapter, (u32 *)val);
13749 break;
13750 case HW_VAR_FWLPS_RF_ON:
13751 /* When we halt NIC, we should check if FW LPS is leave. */
13752 if (rtw_is_surprise_removed(adapter)
13753 || (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
13754 ) {
13755 /*
13756 * If it is in HW/SW Radio OFF or IPS state,
13757 * we do not check Fw LPS Leave,
13758 * because Fw is unload.
13759 */
13760 *val = _TRUE;
13761 } else {
13762 u32 rcr = 0;
13763
13764 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
13765 if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
13766 *val = _FALSE;
13767 else
13768 *val = _TRUE;
13769 }
13770 break;
13771
13772 case HW_VAR_HCI_SUS_STATE:
13773 *((u8 *)val) = hal_data->hci_sus_state;
13774 break;
13775
13776 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
13777 case HW_VAR_BCN_CTRL_ADDR:
13778 *((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
13779 break;
13780 #endif
13781
13782 #ifdef CONFIG_WAPI_SUPPORT
13783 case HW_VAR_CAM_EMPTY_ENTRY: {
13784 u8 ucIndex = *((u8 *)val);
13785 u8 i;
13786 u32 ulCommand = 0;
13787 u32 ulContent = 0;
13788 u32 ulEncAlgo = CAM_AES;
13789
13790 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
13791 /* filled id in CAM config 2 byte */
13792 if (i == 0)
13793 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
13794 else
13795 ulContent = 0;
13796 /* polling bit, and No Write enable, and address */
13797 ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
13798 ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
13799 /* write content 0 is equall to mark invalid */
13800 rtw_write32(adapter, REG_CAMWRITE, ulContent); /* delay_ms(40); */
13801 rtw_write32(adapter, REG_CAMCMD, ulCommand); /* delay_ms(40); */
13802 }
13803 }
13804 #endif
13805
13806 default:
13807 if (0)
13808 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
13809 FUNC_ADPT_ARG(adapter), variable);
13810 break;
13811 }
13812
13813 }
13814
_get_page_size(struct _ADAPTER * a)13815 static u32 _get_page_size(struct _ADAPTER *a)
13816 {
13817 #ifdef RTW_HALMAC
13818 struct dvobj_priv *d;
13819 u32 size = 0;
13820 int err = 0;
13821
13822
13823 d = adapter_to_dvobj(a);
13824
13825 err = rtw_halmac_get_page_size(d, &size);
13826 if (!err)
13827 return size;
13828
13829 RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
13830 FUNC_ADPT_ARG(a), err);
13831 #endif /* RTW_HALMAC */
13832
13833 return PAGE_SIZE_128;
13834 }
13835
13836 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13837 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13838 {
13839 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13840 u8 bResult = _SUCCESS;
13841
13842 switch (variable) {
13843
13844 case HAL_DEF_DBG_DUMP_RXPKT:
13845 hal_data->bDumpRxPkt = *((u8 *)value);
13846 break;
13847 case HAL_DEF_DBG_DUMP_TXPKT:
13848 hal_data->bDumpTxPkt = *((u8 *)value);
13849 break;
13850 case HAL_DEF_ANT_DETECT:
13851 hal_data->AntDetection = *((u8 *)value);
13852 break;
13853 default:
13854 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
13855 bResult = _FAIL;
13856 break;
13857 }
13858
13859 return bResult;
13860 }
13861
13862 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)13863 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
13864 {
13865 struct registry_priv *pregistrypriv = &adapter->registrypriv;
13866 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13867
13868 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)))
13869 return pregistrypriv->beamformer_rf_num;
13870 else if (IS_HARDWARE_TYPE_8814AE(adapter)
13871 #if 0
13872 #if defined(CONFIG_USB_HCI)
13873 || (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) /* for USB3.0 */
13874 #endif
13875 #endif
13876 ) {
13877 /*BF cap provided by Yu Chen, Sean, 2015, 01 */
13878 if (hal_data->rf_type == RF_3T3R)
13879 return 2;
13880 else if (hal_data->rf_type == RF_4T4R)
13881 return 3;
13882 else
13883 return 1;
13884 } else
13885 return 1;
13886
13887 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)13888 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
13889 {
13890 struct registry_priv *pregistrypriv = &adapter->registrypriv;
13891 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13892 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13893
13894 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13895
13896 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)))
13897 return pregistrypriv->beamformee_rf_num;
13898 else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
13899 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
13900 return 2;
13901 else
13902 return 2;/*TODO: May be 3 in the future, by ChenYu. */
13903 } else
13904 return 1;
13905
13906 }
13907 #ifdef RTW_BEAMFORMING_VERSION_2
rtw_hal_beamforming_config_csirate(PADAPTER adapter)13908 void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
13909 {
13910 struct dm_struct *p_dm_odm;
13911 struct beamforming_info *bf_info;
13912 u8 fix_rate_enable = 0;
13913 u8 new_csi_rate_idx;
13914 u8 rrsr_54_en;
13915 u32 temp_rrsr;
13916
13917 /* Acting as BFee */
13918 if (IS_BEAMFORMEE(adapter)) {
13919 #if 0
13920 /* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
13921 if (IS_HARDWARE_TYPE_8821C(Adapter))
13922 FixRateEnable = 1; /* Support after 8821C */
13923 #endif
13924
13925 p_dm_odm = adapter_to_phydm(adapter);
13926 bf_info = GET_BEAMFORM_INFO(adapter);
13927
13928 rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
13929 p_dm_odm->rssi_min,
13930 bf_info->cur_csi_rpt_rate,
13931 fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);
13932
13933 temp_rrsr = rtw_read32(adapter, REG_RRSR);
13934 if (rrsr_54_en == 1)
13935 temp_rrsr |= RRSR_54M;
13936 else if (rrsr_54_en == 0)
13937 temp_rrsr &= ~RRSR_54M;
13938 rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);
13939
13940 if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
13941 bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
13942 }
13943 }
13944 #endif
13945 #endif
13946
13947 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13948 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13949 {
13950 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13951 u8 bResult = _SUCCESS;
13952
13953 switch (variable) {
13954 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
13955 struct mlme_priv *pmlmepriv;
13956 struct sta_priv *pstapriv;
13957 struct sta_info *psta;
13958
13959 pmlmepriv = &adapter->mlmepriv;
13960 pstapriv = &adapter->stapriv;
13961 psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
13962 if (psta)
13963 *((int *)value) = psta->cmn.rssi_stat.rssi;
13964 }
13965 break;
13966 case HAL_DEF_DBG_DUMP_RXPKT:
13967 *((u8 *)value) = hal_data->bDumpRxPkt;
13968 break;
13969 case HAL_DEF_DBG_DUMP_TXPKT:
13970 *((u8 *)value) = hal_data->bDumpTxPkt;
13971 break;
13972 case HAL_DEF_ANT_DETECT:
13973 *((u8 *)value) = hal_data->AntDetection;
13974 break;
13975 case HAL_DEF_TX_PAGE_SIZE:
13976 *((u32 *)value) = _get_page_size(adapter);
13977 break;
13978 case HAL_DEF_TX_STBC:
13979 #ifdef CONFIG_ALPHA_SMART_ANTENNA
13980 *(u8 *)value = 0;
13981 #else
13982 *(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;
13983 #endif
13984 break;
13985 case HAL_DEF_EXPLICIT_BEAMFORMER:
13986 case HAL_DEF_EXPLICIT_BEAMFORMEE:
13987 case HAL_DEF_VHT_MU_BEAMFORMER:
13988 case HAL_DEF_VHT_MU_BEAMFORMEE:
13989 *(u8 *)value = _FALSE;
13990 break;
13991 #ifdef CONFIG_BEAMFORMING
13992 case HAL_DEF_BEAMFORMER_CAP:
13993 *(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
13994 break;
13995 case HAL_DEF_BEAMFORMEE_CAP:
13996 *(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
13997 break;
13998 #endif
13999 default:
14000 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
14001 bResult = _FAIL;
14002 break;
14003 }
14004
14005 return bResult;
14006 }
14007
14008 /*
14009 * Description:
14010 * Translate a character to hex digit.
14011 * */
14012 u32
MapCharToHexDigit(char chTmp)14013 MapCharToHexDigit(
14014 char chTmp
14015 )
14016 {
14017 if (chTmp >= '0' && chTmp <= '9')
14018 return chTmp - '0';
14019 else if (chTmp >= 'a' && chTmp <= 'f')
14020 return 10 + (chTmp - 'a');
14021 else if (chTmp >= 'A' && chTmp <= 'F')
14022 return 10 + (chTmp - 'A');
14023 else
14024 return 0;
14025 }
14026
14027
14028
14029 /*
14030 * Description:
14031 * Parse hex number from the string pucStr.
14032 * */
14033 BOOLEAN
GetHexValueFromString(char * szStr,u32 * pu4bVal,u32 * pu4bMove)14034 GetHexValueFromString(
14035 char *szStr,
14036 u32 *pu4bVal,
14037 u32 *pu4bMove
14038 )
14039 {
14040 char *szScan = szStr;
14041
14042 /* Check input parameter. */
14043 if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
14044 RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
14045 return _FALSE;
14046 }
14047
14048 /* Initialize output. */
14049 *pu4bMove = 0;
14050 *pu4bVal = 0;
14051
14052 /* Skip leading space. */
14053 while (*szScan != '\0' &&
14054 (*szScan == ' ' || *szScan == '\t')) {
14055 szScan++;
14056 (*pu4bMove)++;
14057 }
14058
14059 /* Skip leading '0x' or '0X'. */
14060 if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
14061 szScan += 2;
14062 (*pu4bMove) += 2;
14063 }
14064
14065 /* Check if szScan is now pointer to a character for hex digit, */
14066 /* if not, it means this is not a valid hex number. */
14067 if (!IsHexDigit(*szScan))
14068 return _FALSE;
14069
14070 /* Parse each digit. */
14071 do {
14072 (*pu4bVal) <<= 4;
14073 *pu4bVal += MapCharToHexDigit(*szScan);
14074
14075 szScan++;
14076 (*pu4bMove)++;
14077 } while (IsHexDigit(*szScan));
14078
14079 return _TRUE;
14080 }
14081
14082 BOOLEAN
GetFractionValueFromString(char * szStr,u8 * pInteger,u8 * pFraction,u32 * pu4bMove)14083 GetFractionValueFromString(
14084 char *szStr,
14085 u8 *pInteger,
14086 u8 *pFraction,
14087 u32 *pu4bMove
14088 )
14089 {
14090 char *szScan = szStr;
14091
14092 /* Initialize output. */
14093 *pu4bMove = 0;
14094 *pInteger = 0;
14095 *pFraction = 0;
14096
14097 /* Skip leading space. */
14098 while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) {
14099 ++szScan;
14100 ++(*pu4bMove);
14101 }
14102
14103 if (*szScan < '0' || *szScan > '9')
14104 return _FALSE;
14105
14106 /* Parse each digit. */
14107 do {
14108 (*pInteger) *= 10;
14109 *pInteger += (*szScan - '0');
14110
14111 ++szScan;
14112 ++(*pu4bMove);
14113
14114 if (*szScan == '.') {
14115 ++szScan;
14116 ++(*pu4bMove);
14117
14118 if (*szScan < '0' || *szScan > '9')
14119 return _FALSE;
14120
14121 *pFraction += (*szScan - '0') * 10;
14122 ++szScan;
14123 ++(*pu4bMove);
14124
14125 if (*szScan >= '0' && *szScan <= '9') {
14126 *pFraction += *szScan - '0';
14127 ++szScan;
14128 ++(*pu4bMove);
14129 }
14130 return _TRUE;
14131 }
14132 } while (*szScan >= '0' && *szScan <= '9');
14133
14134 return _TRUE;
14135 }
14136
14137 /*
14138 * Description:
14139 * Return TRUE if szStr is comment out with leading " */ /* ".
14140 * */
14141 BOOLEAN
IsCommentString(char * szStr)14142 IsCommentString(
14143 char *szStr
14144 )
14145 {
14146 if (*szStr == '/' && *(szStr + 1) == '/')
14147 return _TRUE;
14148 else
14149 return _FALSE;
14150 }
14151
14152 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(char * Str,u8 * pInt)14153 GetU1ByteIntegerFromStringInDecimal(
14154 char *Str,
14155 u8 *pInt
14156 )
14157 {
14158 u16 i = 0;
14159 *pInt = 0;
14160
14161 while (Str[i] != '\0') {
14162 if (Str[i] >= '0' && Str[i] <= '9') {
14163 *pInt *= 10;
14164 *pInt += (Str[i] - '0');
14165 } else
14166 return _FALSE;
14167 ++i;
14168 }
14169
14170 return _TRUE;
14171 }
14172
14173 /* <20121004, Kordan> For example,
14174 * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
14175 * If RightQualifier does not exist, it will hang on in the while loop */
14176 BOOLEAN
ParseQualifiedString(char * In,u32 * Start,char * Out,char LeftQualifier,char RightQualifier)14177 ParseQualifiedString(
14178 char *In,
14179 u32 *Start,
14180 char *Out,
14181 char LeftQualifier,
14182 char RightQualifier
14183 )
14184 {
14185 u32 i = 0, j = 0;
14186 char c = In[(*Start)++];
14187
14188 if (c != LeftQualifier)
14189 return _FALSE;
14190
14191 i = (*Start);
14192 c = In[(*Start)++];
14193 while (c != RightQualifier && c != '\0')
14194 c = In[(*Start)++];
14195
14196 if (c == '\0')
14197 return _FALSE;
14198
14199 j = (*Start) - 2;
14200 strncpy((char *)Out, (const char *)(In + i), j - i + 1);
14201
14202 return _TRUE;
14203 }
14204
14205 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)14206 isAllSpaceOrTab(
14207 u8 *data,
14208 u8 size
14209 )
14210 {
14211 u8 cnt = 0, NumOfSpaceAndTab = 0;
14212
14213 while (size > cnt) {
14214 if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
14215 ++NumOfSpaceAndTab;
14216
14217 ++cnt;
14218 }
14219
14220 return size == NumOfSpaceAndTab;
14221 }
14222
14223
rtw_hal_check_rxfifo_full(_adapter * adapter)14224 void rtw_hal_check_rxfifo_full(_adapter *adapter)
14225 {
14226 struct dvobj_priv *psdpriv = adapter->dvobj;
14227 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
14228 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
14229 struct registry_priv *regsty = &adapter->registrypriv;
14230 int save_cnt = _FALSE;
14231
14232 if (regsty->check_hw_status == 1) {
14233 /* switch counter to RX fifo */
14234 if (IS_8188E(pHalData->version_id) ||
14235 IS_8188F(pHalData->version_id) ||
14236 IS_8188GTV(pHalData->version_id) ||
14237 IS_8812_SERIES(pHalData->version_id) ||
14238 IS_8821_SERIES(pHalData->version_id) ||
14239 IS_8723B_SERIES(pHalData->version_id) ||
14240 IS_8192E(pHalData->version_id) ||
14241 IS_8703B_SERIES(pHalData->version_id) ||
14242 IS_8723D_SERIES(pHalData->version_id) ||
14243 IS_8192F_SERIES(pHalData->version_id) ||
14244 IS_8822C_SERIES(pHalData->version_id)) {
14245 rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
14246 save_cnt = _TRUE;
14247 } else {
14248 /* todo: other chips */
14249 }
14250
14251
14252 if (save_cnt) {
14253 pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
14254 pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
14255 pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
14256 } else {
14257 /* special value to indicate no implementation */
14258 pdbgpriv->dbg_rx_fifo_last_overflow = 1;
14259 pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
14260 pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
14261 }
14262 }
14263 }
14264
linked_info_dump(_adapter * padapter,u8 benable)14265 void linked_info_dump(_adapter *padapter, u8 benable)
14266 {
14267 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
14268
14269 if (padapter->bLinkInfoDump == benable)
14270 return;
14271
14272 RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
14273
14274 if (benable) {
14275 #ifdef CONFIG_LPS
14276 pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
14277 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
14278 #endif
14279
14280 #ifdef CONFIG_IPS
14281 pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
14282 rtw_pm_set_ips(padapter, IPS_NONE);
14283 #endif
14284 } else {
14285 #ifdef CONFIG_IPS
14286 rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
14287 #endif /* CONFIG_IPS */
14288
14289 #ifdef CONFIG_LPS
14290 rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
14291 #endif /* CONFIG_LPS */
14292 }
14293 padapter->bLinkInfoDump = benable ;
14294 }
14295
14296 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)14297 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
14298 {
14299 u8 isCCKrate, rf_path;
14300 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14301 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14302 RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
14303 HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
14304 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14305
14306 if (isCCKrate)
14307 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
14308
14309 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14310 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14311 continue;
14312 RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
14313 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
14314
14315 if (!isCCKrate) {
14316 RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
14317 psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
14318 }
14319 }
14320 }
14321
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)14322 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
14323 {
14324 u8 isCCKrate, rf_path;
14325 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14326 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14327 _RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
14328 _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);
14329
14330 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14331
14332 if (isCCKrate)
14333 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
14334
14335 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14336 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14337 continue;
14338 _RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
14339 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
14340
14341 if (!isCCKrate)
14342 _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]);
14343 else
14344 _RTW_PRINT_SEL(sel , "\n");
14345
14346 }
14347 }
14348 #endif
14349
14350 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)14351 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
14352 {
14353 #define DBG_RX_DFRAME_RAW_DATA_UC 0
14354 #define DBG_RX_DFRAME_RAW_DATA_BMC 1
14355 #define DBG_RX_DFRAME_RAW_DATA_TYPES 2
14356
14357 _irqL irqL;
14358 u8 isCCKrate, rf_path;
14359 struct recv_priv *precvpriv = &(padapter->recvpriv);
14360 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14361 struct sta_priv *pstapriv = &padapter->stapriv;
14362 struct sta_info *psta;
14363 struct sta_recv_dframe_info *psta_dframe_info;
14364 int i, j;
14365 _list *plist, *phead;
14366 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14367 u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14368
14369 if (precvpriv->store_law_data_flag) {
14370
14371 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
14372
14373 for (i = 0; i < NUM_STA; i++) {
14374 phead = &(pstapriv->sta_hash[i]);
14375 plist = get_next(phead);
14376
14377 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
14378
14379 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
14380 plist = get_next(plist);
14381
14382 if (psta) {
14383 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE)
14384 && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN) != _TRUE)
14385 && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN) != _TRUE)) {
14386
14387 RTW_PRINT_SEL(sel, "==============================\n");
14388 RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
14389
14390 for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
14391 if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
14392 psta_dframe_info = &psta->sta_dframe_info;
14393 RTW_PRINT_SEL(sel, "\n");
14394 RTW_PRINT_SEL(sel, "Unicast:\n");
14395 } else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
14396 psta_dframe_info = &psta->sta_dframe_info_bmc;
14397 RTW_PRINT_SEL(sel, "\n");
14398 RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
14399 }
14400
14401 isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14402
14403 RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
14404 RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
14405
14406 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14407 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14408 continue;
14409 if (!isCCKrate) {
14410 RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
14411 _RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
14412 } else
14413 RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
14414 }
14415 }
14416
14417 }
14418 }
14419 }
14420 }
14421 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
14422 }
14423 }
14424 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)14425 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
14426 {
14427 u8 isCCKrate, rf_path , dframe_type;
14428 u8 *ptr;
14429 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14430 #ifdef DBG_RX_DFRAME_RAW_DATA
14431 struct sta_recv_dframe_info *psta_dframe_info;
14432 #endif
14433 struct recv_priv *precvpriv = &(padapter->recvpriv);
14434 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14435 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
14436 struct sta_info *psta = prframe->u.hdr.psta;
14437 struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
14438 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14439 psample_pkt_rssi->data_rate = pattrib->data_rate;
14440 ptr = prframe->u.hdr.rx_data;
14441 dframe_type = GetFrameType(ptr);
14442 /*RTW_INFO("=>%s\n", __FUNCTION__);*/
14443
14444
14445 if (precvpriv->store_law_data_flag) {
14446 isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14447
14448 psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
14449 psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
14450
14451 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14452 psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
14453 psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
14454 if (!isCCKrate) {
14455 psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
14456 psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
14457 }
14458 }
14459 #ifdef DBG_RX_DFRAME_RAW_DATA
14460 if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
14461
14462 /*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
14463 if (psta) {
14464 if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
14465 psta_dframe_info = &psta->sta_dframe_info_bmc;
14466 else
14467 psta_dframe_info = &psta->sta_dframe_info;
14468 /*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
14469 __FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
14470 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
14471 psta_dframe_info->sta_data_rate = pattrib->data_rate;
14472 psta_dframe_info->sta_sgi = pattrib->sgi;
14473 psta_dframe_info->sta_bw_mode = pattrib->bw;
14474 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14475
14476 psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
14477
14478 if (!isCCKrate) {
14479 psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
14480 psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
14481 }
14482 }
14483 }
14484 }
14485 }
14486 #endif
14487 }
14488
14489 }
14490
hal_efuse_macaddr_offset(_adapter * adapter)14491 int hal_efuse_macaddr_offset(_adapter *adapter)
14492 {
14493 u8 interface_type = 0;
14494 int addr_offset = -1;
14495
14496 interface_type = rtw_get_intf_type(adapter);
14497
14498 switch (rtw_get_chip_type(adapter)) {
14499 #ifdef CONFIG_RTL8723B
14500 case RTL8723B:
14501 if (interface_type == RTW_USB)
14502 addr_offset = EEPROM_MAC_ADDR_8723BU;
14503 else if (interface_type == RTW_SDIO)
14504 addr_offset = EEPROM_MAC_ADDR_8723BS;
14505 else if (interface_type == RTW_PCIE)
14506 addr_offset = EEPROM_MAC_ADDR_8723BE;
14507 break;
14508 #endif
14509 #ifdef CONFIG_RTL8703B
14510 case RTL8703B:
14511 if (interface_type == RTW_USB)
14512 addr_offset = EEPROM_MAC_ADDR_8703BU;
14513 else if (interface_type == RTW_SDIO)
14514 addr_offset = EEPROM_MAC_ADDR_8703BS;
14515 break;
14516 #endif
14517 #ifdef CONFIG_RTL8723D
14518 case RTL8723D:
14519 if (interface_type == RTW_USB)
14520 addr_offset = EEPROM_MAC_ADDR_8723DU;
14521 else if (interface_type == RTW_SDIO)
14522 addr_offset = EEPROM_MAC_ADDR_8723DS;
14523 else if (interface_type == RTW_PCIE)
14524 addr_offset = EEPROM_MAC_ADDR_8723DE;
14525 break;
14526 #endif
14527
14528 #ifdef CONFIG_RTL8188E
14529 case RTL8188E:
14530 if (interface_type == RTW_USB)
14531 addr_offset = EEPROM_MAC_ADDR_88EU;
14532 else if (interface_type == RTW_SDIO)
14533 addr_offset = EEPROM_MAC_ADDR_88ES;
14534 else if (interface_type == RTW_PCIE)
14535 addr_offset = EEPROM_MAC_ADDR_88EE;
14536 break;
14537 #endif
14538 #ifdef CONFIG_RTL8188F
14539 case RTL8188F:
14540 if (interface_type == RTW_USB)
14541 addr_offset = EEPROM_MAC_ADDR_8188FU;
14542 else if (interface_type == RTW_SDIO)
14543 addr_offset = EEPROM_MAC_ADDR_8188FS;
14544 break;
14545 #endif
14546 #ifdef CONFIG_RTL8188GTV
14547 case RTL8188GTV:
14548 if (interface_type == RTW_USB)
14549 addr_offset = EEPROM_MAC_ADDR_8188GTVU;
14550 else if (interface_type == RTW_SDIO)
14551 addr_offset = EEPROM_MAC_ADDR_8188GTVS;
14552 break;
14553 #endif
14554 #ifdef CONFIG_RTL8812A
14555 case RTL8812:
14556 if (interface_type == RTW_USB)
14557 addr_offset = EEPROM_MAC_ADDR_8812AU;
14558 else if (interface_type == RTW_PCIE)
14559 addr_offset = EEPROM_MAC_ADDR_8812AE;
14560 break;
14561 #endif
14562 #ifdef CONFIG_RTL8821A
14563 case RTL8821:
14564 if (interface_type == RTW_USB)
14565 addr_offset = EEPROM_MAC_ADDR_8821AU;
14566 else if (interface_type == RTW_SDIO)
14567 addr_offset = EEPROM_MAC_ADDR_8821AS;
14568 else if (interface_type == RTW_PCIE)
14569 addr_offset = EEPROM_MAC_ADDR_8821AE;
14570 break;
14571 #endif
14572 #ifdef CONFIG_RTL8192E
14573 case RTL8192E:
14574 if (interface_type == RTW_USB)
14575 addr_offset = EEPROM_MAC_ADDR_8192EU;
14576 else if (interface_type == RTW_SDIO)
14577 addr_offset = EEPROM_MAC_ADDR_8192ES;
14578 else if (interface_type == RTW_PCIE)
14579 addr_offset = EEPROM_MAC_ADDR_8192EE;
14580 break;
14581 #endif
14582 #ifdef CONFIG_RTL8814A
14583 case RTL8814A:
14584 if (interface_type == RTW_USB)
14585 addr_offset = EEPROM_MAC_ADDR_8814AU;
14586 else if (interface_type == RTW_PCIE)
14587 addr_offset = EEPROM_MAC_ADDR_8814AE;
14588 break;
14589 #endif
14590
14591 #ifdef CONFIG_RTL8822B
14592 case RTL8822B:
14593 if (interface_type == RTW_USB)
14594 addr_offset = EEPROM_MAC_ADDR_8822BU;
14595 else if (interface_type == RTW_SDIO)
14596 addr_offset = EEPROM_MAC_ADDR_8822BS;
14597 else if (interface_type == RTW_PCIE)
14598 addr_offset = EEPROM_MAC_ADDR_8822BE;
14599 break;
14600 #endif /* CONFIG_RTL8822B */
14601
14602 #ifdef CONFIG_RTL8821C
14603 case RTL8821C:
14604 if (interface_type == RTW_USB)
14605 addr_offset = EEPROM_MAC_ADDR_8821CU;
14606 else if (interface_type == RTW_SDIO)
14607 addr_offset = EEPROM_MAC_ADDR_8821CS;
14608 else if (interface_type == RTW_PCIE)
14609 addr_offset = EEPROM_MAC_ADDR_8821CE;
14610 break;
14611 #endif /* CONFIG_RTL8821C */
14612
14613 #ifdef CONFIG_RTL8710B
14614 case RTL8710B:
14615 if (interface_type == RTW_USB)
14616 addr_offset = EEPROM_MAC_ADDR_8710B;
14617 break;
14618 #endif
14619
14620 #ifdef CONFIG_RTL8192F
14621 case RTL8192F:
14622 if (interface_type == RTW_USB)
14623 addr_offset = EEPROM_MAC_ADDR_8192FU;
14624 else if (interface_type == RTW_SDIO)
14625 addr_offset = EEPROM_MAC_ADDR_8192FS;
14626 else if (interface_type == RTW_PCIE)
14627 addr_offset = EEPROM_MAC_ADDR_8192FE;
14628 break;
14629 #endif /* CONFIG_RTL8192F */
14630
14631 #ifdef CONFIG_RTL8822C
14632 case RTL8822C:
14633 if (interface_type == RTW_USB)
14634 addr_offset = EEPROM_MAC_ADDR_8822CU;
14635 else if (interface_type == RTW_SDIO)
14636 addr_offset = EEPROM_MAC_ADDR_8822CS;
14637 else if (interface_type == RTW_PCIE)
14638 addr_offset = EEPROM_MAC_ADDR_8822CE;
14639 break;
14640 #endif /* CONFIG_RTL8822C */
14641
14642 #ifdef CONFIG_RTL8814B
14643 case RTL8814B:
14644 if (interface_type == RTW_USB)
14645 addr_offset = EEPROM_MAC_ADDR_8814BU;
14646 else if (interface_type == RTW_PCIE)
14647 addr_offset = EEPROM_MAC_ADDR_8814BE;
14648 break;
14649 #endif /* CONFIG_RTL8814B */
14650
14651 #ifdef CONFIG_RTL8723F
14652 case RTL8723F:
14653 if (interface_type == RTW_USB)
14654 addr_offset = EEPROM_MAC_ADDR_8723FU;
14655 else if (interface_type == RTW_SDIO)
14656 addr_offset = EEPROM_MAC_ADDR_8723FS;
14657 break;
14658 #endif /* CONFIG_RTL8723F */
14659 }
14660
14661 if (addr_offset == -1) {
14662 RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
14663 , __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
14664 }
14665
14666 return addr_offset;
14667 }
14668
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)14669 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
14670 {
14671 int ret = _FAIL;
14672 int addr_offset;
14673
14674 addr_offset = hal_efuse_macaddr_offset(padapter);
14675 if (addr_offset == -1)
14676 goto exit;
14677
14678 ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
14679
14680 exit:
14681 return ret;
14682 }
14683
rtw_dump_cur_efuse(PADAPTER padapter)14684 void rtw_dump_cur_efuse(PADAPTER padapter)
14685 {
14686 int mapsize =0;
14687 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14688
14689 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
14690
14691 if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
14692 RTW_ERR("wrong map size %d\n", mapsize);
14693 return;
14694 }
14695
14696 #ifdef CONFIG_RTW_DEBUG
14697 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14698 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
14699 else {
14700 #ifdef CONFIG_MP_INCLUDED
14701 if (rtw_mp_mode_check(padapter) && GET_EFUSE_UPDATE_ON(padapter))
14702 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "FAKE EFUSE", hal_data->efuse_eeprom_data, mapsize);
14703 else
14704 #endif
14705 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
14706 }
14707 #endif
14708 }
14709
14710
14711 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)14712 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
14713 {
14714 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14715 u32 ret = _FALSE;
14716 u32 maplen = 0;
14717 #ifdef CONFIG_MP_INCLUDED
14718 struct mp_priv *pmp_priv = &padapter->mppriv;
14719 #endif
14720
14721 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
14722
14723 if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
14724 RTW_ERR("eFuse length error :%d\n", maplen);
14725 return _FALSE;
14726 }
14727 #ifdef CONFIG_MP_INCLUDED
14728 if (pmp_priv->efuse_update_file == _TRUE && (rtw_mp_mode_check(padapter))) {
14729 RTW_INFO("%s, eFuse read from file :%s\n", __func__, pmp_priv->efuse_file_path);
14730 ret = rtw_read_efuse_from_file(pmp_priv->efuse_file_path, hal_data->efuse_eeprom_data, maplen);
14731 pmp_priv->efuse_update_file = _FALSE;
14732 } else
14733 #endif
14734 {
14735 ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
14736 }
14737
14738 hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
14739
14740 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14741 rtw_dump_cur_efuse(padapter);
14742
14743 return ret;
14744 }
14745
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)14746 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
14747 {
14748 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14749 u32 ret = _FAIL;
14750
14751 if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
14752 && rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
14753 ) {
14754 hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
14755 ret = _SUCCESS;
14756 } else
14757 hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
14758
14759 return ret;
14760 }
14761 #endif /* CONFIG_EFUSE_CONFIG_FILE */
14762
hal_config_macaddr(_adapter * adapter,bool autoload_fail)14763 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
14764 {
14765 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
14766 u8 addr[ETH_ALEN];
14767 int addr_offset = hal_efuse_macaddr_offset(adapter);
14768 u8 *hw_addr = NULL;
14769 int ret = _SUCCESS;
14770 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
14771 u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
14772 #endif
14773
14774 if (autoload_fail)
14775 goto bypass_hw_pg;
14776
14777 if (addr_offset != -1)
14778 hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
14779
14780 #ifdef CONFIG_EFUSE_CONFIG_FILE
14781 /* if the hw_addr is written by efuse file, set to NULL */
14782 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14783 hw_addr = NULL;
14784 #endif
14785
14786 if (!hw_addr) {
14787 /* try getting hw pg data */
14788 if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
14789 hw_addr = addr;
14790 }
14791
14792 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
14793 if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
14794 hw_addr[0] = 0xff;
14795 #endif
14796
14797 /* check hw pg data */
14798 if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
14799 _rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
14800 goto exit;
14801 }
14802
14803 bypass_hw_pg:
14804
14805 #ifdef CONFIG_EFUSE_CONFIG_FILE
14806 /* check wifi mac file */
14807 if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
14808 _rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
14809 goto exit;
14810 }
14811 #endif
14812
14813 _rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
14814 ret = _FAIL;
14815
14816 exit:
14817 return ret;
14818 }
14819
14820 #ifdef CONFIG_RF_POWER_TRIM
14821 u32 Array_kfreemap[] = {
14822 0x08, 0xe,
14823 0x06, 0xc,
14824 0x04, 0xa,
14825 0x02, 0x8,
14826 0x00, 0x6,
14827 0x03, 0x4,
14828 0x05, 0x2,
14829 0x07, 0x0,
14830 0x09, 0x0,
14831 0x0c, 0x0,
14832 };
14833
rtw_bb_rf_gain_offset(_adapter * padapter)14834 void rtw_bb_rf_gain_offset(_adapter *padapter)
14835 {
14836 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14837 struct registry_priv *registry_par = &padapter->registrypriv;
14838 struct kfree_data_t *kfree_data = &pHalData->kfree_data;
14839 u8 value = pHalData->EEPROMRFGainOffset;
14840 u8 tmp = 0x3e;
14841 u32 res, i = 0;
14842 u32 ArrayLen = sizeof(Array_kfreemap) / sizeof(u32);
14843 u32 *Array = Array_kfreemap;
14844 u32 v1 = 0, v2 = 0, GainValue = 0, target = 0;
14845
14846 if (registry_par->RegPwrTrimEnable == 2) {
14847 RTW_INFO("Registry kfree default force disable.\n");
14848 return;
14849 }
14850
14851 #if defined(CONFIG_RTL8723B)
14852 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
14853 RTW_INFO("Offset RF Gain.\n");
14854 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
14855
14856 if (pHalData->EEPROMRFGainVal != 0xff) {
14857
14858 if (pHalData->ant_path == RF_PATH_A)
14859 GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
14860
14861 else
14862 GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
14863 RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
14864
14865 for (i = 0; i < ArrayLen; i += 2) {
14866 /* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
14867 v1 = Array[i];
14868 v2 = Array[i + 1];
14869 if (v1 == GainValue) {
14870 RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
14871 target = v2;
14872 break;
14873 }
14874 }
14875 RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
14876
14877 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
14878 RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
14879 phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
14880 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
14881
14882 RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
14883
14884 } else
14885
14886 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
14887 } else
14888 RTW_INFO("Using the default RF gain.\n");
14889
14890 #elif defined(CONFIG_RTL8188E)
14891 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
14892 RTW_INFO("8188ES Offset RF Gain.\n");
14893 RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
14894 pHalData->EEPROMRFGainVal);
14895
14896 if (pHalData->EEPROMRFGainVal != 0xff) {
14897 res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
14898 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
14899
14900 RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
14901 res &= 0xfff87fff;
14902
14903 res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
14904 RTW_INFO("Offset RF Gain. res=0x%x\n", res);
14905
14906 rtw_hal_write_rfreg(padapter, RF_PATH_A,
14907 REG_RF_BB_GAIN_OFFSET,
14908 RF_GAIN_OFFSET_MASK, res);
14909 } else {
14910 RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
14911 pHalData->EEPROMRFGainVal);
14912 }
14913 } else
14914 RTW_INFO("Using the default RF gain.\n");
14915 #else
14916 /* TODO: call this when channel switch */
14917 if (kfree_data->flag & KFREE_FLAG_ON)
14918 rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
14919 #endif
14920
14921 }
14922 #endif /*CONFIG_RF_POWER_TRIM */
14923
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)14924 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
14925 {
14926 #ifdef CONFIG_RF_POWER_TRIM
14927 int i, j;
14928
14929 for (i = 0; i < BB_GAIN_NUM; i++)
14930 for (j = 0; j < RF_PATH_MAX; j++)
14931 if (data->bb_gain[i][j] != 0)
14932 return 0;
14933 #endif
14934 return 1;
14935 }
14936
14937 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)14938 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
14939 {
14940 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14941 if (cur_wireless_mode < WIRELESS_11_24N
14942 && cur_wireless_mode > 0) { /* ABG mode */
14943 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14944 u32 remainder = 0;
14945 u8 quotient = 0;
14946
14947 remainder = MAX_RECVBUF_SZ % (4 * 1024);
14948 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14949
14950 if (quotient > 5) {
14951 pHalData->rxagg_usb_size = 0x6;
14952 pHalData->rxagg_usb_timeout = 0x10;
14953 } else {
14954 if (remainder >= 2048) {
14955 pHalData->rxagg_usb_size = quotient;
14956 pHalData->rxagg_usb_timeout = 0x10;
14957 } else {
14958 pHalData->rxagg_usb_size = (quotient - 1);
14959 pHalData->rxagg_usb_timeout = 0x10;
14960 }
14961 }
14962 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14963 if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
14964 pHalData->rxagg_usb_size = 0x6;
14965 pHalData->rxagg_usb_timeout = 0x10;
14966 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14967 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14968 }
14969 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14970
14971 } else if (cur_wireless_mode >= WIRELESS_11_24N
14972 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14973 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14974 u32 remainder = 0;
14975 u8 quotient = 0;
14976
14977 remainder = MAX_RECVBUF_SZ % (4 * 1024);
14978 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14979
14980 if (quotient > 5) {
14981 pHalData->rxagg_usb_size = 0x5;
14982 pHalData->rxagg_usb_timeout = 0x20;
14983 } else {
14984 if (remainder >= 2048) {
14985 pHalData->rxagg_usb_size = quotient;
14986 pHalData->rxagg_usb_timeout = 0x10;
14987 } else {
14988 pHalData->rxagg_usb_size = (quotient - 1);
14989 pHalData->rxagg_usb_timeout = 0x10;
14990 }
14991 }
14992 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14993 if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
14994 pHalData->rxagg_usb_size = 0x5;
14995 pHalData->rxagg_usb_timeout = 0x20;
14996 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14997 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14998 }
14999 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
15000
15001 } else {
15002 /* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
15003 }
15004 }
15005
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)15006 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
15007 {
15008 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15009
15010 if (cur_wireless_mode < WIRELESS_11_24N
15011 && cur_wireless_mode > 0) { /* ABG mode */
15012 if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
15013 || 0x10 != pHalData->rxagg_usb_timeout) {
15014 pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
15015 pHalData->rxagg_usb_timeout = 0x10;
15016 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
15017 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
15018 }
15019 } else if (cur_wireless_mode >= WIRELESS_11_24N
15020 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
15021 if (UsbDmaSize != pHalData->rxagg_usb_size
15022 || 0x20 != pHalData->rxagg_usb_timeout) {
15023 pHalData->rxagg_usb_size = UsbDmaSize;
15024 pHalData->rxagg_usb_timeout = 0x20;
15025 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
15026 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
15027 }
15028 } else {
15029 /* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
15030 }
15031 }
15032
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)15033 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
15034 {
15035 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
15036 rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
15037 return;
15038 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
15039
15040 rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
15041 }
15042 #endif /* CONFIG_USB_RX_AGGREGATION */
15043
15044 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)15045 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
15046 {
15047 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
15048 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
15049 struct registry_priv *registry_par = &padapter->registrypriv;
15050 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15051 u8 cur_wireless_mode = WIRELESS_INVALID;
15052
15053 #ifdef CONFIG_USB_RX_AGGREGATION
15054 if (!registry_par->dynamic_agg_enable)
15055 return;
15056
15057 #ifdef RTW_HALMAC
15058 if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter)
15059 || IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter)
15060 || IS_HARDWARE_TYPE_8723FU(padapter))
15061 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
15062 #else /* !RTW_HALMAC */
15063 if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
15064 /* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
15065 if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) {
15066 if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
15067 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
15068 else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
15069 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
15070 else
15071 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
15072
15073 /* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
15074 }
15075 } else if (IS_HARDWARE_TYPE_8812(padapter)) {
15076 #ifdef CONFIG_CONCURRENT_MODE
15077 u8 i;
15078 _adapter *iface;
15079 u8 bassocaed = _FALSE;
15080 struct mlme_ext_priv *mlmeext;
15081
15082 for (i = 0; i < pdvobjpriv->iface_nums; i++) {
15083 iface = pdvobjpriv->padapters[i];
15084 mlmeext = &iface->mlmeextpriv;
15085 if (rtw_linked_check(iface) == _TRUE) {
15086 if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
15087 cur_wireless_mode = mlmeext->cur_wireless_mode;
15088 bassocaed = _TRUE;
15089 }
15090 }
15091 if (bassocaed)
15092 #endif
15093 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
15094 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
15095 } else {
15096 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
15097 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
15098 }
15099 #endif /* RTW_HALMAC */
15100 #endif /* CONFIG_USB_RX_AGGREGATION */
15101
15102 }
15103
15104 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)15105 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
15106 {
15107 #ifdef CONFIG_AP_MODE
15108 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
15109 u8 chk_rst = _SUCCESS;
15110
15111 if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
15112 return chk_rst;
15113
15114 /* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
15115 /* return chk_rst; */
15116
15117 if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
15118 && (pre_qsel != next_qsel)) {
15119 /* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
15120 /* pre_qsel,next_qsel); */
15121 chk_rst = _FAIL;
15122 }
15123 return chk_rst;
15124 #else
15125 return _SUCCESS;
15126 #endif /* CONFIG_AP_MODE */
15127 }
15128
15129 #ifdef CONFIG_WOWLAN
15130 /*
15131 * Description:
15132 * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
15133 * contant.
15134 *
15135 * Input:
15136 * adapter: adapter pointer.
15137 * page_num: The max. page number that user want to dump.
15138 * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
15139 */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)15140 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
15141 {
15142
15143 int i;
15144 u8 val = 0;
15145 u8 base = 0;
15146 u32 addr = 0;
15147 u32 count = (page_size / 8);
15148
15149 if (page_num <= 0) {
15150 RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
15151 return;
15152 }
15153
15154 if (page_size < 128 || page_size > 512) {
15155 RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
15156 return;
15157 }
15158
15159 RTW_INFO("+%s+\n", __func__);
15160 val = rtw_read8(padapter, 0x106);
15161 rtw_write8(padapter, 0x106, 0x69);
15162 RTW_INFO("0x106: 0x%02x\n", val);
15163 base = rtw_read8(padapter, 0x209);
15164 RTW_INFO("0x209: 0x%02x\n", base);
15165
15166 addr = ((base)*page_size) / 8;
15167 for (i = 0 ; i < page_num * count ; i += 2) {
15168 rtw_write32(padapter, 0x140, addr + i);
15169 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
15170 rtw_write32(padapter, 0x140, addr + i + 1);
15171 printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
15172 }
15173 }
15174 #endif
15175
15176 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)15177 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
15178 {
15179 u8 value = 0;
15180 u8 direction = 0;
15181 u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
15182 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
15183 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
15184 u8 gpio_num_to_set = gpio_num;
15185 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
15186
15187 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15188 return value;
15189
15190 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15191
15192 RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
15193 LeaveAllPowerSaveModeDirect(adapter);
15194
15195 if (gpio_num > 7) {
15196 gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
15197 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
15198 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
15199 gpio_num_to_set = gpio_num - 8;
15200 }
15201
15202 /* Read GPIO Direction */
15203 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15204
15205 /* According the direction to read register value */
15206 if (direction)
15207 value = (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15208 else
15209 value = (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15210
15211 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15212 RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
15213
15214 return value;
15215 }
15216
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)15217 int rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
15218 {
15219 u8 direction = 0;
15220 u8 res = -1;
15221 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
15222 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
15223 u8 gpio_num_to_set = gpio_num;
15224
15225 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15226 return -1;
15227
15228 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15229
15230 LeaveAllPowerSaveModeDirect(adapter);
15231
15232 if (gpio_num > 7) {
15233 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
15234 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
15235 gpio_num_to_set = gpio_num - 8;
15236 }
15237
15238 /* Read GPIO direction */
15239 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15240
15241 /* If GPIO is output direction, setting value. */
15242 if (direction) {
15243 if (isHigh)
15244 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
15245 else
15246 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
15247
15248 RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
15249 res = 0;
15250 } else {
15251 RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
15252 res = -1;
15253 }
15254
15255 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15256 return res;
15257 }
15258
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)15259 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
15260 {
15261 u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
15262 u8 gpio_num_to_set = gpio_num;
15263
15264 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15265 return -1;
15266
15267 RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
15268
15269 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15270
15271 LeaveAllPowerSaveModeDirect(adapter);
15272
15273 rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
15274
15275 if (gpio_num > 7) {
15276 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
15277 gpio_num_to_set = gpio_num - 8;
15278 }
15279
15280 if (isOutput)
15281 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
15282 else
15283 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
15284
15285 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15286
15287 return 0;
15288 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))15289 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
15290 {
15291 u8 value;
15292 u8 direction;
15293 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
15294
15295 if (IS_HARDWARE_TYPE_8188E(adapter)) {
15296 if (gpio_num > 7 || gpio_num < 4) {
15297 RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
15298 return -1;
15299 }
15300 }
15301
15302 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15303
15304 LeaveAllPowerSaveModeDirect(adapter);
15305
15306 /* Read GPIO direction */
15307 direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
15308 if (direction) {
15309 RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
15310 return -1;
15311 }
15312
15313 /* Config GPIO Mode */
15314 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
15315
15316 /* Register GPIO interrupt handler*/
15317 adapter->gpiointpriv.callback[gpio_num] = callback;
15318
15319 /* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
15320 value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
15321 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
15322 rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
15323
15324 /* Enable GPIO interrupt */
15325 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
15326 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
15327
15328 rtw_hal_update_hisr_hsisr_ind(adapter, 1);
15329
15330 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15331
15332 return 0;
15333 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)15334 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
15335 {
15336 u8 value;
15337 u8 direction;
15338 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
15339
15340 if (IS_HARDWARE_TYPE_8188E(adapter)) {
15341 if (gpio_num > 7 || gpio_num < 4) {
15342 RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
15343 return -1;
15344 }
15345 }
15346
15347 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15348
15349 LeaveAllPowerSaveModeDirect(adapter);
15350
15351 /* Config GPIO Mode */
15352 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
15353
15354 /* Unregister GPIO interrupt handler*/
15355 adapter->gpiointpriv.callback[gpio_num] = NULL;
15356
15357 /* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
15358 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
15359 rtw_write8(adapter, REG_GPIO_INTM, 0x00);
15360
15361 /* Disable GPIO interrupt */
15362 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
15363 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
15364
15365 if (!adapter->gpiointpriv.interrupt_enable_mask)
15366 rtw_hal_update_hisr_hsisr_ind(adapter, 0);
15367
15368 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15369
15370 return 0;
15371 }
15372 #endif
15373
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)15374 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
15375 {
15376 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15377 u8 i;
15378
15379 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
15380 if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
15381 if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
15382 && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
15383 return i;
15384 }
15385 }
15386
15387 return -1;
15388 }
15389
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)15390 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
15391 {
15392 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15393 s8 res;
15394 u8 i;
15395
15396 /* If it's an existed record, overwrite it */
15397 res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
15398 if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
15399 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
15400 return;
15401 }
15402
15403 /* Search for the empty record to use */
15404 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
15405 if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
15406 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
15407 return;
15408 }
15409 }
15410
15411 /* Else, overwrite the oldest record */
15412 for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
15413 _rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
15414
15415 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
15416 }
15417
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)15418 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
15419 {
15420 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
15421 }
15422
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15423 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15424 {
15425 u32 mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
15426 u32 mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
15427 u32 mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
15428 u32 DropPacket = 0;
15429
15430 if (!rx_counter) {
15431 rtw_warn_on(1);
15432 return;
15433 }
15434 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
15435 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15436
15437 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
15438 mac_cck_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15439 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
15440 mac_ofdm_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15441 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
15442 mac_ht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15443 mac_vht_ok = 0;
15444 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15445 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
15446 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
15447 mac_vht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
15448 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15449 }
15450
15451 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
15452 mac_cck_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15453 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
15454 mac_ofdm_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15455 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
15456 mac_ht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15457 mac_vht_err = 0;
15458 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15459 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
15460 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
15461 mac_vht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
15462 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15463 }
15464
15465 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
15466 mac_cck_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15467 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
15468 mac_ofdm_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15469 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
15470 mac_ht_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15471
15472 /* Mac_DropPacket */
15473 rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
15474 DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
15475
15476 rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
15477 rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
15478 rx_counter->rx_cck_fa = mac_cck_fa;
15479 rx_counter->rx_ofdm_fa = mac_ofdm_fa;
15480 rx_counter->rx_ht_fa = mac_ht_fa;
15481 rx_counter->rx_pkt_drop = DropPacket;
15482 }
rtw_reset_mac_rx_counters(_adapter * padapter)15483 void rtw_reset_mac_rx_counters(_adapter *padapter)
15484 {
15485
15486 /* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
15487 if (IS_HARDWARE_TYPE_8703B(padapter) ||
15488 IS_HARDWARE_TYPE_8723D(padapter) ||
15489 IS_HARDWARE_TYPE_8188F(padapter) ||
15490 IS_HARDWARE_TYPE_8188GTV(padapter) ||
15491 IS_HARDWARE_TYPE_8192F(padapter) ||
15492 IS_HARDWARE_TYPE_8822C(padapter))
15493 phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
15494
15495 /* reset mac counter */
15496 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
15497 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
15498 }
15499
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15500 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15501 {
15502 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;
15503 if (!rx_counter) {
15504 rtw_warn_on(1);
15505 return;
15506 }
15507 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15508 cckok = phy_query_bb_reg(padapter, 0xF04, 0x3FFF); /* [13:0] */
15509 ofdmok = phy_query_bb_reg(padapter, 0xF14, 0x3FFF); /* [13:0] */
15510 htok = phy_query_bb_reg(padapter, 0xF10, 0x3FFF); /* [13:0] */
15511 vht_ok = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF); /* [13:0] */
15512 cckcrc = phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16] */
15513 ofdmcrc = phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
15514 htcrc = phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
15515 vht_err = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
15516 CCK_FA = phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
15517 OFDM_FA = phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
15518 } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){
15519 cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);
15520 ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
15521 htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
15522 vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);
15523 cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);
15524 ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
15525 htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
15526 vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);
15527 CCK_FA = phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);
15528 OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
15529 } else if(IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)){
15530 cckok = phy_query_bb_reg(padapter, 0x2aac, 0xffff);
15531 ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
15532 htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
15533 cckcrc = phy_query_bb_reg(padapter, 0x2aac, 0xffff0000);
15534 ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
15535 htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
15536 CCK_FA = phy_query_bb_reg(padapter, 0x2aa8, 0xffff0000) + phy_query_bb_reg(padapter, 0x2aa8, 0x0000ffff);
15537 OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
15538 } else {
15539 cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
15540 ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
15541 htok = phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
15542 vht_ok = 0;
15543 cckcrc = phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
15544 ofdmcrc = phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
15545 htcrc = phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
15546 vht_err = 0;
15547 OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF0, bMaskHWord) +
15548 phy_query_bb_reg(padapter, 0xDA0, bMaskHWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
15549 phy_query_bb_reg(padapter, 0xDA4, bMaskHWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
15550
15551 CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
15552 }
15553
15554 rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
15555 rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
15556 rx_counter->rx_ofdm_fa = OFDM_FA;
15557 rx_counter->rx_cck_fa = CCK_FA;
15558
15559 }
15560
rtw_reset_phy_trx_ok_counters(_adapter * padapter)15561 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
15562 {
15563 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15564 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
15565 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
15566 } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) {
15567 phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);
15568 phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);
15569 } else {
15570 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
15571 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
15572 }
15573 }
15574
rtw_reset_phy_rx_counters(_adapter * padapter)15575 void rtw_reset_phy_rx_counters(_adapter *padapter)
15576 {
15577 /* reset phy counter */
15578 if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
15579 /* reset CCK FA counter */
15580 phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);
15581 phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);
15582
15583 /* reset CCK CCA counter */
15584 phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);
15585 phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);
15586
15587 } else if (IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) {
15588 /* reset CCK FA and CCK CCA counter */
15589 phy_set_bb_reg(padapter, 0x2a44, BIT21, 0);
15590 phy_set_bb_reg(padapter, 0x2a44, BIT21, 1);
15591 rtw_reset_phy_trx_ok_counters(padapter);
15592
15593 } else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15594 rtw_reset_phy_trx_ok_counters(padapter);
15595
15596 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset OFDA FA counter */
15597 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
15598
15599 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
15600 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
15601 } else {
15602 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
15603 rtw_msleep_os(10);
15604 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
15605
15606 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset OFDA FA counter */
15607 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset OFDA FA counter */
15608 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
15609 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
15610
15611 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
15612 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
15613 }
15614 }
15615 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15616 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15617 {
15618 struct recv_priv *precvpriv = &padapter->recvpriv;
15619 if (!rx_counter) {
15620 rtw_warn_on(1);
15621 return;
15622 }
15623 rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
15624 rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
15625 rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
15626 }
rtw_reset_drv_rx_counters(_adapter * padapter)15627 void rtw_reset_drv_rx_counters(_adapter *padapter)
15628 {
15629 struct recv_priv *precvpriv = &padapter->recvpriv;
15630 padapter->drv_rx_cnt_ok = 0;
15631 padapter->drv_rx_cnt_crcerror = 0;
15632 padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
15633 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)15634 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
15635 {
15636 u8 initialgain;
15637 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15638
15639 if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
15640 rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
15641 RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
15642 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
15643 /*disable dynamic functions, such as high power, DIG*/
15644 rtw_phydm_ability_backup(padapter);
15645 rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
15646 } else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
15647 /* turn on phy-dynamic functions */
15648 rtw_phydm_ability_restore(padapter);
15649 initialgain = 0xff; /* restore RX GAIN */
15650 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
15651
15652 }
15653 }
15654
rtw_dump_rx_counters(_adapter * padapter)15655 void rtw_dump_rx_counters(_adapter *padapter)
15656 {
15657 struct dbg_rx_counter rx_counter;
15658
15659 if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
15660 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15661 rtw_dump_drv_rx_counters(padapter, &rx_counter);
15662 RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
15663 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
15664 rtw_reset_drv_rx_counters(padapter);
15665 }
15666
15667 if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
15668 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15669 rtw_dump_mac_rx_counters(padapter, &rx_counter);
15670 RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
15671 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
15672 rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
15673 rx_counter.rx_pkt_drop);
15674 rtw_reset_mac_rx_counters(padapter);
15675 }
15676
15677 if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
15678 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15679 rtw_dump_phy_rx_counters(padapter, &rx_counter);
15680 /* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
15681 /* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
15682 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,
15683 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
15684 rtw_reset_phy_rx_counters(padapter);
15685 }
15686 }
15687 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)15688 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
15689 {
15690 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15691 u8 curr_tx_sgi = 0;
15692 struct ra_sta_info *ra_info;
15693
15694 if (!psta)
15695 return curr_tx_sgi;
15696
15697 if (padapter->fix_rate == 0xff) {
15698 #if defined(CONFIG_RTL8188E)
15699 #if (RATE_ADAPTIVE_SUPPORT == 1)
15700 curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
15701 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
15702 #else
15703 ra_info = &psta->cmn.ra_info;
15704 curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
15705 #endif
15706 } else {
15707 curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
15708 }
15709
15710 return curr_tx_sgi;
15711 }
15712
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)15713 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
15714 {
15715 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15716 u8 rate_id = 0;
15717 struct ra_sta_info *ra_info;
15718
15719 if (!psta)
15720 return rate_id;
15721
15722 if (padapter->fix_rate == 0xff) {
15723 #if defined(CONFIG_RTL8188E)
15724 #if (RATE_ADAPTIVE_SUPPORT == 1)
15725 rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
15726 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
15727 #else
15728 ra_info = &psta->cmn.ra_info;
15729 rate_id = ra_info->curr_tx_rate & 0x7f;
15730 #endif
15731 } else {
15732 rate_id = padapter->fix_rate & 0x7f;
15733 }
15734
15735 return rate_id;
15736 }
15737
update_IOT_info(_adapter * padapter)15738 void update_IOT_info(_adapter *padapter)
15739 {
15740 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15741 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15742
15743 switch (pmlmeinfo->assoc_AP_vendor) {
15744 case HT_IOT_PEER_MARVELL:
15745 pmlmeinfo->turboMode_cts2self = 1;
15746 pmlmeinfo->turboMode_rtsen = 0;
15747 break;
15748
15749 case HT_IOT_PEER_RALINK:
15750 pmlmeinfo->turboMode_cts2self = 0;
15751 pmlmeinfo->turboMode_rtsen = 1;
15752 break;
15753 case HT_IOT_PEER_REALTEK:
15754 /* rtw_write16(padapter, 0x4cc, 0xffff); */
15755 /* rtw_write16(padapter, 0x546, 0x01c0); */
15756 break;
15757 default:
15758 pmlmeinfo->turboMode_cts2self = 0;
15759 pmlmeinfo->turboMode_rtsen = 1;
15760 break;
15761 }
15762
15763 }
15764 #ifdef CONFIG_RTS_FULL_BW
15765 /*
15766 8188E: not support full RTS BW feature(mac REG no define 480[5])
15767 */
rtw_set_rts_bw(_adapter * padapter)15768 void rtw_set_rts_bw(_adapter *padapter) {
15769 int i;
15770 u8 enable = 1;
15771 bool connect_to_8812 = _FALSE;
15772 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
15773 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
15774 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
15775 struct sta_info *station = NULL;
15776
15777 for (i = 0; i < macid_ctl->num; i++) {
15778 if (rtw_macid_is_used(macid_ctl, i)) {
15779
15780 station = NULL;
15781 station = macid_ctl->sta[i];
15782 if(station) {
15783
15784 _adapter *sta_adapter =station->padapter;
15785 struct mlme_ext_priv *pmlmeext = &(sta_adapter->mlmeextpriv);
15786 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15787
15788 if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {
15789 if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) {
15790 if ( macid_ctl->sta[i]->vendor_8812) {
15791 connect_to_8812 = _TRUE;
15792 enable = 0;
15793 }
15794 }
15795 }
15796 }
15797 }
15798
15799 if(connect_to_8812)
15800 break;
15801 }
15802
15803 RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);
15804 rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);
15805 }
15806 #endif/*CONFIG_RTS_FULL_BW*/
15807
hal_spec_init(_adapter * adapter)15808 int hal_spec_init(_adapter *adapter)
15809 {
15810 u8 interface_type = 0;
15811 int ret = _SUCCESS;
15812
15813 interface_type = rtw_get_intf_type(adapter);
15814
15815 switch (rtw_get_chip_type(adapter)) {
15816 #ifdef CONFIG_RTL8723B
15817 case RTL8723B:
15818 init_hal_spec_8723b(adapter);
15819 break;
15820 #endif
15821 #ifdef CONFIG_RTL8703B
15822 case RTL8703B:
15823 init_hal_spec_8703b(adapter);
15824 break;
15825 #endif
15826 #ifdef CONFIG_RTL8723D
15827 case RTL8723D:
15828 init_hal_spec_8723d(adapter);
15829 break;
15830 #endif
15831 #ifdef CONFIG_RTL8188E
15832 case RTL8188E:
15833 init_hal_spec_8188e(adapter);
15834 break;
15835 #endif
15836 #ifdef CONFIG_RTL8188F
15837 case RTL8188F:
15838 init_hal_spec_8188f(adapter);
15839 break;
15840 #endif
15841 #ifdef CONFIG_RTL8188GTV
15842 case RTL8188GTV:
15843 init_hal_spec_8188gtv(adapter);
15844 break;
15845 #endif
15846 #ifdef CONFIG_RTL8812A
15847 case RTL8812:
15848 init_hal_spec_8812a(adapter);
15849 break;
15850 #endif
15851 #ifdef CONFIG_RTL8821A
15852 case RTL8821:
15853 init_hal_spec_8821a(adapter);
15854 break;
15855 #endif
15856 #ifdef CONFIG_RTL8192E
15857 case RTL8192E:
15858 init_hal_spec_8192e(adapter);
15859 break;
15860 #endif
15861 #ifdef CONFIG_RTL8814A
15862 case RTL8814A:
15863 init_hal_spec_8814a(adapter);
15864 break;
15865 #endif
15866 #ifdef CONFIG_RTL8822B
15867 case RTL8822B:
15868 rtl8822b_init_hal_spec(adapter);
15869 break;
15870 #endif
15871 #ifdef CONFIG_RTL8821C
15872 case RTL8821C:
15873 init_hal_spec_rtl8821c(adapter);
15874 break;
15875 #endif
15876 #ifdef CONFIG_RTL8710B
15877 case RTL8710B:
15878 init_hal_spec_8710b(adapter);
15879 break;
15880 #endif
15881 #ifdef CONFIG_RTL8192F
15882 case RTL8192F:
15883 init_hal_spec_8192f(adapter);
15884 break;
15885 #endif
15886 #ifdef CONFIG_RTL8822C
15887 case RTL8822C:
15888 rtl8822c_init_hal_spec(adapter);
15889 break;
15890 #endif
15891 #ifdef CONFIG_RTL8814B
15892 case RTL8814B:
15893 rtl8814b_init_hal_spec(adapter);
15894 break;
15895 #endif
15896 #ifdef CONFIG_RTL8723F
15897 case RTL8723F:
15898 rtl8723f_init_hal_spec(adapter);
15899 break;
15900 #endif
15901 default:
15902 RTW_ERR("%s: unknown chip_type:%u\n"
15903 , __func__, rtw_get_chip_type(adapter));
15904 ret = _FAIL;
15905 break;
15906 }
15907
15908 return ret;
15909 }
15910
15911 static const char *const _band_cap_str[] = {
15912 /* BIT0 */"2G",
15913 /* BIT1 */"5G",
15914 };
15915
15916 static const char *const _bw_cap_str[] = {
15917 /* BIT0 */"5M",
15918 /* BIT1 */"10M",
15919 /* BIT2 */"20M",
15920 /* BIT3 */"40M",
15921 /* BIT4 */"80M",
15922 /* BIT5 */"160M",
15923 /* BIT6 */"80_80M",
15924 };
15925
15926 static const char *const _proto_cap_str[] = {
15927 /* BIT0 */"b",
15928 /* BIT1 */"g",
15929 /* BIT2 */"n",
15930 /* BIT3 */"ac",
15931 };
15932
15933 static const char *const _wl_func_str[] = {
15934 /* BIT0 */"P2P",
15935 /* BIT1 */"MIRACAST",
15936 /* BIT2 */"TDLS",
15937 /* BIT3 */"FTM",
15938 };
15939
dump_hal_spec(void * sel,_adapter * adapter)15940 void dump_hal_spec(void *sel, _adapter *adapter)
15941 {
15942 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15943 int i;
15944
15945 RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
15946 RTW_PRINT_SEL(sel, "macid_cap:%u\n", hal_spec->macid_cap);
15947 RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
15948 RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
15949
15950 RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
15951 RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
15952 RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);
15953 RTW_PRINT_SEL(sel, "rf_reg_path_avail_num:%u\n", hal_spec->rf_reg_path_avail_num);
15954 RTW_PRINT_SEL(sel, "rf_reg_trx_path_bmp:0x%02x\n", hal_spec->rf_reg_trx_path_bmp);
15955 RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
15956
15957 RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
15958 RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
15959
15960 RTW_PRINT_SEL(sel, "band_cap:");
15961 for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
15962 if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
15963 _RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
15964 }
15965 _RTW_PRINT_SEL(sel, "\n");
15966
15967 RTW_PRINT_SEL(sel, "bw_cap:");
15968 for (i = 0; i < BW_CAP_BIT_NUM; i++) {
15969 if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
15970 _RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
15971 }
15972 _RTW_PRINT_SEL(sel, "\n");
15973
15974 RTW_PRINT_SEL(sel, "proto_cap:");
15975 for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
15976 if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
15977 _RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
15978 }
15979 _RTW_PRINT_SEL(sel, "\n");
15980
15981 RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
15982 RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
15983
15984 RTW_PRINT_SEL(sel, "wl_func:");
15985 for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
15986 if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
15987 _RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
15988 }
15989 _RTW_PRINT_SEL(sel, "\n");
15990
15991 #if CONFIG_TX_AC_LIFETIME
15992 RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"
15993 , hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);
15994 #endif
15995
15996 RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
15997
15998 RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
15999 RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
16000 }
16001
hal_chk_band_cap(_adapter * adapter,u8 cap)16002 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
16003 {
16004 return GET_HAL_SPEC(adapter)->band_cap & cap;
16005 }
16006
hal_chk_bw_cap(_adapter * adapter,u8 cap)16007 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
16008 {
16009 return GET_HAL_SPEC(adapter)->bw_cap & cap;
16010 }
16011
hal_chk_proto_cap(_adapter * adapter,u8 cap)16012 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
16013 {
16014 return GET_HAL_SPEC(adapter)->proto_cap & cap;
16015 }
16016
hal_chk_wl_func(_adapter * adapter,u8 func)16017 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
16018 {
16019 return GET_HAL_SPEC(adapter)->wl_func & func;
16020 }
16021
hal_is_band_support(_adapter * adapter,u8 band)16022 inline bool hal_is_band_support(_adapter *adapter, u8 band)
16023 {
16024 return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
16025 }
16026
hal_is_bw_support(_adapter * adapter,u8 bw)16027 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
16028 {
16029 return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
16030 }
16031
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)16032 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
16033 {
16034 u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
16035
16036 if (mode == WIRELESS_11B)
16037 if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
16038 return 1;
16039
16040 if (mode == WIRELESS_11G)
16041 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
16042 return 1;
16043
16044 if (mode == WIRELESS_11A)
16045 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
16046 return 1;
16047
16048 if (mode == WIRELESS_11_24N)
16049 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
16050 return 1;
16051
16052 if (mode == WIRELESS_11_5N)
16053 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
16054 return 1;
16055
16056 if (mode == WIRELESS_11AC)
16057 if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
16058 return 1;
16059
16060 return 0;
16061 }
hal_is_mimo_support(_adapter * adapter)16062 inline bool hal_is_mimo_support(_adapter *adapter)
16063 {
16064 if ((GET_HAL_TX_NSS(adapter) == 1) &&
16065 (GET_HAL_RX_NSS(adapter) == 1))
16066 return 0;
16067 return 1;
16068 }
16069
16070 /*
16071 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
16072 * @adapter:
16073 * @in_bw: starting bw, value of enum channel_width
16074 *
16075 * Returns: value of enum channel_width
16076 */
hal_largest_bw(_adapter * adapter,u8 in_bw)16077 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
16078 {
16079 for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
16080 if (hal_is_bw_support(adapter, in_bw))
16081 break;
16082 }
16083
16084 if (!hal_is_bw_support(adapter, in_bw))
16085 rtw_warn_on(1);
16086
16087 return in_bw;
16088 }
16089
16090 #ifndef CONFIG_HAS_TX_BEACON_PAUSE
ResumeTxBeacon(_adapter * padapter)16091 void ResumeTxBeacon(_adapter *padapter)
16092 {
16093 RTW_DBG("ResumeTxBeacon\n");
16094 #ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE
16095 rtw_write8(padapter, REG_TXPAUSE,
16096 rtw_read8(padapter, REG_TXPAUSE) & (~BIT6));
16097 #else
16098 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
16099 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
16100 #endif
16101
16102 #ifdef RTW_HALMAC
16103 /* Add this for driver using HALMAC because driver doesn't have setup time init by self */
16104 /* TBTT setup time */
16105 rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
16106 #endif
16107
16108 /* TBTT hold time: 0x540[19:8] */
16109 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
16110 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
16111 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
16112 }
16113
StopTxBeacon(_adapter * padapter)16114 void StopTxBeacon(_adapter *padapter)
16115 {
16116 RTW_DBG("StopTxBeacon\n");
16117 #ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE
16118 rtw_write8(padapter, REG_TXPAUSE,
16119 rtw_read8(padapter, REG_TXPAUSE) | BIT6);
16120 #else
16121 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
16122 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
16123 #endif
16124
16125 /* TBTT hold time: 0x540[19:8] */
16126 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
16127 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
16128 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
16129 }
16130 #endif /* CONFIG_HAS_TX_BEACON_PAUSE */
16131
16132 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
16133
16134 #ifdef CONFIG_CLIENT_PORT_CFG
16135 const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
16136 CLT_PORT0,
16137 CLT_PORT1,
16138 CLT_PORT2,
16139 CLT_PORT3
16140 };
16141
rtw_clt_port_init(struct clt_port_t * cltp)16142 void rtw_clt_port_init(struct clt_port_t *cltp)
16143 {
16144 cltp->bmp = 0;
16145 cltp->num = 0;
16146 _rtw_spinlock_init(&cltp->lock);
16147 }
rtw_clt_port_deinit(struct clt_port_t * cltp)16148 void rtw_clt_port_deinit(struct clt_port_t *cltp)
16149 {
16150 _rtw_spinlock_free(&cltp->lock);
16151 }
_hw_client_port_alloc(_adapter * adapter)16152 static void _hw_client_port_alloc(_adapter *adapter)
16153 {
16154 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
16155 struct clt_port_t *cltp = &dvobj->clt_port;
16156 _irqL irql;
16157 int i;
16158
16159 #if 0
16160 if (cltp->num > MAX_CLIENT_PORT_NUM) {
16161 RTW_ERR(ADPT_FMT" cann't alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
16162 rtw_warn_on(1);
16163 return;
16164 }
16165 #endif
16166
16167 if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
16168 RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
16169 ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
16170 return;
16171 }
16172 _enter_critical_bh(&cltp->lock, &irql);
16173 for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
16174 if (!(cltp->bmp & BIT(i)))
16175 break;
16176 }
16177
16178 if (i < MAX_CLIENT_PORT_NUM) {
16179 adapter->client_id = i;
16180 cltp->bmp |= BIT(i);
16181 adapter->client_port = _clt_port_id[i];
16182 }
16183 cltp->num++;
16184 _exit_critical_bh(&cltp->lock, &irql);
16185 RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
16186 __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
16187 }
_hw_client_port_free(_adapter * adapter)16188 static void _hw_client_port_free(_adapter *adapter)
16189 {
16190 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
16191 struct clt_port_t *cltp = &dvobj->clt_port;
16192 _irqL irql;
16193
16194 #if 0
16195 if (adapter->client_id >= MAX_CLIENT_PORT_NUM) {
16196 RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
16197 /*rtw_warn_on(1);*/
16198 }
16199 #endif
16200
16201 RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
16202 __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
16203
16204 _enter_critical_bh(&cltp->lock, &irql);
16205 if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
16206 cltp->bmp &= ~ BIT(adapter->client_id);
16207 adapter->client_id = MAX_CLIENT_PORT_NUM;
16208 adapter->client_port = CLT_PORT_INVALID;
16209 }
16210 cltp->num--;
16211 if (cltp->num < 0)
16212 cltp->num = 0;
16213 _exit_critical_bh(&cltp->lock, &irql);
16214 }
rtw_hw_client_port_allocate(_adapter * adapter)16215 void rtw_hw_client_port_allocate(_adapter *adapter)
16216 {
16217 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16218
16219 if (hal_spec->port_num != 5)
16220 return;
16221
16222 _hw_client_port_alloc(adapter);
16223 }
rtw_hw_client_port_release(_adapter * adapter)16224 void rtw_hw_client_port_release(_adapter *adapter)
16225 {
16226 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16227
16228 if (hal_spec->port_num != 5)
16229 return;
16230
16231 _hw_client_port_free(adapter);
16232 }
16233 #endif /*CONFIG_CLIENT_PORT_CFG*/
16234
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)16235 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
16236 {
16237 RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
16238
16239 rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
16240
16241 /* set net_type */
16242 Set_MSR(Adapter, mode);
16243
16244 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
16245 if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
16246 StopTxBeacon(Adapter);
16247 } else if (mode == _HW_STATE_ADHOC_)
16248 ResumeTxBeacon(Adapter);
16249 else if (mode == _HW_STATE_AP_)
16250 /* enable rx ps-poll */
16251 rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
16252
16253 /* enable rx data frame */
16254 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
16255
16256 #ifdef CONFIG_CLIENT_PORT_CFG
16257 if (mode == _HW_STATE_STATION_)
16258 rtw_hw_client_port_allocate(Adapter);
16259 else
16260 rtw_hw_client_port_release(Adapter);
16261 #endif
16262 #if defined(CONFIG_RTL8192F)
16263 rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
16264 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
16265 #endif
16266 }
16267 #endif
16268
16269 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)16270 u8 rtw_hal_antdiv_before_linked(_adapter *padapter)
16271 {
16272 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16273 u8 cur_ant, change_ant;
16274
16275 if (!pHalData->AntDivCfg)
16276 return _FALSE;
16277
16278 if (pHalData->sw_antdiv_bl_state == 0) {
16279 pHalData->sw_antdiv_bl_state = 1;
16280
16281 rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
16282 change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
16283
16284 return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
16285 }
16286
16287 pHalData->sw_antdiv_bl_state = 0;
16288 return _FALSE;
16289 }
16290
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)16291 void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
16292 {
16293 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16294
16295 if (pHalData->AntDivCfg) {
16296 /*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
16297 /*select optimum_antenna for before linked =>For antenna diversity*/
16298 if (dst->Rssi >= src->Rssi) {/*keep org parameter*/
16299 src->Rssi = dst->Rssi;
16300 src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
16301 }
16302 }
16303 }
16304 #endif
16305
16306 #ifdef CONFIG_PROC_DEBUG
16307 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)16308 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
16309 {
16310 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
16311 struct phy_spec_t *phy_spec = &pHalData->phy_spec;
16312
16313 RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
16314 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
16315 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
16316 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index [15:8]*/
16317 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index [7:0]*/
16318
16319 RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
16320 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]*/
16321 /*VHT STBC Rx [23:16]
16322 0 = not support
16323 1 = support for 1 spatial stream
16324 2 = support for 1 or 2 spatial streams
16325 3 = support for 1 or 2 or 3 spatial streams
16326 4 = support for 1 or 2 or 3 or 4 spatial streams*/
16327 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
16328 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]*/
16329 /*HT STBC Rx [7:0]
16330 0 = not support
16331 1 = support for 1 spatial stream
16332 2 = support for 1 or 2 spatial streams
16333 3 = support for 1 or 2 or 3 spatial streams*/
16334 RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
16335
16336 RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
16337 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]*/
16338 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]*/
16339 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]*/
16340 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]*/
16341 #ifdef CONFIG_BEAMFORMING
16342 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
16343 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]*/
16344 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]*/
16345 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]*/
16346 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]*/
16347 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF) ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
16348 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
16349
16350 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
16351 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
16352 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
16353 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
16354 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
16355 #endif
16356 }
16357 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)16358 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
16359 {
16360 u8 phy_cap = _FALSE;
16361
16362 /* STBC */
16363 rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
16364 RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16365
16366 phy_cap = _FALSE;
16367 rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
16368 RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16369
16370 /* LDPC support */
16371 phy_cap = _FALSE;
16372 rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
16373 RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16374
16375 phy_cap = _FALSE;
16376 rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
16377 RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16378
16379 #ifdef CONFIG_BEAMFORMING
16380 phy_cap = _FALSE;
16381 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
16382 RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16383
16384 phy_cap = _FALSE;
16385 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
16386 RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16387
16388 phy_cap = _FALSE;
16389 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
16390 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16391
16392 phy_cap = _FALSE;
16393 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
16394 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16395 #endif
16396 }
16397 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)16398 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
16399 {
16400 RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
16401 #ifdef CONFIG_PHY_CAPABILITY_QUERY
16402 rtw_dump_phy_cap_by_phydmapi(sel, adapter);
16403 #else
16404 rtw_dump_phy_cap_by_hal(sel, adapter);
16405 #endif
16406 }
16407 #endif
16408
translate_dbm_to_percentage(s16 signal)16409 inline s16 translate_dbm_to_percentage(s16 signal)
16410 {
16411 if ((signal <= -100) || (signal >= 20))
16412 return 0;
16413 else if (signal >= 0)
16414 return 100;
16415 else
16416 return 100 + signal;
16417 }
16418
16419 #ifdef CONFIG_SWTIMER_BASED_TXBCN
16420 #ifdef CONFIG_BCN_RECOVERY
16421 #define REG_CPU_MGQ_INFO 0x041C
16422 #define BIT_BCN_POLL BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)16423 u8 rtw_ap_bcn_recovery(_adapter *padapter)
16424 {
16425 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
16426
16427 if (hal_data->issue_bcn_fail >= 2) {
16428 RTW_ERR("%s ISSUE BCN Fail\n", __func__);
16429 rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
16430 hal_data->issue_bcn_fail = 0;
16431 }
16432 return _SUCCESS;
16433 }
16434 #endif /*CONFIG_BCN_RECOVERY*/
16435
16436 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)16437 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
16438 {
16439 u32 start_time = rtw_get_current_time();
16440 u8 bcn_queue_empty = _FALSE;
16441
16442 do {
16443 if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
16444 bcn_queue_empty = _TRUE;
16445 break;
16446 }
16447 } while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
16448
16449 if (bcn_queue_empty == _FALSE)
16450 RTW_ERR("%s BCN queue not empty\n", __func__);
16451
16452 return bcn_queue_empty;
16453 }
16454 #endif /*CONFIG_BCN_XMIT_PROTECT*/
16455 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
16456
16457 /**
16458 * rtw_hal_get_trx_path() - Get RF path related information
16459 * @d: struct dvobj_priv*
16460 * @type: RF type, nTnR
16461 * @tx: Tx path
16462 * @rx: Rx path
16463 *
16464 * Get RF type, TX path and RX path information.
16465 */
rtw_hal_get_trx_path(struct dvobj_priv * d,enum rf_type * type,enum bb_path * tx,enum bb_path * rx)16466 void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,
16467 enum bb_path *tx, enum bb_path *rx)
16468 {
16469 struct _ADAPTER *a = dvobj_get_primary_adapter(d);
16470 enum rf_type t = GET_HAL_RFPATH(a);
16471
16472 if (type)
16473 *type = t;
16474
16475 if (tx || rx) {
16476 u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);
16477 u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);
16478
16479 if (!tx_bmp && !rx_bmp)
16480 rf_type_to_default_trx_bmp(t, tx, rx);
16481 else {
16482 if (tx)
16483 *tx = GET_HAL_TX_PATH_BMP(a);
16484 if (rx)
16485 *rx = GET_HAL_RX_PATH_BMP(a);
16486 }
16487 }
16488 }
16489
16490 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
rtw_hal_switch_chnl_and_set_bw_offload(_adapter * adapter,u8 central_ch,u8 pri_ch_idx,u8 bw)16491 void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
16492 {
16493 u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
16494 PHAL_DATA_TYPE hal;
16495 struct submit_ctx *chsw_sctx;
16496
16497 hal = GET_HAL_DATA(adapter);
16498 chsw_sctx = &hal->chsw_sctx;
16499
16500 SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
16501 SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
16502 SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
16503 SET_H2CCMD_SINGLE_CH_SWITCH_V2_IQK_UPDATE_EN(h2c, 1);
16504
16505 rtw_sctx_init(chsw_sctx, 10);
16506 rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
16507 rtw_sctx_wait(chsw_sctx, __func__);
16508 }
16509 #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
16510
phy_get_capable_tx_num(_adapter * adapter,enum MGN_RATE rate)16511 u8 phy_get_capable_tx_num(_adapter *adapter, enum MGN_RATE rate)
16512 {
16513 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16514 u8 tx_num = 0;
16515
16516 if (IS_1T_RATE(rate))
16517 tx_num = hal_data->txpath_cap_num_nss[0];
16518 else if (IS_2T_RATE(rate))
16519 tx_num = hal_data->txpath_cap_num_nss[1];
16520 else if (IS_3T_RATE(rate))
16521 tx_num = hal_data->txpath_cap_num_nss[2];
16522 else if (IS_4T_RATE(rate))
16523 tx_num = hal_data->txpath_cap_num_nss[3];
16524 else
16525 rtw_warn_on(1);
16526
16527 return tx_num == 0 ? RF_1TX : tx_num - 1;
16528 }
16529
phy_get_current_tx_num(_adapter * adapter,enum MGN_RATE rate)16530 u8 phy_get_current_tx_num(_adapter *adapter, enum MGN_RATE rate)
16531 {
16532 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16533 u8 tx_num = 0;
16534
16535 if (IS_1T_RATE(rate))
16536 tx_num = hal_data->txpath_num_nss[0];
16537 else if (IS_2T_RATE(rate))
16538 tx_num = hal_data->txpath_num_nss[1];
16539 else if (IS_3T_RATE(rate))
16540 tx_num = hal_data->txpath_num_nss[2];
16541 else if (IS_4T_RATE(rate))
16542 tx_num = hal_data->txpath_num_nss[3];
16543 else
16544 rtw_warn_on(1);
16545
16546 return tx_num == 0 ? RF_1TX : tx_num - 1;
16547 }
16548
16549 #ifdef CONFIG_RTL8812A
rtw_hal_set_8812a_vendor_ie(_adapter * padapter,u8 * pframe,uint * frlen)16550 u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {
16551 int vender_len = 7;
16552 unsigned char vendor_info[vender_len];
16553 unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
16554 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16555
16556 if( !IS_HARDWARE_TYPE_8812(padapter) )
16557 return pframe;
16558
16559 _rtw_memset(vendor_info,0,vender_len);
16560 _rtw_memcpy(vendor_info, REALTEK_OUI, 3);
16561 vendor_info[4] =2;
16562 if(pHalData->version_id.CUTVersion > B_CUT_VERSION )
16563 vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;
16564 else
16565 vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;
16566 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);
16567
16568 return pframe;
16569 }
16570 #endif /*CONFIG_RTL8812A*/
16571
rtw_enter_protsel(struct protsel * protsel,u32 sel)16572 static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)
16573 {
16574 int refcnt;
16575
16576 _enter_critical_mutex(&protsel->mutex, NULL);
16577
16578 refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);
16579
16580 WARN_ON(refcnt > 1 && protsel->sel != sel);
16581
16582 protsel->sel = sel;
16583
16584 _exit_critical_mutex(&protsel->mutex, NULL);
16585 }
16586
rtw_leave_protsel(struct protsel * protsel)16587 static inline void rtw_leave_protsel(struct protsel *protsel)
16588 {
16589 int refcnt;
16590
16591 _enter_critical_mutex(&protsel->mutex, NULL);
16592
16593 refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);
16594
16595 _exit_critical_mutex(&protsel->mutex, NULL);
16596
16597 WARN_ON(refcnt < 0);
16598 }
16599
rtw_assert_protsel(struct protsel * protsel)16600 static inline bool rtw_assert_protsel(struct protsel *protsel)
16601 {
16602 int refcnt = ATOMIC_READ(&protsel->refcnt);
16603
16604 if (refcnt > 0)
16605 return true;
16606
16607 return false;
16608 }
16609
16610 #ifdef CONFIG_PROTSEL_PORT
rtw_enter_protsel_port(_adapter * padapter,u8 port_sel)16611 void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)
16612 {
16613 u8 val8;
16614
16615 rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);
16616
16617 val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);
16618 val8 &= ~BIT_MASK_PORT_CTRL_SEL;
16619 val8 |= BIT_PORT_CTRL_SEL(port_sel);
16620 rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);
16621 }
16622
rtw_assert_protsel_port(_adapter * padapter,u32 addr,u8 len)16623 bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)
16624 {
16625 if (!padapter->bup) /* don't assert before IF up */
16626 return true;
16627
16628 return rtw_assert_protsel(&padapter->dvobj->protsel_port);
16629 }
16630
rtw_leave_protsel_port(_adapter * padapter)16631 void rtw_leave_protsel_port(_adapter *padapter)
16632 {
16633 rtw_leave_protsel(&padapter->dvobj->protsel_port);
16634 }
16635 #endif
16636
16637 #ifdef CONFIG_PROTSEL_ATIMDTIM
rtw_enter_protsel_atimdtim(_adapter * padapter,u8 port_sel)16638 void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)
16639 {
16640 /* 0~15 is for port 0 MBSSID setting
16641 * 16 is for port 1 setting
16642 * 17 is for port 2 setting
16643 * 18 is for port 3 setting
16644 * 19 is for port 4 setting
16645 */
16646 u8 val8;
16647
16648 if (port_sel >= 1 && port_sel <= 4)
16649 port_sel += 15;
16650
16651 rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);
16652
16653 val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);
16654 val8 &= ~BIT_MASK_ATIM_DTIM_SEL;
16655 val8 |= BIT_ATIM_DTIM_SEL(port_sel);
16656 rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);
16657 }
16658
rtw_assert_protsel_atimdtim(_adapter * padapter,u32 addr,u8 len)16659 bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)
16660 {
16661 return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);
16662 }
16663
rtw_leave_protsel_atimdtim(_adapter * padapter)16664 void rtw_leave_protsel_atimdtim(_adapter *padapter)
16665 {
16666 rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);
16667 }
16668 #endif
16669
16670 #ifdef CONFIG_PROTSEL_MACSLEEP
rtw_enter_protsel_macsleep(_adapter * padapter,u8 sel)16671 void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)
16672 {
16673 u32 val32;
16674
16675 rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);
16676
16677 val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);
16678 val32 &= ~BIT_MASK_MACID_SLEEP_SEL;
16679 val32 |= BIT_MACID_SLEEP_SEL(sel);
16680 rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);
16681 }
16682
rtw_assert_protsel_macsleep(_adapter * padapter,u32 addr,u8 len)16683 bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)
16684 {
16685 return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);
16686 }
16687
rtw_leave_protsel_macsleep(_adapter * padapter)16688 void rtw_leave_protsel_macsleep(_adapter *padapter)
16689 {
16690 rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);
16691 }
16692 #endif
16693
rtw_hal_bcn_early_rpt_c2h_handler(_adapter * padapter)16694 void rtw_hal_bcn_early_rpt_c2h_handler(_adapter *padapter)
16695 {
16696
16697 if(0)
16698 RTW_INFO("Recv Bcn Early report!!\n");
16699
16700 #ifdef CONFIG_TDLS
16701 #ifdef CONFIG_TDLS_CH_SW
16702 if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
16703 rtw_tdls_ch_sw_back_to_base_chnl(padapter);
16704 #endif
16705 #endif
16706 }
16707