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)
2014 w_set |= WIRELESS_HT;
2015
2016 if ((psta->wireless_mode & WIRELESS_11AC) || (psta->wireless_mode & WIRELESS_11_5N))
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 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3096 #endif
3097
3098 /*reset TSF*/
3099 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
3100
3101 /*enable BCN0 Function for if1*/
3102 /*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
3103 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3104 rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);
3105 #else
3106 rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3107 #endif
3108 #ifdef CONFIG_BCN_XMIT_PROTECT
3109 rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
3110 #endif
3111
3112 if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/
3113 rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
3114
3115 /* Enable HW seq for BCN
3116 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
3117 #ifdef CONFIG_RTL8822B
3118 if (IS_HARDWARE_TYPE_8822B(adapter))
3119 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3120 #endif
3121
3122 #ifdef CONFIG_RTL8822C
3123 if (IS_HARDWARE_TYPE_8822C(adapter))
3124 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3125 #endif
3126 }
3127 #endif
3128
3129 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3130 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3131 {
3132
3133 #if 0 /*TODO - modify for more flexible*/
3134 u8 idx = 0;
3135
3136 if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
3137 (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
3138 for (idx = 0; idx < 6; idx++)
3139 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
3140 } else {
3141 /*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
3142 u8 entry_id;
3143
3144 if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
3145 (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
3146 entry_id = 0;
3147 if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
3148 RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
3149 write_mbssid_cam(adapter, entry_id, val);
3150 }
3151 } else {
3152 entry_id = rtw_mbid_camid_alloc(adapter, val);
3153 if (entry_id != INVALID_CAM_ID)
3154 write_mbssid_cam(adapter, entry_id, val);
3155 }
3156 }
3157 #else
3158 {
3159 /*
3160 MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
3161 */
3162 u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
3163
3164
3165 if (entry_id != INVALID_CAM_ID) {
3166 write_mbssid_cam(adapter, entry_id, mac_addr);
3167 RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,
3168 ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));
3169 }
3170 }
3171 #endif
3172 }
3173
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3174 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3175 {
3176 u8 idx = 0;
3177 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3178 u8 entry_id;
3179
3180 if (!mac_addr) {
3181 rtw_warn_on(1);
3182 return;
3183 }
3184
3185
3186 entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
3187
3188 if (entry_id != INVALID_CAM_ID)
3189 write_mbssid_cam(adapter, entry_id, mac_addr);
3190 }
3191
3192 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_hal_bcn_interval_adjust(_adapter * adapter,u16 bcn_interval)3193 u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
3194 {
3195 if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
3196 return adapter_to_dvobj(adapter)->inter_bcn_space;
3197 else
3198 return bcn_interval;
3199 }
3200 #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
3201
3202 #else
3203
3204 #ifndef RTW_HALMAC
_get_macaddr_reg(enum _hw_port hwport)3205 static u32 _get_macaddr_reg(enum _hw_port hwport)
3206 {
3207 u32 reg_macaddr = REG_MACID;
3208
3209 #ifdef CONFIG_CONCURRENT_MODE
3210 if (hwport == HW_PORT1)
3211 reg_macaddr = REG_MACID1;
3212 #if defined(CONFIG_RTL8814A)
3213 else if (hwport == HW_PORT2)
3214 reg_macaddr = REG_MACID2;
3215 else if (hwport == HW_PORT3)
3216 reg_macaddr = REG_MACID3;
3217 else if (hwport == HW_PORT4)
3218 reg_macaddr = REG_MACID4;
3219 #endif /*CONFIG_RTL8814A*/
3220 #endif /*CONFIG_CONCURRENT_MODE*/
3221
3222 return reg_macaddr;
3223 }
3224 #endif /*!RTW_HALMAC*/
3225
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * mac_addr)3226 static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr)
3227 {
3228 enum _hw_port hwport;
3229
3230 if (mac_addr == NULL)
3231 return;
3232 hwport = get_hw_port(adapter);
3233
3234 RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3235 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3236
3237 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3238 rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3239 #else /* !RTW_HALMAC */
3240 {
3241 u8 idx = 0;
3242 u32 reg_macaddr = _get_macaddr_reg(hwport);
3243
3244 for (idx = 0; idx < ETH_ALEN; idx++)
3245 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx), mac_addr[idx]);
3246 }
3247 #endif /* !RTW_HALMAC */
3248 }
3249
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)3250 static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
3251 {
3252 enum _hw_port hwport;
3253
3254 if (mac_addr == NULL)
3255 return;
3256 hwport = get_hw_port(adapter);
3257
3258 _rtw_memset(mac_addr, 0, ETH_ALEN);
3259 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3260 rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3261 #else /* !RTW_HALMAC */
3262 {
3263 u8 idx = 0;
3264 u32 reg_macaddr = _get_macaddr_reg(hwport);
3265
3266 for (idx = 0; idx < ETH_ALEN; idx++)
3267 mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx));
3268 }
3269 #endif /* !RTW_HALMAC */
3270
3271 RTW_DBG("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3272 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3273 }
3274 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
3275
3276 #ifndef RTW_HALMAC
_get_bssid_reg(enum _hw_port hw_port)3277 static u32 _get_bssid_reg(enum _hw_port hw_port)
3278 {
3279 u32 reg_bssid = REG_BSSID;
3280
3281 #ifdef CONFIG_CONCURRENT_MODE
3282 if (hw_port == HW_PORT1)
3283 reg_bssid = REG_BSSID1;
3284 #if defined(CONFIG_RTL8814A)
3285 else if (hw_port == HW_PORT2)
3286 reg_bssid = REG_BSSID2;
3287 else if (hw_port == HW_PORT3)
3288 reg_bssid = REG_BSSID3;
3289 else if (hw_port == HW_PORT4)
3290 reg_bssid = REG_BSSID4;
3291 #endif /*CONFIG_RTL8814A*/
3292 #endif /*CONFIG_CONCURRENT_MODE*/
3293
3294 return reg_bssid;
3295 }
3296 #endif /*!RTW_HALMAC*/
rtw_hal_set_bssid(_adapter * adapter,u8 * val)3297 static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
3298 {
3299 enum _hw_port hw_port = rtw_hal_get_port(adapter);
3300 #ifdef RTW_HALMAC
3301
3302 rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);
3303 #else /* !RTW_HALMAC */
3304 u8 idx = 0;
3305 u32 reg_bssid = _get_bssid_reg(hw_port);
3306
3307 for (idx = 0 ; idx < ETH_ALEN; idx++)
3308 rtw_write8(adapter, (reg_bssid + idx), val[idx]);
3309 #endif /* !RTW_HALMAC */
3310
3311 RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",
3312 __func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));
3313 }
3314
3315 #ifndef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_tsf_update(_adapter * adapter,u8 en)3316 static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)
3317 {
3318 u32 addr = 0;
3319 u8 val8;
3320
3321 rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);
3322 if (addr) {
3323 rtw_enter_protsel_port(adapter, get_hw_port(adapter));
3324 val8 = rtw_read8(adapter, addr);
3325 if (en && (val8 & DIS_TSF_UDT)) {
3326 rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);
3327 #ifdef DBG_TSF_UPDATE
3328 RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3329 #endif
3330 }
3331 if (!en && !(val8 & DIS_TSF_UDT)) {
3332 rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);
3333 #ifdef DBG_TSF_UPDATE
3334 RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3335 #endif
3336 }
3337 rtw_leave_protsel_port(adapter);
3338 } else {
3339 RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"
3340 , adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");
3341 rtw_warn_on(1);
3342 }
3343 }
3344 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_set_hw_update_tsf(PADAPTER padapter)3345 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
3346 {
3347 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3348
3349 #else
3350 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3351
3352 if (!pmlmeext->en_hw_update_tsf)
3353 return;
3354
3355 /* check RCR */
3356 if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
3357 return;
3358
3359 if (pmlmeext->tsf_update_required) {
3360 pmlmeext->tsf_update_pause_stime = 0;
3361 rtw_hal_set_tsf_update(padapter, 1);
3362 }
3363
3364 pmlmeext->en_hw_update_tsf = 0;
3365 #endif
3366 }
3367
rtw_iface_enable_tsf_update(_adapter * adapter)3368 void rtw_iface_enable_tsf_update(_adapter *adapter)
3369 {
3370 adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3371 adapter->mlmeextpriv.tsf_update_required = 1;
3372 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3373
3374 #else
3375 rtw_hal_set_tsf_update(adapter, 1);
3376 #endif
3377 }
3378
rtw_iface_disable_tsf_update(_adapter * adapter)3379 void rtw_iface_disable_tsf_update(_adapter *adapter)
3380 {
3381 adapter->mlmeextpriv.tsf_update_required = 0;
3382 adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3383 adapter->mlmeextpriv.en_hw_update_tsf = 0;
3384 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3385
3386 #else
3387 rtw_hal_set_tsf_update(adapter, 0);
3388 #endif
3389 }
3390
rtw_hal_tsf_update_pause(_adapter * adapter)3391 static void rtw_hal_tsf_update_pause(_adapter *adapter)
3392 {
3393 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3394
3395 #else
3396 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3397 _adapter *iface;
3398 int i;
3399
3400 for (i = 0; i < dvobj->iface_nums; i++) {
3401 iface = dvobj->padapters[i];
3402 if (!iface)
3403 continue;
3404
3405 rtw_hal_set_tsf_update(iface, 0);
3406 if (iface->mlmeextpriv.tsf_update_required) {
3407 iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();
3408 if (!iface->mlmeextpriv.tsf_update_pause_stime)
3409 iface->mlmeextpriv.tsf_update_pause_stime++;
3410 }
3411 iface->mlmeextpriv.en_hw_update_tsf = 0;
3412 }
3413 #endif
3414 }
3415
rtw_hal_tsf_update_restore(_adapter * adapter)3416 static void rtw_hal_tsf_update_restore(_adapter *adapter)
3417 {
3418 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3419
3420 #else
3421 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3422 _adapter *iface;
3423 int i;
3424
3425 for (i = 0; i < dvobj->iface_nums; i++) {
3426 iface = dvobj->padapters[i];
3427 if (!iface)
3428 continue;
3429
3430 if (iface->mlmeextpriv.tsf_update_required) {
3431 /* enable HW TSF update when recive beacon*/
3432 iface->mlmeextpriv.en_hw_update_tsf = 1;
3433 #ifdef DBG_TSF_UPDATE
3434 RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"
3435 , iface->hw_port, ADPT_ARG(iface));
3436 #endif
3437 }
3438 }
3439 #endif
3440 }
3441
rtw_hal_periodic_tsf_update_chk(_adapter * adapter)3442 void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)
3443 {
3444 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3445
3446 #else
3447 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3448 _adapter *iface;
3449 struct mlme_ext_priv *mlmeext;
3450 int i;
3451 u32 restore_ms = 0;
3452
3453 if (dvobj->periodic_tsf_update_etime) {
3454 if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {
3455 /* end for restore status */
3456 dvobj->periodic_tsf_update_etime = 0;
3457 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3458 }
3459 return;
3460 }
3461
3462 if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)
3463 return;
3464
3465 /*
3466 * all required ifaces can switch to restore status together
3467 * loop all pause iface to get largest restore time required
3468 */
3469 for (i = 0; i < dvobj->iface_nums; i++) {
3470 iface = dvobj->padapters[i];
3471 if (!iface)
3472 continue;
3473
3474 mlmeext = &iface->mlmeextpriv;
3475
3476 if (mlmeext->tsf_update_required
3477 && mlmeext->tsf_update_pause_stime
3478 && rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)
3479 > mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor
3480 ) {
3481 if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)
3482 restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;
3483 }
3484 }
3485
3486 if (!restore_ms)
3487 return;
3488
3489 dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);
3490 if (!dvobj->periodic_tsf_update_etime)
3491 dvobj->periodic_tsf_update_etime++;
3492
3493 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3494
3495 /* set timer to end restore status */
3496 _set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);
3497 #endif
3498 }
3499
rtw_hal_periodic_tsf_update_end_timer_hdl(void * ctx)3500 void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)
3501 {
3502 struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;
3503
3504 if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
3505 return;
3506
3507 rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));
3508 }
3509
hw_var_rcr_config(_adapter * adapter,u32 rcr)3510 static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
3511 {
3512 int err;
3513
3514 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
3515 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;
3516 #endif
3517 err = rtw_write32(adapter, REG_RCR, rcr);
3518 if (err == _SUCCESS)
3519 GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
3520 return err;
3521 }
3522
hw_var_rcr_get(_adapter * adapter,u32 * rcr)3523 static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
3524 {
3525 u32 v32;
3526
3527 v32 = rtw_read32(adapter, REG_RCR);
3528 if (rcr)
3529 *rcr = v32;
3530 GET_HAL_DATA(adapter)->ReceiveConfig = v32;
3531 return _SUCCESS;
3532 }
3533
3534 /* only check SW RCR variable */
rtw_hal_rcr_check(_adapter * adapter,u32 check_bit)3535 inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
3536 {
3537 PHAL_DATA_TYPE hal;
3538 u32 rcr;
3539
3540 hal = GET_HAL_DATA(adapter);
3541
3542 rcr = hal->ReceiveConfig;
3543 if ((rcr & check_bit) == check_bit)
3544 return 1;
3545
3546 return 0;
3547 }
3548
rtw_hal_rcr_add(_adapter * adapter,u32 add)3549 inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
3550 {
3551 PHAL_DATA_TYPE hal;
3552 u32 rcr;
3553 u8 ret = _SUCCESS;
3554
3555 hal = GET_HAL_DATA(adapter);
3556
3557 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3558 rcr |= add;
3559 if (rcr != hal->ReceiveConfig)
3560 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3561
3562 return ret;
3563 }
3564
rtw_hal_rcr_clear(_adapter * adapter,u32 clear)3565 inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
3566 {
3567 PHAL_DATA_TYPE hal;
3568 u32 rcr;
3569 u8 ret = _SUCCESS;
3570
3571 hal = GET_HAL_DATA(adapter);
3572
3573 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3574 rcr &= ~clear;
3575 if (rcr != hal->ReceiveConfig)
3576 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3577
3578 return ret;
3579 }
3580
rtw_hal_rcr_set_chk_bssid(_adapter * adapter,u8 self_action)3581 void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
3582 {
3583 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3584 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3585 u32 rcr, rcr_new;
3586 struct mi_state mstate, mstate_s;
3587
3588 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3589 rcr_new = rcr;
3590
3591 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)
3592 rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
3593 #else
3594 rtw_mi_status_no_self(adapter, &mstate);
3595 rtw_mi_status_no_others(adapter, &mstate_s);
3596
3597 /* only adjust parameters interested */
3598 switch (self_action) {
3599 case MLME_SCAN_ENTER:
3600 mstate_s.scan_num = 1;
3601 mstate_s.scan_enter_num = 1;
3602 break;
3603 case MLME_SCAN_DONE:
3604 mstate_s.scan_enter_num = 0;
3605 break;
3606 case MLME_STA_CONNECTING:
3607 mstate_s.lg_sta_num = 1;
3608 mstate_s.ld_sta_num = 0;
3609 break;
3610 case MLME_STA_CONNECTED:
3611 mstate_s.lg_sta_num = 0;
3612 mstate_s.ld_sta_num = 1;
3613 break;
3614 case MLME_STA_DISCONNECTED:
3615 mstate_s.lg_sta_num = 0;
3616 mstate_s.ld_sta_num = 0;
3617 break;
3618 #ifdef CONFIG_TDLS
3619 case MLME_TDLS_LINKED:
3620 mstate_s.ld_tdls_num = 1;
3621 break;
3622 case MLME_TDLS_NOLINK:
3623 mstate_s.ld_tdls_num = 0;
3624 break;
3625 #endif
3626 #ifdef CONFIG_AP_MODE
3627 case MLME_AP_STARTED:
3628 mstate_s.ap_num = 1;
3629 break;
3630 case MLME_AP_STOPPED:
3631 mstate_s.ap_num = 0;
3632 mstate_s.ld_ap_num = 0;
3633 break;
3634 #endif
3635 #ifdef CONFIG_RTW_MESH
3636 case MLME_MESH_STARTED:
3637 mstate_s.mesh_num = 1;
3638 break;
3639 case MLME_MESH_STOPPED:
3640 mstate_s.mesh_num = 0;
3641 mstate_s.ld_mesh_num = 0;
3642 break;
3643 #endif
3644 case MLME_ACTION_NONE:
3645 case MLME_ADHOC_STARTED:
3646 /* caller without effect of decision */
3647 break;
3648 default:
3649 rtw_warn_on(1);
3650 };
3651
3652 rtw_mi_status_merge(&mstate, &mstate_s);
3653
3654 if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
3655 #ifdef CONFIG_FIND_BEST_CHANNEL
3656 || MSTATE_SCAN_ENTER_NUM(&mstate)
3657 #endif
3658 || hal_data->in_cta_test
3659 )
3660 rcr_new &= ~RCR_CBSSID_DATA;
3661 else
3662 rcr_new |= RCR_CBSSID_DATA;
3663
3664 if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)
3665 rcr_new &= ~RCR_CBSSID_BCN;
3666 else if (MSTATE_STA_LG_NUM(&mstate)
3667 || adapter_to_dvobj(adapter)->periodic_tsf_update_etime
3668 )
3669 rcr_new |= RCR_CBSSID_BCN;
3670 else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
3671 || MSTATE_MESH_NUM(&mstate)
3672 )
3673 rcr_new &= ~RCR_CBSSID_BCN;
3674 else
3675 rcr_new |= RCR_CBSSID_BCN;
3676
3677 #ifdef CONFIG_CLIENT_PORT_CFG
3678 if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)
3679 rcr_new &= ~RCR_CBSSID_BCN;
3680 #endif
3681 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
3682
3683 #ifdef CONFIG_RTW_MULTI_AP
3684 if (MSTATE_AP_NUM(&mstate)
3685 && rtw_unassoc_sta_src_chk(adapter, UNASOC_STA_SRC_RX_NMY_UC)
3686 ) {
3687 rcr_new |= RCR_AAP;
3688 } else
3689 rcr_new &= ~RCR_AAP;
3690 #endif
3691
3692 if (rcr == rcr_new)
3693 return;
3694
3695 if (!hal_spec->rx_tsf_filter
3696 && (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))
3697 rtw_hal_tsf_update_pause(adapter);
3698
3699 rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
3700
3701 if (!hal_spec->rx_tsf_filter
3702 && !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)
3703 && self_action != MLME_STA_CONNECTING)
3704 rtw_hal_tsf_update_restore(adapter);
3705 }
3706
rtw_hal_rcr_set_chk_bssid_act_non(_adapter * adapter)3707 void rtw_hal_rcr_set_chk_bssid_act_non(_adapter *adapter)
3708 {
3709 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3710 }
3711
hw_var_set_rcr_am(_adapter * adapter,u8 enable)3712 static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
3713 {
3714 u32 rcr = RCR_AM;
3715
3716 if (enable)
3717 rtw_hal_rcr_add(adapter, rcr);
3718 else
3719 rtw_hal_rcr_clear(adapter, rcr);
3720 }
3721
hw_var_set_bcn_interval(_adapter * adapter,u16 interval)3722 static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)
3723 {
3724 #ifdef CONFIG_SWTIMER_BASED_TXBCN
3725 interval = rtw_hal_bcn_interval_adjust(adapter, interval);
3726 #endif
3727
3728 #ifdef RTW_HALMAC
3729 rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);
3730 #else
3731 rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);
3732 #endif
3733
3734 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3735 {
3736 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3737 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3738
3739 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3740 RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);
3741 rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);
3742 }
3743 }
3744 #endif
3745 }
3746
3747 #if CONFIG_TX_AC_LIFETIME
3748 const char *const _tx_aclt_conf_str[] = {
3749 "DEFAULT",
3750 "AP_M2U",
3751 "MESH",
3752 "INVALID",
3753 };
3754
dump_tx_aclt_force_val(void * sel,struct dvobj_priv * dvobj)3755 void dump_tx_aclt_force_val(void *sel, struct dvobj_priv *dvobj)
3756 {
3757 #define TX_ACLT_FORCE_MSG_LEN 64
3758 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3759 struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3760 char buf[TX_ACLT_FORCE_MSG_LEN];
3761 int cnt = 0;
3762
3763 RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3764 , hal_spec->tx_aclt_unit_factor * 32
3765 , 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3766
3767 RTW_PRINT_SEL(sel, "%-5s %-12s %-12s\n", "en", "vo_vi(us)", "be_bk(us)");
3768 RTW_PRINT_SEL(sel, " 0x%02x %12u %12u\n"
3769 , conf->en
3770 , conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3771 , conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3772 );
3773
3774 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "%5s", conf->en == 0xFF ? "AUTO" : "FORCE");
3775 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3776 goto exit;
3777
3778 if (conf->vo_vi)
3779 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->vo_vi);
3780 else
3781 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");
3782 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3783 goto exit;
3784
3785
3786 if (conf->be_bk)
3787 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->be_bk);
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 RTW_PRINT_SEL(sel, "%s\n", buf);
3794
3795 exit:
3796 return;
3797 }
3798
rtw_hal_set_tx_aclt_force_val(_adapter * adapter,struct tx_aclt_conf_t * input,u8 arg_num)3799 void rtw_hal_set_tx_aclt_force_val(_adapter *adapter, struct tx_aclt_conf_t *input, u8 arg_num)
3800 {
3801 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3802 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3803 struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3804
3805 if (arg_num >= 1) {
3806 if (input->en == 0xFF)
3807 conf->en = input->en;
3808 else
3809 conf->en = input->en & 0xF;
3810 }
3811 if (arg_num >= 2) {
3812 conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
3813 if (conf->vo_vi > 0xFFFF)
3814 conf->vo_vi = 0xFFFF;
3815 }
3816 if (arg_num >= 3) {
3817 conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
3818 if (conf->be_bk > 0xFFFF)
3819 conf->be_bk = 0xFFFF;
3820 }
3821 }
3822
dump_tx_aclt_confs(void * sel,struct dvobj_priv * dvobj)3823 void dump_tx_aclt_confs(void *sel, struct dvobj_priv *dvobj)
3824 {
3825 #define TX_ACLT_CONF_MSG_LEN 32
3826 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3827 struct tx_aclt_conf_t *conf;
3828 char buf[TX_ACLT_CONF_MSG_LEN];
3829 int cnt;
3830 int i;
3831
3832 RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3833 , hal_spec->tx_aclt_unit_factor * 32
3834 , 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3835
3836 RTW_PRINT_SEL(sel, "%-7s %-1s %-3s %-9s %-9s %-10s %-10s\n"
3837 , "name", "#", "en", "vo_vi(us)", "be_bk(us)", "vo_vi(reg)", "be_bk(reg)");
3838
3839 for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
3840 conf = &dvobj->tx_aclt_confs[i];
3841 cnt = 0;
3842
3843 if (conf->vo_vi)
3844 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->vo_vi);
3845 else
3846 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
3847 if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
3848 continue;
3849
3850 if (conf->be_bk)
3851 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->be_bk);
3852 else
3853 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
3854 if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
3855 continue;
3856
3857 RTW_PRINT_SEL(sel, "%7s %1u 0x%x %9u %9u%s\n"
3858 , tx_aclt_conf_str(i), i
3859 , conf->en
3860 , conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3861 , conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3862 , buf
3863 );
3864 }
3865 }
3866
rtw_hal_set_tx_aclt_conf(_adapter * adapter,u8 conf_idx,struct tx_aclt_conf_t * input,u8 arg_num)3867 void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_conf_t *input, u8 arg_num)
3868 {
3869 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3870 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3871 struct tx_aclt_conf_t *conf;
3872
3873 if (conf_idx >= TX_ACLT_CONF_NUM)
3874 return;
3875
3876 conf = &dvobj->tx_aclt_confs[conf_idx];
3877
3878 if (arg_num >= 1) {
3879 if (input->en != 0xFF)
3880 conf->en = input->en & 0xF;
3881 }
3882 if (arg_num >= 2) {
3883 conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
3884 if (conf->vo_vi > 0xFFFF)
3885 conf->vo_vi = 0xFFFF;
3886 }
3887 if (arg_num >= 3) {
3888 conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
3889 if (conf->be_bk > 0xFFFF)
3890 conf->be_bk = 0xFFFF;
3891 }
3892 }
3893
rtw_hal_update_tx_aclt(_adapter * adapter)3894 void rtw_hal_update_tx_aclt(_adapter *adapter)
3895 {
3896 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3897 struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter);
3898 u8 lt_en = 0, lt_en_ori;
3899 u16 lt_vo_vi = 0xFFFF, lt_be_bk = 0xFFFF;
3900 u32 lt, lt_ori;
3901 struct tx_aclt_conf_t *conf;
3902 int i;
3903 #ifdef CONFIG_AP_MODE
3904 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
3905 _adapter *iface;
3906 u8 ap_m2u_num = 0;
3907
3908 for (i = 0; i < dvobj->iface_nums; i++) {
3909 iface = dvobj->padapters[i];
3910 if (!iface)
3911 continue;
3912
3913 if (MLME_IS_AP(iface)
3914 && ((iface->b2u_flags_ap_src & RTW_AP_B2U_IP_MCAST)
3915 || (iface->b2u_flags_ap_fwd & RTW_AP_B2U_IP_MCAST))
3916 )
3917 ap_m2u_num++;
3918 }
3919 #endif
3920 #endif /* CONFIG_AP_MODE */
3921
3922 lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN);
3923 lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME);
3924
3925 for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
3926 if (!(dvobj->tx_aclt_flags & BIT(i)))
3927 continue;
3928
3929 conf = &dvobj->tx_aclt_confs[i];
3930
3931 if (i == TX_ACLT_CONF_DEFAULT) {
3932 /* first and default status, assign directly */
3933 lt_en = conf->en;
3934 if (conf->vo_vi)
3935 lt_vo_vi = conf->vo_vi;
3936 if (conf->be_bk)
3937 lt_be_bk = conf->be_bk;
3938 }
3939 #ifdef CONFIG_AP_MODE
3940 #if CONFIG_RTW_AP_DATA_BMC_TO_UC || defined(CONFIG_RTW_MESH)
3941 else if (0
3942 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
3943 || (i == TX_ACLT_CONF_AP_M2U
3944 && ap_m2u_num
3945 && macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */)
3946 #endif
3947 #ifdef CONFIG_RTW_MESH
3948 || (i == TX_ACLT_CONF_MESH
3949 && macid_ctl->op_num[H2C_MSR_ROLE_MESH] > 1 /* implies only 1 MESH mode supported */)
3950 #endif
3951 ) {
3952 /* long term status, OR en and MIN lifetime */
3953 lt_en |= conf->en;
3954 if (conf->vo_vi && lt_vo_vi > conf->vo_vi)
3955 lt_vo_vi = conf->vo_vi;
3956 if (conf->be_bk && lt_be_bk > conf->be_bk)
3957 lt_be_bk = conf->be_bk;
3958 }
3959 #endif
3960 #endif /* CONFIG_AP_MODE */
3961 }
3962
3963 if (dvobj->tx_aclt_force_val.en != 0xFF)
3964 lt_en = dvobj->tx_aclt_force_val.en;
3965 if (dvobj->tx_aclt_force_val.vo_vi)
3966 lt_vo_vi = dvobj->tx_aclt_force_val.vo_vi;
3967 if (dvobj->tx_aclt_force_val.be_bk)
3968 lt_be_bk = dvobj->tx_aclt_force_val.be_bk;
3969
3970 lt_en = (lt_en_ori & 0xF0) | (lt_en & 0x0F);
3971 lt = (lt_be_bk << 16) | lt_vo_vi;
3972
3973 if (0)
3974 RTW_INFO("lt_en:0x%x(0x%x), lt:0x%08x(0x%08x)\n", lt_en, lt_en_ori, lt, lt_ori);
3975
3976 if (lt_en != lt_en_ori)
3977 rtw_write8(adapter, REG_LIFETIME_EN, lt_en);
3978 if (lt != lt_ori)
3979 rtw_write32(adapter, REG_PKT_LIFE_TIME, lt);
3980 }
3981 #endif /* CONFIG_TX_AC_LIFETIME */
3982
hw_var_port_switch(_adapter * adapter)3983 void hw_var_port_switch(_adapter *adapter)
3984 {
3985 #ifdef CONFIG_CONCURRENT_MODE
3986 #ifdef CONFIG_RUNTIME_PORT_SWITCH
3987 /*
3988 0x102: MSR
3989 0x550: REG_BCN_CTRL
3990 0x551: REG_BCN_CTRL_1
3991 0x55A: REG_ATIMWND
3992 0x560: REG_TSFTR
3993 0x568: REG_TSFTR1
3994 0x570: REG_ATIMWND_1
3995 0x610: REG_MACID
3996 0x618: REG_BSSID
3997 0x700: REG_MACID1
3998 0x708: REG_BSSID1
3999 */
4000
4001 int i;
4002 u8 msr;
4003 u8 bcn_ctrl;
4004 u8 bcn_ctrl_1;
4005 u8 atimwnd[2];
4006 u8 atimwnd_1[2];
4007 u8 tsftr[8];
4008 u8 tsftr_1[8];
4009 u8 macid[6];
4010 u8 bssid[6];
4011 u8 macid_1[6];
4012 u8 bssid_1[6];
4013 #if defined(CONFIG_RTL8192F)
4014 u16 wlan_act_mask_ctrl = 0;
4015 u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;
4016 #endif
4017
4018 u8 hw_port;
4019 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4020 _adapter *iface = NULL;
4021
4022 msr = rtw_read8(adapter, MSR);
4023 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4024 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4025 #if defined(CONFIG_RTL8192F)
4026 wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4027 #endif
4028
4029 for (i = 0; i < 2; i++)
4030 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4031 for (i = 0; i < 2; i++)
4032 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4033
4034 for (i = 0; i < 8; i++)
4035 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4036 for (i = 0; i < 8; i++)
4037 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4038
4039 for (i = 0; i < 6; i++)
4040 macid[i] = rtw_read8(adapter, REG_MACID + i);
4041
4042 for (i = 0; i < 6; i++)
4043 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4044
4045 for (i = 0; i < 6; i++)
4046 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4047
4048 for (i = 0; i < 6; i++)
4049 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4050
4051 #ifdef DBG_RUNTIME_PORT_SWITCH
4052 RTW_INFO(FUNC_ADPT_FMT" before switch\n"
4053 "msr:0x%02x\n"
4054 "bcn_ctrl:0x%02x\n"
4055 "bcn_ctrl_1:0x%02x\n"
4056 #if defined(CONFIG_RTL8192F)
4057 "wlan_act_mask_ctrl:0x%02x\n"
4058 #endif
4059 "atimwnd:0x%04x\n"
4060 "atimwnd_1:0x%04x\n"
4061 "tsftr:%llu\n"
4062 "tsftr1:%llu\n"
4063 "macid:"MAC_FMT"\n"
4064 "bssid:"MAC_FMT"\n"
4065 "macid_1:"MAC_FMT"\n"
4066 "bssid_1:"MAC_FMT"\n"
4067 , FUNC_ADPT_ARG(adapter)
4068 , msr
4069 , bcn_ctrl
4070 , bcn_ctrl_1
4071 #if defined(CONFIG_RTL8192F)
4072 , wlan_act_mask_ctrl
4073 #endif
4074 , *((u16 *)atimwnd)
4075 , *((u16 *)atimwnd_1)
4076 , *((u64 *)tsftr)
4077 , *((u64 *)tsftr_1)
4078 , MAC_ARG(macid)
4079 , MAC_ARG(bssid)
4080 , MAC_ARG(macid_1)
4081 , MAC_ARG(bssid_1)
4082 );
4083 #endif /* DBG_RUNTIME_PORT_SWITCH */
4084
4085 /* disable bcn function, disable update TSF */
4086 rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4087 rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4088
4089 #if defined(CONFIG_RTL8192F)
4090 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);
4091 #endif
4092
4093 /* switch msr */
4094 msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
4095 rtw_write8(adapter, MSR, msr);
4096
4097 /* write port0 */
4098 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
4099 for (i = 0; i < 2; i++)
4100 rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
4101 for (i = 0; i < 8; i++)
4102 rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
4103 for (i = 0; i < 6; i++)
4104 rtw_write8(adapter, REG_MACID + i, macid_1[i]);
4105 for (i = 0; i < 6; i++)
4106 rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
4107
4108 /* write port1 */
4109 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
4110 for (i = 0; i < 2; i++)
4111 rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
4112 for (i = 0; i < 8; i++)
4113 rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
4114 for (i = 0; i < 6; i++)
4115 rtw_write8(adapter, REG_MACID1 + i, macid[i]);
4116 for (i = 0; i < 6; i++)
4117 rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
4118
4119 /* write bcn ctl */
4120 #ifdef CONFIG_BT_COEXIST
4121 /* always enable port0 beacon function for PSTDMA */
4122 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
4123 || IS_HARDWARE_TYPE_8723D(adapter))
4124 bcn_ctrl_1 |= EN_BCN_FUNCTION;
4125 /* always disable port1 beacon function for PSTDMA */
4126 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
4127 bcn_ctrl &= ~EN_BCN_FUNCTION;
4128 #endif
4129 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
4130 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
4131
4132 #if defined(CONFIG_RTL8192F)
4133 /* if the setting of port0 and port1 are the same, it does not need to switch port setting*/
4134 if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)
4135 != (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))
4136 wlan_act_mask_ctrl ^= en_port_mask;
4137 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);
4138 #endif
4139
4140 if (adapter->iface_id == IFACE_ID0)
4141 iface = dvobj->padapters[IFACE_ID1];
4142 else if (adapter->iface_id == IFACE_ID1)
4143 iface = dvobj->padapters[IFACE_ID0];
4144
4145
4146 if (adapter->hw_port == HW_PORT0) {
4147 adapter->hw_port = HW_PORT1;
4148 iface->hw_port = HW_PORT0;
4149 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4150 ADPT_ARG(iface), ADPT_ARG(adapter));
4151 } else {
4152 adapter->hw_port = HW_PORT0;
4153 iface->hw_port = HW_PORT1;
4154 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4155 ADPT_ARG(adapter), ADPT_ARG(iface));
4156 }
4157
4158 #ifdef DBG_RUNTIME_PORT_SWITCH
4159 msr = rtw_read8(adapter, MSR);
4160 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4161 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4162 #if defined(CONFIG_RTL8192F)
4163 wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4164 #endif
4165
4166 for (i = 0; i < 2; i++)
4167 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4168 for (i = 0; i < 2; i++)
4169 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4170
4171 for (i = 0; i < 8; i++)
4172 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4173 for (i = 0; i < 8; i++)
4174 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4175
4176 for (i = 0; i < 6; i++)
4177 macid[i] = rtw_read8(adapter, REG_MACID + i);
4178
4179 for (i = 0; i < 6; i++)
4180 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4181
4182 for (i = 0; i < 6; i++)
4183 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4184
4185 for (i = 0; i < 6; i++)
4186 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4187
4188 RTW_INFO(FUNC_ADPT_FMT" after switch\n"
4189 "msr:0x%02x\n"
4190 "bcn_ctrl:0x%02x\n"
4191 "bcn_ctrl_1:0x%02x\n"
4192 #if defined(CONFIG_RTL8192F)
4193 "wlan_act_mask_ctrl:0x%02x\n"
4194 #endif
4195 "atimwnd:%u\n"
4196 "atimwnd_1:%u\n"
4197 "tsftr:%llu\n"
4198 "tsftr1:%llu\n"
4199 "macid:"MAC_FMT"\n"
4200 "bssid:"MAC_FMT"\n"
4201 "macid_1:"MAC_FMT"\n"
4202 "bssid_1:"MAC_FMT"\n"
4203 , FUNC_ADPT_ARG(adapter)
4204 , msr
4205 , bcn_ctrl
4206 , bcn_ctrl_1
4207 #if defined(CONFIG_RTL8192F)
4208 , wlan_act_mask_ctrl
4209 #endif
4210 , *((u16 *)atimwnd)
4211 , *((u16 *)atimwnd_1)
4212 , *((u64 *)tsftr)
4213 , *((u64 *)tsftr_1)
4214 , MAC_ARG(macid)
4215 , MAC_ARG(bssid)
4216 , MAC_ARG(macid_1)
4217 , MAC_ARG(bssid_1)
4218 );
4219 #endif /* DBG_RUNTIME_PORT_SWITCH */
4220
4221 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
4222 #endif /* CONFIG_CONCURRENT_MODE */
4223 }
4224
4225 const char *const _h2c_msr_role_str[] = {
4226 "RSVD",
4227 "STA",
4228 "AP",
4229 "GC",
4230 "GO",
4231 "TDLS",
4232 "ADHOC",
4233 "MESH",
4234 "INVALID",
4235 };
4236
4237 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_default_port_id_cmd(_adapter * adapter,u8 mac_id)4238 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
4239 {
4240 s32 ret = _SUCCESS;
4241 u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
4242 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4243 u8 port_id = rtw_hal_get_port(adapter);
4244
4245 if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))
4246 return ret;
4247
4248 SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);
4249 SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
4250
4251 RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
4252 RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",
4253 __func__, ADPT_ARG(adapter), port_id, mac_id);
4254
4255 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
4256 dvobj->dft.port_id = port_id;
4257 dvobj->dft.mac_id = mac_id;
4258
4259 return ret;
4260 }
rtw_set_default_port_id(_adapter * adapter)4261 s32 rtw_set_default_port_id(_adapter *adapter)
4262 {
4263 s32 ret = _SUCCESS;
4264 struct sta_info *psta;
4265 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4266
4267 if (is_client_associated_to_ap(adapter)) {
4268 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
4269 if (psta)
4270 ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
4271 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
4272
4273 } else {
4274 }
4275
4276 return ret;
4277 }
rtw_set_ps_rsvd_page(_adapter * adapter)4278 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
4279 {
4280 s32 ret = _SUCCESS;
4281 u16 media_status_rpt = RT_MEDIA_CONNECT;
4282 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4283
4284 if (adapter->iface_id == pwrctl->fw_psmode_iface_id)
4285 return ret;
4286
4287 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
4288 (u8 *)&media_status_rpt);
4289
4290 return ret;
4291 }
4292
4293 #if 0
4294 _adapter * _rtw_search_dp_iface(_adapter *adapter)
4295 {
4296 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4297 _adapter *iface;
4298 _adapter *target_iface = NULL;
4299 int i;
4300 u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;
4301 u8 p2p_go_num = 0, p2p_gc_num = 0;
4302 _adapter *sta_ifs[8];
4303 _adapter *ap_ifs[8];
4304 _adapter *mesh_ifs[8];
4305 _adapter *gc_ifs[8];
4306 _adapter *go_ifs[8];
4307
4308 for (i = 0; i < dvobj->iface_nums; i++) {
4309 iface = dvobj->padapters[i];
4310
4311 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
4312 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4313 sta_ifs[sta_num++] = iface;
4314
4315 #ifdef CONFIG_TDLS
4316 if (iface->tdlsinfo.link_established == _TRUE)
4317 tdls_num++;
4318 #endif
4319 #ifdef CONFIG_P2P
4320 if (MLME_IS_GC(iface))
4321 gc_ifs[p2p_gc_num++] = iface;
4322 #endif
4323 }
4324 #ifdef CONFIG_AP_MODE
4325 } else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
4326 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4327 ap_ifs[ap_num++] = iface;
4328 #ifdef CONFIG_P2P
4329 if (MLME_IS_GO(iface))
4330 go_ifs[p2p_go_num++] = iface;
4331 #endif
4332 }
4333 #endif
4334 } else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
4335 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4336 ) {
4337 adhoc_num++;
4338
4339 #ifdef CONFIG_RTW_MESH
4340 } else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
4341 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4342 ) {
4343 mesh_ifs[mesh_num++] = iface;
4344 #endif
4345 }
4346 }
4347
4348 if (p2p_gc_num) {
4349 target_iface = gc_ifs[0];
4350 }
4351 else if (sta_num) {
4352 if(sta_num == 1) {
4353 target_iface = sta_ifs[0];
4354 } else if (sta_num >= 2) {
4355 /*TODO get target_iface by timestamp*/
4356 target_iface = sta_ifs[0];
4357 }
4358 } else if (ap_num) {
4359 target_iface = ap_ifs[0];
4360 }
4361
4362 RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);
4363 RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);
4364 RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);
4365 RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);
4366 RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);
4367 RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);
4368 RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);
4369
4370 if (target_iface)
4371 RTW_INFO("%s => target_iface ("ADPT_FMT")\n",
4372 __func__, ADPT_ARG(target_iface));
4373 else
4374 RTW_INFO("%s => target_iface NULL\n", __func__);
4375
4376 return target_iface;
4377 }
4378
4379 void rtw_search_default_port(_adapter *adapter)
4380 {
4381 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4382 _adapter *adp_iface = NULL;
4383 #ifdef CONFIG_WOWLAN
4384 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
4385
4386 if (pwrpriv->wowlan_mode == _TRUE) {
4387 adp_iface = adapter;
4388 goto exit;
4389 }
4390 #endif
4391 adp_iface = _rtw_search_dp_iface(adapter);
4392
4393 exit :
4394 if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))
4395 rtw_set_default_port_id(adp_iface);
4396 else
4397 rtw_hal_set_default_port_id_cmd(adapter, 0);
4398
4399 if (1) {
4400 _adapter *tmp_adp;
4401
4402 tmp_adp = (adp_iface) ? adp_iface : adapter;
4403
4404 RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",
4405 __func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));
4406 }
4407 }
4408 #endif
4409 #endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/
4410
4411 #ifdef CONFIG_P2P_PS
4412 #ifdef RTW_HALMAC
rtw_set_p2p_ps_offload_cmd(_adapter * adapter,u8 p2p_ps_state)4413 void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
4414 {
4415 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4416 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4417 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4418 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4419 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
4420 struct sta_priv *pstapriv = &adapter->stapriv;
4421 struct sta_info *psta;
4422 HAL_P2P_PS_PARA p2p_ps_para;
4423 int status = -1;
4424 u8 i;
4425 u8 hw_port = rtw_hal_get_port(adapter);
4426
4427 _rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
4428 _rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
4429
4430 (&p2p_ps_para)->p2p_port_id = hw_port;
4431 (&p2p_ps_para)->p2p_group = 0;
4432 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
4433 if (psta) {
4434 (&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
4435 } else {
4436 if (p2p_ps_state != P2P_PS_DISABLE) {
4437 RTW_ERR("%s , psta was NULL\n", __func__);
4438 return;
4439 }
4440 }
4441
4442
4443 switch (p2p_ps_state) {
4444 case P2P_PS_DISABLE:
4445 RTW_INFO("P2P_PS_DISABLE\n");
4446 _rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
4447 break;
4448
4449 case P2P_PS_ENABLE:
4450 RTW_INFO("P2P_PS_ENABLE\n");
4451 /* update CTWindow value. */
4452 if (pwdinfo->ctwindow > 0) {
4453 (&p2p_ps_para)->ctwindow_en = 1;
4454 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4455 /*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
4456 }
4457
4458
4459 if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
4460 (&p2p_ps_para)->offload_en = 1;
4461 if (pwdinfo->role == P2P_ROLE_GO) {
4462 (&p2p_ps_para)->role = 1;
4463 (&p2p_ps_para)->all_sta_sleep = 0;
4464 } else
4465 (&p2p_ps_para)->role = 0;
4466
4467 (&p2p_ps_para)->discovery = 0;
4468 }
4469 /* hw only support 2 set of NoA */
4470 for (i = 0; i < pwdinfo->noa_num; i++) {
4471 /* To control the register setting for which NOA */
4472 (&p2p_ps_para)->noa_sel = i;
4473 (&p2p_ps_para)->noa_en = 1;
4474 (&p2p_ps_para)->disable_close_rf = 0;
4475 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
4476 #ifdef CONFIG_CONCURRENT_MODE
4477 if (rtw_mi_buddy_check_fwstate(adapter, WIFI_ASOC_STATE))
4478 #endif /* CONFIG_CONCURRENT_MODE */
4479 (&p2p_ps_para)->disable_close_rf = 1;
4480 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
4481 /* config P2P NoA Descriptor Register */
4482 /* config NOA duration */
4483 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
4484 /* config NOA interval */
4485 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
4486 /* config NOA start time */
4487 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
4488 /* config NOA count */
4489 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
4490 /*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
4491 (&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
4492 (&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
4493 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4494 if (status == -1)
4495 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4496 }
4497
4498 break;
4499
4500 case P2P_PS_SCAN:
4501 /*This feature FW not ready 20161116 YiWei*/
4502 return;
4503 /*
4504 RTW_INFO("P2P_PS_SCAN\n");
4505 (&p2p_ps_para)->discovery = 1;
4506 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4507 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4508 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4509 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4510 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4511 */
4512 break;
4513
4514 case P2P_PS_SCAN_DONE:
4515 /*This feature FW not ready 20161116 YiWei*/
4516 return;
4517 /*
4518 RTW_INFO("P2P_PS_SCAN_DONE\n");
4519 (&p2p_ps_para)->discovery = 0;
4520 pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
4521 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4522 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4523 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4524 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4525 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4526 */
4527 break;
4528
4529 default:
4530 break;
4531 }
4532
4533 if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
4534 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4535 if (status == -1)
4536 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4537 }
4538 _rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
4539
4540 }
4541 #endif /* RTW_HALMAC */
4542 #endif /* CONFIG_P2P */
4543
4544 #if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR)
_rtw_hal_dtp_macid_set(_adapter * padapter,u8 opmode,u8 mac_id)4545 static void _rtw_hal_dtp_macid_set(
4546 _adapter *padapter, u8 opmode, u8 mac_id)
4547 {
4548 struct macid_ctl_t *macid_ctl = &(padapter->dvobj->macid_ctl);
4549 struct sta_info *psta;
4550 u8 h2c_cmd[H2C_FW_CRC5_SEARCH_LEN] = {0};
4551 u8 mac_addr[ETH_ALEN] = {0};
4552
4553 if (opmode) {
4554 psta = macid_ctl->sta[mac_id];
4555 if (psta)
4556 _rtw_memcpy(mac_addr, psta->cmn.mac_addr, ETH_ALEN);
4557
4558 if (rtw_check_invalid_mac_address(mac_addr, _FALSE))
4559 return;
4560 }
4561 /* else DON'T CARE H2C_FW_CRC5_SEARCH mac addr in disconnected case */
4562
4563 if (rtw_get_chip_type(padapter) == RTL8822C) {
4564 SET_H2CCMD_FW_CRC5_SEARCH_EN(h2c_cmd, opmode);
4565 SET_H2CCMD_FW_CRC5_SEARCH_MACID(h2c_cmd, mac_id);
4566 SET_H2CCMD_FW_CRC5_SEARCH_MAC(&h2c_cmd[1], mac_addr);
4567 if (rtw_hal_fill_h2c_cmd(padapter, H2C_FW_CRC5_SEARCH,
4568 H2C_FW_CRC5_SEARCH_LEN, h2c_cmd) != _SUCCESS)
4569 RTW_WARN("%s : set h2c - 0x%02x fail!\n", __func__, H2C_FW_CRC5_SEARCH);
4570 }
4571 }
4572
rtw_hal_dtp_macid_set(_adapter * padapter,u8 opmode,bool macid_ind,u8 mac_id,u8 macid_end)4573 static void rtw_hal_dtp_macid_set(_adapter *padapter, u8 opmode,
4574 bool macid_ind, u8 mac_id, u8 macid_end)
4575 {
4576 int i;
4577
4578 if (macid_ind == 0) {
4579 _rtw_hal_dtp_macid_set(padapter, opmode, mac_id);
4580 } else {
4581 for (i = mac_id; i <= macid_end; i++)
4582 _rtw_hal_dtp_macid_set(padapter, opmode, i);
4583 }
4584 }
4585 #endif
4586
4587 /*
4588 * rtw_hal_set_FwMediaStatusRpt_cmd -
4589 *
4590 * @adapter:
4591 * @opmode: 0:disconnect, 1:connect
4592 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
4593 * @miracast_sink: 0:source. 1:sink
4594 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
4595 * @macid:
4596 * @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end
4597 * @macid_end:
4598 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)4599 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)
4600 {
4601 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
4602 u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
4603 int i;
4604 s32 ret;
4605 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4606 u8 hw_port = rtw_hal_get_port(adapter);
4607 #endif
4608 u8 op_num_change_bmp = 0;
4609
4610 #if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR)
4611 rtw_hal_dtp_macid_set(adapter, opmode, macid_ind, macid, macid_end);
4612 #endif
4613
4614 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
4615 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
4616 SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
4617 SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
4618 SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
4619 SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
4620 SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
4621 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4622 SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);
4623 #endif
4624 RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
4625
4626 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
4627 if (ret != _SUCCESS)
4628 goto exit;
4629
4630 #if defined(CONFIG_RTL8188E)
4631 if (rtw_get_chip_type(adapter) == RTL8188E) {
4632 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4633
4634 /* 8188E FW doesn't set macid no link, driver does it by self */
4635 if (opmode)
4636 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
4637 else
4638 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
4639
4640 /* for 8188E RA */
4641 #if (RATE_ADAPTIVE_SUPPORT == 1)
4642 if (hal_data->fw_ractrl == _FALSE) {
4643 u8 max_macid;
4644
4645 max_macid = rtw_search_max_mac_id(adapter);
4646 rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
4647 }
4648 #endif
4649 }
4650 #endif
4651
4652 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
4653 /* TODO: this should move to IOT issue area */
4654 if (rtw_get_chip_type(adapter) == RTL8812
4655 || rtw_get_chip_type(adapter) == RTL8821
4656 ) {
4657 if (MLME_IS_STA(adapter))
4658 Hal_PatchwithJaguar_8812(adapter, opmode);
4659 }
4660 #endif
4661
4662 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
4663 if (macid_ind == 0)
4664 macid_end = macid;
4665
4666 for (i = macid; macid <= macid_end; macid++) {
4667 op_num_change_bmp |= rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
4668 if (!opmode) {
4669 rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
4670 rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
4671 rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
4672 rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
4673 }
4674 }
4675
4676 #if CONFIG_TX_AC_LIFETIME
4677 if (op_num_change_bmp)
4678 rtw_hal_update_tx_aclt(adapter);
4679 #endif
4680
4681 if (!opmode)
4682 rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
4683
4684 exit:
4685 return ret;
4686 }
4687
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)4688 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
4689 {
4690 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
4691 }
4692
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)4693 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
4694 {
4695 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
4696 }
4697
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4698 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4699 {
4700 u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
4701 u8 ret = 0;
4702
4703 RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
4704 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
4705 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
4706 rsvdpageloc->LocBTQosNull);
4707
4708 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
4709 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
4710 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
4711 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
4712 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
4713
4714 ret = rtw_hal_fill_h2c_cmd(padapter,
4715 H2C_RSVD_PAGE,
4716 H2C_RSVDPAGE_LOC_LEN,
4717 u1H2CRsvdPageParm);
4718
4719 }
4720
4721 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)4722 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
4723 {
4724 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4725
4726 if (IS_8723D_SERIES(pHalData->version_id) || IS_8192F_SERIES(pHalData->version_id)
4727 || IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id)
4728 || IS_8822C_SERIES(pHalData->version_id))
4729 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4730 /*
4731 * Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
4732 * It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
4733 * and implement HAL function.
4734 * TODO: GPIO_8 multi function?
4735 */
4736
4737 if ((index == 13 || index == 14)
4738 #if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
4739 /* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
4740 && (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
4741 #endif
4742 )
4743 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4744 }
4745
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)4746 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
4747 {
4748 #if defined(CONFIG_RTL8192F)
4749 rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&outputval));
4750 #else
4751 if (index <= 7) {
4752 /* config GPIO mode */
4753 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4754 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4755
4756 /* config GPIO Sel */
4757 /* 0: input */
4758 /* 1: output */
4759 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4760 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
4761
4762 /* set output value */
4763 if (outputval) {
4764 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4765 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
4766 } else {
4767 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4768 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
4769 }
4770 } else if (index <= 15) {
4771 /* 88C Series: */
4772 /* index: 11~8 transform to 3~0 */
4773 /* 8723 Series: */
4774 /* index: 12~8 transform to 4~0 */
4775
4776 index -= 8;
4777
4778 /* config GPIO mode */
4779 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4780 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4781
4782 /* config GPIO Sel */
4783 /* 0: input */
4784 /* 1: output */
4785 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4786 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
4787
4788 /* set output value */
4789 if (outputval) {
4790 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4791 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
4792 } else {
4793 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4794 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
4795 }
4796 } else {
4797 RTW_INFO("%s: invalid GPIO%d=%d\n",
4798 __FUNCTION__, index, outputval);
4799 }
4800 #endif
4801 }
rtw_hal_set_input_gpio(_adapter * padapter,u8 index)4802 void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
4803 {
4804 #if defined(CONFIG_RTL8192F)
4805 rtw_hal_set_hwreg(padapter, HW_VAR_WOW_INPUT_GPIO, (u8 *)(&index));
4806 #else
4807 if (index <= 7) {
4808 /* config GPIO mode */
4809 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4810 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4811
4812 /* config GPIO Sel */
4813 /* 0: input */
4814 /* 1: output */
4815 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4816 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
4817
4818 } else if (index <= 15) {
4819 /* 88C Series: */
4820 /* index: 11~8 transform to 3~0 */
4821 /* 8723 Series: */
4822 /* index: 12~8 transform to 4~0 */
4823
4824 index -= 8;
4825
4826 /* config GPIO mode */
4827 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4828 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4829
4830 /* config GPIO Sel */
4831 /* 0: input */
4832 /* 1: output */
4833 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4834 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
4835 } else
4836 RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
4837 #endif
4838 }
4839
4840 #endif
4841
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4842 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4843 {
4844 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
4845 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4846 u8 ret = 0;
4847 #ifdef CONFIG_WOWLAN
4848 u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
4849
4850 RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
4851 __func__, rsvdpageloc->LocRemoteCtrlInfo,
4852 rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
4853 rsvdpageloc->LocNDPInfo);
4854 RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
4855 __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
4856 rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
4857
4858 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
4859 SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
4860 SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
4861 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
4862 rsvdpageloc->LocNbrAdv);
4863 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
4864 rsvdpageloc->LocNDPInfo);
4865 #ifdef CONFIG_GTK_OL
4866 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
4867 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
4868 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
4869 #endif /* CONFIG_GTK_OL */
4870 ret = rtw_hal_fill_h2c_cmd(padapter,
4871 H2C_AOAC_RSVD_PAGE,
4872 H2C_AOAC_RSVDPAGE_LOC_LEN,
4873 u1H2CAoacRsvdPageParm);
4874
4875 RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
4876 _rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
4877 SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
4878 rsvdpageloc->LocAOACReport);
4879 ret = rtw_hal_fill_h2c_cmd(padapter,
4880 H2C_AOAC_RSVDPAGE3,
4881 H2C_AOAC_RSVDPAGE_LOC_LEN,
4882 u1H2CAoacRsvdPageParm);
4883 pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
4884 }
4885 #ifdef CONFIG_PNO_SUPPORT
4886 else {
4887
4888 if (!pwrpriv->wowlan_in_resume) {
4889 RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
4890 _rtw_memset(&u1H2CAoacRsvdPageParm, 0,
4891 sizeof(u1H2CAoacRsvdPageParm));
4892 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
4893 rsvdpageloc->LocPNOInfo);
4894 ret = rtw_hal_fill_h2c_cmd(padapter,
4895 H2C_AOAC_RSVDPAGE3,
4896 H2C_AOAC_RSVDPAGE_LOC_LEN,
4897 u1H2CAoacRsvdPageParm);
4898 }
4899 }
4900 #endif /* CONFIG_PNO_SUPPORT */
4901 #endif /* CONFIG_WOWLAN */
4902 }
4903
4904 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4905 void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4906 {
4907 struct hal_ops *pHalFunc = &padapter->hal_func;
4908 u8 u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};
4909 u8 ret = 0;
4910
4911
4912 RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);
4913
4914 SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);
4915 SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);
4916 ret = rtw_hal_fill_h2c_cmd(padapter,
4917 H2C_FW_DBG_MSG_PKT,
4918 H2C_FW_DBG_MSG_PKT_LEN,
4919 u1H2C_fw_dbg_msg_pkt_parm);
4920
4921 }
4922 #endif /*DBG_FW_DEBUG_MSG_PKT*/
4923
4924 /*#define DBG_GET_RSVD_PAGE*/
rtw_hal_get_rsvd_page(_adapter * adapter,u32 page_offset,u32 page_num,u8 * buffer,u32 buffer_size)4925 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
4926 u32 page_num, u8 *buffer, u32 buffer_size)
4927 {
4928 u32 addr = 0, size = 0, count = 0;
4929 u32 page_size = 0, data_low = 0, data_high = 0;
4930 u16 txbndy = 0, offset = 0;
4931 u8 i = 0;
4932 bool rst = _FALSE;
4933
4934 #ifdef DBG_LA_MODE
4935 struct registry_priv *registry_par = &adapter->registrypriv;
4936
4937 if(registry_par->la_mode_en == 1) {
4938 RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);
4939 return rst;
4940 }
4941 #endif
4942 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
4943
4944 addr = page_offset * page_size;
4945 size = page_num * page_size;
4946
4947 if (buffer_size < size) {
4948 RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
4949 __func__, buffer_size, size);
4950 return rst;
4951 }
4952 #ifdef RTW_HALMAC
4953 if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
4954 rst = _FALSE;
4955 else
4956 rst = _TRUE;
4957 #else
4958 txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
4959
4960 offset = (txbndy + page_offset) * page_size / 8;
4961 count = (buffer_size / 8) + 1;
4962
4963 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
4964
4965 for (i = 0 ; i < count ; i++) {
4966 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
4967 data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
4968 data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
4969 _rtw_memcpy(buffer + (i * 8),
4970 &data_low, sizeof(data_low));
4971 _rtw_memcpy(buffer + ((i * 8) + 4),
4972 &data_high, sizeof(data_high));
4973 }
4974 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
4975 rst = _TRUE;
4976 #endif /*RTW_HALMAC*/
4977
4978 #ifdef DBG_GET_RSVD_PAGE
4979 RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
4980 __func__, page_offset, page_num, addr, size);
4981 RTW_INFO_DUMP("\n", buffer, size);
4982 RTW_INFO(" ==================================================\n");
4983 #endif
4984 return rst;
4985 }
4986
rtw_dump_rsvd_page(void * sel,_adapter * adapter,u8 page_offset,u8 page_num)4987 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
4988 {
4989 #if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG)
4990 u32 page_size = 0;
4991 u8 *buffer = NULL;
4992 u32 buf_size = 0;
4993
4994 if (page_num == 0)
4995 return;
4996
4997 RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");
4998 RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
4999
5000 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5001 if (page_size) {
5002 buf_size = page_size * page_num;
5003 buffer = rtw_zvmalloc(buf_size);
5004
5005 if (buffer) {
5006 rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
5007 RTW_DUMP_SEL(sel, buffer, buf_size);
5008 rtw_vmfree(buffer, buf_size);
5009 } else
5010 RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
5011 } else
5012 RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
5013
5014 RTW_PRINT_SEL(sel, "==========================\n");
5015 #endif
5016 }
5017
5018 #ifdef CONFIG_SUPPORT_FIFO_DUMP
rtw_dump_fifo(void * sel,_adapter * adapter,u8 fifo_sel,u32 fifo_addr,u32 fifo_size)5019 void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
5020 {
5021 u8 *buffer = NULL;
5022 u32 buff_size = 0;
5023 static const char * const fifo_sel_str[] = {
5024 "TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
5025 };
5026
5027 if (fifo_sel > 5) {
5028 RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
5029 return;
5030 }
5031
5032 RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
5033 RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
5034
5035 if (fifo_size) {
5036 buff_size = RND4(fifo_size);
5037 buffer = rtw_zvmalloc(buff_size);
5038 if (buffer == NULL)
5039 buff_size = 0;
5040 }
5041
5042 rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
5043
5044 if (buffer) {
5045 RTW_DUMP_SEL(sel, buffer, fifo_size);
5046 rtw_vmfree(buffer, buff_size);
5047 }
5048
5049 RTW_PRINT_SEL(sel, "==========================\n");
5050 }
5051 #endif
5052
5053 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)5054 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
5055 {
5056 RTW_INFO("%s: Set 0x690=0x00\n", __func__);
5057 rtw_write8(adapter, REG_WOW_CTRL,
5058 (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
5059 RTW_PRINT("%s: Release RXDMA\n", __func__);
5060 rtw_write32(adapter, REG_RXPKT_NUM,
5061 (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
5062 }
5063 #if defined(CONFIG_RTL8188E)
rtw_hal_disable_tx_report(_adapter * adapter)5064 static void rtw_hal_disable_tx_report(_adapter *adapter)
5065 {
5066 rtw_write8(adapter, REG_TX_RPT_CTRL,
5067 ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
5068 RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5069 }
5070
rtw_hal_enable_tx_report(_adapter * adapter)5071 static void rtw_hal_enable_tx_report(_adapter *adapter)
5072 {
5073 rtw_write8(adapter, REG_TX_RPT_CTRL,
5074 ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
5075 RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5076 }
5077 #endif
rtw_hal_release_rx_dma(_adapter * adapter)5078 static void rtw_hal_release_rx_dma(_adapter *adapter)
5079 {
5080 u32 val32 = 0;
5081
5082 val32 = rtw_read32(adapter, REG_RXPKT_NUM);
5083
5084 rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
5085
5086 RTW_INFO("%s, [0x%04x]: 0x%08x\n",
5087 __func__, REG_RXPKT_NUM, (u32)(val32 & (~RW_RELEASE_EN)));
5088 }
5089
rtw_hal_pause_rx_dma(_adapter * adapter)5090 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
5091 {
5092 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
5093 u8 ret = 0;
5094 s8 trycnt = 100;
5095 u32 tmp = 0;
5096 int res = 0;
5097 /* RX DMA stop */
5098 RTW_PRINT("Pause DMA\n");
5099 rtw_write32(adapter, REG_RXPKT_NUM,
5100 (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
5101 do {
5102 if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
5103 #ifdef CONFIG_USB_HCI
5104 /* stop interface before leave */
5105 if (_TRUE == hal->usb_intf_start) {
5106 rtw_intf_stop(adapter);
5107 RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
5108 RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
5109 }
5110 #endif /* CONFIG_USB_HCI */
5111
5112 RTW_PRINT("RX_DMA_IDLE is true\n");
5113 ret = _SUCCESS;
5114 break;
5115 }
5116 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5117 else {
5118 res = RecvOnePkt(adapter);
5119 RTW_PRINT("RecvOnePkt Result: %d\n", res);
5120 }
5121 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
5122
5123 #ifdef CONFIG_USB_HCI
5124 else {
5125 /* to avoid interface start repeatedly */
5126 if (_FALSE == hal->usb_intf_start)
5127 rtw_intf_start(adapter);
5128 }
5129 #endif /* CONFIG_USB_HCI */
5130 } while (trycnt--);
5131
5132 if (trycnt < 0) {
5133 tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
5134
5135 RTW_PRINT("Stop RX DMA failed......\n");
5136 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
5137 RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
5138 __func__, rtw_read16(adapter, REG_RXPKTNUM));
5139 #else
5140 RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
5141 __func__, ((tmp & 0xFF00) >> 8));
5142 #endif
5143 if (tmp & BIT(3))
5144 RTW_PRINT("%s, RX DMA has req\n",
5145 __func__);
5146 else
5147 RTW_PRINT("%s, RX DMA no req\n",
5148 __func__);
5149 ret = _FAIL;
5150 }
5151
5152 return ret;
5153 }
5154
5155 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5156 #ifndef RTW_HALMAC
rtw_hal_enable_cpwm2(_adapter * adapter)5157 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
5158 {
5159 u8 ret = 0;
5160 int res = 0;
5161 u32 tmp = 0;
5162 #ifdef CONFIG_GPIO_WAKEUP
5163 return _SUCCESS;
5164 #else
5165 RTW_PRINT("%s\n", __func__);
5166
5167 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5168 if (!res)
5169 RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
5170 else
5171 RTW_INFO("sdio_local_read fail\n");
5172
5173 tmp = SDIO_HIMR_CPWM2_MSK;
5174
5175 res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5176
5177 if (!res) {
5178 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5179 RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
5180 ret = _SUCCESS;
5181 } else {
5182 RTW_INFO("sdio_local_write fail\n");
5183 ret = _FAIL;
5184 }
5185 return ret;
5186 #endif /* CONFIG_CPIO_WAKEUP */
5187 }
5188 #endif
5189 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
5190 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
5191
5192 #ifdef CONFIG_WOWLAN
5193 /*
5194 * rtw_hal_check_wow_ctrl
5195 * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
5196 * If 0x1C7 == 0 (for 3081), WOW enable successful.
5197 * _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
5198 * If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
5199 */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)5200 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
5201 {
5202 u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
5203 u8 mstatus = 0;
5204 u8 reason = 0xFF;
5205 u8 trycnt = 25;
5206 u8 res = _FALSE;
5207
5208 if (IS_HARDWARE_TYPE_JAGUAR2(adapter) || IS_HARDWARE_TYPE_JAGUAR3(adapter)) {
5209 if (chk_type) {
5210 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5211 RTW_INFO("%s reason:0x%02x\n", __func__, reason);
5212
5213 while (reason && trycnt > 1) {
5214 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5215 RTW_PRINT("Loop index: %d :0x%02x\n",
5216 trycnt, reason);
5217 trycnt--;
5218 rtw_msleep_os(20);
5219 }
5220 if (!reason)
5221 res = _TRUE;
5222 else
5223 res = _FALSE;
5224 } else {
5225 /* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
5226 fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
5227 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
5228 RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
5229
5230 while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
5231 rtw_msleep_os(20);
5232 fe1_imr = rtw_read32(adapter, REG_FE1IMR);
5233 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
5234 RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
5235 trycnt, fe1_imr, rxpkt_num);
5236 trycnt--;
5237 }
5238
5239 if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
5240 res = _FALSE;
5241 else
5242 res = _TRUE;
5243 }
5244 } else {
5245 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5246 RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
5247
5248
5249 if (chk_type) {
5250 while (!(mstatus & BIT1) && trycnt > 1) {
5251 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5252 RTW_PRINT("Loop index: %d :0x%02x\n",
5253 trycnt, mstatus);
5254 trycnt--;
5255 rtw_msleep_os(20);
5256 }
5257 if (mstatus & BIT1)
5258 res = _TRUE;
5259 else
5260 res = _FALSE;
5261 } else {
5262 while (mstatus & BIT1 && trycnt > 1) {
5263 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5264 RTW_PRINT("Loop index: %d :0x%02x\n",
5265 trycnt, mstatus);
5266 trycnt--;
5267 rtw_msleep_os(20);
5268 }
5269
5270 if (mstatus & BIT1)
5271 res = _FALSE;
5272 else
5273 res = _TRUE;
5274 }
5275 }
5276
5277 RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
5278 __func__, chk_type, res, (25 - trycnt));
5279 return res;
5280 }
5281
5282 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_check_pno_enabled(_adapter * adapter)5283 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
5284 {
5285 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5286 u8 res = 0, count = 0;
5287 u8 ret = _FALSE;
5288
5289 if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
5290 res = rtw_read8(adapter, REG_PNO_STATUS);
5291 while (!(res & BIT(7)) && count < 25) {
5292 RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
5293 count, res);
5294 res = rtw_read8(adapter, REG_PNO_STATUS);
5295 count++;
5296 rtw_msleep_os(2);
5297 }
5298 if (res & BIT(7))
5299 ret = _TRUE;
5300 else
5301 ret = _FALSE;
5302 RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
5303 }
5304 return ret;
5305 }
5306 #endif
5307
rtw_hal_backup_rate(_adapter * adapter)5308 static void rtw_hal_backup_rate(_adapter *adapter)
5309 {
5310 RTW_INFO("%s\n", __func__);
5311 /* backup data rate to register 0x8b for wowlan FW */
5312 rtw_write8(adapter, 0x8d, 1);
5313 rtw_write8(adapter, 0x8c, 0);
5314 rtw_write8(adapter, 0x8f, 0x40);
5315 rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
5316 }
5317
5318 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)5319 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
5320 {
5321 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5322 int cam_id, index = 0;
5323 u8 *addr = NULL;
5324
5325 if (!MLME_IS_STA(adapter))
5326 return;
5327
5328 addr = get_bssid(pmlmepriv);
5329
5330 if (addr == NULL) {
5331 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
5332 return;
5333 }
5334
5335 rtw_clean_dk_section(adapter);
5336
5337 do {
5338 cam_id = rtw_camid_search(adapter, addr, index, 1);
5339
5340 if (cam_id == -1)
5341 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
5342 else
5343 rtw_sec_cam_swap(adapter, cam_id, index);
5344
5345 index++;
5346 } while (index < 4);
5347
5348 rtw_write8(adapter, REG_SECCFG, 0xcc);
5349 }
5350
rtw_hal_update_gtk_offload_info(_adapter * adapter)5351 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
5352 {
5353 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5354 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5355 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5356 struct security_priv *psecuritypriv = &adapter->securitypriv;
5357 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5358 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
5359 _irqL irqL;
5360 u8 get_key[16];
5361 u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;
5362 u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
5363
5364 if (!MLME_IS_STA(adapter))
5365 return;
5366
5367 _rtw_memset(get_key, 0, sizeof(get_key));
5368 _rtw_memcpy(&replay_count,
5369 paoac_rpt->replay_counter_eapol_key, 8);
5370
5371 /*read gtk key index*/
5372 gtk_id = paoac_rpt->key_index;
5373 aoac_rpt_ver = paoac_rpt->version_info;
5374
5375 if (aoac_rpt_ver == 0) {
5376 /* initial verison */
5377 if (gtk_id == 5)
5378 has_rekey = _FALSE;
5379 else
5380 has_rekey = _TRUE;
5381 } else if (aoac_rpt_ver >= 1) {
5382 /* Add krack patch */
5383 if (gtk_id == 5)
5384 RTW_WARN("%s FW check iv fail\n", __func__);
5385
5386 if (aoac_rpt_ver == 1)
5387 RTW_WARN("%s aoac report version should be update to v2\n", __func__);
5388
5389 /* Fix key id mismatch */
5390 if (aoac_rpt_ver == 2)
5391 has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;
5392 }
5393
5394 if (has_rekey == _FALSE) {
5395 RTW_INFO("%s no rekey event happened.\n", __func__);
5396 } else if (has_rekey == _TRUE) {
5397 RTW_INFO("%s update security key.\n", __func__);
5398 /*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
5399 rtw_sec_read_cam_ent(adapter, gtk_id,
5400 NULL, NULL, get_key);
5401 rtw_clean_hw_dk_cam(adapter);
5402
5403 if (_rtw_camid_is_gk(adapter, gtk_id)) {
5404 _enter_critical_bh(&cam_ctl->lock, &irqL);
5405 _rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
5406 get_key, 16);
5407 _exit_critical_bh(&cam_ctl->lock, &irqL);
5408 } else {
5409 struct setkey_parm parm_gtk;
5410
5411 parm_gtk.algorithm = paoac_rpt->security_type;
5412 parm_gtk.keyid = gtk_id;
5413 _rtw_memcpy(parm_gtk.key, get_key, 16);
5414 setkey_hdl(adapter, (u8 *)&parm_gtk);
5415 }
5416
5417 /*update key into related sw variable and sec-cam cache*/
5418 psecuritypriv->dot118021XGrpKeyid = gtk_id;
5419 _rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
5420 get_key, 16);
5421 /* update SW TKIP TX/RX MIC value */
5422 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
5423 offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
5424 _rtw_memcpy(
5425 &psecuritypriv->dot118021XGrptxmickey[gtk_id],
5426 &(paoac_rpt->group_key[offset]),
5427 RTW_TKIP_MIC_LEN);
5428
5429 offset = RTW_KEK_LEN;
5430 _rtw_memcpy(
5431 &psecuritypriv->dot118021XGrprxmickey[gtk_id],
5432 &(paoac_rpt->group_key[offset]),
5433 RTW_TKIP_MIC_LEN);
5434 }
5435 RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
5436 KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
5437 }
5438
5439 /* Update broadcast RX IV */
5440 if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
5441 sz = sizeof(psecuritypriv->iv_seq[0]);
5442 for (i = 0 ; i < 4 ; i++) {
5443 _rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
5444 tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
5445 pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
5446 _rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
5447 }
5448 }
5449
5450 rtw_clean_dk_section(adapter);
5451
5452 rtw_write8(adapter, REG_SECCFG, 0x0c);
5453
5454 #ifdef CONFIG_GTK_OL_DBG
5455 /* if (gtk_keyindex != 5) */
5456 dump_sec_cam(RTW_DBGDUMP, adapter);
5457 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
5458 #endif
5459 }
5460 #endif /*CONFIG_GTK_OL*/
5461
rtw_dump_aoac_rpt(_adapter * adapter)5462 static void rtw_dump_aoac_rpt(_adapter *adapter)
5463 {
5464 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5465 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5466 int i = 0;
5467
5468 RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
5469 RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
5470 paoac_rpt->replay_counter_eapol_key, 8);
5471 RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
5472 RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
5473 RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
5474 RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
5475 paoac_rpt->wow_pattern_idx);
5476 RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
5477 RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);
5478 RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
5479 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
5480 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
5481 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
5482 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
5483 }
5484
rtw_hal_get_aoac_rpt(_adapter * adapter)5485 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
5486 {
5487 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5488 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5489 u32 page_offset = 0, page_number = 0;
5490 u32 page_size = 0, buf_size = 0;
5491 u8 *buffer = NULL;
5492 u8 i = 0, tmp = 0;
5493 int ret = -1;
5494
5495 /* read aoac report from rsvd page */
5496 page_offset = pwrctl->wowlan_aoac_rpt_loc;
5497 page_number = 1;
5498
5499 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5500 buf_size = page_size * page_number;
5501
5502 buffer = rtw_zvmalloc(buf_size);
5503
5504 if (buffer == NULL) {
5505 RTW_ERR("%s buffer allocate failed size(%d)\n",
5506 __func__, buf_size);
5507 return;
5508 }
5509
5510 RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
5511
5512 ret = rtw_hal_get_rsvd_page(adapter, page_offset,
5513 page_number, buffer, buf_size);
5514
5515 if (ret == _FALSE) {
5516 RTW_ERR("%s get aoac report failed\n", __func__);
5517 rtw_warn_on(1);
5518 goto _exit;
5519 }
5520
5521 _rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
5522 _rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
5523
5524 for (i = 0 ; i < 4 ; i++) {
5525 tmp = paoac_rpt->replay_counter_eapol_key[i];
5526 paoac_rpt->replay_counter_eapol_key[i] =
5527 paoac_rpt->replay_counter_eapol_key[7 - i];
5528 paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
5529 }
5530
5531 rtw_dump_aoac_rpt(adapter);
5532
5533 _exit:
5534 if (buffer)
5535 rtw_vmfree(buffer, buf_size);
5536 }
5537
rtw_hal_update_tx_iv(_adapter * adapter)5538 static void rtw_hal_update_tx_iv(_adapter *adapter)
5539 {
5540 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5541 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5542 struct sta_info *psta;
5543 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
5544 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5545 struct security_priv *psecpriv = &adapter->securitypriv;
5546
5547 u16 val16 = 0;
5548 u32 val32 = 0;
5549 u64 txiv = 0;
5550 u8 *pval = NULL;
5551
5552 psta = rtw_get_stainfo(&adapter->stapriv,
5553 get_my_bssid(&pmlmeinfo->network));
5554
5555 /* Update TX iv data. */
5556 pval = (u8 *)&paoac_rpt->iv;
5557
5558 if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
5559 val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
5560 ((u16)(paoac_rpt->iv[0]) << 8);
5561 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5562 ((u32)(paoac_rpt->iv[5]) << 8) +
5563 ((u32)(paoac_rpt->iv[6]) << 16) +
5564 ((u32)(paoac_rpt->iv[7]) << 24);
5565 } else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
5566 val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
5567 ((u16)(paoac_rpt->iv[1]) << 8);
5568 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5569 ((u32)(paoac_rpt->iv[5]) << 8) +
5570 ((u32)(paoac_rpt->iv[6]) << 16) +
5571 ((u32)(paoac_rpt->iv[7]) << 24);
5572 }
5573
5574 if (psta) {
5575 txiv = val16 + ((u64)val32 << 16);
5576 if (txiv != 0)
5577 psta->dot11txpn.val = txiv;
5578 }
5579 }
5580
rtw_hal_update_sw_security_info(_adapter * adapter)5581 static void rtw_hal_update_sw_security_info(_adapter *adapter)
5582 {
5583 struct security_priv *psecpriv = &adapter->securitypriv;
5584 u8 sz = sizeof (psecpriv->iv_seq);
5585
5586 rtw_hal_update_tx_iv(adapter);
5587 #ifdef CONFIG_GTK_OL
5588 if (psecpriv->binstallKCK_KEK == _TRUE &&
5589 (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5590 rtw_hal_update_gtk_offload_info(adapter);
5591 #else
5592 _rtw_memset(psecpriv->iv_seq, 0, sz);
5593 #endif
5594 }
5595 #ifdef CONFIG_CUSTOM_PULSE
rtw_hal_set_gpio_custom_cmd(_adapter * adapter,u8 enable)5596 static u8 rtw_hal_set_gpio_custom_cmd(_adapter *adapter, u8 enable)
5597 {
5598 u8 H2CGpioCustomParm[H2C_GPIO_CUSTOM_LEN] = {0};
5599 u8 customid = 0x2, special_wakeup_reason = RX_MAGIC_PKT, custom_for_wakeup_reason=0x1;
5600 u8 ret = _FAIL;
5601
5602 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5603
5604 if(enable) {
5605 SET_H2CCMD_CUSTOMERID(H2CGpioCustomParm, customid);
5606 SET_H2CCMD_SPECIAL_WAKE_REASON(H2CGpioCustomParm, special_wakeup_reason);
5607 SET_H2CCMD_CUSTOM_WAKE_REASON(H2CGpioCustomParm, custom_for_wakeup_reason);
5608
5609 ret = rtw_hal_fill_h2c_cmd(adapter,
5610 H2C_GPIO_CUSTOM,
5611 H2C_GPIO_CUSTOM_LEN,
5612 H2CGpioCustomParm);
5613 RTW_DBG("%s(): H2C_cmd=%x, cmd=%02x, %02x, %02x\n", __func__, H2C_GPIO_CUSTOM,
5614 H2CGpioCustomParm[0], H2CGpioCustomParm[1], H2CGpioCustomParm[2]);
5615 }
5616
5617 return ret;
5618 }
5619 #endif /* CONFIG_CUSTOM_PULSE */
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)5620 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
5621 {
5622 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
5623 u8 adopt = 1, check_period = 5;
5624 u8 ret = _FAIL;
5625 u8 hw_port = rtw_hal_get_port(adapter);
5626
5627 SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
5628 SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
5629 SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
5630 SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
5631 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5632 SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);
5633 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5634 #else
5635 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5636 #endif
5637 ret = rtw_hal_fill_h2c_cmd(adapter,
5638 H2C_KEEP_ALIVE,
5639 H2C_KEEP_ALIVE_CTRL_LEN,
5640 u1H2CKeepAliveParm);
5641
5642 return ret;
5643 }
5644
5645 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter,u8 enable)5646 static u8 rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter, u8 enable)
5647 {
5648 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5649 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_PATTERN_LEN] = {0};
5650 u8 ret = _FAIL;
5651 int i;
5652
5653 /* If keep alive pattern is set, FW will use pattern for keep alive action */
5654 if(enable == 0 || (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_disable)) {
5655 SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _FALSE);
5656 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE);
5657 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5658 return ret;
5659 }
5660 /*step1:set keep alive period*/
5661 SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_LOW_BIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_period & 0x00FF);
5662 SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_HI_BIT(u1H2CKeepAliveParm, ((pwrctl->wowlan_keep_alive_period & 0xFF00)>> 8));
5663
5664 if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_tx) {
5665 SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5666 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE);
5667 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5668 SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5669 goto exit;
5670 }
5671 if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx) {
5672 SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5673 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE);
5674 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5675 SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5676 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index);
5677 SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval);
5678 SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter);
5679 goto exit;
5680 }
5681 if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx_with_ack) {
5682 SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5683 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE);
5684 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _TRUE);
5685 SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5686 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index);
5687 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_wake_pattern_index);
5688 SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval);
5689 SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter);
5690 goto exit;
5691 }
5692 exit:
5693 for(i=0; i<H2C_KEEP_ALIVE_PATTERN_LEN; i++) {
5694 RTW_INFO("u1H2CKeepAliveParm[%d]= x%0x\n", i, u1H2CKeepAliveParm[i]);
5695 }
5696 ret = rtw_hal_fill_h2c_cmd(adapter,
5697 H2C_UDP_KEEPALIVE,
5698 H2C_KEEP_ALIVE_PATTERN_LEN,
5699 u1H2CKeepAliveParm);
5700
5701 return ret;
5702 }
5703 #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
5704
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)5705 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
5706 {
5707 u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
5708 u8 adopt = 1, check_period = 100, trypkt_num = 5;
5709 u8 ret = _FAIL;
5710 struct registry_priv *pregistry = &adapter->registrypriv;
5711 u8 hw_port = rtw_hal_get_port(adapter);
5712
5713 SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
5714 SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
5715 if (!(pregistry->wakeup_event & BIT(2)))
5716 SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt);
5717 SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
5718 SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
5719 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5720 SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);
5721 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5722 #else
5723 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5724 #endif
5725
5726 ret = rtw_hal_fill_h2c_cmd(adapter,
5727 H2C_DISCON_DECISION,
5728 H2C_DISCON_DECISION_LEN,
5729 u1H2CDisconDecisionParm);
5730 return ret;
5731 }
5732
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)5733 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
5734 {
5735 struct registry_priv *registry_par = &adapter->registrypriv;
5736 struct security_priv *psecpriv = &adapter->securitypriv;
5737 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5738 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5739
5740 u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
5741 u8 discont_wake = 0, gpionum = 0, gpio_dur = 0, no_wake = 0;
5742 u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
5743 u8 sdio_wakeup_enable = 1;
5744 u8 gpio_high_active = 0;
5745 u8 magic_pkt = 0;
5746 u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
5747 u8 ret = _FAIL;
5748 #ifdef CONFIG_DIS_UPHY
5749 u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;
5750 #endif /* CONFIG_DIS_UPHY */
5751
5752 #ifdef CONFIG_GPIO_WAKEUP
5753 gpio_high_active = ppwrpriv->is_high_active;
5754 gpionum = ppwrpriv->wowlan_gpio_index;
5755 sdio_wakeup_enable = 0;
5756 #endif /* CONFIG_GPIO_WAKEUP */
5757
5758 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
5759 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5760 no_wake = 1;
5761
5762 if (!ppwrpriv->wowlan_pno_enable &&
5763 registry_par->wakeup_event & BIT(0) && !no_wake)
5764 magic_pkt = enable;
5765
5766 if ((registry_par->wakeup_event & BIT(1)) &&
5767 (psecpriv->dot11PrivacyAlgrthm == _WEP40_ ||
5768 psecpriv->dot11PrivacyAlgrthm == _WEP104_) && !no_wake)
5769 hw_unicast = 1;
5770
5771 if (registry_par->wakeup_event & BIT(2) && !no_wake)
5772 discont_wake = enable;
5773
5774 RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
5775 enable, change_unit);
5776
5777 /* time = (gpio_dur/2) * gpio_unit, default:256 ms */
5778 if (enable && change_unit) {
5779 gpio_dur = 0x40;
5780 gpio_unit = 1;
5781 gpio_pulse_en = 1;
5782 }
5783
5784 #ifdef CONFIG_PLATFORM_ARM_RK3188
5785 if (enable) {
5786 gpio_pulse_en = 1;
5787 gpio_pulse_cnt = 0x04;
5788 }
5789 #endif
5790
5791 SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
5792 if(!no_wake)
5793 SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
5794 SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
5795 SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
5796 SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
5797 SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
5798
5799 #ifdef CONFIG_GTK_OL
5800 if (psecpriv->binstallKCK_KEK == _TRUE &&
5801 (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5802 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
5803 else
5804 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
5805 #else
5806 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
5807 #endif
5808 SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
5809 SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
5810 SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
5811
5812 SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
5813 SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
5814
5815 SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
5816 SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
5817
5818 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
5819 if (enable)
5820 SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5821 #endif
5822
5823 #ifdef CONFIG_DIS_UPHY
5824 if (enable) {
5825 dis_uphy = 1;
5826 /* time unit: 0 -> ms, 1 -> 256 ms*/
5827 dis_uphy_unit = 1;
5828 dis_uphy_time = 0x4;
5829 }
5830
5831 SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
5832 SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
5833 SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
5834 if (ppwrpriv->hst2dev_high_active == 1)
5835 SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
5836 #ifdef CONFIG_RTW_ONE_PIN_GPIO
5837 SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5838 SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
5839 SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
5840 #else
5841 SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
5842 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
5843 #endif /* CONFIG_DIS_UPHY */
5844
5845
5846 ret = rtw_hal_fill_h2c_cmd(adapter,
5847 H2C_WOWLAN,
5848 H2C_WOWLAN_LEN,
5849 u1H2CWoWlanCtrlParm);
5850 return ret;
5851 }
5852
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)5853 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
5854 {
5855 struct security_priv *psecuritypriv = &(adapter->securitypriv);
5856 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5857 struct registry_priv *pregistrypriv = &adapter->registrypriv;
5858 u8 arp_en = pregistrypriv->wakeup_event & BIT(3);
5859 u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
5860 u8 ret = _FAIL, count = 0, no_wake = 0;
5861 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5862
5863 RTW_INFO("%s(): enable=%d\n", __func__, enable);
5864
5865 if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&
5866 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5867 no_wake = 1;
5868 if(no_wake) {
5869 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5870 u1H2CRemoteWakeCtrlParm, enable);
5871 } else {
5872 if (!ppwrpriv->wowlan_pno_enable) {
5873 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5874 u1H2CRemoteWakeCtrlParm, enable);
5875 if (arp_en)
5876 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5877 u1H2CRemoteWakeCtrlParm, 1);
5878 else
5879 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5880 u1H2CRemoteWakeCtrlParm, 0);
5881 #ifdef CONFIG_GTK_OL
5882 if (psecuritypriv->binstallKCK_KEK == _TRUE &&
5883 (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) {
5884 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5885 u1H2CRemoteWakeCtrlParm, 1);
5886 } else {
5887 RTW_INFO("no kck kek\n");
5888 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5889 u1H2CRemoteWakeCtrlParm, 0);
5890 }
5891 #endif /* CONFIG_GTK_OL */
5892
5893 #ifdef CONFIG_IPV6
5894 if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
5895 RTW_INFO("enable NS offload\n");
5896 SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
5897 u1H2CRemoteWakeCtrlParm, enable);
5898 }
5899
5900 /*
5901 * filter NetBios name service pkt to avoid being waked-up
5902 * by this kind of unicast pkt this exceptional modification
5903 * is used for match competitor's behavior
5904 */
5905
5906 SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
5907 u1H2CRemoteWakeCtrlParm, enable);
5908 #endif /*CONFIG_IPV6*/
5909 #if 0 /* replaced by WOWLAN pattern match */
5910 #ifdef CONFIG_RTL8192F
5911 if (IS_HARDWARE_TYPE_8192F(adapter)){
5912 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
5913 u1H2CRemoteWakeCtrlParm, enable);
5914 }
5915 #endif /* CONFIG_RTL8192F */
5916 #endif
5917 if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
5918 (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
5919 (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
5920 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5921 u1H2CRemoteWakeCtrlParm, 0);
5922 } else { /* WEP etc. */
5923 if (arp_en)
5924 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5925 u1H2CRemoteWakeCtrlParm, 1);
5926 }
5927
5928 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
5929 #ifdef CONFIG_GTK_OL
5930 if(_rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))
5931 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5932 u1H2CRemoteWakeCtrlParm, enable);
5933 #endif /* CONFIG_GTK_OL */
5934 if (IS_HARDWARE_TYPE_8188E(adapter) ||
5935 IS_HARDWARE_TYPE_8812(adapter)) {
5936 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5937 u1H2CRemoteWakeCtrlParm, 0);
5938 if (arp_en)
5939 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5940 u1H2CRemoteWakeCtrlParm, 1);
5941 }
5942 }
5943
5944 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
5945 u1H2CRemoteWakeCtrlParm, 1);
5946 }
5947 #ifdef CONFIG_PNO_SUPPORT
5948 else {
5949 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5950 u1H2CRemoteWakeCtrlParm, enable);
5951 SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
5952 u1H2CRemoteWakeCtrlParm, enable);
5953 }
5954 #endif
5955
5956 #ifdef CONFIG_P2P_WOWLAN
5957 if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
5958 RTW_INFO("P2P OFFLOAD ENABLE\n");
5959 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
5960 } else {
5961 RTW_INFO("P2P OFFLOAD DISABLE\n");
5962 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
5963 }
5964 #endif /* CONFIG_P2P_WOWLAN */
5965 }
5966
5967
5968 ret = rtw_hal_fill_h2c_cmd(adapter,
5969 H2C_REMOTE_WAKE_CTRL,
5970 H2C_REMOTE_WAKE_CTRL_LEN,
5971 u1H2CRemoteWakeCtrlParm);
5972 return ret;
5973 }
5974
5975 #ifdef CONFIG_WAR_OFFLOAD
rtw_hal_set_war_offload_ctrl_cmd(_adapter * adapter,u8 enable)5976 static u8 rtw_hal_set_war_offload_ctrl_cmd(_adapter *adapter, u8 enable)
5977 {
5978 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5979 u8 u1H2CWarOffloadParm[H2C_WAR_OFFLOAD_LEN] = {0};
5980 u8 ret = _FAIL;
5981
5982 RTW_INFO("%s(): enable=%d\n", __func__, enable);
5983
5984 if (_TRUE == ppwrpriv->wowlan_war_offload_mode) {
5985 SET_H2CCMD_WAR_CFG_EN(u1H2CWarOffloadParm, enable);
5986 SET_H2CCMD_WAR_CFG_ARP_RSP_EN(u1H2CWarOffloadParm, 1);
5987
5988 #ifdef CONFIG_OFFLOAD_MDNS_V4
5989 if (WAR_MDNS_V4_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
5990 SET_H2CCMD_WAR_CFG_MDNSV4_RSP_EN(u1H2CWarOffloadParm, 1);
5991 }
5992 if (WAR_MDNS_V4_WAKEUP_EN& ppwrpriv->wowlan_war_offload_ctrl) {
5993 SET_H2CCMD_WAR_CFG_MDNSV4_WAKE_EN(u1H2CWarOffloadParm, 1);
5994 }
5995 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
5996
5997 #ifdef CONFIG_OFFLOAD_MDNS_V6
5998 if (WAR_MDNS_V6_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
5999 SET_H2CCMD_WAR_CFG_MDNSV6_RSP_EN(u1H2CWarOffloadParm, 1);
6000 }
6001 if (WAR_MDNS_V6_WAKEUP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
6002 SET_H2CCMD_WAR_CFG_MDNSV6_WAKE_EN(u1H2CWarOffloadParm, 1);
6003 }
6004 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
6005
6006 }
6007
6008 ret = rtw_hal_fill_h2c_cmd(adapter,
6009 H2C_WAR_OFFLOAD,
6010 H2C_WAR_OFFLOAD_LEN,
6011 u1H2CWarOffloadParm);
6012 return ret;
6013 }
6014
rtw_hal_set_war_offload_parm(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)6015 static u8 rtw_hal_set_war_offload_parm(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
6016 {
6017 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6018 u8 u1H2CWarOfldParm[H2C_WAROFLD_RSVDPAGE1_LEN] = {0};
6019 u8 ret = _FAIL;
6020
6021 SET_H2CCMD_WAROFLD_RSVDPAGE1_LOC_PARM(u1H2CWarOfldParm, rsvdpageloc->LocIpParm);
6022 RTW_INFO("%s(): LocIpParm = %d\n", __func__, rsvdpageloc->LocIpParm);
6023
6024
6025 ret = rtw_hal_fill_h2c_cmd(adapter,
6026 H2C_WAROFLD_RSVDPAGE1,
6027 H2C_WAROFLD_RSVDPAGE1_LEN,
6028 u1H2CWarOfldParm);
6029
6030 return ret;
6031 }
6032 #endif /* CONFIG_WAR_OFFLOAD */
6033
6034
6035
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)6036 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
6037 {
6038 u8 ret = _FAIL;
6039 u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
6040
6041 RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
6042 __func__, group_alg, pairwise_alg);
6043 SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
6044 pairwise_alg);
6045 SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
6046 group_alg);
6047
6048 ret = rtw_hal_fill_h2c_cmd(adapter,
6049 H2C_AOAC_GLOBAL_INFO,
6050 H2C_AOAC_GLOBAL_INFO_LEN,
6051 u1H2CAOACGlobalInfoParm);
6052
6053 return ret;
6054 }
6055
6056 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)6057 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
6058 PRSVDPAGE_LOC rsvdpageloc, u8 enable)
6059 {
6060 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6061 u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
6062 u8 res = 0, count = 0, ret = _FAIL;
6063
6064 RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
6065 __func__, rsvdpageloc->LocProbePacket,
6066 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
6067
6068 SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
6069 SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
6070 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
6071 rsvdpageloc->LocScanInfo);
6072 SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
6073 rsvdpageloc->LocProbePacket);
6074 /*
6075 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
6076 rsvdpageloc->LocSSIDInfo);
6077 */
6078 ret = rtw_hal_fill_h2c_cmd(adapter,
6079 H2C_D0_SCAN_OFFLOAD_INFO,
6080 H2C_SCAN_OFFLOAD_CTRL_LEN,
6081 u1H2CScanOffloadInfoParm);
6082 return ret;
6083 }
6084 #endif /* CONFIG_PNO_SUPPORT */
6085
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)6086 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
6087 {
6088 struct security_priv *psecpriv = &padapter->securitypriv;
6089 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
6090 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6091 struct registry_priv *pregistry = &padapter->registrypriv;
6092 u8 pkt_type = 0, no_wake = 0;
6093
6094 if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&
6095 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
6096 no_wake = 1;
6097
6098 RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
6099
6100 rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
6101
6102 if (enable) {
6103 if(!no_wake)
6104 rtw_hal_set_global_info_cmd(padapter,
6105 psecpriv->dot118021XGrpPrivacy,
6106 psecpriv->dot11PrivacyAlgrthm);
6107
6108 if (!(ppwrpriv->wowlan_pno_enable)) {
6109 if (!no_wake)
6110 rtw_hal_set_disconnect_decision_cmd(padapter,
6111 enable);
6112 #ifdef CONFIG_ARP_KEEP_ALIVE
6113 if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
6114 (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
6115 pkt_type = 0;
6116 else
6117 pkt_type = 1;
6118 #else
6119 pkt_type = 0;
6120 #endif /* CONFIG_ARP_KEEP_ALIVE */
6121 if(!no_wake) {
6122 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
6123 rtw_hal_set_keep_alive_pattern_cmd(padapter,enable);
6124 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
6125 rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
6126 }
6127 }
6128 #ifdef CONFIG_PNO_SUPPORT
6129 rtw_hal_check_pno_enabled(padapter);
6130 #endif /* CONFIG_PNO_SUPPORT */
6131 #ifdef CONFIG_WAR_OFFLOAD
6132 rtw_hal_set_war_offload_ctrl_cmd(padapter, enable);
6133 #endif /* CONFIG_WAR_OFFLOAD */
6134
6135 } else {
6136 #if 0
6137 {
6138 u32 PageSize = 0;
6139 rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
6140 dump_TX_FIFO(padapter, 4, PageSize);
6141 }
6142 #endif
6143 }
6144 #ifdef CONFIG_CUSTOM_PULSE
6145 rtw_hal_set_gpio_custom_cmd(padapter, enable);
6146 #endif /* CONFIG_CUSTOM_PULSE */
6147 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
6148 RTW_PRINT("-%s()-\n", __func__);
6149 }
6150 #endif /* CONFIG_WOWLAN */
6151
6152 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)6153 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
6154 {
6155 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6156
6157 u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
6158 u8 gpionum = 0, gpio_dur = 0;
6159 u8 gpio_pulse = enable;
6160 u8 sdio_wakeup_enable = 1;
6161 u8 gpio_high_active = 0;
6162 u8 ret = _FAIL;
6163
6164 #ifdef CONFIG_GPIO_WAKEUP
6165 gpio_high_active = ppwrpriv->is_high_active;
6166 gpionum = ppwrpriv->wowlan_gpio_index;
6167 sdio_wakeup_enable = 0;
6168 #endif /*CONFIG_GPIO_WAKEUP*/
6169
6170 RTW_INFO("%s(): enable=%d\n", __func__, enable);
6171
6172 SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
6173 gpionum);
6174 SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
6175 gpio_pulse);
6176 SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
6177 gpio_high_active);
6178 SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
6179 enable);
6180 SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
6181 gpio_dur);
6182
6183 ret = rtw_hal_fill_h2c_cmd(adapter,
6184 H2C_AP_WOW_GPIO_CTRL,
6185 H2C_AP_WOW_GPIO_CTRL_LEN,
6186 u1H2CAPWoWlanCtrlParm);
6187
6188 return ret;
6189 }
6190
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)6191 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6192 {
6193 u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
6194 u8 ret = _FAIL;
6195
6196 RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
6197
6198 SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
6199
6200 ret = rtw_hal_fill_h2c_cmd(adapter,
6201 H2C_AP_OFFLOAD,
6202 H2C_AP_OFFLOAD_LEN,
6203 u1H2CAPOffloadCtrlParm);
6204
6205 return ret;
6206 }
6207
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)6208 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
6209 {
6210 u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
6211 u8 ret = _FAIL;
6212
6213 RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
6214
6215 SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
6216 #ifndef CONFIG_USB_HCI
6217 SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
6218 #endif /*CONFIG_USB_HCI*/
6219 SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
6220
6221 if (enable)
6222 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
6223 else
6224 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
6225
6226 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
6227 H2C_AP_PS_LEN, ap_ps_parm);
6228
6229 return ret;
6230 }
6231
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)6232 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
6233 PRSVDPAGE_LOC rsvdpageloc)
6234 {
6235 struct hal_ops *pHalFunc = &padapter->hal_func;
6236 u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
6237 u8 ret = _FAIL, header = 0;
6238
6239 if (pHalFunc->fill_h2c_cmd == NULL) {
6240 RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
6241 return;
6242 }
6243
6244 header = rtw_read8(padapter, REG_BCNQ_BDNY);
6245
6246 RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
6247 rsvdpageloc->LocApOffloadBCN,
6248 rsvdpageloc->LocProbeRsp,
6249 header);
6250
6251 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
6252 rsvdpageloc->LocApOffloadBCN + header);
6253
6254 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
6255 H2C_BCN_RSVDPAGE_LEN, rsvdparm);
6256
6257 if (ret == _FAIL)
6258 RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
6259
6260 rtw_msleep_os(10);
6261
6262 _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
6263
6264 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
6265 rsvdpageloc->LocProbeRsp + header);
6266
6267 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
6268 H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
6269
6270 if (ret == _FAIL)
6271 RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
6272
6273 rtw_msleep_os(10);
6274 }
6275
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)6276 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
6277 {
6278 rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
6279 rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
6280 rtw_hal_set_ap_ps_cmd(padapter, enable);
6281 }
6282
rtw_hal_ap_wow_enable(_adapter * padapter)6283 static void rtw_hal_ap_wow_enable(_adapter *padapter)
6284 {
6285 struct security_priv *psecuritypriv = &padapter->securitypriv;
6286 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6287 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6288 struct sta_info *psta = NULL;
6289 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6290 #ifdef DBG_CHECK_FW_PS_STATE
6291 struct dvobj_priv *psdpriv = padapter->dvobj;
6292 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6293 #endif /*DBG_CHECK_FW_PS_STATE*/
6294 int res;
6295 u16 media_status_rpt;
6296 #ifdef CONFIG_GPIO_WAKEUP
6297 u8 val8 = 0;
6298 #endif
6299
6300 RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
6301 #ifdef DBG_CHECK_FW_PS_STATE
6302 if (rtw_fw_ps_state(padapter) == _FAIL) {
6303 pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
6304 RTW_PRINT("wowlan enable no leave 32k\n");
6305 }
6306 #endif /*DBG_CHECK_FW_PS_STATE*/
6307
6308 /* 1. Download WOWLAN FW*/
6309 rtw_hal_fw_dl(padapter, _TRUE);
6310
6311 media_status_rpt = RT_MEDIA_CONNECT;
6312 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6313 (u8 *)&media_status_rpt);
6314
6315 issue_beacon(padapter, 0);
6316
6317 rtw_msleep_os(2);
6318 #if defined(CONFIG_RTL8188E)
6319 if (IS_HARDWARE_TYPE_8188E(padapter))
6320 rtw_hal_disable_tx_report(padapter);
6321 #endif
6322 /* RX DMA stop */
6323 res = rtw_hal_pause_rx_dma(padapter);
6324 if (res == _FAIL)
6325 RTW_PRINT("[WARNING] pause RX DMA fail\n");
6326
6327 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6328 /* Enable CPWM2 only. */
6329 res = rtw_hal_enable_cpwm2(padapter);
6330 if (res == _FAIL)
6331 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6332 #endif
6333
6334 #ifdef CONFIG_GPIO_WAKEUP
6335 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6336 rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6337 rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6338 #else
6339 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6340 if (pwrctrlpriv->is_high_active == 0)
6341 rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6342 else
6343 rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index,
6344 GPIO_OUTPUT_LOW);
6345 #else
6346 val8 = (pwrpriv->is_high_active == 0) ? 1 : 0;
6347 rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8);
6348 rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6349 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow suspend and %s_ACTIVE.\n",
6350 __func__, pwrpriv->wowlan_gpio_index,
6351 pwrpriv->wowlan_gpio_output_state ? "HIGH" : "LOW",
6352 pwrpriv->is_high_active ? "HIGI" : "LOW");
6353 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
6354 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6355 #endif /* CONFIG_GPIO_WAKEUP */
6356
6357 /* 5. Set Enable WOWLAN H2C command. */
6358 RTW_PRINT("Set Enable AP WOWLan cmd\n");
6359 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
6360
6361 rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
6362 #ifdef CONFIG_USB_HCI
6363 rtw_mi_intf_stop(padapter);
6364 #endif
6365 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
6366 /* Invoid SE0 reset signal during suspending*/
6367 rtw_write8(padapter, REG_RSV_CTRL, 0x20);
6368 if (IS_8188F(pHalData->version_id) == FALSE
6369 && IS_8188GTV(pHalData->version_id) == FALSE)
6370 rtw_write8(padapter, REG_RSV_CTRL, 0x60);
6371 #endif
6372 }
6373
rtw_hal_ap_wow_disable(_adapter * padapter)6374 static void rtw_hal_ap_wow_disable(_adapter *padapter)
6375 {
6376 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6377 #ifdef DBG_CHECK_FW_PS_STATE
6378 struct dvobj_priv *psdpriv = padapter->dvobj;
6379 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6380 #endif /*DBG_CHECK_FW_PS_STATE*/
6381 u16 media_status_rpt;
6382
6383 RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
6384 /* 1. Read wakeup reason*/
6385 pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
6386
6387 RTW_PRINT("wakeup_reason: 0x%02x\n",
6388 pwrctl->wowlan_wake_reason);
6389
6390 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
6391
6392 rtw_msleep_os(2);
6393 #ifdef DBG_CHECK_FW_PS_STATE
6394 if (rtw_fw_ps_state(padapter) == _FAIL) {
6395 pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
6396 RTW_PRINT("wowlan enable no leave 32k\n");
6397 }
6398 #endif /*DBG_CHECK_FW_PS_STATE*/
6399
6400 #if defined(CONFIG_RTL8188E)
6401 if (IS_HARDWARE_TYPE_8188E(padapter))
6402 rtw_hal_enable_tx_report(padapter);
6403 #endif
6404
6405 rtw_hal_force_enable_rxdma(padapter);
6406
6407 rtw_hal_fw_dl(padapter, _FALSE);
6408
6409 #ifdef CONFIG_GPIO_WAKEUP
6410 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6411 rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6412 #else
6413 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6414 if (pwrctl->is_high_active == 0)
6415 rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6416 else
6417 rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index
6418 , GPIO_OUTPUT_LOW);
6419 #else
6420 rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index,
6421 pwrctl->wowlan_gpio_output_state);
6422 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow resume and %s_ACTIVE.\n",
6423 __func__, pwrctl->wowlan_gpio_index,
6424 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
6425 pwrctl->is_high_active ? "HIGI" : "LOW");
6426 #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
6427 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6428 #endif /* CONFIG_GPIO_WAKEUP */
6429 media_status_rpt = RT_MEDIA_CONNECT;
6430
6431 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6432 (u8 *)&media_status_rpt);
6433
6434 issue_beacon(padapter, 0);
6435 }
6436 #endif /*CONFIG_AP_WOWLAN*/
6437
6438 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)6439 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
6440 {
6441 u8 *ssid_ie;
6442 sint ssid_len_ori;
6443 int len_diff = 0;
6444
6445 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
6446
6447 /* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
6448
6449 if (ssid_ie && ssid_len_ori > 0) {
6450 switch (hidden_ssid_mode) {
6451 case 1: {
6452 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
6453 u32 remain_len = 0;
6454
6455 remain_len = ies_len - (next_ie - ies);
6456
6457 ssid_ie[1] = 0;
6458 _rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
6459 len_diff -= ssid_len_ori;
6460
6461 break;
6462 }
6463 case 2:
6464 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
6465 break;
6466 default:
6467 break;
6468 }
6469 }
6470
6471 return len_diff;
6472 }
6473
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)6474 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
6475 {
6476 /* struct xmit_frame *pmgntframe; */
6477 /* struct pkt_attrib *pattrib; */
6478 /* unsigned char *pframe; */
6479 struct rtw_ieee80211_hdr *pwlanhdr;
6480 unsigned short *fctrl;
6481 unsigned int rate_len;
6482 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6483 u32 pktlen;
6484 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6485 /* _irqL irqL;
6486 * struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6487 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6488 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6489 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6490 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6491 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
6492 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6493 #ifdef CONFIG_P2P
6494 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6495 #endif /* CONFIG_P2P */
6496
6497 /* for debug */
6498 u8 *dbgbuf = pframe;
6499 u8 dbgbufLen = 0, index = 0;
6500
6501 RTW_INFO("%s\n", __FUNCTION__);
6502 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6503 /* _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6504 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6505
6506 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6507
6508
6509 fctrl = &(pwlanhdr->frame_ctl);
6510 *(fctrl) = 0;
6511
6512 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6513 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6514 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6515
6516 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6517 /* pmlmeext->mgnt_seq++; */
6518 set_frame_sub_type(pframe, WIFI_BEACON);
6519
6520 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6521 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6522
6523 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6524 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6525 #ifdef CONFIG_P2P
6526 /* for P2P : Primary Device Type & Device Name */
6527 u32 wpsielen = 0, insert_len = 0;
6528 u8 *wpsie = NULL;
6529 wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
6530
6531 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
6532 uint wps_offset, remainder_ielen;
6533 u8 *premainder_ie, *pframe_wscie;
6534
6535 wps_offset = (uint)(wpsie - cur_network->IEs);
6536
6537 premainder_ie = wpsie + wpsielen;
6538
6539 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6540
6541 #ifdef CONFIG_IOCTL_CFG80211
6542 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6543 if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
6544 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
6545 pframe += wps_offset;
6546 pktlen += wps_offset;
6547
6548 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6549 pframe += pmlmepriv->wps_beacon_ie_len;
6550 pktlen += pmlmepriv->wps_beacon_ie_len;
6551
6552 /* copy remainder_ie to pframe */
6553 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6554 pframe += remainder_ielen;
6555 pktlen += remainder_ielen;
6556 } else {
6557 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6558 pframe += cur_network->IELength;
6559 pktlen += cur_network->IELength;
6560 }
6561 } else
6562 #endif /* CONFIG_IOCTL_CFG80211 */
6563 {
6564 pframe_wscie = pframe + wps_offset;
6565 _rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
6566 pframe += (wps_offset + wpsielen);
6567 pktlen += (wps_offset + wpsielen);
6568
6569 /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6570 /* Primary Device Type */
6571 /* Type: */
6572 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6573 insert_len += 2;
6574
6575 /* Length: */
6576 *(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
6577 insert_len += 2;
6578
6579 /* Value: */
6580 /* Category ID */
6581 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6582 insert_len += 2;
6583
6584 /* OUI */
6585 *(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
6586 insert_len += 4;
6587
6588 /* Sub Category ID */
6589 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6590 insert_len += 2;
6591
6592
6593 /* Device Name */
6594 /* Type: */
6595 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6596 insert_len += 2;
6597
6598 /* Length: */
6599 *(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
6600 insert_len += 2;
6601
6602 /* Value: */
6603 _rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
6604 insert_len += pwdinfo->device_name_len;
6605
6606
6607 /* update wsc ie length */
6608 *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
6609
6610 /* pframe move to end */
6611 pframe += insert_len;
6612 pktlen += insert_len;
6613
6614 /* copy remainder_ie to pframe */
6615 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6616 pframe += remainder_ielen;
6617 pktlen += remainder_ielen;
6618 }
6619 } else
6620 #endif /* CONFIG_P2P */
6621 {
6622 int len_diff;
6623 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6624 len_diff = update_hidden_ssid(
6625 pframe + _BEACON_IE_OFFSET_
6626 , cur_network->IELength - _BEACON_IE_OFFSET_
6627 , pmlmeinfo->hidden_ssid_mode
6628 );
6629 pframe += (cur_network->IELength + len_diff);
6630 pktlen += (cur_network->IELength + len_diff);
6631 }
6632 #if 0
6633 {
6634 u8 *wps_ie;
6635 uint wps_ielen;
6636 u8 sr = 0;
6637 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
6638 pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
6639 if (wps_ie && wps_ielen > 0)
6640 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6641 if (sr != 0)
6642 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6643 else
6644 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6645 }
6646 #endif
6647 #ifdef CONFIG_P2P
6648 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6649 u32 len;
6650 #ifdef CONFIG_IOCTL_CFG80211
6651 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6652 len = pmlmepriv->p2p_beacon_ie_len;
6653 if (pmlmepriv->p2p_beacon_ie && len > 0)
6654 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6655 } else
6656 #endif /* CONFIG_IOCTL_CFG80211 */
6657 {
6658 len = build_beacon_p2p_ie(pwdinfo, pframe);
6659 }
6660
6661 pframe += len;
6662 pktlen += len;
6663
6664 #ifdef CONFIG_WFD
6665 len = rtw_append_beacon_wfd_ie(padapter, pframe);
6666 pframe += len;
6667 pktlen += len;
6668 #endif
6669
6670 }
6671 #endif /* CONFIG_P2P */
6672
6673 goto _issue_bcn;
6674
6675 }
6676
6677 /* below for ad-hoc mode */
6678
6679 /* timestamp will be inserted by hardware */
6680 pframe += 8;
6681 pktlen += 8;
6682
6683 /* beacon interval: 2 bytes */
6684
6685 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6686
6687 pframe += 2;
6688 pktlen += 2;
6689
6690 /* capability info: 2 bytes */
6691
6692 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6693
6694 pframe += 2;
6695 pktlen += 2;
6696
6697 /* SSID */
6698 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6699
6700 /* supported rates... */
6701 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6702 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6703
6704 /* DS parameter set */
6705 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6706
6707 /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6708 {
6709 u8 erpinfo = 0;
6710 u32 ATIMWindow;
6711 /* IBSS Parameter Set... */
6712 /* ATIMWindow = cur->Configuration.ATIMWindow; */
6713 ATIMWindow = 0;
6714 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6715
6716 /* ERP IE */
6717 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
6718 }
6719
6720
6721 /* EXTERNDED SUPPORTED RATE */
6722 if (rate_len > 8)
6723 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6724
6725
6726 /* todo:HT for adhoc */
6727
6728 _issue_bcn:
6729
6730 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6731 /* pmlmepriv->update_bcn = _FALSE;
6732 *
6733 * _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6734 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6735
6736 *pLength = pktlen;
6737 #if 0
6738 /* printf dbg msg */
6739 dbgbufLen = pktlen;
6740 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6741
6742 for (index = 0; index < dbgbufLen; index++)
6743 printk("%x ", *(dbgbuf + index));
6744
6745 printk("\n");
6746 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6747
6748 #endif
6749 }
6750
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6751 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6752 {
6753 /* struct xmit_frame *pmgntframe; */
6754 /* struct pkt_attrib *pattrib; */
6755 /* unsigned char *pframe; */
6756 struct rtw_ieee80211_hdr *pwlanhdr;
6757 unsigned short *fctrl;
6758 unsigned char *mac;
6759 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6760 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6761 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6762 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6763 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
6764 u16 beacon_interval = 100;
6765 u16 capInfo = 0;
6766 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6767 u8 wpsie[255] = { 0x00 };
6768 u32 wpsielen = 0, p2pielen = 0;
6769 u32 pktlen;
6770 #ifdef CONFIG_WFD
6771 u32 wfdielen = 0;
6772 #endif
6773
6774 /* for debug */
6775 u8 *dbgbuf = pframe;
6776 u8 dbgbufLen = 0, index = 0;
6777
6778 RTW_INFO("%s\n", __FUNCTION__);
6779 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6780
6781 mac = adapter_mac_addr(padapter);
6782
6783 fctrl = &(pwlanhdr->frame_ctl);
6784 *(fctrl) = 0;
6785
6786 /* DA filled by FW */
6787 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6788 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6789
6790 /* Use the device address for BSSID field. */
6791 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6792
6793 SetSeqNum(pwlanhdr, 0);
6794 set_frame_sub_type(fctrl, WIFI_PROBERSP);
6795
6796 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6797 pframe += pktlen;
6798
6799
6800 /* timestamp will be inserted by hardware */
6801 pframe += 8;
6802 pktlen += 8;
6803
6804 /* beacon interval: 2 bytes */
6805 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6806 pframe += 2;
6807 pktlen += 2;
6808
6809 /* capability info: 2 bytes */
6810 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6811 capInfo |= cap_ShortPremble;
6812 capInfo |= cap_ShortSlot;
6813
6814 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6815 pframe += 2;
6816 pktlen += 2;
6817
6818
6819 /* SSID */
6820 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
6821
6822 /* supported rates... */
6823 /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6824 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
6825
6826 /* DS parameter set */
6827 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
6828
6829 #ifdef CONFIG_IOCTL_CFG80211
6830 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6831 if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6832 /* WPS IE */
6833 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6834 pktlen += pmlmepriv->wps_probe_resp_ie_len;
6835 pframe += pmlmepriv->wps_probe_resp_ie_len;
6836
6837 /* P2P IE */
6838 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6839 pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6840 pframe += pmlmepriv->p2p_probe_resp_ie_len;
6841 }
6842 } else
6843 #endif /* CONFIG_IOCTL_CFG80211 */
6844 {
6845
6846 /* Todo: WPS IE */
6847 /* Noted by Albert 20100907 */
6848 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6849
6850 wpsielen = 0;
6851 /* WPS OUI */
6852 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6853 wpsielen += 4;
6854
6855 /* WPS version */
6856 /* Type: */
6857 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6858 wpsielen += 2;
6859
6860 /* Length: */
6861 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6862 wpsielen += 2;
6863
6864 /* Value: */
6865 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
6866
6867 /* WiFi Simple Config State */
6868 /* Type: */
6869 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6870 wpsielen += 2;
6871
6872 /* Length: */
6873 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6874 wpsielen += 2;
6875
6876 /* Value: */
6877 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
6878
6879 /* Response Type */
6880 /* Type: */
6881 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6882 wpsielen += 2;
6883
6884 /* Length: */
6885 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6886 wpsielen += 2;
6887
6888 /* Value: */
6889 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6890
6891 /* UUID-E */
6892 /* Type: */
6893 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6894 wpsielen += 2;
6895
6896 /* Length: */
6897 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6898 wpsielen += 2;
6899
6900 /* Value: */
6901 if (pwdinfo->external_uuid == 0) {
6902 _rtw_memset(wpsie + wpsielen, 0x0, 16);
6903 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6904 } else
6905 _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6906 wpsielen += 0x10;
6907
6908 /* Manufacturer */
6909 /* Type: */
6910 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6911 wpsielen += 2;
6912
6913 /* Length: */
6914 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6915 wpsielen += 2;
6916
6917 /* Value: */
6918 _rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6919 wpsielen += 7;
6920
6921 /* Model Name */
6922 /* Type: */
6923 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
6924 wpsielen += 2;
6925
6926 /* Length: */
6927 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
6928 wpsielen += 2;
6929
6930 /* Value: */
6931 _rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
6932 wpsielen += 6;
6933
6934 /* Model Number */
6935 /* Type: */
6936 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
6937 wpsielen += 2;
6938
6939 /* Length: */
6940 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6941 wpsielen += 2;
6942
6943 /* Value: */
6944 wpsie[wpsielen++] = 0x31; /* character 1 */
6945
6946 /* Serial Number */
6947 /* Type: */
6948 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
6949 wpsielen += 2;
6950
6951 /* Length: */
6952 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
6953 wpsielen += 2;
6954
6955 /* Value: */
6956 _rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
6957 wpsielen += ETH_ALEN;
6958
6959 /* Primary Device Type */
6960 /* Type: */
6961 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6962 wpsielen += 2;
6963
6964 /* Length: */
6965 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6966 wpsielen += 2;
6967
6968 /* Value: */
6969 /* Category ID */
6970 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6971 wpsielen += 2;
6972
6973 /* OUI */
6974 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6975 wpsielen += 4;
6976
6977 /* Sub Category ID */
6978 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6979 wpsielen += 2;
6980
6981 /* Device Name */
6982 /* Type: */
6983 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6984 wpsielen += 2;
6985
6986 /* Length: */
6987 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
6988 wpsielen += 2;
6989
6990 /* Value: */
6991 _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
6992 wpsielen += pwdinfo->device_name_len;
6993
6994 /* Config Method */
6995 /* Type: */
6996 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
6997 wpsielen += 2;
6998
6999 /* Length: */
7000 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7001 wpsielen += 2;
7002
7003 /* Value: */
7004 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7005 wpsielen += 2;
7006
7007
7008 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7009
7010
7011 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
7012 pframe += p2pielen;
7013 pktlen += p2pielen;
7014 }
7015
7016 #ifdef CONFIG_WFD
7017 wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
7018 pframe += wfdielen;
7019 pktlen += wfdielen;
7020 #endif
7021
7022 *pLength = pktlen;
7023
7024 #if 0
7025 /* printf dbg msg */
7026 dbgbufLen = pktlen;
7027 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7028
7029 for (index = 0; index < dbgbufLen; index++)
7030 printk("%x ", *(dbgbuf + index));
7031
7032 printk("\n");
7033 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7034 #endif
7035 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7036 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7037 {
7038 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7039 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7040 u8 action = P2P_PUB_ACTION_ACTION;
7041 u32 p2poui = cpu_to_be32(P2POUI);
7042 u8 oui_subtype = P2P_GO_NEGO_RESP;
7043 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
7044 u8 p2pielen = 0, i;
7045 uint wpsielen = 0;
7046 u16 wps_devicepassword_id = 0x0000;
7047 uint wps_devicepassword_id_len = 0;
7048 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
7049 u16 len_channellist_attr = 0;
7050 u32 pktlen;
7051 u8 dialogToken = 0;
7052
7053 /* struct xmit_frame *pmgntframe; */
7054 /* struct pkt_attrib *pattrib; */
7055 /* unsigned char *pframe; */
7056 struct rtw_ieee80211_hdr *pwlanhdr;
7057 unsigned short *fctrl;
7058 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7059 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7060 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7061 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7062 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
7063
7064 #ifdef CONFIG_WFD
7065 u32 wfdielen = 0;
7066 #endif
7067
7068 /* for debug */
7069 u8 *dbgbuf = pframe;
7070 u8 dbgbufLen = 0, index = 0;
7071
7072 RTW_INFO("%s\n", __FUNCTION__);
7073 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7074
7075 fctrl = &(pwlanhdr->frame_ctl);
7076 *(fctrl) = 0;
7077
7078 /* RA, filled by FW */
7079 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7080 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7081 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7082
7083 SetSeqNum(pwlanhdr, 0);
7084 set_frame_sub_type(pframe, WIFI_ACTION);
7085
7086 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7087 pframe += pktlen;
7088
7089 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7090 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7091 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7092 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7093
7094 /* dialog token, filled by FW */
7095 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7096
7097 _rtw_memset(wpsie, 0x00, 255);
7098 wpsielen = 0;
7099
7100 /* WPS Section */
7101 wpsielen = 0;
7102 /* WPS OUI */
7103 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
7104 wpsielen += 4;
7105
7106 /* WPS version */
7107 /* Type: */
7108 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7109 wpsielen += 2;
7110
7111 /* Length: */
7112 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7113 wpsielen += 2;
7114
7115 /* Value: */
7116 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7117
7118 /* Device Password ID */
7119 /* Type: */
7120 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
7121 wpsielen += 2;
7122
7123 /* Length: */
7124 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7125 wpsielen += 2;
7126
7127 /* Value: */
7128 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
7129 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
7130 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
7131 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
7132 else
7133 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
7134 wpsielen += 2;
7135
7136 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7137
7138
7139 /* P2P IE Section. */
7140
7141 /* P2P OUI */
7142 p2pielen = 0;
7143 p2pie[p2pielen++] = 0x50;
7144 p2pie[p2pielen++] = 0x6F;
7145 p2pie[p2pielen++] = 0x9A;
7146 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7147
7148 /* Commented by Albert 20100908 */
7149 /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
7150 /* 1. Status */
7151 /* 2. P2P Capability */
7152 /* 3. Group Owner Intent */
7153 /* 4. Configuration Timeout */
7154 /* 5. Operating Channel */
7155 /* 6. Intended P2P Interface Address */
7156 /* 7. Channel List */
7157 /* 8. Device Info */
7158 /* 9. Group ID ( Only GO ) */
7159
7160
7161 /* ToDo: */
7162
7163 /* P2P Status */
7164 /* Type: */
7165 p2pie[p2pielen++] = P2P_ATTR_STATUS;
7166
7167 /* Length: */
7168 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7169 p2pielen += 2;
7170
7171 /* Value, filled by FW */
7172 p2pie[p2pielen++] = 1;
7173
7174 /* P2P Capability */
7175 /* Type: */
7176 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
7177
7178 /* Length: */
7179 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7180 p2pielen += 2;
7181
7182 /* Value: */
7183 /* Device Capability Bitmap, 1 byte */
7184
7185 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
7186 /* Commented by Albert 2011/03/08 */
7187 /* According to the P2P specification */
7188 /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
7189 p2pie[p2pielen++] = 0;
7190 } else {
7191 /* Be group owner or meet the error case */
7192 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
7193 }
7194
7195 /* Group Capability Bitmap, 1 byte */
7196 if (pwdinfo->persistent_supported)
7197 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
7198 else
7199 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
7200
7201 /* Group Owner Intent */
7202 /* Type: */
7203 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
7204
7205 /* Length: */
7206 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7207 p2pielen += 2;
7208
7209 /* Value: */
7210 if (pwdinfo->peer_intent & 0x01) {
7211 /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
7212 p2pie[p2pielen++] = (pwdinfo->intent << 1);
7213 } else {
7214 /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
7215 p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
7216 }
7217
7218
7219 /* Configuration Timeout */
7220 /* Type: */
7221 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7222
7223 /* Length: */
7224 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7225 p2pielen += 2;
7226
7227 /* Value: */
7228 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7229 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7230
7231 /* Operating Channel */
7232 /* Type: */
7233 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7234
7235 /* Length: */
7236 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7237 p2pielen += 2;
7238
7239 /* Value: */
7240 /* Country String */
7241 p2pie[p2pielen++] = 'X';
7242 p2pie[p2pielen++] = 'X';
7243
7244 /* The third byte should be set to 0x04. */
7245 /* Described in the "Operating Channel Attribute" section. */
7246 p2pie[p2pielen++] = 0x04;
7247
7248 /* Operating Class */
7249 if (pwdinfo->operating_channel <= 14) {
7250 /* Operating Class */
7251 p2pie[p2pielen++] = 0x51;
7252 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
7253 /* Operating Class */
7254 p2pie[p2pielen++] = 0x73;
7255 } else {
7256 /* Operating Class */
7257 p2pie[p2pielen++] = 0x7c;
7258 }
7259
7260 /* Channel Number */
7261 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7262
7263 /* Intended P2P Interface Address */
7264 /* Type: */
7265 p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
7266
7267 /* Length: */
7268 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7269 p2pielen += 2;
7270
7271 /* Value: */
7272 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7273 p2pielen += ETH_ALEN;
7274
7275 /* Channel List */
7276 /* Type: */
7277 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7278
7279 /* Country String(3) */
7280 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7281 /* + number of channels in all classes */
7282 len_channellist_attr = 3
7283 + (1 + 1) * (u16)ch_list->reg_classes
7284 + get_reg_classes_full_count(ch_list);
7285
7286 #ifdef CONFIG_CONCURRENT_MODE
7287 if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7288 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7289 else
7290 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7291
7292 #else
7293
7294 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7295
7296 #endif
7297 p2pielen += 2;
7298
7299 /* Value: */
7300 /* Country String */
7301 p2pie[p2pielen++] = 'X';
7302 p2pie[p2pielen++] = 'X';
7303
7304 /* The third byte should be set to 0x04. */
7305 /* Described in the "Operating Channel Attribute" section. */
7306 p2pie[p2pielen++] = 0x04;
7307
7308 /* Channel Entry List */
7309
7310 #ifdef CONFIG_CONCURRENT_MODE
7311 if (rtw_mi_check_status(padapter, MI_LINKED)) {
7312 u8 union_ch = rtw_mi_get_union_chan(padapter);
7313
7314 /* Operating Class */
7315 if (union_ch > 14) {
7316 if (union_ch >= 149)
7317 p2pie[p2pielen++] = 0x7c;
7318 else
7319 p2pie[p2pielen++] = 0x73;
7320 } else
7321 p2pie[p2pielen++] = 0x51;
7322
7323
7324 /* Number of Channels */
7325 /* Just support 1 channel and this channel is AP's channel */
7326 p2pie[p2pielen++] = 1;
7327
7328 /* Channel List */
7329 p2pie[p2pielen++] = union_ch;
7330 } else
7331 #endif /* CONFIG_CONCURRENT_MODE */
7332 {
7333 int i, j;
7334 for (j = 0; j < ch_list->reg_classes; j++) {
7335 /* Operating Class */
7336 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7337
7338 /* Number of Channels */
7339 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7340
7341 /* Channel List */
7342 for (i = 0; i < ch_list->reg_class[j].channels; i++)
7343 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7344 }
7345 }
7346
7347 /* Device Info */
7348 /* Type: */
7349 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
7350
7351 /* Length: */
7352 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
7353 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7354 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
7355 p2pielen += 2;
7356
7357 /* Value: */
7358 /* P2P Device Address */
7359 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7360 p2pielen += ETH_ALEN;
7361
7362 /* Config Method */
7363 /* This field should be big endian. Noted by P2P specification. */
7364
7365 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7366
7367 p2pielen += 2;
7368
7369 /* Primary Device Type */
7370 /* Category ID */
7371 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7372 p2pielen += 2;
7373
7374 /* OUI */
7375 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
7376 p2pielen += 4;
7377
7378 /* Sub Category ID */
7379 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7380 p2pielen += 2;
7381
7382 /* Number of Secondary Device Types */
7383 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
7384
7385 /* Device Name */
7386 /* Type: */
7387 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7388 p2pielen += 2;
7389
7390 /* Length: */
7391 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
7392 p2pielen += 2;
7393
7394 /* Value: */
7395 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
7396 p2pielen += pwdinfo->device_name_len;
7397
7398 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7399 /* Group ID Attribute */
7400 /* Type: */
7401 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
7402
7403 /* Length: */
7404 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
7405 p2pielen += 2;
7406
7407 /* Value: */
7408 /* p2P Device Address */
7409 _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
7410 p2pielen += ETH_ALEN;
7411
7412 /* SSID */
7413 _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
7414 p2pielen += pwdinfo->nego_ssidlen;
7415
7416 }
7417
7418 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7419
7420 #ifdef CONFIG_WFD
7421 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
7422 pframe += wfdielen;
7423 pktlen += wfdielen;
7424 #endif
7425
7426 *pLength = pktlen;
7427 #if 0
7428 /* printf dbg msg */
7429 dbgbufLen = pktlen;
7430 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7431
7432 for (index = 0; index < dbgbufLen; index++)
7433 printk("%x ", *(dbgbuf + index));
7434
7435 printk("\n");
7436 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7437 #endif
7438 }
7439
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7440 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7441 {
7442 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7443 u8 action = P2P_PUB_ACTION_ACTION;
7444 u32 p2poui = cpu_to_be32(P2POUI);
7445 u8 oui_subtype = P2P_INVIT_RESP;
7446 u8 p2pie[255] = { 0x00 };
7447 u8 p2pielen = 0, i;
7448 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
7449 u16 len_channellist_attr = 0;
7450 u32 pktlen;
7451 u8 dialogToken = 0;
7452 #ifdef CONFIG_WFD
7453 u32 wfdielen = 0;
7454 #endif
7455
7456 /* struct xmit_frame *pmgntframe; */
7457 /* struct pkt_attrib *pattrib; */
7458 /* unsigned char *pframe; */
7459 struct rtw_ieee80211_hdr *pwlanhdr;
7460 unsigned short *fctrl;
7461 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7462 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7463 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7464 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7465
7466 /* for debug */
7467 u8 *dbgbuf = pframe;
7468 u8 dbgbufLen = 0, index = 0;
7469
7470
7471 RTW_INFO("%s\n", __FUNCTION__);
7472 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7473
7474 fctrl = &(pwlanhdr->frame_ctl);
7475 *(fctrl) = 0;
7476
7477 /* RA fill by FW */
7478 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7479 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7480
7481 /* BSSID fill by FW */
7482 _rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
7483
7484 SetSeqNum(pwlanhdr, 0);
7485 set_frame_sub_type(pframe, WIFI_ACTION);
7486
7487 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7488 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7489
7490 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7491 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7492 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7493 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7494
7495 /* dialog token, filled by FW */
7496 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7497
7498 /* P2P IE Section. */
7499
7500 /* P2P OUI */
7501 p2pielen = 0;
7502 p2pie[p2pielen++] = 0x50;
7503 p2pie[p2pielen++] = 0x6F;
7504 p2pie[p2pielen++] = 0x9A;
7505 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7506
7507 /* Commented by Albert 20101005 */
7508 /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
7509 /* 1. Status */
7510 /* 2. Configuration Timeout */
7511 /* 3. Operating Channel ( Only GO ) */
7512 /* 4. P2P Group BSSID ( Only GO ) */
7513 /* 5. Channel List */
7514
7515 /* P2P Status */
7516 /* Type: */
7517 p2pie[p2pielen++] = P2P_ATTR_STATUS;
7518
7519 /* Length: */
7520 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7521 p2pielen += 2;
7522
7523 /* Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
7524 p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7525
7526 /* Configuration Timeout */
7527 /* Type: */
7528 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7529
7530 /* Length: */
7531 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7532 p2pielen += 2;
7533
7534 /* Value: */
7535 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7536 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7537
7538 /* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
7539 #if 0
7540 if (status_code == P2P_STATUS_SUCCESS) {
7541 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7542
7543 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7544 /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
7545 /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
7546 /* First one is operating channel attribute. */
7547 /* Second one is P2P Group BSSID attribute. */
7548
7549 /* Operating Channel */
7550 /* Type: */
7551 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7552
7553 /* Length: */
7554 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7555 p2pielen += 2;
7556
7557 /* Value: */
7558 /* Country String */
7559 p2pie[p2pielen++] = 'X';
7560 p2pie[p2pielen++] = 'X';
7561
7562 /* The third byte should be set to 0x04. */
7563 /* Described in the "Operating Channel Attribute" section. */
7564 p2pie[p2pielen++] = 0x04;
7565
7566 /* Operating Class */
7567 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
7568
7569 /* Channel Number */
7570 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7571
7572
7573 /* P2P Group BSSID */
7574 /* Type: */
7575 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
7576
7577 /* Length: */
7578 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7579 p2pielen += 2;
7580
7581 /* Value: */
7582 /* P2P Device Address for GO */
7583 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7584 p2pielen += ETH_ALEN;
7585
7586 }
7587
7588 /* Channel List */
7589 /* Type: */
7590 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7591
7592 /* Length: */
7593 /* Country String(3) */
7594 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7595 /* + number of channels in all classes */
7596 len_channellist_attr = 3
7597 + (1 + 1) * (u16)ch_list->reg_classes
7598 + get_reg_classes_full_count(ch_list);
7599
7600 #ifdef CONFIG_CONCURRENT_MODE
7601 if (rtw_mi_check_status(padapter, MI_LINKED))
7602 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7603 else
7604 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7605
7606 #else
7607
7608 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7609
7610 #endif
7611 p2pielen += 2;
7612
7613 /* Value: */
7614 /* Country String */
7615 p2pie[p2pielen++] = 'X';
7616 p2pie[p2pielen++] = 'X';
7617
7618 /* The third byte should be set to 0x04. */
7619 /* Described in the "Operating Channel Attribute" section. */
7620 p2pie[p2pielen++] = 0x04;
7621
7622 /* Channel Entry List */
7623 #ifdef CONFIG_CONCURRENT_MODE
7624 if (rtw_mi_check_status(padapter, MI_LINKED)) {
7625 u8 union_ch = rtw_mi_get_union_chan(padapter);
7626
7627 /* Operating Class */
7628 if (union_ch > 14) {
7629 if (union_ch >= 149)
7630 p2pie[p2pielen++] = 0x7c;
7631 else
7632 p2pie[p2pielen++] = 0x73;
7633
7634 } else
7635 p2pie[p2pielen++] = 0x51;
7636
7637
7638 /* Number of Channels */
7639 /* Just support 1 channel and this channel is AP's channel */
7640 p2pie[p2pielen++] = 1;
7641
7642 /* Channel List */
7643 p2pie[p2pielen++] = union_ch;
7644 } else
7645 #endif /* CONFIG_CONCURRENT_MODE */
7646 {
7647 int i, j;
7648 for (j = 0; j < ch_list->reg_classes; j++) {
7649 /* Operating Class */
7650 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7651
7652 /* Number of Channels */
7653 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7654
7655 /* Channel List */
7656 for (i = 0; i < ch_list->reg_class[j].channels; i++)
7657 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7658 }
7659 }
7660 }
7661 #endif
7662
7663 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7664
7665 #ifdef CONFIG_WFD
7666 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
7667 pframe += wfdielen;
7668 pktlen += wfdielen;
7669 #endif
7670
7671 *pLength = pktlen;
7672
7673 #if 0
7674 /* printf dbg msg */
7675 dbgbufLen = pktlen;
7676 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7677
7678 for (index = 0; index < dbgbufLen; index++)
7679 printk("%x ", *(dbgbuf + index));
7680
7681 printk("\n");
7682 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7683 #endif
7684 }
7685
7686
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7687 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7688 {
7689 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7690 u8 action = P2P_PUB_ACTION_ACTION;
7691 u8 dialogToken = 0;
7692 u32 p2poui = cpu_to_be32(P2POUI);
7693 u8 oui_subtype = P2P_PROVISION_DISC_RESP;
7694 u8 wpsie[100] = { 0x00 };
7695 u8 wpsielen = 0;
7696 u32 pktlen;
7697 #ifdef CONFIG_WFD
7698 u32 wfdielen = 0;
7699 #endif
7700
7701 /* struct xmit_frame *pmgntframe; */
7702 /* struct pkt_attrib *pattrib; */
7703 /* unsigned char *pframe; */
7704 struct rtw_ieee80211_hdr *pwlanhdr;
7705 unsigned short *fctrl;
7706 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7707 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7708 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7709 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7710
7711 /* for debug */
7712 u8 *dbgbuf = pframe;
7713 u8 dbgbufLen = 0, index = 0;
7714
7715 RTW_INFO("%s\n", __FUNCTION__);
7716
7717 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7718
7719 fctrl = &(pwlanhdr->frame_ctl);
7720 *(fctrl) = 0;
7721
7722 /* RA filled by FW */
7723 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7724 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7725 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7726
7727 SetSeqNum(pwlanhdr, 0);
7728 set_frame_sub_type(pframe, WIFI_ACTION);
7729
7730 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7731 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7732
7733 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7734 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7735 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7736 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7737 /* dialog token, filled by FW */
7738 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7739
7740 wpsielen = 0;
7741 /* WPS OUI */
7742 /* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
7743 RTW_PUT_BE32(wpsie, WPSOUI);
7744 wpsielen += 4;
7745
7746 #if 0
7747 /* WPS version */
7748 /* Type: */
7749 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7750 wpsielen += 2;
7751
7752 /* Length: */
7753 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7754 wpsielen += 2;
7755
7756 /* Value: */
7757 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7758 #endif
7759
7760 /* Config Method */
7761 /* Type: */
7762 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
7763 RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
7764 wpsielen += 2;
7765
7766 /* Length: */
7767 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
7768 RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
7769 wpsielen += 2;
7770
7771 /* Value: filled by FW, default value is PBC */
7772 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
7773 RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
7774 wpsielen += 2;
7775
7776 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7777
7778 #ifdef CONFIG_WFD
7779 wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
7780 pframe += wfdielen;
7781 pktlen += wfdielen;
7782 #endif
7783
7784 *pLength = pktlen;
7785
7786 /* printf dbg msg */
7787 #if 0
7788 dbgbufLen = pktlen;
7789 RTW_INFO("======> DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7790
7791 for (index = 0; index < dbgbufLen; index++)
7792 printk("%x ", *(dbgbuf + index));
7793
7794 printk("\n");
7795 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7796 #endif
7797 }
7798
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)7799 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
7800 {
7801 u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
7802 struct hal_ops *pHalFunc = &adapter->hal_func;
7803 u8 ret = _FAIL;
7804
7805 RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
7806 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
7807 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
7808 rsvdpageloc->LocPDRsp);
7809
7810 SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
7811 SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
7812 SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
7813 SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
7814 SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
7815
7816 /* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
7817 ret = rtw_hal_fill_h2c_cmd(adapter,
7818 H2C_P2P_OFFLOAD_RSVD_PAGE,
7819 H2C_P2PRSVDPAGE_LOC_LEN,
7820 u1H2CP2PRsvdPageParm);
7821
7822 return ret;
7823 }
7824
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)7825 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
7826 {
7827
7828 u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
7829 struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
7830 struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
7831 struct hal_ops *pHalFunc = &adapter->hal_func;
7832 u8 ret = _FAIL;
7833
7834 _rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
7835 RTW_INFO("%s\n", __func__);
7836 switch (pwdinfo->role) {
7837 case P2P_ROLE_DEVICE:
7838 RTW_INFO("P2P_ROLE_DEVICE\n");
7839 p2p_wowlan_offload->role = 0;
7840 break;
7841 case P2P_ROLE_CLIENT:
7842 RTW_INFO("P2P_ROLE_CLIENT\n");
7843 p2p_wowlan_offload->role = 1;
7844 break;
7845 case P2P_ROLE_GO:
7846 RTW_INFO("P2P_ROLE_GO\n");
7847 p2p_wowlan_offload->role = 2;
7848 break;
7849 default:
7850 RTW_INFO("P2P_ROLE_DISABLE\n");
7851 break;
7852 }
7853 p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
7854 p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
7855 offload_cmd = (u8 *)p2p_wowlan_offload;
7856 RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
7857
7858 ret = rtw_hal_fill_h2c_cmd(adapter,
7859 H2C_P2P_OFFLOAD,
7860 H2C_P2P_OFFLOAD_LEN,
7861 offload_cmd);
7862 return ret;
7863
7864 /* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
7865 }
7866 #endif /* CONFIG_P2P_WOWLAN */
7867
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)7868 void rtw_hal_construct_beacon(_adapter *padapter,
7869 u8 *pframe, u32 *pLength)
7870 {
7871 struct rtw_ieee80211_hdr *pwlanhdr;
7872 u16 *fctrl;
7873 u32 pktlen;
7874 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7875 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7876 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7877 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7878
7879
7880 /* RTW_INFO("%s\n", __FUNCTION__); */
7881
7882 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7883
7884 fctrl = &(pwlanhdr->frame_ctl);
7885 *(fctrl) = 0;
7886
7887 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7888 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7889 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7890
7891 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7892 /* pmlmeext->mgnt_seq++; */
7893 set_frame_sub_type(pframe, WIFI_BEACON);
7894
7895 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7896 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7897
7898 /* timestamp will be inserted by hardware */
7899 pframe += 8;
7900 pktlen += 8;
7901
7902 /* beacon interval: 2 bytes */
7903 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7904
7905 pframe += 2;
7906 pktlen += 2;
7907
7908 #if 0
7909 /* capability info: 2 bytes */
7910 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7911
7912 pframe += 2;
7913 pktlen += 2;
7914
7915 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7916 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7917 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
7918 _rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
7919
7920 goto _ConstructBeacon;
7921 }
7922
7923 /* below for ad-hoc mode */
7924
7925 /* SSID */
7926 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
7927
7928 /* supported rates... */
7929 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7930 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
7931
7932 /* DS parameter set */
7933 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
7934
7935 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
7936 u32 ATIMWindow;
7937 /* IBSS Parameter Set... */
7938 /* ATIMWindow = cur->Configuration.ATIMWindow; */
7939 ATIMWindow = 0;
7940 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
7941 }
7942
7943
7944 /* todo: ERP IE */
7945
7946
7947 /* EXTERNDED SUPPORTED RATE */
7948 if (rate_len > 8)
7949 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
7950
7951 /* todo:HT for adhoc */
7952
7953 _ConstructBeacon:
7954 #endif
7955
7956 if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
7957 RTW_ERR("beacon frame too large ,len(%d,%d)\n",
7958 (pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
7959 rtw_warn_on(1);
7960 return;
7961 }
7962
7963 *pLength = pktlen;
7964
7965 /* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
7966
7967 }
7968
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)7969 static void rtw_hal_construct_PSPoll(_adapter *padapter,
7970 u8 *pframe, u32 *pLength)
7971 {
7972 struct rtw_ieee80211_hdr *pwlanhdr;
7973 u16 *fctrl;
7974 u32 pktlen;
7975 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7976 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7977
7978 /* RTW_INFO("%s\n", __FUNCTION__); */
7979
7980 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7981
7982 /* Frame control. */
7983 fctrl = &(pwlanhdr->frame_ctl);
7984 *(fctrl) = 0;
7985 SetPwrMgt(fctrl);
7986 set_frame_sub_type(pframe, WIFI_PSPOLL);
7987
7988 /* AID. */
7989 set_duration(pframe, (pmlmeinfo->aid | 0xc000));
7990
7991 /* BSSID. */
7992 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7993
7994 /* TA. */
7995 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7996
7997 *pLength = 16;
7998 }
7999
8000
8001 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_construct_fw_dbg_msg_pkt(PADAPTER padapter,u8 * pframe,u32 * plength)8002 void rtw_hal_construct_fw_dbg_msg_pkt(
8003 PADAPTER padapter,
8004 u8 *pframe,
8005 u32 *plength)
8006 {
8007 struct rtw_ieee80211_hdr *pwlanhdr;
8008 u16 *fctrl;
8009 u32 pktlen;
8010 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8011 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8012 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8013 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8014 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8015
8016
8017 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8018
8019 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8020
8021 fctrl = &pwlanhdr->frame_ctl;
8022 *(fctrl) = 0;
8023
8024 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8025 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8026 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8027
8028 SetSeqNum(pwlanhdr, 0);
8029
8030 set_frame_sub_type(pframe, WIFI_DATA);
8031
8032 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8033
8034 *plength = pktlen;
8035 }
8036 #endif /*DBG_FW_DEBUG_MSG_PKT*/
8037
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)8038 void rtw_hal_construct_NullFunctionData(
8039 PADAPTER padapter,
8040 u8 *pframe,
8041 u32 *pLength,
8042 u8 bQoS,
8043 u8 AC,
8044 u8 bEosp,
8045 u8 bForcePowerSave)
8046 {
8047 struct rtw_ieee80211_hdr *pwlanhdr;
8048 u16 *fctrl;
8049 u32 pktlen;
8050 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8051 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8052 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8053 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8054 u8 *sta_addr = NULL;
8055 u8 bssid[ETH_ALEN] = {0};
8056
8057 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8058
8059 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8060
8061 fctrl = &pwlanhdr->frame_ctl;
8062 *(fctrl) = 0;
8063 if (bForcePowerSave)
8064 SetPwrMgt(fctrl);
8065
8066 sta_addr = get_my_bssid(&pmlmeinfo->network);
8067 if (NULL == sta_addr) {
8068 _rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
8069 sta_addr = bssid;
8070 }
8071
8072 switch (cur_network->network.InfrastructureMode) {
8073 case Ndis802_11Infrastructure:
8074 SetToDs(fctrl);
8075 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8076 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8077 _rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);
8078 break;
8079 case Ndis802_11APMode:
8080 SetFrDs(fctrl);
8081 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8082 _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8083 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8084 break;
8085 case Ndis802_11IBSS:
8086 default:
8087 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8088 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8089 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8090 break;
8091 }
8092
8093 SetSeqNum(pwlanhdr, 0);
8094 set_duration(pwlanhdr, 0);
8095
8096 if (bQoS == _TRUE) {
8097 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
8098
8099 set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
8100
8101 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
8102 SetPriority(&pwlanqoshdr->qc, AC);
8103 SetEOSP(&pwlanqoshdr->qc, bEosp);
8104
8105 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8106 } else {
8107 set_frame_sub_type(pframe, WIFI_DATA_NULL);
8108
8109 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8110 }
8111
8112 *pLength = pktlen;
8113 }
8114
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,BOOLEAN bHideSSID)8115 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
8116 BOOLEAN bHideSSID)
8117 {
8118 struct rtw_ieee80211_hdr *pwlanhdr;
8119 u16 *fctrl;
8120 u8 *mac, *bssid, *sta_addr;
8121 u32 pktlen;
8122 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8123 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8124 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
8125
8126 /*RTW_INFO("%s\n", __FUNCTION__);*/
8127
8128 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8129
8130 mac = adapter_mac_addr(padapter);
8131 bssid = cur_network->MacAddress;
8132 sta_addr = get_my_bssid(&pmlmeinfo->network);
8133
8134 fctrl = &(pwlanhdr->frame_ctl);
8135 *(fctrl) = 0;
8136 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8137 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8138 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8139
8140 SetSeqNum(pwlanhdr, 0);
8141 set_frame_sub_type(fctrl, WIFI_PROBERSP);
8142
8143 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8144 pframe += pktlen;
8145
8146 if (cur_network->IELength > MAX_IE_SZ)
8147 return;
8148
8149 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8150 pframe += cur_network->IELength;
8151 pktlen += cur_network->IELength;
8152
8153 *pLength = pktlen;
8154 }
8155
8156 #ifdef CONFIG_WOWLAN
rtw_hal_append_tkip_mic(PADAPTER padapter,u8 * pframe,u32 offset)8157 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
8158 u8 *pframe, u32 offset)
8159 {
8160 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8161 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8162 struct rtw_ieee80211_hdr *pwlanhdr;
8163 struct mic_data micdata;
8164 struct sta_info *psta = NULL;
8165 int res = 0;
8166
8167 u8 *payload = (u8 *)(pframe + offset);
8168
8169 u8 mic[8];
8170 u8 priority[4] = {0x0};
8171 u8 null_key[16] = {0x0};
8172
8173 RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
8174
8175 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8176
8177 psta = rtw_get_stainfo(&padapter->stapriv,
8178 get_my_bssid(&(pmlmeinfo->network)));
8179 if (psta != NULL) {
8180 res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
8181 null_key, 16);
8182 if (res == _TRUE)
8183 RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
8184 rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
8185 }
8186
8187 rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); /* DA */
8188
8189 rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
8190
8191 priority[0] = 0;
8192
8193 rtw_secmicappend(&micdata, &priority[0], 4);
8194
8195 rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
8196
8197 rtw_secgetmic(&micdata, &(mic[0]));
8198
8199 payload += 36;
8200
8201 _rtw_memcpy(payload, &(mic[0]), 8);
8202 }
8203 /*
8204 * Description:
8205 * Construct the ARP response packet to support ARP offload.
8206 * */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8207 static void rtw_hal_construct_ARPRsp(
8208 PADAPTER padapter,
8209 u8 *pframe,
8210 u32 *pLength,
8211 u8 *pIPAddress
8212 )
8213 {
8214 struct rtw_ieee80211_hdr *pwlanhdr;
8215 u16 *fctrl;
8216 u32 pktlen;
8217 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8218 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8219 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8220 struct security_priv *psecuritypriv = &padapter->securitypriv;
8221 static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
8222 u8 *pARPRspPkt = pframe;
8223 /* for TKIP Cal MIC */
8224 u8 *payload = pframe;
8225 u8 EncryptionHeadOverhead = 0, arp_offset = 0;
8226 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8227
8228 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8229
8230 fctrl = &pwlanhdr->frame_ctl;
8231 *(fctrl) = 0;
8232
8233 /* ------------------------------------------------------------------------- */
8234 /* MAC Header. */
8235 /* ------------------------------------------------------------------------- */
8236 SetFrameType(fctrl, WIFI_DATA);
8237 /* set_frame_sub_type(fctrl, 0); */
8238 SetToDs(fctrl);
8239 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8240 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8241 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8242
8243 SetSeqNum(pwlanhdr, 0);
8244 set_duration(pwlanhdr, 0);
8245 /* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
8246 /* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
8247 /* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
8248 /* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
8249 /* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
8250 /* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
8251
8252 /* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
8253 /* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
8254 #ifdef CONFIG_WAPI_SUPPORT
8255 *pLength = sMacHdrLng;
8256 #else
8257 *pLength = 24;
8258 #endif
8259 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8260 case _WEP40_:
8261 case _WEP104_:
8262 EncryptionHeadOverhead = 4;
8263 break;
8264 case _TKIP_:
8265 EncryptionHeadOverhead = 8;
8266 break;
8267 case _AES_:
8268 EncryptionHeadOverhead = 8;
8269 break;
8270 #ifdef CONFIG_WAPI_SUPPORT
8271 case _SMS4_:
8272 EncryptionHeadOverhead = 18;
8273 break;
8274 #endif
8275 default:
8276 EncryptionHeadOverhead = 0;
8277 }
8278
8279 if (EncryptionHeadOverhead > 0) {
8280 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8281 *pLength += EncryptionHeadOverhead;
8282 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8283 SetPrivacy(fctrl);
8284 }
8285
8286 /* ------------------------------------------------------------------------- */
8287 /* Frame Body. */
8288 /* ------------------------------------------------------------------------- */
8289 arp_offset = *pLength;
8290 pARPRspPkt = (u8 *)(pframe + arp_offset);
8291 payload = pARPRspPkt; /* Get Payload pointer */
8292 /* LLC header */
8293 _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
8294 *pLength += 8;
8295
8296 /* ARP element */
8297 pARPRspPkt += 8;
8298 SET_ARP_HTYPE(pARPRspPkt, 1);
8299 SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP); /* IP protocol */
8300 SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);
8301 SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);
8302 SET_ARP_OPER(pARPRspPkt, 2); /* ARP response */
8303 SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
8304 SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
8305 #ifdef CONFIG_ARP_KEEP_ALIVE
8306 if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
8307 SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
8308 SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
8309 } else
8310 #endif
8311 {
8312 SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,
8313 get_my_bssid(&(pmlmeinfo->network)));
8314 SET_ARP_TARGET_IP_ADDR(pARPRspPkt,
8315 pIPAddress);
8316 RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
8317 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
8318 RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
8319 IP_ARG(pIPAddress));
8320 }
8321
8322 *pLength += 28;
8323
8324 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8325 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8326 IS_HARDWARE_TYPE_8812(padapter)) {
8327 rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
8328 }
8329 *pLength += 8;
8330 }
8331 }
8332 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
8333 /*
8334 * Description:
8335 * Construct the Keep Alive packet to support specific Keep Alive packet.
8336 * */
rtw_hal_construct_keepalive(PADAPTER padapter,u8 * pframe,u32 * pLength)8337 static void rtw_hal_construct_keepalive( PADAPTER padapter,
8338 u8 *pframe,
8339 u32 *pLength
8340 ){
8341 struct rtw_ieee80211_hdr *pwlanhdr;
8342 u16 *fctrl;
8343 u32 pktlen;
8344 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8345 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8346 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8347 struct security_priv *psecuritypriv = &padapter->securitypriv;
8348 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
8349 static u8 LLCHeader[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
8350 u8 *pKeepAlivePkt = pframe;
8351 /* for TKIP Cal MIC */
8352 u8 *payload = pframe;
8353 u8 EncryptionHeadOverhead = 0, frame_offset = 0;
8354 int i;
8355
8356 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8357
8358 fctrl = &pwlanhdr->frame_ctl;
8359 *(fctrl) = 0;
8360
8361 RTW_INFO("%s======>\n", __func__);
8362
8363
8364 /* ------------------------------------------------------------------------- */
8365 /* MAC Header. */
8366 /* ------------------------------------------------------------------------- */
8367 SetFrameType(fctrl, WIFI_DATA);
8368 /* set_frame_sub_type(fctrl, 0); */
8369 SetToDs(fctrl);
8370 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8371 _rtw_memcpy(pwlanhdr->addr2, pwrpriv->keep_alive_pattern+6, ETH_ALEN);
8372 _rtw_memcpy(pwlanhdr->addr3,pwrpriv->keep_alive_pattern, ETH_ALEN);
8373
8374 SetSeqNum(pwlanhdr, 0);
8375 set_duration(pwlanhdr, 0);
8376
8377 #ifdef CONFIG_WAPI_SUPPORT
8378 *pLength = sMacHdrLng;
8379 #else
8380 *pLength = 24;
8381 #endif
8382 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8383 case _WEP40_:
8384 case _WEP104_:
8385 EncryptionHeadOverhead = 4;
8386 break;
8387 case _TKIP_:
8388 EncryptionHeadOverhead = 8;
8389 break;
8390 case _AES_:
8391 EncryptionHeadOverhead = 8;
8392 break;
8393 #ifdef CONFIG_WAPI_SUPPORT
8394 case _SMS4_:
8395 EncryptionHeadOverhead = 18;
8396 break;
8397 #endif
8398 default:
8399 EncryptionHeadOverhead = 0;
8400 }
8401
8402 if (EncryptionHeadOverhead > 0) {
8403 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8404 *pLength += EncryptionHeadOverhead;
8405 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8406 SetPrivacy(fctrl);
8407 }
8408
8409 /* ------------------------------------------------------------------------- */
8410 /* Frame Body. */
8411 /* ------------------------------------------------------------------------- */
8412 frame_offset = *pLength;
8413 pKeepAlivePkt = (u8 *)(pframe + frame_offset);
8414 payload = pKeepAlivePkt; /* Get Payload pointer */
8415 /* LLC header */
8416 _rtw_memcpy(pKeepAlivePkt, LLCHeader, 6);
8417 *pLength += 6;
8418
8419 /*From protocol type*/
8420 pKeepAlivePkt+=6;
8421
8422 _rtw_memcpy(pKeepAlivePkt,pwrpriv->keep_alive_pattern+12,pwrpriv->keep_alive_pattern_len-12);
8423
8424 *pLength+=pwrpriv->keep_alive_pattern_len-12;
8425
8426 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8427 *pLength += 8;
8428 }
8429
8430 /* for debug
8431 for (i=0; i< (*pLength) ;i++) {
8432 RTW_INFO("KA_Pkt[0x%x]=x%0x", i,pKeepAlivePkt[i]);
8433 if((i%8) == 7)
8434 RTW_INFO("\n");
8435 }
8436 */
8437
8438 RTW_INFO("%s <======\n", __func__);
8439 }
8440
8441 #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
8442
8443 #ifdef CONFIG_IPV6
8444 /*
8445 * Description: Neighbor Discovery Offload.
8446 */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)8447 static void rtw_hal_construct_na_message(_adapter *padapter,
8448 u8 *pframe, u32 *pLength)
8449 {
8450 struct rtw_ieee80211_hdr *pwlanhdr = NULL;
8451 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8452 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8453 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8454 struct security_priv *psecuritypriv = &padapter->securitypriv;
8455
8456 u32 pktlen = 0;
8457 u16 *fctrl = NULL;
8458
8459 u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8460 u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
8461 u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
8462 u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
8463 u8 val8 = 0;
8464
8465 u8 *p_na_msg = pframe;
8466 /* for TKIP Cal MIC */
8467 u8 *payload = pframe;
8468 u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
8469 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8470
8471 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8472
8473 fctrl = &pwlanhdr->frame_ctl;
8474 *(fctrl) = 0;
8475
8476 /* ------------------------------------------------------------------------- */
8477 /* MAC Header. */
8478 /* ------------------------------------------------------------------------- */
8479 SetFrameType(fctrl, WIFI_DATA);
8480 SetToDs(fctrl);
8481 _rtw_memcpy(pwlanhdr->addr1,
8482 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8483 _rtw_memcpy(pwlanhdr->addr2,
8484 adapter_mac_addr(padapter), ETH_ALEN);
8485 _rtw_memcpy(pwlanhdr->addr3,
8486 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8487
8488 SetSeqNum(pwlanhdr, 0);
8489 set_duration(pwlanhdr, 0);
8490
8491 #ifdef CONFIG_WAPI_SUPPORT
8492 *pLength = sMacHdrLng;
8493 #else
8494 *pLength = 24;
8495 #endif
8496 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8497 case _WEP40_:
8498 case _WEP104_:
8499 EncryptionHeadOverhead = 4;
8500 break;
8501 case _TKIP_:
8502 EncryptionHeadOverhead = 8;
8503 break;
8504 case _AES_:
8505 EncryptionHeadOverhead = 8;
8506 break;
8507 #ifdef CONFIG_WAPI_SUPPORT
8508 case _SMS4_:
8509 EncryptionHeadOverhead = 18;
8510 break;
8511 #endif
8512 default:
8513 EncryptionHeadOverhead = 0;
8514 }
8515
8516 if (EncryptionHeadOverhead > 0) {
8517 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8518 *pLength += EncryptionHeadOverhead;
8519 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8520 SetPrivacy(fctrl);
8521 }
8522
8523 /* ------------------------------------------------------------------------- */
8524 /* Frame Body. */
8525 /* ------------------------------------------------------------------------- */
8526 na_msg_offset = *pLength;
8527 p_na_msg = (u8 *)(pframe + na_msg_offset);
8528 payload = p_na_msg; /* Get Payload pointer */
8529
8530 /* LLC header */
8531 val8 = sizeof(ns_hdr);
8532 _rtw_memcpy(p_na_msg, ns_hdr, val8);
8533 *pLength += val8;
8534 p_na_msg += val8;
8535
8536 /* IPv6 Header */
8537 /* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
8538 val8 = sizeof(ipv6_info);
8539 _rtw_memcpy(p_na_msg, ipv6_info, val8);
8540 *pLength += val8;
8541 p_na_msg += val8;
8542
8543 /* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
8544 val8 = sizeof(ipv6_contx);
8545 _rtw_memcpy(p_na_msg, ipv6_contx, val8);
8546 *pLength += val8;
8547 p_na_msg += val8;
8548
8549 /* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
8550 _rtw_memset(&(p_na_msg[*pLength]), 0, 32);
8551 *pLength += 32;
8552 p_na_msg += 32;
8553
8554 /* ICMPv6 */
8555 /* 1. Type : 0x88 (NA)
8556 * 2. Code : 0x00
8557 * 3. ChechSum : 0x00 0x00 (RSvd)
8558 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
8559 */
8560 val8 = sizeof(icmpv6_hdr);
8561 _rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
8562 *pLength += val8;
8563 p_na_msg += val8;
8564
8565 /* TA: 16 bytes*/
8566 _rtw_memset(&(p_na_msg[*pLength]), 0, 16);
8567 *pLength += 16;
8568 p_na_msg += 16;
8569
8570 /* ICMPv6 Target Link Layer Address */
8571 p_na_msg[0] = 0x02; /* type */
8572 p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
8573 *pLength += 2;
8574 p_na_msg += 2;
8575
8576 _rtw_memset(&(p_na_msg[*pLength]), 0, 6);
8577 *pLength += 6;
8578 p_na_msg += 6;
8579
8580 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8581 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8582 IS_HARDWARE_TYPE_8812(padapter)) {
8583 rtw_hal_append_tkip_mic(padapter, pframe,
8584 na_msg_offset);
8585 }
8586 *pLength += 8;
8587 }
8588 }
8589 /*
8590 * Description: Neighbor Discovery Protocol Information.
8591 */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)8592 static void rtw_hal_construct_ndp_info(_adapter *padapter,
8593 u8 *pframe, u32 *pLength)
8594 {
8595 struct mlme_ext_priv *pmlmeext = NULL;
8596 struct mlme_ext_info *pmlmeinfo = NULL;
8597 struct rtw_ndp_info ndp_info;
8598 u8 *pndp_info = pframe;
8599 u8 len = sizeof(struct rtw_ndp_info);
8600
8601 RTW_INFO("%s: len: %d\n", __func__, len);
8602
8603 pmlmeext = &padapter->mlmeextpriv;
8604 pmlmeinfo = &pmlmeext->mlmext_info;
8605
8606 _rtw_memset(pframe, 0, len);
8607 _rtw_memset(&ndp_info, 0, len);
8608
8609 ndp_info.enable = 1;
8610 ndp_info.check_remote_ip = 0;
8611 ndp_info.num_of_target_ip = 1;
8612
8613 _rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
8614 ETH_ALEN);
8615 _rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
8616 RTW_IPv6_ADDR_LEN);
8617
8618 _rtw_memcpy(pndp_info, &ndp_info, len);
8619 }
8620 #endif /* CONFIG_IPV6 */
8621
8622 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)8623 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
8624 u32 *pLength, pno_ssid_t *ssid)
8625 {
8626 struct rtw_ieee80211_hdr *pwlanhdr;
8627 u16 *fctrl;
8628 u32 pktlen;
8629 unsigned char *mac;
8630 unsigned char bssrate[NumRates];
8631 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8632 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8633 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8634 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8635 int bssrate_len = 0;
8636 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8637
8638 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8639 mac = adapter_mac_addr(padapter);
8640
8641 fctrl = &(pwlanhdr->frame_ctl);
8642 *(fctrl) = 0;
8643
8644 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8645 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8646
8647 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8648
8649 SetSeqNum(pwlanhdr, 0);
8650 set_frame_sub_type(pframe, WIFI_PROBEREQ);
8651
8652 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8653 pframe += pktlen;
8654
8655 if (ssid == NULL)
8656 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
8657 else {
8658 /* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
8659 pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
8660 }
8661
8662 get_rate_set(padapter, bssrate, &bssrate_len);
8663
8664 if (bssrate_len > 8) {
8665 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
8666 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
8667 } else
8668 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
8669
8670 *pLength = pktlen;
8671 }
8672
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)8673 static void rtw_hal_construct_PNO_info(_adapter *padapter,
8674 u8 *pframe, u32 *pLength)
8675 {
8676 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8677 int i;
8678
8679 u8 *pPnoInfoPkt = pframe;
8680 pPnoInfoPkt = (u8 *)(pframe + *pLength);
8681 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
8682
8683 pPnoInfoPkt += 1;
8684 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
8685
8686 pPnoInfoPkt += 3;
8687 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
8688
8689 pPnoInfoPkt += 4;
8690 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
8691
8692 pPnoInfoPkt += 4;
8693 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
8694
8695 pPnoInfoPkt += 4;
8696 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
8697
8698 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8699 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
8700
8701 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8702 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
8703
8704 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8705 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
8706
8707 pPnoInfoPkt += MAX_HIDDEN_AP;
8708
8709 /*
8710 SSID is located at 128th Byte in NLO info Page
8711 */
8712
8713 *pLength += 128;
8714 pPnoInfoPkt = pframe + 128;
8715
8716 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8717 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8718 pwrctl->pnlo_info->ssid_length[i]);
8719 *pLength += WLAN_SSID_MAXLEN;
8720 pPnoInfoPkt += WLAN_SSID_MAXLEN;
8721 }
8722 }
8723
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)8724 static void rtw_hal_construct_ssid_list(_adapter *padapter,
8725 u8 *pframe, u32 *pLength)
8726 {
8727 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8728 u8 *pSSIDListPkt = pframe;
8729 int i;
8730
8731 pSSIDListPkt = (u8 *)(pframe + *pLength);
8732
8733 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8734 _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8735 pwrctl->pnlo_info->ssid_length[i]);
8736
8737 *pLength += WLAN_SSID_MAXLEN;
8738 pSSIDListPkt += WLAN_SSID_MAXLEN;
8739 }
8740 }
8741
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)8742 static void rtw_hal_construct_scan_info(_adapter *padapter,
8743 u8 *pframe, u32 *pLength)
8744 {
8745 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8746 u8 *pScanInfoPkt = pframe;
8747 int i;
8748
8749 pScanInfoPkt = (u8 *)(pframe + *pLength);
8750
8751 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
8752
8753 *pLength += 1;
8754 pScanInfoPkt += 1;
8755 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
8756
8757
8758 *pLength += 1;
8759 pScanInfoPkt += 1;
8760 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
8761
8762
8763 *pLength += 1;
8764 pScanInfoPkt += 1;
8765 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
8766
8767 *pLength += 1;
8768 pScanInfoPkt += 1;
8769 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
8770
8771 *pLength += 1;
8772 pScanInfoPkt += 1;
8773 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
8774
8775 *pLength += 1;
8776 pScanInfoPkt += 1;
8777 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
8778
8779 *pLength += 1;
8780 pScanInfoPkt += 1;
8781 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
8782
8783 *pLength += 1;
8784 pScanInfoPkt += 1;
8785 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
8786
8787 *pLength += 8;
8788 pScanInfoPkt += 8;
8789
8790 for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
8791 _rtw_memcpy(pScanInfoPkt,
8792 &pwrctl->pscan_info->ssid_channel_info[i], 4);
8793 *pLength += 4;
8794 pScanInfoPkt += 4;
8795 }
8796 }
8797 #endif /* CONFIG_PNO_SUPPORT */
8798
8799 #ifdef CONFIG_WAR_OFFLOAD
8800 #ifdef CONFIG_OFFLOAD_MDNS_V4
8801
8802 /*
8803 * Description:
8804 * Construct the MDNS V4 response packet to support MDNS offload.
8805 *
8806 */
rtw_hal_construct_mdns_rsp_v4(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8807 static void rtw_hal_construct_mdns_rsp_v4(
8808 PADAPTER padapter,
8809 u8 *pframe,
8810 u32 *pLength,
8811 u8 *pIPAddress
8812 )
8813 {
8814 struct rtw_ieee80211_hdr *pwlanhdr;
8815 u16 *fctrl;
8816 u32 pktlen;
8817 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8818 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8819 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8820 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8821 struct security_priv *psecuritypriv = &padapter->securitypriv;
8822 static u8 ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00};
8823 u8 mulicast_ipv4_addr[4] = {0xe0, 0x00, 0x00, 0xfb};
8824 u8 mulicast_mac_addr_for_mdns[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb};
8825 u8 *pMdnsRspPkt = pframe;
8826 /* for TKIP Cal MIC */
8827 u8 EncryptionHeadOverhead = 0, mdns_offset = 0;
8828
8829 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
8830 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
8831
8832 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8833
8834 fctrl = &pwlanhdr->frame_ctl;
8835 *(fctrl) = 0;
8836
8837 /* ------------------------------------------------------------------------- */
8838 /* MAC Header. */
8839 /* ------------------------------------------------------------------------- */
8840 SetFrameType(fctrl, WIFI_DATA);
8841 /* set_frame_sub_type(fctrl, 0); */
8842 SetToDs(fctrl);
8843 //_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8844 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8845 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8846 _rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN );
8847
8848 SetSeqNum(pwlanhdr, 0);
8849 set_duration(pwlanhdr, 0);
8850
8851 #ifdef CONFIG_WAPI_SUPPORT
8852 *pLength = sMacHdrLng;
8853 #else
8854 *pLength = 24;
8855 #endif
8856 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8857 case _WEP40_:
8858 case _WEP104_:
8859 EncryptionHeadOverhead = 4;
8860 break;
8861 case _TKIP_:
8862 EncryptionHeadOverhead = 8;
8863 break;
8864 case _AES_:
8865 EncryptionHeadOverhead = 8;
8866 break;
8867 #ifdef CONFIG_WAPI_SUPPORT
8868 case _SMS4_:
8869 EncryptionHeadOverhead = 18;
8870 break;
8871 #endif
8872 default:
8873 EncryptionHeadOverhead = 0;
8874 }
8875
8876 if (EncryptionHeadOverhead > 0) {
8877 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8878 *pLength += EncryptionHeadOverhead;
8879 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8880 SetPrivacy(fctrl);
8881 }
8882
8883 /* ------------------------------------------------------------------------- */
8884 /* Frame Body. */
8885 /* ------------------------------------------------------------------------- */
8886 mdns_offset = *pLength;
8887 pMdnsRspPkt = (u8 *)(pframe + mdns_offset);
8888 /* LLC header */
8889 _rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8);
8890 *pLength += 8;
8891
8892 /* IP element */
8893 pMdnsRspPkt += 8;
8894 SET_IPHDR_VERSION(pMdnsRspPkt, 0x45);
8895 SET_IPHDR_DSCP(pMdnsRspPkt, 0);
8896 SET_IPHDR_TOTAL_LEN(pMdnsRspPkt, 0); // filled by fw
8897 SET_IPHDR_IDENTIFIER(pMdnsRspPkt, 0); // filled by fw
8898 SET_IPHDR_FLAGS(pMdnsRspPkt, 0x40);
8899 SET_IPHDR_FRAG_OFFSET(pMdnsRspPkt, 0);
8900 SET_IPHDR_TTL(pMdnsRspPkt, 0x40);
8901 SET_IPHDR_PROTOCOL(pMdnsRspPkt, 0x11); // ICMP-UDP
8902 SET_IPHDR_HDR_CHECKSUM(pMdnsRspPkt, 0); // filled by fw
8903 SET_IPHDR_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress);
8904 SET_IPHDR_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv4_addr); // filled by fw
8905
8906 *pLength += 20;
8907
8908 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8909 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8910 IS_HARDWARE_TYPE_8812(padapter)) {
8911 rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset);
8912 }
8913 *pLength += 8;
8914 }
8915
8916 /* UDP element */
8917 pMdnsRspPkt += 20;
8918 SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // MDNS
8919 SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // MDNS
8920 SET_UDP_LEN(pMdnsRspPkt, 0); // filled by fw
8921 SET_UDP_CHECKSUM(pMdnsRspPkt, 0); // filled by fw
8922 *pLength += 8;
8923
8924 /* MDNS Header */
8925 pMdnsRspPkt += 8;
8926 SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84);
8927 *pLength += 12;
8928
8929 }
8930
8931 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
8932
8933 #ifdef CONFIG_OFFLOAD_MDNS_V6
8934
8935 /*
8936 * Description:
8937 * Construct the MDNS response V6 packet to support MDNS offload.
8938 *
8939 */
rtw_hal_construct_mdns_rsp_v6(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8940 static void rtw_hal_construct_mdns_rsp_v6(
8941 PADAPTER padapter,
8942 u8 *pframe,
8943 u32 *pLength,
8944 u8 *pIPAddress
8945 )
8946 {
8947 struct rtw_ieee80211_hdr *pwlanhdr;
8948 u16 *fctrl;
8949 u32 pktlen;
8950 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8951 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8952 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8953 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8954 struct security_priv *psecuritypriv = &padapter->securitypriv;
8955 static u8 ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8956 u8 mulicast_ipv6_addr[16] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
8957 u8 mulicast_mac_addr_for_mdns[6] = {0x33, 0x33, 0x00, 0x00, 0x00, 0xfb}; /* could be revise by fw */
8958 u8 *pMdnsRspPkt = pframe;
8959 /* for TKIP Cal MIC */
8960 u8 EncryptionHeadOverhead = 0, mdns_offset = 0;
8961 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8962
8963 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
8964 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
8965
8966 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8967
8968 fctrl = &pwlanhdr->frame_ctl;
8969 *(fctrl) = 0;
8970
8971 /* ------------------------------------------------------------------------- */
8972 /* MAC Header. */
8973 /* ------------------------------------------------------------------------- */
8974 SetFrameType(fctrl, WIFI_DATA);
8975 /* set_frame_sub_type(fctrl, 0); */
8976 SetToDs(fctrl);
8977 //_rtw_memcpy(pwlanhdr->addr1, mulicast_mac_addr_for_mdns, ETH_ALEN);
8978 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8979 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8980 //_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8981 _rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN);
8982
8983 SetSeqNum(pwlanhdr, 0);
8984 set_duration(pwlanhdr, 0);
8985
8986 #ifdef CONFIG_WAPI_SUPPORT
8987 *pLength = sMacHdrLng;
8988 #else
8989 *pLength = 24;
8990 #endif
8991 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8992 case _WEP40_:
8993 case _WEP104_:
8994 EncryptionHeadOverhead = 4;
8995 break;
8996 case _TKIP_:
8997 EncryptionHeadOverhead = 8;
8998 break;
8999 case _AES_:
9000 EncryptionHeadOverhead = 8;
9001 break;
9002 #ifdef CONFIG_WAPI_SUPPORT
9003 case _SMS4_:
9004 EncryptionHeadOverhead = 18;
9005 break;
9006 #endif
9007 default:
9008 EncryptionHeadOverhead = 0;
9009 }
9010
9011 if (EncryptionHeadOverhead > 0) {
9012 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
9013 *pLength += EncryptionHeadOverhead;
9014 SetPrivacy(fctrl);
9015 }
9016
9017 /* ------------------------------------------------------------------------- */
9018 /* Frame Body. */
9019 /* ------------------------------------------------------------------------- */
9020 mdns_offset = *pLength;
9021 pMdnsRspPkt = (u8 *)(pframe + mdns_offset);
9022 /* LLC header */
9023 _rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8);
9024 *pLength += 8;
9025
9026 /* ICMP element */
9027 pMdnsRspPkt += 8;
9028 SET_IPHDRV6_VERSION(pMdnsRspPkt, 0x06);
9029 SET_IPHDRV6_PAYLOAD_LENGTH(pMdnsRspPkt, 0); // filled by fw
9030 SET_IPHDRV6_NEXT_HEADER(pMdnsRspPkt, 0x3A);
9031 SET_IPHDRV6_HOP_LIMIT(pMdnsRspPkt, 0xFF);
9032 SET_IPHDRV6_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress); // filled by fw
9033 SET_IPHDRV6_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv6_addr); // filled by fw
9034
9035 *pLength += 40;
9036
9037 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
9038 if (IS_HARDWARE_TYPE_8188E(padapter) ||
9039 IS_HARDWARE_TYPE_8812(padapter)) {
9040 rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset);
9041 }
9042 *pLength += 8;
9043 }
9044
9045 /* UDP element */
9046 pMdnsRspPkt += 40;
9047 SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // SNMP
9048 SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // SNMP
9049 SET_UDP_LEN(pMdnsRspPkt, 0); // filled by fw
9050 SET_UDP_CHECKSUM(pMdnsRspPkt, 0); // filled by fw
9051 *pLength += 8;
9052
9053 /* MDNS Header */
9054 pMdnsRspPkt += 8;
9055 SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84);
9056 *pLength += 12;
9057
9058 }
9059
9060 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
9061 #endif
9062
9063 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)9064 static void rtw_hal_construct_GTKRsp(
9065 PADAPTER padapter,
9066 u8 *pframe,
9067 u32 *pLength
9068 )
9069 {
9070 struct rtw_ieee80211_hdr *pwlanhdr;
9071 u16 *fctrl;
9072 u32 pktlen;
9073 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9074 struct wlan_network *cur_network = &pmlmepriv->cur_network;
9075 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9076 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9077 struct security_priv *psecuritypriv = &padapter->securitypriv;
9078 static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
9079 static u8 GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
9080 u8 *pGTKRspPkt = pframe;
9081 u8 EncryptionHeadOverhead = 0;
9082 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
9083
9084 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9085
9086 fctrl = &pwlanhdr->frame_ctl;
9087 *(fctrl) = 0;
9088
9089 /* ------------------------------------------------------------------------- */
9090 /* MAC Header. */
9091 /* ------------------------------------------------------------------------- */
9092 SetFrameType(fctrl, WIFI_DATA);
9093 /* set_frame_sub_type(fctrl, 0); */
9094 SetToDs(fctrl);
9095
9096 _rtw_memcpy(pwlanhdr->addr1,
9097 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9098
9099 _rtw_memcpy(pwlanhdr->addr2,
9100 adapter_mac_addr(padapter), ETH_ALEN);
9101
9102 _rtw_memcpy(pwlanhdr->addr3,
9103 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9104
9105 SetSeqNum(pwlanhdr, 0);
9106 set_duration(pwlanhdr, 0);
9107
9108 #ifdef CONFIG_WAPI_SUPPORT
9109 *pLength = sMacHdrLng;
9110 #else
9111 *pLength = 24;
9112 #endif /* CONFIG_WAPI_SUPPORT */
9113
9114 /* ------------------------------------------------------------------------- */
9115 /* Security Header: leave space for it if necessary. */
9116 /* ------------------------------------------------------------------------- */
9117 switch (psecuritypriv->dot11PrivacyAlgrthm) {
9118 case _WEP40_:
9119 case _WEP104_:
9120 EncryptionHeadOverhead = 4;
9121 break;
9122 case _TKIP_:
9123 EncryptionHeadOverhead = 8;
9124 break;
9125 case _AES_:
9126 EncryptionHeadOverhead = 8;
9127 break;
9128 #ifdef CONFIG_WAPI_SUPPORT
9129 case _SMS4_:
9130 EncryptionHeadOverhead = 18;
9131 break;
9132 #endif /* CONFIG_WAPI_SUPPORT */
9133 default:
9134 EncryptionHeadOverhead = 0;
9135 }
9136
9137 if (EncryptionHeadOverhead > 0) {
9138 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
9139 *pLength += EncryptionHeadOverhead;
9140 /* SET_80211_HDR_WEP(pGTKRspPkt, 1); */ /* Suggested by CCW. */
9141 /* GTK's privacy bit is done by FW */
9142 /* SetPrivacy(fctrl); */
9143 }
9144 /* ------------------------------------------------------------------------- */
9145 /* Frame Body. */
9146 /* ------------------------------------------------------------------------- */
9147 pGTKRspPkt = (u8 *)(pframe + *pLength);
9148 /* LLC header */
9149 _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
9150 *pLength += 8;
9151
9152 /* GTK element */
9153 pGTKRspPkt += 8;
9154
9155 /* GTK frame body after LLC, part 1 */
9156 /* TKIP key_length = 32, AES key_length = 16 */
9157 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
9158 GTKbody_a[8] = 0x20;
9159
9160 /* GTK frame body after LLC, part 1 */
9161 _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
9162 *pLength += 11;
9163 pGTKRspPkt += 11;
9164 /* GTK frame body after LLC, part 2 */
9165 _rtw_memset(&(pframe[*pLength]), 0, 88);
9166 *pLength += 88;
9167 pGTKRspPkt += 88;
9168
9169 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
9170 *pLength += 8;
9171 }
9172 #endif /* CONFIG_GTK_OL */
9173
9174 #define PN_2_CCMPH(ch,key_id) ((ch) & 0x000000000000ffff) \
9175 | (((ch) & 0x0000ffffffff0000) << 16) \
9176 | (((key_id) << 30)) \
9177 | BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)9178 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
9179 u8 *pframe, u32 *pLength)
9180 {
9181 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
9182 struct sta_priv *pstapriv = &adapter->stapriv;
9183 struct security_priv *psecuritypriv = &adapter->securitypriv;
9184 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
9185 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9186 struct sta_info *psta;
9187 struct stainfo_rxcache *prxcache;
9188 u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
9189 size_t sz = 0, total = 0;
9190 u64 ccmp_hdr = 0, tmp_key = 0;
9191
9192 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
9193
9194 if (psta == NULL) {
9195 rtw_warn_on(1);
9196 return;
9197 }
9198
9199 prxcache = &psta->sta_recvpriv.rxcache;
9200 sz = sizeof(cur_dot11rxiv);
9201
9202 /* 3 SEC IV * 1 page */
9203 rtw_get_sec_iv(adapter, cur_dot11rxiv,
9204 get_my_bssid(&pmlmeinfo->network));
9205
9206 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
9207 *pLength += sz;
9208 pframe += sz;
9209
9210 _rtw_memset(&cur_dot11rxiv, 0, sz);
9211
9212 if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
9213 id = psecuritypriv->dot118021XGrpKeyid;
9214 tid_id = prxcache->last_tid;
9215 REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
9216 REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
9217 REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
9218 REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
9219 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
9220 *pLength += sz;
9221 pframe += sz;
9222
9223 _rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
9224 *pLength += sz;
9225 pframe += sz;
9226
9227 total = sizeof(psecuritypriv->iv_seq);
9228 total /= sizeof(psecuritypriv->iv_seq[0]);
9229
9230 for (i = 0 ; i < total ; i ++) {
9231 ccmp_hdr =
9232 le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
9233 _rtw_memset(&cur_dot11rxiv, 0, sz);
9234 if (ccmp_hdr != 0) {
9235 tmp_key = i;
9236 ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
9237 *(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
9238 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
9239 }
9240 *pLength += sz;
9241 pframe += sz;
9242 }
9243 }
9244 }
9245
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)9246 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
9247 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
9248 RSVDPAGE_LOC *rsvd_page_loc)
9249 {
9250 struct security_priv *psecuritypriv = &adapter->securitypriv;
9251 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
9252 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9253 struct mlme_ext_priv *pmlmeext;
9254 struct mlme_ext_info *pmlmeinfo;
9255 u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
9256 u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;
9257 u8 CurtPktPageNum = 0;
9258 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
9259 u32 keep_alive_len=0;
9260 int i;
9261 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN */
9262 #ifdef CONFIG_WAR_OFFLOAD
9263 u16 tmp_idx = 0;
9264 u32 buf_len = 0;
9265 #endif
9266
9267 #ifdef CONFIG_GTK_OL
9268 struct sta_priv *pstapriv = &adapter->stapriv;
9269 struct sta_info *psta;
9270 struct security_priv *psecpriv = &adapter->securitypriv;
9271 u8 kek[RTW_KEK_LEN];
9272 u8 kck[RTW_KCK_LEN];
9273 #endif /* CONFIG_GTK_OL */
9274 #ifdef CONFIG_PNO_SUPPORT
9275 int pno_index;
9276 u8 ssid_num;
9277 #endif /* CONFIG_PNO_SUPPORT */
9278
9279 pmlmeext = &adapter->mlmeextpriv;
9280 pmlmeinfo = &pmlmeext->mlmext_info;
9281
9282 if (pwrctl->wowlan_pno_enable == _FALSE) {
9283 /* ARP RSP * 1 page */
9284
9285 rsvd_page_loc->LocArpRsp = *page_num;
9286
9287 RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
9288
9289 #ifdef CONFIG_WAR_OFFLOAD
9290 if ((0 != pwrctl->wowlan_war_offload_ipv4.ip_addr[0]) &&
9291 (_FALSE == _rtw_memcmp(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4))) {
9292 _rtw_memcpy(pmlmeinfo->ip_addr, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4);
9293 RTW_INFO("Update IP(%d.%d.%d.%d) to arp rsvd page\n",
9294 pmlmeinfo->ip_addr[0], pmlmeinfo->ip_addr[1],
9295 pmlmeinfo->ip_addr[2], pmlmeinfo->ip_addr[3]);
9296 }
9297 #endif /* CONFIG_WAR_OFFLOAD */
9298
9299
9300 rtw_hal_construct_ARPRsp(adapter, &pframe[index],
9301 &ARPLength, pmlmeinfo->ip_addr);
9302
9303 rtw_hal_fill_fake_txdesc(adapter,
9304 &pframe[index - tx_desc],
9305 ARPLength, _FALSE, _FALSE, _TRUE);
9306
9307 CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
9308
9309 *page_num += CurtPktPageNum;
9310
9311 index += (CurtPktPageNum * page_size);
9312 RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
9313 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
9314 /* Keep Alive * ? page*/
9315 if(pwrctl->keep_alive_pattern_len){
9316 rsvd_page_loc->LocKeepAlive = *page_num;
9317 pwrctl->keep_alive_pattern_loc = rsvd_page_loc->LocKeepAlive;
9318 RTW_INFO("pwrctl->keep_alive_pattern_loc: %d\n", pwrctl->keep_alive_pattern_loc);
9319 rtw_hal_construct_keepalive(adapter,&pframe[index],&keep_alive_len);
9320 rtw_hal_fill_fake_txdesc(adapter,
9321 &pframe[index - tx_desc],
9322 keep_alive_len, _FALSE, _FALSE, _TRUE);
9323 CurtPktPageNum = (u8)PageNum(tx_desc + keep_alive_len, page_size);
9324 *page_num += CurtPktPageNum;
9325 index += (CurtPktPageNum * page_size);
9326 RSVD_PAGE_CFG("WOW-KeepAlive:", CurtPktPageNum, *page_num, 0);
9327 }
9328 #endif /* CONFIG_WOW_KEEP_ALIVE_PATTERN*/
9329
9330 #ifdef CONFIG_IPV6
9331 /* 2 NS offload and NDP Info*/
9332 if (pwrctl->wowlan_ns_offload_en == _TRUE) {
9333 rsvd_page_loc->LocNbrAdv = *page_num;
9334 RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
9335 rtw_hal_construct_na_message(adapter,
9336 &pframe[index], &ns_len);
9337 rtw_hal_fill_fake_txdesc(adapter,
9338 &pframe[index - tx_desc],
9339 ns_len, _FALSE,
9340 _FALSE, _TRUE);
9341 CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
9342 page_size);
9343 *page_num += CurtPktPageNum;
9344 index += (CurtPktPageNum * page_size);
9345 RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
9346
9347 rsvd_page_loc->LocNDPInfo = *page_num;
9348 RTW_INFO("LocNDPInfo: %d\n",
9349 rsvd_page_loc->LocNDPInfo);
9350
9351 rtw_hal_construct_ndp_info(adapter,
9352 &pframe[index - tx_desc],
9353 &ns_len);
9354 CurtPktPageNum =
9355 (u8)PageNum(tx_desc + ns_len, page_size);
9356 *page_num += CurtPktPageNum;
9357 index += (CurtPktPageNum * page_size);
9358 RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
9359
9360 }
9361 #endif /*CONFIG_IPV6*/
9362 /* 3 Remote Control Info. * 1 page */
9363 rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
9364 RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
9365 rtw_hal_construct_remote_control_info(adapter,
9366 &pframe[index - tx_desc],
9367 &rc_len);
9368 CurtPktPageNum = (u8)PageNum(rc_len, page_size);
9369 *page_num += CurtPktPageNum;
9370 *total_pkt_len = index + rc_len;
9371 RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
9372 #ifdef CONFIG_GTK_OL
9373 index += (CurtPktPageNum * page_size);
9374
9375 /* if the ap staion info. exists, get the kek, kck from staion info. */
9376 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
9377 if (psta == NULL) {
9378 _rtw_memset(kek, 0, RTW_KEK_LEN);
9379 _rtw_memset(kck, 0, RTW_KCK_LEN);
9380 RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
9381 __func__);
9382 } else {
9383 _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
9384 _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
9385 }
9386
9387 /* 3 KEK, KCK */
9388 rsvd_page_loc->LocGTKInfo = *page_num;
9389 RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
9390
9391 if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
9392 struct security_priv *psecpriv = NULL;
9393
9394 psecpriv = &adapter->securitypriv;
9395 _rtw_memcpy(pframe + index - tx_desc,
9396 &psecpriv->dot11PrivacyAlgrthm, 1);
9397 _rtw_memcpy(pframe + index - tx_desc + 1,
9398 &psecpriv->dot118021XGrpPrivacy, 1);
9399 _rtw_memcpy(pframe + index - tx_desc + 2,
9400 kck, RTW_KCK_LEN);
9401 _rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
9402 kek, RTW_KEK_LEN);
9403 CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
9404 } else {
9405
9406 _rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
9407 _rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
9408 kek, RTW_KEK_LEN);
9409 GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
9410
9411 if (psta != NULL &&
9412 psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
9413 _rtw_memcpy(pframe + index - tx_desc + 56,
9414 &psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
9415 GTKLength += RTW_TKIP_MIC_LEN;
9416 }
9417 CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
9418 }
9419 #if 0
9420 {
9421 int i;
9422 printk("\ntoFW KCK: ");
9423 for (i = 0; i < 16; i++)
9424 printk(" %02x ", kck[i]);
9425 printk("\ntoFW KEK: ");
9426 for (i = 0; i < 16; i++)
9427 printk(" %02x ", kek[i]);
9428 printk("\n");
9429 }
9430
9431 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
9432 __FUNCTION__, &pframe[index - tx_desc],
9433 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
9434 #endif
9435
9436 *page_num += CurtPktPageNum;
9437
9438 index += (CurtPktPageNum * page_size);
9439 RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
9440
9441 /* 3 GTK Response */
9442 rsvd_page_loc->LocGTKRsp = *page_num;
9443 RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
9444 rtw_hal_construct_GTKRsp(adapter, &pframe[index], >KLength);
9445
9446 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
9447 GTKLength, _FALSE, _FALSE, _TRUE);
9448 #if 0
9449 {
9450 int gj;
9451 printk("123GTK pkt=>\n");
9452 for (gj = 0; gj < GTKLength + tx_desc; gj++) {
9453 printk(" %02x ", pframe[index - tx_desc + gj]);
9454 if ((gj + 1) % 16 == 0)
9455 printk("\n");
9456 }
9457 printk(" <=end\n");
9458 }
9459
9460 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
9461 __FUNCTION__, &pframe[index - tx_desc],
9462 (tx_desc + GTKLength));
9463 #endif
9464
9465 CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
9466
9467 *page_num += CurtPktPageNum;
9468
9469 index += (CurtPktPageNum * page_size);
9470 RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
9471
9472 /* below page is empty for GTK extension memory */
9473 /* 3(11) GTK EXT MEM */
9474 rsvd_page_loc->LocGTKEXTMEM = *page_num;
9475 RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
9476 CurtPktPageNum = 2;
9477
9478 if (page_size >= 256)
9479 CurtPktPageNum = 1;
9480
9481 *page_num += CurtPktPageNum;
9482 /* extension memory for FW */
9483 *total_pkt_len = index + (page_size * CurtPktPageNum);
9484 RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
9485 #endif /* CONFIG_GTK_OL */
9486
9487 index += (CurtPktPageNum * page_size);
9488
9489 #ifdef CONFIG_WAR_OFFLOAD
9490 if(_TRUE == pwrctl->wowlan_war_offload_mode) {
9491 u8 zero_ary[16] = {0x00};
9492 u8 war_tmp_cnt = 0;
9493
9494 /* Reserve 2 page for Ip parameters */
9495 /* First page
9496 | Byte 15 -----------Byte 0 |
9497 | IP-4 | IP-3 | IP-2 | IP-1 |
9498 | location of each feature | mac addr |
9499 | NetBIOS name |
9500 | location of each feature |
9501 Second page
9502 | IPv6 - 1 |
9503 | IPv6 - 2 |
9504 | IPv6 - 3 |
9505 | IPv6 - 4 |
9506 | IPv6 - 5 |
9507 | IPv6 - 6 |
9508 | IPv6 - 7 |
9509 | IPv6 - 8 |
9510 */
9511
9512 /* location of each feature : Byte 22 ~ Byte 31
9513 * Byte22 : location of SNMP RX
9514 * Byte23 : location of SNMP V4
9515 * Byte24 : location of SNMP V6
9516 * Byte25 : location of MDNS Param
9517 * Byte26 : location of MDNS V4
9518 * Byte27 : location of MDNS V6
9519 * Byte28 : location of SSDP pattern
9520 * Byte29 : location of WSD pattern
9521 * Byte30 : location of SLP pattern
9522 * Byte31 : location of LLMNR
9523 */
9524
9525 /* ipv4 : 4 */
9526 if (0 == pwrctl->wowlan_war_offload_ipv4.ip_addr[0])
9527 _rtw_memcpy(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4);
9528 for(war_tmp_cnt=0; war_tmp_cnt<4 ;war_tmp_cnt++)
9529 _rtw_memcpy(pframe + index - tx_desc + (war_tmp_cnt*4), &pwrctl->wowlan_war_offload_ipv4.ip_addr[war_tmp_cnt], 4);
9530
9531 if (is_zero_mac_addr(pwrctl->wowlan_war_offload_mac)) {
9532 _rtw_memcpy(pwrctl->wowlan_war_offload_mac, adapter_mac_addr(adapter), 6);
9533 }
9534 _rtw_memcpy(pframe + index + 16 - tx_desc, pwrctl->wowlan_war_offload_mac, 6);
9535
9536
9537 /* ipv6 : 8 */
9538 if (_TRUE == _rtw_memcmp(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], zero_ary, RTW_IPv6_ADDR_LEN))
9539 _rtw_memcpy(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], pmlmeinfo->ip6_addr, RTW_IPv6_ADDR_LEN);
9540
9541 for(war_tmp_cnt=0; war_tmp_cnt<8 ;war_tmp_cnt++)
9542 _rtw_memcpy(pframe + index + page_size - tx_desc + (war_tmp_cnt*16), pwrctl->wowlan_war_offload_ipv6.ipv6_addr[war_tmp_cnt], 16);
9543
9544 rsvd_page_loc->LocIpParm = *page_num;
9545
9546 tmp_idx = index;
9547 CurtPktPageNum = 2;
9548 *page_num += CurtPktPageNum;
9549 *total_pkt_len = index + (page_size * CurtPktPageNum);
9550 index += (CurtPktPageNum * page_size);
9551
9552
9553 #if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6)
9554 if ( (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) ||
9555 (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) ||
9556 (WAR_MDNS_V4_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl) ||
9557 (WAR_MDNS_V6_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl)) {
9558
9559 struct war_mdns_service_info *psinfo = pwrctl->wowlan_war_offload_mdns_service;
9560 u8 txt_in_ptr[31]={ 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9561 0x00, 0x13, 0x09, 0x74, 0x78, 0x74, 0x76, 0x65, 0x72, 0x73,
9562 0x3d, 0x31, 0x08, 0x71, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x3d, 0x31};
9563 u16 mdns_offset = index - tx_desc;
9564 u8 i = 0;
9565
9566 rsvd_page_loc->LocMdnsPara = *page_num;
9567 RTW_INFO("LocMdnsPara : %d\n", rsvd_page_loc->LocMdnsPara);
9568
9569 /* 1. service info */
9570 pframe[mdns_offset] = 0x01; // TLV(T)
9571 mdns_offset += 1;
9572 _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_service_info_num, 1);
9573 mdns_offset += 1;
9574
9575 for(i=0; i<pwrctl->wowlan_war_offload_mdns_service_info_num ;i++)
9576 {
9577 u16 srv_rsp_len = 0;
9578
9579 // 1.1 : construct service name string
9580 // : length of total service name string (service+transport+domain)
9581 pframe[mdns_offset] = psinfo[i].service_len + psinfo[i].transport_len + psinfo[i].domain_len + 4;
9582 mdns_offset += 1;
9583
9584 // : service name
9585 pframe[mdns_offset] = psinfo[i].service_len;
9586 mdns_offset += 1;
9587 _rtw_memcpy(pframe + mdns_offset, &psinfo[i].service, psinfo[i].service_len);
9588 mdns_offset += psinfo[i].service_len;
9589
9590 // : transport name
9591 pframe[mdns_offset] = psinfo[i].transport_len;
9592 mdns_offset += 1;
9593 _rtw_memcpy(pframe + mdns_offset, &psinfo[i].transport, psinfo[i].transport_len);
9594 mdns_offset += psinfo[i].transport_len;
9595
9596 // : domain name
9597 pframe[mdns_offset] = psinfo[i].domain_len;
9598 mdns_offset += 1;
9599 _rtw_memcpy(pframe + mdns_offset, &psinfo[i].domain, psinfo[i].domain_len);
9600 mdns_offset += psinfo[i].domain_len;
9601
9602 // : delimiter
9603 mdns_offset += 1;
9604
9605 // 1.2 : construct type srv rsp
9606 pframe[mdns_offset] = psinfo[i].target_len + 19; // length
9607 pframe[mdns_offset + 2] = 0x21; // rsp type (srv)
9608 pframe[mdns_offset + 4] = 0x01; // cache flush + class
9609 _rtw_memcpy(pframe + mdns_offset + 5, &psinfo[i].ttl, 4); // ttl
9610 pframe[mdns_offset + 5] = (u8) ( (psinfo[i].ttl & 0xff000000) >> 24); // ttl - byte0
9611 pframe[mdns_offset + 6] = (u8) ( (psinfo[i].ttl & 0x00ff0000) >> 16); // ttl - byte1
9612 pframe[mdns_offset + 7] = (u8) ( (psinfo[i].ttl & 0x0000ff00) >> 8 ); // ttl - byte2
9613 pframe[mdns_offset + 8] = (u8) (psinfo[i].ttl & 0x000000ff); // ttl - byte3
9614 pframe[mdns_offset + 10] = psinfo[i].target_len + 9; // data length
9615 _rtw_memcpy(pframe + mdns_offset + 15, &psinfo[i].port, 2); // port
9616 _rtw_memcpy(pframe + mdns_offset + 17, &psinfo[i].target_len, 1); // target len
9617 _rtw_memcpy(pframe + mdns_offset + 18, &psinfo[i].target, psinfo[i].target_len); // target
9618 pframe[mdns_offset + 18 + psinfo[i].target_len] = 0xc0; // message compresion, offset will be filled by fw.
9619 mdns_offset += (1 + psinfo[i].target_len + 19);
9620
9621 // 1.3 : set the idx of txt rsp
9622 pframe[mdns_offset] = psinfo[i].txt_rsp_idx;
9623 mdns_offset += 1;
9624 }
9625
9626 /* 2. machine name */
9627 pframe[mdns_offset] = 0x02; // TLV(T)
9628 mdns_offset += 1;
9629 _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_mnane_num, 1); // NUM
9630 mdns_offset += 1;
9631
9632 for(i=0; i<pwrctl->wowlan_war_offload_mdns_mnane_num; i++)
9633 {
9634 pframe[mdns_offset] = pwrctl->wowlan_war_offload_mdns_mnane[i].name_len;
9635 _rtw_memcpy(pframe + mdns_offset + 1, pwrctl->wowlan_war_offload_mdns_mnane[i].name,
9636 pwrctl->wowlan_war_offload_mdns_mnane[i].name_len); // machine name
9637 mdns_offset += (1+pwrctl->wowlan_war_offload_mdns_mnane[i].name_len);
9638 }
9639
9640 /* 3. A rsp */
9641 pframe[mdns_offset] = 0x03; // TLV(T)
9642 pframe[mdns_offset + 1] = 14; // TLV(L)
9643 pframe[mdns_offset + 3] = 0x01; // rsp type (a)
9644 pframe[mdns_offset + 5] = 0x01; // cache flush + class
9645 pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec)
9646 pframe[mdns_offset + 11] = 4; // length of ipv4 addr.
9647 _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4);
9648 mdns_offset += (2 + 14);
9649
9650 /* 4. AAAA rsp */
9651 pframe[mdns_offset] = 0x04; // TLV(T)
9652 pframe[mdns_offset + 1] = 26; // TLV(L)
9653 pframe[mdns_offset + 3] = 0x1c; // rsp type (aaaa)
9654 pframe[mdns_offset + 5] = 0x01; // cache flush + class
9655 pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec)
9656 pframe[mdns_offset + 11] = 16; // length of ipv6 addr.
9657 _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], 16);
9658 mdns_offset += (2 + 26);
9659
9660 /* 5. PTR rsp */
9661 pframe[mdns_offset] = 0x05; // TLV(T)
9662 pframe[mdns_offset + 1] = 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // TLV(L)
9663 pframe[mdns_offset + 3] = 0x0c; // rsp type (aaaa)
9664 pframe[mdns_offset + 5] = 0x01; // cache flush + class
9665 pframe[mdns_offset + 8] = 0x1c; // ttl
9666 pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec)
9667 pframe[mdns_offset + 11] = 3 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // data length
9668 pframe[mdns_offset + 12] = pwrctl->wowlan_war_offload_mdns_domain_name_len; // domain name length
9669 _rtw_memcpy(pframe + mdns_offset + 13, &pwrctl->wowlan_war_offload_mdns_domain_name,
9670 pwrctl->wowlan_war_offload_mdns_domain_name_len);
9671 pframe[mdns_offset + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len] = 0xc0; // message compression
9672 mdns_offset += (2 + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len);
9673
9674 /* 6. TXT in PTR rsp */
9675 pframe[mdns_offset] = 0x06; // TLV(T)
9676 pframe[mdns_offset + 1] = 31; // TLV(L)
9677 _rtw_memcpy(pframe + mdns_offset + 2, &txt_in_ptr, 31);
9678 mdns_offset += (2 + 31);
9679
9680 /* 7. TXT rsp */
9681 pframe[mdns_offset] = 0x07; // TLV(T)
9682 mdns_offset += 1;
9683 _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_txt_rsp_num, 1); // NUM
9684 mdns_offset += 1;
9685
9686 for(i=0; i<pwrctl->wowlan_war_offload_mdns_txt_rsp_num; i++)
9687 {
9688 u16 txt_rsp_len = pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len;
9689
9690 if(pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len==0)
9691 {
9692 _rtw_memcpy(pframe + mdns_offset, &txt_rsp_len, 2);
9693 mdns_offset += ( 2 + txt_rsp_len );
9694 continue;
9695 }
9696
9697 txt_rsp_len += 10;
9698 _rtw_memcpy(pframe + mdns_offset, &txt_rsp_len, 2);
9699 pframe[mdns_offset + 3] = 0x10; // rsp type (txt)
9700 pframe[mdns_offset + 5] = 0x01; // cache flush + class
9701 pframe[mdns_offset + 8] = 0x1c; // ttl
9702 pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec)
9703 pframe[mdns_offset + 10] = (u8) ((pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0xff00) >> 8);
9704 pframe[mdns_offset + 11] = (u8) (pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0x00ff);
9705 _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt,
9706 pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len);
9707 mdns_offset += ( 2 + txt_rsp_len );
9708 }
9709
9710 CurtPktPageNum = (u8)PageNum(mdns_offset - index, page_size)+1;
9711 *page_num += CurtPktPageNum;
9712 *total_pkt_len = index + (page_size * CurtPktPageNum);
9713 index += (CurtPktPageNum * page_size);
9714 }
9715 #endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */
9716
9717 #ifdef CONFIG_OFFLOAD_MDNS_V4
9718 if (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) {
9719 rsvd_page_loc->LocMdnsv4 = *page_num;
9720 RTW_INFO("LocMdnsv4: %d\n", rsvd_page_loc->LocMdnsv4);
9721
9722 rtw_hal_construct_mdns_rsp_v4(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr);
9723 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE);
9724 CurtPktPageNum = 16;
9725 *page_num += CurtPktPageNum;
9726 index += (CurtPktPageNum * page_size);
9727 }
9728 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
9729
9730 #ifdef CONFIG_OFFLOAD_MDNS_V6
9731 if (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) {
9732 rsvd_page_loc->LocMdnsv6 = *page_num;
9733 RTW_INFO("LocMdnsv6: %d\n", rsvd_page_loc->LocMdnsv6);
9734
9735 rtw_hal_construct_mdns_rsp_v6(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr);
9736 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE);
9737 CurtPktPageNum = 16;
9738 *page_num += CurtPktPageNum;
9739 index += (CurtPktPageNum * page_size);
9740 }
9741 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
9742
9743 #if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6)
9744 *(pframe+tmp_idx+25-tx_desc) = rsvd_page_loc->LocMdnsPara;
9745 *(pframe+tmp_idx+26-tx_desc) = rsvd_page_loc->LocMdnsv4;
9746 *(pframe+tmp_idx+27-tx_desc) = rsvd_page_loc->LocMdnsv6;
9747 #endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */
9748
9749 }
9750 //rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, rsvd_page_loc->LocIpParm, 46);
9751 #endif /* CONFIG_WAR_OFFLOAD */
9752
9753
9754 /*Reserve 1 page for AOAC report*/
9755 rsvd_page_loc->LocAOACReport = *page_num;
9756 RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
9757 *page_num += 1;
9758 *total_pkt_len = index + (page_size * 1);
9759 RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
9760 } else {
9761 #ifdef CONFIG_PNO_SUPPORT
9762 if (pwrctl->wowlan_in_resume == _FALSE &&
9763 pwrctl->pno_inited == _TRUE) {
9764
9765 /* Broadcast Probe Request */
9766 rsvd_page_loc->LocProbePacket = *page_num;
9767
9768 RTW_INFO("loc_probe_req: %d\n",
9769 rsvd_page_loc->LocProbePacket);
9770
9771 rtw_hal_construct_ProbeReq(
9772 adapter,
9773 &pframe[index],
9774 &ProbeReqLength,
9775 NULL);
9776
9777 rtw_hal_fill_fake_txdesc(adapter,
9778 &pframe[index - tx_desc],
9779 ProbeReqLength, _FALSE, _FALSE, _FALSE);
9780
9781 CurtPktPageNum =
9782 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
9783
9784 *page_num += CurtPktPageNum;
9785
9786 index += (CurtPktPageNum * page_size);
9787 RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9788
9789 /* Hidden SSID Probe Request */
9790 ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
9791
9792 for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
9793 pwrctl->pnlo_info->loc_probe_req[pno_index] =
9794 *page_num;
9795
9796 rtw_hal_construct_ProbeReq(
9797 adapter,
9798 &pframe[index],
9799 &ProbeReqLength,
9800 &pwrctl->pno_ssid_list->node[pno_index]);
9801
9802 rtw_hal_fill_fake_txdesc(adapter,
9803 &pframe[index - tx_desc],
9804 ProbeReqLength, _FALSE, _FALSE, _FALSE);
9805
9806 CurtPktPageNum =
9807 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
9808
9809 *page_num += CurtPktPageNum;
9810
9811 index += (CurtPktPageNum * page_size);
9812 RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
9813 }
9814
9815 /* PNO INFO Page */
9816 rsvd_page_loc->LocPNOInfo = *page_num;
9817 RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
9818 rtw_hal_construct_PNO_info(adapter,
9819 &pframe[index - tx_desc],
9820 &PNOLength);
9821
9822 CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
9823 *page_num += CurtPktPageNum;
9824 index += (CurtPktPageNum * page_size);
9825 RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
9826
9827 /* Scan Info Page */
9828 rsvd_page_loc->LocScanInfo = *page_num;
9829 RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
9830 rtw_hal_construct_scan_info(adapter,
9831 &pframe[index - tx_desc],
9832 &ScanInfoLength);
9833
9834 CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
9835 *page_num += CurtPktPageNum;
9836 *total_pkt_len = index + ScanInfoLength;
9837 index += (CurtPktPageNum * page_size);
9838 RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
9839 }
9840 #endif /* CONFIG_PNO_SUPPORT */
9841 }
9842 }
9843
rtw_hal_gate_bb(_adapter * adapter,bool stop)9844 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
9845 {
9846 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9847 u8 i = 0, val8 = 0, empty = _FAIL;
9848
9849 if (stop) {
9850 /* checking TX queue status */
9851 for (i = 0 ; i < 5 ; i++) {
9852 rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
9853 if (empty) {
9854 break;
9855 } else {
9856 RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
9857 __func__, i);
9858 rtw_mdelay_os(10);
9859 }
9860 }
9861
9862 if (val8 == 5)
9863 RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
9864
9865 /* Pause TX*/
9866 pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
9867 rtw_write8(adapter, REG_TXPAUSE, 0xff);
9868 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9869 val8 &= ~BIT(0);
9870 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9871 RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
9872 __func__,
9873 rtw_read8(adapter, REG_SYS_FUNC_EN),
9874 pwrpriv->wowlan_txpause_status);
9875 } else {
9876 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9877 val8 |= BIT(0);
9878 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9879 RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
9880 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
9881 pwrpriv->wowlan_txpause_status);
9882 /* release TX*/
9883 rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
9884 }
9885 }
9886
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)9887 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
9888 {
9889 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9890 u8 *pattern;
9891 u8 len = 0;
9892 u8 *mask;
9893
9894 u8 mask_hw[MAX_WKFM_SIZE] = {0};
9895 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9896 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9897 u8 multicast_addr1[2] = {0x33, 0x33};
9898 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9899 u8 mask_len = 0;
9900 u8 mac_addr[ETH_ALEN] = {0};
9901 u16 count = 0;
9902 int i;
9903
9904 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9905 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9906 __func__, MAX_WKFM_CAM_NUM);
9907 return _FAIL;
9908 }
9909
9910 pattern = pwrctl->patterns[idx].content;
9911 len = pwrctl->patterns[idx].len;
9912 mask = pwrctl->patterns[idx].mask;
9913
9914 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9915 _rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
9916
9917 mask_len = DIV_ROUND_UP(len, 8);
9918
9919 /* 1. setup A1 table */
9920 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9921 pwow_pattern->type = PATTERN_BROADCAST;
9922 else if (memcmp(pattern, multicast_addr1, 2) == 0)
9923 pwow_pattern->type = PATTERN_MULTICAST;
9924 else if (memcmp(pattern, multicast_addr2, 3) == 0)
9925 pwow_pattern->type = PATTERN_MULTICAST;
9926 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9927 pwow_pattern->type = PATTERN_UNICAST;
9928 else
9929 pwow_pattern->type = PATTERN_INVALID;
9930
9931 /* translate mask from os to mask for hw */
9932
9933 /******************************************************************************
9934 * pattern from OS uses 'ethenet frame', like this:
9935
9936 | 6 | 6 | 2 | 20 | Variable | 4 |
9937 |--------+--------+------+-----------+------------+-----|
9938 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
9939 | DA | SA | Type |
9940
9941 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9942
9943 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
9944 |-------------------+--------+------+-----------+------------+-----|
9945 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
9946 | Others | Tpye |
9947
9948 * Therefore, we need translate mask_from_OS to mask_to_hw.
9949 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9950 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9951 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9952 ******************************************************************************/
9953 /* Shift 6 bits */
9954 for (i = 0; i < mask_len - 1; i++) {
9955 mask_hw[i] = mask[i] >> 6;
9956 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9957 }
9958
9959 mask_hw[i] = (mask[i] >> 6) & 0x3F;
9960 /* Set bit 0-5 to zero */
9961 mask_hw[0] &= 0xC0;
9962
9963 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9964 pwow_pattern->mask[i] = mask_hw[i * 4];
9965 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
9966 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
9967 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
9968 }
9969
9970 /* To get the wake up pattern from the mask.
9971 * We do not count first 12 bits which means
9972 * DA[6] and SA[6] in the pattern to match HW design. */
9973 count = 0;
9974 for (i = 12; i < len; i++) {
9975 if ((mask[i / 8] >> (i % 8)) & 0x01) {
9976 content[count] = pattern[i];
9977 count++;
9978 }
9979 }
9980
9981 pwow_pattern->crc = rtw_calc_crc(content, count);
9982
9983 if (pwow_pattern->crc != 0) {
9984 if (pwow_pattern->type == PATTERN_INVALID)
9985 pwow_pattern->type = PATTERN_VALID;
9986 }
9987
9988 return _SUCCESS;
9989 }
9990
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)9991 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
9992 {
9993 int j;
9994
9995 RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
9996 RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
9997 RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
9998 for (j = 0; j < 4; j++)
9999 RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
10000 }
10001 /*bit definition of pattern match format*/
10002 #define WOW_VALID_BIT BIT31
10003 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10004 #define WOW_BC_BIT BIT26
10005 #define WOW_MC_BIT BIT25
10006 #define WOW_UC_BIT BIT24
10007 #else
10008 #define WOW_BC_BIT BIT18
10009 #define WOW_UC_BIT BIT17
10010 #define WOW_MC_BIT BIT16
10011 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10012
10013 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10014 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_hal_reset_mac_rx(_adapter * adapter)10015 static void rtw_hal_reset_mac_rx(_adapter *adapter)
10016 {
10017 u8 val8 = 0;
10018 /* Set REG_CR bit1, bit3, bit7 to 0*/
10019 val8 = rtw_read8(adapter, REG_CR);
10020 val8 &= 0x75;
10021 rtw_write8(adapter, REG_CR, val8);
10022 val8 = rtw_read8(adapter, REG_CR);
10023 /* Set REG_CR bit1, bit3, bit7 to 1*/
10024 val8 |= 0x8a;
10025 rtw_write8(adapter, REG_CR, val8);
10026 RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
10027 }
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)10028 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
10029 {
10030 u8 val8 = 0;
10031 u16 rxff_bndy = 0;
10032 u32 rx_dma_buff_sz = 0;
10033
10034 val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
10035 if (val8 != 0)
10036 RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
10037 __func__, (REG_FIFOPAGE + 3));
10038
10039 rtw_hal_reset_mac_rx(adapter);
10040
10041 if (wow_mode) {
10042 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
10043 (u8 *)&rx_dma_buff_sz);
10044 rxff_bndy = rx_dma_buff_sz - 1;
10045
10046 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
10047 RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
10048 REG_TRXFF_BNDY + 2,
10049 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
10050 } else {
10051 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
10052 (u8 *)&rx_dma_buff_sz);
10053 rxff_bndy = rx_dma_buff_sz - 1;
10054 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
10055 RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
10056 REG_TRXFF_BNDY + 2,
10057 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
10058 }
10059 }
10060 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO*/
10061 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)10062 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
10063 {
10064 u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
10065 u16 offset, rx_buf_ptr = 0;
10066 u16 cam_start_offset = 0;
10067 u16 ctrl_l = 0, ctrl_h = 0;
10068 u8 count = 0, tmp = 0;
10069 int i = 0;
10070 bool res = _TRUE;
10071
10072 if (idx > MAX_WKFM_CAM_NUM) {
10073 RTW_INFO("[Error]: %s, pattern index is out of range\n",
10074 __func__);
10075 return _FALSE;
10076 }
10077
10078 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
10079 (u8 *)&rx_dma_buff_sz);
10080
10081 if (rx_dma_buff_sz == 0) {
10082 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
10083 return _FALSE;
10084 }
10085
10086 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
10087
10088 if (page_sz == 0) {
10089 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
10090 return _FALSE;
10091 }
10092
10093 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
10094 cam_start_offset = offset * page_sz;
10095
10096 ctrl_l = 0x0;
10097 ctrl_h = 0x0;
10098
10099 /* Enable RX packet buffer access */
10100 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
10101
10102 /* Read the WKFM CAM */
10103 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
10104 /*
10105 * Set Rx packet buffer offset.
10106 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
10107 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
10108 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
10109 * * Index: The index of the wake up frame mask
10110 * * WKFMCAM_SIZE: the total size of one WKFM CAM
10111 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
10112 */
10113 rx_buf_ptr =
10114 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
10115 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
10116
10117 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
10118 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
10119 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
10120
10121 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
10122
10123 count = 0;
10124
10125 do {
10126 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
10127 rtw_udelay_os(2);
10128 count++;
10129 } while (!tmp && count < 100);
10130
10131 if (count >= 100) {
10132 RTW_INFO("%s count:%d\n", __func__, count);
10133 res = _FALSE;
10134 }
10135 }
10136
10137 /* Disable RX packet buffer access */
10138 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
10139 DISABLE_TRXPKT_BUF_ACCESS);
10140 return res;
10141 }
10142
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)10143 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
10144 struct rtl_wow_pattern *context)
10145 {
10146 u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
10147 u16 offset, rx_buf_ptr = 0;
10148 u16 cam_start_offset = 0;
10149 u16 ctrl_l = 0, ctrl_h = 0;
10150 u8 count = 0, tmp = 0;
10151 int res = 0, i = 0;
10152
10153 if (idx > MAX_WKFM_CAM_NUM) {
10154 RTW_INFO("[Error]: %s, pattern index is out of range\n",
10155 __func__);
10156 return _FALSE;
10157 }
10158
10159 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
10160 (u8 *)&rx_dma_buff_sz);
10161
10162 if (rx_dma_buff_sz == 0) {
10163 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
10164 return _FALSE;
10165 }
10166
10167 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
10168
10169 if (page_sz == 0) {
10170 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
10171 return _FALSE;
10172 }
10173
10174 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
10175
10176 cam_start_offset = offset * page_sz;
10177
10178 if (IS_HARDWARE_TYPE_8188E(adapter)) {
10179 ctrl_l = 0x0001;
10180 ctrl_h = 0x0001;
10181 } else {
10182 ctrl_l = 0x0f01;
10183 ctrl_h = 0xf001;
10184 }
10185
10186 /* Enable RX packet buffer access */
10187 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
10188
10189 /* Write the WKFM CAM */
10190 for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
10191 /*
10192 * Set Rx packet buffer offset.
10193 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
10194 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
10195 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
10196 * * Index: The index of the wake up frame mask
10197 * * WKFMCAM_SIZE: the total size of one WKFM CAM
10198 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
10199 */
10200 rx_buf_ptr =
10201 (cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
10202 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
10203
10204 if (i == 0) {
10205 if (context->type == PATTERN_VALID)
10206 data = WOW_VALID_BIT;
10207 else if (context->type == PATTERN_BROADCAST)
10208 data = WOW_VALID_BIT | WOW_BC_BIT;
10209 else if (context->type == PATTERN_MULTICAST)
10210 data = WOW_VALID_BIT | WOW_MC_BIT;
10211 else if (context->type == PATTERN_UNICAST)
10212 data = WOW_VALID_BIT | WOW_UC_BIT;
10213
10214 if (context->crc != 0)
10215 data |= context->crc;
10216
10217 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
10218 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
10219 } else if (i == 1) {
10220 data = 0;
10221 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
10222 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
10223 } else if (i == 2 || i == 4) {
10224 data = context->mask[i - 2];
10225 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
10226 /* write to RX packet buffer*/
10227 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
10228 } else if (i == 3 || i == 5) {
10229 data = context->mask[i - 2];
10230 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
10231 /* write to RX packet buffer*/
10232 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
10233 }
10234
10235 count = 0;
10236 do {
10237 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
10238 rtw_udelay_os(2);
10239 count++;
10240 } while (tmp && count < 100);
10241
10242 if (count >= 100)
10243 res = _FALSE;
10244 else
10245 res = _TRUE;
10246 }
10247
10248 /* Disable RX packet buffer access */
10249 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
10250 DISABLE_TRXPKT_BUF_ACCESS);
10251
10252 return res;
10253 }
10254 #else /* CONFIG_WOW_PATTERN_IN_TXFIFO */
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)10255 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
10256 {
10257 u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
10258 u16 tx_page_start, tx_buf_ptr = 0;
10259 u16 cam_start_offset = 0;
10260 u16 ctrl_l = 0, ctrl_h = 0;
10261 u8 count = 0, tmp = 0, last_entry = 0;
10262 int i = 0;
10263 bool res = _TRUE;
10264
10265 if (idx > MAX_WKFM_CAM_NUM) {
10266 RTW_INFO("[Error]: %s, pattern index is out of range\n",
10267 __func__);
10268 return _FALSE;
10269 }
10270
10271 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
10272 if (page_sz == 0) {
10273 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
10274 return _FALSE;
10275 }
10276
10277 rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
10278 if (last_entry == 0) {
10279 RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
10280 return _FALSE;
10281 }
10282
10283 /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
10284 tx_page_start = last_entry - 1;
10285 cam_start_offset = tx_page_start * page_sz / 8;
10286 ctrl_l = 0x0;
10287 ctrl_h = 0x0;
10288
10289 /* Enable TX packet buffer access */
10290 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
10291
10292 /* Read the WKFM CAM */
10293 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
10294 /*
10295 * Set Tx packet buffer offset.
10296 * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer.
10297 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
10298 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
10299 * * Index: The index of the wake up frame mask
10300 * * WKFMCAM_SIZE: the total size of one WKFM CAM
10301 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
10302 */
10303 tx_buf_ptr =
10304 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
10305 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr);
10306 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
10307 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
10308 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
10309
10310 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
10311
10312 count = 0;
10313
10314 do {
10315 tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
10316 rtw_udelay_os(2);
10317 count++;
10318 } while (!tmp && count < 100);
10319
10320 if (count >= 100) {
10321 RTW_INFO("%s count:%d\n", __func__, count);
10322 res = _FALSE;
10323 }
10324 }
10325
10326 /* Disable RX packet buffer access */
10327 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
10328 DISABLE_TRXPKT_BUF_ACCESS);
10329 return res;
10330 }
10331
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)10332 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
10333 struct rtl_wow_pattern *context)
10334 {
10335 u32 tx_page_start = 0, page_sz = 0;
10336 u16 tx_buf_ptr = 0;
10337 u16 cam_start_offset = 0;
10338 u32 data_l = 0, data_h = 0;
10339 u8 count = 0, tmp = 0, last_entry = 0;
10340 int res = 0, i = 0;
10341
10342 if (idx > MAX_WKFM_CAM_NUM) {
10343 RTW_INFO("[Error]: %s, pattern index is out of range\n",
10344 __func__);
10345 return _FALSE;
10346 }
10347
10348 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
10349 if (page_sz == 0) {
10350 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
10351 return _FALSE;
10352 }
10353
10354 rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
10355 if (last_entry == 0) {
10356 RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
10357 return _FALSE;
10358 }
10359
10360 /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
10361 tx_page_start = last_entry - 1;
10362 cam_start_offset = tx_page_start * page_sz / 8;
10363
10364 /* Write the PATTERN location to BIT_TXBUF_WKCAM_OFFSET */
10365 rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET, cam_start_offset & 0xFF);
10366 rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET + 1, (cam_start_offset >> 8) & 0xFF);
10367 /* Enable TX packet buffer access */
10368 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
10369
10370 /* Write the WKFM CAM */
10371 for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
10372 /*
10373 * Set Tx packet buffer offset.
10374 * TxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
10375 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
10376 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
10377 * * Index: The index of the wake up frame mask
10378 * * WKFMCAM_SIZE: the total size of one WKFM CAM
10379 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
10380 */
10381 tx_buf_ptr = cam_start_offset + ((idx * WKFMCAM_SIZE + i * 8) >> 3);
10382
10383 if (i == 0) {
10384 if (context->type == PATTERN_VALID)
10385 data_l = WOW_VALID_BIT;
10386 else if (context->type == PATTERN_BROADCAST)
10387 data_l = WOW_VALID_BIT | WOW_BC_BIT;
10388 else if (context->type == PATTERN_MULTICAST)
10389 data_l = WOW_VALID_BIT | WOW_MC_BIT;
10390 else if (context->type == PATTERN_UNICAST)
10391 data_l = WOW_VALID_BIT | WOW_UC_BIT;
10392
10393 if (context->crc != 0)
10394 data_l |= context->crc;
10395
10396 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
10397 } else {
10398 data_l = context->mask[i * 2 - 2];
10399 data_h = context->mask[i * 2 - 1];
10400 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
10401 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h);
10402 }
10403
10404 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0x1FFF) | BIT23 | (0xff <<24));
10405 count = 0;
10406 do {
10407 tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
10408 rtw_udelay_os(2);
10409 count++;
10410 } while (tmp && count < 100);
10411
10412 if (count >= 100) {
10413 res = _FALSE;
10414 RTW_INFO("%s write failed\n", __func__);
10415 } else {
10416 res = _TRUE;
10417 RTW_INFO("%s write OK\n", __func__);
10418 }
10419 }
10420
10421 /* Disable TX packet buffer access */
10422 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
10423 return res;
10424 }
10425 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
10426
rtw_clean_pattern(_adapter * adapter)10427 void rtw_clean_pattern(_adapter *adapter)
10428 {
10429 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10430 struct rtl_wow_pattern zero_pattern;
10431 int i = 0;
10432
10433 _rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
10434
10435 zero_pattern.type = PATTERN_INVALID;
10436
10437 for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
10438 rtw_write_to_frame_mask(adapter, i, &zero_pattern);
10439
10440 rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
10441 }
10442 #if 0
10443 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
10444 u8 len, u8 *mask, u8 idx)
10445 {
10446 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10447 struct mlme_ext_priv *pmlmeext = NULL;
10448 struct mlme_ext_info *pmlmeinfo = NULL;
10449 struct rtl_wow_pattern wow_pattern;
10450 u8 mask_hw[MAX_WKFM_SIZE] = {0};
10451 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
10452 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
10453 u8 multicast_addr1[2] = {0x33, 0x33};
10454 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
10455 u8 res = _FALSE, index = 0, mask_len = 0;
10456 u8 mac_addr[ETH_ALEN] = {0};
10457 u16 count = 0;
10458 int i, j;
10459
10460 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
10461 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
10462 __func__, MAX_WKFM_CAM_NUM);
10463 return _FALSE;
10464 }
10465
10466 pmlmeext = &adapter->mlmeextpriv;
10467 pmlmeinfo = &pmlmeext->mlmext_info;
10468 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
10469 _rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
10470
10471 mask_len = DIV_ROUND_UP(len, 8);
10472
10473 /* 1. setup A1 table */
10474 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
10475 wow_pattern.type = PATTERN_BROADCAST;
10476 else if (memcmp(pattern, multicast_addr1, 2) == 0)
10477 wow_pattern.type = PATTERN_MULTICAST;
10478 else if (memcmp(pattern, multicast_addr2, 3) == 0)
10479 wow_pattern.type = PATTERN_MULTICAST;
10480 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
10481 wow_pattern.type = PATTERN_UNICAST;
10482 else
10483 wow_pattern.type = PATTERN_INVALID;
10484
10485 /* translate mask from os to mask for hw */
10486
10487 /******************************************************************************
10488 * pattern from OS uses 'ethenet frame', like this:
10489
10490 | 6 | 6 | 2 | 20 | Variable | 4 |
10491 |--------+--------+------+-----------+------------+-----|
10492 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
10493 | DA | SA | Type |
10494
10495 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
10496
10497 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
10498 |-------------------+--------+------+-----------+------------+-----|
10499 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
10500 | Others | Tpye |
10501
10502 * Therefore, we need translate mask_from_OS to mask_to_hw.
10503 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
10504 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
10505 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
10506 ******************************************************************************/
10507 /* Shift 6 bits */
10508 for (i = 0; i < mask_len - 1; i++) {
10509 mask_hw[i] = mask[i] >> 6;
10510 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
10511 }
10512
10513 mask_hw[i] = (mask[i] >> 6) & 0x3F;
10514 /* Set bit 0-5 to zero */
10515 mask_hw[0] &= 0xC0;
10516
10517 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
10518 wow_pattern.mask[i] = mask_hw[i * 4];
10519 wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
10520 wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
10521 wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
10522 }
10523
10524 /* To get the wake up pattern from the mask.
10525 * We do not count first 12 bits which means
10526 * DA[6] and SA[6] in the pattern to match HW design. */
10527 count = 0;
10528 for (i = 12; i < len; i++) {
10529 if ((mask[i / 8] >> (i % 8)) & 0x01) {
10530 content[count] = pattern[i];
10531 count++;
10532 }
10533 }
10534
10535 wow_pattern.crc = rtw_calc_crc(content, count);
10536
10537 if (wow_pattern.crc != 0) {
10538 if (wow_pattern.type == PATTERN_INVALID)
10539 wow_pattern.type = PATTERN_VALID;
10540 }
10541
10542 index = idx;
10543
10544 if (!pwrctl->bInSuspend)
10545 index += 2;
10546
10547 /* write pattern */
10548 res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
10549
10550 if (res == _FALSE)
10551 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
10552 __func__, idx);
10553
10554 return res;
10555 }
10556 #endif
10557
rtw_fill_pattern(_adapter * adapter)10558 void rtw_fill_pattern(_adapter *adapter)
10559 {
10560 int i = 0, total = 0, index;
10561 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10562 struct rtl_wow_pattern wow_pattern;
10563
10564 total = pwrpriv->wowlan_pattern_idx;
10565
10566 if (total > MAX_WKFM_CAM_NUM)
10567 total = MAX_WKFM_CAM_NUM;
10568
10569 for (i = 0 ; i < total ; i++) {
10570 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10571
10572 index = i;
10573 if (!pwrpriv->bInSuspend)
10574 index += 2;
10575 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10576 if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
10577 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
10578 }
10579
10580 }
10581 rtw_write8(adapter, REG_WKFMCAM_NUM, total);
10582
10583 }
10584
10585 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
10586
10587 #define WOW_CAM_ACCESS_TIMEOUT_MS 200
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)10588 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
10589 {
10590 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10591 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10592
10593 u32 rdata = 0;
10594 u32 cnt = 0;
10595 systime start = 0;
10596 u8 timeout = 0;
10597 u8 rst = _FALSE;
10598
10599 _enter_critical_mutex(mutex, NULL);
10600
10601 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
10602
10603 start = rtw_get_current_time();
10604 while (1) {
10605 if (rtw_is_surprise_removed(adapter))
10606 break;
10607
10608 cnt++;
10609 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10610 rst = _SUCCESS;
10611 break;
10612 }
10613 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10614 timeout = 1;
10615 break;
10616 }
10617 }
10618
10619 rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
10620
10621 _exit_critical_mutex(mutex, NULL);
10622
10623 /*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
10624
10625 if (timeout)
10626 RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
10627
10628 return rdata;
10629 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10630 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
10631 {
10632 int i;
10633 u32 rdata;
10634
10635 _rtw_memset(context, 0, sizeof(struct rtl_wow_pattern));
10636
10637 for (i = 4; i >= 0; i--) {
10638 rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
10639
10640 switch (i) {
10641 case 4:
10642 if (rdata & WOW_BC_BIT)
10643 context->type = PATTERN_BROADCAST;
10644 else if (rdata & WOW_MC_BIT)
10645 context->type = PATTERN_MULTICAST;
10646 else if (rdata & WOW_UC_BIT)
10647 context->type = PATTERN_UNICAST;
10648 else
10649 context->type = PATTERN_INVALID;
10650
10651 context->crc = rdata & 0xFFFF;
10652 break;
10653 default:
10654 _rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
10655 break;
10656 }
10657 }
10658 }
10659
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)10660 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
10661 {
10662 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10663 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10664 u32 cnt = 0;
10665 systime start = 0, end = 0;
10666 u8 timeout = 0;
10667
10668 /*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
10669 _enter_critical_mutex(mutex, NULL);
10670
10671 rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
10672 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
10673
10674 start = rtw_get_current_time();
10675 while (1) {
10676 if (rtw_is_surprise_removed(adapter))
10677 break;
10678
10679 cnt++;
10680 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
10681 break;
10682
10683 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10684 timeout = 1;
10685 break;
10686 }
10687 }
10688 end = rtw_get_current_time();
10689
10690 _exit_critical_mutex(mutex, NULL);
10691
10692 if (timeout) {
10693 RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
10694 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
10695 }
10696 }
10697
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10698 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
10699 {
10700 int j;
10701 u8 addr;
10702 u32 wdata = 0;
10703
10704 for (j = 4; j >= 0; j--) {
10705 switch (j) {
10706 case 4:
10707 wdata = context->crc;
10708
10709 if (PATTERN_BROADCAST == context->type)
10710 wdata |= WOW_BC_BIT;
10711 if (PATTERN_MULTICAST == context->type)
10712 wdata |= WOW_MC_BIT;
10713 if (PATTERN_UNICAST == context->type)
10714 wdata |= WOW_UC_BIT;
10715 if (PATTERN_INVALID != context->type)
10716 wdata |= WOW_VALID_BIT;
10717 break;
10718 default:
10719 wdata = context->mask[j];
10720 break;
10721 }
10722
10723 addr = (id << 3) + j;
10724
10725 _rtw_wow_pattern_write_cam(adapter, addr, wdata);
10726 }
10727 }
10728
_rtw_wow_pattern_clean_cam(_adapter * adapter)10729 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
10730 {
10731 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10732 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10733 u32 cnt = 0;
10734 systime start = 0;
10735 u8 timeout = 0;
10736 u8 rst = _FAIL;
10737
10738 _enter_critical_mutex(mutex, NULL);
10739 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
10740
10741 start = rtw_get_current_time();
10742 while (1) {
10743 if (rtw_is_surprise_removed(adapter))
10744 break;
10745
10746 cnt++;
10747 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10748 rst = _SUCCESS;
10749 break;
10750 }
10751 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10752 timeout = 1;
10753 break;
10754 }
10755 }
10756 _exit_critical_mutex(mutex, NULL);
10757
10758 if (timeout)
10759 RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
10760
10761 return rst;
10762 }
10763
rtw_clean_pattern(_adapter * adapter)10764 void rtw_clean_pattern(_adapter *adapter)
10765 {
10766 if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
10767 RTW_ERR("rtw_clean_pattern failed\n");
10768 }
rtw_fill_pattern(_adapter * adapter)10769 void rtw_fill_pattern(_adapter *adapter)
10770 {
10771 int i = 0, total = 0;
10772 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10773 struct rtl_wow_pattern wow_pattern;
10774
10775 total = pwrpriv->wowlan_pattern_idx;
10776
10777 if (total > MAX_WKFM_CAM_NUM)
10778 total = MAX_WKFM_CAM_NUM;
10779
10780 for (i = 0 ; i < total ; i++) {
10781 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10782 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10783 rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
10784 }
10785 }
10786 }
10787
10788 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)10789 void rtw_wow_pattern_cam_dump(_adapter *adapter)
10790 {
10791
10792 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10793 int i;
10794
10795 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10796 RTW_INFO("=======[%d]=======\n", i);
10797 rtw_read_from_frame_mask(adapter, i);
10798 }
10799 #else
10800 struct rtl_wow_pattern context;
10801 int i;
10802
10803 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10804 rtw_wow_pattern_read_cam_ent(adapter, i, &context);
10805 rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
10806 }
10807
10808 #endif
10809 }
10810
10811
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)10812 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
10813 {
10814 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10815
10816 switch (mode) {
10817 case 0:
10818 rtw_clean_pattern(adapter);
10819 RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
10820 break;
10821 case 1:
10822 rtw_set_default_pattern(adapter);
10823 rtw_fill_pattern(adapter);
10824 RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
10825 break;
10826 case 2:
10827 rtw_clean_pattern(adapter);
10828 rtw_wow_pattern_sw_reset(adapter);
10829 RTW_INFO("%s: clean patterns\n", __func__);
10830 break;
10831 default:
10832 RTW_INFO("%s: unknown mode\n", __func__);
10833 break;
10834 }
10835 }
10836
rtw_hal_wow_enable(_adapter * adapter)10837 static void rtw_hal_wow_enable(_adapter *adapter)
10838 {
10839 struct registry_priv *registry_par = &adapter->registrypriv;
10840 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10841 struct security_priv *psecuritypriv = &adapter->securitypriv;
10842 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10843 struct sta_info *psta = NULL;
10844 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
10845 int res;
10846 u16 media_status_rpt;
10847 u8 no_wake = 0, i;
10848 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10849 _adapter *iface;
10850 #ifdef CONFIG_GPIO_WAKEUP
10851 u8 val8 = 0;
10852 #endif
10853
10854 #ifdef CONFIG_LPS_PG
10855 u8 lps_pg_hdl_id = 0;
10856 #endif
10857
10858
10859
10860 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
10861 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
10862 no_wake = 1;
10863
10864 RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
10865 rtw_hal_gate_bb(adapter, _TRUE);
10866
10867 for (i = 0; i < dvobj->iface_nums; i++) {
10868 iface = dvobj->padapters[i];
10869 /* Start Usb TxDMA */
10870 if(iface) {
10871 RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface));
10872 RTW_ENABLE_FUNC(iface, DF_TX_BIT);
10873 }
10874 }
10875
10876 #ifdef CONFIG_GTK_OL
10877 if (psecuritypriv->binstallKCK_KEK == _TRUE)
10878 rtw_hal_fw_sync_cam_id(adapter);
10879 #endif
10880 if (IS_HARDWARE_TYPE_8723B(adapter))
10881 rtw_hal_backup_rate(adapter);
10882
10883 rtw_hal_fw_dl(adapter, _TRUE);
10884 if(no_wake)
10885 media_status_rpt = RT_MEDIA_DISCONNECT;
10886 else
10887 media_status_rpt = RT_MEDIA_CONNECT;
10888 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10889 (u8 *)&media_status_rpt);
10890
10891 /* RX DMA stop */
10892 #if defined(CONFIG_RTL8188E)
10893 if (IS_HARDWARE_TYPE_8188E(adapter))
10894 rtw_hal_disable_tx_report(adapter);
10895 #endif
10896
10897 res = rtw_hal_pause_rx_dma(adapter);
10898 if (res == _FAIL)
10899 RTW_PRINT("[WARNING] pause RX DMA fail\n");
10900
10901 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10902 /* Reconfig RX_FF Boundary */
10903 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10904 rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
10905 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10906 #endif
10907
10908 /* redownload wow pattern */
10909 if(!no_wake)
10910 rtw_hal_dl_pattern(adapter, 1);
10911
10912 if (!pwrctl->wowlan_pno_enable) {
10913 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10914
10915 if (psta != NULL) {
10916 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10917 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10918 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10919 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10920 #endif
10921 if(!no_wake)
10922 rtw_sta_media_status_rpt(adapter, psta, 1);
10923 }
10924 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10925 else {
10926 if(registry_par->suspend_type == FW_IPS_WRC) {
10927 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10928 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10929 rtw_hal_set_default_port_id_cmd(adapter, 0);
10930 }
10931 }
10932 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10933 }
10934
10935 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10936 /* Enable CPWM2 only. */
10937 res = rtw_hal_enable_cpwm2(adapter);
10938 if (res == _FAIL)
10939 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
10940 #endif
10941 #ifdef CONFIG_GPIO_WAKEUP
10942 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10943 rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10944 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10945 #else
10946 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10947 if (pwrctl->is_high_active == 0)
10948 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10949 else
10950 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10951 GPIO_OUTPUT_LOW);
10952 #else
10953 val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
10954 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8);
10955 rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10956 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n",
10957 __func__, pwrctl->wowlan_gpio_index,
10958 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10959 pwrctl->is_high_active ? "HIGI" : "LOW");
10960 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10961 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10962 #endif /* CONFIG_GPIO_WAKEUP */
10963 /* Set WOWLAN H2C command. */
10964 RTW_PRINT("Set WOWLan cmd\n");
10965 rtw_hal_set_fw_wow_related_cmd(adapter, 1);
10966
10967 res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
10968
10969 if (res == _FALSE)
10970 RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
10971
10972 pwrctl->wowlan_wake_reason =
10973 rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10974
10975 RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
10976 pwrctl->wowlan_wake_reason);
10977 #ifdef CONFIG_GTK_OL_DBG
10978 dump_sec_cam(RTW_DBGDUMP, adapter);
10979 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
10980 #endif
10981
10982 #ifdef CONFIG_LPS_PG
10983 if (pwrctl->lps_level == LPS_PG) {
10984 lps_pg_hdl_id = LPS_PG_INFO_CFG;
10985 rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
10986 }
10987 #endif
10988
10989 #ifdef CONFIG_USB_HCI
10990 /* free adapter's resource */
10991 rtw_mi_intf_stop(adapter);
10992
10993 #endif
10994 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
10995 /* Invoid SE0 reset signal during suspending*/
10996 rtw_write8(adapter, REG_RSV_CTRL, 0x20);
10997 if (IS_8188F(pHalData->version_id) == FALSE
10998 && IS_8188GTV(pHalData->version_id) == FALSE)
10999 rtw_write8(adapter, REG_RSV_CTRL, 0x60);
11000 #endif
11001
11002 rtw_hal_gate_bb(adapter, _FALSE);
11003 }
11004
11005 #define DBG_WAKEUP_REASON
11006 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)11007 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
11008 {
11009 RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
11010 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)11011 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
11012 {
11013 if (RX_PAIRWISEKEY == reason)
11014 _dbg_wake_up_reason_string(adapter, "Rx pairwise key");
11015 else if (RX_GTK == reason)
11016 _dbg_wake_up_reason_string(adapter, "Rx GTK");
11017 else if (RX_FOURWAY_HANDSHAKE == reason)
11018 _dbg_wake_up_reason_string(adapter, "Rx four way handshake");
11019 else if (RX_DISASSOC == reason)
11020 _dbg_wake_up_reason_string(adapter, "Rx disassoc");
11021 else if (RX_DEAUTH == reason)
11022 _dbg_wake_up_reason_string(adapter, "Rx deauth");
11023 else if (RX_ARP_REQUEST == reason)
11024 _dbg_wake_up_reason_string(adapter, "Rx ARP request");
11025 else if (FW_DECISION_DISCONNECT == reason)
11026 _dbg_wake_up_reason_string(adapter, "FW detect disconnect");
11027 else if (RX_MAGIC_PKT == reason)
11028 _dbg_wake_up_reason_string(adapter, "Rx magic packet");
11029 else if (RX_UNICAST_PKT == reason)
11030 _dbg_wake_up_reason_string(adapter, "Rx unicast packet");
11031 else if (RX_PATTERN_PKT == reason)
11032 _dbg_wake_up_reason_string(adapter, "Rx pattern packet");
11033 else if (RTD3_SSID_MATCH == reason)
11034 _dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
11035 else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
11036 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
11037 else if (RX_REALWOW_V2_ACK_LOST == reason)
11038 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
11039 else if (ENABLE_FAIL_DMA_IDLE == reason)
11040 _dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
11041 else if (ENABLE_FAIL_DMA_PAUSE == reason)
11042 _dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
11043 else if (AP_OFFLOAD_WAKEUP == reason)
11044 _dbg_wake_up_reason_string(adapter, "AP offload wakeup");
11045 else if (CLK_32K_UNLOCK == reason)
11046 _dbg_wake_up_reason_string(adapter, "clk 32k unlock");
11047 else if (RTIME_FAIL_DMA_IDLE == reason)
11048 _dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
11049 else if (CLK_32K_LOCK == reason)
11050 _dbg_wake_up_reason_string(adapter, "clk 32k lock");
11051 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
11052 else if (WOW_KEEPALIVE_ACK_TIMEOUT == reason)
11053 _dbg_wake_up_reason_string(adapter, "rx keep alive ack timeout");
11054 else if (WOW_KEEPALIVE_WAKE == reason)
11055 _dbg_wake_up_reason_string(adapter, "rx keep alive wake pattern");
11056 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
11057 else
11058 _dbg_wake_up_reason_string(adapter, "unknown reasoen");
11059 }
11060 #endif
11061
rtw_hal_wow_disable(_adapter * adapter)11062 static void rtw_hal_wow_disable(_adapter *adapter)
11063 {
11064 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
11065 struct security_priv *psecuritypriv = &adapter->securitypriv;
11066 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11067 struct sta_info *psta = NULL;
11068 struct registry_priv *registry_par = &adapter->registrypriv;
11069 int res;
11070 u16 media_status_rpt;
11071
11072 RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
11073
11074 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
11075 RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");
11076 return;
11077 }
11078
11079 if (!pwrctl->wowlan_pno_enable) {
11080 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
11081 if (psta != NULL)
11082 rtw_sta_media_status_rpt(adapter, psta, 0);
11083 else
11084 RTW_INFO("%s: psta is null\n", __func__);
11085 }
11086
11087 if (0) {
11088 RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
11089 RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
11090 RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
11091 RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
11092 }
11093
11094 pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
11095
11096 RTW_PRINT("wakeup_reason: 0x%02x\n",
11097 pwrctl->wowlan_wake_reason);
11098 #ifdef DBG_WAKEUP_REASON
11099 _dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
11100 #endif
11101
11102 rtw_hal_set_fw_wow_related_cmd(adapter, 0);
11103
11104 res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
11105
11106 #if defined(CONFIG_RTL8188E)
11107 if (IS_HARDWARE_TYPE_8188E(adapter))
11108 rtw_hal_enable_tx_report(adapter);
11109 #endif
11110
11111 if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
11112 (pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
11113 (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) {
11114 rtw_hal_get_aoac_rpt(adapter);
11115 rtw_hal_update_sw_security_info(adapter);
11116 }
11117
11118 if (res == _FALSE) {
11119 RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
11120 rtw_hal_force_enable_rxdma(adapter);
11121 }
11122
11123 rtw_hal_gate_bb(adapter, _TRUE);
11124
11125 res = rtw_hal_pause_rx_dma(adapter);
11126 if (res == _FAIL)
11127 RTW_PRINT("[WARNING] pause RX DMA fail\n");
11128
11129 /* clean HW pattern match */
11130 rtw_hal_dl_pattern(adapter, 0);
11131
11132 #ifndef CONFIG_WOW_PATTERN_HW_CAM
11133 /* config RXFF boundary to original */
11134 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
11135 rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
11136 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
11137 #endif
11138 rtw_hal_release_rx_dma(adapter);
11139
11140 rtw_hal_fw_dl(adapter, _FALSE);
11141
11142 #ifdef CONFIG_GPIO_WAKEUP
11143
11144 #ifdef CONFIG_RTW_ONE_PIN_GPIO
11145 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
11146 #else
11147 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
11148 if (pwrctl->is_high_active == 0)
11149 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
11150 else
11151 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
11152 GPIO_OUTPUT_LOW);
11153 #else
11154 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index
11155 , pwrctl->wowlan_gpio_output_state);
11156 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n",
11157 __func__, pwrctl->wowlan_gpio_index,
11158 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
11159 pwrctl->is_high_active ? "HIGI" : "LOW");
11160 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
11161 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
11162 #endif /* CONFIG_GPIO_WAKEUP */
11163 if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
11164 (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
11165 (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
11166 (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
11167
11168 media_status_rpt = RT_MEDIA_CONNECT;
11169 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
11170 (u8 *)&media_status_rpt);
11171
11172 if (psta != NULL) {
11173 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
11174 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
11175 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
11176 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
11177 #endif
11178 rtw_sta_media_status_rpt(adapter, psta, 1);
11179 }
11180 }
11181 rtw_hal_gate_bb(adapter, _FALSE);
11182 }
11183 #endif /*CONFIG_WOWLAN*/
11184
11185 #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)11186 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
11187 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
11188 RSVDPAGE_LOC *rsvd_page_loc)
11189 {
11190 u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
11191 u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
11192 u8 CurtPktPageNum = 0;
11193
11194 /* P2P Beacon */
11195 rsvd_page_loc->LocP2PBeacon = *page_num;
11196 rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
11197 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11198 P2PBCNLength, _FALSE, _FALSE, _FALSE);
11199
11200 #if 0
11201 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
11202 __FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
11203 #endif
11204
11205 CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
11206
11207 *page_num += CurtPktPageNum;
11208
11209 index += (CurtPktPageNum * page_size);
11210 RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
11211
11212 /* P2P Probe rsp */
11213 rsvd_page_loc->LocP2PProbeRsp = *page_num;
11214 rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
11215 &P2PProbeRspLength);
11216 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11217 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
11218
11219 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", */
11220 /* __FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
11221
11222 CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
11223
11224 *page_num += CurtPktPageNum;
11225
11226 index += (CurtPktPageNum * page_size);
11227 RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
11228
11229 /* P2P nego rsp */
11230 rsvd_page_loc->LocNegoRsp = *page_num;
11231 rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
11232 &P2PNegoRspLength);
11233 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11234 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
11235
11236 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
11237 /* __FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
11238
11239 CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
11240
11241 *page_num += CurtPktPageNum;
11242
11243 index += (CurtPktPageNum * page_size);
11244 RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
11245
11246 /* P2P invite rsp */
11247 rsvd_page_loc->LocInviteRsp = *page_num;
11248 rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
11249 &P2PInviteRspLength);
11250 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11251 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
11252
11253 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
11254 /* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
11255
11256 CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
11257
11258 *page_num += CurtPktPageNum;
11259
11260 index += (CurtPktPageNum * page_size);
11261 RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
11262
11263 /* P2P provision discovery rsp */
11264 rsvd_page_loc->LocPDRsp = *page_num;
11265 rtw_hal_construct_P2PProvisionDisRsp(adapter,
11266 &pframe[index], &P2PPDRspLength);
11267
11268 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11269 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
11270
11271 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
11272 /* __FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
11273
11274 CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
11275
11276 *page_num += CurtPktPageNum;
11277
11278 *total_pkt_len = index + P2PPDRspLength;
11279 RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
11280
11281 index += (CurtPktPageNum * page_size);
11282
11283
11284 }
11285 #endif /* CONFIG_P2P_WOWLAN */
11286
11287 #ifdef CONFIG_LPS_PG
11288 #ifndef DBG_LPSPG_INFO_DUMP
11289 #define DBG_LPSPG_INFO_DUMP 1
11290 #endif
11291
11292 #include "hal_halmac.h"
11293
11294 #ifdef CONFIG_RTL8822C
rtw_lps_pg_set_dpk_info_rsvd_page(_adapter * adapter)11295 static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)
11296 {
11297 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11298 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11299 struct dm_struct *dm = adapter_to_phydm(adapter);
11300 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;
11301 u8 *info = NULL;
11302 u32 info_len;
11303 int ret = _FAIL;
11304
11305 /* get length */
11306 halrf_dpk_info_rsvd_page(dm, NULL, &info_len);
11307 if (!info_len) {
11308 RTW_ERR("get %s length fail\n", cache->name);
11309 goto exit;
11310 }
11311
11312 /* allocate buf */
11313 info = rtw_zmalloc(info_len);
11314 if (!info) {
11315 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11316 goto exit;
11317 }
11318
11319 /* get content */
11320 halrf_dpk_info_rsvd_page(dm, info, NULL);
11321
11322 if (rsvd_page_cache_update_data(cache, info, info_len)) {
11323
11324 #if (DBG_LPSPG_INFO_DUMP >= 1)
11325 RTW_INFO_DUMP(cache->name, info, info_len);
11326 #endif
11327
11328 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11329 ret = !ret ? _SUCCESS : _FAIL;
11330 if (ret != _SUCCESS) {
11331 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11332 goto free_mem;
11333 }
11334
11335 #if (DBG_LPSPG_INFO_DUMP >= 2)
11336 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11337 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11338 #endif
11339 }
11340
11341 free_mem:
11342 rtw_mfree(info, info_len);
11343
11344 exit:
11345 return ret;
11346 }
11347
rtw_lps_pg_set_iqk_info_rsvd_page(_adapter * adapter)11348 static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)
11349 {
11350 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11351 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11352 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11353 struct dm_struct *dm = adapter_to_phydm(adapter);
11354 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;
11355 u8 *info = NULL;
11356 u32 info_len = 0;
11357 int ret = _FAIL;
11358
11359 if (hal_data->RegIQKFWOffload) {
11360 rsvd_page_cache_free_data(cache);
11361 ret = _SUCCESS;
11362 goto exit;
11363 }
11364
11365 /* get length */
11366 halrf_iqk_info_rsvd_page(dm, NULL, &info_len);
11367 if (!info_len) {
11368 RTW_ERR("get %s length fail\n", cache->name);
11369 goto exit;
11370 }
11371
11372 /* allocate buf */
11373 info = rtw_zmalloc(info_len);
11374 if (!info) {
11375 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11376 goto exit;
11377 }
11378
11379 /* get content */
11380 halrf_iqk_info_rsvd_page(dm, info, NULL);
11381
11382 if (rsvd_page_cache_update_data(cache, info, info_len)) {
11383
11384 #if (DBG_LPSPG_INFO_DUMP >= 1)
11385 RTW_INFO_DUMP(cache->name, info, info_len);
11386 #endif
11387
11388 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11389 ret = !ret ? _SUCCESS : _FAIL;
11390 if (ret != _SUCCESS) {
11391 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11392 goto free_mem;
11393 }
11394
11395 #if (DBG_LPSPG_INFO_DUMP >= 2)
11396 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11397 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11398 #endif
11399 }
11400
11401 free_mem:
11402 rtw_mfree(info, info_len);
11403
11404 exit:
11405 return ret;
11406 }
11407 #endif /* CONFIG_RTL8822C */
11408
rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv * dvobj,_adapter * ld_sta_iface,u8 * buf,u32 * buf_size)11409 static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size)
11410 {
11411 #define LPS_PG_INFO_RSVD_LEN 16
11412
11413 if (buf) {
11414 _adapter *adapter = dvobj_get_primary_adapter(dvobj);
11415 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11416 struct sta_info *psta;
11417 #ifdef CONFIG_MBSSID_CAM
11418 u8 cam_id = INVALID_CAM_ID;
11419 #endif
11420 u8 *psec_cam_id = buf + 8;
11421 u8 sec_cam_num = 0;
11422 u8 drv_rsvdpage_num = 0;
11423
11424 if (ld_sta_iface) {
11425 psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv));
11426 if (!psta) {
11427 RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
11428 rtw_warn_on(1);
11429 goto size_chk;
11430 }
11431 /*Byte 0 - used macid*/
11432 LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);
11433 RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
11434 }
11435
11436 #ifdef CONFIG_MBSSID_CAM
11437 /*Byte 1 - used BSSID CAM entry*/
11438 cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
11439 if (cam_id != INVALID_CAM_ID)
11440 LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);
11441 RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
11442 #endif
11443
11444 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
11445 /*Btye 2 - Max used Pattern Match CAM entry*/
11446 if (pwrpriv->wowlan_mode == _TRUE
11447 && ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11448 LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);
11449 RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
11450 }
11451 #endif
11452 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
11453 /*Btye 3 - Max MU rate table Group ID*/
11454 LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);
11455 RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
11456 #endif
11457
11458 /*Btye 8 ~15 - used Security CAM entry */
11459 sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
11460
11461 /*Btye 4 - used Security CAM entry number*/
11462 if (sec_cam_num < 8)
11463 LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);
11464 RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
11465
11466 /*Btye 5 - Txbuf used page number for fw offload*/
11467 if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
11468 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11469 else
11470 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11471 LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);
11472 RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
11473 }
11474
11475 size_chk:
11476 if (buf_size)
11477 *buf_size = LPS_PG_INFO_RSVD_LEN;
11478 }
11479
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)11480 static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
11481 {
11482 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11483 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11484 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;
11485 u8 *info = NULL;
11486 u32 info_len = 0;
11487 int ret = _FAIL;
11488
11489 /* get length */
11490 rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len);
11491 if (!info_len) {
11492 RTW_ERR("get %s length fail\n", cache->name);
11493 goto exit;
11494 }
11495
11496 /* allocate buf */
11497 info = rtw_zmalloc(info_len);
11498 if (!info) {
11499 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11500 goto exit;
11501 }
11502
11503 /* get content */
11504 rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL);
11505
11506 if (rsvd_page_cache_update_data(cache, info, info_len)) {
11507
11508 #if (DBG_LPSPG_INFO_DUMP >= 1)
11509 RTW_INFO_DUMP(cache->name, info, info_len);
11510 #endif
11511
11512 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11513 ret = !ret ? _SUCCESS : _FAIL;
11514 if (ret != _SUCCESS) {
11515 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11516 goto free_mem;
11517 }
11518
11519 #if (DBG_LPSPG_INFO_DUMP >= 2)
11520 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11521 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11522 #endif
11523 }
11524
11525 free_mem:
11526 rtw_mfree(info, info_len);
11527
11528 exit:
11529 return ret;
11530 }
11531
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)11532 static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index
11533 , u8 txdesc_size, u32 page_size, u8 *total_page_num
11534 , bool is_wow_mode, _adapter *ld_sta_iface, bool only_get_page_num)
11535 {
11536 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11537 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
11538 struct rsvd_page_cache_t *cache;
11539 bool rsvd = 1;
11540 u8 *pos;
11541 u32 len;
11542
11543 if (is_wow_mode) {
11544 /* lps_level will not change when enter wow_mode */
11545 if (pwrctl->lps_level != LPS_PG)
11546 rsvd = 0;
11547 } else {
11548 if (!only_get_page_num && !ld_sta_iface)
11549 rsvd = 0;
11550 }
11551
11552 pos = only_get_page_num ? NULL : frame + *index;
11553
11554 #ifdef CONFIG_RTL8822C
11555 if (IS_8822C_SERIES(hal_data->version_id)) {
11556 /* LPSPG_DPK_INFO */
11557 cache = &pwrctl->lpspg_dpk_info;
11558 if (rsvd) {
11559 if (pwrctl->lps_level != LPS_PG)
11560 pos = NULL;
11561 len = 0;
11562 halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
11563 #if (DBG_LPSPG_INFO_DUMP >= 1)
11564 if (pos)
11565 RTW_INFO_DUMP(cache->name, pos, len);
11566 #endif
11567 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11568 *total_page_num += cache->page_num;
11569 *index += page_size * cache->page_num;
11570 pos = only_get_page_num ? NULL : frame + *index;
11571 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11572 } else
11573 rsvd_page_cache_free(cache);
11574
11575 /* LPSPG_IQK_INFO */
11576 cache = &pwrctl->lpspg_iqk_info;
11577 if (rsvd
11578 /* RegIQKFWOffload will not change when enter wow_mode */
11579 && !(is_wow_mode && hal_data->RegIQKFWOffload)
11580 ) {
11581 if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)
11582 pos = NULL;
11583 len = 0;
11584 halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
11585 #if (DBG_LPSPG_INFO_DUMP >= 1)
11586 if (pos)
11587 RTW_INFO_DUMP(cache->name, pos, len);
11588 #endif
11589 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11590 *total_page_num += cache->page_num;
11591 *index += page_size * cache->page_num;
11592 pos = only_get_page_num ? NULL : frame + *index;
11593 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11594 } else
11595 rsvd_page_cache_free(cache);
11596 }
11597 #endif
11598
11599 /* LPSPG_INFO */
11600 cache = &pwrctl->lpspg_info;
11601 if (rsvd) {
11602 if (pwrctl->lps_level != LPS_PG)
11603 pos = NULL;
11604 rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len);
11605 #if (DBG_LPSPG_INFO_DUMP >= 1)
11606 if (pos)
11607 RTW_INFO_DUMP(cache->name, pos, len);
11608 #endif
11609 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11610 *total_page_num += cache->page_num;
11611 *index += page_size * cache->page_num;
11612 pos = only_get_page_num ? NULL : frame + *index;
11613 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11614 } else
11615 rsvd_page_cache_free(cache);
11616 }
11617
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)11618 u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
11619 {
11620 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11621 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11622
11623 u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
11624 u8 ret = _FAIL;
11625
11626 if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
11627 SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1); /*SecurityCAM_En*/
11628
11629 #ifdef CONFIG_MBSSID_CAM
11630 SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1); /*BSSIDCAM_En*/
11631 #endif
11632
11633 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
11634 if (pwrpriv->wowlan_mode == _TRUE &&
11635 check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11636
11637 SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/
11638 }
11639 #endif
11640
11641 #ifdef CONFIG_MACID_SEARCH
11642 SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1); /*MACIDSearch_En*/
11643 #endif
11644
11645 #ifdef CONFIG_TX_SC
11646 SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1); /*TXSC_En*/
11647 #endif
11648
11649 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
11650 SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1); /*MURateTable_En*/
11651 #endif
11652
11653 SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);
11654
11655 #ifdef CONFIG_RTL8822C
11656 if (pwrpriv->bFwCurrentInPSMode == _FALSE) {
11657 SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);
11658 if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11659 SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);
11660 } else {
11661 SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0);
11662 if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11663 SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0);
11664 }
11665 #endif
11666
11667 #if (DBG_LPSPG_INFO_DUMP >= 1)
11668 RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);
11669 #endif
11670
11671 ret = rtw_hal_fill_h2c_cmd(adapter,
11672 H2C_LPS_PG_INFO,
11673 H2C_LPS_PG_INFO_LEN,
11674 lpspg_info);
11675 return ret;
11676 }
rtw_hal_set_lps_pg_info(_adapter * adapter)11677 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
11678 {
11679 u8 ret = _FAIL;
11680 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11681
11682 if (pwrpriv->lpspg_info.loc == 0) {
11683 RTW_ERR("%s lpspg_info.loc = 0\n", __func__);
11684 rtw_warn_on(1);
11685 return ret;
11686 }
11687 #ifdef CONFIG_RTL8822C
11688 rtw_lps_pg_set_dpk_info_rsvd_page(adapter);
11689 rtw_lps_pg_set_iqk_info_rsvd_page(adapter);
11690 #endif
11691 rtw_hal_set_lps_pg_info_rsvd_page(adapter);
11692
11693 ret = rtw_hal_set_lps_pg_info_cmd(adapter);
11694
11695 return ret;
11696 }
11697
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)11698 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
11699 {
11700 #if 0
11701 if (sta->cmn.ra_info.rssi_level >= 4)
11702 sta->lps_pg_rssi_lv = 3; /*RSSI High - 1SS_VHT_MCS7*/
11703 else if (sta->cmn.ra_info.rssi_level >= 2)
11704 sta->lps_pg_rssi_lv = 2; /*RSSI Middle - 1SS_VHT_MCS3*/
11705 else
11706 sta->lps_pg_rssi_lv = 1; /*RSSI Lower - Lowest_rate*/
11707 #else
11708 sta->lps_pg_rssi_lv = 0;
11709 #endif
11710 RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
11711 __func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
11712 }
11713
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)11714 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
11715 {
11716 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
11717 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11718 struct sta_priv *pstapriv = &adapter->stapriv;
11719 struct sta_info *sta;
11720
11721 sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
11722
11723 switch (hdl_id) {
11724 case LPS_PG_INFO_CFG:
11725 rtw_hal_set_lps_pg_info(adapter);
11726 break;
11727 case LPS_PG_REDLEMEM:
11728 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11729 break;
11730
11731 /*set xmit_block*/
11732 rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11733 if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
11734 rtw_warn_on(1);
11735 /*clearn xmit_block*/
11736 rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
11737 break;
11738 case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
11739 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11740 break;
11741
11742 if (sta)
11743 rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
11744 break;
11745 case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
11746 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
11747 break;
11748
11749 if (sta) {
11750 rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
11751 rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
11752 sta->lps_pg_rssi_lv = 0;
11753 }
11754 break;
11755
11756 default:
11757 break;
11758 }
11759 }
11760
11761 #endif /*CONFIG_LPS_PG*/
11762
_rtw_mi_assoc_if_num(_adapter * adapter)11763 static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
11764 {
11765 u8 mi_iface_num = 0;
11766
11767 if (0) {
11768 RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
11769 RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
11770 RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11771 RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
11772 RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
11773 /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
11774 /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
11775 }
11776
11777 mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
11778 DEV_AP_NUM(adapter_to_dvobj(adapter)) +
11779 DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
11780 return mi_iface_num;
11781 }
11782 #ifdef CONFIG_CONCURRENT_MODE
_rtw_search_sta_iface(_adapter * adapter)11783 static _adapter *_rtw_search_sta_iface(_adapter *adapter)
11784 {
11785 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11786 _adapter *iface = NULL;
11787 _adapter *sta_iface = NULL;
11788 int i;
11789
11790 for (i = 0; i < dvobj->iface_nums; i++) {
11791 iface = dvobj->padapters[i];
11792 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
11793 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11794 sta_iface = iface;
11795 break;
11796 }
11797 }
11798 }
11799 return sta_iface;
11800 }
11801 #if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)
_rtw_search_ap_iface(_adapter * adapter)11802 static _adapter *_rtw_search_ap_iface(_adapter *adapter)
11803 {
11804 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11805 _adapter *iface = NULL;
11806 _adapter *ap_iface = NULL;
11807 int i;
11808
11809 for (i = 0; i < dvobj->iface_nums; i++) {
11810 iface = dvobj->padapters[i];
11811 if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
11812 ap_iface = iface;
11813 break;
11814 }
11815 }
11816 return ap_iface;
11817 }
11818 #endif/*CONFIG_AP_MODE*/
11819 #endif/*CONFIG_CONCURRENT_MODE*/
11820
11821 #ifdef CONFIG_CUSTOMER01_SMART_ANTENNA
rtw_hal_set_pathb_phase(_adapter * adapter,u8 phase_idx)11822 void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)
11823 {
11824 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
11825 struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
11826
11827 return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);
11828 }
11829 #endif
11830
11831 /*
11832 * Description: Fill the reserved packets that FW will use to RSVD page.
11833 * Now we just send 4 types packet to rsvd page.
11834 * (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
11835 * Input:
11836 * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
11837 * so we need to set the packet length to total lengh.
11838 * TRUE: At the second time, we should send the first packet (default:beacon)
11839 * to Hw again and set the lengh in descriptor to the real beacon lengh.
11840 * page_num - The amount of reserved page which driver need.
11841 * If this is not NULL, this function doesn't real download reserved
11842 * page, but just count the number of reserved page.
11843 *
11844 * 2009.10.15 by tynli.
11845 * 2017.06.20 modified by Lucas.
11846 *
11847 * Page Size = 128: 8188e, 8723a/b, 8192c/d,
11848 * Page Size = 256: 8192e, 8821a
11849 * Page Size = 512: 8812a
11850 */
11851
11852 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)11853 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
11854 {
11855 PHAL_DATA_TYPE pHalData;
11856 struct xmit_frame *pcmdframe = NULL;
11857 struct pkt_attrib *pattrib;
11858 struct xmit_priv *pxmitpriv;
11859 struct pwrctrl_priv *pwrctl;
11860 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11861 u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
11862 u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
11863 u32 ProbeReqLength = 0, NullFunctionDataLength = 0;
11864 u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
11865 u8 TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
11866 u8 *ReservedPagePacket;
11867 u16 BufIndex = 0;
11868 u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
11869 RSVDPAGE_LOC RsvdPageLoc;
11870 struct registry_priv *registry_par = &adapter->registrypriv;
11871
11872 #ifdef DBG_FW_DEBUG_MSG_PKT
11873 u32 fw_dbg_msg_pkt_len = 0;
11874 #endif /*DBG_FW_DEBUG_MSG_PKT*/
11875
11876 #ifdef DBG_CONFIG_ERROR_DETECT
11877 struct sreset_priv *psrtpriv;
11878 #endif /* DBG_CONFIG_ERROR_DETECT */
11879
11880 #ifdef CONFIG_MCC_MODE
11881 u8 dl_mcc_page = _FAIL;
11882 #endif /* CONFIG_MCC_MODE */
11883 u8 nr_assoc_if;
11884
11885 _adapter *sta_iface = NULL;
11886 _adapter *ap_iface = NULL;
11887
11888 bool is_wow_mode = _FALSE;
11889
11890 pHalData = GET_HAL_DATA(adapter);
11891 #ifdef DBG_CONFIG_ERROR_DETECT
11892 psrtpriv = &pHalData->srestpriv;
11893 #endif
11894 pxmitpriv = &adapter->xmitpriv;
11895 pwrctl = adapter_to_pwrctl(adapter);
11896
11897 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
11898
11899 if (PageSize == 0) {
11900 RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
11901 return;
11902 }
11903 nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
11904
11905 if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
11906 pwrctl->wowlan_ap_mode == _TRUE ||
11907 pwrctl->wowlan_p2p_mode == _TRUE)
11908 is_wow_mode = _TRUE;
11909
11910 /*page_num for init time to get rsvd page number*/
11911 /* Prepare ReservedPagePacket */
11912 if (page_num) {
11913 ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
11914 if (!ReservedPagePacket) {
11915 RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11916 *page_num = 0xFF;
11917 return;
11918 }
11919 RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm ==>\n",
11920 FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
11921
11922 } else {
11923 if (is_wow_mode)
11924 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11925 else
11926 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11927
11928 RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
11929 FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
11930
11931 MaxRsvdPageBufSize = RsvdPageNum * PageSize;
11932 if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
11933 RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
11934 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
11935 rtw_warn_on(1);
11936 return;
11937 }
11938
11939 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
11940 if (pcmdframe == NULL) {
11941 RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
11942 return;
11943 }
11944
11945 ReservedPagePacket = pcmdframe->buf_addr;
11946 }
11947
11948 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
11949
11950 BufIndex = TxDescOffset;
11951
11952 /*======== beacon content =======*/
11953 rtw_hal_construct_beacon(adapter,
11954 &ReservedPagePacket[BufIndex], &BeaconLength);
11955
11956 /*
11957 * When we count the first page size, we need to reserve description size for the RSVD
11958 * packet, it will be filled in front of the packet in TXPKTBUF.
11959 */
11960 BeaconLength = MAX_BEACON_LEN - TxDescLen;
11961 CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
11962
11963 #if defined(CONFIG_FW_HANDLE_TXBCN) || defined(CONFIG_PORT_BASED_TXBCN)
11964 CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
11965 #endif
11966 TotalPageNum += CurtPktPageNum;
11967
11968 BufIndex += (CurtPktPageNum * PageSize);
11969
11970 RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11971
11972 /*======== probe response content ========*/
11973 if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
11974 #ifdef CONFIG_CONCURRENT_MODE
11975 if (nr_assoc_if >= 2)
11976 RTW_ERR("Not support > 2 net-interface in WOW\n");
11977 #endif
11978 /* (4) probe response*/
11979 RsvdPageLoc.LocProbeRsp = TotalPageNum;
11980 rtw_hal_construct_ProbeRsp(
11981 adapter, &ReservedPagePacket[BufIndex],
11982 &ProbeRspLength,
11983 _FALSE);
11984 rtw_hal_fill_fake_txdesc(adapter,
11985 &ReservedPagePacket[BufIndex - TxDescLen],
11986 ProbeRspLength, _FALSE, _FALSE, _FALSE);
11987
11988 CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
11989 TotalPageNum += CurtPktPageNum;
11990 TotalPacketLen = BufIndex + ProbeRspLength;
11991 BufIndex += (CurtPktPageNum * PageSize);
11992 RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
11993 goto download_page;
11994 }
11995
11996 /*======== ps-poll content * 1 page ========*/
11997 sta_iface = adapter;
11998 #ifdef CONFIG_CONCURRENT_MODE
11999 if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
12000 sta_iface = _rtw_search_sta_iface(adapter);
12001 RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
12002 }
12003 #endif
12004
12005 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12006 RsvdPageLoc.LocPsPoll = TotalPageNum;
12007 RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
12008 rtw_hal_construct_PSPoll(sta_iface,
12009 &ReservedPagePacket[BufIndex], &PSPollLength);
12010 rtw_hal_fill_fake_txdesc(sta_iface,
12011 &ReservedPagePacket[BufIndex - TxDescLen],
12012 PSPollLength, _TRUE, _FALSE, _FALSE);
12013
12014 CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
12015
12016 TotalPageNum += CurtPktPageNum;
12017
12018 BufIndex += (CurtPktPageNum * PageSize);
12019 RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12020 }
12021
12022 #ifdef CONFIG_MCC_MODE
12023 /*======== MCC * n page ======== */
12024 if (MCC_EN(adapter)) {/*Normal mode*/
12025 dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
12026 &BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
12027 } else {
12028 dl_mcc_page = _FAIL;
12029 }
12030
12031 if (dl_mcc_page == _FAIL)
12032 #endif /* CONFIG_MCC_MODE */
12033 { /*======== null data * 1 page ======== */
12034 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12035 RsvdPageLoc.LocNullData = TotalPageNum;
12036 RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
12037 rtw_hal_construct_NullFunctionData(
12038 sta_iface,
12039 &ReservedPagePacket[BufIndex],
12040 &NullDataLength,
12041 _FALSE, 0, 0, _FALSE);
12042 rtw_hal_fill_fake_txdesc(sta_iface,
12043 &ReservedPagePacket[BufIndex - TxDescLen],
12044 NullDataLength, _FALSE, _FALSE, _FALSE);
12045
12046 CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
12047
12048 TotalPageNum += CurtPktPageNum;
12049
12050 BufIndex += (CurtPktPageNum * PageSize);
12051 RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12052 }
12053 }
12054
12055 /*======== Qos null data * 1 page ======== */
12056 if (pwrctl->wowlan_mode == _FALSE ||
12057 pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
12058 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12059 RsvdPageLoc.LocQosNull = TotalPageNum;
12060 RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
12061 rtw_hal_construct_NullFunctionData(sta_iface,
12062 &ReservedPagePacket[BufIndex],
12063 &QosNullLength,
12064 _TRUE, 0, 0, _FALSE);
12065 rtw_hal_fill_fake_txdesc(sta_iface,
12066 &ReservedPagePacket[BufIndex - TxDescLen],
12067 QosNullLength, _FALSE, _FALSE, _FALSE);
12068
12069 CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
12070 PageSize);
12071
12072 TotalPageNum += CurtPktPageNum;
12073
12074 BufIndex += (CurtPktPageNum * PageSize);
12075 RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12076 }
12077 }
12078
12079 #ifdef CONFIG_BT_COEXIST
12080 /*======== BT Qos null data * 1 page ======== */
12081 if (pwrctl->wowlan_mode == _FALSE ||
12082 pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
12083
12084 ap_iface = adapter;
12085 #if defined (CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
12086 if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) { /*DEV_AP_STARTING_NUM*/
12087 ap_iface = _rtw_search_ap_iface(adapter);
12088 RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
12089 }
12090 #endif
12091
12092 if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
12093 RsvdPageLoc.LocBTQosNull = TotalPageNum;
12094
12095 RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
12096
12097 rtw_hal_construct_NullFunctionData(ap_iface,
12098 &ReservedPagePacket[BufIndex],
12099 &BTQosNullLength,
12100 _TRUE, 0, 0, _FALSE);
12101
12102 rtw_hal_fill_fake_txdesc(ap_iface,
12103 &ReservedPagePacket[BufIndex - TxDescLen],
12104 BTQosNullLength, _FALSE, _TRUE, _FALSE);
12105
12106 CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
12107 PageSize);
12108
12109 TotalPageNum += CurtPktPageNum;
12110 BufIndex += (CurtPktPageNum * PageSize);
12111
12112 RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12113 }
12114 }
12115 #endif /* CONFIG_BT_COEXIT */
12116
12117 TotalPacketLen = BufIndex;
12118
12119 #ifdef DBG_FW_DEBUG_MSG_PKT
12120 /*======== FW DEBUG MSG * n page ======== */
12121 RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
12122 RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
12123 rtw_hal_construct_fw_dbg_msg_pkt(
12124 adapter,
12125 &ReservedPagePacket[BufIndex],
12126 &fw_dbg_msg_pkt_len);
12127
12128 rtw_hal_fill_fake_txdesc(adapter,
12129 &ReservedPagePacket[BufIndex - TxDescLen],
12130 fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
12131
12132 CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
12133
12134 if (CurtPktPageNum < 2)
12135 CurtPktPageNum = 2; /*Need at least 2 rsvd page*/
12136 TotalPageNum += CurtPktPageNum;
12137
12138 TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
12139 BufIndex += (CurtPktPageNum * PageSize);
12140 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12141
12142 #ifdef CONFIG_LPS_PG
12143 rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex
12144 , TxDescLen, PageSize, &TotalPageNum, is_wow_mode
12145 , (sta_iface && MLME_IS_STA(sta_iface) && MLME_IS_ASOC(sta_iface)) ? sta_iface : NULL
12146 , page_num ? 1 : 0
12147 );
12148 TotalPacketLen = BufIndex;
12149 #endif
12150
12151 #ifdef CONFIG_WOWLAN
12152 /*======== WOW * n page ======== */
12153 if (pwrctl->wowlan_mode == _TRUE &&
12154 pwrctl->wowlan_in_resume == _FALSE &&
12155 check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {/*WOW mode*/
12156 rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
12157 BufIndex, TxDescLen, PageSize,
12158 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
12159 #ifdef CONFIG_WAR_OFFLOAD
12160 rtw_hal_set_war_offload_parm(adapter, &RsvdPageLoc);
12161 #endif /* CONFIG_WAR_OFFLOAD */
12162 }
12163 #endif /* CONFIG_WOWLAN */
12164
12165 #ifdef CONFIG_P2P_WOWLAN
12166 /*======== P2P WOW * n page ======== */
12167 if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
12168 rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
12169 BufIndex, TxDescLen, PageSize,
12170 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
12171 }
12172 #endif /* CONFIG_P2P_WOWLAN */
12173
12174 /*Note: BufIndex already add a TxDescOffset offset in first Beacon page
12175 * The "TotalPacketLen" is calculate by BufIndex.
12176 * We need to decrease TxDescOffset before doing length check. by yiwei
12177 */
12178 TotalPacketLen = TotalPacketLen - TxDescOffset;
12179
12180 download_page:
12181 if (page_num) {
12182 *page_num = TotalPageNum;
12183 rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
12184 ReservedPagePacket = NULL;
12185 RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
12186 FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
12187 return;
12188 }
12189
12190 /* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
12191 RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
12192 __func__, TotalPageNum, TotalPacketLen);
12193
12194 if (TotalPacketLen > MaxRsvdPageBufSize) {
12195 RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
12196 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
12197 rtw_warn_on(1);
12198 goto error;
12199 } else {
12200 /* update attribute */
12201 pattrib = &pcmdframe->attrib;
12202 update_mgntframe_attrib(adapter, pattrib);
12203 pattrib->qsel = QSLT_BEACON;
12204 pattrib->pktlen = TotalPacketLen;
12205 pattrib->last_txcmdsz = TotalPacketLen;
12206 #ifdef CONFIG_PCI_HCI
12207 dump_mgntframe(adapter, pcmdframe);
12208 #else
12209 dump_mgntframe_and_wait(adapter, pcmdframe, 100);
12210 #endif
12211 }
12212
12213 RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
12214 __func__, TotalPacketLen, TotalPageNum);
12215 #ifdef DBG_DUMP_SET_RSVD_PAGE
12216 RTW_INFO(" ==================================================\n");
12217 RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
12218 RTW_INFO(" ==================================================\n");
12219 #endif
12220
12221
12222 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
12223 || MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
12224 rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
12225 #ifdef DBG_FW_DEBUG_MSG_PKT
12226 rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
12227 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12228 #ifdef CONFIG_WOWLAN
12229 if (pwrctl->wowlan_mode == _TRUE &&
12230 pwrctl->wowlan_in_resume == _FALSE)
12231 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
12232 #endif /* CONFIG_WOWLAN */
12233 #ifdef CONFIG_AP_WOWLAN
12234 if (pwrctl->wowlan_ap_mode == _TRUE)
12235 rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
12236 #endif /* CONFIG_AP_WOWLAN */
12237 } else if (pwrctl->wowlan_pno_enable) {
12238 #ifdef CONFIG_PNO_SUPPORT
12239 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
12240 if (pwrctl->wowlan_in_resume)
12241 rtw_hal_set_scan_offload_info_cmd(adapter,
12242 &RsvdPageLoc, 0);
12243 else
12244 rtw_hal_set_scan_offload_info_cmd(adapter,
12245 &RsvdPageLoc, 1);
12246 #endif /* CONFIG_PNO_SUPPORT */
12247 }
12248
12249 #ifdef CONFIG_P2P_WOWLAN
12250 if (_TRUE == pwrctl->wowlan_p2p_mode)
12251 rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
12252 #endif /* CONFIG_P2P_WOWLAN */
12253
12254 return;
12255 error:
12256 rtw_free_xmitframe(pxmitpriv, pcmdframe);
12257 }
12258
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)12259 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
12260 {
12261 #ifdef CONFIG_AP_MODE
12262 if (finished)
12263 rtw_mi_tx_beacon_hdl(adapter);
12264 else
12265 #endif
12266 _rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
12267 }
12268
rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER * adapter,u8 enable)12269 static u8 rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER *adapter, u8 enable)
12270 {
12271 u8 u1H2CSetPwrMode[H2C_PWRMODE_LEN] = {0};
12272 u8 ret = _FAIL;
12273
12274 #ifdef CONFIG_TDLS
12275 #ifdef CONFIG_TDLS_CH_SW
12276 if (ATOMIC_READ(&adapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12277 {
12278 SET_H2CCMD_PWRMODE_PARM_RLBM(u1H2CSetPwrMode, 1);
12279 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CSetPwrMode, 0);
12280 }
12281 #endif
12282 #endif
12283
12284 SET_H2CCMD_PWRMODE_PARM_MODE(u1H2CSetPwrMode, 0);
12285 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CSetPwrMode, 0x0C);
12286 SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_C2H_RPT(u1H2CSetPwrMode, enable);
12287
12288 ret = rtw_hal_fill_h2c_cmd(adapter,
12289 H2C_SET_PWR_MODE,
12290 H2C_PWRMODE_LEN,
12291 u1H2CSetPwrMode);
12292
12293 RTW_PRINT("-%s()-\n", __func__);
12294
12295 return ret;
12296 }
12297
12298 /**
12299 * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
12300 * @adapter: struct _ADAPTER*
12301 *
12302 * Caculate needed reserved page number.
12303 * In different state would get different number, for example normal mode and
12304 * WOW mode would need different reserved page size.
12305 *
12306 * Return the number of reserved page which driver need.
12307 */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)12308 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
12309 {
12310 u8 num = 0;
12311
12312
12313 _rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
12314
12315 return num;
12316 }
12317
12318 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
hw_var_set_bcn_func(_adapter * adapter,u8 enable)12319 static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
12320 {
12321 u32 bcn_ctrl_reg;
12322
12323 #ifdef CONFIG_CONCURRENT_MODE
12324 if (adapter->hw_port == HW_PORT1)
12325 bcn_ctrl_reg = REG_BCN_CTRL_1;
12326 else
12327 #endif
12328 bcn_ctrl_reg = REG_BCN_CTRL;
12329
12330 if (enable)
12331 rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
12332 else {
12333 u8 val8;
12334
12335 val8 = rtw_read8(adapter, bcn_ctrl_reg);
12336 val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
12337
12338 #ifdef CONFIG_BT_COEXIST
12339 if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
12340 /* Always enable port0 beacon function for PSTDMA */
12341 if (REG_BCN_CTRL == bcn_ctrl_reg)
12342 val8 |= EN_BCN_FUNCTION;
12343 }
12344 #endif
12345
12346 rtw_write8(adapter, bcn_ctrl_reg, val8);
12347 }
12348
12349 #ifdef CONFIG_RTL8192F
12350 if (IS_HARDWARE_TYPE_8192F(adapter)) {
12351 u16 val16, val16_ori;
12352
12353 val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
12354
12355 #ifdef CONFIG_CONCURRENT_MODE
12356 if (adapter->hw_port == HW_PORT1) {
12357 if (enable)
12358 val16 |= EN_PORT_1_FUNCTION;
12359 else
12360 val16 &= ~EN_PORT_1_FUNCTION;
12361 } else
12362 #endif
12363 {
12364 if (enable)
12365 val16 |= EN_PORT_0_FUNCTION;
12366 else
12367 val16 &= ~EN_PORT_0_FUNCTION;
12368
12369 #ifdef CONFIG_BT_COEXIST
12370 if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
12371 val16 |= EN_PORT_0_FUNCTION;
12372 #endif
12373 }
12374
12375 if (val16 != val16_ori)
12376 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, val16);
12377 }
12378 #endif
12379 }
12380 #endif
12381
12382 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
hw_var_set_mlme_disconnect(_adapter * adapter)12383 static void hw_var_set_mlme_disconnect(_adapter *adapter)
12384 {
12385 u8 val8;
12386
12387 /* reject all data frames */
12388 #ifdef CONFIG_CONCURRENT_MODE
12389 if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
12390 #endif
12391 rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
12392
12393 #ifdef CONFIG_CONCURRENT_MODE
12394 if (adapter->hw_port == HW_PORT1) {
12395 /* reset TSF1 */
12396 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
12397
12398 /* disable update TSF1 */
12399 rtw_iface_disable_tsf_update(adapter);
12400
12401 if (!IS_HARDWARE_TYPE_8723D(adapter)
12402 && !IS_HARDWARE_TYPE_8192F(adapter)
12403 && !IS_HARDWARE_TYPE_8710B(adapter)
12404 ) {
12405 /* disable Port1's beacon function */
12406 val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
12407 val8 &= ~EN_BCN_FUNCTION;
12408 rtw_write8(adapter, REG_BCN_CTRL_1, val8);
12409 }
12410 } else
12411 #endif
12412 {
12413 /* reset TSF */
12414 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
12415
12416 /* disable update TSF */
12417 rtw_iface_disable_tsf_update(adapter);
12418 }
12419 }
12420 #endif
12421
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 enable)12422 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
12423 {
12424 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12425 u16 value_rxfltmap2;
12426
12427 #ifdef DBG_IFACE_STATUS
12428 DBG_IFACE_STATUS_DUMP(adapter);
12429 #endif
12430
12431 #ifdef CONFIG_FIND_BEST_CHANNEL
12432 /* Receive all data frames */
12433 value_rxfltmap2 = 0xFFFF;
12434 #else
12435 /* not to receive data frame */
12436 value_rxfltmap2 = 0;
12437 #endif
12438
12439 if (enable) { /* under sitesurvey */
12440 /*
12441 * 1. configure REG_RXFLTMAP2
12442 * 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
12443 * 3. config RCR to receive different BSSID BCN or probe rsp
12444 */
12445 rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
12446
12447 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
12448
12449 /* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */
12450 #if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
12451 hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);
12452 hal_data->RegRRSR &= 0x000FFFFF;
12453 #endif
12454
12455 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
12456 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
12457 /* set 718[1:0]=2'b00 to avoid BF scan hang */
12458 hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
12459 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
12460 }
12461 #endif
12462
12463 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12464 StopTxBeacon(adapter);
12465 } else { /* sitesurvey done */
12466 /*
12467 * 1. enable rx data frame
12468 * 2. config RCR not to receive different BSSID BCN or probe rsp
12469 * 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict
12470 * so, we enable TSF update when rx first BCN after sitesurvey done
12471 */
12472 if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) {
12473 /* enable to rx data frame */
12474 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12475 }
12476
12477 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
12478
12479 /* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */
12480 #if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
12481 rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);
12482 #endif
12483
12484 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
12485 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
12486 /* Restore orignal 0x718 setting*/
12487 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
12488 }
12489 #endif
12490
12491 #ifdef CONFIG_AP_MODE
12492 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12493 ResumeTxBeacon(adapter);
12494 rtw_mi_tx_beacon_hdl(adapter);
12495 }
12496 #endif
12497 }
12498 }
12499
12500 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
hw_var_set_mlme_join(_adapter * adapter,u8 type)12501 static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
12502 {
12503 u8 val8;
12504 u16 val16;
12505 u32 val32;
12506 u8 RetryLimit = RL_VAL_STA;
12507 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12508 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12509
12510 #ifdef CONFIG_CONCURRENT_MODE
12511 if (type == 0) {
12512 /* prepare to join */
12513 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12514 StopTxBeacon(adapter);
12515
12516 /* enable to rx data frame.Accept all data frame */
12517 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12518
12519 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
12520 RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
12521 else /* Ad-hoc Mode */
12522 RetryLimit = RL_VAL_AP;
12523
12524 rtw_iface_enable_tsf_update(adapter);
12525
12526 } else if (type == 1) {
12527 /* joinbss_event call back when join res < 0 */
12528 if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
12529 rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
12530
12531 rtw_iface_disable_tsf_update(adapter);
12532
12533 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12534 ResumeTxBeacon(adapter);
12535
12536 /* reset TSF 1/2 after ResumeTxBeacon */
12537 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
12538 }
12539
12540 } else if (type == 2) {
12541 /* sta add event call back */
12542 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
12543 /* fixed beacon issue for 8191su........... */
12544 rtw_write8(adapter, 0x542 , 0x02);
12545 RetryLimit = RL_VAL_AP;
12546 }
12547
12548 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12549 ResumeTxBeacon(adapter);
12550
12551 /* reset TSF 1/2 after ResumeTxBeacon */
12552 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
12553 }
12554 }
12555
12556 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
12557 rtw_write16(adapter, REG_RETRY_LIMIT, val16);
12558 #else /* !CONFIG_CONCURRENT_MODE */
12559 if (type == 0) { /* prepare to join */
12560 /* enable to rx data frame.Accept all data frame */
12561 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12562
12563 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
12564 RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
12565 else /* Ad-hoc Mode */
12566 RetryLimit = RL_VAL_AP;
12567
12568 rtw_iface_enable_tsf_update(adapter);
12569
12570 } else if (type == 1) { /* joinbss_event call back when join res < 0 */
12571 rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
12572
12573 rtw_iface_disable_tsf_update(adapter);
12574
12575 } else if (type == 2) { /* sta add event call back */
12576 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
12577 RetryLimit = RL_VAL_AP;
12578 }
12579
12580 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
12581 rtw_write16(adapter, REG_RETRY_LIMIT, val16);
12582 #endif /* !CONFIG_CONCURRENT_MODE */
12583 }
12584 #endif
12585
12586 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)12587 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
12588 {
12589 u8 buf[2];
12590 int ret;
12591
12592 if (reset_port == HW_PORT0) {
12593 buf[0] = 0x1;
12594 buf[1] = 0;
12595 } else {
12596 buf[0] = 0x0;
12597 buf[1] = 0x1;
12598 }
12599
12600 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
12601
12602 return ret;
12603 }
12604
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)12605 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
12606 {
12607 u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
12608 u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
12609 REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
12610 int ret;
12611
12612 /* site survey will cause reset tsf fail */
12613 rtw_mi_buddy_scan_abort(adapter, _FALSE);
12614 reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
12615 ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
12616 if (ret != _SUCCESS)
12617 return ret;
12618
12619 while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
12620 rtw_msleep_os(100);
12621 loop_cnt++;
12622 reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
12623 }
12624
12625 return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
12626 }
12627 #endif /* CONFIG_TSF_RESET_OFFLOAD */
12628
12629 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
12630 #ifdef CONFIG_HW_P0_TSF_SYNC
12631 #ifdef CONFIG_CONCURRENT_MODE
hw_port0_tsf_sync_sel(_adapter * adapter,u8 benable,u8 hw_port,u16 tr_offset)12632 static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
12633 {
12634 u8 val8;
12635 u8 client_id = 0;
12636 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12637
12638 #ifdef CONFIG_MCC_MODE
12639 if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
12640 RTW_INFO("[MCC] do not set HW TSF sync\n");
12641 return;
12642 }
12643 #endif
12644 /* check if port0 is already synced */
12645 if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
12646 RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
12647 FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
12648 return;
12649 }
12650
12651 /* check if port0 already disable sync */
12652 if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
12653 RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
12654 return;
12655 }
12656
12657 /* check if port0 sync to port0 */
12658 if (benable && hw_port == HW_PORT0) {
12659 RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
12660 rtw_warn_on(1);
12661 return;
12662 }
12663
12664 /*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
12665 /* Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
12666 Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
12667
12668 val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
12669
12670 if (benable) {
12671 /*Disable Port0's beacon function*/
12672 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
12673
12674 /*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
12675 if (tr_offset)
12676 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
12677
12678 /*reg 0x577[6]=1*/ /*auto sync by tbtt*/
12679 rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
12680
12681 if (HW_PORT1 == hw_port)
12682 client_id = 0;
12683 else if (HW_PORT2 == hw_port)
12684 client_id = 1;
12685 else if (HW_PORT3 == hw_port)
12686 client_id = 2;
12687 else if (HW_PORT4 == hw_port)
12688 client_id = 3;
12689
12690 val8 &= 0x8F;
12691 val8 |= (BIT(6) | (client_id << 4));
12692
12693 dvobj->p0_tsf.sync_port = hw_port;
12694 dvobj->p0_tsf.offset = tr_offset;
12695 rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12696
12697 /*Enable Port0's beacon function*/
12698 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) | BIT_EN_BCN_FUNCTION);
12699 RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
12700 } else {
12701 val8 &= ~BIT(6);
12702
12703 dvobj->p0_tsf.sync_port = MAX_HW_PORT;
12704 dvobj->p0_tsf.offset = 0;
12705 rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
12706 RTW_INFO("%s P0 TSF sync disable\n", __func__);
12707 }
12708 }
_search_ld_sta(_adapter * adapter,u8 include_self)12709 static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
12710 {
12711 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12712 u8 i;
12713 _adapter *iface = NULL;
12714
12715 if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
12716 RTW_ERR("STA_LD_NUM == 0\n");
12717 rtw_warn_on(1);
12718 }
12719
12720 for (i = 0; i < dvobj->iface_nums; i++) {
12721 iface = dvobj->padapters[i];
12722 if (!iface)
12723 continue;
12724 if (include_self == _FALSE && adapter == iface)
12725 continue;
12726 if (is_client_associated_to_ap(iface))
12727 break;
12728 }
12729 if (iface)
12730 RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
12731 return iface;
12732 }
12733 #endif /*CONFIG_CONCURRENT_MODE*/
12734 /*Correct port0's TSF*/
12735 /*#define DBG_P0_TSF_SYNC*/
hw_var_set_correct_tsf(PADAPTER adapter,u8 mlme_state)12736 void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
12737 {
12738 #ifdef CONFIG_CONCURRENT_MODE
12739 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12740 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12741 _adapter *sta_if = NULL;
12742 u8 hw_port;
12743
12744 RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
12745 #ifdef DBG_P0_TSF_SYNC
12746 RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
12747 RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
12748 RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
12749 if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12750 RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
12751 else
12752 RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12753 RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12754 #endif
12755 switch (mlme_state) {
12756 case MLME_STA_CONNECTED :
12757 {
12758 hw_port = rtw_hal_get_port(adapter);
12759
12760 if (!MLME_IS_STA(adapter)) {
12761 RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12762 rtw_warn_on(1);
12763 }
12764
12765 if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
12766 RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
12767 rtw_warn_on(1);
12768 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12769 }
12770
12771 if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12772 (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
12773 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12774 #ifdef DBG_P0_TSF_SYNC
12775 RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
12776 #endif
12777 }
12778 }
12779 break;
12780 case MLME_STA_DISCONNECTED :
12781 {
12782 hw_port = rtw_hal_get_port(adapter);
12783
12784 if (!MLME_IS_STA(adapter)) {
12785 RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
12786 rtw_warn_on(1);
12787 }
12788
12789 if (dvobj->p0_tsf.sync_port == hw_port) {
12790 if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
12791 /* search next appropriate sta*/
12792 sta_if = _search_ld_sta(adapter, _FALSE);
12793 if (sta_if) {
12794 hw_port = rtw_hal_get_port(sta_if);
12795 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12796 #ifdef DBG_P0_TSF_SYNC
12797 RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
12798 #endif
12799 }
12800 } else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
12801 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12802 #ifdef DBG_P0_TSF_SYNC
12803 RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
12804 #endif
12805 }
12806 }
12807 }
12808 break;
12809 #ifdef CONFIG_AP_MODE
12810 case MLME_AP_STARTED :
12811 case MLME_MESH_STARTED :
12812 {
12813 if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12814 RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12815 rtw_warn_on(1);
12816 }
12817
12818 if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
12819 rtw_mi_get_assoced_sta_num(adapter)) {
12820 /* get port of sta */
12821 sta_if = _search_ld_sta(adapter, _FALSE);
12822 if (sta_if) {
12823 hw_port = rtw_hal_get_port(sta_if);
12824 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
12825 #ifdef DBG_P0_TSF_SYNC
12826 RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
12827 #endif
12828 }
12829 }
12830 }
12831 break;
12832 case MLME_AP_STOPPED :
12833 case MLME_MESH_STOPPED :
12834 {
12835 if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
12836 RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
12837 rtw_warn_on(1);
12838 }
12839 /*stop ap mode*/
12840 if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
12841 (dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
12842 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
12843 #ifdef DBG_P0_TSF_SYNC
12844 RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
12845 #endif
12846 }
12847 }
12848 break;
12849 #endif /* CONFIG_AP_MODE */
12850 default :
12851 RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
12852 break;
12853 }
12854
12855 /*#ifdef DBG_P0_TSF_SYNC*/
12856 #if 1
12857 if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
12858 RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
12859 else
12860 RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
12861 RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
12862 #endif
12863 #endif /*CONFIG_CONCURRENT_MODE*/
12864 }
12865
12866 #else /*! CONFIG_HW_P0_TSF_SYNC*/
12867
12868 #ifdef CONFIG_MI_WITH_MBSSID_CAM
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12869 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12870 {
12871 /*do nothing*/
12872 }
12873 #else /* !CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)12874 static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
12875 {
12876 if (hw_port == HW_PORT0) {
12877 /*disable related TSF function*/
12878 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
12879 #if defined(CONFIG_RTL8192F)
12880 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12881 REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
12882 #endif
12883
12884 rtw_write32(padapter, REG_TSFTR, tsf);
12885 rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
12886
12887 /*enable related TSF function*/
12888 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
12889 #if defined(CONFIG_RTL8192F)
12890 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12891 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
12892 #endif
12893 } else if (hw_port == HW_PORT1) {
12894 /*disable related TSF function*/
12895 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
12896 #if defined(CONFIG_RTL8192F)
12897 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12898 REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);
12899 #endif
12900
12901 rtw_write32(padapter, REG_TSFTR1, tsf);
12902 rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
12903
12904 /*enable related TSF function*/
12905 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
12906 #if defined(CONFIG_RTL8192F)
12907 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
12908 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
12909 #endif
12910 } else
12911 RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
12912 }
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)12913 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
12914 {
12915 u64 tsf;
12916 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
12917 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
12918
12919 tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
12920
12921 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12922 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12923 StopTxBeacon(adapter);
12924
12925 rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
12926
12927 #ifdef CONFIG_CONCURRENT_MODE
12928 /* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
12929 if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
12930 && (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12931 ) {
12932 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12933 int i;
12934 _adapter *iface;
12935
12936 for (i = 0; i < dvobj->iface_nums; i++) {
12937 iface = dvobj->padapters[i];
12938 if (!iface)
12939 continue;
12940 if (iface == adapter)
12941 continue;
12942
12943 #ifdef CONFIG_AP_MODE
12944 if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
12945 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
12946 ) {
12947 rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
12948 #ifdef CONFIG_TSF_RESET_OFFLOAD
12949 if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
12950 RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
12951 , __func__, ADPT_ARG(iface), iface->hw_port);
12952 #endif /* CONFIG_TSF_RESET_OFFLOAD*/
12953 }
12954 #endif /* CONFIG_AP_MODE */
12955 }
12956 }
12957 #endif /* CONFIG_CONCURRENT_MODE */
12958 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
12959 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
12960 ResumeTxBeacon(adapter);
12961 }
12962 #endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
12963 #endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/
12964 #endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/
12965
rtw_hal_get_tsftr_by_port(_adapter * adapter,u8 port)12966 u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
12967 {
12968 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
12969 u64 tsftr = 0;
12970
12971 if (port >= hal_spec->port_num) {
12972 RTW_ERR("%s invalid port(%d) \n", __func__, port);
12973 goto exit;
12974 }
12975
12976 switch (rtw_get_chip_type(adapter)) {
12977 #if defined(CONFIG_RTL8814B)
12978 case RTL8814B:
12979 {
12980 u8 val8;
12981
12982 /* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */
12983 val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);
12984 val8 &= ~0x70;
12985 val8 |= port << 4;
12986 rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);
12987
12988 tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);
12989 tsftr = tsftr << 32;
12990 tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);
12991
12992 break;
12993 }
12994 #endif
12995 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
12996 case RTL8814A:
12997 case RTL8822B:
12998 case RTL8821C:
12999 case RTL8822C:
13000 {
13001 u8 val8;
13002
13003 /* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
13004 val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
13005 val8 &= 0x8F;
13006 val8 |= port << 4;
13007 rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
13008
13009 tsftr = rtw_read32(adapter, REG_TSFTR + 4);
13010 tsftr = tsftr << 32;
13011 tsftr |= rtw_read32(adapter, REG_TSFTR);
13012
13013 break;
13014 }
13015 #endif
13016 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
13017 || defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
13018 || defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
13019 || defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
13020 || defined(CONFIG_RTL8710B)
13021 case RTL8188E:
13022 case RTL8188F:
13023 case RTL8188GTV:
13024 case RTL8192E:
13025 case RTL8192F:
13026 case RTL8723B:
13027 case RTL8703B:
13028 case RTL8723D:
13029 case RTL8812:
13030 case RTL8821:
13031 case RTL8710B:
13032 {
13033 u32 addr;
13034
13035 if (port == HW_PORT0)
13036 addr = REG_TSFTR;
13037 else if (port == HW_PORT1)
13038 addr = REG_TSFTR1;
13039 else {
13040 RTW_ERR("%s unknown port(%d) \n", __func__, port);
13041 goto exit;
13042 }
13043
13044 tsftr = rtw_read32(adapter, addr + 4);
13045 tsftr = tsftr << 32;
13046 tsftr |= rtw_read32(adapter, addr);
13047
13048 break;
13049 }
13050 #endif
13051 default:
13052 RTW_ERR("%s unknow chip type\n", __func__);
13053 }
13054
13055 exit:
13056 return tsftr;
13057 }
13058
13059 #ifdef CONFIG_TDLS
13060 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)13061 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
13062 {
13063 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
13064 u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
13065
13066
13067 SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
13068 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
13069 switch (bwmode) {
13070 case CHANNEL_WIDTH_40:
13071 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
13072 break;
13073 case CHANNEL_WIDTH_80:
13074 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
13075 break;
13076 case CHANNEL_WIDTH_20:
13077 default:
13078 break;
13079 }
13080 SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
13081
13082 return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
13083 }
13084 #endif
13085 #endif
13086
13087 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)13088 void rtw_hal_update_uapsd_tid(_adapter *adapter)
13089 {
13090 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
13091 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
13092
13093 /* write complement of pqospriv->uapsd_tid to mac register 0x693 because
13094 it's designed for "0" represents "enable" and "1" represents "disable" */
13095 rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
13096 }
13097 #endif /* CONFIG_WMMPS_STA */
13098
13099 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
13100 /* 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)13101 s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
13102 {
13103 u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
13104 u8 hw_port = rtw_hal_get_port(adapter);
13105
13106 SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
13107 RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
13108 return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
13109 }
13110 #endif
13111
13112 #define LPS_ACTIVE_TIMEOUT 50 /*number of times*/
rtw_lps_state_chk(_adapter * adapter,u8 ps_mode)13113 void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
13114 {
13115 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
13116 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13117 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13118 struct sta_priv *pstapriv = &adapter->stapriv;
13119 struct sta_info *psta = NULL;
13120 u8 ps_ready = _FALSE;
13121 s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
13122
13123 if (ps_mode == PS_MODE_ACTIVE) {
13124 #ifdef CONFIG_LPS_ACK
13125 if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {
13126 if (pwrpriv->lps_ack_status > 0) {
13127 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
13128 if (psta != NULL) {
13129 if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)
13130 RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));
13131 }
13132 }
13133 } else {
13134 RTW_WARN("LPS sctx query timeout, operation abort!!\n");
13135 return;
13136 }
13137 pwrpriv->lps_ack_status = -1;
13138 #else
13139 do {
13140 if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
13141 ps_ready = _TRUE;
13142 break;
13143 }
13144 rtw_msleep_os(1);
13145 } while (leave_wait_count--);
13146
13147 if (ps_ready == _FALSE) {
13148 RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));
13149 return;
13150 }
13151 #endif /* CONFIG_LPS_ACK */
13152 }
13153 }
13154
rtw_var_set_basic_rate(PADAPTER padapter,u8 * val)13155 void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {
13156
13157 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
13158 struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
13159 u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
13160 u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
13161 u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
13162 #if CONFIG_IEEE80211_BAND_5GHZ
13163 u16 rrsr_5g_force_mask = (RRSR_6M);
13164 u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);
13165 #endif
13166 u32 temp_RRSR;
13167
13168 HalSetBrateCfg(padapter, val, &BrateCfg);
13169 input_b = BrateCfg;
13170
13171 /* apply force and allow mask */
13172 #if CONFIG_IEEE80211_BAND_5GHZ
13173 if (pHalData->current_band_type != BAND_ON_2_4G) {
13174 BrateCfg |= rrsr_5g_force_mask;
13175 BrateCfg &= rrsr_5g_allow_mask;
13176 } else
13177 #endif
13178 { /* 2.4G */
13179 BrateCfg |= rrsr_2g_force_mask;
13180 BrateCfg &= rrsr_2g_allow_mask;
13181 }
13182 masked = BrateCfg;
13183
13184 #ifdef CONFIG_CMCC_TEST
13185 BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
13186 BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */
13187 #endif
13188
13189 /* IOT consideration */
13190 if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
13191 /* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
13192 if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
13193 BrateCfg |= RRSR_6M;
13194 }
13195 ioted = BrateCfg;
13196
13197 #ifdef CONFIG_NARROWBAND_SUPPORTING
13198 if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
13199 || (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {
13200 BrateCfg &= ~RRSR_CCK_RATES;
13201 BrateCfg |= RRSR_6M;
13202 }
13203 #endif
13204 pHalData->BasicRateSet = BrateCfg;
13205
13206 RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
13207
13208 /* Set RRSR rate table. */
13209 temp_RRSR = rtw_read32(padapter, REG_RRSR);
13210 temp_RRSR &=0xFFFF0000;
13211 temp_RRSR |=BrateCfg;
13212 rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);
13213
13214 rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
13215
13216 #if defined(CONFIG_RTL8188E)
13217 rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
13218 #endif
13219 }
13220
SetHwReg(_adapter * adapter,u8 variable,u8 * val)13221 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
13222 {
13223 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13224 u8 ret = _SUCCESS;
13225
13226 switch (variable) {
13227 case HW_VAR_MEDIA_STATUS: {
13228 u8 net_type = *((u8 *)val);
13229
13230 rtw_hal_set_msr(adapter, net_type);
13231 }
13232 break;
13233 case HW_VAR_DO_IQK:
13234 if (*val)
13235 hal_data->bNeedIQK = _TRUE;
13236 else
13237 hal_data->bNeedIQK = _FALSE;
13238 break;
13239 case HW_VAR_MAC_ADDR:
13240 #ifdef CONFIG_MI_WITH_MBSSID_CAM
13241 rtw_hal_set_macaddr_mbid(adapter, val);
13242 #else
13243 rtw_hal_set_macaddr_port(adapter, val);
13244 #endif
13245 break;
13246 case HW_VAR_BSSID:
13247 rtw_hal_set_bssid(adapter, val);
13248 break;
13249 case HW_VAR_RCR:
13250 ret = hw_var_rcr_config(adapter, *((u32 *)val));
13251 break;
13252 case HW_VAR_ON_RCR_AM:
13253 hw_var_set_rcr_am(adapter, 1);
13254 break;
13255 case HW_VAR_OFF_RCR_AM:
13256 hw_var_set_rcr_am(adapter, 0);
13257 break;
13258 case HW_VAR_BEACON_INTERVAL:
13259 hw_var_set_bcn_interval(adapter, *(u16 *)val);
13260 break;
13261 #ifdef CONFIG_MBSSID_CAM
13262 case HW_VAR_MBSSID_CAM_WRITE: {
13263 u32 cmd = 0;
13264 u32 *cam_val = (u32 *)val;
13265
13266 rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
13267 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
13268 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
13269 }
13270 break;
13271 case HW_VAR_MBSSID_CAM_CLEAR: {
13272 u32 cmd;
13273 u8 entry_id = *(u8 *)val;
13274
13275 rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
13276
13277 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
13278 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
13279 }
13280 break;
13281 case HW_VAR_RCR_MBSSID_EN:
13282 if (*((u8 *)val))
13283 rtw_hal_rcr_add(adapter, RCR_ENMBID);
13284 else
13285 rtw_hal_rcr_clear(adapter, RCR_ENMBID);
13286 break;
13287 #endif
13288 case HW_VAR_PORT_SWITCH:
13289 hw_var_port_switch(adapter);
13290 break;
13291 case HW_VAR_INIT_RTS_RATE: {
13292 u16 brate_cfg = *((u16 *)val);
13293 u8 rate_index = 0;
13294 HAL_VERSION *hal_ver = &hal_data->version_id;
13295
13296 if (IS_8188E(*hal_ver)) {
13297
13298 while (brate_cfg > 0x1) {
13299 brate_cfg = (brate_cfg >> 1);
13300 rate_index++;
13301 }
13302 rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
13303 } else
13304 rtw_warn_on(1);
13305 }
13306 break;
13307 case HW_VAR_SEC_CFG: {
13308 u16 reg_scr_ori;
13309 u16 reg_scr;
13310
13311 reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
13312 reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
13313
13314 if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
13315 reg_scr |= SCR_CHK_BMC;
13316
13317 if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
13318 reg_scr |= SCR_NoSKMC;
13319
13320 if (reg_scr != reg_scr_ori)
13321 rtw_write16(adapter, REG_SECCFG, reg_scr);
13322 }
13323 break;
13324 case HW_VAR_SEC_DK_CFG: {
13325 struct security_priv *sec = &adapter->securitypriv;
13326 u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
13327
13328 if (val) { /* Enable default key related setting */
13329 reg_scr |= SCR_TXBCUSEDK;
13330 if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
13331 reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
13332 } else /* Disable default key related setting */
13333 reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
13334
13335 rtw_write8(adapter, REG_SECCFG, reg_scr);
13336 }
13337 break;
13338
13339 case HW_VAR_ASIX_IOT:
13340 /* enable ASIX IOT function */
13341 if (*((u8 *)val) == _TRUE) {
13342 /* 0xa2e[0]=0 (disable rake receiver) */
13343 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
13344 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
13345 /* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
13346 rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
13347 } else {
13348 /* restore reg:0xa2e, reg:0xa1c */
13349 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
13350 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
13351 rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
13352 }
13353 break;
13354 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
13355 case HW_VAR_WOWLAN: {
13356 struct wowlan_ioctl_param *poidparam;
13357
13358 poidparam = (struct wowlan_ioctl_param *)val;
13359 switch (poidparam->subcode) {
13360 #ifdef CONFIG_WOWLAN
13361 case WOWLAN_PATTERN_CLEAN:
13362 rtw_hal_dl_pattern(adapter, 2);
13363 break;
13364 case WOWLAN_ENABLE:
13365 rtw_hal_wow_enable(adapter);
13366 break;
13367 case WOWLAN_DISABLE:
13368 rtw_hal_wow_disable(adapter);
13369 break;
13370 #endif /*CONFIG_WOWLAN*/
13371 #ifdef CONFIG_AP_WOWLAN
13372 case WOWLAN_AP_ENABLE:
13373 rtw_hal_ap_wow_enable(adapter);
13374 break;
13375 case WOWLAN_AP_DISABLE:
13376 rtw_hal_ap_wow_disable(adapter);
13377 break;
13378 #endif /*CONFIG_AP_WOWLAN*/
13379 default:
13380 break;
13381 }
13382 }
13383 break;
13384 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
13385
13386 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
13387 case HW_VAR_BCN_FUNC:
13388 hw_var_set_bcn_func(adapter, *val);
13389 break;
13390 #endif
13391
13392 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
13393 case HW_VAR_MLME_DISCONNECT:
13394 hw_var_set_mlme_disconnect(adapter);
13395 break;
13396 #endif
13397
13398 case HW_VAR_MLME_SITESURVEY:
13399 hw_var_set_mlme_sitesurvey(adapter, *val);
13400 #ifdef CONFIG_BT_COEXIST
13401 if (hal_data->EEPROMBluetoothCoexist == 1)
13402 rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
13403 #endif
13404 break;
13405
13406 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
13407 case HW_VAR_MLME_JOIN:
13408 hw_var_set_mlme_join(adapter, *val);
13409 break;
13410 #endif
13411
13412 case HW_VAR_EN_HW_UPDATE_TSF:
13413 rtw_hal_set_hw_update_tsf(adapter);
13414 break;
13415 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
13416 case HW_VAR_CORRECT_TSF:
13417 hw_var_set_correct_tsf(adapter, *val);
13418 break;
13419 #endif
13420
13421 #if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)
13422 case HW_VAR_TSF_AUTO_SYNC:
13423 if (*val == _TRUE)
13424 hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
13425 else
13426 hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
13427 break;
13428 #endif
13429 case HW_VAR_APFM_ON_MAC:
13430 hal_data->bMacPwrCtrlOn = *val;
13431 RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
13432 break;
13433 #ifdef CONFIG_WMMPS_STA
13434 case HW_VAR_UAPSD_TID:
13435 rtw_hal_update_uapsd_tid(adapter);
13436 break;
13437 #endif /* CONFIG_WMMPS_STA */
13438 #ifdef CONFIG_LPS_PG
13439 case HW_VAR_LPS_PG_HANDLE:
13440 rtw_hal_lps_pg_handler(adapter, *val);
13441 break;
13442 #endif
13443 #ifdef CONFIG_LPS_LCLK_WD_TIMER
13444 case HW_VAR_DM_IN_LPS_LCLK:
13445 rtw_phydm_wd_lps_lclk_hdl(adapter);
13446 break;
13447 #endif
13448 case HW_VAR_ENABLE_RX_BAR:
13449 if (*val == _TRUE) {
13450 /* enable RX BAR */
13451 u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
13452
13453 val16 |= BIT(8);
13454 rtw_write16(adapter, REG_RXFLTMAP1, val16);
13455 } else {
13456 /* disable RX BAR */
13457 u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
13458
13459 val16 &= (~BIT(8));
13460 rtw_write16(adapter, REG_RXFLTMAP1, val16);
13461 }
13462 RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
13463 REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
13464 break;
13465 case HW_VAR_HCI_SUS_STATE:
13466 hal_data->hci_sus_state = *(u8 *)val;
13467 RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
13468 break;
13469 #if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
13470 case HW_VAR_BCN_HEAD_SEL:
13471 {
13472 u8 vap_id = *(u8 *)val;
13473
13474 if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
13475 RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
13476 rtw_warn_on(1);
13477 }
13478 if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
13479 u16 drv_pg_bndy = 0, bcn_addr = 0;
13480 u32 page_size = 0;
13481
13482 /*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
13483 rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
13484 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
13485
13486 if (vap_id != 0xFF)
13487 bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
13488 else
13489 bcn_addr = drv_pg_bndy;
13490 RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
13491 ADPT_ARG(adapter), vap_id, bcn_addr);
13492 rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
13493 (bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
13494 }
13495 }
13496 break;
13497 #endif
13498 case HW_VAR_LPS_STATE_CHK :
13499 rtw_lps_state_chk(adapter, *(u8 *)val);
13500 break;
13501
13502 #ifdef CONFIG_RTS_FULL_BW
13503 case HW_VAR_SET_RTS_BW:
13504 {
13505 #ifdef RTW_HALMAC
13506 rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));
13507 #else
13508 u8 temp;
13509 if(*val)
13510 temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );
13511 else
13512 temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));
13513 rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);
13514 /*RTW_INFO("HW_VAR_SET_RTS_BW val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/
13515 #endif
13516 }
13517 break;
13518 #endif/*CONFIG_RTS_FULL_BW*/
13519 #if defined(CONFIG_PCI_HCI)
13520 case HW_VAR_ENSWBCN:
13521 if (*val == _TRUE) {
13522 rtw_write8(adapter, REG_CR + 1,
13523 rtw_read8(adapter, REG_CR + 1) | BIT(0));
13524 } else
13525 rtw_write8(adapter, REG_CR + 1,
13526 rtw_read8(adapter, REG_CR + 1) & ~BIT(0));
13527 break;
13528 #endif
13529 case HW_VAR_BCN_EARLY_C2H_RPT:
13530 rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(adapter, *(u8 *)val);
13531 break;
13532 default:
13533 if (0)
13534 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
13535 FUNC_ADPT_ARG(adapter), variable);
13536 ret = _FAIL;
13537 break;
13538 }
13539
13540 return ret;
13541 }
13542
GetHwReg(_adapter * adapter,u8 variable,u8 * val)13543 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
13544 {
13545 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13546 u64 val64;
13547
13548
13549 switch (variable) {
13550 case HW_VAR_MAC_ADDR:
13551 #ifndef CONFIG_MI_WITH_MBSSID_CAM
13552 rtw_hal_get_macaddr_port(adapter, val);
13553 #endif
13554 break;
13555 case HW_VAR_BASIC_RATE:
13556 *((u16 *)val) = hal_data->BasicRateSet;
13557 break;
13558 case HW_VAR_MEDIA_STATUS:
13559 rtw_hal_get_msr(adapter, val);
13560 break;
13561 case HW_VAR_DO_IQK:
13562 *val = hal_data->bNeedIQK;
13563 break;
13564 case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
13565 if (hal_is_band_support(adapter, BAND_ON_5G))
13566 *val = _TRUE;
13567 else
13568 *val = _FALSE;
13569 break;
13570 case HW_VAR_APFM_ON_MAC:
13571 *val = hal_data->bMacPwrCtrlOn;
13572 break;
13573 case HW_VAR_RCR:
13574 hw_var_rcr_get(adapter, (u32 *)val);
13575 break;
13576 case HW_VAR_FWLPS_RF_ON:
13577 /* When we halt NIC, we should check if FW LPS is leave. */
13578 if (rtw_is_surprise_removed(adapter)
13579 || (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
13580 ) {
13581 /*
13582 * If it is in HW/SW Radio OFF or IPS state,
13583 * we do not check Fw LPS Leave,
13584 * because Fw is unload.
13585 */
13586 *val = _TRUE;
13587 } else {
13588 u32 rcr = 0;
13589
13590 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
13591 if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
13592 *val = _FALSE;
13593 else
13594 *val = _TRUE;
13595 }
13596 break;
13597
13598 case HW_VAR_HCI_SUS_STATE:
13599 *((u8 *)val) = hal_data->hci_sus_state;
13600 break;
13601
13602 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
13603 case HW_VAR_BCN_CTRL_ADDR:
13604 *((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
13605 break;
13606 #endif
13607
13608 #ifdef CONFIG_WAPI_SUPPORT
13609 case HW_VAR_CAM_EMPTY_ENTRY: {
13610 u8 ucIndex = *((u8 *)val);
13611 u8 i;
13612 u32 ulCommand = 0;
13613 u32 ulContent = 0;
13614 u32 ulEncAlgo = CAM_AES;
13615
13616 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
13617 /* filled id in CAM config 2 byte */
13618 if (i == 0)
13619 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
13620 else
13621 ulContent = 0;
13622 /* polling bit, and No Write enable, and address */
13623 ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
13624 ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
13625 /* write content 0 is equall to mark invalid */
13626 rtw_write32(adapter, REG_CAMWRITE, ulContent); /* delay_ms(40); */
13627 rtw_write32(adapter, REG_CAMCMD, ulCommand); /* delay_ms(40); */
13628 }
13629 }
13630 #endif
13631
13632 default:
13633 if (0)
13634 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
13635 FUNC_ADPT_ARG(adapter), variable);
13636 break;
13637 }
13638
13639 }
13640
_get_page_size(struct _ADAPTER * a)13641 static u32 _get_page_size(struct _ADAPTER *a)
13642 {
13643 #ifdef RTW_HALMAC
13644 struct dvobj_priv *d;
13645 u32 size = 0;
13646 int err = 0;
13647
13648
13649 d = adapter_to_dvobj(a);
13650
13651 err = rtw_halmac_get_page_size(d, &size);
13652 if (!err)
13653 return size;
13654
13655 RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
13656 FUNC_ADPT_ARG(a), err);
13657 #endif /* RTW_HALMAC */
13658
13659 return PAGE_SIZE_128;
13660 }
13661
13662 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13663 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13664 {
13665 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13666 u8 bResult = _SUCCESS;
13667
13668 switch (variable) {
13669
13670 case HAL_DEF_DBG_DUMP_RXPKT:
13671 hal_data->bDumpRxPkt = *((u8 *)value);
13672 break;
13673 case HAL_DEF_DBG_DUMP_TXPKT:
13674 hal_data->bDumpTxPkt = *((u8 *)value);
13675 break;
13676 case HAL_DEF_ANT_DETECT:
13677 hal_data->AntDetection = *((u8 *)value);
13678 break;
13679 default:
13680 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
13681 bResult = _FAIL;
13682 break;
13683 }
13684
13685 return bResult;
13686 }
13687
13688 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)13689 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
13690 {
13691 struct registry_priv *pregistrypriv = &adapter->registrypriv;
13692 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13693
13694 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)))
13695 return pregistrypriv->beamformer_rf_num;
13696 else if (IS_HARDWARE_TYPE_8814AE(adapter)
13697 #if 0
13698 #if defined(CONFIG_USB_HCI)
13699 || (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) /* for USB3.0 */
13700 #endif
13701 #endif
13702 ) {
13703 /*BF cap provided by Yu Chen, Sean, 2015, 01 */
13704 if (hal_data->rf_type == RF_3T3R)
13705 return 2;
13706 else if (hal_data->rf_type == RF_4T4R)
13707 return 3;
13708 else
13709 return 1;
13710 } else
13711 return 1;
13712
13713 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)13714 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
13715 {
13716 struct registry_priv *pregistrypriv = &adapter->registrypriv;
13717 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13718 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13719
13720 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13721
13722 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)))
13723 return pregistrypriv->beamformee_rf_num;
13724 else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
13725 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
13726 return 2;
13727 else
13728 return 2;/*TODO: May be 3 in the future, by ChenYu. */
13729 } else
13730 return 1;
13731
13732 }
13733 #ifdef RTW_BEAMFORMING_VERSION_2
rtw_hal_beamforming_config_csirate(PADAPTER adapter)13734 void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
13735 {
13736 struct dm_struct *p_dm_odm;
13737 struct beamforming_info *bf_info;
13738 u8 fix_rate_enable = 0;
13739 u8 new_csi_rate_idx;
13740 u8 rrsr_54_en;
13741 u32 temp_rrsr;
13742
13743 /* Acting as BFee */
13744 if (IS_BEAMFORMEE(adapter)) {
13745 #if 0
13746 /* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
13747 if (IS_HARDWARE_TYPE_8821C(Adapter))
13748 FixRateEnable = 1; /* Support after 8821C */
13749 #endif
13750
13751 p_dm_odm = adapter_to_phydm(adapter);
13752 bf_info = GET_BEAMFORM_INFO(adapter);
13753
13754 rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
13755 p_dm_odm->rssi_min,
13756 bf_info->cur_csi_rpt_rate,
13757 fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);
13758
13759 temp_rrsr = rtw_read32(adapter, REG_RRSR);
13760 if (rrsr_54_en == 1)
13761 temp_rrsr |= RRSR_54M;
13762 else if (rrsr_54_en == 0)
13763 temp_rrsr &= ~RRSR_54M;
13764 rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);
13765
13766 if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
13767 bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
13768 }
13769 }
13770 #endif
13771 #endif
13772
13773 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13774 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13775 {
13776 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13777 u8 bResult = _SUCCESS;
13778
13779 switch (variable) {
13780 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
13781 struct mlme_priv *pmlmepriv;
13782 struct sta_priv *pstapriv;
13783 struct sta_info *psta;
13784
13785 pmlmepriv = &adapter->mlmepriv;
13786 pstapriv = &adapter->stapriv;
13787 psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
13788 if (psta)
13789 *((int *)value) = psta->cmn.rssi_stat.rssi;
13790 }
13791 break;
13792 case HAL_DEF_DBG_DUMP_RXPKT:
13793 *((u8 *)value) = hal_data->bDumpRxPkt;
13794 break;
13795 case HAL_DEF_DBG_DUMP_TXPKT:
13796 *((u8 *)value) = hal_data->bDumpTxPkt;
13797 break;
13798 case HAL_DEF_ANT_DETECT:
13799 *((u8 *)value) = hal_data->AntDetection;
13800 break;
13801 case HAL_DEF_TX_PAGE_SIZE:
13802 *((u32 *)value) = _get_page_size(adapter);
13803 break;
13804 case HAL_DEF_TX_STBC:
13805 #ifdef CONFIG_ALPHA_SMART_ANTENNA
13806 *(u8 *)value = 0;
13807 #else
13808 *(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;
13809 #endif
13810 break;
13811 case HAL_DEF_EXPLICIT_BEAMFORMER:
13812 case HAL_DEF_EXPLICIT_BEAMFORMEE:
13813 case HAL_DEF_VHT_MU_BEAMFORMER:
13814 case HAL_DEF_VHT_MU_BEAMFORMEE:
13815 *(u8 *)value = _FALSE;
13816 break;
13817 #ifdef CONFIG_BEAMFORMING
13818 case HAL_DEF_BEAMFORMER_CAP:
13819 *(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
13820 break;
13821 case HAL_DEF_BEAMFORMEE_CAP:
13822 *(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
13823 break;
13824 #endif
13825 default:
13826 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
13827 bResult = _FAIL;
13828 break;
13829 }
13830
13831 return bResult;
13832 }
13833
13834 /*
13835 * Description:
13836 * Translate a character to hex digit.
13837 * */
13838 u32
MapCharToHexDigit(char chTmp)13839 MapCharToHexDigit(
13840 char chTmp
13841 )
13842 {
13843 if (chTmp >= '0' && chTmp <= '9')
13844 return chTmp - '0';
13845 else if (chTmp >= 'a' && chTmp <= 'f')
13846 return 10 + (chTmp - 'a');
13847 else if (chTmp >= 'A' && chTmp <= 'F')
13848 return 10 + (chTmp - 'A');
13849 else
13850 return 0;
13851 }
13852
13853
13854
13855 /*
13856 * Description:
13857 * Parse hex number from the string pucStr.
13858 * */
13859 BOOLEAN
GetHexValueFromString(char * szStr,u32 * pu4bVal,u32 * pu4bMove)13860 GetHexValueFromString(
13861 char *szStr,
13862 u32 *pu4bVal,
13863 u32 *pu4bMove
13864 )
13865 {
13866 char *szScan = szStr;
13867
13868 /* Check input parameter. */
13869 if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
13870 RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
13871 return _FALSE;
13872 }
13873
13874 /* Initialize output. */
13875 *pu4bMove = 0;
13876 *pu4bVal = 0;
13877
13878 /* Skip leading space. */
13879 while (*szScan != '\0' &&
13880 (*szScan == ' ' || *szScan == '\t')) {
13881 szScan++;
13882 (*pu4bMove)++;
13883 }
13884
13885 /* Skip leading '0x' or '0X'. */
13886 if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
13887 szScan += 2;
13888 (*pu4bMove) += 2;
13889 }
13890
13891 /* Check if szScan is now pointer to a character for hex digit, */
13892 /* if not, it means this is not a valid hex number. */
13893 if (!IsHexDigit(*szScan))
13894 return _FALSE;
13895
13896 /* Parse each digit. */
13897 do {
13898 (*pu4bVal) <<= 4;
13899 *pu4bVal += MapCharToHexDigit(*szScan);
13900
13901 szScan++;
13902 (*pu4bMove)++;
13903 } while (IsHexDigit(*szScan));
13904
13905 return _TRUE;
13906 }
13907
13908 BOOLEAN
GetFractionValueFromString(char * szStr,u8 * pInteger,u8 * pFraction,u32 * pu4bMove)13909 GetFractionValueFromString(
13910 char *szStr,
13911 u8 *pInteger,
13912 u8 *pFraction,
13913 u32 *pu4bMove
13914 )
13915 {
13916 char *szScan = szStr;
13917
13918 /* Initialize output. */
13919 *pu4bMove = 0;
13920 *pInteger = 0;
13921 *pFraction = 0;
13922
13923 /* Skip leading space. */
13924 while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) {
13925 ++szScan;
13926 ++(*pu4bMove);
13927 }
13928
13929 if (*szScan < '0' || *szScan > '9')
13930 return _FALSE;
13931
13932 /* Parse each digit. */
13933 do {
13934 (*pInteger) *= 10;
13935 *pInteger += (*szScan - '0');
13936
13937 ++szScan;
13938 ++(*pu4bMove);
13939
13940 if (*szScan == '.') {
13941 ++szScan;
13942 ++(*pu4bMove);
13943
13944 if (*szScan < '0' || *szScan > '9')
13945 return _FALSE;
13946
13947 *pFraction += (*szScan - '0') * 10;
13948 ++szScan;
13949 ++(*pu4bMove);
13950
13951 if (*szScan >= '0' && *szScan <= '9') {
13952 *pFraction += *szScan - '0';
13953 ++szScan;
13954 ++(*pu4bMove);
13955 }
13956 return _TRUE;
13957 }
13958 } while (*szScan >= '0' && *szScan <= '9');
13959
13960 return _TRUE;
13961 }
13962
13963 /*
13964 * Description:
13965 * Return TRUE if szStr is comment out with leading " */ /* ".
13966 * */
13967 BOOLEAN
IsCommentString(char * szStr)13968 IsCommentString(
13969 char *szStr
13970 )
13971 {
13972 if (*szStr == '/' && *(szStr + 1) == '/')
13973 return _TRUE;
13974 else
13975 return _FALSE;
13976 }
13977
13978 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(char * Str,u8 * pInt)13979 GetU1ByteIntegerFromStringInDecimal(
13980 char *Str,
13981 u8 *pInt
13982 )
13983 {
13984 u16 i = 0;
13985 *pInt = 0;
13986
13987 while (Str[i] != '\0') {
13988 if (Str[i] >= '0' && Str[i] <= '9') {
13989 *pInt *= 10;
13990 *pInt += (Str[i] - '0');
13991 } else
13992 return _FALSE;
13993 ++i;
13994 }
13995
13996 return _TRUE;
13997 }
13998
13999 /* <20121004, Kordan> For example,
14000 * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
14001 * If RightQualifier does not exist, it will hang on in the while loop */
14002 BOOLEAN
ParseQualifiedString(char * In,u32 * Start,char * Out,char LeftQualifier,char RightQualifier)14003 ParseQualifiedString(
14004 char *In,
14005 u32 *Start,
14006 char *Out,
14007 char LeftQualifier,
14008 char RightQualifier
14009 )
14010 {
14011 u32 i = 0, j = 0;
14012 char c = In[(*Start)++];
14013
14014 if (c != LeftQualifier)
14015 return _FALSE;
14016
14017 i = (*Start);
14018 c = In[(*Start)++];
14019 while (c != RightQualifier && c != '\0')
14020 c = In[(*Start)++];
14021
14022 if (c == '\0')
14023 return _FALSE;
14024
14025 j = (*Start) - 2;
14026 strncpy((char *)Out, (const char *)(In + i), j - i + 1);
14027
14028 return _TRUE;
14029 }
14030
14031 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)14032 isAllSpaceOrTab(
14033 u8 *data,
14034 u8 size
14035 )
14036 {
14037 u8 cnt = 0, NumOfSpaceAndTab = 0;
14038
14039 while (size > cnt) {
14040 if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
14041 ++NumOfSpaceAndTab;
14042
14043 ++cnt;
14044 }
14045
14046 return size == NumOfSpaceAndTab;
14047 }
14048
14049
rtw_hal_check_rxfifo_full(_adapter * adapter)14050 void rtw_hal_check_rxfifo_full(_adapter *adapter)
14051 {
14052 struct dvobj_priv *psdpriv = adapter->dvobj;
14053 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
14054 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
14055 struct registry_priv *regsty = &adapter->registrypriv;
14056 int save_cnt = _FALSE;
14057
14058 if (regsty->check_hw_status == 1) {
14059 /* switch counter to RX fifo */
14060 if (IS_8188E(pHalData->version_id) ||
14061 IS_8188F(pHalData->version_id) ||
14062 IS_8188GTV(pHalData->version_id) ||
14063 IS_8812_SERIES(pHalData->version_id) ||
14064 IS_8821_SERIES(pHalData->version_id) ||
14065 IS_8723B_SERIES(pHalData->version_id) ||
14066 IS_8192E(pHalData->version_id) ||
14067 IS_8703B_SERIES(pHalData->version_id) ||
14068 IS_8723D_SERIES(pHalData->version_id) ||
14069 IS_8192F_SERIES(pHalData->version_id)) {
14070 rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
14071 save_cnt = _TRUE;
14072 } else {
14073 /* todo: other chips */
14074 }
14075
14076
14077 if (save_cnt) {
14078 pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
14079 pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
14080 pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
14081 } else {
14082 /* special value to indicate no implementation */
14083 pdbgpriv->dbg_rx_fifo_last_overflow = 1;
14084 pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
14085 pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
14086 }
14087 }
14088 }
14089
linked_info_dump(_adapter * padapter,u8 benable)14090 void linked_info_dump(_adapter *padapter, u8 benable)
14091 {
14092 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
14093
14094 if (padapter->bLinkInfoDump == benable)
14095 return;
14096
14097 RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
14098
14099 if (benable) {
14100 #ifdef CONFIG_LPS
14101 pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
14102 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
14103 #endif
14104
14105 #ifdef CONFIG_IPS
14106 pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
14107 rtw_pm_set_ips(padapter, IPS_NONE);
14108 #endif
14109 } else {
14110 #ifdef CONFIG_IPS
14111 rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
14112 #endif /* CONFIG_IPS */
14113
14114 #ifdef CONFIG_LPS
14115 rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
14116 #endif /* CONFIG_LPS */
14117 }
14118 padapter->bLinkInfoDump = benable ;
14119 }
14120
14121 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)14122 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
14123 {
14124 u8 isCCKrate, rf_path;
14125 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14126 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14127 RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
14128 HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
14129 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14130
14131 if (isCCKrate)
14132 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
14133
14134 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14135 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14136 continue;
14137 RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
14138 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
14139
14140 if (!isCCKrate) {
14141 RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
14142 psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
14143 }
14144 }
14145 }
14146
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)14147 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
14148 {
14149 u8 isCCKrate, rf_path;
14150 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14151 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14152 _RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
14153 _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);
14154
14155 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14156
14157 if (isCCKrate)
14158 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
14159
14160 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14161 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14162 continue;
14163 _RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
14164 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
14165
14166 if (!isCCKrate)
14167 _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]);
14168 else
14169 _RTW_PRINT_SEL(sel , "\n");
14170
14171 }
14172 }
14173 #endif
14174
14175 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)14176 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
14177 {
14178 #define DBG_RX_DFRAME_RAW_DATA_UC 0
14179 #define DBG_RX_DFRAME_RAW_DATA_BMC 1
14180 #define DBG_RX_DFRAME_RAW_DATA_TYPES 2
14181
14182 _irqL irqL;
14183 u8 isCCKrate, rf_path;
14184 struct recv_priv *precvpriv = &(padapter->recvpriv);
14185 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14186 struct sta_priv *pstapriv = &padapter->stapriv;
14187 struct sta_info *psta;
14188 struct sta_recv_dframe_info *psta_dframe_info;
14189 int i, j;
14190 _list *plist, *phead;
14191 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14192 u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14193
14194 if (precvpriv->store_law_data_flag) {
14195
14196 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
14197
14198 for (i = 0; i < NUM_STA; i++) {
14199 phead = &(pstapriv->sta_hash[i]);
14200 plist = get_next(phead);
14201
14202 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
14203
14204 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
14205 plist = get_next(plist);
14206
14207 if (psta) {
14208 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE)
14209 && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN) != _TRUE)
14210 && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN) != _TRUE)) {
14211
14212 RTW_PRINT_SEL(sel, "==============================\n");
14213 RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
14214
14215 for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
14216 if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
14217 psta_dframe_info = &psta->sta_dframe_info;
14218 RTW_PRINT_SEL(sel, "\n");
14219 RTW_PRINT_SEL(sel, "Unicast:\n");
14220 } else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
14221 psta_dframe_info = &psta->sta_dframe_info_bmc;
14222 RTW_PRINT_SEL(sel, "\n");
14223 RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
14224 }
14225
14226 isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14227
14228 RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
14229 RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
14230
14231 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14232 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14233 continue;
14234 if (!isCCKrate) {
14235 RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
14236 _RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
14237 } else
14238 RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
14239 }
14240 }
14241
14242 }
14243 }
14244 }
14245 }
14246 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
14247 }
14248 }
14249 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)14250 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
14251 {
14252 u8 isCCKrate, rf_path , dframe_type;
14253 u8 *ptr;
14254 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14255 #ifdef DBG_RX_DFRAME_RAW_DATA
14256 struct sta_recv_dframe_info *psta_dframe_info;
14257 #endif
14258 struct recv_priv *precvpriv = &(padapter->recvpriv);
14259 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14260 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
14261 struct sta_info *psta = prframe->u.hdr.psta;
14262 struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
14263 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14264 psample_pkt_rssi->data_rate = pattrib->data_rate;
14265 ptr = prframe->u.hdr.rx_data;
14266 dframe_type = GetFrameType(ptr);
14267 /*RTW_INFO("=>%s\n", __FUNCTION__);*/
14268
14269
14270 if (precvpriv->store_law_data_flag) {
14271 isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14272
14273 psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
14274 psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
14275
14276 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14277 psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
14278 psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
14279 if (!isCCKrate) {
14280 psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
14281 psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
14282 }
14283 }
14284 #ifdef DBG_RX_DFRAME_RAW_DATA
14285 if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
14286
14287 /*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
14288 if (psta) {
14289 if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
14290 psta_dframe_info = &psta->sta_dframe_info_bmc;
14291 else
14292 psta_dframe_info = &psta->sta_dframe_info;
14293 /*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
14294 __FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
14295 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
14296 psta_dframe_info->sta_data_rate = pattrib->data_rate;
14297 psta_dframe_info->sta_sgi = pattrib->sgi;
14298 psta_dframe_info->sta_bw_mode = pattrib->bw;
14299 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14300
14301 psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
14302
14303 if (!isCCKrate) {
14304 psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
14305 psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
14306 }
14307 }
14308 }
14309 }
14310 }
14311 #endif
14312 }
14313
14314 }
14315
hal_efuse_macaddr_offset(_adapter * adapter)14316 int hal_efuse_macaddr_offset(_adapter *adapter)
14317 {
14318 u8 interface_type = 0;
14319 int addr_offset = -1;
14320
14321 interface_type = rtw_get_intf_type(adapter);
14322
14323 switch (rtw_get_chip_type(adapter)) {
14324 #ifdef CONFIG_RTL8723B
14325 case RTL8723B:
14326 if (interface_type == RTW_USB)
14327 addr_offset = EEPROM_MAC_ADDR_8723BU;
14328 else if (interface_type == RTW_SDIO)
14329 addr_offset = EEPROM_MAC_ADDR_8723BS;
14330 else if (interface_type == RTW_PCIE)
14331 addr_offset = EEPROM_MAC_ADDR_8723BE;
14332 break;
14333 #endif
14334 #ifdef CONFIG_RTL8703B
14335 case RTL8703B:
14336 if (interface_type == RTW_USB)
14337 addr_offset = EEPROM_MAC_ADDR_8703BU;
14338 else if (interface_type == RTW_SDIO)
14339 addr_offset = EEPROM_MAC_ADDR_8703BS;
14340 break;
14341 #endif
14342 #ifdef CONFIG_RTL8723D
14343 case RTL8723D:
14344 if (interface_type == RTW_USB)
14345 addr_offset = EEPROM_MAC_ADDR_8723DU;
14346 else if (interface_type == RTW_SDIO)
14347 addr_offset = EEPROM_MAC_ADDR_8723DS;
14348 else if (interface_type == RTW_PCIE)
14349 addr_offset = EEPROM_MAC_ADDR_8723DE;
14350 break;
14351 #endif
14352
14353 #ifdef CONFIG_RTL8188E
14354 case RTL8188E:
14355 if (interface_type == RTW_USB)
14356 addr_offset = EEPROM_MAC_ADDR_88EU;
14357 else if (interface_type == RTW_SDIO)
14358 addr_offset = EEPROM_MAC_ADDR_88ES;
14359 else if (interface_type == RTW_PCIE)
14360 addr_offset = EEPROM_MAC_ADDR_88EE;
14361 break;
14362 #endif
14363 #ifdef CONFIG_RTL8188F
14364 case RTL8188F:
14365 if (interface_type == RTW_USB)
14366 addr_offset = EEPROM_MAC_ADDR_8188FU;
14367 else if (interface_type == RTW_SDIO)
14368 addr_offset = EEPROM_MAC_ADDR_8188FS;
14369 break;
14370 #endif
14371 #ifdef CONFIG_RTL8188GTV
14372 case RTL8188GTV:
14373 if (interface_type == RTW_USB)
14374 addr_offset = EEPROM_MAC_ADDR_8188GTVU;
14375 else if (interface_type == RTW_SDIO)
14376 addr_offset = EEPROM_MAC_ADDR_8188GTVS;
14377 break;
14378 #endif
14379 #ifdef CONFIG_RTL8812A
14380 case RTL8812:
14381 if (interface_type == RTW_USB)
14382 addr_offset = EEPROM_MAC_ADDR_8812AU;
14383 else if (interface_type == RTW_PCIE)
14384 addr_offset = EEPROM_MAC_ADDR_8812AE;
14385 break;
14386 #endif
14387 #ifdef CONFIG_RTL8821A
14388 case RTL8821:
14389 if (interface_type == RTW_USB)
14390 addr_offset = EEPROM_MAC_ADDR_8821AU;
14391 else if (interface_type == RTW_SDIO)
14392 addr_offset = EEPROM_MAC_ADDR_8821AS;
14393 else if (interface_type == RTW_PCIE)
14394 addr_offset = EEPROM_MAC_ADDR_8821AE;
14395 break;
14396 #endif
14397 #ifdef CONFIG_RTL8192E
14398 case RTL8192E:
14399 if (interface_type == RTW_USB)
14400 addr_offset = EEPROM_MAC_ADDR_8192EU;
14401 else if (interface_type == RTW_SDIO)
14402 addr_offset = EEPROM_MAC_ADDR_8192ES;
14403 else if (interface_type == RTW_PCIE)
14404 addr_offset = EEPROM_MAC_ADDR_8192EE;
14405 break;
14406 #endif
14407 #ifdef CONFIG_RTL8814A
14408 case RTL8814A:
14409 if (interface_type == RTW_USB)
14410 addr_offset = EEPROM_MAC_ADDR_8814AU;
14411 else if (interface_type == RTW_PCIE)
14412 addr_offset = EEPROM_MAC_ADDR_8814AE;
14413 break;
14414 #endif
14415
14416 #ifdef CONFIG_RTL8822B
14417 case RTL8822B:
14418 if (interface_type == RTW_USB)
14419 addr_offset = EEPROM_MAC_ADDR_8822BU;
14420 else if (interface_type == RTW_SDIO)
14421 addr_offset = EEPROM_MAC_ADDR_8822BS;
14422 else if (interface_type == RTW_PCIE)
14423 addr_offset = EEPROM_MAC_ADDR_8822BE;
14424 break;
14425 #endif /* CONFIG_RTL8822B */
14426
14427 #ifdef CONFIG_RTL8821C
14428 case RTL8821C:
14429 if (interface_type == RTW_USB)
14430 addr_offset = EEPROM_MAC_ADDR_8821CU;
14431 else if (interface_type == RTW_SDIO)
14432 addr_offset = EEPROM_MAC_ADDR_8821CS;
14433 else if (interface_type == RTW_PCIE)
14434 addr_offset = EEPROM_MAC_ADDR_8821CE;
14435 break;
14436 #endif /* CONFIG_RTL8821C */
14437
14438 #ifdef CONFIG_RTL8710B
14439 case RTL8710B:
14440 if (interface_type == RTW_USB)
14441 addr_offset = EEPROM_MAC_ADDR_8710B;
14442 break;
14443 #endif
14444
14445 #ifdef CONFIG_RTL8192F
14446 case RTL8192F:
14447 if (interface_type == RTW_USB)
14448 addr_offset = EEPROM_MAC_ADDR_8192FU;
14449 else if (interface_type == RTW_SDIO)
14450 addr_offset = EEPROM_MAC_ADDR_8192FS;
14451 else if (interface_type == RTW_PCIE)
14452 addr_offset = EEPROM_MAC_ADDR_8192FE;
14453 break;
14454 #endif /* CONFIG_RTL8192F */
14455
14456 #ifdef CONFIG_RTL8822C
14457 case RTL8822C:
14458 if (interface_type == RTW_USB)
14459 addr_offset = EEPROM_MAC_ADDR_8822CU;
14460 else if (interface_type == RTW_SDIO)
14461 addr_offset = EEPROM_MAC_ADDR_8822CS;
14462 else if (interface_type == RTW_PCIE)
14463 addr_offset = EEPROM_MAC_ADDR_8822CE;
14464 break;
14465 #endif /* CONFIG_RTL8822C */
14466
14467 #ifdef CONFIG_RTL8814B
14468 case RTL8814B:
14469 if (interface_type == RTW_USB)
14470 addr_offset = EEPROM_MAC_ADDR_8814BU;
14471 else if (interface_type == RTW_PCIE)
14472 addr_offset = EEPROM_MAC_ADDR_8814BE;
14473 break;
14474 #endif /* CONFIG_RTL8814B */
14475
14476 #ifdef CONFIG_RTL8723F
14477 case RTL8723F:
14478 if (interface_type == RTW_USB)
14479 addr_offset = EEPROM_MAC_ADDR_8723FU;
14480 else if (interface_type == RTW_SDIO)
14481 addr_offset = EEPROM_MAC_ADDR_8723FS;
14482 break;
14483 #endif /* CONFIG_RTL8723F */
14484 }
14485
14486 if (addr_offset == -1) {
14487 RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
14488 , __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
14489 }
14490
14491 return addr_offset;
14492 }
14493
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)14494 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
14495 {
14496 int ret = _FAIL;
14497 int addr_offset;
14498
14499 addr_offset = hal_efuse_macaddr_offset(padapter);
14500 if (addr_offset == -1)
14501 goto exit;
14502
14503 ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
14504
14505 exit:
14506 return ret;
14507 }
14508
rtw_dump_cur_efuse(PADAPTER padapter)14509 void rtw_dump_cur_efuse(PADAPTER padapter)
14510 {
14511 int mapsize =0;
14512 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14513
14514 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
14515
14516 if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
14517 RTW_ERR("wrong map size %d\n", mapsize);
14518 return;
14519 }
14520
14521 #ifdef CONFIG_RTW_DEBUG
14522 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14523 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
14524 else
14525 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
14526 #endif
14527 }
14528
14529
14530 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)14531 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
14532 {
14533 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14534 u32 ret = _FALSE;
14535 u32 maplen = 0;
14536 #ifdef CONFIG_MP_INCLUDED
14537 struct mp_priv *pmp_priv = &padapter->mppriv;
14538 #endif
14539
14540 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
14541
14542 if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
14543 RTW_ERR("eFuse length error :%d\n", maplen);
14544 return _FALSE;
14545 }
14546 #ifdef CONFIG_MP_INCLUDED
14547 if (pmp_priv->efuse_update_file == _TRUE && (rtw_mp_mode_check(padapter))) {
14548 RTW_INFO("%s, eFuse read from file :%s\n", __func__, pmp_priv->efuse_file_path);
14549 ret = rtw_read_efuse_from_file(pmp_priv->efuse_file_path, hal_data->efuse_eeprom_data, maplen);
14550 pmp_priv->efuse_update_file = _FALSE;
14551 } else
14552 #endif
14553 {
14554 ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
14555 }
14556
14557 hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
14558
14559 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14560 rtw_dump_cur_efuse(padapter);
14561
14562 return ret;
14563 }
14564
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)14565 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
14566 {
14567 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14568 u32 ret = _FAIL;
14569
14570 if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
14571 && rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
14572 ) {
14573 hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
14574 ret = _SUCCESS;
14575 } else
14576 hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
14577
14578 return ret;
14579 }
14580 #endif /* CONFIG_EFUSE_CONFIG_FILE */
14581
hal_config_macaddr(_adapter * adapter,bool autoload_fail)14582 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
14583 {
14584 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
14585 u8 addr[ETH_ALEN];
14586 int addr_offset = hal_efuse_macaddr_offset(adapter);
14587 u8 *hw_addr = NULL;
14588 int ret = _SUCCESS;
14589 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
14590 u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
14591 #endif
14592
14593 if (autoload_fail)
14594 goto bypass_hw_pg;
14595
14596 if (addr_offset != -1)
14597 hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
14598
14599 #ifdef CONFIG_EFUSE_CONFIG_FILE
14600 /* if the hw_addr is written by efuse file, set to NULL */
14601 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14602 hw_addr = NULL;
14603 #endif
14604
14605 if (!hw_addr) {
14606 /* try getting hw pg data */
14607 if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
14608 hw_addr = addr;
14609 }
14610
14611 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
14612 if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
14613 hw_addr[0] = 0xff;
14614 #endif
14615
14616 /* check hw pg data */
14617 if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
14618 _rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
14619 goto exit;
14620 }
14621
14622 bypass_hw_pg:
14623
14624 #ifdef CONFIG_EFUSE_CONFIG_FILE
14625 /* check wifi mac file */
14626 if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
14627 _rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
14628 goto exit;
14629 }
14630 #endif
14631
14632 _rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
14633 ret = _FAIL;
14634
14635 exit:
14636 return ret;
14637 }
14638
14639 #ifdef CONFIG_RF_POWER_TRIM
14640 u32 Array_kfreemap[] = {
14641 0x08, 0xe,
14642 0x06, 0xc,
14643 0x04, 0xa,
14644 0x02, 0x8,
14645 0x00, 0x6,
14646 0x03, 0x4,
14647 0x05, 0x2,
14648 0x07, 0x0,
14649 0x09, 0x0,
14650 0x0c, 0x0,
14651 };
14652
rtw_bb_rf_gain_offset(_adapter * padapter)14653 void rtw_bb_rf_gain_offset(_adapter *padapter)
14654 {
14655 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14656 struct registry_priv *registry_par = &padapter->registrypriv;
14657 struct kfree_data_t *kfree_data = &pHalData->kfree_data;
14658 u8 value = pHalData->EEPROMRFGainOffset;
14659 u8 tmp = 0x3e;
14660 u32 res, i = 0;
14661 u32 ArrayLen = sizeof(Array_kfreemap) / sizeof(u32);
14662 u32 *Array = Array_kfreemap;
14663 u32 v1 = 0, v2 = 0, GainValue = 0, target = 0;
14664
14665 if (registry_par->RegPwrTrimEnable == 2) {
14666 RTW_INFO("Registry kfree default force disable.\n");
14667 return;
14668 }
14669
14670 #if defined(CONFIG_RTL8723B)
14671 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
14672 RTW_INFO("Offset RF Gain.\n");
14673 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
14674
14675 if (pHalData->EEPROMRFGainVal != 0xff) {
14676
14677 if (pHalData->ant_path == RF_PATH_A)
14678 GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
14679
14680 else
14681 GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
14682 RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
14683
14684 for (i = 0; i < ArrayLen; i += 2) {
14685 /* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
14686 v1 = Array[i];
14687 v2 = Array[i + 1];
14688 if (v1 == GainValue) {
14689 RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
14690 target = v2;
14691 break;
14692 }
14693 }
14694 RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
14695
14696 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
14697 RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
14698 phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
14699 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
14700
14701 RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
14702
14703 } else
14704
14705 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
14706 } else
14707 RTW_INFO("Using the default RF gain.\n");
14708
14709 #elif defined(CONFIG_RTL8188E)
14710 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
14711 RTW_INFO("8188ES Offset RF Gain.\n");
14712 RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
14713 pHalData->EEPROMRFGainVal);
14714
14715 if (pHalData->EEPROMRFGainVal != 0xff) {
14716 res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
14717 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
14718
14719 RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
14720 res &= 0xfff87fff;
14721
14722 res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
14723 RTW_INFO("Offset RF Gain. res=0x%x\n", res);
14724
14725 rtw_hal_write_rfreg(padapter, RF_PATH_A,
14726 REG_RF_BB_GAIN_OFFSET,
14727 RF_GAIN_OFFSET_MASK, res);
14728 } else {
14729 RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
14730 pHalData->EEPROMRFGainVal);
14731 }
14732 } else
14733 RTW_INFO("Using the default RF gain.\n");
14734 #else
14735 /* TODO: call this when channel switch */
14736 if (kfree_data->flag & KFREE_FLAG_ON)
14737 rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
14738 #endif
14739
14740 }
14741 #endif /*CONFIG_RF_POWER_TRIM */
14742
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)14743 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
14744 {
14745 #ifdef CONFIG_RF_POWER_TRIM
14746 int i, j;
14747
14748 for (i = 0; i < BB_GAIN_NUM; i++)
14749 for (j = 0; j < RF_PATH_MAX; j++)
14750 if (data->bb_gain[i][j] != 0)
14751 return 0;
14752 #endif
14753 return 1;
14754 }
14755
14756 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)14757 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
14758 {
14759 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14760 if (cur_wireless_mode < WIRELESS_11_24N
14761 && cur_wireless_mode > 0) { /* ABG mode */
14762 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14763 u32 remainder = 0;
14764 u8 quotient = 0;
14765
14766 remainder = MAX_RECVBUF_SZ % (4 * 1024);
14767 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14768
14769 if (quotient > 5) {
14770 pHalData->rxagg_usb_size = 0x6;
14771 pHalData->rxagg_usb_timeout = 0x10;
14772 } else {
14773 if (remainder >= 2048) {
14774 pHalData->rxagg_usb_size = quotient;
14775 pHalData->rxagg_usb_timeout = 0x10;
14776 } else {
14777 pHalData->rxagg_usb_size = (quotient - 1);
14778 pHalData->rxagg_usb_timeout = 0x10;
14779 }
14780 }
14781 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14782 if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
14783 pHalData->rxagg_usb_size = 0x6;
14784 pHalData->rxagg_usb_timeout = 0x10;
14785 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14786 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14787 }
14788 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14789
14790 } else if (cur_wireless_mode >= WIRELESS_11_24N
14791 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14792 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
14793 u32 remainder = 0;
14794 u8 quotient = 0;
14795
14796 remainder = MAX_RECVBUF_SZ % (4 * 1024);
14797 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
14798
14799 if (quotient > 5) {
14800 pHalData->rxagg_usb_size = 0x5;
14801 pHalData->rxagg_usb_timeout = 0x20;
14802 } else {
14803 if (remainder >= 2048) {
14804 pHalData->rxagg_usb_size = quotient;
14805 pHalData->rxagg_usb_timeout = 0x10;
14806 } else {
14807 pHalData->rxagg_usb_size = (quotient - 1);
14808 pHalData->rxagg_usb_timeout = 0x10;
14809 }
14810 }
14811 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
14812 if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
14813 pHalData->rxagg_usb_size = 0x5;
14814 pHalData->rxagg_usb_timeout = 0x20;
14815 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14816 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14817 }
14818 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
14819
14820 } else {
14821 /* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14822 }
14823 }
14824
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)14825 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
14826 {
14827 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14828
14829 if (cur_wireless_mode < WIRELESS_11_24N
14830 && cur_wireless_mode > 0) { /* ABG mode */
14831 if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
14832 || 0x10 != pHalData->rxagg_usb_timeout) {
14833 pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
14834 pHalData->rxagg_usb_timeout = 0x10;
14835 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14836 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14837 }
14838 } else if (cur_wireless_mode >= WIRELESS_11_24N
14839 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
14840 if (UsbDmaSize != pHalData->rxagg_usb_size
14841 || 0x20 != pHalData->rxagg_usb_timeout) {
14842 pHalData->rxagg_usb_size = UsbDmaSize;
14843 pHalData->rxagg_usb_timeout = 0x20;
14844 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
14845 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
14846 }
14847 } else {
14848 /* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
14849 }
14850 }
14851
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)14852 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
14853 {
14854 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14855 rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
14856 return;
14857 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14858
14859 rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
14860 }
14861 #endif /* CONFIG_USB_RX_AGGREGATION */
14862
14863 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)14864 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
14865 {
14866 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
14867 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14868 struct registry_priv *registry_par = &padapter->registrypriv;
14869 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14870 u8 cur_wireless_mode = WIRELESS_INVALID;
14871
14872 #ifdef CONFIG_USB_RX_AGGREGATION
14873 if (!registry_par->dynamic_agg_enable)
14874 return;
14875
14876 #ifdef RTW_HALMAC
14877 if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter)
14878 || IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter)
14879 || IS_HARDWARE_TYPE_8723FU(padapter))
14880 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
14881 #else /* !RTW_HALMAC */
14882 if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
14883 /* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
14884 if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) {
14885 if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14886 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
14887 else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
14888 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
14889 else
14890 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
14891
14892 /* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
14893 }
14894 } else if (IS_HARDWARE_TYPE_8812(padapter)) {
14895 #ifdef CONFIG_CONCURRENT_MODE
14896 u8 i;
14897 _adapter *iface;
14898 u8 bassocaed = _FALSE;
14899 struct mlme_ext_priv *mlmeext;
14900
14901 for (i = 0; i < pdvobjpriv->iface_nums; i++) {
14902 iface = pdvobjpriv->padapters[i];
14903 mlmeext = &iface->mlmeextpriv;
14904 if (rtw_linked_check(iface) == _TRUE) {
14905 if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
14906 cur_wireless_mode = mlmeext->cur_wireless_mode;
14907 bassocaed = _TRUE;
14908 }
14909 }
14910 if (bassocaed)
14911 #endif
14912 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14913 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
14914 } else {
14915 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
14916 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
14917 }
14918 #endif /* RTW_HALMAC */
14919 #endif /* CONFIG_USB_RX_AGGREGATION */
14920
14921 }
14922
14923 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)14924 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
14925 {
14926 #ifdef CONFIG_AP_MODE
14927 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
14928 u8 chk_rst = _SUCCESS;
14929
14930 if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
14931 return chk_rst;
14932
14933 /* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
14934 /* return chk_rst; */
14935
14936 if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
14937 && (pre_qsel != next_qsel)) {
14938 /* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
14939 /* pre_qsel,next_qsel); */
14940 chk_rst = _FAIL;
14941 }
14942 return chk_rst;
14943 #else
14944 return _SUCCESS;
14945 #endif /* CONFIG_AP_MODE */
14946 }
14947
14948 #ifdef CONFIG_WOWLAN
14949 /*
14950 * Description:
14951 * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
14952 * contant.
14953 *
14954 * Input:
14955 * adapter: adapter pointer.
14956 * page_num: The max. page number that user want to dump.
14957 * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
14958 */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)14959 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
14960 {
14961
14962 int i;
14963 u8 val = 0;
14964 u8 base = 0;
14965 u32 addr = 0;
14966 u32 count = (page_size / 8);
14967
14968 if (page_num <= 0) {
14969 RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
14970 return;
14971 }
14972
14973 if (page_size < 128 || page_size > 512) {
14974 RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
14975 return;
14976 }
14977
14978 RTW_INFO("+%s+\n", __func__);
14979 val = rtw_read8(padapter, 0x106);
14980 rtw_write8(padapter, 0x106, 0x69);
14981 RTW_INFO("0x106: 0x%02x\n", val);
14982 base = rtw_read8(padapter, 0x209);
14983 RTW_INFO("0x209: 0x%02x\n", base);
14984
14985 addr = ((base)*page_size) / 8;
14986 for (i = 0 ; i < page_num * count ; i += 2) {
14987 rtw_write32(padapter, 0x140, addr + i);
14988 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14989 rtw_write32(padapter, 0x140, addr + i + 1);
14990 printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
14991 }
14992 }
14993 #endif
14994
14995 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)14996 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
14997 {
14998 u8 value = 0;
14999 u8 direction = 0;
15000 u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
15001 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
15002 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
15003 u8 gpio_num_to_set = gpio_num;
15004 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
15005
15006 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15007 return value;
15008
15009 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15010
15011 RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
15012 LeaveAllPowerSaveModeDirect(adapter);
15013
15014 if (gpio_num > 7) {
15015 gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
15016 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
15017 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
15018 gpio_num_to_set = gpio_num - 8;
15019 }
15020
15021 /* Read GPIO Direction */
15022 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15023
15024 /* According the direction to read register value */
15025 if (direction)
15026 value = (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15027 else
15028 value = (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15029
15030 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15031 RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
15032
15033 return value;
15034 }
15035
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)15036 int rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
15037 {
15038 u8 direction = 0;
15039 u8 res = -1;
15040 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
15041 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
15042 u8 gpio_num_to_set = gpio_num;
15043
15044 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15045 return -1;
15046
15047 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15048
15049 LeaveAllPowerSaveModeDirect(adapter);
15050
15051 if (gpio_num > 7) {
15052 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
15053 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
15054 gpio_num_to_set = gpio_num - 8;
15055 }
15056
15057 /* Read GPIO direction */
15058 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15059
15060 /* If GPIO is output direction, setting value. */
15061 if (direction) {
15062 if (isHigh)
15063 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
15064 else
15065 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
15066
15067 RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
15068 res = 0;
15069 } else {
15070 RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
15071 res = -1;
15072 }
15073
15074 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15075 return res;
15076 }
15077
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)15078 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
15079 {
15080 u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
15081 u8 gpio_num_to_set = gpio_num;
15082
15083 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15084 return -1;
15085
15086 RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
15087
15088 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15089
15090 LeaveAllPowerSaveModeDirect(adapter);
15091
15092 rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
15093
15094 if (gpio_num > 7) {
15095 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
15096 gpio_num_to_set = gpio_num - 8;
15097 }
15098
15099 if (isOutput)
15100 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
15101 else
15102 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
15103
15104 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15105
15106 return 0;
15107 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))15108 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
15109 {
15110 u8 value;
15111 u8 direction;
15112 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
15113
15114 if (IS_HARDWARE_TYPE_8188E(adapter)) {
15115 if (gpio_num > 7 || gpio_num < 4) {
15116 RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
15117 return -1;
15118 }
15119 }
15120
15121 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15122
15123 LeaveAllPowerSaveModeDirect(adapter);
15124
15125 /* Read GPIO direction */
15126 direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
15127 if (direction) {
15128 RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
15129 return -1;
15130 }
15131
15132 /* Config GPIO Mode */
15133 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
15134
15135 /* Register GPIO interrupt handler*/
15136 adapter->gpiointpriv.callback[gpio_num] = callback;
15137
15138 /* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
15139 value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
15140 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
15141 rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
15142
15143 /* Enable GPIO interrupt */
15144 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
15145 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
15146
15147 rtw_hal_update_hisr_hsisr_ind(adapter, 1);
15148
15149 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15150
15151 return 0;
15152 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)15153 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
15154 {
15155 u8 value;
15156 u8 direction;
15157 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
15158
15159 if (IS_HARDWARE_TYPE_8188E(adapter)) {
15160 if (gpio_num > 7 || gpio_num < 4) {
15161 RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
15162 return -1;
15163 }
15164 }
15165
15166 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15167
15168 LeaveAllPowerSaveModeDirect(adapter);
15169
15170 /* Config GPIO Mode */
15171 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
15172
15173 /* Unregister GPIO interrupt handler*/
15174 adapter->gpiointpriv.callback[gpio_num] = NULL;
15175
15176 /* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
15177 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
15178 rtw_write8(adapter, REG_GPIO_INTM, 0x00);
15179
15180 /* Disable GPIO interrupt */
15181 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
15182 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
15183
15184 if (!adapter->gpiointpriv.interrupt_enable_mask)
15185 rtw_hal_update_hisr_hsisr_ind(adapter, 0);
15186
15187 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15188
15189 return 0;
15190 }
15191 #endif
15192
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)15193 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
15194 {
15195 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15196 u8 i;
15197
15198 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
15199 if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
15200 if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
15201 && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
15202 return i;
15203 }
15204 }
15205
15206 return -1;
15207 }
15208
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)15209 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
15210 {
15211 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15212 s8 res;
15213 u8 i;
15214
15215 /* If it's an existed record, overwrite it */
15216 res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
15217 if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
15218 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
15219 return;
15220 }
15221
15222 /* Search for the empty record to use */
15223 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
15224 if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
15225 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
15226 return;
15227 }
15228 }
15229
15230 /* Else, overwrite the oldest record */
15231 for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
15232 _rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
15233
15234 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
15235 }
15236
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)15237 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
15238 {
15239 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
15240 }
15241
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15242 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15243 {
15244 u32 mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
15245 u32 mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
15246 u32 mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
15247 u32 DropPacket = 0;
15248
15249 if (!rx_counter) {
15250 rtw_warn_on(1);
15251 return;
15252 }
15253 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
15254 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15255
15256 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
15257 mac_cck_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15258 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
15259 mac_ofdm_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15260 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
15261 mac_ht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15262 mac_vht_ok = 0;
15263 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15264 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
15265 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
15266 mac_vht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
15267 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15268 }
15269
15270 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
15271 mac_cck_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15272 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
15273 mac_ofdm_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15274 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
15275 mac_ht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15276 mac_vht_err = 0;
15277 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15278 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
15279 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
15280 mac_vht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
15281 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15282 }
15283
15284 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
15285 mac_cck_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15286 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
15287 mac_ofdm_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15288 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
15289 mac_ht_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15290
15291 /* Mac_DropPacket */
15292 rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
15293 DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
15294
15295 rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
15296 rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
15297 rx_counter->rx_cck_fa = mac_cck_fa;
15298 rx_counter->rx_ofdm_fa = mac_ofdm_fa;
15299 rx_counter->rx_ht_fa = mac_ht_fa;
15300 rx_counter->rx_pkt_drop = DropPacket;
15301 }
rtw_reset_mac_rx_counters(_adapter * padapter)15302 void rtw_reset_mac_rx_counters(_adapter *padapter)
15303 {
15304
15305 /* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
15306 if (IS_HARDWARE_TYPE_8703B(padapter) ||
15307 IS_HARDWARE_TYPE_8723D(padapter) ||
15308 IS_HARDWARE_TYPE_8188F(padapter) ||
15309 IS_HARDWARE_TYPE_8188GTV(padapter) ||
15310 IS_HARDWARE_TYPE_8192F(padapter) ||
15311 IS_HARDWARE_TYPE_8822C(padapter))
15312 phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
15313
15314 /* reset mac counter */
15315 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
15316 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
15317 }
15318
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15319 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15320 {
15321 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;
15322 if (!rx_counter) {
15323 rtw_warn_on(1);
15324 return;
15325 }
15326 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15327 cckok = phy_query_bb_reg(padapter, 0xF04, 0x3FFF); /* [13:0] */
15328 ofdmok = phy_query_bb_reg(padapter, 0xF14, 0x3FFF); /* [13:0] */
15329 htok = phy_query_bb_reg(padapter, 0xF10, 0x3FFF); /* [13:0] */
15330 vht_ok = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF); /* [13:0] */
15331 cckcrc = phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16] */
15332 ofdmcrc = phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
15333 htcrc = phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
15334 vht_err = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
15335 CCK_FA = phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
15336 OFDM_FA = phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
15337 } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){
15338 cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);
15339 ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
15340 htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
15341 vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);
15342 cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);
15343 ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
15344 htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
15345 vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);
15346 CCK_FA = phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);
15347 OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
15348 } else if(IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)){
15349 cckok = phy_query_bb_reg(padapter, 0x2aac, 0xffff);
15350 ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
15351 htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
15352 cckcrc = phy_query_bb_reg(padapter, 0x2aac, 0xffff0000);
15353 ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
15354 htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
15355 CCK_FA = phy_query_bb_reg(padapter, 0x2aa8, 0xffff0000) + phy_query_bb_reg(padapter, 0x2aa8, 0x0000ffff);
15356 OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
15357 } else {
15358 cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
15359 ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
15360 htok = phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
15361 vht_ok = 0;
15362 cckcrc = phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
15363 ofdmcrc = phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
15364 htcrc = phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
15365 vht_err = 0;
15366 OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
15367 phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
15368 phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
15369
15370 CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
15371 }
15372
15373 rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
15374 rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
15375 rx_counter->rx_ofdm_fa = OFDM_FA;
15376 rx_counter->rx_cck_fa = CCK_FA;
15377
15378 }
15379
rtw_reset_phy_trx_ok_counters(_adapter * padapter)15380 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
15381 {
15382 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15383 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
15384 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
15385 } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) {
15386 phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);
15387 phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);
15388 } else {
15389 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
15390 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
15391 }
15392 }
15393
rtw_reset_phy_rx_counters(_adapter * padapter)15394 void rtw_reset_phy_rx_counters(_adapter *padapter)
15395 {
15396 /* reset phy counter */
15397 if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
15398 /* reset CCK FA counter */
15399 phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);
15400 phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);
15401
15402 /* reset CCK CCA counter */
15403 phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);
15404 phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);
15405
15406 } else if (IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) {
15407 /* reset CCK FA and CCK CCA counter */
15408 phy_set_bb_reg(padapter, 0x2a44, BIT21, 0);
15409 phy_set_bb_reg(padapter, 0x2a44, BIT21, 1);
15410 rtw_reset_phy_trx_ok_counters(padapter);
15411
15412 } else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15413 rtw_reset_phy_trx_ok_counters(padapter);
15414
15415 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset OFDA FA counter */
15416 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
15417
15418 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
15419 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
15420 } else {
15421 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
15422 rtw_msleep_os(10);
15423 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
15424
15425 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset OFDA FA counter */
15426 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset OFDA FA counter */
15427 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
15428 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
15429
15430 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
15431 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
15432 }
15433 }
15434 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15435 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15436 {
15437 struct recv_priv *precvpriv = &padapter->recvpriv;
15438 if (!rx_counter) {
15439 rtw_warn_on(1);
15440 return;
15441 }
15442 rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
15443 rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
15444 rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
15445 }
rtw_reset_drv_rx_counters(_adapter * padapter)15446 void rtw_reset_drv_rx_counters(_adapter *padapter)
15447 {
15448 struct recv_priv *precvpriv = &padapter->recvpriv;
15449 padapter->drv_rx_cnt_ok = 0;
15450 padapter->drv_rx_cnt_crcerror = 0;
15451 padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
15452 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)15453 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
15454 {
15455 u8 initialgain;
15456 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15457
15458 if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
15459 rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
15460 RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
15461 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
15462 /*disable dynamic functions, such as high power, DIG*/
15463 rtw_phydm_ability_backup(padapter);
15464 rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
15465 } else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
15466 /* turn on phy-dynamic functions */
15467 rtw_phydm_ability_restore(padapter);
15468 initialgain = 0xff; /* restore RX GAIN */
15469 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
15470
15471 }
15472 }
15473
rtw_dump_rx_counters(_adapter * padapter)15474 void rtw_dump_rx_counters(_adapter *padapter)
15475 {
15476 struct dbg_rx_counter rx_counter;
15477
15478 if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
15479 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15480 rtw_dump_drv_rx_counters(padapter, &rx_counter);
15481 RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
15482 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
15483 rtw_reset_drv_rx_counters(padapter);
15484 }
15485
15486 if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
15487 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15488 rtw_dump_mac_rx_counters(padapter, &rx_counter);
15489 RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
15490 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
15491 rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
15492 rx_counter.rx_pkt_drop);
15493 rtw_reset_mac_rx_counters(padapter);
15494 }
15495
15496 if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
15497 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15498 rtw_dump_phy_rx_counters(padapter, &rx_counter);
15499 /* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
15500 /* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
15501 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,
15502 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
15503 rtw_reset_phy_rx_counters(padapter);
15504 }
15505 }
15506 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)15507 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
15508 {
15509 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15510 u8 curr_tx_sgi = 0;
15511 struct ra_sta_info *ra_info;
15512
15513 if (!psta)
15514 return curr_tx_sgi;
15515
15516 if (padapter->fix_rate == 0xff) {
15517 #if defined(CONFIG_RTL8188E)
15518 #if (RATE_ADAPTIVE_SUPPORT == 1)
15519 curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
15520 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
15521 #else
15522 ra_info = &psta->cmn.ra_info;
15523 curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
15524 #endif
15525 } else {
15526 curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
15527 }
15528
15529 return curr_tx_sgi;
15530 }
15531
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)15532 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
15533 {
15534 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15535 u8 rate_id = 0;
15536 struct ra_sta_info *ra_info;
15537
15538 if (!psta)
15539 return rate_id;
15540
15541 if (padapter->fix_rate == 0xff) {
15542 #if defined(CONFIG_RTL8188E)
15543 #if (RATE_ADAPTIVE_SUPPORT == 1)
15544 rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
15545 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
15546 #else
15547 ra_info = &psta->cmn.ra_info;
15548 rate_id = ra_info->curr_tx_rate & 0x7f;
15549 #endif
15550 } else {
15551 rate_id = padapter->fix_rate & 0x7f;
15552 }
15553
15554 return rate_id;
15555 }
15556
update_IOT_info(_adapter * padapter)15557 void update_IOT_info(_adapter *padapter)
15558 {
15559 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15560 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15561
15562 switch (pmlmeinfo->assoc_AP_vendor) {
15563 case HT_IOT_PEER_MARVELL:
15564 pmlmeinfo->turboMode_cts2self = 1;
15565 pmlmeinfo->turboMode_rtsen = 0;
15566 break;
15567
15568 case HT_IOT_PEER_RALINK:
15569 pmlmeinfo->turboMode_cts2self = 0;
15570 pmlmeinfo->turboMode_rtsen = 1;
15571 break;
15572 case HT_IOT_PEER_REALTEK:
15573 /* rtw_write16(padapter, 0x4cc, 0xffff); */
15574 /* rtw_write16(padapter, 0x546, 0x01c0); */
15575 break;
15576 default:
15577 pmlmeinfo->turboMode_cts2self = 0;
15578 pmlmeinfo->turboMode_rtsen = 1;
15579 break;
15580 }
15581
15582 }
15583 #ifdef CONFIG_RTS_FULL_BW
15584 /*
15585 8188E: not support full RTS BW feature(mac REG no define 480[5])
15586 */
rtw_set_rts_bw(_adapter * padapter)15587 void rtw_set_rts_bw(_adapter *padapter) {
15588 int i;
15589 u8 enable = 1;
15590 bool connect_to_8812 = _FALSE;
15591 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
15592 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
15593 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
15594 struct sta_info *station = NULL;
15595
15596 for (i = 0; i < macid_ctl->num; i++) {
15597 if (rtw_macid_is_used(macid_ctl, i)) {
15598
15599 station = NULL;
15600 station = macid_ctl->sta[i];
15601 if(station) {
15602
15603 _adapter *sta_adapter =station->padapter;
15604 struct mlme_ext_priv *pmlmeext = &(sta_adapter->mlmeextpriv);
15605 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15606
15607 if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {
15608 if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) {
15609 if ( macid_ctl->sta[i]->vendor_8812) {
15610 connect_to_8812 = _TRUE;
15611 enable = 0;
15612 }
15613 }
15614 }
15615 }
15616 }
15617
15618 if(connect_to_8812)
15619 break;
15620 }
15621
15622 RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);
15623 rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);
15624 }
15625 #endif/*CONFIG_RTS_FULL_BW*/
15626
hal_spec_init(_adapter * adapter)15627 int hal_spec_init(_adapter *adapter)
15628 {
15629 u8 interface_type = 0;
15630 int ret = _SUCCESS;
15631
15632 interface_type = rtw_get_intf_type(adapter);
15633
15634 switch (rtw_get_chip_type(adapter)) {
15635 #ifdef CONFIG_RTL8723B
15636 case RTL8723B:
15637 init_hal_spec_8723b(adapter);
15638 break;
15639 #endif
15640 #ifdef CONFIG_RTL8703B
15641 case RTL8703B:
15642 init_hal_spec_8703b(adapter);
15643 break;
15644 #endif
15645 #ifdef CONFIG_RTL8723D
15646 case RTL8723D:
15647 init_hal_spec_8723d(adapter);
15648 break;
15649 #endif
15650 #ifdef CONFIG_RTL8188E
15651 case RTL8188E:
15652 init_hal_spec_8188e(adapter);
15653 break;
15654 #endif
15655 #ifdef CONFIG_RTL8188F
15656 case RTL8188F:
15657 init_hal_spec_8188f(adapter);
15658 break;
15659 #endif
15660 #ifdef CONFIG_RTL8188GTV
15661 case RTL8188GTV:
15662 init_hal_spec_8188gtv(adapter);
15663 break;
15664 #endif
15665 #ifdef CONFIG_RTL8812A
15666 case RTL8812:
15667 init_hal_spec_8812a(adapter);
15668 break;
15669 #endif
15670 #ifdef CONFIG_RTL8821A
15671 case RTL8821:
15672 init_hal_spec_8821a(adapter);
15673 break;
15674 #endif
15675 #ifdef CONFIG_RTL8192E
15676 case RTL8192E:
15677 init_hal_spec_8192e(adapter);
15678 break;
15679 #endif
15680 #ifdef CONFIG_RTL8814A
15681 case RTL8814A:
15682 init_hal_spec_8814a(adapter);
15683 break;
15684 #endif
15685 #ifdef CONFIG_RTL8822B
15686 case RTL8822B:
15687 rtl8822b_init_hal_spec(adapter);
15688 break;
15689 #endif
15690 #ifdef CONFIG_RTL8821C
15691 case RTL8821C:
15692 init_hal_spec_rtl8821c(adapter);
15693 break;
15694 #endif
15695 #ifdef CONFIG_RTL8710B
15696 case RTL8710B:
15697 init_hal_spec_8710b(adapter);
15698 break;
15699 #endif
15700 #ifdef CONFIG_RTL8192F
15701 case RTL8192F:
15702 init_hal_spec_8192f(adapter);
15703 break;
15704 #endif
15705 #ifdef CONFIG_RTL8822C
15706 case RTL8822C:
15707 rtl8822c_init_hal_spec(adapter);
15708 break;
15709 #endif
15710 #ifdef CONFIG_RTL8814B
15711 case RTL8814B:
15712 rtl8814b_init_hal_spec(adapter);
15713 break;
15714 #endif
15715 #ifdef CONFIG_RTL8723F
15716 case RTL8723F:
15717 rtl8723f_init_hal_spec(adapter);
15718 break;
15719 #endif
15720 default:
15721 RTW_ERR("%s: unknown chip_type:%u\n"
15722 , __func__, rtw_get_chip_type(adapter));
15723 ret = _FAIL;
15724 break;
15725 }
15726
15727 return ret;
15728 }
15729
15730 static const char *const _band_cap_str[] = {
15731 /* BIT0 */"2G",
15732 /* BIT1 */"5G",
15733 };
15734
15735 static const char *const _bw_cap_str[] = {
15736 /* BIT0 */"5M",
15737 /* BIT1 */"10M",
15738 /* BIT2 */"20M",
15739 /* BIT3 */"40M",
15740 /* BIT4 */"80M",
15741 /* BIT5 */"160M",
15742 /* BIT6 */"80_80M",
15743 };
15744
15745 static const char *const _proto_cap_str[] = {
15746 /* BIT0 */"b",
15747 /* BIT1 */"g",
15748 /* BIT2 */"n",
15749 /* BIT3 */"ac",
15750 };
15751
15752 static const char *const _wl_func_str[] = {
15753 /* BIT0 */"P2P",
15754 /* BIT1 */"MIRACAST",
15755 /* BIT2 */"TDLS",
15756 /* BIT3 */"FTM",
15757 };
15758
dump_hal_spec(void * sel,_adapter * adapter)15759 void dump_hal_spec(void *sel, _adapter *adapter)
15760 {
15761 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
15762 int i;
15763
15764 RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
15765 RTW_PRINT_SEL(sel, "macid_cap:%u\n", hal_spec->macid_cap);
15766 RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
15767 RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
15768
15769 RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
15770 RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
15771 RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);
15772 RTW_PRINT_SEL(sel, "rf_reg_path_avail_num:%u\n", hal_spec->rf_reg_path_avail_num);
15773 RTW_PRINT_SEL(sel, "rf_reg_trx_path_bmp:0x%02x\n", hal_spec->rf_reg_trx_path_bmp);
15774 RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
15775
15776 RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
15777 RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
15778
15779 RTW_PRINT_SEL(sel, "band_cap:");
15780 for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
15781 if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
15782 _RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
15783 }
15784 _RTW_PRINT_SEL(sel, "\n");
15785
15786 RTW_PRINT_SEL(sel, "bw_cap:");
15787 for (i = 0; i < BW_CAP_BIT_NUM; i++) {
15788 if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
15789 _RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
15790 }
15791 _RTW_PRINT_SEL(sel, "\n");
15792
15793 RTW_PRINT_SEL(sel, "proto_cap:");
15794 for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
15795 if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
15796 _RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
15797 }
15798 _RTW_PRINT_SEL(sel, "\n");
15799
15800 RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
15801 RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
15802
15803 RTW_PRINT_SEL(sel, "wl_func:");
15804 for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
15805 if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
15806 _RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
15807 }
15808 _RTW_PRINT_SEL(sel, "\n");
15809
15810 #if CONFIG_TX_AC_LIFETIME
15811 RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"
15812 , hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);
15813 #endif
15814
15815 RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
15816
15817 RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
15818 RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
15819 }
15820
hal_chk_band_cap(_adapter * adapter,u8 cap)15821 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
15822 {
15823 return GET_HAL_SPEC(adapter)->band_cap & cap;
15824 }
15825
hal_chk_bw_cap(_adapter * adapter,u8 cap)15826 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
15827 {
15828 return GET_HAL_SPEC(adapter)->bw_cap & cap;
15829 }
15830
hal_chk_proto_cap(_adapter * adapter,u8 cap)15831 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
15832 {
15833 return GET_HAL_SPEC(adapter)->proto_cap & cap;
15834 }
15835
hal_chk_wl_func(_adapter * adapter,u8 func)15836 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
15837 {
15838 return GET_HAL_SPEC(adapter)->wl_func & func;
15839 }
15840
hal_is_band_support(_adapter * adapter,u8 band)15841 inline bool hal_is_band_support(_adapter *adapter, u8 band)
15842 {
15843 return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
15844 }
15845
hal_is_bw_support(_adapter * adapter,u8 bw)15846 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
15847 {
15848 return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
15849 }
15850
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)15851 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
15852 {
15853 u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
15854
15855 if (mode == WIRELESS_11B)
15856 if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15857 return 1;
15858
15859 if (mode == WIRELESS_11G)
15860 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15861 return 1;
15862
15863 if (mode == WIRELESS_11A)
15864 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15865 return 1;
15866
15867 if (mode == WIRELESS_11_24N)
15868 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
15869 return 1;
15870
15871 if (mode == WIRELESS_11_5N)
15872 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15873 return 1;
15874
15875 if (mode == WIRELESS_11AC)
15876 if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
15877 return 1;
15878
15879 return 0;
15880 }
hal_is_mimo_support(_adapter * adapter)15881 inline bool hal_is_mimo_support(_adapter *adapter)
15882 {
15883 if ((GET_HAL_TX_NSS(adapter) == 1) &&
15884 (GET_HAL_RX_NSS(adapter) == 1))
15885 return 0;
15886 return 1;
15887 }
15888
15889 /*
15890 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
15891 * @adapter:
15892 * @in_bw: starting bw, value of enum channel_width
15893 *
15894 * Returns: value of enum channel_width
15895 */
hal_largest_bw(_adapter * adapter,u8 in_bw)15896 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
15897 {
15898 for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
15899 if (hal_is_bw_support(adapter, in_bw))
15900 break;
15901 }
15902
15903 if (!hal_is_bw_support(adapter, in_bw))
15904 rtw_warn_on(1);
15905
15906 return in_bw;
15907 }
15908
15909 #ifndef CONFIG_HAS_TX_BEACON_PAUSE
ResumeTxBeacon(_adapter * padapter)15910 void ResumeTxBeacon(_adapter *padapter)
15911 {
15912 RTW_DBG("ResumeTxBeacon\n");
15913 #ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE
15914 rtw_write8(padapter, REG_TXPAUSE,
15915 rtw_read8(padapter, REG_TXPAUSE) & (~BIT6));
15916 #else
15917 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15918 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
15919 #endif
15920
15921 #ifdef RTW_HALMAC
15922 /* Add this for driver using HALMAC because driver doesn't have setup time init by self */
15923 /* TBTT setup time */
15924 rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
15925 #endif
15926
15927 /* TBTT hold time: 0x540[19:8] */
15928 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
15929 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15930 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
15931 }
15932
StopTxBeacon(_adapter * padapter)15933 void StopTxBeacon(_adapter *padapter)
15934 {
15935 RTW_DBG("StopTxBeacon\n");
15936 #ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE
15937 rtw_write8(padapter, REG_TXPAUSE,
15938 rtw_read8(padapter, REG_TXPAUSE) | BIT6);
15939 #else
15940 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
15941 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
15942 #endif
15943
15944 /* TBTT hold time: 0x540[19:8] */
15945 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
15946 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
15947 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
15948 }
15949 #endif /* CONFIG_HAS_TX_BEACON_PAUSE */
15950
15951 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
15952
15953 #ifdef CONFIG_CLIENT_PORT_CFG
15954 const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
15955 CLT_PORT0,
15956 CLT_PORT1,
15957 CLT_PORT2,
15958 CLT_PORT3
15959 };
15960
rtw_clt_port_init(struct clt_port_t * cltp)15961 void rtw_clt_port_init(struct clt_port_t *cltp)
15962 {
15963 cltp->bmp = 0;
15964 cltp->num = 0;
15965 _rtw_spinlock_init(&cltp->lock);
15966 }
rtw_clt_port_deinit(struct clt_port_t * cltp)15967 void rtw_clt_port_deinit(struct clt_port_t *cltp)
15968 {
15969 _rtw_spinlock_free(&cltp->lock);
15970 }
_hw_client_port_alloc(_adapter * adapter)15971 static void _hw_client_port_alloc(_adapter *adapter)
15972 {
15973 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
15974 struct clt_port_t *cltp = &dvobj->clt_port;
15975 _irqL irql;
15976 int i;
15977
15978 #if 0
15979 if (cltp->num > MAX_CLIENT_PORT_NUM) {
15980 RTW_ERR(ADPT_FMT" cann't alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
15981 rtw_warn_on(1);
15982 return;
15983 }
15984 #endif
15985
15986 if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
15987 RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
15988 ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
15989 return;
15990 }
15991 _enter_critical_bh(&cltp->lock, &irql);
15992 for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
15993 if (!(cltp->bmp & BIT(i)))
15994 break;
15995 }
15996
15997 if (i < MAX_CLIENT_PORT_NUM) {
15998 adapter->client_id = i;
15999 cltp->bmp |= BIT(i);
16000 adapter->client_port = _clt_port_id[i];
16001 }
16002 cltp->num++;
16003 _exit_critical_bh(&cltp->lock, &irql);
16004 RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
16005 __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
16006 }
_hw_client_port_free(_adapter * adapter)16007 static void _hw_client_port_free(_adapter *adapter)
16008 {
16009 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
16010 struct clt_port_t *cltp = &dvobj->clt_port;
16011 _irqL irql;
16012
16013 #if 0
16014 if (adapter->client_id >= MAX_CLIENT_PORT_NUM) {
16015 RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
16016 /*rtw_warn_on(1);*/
16017 }
16018 #endif
16019
16020 RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
16021 __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
16022
16023 _enter_critical_bh(&cltp->lock, &irql);
16024 if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
16025 cltp->bmp &= ~ BIT(adapter->client_id);
16026 adapter->client_id = MAX_CLIENT_PORT_NUM;
16027 adapter->client_port = CLT_PORT_INVALID;
16028 }
16029 cltp->num--;
16030 if (cltp->num < 0)
16031 cltp->num = 0;
16032 _exit_critical_bh(&cltp->lock, &irql);
16033 }
rtw_hw_client_port_allocate(_adapter * adapter)16034 void rtw_hw_client_port_allocate(_adapter *adapter)
16035 {
16036 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16037
16038 if (hal_spec->port_num != 5)
16039 return;
16040
16041 _hw_client_port_alloc(adapter);
16042 }
rtw_hw_client_port_release(_adapter * adapter)16043 void rtw_hw_client_port_release(_adapter *adapter)
16044 {
16045 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16046
16047 if (hal_spec->port_num != 5)
16048 return;
16049
16050 _hw_client_port_free(adapter);
16051 }
16052 #endif /*CONFIG_CLIENT_PORT_CFG*/
16053
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)16054 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
16055 {
16056 RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
16057
16058 rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
16059
16060 /* set net_type */
16061 Set_MSR(Adapter, mode);
16062
16063 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
16064 if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
16065 StopTxBeacon(Adapter);
16066 } else if (mode == _HW_STATE_ADHOC_)
16067 ResumeTxBeacon(Adapter);
16068 else if (mode == _HW_STATE_AP_)
16069 /* enable rx ps-poll */
16070 rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
16071
16072 /* enable rx data frame */
16073 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
16074
16075 #ifdef CONFIG_CLIENT_PORT_CFG
16076 if (mode == _HW_STATE_STATION_)
16077 rtw_hw_client_port_allocate(Adapter);
16078 else
16079 rtw_hw_client_port_release(Adapter);
16080 #endif
16081 #if defined(CONFIG_RTL8192F)
16082 rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
16083 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
16084 #endif
16085 }
16086 #endif
16087
16088 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)16089 u8 rtw_hal_antdiv_before_linked(_adapter *padapter)
16090 {
16091 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16092 u8 cur_ant, change_ant;
16093
16094 if (!pHalData->AntDivCfg)
16095 return _FALSE;
16096
16097 if (pHalData->sw_antdiv_bl_state == 0) {
16098 pHalData->sw_antdiv_bl_state = 1;
16099
16100 rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
16101 change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
16102
16103 return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
16104 }
16105
16106 pHalData->sw_antdiv_bl_state = 0;
16107 return _FALSE;
16108 }
16109
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)16110 void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
16111 {
16112 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16113
16114 if (pHalData->AntDivCfg) {
16115 /*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
16116 /*select optimum_antenna for before linked =>For antenna diversity*/
16117 if (dst->Rssi >= src->Rssi) {/*keep org parameter*/
16118 src->Rssi = dst->Rssi;
16119 src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
16120 }
16121 }
16122 }
16123 #endif
16124
16125 #ifdef CONFIG_PROC_DEBUG
16126 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)16127 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
16128 {
16129 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
16130 struct phy_spec_t *phy_spec = &pHalData->phy_spec;
16131
16132 RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
16133 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
16134 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
16135 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index [15:8]*/
16136 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index [7:0]*/
16137
16138 RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
16139 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]*/
16140 /*VHT STBC Rx [23:16]
16141 0 = not support
16142 1 = support for 1 spatial stream
16143 2 = support for 1 or 2 spatial streams
16144 3 = support for 1 or 2 or 3 spatial streams
16145 4 = support for 1 or 2 or 3 or 4 spatial streams*/
16146 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
16147 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]*/
16148 /*HT STBC Rx [7:0]
16149 0 = not support
16150 1 = support for 1 spatial stream
16151 2 = support for 1 or 2 spatial streams
16152 3 = support for 1 or 2 or 3 spatial streams*/
16153 RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
16154
16155 RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
16156 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]*/
16157 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]*/
16158 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]*/
16159 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]*/
16160 #ifdef CONFIG_BEAMFORMING
16161 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
16162 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]*/
16163 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]*/
16164 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]*/
16165 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]*/
16166 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF) ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
16167 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
16168
16169 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
16170 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
16171 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
16172 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
16173 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
16174 #endif
16175 }
16176 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)16177 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
16178 {
16179 u8 phy_cap = _FALSE;
16180
16181 /* STBC */
16182 rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
16183 RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16184
16185 phy_cap = _FALSE;
16186 rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
16187 RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16188
16189 /* LDPC support */
16190 phy_cap = _FALSE;
16191 rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
16192 RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16193
16194 phy_cap = _FALSE;
16195 rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
16196 RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16197
16198 #ifdef CONFIG_BEAMFORMING
16199 phy_cap = _FALSE;
16200 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
16201 RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16202
16203 phy_cap = _FALSE;
16204 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
16205 RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16206
16207 phy_cap = _FALSE;
16208 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
16209 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16210
16211 phy_cap = _FALSE;
16212 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
16213 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16214 #endif
16215 }
16216 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)16217 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
16218 {
16219 RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
16220 #ifdef CONFIG_PHY_CAPABILITY_QUERY
16221 rtw_dump_phy_cap_by_phydmapi(sel, adapter);
16222 #else
16223 rtw_dump_phy_cap_by_hal(sel, adapter);
16224 #endif
16225 }
16226 #endif
16227
translate_dbm_to_percentage(s16 signal)16228 inline s16 translate_dbm_to_percentage(s16 signal)
16229 {
16230 if ((signal <= -100) || (signal >= 20))
16231 return 0;
16232 else if (signal >= 0)
16233 return 100;
16234 else
16235 return 100 + signal;
16236 }
16237
16238 #ifdef CONFIG_SWTIMER_BASED_TXBCN
16239 #ifdef CONFIG_BCN_RECOVERY
16240 #define REG_CPU_MGQ_INFO 0x041C
16241 #define BIT_BCN_POLL BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)16242 u8 rtw_ap_bcn_recovery(_adapter *padapter)
16243 {
16244 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
16245
16246 if (hal_data->issue_bcn_fail >= 2) {
16247 RTW_ERR("%s ISSUE BCN Fail\n", __func__);
16248 rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
16249 hal_data->issue_bcn_fail = 0;
16250 }
16251 return _SUCCESS;
16252 }
16253 #endif /*CONFIG_BCN_RECOVERY*/
16254
16255 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)16256 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
16257 {
16258 u32 start_time = rtw_get_current_time();
16259 u8 bcn_queue_empty = _FALSE;
16260
16261 do {
16262 if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
16263 bcn_queue_empty = _TRUE;
16264 break;
16265 }
16266 } while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
16267
16268 if (bcn_queue_empty == _FALSE)
16269 RTW_ERR("%s BCN queue not empty\n", __func__);
16270
16271 return bcn_queue_empty;
16272 }
16273 #endif /*CONFIG_BCN_XMIT_PROTECT*/
16274 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
16275
16276 /**
16277 * rtw_hal_get_trx_path() - Get RF path related information
16278 * @d: struct dvobj_priv*
16279 * @type: RF type, nTnR
16280 * @tx: Tx path
16281 * @rx: Rx path
16282 *
16283 * Get RF type, TX path and RX path information.
16284 */
rtw_hal_get_trx_path(struct dvobj_priv * d,enum rf_type * type,enum bb_path * tx,enum bb_path * rx)16285 void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,
16286 enum bb_path *tx, enum bb_path *rx)
16287 {
16288 struct _ADAPTER *a = dvobj_get_primary_adapter(d);
16289 enum rf_type t = GET_HAL_RFPATH(a);
16290
16291 if (type)
16292 *type = t;
16293
16294 if (tx || rx) {
16295 u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);
16296 u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);
16297
16298 if (!tx_bmp && !rx_bmp)
16299 rf_type_to_default_trx_bmp(t, tx, rx);
16300 else {
16301 if (tx)
16302 *tx = GET_HAL_TX_PATH_BMP(a);
16303 if (rx)
16304 *rx = GET_HAL_RX_PATH_BMP(a);
16305 }
16306 }
16307 }
16308
16309 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
rtw_hal_switch_chnl_and_set_bw_offload(_adapter * adapter,u8 central_ch,u8 pri_ch_idx,u8 bw)16310 void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
16311 {
16312 u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
16313 PHAL_DATA_TYPE hal;
16314 struct submit_ctx *chsw_sctx;
16315
16316 hal = GET_HAL_DATA(adapter);
16317 chsw_sctx = &hal->chsw_sctx;
16318
16319 SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
16320 SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
16321 SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
16322 SET_H2CCMD_SINGLE_CH_SWITCH_V2_IQK_UPDATE_EN(h2c, 1);
16323
16324 rtw_sctx_init(chsw_sctx, 10);
16325 rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
16326 rtw_sctx_wait(chsw_sctx, __func__);
16327 }
16328 #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
16329
phy_get_capable_tx_num(_adapter * adapter,enum MGN_RATE rate)16330 u8 phy_get_capable_tx_num(_adapter *adapter, enum MGN_RATE rate)
16331 {
16332 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16333 u8 tx_num = 0;
16334
16335 if (IS_1T_RATE(rate))
16336 tx_num = hal_data->txpath_cap_num_nss[0];
16337 else if (IS_2T_RATE(rate))
16338 tx_num = hal_data->txpath_cap_num_nss[1];
16339 else if (IS_3T_RATE(rate))
16340 tx_num = hal_data->txpath_cap_num_nss[2];
16341 else if (IS_4T_RATE(rate))
16342 tx_num = hal_data->txpath_cap_num_nss[3];
16343 else
16344 rtw_warn_on(1);
16345
16346 return tx_num == 0 ? RF_1TX : tx_num - 1;
16347 }
16348
phy_get_current_tx_num(_adapter * adapter,enum MGN_RATE rate)16349 u8 phy_get_current_tx_num(_adapter *adapter, enum MGN_RATE rate)
16350 {
16351 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16352 u8 tx_num = 0;
16353
16354 if (IS_1T_RATE(rate))
16355 tx_num = hal_data->txpath_num_nss[0];
16356 else if (IS_2T_RATE(rate))
16357 tx_num = hal_data->txpath_num_nss[1];
16358 else if (IS_3T_RATE(rate))
16359 tx_num = hal_data->txpath_num_nss[2];
16360 else if (IS_4T_RATE(rate))
16361 tx_num = hal_data->txpath_num_nss[3];
16362 else
16363 rtw_warn_on(1);
16364
16365 return tx_num == 0 ? RF_1TX : tx_num - 1;
16366 }
16367
16368 #ifdef CONFIG_RTL8812A
rtw_hal_set_8812a_vendor_ie(_adapter * padapter,u8 * pframe,uint * frlen)16369 u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {
16370 int vender_len = 7;
16371 unsigned char vendor_info[vender_len];
16372 unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
16373 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16374
16375 if( !IS_HARDWARE_TYPE_8812(padapter) )
16376 return pframe;
16377
16378 _rtw_memset(vendor_info,0,vender_len);
16379 _rtw_memcpy(vendor_info, REALTEK_OUI, 3);
16380 vendor_info[4] =2;
16381 if(pHalData->version_id.CUTVersion > B_CUT_VERSION )
16382 vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;
16383 else
16384 vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;
16385 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);
16386
16387 return pframe;
16388 }
16389 #endif /*CONFIG_RTL8812A*/
16390
rtw_enter_protsel(struct protsel * protsel,u32 sel)16391 static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)
16392 {
16393 int refcnt;
16394
16395 _enter_critical_mutex(&protsel->mutex, NULL);
16396
16397 refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);
16398
16399 WARN_ON(refcnt > 1 && protsel->sel != sel);
16400
16401 protsel->sel = sel;
16402
16403 _exit_critical_mutex(&protsel->mutex, NULL);
16404 }
16405
rtw_leave_protsel(struct protsel * protsel)16406 static inline void rtw_leave_protsel(struct protsel *protsel)
16407 {
16408 int refcnt;
16409
16410 _enter_critical_mutex(&protsel->mutex, NULL);
16411
16412 refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);
16413
16414 _exit_critical_mutex(&protsel->mutex, NULL);
16415
16416 WARN_ON(refcnt < 0);
16417 }
16418
rtw_assert_protsel(struct protsel * protsel)16419 static inline bool rtw_assert_protsel(struct protsel *protsel)
16420 {
16421 int refcnt = ATOMIC_READ(&protsel->refcnt);
16422
16423 if (refcnt > 0)
16424 return true;
16425
16426 return false;
16427 }
16428
16429 #ifdef CONFIG_PROTSEL_PORT
rtw_enter_protsel_port(_adapter * padapter,u8 port_sel)16430 void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)
16431 {
16432 u8 val8;
16433
16434 rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);
16435
16436 val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);
16437 val8 &= ~BIT_MASK_PORT_CTRL_SEL;
16438 val8 |= BIT_PORT_CTRL_SEL(port_sel);
16439 rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);
16440 }
16441
rtw_assert_protsel_port(_adapter * padapter,u32 addr,u8 len)16442 bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)
16443 {
16444 if (!padapter->bup) /* don't assert before IF up */
16445 return true;
16446
16447 return rtw_assert_protsel(&padapter->dvobj->protsel_port);
16448 }
16449
rtw_leave_protsel_port(_adapter * padapter)16450 void rtw_leave_protsel_port(_adapter *padapter)
16451 {
16452 rtw_leave_protsel(&padapter->dvobj->protsel_port);
16453 }
16454 #endif
16455
16456 #ifdef CONFIG_PROTSEL_ATIMDTIM
rtw_enter_protsel_atimdtim(_adapter * padapter,u8 port_sel)16457 void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)
16458 {
16459 /* 0~15 is for port 0 MBSSID setting
16460 * 16 is for port 1 setting
16461 * 17 is for port 2 setting
16462 * 18 is for port 3 setting
16463 * 19 is for port 4 setting
16464 */
16465 u8 val8;
16466
16467 if (port_sel >= 1 && port_sel <= 4)
16468 port_sel += 15;
16469
16470 rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);
16471
16472 val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);
16473 val8 &= ~BIT_MASK_ATIM_DTIM_SEL;
16474 val8 |= BIT_ATIM_DTIM_SEL(port_sel);
16475 rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);
16476 }
16477
rtw_assert_protsel_atimdtim(_adapter * padapter,u32 addr,u8 len)16478 bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)
16479 {
16480 return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);
16481 }
16482
rtw_leave_protsel_atimdtim(_adapter * padapter)16483 void rtw_leave_protsel_atimdtim(_adapter *padapter)
16484 {
16485 rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);
16486 }
16487 #endif
16488
16489 #ifdef CONFIG_PROTSEL_MACSLEEP
rtw_enter_protsel_macsleep(_adapter * padapter,u8 sel)16490 void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)
16491 {
16492 u32 val32;
16493
16494 rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);
16495
16496 val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);
16497 val32 &= ~BIT_MASK_MACID_SLEEP_SEL;
16498 val32 |= BIT_MACID_SLEEP_SEL(sel);
16499 rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);
16500 }
16501
rtw_assert_protsel_macsleep(_adapter * padapter,u32 addr,u8 len)16502 bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)
16503 {
16504 return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);
16505 }
16506
rtw_leave_protsel_macsleep(_adapter * padapter)16507 void rtw_leave_protsel_macsleep(_adapter *padapter)
16508 {
16509 rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);
16510 }
16511 #endif
16512
rtw_hal_bcn_early_rpt_c2h_handler(_adapter * padapter)16513 void rtw_hal_bcn_early_rpt_c2h_handler(_adapter *padapter)
16514 {
16515
16516 if(0)
16517 RTW_INFO("Recv Bcn Early report!!\n");
16518
16519 #ifdef CONFIG_TDLS
16520 #ifdef CONFIG_TDLS_CH_SW
16521 if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
16522 rtw_tdls_ch_sw_back_to_base_chnl(padapter);
16523 #endif
16524 #endif
16525 }
16526