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,const char * hw_alpha2,u8 hw_chplan,u8 hw_chplan_6g,BOOLEAN AutoLoadFail)380 void hal_com_config_channel_plan(
381 PADAPTER padapter,
382 const char *hw_alpha2,
383 u8 hw_chplan,
384 u8 hw_chplan_6g,
385 BOOLEAN AutoLoadFail
386 )
387 {
388 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
389 u8 force_hw_chplan = _FALSE;
390
391 /*
392 * autoload fail, by pass all hw settings
393 */
394 if (AutoLoadFail == _TRUE) {
395 hw_alpha2 = NULL;
396 hw_chplan = RTW_CHPLAN_UNSPECIFIED;
397 goto init;
398 }
399
400 /*
401 * treat {0xFF, 0xFF} as unspecified
402 */
403 if (hw_alpha2 && strncmp(hw_alpha2, "\xFF\xFF", 2) == 0)
404 hw_alpha2 = NULL;
405
406 /*
407 * treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing
408 * and check hw setting with only country code
409 */
410 if (hw_chplan == 0xFF) {
411 hw_chplan = RTW_CHPLAN_UNSPECIFIED;
412 goto init;
413 }
414
415 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
416 if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
417 force_hw_chplan = _TRUE;
418 #endif
419 hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
420
421 init:
422 rtw_rfctl_decide_init_chplan(adapter_to_rfctl(padapter), hw_alpha2, hw_chplan, hw_chplan_6g, force_hw_chplan);
423 }
424
425 BOOLEAN
HAL_IsLegalChannel(PADAPTER Adapter,u32 Channel)426 HAL_IsLegalChannel(
427 PADAPTER Adapter,
428 u32 Channel
429 )
430 {
431 BOOLEAN bLegalChannel = _TRUE;
432
433 if (Channel > 14) {
434 if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
435 bLegalChannel = _FALSE;
436 RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
437 }
438 } else if ((Channel <= 14) && (Channel >= 1)) {
439 if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
440 bLegalChannel = _FALSE;
441 RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
442 }
443 } else {
444 bLegalChannel = _FALSE;
445 RTW_INFO("Channel is Invalid !!!\n");
446 }
447
448 return bLegalChannel;
449 }
450
451 static const u8 _MRateToHwRate[MGN_UNKNOWN] = {
452 [MGN_1M] = DESC_RATE1M,
453 [MGN_2M] = DESC_RATE2M,
454 [MGN_5_5M] = DESC_RATE5_5M,
455 [MGN_11M] = DESC_RATE11M,
456 [MGN_6M] = DESC_RATE6M,
457 [MGN_9M] = DESC_RATE9M,
458 [MGN_12M] = DESC_RATE12M,
459 [MGN_18M] = DESC_RATE18M,
460 [MGN_24M] = DESC_RATE24M,
461 [MGN_36M] = DESC_RATE36M,
462 [MGN_48M] = DESC_RATE48M,
463 [MGN_54M] = DESC_RATE54M,
464 [MGN_MCS0] = DESC_RATEMCS0,
465 [MGN_MCS1] = DESC_RATEMCS1,
466 [MGN_MCS2] = DESC_RATEMCS2,
467 [MGN_MCS3] = DESC_RATEMCS3,
468 [MGN_MCS4] = DESC_RATEMCS4,
469 [MGN_MCS5] = DESC_RATEMCS5,
470 [MGN_MCS6] = DESC_RATEMCS6,
471 [MGN_MCS7] = DESC_RATEMCS7,
472 [MGN_MCS8] = DESC_RATEMCS8,
473 [MGN_MCS9] = DESC_RATEMCS9,
474 [MGN_MCS10] = DESC_RATEMCS10,
475 [MGN_MCS11] = DESC_RATEMCS11,
476 [MGN_MCS12] = DESC_RATEMCS12,
477 [MGN_MCS13] = DESC_RATEMCS13,
478 [MGN_MCS14] = DESC_RATEMCS14,
479 [MGN_MCS15] = DESC_RATEMCS15,
480 [MGN_MCS16] = DESC_RATEMCS16,
481 [MGN_MCS17] = DESC_RATEMCS17,
482 [MGN_MCS18] = DESC_RATEMCS18,
483 [MGN_MCS19] = DESC_RATEMCS19,
484 [MGN_MCS20] = DESC_RATEMCS20,
485 [MGN_MCS21] = DESC_RATEMCS21,
486 [MGN_MCS22] = DESC_RATEMCS22,
487 [MGN_MCS23] = DESC_RATEMCS23,
488 [MGN_MCS24] = DESC_RATEMCS24,
489 [MGN_MCS25] = DESC_RATEMCS25,
490 [MGN_MCS26] = DESC_RATEMCS26,
491 [MGN_MCS27] = DESC_RATEMCS27,
492 [MGN_MCS28] = DESC_RATEMCS28,
493 [MGN_MCS29] = DESC_RATEMCS29,
494 [MGN_MCS30] = DESC_RATEMCS30,
495 [MGN_MCS31] = DESC_RATEMCS31,
496 [MGN_VHT1SS_MCS0] = DESC_RATEVHTSS1MCS0,
497 [MGN_VHT1SS_MCS1] = DESC_RATEVHTSS1MCS1,
498 [MGN_VHT1SS_MCS2] = DESC_RATEVHTSS1MCS2,
499 [MGN_VHT1SS_MCS3] = DESC_RATEVHTSS1MCS3,
500 [MGN_VHT1SS_MCS4] = DESC_RATEVHTSS1MCS4,
501 [MGN_VHT1SS_MCS5] = DESC_RATEVHTSS1MCS5,
502 [MGN_VHT1SS_MCS6] = DESC_RATEVHTSS1MCS6,
503 [MGN_VHT1SS_MCS7] = DESC_RATEVHTSS1MCS7,
504 [MGN_VHT1SS_MCS8] = DESC_RATEVHTSS1MCS8,
505 [MGN_VHT1SS_MCS9] = DESC_RATEVHTSS1MCS9,
506 [MGN_VHT2SS_MCS0] = DESC_RATEVHTSS2MCS0,
507 [MGN_VHT2SS_MCS1] = DESC_RATEVHTSS2MCS1,
508 [MGN_VHT2SS_MCS2] = DESC_RATEVHTSS2MCS2,
509 [MGN_VHT2SS_MCS3] = DESC_RATEVHTSS2MCS3,
510 [MGN_VHT2SS_MCS4] = DESC_RATEVHTSS2MCS4,
511 [MGN_VHT2SS_MCS5] = DESC_RATEVHTSS2MCS5,
512 [MGN_VHT2SS_MCS6] = DESC_RATEVHTSS2MCS6,
513 [MGN_VHT2SS_MCS7] = DESC_RATEVHTSS2MCS7,
514 [MGN_VHT2SS_MCS8] = DESC_RATEVHTSS2MCS8,
515 [MGN_VHT2SS_MCS9] = DESC_RATEVHTSS2MCS9,
516 [MGN_VHT3SS_MCS0] = DESC_RATEVHTSS3MCS0,
517 [MGN_VHT3SS_MCS1] = DESC_RATEVHTSS3MCS1,
518 [MGN_VHT3SS_MCS2] = DESC_RATEVHTSS3MCS2,
519 [MGN_VHT3SS_MCS3] = DESC_RATEVHTSS3MCS3,
520 [MGN_VHT3SS_MCS4] = DESC_RATEVHTSS3MCS4,
521 [MGN_VHT3SS_MCS5] = DESC_RATEVHTSS3MCS5,
522 [MGN_VHT3SS_MCS6] = DESC_RATEVHTSS3MCS6,
523 [MGN_VHT3SS_MCS7] = DESC_RATEVHTSS3MCS7,
524 [MGN_VHT3SS_MCS8] = DESC_RATEVHTSS3MCS8,
525 [MGN_VHT3SS_MCS9] = DESC_RATEVHTSS3MCS9,
526 [MGN_VHT4SS_MCS0] = DESC_RATEVHTSS4MCS0,
527 [MGN_VHT4SS_MCS1] = DESC_RATEVHTSS4MCS1,
528 [MGN_VHT4SS_MCS2] = DESC_RATEVHTSS4MCS2,
529 [MGN_VHT4SS_MCS3] = DESC_RATEVHTSS4MCS3,
530 [MGN_VHT4SS_MCS4] = DESC_RATEVHTSS4MCS4,
531 [MGN_VHT4SS_MCS5] = DESC_RATEVHTSS4MCS5,
532 [MGN_VHT4SS_MCS6] = DESC_RATEVHTSS4MCS6,
533 [MGN_VHT4SS_MCS7] = DESC_RATEVHTSS4MCS7,
534 [MGN_VHT4SS_MCS8] = DESC_RATEVHTSS4MCS8,
535 [MGN_VHT4SS_MCS9] = DESC_RATEVHTSS4MCS9,
536 };
537
MRateToHwRate(enum MGN_RATE rate)538 u8 MRateToHwRate(enum MGN_RATE rate)
539 {
540 u8 hw_rate = DESC_RATE1M; /* default value, also is zero */
541
542 if (rate < MGN_UNKNOWN)
543 hw_rate = _MRateToHwRate[rate];
544
545 if (rate != MGN_1M && hw_rate == DESC_RATE1M)
546 RTW_WARN("Invalid rate 0x%x in %s\n", rate, __FUNCTION__);
547
548 return hw_rate;
549 }
550
551 const char * const _HDATA_RATE[DESC_RATE_NUM + 1] = {
552 [DESC_RATE1M] = "CCK_1M",
553 [DESC_RATE2M] = "CCK_2M",
554 [DESC_RATE5_5M] = "CCK5_5M",
555 [DESC_RATE11M] = "CCK_11M",
556 [DESC_RATE6M] = "OFDM_6M",
557 [DESC_RATE9M] = "OFDM_9M",
558 [DESC_RATE12M] = "OFDM_12M",
559 [DESC_RATE18M] = "OFDM_18M",
560 [DESC_RATE24M] = "OFDM_24M",
561 [DESC_RATE36M] = "OFDM_36M",
562 [DESC_RATE48M] = "OFDM_48M",
563 [DESC_RATE54M] = "OFDM_54M",
564 [DESC_RATEMCS0] = "MCS0",
565 [DESC_RATEMCS1] = "MCS1",
566 [DESC_RATEMCS2] = "MCS2",
567 [DESC_RATEMCS3] = "MCS3",
568 [DESC_RATEMCS4] = "MCS4",
569 [DESC_RATEMCS5] = "MCS5",
570 [DESC_RATEMCS6] = "MCS6",
571 [DESC_RATEMCS7] = "MCS7",
572 [DESC_RATEMCS8] = "MCS8",
573 [DESC_RATEMCS9] = "MCS9",
574 [DESC_RATEMCS10] = "MCS10",
575 [DESC_RATEMCS11] = "MCS11",
576 [DESC_RATEMCS12] = "MCS12",
577 [DESC_RATEMCS13] = "MCS13",
578 [DESC_RATEMCS14] = "MCS14",
579 [DESC_RATEMCS15] = "MCS15",
580 [DESC_RATEMCS16] = "MCS16",
581 [DESC_RATEMCS17] = "MCS17",
582 [DESC_RATEMCS18] = "MCS18",
583 [DESC_RATEMCS19] = "MCS19",
584 [DESC_RATEMCS20] = "MCS20",
585 [DESC_RATEMCS21] = "MCS21",
586 [DESC_RATEMCS22] = "MCS22",
587 [DESC_RATEMCS23] = "MCS23",
588 [DESC_RATEMCS24] = "MCS24",
589 [DESC_RATEMCS25] = "MCS25",
590 [DESC_RATEMCS26] = "MCS26",
591 [DESC_RATEMCS27] = "MCS27",
592 [DESC_RATEMCS28] = "MCS28",
593 [DESC_RATEMCS29] = "MCS29",
594 [DESC_RATEMCS30] = "MCS30",
595 [DESC_RATEMCS31] = "MCS31",
596 [DESC_RATEVHTSS1MCS0] = "VHT1SMCS0",
597 [DESC_RATEVHTSS1MCS1] = "VHT1SMCS1",
598 [DESC_RATEVHTSS1MCS2] = "VHT1SMCS2",
599 [DESC_RATEVHTSS1MCS3] = "VHT1SMCS3",
600 [DESC_RATEVHTSS1MCS4] = "VHT1SMCS4",
601 [DESC_RATEVHTSS1MCS5] = "VHT1SMCS5",
602 [DESC_RATEVHTSS1MCS6] = "VHT1SMCS6",
603 [DESC_RATEVHTSS1MCS7] = "VHT1SMCS7",
604 [DESC_RATEVHTSS1MCS8] = "VHT1SMCS8",
605 [DESC_RATEVHTSS1MCS9] = "VHT1SMCS9",
606 [DESC_RATEVHTSS2MCS0] = "VHT2SMCS0",
607 [DESC_RATEVHTSS2MCS1] = "VHT2SMCS1",
608 [DESC_RATEVHTSS2MCS2] = "VHT2SMCS2",
609 [DESC_RATEVHTSS2MCS3] = "VHT2SMCS3",
610 [DESC_RATEVHTSS2MCS4] = "VHT2SMCS4",
611 [DESC_RATEVHTSS2MCS5] = "VHT2SMCS5",
612 [DESC_RATEVHTSS2MCS6] = "VHT2SMCS6",
613 [DESC_RATEVHTSS2MCS7] = "VHT2SMCS7",
614 [DESC_RATEVHTSS2MCS8] = "VHT2SMCS8",
615 [DESC_RATEVHTSS2MCS9] = "VHT2SMCS9",
616 [DESC_RATEVHTSS3MCS0] = "VHT3SMCS0",
617 [DESC_RATEVHTSS3MCS1] = "VHT3SMCS1",
618 [DESC_RATEVHTSS3MCS2] = "VHT3SMCS2",
619 [DESC_RATEVHTSS3MCS3] = "VHT3SMCS3",
620 [DESC_RATEVHTSS3MCS4] = "VHT3SMCS4",
621 [DESC_RATEVHTSS3MCS5] = "VHT3SMCS5",
622 [DESC_RATEVHTSS3MCS6] = "VHT3SMCS6",
623 [DESC_RATEVHTSS3MCS7] = "VHT3SMCS7",
624 [DESC_RATEVHTSS3MCS8] = "VHT3SMCS8",
625 [DESC_RATEVHTSS3MCS9] = "VHT3SMCS9",
626 [DESC_RATEVHTSS4MCS0] = "VHT4SMCS0",
627 [DESC_RATEVHTSS4MCS1] = "VHT4SMCS1",
628 [DESC_RATEVHTSS4MCS2] = "VHT4SMCS2",
629 [DESC_RATEVHTSS4MCS3] = "VHT4SMCS3",
630 [DESC_RATEVHTSS4MCS4] = "VHT4SMCS4",
631 [DESC_RATEVHTSS4MCS5] = "VHT4SMCS5",
632 [DESC_RATEVHTSS4MCS6] = "VHT4SMCS6",
633 [DESC_RATEVHTSS4MCS7] = "VHT4SMCS7",
634 [DESC_RATEVHTSS4MCS8] = "VHT4SMCS8",
635 [DESC_RATEVHTSS4MCS9] = "VHT4SMCS9",
636 [DESC_RATE_NUM] = "UNKNOWN",
637 };
638
639 static const u8 _hw_rate_to_m_rate[DESC_RATE_NUM] = {
640 [DESC_RATE1M] = MGN_1M,
641 [DESC_RATE2M] = MGN_2M,
642 [DESC_RATE5_5M] = MGN_5_5M,
643 [DESC_RATE11M] = MGN_11M,
644 [DESC_RATE6M] = MGN_6M,
645 [DESC_RATE9M] = MGN_9M,
646 [DESC_RATE12M] = MGN_12M,
647 [DESC_RATE18M] = MGN_18M,
648 [DESC_RATE24M] = MGN_24M,
649 [DESC_RATE36M] = MGN_36M,
650 [DESC_RATE48M] = MGN_48M,
651 [DESC_RATE54M] = MGN_54M,
652 [DESC_RATEMCS0] = MGN_MCS0,
653 [DESC_RATEMCS1] = MGN_MCS1,
654 [DESC_RATEMCS2] = MGN_MCS2,
655 [DESC_RATEMCS3] = MGN_MCS3,
656 [DESC_RATEMCS4] = MGN_MCS4,
657 [DESC_RATEMCS5] = MGN_MCS5,
658 [DESC_RATEMCS6] = MGN_MCS6,
659 [DESC_RATEMCS7] = MGN_MCS7,
660 [DESC_RATEMCS8] = MGN_MCS8,
661 [DESC_RATEMCS9] = MGN_MCS9,
662 [DESC_RATEMCS10] = MGN_MCS10,
663 [DESC_RATEMCS11] = MGN_MCS11,
664 [DESC_RATEMCS12] = MGN_MCS12,
665 [DESC_RATEMCS13] = MGN_MCS13,
666 [DESC_RATEMCS14] = MGN_MCS14,
667 [DESC_RATEMCS15] = MGN_MCS15,
668 [DESC_RATEMCS16] = MGN_MCS16,
669 [DESC_RATEMCS17] = MGN_MCS17,
670 [DESC_RATEMCS18] = MGN_MCS18,
671 [DESC_RATEMCS19] = MGN_MCS19,
672 [DESC_RATEMCS20] = MGN_MCS20,
673 [DESC_RATEMCS21] = MGN_MCS21,
674 [DESC_RATEMCS22] = MGN_MCS22,
675 [DESC_RATEMCS23] = MGN_MCS23,
676 [DESC_RATEMCS24] = MGN_MCS24,
677 [DESC_RATEMCS25] = MGN_MCS25,
678 [DESC_RATEMCS26] = MGN_MCS26,
679 [DESC_RATEMCS27] = MGN_MCS27,
680 [DESC_RATEMCS28] = MGN_MCS28,
681 [DESC_RATEMCS29] = MGN_MCS29,
682 [DESC_RATEMCS30] = MGN_MCS30,
683 [DESC_RATEMCS31] = MGN_MCS31,
684 [DESC_RATEVHTSS1MCS0] = MGN_VHT1SS_MCS0,
685 [DESC_RATEVHTSS1MCS1] = MGN_VHT1SS_MCS1,
686 [DESC_RATEVHTSS1MCS2] = MGN_VHT1SS_MCS2,
687 [DESC_RATEVHTSS1MCS3] = MGN_VHT1SS_MCS3,
688 [DESC_RATEVHTSS1MCS4] = MGN_VHT1SS_MCS4,
689 [DESC_RATEVHTSS1MCS5] = MGN_VHT1SS_MCS5,
690 [DESC_RATEVHTSS1MCS6] = MGN_VHT1SS_MCS6,
691 [DESC_RATEVHTSS1MCS7] = MGN_VHT1SS_MCS7,
692 [DESC_RATEVHTSS1MCS8] = MGN_VHT1SS_MCS8,
693 [DESC_RATEVHTSS1MCS9] = MGN_VHT1SS_MCS9,
694 [DESC_RATEVHTSS2MCS0] = MGN_VHT2SS_MCS0,
695 [DESC_RATEVHTSS2MCS1] = MGN_VHT2SS_MCS1,
696 [DESC_RATEVHTSS2MCS2] = MGN_VHT2SS_MCS2,
697 [DESC_RATEVHTSS2MCS3] = MGN_VHT2SS_MCS3,
698 [DESC_RATEVHTSS2MCS4] = MGN_VHT2SS_MCS4,
699 [DESC_RATEVHTSS2MCS5] = MGN_VHT2SS_MCS5,
700 [DESC_RATEVHTSS2MCS6] = MGN_VHT2SS_MCS6,
701 [DESC_RATEVHTSS2MCS7] = MGN_VHT2SS_MCS7,
702 [DESC_RATEVHTSS2MCS8] = MGN_VHT2SS_MCS8,
703 [DESC_RATEVHTSS2MCS9] = MGN_VHT2SS_MCS9,
704 [DESC_RATEVHTSS3MCS0] = MGN_VHT3SS_MCS0,
705 [DESC_RATEVHTSS3MCS1] = MGN_VHT3SS_MCS1,
706 [DESC_RATEVHTSS3MCS2] = MGN_VHT3SS_MCS2,
707 [DESC_RATEVHTSS3MCS3] = MGN_VHT3SS_MCS3,
708 [DESC_RATEVHTSS3MCS4] = MGN_VHT3SS_MCS4,
709 [DESC_RATEVHTSS3MCS5] = MGN_VHT3SS_MCS5,
710 [DESC_RATEVHTSS3MCS6] = MGN_VHT3SS_MCS6,
711 [DESC_RATEVHTSS3MCS7] = MGN_VHT3SS_MCS7,
712 [DESC_RATEVHTSS3MCS8] = MGN_VHT3SS_MCS8,
713 [DESC_RATEVHTSS3MCS9] = MGN_VHT3SS_MCS9,
714 [DESC_RATEVHTSS4MCS0] = MGN_VHT4SS_MCS0,
715 [DESC_RATEVHTSS4MCS1] = MGN_VHT4SS_MCS1,
716 [DESC_RATEVHTSS4MCS2] = MGN_VHT4SS_MCS2,
717 [DESC_RATEVHTSS4MCS3] = MGN_VHT4SS_MCS3,
718 [DESC_RATEVHTSS4MCS4] = MGN_VHT4SS_MCS4,
719 [DESC_RATEVHTSS4MCS5] = MGN_VHT4SS_MCS5,
720 [DESC_RATEVHTSS4MCS6] = MGN_VHT4SS_MCS6,
721 [DESC_RATEVHTSS4MCS7] = MGN_VHT4SS_MCS7,
722 [DESC_RATEVHTSS4MCS8] = MGN_VHT4SS_MCS8,
723 [DESC_RATEVHTSS4MCS9] = MGN_VHT4SS_MCS9,
724 };
725
hw_rate_to_m_rate(u8 hw_rate)726 u8 hw_rate_to_m_rate(u8 hw_rate)
727 {
728 u8 rate = MGN_1M; /* default value */
729
730 if (hw_rate < DESC_RATE_NUM)
731 rate = _hw_rate_to_m_rate[hw_rate];
732 else
733 RTW_WARN("Invalid hw_rate 0x%x in %s\n", hw_rate, __FUNCTION__);
734
735 return rate;
736 }
737
738 #ifdef CONFIG_RTW_DEBUG
dump_hw_rate_map_test(void * sel)739 void dump_hw_rate_map_test(void *sel)
740 {
741 RATE_SECTION rs;
742 u8 hw_rate;
743 enum MGN_RATE m_rate;
744 int i;
745
746 for (rs = 0; rs < RATE_SECTION_NUM; rs++) {
747 for (i = 0; i < rates_by_sections[rs].rate_num; i++) {
748 hw_rate = MRateToHwRate(rates_by_sections[rs].rates[i]);
749 RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
750 , MGN_RATE_STR(rates_by_sections[rs].rates[i]), rates_by_sections[rs].rates[i]
751 , HDATA_RATE(hw_rate), hw_rate
752 );
753 }
754 if (rs == HT_4SS) { /* show MCS32 after MCS31 */
755 hw_rate = MRateToHwRate(MGN_MCS32);
756 RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
757 , MGN_RATE_STR(MGN_MCS32), MGN_MCS32
758 , HDATA_RATE(hw_rate), hw_rate
759 );
760 }
761 }
762 hw_rate = MRateToHwRate(MGN_UNKNOWN);
763 RTW_PRINT_SEL(sel, "m_rate:%s(%d) to hw_rate:%s(%d)\n"
764 , MGN_RATE_STR(MGN_UNKNOWN), MGN_UNKNOWN
765 , HDATA_RATE(hw_rate), hw_rate
766 );
767
768 for (i = DESC_RATE1M; i <= DESC_RATE_NUM; i++) {
769 m_rate = hw_rate_to_m_rate(i);
770 RTW_PRINT_SEL(sel, "hw_rate:%s(%d) to m_rate:%s(%d)\n"
771 , HDATA_RATE(i), i
772 , MGN_RATE_STR(m_rate), m_rate
773 );
774 }
775 }
776 #endif /* CONFIG_RTW_DEBUG */
777
HalSetBrateCfg(PADAPTER Adapter,u8 * mBratesOS,u16 * pBrateCfg)778 void HalSetBrateCfg(
779 PADAPTER Adapter,
780 u8 *mBratesOS,
781 u16 *pBrateCfg)
782 {
783 u8 i, is_brate, brate;
784
785 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
786 is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
787 brate = mBratesOS[i] & 0x7f;
788
789 if (is_brate) {
790 switch (brate) {
791 case IEEE80211_CCK_RATE_1MB:
792 *pBrateCfg |= RATE_1M;
793 break;
794 case IEEE80211_CCK_RATE_2MB:
795 *pBrateCfg |= RATE_2M;
796 break;
797 case IEEE80211_CCK_RATE_5MB:
798 *pBrateCfg |= RATE_5_5M;
799 break;
800 case IEEE80211_CCK_RATE_11MB:
801 *pBrateCfg |= RATE_11M;
802 break;
803 case IEEE80211_OFDM_RATE_6MB:
804 *pBrateCfg |= RATE_6M;
805 break;
806 case IEEE80211_OFDM_RATE_9MB:
807 *pBrateCfg |= RATE_9M;
808 break;
809 case IEEE80211_OFDM_RATE_12MB:
810 *pBrateCfg |= RATE_12M;
811 break;
812 case IEEE80211_OFDM_RATE_18MB:
813 *pBrateCfg |= RATE_18M;
814 break;
815 case IEEE80211_OFDM_RATE_24MB:
816 *pBrateCfg |= RATE_24M;
817 break;
818 case IEEE80211_OFDM_RATE_36MB:
819 *pBrateCfg |= RATE_36M;
820 break;
821 case IEEE80211_OFDM_RATE_48MB:
822 *pBrateCfg |= RATE_48M;
823 break;
824 case IEEE80211_OFDM_RATE_54MB:
825 *pBrateCfg |= RATE_54M;
826 break;
827 }
828 }
829 }
830 }
831
832 static void
_OneOutPipeMapping(PADAPTER pAdapter)833 _OneOutPipeMapping(
834 PADAPTER pAdapter
835 )
836 {
837 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
838
839 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
840 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
841 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
842 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
843
844 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
845 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
846 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
847 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
848 }
849
850 static void
_TwoOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)851 _TwoOutPipeMapping(
852 PADAPTER pAdapter,
853 BOOLEAN bWIFICfg
854 )
855 {
856 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
857
858 if (bWIFICfg) { /* WMM */
859
860 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
861 /* { 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
862 /* 0:ep_0 num, 1:ep_1 num */
863
864 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
865 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
866 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
867 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
868
869 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
870 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
871 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
872 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
873
874 } else { /* typical setting */
875
876
877 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
878 /* { 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
879 /* 0:ep_0 num, 1:ep_1 num */
880
881 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
882 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
883 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
884 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
885
886 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
887 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
888 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
889 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
890
891 }
892
893 }
894
_ThreeOutPipeMapping(PADAPTER pAdapter,BOOLEAN bWIFICfg)895 static void _ThreeOutPipeMapping(
896 PADAPTER pAdapter,
897 BOOLEAN bWIFICfg
898 )
899 {
900 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
901
902 if (bWIFICfg) { /* for WMM */
903
904 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
905 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
906 /* 0:H, 1:N, 2:L */
907
908 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
909 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
910 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
911 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* 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 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
923 /* 0:H, 1:N, 2:L */
924
925 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
926 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
927 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
928 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* 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 #if 0
938 static void _FourOutPipeMapping(
939 PADAPTER pAdapter,
940 BOOLEAN bWIFICfg
941 )
942 {
943 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
944
945 if (bWIFICfg) { /* for WMM */
946
947 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
948 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
949 /* 0:H, 1:N, 2:L ,3:E */
950
951 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
952 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
953 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
954 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
955
956 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
957 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
958 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
959 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
960
961 } else { /* typical setting */
962
963
964 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
965 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
966 /* 0:H, 1:N, 2:L */
967
968 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
969 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
970 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
971 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
972
973 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
974 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
975 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
976 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
977 }
978
979 }
980 #endif
981 BOOLEAN
Hal_MappingOutPipe(PADAPTER pAdapter,u8 NumOutPipe)982 Hal_MappingOutPipe(
983 PADAPTER pAdapter,
984 u8 NumOutPipe
985 )
986 {
987 struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
988
989 BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
990
991 BOOLEAN result = _TRUE;
992
993 switch (NumOutPipe) {
994 case 2:
995 _TwoOutPipeMapping(pAdapter, bWIFICfg);
996 break;
997 case 3:
998 case 4:
999 case 5:
1000 case 6:
1001 _ThreeOutPipeMapping(pAdapter, bWIFICfg);
1002 break;
1003 case 1:
1004 _OneOutPipeMapping(pAdapter);
1005 break;
1006 default:
1007 result = _FALSE;
1008 break;
1009 }
1010
1011 return result;
1012
1013 }
1014
rtw_hal_reqtxrpt(_adapter * padapter,u8 macid)1015 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1016 {
1017 if (padapter->hal_func.reqtxrpt)
1018 padapter->hal_func.reqtxrpt(padapter, macid);
1019 }
1020
rtw_get_sta_tx_stat(_adapter * adapter,u8 mac_id,u8 * macaddr)1021 int rtw_get_sta_tx_stat(_adapter *adapter, u8 mac_id, u8 *macaddr)
1022 {
1023 struct sta_priv *pstapriv_primary = &(GET_PRIMARY_ADAPTER(adapter))->stapriv;
1024 struct submit_ctx gotc2h;
1025 u8 cmd_ret;
1026 int ret = _SUCCESS;
1027
1028 if (!adapter->hal_func.reqtxrpt) {
1029 RTW_INFO("Not support.\n");
1030 ret = RTW_NOT_SUPPORT;
1031 goto exit;
1032 }
1033
1034 if (pstapriv_primary->gotc2h != NULL) {
1035 RTW_INFO("sta tx stat is processing.\n");
1036 ret = RTW_BUSY;
1037 goto exit;
1038 }
1039
1040 rtw_sctx_init(&gotc2h, 60);
1041 pstapriv_primary->gotc2h = &gotc2h;
1042 _rtw_memcpy(pstapriv_primary->c2h_sta_mac, macaddr, ETH_ALEN);
1043 pstapriv_primary->c2h_adapter_id = adapter->iface_id;
1044
1045 cmd_ret = rtw_reqtxrpt_cmd(adapter, mac_id);
1046 if (cmd_ret != _SUCCESS) {
1047 RTW_WARN("rtw_reqtxrpt_cmd fail\n");
1048 ret = _FAIL;
1049 } else
1050 rtw_sctx_wait(&gotc2h, __func__);
1051
1052 enter_critical_bh(&pstapriv_primary->tx_rpt_lock);
1053 pstapriv_primary->gotc2h = NULL;
1054 exit_critical_bh(&pstapriv_primary->tx_rpt_lock);
1055
1056 if (cmd_ret == _SUCCESS && gotc2h.status != RTW_SCTX_DONE_SUCCESS) {
1057 RTW_WARN("wait for C2H timeout, operation abort!!\n");
1058 ret = _FAIL;
1059 }
1060
1061 _rtw_memset(pstapriv_primary->c2h_sta_mac, 0, ETH_ALEN);
1062 pstapriv_primary->c2h_adapter_id = CONFIG_IFACE_NUMBER;
1063
1064 exit:
1065 return ret;
1066 }
1067
rtw_hal_dump_macaddr(void * sel,_adapter * adapter)1068 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1069 {
1070 int i;
1071 _adapter *iface;
1072 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1073 u8 mac_addr[ETH_ALEN];
1074
1075 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1076 rtw_mbid_cam_dump(sel, __func__, adapter);
1077 #else
1078 rtw_mi_hal_dump_macaddr(sel, adapter);
1079 #endif
1080 }
1081
1082 /**
1083 * rtw_hal_set_hw_macaddr() - Set HW MAC address
1084 * @adapter: struct PADAPTER
1085 * @mac_addr: 6-bytes mac address
1086 *
1087 * Set Wifi Mac address by writing to the relative HW registers,
1088 *
1089 */
rtw_hal_set_hw_macaddr(PADAPTER adapter,u8 * mac_addr)1090 void rtw_hal_set_hw_macaddr(PADAPTER adapter, u8 *mac_addr)
1091 {
1092 rtw_ps_deny(adapter, PS_DENY_IOCTL);
1093 LeaveAllPowerSaveModeDirect(adapter);
1094
1095 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1096 rtw_hal_change_macaddr_mbid(adapter, mac_addr);
1097 #else
1098 rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR, mac_addr);
1099 #endif
1100 #ifdef CONFIG_RTW_DEBUG
1101 rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1102 #endif
1103 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
1104 }
1105
1106 #ifdef RTW_HALMAC
rtw_hal_hw_port_enable(_adapter * adapter)1107 void rtw_hal_hw_port_enable(_adapter *adapter)
1108 {
1109 #if 1
1110 u8 port_enable = _TRUE;
1111
1112 rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1113 #else
1114 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1115 struct rtw_halmac_bcn_ctrl bcn_ctrl;
1116
1117 _rtw_memset(&bcn_ctrl, 0, sizeof(struct rtw_halmac_bcn_ctrl));
1118 bcn_ctrl.enable_bcn = 1;
1119 bcn_ctrl.rx_bssid_fit = 1;
1120 bcn_ctrl.rxbcn_rpt = 1;
1121
1122 /*rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
1123 struct rtw_halmac_bcn_ctrl *bcn_ctrl)*/
1124 if (rtw_halmac_set_bcn_ctrl(dvobj, get_hw_port(adapter), &bcn_ctrl) == -1) {
1125 RTW_ERR(ADPT_FMT" - hw port(%d) enable fail!!\n", ADPT_ARG(adapter), get_hw_port(adapter));
1126 rtw_warn_on(1);
1127 }
1128 #endif
1129 }
rtw_hal_hw_port_disable(_adapter * adapter)1130 void rtw_hal_hw_port_disable(_adapter *adapter)
1131 {
1132 u8 port_enable = _FALSE;
1133
1134 rtw_hal_set_hwreg(adapter, HW_VAR_PORT_CFG, &port_enable);
1135 }
1136
rtw_restore_hw_port_cfg(_adapter * adapter)1137 void rtw_restore_hw_port_cfg(_adapter *adapter)
1138 {
1139 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1140
1141 #else
1142 int i;
1143 _adapter *iface;
1144 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1145
1146 for (i = 0; i < dvobj->iface_nums; i++) {
1147 iface = dvobj->padapters[i];
1148 if (iface)
1149 rtw_hal_hw_port_enable(iface);
1150 }
1151 #endif
1152 }
1153 #endif
1154
rtw_mi_set_mac_addr(_adapter * adapter)1155 void rtw_mi_set_mac_addr(_adapter *adapter)
1156 {
1157 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1158 rtw_mi_set_mbid_cam(adapter);
1159 #else
1160 int i;
1161 _adapter *iface;
1162 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1163
1164 for (i = 0; i < dvobj->iface_nums; i++) {
1165 iface = dvobj->padapters[i];
1166 if (iface)
1167 rtw_hal_set_hwreg(iface, HW_VAR_MAC_ADDR, adapter_mac_addr(iface));
1168 }
1169 #endif
1170 if (0)
1171 rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1172 }
1173
rtw_init_hal_com_default_value(PADAPTER Adapter)1174 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1175 {
1176 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
1177 struct registry_priv *regsty = adapter_to_regsty(Adapter);
1178
1179 pHalData->AntDetection = 1;
1180 pHalData->antenna_test = _FALSE;
1181 pHalData->RegIQKFWOffload = regsty->iqk_fw_offload;
1182 pHalData->ch_switch_offload = regsty->ch_switch_offload;
1183 pHalData->multi_ch_switch_mode = 0;
1184 #ifdef RTW_REDUCE_SCAN_SWITCH_CH_TIME
1185 if (pHalData->ch_switch_offload == 0)
1186 pHalData->ch_switch_offload = 1;
1187 #endif
1188 }
1189
1190 #ifdef CONFIG_FW_C2H_REG
c2h_evt_clear(_adapter * adapter)1191 void c2h_evt_clear(_adapter *adapter)
1192 {
1193 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1194 }
1195
c2h_evt_read_88xx(_adapter * adapter,u8 * buf)1196 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1197 {
1198 s32 ret = _FAIL;
1199 int i;
1200 u8 trigger;
1201
1202 if (buf == NULL)
1203 goto exit;
1204
1205 trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1206
1207 if (trigger == C2H_EVT_HOST_CLOSE) {
1208 goto exit; /* Not ready */
1209 } else if (trigger != C2H_EVT_FW_CLOSE) {
1210 goto clear_evt; /* Not a valid value */
1211 }
1212
1213 _rtw_memset(buf, 0, C2H_REG_LEN);
1214
1215 /* Read ID, LEN, SEQ */
1216 SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
1217 SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
1218 SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
1219
1220 if (0) {
1221 RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
1222 , C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
1223 }
1224
1225 /* Read the content */
1226 for (i = 0; i < C2H_PLEN_88XX(buf); i++)
1227 *(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1228
1229 RTW_DBG_DUMP("payload: ", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
1230
1231 ret = _SUCCESS;
1232
1233 clear_evt:
1234 /*
1235 * Clear event to notify FW we have read the command.
1236 * If this field isn't clear, the FW won't update the next command message.
1237 */
1238 c2h_evt_clear(adapter);
1239
1240 exit:
1241 return ret;
1242 }
1243 #endif /* CONFIG_FW_C2H_REG */
1244
1245 #ifdef CONFIG_FW_C2H_PKT
1246 #ifndef DBG_C2H_PKT_PRE_HDL
1247 #define DBG_C2H_PKT_PRE_HDL 0
1248 #endif
1249 #ifndef DBG_C2H_PKT_HDL
1250 #define DBG_C2H_PKT_HDL 0
1251 #endif
rtw_hal_c2h_pkt_pre_hdl(_adapter * adapter,u8 * buf,u16 len)1252 void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
1253 {
1254 #ifdef RTW_HALMAC
1255 /* TODO: extract hal_mac IC's code here*/
1256 #else
1257 u8 parse_fail = 0;
1258 u8 hdl_here = 0;
1259 s32 ret = _FAIL;
1260 u8 id, seq, plen;
1261 u8 *payload;
1262
1263 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1264 parse_fail = 1;
1265 goto exit;
1266 }
1267
1268 hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
1269 if (hdl_here)
1270 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1271 else
1272 ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
1273
1274 exit:
1275 if (parse_fail)
1276 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1277 else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
1278 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1279 , hdl_here ? "handle" : "enqueue"
1280 , ret == _SUCCESS ? "ok" : "fail"
1281 );
1282 if (DBG_C2H_PKT_PRE_HDL >= 2)
1283 RTW_PRINT_DUMP("dump: ", buf, len);
1284 }
1285 #endif
1286 }
1287
rtw_hal_c2h_pkt_hdl(_adapter * adapter,u8 * buf,u16 len)1288 void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
1289 {
1290 #ifdef RTW_HALMAC
1291 adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
1292 #else
1293 u8 parse_fail = 0;
1294 u8 bypass = 0;
1295 s32 ret = _FAIL;
1296 u8 id, seq, plen;
1297 u8 *payload;
1298
1299 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1300 parse_fail = 1;
1301 goto exit;
1302 }
1303
1304 #ifdef CONFIG_WOWLAN
1305 if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
1306 bypass = 1;
1307 ret = _SUCCESS;
1308 goto exit;
1309 }
1310 #endif
1311
1312 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1313
1314 exit:
1315 if (parse_fail)
1316 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1317 else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
1318 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1319 , !bypass ? "handle" : "bypass"
1320 , ret == _SUCCESS ? "ok" : "fail"
1321 );
1322 if (DBG_C2H_PKT_HDL >= 2)
1323 RTW_PRINT_DUMP("dump: ", buf, len);
1324 }
1325 #endif
1326 }
1327 #endif /* CONFIG_FW_C2H_PKT */
1328
c2h_iqk_offload(_adapter * adapter,u8 * data,u8 len)1329 void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
1330 {
1331 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1332 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1333
1334 RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
1335 if (0)
1336 RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
1337
1338 rtw_sctx_done(&iqk_sctx);
1339 }
1340
c2h_iqk_offload_wait(_adapter * adapter,u32 timeout_ms)1341 int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
1342 {
1343 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1344 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1345
1346 iqk_sctx->submit_time = rtw_get_current_time();
1347 iqk_sctx->timeout_ms = timeout_ms;
1348 iqk_sctx->status = RTW_SCTX_SUBMITTED;
1349
1350 return rtw_sctx_wait(iqk_sctx, __func__);
1351 }
1352
1353 #ifdef CONFIG_FW_OFFLOAD_SET_TXPWR_IDX
c2h_txpwr_idx_offload_done(_adapter * adapter,u8 * data,u8 len)1354 void c2h_txpwr_idx_offload_done(_adapter *adapter, u8 *data, u8 len)
1355 {
1356 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1357 struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1358
1359 if (0)
1360 RTW_INFO("txpwr_idx offload finish in %dms\n", rtw_get_passing_time_ms(sctx->submit_time));
1361 rtw_sctx_done(&sctx);
1362 }
1363
c2h_txpwr_idx_offload_wait(_adapter * adapter)1364 int c2h_txpwr_idx_offload_wait(_adapter *adapter)
1365 {
1366 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1367 struct submit_ctx *sctx = &hal_data->txpwr_idx_offload_sctx;
1368
1369 return rtw_sctx_wait(sctx, __func__);
1370 }
1371 #endif
1372
1373 #define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1374 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1375 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1376 #define GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1377 #define GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1378 #define GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
1379 #define GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
1380 #define GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1381 #define GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1382 #define GET_C2H_MAC_HIDDEN_RPT_BW(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1383 #define GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1384 #define GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1385 #define GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1386
1387 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1388 #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1389 #endif
1390
1391 #ifdef CONFIG_RTW_MAC_HIDDEN_RPT
c2h_mac_hidden_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1392 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1393 {
1394 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1395 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1396 enum rf_type rf_type;
1397 u8 tx_path_num, rx_path_num;
1398 int ret = _FAIL;
1399
1400 u8 uuid_x;
1401 u8 uuid_y;
1402 u8 uuid_z;
1403 u16 uuid_crc;
1404
1405 u8 hci_type;
1406 u8 package_type;
1407 u8 tr_switch;
1408 u8 wl_func;
1409 u8 hw_stype;
1410 u8 bw;
1411 u8 ss_num = 4;
1412 u8 ant_num;
1413 u8 protocol;
1414 u8 nic;
1415
1416 int i;
1417
1418 if (len < MAC_HIDDEN_RPT_LEN) {
1419 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1420 goto exit;
1421 }
1422
1423 uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1424 uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1425 uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1426 uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1427
1428 hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1429 package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1430
1431 tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
1432
1433 wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1434 hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1435
1436 bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1437 ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1438
1439 protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1440 nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1441
1442 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1443 for (i = 0; i < len; i++)
1444 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1445
1446 RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1447 RTW_PRINT("hci_type:0x%x\n", hci_type);
1448 RTW_PRINT("package_type:0x%x\n", package_type);
1449 RTW_PRINT("tr_switch:0x%x\n", tr_switch);
1450 RTW_PRINT("wl_func:0x%x\n", wl_func);
1451 RTW_PRINT("hw_stype:0x%x\n", hw_stype);
1452 RTW_PRINT("bw:0x%x\n", bw);
1453 RTW_PRINT("ant_num:0x%x\n", ant_num);
1454 RTW_PRINT("protocol:0x%x\n", protocol);
1455 RTW_PRINT("nic:0x%x\n", nic);
1456 }
1457
1458 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
1459 if (IS_8822C_SERIES(hal_data->version_id) || IS_8814B_SERIES(hal_data->version_id)) {
1460 #define GET_C2H_MAC_HIDDEN_RPT_SS_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)
1461 ss_num = GET_C2H_MAC_HIDDEN_RPT_SS_NUM(data);
1462
1463 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1464 RTW_PRINT("ss_num:0x%x\n", ss_num);
1465
1466 if (ss_num == 0x03)
1467 ss_num = 4;
1468 }
1469 #endif
1470
1471 #if defined(CONFIG_RTL8822C)
1472 if (IS_8822C_SERIES(hal_data->version_id)) {
1473 if (ant_num == 1)
1474 hal_spec->rf_reg_trx_path_bmp = 0x22; /* 1T1R pathB */
1475 if (hw_stype == 0xE)
1476 hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, 1); /* limit 1TX only */
1477 }
1478 #endif
1479 hal_data->PackageType = package_type;
1480 hal_spec->hci_type = hci_type;
1481 hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1482 hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1483 hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1484
1485 rf_type = rtw_chip_rftype_to_hal_rftype(adapter, 0);
1486 if (!RF_TYPE_VALID(rf_type)) {
1487 RTW_ERR("%s rtw_chip_rftype_to_hal_rftype failed\n", __func__);
1488 goto exit;
1489 }
1490 hal_spec->rf_reg_path_avail_num = rtw_min(hal_spec->rf_reg_path_num, ant_num);
1491 tx_path_num = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1492 rx_path_num = rtw_min(rf_type_to_rf_rx_cnt(rf_type), hal_spec->rf_reg_path_avail_num);
1493 hal_spec->rf_reg_trx_path_bmp = rtw_restrict_trx_path_bmp_by_trx_num_lmt(
1494 hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num, &tx_path_num, &rx_path_num);
1495 if (!hal_spec->rf_reg_trx_path_bmp) {
1496 RTW_ERR("%s rtw_restrict_trx_path_bmp_by_trx_num_lmt(0x%x, %u, %u) failed\n"
1497 , __func__, hal_spec->rf_reg_trx_path_bmp, tx_path_num, rx_path_num);
1498 goto exit;
1499 }
1500 hal_spec->rf_reg_path_avail_num = rtw_max(tx_path_num, rx_path_num);
1501
1502 /*
1503 * RF TX path num >= max_tx_cnt >= tx_nss_num
1504 * ex: RF TX path num(4) >= max_tx_cnt(2) >= tx_nss_num(1)
1505 * Select at most 2 out of 4 TX RF path to do 1SS 2TX
1506 */
1507 hal_spec->max_tx_cnt = rtw_min(hal_spec->max_tx_cnt, tx_path_num);
1508 hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, hal_spec->max_tx_cnt);
1509 hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ss_num);
1510
1511 hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, rx_path_num);
1512 hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ss_num);
1513
1514 ret = _SUCCESS;
1515
1516 exit:
1517 return ret;
1518 }
1519
c2h_mac_hidden_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1520 int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1521 {
1522 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1523 int ret = _FAIL;
1524
1525 int i;
1526
1527 if (len < MAC_HIDDEN_RPT_2_LEN) {
1528 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
1529 goto exit;
1530 }
1531
1532 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1533 for (i = 0; i < len; i++)
1534 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1535 }
1536
1537 #if defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV)
1538 if (IS_8188F(hal_data->version_id) || IS_8188GTV(hal_data->version_id)) {
1539 #define GET_C2H_MAC_HIDDEN_RPT_IRV(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 4)
1540 u8 irv = GET_C2H_MAC_HIDDEN_RPT_IRV(data);
1541
1542 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE)
1543 RTW_PRINT("irv:0x%x\n", irv);
1544
1545 if(irv != 0xf)
1546 hal_data->version_id.CUTVersion = irv;
1547 }
1548 #endif
1549
1550 #if defined(CONFIG_8723F)
1551 if (IS_8723F_SERIES(hal_data->version_id)) {
1552 #define GET_C2H_MAC_HIDDEN_RPT_BT_SUPPORT(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 1)
1553 #define GET_C2H_MAC_HIDDEN_RPT_5G_SUPPORT(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 1, 1)
1554
1555 struct hal_spec_t *hal_spec;
1556 u8 bt_support = GET_C2H_MAC_HIDDEN_RPT_BT_SUPPORT(data);
1557 u8 band_5g_support = GET_C2H_MAC_HIDDEN_RPT_5G_SUPPORT(data);
1558
1559 hal_spec = GET_HAL_SPEC(adapter);
1560
1561 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1562 RTW_PRINT("bt support:%u\n", bt_support);
1563 RTW_PRINT("band 5g support:%u\n", band_5g_support);
1564 }
1565
1566 hal_spec->rfpath_num_5g = (band_5g_support ? hal_spec->rfpath_num_5g : 0);
1567 if(!band_5g_support)
1568 hal_spec->band_cap &= ~BAND_CAP_5G;
1569
1570 hal_data->EEPROMBluetoothCoexist = bt_support;
1571 /* 0 : solo module, 1 : combo module */
1572 hal_data->InterfaceSel = bt_support;
1573 }
1574 #endif
1575
1576 ret = _SUCCESS;
1577
1578 exit:
1579 return ret;
1580 }
1581
hal_read_mac_hidden_rpt(_adapter * adapter)1582 int hal_read_mac_hidden_rpt(_adapter *adapter)
1583 {
1584 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
1585 int ret = _FAIL;
1586 int ret_fwdl;
1587 u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
1588 systime start = rtw_get_current_time();
1589 u32 cnt = 0;
1590 u32 timeout_ms = 800;
1591 u32 min_cnt = 10;
1592 u8 id = C2H_DEFEATURE_RSVD;
1593 int i;
1594
1595 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1596 u8 hci_type = rtw_get_intf_type(adapter);
1597
1598 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1599 && !rtw_is_hw_init_completed(adapter))
1600 rtw_hal_power_on(adapter);
1601 #endif
1602
1603 /* inform FW mac hidden rpt from reg is needed */
1604 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
1605
1606 /* download FW */
1607 pHalData->not_xmitframe_fw_dl = 1;
1608 ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1609 pHalData->not_xmitframe_fw_dl = 0;
1610 if (ret_fwdl != _SUCCESS)
1611 goto mac_hidden_rpt_hdl;
1612
1613 /* polling for data ready */
1614 start = rtw_get_current_time();
1615 do {
1616 cnt++;
1617 id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1618 if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1619 break;
1620 rtw_msleep_os(10);
1621 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1622
1623 if (id == C2H_MAC_HIDDEN_RPT) {
1624 /* read data */
1625 for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
1626 mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1627 }
1628
1629 /* inform FW mac hidden rpt has read */
1630 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
1631
1632 mac_hidden_rpt_hdl:
1633 c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1634 c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
1635
1636 if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1637 ret = _SUCCESS;
1638
1639 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1640 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1641 && !rtw_is_hw_init_completed(adapter))
1642 rtw_hal_power_off(adapter);
1643 #endif
1644
1645 RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1646 , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1647
1648 return ret;
1649 }
1650 #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
1651
c2h_defeature_dbg_hdl(_adapter * adapter,u8 * data,u8 len)1652 int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
1653 {
1654 int ret = _FAIL;
1655
1656 int i;
1657
1658 if (len < DEFEATURE_DBG_LEN) {
1659 RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
1660 goto exit;
1661 }
1662
1663 for (i = 0; i < len; i++)
1664 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1665
1666 ret = _SUCCESS;
1667
1668 exit:
1669 return ret;
1670 }
1671
1672 #ifndef DBG_CUSTOMER_STR_RPT_HANDLE
1673 #define DBG_CUSTOMER_STR_RPT_HANDLE 0
1674 #endif
1675
1676 #ifdef CONFIG_RTW_CUSTOMER_STR
rtw_hal_h2c_customer_str_req(_adapter * adapter)1677 s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
1678 {
1679 u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
1680
1681 SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
1682 return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
1683 }
1684
1685 #define C2H_CUSTOMER_STR_RPT_BYTE0(_data) ((u8 *)(_data))
1686 #define C2H_CUSTOMER_STR_RPT_2_BYTE8(_data) ((u8 *)(_data))
1687
c2h_customer_str_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1688 int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1689 {
1690 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1691 int ret = _FAIL;
1692 int i;
1693
1694 if (len < CUSTOMER_STR_RPT_LEN) {
1695 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
1696 goto exit;
1697 }
1698
1699 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1700 RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
1701
1702 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1703
1704 if (dvobj->customer_str_sctx != NULL) {
1705 if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
1706 RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
1707 _rtw_memcpy(dvobj->customer_str, C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
1708 dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
1709 } else
1710 RTW_WARN("%s sctx not set\n", __func__);
1711
1712 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1713
1714 ret = _SUCCESS;
1715
1716 exit:
1717 return ret;
1718 }
1719
c2h_customer_str_rpt_2_hdl(_adapter * adapter,u8 * data,u8 len)1720 int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1721 {
1722 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1723 int ret = _FAIL;
1724 int i;
1725
1726 if (len < CUSTOMER_STR_RPT_2_LEN) {
1727 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
1728 goto exit;
1729 }
1730
1731 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1732 RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
1733
1734 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1735
1736 if (dvobj->customer_str_sctx != NULL) {
1737 if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
1738 RTW_WARN("%s rpt not ready\n", __func__);
1739 _rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN, C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
1740 rtw_sctx_done(&dvobj->customer_str_sctx);
1741 } else
1742 RTW_WARN("%s sctx not set\n", __func__);
1743
1744 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1745
1746 ret = _SUCCESS;
1747
1748 exit:
1749 return ret;
1750 }
1751
1752 /* read customer str */
rtw_hal_customer_str_read(_adapter * adapter,u8 * cs)1753 s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
1754 {
1755 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1756 struct submit_ctx sctx;
1757 s32 ret = _SUCCESS;
1758
1759 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1760 if (dvobj->customer_str_sctx != NULL)
1761 ret = _FAIL;
1762 else {
1763 rtw_sctx_init(&sctx, 2 * 1000);
1764 dvobj->customer_str_sctx = &sctx;
1765 }
1766 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1767
1768 if (ret == _FAIL) {
1769 RTW_WARN("%s another handle ongoing\n", __func__);
1770 goto exit;
1771 }
1772
1773 ret = rtw_customer_str_req_cmd(adapter);
1774 if (ret != _SUCCESS) {
1775 RTW_WARN("%s read cmd fail\n", __func__);
1776 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1777 dvobj->customer_str_sctx = NULL;
1778 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1779 goto exit;
1780 }
1781
1782 /* wait till rpt done or timeout */
1783 rtw_sctx_wait(&sctx, __func__);
1784
1785 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1786 dvobj->customer_str_sctx = NULL;
1787 if (sctx.status == RTW_SCTX_DONE_SUCCESS)
1788 _rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1789 else
1790 ret = _FAIL;
1791 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1792
1793 exit:
1794 return ret;
1795 }
1796
rtw_hal_h2c_customer_str_write(_adapter * adapter,const u8 * cs)1797 s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
1798 {
1799 u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
1800 u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
1801 u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
1802 s32 ret;
1803
1804 SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
1805 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
1806
1807 SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
1808 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
1809
1810 SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
1811 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
1812
1813 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
1814 if (ret != _SUCCESS) {
1815 RTW_WARN("%s w1 fail\n", __func__);
1816 goto exit;
1817 }
1818
1819 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
1820 if (ret != _SUCCESS) {
1821 RTW_WARN("%s w2 fail\n", __func__);
1822 goto exit;
1823 }
1824
1825 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
1826 if (ret != _SUCCESS) {
1827 RTW_WARN("%s w3 fail\n", __func__);
1828 goto exit;
1829 }
1830
1831 exit:
1832 return ret;
1833 }
1834
1835 /* write customer str and check if value reported is the same as requested */
rtw_hal_customer_str_write(_adapter * adapter,const u8 * cs)1836 s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
1837 {
1838 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1839 struct submit_ctx sctx;
1840 s32 ret = _SUCCESS;
1841
1842 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1843 if (dvobj->customer_str_sctx != NULL)
1844 ret = _FAIL;
1845 else {
1846 rtw_sctx_init(&sctx, 2 * 1000);
1847 dvobj->customer_str_sctx = &sctx;
1848 }
1849 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1850
1851 if (ret == _FAIL) {
1852 RTW_WARN("%s another handle ongoing\n", __func__);
1853 goto exit;
1854 }
1855
1856 ret = rtw_customer_str_write_cmd(adapter, cs);
1857 if (ret != _SUCCESS) {
1858 RTW_WARN("%s write cmd fail\n", __func__);
1859 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1860 dvobj->customer_str_sctx = NULL;
1861 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1862 goto exit;
1863 }
1864
1865 ret = rtw_customer_str_req_cmd(adapter);
1866 if (ret != _SUCCESS) {
1867 RTW_WARN("%s read cmd fail\n", __func__);
1868 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1869 dvobj->customer_str_sctx = NULL;
1870 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1871 goto exit;
1872 }
1873
1874 /* wait till rpt done or timeout */
1875 rtw_sctx_wait(&sctx, __func__);
1876
1877 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1878 dvobj->customer_str_sctx = NULL;
1879 if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
1880 if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
1881 RTW_WARN("%s read back check fail\n", __func__);
1882 RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
1883 RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1884 ret = _FAIL;
1885 }
1886 } else
1887 ret = _FAIL;
1888 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1889
1890 exit:
1891 return ret;
1892 }
1893 #endif /* CONFIG_RTW_CUSTOMER_STR */
1894
1895 #ifdef RTW_PER_CMD_SUPPORT_FW
1896 #define H2C_REQ_PER_RPT_LEN 5
1897 #define SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value)
1898 #define SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value)
1899 #define SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(__pH2CCmd, __Value) SET_BITS_TO_LE_4BYTE(__pH2CCmd + 1, 0, 32, __Value)
1900
rtw_hal_set_req_per_rpt_cmd(_adapter * adapter,u8 group_macid,u8 rpt_type,u32 macid_bitmap)1901 u8 rtw_hal_set_req_per_rpt_cmd(_adapter *adapter, u8 group_macid,
1902 u8 rpt_type, u32 macid_bitmap)
1903 {
1904 u8 ret = _FAIL;
1905 u8 cmd_buf[H2C_REQ_PER_RPT_LEN] = {0};
1906
1907 SET_H2CCMD_REQ_PER_RPT_GROUP_MACID(cmd_buf, group_macid);
1908 SET_H2CCMD_REQ_PER_RPT_RPT_TYPE(cmd_buf, rpt_type);
1909 SET_H2CCMD_REQ_PER_RPT_MACID_BMAP(cmd_buf, macid_bitmap);
1910
1911 ret = rtw_hal_fill_h2c_cmd(adapter,
1912 H2C_REQ_PER_RPT,
1913 H2C_REQ_PER_RPT_LEN,
1914 cmd_buf);
1915 return ret;
1916 }
1917
1918 #define GET_C2H_PER_RATE_RPT_TYPE0_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
1919 #define GET_C2H_PER_RATE_RPT_TYPE0_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1920 #define GET_C2H_PER_RATE_RPT_TYPE0_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
1921 #define GET_C2H_PER_RATE_RPT_TYPE0_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
1922 #define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 4, 0, 16)
1923 #define GET_C2H_PER_RATE_RPT_TYPE0_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
1924 #define GET_C2H_PER_RATE_RPT_TYPE0_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 8)
1925 #define GET_C2H_PER_RATE_RPT_TYPE0_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
1926 #define GET_C2H_PER_RATE_RPT_TYPE0_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 2)
1927 #define GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 10, 0, 16)
1928
1929 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
1930 #define GET_C2H_PER_RATE_RPT_TYPE1_PER0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1931 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 8)
1932 #define GET_C2H_PER_RATE_RPT_TYPE1_BW0(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 3, 0, 2)
1933 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 8)
1934 #define GET_C2H_PER_RATE_RPT_TYPE1_PER1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 8)
1935 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 8)
1936 #define GET_C2H_PER_RATE_RPT_TYPE1_BW1(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 0, 2)
1937 #define GET_C2H_PER_RATE_RPT_TYPE1_MACID2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 8, 0, 8)
1938 #define GET_C2H_PER_RATE_RPT_TYPE1_PER2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 9, 0, 8)
1939 #define GET_C2H_PER_RATE_RPT_TYPE1_RATE2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 10, 0, 8)
1940 #define GET_C2H_PER_RATE_RPT_TYPE1_BW2(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 11, 0, 2)
1941
per_rate_rpt_update(_adapter * adapter,u8 mac_id,u8 per,u8 rate,u8 bw,u8 total_pkt)1942 static void per_rate_rpt_update(_adapter *adapter, u8 mac_id,
1943 u8 per, u8 rate,
1944 u8 bw, u8 total_pkt)
1945 {
1946 #ifdef CONFIG_RTW_MESH
1947 rtw_ieee80211s_update_metric(adapter, mac_id,
1948 per, rate,
1949 bw, total_pkt);
1950 #endif
1951 }
1952
c2h_per_rate_rpt_hdl(_adapter * adapter,u8 * data,u8 len)1953 int c2h_per_rate_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1954 {
1955 /* Now only consider type0, since it covers all params in type1
1956 * type0: mac_id, per, rate, bw, total_pkt
1957 * type1: mac_id, per, rate, bw
1958 */
1959 u8 mac_id[2] = {0}, per[2] = {0}, rate[2] = {0}, bw[2] = {0};
1960 u16 total_pkt[2] = {0};
1961 int ret = _FAIL, i, macid_cnt = 0;
1962
1963 /* type0:
1964 * 1 macid includes 6 bytes info + 1 byte 0xff
1965 * 2 macid includes 2*6 bytes info
1966 */
1967 if (!(len == 7 || len == 12)) {
1968 RTW_WARN("%s len(%u) != 7 or 12\n", __FUNCTION__, len);
1969 goto exit;
1970 }
1971
1972 macid_cnt++;
1973 mac_id[0] = GET_C2H_PER_RATE_RPT_TYPE0_MACID0(data);
1974 per[0] = GET_C2H_PER_RATE_RPT_TYPE0_PER0(data);
1975 rate[0] = GET_C2H_PER_RATE_RPT_TYPE0_RATE0(data);
1976 bw[0] = GET_C2H_PER_RATE_RPT_TYPE0_BW0(data);
1977 total_pkt[0] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT0(data);
1978
1979 mac_id[1] = GET_C2H_PER_RATE_RPT_TYPE0_MACID1(data);
1980 /* 0xff means no report anymore */
1981 if (mac_id[1] == 0xff)
1982 goto update_per;
1983 if (len != 12) {
1984 RTW_WARN("%s incorrect format\n", __FUNCTION__);
1985 goto exit;
1986 }
1987 macid_cnt++;
1988 per[1] = GET_C2H_PER_RATE_RPT_TYPE0_PER1(data);
1989 rate[1] = GET_C2H_PER_RATE_RPT_TYPE0_RATE1(data);
1990 bw[1] = GET_C2H_PER_RATE_RPT_TYPE0_BW1(data);
1991 total_pkt[1] = GET_C2H_PER_RATE_RPT_TYPE0_TOTAL_PKT1(data);
1992
1993 update_per:
1994 for (i = 0; i < macid_cnt; i++) {
1995 RTW_DBG("[%s] type0 rpt[%d]: macid = %u, per = %u, "
1996 "rate = %u, bw = %u, total_pkt = %u\n",
1997 __FUNCTION__, i, mac_id[i], per[i],
1998 rate[i], bw[i], total_pkt[i]);
1999 per_rate_rpt_update(adapter, mac_id[i],
2000 per[i], rate[i],
2001 bw[i], total_pkt[i]);
2002 }
2003 ret = _SUCCESS;
2004 exit:
2005 return ret;
2006 }
2007 #endif /* RTW_PER_CMD_SUPPORT_FW */
2008
2009 #ifdef CONFIG_LPS_ACK
2010 #define GET_C2H_LPS_STATUS_RPT_GET_ACTION(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)), 0, 8)
2011 #define GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
2012 #define DBG_LPS_STATUS_RPT 0
2013
c2h_lps_status_rpt(PADAPTER adapter,u8 * data,u8 len)2014 int c2h_lps_status_rpt(PADAPTER adapter, u8 *data, u8 len)
2015 {
2016 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
2017 struct submit_ctx *lps_sctx = &pwrpriv->lps_ack_sctx;
2018 u8 action = 0;
2019 s8 status_code = 0;
2020 int ret = _FAIL;
2021
2022 if (len < LPS_STATUS_RPT_LEN) {
2023 RTW_WARN("%s len(%u) < %d\n", __func__, len, LPS_STATUS_RPT_LEN);
2024 goto exit;
2025 }
2026
2027 action = GET_C2H_LPS_STATUS_RPT_GET_ACTION(data);
2028 status_code = GET_C2H_LPS_STATUS_RPT_GET_STATUS_CODE(data);
2029
2030 /* action=0: report force leave null data status */
2031 /* action=1: report Rf on status when receiving a SetPwrMode H2C with PwrState = RFON */
2032 switch (action) {
2033 case 0:
2034 /* status code 0: success, 1: no ack, 2: timeout, 3: cancel */
2035 case 1:
2036 /* status code 0: FW has already turn to RFON */
2037 pwrpriv->lps_ack_status = status_code;
2038
2039 if (DBG_LPS_STATUS_RPT)
2040 RTW_INFO("=== [C2H LPS Action(%d)] LPS Status Code:%d ===\n", action, status_code);
2041
2042 break;
2043 default:
2044 RTW_INFO("UnKnown Action(%d) for C2H LPS RPT\n", action);
2045 break;
2046 }
2047
2048 rtw_sctx_done(&lps_sctx);
2049 ret = _SUCCESS;
2050
2051 exit:
2052 return ret;
2053 }
2054 #endif /* CONFIG_LPS_ACK */
2055
rtw_hal_update_sta_wset(_adapter * adapter,struct sta_info * psta)2056 void rtw_hal_update_sta_wset(_adapter *adapter, struct sta_info *psta)
2057 {
2058 u8 w_set = 0;
2059
2060 if (psta->wireless_mode & WIRELESS_11B)
2061 w_set |= WIRELESS_CCK;
2062
2063 if ((psta->wireless_mode & WIRELESS_11G) || (psta->wireless_mode & WIRELESS_11A))
2064 w_set |= WIRELESS_OFDM;
2065
2066 if ((psta->wireless_mode & WIRELESS_11_24N) || (psta->wireless_mode & WIRELESS_11_5N))
2067 w_set |= WIRELESS_HT;
2068
2069 if (psta->wireless_mode & WIRELESS_11AC)
2070 w_set |= WIRELESS_VHT;
2071
2072 psta->cmn.support_wireless_set = w_set;
2073 }
2074
rtw_hal_update_sta_mimo_type(_adapter * adapter,struct sta_info * psta)2075 void rtw_hal_update_sta_mimo_type(_adapter *adapter, struct sta_info *psta)
2076 {
2077 s8 tx_nss, rx_nss;
2078
2079 tx_nss = rtw_get_sta_tx_nss(adapter, psta);
2080 rx_nss = rtw_get_sta_rx_nss(adapter, psta);
2081 if ((tx_nss == 1) && (rx_nss == 1))
2082 psta->cmn.mimo_type = RF_1T1R;
2083 else if ((tx_nss == 1) && (rx_nss == 2))
2084 psta->cmn.mimo_type = RF_1T2R;
2085 else if ((tx_nss == 2) && (rx_nss == 2))
2086 psta->cmn.mimo_type = RF_2T2R;
2087 else if ((tx_nss == 2) && (rx_nss == 3))
2088 psta->cmn.mimo_type = RF_2T3R;
2089 else if ((tx_nss == 2) && (rx_nss == 4))
2090 psta->cmn.mimo_type = RF_2T4R;
2091 else if ((tx_nss == 3) && (rx_nss == 3))
2092 psta->cmn.mimo_type = RF_3T3R;
2093 else if ((tx_nss == 3) && (rx_nss == 4))
2094 psta->cmn.mimo_type = RF_3T4R;
2095 else if ((tx_nss == 4) && (rx_nss == 4))
2096 psta->cmn.mimo_type = RF_4T4R;
2097 else
2098 rtw_warn_on(1);
2099
2100 #ifdef CONFIG_CTRL_TXSS_BY_TP
2101 rtw_ctrl_txss_update_mimo_type(adapter, psta);
2102 #endif
2103
2104 RTW_INFO("STA - MAC_ID:%d, Tx - %d SS, Rx - %d SS\n",
2105 psta->cmn.mac_id, tx_nss, rx_nss);
2106 }
2107
rtw_hal_update_sta_smps_cap(_adapter * adapter,struct sta_info * psta)2108 void rtw_hal_update_sta_smps_cap(_adapter *adapter, struct sta_info *psta)
2109 {
2110 /*Spatial Multiplexing Power Save*/
2111 #if 0
2112 if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2113 #ifdef CONFIG_80211N_HT
2114 if (psta->htpriv.ht_option) {
2115 if (psta->htpriv.smps_cap == 0)
2116 psta->cmn.sm_ps = SM_PS_STATIC;
2117 else if (psta->htpriv.smps_cap == 1)
2118 psta->cmn.sm_ps = SM_PS_DYNAMIC;
2119 else
2120 psta->cmn.sm_ps = SM_PS_DISABLE;
2121 }
2122 #endif /* CONFIG_80211N_HT */
2123 } else
2124 #endif
2125 psta->cmn.sm_ps = SM_PS_DISABLE;
2126
2127 RTW_INFO("STA - MAC_ID:%d, SM_PS %d\n",
2128 psta->cmn.mac_id, psta->cmn.sm_ps);
2129 }
2130
rtw_get_mgntframe_raid(_adapter * adapter,unsigned char network_type)2131 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
2132 {
2133
2134 u8 raid;
2135 if (IS_NEW_GENERATION_IC(adapter)) {
2136
2137 raid = (network_type & WIRELESS_11B) ? RATEID_IDX_B
2138 : RATEID_IDX_G;
2139 } else {
2140 raid = (network_type & WIRELESS_11B) ? RATR_INX_WIRELESS_B
2141 : RATR_INX_WIRELESS_G;
2142 }
2143 return raid;
2144 }
2145
rtw_hal_update_sta_rate_mask(PADAPTER padapter,struct sta_info * psta)2146 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
2147 {
2148 u8 i, tx_nss;
2149 u64 tx_ra_bitmap = 0, tmp64=0;
2150
2151 if (psta == NULL)
2152 return;
2153
2154 /* b/g mode ra_bitmap */
2155 for (i = 0; i < sizeof(psta->bssrateset); i++) {
2156 if (psta->bssrateset[i])
2157 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
2158 }
2159
2160 #ifdef CONFIG_80211N_HT
2161 if (padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
2162 tx_nss = GET_HAL_TX_NSS(padapter);
2163 #ifdef CONFIG_80211AC_VHT
2164 if (psta->vhtpriv.vht_option) {
2165 /* AC mode ra_bitmap */
2166 tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
2167 } else
2168 #endif /* CONFIG_80211AC_VHT */
2169 if (psta->htpriv.ht_option) {
2170 /* n mode ra_bitmap */
2171
2172 /* Handling SMPS mode for AP MODE only*/
2173 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
2174 /*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
2175 if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
2176 /*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
2177 tx_nss = rtw_min(tx_nss, 1);
2178 }
2179 }
2180
2181 tmp64 = rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss);
2182 tx_ra_bitmap |= (tmp64 << 12);
2183 }
2184 }
2185 #endif /* CONFIG_80211N_HT */
2186 psta->cmn.ra_info.ramask = tx_ra_bitmap;
2187 psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
2188 }
2189
rtw_hal_update_sta_ra_info(PADAPTER padapter,struct sta_info * psta)2190 void rtw_hal_update_sta_ra_info(PADAPTER padapter, struct sta_info *psta)
2191 {
2192 rtw_hal_update_sta_mimo_type(padapter, psta);
2193 rtw_hal_update_sta_smps_cap(padapter, psta);
2194 rtw_hal_update_sta_rate_mask(padapter, psta);
2195 }
2196
2197 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
hw_bcn_ctrl_addr(_adapter * adapter,u8 hw_port)2198 static u32 hw_bcn_ctrl_addr(_adapter *adapter, u8 hw_port)
2199 {
2200 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
2201
2202 if (hw_port >= hal_spec->port_num) {
2203 RTW_ERR(FUNC_ADPT_FMT" HW Port(%d) invalid\n", FUNC_ADPT_ARG(adapter), hw_port);
2204 rtw_warn_on(1);
2205 return 0;
2206 }
2207
2208 switch (hw_port) {
2209 case HW_PORT0:
2210 return REG_BCN_CTRL;
2211 case HW_PORT1:
2212 return REG_BCN_CTRL_1;
2213 }
2214
2215 return 0;
2216 }
2217 #endif
2218
rtw_hal_get_msr(_adapter * adapter,u8 * net_type)2219 static void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2220 {
2221 #ifdef RTW_HALMAC
2222 rtw_halmac_get_network_type(adapter_to_dvobj(adapter),
2223 adapter->hw_port, net_type);
2224 #else /* !RTW_HALMAC */
2225 switch (adapter->hw_port) {
2226 case HW_PORT0:
2227 /*REG_CR - BIT[17:16]-Network Type for port 1*/
2228 *net_type = rtw_read8(adapter, MSR) & 0x03;
2229 break;
2230 case HW_PORT1:
2231 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2232 *net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2233 break;
2234 #if defined(CONFIG_RTL8814A)
2235 case HW_PORT2:
2236 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2237 *net_type = rtw_read8(adapter, MSR1) & 0x03;
2238 break;
2239 case HW_PORT3:
2240 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2241 *net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2242 break;
2243 case HW_PORT4:
2244 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2245 *net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2246 break;
2247 #endif /*#if defined(CONFIG_RTL8814A)*/
2248 default:
2249 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2250 ADPT_ARG(adapter), adapter->hw_port);
2251 rtw_warn_on(1);
2252 break;
2253 }
2254 #endif /* !RTW_HALMAC */
2255 }
2256
2257 #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)2258 static u8 rtw_hal_net_type_decision(_adapter *adapter, u8 net_type)
2259 {
2260 if ((adapter->hw_port == HW_PORT0) && (rtw_get_mbid_cam_entry_num(adapter))) {
2261 if (net_type != _HW_STATE_NOLINK_)
2262 return _HW_STATE_AP_;
2263 }
2264 return net_type;
2265 }
2266 #endif
rtw_hal_set_msr(_adapter * adapter,u8 net_type)2267 static void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2268 {
2269 #ifdef RTW_HALMAC
2270 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2271 net_type = rtw_hal_net_type_decision(adapter, net_type);
2272 #endif
2273 rtw_halmac_set_network_type(adapter_to_dvobj(adapter),
2274 adapter->hw_port, net_type);
2275 #else /* !RTW_HALMAC */
2276 u8 val8 = 0;
2277
2278 switch (adapter->hw_port) {
2279 case HW_PORT0:
2280 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM)
2281 net_type = rtw_hal_net_type_decision(adapter, net_type);
2282 #endif
2283 /*REG_CR - BIT[17:16]-Network Type for port 0*/
2284 val8 = rtw_read8(adapter, MSR) & 0x0C;
2285 val8 |= net_type;
2286 rtw_write8(adapter, MSR, val8);
2287 break;
2288 case HW_PORT1:
2289 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2290 val8 = rtw_read8(adapter, MSR) & 0x03;
2291 val8 |= net_type << 2;
2292 rtw_write8(adapter, MSR, val8);
2293 break;
2294 #if defined(CONFIG_RTL8814A)
2295 case HW_PORT2:
2296 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2297 val8 = rtw_read8(adapter, MSR1) & 0xFC;
2298 val8 |= net_type;
2299 rtw_write8(adapter, MSR1, val8);
2300 break;
2301 case HW_PORT3:
2302 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2303 val8 = rtw_read8(adapter, MSR1) & 0xF3;
2304 val8 |= net_type << 2;
2305 rtw_write8(adapter, MSR1, val8);
2306 break;
2307 case HW_PORT4:
2308 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2309 val8 = rtw_read8(adapter, MSR1) & 0xCF;
2310 val8 |= net_type << 4;
2311 rtw_write8(adapter, MSR1, val8);
2312 break;
2313 #endif /* CONFIG_RTL8814A */
2314 default:
2315 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2316 ADPT_ARG(adapter), adapter->hw_port);
2317 rtw_warn_on(1);
2318 break;
2319 }
2320 #endif /* !RTW_HALMAC */
2321 }
2322
2323 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
2324 #define SEC_CAM_ACCESS_TIMEOUT_MS 200
2325 #endif
2326
2327 #ifndef DBG_SEC_CAM_ACCESS
2328 #define DBG_SEC_CAM_ACCESS 0
2329 #endif
2330
rtw_sec_read_cam(_adapter * adapter,u8 addr)2331 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
2332 {
2333 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2334 u32 rdata;
2335 u32 cnt = 0;
2336 systime start = 0, end = 0;
2337 u8 timeout = 0;
2338 u8 sr = 0;
2339
2340 _enter_critical_mutex(mutex, NULL);
2341
2342 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
2343
2344 start = rtw_get_current_time();
2345 while (1) {
2346 if (rtw_is_surprise_removed(adapter)) {
2347 sr = 1;
2348 break;
2349 }
2350
2351 cnt++;
2352 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2353 break;
2354
2355 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2356 timeout = 1;
2357 break;
2358 }
2359 }
2360 end = rtw_get_current_time();
2361
2362 rdata = rtw_read32(adapter, REG_CAMREAD);
2363
2364 _exit_critical_mutex(mutex, NULL);
2365
2366 if (DBG_SEC_CAM_ACCESS || timeout) {
2367 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
2368 , FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2369 }
2370
2371 return rdata;
2372 }
2373
rtw_sec_write_cam(_adapter * adapter,u8 addr,u32 wdata)2374 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
2375 {
2376 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
2377 u32 cnt = 0;
2378 systime start = 0, end = 0;
2379 u8 timeout = 0;
2380 u8 sr = 0;
2381
2382 _enter_critical_mutex(mutex, NULL);
2383
2384 rtw_write32(adapter, REG_CAMWRITE, wdata);
2385 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
2386
2387 start = rtw_get_current_time();
2388 while (1) {
2389 if (rtw_is_surprise_removed(adapter)) {
2390 sr = 1;
2391 break;
2392 }
2393
2394 cnt++;
2395 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
2396 break;
2397
2398 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
2399 timeout = 1;
2400 break;
2401 }
2402 }
2403 end = rtw_get_current_time();
2404
2405 _exit_critical_mutex(mutex, NULL);
2406
2407 if (DBG_SEC_CAM_ACCESS || timeout) {
2408 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
2409 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
2410 }
2411 }
2412
rtw_sec_read_cam_ent(_adapter * adapter,u8 id,u8 * ctrl,u8 * mac,u8 * key)2413 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
2414 {
2415 u8 i;
2416 u32 rdata;
2417 u8 begin = 0;
2418 u8 end = 5; /* TODO: consider other key length accordingly */
2419
2420 if (!ctrl && !mac && !key) {
2421 rtw_warn_on(1);
2422 goto exit;
2423 }
2424
2425 /* TODO: check id range */
2426
2427 if (!ctrl && !mac)
2428 begin = 2; /* read from key */
2429
2430 if (!key && !mac)
2431 end = 0; /* read to ctrl */
2432 else if (!key)
2433 end = 2; /* read to mac */
2434
2435 for (i = begin; i <= end; i++) {
2436 rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
2437
2438 switch (i) {
2439 case 0:
2440 if (ctrl)
2441 _rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
2442 if (mac)
2443 _rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
2444 break;
2445 case 1:
2446 if (mac)
2447 _rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
2448 break;
2449 default:
2450 if (key)
2451 _rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
2452 break;
2453 }
2454 }
2455
2456 exit:
2457 return;
2458 }
2459
2460
rtw_sec_write_cam_ent(_adapter * adapter,u8 id,u16 ctrl,u8 * mac,u8 * key)2461 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
2462 {
2463 unsigned int i;
2464 int j;
2465 u8 addr, addr1 = 0;
2466 u32 wdata, wdata1 = 0;
2467
2468 /* TODO: consider other key length accordingly */
2469 #if 0
2470 switch ((ctrl & 0x1c) >> 2) {
2471 case _WEP40_:
2472 case _TKIP_:
2473 case _AES_:
2474 case _WEP104_:
2475
2476 }
2477 #else
2478 j = 7;
2479 #endif
2480
2481 for (; j >= 0; j--) {
2482 switch (j) {
2483 case 0:
2484 wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
2485 break;
2486 case 1:
2487 wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
2488 break;
2489 case 6:
2490 case 7:
2491 wdata = 0;
2492 break;
2493 default:
2494 i = (j - 2) << 2;
2495 wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
2496 break;
2497 }
2498
2499 addr = (id << 3) + j;
2500
2501 #if defined(CONFIG_RTL8192F)
2502 if(j == 1) {
2503 wdata1 = wdata;
2504 addr1 = addr;
2505 continue;
2506 }
2507 #endif
2508
2509 rtw_sec_write_cam(adapter, addr, wdata);
2510 }
2511
2512 #if defined(CONFIG_RTL8192F)
2513 rtw_sec_write_cam(adapter, addr1, wdata1);
2514 #endif
2515 }
2516
rtw_sec_clr_cam_ent(_adapter * adapter,u8 id)2517 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
2518 {
2519 u8 addr;
2520
2521 addr = (id << 3);
2522 rtw_sec_write_cam(adapter, addr, 0);
2523 }
2524
rtw_sec_read_cam_is_gk(_adapter * adapter,u8 id)2525 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
2526 {
2527 bool res;
2528 u16 ctrl;
2529
2530 rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
2531
2532 res = (ctrl & BIT6) ? _TRUE : _FALSE;
2533 return res;
2534 }
2535 #ifdef CONFIG_MBSSID_CAM
rtw_mbid_cam_init(struct dvobj_priv * dvobj)2536 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
2537 {
2538 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2539
2540 _rtw_spinlock_init(&mbid_cam_ctl->lock);
2541 mbid_cam_ctl->bitmap = 0;
2542 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2543 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2544 }
2545
rtw_mbid_cam_deinit(struct dvobj_priv * dvobj)2546 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
2547 {
2548 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2549
2550 _rtw_spinlock_free(&mbid_cam_ctl->lock);
2551 }
2552
rtw_mbid_cam_reset(_adapter * adapter)2553 void rtw_mbid_cam_reset(_adapter *adapter)
2554 {
2555 _irqL irqL;
2556 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2557 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2558
2559 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2560 mbid_cam_ctl->bitmap = 0;
2561 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2562 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2563
2564 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2565 }
_rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2566 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2567 {
2568 u8 i;
2569 u8 cam_id = INVALID_CAM_ID;
2570 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2571
2572 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2573 if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
2574 cam_id = i;
2575 break;
2576 }
2577 }
2578
2579 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2580 return cam_id;
2581 }
2582
rtw_mbid_cam_search_by_macaddr(_adapter * adapter,u8 * mac_addr)2583 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2584 {
2585 _irqL irqL;
2586
2587 u8 cam_id = INVALID_CAM_ID;
2588 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2589 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2590
2591 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2592 cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
2593 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2594
2595 return cam_id;
2596 }
_rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2597 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2598 {
2599 u8 i;
2600 u8 cam_id = INVALID_CAM_ID;
2601 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2602
2603 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2604 if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
2605 cam_id = i;
2606 break;
2607 }
2608 }
2609 if (cam_id != INVALID_CAM_ID)
2610 RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
2611 __func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
2612
2613 return cam_id;
2614 }
2615
rtw_mbid_cam_search_by_ifaceid(_adapter * adapter,u8 iface_id)2616 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2617 {
2618 _irqL irqL;
2619 u8 cam_id = INVALID_CAM_ID;
2620 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2621 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2622
2623 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2624 cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
2625 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2626
2627 return cam_id;
2628 }
rtw_get_max_mbid_cam_id(_adapter * adapter)2629 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
2630 {
2631 _irqL irqL;
2632 s8 i;
2633 u8 cam_id = INVALID_CAM_ID;
2634 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2635 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2636
2637 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2638 for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
2639 if (mbid_cam_ctl->bitmap & BIT(i)) {
2640 cam_id = i;
2641 break;
2642 }
2643 }
2644 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2645 /*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
2646 return cam_id;
2647 }
2648
rtw_get_mbid_cam_entry_num(_adapter * adapter)2649 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
2650 {
2651 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2652 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2653
2654 return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2655 }
2656
mbid_cam_cache_init(_adapter * adapter,struct mbid_cam_cache * pmbid_cam,u8 * mac_addr)2657 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
2658 {
2659 if (adapter && pmbid_cam && mac_addr) {
2660 _rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
2661 pmbid_cam->iface_id = adapter->iface_id;
2662 }
2663 }
mbid_cam_cache_clr(struct mbid_cam_cache * pmbid_cam)2664 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
2665 {
2666 if (pmbid_cam) {
2667 _rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
2668 pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
2669 }
2670 }
2671
rtw_mbid_camid_alloc(_adapter * adapter,u8 * mac_addr)2672 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
2673 {
2674 _irqL irqL;
2675 u8 cam_id = INVALID_CAM_ID, i;
2676 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2677 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2678 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2679
2680 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2681 goto exit;
2682
2683 if (entry_num >= TOTAL_MBID_CAM_NUM) {
2684 RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
2685 rtw_warn_on(1);
2686 }
2687
2688 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2689 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2690 if (!(mbid_cam_ctl->bitmap & BIT(i))) {
2691 mbid_cam_ctl->bitmap |= BIT(i);
2692 cam_id = i;
2693 break;
2694 }
2695 }
2696 if ((cam_id != INVALID_CAM_ID) && (mac_addr))
2697 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
2698 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2699
2700 if (cam_id != INVALID_CAM_ID) {
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), cam_id);
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_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2708 exit:
2709 return cam_id;
2710 }
2711
rtw_mbid_cam_info_change(_adapter * adapter,u8 * mac_addr)2712 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
2713 {
2714 _irqL irqL;
2715 u8 entry_id = INVALID_CAM_ID;
2716 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2717 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2718
2719 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2720 entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
2721 if (entry_id != INVALID_CAM_ID)
2722 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
2723
2724 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2725
2726 return entry_id;
2727 }
2728
rtw_mbid_cam_assign(_adapter * adapter,u8 * mac_addr,u8 camid)2729 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
2730 {
2731 _irqL irqL;
2732 u8 ret = _FALSE;
2733 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2734 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2735
2736 if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
2737 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
2738 rtw_warn_on(1);
2739 }
2740 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2741 goto exit;
2742
2743 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2744 if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
2745 if (mac_addr) {
2746 mbid_cam_ctl->bitmap |= BIT(camid);
2747 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
2748 ret = _TRUE;
2749 }
2750 }
2751 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2752
2753 if (ret == _TRUE) {
2754 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2755 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
2756 #ifdef DBG_MBID_CAM_DUMP
2757 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2758 #endif
2759 } else
2760 RTW_INFO("%s [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
2761
2762 exit:
2763 return ret;
2764 }
2765
rtw_mbid_camid_clean(_adapter * adapter,u8 mbss_canid)2766 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
2767 {
2768 _irqL irqL;
2769 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2770 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2771
2772 if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
2773 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
2774 rtw_warn_on(1);
2775 }
2776 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2777 mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
2778 mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
2779 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2780 ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
2781 RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
2782 }
rtw_mbid_cam_cache_dump(void * sel,const char * fun_name,_adapter * adapter)2783 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
2784 {
2785 _irqL irqL;
2786 u8 i;
2787 _adapter *iface;
2788 u8 iface_id;
2789 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2790 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2791 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2792 u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2793
2794 RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
2795
2796 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2797 RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
2798 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2799 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2800
2801 if (mbid_cam_ctl->bitmap & BIT(i)) {
2802 iface_id = dvobj->mbid_cam_cache[i].iface_id;
2803 _RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
2804 _RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2805
2806 iface = dvobj->padapters[iface_id];
2807 if (iface) {
2808 if (MLME_IS_STA(iface))
2809 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
2810 else if (MLME_IS_AP(iface))
2811 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
2812 else if (MLME_IS_MESH(iface))
2813 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "MESH");
2814 else
2815 _RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2816 }
2817
2818 } else
2819 _RTW_PRINT_SEL(sel, "N/A\n");
2820 }
2821 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2822 return 0;
2823 }
2824
read_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2825 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2826 {
2827 u8 poll = 1;
2828 u8 cam_ready = _FALSE;
2829 u32 cam_data1 = 0;
2830 u16 cam_data2 = 0;
2831
2832 if (RTW_CANNOT_RUN(padapter))
2833 return;
2834
2835 rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2836
2837 do {
2838 if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2839 cam_ready = _TRUE;
2840 break;
2841 }
2842 poll++;
2843 } while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2844
2845 if (cam_ready) {
2846 cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2847 mac[0] = cam_data1 & 0xFF;
2848 mac[1] = (cam_data1 >> 8) & 0xFF;
2849 mac[2] = (cam_data1 >> 16) & 0xFF;
2850 mac[3] = (cam_data1 >> 24) & 0xFF;
2851
2852 cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
2853 mac[4] = cam_data2 & 0xFF;
2854 mac[5] = (cam_data2 >> 8) & 0xFF;
2855 }
2856
2857 }
rtw_mbid_cam_dump(void * sel,const char * fun_name,_adapter * adapter)2858 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
2859 {
2860 /*_irqL irqL;*/
2861 u8 i;
2862 u8 mac_addr[ETH_ALEN];
2863
2864 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2865 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2866
2867 RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
2868
2869 /*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2870 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2871 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2872 _rtw_memset(mac_addr, 0, ETH_ALEN);
2873 read_mbssid_cam(adapter, i, mac_addr);
2874 _RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
2875 }
2876 /*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2877 return 0;
2878 }
2879
write_mbssid_cam(_adapter * padapter,u8 cam_addr,u8 * mac)2880 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2881 {
2882 u32 cam_val[2] = {0};
2883
2884 cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
2885 cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT) | (mac[5] << 8) | mac[4];
2886
2887 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
2888 }
2889
2890 /*
2891 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
2892 {
2893 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
2894 }
2895 */
2896
rtw_ap_set_mbid_num(_adapter * adapter,u8 ap_num)2897 void rtw_ap_set_mbid_num(_adapter *adapter, u8 ap_num)
2898 {
2899 rtw_write8(adapter, REG_MBID_NUM,
2900 ((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | ((ap_num -1) & 0x07)));
2901
2902 }
rtw_mbid_cam_enable(_adapter * adapter)2903 void rtw_mbid_cam_enable(_adapter *adapter)
2904 {
2905 /*enable MBSSID*/
2906 rtw_hal_rcr_add(adapter, RCR_ENMBID);
2907 }
rtw_mi_set_mbid_cam(_adapter * adapter)2908 void rtw_mi_set_mbid_cam(_adapter *adapter)
2909 {
2910 u8 i;
2911 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2912 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2913
2914 #ifdef DBG_MBID_CAM_DUMP
2915 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2916 #endif
2917
2918 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2919 if (mbid_cam_ctl->bitmap & BIT(i)) {
2920 write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
2921 RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2922 }
2923 }
2924 rtw_mbid_cam_enable(adapter);
2925 }
2926 #endif /*CONFIG_MBSSID_CAM*/
2927
2928 #ifdef CONFIG_FW_HANDLE_TXBCN
2929 #define H2C_BCN_OFFLOAD_LEN 1
2930
2931 #define SET_H2CCMD_BCN_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value)
2932 #define SET_H2CCMD_BCN_ROOT_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value)
2933 #define SET_H2CCMD_BCN_VAP1_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value)
2934 #define SET_H2CCMD_BCN_VAP2_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value)
2935 #define SET_H2CCMD_BCN_VAP3_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value)
2936 #define SET_H2CCMD_BCN_VAP4_TBTT_RPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value)
2937
rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter * adapter,bool fw_bcn_en,u8 tbtt_rpt_map)2938 void rtw_hal_set_fw_ap_bcn_offload_cmd(_adapter *adapter, bool fw_bcn_en, u8 tbtt_rpt_map)
2939 {
2940 u8 fw_bcn_offload[1] = {0};
2941 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2942
2943 if (fw_bcn_en)
2944 SET_H2CCMD_BCN_OFFLOAD_EN(fw_bcn_offload, 1);
2945
2946 if (tbtt_rpt_map & BIT(0))
2947 SET_H2CCMD_BCN_ROOT_TBTT_RPT(fw_bcn_offload, 1);
2948 if (tbtt_rpt_map & BIT(1))
2949 SET_H2CCMD_BCN_VAP1_TBTT_RPT(fw_bcn_offload, 1);
2950 if (tbtt_rpt_map & BIT(2))
2951 SET_H2CCMD_BCN_VAP2_TBTT_RPT(fw_bcn_offload, 1);
2952 if (tbtt_rpt_map & BIT(3))
2953 SET_H2CCMD_BCN_VAP3_TBTT_RPT(fw_bcn_offload, 1);
2954
2955 dvobj->vap_tbtt_rpt_map = tbtt_rpt_map;
2956 dvobj->fw_bcn_offload = fw_bcn_en;
2957 RTW_INFO("[FW BCN] Offload : %s\n", (dvobj->fw_bcn_offload) ? "EN" : "DIS");
2958 RTW_INFO("[FW BCN] TBTT RPT map : 0x%02x\n", dvobj->vap_tbtt_rpt_map);
2959
2960 rtw_hal_fill_h2c_cmd(adapter, H2C_FW_BCN_OFFLOAD,
2961 H2C_BCN_OFFLOAD_LEN, fw_bcn_offload);
2962 }
2963
rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter * adapter)2964 void rtw_hal_set_bcn_rsvdpage_loc_cmd(_adapter *adapter)
2965 {
2966 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2967 u8 ret, vap_id;
2968 u32 page_size = 0;
2969 u8 bcn_rsvdpage[H2C_BCN_RSVDPAGE_LEN] = {0};
2970
2971 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
2972 #if 1
2973 for (vap_id = 0; vap_id < CONFIG_LIMITED_AP_NUM; vap_id++) {
2974 if (dvobj->vap_map & BIT(vap_id))
2975 bcn_rsvdpage[vap_id] = vap_id * (MAX_BEACON_LEN / page_size);
2976 }
2977 #else
2978 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value)
2979 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 8, __Value)
2980 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 8, __Value)
2981 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 8, __Value)
2982 #define SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 8, __Value)
2983
2984 if (dvobj->vap_map & BIT(0))
2985 SET_H2CCMD_BCN_RSVDPAGE_LOC_ROOT(bcn_rsvdpage, 0);
2986 if (dvobj->vap_map & BIT(1))
2987 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP1(bcn_rsvdpage,
2988 1 * (MAX_BEACON_LEN / page_size));
2989 if (dvobj->vap_map & BIT(2))
2990 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP2(bcn_rsvdpage,
2991 2 * (MAX_BEACON_LEN / page_size));
2992 if (dvobj->vap_map & BIT(3))
2993 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP3(bcn_rsvdpage,
2994 3 * (MAX_BEACON_LEN / page_size));
2995 if (dvobj->vap_map & BIT(4))
2996 SET_H2CCMD_BCN_RSVDPAGE_LOC_VAP4(bcn_rsvdpage,
2997 4 * (MAX_BEACON_LEN / page_size));
2998 #endif
2999 if (1) {
3000 RTW_INFO("[BCN_LOC] vap_map : 0x%02x\n", dvobj->vap_map);
3001 RTW_INFO("[BCN_LOC] page_size :%d, @bcn_page_num :%d\n"
3002 , page_size, (MAX_BEACON_LEN / page_size));
3003 RTW_INFO("[BCN_LOC] root ap : 0x%02x\n", *bcn_rsvdpage);
3004 RTW_INFO("[BCN_LOC] vap_1 : 0x%02x\n", *(bcn_rsvdpage + 1));
3005 RTW_INFO("[BCN_LOC] vap_2 : 0x%02x\n", *(bcn_rsvdpage + 2));
3006 RTW_INFO("[BCN_LOC] vap_3 : 0x%02x\n", *(bcn_rsvdpage + 3));
3007 RTW_INFO("[BCN_LOC] vap_4 : 0x%02x\n", *(bcn_rsvdpage + 4));
3008 }
3009 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_BCN_RSVDPAGE,
3010 H2C_BCN_RSVDPAGE_LEN, bcn_rsvdpage);
3011 }
3012
rtw_ap_multi_bcn_cfg(_adapter * adapter)3013 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3014 {
3015 u8 dft_bcn_space = DEFAULT_BCN_INTERVAL;
3016 u8 sub_bcn_space = (DEFAULT_BCN_INTERVAL / CONFIG_LIMITED_AP_NUM);
3017
3018 /*enable to rx data frame*/
3019 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3020
3021 /*Disable Port0's beacon function*/
3022 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
3023 /*Reset Port0's TSF*/
3024 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT_TSFTR_RST);
3025
3026 rtw_ap_set_mbid_num(adapter, CONFIG_LIMITED_AP_NUM);
3027
3028 /*BCN space & BCN sub-space 0x554[15:0] = 0x64,0x5BC[23:16] = 0x21*/
3029 rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), HW_PORT0, dft_bcn_space);
3030 rtw_write8(adapter, REG_MBSSID_BCN_SPACE3 + 2, sub_bcn_space);
3031
3032 #if 0 /*setting in hw_var_set_opmode_mbid - ResumeTxBeacon*/
3033 /*BCN hold time 0x540[19:8] = 0x80*/
3034 rtw_write8(adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
3035 rtw_write8(adapter, REG_TBTT_PROHIBIT + 2,
3036 (rtw_read8(adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
3037 #endif
3038
3039 /*ATIM window -0x55A = 0x32, reg 0x570 = 0x32, reg 0x5A0 = 0x32 */
3040 rtw_write8(adapter, REG_ATIMWND, 0x32);
3041 rtw_write8(adapter, REG_ATIMWND1_V1, 0x32);
3042 rtw_write8(adapter, REG_ATIMWND2, 0x32);
3043 rtw_write8(adapter, REG_ATIMWND3, 0x32);
3044 /*
3045 rtw_write8(adapter, REG_ATIMWND4, 0x32);
3046 rtw_write8(adapter, REG_ATIMWND5, 0x32);
3047 rtw_write8(adapter, REG_ATIMWND6, 0x32);
3048 rtw_write8(adapter, REG_ATIMWND7, 0x32);*/
3049
3050 /*no limit setting - 0x5A7 = 0xFF - Packet in Hi Queue Tx immediately*/
3051 rtw_write8(adapter, REG_HIQ_NO_LMT_EN, 0xFF);
3052
3053 /*Mask all beacon*/
3054 rtw_write8(adapter, REG_MBSSID_CTRL, 0);
3055
3056 /*BCN invalid bit setting 0x454[6] = 1*/
3057 /*rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);*/
3058
3059 /*Enable Port0's beacon function*/
3060 rtw_write8(adapter, REG_BCN_CTRL,
3061 rtw_read8(adapter, REG_BCN_CTRL) | BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION);
3062
3063 /* Enable HW seq for BCN
3064 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
3065 #ifdef CONFIG_RTL8822B
3066 if (IS_HARDWARE_TYPE_8822B(adapter))
3067 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3068 #endif
3069
3070 #ifdef CONFIG_RTL8822C
3071 if (IS_HARDWARE_TYPE_8822C(adapter))
3072 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3073 #endif
3074 }
_rtw_mbid_bcn_cfg(_adapter * adapter,bool mbcnq_en,u8 mbcnq_id)3075 static void _rtw_mbid_bcn_cfg(_adapter *adapter, bool mbcnq_en, u8 mbcnq_id)
3076 {
3077 if (mbcnq_id >= CONFIG_LIMITED_AP_NUM) {
3078 RTW_ERR(FUNC_ADPT_FMT"- mbid bcnq_id(%d) invalid\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3079 rtw_warn_on(1);
3080 }
3081
3082 if (mbcnq_en) {
3083 rtw_write8(adapter, REG_MBSSID_CTRL,
3084 rtw_read8(adapter, REG_MBSSID_CTRL) | BIT(mbcnq_id));
3085 RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) enabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3086 } else {
3087 rtw_write8(adapter, REG_MBSSID_CTRL,
3088 rtw_read8(adapter, REG_MBSSID_CTRL) & (~BIT(mbcnq_id)));
3089 RTW_INFO(FUNC_ADPT_FMT"- mbid bcnq_id(%d) disabled\n", FUNC_ADPT_ARG(adapter), mbcnq_id);
3090 }
3091 }
3092 /*#define CONFIG_FW_TBTT_RPT*/
rtw_ap_mbid_bcn_en(_adapter * adapter,u8 ap_id)3093 void rtw_ap_mbid_bcn_en(_adapter *adapter, u8 ap_id)
3094 {
3095 RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3096
3097 #ifdef CONFIG_FW_TBTT_RPT
3098 if (rtw_ap_get_nums(adapter) >= 1) {
3099 u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3100
3101 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3102 tbtt_rpt_map | BIT(ap_id));/*H2C-0xBA*/
3103 }
3104 #else
3105 if (rtw_ap_get_nums(adapter) == 1)
3106 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE, 0);/*H2C-0xBA*/
3107 #endif
3108
3109 rtw_hal_set_bcn_rsvdpage_loc_cmd(adapter);/*H2C-0x09*/
3110
3111 _rtw_mbid_bcn_cfg(adapter, _TRUE, ap_id);
3112 }
rtw_ap_mbid_bcn_dis(_adapter * adapter,u8 ap_id)3113 void rtw_ap_mbid_bcn_dis(_adapter *adapter, u8 ap_id)
3114 {
3115 RTW_INFO(FUNC_ADPT_FMT"- ap_id(%d)\n", FUNC_ADPT_ARG(adapter), ap_id);
3116 _rtw_mbid_bcn_cfg(adapter, _FALSE, ap_id);
3117
3118 if (rtw_ap_get_nums(adapter) == 0)
3119 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _FALSE, 0);
3120 #ifdef CONFIG_FW_TBTT_RPT
3121 else if (rtw_ap_get_nums(adapter) >= 1) {
3122 u8 tbtt_rpt_map = adapter_to_dvobj(adapter)->vap_tbtt_rpt_map;
3123
3124 rtw_hal_set_fw_ap_bcn_offload_cmd(adapter, _TRUE,
3125 tbtt_rpt_map & ~BIT(ap_id));/*H2C-0xBA*/
3126 }
3127 #endif
3128 }
3129 #endif
3130 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_ap_multi_bcn_cfg(_adapter * adapter)3131 void rtw_ap_multi_bcn_cfg(_adapter *adapter)
3132 {
3133 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3134 rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT);
3135 #else
3136 rtw_write8(adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
3137 #endif
3138 /*enable to rx data frame*/
3139 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
3140
3141 /*Beacon Control related register for first time*/
3142 rtw_write8(adapter, REG_BCNDMATIM, 0x02); /* 2ms */
3143
3144 /*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
3145 rtw_write8(adapter, REG_ATIMWND, 0x0c); /* 12ms */
3146
3147 #ifndef CONFIG_HW_P0_TSF_SYNC
3148 #ifdef CONFIG_RTL8192F
3149 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x640);/*unit:32us*/
3150 #else/*not CONFIG_RTL8192F*/
3151 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
3152 #endif
3153 #endif
3154
3155 /*reset TSF*/
3156 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
3157
3158 /*enable BCN0 Function for if1*/
3159 /*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
3160 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
3161 rtw_write8(adapter, REG_BCN_CTRL, BIT_DIS_RX_BSSID_FIT | BIT_P0_EN_TXBCN_RPT | BIT_DIS_TSF_UDT |BIT_EN_BCN_FUNCTION);
3162 #else
3163 rtw_write8(adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
3164 #endif
3165 #ifdef CONFIG_BCN_XMIT_PROTECT
3166 rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) | BIT_EN_BCN_PKT_REL);
3167 #endif
3168
3169 if (IS_HARDWARE_TYPE_8821(adapter) || IS_HARDWARE_TYPE_8192E(adapter))/* select BCN on port 0 for DualBeacon*/
3170 rtw_write8(adapter, REG_CCK_CHECK, rtw_read8(adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
3171
3172 /* Enable HW seq for BCN
3173 * 0x4FC[0]: EN_HWSEQ / 0x4FC[1]: EN_HWSEQEXT */
3174 #ifdef CONFIG_RTL8822B
3175 if (IS_HARDWARE_TYPE_8822B(adapter))
3176 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822B, 0x01);
3177 #endif
3178
3179 #ifdef CONFIG_RTL8822C
3180 if (IS_HARDWARE_TYPE_8822C(adapter))
3181 rtw_write8(adapter, REG_DUMMY_PAGE4_V1_8822C, 0x01);
3182 #endif
3183 }
3184 #endif
3185
3186 #ifdef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3187 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3188 {
3189
3190 #if 0 /*TODO - modify for more flexible*/
3191 u8 idx = 0;
3192
3193 if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
3194 (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
3195 for (idx = 0; idx < 6; idx++)
3196 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
3197 } else {
3198 /*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
3199 u8 entry_id;
3200
3201 if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
3202 (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
3203 entry_id = 0;
3204 if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
3205 RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
3206 write_mbssid_cam(adapter, entry_id, val);
3207 }
3208 } else {
3209 entry_id = rtw_mbid_camid_alloc(adapter, val);
3210 if (entry_id != INVALID_CAM_ID)
3211 write_mbssid_cam(adapter, entry_id, val);
3212 }
3213 }
3214 #else
3215 {
3216 /*
3217 MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
3218 */
3219 u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
3220
3221
3222 if (entry_id != INVALID_CAM_ID) {
3223 write_mbssid_cam(adapter, entry_id, mac_addr);
3224 RTW_INFO("%s "ADPT_FMT"- mbid(%d) mac_addr ="MAC_FMT"\n", __func__,
3225 ADPT_ARG(adapter), entry_id, MAC_ARG(mac_addr));
3226 }
3227 }
3228 #endif
3229 }
3230
rtw_hal_change_macaddr_mbid(_adapter * adapter,u8 * mac_addr)3231 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
3232 {
3233 u8 idx = 0;
3234 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3235 u8 entry_id;
3236
3237 if (!mac_addr) {
3238 rtw_warn_on(1);
3239 return;
3240 }
3241
3242
3243 entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
3244
3245 if (entry_id != INVALID_CAM_ID)
3246 write_mbssid_cam(adapter, entry_id, mac_addr);
3247 }
3248
3249 #ifdef CONFIG_SWTIMER_BASED_TXBCN
rtw_hal_bcn_interval_adjust(_adapter * adapter,u16 bcn_interval)3250 u16 rtw_hal_bcn_interval_adjust(_adapter *adapter, u16 bcn_interval)
3251 {
3252 if (adapter_to_dvobj(adapter)->inter_bcn_space != bcn_interval)
3253 return adapter_to_dvobj(adapter)->inter_bcn_space;
3254 else
3255 return bcn_interval;
3256 }
3257 #endif/*CONFIG_SWTIMER_BASED_TXBCN*/
3258
3259 #else
3260
3261 #ifndef RTW_HALMAC
_get_macaddr_reg(enum _hw_port hwport)3262 static u32 _get_macaddr_reg(enum _hw_port hwport)
3263 {
3264 u32 reg_macaddr = REG_MACID;
3265
3266 #ifdef CONFIG_CONCURRENT_MODE
3267 if (hwport == HW_PORT1)
3268 reg_macaddr = REG_MACID1;
3269 #if defined(CONFIG_RTL8814A)
3270 else if (hwport == HW_PORT2)
3271 reg_macaddr = REG_MACID2;
3272 else if (hwport == HW_PORT3)
3273 reg_macaddr = REG_MACID3;
3274 else if (hwport == HW_PORT4)
3275 reg_macaddr = REG_MACID4;
3276 #endif /*CONFIG_RTL8814A*/
3277 #endif /*CONFIG_CONCURRENT_MODE*/
3278
3279 return reg_macaddr;
3280 }
3281 #endif /*!RTW_HALMAC*/
3282
rtw_hal_set_macaddr_port(_adapter * adapter,u8 * mac_addr)3283 static void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *mac_addr)
3284 {
3285 enum _hw_port hwport;
3286
3287 if (mac_addr == NULL)
3288 return;
3289 hwport = get_hw_port(adapter);
3290
3291 RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3292 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3293
3294 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3295 rtw_halmac_set_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3296 #else /* !RTW_HALMAC */
3297 {
3298 u8 idx = 0;
3299 u32 reg_macaddr = _get_macaddr_reg(hwport);
3300
3301 for (idx = 0; idx < ETH_ALEN; idx++)
3302 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx), mac_addr[idx]);
3303 }
3304 #endif /* !RTW_HALMAC */
3305 }
3306
rtw_hal_get_macaddr_port(_adapter * adapter,u8 * mac_addr)3307 static void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
3308 {
3309 enum _hw_port hwport;
3310
3311 if (mac_addr == NULL)
3312 return;
3313 hwport = get_hw_port(adapter);
3314
3315 _rtw_memset(mac_addr, 0, ETH_ALEN);
3316 #ifdef RTW_HALMAC /*8822B ~ 8814B*/
3317 rtw_halmac_get_mac_address(adapter_to_dvobj(adapter), hwport, mac_addr);
3318 #else /* !RTW_HALMAC */
3319 {
3320 u8 idx = 0;
3321 u32 reg_macaddr = _get_macaddr_reg(hwport);
3322
3323 for (idx = 0; idx < ETH_ALEN; idx++)
3324 mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macaddr + idx));
3325 }
3326 #endif /* !RTW_HALMAC */
3327
3328 RTW_DBG("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
3329 ADPT_ARG(adapter), hwport, MAC_ARG(mac_addr));
3330 }
3331 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
3332
3333 #ifndef RTW_HALMAC
_get_bssid_reg(enum _hw_port hw_port)3334 static u32 _get_bssid_reg(enum _hw_port hw_port)
3335 {
3336 u32 reg_bssid = REG_BSSID;
3337
3338 #ifdef CONFIG_CONCURRENT_MODE
3339 if (hw_port == HW_PORT1)
3340 reg_bssid = REG_BSSID1;
3341 #if defined(CONFIG_RTL8814A)
3342 else if (hw_port == HW_PORT2)
3343 reg_bssid = REG_BSSID2;
3344 else if (hw_port == HW_PORT3)
3345 reg_bssid = REG_BSSID3;
3346 else if (hw_port == HW_PORT4)
3347 reg_bssid = REG_BSSID4;
3348 #endif /*CONFIG_RTL8814A*/
3349 #endif /*CONFIG_CONCURRENT_MODE*/
3350
3351 return reg_bssid;
3352 }
3353 #endif /*!RTW_HALMAC*/
rtw_hal_set_bssid(_adapter * adapter,u8 * val)3354 static void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
3355 {
3356 enum _hw_port hw_port = rtw_hal_get_port(adapter);
3357 #ifdef RTW_HALMAC
3358
3359 rtw_halmac_set_bssid(adapter_to_dvobj(adapter), hw_port, val);
3360 #else /* !RTW_HALMAC */
3361 u8 idx = 0;
3362 u32 reg_bssid = _get_bssid_reg(hw_port);
3363
3364 for (idx = 0 ; idx < ETH_ALEN; idx++)
3365 rtw_write8(adapter, (reg_bssid + idx), val[idx]);
3366 #endif /* !RTW_HALMAC */
3367
3368 RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n",
3369 __func__, ADPT_ARG(adapter), hw_port, MAC_ARG(val));
3370 }
3371
3372 #ifndef CONFIG_MI_WITH_MBSSID_CAM
rtw_hal_set_tsf_update(_adapter * adapter,u8 en)3373 static void rtw_hal_set_tsf_update(_adapter *adapter, u8 en)
3374 {
3375 u32 addr = 0;
3376 u8 val8;
3377
3378 rtw_hal_get_hwreg(adapter, HW_VAR_BCN_CTRL_ADDR, (u8 *)&addr);
3379 if (addr) {
3380 rtw_enter_protsel_port(adapter, get_hw_port(adapter));
3381 val8 = rtw_read8(adapter, addr);
3382 if (en && (val8 & DIS_TSF_UDT)) {
3383 rtw_write8(adapter, addr, val8 & ~DIS_TSF_UDT);
3384 #ifdef DBG_TSF_UPDATE
3385 RTW_INFO("port%u("ADPT_FMT") enable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3386 #endif
3387 }
3388 if (!en && !(val8 & DIS_TSF_UDT)) {
3389 rtw_write8(adapter, addr, val8 | DIS_TSF_UDT);
3390 #ifdef DBG_TSF_UPDATE
3391 RTW_INFO("port%u("ADPT_FMT") disable TSF update\n", adapter->hw_port, ADPT_ARG(adapter));
3392 #endif
3393 }
3394 rtw_leave_protsel_port(adapter);
3395 } else {
3396 RTW_WARN("unknown port%d("ADPT_FMT") %s TSF update\n"
3397 , adapter->hw_port, ADPT_ARG(adapter), en ? "enable" : "disable");
3398 rtw_warn_on(1);
3399 }
3400 }
3401 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_set_hw_update_tsf(PADAPTER padapter)3402 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
3403 {
3404 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3405
3406 #else
3407 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3408
3409 if (!pmlmeext->en_hw_update_tsf)
3410 return;
3411
3412 /* check RCR */
3413 if (!rtw_hal_rcr_check(padapter, RCR_CBSSID_BCN))
3414 return;
3415
3416 if (pmlmeext->tsf_update_required) {
3417 pmlmeext->tsf_update_pause_stime = 0;
3418 rtw_hal_set_tsf_update(padapter, 1);
3419 }
3420
3421 pmlmeext->en_hw_update_tsf = 0;
3422 #endif
3423 }
3424
rtw_iface_enable_tsf_update(_adapter * adapter)3425 void rtw_iface_enable_tsf_update(_adapter *adapter)
3426 {
3427 adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3428 adapter->mlmeextpriv.tsf_update_required = 1;
3429 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3430
3431 #else
3432 rtw_hal_set_tsf_update(adapter, 1);
3433 #endif
3434 }
3435
rtw_iface_disable_tsf_update(_adapter * adapter)3436 void rtw_iface_disable_tsf_update(_adapter *adapter)
3437 {
3438 adapter->mlmeextpriv.tsf_update_required = 0;
3439 adapter->mlmeextpriv.tsf_update_pause_stime = 0;
3440 adapter->mlmeextpriv.en_hw_update_tsf = 0;
3441 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3442
3443 #else
3444 rtw_hal_set_tsf_update(adapter, 0);
3445 #endif
3446 }
3447
rtw_hal_tsf_update_pause(_adapter * adapter)3448 static void rtw_hal_tsf_update_pause(_adapter *adapter)
3449 {
3450 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3451
3452 #else
3453 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3454 _adapter *iface;
3455 int i;
3456
3457 for (i = 0; i < dvobj->iface_nums; i++) {
3458 iface = dvobj->padapters[i];
3459 if (!iface)
3460 continue;
3461
3462 rtw_hal_set_tsf_update(iface, 0);
3463 if (iface->mlmeextpriv.tsf_update_required) {
3464 iface->mlmeextpriv.tsf_update_pause_stime = rtw_get_current_time();
3465 if (!iface->mlmeextpriv.tsf_update_pause_stime)
3466 iface->mlmeextpriv.tsf_update_pause_stime++;
3467 }
3468 iface->mlmeextpriv.en_hw_update_tsf = 0;
3469 }
3470 #endif
3471 }
3472
rtw_hal_tsf_update_restore(_adapter * adapter)3473 static void rtw_hal_tsf_update_restore(_adapter *adapter)
3474 {
3475 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3476
3477 #else
3478 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3479 _adapter *iface;
3480 int i;
3481
3482 for (i = 0; i < dvobj->iface_nums; i++) {
3483 iface = dvobj->padapters[i];
3484 if (!iface)
3485 continue;
3486
3487 if (iface->mlmeextpriv.tsf_update_required) {
3488 /* enable HW TSF update when recive beacon*/
3489 iface->mlmeextpriv.en_hw_update_tsf = 1;
3490 #ifdef DBG_TSF_UPDATE
3491 RTW_INFO("port%d("ADPT_FMT") enabling TSF update...\n"
3492 , iface->hw_port, ADPT_ARG(iface));
3493 #endif
3494 }
3495 }
3496 #endif
3497 }
3498
rtw_hal_periodic_tsf_update_chk(_adapter * adapter)3499 void rtw_hal_periodic_tsf_update_chk(_adapter *adapter)
3500 {
3501 #ifdef CONFIG_MI_WITH_MBSSID_CAM
3502
3503 #else
3504 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3505 _adapter *iface;
3506 struct mlme_ext_priv *mlmeext;
3507 int i;
3508 u32 restore_ms = 0;
3509
3510 if (dvobj->periodic_tsf_update_etime) {
3511 if (rtw_time_after(rtw_get_current_time(), dvobj->periodic_tsf_update_etime)) {
3512 /* end for restore status */
3513 dvobj->periodic_tsf_update_etime = 0;
3514 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3515 }
3516 return;
3517 }
3518
3519 if (dvobj->rf_ctl.offch_state != OFFCHS_NONE)
3520 return;
3521
3522 /*
3523 * all required ifaces can switch to restore status together
3524 * loop all pause iface to get largest restore time required
3525 */
3526 for (i = 0; i < dvobj->iface_nums; i++) {
3527 iface = dvobj->padapters[i];
3528 if (!iface)
3529 continue;
3530
3531 mlmeext = &iface->mlmeextpriv;
3532
3533 if (mlmeext->tsf_update_required
3534 && mlmeext->tsf_update_pause_stime
3535 && rtw_get_passing_time_ms(mlmeext->tsf_update_pause_stime)
3536 > mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_pause_factor
3537 ) {
3538 if (restore_ms < mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor)
3539 restore_ms = mlmeext->mlmext_info.bcn_interval * mlmeext->tsf_update_restore_factor;
3540 }
3541 }
3542
3543 if (!restore_ms)
3544 return;
3545
3546 dvobj->periodic_tsf_update_etime = rtw_get_current_time() + rtw_ms_to_systime(restore_ms);
3547 if (!dvobj->periodic_tsf_update_etime)
3548 dvobj->periodic_tsf_update_etime++;
3549
3550 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3551
3552 /* set timer to end restore status */
3553 _set_timer(&dvobj->periodic_tsf_update_end_timer, restore_ms);
3554 #endif
3555 }
3556
rtw_hal_periodic_tsf_update_end_timer_hdl(void * ctx)3557 void rtw_hal_periodic_tsf_update_end_timer_hdl(void *ctx)
3558 {
3559 struct dvobj_priv *dvobj = (struct dvobj_priv *)ctx;
3560
3561 if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
3562 return;
3563
3564 rtw_periodic_tsf_update_end_cmd(dvobj_get_primary_adapter(dvobj));
3565 }
3566
hw_var_rcr_config(_adapter * adapter,u32 rcr)3567 static inline u8 hw_var_rcr_config(_adapter *adapter, u32 rcr)
3568 {
3569 int err;
3570
3571 #ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
3572 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;
3573 #endif
3574 err = rtw_write32(adapter, REG_RCR, rcr);
3575 if (err == _SUCCESS)
3576 GET_HAL_DATA(adapter)->ReceiveConfig = rcr;
3577 return err;
3578 }
3579
hw_var_rcr_get(_adapter * adapter,u32 * rcr)3580 static inline u8 hw_var_rcr_get(_adapter *adapter, u32 *rcr)
3581 {
3582 u32 v32;
3583
3584 v32 = rtw_read32(adapter, REG_RCR);
3585 if (rcr)
3586 *rcr = v32;
3587 GET_HAL_DATA(adapter)->ReceiveConfig = v32;
3588 return _SUCCESS;
3589 }
3590
3591 /* only check SW RCR variable */
rtw_hal_rcr_check(_adapter * adapter,u32 check_bit)3592 inline u8 rtw_hal_rcr_check(_adapter *adapter, u32 check_bit)
3593 {
3594 PHAL_DATA_TYPE hal;
3595 u32 rcr;
3596
3597 hal = GET_HAL_DATA(adapter);
3598
3599 rcr = hal->ReceiveConfig;
3600 if ((rcr & check_bit) == check_bit)
3601 return 1;
3602
3603 return 0;
3604 }
3605
rtw_hal_rcr_add(_adapter * adapter,u32 add)3606 inline u8 rtw_hal_rcr_add(_adapter *adapter, u32 add)
3607 {
3608 PHAL_DATA_TYPE hal;
3609 u32 rcr;
3610 u8 ret = _SUCCESS;
3611
3612 hal = GET_HAL_DATA(adapter);
3613
3614 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3615 rcr |= add;
3616 if (rcr != hal->ReceiveConfig)
3617 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3618
3619 return ret;
3620 }
3621
rtw_hal_rcr_clear(_adapter * adapter,u32 clear)3622 inline u8 rtw_hal_rcr_clear(_adapter *adapter, u32 clear)
3623 {
3624 PHAL_DATA_TYPE hal;
3625 u32 rcr;
3626 u8 ret = _SUCCESS;
3627
3628 hal = GET_HAL_DATA(adapter);
3629
3630 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3631 rcr &= ~clear;
3632 if (rcr != hal->ReceiveConfig)
3633 ret = rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3634
3635 return ret;
3636 }
3637
rtw_hal_rcr_set_chk_bssid(_adapter * adapter,u8 self_action)3638 void rtw_hal_rcr_set_chk_bssid(_adapter *adapter, u8 self_action)
3639 {
3640 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3641 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3642 u32 rcr, rcr_new;
3643 #if !defined(CONFIG_MI_WITH_MBSSID_CAM) || defined(CONFIG_CLIENT_PORT_CFG) || defined(CONFIG_RTW_MULTI_AP)
3644 struct mi_state mstate, mstate_s;
3645 #endif
3646
3647 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
3648 rcr_new = rcr;
3649
3650 #if !defined(CONFIG_MI_WITH_MBSSID_CAM) || defined(CONFIG_CLIENT_PORT_CFG) || defined(CONFIG_RTW_MULTI_AP)
3651 rtw_mi_status_no_self(adapter, &mstate);
3652 rtw_mi_status_no_others(adapter, &mstate_s);
3653
3654 /* only adjust parameters interested */
3655 switch (self_action) {
3656 case MLME_SCAN_ENTER:
3657 mstate_s.scan_num = 1;
3658 mstate_s.scan_enter_num = 1;
3659 break;
3660 case MLME_SCAN_DONE:
3661 mstate_s.scan_enter_num = 0;
3662 break;
3663 case MLME_STA_CONNECTING:
3664 mstate_s.lg_sta_num = 1;
3665 mstate_s.ld_sta_num = 0;
3666 break;
3667 case MLME_STA_CONNECTED:
3668 mstate_s.lg_sta_num = 0;
3669 mstate_s.ld_sta_num = 1;
3670 break;
3671 case MLME_STA_DISCONNECTED:
3672 mstate_s.lg_sta_num = 0;
3673 mstate_s.ld_sta_num = 0;
3674 break;
3675 #ifdef CONFIG_TDLS
3676 case MLME_TDLS_LINKED:
3677 mstate_s.ld_tdls_num = 1;
3678 break;
3679 case MLME_TDLS_NOLINK:
3680 mstate_s.ld_tdls_num = 0;
3681 break;
3682 #endif
3683 #ifdef CONFIG_AP_MODE
3684 case MLME_AP_STARTED:
3685 mstate_s.ap_num = 1;
3686 break;
3687 case MLME_AP_STOPPED:
3688 mstate_s.ap_num = 0;
3689 mstate_s.ld_ap_num = 0;
3690 break;
3691 #endif
3692 #ifdef CONFIG_RTW_MESH
3693 case MLME_MESH_STARTED:
3694 mstate_s.mesh_num = 1;
3695 break;
3696 case MLME_MESH_STOPPED:
3697 mstate_s.mesh_num = 0;
3698 mstate_s.ld_mesh_num = 0;
3699 break;
3700 #endif
3701 case MLME_ACTION_NONE:
3702 case MLME_ADHOC_STARTED:
3703 /* caller without effect of decision */
3704 break;
3705 default:
3706 rtw_warn_on(1);
3707 };
3708
3709 rtw_mi_status_merge(&mstate, &mstate_s);
3710 #endif /* !defined(CONFIG_MI_WITH_MBSSID_CAM) || defined(CONFIG_CLIENT_PORT_CFG) || defined(CONFIG_RTW_MULTI_AP) */
3711
3712 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && !defined(CONFIG_CLIENT_PORT_CFG)
3713 rcr_new &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
3714 #else
3715 if (MSTATE_AP_NUM(&mstate) || MSTATE_MESH_NUM(&mstate) || MSTATE_TDLS_LD_NUM(&mstate)
3716 #ifdef CONFIG_FIND_BEST_CHANNEL
3717 || MSTATE_SCAN_ENTER_NUM(&mstate)
3718 #endif
3719 || hal_data->in_cta_test
3720 )
3721 rcr_new &= ~RCR_CBSSID_DATA;
3722 else
3723 rcr_new |= RCR_CBSSID_DATA;
3724
3725 if (MSTATE_SCAN_ENTER_NUM(&mstate) || hal_data->in_cta_test)
3726 rcr_new &= ~RCR_CBSSID_BCN;
3727 else if (MSTATE_STA_LG_NUM(&mstate)
3728 || adapter_to_dvobj(adapter)->periodic_tsf_update_etime
3729 )
3730 rcr_new |= RCR_CBSSID_BCN;
3731 else if ((MSTATE_AP_NUM(&mstate) && adapter->registrypriv.wifi_spec) /* for 11n Logo 4.2.31/4.2.32 */
3732 || MSTATE_MESH_NUM(&mstate)
3733 )
3734 rcr_new &= ~RCR_CBSSID_BCN;
3735 else
3736 rcr_new |= RCR_CBSSID_BCN;
3737
3738 #ifdef CONFIG_CLIENT_PORT_CFG
3739 if (get_clt_num(adapter) > MAX_CLIENT_PORT_NUM)
3740 rcr_new &= ~RCR_CBSSID_BCN;
3741 #endif
3742 #endif /* CONFIG_MI_WITH_MBSSID_CAM */
3743
3744 #ifdef CONFIG_RTW_MULTI_AP
3745 if (MSTATE_AP_NUM(&mstate)
3746 && rtw_unassoc_sta_src_chk(adapter, UNASOC_STA_SRC_RX_NMY_UC)
3747 ) {
3748 rcr_new |= RCR_AAP;
3749 } else
3750 rcr_new &= ~RCR_AAP;
3751 #endif
3752
3753 if (rcr == rcr_new)
3754 return;
3755
3756 if (!hal_spec->rx_tsf_filter
3757 && (rcr & RCR_CBSSID_BCN) && !(rcr_new & RCR_CBSSID_BCN))
3758 rtw_hal_tsf_update_pause(adapter);
3759
3760 rtw_hal_set_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr_new);
3761
3762 if (!hal_spec->rx_tsf_filter
3763 && !(rcr & RCR_CBSSID_BCN) && (rcr_new & RCR_CBSSID_BCN)
3764 && self_action != MLME_STA_CONNECTING)
3765 rtw_hal_tsf_update_restore(adapter);
3766 }
3767
rtw_hal_rcr_set_chk_bssid_act_non(_adapter * adapter)3768 void rtw_hal_rcr_set_chk_bssid_act_non(_adapter *adapter)
3769 {
3770 rtw_hal_rcr_set_chk_bssid(adapter, MLME_ACTION_NONE);
3771 }
3772
hw_var_set_rcr_am(_adapter * adapter,u8 enable)3773 static void hw_var_set_rcr_am(_adapter *adapter, u8 enable)
3774 {
3775 u32 rcr = RCR_AM;
3776
3777 if (enable)
3778 rtw_hal_rcr_add(adapter, rcr);
3779 else
3780 rtw_hal_rcr_clear(adapter, rcr);
3781 }
3782
hw_var_set_bcn_interval(_adapter * adapter,u16 interval)3783 static void hw_var_set_bcn_interval(_adapter *adapter, u16 interval)
3784 {
3785 #ifdef CONFIG_SWTIMER_BASED_TXBCN
3786 interval = rtw_hal_bcn_interval_adjust(adapter, interval);
3787 #endif
3788
3789 #ifdef RTW_HALMAC
3790 rtw_halmac_set_bcn_interval(adapter_to_dvobj(adapter), adapter->hw_port, interval);
3791 #else
3792 rtw_write16(adapter, REG_MBSSID_BCN_SPACE, interval);
3793 #endif
3794
3795 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
3796 {
3797 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3798 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3799
3800 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
3801 RTW_INFO("%s==> bcn_interval:%d, eraly_int:%d\n", __func__, interval, interval >> 1);
3802 rtw_write8(adapter, REG_DRVERLYINT, interval >> 1);
3803 }
3804 }
3805 #endif
3806 }
3807
3808 #if CONFIG_TX_AC_LIFETIME
3809 const char *const _tx_aclt_conf_str[] = {
3810 "DEFAULT",
3811 "AP_M2U",
3812 "MESH",
3813 "INVALID",
3814 };
3815
dump_tx_aclt_force_val(void * sel,struct dvobj_priv * dvobj)3816 void dump_tx_aclt_force_val(void *sel, struct dvobj_priv *dvobj)
3817 {
3818 #define TX_ACLT_FORCE_MSG_LEN 64
3819 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3820 struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3821 char buf[TX_ACLT_FORCE_MSG_LEN];
3822 int cnt = 0;
3823
3824 RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3825 , hal_spec->tx_aclt_unit_factor * 32
3826 , 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3827
3828 RTW_PRINT_SEL(sel, "%-5s %-12s %-12s\n", "en", "vo_vi(us)", "be_bk(us)");
3829 RTW_PRINT_SEL(sel, " 0x%02x %12u %12u\n"
3830 , conf->en
3831 , conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3832 , conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3833 );
3834
3835 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, "%5s", conf->en == 0xFF ? "AUTO" : "FORCE");
3836 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3837 goto exit;
3838
3839 if (conf->vo_vi)
3840 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->vo_vi);
3841 else
3842 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");
3843 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3844 goto exit;
3845
3846
3847 if (conf->be_bk)
3848 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " FORCE:0x%04x", conf->be_bk);
3849 else
3850 cnt += snprintf(buf + cnt, TX_ACLT_FORCE_MSG_LEN - cnt - 1, " AUTO");
3851 if (cnt >= TX_ACLT_FORCE_MSG_LEN - 1)
3852 goto exit;
3853
3854 RTW_PRINT_SEL(sel, "%s\n", buf);
3855
3856 exit:
3857 return;
3858 }
3859
rtw_hal_set_tx_aclt_force_val(_adapter * adapter,struct tx_aclt_conf_t * input,u8 arg_num)3860 void rtw_hal_set_tx_aclt_force_val(_adapter *adapter, struct tx_aclt_conf_t *input, u8 arg_num)
3861 {
3862 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3863 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3864 struct tx_aclt_conf_t *conf = &dvobj->tx_aclt_force_val;
3865
3866 if (arg_num >= 1) {
3867 if (input->en == 0xFF)
3868 conf->en = input->en;
3869 else
3870 conf->en = input->en & 0xF;
3871 }
3872 if (arg_num >= 2) {
3873 conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
3874 if (conf->vo_vi > 0xFFFF)
3875 conf->vo_vi = 0xFFFF;
3876 }
3877 if (arg_num >= 3) {
3878 conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
3879 if (conf->be_bk > 0xFFFF)
3880 conf->be_bk = 0xFFFF;
3881 }
3882 }
3883
dump_tx_aclt_confs(void * sel,struct dvobj_priv * dvobj)3884 void dump_tx_aclt_confs(void *sel, struct dvobj_priv *dvobj)
3885 {
3886 #define TX_ACLT_CONF_MSG_LEN 32
3887 struct hal_spec_t *hal_spec = GET_HAL_SPEC(dvobj_get_primary_adapter(dvobj));
3888 struct tx_aclt_conf_t *conf;
3889 char buf[TX_ACLT_CONF_MSG_LEN];
3890 int cnt;
3891 int i;
3892
3893 RTW_PRINT_SEL(sel, "unit:%uus, maximum:%uus\n"
3894 , hal_spec->tx_aclt_unit_factor * 32
3895 , 0xFFFF * hal_spec->tx_aclt_unit_factor * 32);
3896
3897 RTW_PRINT_SEL(sel, "%-7s %-1s %-3s %-9s %-9s %-10s %-10s\n"
3898 , "name", "#", "en", "vo_vi(us)", "be_bk(us)", "vo_vi(reg)", "be_bk(reg)");
3899
3900 for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
3901 conf = &dvobj->tx_aclt_confs[i];
3902 cnt = 0;
3903
3904 if (conf->vo_vi)
3905 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->vo_vi);
3906 else
3907 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
3908 if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
3909 continue;
3910
3911 if (conf->be_bk)
3912 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " 0x%04x", conf->be_bk);
3913 else
3914 cnt += snprintf(buf + cnt, TX_ACLT_CONF_MSG_LEN - cnt - 1, " N/A");
3915 if (cnt >= TX_ACLT_CONF_MSG_LEN - 1)
3916 continue;
3917
3918 RTW_PRINT_SEL(sel, "%7s %1u 0x%x %9u %9u%s\n"
3919 , tx_aclt_conf_str(i), i
3920 , conf->en
3921 , conf->vo_vi * hal_spec->tx_aclt_unit_factor * 32
3922 , conf->be_bk * hal_spec->tx_aclt_unit_factor * 32
3923 , buf
3924 );
3925 }
3926 }
3927
rtw_hal_set_tx_aclt_conf(_adapter * adapter,u8 conf_idx,struct tx_aclt_conf_t * input,u8 arg_num)3928 void rtw_hal_set_tx_aclt_conf(_adapter *adapter, u8 conf_idx, struct tx_aclt_conf_t *input, u8 arg_num)
3929 {
3930 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3931 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3932 struct tx_aclt_conf_t *conf;
3933
3934 if (conf_idx >= TX_ACLT_CONF_NUM)
3935 return;
3936
3937 conf = &dvobj->tx_aclt_confs[conf_idx];
3938
3939 if (arg_num >= 1) {
3940 if (input->en != 0xFF)
3941 conf->en = input->en & 0xF;
3942 }
3943 if (arg_num >= 2) {
3944 conf->vo_vi = input->vo_vi / (hal_spec->tx_aclt_unit_factor * 32);
3945 if (conf->vo_vi > 0xFFFF)
3946 conf->vo_vi = 0xFFFF;
3947 }
3948 if (arg_num >= 3) {
3949 conf->be_bk = input->be_bk / (hal_spec->tx_aclt_unit_factor * 32);
3950 if (conf->be_bk > 0xFFFF)
3951 conf->be_bk = 0xFFFF;
3952 }
3953 }
3954
rtw_hal_update_tx_aclt(_adapter * adapter)3955 void rtw_hal_update_tx_aclt(_adapter *adapter)
3956 {
3957 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3958 struct macid_ctl_t *macid_ctl = adapter_to_macidctl(adapter);
3959 u8 lt_en = 0, lt_en_ori;
3960 u16 lt_vo_vi = 0xFFFF, lt_be_bk = 0xFFFF;
3961 u32 lt, lt_ori;
3962 struct tx_aclt_conf_t *conf;
3963 int i;
3964 #ifdef CONFIG_AP_MODE
3965 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
3966 _adapter *iface;
3967 u8 ap_m2u_num = 0;
3968
3969 for (i = 0; i < dvobj->iface_nums; i++) {
3970 iface = dvobj->padapters[i];
3971 if (!iface)
3972 continue;
3973
3974 if (MLME_IS_AP(iface)
3975 && ((iface->b2u_flags_ap_src & RTW_AP_B2U_IP_MCAST)
3976 || (iface->b2u_flags_ap_fwd & RTW_AP_B2U_IP_MCAST))
3977 )
3978 ap_m2u_num++;
3979 }
3980 #endif
3981 #endif /* CONFIG_AP_MODE */
3982
3983 lt_en_ori = rtw_read8(adapter, REG_LIFETIME_EN);
3984 lt_ori = rtw_read32(adapter, REG_PKT_LIFE_TIME);
3985
3986 for (i = 0; i < TX_ACLT_CONF_NUM; i++) {
3987 if (!(dvobj->tx_aclt_flags & BIT(i)))
3988 continue;
3989
3990 conf = &dvobj->tx_aclt_confs[i];
3991
3992 if (i == TX_ACLT_CONF_DEFAULT) {
3993 /* first and default status, assign directly */
3994 lt_en = conf->en;
3995 if (conf->vo_vi)
3996 lt_vo_vi = conf->vo_vi;
3997 if (conf->be_bk)
3998 lt_be_bk = conf->be_bk;
3999 }
4000 #ifdef CONFIG_AP_MODE
4001 #if CONFIG_RTW_AP_DATA_BMC_TO_UC || defined(CONFIG_RTW_MESH)
4002 else if (0
4003 #if CONFIG_RTW_AP_DATA_BMC_TO_UC
4004 || (i == TX_ACLT_CONF_AP_M2U
4005 && ap_m2u_num
4006 && macid_ctl->op_num[H2C_MSR_ROLE_STA] /* having AP mode with STA connected */)
4007 #endif
4008 #ifdef CONFIG_RTW_MESH
4009 || (i == TX_ACLT_CONF_MESH
4010 && macid_ctl->op_num[H2C_MSR_ROLE_MESH] > 1 /* implies only 1 MESH mode supported */)
4011 #endif
4012 ) {
4013 /* long term status, OR en and MIN lifetime */
4014 lt_en |= conf->en;
4015 if (conf->vo_vi && lt_vo_vi > conf->vo_vi)
4016 lt_vo_vi = conf->vo_vi;
4017 if (conf->be_bk && lt_be_bk > conf->be_bk)
4018 lt_be_bk = conf->be_bk;
4019 }
4020 #endif
4021 #endif /* CONFIG_AP_MODE */
4022 }
4023
4024 if (dvobj->tx_aclt_force_val.en != 0xFF)
4025 lt_en = dvobj->tx_aclt_force_val.en;
4026 if (dvobj->tx_aclt_force_val.vo_vi)
4027 lt_vo_vi = dvobj->tx_aclt_force_val.vo_vi;
4028 if (dvobj->tx_aclt_force_val.be_bk)
4029 lt_be_bk = dvobj->tx_aclt_force_val.be_bk;
4030
4031 lt_en = (lt_en_ori & 0xF0) | (lt_en & 0x0F);
4032 lt = (lt_be_bk << 16) | lt_vo_vi;
4033
4034 if (0)
4035 RTW_INFO("lt_en:0x%x(0x%x), lt:0x%08x(0x%08x)\n", lt_en, lt_en_ori, lt, lt_ori);
4036
4037 if (lt_en != lt_en_ori)
4038 rtw_write8(adapter, REG_LIFETIME_EN, lt_en);
4039 if (lt != lt_ori)
4040 rtw_write32(adapter, REG_PKT_LIFE_TIME, lt);
4041 }
4042 #endif /* CONFIG_TX_AC_LIFETIME */
4043
hw_var_port_switch(_adapter * adapter)4044 void hw_var_port_switch(_adapter *adapter)
4045 {
4046 #ifdef CONFIG_CONCURRENT_MODE
4047 #ifdef CONFIG_RUNTIME_PORT_SWITCH
4048 /*
4049 0x102: MSR
4050 0x550: REG_BCN_CTRL
4051 0x551: REG_BCN_CTRL_1
4052 0x55A: REG_ATIMWND
4053 0x560: REG_TSFTR
4054 0x568: REG_TSFTR1
4055 0x570: REG_ATIMWND_1
4056 0x610: REG_MACID
4057 0x618: REG_BSSID
4058 0x700: REG_MACID1
4059 0x708: REG_BSSID1
4060 */
4061
4062 int i;
4063 u8 msr;
4064 u8 bcn_ctrl;
4065 u8 bcn_ctrl_1;
4066 u8 atimwnd[2];
4067 u8 atimwnd_1[2];
4068 u8 tsftr[8];
4069 u8 tsftr_1[8];
4070 u8 macid[6];
4071 u8 bssid[6];
4072 u8 macid_1[6];
4073 u8 bssid_1[6];
4074 #if defined(CONFIG_RTL8192F)
4075 u16 wlan_act_mask_ctrl = 0;
4076 u16 en_port_mask = EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION;
4077 #endif
4078
4079 u8 hw_port;
4080 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4081 _adapter *iface = NULL;
4082
4083 msr = rtw_read8(adapter, MSR);
4084 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4085 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4086 #if defined(CONFIG_RTL8192F)
4087 wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4088 #endif
4089
4090 for (i = 0; i < 2; i++)
4091 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4092 for (i = 0; i < 2; i++)
4093 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4094
4095 for (i = 0; i < 8; i++)
4096 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4097 for (i = 0; i < 8; i++)
4098 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4099
4100 for (i = 0; i < 6; i++)
4101 macid[i] = rtw_read8(adapter, REG_MACID + i);
4102
4103 for (i = 0; i < 6; i++)
4104 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4105
4106 for (i = 0; i < 6; i++)
4107 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4108
4109 for (i = 0; i < 6; i++)
4110 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4111
4112 #ifdef DBG_RUNTIME_PORT_SWITCH
4113 RTW_INFO(FUNC_ADPT_FMT" before switch\n"
4114 "msr:0x%02x\n"
4115 "bcn_ctrl:0x%02x\n"
4116 "bcn_ctrl_1:0x%02x\n"
4117 #if defined(CONFIG_RTL8192F)
4118 "wlan_act_mask_ctrl:0x%02x\n"
4119 #endif
4120 "atimwnd:0x%04x\n"
4121 "atimwnd_1:0x%04x\n"
4122 "tsftr:%llu\n"
4123 "tsftr1:%llu\n"
4124 "macid:"MAC_FMT"\n"
4125 "bssid:"MAC_FMT"\n"
4126 "macid_1:"MAC_FMT"\n"
4127 "bssid_1:"MAC_FMT"\n"
4128 , FUNC_ADPT_ARG(adapter)
4129 , msr
4130 , bcn_ctrl
4131 , bcn_ctrl_1
4132 #if defined(CONFIG_RTL8192F)
4133 , wlan_act_mask_ctrl
4134 #endif
4135 , *((u16 *)atimwnd)
4136 , *((u16 *)atimwnd_1)
4137 , *((u64 *)tsftr)
4138 , *((u64 *)tsftr_1)
4139 , MAC_ARG(macid)
4140 , MAC_ARG(bssid)
4141 , MAC_ARG(macid_1)
4142 , MAC_ARG(bssid_1)
4143 );
4144 #endif /* DBG_RUNTIME_PORT_SWITCH */
4145
4146 /* disable bcn function, disable update TSF */
4147 rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4148 rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
4149
4150 #if defined(CONFIG_RTL8192F)
4151 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl & ~en_port_mask);
4152 #endif
4153
4154 /* switch msr */
4155 msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
4156 rtw_write8(adapter, MSR, msr);
4157
4158 /* write port0 */
4159 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
4160 for (i = 0; i < 2; i++)
4161 rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
4162 for (i = 0; i < 8; i++)
4163 rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
4164 for (i = 0; i < 6; i++)
4165 rtw_write8(adapter, REG_MACID + i, macid_1[i]);
4166 for (i = 0; i < 6; i++)
4167 rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
4168
4169 /* write port1 */
4170 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
4171 for (i = 0; i < 2; i++)
4172 rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
4173 for (i = 0; i < 8; i++)
4174 rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
4175 for (i = 0; i < 6; i++)
4176 rtw_write8(adapter, REG_MACID1 + i, macid[i]);
4177 for (i = 0; i < 6; i++)
4178 rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
4179
4180 /* write bcn ctl */
4181 #ifdef CONFIG_BT_COEXIST
4182 /* always enable port0 beacon function for PSTDMA */
4183 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
4184 || IS_HARDWARE_TYPE_8723D(adapter))
4185 bcn_ctrl_1 |= EN_BCN_FUNCTION;
4186 /* always disable port1 beacon function for PSTDMA */
4187 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
4188 bcn_ctrl &= ~EN_BCN_FUNCTION;
4189 #endif
4190 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
4191 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
4192
4193 #if defined(CONFIG_RTL8192F)
4194 /* if the setting of port0 and port1 are the same, it does not need to switch port setting*/
4195 if(((wlan_act_mask_ctrl & en_port_mask) != 0) && ((wlan_act_mask_ctrl & en_port_mask)
4196 != (EN_PORT_0_FUNCTION | EN_PORT_1_FUNCTION)))
4197 wlan_act_mask_ctrl ^= en_port_mask;
4198 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, wlan_act_mask_ctrl);
4199 #endif
4200
4201 if (adapter->iface_id == IFACE_ID0)
4202 iface = dvobj->padapters[IFACE_ID1];
4203 else if (adapter->iface_id == IFACE_ID1)
4204 iface = dvobj->padapters[IFACE_ID0];
4205
4206
4207 if (adapter->hw_port == HW_PORT0) {
4208 adapter->hw_port = HW_PORT1;
4209 iface->hw_port = HW_PORT0;
4210 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4211 ADPT_ARG(iface), ADPT_ARG(adapter));
4212 } else {
4213 adapter->hw_port = HW_PORT0;
4214 iface->hw_port = HW_PORT1;
4215 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
4216 ADPT_ARG(adapter), ADPT_ARG(iface));
4217 }
4218
4219 #ifdef DBG_RUNTIME_PORT_SWITCH
4220 msr = rtw_read8(adapter, MSR);
4221 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
4222 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
4223 #if defined(CONFIG_RTL8192F)
4224 wlan_act_mask_ctrl = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
4225 #endif
4226
4227 for (i = 0; i < 2; i++)
4228 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
4229 for (i = 0; i < 2; i++)
4230 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
4231
4232 for (i = 0; i < 8; i++)
4233 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
4234 for (i = 0; i < 8; i++)
4235 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
4236
4237 for (i = 0; i < 6; i++)
4238 macid[i] = rtw_read8(adapter, REG_MACID + i);
4239
4240 for (i = 0; i < 6; i++)
4241 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
4242
4243 for (i = 0; i < 6; i++)
4244 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
4245
4246 for (i = 0; i < 6; i++)
4247 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
4248
4249 RTW_INFO(FUNC_ADPT_FMT" after switch\n"
4250 "msr:0x%02x\n"
4251 "bcn_ctrl:0x%02x\n"
4252 "bcn_ctrl_1:0x%02x\n"
4253 #if defined(CONFIG_RTL8192F)
4254 "wlan_act_mask_ctrl:0x%02x\n"
4255 #endif
4256 "atimwnd:%u\n"
4257 "atimwnd_1:%u\n"
4258 "tsftr:%llu\n"
4259 "tsftr1:%llu\n"
4260 "macid:"MAC_FMT"\n"
4261 "bssid:"MAC_FMT"\n"
4262 "macid_1:"MAC_FMT"\n"
4263 "bssid_1:"MAC_FMT"\n"
4264 , FUNC_ADPT_ARG(adapter)
4265 , msr
4266 , bcn_ctrl
4267 , bcn_ctrl_1
4268 #if defined(CONFIG_RTL8192F)
4269 , wlan_act_mask_ctrl
4270 #endif
4271 , *((u16 *)atimwnd)
4272 , *((u16 *)atimwnd_1)
4273 , *((u64 *)tsftr)
4274 , *((u64 *)tsftr_1)
4275 , MAC_ARG(macid)
4276 , MAC_ARG(bssid)
4277 , MAC_ARG(macid_1)
4278 , MAC_ARG(bssid_1)
4279 );
4280 #endif /* DBG_RUNTIME_PORT_SWITCH */
4281
4282 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
4283 #endif /* CONFIG_CONCURRENT_MODE */
4284 }
4285
4286 const char *const _h2c_msr_role_str[] = {
4287 "RSVD",
4288 "STA",
4289 "AP",
4290 "GC",
4291 "GO",
4292 "TDLS",
4293 "ADHOC",
4294 "MESH",
4295 "INVALID",
4296 };
4297
4298 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_default_port_id_cmd(_adapter * adapter,u8 mac_id)4299 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
4300 {
4301 s32 ret = _SUCCESS;
4302 u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
4303 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4304 u8 port_id = rtw_hal_get_port(adapter);
4305
4306 if ((dvobj->dft.port_id == port_id) && (dvobj->dft.mac_id == mac_id))
4307 return ret;
4308
4309 SET_H2CCMD_DFTPID_PORT_ID(parm, port_id);
4310 SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
4311
4312 RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
4313 RTW_INFO("%s ("ADPT_FMT") port_id :%d, mad_id:%d\n",
4314 __func__, ADPT_ARG(adapter), port_id, mac_id);
4315
4316 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
4317 dvobj->dft.port_id = port_id;
4318 dvobj->dft.mac_id = mac_id;
4319
4320 return ret;
4321 }
rtw_set_default_port_id(_adapter * adapter)4322 s32 rtw_set_default_port_id(_adapter *adapter)
4323 {
4324 s32 ret = _SUCCESS;
4325 struct sta_info *psta;
4326 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4327
4328 if (is_client_associated_to_ap(adapter)) {
4329 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
4330 if (psta)
4331 ret = rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
4332 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
4333
4334 } else {
4335 }
4336
4337 return ret;
4338 }
rtw_set_ps_rsvd_page(_adapter * adapter)4339 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
4340 {
4341 s32 ret = _SUCCESS;
4342 u16 media_status_rpt = RT_MEDIA_CONNECT;
4343 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
4344
4345 if (adapter->iface_id == pwrctl->fw_psmode_iface_id)
4346 return ret;
4347
4348 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
4349 (u8 *)&media_status_rpt);
4350
4351 return ret;
4352 }
4353
4354 #if 0
4355 _adapter * _rtw_search_dp_iface(_adapter *adapter)
4356 {
4357 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4358 _adapter *iface;
4359 _adapter *target_iface = NULL;
4360 int i;
4361 u8 sta_num = 0, tdls_num = 0, ap_num = 0, mesh_num = 0, adhoc_num = 0;
4362 u8 p2p_go_num = 0, p2p_gc_num = 0;
4363 _adapter *sta_ifs[8];
4364 _adapter *ap_ifs[8];
4365 _adapter *mesh_ifs[8];
4366 _adapter *gc_ifs[8];
4367 _adapter *go_ifs[8];
4368
4369 for (i = 0; i < dvobj->iface_nums; i++) {
4370 iface = dvobj->padapters[i];
4371
4372 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
4373 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4374 sta_ifs[sta_num++] = iface;
4375
4376 #ifdef CONFIG_TDLS
4377 if (iface->tdlsinfo.link_established == _TRUE)
4378 tdls_num++;
4379 #endif
4380 #ifdef CONFIG_P2P
4381 if (MLME_IS_GC(iface))
4382 gc_ifs[p2p_gc_num++] = iface;
4383 #endif
4384 }
4385 #ifdef CONFIG_AP_MODE
4386 } else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
4387 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4388 ap_ifs[ap_num++] = iface;
4389 #ifdef CONFIG_P2P
4390 if (MLME_IS_GO(iface))
4391 go_ifs[p2p_go_num++] = iface;
4392 #endif
4393 }
4394 #endif
4395 } else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
4396 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4397 ) {
4398 adhoc_num++;
4399
4400 #ifdef CONFIG_RTW_MESH
4401 } else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
4402 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4403 ) {
4404 mesh_ifs[mesh_num++] = iface;
4405 #endif
4406 }
4407 }
4408
4409 if (p2p_gc_num) {
4410 target_iface = gc_ifs[0];
4411 }
4412 else if (sta_num) {
4413 if(sta_num == 1) {
4414 target_iface = sta_ifs[0];
4415 } else if (sta_num >= 2) {
4416 /*TODO get target_iface by timestamp*/
4417 target_iface = sta_ifs[0];
4418 }
4419 } else if (ap_num) {
4420 target_iface = ap_ifs[0];
4421 }
4422
4423 RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", sta_num);
4424 RTW_INFO("[IFS_ASSOC_STATUS] - TDLS :%d", tdls_num);
4425 RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", ap_num);
4426 RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", mesh_num);
4427 RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", adhoc_num);
4428 RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", p2p_gc_num);
4429 RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", p2p_go_num);
4430
4431 if (target_iface)
4432 RTW_INFO("%s => target_iface ("ADPT_FMT")\n",
4433 __func__, ADPT_ARG(target_iface));
4434 else
4435 RTW_INFO("%s => target_iface NULL\n", __func__);
4436
4437 return target_iface;
4438 }
4439
4440 void rtw_search_default_port(_adapter *adapter)
4441 {
4442 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4443 _adapter *adp_iface = NULL;
4444 #ifdef CONFIG_WOWLAN
4445 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
4446
4447 if (pwrpriv->wowlan_mode == _TRUE) {
4448 adp_iface = adapter;
4449 goto exit;
4450 }
4451 #endif
4452 adp_iface = _rtw_search_dp_iface(adapter);
4453
4454 exit :
4455 if ((adp_iface != NULL) && (MLME_IS_STA(adp_iface)))
4456 rtw_set_default_port_id(adp_iface);
4457 else
4458 rtw_hal_set_default_port_id_cmd(adapter, 0);
4459
4460 if (1) {
4461 _adapter *tmp_adp;
4462
4463 tmp_adp = (adp_iface) ? adp_iface : adapter;
4464
4465 RTW_INFO("%s ("ADPT_FMT")=> hw_port :%d, default_port(%d)\n",
4466 __func__, ADPT_ARG(adapter), get_hw_port(tmp_adp), get_dft_portid(tmp_adp));
4467 }
4468 }
4469 #endif
4470 #endif /*CONFIG_FW_MULTI_PORT_SUPPORT*/
4471
4472 #ifdef CONFIG_P2P_PS
4473 #ifdef RTW_HALMAC
rtw_set_p2p_ps_offload_cmd(_adapter * adapter,u8 p2p_ps_state)4474 void rtw_set_p2p_ps_offload_cmd(_adapter *adapter, u8 p2p_ps_state)
4475 {
4476 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4477 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4478 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4479 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4480 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
4481 struct sta_priv *pstapriv = &adapter->stapriv;
4482 struct sta_info *psta;
4483 HAL_P2P_PS_PARA p2p_ps_para;
4484 int status = -1;
4485 u8 i;
4486 u8 hw_port = rtw_hal_get_port(adapter);
4487
4488 _rtw_memset(&p2p_ps_para, 0, sizeof(HAL_P2P_PS_PARA));
4489 _rtw_memcpy((&p2p_ps_para) , &hal->p2p_ps_offload , sizeof(hal->p2p_ps_offload));
4490
4491 (&p2p_ps_para)->p2p_port_id = hw_port;
4492 (&p2p_ps_para)->p2p_group = 0;
4493 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
4494 if (psta) {
4495 (&p2p_ps_para)->p2p_macid = psta->cmn.mac_id;
4496 } else {
4497 if (p2p_ps_state != P2P_PS_DISABLE) {
4498 RTW_ERR("%s , psta was NULL\n", __func__);
4499 return;
4500 }
4501 }
4502
4503
4504 switch (p2p_ps_state) {
4505 case P2P_PS_DISABLE:
4506 RTW_INFO("P2P_PS_DISABLE\n");
4507 _rtw_memset(&p2p_ps_para , 0, sizeof(HAL_P2P_PS_PARA));
4508 break;
4509
4510 case P2P_PS_ENABLE:
4511 RTW_INFO("P2P_PS_ENABLE\n");
4512 /* update CTWindow value. */
4513 if (pwdinfo->ctwindow > 0) {
4514 (&p2p_ps_para)->ctwindow_en = 1;
4515 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4516 /*RTW_INFO("%s , ctwindow_length = %d\n" , __func__ , (&p2p_ps_para)->ctwindow_length);*/
4517 }
4518
4519
4520 if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
4521 (&p2p_ps_para)->offload_en = 1;
4522 if (pwdinfo->role == P2P_ROLE_GO) {
4523 (&p2p_ps_para)->role = 1;
4524 (&p2p_ps_para)->all_sta_sleep = 0;
4525 } else
4526 (&p2p_ps_para)->role = 0;
4527
4528 (&p2p_ps_para)->discovery = 0;
4529 }
4530 /* hw only support 2 set of NoA */
4531 for (i = 0; i < pwdinfo->noa_num; i++) {
4532 /* To control the register setting for which NOA */
4533 (&p2p_ps_para)->noa_sel = i;
4534 (&p2p_ps_para)->noa_en = 1;
4535 (&p2p_ps_para)->disable_close_rf = 0;
4536 #ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
4537 #ifdef CONFIG_CONCURRENT_MODE
4538 if (rtw_mi_buddy_check_fwstate(adapter, WIFI_ASOC_STATE))
4539 #endif /* CONFIG_CONCURRENT_MODE */
4540 (&p2p_ps_para)->disable_close_rf = 1;
4541 #endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
4542 /* config P2P NoA Descriptor Register */
4543 /* config NOA duration */
4544 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[i];
4545 /* config NOA interval */
4546 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[i];
4547 /* config NOA start time */
4548 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[i];
4549 /* config NOA count */
4550 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[i];
4551 /*RTW_INFO("%s , noa_duration_para = %d , noa_interval_para = %d , noa_start_time_para = %d , noa_count_para = %d\n" , __func__ ,
4552 (&p2p_ps_para)->noa_duration_para , (&p2p_ps_para)->noa_interval_para ,
4553 (&p2p_ps_para)->noa_start_time_para , (&p2p_ps_para)->noa_count_para);*/
4554 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4555 if (status == -1)
4556 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4557 }
4558
4559 break;
4560
4561 case P2P_PS_SCAN:
4562 /*This feature FW not ready 20161116 YiWei*/
4563 return;
4564 /*
4565 RTW_INFO("P2P_PS_SCAN\n");
4566 (&p2p_ps_para)->discovery = 1;
4567 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4568 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4569 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4570 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4571 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4572 */
4573 break;
4574
4575 case P2P_PS_SCAN_DONE:
4576 /*This feature FW not ready 20161116 YiWei*/
4577 return;
4578 /*
4579 RTW_INFO("P2P_PS_SCAN_DONE\n");
4580 (&p2p_ps_para)->discovery = 0;
4581 pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
4582 (&p2p_ps_para)->ctwindow_length = pwdinfo->ctwindow;
4583 (&p2p_ps_para)->noa_duration_para = pwdinfo->noa_duration[0];
4584 (&p2p_ps_para)->noa_interval_para = pwdinfo->noa_interval[0];
4585 (&p2p_ps_para)->noa_start_time_para = pwdinfo->noa_start_time[0];
4586 (&p2p_ps_para)->noa_count_para = pwdinfo->noa_count[0];
4587 */
4588 break;
4589
4590 default:
4591 break;
4592 }
4593
4594 if (p2p_ps_state != P2P_PS_ENABLE || (&p2p_ps_para)->noa_en == 0) {
4595 status = rtw_halmac_p2pps(adapter_to_dvobj(adapter) , (&p2p_ps_para));
4596 if (status == -1)
4597 RTW_ERR("%s , rtw_halmac_p2pps fail\n", __func__);
4598 }
4599 _rtw_memcpy(&hal->p2p_ps_offload , (&p2p_ps_para) , sizeof(hal->p2p_ps_offload));
4600
4601 }
4602 #endif /* RTW_HALMAC */
4603 #endif /* CONFIG_P2P */
4604
4605 #if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR)
_rtw_hal_dtp_macid_set(_adapter * padapter,u8 opmode,u8 mac_id)4606 static void _rtw_hal_dtp_macid_set(
4607 _adapter *padapter, u8 opmode, u8 mac_id)
4608 {
4609 struct macid_ctl_t *macid_ctl = &(padapter->dvobj->macid_ctl);
4610 struct sta_info *psta;
4611 u8 h2c_cmd[H2C_FW_CRC5_SEARCH_LEN] = {0};
4612 u8 mac_addr[ETH_ALEN] = {0};
4613
4614 if (opmode) {
4615 psta = macid_ctl->sta[mac_id];
4616 if (psta)
4617 _rtw_memcpy(mac_addr, psta->cmn.mac_addr, ETH_ALEN);
4618
4619 if (rtw_check_invalid_mac_address(mac_addr, _FALSE))
4620 return;
4621 }
4622 /* else DON'T CARE H2C_FW_CRC5_SEARCH mac addr in disconnected case */
4623
4624 if (rtw_get_chip_type(padapter) == RTL8822C) {
4625 SET_H2CCMD_FW_CRC5_SEARCH_EN(h2c_cmd, opmode);
4626 SET_H2CCMD_FW_CRC5_SEARCH_MACID(h2c_cmd, mac_id);
4627 SET_H2CCMD_FW_CRC5_SEARCH_MAC(&h2c_cmd[1], mac_addr);
4628 if (rtw_hal_fill_h2c_cmd(padapter, H2C_FW_CRC5_SEARCH,
4629 H2C_FW_CRC5_SEARCH_LEN, h2c_cmd) != _SUCCESS)
4630 RTW_WARN("%s : set h2c - 0x%02x fail!\n", __func__, H2C_FW_CRC5_SEARCH);
4631 }
4632 }
4633
rtw_hal_dtp_macid_set(_adapter * padapter,u8 opmode,bool macid_ind,u8 mac_id,u8 macid_end)4634 static void rtw_hal_dtp_macid_set(_adapter *padapter, u8 opmode,
4635 bool macid_ind, u8 mac_id, u8 macid_end)
4636 {
4637 int i;
4638
4639 if (macid_ind == 0) {
4640 _rtw_hal_dtp_macid_set(padapter, opmode, mac_id);
4641 } else {
4642 for (i = mac_id; i <= macid_end; i++)
4643 _rtw_hal_dtp_macid_set(padapter, opmode, i);
4644 }
4645 }
4646 #endif
4647
4648 /*
4649 * rtw_hal_set_FwMediaStatusRpt_cmd -
4650 *
4651 * @adapter:
4652 * @opmode: 0:disconnect, 1:connect
4653 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
4654 * @miracast_sink: 0:source. 1:sink
4655 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
4656 * @macid:
4657 * @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end
4658 * @macid_end:
4659 */
rtw_hal_set_FwMediaStatusRpt_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,bool macid_ind,u8 macid_end)4660 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)
4661 {
4662 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
4663 u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
4664 int i;
4665 s32 ret;
4666 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4667 u8 hw_port = rtw_hal_get_port(adapter);
4668 #endif
4669 u8 op_num_change_bmp = 0;
4670
4671 #if defined(CONFIG_RTL8822C) && defined(CONFIG_SUPPORT_DYNAMIC_TXPWR)
4672 rtw_hal_dtp_macid_set(adapter, opmode, macid_ind, macid, macid_end);
4673 #endif
4674
4675 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
4676 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
4677 SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
4678 SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
4679 SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
4680 SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
4681 SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
4682 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
4683 SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, hw_port);
4684 #endif
4685 RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
4686
4687 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
4688 if (ret != _SUCCESS)
4689 goto exit;
4690
4691 #if defined(CONFIG_RTL8188E)
4692 if (rtw_get_chip_type(adapter) == RTL8188E) {
4693 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
4694
4695 /* 8188E FW doesn't set macid no link, driver does it by self */
4696 if (opmode)
4697 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
4698 else
4699 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
4700
4701 /* for 8188E RA */
4702 #if (RATE_ADAPTIVE_SUPPORT == 1)
4703 if (hal_data->fw_ractrl == _FALSE) {
4704 u8 max_macid;
4705
4706 max_macid = rtw_search_max_mac_id(adapter);
4707 rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
4708 }
4709 #endif
4710 }
4711 #endif
4712
4713 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
4714 /* TODO: this should move to IOT issue area */
4715 if (rtw_get_chip_type(adapter) == RTL8812
4716 || rtw_get_chip_type(adapter) == RTL8821
4717 ) {
4718 if (MLME_IS_STA(adapter))
4719 Hal_PatchwithJaguar_8812(adapter, opmode);
4720 }
4721 #endif
4722
4723 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
4724 if (macid_ind == 0)
4725 macid_end = macid;
4726
4727 for (i = macid; macid <= macid_end; macid++) {
4728 op_num_change_bmp |= rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
4729 if (!opmode) {
4730 rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
4731 rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
4732 rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
4733 rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
4734 }
4735 }
4736
4737 #if CONFIG_TX_AC_LIFETIME
4738 if (op_num_change_bmp)
4739 rtw_hal_update_tx_aclt(adapter);
4740 #endif
4741
4742 if (!opmode)
4743 rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
4744
4745 exit:
4746 return ret;
4747 }
4748
rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid)4749 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
4750 {
4751 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
4752 }
4753
rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter * adapter,bool opmode,bool miracast,bool miracast_sink,u8 role,u8 macid,u8 macid_end)4754 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
4755 {
4756 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
4757 }
4758
rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4759 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4760 {
4761 u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
4762 u8 ret = 0;
4763
4764 RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
4765 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
4766 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
4767 rsvdpageloc->LocBTQosNull);
4768
4769 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
4770 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
4771 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
4772 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
4773 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
4774
4775 ret = rtw_hal_fill_h2c_cmd(padapter,
4776 H2C_RSVD_PAGE,
4777 H2C_RSVDPAGE_LOC_LEN,
4778 u1H2CRsvdPageParm);
4779
4780 }
4781
4782 #ifdef CONFIG_GPIO_WAKEUP
rtw_hal_switch_gpio_wl_ctrl(_adapter * padapter,u8 index,u8 enable)4783 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
4784 {
4785 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4786
4787 if (IS_8723D_SERIES(pHalData->version_id) || IS_8192F_SERIES(pHalData->version_id)
4788 || IS_8822B_SERIES(pHalData->version_id) || IS_8821C_SERIES(pHalData->version_id)
4789 || IS_8822C_SERIES(pHalData->version_id))
4790 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4791 /*
4792 * Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
4793 * It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
4794 * and implement HAL function.
4795 * TODO: GPIO_8 multi function?
4796 */
4797
4798 if ((index == 13 || index == 14)
4799 #if defined(CONFIG_RTL8821A) && defined(CONFIG_SDIO_HCI)
4800 /* 8821A's LED2 circuit(used by HW_LED strategy) needs enable WL GPIO control of GPIO[14:13], can't disable */
4801 && (!IS_HW_LED_STRATEGY(rtw_led_get_strategy(padapter)) || enable)
4802 #endif
4803 )
4804 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
4805 }
4806
rtw_hal_set_output_gpio(_adapter * padapter,u8 index,u8 outputval)4807 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
4808 {
4809 #if defined(CONFIG_RTL8192F)
4810 rtw_hal_set_hwreg(padapter, HW_VAR_WOW_OUTPUT_GPIO, (u8 *)(&outputval));
4811 #else
4812 if (index <= 7) {
4813 /* config GPIO mode */
4814 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4815 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4816
4817 /* config GPIO Sel */
4818 /* 0: input */
4819 /* 1: output */
4820 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4821 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
4822
4823 /* set output value */
4824 if (outputval) {
4825 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4826 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
4827 } else {
4828 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
4829 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
4830 }
4831 } else if (index <= 15) {
4832 /* 88C Series: */
4833 /* index: 11~8 transform to 3~0 */
4834 /* 8723 Series: */
4835 /* index: 12~8 transform to 4~0 */
4836
4837 index -= 8;
4838
4839 /* config GPIO mode */
4840 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4841 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4842
4843 /* config GPIO Sel */
4844 /* 0: input */
4845 /* 1: output */
4846 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4847 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
4848
4849 /* set output value */
4850 if (outputval) {
4851 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4852 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
4853 } else {
4854 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
4855 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
4856 }
4857 } else {
4858 RTW_INFO("%s: invalid GPIO%d=%d\n",
4859 __FUNCTION__, index, outputval);
4860 }
4861 #endif
4862 }
rtw_hal_set_input_gpio(_adapter * padapter,u8 index)4863 void rtw_hal_set_input_gpio(_adapter *padapter, u8 index)
4864 {
4865 #if defined(CONFIG_RTL8192F)
4866 rtw_hal_set_hwreg(padapter, HW_VAR_WOW_INPUT_GPIO, (u8 *)(&index));
4867 #else
4868 if (index <= 7) {
4869 /* config GPIO mode */
4870 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
4871 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
4872
4873 /* config GPIO Sel */
4874 /* 0: input */
4875 /* 1: output */
4876 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
4877 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) & ~BIT(index));
4878
4879 } else if (index <= 15) {
4880 /* 88C Series: */
4881 /* index: 11~8 transform to 3~0 */
4882 /* 8723 Series: */
4883 /* index: 12~8 transform to 4~0 */
4884
4885 index -= 8;
4886
4887 /* config GPIO mode */
4888 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
4889 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
4890
4891 /* config GPIO Sel */
4892 /* 0: input */
4893 /* 1: output */
4894 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
4895 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) & ~BIT(index));
4896 } else
4897 RTW_INFO("%s: invalid GPIO%d\n", __func__, index);
4898 #endif
4899 }
4900
4901 #endif
4902
rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4903 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4904 {
4905 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
4906 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4907 u8 ret = 0;
4908 #ifdef CONFIG_WOWLAN
4909 u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
4910
4911 RTW_INFO("%s: RWC: %d ArpRsp: %d NbrAdv: %d LocNDPInfo: %d\n",
4912 __func__, rsvdpageloc->LocRemoteCtrlInfo,
4913 rsvdpageloc->LocArpRsp, rsvdpageloc->LocNbrAdv,
4914 rsvdpageloc->LocNDPInfo);
4915 RTW_INFO("%s:GtkRsp: %d GtkInfo: %d ProbeReq: %d NetworkList: %d\n",
4916 __func__, rsvdpageloc->LocGTKRsp, rsvdpageloc->LocGTKInfo,
4917 rsvdpageloc->LocProbeReq, rsvdpageloc->LocNetList);
4918
4919 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
4920 SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
4921 SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
4922 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm,
4923 rsvdpageloc->LocNbrAdv);
4924 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NDP_INFO(u1H2CAoacRsvdPageParm,
4925 rsvdpageloc->LocNDPInfo);
4926 #ifdef CONFIG_GTK_OL
4927 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
4928 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
4929 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
4930 #endif /* CONFIG_GTK_OL */
4931 ret = rtw_hal_fill_h2c_cmd(padapter,
4932 H2C_AOAC_RSVD_PAGE,
4933 H2C_AOAC_RSVDPAGE_LOC_LEN,
4934 u1H2CAoacRsvdPageParm);
4935
4936 RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
4937 _rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
4938 SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
4939 rsvdpageloc->LocAOACReport);
4940 ret = rtw_hal_fill_h2c_cmd(padapter,
4941 H2C_AOAC_RSVDPAGE3,
4942 H2C_AOAC_RSVDPAGE_LOC_LEN,
4943 u1H2CAoacRsvdPageParm);
4944 pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
4945 }
4946 #if defined(CONFIG_PNO_SUPPORT) && !defined(RTW_HALMAC)
4947 else {
4948
4949 if (!pwrpriv->wowlan_in_resume) {
4950 RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
4951 _rtw_memset(&u1H2CAoacRsvdPageParm, 0,
4952 sizeof(u1H2CAoacRsvdPageParm));
4953 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
4954 rsvdpageloc->LocPNOInfo);
4955 ret = rtw_hal_fill_h2c_cmd(padapter,
4956 H2C_AOAC_RSVDPAGE3,
4957 H2C_AOAC_RSVDPAGE_LOC_LEN,
4958 u1H2CAoacRsvdPageParm);
4959 }
4960 }
4961 #endif /* defined(CONFIG_PNO_SUPPORT) && !defined(RTW_HALMAC) */
4962 #endif /* CONFIG_WOWLAN */
4963 }
4964
4965 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)4966 void rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
4967 {
4968 struct hal_ops *pHalFunc = &padapter->hal_func;
4969 u8 u1H2C_fw_dbg_msg_pkt_parm[H2C_FW_DBG_MSG_PKT_LEN] = {0};
4970 u8 ret = 0;
4971
4972
4973 RTW_INFO("RsvdPageLoc: loc_fw_dbg_msg_pkt =%d\n", rsvdpageloc->loc_fw_dbg_msg_pkt);
4974
4975 SET_H2CCMD_FW_DBG_MSG_PKT_EN(u1H2C_fw_dbg_msg_pkt_parm, 1);
4976 SET_H2CCMD_RSVDPAGE_LOC_FW_DBG_MSG_PKT(u1H2C_fw_dbg_msg_pkt_parm, rsvdpageloc->loc_fw_dbg_msg_pkt);
4977 ret = rtw_hal_fill_h2c_cmd(padapter,
4978 H2C_FW_DBG_MSG_PKT,
4979 H2C_FW_DBG_MSG_PKT_LEN,
4980 u1H2C_fw_dbg_msg_pkt_parm);
4981
4982 }
4983 #endif /*DBG_FW_DEBUG_MSG_PKT*/
4984
4985 /*#define DBG_GET_RSVD_PAGE*/
rtw_hal_get_rsvd_page(_adapter * adapter,u32 page_offset,u32 page_num,u8 * buffer,u32 buffer_size)4986 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
4987 u32 page_num, u8 *buffer, u32 buffer_size)
4988 {
4989 u32 addr = 0, size = 0, count = 0;
4990 u32 page_size = 0, data_low = 0, data_high = 0;
4991 u16 txbndy = 0, offset = 0;
4992 u8 i = 0;
4993 bool rst = _FALSE;
4994
4995 #ifdef DBG_LA_MODE
4996 struct registry_priv *registry_par = &adapter->registrypriv;
4997
4998 if(registry_par->la_mode_en == 1) {
4999 RTW_INFO("%s LA debug mode can't dump rsvd pg \n", __func__);
5000 return rst;
5001 }
5002 #endif
5003 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5004
5005 addr = page_offset * page_size;
5006 size = page_num * page_size;
5007
5008 if (buffer_size < size) {
5009 RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
5010 __func__, buffer_size, size);
5011 return rst;
5012 }
5013 #ifdef RTW_HALMAC
5014 if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
5015 rst = _FALSE;
5016 else
5017 rst = _TRUE;
5018 #else
5019 txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
5020
5021 offset = (txbndy + page_offset) * page_size / 8;
5022 count = (buffer_size / 8) + 1;
5023
5024 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
5025
5026 for (i = 0 ; i < count ; i++) {
5027 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
5028 data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
5029 data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
5030 _rtw_memcpy(buffer + (i * 8),
5031 &data_low, sizeof(data_low));
5032 _rtw_memcpy(buffer + ((i * 8) + 4),
5033 &data_high, sizeof(data_high));
5034 }
5035 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
5036 rst = _TRUE;
5037 #endif /*RTW_HALMAC*/
5038
5039 #ifdef DBG_GET_RSVD_PAGE
5040 RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
5041 __func__, page_offset, page_num, addr, size);
5042 RTW_INFO_DUMP("\n", buffer, size);
5043 RTW_INFO(" ==================================================\n");
5044 #endif
5045 return rst;
5046 }
5047
rtw_dump_rsvd_page(void * sel,_adapter * adapter,u8 page_offset,u8 page_num)5048 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
5049 {
5050 #if defined(CONFIG_RTW_DEBUG) || defined(CONFIG_PROC_DEBUG)
5051 u32 page_size = 0;
5052 u8 *buffer = NULL;
5053 u32 buf_size = 0;
5054
5055 if (page_num == 0)
5056 return;
5057
5058 RTW_PRINT_SEL(sel, "======= RSVD PAGE DUMP =======\n");
5059 RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
5060
5061 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5062 if (page_size) {
5063 buf_size = page_size * page_num;
5064 buffer = rtw_zvmalloc(buf_size);
5065
5066 if (buffer) {
5067 rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
5068 RTW_DUMP_SEL(sel, buffer, buf_size);
5069 rtw_vmfree(buffer, buf_size);
5070 } else
5071 RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
5072 } else
5073 RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
5074
5075 RTW_PRINT_SEL(sel, "==========================\n");
5076 #endif
5077 }
5078
5079 #ifdef CONFIG_SUPPORT_FIFO_DUMP
rtw_dump_fifo(void * sel,_adapter * adapter,u8 fifo_sel,u32 fifo_addr,u32 fifo_size)5080 void rtw_dump_fifo(void *sel, _adapter *adapter, u8 fifo_sel, u32 fifo_addr, u32 fifo_size)
5081 {
5082 u8 *buffer = NULL;
5083 u32 buff_size = 0;
5084 static const char * const fifo_sel_str[] = {
5085 "TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
5086 };
5087
5088 if (fifo_sel > 5) {
5089 RTW_ERR("fifo_sel:%d invalid\n", fifo_sel);
5090 return;
5091 }
5092
5093 RTW_PRINT_SEL(sel, "========= FIFO DUMP =========\n");
5094 RTW_PRINT_SEL(sel, "%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[fifo_sel], fifo_addr, fifo_size);
5095
5096 if (fifo_size) {
5097 buff_size = RND4(fifo_size);
5098 buffer = rtw_zvmalloc(buff_size);
5099 if (buffer == NULL)
5100 buff_size = 0;
5101 }
5102
5103 rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), fifo_sel, fifo_addr, buff_size, buffer);
5104
5105 if (buffer) {
5106 RTW_DUMP_SEL(sel, buffer, fifo_size);
5107 rtw_vmfree(buffer, buff_size);
5108 }
5109
5110 RTW_PRINT_SEL(sel, "==========================\n");
5111 }
5112 #endif
5113
5114 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
rtw_hal_force_enable_rxdma(_adapter * adapter)5115 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
5116 {
5117 RTW_INFO("%s: Set 0x690=0x00\n", __func__);
5118 rtw_write8(adapter, REG_WOW_CTRL,
5119 (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
5120 RTW_PRINT("%s: Release RXDMA\n", __func__);
5121 rtw_write32(adapter, REG_RXPKT_NUM,
5122 (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
5123 }
5124 #if defined(CONFIG_RTL8188E)
rtw_hal_disable_tx_report(_adapter * adapter)5125 static void rtw_hal_disable_tx_report(_adapter *adapter)
5126 {
5127 rtw_write8(adapter, REG_TX_RPT_CTRL,
5128 ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
5129 RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5130 }
5131
rtw_hal_enable_tx_report(_adapter * adapter)5132 static void rtw_hal_enable_tx_report(_adapter *adapter)
5133 {
5134 rtw_write8(adapter, REG_TX_RPT_CTRL,
5135 ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
5136 RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
5137 }
5138 #endif
rtw_hal_release_rx_dma(_adapter * adapter)5139 static void rtw_hal_release_rx_dma(_adapter *adapter)
5140 {
5141 u32 val32 = 0;
5142
5143 val32 = rtw_read32(adapter, REG_RXPKT_NUM);
5144
5145 rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
5146
5147 RTW_INFO("%s, [0x%04x]: 0x%08x\n",
5148 __func__, REG_RXPKT_NUM, (u32)(val32 & (~RW_RELEASE_EN)));
5149 }
5150
rtw_hal_pause_rx_dma(_adapter * adapter)5151 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
5152 {
5153 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
5154 u8 ret = 0;
5155 s8 trycnt = 100;
5156 u32 tmp = 0;
5157 int res = 0;
5158 /* RX DMA stop */
5159 RTW_PRINT("Pause DMA\n");
5160 rtw_write32(adapter, REG_RXPKT_NUM,
5161 (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
5162 do {
5163 if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
5164 #ifdef CONFIG_USB_HCI
5165 /* stop interface before leave */
5166 if (_TRUE == hal->usb_intf_start) {
5167 rtw_intf_stop(adapter);
5168 RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
5169 RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
5170 }
5171 #endif /* CONFIG_USB_HCI */
5172
5173 RTW_PRINT("RX_DMA_IDLE is true\n");
5174 ret = _SUCCESS;
5175 break;
5176 }
5177 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5178 else {
5179 res = RecvOnePkt(adapter);
5180 RTW_PRINT("RecvOnePkt Result: %d\n", res);
5181 }
5182 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
5183
5184 #ifdef CONFIG_USB_HCI
5185 else {
5186 /* to avoid interface start repeatedly */
5187 if (_FALSE == hal->usb_intf_start)
5188 rtw_intf_start(adapter);
5189 }
5190 #endif /* CONFIG_USB_HCI */
5191 } while (trycnt--);
5192
5193 if (trycnt < 0) {
5194 tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
5195
5196 RTW_PRINT("Stop RX DMA failed......\n");
5197 #if defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8814B)
5198 RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
5199 __func__, rtw_read16(adapter, REG_RXPKTNUM));
5200 #else
5201 RTW_PRINT("%s, RXPKT_NUM: 0x%02x\n",
5202 __func__, ((tmp & 0xFF00) >> 8));
5203 #endif
5204 if (tmp & BIT(3))
5205 RTW_PRINT("%s, RX DMA has req\n",
5206 __func__);
5207 else
5208 RTW_PRINT("%s, RX DMA no req\n",
5209 __func__);
5210 ret = _FAIL;
5211 }
5212
5213 return ret;
5214 }
5215
5216 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5217 #ifndef RTW_HALMAC
rtw_hal_enable_cpwm2(_adapter * adapter)5218 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
5219 {
5220 u8 ret = 0;
5221 int res = 0;
5222 u32 tmp = 0;
5223 #ifdef CONFIG_GPIO_WAKEUP
5224 return _SUCCESS;
5225 #else
5226 RTW_PRINT("%s\n", __func__);
5227
5228 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5229 if (!res)
5230 RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
5231 else
5232 RTW_INFO("sdio_local_read fail\n");
5233
5234 tmp = SDIO_HIMR_CPWM2_MSK;
5235
5236 res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5237
5238 if (!res) {
5239 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
5240 RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
5241 ret = _SUCCESS;
5242 } else {
5243 RTW_INFO("sdio_local_write fail\n");
5244 ret = _FAIL;
5245 }
5246 return ret;
5247 #endif /* CONFIG_CPIO_WAKEUP */
5248 }
5249 #endif
5250 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
5251 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
5252
5253 #ifdef CONFIG_WOWLAN
5254 /*
5255 * rtw_hal_check_wow_ctrl
5256 * chk_type: _TRUE means to check enable, if 0x690 & bit1 (for 8051), WOW enable successful.
5257 * If 0x1C7 == 0 (for 3081), WOW enable successful.
5258 * _FALSE means to check disable, if 0x690 & bit1 (for 8051), WOW disable fail.
5259 * If 0x120 & bit16 || 0x284 & bit18 (for 3081), WOW disable fail.
5260 */
rtw_hal_check_wow_ctrl(_adapter * adapter,u8 chk_type)5261 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
5262 {
5263 u32 fe1_imr = 0xFF, rxpkt_num = 0xFF;
5264 u8 mstatus = 0;
5265 u8 reason = 0xFF;
5266 u8 trycnt = 25;
5267 u8 res = _FALSE;
5268
5269 if (IS_HARDWARE_TYPE_JAGUAR2(adapter) || IS_HARDWARE_TYPE_JAGUAR3(adapter)) {
5270 if (chk_type) {
5271 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5272 RTW_INFO("%s reason:0x%02x\n", __func__, reason);
5273
5274 while (reason && trycnt > 1) {
5275 reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
5276 RTW_PRINT("Loop index: %d :0x%02x\n",
5277 trycnt, reason);
5278 trycnt--;
5279 rtw_msleep_os(20);
5280 }
5281 if (!reason)
5282 res = _TRUE;
5283 else
5284 res = _FALSE;
5285 } else {
5286 /* Wait FW to cleare 0x120 bit16, 0x284 bit18 to 0 */
5287 fe1_imr = rtw_read32(adapter, REG_FE1IMR); /* RxDone IMR for 3081 */
5288 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM); /* Release RXDMA */
5289 RTW_PRINT("%s REG_FE1IMR (reg120): 0x%x, REG_RXPKT_NUM(reg284): 0x%x\n", __func__, fe1_imr, rxpkt_num);
5290
5291 while (((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN)) && trycnt > 1) {
5292 rtw_msleep_os(20);
5293 fe1_imr = rtw_read32(adapter, REG_FE1IMR);
5294 rxpkt_num = rtw_read32(adapter, REG_RXPKT_NUM);
5295 RTW_PRINT("Loop index: %d :0x%x, 0x%x\n",
5296 trycnt, fe1_imr, rxpkt_num);
5297 trycnt--;
5298 }
5299
5300 if ((fe1_imr & BIT_FS_RXDONE_INT_EN) || (rxpkt_num & BIT_RW_RELEASE_EN))
5301 res = _FALSE;
5302 else
5303 res = _TRUE;
5304 }
5305 } else {
5306 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5307 RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
5308
5309
5310 if (chk_type) {
5311 while (!(mstatus & BIT1) && trycnt > 1) {
5312 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5313 RTW_PRINT("Loop index: %d :0x%02x\n",
5314 trycnt, mstatus);
5315 trycnt--;
5316 rtw_msleep_os(20);
5317 }
5318 if (mstatus & BIT1)
5319 res = _TRUE;
5320 else
5321 res = _FALSE;
5322 } else {
5323 while (mstatus & BIT1 && trycnt > 1) {
5324 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
5325 RTW_PRINT("Loop index: %d :0x%02x\n",
5326 trycnt, mstatus);
5327 trycnt--;
5328 rtw_msleep_os(20);
5329 }
5330
5331 if (mstatus & BIT1)
5332 res = _FALSE;
5333 else
5334 res = _TRUE;
5335 }
5336 }
5337
5338 RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
5339 __func__, chk_type, res, (25 - trycnt));
5340 return res;
5341 }
5342
5343 #if defined(CONFIG_PNO_SUPPORT) && !defined(RTW_HALMAC)
rtw_hal_check_pno_enabled(_adapter * adapter)5344 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
5345 {
5346 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5347 u8 res = 0, count = 0;
5348 u8 ret = _FALSE;
5349
5350 if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
5351 res = rtw_read8(adapter, REG_PNO_STATUS);
5352 while (!(res & BIT(7)) && count < 25) {
5353 RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
5354 count, res);
5355 res = rtw_read8(adapter, REG_PNO_STATUS);
5356 count++;
5357 rtw_msleep_os(2);
5358 }
5359 if (res & BIT(7))
5360 ret = _TRUE;
5361 else
5362 ret = _FALSE;
5363 RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
5364 }
5365 return ret;
5366 }
5367 #endif
5368
rtw_hal_backup_rate(_adapter * adapter)5369 static void rtw_hal_backup_rate(_adapter *adapter)
5370 {
5371 RTW_INFO("%s\n", __func__);
5372 /* backup data rate to register 0x8b for wowlan FW */
5373 rtw_write8(adapter, 0x8d, 1);
5374 rtw_write8(adapter, 0x8c, 0);
5375 rtw_write8(adapter, 0x8f, 0x40);
5376 rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
5377 }
5378
5379 #ifdef CONFIG_GTK_OL
rtw_hal_fw_sync_cam_id(_adapter * adapter)5380 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
5381 {
5382 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5383 int cam_id, index = 0;
5384 u8 *addr = NULL;
5385
5386 if (!MLME_IS_STA(adapter))
5387 return;
5388
5389 addr = get_bssid(pmlmepriv);
5390
5391 if (addr == NULL) {
5392 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
5393 return;
5394 }
5395
5396 rtw_clean_dk_section(adapter);
5397
5398 do {
5399 cam_id = rtw_camid_search(adapter, addr, index, 1);
5400
5401 if (cam_id == -1)
5402 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
5403 else
5404 rtw_sec_cam_swap(adapter, cam_id, index);
5405
5406 index++;
5407 } while (index < 4);
5408
5409 rtw_write8(adapter, REG_SECCFG, 0xcc);
5410 }
5411
rtw_hal_update_gtk_offload_info(_adapter * adapter)5412 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
5413 {
5414 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5415 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5416 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
5417 struct security_priv *psecuritypriv = &adapter->securitypriv;
5418 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
5419 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
5420 _irqL irqL;
5421 u8 get_key[16];
5422 u8 gtk_id = 0, offset = 0, i = 0, sz = 0, aoac_rpt_ver = 0, has_rekey = _FALSE;
5423 u64 replay_count = 0, tmp_iv_hdr = 0, pkt_pn = 0;
5424
5425 if (!MLME_IS_STA(adapter))
5426 return;
5427
5428 _rtw_memset(get_key, 0, sizeof(get_key));
5429 _rtw_memcpy(&replay_count,
5430 paoac_rpt->replay_counter_eapol_key, 8);
5431
5432 /*read gtk key index*/
5433 gtk_id = paoac_rpt->key_index;
5434 aoac_rpt_ver = paoac_rpt->version_info;
5435
5436 if (aoac_rpt_ver == 0) {
5437 /* initial verison */
5438 if (gtk_id == 5)
5439 has_rekey = _FALSE;
5440 else
5441 has_rekey = _TRUE;
5442 } else if (aoac_rpt_ver >= 1) {
5443 /* Add krack patch */
5444 if (gtk_id == 5)
5445 RTW_WARN("%s FW check iv fail\n", __func__);
5446
5447 if (aoac_rpt_ver == 1)
5448 RTW_WARN("%s aoac report version should be update to v2\n", __func__);
5449
5450 /* Fix key id mismatch */
5451 if (aoac_rpt_ver == 2)
5452 has_rekey = paoac_rpt->rekey_ok == 1 ? _TRUE : _FALSE;
5453 }
5454
5455 if (has_rekey == _FALSE) {
5456 RTW_INFO("%s no rekey event happened.\n", __func__);
5457 } else if (has_rekey == _TRUE) {
5458 RTW_INFO("%s update security key.\n", __func__);
5459 /*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
5460 rtw_sec_read_cam_ent(adapter, gtk_id,
5461 NULL, NULL, get_key);
5462 rtw_clean_hw_dk_cam(adapter);
5463
5464 if (_rtw_camid_is_gk(adapter, gtk_id)) {
5465 _enter_critical_bh(&cam_ctl->lock, &irqL);
5466 _rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
5467 get_key, 16);
5468 _exit_critical_bh(&cam_ctl->lock, &irqL);
5469 } else {
5470 struct setkey_parm parm_gtk;
5471
5472 parm_gtk.algorithm = paoac_rpt->security_type;
5473 parm_gtk.keyid = gtk_id;
5474 _rtw_memcpy(parm_gtk.key, get_key, 16);
5475 setkey_hdl(adapter, (u8 *)&parm_gtk);
5476 }
5477
5478 /*update key into related sw variable and sec-cam cache*/
5479 psecuritypriv->dot118021XGrpKeyid = gtk_id;
5480 _rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
5481 get_key, 16);
5482 /* update SW TKIP TX/RX MIC value */
5483 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
5484 offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
5485 _rtw_memcpy(
5486 &psecuritypriv->dot118021XGrptxmickey[gtk_id],
5487 &(paoac_rpt->group_key[offset]),
5488 RTW_TKIP_MIC_LEN);
5489
5490 offset = RTW_KEK_LEN;
5491 _rtw_memcpy(
5492 &psecuritypriv->dot118021XGrprxmickey[gtk_id],
5493 &(paoac_rpt->group_key[offset]),
5494 RTW_TKIP_MIC_LEN);
5495 }
5496 RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
5497 KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
5498 }
5499
5500 /* Update broadcast RX IV */
5501 if (psecuritypriv->dot118021XGrpPrivacy == _AES_) {
5502 sz = sizeof(psecuritypriv->iv_seq[0]);
5503 for (i = 0 ; i < 4 ; i++) {
5504 _rtw_memcpy(&tmp_iv_hdr, paoac_rpt->rxgtk_iv[i], sz);
5505 tmp_iv_hdr = le64_to_cpu(tmp_iv_hdr);
5506 pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
5507 _rtw_memcpy(psecuritypriv->iv_seq[i], &pkt_pn, sz);
5508 }
5509 }
5510
5511 rtw_clean_dk_section(adapter);
5512
5513 rtw_write8(adapter, REG_SECCFG, 0x0c);
5514
5515 #ifdef CONFIG_GTK_OL_DBG
5516 /* if (gtk_keyindex != 5) */
5517 dump_sec_cam(RTW_DBGDUMP, adapter);
5518 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
5519 #endif
5520 }
5521 #endif /*CONFIG_GTK_OL*/
5522
rtw_dump_aoac_rpt(_adapter * adapter)5523 static void rtw_dump_aoac_rpt(_adapter *adapter)
5524 {
5525 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5526 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5527 int i = 0;
5528
5529 RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
5530 RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
5531 paoac_rpt->replay_counter_eapol_key, 8);
5532 RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
5533 RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
5534 RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
5535 RTW_INFO("[AOAC-RPT] wow_pattern_idx - %d\n",
5536 paoac_rpt->wow_pattern_idx);
5537 RTW_INFO("[AOAC-RPT] version_info - %d\n", paoac_rpt->version_info);
5538 RTW_INFO("[AOAC-RPT] rekey_ok - %d\n", paoac_rpt->rekey_ok);
5539 RTW_INFO_DUMP("[AOAC-RPT] RX PTK IV-", paoac_rpt->rxptk_iv, 8);
5540 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[0] IV-", paoac_rpt->rxgtk_iv[0], 8);
5541 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[1] IV-", paoac_rpt->rxgtk_iv[1], 8);
5542 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[2] IV-", paoac_rpt->rxgtk_iv[2], 8);
5543 RTW_INFO_DUMP("[AOAC-RPT] RX GTK[3] IV-", paoac_rpt->rxgtk_iv[3], 8);
5544 }
5545
rtw_hal_get_aoac_rpt(_adapter * adapter)5546 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
5547 {
5548 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5549 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5550 u32 page_offset = 0, page_number = 0;
5551 u32 page_size = 0, buf_size = 0;
5552 u8 *buffer = NULL;
5553 u8 i = 0, tmp = 0;
5554 int ret = -1;
5555
5556 /* read aoac report from rsvd page */
5557 page_offset = pwrctl->wowlan_aoac_rpt_loc;
5558 page_number = 1;
5559
5560 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
5561 buf_size = page_size * page_number;
5562
5563 buffer = rtw_zvmalloc(buf_size);
5564
5565 if (buffer == NULL) {
5566 RTW_ERR("%s buffer allocate failed size(%d)\n",
5567 __func__, buf_size);
5568 return;
5569 }
5570
5571 RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
5572
5573 ret = rtw_hal_get_rsvd_page(adapter, page_offset,
5574 page_number, buffer, buf_size);
5575
5576 if (ret == _FALSE) {
5577 RTW_ERR("%s get aoac report failed\n", __func__);
5578 rtw_warn_on(1);
5579 goto _exit;
5580 }
5581
5582 _rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
5583 _rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
5584
5585 for (i = 0 ; i < 4 ; i++) {
5586 tmp = paoac_rpt->replay_counter_eapol_key[i];
5587 paoac_rpt->replay_counter_eapol_key[i] =
5588 paoac_rpt->replay_counter_eapol_key[7 - i];
5589 paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
5590 }
5591
5592 rtw_dump_aoac_rpt(adapter);
5593
5594 _exit:
5595 if (buffer)
5596 rtw_vmfree(buffer, buf_size);
5597 }
5598
rtw_hal_update_tx_iv(_adapter * adapter)5599 static void rtw_hal_update_tx_iv(_adapter *adapter)
5600 {
5601 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5602 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
5603 struct sta_info *psta;
5604 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
5605 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5606 struct security_priv *psecpriv = &adapter->securitypriv;
5607
5608 u16 val16 = 0;
5609 u32 val32 = 0;
5610 u64 txiv = 0;
5611 u8 *pval = NULL;
5612
5613 psta = rtw_get_stainfo(&adapter->stapriv,
5614 get_my_bssid(&pmlmeinfo->network));
5615
5616 /* Update TX iv data. */
5617 pval = (u8 *)&paoac_rpt->iv;
5618
5619 if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
5620 val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
5621 ((u16)(paoac_rpt->iv[0]) << 8);
5622 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5623 ((u32)(paoac_rpt->iv[5]) << 8) +
5624 ((u32)(paoac_rpt->iv[6]) << 16) +
5625 ((u32)(paoac_rpt->iv[7]) << 24);
5626 } else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
5627 val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
5628 ((u16)(paoac_rpt->iv[1]) << 8);
5629 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
5630 ((u32)(paoac_rpt->iv[5]) << 8) +
5631 ((u32)(paoac_rpt->iv[6]) << 16) +
5632 ((u32)(paoac_rpt->iv[7]) << 24);
5633 }
5634
5635 if (psta) {
5636 txiv = val16 + ((u64)val32 << 16);
5637 if (txiv != 0)
5638 psta->dot11txpn.val = txiv;
5639 }
5640 }
5641
rtw_hal_update_sw_security_info(_adapter * adapter)5642 static void rtw_hal_update_sw_security_info(_adapter *adapter)
5643 {
5644 struct security_priv *psecpriv = &adapter->securitypriv;
5645 u8 sz = sizeof (psecpriv->iv_seq);
5646
5647 rtw_hal_update_tx_iv(adapter);
5648 #ifdef CONFIG_GTK_OL
5649 if (psecpriv->binstallKCK_KEK == _TRUE &&
5650 (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5651 rtw_hal_update_gtk_offload_info(adapter);
5652 #else
5653 _rtw_memset(psecpriv->iv_seq, 0, sz);
5654 #endif
5655 }
5656 #ifdef CONFIG_CUSTOM_PULSE
rtw_hal_set_gpio_custom_cmd(_adapter * adapter,u8 enable)5657 static u8 rtw_hal_set_gpio_custom_cmd(_adapter *adapter, u8 enable)
5658 {
5659 u8 H2CGpioCustomParm[H2C_GPIO_CUSTOM_LEN] = {0};
5660 u8 customid = 0x2, special_wakeup_reason = RX_MAGIC_PKT, custom_for_wakeup_reason=0x1;
5661 u8 ret = _FAIL;
5662
5663 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5664
5665 if(enable) {
5666 SET_H2CCMD_CUSTOMERID(H2CGpioCustomParm, customid);
5667 SET_H2CCMD_SPECIAL_WAKE_REASON(H2CGpioCustomParm, special_wakeup_reason);
5668 SET_H2CCMD_CUSTOM_WAKE_REASON(H2CGpioCustomParm, custom_for_wakeup_reason);
5669
5670 ret = rtw_hal_fill_h2c_cmd(adapter,
5671 H2C_GPIO_CUSTOM,
5672 H2C_GPIO_CUSTOM_LEN,
5673 H2CGpioCustomParm);
5674 RTW_DBG("%s(): H2C_cmd=%x, cmd=%02x, %02x, %02x\n", __func__, H2C_GPIO_CUSTOM,
5675 H2CGpioCustomParm[0], H2CGpioCustomParm[1], H2CGpioCustomParm[2]);
5676 }
5677
5678 return ret;
5679 }
5680 #endif /* CONFIG_CUSTOM_PULSE */
rtw_hal_set_keep_alive_cmd(_adapter * adapter,u8 enable,u8 pkt_type)5681 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
5682 {
5683 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
5684 u8 adopt = 1, check_period = 5;
5685 u8 ret = _FAIL;
5686 u8 hw_port = rtw_hal_get_port(adapter);
5687
5688 SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
5689 SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
5690 SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
5691 SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
5692 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5693 SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, hw_port);
5694 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5695 #else
5696 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5697 #endif
5698 ret = rtw_hal_fill_h2c_cmd(adapter,
5699 H2C_KEEP_ALIVE,
5700 H2C_KEEP_ALIVE_CTRL_LEN,
5701 u1H2CKeepAliveParm);
5702
5703 return ret;
5704 }
5705
5706 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter,u8 enable)5707 static u8 rtw_hal_set_keep_alive_pattern_cmd(PADAPTER adapter, u8 enable)
5708 {
5709 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
5710 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_PATTERN_LEN] = {0};
5711 u8 ret = _FAIL;
5712 int i;
5713
5714 /* If keep alive pattern is set, FW will use pattern for keep alive action */
5715 if(enable == 0 || (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_disable)) {
5716 SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _FALSE);
5717 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE);
5718 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5719 return ret;
5720 }
5721 /*step1:set keep alive period*/
5722 SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_LOW_BIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_period & 0x00FF);
5723 SET_H2CCMD_UDP_KEEP_ALIVE_PERIOD_HI_BIT(u1H2CKeepAliveParm, ((pwrctl->wowlan_keep_alive_period & 0xFF00)>> 8));
5724
5725 if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_tx) {
5726 SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5727 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _FALSE);
5728 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5729 SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5730 goto exit;
5731 }
5732 if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx) {
5733 SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5734 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE);
5735 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _FALSE);
5736 SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5737 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index);
5738 SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval);
5739 SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter);
5740 goto exit;
5741 }
5742 if (pwrctl->wowlan_keep_alive_mode == wow_keep_alive_pattern_trx_with_ack) {
5743 SET_H2CCMD_UDP_KEEP_ALIVE_EN(u1H2CKeepAliveParm, _TRUE);
5744 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_EN(u1H2CKeepAliveParm, _TRUE);
5745 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_EN(u1H2CKeepAliveParm, _TRUE);
5746 SET_H2CCMD_UDP_KEEP_ALIVE_PACKET_LOC(u1H2CKeepAliveParm, pwrctl->keep_alive_pattern_loc);
5747 SET_H2CCMD_UDP_KEEP_ALIVE_ACK_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_ack_index);
5748 SET_H2CCMD_UDP_KEEP_ALIVE_WAKE_PATTERN_idx(u1H2CKeepAliveParm, pwrctl->wowlan_wake_pattern_index);
5749 SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_INTERVAL(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_interval);
5750 SET_H2CCMD_UDP_KEEP_ALIVE_RETRY_LIMIT(u1H2CKeepAliveParm, pwrctl->wowlan_keep_alive_retry_counter);
5751 goto exit;
5752 }
5753 exit:
5754 for(i=0; i<H2C_KEEP_ALIVE_PATTERN_LEN; i++) {
5755 RTW_INFO("u1H2CKeepAliveParm[%d]= x%0x\n", i, u1H2CKeepAliveParm[i]);
5756 }
5757 ret = rtw_hal_fill_h2c_cmd(adapter,
5758 H2C_UDP_KEEPALIVE,
5759 H2C_KEEP_ALIVE_PATTERN_LEN,
5760 u1H2CKeepAliveParm);
5761
5762 return ret;
5763 }
5764 #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
5765
rtw_hal_set_disconnect_decision_cmd(_adapter * adapter,u8 enable)5766 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
5767 {
5768 u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
5769 u8 adopt = 1, check_period = 100, trypkt_num = 5;
5770 u8 ret = _FAIL;
5771 struct registry_priv *pregistry = &adapter->registrypriv;
5772 u8 hw_port = rtw_hal_get_port(adapter);
5773
5774 SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
5775 SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
5776 if (!(pregistry->wakeup_event & BIT(2)))
5777 SET_H2CCMD_DISCONDECISION_PARM_DISCONNECT_EN(u1H2CDisconDecisionParm, adopt);
5778 SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
5779 SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
5780 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
5781 SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, hw_port);
5782 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, hw_port);
5783 #else
5784 RTW_INFO("%s(): enable = %d\n", __func__, enable);
5785 #endif
5786
5787 ret = rtw_hal_fill_h2c_cmd(adapter,
5788 H2C_DISCON_DECISION,
5789 H2C_DISCON_DECISION_LEN,
5790 u1H2CDisconDecisionParm);
5791 return ret;
5792 }
5793
rtw_hal_set_wowlan_ctrl_cmd(_adapter * adapter,u8 enable,u8 change_unit)5794 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
5795 {
5796 struct registry_priv *registry_par = &adapter->registrypriv;
5797 struct security_priv *psecpriv = &adapter->securitypriv;
5798 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5799 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5800
5801 u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
5802 u8 discont_wake = 0, gpionum = 0, gpio_dur = 0, no_wake = 0;
5803 u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
5804 u8 sdio_wakeup_enable = 1;
5805 u8 gpio_high_active = 0;
5806 u8 magic_pkt = 0;
5807 u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
5808 u8 ret = _FAIL;
5809 #ifdef CONFIG_DIS_UPHY
5810 u8 dis_uphy = 0, dis_uphy_unit = 0, dis_uphy_time = 0;
5811 #endif /* CONFIG_DIS_UPHY */
5812
5813 #ifdef CONFIG_GPIO_WAKEUP
5814 gpio_high_active = ppwrpriv->is_high_active;
5815 gpionum = ppwrpriv->wowlan_gpio_index;
5816 sdio_wakeup_enable = 0;
5817 #endif /* CONFIG_GPIO_WAKEUP */
5818
5819 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
5820 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5821 no_wake = 1;
5822
5823 if (!ppwrpriv->wowlan_pno_enable &&
5824 registry_par->wakeup_event & BIT(0) && !no_wake)
5825 magic_pkt = enable;
5826
5827 if (registry_par->wakeup_event & BIT(2) && !no_wake)
5828 discont_wake = enable;
5829
5830 RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
5831 enable, change_unit);
5832
5833 /* time = (gpio_dur/2) * gpio_unit, default:256 ms */
5834 if (enable && change_unit) {
5835 gpio_dur = 0x40;
5836 gpio_unit = 1;
5837 gpio_pulse_en = 1;
5838 }
5839
5840 #ifdef CONFIG_PLATFORM_ARM_RK3188
5841 if (enable) {
5842 gpio_pulse_en = 1;
5843 gpio_pulse_cnt = 0x04;
5844 }
5845 #endif
5846
5847 SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
5848 if(!no_wake)
5849 SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
5850 SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
5851 SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
5852 SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
5853 SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
5854
5855 #ifdef CONFIG_GTK_OL
5856 if (psecpriv->binstallKCK_KEK == _TRUE &&
5857 (psecpriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)))
5858 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
5859 else
5860 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
5861 #else
5862 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
5863 #endif
5864 SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
5865 SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
5866 SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
5867
5868 SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
5869 SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
5870
5871 SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
5872 SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
5873
5874 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
5875 if (enable)
5876 SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5877 #endif
5878
5879 #ifdef CONFIG_DIS_UPHY
5880 if (enable) {
5881 dis_uphy = 1;
5882 /* time unit: 0 -> ms, 1 -> 256 ms*/
5883 dis_uphy_unit = 1;
5884 dis_uphy_time = 0x4;
5885 }
5886
5887 SET_H2CCMD_WOWLAN_DISABLE_UPHY(u1H2CWoWlanCtrlParm, dis_uphy);
5888 SET_H2CCMD_WOWLAN_UNIT_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_unit);
5889 SET_H2CCMD_WOWLAN_TIME_FOR_UPHY_DISABLE(u1H2CWoWlanCtrlParm, dis_uphy_time);
5890 if (ppwrpriv->hst2dev_high_active == 1)
5891 SET_H2CCMD_WOWLAN_RISE_HST2DEV(u1H2CWoWlanCtrlParm, 1);
5892 #ifdef CONFIG_RTW_ONE_PIN_GPIO
5893 SET_H2CCMD_WOWLAN_GPIO_INPUT_EN(u1H2CWoWlanCtrlParm, 1);
5894 SET_H2CCMD_WOWLAN_DEV2HST_EN(u1H2CWoWlanCtrlParm, 1);
5895 SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 0);
5896 #else
5897 SET_H2CCMD_WOWLAN_HST2DEV_EN(u1H2CWoWlanCtrlParm, 1);
5898 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
5899 #endif /* CONFIG_DIS_UPHY */
5900
5901
5902 ret = rtw_hal_fill_h2c_cmd(adapter,
5903 H2C_WOWLAN,
5904 H2C_WOWLAN_LEN,
5905 u1H2CWoWlanCtrlParm);
5906 return ret;
5907 }
5908
rtw_hal_set_remote_wake_ctrl_cmd(_adapter * adapter,u8 enable)5909 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
5910 {
5911 struct security_priv *psecuritypriv = &(adapter->securitypriv);
5912 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
5913 struct registry_priv *pregistrypriv = &adapter->registrypriv;
5914 u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
5915 u8 ret = _FAIL, count = 0, no_wake = 0;
5916 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
5917
5918 RTW_INFO("%s(): enable=%d\n", __func__, enable);
5919
5920 if(pregistrypriv->suspend_type == FW_IPS_DISABLE_BBRF &&
5921 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
5922 no_wake = 1;
5923 if(no_wake) {
5924 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5925 u1H2CRemoteWakeCtrlParm, enable);
5926 } else {
5927 if (!ppwrpriv->wowlan_pno_enable) {
5928 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
5929 u1H2CRemoteWakeCtrlParm, enable);
5930 #ifdef CONFIG_GTK_OL
5931 if (psecuritypriv->binstallKCK_KEK == _TRUE &&
5932 (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK || _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))) {
5933 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5934 u1H2CRemoteWakeCtrlParm, 1);
5935 } else {
5936 RTW_INFO("no kck kek\n");
5937 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
5938 u1H2CRemoteWakeCtrlParm, 0);
5939 }
5940 #endif /* CONFIG_GTK_OL */
5941
5942 #ifdef CONFIG_IPV6
5943 if (ppwrpriv->wowlan_ns_offload_en == _TRUE) {
5944 RTW_INFO("enable NS offload\n");
5945 SET_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(
5946 u1H2CRemoteWakeCtrlParm, enable);
5947 }
5948
5949 /*
5950 * filter NetBios name service pkt to avoid being waked-up
5951 * by this kind of unicast pkt this exceptional modification
5952 * is used for match competitor's behavior
5953 */
5954
5955 SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
5956 u1H2CRemoteWakeCtrlParm, enable);
5957 #endif /*CONFIG_IPV6*/
5958 #if 0 /* replaced by WOWLAN pattern match */
5959 #ifdef CONFIG_RTL8192F
5960 if (IS_HARDWARE_TYPE_8192F(adapter)){
5961 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
5962 u1H2CRemoteWakeCtrlParm, enable);
5963 }
5964 #endif /* CONFIG_RTL8192F */
5965 #endif
5966 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
5967 #ifdef CONFIG_GTK_OL
5968 if(_rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL))
5969 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5970 u1H2CRemoteWakeCtrlParm, enable);
5971 #endif /* CONFIG_GTK_OL */
5972 if (IS_HARDWARE_TYPE_8188E(adapter) ||
5973 IS_HARDWARE_TYPE_8812(adapter)) {
5974 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
5975 u1H2CRemoteWakeCtrlParm, 0);
5976 }
5977 }
5978
5979 if (0) {
5980 /* ARP wake up case */
5981 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5982 u1H2CRemoteWakeCtrlParm, 1);
5983 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
5984 u1H2CRemoteWakeCtrlParm, 1);
5985 } else if (pregistrypriv->wakeup_event) {
5986 /* ARP no wake up case */
5987 if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
5988 (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
5989 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5990 u1H2CRemoteWakeCtrlParm, 1);
5991 }
5992 #ifdef CONFIG_GTK_OL
5993 else if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_ &&
5994 _rtw_wow_chk_cap(adapter, WOW_CAP_TKIP_OL)) {
5995 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
5996 u1H2CRemoteWakeCtrlParm, 1);
5997 }
5998 #endif
5999 } else {
6000 /* ARP no wake up and no ARP response case */
6001 }
6002
6003 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
6004 u1H2CRemoteWakeCtrlParm, 1);
6005 }
6006 #ifdef CONFIG_PNO_SUPPORT
6007 else {
6008 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
6009 u1H2CRemoteWakeCtrlParm, enable);
6010 SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
6011 u1H2CRemoteWakeCtrlParm, enable);
6012 }
6013 #endif
6014
6015 #ifdef CONFIG_P2P_WOWLAN
6016 if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
6017 RTW_INFO("P2P OFFLOAD ENABLE\n");
6018 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
6019 } else {
6020 RTW_INFO("P2P OFFLOAD DISABLE\n");
6021 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
6022 }
6023 #endif /* CONFIG_P2P_WOWLAN */
6024 }
6025
6026
6027 ret = rtw_hal_fill_h2c_cmd(adapter,
6028 H2C_REMOTE_WAKE_CTRL,
6029 H2C_REMOTE_WAKE_CTRL_LEN,
6030 u1H2CRemoteWakeCtrlParm);
6031 return ret;
6032 }
6033
6034 #ifdef CONFIG_WAR_OFFLOAD
rtw_hal_set_war_offload_ctrl_cmd(_adapter * adapter,u8 enable)6035 static u8 rtw_hal_set_war_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6036 {
6037 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6038 u8 u1H2CWarOffloadParm[H2C_WAR_OFFLOAD_LEN] = {0};
6039 u8 ret = _FAIL;
6040
6041 RTW_INFO("%s(): enable=%d\n", __func__, enable);
6042
6043 if (_TRUE == ppwrpriv->wowlan_war_offload_mode) {
6044 SET_H2CCMD_WAR_CFG_EN(u1H2CWarOffloadParm, enable);
6045 SET_H2CCMD_WAR_CFG_ARP_RSP_EN(u1H2CWarOffloadParm, 1);
6046
6047 #ifdef CONFIG_OFFLOAD_MDNS_V4
6048 if (WAR_MDNS_V4_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
6049 SET_H2CCMD_WAR_CFG_MDNSV4_RSP_EN(u1H2CWarOffloadParm, 1);
6050 }
6051 if (WAR_MDNS_V4_WAKEUP_EN& ppwrpriv->wowlan_war_offload_ctrl) {
6052 SET_H2CCMD_WAR_CFG_MDNSV4_WAKE_EN(u1H2CWarOffloadParm, 1);
6053 }
6054 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
6055
6056 #ifdef CONFIG_OFFLOAD_MDNS_V6
6057 if (WAR_MDNS_V6_RSP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
6058 SET_H2CCMD_WAR_CFG_MDNSV6_RSP_EN(u1H2CWarOffloadParm, 1);
6059 }
6060 if (WAR_MDNS_V6_WAKEUP_EN & ppwrpriv->wowlan_war_offload_ctrl) {
6061 SET_H2CCMD_WAR_CFG_MDNSV6_WAKE_EN(u1H2CWarOffloadParm, 1);
6062 }
6063 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
6064
6065 }
6066
6067 ret = rtw_hal_fill_h2c_cmd(adapter,
6068 H2C_WAR_OFFLOAD,
6069 H2C_WAR_OFFLOAD_LEN,
6070 u1H2CWarOffloadParm);
6071 return ret;
6072 }
6073
rtw_hal_set_war_offload_parm(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)6074 static u8 rtw_hal_set_war_offload_parm(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
6075 {
6076 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6077 u8 u1H2CWarOfldParm[H2C_WAROFLD_RSVDPAGE1_LEN] = {0};
6078 u8 ret = _FAIL;
6079
6080 SET_H2CCMD_WAROFLD_RSVDPAGE1_LOC_PARM(u1H2CWarOfldParm, rsvdpageloc->LocIpParm);
6081 RTW_INFO("%s(): LocIpParm = %d\n", __func__, rsvdpageloc->LocIpParm);
6082
6083
6084 ret = rtw_hal_fill_h2c_cmd(adapter,
6085 H2C_WAROFLD_RSVDPAGE1,
6086 H2C_WAROFLD_RSVDPAGE1_LEN,
6087 u1H2CWarOfldParm);
6088
6089 return ret;
6090 }
6091 #endif /* CONFIG_WAR_OFFLOAD */
6092
6093
6094
rtw_hal_set_global_info_cmd(_adapter * adapter,u8 group_alg,u8 pairwise_alg)6095 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
6096 {
6097 u8 ret = _FAIL;
6098 u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
6099
6100 RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
6101 __func__, group_alg, pairwise_alg);
6102 SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
6103 pairwise_alg);
6104 SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
6105 group_alg);
6106
6107 ret = rtw_hal_fill_h2c_cmd(adapter,
6108 H2C_AOAC_GLOBAL_INFO,
6109 H2C_AOAC_GLOBAL_INFO_LEN,
6110 u1H2CAOACGlobalInfoParm);
6111
6112 return ret;
6113 }
6114
6115 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_set_scan_offload_info_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc,u8 enable)6116 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
6117 PRSVDPAGE_LOC rsvdpageloc, u8 enable)
6118 {
6119 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6120 u8 ret = _FAIL;
6121 #ifndef RTW_HALMAC
6122 u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
6123
6124 RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
6125 __func__, rsvdpageloc->LocProbePacket,
6126 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
6127
6128 SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
6129 SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
6130 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
6131 rsvdpageloc->LocScanInfo);
6132 SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
6133 rsvdpageloc->LocProbePacket);
6134 /*
6135 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
6136 rsvdpageloc->LocSSIDInfo);
6137 */
6138 ret = rtw_hal_fill_h2c_cmd(adapter,
6139 H2C_D0_SCAN_OFFLOAD_INFO,
6140 H2C_SCAN_OFFLOAD_CTRL_LEN,
6141 u1H2CScanOffloadInfoParm);
6142 #else
6143 u8 u1H2CNLOINFOInfoParm[H2C_NLO_INFO_LEN] = {0};
6144
6145 RTW_INFO("%s: loc_nlo_info: %d enable %d\n", __func__,
6146 rsvdpageloc->LocPNOInfo, enable);
6147
6148 SET_H2CCMD_NLO_FUN_EN(u1H2CNLOINFOInfoParm, enable);
6149 #ifdef CONFIG_LPS_LCLK
6150 // TODO(Owen): Controlled by wowlan lps level
6151 /* This H2C bit requires driver leave LCLK in rtw_resume_process_wow() */
6152 SET_H2CCMD_NLO_PS_32K(u1H2CNLOINFOInfoParm, enable);
6153 #endif
6154 SET_H2CCMD_NLO_LOC_NLO_INFO(u1H2CNLOINFOInfoParm, rsvdpageloc->LocPNOInfo);
6155
6156 ret = rtw_hal_fill_h2c_cmd(adapter,
6157 H2C_NLO_INFO,
6158 H2C_NLO_INFO_LEN,
6159 u1H2CNLOINFOInfoParm);
6160 #endif
6161 return ret;
6162 }
6163 #endif /* CONFIG_PNO_SUPPORT */
6164
rtw_hal_set_fw_wow_related_cmd(_adapter * padapter,u8 enable)6165 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
6166 {
6167 struct security_priv *psecpriv = &padapter->securitypriv;
6168 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
6169 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6170 struct registry_priv *pregistry = &padapter->registrypriv;
6171 u8 pkt_type = 0, no_wake = 0;
6172
6173 if(pregistry->suspend_type == FW_IPS_DISABLE_BBRF &&
6174 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
6175 no_wake = 1;
6176
6177 RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
6178
6179 rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
6180
6181 if (enable) {
6182 if(!no_wake)
6183 rtw_hal_set_global_info_cmd(padapter,
6184 psecpriv->dot118021XGrpPrivacy,
6185 psecpriv->dot11PrivacyAlgrthm);
6186
6187 if (!(ppwrpriv->wowlan_pno_enable)) {
6188 if (!no_wake)
6189 rtw_hal_set_disconnect_decision_cmd(padapter,
6190 enable);
6191 #ifdef CONFIG_ARP_KEEP_ALIVE
6192 if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
6193 (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
6194 pkt_type = 0;
6195 else
6196 pkt_type = 1;
6197 #else
6198 pkt_type = 0;
6199 #endif /* CONFIG_ARP_KEEP_ALIVE */
6200 if(!no_wake) {
6201 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
6202 rtw_hal_set_keep_alive_pattern_cmd(padapter,enable);
6203 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
6204 rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
6205 }
6206 }
6207 #if defined(CONFIG_PNO_SUPPORT) && !defined(RTW_HALMAC)
6208 rtw_hal_check_pno_enabled(padapter);
6209 #endif /* defined(CONFIG_PNO_SUPPORT) && !defined(RTW_HALMAC) */
6210 #ifdef CONFIG_WAR_OFFLOAD
6211 rtw_hal_set_war_offload_ctrl_cmd(padapter, enable);
6212 #endif /* CONFIG_WAR_OFFLOAD */
6213
6214 } else {
6215 #if 0
6216 {
6217 u32 PageSize = 0;
6218 rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
6219 dump_TX_FIFO(padapter, 4, PageSize);
6220 }
6221 #endif
6222 }
6223 #ifdef CONFIG_CUSTOM_PULSE
6224 rtw_hal_set_gpio_custom_cmd(padapter, enable);
6225 #endif /* CONFIG_CUSTOM_PULSE */
6226 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
6227 RTW_PRINT("-%s()-\n", __func__);
6228 }
6229 #endif /* CONFIG_WOWLAN */
6230
6231 #ifdef CONFIG_AP_WOWLAN
rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter * adapter,u8 enable)6232 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
6233 {
6234 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
6235
6236 u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
6237 u8 gpionum = 0, gpio_dur = 0;
6238 u8 gpio_pulse = enable;
6239 u8 sdio_wakeup_enable = 1;
6240 u8 gpio_high_active = 0;
6241 u8 ret = _FAIL;
6242
6243 #ifdef CONFIG_GPIO_WAKEUP
6244 gpio_high_active = ppwrpriv->is_high_active;
6245 gpionum = ppwrpriv->wowlan_gpio_index;
6246 sdio_wakeup_enable = 0;
6247 #endif /*CONFIG_GPIO_WAKEUP*/
6248
6249 RTW_INFO("%s(): enable=%d\n", __func__, enable);
6250
6251 SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
6252 gpionum);
6253 SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
6254 gpio_pulse);
6255 SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
6256 gpio_high_active);
6257 SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
6258 enable);
6259 SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
6260 gpio_dur);
6261
6262 ret = rtw_hal_fill_h2c_cmd(adapter,
6263 H2C_AP_WOW_GPIO_CTRL,
6264 H2C_AP_WOW_GPIO_CTRL_LEN,
6265 u1H2CAPWoWlanCtrlParm);
6266
6267 return ret;
6268 }
6269
rtw_hal_set_ap_offload_ctrl_cmd(_adapter * adapter,u8 enable)6270 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
6271 {
6272 u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
6273 u8 ret = _FAIL;
6274
6275 RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
6276
6277 SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
6278
6279 ret = rtw_hal_fill_h2c_cmd(adapter,
6280 H2C_AP_OFFLOAD,
6281 H2C_AP_OFFLOAD_LEN,
6282 u1H2CAPOffloadCtrlParm);
6283
6284 return ret;
6285 }
6286
rtw_hal_set_ap_ps_cmd(_adapter * adapter,u8 enable)6287 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
6288 {
6289 u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
6290 u8 ret = _FAIL;
6291
6292 RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
6293
6294 SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
6295 #ifndef CONFIG_USB_HCI
6296 SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
6297 #endif /*CONFIG_USB_HCI*/
6298 SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
6299
6300 if (enable)
6301 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
6302 else
6303 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
6304
6305 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
6306 H2C_AP_PS_LEN, ap_ps_parm);
6307
6308 return ret;
6309 }
6310
rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,PRSVDPAGE_LOC rsvdpageloc)6311 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
6312 PRSVDPAGE_LOC rsvdpageloc)
6313 {
6314 struct hal_ops *pHalFunc = &padapter->hal_func;
6315 u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
6316 u8 ret = _FAIL, header = 0;
6317
6318 if (pHalFunc->fill_h2c_cmd == NULL) {
6319 RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
6320 return;
6321 }
6322
6323 header = rtw_read8(padapter, REG_BCNQ_BDNY);
6324
6325 RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
6326 rsvdpageloc->LocApOffloadBCN,
6327 rsvdpageloc->LocProbeRsp,
6328 header);
6329
6330 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
6331 rsvdpageloc->LocApOffloadBCN + header);
6332
6333 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
6334 H2C_BCN_RSVDPAGE_LEN, rsvdparm);
6335
6336 if (ret == _FAIL)
6337 RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
6338
6339 rtw_msleep_os(10);
6340
6341 _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
6342
6343 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
6344 rsvdpageloc->LocProbeRsp + header);
6345
6346 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
6347 H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
6348
6349 if (ret == _FAIL)
6350 RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
6351
6352 rtw_msleep_os(10);
6353 }
6354
rtw_hal_set_fw_ap_wow_related_cmd(_adapter * padapter,u8 enable)6355 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
6356 {
6357 rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
6358 rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
6359 rtw_hal_set_ap_ps_cmd(padapter, enable);
6360 }
6361
rtw_hal_ap_wow_enable(_adapter * padapter)6362 static void rtw_hal_ap_wow_enable(_adapter *padapter)
6363 {
6364 struct security_priv *psecuritypriv = &padapter->securitypriv;
6365 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6366 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6367 struct sta_info *psta = NULL;
6368 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6369 #ifdef DBG_CHECK_FW_PS_STATE
6370 struct dvobj_priv *psdpriv = padapter->dvobj;
6371 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6372 #endif /*DBG_CHECK_FW_PS_STATE*/
6373 int res;
6374 u16 media_status_rpt;
6375 #ifdef CONFIG_GPIO_WAKEUP
6376 u8 val8 = 0;
6377 #endif
6378
6379 RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
6380 #ifdef DBG_CHECK_FW_PS_STATE
6381 if (rtw_fw_ps_state(padapter) == _FAIL) {
6382 pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
6383 RTW_PRINT("wowlan enable no leave 32k\n");
6384 }
6385 #endif /*DBG_CHECK_FW_PS_STATE*/
6386
6387 /* 1. Download WOWLAN FW*/
6388 rtw_hal_fw_dl(padapter, _TRUE);
6389
6390 media_status_rpt = RT_MEDIA_CONNECT;
6391 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6392 (u8 *)&media_status_rpt);
6393
6394 issue_beacon(padapter, 0);
6395
6396 rtw_msleep_os(2);
6397 #if defined(CONFIG_RTL8188E)
6398 if (IS_HARDWARE_TYPE_8188E(padapter))
6399 rtw_hal_disable_tx_report(padapter);
6400 #endif
6401 /* RX DMA stop */
6402 res = rtw_hal_pause_rx_dma(padapter);
6403 if (res == _FAIL)
6404 RTW_PRINT("[WARNING] pause RX DMA fail\n");
6405
6406 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6407 /* Enable CPWM2 only. */
6408 res = rtw_hal_enable_cpwm2(padapter);
6409 if (res == _FAIL)
6410 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
6411 #endif
6412
6413 #ifdef CONFIG_GPIO_WAKEUP
6414 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6415 rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6416 rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6417 #else
6418 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6419 if (pwrctrlpriv->is_high_active == 0)
6420 rtw_hal_set_input_gpio(padapter, pwrpriv->wowlan_gpio_index);
6421 else
6422 rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index,
6423 GPIO_OUTPUT_LOW);
6424 #else
6425 val8 = (pwrpriv->is_high_active == 0) ? 1 : 0;
6426 rtw_hal_set_output_gpio(padapter, pwrpriv->wowlan_gpio_index, val8);
6427 rtw_hal_switch_gpio_wl_ctrl(padapter, pwrpriv->wowlan_gpio_index, _TRUE);
6428 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow suspend and %s_ACTIVE.\n",
6429 __func__, pwrpriv->wowlan_gpio_index,
6430 pwrpriv->wowlan_gpio_output_state ? "HIGH" : "LOW",
6431 pwrpriv->is_high_active ? "HIGI" : "LOW");
6432 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
6433 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6434 #endif /* CONFIG_GPIO_WAKEUP */
6435
6436 /* 5. Set Enable WOWLAN H2C command. */
6437 RTW_PRINT("Set Enable AP WOWLan cmd\n");
6438 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
6439
6440 rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
6441 #ifdef CONFIG_USB_HCI
6442 rtw_mi_intf_stop(padapter);
6443 #endif
6444 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
6445 /* Invoid SE0 reset signal during suspending*/
6446 rtw_write8(padapter, REG_RSV_CTRL, 0x20);
6447 if (IS_8188F(pHalData->version_id) == FALSE
6448 && IS_8188GTV(pHalData->version_id) == FALSE)
6449 rtw_write8(padapter, REG_RSV_CTRL, 0x60);
6450 #endif
6451 }
6452
rtw_hal_ap_wow_disable(_adapter * padapter)6453 static void rtw_hal_ap_wow_disable(_adapter *padapter)
6454 {
6455 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6456 #ifdef DBG_CHECK_FW_PS_STATE
6457 struct dvobj_priv *psdpriv = padapter->dvobj;
6458 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
6459 #endif /*DBG_CHECK_FW_PS_STATE*/
6460 u16 media_status_rpt;
6461
6462 RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
6463 /* 1. Read wakeup reason*/
6464 pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
6465
6466 RTW_PRINT("wakeup_reason: 0x%02x\n",
6467 pwrctl->wowlan_wake_reason);
6468
6469 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
6470
6471 rtw_msleep_os(2);
6472 #ifdef DBG_CHECK_FW_PS_STATE
6473 if (rtw_fw_ps_state(padapter) == _FAIL) {
6474 pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
6475 RTW_PRINT("wowlan enable no leave 32k\n");
6476 }
6477 #endif /*DBG_CHECK_FW_PS_STATE*/
6478
6479 #if defined(CONFIG_RTL8188E)
6480 if (IS_HARDWARE_TYPE_8188E(padapter))
6481 rtw_hal_enable_tx_report(padapter);
6482 #endif
6483
6484 rtw_hal_force_enable_rxdma(padapter);
6485
6486 rtw_hal_fw_dl(padapter, _FALSE);
6487
6488 #ifdef CONFIG_GPIO_WAKEUP
6489 #ifdef CONFIG_RTW_ONE_PIN_GPIO
6490 rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6491 #else
6492 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
6493 if (pwrctl->is_high_active == 0)
6494 rtw_hal_set_input_gpio(padapter, pwrctl->wowlan_gpio_index);
6495 else
6496 rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index
6497 , GPIO_OUTPUT_LOW);
6498 #else
6499 rtw_hal_set_output_gpio(padapter, pwrctl->wowlan_gpio_index,
6500 pwrctl->wowlan_gpio_output_state);
6501 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in ap wow resume and %s_ACTIVE.\n",
6502 __func__, pwrctl->wowlan_gpio_index,
6503 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
6504 pwrctl->is_high_active ? "HIGI" : "LOW");
6505 #endif /*CONFIG_WAKEUP_GPIO_INPUT_MODE*/
6506 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
6507 #endif /* CONFIG_GPIO_WAKEUP */
6508 media_status_rpt = RT_MEDIA_CONNECT;
6509
6510 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
6511 (u8 *)&media_status_rpt);
6512
6513 issue_beacon(padapter, 0);
6514 }
6515 #endif /*CONFIG_AP_WOWLAN*/
6516
6517 #ifdef CONFIG_P2P_WOWLAN
update_hidden_ssid(u8 * ies,u32 ies_len,u8 hidden_ssid_mode)6518 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
6519 {
6520 u8 *ssid_ie;
6521 sint ssid_len_ori;
6522 int len_diff = 0;
6523
6524 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
6525
6526 /* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
6527
6528 if (ssid_ie && ssid_len_ori > 0) {
6529 switch (hidden_ssid_mode) {
6530 case 1: {
6531 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
6532 u32 remain_len = 0;
6533
6534 remain_len = ies_len - (next_ie - ies);
6535
6536 ssid_ie[1] = 0;
6537 _rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
6538 len_diff -= ssid_len_ori;
6539
6540 break;
6541 }
6542 case 2:
6543 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
6544 break;
6545 default:
6546 break;
6547 }
6548 }
6549
6550 return len_diff;
6551 }
6552
rtw_hal_construct_P2PBeacon(_adapter * padapter,u8 * pframe,u32 * pLength)6553 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
6554 {
6555 /* struct xmit_frame *pmgntframe; */
6556 /* struct pkt_attrib *pattrib; */
6557 /* unsigned char *pframe; */
6558 struct rtw_ieee80211_hdr *pwlanhdr;
6559 unsigned short *fctrl;
6560 unsigned int rate_len;
6561 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6562 u32 pktlen;
6563 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6564 /* _irqL irqL;
6565 * struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6566 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6567 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6568 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6569 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6570 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
6571 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6572 #ifdef CONFIG_P2P
6573 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6574 #endif /* CONFIG_P2P */
6575
6576 /* for debug */
6577 u8 *dbgbuf = pframe;
6578 u8 dbgbufLen = 0, index = 0;
6579
6580 RTW_INFO("%s\n", __FUNCTION__);
6581 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6582 /* _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6583 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6584
6585 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6586
6587
6588 fctrl = &(pwlanhdr->frame_ctl);
6589 *(fctrl) = 0;
6590
6591 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6592 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6593 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
6594
6595 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
6596 /* pmlmeext->mgnt_seq++; */
6597 set_frame_sub_type(pframe, WIFI_BEACON);
6598
6599 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6600 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6601
6602 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
6603 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
6604 #ifdef CONFIG_P2P
6605 /* for P2P : Primary Device Type & Device Name */
6606 u32 wpsielen = 0, insert_len = 0;
6607 u8 *wpsie = NULL;
6608 wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
6609
6610 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
6611 uint wps_offset, remainder_ielen;
6612 u8 *premainder_ie, *pframe_wscie;
6613
6614 wps_offset = (uint)(wpsie - cur_network->IEs);
6615
6616 premainder_ie = wpsie + wpsielen;
6617
6618 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6619
6620 #ifdef CONFIG_IOCTL_CFG80211
6621 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6622 if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
6623 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
6624 pframe += wps_offset;
6625 pktlen += wps_offset;
6626
6627 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6628 pframe += pmlmepriv->wps_beacon_ie_len;
6629 pktlen += pmlmepriv->wps_beacon_ie_len;
6630
6631 /* copy remainder_ie to pframe */
6632 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6633 pframe += remainder_ielen;
6634 pktlen += remainder_ielen;
6635 } else {
6636 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6637 pframe += cur_network->IELength;
6638 pktlen += cur_network->IELength;
6639 }
6640 } else
6641 #endif /* CONFIG_IOCTL_CFG80211 */
6642 {
6643 pframe_wscie = pframe + wps_offset;
6644 _rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
6645 pframe += (wps_offset + wpsielen);
6646 pktlen += (wps_offset + wpsielen);
6647
6648 /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6649 /* Primary Device Type */
6650 /* Type: */
6651 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6652 insert_len += 2;
6653
6654 /* Length: */
6655 *(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
6656 insert_len += 2;
6657
6658 /* Value: */
6659 /* Category ID */
6660 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6661 insert_len += 2;
6662
6663 /* OUI */
6664 *(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
6665 insert_len += 4;
6666
6667 /* Sub Category ID */
6668 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6669 insert_len += 2;
6670
6671
6672 /* Device Name */
6673 /* Type: */
6674 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6675 insert_len += 2;
6676
6677 /* Length: */
6678 *(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
6679 insert_len += 2;
6680
6681 /* Value: */
6682 _rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
6683 insert_len += pwdinfo->device_name_len;
6684
6685
6686 /* update wsc ie length */
6687 *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
6688
6689 /* pframe move to end */
6690 pframe += insert_len;
6691 pktlen += insert_len;
6692
6693 /* copy remainder_ie to pframe */
6694 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
6695 pframe += remainder_ielen;
6696 pktlen += remainder_ielen;
6697 }
6698 } else
6699 #endif /* CONFIG_P2P */
6700 {
6701 int len_diff;
6702 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6703 len_diff = update_hidden_ssid(
6704 pframe + _BEACON_IE_OFFSET_
6705 , cur_network->IELength - _BEACON_IE_OFFSET_
6706 , pmlmeinfo->hidden_ssid_mode
6707 );
6708 pframe += (cur_network->IELength + len_diff);
6709 pktlen += (cur_network->IELength + len_diff);
6710 }
6711 #if 0
6712 {
6713 u8 *wps_ie;
6714 uint wps_ielen;
6715 u8 sr = 0;
6716 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
6717 pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
6718 if (wps_ie && wps_ielen > 0)
6719 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6720 if (sr != 0)
6721 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6722 else
6723 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6724 }
6725 #endif
6726 #ifdef CONFIG_P2P
6727 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6728 u32 len;
6729 #ifdef CONFIG_IOCTL_CFG80211
6730 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6731 len = pmlmepriv->p2p_beacon_ie_len;
6732 if (pmlmepriv->p2p_beacon_ie && len > 0)
6733 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6734 } else
6735 #endif /* CONFIG_IOCTL_CFG80211 */
6736 {
6737 len = build_beacon_p2p_ie(pwdinfo, pframe);
6738 }
6739
6740 pframe += len;
6741 pktlen += len;
6742
6743 #ifdef CONFIG_WFD
6744 len = rtw_append_beacon_wfd_ie(padapter, pframe);
6745 pframe += len;
6746 pktlen += len;
6747 #endif
6748
6749 }
6750 #endif /* CONFIG_P2P */
6751
6752 goto _issue_bcn;
6753
6754 }
6755
6756 /* below for ad-hoc mode */
6757
6758 /* timestamp will be inserted by hardware */
6759 pframe += 8;
6760 pktlen += 8;
6761
6762 /* beacon interval: 2 bytes */
6763
6764 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6765
6766 pframe += 2;
6767 pktlen += 2;
6768
6769 /* capability info: 2 bytes */
6770
6771 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6772
6773 pframe += 2;
6774 pktlen += 2;
6775
6776 /* SSID */
6777 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
6778
6779 /* supported rates... */
6780 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6781 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
6782
6783 /* DS parameter set */
6784 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
6785
6786 /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6787 {
6788 u8 erpinfo = 0;
6789 u32 ATIMWindow;
6790 /* IBSS Parameter Set... */
6791 /* ATIMWindow = cur->Configuration.ATIMWindow; */
6792 ATIMWindow = 0;
6793 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
6794
6795 /* ERP IE */
6796 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
6797 }
6798
6799
6800 /* EXTERNDED SUPPORTED RATE */
6801 if (rate_len > 8)
6802 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
6803
6804
6805 /* todo:HT for adhoc */
6806
6807 _issue_bcn:
6808
6809 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6810 /* pmlmepriv->update_bcn = _FALSE;
6811 *
6812 * _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
6813 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6814
6815 *pLength = pktlen;
6816 #if 0
6817 /* printf dbg msg */
6818 dbgbufLen = pktlen;
6819 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6820
6821 for (index = 0; index < dbgbufLen; index++)
6822 printk("%x ", *(dbgbuf + index));
6823
6824 printk("\n");
6825 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
6826
6827 #endif
6828 }
6829
rtw_hal_construct_P2PProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength)6830 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
6831 {
6832 /* struct xmit_frame *pmgntframe; */
6833 /* struct pkt_attrib *pattrib; */
6834 /* unsigned char *pframe; */
6835 struct rtw_ieee80211_hdr *pwlanhdr;
6836 unsigned short *fctrl;
6837 unsigned char *mac;
6838 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6839 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6840 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6841 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6842 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
6843 u16 beacon_interval = 100;
6844 u16 capInfo = 0;
6845 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6846 u8 wpsie[255] = { 0x00 };
6847 u32 wpsielen = 0, p2pielen = 0;
6848 u32 pktlen;
6849 #ifdef CONFIG_WFD
6850 u32 wfdielen = 0;
6851 #endif
6852
6853 /* for debug */
6854 u8 *dbgbuf = pframe;
6855 u8 dbgbufLen = 0, index = 0;
6856
6857 RTW_INFO("%s\n", __FUNCTION__);
6858 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6859
6860 mac = adapter_mac_addr(padapter);
6861
6862 fctrl = &(pwlanhdr->frame_ctl);
6863 *(fctrl) = 0;
6864
6865 /* DA filled by FW */
6866 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
6867 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6868
6869 /* Use the device address for BSSID field. */
6870 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
6871
6872 SetSeqNum(pwlanhdr, 0);
6873 set_frame_sub_type(fctrl, WIFI_PROBERSP);
6874
6875 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6876 pframe += pktlen;
6877
6878
6879 /* timestamp will be inserted by hardware */
6880 pframe += 8;
6881 pktlen += 8;
6882
6883 /* beacon interval: 2 bytes */
6884 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
6885 pframe += 2;
6886 pktlen += 2;
6887
6888 /* capability info: 2 bytes */
6889 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
6890 capInfo |= cap_ShortPremble;
6891 capInfo |= cap_ShortSlot;
6892
6893 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
6894 pframe += 2;
6895 pktlen += 2;
6896
6897
6898 /* SSID */
6899 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
6900
6901 /* supported rates... */
6902 /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
6903 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
6904
6905 /* DS parameter set */
6906 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
6907
6908 #ifdef CONFIG_IOCTL_CFG80211
6909 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
6910 if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
6911 /* WPS IE */
6912 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
6913 pktlen += pmlmepriv->wps_probe_resp_ie_len;
6914 pframe += pmlmepriv->wps_probe_resp_ie_len;
6915
6916 /* P2P IE */
6917 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
6918 pktlen += pmlmepriv->p2p_probe_resp_ie_len;
6919 pframe += pmlmepriv->p2p_probe_resp_ie_len;
6920 }
6921 } else
6922 #endif /* CONFIG_IOCTL_CFG80211 */
6923 {
6924
6925 /* Todo: WPS IE */
6926 /* Noted by Albert 20100907 */
6927 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6928
6929 wpsielen = 0;
6930 /* WPS OUI */
6931 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6932 wpsielen += 4;
6933
6934 /* WPS version */
6935 /* Type: */
6936 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6937 wpsielen += 2;
6938
6939 /* Length: */
6940 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6941 wpsielen += 2;
6942
6943 /* Value: */
6944 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
6945
6946 /* WiFi Simple Config State */
6947 /* Type: */
6948 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
6949 wpsielen += 2;
6950
6951 /* Length: */
6952 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6953 wpsielen += 2;
6954
6955 /* Value: */
6956 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
6957
6958 /* Response Type */
6959 /* Type: */
6960 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
6961 wpsielen += 2;
6962
6963 /* Length: */
6964 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6965 wpsielen += 2;
6966
6967 /* Value: */
6968 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
6969
6970 /* UUID-E */
6971 /* Type: */
6972 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6973 wpsielen += 2;
6974
6975 /* Length: */
6976 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6977 wpsielen += 2;
6978
6979 /* Value: */
6980 if (pwdinfo->external_uuid == 0) {
6981 _rtw_memset(wpsie + wpsielen, 0x0, 16);
6982 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6983 } else
6984 _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6985 wpsielen += 0x10;
6986
6987 /* Manufacturer */
6988 /* Type: */
6989 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
6990 wpsielen += 2;
6991
6992 /* Length: */
6993 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
6994 wpsielen += 2;
6995
6996 /* Value: */
6997 _rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
6998 wpsielen += 7;
6999
7000 /* Model Name */
7001 /* Type: */
7002 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
7003 wpsielen += 2;
7004
7005 /* Length: */
7006 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
7007 wpsielen += 2;
7008
7009 /* Value: */
7010 _rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
7011 wpsielen += 6;
7012
7013 /* Model Number */
7014 /* Type: */
7015 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
7016 wpsielen += 2;
7017
7018 /* Length: */
7019 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7020 wpsielen += 2;
7021
7022 /* Value: */
7023 wpsie[wpsielen++] = 0x31; /* character 1 */
7024
7025 /* Serial Number */
7026 /* Type: */
7027 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
7028 wpsielen += 2;
7029
7030 /* Length: */
7031 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
7032 wpsielen += 2;
7033
7034 /* Value: */
7035 _rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
7036 wpsielen += ETH_ALEN;
7037
7038 /* Primary Device Type */
7039 /* Type: */
7040 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
7041 wpsielen += 2;
7042
7043 /* Length: */
7044 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
7045 wpsielen += 2;
7046
7047 /* Value: */
7048 /* Category ID */
7049 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7050 wpsielen += 2;
7051
7052 /* OUI */
7053 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
7054 wpsielen += 4;
7055
7056 /* Sub Category ID */
7057 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7058 wpsielen += 2;
7059
7060 /* Device Name */
7061 /* Type: */
7062 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7063 wpsielen += 2;
7064
7065 /* Length: */
7066 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
7067 wpsielen += 2;
7068
7069 /* Value: */
7070 _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
7071 wpsielen += pwdinfo->device_name_len;
7072
7073 /* Config Method */
7074 /* Type: */
7075 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
7076 wpsielen += 2;
7077
7078 /* Length: */
7079 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7080 wpsielen += 2;
7081
7082 /* Value: */
7083 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7084 wpsielen += 2;
7085
7086
7087 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7088
7089
7090 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
7091 pframe += p2pielen;
7092 pktlen += p2pielen;
7093 }
7094
7095 #ifdef CONFIG_WFD
7096 wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
7097 pframe += wfdielen;
7098 pktlen += wfdielen;
7099 #endif
7100
7101 *pLength = pktlen;
7102
7103 #if 0
7104 /* printf dbg msg */
7105 dbgbufLen = pktlen;
7106 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7107
7108 for (index = 0; index < dbgbufLen; index++)
7109 printk("%x ", *(dbgbuf + index));
7110
7111 printk("\n");
7112 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
7113 #endif
7114 }
rtw_hal_construct_P2PNegoRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7115 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7116 {
7117 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7118 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7119 u8 action = P2P_PUB_ACTION_ACTION;
7120 u32 p2poui = cpu_to_be32(P2POUI);
7121 u8 oui_subtype = P2P_GO_NEGO_RESP;
7122 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
7123 u8 p2pielen = 0, i;
7124 uint wpsielen = 0;
7125 u16 wps_devicepassword_id = 0x0000;
7126 uint wps_devicepassword_id_len = 0;
7127 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
7128 u16 len_channellist_attr = 0;
7129 u32 pktlen;
7130 u8 dialogToken = 0;
7131
7132 /* struct xmit_frame *pmgntframe; */
7133 /* struct pkt_attrib *pattrib; */
7134 /* unsigned char *pframe; */
7135 struct rtw_ieee80211_hdr *pwlanhdr;
7136 unsigned short *fctrl;
7137 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7138 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7139 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7140 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7141 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
7142
7143 #ifdef CONFIG_WFD
7144 u32 wfdielen = 0;
7145 #endif
7146
7147 /* for debug */
7148 u8 *dbgbuf = pframe;
7149 u8 dbgbufLen = 0, index = 0;
7150
7151 RTW_INFO("%s\n", __FUNCTION__);
7152 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7153
7154 fctrl = &(pwlanhdr->frame_ctl);
7155 *(fctrl) = 0;
7156
7157 /* RA, filled by FW */
7158 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7159 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7160 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7161
7162 SetSeqNum(pwlanhdr, 0);
7163 set_frame_sub_type(pframe, WIFI_ACTION);
7164
7165 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7166 pframe += pktlen;
7167
7168 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7169 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7170 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7171 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7172
7173 /* dialog token, filled by FW */
7174 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7175
7176 _rtw_memset(wpsie, 0x00, 255);
7177 wpsielen = 0;
7178
7179 /* WPS Section */
7180 wpsielen = 0;
7181 /* WPS OUI */
7182 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
7183 wpsielen += 4;
7184
7185 /* WPS version */
7186 /* Type: */
7187 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7188 wpsielen += 2;
7189
7190 /* Length: */
7191 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7192 wpsielen += 2;
7193
7194 /* Value: */
7195 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7196
7197 /* Device Password ID */
7198 /* Type: */
7199 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
7200 wpsielen += 2;
7201
7202 /* Length: */
7203 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
7204 wpsielen += 2;
7205
7206 /* Value: */
7207 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
7208 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
7209 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
7210 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
7211 else
7212 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
7213 wpsielen += 2;
7214
7215 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7216
7217
7218 /* P2P IE Section. */
7219
7220 /* P2P OUI */
7221 p2pielen = 0;
7222 p2pie[p2pielen++] = 0x50;
7223 p2pie[p2pielen++] = 0x6F;
7224 p2pie[p2pielen++] = 0x9A;
7225 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7226
7227 /* Commented by Albert 20100908 */
7228 /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
7229 /* 1. Status */
7230 /* 2. P2P Capability */
7231 /* 3. Group Owner Intent */
7232 /* 4. Configuration Timeout */
7233 /* 5. Operating Channel */
7234 /* 6. Intended P2P Interface Address */
7235 /* 7. Channel List */
7236 /* 8. Device Info */
7237 /* 9. Group ID ( Only GO ) */
7238
7239
7240 /* ToDo: */
7241
7242 /* P2P Status */
7243 /* Type: */
7244 p2pie[p2pielen++] = P2P_ATTR_STATUS;
7245
7246 /* Length: */
7247 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7248 p2pielen += 2;
7249
7250 /* Value, filled by FW */
7251 p2pie[p2pielen++] = 1;
7252
7253 /* P2P Capability */
7254 /* Type: */
7255 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
7256
7257 /* Length: */
7258 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7259 p2pielen += 2;
7260
7261 /* Value: */
7262 /* Device Capability Bitmap, 1 byte */
7263
7264 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
7265 /* Commented by Albert 2011/03/08 */
7266 /* According to the P2P specification */
7267 /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
7268 p2pie[p2pielen++] = 0;
7269 } else {
7270 /* Be group owner or meet the error case */
7271 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
7272 }
7273
7274 /* Group Capability Bitmap, 1 byte */
7275 if (pwdinfo->persistent_supported)
7276 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
7277 else
7278 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
7279
7280 /* Group Owner Intent */
7281 /* Type: */
7282 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
7283
7284 /* Length: */
7285 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7286 p2pielen += 2;
7287
7288 /* Value: */
7289 if (pwdinfo->peer_intent & 0x01) {
7290 /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
7291 p2pie[p2pielen++] = (pwdinfo->intent << 1);
7292 } else {
7293 /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
7294 p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
7295 }
7296
7297
7298 /* Configuration Timeout */
7299 /* Type: */
7300 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7301
7302 /* Length: */
7303 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7304 p2pielen += 2;
7305
7306 /* Value: */
7307 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7308 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7309
7310 /* Operating Channel */
7311 /* Type: */
7312 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7313
7314 /* Length: */
7315 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7316 p2pielen += 2;
7317
7318 /* Value: */
7319 /* Country String */
7320 p2pie[p2pielen++] = 'X';
7321 p2pie[p2pielen++] = 'X';
7322
7323 /* The third byte should be set to 0x04. */
7324 /* Described in the "Operating Channel Attribute" section. */
7325 p2pie[p2pielen++] = 0x04;
7326
7327 /* Operating Class */
7328 if (pwdinfo->operating_channel <= 14) {
7329 /* Operating Class */
7330 p2pie[p2pielen++] = 0x51;
7331 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
7332 /* Operating Class */
7333 p2pie[p2pielen++] = 0x73;
7334 } else {
7335 /* Operating Class */
7336 p2pie[p2pielen++] = 0x7c;
7337 }
7338
7339 /* Channel Number */
7340 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7341
7342 /* Intended P2P Interface Address */
7343 /* Type: */
7344 p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
7345
7346 /* Length: */
7347 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7348 p2pielen += 2;
7349
7350 /* Value: */
7351 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7352 p2pielen += ETH_ALEN;
7353
7354 /* Channel List */
7355 /* Type: */
7356 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7357
7358 /* Country String(3) */
7359 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7360 /* + number of channels in all classes */
7361 len_channellist_attr = 3
7362 + (1 + 1) * (u16)ch_list->reg_classes
7363 + get_reg_classes_full_count(ch_list);
7364
7365 #ifdef CONFIG_CONCURRENT_MODE
7366 if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7367 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7368 else
7369 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7370
7371 #else
7372
7373 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7374
7375 #endif
7376 p2pielen += 2;
7377
7378 /* Value: */
7379 /* Country String */
7380 p2pie[p2pielen++] = 'X';
7381 p2pie[p2pielen++] = 'X';
7382
7383 /* The third byte should be set to 0x04. */
7384 /* Described in the "Operating Channel Attribute" section. */
7385 p2pie[p2pielen++] = 0x04;
7386
7387 /* Channel Entry List */
7388
7389 #ifdef CONFIG_CONCURRENT_MODE
7390 if (rtw_mi_check_status(padapter, MI_LINKED)) {
7391 u8 union_ch = rtw_mi_get_union_chan(padapter);
7392
7393 /* Operating Class */
7394 if (union_ch > 14) {
7395 if (union_ch >= 149)
7396 p2pie[p2pielen++] = 0x7c;
7397 else
7398 p2pie[p2pielen++] = 0x73;
7399 } else
7400 p2pie[p2pielen++] = 0x51;
7401
7402
7403 /* Number of Channels */
7404 /* Just support 1 channel and this channel is AP's channel */
7405 p2pie[p2pielen++] = 1;
7406
7407 /* Channel List */
7408 p2pie[p2pielen++] = union_ch;
7409 } else
7410 #endif /* CONFIG_CONCURRENT_MODE */
7411 {
7412 int i, j;
7413 for (j = 0; j < ch_list->reg_classes; j++) {
7414 /* Operating Class */
7415 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7416
7417 /* Number of Channels */
7418 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7419
7420 /* Channel List */
7421 for (i = 0; i < ch_list->reg_class[j].channels; i++)
7422 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7423 }
7424 }
7425
7426 /* Device Info */
7427 /* Type: */
7428 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
7429
7430 /* Length: */
7431 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
7432 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7433 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
7434 p2pielen += 2;
7435
7436 /* Value: */
7437 /* P2P Device Address */
7438 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7439 p2pielen += ETH_ALEN;
7440
7441 /* Config Method */
7442 /* This field should be big endian. Noted by P2P specification. */
7443
7444 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
7445
7446 p2pielen += 2;
7447
7448 /* Primary Device Type */
7449 /* Category ID */
7450 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7451 p2pielen += 2;
7452
7453 /* OUI */
7454 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
7455 p2pielen += 4;
7456
7457 /* Sub Category ID */
7458 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7459 p2pielen += 2;
7460
7461 /* Number of Secondary Device Types */
7462 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
7463
7464 /* Device Name */
7465 /* Type: */
7466 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7467 p2pielen += 2;
7468
7469 /* Length: */
7470 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
7471 p2pielen += 2;
7472
7473 /* Value: */
7474 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
7475 p2pielen += pwdinfo->device_name_len;
7476
7477 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7478 /* Group ID Attribute */
7479 /* Type: */
7480 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
7481
7482 /* Length: */
7483 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
7484 p2pielen += 2;
7485
7486 /* Value: */
7487 /* p2P Device Address */
7488 _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
7489 p2pielen += ETH_ALEN;
7490
7491 /* SSID */
7492 _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
7493 p2pielen += pwdinfo->nego_ssidlen;
7494
7495 }
7496
7497 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7498
7499 #ifdef CONFIG_WFD
7500 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
7501 pframe += wfdielen;
7502 pktlen += wfdielen;
7503 #endif
7504
7505 *pLength = pktlen;
7506 #if 0
7507 /* printf dbg msg */
7508 dbgbufLen = pktlen;
7509 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7510
7511 for (index = 0; index < dbgbufLen; index++)
7512 printk("%x ", *(dbgbuf + index));
7513
7514 printk("\n");
7515 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
7516 #endif
7517 }
7518
rtw_hal_construct_P2PInviteRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7519 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7520 {
7521 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7522 u8 action = P2P_PUB_ACTION_ACTION;
7523 u32 p2poui = cpu_to_be32(P2POUI);
7524 u8 oui_subtype = P2P_INVIT_RESP;
7525 u8 p2pie[255] = { 0x00 };
7526 u8 p2pielen = 0, i;
7527 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
7528 u16 len_channellist_attr = 0;
7529 u32 pktlen;
7530 u8 dialogToken = 0;
7531 #ifdef CONFIG_WFD
7532 u32 wfdielen = 0;
7533 #endif
7534
7535 /* struct xmit_frame *pmgntframe; */
7536 /* struct pkt_attrib *pattrib; */
7537 /* unsigned char *pframe; */
7538 struct rtw_ieee80211_hdr *pwlanhdr;
7539 unsigned short *fctrl;
7540 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7541 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7542 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7543 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7544
7545 /* for debug */
7546 u8 *dbgbuf = pframe;
7547 u8 dbgbufLen = 0, index = 0;
7548
7549
7550 RTW_INFO("%s\n", __FUNCTION__);
7551 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7552
7553 fctrl = &(pwlanhdr->frame_ctl);
7554 *(fctrl) = 0;
7555
7556 /* RA fill by FW */
7557 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7558 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7559
7560 /* BSSID fill by FW */
7561 _rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
7562
7563 SetSeqNum(pwlanhdr, 0);
7564 set_frame_sub_type(pframe, WIFI_ACTION);
7565
7566 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7567 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7568
7569 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7570 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7571 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7572 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7573
7574 /* dialog token, filled by FW */
7575 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7576
7577 /* P2P IE Section. */
7578
7579 /* P2P OUI */
7580 p2pielen = 0;
7581 p2pie[p2pielen++] = 0x50;
7582 p2pie[p2pielen++] = 0x6F;
7583 p2pie[p2pielen++] = 0x9A;
7584 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
7585
7586 /* Commented by Albert 20101005 */
7587 /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
7588 /* 1. Status */
7589 /* 2. Configuration Timeout */
7590 /* 3. Operating Channel ( Only GO ) */
7591 /* 4. P2P Group BSSID ( Only GO ) */
7592 /* 5. Channel List */
7593
7594 /* P2P Status */
7595 /* Type: */
7596 p2pie[p2pielen++] = P2P_ATTR_STATUS;
7597
7598 /* Length: */
7599 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
7600 p2pielen += 2;
7601
7602 /* Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
7603 p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
7604
7605 /* Configuration Timeout */
7606 /* Type: */
7607 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
7608
7609 /* Length: */
7610 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
7611 p2pielen += 2;
7612
7613 /* Value: */
7614 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
7615 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
7616
7617 /* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
7618 #if 0
7619 if (status_code == P2P_STATUS_SUCCESS) {
7620 struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
7621
7622 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7623 /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
7624 /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
7625 /* First one is operating channel attribute. */
7626 /* Second one is P2P Group BSSID attribute. */
7627
7628 /* Operating Channel */
7629 /* Type: */
7630 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
7631
7632 /* Length: */
7633 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
7634 p2pielen += 2;
7635
7636 /* Value: */
7637 /* Country String */
7638 p2pie[p2pielen++] = 'X';
7639 p2pie[p2pielen++] = 'X';
7640
7641 /* The third byte should be set to 0x04. */
7642 /* Described in the "Operating Channel Attribute" section. */
7643 p2pie[p2pielen++] = 0x04;
7644
7645 /* Operating Class */
7646 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
7647
7648 /* Channel Number */
7649 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
7650
7651
7652 /* P2P Group BSSID */
7653 /* Type: */
7654 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
7655
7656 /* Length: */
7657 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
7658 p2pielen += 2;
7659
7660 /* Value: */
7661 /* P2P Device Address for GO */
7662 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
7663 p2pielen += ETH_ALEN;
7664
7665 }
7666
7667 /* Channel List */
7668 /* Type: */
7669 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
7670
7671 /* Length: */
7672 /* Country String(3) */
7673 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
7674 /* + number of channels in all classes */
7675 len_channellist_attr = 3
7676 + (1 + 1) * (u16)ch_list->reg_classes
7677 + get_reg_classes_full_count(ch_list);
7678
7679 #ifdef CONFIG_CONCURRENT_MODE
7680 if (rtw_mi_check_status(padapter, MI_LINKED))
7681 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
7682 else
7683 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7684
7685 #else
7686
7687 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
7688
7689 #endif
7690 p2pielen += 2;
7691
7692 /* Value: */
7693 /* Country String */
7694 p2pie[p2pielen++] = 'X';
7695 p2pie[p2pielen++] = 'X';
7696
7697 /* The third byte should be set to 0x04. */
7698 /* Described in the "Operating Channel Attribute" section. */
7699 p2pie[p2pielen++] = 0x04;
7700
7701 /* Channel Entry List */
7702 #ifdef CONFIG_CONCURRENT_MODE
7703 if (rtw_mi_check_status(padapter, MI_LINKED)) {
7704 u8 union_ch = rtw_mi_get_union_chan(padapter);
7705
7706 /* Operating Class */
7707 if (union_ch > 14) {
7708 if (union_ch >= 149)
7709 p2pie[p2pielen++] = 0x7c;
7710 else
7711 p2pie[p2pielen++] = 0x73;
7712
7713 } else
7714 p2pie[p2pielen++] = 0x51;
7715
7716
7717 /* Number of Channels */
7718 /* Just support 1 channel and this channel is AP's channel */
7719 p2pie[p2pielen++] = 1;
7720
7721 /* Channel List */
7722 p2pie[p2pielen++] = union_ch;
7723 } else
7724 #endif /* CONFIG_CONCURRENT_MODE */
7725 {
7726 int i, j;
7727 for (j = 0; j < ch_list->reg_classes; j++) {
7728 /* Operating Class */
7729 p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
7730
7731 /* Number of Channels */
7732 p2pie[p2pielen++] = ch_list->reg_class[j].channels;
7733
7734 /* Channel List */
7735 for (i = 0; i < ch_list->reg_class[j].channels; i++)
7736 p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
7737 }
7738 }
7739 }
7740 #endif
7741
7742 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
7743
7744 #ifdef CONFIG_WFD
7745 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
7746 pframe += wfdielen;
7747 pktlen += wfdielen;
7748 #endif
7749
7750 *pLength = pktlen;
7751
7752 #if 0
7753 /* printf dbg msg */
7754 dbgbufLen = pktlen;
7755 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7756
7757 for (index = 0; index < dbgbufLen; index++)
7758 printk("%x ", *(dbgbuf + index));
7759
7760 printk("\n");
7761 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
7762 #endif
7763 }
7764
7765
rtw_hal_construct_P2PProvisionDisRsp(_adapter * padapter,u8 * pframe,u32 * pLength)7766 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
7767 {
7768 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
7769 u8 action = P2P_PUB_ACTION_ACTION;
7770 u8 dialogToken = 0;
7771 u32 p2poui = cpu_to_be32(P2POUI);
7772 u8 oui_subtype = P2P_PROVISION_DISC_RESP;
7773 u8 wpsie[100] = { 0x00 };
7774 u8 wpsielen = 0;
7775 u32 pktlen;
7776 #ifdef CONFIG_WFD
7777 u32 wfdielen = 0;
7778 #endif
7779
7780 /* struct xmit_frame *pmgntframe; */
7781 /* struct pkt_attrib *pattrib; */
7782 /* unsigned char *pframe; */
7783 struct rtw_ieee80211_hdr *pwlanhdr;
7784 unsigned short *fctrl;
7785 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7786 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7787 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7788 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7789
7790 /* for debug */
7791 u8 *dbgbuf = pframe;
7792 u8 dbgbufLen = 0, index = 0;
7793
7794 RTW_INFO("%s\n", __FUNCTION__);
7795
7796 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7797
7798 fctrl = &(pwlanhdr->frame_ctl);
7799 *(fctrl) = 0;
7800
7801 /* RA filled by FW */
7802 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
7803 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7804 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
7805
7806 SetSeqNum(pwlanhdr, 0);
7807 set_frame_sub_type(pframe, WIFI_ACTION);
7808
7809 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7810 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7811
7812 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
7813 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
7814 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
7815 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
7816 /* dialog token, filled by FW */
7817 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
7818
7819 wpsielen = 0;
7820 /* WPS OUI */
7821 /* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
7822 RTW_PUT_BE32(wpsie, WPSOUI);
7823 wpsielen += 4;
7824
7825 #if 0
7826 /* WPS version */
7827 /* Type: */
7828 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
7829 wpsielen += 2;
7830
7831 /* Length: */
7832 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
7833 wpsielen += 2;
7834
7835 /* Value: */
7836 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
7837 #endif
7838
7839 /* Config Method */
7840 /* Type: */
7841 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
7842 RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
7843 wpsielen += 2;
7844
7845 /* Length: */
7846 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
7847 RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
7848 wpsielen += 2;
7849
7850 /* Value: filled by FW, default value is PBC */
7851 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
7852 RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
7853 wpsielen += 2;
7854
7855 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
7856
7857 #ifdef CONFIG_WFD
7858 wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
7859 pframe += wfdielen;
7860 pktlen += wfdielen;
7861 #endif
7862
7863 *pLength = pktlen;
7864
7865 /* printf dbg msg */
7866 #if 0
7867 dbgbufLen = pktlen;
7868 RTW_INFO("======> DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7869
7870 for (index = 0; index < dbgbufLen; index++)
7871 printk("%x ", *(dbgbuf + index));
7872
7873 printk("\n");
7874 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
7875 #endif
7876 }
7877
rtw_hal_set_FwP2PRsvdPage_cmd(_adapter * adapter,PRSVDPAGE_LOC rsvdpageloc)7878 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
7879 {
7880 u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
7881 struct hal_ops *pHalFunc = &adapter->hal_func;
7882 u8 ret = _FAIL;
7883
7884 RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
7885 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
7886 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
7887 rsvdpageloc->LocPDRsp);
7888
7889 SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
7890 SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
7891 SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
7892 SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
7893 SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
7894
7895 /* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
7896 ret = rtw_hal_fill_h2c_cmd(adapter,
7897 H2C_P2P_OFFLOAD_RSVD_PAGE,
7898 H2C_P2PRSVDPAGE_LOC_LEN,
7899 u1H2CP2PRsvdPageParm);
7900
7901 return ret;
7902 }
7903
rtw_hal_set_p2p_wowlan_offload_cmd(_adapter * adapter)7904 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
7905 {
7906
7907 u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
7908 struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
7909 struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
7910 struct hal_ops *pHalFunc = &adapter->hal_func;
7911 u8 ret = _FAIL;
7912
7913 _rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
7914 RTW_INFO("%s\n", __func__);
7915 switch (pwdinfo->role) {
7916 case P2P_ROLE_DEVICE:
7917 RTW_INFO("P2P_ROLE_DEVICE\n");
7918 p2p_wowlan_offload->role = 0;
7919 break;
7920 case P2P_ROLE_CLIENT:
7921 RTW_INFO("P2P_ROLE_CLIENT\n");
7922 p2p_wowlan_offload->role = 1;
7923 break;
7924 case P2P_ROLE_GO:
7925 RTW_INFO("P2P_ROLE_GO\n");
7926 p2p_wowlan_offload->role = 2;
7927 break;
7928 default:
7929 RTW_INFO("P2P_ROLE_DISABLE\n");
7930 break;
7931 }
7932 p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
7933 p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
7934 offload_cmd = (u8 *)p2p_wowlan_offload;
7935 RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
7936
7937 ret = rtw_hal_fill_h2c_cmd(adapter,
7938 H2C_P2P_OFFLOAD,
7939 H2C_P2P_OFFLOAD_LEN,
7940 offload_cmd);
7941 return ret;
7942
7943 /* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
7944 }
7945 #endif /* CONFIG_P2P_WOWLAN */
7946
rtw_hal_construct_beacon(_adapter * padapter,u8 * pframe,u32 * pLength)7947 void rtw_hal_construct_beacon(_adapter *padapter,
7948 u8 *pframe, u32 *pLength)
7949 {
7950 struct rtw_ieee80211_hdr *pwlanhdr;
7951 u16 *fctrl;
7952 u32 pktlen;
7953 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7954 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7955 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7956 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7957
7958
7959 /* RTW_INFO("%s\n", __FUNCTION__); */
7960
7961 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7962
7963 fctrl = &(pwlanhdr->frame_ctl);
7964 *(fctrl) = 0;
7965
7966 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7967 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7968 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7969
7970 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7971 /* pmlmeext->mgnt_seq++; */
7972 set_frame_sub_type(pframe, WIFI_BEACON);
7973
7974 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7975 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7976
7977 /* timestamp will be inserted by hardware */
7978 pframe += 8;
7979 pktlen += 8;
7980
7981 /* beacon interval: 2 bytes */
7982 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7983
7984 pframe += 2;
7985 pktlen += 2;
7986
7987 #if 0
7988 /* capability info: 2 bytes */
7989 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7990
7991 pframe += 2;
7992 pktlen += 2;
7993
7994 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7995 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7996 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
7997 _rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
7998
7999 goto _ConstructBeacon;
8000 }
8001
8002 /* below for ad-hoc mode */
8003
8004 /* SSID */
8005 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
8006
8007 /* supported rates... */
8008 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
8009 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
8010
8011 /* DS parameter set */
8012 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
8013
8014 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
8015 u32 ATIMWindow;
8016 /* IBSS Parameter Set... */
8017 /* ATIMWindow = cur->Configuration.ATIMWindow; */
8018 ATIMWindow = 0;
8019 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
8020 }
8021
8022
8023 /* todo: ERP IE */
8024
8025
8026 /* EXTERNDED SUPPORTED RATE */
8027 if (rate_len > 8)
8028 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
8029
8030 /* todo:HT for adhoc */
8031
8032 _ConstructBeacon:
8033 #endif
8034
8035 if ((pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
8036 RTW_ERR("beacon frame too large ,len(%d,%d)\n",
8037 (pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
8038 rtw_warn_on(1);
8039 return;
8040 }
8041
8042 *pLength = pktlen;
8043
8044 /* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
8045
8046 }
8047
rtw_hal_construct_PSPoll(_adapter * padapter,u8 * pframe,u32 * pLength)8048 static void rtw_hal_construct_PSPoll(_adapter *padapter,
8049 u8 *pframe, u32 *pLength)
8050 {
8051 struct rtw_ieee80211_hdr *pwlanhdr;
8052 u16 *fctrl;
8053 u32 pktlen;
8054 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8055 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8056
8057 /* RTW_INFO("%s\n", __FUNCTION__); */
8058
8059 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8060
8061 /* Frame control. */
8062 fctrl = &(pwlanhdr->frame_ctl);
8063 *(fctrl) = 0;
8064 SetPwrMgt(fctrl);
8065 set_frame_sub_type(pframe, WIFI_PSPOLL);
8066
8067 /* AID. */
8068 set_duration(pframe, (pmlmeinfo->aid | 0xc000));
8069
8070 /* BSSID. */
8071 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8072
8073 /* TA. */
8074 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8075
8076 *pLength = 16;
8077 }
8078
8079
8080 #ifdef DBG_FW_DEBUG_MSG_PKT
rtw_hal_construct_fw_dbg_msg_pkt(PADAPTER padapter,u8 * pframe,u32 * plength)8081 void rtw_hal_construct_fw_dbg_msg_pkt(
8082 PADAPTER padapter,
8083 u8 *pframe,
8084 u32 *plength)
8085 {
8086 struct rtw_ieee80211_hdr *pwlanhdr;
8087 u16 *fctrl;
8088 u32 pktlen;
8089 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8090 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8091 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8092 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8093 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8094
8095
8096 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8097
8098 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8099
8100 fctrl = &pwlanhdr->frame_ctl;
8101 *(fctrl) = 0;
8102
8103 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8104 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8105 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8106
8107 SetSeqNum(pwlanhdr, 0);
8108
8109 set_frame_sub_type(pframe, WIFI_DATA);
8110
8111 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8112
8113 *plength = pktlen;
8114 }
8115 #endif /*DBG_FW_DEBUG_MSG_PKT*/
8116
rtw_hal_construct_NullFunctionData(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 bQoS,u8 AC,u8 bEosp,u8 bForcePowerSave)8117 void rtw_hal_construct_NullFunctionData(
8118 PADAPTER padapter,
8119 u8 *pframe,
8120 u32 *pLength,
8121 u8 bQoS,
8122 u8 AC,
8123 u8 bEosp,
8124 u8 bForcePowerSave)
8125 {
8126 struct rtw_ieee80211_hdr *pwlanhdr;
8127 u16 *fctrl;
8128 u32 pktlen;
8129 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8130 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8131 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8132 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8133 u8 *sta_addr = NULL;
8134 u8 bssid[ETH_ALEN] = {0};
8135
8136 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8137
8138 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8139
8140 fctrl = &pwlanhdr->frame_ctl;
8141 *(fctrl) = 0;
8142 if (bForcePowerSave)
8143 SetPwrMgt(fctrl);
8144
8145 sta_addr = get_my_bssid(&pmlmeinfo->network);
8146 if (NULL == sta_addr) {
8147 _rtw_memcpy(bssid, adapter_mac_addr(padapter), ETH_ALEN);
8148 sta_addr = bssid;
8149 }
8150
8151 switch (cur_network->network.InfrastructureMode) {
8152 case Ndis802_11Infrastructure:
8153 SetToDs(fctrl);
8154 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8155 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8156 _rtw_memcpy(pwlanhdr->addr3, sta_addr, ETH_ALEN);
8157 break;
8158 case Ndis802_11APMode:
8159 SetFrDs(fctrl);
8160 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8161 _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8162 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8163 break;
8164 case Ndis802_11IBSS:
8165 default:
8166 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8167 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8168 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8169 break;
8170 }
8171
8172 SetSeqNum(pwlanhdr, 0);
8173 set_duration(pwlanhdr, 0);
8174
8175 if (bQoS == _TRUE) {
8176 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
8177
8178 set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
8179
8180 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
8181 SetPriority(&pwlanqoshdr->qc, AC);
8182 SetEOSP(&pwlanqoshdr->qc, bEosp);
8183
8184 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
8185 } else {
8186 set_frame_sub_type(pframe, WIFI_DATA_NULL);
8187
8188 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8189 }
8190
8191 *pLength = pktlen;
8192 }
8193
rtw_hal_construct_ProbeRsp(_adapter * padapter,u8 * pframe,u32 * pLength,BOOLEAN bHideSSID)8194 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
8195 BOOLEAN bHideSSID)
8196 {
8197 struct rtw_ieee80211_hdr *pwlanhdr;
8198 u16 *fctrl;
8199 u8 *mac, *bssid, *sta_addr;
8200 u32 pktlen;
8201 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8202 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8203 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
8204
8205 /*RTW_INFO("%s\n", __FUNCTION__);*/
8206
8207 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8208
8209 mac = adapter_mac_addr(padapter);
8210 bssid = cur_network->MacAddress;
8211 sta_addr = get_my_bssid(&pmlmeinfo->network);
8212
8213 fctrl = &(pwlanhdr->frame_ctl);
8214 *(fctrl) = 0;
8215 _rtw_memcpy(pwlanhdr->addr1, sta_addr, ETH_ALEN);
8216 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8217 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8218
8219 SetSeqNum(pwlanhdr, 0);
8220 set_frame_sub_type(fctrl, WIFI_PROBERSP);
8221
8222 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8223 pframe += pktlen;
8224
8225 if (cur_network->IELength > MAX_IE_SZ)
8226 return;
8227
8228 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8229 pframe += cur_network->IELength;
8230 pktlen += cur_network->IELength;
8231
8232 *pLength = pktlen;
8233 }
8234
8235 #ifdef CONFIG_WOWLAN
rtw_hal_append_tkip_mic(PADAPTER padapter,u8 * pframe,u32 offset)8236 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
8237 u8 *pframe, u32 offset)
8238 {
8239 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8240 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8241 struct rtw_ieee80211_hdr *pwlanhdr;
8242 struct mic_data micdata;
8243 struct sta_info *psta = NULL;
8244 int res = 0;
8245
8246 u8 *payload = (u8 *)(pframe + offset);
8247
8248 u8 mic[8];
8249 u8 priority[4] = {0x0};
8250 u8 null_key[16] = {0x0};
8251
8252 RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
8253
8254 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8255
8256 psta = rtw_get_stainfo(&padapter->stapriv,
8257 get_my_bssid(&(pmlmeinfo->network)));
8258 if (psta != NULL) {
8259 res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
8260 null_key, 16);
8261 if (res == _TRUE)
8262 RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
8263 rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
8264 }
8265
8266 rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); /* DA */
8267
8268 rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
8269
8270 priority[0] = 0;
8271
8272 rtw_secmicappend(&micdata, &priority[0], 4);
8273
8274 rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
8275
8276 rtw_secgetmic(&micdata, &(mic[0]));
8277
8278 payload += 36;
8279
8280 _rtw_memcpy(payload, &(mic[0]), 8);
8281 }
8282 /*
8283 * Description:
8284 * Construct the ARP response packet to support ARP offload.
8285 * */
rtw_hal_construct_ARPRsp(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8286 static void rtw_hal_construct_ARPRsp(
8287 PADAPTER padapter,
8288 u8 *pframe,
8289 u32 *pLength,
8290 u8 *pIPAddress
8291 )
8292 {
8293 struct rtw_ieee80211_hdr *pwlanhdr;
8294 u16 *fctrl;
8295 u32 pktlen;
8296 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8297 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8298 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8299 struct security_priv *psecuritypriv = &padapter->securitypriv;
8300 static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
8301 u8 *pARPRspPkt = pframe;
8302 /* for TKIP Cal MIC */
8303 u8 *payload = pframe;
8304 u8 EncryptionHeadOverhead = 0, arp_offset = 0;
8305 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8306
8307 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8308
8309 fctrl = &pwlanhdr->frame_ctl;
8310 *(fctrl) = 0;
8311
8312 /* ------------------------------------------------------------------------- */
8313 /* MAC Header. */
8314 /* ------------------------------------------------------------------------- */
8315 SetFrameType(fctrl, WIFI_DATA);
8316 /* set_frame_sub_type(fctrl, 0); */
8317 SetToDs(fctrl);
8318 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8319 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8320 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8321
8322 SetSeqNum(pwlanhdr, 0);
8323 set_duration(pwlanhdr, 0);
8324 /* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
8325 /* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
8326 /* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
8327 /* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
8328 /* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
8329 /* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
8330
8331 /* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
8332 /* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
8333 #ifdef CONFIG_WAPI_SUPPORT
8334 *pLength = sMacHdrLng;
8335 #else
8336 *pLength = 24;
8337 #endif
8338 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8339 case _WEP40_:
8340 case _WEP104_:
8341 EncryptionHeadOverhead = 4;
8342 break;
8343 case _TKIP_:
8344 EncryptionHeadOverhead = 8;
8345 break;
8346 case _AES_:
8347 EncryptionHeadOverhead = 8;
8348 break;
8349 #ifdef CONFIG_WAPI_SUPPORT
8350 case _SMS4_:
8351 EncryptionHeadOverhead = 18;
8352 break;
8353 #endif
8354 default:
8355 EncryptionHeadOverhead = 0;
8356 }
8357
8358 if (EncryptionHeadOverhead > 0) {
8359 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8360 *pLength += EncryptionHeadOverhead;
8361 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8362 SetPrivacy(fctrl);
8363 }
8364
8365 /* ------------------------------------------------------------------------- */
8366 /* Frame Body. */
8367 /* ------------------------------------------------------------------------- */
8368 arp_offset = *pLength;
8369 pARPRspPkt = (u8 *)(pframe + arp_offset);
8370 payload = pARPRspPkt; /* Get Payload pointer */
8371 /* LLC header */
8372 _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
8373 *pLength += 8;
8374
8375 /* ARP element */
8376 pARPRspPkt += 8;
8377 SET_ARP_HTYPE(pARPRspPkt, 1);
8378 SET_ARP_PTYPE(pARPRspPkt, ETH_P_IP); /* IP protocol */
8379 SET_ARP_HLEN(pARPRspPkt, ETH_ALEN);
8380 SET_ARP_PLEN(pARPRspPkt, RTW_IP_ADDR_LEN);
8381 SET_ARP_OPER(pARPRspPkt, 2); /* ARP response */
8382 SET_ARP_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
8383 SET_ARP_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
8384 #ifdef CONFIG_ARP_KEEP_ALIVE
8385 if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
8386 SET_ARP_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
8387 SET_ARP_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
8388 } else
8389 #endif
8390 {
8391 SET_ARP_TARGET_MAC_ADDR(pARPRspPkt,
8392 get_my_bssid(&(pmlmeinfo->network)));
8393 SET_ARP_TARGET_IP_ADDR(pARPRspPkt,
8394 pIPAddress);
8395 RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
8396 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
8397 RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
8398 IP_ARG(pIPAddress));
8399 }
8400
8401 *pLength += 28;
8402
8403 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8404 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8405 IS_HARDWARE_TYPE_8812(padapter)) {
8406 rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
8407 }
8408 *pLength += 8;
8409 }
8410 }
8411 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
8412 /*
8413 * Description:
8414 * Construct the Keep Alive packet to support specific Keep Alive packet.
8415 * */
rtw_hal_construct_keepalive(PADAPTER padapter,u8 * pframe,u32 * pLength)8416 static void rtw_hal_construct_keepalive( PADAPTER padapter,
8417 u8 *pframe,
8418 u32 *pLength
8419 ){
8420 struct rtw_ieee80211_hdr *pwlanhdr;
8421 u16 *fctrl;
8422 u32 pktlen;
8423 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8424 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8425 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8426 struct security_priv *psecuritypriv = &padapter->securitypriv;
8427 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
8428 static u8 LLCHeader[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
8429 u8 *pKeepAlivePkt = pframe;
8430 /* for TKIP Cal MIC */
8431 u8 *payload = pframe;
8432 u8 EncryptionHeadOverhead = 0, frame_offset = 0;
8433 int i;
8434
8435 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8436
8437 fctrl = &pwlanhdr->frame_ctl;
8438 *(fctrl) = 0;
8439
8440 RTW_INFO("%s======>\n", __func__);
8441
8442
8443 /* ------------------------------------------------------------------------- */
8444 /* MAC Header. */
8445 /* ------------------------------------------------------------------------- */
8446 SetFrameType(fctrl, WIFI_DATA);
8447 /* set_frame_sub_type(fctrl, 0); */
8448 SetToDs(fctrl);
8449 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8450 _rtw_memcpy(pwlanhdr->addr2, pwrpriv->keep_alive_pattern+6, ETH_ALEN);
8451 _rtw_memcpy(pwlanhdr->addr3,pwrpriv->keep_alive_pattern, ETH_ALEN);
8452
8453 SetSeqNum(pwlanhdr, 0);
8454 set_duration(pwlanhdr, 0);
8455
8456 #ifdef CONFIG_WAPI_SUPPORT
8457 *pLength = sMacHdrLng;
8458 #else
8459 *pLength = 24;
8460 #endif
8461 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8462 case _WEP40_:
8463 case _WEP104_:
8464 EncryptionHeadOverhead = 4;
8465 break;
8466 case _TKIP_:
8467 EncryptionHeadOverhead = 8;
8468 break;
8469 case _AES_:
8470 EncryptionHeadOverhead = 8;
8471 break;
8472 #ifdef CONFIG_WAPI_SUPPORT
8473 case _SMS4_:
8474 EncryptionHeadOverhead = 18;
8475 break;
8476 #endif
8477 default:
8478 EncryptionHeadOverhead = 0;
8479 }
8480
8481 if (EncryptionHeadOverhead > 0) {
8482 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8483 *pLength += EncryptionHeadOverhead;
8484 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8485 SetPrivacy(fctrl);
8486 }
8487
8488 /* ------------------------------------------------------------------------- */
8489 /* Frame Body. */
8490 /* ------------------------------------------------------------------------- */
8491 frame_offset = *pLength;
8492 pKeepAlivePkt = (u8 *)(pframe + frame_offset);
8493 payload = pKeepAlivePkt; /* Get Payload pointer */
8494 /* LLC header */
8495 _rtw_memcpy(pKeepAlivePkt, LLCHeader, 6);
8496 *pLength += 6;
8497
8498 /*From protocol type*/
8499 pKeepAlivePkt+=6;
8500
8501 _rtw_memcpy(pKeepAlivePkt,pwrpriv->keep_alive_pattern+12,pwrpriv->keep_alive_pattern_len-12);
8502
8503 *pLength+=pwrpriv->keep_alive_pattern_len-12;
8504
8505 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8506 *pLength += 8;
8507 }
8508
8509 /* for debug
8510 for (i=0; i< (*pLength) ;i++) {
8511 RTW_INFO("KA_Pkt[0x%x]=x%0x", i,pKeepAlivePkt[i]);
8512 if((i%8) == 7)
8513 RTW_INFO("\n");
8514 }
8515 */
8516
8517 RTW_INFO("%s <======\n", __func__);
8518 }
8519
8520 #endif/*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
8521
8522 #ifdef CONFIG_IPV6
8523 /*
8524 * Description: Neighbor Discovery Offload.
8525 */
rtw_hal_construct_na_message(_adapter * padapter,u8 * pframe,u32 * pLength)8526 static void rtw_hal_construct_na_message(_adapter *padapter,
8527 u8 *pframe, u32 *pLength)
8528 {
8529 struct rtw_ieee80211_hdr *pwlanhdr = NULL;
8530 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8531 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8532 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8533 struct security_priv *psecuritypriv = &padapter->securitypriv;
8534
8535 u32 pktlen = 0;
8536 u16 *fctrl = NULL;
8537
8538 u8 ns_hdr[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
8539 u8 ipv6_info[4] = {0x60, 0x00, 0x00, 0x00};
8540 u8 ipv6_contx[4] = {0x00, 0x20, 0x3a, 0xff};
8541 u8 icmpv6_hdr[8] = {0x88, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00};
8542 u8 val8 = 0;
8543
8544 u8 *p_na_msg = pframe;
8545 /* for TKIP Cal MIC */
8546 u8 *payload = pframe;
8547 u8 EncryptionHeadOverhead = 0, na_msg_offset = 0;
8548 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
8549
8550 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8551
8552 fctrl = &pwlanhdr->frame_ctl;
8553 *(fctrl) = 0;
8554
8555 /* ------------------------------------------------------------------------- */
8556 /* MAC Header. */
8557 /* ------------------------------------------------------------------------- */
8558 SetFrameType(fctrl, WIFI_DATA);
8559 SetToDs(fctrl);
8560 _rtw_memcpy(pwlanhdr->addr1,
8561 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8562 _rtw_memcpy(pwlanhdr->addr2,
8563 adapter_mac_addr(padapter), ETH_ALEN);
8564 _rtw_memcpy(pwlanhdr->addr3,
8565 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8566
8567 SetSeqNum(pwlanhdr, 0);
8568 set_duration(pwlanhdr, 0);
8569
8570 #ifdef CONFIG_WAPI_SUPPORT
8571 *pLength = sMacHdrLng;
8572 #else
8573 *pLength = 24;
8574 #endif
8575 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8576 case _WEP40_:
8577 case _WEP104_:
8578 EncryptionHeadOverhead = 4;
8579 break;
8580 case _TKIP_:
8581 EncryptionHeadOverhead = 8;
8582 break;
8583 case _AES_:
8584 EncryptionHeadOverhead = 8;
8585 break;
8586 #ifdef CONFIG_WAPI_SUPPORT
8587 case _SMS4_:
8588 EncryptionHeadOverhead = 18;
8589 break;
8590 #endif
8591 default:
8592 EncryptionHeadOverhead = 0;
8593 }
8594
8595 if (EncryptionHeadOverhead > 0) {
8596 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8597 *pLength += EncryptionHeadOverhead;
8598 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8599 SetPrivacy(fctrl);
8600 }
8601
8602 /* ------------------------------------------------------------------------- */
8603 /* Frame Body. */
8604 /* ------------------------------------------------------------------------- */
8605 na_msg_offset = *pLength;
8606 p_na_msg = (u8 *)(pframe + na_msg_offset);
8607 payload = p_na_msg; /* Get Payload pointer */
8608
8609 /* LLC header */
8610 val8 = sizeof(ns_hdr);
8611 _rtw_memcpy(p_na_msg, ns_hdr, val8);
8612 *pLength += val8;
8613 p_na_msg += val8;
8614
8615 /* IPv6 Header */
8616 /* 1 . Information (4 bytes): 0x60 0x00 0x00 0x00 */
8617 val8 = sizeof(ipv6_info);
8618 _rtw_memcpy(p_na_msg, ipv6_info, val8);
8619 *pLength += val8;
8620 p_na_msg += val8;
8621
8622 /* 2 . playload : 0x00 0x20 , NextProt : 0x3a (ICMPv6) HopLim : 0xff */
8623 val8 = sizeof(ipv6_contx);
8624 _rtw_memcpy(p_na_msg, ipv6_contx, val8);
8625 *pLength += val8;
8626 p_na_msg += val8;
8627
8628 /* 3 . SA : 16 bytes , DA : 16 bytes ( Fw will filled ) */
8629 _rtw_memset(&(p_na_msg[*pLength]), 0, 32);
8630 *pLength += 32;
8631 p_na_msg += 32;
8632
8633 /* ICMPv6 */
8634 /* 1. Type : 0x88 (NA)
8635 * 2. Code : 0x00
8636 * 3. ChechSum : 0x00 0x00 (RSvd)
8637 * 4. NAFlag: 0x60 0x00 0x00 0x00 ( Solicited , Override)
8638 */
8639 val8 = sizeof(icmpv6_hdr);
8640 _rtw_memcpy(p_na_msg, icmpv6_hdr, val8);
8641 *pLength += val8;
8642 p_na_msg += val8;
8643
8644 /* TA: 16 bytes*/
8645 _rtw_memset(&(p_na_msg[*pLength]), 0, 16);
8646 *pLength += 16;
8647 p_na_msg += 16;
8648
8649 /* ICMPv6 Target Link Layer Address */
8650 p_na_msg[0] = 0x02; /* type */
8651 p_na_msg[1] = 0x01; /* len 1 unit of 8 octes */
8652 *pLength += 2;
8653 p_na_msg += 2;
8654
8655 _rtw_memset(&(p_na_msg[*pLength]), 0, 6);
8656 *pLength += 6;
8657 p_na_msg += 6;
8658
8659 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8660 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8661 IS_HARDWARE_TYPE_8812(padapter)) {
8662 rtw_hal_append_tkip_mic(padapter, pframe,
8663 na_msg_offset);
8664 }
8665 *pLength += 8;
8666 }
8667 }
8668 /*
8669 * Description: Neighbor Discovery Protocol Information.
8670 */
rtw_hal_construct_ndp_info(_adapter * padapter,u8 * pframe,u32 * pLength)8671 static void rtw_hal_construct_ndp_info(_adapter *padapter,
8672 u8 *pframe, u32 *pLength)
8673 {
8674 struct mlme_ext_priv *pmlmeext = NULL;
8675 struct mlme_ext_info *pmlmeinfo = NULL;
8676 struct rtw_ndp_info ndp_info;
8677 u8 *pndp_info = pframe;
8678 u8 len = sizeof(struct rtw_ndp_info);
8679
8680 RTW_INFO("%s: len: %d\n", __func__, len);
8681
8682 pmlmeext = &padapter->mlmeextpriv;
8683 pmlmeinfo = &pmlmeext->mlmext_info;
8684
8685 _rtw_memset(pframe, 0, len);
8686 _rtw_memset(&ndp_info, 0, len);
8687
8688 ndp_info.enable = 1;
8689 ndp_info.check_remote_ip = 0;
8690 ndp_info.num_of_target_ip = 1;
8691
8692 _rtw_memcpy(&ndp_info.target_link_addr, adapter_mac_addr(padapter),
8693 ETH_ALEN);
8694 _rtw_memcpy(&ndp_info.target_ipv6_addr, pmlmeinfo->ip6_addr,
8695 RTW_IPv6_ADDR_LEN);
8696
8697 _rtw_memcpy(pndp_info, &ndp_info, len);
8698 }
8699 #endif /* CONFIG_IPV6 */
8700
8701 #ifdef CONFIG_PNO_SUPPORT
rtw_hal_construct_ProbeReq(_adapter * padapter,u8 * pframe,u32 * pLength,pno_ssid_t * ssid)8702 void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
8703 u32 *pLength, pno_ssid_t *ssid)
8704 {
8705 struct rtw_ieee80211_hdr *pwlanhdr;
8706 u16 *fctrl;
8707 u32 pktlen;
8708 unsigned char *mac;
8709 unsigned char bssrate[NumRates];
8710 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8711 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8712 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8713 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8714 int bssrate_len = 0;
8715 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8716
8717 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8718 mac = adapter_mac_addr(padapter);
8719
8720 fctrl = &(pwlanhdr->frame_ctl);
8721 *(fctrl) = 0;
8722
8723 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8724 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8725
8726 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8727
8728 SetSeqNum(pwlanhdr, 0);
8729 set_frame_sub_type(pframe, WIFI_PROBEREQ);
8730
8731 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8732 pframe += pktlen;
8733
8734 if (ssid == NULL)
8735 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
8736 else {
8737 /* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
8738 pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
8739 }
8740
8741 get_rate_set(padapter, bssrate, &bssrate_len);
8742
8743 if (bssrate_len > 8) {
8744 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
8745 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
8746 } else
8747 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
8748
8749 *pLength = pktlen;
8750 }
8751
rtw_hal_construct_PNO_info(_adapter * padapter,u8 * pframe,u32 * pLength)8752 static void rtw_hal_construct_PNO_info(_adapter *padapter,
8753 u8 *pframe, u32 *pLength)
8754 {
8755 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8756 int i;
8757
8758 u8 *pPnoInfoPkt = pframe;
8759 pPnoInfoPkt = (u8 *)(pframe + *pLength);
8760 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
8761
8762 pPnoInfoPkt += 1;
8763 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
8764
8765 pPnoInfoPkt += 3;
8766 #ifdef RTW_HALMAC
8767 /* Pattern check for 3081 ICs */
8768 _rtw_memset(pPnoInfoPkt, 0xA5A5A5A5, 4);
8769 pPnoInfoPkt += 12;
8770 #else
8771 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
8772
8773 pPnoInfoPkt += 4;
8774 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
8775
8776 pPnoInfoPkt += 4;
8777 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
8778
8779 pPnoInfoPkt += 4;
8780 #endif
8781 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
8782
8783 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8784 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
8785
8786 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8787 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
8788
8789 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
8790 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
8791
8792 pPnoInfoPkt += MAX_HIDDEN_AP;
8793
8794 #ifdef RTW_HALMAC
8795 /* SSID is located at 72th byte in NLO info Page for ICs that have HAMMAC */
8796 *pLength += 72;
8797 pPnoInfoPkt = pframe + 72;
8798 #else
8799 /* SSID is located at 128th Byte in NLO info Page for ICs that don't have HAMMAC */
8800 *pLength += 128;
8801 pPnoInfoPkt = pframe + 128;
8802 #endif
8803 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8804 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8805 pwrctl->pnlo_info->ssid_length[i]);
8806 *pLength += WLAN_SSID_MAXLEN;
8807 pPnoInfoPkt += WLAN_SSID_MAXLEN;
8808 }
8809 }
8810
8811 #ifndef RTW_HALMAC
rtw_hal_construct_ssid_list(_adapter * padapter,u8 * pframe,u32 * pLength)8812 static void rtw_hal_construct_ssid_list(_adapter *padapter,
8813 u8 *pframe, u32 *pLength)
8814 {
8815 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8816 u8 *pSSIDListPkt = pframe;
8817 int i;
8818
8819 pSSIDListPkt = (u8 *)(pframe + *pLength);
8820
8821 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
8822 _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
8823 pwrctl->pnlo_info->ssid_length[i]);
8824
8825 *pLength += WLAN_SSID_MAXLEN;
8826 pSSIDListPkt += WLAN_SSID_MAXLEN;
8827 }
8828 }
8829
rtw_hal_construct_scan_info(_adapter * padapter,u8 * pframe,u32 * pLength)8830 static void rtw_hal_construct_scan_info(_adapter *padapter,
8831 u8 *pframe, u32 *pLength)
8832 {
8833 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
8834 u8 *pScanInfoPkt = pframe;
8835 int i;
8836
8837 pScanInfoPkt = (u8 *)(pframe + *pLength);
8838
8839 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
8840
8841 *pLength += 1;
8842 pScanInfoPkt += 1;
8843 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
8844
8845
8846 *pLength += 1;
8847 pScanInfoPkt += 1;
8848 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
8849
8850
8851 *pLength += 1;
8852 pScanInfoPkt += 1;
8853 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
8854
8855 *pLength += 1;
8856 pScanInfoPkt += 1;
8857 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
8858
8859 *pLength += 1;
8860 pScanInfoPkt += 1;
8861 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
8862
8863 *pLength += 1;
8864 pScanInfoPkt += 1;
8865 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
8866
8867 *pLength += 1;
8868 pScanInfoPkt += 1;
8869 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
8870
8871 *pLength += 1;
8872 pScanInfoPkt += 1;
8873 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
8874
8875 *pLength += 8;
8876 pScanInfoPkt += 8;
8877
8878 for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
8879 _rtw_memcpy(pScanInfoPkt,
8880 &pwrctl->pscan_info->ssid_channel_info[i], 4);
8881 *pLength += 4;
8882 pScanInfoPkt += 4;
8883 }
8884 }
8885 #endif /* !RTW_HALMAC */
8886 #endif /* CONFIG_PNO_SUPPORT */
8887
8888 #ifdef CONFIG_WAR_OFFLOAD
8889 #ifdef CONFIG_OFFLOAD_MDNS_V4
8890
8891 /*
8892 * Description:
8893 * Construct the MDNS V4 response packet to support MDNS offload.
8894 *
8895 */
rtw_hal_construct_mdns_rsp_v4(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)8896 static void rtw_hal_construct_mdns_rsp_v4(
8897 PADAPTER padapter,
8898 u8 *pframe,
8899 u32 *pLength,
8900 u8 *pIPAddress
8901 )
8902 {
8903 struct rtw_ieee80211_hdr *pwlanhdr;
8904 u16 *fctrl;
8905 u32 pktlen;
8906 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8907 struct wlan_network *cur_network = &pmlmepriv->cur_network;
8908 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8909 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8910 struct security_priv *psecuritypriv = &padapter->securitypriv;
8911 static u8 ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00};
8912 u8 mulicast_ipv4_addr[4] = {0xe0, 0x00, 0x00, 0xfb};
8913 u8 mulicast_mac_addr_for_mdns[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb};
8914 u8 *pMdnsRspPkt = pframe;
8915 /* for TKIP Cal MIC */
8916 u8 EncryptionHeadOverhead = 0, mdns_offset = 0;
8917
8918 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
8919 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
8920
8921 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8922
8923 fctrl = &pwlanhdr->frame_ctl;
8924 *(fctrl) = 0;
8925
8926 /* ------------------------------------------------------------------------- */
8927 /* MAC Header. */
8928 /* ------------------------------------------------------------------------- */
8929 SetFrameType(fctrl, WIFI_DATA);
8930 /* set_frame_sub_type(fctrl, 0); */
8931 SetToDs(fctrl);
8932 //_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8933 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8934 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8935 _rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN );
8936
8937 SetSeqNum(pwlanhdr, 0);
8938 set_duration(pwlanhdr, 0);
8939
8940 #ifdef CONFIG_WAPI_SUPPORT
8941 *pLength = sMacHdrLng;
8942 #else
8943 *pLength = 24;
8944 #endif
8945 switch (psecuritypriv->dot11PrivacyAlgrthm) {
8946 case _WEP40_:
8947 case _WEP104_:
8948 EncryptionHeadOverhead = 4;
8949 break;
8950 case _TKIP_:
8951 EncryptionHeadOverhead = 8;
8952 break;
8953 case _AES_:
8954 EncryptionHeadOverhead = 8;
8955 break;
8956 #ifdef CONFIG_WAPI_SUPPORT
8957 case _SMS4_:
8958 EncryptionHeadOverhead = 18;
8959 break;
8960 #endif
8961 default:
8962 EncryptionHeadOverhead = 0;
8963 }
8964
8965 if (EncryptionHeadOverhead > 0) {
8966 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
8967 *pLength += EncryptionHeadOverhead;
8968 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
8969 SetPrivacy(fctrl);
8970 }
8971
8972 /* ------------------------------------------------------------------------- */
8973 /* Frame Body. */
8974 /* ------------------------------------------------------------------------- */
8975 mdns_offset = *pLength;
8976 pMdnsRspPkt = (u8 *)(pframe + mdns_offset);
8977 /* LLC header */
8978 _rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8);
8979 *pLength += 8;
8980
8981 /* IP element */
8982 pMdnsRspPkt += 8;
8983 SET_IPHDR_VERSION(pMdnsRspPkt, 0x45);
8984 SET_IPHDR_DSCP(pMdnsRspPkt, 0);
8985 SET_IPHDR_TOTAL_LEN(pMdnsRspPkt, 0); // filled by fw
8986 SET_IPHDR_IDENTIFIER(pMdnsRspPkt, 0); // filled by fw
8987 SET_IPHDR_FLAGS(pMdnsRspPkt, 0x40);
8988 SET_IPHDR_FRAG_OFFSET(pMdnsRspPkt, 0);
8989 SET_IPHDR_TTL(pMdnsRspPkt, 0x40);
8990 SET_IPHDR_PROTOCOL(pMdnsRspPkt, 0x11); // ICMP-UDP
8991 SET_IPHDR_HDR_CHECKSUM(pMdnsRspPkt, 0); // filled by fw
8992 SET_IPHDR_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress);
8993 SET_IPHDR_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv4_addr); // filled by fw
8994
8995 *pLength += 20;
8996
8997 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
8998 if (IS_HARDWARE_TYPE_8188E(padapter) ||
8999 IS_HARDWARE_TYPE_8812(padapter)) {
9000 rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset);
9001 }
9002 *pLength += 8;
9003 }
9004
9005 /* UDP element */
9006 pMdnsRspPkt += 20;
9007 SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // MDNS
9008 SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // MDNS
9009 SET_UDP_LEN(pMdnsRspPkt, 0); // filled by fw
9010 SET_UDP_CHECKSUM(pMdnsRspPkt, 0); // filled by fw
9011 *pLength += 8;
9012
9013 /* MDNS Header */
9014 pMdnsRspPkt += 8;
9015 SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84);
9016 *pLength += 12;
9017
9018 }
9019
9020 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
9021
9022 #ifdef CONFIG_OFFLOAD_MDNS_V6
9023
9024 /*
9025 * Description:
9026 * Construct the MDNS response V6 packet to support MDNS offload.
9027 *
9028 */
rtw_hal_construct_mdns_rsp_v6(PADAPTER padapter,u8 * pframe,u32 * pLength,u8 * pIPAddress)9029 static void rtw_hal_construct_mdns_rsp_v6(
9030 PADAPTER padapter,
9031 u8 *pframe,
9032 u32 *pLength,
9033 u8 *pIPAddress
9034 )
9035 {
9036 struct rtw_ieee80211_hdr *pwlanhdr;
9037 u16 *fctrl;
9038 u32 pktlen;
9039 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9040 struct wlan_network *cur_network = &pmlmepriv->cur_network;
9041 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9042 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9043 struct security_priv *psecuritypriv = &padapter->securitypriv;
9044 static u8 ICMPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x86, 0xDD};
9045 u8 mulicast_ipv6_addr[16] = {0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
9046 u8 mulicast_mac_addr_for_mdns[6] = {0x33, 0x33, 0x00, 0x00, 0x00, 0xfb}; /* could be revise by fw */
9047 u8 *pMdnsRspPkt = pframe;
9048 /* for TKIP Cal MIC */
9049 u8 EncryptionHeadOverhead = 0, mdns_offset = 0;
9050 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
9051
9052 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
9053 struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(dvobj);
9054
9055 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9056
9057 fctrl = &pwlanhdr->frame_ctl;
9058 *(fctrl) = 0;
9059
9060 /* ------------------------------------------------------------------------- */
9061 /* MAC Header. */
9062 /* ------------------------------------------------------------------------- */
9063 SetFrameType(fctrl, WIFI_DATA);
9064 /* set_frame_sub_type(fctrl, 0); */
9065 SetToDs(fctrl);
9066 //_rtw_memcpy(pwlanhdr->addr1, mulicast_mac_addr_for_mdns, ETH_ALEN);
9067 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9068 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9069 //_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9070 _rtw_memcpy(pwlanhdr->addr3, mulicast_mac_addr_for_mdns, ETH_ALEN);
9071
9072 SetSeqNum(pwlanhdr, 0);
9073 set_duration(pwlanhdr, 0);
9074
9075 #ifdef CONFIG_WAPI_SUPPORT
9076 *pLength = sMacHdrLng;
9077 #else
9078 *pLength = 24;
9079 #endif
9080 switch (psecuritypriv->dot11PrivacyAlgrthm) {
9081 case _WEP40_:
9082 case _WEP104_:
9083 EncryptionHeadOverhead = 4;
9084 break;
9085 case _TKIP_:
9086 EncryptionHeadOverhead = 8;
9087 break;
9088 case _AES_:
9089 EncryptionHeadOverhead = 8;
9090 break;
9091 #ifdef CONFIG_WAPI_SUPPORT
9092 case _SMS4_:
9093 EncryptionHeadOverhead = 18;
9094 break;
9095 #endif
9096 default:
9097 EncryptionHeadOverhead = 0;
9098 }
9099
9100 if (EncryptionHeadOverhead > 0) {
9101 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
9102 *pLength += EncryptionHeadOverhead;
9103 SetPrivacy(fctrl);
9104 }
9105
9106 /* ------------------------------------------------------------------------- */
9107 /* Frame Body. */
9108 /* ------------------------------------------------------------------------- */
9109 mdns_offset = *pLength;
9110 pMdnsRspPkt = (u8 *)(pframe + mdns_offset);
9111 /* LLC header */
9112 _rtw_memcpy(pMdnsRspPkt, ICMPLLCHeader, 8);
9113 *pLength += 8;
9114
9115 /* ICMP element */
9116 pMdnsRspPkt += 8;
9117 SET_IPHDRV6_VERSION(pMdnsRspPkt, 0x06);
9118 SET_IPHDRV6_PAYLOAD_LENGTH(pMdnsRspPkt, 0); // filled by fw
9119 SET_IPHDRV6_NEXT_HEADER(pMdnsRspPkt, 0x3A);
9120 SET_IPHDRV6_HOP_LIMIT(pMdnsRspPkt, 0xFF);
9121 SET_IPHDRV6_SRC_IP_ADDR(pMdnsRspPkt, pIPAddress); // filled by fw
9122 SET_IPHDRV6_DST_IP_ADDR(pMdnsRspPkt, mulicast_ipv6_addr); // filled by fw
9123
9124 *pLength += 40;
9125
9126 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
9127 if (IS_HARDWARE_TYPE_8188E(padapter) ||
9128 IS_HARDWARE_TYPE_8812(padapter)) {
9129 rtw_hal_append_tkip_mic(padapter, pframe, mdns_offset);
9130 }
9131 *pLength += 8;
9132 }
9133
9134 /* UDP element */
9135 pMdnsRspPkt += 40;
9136 SET_UDP_SRC_PORT(pMdnsRspPkt, 0xe914); // SNMP
9137 SET_UDP_DST_PORT(pMdnsRspPkt, 0xe914); // SNMP
9138 SET_UDP_LEN(pMdnsRspPkt, 0); // filled by fw
9139 SET_UDP_CHECKSUM(pMdnsRspPkt, 0); // filled by fw
9140 *pLength += 8;
9141
9142 /* MDNS Header */
9143 pMdnsRspPkt += 8;
9144 SET_MDNS_HDR_FLAG(pMdnsRspPkt, 0x84);
9145 *pLength += 12;
9146
9147 }
9148
9149 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
9150 #endif
9151
9152 #ifdef CONFIG_GTK_OL
rtw_hal_construct_GTKRsp(PADAPTER padapter,u8 * pframe,u32 * pLength)9153 static void rtw_hal_construct_GTKRsp(
9154 PADAPTER padapter,
9155 u8 *pframe,
9156 u32 *pLength
9157 )
9158 {
9159 struct rtw_ieee80211_hdr *pwlanhdr;
9160 u16 *fctrl;
9161 u32 pktlen;
9162 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9163 struct wlan_network *cur_network = &pmlmepriv->cur_network;
9164 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9165 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9166 struct security_priv *psecuritypriv = &padapter->securitypriv;
9167 static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
9168 static u8 GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
9169 u8 *pGTKRspPkt = pframe;
9170 u8 EncryptionHeadOverhead = 0;
9171 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
9172
9173 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9174
9175 fctrl = &pwlanhdr->frame_ctl;
9176 *(fctrl) = 0;
9177
9178 /* ------------------------------------------------------------------------- */
9179 /* MAC Header. */
9180 /* ------------------------------------------------------------------------- */
9181 SetFrameType(fctrl, WIFI_DATA);
9182 /* set_frame_sub_type(fctrl, 0); */
9183 SetToDs(fctrl);
9184
9185 _rtw_memcpy(pwlanhdr->addr1,
9186 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9187
9188 _rtw_memcpy(pwlanhdr->addr2,
9189 adapter_mac_addr(padapter), ETH_ALEN);
9190
9191 _rtw_memcpy(pwlanhdr->addr3,
9192 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9193
9194 SetSeqNum(pwlanhdr, 0);
9195 set_duration(pwlanhdr, 0);
9196
9197 #ifdef CONFIG_WAPI_SUPPORT
9198 *pLength = sMacHdrLng;
9199 #else
9200 *pLength = 24;
9201 #endif /* CONFIG_WAPI_SUPPORT */
9202
9203 /* ------------------------------------------------------------------------- */
9204 /* Security Header: leave space for it if necessary. */
9205 /* ------------------------------------------------------------------------- */
9206 switch (psecuritypriv->dot11PrivacyAlgrthm) {
9207 case _WEP40_:
9208 case _WEP104_:
9209 EncryptionHeadOverhead = 4;
9210 break;
9211 case _TKIP_:
9212 EncryptionHeadOverhead = 8;
9213 break;
9214 case _AES_:
9215 EncryptionHeadOverhead = 8;
9216 break;
9217 #ifdef CONFIG_WAPI_SUPPORT
9218 case _SMS4_:
9219 EncryptionHeadOverhead = 18;
9220 break;
9221 #endif /* CONFIG_WAPI_SUPPORT */
9222 default:
9223 EncryptionHeadOverhead = 0;
9224 }
9225
9226 if (EncryptionHeadOverhead > 0) {
9227 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
9228 *pLength += EncryptionHeadOverhead;
9229 /* SET_80211_HDR_WEP(pGTKRspPkt, 1); */ /* Suggested by CCW. */
9230 /* GTK's privacy bit is done by FW */
9231 /* SetPrivacy(fctrl); */
9232 }
9233 /* ------------------------------------------------------------------------- */
9234 /* Frame Body. */
9235 /* ------------------------------------------------------------------------- */
9236 pGTKRspPkt = (u8 *)(pframe + *pLength);
9237 /* LLC header */
9238 _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
9239 *pLength += 8;
9240
9241 /* GTK element */
9242 pGTKRspPkt += 8;
9243
9244 /* GTK frame body after LLC, part 1 */
9245 /* TKIP key_length = 32, AES key_length = 16 */
9246 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
9247 GTKbody_a[8] = 0x20;
9248
9249 /* GTK frame body after LLC, part 1 */
9250 _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
9251 *pLength += 11;
9252 pGTKRspPkt += 11;
9253 /* GTK frame body after LLC, part 2 */
9254 _rtw_memset(&(pframe[*pLength]), 0, 88);
9255 *pLength += 88;
9256 pGTKRspPkt += 88;
9257
9258 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
9259 *pLength += 8;
9260 }
9261 #endif /* CONFIG_GTK_OL */
9262
9263 #define PN_2_CCMPH(ch,key_id) ((ch) & 0x000000000000ffff) \
9264 | (((ch) & 0x0000ffffffff0000) << 16) \
9265 | (((key_id) << 30)) \
9266 | BIT(29)
rtw_hal_construct_remote_control_info(_adapter * adapter,u8 * pframe,u32 * pLength)9267 static void rtw_hal_construct_remote_control_info(_adapter *adapter,
9268 u8 *pframe, u32 *pLength)
9269 {
9270 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
9271 struct sta_priv *pstapriv = &adapter->stapriv;
9272 struct security_priv *psecuritypriv = &adapter->securitypriv;
9273 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
9274 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9275 struct sta_info *psta;
9276 struct stainfo_rxcache *prxcache;
9277 u8 cur_dot11rxiv[8], id = 0, tid_id = 0, i = 0;
9278 size_t sz = 0, total = 0;
9279 u64 ccmp_hdr = 0, tmp_key = 0;
9280
9281 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
9282
9283 if (psta == NULL) {
9284 rtw_warn_on(1);
9285 return;
9286 }
9287
9288 prxcache = &psta->sta_recvpriv.rxcache;
9289 sz = sizeof(cur_dot11rxiv);
9290
9291 /* 3 SEC IV * 1 page */
9292 rtw_get_sec_iv(adapter, cur_dot11rxiv,
9293 get_my_bssid(&pmlmeinfo->network));
9294
9295 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
9296 *pLength += sz;
9297 pframe += sz;
9298
9299 _rtw_memset(&cur_dot11rxiv, 0, sz);
9300
9301 if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
9302 id = psecuritypriv->dot118021XGrpKeyid;
9303 tid_id = prxcache->last_tid;
9304 REMOTE_INFO_CTRL_SET_VALD_EN(cur_dot11rxiv, 0xdd);
9305 REMOTE_INFO_CTRL_SET_PTK_EN(cur_dot11rxiv, 1);
9306 REMOTE_INFO_CTRL_SET_GTK_EN(cur_dot11rxiv, 1);
9307 REMOTE_INFO_CTRL_SET_GTK_IDX(cur_dot11rxiv, id);
9308 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
9309 *pLength += sz;
9310 pframe += sz;
9311
9312 _rtw_memcpy(pframe, prxcache->iv[tid_id], sz);
9313 *pLength += sz;
9314 pframe += sz;
9315
9316 total = sizeof(psecuritypriv->iv_seq);
9317 total /= sizeof(psecuritypriv->iv_seq[0]);
9318
9319 for (i = 0 ; i < total ; i ++) {
9320 ccmp_hdr =
9321 le64_to_cpu(*(u64*)psecuritypriv->iv_seq[i]);
9322 _rtw_memset(&cur_dot11rxiv, 0, sz);
9323 if (ccmp_hdr != 0) {
9324 tmp_key = i;
9325 ccmp_hdr = PN_2_CCMPH(ccmp_hdr, tmp_key);
9326 *(u64*)cur_dot11rxiv = cpu_to_le64(ccmp_hdr);
9327 _rtw_memcpy(pframe, cur_dot11rxiv, sz);
9328 }
9329 *pLength += sz;
9330 pframe += sz;
9331 }
9332 }
9333 }
9334
rtw_hal_gate_bb(_adapter * adapter,bool stop)9335 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
9336 {
9337 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9338 u8 i = 0, val8 = 0, empty = _FAIL;
9339
9340 if (stop) {
9341 /* checking TX queue status */
9342 for (i = 0 ; i < 5 ; i++) {
9343 rtw_hal_get_hwreg(adapter, HW_VAR_CHK_MGQ_CPU_EMPTY, &empty);
9344 if (empty) {
9345 break;
9346 } else {
9347 RTW_WARN("%s: MGQ_CPU is busy(%d)!\n",
9348 __func__, i);
9349 rtw_mdelay_os(10);
9350 }
9351 }
9352
9353 if (val8 == 5)
9354 RTW_ERR("%s: Polling MGQ_CPU empty fail!\n", __func__);
9355
9356 /* Pause TX*/
9357 pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
9358 rtw_write8(adapter, REG_TXPAUSE, 0xff);
9359 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9360 val8 &= ~BIT(0);
9361 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9362 RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
9363 __func__,
9364 rtw_read8(adapter, REG_SYS_FUNC_EN),
9365 pwrpriv->wowlan_txpause_status);
9366 } else {
9367 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
9368 val8 |= BIT(0);
9369 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
9370 RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
9371 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
9372 pwrpriv->wowlan_txpause_status);
9373 /* release TX*/
9374 rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
9375 }
9376 }
9377
rtw_hal_wow_pattern_generate(_adapter * adapter,u8 idx,struct rtl_wow_pattern * pwow_pattern)9378 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
9379 {
9380 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9381 u8 *pattern;
9382 u8 len = 0;
9383 u8 *mask;
9384
9385 u8 mask_hw[MAX_WKFM_SIZE] = {0};
9386 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
9387 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9388 u8 multicast_addr1[2] = {0x33, 0x33};
9389 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
9390 u8 mask_len = 0;
9391 u8 mac_addr[ETH_ALEN] = {0};
9392 u16 count = 0;
9393 int i;
9394
9395 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
9396 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
9397 __func__, MAX_WKFM_CAM_NUM);
9398 return _FAIL;
9399 }
9400
9401 pattern = pwrctl->patterns[idx].content;
9402 len = pwrctl->patterns[idx].len;
9403 mask = pwrctl->patterns[idx].mask;
9404
9405 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
9406 _rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
9407
9408 mask_len = DIV_ROUND_UP(len, 8);
9409
9410 /* 1. setup A1 table */
9411 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
9412 pwow_pattern->type = PATTERN_BROADCAST;
9413 else if (memcmp(pattern, multicast_addr1, 2) == 0)
9414 pwow_pattern->type = PATTERN_MULTICAST;
9415 else if (memcmp(pattern, multicast_addr2, 3) == 0)
9416 pwow_pattern->type = PATTERN_MULTICAST;
9417 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
9418 pwow_pattern->type = PATTERN_UNICAST;
9419 else
9420 pwow_pattern->type = PATTERN_INVALID;
9421
9422 /* translate mask from os to mask for hw */
9423
9424 /******************************************************************************
9425 * pattern from OS uses 'ethenet frame', like this:
9426
9427 | 6 | 6 | 2 | 20 | Variable | 4 |
9428 |--------+--------+------+-----------+------------+-----|
9429 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
9430 | DA | SA | Type |
9431
9432 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
9433
9434 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
9435 |-------------------+--------+------+-----------+------------+-----|
9436 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
9437 | Others | Tpye |
9438
9439 * Therefore, we need translate mask_from_OS to mask_to_hw.
9440 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
9441 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
9442 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
9443 ******************************************************************************/
9444 /* Shift 6 bits */
9445 for (i = 0; i < mask_len - 1; i++) {
9446 mask_hw[i] = mask[i] >> 6;
9447 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
9448 }
9449
9450 mask_hw[i] = (mask[i] >> 6) & 0x3F;
9451 /* Set bit 0-5 to zero */
9452 mask_hw[0] &= 0xC0;
9453
9454 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
9455 pwow_pattern->mask[i] = mask_hw[i * 4];
9456 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
9457 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
9458 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
9459 }
9460
9461 /* To get the wake up pattern from the mask.
9462 * We do not count first 12 bits which means
9463 * DA[6] and SA[6] in the pattern to match HW design. */
9464 count = 0;
9465 for (i = 12; i < len; i++) {
9466 if ((mask[i / 8] >> (i % 8)) & 0x01) {
9467 content[count] = pattern[i];
9468 count++;
9469 }
9470 }
9471
9472 pwow_pattern->crc = rtw_calc_crc(content, count);
9473
9474 if (pwow_pattern->crc != 0) {
9475 if (pwow_pattern->type == PATTERN_INVALID)
9476 pwow_pattern->type = PATTERN_VALID;
9477 }
9478
9479 return _SUCCESS;
9480 }
9481
rtw_dump_wow_pattern(void * sel,struct rtl_wow_pattern * pwow_pattern,u8 idx)9482 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
9483 {
9484 int j;
9485
9486 RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
9487 RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
9488 RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
9489 for (j = 0; j < 4; j++)
9490 RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
9491 }
9492 /*bit definition of pattern match format*/
9493 #define WOW_VALID_BIT BIT31
9494 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
9495 #define WOW_BC_BIT BIT26
9496 #define WOW_MC_BIT BIT25
9497 #define WOW_UC_BIT BIT24
9498 #else
9499 #define WOW_BC_BIT BIT18
9500 #define WOW_UC_BIT BIT17
9501 #define WOW_MC_BIT BIT16
9502 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
9503
9504 #ifndef CONFIG_WOW_PATTERN_HW_CAM
9505 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_hal_reset_mac_rx(_adapter * adapter)9506 static void rtw_hal_reset_mac_rx(_adapter *adapter)
9507 {
9508 u8 val8 = 0;
9509 /* Set REG_CR bit1, bit3, bit7 to 0*/
9510 val8 = rtw_read8(adapter, REG_CR);
9511 val8 &= 0x75;
9512 rtw_write8(adapter, REG_CR, val8);
9513 val8 = rtw_read8(adapter, REG_CR);
9514 /* Set REG_CR bit1, bit3, bit7 to 1*/
9515 val8 |= 0x8a;
9516 rtw_write8(adapter, REG_CR, val8);
9517 RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
9518 }
rtw_hal_set_wow_rxff_boundary(_adapter * adapter,bool wow_mode)9519 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
9520 {
9521 u8 val8 = 0;
9522 u16 rxff_bndy = 0;
9523 u32 rx_dma_buff_sz = 0;
9524
9525 val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
9526 if (val8 != 0)
9527 RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
9528 __func__, (REG_FIFOPAGE + 3));
9529
9530 rtw_hal_reset_mac_rx(adapter);
9531
9532 if (wow_mode) {
9533 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9534 (u8 *)&rx_dma_buff_sz);
9535 rxff_bndy = rx_dma_buff_sz - 1;
9536
9537 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9538 RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
9539 REG_TRXFF_BNDY + 2,
9540 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9541 } else {
9542 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
9543 (u8 *)&rx_dma_buff_sz);
9544 rxff_bndy = rx_dma_buff_sz - 1;
9545 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
9546 RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
9547 REG_TRXFF_BNDY + 2,
9548 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
9549 }
9550 }
9551 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO*/
9552 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9553 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9554 {
9555 u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
9556 u16 offset, rx_buf_ptr = 0;
9557 u16 cam_start_offset = 0;
9558 u16 ctrl_l = 0, ctrl_h = 0;
9559 u8 count = 0, tmp = 0;
9560 int i = 0;
9561 bool res = _TRUE;
9562
9563 if (idx > MAX_WKFM_CAM_NUM) {
9564 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9565 __func__);
9566 return _FALSE;
9567 }
9568
9569 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9570 (u8 *)&rx_dma_buff_sz);
9571
9572 if (rx_dma_buff_sz == 0) {
9573 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9574 return _FALSE;
9575 }
9576
9577 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9578
9579 if (page_sz == 0) {
9580 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9581 return _FALSE;
9582 }
9583
9584 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9585 cam_start_offset = offset * page_sz;
9586
9587 ctrl_l = 0x0;
9588 ctrl_h = 0x0;
9589
9590 /* Enable RX packet buffer access */
9591 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9592
9593 /* Read the WKFM CAM */
9594 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9595 /*
9596 * Set Rx packet buffer offset.
9597 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9598 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9599 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9600 * * Index: The index of the wake up frame mask
9601 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9602 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9603 */
9604 rx_buf_ptr =
9605 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9606 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9607
9608 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9609 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9610 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9611
9612 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9613
9614 count = 0;
9615
9616 do {
9617 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9618 rtw_udelay_os(2);
9619 count++;
9620 } while (!tmp && count < 100);
9621
9622 if (count >= 100) {
9623 RTW_INFO("%s count:%d\n", __func__, count);
9624 res = _FALSE;
9625 }
9626 }
9627
9628 /* Disable RX packet buffer access */
9629 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9630 DISABLE_TRXPKT_BUF_ACCESS);
9631 return res;
9632 }
9633
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9634 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9635 struct rtl_wow_pattern *context)
9636 {
9637 u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
9638 u16 offset, rx_buf_ptr = 0;
9639 u16 cam_start_offset = 0;
9640 u16 ctrl_l = 0, ctrl_h = 0;
9641 u8 count = 0, tmp = 0;
9642 int res = 0, i = 0;
9643
9644 if (idx > MAX_WKFM_CAM_NUM) {
9645 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9646 __func__);
9647 return _FALSE;
9648 }
9649
9650 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
9651 (u8 *)&rx_dma_buff_sz);
9652
9653 if (rx_dma_buff_sz == 0) {
9654 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
9655 return _FALSE;
9656 }
9657
9658 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
9659
9660 if (page_sz == 0) {
9661 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9662 return _FALSE;
9663 }
9664
9665 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
9666
9667 cam_start_offset = offset * page_sz;
9668
9669 if (IS_HARDWARE_TYPE_8188E(adapter)) {
9670 ctrl_l = 0x0001;
9671 ctrl_h = 0x0001;
9672 } else {
9673 ctrl_l = 0x0f01;
9674 ctrl_h = 0xf001;
9675 }
9676
9677 /* Enable RX packet buffer access */
9678 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
9679
9680 /* Write the WKFM CAM */
9681 for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
9682 /*
9683 * Set Rx packet buffer offset.
9684 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9685 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9686 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9687 * * Index: The index of the wake up frame mask
9688 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9689 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9690 */
9691 rx_buf_ptr =
9692 (cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
9693 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
9694
9695 if (i == 0) {
9696 if (context->type == PATTERN_VALID)
9697 data = WOW_VALID_BIT;
9698 else if (context->type == PATTERN_BROADCAST)
9699 data = WOW_VALID_BIT | WOW_BC_BIT;
9700 else if (context->type == PATTERN_MULTICAST)
9701 data = WOW_VALID_BIT | WOW_MC_BIT;
9702 else if (context->type == PATTERN_UNICAST)
9703 data = WOW_VALID_BIT | WOW_UC_BIT;
9704
9705 if (context->crc != 0)
9706 data |= context->crc;
9707
9708 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9709 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9710 } else if (i == 1) {
9711 data = 0;
9712 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9713 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9714 } else if (i == 2 || i == 4) {
9715 data = context->mask[i - 2];
9716 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
9717 /* write to RX packet buffer*/
9718 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9719 } else if (i == 3 || i == 5) {
9720 data = context->mask[i - 2];
9721 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
9722 /* write to RX packet buffer*/
9723 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
9724 }
9725
9726 count = 0;
9727 do {
9728 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
9729 rtw_udelay_os(2);
9730 count++;
9731 } while (tmp && count < 100);
9732
9733 if (count >= 100)
9734 res = _FALSE;
9735 else
9736 res = _TRUE;
9737 }
9738
9739 /* Disable RX packet buffer access */
9740 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9741 DISABLE_TRXPKT_BUF_ACCESS);
9742
9743 return res;
9744 }
rtw_fill_pattern(_adapter * adapter)9745 void rtw_fill_pattern(_adapter *adapter)
9746 {
9747 int i = 0, total = 0, index;
9748 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9749 struct rtl_wow_pattern wow_pattern;
9750
9751 total = pwrpriv->wowlan_pattern_idx;
9752
9753 if (total > MAX_WKFM_CAM_NUM)
9754 total = MAX_WKFM_CAM_NUM;
9755
9756 for (i = 0 ; i < total ; i++) {
9757 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
9758
9759 index = i;
9760 if (!pwrpriv->bInSuspend)
9761 index += 2;
9762 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
9763 if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
9764 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
9765 }
9766
9767 }
9768 rtw_write8(adapter, REG_WKFMCAM_NUM, total);
9769
9770 }
9771 #else /* CONFIG_WOW_PATTERN_IN_TXFIFO */
rtw_read_from_frame_mask(_adapter * adapter,u8 idx)9772 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
9773 {
9774 u32 data_l = 0, data_h = 0, page_sz = 0;
9775 u16 tx_page_start, tx_buf_ptr = 0;
9776 u16 cam_start_offset = 0;
9777 u16 ctrl_l = 0, ctrl_h = 0;
9778 u8 count = 0, tmp = 0, last_entry = 0;
9779 int i = 0;
9780 bool res = _TRUE;
9781 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
9782 u32 buffer[WKFMCAM_ADDR_NUM];
9783
9784
9785 if (idx > MAX_WKFM_CAM_NUM) {
9786 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9787 __func__);
9788 return _FALSE;
9789 }
9790
9791 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9792 if (page_sz == 0) {
9793 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9794 return _FALSE;
9795 }
9796
9797 rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9798 if (last_entry == 0) {
9799 RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9800 return _FALSE;
9801 }
9802
9803
9804 if(_rtw_wow_chk_cap(adapter, WOW_CAP_HALMAC_ACCESS_PATTERN_IN_TXFIFO)) {
9805 /* 8723F cannot indirect access tx fifo
9806 * rtw_halmac_dump_fifo(dvobj, fifo_sel, fifo_addr, buf_sz, buf)
9807 */
9808 #ifdef RTW_HALMAC
9809 rtw_halmac_dump_fifo(adapter_to_dvobj(adapter),
9810 2,
9811 (pwrctl->pattern_rsvd_page_loc * page_sz) + (idx * WKFMCAM_ADDR_NUM * 4),
9812 WKFMCAM_ADDR_NUM*4, (u8*)buffer);
9813 #endif
9814
9815 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9816 RTW_INFO("[%d]: %08x %08x\n", i, *(buffer + i*2), *(buffer + i*2 + 1));
9817 }
9818 } else {
9819 /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9820 tx_page_start = last_entry - 1;
9821 cam_start_offset = tx_page_start * page_sz / 8;
9822 ctrl_l = 0x0;
9823 ctrl_h = 0x0;
9824
9825 /* Enable TX packet buffer access */
9826 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9827
9828 /* Read the WKFM CAM */
9829 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
9830 /*
9831 * Set Tx packet buffer offset.
9832 * TxBufer pointer increases 1, we can access 8 bytes in Tx packet buffer.
9833 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9834 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9835 * * Index: The index of the wake up frame mask
9836 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9837 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9838 */
9839 tx_buf_ptr =
9840 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
9841 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, tx_buf_ptr);
9842 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
9843 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
9844 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
9845
9846 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
9847
9848 count = 0;
9849
9850 do {
9851 tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9852 rtw_udelay_os(2);
9853 count++;
9854 } while (!tmp && count < 100);
9855
9856 if (count >= 100) {
9857 RTW_INFO("%s count:%d\n", __func__, count);
9858 res = _FALSE;
9859 }
9860 }
9861
9862 /* Disable RX packet buffer access */
9863 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
9864 DISABLE_TRXPKT_BUF_ACCESS);
9865 }
9866
9867 return res;
9868 }
9869
rtw_write_to_frame_mask(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context)9870 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
9871 struct rtl_wow_pattern *context)
9872 {
9873 u32 tx_page_start = 0, page_sz = 0;
9874 u16 tx_buf_ptr = 0;
9875 u16 cam_start_offset = 0;
9876 u32 data_l = 0, data_h = 0;
9877 u8 count = 0, tmp = 0, last_entry = 0;
9878 int res = 0, i = 0;
9879
9880 if (idx > MAX_WKFM_CAM_NUM) {
9881 RTW_INFO("[Error]: %s, pattern index is out of range\n",
9882 __func__);
9883 return _FALSE;
9884 }
9885
9886 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9887 if (page_sz == 0) {
9888 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
9889 return _FALSE;
9890 }
9891
9892 rtw_hal_get_def_var(adapter, HAL_DEF_TX_BUFFER_LAST_ENTRY, (u8 *)&last_entry);
9893 if (last_entry == 0) {
9894 RTW_INFO("[Error]: %s, last entry of tx buffer is 0!!\n", __func__);
9895 return _FALSE;
9896 }
9897
9898 /* use the last 2 pages for wow pattern e.g. 0xfe and 0xff */
9899 tx_page_start = last_entry - 1;
9900 cam_start_offset = tx_page_start * page_sz / 8;
9901
9902 /* Write the PATTERN location to BIT_TXBUF_WKCAM_OFFSET */
9903 rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET, cam_start_offset & 0xFF);
9904 rtw_write8(adapter, REG_TXBUF_WKCAM_OFFSET + 1, (cam_start_offset >> 8) & 0xFF);
9905 /* Enable TX packet buffer access */
9906 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
9907
9908 /* Write the WKFM CAM */
9909 for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9910 /*
9911 * Set Tx packet buffer offset.
9912 * TxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
9913 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
9914 * TxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
9915 * * Index: The index of the wake up frame mask
9916 * * WKFMCAM_SIZE: the total size of one WKFM CAM
9917 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
9918 */
9919 tx_buf_ptr = cam_start_offset + ((idx * WKFMCAM_SIZE + i * 8) >> 3);
9920
9921 if (i == 0) {
9922 if (context->type == PATTERN_VALID)
9923 data_l = WOW_VALID_BIT;
9924 else if (context->type == PATTERN_BROADCAST)
9925 data_l = WOW_VALID_BIT | WOW_BC_BIT;
9926 else if (context->type == PATTERN_MULTICAST)
9927 data_l = WOW_VALID_BIT | WOW_MC_BIT;
9928 else if (context->type == PATTERN_UNICAST)
9929 data_l = WOW_VALID_BIT | WOW_UC_BIT;
9930
9931 if (context->crc != 0)
9932 data_l |= context->crc;
9933
9934 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9935 } else {
9936 data_l = context->mask[i * 2 - 2];
9937 data_h = context->mask[i * 2 - 1];
9938 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data_l);
9939 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data_h);
9940 }
9941
9942 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, (tx_buf_ptr & 0x1FFF) | BIT23 | (0xff <<24));
9943 count = 0;
9944 do {
9945 tmp = rtw_read32(adapter, REG_PKTBUF_DBG_CTRL) & BIT23;
9946 rtw_udelay_os(2);
9947 count++;
9948 } while (tmp && count < 100);
9949
9950 if (count >= 100) {
9951 res = _FALSE;
9952 RTW_INFO("%s write failed\n", __func__);
9953 } else {
9954 res = _TRUE;
9955 RTW_INFO("%s write OK\n", __func__);
9956 }
9957 }
9958
9959 /* Disable TX packet buffer access */
9960 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
9961 return res;
9962 }
rtw_write_to_frame_mask_buf(_adapter * adapter,u8 idx,struct rtl_wow_pattern * context,char * pattern_info,u32 * ppattern_info_len)9963 bool rtw_write_to_frame_mask_buf(_adapter *adapter, u8 idx,
9964 struct rtl_wow_pattern *context, char *pattern_info, u32 *ppattern_info_len)
9965 {
9966
9967 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
9968 u32 page_sz = 0;
9969 int res = _FALSE, i = 0;
9970 u32 tmp_pattern_buf[6] = {0};
9971
9972 if (pattern_info == NULL) {
9973 RTW_ERR("[Error]: %s, pattern info is NULL\n", __func__);
9974 }
9975 if (idx > MAX_WKFM_CAM_NUM) {
9976 RTW_ERR("[Error]: %s, pattern index is out of range\n",
9977 __func__);
9978 return _FALSE;
9979 }
9980
9981 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_sz);
9982 if (page_sz == 0) {
9983 RTW_ERR("[Error]: %s, page_sz is 0!!\n", __func__);
9984 return _FALSE;
9985 }
9986
9987 /* Fill WKFM */
9988 for (i = 0; i < WKFMCAM_ADDR_NUM / 2; i++) {
9989 if (i == 0) {
9990 if (context->type == PATTERN_VALID)
9991 tmp_pattern_buf[0] = WOW_VALID_BIT;
9992 else if (context->type == PATTERN_BROADCAST)
9993 tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_BC_BIT;
9994 else if (context->type == PATTERN_MULTICAST)
9995 tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_MC_BIT;
9996 else if (context->type == PATTERN_UNICAST)
9997 tmp_pattern_buf[0] = WOW_VALID_BIT | WOW_UC_BIT;
9998
9999 if (context->crc != 0)
10000 tmp_pattern_buf[0] |= context->crc;
10001 /* pattern[1] is reserved in pattern format, dont care. */
10002
10003 } else {
10004 tmp_pattern_buf[i * 2] = context->mask[i * 2 - 2];
10005 tmp_pattern_buf[i * 2 + 1] = context->mask[i * 2 - 1];
10006 }
10007 }
10008
10009
10010 /* put pattern to pattern_buf */
10011 _rtw_memcpy((pattern_info + idx * WKFMCAM_SIZE) , tmp_pattern_buf, WKFMCAM_SIZE);
10012 *ppattern_info_len += WKFMCAM_SIZE;
10013 #ifdef CONFIG_WOW_PATTERN_IN_TXFIFO_DBG
10014 RTW_INFO("\nidx : %u pattern_info_len : %u\n", idx, *ppattern_info_len);
10015 RTW_INFO_DUMP("", (pattern_info + idx * WKFMCAM_SIZE), WKFMCAM_SIZE);
10016 #endif
10017 res = _TRUE;
10018
10019
10020 return res;
10021 }
10022 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
10023
rtw_clean_pattern(_adapter * adapter)10024 void rtw_clean_pattern(_adapter *adapter)
10025 {
10026 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10027 struct rtl_wow_pattern zero_pattern;
10028 int i = 0;
10029
10030 _rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
10031
10032 zero_pattern.type = PATTERN_INVALID;
10033 /* pattern in tx fifo do not need clear to zero*/
10034
10035 rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
10036 }
10037 #if 0
10038 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
10039 u8 len, u8 *mask, u8 idx)
10040 {
10041 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10042 struct mlme_ext_priv *pmlmeext = NULL;
10043 struct mlme_ext_info *pmlmeinfo = NULL;
10044 struct rtl_wow_pattern wow_pattern;
10045 u8 mask_hw[MAX_WKFM_SIZE] = {0};
10046 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
10047 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
10048 u8 multicast_addr1[2] = {0x33, 0x33};
10049 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
10050 u8 res = _FALSE, index = 0, mask_len = 0;
10051 u8 mac_addr[ETH_ALEN] = {0};
10052 u16 count = 0;
10053 int i, j;
10054
10055 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
10056 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
10057 __func__, MAX_WKFM_CAM_NUM);
10058 return _FALSE;
10059 }
10060
10061 pmlmeext = &adapter->mlmeextpriv;
10062 pmlmeinfo = &pmlmeext->mlmext_info;
10063 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
10064 _rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
10065
10066 mask_len = DIV_ROUND_UP(len, 8);
10067
10068 /* 1. setup A1 table */
10069 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
10070 wow_pattern.type = PATTERN_BROADCAST;
10071 else if (memcmp(pattern, multicast_addr1, 2) == 0)
10072 wow_pattern.type = PATTERN_MULTICAST;
10073 else if (memcmp(pattern, multicast_addr2, 3) == 0)
10074 wow_pattern.type = PATTERN_MULTICAST;
10075 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
10076 wow_pattern.type = PATTERN_UNICAST;
10077 else
10078 wow_pattern.type = PATTERN_INVALID;
10079
10080 /* translate mask from os to mask for hw */
10081
10082 /******************************************************************************
10083 * pattern from OS uses 'ethenet frame', like this:
10084
10085 | 6 | 6 | 2 | 20 | Variable | 4 |
10086 |--------+--------+------+-----------+------------+-----|
10087 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
10088 | DA | SA | Type |
10089
10090 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
10091
10092 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
10093 |-------------------+--------+------+-----------+------------+-----|
10094 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
10095 | Others | Tpye |
10096
10097 * Therefore, we need translate mask_from_OS to mask_to_hw.
10098 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
10099 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
10100 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
10101 ******************************************************************************/
10102 /* Shift 6 bits */
10103 for (i = 0; i < mask_len - 1; i++) {
10104 mask_hw[i] = mask[i] >> 6;
10105 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
10106 }
10107
10108 mask_hw[i] = (mask[i] >> 6) & 0x3F;
10109 /* Set bit 0-5 to zero */
10110 mask_hw[0] &= 0xC0;
10111
10112 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
10113 wow_pattern.mask[i] = mask_hw[i * 4];
10114 wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
10115 wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
10116 wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
10117 }
10118
10119 /* To get the wake up pattern from the mask.
10120 * We do not count first 12 bits which means
10121 * DA[6] and SA[6] in the pattern to match HW design. */
10122 count = 0;
10123 for (i = 12; i < len; i++) {
10124 if ((mask[i / 8] >> (i % 8)) & 0x01) {
10125 content[count] = pattern[i];
10126 count++;
10127 }
10128 }
10129
10130 wow_pattern.crc = rtw_calc_crc(content, count);
10131
10132 if (wow_pattern.crc != 0) {
10133 if (wow_pattern.type == PATTERN_INVALID)
10134 wow_pattern.type = PATTERN_VALID;
10135 }
10136
10137 index = idx;
10138
10139 if (!pwrctl->bInSuspend)
10140 index += 2;
10141
10142 /* write pattern */
10143 res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
10144
10145 if (res == _FALSE)
10146 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
10147 __func__, idx);
10148
10149 return res;
10150 }
10151 #endif
10152 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
10153
10154 #define WOW_CAM_ACCESS_TIMEOUT_MS 200
_rtw_wow_pattern_read_cam(_adapter * adapter,u8 addr)10155 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
10156 {
10157 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10158 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10159
10160 u32 rdata = 0;
10161 u32 cnt = 0;
10162 systime start = 0;
10163 u8 timeout = 0;
10164 u8 rst = _FALSE;
10165
10166 _enter_critical_mutex(mutex, NULL);
10167
10168 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
10169
10170 start = rtw_get_current_time();
10171 while (1) {
10172 if (rtw_is_surprise_removed(adapter))
10173 break;
10174
10175 cnt++;
10176 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10177 rst = _SUCCESS;
10178 break;
10179 }
10180 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10181 timeout = 1;
10182 break;
10183 }
10184 }
10185
10186 rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
10187
10188 _exit_critical_mutex(mutex, NULL);
10189
10190 /*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
10191
10192 if (timeout)
10193 RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
10194
10195 return rdata;
10196 }
rtw_wow_pattern_read_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10197 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
10198 {
10199 int i;
10200 u32 rdata;
10201
10202 _rtw_memset(context, 0, sizeof(struct rtl_wow_pattern));
10203
10204 for (i = 4; i >= 0; i--) {
10205 rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
10206
10207 switch (i) {
10208 case 4:
10209 if (rdata & WOW_BC_BIT)
10210 context->type = PATTERN_BROADCAST;
10211 else if (rdata & WOW_MC_BIT)
10212 context->type = PATTERN_MULTICAST;
10213 else if (rdata & WOW_UC_BIT)
10214 context->type = PATTERN_UNICAST;
10215 else
10216 context->type = PATTERN_INVALID;
10217
10218 context->crc = rdata & 0xFFFF;
10219 break;
10220 default:
10221 _rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
10222 break;
10223 }
10224 }
10225 }
10226
_rtw_wow_pattern_write_cam(_adapter * adapter,u8 addr,u32 wdata)10227 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
10228 {
10229 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10230 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10231 u32 cnt = 0;
10232 systime start = 0, end = 0;
10233 u8 timeout = 0;
10234
10235 /*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
10236 _enter_critical_mutex(mutex, NULL);
10237
10238 rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
10239 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
10240
10241 start = rtw_get_current_time();
10242 while (1) {
10243 if (rtw_is_surprise_removed(adapter))
10244 break;
10245
10246 cnt++;
10247 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
10248 break;
10249
10250 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10251 timeout = 1;
10252 break;
10253 }
10254 }
10255 end = rtw_get_current_time();
10256
10257 _exit_critical_mutex(mutex, NULL);
10258
10259 if (timeout) {
10260 RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
10261 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
10262 }
10263 }
10264
rtw_wow_pattern_write_cam_ent(_adapter * adapter,u8 id,struct rtl_wow_pattern * context)10265 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
10266 {
10267 int j;
10268 u8 addr;
10269 u32 wdata = 0;
10270
10271 for (j = 4; j >= 0; j--) {
10272 switch (j) {
10273 case 4:
10274 wdata = context->crc;
10275
10276 if (PATTERN_BROADCAST == context->type)
10277 wdata |= WOW_BC_BIT;
10278 if (PATTERN_MULTICAST == context->type)
10279 wdata |= WOW_MC_BIT;
10280 if (PATTERN_UNICAST == context->type)
10281 wdata |= WOW_UC_BIT;
10282 if (PATTERN_INVALID != context->type)
10283 wdata |= WOW_VALID_BIT;
10284 break;
10285 default:
10286 wdata = context->mask[j];
10287 break;
10288 }
10289
10290 addr = (id << 3) + j;
10291
10292 _rtw_wow_pattern_write_cam(adapter, addr, wdata);
10293 }
10294 }
10295
_rtw_wow_pattern_clean_cam(_adapter * adapter)10296 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
10297 {
10298 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10299 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
10300 u32 cnt = 0;
10301 systime start = 0;
10302 u8 timeout = 0;
10303 u8 rst = _FAIL;
10304
10305 _enter_critical_mutex(mutex, NULL);
10306 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
10307
10308 start = rtw_get_current_time();
10309 while (1) {
10310 if (rtw_is_surprise_removed(adapter))
10311 break;
10312
10313 cnt++;
10314 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
10315 rst = _SUCCESS;
10316 break;
10317 }
10318 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
10319 timeout = 1;
10320 break;
10321 }
10322 }
10323 _exit_critical_mutex(mutex, NULL);
10324
10325 if (timeout)
10326 RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
10327
10328 return rst;
10329 }
10330
rtw_clean_pattern(_adapter * adapter)10331 void rtw_clean_pattern(_adapter *adapter)
10332 {
10333 if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
10334 RTW_ERR("rtw_clean_pattern failed\n");
10335 }
rtw_fill_pattern(_adapter * adapter)10336 void rtw_fill_pattern(_adapter *adapter)
10337 {
10338 int i = 0, total = 0;
10339 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10340 struct rtl_wow_pattern wow_pattern;
10341
10342 total = pwrpriv->wowlan_pattern_idx;
10343
10344 if (total > MAX_WKFM_CAM_NUM)
10345 total = MAX_WKFM_CAM_NUM;
10346
10347 for (i = 0 ; i < total ; i++) {
10348 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
10349 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10350 rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
10351 }
10352 }
10353 }
10354
10355 #endif
rtw_wow_pattern_cam_dump(_adapter * adapter)10356 void rtw_wow_pattern_cam_dump(_adapter *adapter)
10357 {
10358
10359 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10360 int i = 0, total = 0;
10361 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10362 total = pwrpriv->wowlan_pattern_idx;
10363
10364 if (total > MAX_WKFM_CAM_NUM)
10365 total = MAX_WKFM_CAM_NUM;
10366
10367 for (i = 0 ; i < total; i++) {
10368 RTW_INFO("=======[%d]=======\n", i);
10369 rtw_read_from_frame_mask(adapter, i);
10370 }
10371 #else
10372 struct rtl_wow_pattern context;
10373 int i;
10374
10375 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
10376 rtw_wow_pattern_read_cam_ent(adapter, i, &context);
10377 rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
10378 }
10379
10380 #endif
10381 }
10382
10383
rtw_hal_dl_pattern(_adapter * adapter,u8 mode)10384 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
10385 {
10386 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10387
10388 switch (mode) {
10389 case 0:
10390 rtw_clean_pattern(adapter);
10391 RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
10392 break;
10393 case 1:
10394 #if defined(CONFIG_WOW_PATTERN_IN_TXFIFO)
10395 RTW_INFO("%s Patterns have been downloaded in rsvd pages\n", __func__);
10396 #else
10397 rtw_set_default_pattern(adapter);
10398 rtw_fill_pattern(adapter);
10399 RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
10400 #endif
10401 break;
10402 case 2:
10403 rtw_clean_pattern(adapter);
10404 rtw_wow_pattern_sw_reset(adapter);
10405 RTW_INFO("%s: clean patterns\n", __func__);
10406 break;
10407 default:
10408 RTW_INFO("%s: unknown mode\n", __func__);
10409 break;
10410 }
10411 }
10412
rtw_hal_wow_enable(_adapter * adapter)10413 static void rtw_hal_wow_enable(_adapter *adapter)
10414 {
10415 struct registry_priv *registry_par = &adapter->registrypriv;
10416 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10417 struct security_priv *psecuritypriv = &adapter->securitypriv;
10418 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10419 struct sta_info *psta = NULL;
10420 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
10421 int res;
10422 u16 media_status_rpt;
10423 u8 no_wake = 0, i;
10424 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
10425 _adapter *iface;
10426 #ifdef CONFIG_GPIO_WAKEUP
10427 u8 val8 = 0;
10428 #endif
10429
10430 #ifdef CONFIG_LPS_PG
10431 u8 lps_pg_hdl_id = 0;
10432 #endif
10433
10434
10435
10436 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF &&
10437 !check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
10438 no_wake = 1;
10439
10440 RTW_PRINT(FUNC_ADPT_FMT " WOWLAN_ENABLE\n", FUNC_ADPT_ARG(adapter));
10441 rtw_hal_gate_bb(adapter, _TRUE);
10442
10443 for (i = 0; i < dvobj->iface_nums; i++) {
10444 iface = dvobj->padapters[i];
10445 /* Start Usb TxDMA */
10446 if(iface) {
10447 RTW_INFO(ADPT_FMT "enable TX\n", ADPT_ARG(iface));
10448 RTW_ENABLE_FUNC(iface, DF_TX_BIT);
10449 }
10450 }
10451
10452 #ifdef CONFIG_GTK_OL
10453 if (psecuritypriv->binstallKCK_KEK == _TRUE)
10454 rtw_hal_fw_sync_cam_id(adapter);
10455 #endif
10456 if (IS_HARDWARE_TYPE_8723B(adapter))
10457 rtw_hal_backup_rate(adapter);
10458
10459 rtw_hal_fw_dl(adapter, _TRUE);
10460 if(no_wake)
10461 media_status_rpt = RT_MEDIA_DISCONNECT;
10462 else
10463 media_status_rpt = RT_MEDIA_CONNECT;
10464 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10465 (u8 *)&media_status_rpt);
10466
10467 /* RX DMA stop */
10468 #if defined(CONFIG_RTL8188E)
10469 if (IS_HARDWARE_TYPE_8188E(adapter))
10470 rtw_hal_disable_tx_report(adapter);
10471 #endif
10472
10473 res = rtw_hal_pause_rx_dma(adapter);
10474 if (res == _FAIL)
10475 RTW_PRINT("[WARNING] pause RX DMA fail\n");
10476
10477 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10478 /* Reconfig RX_FF Boundary */
10479 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10480 rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
10481 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10482 #endif
10483
10484 /* redownload wow pattern */
10485 if(!no_wake)
10486 rtw_hal_dl_pattern(adapter, 1);
10487
10488 if (!pwrctl->wowlan_pno_enable) {
10489 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10490
10491 if (psta != NULL) {
10492 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10493 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10494 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10495 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10496 #endif
10497 if(!no_wake)
10498 rtw_sta_media_status_rpt(adapter, psta, 1);
10499 }
10500 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10501 else {
10502 if(registry_par->suspend_type == FW_IPS_WRC) {
10503 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10504 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10505 rtw_hal_set_default_port_id_cmd(adapter, 0);
10506 }
10507 }
10508 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10509 }
10510 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10511 else {
10512 rtw_hal_set_default_port_id_cmd(adapter, 0);
10513 }
10514 #endif /* CONFIG_FW_MULTI_PORT_SUPPORT */
10515
10516 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10517 /* Enable CPWM2 only. */
10518 res = rtw_hal_enable_cpwm2(adapter);
10519 if (res == _FAIL)
10520 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
10521 #endif
10522 #ifdef CONFIG_GPIO_WAKEUP
10523 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10524 rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10525 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10526 #else
10527 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10528 if (pwrctl->is_high_active == 0)
10529 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10530 else
10531 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10532 GPIO_OUTPUT_LOW);
10533 #else
10534 val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
10535 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index, val8);
10536 rtw_hal_switch_gpio_wl_ctrl(adapter, pwrctl->wowlan_gpio_index, _TRUE);
10537 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow suspend and %s_ACTIVE.\n",
10538 __func__, pwrctl->wowlan_gpio_index,
10539 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10540 pwrctl->is_high_active ? "HIGI" : "LOW");
10541 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10542 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10543 #endif /* CONFIG_GPIO_WAKEUP */
10544 /* Set WOWLAN H2C command. */
10545 RTW_PRINT("Set WOWLan cmd\n");
10546 rtw_hal_set_fw_wow_related_cmd(adapter, 1);
10547
10548 res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
10549
10550 if (res == _FALSE)
10551 RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
10552
10553 pwrctl->wowlan_wake_reason =
10554 rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10555
10556 RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
10557 pwrctl->wowlan_wake_reason);
10558
10559 #if defined(RTW_HALMAC) && defined(CONFIG_PNO_SUPPORT)
10560 if(pwrctl->wowlan_pno_enable)
10561 rtw_halmac_pno_scanoffload(adapter->dvobj, 1);
10562 #endif
10563
10564 #ifdef CONFIG_GTK_OL_DBG
10565 dump_sec_cam(RTW_DBGDUMP, adapter);
10566 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
10567 #endif
10568
10569 #ifdef CONFIG_LPS_PG
10570 if (pwrctl->lps_level == LPS_PG) {
10571 lps_pg_hdl_id = LPS_PG_INFO_CFG;
10572 rtw_hal_set_hwreg(adapter, HW_VAR_LPS_PG_HANDLE, (u8 *)(&lps_pg_hdl_id));
10573 }
10574 #endif
10575
10576 #ifdef CONFIG_USB_HCI
10577 /* free adapter's resource */
10578 rtw_mi_intf_stop(adapter);
10579
10580 #endif
10581 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
10582 /* Invoid SE0 reset signal during suspending*/
10583 rtw_write8(adapter, REG_RSV_CTRL, 0x20);
10584 if (IS_8188F(pHalData->version_id) == FALSE
10585 && IS_8188GTV(pHalData->version_id) == FALSE)
10586 rtw_write8(adapter, REG_RSV_CTRL, 0x60);
10587 #endif
10588
10589 rtw_hal_gate_bb(adapter, _FALSE);
10590 }
10591
10592 #define DBG_WAKEUP_REASON
10593 #ifdef DBG_WAKEUP_REASON
_dbg_wake_up_reason_string(_adapter * adapter,const char * srt_res)10594 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
10595 {
10596 RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
10597 }
_dbg_rtw_wake_up_reason(_adapter * adapter,u8 reason)10598 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
10599 {
10600 if (RX_PAIRWISEKEY == reason)
10601 _dbg_wake_up_reason_string(adapter, "Rx pairwise key");
10602 else if (RX_GTK == reason)
10603 _dbg_wake_up_reason_string(adapter, "Rx GTK");
10604 else if (RX_FOURWAY_HANDSHAKE == reason)
10605 _dbg_wake_up_reason_string(adapter, "Rx four way handshake");
10606 else if (RX_DISASSOC == reason)
10607 _dbg_wake_up_reason_string(adapter, "Rx disassoc");
10608 else if (RX_DEAUTH == reason)
10609 _dbg_wake_up_reason_string(adapter, "Rx deauth");
10610 else if (RX_ARP_REQUEST == reason)
10611 _dbg_wake_up_reason_string(adapter, "Rx ARP request");
10612 else if (FW_DECISION_DISCONNECT == reason)
10613 _dbg_wake_up_reason_string(adapter, "FW detect disconnect");
10614 else if (RX_MAGIC_PKT == reason)
10615 _dbg_wake_up_reason_string(adapter, "Rx magic packet");
10616 else if (RX_UNICAST_PKT == reason)
10617 _dbg_wake_up_reason_string(adapter, "Rx unicast packet");
10618 else if (RX_PATTERN_PKT == reason)
10619 _dbg_wake_up_reason_string(adapter, "Rx pattern packet");
10620 else if (RX_PNO == reason)
10621 _dbg_wake_up_reason_string(adapter, "RX PNO");
10622 else if (RTD3_SSID_MATCH == reason)
10623 _dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
10624 else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
10625 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
10626 else if (RX_REALWOW_V2_ACK_LOST == reason)
10627 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
10628 else if (ENABLE_FAIL_DMA_IDLE == reason)
10629 _dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
10630 else if (ENABLE_FAIL_DMA_PAUSE == reason)
10631 _dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
10632 else if (AP_OFFLOAD_WAKEUP == reason)
10633 _dbg_wake_up_reason_string(adapter, "AP offload wakeup");
10634 else if (CLK_32K_UNLOCK == reason)
10635 _dbg_wake_up_reason_string(adapter, "clk 32k unlock");
10636 else if (RTIME_FAIL_DMA_IDLE == reason)
10637 _dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
10638 else if (CLK_32K_LOCK == reason)
10639 _dbg_wake_up_reason_string(adapter, "clk 32k lock");
10640 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10641 else if (WOW_KEEPALIVE_ACK_TIMEOUT == reason)
10642 _dbg_wake_up_reason_string(adapter, "rx keep alive ack timeout");
10643 else if (WOW_KEEPALIVE_WAKE == reason)
10644 _dbg_wake_up_reason_string(adapter, "rx keep alive wake pattern");
10645 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
10646 else
10647 _dbg_wake_up_reason_string(adapter, "unknown reasoen");
10648 }
10649 #endif
10650
rtw_hal_wow_disable(_adapter * adapter)10651 static void rtw_hal_wow_disable(_adapter *adapter)
10652 {
10653 int i;
10654 struct recv_reorder_ctrl *preorder_ctrl;
10655 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10656 struct security_priv *psecuritypriv = &adapter->securitypriv;
10657 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10658 struct sta_info *psta = NULL;
10659 struct registry_priv *registry_par = &adapter->registrypriv;
10660 int res;
10661 u16 media_status_rpt;
10662
10663 RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
10664
10665 if(registry_par->suspend_type == FW_IPS_DISABLE_BBRF && !check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
10666 RTW_INFO("FW_IPS_DISABLE_BBRF resume\n");
10667 return;
10668 }
10669
10670 if (!pwrctl->wowlan_pno_enable) {
10671 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
10672 if (psta != NULL)
10673 rtw_sta_media_status_rpt(adapter, psta, 0);
10674 else
10675 RTW_INFO("%s: psta is null\n", __func__);
10676 }
10677 #if defined(RTW_HALMAC) && defined(CONFIG_PNO_SUPPORT)
10678 else {
10679 rtw_halmac_pno_scanoffload(adapter->dvobj, 0);
10680 }
10681 #endif
10682
10683 if (0) {
10684 RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
10685 RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
10686 RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
10687 RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
10688 }
10689
10690 pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
10691
10692 RTW_PRINT("wakeup_reason: 0x%02x\n",
10693 pwrctl->wowlan_wake_reason);
10694 #ifdef DBG_WAKEUP_REASON
10695 _dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
10696 #endif
10697
10698 rtw_hal_set_fw_wow_related_cmd(adapter, 0);
10699
10700 res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
10701
10702 #if defined(CONFIG_RTL8188E)
10703 if (IS_HARDWARE_TYPE_8188E(adapter))
10704 rtw_hal_enable_tx_report(adapter);
10705 #endif
10706
10707 if ((pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10708 (pwrctl->wowlan_wake_reason != RX_DEAUTH) &&
10709 (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
10710 (pwrctl->wowlan_wake_reason != NO_WAKE_RX_PAIRWISEKEY) &&
10711 (pwrctl->wowlan_wake_reason != NO_WAKE_RX_GTK) &&
10712 (pwrctl->wowlan_wake_reason != NO_WAKE_RX_DISASSOC) &&
10713 (pwrctl->wowlan_wake_reason != NO_WAKE_RX_DEAUTH) &&
10714 (pwrctl->wowlan_wake_reason != NO_WAKE_RX_EAPREQ_IDENTIFY)) {
10715 rtw_hal_get_aoac_rpt(adapter);
10716 rtw_hal_update_sw_security_info(adapter);
10717 }
10718
10719 if (res == _FALSE) {
10720 RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
10721 rtw_hal_force_enable_rxdma(adapter);
10722 }
10723
10724 rtw_hal_gate_bb(adapter, _TRUE);
10725
10726 res = rtw_hal_pause_rx_dma(adapter);
10727 if (res == _FAIL)
10728 RTW_PRINT("[WARNING] pause RX DMA fail\n");
10729
10730 /* clean HW pattern match */
10731 rtw_hal_dl_pattern(adapter, 0);
10732
10733 #ifndef CONFIG_WOW_PATTERN_HW_CAM
10734 /* config RXFF boundary to original */
10735 #ifndef CONFIG_WOW_PATTERN_IN_TXFIFO
10736 rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
10737 #endif /*CONFIG_WOW_PATTERN_IN_TXFIFO*/
10738 #endif
10739 rtw_hal_release_rx_dma(adapter);
10740
10741 rtw_hal_fw_dl(adapter, _FALSE);
10742
10743 #ifdef CONFIG_GPIO_WAKEUP
10744
10745 #ifdef CONFIG_RTW_ONE_PIN_GPIO
10746 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10747 #else
10748 #ifdef CONFIG_WAKEUP_GPIO_INPUT_MODE
10749 if (pwrctl->is_high_active == 0)
10750 rtw_hal_set_input_gpio(adapter, pwrctl->wowlan_gpio_index);
10751 else
10752 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index,
10753 GPIO_OUTPUT_LOW);
10754 #else
10755 rtw_hal_set_output_gpio(adapter, pwrctl->wowlan_gpio_index
10756 , pwrctl->wowlan_gpio_output_state);
10757 RTW_INFO("%s: set GPIO_%d to OUTPUT %s state in wow resume and %s_ACTIVE.\n",
10758 __func__, pwrctl->wowlan_gpio_index,
10759 pwrctl->wowlan_gpio_output_state ? "HIGH" : "LOW",
10760 pwrctl->is_high_active ? "HIGI" : "LOW");
10761 #endif /* CONFIG_WAKEUP_GPIO_INPUT_MODE */
10762 #endif /* CONFIG_RTW_ONE_PIN_GPIO */
10763 #endif /* CONFIG_GPIO_WAKEUP */
10764 if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
10765 (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
10766 (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
10767 (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
10768
10769 media_status_rpt = RT_MEDIA_CONNECT;
10770 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
10771 (u8 *)&media_status_rpt);
10772
10773 if (psta != NULL) {
10774 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
10775 adapter_to_dvobj(adapter)->dft.port_id = 0xFF;
10776 adapter_to_dvobj(adapter)->dft.mac_id = 0xFF;
10777 rtw_hal_set_default_port_id_cmd(adapter, psta->cmn.mac_id);
10778 #endif
10779 rtw_sta_media_status_rpt(adapter, psta, 1);
10780 }
10781 }
10782
10783 if (psta != NULL) {
10784 RTW_PRINT("rtw_set_bit RTW_RECV_REORDER_WOW\n");
10785 for (i = 0; i < TID_NUM; i++) {
10786 preorder_ctrl = &psta->recvreorder_ctrl[i];
10787 rtw_set_bit(RTW_RECV_REORDER_WOW,
10788 &preorder_ctrl->rec_abba_rsp_ack);
10789 }
10790 }
10791
10792 rtw_hal_gate_bb(adapter, _FALSE);
10793 }
10794 #if defined(CONFIG_WOW_PATTERN_IN_TXFIFO)
rtw_hal_construct_pattern_info(PADAPTER padapter,u8 * pframe,u32 * pLength)10795 static void rtw_hal_construct_pattern_info(
10796 PADAPTER padapter,
10797 u8 *pframe,
10798 u32 *pLength
10799 )
10800 {
10801
10802 u32 pattern_info_len = 0;
10803 int i = 0, total = 0, index;
10804 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
10805 struct rtl_wow_pattern wow_pattern;
10806 u32 page_sz = 0;
10807
10808 total = pwrpriv->wowlan_pattern_idx;
10809
10810 if (total > MAX_WKFM_CAM_NUM)
10811 total = MAX_WKFM_CAM_NUM;
10812
10813 /* Generate default pattern */
10814 rtw_set_default_pattern(padapter);
10815
10816 /* Convert pattern to WKFM_CAM pattern */
10817 for (i = 0 ; i < total ; i++) {
10818 if (_SUCCESS == rtw_hal_wow_pattern_generate(padapter, i, &wow_pattern)) {
10819
10820 index = i;
10821 if (!pwrpriv->bInSuspend)
10822 index += 2;
10823 #ifdef CONFIG_WOW_PATTERN_IN_TXFIFO_DBG
10824 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
10825 #endif
10826
10827 if (rtw_write_to_frame_mask_buf(padapter, index, &wow_pattern,
10828 pframe, &pattern_info_len) == _FALSE)
10829 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
10830 }
10831 }
10832 *pLength = pattern_info_len;
10833
10834
10835 }
10836 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
rtw_hal_set_wow_fw_rsvd_page(_adapter * adapter,u8 * pframe,u16 index,u8 tx_desc,u32 page_size,u8 * page_num,u32 * total_pkt_len,RSVDPAGE_LOC * rsvd_page_loc)10837 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
10838 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
10839 RSVDPAGE_LOC *rsvd_page_loc)
10840 {
10841 struct security_priv *psecuritypriv = &adapter->securitypriv;
10842 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
10843 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
10844 struct mlme_ext_priv *pmlmeext;
10845 struct mlme_ext_info *pmlmeinfo;
10846 u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
10847 u32 ProbeReqLength = 0, ns_len = 0, rc_len = 0;
10848 u8 CurtPktPageNum = 0;
10849 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10850 u32 keep_alive_len=0;
10851 int i;
10852 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN */
10853 #ifdef CONFIG_WAR_OFFLOAD
10854 u16 tmp_idx = 0;
10855 u32 buf_len = 0;
10856 #endif
10857
10858 #ifdef CONFIG_GTK_OL
10859 struct sta_priv *pstapriv = &adapter->stapriv;
10860 struct sta_info *psta;
10861 struct security_priv *psecpriv = &adapter->securitypriv;
10862 u8 kek[RTW_KEK_LEN];
10863 u8 kck[RTW_KCK_LEN];
10864 #endif /* CONFIG_GTK_OL */
10865 #ifdef CONFIG_PNO_SUPPORT
10866 int pno_index;
10867 u8 ssid_num;
10868 #endif /* CONFIG_PNO_SUPPORT */
10869 #ifdef CONFIG_WOW_PATTERN_IN_TXFIFO
10870 u32 PatternLen = 0;
10871 u32 cam_start_offset = 0;
10872 u32 reg_cam_start_offset_val = 0;
10873 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
10874
10875 pmlmeext = &adapter->mlmeextpriv;
10876 pmlmeinfo = &pmlmeext->mlmext_info;
10877
10878 if (pwrctl->wowlan_pno_enable == _FALSE) {
10879 /* ARP RSP * 1 page */
10880
10881 rsvd_page_loc->LocArpRsp = *page_num;
10882
10883 RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
10884
10885 #ifdef CONFIG_WAR_OFFLOAD
10886 if ((0 != pwrctl->wowlan_war_offload_ipv4.ip_addr[0]) &&
10887 (_FALSE == _rtw_memcmp(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4))) {
10888 _rtw_memcpy(pmlmeinfo->ip_addr, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4);
10889 RTW_INFO("Update IP(%d.%d.%d.%d) to arp rsvd page\n",
10890 pmlmeinfo->ip_addr[0], pmlmeinfo->ip_addr[1],
10891 pmlmeinfo->ip_addr[2], pmlmeinfo->ip_addr[3]);
10892 }
10893 #endif /* CONFIG_WAR_OFFLOAD */
10894
10895
10896 rtw_hal_construct_ARPRsp(adapter, &pframe[index],
10897 &ARPLength, pmlmeinfo->ip_addr);
10898
10899 rtw_hal_fill_fake_txdesc(adapter,
10900 &pframe[index - tx_desc],
10901 ARPLength, _FALSE, _FALSE, _TRUE);
10902
10903 CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
10904
10905 *page_num += CurtPktPageNum;
10906
10907 index += (CurtPktPageNum * page_size);
10908 RSVD_PAGE_CFG("WOW-ARPRsp", CurtPktPageNum, *page_num, 0);
10909 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10910 /* Keep Alive * ? page*/
10911 if(pwrctl->keep_alive_pattern_len){
10912 rsvd_page_loc->LocKeepAlive = *page_num;
10913 pwrctl->keep_alive_pattern_loc = rsvd_page_loc->LocKeepAlive;
10914 RTW_INFO("pwrctl->keep_alive_pattern_loc: %d\n", pwrctl->keep_alive_pattern_loc);
10915 rtw_hal_construct_keepalive(adapter,&pframe[index],&keep_alive_len);
10916 rtw_hal_fill_fake_txdesc(adapter,
10917 &pframe[index - tx_desc],
10918 keep_alive_len, _FALSE, _FALSE, _TRUE);
10919 CurtPktPageNum = (u8)PageNum(tx_desc + keep_alive_len, page_size);
10920 *page_num += CurtPktPageNum;
10921 index += (CurtPktPageNum * page_size);
10922 RSVD_PAGE_CFG("WOW-KeepAlive:", CurtPktPageNum, *page_num, 0);
10923 }
10924 #endif /* CONFIG_WOW_KEEP_ALIVE_PATTERN*/
10925
10926 #ifdef CONFIG_IPV6
10927 /* 2 NS offload and NDP Info*/
10928 if (pwrctl->wowlan_ns_offload_en == _TRUE) {
10929 rsvd_page_loc->LocNbrAdv = *page_num;
10930 RTW_INFO("LocNbrAdv: %d\n", rsvd_page_loc->LocNbrAdv);
10931 rtw_hal_construct_na_message(adapter,
10932 &pframe[index], &ns_len);
10933 rtw_hal_fill_fake_txdesc(adapter,
10934 &pframe[index - tx_desc],
10935 ns_len, _FALSE,
10936 _FALSE, _TRUE);
10937 CurtPktPageNum = (u8)PageNum(tx_desc + ns_len,
10938 page_size);
10939 *page_num += CurtPktPageNum;
10940 index += (CurtPktPageNum * page_size);
10941 RSVD_PAGE_CFG("WOW-NbrAdv", CurtPktPageNum, *page_num, 0);
10942
10943 rsvd_page_loc->LocNDPInfo = *page_num;
10944 RTW_INFO("LocNDPInfo: %d\n",
10945 rsvd_page_loc->LocNDPInfo);
10946
10947 rtw_hal_construct_ndp_info(adapter,
10948 &pframe[index - tx_desc],
10949 &ns_len);
10950 CurtPktPageNum =
10951 (u8)PageNum(tx_desc + ns_len, page_size);
10952 *page_num += CurtPktPageNum;
10953 index += (CurtPktPageNum * page_size);
10954 RSVD_PAGE_CFG("WOW-NDPInfo", CurtPktPageNum, *page_num, 0);
10955
10956 }
10957 #endif /*CONFIG_IPV6*/
10958 /* 3 Remote Control Info. * 1 page */
10959 rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
10960 RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
10961 rtw_hal_construct_remote_control_info(adapter,
10962 &pframe[index - tx_desc],
10963 &rc_len);
10964 CurtPktPageNum = (u8)PageNum(rc_len, page_size);
10965 *page_num += CurtPktPageNum;
10966 *total_pkt_len = index + rc_len;
10967 RSVD_PAGE_CFG("WOW-RCI", CurtPktPageNum, *page_num, *total_pkt_len);
10968 #ifdef CONFIG_GTK_OL
10969 index += (CurtPktPageNum * page_size);
10970
10971 /* if the ap staion info. exists, get the kek, kck from staion info. */
10972 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
10973 if (psta == NULL) {
10974 _rtw_memset(kek, 0, RTW_KEK_LEN);
10975 _rtw_memset(kck, 0, RTW_KCK_LEN);
10976 RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
10977 __func__);
10978 } else {
10979 _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
10980 _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
10981 }
10982
10983 /* 3 KEK, KCK */
10984 rsvd_page_loc->LocGTKInfo = *page_num;
10985 RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
10986
10987 if (IS_HARDWARE_TYPE_8188E(adapter) || IS_HARDWARE_TYPE_8812(adapter)) {
10988 struct security_priv *psecpriv = NULL;
10989
10990 psecpriv = &adapter->securitypriv;
10991 _rtw_memcpy(pframe + index - tx_desc,
10992 &psecpriv->dot11PrivacyAlgrthm, 1);
10993 _rtw_memcpy(pframe + index - tx_desc + 1,
10994 &psecpriv->dot118021XGrpPrivacy, 1);
10995 _rtw_memcpy(pframe + index - tx_desc + 2,
10996 kck, RTW_KCK_LEN);
10997 _rtw_memcpy(pframe + index - tx_desc + 2 + RTW_KCK_LEN,
10998 kek, RTW_KEK_LEN);
10999 CurtPktPageNum = (u8)PageNum(tx_desc + 2 + RTW_KCK_LEN + RTW_KEK_LEN, page_size);
11000 } else {
11001
11002 _rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
11003 _rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
11004 kek, RTW_KEK_LEN);
11005 GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
11006
11007 if (psta != NULL &&
11008 psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
11009 _rtw_memcpy(pframe + index - tx_desc + 56,
11010 &psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
11011 GTKLength += RTW_TKIP_MIC_LEN;
11012 }
11013 CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
11014 }
11015 #if 0
11016 {
11017 int i;
11018 printk("\ntoFW KCK: ");
11019 for (i = 0; i < 16; i++)
11020 printk(" %02x ", kck[i]);
11021 printk("\ntoFW KEK: ");
11022 for (i = 0; i < 16; i++)
11023 printk(" %02x ", kek[i]);
11024 printk("\n");
11025 }
11026
11027 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
11028 __FUNCTION__, &pframe[index - tx_desc],
11029 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
11030 #endif
11031
11032 *page_num += CurtPktPageNum;
11033
11034 index += (CurtPktPageNum * page_size);
11035 RSVD_PAGE_CFG("WOW-GTKInfo", CurtPktPageNum, *page_num, 0);
11036
11037 /* 3 GTK Response */
11038 rsvd_page_loc->LocGTKRsp = *page_num;
11039 RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
11040 rtw_hal_construct_GTKRsp(adapter, &pframe[index], >KLength);
11041
11042 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11043 GTKLength, _FALSE, _FALSE, _TRUE);
11044 #if 0
11045 {
11046 int gj;
11047 printk("123GTK pkt=>\n");
11048 for (gj = 0; gj < GTKLength + tx_desc; gj++) {
11049 printk(" %02x ", pframe[index - tx_desc + gj]);
11050 if ((gj + 1) % 16 == 0)
11051 printk("\n");
11052 }
11053 printk(" <=end\n");
11054 }
11055
11056 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
11057 __FUNCTION__, &pframe[index - tx_desc],
11058 (tx_desc + GTKLength));
11059 #endif
11060
11061 CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
11062
11063 *page_num += CurtPktPageNum;
11064
11065 index += (CurtPktPageNum * page_size);
11066 RSVD_PAGE_CFG("WOW-GTKRsp", CurtPktPageNum, *page_num, 0);
11067
11068 /* below page is empty for GTK extension memory */
11069 /* 3(11) GTK EXT MEM */
11070 rsvd_page_loc->LocGTKEXTMEM = *page_num;
11071 RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
11072 CurtPktPageNum = 2;
11073
11074 if (page_size >= 256)
11075 CurtPktPageNum = 1;
11076
11077 *page_num += CurtPktPageNum;
11078 /* extension memory for FW */
11079 *total_pkt_len = index + (page_size * CurtPktPageNum);
11080 RSVD_PAGE_CFG("WOW-GTKEXTMEM", CurtPktPageNum, *page_num, *total_pkt_len);
11081 #endif /* CONFIG_GTK_OL */
11082
11083 index += (CurtPktPageNum * page_size);
11084
11085 #ifdef CONFIG_WAR_OFFLOAD
11086 if(_TRUE == pwrctl->wowlan_war_offload_mode) {
11087 u8 zero_ary[16] = {0x00};
11088 u8 war_tmp_cnt = 0;
11089
11090 /* Reserve 2 page for Ip parameters */
11091 /* First page
11092 | Byte 15 -----------Byte 0 |
11093 | IP-4 | IP-3 | IP-2 | IP-1 |
11094 | location of each feature | mac addr |
11095 | NetBIOS name |
11096 | location of each feature |
11097 Second page
11098 | IPv6 - 1 |
11099 | IPv6 - 2 |
11100 | IPv6 - 3 |
11101 | IPv6 - 4 |
11102 | IPv6 - 5 |
11103 | IPv6 - 6 |
11104 | IPv6 - 7 |
11105 | IPv6 - 8 |
11106 */
11107
11108 /* location of each feature : Byte 22 ~ Byte 31
11109 * Byte22 : location of SNMP RX
11110 * Byte23 : location of SNMP V4
11111 * Byte24 : location of SNMP V6
11112 * Byte25 : location of MDNS Param
11113 * Byte26 : location of MDNS V4
11114 * Byte27 : location of MDNS V6
11115 * Byte28 : location of SSDP pattern
11116 * Byte29 : location of WSD pattern
11117 * Byte30 : location of SLP pattern
11118 * Byte31 : location of LLMNR
11119 */
11120
11121 /* ipv4 : 4 */
11122 if (0 == pwrctl->wowlan_war_offload_ipv4.ip_addr[0])
11123 _rtw_memcpy(&pwrctl->wowlan_war_offload_ipv4.ip_addr[0], pmlmeinfo->ip_addr, 4);
11124 for(war_tmp_cnt=0; war_tmp_cnt<4 ;war_tmp_cnt++)
11125 _rtw_memcpy(pframe + index - tx_desc + (war_tmp_cnt*4), &pwrctl->wowlan_war_offload_ipv4.ip_addr[war_tmp_cnt], 4);
11126
11127 if (is_zero_mac_addr(pwrctl->wowlan_war_offload_mac)) {
11128 _rtw_memcpy(pwrctl->wowlan_war_offload_mac, adapter_mac_addr(adapter), 6);
11129 }
11130 _rtw_memcpy(pframe + index + 16 - tx_desc, pwrctl->wowlan_war_offload_mac, 6);
11131
11132
11133 /* ipv6 : 8 */
11134 if (_TRUE == _rtw_memcmp(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], zero_ary, RTW_IPv6_ADDR_LEN))
11135 _rtw_memcpy(pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], pmlmeinfo->ip6_addr, RTW_IPv6_ADDR_LEN);
11136
11137 for(war_tmp_cnt=0; war_tmp_cnt<8 ;war_tmp_cnt++)
11138 _rtw_memcpy(pframe + index + page_size - tx_desc + (war_tmp_cnt*16), pwrctl->wowlan_war_offload_ipv6.ipv6_addr[war_tmp_cnt], 16);
11139
11140 rsvd_page_loc->LocIpParm = *page_num;
11141
11142 tmp_idx = index;
11143 CurtPktPageNum = 2;
11144 *page_num += CurtPktPageNum;
11145 *total_pkt_len = index + (page_size * CurtPktPageNum);
11146 index += (CurtPktPageNum * page_size);
11147
11148
11149 #if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6)
11150 if ( (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) ||
11151 (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) ||
11152 (WAR_MDNS_V4_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl) ||
11153 (WAR_MDNS_V6_WAKEUP_EN & pwrctl->wowlan_war_offload_ctrl)) {
11154
11155 struct war_mdns_service_info *psinfo = pwrctl->wowlan_war_offload_mdns_service;
11156 u8 txt_in_ptr[31]={ 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
11157 0x00, 0x13, 0x09, 0x74, 0x78, 0x74, 0x76, 0x65, 0x72, 0x73,
11158 0x3d, 0x31, 0x08, 0x71, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x3d, 0x31};
11159 u16 mdns_offset = index - tx_desc;
11160 u8 i = 0;
11161
11162 rsvd_page_loc->LocMdnsPara = *page_num;
11163 RTW_INFO("LocMdnsPara : %d\n", rsvd_page_loc->LocMdnsPara);
11164
11165 /* 1. service info */
11166 pframe[mdns_offset] = 0x01; // TLV(T)
11167 mdns_offset += 1;
11168 _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_service_info_num, 1);
11169 mdns_offset += 1;
11170
11171 for(i=0; i<pwrctl->wowlan_war_offload_mdns_service_info_num ;i++)
11172 {
11173 u16 srv_rsp_len = 0;
11174
11175 // 1.1 : construct service name string
11176 // : length of total service name string (service+transport+domain)
11177 pframe[mdns_offset] = psinfo[i].service_len + psinfo[i].transport_len + psinfo[i].domain_len + 4;
11178 mdns_offset += 1;
11179
11180 // : service name
11181 pframe[mdns_offset] = psinfo[i].service_len;
11182 mdns_offset += 1;
11183 _rtw_memcpy(pframe + mdns_offset, &psinfo[i].service, psinfo[i].service_len);
11184 mdns_offset += psinfo[i].service_len;
11185
11186 // : transport name
11187 pframe[mdns_offset] = psinfo[i].transport_len;
11188 mdns_offset += 1;
11189 _rtw_memcpy(pframe + mdns_offset, &psinfo[i].transport, psinfo[i].transport_len);
11190 mdns_offset += psinfo[i].transport_len;
11191
11192 // : domain name
11193 pframe[mdns_offset] = psinfo[i].domain_len;
11194 mdns_offset += 1;
11195 _rtw_memcpy(pframe + mdns_offset, &psinfo[i].domain, psinfo[i].domain_len);
11196 mdns_offset += psinfo[i].domain_len;
11197
11198 // : delimiter
11199 mdns_offset += 1;
11200
11201 // 1.2 : construct type srv rsp
11202 pframe[mdns_offset] = psinfo[i].target_len + 19; // length
11203 pframe[mdns_offset + 2] = 0x21; // rsp type (srv)
11204 pframe[mdns_offset + 4] = 0x01; // cache flush + class
11205 _rtw_memcpy(pframe + mdns_offset + 5, &psinfo[i].ttl, 4); // ttl
11206 pframe[mdns_offset + 5] = (u8) ( (psinfo[i].ttl & 0xff000000) >> 24); // ttl - byte0
11207 pframe[mdns_offset + 6] = (u8) ( (psinfo[i].ttl & 0x00ff0000) >> 16); // ttl - byte1
11208 pframe[mdns_offset + 7] = (u8) ( (psinfo[i].ttl & 0x0000ff00) >> 8 ); // ttl - byte2
11209 pframe[mdns_offset + 8] = (u8) (psinfo[i].ttl & 0x000000ff); // ttl - byte3
11210 pframe[mdns_offset + 10] = psinfo[i].target_len + 9; // data length
11211 _rtw_memcpy(pframe + mdns_offset + 15, &psinfo[i].port, 2); // port
11212 _rtw_memcpy(pframe + mdns_offset + 17, &psinfo[i].target_len, 1); // target len
11213 _rtw_memcpy(pframe + mdns_offset + 18, &psinfo[i].target, psinfo[i].target_len); // target
11214 pframe[mdns_offset + 18 + psinfo[i].target_len] = 0xc0; // message compresion, offset will be filled by fw.
11215 mdns_offset += (1 + psinfo[i].target_len + 19);
11216
11217 // 1.3 : set the idx of txt rsp
11218 pframe[mdns_offset] = psinfo[i].txt_rsp_idx;
11219 mdns_offset += 1;
11220 }
11221
11222 /* 2. machine name */
11223 pframe[mdns_offset] = 0x02; // TLV(T)
11224 mdns_offset += 1;
11225 _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_mnane_num, 1); // NUM
11226 mdns_offset += 1;
11227
11228 for(i=0; i<pwrctl->wowlan_war_offload_mdns_mnane_num; i++)
11229 {
11230 pframe[mdns_offset] = pwrctl->wowlan_war_offload_mdns_mnane[i].name_len;
11231 _rtw_memcpy(pframe + mdns_offset + 1, pwrctl->wowlan_war_offload_mdns_mnane[i].name,
11232 pwrctl->wowlan_war_offload_mdns_mnane[i].name_len); // machine name
11233 mdns_offset += (1+pwrctl->wowlan_war_offload_mdns_mnane[i].name_len);
11234 }
11235
11236 /* 3. A rsp */
11237 pframe[mdns_offset] = 0x03; // TLV(T)
11238 pframe[mdns_offset + 1] = 14; // TLV(L)
11239 pframe[mdns_offset + 3] = 0x01; // rsp type (a)
11240 pframe[mdns_offset + 5] = 0x01; // cache flush + class
11241 pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec)
11242 pframe[mdns_offset + 11] = 4; // length of ipv4 addr.
11243 _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv4.ip_addr[0], 4);
11244 mdns_offset += (2 + 14);
11245
11246 /* 4. AAAA rsp */
11247 pframe[mdns_offset] = 0x04; // TLV(T)
11248 pframe[mdns_offset + 1] = 26; // TLV(L)
11249 pframe[mdns_offset + 3] = 0x1c; // rsp type (aaaa)
11250 pframe[mdns_offset + 5] = 0x01; // cache flush + class
11251 pframe[mdns_offset + 9] = 0xf0; // ttl (240 sec)
11252 pframe[mdns_offset + 11] = 16; // length of ipv6 addr.
11253 _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_ipv6.ipv6_addr[0], 16);
11254 mdns_offset += (2 + 26);
11255
11256 /* 5. PTR rsp */
11257 pframe[mdns_offset] = 0x05; // TLV(T)
11258 pframe[mdns_offset + 1] = 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // TLV(L)
11259 pframe[mdns_offset + 3] = 0x0c; // rsp type (aaaa)
11260 pframe[mdns_offset + 5] = 0x01; // cache flush + class
11261 pframe[mdns_offset + 8] = 0x1c; // ttl
11262 pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec)
11263 pframe[mdns_offset + 11] = 3 + pwrctl->wowlan_war_offload_mdns_domain_name_len; // data length
11264 pframe[mdns_offset + 12] = pwrctl->wowlan_war_offload_mdns_domain_name_len; // domain name length
11265 _rtw_memcpy(pframe + mdns_offset + 13, &pwrctl->wowlan_war_offload_mdns_domain_name,
11266 pwrctl->wowlan_war_offload_mdns_domain_name_len);
11267 pframe[mdns_offset + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len] = 0xc0; // message compression
11268 mdns_offset += (2 + 13 + pwrctl->wowlan_war_offload_mdns_domain_name_len);
11269
11270 /* 6. TXT in PTR rsp */
11271 pframe[mdns_offset] = 0x06; // TLV(T)
11272 pframe[mdns_offset + 1] = 31; // TLV(L)
11273 _rtw_memcpy(pframe + mdns_offset + 2, &txt_in_ptr, 31);
11274 mdns_offset += (2 + 31);
11275
11276 /* 7. TXT rsp */
11277 pframe[mdns_offset] = 0x07; // TLV(T)
11278 mdns_offset += 1;
11279 _rtw_memcpy(pframe + mdns_offset, &pwrctl->wowlan_war_offload_mdns_txt_rsp_num, 1); // NUM
11280 mdns_offset += 1;
11281
11282 for(i=0; i<pwrctl->wowlan_war_offload_mdns_txt_rsp_num; i++)
11283 {
11284 u16 txt_rsp_len = pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len;
11285
11286 if(pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len==0)
11287 {
11288 _rtw_memcpy(pframe + mdns_offset, &txt_rsp_len, 2);
11289 mdns_offset += ( 2 + txt_rsp_len );
11290 continue;
11291 }
11292
11293 txt_rsp_len += 10;
11294 _rtw_memcpy(pframe + mdns_offset, &txt_rsp_len, 2);
11295 pframe[mdns_offset + 3] = 0x10; // rsp type (txt)
11296 pframe[mdns_offset + 5] = 0x01; // cache flush + class
11297 pframe[mdns_offset + 8] = 0x1c; // ttl
11298 pframe[mdns_offset + 9] = 0x20; // ttl (7200 sec)
11299 pframe[mdns_offset + 10] = (u8) ((pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0xff00) >> 8);
11300 pframe[mdns_offset + 11] = (u8) (pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len & 0x00ff);
11301 _rtw_memcpy(pframe + mdns_offset + 12, &pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt,
11302 pwrctl->wowlan_war_offload_mdns_txt_rsp[i].txt_len);
11303 mdns_offset += ( 2 + txt_rsp_len );
11304 }
11305
11306 CurtPktPageNum = (u8)PageNum(mdns_offset - index, page_size)+1;
11307 *page_num += CurtPktPageNum;
11308 *total_pkt_len = index + (page_size * CurtPktPageNum);
11309 index += (CurtPktPageNum * page_size);
11310 }
11311 #endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */
11312
11313 #ifdef CONFIG_OFFLOAD_MDNS_V4
11314 if (WAR_MDNS_V4_RSP_EN & pwrctl->wowlan_war_offload_ctrl) {
11315 rsvd_page_loc->LocMdnsv4 = *page_num;
11316 RTW_INFO("LocMdnsv4: %d\n", rsvd_page_loc->LocMdnsv4);
11317
11318 rtw_hal_construct_mdns_rsp_v4(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr);
11319 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE);
11320 CurtPktPageNum = 16;
11321 *page_num += CurtPktPageNum;
11322 index += (CurtPktPageNum * page_size);
11323 }
11324 #endif /* CONFIG_OFFLOAD_MDNS_V4 */
11325
11326 #ifdef CONFIG_OFFLOAD_MDNS_V6
11327 if (WAR_MDNS_V6_RSP_EN & pwrctl->wowlan_war_offload_ctrl) {
11328 rsvd_page_loc->LocMdnsv6 = *page_num;
11329 RTW_INFO("LocMdnsv6: %d\n", rsvd_page_loc->LocMdnsv6);
11330
11331 rtw_hal_construct_mdns_rsp_v6(adapter, &pframe[index], &buf_len, pmlmeinfo->ip_addr);
11332 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc], buf_len, _FALSE, _FALSE, _TRUE);
11333 CurtPktPageNum = 16;
11334 *page_num += CurtPktPageNum;
11335 index += (CurtPktPageNum * page_size);
11336 }
11337 #endif /* CONFIG_OFFLOAD_MDNS_V6 */
11338
11339 #if defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6)
11340 *(pframe+tmp_idx+25-tx_desc) = rsvd_page_loc->LocMdnsPara;
11341 *(pframe+tmp_idx+26-tx_desc) = rsvd_page_loc->LocMdnsv4;
11342 *(pframe+tmp_idx+27-tx_desc) = rsvd_page_loc->LocMdnsv6;
11343 #endif /* defined(CONFIG_OFFLOAD_MDNS_V4) || defined(CONFIG_OFFLOAD_MDNS_V6) */
11344
11345 }
11346 //rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, rsvd_page_loc->LocIpParm, 46);
11347 #endif /* CONFIG_WAR_OFFLOAD */
11348
11349 #if defined(CONFIG_WOW_PATTERN_IN_TXFIFO)
11350 /* pattern_rsvd_page_loc will be used by rtw_read_from_frame_mask() */
11351 pwrctl->pattern_rsvd_page_loc = *page_num;
11352 RTW_INFO("LocPatternInfo: %d\n", pwrctl->pattern_rsvd_page_loc);
11353 rtw_hal_construct_pattern_info(adapter,
11354 &pframe[index - tx_desc],
11355 &PatternLen);
11356
11357 /* Set cam_start_offset to REG_TXBUF_WKCAM_OFFSET
11358 * Cam address(TxBufer pointer) access 8 bytes at a time
11359 */
11360
11361 // Get rsvd page start page number + pattern located page
11362 cam_start_offset = rtw_read8(adapter, REG_BCNQ_BDNY) + *page_num;
11363 cam_start_offset *= page_size;
11364 cam_start_offset /= 8;
11365
11366 reg_cam_start_offset_val = rtw_read32(adapter, REG_TXBUF_WKCAM_OFFSET);
11367 reg_cam_start_offset_val &= ~(WKCAM_OFFSET_BIT_MASK << WKCAM_OFFSET_BIT_MASK_OFFSET);
11368 reg_cam_start_offset_val |= (cam_start_offset << WKCAM_OFFSET_BIT_MASK_OFFSET);
11369 rtw_write32(adapter, REG_TXBUF_WKCAM_OFFSET, reg_cam_start_offset_val);
11370
11371 /* Set pattern number to REG_WKFMCAM_NUM */
11372 rtw_write8(adapter, REG_WKFMCAM_NUM, PatternLen / WKFMCAM_SIZE);
11373
11374 CurtPktPageNum = (u8)PageNum(PatternLen, page_size);
11375 *page_num += CurtPktPageNum;
11376 index += (CurtPktPageNum * page_size);
11377 RSVD_PAGE_CFG("WOW-PatternInfo", CurtPktPageNum, *page_num, index);
11378
11379 #endif /* CONFIG_WOW_PATTERN_IN_TXFIFO */
11380
11381 /*Reserve 1 page for AOAC report*/
11382 rsvd_page_loc->LocAOACReport = *page_num;
11383 RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
11384 *page_num += 1;
11385 *total_pkt_len = index + (page_size * 1);
11386 RSVD_PAGE_CFG("WOW-AOAC", 1, *page_num, *total_pkt_len);
11387
11388
11389 } else {
11390 #ifdef CONFIG_PNO_SUPPORT
11391 if (pwrctl->wowlan_in_resume == _FALSE &&
11392 pwrctl->pno_inited == _TRUE) {
11393 #ifndef RTW_HALMAC
11394 /* Broadcast Probe Request */
11395 rsvd_page_loc->LocProbePacket = *page_num;
11396
11397 RTW_INFO("loc_probe_req: %d\n",
11398 rsvd_page_loc->LocProbePacket);
11399
11400 rtw_hal_construct_ProbeReq(
11401 adapter,
11402 &pframe[index],
11403 &ProbeReqLength,
11404 NULL);
11405
11406 rtw_hal_fill_fake_txdesc(adapter,
11407 &pframe[index - tx_desc],
11408 ProbeReqLength, _FALSE, _FALSE, _FALSE);
11409
11410 CurtPktPageNum =
11411 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
11412
11413 *page_num += CurtPktPageNum;
11414
11415 index += (CurtPktPageNum * page_size);
11416 RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
11417
11418 /* Scan Info Page */
11419 rsvd_page_loc->LocScanInfo = *page_num;
11420 RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
11421 rtw_hal_construct_scan_info(adapter,
11422 &pframe[index - tx_desc],
11423 &ScanInfoLength);
11424
11425 CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
11426 *page_num += CurtPktPageNum;
11427
11428 index += (CurtPktPageNum * page_size);
11429 RSVD_PAGE_CFG("WOW-ScanInfo", CurtPktPageNum, *page_num, *total_pkt_len);
11430 #endif
11431 /* Hidden SSID Probe Request */
11432 ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
11433
11434 for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
11435 pwrctl->pnlo_info->loc_probe_req[pno_index] =
11436 *page_num;
11437
11438 rtw_hal_construct_ProbeReq(
11439 adapter,
11440 &pframe[index],
11441 &ProbeReqLength,
11442 &pwrctl->pno_ssid_list->node[pno_index]);
11443
11444 rtw_hal_fill_fake_txdesc(adapter,
11445 &pframe[index - tx_desc],
11446 ProbeReqLength, _FALSE, _FALSE, _FALSE);
11447
11448 CurtPktPageNum =
11449 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
11450
11451 *page_num += CurtPktPageNum;
11452
11453 index += (CurtPktPageNum * page_size);
11454 RSVD_PAGE_CFG("WOW-ProbeReq", CurtPktPageNum, *page_num, 0);
11455 }
11456
11457 /* PNO INFO Page */
11458 rsvd_page_loc->LocPNOInfo = *page_num;
11459 RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
11460 rtw_hal_construct_PNO_info(adapter,
11461 &pframe[index - tx_desc],
11462 &PNOLength);
11463
11464 CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
11465 *page_num += CurtPktPageNum;
11466 *total_pkt_len = index + PNOLength;
11467 index += (CurtPktPageNum * page_size);
11468 RSVD_PAGE_CFG("WOW-PNOInfo", CurtPktPageNum, *page_num, 0);
11469 }
11470 #endif /* CONFIG_PNO_SUPPORT */
11471 }
11472 }
11473 #endif /*CONFIG_WOWLAN*/
11474
11475 #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)11476 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
11477 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
11478 RSVDPAGE_LOC *rsvd_page_loc)
11479 {
11480 u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
11481 u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
11482 u8 CurtPktPageNum = 0;
11483
11484 /* P2P Beacon */
11485 rsvd_page_loc->LocP2PBeacon = *page_num;
11486 rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
11487 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11488 P2PBCNLength, _FALSE, _FALSE, _FALSE);
11489
11490 #if 0
11491 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
11492 __FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
11493 #endif
11494
11495 CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
11496
11497 *page_num += CurtPktPageNum;
11498
11499 index += (CurtPktPageNum * page_size);
11500 RSVD_PAGE_CFG("WOW-P2P-Beacon", CurtPktPageNum, *page_num, 0);
11501
11502 /* P2P Probe rsp */
11503 rsvd_page_loc->LocP2PProbeRsp = *page_num;
11504 rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
11505 &P2PProbeRspLength);
11506 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11507 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
11508
11509 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", */
11510 /* __FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
11511
11512 CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
11513
11514 *page_num += CurtPktPageNum;
11515
11516 index += (CurtPktPageNum * page_size);
11517 RSVD_PAGE_CFG("WOW-P2P-ProbeRsp", CurtPktPageNum, *page_num, 0);
11518
11519 /* P2P nego rsp */
11520 rsvd_page_loc->LocNegoRsp = *page_num;
11521 rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
11522 &P2PNegoRspLength);
11523 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11524 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
11525
11526 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
11527 /* __FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
11528
11529 CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
11530
11531 *page_num += CurtPktPageNum;
11532
11533 index += (CurtPktPageNum * page_size);
11534 RSVD_PAGE_CFG("WOW-P2P-NegoRsp", CurtPktPageNum, *page_num, 0);
11535
11536 /* P2P invite rsp */
11537 rsvd_page_loc->LocInviteRsp = *page_num;
11538 rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
11539 &P2PInviteRspLength);
11540 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11541 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
11542
11543 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
11544 /* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
11545
11546 CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
11547
11548 *page_num += CurtPktPageNum;
11549
11550 index += (CurtPktPageNum * page_size);
11551 RSVD_PAGE_CFG("WOW-P2P-InviteRsp", CurtPktPageNum, *page_num, 0);
11552
11553 /* P2P provision discovery rsp */
11554 rsvd_page_loc->LocPDRsp = *page_num;
11555 rtw_hal_construct_P2PProvisionDisRsp(adapter,
11556 &pframe[index], &P2PPDRspLength);
11557
11558 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
11559 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
11560
11561 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
11562 /* __FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
11563
11564 CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
11565
11566 *page_num += CurtPktPageNum;
11567
11568 *total_pkt_len = index + P2PPDRspLength;
11569 RSVD_PAGE_CFG("WOW-P2P-PDR", CurtPktPageNum, *page_num, *total_pkt_len);
11570
11571 index += (CurtPktPageNum * page_size);
11572
11573
11574 }
11575 #endif /* CONFIG_P2P_WOWLAN */
11576
11577 #ifdef CONFIG_LPS_PG
11578 #ifndef DBG_LPSPG_INFO_DUMP
11579 #define DBG_LPSPG_INFO_DUMP 1
11580 #endif
11581
11582 #include "hal_halmac.h"
11583
11584 #ifdef CONFIG_RTL8822C
rtw_lps_pg_set_dpk_info_rsvd_page(_adapter * adapter)11585 static int rtw_lps_pg_set_dpk_info_rsvd_page(_adapter *adapter)
11586 {
11587 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11588 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11589 struct dm_struct *dm = adapter_to_phydm(adapter);
11590 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_dpk_info;
11591 u8 *info = NULL;
11592 u32 info_len;
11593 int ret = _FAIL;
11594
11595 /* get length */
11596 halrf_dpk_info_rsvd_page(dm, NULL, &info_len);
11597 if (!info_len) {
11598 RTW_ERR("get %s length fail\n", cache->name);
11599 goto exit;
11600 }
11601
11602 /* allocate buf */
11603 info = rtw_zmalloc(info_len);
11604 if (!info) {
11605 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11606 goto exit;
11607 }
11608
11609 /* get content */
11610 halrf_dpk_info_rsvd_page(dm, info, NULL);
11611
11612 if (rsvd_page_cache_update_data(cache, info, info_len)) {
11613
11614 #if (DBG_LPSPG_INFO_DUMP >= 1)
11615 RTW_INFO_DUMP(cache->name, info, info_len);
11616 #endif
11617
11618 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11619 ret = !ret ? _SUCCESS : _FAIL;
11620 if (ret != _SUCCESS) {
11621 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11622 goto free_mem;
11623 }
11624
11625 #if (DBG_LPSPG_INFO_DUMP >= 2)
11626 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11627 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11628 #endif
11629 }
11630
11631 free_mem:
11632 rtw_mfree(info, info_len);
11633
11634 exit:
11635 return ret;
11636 }
11637
rtw_lps_pg_set_iqk_info_rsvd_page(_adapter * adapter)11638 static int rtw_lps_pg_set_iqk_info_rsvd_page(_adapter *adapter)
11639 {
11640 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11641 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11642 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11643 struct dm_struct *dm = adapter_to_phydm(adapter);
11644 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_iqk_info;
11645 u8 *info = NULL;
11646 u32 info_len = 0;
11647 int ret = _FAIL;
11648
11649 if (hal_data->RegIQKFWOffload) {
11650 rsvd_page_cache_free_data(cache);
11651 ret = _SUCCESS;
11652 goto exit;
11653 }
11654
11655 /* get length */
11656 halrf_iqk_info_rsvd_page(dm, NULL, &info_len);
11657 if (!info_len) {
11658 RTW_ERR("get %s length fail\n", cache->name);
11659 goto exit;
11660 }
11661
11662 /* allocate buf */
11663 info = rtw_zmalloc(info_len);
11664 if (!info) {
11665 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11666 goto exit;
11667 }
11668
11669 /* get content */
11670 halrf_iqk_info_rsvd_page(dm, info, NULL);
11671
11672 if (rsvd_page_cache_update_data(cache, info, info_len)) {
11673
11674 #if (DBG_LPSPG_INFO_DUMP >= 1)
11675 RTW_INFO_DUMP(cache->name, info, info_len);
11676 #endif
11677
11678 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11679 ret = !ret ? _SUCCESS : _FAIL;
11680 if (ret != _SUCCESS) {
11681 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11682 goto free_mem;
11683 }
11684
11685 #if (DBG_LPSPG_INFO_DUMP >= 2)
11686 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11687 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11688 #endif
11689 }
11690
11691 free_mem:
11692 rtw_mfree(info, info_len);
11693
11694 exit:
11695 return ret;
11696 }
11697 #endif /* CONFIG_RTL8822C */
11698
rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv * dvobj,_adapter * ld_sta_iface,u8 * buf,u32 * buf_size)11699 static void rtw_hal_build_lps_pg_info_rsvd_page(struct dvobj_priv *dvobj, _adapter *ld_sta_iface, u8 *buf, u32 *buf_size)
11700 {
11701 #define LPS_PG_INFO_RSVD_LEN 16
11702
11703 if (buf) {
11704 _adapter *adapter = dvobj_get_primary_adapter(dvobj);
11705 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11706 struct sta_info *psta;
11707 #ifdef CONFIG_MBSSID_CAM
11708 u8 cam_id = INVALID_CAM_ID;
11709 #endif
11710 u8 *psec_cam_id = buf + 8;
11711 u8 sec_cam_num = 0;
11712 u8 drv_rsvdpage_num = 0;
11713
11714 if (ld_sta_iface) {
11715 psta = rtw_get_stainfo(&ld_sta_iface->stapriv, get_bssid(&ld_sta_iface->mlmepriv));
11716 if (!psta) {
11717 RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
11718 rtw_warn_on(1);
11719 goto size_chk;
11720 }
11721 /*Byte 0 - used macid*/
11722 LPSPG_RSVD_PAGE_SET_MACID(buf, psta->cmn.mac_id);
11723 RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->cmn.mac_id);
11724 }
11725
11726 #ifdef CONFIG_MBSSID_CAM
11727 /*Byte 1 - used BSSID CAM entry*/
11728 cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
11729 if (cam_id != INVALID_CAM_ID)
11730 LPSPG_RSVD_PAGE_SET_MBSSCAMID(buf, cam_id);
11731 RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
11732 #endif
11733
11734 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
11735 /*Btye 2 - Max used Pattern Match CAM entry*/
11736 if (pwrpriv->wowlan_mode == _TRUE
11737 && ld_sta_iface && check_fwstate(&ld_sta_iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11738 LPSPG_RSVD_PAGE_SET_PMC_NUM(buf, pwrpriv->wowlan_pattern_idx);
11739 RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
11740 }
11741 #endif
11742 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
11743 /*Btye 3 - Max MU rate table Group ID*/
11744 LPSPG_RSVD_PAGE_SET_MU_RAID_GID(buf, 0);
11745 RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", 0);
11746 #endif
11747
11748 /*Btye 8 ~15 - used Security CAM entry */
11749 sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
11750
11751 /*Btye 4 - used Security CAM entry number*/
11752 if (sec_cam_num < 8)
11753 LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(buf, sec_cam_num);
11754 RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
11755
11756 /*Btye 5 - Txbuf used page number for fw offload*/
11757 if (pwrpriv->wowlan_mode == _TRUE || pwrpriv->wowlan_ap_mode == _TRUE)
11758 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
11759 else
11760 drv_rsvdpage_num = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
11761 LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(buf, drv_rsvdpage_num);
11762 RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", drv_rsvdpage_num);
11763 }
11764
11765 size_chk:
11766 if (buf_size)
11767 *buf_size = LPS_PG_INFO_RSVD_LEN;
11768 }
11769
rtw_hal_set_lps_pg_info_rsvd_page(_adapter * adapter)11770 static int rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
11771 {
11772 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11773 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11774 struct rsvd_page_cache_t *cache = &pwrpriv->lpspg_info;
11775 u8 *info = NULL;
11776 u32 info_len = 0;
11777 int ret = _FAIL;
11778
11779 /* get length */
11780 rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, NULL, &info_len);
11781 if (!info_len) {
11782 RTW_ERR("get %s length fail\n", cache->name);
11783 goto exit;
11784 }
11785
11786 /* allocate buf */
11787 info = rtw_zmalloc(info_len);
11788 if (!info) {
11789 RTW_ERR("alloc %s buffer fail(len=%d)\n", cache->name, info_len);
11790 goto exit;
11791 }
11792
11793 /* get content */
11794 rtw_hal_build_lps_pg_info_rsvd_page(dvobj, adapter, info, NULL);
11795
11796 if (rsvd_page_cache_update_data(cache, info, info_len)) {
11797
11798 #if (DBG_LPSPG_INFO_DUMP >= 1)
11799 RTW_INFO_DUMP(cache->name, info, info_len);
11800 #endif
11801
11802 ret = rtw_halmac_download_rsvd_page(dvobj, cache->loc, info, info_len);
11803 ret = !ret ? _SUCCESS : _FAIL;
11804 if (ret != _SUCCESS) {
11805 RTW_ERR("download %s rsvd page to offset:%u fail\n", cache->name, cache->loc);
11806 goto free_mem;
11807 }
11808
11809 #if (DBG_LPSPG_INFO_DUMP >= 2)
11810 RTW_INFO("get %s from rsvd page offset:%d\n", cache->name, cache->loc);
11811 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, cache->loc, cache->page_num);
11812 #endif
11813 }
11814
11815 free_mem:
11816 rtw_mfree(info, info_len);
11817
11818 exit:
11819 return ret;
11820 }
11821
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)11822 static void rtw_lps_pg_set_rsvd_page(_adapter *adapter, u8 *frame, u16 *index
11823 , u8 txdesc_size, u32 page_size, u8 *total_page_num
11824 , bool is_wow_mode, _adapter *ld_sta_iface, bool only_get_page_num)
11825 {
11826 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
11827 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
11828 struct rsvd_page_cache_t *cache;
11829 bool rsvd = 1;
11830 u8 *pos;
11831 u32 len;
11832
11833 if (is_wow_mode) {
11834 /* lps_level will not change when enter wow_mode */
11835 if (pwrctl->lps_level != LPS_PG)
11836 rsvd = 0;
11837 } else {
11838 if (!only_get_page_num && !ld_sta_iface)
11839 rsvd = 0;
11840 }
11841
11842 pos = only_get_page_num ? NULL : frame + *index;
11843
11844 #ifdef CONFIG_RTL8822C
11845 if (IS_8822C_SERIES(hal_data->version_id)) {
11846 /* LPSPG_DPK_INFO */
11847 cache = &pwrctl->lpspg_dpk_info;
11848 if (rsvd) {
11849 if (pwrctl->lps_level != LPS_PG)
11850 pos = NULL;
11851 len = 0;
11852 halrf_dpk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
11853 #if (DBG_LPSPG_INFO_DUMP >= 1)
11854 if (pos)
11855 RTW_INFO_DUMP(cache->name, pos, len);
11856 #endif
11857 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11858 *total_page_num += cache->page_num;
11859 *index += page_size * cache->page_num;
11860 pos = only_get_page_num ? NULL : frame + *index;
11861 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11862 } else
11863 rsvd_page_cache_free(cache);
11864
11865 /* LPSPG_IQK_INFO */
11866 cache = &pwrctl->lpspg_iqk_info;
11867 if (rsvd
11868 /* RegIQKFWOffload will not change when enter wow_mode */
11869 && !(is_wow_mode && hal_data->RegIQKFWOffload)
11870 ) {
11871 if (pwrctl->lps_level != LPS_PG || hal_data->RegIQKFWOffload)
11872 pos = NULL;
11873 len = 0;
11874 halrf_iqk_info_rsvd_page(adapter_to_phydm(adapter), pos, &len);
11875 #if (DBG_LPSPG_INFO_DUMP >= 1)
11876 if (pos)
11877 RTW_INFO_DUMP(cache->name, pos, len);
11878 #endif
11879 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11880 *total_page_num += cache->page_num;
11881 *index += page_size * cache->page_num;
11882 pos = only_get_page_num ? NULL : frame + *index;
11883 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11884 } else
11885 rsvd_page_cache_free(cache);
11886 }
11887 #endif
11888
11889 /* LPSPG_INFO */
11890 cache = &pwrctl->lpspg_info;
11891 if (rsvd) {
11892 if (pwrctl->lps_level != LPS_PG)
11893 pos = NULL;
11894 rtw_hal_build_lps_pg_info_rsvd_page(adapter_to_dvobj(adapter), ld_sta_iface, pos, &len);
11895 #if (DBG_LPSPG_INFO_DUMP >= 1)
11896 if (pos)
11897 RTW_INFO_DUMP(cache->name, pos, len);
11898 #endif
11899 rsvd_page_cache_update_all(cache, *total_page_num, txdesc_size, page_size, pos, len);
11900 *total_page_num += cache->page_num;
11901 *index += page_size * cache->page_num;
11902 pos = only_get_page_num ? NULL : frame + *index;
11903 RSVD_PAGE_CFG(cache->name, cache->page_num, *total_page_num, *index);
11904 } else
11905 rsvd_page_cache_free(cache);
11906 }
11907
rtw_hal_set_lps_pg_info_cmd(_adapter * adapter)11908 u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
11909 {
11910 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11911 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
11912
11913 u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
11914 u8 ret = _FAIL;
11915
11916 if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
11917 SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1); /*SecurityCAM_En*/
11918
11919 #ifdef CONFIG_MBSSID_CAM
11920 SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1); /*BSSIDCAM_En*/
11921 #endif
11922
11923 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
11924 if (pwrpriv->wowlan_mode == _TRUE &&
11925 check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
11926
11927 SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/
11928 }
11929 #endif
11930
11931 #ifdef CONFIG_MACID_SEARCH
11932 SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1); /*MACIDSearch_En*/
11933 #endif
11934
11935 #ifdef CONFIG_TX_SC
11936 SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1); /*TXSC_En*/
11937 #endif
11938
11939 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
11940 SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1); /*MURateTable_En*/
11941 #endif
11942
11943 SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_info.loc);
11944
11945 #ifdef CONFIG_RTL8822C
11946 if (pwrpriv->bFwCurrentInPSMode == _FALSE) {
11947 SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, pwrpriv->lpspg_dpk_info.loc);
11948 if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11949 SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, pwrpriv->lpspg_iqk_info.loc);
11950 } else {
11951 SET_H2CCMD_LPSPG_DPK_INFO_LOC(lpspg_info, 0);
11952 if (!GET_HAL_DATA(adapter)->RegIQKFWOffload)
11953 SET_H2CCMD_LPSPG_IQK_INFO_LOC(lpspg_info, 0);
11954 }
11955 #endif
11956
11957 #if (DBG_LPSPG_INFO_DUMP >= 1)
11958 RTW_INFO_DUMP("H2C_LPS_PG_INFO: ", lpspg_info, H2C_LPS_PG_INFO_LEN);
11959 #endif
11960
11961 ret = rtw_hal_fill_h2c_cmd(adapter,
11962 H2C_LPS_PG_INFO,
11963 H2C_LPS_PG_INFO_LEN,
11964 lpspg_info);
11965 return ret;
11966 }
rtw_hal_set_lps_pg_info(_adapter * adapter)11967 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
11968 {
11969 u8 ret = _FAIL;
11970 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
11971
11972 if (pwrpriv->lpspg_info.loc == 0) {
11973 RTW_ERR("%s lpspg_info.loc = 0\n", __func__);
11974 rtw_warn_on(1);
11975 return ret;
11976 }
11977 #ifdef CONFIG_RTL8822C
11978 rtw_lps_pg_set_dpk_info_rsvd_page(adapter);
11979 rtw_lps_pg_set_iqk_info_rsvd_page(adapter);
11980 #endif
11981 rtw_hal_set_lps_pg_info_rsvd_page(adapter);
11982
11983 ret = rtw_hal_set_lps_pg_info_cmd(adapter);
11984
11985 return ret;
11986 }
11987
rtw_hal_lps_pg_rssi_lv_decide(_adapter * adapter,struct sta_info * sta)11988 void rtw_hal_lps_pg_rssi_lv_decide(_adapter *adapter, struct sta_info *sta)
11989 {
11990 #if 0
11991 if (sta->cmn.ra_info.rssi_level >= 4)
11992 sta->lps_pg_rssi_lv = 3; /*RSSI High - 1SS_VHT_MCS7*/
11993 else if (sta->cmn.ra_info.rssi_level >= 2)
11994 sta->lps_pg_rssi_lv = 2; /*RSSI Middle - 1SS_VHT_MCS3*/
11995 else
11996 sta->lps_pg_rssi_lv = 1; /*RSSI Lower - Lowest_rate*/
11997 #else
11998 sta->lps_pg_rssi_lv = 0;
11999 #endif
12000 RTW_INFO("%s mac-id:%d, rssi:%d, rssi_level:%d, lps_pg_rssi_lv:%d\n",
12001 __func__, sta->cmn.mac_id, sta->cmn.rssi_stat.rssi, sta->cmn.ra_info.rssi_level, sta->lps_pg_rssi_lv);
12002 }
12003
rtw_hal_lps_pg_handler(_adapter * adapter,enum lps_pg_hdl_id hdl_id)12004 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
12005 {
12006 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
12007 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12008 struct sta_priv *pstapriv = &adapter->stapriv;
12009 struct sta_info *sta;
12010
12011 sta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
12012
12013 switch (hdl_id) {
12014 case LPS_PG_INFO_CFG:
12015 rtw_hal_set_lps_pg_info(adapter);
12016 break;
12017 case LPS_PG_REDLEMEM:
12018 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
12019 break;
12020
12021 /*set xmit_block*/
12022 rtw_set_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
12023 if (_FAIL == rtw_hal_fw_mem_dl(adapter, FW_EMEM))
12024 rtw_warn_on(1);
12025 /*clearn xmit_block*/
12026 rtw_clr_xmit_block(adapter, XMIT_BLOCK_REDLMEM);
12027 break;
12028 case LPS_PG_PHYDM_DIS:/*Disable RA and PT by H2C*/
12029 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
12030 break;
12031
12032 if (sta)
12033 rtw_phydm_lps_pg_hdl(adapter, sta, _TRUE);
12034 break;
12035 case LPS_PG_PHYDM_EN:/*Enable RA and PT by H2C*/
12036 if (IS_8822C_SERIES(GET_HAL_DATA(adapter)->version_id))
12037 break;
12038
12039 if (sta) {
12040 rtw_hal_lps_pg_rssi_lv_decide(adapter, sta);
12041 rtw_phydm_lps_pg_hdl(adapter, sta, _FALSE);
12042 sta->lps_pg_rssi_lv = 0;
12043 }
12044 break;
12045
12046 default:
12047 break;
12048 }
12049 }
12050
12051 #endif /*CONFIG_LPS_PG*/
12052
_rtw_mi_assoc_if_num(_adapter * adapter)12053 static u8 _rtw_mi_assoc_if_num(_adapter *adapter)
12054 {
12055 u8 mi_iface_num = 0;
12056
12057 if (0) {
12058 RTW_INFO("[IFS_ASSOC_STATUS] - STA :%d", DEV_STA_LD_NUM(adapter_to_dvobj(adapter)));
12059 RTW_INFO("[IFS_ASSOC_STATUS] - AP:%d", DEV_AP_NUM(adapter_to_dvobj(adapter)));
12060 RTW_INFO("[IFS_ASSOC_STATUS] - AP starting :%d", DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
12061 RTW_INFO("[IFS_ASSOC_STATUS] - MESH :%d", DEV_MESH_NUM(adapter_to_dvobj(adapter)));
12062 RTW_INFO("[IFS_ASSOC_STATUS] - ADHOC :%d", DEV_ADHOC_NUM(adapter_to_dvobj(adapter)));
12063 /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GC :%d", DEV_P2P_GC_NUM(adapter_to_dvobj(adapter)));*/
12064 /*RTW_INFO("[IFS_ASSOC_STATUS] - P2P-GO :%d", DEV_P2P_GO_NUM(adapter_to_dvobj(adapter)));*/
12065 }
12066
12067 mi_iface_num = (DEV_STA_LD_NUM(adapter_to_dvobj(adapter)) +
12068 DEV_AP_NUM(adapter_to_dvobj(adapter)) +
12069 DEV_AP_STARTING_NUM(adapter_to_dvobj(adapter)));
12070 return mi_iface_num;
12071 }
12072 #ifdef CONFIG_CONCURRENT_MODE
_rtw_search_sta_iface(_adapter * adapter)12073 static _adapter *_rtw_search_sta_iface(_adapter *adapter)
12074 {
12075 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12076 _adapter *iface = NULL;
12077 _adapter *sta_iface = NULL;
12078 int i;
12079
12080 for (i = 0; i < dvobj->iface_nums; i++) {
12081 iface = dvobj->padapters[i];
12082 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
12083 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
12084 sta_iface = iface;
12085 break;
12086 }
12087 }
12088 }
12089 return sta_iface;
12090 }
12091 #if defined(CONFIG_AP_MODE) && defined(CONFIG_BT_COEXIST)
_rtw_search_ap_iface(_adapter * adapter)12092 static _adapter *_rtw_search_ap_iface(_adapter *adapter)
12093 {
12094 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12095 _adapter *iface = NULL;
12096 _adapter *ap_iface = NULL;
12097 int i;
12098
12099 for (i = 0; i < dvobj->iface_nums; i++) {
12100 iface = dvobj->padapters[i];
12101 if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
12102 ap_iface = iface;
12103 break;
12104 }
12105 }
12106 return ap_iface;
12107 }
12108 #endif/*CONFIG_AP_MODE*/
12109 #endif/*CONFIG_CONCURRENT_MODE*/
12110
12111 #ifdef CONFIG_CUSTOMER01_SMART_ANTENNA
rtw_hal_set_pathb_phase(_adapter * adapter,u8 phase_idx)12112 void rtw_hal_set_pathb_phase(_adapter *adapter, u8 phase_idx)
12113 {
12114 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
12115 struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
12116
12117 return phydm_pathb_q_matrix_rotate(pDM_Odm, phase_idx);
12118 }
12119 #endif
12120
12121 /*
12122 * Description: Fill the reserved packets that FW will use to RSVD page.
12123 * Now we just send 4 types packet to rsvd page.
12124 * (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
12125 * Input:
12126 * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
12127 * so we need to set the packet length to total lengh.
12128 * TRUE: At the second time, we should send the first packet (default:beacon)
12129 * to Hw again and set the lengh in descriptor to the real beacon lengh.
12130 * page_num - The amount of reserved page which driver need.
12131 * If this is not NULL, this function doesn't real download reserved
12132 * page, but just count the number of reserved page.
12133 *
12134 * 2009.10.15 by tynli.
12135 * 2017.06.20 modified by Lucas.
12136 *
12137 * Page Size = 128: 8188e, 8723a/b, 8192c/d,
12138 * Page Size = 256: 8192e, 8821a
12139 * Page Size = 512: 8812a
12140 */
12141
12142 /*#define DBG_DUMP_SET_RSVD_PAGE*/
_rtw_hal_set_fw_rsvd_page(_adapter * adapter,bool finished,u8 * page_num)12143 static void _rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished, u8 *page_num)
12144 {
12145 PHAL_DATA_TYPE pHalData;
12146 struct xmit_frame *pcmdframe = NULL;
12147 struct pkt_attrib *pattrib;
12148 struct xmit_priv *pxmitpriv;
12149 struct pwrctrl_priv *pwrctl;
12150 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12151 u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
12152 u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
12153 u32 ProbeReqLength = 0, NullFunctionDataLength = 0;
12154 u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
12155 u8 TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
12156 u8 *ReservedPagePacket;
12157 u16 BufIndex = 0;
12158 u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
12159 RSVDPAGE_LOC RsvdPageLoc;
12160 struct registry_priv *registry_par = &adapter->registrypriv;
12161
12162 #ifdef DBG_FW_DEBUG_MSG_PKT
12163 u32 fw_dbg_msg_pkt_len = 0;
12164 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12165
12166 #ifdef DBG_CONFIG_ERROR_DETECT
12167 struct sreset_priv *psrtpriv;
12168 #endif /* DBG_CONFIG_ERROR_DETECT */
12169
12170 #ifdef CONFIG_MCC_MODE
12171 u8 dl_mcc_page = _FAIL;
12172 #endif /* CONFIG_MCC_MODE */
12173 u8 nr_assoc_if;
12174
12175 _adapter *sta_iface = NULL;
12176 _adapter *ap_iface = NULL;
12177
12178 bool is_wow_mode = _FALSE;
12179
12180 pHalData = GET_HAL_DATA(adapter);
12181 #ifdef DBG_CONFIG_ERROR_DETECT
12182 psrtpriv = &pHalData->srestpriv;
12183 #endif
12184 pxmitpriv = &adapter->xmitpriv;
12185 pwrctl = adapter_to_pwrctl(adapter);
12186
12187 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
12188
12189 if (PageSize == 0) {
12190 RTW_ERR("[Error]: %s, PageSize is zero!!\n", __func__);
12191 return;
12192 }
12193 nr_assoc_if = _rtw_mi_assoc_if_num(adapter);
12194
12195 if ((pwrctl->wowlan_mode == _TRUE && pwrctl->wowlan_in_resume == _FALSE) ||
12196 pwrctl->wowlan_ap_mode == _TRUE ||
12197 pwrctl->wowlan_p2p_mode == _TRUE)
12198 is_wow_mode = _TRUE;
12199
12200 /*page_num for init time to get rsvd page number*/
12201 /* Prepare ReservedPagePacket */
12202 if (page_num) {
12203 ReservedPagePacket = rtw_zmalloc(MAX_CMDBUF_SZ);
12204 if (!ReservedPagePacket) {
12205 RTW_WARN("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
12206 *page_num = 0xFF;
12207 return;
12208 }
12209 RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm ==>\n",
12210 FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
12211
12212 } else {
12213 if (is_wow_mode)
12214 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
12215 else
12216 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
12217
12218 RTW_INFO(FUNC_ADPT_FMT" PageSize: %d, [ %s ]-RsvdPageNUm: %d\n",
12219 FUNC_ADPT_ARG(adapter), PageSize, (is_wow_mode) ? "WOW" : "NOR", RsvdPageNum);
12220
12221 MaxRsvdPageBufSize = RsvdPageNum * PageSize;
12222 if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
12223 RTW_ERR("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
12224 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
12225 rtw_warn_on(1);
12226 return;
12227 }
12228
12229 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
12230 if (pcmdframe == NULL) {
12231 RTW_ERR("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
12232 return;
12233 }
12234
12235 ReservedPagePacket = pcmdframe->buf_addr;
12236 }
12237
12238 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
12239
12240 BufIndex = TxDescOffset;
12241
12242 /*======== beacon content =======*/
12243 rtw_hal_construct_beacon(adapter,
12244 &ReservedPagePacket[BufIndex], &BeaconLength);
12245
12246 /*
12247 * When we count the first page size, we need to reserve description size for the RSVD
12248 * packet, it will be filled in front of the packet in TXPKTBUF.
12249 */
12250 BeaconLength = MAX_BEACON_LEN - TxDescLen;
12251 CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
12252
12253 #if defined(CONFIG_FW_HANDLE_TXBCN) || defined(CONFIG_PORT_BASED_TXBCN)
12254 CurtPktPageNum = CurtPktPageNum * CONFIG_LIMITED_AP_NUM;
12255 #endif
12256 TotalPageNum += CurtPktPageNum;
12257
12258 BufIndex += (CurtPktPageNum * PageSize);
12259
12260 RSVD_PAGE_CFG("Beacon", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12261
12262 /*======== probe response content ========*/
12263 if (pwrctl->wowlan_ap_mode == _TRUE) {/*WOW mode*/
12264 #ifdef CONFIG_CONCURRENT_MODE
12265 if (nr_assoc_if >= 2)
12266 RTW_ERR("Not support > 2 net-interface in WOW\n");
12267 #endif
12268 /* (4) probe response*/
12269 RsvdPageLoc.LocProbeRsp = TotalPageNum;
12270 rtw_hal_construct_ProbeRsp(
12271 adapter, &ReservedPagePacket[BufIndex],
12272 &ProbeRspLength,
12273 _FALSE);
12274 rtw_hal_fill_fake_txdesc(adapter,
12275 &ReservedPagePacket[BufIndex - TxDescLen],
12276 ProbeRspLength, _FALSE, _FALSE, _FALSE);
12277
12278 CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
12279 TotalPageNum += CurtPktPageNum;
12280 TotalPacketLen = BufIndex + ProbeRspLength;
12281 BufIndex += (CurtPktPageNum * PageSize);
12282 RSVD_PAGE_CFG("ProbeRsp", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12283 goto download_page;
12284 }
12285
12286 /*======== ps-poll content * 1 page ========*/
12287 sta_iface = adapter;
12288 #ifdef CONFIG_CONCURRENT_MODE
12289 if (!MLME_IS_STA(sta_iface) && DEV_STA_LD_NUM(adapter_to_dvobj(sta_iface))) {
12290 sta_iface = _rtw_search_sta_iface(adapter);
12291 RTW_INFO("get ("ADPT_FMT") to create PS-Poll/Null/QosNull\n", ADPT_ARG(sta_iface));
12292 }
12293 #endif
12294
12295 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12296 RsvdPageLoc.LocPsPoll = TotalPageNum;
12297 RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
12298 rtw_hal_construct_PSPoll(sta_iface,
12299 &ReservedPagePacket[BufIndex], &PSPollLength);
12300 rtw_hal_fill_fake_txdesc(sta_iface,
12301 &ReservedPagePacket[BufIndex - TxDescLen],
12302 PSPollLength, _TRUE, _FALSE, _FALSE);
12303
12304 CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
12305
12306 TotalPageNum += CurtPktPageNum;
12307
12308 BufIndex += (CurtPktPageNum * PageSize);
12309 RSVD_PAGE_CFG("PSPoll", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12310 }
12311
12312 #ifdef CONFIG_MCC_MODE
12313 /*======== MCC * n page ======== */
12314 if (MCC_EN(adapter)) {/*Normal mode*/
12315 dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
12316 &BufIndex, TxDescLen, PageSize, &TotalPageNum, &RsvdPageLoc, page_num);
12317 } else {
12318 dl_mcc_page = _FAIL;
12319 }
12320
12321 if (dl_mcc_page == _FAIL)
12322 #endif /* CONFIG_MCC_MODE */
12323 { /*======== null data * 1 page ======== */
12324 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12325 RsvdPageLoc.LocNullData = TotalPageNum;
12326 RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
12327 rtw_hal_construct_NullFunctionData(
12328 sta_iface,
12329 &ReservedPagePacket[BufIndex],
12330 &NullDataLength,
12331 _FALSE, 0, 0, _FALSE);
12332 rtw_hal_fill_fake_txdesc(sta_iface,
12333 &ReservedPagePacket[BufIndex - TxDescLen],
12334 NullDataLength, _FALSE, _FALSE, _FALSE);
12335
12336 CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
12337
12338 TotalPageNum += CurtPktPageNum;
12339
12340 BufIndex += (CurtPktPageNum * PageSize);
12341 RSVD_PAGE_CFG("NullData", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12342 }
12343 }
12344
12345 /*======== Qos null data * 1 page ======== */
12346 if (pwrctl->wowlan_mode == _FALSE ||
12347 pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
12348 if (MLME_IS_STA(sta_iface) || (nr_assoc_if == 0)) {
12349 RsvdPageLoc.LocQosNull = TotalPageNum;
12350 RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
12351 rtw_hal_construct_NullFunctionData(sta_iface,
12352 &ReservedPagePacket[BufIndex],
12353 &QosNullLength,
12354 _TRUE, 0, 0, _FALSE);
12355 rtw_hal_fill_fake_txdesc(sta_iface,
12356 &ReservedPagePacket[BufIndex - TxDescLen],
12357 QosNullLength, _FALSE, _FALSE, _FALSE);
12358
12359 CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength,
12360 PageSize);
12361
12362 TotalPageNum += CurtPktPageNum;
12363
12364 BufIndex += (CurtPktPageNum * PageSize);
12365 RSVD_PAGE_CFG("QosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12366 }
12367 }
12368
12369 #ifdef CONFIG_BT_COEXIST
12370 /*======== BT Qos null data * 1 page ======== */
12371 if (pwrctl->wowlan_mode == _FALSE ||
12372 pwrctl->wowlan_in_resume == _TRUE) {/*Normal mode*/
12373
12374 ap_iface = adapter;
12375 #if defined (CONFIG_CONCURRENT_MODE) && defined(CONFIG_AP_MODE)
12376 if (!MLME_IS_AP(ap_iface) && DEV_AP_NUM(adapter_to_dvobj(ap_iface))) { /*DEV_AP_STARTING_NUM*/
12377 ap_iface = _rtw_search_ap_iface(adapter);
12378 RTW_INFO("get ("ADPT_FMT") to create BTQoSNull\n", ADPT_ARG(ap_iface));
12379 }
12380 #endif
12381
12382 if (MLME_IS_AP(ap_iface) || (nr_assoc_if == 0)) {
12383 RsvdPageLoc.LocBTQosNull = TotalPageNum;
12384
12385 RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
12386
12387 rtw_hal_construct_NullFunctionData(ap_iface,
12388 &ReservedPagePacket[BufIndex],
12389 &BTQosNullLength,
12390 _TRUE, 0, 0, _FALSE);
12391
12392 rtw_hal_fill_fake_txdesc(ap_iface,
12393 &ReservedPagePacket[BufIndex - TxDescLen],
12394 BTQosNullLength, _FALSE, _TRUE, _FALSE);
12395
12396 CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength,
12397 PageSize);
12398
12399 TotalPageNum += CurtPktPageNum;
12400 BufIndex += (CurtPktPageNum * PageSize);
12401
12402 RSVD_PAGE_CFG("BTQosNull", CurtPktPageNum, TotalPageNum, TotalPacketLen);
12403 }
12404 }
12405 #endif /* CONFIG_BT_COEXIT */
12406
12407 TotalPacketLen = BufIndex;
12408
12409 #ifdef DBG_FW_DEBUG_MSG_PKT
12410 /*======== FW DEBUG MSG * n page ======== */
12411 RsvdPageLoc.loc_fw_dbg_msg_pkt = TotalPageNum;
12412 RTW_INFO("loc_fw_dbg_msg_pkt: %d\n", RsvdPageLoc.loc_fw_dbg_msg_pkt);
12413 rtw_hal_construct_fw_dbg_msg_pkt(
12414 adapter,
12415 &ReservedPagePacket[BufIndex],
12416 &fw_dbg_msg_pkt_len);
12417
12418 rtw_hal_fill_fake_txdesc(adapter,
12419 &ReservedPagePacket[BufIndex - TxDescLen],
12420 fw_dbg_msg_pkt_len, _FALSE, _FALSE, _FALSE);
12421
12422 CurtPktPageNum = (u8)PageNum(TxDescLen + fw_dbg_msg_pkt_len, PageSize);
12423
12424 if (CurtPktPageNum < 2)
12425 CurtPktPageNum = 2; /*Need at least 2 rsvd page*/
12426 TotalPageNum += CurtPktPageNum;
12427
12428 TotalPacketLen = BufIndex + fw_dbg_msg_pkt_len;
12429 BufIndex += (CurtPktPageNum * PageSize);
12430 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12431
12432 #ifdef CONFIG_LPS_PG
12433 rtw_lps_pg_set_rsvd_page(adapter, ReservedPagePacket, &BufIndex
12434 , TxDescLen, PageSize, &TotalPageNum, is_wow_mode
12435 , (sta_iface && MLME_IS_STA(sta_iface) && MLME_IS_ASOC(sta_iface)) ? sta_iface : NULL
12436 , page_num ? 1 : 0
12437 );
12438 TotalPacketLen = BufIndex;
12439 #endif
12440
12441 #ifdef CONFIG_WOWLAN
12442 /*======== WOW * n page ======== */
12443 if (pwrctl->wowlan_mode == _TRUE &&
12444 pwrctl->wowlan_in_resume == _FALSE) {
12445 rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
12446 BufIndex, TxDescLen, PageSize,
12447 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
12448 #ifdef CONFIG_WAR_OFFLOAD
12449 rtw_hal_set_war_offload_parm(adapter, &RsvdPageLoc);
12450 #endif /* CONFIG_WAR_OFFLOAD */
12451 }
12452 #endif /* CONFIG_WOWLAN */
12453
12454 #ifdef CONFIG_P2P_WOWLAN
12455 /*======== P2P WOW * n page ======== */
12456 if (_TRUE == pwrctl->wowlan_p2p_mode) {/*WOW mode*/
12457 rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
12458 BufIndex, TxDescLen, PageSize,
12459 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
12460 }
12461 #endif /* CONFIG_P2P_WOWLAN */
12462
12463 /*Note: BufIndex already add a TxDescOffset offset in first Beacon page
12464 * The "TotalPacketLen" is calculate by BufIndex.
12465 * We need to decrease TxDescOffset before doing length check. by yiwei
12466 */
12467 TotalPacketLen = TotalPacketLen - TxDescOffset;
12468
12469 download_page:
12470 if (page_num) {
12471 *page_num = TotalPageNum;
12472 rtw_mfree(ReservedPagePacket, MAX_CMDBUF_SZ);
12473 ReservedPagePacket = NULL;
12474 RTW_INFO(FUNC_ADPT_FMT" Get [ %s ] RsvdPageNUm <==\n",
12475 FUNC_ADPT_ARG(adapter), (is_wow_mode) ? "WOW" : "NOR");
12476 return;
12477 }
12478
12479 /* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
12480 RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
12481 __func__, TotalPageNum, TotalPacketLen);
12482
12483 if (TotalPacketLen > MaxRsvdPageBufSize) {
12484 RTW_ERR("%s : rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
12485 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
12486 rtw_warn_on(1);
12487 goto error;
12488 } else {
12489 /* update attribute */
12490 pattrib = &pcmdframe->attrib;
12491 update_mgntframe_attrib(adapter, pattrib);
12492 pattrib->qsel = QSLT_BEACON;
12493 pattrib->pktlen = TotalPacketLen;
12494 pattrib->last_txcmdsz = TotalPacketLen;
12495 #ifdef CONFIG_PCI_HCI
12496 dump_mgntframe(adapter, pcmdframe);
12497 #else
12498 dump_mgntframe_and_wait(adapter, pcmdframe, 100);
12499 #endif
12500 }
12501
12502 RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
12503 __func__, TotalPacketLen, TotalPageNum);
12504 #ifdef DBG_DUMP_SET_RSVD_PAGE
12505 RTW_INFO(" ==================================================\n");
12506 RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
12507 RTW_INFO(" ==================================================\n");
12508 #endif
12509
12510
12511 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
12512 || MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)){
12513 rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
12514 #ifdef DBG_FW_DEBUG_MSG_PKT
12515 rtw_hal_set_fw_dbg_msg_pkt_rsvd_page_cmd(adapter, &RsvdPageLoc);
12516 #endif /*DBG_FW_DEBUG_MSG_PKT*/
12517 #ifdef CONFIG_WOWLAN
12518 if (pwrctl->wowlan_mode == _TRUE &&
12519 pwrctl->wowlan_in_resume == _FALSE)
12520 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
12521 #endif /* CONFIG_WOWLAN */
12522 #ifdef CONFIG_AP_WOWLAN
12523 if (pwrctl->wowlan_ap_mode == _TRUE)
12524 rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
12525 #endif /* CONFIG_AP_WOWLAN */
12526 } else if (pwrctl->wowlan_pno_enable) {
12527 #ifdef CONFIG_PNO_SUPPORT
12528 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
12529 if (pwrctl->wowlan_in_resume)
12530 rtw_hal_set_scan_offload_info_cmd(adapter,
12531 &RsvdPageLoc, 0);
12532 else
12533 rtw_hal_set_scan_offload_info_cmd(adapter,
12534 &RsvdPageLoc, 1);
12535 #endif /* CONFIG_PNO_SUPPORT */
12536 }
12537
12538 #ifdef CONFIG_P2P_WOWLAN
12539 if (_TRUE == pwrctl->wowlan_p2p_mode)
12540 rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
12541 #endif /* CONFIG_P2P_WOWLAN */
12542
12543 return;
12544 error:
12545 rtw_free_xmitframe(pxmitpriv, pcmdframe);
12546 }
12547
rtw_hal_set_fw_rsvd_page(struct _ADAPTER * adapter,bool finished)12548 void rtw_hal_set_fw_rsvd_page(struct _ADAPTER *adapter, bool finished)
12549 {
12550 #ifdef CONFIG_AP_MODE
12551 if (finished)
12552 rtw_mi_tx_beacon_hdl(adapter);
12553 else
12554 #endif
12555 _rtw_hal_set_fw_rsvd_page(adapter, finished, NULL);
12556 }
12557
rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER * adapter,u8 enable)12558 static u8 rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(struct _ADAPTER *adapter, u8 enable)
12559 {
12560 u8 u1H2CSetPwrMode[H2C_PWRMODE_LEN] = {0};
12561 u8 ret = _FAIL;
12562
12563 #ifdef CONFIG_TDLS
12564 #ifdef CONFIG_TDLS_CH_SW
12565 if (ATOMIC_READ(&adapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12566 {
12567 SET_H2CCMD_PWRMODE_PARM_RLBM(u1H2CSetPwrMode, 1);
12568 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CSetPwrMode, 0);
12569 }
12570 #endif
12571 #endif
12572
12573 SET_H2CCMD_PWRMODE_PARM_MODE(u1H2CSetPwrMode, 0);
12574 SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CSetPwrMode, 0x0C);
12575 SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_C2H_RPT(u1H2CSetPwrMode, enable);
12576
12577 ret = rtw_hal_fill_h2c_cmd(adapter,
12578 H2C_SET_PWR_MODE,
12579 H2C_PWRMODE_LEN,
12580 u1H2CSetPwrMode);
12581
12582 RTW_PRINT("-%s()-\n", __func__);
12583
12584 return ret;
12585 }
12586
12587 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
rtw_hal_set_ap_bcn_imr_cmd(struct _ADAPTER * adapter,u8 enable)12588 u8 rtw_hal_set_ap_bcn_imr_cmd(struct _ADAPTER *adapter, u8 enable)
12589 {
12590 u8 ap_port_id;
12591 u8 ret = _FAIL;
12592
12593 if (!MLME_IS_AP(adapter))
12594 goto exit;
12595
12596 ap_port_id = get_hw_port(adapter);
12597 if (ap_port_id != HW_PORT0) {
12598 RTW_WARN("AP mode should use port0\n");
12599 goto exit;
12600 }
12601
12602 ret = rtw_hal_fill_h2c_cmd(adapter,
12603 H2C_SET_AP_BCN_IMR,
12604 H2C_AP_BCN_MIR_LEN,
12605 &enable);
12606
12607 RTW_INFO(FUNC_ADPT_FMT" : AP mode %s beacon early IMR\n",
12608 FUNC_ADPT_ARG(adapter), enable ? "enable" : "disable");
12609 exit:
12610 return ret;
12611 }
12612 #endif
12613
12614 /**
12615 * rtw_hal_get_rsvd_page_num() - Get needed reserved page number
12616 * @adapter: struct _ADAPTER*
12617 *
12618 * Caculate needed reserved page number.
12619 * In different state would get different number, for example normal mode and
12620 * WOW mode would need different reserved page size.
12621 *
12622 * Return the number of reserved page which driver need.
12623 */
rtw_hal_get_rsvd_page_num(struct _ADAPTER * adapter)12624 u8 rtw_hal_get_rsvd_page_num(struct _ADAPTER *adapter)
12625 {
12626 u8 num = 0;
12627
12628
12629 _rtw_hal_set_fw_rsvd_page(adapter, _FALSE, &num);
12630
12631 return num;
12632 }
12633
12634 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
hw_var_set_bcn_func(_adapter * adapter,u8 enable)12635 static void hw_var_set_bcn_func(_adapter *adapter, u8 enable)
12636 {
12637 u32 bcn_ctrl_reg;
12638
12639 #ifdef CONFIG_CONCURRENT_MODE
12640 if (adapter->hw_port == HW_PORT1)
12641 bcn_ctrl_reg = REG_BCN_CTRL_1;
12642 else
12643 #endif
12644 bcn_ctrl_reg = REG_BCN_CTRL;
12645
12646 if (enable)
12647 rtw_write8(adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
12648 else {
12649 u8 val8;
12650
12651 val8 = rtw_read8(adapter, bcn_ctrl_reg);
12652 val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
12653
12654 #ifdef CONFIG_BT_COEXIST
12655 if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1) {
12656 /* Always enable port0 beacon function for PSTDMA */
12657 if (REG_BCN_CTRL == bcn_ctrl_reg)
12658 val8 |= EN_BCN_FUNCTION;
12659 }
12660 #endif
12661
12662 rtw_write8(adapter, bcn_ctrl_reg, val8);
12663 }
12664
12665 #ifdef CONFIG_RTL8192F
12666 if (IS_HARDWARE_TYPE_8192F(adapter)) {
12667 u16 val16, val16_ori;
12668
12669 val16_ori = val16 = rtw_read16(adapter, REG_WLAN_ACT_MASK_CTRL_1);
12670
12671 #ifdef CONFIG_CONCURRENT_MODE
12672 if (adapter->hw_port == HW_PORT1) {
12673 if (enable)
12674 val16 |= EN_PORT_1_FUNCTION;
12675 else
12676 val16 &= ~EN_PORT_1_FUNCTION;
12677 } else
12678 #endif
12679 {
12680 if (enable)
12681 val16 |= EN_PORT_0_FUNCTION;
12682 else
12683 val16 &= ~EN_PORT_0_FUNCTION;
12684
12685 #ifdef CONFIG_BT_COEXIST
12686 if (GET_HAL_DATA(adapter)->EEPROMBluetoothCoexist == 1)
12687 val16 |= EN_PORT_0_FUNCTION;
12688 #endif
12689 }
12690
12691 if (val16 != val16_ori)
12692 rtw_write16(adapter, REG_WLAN_ACT_MASK_CTRL_1, val16);
12693 }
12694 #endif
12695 }
12696 #endif
12697
12698 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
hw_var_set_mlme_disconnect(_adapter * adapter)12699 static void hw_var_set_mlme_disconnect(_adapter *adapter)
12700 {
12701 u8 val8;
12702
12703 /* reject all data frames */
12704 #ifdef CONFIG_CONCURRENT_MODE
12705 if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
12706 #endif
12707 rtw_write16(adapter, REG_RXFLTMAP2, 0x0000);
12708
12709 #ifdef CONFIG_CONCURRENT_MODE
12710 if (adapter->hw_port == HW_PORT1) {
12711 /* reset TSF1 */
12712 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1));
12713
12714 /* disable update TSF1 */
12715 rtw_iface_disable_tsf_update(adapter);
12716
12717 if (!IS_HARDWARE_TYPE_8723D(adapter)
12718 && !IS_HARDWARE_TYPE_8192F(adapter)
12719 && !IS_HARDWARE_TYPE_8710B(adapter)
12720 ) {
12721 /* disable Port1's beacon function */
12722 val8 = rtw_read8(adapter, REG_BCN_CTRL_1);
12723 val8 &= ~EN_BCN_FUNCTION;
12724 rtw_write8(adapter, REG_BCN_CTRL_1, val8);
12725 }
12726 } else
12727 #endif
12728 {
12729 /* reset TSF */
12730 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(0));
12731
12732 /* disable update TSF */
12733 rtw_iface_disable_tsf_update(adapter);
12734 }
12735 }
12736 #endif
12737
hw_var_set_mlme_sitesurvey(_adapter * adapter,u8 enable)12738 static void hw_var_set_mlme_sitesurvey(_adapter *adapter, u8 enable)
12739 {
12740 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12741 u16 value_rxfltmap2;
12742
12743 #ifdef DBG_IFACE_STATUS
12744 DBG_IFACE_STATUS_DUMP(adapter);
12745 #endif
12746
12747 #ifdef CONFIG_FIND_BEST_CHANNEL
12748 /* Receive all data frames */
12749 value_rxfltmap2 = 0xFFFF;
12750 #else
12751 /* not to receive data frame */
12752 value_rxfltmap2 = 0;
12753 #endif
12754
12755 if (enable) { /* under sitesurvey */
12756 /*
12757 * 1. configure REG_RXFLTMAP2
12758 * 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
12759 * 3. config RCR to receive different BSSID BCN or probe rsp
12760 */
12761 rtw_write16(adapter, REG_RXFLTMAP2, value_rxfltmap2);
12762
12763 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_ENTER);
12764
12765 /* Save orignal RRSR setting, only 8812 set RRSR after set ch/bw/band */
12766 #if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
12767 hal_data->RegRRSR = rtw_read32(adapter, REG_RRSR);
12768 hal_data->RegRRSR &= 0x000FFFFF;
12769 #endif
12770
12771 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
12772 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
12773 /* set 718[1:0]=2'b00 to avoid BF scan hang */
12774 hal_data->backup_snd_ptcl_ctrl = rtw_read8(adapter, REG_SND_PTCL_CTRL_8812A);
12775 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, (hal_data->backup_snd_ptcl_ctrl & 0xfc));
12776 }
12777 #endif
12778
12779 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12780 StopTxBeacon(adapter);
12781 } else { /* sitesurvey done */
12782 /*
12783 * 1. enable rx data frame
12784 * 2. config RCR not to receive different BSSID BCN or probe rsp
12785 * 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict
12786 * so, we enable TSF update when rx first BCN after sitesurvey done
12787 */
12788 if (rtw_mi_check_fwstate(adapter, WIFI_ASOC_STATE | WIFI_AP_STATE | WIFI_MESH_STATE)) {
12789 /* enable to rx data frame */
12790 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12791 }
12792
12793 rtw_hal_rcr_set_chk_bssid(adapter, MLME_SCAN_DONE);
12794
12795 /* Restore orignal RRSR setting,only 8812 set RRSR after set ch/bw/band */
12796 #if defined (CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
12797 rtw_phydm_set_rrsr(adapter, hal_data->RegRRSR, TRUE);
12798 #endif
12799
12800 #if defined(CONFIG_BEAMFORMING) && (defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A))
12801 if (IS_8812_SERIES(hal_data->version_id) || IS_8821_SERIES(hal_data->version_id)) {
12802 /* Restore orignal 0x718 setting*/
12803 rtw_write8(adapter, REG_SND_PTCL_CTRL_8812A, hal_data->backup_snd_ptcl_ctrl);
12804 }
12805 #endif
12806
12807 #ifdef CONFIG_AP_MODE
12808 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12809 ResumeTxBeacon(adapter);
12810 rtw_mi_tx_beacon_hdl(adapter);
12811 }
12812 #endif
12813 }
12814 }
12815
12816 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
hw_var_set_mlme_join(_adapter * adapter,u8 type)12817 static void hw_var_set_mlme_join(_adapter *adapter, u8 type)
12818 {
12819 u8 val8;
12820 u16 val16;
12821 u32 val32;
12822 u8 RetryLimit = RL_VAL_STA;
12823 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
12824 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
12825
12826 #ifdef CONFIG_CONCURRENT_MODE
12827 if (type == 0) {
12828 /* prepare to join */
12829 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
12830 StopTxBeacon(adapter);
12831
12832 /* enable to rx data frame.Accept all data frame */
12833 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12834
12835 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
12836 RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
12837 else /* Ad-hoc Mode */
12838 RetryLimit = RL_VAL_AP;
12839
12840 rtw_iface_enable_tsf_update(adapter);
12841
12842 } else if (type == 1) {
12843 /* joinbss_event call back when join res < 0 */
12844 if (rtw_mi_check_status(adapter, MI_LINKED) == _FALSE)
12845 rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
12846
12847 rtw_iface_disable_tsf_update(adapter);
12848
12849 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12850 ResumeTxBeacon(adapter);
12851
12852 /* reset TSF 1/2 after ResumeTxBeacon */
12853 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
12854 }
12855
12856 } else if (type == 2) {
12857 /* sta add event call back */
12858 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
12859 /* fixed beacon issue for 8191su........... */
12860 rtw_write8(adapter, 0x542 , 0x02);
12861 RetryLimit = RL_VAL_AP;
12862 }
12863
12864 if (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter)) {
12865 ResumeTxBeacon(adapter);
12866
12867 /* reset TSF 1/2 after ResumeTxBeacon */
12868 rtw_write8(adapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
12869 }
12870 }
12871
12872 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
12873 rtw_write16(adapter, REG_RETRY_LIMIT, val16);
12874 #else /* !CONFIG_CONCURRENT_MODE */
12875 if (type == 0) { /* prepare to join */
12876 /* enable to rx data frame.Accept all data frame */
12877 rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF);
12878
12879 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
12880 RetryLimit = (hal_data->CustomerID == RT_CID_CCX) ? RL_VAL_AP : RL_VAL_STA;
12881 else /* Ad-hoc Mode */
12882 RetryLimit = RL_VAL_AP;
12883
12884 rtw_iface_enable_tsf_update(adapter);
12885
12886 } else if (type == 1) { /* joinbss_event call back when join res < 0 */
12887 rtw_write16(adapter, REG_RXFLTMAP2, 0x00);
12888
12889 rtw_iface_disable_tsf_update(adapter);
12890
12891 } else if (type == 2) { /* sta add event call back */
12892 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
12893 RetryLimit = RL_VAL_AP;
12894 }
12895
12896 val16 = BIT_SRL(RetryLimit) | BIT_LRL(RetryLimit);
12897 rtw_write16(adapter, REG_RETRY_LIMIT, val16);
12898 #endif /* !CONFIG_CONCURRENT_MODE */
12899 }
12900 #endif
12901
12902 #ifdef CONFIG_TSF_RESET_OFFLOAD
rtw_hal_h2c_reset_tsf(_adapter * adapter,u8 reset_port)12903 static int rtw_hal_h2c_reset_tsf(_adapter *adapter, u8 reset_port)
12904 {
12905 u8 buf[2];
12906 int ret;
12907
12908 if (reset_port == HW_PORT0) {
12909 buf[0] = 0x1;
12910 buf[1] = 0;
12911 } else {
12912 buf[0] = 0x0;
12913 buf[1] = 0x1;
12914 }
12915
12916 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_RESET_TSF, 2, buf);
12917
12918 return ret;
12919 }
12920
rtw_hal_reset_tsf(_adapter * adapter,u8 reset_port)12921 int rtw_hal_reset_tsf(_adapter *adapter, u8 reset_port)
12922 {
12923 u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
12924 u32 reg_reset_tsf_cnt = (reset_port == HW_PORT0) ?
12925 REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
12926 int ret;
12927
12928 /* site survey will cause reset tsf fail */
12929 rtw_mi_buddy_scan_abort(adapter, _FALSE);
12930 reset_cnt_after = reset_cnt_before = rtw_read8(adapter, reg_reset_tsf_cnt);
12931 ret = rtw_hal_h2c_reset_tsf(adapter, reset_port);
12932 if (ret != _SUCCESS)
12933 return ret;
12934
12935 while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
12936 rtw_msleep_os(100);
12937 loop_cnt++;
12938 reset_cnt_after = rtw_read8(adapter, reg_reset_tsf_cnt);
12939 }
12940
12941 return (loop_cnt >= 10) ? _FAIL : _SUCCESS;
12942 }
12943 #endif /* CONFIG_TSF_RESET_OFFLOAD */
12944
12945 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
12946 #ifdef CONFIG_HW_P0_TSF_SYNC
12947 #ifdef CONFIG_CONCURRENT_MODE
hw_port0_tsf_sync_sel(_adapter * adapter,u8 benable,u8 hw_port,u16 tr_offset)12948 static void hw_port0_tsf_sync_sel(_adapter *adapter, u8 benable, u8 hw_port, u16 tr_offset)
12949 {
12950 u8 val8;
12951 u8 client_id = 0;
12952 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
12953
12954 #ifdef CONFIG_MCC_MODE
12955 if (MCC_EN(adapter) && (rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))) {
12956 RTW_INFO("[MCC] do not set HW TSF sync\n");
12957 return;
12958 }
12959 #endif
12960 /* check if port0 is already synced */
12961 if (benable && dvobj->p0_tsf.sync_port != MAX_HW_PORT && dvobj->p0_tsf.sync_port == hw_port) {
12962 RTW_WARN(FUNC_ADPT_FMT ": port0 already enable TSF sync(%d)\n",
12963 FUNC_ADPT_ARG(adapter), dvobj->p0_tsf.sync_port);
12964 return;
12965 }
12966
12967 /* check if port0 already disable sync */
12968 if (!benable && dvobj->p0_tsf.sync_port == MAX_HW_PORT) {
12969 RTW_WARN(FUNC_ADPT_FMT ": port0 already disable TSF sync\n", FUNC_ADPT_ARG(adapter));
12970 return;
12971 }
12972
12973 /* check if port0 sync to port0 */
12974 if (benable && hw_port == HW_PORT0) {
12975 RTW_ERR(FUNC_ADPT_FMT ": hw_port is port0 under enable\n", FUNC_ADPT_ARG(adapter));
12976 rtw_warn_on(1);
12977 return;
12978 }
12979
12980 /*0x5B4 [6:4] :SYNC_CLI_SEL - The selector for the CLINT port of sync tsft source for port 0*/
12981 /* Bit[5:4] : 0 for clint0, 1 for clint1, 2 for clint2, 3 for clint3.
12982 Bit6 : 1= enable sync to port 0. 0=disable sync to port 0.*/
12983
12984 val8 = rtw_read8(adapter, REG_TIMER0_SRC_SEL);
12985
12986 if (benable) {
12987 /*Disable Port0's beacon function*/
12988 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) & ~BIT_EN_BCN_FUNCTION);
12989
12990 /*Reg 0x518[15:0]: TSFTR_SYN_OFFSET*/
12991 if (tr_offset)
12992 rtw_write16(adapter, REG_TSFTR_SYN_OFFSET, tr_offset);
12993
12994 /*reg 0x577[6]=1*/ /*auto sync by tbtt*/
12995 rtw_write8(adapter, REG_MISC_CTRL, rtw_read8(adapter, REG_MISC_CTRL) | BIT_AUTO_SYNC_BY_TBTT);
12996
12997 if (HW_PORT1 == hw_port)
12998 client_id = 0;
12999 else if (HW_PORT2 == hw_port)
13000 client_id = 1;
13001 else if (HW_PORT3 == hw_port)
13002 client_id = 2;
13003 else if (HW_PORT4 == hw_port)
13004 client_id = 3;
13005
13006 val8 &= 0x8F;
13007 val8 |= (BIT(6) | (client_id << 4));
13008
13009 dvobj->p0_tsf.sync_port = hw_port;
13010 dvobj->p0_tsf.offset = tr_offset;
13011 rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
13012
13013 /*Enable Port0's beacon function*/
13014 rtw_write8(adapter, REG_BCN_CTRL, rtw_read8(adapter, REG_BCN_CTRL) | BIT_EN_BCN_FUNCTION);
13015 RTW_INFO("%s Port_%d TSF sync to P0, timer offset :%d\n", __func__, hw_port, tr_offset);
13016 } else {
13017 val8 &= ~BIT(6);
13018
13019 dvobj->p0_tsf.sync_port = MAX_HW_PORT;
13020 dvobj->p0_tsf.offset = 0;
13021 rtw_write8(adapter, REG_TIMER0_SRC_SEL, val8);
13022 RTW_INFO("%s P0 TSF sync disable\n", __func__);
13023 }
13024 }
_search_ld_sta(_adapter * adapter,u8 include_self)13025 static _adapter * _search_ld_sta(_adapter *adapter, u8 include_self)
13026 {
13027 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
13028 u8 i;
13029 _adapter *iface = NULL;
13030
13031 if (rtw_mi_get_assoced_sta_num(adapter) == 0) {
13032 RTW_ERR("STA_LD_NUM == 0\n");
13033 rtw_warn_on(1);
13034 }
13035
13036 for (i = 0; i < dvobj->iface_nums; i++) {
13037 iface = dvobj->padapters[i];
13038 if (!iface)
13039 continue;
13040 if (include_self == _FALSE && adapter == iface)
13041 continue;
13042 if (is_client_associated_to_ap(iface))
13043 break;
13044 }
13045 if (iface)
13046 RTW_INFO("search STA iface -"ADPT_FMT"\n", ADPT_ARG(iface));
13047 return iface;
13048 }
13049 #endif /*CONFIG_CONCURRENT_MODE*/
13050 /*Correct port0's TSF*/
13051 /*#define DBG_P0_TSF_SYNC*/
hw_var_set_correct_tsf(PADAPTER adapter,u8 mlme_state)13052 void hw_var_set_correct_tsf(PADAPTER adapter, u8 mlme_state)
13053 {
13054 #ifdef CONFIG_CONCURRENT_MODE
13055 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
13056 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13057 _adapter *sta_if = NULL;
13058 u8 hw_port;
13059
13060 RTW_INFO(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter));
13061 #ifdef DBG_P0_TSF_SYNC
13062 RTW_INFO("[TSF_SYNC] AP_NUM = %d\n", rtw_mi_get_ap_num(adapter));
13063 RTW_INFO("[TSF_SYNC] MESH_NUM = %d\n", rtw_mi_get_mesh_num(adapter));
13064 RTW_INFO("[TSF_SYNC] LD_STA_NUM = %d\n", rtw_mi_get_assoced_sta_num(adapter));
13065 if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
13066 RTW_INFO("[TSF_SYNC] org p0 sync port = N/A\n");
13067 else
13068 RTW_INFO("[TSF_SYNC] org p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
13069 RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
13070 #endif
13071 switch (mlme_state) {
13072 case MLME_STA_CONNECTED :
13073 {
13074 hw_port = rtw_hal_get_port(adapter);
13075
13076 if (!MLME_IS_STA(adapter)) {
13077 RTW_ERR("STA CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
13078 rtw_warn_on(1);
13079 }
13080
13081 if ((dvobj->p0_tsf.sync_port != MAX_HW_PORT) && (hw_port == HW_PORT0)) {
13082 RTW_ERR(ADPT_FMT" is STA with P0 connected => DIS P0_TSF_SYNC\n", ADPT_ARG(adapter));
13083 rtw_warn_on(1);
13084 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
13085 }
13086
13087 if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
13088 (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))) {
13089 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
13090 #ifdef DBG_P0_TSF_SYNC
13091 RTW_INFO("[TSF_SYNC] STA_LINKED => EN P0_TSF_SYNC\n");
13092 #endif
13093 }
13094 }
13095 break;
13096 case MLME_STA_DISCONNECTED :
13097 {
13098 hw_port = rtw_hal_get_port(adapter);
13099
13100 if (!MLME_IS_STA(adapter)) {
13101 RTW_ERR("STA DIS_CON state,but iface("ADPT_FMT") is not STA\n", ADPT_ARG(adapter));
13102 rtw_warn_on(1);
13103 }
13104
13105 if (dvobj->p0_tsf.sync_port == hw_port) {
13106 if (rtw_mi_get_assoced_sta_num(adapter) >= 2) {
13107 /* search next appropriate sta*/
13108 sta_if = _search_ld_sta(adapter, _FALSE);
13109 if (sta_if) {
13110 hw_port = rtw_hal_get_port(sta_if);
13111 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
13112 #ifdef DBG_P0_TSF_SYNC
13113 RTW_INFO("[TSF_SYNC] STA_DIS_CON => CHANGE P0_TSF_SYNC\n");
13114 #endif
13115 }
13116 } else if (rtw_mi_get_assoced_sta_num(adapter) == 1) {
13117 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
13118 #ifdef DBG_P0_TSF_SYNC
13119 RTW_INFO("[TSF_SYNC] STA_DIS_CON => DIS P0_TSF_SYNC\n");
13120 #endif
13121 }
13122 }
13123 }
13124 break;
13125 #ifdef CONFIG_AP_MODE
13126 case MLME_AP_STARTED :
13127 case MLME_MESH_STARTED :
13128 {
13129 if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
13130 RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
13131 rtw_warn_on(1);
13132 }
13133
13134 if ((dvobj->p0_tsf.sync_port == MAX_HW_PORT) &&
13135 rtw_mi_get_assoced_sta_num(adapter)) {
13136 /* get port of sta */
13137 sta_if = _search_ld_sta(adapter, _FALSE);
13138 if (sta_if) {
13139 hw_port = rtw_hal_get_port(sta_if);
13140 hw_port0_tsf_sync_sel(adapter, _TRUE, hw_port, 50);/*timer offset 50ms*/
13141 #ifdef DBG_P0_TSF_SYNC
13142 RTW_INFO("[TSF_SYNC] AP_START => EN P0_TSF_SYNC\n");
13143 #endif
13144 }
13145 }
13146 }
13147 break;
13148 case MLME_AP_STOPPED :
13149 case MLME_MESH_STOPPED :
13150 {
13151 if (!(MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))) {
13152 RTW_ERR("AP START state,but iface("ADPT_FMT") is not AP\n", ADPT_ARG(adapter));
13153 rtw_warn_on(1);
13154 }
13155 /*stop ap mode*/
13156 if ((rtw_mi_get_ap_num(adapter) + rtw_mi_get_mesh_num(adapter) == 1) &&
13157 (dvobj->p0_tsf.sync_port != MAX_HW_PORT)) {
13158 hw_port0_tsf_sync_sel(adapter, _FALSE, 0, 0);
13159 #ifdef DBG_P0_TSF_SYNC
13160 RTW_INFO("[TSF_SYNC] AP_STOP => DIS P0_TSF_SYNC\n");
13161 #endif
13162 }
13163 }
13164 break;
13165 #endif /* CONFIG_AP_MODE */
13166 default :
13167 RTW_ERR(FUNC_ADPT_FMT" unknow state(0x%02x)\n", FUNC_ADPT_ARG(adapter), mlme_state);
13168 break;
13169 }
13170
13171 /*#ifdef DBG_P0_TSF_SYNC*/
13172 #if 1
13173 if (dvobj->p0_tsf.sync_port == MAX_HW_PORT)
13174 RTW_INFO("[TSF_SYNC] p0 sync port = N/A\n");
13175 else
13176 RTW_INFO("[TSF_SYNC] p0 sync port = %d\n", dvobj->p0_tsf.sync_port);
13177 RTW_INFO("[TSF_SYNC] timer offset = %d\n", dvobj->p0_tsf.offset);
13178 #endif
13179 #endif /*CONFIG_CONCURRENT_MODE*/
13180 }
13181
13182 #else /*! CONFIG_HW_P0_TSF_SYNC*/
13183
13184 #ifdef CONFIG_MI_WITH_MBSSID_CAM
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)13185 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
13186 {
13187 /*do nothing*/
13188 }
13189 #else /* !CONFIG_MI_WITH_MBSSID_CAM*/
rtw_hal_correct_tsf(_adapter * padapter,u8 hw_port,u64 tsf)13190 static void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
13191 {
13192 if (hw_port == HW_PORT0) {
13193 /*disable related TSF function*/
13194 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
13195 #if defined(CONFIG_RTL8192F)
13196 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13197 REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_0_FUNCTION);
13198 #endif
13199
13200 rtw_write32(padapter, REG_TSFTR, tsf);
13201 rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
13202
13203 /*enable related TSF function*/
13204 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
13205 #if defined(CONFIG_RTL8192F)
13206 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13207 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
13208 #endif
13209 } else if (hw_port == HW_PORT1) {
13210 /*disable related TSF function*/
13211 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
13212 #if defined(CONFIG_RTL8192F)
13213 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13214 REG_WLAN_ACT_MASK_CTRL_1) & ~EN_PORT_1_FUNCTION);
13215 #endif
13216
13217 rtw_write32(padapter, REG_TSFTR1, tsf);
13218 rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
13219
13220 /*enable related TSF function*/
13221 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
13222 #if defined(CONFIG_RTL8192F)
13223 rtw_write16(padapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(padapter,
13224 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_1_FUNCTION);
13225 #endif
13226 } else
13227 RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
13228 }
hw_var_set_correct_tsf(_adapter * adapter,u8 mlme_state)13229 static void hw_var_set_correct_tsf(_adapter *adapter, u8 mlme_state)
13230 {
13231 u64 tsf;
13232 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
13233 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
13234
13235 tsf = mlmeext->TSFValue - rtw_modular64(mlmeext->TSFValue, (mlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
13236
13237 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
13238 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
13239 StopTxBeacon(adapter);
13240
13241 rtw_hal_correct_tsf(adapter, adapter->hw_port, tsf);
13242
13243 #ifdef CONFIG_CONCURRENT_MODE
13244 /* Update buddy port's TSF if it is SoftAP/Mesh for beacon TX issue! */
13245 if ((mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
13246 && (rtw_mi_get_ap_num(adapter) || rtw_mi_get_mesh_num(adapter))
13247 ) {
13248 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
13249 int i;
13250 _adapter *iface;
13251
13252 for (i = 0; i < dvobj->iface_nums; i++) {
13253 iface = dvobj->padapters[i];
13254 if (!iface)
13255 continue;
13256 if (iface == adapter)
13257 continue;
13258
13259 #ifdef CONFIG_AP_MODE
13260 if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
13261 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
13262 ) {
13263 rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
13264 #ifdef CONFIG_TSF_RESET_OFFLOAD
13265 if (rtw_hal_reset_tsf(iface, iface->hw_port) == _FAIL)
13266 RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n"
13267 , __func__, ADPT_ARG(iface), iface->hw_port);
13268 #endif /* CONFIG_TSF_RESET_OFFLOAD*/
13269 #ifdef CONFIG_TSF_SYNC
13270 if(iface->hw_port == HW_PORT0)
13271 rtw_write8(iface, REG_DUAL_TSF_RST, rtw_read8(iface, REG_DUAL_TSF_RST) | BIT(2));
13272 else if(iface->hw_port == HW_PORT1)
13273 rtw_write8(iface, REG_DUAL_TSF_RST, rtw_read8(iface, REG_DUAL_TSF_RST) | BIT(3));
13274 #endif
13275 }
13276 #endif /* CONFIG_AP_MODE */
13277 }
13278 }
13279 #endif /* CONFIG_CONCURRENT_MODE */
13280 if ((mlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE
13281 || (mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
13282 ResumeTxBeacon(adapter);
13283 }
13284 #endif /*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
13285 #endif /*#ifdef CONFIG_HW_P0_TSF_SYNC*/
13286 #endif /*#ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF*/
13287
rtw_hal_get_tsftr_by_port(_adapter * adapter,u8 port)13288 u64 rtw_hal_get_tsftr_by_port(_adapter *adapter, u8 port)
13289 {
13290 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
13291 u64 tsftr = 0;
13292
13293 if (port >= hal_spec->port_num) {
13294 RTW_ERR("%s invalid port(%d) \n", __func__, port);
13295 goto exit;
13296 }
13297
13298 switch (rtw_get_chip_type(adapter)) {
13299 #if defined(CONFIG_RTL8814B)
13300 case RTL8814B:
13301 {
13302 u8 val8;
13303
13304 /* 0x1500[6:4] - BIT_BCN_TIMER_SEL_FWRD_V1 */
13305 val8 = rtw_read8(adapter, REG_PORT_CTRL_SEL);
13306 val8 &= ~0x70;
13307 val8 |= port << 4;
13308 rtw_write8(adapter, REG_PORT_CTRL_SEL, val8);
13309
13310 tsftr = rtw_read32(adapter, REG_TSFTR_HIGH);
13311 tsftr = tsftr << 32;
13312 tsftr |= rtw_read32(adapter, REG_TSFTR_LOW);
13313
13314 break;
13315 }
13316 #endif
13317 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
13318 case RTL8814A:
13319 case RTL8822B:
13320 case RTL8821C:
13321 case RTL8822C:
13322 {
13323 u8 val8;
13324
13325 /* 0x554[30:28] - BIT_BCN_TIMER_SEL_FWRD */
13326 val8 = rtw_read8(adapter, REG_MBSSID_BCN_SPACE + 3);
13327 val8 &= 0x8F;
13328 val8 |= port << 4;
13329 rtw_write8(adapter, REG_MBSSID_BCN_SPACE + 3, val8);
13330
13331 tsftr = rtw_read32(adapter, REG_TSFTR + 4);
13332 tsftr = tsftr << 32;
13333 tsftr |= rtw_read32(adapter, REG_TSFTR);
13334
13335 break;
13336 }
13337 #endif
13338 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F) || defined(CONFIG_RTL8188GTV) \
13339 || defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8192F) \
13340 || defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || defined(CONFIG_RTL8723D) \
13341 || defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) \
13342 || defined(CONFIG_RTL8710B)
13343 case RTL8188E:
13344 case RTL8188F:
13345 case RTL8188GTV:
13346 case RTL8192E:
13347 case RTL8192F:
13348 case RTL8723B:
13349 case RTL8703B:
13350 case RTL8723D:
13351 case RTL8812:
13352 case RTL8821:
13353 case RTL8710B:
13354 {
13355 u32 addr;
13356
13357 if (port == HW_PORT0)
13358 addr = REG_TSFTR;
13359 else if (port == HW_PORT1)
13360 addr = REG_TSFTR1;
13361 else {
13362 RTW_ERR("%s unknown port(%d) \n", __func__, port);
13363 goto exit;
13364 }
13365
13366 tsftr = rtw_read32(adapter, addr + 4);
13367 tsftr = tsftr << 32;
13368 tsftr |= rtw_read32(adapter, addr);
13369
13370 break;
13371 }
13372 #endif
13373 default:
13374 RTW_ERR("%s unknow chip type\n", __func__);
13375 }
13376
13377 exit:
13378 return tsftr;
13379 }
13380
13381 #ifdef CONFIG_TDLS
13382 #ifdef CONFIG_TDLS_CH_SW
rtw_hal_ch_sw_oper_offload(_adapter * padapter,u8 channel,u8 channel_offset,u16 bwmode)13383 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
13384 {
13385 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
13386 u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
13387
13388
13389 SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
13390 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
13391 switch (bwmode) {
13392 case CHANNEL_WIDTH_40:
13393 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
13394 break;
13395 case CHANNEL_WIDTH_80:
13396 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
13397 break;
13398 case CHANNEL_WIDTH_20:
13399 default:
13400 break;
13401 }
13402 SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
13403
13404 return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
13405 }
13406 #endif
13407 #endif
13408
13409 #ifdef CONFIG_WMMPS_STA
rtw_hal_update_uapsd_tid(_adapter * adapter)13410 void rtw_hal_update_uapsd_tid(_adapter *adapter)
13411 {
13412 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
13413 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
13414
13415 /* write complement of pqospriv->uapsd_tid to mac register 0x693 because
13416 it's designed for "0" represents "enable" and "1" represents "disable" */
13417 rtw_write8(adapter, REG_WMMPS_UAPSD_TID, (u8)(~pqospriv->uapsd_tid));
13418 }
13419 #endif /* CONFIG_WMMPS_STA */
13420
13421 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
13422 /* 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)13423 s32 rtw_hal_set_wifi_btc_port_id_cmd(_adapter *adapter)
13424 {
13425 u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
13426 u8 hw_port = rtw_hal_get_port(adapter);
13427
13428 SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, hw_port);
13429 RTW_INFO("%s ("ADPT_FMT") - hw_port :%d\n", __func__, ADPT_ARG(adapter), hw_port);
13430 return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
13431 }
13432 #endif
13433
13434 #define LPS_ACTIVE_TIMEOUT 50 /*number of times*/
rtw_lps_state_chk(_adapter * adapter,u8 ps_mode)13435 void rtw_lps_state_chk(_adapter *adapter, u8 ps_mode)
13436 {
13437 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
13438 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13439 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13440 struct sta_priv *pstapriv = &adapter->stapriv;
13441 struct sta_info *psta = NULL;
13442 u8 ps_ready = _FALSE;
13443 s8 leave_wait_count = LPS_ACTIVE_TIMEOUT;
13444
13445 if (ps_mode == PS_MODE_ACTIVE) {
13446 #ifdef CONFIG_LPS_ACK
13447 if (rtw_sctx_wait(&pwrpriv->lps_ack_sctx, __func__)) {
13448 if (pwrpriv->lps_ack_status > 0) {
13449 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
13450 if (psta != NULL) {
13451 if(issue_nulldata(adapter, psta->cmn.mac_addr, PS_MODE_ACTIVE, 3, 1) == _FAIL)
13452 RTW_INFO(FUNC_ADPT_FMT" LPS state sync not yet finished.\n", FUNC_ADPT_ARG(adapter));
13453 }
13454 }
13455 } else {
13456 RTW_WARN("LPS sctx query timeout, operation abort!!\n");
13457 return;
13458 }
13459 pwrpriv->lps_ack_status = -1;
13460 #else
13461 do {
13462 if ((rtw_read8(adapter, REG_TCR) & BIT_PWRBIT_OW_EN) == 0) {
13463 ps_ready = _TRUE;
13464 break;
13465 }
13466 rtw_msleep_os(1);
13467 } while (leave_wait_count--);
13468
13469 if (ps_ready == _FALSE) {
13470 RTW_WARN(FUNC_ADPT_FMT" Power Bit Control is still in HW!\n", FUNC_ADPT_ARG(adapter));
13471 return;
13472 }
13473 #endif /* CONFIG_LPS_ACK */
13474 }
13475 }
13476
rtw_var_set_basic_rate(PADAPTER padapter,u8 * val)13477 void rtw_var_set_basic_rate(PADAPTER padapter, u8 *val) {
13478
13479 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
13480 struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
13481 u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
13482 u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
13483 u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
13484 #if CONFIG_IEEE80211_BAND_5GHZ
13485 u16 rrsr_5g_force_mask = (RRSR_6M);
13486 u16 rrsr_5g_allow_mask = (RRSR_OFDM_RATES);
13487 #endif
13488 u32 temp_RRSR;
13489
13490 HalSetBrateCfg(padapter, val, &BrateCfg);
13491 input_b = BrateCfg;
13492
13493 /* apply force and allow mask */
13494 #if CONFIG_IEEE80211_BAND_5GHZ
13495 if (pHalData->current_band_type != BAND_ON_2_4G) {
13496 BrateCfg |= rrsr_5g_force_mask;
13497 BrateCfg &= rrsr_5g_allow_mask;
13498 } else
13499 #endif
13500 { /* 2.4G */
13501 BrateCfg |= rrsr_2g_force_mask;
13502 BrateCfg &= rrsr_2g_allow_mask;
13503 }
13504 masked = BrateCfg;
13505
13506 #ifdef CONFIG_CMCC_TEST
13507 BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
13508 BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /*CMCC_OFDM_ACK 12/18/24M */
13509 #endif
13510
13511 /* IOT consideration */
13512 if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
13513 /* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
13514 if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
13515 BrateCfg |= RRSR_6M;
13516 }
13517 ioted = BrateCfg;
13518
13519 #ifdef CONFIG_NARROWBAND_SUPPORTING
13520 if ((padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
13521 || (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_5)) {
13522 BrateCfg &= ~RRSR_CCK_RATES;
13523 BrateCfg |= RRSR_6M;
13524 }
13525 #endif
13526 pHalData->BasicRateSet = BrateCfg;
13527
13528 RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
13529
13530 /* Set RRSR rate table. */
13531 temp_RRSR = rtw_read32(padapter, REG_RRSR);
13532 temp_RRSR &=0xFFFF0000;
13533 temp_RRSR |=BrateCfg;
13534 rtw_phydm_set_rrsr(padapter, temp_RRSR, TRUE);
13535
13536 rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
13537
13538 #if defined(CONFIG_RTL8188E)
13539 rtw_hal_set_hwreg(padapter, HW_VAR_INIT_RTS_RATE, (u8 *)&BrateCfg);
13540 #endif
13541 }
13542
SetHwReg(_adapter * adapter,u8 variable,u8 * val)13543 u8 SetHwReg(_adapter *adapter, u8 variable, u8 *val)
13544 {
13545 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13546 u8 ret = _SUCCESS;
13547
13548 switch (variable) {
13549 case HW_VAR_MEDIA_STATUS: {
13550 u8 net_type = *((u8 *)val);
13551
13552 rtw_hal_set_msr(adapter, net_type);
13553 }
13554 break;
13555 case HW_VAR_DO_IQK:
13556 if (*val)
13557 hal_data->bNeedIQK = _TRUE;
13558 else
13559 hal_data->bNeedIQK = _FALSE;
13560 break;
13561 case HW_VAR_MAC_ADDR:
13562 #ifdef CONFIG_MI_WITH_MBSSID_CAM
13563 rtw_hal_set_macaddr_mbid(adapter, val);
13564 #else
13565 rtw_hal_set_macaddr_port(adapter, val);
13566 #endif
13567 break;
13568 case HW_VAR_BSSID:
13569 rtw_hal_set_bssid(adapter, val);
13570 break;
13571 case HW_VAR_RCR:
13572 ret = hw_var_rcr_config(adapter, *((u32 *)val));
13573 break;
13574 case HW_VAR_ON_RCR_AM:
13575 hw_var_set_rcr_am(adapter, 1);
13576 break;
13577 case HW_VAR_OFF_RCR_AM:
13578 hw_var_set_rcr_am(adapter, 0);
13579 break;
13580 case HW_VAR_BEACON_INTERVAL:
13581 hw_var_set_bcn_interval(adapter, *(u16 *)val);
13582 break;
13583 #ifdef CONFIG_MBSSID_CAM
13584 case HW_VAR_MBSSID_CAM_WRITE: {
13585 u32 cmd = 0;
13586 u32 *cam_val = (u32 *)val;
13587
13588 rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
13589 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
13590 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
13591 }
13592 break;
13593 case HW_VAR_MBSSID_CAM_CLEAR: {
13594 u32 cmd;
13595 u8 entry_id = *(u8 *)val;
13596
13597 rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
13598
13599 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
13600 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
13601 }
13602 break;
13603 case HW_VAR_RCR_MBSSID_EN:
13604 if (*((u8 *)val))
13605 rtw_hal_rcr_add(adapter, RCR_ENMBID);
13606 else
13607 rtw_hal_rcr_clear(adapter, RCR_ENMBID);
13608 break;
13609 #endif
13610 case HW_VAR_PORT_SWITCH:
13611 hw_var_port_switch(adapter);
13612 break;
13613 case HW_VAR_INIT_RTS_RATE: {
13614 u16 brate_cfg = *((u16 *)val);
13615 u8 rate_index = 0;
13616 HAL_VERSION *hal_ver = &hal_data->version_id;
13617
13618 if (IS_8188E(*hal_ver)) {
13619
13620 while (brate_cfg > 0x1) {
13621 brate_cfg = (brate_cfg >> 1);
13622 rate_index++;
13623 }
13624 rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
13625 } else
13626 rtw_warn_on(1);
13627 }
13628 break;
13629 case HW_VAR_SEC_CFG: {
13630 u16 reg_scr_ori;
13631 u16 reg_scr;
13632
13633 reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
13634 reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
13635
13636 if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
13637 reg_scr |= SCR_CHK_BMC;
13638
13639 if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
13640 reg_scr |= SCR_NoSKMC;
13641
13642 if (reg_scr != reg_scr_ori)
13643 rtw_write16(adapter, REG_SECCFG, reg_scr);
13644 }
13645 break;
13646 case HW_VAR_SEC_DK_CFG: {
13647 struct security_priv *sec = &adapter->securitypriv;
13648 u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
13649
13650 if (val) { /* Enable default key related setting */
13651 reg_scr |= SCR_TXBCUSEDK;
13652 if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
13653 reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
13654 } else /* Disable default key related setting */
13655 reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
13656
13657 rtw_write8(adapter, REG_SECCFG, reg_scr);
13658 }
13659 break;
13660
13661 case HW_VAR_ASIX_IOT:
13662 /* enable ASIX IOT function */
13663 if (*((u8 *)val) == _TRUE) {
13664 /* 0xa2e[0]=0 (disable rake receiver) */
13665 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
13666 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
13667 /* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
13668 rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
13669 } else {
13670 /* restore reg:0xa2e, reg:0xa1c */
13671 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
13672 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
13673 rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
13674 }
13675 break;
13676 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
13677 case HW_VAR_WOWLAN: {
13678 struct wowlan_ioctl_param *poidparam;
13679
13680 poidparam = (struct wowlan_ioctl_param *)val;
13681 switch (poidparam->subcode) {
13682 #ifdef CONFIG_WOWLAN
13683 case WOWLAN_PATTERN_CLEAN:
13684 rtw_hal_dl_pattern(adapter, 2);
13685 break;
13686 case WOWLAN_ENABLE:
13687 rtw_hal_wow_enable(adapter);
13688 break;
13689 case WOWLAN_DISABLE:
13690 rtw_hal_wow_disable(adapter);
13691 break;
13692 #endif /*CONFIG_WOWLAN*/
13693 #ifdef CONFIG_AP_WOWLAN
13694 case WOWLAN_AP_ENABLE:
13695 rtw_hal_ap_wow_enable(adapter);
13696 break;
13697 case WOWLAN_AP_DISABLE:
13698 rtw_hal_ap_wow_disable(adapter);
13699 break;
13700 #endif /*CONFIG_AP_WOWLAN*/
13701 default:
13702 break;
13703 }
13704 }
13705 break;
13706 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
13707
13708 #ifndef CONFIG_HAS_HW_VAR_BCN_FUNC
13709 case HW_VAR_BCN_FUNC:
13710 hw_var_set_bcn_func(adapter, *val);
13711 break;
13712 #endif
13713
13714 #ifndef CONFIG_HAS_HW_VAR_MLME_DISCONNECT
13715 case HW_VAR_MLME_DISCONNECT:
13716 hw_var_set_mlme_disconnect(adapter);
13717 break;
13718 #endif
13719
13720 case HW_VAR_MLME_SITESURVEY:
13721 hw_var_set_mlme_sitesurvey(adapter, *val);
13722 #ifdef CONFIG_BT_COEXIST
13723 if (hal_data->EEPROMBluetoothCoexist == 1)
13724 rtw_btcoex_ScanNotify(adapter, *val ? _TRUE : _FALSE);
13725 #endif
13726 break;
13727
13728 #ifndef CONFIG_HAS_HW_VAR_MLME_JOIN
13729 case HW_VAR_MLME_JOIN:
13730 hw_var_set_mlme_join(adapter, *val);
13731 break;
13732 #endif
13733
13734 case HW_VAR_EN_HW_UPDATE_TSF:
13735 rtw_hal_set_hw_update_tsf(adapter);
13736 break;
13737 #ifndef CONFIG_HAS_HW_VAR_CORRECT_TSF
13738 case HW_VAR_CORRECT_TSF:
13739 hw_var_set_correct_tsf(adapter, *val);
13740 break;
13741 #endif
13742
13743 #if defined(CONFIG_HW_P0_TSF_SYNC) && defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_MCC_MODE)
13744 case HW_VAR_TSF_AUTO_SYNC:
13745 if (*val == _TRUE)
13746 hw_port0_tsf_sync_sel(adapter, _TRUE, adapter->hw_port, 50);
13747 else
13748 hw_port0_tsf_sync_sel(adapter, _FALSE, adapter->hw_port, 50);
13749 break;
13750 #endif
13751 case HW_VAR_APFM_ON_MAC:
13752 hal_data->bMacPwrCtrlOn = *val;
13753 RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
13754 break;
13755 #ifdef CONFIG_WMMPS_STA
13756 case HW_VAR_UAPSD_TID:
13757 rtw_hal_update_uapsd_tid(adapter);
13758 break;
13759 #endif /* CONFIG_WMMPS_STA */
13760 #ifdef CONFIG_LPS_PG
13761 case HW_VAR_LPS_PG_HANDLE:
13762 rtw_hal_lps_pg_handler(adapter, *val);
13763 break;
13764 #endif
13765 #ifdef CONFIG_LPS_LCLK_WD_TIMER
13766 case HW_VAR_DM_IN_LPS_LCLK:
13767 rtw_phydm_wd_lps_lclk_hdl(adapter);
13768 break;
13769 #endif
13770 case HW_VAR_ENABLE_RX_BAR:
13771 if (*val == _TRUE) {
13772 /* enable RX BAR */
13773 u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
13774
13775 val16 |= BIT(8);
13776 rtw_write16(adapter, REG_RXFLTMAP1, val16);
13777 } else {
13778 /* disable RX BAR */
13779 u16 val16 = rtw_read16(adapter, REG_RXFLTMAP1);
13780
13781 val16 &= (~BIT(8));
13782 rtw_write16(adapter, REG_RXFLTMAP1, val16);
13783 }
13784 RTW_INFO("[HW_VAR_ENABLE_RX_BAR] 0x%02X=0x%02X\n",
13785 REG_RXFLTMAP1, rtw_read16(adapter, REG_RXFLTMAP1));
13786 break;
13787 case HW_VAR_HCI_SUS_STATE:
13788 hal_data->hci_sus_state = *(u8 *)val;
13789 RTW_INFO("%s: hci_sus_state=%u\n", __func__, hal_data->hci_sus_state);
13790 break;
13791 #if defined(CONFIG_AP_MODE) && defined(CONFIG_FW_HANDLE_TXBCN) && defined(CONFIG_SUPPORT_MULTI_BCN)
13792 case HW_VAR_BCN_HEAD_SEL:
13793 {
13794 u8 vap_id = *(u8 *)val;
13795
13796 if ((vap_id >= CONFIG_LIMITED_AP_NUM) && (vap_id != 0xFF)) {
13797 RTW_ERR(ADPT_FMT " vap_id(%d:%d) is invalid\n", ADPT_ARG(adapter),vap_id, adapter->vap_id);
13798 rtw_warn_on(1);
13799 }
13800 if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
13801 u16 drv_pg_bndy = 0, bcn_addr = 0;
13802 u32 page_size = 0;
13803
13804 /*rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_BOUNDARY, &drv_pg_bndy);*/
13805 rtw_halmac_get_rsvd_drv_pg_bndy(adapter_to_dvobj(adapter), &drv_pg_bndy);
13806 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&page_size);
13807
13808 if (vap_id != 0xFF)
13809 bcn_addr = drv_pg_bndy + (vap_id * (MAX_BEACON_LEN / page_size));
13810 else
13811 bcn_addr = drv_pg_bndy;
13812 RTW_INFO(ADPT_FMT" vap_id(%d) change BCN HEAD to 0x%04x\n",
13813 ADPT_ARG(adapter), vap_id, bcn_addr);
13814 rtw_write16(adapter, REG_FIFOPAGE_CTRL_2,
13815 (bcn_addr & BIT_MASK_BCN_HEAD_1_V1) | BIT_BCN_VALID_V1);
13816 }
13817 }
13818 break;
13819 #endif
13820 case HW_VAR_LPS_STATE_CHK :
13821 rtw_lps_state_chk(adapter, *(u8 *)val);
13822 break;
13823
13824 #ifdef CONFIG_RTS_FULL_BW
13825 case HW_VAR_SET_RTS_BW:
13826 {
13827 #ifdef RTW_HALMAC
13828 rtw_halmac_set_rts_full_bw(adapter_to_dvobj(adapter), (*val));
13829 #else
13830 u8 temp;
13831 if(*val)
13832 temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) | BIT5 );
13833 else
13834 temp = (( rtw_read8(adapter, REG_INIRTS_RATE_SEL)) & (~BIT5));
13835 rtw_write8(adapter, REG_INIRTS_RATE_SEL, temp);
13836 /*RTW_INFO("HW_VAR_SET_RTS_BW val=%u REG480=0x%x\n", *val, rtw_read8(adapter, REG_INIRTS_RATE_SEL));*/
13837 #endif
13838 }
13839 break;
13840 #endif/*CONFIG_RTS_FULL_BW*/
13841 #if defined(CONFIG_PCI_HCI)
13842 case HW_VAR_ENSWBCN:
13843 if (*val == _TRUE) {
13844 rtw_write8(adapter, REG_CR + 1,
13845 rtw_read8(adapter, REG_CR + 1) | BIT(0));
13846 } else
13847 rtw_write8(adapter, REG_CR + 1,
13848 rtw_read8(adapter, REG_CR + 1) & ~BIT(0));
13849 break;
13850 #endif
13851 case HW_VAR_BCN_EARLY_C2H_RPT:
13852 rtw_hal_set_fw_bcn_early_c2h_rpt_cmd(adapter, *(u8 *)val);
13853 break;
13854 default:
13855 if (0)
13856 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
13857 FUNC_ADPT_ARG(adapter), variable);
13858 ret = _FAIL;
13859 break;
13860 }
13861
13862 return ret;
13863 }
13864
GetHwReg(_adapter * adapter,u8 variable,u8 * val)13865 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
13866 {
13867 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13868 u64 val64;
13869
13870
13871 switch (variable) {
13872 case HW_VAR_MAC_ADDR:
13873 #ifndef CONFIG_MI_WITH_MBSSID_CAM
13874 rtw_hal_get_macaddr_port(adapter, val);
13875 #endif
13876 break;
13877 case HW_VAR_BASIC_RATE:
13878 *((u16 *)val) = hal_data->BasicRateSet;
13879 break;
13880 case HW_VAR_MEDIA_STATUS:
13881 rtw_hal_get_msr(adapter, val);
13882 break;
13883 case HW_VAR_DO_IQK:
13884 *val = hal_data->bNeedIQK;
13885 break;
13886 case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
13887 if (hal_is_band_support(adapter, BAND_ON_5G))
13888 *val = _TRUE;
13889 else
13890 *val = _FALSE;
13891 break;
13892 case HW_VAR_APFM_ON_MAC:
13893 *val = hal_data->bMacPwrCtrlOn;
13894 break;
13895 case HW_VAR_RCR:
13896 hw_var_rcr_get(adapter, (u32 *)val);
13897 break;
13898 case HW_VAR_FWLPS_RF_ON:
13899 /* When we halt NIC, we should check if FW LPS is leave. */
13900 if (rtw_is_surprise_removed(adapter)
13901 || (adapter_to_pwrctl(adapter)->rf_pwrstate == rf_off)
13902 ) {
13903 /*
13904 * If it is in HW/SW Radio OFF or IPS state,
13905 * we do not check Fw LPS Leave,
13906 * because Fw is unload.
13907 */
13908 *val = _TRUE;
13909 } else {
13910 u32 rcr = 0;
13911
13912 rtw_hal_get_hwreg(adapter, HW_VAR_RCR, (u8 *)&rcr);
13913 if (rcr & (RCR_UC_MD_EN | RCR_BC_MD_EN | RCR_TIM_PARSER_EN))
13914 *val = _FALSE;
13915 else
13916 *val = _TRUE;
13917 }
13918 break;
13919
13920 case HW_VAR_HCI_SUS_STATE:
13921 *((u8 *)val) = hal_data->hci_sus_state;
13922 break;
13923
13924 #ifndef CONFIG_HAS_HW_VAR_BCN_CTRL_ADDR
13925 case HW_VAR_BCN_CTRL_ADDR:
13926 *((u32 *)val) = hw_bcn_ctrl_addr(adapter, adapter->hw_port);
13927 break;
13928 #endif
13929
13930 #ifdef CONFIG_WAPI_SUPPORT
13931 case HW_VAR_CAM_EMPTY_ENTRY: {
13932 u8 ucIndex = *((u8 *)val);
13933 u8 i;
13934 u32 ulCommand = 0;
13935 u32 ulContent = 0;
13936 u32 ulEncAlgo = CAM_AES;
13937
13938 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
13939 /* filled id in CAM config 2 byte */
13940 if (i == 0)
13941 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
13942 else
13943 ulContent = 0;
13944 /* polling bit, and No Write enable, and address */
13945 ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
13946 ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
13947 /* write content 0 is equall to mark invalid */
13948 rtw_write32(adapter, REG_CAMWRITE, ulContent); /* delay_ms(40); */
13949 rtw_write32(adapter, REG_CAMCMD, ulCommand); /* delay_ms(40); */
13950 }
13951 }
13952 #endif
13953
13954 default:
13955 if (0)
13956 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
13957 FUNC_ADPT_ARG(adapter), variable);
13958 break;
13959 }
13960
13961 }
13962
_get_page_size(struct _ADAPTER * a)13963 static u32 _get_page_size(struct _ADAPTER *a)
13964 {
13965 #ifdef RTW_HALMAC
13966 struct dvobj_priv *d;
13967 u32 size = 0;
13968 int err = 0;
13969
13970
13971 d = adapter_to_dvobj(a);
13972
13973 err = rtw_halmac_get_page_size(d, &size);
13974 if (!err)
13975 return size;
13976
13977 RTW_WARN(FUNC_ADPT_FMT ": Fail to get Page size!!(err=%d)\n",
13978 FUNC_ADPT_ARG(a), err);
13979 #endif /* RTW_HALMAC */
13980
13981 return PAGE_SIZE_128;
13982 }
13983
13984 u8
SetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)13985 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
13986 {
13987 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
13988 u8 bResult = _SUCCESS;
13989
13990 switch (variable) {
13991
13992 case HAL_DEF_DBG_DUMP_RXPKT:
13993 hal_data->bDumpRxPkt = *((u8 *)value);
13994 break;
13995 case HAL_DEF_DBG_DUMP_TXPKT:
13996 hal_data->bDumpTxPkt = *((u8 *)value);
13997 break;
13998 case HAL_DEF_ANT_DETECT:
13999 hal_data->AntDetection = *((u8 *)value);
14000 break;
14001 default:
14002 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
14003 bResult = _FAIL;
14004 break;
14005 }
14006
14007 return bResult;
14008 }
14009
14010 #ifdef CONFIG_BEAMFORMING
rtw_hal_query_txbfer_rf_num(_adapter * adapter)14011 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
14012 {
14013 struct registry_priv *pregistrypriv = &adapter->registrypriv;
14014 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
14015
14016 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)))
14017 return pregistrypriv->beamformer_rf_num;
14018 else if (IS_HARDWARE_TYPE_8814AE(adapter)
14019 #if 0
14020 #if defined(CONFIG_USB_HCI)
14021 || (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) /* for USB3.0 */
14022 #endif
14023 #endif
14024 ) {
14025 /*BF cap provided by Yu Chen, Sean, 2015, 01 */
14026 if (hal_data->rf_type == RF_3T3R)
14027 return 2;
14028 else if (hal_data->rf_type == RF_4T4R)
14029 return 3;
14030 else
14031 return 1;
14032 } else
14033 return 1;
14034
14035 }
rtw_hal_query_txbfee_rf_num(_adapter * adapter)14036 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
14037 {
14038 struct registry_priv *pregistrypriv = &adapter->registrypriv;
14039 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
14040 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14041
14042 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
14043
14044 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)))
14045 return pregistrypriv->beamformee_rf_num;
14046 else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
14047 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
14048 return 2;
14049 else
14050 return 2;/*TODO: May be 3 in the future, by ChenYu. */
14051 } else
14052 return 1;
14053
14054 }
14055 #ifdef RTW_BEAMFORMING_VERSION_2
rtw_hal_beamforming_config_csirate(PADAPTER adapter)14056 void rtw_hal_beamforming_config_csirate(PADAPTER adapter)
14057 {
14058 struct dm_struct *p_dm_odm;
14059 struct beamforming_info *bf_info;
14060 u8 fix_rate_enable = 0;
14061 u8 new_csi_rate_idx;
14062 u8 rrsr_54_en;
14063 u32 temp_rrsr;
14064
14065 /* Acting as BFee */
14066 if (IS_BEAMFORMEE(adapter)) {
14067 #if 0
14068 /* Do not enable now because it will affect MU performance and CTS/BA rate. 2016.07.19. by tynli. [PCIE-1660] */
14069 if (IS_HARDWARE_TYPE_8821C(Adapter))
14070 FixRateEnable = 1; /* Support after 8821C */
14071 #endif
14072
14073 p_dm_odm = adapter_to_phydm(adapter);
14074 bf_info = GET_BEAMFORM_INFO(adapter);
14075
14076 rtw_halmac_bf_cfg_csi_rate(adapter_to_dvobj(adapter),
14077 p_dm_odm->rssi_min,
14078 bf_info->cur_csi_rpt_rate,
14079 fix_rate_enable, &new_csi_rate_idx, &rrsr_54_en);
14080
14081 temp_rrsr = rtw_read32(adapter, REG_RRSR);
14082 if (rrsr_54_en == 1)
14083 temp_rrsr |= RRSR_54M;
14084 else if (rrsr_54_en == 0)
14085 temp_rrsr &= ~RRSR_54M;
14086 rtw_phydm_set_rrsr(adapter, temp_rrsr, FALSE);
14087
14088 if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate)
14089 bf_info->cur_csi_rpt_rate = new_csi_rate_idx;
14090 }
14091 }
14092 #endif
14093 #endif
14094
14095 u8
GetHalDefVar(_adapter * adapter,HAL_DEF_VARIABLE variable,void * value)14096 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
14097 {
14098 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
14099 u8 bResult = _SUCCESS;
14100
14101 switch (variable) {
14102 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
14103 struct mlme_priv *pmlmepriv;
14104 struct sta_priv *pstapriv;
14105 struct sta_info *psta;
14106
14107 pmlmepriv = &adapter->mlmepriv;
14108 pstapriv = &adapter->stapriv;
14109 psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
14110 if (psta)
14111 *((int *)value) = psta->cmn.rssi_stat.rssi;
14112 }
14113 break;
14114 case HAL_DEF_DBG_DUMP_RXPKT:
14115 *((u8 *)value) = hal_data->bDumpRxPkt;
14116 break;
14117 case HAL_DEF_DBG_DUMP_TXPKT:
14118 *((u8 *)value) = hal_data->bDumpTxPkt;
14119 break;
14120 case HAL_DEF_ANT_DETECT:
14121 *((u8 *)value) = hal_data->AntDetection;
14122 break;
14123 case HAL_DEF_TX_PAGE_SIZE:
14124 *((u32 *)value) = _get_page_size(adapter);
14125 break;
14126 case HAL_DEF_TX_STBC:
14127 #ifdef CONFIG_ALPHA_SMART_ANTENNA
14128 *(u8 *)value = 0;
14129 #else
14130 *(u8 *)value = hal_data->max_tx_cnt > 1 ? 1 : 0;
14131 #endif
14132 break;
14133 case HAL_DEF_EXPLICIT_BEAMFORMER:
14134 case HAL_DEF_EXPLICIT_BEAMFORMEE:
14135 case HAL_DEF_VHT_MU_BEAMFORMER:
14136 case HAL_DEF_VHT_MU_BEAMFORMEE:
14137 *(u8 *)value = _FALSE;
14138 break;
14139 #ifdef CONFIG_BEAMFORMING
14140 case HAL_DEF_BEAMFORMER_CAP:
14141 *(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
14142 break;
14143 case HAL_DEF_BEAMFORMEE_CAP:
14144 *(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
14145 break;
14146 #endif
14147 default:
14148 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
14149 bResult = _FAIL;
14150 break;
14151 }
14152
14153 return bResult;
14154 }
14155
14156 /*
14157 * Description:
14158 * Translate a character to hex digit.
14159 * */
14160 u32
MapCharToHexDigit(char chTmp)14161 MapCharToHexDigit(
14162 char chTmp
14163 )
14164 {
14165 if (chTmp >= '0' && chTmp <= '9')
14166 return chTmp - '0';
14167 else if (chTmp >= 'a' && chTmp <= 'f')
14168 return 10 + (chTmp - 'a');
14169 else if (chTmp >= 'A' && chTmp <= 'F')
14170 return 10 + (chTmp - 'A');
14171 else
14172 return 0;
14173 }
14174
14175
14176
14177 /*
14178 * Description:
14179 * Parse hex number from the string pucStr.
14180 * */
14181 BOOLEAN
GetHexValueFromString(char * szStr,u32 * pu4bVal,u32 * pu4bMove)14182 GetHexValueFromString(
14183 char *szStr,
14184 u32 *pu4bVal,
14185 u32 *pu4bMove
14186 )
14187 {
14188 char *szScan = szStr;
14189
14190 /* Check input parameter. */
14191 if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
14192 RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
14193 return _FALSE;
14194 }
14195
14196 /* Initialize output. */
14197 *pu4bMove = 0;
14198 *pu4bVal = 0;
14199
14200 /* Skip leading space. */
14201 while (*szScan != '\0' &&
14202 (*szScan == ' ' || *szScan == '\t')) {
14203 szScan++;
14204 (*pu4bMove)++;
14205 }
14206
14207 /* Skip leading '0x' or '0X'. */
14208 if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
14209 szScan += 2;
14210 (*pu4bMove) += 2;
14211 }
14212
14213 /* Check if szScan is now pointer to a character for hex digit, */
14214 /* if not, it means this is not a valid hex number. */
14215 if (!IsHexDigit(*szScan))
14216 return _FALSE;
14217
14218 /* Parse each digit. */
14219 do {
14220 (*pu4bVal) <<= 4;
14221 *pu4bVal += MapCharToHexDigit(*szScan);
14222
14223 szScan++;
14224 (*pu4bMove)++;
14225 } while (IsHexDigit(*szScan));
14226
14227 return _TRUE;
14228 }
14229
14230 BOOLEAN
GetFractionValueFromString(char * szStr,u8 * pInteger,u8 * pFraction,u32 * pu4bMove)14231 GetFractionValueFromString(
14232 char *szStr,
14233 u8 *pInteger,
14234 u8 *pFraction,
14235 u32 *pu4bMove
14236 )
14237 {
14238 char *szScan = szStr;
14239
14240 /* Initialize output. */
14241 *pu4bMove = 0;
14242 *pInteger = 0;
14243 *pFraction = 0;
14244
14245 /* Skip leading space. */
14246 while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) {
14247 ++szScan;
14248 ++(*pu4bMove);
14249 }
14250
14251 if (*szScan < '0' || *szScan > '9')
14252 return _FALSE;
14253
14254 /* Parse each digit. */
14255 do {
14256 (*pInteger) *= 10;
14257 *pInteger += (*szScan - '0');
14258
14259 ++szScan;
14260 ++(*pu4bMove);
14261
14262 if (*szScan == '.') {
14263 ++szScan;
14264 ++(*pu4bMove);
14265
14266 if (*szScan < '0' || *szScan > '9')
14267 return _FALSE;
14268
14269 *pFraction += (*szScan - '0') * 10;
14270 ++szScan;
14271 ++(*pu4bMove);
14272
14273 if (*szScan >= '0' && *szScan <= '9') {
14274 *pFraction += *szScan - '0';
14275 ++szScan;
14276 ++(*pu4bMove);
14277 }
14278 return _TRUE;
14279 }
14280 } while (*szScan >= '0' && *szScan <= '9');
14281
14282 return _TRUE;
14283 }
14284
14285 /*
14286 * Description:
14287 * Return TRUE if szStr is comment out with leading " */ /* ".
14288 * */
14289 BOOLEAN
IsCommentString(char * szStr)14290 IsCommentString(
14291 char *szStr
14292 )
14293 {
14294 if (*szStr == '/' && *(szStr + 1) == '/')
14295 return _TRUE;
14296 else
14297 return _FALSE;
14298 }
14299
14300 BOOLEAN
GetU1ByteIntegerFromStringInDecimal(char * Str,u8 * pInt)14301 GetU1ByteIntegerFromStringInDecimal(
14302 char *Str,
14303 u8 *pInt
14304 )
14305 {
14306 u16 i = 0;
14307 *pInt = 0;
14308
14309 while (Str[i] != '\0') {
14310 if (Str[i] >= '0' && Str[i] <= '9') {
14311 *pInt *= 10;
14312 *pInt += (Str[i] - '0');
14313 } else
14314 return _FALSE;
14315 ++i;
14316 }
14317
14318 return _TRUE;
14319 }
14320
14321 /* <20121004, Kordan> For example,
14322 * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
14323 * If RightQualifier does not exist, it will hang on in the while loop */
14324 BOOLEAN
ParseQualifiedString(char * In,u32 * Start,char * Out,char LeftQualifier,char RightQualifier)14325 ParseQualifiedString(
14326 char *In,
14327 u32 *Start,
14328 char *Out,
14329 char LeftQualifier,
14330 char RightQualifier
14331 )
14332 {
14333 u32 i = 0, j = 0;
14334 char c = In[(*Start)++];
14335
14336 if (c != LeftQualifier)
14337 return _FALSE;
14338
14339 i = (*Start);
14340 c = In[(*Start)++];
14341 while (c != RightQualifier && c != '\0')
14342 c = In[(*Start)++];
14343
14344 if (c == '\0')
14345 return _FALSE;
14346
14347 j = (*Start) - 2;
14348 strncpy((char *)Out, (const char *)(In + i), j - i + 1);
14349
14350 return _TRUE;
14351 }
14352
14353 BOOLEAN
isAllSpaceOrTab(u8 * data,u8 size)14354 isAllSpaceOrTab(
14355 u8 *data,
14356 u8 size
14357 )
14358 {
14359 u8 cnt = 0, NumOfSpaceAndTab = 0;
14360
14361 while (size > cnt) {
14362 if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
14363 ++NumOfSpaceAndTab;
14364
14365 ++cnt;
14366 }
14367
14368 return size == NumOfSpaceAndTab;
14369 }
14370
14371
rtw_hal_check_rxfifo_full(_adapter * adapter)14372 void rtw_hal_check_rxfifo_full(_adapter *adapter)
14373 {
14374 struct dvobj_priv *psdpriv = adapter->dvobj;
14375 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
14376 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
14377 struct registry_priv *regsty = &adapter->registrypriv;
14378 int save_cnt = _FALSE;
14379
14380 if (regsty->check_hw_status == 1) {
14381 /* switch counter to RX fifo */
14382 if (IS_8188E(pHalData->version_id) ||
14383 IS_8188F(pHalData->version_id) ||
14384 IS_8188GTV(pHalData->version_id) ||
14385 IS_8812_SERIES(pHalData->version_id) ||
14386 IS_8821_SERIES(pHalData->version_id) ||
14387 IS_8723B_SERIES(pHalData->version_id) ||
14388 IS_8192E(pHalData->version_id) ||
14389 IS_8703B_SERIES(pHalData->version_id) ||
14390 IS_8723D_SERIES(pHalData->version_id) ||
14391 IS_8192F_SERIES(pHalData->version_id) ||
14392 IS_8822C_SERIES(pHalData->version_id)) {
14393 rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
14394 save_cnt = _TRUE;
14395 } else {
14396 /* todo: other chips */
14397 }
14398
14399
14400 if (save_cnt) {
14401 pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
14402 pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
14403 pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
14404 } else {
14405 /* special value to indicate no implementation */
14406 pdbgpriv->dbg_rx_fifo_last_overflow = 1;
14407 pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
14408 pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
14409 }
14410 }
14411 }
14412
linked_info_dump(_adapter * padapter,u8 benable)14413 void linked_info_dump(_adapter *padapter, u8 benable)
14414 {
14415 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
14416
14417 if (padapter->bLinkInfoDump == benable)
14418 return;
14419
14420 RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
14421
14422 if (benable) {
14423 #ifdef CONFIG_LPS
14424 pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
14425 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
14426 #endif
14427
14428 #ifdef CONFIG_IPS
14429 pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
14430 rtw_pm_set_ips(padapter, IPS_NONE);
14431 #endif
14432 } else {
14433 #ifdef CONFIG_IPS
14434 rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
14435 #endif /* CONFIG_IPS */
14436
14437 #ifdef CONFIG_LPS
14438 rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
14439 #endif /* CONFIG_LPS */
14440 }
14441 padapter->bLinkInfoDump = benable ;
14442 }
14443
14444 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
rtw_get_raw_rssi_info(void * sel,_adapter * padapter)14445 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
14446 {
14447 u8 isCCKrate, rf_path;
14448 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14449 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14450 RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
14451 HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
14452 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14453
14454 if (isCCKrate)
14455 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
14456
14457 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14458 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14459 continue;
14460 RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
14461 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
14462
14463 if (!isCCKrate) {
14464 RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
14465 psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
14466 }
14467 }
14468 }
14469
rtw_dump_raw_rssi_info(_adapter * padapter,void * sel)14470 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
14471 {
14472 u8 isCCKrate, rf_path;
14473 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14474 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14475 _RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
14476 _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);
14477
14478 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14479
14480 if (isCCKrate)
14481 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
14482
14483 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14484 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14485 continue;
14486 _RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
14487 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
14488
14489 if (!isCCKrate)
14490 _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]);
14491 else
14492 _RTW_PRINT_SEL(sel , "\n");
14493
14494 }
14495 }
14496 #endif
14497
14498 #ifdef DBG_RX_DFRAME_RAW_DATA
rtw_dump_rx_dframe_info(_adapter * padapter,void * sel)14499 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
14500 {
14501 #define DBG_RX_DFRAME_RAW_DATA_UC 0
14502 #define DBG_RX_DFRAME_RAW_DATA_BMC 1
14503 #define DBG_RX_DFRAME_RAW_DATA_TYPES 2
14504
14505 _irqL irqL;
14506 u8 isCCKrate, rf_path;
14507 struct recv_priv *precvpriv = &(padapter->recvpriv);
14508 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14509 struct sta_priv *pstapriv = &padapter->stapriv;
14510 struct sta_info *psta;
14511 struct sta_recv_dframe_info *psta_dframe_info;
14512 int i, j;
14513 _list *plist, *phead;
14514 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14515 u8 null_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14516
14517 if (precvpriv->store_law_data_flag) {
14518
14519 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
14520
14521 for (i = 0; i < NUM_STA; i++) {
14522 phead = &(pstapriv->sta_hash[i]);
14523 plist = get_next(phead);
14524
14525 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
14526
14527 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
14528 plist = get_next(plist);
14529
14530 if (psta) {
14531 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE)
14532 && (_rtw_memcmp(psta->cmn.mac_addr, null_addr, ETH_ALEN) != _TRUE)
14533 && (_rtw_memcmp(psta->cmn.mac_addr, adapter_mac_addr(padapter), ETH_ALEN) != _TRUE)) {
14534
14535 RTW_PRINT_SEL(sel, "==============================\n");
14536 RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
14537
14538 for (j = 0; j < DBG_RX_DFRAME_RAW_DATA_TYPES; j++) {
14539 if (j == DBG_RX_DFRAME_RAW_DATA_UC) {
14540 psta_dframe_info = &psta->sta_dframe_info;
14541 RTW_PRINT_SEL(sel, "\n");
14542 RTW_PRINT_SEL(sel, "Unicast:\n");
14543 } else if (j == DBG_RX_DFRAME_RAW_DATA_BMC) {
14544 psta_dframe_info = &psta->sta_dframe_info_bmc;
14545 RTW_PRINT_SEL(sel, "\n");
14546 RTW_PRINT_SEL(sel, "Broadcast/Multicast:\n");
14547 }
14548
14549 isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14550
14551 RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", ch_width_str(psta_dframe_info->sta_bw_mode), psta_dframe_info->sta_sgi);
14552 RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
14553
14554 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14555 if (!(GET_HAL_RX_PATH_BMP(padapter) & BIT(rf_path)))
14556 continue;
14557 if (!isCCKrate) {
14558 RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
14559 _RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
14560 } else
14561 RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
14562 }
14563 }
14564
14565 }
14566 }
14567 }
14568 }
14569 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
14570 }
14571 }
14572 #endif
rtw_store_phy_info(_adapter * padapter,union recv_frame * prframe)14573 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
14574 {
14575 u8 isCCKrate, rf_path , dframe_type;
14576 u8 *ptr;
14577 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
14578 #ifdef DBG_RX_DFRAME_RAW_DATA
14579 struct sta_recv_dframe_info *psta_dframe_info;
14580 #endif
14581 struct recv_priv *precvpriv = &(padapter->recvpriv);
14582 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
14583 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
14584 struct sta_info *psta = prframe->u.hdr.psta;
14585 struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
14586 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
14587 psample_pkt_rssi->data_rate = pattrib->data_rate;
14588 ptr = prframe->u.hdr.rx_data;
14589 dframe_type = GetFrameType(ptr);
14590 /*RTW_INFO("=>%s\n", __FUNCTION__);*/
14591
14592
14593 if (precvpriv->store_law_data_flag) {
14594 isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
14595
14596 psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
14597 psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
14598
14599 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14600 psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
14601 psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
14602 if (!isCCKrate) {
14603 psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
14604 psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
14605 }
14606 }
14607 #ifdef DBG_RX_DFRAME_RAW_DATA
14608 if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
14609
14610 /*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
14611 if (psta) {
14612 if (IS_MCAST(get_ra(get_recvframe_data(prframe))))
14613 psta_dframe_info = &psta->sta_dframe_info_bmc;
14614 else
14615 psta_dframe_info = &psta->sta_dframe_info;
14616 /*RTW_INFO("=>%s psta->cmn.mac_addr="MAC_FMT" !\n",
14617 __FUNCTION__, MAC_ARG(psta->cmn.mac_addr));*/
14618 if ((_rtw_memcmp(psta->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
14619 psta_dframe_info->sta_data_rate = pattrib->data_rate;
14620 psta_dframe_info->sta_sgi = pattrib->sgi;
14621 psta_dframe_info->sta_bw_mode = pattrib->bw;
14622 for (rf_path = 0; rf_path < hal_spec->rf_reg_path_num; rf_path++) {
14623
14624 psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
14625
14626 if (!isCCKrate) {
14627 psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
14628 psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
14629 }
14630 }
14631 }
14632 }
14633 }
14634 #endif
14635 }
14636
14637 }
14638
hal_efuse_macaddr_offset(_adapter * adapter)14639 int hal_efuse_macaddr_offset(_adapter *adapter)
14640 {
14641 u8 interface_type = 0;
14642 int addr_offset = -1;
14643
14644 interface_type = rtw_get_intf_type(adapter);
14645
14646 switch (rtw_get_chip_type(adapter)) {
14647 #ifdef CONFIG_RTL8723B
14648 case RTL8723B:
14649 if (interface_type == RTW_USB)
14650 addr_offset = EEPROM_MAC_ADDR_8723BU;
14651 else if (interface_type == RTW_SDIO)
14652 addr_offset = EEPROM_MAC_ADDR_8723BS;
14653 else if (interface_type == RTW_PCIE)
14654 addr_offset = EEPROM_MAC_ADDR_8723BE;
14655 break;
14656 #endif
14657 #ifdef CONFIG_RTL8703B
14658 case RTL8703B:
14659 if (interface_type == RTW_USB)
14660 addr_offset = EEPROM_MAC_ADDR_8703BU;
14661 else if (interface_type == RTW_SDIO)
14662 addr_offset = EEPROM_MAC_ADDR_8703BS;
14663 break;
14664 #endif
14665 #ifdef CONFIG_RTL8723D
14666 case RTL8723D:
14667 if (interface_type == RTW_USB)
14668 addr_offset = EEPROM_MAC_ADDR_8723DU;
14669 else if (interface_type == RTW_SDIO)
14670 addr_offset = EEPROM_MAC_ADDR_8723DS;
14671 else if (interface_type == RTW_PCIE)
14672 addr_offset = EEPROM_MAC_ADDR_8723DE;
14673 break;
14674 #endif
14675
14676 #ifdef CONFIG_RTL8188E
14677 case RTL8188E:
14678 if (interface_type == RTW_USB)
14679 addr_offset = EEPROM_MAC_ADDR_88EU;
14680 else if (interface_type == RTW_SDIO)
14681 addr_offset = EEPROM_MAC_ADDR_88ES;
14682 else if (interface_type == RTW_PCIE)
14683 addr_offset = EEPROM_MAC_ADDR_88EE;
14684 break;
14685 #endif
14686 #ifdef CONFIG_RTL8188F
14687 case RTL8188F:
14688 if (interface_type == RTW_USB)
14689 addr_offset = EEPROM_MAC_ADDR_8188FU;
14690 else if (interface_type == RTW_SDIO)
14691 addr_offset = EEPROM_MAC_ADDR_8188FS;
14692 break;
14693 #endif
14694 #ifdef CONFIG_RTL8188GTV
14695 case RTL8188GTV:
14696 if (interface_type == RTW_USB)
14697 addr_offset = EEPROM_MAC_ADDR_8188GTVU;
14698 else if (interface_type == RTW_SDIO)
14699 addr_offset = EEPROM_MAC_ADDR_8188GTVS;
14700 break;
14701 #endif
14702 #ifdef CONFIG_RTL8812A
14703 case RTL8812:
14704 if (interface_type == RTW_USB)
14705 addr_offset = EEPROM_MAC_ADDR_8812AU;
14706 else if (interface_type == RTW_PCIE)
14707 addr_offset = EEPROM_MAC_ADDR_8812AE;
14708 break;
14709 #endif
14710 #ifdef CONFIG_RTL8821A
14711 case RTL8821:
14712 if (interface_type == RTW_USB)
14713 addr_offset = EEPROM_MAC_ADDR_8821AU;
14714 else if (interface_type == RTW_SDIO)
14715 addr_offset = EEPROM_MAC_ADDR_8821AS;
14716 else if (interface_type == RTW_PCIE)
14717 addr_offset = EEPROM_MAC_ADDR_8821AE;
14718 break;
14719 #endif
14720 #ifdef CONFIG_RTL8192E
14721 case RTL8192E:
14722 if (interface_type == RTW_USB)
14723 addr_offset = EEPROM_MAC_ADDR_8192EU;
14724 else if (interface_type == RTW_SDIO)
14725 addr_offset = EEPROM_MAC_ADDR_8192ES;
14726 else if (interface_type == RTW_PCIE)
14727 addr_offset = EEPROM_MAC_ADDR_8192EE;
14728 break;
14729 #endif
14730 #ifdef CONFIG_RTL8814A
14731 case RTL8814A:
14732 if (interface_type == RTW_USB)
14733 addr_offset = EEPROM_MAC_ADDR_8814AU;
14734 else if (interface_type == RTW_PCIE)
14735 addr_offset = EEPROM_MAC_ADDR_8814AE;
14736 break;
14737 #endif
14738
14739 #ifdef CONFIG_RTL8822B
14740 case RTL8822B:
14741 if (interface_type == RTW_USB)
14742 addr_offset = EEPROM_MAC_ADDR_8822BU;
14743 else if (interface_type == RTW_SDIO)
14744 addr_offset = EEPROM_MAC_ADDR_8822BS;
14745 else if (interface_type == RTW_PCIE)
14746 addr_offset = EEPROM_MAC_ADDR_8822BE;
14747 break;
14748 #endif /* CONFIG_RTL8822B */
14749
14750 #ifdef CONFIG_RTL8821C
14751 case RTL8821C:
14752 if (interface_type == RTW_USB)
14753 addr_offset = EEPROM_MAC_ADDR_8821CU;
14754 else if (interface_type == RTW_SDIO)
14755 addr_offset = EEPROM_MAC_ADDR_8821CS;
14756 else if (interface_type == RTW_PCIE)
14757 addr_offset = EEPROM_MAC_ADDR_8821CE;
14758 break;
14759 #endif /* CONFIG_RTL8821C */
14760
14761 #ifdef CONFIG_RTL8710B
14762 case RTL8710B:
14763 if (interface_type == RTW_USB)
14764 addr_offset = EEPROM_MAC_ADDR_8710B;
14765 break;
14766 #endif
14767
14768 #ifdef CONFIG_RTL8192F
14769 case RTL8192F:
14770 if (interface_type == RTW_USB)
14771 addr_offset = EEPROM_MAC_ADDR_8192FU;
14772 else if (interface_type == RTW_SDIO)
14773 addr_offset = EEPROM_MAC_ADDR_8192FS;
14774 else if (interface_type == RTW_PCIE)
14775 addr_offset = EEPROM_MAC_ADDR_8192FE;
14776 break;
14777 #endif /* CONFIG_RTL8192F */
14778
14779 #ifdef CONFIG_RTL8822C
14780 case RTL8822C:
14781 if (interface_type == RTW_USB)
14782 addr_offset = EEPROM_MAC_ADDR_8822CU;
14783 else if (interface_type == RTW_SDIO)
14784 addr_offset = EEPROM_MAC_ADDR_8822CS;
14785 else if (interface_type == RTW_PCIE)
14786 addr_offset = EEPROM_MAC_ADDR_8822CE;
14787 break;
14788 #endif /* CONFIG_RTL8822C */
14789
14790 #ifdef CONFIG_RTL8814B
14791 case RTL8814B:
14792 if (interface_type == RTW_USB)
14793 addr_offset = EEPROM_MAC_ADDR_8814BU;
14794 else if (interface_type == RTW_PCIE)
14795 addr_offset = EEPROM_MAC_ADDR_8814BE;
14796 break;
14797 #endif /* CONFIG_RTL8814B */
14798
14799 #ifdef CONFIG_RTL8723F
14800 case RTL8723F:
14801 if (interface_type == RTW_USB)
14802 addr_offset = EEPROM_MAC_ADDR_8723FU;
14803 else if (interface_type == RTW_SDIO)
14804 addr_offset = EEPROM_MAC_ADDR_8723FS;
14805 break;
14806 #endif /* CONFIG_RTL8723F */
14807 }
14808
14809 if (addr_offset == -1) {
14810 RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
14811 , __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
14812 }
14813
14814 return addr_offset;
14815 }
14816
Hal_GetPhyEfuseMACAddr(PADAPTER padapter,u8 * mac_addr)14817 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
14818 {
14819 int ret = _FAIL;
14820 int addr_offset;
14821
14822 addr_offset = hal_efuse_macaddr_offset(padapter);
14823 if (addr_offset == -1)
14824 goto exit;
14825
14826 ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
14827
14828 exit:
14829 return ret;
14830 }
14831
rtw_dump_cur_efuse(PADAPTER padapter)14832 void rtw_dump_cur_efuse(PADAPTER padapter)
14833 {
14834 int mapsize =0;
14835 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14836
14837 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
14838
14839 if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
14840 RTW_ERR("wrong map size %d\n", mapsize);
14841 return;
14842 }
14843
14844 #ifdef CONFIG_RTW_DEBUG
14845 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14846 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "EFUSE FILE", hal_data->efuse_eeprom_data, mapsize);
14847 else {
14848 #ifdef CONFIG_MP_INCLUDED
14849 if (rtw_mp_mode_check(padapter) && GET_EFUSE_UPDATE_ON(padapter))
14850 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "FAKE EFUSE", hal_data->efuse_eeprom_data, mapsize);
14851 else
14852 #endif
14853 RTW_MAP_DUMP_SEL(RTW_DBGDUMP, "HW EFUSE", hal_data->efuse_eeprom_data, mapsize);
14854 }
14855 #endif
14856 }
14857
14858
14859 #ifdef CONFIG_EFUSE_CONFIG_FILE
Hal_readPGDataFromConfigFile(PADAPTER padapter)14860 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
14861 {
14862 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14863 u32 ret = _FALSE;
14864 u32 maplen = 0;
14865 #ifdef CONFIG_MP_INCLUDED
14866 struct mp_priv *pmp_priv = &padapter->mppriv;
14867 #endif
14868
14869 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
14870
14871 if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
14872 RTW_ERR("eFuse length error :%d\n", maplen);
14873 return _FALSE;
14874 }
14875 #ifdef CONFIG_MP_INCLUDED
14876 if (pmp_priv->efuse_update_file == _TRUE && (rtw_mp_mode_check(padapter))) {
14877 RTW_INFO("%s, eFuse read from file :%s\n", __func__, pmp_priv->efuse_file_path);
14878 ret = rtw_read_efuse_from_file(pmp_priv->efuse_file_path, hal_data->efuse_eeprom_data, maplen);
14879 pmp_priv->efuse_update_file = _FALSE;
14880 } else
14881 #endif
14882 {
14883 ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
14884 }
14885
14886 hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
14887
14888 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14889 rtw_dump_cur_efuse(padapter);
14890
14891 return ret;
14892 }
14893
Hal_ReadMACAddrFromFile(PADAPTER padapter,u8 * mac_addr)14894 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
14895 {
14896 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
14897 u32 ret = _FAIL;
14898
14899 if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
14900 && rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
14901 ) {
14902 hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
14903 ret = _SUCCESS;
14904 } else
14905 hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
14906
14907 return ret;
14908 }
14909 #endif /* CONFIG_EFUSE_CONFIG_FILE */
14910
hal_config_macaddr(_adapter * adapter,bool autoload_fail)14911 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
14912 {
14913 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
14914 u8 addr[ETH_ALEN];
14915 int addr_offset = hal_efuse_macaddr_offset(adapter);
14916 u8 *hw_addr = NULL;
14917 int ret = _SUCCESS;
14918 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
14919 u8 ft_mac_addr[ETH_ALEN] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; /* FT USB2 for 8822B */
14920 #endif
14921
14922 if (autoload_fail)
14923 goto bypass_hw_pg;
14924
14925 if (addr_offset != -1)
14926 hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
14927
14928 #ifdef CONFIG_EFUSE_CONFIG_FILE
14929 /* if the hw_addr is written by efuse file, set to NULL */
14930 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
14931 hw_addr = NULL;
14932 #endif
14933
14934 if (!hw_addr) {
14935 /* try getting hw pg data */
14936 if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
14937 hw_addr = addr;
14938 }
14939
14940 #if defined(CONFIG_RTL8822B) && defined(CONFIG_USB_HCI)
14941 if (_rtw_memcmp(hw_addr, ft_mac_addr, ETH_ALEN))
14942 hw_addr[0] = 0xff;
14943 #endif
14944
14945 /* check hw pg data */
14946 if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
14947 _rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
14948 goto exit;
14949 }
14950
14951 bypass_hw_pg:
14952
14953 #ifdef CONFIG_EFUSE_CONFIG_FILE
14954 /* check wifi mac file */
14955 if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
14956 _rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
14957 goto exit;
14958 }
14959 #endif
14960
14961 _rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
14962 ret = _FAIL;
14963
14964 exit:
14965 return ret;
14966 }
14967
14968 #ifdef CONFIG_RF_POWER_TRIM
14969 u32 Array_kfreemap[] = {
14970 0x08, 0xe,
14971 0x06, 0xc,
14972 0x04, 0xa,
14973 0x02, 0x8,
14974 0x00, 0x6,
14975 0x03, 0x4,
14976 0x05, 0x2,
14977 0x07, 0x0,
14978 0x09, 0x0,
14979 0x0c, 0x0,
14980 };
14981
rtw_bb_rf_gain_offset(_adapter * padapter)14982 void rtw_bb_rf_gain_offset(_adapter *padapter)
14983 {
14984 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
14985 struct registry_priv *registry_par = &padapter->registrypriv;
14986 struct kfree_data_t *kfree_data = &pHalData->kfree_data;
14987 u8 value = pHalData->EEPROMRFGainOffset;
14988 u8 tmp = 0x3e;
14989 u32 res, i = 0;
14990 u32 ArrayLen = sizeof(Array_kfreemap) / sizeof(u32);
14991 u32 *Array = Array_kfreemap;
14992 u32 v1 = 0, v2 = 0, GainValue = 0, target = 0;
14993
14994 if (registry_par->RegPwrTrimEnable == 2) {
14995 RTW_INFO("Registry kfree default force disable.\n");
14996 return;
14997 }
14998
14999 #if defined(CONFIG_RTL8723B)
15000 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
15001 RTW_INFO("Offset RF Gain.\n");
15002 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
15003
15004 if (pHalData->EEPROMRFGainVal != 0xff) {
15005
15006 if (pHalData->ant_path == RF_PATH_A)
15007 GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
15008
15009 else
15010 GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
15011 RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == RF_PATH_A) ? (RF_PATH_A) : (RF_PATH_B), GainValue);
15012
15013 for (i = 0; i < ArrayLen; i += 2) {
15014 /* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
15015 v1 = Array[i];
15016 v2 = Array[i + 1];
15017 if (v1 == GainValue) {
15018 RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
15019 target = v2;
15020 break;
15021 }
15022 }
15023 RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
15024
15025 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
15026 RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
15027 phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
15028 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
15029
15030 RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
15031
15032 } else
15033
15034 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
15035 } else
15036 RTW_INFO("Using the default RF gain.\n");
15037
15038 #elif defined(CONFIG_RTL8188E)
15039 if (value & BIT4 && (registry_par->RegPwrTrimEnable == 1)) {
15040 RTW_INFO("8188ES Offset RF Gain.\n");
15041 RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
15042 pHalData->EEPROMRFGainVal);
15043
15044 if (pHalData->EEPROMRFGainVal != 0xff) {
15045 res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
15046 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
15047
15048 RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
15049 res &= 0xfff87fff;
15050
15051 res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
15052 RTW_INFO("Offset RF Gain. res=0x%x\n", res);
15053
15054 rtw_hal_write_rfreg(padapter, RF_PATH_A,
15055 REG_RF_BB_GAIN_OFFSET,
15056 RF_GAIN_OFFSET_MASK, res);
15057 } else {
15058 RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
15059 pHalData->EEPROMRFGainVal);
15060 }
15061 } else
15062 RTW_INFO("Using the default RF gain.\n");
15063 #else
15064 /* TODO: call this when channel switch */
15065 if (kfree_data->flag & KFREE_FLAG_ON)
15066 rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
15067 #endif
15068
15069 }
15070 #endif /*CONFIG_RF_POWER_TRIM */
15071
kfree_data_is_bb_gain_empty(struct kfree_data_t * data)15072 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
15073 {
15074 #ifdef CONFIG_RF_POWER_TRIM
15075 int i, j;
15076
15077 for (i = 0; i < BB_GAIN_NUM; i++)
15078 for (j = 0; j < RF_PATH_MAX; j++)
15079 if (data->bb_gain[i][j] != 0)
15080 return 0;
15081 #endif
15082 return 1;
15083 }
15084
15085 #ifdef CONFIG_USB_RX_AGGREGATION
rtw_set_usb_agg_by_mode_normal(_adapter * padapter,u8 cur_wireless_mode)15086 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
15087 {
15088 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15089 if (cur_wireless_mode < WIRELESS_11_24N
15090 && cur_wireless_mode > 0) { /* ABG mode */
15091 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
15092 u32 remainder = 0;
15093 u8 quotient = 0;
15094
15095 remainder = MAX_RECVBUF_SZ % (4 * 1024);
15096 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
15097
15098 if (quotient > 5) {
15099 pHalData->rxagg_usb_size = 0x6;
15100 pHalData->rxagg_usb_timeout = 0x10;
15101 } else {
15102 if (remainder >= 2048) {
15103 pHalData->rxagg_usb_size = quotient;
15104 pHalData->rxagg_usb_timeout = 0x10;
15105 } else {
15106 pHalData->rxagg_usb_size = (quotient - 1);
15107 pHalData->rxagg_usb_timeout = 0x10;
15108 }
15109 }
15110 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
15111 if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
15112 pHalData->rxagg_usb_size = 0x6;
15113 pHalData->rxagg_usb_timeout = 0x10;
15114 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
15115 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
15116 }
15117 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
15118
15119 } else if (cur_wireless_mode >= WIRELESS_11_24N
15120 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
15121 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
15122 u32 remainder = 0;
15123 u8 quotient = 0;
15124
15125 remainder = MAX_RECVBUF_SZ % (4 * 1024);
15126 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
15127
15128 if (quotient > 5) {
15129 pHalData->rxagg_usb_size = 0x5;
15130 pHalData->rxagg_usb_timeout = 0x20;
15131 } else {
15132 if (remainder >= 2048) {
15133 pHalData->rxagg_usb_size = quotient;
15134 pHalData->rxagg_usb_timeout = 0x10;
15135 } else {
15136 pHalData->rxagg_usb_size = (quotient - 1);
15137 pHalData->rxagg_usb_timeout = 0x10;
15138 }
15139 }
15140 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
15141 if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
15142 pHalData->rxagg_usb_size = 0x5;
15143 pHalData->rxagg_usb_timeout = 0x20;
15144 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
15145 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
15146 }
15147 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
15148
15149 } else {
15150 /* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
15151 }
15152 }
15153
rtw_set_usb_agg_by_mode_customer(_adapter * padapter,u8 cur_wireless_mode,u8 UsbDmaSize,u8 Legacy_UsbDmaSize)15154 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
15155 {
15156 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15157
15158 if (cur_wireless_mode < WIRELESS_11_24N
15159 && cur_wireless_mode > 0) { /* ABG mode */
15160 if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
15161 || 0x10 != pHalData->rxagg_usb_timeout) {
15162 pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
15163 pHalData->rxagg_usb_timeout = 0x10;
15164 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
15165 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
15166 }
15167 } else if (cur_wireless_mode >= WIRELESS_11_24N
15168 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
15169 if (UsbDmaSize != pHalData->rxagg_usb_size
15170 || 0x20 != pHalData->rxagg_usb_timeout) {
15171 pHalData->rxagg_usb_size = UsbDmaSize;
15172 pHalData->rxagg_usb_timeout = 0x20;
15173 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
15174 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
15175 }
15176 } else {
15177 /* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
15178 }
15179 }
15180
rtw_set_usb_agg_by_mode(_adapter * padapter,u8 cur_wireless_mode)15181 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
15182 {
15183 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
15184 rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
15185 return;
15186 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
15187
15188 rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
15189 }
15190 #endif /* CONFIG_USB_RX_AGGREGATION */
15191
15192 /* To avoid RX affect TX throughput */
dm_DynamicUsbTxAgg(_adapter * padapter,u8 from_timer)15193 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
15194 {
15195 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
15196 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
15197 struct registry_priv *registry_par = &padapter->registrypriv;
15198 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15199 u8 cur_wireless_mode = WIRELESS_INVALID;
15200
15201 #ifdef CONFIG_USB_RX_AGGREGATION
15202 if (!registry_par->dynamic_agg_enable)
15203 return;
15204
15205 #ifdef RTW_HALMAC
15206 if (IS_HARDWARE_TYPE_8822BU(padapter) || IS_HARDWARE_TYPE_8821CU(padapter)
15207 || IS_HARDWARE_TYPE_8822CU(padapter) || IS_HARDWARE_TYPE_8814BU(padapter)
15208 || IS_HARDWARE_TYPE_8723FU(padapter))
15209 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, NULL);
15210 #else /* !RTW_HALMAC */
15211 if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
15212 /* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
15213 if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)) {
15214 if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
15215 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
15216 else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
15217 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
15218 else
15219 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
15220
15221 /* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
15222 }
15223 } else if (IS_HARDWARE_TYPE_8812(padapter)) {
15224 #ifdef CONFIG_CONCURRENT_MODE
15225 u8 i;
15226 _adapter *iface;
15227 u8 bassocaed = _FALSE;
15228 struct mlme_ext_priv *mlmeext;
15229
15230 for (i = 0; i < pdvobjpriv->iface_nums; i++) {
15231 iface = pdvobjpriv->padapters[i];
15232 mlmeext = &iface->mlmeextpriv;
15233 if (rtw_linked_check(iface) == _TRUE) {
15234 if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
15235 cur_wireless_mode = mlmeext->cur_wireless_mode;
15236 bassocaed = _TRUE;
15237 }
15238 }
15239 if (bassocaed)
15240 #endif
15241 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
15242 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
15243 } else {
15244 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
15245 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
15246 }
15247 #endif /* RTW_HALMAC */
15248 #endif /* CONFIG_USB_RX_AGGREGATION */
15249
15250 }
15251
15252 /* bus-agg check for SoftAP mode */
rtw_hal_busagg_qsel_check(_adapter * padapter,u8 pre_qsel,u8 next_qsel)15253 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
15254 {
15255 #ifdef CONFIG_AP_MODE
15256 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
15257 u8 chk_rst = _SUCCESS;
15258
15259 if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
15260 return chk_rst;
15261
15262 /* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
15263 /* return chk_rst; */
15264
15265 if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
15266 && (pre_qsel != next_qsel)) {
15267 /* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
15268 /* pre_qsel,next_qsel); */
15269 chk_rst = _FAIL;
15270 }
15271 return chk_rst;
15272 #else
15273 return _SUCCESS;
15274 #endif /* CONFIG_AP_MODE */
15275 }
15276
15277 #ifdef CONFIG_WOWLAN
15278 /*
15279 * Description:
15280 * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
15281 * contant.
15282 *
15283 * Input:
15284 * adapter: adapter pointer.
15285 * page_num: The max. page number that user want to dump.
15286 * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
15287 */
dump_TX_FIFO(_adapter * padapter,u8 page_num,u16 page_size)15288 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
15289 {
15290
15291 int i;
15292 u8 val = 0;
15293 u8 base = 0;
15294 u32 addr = 0;
15295 u32 count = (page_size / 8);
15296
15297 if (page_num <= 0) {
15298 RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
15299 return;
15300 }
15301
15302 if (page_size < 128 || page_size > 512) {
15303 RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
15304 return;
15305 }
15306
15307 RTW_INFO("+%s+\n", __func__);
15308 val = rtw_read8(padapter, 0x106);
15309 rtw_write8(padapter, 0x106, 0x69);
15310 RTW_INFO("0x106: 0x%02x\n", val);
15311 base = rtw_read8(padapter, 0x209);
15312 RTW_INFO("0x209: 0x%02x\n", base);
15313
15314 addr = ((base)*page_size) / 8;
15315 for (i = 0 ; i < page_num * count ; i += 2) {
15316 rtw_write32(padapter, 0x140, addr + i);
15317 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
15318 rtw_write32(padapter, 0x140, addr + i + 1);
15319 printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
15320 }
15321 }
15322 #endif
15323
15324 #ifdef CONFIG_GPIO_API
rtw_hal_get_gpio(_adapter * adapter,u8 gpio_num)15325 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
15326 {
15327 u8 value = 0;
15328 u8 direction = 0;
15329 u32 gpio_pin_input_val = REG_GPIO_PIN_CTRL;
15330 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
15331 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
15332 u8 gpio_num_to_set = gpio_num;
15333 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
15334
15335 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15336 return value;
15337
15338 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15339
15340 RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
15341 LeaveAllPowerSaveModeDirect(adapter);
15342
15343 if (gpio_num > 7) {
15344 gpio_pin_input_val = REG_GPIO_PIN_CTRL_2;
15345 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
15346 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
15347 gpio_num_to_set = gpio_num - 8;
15348 }
15349
15350 /* Read GPIO Direction */
15351 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15352
15353 /* According the direction to read register value */
15354 if (direction)
15355 value = (rtw_read8(adapter, gpio_pin_output_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15356 else
15357 value = (rtw_read8(adapter, gpio_pin_input_val) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15358
15359 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15360 RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
15361
15362 return value;
15363 }
15364
rtw_hal_set_gpio_output_value(_adapter * adapter,u8 gpio_num,bool isHigh)15365 int rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
15366 {
15367 u8 direction = 0;
15368 u8 res = -1;
15369 u32 gpio_pin_output_val = REG_GPIO_PIN_CTRL + 1;
15370 u32 gpio_pin_output_en = REG_GPIO_PIN_CTRL + 2;
15371 u8 gpio_num_to_set = gpio_num;
15372
15373 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15374 return -1;
15375
15376 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15377
15378 LeaveAllPowerSaveModeDirect(adapter);
15379
15380 if (gpio_num > 7) {
15381 gpio_pin_output_val = REG_GPIO_PIN_CTRL_2 + 1;
15382 gpio_pin_output_en = REG_GPIO_PIN_CTRL_2 + 2;
15383 gpio_num_to_set = gpio_num - 8;
15384 }
15385
15386 /* Read GPIO direction */
15387 direction = (rtw_read8(adapter, gpio_pin_output_en) & BIT(gpio_num_to_set)) >> gpio_num_to_set;
15388
15389 /* If GPIO is output direction, setting value. */
15390 if (direction) {
15391 if (isHigh)
15392 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) | BIT(gpio_num_to_set));
15393 else
15394 rtw_write8(adapter, gpio_pin_output_val, rtw_read8(adapter, gpio_pin_output_val) & ~BIT(gpio_num_to_set));
15395
15396 RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
15397 res = 0;
15398 } else {
15399 RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
15400 res = -1;
15401 }
15402
15403 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15404 return res;
15405 }
15406
rtw_hal_config_gpio(_adapter * adapter,u8 gpio_num,bool isOutput)15407 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
15408 {
15409 u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
15410 u8 gpio_num_to_set = gpio_num;
15411
15412 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
15413 return -1;
15414
15415 RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
15416
15417 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15418
15419 LeaveAllPowerSaveModeDirect(adapter);
15420
15421 rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
15422
15423 if (gpio_num > 7) {
15424 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
15425 gpio_num_to_set = gpio_num - 8;
15426 }
15427
15428 if (isOutput)
15429 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
15430 else
15431 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
15432
15433 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15434
15435 return 0;
15436 }
rtw_hal_register_gpio_interrupt(_adapter * adapter,int gpio_num,void (* callback)(u8 level))15437 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
15438 {
15439 u8 value;
15440 u8 direction;
15441 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
15442
15443 if (IS_HARDWARE_TYPE_8188E(adapter)) {
15444 if (gpio_num > 7 || gpio_num < 4) {
15445 RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
15446 return -1;
15447 }
15448 }
15449
15450 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15451
15452 LeaveAllPowerSaveModeDirect(adapter);
15453
15454 /* Read GPIO direction */
15455 direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
15456 if (direction) {
15457 RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
15458 return -1;
15459 }
15460
15461 /* Config GPIO Mode */
15462 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
15463
15464 /* Register GPIO interrupt handler*/
15465 adapter->gpiointpriv.callback[gpio_num] = callback;
15466
15467 /* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
15468 value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
15469 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
15470 rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
15471
15472 /* Enable GPIO interrupt */
15473 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
15474 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
15475
15476 rtw_hal_update_hisr_hsisr_ind(adapter, 1);
15477
15478 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15479
15480 return 0;
15481 }
rtw_hal_disable_gpio_interrupt(_adapter * adapter,int gpio_num)15482 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
15483 {
15484 u8 value;
15485 u8 direction;
15486 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
15487
15488 if (IS_HARDWARE_TYPE_8188E(adapter)) {
15489 if (gpio_num > 7 || gpio_num < 4) {
15490 RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
15491 return -1;
15492 }
15493 }
15494
15495 rtw_ps_deny(adapter, PS_DENY_IOCTL);
15496
15497 LeaveAllPowerSaveModeDirect(adapter);
15498
15499 /* Config GPIO Mode */
15500 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
15501
15502 /* Unregister GPIO interrupt handler*/
15503 adapter->gpiointpriv.callback[gpio_num] = NULL;
15504
15505 /* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
15506 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
15507 rtw_write8(adapter, REG_GPIO_INTM, 0x00);
15508
15509 /* Disable GPIO interrupt */
15510 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
15511 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
15512
15513 if (!adapter->gpiointpriv.interrupt_enable_mask)
15514 rtw_hal_update_hisr_hsisr_ind(adapter, 0);
15515
15516 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
15517
15518 return 0;
15519 }
15520 #endif
15521
rtw_hal_ch_sw_iqk_info_search(_adapter * padapter,u8 central_chnl,u8 bw_mode)15522 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
15523 {
15524 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15525 u8 i;
15526
15527 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
15528 if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
15529 if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
15530 && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
15531 return i;
15532 }
15533 }
15534
15535 return -1;
15536 }
15537
rtw_hal_ch_sw_iqk_info_backup(_adapter * padapter)15538 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
15539 {
15540 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15541 s8 res;
15542 u8 i;
15543
15544 /* If it's an existed record, overwrite it */
15545 res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
15546 if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
15547 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
15548 return;
15549 }
15550
15551 /* Search for the empty record to use */
15552 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
15553 if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
15554 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
15555 return;
15556 }
15557 }
15558
15559 /* Else, overwrite the oldest record */
15560 for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
15561 _rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
15562
15563 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
15564 }
15565
rtw_hal_ch_sw_iqk_info_restore(_adapter * padapter,u8 ch_sw_use_case)15566 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
15567 {
15568 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
15569 }
15570
rtw_dump_mac_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15571 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15572 {
15573 u32 mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
15574 u32 mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
15575 u32 mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
15576 u32 DropPacket = 0;
15577
15578 if (!rx_counter) {
15579 rtw_warn_on(1);
15580 return;
15581 }
15582 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
15583 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15584
15585 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
15586 mac_cck_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15587 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
15588 mac_ofdm_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15589 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
15590 mac_ht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15591 mac_vht_ok = 0;
15592 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15593 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
15594 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
15595 mac_vht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
15596 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15597 }
15598
15599 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
15600 mac_cck_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15601 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
15602 mac_ofdm_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15603 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
15604 mac_ht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15605 mac_vht_err = 0;
15606 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15607 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
15608 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
15609 mac_vht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
15610 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
15611 }
15612
15613 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
15614 mac_cck_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15615 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
15616 mac_ofdm_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15617 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
15618 mac_ht_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
15619
15620 /* Mac_DropPacket */
15621 rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
15622 DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
15623
15624 rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
15625 rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
15626 rx_counter->rx_cck_fa = mac_cck_fa;
15627 rx_counter->rx_ofdm_fa = mac_ofdm_fa;
15628 rx_counter->rx_ht_fa = mac_ht_fa;
15629 rx_counter->rx_pkt_drop = DropPacket;
15630 }
rtw_reset_mac_rx_counters(_adapter * padapter)15631 void rtw_reset_mac_rx_counters(_adapter *padapter)
15632 {
15633
15634 /* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
15635 if (IS_HARDWARE_TYPE_8703B(padapter) ||
15636 IS_HARDWARE_TYPE_8723D(padapter) ||
15637 IS_HARDWARE_TYPE_8188F(padapter) ||
15638 IS_HARDWARE_TYPE_8188GTV(padapter) ||
15639 IS_HARDWARE_TYPE_8192F(padapter) ||
15640 IS_HARDWARE_TYPE_8822C(padapter))
15641 phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
15642
15643 /* reset mac counter */
15644 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
15645 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
15646 }
15647
rtw_dump_phy_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15648 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15649 {
15650 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;
15651 if (!rx_counter) {
15652 rtw_warn_on(1);
15653 return;
15654 }
15655 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15656 cckok = phy_query_bb_reg(padapter, 0xF04, 0x3FFF); /* [13:0] */
15657 ofdmok = phy_query_bb_reg(padapter, 0xF14, 0x3FFF); /* [13:0] */
15658 htok = phy_query_bb_reg(padapter, 0xF10, 0x3FFF); /* [13:0] */
15659 vht_ok = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF); /* [13:0] */
15660 cckcrc = phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16] */
15661 ofdmcrc = phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
15662 htcrc = phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
15663 vht_err = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
15664 CCK_FA = phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
15665 OFDM_FA = phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
15666 } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter)){
15667 cckok = phy_query_bb_reg(padapter, 0x2c04, 0xffff);
15668 ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
15669 htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
15670 vht_ok = phy_query_bb_reg(padapter, 0x2c0c, 0xffff);
15671 cckcrc = phy_query_bb_reg(padapter, 0x2c04, 0xffff0000);
15672 ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
15673 htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
15674 vht_err = phy_query_bb_reg(padapter, 0x2c0c, 0xffff0000);
15675 CCK_FA = phy_query_bb_reg(padapter, 0x1a5c, bMaskLWord);
15676 OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
15677 } else if(IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)){
15678 cckok = phy_query_bb_reg(padapter, 0x2aac, 0xffff);
15679 ofdmok = phy_query_bb_reg(padapter, 0x2c14, 0xffff);
15680 htok = phy_query_bb_reg(padapter, 0x2c10, 0xffff);
15681 cckcrc = phy_query_bb_reg(padapter, 0x2aac, 0xffff0000);
15682 ofdmcrc = phy_query_bb_reg(padapter, 0x2c14, 0xffff0000);
15683 htcrc = phy_query_bb_reg(padapter, 0x2c10, 0xffff0000);
15684 CCK_FA = phy_query_bb_reg(padapter, 0x2aa8, 0xffff0000) + phy_query_bb_reg(padapter, 0x2aa8, 0x0000ffff);
15685 OFDM_FA = phy_query_bb_reg(padapter, 0x2d00, bMaskLWord) - phy_query_bb_reg(padapter, 0x2de0, bMaskLWord);
15686 } else {
15687 cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
15688 ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
15689 htok = phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
15690 vht_ok = 0;
15691 cckcrc = phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
15692 ofdmcrc = phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
15693 htcrc = phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
15694 vht_err = 0;
15695 OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF0, bMaskHWord) +
15696 phy_query_bb_reg(padapter, 0xDA0, bMaskHWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
15697 phy_query_bb_reg(padapter, 0xDA4, bMaskHWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
15698
15699 CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
15700 }
15701
15702 rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
15703 rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
15704 rx_counter->rx_ofdm_fa = OFDM_FA;
15705 rx_counter->rx_cck_fa = CCK_FA;
15706
15707 }
15708
rtw_reset_phy_trx_ok_counters(_adapter * padapter)15709 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
15710 {
15711 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15712 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
15713 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
15714 } else if(IS_HARDWARE_TYPE_JAGUAR3(padapter) || IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) {
15715 phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x1);
15716 phy_set_bb_reg(padapter, 0x1EB4, BIT25, 0x0);
15717 } else {
15718 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
15719 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
15720 }
15721 }
15722
rtw_reset_phy_rx_counters(_adapter * padapter)15723 void rtw_reset_phy_rx_counters(_adapter *padapter)
15724 {
15725 /* reset phy counter */
15726 if (IS_HARDWARE_TYPE_JAGUAR3(padapter)) {
15727 /* reset CCK FA counter */
15728 phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 0);
15729 phy_set_bb_reg(padapter, 0x1a2c, BIT(15) | BIT(14), 2);
15730
15731 /* reset CCK CCA counter */
15732 phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 0);
15733 phy_set_bb_reg(padapter, 0x1a2c, BIT(13) | BIT(12), 2);
15734 rtw_reset_phy_trx_ok_counters(padapter);
15735
15736 } else if (IS_HARDWARE_TYPE_JAGUAR3_11N(padapter)) {
15737 /* reset CCK FA and CCK CCA counter */
15738 phy_set_bb_reg(padapter, 0x2a44, BIT21, 0);
15739 phy_set_bb_reg(padapter, 0x2a44, BIT21, 1);
15740 rtw_reset_phy_trx_ok_counters(padapter);
15741
15742 } else if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
15743 rtw_reset_phy_trx_ok_counters(padapter);
15744
15745 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset OFDA FA counter */
15746 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
15747
15748 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
15749 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
15750 } else {
15751 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
15752 rtw_msleep_os(10);
15753 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
15754
15755 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset OFDA FA counter */
15756 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset OFDA FA counter */
15757 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
15758 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
15759
15760 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
15761 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
15762 }
15763 }
15764 #ifdef DBG_RX_COUNTER_DUMP
rtw_dump_drv_rx_counters(_adapter * padapter,struct dbg_rx_counter * rx_counter)15765 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
15766 {
15767 struct recv_priv *precvpriv = &padapter->recvpriv;
15768 if (!rx_counter) {
15769 rtw_warn_on(1);
15770 return;
15771 }
15772 rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
15773 rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
15774 rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
15775 }
rtw_reset_drv_rx_counters(_adapter * padapter)15776 void rtw_reset_drv_rx_counters(_adapter *padapter)
15777 {
15778 struct recv_priv *precvpriv = &padapter->recvpriv;
15779 padapter->drv_rx_cnt_ok = 0;
15780 padapter->drv_rx_cnt_crcerror = 0;
15781 padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
15782 }
rtw_dump_phy_rxcnts_preprocess(_adapter * padapter,u8 rx_cnt_mode)15783 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
15784 {
15785 u8 initialgain;
15786 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15787
15788 if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
15789 rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
15790 RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
15791 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
15792 /*disable dynamic functions, such as high power, DIG*/
15793 rtw_phydm_ability_backup(padapter);
15794 rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
15795 } else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
15796 /* turn on phy-dynamic functions */
15797 rtw_phydm_ability_restore(padapter);
15798 initialgain = 0xff; /* restore RX GAIN */
15799 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
15800
15801 }
15802 }
15803
rtw_dump_rx_counters(_adapter * padapter)15804 void rtw_dump_rx_counters(_adapter *padapter)
15805 {
15806 struct dbg_rx_counter rx_counter;
15807
15808 if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
15809 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15810 rtw_dump_drv_rx_counters(padapter, &rx_counter);
15811 RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
15812 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
15813 rtw_reset_drv_rx_counters(padapter);
15814 }
15815
15816 if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
15817 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15818 rtw_dump_mac_rx_counters(padapter, &rx_counter);
15819 RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
15820 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
15821 rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
15822 rx_counter.rx_pkt_drop);
15823 rtw_reset_mac_rx_counters(padapter);
15824 }
15825
15826 if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
15827 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
15828 rtw_dump_phy_rx_counters(padapter, &rx_counter);
15829 /* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
15830 /* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
15831 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,
15832 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
15833 rtw_reset_phy_rx_counters(padapter);
15834 }
15835 }
15836 #endif
rtw_get_current_tx_sgi(_adapter * padapter,struct sta_info * psta)15837 u8 rtw_get_current_tx_sgi(_adapter *padapter, struct sta_info *psta)
15838 {
15839 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15840 u8 curr_tx_sgi = 0;
15841 struct ra_sta_info *ra_info;
15842
15843 if (!psta)
15844 return curr_tx_sgi;
15845
15846 if (padapter->fix_rate == 0xff) {
15847 #if defined(CONFIG_RTL8188E)
15848 #if (RATE_ADAPTIVE_SUPPORT == 1)
15849 curr_tx_sgi = hal_data->odmpriv.ra_info[psta->cmn.mac_id].rate_sgi;
15850 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
15851 #else
15852 ra_info = &psta->cmn.ra_info;
15853 curr_tx_sgi = ((ra_info->curr_tx_rate) & 0x80) >> 7;
15854 #endif
15855 } else {
15856 curr_tx_sgi = ((padapter->fix_rate) & 0x80) >> 7;
15857 }
15858
15859 return curr_tx_sgi;
15860 }
15861
rtw_get_current_tx_rate(_adapter * padapter,struct sta_info * psta)15862 u8 rtw_get_current_tx_rate(_adapter *padapter, struct sta_info *psta)
15863 {
15864 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
15865 u8 rate_id = 0;
15866 struct ra_sta_info *ra_info;
15867
15868 if (!psta)
15869 return rate_id;
15870
15871 if (padapter->fix_rate == 0xff) {
15872 #if defined(CONFIG_RTL8188E)
15873 #if (RATE_ADAPTIVE_SUPPORT == 1)
15874 rate_id = hal_data->odmpriv.ra_info[psta->cmn.mac_id].decision_rate;
15875 #endif /* (RATE_ADAPTIVE_SUPPORT == 1)*/
15876 #else
15877 ra_info = &psta->cmn.ra_info;
15878 rate_id = ra_info->curr_tx_rate & 0x7f;
15879 #endif
15880 } else {
15881 rate_id = padapter->fix_rate & 0x7f;
15882 }
15883
15884 return rate_id;
15885 }
15886
update_IOT_info(_adapter * padapter)15887 void update_IOT_info(_adapter *padapter)
15888 {
15889 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15890 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15891
15892 switch (pmlmeinfo->assoc_AP_vendor) {
15893 case HT_IOT_PEER_MARVELL:
15894 pmlmeinfo->turboMode_cts2self = 1;
15895 pmlmeinfo->turboMode_rtsen = 0;
15896 break;
15897
15898 case HT_IOT_PEER_RALINK:
15899 pmlmeinfo->turboMode_cts2self = 0;
15900 pmlmeinfo->turboMode_rtsen = 1;
15901 break;
15902 case HT_IOT_PEER_REALTEK:
15903 /* rtw_write16(padapter, 0x4cc, 0xffff); */
15904 /* rtw_write16(padapter, 0x546, 0x01c0); */
15905 break;
15906 default:
15907 pmlmeinfo->turboMode_cts2self = 0;
15908 pmlmeinfo->turboMode_rtsen = 1;
15909 break;
15910 }
15911
15912 }
15913 #ifdef CONFIG_RTS_FULL_BW
15914 /*
15915 8188E: not support full RTS BW feature(mac REG no define 480[5])
15916 */
rtw_set_rts_bw(_adapter * padapter)15917 void rtw_set_rts_bw(_adapter *padapter) {
15918 int i;
15919 u8 enable = 1;
15920 bool connect_to_8812 = _FALSE;
15921 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
15922 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
15923 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
15924 struct sta_info *station = NULL;
15925
15926 for (i = 0; i < macid_ctl->num; i++) {
15927 if (rtw_macid_is_used(macid_ctl, i)) {
15928
15929 station = NULL;
15930 station = macid_ctl->sta[i];
15931 if(station) {
15932
15933 _adapter *sta_adapter =station->padapter;
15934 struct mlme_ext_priv *pmlmeext = &(sta_adapter->mlmeextpriv);
15935 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15936
15937 if ( pmlmeinfo->state != WIFI_FW_NULL_STATE) {
15938 if(_rtw_memcmp(macid_ctl->sta[i]->cmn.mac_addr, bc_addr, ETH_ALEN) != _TRUE) {
15939 if ( macid_ctl->sta[i]->vendor_8812) {
15940 connect_to_8812 = _TRUE;
15941 enable = 0;
15942 }
15943 }
15944 }
15945 }
15946 }
15947
15948 if(connect_to_8812)
15949 break;
15950 }
15951
15952 RTW_INFO("%s connect_to_8812=%d,enable=%u\n", __FUNCTION__,connect_to_8812,enable);
15953 rtw_hal_set_hwreg(padapter, HW_VAR_SET_RTS_BW, &enable);
15954 }
15955 #endif/*CONFIG_RTS_FULL_BW*/
15956
hal_spec_init(_adapter * adapter)15957 int hal_spec_init(_adapter *adapter)
15958 {
15959 u8 interface_type = 0;
15960 int ret = _SUCCESS;
15961
15962 interface_type = rtw_get_intf_type(adapter);
15963
15964 switch (rtw_get_chip_type(adapter)) {
15965 #ifdef CONFIG_RTL8723B
15966 case RTL8723B:
15967 init_hal_spec_8723b(adapter);
15968 break;
15969 #endif
15970 #ifdef CONFIG_RTL8703B
15971 case RTL8703B:
15972 init_hal_spec_8703b(adapter);
15973 break;
15974 #endif
15975 #ifdef CONFIG_RTL8723D
15976 case RTL8723D:
15977 init_hal_spec_8723d(adapter);
15978 break;
15979 #endif
15980 #ifdef CONFIG_RTL8188E
15981 case RTL8188E:
15982 init_hal_spec_8188e(adapter);
15983 break;
15984 #endif
15985 #ifdef CONFIG_RTL8188F
15986 case RTL8188F:
15987 init_hal_spec_8188f(adapter);
15988 break;
15989 #endif
15990 #ifdef CONFIG_RTL8188GTV
15991 case RTL8188GTV:
15992 init_hal_spec_8188gtv(adapter);
15993 break;
15994 #endif
15995 #ifdef CONFIG_RTL8812A
15996 case RTL8812:
15997 init_hal_spec_8812a(adapter);
15998 break;
15999 #endif
16000 #ifdef CONFIG_RTL8821A
16001 case RTL8821:
16002 init_hal_spec_8821a(adapter);
16003 break;
16004 #endif
16005 #ifdef CONFIG_RTL8192E
16006 case RTL8192E:
16007 init_hal_spec_8192e(adapter);
16008 break;
16009 #endif
16010 #ifdef CONFIG_RTL8814A
16011 case RTL8814A:
16012 init_hal_spec_8814a(adapter);
16013 break;
16014 #endif
16015 #ifdef CONFIG_RTL8822B
16016 case RTL8822B:
16017 rtl8822b_init_hal_spec(adapter);
16018 break;
16019 #endif
16020 #ifdef CONFIG_RTL8821C
16021 case RTL8821C:
16022 init_hal_spec_rtl8821c(adapter);
16023 break;
16024 #endif
16025 #ifdef CONFIG_RTL8710B
16026 case RTL8710B:
16027 init_hal_spec_8710b(adapter);
16028 break;
16029 #endif
16030 #ifdef CONFIG_RTL8192F
16031 case RTL8192F:
16032 init_hal_spec_8192f(adapter);
16033 break;
16034 #endif
16035 #ifdef CONFIG_RTL8822C
16036 case RTL8822C:
16037 rtl8822c_init_hal_spec(adapter);
16038 break;
16039 #endif
16040 #ifdef CONFIG_RTL8814B
16041 case RTL8814B:
16042 rtl8814b_init_hal_spec(adapter);
16043 break;
16044 #endif
16045 #ifdef CONFIG_RTL8723F
16046 case RTL8723F:
16047 rtl8723f_init_hal_spec(adapter);
16048 break;
16049 #endif
16050 default:
16051 RTW_ERR("%s: unknown chip_type:%u\n"
16052 , __func__, rtw_get_chip_type(adapter));
16053 ret = _FAIL;
16054 break;
16055 }
16056
16057 return ret;
16058 }
16059
16060 static const char *const _band_cap_str[] = {
16061 /* BIT0 */"2G",
16062 /* BIT1 */"5G",
16063 };
16064
16065 static const char *const _bw_cap_str[] = {
16066 /* BIT0 */"5M",
16067 /* BIT1 */"10M",
16068 /* BIT2 */"20M",
16069 /* BIT3 */"40M",
16070 /* BIT4 */"80M",
16071 /* BIT5 */"160M",
16072 /* BIT6 */"80_80M",
16073 };
16074
16075 static const char *const _proto_cap_str[] = {
16076 /* BIT0 */"b",
16077 /* BIT1 */"g",
16078 /* BIT2 */"n",
16079 /* BIT3 */"ac",
16080 };
16081
16082 static const char *const _wl_func_str[] = {
16083 /* BIT0 */"P2P",
16084 /* BIT1 */"MIRACAST",
16085 /* BIT2 */"TDLS",
16086 /* BIT3 */"FTM",
16087 };
16088
dump_hal_spec(void * sel,_adapter * adapter)16089 void dump_hal_spec(void *sel, _adapter *adapter)
16090 {
16091 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16092 int i;
16093
16094 RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
16095 RTW_PRINT_SEL(sel, "macid_cap:%u\n", hal_spec->macid_cap);
16096 RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
16097 RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
16098
16099 RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
16100 RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
16101 RTW_PRINT_SEL(sel, "rf_reg_path_num:%u\n", hal_spec->rf_reg_path_num);
16102 RTW_PRINT_SEL(sel, "rf_reg_path_avail_num:%u\n", hal_spec->rf_reg_path_avail_num);
16103 RTW_PRINT_SEL(sel, "rf_reg_trx_path_bmp:0x%02x\n", hal_spec->rf_reg_trx_path_bmp);
16104 RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
16105
16106 RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
16107 RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
16108
16109 RTW_PRINT_SEL(sel, "band_cap:");
16110 for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
16111 if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
16112 _RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
16113 }
16114 _RTW_PRINT_SEL(sel, "\n");
16115
16116 RTW_PRINT_SEL(sel, "bw_cap:");
16117 for (i = 0; i < BW_CAP_BIT_NUM; i++) {
16118 if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
16119 _RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
16120 }
16121 _RTW_PRINT_SEL(sel, "\n");
16122
16123 RTW_PRINT_SEL(sel, "proto_cap:");
16124 for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
16125 if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
16126 _RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
16127 }
16128 _RTW_PRINT_SEL(sel, "\n");
16129
16130 RTW_PRINT_SEL(sel, "txgi_max:%u\n", hal_spec->txgi_max);
16131 RTW_PRINT_SEL(sel, "txgi_pdbm:%u\n", hal_spec->txgi_pdbm);
16132
16133 RTW_PRINT_SEL(sel, "wl_func:");
16134 for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
16135 if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
16136 _RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
16137 }
16138 _RTW_PRINT_SEL(sel, "\n");
16139
16140 #if CONFIG_TX_AC_LIFETIME
16141 RTW_PRINT_SEL(sel, "tx_aclt_unit_factor:%u (unit:%uus)\n"
16142 , hal_spec->tx_aclt_unit_factor, hal_spec->tx_aclt_unit_factor * 32);
16143 #endif
16144
16145 RTW_PRINT_SEL(sel, "rx_tsf_filter:%u\n", hal_spec->rx_tsf_filter);
16146
16147 RTW_PRINT_SEL(sel, "pg_txpwr_saddr:0x%X\n", hal_spec->pg_txpwr_saddr);
16148 RTW_PRINT_SEL(sel, "pg_txgi_diff_factor:%u\n", hal_spec->pg_txgi_diff_factor);
16149 }
16150
hal_chk_band_cap(_adapter * adapter,u8 cap)16151 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
16152 {
16153 return GET_HAL_SPEC(adapter)->band_cap & cap;
16154 }
16155
hal_chk_bw_cap(_adapter * adapter,u8 cap)16156 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
16157 {
16158 return GET_HAL_SPEC(adapter)->bw_cap & cap;
16159 }
16160
hal_chk_proto_cap(_adapter * adapter,u8 cap)16161 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
16162 {
16163 return GET_HAL_SPEC(adapter)->proto_cap & cap;
16164 }
16165
hal_chk_wl_func(_adapter * adapter,u8 func)16166 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
16167 {
16168 return GET_HAL_SPEC(adapter)->wl_func & func;
16169 }
16170
hal_is_band_support(_adapter * adapter,u8 band)16171 inline bool hal_is_band_support(_adapter *adapter, u8 band)
16172 {
16173 return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
16174 }
16175
hal_is_bw_support(_adapter * adapter,u8 bw)16176 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
16177 {
16178 return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
16179 }
16180
hal_is_wireless_mode_support(_adapter * adapter,u8 mode)16181 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
16182 {
16183 u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
16184
16185 if (mode == WIRELESS_11B)
16186 if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
16187 return 1;
16188
16189 if (mode == WIRELESS_11G)
16190 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
16191 return 1;
16192
16193 if (mode == WIRELESS_11A)
16194 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
16195 return 1;
16196
16197 if (mode == WIRELESS_11_24N)
16198 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
16199 return 1;
16200
16201 if (mode == WIRELESS_11_5N)
16202 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
16203 return 1;
16204
16205 if (mode == WIRELESS_11AC)
16206 if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
16207 return 1;
16208
16209 return 0;
16210 }
hal_is_mimo_support(_adapter * adapter)16211 inline bool hal_is_mimo_support(_adapter *adapter)
16212 {
16213 if ((GET_HAL_TX_NSS(adapter) == 1) &&
16214 (GET_HAL_RX_NSS(adapter) == 1))
16215 return 0;
16216 return 1;
16217 }
16218
16219 /*
16220 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
16221 * @adapter:
16222 * @in_bw: starting bw, value of enum channel_width
16223 *
16224 * Returns: value of enum channel_width
16225 */
hal_largest_bw(_adapter * adapter,u8 in_bw)16226 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
16227 {
16228 for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
16229 if (hal_is_bw_support(adapter, in_bw))
16230 break;
16231 }
16232
16233 if (!hal_is_bw_support(adapter, in_bw))
16234 rtw_warn_on(1);
16235
16236 return in_bw;
16237 }
16238
16239 #ifndef CONFIG_HAS_TX_BEACON_PAUSE
ResumeTxBeacon(_adapter * padapter)16240 void ResumeTxBeacon(_adapter *padapter)
16241 {
16242 RTW_DBG("ResumeTxBeacon\n");
16243 #ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE
16244 rtw_write8(padapter, REG_TXPAUSE,
16245 rtw_read8(padapter, REG_TXPAUSE) & (~BIT6));
16246 #else
16247 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
16248 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) | BIT(6));
16249 #endif
16250
16251 #ifdef RTW_HALMAC
16252 /* Add this for driver using HALMAC because driver doesn't have setup time init by self */
16253 /* TBTT setup time */
16254 rtw_write8(padapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);
16255 #endif
16256 /* TBTT hold time: 0x540[19:8] */
16257 #ifdef CONFIG_NARROWBAND_SUPPORTING
16258 if (padapter->registrypriv.rtw_nb_config == RTW_NB_CONFIG_WIDTH_10)
16259 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0xc8);
16260 else
16261 #endif
16262 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME & 0xFF);
16263 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
16264 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME >> 8));
16265 }
16266
StopTxBeacon(_adapter * padapter)16267 void StopTxBeacon(_adapter *padapter)
16268 {
16269 RTW_DBG("StopTxBeacon\n");
16270 #ifdef CONFIG_STOP_RESUME_BCN_BY_TXPAUSE
16271 rtw_write8(padapter, REG_TXPAUSE,
16272 rtw_read8(padapter, REG_TXPAUSE) | BIT6);
16273 #else
16274 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2,
16275 rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2) & (~BIT6));
16276 #endif
16277
16278 /* TBTT hold time: 0x540[19:8] */
16279 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);
16280 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2,
16281 (rtw_read8(padapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));
16282 }
16283 #endif /* CONFIG_HAS_TX_BEACON_PAUSE */
16284
16285 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
16286
16287 #ifdef CONFIG_CLIENT_PORT_CFG
16288 const u8 _clt_port_id[MAX_CLIENT_PORT_NUM] = {
16289 CLT_PORT0,
16290 CLT_PORT1,
16291 CLT_PORT2,
16292 CLT_PORT3
16293 };
16294
rtw_clt_port_init(struct clt_port_t * cltp)16295 void rtw_clt_port_init(struct clt_port_t *cltp)
16296 {
16297 cltp->bmp = 0;
16298 cltp->num = 0;
16299 _rtw_spinlock_init(&cltp->lock);
16300 }
rtw_clt_port_deinit(struct clt_port_t * cltp)16301 void rtw_clt_port_deinit(struct clt_port_t *cltp)
16302 {
16303 _rtw_spinlock_free(&cltp->lock);
16304 }
_hw_client_port_alloc(_adapter * adapter)16305 static void _hw_client_port_alloc(_adapter *adapter)
16306 {
16307 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
16308 struct clt_port_t *cltp = &dvobj->clt_port;
16309 _irqL irql;
16310 int i;
16311
16312 #if 0
16313 if (cltp->num > MAX_CLIENT_PORT_NUM) {
16314 RTW_ERR(ADPT_FMT" cann't alloc client (%d)\n", ADPT_ARG(adapter), cltp->num);
16315 rtw_warn_on(1);
16316 return;
16317 }
16318 #endif
16319
16320 if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
16321 RTW_INFO(ADPT_FMT" client_id %d has allocated port:%d\n",
16322 ADPT_ARG(adapter), adapter->client_id, adapter->client_port);
16323 return;
16324 }
16325 _enter_critical_bh(&cltp->lock, &irql);
16326 for (i = 0; i < MAX_CLIENT_PORT_NUM; i++) {
16327 if (!(cltp->bmp & BIT(i)))
16328 break;
16329 }
16330
16331 if (i < MAX_CLIENT_PORT_NUM) {
16332 adapter->client_id = i;
16333 cltp->bmp |= BIT(i);
16334 adapter->client_port = _clt_port_id[i];
16335 }
16336 cltp->num++;
16337 _exit_critical_bh(&cltp->lock, &irql);
16338 RTW_INFO("%s("ADPT_FMT")id:%d, port:%d clt_num:%d\n",
16339 __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
16340 }
_hw_client_port_free(_adapter * adapter)16341 static void _hw_client_port_free(_adapter *adapter)
16342 {
16343 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
16344 struct clt_port_t *cltp = &dvobj->clt_port;
16345 _irqL irql;
16346
16347 #if 0
16348 if (adapter->client_id >= MAX_CLIENT_PORT_NUM) {
16349 RTW_ERR(ADPT_FMT" client_id %d is invalid\n", ADPT_ARG(adapter), adapter->client_id);
16350 /*rtw_warn_on(1);*/
16351 }
16352 #endif
16353
16354 RTW_INFO("%s ("ADPT_FMT") id:%d, port:%d clt_num:%d\n",
16355 __func__, ADPT_ARG(adapter), adapter->client_id, adapter->client_port, cltp->num);
16356
16357 _enter_critical_bh(&cltp->lock, &irql);
16358 if (adapter->client_id != MAX_CLIENT_PORT_NUM) {
16359 cltp->bmp &= ~ BIT(adapter->client_id);
16360 adapter->client_id = MAX_CLIENT_PORT_NUM;
16361 adapter->client_port = CLT_PORT_INVALID;
16362 }
16363 cltp->num--;
16364 if (cltp->num < 0)
16365 cltp->num = 0;
16366 _exit_critical_bh(&cltp->lock, &irql);
16367 }
rtw_hw_client_port_allocate(_adapter * adapter)16368 void rtw_hw_client_port_allocate(_adapter *adapter)
16369 {
16370 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16371
16372 if (hal_spec->port_num != 5)
16373 return;
16374
16375 _hw_client_port_alloc(adapter);
16376 }
rtw_hw_client_port_release(_adapter * adapter)16377 void rtw_hw_client_port_release(_adapter *adapter)
16378 {
16379 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
16380
16381 if (hal_spec->port_num != 5)
16382 return;
16383
16384 _hw_client_port_free(adapter);
16385 }
16386 #endif /*CONFIG_CLIENT_PORT_CFG*/
16387
hw_var_set_opmode_mbid(_adapter * Adapter,u8 mode)16388 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
16389 {
16390 RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
16391
16392 rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);
16393
16394 /* set net_type */
16395 Set_MSR(Adapter, mode);
16396
16397 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
16398 if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))
16399 StopTxBeacon(Adapter);
16400 } else if (mode == _HW_STATE_ADHOC_)
16401 ResumeTxBeacon(Adapter);
16402 else if (mode == _HW_STATE_AP_)
16403 /* enable rx ps-poll */
16404 rtw_write16(Adapter, REG_RXFLTMAP1, rtw_read16(Adapter, REG_RXFLTMAP1) | BIT_CTRLFLT10EN);
16405
16406 /* enable rx data frame */
16407 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
16408
16409 #ifdef CONFIG_CLIENT_PORT_CFG
16410 if (mode == _HW_STATE_STATION_)
16411 rtw_hw_client_port_allocate(Adapter);
16412 else
16413 rtw_hw_client_port_release(Adapter);
16414 #endif
16415 #if defined(CONFIG_RTL8192F)
16416 rtw_write16(Adapter, REG_WLAN_ACT_MASK_CTRL_1, rtw_read16(Adapter,
16417 REG_WLAN_ACT_MASK_CTRL_1) | EN_PORT_0_FUNCTION);
16418 #endif
16419 }
16420 #endif
16421
16422 #ifdef CONFIG_ANTENNA_DIVERSITY
rtw_hal_antdiv_before_linked(_adapter * padapter)16423 u8 rtw_hal_antdiv_before_linked(_adapter *padapter)
16424 {
16425 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16426 u8 cur_ant, change_ant;
16427
16428 if (!pHalData->AntDivCfg)
16429 return _FALSE;
16430
16431 if (pHalData->sw_antdiv_bl_state == 0) {
16432 pHalData->sw_antdiv_bl_state = 1;
16433
16434 rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
16435 change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
16436
16437 return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
16438 }
16439
16440 pHalData->sw_antdiv_bl_state = 0;
16441 return _FALSE;
16442 }
16443
rtw_hal_antdiv_rssi_compared(_adapter * padapter,WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src)16444 void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
16445 {
16446 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16447
16448 if (pHalData->AntDivCfg) {
16449 /*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
16450 /*select optimum_antenna for before linked =>For antenna diversity*/
16451 if (dst->Rssi >= src->Rssi) {/*keep org parameter*/
16452 src->Rssi = dst->Rssi;
16453 src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
16454 }
16455 }
16456 }
16457 #endif
16458
16459 #ifdef CONFIG_PROC_DEBUG
16460 #ifdef CONFIG_PHY_CAPABILITY_QUERY
rtw_dump_phy_cap_by_phydmapi(void * sel,_adapter * adapter)16461 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
16462 {
16463 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
16464 struct phy_spec_t *phy_spec = &pHalData->phy_spec;
16465
16466 RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
16467 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
16468 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
16469 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index [15:8]*/
16470 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index [7:0]*/
16471
16472 RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
16473 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]*/
16474 /*VHT STBC Rx [23:16]
16475 0 = not support
16476 1 = support for 1 spatial stream
16477 2 = support for 1 or 2 spatial streams
16478 3 = support for 1 or 2 or 3 spatial streams
16479 4 = support for 1 or 2 or 3 or 4 spatial streams*/
16480 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
16481 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]*/
16482 /*HT STBC Rx [7:0]
16483 0 = not support
16484 1 = support for 1 spatial stream
16485 2 = support for 1 or 2 spatial streams
16486 3 = support for 1 or 2 or 3 spatial streams*/
16487 RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
16488
16489 RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
16490 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]*/
16491 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]*/
16492 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]*/
16493 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]*/
16494 #ifdef CONFIG_BEAMFORMING
16495 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
16496 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]*/
16497 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]*/
16498 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]*/
16499 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]*/
16500 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF) ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
16501 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
16502
16503 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
16504 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
16505 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
16506 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
16507 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
16508 #endif
16509 }
16510 #else
rtw_dump_phy_cap_by_hal(void * sel,_adapter * adapter)16511 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
16512 {
16513 u8 phy_cap = _FALSE;
16514
16515 /* STBC */
16516 rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
16517 RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16518
16519 phy_cap = _FALSE;
16520 rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
16521 RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16522
16523 /* LDPC support */
16524 phy_cap = _FALSE;
16525 rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
16526 RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16527
16528 phy_cap = _FALSE;
16529 rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
16530 RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16531
16532 #ifdef CONFIG_BEAMFORMING
16533 phy_cap = _FALSE;
16534 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
16535 RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16536
16537 phy_cap = _FALSE;
16538 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
16539 RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16540
16541 phy_cap = _FALSE;
16542 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
16543 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16544
16545 phy_cap = _FALSE;
16546 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
16547 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
16548 #endif
16549 }
16550 #endif
rtw_dump_phy_cap(void * sel,_adapter * adapter)16551 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
16552 {
16553 RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
16554 #ifdef CONFIG_PHY_CAPABILITY_QUERY
16555 rtw_dump_phy_cap_by_phydmapi(sel, adapter);
16556 #else
16557 rtw_dump_phy_cap_by_hal(sel, adapter);
16558 #endif
16559 }
16560 #endif
16561
translate_dbm_to_percentage(s16 signal)16562 inline s16 translate_dbm_to_percentage(s16 signal)
16563 {
16564 if ((signal <= -100) || (signal >= 20))
16565 return 0;
16566 else if (signal >= 0)
16567 return 100;
16568 else
16569 return 100 + signal;
16570 }
16571
16572 #ifdef CONFIG_SWTIMER_BASED_TXBCN
16573 #ifdef CONFIG_BCN_RECOVERY
16574 #define REG_CPU_MGQ_INFO 0x041C
16575 #define BIT_BCN_POLL BIT(28)
rtw_ap_bcn_recovery(_adapter * padapter)16576 u8 rtw_ap_bcn_recovery(_adapter *padapter)
16577 {
16578 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
16579
16580 if (hal_data->issue_bcn_fail >= 2) {
16581 RTW_ERR("%s ISSUE BCN Fail\n", __func__);
16582 rtw_write8(padapter, REG_CPU_MGQ_INFO + 3, 0x10);
16583 hal_data->issue_bcn_fail = 0;
16584 }
16585 return _SUCCESS;
16586 }
16587 #endif /*CONFIG_BCN_RECOVERY*/
16588
16589 #ifdef CONFIG_BCN_XMIT_PROTECT
rtw_ap_bcn_queue_empty_check(_adapter * padapter,u32 txbcn_timer_ms)16590 u8 rtw_ap_bcn_queue_empty_check(_adapter *padapter, u32 txbcn_timer_ms)
16591 {
16592 u32 start_time = rtw_get_current_time();
16593 u8 bcn_queue_empty = _FALSE;
16594
16595 do {
16596 if (rtw_read16(padapter, REG_TXPKT_EMPTY) & BIT(11)) {
16597 bcn_queue_empty = _TRUE;
16598 break;
16599 }
16600 } while (rtw_get_passing_time_ms(start_time) <= (txbcn_timer_ms + 10));
16601
16602 if (bcn_queue_empty == _FALSE)
16603 RTW_ERR("%s BCN queue not empty\n", __func__);
16604
16605 return bcn_queue_empty;
16606 }
16607 #endif /*CONFIG_BCN_XMIT_PROTECT*/
16608 #endif /*CONFIG_SWTIMER_BASED_TXBCN*/
16609
16610 /**
16611 * rtw_hal_get_trx_path() - Get RF path related information
16612 * @d: struct dvobj_priv*
16613 * @type: RF type, nTnR
16614 * @tx: Tx path
16615 * @rx: Rx path
16616 *
16617 * Get RF type, TX path and RX path information.
16618 */
rtw_hal_get_trx_path(struct dvobj_priv * d,enum rf_type * type,enum bb_path * tx,enum bb_path * rx)16619 void rtw_hal_get_trx_path(struct dvobj_priv *d, enum rf_type *type,
16620 enum bb_path *tx, enum bb_path *rx)
16621 {
16622 struct _ADAPTER *a = dvobj_get_primary_adapter(d);
16623 enum rf_type t = GET_HAL_RFPATH(a);
16624
16625 if (type)
16626 *type = t;
16627
16628 if (tx || rx) {
16629 u8 tx_bmp = GET_HAL_TX_PATH_BMP(a);
16630 u8 rx_bmp = GET_HAL_RX_PATH_BMP(a);
16631
16632 if (!tx_bmp && !rx_bmp)
16633 rf_type_to_default_trx_bmp(t, tx, rx);
16634 else {
16635 if (tx)
16636 *tx = GET_HAL_TX_PATH_BMP(a);
16637 if (rx)
16638 *rx = GET_HAL_RX_PATH_BMP(a);
16639 }
16640 }
16641 }
16642
16643 #ifdef RTW_CHANNEL_SWITCH_OFFLOAD
rtw_hal_switch_chnl_and_set_bw_offload(_adapter * adapter,u8 central_ch,u8 pri_ch_idx,u8 bw)16644 void rtw_hal_switch_chnl_and_set_bw_offload(_adapter *adapter, u8 central_ch, u8 pri_ch_idx, u8 bw)
16645 {
16646 u8 h2c[H2C_SINGLE_CHANNELSWITCH_V2_LEN] = {0};
16647 PHAL_DATA_TYPE hal;
16648 struct submit_ctx *chsw_sctx;
16649
16650 hal = GET_HAL_DATA(adapter);
16651 chsw_sctx = &hal->chsw_sctx;
16652
16653 SET_H2CCMD_SINGLE_CH_SWITCH_V2_CENTRAL_CH_NUM(h2c, central_ch);
16654 SET_H2CCMD_SINGLE_CH_SWITCH_V2_PRIMARY_CH_IDX(h2c, pri_ch_idx);
16655 SET_H2CCMD_SINGLE_CH_SWITCH_V2_BW(h2c, bw);
16656 SET_H2CCMD_SINGLE_CH_SWITCH_V2_IQK_UPDATE_EN(h2c, 1);
16657
16658 rtw_sctx_init(chsw_sctx, 10);
16659 rtw_hal_fill_h2c_cmd(adapter, H2C_SINGLE_CHANNELSWITCH_V2, H2C_SINGLE_CHANNELSWITCH_V2_LEN, h2c);
16660 rtw_sctx_wait(chsw_sctx, __func__);
16661 }
16662 #endif /* RTW_CHANNEL_SWITCH_OFFLOAD */
16663
phy_get_capable_tx_num(_adapter * adapter,enum MGN_RATE rate)16664 u8 phy_get_capable_tx_num(_adapter *adapter, enum MGN_RATE rate)
16665 {
16666 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16667 u8 tx_num = 0;
16668
16669 if (IS_1T_RATE(rate))
16670 tx_num = hal_data->txpath_cap_num_nss[0];
16671 else if (IS_2T_RATE(rate))
16672 tx_num = hal_data->txpath_cap_num_nss[1];
16673 else if (IS_3T_RATE(rate))
16674 tx_num = hal_data->txpath_cap_num_nss[2];
16675 else if (IS_4T_RATE(rate))
16676 tx_num = hal_data->txpath_cap_num_nss[3];
16677 else
16678 rtw_warn_on(1);
16679
16680 return tx_num == 0 ? RF_1TX : tx_num - 1;
16681 }
16682
phy_get_current_tx_num(_adapter * adapter,enum MGN_RATE rate)16683 u8 phy_get_current_tx_num(_adapter *adapter, enum MGN_RATE rate)
16684 {
16685 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16686 u8 tx_num = 0;
16687
16688 if (IS_1T_RATE(rate))
16689 tx_num = hal_data->txpath_num_nss[0];
16690 else if (IS_2T_RATE(rate))
16691 tx_num = hal_data->txpath_num_nss[1];
16692 else if (IS_3T_RATE(rate))
16693 tx_num = hal_data->txpath_num_nss[2];
16694 else if (IS_4T_RATE(rate))
16695 tx_num = hal_data->txpath_num_nss[3];
16696 else
16697 rtw_warn_on(1);
16698
16699 return tx_num == 0 ? RF_1TX : tx_num - 1;
16700 }
16701
16702 #ifdef CONFIG_RTL8812A
rtw_hal_set_8812a_vendor_ie(_adapter * padapter,u8 * pframe,uint * frlen)16703 u8 * rtw_hal_set_8812a_vendor_ie(_adapter *padapter , u8 *pframe ,uint *frlen ) {
16704 int vender_len = 7;
16705 unsigned char vendor_info[vender_len];
16706 unsigned char REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
16707 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16708
16709 if( !IS_HARDWARE_TYPE_8812(padapter) )
16710 return pframe;
16711
16712 _rtw_memset(vendor_info,0,vender_len);
16713 _rtw_memcpy(vendor_info, REALTEK_OUI, 3);
16714 vendor_info[4] =2;
16715 if(pHalData->version_id.CUTVersion > B_CUT_VERSION )
16716 vendor_info[6] = RT_HT_CAP_USE_JAGUAR_CCUT;
16717 else
16718 vendor_info[6] = RT_HT_CAP_USE_JAGUAR_BCUT;
16719 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,vender_len,vendor_info , frlen);
16720
16721 return pframe;
16722 }
16723 #endif /*CONFIG_RTL8812A*/
16724
rtw_enter_protsel(struct protsel * protsel,u32 sel)16725 static inline void rtw_enter_protsel(struct protsel *protsel, u32 sel)
16726 {
16727 int refcnt;
16728
16729 _enter_critical_mutex(&protsel->mutex, NULL);
16730
16731 refcnt = ATOMIC_INC_RETURN(&protsel->refcnt);
16732
16733 WARN_ON(refcnt > 1 && protsel->sel != sel);
16734
16735 protsel->sel = sel;
16736
16737 _exit_critical_mutex(&protsel->mutex, NULL);
16738 }
16739
rtw_leave_protsel(struct protsel * protsel)16740 static inline void rtw_leave_protsel(struct protsel *protsel)
16741 {
16742 int refcnt;
16743
16744 _enter_critical_mutex(&protsel->mutex, NULL);
16745
16746 refcnt = ATOMIC_DEC_RETURN(&protsel->refcnt);
16747
16748 _exit_critical_mutex(&protsel->mutex, NULL);
16749
16750 WARN_ON(refcnt < 0);
16751 }
16752
rtw_assert_protsel(struct protsel * protsel)16753 static inline bool rtw_assert_protsel(struct protsel *protsel)
16754 {
16755 int refcnt = ATOMIC_READ(&protsel->refcnt);
16756
16757 if (refcnt > 0)
16758 return true;
16759
16760 return false;
16761 }
16762
16763 #ifdef CONFIG_PROTSEL_PORT
rtw_enter_protsel_port(_adapter * padapter,u8 port_sel)16764 void rtw_enter_protsel_port(_adapter *padapter, u8 port_sel)
16765 {
16766 u8 val8;
16767
16768 rtw_enter_protsel(&padapter->dvobj->protsel_port, port_sel);
16769
16770 val8 = rtw_read8(padapter, REG_PORT_CTRL_SEL);
16771 val8 &= ~BIT_MASK_PORT_CTRL_SEL;
16772 val8 |= BIT_PORT_CTRL_SEL(port_sel);
16773 rtw_write8(padapter, REG_PORT_CTRL_SEL, val8);
16774 }
16775
rtw_assert_protsel_port(_adapter * padapter,u32 addr,u8 len)16776 bool rtw_assert_protsel_port(_adapter *padapter, u32 addr, u8 len)
16777 {
16778 if (!padapter->bup) /* don't assert before IF up */
16779 return true;
16780
16781 return rtw_assert_protsel(&padapter->dvobj->protsel_port);
16782 }
16783
rtw_leave_protsel_port(_adapter * padapter)16784 void rtw_leave_protsel_port(_adapter *padapter)
16785 {
16786 rtw_leave_protsel(&padapter->dvobj->protsel_port);
16787 }
16788 #endif
16789
16790 #ifdef CONFIG_PROTSEL_ATIMDTIM
rtw_enter_protsel_atimdtim(_adapter * padapter,u8 port_sel)16791 void rtw_enter_protsel_atimdtim(_adapter *padapter, u8 port_sel)
16792 {
16793 /* 0~15 is for port 0 MBSSID setting
16794 * 16 is for port 1 setting
16795 * 17 is for port 2 setting
16796 * 18 is for port 3 setting
16797 * 19 is for port 4 setting
16798 */
16799 u8 val8;
16800
16801 if (port_sel >= 1 && port_sel <= 4)
16802 port_sel += 15;
16803
16804 rtw_enter_protsel(&padapter->dvobj->protsel_atimdtim, port_sel);
16805
16806 val8 = rtw_read8(padapter, REG_ATIM_DTIM_CTRL_SEL);
16807 val8 &= ~BIT_MASK_ATIM_DTIM_SEL;
16808 val8 |= BIT_ATIM_DTIM_SEL(port_sel);
16809 rtw_write8(padapter, REG_ATIM_DTIM_CTRL_SEL, val8);
16810 }
16811
rtw_assert_protsel_atimdtim(_adapter * padapter,u32 addr,u8 len)16812 bool rtw_assert_protsel_atimdtim(_adapter *padapter, u32 addr, u8 len)
16813 {
16814 return rtw_assert_protsel(&padapter->dvobj->protsel_atimdtim);
16815 }
16816
rtw_leave_protsel_atimdtim(_adapter * padapter)16817 void rtw_leave_protsel_atimdtim(_adapter *padapter)
16818 {
16819 rtw_leave_protsel(&padapter->dvobj->protsel_atimdtim);
16820 }
16821 #endif
16822
16823 #ifdef CONFIG_PROTSEL_MACSLEEP
rtw_enter_protsel_macsleep(_adapter * padapter,u8 sel)16824 void rtw_enter_protsel_macsleep(_adapter *padapter, u8 sel)
16825 {
16826 u32 val32;
16827
16828 rtw_enter_protsel(&padapter->dvobj->protsel_macsleep, sel);
16829
16830 val32 = rtw_read32(padapter, REG_MACID_SLEEP_CTRL);
16831 val32 &= ~BIT_MASK_MACID_SLEEP_SEL;
16832 val32 |= BIT_MACID_SLEEP_SEL(sel);
16833 rtw_write32(padapter, REG_MACID_SLEEP_CTRL, val32);
16834 }
16835
rtw_assert_protsel_macsleep(_adapter * padapter,u32 addr,u8 len)16836 bool rtw_assert_protsel_macsleep(_adapter *padapter, u32 addr, u8 len)
16837 {
16838 return rtw_assert_protsel(&padapter->dvobj->protsel_macsleep);
16839 }
16840
rtw_leave_protsel_macsleep(_adapter * padapter)16841 void rtw_leave_protsel_macsleep(_adapter *padapter)
16842 {
16843 rtw_leave_protsel(&padapter->dvobj->protsel_macsleep);
16844 }
16845 #endif
16846
rtw_hal_bcn_early_rpt_c2h_handler(_adapter * padapter)16847 void rtw_hal_bcn_early_rpt_c2h_handler(_adapter *padapter)
16848 {
16849 if(0)
16850 RTW_INFO("Recv Bcn Early report!!\n");
16851
16852 #ifdef CONFIG_AP_MODE
16853 rtw_mi_update_csa(padapter);
16854 #endif
16855
16856 #ifdef CONFIG_TDLS
16857 #ifdef CONFIG_TDLS_CH_SW
16858 if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
16859 rtw_tdls_ch_sw_back_to_base_chnl(padapter);
16860 #endif
16861 #endif
16862 }
16863
16864 #ifndef RTW_HALMAC
rtw_hal_init_sifs_backup(_adapter * adapter)16865 void rtw_hal_init_sifs_backup(_adapter *adapter)
16866 {
16867 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
16868
16869 hal_data->init_reg_0x428 = rtw_read16(adapter, 0x428);
16870 hal_data->init_reg_0x514 = rtw_read32(adapter, 0x514);
16871 hal_data->init_reg_0x63a = rtw_read16(adapter, 0x63a);
16872 hal_data->init_reg_0x63c = rtw_read32(adapter, 0x63c);
16873
16874 #ifndef RTW_SIFS_INIT_CHK
16875 #define RTW_SIFS_INIT_CHK 1
16876 #endif
16877
16878 #if RTW_SIFS_INIT_CHK
16879 /*
16880 the expected initial values:
16881 0x428[15:0]=0x100A
16882 0x514[31:0]=0x0E0A0E0A
16883 0x63A[15:0]=0x100A
16884 0x63C[31:0]=0x0E0E0A0A
16885 */
16886 #define INIT_REG_0x428 0x100A
16887 #define INIT_REG_0x514 0x0E0A0E0A
16888 #define INIT_REG_0x63A 0x100A
16889 #define INIT_REG_0x63C 0x0E0E0A0A
16890
16891 if (hal_data->init_reg_0x428 != INIT_REG_0x428) {
16892 RTW_WARN("init_reg_0x428:0x%04x != 0x%04x\n", hal_data->init_reg_0x428, INIT_REG_0x428);
16893 #if RTW_SIFS_INIT_CHK > 1
16894 hal_data->init_reg_0x428 = INIT_REG_0x428;
16895 rtw_write16(adapter, 0x428, hal_data->init_reg_0x428);
16896 #endif
16897 }
16898 if (hal_data->init_reg_0x514 != INIT_REG_0x514) {
16899 RTW_WARN("init_reg_0x514:0x%08x != 0x%08x\n", hal_data->init_reg_0x514, INIT_REG_0x514);
16900 #if RTW_SIFS_INIT_CHK > 1
16901 hal_data->init_reg_0x514 = INIT_REG_0x514;
16902 rtw_write32(adapter, 0x514, hal_data->init_reg_0x514);
16903 #endif
16904 }
16905 if (hal_data->init_reg_0x63a != INIT_REG_0x63A) {
16906 RTW_WARN("init_reg_0x63a:0x%04x != 0x%04x\n", hal_data->init_reg_0x63a, INIT_REG_0x63A);
16907 #if RTW_SIFS_INIT_CHK > 1
16908 hal_data->init_reg_0x63a = INIT_REG_0x63A;
16909 rtw_write16(adapter, 0x63a, hal_data->init_reg_0x63a);
16910 #endif
16911 }
16912 if (hal_data->init_reg_0x63c != INIT_REG_0x63C) {
16913 RTW_WARN("init_reg_0x63c:0x%08x != 0x%08x\n", hal_data->init_reg_0x63c, INIT_REG_0x63C);
16914 #if RTW_SIFS_INIT_CHK > 1
16915 hal_data->init_reg_0x63c = INIT_REG_0x63C;
16916 rtw_write32(adapter, 0x63c, hal_data->init_reg_0x63c);
16917 #endif
16918 }
16919 #endif
16920 }
16921 #endif
16922