1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
22 #include <drv_types.h>
23 #include "hal_com_h2c.h"
28 #include "../../hal/hal_halmac.h"
31 void rtw_dump_fw_info(void *sel, _adapter *adapter)
33 HAL_DATA_TYPE *hal_data = NULL;
38 hal_data = GET_HAL_DATA(adapter);
39 if (adapter->bFWReady)
40 RTW_PRINT_SEL(sel, "FW VER -%d.%d\n", hal_data->firmware_version, hal_data->firmware_sub_version);
42 RTW_PRINT_SEL(sel, "FW not ready\n");
45 /* #define CONFIG_GTK_OL_DBG */
47 /*#define DBG_SEC_CAM_MOVE*/
48 #ifdef DBG_SEC_CAM_MOVE
49 void rtw_hal_move_sta_gk_to_dk(_adapter *adapter)
51 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
52 int cam_id, index = 0;
55 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
58 addr = get_bssid(pmlmepriv);
61 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
65 rtw_clean_dk_section(adapter);
68 cam_id = rtw_camid_search(adapter, addr, index, 1);
71 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
73 rtw_sec_cam_swap(adapter, cam_id, index);
80 void rtw_hal_read_sta_dk_key(_adapter *adapter, u8 key_id)
82 struct security_priv *psecuritypriv = &adapter->securitypriv;
83 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
84 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
88 _rtw_memset(get_key, 0, sizeof(get_key));
91 RTW_INFO("%s [ERROR] gtk_keyindex:%d invalid\n", __func__, key_id);
95 rtw_sec_read_cam_ent(adapter, key_id, NULL, NULL, get_key);
97 /*update key into related sw variable*/
98 _enter_critical_bh(&cam_ctl->lock, &irqL);
99 if (_rtw_camid_is_gk(adapter, key_id)) {
100 RTW_INFO("[HW KEY] -Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(get_key));
101 RTW_INFO("[cam_cache KEY] - Key-id:%d "KEY_FMT"\n", key_id, KEY_ARG(&dvobj->cam_cache[key_id].key));
103 _exit_critical_bh(&cam_ctl->lock, &irqL);
109 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
110 char rtw_phy_para_file_path[PATH_LENGTH_MAX];
113 void dump_chip_info(HAL_VERSION ChipVersion)
118 if (IS_8188E(ChipVersion))
119 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188E_");
120 else if (IS_8188F(ChipVersion))
121 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8188F_");
122 else if (IS_8812_SERIES(ChipVersion))
123 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8812_");
124 else if (IS_8192E(ChipVersion))
125 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8192E_");
126 else if (IS_8821_SERIES(ChipVersion))
127 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821_");
128 else if (IS_8723B_SERIES(ChipVersion))
129 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723B_");
130 else if (IS_8703B_SERIES(ChipVersion))
131 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8703B_");
132 else if (IS_8723D_SERIES(ChipVersion))
133 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723D_");
134 else if (IS_8814A_SERIES(ChipVersion))
135 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8814A_");
136 else if (IS_8822B_SERIES(ChipVersion))
137 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8822B_");
138 else if (IS_8821C_SERIES(ChipVersion))
139 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8821C_");
141 cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_UNKNOWN_");
143 cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(ChipVersion) ? "Normal_Chip" : "Test_Chip");
144 if (IS_CHIP_VENDOR_TSMC(ChipVersion))
145 cnt += sprintf((buf + cnt), "%s_", "TSMC");
146 else if (IS_CHIP_VENDOR_UMC(ChipVersion))
147 cnt += sprintf((buf + cnt), "%s_", "UMC");
148 else if (IS_CHIP_VENDOR_SMIC(ChipVersion))
149 cnt += sprintf((buf + cnt), "%s_", "SMIC");
151 if (IS_A_CUT(ChipVersion))
152 cnt += sprintf((buf + cnt), "A_CUT_");
153 else if (IS_B_CUT(ChipVersion))
154 cnt += sprintf((buf + cnt), "B_CUT_");
155 else if (IS_C_CUT(ChipVersion))
156 cnt += sprintf((buf + cnt), "C_CUT_");
157 else if (IS_D_CUT(ChipVersion))
158 cnt += sprintf((buf + cnt), "D_CUT_");
159 else if (IS_E_CUT(ChipVersion))
160 cnt += sprintf((buf + cnt), "E_CUT_");
161 else if (IS_F_CUT(ChipVersion))
162 cnt += sprintf((buf + cnt), "F_CUT_");
163 else if (IS_I_CUT(ChipVersion))
164 cnt += sprintf((buf + cnt), "I_CUT_");
165 else if (IS_J_CUT(ChipVersion))
166 cnt += sprintf((buf + cnt), "J_CUT_");
167 else if (IS_K_CUT(ChipVersion))
168 cnt += sprintf((buf + cnt), "K_CUT_");
170 cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_", ChipVersion.CUTVersion);
172 if (IS_1T1R(ChipVersion))
173 cnt += sprintf((buf + cnt), "1T1R_");
174 else if (IS_1T2R(ChipVersion))
175 cnt += sprintf((buf + cnt), "1T2R_");
176 else if (IS_2T2R(ChipVersion))
177 cnt += sprintf((buf + cnt), "2T2R_");
178 else if (IS_3T3R(ChipVersion))
179 cnt += sprintf((buf + cnt), "3T3R_");
180 else if (IS_3T4R(ChipVersion))
181 cnt += sprintf((buf + cnt), "3T4R_");
182 else if (IS_4T4R(ChipVersion))
183 cnt += sprintf((buf + cnt), "4T4R_");
185 cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", ChipVersion.RFType);
187 cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer);
191 void rtw_hal_config_rftype(PADAPTER padapter)
193 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
195 if (IS_1T1R(pHalData->version_id)) {
196 pHalData->rf_type = RF_1T1R;
197 pHalData->NumTotalRFPath = 1;
198 } else if (IS_2T2R(pHalData->version_id)) {
199 pHalData->rf_type = RF_2T2R;
200 pHalData->NumTotalRFPath = 2;
201 } else if (IS_1T2R(pHalData->version_id)) {
202 pHalData->rf_type = RF_1T2R;
203 pHalData->NumTotalRFPath = 2;
204 } else if (IS_3T3R(pHalData->version_id)) {
205 pHalData->rf_type = RF_3T3R;
206 pHalData->NumTotalRFPath = 3;
207 } else if (IS_4T4R(pHalData->version_id)) {
208 pHalData->rf_type = RF_4T4R;
209 pHalData->NumTotalRFPath = 4;
211 pHalData->rf_type = RF_1T1R;
212 pHalData->NumTotalRFPath = 1;
215 RTW_INFO("%s RF_Type is %d TotalTxPath is %d\n", __FUNCTION__, pHalData->rf_type, pHalData->NumTotalRFPath);
218 #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
222 * Use hardware(efuse), driver parameter(registry) and default channel plan
223 * to decide which one should be used.
226 * padapter pointer of adapter
227 * hw_alpha2 country code from HW (efuse/eeprom/mapfile)
228 * hw_chplan channel plan from HW (efuse/eeprom/mapfile)
229 * BIT[7] software configure mode; 0:Enable, 1:disable
230 * BIT[6:0] Channel Plan
231 * sw_alpha2 country code from HW (registry/module param)
232 * sw_chplan channel plan from SW (registry/module param)
233 * def_chplan channel plan used when HW/SW both invalid
234 * AutoLoadFail efuse autoload fail or not
237 * Final channel plan decision
240 u8 hal_com_config_channel_plan(
241 IN PADAPTER padapter,
247 IN BOOLEAN AutoLoadFail
250 PHAL_DATA_TYPE pHalData;
251 u8 force_hw_chplan = _FALSE;
253 const struct country_chplan *country_ent = NULL, *ent;
255 pHalData = GET_HAL_DATA(padapter);
257 /* treat 0xFF as invalid value, bypass hw_chplan & force_hw_chplan parsing */
258 if (hw_chplan == 0xFF)
259 goto chk_hw_country_code;
261 if (AutoLoadFail == _TRUE)
264 #ifndef CONFIG_FORCE_SW_CHANNEL_PLAN
265 if (hw_chplan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
266 force_hw_chplan = _TRUE;
269 hw_chplan &= (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
272 if (hw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(hw_alpha2)) {
273 ent = rtw_get_chplan_from_country(hw_alpha2);
275 /* get chplan from hw country code, by pass hw chplan setting */
277 chplan = ent->chplan;
280 RTW_PRINT("%s unsupported hw_alpha2:\"%c%c\"\n", __func__, hw_alpha2[0], hw_alpha2[1]);
283 if (rtw_is_channel_plan_valid(hw_chplan))
285 else if (force_hw_chplan == _TRUE) {
286 RTW_PRINT("%s unsupported hw_chplan:0x%02X\n", __func__, hw_chplan);
287 /* hw infomaton invalid, refer to sw information */
288 force_hw_chplan = _FALSE;
292 if (force_hw_chplan == _TRUE)
295 if (sw_alpha2 && !IS_ALPHA2_NO_SPECIFIED(sw_alpha2)) {
296 ent = rtw_get_chplan_from_country(sw_alpha2);
298 /* get chplan from sw country code, by pass sw chplan setting */
300 chplan = ent->chplan;
303 RTW_PRINT("%s unsupported sw_alpha2:\"%c%c\"\n", __func__, sw_alpha2[0], sw_alpha2[1]);
306 if (rtw_is_channel_plan_valid(sw_chplan)) {
307 /* cancel hw_alpha2 because chplan is specified by sw_chplan*/
310 } else if (sw_chplan != RTW_CHPLAN_MAX)
311 RTW_PRINT("%s unsupported sw_chplan:0x%02X\n", __func__, sw_chplan);
315 RTW_PRINT("%s use def_chplan:0x%02X\n", __func__, def_chplan);
317 } else if (country_ent) {
318 RTW_PRINT("%s country code:\"%c%c\" with chplan:0x%02X\n", __func__
319 , country_ent->alpha2[0], country_ent->alpha2[1], country_ent->chplan);
321 RTW_PRINT("%s chplan:0x%02X\n", __func__, chplan);
323 padapter->mlmepriv.country_ent = country_ent;
324 pHalData->bDisableSWChannelPlan = force_hw_chplan;
335 BOOLEAN bLegalChannel = _TRUE;
338 if (is_supported_5g(Adapter->registrypriv.wireless_mode) == _FALSE) {
339 bLegalChannel = _FALSE;
340 RTW_INFO("Channel > 14 but wireless_mode do not support 5G\n");
342 } else if ((Channel <= 14) && (Channel >= 1)) {
343 if (IsSupported24G(Adapter->registrypriv.wireless_mode) == _FALSE) {
344 bLegalChannel = _FALSE;
345 RTW_INFO("(Channel <= 14) && (Channel >=1) but wireless_mode do not support 2.4G\n");
348 bLegalChannel = _FALSE;
349 RTW_INFO("Channel is Invalid !!!\n");
352 return bLegalChannel;
355 u8 MRateToHwRate(u8 rate)
357 u8 ret = DESC_RATE1M;
428 ret = DESC_RATEMCS10;
431 ret = DESC_RATEMCS11;
434 ret = DESC_RATEMCS12;
437 ret = DESC_RATEMCS13;
440 ret = DESC_RATEMCS14;
443 ret = DESC_RATEMCS15;
446 ret = DESC_RATEMCS16;
449 ret = DESC_RATEMCS17;
452 ret = DESC_RATEMCS18;
455 ret = DESC_RATEMCS19;
458 ret = DESC_RATEMCS20;
461 ret = DESC_RATEMCS21;
464 ret = DESC_RATEMCS22;
467 ret = DESC_RATEMCS23;
470 ret = DESC_RATEMCS24;
473 ret = DESC_RATEMCS25;
476 ret = DESC_RATEMCS26;
479 ret = DESC_RATEMCS27;
482 ret = DESC_RATEMCS28;
485 ret = DESC_RATEMCS29;
488 ret = DESC_RATEMCS30;
491 ret = DESC_RATEMCS31;
494 case MGN_VHT1SS_MCS0:
495 ret = DESC_RATEVHTSS1MCS0;
497 case MGN_VHT1SS_MCS1:
498 ret = DESC_RATEVHTSS1MCS1;
500 case MGN_VHT1SS_MCS2:
501 ret = DESC_RATEVHTSS1MCS2;
503 case MGN_VHT1SS_MCS3:
504 ret = DESC_RATEVHTSS1MCS3;
506 case MGN_VHT1SS_MCS4:
507 ret = DESC_RATEVHTSS1MCS4;
509 case MGN_VHT1SS_MCS5:
510 ret = DESC_RATEVHTSS1MCS5;
512 case MGN_VHT1SS_MCS6:
513 ret = DESC_RATEVHTSS1MCS6;
515 case MGN_VHT1SS_MCS7:
516 ret = DESC_RATEVHTSS1MCS7;
518 case MGN_VHT1SS_MCS8:
519 ret = DESC_RATEVHTSS1MCS8;
521 case MGN_VHT1SS_MCS9:
522 ret = DESC_RATEVHTSS1MCS9;
524 case MGN_VHT2SS_MCS0:
525 ret = DESC_RATEVHTSS2MCS0;
527 case MGN_VHT2SS_MCS1:
528 ret = DESC_RATEVHTSS2MCS1;
530 case MGN_VHT2SS_MCS2:
531 ret = DESC_RATEVHTSS2MCS2;
533 case MGN_VHT2SS_MCS3:
534 ret = DESC_RATEVHTSS2MCS3;
536 case MGN_VHT2SS_MCS4:
537 ret = DESC_RATEVHTSS2MCS4;
539 case MGN_VHT2SS_MCS5:
540 ret = DESC_RATEVHTSS2MCS5;
542 case MGN_VHT2SS_MCS6:
543 ret = DESC_RATEVHTSS2MCS6;
545 case MGN_VHT2SS_MCS7:
546 ret = DESC_RATEVHTSS2MCS7;
548 case MGN_VHT2SS_MCS8:
549 ret = DESC_RATEVHTSS2MCS8;
551 case MGN_VHT2SS_MCS9:
552 ret = DESC_RATEVHTSS2MCS9;
554 case MGN_VHT3SS_MCS0:
555 ret = DESC_RATEVHTSS3MCS0;
557 case MGN_VHT3SS_MCS1:
558 ret = DESC_RATEVHTSS3MCS1;
560 case MGN_VHT3SS_MCS2:
561 ret = DESC_RATEVHTSS3MCS2;
563 case MGN_VHT3SS_MCS3:
564 ret = DESC_RATEVHTSS3MCS3;
566 case MGN_VHT3SS_MCS4:
567 ret = DESC_RATEVHTSS3MCS4;
569 case MGN_VHT3SS_MCS5:
570 ret = DESC_RATEVHTSS3MCS5;
572 case MGN_VHT3SS_MCS6:
573 ret = DESC_RATEVHTSS3MCS6;
575 case MGN_VHT3SS_MCS7:
576 ret = DESC_RATEVHTSS3MCS7;
578 case MGN_VHT3SS_MCS8:
579 ret = DESC_RATEVHTSS3MCS8;
581 case MGN_VHT3SS_MCS9:
582 ret = DESC_RATEVHTSS3MCS9;
584 case MGN_VHT4SS_MCS0:
585 ret = DESC_RATEVHTSS4MCS0;
587 case MGN_VHT4SS_MCS1:
588 ret = DESC_RATEVHTSS4MCS1;
590 case MGN_VHT4SS_MCS2:
591 ret = DESC_RATEVHTSS4MCS2;
593 case MGN_VHT4SS_MCS3:
594 ret = DESC_RATEVHTSS4MCS3;
596 case MGN_VHT4SS_MCS4:
597 ret = DESC_RATEVHTSS4MCS4;
599 case MGN_VHT4SS_MCS5:
600 ret = DESC_RATEVHTSS4MCS5;
602 case MGN_VHT4SS_MCS6:
603 ret = DESC_RATEVHTSS4MCS6;
605 case MGN_VHT4SS_MCS7:
606 ret = DESC_RATEVHTSS4MCS7;
608 case MGN_VHT4SS_MCS8:
609 ret = DESC_RATEVHTSS4MCS8;
611 case MGN_VHT4SS_MCS9:
612 ret = DESC_RATEVHTSS4MCS9;
621 u8 hw_rate_to_m_rate(u8 rate)
623 u8 ret_rate = MGN_1M;
694 ret_rate = MGN_MCS10;
697 ret_rate = MGN_MCS11;
700 ret_rate = MGN_MCS12;
703 ret_rate = MGN_MCS13;
706 ret_rate = MGN_MCS14;
709 ret_rate = MGN_MCS15;
712 ret_rate = MGN_MCS16;
715 ret_rate = MGN_MCS17;
718 ret_rate = MGN_MCS18;
721 ret_rate = MGN_MCS19;
724 ret_rate = MGN_MCS20;
727 ret_rate = MGN_MCS21;
730 ret_rate = MGN_MCS22;
733 ret_rate = MGN_MCS23;
736 ret_rate = MGN_MCS24;
739 ret_rate = MGN_MCS25;
742 ret_rate = MGN_MCS26;
745 ret_rate = MGN_MCS27;
748 ret_rate = MGN_MCS28;
751 ret_rate = MGN_MCS29;
754 ret_rate = MGN_MCS30;
757 ret_rate = MGN_MCS31;
759 case DESC_RATEVHTSS1MCS0:
760 ret_rate = MGN_VHT1SS_MCS0;
762 case DESC_RATEVHTSS1MCS1:
763 ret_rate = MGN_VHT1SS_MCS1;
765 case DESC_RATEVHTSS1MCS2:
766 ret_rate = MGN_VHT1SS_MCS2;
768 case DESC_RATEVHTSS1MCS3:
769 ret_rate = MGN_VHT1SS_MCS3;
771 case DESC_RATEVHTSS1MCS4:
772 ret_rate = MGN_VHT1SS_MCS4;
774 case DESC_RATEVHTSS1MCS5:
775 ret_rate = MGN_VHT1SS_MCS5;
777 case DESC_RATEVHTSS1MCS6:
778 ret_rate = MGN_VHT1SS_MCS6;
780 case DESC_RATEVHTSS1MCS7:
781 ret_rate = MGN_VHT1SS_MCS7;
783 case DESC_RATEVHTSS1MCS8:
784 ret_rate = MGN_VHT1SS_MCS8;
786 case DESC_RATEVHTSS1MCS9:
787 ret_rate = MGN_VHT1SS_MCS9;
789 case DESC_RATEVHTSS2MCS0:
790 ret_rate = MGN_VHT2SS_MCS0;
792 case DESC_RATEVHTSS2MCS1:
793 ret_rate = MGN_VHT2SS_MCS1;
795 case DESC_RATEVHTSS2MCS2:
796 ret_rate = MGN_VHT2SS_MCS2;
798 case DESC_RATEVHTSS2MCS3:
799 ret_rate = MGN_VHT2SS_MCS3;
801 case DESC_RATEVHTSS2MCS4:
802 ret_rate = MGN_VHT2SS_MCS4;
804 case DESC_RATEVHTSS2MCS5:
805 ret_rate = MGN_VHT2SS_MCS5;
807 case DESC_RATEVHTSS2MCS6:
808 ret_rate = MGN_VHT2SS_MCS6;
810 case DESC_RATEVHTSS2MCS7:
811 ret_rate = MGN_VHT2SS_MCS7;
813 case DESC_RATEVHTSS2MCS8:
814 ret_rate = MGN_VHT2SS_MCS8;
816 case DESC_RATEVHTSS2MCS9:
817 ret_rate = MGN_VHT2SS_MCS9;
819 case DESC_RATEVHTSS3MCS0:
820 ret_rate = MGN_VHT3SS_MCS0;
822 case DESC_RATEVHTSS3MCS1:
823 ret_rate = MGN_VHT3SS_MCS1;
825 case DESC_RATEVHTSS3MCS2:
826 ret_rate = MGN_VHT3SS_MCS2;
828 case DESC_RATEVHTSS3MCS3:
829 ret_rate = MGN_VHT3SS_MCS3;
831 case DESC_RATEVHTSS3MCS4:
832 ret_rate = MGN_VHT3SS_MCS4;
834 case DESC_RATEVHTSS3MCS5:
835 ret_rate = MGN_VHT3SS_MCS5;
837 case DESC_RATEVHTSS3MCS6:
838 ret_rate = MGN_VHT3SS_MCS6;
840 case DESC_RATEVHTSS3MCS7:
841 ret_rate = MGN_VHT3SS_MCS7;
843 case DESC_RATEVHTSS3MCS8:
844 ret_rate = MGN_VHT3SS_MCS8;
846 case DESC_RATEVHTSS3MCS9:
847 ret_rate = MGN_VHT3SS_MCS9;
849 case DESC_RATEVHTSS4MCS0:
850 ret_rate = MGN_VHT4SS_MCS0;
852 case DESC_RATEVHTSS4MCS1:
853 ret_rate = MGN_VHT4SS_MCS1;
855 case DESC_RATEVHTSS4MCS2:
856 ret_rate = MGN_VHT4SS_MCS2;
858 case DESC_RATEVHTSS4MCS3:
859 ret_rate = MGN_VHT4SS_MCS3;
861 case DESC_RATEVHTSS4MCS4:
862 ret_rate = MGN_VHT4SS_MCS4;
864 case DESC_RATEVHTSS4MCS5:
865 ret_rate = MGN_VHT4SS_MCS5;
867 case DESC_RATEVHTSS4MCS6:
868 ret_rate = MGN_VHT4SS_MCS6;
870 case DESC_RATEVHTSS4MCS7:
871 ret_rate = MGN_VHT4SS_MCS7;
873 case DESC_RATEVHTSS4MCS8:
874 ret_rate = MGN_VHT4SS_MCS8;
876 case DESC_RATEVHTSS4MCS9:
877 ret_rate = MGN_VHT4SS_MCS9;
881 RTW_INFO("hw_rate_to_m_rate(): Non supported Rate [%x]!!!\n", rate);
893 u8 i, is_brate, brate;
895 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
896 is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
897 brate = mBratesOS[i] & 0x7f;
901 case IEEE80211_CCK_RATE_1MB:
902 *pBrateCfg |= RATE_1M;
904 case IEEE80211_CCK_RATE_2MB:
905 *pBrateCfg |= RATE_2M;
907 case IEEE80211_CCK_RATE_5MB:
908 *pBrateCfg |= RATE_5_5M;
910 case IEEE80211_CCK_RATE_11MB:
911 *pBrateCfg |= RATE_11M;
913 case IEEE80211_OFDM_RATE_6MB:
914 *pBrateCfg |= RATE_6M;
916 case IEEE80211_OFDM_RATE_9MB:
917 *pBrateCfg |= RATE_9M;
919 case IEEE80211_OFDM_RATE_12MB:
920 *pBrateCfg |= RATE_12M;
922 case IEEE80211_OFDM_RATE_18MB:
923 *pBrateCfg |= RATE_18M;
925 case IEEE80211_OFDM_RATE_24MB:
926 *pBrateCfg |= RATE_24M;
928 case IEEE80211_OFDM_RATE_36MB:
929 *pBrateCfg |= RATE_36M;
931 case IEEE80211_OFDM_RATE_48MB:
932 *pBrateCfg |= RATE_48M;
934 case IEEE80211_OFDM_RATE_54MB:
935 *pBrateCfg |= RATE_54M;
947 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
949 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
950 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
951 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];/* BE */
952 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
954 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
955 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
956 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
957 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
962 IN PADAPTER pAdapter,
966 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
968 if (bWIFICfg) { /* WMM */
970 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
971 /* { 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */
972 /* 0:ep_0 num, 1:ep_1 num */
974 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1];/* VO */
975 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
976 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
977 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];/* BK */
979 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
980 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
981 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
982 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
984 } else { /* typical setting */
987 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
988 /* { 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */
989 /* 0:ep_0 num, 1:ep_1 num */
991 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
992 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];/* VI */
993 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1];/* BE */
994 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
996 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
997 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
998 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
999 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1005 static VOID _ThreeOutPipeMapping(
1006 IN PADAPTER pAdapter,
1010 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1012 if (bWIFICfg) { /* for WMM */
1014 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1015 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1018 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1019 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1020 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1021 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1023 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1024 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1025 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1026 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1028 } else { /* typical setting */
1031 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1032 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1035 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1036 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1037 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1038 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1040 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1041 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1042 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];/* HIGH */
1043 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1047 static VOID _FourOutPipeMapping(
1048 IN PADAPTER pAdapter,
1052 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
1054 if (bWIFICfg) { /* for WMM */
1056 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1057 /* { 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1058 /* 0:H, 1:N, 2:L ,3:E */
1060 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1061 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1062 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1063 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1];/* BK */
1065 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1066 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1067 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1068 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1070 } else { /* typical setting */
1073 /* BK, BE, VI, VO, BCN, CMD,MGT,HIGH,HCCA */
1074 /* { 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */
1077 pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];/* VO */
1078 pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1];/* VI */
1079 pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2];/* BE */
1080 pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2];/* BK */
1082 pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];/* BCN */
1083 pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];/* MGT */
1084 pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[3];/* HIGH */
1085 pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];/* TXCMD */
1091 IN PADAPTER pAdapter,
1095 struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
1097 BOOLEAN bWIFICfg = (pregistrypriv->wifi_spec) ? _TRUE : _FALSE;
1099 BOOLEAN result = _TRUE;
1101 switch (NumOutPipe) {
1103 _TwoOutPipeMapping(pAdapter, bWIFICfg);
1107 _ThreeOutPipeMapping(pAdapter, bWIFICfg);
1110 _OneOutPipeMapping(pAdapter);
1121 void rtw_hal_reqtxrpt(_adapter *padapter, u8 macid)
1123 if (padapter->hal_func.reqtxrpt)
1124 padapter->hal_func.reqtxrpt(padapter, macid);
1127 void rtw_hal_dump_macaddr(void *sel, _adapter *adapter)
1131 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1132 u8 mac_addr[ETH_ALEN];
1134 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1135 rtw_mbid_cam_dump(sel, __func__, adapter);
1137 for (i = 0; i < dvobj->iface_nums; i++) {
1138 iface = dvobj->padapters[i];
1140 rtw_hal_get_macaddr_port(iface, mac_addr);
1141 RTW_PRINT_SEL(sel, ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n",
1142 ADPT_ARG(iface), iface->hw_port, MAC_ARG(mac_addr));
1148 void rtw_restore_mac_addr(_adapter *adapter)
1150 #ifdef CONFIG_MI_WITH_MBSSID_CAM
1152 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1154 rtw_mbid_cam_restore(adapter);
1158 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1160 for (i = 0; i < dvobj->iface_nums; i++) {
1161 iface = dvobj->padapters[i];
1163 rtw_hal_set_macaddr_port(iface, adapter_mac_addr(iface));
1167 rtw_hal_dump_macaddr(RTW_DBGDUMP, adapter);
1170 void rtw_init_hal_com_default_value(PADAPTER Adapter)
1172 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
1173 struct registry_priv *regsty = adapter_to_regsty(Adapter);
1175 pHalData->AntDetection = 1;
1176 pHalData->antenna_test = _FALSE;
1177 pHalData->u1ForcedIgiLb = regsty->force_igi_lb;
1180 #ifdef CONFIG_FW_C2H_REG
1181 void c2h_evt_clear(_adapter *adapter)
1183 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1186 s32 c2h_evt_read_88xx(_adapter *adapter, u8 *buf)
1195 trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
1197 if (trigger == C2H_EVT_HOST_CLOSE) {
1198 goto exit; /* Not ready */
1199 } else if (trigger != C2H_EVT_FW_CLOSE) {
1200 goto clear_evt; /* Not a valid value */
1203 _rtw_memset(buf, 0, C2H_REG_LEN);
1205 /* Read ID, LEN, SEQ */
1206 SET_C2H_ID_88XX(buf, rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL));
1207 SET_C2H_SEQ_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_SEQ_88XX));
1208 SET_C2H_PLEN_88XX(buf, rtw_read8(adapter, REG_C2HEVT_CMD_LEN_88XX));
1211 RTW_INFO("%s id=0x%02x, seq=%u, plen=%u, trigger=0x%02x\n", __func__
1212 , C2H_ID_88XX(buf), C2H_SEQ_88XX(buf), C2H_PLEN_88XX(buf), trigger);
1215 /* Read the content */
1216 for (i = 0; i < C2H_PLEN_88XX(buf); i++)
1217 *(C2H_PAYLOAD_88XX(buf) + i) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1219 RTW_DBG_DUMP("payload:\n", C2H_PAYLOAD_88XX(buf), C2H_PLEN_88XX(buf));
1225 * Clear event to notify FW we have read the command.
1226 * If this field isn't clear, the FW won't update the next command message.
1228 c2h_evt_clear(adapter);
1233 #endif /* CONFIG_FW_C2H_REG */
1235 #ifdef CONFIG_FW_C2H_PKT
1236 #ifndef DBG_C2H_PKT_PRE_HDL
1237 #define DBG_C2H_PKT_PRE_HDL 0
1239 #ifndef DBG_C2H_PKT_HDL
1240 #define DBG_C2H_PKT_HDL 0
1242 void rtw_hal_c2h_pkt_pre_hdl(_adapter *adapter, u8 *buf, u16 len)
1245 /* TODO: extract hal_mac IC's code here*/
1253 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1258 hdl_here = rtw_hal_c2h_id_handle_directly(adapter, id, seq, plen, payload) == _TRUE ? 1 : 0;
1260 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1262 ret = rtw_c2h_packet_wk_cmd(adapter, buf, len);
1266 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1267 else if (ret != _SUCCESS || DBG_C2H_PKT_PRE_HDL > 0) {
1268 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1269 , hdl_here ? "handle" : "enqueue"
1270 , ret == _SUCCESS ? "ok" : "fail"
1272 if (DBG_C2H_PKT_PRE_HDL >= 2)
1273 RTW_PRINT_DUMP("dump: ", buf, len);
1278 void rtw_hal_c2h_pkt_hdl(_adapter *adapter, u8 *buf, u16 len)
1281 adapter->hal_func.hal_mac_c2h_handler(adapter, buf, len);
1289 if (rtw_hal_c2h_pkt_hdr_parse(adapter, buf, len, &id, &seq, &plen, &payload) != _SUCCESS) {
1294 #ifdef CONFIG_WOWLAN
1295 if (adapter_to_pwrctl(adapter)->wowlan_mode == _TRUE) {
1302 ret = rtw_hal_c2h_handler(adapter, id, seq, plen, payload);
1306 RTW_ERR("%s parse fail, buf=%p, len=:%u\n", __func__, buf, len);
1307 else if (ret != _SUCCESS || bypass || DBG_C2H_PKT_HDL > 0) {
1308 RTW_PRINT("%s: id=0x%02x, seq=%u, plen=%u, %s %s\n", __func__, id, seq, plen
1309 , !bypass ? "handle" : "bypass"
1310 , ret == _SUCCESS ? "ok" : "fail"
1312 if (DBG_C2H_PKT_HDL >= 2)
1313 RTW_PRINT_DUMP("dump: ", buf, len);
1317 #endif /* CONFIG_FW_C2H_PKT */
1319 void c2h_iqk_offload(_adapter *adapter, u8 *data, u8 len)
1321 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1322 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1324 RTW_INFO("IQK offload finish in %dms\n", rtw_get_passing_time_ms(iqk_sctx->submit_time));
1326 RTW_INFO_DUMP("C2H_IQK_FINISH: ", data, len);
1328 rtw_sctx_done(&iqk_sctx);
1331 int c2h_iqk_offload_wait(_adapter *adapter, u32 timeout_ms)
1333 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1334 struct submit_ctx *iqk_sctx = &hal_data->iqk_sctx;
1336 iqk_sctx->submit_time = rtw_get_current_time();
1337 iqk_sctx->timeout_ms = timeout_ms;
1338 iqk_sctx->status = RTW_SCTX_SUBMITTED;
1340 return rtw_sctx_wait(iqk_sctx, __func__);
1343 #define GET_C2H_MAC_HIDDEN_RPT_UUID_X(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 0, 0, 8)
1344 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Y(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 1, 0, 8)
1345 #define GET_C2H_MAC_HIDDEN_RPT_UUID_Z(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 2, 0, 5)
1346 #define GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(_data) LE_BITS_TO_2BYTE(((u8 *)(_data)) + 2, 5, 11)
1347 #define GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 0, 4)
1348 #define GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 4, 3)
1349 #define GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 4, 7, 1)
1350 #define GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 0, 4)
1351 #define GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 5, 4, 4)
1352 #define GET_C2H_MAC_HIDDEN_RPT_BW(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 0, 3)
1353 #define GET_C2H_MAC_HIDDEN_RPT_FAB(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 3, 2)
1354 #define GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 6, 5, 3)
1355 #define GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 2, 2)
1356 #define GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(_data) LE_BITS_TO_1BYTE(((u8 *)(_data)) + 7, 6, 2)
1358 #ifndef DBG_C2H_MAC_HIDDEN_RPT_HANDLE
1359 #define DBG_C2H_MAC_HIDDEN_RPT_HANDLE 0
1362 #ifdef CONFIG_RTW_MAC_HIDDEN_RPT
1363 int c2h_mac_hidden_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1365 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1366 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1388 if (len < MAC_HIDDEN_RPT_LEN) {
1389 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_LEN);
1393 uuid_x = GET_C2H_MAC_HIDDEN_RPT_UUID_X(data);
1394 uuid_y = GET_C2H_MAC_HIDDEN_RPT_UUID_Y(data);
1395 uuid_z = GET_C2H_MAC_HIDDEN_RPT_UUID_Z(data);
1396 uuid_crc = GET_C2H_MAC_HIDDEN_RPT_UUID_CRC(data);
1398 hci_type = GET_C2H_MAC_HIDDEN_RPT_HCI_TYPE(data);
1399 package_type = GET_C2H_MAC_HIDDEN_RPT_PACKAGE_TYPE(data);
1401 tr_switch = GET_C2H_MAC_HIDDEN_RPT_TR_SWITCH(data);
1403 wl_func = GET_C2H_MAC_HIDDEN_RPT_WL_FUNC(data);
1404 hw_stype = GET_C2H_MAC_HIDDEN_RPT_HW_STYPE(data);
1406 bw = GET_C2H_MAC_HIDDEN_RPT_BW(data);
1407 fab = GET_C2H_MAC_HIDDEN_RPT_FAB(data);
1408 ant_num = GET_C2H_MAC_HIDDEN_RPT_ANT_NUM(data);
1410 protocol = GET_C2H_MAC_HIDDEN_RPT_80211_PROTOCOL(data);
1411 nic = GET_C2H_MAC_HIDDEN_RPT_NIC_ROUTER(data);
1413 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1414 for (i = 0; i < len; i++)
1415 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1417 RTW_PRINT("uuid x:0x%02x y:0x%02x z:0x%x crc:0x%x\n", uuid_x, uuid_y, uuid_z, uuid_crc);
1418 RTW_PRINT("hci_type:0x%x\n", hci_type);
1419 RTW_PRINT("package_type:0x%x\n", package_type);
1420 RTW_PRINT("tr_switch:0x%x\n", tr_switch);
1421 RTW_PRINT("wl_func:0x%x\n", wl_func);
1422 RTW_PRINT("hw_stype:0x%x\n", hw_stype);
1423 RTW_PRINT("bw:0x%x\n", bw);
1424 RTW_PRINT("fab:0x%x\n", fab);
1425 RTW_PRINT("ant_num:0x%x\n", ant_num);
1426 RTW_PRINT("protocol:0x%x\n", protocol);
1427 RTW_PRINT("nic:0x%x\n", nic);
1432 * for now, the following is common info/format
1433 * if there is any hal difference need to export
1434 * some IC dependent code will need to be implement
1436 hal_data->PackageType = package_type;
1437 hal_spec->wl_func &= mac_hidden_wl_func_to_hal_wl_func(wl_func);
1438 hal_spec->bw_cap &= mac_hidden_max_bw_to_hal_bw_cap(bw);
1439 hal_spec->tx_nss_num = rtw_min(hal_spec->tx_nss_num, ant_num);
1440 hal_spec->rx_nss_num = rtw_min(hal_spec->rx_nss_num, ant_num);
1441 hal_spec->proto_cap &= mac_hidden_proto_to_hal_proto_cap(protocol);
1442 hal_spec->hci_type = hci_type;
1444 /* TODO: tr_switch */
1453 int c2h_mac_hidden_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1455 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1456 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1461 if (len < MAC_HIDDEN_RPT_2_LEN) {
1462 RTW_WARN("%s len(%u) < %d\n", __func__, len, MAC_HIDDEN_RPT_2_LEN);
1466 if (DBG_C2H_MAC_HIDDEN_RPT_HANDLE) {
1467 for (i = 0; i < len; i++)
1468 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1477 int hal_read_mac_hidden_rpt(_adapter *adapter)
1479 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
1482 u8 mac_hidden_rpt[MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN] = {0};
1483 u32 start = rtw_get_current_time();
1485 u32 timeout_ms = 800;
1487 u8 id = C2H_DEFEATURE_RSVD;
1490 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1491 u8 hci_type = rtw_get_intf_type(adapter);
1493 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1494 && !rtw_is_hw_init_completed(adapter))
1495 rtw_hal_power_on(adapter);
1498 /* inform FW mac hidden rpt from reg is needed */
1499 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DEFEATURE_RSVD);
1502 pHalData->not_xmitframe_fw_dl = 1;
1503 ret_fwdl = rtw_hal_fw_dl(adapter, _FALSE);
1504 pHalData->not_xmitframe_fw_dl = 0;
1505 if (ret_fwdl != _SUCCESS)
1506 goto mac_hidden_rpt_hdl;
1508 /* polling for data ready */
1509 start = rtw_get_current_time();
1512 id = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
1513 if (id == C2H_MAC_HIDDEN_RPT || RTW_CANNOT_IO(adapter))
1516 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
1518 if (id == C2H_MAC_HIDDEN_RPT) {
1520 for (i = 0; i < MAC_HIDDEN_RPT_LEN + MAC_HIDDEN_RPT_2_LEN; i++)
1521 mac_hidden_rpt[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 2 + i);
1524 /* inform FW mac hidden rpt has read */
1525 rtw_write8(adapter, REG_C2HEVT_MSG_NORMAL, C2H_DBG);
1528 c2h_mac_hidden_rpt_hdl(adapter, mac_hidden_rpt, MAC_HIDDEN_RPT_LEN);
1529 c2h_mac_hidden_rpt_2_hdl(adapter, mac_hidden_rpt + MAC_HIDDEN_RPT_LEN, MAC_HIDDEN_RPT_2_LEN);
1531 if (ret_fwdl == _SUCCESS && id == C2H_MAC_HIDDEN_RPT)
1536 #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
1537 if ((hci_type == RTW_USB || hci_type == RTW_PCIE)
1538 && !rtw_is_hw_init_completed(adapter))
1539 rtw_hal_power_off(adapter);
1542 RTW_INFO("%s %s! (%u, %dms), fwdl:%d, id:0x%02x\n", __func__
1543 , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), ret_fwdl, id);
1547 #endif /* CONFIG_RTW_MAC_HIDDEN_RPT */
1549 int c2h_defeature_dbg_hdl(_adapter *adapter, u8 *data, u8 len)
1551 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
1552 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
1557 if (len < DEFEATURE_DBG_LEN) {
1558 RTW_WARN("%s len(%u) < %d\n", __func__, len, DEFEATURE_DBG_LEN);
1562 for (i = 0; i < len; i++)
1563 RTW_PRINT("%s: 0x%02X\n", __func__, *(data + i));
1571 #ifndef DBG_CUSTOMER_STR_RPT_HANDLE
1572 #define DBG_CUSTOMER_STR_RPT_HANDLE 0
1575 #ifdef CONFIG_RTW_CUSTOMER_STR
1576 s32 rtw_hal_h2c_customer_str_req(_adapter *adapter)
1578 u8 h2c_data[H2C_CUSTOMER_STR_REQ_LEN] = {0};
1580 SET_H2CCMD_CUSTOMER_STR_REQ_EN(h2c_data, 1);
1581 return rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_REQ, H2C_CUSTOMER_STR_REQ_LEN, h2c_data);
1584 #define C2H_CUSTOMER_STR_RPT_BYTE0(_data) ((u8 *)(_data))
1585 #define C2H_CUSTOMER_STR_RPT_2_BYTE8(_data) ((u8 *)(_data))
1587 int c2h_customer_str_rpt_hdl(_adapter *adapter, u8 *data, u8 len)
1589 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1593 if (len < CUSTOMER_STR_RPT_LEN) {
1594 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_LEN);
1598 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1599 RTW_PRINT_DUMP("customer_str_rpt: ", data, CUSTOMER_STR_RPT_LEN);
1601 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1603 if (dvobj->customer_str_sctx != NULL) {
1604 if (dvobj->customer_str_sctx->status != RTW_SCTX_SUBMITTED)
1605 RTW_WARN("%s invalid sctx.status:%d\n", __func__, dvobj->customer_str_sctx->status);
1606 _rtw_memcpy(dvobj->customer_str, C2H_CUSTOMER_STR_RPT_BYTE0(data), CUSTOMER_STR_RPT_LEN);
1607 dvobj->customer_str_sctx->status = RTX_SCTX_CSTR_WAIT_RPT2;
1609 RTW_WARN("%s sctx not set\n", __func__);
1611 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1619 int c2h_customer_str_rpt_2_hdl(_adapter *adapter, u8 *data, u8 len)
1621 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1625 if (len < CUSTOMER_STR_RPT_2_LEN) {
1626 RTW_WARN("%s len(%u) < %d\n", __func__, len, CUSTOMER_STR_RPT_2_LEN);
1630 if (DBG_CUSTOMER_STR_RPT_HANDLE)
1631 RTW_PRINT_DUMP("customer_str_rpt_2: ", data, CUSTOMER_STR_RPT_2_LEN);
1633 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1635 if (dvobj->customer_str_sctx != NULL) {
1636 if (dvobj->customer_str_sctx->status != RTX_SCTX_CSTR_WAIT_RPT2)
1637 RTW_WARN("%s rpt not ready\n", __func__);
1638 _rtw_memcpy(dvobj->customer_str + CUSTOMER_STR_RPT_LEN, C2H_CUSTOMER_STR_RPT_2_BYTE8(data), CUSTOMER_STR_RPT_2_LEN);
1639 rtw_sctx_done(&dvobj->customer_str_sctx);
1641 RTW_WARN("%s sctx not set\n", __func__);
1643 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1651 /* read customer str */
1652 s32 rtw_hal_customer_str_read(_adapter *adapter, u8 *cs)
1654 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1655 struct submit_ctx sctx;
1658 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1659 if (dvobj->customer_str_sctx != NULL)
1662 rtw_sctx_init(&sctx, 2 * 1000);
1663 dvobj->customer_str_sctx = &sctx;
1665 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1668 RTW_WARN("%s another handle ongoing\n", __func__);
1672 ret = rtw_customer_str_req_cmd(adapter);
1673 if (ret != _SUCCESS) {
1674 RTW_WARN("%s read cmd fail\n", __func__);
1675 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1676 dvobj->customer_str_sctx = NULL;
1677 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1681 /* wait till rpt done or timeout */
1682 rtw_sctx_wait(&sctx, __func__);
1684 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1685 dvobj->customer_str_sctx = NULL;
1686 if (sctx.status == RTW_SCTX_DONE_SUCCESS)
1687 _rtw_memcpy(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1690 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1696 s32 rtw_hal_h2c_customer_str_write(_adapter *adapter, const u8 *cs)
1698 u8 h2c_data_w1[H2C_CUSTOMER_STR_W1_LEN] = {0};
1699 u8 h2c_data_w2[H2C_CUSTOMER_STR_W2_LEN] = {0};
1700 u8 h2c_data_w3[H2C_CUSTOMER_STR_W3_LEN] = {0};
1703 SET_H2CCMD_CUSTOMER_STR_W1_EN(h2c_data_w1, 1);
1704 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W1_BYTE0(h2c_data_w1), cs, 6);
1706 SET_H2CCMD_CUSTOMER_STR_W2_EN(h2c_data_w2, 1);
1707 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W2_BYTE6(h2c_data_w2), cs + 6, 6);
1709 SET_H2CCMD_CUSTOMER_STR_W3_EN(h2c_data_w3, 1);
1710 _rtw_memcpy(H2CCMD_CUSTOMER_STR_W3_BYTE12(h2c_data_w3), cs + 6 + 6, 4);
1712 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W1, H2C_CUSTOMER_STR_W1_LEN, h2c_data_w1);
1713 if (ret != _SUCCESS) {
1714 RTW_WARN("%s w1 fail\n", __func__);
1718 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W2, H2C_CUSTOMER_STR_W2_LEN, h2c_data_w2);
1719 if (ret != _SUCCESS) {
1720 RTW_WARN("%s w2 fail\n", __func__);
1724 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_CUSTOMER_STR_W3, H2C_CUSTOMER_STR_W3_LEN, h2c_data_w3);
1725 if (ret != _SUCCESS) {
1726 RTW_WARN("%s w3 fail\n", __func__);
1734 /* write customer str and check if value reported is the same as requested */
1735 s32 rtw_hal_customer_str_write(_adapter *adapter, const u8 *cs)
1737 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1738 struct submit_ctx sctx;
1741 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1742 if (dvobj->customer_str_sctx != NULL)
1745 rtw_sctx_init(&sctx, 2 * 1000);
1746 dvobj->customer_str_sctx = &sctx;
1748 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1751 RTW_WARN("%s another handle ongoing\n", __func__);
1755 ret = rtw_customer_str_write_cmd(adapter, cs);
1756 if (ret != _SUCCESS) {
1757 RTW_WARN("%s write cmd fail\n", __func__);
1758 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1759 dvobj->customer_str_sctx = NULL;
1760 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1764 ret = rtw_customer_str_req_cmd(adapter);
1765 if (ret != _SUCCESS) {
1766 RTW_WARN("%s read cmd fail\n", __func__);
1767 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1768 dvobj->customer_str_sctx = NULL;
1769 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1773 /* wait till rpt done or timeout */
1774 rtw_sctx_wait(&sctx, __func__);
1776 _enter_critical_mutex(&dvobj->customer_str_mutex, NULL);
1777 dvobj->customer_str_sctx = NULL;
1778 if (sctx.status == RTW_SCTX_DONE_SUCCESS) {
1779 if (_rtw_memcmp(cs, dvobj->customer_str, RTW_CUSTOMER_STR_LEN) != _TRUE) {
1780 RTW_WARN("%s read back check fail\n", __func__);
1781 RTW_INFO_DUMP("write req: ", cs, RTW_CUSTOMER_STR_LEN);
1782 RTW_INFO_DUMP("read back: ", dvobj->customer_str, RTW_CUSTOMER_STR_LEN);
1787 _exit_critical_mutex(&dvobj->customer_str_mutex, NULL);
1792 #endif /* CONFIG_RTW_CUSTOMER_STR */
1794 u8 rtw_hal_networktype_to_raid(_adapter *adapter, struct sta_info *psta)
1796 #ifdef CONFIG_GET_RAID_BY_DRV /*Just for 8188E now*/
1797 if (IS_NEW_GENERATION_IC(adapter))
1798 return networktype_to_raid_ex(adapter, psta);
1800 return networktype_to_raid(adapter, psta);
1802 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
1805 bw = rtw_get_tx_bw_mode(adapter, psta);
1807 return phydm_rate_id_mapping(&pHalData->odmpriv, psta->wireless_mode, pHalData->rf_type, bw);
1810 u8 rtw_get_mgntframe_raid(_adapter *adapter, unsigned char network_type)
1814 if (IS_NEW_GENERATION_IC(adapter)) {
1816 raid = (network_type & WIRELESS_11B) ? RATEID_IDX_B
1819 raid = (network_type & WIRELESS_11B) ? RATR_INX_WIRELESS_B
1820 : RATR_INX_WIRELESS_G;
1825 void rtw_hal_update_sta_rate_mask(PADAPTER padapter, struct sta_info *psta)
1827 struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
1828 u8 i, rf_type, tx_nss;
1836 /* b/g mode ra_bitmap */
1837 for (i = 0; i < sizeof(psta->bssrateset); i++) {
1838 if (psta->bssrateset[i])
1839 tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i] & 0x7f);
1842 #ifdef CONFIG_80211N_HT
1843 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1844 tx_nss = rtw_min(rf_type_to_rf_tx_cnt(rf_type), hal_spec->tx_nss_num);
1845 #ifdef CONFIG_80211AC_VHT
1846 if (psta->vhtpriv.vht_option) {
1847 /* AC mode ra_bitmap */
1848 tx_ra_bitmap |= (rtw_vht_mcs_map_to_bitmap(psta->vhtpriv.vht_mcs_map, tx_nss) << 12);
1850 #endif /* CONFIG_80211AC_VHT */
1851 if (psta->htpriv.ht_option) {
1852 /* n mode ra_bitmap */
1854 /* Handling SMPS mode for AP MODE only*/
1855 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE) {
1856 /*0:static SMPS, 1:dynamic SMPS, 3:SMPS disabled, 2:reserved*/
1857 if (psta->htpriv.smps_cap == 0 || psta->htpriv.smps_cap == 1) {
1858 /*operate with only one active receive chain // 11n-MCS rate <= MSC7*/
1859 tx_nss = rtw_min(tx_nss, 1);
1863 tx_ra_bitmap |= (rtw_ht_mcs_set_to_bitmap(psta->htpriv.ht_cap.supp_mcs_set, tx_nss) << 12);
1865 #endif /* CONFIG_80211N_HT */
1866 psta->ra_mask = tx_ra_bitmap;
1867 psta->init_rate = get_highest_rate_idx(tx_ra_bitmap) & 0x3f;
1870 #ifndef SEC_CAM_ACCESS_TIMEOUT_MS
1871 #define SEC_CAM_ACCESS_TIMEOUT_MS 200
1874 #ifndef DBG_SEC_CAM_ACCESS
1875 #define DBG_SEC_CAM_ACCESS 0
1878 u32 rtw_sec_read_cam(_adapter *adapter, u8 addr)
1880 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
1883 u32 start = 0, end = 0;
1887 _enter_critical_mutex(mutex, NULL);
1889 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | addr);
1891 start = rtw_get_current_time();
1893 if (rtw_is_surprise_removed(adapter)) {
1899 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
1902 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
1907 end = rtw_get_current_time();
1909 rdata = rtw_read32(adapter, REG_CAMREAD);
1911 _exit_critical_mutex(mutex, NULL);
1913 if (DBG_SEC_CAM_ACCESS || timeout) {
1914 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, rdata:0x%08x, to:%u, polling:%u, %d ms\n"
1915 , FUNC_ADPT_ARG(adapter), addr, rdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
1921 void rtw_sec_write_cam(_adapter *adapter, u8 addr, u32 wdata)
1923 _mutex *mutex = &adapter_to_dvobj(adapter)->cam_ctl.sec_cam_access_mutex;
1925 u32 start = 0, end = 0;
1929 _enter_critical_mutex(mutex, NULL);
1931 rtw_write32(adapter, REG_CAMWRITE, wdata);
1932 rtw_write32(adapter, REG_CAMCMD, CAM_POLLINIG | CAM_WRITE | addr);
1934 start = rtw_get_current_time();
1936 if (rtw_is_surprise_removed(adapter)) {
1942 if (0 == (rtw_read32(adapter, REG_CAMCMD) & CAM_POLLINIG))
1945 if (rtw_get_passing_time_ms(start) > SEC_CAM_ACCESS_TIMEOUT_MS) {
1950 end = rtw_get_current_time();
1952 _exit_critical_mutex(mutex, NULL);
1954 if (DBG_SEC_CAM_ACCESS || timeout) {
1955 RTW_INFO(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
1956 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
1960 void rtw_sec_read_cam_ent(_adapter *adapter, u8 id, u8 *ctrl, u8 *mac, u8 *key)
1962 unsigned int val, addr;
1966 u8 end = 5; /* TODO: consider other key length accordingly */
1968 if (!ctrl && !mac && !key) {
1973 /* TODO: check id range */
1976 begin = 2; /* read from key */
1979 end = 0; /* read to ctrl */
1981 end = 2; /* read to mac */
1983 for (i = begin; i <= end; i++) {
1984 rdata = rtw_sec_read_cam(adapter, (id << 3) | i);
1989 _rtw_memcpy(ctrl, (u8 *)(&rdata), 2);
1991 _rtw_memcpy(mac, ((u8 *)(&rdata)) + 2, 2);
1995 _rtw_memcpy(mac + 2, (u8 *)(&rdata), 4);
1999 _rtw_memcpy(key + (i - 2) * 4, (u8 *)(&rdata), 4);
2009 void rtw_sec_write_cam_ent(_adapter *adapter, u8 id, u16 ctrl, u8 *mac, u8 *key)
2016 /* TODO: consider other key length accordingly */
2018 switch ((ctrl & 0x1c) >> 2) {
2029 for (; j >= 0; j--) {
2032 wdata = (ctrl | (mac[0] << 16) | (mac[1] << 24));
2035 wdata = (mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24));
2043 wdata = (key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) | (key[i + 3] << 24));
2047 addr = (id << 3) + j;
2049 rtw_sec_write_cam(adapter, addr, wdata);
2053 void rtw_sec_clr_cam_ent(_adapter *adapter, u8 id)
2058 rtw_sec_write_cam(adapter, addr, 0);
2061 bool rtw_sec_read_cam_is_gk(_adapter *adapter, u8 id)
2066 rtw_sec_read_cam_ent(adapter, id, (u8 *)&ctrl, NULL, NULL);
2068 res = (ctrl & BIT6) ? _TRUE : _FALSE;
2071 #ifdef CONFIG_MBSSID_CAM
2072 void rtw_mbid_cam_init(struct dvobj_priv *dvobj)
2074 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2076 _rtw_spinlock_init(&mbid_cam_ctl->lock);
2077 mbid_cam_ctl->bitmap = 0;
2078 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2079 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2082 void rtw_mbid_cam_deinit(struct dvobj_priv *dvobj)
2084 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2086 _rtw_spinlock_free(&mbid_cam_ctl->lock);
2089 void rtw_mbid_cam_reset(_adapter *adapter)
2092 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2093 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2095 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2096 mbid_cam_ctl->bitmap = 0;
2097 _rtw_memset(&dvobj->mbid_cam_cache, 0, sizeof(dvobj->mbid_cam_cache));
2098 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2100 ATOMIC_SET(&mbid_cam_ctl->mbid_entry_num, 0);
2102 static u8 _rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2105 u8 cam_id = INVALID_CAM_ID;
2106 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2108 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2109 if (mac_addr && _rtw_memcmp(dvobj->mbid_cam_cache[i].mac_addr, mac_addr, ETH_ALEN) == _TRUE) {
2115 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2119 u8 rtw_mbid_cam_search_by_macaddr(_adapter *adapter, u8 *mac_addr)
2123 u8 cam_id = INVALID_CAM_ID;
2124 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2125 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2127 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2128 cam_id = _rtw_mbid_cam_search_by_macaddr(adapter, mac_addr);
2129 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2133 static u8 _rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2136 u8 cam_id = INVALID_CAM_ID;
2137 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2139 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2140 if (iface_id == dvobj->mbid_cam_cache[i].iface_id) {
2145 if (cam_id != INVALID_CAM_ID)
2146 RTW_INFO("%s iface_id:%d mac:"MAC_FMT" - cam_id:%d\n",
2147 __func__, iface_id, MAC_ARG(dvobj->mbid_cam_cache[cam_id].mac_addr), cam_id);
2152 u8 rtw_mbid_cam_search_by_ifaceid(_adapter *adapter, u8 iface_id)
2155 u8 cam_id = INVALID_CAM_ID;
2156 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2157 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2159 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2160 cam_id = _rtw_mbid_cam_search_by_ifaceid(adapter, iface_id);
2161 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2165 u8 rtw_get_max_mbid_cam_id(_adapter *adapter)
2169 u8 cam_id = INVALID_CAM_ID;
2170 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2171 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2173 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2174 for (i = (TOTAL_MBID_CAM_NUM - 1); i >= 0; i--) {
2175 if (mbid_cam_ctl->bitmap & BIT(i)) {
2180 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2181 /*RTW_INFO("%s max cam_id:%d\n", __func__, cam_id);*/
2185 inline u8 rtw_get_mbid_cam_entry_num(_adapter *adapter)
2187 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2188 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2190 return ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2193 static inline void mbid_cam_cache_init(_adapter *adapter, struct mbid_cam_cache *pmbid_cam, u8 *mac_addr)
2195 if (adapter && pmbid_cam && mac_addr) {
2196 _rtw_memcpy(pmbid_cam->mac_addr, mac_addr, ETH_ALEN);
2197 pmbid_cam->iface_id = adapter->iface_id;
2200 static inline void mbid_cam_cache_clr(struct mbid_cam_cache *pmbid_cam)
2203 _rtw_memset(pmbid_cam->mac_addr, 0, ETH_ALEN);
2204 pmbid_cam->iface_id = CONFIG_IFACE_NUMBER;
2208 u8 rtw_mbid_camid_alloc(_adapter *adapter, u8 *mac_addr)
2211 u8 cam_id = INVALID_CAM_ID, i;
2212 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2213 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2214 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2216 if (entry_num >= TOTAL_MBID_CAM_NUM) {
2217 RTW_INFO(FUNC_ADPT_FMT" failed !! MBSSID number :%d over TOTAL_CAM_ENTRY(8)\n", FUNC_ADPT_ARG(adapter), entry_num);
2221 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2224 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2225 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2226 if (!(mbid_cam_ctl->bitmap & BIT(i))) {
2227 mbid_cam_ctl->bitmap |= BIT(i);
2232 if ((cam_id != INVALID_CAM_ID) && (mac_addr))
2233 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[cam_id], mac_addr);
2234 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2236 if (cam_id != INVALID_CAM_ID) {
2237 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2238 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2239 #ifdef DBG_MBID_CAM_DUMP
2240 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2243 RTW_INFO("%s [WARN] "MAC_FMT" - invalid cam_id:%d\n", __func__, MAC_ARG(mac_addr), cam_id);
2248 u8 rtw_mbid_cam_info_change(_adapter *adapter, u8 *mac_addr)
2251 u8 entry_id = INVALID_CAM_ID;
2252 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2253 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2255 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2256 entry_id = _rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
2257 if (entry_id != INVALID_CAM_ID)
2258 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[entry_id], mac_addr);
2260 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2265 u8 rtw_mbid_cam_assign(_adapter *adapter, u8 *mac_addr, u8 camid)
2269 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2270 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2272 if ((camid >= TOTAL_MBID_CAM_NUM) || (camid == INVALID_CAM_ID)) {
2273 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), camid);
2276 if (INVALID_CAM_ID != rtw_mbid_cam_search_by_macaddr(adapter, mac_addr))
2279 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2280 if (!(mbid_cam_ctl->bitmap & BIT(camid))) {
2282 mbid_cam_ctl->bitmap |= BIT(camid);
2283 mbid_cam_cache_init(adapter, &dvobj->mbid_cam_cache[camid], mac_addr);
2287 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2290 ATOMIC_INC(&mbid_cam_ctl->mbid_entry_num);
2291 RTW_INFO("%s mac:"MAC_FMT" - cam_id:%d\n", __func__, MAC_ARG(mac_addr), camid);
2292 #ifdef DBG_MBID_CAM_DUMP
2293 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2296 RTW_INFO("%s [WARN] mac:"MAC_FMT" - cam_id:%d assigned failed\n", __func__, MAC_ARG(mac_addr), camid);
2302 void rtw_mbid_camid_clean(_adapter *adapter, u8 mbss_canid)
2305 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2306 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2308 if ((mbss_canid >= TOTAL_MBID_CAM_NUM) || (mbss_canid == INVALID_CAM_ID)) {
2309 RTW_INFO(FUNC_ADPT_FMT" failed !! invlaid mbid_canid :%d\n", FUNC_ADPT_ARG(adapter), mbss_canid);
2312 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2313 mbid_cam_cache_clr(&dvobj->mbid_cam_cache[mbss_canid]);
2314 mbid_cam_ctl->bitmap &= (~BIT(mbss_canid));
2315 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2316 ATOMIC_DEC(&mbid_cam_ctl->mbid_entry_num);
2317 RTW_INFO("%s - cam_id:%d\n", __func__, mbss_canid);
2319 int rtw_mbid_cam_cache_dump(void *sel, const char *fun_name, _adapter *adapter)
2325 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2326 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2327 u8 entry_num = ATOMIC_READ(&mbid_cam_ctl->mbid_entry_num);
2328 u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2330 RTW_PRINT_SEL(sel, "== MBSSID CAM DUMP (%s)==\n", fun_name);
2332 _enter_critical_bh(&mbid_cam_ctl->lock, &irqL);
2333 RTW_PRINT_SEL(sel, "Entry numbers:%d, max_camid:%d, bitmap:0x%08x\n", entry_num, max_cam_id, mbid_cam_ctl->bitmap);
2334 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2335 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2337 if (mbid_cam_ctl->bitmap & BIT(i)) {
2338 iface_id = dvobj->mbid_cam_cache[i].iface_id;
2339 RTW_PRINT_SEL(sel, "IF_ID:%d\t", iface_id);
2340 RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\t", MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2342 iface = dvobj->padapters[iface_id];
2344 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE)
2345 RTW_PRINT_SEL(sel, "ROLE:%s\n", "STA");
2346 else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE)
2347 RTW_PRINT_SEL(sel, "ROLE:%s\n", "AP");
2349 RTW_PRINT_SEL(sel, "ROLE:%s\n", "NONE");
2353 RTW_PRINT_SEL(sel, "N/A\n");
2355 _exit_critical_bh(&mbid_cam_ctl->lock, &irqL);
2359 static void read_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2362 u8 cam_ready = _FALSE;
2366 if (RTW_CANNOT_RUN(padapter))
2369 rtw_write32(padapter, REG_MBIDCAMCFG_2, BIT_MBIDCAM_POLL | ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT));
2372 if (0 == (rtw_read32(padapter, REG_MBIDCAMCFG_2) & BIT_MBIDCAM_POLL)) {
2377 } while ((poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));
2380 cam_data1 = rtw_read32(padapter, REG_MBIDCAMCFG_1);
2381 mac[0] = cam_data1 & 0xFF;
2382 mac[1] = (cam_data1 >> 8) & 0xFF;
2383 mac[2] = (cam_data1 >> 16) & 0xFF;
2384 mac[3] = (cam_data1 >> 24) & 0xFF;
2386 cam_data2 = rtw_read16(padapter, REG_MBIDCAMCFG_2);
2387 mac[4] = cam_data2 & 0xFF;
2388 mac[5] = (cam_data2 >> 8) & 0xFF;
2392 int rtw_mbid_cam_dump(void *sel, const char *fun_name, _adapter *adapter)
2396 u8 mac_addr[ETH_ALEN];
2398 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2399 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2401 RTW_PRINT_SEL(sel, "\n== MBSSID HW-CAM DUMP (%s)==\n", fun_name);
2403 /*_enter_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2404 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2405 RTW_PRINT_SEL(sel, "CAM_ID = %d\t", i);
2406 _rtw_memset(mac_addr, 0, ETH_ALEN);
2407 read_mbssid_cam(adapter, i, mac_addr);
2408 RTW_PRINT_SEL(sel, "MAC Addr:"MAC_FMT"\n", MAC_ARG(mac_addr));
2410 /*_exit_critical_bh(&mbid_cam_ctl->lock, &irqL);*/
2414 static void write_mbssid_cam(_adapter *padapter, u8 cam_addr, u8 *mac)
2416 u32 cam_val[2] = {0};
2418 cam_val[0] = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
2419 cam_val[1] = ((cam_addr & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT) | (mac[5] << 8) | mac[4];
2421 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_WRITE, (u8 *)cam_val);
2424 static void clear_mbssid_cam(_adapter *padapter, u8 cam_addr)
2426 rtw_hal_set_hwreg(padapter, HW_VAR_MBSSID_CAM_CLEAR, &cam_addr);
2428 static void enable_mbssid_cam(_adapter *adapter)
2430 u8 max_cam_id = rtw_get_max_mbid_cam_id(adapter);
2432 rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) | RCR_ENMBID);
2433 if (max_cam_id != INVALID_CAM_ID) {
2434 rtw_write8(adapter, REG_MBID_NUM,
2435 ((rtw_read8(adapter, REG_MBID_NUM) & 0xF8) | (max_cam_id & 0x07)));
2438 void rtw_mbid_cam_restore(_adapter *adapter)
2441 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2442 struct mbid_cam_ctl_t *mbid_cam_ctl = &dvobj->mbid_cam_ctl;
2444 #ifdef DBG_MBID_CAM_DUMP
2445 rtw_mbid_cam_cache_dump(RTW_DBGDUMP, __func__, adapter);
2448 for (i = 0; i < TOTAL_MBID_CAM_NUM; i++) {
2449 if (mbid_cam_ctl->bitmap & BIT(i)) {
2450 write_mbssid_cam(adapter, i, dvobj->mbid_cam_cache[i].mac_addr);
2451 RTW_INFO("%s - cam_id:%d => mac:"MAC_FMT"\n", __func__, i, MAC_ARG(dvobj->mbid_cam_cache[i].mac_addr));
2454 enable_mbssid_cam(adapter);
2456 #endif /*CONFIG_MBSSID_CAM*/
2458 #ifdef CONFIG_MI_WITH_MBSSID_CAM
2459 void rtw_hal_set_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
2462 #if 0 /*TODO - modify for more flexible*/
2465 if ((check_fwstate(&adapter->mlmepriv, WIFI_STATION_STATE) == _TRUE) &&
2466 (DEV_STA_NUM(adapter_to_dvobj(adapter)) == 1)) {
2467 for (idx = 0; idx < 6; idx++)
2468 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (REG_MACID + idx), val[idx]);
2470 /*MBID entry_id = 0~7 ,0 for root AP, 1~7 for VAP*/
2473 if ((check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE) &&
2474 (DEV_AP_NUM(adapter_to_dvobj(adapter)) == 1)) {
2476 if (rtw_mbid_cam_assign(adapter, val, entry_id)) {
2477 RTW_INFO(FUNC_ADPT_FMT" Root AP assigned success\n", FUNC_ADPT_ARG(adapter));
2478 write_mbssid_cam(adapter, entry_id, val);
2481 entry_id = rtw_mbid_camid_alloc(adapter, val);
2482 if (entry_id != INVALID_CAM_ID)
2483 write_mbssid_cam(adapter, entry_id, val);
2489 MBID entry_id = 0~7 ,for IFACE_ID0 ~ IFACE_IDx
2491 u8 entry_id = rtw_mbid_camid_alloc(adapter, mac_addr);
2494 if (entry_id != INVALID_CAM_ID) {
2495 write_mbssid_cam(adapter, entry_id, mac_addr);
2496 enable_mbssid_cam(adapter);
2502 void rtw_hal_change_macaddr_mbid(_adapter *adapter, u8 *mac_addr)
2505 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2514 entry_id = rtw_mbid_cam_info_change(adapter, mac_addr);
2516 if (entry_id != INVALID_CAM_ID)
2517 write_mbssid_cam(adapter, entry_id, mac_addr);
2521 #endif/*#ifdef CONFIG_MI_WITH_MBSSID_CAM*/
2523 void rtw_hal_set_macaddr_port(_adapter *adapter, u8 *val)
2531 RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
2532 ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(val));
2534 switch (adapter->hw_port) {
2537 reg_macid = REG_MACID;
2540 reg_macid = REG_MACID1;
2542 #if defined(CONFIG_RTL8814A)
2544 reg_macid = REG_MACID2;
2547 reg_macid = REG_MACID3;
2550 reg_macid = REG_MACID4;
2552 #endif/*defined(CONFIG_RTL8814A)*/
2555 for (idx = 0; idx < 6; idx++)
2556 rtw_write8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx), val[idx]);
2558 void rtw_hal_get_macaddr_port(_adapter *adapter, u8 *mac_addr)
2563 if (mac_addr == NULL)
2566 _rtw_memset(mac_addr, 0, ETH_ALEN);
2567 switch (adapter->hw_port) {
2570 reg_macid = REG_MACID;
2573 reg_macid = REG_MACID1;
2575 #if defined(CONFIG_RTL8814A)
2577 reg_macid = REG_MACID2;
2580 reg_macid = REG_MACID3;
2583 reg_macid = REG_MACID4;
2585 #endif /*defined(CONFIG_RTL8814A)*/
2588 for (idx = 0; idx < 6; idx++)
2589 mac_addr[idx] = rtw_read8(GET_PRIMARY_ADAPTER(adapter), (reg_macid + idx));
2591 RTW_INFO("%s "ADPT_FMT"- hw port(%d) mac_addr ="MAC_FMT"\n", __func__,
2592 ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(mac_addr));
2595 void rtw_hal_set_bssid(_adapter *adapter, u8 *val)
2600 switch (adapter->hw_port) {
2603 reg_bssid = REG_BSSID;
2606 reg_bssid = REG_BSSID1;
2608 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)
2610 reg_bssid = REG_BSSID2;
2613 reg_bssid = REG_BSSID3;
2616 reg_bssid = REG_BSSID4;
2618 #endif/*defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)*/
2621 for (idx = 0 ; idx < 6; idx++)
2622 rtw_write8(adapter, (reg_bssid + idx), val[idx]);
2624 RTW_INFO("%s "ADPT_FMT"- hw port -%d BSSID: "MAC_FMT"\n", __func__, ADPT_ARG(adapter), adapter->hw_port, MAC_ARG(val));
2627 void rtw_hal_get_msr(_adapter *adapter, u8 *net_type)
2629 switch (adapter->hw_port) {
2631 /*REG_CR - BIT[17:16]-Network Type for port 1*/
2632 *net_type = rtw_read8(adapter, MSR) & 0x03;
2635 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2636 *net_type = (rtw_read8(adapter, MSR) & 0x0C) >> 2;
2638 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)
2640 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2641 *net_type = rtw_read8(adapter, MSR1) & 0x03;
2644 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2645 *net_type = (rtw_read8(adapter, MSR1) & 0x0C) >> 2;
2648 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2649 *net_type = (rtw_read8(adapter, MSR1) & 0x30) >> 4;
2651 #endif /*#if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)*/
2653 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2654 ADPT_ARG(adapter), adapter->hw_port);
2660 void rtw_hal_set_msr(_adapter *adapter, u8 net_type)
2664 switch (adapter->hw_port) {
2666 #if defined(CONFIG_MI_WITH_MBSSID_CAM) && defined(CONFIG_MBSSID_CAM) /*For 2 hw ports - 88E/92E/8812/8821/8723B*/
2667 if (rtw_get_mbid_cam_entry_num(adapter)) {
2668 if (net_type != _HW_STATE_NOLINK_)
2669 net_type = _HW_STATE_AP_;
2672 /*REG_CR - BIT[17:16]-Network Type for port 0*/
2673 val8 = rtw_read8(adapter, MSR) & 0x0C;
2675 rtw_write8(adapter, MSR, val8);
2678 /*REG_CR - BIT[19:18]-Network Type for port 1*/
2679 val8 = rtw_read8(adapter, MSR) & 0x03;
2680 val8 |= net_type << 2;
2681 rtw_write8(adapter, MSR, val8);
2683 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C)
2685 /*REG_CR_EXT- BIT[1:0]-Network Type for port 2*/
2686 val8 = rtw_read8(adapter, MSR1) & 0xFC;
2688 rtw_write8(adapter, MSR1, val8);
2691 /*REG_CR_EXT- BIT[3:2]-Network Type for port 3*/
2692 val8 = rtw_read8(adapter, MSR1) & 0xF3;
2693 val8 |= net_type << 2;
2694 rtw_write8(adapter, MSR1, val8);
2697 /*REG_CR_EXT- BIT[5:4]-Network Type for port 4*/
2698 val8 = rtw_read8(adapter, MSR1) & 0xCF;
2699 val8 |= net_type << 4;
2700 rtw_write8(adapter, MSR1, val8);
2702 #endif /* CONFIG_RTL8814A | CONFIG_RTL8822B */
2704 RTW_INFO("[WARN] "ADPT_FMT"- invalid hw port -%d\n",
2705 ADPT_ARG(adapter), adapter->hw_port);
2711 void hw_var_port_switch(_adapter *adapter)
2713 #ifdef CONFIG_CONCURRENT_MODE
2714 #ifdef CONFIG_RUNTIME_PORT_SWITCH
2718 0x551: REG_BCN_CTRL_1
2722 0x570: REG_ATIMWND_1
2743 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2744 _adapter *iface = NULL;
2746 msr = rtw_read8(adapter, MSR);
2747 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
2748 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
2750 for (i = 0; i < 2; i++)
2751 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
2752 for (i = 0; i < 2; i++)
2753 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
2755 for (i = 0; i < 8; i++)
2756 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
2757 for (i = 0; i < 8; i++)
2758 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
2760 for (i = 0; i < 6; i++)
2761 macid[i] = rtw_read8(adapter, REG_MACID + i);
2763 for (i = 0; i < 6; i++)
2764 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
2766 for (i = 0; i < 6; i++)
2767 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
2769 for (i = 0; i < 6; i++)
2770 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
2772 #ifdef DBG_RUNTIME_PORT_SWITCH
2773 RTW_INFO(FUNC_ADPT_FMT" before switch\n"
2776 "bcn_ctrl_1:0x%02x\n"
2778 "atimwnd_1:0x%04x\n"
2783 "macid_1:"MAC_FMT"\n"
2784 "bssid_1:"MAC_FMT"\n"
2785 , FUNC_ADPT_ARG(adapter)
2790 , *((u16 *)atimwnd_1)
2798 #endif /* DBG_RUNTIME_PORT_SWITCH */
2800 /* disable bcn function, disable update TSF */
2801 rtw_write8(adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
2802 rtw_write8(adapter, REG_BCN_CTRL_1, (bcn_ctrl_1 & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);
2805 msr = (msr & 0xf0) | ((msr & 0x03) << 2) | ((msr & 0x0c) >> 2);
2806 rtw_write8(adapter, MSR, msr);
2809 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1 & ~EN_BCN_FUNCTION);
2810 for (i = 0; i < 2; i++)
2811 rtw_write8(adapter, REG_ATIMWND + i, atimwnd_1[i]);
2812 for (i = 0; i < 8; i++)
2813 rtw_write8(adapter, REG_TSFTR + i, tsftr_1[i]);
2814 for (i = 0; i < 6; i++)
2815 rtw_write8(adapter, REG_MACID + i, macid_1[i]);
2816 for (i = 0; i < 6; i++)
2817 rtw_write8(adapter, REG_BSSID + i, bssid_1[i]);
2820 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl & ~EN_BCN_FUNCTION);
2821 for (i = 0; i < 2; i++)
2822 rtw_write8(adapter, REG_ATIMWND_1 + i, atimwnd[i]);
2823 for (i = 0; i < 8; i++)
2824 rtw_write8(adapter, REG_TSFTR1 + i, tsftr[i]);
2825 for (i = 0; i < 6; i++)
2826 rtw_write8(adapter, REG_MACID1 + i, macid[i]);
2827 for (i = 0; i < 6; i++)
2828 rtw_write8(adapter, REG_BSSID1 + i, bssid[i]);
2831 #ifdef CONFIG_BT_COEXIST
2832 /* always enable port0 beacon function for PSTDMA */
2833 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter)
2834 || IS_HARDWARE_TYPE_8723D(adapter))
2835 bcn_ctrl_1 |= EN_BCN_FUNCTION;
2836 /* always disable port1 beacon function for PSTDMA */
2837 if (IS_HARDWARE_TYPE_8723B(adapter) || IS_HARDWARE_TYPE_8703B(adapter))
2838 bcn_ctrl &= ~EN_BCN_FUNCTION;
2840 rtw_write8(adapter, REG_BCN_CTRL, bcn_ctrl_1);
2841 rtw_write8(adapter, REG_BCN_CTRL_1, bcn_ctrl);
2843 if (adapter->iface_id == IFACE_ID0)
2844 iface = dvobj->padapters[IFACE_ID1];
2845 else if (adapter->iface_id == IFACE_ID1)
2846 iface = dvobj->padapters[IFACE_ID0];
2849 if (adapter->hw_port == HW_PORT0) {
2850 adapter->hw_port = HW_PORT1;
2851 iface->hw_port = HW_PORT0;
2852 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
2853 ADPT_ARG(iface), ADPT_ARG(adapter));
2855 adapter->hw_port = HW_PORT0;
2856 iface->hw_port = HW_PORT1;
2857 RTW_PRINT("port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n",
2858 ADPT_ARG(adapter), ADPT_ARG(iface));
2861 #ifdef DBG_RUNTIME_PORT_SWITCH
2862 msr = rtw_read8(adapter, MSR);
2863 bcn_ctrl = rtw_read8(adapter, REG_BCN_CTRL);
2864 bcn_ctrl_1 = rtw_read8(adapter, REG_BCN_CTRL_1);
2866 for (i = 0; i < 2; i++)
2867 atimwnd[i] = rtw_read8(adapter, REG_ATIMWND + i);
2868 for (i = 0; i < 2; i++)
2869 atimwnd_1[i] = rtw_read8(adapter, REG_ATIMWND_1 + i);
2871 for (i = 0; i < 8; i++)
2872 tsftr[i] = rtw_read8(adapter, REG_TSFTR + i);
2873 for (i = 0; i < 8; i++)
2874 tsftr_1[i] = rtw_read8(adapter, REG_TSFTR1 + i);
2876 for (i = 0; i < 6; i++)
2877 macid[i] = rtw_read8(adapter, REG_MACID + i);
2879 for (i = 0; i < 6; i++)
2880 bssid[i] = rtw_read8(adapter, REG_BSSID + i);
2882 for (i = 0; i < 6; i++)
2883 macid_1[i] = rtw_read8(adapter, REG_MACID1 + i);
2885 for (i = 0; i < 6; i++)
2886 bssid_1[i] = rtw_read8(adapter, REG_BSSID1 + i);
2888 RTW_INFO(FUNC_ADPT_FMT" after switch\n"
2891 "bcn_ctrl_1:0x%02x\n"
2898 "macid_1:"MAC_FMT"\n"
2899 "bssid_1:"MAC_FMT"\n"
2900 , FUNC_ADPT_ARG(adapter)
2905 , *((u16 *)atimwnd_1)
2913 #endif /* DBG_RUNTIME_PORT_SWITCH */
2915 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
2916 #endif /* CONFIG_CONCURRENT_MODE */
2919 const char *const _h2c_msr_role_str[] = {
2930 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
2931 s32 rtw_hal_set_default_port_id_cmd(_adapter *adapter, u8 mac_id)
2934 u8 parm[H2C_DEFAULT_PORT_ID_LEN] = {0};
2935 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2937 SET_H2CCMD_DFTPID_PORT_ID(parm, adapter->hw_port);
2938 SET_H2CCMD_DFTPID_MAC_ID(parm, mac_id);
2940 RTW_DBG_DUMP("DFT port id parm:", parm, H2C_DEFAULT_PORT_ID_LEN);
2941 RTW_INFO("%s port_id :%d, mad_id:%d\n", __func__, adapter->hw_port, mac_id);
2943 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_DEFAULT_PORT_ID, H2C_DEFAULT_PORT_ID_LEN, parm);
2944 dvobj->default_port_id = adapter->hw_port;
2948 s32 rtw_set_default_port_id(_adapter *adapter)
2951 struct sta_info *psta;
2952 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2953 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2955 if (adapter->hw_port == dvobj->default_port_id)
2958 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
2959 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
2961 ret = rtw_hal_set_default_port_id_cmd(adapter, psta->mac_id);
2962 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
2969 s32 rtw_set_ps_rsvd_page(_adapter *adapter)
2972 u16 media_status_rpt = RT_MEDIA_CONNECT;
2973 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
2975 if (adapter->hw_port == dvobj->default_port_id)
2978 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
2979 (u8 *)&media_status_rpt);
2986 * rtw_hal_set_FwMediaStatusRpt_cmd -
2989 * @opmode: 0:disconnect, 1:connect
2990 * @miracast: 0:it's not in miracast scenario. 1:it's in miracast scenario
2991 * @miracast_sink: 0:source. 1:sink
2992 * @role: The role of this macid. 0:rsvd. 1:STA. 2:AP. 3:GC. 4:GO. 5:TDLS
2994 * @macid_ind: 0:update Media Status to macid. 1:update Media Status from macid to macid_end
2997 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)
2999 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
3000 u8 parm[H2C_MEDIA_STATUS_RPT_LEN] = {0};
3004 SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, opmode);
3005 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, macid_ind);
3006 SET_H2CCMD_MSRRPT_PARM_MIRACAST(parm, miracast);
3007 SET_H2CCMD_MSRRPT_PARM_MIRACAST_SINK(parm, miracast_sink);
3008 SET_H2CCMD_MSRRPT_PARM_ROLE(parm, role);
3009 SET_H2CCMD_MSRRPT_PARM_MACID(parm, macid);
3010 SET_H2CCMD_MSRRPT_PARM_MACID_END(parm, macid_end);
3011 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
3012 SET_H2CCMD_MSRRPT_PARM_PORT_NUM(parm, adapter->hw_port);
3014 RTW_DBG_DUMP("MediaStatusRpt parm:", parm, H2C_MEDIA_STATUS_RPT_LEN);
3016 #ifdef CONFIG_DFS_MASTER
3017 /* workaround for TXPAUSE cleared issue by FW's MediaStatusRpt handling */
3018 if (macid_ind == 0 && macid == 1
3019 && !rtw_odm_dfs_domain_unknown(adapter)
3021 u8 parm0_bak = parm[0];
3023 SET_H2CCMD_MSRRPT_PARM_MACID_IND(&parm0_bak, 0);
3024 if (macid_ctl->h2c_msr[macid] == parm0_bak) {
3031 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, parm);
3032 if (ret != _SUCCESS)
3035 #ifdef CONFIG_DFS_MASTER
3039 #if defined(CONFIG_RTL8188E)
3040 if (rtw_get_chip_type(adapter) == RTL8188E) {
3041 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
3043 /* 8188E FW doesn't set macid no link, driver does it by self */
3045 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_LINK, &macid);
3047 rtw_hal_set_hwreg(adapter, HW_VAR_MACID_NOLINK, &macid);
3050 #if (RATE_ADAPTIVE_SUPPORT == 1)
3051 if (hal_data->fw_ractrl == _FALSE) {
3054 max_macid = rtw_search_max_mac_id(adapter);
3055 rtw_hal_set_hwreg(adapter, HW_VAR_TX_RPT_MAX_MACID, &max_macid);
3061 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)
3062 /* TODO: this should move to IOT issue area */
3063 if (rtw_get_chip_type(adapter) == RTL8812
3064 || rtw_get_chip_type(adapter) == RTL8821
3066 if (MLME_IS_STA(adapter))
3067 Hal_PatchwithJaguar_8812(adapter, opmode);
3071 SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0);
3075 for (i = macid; macid <= macid_end; macid++) {
3076 rtw_macid_ctl_set_h2c_msr(macid_ctl, macid, parm[0]);
3078 rtw_macid_ctl_set_bw(macid_ctl, macid, CHANNEL_WIDTH_20);
3079 rtw_macid_ctl_set_vht_en(macid_ctl, macid, 0);
3080 rtw_macid_ctl_set_rate_bmp0(macid_ctl, macid, 0);
3081 rtw_macid_ctl_set_rate_bmp1(macid_ctl, macid, 0);
3085 rtw_update_tx_rate_bmp(adapter_to_dvobj(adapter));
3091 inline s32 rtw_hal_set_FwMediaStatusRpt_single_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid)
3093 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 0, 0);
3096 inline s32 rtw_hal_set_FwMediaStatusRpt_range_cmd(_adapter *adapter, bool opmode, bool miracast, bool miracast_sink, u8 role, u8 macid, u8 macid_end)
3098 return rtw_hal_set_FwMediaStatusRpt_cmd(adapter, opmode, miracast, miracast_sink, role, macid, 1, macid_end);
3101 void rtw_hal_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
3103 struct hal_ops *pHalFunc = &padapter->hal_func;
3104 u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};
3107 RTW_INFO("RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
3108 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
3109 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
3110 rsvdpageloc->LocBTQosNull);
3112 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
3113 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
3114 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
3115 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
3116 SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
3118 ret = rtw_hal_fill_h2c_cmd(padapter,
3120 H2C_RSVDPAGE_LOC_LEN,
3125 #ifdef CONFIG_GPIO_WAKEUP
3126 void rtw_hal_switch_gpio_wl_ctrl(_adapter *padapter, u8 index, u8 enable)
3128 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3130 if (IS_8723D_SERIES(pHalData->version_id) || IS_8822B_SERIES(pHalData->version_id))
3131 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
3133 * Switch GPIO_13, GPIO_14 to wlan control, or pull GPIO_13,14 MUST fail.
3134 * It happended at 8723B/8192E/8821A. New IC will check multi function GPIO,
3135 * and implement HAL function.
3136 * TODO: GPIO_8 multi function?
3139 if (index == 13 || index == 14)
3140 rtw_hal_set_hwreg(padapter, HW_SET_GPIO_WL_CTRL, (u8 *)(&enable));
3143 void rtw_hal_set_output_gpio(_adapter *padapter, u8 index, u8 outputval)
3146 /* config GPIO mode */
3147 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3,
3148 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
3150 /* config GPIO Sel */
3153 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2,
3154 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
3156 /* set output value */
3158 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
3159 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
3161 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1,
3162 rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
3164 } else if (index <= 15) {
3166 /* index: 11~8 transform to 3~0 */
3168 /* index: 12~8 transform to 4~0 */
3172 /* config GPIO mode */
3173 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3,
3174 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
3176 /* config GPIO Sel */
3179 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2,
3180 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
3182 /* set output value */
3184 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
3185 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
3187 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1,
3188 rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
3191 RTW_INFO("%s: invalid GPIO%d=%d\n",
3192 __FUNCTION__, index, outputval);
3197 void rtw_hal_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
3199 struct hal_ops *pHalFunc = &padapter->hal_func;
3200 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
3201 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3202 u8 res = 0, count = 0, ret = 0;
3203 #ifdef CONFIG_WOWLAN
3204 u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
3206 RTW_INFO("AOACRsvdPageLoc: RWC=%d ArpRsp=%d NbrAdv=%d GtkRsp=%d GtkInfo=%d ProbeReq=%d NetworkList=%d\n",
3207 rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp,
3208 rsvdpageloc->LocNbrAdv, rsvdpageloc->LocGTKRsp,
3209 rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq,
3210 rsvdpageloc->LocNetList);
3212 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
3213 SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
3214 SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
3215 /* SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, rsvdpageloc->LocNbrAdv); */
3216 #ifdef CONFIG_GTK_OL
3217 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
3218 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
3219 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
3220 #endif /* CONFIG_GTK_OL */
3221 ret = rtw_hal_fill_h2c_cmd(padapter,
3223 H2C_AOAC_RSVDPAGE_LOC_LEN,
3224 u1H2CAoacRsvdPageParm);
3226 RTW_INFO("AOAC Report=%d\n", rsvdpageloc->LocAOACReport);
3227 _rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
3228 SET_H2CCMD_AOAC_RSVDPAGE_LOC_AOAC_REPORT(u1H2CAoacRsvdPageParm,
3229 rsvdpageloc->LocAOACReport);
3230 ret = rtw_hal_fill_h2c_cmd(padapter,
3232 H2C_AOAC_RSVDPAGE_LOC_LEN,
3233 u1H2CAoacRsvdPageParm);
3234 pwrpriv->wowlan_aoac_rpt_loc = rsvdpageloc->LocAOACReport;
3236 #ifdef CONFIG_PNO_SUPPORT
3239 if (!pwrpriv->wowlan_in_resume) {
3240 RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
3241 _rtw_memset(&u1H2CAoacRsvdPageParm, 0,
3242 sizeof(u1H2CAoacRsvdPageParm));
3243 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm,
3244 rsvdpageloc->LocPNOInfo);
3245 ret = rtw_hal_fill_h2c_cmd(padapter,
3247 H2C_AOAC_RSVDPAGE_LOC_LEN,
3248 u1H2CAoacRsvdPageParm);
3251 #endif /* CONFIG_PNO_SUPPORT */
3252 #endif /* CONFIG_WOWLAN */
3255 /*#define DBG_GET_RSVD_PAGE*/
3256 int rtw_hal_get_rsvd_page(_adapter *adapter, u32 page_offset,
3257 u32 page_num, u8 *buffer, u32 buffer_size)
3259 u32 addr = 0, size = 0, count = 0;
3260 u32 page_size = 0, data_low = 0, data_high = 0;
3261 u16 txbndy = 0, offset = 0;
3265 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
3267 addr = page_offset * page_size;
3268 size = page_num * page_size;
3270 if (buffer_size < size) {
3271 RTW_ERR("%s buffer_size(%d) < get page total size(%d)\n",
3272 __func__, buffer_size, size);
3276 if (rtw_halmac_dump_fifo(adapter_to_dvobj(adapter), 2, addr, size, buffer) < 0)
3281 txbndy = rtw_read8(adapter, REG_TDECTRL + 1);
3283 offset = (txbndy + page_offset) << 4;
3284 count = (buffer_size / 8) + 1;
3286 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x69);
3288 for (i = 0 ; i < count ; i++) {
3289 rtw_write32(adapter, REG_PKTBUF_DBG_CTRL, offset + i);
3290 data_low = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
3291 data_high = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
3292 _rtw_memcpy(buffer + (i * 8),
3293 &data_low, sizeof(data_low));
3294 _rtw_memcpy(buffer + ((i * 8) + 4),
3295 &data_high, sizeof(data_high));
3297 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, 0x0);
3299 #endif /*RTW_HALMAC*/
3301 #ifdef DBG_GET_RSVD_PAGE
3302 RTW_INFO("%s [page_offset:%d , page_num:%d][start_addr:0x%04x , size:%d]\n",
3303 __func__, page_offset, page_num, addr, size);
3304 RTW_INFO_DUMP("\n", buffer, size);
3305 RTW_INFO(" ==================================================\n");
3310 void rtw_dump_rsvd_page(void *sel, _adapter *adapter, u8 page_offset, u8 page_num)
3319 RTW_PRINT_SEL(sel, "======= RSVG PAGE DUMP =======\n");
3320 RTW_PRINT_SEL(sel, "page_offset:%d, page_num:%d\n", page_offset, page_num);
3322 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
3324 buf_size = page_size * page_num;
3325 buffer = rtw_zvmalloc(buf_size);
3328 rtw_hal_get_rsvd_page(adapter, page_offset, page_num, buffer, buf_size);
3329 _RTW_DUMP_SEL(sel, buffer, buf_size);
3330 rtw_vmfree(buffer, buf_size);
3332 RTW_PRINT_SEL(sel, "ERROR - rsvd_buf mem allocate failed\n");
3334 RTW_PRINT_SEL(sel, "ERROR - Tx page size is zero ??\n");
3336 RTW_PRINT_SEL(sel, "==========================\n");
3339 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
3340 static void rtw_hal_force_enable_rxdma(_adapter *adapter)
3342 RTW_INFO("%s: Set 0x690=0x00\n", __func__);
3343 rtw_write8(adapter, REG_WOW_CTRL,
3344 (rtw_read8(adapter, REG_WOW_CTRL) & 0xf0));
3345 RTW_PRINT("%s: Release RXDMA\n", __func__);
3346 rtw_write32(adapter, REG_RXPKT_NUM,
3347 (rtw_read32(adapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
3349 #if defined(CONFIG_RTL8188E)
3350 static void rtw_hal_disable_tx_report(_adapter *adapter)
3352 rtw_write8(adapter, REG_TX_RPT_CTRL,
3353 ((rtw_read8(adapter, REG_TX_RPT_CTRL) & ~BIT(1))) & ~BIT(5));
3354 RTW_INFO("disable TXRPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
3357 static void rtw_hal_enable_tx_report(_adapter *adapter)
3359 rtw_write8(adapter, REG_TX_RPT_CTRL,
3360 ((rtw_read8(adapter, REG_TX_RPT_CTRL) | BIT(1))) | BIT(5));
3361 RTW_INFO("enable TX_RPT:0x%02x\n", rtw_read8(adapter, REG_TX_RPT_CTRL));
3364 static void rtw_hal_release_rx_dma(_adapter *adapter)
3368 val32 = rtw_read32(adapter, REG_RXPKT_NUM);
3370 rtw_write32(adapter, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
3372 RTW_INFO("%s, [0x%04x]: 0x%08x\n",
3373 __func__, REG_RXPKT_NUM, (val32 & (~RW_RELEASE_EN)));
3376 static u8 rtw_hal_pause_rx_dma(_adapter *adapter)
3378 PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
3384 RTW_PRINT("Pause DMA\n");
3385 rtw_write32(adapter, REG_RXPKT_NUM,
3386 (rtw_read32(adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
3388 if ((rtw_read32(adapter, REG_RXPKT_NUM) & RXDMA_IDLE)) {
3389 #ifdef CONFIG_USB_HCI
3390 /* stop interface before leave */
3391 if (_TRUE == hal->usb_intf_start) {
3392 rtw_intf_stop(adapter);
3393 RTW_ENABLE_FUNC(adapter, DF_RX_BIT);
3394 RTW_ENABLE_FUNC(adapter, DF_TX_BIT);
3396 #endif /* CONFIG_USB_HCI */
3398 RTW_PRINT("RX_DMA_IDLE is true\n");
3402 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3404 res = RecvOnePkt(adapter);
3405 RTW_PRINT("RecvOnePkt Result: %d\n", res);
3407 #endif /* CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
3409 #ifdef CONFIG_USB_HCI
3411 /* to avoid interface start repeatedly */
3412 if (_FALSE == hal->usb_intf_start)
3413 rtw_intf_start(adapter);
3415 #endif /* CONFIG_USB_HCI */
3419 tmp = rtw_read16(adapter, REG_RXPKT_NUM + 3);
3421 RTW_PRINT("Stop RX DMA failed......\n");
3422 RTW_PRINT("%s, RXPKT_NUM: 0x%04x\n",
3424 tmp = rtw_read16(adapter, REG_RXPKT_NUM + 2);
3426 RTW_PRINT("%s, RX DMA has req\n",
3429 RTW_PRINT("%s, RX DMA no req\n",
3437 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3439 static u8 rtw_hal_enable_cpwm2(_adapter *adapter)
3444 #ifdef CONFIG_GPIO_WAKEUP
3447 RTW_PRINT("%s\n", __func__);
3449 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
3451 RTW_INFO("read SDIO_REG_HIMR: 0x%08x\n", tmp);
3453 RTW_INFO("sdio_local_read fail\n");
3455 tmp = SDIO_HIMR_CPWM2_MSK;
3457 res = sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
3460 res = sdio_local_read(adapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
3461 RTW_INFO("read again SDIO_REG_HIMR: 0x%08x\n", tmp);
3464 RTW_INFO("sdio_local_write fail\n");
3468 #endif /* CONFIG_CPIO_WAKEUP */
3471 #endif /* CONFIG_SDIO_HCI, CONFIG_GSPI_HCI */
3472 #endif /* CONFIG_WOWLAN || CONFIG_AP_WOWLAN */
3474 #ifdef CONFIG_WOWLAN
3476 * rtw_hal_check_wow_ctrl
3477 * chk_type: _TRUE means to check enable, if 0x690 & bit1, WOW enable successful
3478 * _FALSE means to check disable, if 0x690 & bit1, WOW disable fail
3480 static u8 rtw_hal_check_wow_ctrl(_adapter *adapter, u8 chk_type)
3486 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
3487 RTW_INFO("%s mstatus:0x%02x\n", __func__, mstatus);
3490 while (!(mstatus & BIT1) && trycnt > 1) {
3491 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
3492 RTW_PRINT("Loop index: %d :0x%02x\n",
3502 while (mstatus & BIT1 && trycnt > 1) {
3503 mstatus = rtw_read8(adapter, REG_WOW_CTRL);
3504 RTW_PRINT("Loop index: %d :0x%02x\n",
3515 RTW_PRINT("%s check_type: %d res: %d trycnt: %d\n",
3516 __func__, chk_type, res, (25 - trycnt));
3520 #ifdef CONFIG_PNO_SUPPORT
3521 static u8 rtw_hal_check_pno_enabled(_adapter *adapter)
3523 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
3524 u8 res = 0, count = 0;
3527 if (ppwrpriv->wowlan_pno_enable && ppwrpriv->wowlan_in_resume == _FALSE) {
3528 res = rtw_read8(adapter, REG_PNO_STATUS);
3529 while (!(res & BIT(7)) && count < 25) {
3530 RTW_INFO("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n",
3532 res = rtw_read8(adapter, REG_PNO_STATUS);
3540 RTW_INFO("cmd: 0x81 REG_PNO_STATUS: ret(%d)\n", ret);
3546 static void rtw_hal_backup_rate(_adapter *adapter)
3548 RTW_INFO("%s\n", __func__);
3549 /* backup data rate to register 0x8b for wowlan FW */
3550 rtw_write8(adapter, 0x8d, 1);
3551 rtw_write8(adapter, 0x8c, 0);
3552 rtw_write8(adapter, 0x8f, 0x40);
3553 rtw_write8(adapter, 0x8b, rtw_read8(adapter, 0x2f0));
3556 #ifdef CONFIG_GTK_OL
3557 static void rtw_hal_fw_sync_cam_id(_adapter *adapter)
3559 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3560 int cam_id, index = 0;
3563 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3566 addr = get_bssid(pmlmepriv);
3569 RTW_INFO("%s: get bssid MAC addr fail!!\n", __func__);
3573 rtw_clean_dk_section(adapter);
3576 cam_id = rtw_camid_search(adapter, addr, index, 1);
3579 RTW_INFO("%s: cam_id: %d, key_id:%d\n", __func__, cam_id, index);
3581 rtw_sec_cam_swap(adapter, cam_id, index);
3584 } while (index < 4);
3586 rtw_write8(adapter, REG_SECCFG, 0xcc);
3589 static void rtw_dump_aoac_rpt(_adapter *adapter)
3591 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
3592 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
3594 RTW_INFO_DUMP("[AOAC-RPT] IV -", paoac_rpt->iv, 8);
3595 RTW_INFO_DUMP("[AOAC-RPT] Replay counter of EAPOL key - ",
3596 paoac_rpt->replay_counter_eapol_key, 8);
3597 RTW_INFO_DUMP("[AOAC-RPT] Group key - ", paoac_rpt->group_key, 32);
3598 RTW_INFO("[AOAC-RPT] Key Index - %d\n", paoac_rpt->key_index);
3599 RTW_INFO("[AOAC-RPT] Security Type - %d\n", paoac_rpt->security_type);
3602 static void rtw_hal_get_aoac_rpt(_adapter *adapter)
3604 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
3605 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
3606 u32 page_offset = 0, page_number = 0;
3607 u32 page_size = 0, buf_size = 0;
3612 /* read aoac report from rsvd page */
3613 page_offset = pwrctl->wowlan_aoac_rpt_loc;
3616 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, &page_size);
3617 buf_size = page_size * page_number;
3619 buffer = rtw_zvmalloc(buf_size);
3621 if (NULL == buffer) {
3622 RTW_ERR("%s buffer allocate failed size(%d)\n",
3623 __func__, buf_size);
3627 RTW_INFO("Get AOAC Report from rsvd page_offset:%d\n", page_offset);
3629 ret = rtw_hal_get_rsvd_page(adapter, page_offset,
3630 page_number, buffer, buf_size);
3632 if (ret == _FALSE) {
3633 RTW_ERR("%s get aoac report failed\n", __func__);
3638 _rtw_memset(paoac_rpt, 0, sizeof(struct aoac_report));
3639 _rtw_memcpy(paoac_rpt, buffer, sizeof(struct aoac_report));
3641 for (i = 0 ; i < 4 ; i++) {
3642 tmp = paoac_rpt->replay_counter_eapol_key[i];
3643 paoac_rpt->replay_counter_eapol_key[i] =
3644 paoac_rpt->replay_counter_eapol_key[7 - i];
3645 paoac_rpt->replay_counter_eapol_key[7 - i] = tmp;
3648 /* rtw_dump_aoac_rpt(adapter); */
3652 rtw_vmfree(buffer, buf_size);
3655 static void rtw_hal_update_gtk_offload_info(_adapter *adapter)
3657 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
3658 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
3659 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3660 struct security_priv *psecuritypriv = &adapter->securitypriv;
3661 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
3662 struct cam_ctl_t *cam_ctl = &dvobj->cam_ctl;
3665 u8 gtk_id = 0, offset = 0;
3666 u64 replay_count = 0;
3668 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
3671 _rtw_memset(get_key, 0, sizeof(get_key));
3672 _rtw_memcpy(&replay_count,
3673 paoac_rpt->replay_counter_eapol_key, 8);
3675 /*read gtk key index*/
3676 gtk_id = paoac_rpt->key_index;
3678 if (gtk_id == 5 || gtk_id == 0) {
3679 RTW_INFO("%s no rekey event happened.\n", __func__);
3680 } else if (gtk_id > 0 && gtk_id < 4) {
3681 RTW_INFO("%s update security key.\n", __func__);
3682 /*read key from sec-cam,for DK ,keyindex is equal to cam-id*/
3683 rtw_sec_read_cam_ent(adapter, gtk_id,
3684 NULL, NULL, get_key);
3685 rtw_clean_hw_dk_cam(adapter);
3687 if (_rtw_camid_is_gk(adapter, gtk_id)) {
3688 _enter_critical_bh(&cam_ctl->lock, &irqL);
3689 _rtw_memcpy(&dvobj->cam_cache[gtk_id].key,
3691 _exit_critical_bh(&cam_ctl->lock, &irqL);
3693 struct setkey_parm parm_gtk;
3695 parm_gtk.algorithm = paoac_rpt->security_type;
3696 parm_gtk.keyid = gtk_id;
3697 _rtw_memcpy(parm_gtk.key, get_key, 16);
3698 setkey_hdl(adapter, (u8 *)&parm_gtk);
3701 /*update key into related sw variable and sec-cam cache*/
3702 psecuritypriv->dot118021XGrpKeyid = gtk_id;
3703 _rtw_memcpy(&psecuritypriv->dot118021XGrpKey[gtk_id],
3705 /* update SW TKIP TX/RX MIC value */
3706 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
3707 offset = RTW_KEK_LEN + RTW_TKIP_MIC_LEN;
3709 &psecuritypriv->dot118021XGrptxmickey[gtk_id],
3710 &(paoac_rpt->group_key[offset]),
3713 offset = RTW_KEK_LEN;
3715 &psecuritypriv->dot118021XGrprxmickey[gtk_id],
3716 &(paoac_rpt->group_key[offset]),
3720 RTW_PRINT("GTK (%d) "KEY_FMT"\n", gtk_id,
3721 KEY_ARG(psecuritypriv->dot118021XGrpKey[gtk_id].skey));
3724 rtw_clean_dk_section(adapter);
3726 rtw_write8(adapter, REG_SECCFG, 0x0c);
3728 #ifdef CONFIG_GTK_OL_DBG
3729 /* if (gtk_keyindex != 5) */
3730 dump_sec_cam(RTW_DBGDUMP, adapter);
3731 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
3735 static void rtw_hal_update_tx_iv(_adapter *adapter)
3737 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
3738 struct aoac_report *paoac_rpt = &pwrctl->wowlan_aoac_rpt;
3739 struct sta_info *psta;
3740 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
3741 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3742 struct security_priv *psecpriv = &adapter->securitypriv;
3749 psta = rtw_get_stainfo(&adapter->stapriv,
3750 get_my_bssid(&pmlmeinfo->network));
3752 /* Update TX iv data. */
3753 pval = (u8 *)&paoac_rpt->iv;
3755 if (psecpriv->dot11PrivacyAlgrthm == _TKIP_) {
3756 val16 = ((u16)(paoac_rpt->iv[2]) << 0) +
3757 ((u16)(paoac_rpt->iv[0]) << 8);
3758 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
3759 ((u32)(paoac_rpt->iv[5]) << 8) +
3760 ((u32)(paoac_rpt->iv[6]) << 16) +
3761 ((u32)(paoac_rpt->iv[7]) << 24);
3762 } else if (psecpriv->dot11PrivacyAlgrthm == _AES_) {
3763 val16 = ((u16)(paoac_rpt->iv[0]) << 0) +
3764 ((u16)(paoac_rpt->iv[1]) << 8);
3765 val32 = ((u32)(paoac_rpt->iv[4]) << 0) +
3766 ((u32)(paoac_rpt->iv[5]) << 8) +
3767 ((u32)(paoac_rpt->iv[6]) << 16) +
3768 ((u32)(paoac_rpt->iv[7]) << 24);
3772 txiv = val16 + ((u64)val32 << 16);
3774 psta->dot11txpn.val = txiv;
3778 static void rtw_hal_update_sw_security_info(_adapter *adapter)
3780 rtw_hal_update_tx_iv(adapter);
3781 rtw_hal_update_gtk_offload_info(adapter);
3783 #endif /*CONFIG_GTK_OL*/
3785 static u8 rtw_hal_set_keep_alive_cmd(_adapter *adapter, u8 enable, u8 pkt_type)
3787 struct hal_ops *pHalFunc = &adapter->hal_func;
3789 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN] = {0};
3790 u8 adopt = 1, check_period = 5;
3793 SET_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, enable);
3794 SET_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
3795 SET_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
3796 SET_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
3797 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
3798 SET_H2CCMD_KEEPALIVE_PARM_PORT_NUM(u1H2CKeepAliveParm, adapter->hw_port);
3799 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, adapter->hw_port);
3801 RTW_INFO("%s(): enable = %d\n", __func__, enable);
3803 ret = rtw_hal_fill_h2c_cmd(adapter,
3805 H2C_KEEP_ALIVE_CTRL_LEN,
3806 u1H2CKeepAliveParm);
3811 static u8 rtw_hal_set_disconnect_decision_cmd(_adapter *adapter, u8 enable)
3813 struct hal_ops *pHalFunc = &adapter->hal_func;
3814 u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN] = {0};
3815 u8 adopt = 1, check_period = 10, trypkt_num = 0;
3818 SET_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, enable);
3819 SET_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
3820 SET_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
3821 SET_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
3822 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
3823 SET_H2CCMD_DISCONDECISION_PORT_NUM(u1H2CDisconDecisionParm, adapter->hw_port);
3824 RTW_INFO("%s(): enable = %d, port = %d\n", __func__, enable, adapter->hw_port);
3826 RTW_INFO("%s(): enable = %d\n", __func__, enable);
3829 ret = rtw_hal_fill_h2c_cmd(adapter,
3830 H2C_DISCON_DECISION,
3831 H2C_DISCON_DECISION_LEN,
3832 u1H2CDisconDecisionParm);
3836 static u8 rtw_hal_set_wowlan_ctrl_cmd(_adapter *adapter, u8 enable, u8 change_unit)
3838 struct security_priv *psecpriv = &adapter->securitypriv;
3839 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
3840 struct hal_ops *pHalFunc = &adapter->hal_func;
3842 u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN] = {0};
3843 u8 discont_wake = 1, gpionum = 0, gpio_dur = 0;
3844 u8 hw_unicast = 0, gpio_pulse_cnt = 0, gpio_pulse_en = 0;
3845 u8 sdio_wakeup_enable = 1;
3846 u8 gpio_high_active = 0;
3848 u8 gpio_unit = 0; /*0: 64ns, 1: 8ms*/
3851 #ifdef CONFIG_GPIO_WAKEUP
3852 gpio_high_active = ppwrpriv->is_high_active;
3853 gpionum = WAKEUP_GPIO_IDX;
3854 sdio_wakeup_enable = 0;
3855 #endif /* CONFIG_GPIO_WAKEUP */
3857 if (!ppwrpriv->wowlan_pno_enable)
3860 if (psecpriv->dot11PrivacyAlgrthm == _WEP40_ || psecpriv->dot11PrivacyAlgrthm == _WEP104_)
3865 RTW_INFO("%s(): enable=%d change_unit=%d\n", __func__,
3866 enable, change_unit);
3868 /* time = (gpio_dur/2) * gpio_unit, default:256 ms */
3869 if (enable && change_unit) {
3875 #ifdef CONFIG_PLATFORM_ARM_RK3188
3878 gpio_pulse_cnt = 0x04;
3882 SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, enable);
3883 SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, enable);
3884 SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
3885 SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
3886 SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
3887 SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
3889 #ifdef CONFIG_GTK_OL
3890 /* GTK rekey only for AES, if GTK rekey is TKIP, then wake up*/
3891 if (psecpriv->binstallKCK_KEK == _TRUE)
3892 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 0);
3894 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, 1);
3896 SET_H2CCMD_WOWLAN_REKEY_WAKE_UP(u1H2CWoWlanCtrlParm, enable);
3898 SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
3899 SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
3900 SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
3902 SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
3903 SET_H2CCMD_WOWLAN_CHANGE_UNIT(u1H2CWoWlanCtrlParm, gpio_unit);
3905 SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, gpio_pulse_en);
3906 SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, gpio_pulse_cnt);
3908 ret = rtw_hal_fill_h2c_cmd(adapter,
3911 u1H2CWoWlanCtrlParm);
3915 static u8 rtw_hal_set_remote_wake_ctrl_cmd(_adapter *adapter, u8 enable)
3917 struct hal_ops *pHalFunc = &adapter->hal_func;
3918 struct security_priv *psecuritypriv = &(adapter->securitypriv);
3919 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
3920 struct registry_priv *pregistrypriv = &adapter->registrypriv;
3921 u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN] = {0};
3922 u8 ret = _FAIL, count = 0;
3924 RTW_INFO("%s(): enable=%d\n", __func__, enable);
3926 if (!ppwrpriv->wowlan_pno_enable) {
3927 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
3928 u1H2CRemoteWakeCtrlParm, enable);
3929 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(
3930 u1H2CRemoteWakeCtrlParm, 1);
3931 #ifdef CONFIG_GTK_OL
3932 if (psecuritypriv->binstallKCK_KEK == _TRUE) {
3933 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
3934 u1H2CRemoteWakeCtrlParm, 1);
3936 RTW_INFO("no kck kek\n");
3937 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(
3938 u1H2CRemoteWakeCtrlParm, 0);
3940 #endif /* CONFIG_GTK_OL */
3942 if (pregistrypriv->default_patterns_en == _FALSE) {
3943 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(
3944 u1H2CRemoteWakeCtrlParm, enable);
3946 * filter NetBios name service pkt to avoid being waked-up
3947 * by this kind of unicast pkt this exceptional modification
3948 * is used for match competitor's behavior
3950 SET_H2CCMD_REMOTE_WAKE_CTRL_NBNS_FILTER_EN(
3951 u1H2CRemoteWakeCtrlParm, enable);
3954 if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
3955 (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
3956 (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_)) {
3957 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
3958 u1H2CRemoteWakeCtrlParm, 0);
3960 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
3961 u1H2CRemoteWakeCtrlParm, 1);
3964 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
3965 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
3966 u1H2CRemoteWakeCtrlParm, enable);
3968 if (IS_HARDWARE_TYPE_8188E(adapter) ||
3969 IS_HARDWARE_TYPE_8812(adapter)) {
3970 SET_H2CCMD_REMOTE_WAKE_CTRL_TKIP_OFFLOAD_EN(
3971 u1H2CRemoteWakeCtrlParm, 0);
3972 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(
3973 u1H2CRemoteWakeCtrlParm, 1);
3977 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_PARSING_UNTIL_WAKEUP(
3978 u1H2CRemoteWakeCtrlParm, 1);
3980 #ifdef CONFIG_PNO_SUPPORT
3982 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(
3983 u1H2CRemoteWakeCtrlParm, enable);
3984 SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(
3985 u1H2CRemoteWakeCtrlParm, enable);
3989 #ifdef CONFIG_P2P_WOWLAN
3990 if (_TRUE == ppwrpriv->wowlan_p2p_mode) {
3991 RTW_INFO("P2P OFFLOAD ENABLE\n");
3992 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 1);
3994 RTW_INFO("P2P OFFLOAD DISABLE\n");
3995 SET_H2CCMD_REMOTE_WAKE_CTRL_P2P_OFFLAD_EN(u1H2CRemoteWakeCtrlParm, 0);
3997 #endif /* CONFIG_P2P_WOWLAN */
4000 ret = rtw_hal_fill_h2c_cmd(adapter,
4001 H2C_REMOTE_WAKE_CTRL,
4002 H2C_REMOTE_WAKE_CTRL_LEN,
4003 u1H2CRemoteWakeCtrlParm);
4007 static u8 rtw_hal_set_global_info_cmd(_adapter *adapter, u8 group_alg, u8 pairwise_alg)
4009 struct hal_ops *pHalFunc = &adapter->hal_func;
4011 u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN] = {0};
4013 RTW_INFO("%s(): group_alg=%d pairwise_alg=%d\n",
4014 __func__, group_alg, pairwise_alg);
4015 SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm,
4017 SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm,
4020 ret = rtw_hal_fill_h2c_cmd(adapter,
4021 H2C_AOAC_GLOBAL_INFO,
4022 H2C_AOAC_GLOBAL_INFO_LEN,
4023 u1H2CAOACGlobalInfoParm);
4028 #ifdef CONFIG_PNO_SUPPORT
4029 static u8 rtw_hal_set_scan_offload_info_cmd(_adapter *adapter,
4030 PRSVDPAGE_LOC rsvdpageloc, u8 enable)
4032 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
4033 struct hal_ops *pHalFunc = &adapter->hal_func;
4035 u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN] = {0};
4036 u8 res = 0, count = 0, ret = _FAIL;
4038 RTW_INFO("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
4039 __func__, rsvdpageloc->LocProbePacket,
4040 rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
4042 SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
4043 SET_H2CCMD_AOAC_NLO_IPS_EN(u1H2CScanOffloadInfoParm, enable);
4044 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm,
4045 rsvdpageloc->LocScanInfo);
4046 SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm,
4047 rsvdpageloc->LocProbePacket);
4049 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm,
4050 rsvdpageloc->LocSSIDInfo);
4052 ret = rtw_hal_fill_h2c_cmd(adapter,
4053 H2C_D0_SCAN_OFFLOAD_INFO,
4054 H2C_SCAN_OFFLOAD_CTRL_LEN,
4055 u1H2CScanOffloadInfoParm);
4058 #endif /* CONFIG_PNO_SUPPORT */
4060 void rtw_hal_set_fw_wow_related_cmd(_adapter *padapter, u8 enable)
4062 struct security_priv *psecpriv = &padapter->securitypriv;
4063 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
4064 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4065 struct sta_info *psta = NULL;
4066 u16 media_status_rpt;
4070 RTW_PRINT("+%s()+: enable=%d\n", __func__, enable);
4072 rtw_hal_set_wowlan_ctrl_cmd(padapter, enable, _FALSE);
4075 rtw_hal_set_global_info_cmd(padapter,
4076 psecpriv->dot118021XGrpPrivacy,
4077 psecpriv->dot11PrivacyAlgrthm);
4079 if (!(ppwrpriv->wowlan_pno_enable)) {
4080 rtw_hal_set_disconnect_decision_cmd(padapter, enable);
4081 #ifdef CONFIG_ARP_KEEP_ALIVE
4082 if ((psecpriv->dot11PrivacyAlgrthm == _WEP40_) ||
4083 (psecpriv->dot11PrivacyAlgrthm == _WEP104_))
4089 #endif /* CONFIG_ARP_KEEP_ALIVE */
4090 rtw_hal_set_keep_alive_cmd(padapter, enable, pkt_type);
4092 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
4093 #ifdef CONFIG_PNO_SUPPORT
4094 rtw_hal_check_pno_enabled(padapter);
4095 #endif /* CONFIG_PNO_SUPPORT */
4100 rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
4101 dump_TX_FIFO(padapter, 4, PageSize);
4105 rtw_hal_set_remote_wake_ctrl_cmd(padapter, enable);
4107 RTW_PRINT("-%s()-\n", __func__);
4109 #endif /* CONFIG_WOWLAN */
4111 #ifdef CONFIG_AP_WOWLAN
4112 static u8 rtw_hal_set_ap_wowlan_ctrl_cmd(_adapter *adapter, u8 enable)
4114 struct security_priv *psecpriv = &adapter->securitypriv;
4115 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(adapter);
4116 struct hal_ops *pHalFunc = &adapter->hal_func;
4118 u8 u1H2CAPWoWlanCtrlParm[H2C_AP_WOW_GPIO_CTRL_LEN] = {0};
4119 u8 gpionum = 0, gpio_dur = 0;
4120 u8 gpio_pulse = enable;
4121 u8 sdio_wakeup_enable = 1;
4122 u8 gpio_high_active = 0;
4125 #ifdef CONFIG_GPIO_WAKEUP
4126 gpio_high_active = ppwrpriv->is_high_active;
4127 gpionum = WAKEUP_GPIO_IDX;
4128 sdio_wakeup_enable = 0;
4129 #endif /*CONFIG_GPIO_WAKEUP*/
4131 RTW_INFO("%s(): enable=%d\n", __func__, enable);
4133 SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
4135 SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
4137 SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
4139 SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
4141 SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
4144 ret = rtw_hal_fill_h2c_cmd(adapter,
4145 H2C_AP_WOW_GPIO_CTRL,
4146 H2C_AP_WOW_GPIO_CTRL_LEN,
4147 u1H2CAPWoWlanCtrlParm);
4152 static u8 rtw_hal_set_ap_offload_ctrl_cmd(_adapter *adapter, u8 enable)
4154 struct hal_ops *pHalFunc = &adapter->hal_func;
4155 u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN] = {0};
4158 RTW_INFO("%s(): bFuncEn=%d\n", __func__, enable);
4160 SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, enable);
4162 ret = rtw_hal_fill_h2c_cmd(adapter,
4165 u1H2CAPOffloadCtrlParm);
4170 static u8 rtw_hal_set_ap_ps_cmd(_adapter *adapter, u8 enable)
4172 struct hal_ops *pHalFunc = &adapter->hal_func;
4173 u8 ap_ps_parm[H2C_AP_PS_LEN] = {0};
4176 RTW_INFO("%s(): enable=%d\n" , __func__ , enable);
4178 SET_H2CCMD_AP_WOW_PS_EN(ap_ps_parm, enable);
4179 #ifndef CONFIG_USB_HCI
4180 SET_H2CCMD_AP_WOW_PS_32K_EN(ap_ps_parm, enable);
4181 #endif /*CONFIG_USB_HCI*/
4182 SET_H2CCMD_AP_WOW_PS_RF(ap_ps_parm, enable);
4185 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x32);
4187 SET_H2CCMD_AP_WOW_PS_DURATION(ap_ps_parm, 0x0);
4189 ret = rtw_hal_fill_h2c_cmd(adapter, H2C_SAP_PS_,
4190 H2C_AP_PS_LEN, ap_ps_parm);
4195 static void rtw_hal_set_ap_rsvdpage_loc_cmd(PADAPTER padapter,
4196 PRSVDPAGE_LOC rsvdpageloc)
4198 struct hal_ops *pHalFunc = &padapter->hal_func;
4199 u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};
4200 u8 ret = _FAIL, header = 0;
4202 if (pHalFunc->fill_h2c_cmd == NULL) {
4203 RTW_INFO("%s: Please hook fill_h2c_cmd first!\n", __func__);
4207 header = rtw_read8(padapter, REG_BCNQ_BDNY);
4209 RTW_INFO("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
4210 rsvdpageloc->LocApOffloadBCN,
4211 rsvdpageloc->LocProbeRsp,
4214 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
4215 rsvdpageloc->LocApOffloadBCN + header);
4217 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_BCN_RSVDPAGE,
4218 H2C_BCN_RSVDPAGE_LEN, rsvdparm);
4221 RTW_INFO("%s: H2C_BCN_RSVDPAGE cmd fail\n", __func__);
4225 _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
4227 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(rsvdparm,
4228 rsvdpageloc->LocProbeRsp + header);
4230 ret = rtw_hal_fill_h2c_cmd(padapter, H2C_PROBERSP_RSVDPAGE,
4231 H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
4234 RTW_INFO("%s: H2C_PROBERSP_RSVDPAGE cmd fail\n", __func__);
4239 static void rtw_hal_set_fw_ap_wow_related_cmd(_adapter *padapter, u8 enable)
4241 rtw_hal_set_ap_offload_ctrl_cmd(padapter, enable);
4242 rtw_hal_set_ap_wowlan_ctrl_cmd(padapter, enable);
4243 rtw_hal_set_ap_ps_cmd(padapter, enable);
4246 static void rtw_hal_ap_wow_enable(_adapter *padapter)
4248 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4249 struct security_priv *psecuritypriv = &padapter->securitypriv;
4250 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4251 struct hal_ops *pHalFunc = &padapter->hal_func;
4252 struct sta_info *psta = NULL;
4253 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4254 #ifdef DBG_CHECK_FW_PS_STATE
4255 struct dvobj_priv *psdpriv = padapter->dvobj;
4256 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
4257 #endif /*DBG_CHECK_FW_PS_STATE*/
4259 u16 media_status_rpt;
4261 RTW_INFO("%s, WOWLAN_AP_ENABLE\n", __func__);
4262 #ifdef DBG_CHECK_FW_PS_STATE
4263 if (rtw_fw_ps_state(padapter) == _FAIL) {
4264 pdbgpriv->dbg_enwow_dload_fw_fail_cnt++;
4265 RTW_PRINT("wowlan enable no leave 32k\n");
4267 #endif /*DBG_CHECK_FW_PS_STATE*/
4269 /* 1. Download WOWLAN FW*/
4270 rtw_hal_fw_dl(padapter, _TRUE);
4272 media_status_rpt = RT_MEDIA_CONNECT;
4273 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
4274 (u8 *)&media_status_rpt);
4276 issue_beacon(padapter, 0);
4279 #if defined(CONFIG_RTL8188E)
4280 if (IS_HARDWARE_TYPE_8188E(padapter))
4281 rtw_hal_disable_tx_report(padapter);
4284 res = rtw_hal_pause_rx_dma(padapter);
4286 RTW_PRINT("[WARNING] pause RX DMA fail\n");
4288 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
4289 /* Enable CPWM2 only. */
4290 res = rtw_hal_enable_cpwm2(padapter);
4292 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
4295 #ifdef CONFIG_GPIO_WAKEUP
4296 rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _TRUE);
4298 /* 5. Set Enable WOWLAN H2C command. */
4299 RTW_PRINT("Set Enable AP WOWLan cmd\n");
4300 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 1);
4302 rtw_write8(padapter, REG_MCUTST_WOWLAN, 0);
4303 #ifdef CONFIG_USB_HCI
4304 rtw_mi_intf_stop(padapter);
4305 /* Invoid SE0 reset signal during suspending*/
4306 rtw_write8(padapter, REG_RSV_CTRL, 0x20);
4307 if (IS_8188F(pHalData->version_id) == FALSE)
4308 rtw_write8(padapter, REG_RSV_CTRL, 0x60);
4309 #endif /*CONFIG_USB_HCI*/
4312 static void rtw_hal_ap_wow_disable(_adapter *padapter)
4314 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
4315 struct hal_ops *pHalFunc = &padapter->hal_func;
4316 #ifdef DBG_CHECK_FW_PS_STATE
4317 struct dvobj_priv *psdpriv = padapter->dvobj;
4318 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
4319 #endif /*DBG_CHECK_FW_PS_STATE*/
4320 u16 media_status_rpt;
4323 RTW_INFO("%s, WOWLAN_AP_DISABLE\n", __func__);
4324 /* 1. Read wakeup reason*/
4325 pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_MCUTST_WOWLAN);
4327 RTW_PRINT("wakeup_reason: 0x%02x\n",
4328 pwrctl->wowlan_wake_reason);
4330 rtw_hal_set_fw_ap_wow_related_cmd(padapter, 0);
4333 #ifdef DBG_CHECK_FW_PS_STATE
4334 if (rtw_fw_ps_state(padapter) == _FAIL) {
4335 pdbgpriv->dbg_diswow_dload_fw_fail_cnt++;
4336 RTW_PRINT("wowlan enable no leave 32k\n");
4338 #endif /*DBG_CHECK_FW_PS_STATE*/
4340 #if defined(CONFIG_RTL8188E)
4341 if (IS_HARDWARE_TYPE_8188E(padapter))
4342 rtw_hal_enable_tx_report(padapter);
4345 rtw_hal_force_enable_rxdma(padapter);
4347 rtw_hal_fw_dl(padapter, _FALSE);
4349 #ifdef CONFIG_GPIO_WAKEUP
4350 val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
4351 RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
4352 rtw_hal_set_output_gpio(padapter, WAKEUP_GPIO_IDX, val8);
4354 rtw_hal_switch_gpio_wl_ctrl(padapter, WAKEUP_GPIO_IDX, _FALSE);
4356 media_status_rpt = RT_MEDIA_CONNECT;
4358 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT,
4359 (u8 *)&media_status_rpt);
4361 issue_beacon(padapter, 0);
4363 #endif /*CONFIG_AP_WOWLAN*/
4365 #ifdef CONFIG_P2P_WOWLAN
4366 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
4372 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
4374 /* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
4376 if (ssid_ie && ssid_len_ori > 0) {
4377 switch (hidden_ssid_mode) {
4379 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
4382 remain_len = ies_len - (next_ie - ies);
4385 _rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
4386 len_diff -= ssid_len_ori;
4391 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
4401 static void rtw_hal_construct_P2PBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
4403 /* struct xmit_frame *pmgntframe; */
4404 /* struct pkt_attrib *pattrib; */
4405 /* unsigned char *pframe; */
4406 struct rtw_ieee80211_hdr *pwlanhdr;
4407 unsigned short *fctrl;
4408 unsigned int rate_len;
4409 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4411 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
4413 * struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4414 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
4415 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4416 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4417 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4418 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
4419 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4421 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4422 #endif /* CONFIG_P2P */
4425 u8 *dbgbuf = pframe;
4426 u8 dbgbufLen = 0, index = 0;
4428 RTW_INFO("%s\n", __FUNCTION__);
4429 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
4430 /* _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
4431 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
4433 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4436 fctrl = &(pwlanhdr->frame_ctl);
4439 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
4440 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4441 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
4443 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
4444 /* pmlmeext->mgnt_seq++; */
4445 set_frame_sub_type(pframe, WIFI_BEACON);
4447 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4448 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4450 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
4451 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
4453 /* for P2P : Primary Device Type & Device Name */
4454 u32 wpsielen = 0, insert_len = 0;
4456 wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
4458 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
4459 uint wps_offset, remainder_ielen;
4460 u8 *premainder_ie, *pframe_wscie;
4462 wps_offset = (uint)(wpsie - cur_network->IEs);
4464 premainder_ie = wpsie + wpsielen;
4466 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
4468 #ifdef CONFIG_IOCTL_CFG80211
4469 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
4470 if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
4471 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
4472 pframe += wps_offset;
4473 pktlen += wps_offset;
4475 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
4476 pframe += pmlmepriv->wps_beacon_ie_len;
4477 pktlen += pmlmepriv->wps_beacon_ie_len;
4479 /* copy remainder_ie to pframe */
4480 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
4481 pframe += remainder_ielen;
4482 pktlen += remainder_ielen;
4484 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
4485 pframe += cur_network->IELength;
4486 pktlen += cur_network->IELength;
4489 #endif /* CONFIG_IOCTL_CFG80211 */
4491 pframe_wscie = pframe + wps_offset;
4492 _rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
4493 pframe += (wps_offset + wpsielen);
4494 pktlen += (wps_offset + wpsielen);
4496 /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
4497 /* Primary Device Type */
4499 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
4503 *(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
4508 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4512 *(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
4515 /* Sub Category ID */
4516 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4522 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4526 *(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
4530 _rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
4531 insert_len += pwdinfo->device_name_len;
4534 /* update wsc ie length */
4535 *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
4537 /* pframe move to end */
4538 pframe += insert_len;
4539 pktlen += insert_len;
4541 /* copy remainder_ie to pframe */
4542 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
4543 pframe += remainder_ielen;
4544 pktlen += remainder_ielen;
4547 #endif /* CONFIG_P2P */
4550 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
4551 len_diff = update_hidden_ssid(
4552 pframe + _BEACON_IE_OFFSET_
4553 , cur_network->IELength - _BEACON_IE_OFFSET_
4554 , pmlmeinfo->hidden_ssid_mode
4556 pframe += (cur_network->IELength + len_diff);
4557 pktlen += (cur_network->IELength + len_diff);
4564 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
4565 pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
4566 if (wps_ie && wps_ielen > 0)
4567 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
4569 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
4571 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
4575 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
4577 #ifdef CONFIG_IOCTL_CFG80211
4578 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
4579 len = pmlmepriv->p2p_beacon_ie_len;
4580 if (pmlmepriv->p2p_beacon_ie && len > 0)
4581 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
4583 #endif /* CONFIG_IOCTL_CFG80211 */
4585 len = build_beacon_p2p_ie(pwdinfo, pframe);
4592 len = rtw_append_beacon_wfd_ie(padapter, pframe);
4598 #endif /* CONFIG_P2P */
4604 /* below for ad-hoc mode */
4606 /* timestamp will be inserted by hardware */
4610 /* beacon interval: 2 bytes */
4612 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
4617 /* capability info: 2 bytes */
4619 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
4625 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
4627 /* supported rates... */
4628 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
4629 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
4631 /* DS parameter set */
4632 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
4634 /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
4638 /* IBSS Parameter Set... */
4639 /* ATIMWindow = cur->Configuration.ATIMWindow; */
4641 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
4644 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pktlen);
4648 /* EXTERNDED SUPPORTED RATE */
4650 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
4653 /* todo:HT for adhoc */
4657 /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
4658 /* pmlmepriv->update_bcn = _FALSE;
4660 * _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
4661 * #endif */ /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
4665 /* printf dbg msg */
4667 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P BEACON\n");
4669 for (index = 0; index < dbgbufLen; index++)
4670 printk("%x ", *(dbgbuf + index));
4673 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P BEACON\n");
4678 static int get_reg_classes_full_count(struct p2p_channels channel_list)
4683 for (i = 0; i < channel_list.reg_classes; i++)
4684 cnt += channel_list.reg_class[i].channels;
4689 static void rtw_hal_construct_P2PProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
4691 /* struct xmit_frame *pmgntframe; */
4692 /* struct pkt_attrib *pattrib; */
4693 /* unsigned char *pframe; */
4694 struct rtw_ieee80211_hdr *pwlanhdr;
4695 unsigned short *fctrl;
4697 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4698 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4699 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4700 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4701 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
4702 u16 beacon_interval = 100;
4704 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4705 u8 wpsie[255] = { 0x00 };
4706 u32 wpsielen = 0, p2pielen = 0;
4711 #ifdef CONFIG_INTEL_WIDI
4712 u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
4713 #endif /* CONFIG_INTEL_WIDI */
4716 u8 *dbgbuf = pframe;
4717 u8 dbgbufLen = 0, index = 0;
4719 RTW_INFO("%s\n", __FUNCTION__);
4720 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4722 mac = adapter_mac_addr(padapter);
4724 fctrl = &(pwlanhdr->frame_ctl);
4727 /* DA filled by FW */
4728 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
4729 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
4731 /* Use the device address for BSSID field. */
4732 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
4734 SetSeqNum(pwlanhdr, 0);
4735 set_frame_sub_type(fctrl, WIFI_PROBERSP);
4737 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4741 /* timestamp will be inserted by hardware */
4745 /* beacon interval: 2 bytes */
4746 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
4750 /* capability info: 2 bytes */
4751 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
4752 capInfo |= cap_ShortPremble;
4753 capInfo |= cap_ShortSlot;
4755 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
4761 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pktlen);
4763 /* supported rates... */
4764 /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
4765 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pktlen);
4767 /* DS parameter set */
4768 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pktlen);
4770 #ifdef CONFIG_IOCTL_CFG80211
4771 if (pwdinfo->driver_interface == DRIVER_CFG80211) {
4772 if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
4774 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
4775 pktlen += pmlmepriv->wps_probe_resp_ie_len;
4776 pframe += pmlmepriv->wps_probe_resp_ie_len;
4779 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
4780 pktlen += pmlmepriv->p2p_probe_resp_ie_len;
4781 pframe += pmlmepriv->p2p_probe_resp_ie_len;
4784 #endif /* CONFIG_IOCTL_CFG80211 */
4788 /* Noted by Albert 20100907 */
4789 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
4793 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
4798 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
4802 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4806 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4808 #ifdef CONFIG_INTEL_WIDI
4809 /* Commented by Kurt */
4810 /* Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext. */
4811 if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
4812 || pmlmepriv->num_p2p_sdt != 0) {
4814 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SEC_DEV_TYPE_LIST);
4818 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
4823 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_DISPLAYS);
4827 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(INTEL_DEV_TYPE_OUI);
4830 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_WIDI_CONSUMER_SINK);
4833 if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE) {
4834 /* Vendor Extension */
4835 _rtw_memcpy(wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN);
4836 wpsielen += L2SDTA_SERVICE_VE_LEN;
4839 #endif /* CONFIG_INTEL_WIDI */
4841 /* WiFi Simple Config State */
4843 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
4847 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4851 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
4855 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
4859 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4863 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
4867 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
4871 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
4875 if (pwdinfo->external_uuid == 0) {
4876 _rtw_memset(wpsie + wpsielen, 0x0, 16);
4877 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
4879 _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
4884 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
4888 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
4892 _rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
4897 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
4901 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
4905 _rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
4910 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
4914 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4918 wpsie[wpsielen++] = 0x31; /* character 1 */
4922 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
4926 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
4930 _rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
4931 wpsielen += ETH_ALEN;
4933 /* Primary Device Type */
4935 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
4939 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
4944 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4948 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
4951 /* Sub Category ID */
4952 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4957 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4961 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
4965 _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
4966 wpsielen += pwdinfo->device_name_len;
4970 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
4974 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
4978 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
4982 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
4985 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
4991 wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
4999 /* printf dbg msg */
5001 RTW_INFO("======> DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
5003 for (index = 0; index < dbgbufLen; index++)
5004 printk("%x ", *(dbgbuf + index));
5007 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT P2P Probe Rsp\n");
5010 static void rtw_hal_construct_P2PNegoRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
5012 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5013 u8 action = P2P_PUB_ACTION_ACTION;
5014 u32 p2poui = cpu_to_be32(P2POUI);
5015 u8 oui_subtype = P2P_GO_NEGO_RESP;
5016 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
5019 u16 wps_devicepassword_id = 0x0000;
5020 uint wps_devicepassword_id_len = 0;
5021 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
5022 u16 len_channellist_attr = 0;
5026 /* struct xmit_frame *pmgntframe; */
5027 /* struct pkt_attrib *pattrib; */
5028 /* unsigned char *pframe; */
5029 struct rtw_ieee80211_hdr *pwlanhdr;
5030 unsigned short *fctrl;
5031 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5032 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5033 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5034 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5035 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
5042 u8 *dbgbuf = pframe;
5043 u8 dbgbufLen = 0, index = 0;
5045 RTW_INFO("%s\n", __FUNCTION__);
5046 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5048 fctrl = &(pwlanhdr->frame_ctl);
5051 /* RA, filled by FW */
5052 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
5053 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5054 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
5056 SetSeqNum(pwlanhdr, 0);
5057 set_frame_sub_type(pframe, WIFI_ACTION);
5059 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5062 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
5063 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
5064 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
5065 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
5067 /* dialog token, filled by FW */
5068 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
5070 _rtw_memset(wpsie, 0x00, 255);
5076 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
5081 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5085 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5089 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
5091 /* Device Password ID */
5093 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
5097 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
5101 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
5102 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
5103 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
5104 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
5106 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
5109 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
5112 /* P2P IE Section. */
5116 p2pie[p2pielen++] = 0x50;
5117 p2pie[p2pielen++] = 0x6F;
5118 p2pie[p2pielen++] = 0x9A;
5119 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
5121 /* Commented by Albert 20100908 */
5122 /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
5124 /* 2. P2P Capability */
5125 /* 3. Group Owner Intent */
5126 /* 4. Configuration Timeout */
5127 /* 5. Operating Channel */
5128 /* 6. Intended P2P Interface Address */
5129 /* 7. Channel List */
5130 /* 8. Device Info */
5131 /* 9. Group ID ( Only GO ) */
5138 p2pie[p2pielen++] = P2P_ATTR_STATUS;
5141 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5144 /* Value, filled by FW */
5145 p2pie[p2pielen++] = 1;
5147 /* P2P Capability */
5149 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
5152 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5156 /* Device Capability Bitmap, 1 byte */
5158 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
5159 /* Commented by Albert 2011/03/08 */
5160 /* According to the P2P specification */
5161 /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
5162 p2pie[p2pielen++] = 0;
5164 /* Be group owner or meet the error case */
5165 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
5168 /* Group Capability Bitmap, 1 byte */
5169 if (pwdinfo->persistent_supported)
5170 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
5172 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
5174 /* Group Owner Intent */
5176 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
5179 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5183 if (pwdinfo->peer_intent & 0x01) {
5184 /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
5185 p2pie[p2pielen++] = (pwdinfo->intent << 1);
5187 /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
5188 p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
5192 /* Configuration Timeout */
5194 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
5197 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5201 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
5202 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
5204 /* Operating Channel */
5206 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5209 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5213 /* Country String */
5214 p2pie[p2pielen++] = 'X';
5215 p2pie[p2pielen++] = 'X';
5217 /* The third byte should be set to 0x04. */
5218 /* Described in the "Operating Channel Attribute" section. */
5219 p2pie[p2pielen++] = 0x04;
5221 /* Operating Class */
5222 if (pwdinfo->operating_channel <= 14) {
5223 /* Operating Class */
5224 p2pie[p2pielen++] = 0x51;
5225 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
5226 /* Operating Class */
5227 p2pie[p2pielen++] = 0x73;
5229 /* Operating Class */
5230 p2pie[p2pielen++] = 0x7c;
5233 /* Channel Number */
5234 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
5236 /* Intended P2P Interface Address */
5238 p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
5241 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
5245 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5246 p2pielen += ETH_ALEN;
5250 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5252 /* Country String(3) */
5253 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
5254 /* + number of channels in all classes */
5255 len_channellist_attr = 3
5256 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5257 + get_reg_classes_full_count(pmlmeext->channel_list);
5259 #ifdef CONFIG_CONCURRENT_MODE
5260 if (rtw_mi_buddy_check_fwstate(padapter, _FW_LINKED))
5261 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
5263 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5267 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5273 /* Country String */
5274 p2pie[p2pielen++] = 'X';
5275 p2pie[p2pielen++] = 'X';
5277 /* The third byte should be set to 0x04. */
5278 /* Described in the "Operating Channel Attribute" section. */
5279 p2pie[p2pielen++] = 0x04;
5281 /* Channel Entry List */
5283 #ifdef CONFIG_CONCURRENT_MODE
5284 if (rtw_mi_check_status(padapter, MI_LINKED)) {
5285 u8 union_ch = rtw_mi_get_union_chan(padapter);
5287 /* Operating Class */
5288 if (union_ch > 14) {
5289 if (union_ch >= 149)
5290 p2pie[p2pielen++] = 0x7c;
5292 p2pie[p2pielen++] = 0x73;
5294 p2pie[p2pielen++] = 0x51;
5297 /* Number of Channels */
5298 /* Just support 1 channel and this channel is AP's channel */
5299 p2pie[p2pielen++] = 1;
5302 p2pie[p2pielen++] = union_ch;
5305 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5306 /* Operating Class */
5307 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5309 /* Number of Channels */
5310 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5313 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
5314 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5317 #else /* CONFIG_CONCURRENT_MODE */
5320 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5321 /* Operating Class */
5322 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5324 /* Number of Channels */
5325 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5328 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
5329 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5332 #endif /* CONFIG_CONCURRENT_MODE */
5337 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
5340 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
5341 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
5342 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
5346 /* P2P Device Address */
5347 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5348 p2pielen += ETH_ALEN;
5351 /* This field should be big endian. Noted by P2P specification. */
5353 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
5357 /* Primary Device Type */
5359 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5363 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
5366 /* Sub Category ID */
5367 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5370 /* Number of Secondary Device Types */
5371 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
5375 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5379 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
5383 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
5384 p2pielen += pwdinfo->device_name_len;
5386 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5387 /* Group ID Attribute */
5389 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
5392 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
5396 /* p2P Device Address */
5397 _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
5398 p2pielen += ETH_ALEN;
5401 _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
5402 p2pielen += pwdinfo->nego_ssidlen;
5406 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
5409 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
5416 /* printf dbg msg */
5418 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Nego Rsp\n");
5420 for (index = 0; index < dbgbufLen; index++)
5421 printk("%x ", *(dbgbuf + index));
5424 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Nego Rsp\n");
5428 static void rtw_hal_construct_P2PInviteRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
5430 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5431 u8 action = P2P_PUB_ACTION_ACTION;
5432 u32 p2poui = cpu_to_be32(P2POUI);
5433 u8 oui_subtype = P2P_INVIT_RESP;
5434 u8 p2pie[255] = { 0x00 };
5436 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
5437 u16 len_channellist_attr = 0;
5444 /* struct xmit_frame *pmgntframe; */
5445 /* struct pkt_attrib *pattrib; */
5446 /* unsigned char *pframe; */
5447 struct rtw_ieee80211_hdr *pwlanhdr;
5448 unsigned short *fctrl;
5449 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5450 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5451 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5452 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5455 u8 *dbgbuf = pframe;
5456 u8 dbgbufLen = 0, index = 0;
5459 RTW_INFO("%s\n", __FUNCTION__);
5460 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5462 fctrl = &(pwlanhdr->frame_ctl);
5466 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
5467 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5469 /* BSSID fill by FW */
5470 _rtw_memset(pwlanhdr->addr3, 0, ETH_ALEN);
5472 SetSeqNum(pwlanhdr, 0);
5473 set_frame_sub_type(pframe, WIFI_ACTION);
5475 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5476 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5478 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
5479 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
5480 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
5481 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
5483 /* dialog token, filled by FW */
5484 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
5486 /* P2P IE Section. */
5490 p2pie[p2pielen++] = 0x50;
5491 p2pie[p2pielen++] = 0x6F;
5492 p2pie[p2pielen++] = 0x9A;
5493 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
5495 /* Commented by Albert 20101005 */
5496 /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
5498 /* 2. Configuration Timeout */
5499 /* 3. Operating Channel ( Only GO ) */
5500 /* 4. P2P Group BSSID ( Only GO ) */
5501 /* 5. Channel List */
5505 p2pie[p2pielen++] = P2P_ATTR_STATUS;
5508 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5511 /* Value: filled by FW, defult value is FAIL INFO UNAVAILABLE */
5512 p2pie[p2pielen++] = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
5514 /* Configuration Timeout */
5516 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
5519 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5523 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
5524 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
5526 /* due to defult value is FAIL INFO UNAVAILABLE, so the following IE is not needed */
5528 if (status_code == P2P_STATUS_SUCCESS) {
5529 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5530 /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
5531 /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
5532 /* First one is operating channel attribute. */
5533 /* Second one is P2P Group BSSID attribute. */
5535 /* Operating Channel */
5537 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5540 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5544 /* Country String */
5545 p2pie[p2pielen++] = 'X';
5546 p2pie[p2pielen++] = 'X';
5548 /* The third byte should be set to 0x04. */
5549 /* Described in the "Operating Channel Attribute" section. */
5550 p2pie[p2pielen++] = 0x04;
5552 /* Operating Class */
5553 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
5555 /* Channel Number */
5556 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
5559 /* P2P Group BSSID */
5561 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
5564 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
5568 /* P2P Device Address for GO */
5569 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5570 p2pielen += ETH_ALEN;
5576 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5579 /* Country String(3) */
5580 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
5581 /* + number of channels in all classes */
5582 len_channellist_attr = 3
5583 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5584 + get_reg_classes_full_count(pmlmeext->channel_list);
5586 #ifdef CONFIG_CONCURRENT_MODE
5587 if (rtw_mi_check_status(padapter, MI_LINKED))
5588 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
5590 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5594 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5600 /* Country String */
5601 p2pie[p2pielen++] = 'X';
5602 p2pie[p2pielen++] = 'X';
5604 /* The third byte should be set to 0x04. */
5605 /* Described in the "Operating Channel Attribute" section. */
5606 p2pie[p2pielen++] = 0x04;
5608 /* Channel Entry List */
5609 #ifdef CONFIG_CONCURRENT_MODE
5610 if (rtw_mi_check_status(padapter, MI_LINKED)) {
5611 u8 union_ch = rtw_mi_get_union_chan(padapter);
5613 /* Operating Class */
5614 if (union_ch > 14) {
5615 if (union_ch >= 149)
5616 p2pie[p2pielen++] = 0x7c;
5618 p2pie[p2pielen++] = 0x73;
5621 p2pie[p2pielen++] = 0x51;
5624 /* Number of Channels */
5625 /* Just support 1 channel and this channel is AP's channel */
5626 p2pie[p2pielen++] = 1;
5629 p2pie[p2pielen++] = union_ch;
5632 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5633 /* Operating Class */
5634 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5636 /* Number of Channels */
5637 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5640 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
5641 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5644 #else /* CONFIG_CONCURRENT_MODE */
5647 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5648 /* Operating Class */
5649 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5651 /* Number of Channels */
5652 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5655 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
5656 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5659 #endif /* CONFIG_CONCURRENT_MODE */
5663 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pktlen);
5666 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
5674 /* printf dbg msg */
5676 RTW_INFO("======> DBG MSG FOR CONSTRAUCT Invite Rsp\n");
5678 for (index = 0; index < dbgbufLen; index++)
5679 printk("%x ", *(dbgbuf + index));
5682 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT Invite Rsp\n");
5687 static void rtw_hal_construct_P2PProvisionDisRsp(_adapter *padapter, u8 *pframe, u32 *pLength)
5689 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5690 u8 action = P2P_PUB_ACTION_ACTION;
5692 u32 p2poui = cpu_to_be32(P2POUI);
5693 u8 oui_subtype = P2P_PROVISION_DISC_RESP;
5694 u8 wpsie[100] = { 0x00 };
5701 /* struct xmit_frame *pmgntframe; */
5702 /* struct pkt_attrib *pattrib; */
5703 /* unsigned char *pframe; */
5704 struct rtw_ieee80211_hdr *pwlanhdr;
5705 unsigned short *fctrl;
5706 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5707 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5708 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5709 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5712 u8 *dbgbuf = pframe;
5713 u8 dbgbufLen = 0, index = 0;
5715 RTW_INFO("%s\n", __FUNCTION__);
5717 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5719 fctrl = &(pwlanhdr->frame_ctl);
5722 /* RA filled by FW */
5723 _rtw_memset(pwlanhdr->addr1, 0, ETH_ALEN);
5724 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5725 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
5727 SetSeqNum(pwlanhdr, 0);
5728 set_frame_sub_type(pframe, WIFI_ACTION);
5730 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5731 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5733 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pktlen));
5734 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pktlen));
5735 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pktlen));
5736 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pktlen));
5737 /* dialog token, filled by FW */
5738 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pktlen));
5742 /* *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI ); */
5743 RTW_PUT_BE32(wpsie, WPSOUI);
5749 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5753 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5757 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
5762 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD ); */
5763 RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
5767 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 ); */
5768 RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
5771 /* Value: filled by FW, default value is PBC */
5772 /* *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method ); */
5773 RTW_PUT_BE16(wpsie + wpsielen, WPS_CM_PUSH_BUTTON);
5776 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pktlen);
5779 wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
5786 /* printf dbg msg */
5789 RTW_INFO("======> DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
5791 for (index = 0; index < dbgbufLen; index++)
5792 printk("%x ", *(dbgbuf + index));
5795 RTW_INFO("<====== DBG MSG FOR CONSTRAUCT ProvisionDis Rsp\n");
5799 u8 rtw_hal_set_FwP2PRsvdPage_cmd(_adapter *adapter, PRSVDPAGE_LOC rsvdpageloc)
5801 u8 u1H2CP2PRsvdPageParm[H2C_P2PRSVDPAGE_LOC_LEN] = {0};
5802 struct hal_ops *pHalFunc = &adapter->hal_func;
5805 RTW_INFO("P2PRsvdPageLoc: P2PBeacon=%d P2PProbeRsp=%d NegoRsp=%d InviteRsp=%d PDRsp=%d\n",
5806 rsvdpageloc->LocP2PBeacon, rsvdpageloc->LocP2PProbeRsp,
5807 rsvdpageloc->LocNegoRsp, rsvdpageloc->LocInviteRsp,
5808 rsvdpageloc->LocPDRsp);
5810 SET_H2CCMD_RSVDPAGE_LOC_P2P_BCN(u1H2CP2PRsvdPageParm, rsvdpageloc->LocProbeRsp);
5811 SET_H2CCMD_RSVDPAGE_LOC_P2P_PROBE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocPsPoll);
5812 SET_H2CCMD_RSVDPAGE_LOC_P2P_NEGO_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocNullData);
5813 SET_H2CCMD_RSVDPAGE_LOC_P2P_INVITE_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocQosNull);
5814 SET_H2CCMD_RSVDPAGE_LOC_P2P_PD_RSP(u1H2CP2PRsvdPageParm, rsvdpageloc->LocBTQosNull);
5816 /* FillH2CCmd8723B(padapter, H2C_8723B_P2P_OFFLOAD_RSVD_PAGE, H2C_P2PRSVDPAGE_LOC_LEN, u1H2CP2PRsvdPageParm); */
5817 ret = rtw_hal_fill_h2c_cmd(adapter,
5818 H2C_P2P_OFFLOAD_RSVD_PAGE,
5819 H2C_P2PRSVDPAGE_LOC_LEN,
5820 u1H2CP2PRsvdPageParm);
5825 u8 rtw_hal_set_p2p_wowlan_offload_cmd(_adapter *adapter)
5828 u8 offload_cmd[H2C_P2P_OFFLOAD_LEN] = {0};
5829 struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
5830 struct P2P_WoWlan_Offload_t *p2p_wowlan_offload = (struct P2P_WoWlan_Offload_t *)offload_cmd;
5831 struct hal_ops *pHalFunc = &adapter->hal_func;
5834 _rtw_memset(p2p_wowlan_offload, 0 , sizeof(struct P2P_WoWlan_Offload_t));
5835 RTW_INFO("%s\n", __func__);
5836 switch (pwdinfo->role) {
5837 case P2P_ROLE_DEVICE:
5838 RTW_INFO("P2P_ROLE_DEVICE\n");
5839 p2p_wowlan_offload->role = 0;
5841 case P2P_ROLE_CLIENT:
5842 RTW_INFO("P2P_ROLE_CLIENT\n");
5843 p2p_wowlan_offload->role = 1;
5846 RTW_INFO("P2P_ROLE_GO\n");
5847 p2p_wowlan_offload->role = 2;
5850 RTW_INFO("P2P_ROLE_DISABLE\n");
5853 p2p_wowlan_offload->Wps_Config[0] = pwdinfo->supported_wps_cm >> 8;
5854 p2p_wowlan_offload->Wps_Config[1] = pwdinfo->supported_wps_cm;
5855 offload_cmd = (u8 *)p2p_wowlan_offload;
5856 RTW_INFO("p2p_wowlan_offload: %x:%x:%x\n", offload_cmd[0], offload_cmd[1], offload_cmd[2]);
5858 ret = rtw_hal_fill_h2c_cmd(adapter,
5860 H2C_P2P_OFFLOAD_LEN,
5864 /* FillH2CCmd8723B(adapter, H2C_8723B_P2P_OFFLOAD, sizeof(struct P2P_WoWlan_Offload_t), (u8 *)p2p_wowlan_offload); */
5866 #endif /* CONFIG_P2P_WOWLAN */
5868 static void rtw_hal_construct_beacon(_adapter *padapter,
5869 u8 *pframe, u32 *pLength)
5871 struct rtw_ieee80211_hdr *pwlanhdr;
5873 u32 rate_len, pktlen;
5874 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5875 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5876 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
5877 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5880 /* RTW_INFO("%s\n", __FUNCTION__); */
5882 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5884 fctrl = &(pwlanhdr->frame_ctl);
5887 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
5888 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5889 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
5891 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
5892 /* pmlmeext->mgnt_seq++; */
5893 set_frame_sub_type(pframe, WIFI_BEACON);
5895 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5896 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5898 /* timestamp will be inserted by hardware */
5902 /* beacon interval: 2 bytes */
5903 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
5908 /* capability info: 2 bytes */
5909 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
5914 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
5915 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
5916 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
5917 _rtw_memcpy(pframe, cur_network->IEs + sizeof(NDIS_802_11_FIXED_IEs), pktlen);
5919 goto _ConstructBeacon;
5922 /* below for ad-hoc mode */
5925 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
5927 /* supported rates... */
5928 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
5929 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pktlen);
5931 /* DS parameter set */
5932 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
5934 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
5936 /* IBSS Parameter Set... */
5937 /* ATIMWindow = cur->Configuration.ATIMWindow; */
5939 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
5946 /* EXTERNDED SUPPORTED RATE */
5948 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
5951 /* todo:HT for adhoc */
5955 if ((pktlen + TXDESC_SIZE) > 512) {
5956 RTW_INFO("beacon frame too large\n");
5962 /* RTW_INFO("%s bcn_sz=%d\n", __FUNCTION__, pktlen); */
5966 static void rtw_hal_construct_PSPoll(_adapter *padapter,
5967 u8 *pframe, u32 *pLength)
5969 struct rtw_ieee80211_hdr *pwlanhdr;
5972 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5973 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5975 /* RTW_INFO("%s\n", __FUNCTION__); */
5977 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5979 /* Frame control. */
5980 fctrl = &(pwlanhdr->frame_ctl);
5983 set_frame_sub_type(pframe, WIFI_PSPOLL);
5986 set_duration(pframe, (pmlmeinfo->aid | 0xc000));
5989 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
5992 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5997 void rtw_hal_construct_NullFunctionData(
6007 struct rtw_ieee80211_hdr *pwlanhdr;
6010 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6011 struct wlan_network *cur_network = &pmlmepriv->cur_network;
6012 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6013 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6016 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
6018 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6020 fctrl = &pwlanhdr->frame_ctl;
6022 if (bForcePowerSave)
6025 switch (cur_network->network.InfrastructureMode) {
6026 case Ndis802_11Infrastructure:
6028 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6029 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6030 _rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
6032 case Ndis802_11APMode:
6034 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
6035 _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6036 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
6038 case Ndis802_11IBSS:
6040 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
6041 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6042 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6046 SetSeqNum(pwlanhdr, 0);
6048 if (bQoS == _TRUE) {
6049 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
6051 set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
6053 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos *)pframe;
6054 SetPriority(&pwlanqoshdr->qc, AC);
6055 SetEOSP(&pwlanqoshdr->qc, bEosp);
6057 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
6059 set_frame_sub_type(pframe, WIFI_DATA_NULL);
6061 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6067 void rtw_hal_construct_ProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength,
6068 u8 *StaAddr, BOOLEAN bHideSSID)
6070 struct rtw_ieee80211_hdr *pwlanhdr;
6074 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6075 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6076 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
6078 /*RTW_INFO("%s\n", __FUNCTION__);*/
6080 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6082 mac = adapter_mac_addr(padapter);
6083 bssid = cur_network->MacAddress;
6085 fctrl = &(pwlanhdr->frame_ctl);
6087 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
6088 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6089 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
6091 SetSeqNum(pwlanhdr, 0);
6092 set_frame_sub_type(fctrl, WIFI_PROBERSP);
6094 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6097 if (cur_network->IELength > MAX_IE_SZ)
6100 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
6101 pframe += cur_network->IELength;
6102 pktlen += cur_network->IELength;
6107 #ifdef CONFIG_WOWLAN
6108 static void rtw_hal_append_tkip_mic(PADAPTER padapter,
6109 u8 *pframe, u32 offset)
6111 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6112 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6113 struct rtw_ieee80211_hdr *pwlanhdr;
6114 struct mic_data micdata;
6115 struct sta_info *psta = NULL;
6118 u8 *payload = (u8 *)(pframe + offset);
6121 u8 priority[4] = {0x0};
6122 u8 null_key[16] = {0x0};
6124 RTW_INFO("%s(): Add MIC, offset: %d\n", __func__, offset);
6126 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6128 psta = rtw_get_stainfo(&padapter->stapriv,
6129 get_my_bssid(&(pmlmeinfo->network)));
6131 res = _rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],
6134 RTW_INFO("%s(): STA dot11tkiptxmickey==0\n", __func__);
6135 rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
6138 rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); /* DA */
6140 rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); /* SA */
6144 rtw_secmicappend(&micdata, &priority[0], 4);
6146 rtw_secmicappend(&micdata, payload, 36); /* payload length = 8 + 28 */
6148 rtw_secgetmic(&micdata, &(mic[0]));
6152 _rtw_memcpy(payload, &(mic[0]), 8);
6156 * Construct the ARP response packet to support ARP offload.
6158 static void rtw_hal_construct_ARPRsp(
6165 struct rtw_ieee80211_hdr *pwlanhdr;
6168 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6169 struct wlan_network *cur_network = &pmlmepriv->cur_network;
6170 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6171 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6172 struct security_priv *psecuritypriv = &padapter->securitypriv;
6173 static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
6174 u8 *pARPRspPkt = pframe;
6175 /* for TKIP Cal MIC */
6176 u8 *payload = pframe;
6177 u8 EncryptionHeadOverhead = 0, arp_offset = 0;
6178 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
6180 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6182 fctrl = &pwlanhdr->frame_ctl;
6185 /* ------------------------------------------------------------------------- */
6187 /* ------------------------------------------------------------------------- */
6188 SetFrameType(fctrl, WIFI_DATA);
6189 /* set_frame_sub_type(fctrl, 0); */
6191 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6192 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6193 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6195 SetSeqNum(pwlanhdr, 0);
6196 set_duration(pwlanhdr, 0);
6197 /* SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); */
6198 /* SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); */
6199 /* SET_80211_HDR_TO_DS(pARPRspPkt, 1); */
6200 /* SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); */
6201 /* SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); */
6202 /* SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); */
6204 /* SET_80211_HDR_DURATION(pARPRspPkt, 0); */
6205 /* SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); */
6206 #ifdef CONFIG_WAPI_SUPPORT
6207 *pLength = sMacHdrLng;
6211 switch (psecuritypriv->dot11PrivacyAlgrthm) {
6214 EncryptionHeadOverhead = 4;
6217 EncryptionHeadOverhead = 8;
6220 EncryptionHeadOverhead = 8;
6222 #ifdef CONFIG_WAPI_SUPPORT
6224 EncryptionHeadOverhead = 18;
6228 EncryptionHeadOverhead = 0;
6231 if (EncryptionHeadOverhead > 0) {
6232 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
6233 *pLength += EncryptionHeadOverhead;
6234 /* SET_80211_HDR_WEP(pARPRspPkt, 1); */ /* Suggested by CCW. */
6238 /* ------------------------------------------------------------------------- */
6240 /* ------------------------------------------------------------------------- */
6241 arp_offset = *pLength;
6242 pARPRspPkt = (u8 *)(pframe + arp_offset);
6243 payload = pARPRspPkt; /* Get Payload pointer */
6245 _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
6250 SET_ARP_PKT_HW(pARPRspPkt, 0x0100);
6251 SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008); /* IP protocol */
6252 SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6);
6253 SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4);
6254 SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200); /* ARP response */
6255 SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, adapter_mac_addr(padapter));
6256 SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
6257 #ifdef CONFIG_ARP_KEEP_ALIVE
6258 if (!is_zero_mac_addr(pmlmepriv->gw_mac_addr)) {
6259 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
6260 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
6264 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt,
6265 get_my_bssid(&(pmlmeinfo->network)));
6266 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt,
6268 RTW_INFO("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__,
6269 MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
6270 RTW_INFO("%s Target IP Addr" IP_FMT "\n", __FUNCTION__,
6271 IP_ARG(pIPAddress));
6276 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) {
6277 if (IS_HARDWARE_TYPE_8188E(padapter) ||
6278 IS_HARDWARE_TYPE_8812(padapter)) {
6279 rtw_hal_append_tkip_mic(padapter, pframe, arp_offset);
6285 #ifdef CONFIG_PNO_SUPPORT
6286 static void rtw_hal_construct_ProbeReq(_adapter *padapter, u8 *pframe,
6287 u32 *pLength, pno_ssid_t *ssid)
6289 struct rtw_ieee80211_hdr *pwlanhdr;
6293 unsigned char bssrate[NumRates];
6294 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6295 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6296 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6297 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6298 int bssrate_len = 0;
6299 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6301 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6302 mac = adapter_mac_addr(padapter);
6304 fctrl = &(pwlanhdr->frame_ctl);
6307 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6308 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
6310 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6312 SetSeqNum(pwlanhdr, 0);
6313 set_frame_sub_type(pframe, WIFI_PROBEREQ);
6315 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6319 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
6321 /* RTW_INFO("%s len:%d\n", ssid->SSID, ssid->SSID_len); */
6322 pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
6325 get_rate_set(padapter, bssrate, &bssrate_len);
6327 if (bssrate_len > 8) {
6328 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
6329 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
6331 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
6336 static void rtw_hal_construct_PNO_info(_adapter *padapter,
6337 u8 *pframe, u32 *pLength)
6339 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6342 u8 *pPnoInfoPkt = pframe;
6343 pPnoInfoPkt = (u8 *)(pframe + *pLength);
6344 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
6347 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
6350 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
6353 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
6356 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
6359 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length, MAX_PNO_LIST_COUNT);
6361 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
6362 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info, MAX_PNO_LIST_COUNT);
6364 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
6365 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info, MAX_PNO_LIST_COUNT);
6367 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
6368 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req, MAX_HIDDEN_AP);
6370 pPnoInfoPkt += MAX_HIDDEN_AP;
6373 SSID is located at 128th Byte in NLO info Page
6377 pPnoInfoPkt = pframe + 128;
6379 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
6380 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pno_ssid_list->node[i].SSID,
6381 pwrctl->pnlo_info->ssid_length[i]);
6382 *pLength += WLAN_SSID_MAXLEN;
6383 pPnoInfoPkt += WLAN_SSID_MAXLEN;
6387 static void rtw_hal_construct_ssid_list(_adapter *padapter,
6388 u8 *pframe, u32 *pLength)
6390 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6391 u8 *pSSIDListPkt = pframe;
6394 pSSIDListPkt = (u8 *)(pframe + *pLength);
6396 for (i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
6397 _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
6398 pwrctl->pnlo_info->ssid_length[i]);
6400 *pLength += WLAN_SSID_MAXLEN;
6401 pSSIDListPkt += WLAN_SSID_MAXLEN;
6405 static void rtw_hal_construct_scan_info(_adapter *padapter,
6406 u8 *pframe, u32 *pLength)
6408 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
6409 u8 *pScanInfoPkt = pframe;
6412 pScanInfoPkt = (u8 *)(pframe + *pLength);
6414 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
6418 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
6423 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
6428 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
6432 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
6436 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
6440 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
6444 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
6448 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
6453 for (i = 0 ; i < MAX_SCAN_LIST_COUNT ; i++) {
6454 _rtw_memcpy(pScanInfoPkt,
6455 &pwrctl->pscan_info->ssid_channel_info[i], 4);
6460 #endif /* CONFIG_PNO_SUPPORT */
6462 #ifdef CONFIG_GTK_OL
6463 static void rtw_hal_construct_GTKRsp(
6469 struct rtw_ieee80211_hdr *pwlanhdr;
6472 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6473 struct wlan_network *cur_network = &pmlmepriv->cur_network;
6474 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6475 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6476 struct security_priv *psecuritypriv = &padapter->securitypriv;
6477 static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
6478 static u8 GTKbody_a[11] = {0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
6479 u8 *pGTKRspPkt = pframe;
6480 u8 EncryptionHeadOverhead = 0;
6481 /* RTW_INFO("%s:%d\n", __FUNCTION__, bForcePowerSave); */
6483 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6485 fctrl = &pwlanhdr->frame_ctl;
6488 /* ------------------------------------------------------------------------- */
6490 /* ------------------------------------------------------------------------- */
6491 SetFrameType(fctrl, WIFI_DATA);
6492 /* set_frame_sub_type(fctrl, 0); */
6495 _rtw_memcpy(pwlanhdr->addr1,
6496 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6498 _rtw_memcpy(pwlanhdr->addr2,
6499 adapter_mac_addr(padapter), ETH_ALEN);
6501 _rtw_memcpy(pwlanhdr->addr3,
6502 get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6504 SetSeqNum(pwlanhdr, 0);
6505 set_duration(pwlanhdr, 0);
6507 #ifdef CONFIG_WAPI_SUPPORT
6508 *pLength = sMacHdrLng;
6511 #endif /* CONFIG_WAPI_SUPPORT */
6513 /* ------------------------------------------------------------------------- */
6514 /* Security Header: leave space for it if necessary. */
6515 /* ------------------------------------------------------------------------- */
6516 switch (psecuritypriv->dot11PrivacyAlgrthm) {
6519 EncryptionHeadOverhead = 4;
6522 EncryptionHeadOverhead = 8;
6525 EncryptionHeadOverhead = 8;
6527 #ifdef CONFIG_WAPI_SUPPORT
6529 EncryptionHeadOverhead = 18;
6531 #endif /* CONFIG_WAPI_SUPPORT */
6533 EncryptionHeadOverhead = 0;
6536 if (EncryptionHeadOverhead > 0) {
6537 _rtw_memset(&(pframe[*pLength]), 0, EncryptionHeadOverhead);
6538 *pLength += EncryptionHeadOverhead;
6539 /* SET_80211_HDR_WEP(pGTKRspPkt, 1); */ /* Suggested by CCW. */
6540 /* GTK's privacy bit is done by FW */
6541 /* SetPrivacy(fctrl); */
6543 /* ------------------------------------------------------------------------- */
6545 /* ------------------------------------------------------------------------- */
6546 pGTKRspPkt = (u8 *)(pframe + *pLength);
6548 _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
6554 /* GTK frame body after LLC, part 1 */
6555 /* TKIP key_length = 32, AES key_length = 16 */
6556 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
6557 GTKbody_a[8] = 0x20;
6559 /* GTK frame body after LLC, part 1 */
6560 _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
6563 /* GTK frame body after LLC, part 2 */
6564 _rtw_memset(&(pframe[*pLength]), 0, 88);
6568 if (psecuritypriv->dot118021XGrpPrivacy == _TKIP_)
6571 #endif /* CONFIG_GTK_OL */
6573 void rtw_hal_set_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
6574 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
6575 RSVDPAGE_LOC *rsvd_page_loc)
6577 struct security_priv *psecuritypriv = &adapter->securitypriv;
6578 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
6579 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
6580 struct mlme_ext_priv *pmlmeext;
6581 struct mlme_ext_info *pmlmeinfo;
6582 u32 ARPLength = 0, GTKLength = 0, PNOLength = 0, ScanInfoLength = 0;
6583 u32 SSIDLegnth = 0, ProbeReqLength = 0;
6584 u8 CurtPktPageNum = 0;
6586 u8 cur_dot11txpn[8];
6588 #ifdef CONFIG_GTK_OL
6589 struct sta_priv *pstapriv = &adapter->stapriv;
6590 struct sta_info *psta;
6591 struct security_priv *psecpriv = &adapter->securitypriv;
6592 u8 kek[RTW_KEK_LEN];
6593 u8 kck[RTW_KCK_LEN];
6594 #endif /* CONFIG_GTK_OL */
6595 #ifdef CONFIG_PNO_SUPPORT
6598 #endif /* CONFIG_PNO_SUPPORT */
6600 pmlmeext = &adapter->mlmeextpriv;
6601 pmlmeinfo = &pmlmeext->mlmext_info;
6603 if (pwrctl->wowlan_pno_enable == _FALSE) {
6604 /* ARP RSP * 1 page */
6605 rtw_get_current_ip_address(adapter, currentip);
6607 rsvd_page_loc->LocArpRsp = *page_num;
6609 RTW_INFO("LocArpRsp: %d\n", rsvd_page_loc->LocArpRsp);
6611 rtw_hal_construct_ARPRsp(adapter, &pframe[index],
6612 &ARPLength, currentip);
6614 rtw_hal_fill_fake_txdesc(adapter,
6615 &pframe[index - tx_desc],
6616 ARPLength, _FALSE, _FALSE, _TRUE);
6618 CurtPktPageNum = (u8)PageNum(tx_desc + ARPLength, page_size);
6620 *page_num += CurtPktPageNum;
6622 index += (CurtPktPageNum * page_size);
6624 /* 3 SEC IV * 1 page */
6625 rtw_get_sec_iv(adapter, cur_dot11txpn,
6626 get_my_bssid(&pmlmeinfo->network));
6628 rsvd_page_loc->LocRemoteCtrlInfo = *page_num;
6630 RTW_INFO("LocRemoteCtrlInfo: %d\n", rsvd_page_loc->LocRemoteCtrlInfo);
6632 _rtw_memcpy(pframe + index - tx_desc, cur_dot11txpn, _AES_IV_LEN_);
6634 CurtPktPageNum = (u8)PageNum(_AES_IV_LEN_, page_size);
6636 *page_num += CurtPktPageNum;
6638 *total_pkt_len = index + _AES_IV_LEN_;
6639 #ifdef CONFIG_GTK_OL
6640 index += (CurtPktPageNum * page_size);
6642 /* if the ap staion info. exists, get the kek, kck from staion info. */
6643 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
6645 _rtw_memset(kek, 0, RTW_KEK_LEN);
6646 _rtw_memset(kck, 0, RTW_KCK_LEN);
6647 RTW_INFO("%s, KEK, KCK download rsvd page all zero\n",
6650 _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
6651 _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
6655 rsvd_page_loc->LocGTKInfo = *page_num;
6656 RTW_INFO("LocGTKInfo: %d\n", rsvd_page_loc->LocGTKInfo);
6658 _rtw_memcpy(pframe + index - tx_desc, kck, RTW_KCK_LEN);
6659 _rtw_memcpy(pframe + index - tx_desc + RTW_KCK_LEN,
6661 GTKLength = tx_desc + RTW_KCK_LEN + RTW_KEK_LEN;
6664 psecuritypriv->dot118021XGrpPrivacy == _TKIP_) {
6665 _rtw_memcpy(pframe + index - tx_desc + 56,
6666 &psta->dot11tkiptxmickey, RTW_TKIP_MIC_LEN);
6667 GTKLength += RTW_TKIP_MIC_LEN;
6670 CurtPktPageNum = (u8)PageNum(GTKLength, page_size);
6674 printk("\ntoFW KCK: ");
6675 for (i = 0; i < 16; i++)
6676 printk(" %02x ", kck[i]);
6677 printk("\ntoFW KEK: ");
6678 for (i = 0; i < 16; i++)
6679 printk(" %02x ", kek[i]);
6683 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
6684 __FUNCTION__, &pframe[index - tx_desc],
6685 (tx_desc + RTW_KCK_LEN + RTW_KEK_LEN));
6688 *page_num += CurtPktPageNum;
6690 index += (CurtPktPageNum * page_size);
6692 /* 3 GTK Response */
6693 rsvd_page_loc->LocGTKRsp = *page_num;
6694 RTW_INFO("LocGTKRsp: %d\n", rsvd_page_loc->LocGTKRsp);
6695 rtw_hal_construct_GTKRsp(adapter, &pframe[index], >KLength);
6697 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
6698 GTKLength, _FALSE, _FALSE, _TRUE);
6702 printk("123GTK pkt=>\n");
6703 for (gj = 0; gj < GTKLength + tx_desc; gj++) {
6704 printk(" %02x ", pframe[index - tx_desc + gj]);
6705 if ((gj + 1) % 16 == 0)
6711 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
6712 __FUNCTION__, &pframe[index - tx_desc],
6713 (tx_desc + GTKLength));
6716 CurtPktPageNum = (u8)PageNum(tx_desc + GTKLength, page_size);
6718 *page_num += CurtPktPageNum;
6720 index += (CurtPktPageNum * page_size);
6722 /* below page is empty for GTK extension memory */
6723 /* 3(11) GTK EXT MEM */
6724 rsvd_page_loc->LocGTKEXTMEM = *page_num;
6725 RTW_INFO("LocGTKEXTMEM: %d\n", rsvd_page_loc->LocGTKEXTMEM);
6728 if (page_size >= 256)
6731 *page_num += CurtPktPageNum;
6732 /* extension memory for FW */
6733 *total_pkt_len = index + (page_size * CurtPktPageNum);
6734 #endif /* CONFIG_GTK_OL */
6736 index += (CurtPktPageNum * page_size);
6738 /*Reserve 1 page for AOAC report*/
6739 rsvd_page_loc->LocAOACReport = *page_num;
6740 RTW_INFO("LocAOACReport: %d\n", rsvd_page_loc->LocAOACReport);
6742 *total_pkt_len = index + (page_size * 1);
6744 #ifdef CONFIG_PNO_SUPPORT
6745 if (pwrctl->wowlan_in_resume == _FALSE &&
6746 pwrctl->pno_inited == _TRUE) {
6748 /* Broadcast Probe Request */
6749 rsvd_page_loc->LocProbePacket = *page_num;
6751 RTW_INFO("loc_probe_req: %d\n",
6752 rsvd_page_loc->LocProbePacket);
6754 rtw_hal_construct_ProbeReq(
6760 rtw_hal_fill_fake_txdesc(adapter,
6761 &pframe[index - tx_desc],
6762 ProbeReqLength, _FALSE, _FALSE, _FALSE);
6765 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
6767 *page_num += CurtPktPageNum;
6769 index += (CurtPktPageNum * page_size);
6771 /* Hidden SSID Probe Request */
6772 ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
6774 for (pno_index = 0 ; pno_index < ssid_num ; pno_index++) {
6775 pwrctl->pnlo_info->loc_probe_req[pno_index] =
6778 rtw_hal_construct_ProbeReq(
6782 &pwrctl->pno_ssid_list->node[pno_index]);
6784 rtw_hal_fill_fake_txdesc(adapter,
6785 &pframe[index - tx_desc],
6786 ProbeReqLength, _FALSE, _FALSE, _FALSE);
6789 (u8)PageNum(tx_desc + ProbeReqLength, page_size);
6791 *page_num += CurtPktPageNum;
6793 index += (CurtPktPageNum * page_size);
6797 rsvd_page_loc->LocPNOInfo = *page_num;
6798 RTW_INFO("LocPNOInfo: %d\n", rsvd_page_loc->LocPNOInfo);
6799 rtw_hal_construct_PNO_info(adapter,
6800 &pframe[index - tx_desc],
6803 CurtPktPageNum = (u8)PageNum(PNOLength, page_size);
6804 *page_num += CurtPktPageNum;
6805 index += (CurtPktPageNum * page_size);
6807 /* Scan Info Page */
6808 rsvd_page_loc->LocScanInfo = *page_num;
6809 RTW_INFO("LocScanInfo: %d\n", rsvd_page_loc->LocScanInfo);
6810 rtw_hal_construct_scan_info(adapter,
6811 &pframe[index - tx_desc],
6814 CurtPktPageNum = (u8)PageNum(ScanInfoLength, page_size);
6815 *page_num += CurtPktPageNum;
6816 *total_pkt_len = index + ScanInfoLength;
6817 index += (CurtPktPageNum * page_size);
6819 #endif /* CONFIG_PNO_SUPPORT */
6823 static void rtw_hal_gate_bb(_adapter *adapter, bool stop)
6825 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
6831 pwrpriv->wowlan_txpause_status = rtw_read8(adapter, REG_TXPAUSE);
6832 rtw_write8(adapter, REG_TXPAUSE, 0xff);
6833 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
6835 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
6836 RTW_INFO("%s: BB gated: 0x%02x, store TXPAUSE: %02x\n",
6838 rtw_read8(adapter, REG_SYS_FUNC_EN),
6839 pwrpriv->wowlan_txpause_status);
6841 val8 = rtw_read8(adapter, REG_SYS_FUNC_EN);
6843 rtw_write8(adapter, REG_SYS_FUNC_EN, val8);
6844 RTW_INFO("%s: BB release: 0x%02x, recover TXPAUSE:%02x\n",
6845 __func__, rtw_read8(adapter, REG_SYS_FUNC_EN),
6846 pwrpriv->wowlan_txpause_status);
6848 rtw_write8(adapter, REG_TXPAUSE, pwrpriv->wowlan_txpause_status);
6852 static void rtw_hal_reset_mac_rx(_adapter *adapter)
6855 /* Set REG_CR bit1, bit3, bit7 to 0*/
6856 val8 = rtw_read8(adapter, REG_CR);
6858 rtw_write8(adapter, REG_CR, val8);
6859 val8 = rtw_read8(adapter, REG_CR);
6860 /* Set REG_CR bit1, bit3, bit7 to 1*/
6862 rtw_write8(adapter, REG_CR, val8);
6863 RTW_INFO("0x%04x: %02x\n", REG_CR, rtw_read8(adapter, REG_CR));
6866 static u8 rtw_hal_wow_pattern_generate(_adapter *adapter, u8 idx, struct rtl_wow_pattern *pwow_pattern)
6868 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
6873 u8 mask_hw[MAX_WKFM_SIZE] = {0};
6874 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
6875 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6876 u8 multicast_addr1[2] = {0x33, 0x33};
6877 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
6879 u8 mac_addr[ETH_ALEN] = {0};
6883 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
6884 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
6885 __func__, MAX_WKFM_CAM_NUM);
6889 pattern = pwrctl->patterns[idx].content;
6890 len = pwrctl->patterns[idx].len;
6891 mask = pwrctl->patterns[idx].mask;
6893 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
6894 _rtw_memset(pwow_pattern, 0, sizeof(struct rtl_wow_pattern));
6896 mask_len = DIV_ROUND_UP(len, 8);
6898 /* 1. setup A1 table */
6899 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
6900 pwow_pattern->type = PATTERN_BROADCAST;
6901 else if (memcmp(pattern, multicast_addr1, 2) == 0)
6902 pwow_pattern->type = PATTERN_MULTICAST;
6903 else if (memcmp(pattern, multicast_addr2, 3) == 0)
6904 pwow_pattern->type = PATTERN_MULTICAST;
6905 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
6906 pwow_pattern->type = PATTERN_UNICAST;
6908 pwow_pattern->type = PATTERN_INVALID;
6910 /* translate mask from os to mask for hw */
6912 /******************************************************************************
6913 * pattern from OS uses 'ethenet frame', like this:
6915 | 6 | 6 | 2 | 20 | Variable | 4 |
6916 |--------+--------+------+-----------+------------+-----|
6917 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
6920 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
6922 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
6923 |-------------------+--------+------+-----------+------------+-----|
6924 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
6927 * Therefore, we need translate mask_from_OS to mask_to_hw.
6928 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
6929 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
6930 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
6931 ******************************************************************************/
6933 for (i = 0; i < mask_len - 1; i++) {
6934 mask_hw[i] = mask[i] >> 6;
6935 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
6938 mask_hw[i] = (mask[i] >> 6) & 0x3F;
6939 /* Set bit 0-5 to zero */
6942 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
6943 pwow_pattern->mask[i] = mask_hw[i * 4];
6944 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 1] << 8);
6945 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 2] << 16);
6946 pwow_pattern->mask[i] |= (mask_hw[i * 4 + 3] << 24);
6949 /* To get the wake up pattern from the mask.
6950 * We do not count first 12 bits which means
6951 * DA[6] and SA[6] in the pattern to match HW design. */
6953 for (i = 12; i < len; i++) {
6954 if ((mask[i / 8] >> (i % 8)) & 0x01) {
6955 content[count] = pattern[i];
6960 pwow_pattern->crc = rtw_calc_crc(content, count);
6962 if (pwow_pattern->crc != 0) {
6963 if (pwow_pattern->type == PATTERN_INVALID)
6964 pwow_pattern->type = PATTERN_VALID;
6970 #ifndef CONFIG_WOW_PATTERN_HW_CAM
6971 static void rtw_hal_set_wow_rxff_boundary(_adapter *adapter, bool wow_mode)
6975 u32 rx_dma_buff_sz = 0;
6977 val8 = rtw_read8(adapter, REG_FIFOPAGE + 3);
6979 RTW_INFO("%s:[%04x]some PKTs in TXPKTBUF\n",
6980 __func__, (REG_FIFOPAGE + 3));
6982 rtw_hal_reset_mac_rx(adapter);
6985 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
6986 (u8 *)&rx_dma_buff_sz);
6987 rxff_bndy = rx_dma_buff_sz - 1;
6989 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
6990 RTW_INFO("%s: wow mode, 0x%04x: 0x%04x\n", __func__,
6992 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
6994 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ,
6995 (u8 *)&rx_dma_buff_sz);
6996 rxff_bndy = rx_dma_buff_sz - 1;
6997 rtw_write16(adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
6998 RTW_INFO("%s: normal mode, 0x%04x: 0x%04x\n", __func__,
7000 rtw_read16(adapter, (REG_TRXFF_BNDY + 2)));
7004 bool rtw_read_from_frame_mask(_adapter *adapter, u8 idx)
7006 u32 data_l = 0, data_h = 0, rx_dma_buff_sz = 0, page_sz = 0;
7007 u16 offset, rx_buf_ptr = 0;
7008 u16 cam_start_offset = 0;
7009 u16 ctrl_l = 0, ctrl_h = 0;
7010 u8 count = 0, tmp = 0;
7014 if (idx > MAX_WKFM_CAM_NUM) {
7015 RTW_INFO("[Error]: %s, pattern index is out of range\n",
7020 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
7021 (u8 *)&rx_dma_buff_sz);
7023 if (rx_dma_buff_sz == 0) {
7024 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
7028 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
7031 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
7035 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
7036 cam_start_offset = offset * page_sz;
7041 /* Enable RX packet buffer access */
7042 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
7044 /* Read the WKFM CAM */
7045 for (i = 0; i < (WKFMCAM_ADDR_NUM / 2); i++) {
7047 * Set Rx packet buffer offset.
7048 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
7049 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
7050 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
7051 * * Index: The index of the wake up frame mask
7052 * * WKFMCAM_SIZE: the total size of one WKFM CAM
7053 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
7056 (cam_start_offset + idx * WKFMCAM_SIZE + i * 8) >> 3;
7057 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
7059 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
7060 data_l = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
7061 data_h = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
7063 RTW_INFO("[%d]: %08x %08x\n", i, data_h, data_l);
7068 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
7071 } while (!tmp && count < 100);
7074 RTW_INFO("%s count:%d\n", __func__, count);
7079 /* Disable RX packet buffer access */
7080 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
7081 DISABLE_TRXPKT_BUF_ACCESS);
7085 bool rtw_write_to_frame_mask(_adapter *adapter, u8 idx,
7086 struct rtl_wow_pattern *context)
7088 u32 data = 0, rx_dma_buff_sz = 0, page_sz = 0;
7089 u16 offset, rx_buf_ptr = 0;
7090 u16 cam_start_offset = 0;
7091 u16 ctrl_l = 0, ctrl_h = 0;
7092 u8 count = 0, tmp = 0;
7095 if (idx > MAX_WKFM_CAM_NUM) {
7096 RTW_INFO("[Error]: %s, pattern index is out of range\n",
7101 rtw_hal_get_def_var(adapter, HAL_DEF_RX_DMA_SZ_WOW,
7102 (u8 *)&rx_dma_buff_sz);
7104 if (rx_dma_buff_sz == 0) {
7105 RTW_INFO("[Error]: %s, rx_dma_buff_sz is 0!!\n", __func__);
7109 rtw_hal_get_def_var(adapter, HAL_DEF_RX_PAGE_SIZE, (u8 *)&page_sz);
7112 RTW_INFO("[Error]: %s, page_sz is 0!!\n", __func__);
7116 offset = (u16)PageNum(rx_dma_buff_sz, page_sz);
7118 cam_start_offset = offset * page_sz;
7120 if (IS_HARDWARE_TYPE_8188E(adapter)) {
7128 /* Enable RX packet buffer access */
7129 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, RXPKT_BUF_SELECT);
7131 /* Write the WKFM CAM */
7132 for (i = 0; i < WKFMCAM_ADDR_NUM; i++) {
7134 * Set Rx packet buffer offset.
7135 * RxBufer pointer increases 1, we can access 8 bytes in Rx packet buffer.
7136 * CAM start offset (unit: 1 byte) = Index*WKFMCAM_SIZE
7137 * RxBufer pointer addr = (CAM start offset + per entry offset of a WKFMCAM)/8
7138 * * Index: The index of the wake up frame mask
7139 * * WKFMCAM_SIZE: the total size of one WKFM CAM
7140 * * per entry offset of a WKFM CAM: Addr i * 4 bytes
7143 (cam_start_offset + idx * WKFMCAM_SIZE + i * 4) >> 3;
7144 rtw_write16(adapter, REG_PKTBUF_DBG_CTRL, rx_buf_ptr);
7147 if (context->type == PATTERN_VALID)
7149 else if (context->type == PATTERN_BROADCAST)
7150 data = BIT(31) | BIT(26);
7151 else if (context->type == PATTERN_MULTICAST)
7152 data = BIT(31) | BIT(25);
7153 else if (context->type == PATTERN_UNICAST)
7154 data = BIT(31) | BIT(24);
7156 if (context->crc != 0)
7157 data |= context->crc;
7159 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
7160 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
7161 } else if (i == 1) {
7163 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
7164 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
7165 } else if (i == 2 || i == 4) {
7166 data = context->mask[i - 2];
7167 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_L, data);
7168 /* write to RX packet buffer*/
7169 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_l);
7170 } else if (i == 3 || i == 5) {
7171 data = context->mask[i - 2];
7172 rtw_write32(adapter, REG_PKTBUF_DBG_DATA_H, data);
7173 /* write to RX packet buffer*/
7174 rtw_write16(adapter, REG_RXPKTBUF_CTRL, ctrl_h);
7179 tmp = rtw_read8(adapter, REG_RXPKTBUF_CTRL);
7182 } while (tmp && count < 100);
7190 /* Disable RX packet buffer access */
7191 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL,
7192 DISABLE_TRXPKT_BUF_ACCESS);
7196 void rtw_clean_pattern(_adapter *adapter)
7198 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
7199 struct rtl_wow_pattern zero_pattern;
7202 _rtw_memset(&zero_pattern, 0, sizeof(struct rtl_wow_pattern));
7204 zero_pattern.type = PATTERN_INVALID;
7206 for (i = 0; i < MAX_WKFM_CAM_NUM; i++)
7207 rtw_write_to_frame_mask(adapter, i, &zero_pattern);
7209 rtw_write8(adapter, REG_WKFMCAM_NUM, 0);
7211 static int rtw_hal_set_pattern(_adapter *adapter, u8 *pattern,
7212 u8 len, u8 *mask, u8 idx)
7214 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
7215 struct mlme_ext_priv *pmlmeext = NULL;
7216 struct mlme_ext_info *pmlmeinfo = NULL;
7217 struct rtl_wow_pattern wow_pattern;
7218 u8 mask_hw[MAX_WKFM_SIZE] = {0};
7219 u8 content[MAX_WKFM_PATTERN_SIZE] = {0};
7220 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7221 u8 multicast_addr1[2] = {0x33, 0x33};
7222 u8 multicast_addr2[3] = {0x01, 0x00, 0x5e};
7223 u8 res = _FALSE, index = 0, mask_len = 0;
7224 u8 mac_addr[ETH_ALEN] = {0};
7228 if (pwrctl->wowlan_pattern_idx > MAX_WKFM_CAM_NUM) {
7229 RTW_INFO("%s pattern_idx is more than MAX_FMC_NUM: %d\n",
7230 __func__, MAX_WKFM_CAM_NUM);
7234 pmlmeext = &adapter->mlmeextpriv;
7235 pmlmeinfo = &pmlmeext->mlmext_info;
7236 _rtw_memcpy(mac_addr, adapter_mac_addr(adapter), ETH_ALEN);
7237 _rtw_memset(&wow_pattern, 0, sizeof(struct rtl_wow_pattern));
7239 mask_len = DIV_ROUND_UP(len, 8);
7241 /* 1. setup A1 table */
7242 if (memcmp(pattern, broadcast_addr, ETH_ALEN) == 0)
7243 wow_pattern.type = PATTERN_BROADCAST;
7244 else if (memcmp(pattern, multicast_addr1, 2) == 0)
7245 wow_pattern.type = PATTERN_MULTICAST;
7246 else if (memcmp(pattern, multicast_addr2, 3) == 0)
7247 wow_pattern.type = PATTERN_MULTICAST;
7248 else if (memcmp(pattern, mac_addr, ETH_ALEN) == 0)
7249 wow_pattern.type = PATTERN_UNICAST;
7251 wow_pattern.type = PATTERN_INVALID;
7253 /* translate mask from os to mask for hw */
7255 /******************************************************************************
7256 * pattern from OS uses 'ethenet frame', like this:
7258 | 6 | 6 | 2 | 20 | Variable | 4 |
7259 |--------+--------+------+-----------+------------+-----|
7260 | 802.3 Mac Header | IP Header | TCP Packet | FCS |
7263 * BUT, packet catched by our HW is in '802.11 frame', begin from LLC,
7265 | 24 or 30 | 6 | 2 | 20 | Variable | 4 |
7266 |-------------------+--------+------+-----------+------------+-----|
7267 | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS |
7270 * Therefore, we need translate mask_from_OS to mask_to_hw.
7271 * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0,
7272 * because new mask[0~5] means 'SA', but our HW packet begins from LLC,
7273 * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match.
7274 ******************************************************************************/
7276 for (i = 0; i < mask_len - 1; i++) {
7277 mask_hw[i] = mask[i] >> 6;
7278 mask_hw[i] |= (mask[i + 1] & 0x3F) << 2;
7281 mask_hw[i] = (mask[i] >> 6) & 0x3F;
7282 /* Set bit 0-5 to zero */
7285 for (i = 0; i < (MAX_WKFM_SIZE / 4); i++) {
7286 wow_pattern.mask[i] = mask_hw[i * 4];
7287 wow_pattern.mask[i] |= (mask_hw[i * 4 + 1] << 8);
7288 wow_pattern.mask[i] |= (mask_hw[i * 4 + 2] << 16);
7289 wow_pattern.mask[i] |= (mask_hw[i * 4 + 3] << 24);
7292 /* To get the wake up pattern from the mask.
7293 * We do not count first 12 bits which means
7294 * DA[6] and SA[6] in the pattern to match HW design. */
7296 for (i = 12; i < len; i++) {
7297 if ((mask[i / 8] >> (i % 8)) & 0x01) {
7298 content[count] = pattern[i];
7303 wow_pattern.crc = rtw_calc_crc(content, count);
7305 if (wow_pattern.crc != 0) {
7306 if (wow_pattern.type == PATTERN_INVALID)
7307 wow_pattern.type = PATTERN_VALID;
7312 if (!pwrctl->bInSuspend)
7316 res = rtw_write_to_frame_mask(adapter, index, &wow_pattern);
7319 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n",
7324 void rtw_fill_pattern(_adapter *adapter)
7326 int i = 0, total = 0, index;
7327 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
7328 struct rtl_wow_pattern wow_pattern;
7330 total = pwrpriv->wowlan_pattern_idx;
7332 if (total > MAX_WKFM_CAM_NUM)
7333 total = MAX_WKFM_CAM_NUM;
7335 for (i = 0 ; i < total ; i++) {
7336 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
7339 if (!pwrpriv->bInSuspend)
7342 if (rtw_write_to_frame_mask(adapter, index, &wow_pattern) == _FALSE)
7343 RTW_INFO("%s: ERROR!! idx: %d write_to_frame_mask_cam fail\n", __func__, i);
7347 rtw_write8(adapter, REG_WKFMCAM_NUM, total);
7351 #else /*CONFIG_WOW_PATTERN_HW_CAM*/
7353 #define WOW_CAM_ACCESS_TIMEOUT_MS 200
7354 #define WOW_VALID_BIT BIT31
7355 #define WOW_BC_BIT BIT26
7356 #define WOW_MC_BIT BIT25
7357 #define WOW_UC_BIT BIT24
7359 static u32 _rtw_wow_pattern_read_cam(_adapter *adapter, u8 addr)
7361 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
7362 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
7370 _enter_critical_mutex(mutex, NULL);
7372 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_ADDR_V2(addr));
7374 start = rtw_get_current_time();
7376 if (rtw_is_surprise_removed(adapter))
7380 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
7384 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
7390 rdata = rtw_read32(adapter, REG_WKFMCAM_RWD);
7392 _exit_critical_mutex(mutex, NULL);
7394 /*RTW_INFO("%s ==> addr:0x%02x , rdata:0x%08x\n", __func__, addr, rdata);*/
7397 RTW_ERR(FUNC_ADPT_FMT" failed due to polling timeout\n", FUNC_ADPT_ARG(adapter));
7401 void rtw_wow_pattern_read_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
7406 _rtw_memset(context, 0, sizeof(struct rtl_wow_pattern));
7408 for (i = 4; i >= 0; i--) {
7409 rdata = _rtw_wow_pattern_read_cam(adapter, (id << 3) | i);
7413 if (rdata & WOW_BC_BIT)
7414 context->type = PATTERN_BROADCAST;
7415 else if (rdata & WOW_MC_BIT)
7416 context->type = PATTERN_MULTICAST;
7417 else if (rdata & WOW_UC_BIT)
7418 context->type = PATTERN_UNICAST;
7420 context->type = PATTERN_INVALID;
7422 context->crc = rdata & 0xFFFF;
7425 _rtw_memcpy(&context->mask[i], (u8 *)(&rdata), 4);
7431 static void _rtw_wow_pattern_write_cam(_adapter *adapter, u8 addr, u32 wdata)
7433 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
7434 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
7436 u32 start = 0, end = 0;
7439 /*RTW_INFO("%s ==> addr:0x%02x , wdata:0x%08x\n", __func__, addr, wdata);*/
7440 _enter_critical_mutex(mutex, NULL);
7442 rtw_write32(adapter, REG_WKFMCAM_RWD, wdata);
7443 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr));
7445 start = rtw_get_current_time();
7447 if (rtw_is_surprise_removed(adapter))
7451 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1))
7454 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
7459 end = rtw_get_current_time();
7461 _exit_critical_mutex(mutex, NULL);
7464 RTW_ERR(FUNC_ADPT_FMT" addr:0x%02x, wdata:0x%08x, to:%u, polling:%u, %d ms\n"
7465 , FUNC_ADPT_ARG(adapter), addr, wdata, timeout, cnt, rtw_get_time_interval_ms(start, end));
7469 void rtw_wow_pattern_write_cam_ent(_adapter *adapter, u8 id, struct rtl_wow_pattern *context)
7475 for (j = 4; j >= 0; j--) {
7478 wdata = context->crc;
7480 if (PATTERN_BROADCAST == context->type)
7481 wdata |= WOW_BC_BIT;
7482 if (PATTERN_MULTICAST == context->type)
7483 wdata |= WOW_MC_BIT;
7484 if (PATTERN_UNICAST == context->type)
7485 wdata |= WOW_UC_BIT;
7486 if (PATTERN_INVALID != context->type)
7487 wdata |= WOW_VALID_BIT;
7490 wdata = context->mask[j];
7494 addr = (id << 3) + j;
7496 _rtw_wow_pattern_write_cam(adapter, addr, wdata);
7500 static u8 _rtw_wow_pattern_clean_cam(_adapter *adapter)
7502 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
7503 _mutex *mutex = &pwrpriv->wowlan_pattern_cam_mutex;
7509 _enter_critical_mutex(mutex, NULL);
7510 rtw_write32(adapter, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | BIT_WKFCAM_CLR_V1);
7512 start = rtw_get_current_time();
7514 if (rtw_is_surprise_removed(adapter))
7518 if (0 == (rtw_read32(adapter, REG_WKFMCAM_CMD) & BIT_WKFCAM_POLLING_V1)) {
7522 if (rtw_get_passing_time_ms(start) > WOW_CAM_ACCESS_TIMEOUT_MS) {
7527 _exit_critical_mutex(mutex, NULL);
7530 RTW_ERR(FUNC_ADPT_FMT" falied ,polling timeout\n", FUNC_ADPT_ARG(adapter));
7535 void rtw_clean_pattern(_adapter *adapter)
7537 if (_FAIL == _rtw_wow_pattern_clean_cam(adapter))
7538 RTW_ERR("rtw_clean_pattern failed\n");
7541 void rtw_dump_wow_pattern(void *sel, struct rtl_wow_pattern *pwow_pattern, u8 idx)
7545 RTW_PRINT_SEL(sel, "=======WOW CAM-ID[%d]=======\n", idx);
7546 RTW_PRINT_SEL(sel, "[WOW CAM] type:%d\n", pwow_pattern->type);
7547 RTW_PRINT_SEL(sel, "[WOW CAM] crc:0x%04x\n", pwow_pattern->crc);
7548 for (j = 0; j < 4; j++)
7549 RTW_PRINT_SEL(sel, "[WOW CAM] Mask:0x%08x\n", pwow_pattern->mask[j]);
7552 void rtw_fill_pattern(_adapter *adapter)
7554 int i = 0, total = 0;
7555 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
7556 struct rtl_wow_pattern wow_pattern;
7558 total = pwrpriv->wowlan_pattern_idx;
7560 if (total > MAX_WKFM_CAM_NUM)
7561 total = MAX_WKFM_CAM_NUM;
7563 for (i = 0 ; i < total ; i++) {
7564 if (_SUCCESS == rtw_hal_wow_pattern_generate(adapter, i, &wow_pattern)) {
7565 rtw_dump_wow_pattern(RTW_DBGDUMP, &wow_pattern, i);
7566 rtw_wow_pattern_write_cam_ent(adapter, i, &wow_pattern);
7572 void rtw_wow_pattern_cam_dump(_adapter *adapter)
7575 #ifndef CONFIG_WOW_PATTERN_HW_CAM
7578 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
7579 RTW_INFO("=======[%d]=======\n", i);
7580 rtw_read_from_frame_mask(adapter, i);
7583 struct rtl_wow_pattern context;
7586 for (i = 0 ; i < MAX_WKFM_CAM_NUM; i++) {
7587 rtw_wow_pattern_read_cam_ent(adapter, i, &context);
7588 rtw_dump_wow_pattern(RTW_DBGDUMP, &context, i);
7595 static void rtw_hal_dl_pattern(_adapter *adapter, u8 mode)
7597 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
7601 rtw_clean_pattern(adapter);
7602 RTW_INFO("%s: total patterns: %d\n", __func__, pwrpriv->wowlan_pattern_idx);
7605 rtw_set_default_pattern(adapter);
7606 rtw_fill_pattern(adapter);
7607 RTW_INFO("%s: pattern total: %d downloaded\n", __func__, pwrpriv->wowlan_pattern_idx);
7610 rtw_clean_pattern(adapter);
7611 rtw_wow_pattern_sw_reset(adapter);
7612 RTW_INFO("%s: clean patterns\n", __func__);
7615 RTW_INFO("%s: unknown mode\n", __func__);
7620 static void rtw_hal_wow_enable(_adapter *adapter)
7622 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
7623 struct security_priv *psecuritypriv = &adapter->securitypriv;
7624 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
7625 struct hal_ops *pHalFunc = &adapter->hal_func;
7626 struct sta_info *psta = NULL;
7627 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
7629 u16 media_status_rpt;
7632 RTW_PRINT("%s, WOWLAN_ENABLE\n", __func__);
7633 rtw_hal_gate_bb(adapter, _TRUE);
7634 #ifdef CONFIG_GTK_OL
7635 if (psecuritypriv->binstallKCK_KEK == _TRUE)
7636 rtw_hal_fw_sync_cam_id(adapter);
7638 if (IS_HARDWARE_TYPE_8723B(adapter))
7639 rtw_hal_backup_rate(adapter);
7642 #if defined(CONFIG_RTL8188E)
7643 if (IS_HARDWARE_TYPE_8188E(adapter))
7644 rtw_hal_disable_tx_report(adapter);
7647 res = rtw_hal_pause_rx_dma(adapter);
7649 RTW_PRINT("[WARNING] pause RX DMA fail\n");
7651 #ifndef CONFIG_WOW_PATTERN_HW_CAM
7652 /* Reconfig RX_FF Boundary */
7653 rtw_hal_set_wow_rxff_boundary(adapter, _TRUE);
7656 /* redownload wow pattern */
7657 rtw_hal_dl_pattern(adapter, 1);
7659 rtw_hal_fw_dl(adapter, _TRUE);
7660 media_status_rpt = RT_MEDIA_CONNECT;
7661 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
7662 (u8 *)&media_status_rpt);
7664 if (!pwrctl->wowlan_pno_enable) {
7665 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
7668 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
7669 rtw_hal_set_default_port_id_cmd(adapter, psta->mac_id);
7672 rtw_sta_media_status_rpt(adapter, psta, 1);
7676 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
7677 /* Enable CPWM2 only. */
7678 res = rtw_hal_enable_cpwm2(adapter);
7680 RTW_PRINT("[WARNING] enable cpwm2 fail\n");
7682 #ifdef CONFIG_GPIO_WAKEUP
7683 rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _TRUE);
7685 /* Set WOWLAN H2C command. */
7686 RTW_PRINT("Set WOWLan cmd\n");
7687 rtw_hal_set_fw_wow_related_cmd(adapter, 1);
7689 res = rtw_hal_check_wow_ctrl(adapter, _TRUE);
7692 RTW_INFO("[Error]%s: set wowlan CMD fail!!\n", __func__);
7694 pwrctl->wowlan_wake_reason =
7695 rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
7697 RTW_PRINT("wowlan_wake_reason: 0x%02x\n",
7698 pwrctl->wowlan_wake_reason);
7699 #ifdef CONFIG_GTK_OL_DBG
7700 dump_sec_cam(RTW_DBGDUMP, adapter);
7701 dump_sec_cam_cache(RTW_DBGDUMP, adapter);
7703 #ifdef CONFIG_USB_HCI
7704 /* free adapter's resource */
7705 rtw_mi_intf_stop(adapter);
7707 /* Invoid SE0 reset signal during suspending*/
7708 rtw_write8(adapter, REG_RSV_CTRL, 0x20);
7709 if (IS_8188F(pHalData->version_id) == FALSE)
7710 rtw_write8(adapter, REG_RSV_CTRL, 0x60);
7711 #endif /*CONFIG_USB_HCI*/
7713 rtw_hal_gate_bb(adapter, _FALSE);
7716 #define DBG_WAKEUP_REASON
7717 #ifdef DBG_WAKEUP_REASON
7718 void _dbg_wake_up_reason_string(_adapter *adapter, const char *srt_res)
7720 RTW_INFO(ADPT_FMT "- wake up reason - %s\n", ADPT_ARG(adapter), srt_res);
7722 void _dbg_rtw_wake_up_reason(_adapter *adapter, u8 reason)
7724 if (RX_PAIRWISEKEY == reason)
7725 _dbg_wake_up_reason_string(adapter, "Rx pairwise key");
7726 else if (RX_GTK == reason)
7727 _dbg_wake_up_reason_string(adapter, "Rx GTK");
7728 else if (RX_FOURWAY_HANDSHAKE == reason)
7729 _dbg_wake_up_reason_string(adapter, "Rx four way handshake");
7730 else if (RX_DISASSOC == reason)
7731 _dbg_wake_up_reason_string(adapter, "Rx disassoc");
7732 else if (RX_DEAUTH == reason)
7733 _dbg_wake_up_reason_string(adapter, "Rx deauth");
7734 else if (RX_ARP_REQUEST == reason)
7735 _dbg_wake_up_reason_string(adapter, "Rx ARP request");
7736 else if (FW_DECISION_DISCONNECT == reason)
7737 _dbg_wake_up_reason_string(adapter, "FW detect disconnect");
7738 else if (RX_MAGIC_PKT == reason)
7739 _dbg_wake_up_reason_string(adapter, "Rx magic packet");
7740 else if (RX_UNICAST_PKT == reason)
7741 _dbg_wake_up_reason_string(adapter, "Rx unicast packet");
7742 else if (RX_PATTERN_PKT == reason)
7743 _dbg_wake_up_reason_string(adapter, "Rx pattern packet");
7744 else if (RTD3_SSID_MATCH == reason)
7745 _dbg_wake_up_reason_string(adapter, "RTD3 SSID match");
7746 else if (RX_REALWOW_V2_WAKEUP_PKT == reason)
7747 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 wakeup packet");
7748 else if (RX_REALWOW_V2_ACK_LOST == reason)
7749 _dbg_wake_up_reason_string(adapter, "Rx real WOW V2 ack lost");
7750 else if (ENABLE_FAIL_DMA_IDLE == reason)
7751 _dbg_wake_up_reason_string(adapter, "enable fail DMA idle");
7752 else if (ENABLE_FAIL_DMA_PAUSE == reason)
7753 _dbg_wake_up_reason_string(adapter, "enable fail DMA pause");
7754 else if (AP_OFFLOAD_WAKEUP == reason)
7755 _dbg_wake_up_reason_string(adapter, "AP offload wakeup");
7756 else if (CLK_32K_UNLOCK == reason)
7757 _dbg_wake_up_reason_string(adapter, "clk 32k unlock");
7758 else if (RTIME_FAIL_DMA_IDLE == reason)
7759 _dbg_wake_up_reason_string(adapter, "RTIME fail DMA idle");
7760 else if (CLK_32K_LOCK == reason)
7761 _dbg_wake_up_reason_string(adapter, "clk 32k lock");
7763 _dbg_wake_up_reason_string(adapter, "unknown reasoen");
7767 static void rtw_hal_wow_disable(_adapter *adapter)
7769 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(adapter);
7770 struct security_priv *psecuritypriv = &adapter->securitypriv;
7771 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
7772 struct hal_ops *pHalFunc = &adapter->hal_func;
7773 struct sta_info *psta = NULL;
7775 u16 media_status_rpt;
7778 RTW_PRINT("%s, WOWLAN_DISABLE\n", __func__);
7780 if (!pwrctl->wowlan_pno_enable) {
7781 psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
7783 rtw_sta_media_status_rpt(adapter, psta, 0);
7785 RTW_INFO("%s: psta is null\n", __func__);
7789 RTW_INFO("0x630:0x%02x\n", rtw_read8(adapter, 0x630));
7790 RTW_INFO("0x631:0x%02x\n", rtw_read8(adapter, 0x631));
7791 RTW_INFO("0x634:0x%02x\n", rtw_read8(adapter, 0x634));
7792 RTW_INFO("0x1c7:0x%02x\n", rtw_read8(adapter, 0x1c7));
7795 pwrctl->wowlan_wake_reason = rtw_read8(adapter, REG_WOWLAN_WAKE_REASON);
7797 RTW_PRINT("wakeup_reason: 0x%02x\n",
7798 pwrctl->wowlan_wake_reason);
7799 #ifdef DBG_WAKEUP_REASON
7800 _dbg_rtw_wake_up_reason(adapter, pwrctl->wowlan_wake_reason);
7803 rtw_hal_set_fw_wow_related_cmd(adapter, 0);
7805 res = rtw_hal_check_wow_ctrl(adapter, _FALSE);
7807 if (res == _FALSE) {
7808 RTW_INFO("[Error]%s: disable WOW cmd fail\n!!", __func__);
7809 rtw_hal_force_enable_rxdma(adapter);
7812 rtw_hal_gate_bb(adapter, _TRUE);
7814 res = rtw_hal_pause_rx_dma(adapter);
7816 RTW_PRINT("[WARNING] pause RX DMA fail\n");
7818 /* clean HW pattern match */
7819 rtw_hal_dl_pattern(adapter, 0);
7821 #ifndef CONFIG_WOW_PATTERN_HW_CAM
7822 /* config RXFF boundary to original */
7823 rtw_hal_set_wow_rxff_boundary(adapter, _FALSE);
7825 rtw_hal_release_rx_dma(adapter);
7827 #if defined(CONFIG_RTL8188E)
7828 if (IS_HARDWARE_TYPE_8188E(adapter))
7829 rtw_hal_enable_tx_report(adapter);
7832 #ifdef CONFIG_GTK_OL
7833 if (((pwrctl->wowlan_wake_reason != RX_DISASSOC) ||
7834 (pwrctl->wowlan_wake_reason != RX_DEAUTH) ||
7835 (pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT)) &&
7836 psecuritypriv->binstallKCK_KEK == _TRUE) {
7837 rtw_hal_get_aoac_rpt(adapter);
7838 rtw_hal_update_sw_security_info(adapter);
7840 #endif /*CONFIG_GTK_OL*/
7842 rtw_hal_fw_dl(adapter, _FALSE);
7844 #ifdef CONFIG_GPIO_WAKEUP
7845 val8 = (pwrctl->is_high_active == 0) ? 1 : 0;
7846 RTW_PRINT("Set Wake GPIO to default(%d).\n", val8);
7847 rtw_hal_set_output_gpio(adapter, WAKEUP_GPIO_IDX, val8);
7849 rtw_hal_switch_gpio_wl_ctrl(adapter, WAKEUP_GPIO_IDX, _FALSE);
7852 if ((pwrctl->wowlan_wake_reason != FW_DECISION_DISCONNECT) &&
7853 (pwrctl->wowlan_wake_reason != RX_PAIRWISEKEY) &&
7854 (pwrctl->wowlan_wake_reason != RX_DISASSOC) &&
7855 (pwrctl->wowlan_wake_reason != RX_DEAUTH)) {
7857 media_status_rpt = RT_MEDIA_CONNECT;
7858 rtw_hal_set_hwreg(adapter, HW_VAR_H2C_FW_JOINBSSRPT,
7859 (u8 *)&media_status_rpt);
7862 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
7863 rtw_hal_set_default_port_id_cmd(adapter, psta->mac_id);
7865 rtw_sta_media_status_rpt(adapter, psta, 1);
7868 rtw_hal_gate_bb(adapter, _FALSE);
7870 #endif /*CONFIG_WOWLAN*/
7872 #ifdef CONFIG_P2P_WOWLAN
7873 void rtw_hal_set_p2p_wow_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 index,
7874 u8 tx_desc, u32 page_size, u8 *page_num, u32 *total_pkt_len,
7875 RSVDPAGE_LOC *rsvd_page_loc)
7877 u32 P2PNegoRspLength = 0, P2PInviteRspLength = 0;
7878 u32 P2PPDRspLength = 0, P2PProbeRspLength = 0, P2PBCNLength = 0;
7879 u8 CurtPktPageNum = 0;
7882 rsvd_page_loc->LocP2PBeacon = *page_num;
7883 rtw_hal_construct_P2PBeacon(adapter, &pframe[index], &P2PBCNLength);
7884 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
7885 P2PBCNLength, _FALSE, _FALSE, _FALSE);
7888 RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
7889 __FUNCTION__, &pframe[index - tx_desc], (P2PBCNLength + tx_desc));
7892 CurtPktPageNum = (u8)PageNum(tx_desc + P2PBCNLength, page_size);
7894 *page_num += CurtPktPageNum;
7896 index += (CurtPktPageNum * page_size);
7899 rsvd_page_loc->LocP2PProbeRsp = *page_num;
7900 rtw_hal_construct_P2PProbeRsp(adapter, &pframe[index],
7901 &P2PProbeRspLength);
7902 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
7903 P2PProbeRspLength, _FALSE, _FALSE, _FALSE);
7905 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", */
7906 /* __FUNCTION__, &pframe[index-tx_desc], (P2PProbeRspLength+tx_desc)); */
7908 CurtPktPageNum = (u8)PageNum(tx_desc + P2PProbeRspLength, page_size);
7910 *page_num += CurtPktPageNum;
7912 index += (CurtPktPageNum * page_size);
7915 rsvd_page_loc->LocNegoRsp = *page_num;
7916 rtw_hal_construct_P2PNegoRsp(adapter, &pframe[index],
7918 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
7919 P2PNegoRspLength, _FALSE, _FALSE, _FALSE);
7921 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
7922 /* __FUNCTION__, &pframe[index-tx_desc], (NegoRspLength+tx_desc)); */
7924 CurtPktPageNum = (u8)PageNum(tx_desc + P2PNegoRspLength, page_size);
7926 *page_num += CurtPktPageNum;
7928 index += (CurtPktPageNum * page_size);
7930 /* P2P invite rsp */
7931 rsvd_page_loc->LocInviteRsp = *page_num;
7932 rtw_hal_construct_P2PInviteRsp(adapter, &pframe[index],
7933 &P2PInviteRspLength);
7934 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
7935 P2PInviteRspLength, _FALSE, _FALSE, _FALSE);
7937 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
7938 /* __FUNCTION__, &pframe[index-tx_desc], (InviteRspLength+tx_desc)); */
7940 CurtPktPageNum = (u8)PageNum(tx_desc + P2PInviteRspLength, page_size);
7942 *page_num += CurtPktPageNum;
7944 index += (CurtPktPageNum * page_size);
7946 /* P2P provision discovery rsp */
7947 rsvd_page_loc->LocPDRsp = *page_num;
7948 rtw_hal_construct_P2PProvisionDisRsp(adapter,
7949 &pframe[index], &P2PPDRspLength);
7951 rtw_hal_fill_fake_txdesc(adapter, &pframe[index - tx_desc],
7952 P2PPDRspLength, _FALSE, _FALSE, _FALSE);
7954 /* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", */
7955 /* __FUNCTION__, &pframe[index-tx_desc], (PDRspLength+tx_desc)); */
7957 CurtPktPageNum = (u8)PageNum(tx_desc + P2PPDRspLength, page_size);
7959 *page_num += CurtPktPageNum;
7961 *total_pkt_len = index + P2PPDRspLength;
7963 index += (CurtPktPageNum * page_size);
7967 #endif /* CONFIG_P2P_WOWLAN */
7969 #ifdef CONFIG_LPS_PG
7970 #include "hal_halmac.h"
7972 #define DBG_LPSPG_SEC_DUMP
7973 #define LPS_PG_INFO_RSVD_LEN 16
7974 #define LPS_PG_INFO_RSVD_PAGE_NUM 1
7976 #define DBG_LPSPG_INFO_DUMP
7977 static void rtw_hal_set_lps_pg_info_rsvd_page(_adapter *adapter)
7979 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
7980 struct sta_info *psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
7981 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
7982 PHAL_DATA_TYPE phal_data = GET_HAL_DATA(adapter);
7983 u8 lps_pg_info[LPS_PG_INFO_RSVD_LEN] = {0};
7984 #ifdef CONFIG_MBSSID_CAM
7985 u8 cam_id = INVALID_CAM_ID;
7987 u8 *psec_cam_id = lps_pg_info + 8;
7991 RTW_ERR("%s [ERROR] sta is NULL\n", __func__);
7996 /*Byte 0 - used macid*/
7997 LPSPG_RSVD_PAGE_SET_MACID(lps_pg_info, psta->mac_id);
7998 RTW_INFO("[LPSPG-INFO] mac_id:%d\n", psta->mac_id);
8000 #ifdef CONFIG_MBSSID_CAM
8001 /*Byte 1 - used BSSID CAM entry*/
8002 cam_id = rtw_mbid_cam_search_by_ifaceid(adapter, adapter->iface_id);
8003 if (cam_id != INVALID_CAM_ID)
8004 LPSPG_RSVD_PAGE_SET_MBSSCAMID(lps_pg_info, cam_id);
8005 RTW_INFO("[LPSPG-INFO] mbss_cam_id:%d\n", cam_id);
8008 #ifdef CONFIG_WOWLAN /*&& pattern match cam used*/
8009 /*Btye 2 - Max used Pattern Match CAM entry*/
8010 if (pwrpriv->wowlan_mode == _TRUE &&
8011 check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _TRUE) {
8012 LPSPG_RSVD_PAGE_SET_PMC_NUM(lps_pg_info, pwrpriv->wowlan_pattern_idx);
8013 RTW_INFO("[LPSPG-INFO] Max Pattern Match CAM entry :%d\n", pwrpriv->wowlan_pattern_idx);
8016 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
8017 /*Btye 3 - Max MU rate table Group ID*/
8018 LPSPG_RSVD_PAGE_SET_MU_RAID_GID(lps_pg_info, _value);
8019 RTW_INFO("[LPSPG-INFO] Max MU rate table Group ID :%d\n", _value);
8022 /*Btye 8 ~15 - used Security CAM entry */
8023 sec_cam_num = rtw_get_sec_camid(adapter, 8, psec_cam_id);
8025 /*Btye 4 - used Security CAM entry number*/
8026 if (sec_cam_num < 8)
8027 LPSPG_RSVD_PAGE_SET_SEC_CAM_NUM(lps_pg_info, sec_cam_num);
8028 RTW_INFO("[LPSPG-INFO] Security CAM entry number :%d\n", sec_cam_num);
8030 /*Btye 5 - Txbuf used page number for fw offload*/
8031 LPSPG_RSVD_PAGE_SET_DRV_RSVDPAGE_NUM(lps_pg_info, phal_data->drv_rsvd_page_number);
8032 RTW_INFO("[LPSPG-INFO] DRV's rsvd page numbers :%d\n", phal_data->drv_rsvd_page_number);
8034 #ifdef DBG_LPSPG_SEC_DUMP
8038 for (i = 0; i < sec_cam_num; i++)
8039 RTW_INFO("%d = sec_cam_id:%d\n", i, psec_cam_id[i]);
8043 #ifdef DBG_LPSPG_INFO_DUMP
8044 RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
8045 RTW_INFO(" %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
8046 *(lps_pg_info), *(lps_pg_info + 1), *(lps_pg_info + 2), *(lps_pg_info + 3),
8047 *(lps_pg_info + 4), *(lps_pg_info + 5), *(lps_pg_info + 6), *(lps_pg_info + 7));
8048 RTW_INFO(" %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
8049 *(lps_pg_info + 8), *(lps_pg_info + 9), *(lps_pg_info + 10), *(lps_pg_info + 11),
8050 *(lps_pg_info + 12), *(lps_pg_info + 13), *(lps_pg_info + 14), *(lps_pg_info + 15));
8051 RTW_INFO("==== DBG_LPSPG_INFO_RSVD_PAGE_DUMP====\n");
8054 rtw_halmac_download_rsvd_page(dvobj, pwrpriv->lpspg_rsvd_page_locate, lps_pg_info, LPS_PG_INFO_RSVD_LEN);
8056 #ifdef DBG_LPSPG_INFO_DUMP
8057 RTW_INFO("Get LPS-PG INFO from rsvd page_offset:%d\n", pwrpriv->lpspg_rsvd_page_locate);
8058 rtw_dump_rsvd_page(RTW_DBGDUMP, adapter, pwrpriv->lpspg_rsvd_page_locate, 1);
8063 static u8 rtw_hal_set_lps_pg_info_cmd(_adapter *adapter)
8065 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8066 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8068 u8 lpspg_info[H2C_LPS_PG_INFO_LEN] = {0};
8071 RTW_INFO("%s: loc_lpspg_info:%d\n", __func__, pwrpriv->lpspg_rsvd_page_locate);
8073 if (_NO_PRIVACY_ != adapter->securitypriv.dot11PrivacyAlgrthm)
8074 SET_H2CCMD_LPSPG_SEC_CAM_EN(lpspg_info, 1); /*SecurityCAM_En*/
8075 #ifdef CONFIG_MBSSID_CAM
8076 SET_H2CCMD_LPSPG_MBID_CAM_EN(lpspg_info, 1); /*BSSIDCAM_En*/
8079 #if defined(CONFIG_WOWLAN) && defined(CONFIG_WOW_PATTERN_HW_CAM)
8080 if (pwrpriv->wowlan_mode == _TRUE &&
8081 check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
8083 SET_H2CCMD_LPSPG_PMC_CAM_EN(lpspg_info, 1); /*PatternMatchCAM_En*/
8087 #ifdef CONFIG_MACID_SEARCH
8088 SET_H2CCMD_LPSPG_MACID_SEARCH_EN(lpspg_info, 1); /*MACIDSearch_En*/
8092 SET_H2CCMD_LPSPG_TXSC_EN(lpspg_info, 1); /*TXSC_En*/
8095 #ifdef CONFIG_BEAMFORMING /*&& MU BF*/
8096 SET_H2CCMD_LPSPG_MU_RATE_TB_EN(lpspg_info, 1); /*MURateTable_En*/
8099 SET_H2CCMD_LPSPG_LOC(lpspg_info, pwrpriv->lpspg_rsvd_page_locate);
8101 #ifdef DBG_LPSPG_INFO_DUMP
8102 RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
8103 RTW_INFO(" H2C_CMD: 0x%02x, H2C_LEN: %d\n", H2C_LPS_PG_INFO, H2C_LPS_PG_INFO_LEN);
8104 RTW_INFO(" %02X:%02X\n", *(lpspg_info), *(lpspg_info + 1));
8105 RTW_INFO("==== DBG_LPSPG_INFO_CMD_DUMP====\n");
8108 ret = rtw_hal_fill_h2c_cmd(adapter,
8110 H2C_LPS_PG_INFO_LEN,
8114 u8 rtw_hal_set_lps_pg_info(_adapter *adapter)
8117 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
8119 if (pwrpriv->lpspg_rsvd_page_locate == 0) {
8120 RTW_ERR("%s [ERROR] lpspg_rsvd_page_locate = 0\n", __func__);
8125 rtw_hal_set_lps_pg_info_rsvd_page(adapter);
8126 ret = rtw_hal_set_lps_pg_info_cmd(adapter);
8127 if (_SUCCESS == ret)
8128 pwrpriv->blpspg_info_up = _FALSE;
8133 void rtw_hal_lps_pg_handler(_adapter *adapter, enum lps_pg_hdl_id hdl_id)
8136 case LPS_PG_INFO_CFG:
8137 rtw_hal_set_lps_pg_info(adapter);
8139 case LPS_PG_REDLEMEM:
8140 /*rtw_halmac_redl_fw();*/
8143 case LPS_PG_RESEND_H2C:
8145 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
8146 struct sta_info *sta;
8147 PHAL_DATA_TYPE hal_data = GET_HAL_DATA(adapter);
8150 for (i = 0; i < MACID_NUM_SW_LIMIT; i++) {
8151 sta = macid_ctl->sta[i];
8152 if (sta && !is_broadcast_mac_addr(sta->hwaddr)) {
8153 /*rtw_dm_ra_mask_hdl(adapter, sta);*/
8154 /*phydm_rssi_report(hal_data->odmpriv, sta->mac_id);*/
8165 #endif /*CONFIG_LPS_PG*/
8168 * Description: Fill the reserved packets that FW will use to RSVD page.
8169 * Now we just send 4 types packet to rsvd page.
8170 * (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
8172 * finished - FALSE:At the first time we will send all the packets as a large packet to Hw,
8173 * so we need to set the packet length to total lengh.
8174 * TRUE: At the second time, we should send the first packet (default:beacon)
8175 * to Hw again and set the lengh in descriptor to the real beacon lengh.
8176 * 2009.10.15 by tynli.
8178 * Page Size = 128: 8188e, 8723a/b, 8192c/d,
8179 * Page Size = 256: 8192e, 8821a
8180 * Page Size = 512: 8812a
8183 /*#define DBG_DUMP_SET_RSVD_PAGE*/
8184 void rtw_hal_set_fw_rsvd_page(_adapter *adapter, bool finished)
8186 PHAL_DATA_TYPE pHalData;
8187 struct xmit_frame *pcmdframe;
8188 struct pkt_attrib *pattrib;
8189 struct xmit_priv *pxmitpriv;
8190 struct mlme_ext_priv *pmlmeext;
8191 struct mlme_ext_info *pmlmeinfo;
8192 struct pwrctrl_priv *pwrctl;
8193 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
8194 struct hal_ops *pHalFunc = &adapter->hal_func;
8195 u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength = 0;
8196 u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;
8197 u32 ProbeReqLength = 0, NullFunctionDataLength = 0;
8198 u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
8199 u8 TotalPageNum = 0 , CurtPktPageNum = 0 , RsvdPageNum = 0;
8200 u8 *ReservedPagePacket;
8202 u32 TotalPacketLen = 0, MaxRsvdPageBufSize = 0, PageSize = 0;
8203 RSVDPAGE_LOC RsvdPageLoc;
8205 #ifdef DBG_CONFIG_ERROR_DETECT
8206 struct sreset_priv *psrtpriv;
8207 #endif /* DBG_CONFIG_ERROR_DETECT */
8209 #ifdef CONFIG_MCC_MODE
8210 u8 dl_mcc_page = _FAIL;
8211 #endif /* CONFIG_MCC_MODE */
8213 pHalData = GET_HAL_DATA(adapter);
8214 #ifdef DBG_CONFIG_ERROR_DETECT
8215 psrtpriv = &pHalData->srestpriv;
8217 pxmitpriv = &adapter->xmitpriv;
8218 pmlmeext = &adapter->mlmeextpriv;
8219 pmlmeinfo = &pmlmeext->mlmext_info;
8220 pwrctl = adapter_to_pwrctl(adapter);
8222 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
8224 if (PageSize == 0) {
8225 RTW_INFO("[Error]: %s, PageSize is zero!!\n", __func__);
8229 if (pwrctl->wowlan_mode == _TRUE || pwrctl->wowlan_ap_mode == _TRUE)
8230 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _TRUE);
8232 RsvdPageNum = rtw_hal_get_txbuff_rsvd_page_num(adapter, _FALSE);
8234 RTW_INFO("%s PageSize: %d, RsvdPageNUm: %d\n", __func__, PageSize, RsvdPageNum);
8236 MaxRsvdPageBufSize = RsvdPageNum * PageSize;
8238 if (MaxRsvdPageBufSize > MAX_CMDBUF_SZ) {
8239 RTW_INFO("%s MaxRsvdPageBufSize(%d) is larger than MAX_CMDBUF_SZ(%d)",
8240 __func__, MaxRsvdPageBufSize, MAX_CMDBUF_SZ);
8245 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
8247 if (pcmdframe == NULL) {
8248 RTW_INFO("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
8252 ReservedPagePacket = pcmdframe->buf_addr;
8253 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
8255 /* beacon * 2 pages */
8256 BufIndex = TxDescOffset;
8257 rtw_hal_construct_beacon(adapter,
8258 &ReservedPagePacket[BufIndex], &BeaconLength);
8261 * When we count the first page size, we need to reserve description size for the RSVD
8262 * packet, it will be filled in front of the packet in TXPKTBUF.
8264 CurtPktPageNum = (u8)PageNum((TxDescLen + BeaconLength), PageSize);
8265 /* If we don't add 1 more page, ARP offload function will fail at 8723bs.*/
8266 if (CurtPktPageNum == 1)
8267 CurtPktPageNum += 1;
8269 TotalPageNum += CurtPktPageNum;
8271 BufIndex += (CurtPktPageNum * PageSize);
8273 if (pwrctl->wowlan_ap_mode == _TRUE) {
8274 /* (4) probe response*/
8275 RsvdPageLoc.LocProbeRsp = TotalPageNum;
8276 rtw_hal_construct_ProbeRsp(
8277 adapter, &ReservedPagePacket[BufIndex],
8279 get_my_bssid(&pmlmeinfo->network), _FALSE);
8280 rtw_hal_fill_fake_txdesc(adapter,
8281 &ReservedPagePacket[BufIndex - TxDescLen],
8282 ProbeRspLength, _FALSE, _FALSE, _FALSE);
8284 CurtPktPageNum = (u8)PageNum(TxDescLen + ProbeRspLength, PageSize);
8285 TotalPageNum += CurtPktPageNum;
8286 TotalPacketLen = BufIndex + ProbeRspLength;
8287 BufIndex += (CurtPktPageNum * PageSize);
8291 /* ps-poll * 1 page */
8292 RsvdPageLoc.LocPsPoll = TotalPageNum;
8293 RTW_INFO("LocPsPoll: %d\n", RsvdPageLoc.LocPsPoll);
8294 rtw_hal_construct_PSPoll(adapter,
8295 &ReservedPagePacket[BufIndex], &PSPollLength);
8296 rtw_hal_fill_fake_txdesc(adapter,
8297 &ReservedPagePacket[BufIndex - TxDescLen],
8298 PSPollLength, _TRUE, _FALSE, _FALSE);
8300 CurtPktPageNum = (u8)PageNum((TxDescLen + PSPollLength), PageSize);
8302 TotalPageNum += CurtPktPageNum;
8304 BufIndex += (CurtPktPageNum * PageSize);
8306 #ifdef CONFIG_BT_COEXIST
8307 /* BT Qos null data * 1 page */
8308 RsvdPageLoc.LocBTQosNull = TotalPageNum;
8309 RTW_INFO("LocBTQosNull: %d\n", RsvdPageLoc.LocBTQosNull);
8310 rtw_hal_construct_NullFunctionData(
8312 &ReservedPagePacket[BufIndex],
8314 get_my_bssid(&pmlmeinfo->network),
8315 _TRUE, 0, 0, _FALSE);
8316 rtw_hal_fill_fake_txdesc(adapter,
8317 &ReservedPagePacket[BufIndex - TxDescLen],
8318 BTQosNullLength, _FALSE, _TRUE, _FALSE);
8320 CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength, PageSize);
8322 TotalPageNum += CurtPktPageNum;
8324 BufIndex += (CurtPktPageNum * PageSize);
8325 #endif /* CONFIG_BT_COEXIT */
8327 #ifdef CONFIG_MCC_MODE
8328 if (MCC_EN(adapter)) {
8329 dl_mcc_page = rtw_hal_dl_mcc_fw_rsvd_page(adapter, ReservedPagePacket,
8330 &BufIndex, TxDescLen, PageSize,
8331 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
8333 dl_mcc_page = _FAIL;
8335 if (dl_mcc_page == _FAIL) {
8336 #endif /* CONFIG_MCC_MODE */
8338 /* null data * 1 page */
8339 RsvdPageLoc.LocNullData = TotalPageNum;
8340 RTW_INFO("LocNullData: %d\n", RsvdPageLoc.LocNullData);
8341 rtw_hal_construct_NullFunctionData(
8343 &ReservedPagePacket[BufIndex],
8345 get_my_bssid(&pmlmeinfo->network),
8346 _FALSE, 0, 0, _FALSE);
8347 rtw_hal_fill_fake_txdesc(adapter,
8348 &ReservedPagePacket[BufIndex - TxDescLen],
8349 NullDataLength, _FALSE, _FALSE, _FALSE);
8351 CurtPktPageNum = (u8)PageNum(TxDescLen + NullDataLength, PageSize);
8353 TotalPageNum += CurtPktPageNum;
8355 BufIndex += (CurtPktPageNum * PageSize);
8356 #ifdef CONFIG_MCC_MODE
8358 #endif /* CONFIG_MCC_MODE */
8360 /* Qos null data * 1 page */
8361 RsvdPageLoc.LocQosNull = TotalPageNum;
8362 RTW_INFO("LocQosNull: %d\n", RsvdPageLoc.LocQosNull);
8363 rtw_hal_construct_NullFunctionData(
8365 &ReservedPagePacket[BufIndex],
8367 get_my_bssid(&pmlmeinfo->network),
8368 _TRUE, 0, 0, _FALSE);
8369 rtw_hal_fill_fake_txdesc(adapter,
8370 &ReservedPagePacket[BufIndex - TxDescLen],
8371 QosNullLength, _FALSE, _FALSE, _FALSE);
8373 CurtPktPageNum = (u8)PageNum(TxDescLen + QosNullLength, PageSize);
8375 TotalPageNum += CurtPktPageNum;
8377 TotalPacketLen = BufIndex + QosNullLength;
8379 BufIndex += (CurtPktPageNum * PageSize);
8381 #ifdef CONFIG_WOWLAN
8382 if (pwrctl->wowlan_mode == _TRUE &&
8383 pwrctl->wowlan_in_resume == _FALSE) {
8384 rtw_hal_set_wow_fw_rsvd_page(adapter, ReservedPagePacket,
8385 BufIndex, TxDescLen, PageSize,
8386 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
8388 #endif /* CONFIG_WOWLAN */
8390 #ifdef CONFIG_P2P_WOWLAN
8391 if (_TRUE == pwrctl->wowlan_p2p_mode) {
8392 rtw_hal_set_p2p_wow_fw_rsvd_page(adapter, ReservedPagePacket,
8393 BufIndex, TxDescLen, PageSize,
8394 &TotalPageNum, &TotalPacketLen, &RsvdPageLoc);
8396 #endif /* CONFIG_P2P_WOWLAN */
8398 #ifdef CONFIG_LPS_PG
8399 /* must reserved last 1 x page for LPS PG Info*/
8400 pwrctl->lpspg_rsvd_page_locate = TotalPageNum;
8401 pwrctl->blpspg_info_up = _TRUE;
8405 /* RTW_INFO("%s BufIndex(%d), TxDescLen(%d), PageSize(%d)\n",__func__, BufIndex, TxDescLen, PageSize);*/
8406 RTW_INFO("%s PageNum(%d), pktlen(%d)\n",
8407 __func__, TotalPageNum, TotalPacketLen);
8409 #ifdef CONFIG_LPS_PG
8410 if ((TotalPacketLen + (LPS_PG_INFO_RSVD_PAGE_NUM * PageSize)) > MaxRsvdPageBufSize) {
8411 pwrctl->lpspg_rsvd_page_locate = 0;
8412 pwrctl->blpspg_info_up = _FALSE;
8414 RTW_ERR("%s rsvd page size is not enough!!TotalPacketLen+LPS_PG_INFO_LEN %d, MaxRsvdPageBufSize %d\n",
8415 __func__, (TotalPacketLen + (LPS_PG_INFO_RSVD_PAGE_NUM * PageSize)), MaxRsvdPageBufSize);
8420 if (TotalPacketLen > MaxRsvdPageBufSize) {
8421 RTW_ERR("%s(ERROR): rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
8422 __FUNCTION__, TotalPacketLen, MaxRsvdPageBufSize);
8426 /* update attribute */
8427 pattrib = &pcmdframe->attrib;
8428 update_mgntframe_attrib(adapter, pattrib);
8429 pattrib->qsel = QSLT_BEACON;
8430 pattrib->pktlen = TotalPacketLen - TxDescOffset;
8431 pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
8432 #ifdef CONFIG_PCI_HCI
8433 dump_mgntframe(adapter, pcmdframe);
8435 dump_mgntframe_and_wait(adapter, pcmdframe, 100);
8439 RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n",
8440 __func__, TotalPacketLen, TotalPageNum);
8441 #ifdef DBG_DUMP_SET_RSVD_PAGE
8442 RTW_INFO(" ==================================================\n");
8443 RTW_INFO_DUMP("\n", ReservedPagePacket, TotalPacketLen);
8444 RTW_INFO(" ==================================================\n");
8446 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
8447 rtw_hal_set_FwRsvdPage_cmd(adapter, &RsvdPageLoc);
8448 #ifdef CONFIG_WOWLAN
8449 if (pwrctl->wowlan_mode == _TRUE &&
8450 pwrctl->wowlan_in_resume == _FALSE)
8451 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
8452 #endif /* CONFIG_WOWLAN */
8453 #ifdef CONFIG_AP_WOWLAN
8454 if (pwrctl->wowlan_ap_mode == _TRUE)
8455 rtw_hal_set_ap_rsvdpage_loc_cmd(adapter, &RsvdPageLoc);
8456 #endif /* CONFIG_AP_WOWLAN */
8457 } else if (pwrctl->wowlan_pno_enable) {
8458 #ifdef CONFIG_PNO_SUPPORT
8459 rtw_hal_set_FwAoacRsvdPage_cmd(adapter, &RsvdPageLoc);
8460 if (pwrctl->wowlan_in_resume)
8461 rtw_hal_set_scan_offload_info_cmd(adapter,
8464 rtw_hal_set_scan_offload_info_cmd(adapter,
8466 #endif /* CONFIG_PNO_SUPPORT */
8468 #ifdef CONFIG_P2P_WOWLAN
8469 if (_TRUE == pwrctl->wowlan_p2p_mode)
8470 rtw_hal_set_FwP2PRsvdPage_cmd(adapter, &RsvdPageLoc);
8471 #endif /* CONFIG_P2P_WOWLAN */
8474 rtw_free_xmitframe(pxmitpriv, pcmdframe);
8476 static void rtw_hal_set_hw_update_tsf(PADAPTER padapter)
8478 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8479 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8481 #if defined(CONFIG_RTL8822B) || defined(CONFIG_MI_WITH_MBSSID_CAM)
8482 RTW_INFO("[Warn] %s "ADPT_FMT" enter func\n", __func__, ADPT_ARG(padapter));
8487 if (!pmlmeext->en_hw_update_tsf)
8490 /* check REG_RCR bit is set */
8491 if (!(rtw_read32(padapter, REG_RCR) & RCR_CBSSID_BCN))
8494 /* enable hw update tsf function for non-AP */
8495 if (rtw_linked_check(padapter) &&
8496 check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) {
8497 #ifdef CONFIG_CONCURRENT_MODE
8498 if (padapter->hw_port == HW_PORT1)
8499 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~DIS_TSF_UDT));
8502 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~DIS_TSF_UDT));
8504 pmlmeext->en_hw_update_tsf = _FALSE;
8508 #ifdef CONFIG_TDLS_CH_SW
8509 s32 rtw_hal_ch_sw_oper_offload(_adapter *padapter, u8 channel, u8 channel_offset, u16 bwmode)
8511 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
8512 u8 ch_sw_h2c_buf[4] = {0x00, 0x00, 0x00, 0x00};
8515 SET_H2CCMD_CH_SW_OPER_OFFLOAD_CH_NUM(ch_sw_h2c_buf, channel);
8516 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_MODE(ch_sw_h2c_buf, bwmode);
8518 case CHANNEL_WIDTH_40:
8519 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_40M_SC(ch_sw_h2c_buf, channel_offset);
8521 case CHANNEL_WIDTH_80:
8522 SET_H2CCMD_CH_SW_OPER_OFFLOAD_BW_80M_SC(ch_sw_h2c_buf, channel_offset);
8524 case CHANNEL_WIDTH_20:
8528 SET_H2CCMD_CH_SW_OPER_OFFLOAD_RFE_TYPE(ch_sw_h2c_buf, pHalData->rfe_type);
8530 return rtw_hal_fill_h2c_cmd(padapter, H2C_CHNL_SWITCH_OPER_OFFLOAD, sizeof(ch_sw_h2c_buf), ch_sw_h2c_buf);
8536 void rtw_hal_update_uapsd_tid(_adapter *adapter)
8538 rtw_write8(adapter, REG_WMMPS_UAPSD_TID, 0xFF);
8542 #if defined(CONFIG_BT_COEXIST) && defined(CONFIG_FW_MULTI_PORT_SUPPORT)
8543 /* For multi-port support, driver needs to inform the port ID to FW for btc operations */
8544 s32 rtw_hal_set_wifi_port_id_cmd(_adapter *adapter)
8547 u8 h2c_buf[H2C_BTC_WL_PORT_ID_LEN] = {0};
8549 SET_H2CCMD_BTC_WL_PORT_ID(h2c_buf, adapter->hw_port);
8550 return rtw_hal_fill_h2c_cmd(adapter, H2C_BTC_WL_PORT_ID, H2C_BTC_WL_PORT_ID_LEN, h2c_buf);
8554 void SetHwReg(_adapter *adapter, u8 variable, u8 *val)
8556 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
8559 case HW_VAR_MEDIA_STATUS: {
8560 u8 net_type = *((u8 *)val);
8562 rtw_hal_set_msr(adapter, net_type);
8565 case HW_VAR_MAC_ADDR:
8566 #ifdef CONFIG_MI_WITH_MBSSID_CAM
8567 rtw_hal_set_macaddr_mbid(adapter, val);
8569 rtw_hal_set_macaddr_port(adapter, val);
8573 rtw_hal_set_bssid(adapter, val);
8575 #ifdef CONFIG_MBSSID_CAM
8576 case HW_VAR_MBSSID_CAM_WRITE: {
8578 u32 *cam_val = (u32 *)val;
8580 rtw_write32(adapter, REG_MBIDCAMCFG_1, cam_val[0]);
8581 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | BIT_MBIDCAM_VALID | cam_val[1];
8582 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
8585 case HW_VAR_MBSSID_CAM_CLEAR: {
8587 u8 entry_id = *(u8 *)val;
8589 rtw_write32(adapter, REG_MBIDCAMCFG_1, 0);
8591 cmd = BIT_MBIDCAM_POLL | BIT_MBIDCAM_WT_EN | ((entry_id & MBIDCAM_ADDR_MASK) << MBIDCAM_ADDR_SHIFT);
8592 rtw_write32(adapter, REG_MBIDCAMCFG_2, cmd);
8595 case HW_VAR_RCR_MBSSID_EN:
8597 rtw_write32(adapter, REG_RCR, rtw_read32(adapter, REG_RCR) | RCR_ENMBID);
8601 val32 = rtw_read32(adapter, REG_RCR);
8602 val32 &= ~(RCR_ENMBID);
8603 rtw_write32(adapter, REG_RCR, val32);
8607 case HW_VAR_PORT_SWITCH:
8608 hw_var_port_switch(adapter);
8610 case HW_VAR_INIT_RTS_RATE: {
8611 u16 brate_cfg = *((u16 *)val);
8613 HAL_VERSION *hal_ver = &hal_data->version_id;
8615 if (IS_8188E(*hal_ver)) {
8617 while (brate_cfg > 0x1) {
8618 brate_cfg = (brate_cfg >> 1);
8621 rtw_write8(adapter, REG_INIRTS_RATE_SEL, rate_index);
8626 case HW_VAR_SEC_CFG: {
8630 reg_scr = reg_scr_ori = rtw_read16(adapter, REG_SECCFG);
8631 reg_scr |= (SCR_CHK_KEYID | SCR_RxDecEnable | SCR_TxEncEnable);
8633 if (_rtw_camctl_chk_cap(adapter, SEC_CAP_CHK_BMC))
8634 reg_scr |= SCR_CHK_BMC;
8636 if (_rtw_camctl_chk_flags(adapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH))
8637 reg_scr |= SCR_NoSKMC;
8639 if (reg_scr != reg_scr_ori)
8640 rtw_write16(adapter, REG_SECCFG, reg_scr);
8643 case HW_VAR_SEC_DK_CFG: {
8644 struct security_priv *sec = &adapter->securitypriv;
8645 u8 reg_scr = rtw_read8(adapter, REG_SECCFG);
8647 if (val) { /* Enable default key related setting */
8648 reg_scr |= SCR_TXBCUSEDK;
8649 if (sec->dot11AuthAlgrthm != dot11AuthAlgrthm_8021X)
8650 reg_scr |= (SCR_RxUseDK | SCR_TxUseDK);
8651 } else /* Disable default key related setting */
8652 reg_scr &= ~(SCR_RXBCUSEDK | SCR_TXBCUSEDK | SCR_RxUseDK | SCR_TxUseDK);
8654 rtw_write8(adapter, REG_SECCFG, reg_scr);
8658 case HW_VAR_ASIX_IOT:
8659 /* enable ASIX IOT function */
8660 if (*((u8 *)val) == _TRUE) {
8661 /* 0xa2e[0]=0 (disable rake receiver) */
8662 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
8663 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) & ~(BIT0));
8664 /* 0xa1c=0xa0 (reset channel estimation if signal quality is bad) */
8665 rtw_write8(adapter, rCCK0_DSPParameter2, 0xa0);
8667 /* restore reg:0xa2e, reg:0xa1c */
8668 rtw_write8(adapter, rCCK0_FalseAlarmReport + 2,
8669 rtw_read8(adapter, rCCK0_FalseAlarmReport + 2) | (BIT0));
8670 rtw_write8(adapter, rCCK0_DSPParameter2, 0x00);
8673 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
8674 case HW_VAR_WOWLAN: {
8675 struct wowlan_ioctl_param *poidparam;
8677 poidparam = (struct wowlan_ioctl_param *)val;
8678 switch (poidparam->subcode) {
8679 #ifdef CONFIG_WOWLAN
8680 case WOWLAN_PATTERN_CLEAN:
8681 rtw_hal_dl_pattern(adapter, 2);
8684 rtw_hal_wow_enable(adapter);
8686 case WOWLAN_DISABLE:
8687 rtw_hal_wow_disable(adapter);
8689 #endif /*CONFIG_WOWLAN*/
8690 #ifdef CONFIG_AP_WOWLAN
8691 case WOWLAN_AP_ENABLE:
8692 rtw_hal_ap_wow_enable(adapter);
8694 case WOWLAN_AP_DISABLE:
8695 rtw_hal_ap_wow_disable(adapter);
8697 #endif /*CONFIG_AP_WOWLAN*/
8703 #endif /*defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)*/
8705 case HW_VAR_EN_HW_UPDATE_TSF:
8706 rtw_hal_set_hw_update_tsf(adapter);
8709 case HW_VAR_APFM_ON_MAC:
8710 hal_data->bMacPwrCtrlOn = *val;
8711 RTW_INFO("%s: bMacPwrCtrlOn=%d\n", __func__, hal_data->bMacPwrCtrlOn);
8714 case HW_VAR_UAPSD_TID:
8715 rtw_hal_update_uapsd_tid(adapter);
8718 #ifdef CONFIG_LPS_PG
8719 case HW_VAR_LPS_PG_HANDLE:
8720 rtw_hal_lps_pg_handler(adapter, *val);
8726 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
8727 FUNC_ADPT_ARG(adapter), variable);
8733 void GetHwReg(_adapter *adapter, u8 variable, u8 *val)
8735 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
8739 case HW_VAR_BASIC_RATE:
8740 *((u16 *)val) = hal_data->BasicRateSet;
8742 case HW_VAR_RF_TYPE:
8743 *((u8 *)val) = hal_data->rf_type;
8745 case HW_VAR_MEDIA_STATUS:
8746 rtw_hal_get_msr(adapter, val);
8749 *val = hal_data->bNeedIQK;
8751 case HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO:
8752 if (hal_is_band_support(adapter, BAND_ON_5G))
8757 case HW_VAR_APFM_ON_MAC:
8758 *val = hal_data->bMacPwrCtrlOn;
8762 RTW_PRINT(FUNC_ADPT_FMT" variable(%d) not defined!\n",
8763 FUNC_ADPT_ARG(adapter), variable);
8770 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
8772 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
8773 u8 bResult = _SUCCESS;
8777 case HAL_DEF_DBG_DUMP_RXPKT:
8778 hal_data->bDumpRxPkt = *((u8 *)value);
8780 case HAL_DEF_DBG_DUMP_TXPKT:
8781 hal_data->bDumpTxPkt = *((u8 *)value);
8783 case HAL_DEF_ANT_DETECT:
8784 hal_data->AntDetection = *((u8 *)value);
8786 case HAL_DEF_DBG_DIS_PWT:
8787 hal_data->bDisableTXPowerTraining = *((u8 *)value);
8790 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
8798 #ifdef CONFIG_BEAMFORMING
8799 u8 rtw_hal_query_txbfer_rf_num(_adapter *adapter)
8801 struct registry_priv *pregistrypriv = &adapter->registrypriv;
8802 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
8804 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)))
8805 return pregistrypriv->beamformer_rf_num;
8806 else if (IS_HARDWARE_TYPE_8814AE(adapter)
8808 #if defined(CONFIG_USB_HCI)
8809 || (IS_HARDWARE_TYPE_8814AU(adapter) && (pUsbModeMech->CurUsbMode == 2 || pUsbModeMech->HubUsbMode == 2)) /* for USB3.0 */
8813 /*BF cap provided by Yu Chen, Sean, 2015, 01 */
8814 if (hal_data->rf_type == RF_3T3R)
8816 else if (hal_data->rf_type == RF_4T4R)
8824 u8 rtw_hal_query_txbfee_rf_num(_adapter *adapter)
8826 struct registry_priv *pregistrypriv = &adapter->registrypriv;
8827 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
8828 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8830 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
8832 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)))
8833 return pregistrypriv->beamformee_rf_num;
8834 else if (IS_HARDWARE_TYPE_8814AE(adapter) || IS_HARDWARE_TYPE_8814AU(adapter)) {
8835 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM)
8838 return 2;/*TODO: May be 3 in the future, by ChenYu. */
8846 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value)
8848 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
8849 u8 bResult = _SUCCESS;
8852 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: {
8853 struct mlme_priv *pmlmepriv;
8854 struct sta_priv *pstapriv;
8855 struct sta_info *psta;
8857 pmlmepriv = &adapter->mlmepriv;
8858 pstapriv = &adapter->stapriv;
8859 psta = rtw_get_stainfo(pstapriv, pmlmepriv->cur_network.network.MacAddress);
8861 *((int *)value) = psta->rssi_stat.undecorated_smoothed_pwdb;
8864 case HAL_DEF_DBG_DUMP_RXPKT:
8865 *((u8 *)value) = hal_data->bDumpRxPkt;
8867 case HAL_DEF_DBG_DUMP_TXPKT:
8868 *((u8 *)value) = hal_data->bDumpTxPkt;
8870 case HAL_DEF_ANT_DETECT:
8871 *((u8 *)value) = hal_data->AntDetection;
8873 case HAL_DEF_MACID_SLEEP:
8874 *(u8 *)value = _FALSE;
8876 case HAL_DEF_TX_PAGE_SIZE:
8877 *((u32 *)value) = PAGE_SIZE_128;
8879 case HAL_DEF_DBG_DIS_PWT:
8880 *(u8 *)value = hal_data->bDisableTXPowerTraining;
8882 case HAL_DEF_EXPLICIT_BEAMFORMER:
8883 case HAL_DEF_EXPLICIT_BEAMFORMEE:
8884 case HAL_DEF_VHT_MU_BEAMFORMER:
8885 case HAL_DEF_VHT_MU_BEAMFORMEE:
8886 *(u8 *)value = _FALSE;
8888 #ifdef CONFIG_BEAMFORMING
8889 case HAL_DEF_BEAMFORMER_CAP:
8890 *(u8 *)value = rtw_hal_query_txbfer_rf_num(adapter);
8892 case HAL_DEF_BEAMFORMEE_CAP:
8893 *(u8 *)value = rtw_hal_query_txbfee_rf_num(adapter);
8897 RTW_PRINT("%s: [WARNING] HAL_DEF_VARIABLE(%d) not defined!\n", __FUNCTION__, variable);
8907 HAL_ODM_VARIABLE eVariable,
8911 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
8912 struct PHY_DM_STRUCT *podmpriv = &pHalData->odmpriv;
8914 switch (eVariable) {
8915 case HAL_ODM_STA_INFO: {
8916 struct sta_info *psta = (struct sta_info *)pValue1;
8918 RTW_INFO("### Set STA_(%d) info ###\n", psta->mac_id);
8919 odm_cmn_info_ptr_array_hook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta);
8921 RTW_INFO("### Clean STA_(%d) info ###\n", psta->mac_id);
8922 /* _enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL); */
8923 psta->rssi_level = 0;
8924 odm_cmn_info_ptr_array_hook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL);
8926 /* _exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL); */
8930 case HAL_ODM_P2P_STATE:
8931 odm_cmn_info_update(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet);
8933 case HAL_ODM_WIFI_DISPLAY_STATE:
8934 odm_cmn_info_update(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet);
8936 case HAL_ODM_REGULATION:
8937 odm_cmn_info_init(podmpriv, ODM_CMNINFO_DOMAIN_CODE_2G, pHalData->Regulation2_4G);
8938 odm_cmn_info_init(podmpriv, ODM_CMNINFO_DOMAIN_CODE_5G, pHalData->Regulation5G);
8940 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
8941 case HAL_ODM_NOISE_MONITOR: {
8942 struct noise_info *pinfo = (struct noise_info *)pValue1;
8944 #ifdef DBG_NOISE_MONITOR
8945 RTW_INFO("### Noise monitor chan(%d)-bPauseDIG:%d,IGIValue:0x%02x,max_time:%d (ms) ###\n",
8946 pinfo->chan, pinfo->bPauseDIG, pinfo->IGIValue, pinfo->max_time);
8949 pHalData->noise[pinfo->chan] = odm_inband_noise_monitor(podmpriv, pinfo->is_pause_dig, pinfo->igi_value, pinfo->max_time);
8950 RTW_INFO("chan_%d, noise = %d (dBm)\n", pinfo->chan, pHalData->noise[pinfo->chan]);
8951 #ifdef DBG_NOISE_MONITOR
8952 RTW_INFO("noise_a = %d, noise_b = %d noise_all:%d\n",
8953 podmpriv->noise_level.noise[ODM_RF_PATH_A],
8954 podmpriv->noise_level.noise[ODM_RF_PATH_B],
8955 podmpriv->noise_level.noise_all);
8959 #endif/*#ifdef CONFIG_BACKGROUND_NOISE_MONITOR*/
8961 case HAL_ODM_INITIAL_GAIN: {
8962 u8 rx_gain = *((u8 *)(pValue1));
8963 /*printk("rx_gain:%x\n",rx_gain);*/
8964 if (rx_gain == 0xff) {/*restore rx gain*/
8965 /*odm_write_dig(podmpriv,pDigTable->backup_ig_value);*/
8966 odm_pause_dig(podmpriv, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, rx_gain);
8968 /*pDigTable->backup_ig_value = pDigTable->cur_ig_value;*/
8969 /*odm_write_dig(podmpriv,rx_gain);*/
8970 odm_pause_dig(podmpriv, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, rx_gain);
8974 case HAL_ODM_FA_CNT_DUMP:
8975 if (*((u8 *)pValue1))
8976 podmpriv->debug_components |= (ODM_COMP_DIG | ODM_COMP_FA_CNT);
8978 podmpriv->debug_components &= ~(ODM_COMP_DIG | ODM_COMP_FA_CNT);
8980 case HAL_ODM_DBG_FLAG:
8981 odm_cmn_info_update(podmpriv, ODM_CMNINFO_DBG_COMP, *((u8Byte *)pValue1));
8983 case HAL_ODM_DBG_LEVEL:
8984 odm_cmn_info_update(podmpriv, ODM_CMNINFO_DBG_LEVEL, *((u4Byte *)pValue1));
8986 case HAL_ODM_RX_INFO_DUMP: {
8987 struct _FALSE_ALARM_STATISTICS *false_alm_cnt = (struct _FALSE_ALARM_STATISTICS *)phydm_get_structure(podmpriv , PHYDM_FALSEALMCNT);
8988 struct _dynamic_initial_gain_threshold_ *pDM_DigTable = &podmpriv->dm_dig_table;
8993 _RTW_PRINT_SEL(sel , "============ Rx Info dump ===================\n");
8994 _RTW_PRINT_SEL(sel , "is_linked = %d, rssi_min = %d(%%), current_igi = 0x%x\n", podmpriv->is_linked, podmpriv->rssi_min, pDM_DigTable->cur_ig_value);
8995 _RTW_PRINT_SEL(sel , "cnt_cck_fail = %d, cnt_ofdm_fail = %d, Total False Alarm = %d\n", false_alm_cnt->cnt_cck_fail, false_alm_cnt->cnt_ofdm_fail, false_alm_cnt->cnt_all);
8997 if (podmpriv->is_linked) {
8998 _RTW_PRINT_SEL(sel , "rx_rate = %s", HDATA_RATE(podmpriv->rx_rate));
8999 _RTW_PRINT_SEL(sel , " RSSI_A = %d(%%), RSSI_B = %d(%%)\n", podmpriv->RSSI_A, podmpriv->RSSI_B);
9000 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
9001 rtw_dump_raw_rssi_info(Adapter, sel);
9006 case HAL_ODM_RX_Dframe_INFO: {
9011 /*_RTW_PRINT_SEL(sel , "HAL_ODM_RX_Dframe_INFO\n");*/
9012 #ifdef DBG_RX_DFRAME_RAW_DATA
9013 rtw_dump_rx_dframe_info(Adapter, sel);
9018 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
9019 case HAL_ODM_AUTO_CHNL_SEL: {
9020 ACS_OP acs_op = *(ACS_OP *)pValue1;
9022 rtw_phydm_func_set(Adapter, ODM_BB_NHM_CNT);
9024 if (ACS_INIT == acs_op) {
9025 #ifdef DBG_AUTO_CHNL_SEL_NHM
9026 RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_INIT\n", ADPT_ARG(Adapter));
9028 odm_AutoChannelSelectInit(podmpriv);
9029 } else if (ACS_RESET == acs_op) {
9030 /* Reset statistics for auto channel selection mechanism.*/
9031 #ifdef DBG_AUTO_CHNL_SEL_NHM
9032 RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_RESET\n", ADPT_ARG(Adapter));
9034 odm_auto_channel_select_reset(podmpriv);
9036 } else if (ACS_SELECT == acs_op) {
9037 /* Collect NHM measurement result after current channel */
9038 #ifdef DBG_AUTO_CHNL_SEL_NHM
9039 RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: ACS_SELECT, CH(%d)\n", ADPT_ARG(Adapter), rtw_get_acs_channel(Adapter));
9041 odm_AutoChannelSelect(podmpriv, rtw_get_acs_channel(Adapter));
9043 RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: Unexpected OP\n", ADPT_ARG(Adapter));
9048 #ifdef CONFIG_ANTENNA_DIVERSITY
9049 case HAL_ODM_ANTDIV_SELECT: {
9050 u8 antenna = (*(u8 *)pValue1);
9053 odm_update_rx_idle_ant(&pHalData->odmpriv, antenna);
9054 /*RTW_INFO("==> HAL_ODM_ANTDIV_SELECT, Ant_(%s)\n", (antenna == MAIN_ANT) ? "MAIN_ANT" : "AUX_ANT");*/
9067 HAL_ODM_VARIABLE eVariable,
9071 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
9072 struct PHY_DM_STRUCT *podmpriv = &pHalData->odmpriv;
9074 switch (eVariable) {
9075 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
9076 case HAL_ODM_NOISE_MONITOR: {
9077 u8 chan = *(u8 *)pValue1;
9078 *(s16 *)pValue2 = pHalData->noise[chan];
9079 #ifdef DBG_NOISE_MONITOR
9080 RTW_INFO("### Noise monitor chan(%d)-noise:%d (dBm) ###\n",
9081 chan, pHalData->noise[chan]);
9085 #endif/*#ifdef CONFIG_BACKGROUND_NOISE_MONITOR*/
9086 case HAL_ODM_DBG_FLAG:
9087 *((u8Byte *)pValue1) = podmpriv->debug_components;
9089 case HAL_ODM_DBG_LEVEL:
9090 *((u4Byte *)pValue1) = podmpriv->debug_level;
9093 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
9094 case HAL_ODM_AUTO_CHNL_SEL: {
9095 #ifdef DBG_AUTO_CHNL_SEL_NHM
9096 RTW_INFO("[ACS-"ADPT_FMT"] HAL_ODM_AUTO_CHNL_SEL: GET_BEST_CHAN\n", ADPT_ARG(Adapter));
9098 /* Retrieve better channel from NHM mechanism */
9099 if (IsSupported24G(Adapter->registrypriv.wireless_mode))
9100 *((u8 *)(pValue1)) = odm_get_auto_channel_select_result(podmpriv, BAND_ON_2_4G);
9101 if (is_supported_5g(Adapter->registrypriv.wireless_mode))
9102 *((u8 *)(pValue2)) = odm_get_auto_channel_select_result(podmpriv, BAND_ON_5G);
9106 #ifdef CONFIG_ANTENNA_DIVERSITY
9107 case HAL_ODM_ANTDIV_SELECT: {
9108 struct _FAST_ANTENNA_TRAINNING_ *pDM_FatTable = &podmpriv->dm_fat_table;
9109 *((u8 *)pValue1) = pDM_FatTable->rx_idle_ant;
9113 case HAL_ODM_INITIAL_GAIN: {
9114 struct _dynamic_initial_gain_threshold_ *pDM_DigTable = &podmpriv->dm_dig_table;
9115 *((u8 *)pValue1) = pDM_DigTable->cur_ig_value;
9124 u32 rtw_phydm_ability_ops(_adapter *adapter, HAL_PHYDM_OPS ops, u32 ability)
9126 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
9127 struct PHY_DM_STRUCT *podmpriv = &pHalData->odmpriv;
9131 case HAL_PHYDM_DIS_ALL_FUNC:
9132 podmpriv->support_ability = DYNAMIC_FUNC_DISABLE;
9134 case HAL_PHYDM_FUNC_SET:
9135 podmpriv->support_ability |= ability;
9137 case HAL_PHYDM_FUNC_CLR:
9138 podmpriv->support_ability &= ~(ability);
9140 case HAL_PHYDM_ABILITY_BK:
9142 podmpriv->bk_support_ability = podmpriv->support_ability;
9144 case HAL_PHYDM_ABILITY_RESTORE:
9145 /* restore dm flag */
9146 podmpriv->support_ability = podmpriv->bk_support_ability;
9148 case HAL_PHYDM_ABILITY_SET:
9149 podmpriv->support_ability = ability;
9151 case HAL_PHYDM_ABILITY_GET:
9152 result = podmpriv->support_ability;
9170 if (str1[num] != str2[num])
9178 * Translate a character to hex digit.
9185 if (chTmp >= '0' && chTmp <= '9')
9187 else if (chTmp >= 'a' && chTmp <= 'f')
9188 return 10 + (chTmp - 'a');
9189 else if (chTmp >= 'A' && chTmp <= 'F')
9190 return 10 + (chTmp - 'A');
9199 * Parse hex number from the string pucStr.
9202 GetHexValueFromString(
9204 IN OUT u32 *pu4bVal,
9205 IN OUT u32 *pu4bMove
9208 char *szScan = szStr;
9210 /* Check input parameter. */
9211 if (szStr == NULL || pu4bVal == NULL || pu4bMove == NULL) {
9212 RTW_INFO("GetHexValueFromString(): Invalid inpur argumetns! szStr: %p, pu4bVal: %p, pu4bMove: %p\n", szStr, pu4bVal, pu4bMove);
9216 /* Initialize output. */
9220 /* Skip leading space. */
9221 while (*szScan != '\0' &&
9222 (*szScan == ' ' || *szScan == '\t')) {
9227 /* Skip leading '0x' or '0X'. */
9228 if (*szScan == '0' && (*(szScan + 1) == 'x' || *(szScan + 1) == 'X')) {
9233 /* Check if szScan is now pointer to a character for hex digit, */
9234 /* if not, it means this is not a valid hex number. */
9235 if (!IsHexDigit(*szScan))
9238 /* Parse each digit. */
9241 *pu4bVal += MapCharToHexDigit(*szScan);
9245 } while (IsHexDigit(*szScan));
9251 GetFractionValueFromString(
9253 IN OUT u8 *pInteger,
9254 IN OUT u8 *pFraction,
9255 IN OUT u32 *pu4bMove
9258 char *szScan = szStr;
9260 /* Initialize output. */
9265 /* Skip leading space. */
9266 while (*szScan != '\0' && (*szScan == ' ' || *szScan == '\t')) {
9271 /* Parse each digit. */
9274 *pInteger += (*szScan - '0');
9279 if (*szScan == '.') {
9283 if (*szScan < '0' || *szScan > '9')
9286 *pFraction = *szScan - '0';
9292 } while (*szScan >= '0' && *szScan <= '9');
9299 * Return TRUE if szStr is comment out with leading " */ /* ".
9306 if (*szStr == '/' && *(szStr + 1) == '/')
9313 GetU1ByteIntegerFromStringInDecimal(
9321 while (Str[i] != '\0') {
9322 if (Str[i] >= '0' && Str[i] <= '9') {
9324 *pInt += (Str[i] - '0');
9333 /* <20121004, Kordan> For example,
9334 * ParseQualifiedString(inString, 0, outString, '[', ']') gets "Kordan" from a string "Hello [Kordan]".
9335 * If RightQualifier does not exist, it will hang on in the while loop */
9337 ParseQualifiedString(
9341 IN char LeftQualifier,
9342 IN char RightQualifier
9346 char c = In[(*Start)++];
9348 if (c != LeftQualifier)
9352 while ((c = In[(*Start)++]) != RightQualifier)
9355 strncpy((char *)Out, (const char *)(In + i), j - i + 1);
9366 u8 cnt = 0, NumOfSpaceAndTab = 0;
9368 while (size > cnt) {
9369 if (data[cnt] == ' ' || data[cnt] == '\t' || data[cnt] == '\0')
9375 return size == NumOfSpaceAndTab;
9379 void rtw_hal_check_rxfifo_full(_adapter *adapter)
9381 struct dvobj_priv *psdpriv = adapter->dvobj;
9382 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
9383 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
9384 struct registry_priv *regsty = &adapter->registrypriv;
9385 int save_cnt = _FALSE;
9387 if (regsty->check_hw_status == 1) {
9388 /* switch counter to RX fifo */
9389 if (IS_8188E(pHalData->version_id) ||
9390 IS_8188F(pHalData->version_id) ||
9391 IS_8812_SERIES(pHalData->version_id) ||
9392 IS_8821_SERIES(pHalData->version_id) ||
9393 IS_8723B_SERIES(pHalData->version_id) ||
9394 IS_8192E(pHalData->version_id) ||
9395 IS_8703B_SERIES(pHalData->version_id) ||
9396 IS_8723D_SERIES(pHalData->version_id)) {
9397 rtw_write8(adapter, REG_RXERR_RPT + 3, rtw_read8(adapter, REG_RXERR_RPT + 3) | 0xa0);
9400 /* todo: other chips */
9405 pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow;
9406 pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT);
9407 pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow - pdbgpriv->dbg_rx_fifo_last_overflow;
9409 /* special value to indicate no implementation */
9410 pdbgpriv->dbg_rx_fifo_last_overflow = 1;
9411 pdbgpriv->dbg_rx_fifo_curr_overflow = 1;
9412 pdbgpriv->dbg_rx_fifo_diff_overflow = 1;
9417 void linked_info_dump(_adapter *padapter, u8 benable)
9419 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
9421 if (padapter->bLinkInfoDump == benable)
9424 RTW_INFO("%s %s\n", __FUNCTION__, (benable) ? "enable" : "disable");
9428 pwrctrlpriv->org_power_mgnt = pwrctrlpriv->power_mgnt;/* keep org value */
9429 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
9433 pwrctrlpriv->ips_org_mode = pwrctrlpriv->ips_mode;/* keep org value */
9434 rtw_pm_set_ips(padapter, IPS_NONE);
9438 rtw_pm_set_ips(padapter, pwrctrlpriv->ips_org_mode);
9439 #endif /* CONFIG_IPS */
9442 rtw_pm_set_lps(padapter, pwrctrlpriv->org_power_mgnt);
9443 #endif /* CONFIG_LPS */
9445 padapter->bLinkInfoDump = benable ;
9448 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
9449 void rtw_get_raw_rssi_info(void *sel, _adapter *padapter)
9451 u8 isCCKrate, rf_path;
9452 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
9453 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
9454 RTW_PRINT_SEL(sel, "RxRate = %s, PWDBALL = %d(%%), rx_pwr_all = %d(dBm)\n",
9455 HDATA_RATE(psample_pkt_rssi->data_rate), psample_pkt_rssi->pwdball, psample_pkt_rssi->pwr_all);
9456 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
9459 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
9461 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
9462 RTW_PRINT_SEL(sel, "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)\n"
9463 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
9466 RTW_PRINT_SEL(sel, "\trx_ofdm_pwr:%d(dBm),rx_ofdm_snr:%d(dB)\n",
9467 psample_pkt_rssi->ofdm_pwr[rf_path], psample_pkt_rssi->ofdm_snr[rf_path]);
9472 void rtw_dump_raw_rssi_info(_adapter *padapter, void *sel)
9474 u8 isCCKrate, rf_path;
9475 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
9476 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
9477 _RTW_PRINT_SEL(sel, "============ RAW Rx Info dump ===================\n");
9478 _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);
9480 isCCKrate = (psample_pkt_rssi->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
9483 psample_pkt_rssi->mimo_signal_strength[0] = psample_pkt_rssi->pwdball;
9485 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
9486 _RTW_PRINT_SEL(sel , "RF_PATH_%d=>signal_strength:%d(%%),signal_quality:%d(%%)"
9487 , rf_path, psample_pkt_rssi->mimo_signal_strength[rf_path], psample_pkt_rssi->mimo_signal_quality[rf_path]);
9490 _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]);
9492 _RTW_PRINT_SEL(sel , "\n");
9498 #ifdef DBG_RX_DFRAME_RAW_DATA
9499 void rtw_dump_rx_dframe_info(_adapter *padapter, void *sel)
9502 u8 isCCKrate, rf_path;
9503 struct recv_priv *precvpriv = &(padapter->recvpriv);
9504 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
9505 struct sta_priv *pstapriv = &padapter->stapriv;
9506 struct sta_info *psta;
9507 struct sta_recv_dframe_info *psta_dframe_info;
9509 _list *plist, *phead;
9511 u8 bc_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9512 u8 null_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
9514 if (precvpriv->store_law_data_flag) {
9516 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
9518 for (i = 0; i < NUM_STA; i++) {
9519 phead = &(pstapriv->sta_hash[i]);
9520 plist = get_next(phead);
9522 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
9524 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
9525 plist = get_next(plist);
9528 psta_dframe_info = &psta->sta_dframe_info;
9529 if ((_rtw_memcmp(psta->hwaddr, bc_addr, 6) != _TRUE)
9530 && (_rtw_memcmp(psta->hwaddr, null_addr, 6) != _TRUE)
9531 && (_rtw_memcmp(psta->hwaddr, adapter_mac_addr(padapter), 6) != _TRUE)) {
9534 isCCKrate = (psta_dframe_info->sta_data_rate <= DESC_RATE11M) ? TRUE : FALSE;
9536 switch (psta_dframe_info->sta_bw_mode) {
9538 case CHANNEL_WIDTH_20:
9542 case CHANNEL_WIDTH_40:
9546 case CHANNEL_WIDTH_80:
9550 case CHANNEL_WIDTH_160:
9559 RTW_PRINT_SEL(sel, "==============================\n");
9560 _RTW_PRINT_SEL(sel, "macaddr =" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
9561 _RTW_PRINT_SEL(sel, "BW=%s, sgi =%d\n", BW, psta_dframe_info->sta_sgi);
9562 _RTW_PRINT_SEL(sel, "Rx_Data_Rate = %s\n", HDATA_RATE(psta_dframe_info->sta_data_rate));
9564 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
9568 _RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)", rf_path, psta_dframe_info->sta_RxPwr[rf_path]);
9569 _RTW_PRINT_SEL(sel , ",rx_ofdm_snr:%d(dB)\n", psta_dframe_info->sta_ofdm_snr[rf_path]);
9573 _RTW_PRINT_SEL(sel , "RF_PATH_%d RSSI:%d(dBm)\n", rf_path, (psta_dframe_info->sta_mimo_signal_strength[rf_path]) - 100);
9579 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
9583 void rtw_store_phy_info(_adapter *padapter, union recv_frame *prframe)
9585 u8 isCCKrate, rf_path , dframe_type;
9587 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
9588 #ifdef DBG_RX_DFRAME_RAW_DATA
9589 struct sta_recv_dframe_info *psta_dframe_info;
9591 struct recv_priv *precvpriv = &(padapter->recvpriv);
9592 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
9593 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
9594 struct sta_info *psta = prframe->u.hdr.psta;
9595 struct _odm_phy_status_info_ *p_phy_info = (struct _odm_phy_status_info_ *)(&pattrib->phy_info);
9596 struct rx_raw_rssi *psample_pkt_rssi = &padapter->recvpriv.raw_rssi_info;
9597 psample_pkt_rssi->data_rate = pattrib->data_rate;
9598 ptr = prframe->u.hdr.rx_data;
9599 dframe_type = GetFrameType(ptr);
9600 /*RTW_INFO("=>%s\n", __FUNCTION__);*/
9603 if (precvpriv->store_law_data_flag) {
9604 isCCKrate = (pattrib->data_rate <= DESC_RATE11M) ? TRUE : FALSE;
9606 psample_pkt_rssi->pwdball = p_phy_info->rx_pwdb_all;
9607 psample_pkt_rssi->pwr_all = p_phy_info->recv_signal_power;
9609 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
9610 psample_pkt_rssi->mimo_signal_strength[rf_path] = p_phy_info->rx_mimo_signal_strength[rf_path];
9611 psample_pkt_rssi->mimo_signal_quality[rf_path] = p_phy_info->rx_mimo_signal_quality[rf_path];
9613 psample_pkt_rssi->ofdm_pwr[rf_path] = p_phy_info->rx_pwr[rf_path];
9614 psample_pkt_rssi->ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
9617 #ifdef DBG_RX_DFRAME_RAW_DATA
9618 if ((dframe_type == WIFI_DATA_TYPE) || (dframe_type == WIFI_QOS_DATA_TYPE) || (padapter->registrypriv.mp_mode == 1)) {
9620 /*RTW_INFO("=>%s WIFI_DATA_TYPE or WIFI_QOS_DATA_TYPE\n", __FUNCTION__);*/
9622 psta_dframe_info = &psta->sta_dframe_info;
9623 /*RTW_INFO("=>%s psta->hwaddr="MAC_FMT" !\n", __FUNCTION__, MAC_ARG(psta->hwaddr));*/
9624 if ((_rtw_memcmp(psta->hwaddr, bc_addr, ETH_ALEN) != _TRUE) || (padapter->registrypriv.mp_mode == 1)) {
9625 psta_dframe_info->sta_data_rate = pattrib->data_rate;
9626 psta_dframe_info->sta_sgi = pattrib->sgi;
9627 psta_dframe_info->sta_bw_mode = pattrib->bw;
9628 for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++) {
9630 psta_dframe_info->sta_mimo_signal_strength[rf_path] = (p_phy_info->rx_mimo_signal_strength[rf_path]);/*Percentage to dbm*/
9633 psta_dframe_info->sta_ofdm_snr[rf_path] = p_phy_info->rx_snr[rf_path];
9634 psta_dframe_info->sta_RxPwr[rf_path] = p_phy_info->rx_pwr[rf_path];
9646 int check_phy_efuse_tx_power_info_valid(PADAPTER padapter)
9648 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
9649 u8 *pContent = pHalData->efuse_eeprom_data;
9651 u16 tx_index_offset = 0x0000;
9653 switch (rtw_get_chip_type(padapter)) {
9655 tx_index_offset = EEPROM_TX_PWR_INX_8723B;
9658 tx_index_offset = EEPROM_TX_PWR_INX_8703B;
9661 tx_index_offset = EEPROM_TX_PWR_INX_8723D;
9664 tx_index_offset = EEPROM_TX_PWR_INX_88E;
9667 tx_index_offset = EEPROM_TX_PWR_INX_8188F;
9670 tx_index_offset = EEPROM_TX_PWR_INX_8192E;
9673 tx_index_offset = EEPROM_TX_PWR_INX_8821;
9676 tx_index_offset = EEPROM_TX_PWR_INX_8812;
9679 tx_index_offset = EEPROM_TX_PWR_INX_8814;
9682 tx_index_offset = EEPROM_TX_PWR_INX_8822B;
9685 tx_index_offset = EEPROM_TX_PWR_INX_8821C;
9688 tx_index_offset = 0x0010;
9692 /* TODO: chacking length by ICs */
9693 for (index = 0 ; index < 11 ; index++) {
9694 if (pContent[tx_index_offset + index] == 0xFF)
9700 int hal_efuse_macaddr_offset(_adapter *adapter)
9702 u8 interface_type = 0;
9703 int addr_offset = -1;
9705 interface_type = rtw_get_intf_type(adapter);
9707 switch (rtw_get_chip_type(adapter)) {
9708 #ifdef CONFIG_RTL8723B
9710 if (interface_type == RTW_USB)
9711 addr_offset = EEPROM_MAC_ADDR_8723BU;
9712 else if (interface_type == RTW_SDIO)
9713 addr_offset = EEPROM_MAC_ADDR_8723BS;
9714 else if (interface_type == RTW_PCIE)
9715 addr_offset = EEPROM_MAC_ADDR_8723BE;
9718 #ifdef CONFIG_RTL8703B
9720 if (interface_type == RTW_USB)
9721 addr_offset = EEPROM_MAC_ADDR_8703BU;
9722 else if (interface_type == RTW_SDIO)
9723 addr_offset = EEPROM_MAC_ADDR_8703BS;
9726 #ifdef CONFIG_RTL8723D
9728 if (interface_type == RTW_USB)
9729 addr_offset = EEPROM_MAC_ADDR_8723DU;
9730 else if (interface_type == RTW_SDIO)
9731 addr_offset = EEPROM_MAC_ADDR_8723DS;
9732 else if (interface_type == RTW_PCIE)
9733 addr_offset = EEPROM_MAC_ADDR_8723DE;
9737 #ifdef CONFIG_RTL8188E
9739 if (interface_type == RTW_USB)
9740 addr_offset = EEPROM_MAC_ADDR_88EU;
9741 else if (interface_type == RTW_SDIO)
9742 addr_offset = EEPROM_MAC_ADDR_88ES;
9743 else if (interface_type == RTW_PCIE)
9744 addr_offset = EEPROM_MAC_ADDR_88EE;
9747 #ifdef CONFIG_RTL8188F
9749 if (interface_type == RTW_USB)
9750 addr_offset = EEPROM_MAC_ADDR_8188FU;
9751 else if (interface_type == RTW_SDIO)
9752 addr_offset = EEPROM_MAC_ADDR_8188FS;
9755 #ifdef CONFIG_RTL8812A
9757 if (interface_type == RTW_USB)
9758 addr_offset = EEPROM_MAC_ADDR_8812AU;
9759 else if (interface_type == RTW_PCIE)
9760 addr_offset = EEPROM_MAC_ADDR_8812AE;
9763 #ifdef CONFIG_RTL8821A
9765 if (interface_type == RTW_USB)
9766 addr_offset = EEPROM_MAC_ADDR_8821AU;
9767 else if (interface_type == RTW_SDIO)
9768 addr_offset = EEPROM_MAC_ADDR_8821AS;
9769 else if (interface_type == RTW_PCIE)
9770 addr_offset = EEPROM_MAC_ADDR_8821AE;
9773 #ifdef CONFIG_RTL8192E
9775 if (interface_type == RTW_USB)
9776 addr_offset = EEPROM_MAC_ADDR_8192EU;
9777 else if (interface_type == RTW_SDIO)
9778 addr_offset = EEPROM_MAC_ADDR_8192ES;
9779 else if (interface_type == RTW_PCIE)
9780 addr_offset = EEPROM_MAC_ADDR_8192EE;
9783 #ifdef CONFIG_RTL8814A
9785 if (interface_type == RTW_USB)
9786 addr_offset = EEPROM_MAC_ADDR_8814AU;
9787 else if (interface_type == RTW_PCIE)
9788 addr_offset = EEPROM_MAC_ADDR_8814AE;
9792 #ifdef CONFIG_RTL8822B
9794 if (interface_type == RTW_USB)
9795 addr_offset = EEPROM_MAC_ADDR_8822BU;
9796 else if (interface_type == RTW_SDIO)
9797 addr_offset = EEPROM_MAC_ADDR_8822BS;
9798 else if (interface_type == RTW_PCIE)
9799 addr_offset = EEPROM_MAC_ADDR_8822BE;
9801 #endif /* CONFIG_RTL8822B */
9803 #ifdef CONFIG_RTL8821C
9805 if (interface_type == RTW_USB)
9806 addr_offset = EEPROM_MAC_ADDR_8821CU;
9807 else if (interface_type == RTW_SDIO)
9808 addr_offset = EEPROM_MAC_ADDR_8821CS;
9809 else if (interface_type == RTW_PCIE)
9810 addr_offset = EEPROM_MAC_ADDR_8821CE;
9812 #endif /* CONFIG_RTL8821C */
9815 if (addr_offset == -1) {
9816 RTW_ERR("%s: unknown combination - chip_type:%u, interface:%u\n"
9817 , __func__, rtw_get_chip_type(adapter), rtw_get_intf_type(adapter));
9823 int Hal_GetPhyEfuseMACAddr(PADAPTER padapter, u8 *mac_addr)
9828 addr_offset = hal_efuse_macaddr_offset(padapter);
9829 if (addr_offset == -1)
9832 ret = rtw_efuse_map_read(padapter, addr_offset, ETH_ALEN, mac_addr);
9838 void rtw_dump_cur_efuse(PADAPTER padapter)
9842 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
9844 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapsize, _FALSE);
9846 if (mapsize <= 0 || mapsize > EEPROM_MAX_SIZE) {
9847 RTW_ERR("wrong map size %d\n", mapsize);
9851 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
9852 RTW_INFO("EFUSE FILE\n");
9854 RTW_INFO("HW EFUSE\n");
9856 #ifdef CONFIG_RTW_DEBUG
9857 for (i = 0; i < mapsize; i++) {
9859 RTW_PRINT_SEL(RTW_DBGDUMP, "0x%03x: ", i);
9861 _RTW_PRINT_SEL(RTW_DBGDUMP, "%02X%s"
9862 , hal_data->efuse_eeprom_data[i]
9863 , ((i + 1) % 16 == 0) ? "\n" : (((i + 1) % 8 == 0) ? " " : " ")
9866 _RTW_PRINT_SEL(RTW_DBGDUMP, "\n");
9871 #ifdef CONFIG_EFUSE_CONFIG_FILE
9872 u32 Hal_readPGDataFromConfigFile(PADAPTER padapter)
9874 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
9878 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&maplen, _FALSE);
9880 if (maplen < 256 || maplen > EEPROM_MAX_SIZE) {
9881 RTW_ERR("eFuse length error :%d\n", maplen);
9885 ret = rtw_read_efuse_from_file(EFUSE_MAP_PATH, hal_data->efuse_eeprom_data, maplen);
9887 hal_data->efuse_file_status = ((ret == _FAIL) ? EFUSE_FILE_FAILED : EFUSE_FILE_LOADED);
9889 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
9890 rtw_dump_cur_efuse(padapter);
9895 u32 Hal_ReadMACAddrFromFile(PADAPTER padapter, u8 *mac_addr)
9897 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
9900 if (rtw_read_macaddr_from_file(WIFIMAC_PATH, mac_addr) == _SUCCESS
9901 && rtw_check_invalid_mac_address(mac_addr, _TRUE) == _FALSE
9903 hal_data->macaddr_file_status = MACADDR_FILE_LOADED;
9906 hal_data->macaddr_file_status = MACADDR_FILE_FAILED;
9910 #endif /* CONFIG_EFUSE_CONFIG_FILE */
9912 int hal_config_macaddr(_adapter *adapter, bool autoload_fail)
9914 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
9916 int addr_offset = hal_efuse_macaddr_offset(adapter);
9923 if (addr_offset != -1)
9924 hw_addr = &hal_data->efuse_eeprom_data[addr_offset];
9926 #ifdef CONFIG_EFUSE_CONFIG_FILE
9927 /* if the hw_addr is written by efuse file, set to NULL */
9928 if (hal_data->efuse_file_status == EFUSE_FILE_LOADED)
9933 /* try getting hw pg data */
9934 if (Hal_GetPhyEfuseMACAddr(adapter, addr) == _SUCCESS)
9938 /* check hw pg data */
9939 if (hw_addr && rtw_check_invalid_mac_address(hw_addr, _TRUE) == _FALSE) {
9940 _rtw_memcpy(hal_data->EEPROMMACAddr, hw_addr, ETH_ALEN);
9946 #ifdef CONFIG_EFUSE_CONFIG_FILE
9947 /* check wifi mac file */
9948 if (Hal_ReadMACAddrFromFile(adapter, addr) == _SUCCESS) {
9949 _rtw_memcpy(hal_data->EEPROMMACAddr, addr, ETH_ALEN);
9954 _rtw_memset(hal_data->EEPROMMACAddr, 0, ETH_ALEN);
9961 #ifdef CONFIG_RF_POWER_TRIM
9962 u32 Array_kfreemap[] = {
9975 void rtw_bb_rf_gain_offset(_adapter *padapter)
9977 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
9978 struct registry_priv *registry_par = &padapter->registrypriv;
9979 struct kfree_data_t *kfree_data = &pHalData->kfree_data;
9980 u8 value = pHalData->EEPROMRFGainOffset;
9983 u4Byte ArrayLen = sizeof(Array_kfreemap) / sizeof(u32);
9984 pu4Byte Array = Array_kfreemap;
9985 u4Byte v1 = 0, v2 = 0, GainValue = 0, target = 0;
9987 if (registry_par->RegPwrTrimEnable == 2) {
9988 RTW_INFO("Registry kfree default force disable.\n");
9992 #if defined(CONFIG_RTL8723B)
9993 if (value & BIT4 || (registry_par->RegPwrTrimEnable == 1)) {
9994 RTW_INFO("Offset RF Gain.\n");
9995 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x\n", pHalData->EEPROMRFGainVal);
9997 if (pHalData->EEPROMRFGainVal != 0xff) {
9999 if (pHalData->ant_path == ODM_RF_PATH_A)
10000 GainValue = (pHalData->EEPROMRFGainVal & 0x0f);
10003 GainValue = (pHalData->EEPROMRFGainVal & 0xf0) >> 4;
10004 RTW_INFO("Ant PATH_%d GainValue Offset = 0x%x\n", (pHalData->ant_path == ODM_RF_PATH_A) ? (ODM_RF_PATH_A) : (ODM_RF_PATH_B), GainValue);
10006 for (i = 0; i < ArrayLen; i += 2) {
10007 /* RTW_INFO("ArrayLen in =%d ,Array 1 =0x%x ,Array2 =0x%x\n",i,Array[i],Array[i]+1); */
10010 if (v1 == GainValue) {
10011 RTW_INFO("Offset RF Gain. got v1 =0x%x ,v2 =0x%x\n", v1, v2);
10016 RTW_INFO("pHalData->EEPROMRFGainVal=0x%x ,Gain offset Target Value=0x%x\n", pHalData->EEPROMRFGainVal, target);
10018 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
10019 RTW_INFO("Offset RF Gain. before reg 0x7f=0x%08x\n", res);
10020 phy_set_rf_reg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18 | BIT17 | BIT16 | BIT15, target);
10021 res = rtw_hal_read_rfreg(padapter, RF_PATH_A, 0x7f, 0xffffffff);
10023 RTW_INFO("Offset RF Gain. After reg 0x7f=0x%08x\n", res);
10027 RTW_INFO("Offset RF Gain. pHalData->EEPROMRFGainVal=0x%x != 0xff, didn't run Kfree\n", pHalData->EEPROMRFGainVal);
10029 RTW_INFO("Using the default RF gain.\n");
10031 #elif defined(CONFIG_RTL8188E)
10032 if (value & BIT4 || (registry_par->RegPwrTrimEnable == 1)) {
10033 RTW_INFO("8188ES Offset RF Gain.\n");
10034 RTW_INFO("8188ES Offset RF Gain. EEPROMRFGainVal=0x%x\n",
10035 pHalData->EEPROMRFGainVal);
10037 if (pHalData->EEPROMRFGainVal != 0xff) {
10038 res = rtw_hal_read_rfreg(padapter, RF_PATH_A,
10039 REG_RF_BB_GAIN_OFFSET, 0xffffffff);
10041 RTW_INFO("Offset RF Gain. reg 0x55=0x%x\n", res);
10044 res |= (pHalData->EEPROMRFGainVal & 0x0f) << 15;
10045 RTW_INFO("Offset RF Gain. res=0x%x\n", res);
10047 rtw_hal_write_rfreg(padapter, RF_PATH_A,
10048 REG_RF_BB_GAIN_OFFSET,
10049 RF_GAIN_OFFSET_MASK, res);
10051 RTW_INFO("Offset RF Gain. EEPROMRFGainVal=0x%x == 0xff, didn't run Kfree\n",
10052 pHalData->EEPROMRFGainVal);
10055 RTW_INFO("Using the default RF gain.\n");
10057 /* TODO: call this when channel switch */
10058 if (kfree_data->flag & KFREE_FLAG_ON)
10059 rtw_rf_apply_tx_gain_offset(padapter, 6); /* input ch6 to select BB_GAIN_2G */
10063 #endif /*CONFIG_RF_POWER_TRIM */
10065 bool kfree_data_is_bb_gain_empty(struct kfree_data_t *data)
10067 #ifdef CONFIG_RF_POWER_TRIM
10070 for (i = 0; i < BB_GAIN_NUM; i++)
10071 for (j = 0; j < RF_PATH_MAX; j++)
10072 if (data->bb_gain[i][j] != 0)
10078 #ifdef CONFIG_USB_RX_AGGREGATION
10079 void rtw_set_usb_agg_by_mode_normal(_adapter *padapter, u8 cur_wireless_mode)
10081 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10082 if (cur_wireless_mode < WIRELESS_11_24N
10083 && cur_wireless_mode > 0) { /* ABG mode */
10084 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
10088 remainder = MAX_RECVBUF_SZ % (4 * 1024);
10089 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
10091 if (quotient > 5) {
10092 pHalData->rxagg_usb_size = 0x6;
10093 pHalData->rxagg_usb_timeout = 0x10;
10095 if (remainder >= 2048) {
10096 pHalData->rxagg_usb_size = quotient;
10097 pHalData->rxagg_usb_timeout = 0x10;
10099 pHalData->rxagg_usb_size = (quotient - 1);
10100 pHalData->rxagg_usb_timeout = 0x10;
10103 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
10104 if (0x6 != pHalData->rxagg_usb_size || 0x10 != pHalData->rxagg_usb_timeout) {
10105 pHalData->rxagg_usb_size = 0x6;
10106 pHalData->rxagg_usb_timeout = 0x10;
10107 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
10108 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
10110 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
10112 } else if (cur_wireless_mode >= WIRELESS_11_24N
10113 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
10114 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
10118 remainder = MAX_RECVBUF_SZ % (4 * 1024);
10119 quotient = (u8)(MAX_RECVBUF_SZ >> 12);
10121 if (quotient > 5) {
10122 pHalData->rxagg_usb_size = 0x5;
10123 pHalData->rxagg_usb_timeout = 0x20;
10125 if (remainder >= 2048) {
10126 pHalData->rxagg_usb_size = quotient;
10127 pHalData->rxagg_usb_timeout = 0x10;
10129 pHalData->rxagg_usb_size = (quotient - 1);
10130 pHalData->rxagg_usb_timeout = 0x10;
10133 #else /* !CONFIG_PREALLOC_RX_SKB_BUFFER */
10134 if ((0x5 != pHalData->rxagg_usb_size) || (0x20 != pHalData->rxagg_usb_timeout)) {
10135 pHalData->rxagg_usb_size = 0x5;
10136 pHalData->rxagg_usb_timeout = 0x20;
10137 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
10138 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
10140 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
10143 /* RTW_INFO("%s: Unknow wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
10147 void rtw_set_usb_agg_by_mode_customer(_adapter *padapter, u8 cur_wireless_mode, u8 UsbDmaSize, u8 Legacy_UsbDmaSize)
10149 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10151 if (cur_wireless_mode < WIRELESS_11_24N
10152 && cur_wireless_mode > 0) { /* ABG mode */
10153 if (Legacy_UsbDmaSize != pHalData->rxagg_usb_size
10154 || 0x10 != pHalData->rxagg_usb_timeout) {
10155 pHalData->rxagg_usb_size = Legacy_UsbDmaSize;
10156 pHalData->rxagg_usb_timeout = 0x10;
10157 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
10158 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
10160 } else if (cur_wireless_mode >= WIRELESS_11_24N
10161 && cur_wireless_mode <= WIRELESS_MODE_MAX) { /* N AC mode */
10162 if (UsbDmaSize != pHalData->rxagg_usb_size
10163 || 0x20 != pHalData->rxagg_usb_timeout) {
10164 pHalData->rxagg_usb_size = UsbDmaSize;
10165 pHalData->rxagg_usb_timeout = 0x20;
10166 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH,
10167 pHalData->rxagg_usb_size | (pHalData->rxagg_usb_timeout << 8));
10170 /* RTW_INFO("%s: Unknown wireless mode(0x%x)\n",__func__,padapter->mlmeextpriv.cur_wireless_mode); */
10174 void rtw_set_usb_agg_by_mode(_adapter *padapter, u8 cur_wireless_mode)
10176 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
10177 rtw_set_usb_agg_by_mode_customer(padapter, cur_wireless_mode, 0x3, 0x3);
10179 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
10181 rtw_set_usb_agg_by_mode_normal(padapter, cur_wireless_mode);
10183 #endif /* CONFIG_USB_RX_AGGREGATION */
10185 /* To avoid RX affect TX throughput */
10186 void dm_DynamicUsbTxAgg(_adapter *padapter, u8 from_timer)
10188 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
10189 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
10190 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10191 u8 cur_wireless_mode = WIRELESS_INVALID;
10193 #ifdef CONFIG_USB_RX_AGGREGATION
10194 if (IS_HARDWARE_TYPE_8821U(padapter)) { /* || IS_HARDWARE_TYPE_8192EU(padapter)) */
10195 /* This AGG_PH_TH only for UsbRxAggMode == USB_RX_AGG_USB */
10196 if ((pHalData->rxagg_mode == RX_AGG_USB) && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {
10197 if (pdvobjpriv->traffic_stat.cur_tx_tp > 2 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
10198 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1010);
10199 else if (pdvobjpriv->traffic_stat.last_tx_bytes > 220000 && pdvobjpriv->traffic_stat.cur_rx_tp < 30)
10200 rtw_write16(padapter , REG_RXDMA_AGG_PG_TH , 0x1006);
10202 rtw_write16(padapter, REG_RXDMA_AGG_PG_TH, 0x2005); /* dmc agg th 20K */
10204 /* RTW_INFO("TX_TP=%u, RX_TP=%u\n", pdvobjpriv->traffic_stat.cur_tx_tp, pdvobjpriv->traffic_stat.cur_rx_tp); */
10206 } else if (IS_HARDWARE_TYPE_8812(padapter)) {
10207 #ifdef CONFIG_CONCURRENT_MODE
10210 u8 bassocaed = _FALSE;
10211 struct mlme_ext_priv *mlmeext;
10213 for (i = 0; i < pdvobjpriv->iface_nums; i++) {
10214 iface = pdvobjpriv->padapters[i];
10215 mlmeext = &iface->mlmeextpriv;
10216 if (rtw_linked_check(iface) == _TRUE) {
10217 if (mlmeext->cur_wireless_mode >= cur_wireless_mode)
10218 cur_wireless_mode = mlmeext->cur_wireless_mode;
10224 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
10225 #ifdef CONFIG_PLATFORM_NOVATEK_NT72668
10227 rtw_set_usb_agg_by_mode(padapter, cur_wireless_mode);
10228 #endif /* CONFIG_PLATFORM_NOVATEK_NT72668 */
10233 /* bus-agg check for SoftAP mode */
10234 inline u8 rtw_hal_busagg_qsel_check(_adapter *padapter, u8 pre_qsel, u8 next_qsel)
10236 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
10237 u8 chk_rst = _SUCCESS;
10239 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
10242 /* if((pre_qsel == 0xFF)||(next_qsel== 0xFF)) */
10243 /* return chk_rst; */
10245 if (((pre_qsel == QSLT_HIGH) || ((next_qsel == QSLT_HIGH)))
10246 && (pre_qsel != next_qsel)) {
10247 /* RTW_INFO("### bus-agg break cause of qsel misatch, pre_qsel=0x%02x,next_qsel=0x%02x ###\n", */
10248 /* pre_qsel,next_qsel); */
10256 * dump_TX_FIFO: This is only used to dump TX_FIFO for debug WoW mode offload
10260 * adapter: adapter pointer.
10261 * page_num: The max. page number that user want to dump.
10262 * page_size: page size of each page. eg. 128 bytes, 256 bytes, 512byte.
10264 void dump_TX_FIFO(_adapter *padapter, u8 page_num, u16 page_size)
10271 u32 count = (page_size / 8);
10273 if (page_num <= 0) {
10274 RTW_INFO("!!%s: incorrect input page_num paramter!\n", __func__);
10278 if (page_size < 128 || page_size > 512) {
10279 RTW_INFO("!!%s: incorrect input page_size paramter!\n", __func__);
10283 RTW_INFO("+%s+\n", __func__);
10284 val = rtw_read8(padapter, 0x106);
10285 rtw_write8(padapter, 0x106, 0x69);
10286 RTW_INFO("0x106: 0x%02x\n", val);
10287 base = rtw_read8(padapter, 0x209);
10288 RTW_INFO("0x209: 0x%02x\n", base);
10290 addr = ((base)*page_size) / 8;
10291 for (i = 0 ; i < page_num * count ; i += 2) {
10292 rtw_write32(padapter, 0x140, addr + i);
10293 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
10294 rtw_write32(padapter, 0x140, addr + i + 1);
10295 printk(" %08x %08x\n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
10299 #ifdef CONFIG_GPIO_API
10300 u8 rtw_hal_get_gpio(_adapter *adapter, u8 gpio_num)
10304 u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
10305 u8 gpio_num_to_set = gpio_num;
10306 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(adapter);
10308 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
10311 rtw_ps_deny(adapter, PS_DENY_IOCTL);
10313 RTW_INFO("rf_pwrstate=0x%02x\n", pwrpriv->rf_pwrstate);
10314 LeaveAllPowerSaveModeDirect(adapter);
10316 if (gpio_num > 7) {
10317 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
10318 gpio_num_to_set = gpio_num - 8;
10321 /* Read GPIO Direction */
10322 direction = (rtw_read8(adapter, gpio_ctrl_reg_to_set) & BIT(gpio_num_to_set)) >> gpio_num;
10324 /* According the direction to read register value */
10326 value = (rtw_read8(adapter, gpio_ctrl_reg_to_set) & BIT(gpio_num_to_set)) >> gpio_num;
10328 value = (rtw_read8(adapter, gpio_ctrl_reg_to_set) & BIT(gpio_num_to_set)) >> gpio_num;
10330 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
10331 RTW_INFO("%s direction=%d value=%d\n", __FUNCTION__, direction, value);
10336 int rtw_hal_set_gpio_output_value(_adapter *adapter, u8 gpio_num, bool isHigh)
10340 u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
10341 u8 gpio_num_to_set = gpio_num;
10343 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
10346 rtw_ps_deny(adapter, PS_DENY_IOCTL);
10348 LeaveAllPowerSaveModeDirect(adapter);
10350 if (gpio_num > 7) {
10351 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
10352 gpio_num_to_set = gpio_num - 8;
10355 /* Read GPIO direction */
10356 direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
10358 /* If GPIO is output direction, setting value. */
10361 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
10363 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
10365 RTW_INFO("%s Set gpio %x[%d]=%d\n", __FUNCTION__, REG_GPIO_PIN_CTRL + 1, gpio_num, isHigh);
10368 RTW_INFO("%s The gpio is input,not be set!\n", __FUNCTION__);
10372 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
10376 int rtw_hal_config_gpio(_adapter *adapter, u8 gpio_num, bool isOutput)
10378 u32 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL + 2;
10379 u8 gpio_num_to_set = gpio_num;
10381 if (rtw_hal_gpio_func_check(adapter, gpio_num) == _FAIL)
10384 RTW_INFO("%s gpio_num =%d direction=%d\n", __FUNCTION__, gpio_num, isOutput);
10386 rtw_ps_deny(adapter, PS_DENY_IOCTL);
10388 LeaveAllPowerSaveModeDirect(adapter);
10390 rtw_hal_gpio_multi_func_reset(adapter, gpio_num);
10392 if (gpio_num > 7) {
10393 gpio_ctrl_reg_to_set = REG_GPIO_PIN_CTRL_2 + 2;
10394 gpio_num_to_set = gpio_num - 8;
10398 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) | BIT(gpio_num_to_set));
10400 rtw_write8(adapter, gpio_ctrl_reg_to_set, rtw_read8(adapter, gpio_ctrl_reg_to_set) & ~BIT(gpio_num_to_set));
10402 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
10406 int rtw_hal_register_gpio_interrupt(_adapter *adapter, int gpio_num, void(*callback)(u8 level))
10410 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
10412 if (IS_HARDWARE_TYPE_8188E(adapter)) {
10413 if (gpio_num > 7 || gpio_num < 4) {
10414 RTW_PRINT("%s The gpio number does not included 4~7.\n", __FUNCTION__);
10419 rtw_ps_deny(adapter, PS_DENY_IOCTL);
10421 LeaveAllPowerSaveModeDirect(adapter);
10423 /* Read GPIO direction */
10424 direction = (rtw_read8(adapter, REG_GPIO_PIN_CTRL + 2) & BIT(gpio_num)) >> gpio_num;
10426 RTW_PRINT("%s Can't register output gpio as interrupt.\n", __FUNCTION__);
10430 /* Config GPIO Mode */
10431 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) | BIT(gpio_num));
10433 /* Register GPIO interrupt handler*/
10434 adapter->gpiointpriv.callback[gpio_num] = callback;
10436 /* Set GPIO interrupt mode, 0:positive edge, 1:negative edge */
10437 value = rtw_read8(adapter, REG_GPIO_PIN_CTRL) & BIT(gpio_num);
10438 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_HSIMR + 2) ^ value;
10439 rtw_write8(adapter, REG_GPIO_INTM, adapter->gpiointpriv.interrupt_mode);
10441 /* Enable GPIO interrupt */
10442 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) | BIT(gpio_num);
10443 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
10445 rtw_hal_update_hisr_hsisr_ind(adapter, 1);
10447 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
10451 int rtw_hal_disable_gpio_interrupt(_adapter *adapter, int gpio_num)
10455 PHAL_DATA_TYPE phal = GET_HAL_DATA(adapter);
10457 if (IS_HARDWARE_TYPE_8188E(adapter)) {
10458 if (gpio_num > 7 || gpio_num < 4) {
10459 RTW_INFO("%s The gpio number does not included 4~7.\n", __FUNCTION__);
10464 rtw_ps_deny(adapter, PS_DENY_IOCTL);
10466 LeaveAllPowerSaveModeDirect(adapter);
10468 /* Config GPIO Mode */
10469 rtw_write8(adapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(adapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(gpio_num));
10471 /* Unregister GPIO interrupt handler*/
10472 adapter->gpiointpriv.callback[gpio_num] = NULL;
10474 /* Reset GPIO interrupt mode, 0:positive edge, 1:negative edge */
10475 adapter->gpiointpriv.interrupt_mode = rtw_read8(adapter, REG_GPIO_INTM) & ~BIT(gpio_num);
10476 rtw_write8(adapter, REG_GPIO_INTM, 0x00);
10478 /* Disable GPIO interrupt */
10479 adapter->gpiointpriv.interrupt_enable_mask = rtw_read8(adapter, REG_HSIMR + 2) & ~BIT(gpio_num);
10480 rtw_write8(adapter, REG_HSIMR + 2, adapter->gpiointpriv.interrupt_enable_mask);
10482 if (!adapter->gpiointpriv.interrupt_enable_mask)
10483 rtw_hal_update_hisr_hsisr_ind(adapter, 0);
10485 rtw_ps_deny_cancel(adapter, PS_DENY_IOCTL);
10491 s8 rtw_hal_ch_sw_iqk_info_search(_adapter *padapter, u8 central_chnl, u8 bw_mode)
10493 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10496 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
10497 if ((pHalData->iqk_reg_backup[i].central_chnl != 0)) {
10498 if ((pHalData->iqk_reg_backup[i].central_chnl == central_chnl)
10499 && (pHalData->iqk_reg_backup[i].bw_mode == bw_mode))
10507 void rtw_hal_ch_sw_iqk_info_backup(_adapter *padapter)
10509 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10513 /* If it's an existed record, overwrite it */
10514 res = rtw_hal_ch_sw_iqk_info_search(padapter, pHalData->current_channel, pHalData->current_channel_bw);
10515 if ((res >= 0) && (res < MAX_IQK_INFO_BACKUP_CHNL_NUM)) {
10516 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[res]));
10520 /* Search for the empty record to use */
10521 for (i = 0; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++) {
10522 if (pHalData->iqk_reg_backup[i].central_chnl == 0) {
10523 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[i]));
10528 /* Else, overwrite the oldest record */
10529 for (i = 1; i < MAX_IQK_INFO_BACKUP_CHNL_NUM; i++)
10530 _rtw_memcpy(&(pHalData->iqk_reg_backup[i - 1]), &(pHalData->iqk_reg_backup[i]), sizeof(struct hal_iqk_reg_backup));
10532 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_BACKUP, (u8 *)&(pHalData->iqk_reg_backup[MAX_IQK_INFO_BACKUP_CHNL_NUM - 1]));
10535 void rtw_hal_ch_sw_iqk_info_restore(_adapter *padapter, u8 ch_sw_use_case)
10537 rtw_hal_set_hwreg(padapter, HW_VAR_CH_SW_IQK_INFO_RESTORE, &ch_sw_use_case);
10540 void rtw_dump_mac_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
10542 u32 mac_cck_ok = 0, mac_ofdm_ok = 0, mac_ht_ok = 0, mac_vht_ok = 0;
10543 u32 mac_cck_err = 0, mac_ofdm_err = 0, mac_ht_err = 0, mac_vht_err = 0;
10544 u32 mac_cck_fa = 0, mac_ofdm_fa = 0, mac_ht_fa = 0;
10545 u32 DropPacket = 0;
10551 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter))
10552 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
10554 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x3);
10555 mac_cck_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
10556 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
10557 mac_ofdm_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
10558 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x6);
10559 mac_ht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
10561 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
10562 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x0);
10563 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
10564 mac_vht_ok = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
10565 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
10568 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x4);
10569 mac_cck_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
10570 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
10571 mac_ofdm_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
10572 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x7);
10573 mac_ht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
10575 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
10576 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x1);
10577 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x1);
10578 mac_vht_err = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0]*/
10579 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT26, 0x0);/*clear bit-26*/
10582 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x5);
10583 mac_cck_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
10584 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x2);
10585 mac_ofdm_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
10586 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT28 | BIT29 | BIT30 | BIT31, 0x9);
10587 mac_ht_fa = phy_query_mac_reg(padapter, REG_RXERR_RPT, bMaskLWord);/* [15:0] */
10589 /* Mac_DropPacket */
10590 rtw_write32(padapter, REG_RXERR_RPT, (rtw_read32(padapter, REG_RXERR_RPT) & 0x0FFFFFFF) | Mac_DropPacket);
10591 DropPacket = rtw_read32(padapter, REG_RXERR_RPT) & 0x0000FFFF;
10593 rx_counter->rx_pkt_ok = mac_cck_ok + mac_ofdm_ok + mac_ht_ok + mac_vht_ok;
10594 rx_counter->rx_pkt_crc_error = mac_cck_err + mac_ofdm_err + mac_ht_err + mac_vht_err;
10595 rx_counter->rx_cck_fa = mac_cck_fa;
10596 rx_counter->rx_ofdm_fa = mac_ofdm_fa;
10597 rx_counter->rx_ht_fa = mac_ht_fa;
10598 rx_counter->rx_pkt_drop = DropPacket;
10600 void rtw_reset_mac_rx_counters(_adapter *padapter)
10603 /* If no packet rx, MaxRx clock be gating ,BIT_DISGCLK bit19 set 1 for fix*/
10604 if (IS_HARDWARE_TYPE_8703B(padapter) ||
10605 IS_HARDWARE_TYPE_8723D(padapter) ||
10606 IS_HARDWARE_TYPE_8188F(padapter))
10607 phy_set_mac_reg(padapter, REG_RCR, BIT19, 0x1);
10609 /* reset mac counter */
10610 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x1);
10611 phy_set_mac_reg(padapter, REG_RXERR_RPT, BIT27, 0x0);
10614 void rtw_dump_phy_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
10616 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;
10621 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
10622 cckok = phy_query_bb_reg(padapter, 0xF04, 0x3FFF); /* [13:0] */
10623 ofdmok = phy_query_bb_reg(padapter, 0xF14, 0x3FFF); /* [13:0] */
10624 htok = phy_query_bb_reg(padapter, 0xF10, 0x3FFF); /* [13:0] */
10625 vht_ok = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF); /* [13:0] */
10626 cckcrc = phy_query_bb_reg(padapter, 0xF04, 0x3FFF0000); /* [29:16] */
10627 ofdmcrc = phy_query_bb_reg(padapter, 0xF14, 0x3FFF0000); /* [29:16] */
10628 htcrc = phy_query_bb_reg(padapter, 0xF10, 0x3FFF0000); /* [29:16] */
10629 vht_err = phy_query_bb_reg(padapter, 0xF0C, 0x3FFF0000); /* [29:16] */
10630 CCK_FA = phy_query_bb_reg(padapter, 0xA5C, bMaskLWord);
10631 OFDM_FA = phy_query_bb_reg(padapter, 0xF48, bMaskLWord);
10633 cckok = phy_query_bb_reg(padapter, 0xF88, bMaskDWord);
10634 ofdmok = phy_query_bb_reg(padapter, 0xF94, bMaskLWord);
10635 htok = phy_query_bb_reg(padapter, 0xF90, bMaskLWord);
10637 cckcrc = phy_query_bb_reg(padapter, 0xF84, bMaskDWord);
10638 ofdmcrc = phy_query_bb_reg(padapter, 0xF94, bMaskHWord);
10639 htcrc = phy_query_bb_reg(padapter, 0xF90, bMaskHWord);
10641 OFDM_FA = phy_query_bb_reg(padapter, 0xCF0, bMaskLWord) + phy_query_bb_reg(padapter, 0xCF2, bMaskLWord) +
10642 phy_query_bb_reg(padapter, 0xDA2, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA4, bMaskLWord) +
10643 phy_query_bb_reg(padapter, 0xDA6, bMaskLWord) + phy_query_bb_reg(padapter, 0xDA8, bMaskLWord);
10645 CCK_FA = (rtw_read8(padapter, 0xA5B) << 8) | (rtw_read8(padapter, 0xA5C));
10648 rx_counter->rx_pkt_ok = cckok + ofdmok + htok + vht_ok;
10649 rx_counter->rx_pkt_crc_error = cckcrc + ofdmcrc + htcrc + vht_err;
10650 rx_counter->rx_ofdm_fa = OFDM_FA;
10651 rx_counter->rx_cck_fa = CCK_FA;
10655 void rtw_reset_phy_trx_ok_counters(_adapter *padapter)
10657 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
10658 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x1);
10659 phy_set_bb_reg(padapter, 0xB58, BIT0, 0x0);
10662 void rtw_reset_phy_rx_counters(_adapter *padapter)
10664 /* reset phy counter */
10665 if (IS_HARDWARE_TYPE_JAGUAR(padapter) || IS_HARDWARE_TYPE_JAGUAR2(padapter)) {
10666 rtw_reset_phy_trx_ok_counters(padapter);
10668 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x1);/* reset OFDA FA counter */
10669 phy_set_bb_reg(padapter, 0x9A4, BIT17, 0x0);
10671 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
10672 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
10674 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x1);
10676 phy_set_bb_reg(padapter, 0xF14, BIT16, 0x0);
10678 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x1);/* reset OFDA FA counter */
10679 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x1);/* reset OFDA FA counter */
10680 phy_set_bb_reg(padapter, 0xD00, BIT27, 0x0);
10681 phy_set_bb_reg(padapter, 0xC0C, BIT31, 0x0);
10683 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x0);/* reset CCK FA counter */
10684 phy_set_bb_reg(padapter, 0xA2C, BIT15, 0x1);
10687 #ifdef DBG_RX_COUNTER_DUMP
10688 void rtw_dump_drv_rx_counters(_adapter *padapter, struct dbg_rx_counter *rx_counter)
10690 struct recv_priv *precvpriv = &padapter->recvpriv;
10695 rx_counter->rx_pkt_ok = padapter->drv_rx_cnt_ok;
10696 rx_counter->rx_pkt_crc_error = padapter->drv_rx_cnt_crcerror;
10697 rx_counter->rx_pkt_drop = precvpriv->rx_drop - padapter->drv_rx_cnt_drop;
10699 void rtw_reset_drv_rx_counters(_adapter *padapter)
10701 struct recv_priv *precvpriv = &padapter->recvpriv;
10702 padapter->drv_rx_cnt_ok = 0;
10703 padapter->drv_rx_cnt_crcerror = 0;
10704 padapter->drv_rx_cnt_drop = precvpriv->rx_drop;
10706 void rtw_dump_phy_rxcnts_preprocess(_adapter *padapter, u8 rx_cnt_mode)
10709 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
10711 if ((!(padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER)) && (rx_cnt_mode & DUMP_PHY_RX_COUNTER)) {
10712 rtw_hal_get_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, NULL);
10713 RTW_INFO("%s CurIGValue:0x%02x\n", __FUNCTION__, initialgain);
10714 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
10715 /*disable dynamic functions, such as high power, DIG*/
10716 rtw_phydm_ability_backup(padapter);
10717 rtw_phydm_func_clr(padapter, (ODM_BB_DIG | ODM_BB_FA_CNT));
10718 } else if ((padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) && (!(rx_cnt_mode & DUMP_PHY_RX_COUNTER))) {
10719 /* turn on phy-dynamic functions */
10720 rtw_phydm_ability_restore(padapter);
10721 initialgain = 0xff; /* restore RX GAIN */
10722 rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);
10727 void rtw_dump_rx_counters(_adapter *padapter)
10729 struct dbg_rx_counter rx_counter;
10731 if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
10732 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
10733 rtw_dump_drv_rx_counters(padapter, &rx_counter);
10734 RTW_INFO("Drv Received packet OK:%d CRC error:%d Drop Packets: %d\n",
10735 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
10736 rtw_reset_drv_rx_counters(padapter);
10739 if (padapter->dump_rx_cnt_mode & DUMP_MAC_RX_COUNTER) {
10740 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
10741 rtw_dump_mac_rx_counters(padapter, &rx_counter);
10742 RTW_INFO("Mac Received packet OK:%d CRC error:%d FA Counter: %d Drop Packets: %d\n",
10743 rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error,
10744 rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa + rx_counter.rx_ht_fa,
10745 rx_counter.rx_pkt_drop);
10746 rtw_reset_mac_rx_counters(padapter);
10749 if (padapter->dump_rx_cnt_mode & DUMP_PHY_RX_COUNTER) {
10750 _rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
10751 rtw_dump_phy_rx_counters(padapter, &rx_counter);
10752 /* RTW_INFO("%s: OFDM_FA =%d\n", __FUNCTION__, rx_counter.rx_ofdm_fa); */
10753 /* RTW_INFO("%s: CCK_FA =%d\n", __FUNCTION__, rx_counter.rx_cck_fa); */
10754 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,
10755 rx_counter.rx_ofdm_fa + rx_counter.rx_cck_fa);
10756 rtw_reset_phy_rx_counters(padapter);
10760 void rtw_get_noise(_adapter *padapter)
10762 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
10763 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10764 struct noise_info info;
10765 if (rtw_linked_check(padapter)) {
10766 info.bPauseDIG = _TRUE;
10767 info.IGIValue = 0x1e;
10768 info.max_time = 100;/* ms */
10769 info.chan = pmlmeext->cur_channel ;/* rtw_get_oper_ch(padapter); */
10770 rtw_ps_deny(padapter, PS_DENY_IOCTL);
10771 LeaveAllPowerSaveModeDirect(padapter);
10773 rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, _FALSE);
10774 /* odm_inband_noise_monitor(podmpriv,_TRUE,0x20,100); */
10775 rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
10776 rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &(info.chan), &(padapter->recvpriv.noise));
10777 #ifdef DBG_NOISE_MONITOR
10778 RTW_INFO("chan:%d,noise_level:%d\n", info.chan, padapter->recvpriv.noise);
10784 u8 rtw_get_current_tx_sgi(_adapter *padapter, u8 macid)
10786 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10787 struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
10788 struct _rate_adaptive_table_ *pRA_Table = &pDM_Odm->dm_ra_table;
10789 u8 curr_tx_sgi = 0;
10791 #if defined(CONFIG_RTL8188E)
10792 curr_tx_sgi = odm_ra_get_decision_rate_8188e(pDM_Odm, macid);
10794 curr_tx_sgi = ((pRA_Table->link_tx_rate[macid]) & 0x80) >> 7;
10797 return curr_tx_sgi;
10800 u8 rtw_get_current_tx_rate(_adapter *padapter, u8 macid)
10802 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10803 struct PHY_DM_STRUCT *pDM_Odm = &pHalData->odmpriv;
10804 struct _rate_adaptive_table_ *pRA_Table = &pDM_Odm->dm_ra_table;
10807 #if (RATE_ADAPTIVE_SUPPORT == 1)
10808 rate_id = odm_ra_get_decision_rate_8188e(pDM_Odm, macid);
10810 rate_id = (pRA_Table->link_tx_rate[macid]) & 0x7f;
10817 void update_IOT_info(_adapter *padapter)
10819 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10820 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10822 switch (pmlmeinfo->assoc_AP_vendor) {
10823 case HT_IOT_PEER_MARVELL:
10824 pmlmeinfo->turboMode_cts2self = 1;
10825 pmlmeinfo->turboMode_rtsen = 0;
10828 case HT_IOT_PEER_RALINK:
10829 pmlmeinfo->turboMode_cts2self = 0;
10830 pmlmeinfo->turboMode_rtsen = 1;
10831 /* disable high power */
10832 rtw_phydm_func_clr(padapter, ODM_BB_DYNAMIC_TXPWR);
10834 case HT_IOT_PEER_REALTEK:
10835 /* rtw_write16(padapter, 0x4cc, 0xffff); */
10836 /* rtw_write16(padapter, 0x546, 0x01c0); */
10837 /* disable high power */
10838 rtw_phydm_func_clr(padapter, ODM_BB_DYNAMIC_TXPWR);
10841 pmlmeinfo->turboMode_cts2self = 0;
10842 pmlmeinfo->turboMode_rtsen = 1;
10847 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
10848 void rtw_acs_start(_adapter *padapter, bool bStart)
10850 if (_TRUE == bStart) {
10851 ACS_OP acs_op = ACS_INIT;
10853 rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
10854 rtw_set_acs_channel(padapter, 0);
10855 SET_ACS_STATE(padapter, ACS_ENABLE);
10857 SET_ACS_STATE(padapter, ACS_DISABLE);
10858 #ifdef DBG_AUTO_CHNL_SEL_NHM
10860 u8 best_24g_ch = 0;
10863 rtw_hal_get_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &(best_24g_ch), &(best_5g_ch));
10864 RTW_INFO("[ACS-"ADPT_FMT"] Best 2.4G CH:%u\n", ADPT_ARG(padapter), best_24g_ch);
10865 RTW_INFO("[ACS-"ADPT_FMT"] Best 5G CH:%u\n", ADPT_ARG(padapter), best_5g_ch);
10872 /* TODO: merge with phydm, see odm_SetCrystalCap() */
10873 void hal_set_crystal_cap(_adapter *adapter, u8 crystal_cap)
10875 crystal_cap = crystal_cap & 0x3F;
10877 switch (rtw_get_chip_type(adapter)) {
10878 #if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8188F)
10881 /* write 0x24[16:11] = 0x24[22:17] = CrystalCap */
10882 phy_set_bb_reg(adapter, REG_AFE_XTAL_CTRL, 0x007FF800, (crystal_cap | (crystal_cap << 6)));
10885 #if defined(CONFIG_RTL8812A)
10887 /* write 0x2C[30:25] = 0x2C[24:19] = CrystalCap */
10888 phy_set_bb_reg(adapter, REG_MAC_PHY_CTRL, 0x7FF80000, (crystal_cap | (crystal_cap << 6)));
10891 #if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8703B) || \
10892 defined(CONFIG_RTL8723D) || defined(CONFIG_RTL8821A) || \
10893 defined(CONFIG_RTL8192E)
10899 /* write 0x2C[23:18] = 0x2C[17:12] = CrystalCap */
10900 phy_set_bb_reg(adapter, REG_MAC_PHY_CTRL, 0x00FFF000, (crystal_cap | (crystal_cap << 6)));
10903 #if defined(CONFIG_RTL8814A)
10905 /* write 0x2C[26:21] = 0x2C[20:15] = CrystalCap*/
10906 phy_set_bb_reg(adapter, REG_MAC_PHY_CTRL, 0x07FF8000, (crystal_cap | (crystal_cap << 6)));
10909 #if defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C)
10913 /* write 0x28[6:1] = 0x24[30:25] = CrystalCap */
10914 crystal_cap = crystal_cap & 0x3F;
10915 phy_set_bb_reg(adapter, REG_AFE_XTAL_CTRL, 0x7E000000, crystal_cap);
10916 phy_set_bb_reg(adapter, REG_AFE_PLL_CTRL, 0x7E, crystal_cap);
10924 int hal_spec_init(_adapter *adapter)
10926 u8 interface_type = 0;
10927 int ret = _SUCCESS;
10929 interface_type = rtw_get_intf_type(adapter);
10931 switch (rtw_get_chip_type(adapter)) {
10932 #ifdef CONFIG_RTL8723B
10934 init_hal_spec_8723b(adapter);
10937 #ifdef CONFIG_RTL8703B
10939 init_hal_spec_8703b(adapter);
10942 #ifdef CONFIG_RTL8723D
10944 init_hal_spec_8723d(adapter);
10947 #ifdef CONFIG_RTL8188E
10949 init_hal_spec_8188e(adapter);
10952 #ifdef CONFIG_RTL8188F
10954 init_hal_spec_8188f(adapter);
10957 #ifdef CONFIG_RTL8812A
10959 init_hal_spec_8812a(adapter);
10962 #ifdef CONFIG_RTL8821A
10964 init_hal_spec_8821a(adapter);
10967 #ifdef CONFIG_RTL8192E
10969 init_hal_spec_8192e(adapter);
10972 #ifdef CONFIG_RTL8814A
10974 init_hal_spec_8814a(adapter);
10977 #ifdef CONFIG_RTL8822B
10979 rtl8822b_init_hal_spec(adapter);
10982 #ifdef CONFIG_RTL8821C
10984 init_hal_spec_rtl8821c(adapter);
10988 RTW_ERR("%s: unknown chip_type:%u\n"
10989 , __func__, rtw_get_chip_type(adapter));
10997 static const char *const _band_cap_str[] = {
11002 static const char *const _bw_cap_str[] = {
11009 /* BIT6 */"80_80M",
11012 static const char *const _proto_cap_str[] = {
11019 static const char *const _wl_func_str[] = {
11021 /* BIT1 */"MIRACAST",
11026 void dump_hal_spec(void *sel, _adapter *adapter)
11028 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
11031 RTW_PRINT_SEL(sel, "macid_num:%u\n", hal_spec->macid_num);
11032 RTW_PRINT_SEL(sel, "sec_cap:0x%02x\n", hal_spec->sec_cap);
11033 RTW_PRINT_SEL(sel, "sec_cam_ent_num:%u\n", hal_spec->sec_cam_ent_num);
11034 RTW_PRINT_SEL(sel, "rfpath_num_2g:%u\n", hal_spec->rfpath_num_2g);
11035 RTW_PRINT_SEL(sel, "rfpath_num_5g:%u\n", hal_spec->rfpath_num_5g);
11036 RTW_PRINT_SEL(sel, "max_tx_cnt:%u\n", hal_spec->max_tx_cnt);
11037 RTW_PRINT_SEL(sel, "tx_nss_num:%u\n", hal_spec->tx_nss_num);
11038 RTW_PRINT_SEL(sel, "rx_nss_num:%u\n", hal_spec->rx_nss_num);
11040 RTW_PRINT_SEL(sel, "band_cap:");
11041 for (i = 0; i < BAND_CAP_BIT_NUM; i++) {
11042 if (((hal_spec->band_cap) >> i) & BIT0 && _band_cap_str[i])
11043 _RTW_PRINT_SEL(sel, "%s ", _band_cap_str[i]);
11045 _RTW_PRINT_SEL(sel, "\n");
11047 RTW_PRINT_SEL(sel, "bw_cap:");
11048 for (i = 0; i < BW_CAP_BIT_NUM; i++) {
11049 if (((hal_spec->bw_cap) >> i) & BIT0 && _bw_cap_str[i])
11050 _RTW_PRINT_SEL(sel, "%s ", _bw_cap_str[i]);
11052 _RTW_PRINT_SEL(sel, "\n");
11054 RTW_PRINT_SEL(sel, "proto_cap:");
11055 for (i = 0; i < PROTO_CAP_BIT_NUM; i++) {
11056 if (((hal_spec->proto_cap) >> i) & BIT0 && _proto_cap_str[i])
11057 _RTW_PRINT_SEL(sel, "%s ", _proto_cap_str[i]);
11059 _RTW_PRINT_SEL(sel, "\n");
11061 RTW_PRINT_SEL(sel, "wl_func:");
11062 for (i = 0; i < WL_FUNC_BIT_NUM; i++) {
11063 if (((hal_spec->wl_func) >> i) & BIT0 && _wl_func_str[i])
11064 _RTW_PRINT_SEL(sel, "%s ", _wl_func_str[i]);
11066 _RTW_PRINT_SEL(sel, "\n");
11069 inline bool hal_chk_band_cap(_adapter *adapter, u8 cap)
11071 return GET_HAL_SPEC(adapter)->band_cap & cap;
11074 inline bool hal_chk_bw_cap(_adapter *adapter, u8 cap)
11076 return GET_HAL_SPEC(adapter)->bw_cap & cap;
11079 inline bool hal_chk_proto_cap(_adapter *adapter, u8 cap)
11081 return GET_HAL_SPEC(adapter)->proto_cap & cap;
11084 inline bool hal_chk_wl_func(_adapter *adapter, u8 func)
11086 return GET_HAL_SPEC(adapter)->wl_func & func;
11089 inline bool hal_is_band_support(_adapter *adapter, u8 band)
11091 return GET_HAL_SPEC(adapter)->band_cap & band_to_band_cap(band);
11094 inline bool hal_is_bw_support(_adapter *adapter, u8 bw)
11096 return GET_HAL_SPEC(adapter)->bw_cap & ch_width_to_bw_cap(bw);
11099 inline bool hal_is_wireless_mode_support(_adapter *adapter, u8 mode)
11101 u8 proto_cap = GET_HAL_SPEC(adapter)->proto_cap;
11103 if (mode == WIRELESS_11B)
11104 if ((proto_cap & PROTO_CAP_11B) && hal_chk_band_cap(adapter, BAND_CAP_2G))
11107 if (mode == WIRELESS_11G)
11108 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_2G))
11111 if (mode == WIRELESS_11A)
11112 if ((proto_cap & PROTO_CAP_11G) && hal_chk_band_cap(adapter, BAND_CAP_5G))
11115 if (mode == WIRELESS_11_24N)
11116 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_2G))
11119 if (mode == WIRELESS_11_5N)
11120 if ((proto_cap & PROTO_CAP_11N) && hal_chk_band_cap(adapter, BAND_CAP_5G))
11123 if (mode == WIRELESS_11AC)
11124 if ((proto_cap & PROTO_CAP_11AC) && hal_chk_band_cap(adapter, BAND_CAP_5G))
11131 * hal_largest_bw - starting from in_bw, get largest bw supported by HAL
11133 * @in_bw: starting bw, value of CHANNEL_WIDTH
11135 * Returns: value of CHANNEL_WIDTH
11137 u8 hal_largest_bw(_adapter *adapter, u8 in_bw)
11139 for (; in_bw > CHANNEL_WIDTH_20; in_bw--) {
11140 if (hal_is_bw_support(adapter, in_bw))
11144 if (!hal_is_bw_support(adapter, in_bw))
11150 void rtw_hal_correct_tsf(_adapter *padapter, u8 hw_port, u64 tsf)
11152 if (hw_port == HW_PORT0) {
11153 /*disable related TSF function*/
11154 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) & (~EN_BCN_FUNCTION));
11156 rtw_write32(padapter, REG_TSFTR, tsf);
11157 rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32);
11159 /*enable related TSF function*/
11160 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | EN_BCN_FUNCTION);
11161 } else if (hw_port == HW_PORT1) {
11162 /*disable related TSF function*/
11163 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) & (~EN_BCN_FUNCTION));
11165 rtw_write32(padapter, REG_TSFTR1, tsf);
11166 rtw_write32(padapter, REG_TSFTR1 + 4, tsf >> 32);
11168 /*enable related TSF function*/
11169 rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1) | EN_BCN_FUNCTION);
11171 RTW_INFO("%s-[WARN] "ADPT_FMT" invalid hw_port:%d\n", __func__, ADPT_ARG(padapter), hw_port);
11174 void ResumeTxBeacon(_adapter *padapter)
11176 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
11179 /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
11180 /* which should be read from register to a global variable. */
11183 pHalData->RegFwHwTxQCtrl |= BIT(6);
11184 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl);
11185 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0xff);
11186 pHalData->RegReg542 |= BIT(0);
11187 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
11190 void StopTxBeacon(_adapter *padapter)
11192 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
11195 /* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
11196 /* which should be read from register to a global variable. */
11199 pHalData->RegFwHwTxQCtrl &= ~BIT(6);
11200 rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl);
11201 rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0x64);
11202 pHalData->RegReg542 &= ~BIT(0);
11203 rtw_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
11205 /*CheckFwRsvdPageContent(padapter);*/ /* 2010.06.23. Added by tynli. */
11208 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*HW port0 - MBSS*/
11209 void hw_var_set_opmode_mbid(_adapter *Adapter, u8 mode)
11211 RTW_INFO("%s()-"ADPT_FMT" mode = %d\n", __func__, ADPT_ARG(Adapter), mode);
11213 rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) & (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)));
11215 /* disable Port0 TSF update*/
11216 rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | DIS_TSF_UDT);
11219 Set_MSR(Adapter, mode);
11221 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
11222 if (!rtw_mi_check_status(Adapter, MI_AP_MODE))
11223 StopTxBeacon(Adapter);
11225 rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM);/*disable atim wnd*/
11226 } else if (mode == _HW_STATE_ADHOC_) {
11227 ResumeTxBeacon(Adapter);
11228 rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
11230 } else if (mode == _HW_STATE_AP_) {
11231 ResumeTxBeacon(Adapter);
11233 rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
11235 /*enable to rx data frame*/
11236 rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
11238 /*Beacon Control related register for first time*/
11239 rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */
11241 /*rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF);*/
11242 rtw_write8(Adapter, REG_ATIMWND, 0x0a); /* 10ms */
11243 rtw_write16(Adapter, REG_BCNTCFG, 0x00);
11244 rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04);
11245 rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
11248 rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
11250 /*enable BCN0 Function for if1*/
11251 /*don't enable update TSF0 for if1 (due to TSF update when beacon,probe rsp are received)*/
11252 rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
11254 if (IS_HARDWARE_TYPE_8821(Adapter) || IS_HARDWARE_TYPE_8192E(Adapter))/* select BCN on port 0 for DualBeacon*/
11255 rtw_write8(Adapter, REG_CCK_CHECK, rtw_read8(Adapter, REG_CCK_CHECK) & (~BIT_BCN_PORT_SEL));
11262 #ifdef CONFIG_ANTENNA_DIVERSITY
11263 u8 rtw_hal_antdiv_before_linked(_adapter *padapter)
11265 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11266 u8 cur_ant, change_ant;
11268 if (!pHalData->AntDivCfg)
11271 if (pHalData->sw_antdiv_bl_state == 0) {
11272 pHalData->sw_antdiv_bl_state = 1;
11274 rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &cur_ant, NULL);
11275 change_ant = (cur_ant == MAIN_ANT) ? AUX_ANT : MAIN_ANT;
11277 return rtw_antenna_select_cmd(padapter, change_ant, _FALSE);
11280 pHalData->sw_antdiv_bl_state = 0;
11284 void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src)
11286 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
11288 if (pHalData->AntDivCfg) {
11289 /*RTW_INFO("update_network=> org-RSSI(%d), new-RSSI(%d)\n", dst->Rssi, src->Rssi);*/
11290 /*select optimum_antenna for before linked =>For antenna diversity*/
11291 if (dst->Rssi >= src->Rssi) {/*keep org parameter*/
11292 src->Rssi = dst->Rssi;
11293 src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
11299 #ifdef CONFIG_PHY_CAPABILITY_QUERY
11300 void rtw_dump_phy_cap_by_phydmapi(void *sel, _adapter *adapter)
11302 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
11303 struct phy_spec_t *phy_spec = &pHalData->phy_spec;
11305 RTW_PRINT_SEL(sel, "[PHY SPEC] TRx Capability : 0x%08x\n", phy_spec->trx_cap);
11306 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Stream Num Index : %d\n", (phy_spec->trx_cap >> 24) & 0xFF); /*Tx Stream Num Index [31:24]*/
11307 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Stream Num Index : %d\n", (phy_spec->trx_cap >> 16) & 0xFF); /*Rx Stream Num Index [23:16]*/
11308 RTW_PRINT_SEL(sel, "[PHY SPEC] Tx Path Num Index : %d\n", (phy_spec->trx_cap >> 8) & 0xFF);/*Tx Path Num Index [15:8]*/
11309 RTW_PRINT_SEL(sel, "[PHY SPEC] Rx Path Num Index : %d\n\n", (phy_spec->trx_cap & 0xFF));/*Rx Path Num Index [7:0]*/
11311 RTW_PRINT_SEL(sel, "[PHY SPEC] STBC Capability : 0x%08x\n", phy_spec->stbc_cap);
11312 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]*/
11313 /*VHT STBC Rx [23:16]
11315 1 = support for 1 spatial stream
11316 2 = support for 1 or 2 spatial streams
11317 3 = support for 1 or 2 or 3 spatial streams
11318 4 = support for 1 or 2 or 3 or 4 spatial streams*/
11319 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT STBC Rx :%d\n", ((phy_spec->stbc_cap >> 16) & 0xFF));
11320 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]*/
11323 1 = support for 1 spatial stream
11324 2 = support for 1 or 2 spatial streams
11325 3 = support for 1 or 2 or 3 spatial streams*/
11326 RTW_PRINT_SEL(sel, "[PHY SPEC] HT STBC Rx : %d\n\n", (phy_spec->stbc_cap & 0xFF));
11328 RTW_PRINT_SEL(sel, "[PHY SPEC] LDPC Capability : 0x%08x\n", phy_spec->ldpc_cap);
11329 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]*/
11330 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]*/
11331 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]*/
11332 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]*/
11333 #ifdef CONFIG_BEAMFORMING
11334 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF Capability : 0x%08x\n", phy_spec->txbf_cap);
11335 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]*/
11336 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]*/
11337 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]*/
11338 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]*/
11339 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfer : %s\n", ((phy_spec->txbf_cap >> 4) & 0xF) ? "Supported" : "N/A"); /*HT Bfer [7:4]*/
11340 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Bfee : %s\n\n", (phy_spec->txbf_cap & 0xF) ? "Supported" : "N/A"); /*HT Bfee [3:0]*/
11342 RTW_PRINT_SEL(sel, "[PHY SPEC] TxBF parameter : 0x%08x\n", phy_spec->txbf_param);
11343 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Sounding Dim : %d\n", (phy_spec->txbf_param >> 24) & 0xFF); /*VHT Sounding Dim [31:24]*/
11344 RTW_PRINT_SEL(sel, "[PHY SPEC] VHT Steering Ant : %d\n", (phy_spec->txbf_param >> 16) & 0xFF); /*VHT Steering Ant [23:16]*/
11345 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Sounding Dim : %d\n", (phy_spec->txbf_param >> 8) & 0xFF); /*HT Sounding Dim [15:8]*/
11346 RTW_PRINT_SEL(sel, "[PHY SPEC] HT Steering Ant : %d\n", phy_spec->txbf_param & 0xFF); /*HT Steering Ant [7:0]*/
11350 void rtw_dump_phy_cap_by_hal(void *sel, _adapter *adapter)
11352 u8 phy_cap = _FALSE;
11355 rtw_hal_get_def_var(adapter, HAL_DEF_TX_STBC, (u8 *)&phy_cap);
11356 RTW_PRINT_SEL(sel, "[HAL] STBC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
11359 rtw_hal_get_def_var(adapter, HAL_DEF_RX_STBC, (u8 *)&phy_cap);
11360 RTW_PRINT_SEL(sel, "[HAL] STBC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
11364 rtw_hal_get_def_var(adapter, HAL_DEF_TX_LDPC, (u8 *)&phy_cap);
11365 RTW_PRINT_SEL(sel, "[HAL] LDPC Tx : %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
11368 rtw_hal_get_def_var(adapter, HAL_DEF_RX_LDPC, (u8 *)&phy_cap);
11369 RTW_PRINT_SEL(sel, "[HAL] LDPC Rx : %s\n\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
11371 #ifdef CONFIG_BEAMFORMING
11373 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&phy_cap);
11374 RTW_PRINT_SEL(sel, "[HAL] Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
11377 rtw_hal_get_def_var(adapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&phy_cap);
11378 RTW_PRINT_SEL(sel, "[HAL] Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
11381 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMER, &phy_cap);
11382 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformer: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
11385 rtw_hal_get_def_var(adapter, HAL_DEF_VHT_MU_BEAMFORMEE, &phy_cap);
11386 RTW_PRINT_SEL(sel, "[HAL] VHT MU Beamformee: %s\n", (_TRUE == phy_cap) ? "Supported" : "N/A");
11390 void rtw_dump_phy_cap(void *sel, _adapter *adapter)
11392 RTW_PRINT_SEL(sel, "\n ======== PHY Capability ========\n");
11393 #ifdef CONFIG_PHY_CAPABILITY_QUERY
11394 rtw_dump_phy_cap_by_phydmapi(sel, adapter);
11396 rtw_dump_phy_cap_by_hal(sel, adapter);