diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2014-03-28 22:37:39 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-04-05 17:51:23 -0400 |
commit | f7c92d2cc2beb3367f244480300eaecdd9502932 (patch) | |
tree | a1bcf064ad3699f760a5b1e26adb2e18050d7807 | |
parent | 5e93f35209578fcabfa855e427354195e54b491f (diff) |
staging: r8723au: Add source files for new driver - part 2
The Realtek USB device RTL8723AU is found in Lenovo Yoga 13 tablets.
A driver for it has been available in a GitHub repo for several months.
This commit contains the second part of the source files. The source
is arbitrarily split to avoid E-mail files that are too large.
Jes Sorensen at RedHat has made many improvements to the vendor code,
and he has been doing the testing. I do not have access to this device.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28 files changed, 28277 insertions, 0 deletions
diff --git a/drivers/staging/rtl8723au/hal/Hal8723PwrSeq.c b/drivers/staging/rtl8723au/hal/Hal8723PwrSeq.c new file mode 100644 index 000000000000..747f86cddeb9 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/Hal8723PwrSeq.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | #include "Hal8723PwrSeq.h" | ||
17 | |||
18 | /* | ||
19 | drivers should parse below arrays and do the corresponding actions | ||
20 | */ | ||
21 | /* 3 Power on Array */ | ||
22 | struct wlan_pwr_cfg rtl8723AU_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STEPS+RTL8723A_TRANS_END_STEPS] = { | ||
23 | RTL8723A_TRANS_CARDEMU_TO_ACT | ||
24 | RTL8723A_TRANS_END | ||
25 | }; | ||
26 | |||
27 | /* 3 Radio off GPIO Array */ | ||
28 | struct wlan_pwr_cfg rtl8723AU_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_END_STEPS] = { | ||
29 | RTL8723A_TRANS_ACT_TO_CARDEMU | ||
30 | RTL8723A_TRANS_END | ||
31 | }; | ||
32 | |||
33 | /* 3 Card Disable Array */ | ||
34 | struct wlan_pwr_cfg rtl8723AU_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723A_TRANS_END_STEPS] = { | ||
35 | RTL8723A_TRANS_ACT_TO_CARDEMU | ||
36 | RTL8723A_TRANS_CARDEMU_TO_CARDDIS | ||
37 | RTL8723A_TRANS_END | ||
38 | }; | ||
39 | |||
40 | /* 3 Card Enable Array */ | ||
41 | struct wlan_pwr_cfg rtl8723AU_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723A_TRANS_END_STEPS] = { | ||
42 | RTL8723A_TRANS_CARDDIS_TO_CARDEMU | ||
43 | RTL8723A_TRANS_CARDEMU_TO_ACT | ||
44 | RTL8723A_TRANS_END | ||
45 | }; | ||
46 | |||
47 | /* 3 Suspend Array */ | ||
48 | struct wlan_pwr_cfg rtl8723AU_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8723A_TRANS_END_STEPS] = { | ||
49 | RTL8723A_TRANS_ACT_TO_CARDEMU | ||
50 | RTL8723A_TRANS_CARDEMU_TO_SUS | ||
51 | RTL8723A_TRANS_END | ||
52 | }; | ||
53 | |||
54 | /* 3 Resume Array */ | ||
55 | struct wlan_pwr_cfg rtl8723AU_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8723A_TRANS_END_STEPS] = { | ||
56 | RTL8723A_TRANS_SUS_TO_CARDEMU | ||
57 | RTL8723A_TRANS_CARDEMU_TO_ACT | ||
58 | RTL8723A_TRANS_END | ||
59 | }; | ||
60 | |||
61 | /* 3 HWPDN Array */ | ||
62 | struct wlan_pwr_cfg rtl8723AU_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8723A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8723A_TRANS_END_STEPS] = { | ||
63 | RTL8723A_TRANS_ACT_TO_CARDEMU | ||
64 | RTL8723A_TRANS_CARDEMU_TO_PDN | ||
65 | RTL8723A_TRANS_END | ||
66 | }; | ||
67 | |||
68 | /* 3 Enter LPS */ | ||
69 | struct wlan_pwr_cfg rtl8723AU_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STEPS+RTL8723A_TRANS_END_STEPS] = { | ||
70 | /* FW behavior */ | ||
71 | RTL8723A_TRANS_ACT_TO_LPS | ||
72 | RTL8723A_TRANS_END | ||
73 | }; | ||
74 | |||
75 | /* 3 Leave LPS */ | ||
76 | struct wlan_pwr_cfg rtl8723AU_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STEPS+RTL8723A_TRANS_END_STEPS] = { | ||
77 | /* FW behavior */ | ||
78 | RTL8723A_TRANS_LPS_TO_ACT | ||
79 | RTL8723A_TRANS_END | ||
80 | }; | ||
diff --git a/drivers/staging/rtl8723au/hal/Hal8723UHWImg_CE.c b/drivers/staging/rtl8723au/hal/Hal8723UHWImg_CE.c new file mode 100644 index 000000000000..56833da63ced --- /dev/null +++ b/drivers/staging/rtl8723au/hal/Hal8723UHWImg_CE.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | /*Created on 2013/01/14, 15:51*/ | ||
17 | #include "odm_precomp.h" | ||
18 | |||
19 | u32 Rtl8723UPHY_REG_Array_PG[Rtl8723UPHY_REG_Array_PGLength] = { | ||
20 | 0xe00, 0xffffffff, 0x0a0c0c0c, | ||
21 | 0xe04, 0xffffffff, 0x02040608, | ||
22 | 0xe08, 0x0000ff00, 0x00000000, | ||
23 | 0x86c, 0xffffff00, 0x00000000, | ||
24 | 0xe10, 0xffffffff, 0x0a0c0d0e, | ||
25 | 0xe14, 0xffffffff, 0x02040608, | ||
26 | 0xe18, 0xffffffff, 0x0a0c0d0e, | ||
27 | 0xe1c, 0xffffffff, 0x02040608, | ||
28 | 0x830, 0xffffffff, 0x0a0c0c0c, | ||
29 | 0x834, 0xffffffff, 0x02040608, | ||
30 | 0x838, 0xffffff00, 0x00000000, | ||
31 | 0x86c, 0x000000ff, 0x00000000, | ||
32 | 0x83c, 0xffffffff, 0x0a0c0d0e, | ||
33 | 0x848, 0xffffffff, 0x02040608, | ||
34 | 0x84c, 0xffffffff, 0x0a0c0d0e, | ||
35 | 0x868, 0xffffffff, 0x02040608, | ||
36 | 0xe00, 0xffffffff, 0x00000000, | ||
37 | 0xe04, 0xffffffff, 0x00000000, | ||
38 | 0xe08, 0x0000ff00, 0x00000000, | ||
39 | 0x86c, 0xffffff00, 0x00000000, | ||
40 | 0xe10, 0xffffffff, 0x00000000, | ||
41 | 0xe14, 0xffffffff, 0x00000000, | ||
42 | 0xe18, 0xffffffff, 0x00000000, | ||
43 | 0xe1c, 0xffffffff, 0x00000000, | ||
44 | 0x830, 0xffffffff, 0x00000000, | ||
45 | 0x834, 0xffffffff, 0x00000000, | ||
46 | 0x838, 0xffffff00, 0x00000000, | ||
47 | 0x86c, 0x000000ff, 0x00000000, | ||
48 | 0x83c, 0xffffffff, 0x00000000, | ||
49 | 0x848, 0xffffffff, 0x00000000, | ||
50 | 0x84c, 0xffffffff, 0x00000000, | ||
51 | 0x868, 0xffffffff, 0x00000000, | ||
52 | 0xe00, 0xffffffff, 0x04040404, | ||
53 | 0xe04, 0xffffffff, 0x00020204, | ||
54 | 0xe08, 0x0000ff00, 0x00000000, | ||
55 | 0x86c, 0xffffff00, 0x00000000, | ||
56 | 0xe10, 0xffffffff, 0x06060606, | ||
57 | 0xe14, 0xffffffff, 0x00020406, | ||
58 | 0xe18, 0xffffffff, 0x00000000, | ||
59 | 0xe1c, 0xffffffff, 0x00000000, | ||
60 | 0x830, 0xffffffff, 0x04040404, | ||
61 | 0x834, 0xffffffff, 0x00020204, | ||
62 | 0x838, 0xffffff00, 0x00000000, | ||
63 | 0x86c, 0x000000ff, 0x00000000, | ||
64 | 0x83c, 0xffffffff, 0x06060606, | ||
65 | 0x848, 0xffffffff, 0x00020406, | ||
66 | 0x84c, 0xffffffff, 0x00000000, | ||
67 | 0x868, 0xffffffff, 0x00000000, | ||
68 | 0xe00, 0xffffffff, 0x00000000, | ||
69 | 0xe04, 0xffffffff, 0x00000000, | ||
70 | 0xe08, 0x0000ff00, 0x00000000, | ||
71 | 0x86c, 0xffffff00, 0x00000000, | ||
72 | 0xe10, 0xffffffff, 0x00000000, | ||
73 | 0xe14, 0xffffffff, 0x00000000, | ||
74 | 0xe18, 0xffffffff, 0x00000000, | ||
75 | 0xe1c, 0xffffffff, 0x00000000, | ||
76 | 0x830, 0xffffffff, 0x00000000, | ||
77 | 0x834, 0xffffffff, 0x00000000, | ||
78 | 0x838, 0xffffff00, 0x00000000, | ||
79 | 0x86c, 0x000000ff, 0x00000000, | ||
80 | 0x83c, 0xffffffff, 0x00000000, | ||
81 | 0x848, 0xffffffff, 0x00000000, | ||
82 | 0x84c, 0xffffffff, 0x00000000, | ||
83 | 0x868, 0xffffffff, 0x00000000, | ||
84 | 0xe00, 0xffffffff, 0x00000000, | ||
85 | 0xe04, 0xffffffff, 0x00000000, | ||
86 | 0xe08, 0x0000ff00, 0x00000000, | ||
87 | 0x86c, 0xffffff00, 0x00000000, | ||
88 | 0xe10, 0xffffffff, 0x00000000, | ||
89 | 0xe14, 0xffffffff, 0x00000000, | ||
90 | 0xe18, 0xffffffff, 0x00000000, | ||
91 | 0xe1c, 0xffffffff, 0x00000000, | ||
92 | 0x830, 0xffffffff, 0x00000000, | ||
93 | 0x834, 0xffffffff, 0x00000000, | ||
94 | 0x838, 0xffffff00, 0x00000000, | ||
95 | 0x86c, 0x000000ff, 0x00000000, | ||
96 | 0x83c, 0xffffffff, 0x00000000, | ||
97 | 0x848, 0xffffffff, 0x00000000, | ||
98 | 0x84c, 0xffffffff, 0x00000000, | ||
99 | 0x868, 0xffffffff, 0x00000000, | ||
100 | 0xe00, 0xffffffff, 0x04040404, | ||
101 | 0xe04, 0xffffffff, 0x00020204, | ||
102 | 0xe08, 0x0000ff00, 0x00000000, | ||
103 | 0x86c, 0xffffff00, 0x00000000, | ||
104 | 0xe10, 0xffffffff, 0x00000000, | ||
105 | 0xe14, 0xffffffff, 0x00000000, | ||
106 | 0xe18, 0xffffffff, 0x00000000, | ||
107 | 0xe1c, 0xffffffff, 0x00000000, | ||
108 | 0x830, 0xffffffff, 0x04040404, | ||
109 | 0x834, 0xffffffff, 0x00020204, | ||
110 | 0x838, 0xffffff00, 0x00000000, | ||
111 | 0x86c, 0x000000ff, 0x00000000, | ||
112 | 0x83c, 0xffffffff, 0x00000000, | ||
113 | 0x848, 0xffffffff, 0x00000000, | ||
114 | 0x84c, 0xffffffff, 0x00000000, | ||
115 | 0x868, 0xffffffff, 0x00000000, | ||
116 | 0xe00, 0xffffffff, 0x00000000, | ||
117 | 0xe04, 0xffffffff, 0x00000000, | ||
118 | 0xe08, 0x0000ff00, 0x00000000, | ||
119 | 0x86c, 0xffffff00, 0x00000000, | ||
120 | 0xe10, 0xffffffff, 0x00000000, | ||
121 | 0xe14, 0xffffffff, 0x00000000, | ||
122 | 0xe18, 0xffffffff, 0x00000000, | ||
123 | 0xe1c, 0xffffffff, 0x00000000, | ||
124 | 0x830, 0xffffffff, 0x00000000, | ||
125 | 0x834, 0xffffffff, 0x00000000, | ||
126 | 0x838, 0xffffff00, 0x00000000, | ||
127 | 0x86c, 0x000000ff, 0x00000000, | ||
128 | 0x83c, 0xffffffff, 0x00000000, | ||
129 | 0x848, 0xffffffff, 0x00000000, | ||
130 | 0x84c, 0xffffffff, 0x00000000, | ||
131 | 0x868, 0xffffffff, 0x00000000, | ||
132 | }; | ||
133 | |||
134 | u32 Rtl8723UMACPHY_Array_PG[Rtl8723UMACPHY_Array_PGLength] = { | ||
135 | 0x0, | ||
136 | }; | ||
diff --git a/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c new file mode 100644 index 000000000000..9796f2e5c68f --- /dev/null +++ b/drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c | |||
@@ -0,0 +1,1063 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | /* Description: */ | ||
16 | /* This file is for 92CE/92CU dynamic mechanism only */ | ||
17 | |||
18 | /* include files */ | ||
19 | |||
20 | #include "odm_precomp.h" | ||
21 | |||
22 | #define DPK_DELTA_MAPPING_NUM 13 | ||
23 | #define index_mapping_HP_NUM 15 | ||
24 | /* 091212 chiyokolin */ | ||
25 | static void | ||
26 | odm_TXPowerTrackingCallback_ThermalMeter_92C( | ||
27 | struct rtw_adapter *Adapter) | ||
28 | { | ||
29 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
30 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
31 | u8 ThermalValue = 0, delta, delta_LCK, delta_IQK, delta_HP; | ||
32 | int ele_A, ele_D, TempCCk, X, value32; | ||
33 | int Y, ele_C; | ||
34 | s8 OFDM_index[2], CCK_index = 0, OFDM_index_old[2] = {0}; | ||
35 | s8 CCK_index_old = 0; | ||
36 | int i = 0; | ||
37 | bool is2T = IS_92C_SERIAL(pHalData->VersionID); | ||
38 | u8 OFDM_min_index = 6, rf; /* OFDM BB Swing should be less than +3.0dB*/ | ||
39 | u8 ThermalValue_HP_count = 0; | ||
40 | u32 ThermalValue_HP = 0; | ||
41 | s32 index_mapping_HP[index_mapping_HP_NUM] = { | ||
42 | 0, 1, 3, 4, 6, | ||
43 | 7, 9, 10, 12, 13, | ||
44 | 15, 16, 18, 19, 21 | ||
45 | }; | ||
46 | s8 index_HP; | ||
47 | |||
48 | pdmpriv->TXPowerTrackingCallbackCnt++; /* cosa add for debug */ | ||
49 | pdmpriv->bTXPowerTrackingInit = true; | ||
50 | |||
51 | if (pHalData->CurrentChannel == 14 && !pdmpriv->bCCKinCH14) | ||
52 | pdmpriv->bCCKinCH14 = true; | ||
53 | else if (pHalData->CurrentChannel != 14 && pdmpriv->bCCKinCH14) | ||
54 | pdmpriv->bCCKinCH14 = false; | ||
55 | |||
56 | ThermalValue = (u8)PHY_QueryRFReg(Adapter, RF_PATH_A, RF_T_METER, | ||
57 | 0x1f);/* 0x24: RF Reg[4:0] */ | ||
58 | |||
59 | rtl8723a_phy_ap_calibrate(Adapter, (ThermalValue - | ||
60 | pHalData->EEPROMThermalMeter)); | ||
61 | |||
62 | if (is2T) | ||
63 | rf = 2; | ||
64 | else | ||
65 | rf = 1; | ||
66 | |||
67 | if (ThermalValue) { | ||
68 | /* Query OFDM path A default setting */ | ||
69 | ele_D = PHY_QueryBBReg(Adapter, rOFDM0_XATxIQImbalance, | ||
70 | bMaskDWord)&bMaskOFDM_D; | ||
71 | for (i = 0; i < OFDM_TABLE_SIZE_92C; i++) { | ||
72 | /* find the index */ | ||
73 | if (ele_D == (OFDMSwingTable23A[i]&bMaskOFDM_D)) { | ||
74 | OFDM_index_old[0] = (u8)i; | ||
75 | break; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | /* Query OFDM path B default setting */ | ||
80 | if (is2T) { | ||
81 | ele_D = PHY_QueryBBReg(Adapter, rOFDM0_XBTxIQImbalance, | ||
82 | bMaskDWord)&bMaskOFDM_D; | ||
83 | for (i = 0; i < OFDM_TABLE_SIZE_92C; i++) { /* find the index */ | ||
84 | if (ele_D == (OFDMSwingTable23A[i]&bMaskOFDM_D)) { | ||
85 | OFDM_index_old[1] = (u8)i; | ||
86 | break; | ||
87 | } | ||
88 | } | ||
89 | } | ||
90 | |||
91 | /* Query CCK default setting From 0xa24 */ | ||
92 | TempCCk = PHY_QueryBBReg(Adapter, rCCK0_TxFilter2, | ||
93 | bMaskDWord)&bMaskCCK; | ||
94 | for (i = 0 ; i < CCK_TABLE_SIZE ; i++) { | ||
95 | if (pdmpriv->bCCKinCH14) { | ||
96 | if (!memcmp(&TempCCk, | ||
97 | &CCKSwingTable_Ch1423A[i][2], 4)) { | ||
98 | CCK_index_old = (u8)i; | ||
99 | break; | ||
100 | } | ||
101 | } else { | ||
102 | if (!memcmp(&TempCCk, | ||
103 | &CCKSwingTable_Ch1_Ch1323A[i][2], 4)) { | ||
104 | CCK_index_old = (u8)i; | ||
105 | break; | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | |||
110 | if (!pdmpriv->ThermalValue) { | ||
111 | pdmpriv->ThermalValue = pHalData->EEPROMThermalMeter; | ||
112 | pdmpriv->ThermalValue_LCK = ThermalValue; | ||
113 | pdmpriv->ThermalValue_IQK = ThermalValue; | ||
114 | pdmpriv->ThermalValue_DPK = pHalData->EEPROMThermalMeter; | ||
115 | |||
116 | for (i = 0; i < rf; i++) { | ||
117 | pdmpriv->OFDM_index_HP[i] = OFDM_index_old[i]; | ||
118 | pdmpriv->OFDM_index[i] = OFDM_index_old[i]; | ||
119 | } | ||
120 | pdmpriv->CCK_index_HP = CCK_index_old; | ||
121 | pdmpriv->CCK_index = CCK_index_old; | ||
122 | } | ||
123 | |||
124 | if (pHalData->BoardType == BOARD_USB_High_PA) { | ||
125 | pdmpriv->ThermalValue_HP[pdmpriv->ThermalValue_HP_index] = ThermalValue; | ||
126 | pdmpriv->ThermalValue_HP_index++; | ||
127 | if (pdmpriv->ThermalValue_HP_index == HP_THERMAL_NUM) | ||
128 | pdmpriv->ThermalValue_HP_index = 0; | ||
129 | |||
130 | for (i = 0; i < HP_THERMAL_NUM; i++) { | ||
131 | if (pdmpriv->ThermalValue_HP[i]) { | ||
132 | ThermalValue_HP += pdmpriv->ThermalValue_HP[i]; | ||
133 | ThermalValue_HP_count++; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | if (ThermalValue_HP_count) | ||
138 | ThermalValue = (u8)(ThermalValue_HP / ThermalValue_HP_count); | ||
139 | } | ||
140 | |||
141 | delta = (ThermalValue > pdmpriv->ThermalValue) ? | ||
142 | (ThermalValue - pdmpriv->ThermalValue) : | ||
143 | (pdmpriv->ThermalValue - ThermalValue); | ||
144 | if (pHalData->BoardType == BOARD_USB_High_PA) { | ||
145 | if (pdmpriv->bDoneTxpower) | ||
146 | delta_HP = (ThermalValue > pdmpriv->ThermalValue) ? | ||
147 | (ThermalValue - pdmpriv->ThermalValue) : | ||
148 | (pdmpriv->ThermalValue - ThermalValue); | ||
149 | else | ||
150 | delta_HP = ThermalValue > pHalData->EEPROMThermalMeter ? | ||
151 | (ThermalValue - pHalData->EEPROMThermalMeter) : | ||
152 | (pHalData->EEPROMThermalMeter - ThermalValue); | ||
153 | } else { | ||
154 | delta_HP = 0; | ||
155 | } | ||
156 | delta_LCK = (ThermalValue > pdmpriv->ThermalValue_LCK) ? | ||
157 | (ThermalValue - pdmpriv->ThermalValue_LCK) : | ||
158 | (pdmpriv->ThermalValue_LCK - ThermalValue); | ||
159 | delta_IQK = (ThermalValue > pdmpriv->ThermalValue_IQK) ? | ||
160 | (ThermalValue - pdmpriv->ThermalValue_IQK) : | ||
161 | (pdmpriv->ThermalValue_IQK - ThermalValue); | ||
162 | |||
163 | if (delta_LCK > 1) { | ||
164 | pdmpriv->ThermalValue_LCK = ThermalValue; | ||
165 | rtl8723a_phy_lc_calibrate(Adapter); | ||
166 | } | ||
167 | |||
168 | if ((delta > 0 || delta_HP > 0) && pdmpriv->TxPowerTrackControl) { | ||
169 | if (pHalData->BoardType == BOARD_USB_High_PA) { | ||
170 | pdmpriv->bDoneTxpower = true; | ||
171 | delta_HP = ThermalValue > pHalData->EEPROMThermalMeter ? | ||
172 | (ThermalValue - pHalData->EEPROMThermalMeter) : | ||
173 | (pHalData->EEPROMThermalMeter - ThermalValue); | ||
174 | |||
175 | if (delta_HP > index_mapping_HP_NUM-1) | ||
176 | index_HP = index_mapping_HP[index_mapping_HP_NUM-1]; | ||
177 | else | ||
178 | index_HP = index_mapping_HP[delta_HP]; | ||
179 | |||
180 | if (ThermalValue > pHalData->EEPROMThermalMeter) { | ||
181 | /* set larger Tx power */ | ||
182 | for (i = 0; i < rf; i++) | ||
183 | OFDM_index[i] = pdmpriv->OFDM_index_HP[i] - index_HP; | ||
184 | CCK_index = pdmpriv->CCK_index_HP - index_HP; | ||
185 | } else { | ||
186 | for (i = 0; i < rf; i++) | ||
187 | OFDM_index[i] = pdmpriv->OFDM_index_HP[i] + index_HP; | ||
188 | CCK_index = pdmpriv->CCK_index_HP + index_HP; | ||
189 | } | ||
190 | |||
191 | delta_HP = (ThermalValue > pdmpriv->ThermalValue) ? | ||
192 | (ThermalValue - pdmpriv->ThermalValue) : | ||
193 | (pdmpriv->ThermalValue - ThermalValue); | ||
194 | } else { | ||
195 | if (ThermalValue > pdmpriv->ThermalValue) { | ||
196 | for (i = 0; i < rf; i++) | ||
197 | pdmpriv->OFDM_index[i] -= delta; | ||
198 | pdmpriv->CCK_index -= delta; | ||
199 | } else { | ||
200 | for (i = 0; i < rf; i++) | ||
201 | pdmpriv->OFDM_index[i] += delta; | ||
202 | pdmpriv->CCK_index += delta; | ||
203 | } | ||
204 | } | ||
205 | |||
206 | /* no adjust */ | ||
207 | if (pHalData->BoardType != BOARD_USB_High_PA) { | ||
208 | if (ThermalValue > pHalData->EEPROMThermalMeter) { | ||
209 | for (i = 0; i < rf; i++) | ||
210 | OFDM_index[i] = pdmpriv->OFDM_index[i]+1; | ||
211 | CCK_index = pdmpriv->CCK_index+1; | ||
212 | } else { | ||
213 | for (i = 0; i < rf; i++) | ||
214 | OFDM_index[i] = pdmpriv->OFDM_index[i]; | ||
215 | CCK_index = pdmpriv->CCK_index; | ||
216 | } | ||
217 | } | ||
218 | for (i = 0; i < rf; i++) { | ||
219 | if (OFDM_index[i] > (OFDM_TABLE_SIZE_92C-1)) | ||
220 | OFDM_index[i] = (OFDM_TABLE_SIZE_92C-1); | ||
221 | else if (OFDM_index[i] < OFDM_min_index) | ||
222 | OFDM_index[i] = OFDM_min_index; | ||
223 | } | ||
224 | |||
225 | if (CCK_index > (CCK_TABLE_SIZE-1)) | ||
226 | CCK_index = (CCK_TABLE_SIZE-1); | ||
227 | else if (CCK_index < 0) | ||
228 | CCK_index = 0; | ||
229 | } | ||
230 | |||
231 | if (pdmpriv->TxPowerTrackControl && (delta != 0 || delta_HP != 0)) { | ||
232 | /* Adujst OFDM Ant_A according to IQK result */ | ||
233 | ele_D = (OFDMSwingTable23A[OFDM_index[0]] & 0xFFC00000)>>22; | ||
234 | X = pdmpriv->RegE94; | ||
235 | Y = pdmpriv->RegE9C; | ||
236 | |||
237 | if (X != 0) { | ||
238 | if ((X & 0x00000200) != 0) | ||
239 | X = X | 0xFFFFFC00; | ||
240 | ele_A = ((X * ele_D)>>8)&0x000003FF; | ||
241 | |||
242 | /* new element C = element D x Y */ | ||
243 | if ((Y & 0x00000200) != 0) | ||
244 | Y = Y | 0xFFFFFC00; | ||
245 | ele_C = ((Y * ele_D)>>8)&0x000003FF; | ||
246 | |||
247 | /* write new elements A, C, D to regC80 and regC94, element B is always 0 */ | ||
248 | value32 = (ele_D<<22)|((ele_C&0x3F)<<16)|ele_A; | ||
249 | PHY_SetBBReg(Adapter, rOFDM0_XATxIQImbalance, bMaskDWord, value32); | ||
250 | |||
251 | value32 = (ele_C&0x000003C0)>>6; | ||
252 | PHY_SetBBReg(Adapter, rOFDM0_XCTxAFE, bMaskH4Bits, value32); | ||
253 | |||
254 | value32 = ((X * ele_D)>>7)&0x01; | ||
255 | PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT31, value32); | ||
256 | |||
257 | value32 = ((Y * ele_D)>>7)&0x01; | ||
258 | PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT29, value32); | ||
259 | } else { | ||
260 | PHY_SetBBReg(Adapter, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable23A[OFDM_index[0]]); | ||
261 | PHY_SetBBReg(Adapter, rOFDM0_XCTxAFE, bMaskH4Bits, 0x00); | ||
262 | PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT31|BIT29, 0x00); | ||
263 | } | ||
264 | |||
265 | /* Adjust CCK according to IQK result */ | ||
266 | if (!pdmpriv->bCCKinCH14) { | ||
267 | rtw_write8(Adapter, 0xa22, CCKSwingTable_Ch1_Ch1323A[CCK_index][0]); | ||
268 | rtw_write8(Adapter, 0xa23, CCKSwingTable_Ch1_Ch1323A[CCK_index][1]); | ||
269 | rtw_write8(Adapter, 0xa24, CCKSwingTable_Ch1_Ch1323A[CCK_index][2]); | ||
270 | rtw_write8(Adapter, 0xa25, CCKSwingTable_Ch1_Ch1323A[CCK_index][3]); | ||
271 | rtw_write8(Adapter, 0xa26, CCKSwingTable_Ch1_Ch1323A[CCK_index][4]); | ||
272 | rtw_write8(Adapter, 0xa27, CCKSwingTable_Ch1_Ch1323A[CCK_index][5]); | ||
273 | rtw_write8(Adapter, 0xa28, CCKSwingTable_Ch1_Ch1323A[CCK_index][6]); | ||
274 | rtw_write8(Adapter, 0xa29, CCKSwingTable_Ch1_Ch1323A[CCK_index][7]); | ||
275 | } else { | ||
276 | rtw_write8(Adapter, 0xa22, CCKSwingTable_Ch1423A[CCK_index][0]); | ||
277 | rtw_write8(Adapter, 0xa23, CCKSwingTable_Ch1423A[CCK_index][1]); | ||
278 | rtw_write8(Adapter, 0xa24, CCKSwingTable_Ch1423A[CCK_index][2]); | ||
279 | rtw_write8(Adapter, 0xa25, CCKSwingTable_Ch1423A[CCK_index][3]); | ||
280 | rtw_write8(Adapter, 0xa26, CCKSwingTable_Ch1423A[CCK_index][4]); | ||
281 | rtw_write8(Adapter, 0xa27, CCKSwingTable_Ch1423A[CCK_index][5]); | ||
282 | rtw_write8(Adapter, 0xa28, CCKSwingTable_Ch1423A[CCK_index][6]); | ||
283 | rtw_write8(Adapter, 0xa29, CCKSwingTable_Ch1423A[CCK_index][7]); | ||
284 | } | ||
285 | |||
286 | if (is2T) { | ||
287 | ele_D = (OFDMSwingTable23A[(u8)OFDM_index[1]] & 0xFFC00000)>>22; | ||
288 | |||
289 | /* new element A = element D x X */ | ||
290 | X = pdmpriv->RegEB4; | ||
291 | Y = pdmpriv->RegEBC; | ||
292 | |||
293 | if (X != 0) { | ||
294 | if ((X & 0x00000200) != 0) /* consider minus */ | ||
295 | X = X | 0xFFFFFC00; | ||
296 | ele_A = ((X * ele_D)>>8)&0x000003FF; | ||
297 | |||
298 | /* new element C = element D x Y */ | ||
299 | if ((Y & 0x00000200) != 0) | ||
300 | Y = Y | 0xFFFFFC00; | ||
301 | ele_C = ((Y * ele_D)>>8)&0x00003FF; | ||
302 | |||
303 | /* write new elements A, C, D to regC88 and regC9C, element B is always 0 */ | ||
304 | value32 = (ele_D<<22)|((ele_C&0x3F)<<16) | ele_A; | ||
305 | PHY_SetBBReg(Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord, value32); | ||
306 | |||
307 | value32 = (ele_C&0x000003C0)>>6; | ||
308 | PHY_SetBBReg(Adapter, rOFDM0_XDTxAFE, bMaskH4Bits, value32); | ||
309 | |||
310 | value32 = ((X * ele_D)>>7)&0x01; | ||
311 | PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT27, value32); | ||
312 | |||
313 | value32 = ((Y * ele_D)>>7)&0x01; | ||
314 | PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT25, value32); | ||
315 | } else { | ||
316 | PHY_SetBBReg(Adapter, rOFDM0_XBTxIQImbalance, bMaskDWord, OFDMSwingTable23A[OFDM_index[1]]); | ||
317 | PHY_SetBBReg(Adapter, rOFDM0_XDTxAFE, bMaskH4Bits, 0x00); | ||
318 | PHY_SetBBReg(Adapter, rOFDM0_ECCAThreshold, BIT27|BIT25, 0x00); | ||
319 | } | ||
320 | } | ||
321 | |||
322 | } | ||
323 | if (delta_IQK > 3) { | ||
324 | pdmpriv->ThermalValue_IQK = ThermalValue; | ||
325 | rtl8723a_phy_iq_calibrate(Adapter, false); | ||
326 | } | ||
327 | |||
328 | /* update thermal meter value */ | ||
329 | if (pdmpriv->TxPowerTrackControl) | ||
330 | pdmpriv->ThermalValue = ThermalValue; | ||
331 | } | ||
332 | pdmpriv->TXPowercount = 0; | ||
333 | } | ||
334 | |||
335 | /* Description: */ | ||
336 | /* - Dispatch TxPower Tracking direct call ONLY for 92s. */ | ||
337 | /* - We shall NOT schedule Workitem within PASSIVE LEVEL, which will cause system resource */ | ||
338 | /* leakage under some platform. */ | ||
339 | /* Assumption: */ | ||
340 | /* PASSIVE_LEVEL when this routine is called. */ | ||
341 | static void ODM_TXPowerTracking92CDirectCall(struct rtw_adapter *Adapter) | ||
342 | { | ||
343 | odm_TXPowerTrackingCallback_ThermalMeter_92C(Adapter); | ||
344 | } | ||
345 | |||
346 | static void odm_CheckTXPowerTracking_ThermalMeter(struct rtw_adapter *Adapter) | ||
347 | { | ||
348 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
349 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
350 | struct dm_odm_t *podmpriv = &pHalData->odmpriv; | ||
351 | |||
352 | if (!(podmpriv->SupportAbility & ODM_RF_TX_PWR_TRACK)) | ||
353 | return; | ||
354 | |||
355 | if (!pdmpriv->TM_Trigger) { /* at least delay 1 sec */ | ||
356 | PHY_SetRFReg(Adapter, RF_PATH_A, RF_T_METER, bRFRegOffsetMask, 0x60); | ||
357 | |||
358 | pdmpriv->TM_Trigger = 1; | ||
359 | return; | ||
360 | } else { | ||
361 | ODM_TXPowerTracking92CDirectCall(Adapter); | ||
362 | pdmpriv->TM_Trigger = 0; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | void rtl8723a_odm_check_tx_power_tracking(struct rtw_adapter *Adapter) | ||
367 | { | ||
368 | odm_CheckTXPowerTracking_ThermalMeter(Adapter); | ||
369 | } | ||
370 | |||
371 | /* IQK */ | ||
372 | #define MAX_TOLERANCE 5 | ||
373 | #define IQK_DELAY_TIME 1 /* ms */ | ||
374 | |||
375 | static u8 _PHY_PathA_IQK(struct rtw_adapter *pAdapter, bool configPathB) | ||
376 | { | ||
377 | u32 regEAC, regE94, regE9C, regEA4; | ||
378 | u8 result = 0x00; | ||
379 | struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); | ||
380 | |||
381 | /* path-A IQK setting */ | ||
382 | PHY_SetBBReg(pAdapter, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1f); | ||
383 | PHY_SetBBReg(pAdapter, rRx_IQK_Tone_A, bMaskDWord, 0x10008c1f); | ||
384 | PHY_SetBBReg(pAdapter, rTx_IQK_PI_A, bMaskDWord, 0x82140102); | ||
385 | |||
386 | PHY_SetBBReg(pAdapter, rRx_IQK_PI_A, bMaskDWord, configPathB ? 0x28160202 : | ||
387 | IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)?0x28160202:0x28160502); | ||
388 | |||
389 | /* path-B IQK setting */ | ||
390 | if (configPathB) { | ||
391 | PHY_SetBBReg(pAdapter, rTx_IQK_Tone_B, bMaskDWord, 0x10008c22); | ||
392 | PHY_SetBBReg(pAdapter, rRx_IQK_Tone_B, bMaskDWord, 0x10008c22); | ||
393 | PHY_SetBBReg(pAdapter, rTx_IQK_PI_B, bMaskDWord, 0x82140102); | ||
394 | PHY_SetBBReg(pAdapter, rRx_IQK_PI_B, bMaskDWord, 0x28160202); | ||
395 | } | ||
396 | |||
397 | /* LO calibration setting */ | ||
398 | PHY_SetBBReg(pAdapter, rIQK_AGC_Rsp, bMaskDWord, 0x001028d1); | ||
399 | |||
400 | /* One shot, path A LOK & IQK */ | ||
401 | PHY_SetBBReg(pAdapter, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); | ||
402 | PHY_SetBBReg(pAdapter, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); | ||
403 | |||
404 | /* delay x ms */ | ||
405 | udelay(IQK_DELAY_TIME*1000);/* PlatformStallExecution(IQK_DELAY_TIME*1000); */ | ||
406 | |||
407 | /* Check failed */ | ||
408 | regEAC = PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_A_2, bMaskDWord); | ||
409 | regE94 = PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_A, bMaskDWord); | ||
410 | regE9C = PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_A, bMaskDWord); | ||
411 | regEA4 = PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_A_2, bMaskDWord); | ||
412 | |||
413 | if (!(regEAC & BIT28) && | ||
414 | (((regE94 & 0x03FF0000)>>16) != 0x142) && | ||
415 | (((regE9C & 0x03FF0000)>>16) != 0x42)) | ||
416 | result |= 0x01; | ||
417 | else /* if Tx not OK, ignore Rx */ | ||
418 | return result; | ||
419 | |||
420 | if (!(regEAC & BIT27) && /* if Tx is OK, check whether Rx is OK */ | ||
421 | (((regEA4 & 0x03FF0000)>>16) != 0x132) && | ||
422 | (((regEAC & 0x03FF0000)>>16) != 0x36)) | ||
423 | result |= 0x02; | ||
424 | else | ||
425 | DBG_8723A("Path A Rx IQK fail!!\n"); | ||
426 | return result; | ||
427 | } | ||
428 | |||
429 | static u8 _PHY_PathB_IQK(struct rtw_adapter *pAdapter) | ||
430 | { | ||
431 | u32 regEAC, regEB4, regEBC, regEC4, regECC; | ||
432 | u8 result = 0x00; | ||
433 | |||
434 | /* One shot, path B LOK & IQK */ | ||
435 | PHY_SetBBReg(pAdapter, rIQK_AGC_Cont, bMaskDWord, 0x00000002); | ||
436 | PHY_SetBBReg(pAdapter, rIQK_AGC_Cont, bMaskDWord, 0x00000000); | ||
437 | |||
438 | /* delay x ms */ | ||
439 | udelay(IQK_DELAY_TIME*1000); | ||
440 | |||
441 | /* Check failed */ | ||
442 | regEAC = PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_A_2, bMaskDWord); | ||
443 | regEB4 = PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_B, bMaskDWord); | ||
444 | regEBC = PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_B, bMaskDWord); | ||
445 | regEC4 = PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_B_2, bMaskDWord); | ||
446 | regECC = PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_B_2, bMaskDWord); | ||
447 | |||
448 | if (!(regEAC & BIT31) && | ||
449 | (((regEB4 & 0x03FF0000)>>16) != 0x142) && | ||
450 | (((regEBC & 0x03FF0000)>>16) != 0x42)) | ||
451 | result |= 0x01; | ||
452 | else | ||
453 | return result; | ||
454 | |||
455 | if (!(regEAC & BIT30) && | ||
456 | (((regEC4 & 0x03FF0000)>>16) != 0x132) && | ||
457 | (((regECC & 0x03FF0000)>>16) != 0x36)) | ||
458 | result |= 0x02; | ||
459 | else | ||
460 | DBG_8723A("Path B Rx IQK fail!!\n"); | ||
461 | return result; | ||
462 | } | ||
463 | |||
464 | static void _PHY_PathAFillIQKMatrix(struct rtw_adapter *pAdapter, | ||
465 | bool bIQKOK, | ||
466 | int result[][8], | ||
467 | u8 final_candidate, | ||
468 | bool bTxOnly | ||
469 | ) | ||
470 | { | ||
471 | u32 Oldval_0, X, TX0_A, reg; | ||
472 | s32 Y, TX0_C; | ||
473 | |||
474 | DBG_8723A("Path A IQ Calibration %s !\n", (bIQKOK)?"Success":"Failed"); | ||
475 | |||
476 | if (final_candidate == 0xFF) { | ||
477 | return; | ||
478 | } else if (bIQKOK) { | ||
479 | Oldval_0 = (PHY_QueryBBReg(pAdapter, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF; | ||
480 | |||
481 | X = result[final_candidate][0]; | ||
482 | if ((X & 0x00000200) != 0) | ||
483 | X = X | 0xFFFFFC00; | ||
484 | TX0_A = (X * Oldval_0) >> 8; | ||
485 | PHY_SetBBReg(pAdapter, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A); | ||
486 | PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(31), ((X * Oldval_0>>7) & 0x1)); | ||
487 | |||
488 | Y = result[final_candidate][1]; | ||
489 | if ((Y & 0x00000200) != 0) | ||
490 | Y = Y | 0xFFFFFC00; | ||
491 | TX0_C = (Y * Oldval_0) >> 8; | ||
492 | PHY_SetBBReg(pAdapter, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C&0x3C0)>>6)); | ||
493 | PHY_SetBBReg(pAdapter, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C&0x3F)); | ||
494 | PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(29), ((Y * Oldval_0>>7) & 0x1)); | ||
495 | |||
496 | if (bTxOnly) { | ||
497 | DBG_8723A("_PHY_PathAFillIQKMatrix only Tx OK\n"); | ||
498 | return; | ||
499 | } | ||
500 | |||
501 | reg = result[final_candidate][2]; | ||
502 | PHY_SetBBReg(pAdapter, rOFDM0_XARxIQImbalance, 0x3FF, reg); | ||
503 | |||
504 | reg = result[final_candidate][3] & 0x3F; | ||
505 | PHY_SetBBReg(pAdapter, rOFDM0_XARxIQImbalance, 0xFC00, reg); | ||
506 | |||
507 | reg = (result[final_candidate][3] >> 6) & 0xF; | ||
508 | PHY_SetBBReg(pAdapter, rOFDM0_RxIQExtAnta, 0xF0000000, reg); | ||
509 | } | ||
510 | } | ||
511 | |||
512 | static void _PHY_PathBFillIQKMatrix(struct rtw_adapter *pAdapter, bool bIQKOK, int result[][8], u8 final_candidate, bool bTxOnly) | ||
513 | { | ||
514 | u32 Oldval_1, X, TX1_A, reg; | ||
515 | s32 Y, TX1_C; | ||
516 | |||
517 | DBG_8723A("Path B IQ Calibration %s !\n", (bIQKOK)?"Success":"Failed"); | ||
518 | |||
519 | if (final_candidate == 0xFF) { | ||
520 | return; | ||
521 | } else if (bIQKOK) { | ||
522 | Oldval_1 = (PHY_QueryBBReg(pAdapter, rOFDM0_XBTxIQImbalance, bMaskDWord) >> 22) & 0x3FF; | ||
523 | |||
524 | X = result[final_candidate][4]; | ||
525 | if ((X & 0x00000200) != 0) | ||
526 | X = X | 0xFFFFFC00; | ||
527 | TX1_A = (X * Oldval_1) >> 8; | ||
528 | PHY_SetBBReg(pAdapter, rOFDM0_XBTxIQImbalance, 0x3FF, TX1_A); | ||
529 | PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(27), ((X * Oldval_1>>7) & 0x1)); | ||
530 | |||
531 | Y = result[final_candidate][5]; | ||
532 | if ((Y & 0x00000200) != 0) | ||
533 | Y = Y | 0xFFFFFC00; | ||
534 | TX1_C = (Y * Oldval_1) >> 8; | ||
535 | PHY_SetBBReg(pAdapter, rOFDM0_XDTxAFE, 0xF0000000, ((TX1_C&0x3C0)>>6)); | ||
536 | PHY_SetBBReg(pAdapter, rOFDM0_XBTxIQImbalance, 0x003F0000, (TX1_C&0x3F)); | ||
537 | PHY_SetBBReg(pAdapter, rOFDM0_ECCAThreshold, BIT(25), ((Y * Oldval_1>>7) & 0x1)); | ||
538 | |||
539 | if (bTxOnly) | ||
540 | return; | ||
541 | |||
542 | reg = result[final_candidate][6]; | ||
543 | PHY_SetBBReg(pAdapter, rOFDM0_XBRxIQImbalance, 0x3FF, reg); | ||
544 | |||
545 | reg = result[final_candidate][7] & 0x3F; | ||
546 | PHY_SetBBReg(pAdapter, rOFDM0_XBRxIQImbalance, 0xFC00, reg); | ||
547 | |||
548 | reg = (result[final_candidate][7] >> 6) & 0xF; | ||
549 | PHY_SetBBReg(pAdapter, rOFDM0_AGCRSSITable, 0x0000F000, reg); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | static void _PHY_SaveADDARegisters(struct rtw_adapter *pAdapter, u32 *ADDAReg, u32 *ADDABackup, u32 RegisterNum) | ||
554 | { | ||
555 | u32 i; | ||
556 | |||
557 | for (i = 0 ; i < RegisterNum ; i++) { | ||
558 | ADDABackup[i] = PHY_QueryBBReg(pAdapter, ADDAReg[i], bMaskDWord); | ||
559 | } | ||
560 | } | ||
561 | |||
562 | static void _PHY_SaveMACRegisters(struct rtw_adapter *pAdapter, u32 *MACReg, u32 *MACBackup) | ||
563 | { | ||
564 | u32 i; | ||
565 | |||
566 | for (i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++) { | ||
567 | MACBackup[i] = rtw_read8(pAdapter, MACReg[i]); | ||
568 | } | ||
569 | MACBackup[i] = rtw_read32(pAdapter, MACReg[i]); | ||
570 | } | ||
571 | |||
572 | static void _PHY_ReloadADDARegisters(struct rtw_adapter *pAdapter, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum) | ||
573 | { | ||
574 | u32 i; | ||
575 | |||
576 | for (i = 0 ; i < RegiesterNum ; i++) { | ||
577 | PHY_SetBBReg(pAdapter, ADDAReg[i], bMaskDWord, ADDABackup[i]); | ||
578 | } | ||
579 | } | ||
580 | |||
581 | static void _PHY_ReloadMACRegisters(struct rtw_adapter *pAdapter, u32 *MACReg, u32 *MACBackup) | ||
582 | { | ||
583 | u32 i; | ||
584 | |||
585 | for (i = 0 ; i < (IQK_MAC_REG_NUM - 1); i++) { | ||
586 | rtw_write8(pAdapter, MACReg[i], (u8)MACBackup[i]); | ||
587 | } | ||
588 | rtw_write32(pAdapter, MACReg[i], MACBackup[i]); | ||
589 | } | ||
590 | |||
591 | static void _PHY_PathADDAOn(struct rtw_adapter *pAdapter, u32 *ADDAReg, bool isPathAOn, bool is2T) | ||
592 | { | ||
593 | u32 pathOn; | ||
594 | u32 i; | ||
595 | |||
596 | pathOn = isPathAOn ? 0x04db25a4 : 0x0b1b25a4; | ||
597 | if (false == is2T) { | ||
598 | pathOn = 0x0bdb25a0; | ||
599 | PHY_SetBBReg(pAdapter, ADDAReg[0], bMaskDWord, 0x0b1b25a0); | ||
600 | } else { | ||
601 | PHY_SetBBReg(pAdapter, ADDAReg[0], bMaskDWord, pathOn); | ||
602 | } | ||
603 | |||
604 | for (i = 1 ; i < IQK_ADDA_REG_NUM ; i++) | ||
605 | PHY_SetBBReg(pAdapter, ADDAReg[i], bMaskDWord, pathOn); | ||
606 | } | ||
607 | |||
608 | static void _PHY_MACSettingCalibration(struct rtw_adapter *pAdapter, u32 *MACReg, u32 *MACBackup) | ||
609 | { | ||
610 | u32 i = 0; | ||
611 | |||
612 | rtw_write8(pAdapter, MACReg[i], 0x3F); | ||
613 | |||
614 | for (i = 1 ; i < (IQK_MAC_REG_NUM - 1); i++) { | ||
615 | rtw_write8(pAdapter, MACReg[i], (u8)(MACBackup[i]&(~BIT3))); | ||
616 | } | ||
617 | rtw_write8(pAdapter, MACReg[i], (u8)(MACBackup[i]&(~BIT5))); | ||
618 | } | ||
619 | |||
620 | static void _PHY_PathAStandBy(struct rtw_adapter *pAdapter) | ||
621 | { | ||
622 | PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x0); | ||
623 | PHY_SetBBReg(pAdapter, 0x840, bMaskDWord, 0x00010000); | ||
624 | PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x80800000); | ||
625 | } | ||
626 | |||
627 | static void _PHY_PIModeSwitch(struct rtw_adapter *pAdapter, bool PIMode) | ||
628 | { | ||
629 | u32 mode; | ||
630 | |||
631 | mode = PIMode ? 0x01000100 : 0x01000000; | ||
632 | PHY_SetBBReg(pAdapter, 0x820, bMaskDWord, mode); | ||
633 | PHY_SetBBReg(pAdapter, 0x828, bMaskDWord, mode); | ||
634 | } | ||
635 | |||
636 | /* | ||
637 | return false => do IQK again | ||
638 | */ | ||
639 | static bool _PHY_SimularityCompare(struct rtw_adapter *pAdapter, int result[][8], u8 c1, u8 c2) | ||
640 | { | ||
641 | u32 i, j, diff, SimularityBitMap, bound = 0; | ||
642 | struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); | ||
643 | u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */ | ||
644 | bool bResult = true, is2T = IS_92C_SERIAL(pHalData->VersionID); | ||
645 | |||
646 | if (is2T) | ||
647 | bound = 8; | ||
648 | else | ||
649 | bound = 4; | ||
650 | |||
651 | SimularityBitMap = 0; | ||
652 | |||
653 | for (i = 0; i < bound; i++) { | ||
654 | diff = (result[c1][i] > result[c2][i]) ? (result[c1][i] - result[c2][i]) : (result[c2][i] - result[c1][i]); | ||
655 | if (diff > MAX_TOLERANCE) { | ||
656 | if ((i == 2 || i == 6) && !SimularityBitMap) { | ||
657 | if (result[c1][i]+result[c1][i+1] == 0) | ||
658 | final_candidate[(i/4)] = c2; | ||
659 | else if (result[c2][i]+result[c2][i+1] == 0) | ||
660 | final_candidate[(i/4)] = c1; | ||
661 | else | ||
662 | SimularityBitMap = SimularityBitMap|(1<<i); | ||
663 | } else { | ||
664 | SimularityBitMap = SimularityBitMap|(1<<i); | ||
665 | } | ||
666 | } | ||
667 | } | ||
668 | |||
669 | if (SimularityBitMap == 0) { | ||
670 | for (i = 0; i < (bound/4); i++) { | ||
671 | if (final_candidate[i] != 0xFF) { | ||
672 | for (j = i*4; j < (i+1)*4-2; j++) | ||
673 | result[3][j] = result[final_candidate[i]][j]; | ||
674 | bResult = false; | ||
675 | } | ||
676 | } | ||
677 | return bResult; | ||
678 | } else if (!(SimularityBitMap & 0x0F)) { | ||
679 | /* path A OK */ | ||
680 | for (i = 0; i < 4; i++) | ||
681 | result[3][i] = result[c1][i]; | ||
682 | return false; | ||
683 | } else if (!(SimularityBitMap & 0xF0) && is2T) { | ||
684 | /* path B OK */ | ||
685 | for (i = 4; i < 8; i++) | ||
686 | result[3][i] = result[c1][i]; | ||
687 | return false; | ||
688 | } else { | ||
689 | return false; | ||
690 | } | ||
691 | } | ||
692 | |||
693 | static void _PHY_IQCalibrate(struct rtw_adapter *pAdapter, int result[][8], u8 t, bool is2T) | ||
694 | { | ||
695 | struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); | ||
696 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
697 | u32 i; | ||
698 | u8 PathAOK, PathBOK; | ||
699 | u32 ADDA_REG[IQK_ADDA_REG_NUM] = { | ||
700 | rFPGA0_XCD_SwitchControl, rBlue_Tooth, | ||
701 | rRx_Wait_CCA, rTx_CCK_RFON, | ||
702 | rTx_CCK_BBON, rTx_OFDM_RFON, | ||
703 | rTx_OFDM_BBON, rTx_To_Rx, | ||
704 | rTx_To_Tx, rRx_CCK, | ||
705 | rRx_OFDM, rRx_Wait_RIFS, | ||
706 | rRx_TO_Rx, rStandby, | ||
707 | rSleep, rPMPD_ANAEN | ||
708 | }; | ||
709 | |||
710 | u32 IQK_MAC_REG[IQK_MAC_REG_NUM] = { | ||
711 | REG_TXPAUSE, REG_BCN_CTRL, | ||
712 | REG_BCN_CTRL_1, REG_GPIO_MUXCFG | ||
713 | }; | ||
714 | |||
715 | u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = { | ||
716 | rOFDM0_TRxPathEnable, rOFDM0_TRMuxPar, | ||
717 | rFPGA0_XCD_RFInterfaceSW, rConfig_AntA, rConfig_AntB, | ||
718 | rFPGA0_XAB_RFInterfaceSW, rFPGA0_XA_RFInterfaceOE, | ||
719 | rFPGA0_XB_RFInterfaceOE, rFPGA0_RFMOD | ||
720 | }; | ||
721 | |||
722 | const u32 retryCount = 2; | ||
723 | |||
724 | /* Note: IQ calibration must be performed after loading */ | ||
725 | /* PHY_REG.txt , and radio_a, radio_b.txt */ | ||
726 | |||
727 | u32 bbvalue; | ||
728 | |||
729 | if (t == 0) { | ||
730 | bbvalue = PHY_QueryBBReg(pAdapter, rFPGA0_RFMOD, bMaskDWord); | ||
731 | |||
732 | /* Save ADDA parameters, turn Path A ADDA on */ | ||
733 | _PHY_SaveADDARegisters(pAdapter, ADDA_REG, pdmpriv->ADDA_backup, IQK_ADDA_REG_NUM); | ||
734 | _PHY_SaveMACRegisters(pAdapter, IQK_MAC_REG, pdmpriv->IQK_MAC_backup); | ||
735 | _PHY_SaveADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup, IQK_BB_REG_NUM); | ||
736 | } | ||
737 | _PHY_PathADDAOn(pAdapter, ADDA_REG, true, is2T); | ||
738 | |||
739 | if (t == 0) | ||
740 | pdmpriv->bRfPiEnable = (u8)PHY_QueryBBReg(pAdapter, rFPGA0_XA_HSSIParameter1, BIT(8)); | ||
741 | |||
742 | if (!pdmpriv->bRfPiEnable) { | ||
743 | /* Switch BB to PI mode to do IQ Calibration. */ | ||
744 | _PHY_PIModeSwitch(pAdapter, true); | ||
745 | } | ||
746 | |||
747 | PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, BIT24, 0x00); | ||
748 | PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600); | ||
749 | PHY_SetBBReg(pAdapter, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4); | ||
750 | PHY_SetBBReg(pAdapter, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000); | ||
751 | PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0x01); | ||
752 | PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0x01); | ||
753 | PHY_SetBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, BIT10, 0x00); | ||
754 | PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0x00); | ||
755 | |||
756 | if (is2T) { | ||
757 | PHY_SetBBReg(pAdapter, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00010000); | ||
758 | PHY_SetBBReg(pAdapter, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00010000); | ||
759 | } | ||
760 | |||
761 | /* MAC settings */ | ||
762 | _PHY_MACSettingCalibration(pAdapter, IQK_MAC_REG, pdmpriv->IQK_MAC_backup); | ||
763 | |||
764 | /* Page B init */ | ||
765 | PHY_SetBBReg(pAdapter, rConfig_AntA, bMaskDWord, 0x00080000); | ||
766 | |||
767 | if (is2T) | ||
768 | PHY_SetBBReg(pAdapter, rConfig_AntB, bMaskDWord, 0x00080000); | ||
769 | |||
770 | /* IQ calibration setting */ | ||
771 | PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0x80800000); | ||
772 | PHY_SetBBReg(pAdapter, rTx_IQK, bMaskDWord, 0x01007c00); | ||
773 | PHY_SetBBReg(pAdapter, rRx_IQK, bMaskDWord, 0x01004800); | ||
774 | |||
775 | for (i = 0 ; i < retryCount ; i++) { | ||
776 | PathAOK = _PHY_PathA_IQK(pAdapter, is2T); | ||
777 | if (PathAOK == 0x03) { | ||
778 | DBG_8723A("Path A IQK Success!!\n"); | ||
779 | result[t][0] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; | ||
780 | result[t][1] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; | ||
781 | result[t][2] = (PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_A_2, bMaskDWord)&0x3FF0000)>>16; | ||
782 | result[t][3] = (PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_A_2, bMaskDWord)&0x3FF0000)>>16; | ||
783 | break; | ||
784 | } else if (i == (retryCount-1) && PathAOK == 0x01) { | ||
785 | /* Tx IQK OK */ | ||
786 | DBG_8723A("Path A IQK Only Tx Success!!\n"); | ||
787 | |||
788 | result[t][0] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_A, bMaskDWord)&0x3FF0000)>>16; | ||
789 | result[t][1] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_A, bMaskDWord)&0x3FF0000)>>16; | ||
790 | } | ||
791 | } | ||
792 | |||
793 | if (0x00 == PathAOK) { | ||
794 | DBG_8723A("Path A IQK failed!!\n"); | ||
795 | } | ||
796 | |||
797 | if (is2T) { | ||
798 | _PHY_PathAStandBy(pAdapter); | ||
799 | |||
800 | /* Turn Path B ADDA on */ | ||
801 | _PHY_PathADDAOn(pAdapter, ADDA_REG, false, is2T); | ||
802 | |||
803 | for (i = 0 ; i < retryCount ; i++) { | ||
804 | PathBOK = _PHY_PathB_IQK(pAdapter); | ||
805 | if (PathBOK == 0x03) { | ||
806 | DBG_8723A("Path B IQK Success!!\n"); | ||
807 | result[t][4] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_B, bMaskDWord)&0x3FF0000)>>16; | ||
808 | result[t][5] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_B, bMaskDWord)&0x3FF0000)>>16; | ||
809 | result[t][6] = (PHY_QueryBBReg(pAdapter, rRx_Power_Before_IQK_B_2, bMaskDWord)&0x3FF0000)>>16; | ||
810 | result[t][7] = (PHY_QueryBBReg(pAdapter, rRx_Power_After_IQK_B_2, bMaskDWord)&0x3FF0000)>>16; | ||
811 | break; | ||
812 | } else if (i == (retryCount - 1) && PathBOK == 0x01) { | ||
813 | /* Tx IQK OK */ | ||
814 | DBG_8723A("Path B Only Tx IQK Success!!\n"); | ||
815 | result[t][4] = (PHY_QueryBBReg(pAdapter, rTx_Power_Before_IQK_B, bMaskDWord)&0x3FF0000)>>16; | ||
816 | result[t][5] = (PHY_QueryBBReg(pAdapter, rTx_Power_After_IQK_B, bMaskDWord)&0x3FF0000)>>16; | ||
817 | } | ||
818 | } | ||
819 | |||
820 | if (0x00 == PathBOK) { | ||
821 | DBG_8723A("Path B IQK failed!!\n"); | ||
822 | } | ||
823 | } | ||
824 | |||
825 | /* Back to BB mode, load original value */ | ||
826 | PHY_SetBBReg(pAdapter, rFPGA0_IQK, bMaskDWord, 0); | ||
827 | |||
828 | if (t != 0) { | ||
829 | if (!pdmpriv->bRfPiEnable) { | ||
830 | /* Switch back BB to SI mode after finish IQ Calibration. */ | ||
831 | _PHY_PIModeSwitch(pAdapter, false); | ||
832 | } | ||
833 | |||
834 | /* Reload ADDA power saving parameters */ | ||
835 | _PHY_ReloadADDARegisters(pAdapter, ADDA_REG, pdmpriv->ADDA_backup, IQK_ADDA_REG_NUM); | ||
836 | |||
837 | /* Reload MAC parameters */ | ||
838 | _PHY_ReloadMACRegisters(pAdapter, IQK_MAC_REG, pdmpriv->IQK_MAC_backup); | ||
839 | |||
840 | /* Reload BB parameters */ | ||
841 | _PHY_ReloadADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup, IQK_BB_REG_NUM); | ||
842 | |||
843 | /* Restore RX initial gain */ | ||
844 | PHY_SetBBReg(pAdapter, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00032ed3); | ||
845 | if (is2T) { | ||
846 | PHY_SetBBReg(pAdapter, rFPGA0_XB_LSSIParameter, bMaskDWord, 0x00032ed3); | ||
847 | } | ||
848 | |||
849 | /* load 0xe30 IQC default value */ | ||
850 | PHY_SetBBReg(pAdapter, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00); | ||
851 | PHY_SetBBReg(pAdapter, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00); | ||
852 | |||
853 | } | ||
854 | } | ||
855 | |||
856 | static void _PHY_LCCalibrate(struct rtw_adapter *pAdapter, bool is2T) | ||
857 | { | ||
858 | u8 tmpReg; | ||
859 | u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal; | ||
860 | |||
861 | /* Check continuous TX and Packet TX */ | ||
862 | tmpReg = rtw_read8(pAdapter, 0xd03); | ||
863 | |||
864 | if ((tmpReg&0x70) != 0) /* Deal with contisuous TX case */ | ||
865 | rtw_write8(pAdapter, 0xd03, tmpReg&0x8F); /* disable all continuous TX */ | ||
866 | else /* Deal with Packet TX case */ | ||
867 | rtw_write8(pAdapter, REG_TXPAUSE, 0xFF); /* block all queues */ | ||
868 | |||
869 | if ((tmpReg&0x70) != 0) { | ||
870 | /* 1. Read original RF mode */ | ||
871 | /* Path-A */ | ||
872 | RF_Amode = PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_AC, bMask12Bits); | ||
873 | |||
874 | /* Path-B */ | ||
875 | if (is2T) | ||
876 | RF_Bmode = PHY_QueryRFReg(pAdapter, RF_PATH_B, RF_AC, bMask12Bits); | ||
877 | |||
878 | /* 2. Set RF mode = standby mode */ | ||
879 | /* Path-A */ | ||
880 | PHY_SetRFReg(pAdapter, RF_PATH_A, RF_AC, bMask12Bits, (RF_Amode&0x8FFFF)|0x10000); | ||
881 | |||
882 | /* Path-B */ | ||
883 | if (is2T) | ||
884 | PHY_SetRFReg(pAdapter, RF_PATH_B, RF_AC, bMask12Bits, (RF_Bmode&0x8FFFF)|0x10000); | ||
885 | } | ||
886 | |||
887 | /* 3. Read RF reg18 */ | ||
888 | LC_Cal = PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_CHNLBW, bMask12Bits); | ||
889 | |||
890 | /* 4. Set LC calibration begin */ | ||
891 | PHY_SetRFReg(pAdapter, RF_PATH_A, RF_CHNLBW, bMask12Bits, LC_Cal|0x08000); | ||
892 | |||
893 | msleep(100); | ||
894 | |||
895 | /* Restore original situation */ | ||
896 | if ((tmpReg&0x70) != 0) { /* Deal with contuous TX case */ | ||
897 | /* Path-A */ | ||
898 | rtw_write8(pAdapter, 0xd03, tmpReg); | ||
899 | PHY_SetRFReg(pAdapter, RF_PATH_A, RF_AC, bMask12Bits, RF_Amode); | ||
900 | |||
901 | /* Path-B */ | ||
902 | if (is2T) | ||
903 | PHY_SetRFReg(pAdapter, RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode); | ||
904 | } else { /* Deal with Packet TX case */ | ||
905 | rtw_write8(pAdapter, REG_TXPAUSE, 0x00); | ||
906 | } | ||
907 | } | ||
908 | |||
909 | /* Analog Pre-distortion calibration */ | ||
910 | #define APK_BB_REG_NUM 8 | ||
911 | #define APK_CURVE_REG_NUM 4 | ||
912 | #define PATH_NUM 2 | ||
913 | |||
914 | void rtl8723a_phy_iq_calibrate(struct rtw_adapter *pAdapter, bool bReCovery) | ||
915 | { | ||
916 | struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); | ||
917 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
918 | s32 result[4][8]; /* last is final result */ | ||
919 | u8 i, final_candidate; | ||
920 | bool bPathAOK, bPathBOK; | ||
921 | s32 RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4; | ||
922 | s32 RegECC, RegTmp = 0; | ||
923 | bool is12simular, is13simular, is23simular; | ||
924 | bool bStartContTx = false, bSingleTone = false; | ||
925 | bool bCarrierSuppression = false; | ||
926 | u32 IQK_BB_REG_92C[IQK_BB_REG_NUM] = { | ||
927 | rOFDM0_XARxIQImbalance, rOFDM0_XBRxIQImbalance, | ||
928 | rOFDM0_ECCAThreshold, rOFDM0_AGCRSSITable, | ||
929 | rOFDM0_XATxIQImbalance, rOFDM0_XBTxIQImbalance, | ||
930 | rOFDM0_XCTxAFE, rOFDM0_XDTxAFE, | ||
931 | rOFDM0_RxIQExtAnta | ||
932 | }; | ||
933 | |||
934 | /* ignore IQK when continuous Tx */ | ||
935 | if (bStartContTx || bSingleTone || bCarrierSuppression) | ||
936 | return; | ||
937 | |||
938 | if (bReCovery) { | ||
939 | _PHY_ReloadADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup_recover, 9); | ||
940 | return; | ||
941 | } | ||
942 | DBG_8723A("IQK:Start!!!\n"); | ||
943 | |||
944 | for (i = 0; i < 8; i++) { | ||
945 | result[0][i] = 0; | ||
946 | result[1][i] = 0; | ||
947 | result[2][i] = 0; | ||
948 | result[3][i] = 0; | ||
949 | } | ||
950 | final_candidate = 0xff; | ||
951 | bPathAOK = false; | ||
952 | bPathBOK = false; | ||
953 | is12simular = false; | ||
954 | is23simular = false; | ||
955 | is13simular = false; | ||
956 | |||
957 | for (i = 0; i < 3; i++) { | ||
958 | if (IS_92C_SERIAL(pHalData->VersionID)) { | ||
959 | _PHY_IQCalibrate(pAdapter, result, i, true); | ||
960 | } else { | ||
961 | /* For 88C 1T1R */ | ||
962 | _PHY_IQCalibrate(pAdapter, result, i, false); | ||
963 | } | ||
964 | |||
965 | if (i == 1) { | ||
966 | is12simular = _PHY_SimularityCompare(pAdapter, result, 0, 1); | ||
967 | if (is12simular) { | ||
968 | final_candidate = 0; | ||
969 | break; | ||
970 | } | ||
971 | } | ||
972 | |||
973 | if (i == 2) { | ||
974 | is13simular = _PHY_SimularityCompare(pAdapter, result, 0, 2); | ||
975 | if (is13simular) { | ||
976 | final_candidate = 0; | ||
977 | break; | ||
978 | } | ||
979 | |||
980 | is23simular = _PHY_SimularityCompare(pAdapter, result, 1, 2); | ||
981 | if (is23simular) { | ||
982 | final_candidate = 1; | ||
983 | } else { | ||
984 | for (i = 0; i < 8; i++) | ||
985 | RegTmp += result[3][i]; | ||
986 | |||
987 | if (RegTmp != 0) | ||
988 | final_candidate = 3; | ||
989 | else | ||
990 | final_candidate = 0xFF; | ||
991 | } | ||
992 | } | ||
993 | } | ||
994 | |||
995 | for (i = 0; i < 4; i++) { | ||
996 | RegE94 = result[i][0]; | ||
997 | RegE9C = result[i][1]; | ||
998 | RegEA4 = result[i][2]; | ||
999 | RegEAC = result[i][3]; | ||
1000 | RegEB4 = result[i][4]; | ||
1001 | RegEBC = result[i][5]; | ||
1002 | RegEC4 = result[i][6]; | ||
1003 | RegECC = result[i][7]; | ||
1004 | } | ||
1005 | |||
1006 | if (final_candidate != 0xff) { | ||
1007 | RegE94 = result[final_candidate][0]; | ||
1008 | pdmpriv->RegE94 = RegE94; | ||
1009 | RegE9C = result[final_candidate][1]; | ||
1010 | pdmpriv->RegE9C = RegE9C; | ||
1011 | RegEA4 = result[final_candidate][2]; | ||
1012 | RegEAC = result[final_candidate][3]; | ||
1013 | RegEB4 = result[final_candidate][4]; | ||
1014 | pdmpriv->RegEB4 = RegEB4; | ||
1015 | RegEBC = result[final_candidate][5]; | ||
1016 | pdmpriv->RegEBC = RegEBC; | ||
1017 | RegEC4 = result[final_candidate][6]; | ||
1018 | RegECC = result[final_candidate][7]; | ||
1019 | DBG_8723A("IQK: final_candidate is %x\n", final_candidate); | ||
1020 | DBG_8723A("IQK: RegE94 =%x RegE9C =%x RegEA4 =%x RegEAC =%x RegEB4 =%x RegEBC =%x RegEC4 =%x RegECC =%x\n ", | ||
1021 | RegE94, RegE9C, RegEA4, RegEAC, RegEB4, RegEBC, RegEC4, RegECC); | ||
1022 | bPathAOK = bPathBOK = true; | ||
1023 | } else { | ||
1024 | RegE94 = RegEB4 = pdmpriv->RegE94 = pdmpriv->RegEB4 = 0x100; /* X default value */ | ||
1025 | RegE9C = RegEBC = pdmpriv->RegE9C = pdmpriv->RegEBC = 0x0; /* Y default value */ | ||
1026 | } | ||
1027 | |||
1028 | if ((RegE94 != 0)/*&&(RegEA4 != 0)*/) | ||
1029 | _PHY_PathAFillIQKMatrix(pAdapter, bPathAOK, result, final_candidate, (RegEA4 == 0)); | ||
1030 | |||
1031 | if (IS_92C_SERIAL(pHalData->VersionID)) { | ||
1032 | if ((RegEB4 != 0)/*&&(RegEC4 != 0)*/) | ||
1033 | _PHY_PathBFillIQKMatrix(pAdapter, bPathBOK, result, final_candidate, (RegEC4 == 0)); | ||
1034 | } | ||
1035 | |||
1036 | _PHY_SaveADDARegisters(pAdapter, IQK_BB_REG_92C, pdmpriv->IQK_BB_backup_recover, 9); | ||
1037 | } | ||
1038 | |||
1039 | void rtl8723a_phy_lc_calibrate(struct rtw_adapter *pAdapter) | ||
1040 | { | ||
1041 | struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); | ||
1042 | struct mlme_ext_priv *pmlmeext = &pAdapter->mlmeextpriv; | ||
1043 | bool bStartContTx = false, bSingleTone = false, bCarrierSuppression = false; | ||
1044 | |||
1045 | /* ignore IQK when continuous Tx */ | ||
1046 | if (bStartContTx || bSingleTone || bCarrierSuppression) | ||
1047 | return; | ||
1048 | |||
1049 | if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) | ||
1050 | return; | ||
1051 | |||
1052 | if (IS_92C_SERIAL(pHalData->VersionID)) { | ||
1053 | _PHY_LCCalibrate(pAdapter, true); | ||
1054 | } else { | ||
1055 | /* For 88C 1T1R */ | ||
1056 | _PHY_LCCalibrate(pAdapter, false); | ||
1057 | } | ||
1058 | } | ||
1059 | |||
1060 | void | ||
1061 | rtl8723a_phy_ap_calibrate(struct rtw_adapter *pAdapter, char delta) | ||
1062 | { | ||
1063 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c b/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c new file mode 100644 index 000000000000..294e6a6c60db --- /dev/null +++ b/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c | |||
@@ -0,0 +1,726 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | #include "odm_precomp.h" | ||
17 | |||
18 | static bool CheckCondition(const u32 Condition, const u32 Hex) | ||
19 | { | ||
20 | u32 _board = (Hex & 0x000000FF); | ||
21 | u32 _interface = (Hex & 0x0000FF00) >> 8; | ||
22 | u32 _platform = (Hex & 0x00FF0000) >> 16; | ||
23 | u32 cond = Condition; | ||
24 | |||
25 | if (Condition == 0xCDCDCDCD) | ||
26 | return true; | ||
27 | |||
28 | cond = Condition & 0x000000FF; | ||
29 | if ((_board == cond) && cond != 0x00) | ||
30 | return false; | ||
31 | |||
32 | cond = Condition & 0x0000FF00; | ||
33 | cond = cond >> 8; | ||
34 | if ((_interface & cond) == 0 && cond != 0x07) | ||
35 | return false; | ||
36 | |||
37 | cond = Condition & 0x00FF0000; | ||
38 | cond = cond >> 16; | ||
39 | if ((_platform & cond) == 0 && cond != 0x0F) | ||
40 | return false; | ||
41 | return true; | ||
42 | } | ||
43 | |||
44 | /****************************************************************************** | ||
45 | * AGC_TAB_1T.TXT | ||
46 | ******************************************************************************/ | ||
47 | |||
48 | static u32 Array_AGC_TAB_1T_8723A[] = { | ||
49 | 0xC78, 0x7B000001, | ||
50 | 0xC78, 0x7B010001, | ||
51 | 0xC78, 0x7B020001, | ||
52 | 0xC78, 0x7B030001, | ||
53 | 0xC78, 0x7B040001, | ||
54 | 0xC78, 0x7B050001, | ||
55 | 0xC78, 0x7A060001, | ||
56 | 0xC78, 0x79070001, | ||
57 | 0xC78, 0x78080001, | ||
58 | 0xC78, 0x77090001, | ||
59 | 0xC78, 0x760A0001, | ||
60 | 0xC78, 0x750B0001, | ||
61 | 0xC78, 0x740C0001, | ||
62 | 0xC78, 0x730D0001, | ||
63 | 0xC78, 0x720E0001, | ||
64 | 0xC78, 0x710F0001, | ||
65 | 0xC78, 0x70100001, | ||
66 | 0xC78, 0x6F110001, | ||
67 | 0xC78, 0x6E120001, | ||
68 | 0xC78, 0x6D130001, | ||
69 | 0xC78, 0x6C140001, | ||
70 | 0xC78, 0x6B150001, | ||
71 | 0xC78, 0x6A160001, | ||
72 | 0xC78, 0x69170001, | ||
73 | 0xC78, 0x68180001, | ||
74 | 0xC78, 0x67190001, | ||
75 | 0xC78, 0x661A0001, | ||
76 | 0xC78, 0x651B0001, | ||
77 | 0xC78, 0x641C0001, | ||
78 | 0xC78, 0x631D0001, | ||
79 | 0xC78, 0x621E0001, | ||
80 | 0xC78, 0x611F0001, | ||
81 | 0xC78, 0x60200001, | ||
82 | 0xC78, 0x49210001, | ||
83 | 0xC78, 0x48220001, | ||
84 | 0xC78, 0x47230001, | ||
85 | 0xC78, 0x46240001, | ||
86 | 0xC78, 0x45250001, | ||
87 | 0xC78, 0x44260001, | ||
88 | 0xC78, 0x43270001, | ||
89 | 0xC78, 0x42280001, | ||
90 | 0xC78, 0x41290001, | ||
91 | 0xC78, 0x402A0001, | ||
92 | 0xC78, 0x262B0001, | ||
93 | 0xC78, 0x252C0001, | ||
94 | 0xC78, 0x242D0001, | ||
95 | 0xC78, 0x232E0001, | ||
96 | 0xC78, 0x222F0001, | ||
97 | 0xC78, 0x21300001, | ||
98 | 0xC78, 0x20310001, | ||
99 | 0xC78, 0x06320001, | ||
100 | 0xC78, 0x05330001, | ||
101 | 0xC78, 0x04340001, | ||
102 | 0xC78, 0x03350001, | ||
103 | 0xC78, 0x02360001, | ||
104 | 0xC78, 0x01370001, | ||
105 | 0xC78, 0x00380001, | ||
106 | 0xC78, 0x00390001, | ||
107 | 0xC78, 0x003A0001, | ||
108 | 0xC78, 0x003B0001, | ||
109 | 0xC78, 0x003C0001, | ||
110 | 0xC78, 0x003D0001, | ||
111 | 0xC78, 0x003E0001, | ||
112 | 0xC78, 0x003F0001, | ||
113 | 0xC78, 0x7B400001, | ||
114 | 0xC78, 0x7B410001, | ||
115 | 0xC78, 0x7B420001, | ||
116 | 0xC78, 0x7B430001, | ||
117 | 0xC78, 0x7B440001, | ||
118 | 0xC78, 0x7B450001, | ||
119 | 0xC78, 0x7A460001, | ||
120 | 0xC78, 0x79470001, | ||
121 | 0xC78, 0x78480001, | ||
122 | 0xC78, 0x77490001, | ||
123 | 0xC78, 0x764A0001, | ||
124 | 0xC78, 0x754B0001, | ||
125 | 0xC78, 0x744C0001, | ||
126 | 0xC78, 0x734D0001, | ||
127 | 0xC78, 0x724E0001, | ||
128 | 0xC78, 0x714F0001, | ||
129 | 0xC78, 0x70500001, | ||
130 | 0xC78, 0x6F510001, | ||
131 | 0xC78, 0x6E520001, | ||
132 | 0xC78, 0x6D530001, | ||
133 | 0xC78, 0x6C540001, | ||
134 | 0xC78, 0x6B550001, | ||
135 | 0xC78, 0x6A560001, | ||
136 | 0xC78, 0x69570001, | ||
137 | 0xC78, 0x68580001, | ||
138 | 0xC78, 0x67590001, | ||
139 | 0xC78, 0x665A0001, | ||
140 | 0xC78, 0x655B0001, | ||
141 | 0xC78, 0x645C0001, | ||
142 | 0xC78, 0x635D0001, | ||
143 | 0xC78, 0x625E0001, | ||
144 | 0xC78, 0x615F0001, | ||
145 | 0xC78, 0x60600001, | ||
146 | 0xC78, 0x49610001, | ||
147 | 0xC78, 0x48620001, | ||
148 | 0xC78, 0x47630001, | ||
149 | 0xC78, 0x46640001, | ||
150 | 0xC78, 0x45650001, | ||
151 | 0xC78, 0x44660001, | ||
152 | 0xC78, 0x43670001, | ||
153 | 0xC78, 0x42680001, | ||
154 | 0xC78, 0x41690001, | ||
155 | 0xC78, 0x406A0001, | ||
156 | 0xC78, 0x266B0001, | ||
157 | 0xC78, 0x256C0001, | ||
158 | 0xC78, 0x246D0001, | ||
159 | 0xC78, 0x236E0001, | ||
160 | 0xC78, 0x226F0001, | ||
161 | 0xC78, 0x21700001, | ||
162 | 0xC78, 0x20710001, | ||
163 | 0xC78, 0x06720001, | ||
164 | 0xC78, 0x05730001, | ||
165 | 0xC78, 0x04740001, | ||
166 | 0xC78, 0x03750001, | ||
167 | 0xC78, 0x02760001, | ||
168 | 0xC78, 0x01770001, | ||
169 | 0xC78, 0x00780001, | ||
170 | 0xC78, 0x00790001, | ||
171 | 0xC78, 0x007A0001, | ||
172 | 0xC78, 0x007B0001, | ||
173 | 0xC78, 0x007C0001, | ||
174 | 0xC78, 0x007D0001, | ||
175 | 0xC78, 0x007E0001, | ||
176 | 0xC78, 0x007F0001, | ||
177 | 0xC78, 0x3800001E, | ||
178 | 0xC78, 0x3801001E, | ||
179 | 0xC78, 0x3802001E, | ||
180 | 0xC78, 0x3803001E, | ||
181 | 0xC78, 0x3804001E, | ||
182 | 0xC78, 0x3805001E, | ||
183 | 0xC78, 0x3806001E, | ||
184 | 0xC78, 0x3807001E, | ||
185 | 0xC78, 0x3808001E, | ||
186 | 0xC78, 0x3C09001E, | ||
187 | 0xC78, 0x3E0A001E, | ||
188 | 0xC78, 0x400B001E, | ||
189 | 0xC78, 0x440C001E, | ||
190 | 0xC78, 0x480D001E, | ||
191 | 0xC78, 0x4C0E001E, | ||
192 | 0xC78, 0x500F001E, | ||
193 | 0xC78, 0x5210001E, | ||
194 | 0xC78, 0x5611001E, | ||
195 | 0xC78, 0x5A12001E, | ||
196 | 0xC78, 0x5E13001E, | ||
197 | 0xC78, 0x6014001E, | ||
198 | 0xC78, 0x6015001E, | ||
199 | 0xC78, 0x6016001E, | ||
200 | 0xC78, 0x6217001E, | ||
201 | 0xC78, 0x6218001E, | ||
202 | 0xC78, 0x6219001E, | ||
203 | 0xC78, 0x621A001E, | ||
204 | 0xC78, 0x621B001E, | ||
205 | 0xC78, 0x621C001E, | ||
206 | 0xC78, 0x621D001E, | ||
207 | 0xC78, 0x621E001E, | ||
208 | 0xC78, 0x621F001E, | ||
209 | }; | ||
210 | |||
211 | #define READ_NEXT_PAIR(v1, v2, i) \ | ||
212 | do { \ | ||
213 | i += 2; v1 = Array[i]; v2 = Array[i+1]; \ | ||
214 | } while (0) | ||
215 | |||
216 | void ODM_ReadAndConfig_AGC_TAB_1T_8723A(struct dm_odm_t *pDM_Odm) | ||
217 | { | ||
218 | |||
219 | u32 hex; | ||
220 | u32 i; | ||
221 | u8 platform = 0x04; | ||
222 | u8 interfaceValue = pDM_Odm->SupportInterface; | ||
223 | u8 board = pDM_Odm->BoardType; | ||
224 | u32 ArrayLen = sizeof(Array_AGC_TAB_1T_8723A)/sizeof(u32); | ||
225 | u32 *Array = Array_AGC_TAB_1T_8723A; | ||
226 | |||
227 | hex = board; | ||
228 | hex += interfaceValue << 8; | ||
229 | hex += platform << 16; | ||
230 | hex += 0xFF000000; | ||
231 | for (i = 0; i < ArrayLen; i += 2) { | ||
232 | u32 v1 = Array[i]; | ||
233 | u32 v2 = Array[i+1]; | ||
234 | |||
235 | /* This (offset, data) pair meets the condition. */ | ||
236 | if (v1 < 0xCDCDCDCD) { | ||
237 | odm_ConfigBB_AGC_8723A(pDM_Odm, v1, bMaskDWord, v2); | ||
238 | continue; | ||
239 | } else { | ||
240 | if (!CheckCondition(Array[i], hex)) { | ||
241 | /* Discard the following (offset, data) pairs. */ | ||
242 | READ_NEXT_PAIR(v1, v2, i); | ||
243 | while (v2 != 0xDEAD && | ||
244 | v2 != 0xCDEF && | ||
245 | v2 != 0xCDCD && i < ArrayLen - 2) | ||
246 | READ_NEXT_PAIR(v1, v2, i); | ||
247 | i -= 2; /* prevent from for-loop += 2 */ | ||
248 | } else { | ||
249 | /* Configure matched pairs and skip to end of if-else. */ | ||
250 | READ_NEXT_PAIR(v1, v2, i); | ||
251 | while (v2 != 0xDEAD && | ||
252 | v2 != 0xCDEF && | ||
253 | v2 != 0xCDCD && i < ArrayLen - 2) { | ||
254 | odm_ConfigBB_AGC_8723A(pDM_Odm, v1, bMaskDWord, v2); | ||
255 | READ_NEXT_PAIR(v1, v2, i); | ||
256 | } | ||
257 | while (v2 != 0xDEAD && i < ArrayLen - 2) | ||
258 | READ_NEXT_PAIR(v1, v2, i); | ||
259 | } | ||
260 | } | ||
261 | } | ||
262 | } | ||
263 | |||
264 | /****************************************************************************** | ||
265 | * PHY_REG_1T.TXT | ||
266 | ******************************************************************************/ | ||
267 | |||
268 | static u32 Array_PHY_REG_1T_8723A[] = { | ||
269 | 0x800, 0x80040000, | ||
270 | 0x804, 0x00000003, | ||
271 | 0x808, 0x0000FC00, | ||
272 | 0x80C, 0x0000000A, | ||
273 | 0x810, 0x10001331, | ||
274 | 0x814, 0x020C3D10, | ||
275 | 0x818, 0x02200385, | ||
276 | 0x81C, 0x00000000, | ||
277 | 0x820, 0x01000100, | ||
278 | 0x824, 0x00390004, | ||
279 | 0x828, 0x00000000, | ||
280 | 0x82C, 0x00000000, | ||
281 | 0x830, 0x00000000, | ||
282 | 0x834, 0x00000000, | ||
283 | 0x838, 0x00000000, | ||
284 | 0x83C, 0x00000000, | ||
285 | 0x840, 0x00010000, | ||
286 | 0x844, 0x00000000, | ||
287 | 0x848, 0x00000000, | ||
288 | 0x84C, 0x00000000, | ||
289 | 0x850, 0x00000000, | ||
290 | 0x854, 0x00000000, | ||
291 | 0x858, 0x569A569A, | ||
292 | 0x85C, 0x001B25A4, | ||
293 | 0x860, 0x66F60110, | ||
294 | 0x864, 0x061F0130, | ||
295 | 0x868, 0x00000000, | ||
296 | 0x86C, 0x32323200, | ||
297 | 0x870, 0x07000760, | ||
298 | 0x874, 0x22004000, | ||
299 | 0x878, 0x00000808, | ||
300 | 0x87C, 0x00000000, | ||
301 | 0x880, 0xC0083070, | ||
302 | 0x884, 0x000004D5, | ||
303 | 0x888, 0x00000000, | ||
304 | 0x88C, 0xCCC000C0, | ||
305 | 0x890, 0x00000800, | ||
306 | 0x894, 0xFFFFFFFE, | ||
307 | 0x898, 0x40302010, | ||
308 | 0x89C, 0x00706050, | ||
309 | 0x900, 0x00000000, | ||
310 | 0x904, 0x00000023, | ||
311 | 0x908, 0x00000000, | ||
312 | 0x90C, 0x81121111, | ||
313 | 0xA00, 0x00D047C8, | ||
314 | 0xA04, 0x80FF000C, | ||
315 | 0xA08, 0x8C838300, | ||
316 | 0xA0C, 0x2E68120F, | ||
317 | 0xA10, 0x9500BB78, | ||
318 | 0xA14, 0x11144028, | ||
319 | 0xA18, 0x00881117, | ||
320 | 0xA1C, 0x89140F00, | ||
321 | 0xA20, 0x1A1B0000, | ||
322 | 0xA24, 0x090E1317, | ||
323 | 0xA28, 0x00000204, | ||
324 | 0xA2C, 0x00D30000, | ||
325 | 0xA70, 0x101FBF00, | ||
326 | 0xA74, 0x00000007, | ||
327 | 0xA78, 0x00000900, | ||
328 | 0xC00, 0x48071D40, | ||
329 | 0xC04, 0x03A05611, | ||
330 | 0xC08, 0x000000E4, | ||
331 | 0xC0C, 0x6C6C6C6C, | ||
332 | 0xC10, 0x08800000, | ||
333 | 0xC14, 0x40000100, | ||
334 | 0xC18, 0x08800000, | ||
335 | 0xC1C, 0x40000100, | ||
336 | 0xC20, 0x00000000, | ||
337 | 0xC24, 0x00000000, | ||
338 | 0xC28, 0x00000000, | ||
339 | 0xC2C, 0x00000000, | ||
340 | 0xC30, 0x69E9AC44, | ||
341 | 0xFF0F011F, 0xABCD, | ||
342 | 0xC34, 0x469652CF, | ||
343 | 0xCDCDCDCD, 0xCDCD, | ||
344 | 0xC34, 0x469652AF, | ||
345 | 0xFF0F011F, 0xDEAD, | ||
346 | 0xC38, 0x49795994, | ||
347 | 0xC3C, 0x0A97971C, | ||
348 | 0xC40, 0x1F7C403F, | ||
349 | 0xC44, 0x000100B7, | ||
350 | 0xC48, 0xEC020107, | ||
351 | 0xC4C, 0x007F037F, | ||
352 | 0xC50, 0x69543420, | ||
353 | 0xC54, 0x43BC0094, | ||
354 | 0xC58, 0x69543420, | ||
355 | 0xC5C, 0x433C0094, | ||
356 | 0xC60, 0x00000000, | ||
357 | 0xFF0F011F, 0xABCD, | ||
358 | 0xC64, 0x7116848B, | ||
359 | 0xCDCDCDCD, 0xCDCD, | ||
360 | 0xC64, 0x7112848B, | ||
361 | 0xFF0F011F, 0xDEAD, | ||
362 | 0xC68, 0x47C00BFF, | ||
363 | 0xC6C, 0x00000036, | ||
364 | 0xC70, 0x2C7F000D, | ||
365 | 0xC74, 0x018610DB, | ||
366 | 0xC78, 0x0000001F, | ||
367 | 0xC7C, 0x00B91612, | ||
368 | 0xC80, 0x40000100, | ||
369 | 0xC84, 0x20F60000, | ||
370 | 0xC88, 0x40000100, | ||
371 | 0xC8C, 0x20200000, | ||
372 | 0xC90, 0x00121820, | ||
373 | 0xC94, 0x00000000, | ||
374 | 0xC98, 0x00121820, | ||
375 | 0xC9C, 0x00007F7F, | ||
376 | 0xCA0, 0x00000000, | ||
377 | 0xCA4, 0x00000080, | ||
378 | 0xCA8, 0x00000000, | ||
379 | 0xCAC, 0x00000000, | ||
380 | 0xCB0, 0x00000000, | ||
381 | 0xCB4, 0x00000000, | ||
382 | 0xCB8, 0x00000000, | ||
383 | 0xCBC, 0x28000000, | ||
384 | 0xCC0, 0x00000000, | ||
385 | 0xCC4, 0x00000000, | ||
386 | 0xCC8, 0x00000000, | ||
387 | 0xCCC, 0x00000000, | ||
388 | 0xCD0, 0x00000000, | ||
389 | 0xCD4, 0x00000000, | ||
390 | 0xCD8, 0x64B22427, | ||
391 | 0xCDC, 0x00766932, | ||
392 | 0xCE0, 0x00222222, | ||
393 | 0xCE4, 0x00000000, | ||
394 | 0xCE8, 0x37644302, | ||
395 | 0xCEC, 0x2F97D40C, | ||
396 | 0xD00, 0x00080740, | ||
397 | 0xD04, 0x00020401, | ||
398 | 0xD08, 0x0000907F, | ||
399 | 0xD0C, 0x20010201, | ||
400 | 0xD10, 0xA0633333, | ||
401 | 0xD14, 0x3333BC43, | ||
402 | 0xD18, 0x7A8F5B6B, | ||
403 | 0xD2C, 0xCC979975, | ||
404 | 0xD30, 0x00000000, | ||
405 | 0xD34, 0x80608000, | ||
406 | 0xD38, 0x00000000, | ||
407 | 0xD3C, 0x00027293, | ||
408 | 0xD40, 0x00000000, | ||
409 | 0xD44, 0x00000000, | ||
410 | 0xD48, 0x00000000, | ||
411 | 0xD4C, 0x00000000, | ||
412 | 0xD50, 0x6437140A, | ||
413 | 0xD54, 0x00000000, | ||
414 | 0xD58, 0x00000000, | ||
415 | 0xD5C, 0x30032064, | ||
416 | 0xD60, 0x4653DE68, | ||
417 | 0xD64, 0x04518A3C, | ||
418 | 0xD68, 0x00002101, | ||
419 | 0xD6C, 0x2A201C16, | ||
420 | 0xD70, 0x1812362E, | ||
421 | 0xD74, 0x322C2220, | ||
422 | 0xD78, 0x000E3C24, | ||
423 | 0xE00, 0x2A2A2A2A, | ||
424 | 0xE04, 0x2A2A2A2A, | ||
425 | 0xE08, 0x03902A2A, | ||
426 | 0xE10, 0x2A2A2A2A, | ||
427 | 0xE14, 0x2A2A2A2A, | ||
428 | 0xE18, 0x2A2A2A2A, | ||
429 | 0xE1C, 0x2A2A2A2A, | ||
430 | 0xE28, 0x00000000, | ||
431 | 0xE30, 0x1000DC1F, | ||
432 | 0xE34, 0x10008C1F, | ||
433 | 0xE38, 0x02140102, | ||
434 | 0xE3C, 0x681604C2, | ||
435 | 0xE40, 0x01007C00, | ||
436 | 0xE44, 0x01004800, | ||
437 | 0xE48, 0xFB000000, | ||
438 | 0xE4C, 0x000028D1, | ||
439 | 0xE50, 0x1000DC1F, | ||
440 | 0xE54, 0x10008C1F, | ||
441 | 0xE58, 0x02140102, | ||
442 | 0xE5C, 0x28160D05, | ||
443 | 0xE60, 0x00000008, | ||
444 | 0xE68, 0x001B25A4, | ||
445 | 0xE6C, 0x631B25A0, | ||
446 | 0xE70, 0x631B25A0, | ||
447 | 0xE74, 0x081B25A0, | ||
448 | 0xE78, 0x081B25A0, | ||
449 | 0xE7C, 0x081B25A0, | ||
450 | 0xE80, 0x081B25A0, | ||
451 | 0xE84, 0x631B25A0, | ||
452 | 0xE88, 0x081B25A0, | ||
453 | 0xE8C, 0x631B25A0, | ||
454 | 0xED0, 0x631B25A0, | ||
455 | 0xED4, 0x631B25A0, | ||
456 | 0xED8, 0x631B25A0, | ||
457 | 0xEDC, 0x001B25A0, | ||
458 | 0xEE0, 0x001B25A0, | ||
459 | 0xEEC, 0x6B1B25A0, | ||
460 | 0xF14, 0x00000003, | ||
461 | 0xF4C, 0x00000000, | ||
462 | 0xF00, 0x00000300, | ||
463 | }; | ||
464 | |||
465 | void ODM_ReadAndConfig_PHY_REG_1T_8723A(struct dm_odm_t *pDM_Odm) | ||
466 | { | ||
467 | u32 hex = 0; | ||
468 | u32 i = 0; | ||
469 | u8 platform = 0x04; | ||
470 | u8 interfaceValue = pDM_Odm->SupportInterface; | ||
471 | u8 board = pDM_Odm->BoardType; | ||
472 | u32 ArrayLen = sizeof(Array_PHY_REG_1T_8723A)/sizeof(u32); | ||
473 | u32 *Array = Array_PHY_REG_1T_8723A; | ||
474 | |||
475 | hex += board; | ||
476 | hex += interfaceValue << 8; | ||
477 | hex += platform << 16; | ||
478 | hex += 0xFF000000; | ||
479 | for (i = 0; i < ArrayLen; i += 2) { | ||
480 | u32 v1 = Array[i]; | ||
481 | u32 v2 = Array[i+1]; | ||
482 | |||
483 | /* This (offset, data) pair meets the condition. */ | ||
484 | if (v1 < 0xCDCDCDCD) { | ||
485 | odm_ConfigBB_PHY_8723A(pDM_Odm, v1, bMaskDWord, v2); | ||
486 | continue; | ||
487 | } else { | ||
488 | if (!CheckCondition(Array[i], hex)) { | ||
489 | /* Discard the following (offset, data) pairs. */ | ||
490 | READ_NEXT_PAIR(v1, v2, i); | ||
491 | while (v2 != 0xDEAD && | ||
492 | v2 != 0xCDEF && | ||
493 | v2 != 0xCDCD && i < ArrayLen - 2) | ||
494 | READ_NEXT_PAIR(v1, v2, i); | ||
495 | i -= 2; /* prevent from for-loop += 2 */ | ||
496 | } else { | ||
497 | /* Configure matched pairs and skip to end of if-else. */ | ||
498 | READ_NEXT_PAIR(v1, v2, i); | ||
499 | while (v2 != 0xDEAD && | ||
500 | v2 != 0xCDEF && | ||
501 | v2 != 0xCDCD && i < ArrayLen - 2) { | ||
502 | odm_ConfigBB_PHY_8723A(pDM_Odm, v1, bMaskDWord, v2); | ||
503 | READ_NEXT_PAIR(v1, v2, i); | ||
504 | } | ||
505 | while (v2 != 0xDEAD && i < ArrayLen - 2) | ||
506 | READ_NEXT_PAIR(v1, v2, i); | ||
507 | } | ||
508 | } | ||
509 | } | ||
510 | } | ||
511 | |||
512 | /****************************************************************************** | ||
513 | * PHY_REG_MP.TXT | ||
514 | ******************************************************************************/ | ||
515 | |||
516 | static u32 Array_PHY_REG_MP_8723A[] = { | ||
517 | 0xC30, 0x69E9AC4A, | ||
518 | 0xC3C, 0x0A979718, | ||
519 | }; | ||
520 | |||
521 | void ODM_ReadAndConfig_PHY_REG_MP_8723A(struct dm_odm_t *pDM_Odm) | ||
522 | { | ||
523 | u32 hex = 0; | ||
524 | u32 i = 0; | ||
525 | u8 platform = 0x04; | ||
526 | u8 interfaceValue = pDM_Odm->SupportInterface; | ||
527 | u8 board = pDM_Odm->BoardType; | ||
528 | u32 ArrayLen = sizeof(Array_PHY_REG_MP_8723A)/sizeof(u32); | ||
529 | u32 *Array = Array_PHY_REG_MP_8723A; | ||
530 | |||
531 | hex += board; | ||
532 | hex += interfaceValue << 8; | ||
533 | hex += platform << 16; | ||
534 | hex += 0xFF000000; | ||
535 | for (i = 0; i < ArrayLen; i += 2) { | ||
536 | u32 v1 = Array[i]; | ||
537 | u32 v2 = Array[i+1]; | ||
538 | |||
539 | /* This (offset, data) pair meets the condition. */ | ||
540 | if (v1 < 0xCDCDCDCD) { | ||
541 | odm_ConfigBB_PHY_8723A(pDM_Odm, v1, bMaskDWord, v2); | ||
542 | continue; | ||
543 | } else { | ||
544 | if (!CheckCondition(Array[i], hex)) { | ||
545 | /* Discard the following (offset, data) pairs. */ | ||
546 | READ_NEXT_PAIR(v1, v2, i); | ||
547 | while (v2 != 0xDEAD && | ||
548 | v2 != 0xCDEF && | ||
549 | v2 != 0xCDCD && i < ArrayLen - 2) | ||
550 | READ_NEXT_PAIR(v1, v2, i); | ||
551 | i -= 2; /* prevent from for-loop += 2 */ | ||
552 | } else { | ||
553 | /* Configure matched pairs and skip to end of if-else. */ | ||
554 | READ_NEXT_PAIR(v1, v2, i); | ||
555 | while (v2 != 0xDEAD && | ||
556 | v2 != 0xCDEF && | ||
557 | v2 != 0xCDCD && i < ArrayLen - 2) { | ||
558 | odm_ConfigBB_PHY_8723A(pDM_Odm, v1, bMaskDWord, v2); | ||
559 | READ_NEXT_PAIR(v1, v2, i); | ||
560 | } | ||
561 | while (v2 != 0xDEAD && i < ArrayLen - 2) | ||
562 | READ_NEXT_PAIR(v1, v2, i); | ||
563 | } | ||
564 | } | ||
565 | } | ||
566 | } | ||
567 | |||
568 | /****************************************************************************** | ||
569 | * PHY_REG_PG.TXT | ||
570 | ******************************************************************************/ | ||
571 | |||
572 | static u32 Array_PHY_REG_PG_8723A[] = { | ||
573 | 0xE00, 0xFFFFFFFF, 0x0A0C0C0C, | ||
574 | 0xE04, 0xFFFFFFFF, 0x02040608, | ||
575 | 0xE08, 0x0000FF00, 0x00000000, | ||
576 | 0x86C, 0xFFFFFF00, 0x00000000, | ||
577 | 0xE10, 0xFFFFFFFF, 0x0A0C0D0E, | ||
578 | 0xE14, 0xFFFFFFFF, 0x02040608, | ||
579 | 0xE18, 0xFFFFFFFF, 0x0A0C0D0E, | ||
580 | 0xE1C, 0xFFFFFFFF, 0x02040608, | ||
581 | 0x830, 0xFFFFFFFF, 0x0A0C0C0C, | ||
582 | 0x834, 0xFFFFFFFF, 0x02040608, | ||
583 | 0x838, 0xFFFFFF00, 0x00000000, | ||
584 | 0x86C, 0x000000FF, 0x00000000, | ||
585 | 0x83C, 0xFFFFFFFF, 0x0A0C0D0E, | ||
586 | 0x848, 0xFFFFFFFF, 0x02040608, | ||
587 | 0x84C, 0xFFFFFFFF, 0x0A0C0D0E, | ||
588 | 0x868, 0xFFFFFFFF, 0x02040608, | ||
589 | 0xE00, 0xFFFFFFFF, 0x00000000, | ||
590 | 0xE04, 0xFFFFFFFF, 0x00000000, | ||
591 | 0xE08, 0x0000FF00, 0x00000000, | ||
592 | 0x86C, 0xFFFFFF00, 0x00000000, | ||
593 | 0xE10, 0xFFFFFFFF, 0x00000000, | ||
594 | 0xE14, 0xFFFFFFFF, 0x00000000, | ||
595 | 0xE18, 0xFFFFFFFF, 0x00000000, | ||
596 | 0xE1C, 0xFFFFFFFF, 0x00000000, | ||
597 | 0x830, 0xFFFFFFFF, 0x00000000, | ||
598 | 0x834, 0xFFFFFFFF, 0x00000000, | ||
599 | 0x838, 0xFFFFFF00, 0x00000000, | ||
600 | 0x86C, 0x000000FF, 0x00000000, | ||
601 | 0x83C, 0xFFFFFFFF, 0x00000000, | ||
602 | 0x848, 0xFFFFFFFF, 0x00000000, | ||
603 | 0x84C, 0xFFFFFFFF, 0x00000000, | ||
604 | 0x868, 0xFFFFFFFF, 0x00000000, | ||
605 | 0xE00, 0xFFFFFFFF, 0x04040404, | ||
606 | 0xE04, 0xFFFFFFFF, 0x00020204, | ||
607 | 0xE08, 0x0000FF00, 0x00000000, | ||
608 | 0x86C, 0xFFFFFF00, 0x00000000, | ||
609 | 0xE10, 0xFFFFFFFF, 0x06060606, | ||
610 | 0xE14, 0xFFFFFFFF, 0x00020406, | ||
611 | 0xE18, 0xFFFFFFFF, 0x00000000, | ||
612 | 0xE1C, 0xFFFFFFFF, 0x00000000, | ||
613 | 0x830, 0xFFFFFFFF, 0x04040404, | ||
614 | 0x834, 0xFFFFFFFF, 0x00020204, | ||
615 | 0x838, 0xFFFFFF00, 0x00000000, | ||
616 | 0x86C, 0x000000FF, 0x00000000, | ||
617 | 0x83C, 0xFFFFFFFF, 0x06060606, | ||
618 | 0x848, 0xFFFFFFFF, 0x00020406, | ||
619 | 0x84C, 0xFFFFFFFF, 0x00000000, | ||
620 | 0x868, 0xFFFFFFFF, 0x00000000, | ||
621 | 0xE00, 0xFFFFFFFF, 0x00000000, | ||
622 | 0xE04, 0xFFFFFFFF, 0x00000000, | ||
623 | 0xE08, 0x0000FF00, 0x00000000, | ||
624 | 0x86C, 0xFFFFFF00, 0x00000000, | ||
625 | 0xE10, 0xFFFFFFFF, 0x00000000, | ||
626 | 0xE14, 0xFFFFFFFF, 0x00000000, | ||
627 | 0xE18, 0xFFFFFFFF, 0x00000000, | ||
628 | 0xE1C, 0xFFFFFFFF, 0x00000000, | ||
629 | 0x830, 0xFFFFFFFF, 0x00000000, | ||
630 | 0x834, 0xFFFFFFFF, 0x00000000, | ||
631 | 0x838, 0xFFFFFF00, 0x00000000, | ||
632 | 0x86C, 0x000000FF, 0x00000000, | ||
633 | 0x83C, 0xFFFFFFFF, 0x00000000, | ||
634 | 0x848, 0xFFFFFFFF, 0x00000000, | ||
635 | 0x84C, 0xFFFFFFFF, 0x00000000, | ||
636 | 0x868, 0xFFFFFFFF, 0x00000000, | ||
637 | 0xE00, 0xFFFFFFFF, 0x00000000, | ||
638 | 0xE04, 0xFFFFFFFF, 0x00000000, | ||
639 | 0xE08, 0x0000FF00, 0x00000000, | ||
640 | 0x86C, 0xFFFFFF00, 0x00000000, | ||
641 | 0xE10, 0xFFFFFFFF, 0x00000000, | ||
642 | 0xE14, 0xFFFFFFFF, 0x00000000, | ||
643 | 0xE18, 0xFFFFFFFF, 0x00000000, | ||
644 | 0xE1C, 0xFFFFFFFF, 0x00000000, | ||
645 | 0x830, 0xFFFFFFFF, 0x00000000, | ||
646 | 0x834, 0xFFFFFFFF, 0x00000000, | ||
647 | 0x838, 0xFFFFFF00, 0x00000000, | ||
648 | 0x86C, 0x000000FF, 0x00000000, | ||
649 | 0x83C, 0xFFFFFFFF, 0x00000000, | ||
650 | 0x848, 0xFFFFFFFF, 0x00000000, | ||
651 | 0x84C, 0xFFFFFFFF, 0x00000000, | ||
652 | 0x868, 0xFFFFFFFF, 0x00000000, | ||
653 | 0xE00, 0xFFFFFFFF, 0x04040404, | ||
654 | 0xE04, 0xFFFFFFFF, 0x00020204, | ||
655 | 0xE08, 0x0000FF00, 0x00000000, | ||
656 | 0x86C, 0xFFFFFF00, 0x00000000, | ||
657 | 0xE10, 0xFFFFFFFF, 0x00000000, | ||
658 | 0xE14, 0xFFFFFFFF, 0x00000000, | ||
659 | 0xE18, 0xFFFFFFFF, 0x00000000, | ||
660 | 0xE1C, 0xFFFFFFFF, 0x00000000, | ||
661 | 0x830, 0xFFFFFFFF, 0x04040404, | ||
662 | 0x834, 0xFFFFFFFF, 0x00020204, | ||
663 | 0x838, 0xFFFFFF00, 0x00000000, | ||
664 | 0x86C, 0x000000FF, 0x00000000, | ||
665 | 0x83C, 0xFFFFFFFF, 0x00000000, | ||
666 | 0x848, 0xFFFFFFFF, 0x00000000, | ||
667 | 0x84C, 0xFFFFFFFF, 0x00000000, | ||
668 | 0x868, 0xFFFFFFFF, 0x00000000, | ||
669 | 0xE00, 0xFFFFFFFF, 0x00000000, | ||
670 | 0xE04, 0xFFFFFFFF, 0x00000000, | ||
671 | 0xE08, 0x0000FF00, 0x00000000, | ||
672 | 0x86C, 0xFFFFFF00, 0x00000000, | ||
673 | 0xE10, 0xFFFFFFFF, 0x00000000, | ||
674 | 0xE14, 0xFFFFFFFF, 0x00000000, | ||
675 | 0xE18, 0xFFFFFFFF, 0x00000000, | ||
676 | 0xE1C, 0xFFFFFFFF, 0x00000000, | ||
677 | 0x830, 0xFFFFFFFF, 0x00000000, | ||
678 | 0x834, 0xFFFFFFFF, 0x00000000, | ||
679 | 0x838, 0xFFFFFF00, 0x00000000, | ||
680 | 0x86C, 0x000000FF, 0x00000000, | ||
681 | 0x83C, 0xFFFFFFFF, 0x00000000, | ||
682 | 0x848, 0xFFFFFFFF, 0x00000000, | ||
683 | 0x84C, 0xFFFFFFFF, 0x00000000, | ||
684 | 0x868, 0xFFFFFFFF, 0x00000000, | ||
685 | }; | ||
686 | |||
687 | void ODM_ReadAndConfig_PHY_REG_PG_8723A(struct dm_odm_t *pDM_Odm) | ||
688 | { | ||
689 | u32 hex = 0; | ||
690 | u32 i = 0; | ||
691 | u8 platform = 0x04; | ||
692 | u8 interfaceValue = pDM_Odm->SupportInterface; | ||
693 | u8 board = pDM_Odm->BoardType; | ||
694 | u32 ArrayLen = sizeof(Array_PHY_REG_PG_8723A)/sizeof(u32); | ||
695 | u32 *Array = Array_PHY_REG_PG_8723A; | ||
696 | |||
697 | hex += board; | ||
698 | hex += interfaceValue << 8; | ||
699 | hex += platform << 16; | ||
700 | hex += 0xFF000000; | ||
701 | for (i = 0; i < ArrayLen; i += 3) { | ||
702 | u32 v1 = Array[i]; | ||
703 | u32 v2 = Array[i+1]; | ||
704 | u32 v3 = Array[i+2]; | ||
705 | |||
706 | /* this line is a line of pure_body */ | ||
707 | if (v1 < 0xCDCDCDCD) { | ||
708 | odm_ConfigBB_PHY_REG_PG_8723A(pDM_Odm, v1, v2, v3); | ||
709 | continue; | ||
710 | } else { /* this line is the start of branch */ | ||
711 | if (!CheckCondition(Array[i], hex)) { | ||
712 | /* don't need the hw_body */ | ||
713 | i += 2; /* skip the pair of expression */ | ||
714 | v1 = Array[i]; | ||
715 | v2 = Array[i+1]; | ||
716 | v3 = Array[i+2]; | ||
717 | while (v2 != 0xDEAD) { | ||
718 | i += 3; | ||
719 | v1 = Array[i]; | ||
720 | v2 = Array[i+1]; | ||
721 | v3 = Array[i+1]; | ||
722 | } | ||
723 | } | ||
724 | } | ||
725 | } | ||
726 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/HalHWImg8723A_MAC.c b/drivers/staging/rtl8723au/hal/HalHWImg8723A_MAC.c new file mode 100644 index 000000000000..12071453be97 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/HalHWImg8723A_MAC.c | |||
@@ -0,0 +1,188 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | #include "odm_precomp.h" | ||
17 | |||
18 | static bool CheckCondition(const u32 Condition, const u32 Hex) | ||
19 | { | ||
20 | u32 _board = (Hex & 0x000000FF); | ||
21 | u32 _interface = (Hex & 0x0000FF00) >> 8; | ||
22 | u32 _platform = (Hex & 0x00FF0000) >> 16; | ||
23 | u32 cond = Condition; | ||
24 | |||
25 | if (Condition == 0xCDCDCDCD) | ||
26 | return true; | ||
27 | |||
28 | cond = Condition & 0x000000FF; | ||
29 | if ((_board == cond) && cond != 0x00) | ||
30 | return false; | ||
31 | |||
32 | cond = Condition & 0x0000FF00; | ||
33 | cond = cond >> 8; | ||
34 | if ((_interface & cond) == 0 && cond != 0x07) | ||
35 | return false; | ||
36 | |||
37 | cond = Condition & 0x00FF0000; | ||
38 | cond = cond >> 16; | ||
39 | if ((_platform & cond) == 0 && cond != 0x0F) | ||
40 | return false; | ||
41 | return true; | ||
42 | } | ||
43 | |||
44 | /****************************************************************************** | ||
45 | * MAC_REG.TXT | ||
46 | ******************************************************************************/ | ||
47 | |||
48 | static u32 Array_MAC_REG_8723A[] = { | ||
49 | 0x420, 0x00000080, | ||
50 | 0x423, 0x00000000, | ||
51 | 0x430, 0x00000000, | ||
52 | 0x431, 0x00000000, | ||
53 | 0x432, 0x00000000, | ||
54 | 0x433, 0x00000001, | ||
55 | 0x434, 0x00000004, | ||
56 | 0x435, 0x00000005, | ||
57 | 0x436, 0x00000006, | ||
58 | 0x437, 0x00000007, | ||
59 | 0x438, 0x00000000, | ||
60 | 0x439, 0x00000000, | ||
61 | 0x43A, 0x00000000, | ||
62 | 0x43B, 0x00000001, | ||
63 | 0x43C, 0x00000004, | ||
64 | 0x43D, 0x00000005, | ||
65 | 0x43E, 0x00000006, | ||
66 | 0x43F, 0x00000007, | ||
67 | 0x440, 0x0000005D, | ||
68 | 0x441, 0x00000001, | ||
69 | 0x442, 0x00000000, | ||
70 | 0x444, 0x00000015, | ||
71 | 0x445, 0x000000F0, | ||
72 | 0x446, 0x0000000F, | ||
73 | 0x447, 0x00000000, | ||
74 | 0x458, 0x00000041, | ||
75 | 0x459, 0x000000A8, | ||
76 | 0x45A, 0x00000072, | ||
77 | 0x45B, 0x000000B9, | ||
78 | 0x460, 0x00000066, | ||
79 | 0x461, 0x00000066, | ||
80 | 0x462, 0x00000008, | ||
81 | 0x463, 0x00000003, | ||
82 | 0x4C8, 0x000000FF, | ||
83 | 0x4C9, 0x00000008, | ||
84 | 0x4CC, 0x000000FF, | ||
85 | 0x4CD, 0x000000FF, | ||
86 | 0x4CE, 0x00000001, | ||
87 | 0x500, 0x00000026, | ||
88 | 0x501, 0x000000A2, | ||
89 | 0x502, 0x0000002F, | ||
90 | 0x503, 0x00000000, | ||
91 | 0x504, 0x00000028, | ||
92 | 0x505, 0x000000A3, | ||
93 | 0x506, 0x0000005E, | ||
94 | 0x507, 0x00000000, | ||
95 | 0x508, 0x0000002B, | ||
96 | 0x509, 0x000000A4, | ||
97 | 0x50A, 0x0000005E, | ||
98 | 0x50B, 0x00000000, | ||
99 | 0x50C, 0x0000004F, | ||
100 | 0x50D, 0x000000A4, | ||
101 | 0x50E, 0x00000000, | ||
102 | 0x50F, 0x00000000, | ||
103 | 0x512, 0x0000001C, | ||
104 | 0x514, 0x0000000A, | ||
105 | 0x515, 0x00000010, | ||
106 | 0x516, 0x0000000A, | ||
107 | 0x517, 0x00000010, | ||
108 | 0x51A, 0x00000016, | ||
109 | 0x524, 0x0000000F, | ||
110 | 0x525, 0x0000004F, | ||
111 | 0x546, 0x00000040, | ||
112 | 0x547, 0x00000000, | ||
113 | 0x550, 0x00000010, | ||
114 | 0x551, 0x00000010, | ||
115 | 0x559, 0x00000002, | ||
116 | 0x55A, 0x00000002, | ||
117 | 0x55D, 0x000000FF, | ||
118 | 0x605, 0x00000030, | ||
119 | 0x608, 0x0000000E, | ||
120 | 0x609, 0x0000002A, | ||
121 | 0x652, 0x00000020, | ||
122 | 0x63C, 0x0000000A, | ||
123 | 0x63D, 0x0000000A, | ||
124 | 0x63E, 0x0000000E, | ||
125 | 0x63F, 0x0000000E, | ||
126 | 0x66E, 0x00000005, | ||
127 | 0x700, 0x00000021, | ||
128 | 0x701, 0x00000043, | ||
129 | 0x702, 0x00000065, | ||
130 | 0x703, 0x00000087, | ||
131 | 0x708, 0x00000021, | ||
132 | 0x709, 0x00000043, | ||
133 | 0x70A, 0x00000065, | ||
134 | 0x70B, 0x00000087, | ||
135 | }; | ||
136 | |||
137 | void ODM_ReadAndConfig_MAC_REG_8723A(struct dm_odm_t *pDM_Odm) | ||
138 | { | ||
139 | #define READ_NEXT_PAIR(v1, v2, i) \ | ||
140 | do { \ | ||
141 | i += 2; v1 = Array[i]; v2 = Array[i+1]; \ | ||
142 | } while (0) | ||
143 | |||
144 | u32 hex = 0; | ||
145 | u32 i = 0; | ||
146 | u8 platform = 0x04; | ||
147 | u8 interfaceValue = pDM_Odm->SupportInterface; | ||
148 | u8 board = pDM_Odm->BoardType; | ||
149 | u32 ArrayLen = sizeof(Array_MAC_REG_8723A)/sizeof(u32); | ||
150 | u32 *Array = Array_MAC_REG_8723A; | ||
151 | |||
152 | hex += board; | ||
153 | hex += interfaceValue << 8; | ||
154 | hex += platform << 16; | ||
155 | hex += 0xFF000000; | ||
156 | for (i = 0; i < ArrayLen; i += 2) { | ||
157 | u32 v1 = Array[i]; | ||
158 | u32 v2 = Array[i+1]; | ||
159 | |||
160 | /* This (offset, data) pair meets the condition. */ | ||
161 | if (v1 < 0xCDCDCDCD) { | ||
162 | odm_ConfigMAC_8723A(pDM_Odm, v1, (u8)v2); | ||
163 | continue; | ||
164 | } else { | ||
165 | if (!CheckCondition(Array[i], hex)) { | ||
166 | /* Discard the following (offset, data) pairs. */ | ||
167 | READ_NEXT_PAIR(v1, v2, i); | ||
168 | while (v2 != 0xDEAD && | ||
169 | v2 != 0xCDEF && | ||
170 | v2 != 0xCDCD && i < ArrayLen - 2) | ||
171 | READ_NEXT_PAIR(v1, v2, i); | ||
172 | i -= 2; /* prevent from for-loop += 2 */ | ||
173 | } else { | ||
174 | /* Configure matched pairs and skip to end of if-else. */ | ||
175 | READ_NEXT_PAIR(v1, v2, i); | ||
176 | while (v2 != 0xDEAD && | ||
177 | v2 != 0xCDEF && | ||
178 | v2 != 0xCDCD && i < ArrayLen - 2) { | ||
179 | odm_ConfigMAC_8723A(pDM_Odm, v1, (u8)v2); | ||
180 | READ_NEXT_PAIR(v1, v2, i); | ||
181 | } | ||
182 | |||
183 | while (v2 != 0xDEAD && i < ArrayLen - 2) | ||
184 | READ_NEXT_PAIR(v1, v2, i); | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c b/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c new file mode 100644 index 000000000000..0f2ae05c8eae --- /dev/null +++ b/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c | |||
@@ -0,0 +1,259 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | #include "odm_precomp.h" | ||
17 | |||
18 | static bool CheckCondition(const u32 Condition, const u32 Hex) | ||
19 | { | ||
20 | u32 _board = (Hex & 0x000000FF); | ||
21 | u32 _interface = (Hex & 0x0000FF00) >> 8; | ||
22 | u32 _platform = (Hex & 0x00FF0000) >> 16; | ||
23 | u32 cond = Condition; | ||
24 | |||
25 | if (Condition == 0xCDCDCDCD) | ||
26 | return true; | ||
27 | |||
28 | cond = Condition & 0x000000FF; | ||
29 | if ((_board == cond) && cond != 0x00) | ||
30 | return false; | ||
31 | |||
32 | cond = Condition & 0x0000FF00; | ||
33 | cond = cond >> 8; | ||
34 | if ((_interface & cond) == 0 && cond != 0x07) | ||
35 | return false; | ||
36 | |||
37 | cond = Condition & 0x00FF0000; | ||
38 | cond = cond >> 16; | ||
39 | if ((_platform & cond) == 0 && cond != 0x0F) | ||
40 | return false; | ||
41 | return true; | ||
42 | } | ||
43 | |||
44 | /****************************************************************************** | ||
45 | * RadioA_1T.TXT | ||
46 | ******************************************************************************/ | ||
47 | |||
48 | static u32 Array_RadioA_1T_8723A[] = { | ||
49 | 0x000, 0x00030159, | ||
50 | 0x001, 0x00031284, | ||
51 | 0x002, 0x00098000, | ||
52 | 0xFF0F011F, 0xABCD, | ||
53 | 0x003, 0x00018C63, | ||
54 | 0xCDCDCDCD, 0xCDCD, | ||
55 | 0x003, 0x00039C63, | ||
56 | 0xFF0F011F, 0xDEAD, | ||
57 | 0x004, 0x000210E7, | ||
58 | 0x009, 0x0002044F, | ||
59 | 0x00A, 0x0001A3F1, | ||
60 | 0x00B, 0x00014787, | ||
61 | 0x00C, 0x000896FE, | ||
62 | 0x00D, 0x0000E02C, | ||
63 | 0x00E, 0x00039CE7, | ||
64 | 0x00F, 0x00000451, | ||
65 | 0x019, 0x00000000, | ||
66 | 0x01A, 0x00030355, | ||
67 | 0x01B, 0x00060A00, | ||
68 | 0x01C, 0x000FC378, | ||
69 | 0x01D, 0x000A1250, | ||
70 | 0x01E, 0x0000024F, | ||
71 | 0x01F, 0x00000000, | ||
72 | 0x020, 0x0000B614, | ||
73 | 0x021, 0x0006C000, | ||
74 | 0x022, 0x00000000, | ||
75 | 0x023, 0x00001558, | ||
76 | 0x024, 0x00000060, | ||
77 | 0x025, 0x00000483, | ||
78 | 0x026, 0x0004F000, | ||
79 | 0x027, 0x000EC7D9, | ||
80 | 0x028, 0x00057730, | ||
81 | 0x029, 0x00004783, | ||
82 | 0x02A, 0x00000001, | ||
83 | 0x02B, 0x00021334, | ||
84 | 0x02A, 0x00000000, | ||
85 | 0x02B, 0x00000054, | ||
86 | 0x02A, 0x00000001, | ||
87 | 0x02B, 0x00000808, | ||
88 | 0x02B, 0x00053333, | ||
89 | 0x02C, 0x0000000C, | ||
90 | 0x02A, 0x00000002, | ||
91 | 0x02B, 0x00000808, | ||
92 | 0x02B, 0x0005B333, | ||
93 | 0x02C, 0x0000000D, | ||
94 | 0x02A, 0x00000003, | ||
95 | 0x02B, 0x00000808, | ||
96 | 0x02B, 0x00063333, | ||
97 | 0x02C, 0x0000000D, | ||
98 | 0x02A, 0x00000004, | ||
99 | 0x02B, 0x00000808, | ||
100 | 0x02B, 0x0006B333, | ||
101 | 0x02C, 0x0000000D, | ||
102 | 0x02A, 0x00000005, | ||
103 | 0x02B, 0x00000808, | ||
104 | 0x02B, 0x00073333, | ||
105 | 0x02C, 0x0000000D, | ||
106 | 0x02A, 0x00000006, | ||
107 | 0x02B, 0x00000709, | ||
108 | 0x02B, 0x0005B333, | ||
109 | 0x02C, 0x0000000D, | ||
110 | 0x02A, 0x00000007, | ||
111 | 0x02B, 0x00000709, | ||
112 | 0x02B, 0x00063333, | ||
113 | 0x02C, 0x0000000D, | ||
114 | 0x02A, 0x00000008, | ||
115 | 0x02B, 0x0000060A, | ||
116 | 0x02B, 0x0004B333, | ||
117 | 0x02C, 0x0000000D, | ||
118 | 0x02A, 0x00000009, | ||
119 | 0x02B, 0x0000060A, | ||
120 | 0x02B, 0x00053333, | ||
121 | 0x02C, 0x0000000D, | ||
122 | 0x02A, 0x0000000A, | ||
123 | 0x02B, 0x0000060A, | ||
124 | 0x02B, 0x0005B333, | ||
125 | 0x02C, 0x0000000D, | ||
126 | 0x02A, 0x0000000B, | ||
127 | 0x02B, 0x0000060A, | ||
128 | 0x02B, 0x00063333, | ||
129 | 0x02C, 0x0000000D, | ||
130 | 0x02A, 0x0000000C, | ||
131 | 0x02B, 0x0000060A, | ||
132 | 0x02B, 0x0006B333, | ||
133 | 0x02C, 0x0000000D, | ||
134 | 0x02A, 0x0000000D, | ||
135 | 0x02B, 0x0000060A, | ||
136 | 0x02B, 0x00073333, | ||
137 | 0x02C, 0x0000000D, | ||
138 | 0x02A, 0x0000000E, | ||
139 | 0x02B, 0x0000050B, | ||
140 | 0x02B, 0x00066666, | ||
141 | 0x02C, 0x0000001A, | ||
142 | 0x02A, 0x000E0000, | ||
143 | 0x010, 0x0004000F, | ||
144 | 0x011, 0x000E31FC, | ||
145 | 0x010, 0x0006000F, | ||
146 | 0x011, 0x000FF9F8, | ||
147 | 0x010, 0x0002000F, | ||
148 | 0x011, 0x000203F9, | ||
149 | 0x010, 0x0003000F, | ||
150 | 0x011, 0x000FF500, | ||
151 | 0x010, 0x00000000, | ||
152 | 0x011, 0x00000000, | ||
153 | 0x010, 0x0008000F, | ||
154 | 0x011, 0x0003F100, | ||
155 | 0x010, 0x0009000F, | ||
156 | 0x011, 0x00023100, | ||
157 | 0x012, 0x00032000, | ||
158 | 0x012, 0x00071000, | ||
159 | 0x012, 0x000B0000, | ||
160 | 0x012, 0x000FC000, | ||
161 | 0x013, 0x000287B3, | ||
162 | 0x013, 0x000244B7, | ||
163 | 0x013, 0x000204AB, | ||
164 | 0x013, 0x0001C49F, | ||
165 | 0x013, 0x00018493, | ||
166 | 0x013, 0x0001429B, | ||
167 | 0x013, 0x00010299, | ||
168 | 0x013, 0x0000C29C, | ||
169 | 0x013, 0x000081A0, | ||
170 | 0x013, 0x000040AC, | ||
171 | 0x013, 0x00000020, | ||
172 | 0x014, 0x0001944C, | ||
173 | 0x014, 0x00059444, | ||
174 | 0x014, 0x0009944C, | ||
175 | 0x014, 0x000D9444, | ||
176 | 0xFF0F011F, 0xABCD, | ||
177 | 0x015, 0x0000F424, | ||
178 | 0x015, 0x0004F424, | ||
179 | 0x015, 0x0008F424, | ||
180 | 0x015, 0x000CF424, | ||
181 | 0xCDCDCDCD, 0xCDCD, | ||
182 | 0x015, 0x0000F474, | ||
183 | 0x015, 0x0004F477, | ||
184 | 0x015, 0x0008F455, | ||
185 | 0x015, 0x000CF455, | ||
186 | 0xFF0F011F, 0xDEAD, | ||
187 | 0x016, 0x00000339, | ||
188 | 0x016, 0x00040339, | ||
189 | 0x016, 0x00080339, | ||
190 | 0xFF0F011F, 0xABCD, | ||
191 | 0x016, 0x000C0356, | ||
192 | 0xCDCDCDCD, 0xCDCD, | ||
193 | 0x016, 0x000C0366, | ||
194 | 0xFF0F011F, 0xDEAD, | ||
195 | 0x000, 0x00010159, | ||
196 | 0x018, 0x0000F401, | ||
197 | 0x0FE, 0x00000000, | ||
198 | 0x0FE, 0x00000000, | ||
199 | 0x01F, 0x00000003, | ||
200 | 0x0FE, 0x00000000, | ||
201 | 0x0FE, 0x00000000, | ||
202 | 0x01E, 0x00000247, | ||
203 | 0x01F, 0x00000000, | ||
204 | 0x000, 0x00030159, | ||
205 | }; | ||
206 | |||
207 | void ODM_ReadAndConfig_RadioA_1T_8723A(struct dm_odm_t *pDM_Odm) | ||
208 | { | ||
209 | #define READ_NEXT_PAIR(v1, v2, i) \ | ||
210 | do { \ | ||
211 | i += 2; v1 = Array[i]; v2 = Array[i+1];\ | ||
212 | } while (0) | ||
213 | |||
214 | u32 hex = 0; | ||
215 | u32 i = 0; | ||
216 | u8 platform = 0x04; | ||
217 | u8 interfaceValue = pDM_Odm->SupportInterface; | ||
218 | u8 board = pDM_Odm->BoardType; | ||
219 | u32 ArrayLen = sizeof(Array_RadioA_1T_8723A)/sizeof(u32); | ||
220 | u32 *Array = Array_RadioA_1T_8723A; | ||
221 | |||
222 | hex += board; | ||
223 | hex += interfaceValue << 8; | ||
224 | hex += platform << 16; | ||
225 | hex += 0xFF000000; | ||
226 | |||
227 | for (i = 0; i < ArrayLen; i += 2) { | ||
228 | u32 v1 = Array[i]; | ||
229 | u32 v2 = Array[i+1]; | ||
230 | |||
231 | /* This (offset, data) pair meets the condition. */ | ||
232 | if (v1 < 0xCDCDCDCD) { | ||
233 | odm_ConfigRF_RadioA_8723A(pDM_Odm, v1, v2); | ||
234 | continue; | ||
235 | } else { | ||
236 | if (!CheckCondition(Array[i], hex)) { | ||
237 | /* Discard the following (offset, data) pairs. */ | ||
238 | READ_NEXT_PAIR(v1, v2, i); | ||
239 | while (v2 != 0xDEAD && | ||
240 | v2 != 0xCDEF && | ||
241 | v2 != 0xCDCD && i < ArrayLen - 2) | ||
242 | READ_NEXT_PAIR(v1, v2, i); | ||
243 | i -= 2; /* prevent from for-loop += 2 */ | ||
244 | } else { | ||
245 | /* Configure matched pairs and skip to end of if-else. */ | ||
246 | READ_NEXT_PAIR(v1, v2, i); | ||
247 | while (v2 != 0xDEAD && | ||
248 | v2 != 0xCDEF && | ||
249 | v2 != 0xCDCD && i < ArrayLen - 2) { | ||
250 | odm_ConfigRF_RadioA_8723A(pDM_Odm, v1, v2); | ||
251 | READ_NEXT_PAIR(v1, v2, i); | ||
252 | } | ||
253 | |||
254 | while (v2 != 0xDEAD && i < ArrayLen - 2) | ||
255 | READ_NEXT_PAIR(v1, v2, i); | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c b/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c new file mode 100644 index 000000000000..4f6b4b72f922 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | /*++ | ||
16 | Copyright (c) Realtek Semiconductor Corp. All rights reserved. | ||
17 | |||
18 | Module Name: | ||
19 | HalPwrSeqCmd.c | ||
20 | |||
21 | Abstract: | ||
22 | Implement HW Power sequence configuration CMD handling routine for | ||
23 | Realtek devices. | ||
24 | |||
25 | Major Change History: | ||
26 | When Who What | ||
27 | ---------- --------------- ------------------------------- | ||
28 | 2011-10-26 Lucas Modify to be compatible with SD4-CE driver. | ||
29 | 2011-07-07 Roger Create. | ||
30 | |||
31 | --*/ | ||
32 | #include <HalPwrSeqCmd.h> | ||
33 | |||
34 | /* */ | ||
35 | /* Description: */ | ||
36 | /* This routine deal with the Power Configuration CMDs parsing | ||
37 | for RTL8723/RTL8188E Series IC. */ | ||
38 | /* */ | ||
39 | /* Assumption: */ | ||
40 | /* We should follow specific format which was released from | ||
41 | HW SD. */ | ||
42 | /* */ | ||
43 | /* 2011.07.07, added by Roger. */ | ||
44 | /* */ | ||
45 | u8 HalPwrSeqCmdParsing23a(struct rtw_adapter *padapter, u8 CutVersion, | ||
46 | u8 FabVersion, u8 InterfaceType, | ||
47 | struct wlan_pwr_cfg PwrSeqCmd[]) | ||
48 | { | ||
49 | struct wlan_pwr_cfg PwrCfgCmd = { 0 }; | ||
50 | u8 bPollingBit = false; | ||
51 | u32 AryIdx = 0; | ||
52 | u8 value = 0; | ||
53 | u32 offset = 0; | ||
54 | u32 pollingCount = 0; /* polling autoload done. */ | ||
55 | u32 maxPollingCnt = 5000; | ||
56 | |||
57 | do { | ||
58 | PwrCfgCmd = PwrSeqCmd[AryIdx]; | ||
59 | |||
60 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
61 | ("HalPwrSeqCmdParsing23a: offset(%#x) cut_msk(%#x) " | ||
62 | "fab_msk(%#x) interface_msk(%#x) base(%#x) cmd(%#x) " | ||
63 | "msk(%#x) value(%#x)\n", | ||
64 | GET_PWR_CFG_OFFSET(PwrCfgCmd), | ||
65 | GET_PWR_CFG_CUT_MASK(PwrCfgCmd), | ||
66 | GET_PWR_CFG_FAB_MASK(PwrCfgCmd), | ||
67 | GET_PWR_CFG_INTF_MASK(PwrCfgCmd), | ||
68 | GET_PWR_CFG_BASE(PwrCfgCmd), | ||
69 | GET_PWR_CFG_CMD(PwrCfgCmd), | ||
70 | GET_PWR_CFG_MASK(PwrCfgCmd), | ||
71 | GET_PWR_CFG_VALUE(PwrCfgCmd))); | ||
72 | |||
73 | /* 2 Only Handle the command whose FAB, CUT, and Interface are | ||
74 | matched */ | ||
75 | if ((GET_PWR_CFG_FAB_MASK(PwrCfgCmd) & FabVersion) && | ||
76 | (GET_PWR_CFG_CUT_MASK(PwrCfgCmd) & CutVersion) && | ||
77 | (GET_PWR_CFG_INTF_MASK(PwrCfgCmd) & InterfaceType)) { | ||
78 | switch (GET_PWR_CFG_CMD(PwrCfgCmd)) { | ||
79 | case PWR_CMD_READ: | ||
80 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
81 | ("HalPwrSeqCmdParsing23a: " | ||
82 | "PWR_CMD_READ\n")); | ||
83 | break; | ||
84 | |||
85 | case PWR_CMD_WRITE: | ||
86 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
87 | ("HalPwrSeqCmdParsing23a: " | ||
88 | "PWR_CMD_WRITE\n")); | ||
89 | offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); | ||
90 | |||
91 | /* Read the value from system register */ | ||
92 | value = rtw_read8(padapter, offset); | ||
93 | |||
94 | value &= ~(GET_PWR_CFG_MASK(PwrCfgCmd)); | ||
95 | value |= (GET_PWR_CFG_VALUE(PwrCfgCmd) & | ||
96 | GET_PWR_CFG_MASK(PwrCfgCmd)); | ||
97 | |||
98 | /* Write the value back to sytem register */ | ||
99 | rtw_write8(padapter, offset, value); | ||
100 | break; | ||
101 | |||
102 | case PWR_CMD_POLLING: | ||
103 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
104 | ("HalPwrSeqCmdParsing23a: " | ||
105 | "PWR_CMD_POLLING\n")); | ||
106 | |||
107 | bPollingBit = false; | ||
108 | offset = GET_PWR_CFG_OFFSET(PwrCfgCmd); | ||
109 | do { | ||
110 | value = rtw_read8(padapter, offset); | ||
111 | |||
112 | value &= GET_PWR_CFG_MASK(PwrCfgCmd); | ||
113 | if (value == | ||
114 | (GET_PWR_CFG_VALUE(PwrCfgCmd) & | ||
115 | GET_PWR_CFG_MASK(PwrCfgCmd))) | ||
116 | bPollingBit = true; | ||
117 | else | ||
118 | udelay(10); | ||
119 | |||
120 | if (pollingCount++ > maxPollingCnt) { | ||
121 | DBG_8723A("Fail to polling " | ||
122 | "Offset[%#x]\n", | ||
123 | offset); | ||
124 | return false; | ||
125 | } | ||
126 | } while (!bPollingBit); | ||
127 | |||
128 | break; | ||
129 | |||
130 | case PWR_CMD_DELAY: | ||
131 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
132 | ("HalPwrSeqCmdParsing23a: " | ||
133 | "PWR_CMD_DELAY\n")); | ||
134 | if (GET_PWR_CFG_VALUE(PwrCfgCmd) == | ||
135 | PWRSEQ_DELAY_US) | ||
136 | udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd)); | ||
137 | else | ||
138 | udelay(GET_PWR_CFG_OFFSET(PwrCfgCmd) * | ||
139 | 1000); | ||
140 | break; | ||
141 | |||
142 | case PWR_CMD_END: | ||
143 | /* When this command is parsed, end | ||
144 | the process */ | ||
145 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
146 | ("HalPwrSeqCmdParsing23a: " | ||
147 | "PWR_CMD_END\n")); | ||
148 | return true; | ||
149 | break; | ||
150 | |||
151 | default: | ||
152 | RT_TRACE(_module_hal_init_c_, _drv_err_, | ||
153 | ("HalPwrSeqCmdParsing23a: " | ||
154 | "Unknown CMD!!\n")); | ||
155 | break; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | AryIdx++; /* Add Array Index */ | ||
160 | } while (1); | ||
161 | |||
162 | return true; | ||
163 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/hal_com.c b/drivers/staging/rtl8723au/hal/hal_com.c new file mode 100644 index 000000000000..0640f3522136 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/hal_com.c | |||
@@ -0,0 +1,881 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | #include <osdep_service.h> | ||
16 | #include <drv_types.h> | ||
17 | |||
18 | #include <hal_intf.h> | ||
19 | #include <hal_com.h> | ||
20 | #include <rtl8723a_hal.h> | ||
21 | |||
22 | #define _HAL_INIT_C_ | ||
23 | |||
24 | void dump_chip_info23a(struct hal_version ChipVersion) | ||
25 | { | ||
26 | int cnt = 0; | ||
27 | u8 buf[128]; | ||
28 | |||
29 | cnt += sprintf((buf + cnt), "Chip Version Info: CHIP_8723A_"); | ||
30 | |||
31 | cnt += sprintf((buf + cnt), "%s_", IS_NORMAL_CHIP(ChipVersion) ? | ||
32 | "Normal_Chip" : "Test_Chip"); | ||
33 | cnt += sprintf((buf + cnt), "%s_", | ||
34 | IS_CHIP_VENDOR_TSMC(ChipVersion) ? "TSMC" : "UMC"); | ||
35 | if (IS_A_CUT(ChipVersion)) | ||
36 | cnt += sprintf((buf + cnt), "A_CUT_"); | ||
37 | else if (IS_B_CUT(ChipVersion)) | ||
38 | cnt += sprintf((buf + cnt), "B_CUT_"); | ||
39 | else if (IS_C_CUT(ChipVersion)) | ||
40 | cnt += sprintf((buf + cnt), "C_CUT_"); | ||
41 | else if (IS_D_CUT(ChipVersion)) | ||
42 | cnt += sprintf((buf + cnt), "D_CUT_"); | ||
43 | else if (IS_E_CUT(ChipVersion)) | ||
44 | cnt += sprintf((buf + cnt), "E_CUT_"); | ||
45 | else | ||
46 | cnt += sprintf((buf + cnt), "UNKNOWN_CUT(%d)_", | ||
47 | ChipVersion.CUTVersion); | ||
48 | |||
49 | if (IS_1T1R(ChipVersion)) | ||
50 | cnt += sprintf((buf + cnt), "1T1R_"); | ||
51 | else if (IS_1T2R(ChipVersion)) | ||
52 | cnt += sprintf((buf + cnt), "1T2R_"); | ||
53 | else if (IS_2T2R(ChipVersion)) | ||
54 | cnt += sprintf((buf + cnt), "2T2R_"); | ||
55 | else | ||
56 | cnt += sprintf((buf + cnt), "UNKNOWN_RFTYPE(%d)_", | ||
57 | ChipVersion.RFType); | ||
58 | |||
59 | cnt += sprintf((buf + cnt), "RomVer(%d)\n", ChipVersion.ROMVer); | ||
60 | |||
61 | DBG_8723A("%s", buf); | ||
62 | } | ||
63 | |||
64 | #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 | ||
65 | |||
66 | /* return the final channel plan decision */ | ||
67 | /* hw_channel_plan: channel plan from HW (efuse/eeprom) */ | ||
68 | /* sw_channel_plan: channel plan from SW (registry/module param) */ | ||
69 | /* def_channel_plan: channel plan used when the former two is invalid */ | ||
70 | u8 hal_com_get_channel_plan23a(struct rtw_adapter *padapter, u8 hw_channel_plan, | ||
71 | u8 sw_channel_plan, u8 def_channel_plan, | ||
72 | bool AutoLoadFail) | ||
73 | { | ||
74 | u8 swConfig; | ||
75 | u8 chnlPlan; | ||
76 | |||
77 | swConfig = true; | ||
78 | if (!AutoLoadFail) { | ||
79 | if (!rtw_is_channel_plan_valid(sw_channel_plan)) | ||
80 | swConfig = false; | ||
81 | if (hw_channel_plan & EEPROM_CHANNEL_PLAN_BY_HW_MASK) | ||
82 | swConfig = false; | ||
83 | } | ||
84 | |||
85 | if (swConfig == true) | ||
86 | chnlPlan = sw_channel_plan; | ||
87 | else | ||
88 | chnlPlan = hw_channel_plan & (~EEPROM_CHANNEL_PLAN_BY_HW_MASK); | ||
89 | |||
90 | if (!rtw_is_channel_plan_valid(chnlPlan)) | ||
91 | chnlPlan = def_channel_plan; | ||
92 | |||
93 | return chnlPlan; | ||
94 | } | ||
95 | |||
96 | u8 MRateToHwRate23a(u8 rate) | ||
97 | { | ||
98 | u8 ret = DESC_RATE1M; | ||
99 | |||
100 | switch (rate) { | ||
101 | /* CCK and OFDM non-HT rates */ | ||
102 | case IEEE80211_CCK_RATE_1MB: | ||
103 | ret = DESC_RATE1M; | ||
104 | break; | ||
105 | case IEEE80211_CCK_RATE_2MB: | ||
106 | ret = DESC_RATE2M; | ||
107 | break; | ||
108 | case IEEE80211_CCK_RATE_5MB: | ||
109 | ret = DESC_RATE5_5M; | ||
110 | break; | ||
111 | case IEEE80211_CCK_RATE_11MB: | ||
112 | ret = DESC_RATE11M; | ||
113 | break; | ||
114 | case IEEE80211_OFDM_RATE_6MB: | ||
115 | ret = DESC_RATE6M; | ||
116 | break; | ||
117 | case IEEE80211_OFDM_RATE_9MB: | ||
118 | ret = DESC_RATE9M; | ||
119 | break; | ||
120 | case IEEE80211_OFDM_RATE_12MB: | ||
121 | ret = DESC_RATE12M; | ||
122 | break; | ||
123 | case IEEE80211_OFDM_RATE_18MB: | ||
124 | ret = DESC_RATE18M; | ||
125 | break; | ||
126 | case IEEE80211_OFDM_RATE_24MB: | ||
127 | ret = DESC_RATE24M; | ||
128 | break; | ||
129 | case IEEE80211_OFDM_RATE_36MB: | ||
130 | ret = DESC_RATE36M; | ||
131 | break; | ||
132 | case IEEE80211_OFDM_RATE_48MB: | ||
133 | ret = DESC_RATE48M; | ||
134 | break; | ||
135 | case IEEE80211_OFDM_RATE_54MB: | ||
136 | ret = DESC_RATE54M; | ||
137 | break; | ||
138 | |||
139 | /* HT rates since here */ | ||
140 | /* case MGN_MCS0: ret = DESC_RATEMCS0; break; */ | ||
141 | /* case MGN_MCS1: ret = DESC_RATEMCS1; break; */ | ||
142 | /* case MGN_MCS2: ret = DESC_RATEMCS2; break; */ | ||
143 | /* case MGN_MCS3: ret = DESC_RATEMCS3; break; */ | ||
144 | /* case MGN_MCS4: ret = DESC_RATEMCS4; break; */ | ||
145 | /* case MGN_MCS5: ret = DESC_RATEMCS5; break; */ | ||
146 | /* case MGN_MCS6: ret = DESC_RATEMCS6; break; */ | ||
147 | /* case MGN_MCS7: ret = DESC_RATEMCS7; break; */ | ||
148 | |||
149 | default: | ||
150 | break; | ||
151 | } | ||
152 | return ret; | ||
153 | } | ||
154 | |||
155 | void HalSetBrateCfg23a(struct rtw_adapter *padapter, u8 *mBratesOS) | ||
156 | { | ||
157 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
158 | u8 i, is_brate, brate; | ||
159 | u16 brate_cfg = 0; | ||
160 | u8 rate_index; | ||
161 | |||
162 | for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { | ||
163 | is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK; | ||
164 | brate = mBratesOS[i] & 0x7f; | ||
165 | |||
166 | if (is_brate) { | ||
167 | switch (brate) { | ||
168 | case IEEE80211_CCK_RATE_1MB: | ||
169 | brate_cfg |= RATE_1M; | ||
170 | break; | ||
171 | case IEEE80211_CCK_RATE_2MB: | ||
172 | brate_cfg |= RATE_2M; | ||
173 | break; | ||
174 | case IEEE80211_CCK_RATE_5MB: | ||
175 | brate_cfg |= RATE_5_5M; | ||
176 | break; | ||
177 | case IEEE80211_CCK_RATE_11MB: | ||
178 | brate_cfg |= RATE_11M; | ||
179 | break; | ||
180 | case IEEE80211_OFDM_RATE_6MB: | ||
181 | brate_cfg |= RATE_6M; | ||
182 | break; | ||
183 | case IEEE80211_OFDM_RATE_9MB: | ||
184 | brate_cfg |= RATE_9M; | ||
185 | break; | ||
186 | case IEEE80211_OFDM_RATE_12MB: | ||
187 | brate_cfg |= RATE_12M; | ||
188 | break; | ||
189 | case IEEE80211_OFDM_RATE_18MB: | ||
190 | brate_cfg |= RATE_18M; | ||
191 | break; | ||
192 | case IEEE80211_OFDM_RATE_24MB: | ||
193 | brate_cfg |= RATE_24M; | ||
194 | break; | ||
195 | case IEEE80211_OFDM_RATE_36MB: | ||
196 | brate_cfg |= RATE_36M; | ||
197 | break; | ||
198 | case IEEE80211_OFDM_RATE_48MB: | ||
199 | brate_cfg |= RATE_48M; | ||
200 | break; | ||
201 | case IEEE80211_OFDM_RATE_54MB: | ||
202 | brate_cfg |= RATE_54M; | ||
203 | break; | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | |||
208 | /* 2007.01.16, by Emily */ | ||
209 | /* Select RRSR (in Legacy-OFDM and CCK) */ | ||
210 | /* For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, | ||
211 | and 1M from the Basic rate. */ | ||
212 | /* We do not use other rates. */ | ||
213 | /* 2011.03.30 add by Luke Lee */ | ||
214 | /* CCK 2M ACK should be disabled for some BCM and Atheros AP IOT */ | ||
215 | /* because CCK 2M has poor TXEVM */ | ||
216 | /* CCK 5.5M & 11M ACK should be enabled for better | ||
217 | performance */ | ||
218 | |||
219 | brate_cfg = (brate_cfg | 0xd) & 0x15d; | ||
220 | pHalData->BasicRateSet = brate_cfg; | ||
221 | brate_cfg |= 0x01; /* default enable 1M ACK rate */ | ||
222 | DBG_8723A("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", brate_cfg); | ||
223 | |||
224 | /* Set RRSR rate table. */ | ||
225 | rtw_write8(padapter, REG_RRSR, brate_cfg & 0xff); | ||
226 | rtw_write8(padapter, REG_RRSR + 1, (brate_cfg >> 8) & 0xff); | ||
227 | rtw_write8(padapter, REG_RRSR + 2, | ||
228 | rtw_read8(padapter, REG_RRSR + 2) & 0xf0); | ||
229 | |||
230 | rate_index = 0; | ||
231 | /* Set RTS initial rate */ | ||
232 | while (brate_cfg > 0x1) { | ||
233 | brate_cfg = (brate_cfg >> 1); | ||
234 | rate_index++; | ||
235 | } | ||
236 | /* Ziv - Check */ | ||
237 | rtw_write8(padapter, REG_INIRTS_RATE_SEL, rate_index); | ||
238 | |||
239 | return; | ||
240 | } | ||
241 | |||
242 | static void _OneOutPipeMapping(struct rtw_adapter *pAdapter) | ||
243 | { | ||
244 | struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter); | ||
245 | |||
246 | pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */ | ||
247 | pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0]; /* VI */ | ||
248 | pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0]; /* BE */ | ||
249 | pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0]; /* BK */ | ||
250 | |||
251 | pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */ | ||
252 | pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */ | ||
253 | pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */ | ||
254 | pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD */ | ||
255 | } | ||
256 | |||
257 | static void _TwoOutPipeMapping(struct rtw_adapter *pAdapter, bool bWIFICfg) | ||
258 | { | ||
259 | struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter); | ||
260 | |||
261 | if (bWIFICfg) { /* WMM */ | ||
262 | /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ | ||
263 | /* 0, 1, 0, 1, 0, 0, 0, 0, 0 }; */ | ||
264 | /* 0:H, 1:L */ | ||
265 | pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1]; /* VO */ | ||
266 | pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0]; /* VI */ | ||
267 | pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1]; /* BE */ | ||
268 | pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0]; /* BK */ | ||
269 | |||
270 | pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */ | ||
271 | pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */ | ||
272 | pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */ | ||
273 | pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/ | ||
274 | } else { /* typical setting */ | ||
275 | /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ | ||
276 | /* 1, 1, 0, 0, 0, 0, 0, 0, 0 }; */ | ||
277 | /* 0:H, 1:L */ | ||
278 | pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */ | ||
279 | pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0]; /* VI */ | ||
280 | pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1]; /* BE */ | ||
281 | pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1]; /* BK */ | ||
282 | |||
283 | pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */ | ||
284 | pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */ | ||
285 | pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */ | ||
286 | pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/ | ||
287 | } | ||
288 | } | ||
289 | |||
290 | static void _ThreeOutPipeMapping(struct rtw_adapter *pAdapter, bool bWIFICfg) | ||
291 | { | ||
292 | struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter); | ||
293 | |||
294 | if (bWIFICfg) { /* for WMM */ | ||
295 | /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ | ||
296 | /* 1, 2, 1, 0, 0, 0, 0, 0, 0 }; */ | ||
297 | /* 0:H, 1:N, 2:L */ | ||
298 | pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */ | ||
299 | pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1]; /* VI */ | ||
300 | pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2]; /* BE */ | ||
301 | pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1]; /* BK */ | ||
302 | |||
303 | pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */ | ||
304 | pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */ | ||
305 | pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */ | ||
306 | pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/ | ||
307 | } else { /* typical setting */ | ||
308 | /* BK, BE, VI, VO, BCN, CMD, MGT, HIGH, HCCA */ | ||
309 | /* 2, 2, 1, 0, 0, 0, 0, 0, 0 }; */ | ||
310 | /* 0:H, 1:N, 2:L */ | ||
311 | pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */ | ||
312 | pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1]; /* VI */ | ||
313 | pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2]; /* BE */ | ||
314 | pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2]; /* BK */ | ||
315 | |||
316 | pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */ | ||
317 | pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */ | ||
318 | pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */ | ||
319 | pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/ | ||
320 | } | ||
321 | } | ||
322 | |||
323 | bool Hal_MappingOutPipe23a(struct rtw_adapter *pAdapter, u8 NumOutPipe) | ||
324 | { | ||
325 | struct registry_priv *pregistrypriv = &pAdapter->registrypriv; | ||
326 | bool bWIFICfg = (pregistrypriv->wifi_spec) ? true : false; | ||
327 | bool result = true; | ||
328 | |||
329 | switch (NumOutPipe) { | ||
330 | case 2: | ||
331 | _TwoOutPipeMapping(pAdapter, bWIFICfg); | ||
332 | break; | ||
333 | case 3: | ||
334 | _ThreeOutPipeMapping(pAdapter, bWIFICfg); | ||
335 | break; | ||
336 | case 1: | ||
337 | _OneOutPipeMapping(pAdapter); | ||
338 | break; | ||
339 | default: | ||
340 | result = false; | ||
341 | break; | ||
342 | } | ||
343 | |||
344 | return result; | ||
345 | } | ||
346 | |||
347 | void hal_init_macaddr23a(struct rtw_adapter *adapter) | ||
348 | { | ||
349 | rtw_hal_set_hwreg23a(adapter, HW_VAR_MAC_ADDR, | ||
350 | adapter->eeprompriv.mac_addr); | ||
351 | } | ||
352 | |||
353 | /* | ||
354 | * C2H event format: | ||
355 | * Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID | ||
356 | * BITS [127:120] [119:16] [15:8] [7:4] [3:0] | ||
357 | */ | ||
358 | |||
359 | void c2h_evt_clear23a(struct rtw_adapter *adapter) | ||
360 | { | ||
361 | rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); | ||
362 | } | ||
363 | |||
364 | s32 c2h_evt_read23a(struct rtw_adapter *adapter, u8 *buf) | ||
365 | { | ||
366 | s32 ret = _FAIL; | ||
367 | struct c2h_evt_hdr *c2h_evt; | ||
368 | int i; | ||
369 | u8 trigger; | ||
370 | |||
371 | if (buf == NULL) | ||
372 | goto exit; | ||
373 | |||
374 | trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR); | ||
375 | |||
376 | if (trigger == C2H_EVT_HOST_CLOSE) | ||
377 | goto exit; /* Not ready */ | ||
378 | else if (trigger != C2H_EVT_FW_CLOSE) | ||
379 | goto clear_evt; /* Not a valid value */ | ||
380 | |||
381 | c2h_evt = (struct c2h_evt_hdr *)buf; | ||
382 | |||
383 | memset(c2h_evt, 0, 16); | ||
384 | |||
385 | *buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL); | ||
386 | *(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1); | ||
387 | |||
388 | RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read23a(): ", | ||
389 | &c2h_evt, sizeof(c2h_evt)); | ||
390 | |||
391 | if (0) { | ||
392 | DBG_8723A("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n", | ||
393 | __func__, c2h_evt->id, c2h_evt->plen, c2h_evt->seq, | ||
394 | trigger); | ||
395 | } | ||
396 | |||
397 | /* Read the content */ | ||
398 | for (i = 0; i < c2h_evt->plen; i++) | ||
399 | c2h_evt->payload[i] = rtw_read8(adapter, | ||
400 | REG_C2HEVT_MSG_NORMAL + | ||
401 | sizeof(*c2h_evt) + i); | ||
402 | |||
403 | RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, | ||
404 | "c2h_evt_read23a(): Command Content:\n", c2h_evt->payload, | ||
405 | c2h_evt->plen); | ||
406 | |||
407 | ret = _SUCCESS; | ||
408 | |||
409 | clear_evt: | ||
410 | /* | ||
411 | * Clear event to notify FW we have read the command. | ||
412 | * If this field isn't clear, the FW won't update the | ||
413 | * next command message. | ||
414 | */ | ||
415 | c2h_evt_clear23a(adapter); | ||
416 | exit: | ||
417 | return ret; | ||
418 | } | ||
419 | |||
420 | void | ||
421 | rtl8723a_set_ampdu_min_space(struct rtw_adapter *padapter, u8 MinSpacingToSet) | ||
422 | { | ||
423 | u8 SecMinSpace; | ||
424 | |||
425 | if (MinSpacingToSet <= 7) { | ||
426 | switch (padapter->securitypriv.dot11PrivacyAlgrthm) { | ||
427 | case _NO_PRIVACY_: | ||
428 | case _AES_: | ||
429 | SecMinSpace = 0; | ||
430 | break; | ||
431 | |||
432 | case _WEP40_: | ||
433 | case _WEP104_: | ||
434 | case _TKIP_: | ||
435 | case _TKIP_WTMIC_: | ||
436 | SecMinSpace = 6; | ||
437 | break; | ||
438 | default: | ||
439 | SecMinSpace = 7; | ||
440 | break; | ||
441 | } | ||
442 | |||
443 | if (MinSpacingToSet < SecMinSpace) | ||
444 | MinSpacingToSet = SecMinSpace; | ||
445 | |||
446 | /* RT_TRACE(COMP_MLME, DBG_LOUD, | ||
447 | ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", | ||
448 | padapter->MgntInfo.MinSpaceCfg)); */ | ||
449 | MinSpacingToSet |= | ||
450 | rtw_read8(padapter, REG_AMPDU_MIN_SPACE) & 0xf8; | ||
451 | rtw_write8(padapter, REG_AMPDU_MIN_SPACE, | ||
452 | MinSpacingToSet); | ||
453 | } | ||
454 | } | ||
455 | |||
456 | void rtl8723a_set_ampdu_factor(struct rtw_adapter *padapter, u8 FactorToSet) | ||
457 | { | ||
458 | u8 RegToSet_Normal[4] = { 0x41, 0xa8, 0x72, 0xb9 }; | ||
459 | u8 MaxAggNum; | ||
460 | u8 *pRegToSet; | ||
461 | u8 index = 0; | ||
462 | |||
463 | pRegToSet = RegToSet_Normal; /* 0xb972a841; */ | ||
464 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
465 | if ((BT_IsBtDisabled(padapter) == false) && | ||
466 | (BT_1Ant(padapter) == true)) { | ||
467 | MaxAggNum = 0x8; | ||
468 | } else | ||
469 | #endif /* CONFIG_8723AU_BT_COEXIST */ | ||
470 | { | ||
471 | MaxAggNum = 0xF; | ||
472 | } | ||
473 | |||
474 | if (FactorToSet <= 3) { | ||
475 | FactorToSet = (1 << (FactorToSet + 2)); | ||
476 | if (FactorToSet > MaxAggNum) | ||
477 | FactorToSet = MaxAggNum; | ||
478 | |||
479 | for (index = 0; index < 4; index++) { | ||
480 | if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4)) | ||
481 | pRegToSet[index] = (pRegToSet[index] & 0x0f) | | ||
482 | (FactorToSet << 4); | ||
483 | |||
484 | if ((pRegToSet[index] & 0x0f) > FactorToSet) | ||
485 | pRegToSet[index] = (pRegToSet[index] & 0xf0) | | ||
486 | FactorToSet; | ||
487 | |||
488 | rtw_write8(padapter, REG_AGGLEN_LMT + index, | ||
489 | pRegToSet[index]); | ||
490 | } | ||
491 | |||
492 | /* RT_TRACE(COMP_MLME, DBG_LOUD, | ||
493 | ("Set HW_VAR_AMPDU_FACTOR: %#x\n", FactorToSet)); */ | ||
494 | } | ||
495 | } | ||
496 | |||
497 | void rtl8723a_set_acm_ctrl(struct rtw_adapter *padapter, u8 ctrl) | ||
498 | { | ||
499 | u8 hwctrl = 0; | ||
500 | |||
501 | if (ctrl != 0) { | ||
502 | hwctrl |= AcmHw_HwEn; | ||
503 | |||
504 | if (ctrl & BIT(1)) /* BE */ | ||
505 | hwctrl |= AcmHw_BeqEn; | ||
506 | |||
507 | if (ctrl & BIT(2)) /* VI */ | ||
508 | hwctrl |= AcmHw_ViqEn; | ||
509 | |||
510 | if (ctrl & BIT(3)) /* VO */ | ||
511 | hwctrl |= AcmHw_VoqEn; | ||
512 | } | ||
513 | |||
514 | DBG_8723A("[HW_VAR_ACM_CTRL] Write 0x%02X\n", hwctrl); | ||
515 | rtw_write8(padapter, REG_ACMHWCTRL, hwctrl); | ||
516 | } | ||
517 | |||
518 | void rtl8723a_set_media_status(struct rtw_adapter *padapter, u8 status) | ||
519 | { | ||
520 | u8 val8; | ||
521 | |||
522 | val8 = rtw_read8(padapter, MSR) & 0x0c; | ||
523 | val8 |= status; | ||
524 | rtw_write8(padapter, MSR, val8); | ||
525 | } | ||
526 | |||
527 | void rtl8723a_set_media_status1(struct rtw_adapter *padapter, u8 status) | ||
528 | { | ||
529 | u8 val8; | ||
530 | |||
531 | val8 = rtw_read8(padapter, MSR) & 0x03; | ||
532 | val8 |= status << 2; | ||
533 | rtw_write8(padapter, MSR, val8); | ||
534 | } | ||
535 | |||
536 | void rtl8723a_set_bcn_func(struct rtw_adapter *padapter, u8 val) | ||
537 | { | ||
538 | if (val) | ||
539 | SetBcnCtrlReg23a(padapter, EN_BCN_FUNCTION | EN_TXBCN_RPT, 0); | ||
540 | else | ||
541 | SetBcnCtrlReg23a(padapter, 0, EN_BCN_FUNCTION | EN_TXBCN_RPT); | ||
542 | } | ||
543 | |||
544 | void rtl8723a_check_bssid(struct rtw_adapter *padapter, u8 val) | ||
545 | { | ||
546 | u32 val32; | ||
547 | val32 = rtw_read32(padapter, REG_RCR); | ||
548 | if (val) | ||
549 | val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN; | ||
550 | else | ||
551 | val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); | ||
552 | rtw_write32(padapter, REG_RCR, val32); | ||
553 | } | ||
554 | |||
555 | void rtl8723a_mlme_sitesurvey(struct rtw_adapter *padapter, u8 flag) | ||
556 | { | ||
557 | if (flag) { /* under sitesurvey */ | ||
558 | u32 v32; | ||
559 | |||
560 | /* config RCR to receive different BSSID & not | ||
561 | to receive data frame */ | ||
562 | v32 = rtw_read32(padapter, REG_RCR); | ||
563 | v32 &= ~(RCR_CBSSID_BCN); | ||
564 | rtw_write32(padapter, REG_RCR, v32); | ||
565 | /* reject all data frame */ | ||
566 | rtw_write16(padapter, REG_RXFLTMAP2, 0); | ||
567 | |||
568 | /* disable update TSF */ | ||
569 | SetBcnCtrlReg23a(padapter, DIS_TSF_UDT, 0); | ||
570 | } else { /* sitesurvey done */ | ||
571 | |||
572 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; | ||
573 | struct mlme_ext_info *pmlmeinfo; | ||
574 | u32 v32; | ||
575 | |||
576 | pmlmeinfo = &pmlmeext->mlmext_info; | ||
577 | |||
578 | if ((is_client_associated_to_ap23a(padapter) == true) || | ||
579 | ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || | ||
580 | ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) { | ||
581 | /* enable to rx data frame */ | ||
582 | rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF); | ||
583 | |||
584 | /* enable update TSF */ | ||
585 | SetBcnCtrlReg23a(padapter, 0, DIS_TSF_UDT); | ||
586 | } | ||
587 | |||
588 | v32 = rtw_read32(padapter, REG_RCR); | ||
589 | v32 |= RCR_CBSSID_BCN; | ||
590 | rtw_write32(padapter, REG_RCR, v32); | ||
591 | } | ||
592 | |||
593 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
594 | BT_WifiScanNotify(padapter, flag ? true : false); | ||
595 | #endif | ||
596 | } | ||
597 | |||
598 | void rtl8723a_on_rcr_am(struct rtw_adapter *padapter) | ||
599 | { | ||
600 | rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) | RCR_AM); | ||
601 | DBG_8723A("%s, %d, RCR = %x \n", __FUNCTION__, __LINE__, | ||
602 | rtw_read32(padapter, REG_RCR)); | ||
603 | } | ||
604 | |||
605 | void rtl8723a_off_rcr_am(struct rtw_adapter *padapter) | ||
606 | { | ||
607 | rtw_write32(padapter, REG_RCR, | ||
608 | rtw_read32(padapter, REG_RCR) & (~RCR_AM)); | ||
609 | DBG_8723A("%s, %d, RCR = %x \n", __FUNCTION__, __LINE__, | ||
610 | rtw_read32(padapter, REG_RCR)); | ||
611 | } | ||
612 | |||
613 | void rtl8723a_set_slot_time(struct rtw_adapter *padapter, u8 slottime) | ||
614 | { | ||
615 | u8 u1bAIFS, aSifsTime; | ||
616 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; | ||
617 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; | ||
618 | |||
619 | rtw_write8(padapter, REG_SLOT, slottime); | ||
620 | |||
621 | if (pmlmeinfo->WMM_enable == 0) { | ||
622 | if (pmlmeext->cur_wireless_mode == WIRELESS_11B) | ||
623 | aSifsTime = 10; | ||
624 | else | ||
625 | aSifsTime = 16; | ||
626 | |||
627 | u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime); | ||
628 | |||
629 | /* <Roger_EXP> Temporary removed, 2008.06.20. */ | ||
630 | rtw_write8(padapter, REG_EDCA_VO_PARAM, u1bAIFS); | ||
631 | rtw_write8(padapter, REG_EDCA_VI_PARAM, u1bAIFS); | ||
632 | rtw_write8(padapter, REG_EDCA_BE_PARAM, u1bAIFS); | ||
633 | rtw_write8(padapter, REG_EDCA_BK_PARAM, u1bAIFS); | ||
634 | } | ||
635 | } | ||
636 | |||
637 | void rtl8723a_ack_preamble(struct rtw_adapter *padapter, u8 bShortPreamble) | ||
638 | { | ||
639 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
640 | u8 regTmp; | ||
641 | |||
642 | /* Joseph marked out for Netgear 3500 TKIP | ||
643 | channel 7 issue.(Temporarily) */ | ||
644 | regTmp = (pHalData->nCur40MhzPrimeSC) << 5; | ||
645 | /* regTmp = 0; */ | ||
646 | if (bShortPreamble) | ||
647 | regTmp |= 0x80; | ||
648 | rtw_write8(padapter, REG_RRSR + 2, regTmp); | ||
649 | } | ||
650 | |||
651 | void rtl8723a_set_sec_cfg(struct rtw_adapter *padapter, u8 sec) | ||
652 | { | ||
653 | rtw_write8(padapter, REG_SECCFG, sec); | ||
654 | } | ||
655 | |||
656 | void rtl8723a_cam_empty_entry(struct rtw_adapter *padapter, u8 ucIndex) | ||
657 | { | ||
658 | u8 i; | ||
659 | u32 ulCommand = 0; | ||
660 | u32 ulContent = 0; | ||
661 | u32 ulEncAlgo = CAM_AES; | ||
662 | |||
663 | for (i = 0; i < CAM_CONTENT_COUNT; i++) { | ||
664 | /* filled id in CAM config 2 byte */ | ||
665 | if (i == 0) { | ||
666 | ulContent |= (ucIndex & 0x03) | | ||
667 | ((u16) (ulEncAlgo) << 2); | ||
668 | /* ulContent |= CAM_VALID; */ | ||
669 | } else { | ||
670 | ulContent = 0; | ||
671 | } | ||
672 | /* polling bit, and No Write enable, and address */ | ||
673 | ulCommand = CAM_CONTENT_COUNT * ucIndex + i; | ||
674 | ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE; | ||
675 | /* write content 0 is equall to mark invalid */ | ||
676 | /* delay_ms(40); */ | ||
677 | rtw_write32(padapter, WCAMI, ulContent); | ||
678 | /* RT_TRACE(COMP_SEC, DBG_LOUD, | ||
679 | ("CAM_empty_entry23a(): WRITE A4: %lx \n", ulContent));*/ | ||
680 | /* delay_ms(40); */ | ||
681 | rtw_write32(padapter, RWCAM, ulCommand); | ||
682 | /* RT_TRACE(COMP_SEC, DBG_LOUD, | ||
683 | ("CAM_empty_entry23a(): WRITE A0: %lx \n", ulCommand));*/ | ||
684 | } | ||
685 | } | ||
686 | |||
687 | void rtl8723a_cam_invalid_all(struct rtw_adapter *padapter) | ||
688 | { | ||
689 | rtw_write32(padapter, RWCAM, BIT(31) | BIT(30)); | ||
690 | } | ||
691 | |||
692 | void rtl8723a_cam_write(struct rtw_adapter *padapter, u32 val1, u32 val2) | ||
693 | { | ||
694 | u32 cmd; | ||
695 | |||
696 | rtw_write32(padapter, WCAMI, val1); | ||
697 | |||
698 | cmd = CAM_POLLINIG | CAM_WRITE | val2; | ||
699 | rtw_write32(padapter, RWCAM, cmd); | ||
700 | } | ||
701 | |||
702 | void rtl8723a_fifo_cleanup(struct rtw_adapter *padapter) | ||
703 | { | ||
704 | #define RW_RELEASE_EN BIT(18) | ||
705 | #define RXDMA_IDLE BIT(17) | ||
706 | |||
707 | struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; | ||
708 | u8 trycnt = 100; | ||
709 | |||
710 | /* pause tx */ | ||
711 | rtw_write8(padapter, REG_TXPAUSE, 0xff); | ||
712 | |||
713 | /* keep sn */ | ||
714 | padapter->xmitpriv.nqos_ssn = rtw_read16(padapter, REG_NQOS_SEQ); | ||
715 | |||
716 | if (pwrpriv->bkeepfwalive != true) { | ||
717 | u32 v32; | ||
718 | |||
719 | /* RX DMA stop */ | ||
720 | v32 = rtw_read32(padapter, REG_RXPKT_NUM); | ||
721 | v32 |= RW_RELEASE_EN; | ||
722 | rtw_write32(padapter, REG_RXPKT_NUM, v32); | ||
723 | do { | ||
724 | v32 = rtw_read32(padapter, REG_RXPKT_NUM) & RXDMA_IDLE; | ||
725 | if (!v32) | ||
726 | break; | ||
727 | } while (trycnt--); | ||
728 | if (trycnt == 0) { | ||
729 | DBG_8723A("Stop RX DMA failed......\n"); | ||
730 | } | ||
731 | |||
732 | /* RQPN Load 0 */ | ||
733 | rtw_write16(padapter, REG_RQPN_NPQ, 0); | ||
734 | rtw_write32(padapter, REG_RQPN, 0x80000000); | ||
735 | mdelay(10); | ||
736 | } | ||
737 | } | ||
738 | |||
739 | void rtl8723a_set_apfm_on_mac(struct rtw_adapter *padapter, u8 val) | ||
740 | { | ||
741 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
742 | |||
743 | pHalData->bMacPwrCtrlOn = val; | ||
744 | DBG_8723A("%s: bMacPwrCtrlOn =%d\n", __func__, pHalData->bMacPwrCtrlOn); | ||
745 | } | ||
746 | |||
747 | void rtl8723a_bcn_valid(struct rtw_adapter *padapter) | ||
748 | { | ||
749 | /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, | ||
750 | write 1 to clear, Clear by sw */ | ||
751 | rtw_write8(padapter, REG_TDECTRL + 2, | ||
752 | rtw_read8(padapter, REG_TDECTRL + 2) | BIT0); | ||
753 | } | ||
754 | |||
755 | void rtl8723a_set_tx_pause(struct rtw_adapter *padapter, u8 pause) | ||
756 | { | ||
757 | rtw_write8(padapter, REG_TXPAUSE, pause); | ||
758 | } | ||
759 | |||
760 | void rtl8723a_set_beacon_interval(struct rtw_adapter *padapter, u16 interval) | ||
761 | { | ||
762 | rtw_write16(padapter, REG_BCN_INTERVAL, interval); | ||
763 | } | ||
764 | |||
765 | void rtl8723a_set_resp_sifs(struct rtw_adapter *padapter, | ||
766 | u8 r2t1, u8 r2t2, u8 t2t1, u8 t2t2) | ||
767 | { | ||
768 | /* SIFS_Timer = 0x0a0a0808; */ | ||
769 | /* RESP_SIFS for CCK */ | ||
770 | /* SIFS_T2T_CCK (0x08) */ | ||
771 | rtw_write8(padapter, REG_R2T_SIFS, r2t1); | ||
772 | /* SIFS_R2T_CCK(0x08) */ | ||
773 | rtw_write8(padapter, REG_R2T_SIFS + 1, r2t2); | ||
774 | /* RESP_SIFS for OFDM */ | ||
775 | /* SIFS_T2T_OFDM (0x0a) */ | ||
776 | rtw_write8(padapter, REG_T2T_SIFS, t2t1); | ||
777 | /* SIFS_R2T_OFDM(0x0a) */ | ||
778 | rtw_write8(padapter, REG_T2T_SIFS + 1, t2t2); | ||
779 | } | ||
780 | |||
781 | void rtl8723a_set_ac_param_vo(struct rtw_adapter *padapter, u32 vo) | ||
782 | { | ||
783 | rtw_write32(padapter, REG_EDCA_VO_PARAM, vo); | ||
784 | } | ||
785 | |||
786 | void rtl8723a_set_ac_param_vi(struct rtw_adapter *padapter, u32 vi) | ||
787 | { | ||
788 | rtw_write32(padapter, REG_EDCA_VI_PARAM, vi); | ||
789 | } | ||
790 | |||
791 | void rtl8723a_set_ac_param_be(struct rtw_adapter *padapter, u32 be) | ||
792 | { | ||
793 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
794 | |||
795 | pHalData->AcParam_BE = be; | ||
796 | rtw_write32(padapter, REG_EDCA_BE_PARAM, be); | ||
797 | } | ||
798 | |||
799 | void rtl8723a_set_ac_param_bk(struct rtw_adapter *padapter, u32 bk) | ||
800 | { | ||
801 | rtw_write32(padapter, REG_EDCA_BK_PARAM, bk); | ||
802 | } | ||
803 | |||
804 | void rtl8723a_set_rxdma_agg_pg_th(struct rtw_adapter *padapter, u8 val) | ||
805 | { | ||
806 | rtw_write8(padapter, REG_RXDMA_AGG_PG_TH, val); | ||
807 | } | ||
808 | |||
809 | void rtl8723a_set_nav_upper(struct rtw_adapter *padapter, u32 usNavUpper) | ||
810 | { | ||
811 | if (usNavUpper > HAL_8723A_NAV_UPPER_UNIT * 0xFF) { | ||
812 | RT_TRACE(_module_hal_init_c_, _drv_notice_, | ||
813 | ("The setting value (0x%08X us) of NAV_UPPER " | ||
814 | "is larger than (%d * 0xFF)!!!\n", | ||
815 | usNavUpper, HAL_8723A_NAV_UPPER_UNIT)); | ||
816 | return; | ||
817 | } | ||
818 | |||
819 | /* The value of ((usNavUpper + HAL_8723A_NAV_UPPER_UNIT - 1) / | ||
820 | HAL_8723A_NAV_UPPER_UNIT) */ | ||
821 | /* is getting the upper integer. */ | ||
822 | usNavUpper = (usNavUpper + HAL_8723A_NAV_UPPER_UNIT - 1) / | ||
823 | HAL_8723A_NAV_UPPER_UNIT; | ||
824 | rtw_write8(padapter, REG_NAV_UPPER, (u8) usNavUpper); | ||
825 | } | ||
826 | |||
827 | void rtl8723a_set_initial_gain(struct rtw_adapter *padapter, u32 rx_gain) | ||
828 | { | ||
829 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
830 | struct dig_t *pDigTable = &pHalData->odmpriv.DM_DigTable; | ||
831 | |||
832 | if (rx_gain == 0xff) /* restore rx gain */ | ||
833 | ODM_Write_DIG23a(&pHalData->odmpriv, pDigTable->BackupIGValue); | ||
834 | else { | ||
835 | pDigTable->BackupIGValue = pDigTable->CurIGValue; | ||
836 | ODM_Write_DIG23a(&pHalData->odmpriv, rx_gain); | ||
837 | } | ||
838 | } | ||
839 | |||
840 | void rtl8723a_odm_support_ability_write(struct rtw_adapter *padapter, u32 val) | ||
841 | { | ||
842 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
843 | |||
844 | pHalData->odmpriv.SupportAbility = val; | ||
845 | } | ||
846 | |||
847 | void rtl8723a_odm_support_ability_backup(struct rtw_adapter *padapter, u8 val) | ||
848 | { | ||
849 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
850 | |||
851 | if (val) /* save dm flag */ | ||
852 | pHalData->odmpriv.BK_SupportAbility = | ||
853 | pHalData->odmpriv.SupportAbility; | ||
854 | else /* restore dm flag */ | ||
855 | pHalData->odmpriv.SupportAbility = | ||
856 | pHalData->odmpriv.BK_SupportAbility; | ||
857 | } | ||
858 | |||
859 | void rtl8723a_odm_support_ability_set(struct rtw_adapter *padapter, u32 val) | ||
860 | { | ||
861 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
862 | |||
863 | if (val == DYNAMIC_ALL_FUNC_ENABLE) { | ||
864 | pHalData->dmpriv.DMFlag = pHalData->dmpriv.InitDMFlag; | ||
865 | pHalData->odmpriv.SupportAbility = pHalData->dmpriv.InitODMFlag; | ||
866 | } else { | ||
867 | pHalData->odmpriv.SupportAbility |= val; | ||
868 | } | ||
869 | } | ||
870 | |||
871 | void rtl8723a_odm_support_ability_clr(struct rtw_adapter *padapter, u32 val) | ||
872 | { | ||
873 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
874 | |||
875 | pHalData->odmpriv.SupportAbility &= val; | ||
876 | } | ||
877 | |||
878 | void rtl8723a_set_rpwm(struct rtw_adapter *padapter, u8 val) | ||
879 | { | ||
880 | rtw_write8(padapter, REG_USB_HRPWM, val); | ||
881 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/hal_intf.c b/drivers/staging/rtl8723au/hal/hal_intf.c new file mode 100644 index 000000000000..c1a5b735ecf3 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/hal_intf.c | |||
@@ -0,0 +1,418 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | #define _HAL_INTF_C_ | ||
17 | #include <osdep_service.h> | ||
18 | #include <drv_types.h> | ||
19 | |||
20 | #include <hal_intf.h> | ||
21 | |||
22 | #include <usb_hal.h> | ||
23 | |||
24 | void rtw_hal_chip_configure23a(struct rtw_adapter *padapter) | ||
25 | { | ||
26 | if (padapter->HalFunc.intf_chip_configure) | ||
27 | padapter->HalFunc.intf_chip_configure(padapter); | ||
28 | } | ||
29 | |||
30 | void rtw_hal_read_chip_info23a(struct rtw_adapter *padapter) | ||
31 | { | ||
32 | if (padapter->HalFunc.read_adapter_info) | ||
33 | padapter->HalFunc.read_adapter_info(padapter); | ||
34 | } | ||
35 | |||
36 | void rtw_hal_read_chip_version23a(struct rtw_adapter *padapter) | ||
37 | { | ||
38 | if (padapter->HalFunc.read_chip_version) | ||
39 | padapter->HalFunc.read_chip_version(padapter); | ||
40 | } | ||
41 | |||
42 | void rtw_hal_def_value_init23a(struct rtw_adapter *padapter) | ||
43 | { | ||
44 | if (padapter->HalFunc.init_default_value) | ||
45 | padapter->HalFunc.init_default_value(padapter); | ||
46 | } | ||
47 | void rtw_hal_free_data23a(struct rtw_adapter *padapter) | ||
48 | { | ||
49 | if (padapter->HalFunc.free_hal_data) | ||
50 | padapter->HalFunc.free_hal_data(padapter); | ||
51 | } | ||
52 | void rtw_hal_dm_init23a(struct rtw_adapter *padapter) | ||
53 | { | ||
54 | if (padapter->HalFunc.dm_init) | ||
55 | padapter->HalFunc.dm_init(padapter); | ||
56 | } | ||
57 | void rtw_hal_dm_deinit23a(struct rtw_adapter *padapter) | ||
58 | { | ||
59 | /* cancel dm timer */ | ||
60 | if (padapter->HalFunc.dm_deinit) | ||
61 | padapter->HalFunc.dm_deinit(padapter); | ||
62 | } | ||
63 | void rtw_hal_sw_led_init23a(struct rtw_adapter *padapter) | ||
64 | { | ||
65 | if (padapter->HalFunc.InitSwLeds) | ||
66 | padapter->HalFunc.InitSwLeds(padapter); | ||
67 | } | ||
68 | |||
69 | void rtw_hal_sw_led_deinit23a(struct rtw_adapter *padapter) | ||
70 | { | ||
71 | if (padapter->HalFunc.DeInitSwLeds) | ||
72 | padapter->HalFunc.DeInitSwLeds(padapter); | ||
73 | } | ||
74 | |||
75 | u32 rtw_hal_power_on23a(struct rtw_adapter *padapter) | ||
76 | { | ||
77 | if (padapter->HalFunc.hal_power_on) | ||
78 | return padapter->HalFunc.hal_power_on(padapter); | ||
79 | return _FAIL; | ||
80 | } | ||
81 | |||
82 | uint rtw_hal_init23a(struct rtw_adapter *padapter) | ||
83 | { | ||
84 | uint status = _SUCCESS; | ||
85 | |||
86 | padapter->hw_init_completed = false; | ||
87 | |||
88 | status = padapter->HalFunc.hal_init(padapter); | ||
89 | |||
90 | if (status == _SUCCESS) { | ||
91 | padapter->hw_init_completed = true; | ||
92 | |||
93 | if (padapter->registrypriv.notch_filter == 1) | ||
94 | rtw_hal_notch_filter23a(padapter, 1); | ||
95 | |||
96 | rtw_hal_reset_security_engine23a(padapter); | ||
97 | } else { | ||
98 | padapter->hw_init_completed = false; | ||
99 | DBG_8723A("rtw_hal_init23a: hal__init fail\n"); | ||
100 | } | ||
101 | |||
102 | RT_TRACE(_module_hal_init_c_, _drv_err_, ("-rtl871x_hal_init:status = 0x%x\n", status)); | ||
103 | |||
104 | return status; | ||
105 | } | ||
106 | |||
107 | uint rtw_hal_deinit23a(struct rtw_adapter *padapter) | ||
108 | { | ||
109 | uint status = _SUCCESS; | ||
110 | |||
111 | status = padapter->HalFunc.hal_deinit(padapter); | ||
112 | |||
113 | if (status == _SUCCESS) | ||
114 | padapter->hw_init_completed = false; | ||
115 | else | ||
116 | DBG_8723A("\n rtw_hal_deinit23a: hal_init fail\n"); | ||
117 | return status; | ||
118 | } | ||
119 | |||
120 | void rtw_hal_set_hwreg23a(struct rtw_adapter *padapter, u8 variable, u8 *val) | ||
121 | { | ||
122 | if (padapter->HalFunc.SetHwRegHandler) | ||
123 | padapter->HalFunc.SetHwRegHandler(padapter, variable, val); | ||
124 | } | ||
125 | |||
126 | void rtw23a_hal_get_hwreg(struct rtw_adapter *padapter, u8 variable, u8 *val) | ||
127 | { | ||
128 | if (padapter->HalFunc.GetHwRegHandler) | ||
129 | padapter->HalFunc.GetHwRegHandler(padapter, variable, val); | ||
130 | } | ||
131 | |||
132 | u8 rtw_hal_set_def_var23a(struct rtw_adapter *padapter, enum hal_def_variable eVariable, void *pValue) | ||
133 | { | ||
134 | if (padapter->HalFunc.SetHalDefVarHandler) | ||
135 | return padapter->HalFunc.SetHalDefVarHandler(padapter, eVariable, pValue); | ||
136 | return _FAIL; | ||
137 | } | ||
138 | u8 rtw_hal_get_def_var23a(struct rtw_adapter *padapter, enum hal_def_variable eVariable, void *pValue) | ||
139 | { | ||
140 | if (padapter->HalFunc.GetHalDefVarHandler) | ||
141 | return padapter->HalFunc.GetHalDefVarHandler(padapter, eVariable, pValue); | ||
142 | return _FAIL; | ||
143 | } | ||
144 | |||
145 | void rtw_hal_set_odm_var23a(struct rtw_adapter *padapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet) | ||
146 | { | ||
147 | if (padapter->HalFunc.SetHalODMVarHandler) | ||
148 | padapter->HalFunc.SetHalODMVarHandler(padapter, eVariable, pValue1, bSet); | ||
149 | } | ||
150 | void rtw_hal_get_odm_var23a(struct rtw_adapter *padapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet) | ||
151 | { | ||
152 | if (padapter->HalFunc.GetHalODMVarHandler) | ||
153 | padapter->HalFunc.GetHalODMVarHandler(padapter, eVariable, pValue1, bSet); | ||
154 | } | ||
155 | |||
156 | void rtw_hal_enable_interrupt23a(struct rtw_adapter *padapter) | ||
157 | { | ||
158 | if (padapter->HalFunc.enable_interrupt) | ||
159 | padapter->HalFunc.enable_interrupt(padapter); | ||
160 | else | ||
161 | DBG_8723A("%s: HalFunc.enable_interrupt is NULL!\n", __FUNCTION__); | ||
162 | |||
163 | } | ||
164 | void rtw_hal_disable_interrupt23a(struct rtw_adapter *padapter) | ||
165 | { | ||
166 | if (padapter->HalFunc.disable_interrupt) | ||
167 | padapter->HalFunc.disable_interrupt(padapter); | ||
168 | else | ||
169 | DBG_8723A("%s: HalFunc.disable_interrupt is NULL!\n", __FUNCTION__); | ||
170 | |||
171 | } | ||
172 | |||
173 | u32 rtw_hal_inirp_init23a(struct rtw_adapter *padapter) | ||
174 | { | ||
175 | u32 rst = _FAIL; | ||
176 | if (padapter->HalFunc.inirp_init) | ||
177 | rst = padapter->HalFunc.inirp_init(padapter); | ||
178 | else | ||
179 | DBG_8723A(" %s HalFunc.inirp_init is NULL!!!\n", __FUNCTION__); | ||
180 | return rst; | ||
181 | } | ||
182 | |||
183 | u32 rtw_hal_inirp_deinit23a(struct rtw_adapter *padapter) | ||
184 | { | ||
185 | |||
186 | if (padapter->HalFunc.inirp_deinit) | ||
187 | return padapter->HalFunc.inirp_deinit(padapter); | ||
188 | |||
189 | return _FAIL; | ||
190 | |||
191 | } | ||
192 | |||
193 | u8 rtw_hal_intf_ps_func23a(struct rtw_adapter *padapter, enum hal_intf_ps_func efunc_id, u8 *val) | ||
194 | { | ||
195 | if (padapter->HalFunc.interface_ps_func) | ||
196 | return padapter->HalFunc.interface_ps_func(padapter, efunc_id, val); | ||
197 | return _FAIL; | ||
198 | } | ||
199 | |||
200 | s32 rtw_hal_xmit23aframe_enqueue(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe) | ||
201 | { | ||
202 | if (padapter->HalFunc.hal_xmitframe_enqueue) | ||
203 | return padapter->HalFunc.hal_xmitframe_enqueue(padapter, pxmitframe); | ||
204 | |||
205 | return false; | ||
206 | } | ||
207 | |||
208 | s32 rtw_hal_xmit23a(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe) | ||
209 | { | ||
210 | if (padapter->HalFunc.hal_xmit) | ||
211 | return padapter->HalFunc.hal_xmit(padapter, pxmitframe); | ||
212 | |||
213 | return false; | ||
214 | } | ||
215 | |||
216 | s32 rtw_hal_mgnt_xmit23a(struct rtw_adapter *padapter, struct xmit_frame *pmgntframe) | ||
217 | { | ||
218 | s32 ret = _FAIL; | ||
219 | if (padapter->HalFunc.mgnt_xmit) | ||
220 | ret = padapter->HalFunc.mgnt_xmit(padapter, pmgntframe); | ||
221 | return ret; | ||
222 | } | ||
223 | |||
224 | s32 rtw_hal_init23a_xmit_priv(struct rtw_adapter *padapter) | ||
225 | { | ||
226 | if (padapter->HalFunc.init_xmit_priv != NULL) | ||
227 | return padapter->HalFunc.init_xmit_priv(padapter); | ||
228 | return _FAIL; | ||
229 | } | ||
230 | void rtw_hal_free_xmit_priv23a(struct rtw_adapter *padapter) | ||
231 | { | ||
232 | if (padapter->HalFunc.free_xmit_priv != NULL) | ||
233 | padapter->HalFunc.free_xmit_priv(padapter); | ||
234 | } | ||
235 | |||
236 | s32 rtw_hal_init23a_recv_priv(struct rtw_adapter *padapter) | ||
237 | { | ||
238 | if (padapter->HalFunc.init_recv_priv) | ||
239 | return padapter->HalFunc.init_recv_priv(padapter); | ||
240 | |||
241 | return _FAIL; | ||
242 | } | ||
243 | void rtw_hal_free_recv_priv23a(struct rtw_adapter *padapter) | ||
244 | { | ||
245 | if (padapter->HalFunc.free_recv_priv) | ||
246 | padapter->HalFunc.free_recv_priv(padapter); | ||
247 | } | ||
248 | |||
249 | void rtw_hal_update_ra_mask23a(struct sta_info *psta, u8 rssi_level) | ||
250 | { | ||
251 | struct rtw_adapter *padapter; | ||
252 | struct mlme_priv *pmlmepriv; | ||
253 | |||
254 | if (!psta) | ||
255 | return; | ||
256 | |||
257 | padapter = psta->padapter; | ||
258 | |||
259 | pmlmepriv = &padapter->mlmepriv; | ||
260 | |||
261 | if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { | ||
262 | add_RATid23a(padapter, psta, rssi_level); | ||
263 | } else { | ||
264 | if (padapter->HalFunc.UpdateRAMaskHandler) | ||
265 | padapter->HalFunc.UpdateRAMaskHandler(padapter, psta->mac_id, rssi_level); | ||
266 | } | ||
267 | } | ||
268 | |||
269 | void rtw_hal_add_ra_tid23a(struct rtw_adapter *padapter, u32 bitmap, u8 arg, u8 rssi_level) | ||
270 | { | ||
271 | if (padapter->HalFunc.Add_RateATid) | ||
272 | padapter->HalFunc.Add_RateATid(padapter, bitmap, arg, rssi_level); | ||
273 | } | ||
274 | |||
275 | /* Start specifical interface thread */ | ||
276 | void rtw_hal_start_thread23a(struct rtw_adapter *padapter) | ||
277 | { | ||
278 | if (padapter->HalFunc.run_thread) | ||
279 | padapter->HalFunc.run_thread(padapter); | ||
280 | } | ||
281 | /* Start specifical interface thread */ | ||
282 | void rtw_hal_stop_thread23a(struct rtw_adapter *padapter) | ||
283 | { | ||
284 | if (padapter->HalFunc.cancel_thread) | ||
285 | padapter->HalFunc.cancel_thread(padapter); | ||
286 | } | ||
287 | |||
288 | u32 rtw_hal_read_bbreg23a(struct rtw_adapter *padapter, u32 RegAddr, u32 BitMask) | ||
289 | { | ||
290 | u32 data = 0; | ||
291 | if (padapter->HalFunc.read_bbreg) | ||
292 | data = padapter->HalFunc.read_bbreg(padapter, RegAddr, BitMask); | ||
293 | return data; | ||
294 | } | ||
295 | void rtw_hal_write_bbreg23a(struct rtw_adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data) | ||
296 | { | ||
297 | if (padapter->HalFunc.write_bbreg) | ||
298 | padapter->HalFunc.write_bbreg(padapter, RegAddr, BitMask, Data); | ||
299 | } | ||
300 | |||
301 | u32 rtw_hal_read_rfreg23a(struct rtw_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask) | ||
302 | { | ||
303 | u32 data = 0; | ||
304 | if (padapter->HalFunc.read_rfreg) | ||
305 | data = padapter->HalFunc.read_rfreg(padapter, eRFPath, RegAddr, BitMask); | ||
306 | return data; | ||
307 | } | ||
308 | void rtw_hal_write_rfreg23a(struct rtw_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask, u32 Data) | ||
309 | { | ||
310 | if (padapter->HalFunc.write_rfreg) | ||
311 | padapter->HalFunc.write_rfreg(padapter, eRFPath, RegAddr, BitMask, Data); | ||
312 | } | ||
313 | |||
314 | s32 rtw_hal_interrupt_handler23a(struct rtw_adapter *padapter) | ||
315 | { | ||
316 | if (padapter->HalFunc.interrupt_handler) | ||
317 | return padapter->HalFunc.interrupt_handler(padapter); | ||
318 | return _FAIL; | ||
319 | } | ||
320 | |||
321 | void rtw_hal_set_bwmode23a(struct rtw_adapter *padapter, | ||
322 | enum ht_channel_width Bandwidth, u8 offset) | ||
323 | { | ||
324 | if (padapter->HalFunc.set_bwmode_handler) | ||
325 | padapter->HalFunc.set_bwmode_handler(padapter, Bandwidth, | ||
326 | offset); | ||
327 | } | ||
328 | |||
329 | void rtw_hal_set_chan23a(struct rtw_adapter *padapter, u8 channel) | ||
330 | { | ||
331 | if (padapter->HalFunc.set_channel_handler) | ||
332 | padapter->HalFunc.set_channel_handler(padapter, channel); | ||
333 | } | ||
334 | |||
335 | void rtw_hal_dm_watchdog23a(struct rtw_adapter *padapter) | ||
336 | { | ||
337 | if (padapter->HalFunc.hal_dm_watchdog) | ||
338 | padapter->HalFunc.hal_dm_watchdog(padapter); | ||
339 | } | ||
340 | |||
341 | void rtw_hal_bcn_related_reg_setting23a(struct rtw_adapter *padapter) | ||
342 | { | ||
343 | if (padapter->HalFunc.SetBeaconRelatedRegistersHandler) | ||
344 | padapter->HalFunc.SetBeaconRelatedRegistersHandler(padapter); | ||
345 | } | ||
346 | |||
347 | void rtw_hal_sreset_init23a(struct rtw_adapter *padapter) | ||
348 | { | ||
349 | if (padapter->HalFunc.sreset_init_value23a) | ||
350 | padapter->HalFunc.sreset_init_value23a(padapter); | ||
351 | } | ||
352 | void rtw_hal_sreset_reset23a(struct rtw_adapter *padapter) | ||
353 | { | ||
354 | padapter = GET_PRIMARY_ADAPTER(padapter); | ||
355 | |||
356 | if (padapter->HalFunc.silentreset) | ||
357 | padapter->HalFunc.silentreset(padapter); | ||
358 | } | ||
359 | |||
360 | void rtw_hal_sreset_reset23a_value23a(struct rtw_adapter *padapter) | ||
361 | { | ||
362 | if (padapter->HalFunc.sreset_reset_value23a) | ||
363 | padapter->HalFunc.sreset_reset_value23a(padapter); | ||
364 | } | ||
365 | |||
366 | void rtw_hal_sreset_xmit_status_check23a(struct rtw_adapter *padapter) | ||
367 | { | ||
368 | if (padapter->HalFunc.sreset_xmit_status_check) | ||
369 | padapter->HalFunc.sreset_xmit_status_check(padapter); | ||
370 | } | ||
371 | void rtw_hal_sreset_linked_status_check23a(struct rtw_adapter *padapter) | ||
372 | { | ||
373 | if (padapter->HalFunc.sreset_linked_status_check) | ||
374 | padapter->HalFunc.sreset_linked_status_check(padapter); | ||
375 | } | ||
376 | u8 rtw_hal_sreset_get_wifi_status23a(struct rtw_adapter *padapter) | ||
377 | { | ||
378 | u8 status = 0; | ||
379 | if (padapter->HalFunc.sreset_get_wifi_status23a) | ||
380 | status = padapter->HalFunc.sreset_get_wifi_status23a(padapter); | ||
381 | return status; | ||
382 | } | ||
383 | |||
384 | bool rtw_hal_sreset_inprogress(struct rtw_adapter *padapter) | ||
385 | { | ||
386 | bool inprogress = false; | ||
387 | |||
388 | padapter = GET_PRIMARY_ADAPTER(padapter); | ||
389 | |||
390 | if (padapter->HalFunc.sreset_inprogress) | ||
391 | inprogress = padapter->HalFunc.sreset_inprogress(padapter); | ||
392 | return inprogress; | ||
393 | } | ||
394 | |||
395 | void rtw_hal_notch_filter23a(struct rtw_adapter *adapter, bool enable) | ||
396 | { | ||
397 | if (adapter->HalFunc.hal_notch_filter) | ||
398 | adapter->HalFunc.hal_notch_filter(adapter, enable); | ||
399 | } | ||
400 | |||
401 | void rtw_hal_reset_security_engine23a(struct rtw_adapter *adapter) | ||
402 | { | ||
403 | if (adapter->HalFunc.hal_reset_security_engine) | ||
404 | adapter->HalFunc.hal_reset_security_engine(adapter); | ||
405 | } | ||
406 | |||
407 | s32 rtw_hal_c2h_handler23a(struct rtw_adapter *adapter, struct c2h_evt_hdr *c2h_evt) | ||
408 | { | ||
409 | s32 ret = _FAIL; | ||
410 | if (adapter->HalFunc.c2h_handler) | ||
411 | ret = adapter->HalFunc.c2h_handler(adapter, c2h_evt); | ||
412 | return ret; | ||
413 | } | ||
414 | |||
415 | c2h_id_filter rtw_hal_c2h_id_filter_ccx23a(struct rtw_adapter *adapter) | ||
416 | { | ||
417 | return adapter->HalFunc.c2h_id_filter_ccx; | ||
418 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c new file mode 100644 index 000000000000..584a74ed2943 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/odm.c | |||
@@ -0,0 +1,2090 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | #include "odm_precomp.h" | ||
17 | |||
18 | static const u16 dB_Invert_Table[8][12] = { | ||
19 | {1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4}, | ||
20 | {4, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16}, | ||
21 | {18, 20, 22, 25, 28, 32, 35, 40, 45, 50, 56, 63}, | ||
22 | {71, 79, 89, 100, 112, 126, 141, 158, 178, 200, 224, 251}, | ||
23 | {282, 316, 355, 398, 447, 501, 562, 631, 708, 794, 891, 1000}, | ||
24 | {1122, 1259, 1413, 1585, 1778, 1995, 2239, 2512, 2818, 3162, 3548, 3981}, | ||
25 | {4467, 5012, 5623, 6310, 7079, 7943, 8913, 10000, 11220, 12589, 14125, 15849}, | ||
26 | {17783, 19953, 22387, 25119, 28184, 31623, 35481, 39811, 44668, 50119, 56234, 65535} | ||
27 | }; | ||
28 | |||
29 | static u32 EDCAParam[HT_IOT_PEER_MAX][3] = { /* UL DL */ | ||
30 | {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 0:unknown AP */ | ||
31 | {0xa44f, 0x5ea44f, 0x5e431c}, /* 1:realtek AP */ | ||
32 | {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 2:unknown AP => realtek_92SE */ | ||
33 | {0x5ea32b, 0x5ea42b, 0x5e4322}, /* 3:broadcom AP */ | ||
34 | {0x5ea422, 0x00a44f, 0x00a44f}, /* 4:ralink AP */ | ||
35 | {0x5ea322, 0x00a630, 0x00a44f}, /* 5:atheros AP */ | ||
36 | {0x5e4322, 0x5e4322, 0x5e4322},/* 6:cisco AP */ | ||
37 | {0x5ea44f, 0x00a44f, 0x5ea42b}, /* 8:marvell AP */ | ||
38 | {0x5ea42b, 0x5ea42b, 0x5ea42b}, /* 10:unknown AP => 92U AP */ | ||
39 | {0x5ea42b, 0xa630, 0x5e431c}, /* 11:airgocap AP */ | ||
40 | }; | ||
41 | |||
42 | /* EDCA Paramter for AP/ADSL by Mingzhi 2011-11-22 */ | ||
43 | |||
44 | /* Global var */ | ||
45 | u32 OFDMSwingTable23A[OFDM_TABLE_SIZE_92D] = { | ||
46 | 0x7f8001fe, /* 0, +6.0dB */ | ||
47 | 0x788001e2, /* 1, +5.5dB */ | ||
48 | 0x71c001c7, /* 2, +5.0dB */ | ||
49 | 0x6b8001ae, /* 3, +4.5dB */ | ||
50 | 0x65400195, /* 4, +4.0dB */ | ||
51 | 0x5fc0017f, /* 5, +3.5dB */ | ||
52 | 0x5a400169, /* 6, +3.0dB */ | ||
53 | 0x55400155, /* 7, +2.5dB */ | ||
54 | 0x50800142, /* 8, +2.0dB */ | ||
55 | 0x4c000130, /* 9, +1.5dB */ | ||
56 | 0x47c0011f, /* 10, +1.0dB */ | ||
57 | 0x43c0010f, /* 11, +0.5dB */ | ||
58 | 0x40000100, /* 12, +0dB */ | ||
59 | 0x3c8000f2, /* 13, -0.5dB */ | ||
60 | 0x390000e4, /* 14, -1.0dB */ | ||
61 | 0x35c000d7, /* 15, -1.5dB */ | ||
62 | 0x32c000cb, /* 16, -2.0dB */ | ||
63 | 0x300000c0, /* 17, -2.5dB */ | ||
64 | 0x2d4000b5, /* 18, -3.0dB */ | ||
65 | 0x2ac000ab, /* 19, -3.5dB */ | ||
66 | 0x288000a2, /* 20, -4.0dB */ | ||
67 | 0x26000098, /* 21, -4.5dB */ | ||
68 | 0x24000090, /* 22, -5.0dB */ | ||
69 | 0x22000088, /* 23, -5.5dB */ | ||
70 | 0x20000080, /* 24, -6.0dB */ | ||
71 | 0x1e400079, /* 25, -6.5dB */ | ||
72 | 0x1c800072, /* 26, -7.0dB */ | ||
73 | 0x1b00006c, /* 27. -7.5dB */ | ||
74 | 0x19800066, /* 28, -8.0dB */ | ||
75 | 0x18000060, /* 29, -8.5dB */ | ||
76 | 0x16c0005b, /* 30, -9.0dB */ | ||
77 | 0x15800056, /* 31, -9.5dB */ | ||
78 | 0x14400051, /* 32, -10.0dB */ | ||
79 | 0x1300004c, /* 33, -10.5dB */ | ||
80 | 0x12000048, /* 34, -11.0dB */ | ||
81 | 0x11000044, /* 35, -11.5dB */ | ||
82 | 0x10000040, /* 36, -12.0dB */ | ||
83 | 0x0f00003c,/* 37, -12.5dB */ | ||
84 | 0x0e400039,/* 38, -13.0dB */ | ||
85 | 0x0d800036,/* 39, -13.5dB */ | ||
86 | 0x0cc00033,/* 40, -14.0dB */ | ||
87 | 0x0c000030,/* 41, -14.5dB */ | ||
88 | 0x0b40002d,/* 42, -15.0dB */ | ||
89 | }; | ||
90 | |||
91 | u8 CCKSwingTable_Ch1_Ch1323A[CCK_TABLE_SIZE][8] = { | ||
92 | {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */ | ||
93 | {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */ | ||
94 | {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */ | ||
95 | {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */ | ||
96 | {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */ | ||
97 | {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */ | ||
98 | {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */ | ||
99 | {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */ | ||
100 | {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */ | ||
101 | {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */ | ||
102 | {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */ | ||
103 | {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */ | ||
104 | {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */ | ||
105 | {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */ | ||
106 | {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */ | ||
107 | {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */ | ||
108 | {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */ | ||
109 | {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */ | ||
110 | {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */ | ||
111 | {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */ | ||
112 | {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB */ | ||
113 | {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB */ | ||
114 | {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB */ | ||
115 | {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB */ | ||
116 | {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB */ | ||
117 | {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB */ | ||
118 | {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB */ | ||
119 | {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB */ | ||
120 | {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB */ | ||
121 | {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB */ | ||
122 | {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB */ | ||
123 | {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB */ | ||
124 | {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB */ | ||
125 | }; | ||
126 | |||
127 | u8 CCKSwingTable_Ch1423A[CCK_TABLE_SIZE][8] = { | ||
128 | {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */ | ||
129 | {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */ | ||
130 | {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */ | ||
131 | {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */ | ||
132 | {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */ | ||
133 | {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */ | ||
134 | {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */ | ||
135 | {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */ | ||
136 | {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */ | ||
137 | {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */ | ||
138 | {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */ | ||
139 | {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */ | ||
140 | {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */ | ||
141 | {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */ | ||
142 | {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */ | ||
143 | {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */ | ||
144 | {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */ | ||
145 | {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */ | ||
146 | {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */ | ||
147 | {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */ | ||
148 | {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB */ | ||
149 | {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB */ | ||
150 | {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB */ | ||
151 | {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB */ | ||
152 | {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB */ | ||
153 | {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB */ | ||
154 | {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB */ | ||
155 | {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB */ | ||
156 | {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB */ | ||
157 | {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB */ | ||
158 | {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB */ | ||
159 | {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB */ | ||
160 | {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB */ | ||
161 | }; | ||
162 | |||
163 | /* Local Function predefine. */ | ||
164 | |||
165 | /* START------------COMMON INFO RELATED--------------- */ | ||
166 | void odm_CommonInfoSelfInit23a(struct dm_odm_t *pDM_Odm); | ||
167 | |||
168 | void odm_CommonInfoSelfUpdate23a(struct dm_odm_t *pDM_Odm); | ||
169 | |||
170 | void odm_CmnInfoInit_Debug23a(struct dm_odm_t *pDM_Odm); | ||
171 | |||
172 | void odm_CmnInfoHook_Debug23a(struct dm_odm_t *pDM_Odm); | ||
173 | |||
174 | void odm_CmnInfoUpdate_Debug23a(struct dm_odm_t *pDM_Odm); | ||
175 | |||
176 | /* START---------------DIG--------------------------- */ | ||
177 | void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm); | ||
178 | |||
179 | void odm_DIG23aInit(struct dm_odm_t *pDM_Odm); | ||
180 | |||
181 | void odm_DIG23a(struct dm_odm_t *pDM_Odm); | ||
182 | |||
183 | void odm_CCKPacketDetectionThresh23a(struct dm_odm_t *pDM_Odm); | ||
184 | /* END---------------DIG--------------------------- */ | ||
185 | |||
186 | /* START-------BB POWER SAVE----------------------- */ | ||
187 | void odm23a_DynBBPSInit(struct dm_odm_t *pDM_Odm); | ||
188 | |||
189 | void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm); | ||
190 | |||
191 | void odm_1R_CCA23a(struct dm_odm_t *pDM_Odm); | ||
192 | /* END---------BB POWER SAVE----------------------- */ | ||
193 | |||
194 | void odm_RefreshRateAdaptiveMask23aMP23a(struct dm_odm_t *pDM_Odm); | ||
195 | |||
196 | void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm); | ||
197 | |||
198 | void odm_RefreshRateAdaptiveMask23aAPADSL23a(struct dm_odm_t *pDM_Odm); | ||
199 | |||
200 | void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm); | ||
201 | |||
202 | void odm_DynamicTxPower23aRestorePowerIndex(struct dm_odm_t *pDM_Odm); | ||
203 | |||
204 | void odm_DynamicTxPower23aSavePowerIndex(struct dm_odm_t *pDM_Odm); | ||
205 | |||
206 | void odm_DynamicTxPower23aWritePowerIndex(struct dm_odm_t *pDM_Odm, | ||
207 | u8 Value); | ||
208 | |||
209 | void odm_DynamicTxPower23a_92C(struct dm_odm_t *pDM_Odm); | ||
210 | |||
211 | void odm_DynamicTxPower23a_92D(struct dm_odm_t *pDM_Odm); | ||
212 | |||
213 | void odm_RSSIMonitorInit(struct dm_odm_t *pDM_Odm); | ||
214 | |||
215 | void odm_RSSIMonitorCheck23aMP(struct dm_odm_t *pDM_Odm); | ||
216 | |||
217 | void odm_RSSIMonitorCheck23aCE(struct dm_odm_t *pDM_Odm); | ||
218 | void odm_RSSIMonitorCheck23aAP(struct dm_odm_t *pDM_Odm); | ||
219 | |||
220 | void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm); | ||
221 | void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm); | ||
222 | |||
223 | void odm_SwAntDivInit(struct dm_odm_t *pDM_Odm); | ||
224 | |||
225 | void odm_SwAntDivInit_NIC(struct dm_odm_t *pDM_Odm); | ||
226 | |||
227 | void odm_SwAntDivChkAntSwitch(struct dm_odm_t *pDM_Odm, u8 Step); | ||
228 | |||
229 | void odm_SwAntDivChkAntSwitchNIC(struct dm_odm_t *pDM_Odm, | ||
230 | u8 Step | ||
231 | ); | ||
232 | |||
233 | void odm_SwAntDivChkAntSwitchCallback23a(unsigned long data); | ||
234 | |||
235 | void odm_GlobalAdapterCheck(void); | ||
236 | |||
237 | void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm); | ||
238 | |||
239 | void ODM_TXPowerTrackingCheck23a(struct dm_odm_t *pDM_Odm); | ||
240 | |||
241 | void odm_TXPowerTrackingCheckAP(struct dm_odm_t *pDM_Odm); | ||
242 | |||
243 | void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm); | ||
244 | |||
245 | void odm_TXPowerTrackingThermalMeterInit23a(struct dm_odm_t *pDM_Odm); | ||
246 | |||
247 | void odm_TXPowerTrackingInit23a(struct dm_odm_t *pDM_Odm); | ||
248 | |||
249 | void odm_TXPowerTrackingCheckMP(struct dm_odm_t *pDM_Odm); | ||
250 | |||
251 | void odm_TXPowerTrackingCheckCE23a(struct dm_odm_t *pDM_Odm); | ||
252 | |||
253 | void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm); | ||
254 | void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm); | ||
255 | |||
256 | void odm_EdcaTurboCheck23aCE23a(struct dm_odm_t *pDM_Odm); | ||
257 | |||
258 | #define RxDefaultAnt1 0x65a9 | ||
259 | #define RxDefaultAnt2 0x569a | ||
260 | |||
261 | void odm_InitHybridAntDiv23a(struct dm_odm_t *pDM_Odm); | ||
262 | |||
263 | bool odm_StaDefAntSel(struct dm_odm_t *pDM_Odm, | ||
264 | u32 OFDM_Ant1_Cnt, | ||
265 | u32 OFDM_Ant2_Cnt, | ||
266 | u32 CCK_Ant1_Cnt, | ||
267 | u32 CCK_Ant2_Cnt, | ||
268 | u8 *pDefAnt | ||
269 | ); | ||
270 | |||
271 | void odm_SetRxIdleAnt(struct dm_odm_t *pDM_Odm, | ||
272 | u8 Ant, | ||
273 | bool bDualPath | ||
274 | ); | ||
275 | |||
276 | void odm_HwAntDiv23a(struct dm_odm_t *pDM_Odm); | ||
277 | |||
278 | /* 3 Export Interface */ | ||
279 | |||
280 | /* 2011/09/21 MH Add to describe different team necessary resource allocate?? */ | ||
281 | void ODM23a_DMInit(struct dm_odm_t *pDM_Odm) | ||
282 | { | ||
283 | /* For all IC series */ | ||
284 | odm_CommonInfoSelfInit23a(pDM_Odm); | ||
285 | odm_CmnInfoInit_Debug23a(pDM_Odm); | ||
286 | odm_DIG23aInit(pDM_Odm); | ||
287 | odm_RateAdaptiveMaskInit23a(pDM_Odm); | ||
288 | |||
289 | if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { | ||
290 | odm23a_DynBBPSInit(pDM_Odm); | ||
291 | odm_DynamicTxPower23aInit(pDM_Odm); | ||
292 | odm_TXPowerTrackingInit23a(pDM_Odm); | ||
293 | ODM_EdcaTurboInit23a(pDM_Odm); | ||
294 | if ((pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) || | ||
295 | (pDM_Odm->AntDivType == CGCS_RX_HW_ANTDIV) || | ||
296 | (pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV)) | ||
297 | odm_InitHybridAntDiv23a(pDM_Odm); | ||
298 | else if (pDM_Odm->AntDivType == CGCS_RX_SW_ANTDIV) | ||
299 | odm_SwAntDivInit(pDM_Odm); | ||
300 | } | ||
301 | } | ||
302 | |||
303 | /* 2011/09/20 MH This is the entry pointer for all team to execute HW out source DM. */ | ||
304 | /* You can not add any dummy function here, be care, you can only use DM structure */ | ||
305 | /* to perform any new ODM_DM. */ | ||
306 | void ODM_DMWatchdog23a(struct dm_odm_t *pDM_Odm) | ||
307 | { | ||
308 | /* 2012.05.03 Luke: For all IC series */ | ||
309 | odm_GlobalAdapterCheck(); | ||
310 | odm_CmnInfoHook_Debug23a(pDM_Odm); | ||
311 | odm_CmnInfoUpdate_Debug23a(pDM_Odm); | ||
312 | odm_CommonInfoSelfUpdate23a(pDM_Odm); | ||
313 | odm_FalseAlarmCounterStatistics23a(pDM_Odm); | ||
314 | odm_RSSIMonitorCheck23a(pDM_Odm); | ||
315 | |||
316 | /* 8723A or 8189ES platform */ | ||
317 | /* NeilChen--2012--08--24-- */ | ||
318 | /* Fix Leave LPS issue */ | ||
319 | if ((pDM_Odm->Adapter->pwrctrlpriv.pwr_mode != PS_MODE_ACTIVE) &&/* in LPS mode */ | ||
320 | (pDM_Odm->SupportICType & (ODM_RTL8723A))) { | ||
321 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("----Step1: odm_DIG23a is in LPS mode\n")); | ||
322 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("---Step2: 8723AS is in LPS mode\n")); | ||
323 | odm_DIG23abyRSSI_LPS(pDM_Odm); | ||
324 | } else { | ||
325 | odm_DIG23a(pDM_Odm); | ||
326 | } | ||
327 | |||
328 | odm_CCKPacketDetectionThresh23a(pDM_Odm); | ||
329 | |||
330 | if (*(pDM_Odm->pbPowerSaving)) | ||
331 | return; | ||
332 | |||
333 | odm_RefreshRateAdaptiveMask23a(pDM_Odm); | ||
334 | |||
335 | odm_DynamicBBPowerSaving23a(pDM_Odm); | ||
336 | if ((pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) || | ||
337 | (pDM_Odm->AntDivType == CGCS_RX_HW_ANTDIV) || | ||
338 | (pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV)) | ||
339 | odm_HwAntDiv23a(pDM_Odm); | ||
340 | else if (pDM_Odm->AntDivType == CGCS_RX_SW_ANTDIV) | ||
341 | odm_SwAntDivChkAntSwitch(pDM_Odm, SWAW_STEP_PEAK); | ||
342 | |||
343 | if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { | ||
344 | ODM_TXPowerTrackingCheck23a(pDM_Odm); | ||
345 | odm_EdcaTurboCheck23a(pDM_Odm); | ||
346 | odm_DynamicTxPower23a(pDM_Odm); | ||
347 | } | ||
348 | |||
349 | odm_dtc(pDM_Odm); | ||
350 | } | ||
351 | |||
352 | /* */ | ||
353 | /* Init /.. Fixed HW value. Only init time. */ | ||
354 | /* */ | ||
355 | void ODM_CmnInfoInit23a(struct dm_odm_t *pDM_Odm, | ||
356 | enum odm_cmninfo CmnInfo, | ||
357 | u32 Value | ||
358 | ) | ||
359 | { | ||
360 | /* ODM_RT_TRACE(pDM_Odm,); */ | ||
361 | |||
362 | /* */ | ||
363 | /* This section is used for init value */ | ||
364 | /* */ | ||
365 | switch (CmnInfo) { | ||
366 | /* Fixed ODM value. */ | ||
367 | case ODM_CMNINFO_ABILITY: | ||
368 | pDM_Odm->SupportAbility = (u32)Value; | ||
369 | break; | ||
370 | case ODM_CMNINFO_PLATFORM: | ||
371 | break; | ||
372 | case ODM_CMNINFO_INTERFACE: | ||
373 | pDM_Odm->SupportInterface = (u8)Value; | ||
374 | break; | ||
375 | case ODM_CMNINFO_MP_TEST_CHIP: | ||
376 | pDM_Odm->bIsMPChip = (u8)Value; | ||
377 | break; | ||
378 | case ODM_CMNINFO_IC_TYPE: | ||
379 | pDM_Odm->SupportICType = Value; | ||
380 | break; | ||
381 | case ODM_CMNINFO_CUT_VER: | ||
382 | pDM_Odm->CutVersion = (u8)Value; | ||
383 | break; | ||
384 | case ODM_CMNINFO_FAB_VER: | ||
385 | pDM_Odm->FabVersion = (u8)Value; | ||
386 | break; | ||
387 | case ODM_CMNINFO_RF_TYPE: | ||
388 | pDM_Odm->RFType = (u8)Value; | ||
389 | break; | ||
390 | case ODM_CMNINFO_RF_ANTENNA_TYPE: | ||
391 | pDM_Odm->AntDivType = (u8)Value; | ||
392 | break; | ||
393 | case ODM_CMNINFO_BOARD_TYPE: | ||
394 | pDM_Odm->BoardType = (u8)Value; | ||
395 | break; | ||
396 | case ODM_CMNINFO_EXT_LNA: | ||
397 | pDM_Odm->ExtLNA = (u8)Value; | ||
398 | break; | ||
399 | case ODM_CMNINFO_EXT_PA: | ||
400 | pDM_Odm->ExtPA = (u8)Value; | ||
401 | break; | ||
402 | case ODM_CMNINFO_EXT_TRSW: | ||
403 | pDM_Odm->ExtTRSW = (u8)Value; | ||
404 | break; | ||
405 | case ODM_CMNINFO_PATCH_ID: | ||
406 | pDM_Odm->PatchID = (u8)Value; | ||
407 | break; | ||
408 | case ODM_CMNINFO_BINHCT_TEST: | ||
409 | pDM_Odm->bInHctTest = (bool)Value; | ||
410 | break; | ||
411 | case ODM_CMNINFO_BWIFI_TEST: | ||
412 | pDM_Odm->bWIFITest = (bool)Value; | ||
413 | break; | ||
414 | case ODM_CMNINFO_SMART_CONCURRENT: | ||
415 | pDM_Odm->bDualMacSmartConcurrent = (bool)Value; | ||
416 | break; | ||
417 | /* To remove the compiler warning, must add an empty default statement to handle the other values. */ | ||
418 | default: | ||
419 | /* do nothing */ | ||
420 | break; | ||
421 | } | ||
422 | |||
423 | /* */ | ||
424 | /* Tx power tracking BB swing table. */ | ||
425 | /* The base index = 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB */ | ||
426 | /* */ | ||
427 | pDM_Odm->BbSwingIdxOfdm = 12; /* Set defalut value as index 12. */ | ||
428 | pDM_Odm->BbSwingIdxOfdmCurrent = 12; | ||
429 | pDM_Odm->BbSwingFlagOfdm = false; | ||
430 | |||
431 | } | ||
432 | |||
433 | void ODM23a_CmnInfoHook(struct dm_odm_t *pDM_Odm, | ||
434 | enum odm_cmninfo CmnInfo, | ||
435 | void *pValue | ||
436 | ) | ||
437 | { | ||
438 | /* Hook call by reference pointer. */ | ||
439 | switch (CmnInfo) { | ||
440 | /* Dynamic call by reference pointer. */ | ||
441 | case ODM_CMNINFO_MAC_PHY_MODE: | ||
442 | pDM_Odm->pMacPhyMode = (u8 *)pValue; | ||
443 | break; | ||
444 | case ODM_CMNINFO_TX_UNI: | ||
445 | pDM_Odm->pNumTxBytesUnicast = (u64 *)pValue; | ||
446 | break; | ||
447 | case ODM_CMNINFO_RX_UNI: | ||
448 | pDM_Odm->pNumRxBytesUnicast = (u64 *)pValue; | ||
449 | break; | ||
450 | case ODM_CMNINFO_WM_MODE: | ||
451 | pDM_Odm->pWirelessMode = (u8 *)pValue; | ||
452 | break; | ||
453 | case ODM_CMNINFO_BAND: | ||
454 | pDM_Odm->pBandType = (u8 *)pValue; | ||
455 | break; | ||
456 | case ODM_CMNINFO_SEC_CHNL_OFFSET: | ||
457 | pDM_Odm->pSecChOffset = (u8 *)pValue; | ||
458 | break; | ||
459 | case ODM_CMNINFO_SEC_MODE: | ||
460 | pDM_Odm->pSecurity = (u8 *)pValue; | ||
461 | break; | ||
462 | case ODM_CMNINFO_BW: | ||
463 | pDM_Odm->pBandWidth = (u8 *)pValue; | ||
464 | break; | ||
465 | case ODM_CMNINFO_CHNL: | ||
466 | pDM_Odm->pChannel = (u8 *)pValue; | ||
467 | break; | ||
468 | case ODM_CMNINFO_DMSP_GET_VALUE: | ||
469 | pDM_Odm->pbGetValueFromOtherMac = (bool *)pValue; | ||
470 | break; | ||
471 | case ODM_CMNINFO_BUDDY_ADAPTOR: | ||
472 | pDM_Odm->pBuddyAdapter = (struct rtw_adapter **)pValue; | ||
473 | break; | ||
474 | case ODM_CMNINFO_DMSP_IS_MASTER: | ||
475 | pDM_Odm->pbMasterOfDMSP = (bool *)pValue; | ||
476 | break; | ||
477 | case ODM_CMNINFO_SCAN: | ||
478 | pDM_Odm->pbScanInProcess = (bool *)pValue; | ||
479 | break; | ||
480 | case ODM_CMNINFO_POWER_SAVING: | ||
481 | pDM_Odm->pbPowerSaving = (bool *)pValue; | ||
482 | break; | ||
483 | case ODM_CMNINFO_ONE_PATH_CCA: | ||
484 | pDM_Odm->pOnePathCCA = (u8 *)pValue; | ||
485 | break; | ||
486 | case ODM_CMNINFO_DRV_STOP: | ||
487 | pDM_Odm->pbDriverStopped = (bool *)pValue; | ||
488 | break; | ||
489 | case ODM_CMNINFO_PNP_IN: | ||
490 | pDM_Odm->pbDriverIsGoingToPnpSetPowerSleep = (bool *)pValue; | ||
491 | break; | ||
492 | case ODM_CMNINFO_INIT_ON: | ||
493 | pDM_Odm->pinit_adpt_in_progress = (bool *)pValue; | ||
494 | break; | ||
495 | case ODM_CMNINFO_ANT_TEST: | ||
496 | pDM_Odm->pAntennaTest = (u8 *)pValue; | ||
497 | break; | ||
498 | case ODM_CMNINFO_NET_CLOSED: | ||
499 | pDM_Odm->pbNet_closed = (bool *)pValue; | ||
500 | break; | ||
501 | /* To remove the compiler warning, must add an empty default statement to handle the other values. */ | ||
502 | default: | ||
503 | /* do nothing */ | ||
504 | break; | ||
505 | } | ||
506 | } | ||
507 | |||
508 | void ODM_CmnInfoPtrArrayHook23a(struct dm_odm_t *pDM_Odm, enum odm_cmninfo CmnInfo, | ||
509 | u16 Index, void *pValue) | ||
510 | { | ||
511 | /* Hook call by reference pointer. */ | ||
512 | switch (CmnInfo) { | ||
513 | /* Dynamic call by reference pointer. */ | ||
514 | case ODM_CMNINFO_STA_STATUS: | ||
515 | pDM_Odm->pODM_StaInfo[Index] = (struct sta_info *)pValue; | ||
516 | break; | ||
517 | /* To remove the compiler warning, must add an empty default statement to handle the other values. */ | ||
518 | default: | ||
519 | /* do nothing */ | ||
520 | break; | ||
521 | } | ||
522 | } | ||
523 | |||
524 | /* Update Band/CHannel/.. The values are dynamic but non-per-packet. */ | ||
525 | void ODM_CmnInfoUpdate23a(struct dm_odm_t *pDM_Odm, u32 CmnInfo, u64 Value) | ||
526 | { | ||
527 | /* This init variable may be changed in run time. */ | ||
528 | switch (CmnInfo) { | ||
529 | case ODM_CMNINFO_ABILITY: | ||
530 | pDM_Odm->SupportAbility = (u32)Value; | ||
531 | break; | ||
532 | case ODM_CMNINFO_RF_TYPE: | ||
533 | pDM_Odm->RFType = (u8)Value; | ||
534 | break; | ||
535 | case ODM_CMNINFO_WIFI_DIRECT: | ||
536 | pDM_Odm->bWIFI_Direct = (bool)Value; | ||
537 | break; | ||
538 | case ODM_CMNINFO_WIFI_DISPLAY: | ||
539 | pDM_Odm->bWIFI_Display = (bool)Value; | ||
540 | break; | ||
541 | case ODM_CMNINFO_LINK: | ||
542 | pDM_Odm->bLinked = (bool)Value; | ||
543 | break; | ||
544 | case ODM_CMNINFO_RSSI_MIN: | ||
545 | pDM_Odm->RSSI_Min = (u8)Value; | ||
546 | break; | ||
547 | case ODM_CMNINFO_DBG_COMP: | ||
548 | pDM_Odm->DebugComponents = Value; | ||
549 | break; | ||
550 | case ODM_CMNINFO_DBG_LEVEL: | ||
551 | pDM_Odm->DebugLevel = (u32)Value; | ||
552 | break; | ||
553 | case ODM_CMNINFO_RA_THRESHOLD_HIGH: | ||
554 | pDM_Odm->RateAdaptive.HighRSSIThresh = (u8)Value; | ||
555 | break; | ||
556 | case ODM_CMNINFO_RA_THRESHOLD_LOW: | ||
557 | pDM_Odm->RateAdaptive.LowRSSIThresh = (u8)Value; | ||
558 | break; | ||
559 | } | ||
560 | |||
561 | } | ||
562 | |||
563 | void odm_CommonInfoSelfInit23a(struct dm_odm_t *pDM_Odm | ||
564 | ) | ||
565 | { | ||
566 | pDM_Odm->bCckHighPower = (bool) ODM_GetBBReg(pDM_Odm, 0x824, BIT9); | ||
567 | pDM_Odm->RFPathRxEnable = (u8) ODM_GetBBReg(pDM_Odm, 0xc04, 0x0F); | ||
568 | if (pDM_Odm->SupportICType & (ODM_RTL8723A)) | ||
569 | pDM_Odm->AntDivType = CGCS_RX_SW_ANTDIV; | ||
570 | |||
571 | ODM_InitDebugSetting23a(pDM_Odm); | ||
572 | } | ||
573 | |||
574 | void odm_CommonInfoSelfUpdate23a(struct dm_odm_t *pDM_Odm) | ||
575 | { | ||
576 | u8 EntryCnt = 0; | ||
577 | u8 i; | ||
578 | struct sta_info *pEntry; | ||
579 | |||
580 | if (*(pDM_Odm->pBandWidth) == ODM_BW40M) { | ||
581 | if (*(pDM_Odm->pSecChOffset) == 1) | ||
582 | pDM_Odm->ControlChannel = *(pDM_Odm->pChannel) - 2; | ||
583 | else if (*(pDM_Odm->pSecChOffset) == 2) | ||
584 | pDM_Odm->ControlChannel = *(pDM_Odm->pChannel) + 2; | ||
585 | } else { | ||
586 | pDM_Odm->ControlChannel = *(pDM_Odm->pChannel); | ||
587 | } | ||
588 | |||
589 | for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { | ||
590 | pEntry = pDM_Odm->pODM_StaInfo[i]; | ||
591 | if (IS_STA_VALID(pEntry)) | ||
592 | EntryCnt++; | ||
593 | } | ||
594 | if (EntryCnt == 1) | ||
595 | pDM_Odm->bOneEntryOnly = true; | ||
596 | else | ||
597 | pDM_Odm->bOneEntryOnly = false; | ||
598 | } | ||
599 | |||
600 | void odm_CmnInfoInit_Debug23a(struct dm_odm_t *pDM_Odm) | ||
601 | { | ||
602 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoInit_Debug23a ==>\n")); | ||
603 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportAbility = 0x%x\n", pDM_Odm->SupportAbility)); | ||
604 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportInterface =%d\n", pDM_Odm->SupportInterface)); | ||
605 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("SupportICType = 0x%x\n", pDM_Odm->SupportICType)); | ||
606 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("CutVersion =%d\n", pDM_Odm->CutVersion)); | ||
607 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("FabVersion =%d\n", pDM_Odm->FabVersion)); | ||
608 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("RFType =%d\n", pDM_Odm->RFType)); | ||
609 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("BoardType =%d\n", pDM_Odm->BoardType)); | ||
610 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtLNA =%d\n", pDM_Odm->ExtLNA)); | ||
611 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtPA =%d\n", pDM_Odm->ExtPA)); | ||
612 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("ExtTRSW =%d\n", pDM_Odm->ExtTRSW)); | ||
613 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("PatchID =%d\n", pDM_Odm->PatchID)); | ||
614 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bInHctTest =%d\n", pDM_Odm->bInHctTest)); | ||
615 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bWIFITest =%d\n", pDM_Odm->bWIFITest)); | ||
616 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bDualMacSmartConcurrent =%d\n", pDM_Odm->bDualMacSmartConcurrent)); | ||
617 | |||
618 | } | ||
619 | |||
620 | void odm_CmnInfoHook_Debug23a(struct dm_odm_t *pDM_Odm) | ||
621 | { | ||
622 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoHook_Debug23a ==>\n")); | ||
623 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pNumTxBytesUnicast =%llu\n", *(pDM_Odm->pNumTxBytesUnicast))); | ||
624 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pNumRxBytesUnicast =%llu\n", *(pDM_Odm->pNumRxBytesUnicast))); | ||
625 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pWirelessMode = 0x%x\n", *(pDM_Odm->pWirelessMode))); | ||
626 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pSecChOffset =%d\n", *(pDM_Odm->pSecChOffset))); | ||
627 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pSecurity =%d\n", *(pDM_Odm->pSecurity))); | ||
628 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pBandWidth =%d\n", *(pDM_Odm->pBandWidth))); | ||
629 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pChannel =%d\n", *(pDM_Odm->pChannel))); | ||
630 | |||
631 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pbScanInProcess =%d\n", *(pDM_Odm->pbScanInProcess))); | ||
632 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pbPowerSaving =%d\n", *(pDM_Odm->pbPowerSaving))); | ||
633 | } | ||
634 | |||
635 | void odm_CmnInfoUpdate_Debug23a(struct dm_odm_t *pDM_Odm) | ||
636 | { | ||
637 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoUpdate_Debug23a ==>\n")); | ||
638 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bWIFI_Direct =%d\n", pDM_Odm->bWIFI_Direct)); | ||
639 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bWIFI_Display =%d\n", pDM_Odm->bWIFI_Display)); | ||
640 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("bLinked =%d\n", pDM_Odm->bLinked)); | ||
641 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("RSSI_Min =%d\n", pDM_Odm->RSSI_Min)); | ||
642 | } | ||
643 | |||
644 | void ODM_Write_DIG23a(struct dm_odm_t *pDM_Odm, | ||
645 | u8 CurrentIGI | ||
646 | ) | ||
647 | { | ||
648 | struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; | ||
649 | |||
650 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("ODM_REG(IGI_A, pDM_Odm) = 0x%x, ODM_BIT(IGI, pDM_Odm) = 0x%x \n", | ||
651 | ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm))); | ||
652 | |||
653 | if (pDM_DigTable->CurIGValue != CurrentIGI) { | ||
654 | ODM_SetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm), CurrentIGI); | ||
655 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("CurrentIGI(0x%02x). \n", CurrentIGI)); | ||
656 | pDM_DigTable->CurIGValue = CurrentIGI; | ||
657 | } | ||
658 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, | ||
659 | ("ODM_Write_DIG23a():CurrentIGI = 0x%x \n", CurrentIGI)); | ||
660 | } | ||
661 | |||
662 | /* Need LPS mode for CE platform --2012--08--24--- */ | ||
663 | /* 8723AS/8189ES */ | ||
664 | void odm_DIG23abyRSSI_LPS(struct dm_odm_t *pDM_Odm) | ||
665 | { | ||
666 | struct rtw_adapter *pAdapter = pDM_Odm->Adapter; | ||
667 | struct false_alarm_stats *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; | ||
668 | u8 RSSI_Lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */ | ||
669 | u8 bFwCurrentInPSMode = false; | ||
670 | u8 CurrentIGI = pDM_Odm->RSSI_Min; | ||
671 | |||
672 | if (!(pDM_Odm->SupportICType & (ODM_RTL8723A))) | ||
673 | return; | ||
674 | |||
675 | CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG; | ||
676 | bFwCurrentInPSMode = pAdapter->pwrctrlpriv.bFwCurrentInPSMode; | ||
677 | |||
678 | /* ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG_LPS, ODM_DBG_LOUD, ("odm_DIG23a() ==>\n")); */ | ||
679 | |||
680 | /* Using FW PS mode to make IGI */ | ||
681 | if (bFwCurrentInPSMode) { | ||
682 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("---Neil---odm_DIG23a is in LPS mode\n")); | ||
683 | /* Adjust by FA in LPS MODE */ | ||
684 | if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2_LPS) | ||
685 | CurrentIGI = CurrentIGI+2; | ||
686 | else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1_LPS) | ||
687 | CurrentIGI = CurrentIGI+1; | ||
688 | else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0_LPS) | ||
689 | CurrentIGI = CurrentIGI-1; | ||
690 | } else { | ||
691 | CurrentIGI = RSSI_Lower; | ||
692 | } | ||
693 | |||
694 | /* Lower bound checking */ | ||
695 | |||
696 | /* RSSI Lower bound check */ | ||
697 | if ((pDM_Odm->RSSI_Min-10) > DM_DIG_MIN_NIC) | ||
698 | RSSI_Lower = (pDM_Odm->RSSI_Min-10); | ||
699 | else | ||
700 | RSSI_Lower = DM_DIG_MIN_NIC; | ||
701 | |||
702 | /* Upper and Lower Bound checking */ | ||
703 | if (CurrentIGI > DM_DIG_MAX_NIC) | ||
704 | CurrentIGI = DM_DIG_MAX_NIC; | ||
705 | else if (CurrentIGI < RSSI_Lower) | ||
706 | CurrentIGI = RSSI_Lower; | ||
707 | |||
708 | ODM_Write_DIG23a(pDM_Odm, CurrentIGI);/* ODM_Write_DIG23a(pDM_Odm, pDM_DigTable->CurIGValue); */ | ||
709 | |||
710 | } | ||
711 | |||
712 | void odm_DIG23aInit(struct dm_odm_t *pDM_Odm) | ||
713 | { | ||
714 | struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; | ||
715 | |||
716 | pDM_DigTable->CurIGValue = (u8) ODM_GetBBReg(pDM_Odm, ODM_REG(IGI_A, pDM_Odm), ODM_BIT(IGI, pDM_Odm)); | ||
717 | pDM_DigTable->RssiLowThresh = DM_DIG_THRESH_LOW; | ||
718 | pDM_DigTable->RssiHighThresh = DM_DIG_THRESH_HIGH; | ||
719 | pDM_DigTable->FALowThresh = DM_FALSEALARM_THRESH_LOW; | ||
720 | pDM_DigTable->FAHighThresh = DM_FALSEALARM_THRESH_HIGH; | ||
721 | if (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) { | ||
722 | pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; | ||
723 | pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; | ||
724 | } else { | ||
725 | pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; | ||
726 | pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; | ||
727 | } | ||
728 | pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT; | ||
729 | pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX; | ||
730 | pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN; | ||
731 | pDM_DigTable->PreCCK_CCAThres = 0xFF; | ||
732 | pDM_DigTable->CurCCK_CCAThres = 0x83; | ||
733 | pDM_DigTable->ForbiddenIGI = DM_DIG_MIN_NIC; | ||
734 | pDM_DigTable->LargeFAHit = 0; | ||
735 | pDM_DigTable->Recover_cnt = 0; | ||
736 | pDM_DigTable->DIG_Dynamic_MIN_0 = DM_DIG_MIN_NIC; | ||
737 | pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC; | ||
738 | pDM_DigTable->bMediaConnect_0 = false; | ||
739 | pDM_DigTable->bMediaConnect_1 = false; | ||
740 | |||
741 | /* To Initialize pDM_Odm->bDMInitialGainEnable == false to avoid DIG error */ | ||
742 | pDM_Odm->bDMInitialGainEnable = true; | ||
743 | |||
744 | } | ||
745 | |||
746 | void odm_DIG23a(struct dm_odm_t *pDM_Odm) | ||
747 | { | ||
748 | |||
749 | struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; | ||
750 | struct false_alarm_stats *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt; | ||
751 | u8 DIG_Dynamic_MIN; | ||
752 | u8 DIG_MaxOfMin; | ||
753 | bool FirstConnect, FirstDisConnect; | ||
754 | u8 dm_dig_max, dm_dig_min; | ||
755 | u8 CurrentIGI = pDM_DigTable->CurIGValue; | ||
756 | |||
757 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a() ==>\n")); | ||
758 | /* if (!(pDM_Odm->SupportAbility & (ODM_BB_DIG|ODM_BB_FA_CNT))) */ | ||
759 | if ((!(pDM_Odm->SupportAbility&ODM_BB_DIG)) || (!(pDM_Odm->SupportAbility&ODM_BB_FA_CNT))) { | ||
760 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, | ||
761 | ("odm_DIG23a() Return: SupportAbility ODM_BB_DIG or ODM_BB_FA_CNT is disabled\n")); | ||
762 | return; | ||
763 | } | ||
764 | |||
765 | if (*(pDM_Odm->pbScanInProcess)) { | ||
766 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a() Return: In Scan Progress \n")); | ||
767 | return; | ||
768 | } | ||
769 | |||
770 | /* add by Neil Chen to avoid PSD is processing */ | ||
771 | if (!pDM_Odm->bDMInitialGainEnable) { | ||
772 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a() Return: PSD is Processing \n")); | ||
773 | return; | ||
774 | } | ||
775 | |||
776 | DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0; | ||
777 | FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_0); | ||
778 | FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0); | ||
779 | |||
780 | /* 1 Boundary Decision */ | ||
781 | if ((pDM_Odm->SupportICType & (ODM_RTL8723A)) && | ||
782 | ((pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) || pDM_Odm->ExtLNA)) { | ||
783 | dm_dig_max = DM_DIG_MAX_NIC_HP; | ||
784 | dm_dig_min = DM_DIG_MIN_NIC_HP; | ||
785 | DIG_MaxOfMin = DM_DIG_MAX_AP_HP; | ||
786 | } else { | ||
787 | dm_dig_max = DM_DIG_MAX_NIC; | ||
788 | dm_dig_min = DM_DIG_MIN_NIC; | ||
789 | DIG_MaxOfMin = DM_DIG_MAX_AP; | ||
790 | } | ||
791 | |||
792 | if (pDM_Odm->bLinked) { | ||
793 | /* 2 8723A Series, offset need to be 10 */ | ||
794 | if (pDM_Odm->SupportICType == (ODM_RTL8723A)) { | ||
795 | /* 2 Upper Bound */ | ||
796 | if ((pDM_Odm->RSSI_Min + 10) > DM_DIG_MAX_NIC) | ||
797 | pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; | ||
798 | else if ((pDM_Odm->RSSI_Min + 10) < DM_DIG_MIN_NIC) | ||
799 | pDM_DigTable->rx_gain_range_max = DM_DIG_MIN_NIC; | ||
800 | else | ||
801 | pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + 10; | ||
802 | |||
803 | /* 2 If BT is Concurrent, need to set Lower Bound */ | ||
804 | DIG_Dynamic_MIN = DM_DIG_MIN_NIC; | ||
805 | } else { | ||
806 | /* 2 Modify DIG upper bound */ | ||
807 | if ((pDM_Odm->RSSI_Min + 20) > dm_dig_max) | ||
808 | pDM_DigTable->rx_gain_range_max = dm_dig_max; | ||
809 | else if ((pDM_Odm->RSSI_Min + 20) < dm_dig_min) | ||
810 | pDM_DigTable->rx_gain_range_max = dm_dig_min; | ||
811 | else | ||
812 | pDM_DigTable->rx_gain_range_max = pDM_Odm->RSSI_Min + 20; | ||
813 | |||
814 | /* 2 Modify DIG lower bound */ | ||
815 | if (pDM_Odm->bOneEntryOnly) { | ||
816 | if (pDM_Odm->RSSI_Min < dm_dig_min) | ||
817 | DIG_Dynamic_MIN = dm_dig_min; | ||
818 | else if (pDM_Odm->RSSI_Min > DIG_MaxOfMin) | ||
819 | DIG_Dynamic_MIN = DIG_MaxOfMin; | ||
820 | else | ||
821 | DIG_Dynamic_MIN = pDM_Odm->RSSI_Min; | ||
822 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, | ||
823 | ("odm_DIG23a() : bOneEntryOnly = true, DIG_Dynamic_MIN = 0x%x\n", | ||
824 | DIG_Dynamic_MIN)); | ||
825 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, | ||
826 | ("odm_DIG23a() : pDM_Odm->RSSI_Min =%d\n", | ||
827 | pDM_Odm->RSSI_Min)); | ||
828 | } else { | ||
829 | DIG_Dynamic_MIN = dm_dig_min; | ||
830 | } | ||
831 | } | ||
832 | } else { | ||
833 | pDM_DigTable->rx_gain_range_max = dm_dig_max; | ||
834 | DIG_Dynamic_MIN = dm_dig_min; | ||
835 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a() : No Link\n")); | ||
836 | } | ||
837 | |||
838 | /* 1 Modify DIG lower bound, deal with abnormally large false alarm */ | ||
839 | if (pFalseAlmCnt->Cnt_all > 10000) { | ||
840 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, | ||
841 | ("dm_DIG(): Abnornally false alarm case. \n")); | ||
842 | |||
843 | if (pDM_DigTable->LargeFAHit != 3) | ||
844 | pDM_DigTable->LargeFAHit++; | ||
845 | if (pDM_DigTable->ForbiddenIGI < CurrentIGI) { | ||
846 | pDM_DigTable->ForbiddenIGI = CurrentIGI; | ||
847 | pDM_DigTable->LargeFAHit = 1; | ||
848 | } | ||
849 | |||
850 | if (pDM_DigTable->LargeFAHit >= 3) { | ||
851 | if ((pDM_DigTable->ForbiddenIGI+1) > pDM_DigTable->rx_gain_range_max) | ||
852 | pDM_DigTable->rx_gain_range_min = pDM_DigTable->rx_gain_range_max; | ||
853 | else | ||
854 | pDM_DigTable->rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1); | ||
855 | pDM_DigTable->Recover_cnt = 3600; /* 3600 = 2hr */ | ||
856 | } | ||
857 | } else { | ||
858 | /* Recovery mechanism for IGI lower bound */ | ||
859 | if (pDM_DigTable->Recover_cnt != 0) { | ||
860 | pDM_DigTable->Recover_cnt--; | ||
861 | } else { | ||
862 | if (pDM_DigTable->LargeFAHit < 3) { | ||
863 | if ((pDM_DigTable->ForbiddenIGI - 1) < DIG_Dynamic_MIN) { | ||
864 | pDM_DigTable->ForbiddenIGI = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ | ||
865 | pDM_DigTable->rx_gain_range_min = DIG_Dynamic_MIN; /* DM_DIG_MIN; */ | ||
866 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, | ||
867 | ("odm_DIG23a(): Normal Case: At Lower Bound\n")); | ||
868 | } else { | ||
869 | pDM_DigTable->ForbiddenIGI--; | ||
870 | pDM_DigTable->rx_gain_range_min = (pDM_DigTable->ForbiddenIGI + 1); | ||
871 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, | ||
872 | ("odm_DIG23a(): Normal Case: Approach Lower Bound\n")); | ||
873 | } | ||
874 | } else { | ||
875 | pDM_DigTable->LargeFAHit = 0; | ||
876 | } | ||
877 | } | ||
878 | } | ||
879 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): pDM_DigTable->LargeFAHit =%d\n", pDM_DigTable->LargeFAHit)); | ||
880 | |||
881 | /* 1 Adjust initial gain by false alarm */ | ||
882 | if (pDM_Odm->bLinked) { | ||
883 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): DIG AfterLink\n")); | ||
884 | if (FirstConnect) { | ||
885 | CurrentIGI = pDM_Odm->RSSI_Min; | ||
886 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: First Connect\n")); | ||
887 | } else { | ||
888 | if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH2) | ||
889 | CurrentIGI = CurrentIGI + 4;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */ | ||
890 | else if (pFalseAlmCnt->Cnt_all > DM_DIG_FA_TH1) | ||
891 | CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */ | ||
892 | else if (pFalseAlmCnt->Cnt_all < DM_DIG_FA_TH0) | ||
893 | CurrentIGI = CurrentIGI - 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue-1; */ | ||
894 | } | ||
895 | } else { | ||
896 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): DIG BeforeLink\n")); | ||
897 | if (FirstDisConnect) { | ||
898 | CurrentIGI = pDM_DigTable->rx_gain_range_min; | ||
899 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): First DisConnect \n")); | ||
900 | } else { | ||
901 | /* 2012.03.30 LukeLee: enable DIG before link but with very high thresholds */ | ||
902 | if (pFalseAlmCnt->Cnt_all > 10000) | ||
903 | CurrentIGI = CurrentIGI + 2;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+2; */ | ||
904 | else if (pFalseAlmCnt->Cnt_all > 8000) | ||
905 | CurrentIGI = CurrentIGI + 1;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue+1; */ | ||
906 | else if (pFalseAlmCnt->Cnt_all < 500) | ||
907 | CurrentIGI = CurrentIGI - 1;/* pDM_DigTable->CurIGValue = pDM_DigTable->PreIGValue-1; */ | ||
908 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): England DIG \n")); | ||
909 | } | ||
910 | } | ||
911 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): DIG End Adjust IGI\n")); | ||
912 | /* 1 Check initial gain by upper/lower bound */ | ||
913 | if (CurrentIGI > pDM_DigTable->rx_gain_range_max) | ||
914 | CurrentIGI = pDM_DigTable->rx_gain_range_max; | ||
915 | if (CurrentIGI < pDM_DigTable->rx_gain_range_min) | ||
916 | CurrentIGI = pDM_DigTable->rx_gain_range_min; | ||
917 | |||
918 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): rx_gain_range_max = 0x%x, rx_gain_range_min = 0x%x\n", | ||
919 | pDM_DigTable->rx_gain_range_max, pDM_DigTable->rx_gain_range_min)); | ||
920 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): TotalFA =%d\n", pFalseAlmCnt->Cnt_all)); | ||
921 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a(): CurIGValue = 0x%x\n", CurrentIGI)); | ||
922 | |||
923 | /* 2 High power RSSI threshold */ | ||
924 | |||
925 | ODM_Write_DIG23a(pDM_Odm, CurrentIGI);/* ODM_Write_DIG23a(pDM_Odm, pDM_DigTable->CurIGValue); */ | ||
926 | pDM_DigTable->bMediaConnect_0 = pDM_Odm->bLinked; | ||
927 | pDM_DigTable->DIG_Dynamic_MIN_0 = DIG_Dynamic_MIN; | ||
928 | } | ||
929 | |||
930 | /* 3 ============================================================ */ | ||
931 | /* 3 FASLE ALARM CHECK */ | ||
932 | /* 3 ============================================================ */ | ||
933 | |||
934 | void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm) | ||
935 | { | ||
936 | u32 ret_value; | ||
937 | struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; | ||
938 | |||
939 | if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT)) | ||
940 | return; | ||
941 | |||
942 | if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { | ||
943 | /* hold ofdm counter */ | ||
944 | ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 1); /* hold page C counter */ | ||
945 | ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 1); /* hold page D counter */ | ||
946 | |||
947 | ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord); | ||
948 | FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff); | ||
949 | FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16); | ||
950 | ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord); | ||
951 | FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff); | ||
952 | FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16); | ||
953 | ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord); | ||
954 | FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff); | ||
955 | FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16); | ||
956 | ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord); | ||
957 | FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff); | ||
958 | |||
959 | FalseAlmCnt->Cnt_Ofdm_fail = FalseAlmCnt->Cnt_Parity_Fail + | ||
960 | FalseAlmCnt->Cnt_Rate_Illegal + | ||
961 | FalseAlmCnt->Cnt_Crc8_fail + | ||
962 | FalseAlmCnt->Cnt_Mcs_fail + | ||
963 | FalseAlmCnt->Cnt_Fast_Fsync + | ||
964 | FalseAlmCnt->Cnt_SB_Search_fail; | ||
965 | /* hold cck counter */ | ||
966 | ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT12, 1); | ||
967 | ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT14, 1); | ||
968 | |||
969 | ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_LSB_11N, bMaskByte0); | ||
970 | FalseAlmCnt->Cnt_Cck_fail = ret_value; | ||
971 | ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_MSB_11N, bMaskByte3); | ||
972 | FalseAlmCnt->Cnt_Cck_fail += (ret_value & 0xff) << 8; | ||
973 | |||
974 | ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord); | ||
975 | FalseAlmCnt->Cnt_CCK_CCA = ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8); | ||
976 | |||
977 | FalseAlmCnt->Cnt_all = (FalseAlmCnt->Cnt_Fast_Fsync + | ||
978 | FalseAlmCnt->Cnt_SB_Search_fail + | ||
979 | FalseAlmCnt->Cnt_Parity_Fail + | ||
980 | FalseAlmCnt->Cnt_Rate_Illegal + | ||
981 | FalseAlmCnt->Cnt_Crc8_fail + | ||
982 | FalseAlmCnt->Cnt_Mcs_fail + | ||
983 | FalseAlmCnt->Cnt_Cck_fail); | ||
984 | |||
985 | FalseAlmCnt->Cnt_CCA_all = FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA; | ||
986 | |||
987 | if (pDM_Odm->SupportICType >= ODM_RTL8723A) { | ||
988 | /* reset false alarm counter registers */ | ||
989 | ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT31, 1); | ||
990 | ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT31, 0); | ||
991 | ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT27, 1); | ||
992 | ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT27, 0); | ||
993 | /* update ofdm counter */ | ||
994 | ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT31, 0); /* update page C counter */ | ||
995 | ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT31, 0); /* update page D counter */ | ||
996 | |||
997 | /* reset CCK CCA counter */ | ||
998 | ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT13|BIT12, 0); | ||
999 | ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT13|BIT12, 2); | ||
1000 | /* reset CCK FA counter */ | ||
1001 | ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT15|BIT14, 0); | ||
1002 | ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT15|BIT14, 2); | ||
1003 | } | ||
1004 | |||
1005 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Enter odm_FalseAlarmCounterStatistics23a\n")); | ||
1006 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Fast_Fsync =%d, Cnt_SB_Search_fail =%d\n", | ||
1007 | FalseAlmCnt->Cnt_Fast_Fsync, FalseAlmCnt->Cnt_SB_Search_fail)); | ||
1008 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Parity_Fail =%d, Cnt_Rate_Illegal =%d\n", | ||
1009 | FalseAlmCnt->Cnt_Parity_Fail, FalseAlmCnt->Cnt_Rate_Illegal)); | ||
1010 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Crc8_fail =%d, Cnt_Mcs_fail =%d\n", | ||
1011 | FalseAlmCnt->Cnt_Crc8_fail, FalseAlmCnt->Cnt_Mcs_fail)); | ||
1012 | } else { /* FOR ODM_IC_11AC_SERIES */ | ||
1013 | /* read OFDM FA counter */ | ||
1014 | FalseAlmCnt->Cnt_Ofdm_fail = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_11AC, bMaskLWord); | ||
1015 | FalseAlmCnt->Cnt_Cck_fail = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_11AC, bMaskLWord); | ||
1016 | FalseAlmCnt->Cnt_all = FalseAlmCnt->Cnt_Ofdm_fail + FalseAlmCnt->Cnt_Cck_fail; | ||
1017 | |||
1018 | /* reset OFDM FA coutner */ | ||
1019 | ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RST_11AC, BIT17, 1); | ||
1020 | ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RST_11AC, BIT17, 0); | ||
1021 | /* reset CCK FA counter */ | ||
1022 | ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11AC, BIT15, 0); | ||
1023 | ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11AC, BIT15, 1); | ||
1024 | } | ||
1025 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Cck_fail =%d\n", FalseAlmCnt->Cnt_Cck_fail)); | ||
1026 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Ofdm_fail =%d\n", FalseAlmCnt->Cnt_Ofdm_fail)); | ||
1027 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Total False Alarm =%d\n", FalseAlmCnt->Cnt_all)); | ||
1028 | } | ||
1029 | |||
1030 | /* 3 ============================================================ */ | ||
1031 | /* 3 CCK Packet Detect Threshold */ | ||
1032 | /* 3 ============================================================ */ | ||
1033 | |||
1034 | void odm_CCKPacketDetectionThresh23a(struct dm_odm_t *pDM_Odm) | ||
1035 | { | ||
1036 | struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; | ||
1037 | u8 CurCCK_CCAThres; | ||
1038 | |||
1039 | if (!(pDM_Odm->SupportAbility & (ODM_BB_CCK_PD|ODM_BB_FA_CNT))) | ||
1040 | return; | ||
1041 | |||
1042 | if (pDM_Odm->ExtLNA) | ||
1043 | return; | ||
1044 | |||
1045 | if (pDM_Odm->bLinked) { | ||
1046 | if (pDM_Odm->RSSI_Min > 25) { | ||
1047 | CurCCK_CCAThres = 0xcd; | ||
1048 | } else if ((pDM_Odm->RSSI_Min <= 25) && (pDM_Odm->RSSI_Min > 10)) { | ||
1049 | CurCCK_CCAThres = 0x83; | ||
1050 | } else { | ||
1051 | if (FalseAlmCnt->Cnt_Cck_fail > 1000) | ||
1052 | CurCCK_CCAThres = 0x83; | ||
1053 | else | ||
1054 | CurCCK_CCAThres = 0x40; | ||
1055 | } | ||
1056 | } else { | ||
1057 | if (FalseAlmCnt->Cnt_Cck_fail > 1000) | ||
1058 | CurCCK_CCAThres = 0x83; | ||
1059 | else | ||
1060 | CurCCK_CCAThres = 0x40; | ||
1061 | } | ||
1062 | |||
1063 | ODM_Write_CCK_CCA_Thres23a(pDM_Odm, CurCCK_CCAThres); | ||
1064 | } | ||
1065 | |||
1066 | void ODM_Write_CCK_CCA_Thres23a(struct dm_odm_t *pDM_Odm, u8 CurCCK_CCAThres) | ||
1067 | { | ||
1068 | struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable; | ||
1069 | |||
1070 | if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres) | ||
1071 | ODM_Write1Byte(pDM_Odm, ODM_REG(CCK_CCA, pDM_Odm), CurCCK_CCAThres); | ||
1072 | pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres; | ||
1073 | pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres; | ||
1074 | |||
1075 | } | ||
1076 | |||
1077 | /* 3 ============================================================ */ | ||
1078 | /* 3 BB Power Save */ | ||
1079 | /* 3 ============================================================ */ | ||
1080 | void odm23a_DynBBPSInit(struct dm_odm_t *pDM_Odm) | ||
1081 | { | ||
1082 | struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable; | ||
1083 | |||
1084 | pDM_PSTable->PreCCAState = CCA_MAX; | ||
1085 | pDM_PSTable->CurCCAState = CCA_MAX; | ||
1086 | pDM_PSTable->PreRFState = RF_MAX; | ||
1087 | pDM_PSTable->CurRFState = RF_MAX; | ||
1088 | pDM_PSTable->Rssi_val_min = 0; | ||
1089 | pDM_PSTable->initialize = 0; | ||
1090 | } | ||
1091 | |||
1092 | void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm) | ||
1093 | { | ||
1094 | return; | ||
1095 | } | ||
1096 | |||
1097 | void odm_1R_CCA23a(struct dm_odm_t *pDM_Odm) | ||
1098 | { | ||
1099 | struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable; | ||
1100 | |||
1101 | if (pDM_Odm->RSSI_Min != 0xFF) { | ||
1102 | if (pDM_PSTable->PreCCAState == CCA_2R) { | ||
1103 | if (pDM_Odm->RSSI_Min >= 35) | ||
1104 | pDM_PSTable->CurCCAState = CCA_1R; | ||
1105 | else | ||
1106 | pDM_PSTable->CurCCAState = CCA_2R; | ||
1107 | } else { | ||
1108 | if (pDM_Odm->RSSI_Min <= 30) | ||
1109 | pDM_PSTable->CurCCAState = CCA_2R; | ||
1110 | else | ||
1111 | pDM_PSTable->CurCCAState = CCA_1R; | ||
1112 | } | ||
1113 | } else { | ||
1114 | pDM_PSTable->CurCCAState = CCA_MAX; | ||
1115 | } | ||
1116 | |||
1117 | if (pDM_PSTable->PreCCAState != pDM_PSTable->CurCCAState) { | ||
1118 | if (pDM_PSTable->CurCCAState == CCA_1R) { | ||
1119 | if (pDM_Odm->RFType == ODM_2T2R) | ||
1120 | ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x13); | ||
1121 | else | ||
1122 | ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x23); | ||
1123 | } else { | ||
1124 | ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x33); | ||
1125 | /* PHY_SetBBReg(pAdapter, 0xe70, bMaskByte3, 0x63); */ | ||
1126 | } | ||
1127 | pDM_PSTable->PreCCAState = pDM_PSTable->CurCCAState; | ||
1128 | } | ||
1129 | } | ||
1130 | |||
1131 | void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal) | ||
1132 | { | ||
1133 | struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable; | ||
1134 | u8 Rssi_Up_bound = 30 ; | ||
1135 | u8 Rssi_Low_bound = 25; | ||
1136 | if (pDM_Odm->PatchID == 40) { /* RT_CID_819x_FUNAI_TV */ | ||
1137 | Rssi_Up_bound = 50 ; | ||
1138 | Rssi_Low_bound = 45; | ||
1139 | } | ||
1140 | if (pDM_PSTable->initialize == 0) { | ||
1141 | |||
1142 | pDM_PSTable->Reg874 = (ODM_GetBBReg(pDM_Odm, 0x874, bMaskDWord)&0x1CC000)>>14; | ||
1143 | pDM_PSTable->RegC70 = (ODM_GetBBReg(pDM_Odm, 0xc70, bMaskDWord)&BIT3)>>3; | ||
1144 | pDM_PSTable->Reg85C = (ODM_GetBBReg(pDM_Odm, 0x85c, bMaskDWord)&0xFF000000)>>24; | ||
1145 | pDM_PSTable->RegA74 = (ODM_GetBBReg(pDM_Odm, 0xa74, bMaskDWord)&0xF000)>>12; | ||
1146 | /* Reg818 = PHY_QueryBBReg(pAdapter, 0x818, bMaskDWord); */ | ||
1147 | pDM_PSTable->initialize = 1; | ||
1148 | } | ||
1149 | |||
1150 | if (!bForceInNormal) { | ||
1151 | if (pDM_Odm->RSSI_Min != 0xFF) { | ||
1152 | if (pDM_PSTable->PreRFState == RF_Normal) { | ||
1153 | if (pDM_Odm->RSSI_Min >= Rssi_Up_bound) | ||
1154 | pDM_PSTable->CurRFState = RF_Save; | ||
1155 | else | ||
1156 | pDM_PSTable->CurRFState = RF_Normal; | ||
1157 | } else { | ||
1158 | if (pDM_Odm->RSSI_Min <= Rssi_Low_bound) | ||
1159 | pDM_PSTable->CurRFState = RF_Normal; | ||
1160 | else | ||
1161 | pDM_PSTable->CurRFState = RF_Save; | ||
1162 | } | ||
1163 | } else { | ||
1164 | pDM_PSTable->CurRFState = RF_MAX; | ||
1165 | } | ||
1166 | } else { | ||
1167 | pDM_PSTable->CurRFState = RF_Normal; | ||
1168 | } | ||
1169 | |||
1170 | if (pDM_PSTable->PreRFState != pDM_PSTable->CurRFState) { | ||
1171 | if (pDM_PSTable->CurRFState == RF_Save) { | ||
1172 | /* <tynli_note> 8723 RSSI report will be wrong. Set 0x874[5]= 1 when enter BB power saving mode. */ | ||
1173 | /* Suggested by SD3 Yu-Nan. 2011.01.20. */ | ||
1174 | if (pDM_Odm->SupportICType == ODM_RTL8723A) | ||
1175 | ODM_SetBBReg(pDM_Odm, 0x874, BIT5, 0x1); /* Reg874[5]= 1b'1 */ | ||
1176 | ODM_SetBBReg(pDM_Odm, 0x874, 0x1C0000, 0x2); /* Reg874[20:18]= 3'b010 */ | ||
1177 | ODM_SetBBReg(pDM_Odm, 0xc70, BIT3, 0); /* RegC70[3]= 1'b0 */ | ||
1178 | ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, 0x63); /* Reg85C[31:24]= 0x63 */ | ||
1179 | ODM_SetBBReg(pDM_Odm, 0x874, 0xC000, 0x2); /* Reg874[15:14]= 2'b10 */ | ||
1180 | ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, 0x3); /* RegA75[7:4]= 0x3 */ | ||
1181 | ODM_SetBBReg(pDM_Odm, 0x818, BIT28, 0x0); /* Reg818[28]= 1'b0 */ | ||
1182 | ODM_SetBBReg(pDM_Odm, 0x818, BIT28, 0x1); /* Reg818[28]= 1'b1 */ | ||
1183 | } else { | ||
1184 | ODM_SetBBReg(pDM_Odm, 0x874, 0x1CC000, pDM_PSTable->Reg874); | ||
1185 | ODM_SetBBReg(pDM_Odm, 0xc70, BIT3, pDM_PSTable->RegC70); | ||
1186 | ODM_SetBBReg(pDM_Odm, 0x85c, 0xFF000000, pDM_PSTable->Reg85C); | ||
1187 | ODM_SetBBReg(pDM_Odm, 0xa74, 0xF000, pDM_PSTable->RegA74); | ||
1188 | ODM_SetBBReg(pDM_Odm, 0x818, BIT28, 0x0); | ||
1189 | |||
1190 | if (pDM_Odm->SupportICType == ODM_RTL8723A) | ||
1191 | ODM_SetBBReg(pDM_Odm, 0x874, BIT5, 0x0); /* Reg874[5]= 1b'0 */ | ||
1192 | } | ||
1193 | pDM_PSTable->PreRFState = pDM_PSTable->CurRFState; | ||
1194 | } | ||
1195 | } | ||
1196 | |||
1197 | /* 3 ============================================================ */ | ||
1198 | /* 3 RATR MASK */ | ||
1199 | /* 3 ============================================================ */ | ||
1200 | /* 3 ============================================================ */ | ||
1201 | /* 3 Rate Adaptive */ | ||
1202 | /* 3 ============================================================ */ | ||
1203 | |||
1204 | void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm) | ||
1205 | { | ||
1206 | struct odm_rate_adapt *pOdmRA = &pDM_Odm->RateAdaptive; | ||
1207 | |||
1208 | pOdmRA->Type = DM_Type_ByDriver; | ||
1209 | if (pOdmRA->Type == DM_Type_ByDriver) | ||
1210 | pDM_Odm->bUseRAMask = true; | ||
1211 | else | ||
1212 | pDM_Odm->bUseRAMask = false; | ||
1213 | |||
1214 | pOdmRA->RATRState = DM_RATR_STA_INIT; | ||
1215 | pOdmRA->HighRSSIThresh = 50; | ||
1216 | pOdmRA->LowRSSIThresh = 20; | ||
1217 | } | ||
1218 | |||
1219 | u32 ODM_Get_Rate_Bitmap23a(struct dm_odm_t *pDM_Odm, | ||
1220 | u32 macid, | ||
1221 | u32 ra_mask, | ||
1222 | u8 rssi_level) | ||
1223 | { | ||
1224 | struct sta_info *pEntry; | ||
1225 | u32 rate_bitmap = 0x0fffffff; | ||
1226 | u8 WirelessMode; | ||
1227 | /* u8 WirelessMode =*(pDM_Odm->pWirelessMode); */ | ||
1228 | |||
1229 | pEntry = pDM_Odm->pODM_StaInfo[macid]; | ||
1230 | if (!IS_STA_VALID(pEntry)) | ||
1231 | return ra_mask; | ||
1232 | |||
1233 | WirelessMode = pEntry->wireless_mode; | ||
1234 | |||
1235 | switch (WirelessMode) { | ||
1236 | case ODM_WM_B: | ||
1237 | if (ra_mask & 0x0000000c) /* 11M or 5.5M enable */ | ||
1238 | rate_bitmap = 0x0000000d; | ||
1239 | else | ||
1240 | rate_bitmap = 0x0000000f; | ||
1241 | break; | ||
1242 | case (ODM_WM_A|ODM_WM_G): | ||
1243 | if (rssi_level == DM_RATR_STA_HIGH) | ||
1244 | rate_bitmap = 0x00000f00; | ||
1245 | else | ||
1246 | rate_bitmap = 0x00000ff0; | ||
1247 | break; | ||
1248 | case (ODM_WM_B|ODM_WM_G): | ||
1249 | if (rssi_level == DM_RATR_STA_HIGH) | ||
1250 | rate_bitmap = 0x00000f00; | ||
1251 | else if (rssi_level == DM_RATR_STA_MIDDLE) | ||
1252 | rate_bitmap = 0x00000ff0; | ||
1253 | else | ||
1254 | rate_bitmap = 0x00000ff5; | ||
1255 | break; | ||
1256 | case (ODM_WM_B|ODM_WM_G|ODM_WM_N24G): | ||
1257 | case (ODM_WM_A|ODM_WM_B|ODM_WM_G|ODM_WM_N24G): | ||
1258 | if (pDM_Odm->RFType == ODM_1T2R || pDM_Odm->RFType == ODM_1T1R) { | ||
1259 | if (rssi_level == DM_RATR_STA_HIGH) { | ||
1260 | rate_bitmap = 0x000f0000; | ||
1261 | } else if (rssi_level == DM_RATR_STA_MIDDLE) { | ||
1262 | rate_bitmap = 0x000ff000; | ||
1263 | } else { | ||
1264 | if (*(pDM_Odm->pBandWidth) == ODM_BW40M) | ||
1265 | rate_bitmap = 0x000ff015; | ||
1266 | else | ||
1267 | rate_bitmap = 0x000ff005; | ||
1268 | } | ||
1269 | } else { | ||
1270 | if (rssi_level == DM_RATR_STA_HIGH) { | ||
1271 | rate_bitmap = 0x0f8f0000; | ||
1272 | } else if (rssi_level == DM_RATR_STA_MIDDLE) { | ||
1273 | rate_bitmap = 0x0f8ff000; | ||
1274 | } else { | ||
1275 | if (*(pDM_Odm->pBandWidth) == ODM_BW40M) | ||
1276 | rate_bitmap = 0x0f8ff015; | ||
1277 | else | ||
1278 | rate_bitmap = 0x0f8ff005; | ||
1279 | } | ||
1280 | } | ||
1281 | break; | ||
1282 | default: | ||
1283 | /* case WIRELESS_11_24N: */ | ||
1284 | /* case WIRELESS_11_5N: */ | ||
1285 | if (pDM_Odm->RFType == RF_1T2R) | ||
1286 | rate_bitmap = 0x000fffff; | ||
1287 | else | ||
1288 | rate_bitmap = 0x0fffffff; | ||
1289 | break; | ||
1290 | } | ||
1291 | |||
1292 | /* printk("%s ==> rssi_level:0x%02x, WirelessMode:0x%02x, rate_bitmap:0x%08x \n", __FUNCTION__, rssi_level, WirelessMode, rate_bitmap); */ | ||
1293 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, (" ==> rssi_level:0x%02x, WirelessMode:0x%02x, rate_bitmap:0x%08x \n", rssi_level, WirelessMode, rate_bitmap)); | ||
1294 | |||
1295 | return rate_bitmap; | ||
1296 | |||
1297 | } | ||
1298 | |||
1299 | /*----------------------------------------------------------------------------- | ||
1300 | * Function: odm_RefreshRateAdaptiveMask23a() | ||
1301 | * | ||
1302 | * Overview: Update rate table mask according to rssi | ||
1303 | * | ||
1304 | * Input: NONE | ||
1305 | * | ||
1306 | * Output: NONE | ||
1307 | * | ||
1308 | * Return: NONE | ||
1309 | * | ||
1310 | * Revised History: | ||
1311 | *When Who Remark | ||
1312 | *05/27/2009 hpfan Create Version 0. | ||
1313 | * | ||
1314 | *---------------------------------------------------------------------------*/ | ||
1315 | void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm) | ||
1316 | { | ||
1317 | if (!(pDM_Odm->SupportAbility & ODM_BB_RA_MASK)) | ||
1318 | return; | ||
1319 | /* */ | ||
1320 | /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ | ||
1321 | /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ | ||
1322 | /* HW dynamic mechanism. */ | ||
1323 | /* */ | ||
1324 | odm_RefreshRateAdaptiveMask23aCE23a(pDM_Odm); | ||
1325 | } | ||
1326 | |||
1327 | void odm_RefreshRateAdaptiveMask23aMP23a(struct dm_odm_t *pDM_Odm) | ||
1328 | { | ||
1329 | } | ||
1330 | |||
1331 | void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm) | ||
1332 | { | ||
1333 | u8 i; | ||
1334 | struct rtw_adapter *pAdapter = pDM_Odm->Adapter; | ||
1335 | |||
1336 | if (pAdapter->bDriverStopped) { | ||
1337 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_TRACE, | ||
1338 | ("<---- odm_RefreshRateAdaptiveMask23a(): driver is going to unload\n")); | ||
1339 | return; | ||
1340 | } | ||
1341 | |||
1342 | if (!pDM_Odm->bUseRAMask) { | ||
1343 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, | ||
1344 | ("<---- odm_RefreshRateAdaptiveMask23a(): driver does not control rate adaptive mask\n")); | ||
1345 | return; | ||
1346 | } | ||
1347 | |||
1348 | /* printk("==> %s \n", __FUNCTION__); */ | ||
1349 | |||
1350 | for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { | ||
1351 | struct sta_info *pstat = pDM_Odm->pODM_StaInfo[i]; | ||
1352 | if (IS_STA_VALID(pstat)) { | ||
1353 | if (ODM_RAStateCheck23a(pDM_Odm, pstat->rssi_stat.UndecoratedSmoothedPWDB, false, &pstat->rssi_level)) { | ||
1354 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, | ||
1355 | ("RSSI:%d, RSSI_LEVEL:%d\n", | ||
1356 | pstat->rssi_stat.UndecoratedSmoothedPWDB, | ||
1357 | pstat->rssi_level)); | ||
1358 | rtw_hal_update_ra_mask23a(pstat, pstat->rssi_level); | ||
1359 | } | ||
1360 | |||
1361 | } | ||
1362 | } | ||
1363 | |||
1364 | } | ||
1365 | |||
1366 | void odm_RefreshRateAdaptiveMask23aAPADSL23a(struct dm_odm_t *pDM_Odm) | ||
1367 | { | ||
1368 | } | ||
1369 | |||
1370 | /* Return Value: bool */ | ||
1371 | /* - true: RATRState is changed. */ | ||
1372 | bool ODM_RAStateCheck23a(struct dm_odm_t *pDM_Odm, s32 RSSI, bool bForceUpdate, | ||
1373 | u8 *pRATRState) | ||
1374 | { | ||
1375 | struct odm_rate_adapt *pRA = &pDM_Odm->RateAdaptive; | ||
1376 | const u8 GoUpGap = 5; | ||
1377 | u8 HighRSSIThreshForRA = pRA->HighRSSIThresh; | ||
1378 | u8 LowRSSIThreshForRA = pRA->LowRSSIThresh; | ||
1379 | u8 RATRState; | ||
1380 | |||
1381 | /* Threshold Adjustment: */ | ||
1382 | /* when RSSI state trends to go up one or two levels, make sure RSSI is high enough. */ | ||
1383 | /* Here GoUpGap is added to solve the boundary's level alternation issue. */ | ||
1384 | switch (*pRATRState) { | ||
1385 | case DM_RATR_STA_INIT: | ||
1386 | case DM_RATR_STA_HIGH: | ||
1387 | break; | ||
1388 | case DM_RATR_STA_MIDDLE: | ||
1389 | HighRSSIThreshForRA += GoUpGap; | ||
1390 | break; | ||
1391 | case DM_RATR_STA_LOW: | ||
1392 | HighRSSIThreshForRA += GoUpGap; | ||
1393 | LowRSSIThreshForRA += GoUpGap; | ||
1394 | break; | ||
1395 | default: | ||
1396 | ODM_RT_ASSERT(pDM_Odm, false, ("wrong rssi level setting %d !", *pRATRState)); | ||
1397 | break; | ||
1398 | } | ||
1399 | |||
1400 | /* Decide RATRState by RSSI. */ | ||
1401 | if (RSSI > HighRSSIThreshForRA) | ||
1402 | RATRState = DM_RATR_STA_HIGH; | ||
1403 | else if (RSSI > LowRSSIThreshForRA) | ||
1404 | RATRState = DM_RATR_STA_MIDDLE; | ||
1405 | else | ||
1406 | RATRState = DM_RATR_STA_LOW; | ||
1407 | |||
1408 | if (*pRATRState != RATRState || bForceUpdate) { | ||
1409 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD, | ||
1410 | ("RSSI Level %d -> %d\n", *pRATRState, RATRState)); | ||
1411 | *pRATRState = RATRState; | ||
1412 | return true; | ||
1413 | } | ||
1414 | return false; | ||
1415 | } | ||
1416 | |||
1417 | /* 3 ============================================================ */ | ||
1418 | /* 3 Dynamic Tx Power */ | ||
1419 | /* 3 ============================================================ */ | ||
1420 | |||
1421 | void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm) | ||
1422 | { | ||
1423 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
1424 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1425 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
1426 | |||
1427 | pdmpriv->bDynamicTxPowerEnable = false; | ||
1428 | |||
1429 | pdmpriv->LastDTPLvl = TxHighPwrLevel_Normal; | ||
1430 | pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal; | ||
1431 | } | ||
1432 | |||
1433 | void odm_DynamicTxPower23aSavePowerIndex(struct dm_odm_t *pDM_Odm) | ||
1434 | { | ||
1435 | u8 index; | ||
1436 | u32 Power_Index_REG[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; | ||
1437 | |||
1438 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
1439 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1440 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
1441 | for (index = 0; index < 6; index++) | ||
1442 | pdmpriv->PowerIndex_backup[index] = rtw_read8(Adapter, Power_Index_REG[index]); | ||
1443 | } | ||
1444 | |||
1445 | void odm_DynamicTxPower23aRestorePowerIndex(struct dm_odm_t *pDM_Odm) | ||
1446 | { | ||
1447 | u8 index; | ||
1448 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
1449 | |||
1450 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1451 | u32 Power_Index_REG[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; | ||
1452 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
1453 | for (index = 0; index < 6; index++) | ||
1454 | rtw_write8(Adapter, Power_Index_REG[index], pdmpriv->PowerIndex_backup[index]); | ||
1455 | } | ||
1456 | |||
1457 | void odm_DynamicTxPower23aWritePowerIndex(struct dm_odm_t *pDM_Odm, | ||
1458 | u8 Value) | ||
1459 | { | ||
1460 | |||
1461 | u8 index; | ||
1462 | u32 Power_Index_REG[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; | ||
1463 | |||
1464 | for (index = 0; index < 6; index++) | ||
1465 | ODM_Write1Byte(pDM_Odm, Power_Index_REG[index], Value); | ||
1466 | |||
1467 | } | ||
1468 | |||
1469 | void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm) | ||
1470 | { | ||
1471 | } | ||
1472 | |||
1473 | void odm_DynamicTxPower23a_92C(struct dm_odm_t *pDM_Odm) | ||
1474 | { | ||
1475 | } | ||
1476 | |||
1477 | void odm_DynamicTxPower23a_92D(struct dm_odm_t *pDM_Odm) | ||
1478 | { | ||
1479 | } | ||
1480 | |||
1481 | /* 3 ============================================================ */ | ||
1482 | /* 3 RSSI Monitor */ | ||
1483 | /* 3 ============================================================ */ | ||
1484 | |||
1485 | void odm_RSSIMonitorInit(struct dm_odm_t *pDM_Odm) | ||
1486 | { | ||
1487 | } | ||
1488 | |||
1489 | void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm) | ||
1490 | { | ||
1491 | /* For AP/ADSL use struct rtl8723a_priv * */ | ||
1492 | /* For CE/NIC use struct rtw_adapter * */ | ||
1493 | |||
1494 | if (!(pDM_Odm->SupportAbility & ODM_BB_RSSI_MONITOR)) | ||
1495 | return; | ||
1496 | |||
1497 | /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ | ||
1498 | /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ | ||
1499 | /* HW dynamic mechanism. */ | ||
1500 | odm_RSSIMonitorCheck23aCE(pDM_Odm); | ||
1501 | } /* odm_RSSIMonitorCheck23a */ | ||
1502 | |||
1503 | void odm_RSSIMonitorCheck23aMP(struct dm_odm_t *pDM_Odm) | ||
1504 | { | ||
1505 | } | ||
1506 | |||
1507 | static void | ||
1508 | FindMinimumRSSI( | ||
1509 | struct rtw_adapter *pAdapter | ||
1510 | ) | ||
1511 | { | ||
1512 | struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); | ||
1513 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
1514 | struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; | ||
1515 | |||
1516 | /* 1 1.Determine the minimum RSSI */ | ||
1517 | |||
1518 | if ((!pDM_Odm->bLinked) && | ||
1519 | (pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0)) | ||
1520 | pdmpriv->MinUndecoratedPWDBForDM = 0; | ||
1521 | else | ||
1522 | pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB; | ||
1523 | } | ||
1524 | |||
1525 | void odm_RSSIMonitorCheck23aCE(struct dm_odm_t *pDM_Odm) | ||
1526 | { | ||
1527 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
1528 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1529 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
1530 | int i; | ||
1531 | int tmpEntryMaxPWDB = 0, tmpEntryMinPWDB = 0xff; | ||
1532 | u8 sta_cnt = 0; | ||
1533 | u32 PWDB_rssi[NUM_STA] = {0};/* 0~15]:MACID, [16~31]:PWDB_rssi */ | ||
1534 | struct sta_info *psta; | ||
1535 | |||
1536 | if (!pDM_Odm->bLinked) | ||
1537 | return; | ||
1538 | |||
1539 | for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { | ||
1540 | psta = pDM_Odm->pODM_StaInfo[i]; | ||
1541 | if (IS_STA_VALID(psta)) { | ||
1542 | if (psta->rssi_stat.UndecoratedSmoothedPWDB < tmpEntryMinPWDB) | ||
1543 | tmpEntryMinPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; | ||
1544 | |||
1545 | if (psta->rssi_stat.UndecoratedSmoothedPWDB > tmpEntryMaxPWDB) | ||
1546 | tmpEntryMaxPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB; | ||
1547 | |||
1548 | if (psta->rssi_stat.UndecoratedSmoothedPWDB != (-1)) | ||
1549 | PWDB_rssi[sta_cnt++] = (psta->mac_id | (psta->rssi_stat.UndecoratedSmoothedPWDB<<16)); | ||
1550 | } | ||
1551 | } | ||
1552 | |||
1553 | for (i = 0; i < sta_cnt; i++) { | ||
1554 | if (PWDB_rssi[i] != (0)) { | ||
1555 | if (pHalData->fw_ractrl) /* Report every sta's RSSI to FW */ | ||
1556 | rtl8723a_set_rssi_cmd(Adapter, (u8 *)&PWDB_rssi[i]); | ||
1557 | } | ||
1558 | } | ||
1559 | |||
1560 | if (tmpEntryMaxPWDB != 0) /* If associated entry is found */ | ||
1561 | pdmpriv->EntryMaxUndecoratedSmoothedPWDB = tmpEntryMaxPWDB; | ||
1562 | else | ||
1563 | pdmpriv->EntryMaxUndecoratedSmoothedPWDB = 0; | ||
1564 | |||
1565 | if (tmpEntryMinPWDB != 0xff) /* If associated entry is found */ | ||
1566 | pdmpriv->EntryMinUndecoratedSmoothedPWDB = tmpEntryMinPWDB; | ||
1567 | else | ||
1568 | pdmpriv->EntryMinUndecoratedSmoothedPWDB = 0; | ||
1569 | |||
1570 | FindMinimumRSSI(Adapter);/* get pdmpriv->MinUndecoratedPWDBForDM */ | ||
1571 | |||
1572 | ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_RSSI_MIN, pdmpriv->MinUndecoratedPWDBForDM); | ||
1573 | } | ||
1574 | |||
1575 | void odm_RSSIMonitorCheck23aAP(struct dm_odm_t *pDM_Odm) | ||
1576 | { | ||
1577 | } | ||
1578 | |||
1579 | void ODM_InitAllTimers(struct dm_odm_t *pDM_Odm) | ||
1580 | { | ||
1581 | setup_timer(&pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer, | ||
1582 | odm_SwAntDivChkAntSwitchCallback23a, (unsigned long)pDM_Odm); | ||
1583 | } | ||
1584 | |||
1585 | void ODM_CancelAllTimers(struct dm_odm_t *pDM_Odm) | ||
1586 | { | ||
1587 | del_timer_sync(&pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer); | ||
1588 | } | ||
1589 | |||
1590 | void ODM_ReleaseAllTimers(struct dm_odm_t *pDM_Odm) | ||
1591 | { | ||
1592 | ODM_ReleaseTimer(pDM_Odm, &pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer); | ||
1593 | } | ||
1594 | |||
1595 | /* endif */ | ||
1596 | /* 3 ============================================================ */ | ||
1597 | /* 3 Tx Power Tracking */ | ||
1598 | /* 3 ============================================================ */ | ||
1599 | |||
1600 | void odm_TXPowerTrackingInit23a(struct dm_odm_t *pDM_Odm) | ||
1601 | { | ||
1602 | odm_TXPowerTrackingThermalMeterInit23a(pDM_Odm); | ||
1603 | } | ||
1604 | |||
1605 | void odm_TXPowerTrackingThermalMeterInit23a(struct dm_odm_t *pDM_Odm) | ||
1606 | { | ||
1607 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
1608 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1609 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
1610 | |||
1611 | pdmpriv->bTXPowerTracking = true; | ||
1612 | pdmpriv->TXPowercount = 0; | ||
1613 | pdmpriv->bTXPowerTrackingInit = false; | ||
1614 | pdmpriv->TxPowerTrackControl = true; | ||
1615 | MSG_8723A("pdmpriv->TxPowerTrackControl = %d\n", pdmpriv->TxPowerTrackControl); | ||
1616 | |||
1617 | pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = true; | ||
1618 | } | ||
1619 | |||
1620 | void ODM_TXPowerTrackingCheck23a(struct dm_odm_t *pDM_Odm) | ||
1621 | { | ||
1622 | /* For AP/ADSL use struct rtl8723a_priv * */ | ||
1623 | /* For CE/NIC use struct rtw_adapter * */ | ||
1624 | |||
1625 | /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ | ||
1626 | /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ | ||
1627 | /* HW dynamic mechanism. */ | ||
1628 | odm_TXPowerTrackingCheckCE23a(pDM_Odm); | ||
1629 | } | ||
1630 | |||
1631 | void odm_TXPowerTrackingCheckCE23a(struct dm_odm_t *pDM_Odm) | ||
1632 | { | ||
1633 | } | ||
1634 | |||
1635 | void odm_TXPowerTrackingCheckMP(struct dm_odm_t *pDM_Odm) | ||
1636 | { | ||
1637 | } | ||
1638 | |||
1639 | void odm_TXPowerTrackingCheckAP(struct dm_odm_t *pDM_Odm) | ||
1640 | { | ||
1641 | } | ||
1642 | |||
1643 | /* antenna mapping info */ | ||
1644 | /* 1: right-side antenna */ | ||
1645 | /* 2/0: left-side antenna */ | ||
1646 | /* PpDM_SWAT_Table->CCK_Ant1_Cnt /OFDM_Ant1_Cnt: for right-side antenna: Ant:1 RxDefaultAnt1 */ | ||
1647 | /* PpDM_SWAT_Table->CCK_Ant2_Cnt /OFDM_Ant2_Cnt: for left-side antenna: Ant:0 RxDefaultAnt2 */ | ||
1648 | /* We select left antenna as default antenna in initial process, modify it as needed */ | ||
1649 | /* */ | ||
1650 | |||
1651 | /* 3 ============================================================ */ | ||
1652 | /* 3 SW Antenna Diversity */ | ||
1653 | /* 3 ============================================================ */ | ||
1654 | void odm_SwAntDivInit(struct dm_odm_t *pDM_Odm) | ||
1655 | { | ||
1656 | } | ||
1657 | |||
1658 | void ODM_SwAntDivChkPerPktRssi(struct dm_odm_t *pDM_Odm, u8 StationID, struct odm_phy_info *pPhyInfo) | ||
1659 | { | ||
1660 | } | ||
1661 | |||
1662 | void odm_SwAntDivChkAntSwitch(struct dm_odm_t *pDM_Odm, u8 Step) | ||
1663 | { | ||
1664 | } | ||
1665 | |||
1666 | void ODM_SwAntDivRestAfterLink(struct dm_odm_t *pDM_Odm) | ||
1667 | { | ||
1668 | } | ||
1669 | |||
1670 | void odm_SwAntDivChkAntSwitchCallback23a(unsigned long data) | ||
1671 | { | ||
1672 | } | ||
1673 | |||
1674 | /* 3 ============================================================ */ | ||
1675 | /* 3 SW Antenna Diversity */ | ||
1676 | /* 3 ============================================================ */ | ||
1677 | |||
1678 | void odm_InitHybridAntDiv23a(struct dm_odm_t *pDM_Odm) | ||
1679 | { | ||
1680 | } | ||
1681 | |||
1682 | void odm_HwAntDiv23a(struct dm_odm_t *pDM_Odm) | ||
1683 | { | ||
1684 | } | ||
1685 | |||
1686 | /* EDCA Turbo */ | ||
1687 | void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm) | ||
1688 | { | ||
1689 | |||
1690 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
1691 | pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; | ||
1692 | pDM_Odm->DM_EDCA_Table.bIsCurRDLState = false; | ||
1693 | Adapter->recvpriv.bIsAnyNonBEPkts = false; | ||
1694 | |||
1695 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial VO PARAM: 0x%x\n", ODM_Read4Byte(pDM_Odm, ODM_EDCA_VO_PARAM))); | ||
1696 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial VI PARAM: 0x%x\n", ODM_Read4Byte(pDM_Odm, ODM_EDCA_VI_PARAM))); | ||
1697 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial BE PARAM: 0x%x\n", ODM_Read4Byte(pDM_Odm, ODM_EDCA_BE_PARAM))); | ||
1698 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial BK PARAM: 0x%x\n", ODM_Read4Byte(pDM_Odm, ODM_EDCA_BK_PARAM))); | ||
1699 | |||
1700 | } /* ODM_InitEdcaTurbo */ | ||
1701 | |||
1702 | void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm) | ||
1703 | { | ||
1704 | /* For AP/ADSL use struct rtl8723a_priv * */ | ||
1705 | /* For CE/NIC use struct rtw_adapter * */ | ||
1706 | |||
1707 | /* 2011/09/29 MH In HW integration first stage, we provide 4 different handle to operate */ | ||
1708 | /* at the same time. In the stage2/3, we need to prive universal interface and merge all */ | ||
1709 | /* HW dynamic mechanism. */ | ||
1710 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("odm_EdcaTurboCheck23a ========================>\n")); | ||
1711 | |||
1712 | if (!(pDM_Odm->SupportAbility & ODM_MAC_EDCA_TURBO)) | ||
1713 | return; | ||
1714 | |||
1715 | odm_EdcaTurboCheck23aCE23a(pDM_Odm); | ||
1716 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("<======================== odm_EdcaTurboCheck23a\n")); | ||
1717 | |||
1718 | } /* odm_CheckEdcaTurbo */ | ||
1719 | |||
1720 | void odm_EdcaTurboCheck23aCE23a(struct dm_odm_t *pDM_Odm) | ||
1721 | { | ||
1722 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
1723 | |||
1724 | u32 trafficIndex; | ||
1725 | u32 edca_param; | ||
1726 | u64 cur_tx_bytes = 0; | ||
1727 | u64 cur_rx_bytes = 0; | ||
1728 | u8 bbtchange = false; | ||
1729 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1730 | struct xmit_priv *pxmitpriv = &Adapter->xmitpriv; | ||
1731 | struct recv_priv *precvpriv = &Adapter->recvpriv; | ||
1732 | struct registry_priv *pregpriv = &Adapter->registrypriv; | ||
1733 | struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; | ||
1734 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; | ||
1735 | |||
1736 | if ((pregpriv->wifi_spec == 1))/* (pmlmeinfo->HT_enable == 0)) */ | ||
1737 | goto dm_CheckEdcaTurbo_EXIT; | ||
1738 | |||
1739 | if (pmlmeinfo->assoc_AP_vendor >= HT_IOT_PEER_MAX) | ||
1740 | goto dm_CheckEdcaTurbo_EXIT; | ||
1741 | |||
1742 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
1743 | if (BT_DisableEDCATurbo(Adapter)) | ||
1744 | goto dm_CheckEdcaTurbo_EXIT; | ||
1745 | #endif | ||
1746 | |||
1747 | /* Check if the status needs to be changed. */ | ||
1748 | if ((bbtchange) || (!precvpriv->bIsAnyNonBEPkts)) { | ||
1749 | cur_tx_bytes = pxmitpriv->tx_bytes - pxmitpriv->last_tx_bytes; | ||
1750 | cur_rx_bytes = precvpriv->rx_bytes - precvpriv->last_rx_bytes; | ||
1751 | |||
1752 | /* traffic, TX or RX */ | ||
1753 | if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK) || | ||
1754 | (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS)) { | ||
1755 | if (cur_tx_bytes > (cur_rx_bytes << 2)) { | ||
1756 | /* Uplink TP is present. */ | ||
1757 | trafficIndex = UP_LINK; | ||
1758 | } else { /* Balance TP is present. */ | ||
1759 | trafficIndex = DOWN_LINK; | ||
1760 | } | ||
1761 | } else { | ||
1762 | if (cur_rx_bytes > (cur_tx_bytes << 2)) { | ||
1763 | /* Downlink TP is present. */ | ||
1764 | trafficIndex = DOWN_LINK; | ||
1765 | } else { /* Balance TP is present. */ | ||
1766 | trafficIndex = UP_LINK; | ||
1767 | } | ||
1768 | } | ||
1769 | |||
1770 | if ((pDM_Odm->DM_EDCA_Table.prv_traffic_idx != trafficIndex) || | ||
1771 | (!pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA)) { | ||
1772 | if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_CISCO) && | ||
1773 | (pmlmeext->cur_wireless_mode & WIRELESS_11_24N)) | ||
1774 | edca_param = EDCAParam[pmlmeinfo->assoc_AP_vendor][trafficIndex]; | ||
1775 | else | ||
1776 | edca_param = EDCAParam[HT_IOT_PEER_UNKNOWN][trafficIndex]; | ||
1777 | rtw_write32(Adapter, REG_EDCA_BE_PARAM, edca_param); | ||
1778 | |||
1779 | pDM_Odm->DM_EDCA_Table.prv_traffic_idx = trafficIndex; | ||
1780 | } | ||
1781 | |||
1782 | pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = true; | ||
1783 | } else { | ||
1784 | /* Turn Off EDCA turbo here. */ | ||
1785 | /* Restore original EDCA according to the declaration of AP. */ | ||
1786 | if (pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) { | ||
1787 | rtw_write32(Adapter, REG_EDCA_BE_PARAM, pHalData->AcParam_BE); | ||
1788 | pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; | ||
1789 | } | ||
1790 | } | ||
1791 | |||
1792 | dm_CheckEdcaTurbo_EXIT: | ||
1793 | /* Set variables for next time. */ | ||
1794 | precvpriv->bIsAnyNonBEPkts = false; | ||
1795 | pxmitpriv->last_tx_bytes = pxmitpriv->tx_bytes; | ||
1796 | precvpriv->last_rx_bytes = precvpriv->rx_bytes; | ||
1797 | } | ||
1798 | |||
1799 | u32 GetPSDData(struct dm_odm_t *pDM_Odm, unsigned int point, u8 initial_gain_psd) | ||
1800 | { | ||
1801 | u32 psd_report; | ||
1802 | |||
1803 | /* Set DCO frequency index, offset = (40MHz/SamplePts)*point */ | ||
1804 | ODM_SetBBReg(pDM_Odm, 0x808, 0x3FF, point); | ||
1805 | |||
1806 | /* Start PSD calculation, Reg808[22]= 0->1 */ | ||
1807 | ODM_SetBBReg(pDM_Odm, 0x808, BIT22, 1); | ||
1808 | /* Need to wait for HW PSD report */ | ||
1809 | udelay(30); | ||
1810 | ODM_SetBBReg(pDM_Odm, 0x808, BIT22, 0); | ||
1811 | /* Read PSD report, Reg8B4[15:0] */ | ||
1812 | psd_report = ODM_GetBBReg(pDM_Odm, 0x8B4, bMaskDWord) & 0x0000FFFF; | ||
1813 | |||
1814 | psd_report = (u32)(ConvertTo_dB23a(psd_report))+(u32)(initial_gain_psd-0x1c); | ||
1815 | |||
1816 | return psd_report; | ||
1817 | } | ||
1818 | |||
1819 | u32 | ||
1820 | ConvertTo_dB23a( | ||
1821 | u32 Value) | ||
1822 | { | ||
1823 | u8 i; | ||
1824 | u8 j; | ||
1825 | u32 dB; | ||
1826 | |||
1827 | Value = Value & 0xFFFF; | ||
1828 | |||
1829 | for (i = 0; i < 8; i++) { | ||
1830 | if (Value <= dB_Invert_Table[i][11]) | ||
1831 | break; | ||
1832 | } | ||
1833 | |||
1834 | if (i >= 8) | ||
1835 | return 96; /* maximum 96 dB */ | ||
1836 | |||
1837 | for (j = 0; j < 12; j++) { | ||
1838 | if (Value <= dB_Invert_Table[i][j]) | ||
1839 | break; | ||
1840 | } | ||
1841 | |||
1842 | dB = i*12 + j + 1; | ||
1843 | |||
1844 | return dB; | ||
1845 | } | ||
1846 | |||
1847 | /* */ | ||
1848 | /* 2011/09/22 MH Add for 92D global spin lock utilization. */ | ||
1849 | /* */ | ||
1850 | void | ||
1851 | odm_GlobalAdapterCheck( | ||
1852 | void | ||
1853 | ) | ||
1854 | { | ||
1855 | } /* odm_GlobalAdapterCheck */ | ||
1856 | |||
1857 | /* */ | ||
1858 | /* Description: */ | ||
1859 | /*Set Single/Dual Antenna default setting for products that do not do detection in advance. */ | ||
1860 | /* */ | ||
1861 | /* Added by Joseph, 2012.03.22 */ | ||
1862 | /* */ | ||
1863 | void ODM_SingleDualAntennaDefaultSetting(struct dm_odm_t *pDM_Odm) | ||
1864 | { | ||
1865 | struct sw_ant_sw *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; | ||
1866 | pDM_SWAT_Table->ANTA_ON = true; | ||
1867 | pDM_SWAT_Table->ANTB_ON = true; | ||
1868 | } | ||
1869 | |||
1870 | /* 2 8723A ANT DETECT */ | ||
1871 | |||
1872 | static void odm_PHY_SaveAFERegisters( | ||
1873 | struct dm_odm_t *pDM_Odm, | ||
1874 | u32 *AFEReg, | ||
1875 | u32 *AFEBackup, | ||
1876 | u32 RegisterNum | ||
1877 | ) | ||
1878 | { | ||
1879 | u32 i; | ||
1880 | |||
1881 | /* RTPRINT(FINIT, INIT_IQK, ("Save ADDA parameters.\n")); */ | ||
1882 | for (i = 0 ; i < RegisterNum ; i++) | ||
1883 | AFEBackup[i] = ODM_GetBBReg(pDM_Odm, AFEReg[i], bMaskDWord); | ||
1884 | } | ||
1885 | |||
1886 | static void odm_PHY_ReloadAFERegisters(struct dm_odm_t *pDM_Odm, u32 *AFEReg, | ||
1887 | u32 *AFEBackup, u32 RegiesterNum) | ||
1888 | { | ||
1889 | u32 i; | ||
1890 | |||
1891 | for (i = 0 ; i < RegiesterNum; i++) | ||
1892 | ODM_SetBBReg(pDM_Odm, AFEReg[i], bMaskDWord, AFEBackup[i]); | ||
1893 | } | ||
1894 | |||
1895 | /* 2 8723A ANT DETECT */ | ||
1896 | /* Description: */ | ||
1897 | /* Implement IQK single tone for RF DPK loopback and BB PSD scanning. */ | ||
1898 | /* This function is cooperated with BB team Neil. */ | ||
1899 | bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode) | ||
1900 | { | ||
1901 | struct sw_ant_sw *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; | ||
1902 | u32 CurrentChannel, RfLoopReg; | ||
1903 | u8 n; | ||
1904 | u32 Reg88c, Regc08, Reg874, Regc50; | ||
1905 | u8 initial_gain = 0x5a; | ||
1906 | u32 PSD_report_tmp; | ||
1907 | u32 AntA_report = 0x0, AntB_report = 0x0, AntO_report = 0x0; | ||
1908 | bool bResult = true; | ||
1909 | u32 AFE_Backup[16]; | ||
1910 | u32 AFE_REG_8723A[16] = { | ||
1911 | rRx_Wait_CCA, rTx_CCK_RFON, | ||
1912 | rTx_CCK_BBON, rTx_OFDM_RFON, | ||
1913 | rTx_OFDM_BBON, rTx_To_Rx, | ||
1914 | rTx_To_Tx, rRx_CCK, | ||
1915 | rRx_OFDM, rRx_Wait_RIFS, | ||
1916 | rRx_TO_Rx, rStandby, | ||
1917 | rSleep, rPMPD_ANAEN, | ||
1918 | rFPGA0_XCD_SwitchControl, rBlue_Tooth}; | ||
1919 | |||
1920 | if (!(pDM_Odm->SupportICType & (ODM_RTL8723A))) | ||
1921 | return bResult; | ||
1922 | |||
1923 | if (!(pDM_Odm->SupportAbility&ODM_BB_ANT_DIV)) | ||
1924 | return bResult; | ||
1925 | /* 1 Backup Current RF/BB Settings */ | ||
1926 | |||
1927 | CurrentChannel = ODM_GetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask); | ||
1928 | RfLoopReg = ODM_GetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask); | ||
1929 | ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, ODM_DPDT, Antenna_A); /* change to Antenna A */ | ||
1930 | /* Step 1: USE IQK to transmitter single tone */ | ||
1931 | |||
1932 | udelay(10); | ||
1933 | |||
1934 | /* Store A Path Register 88c, c08, 874, c50 */ | ||
1935 | Reg88c = ODM_GetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord); | ||
1936 | Regc08 = ODM_GetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord); | ||
1937 | Reg874 = ODM_GetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord); | ||
1938 | Regc50 = ODM_GetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord); | ||
1939 | |||
1940 | /* Store AFE Registers */ | ||
1941 | odm_PHY_SaveAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16); | ||
1942 | |||
1943 | /* Set PSD 128 pts */ | ||
1944 | ODM_SetBBReg(pDM_Odm, rFPGA0_PSDFunction, BIT14|BIT15, 0x0); /* 128 pts */ | ||
1945 | |||
1946 | /* To SET CH1 to do */ | ||
1947 | ODM_SetRFReg(pDM_Odm, RF_PATH_A, ODM_CHANNEL, bRFRegOffsetMask, 0x01); /* Channel 1 */ | ||
1948 | |||
1949 | /* AFE all on step */ | ||
1950 | ODM_SetBBReg(pDM_Odm, rRx_Wait_CCA, bMaskDWord, 0x6FDB25A4); | ||
1951 | ODM_SetBBReg(pDM_Odm, rTx_CCK_RFON, bMaskDWord, 0x6FDB25A4); | ||
1952 | ODM_SetBBReg(pDM_Odm, rTx_CCK_BBON, bMaskDWord, 0x6FDB25A4); | ||
1953 | ODM_SetBBReg(pDM_Odm, rTx_OFDM_RFON, bMaskDWord, 0x6FDB25A4); | ||
1954 | ODM_SetBBReg(pDM_Odm, rTx_OFDM_BBON, bMaskDWord, 0x6FDB25A4); | ||
1955 | ODM_SetBBReg(pDM_Odm, rTx_To_Rx, bMaskDWord, 0x6FDB25A4); | ||
1956 | ODM_SetBBReg(pDM_Odm, rTx_To_Tx, bMaskDWord, 0x6FDB25A4); | ||
1957 | ODM_SetBBReg(pDM_Odm, rRx_CCK, bMaskDWord, 0x6FDB25A4); | ||
1958 | ODM_SetBBReg(pDM_Odm, rRx_OFDM, bMaskDWord, 0x6FDB25A4); | ||
1959 | ODM_SetBBReg(pDM_Odm, rRx_Wait_RIFS, bMaskDWord, 0x6FDB25A4); | ||
1960 | ODM_SetBBReg(pDM_Odm, rRx_TO_Rx, bMaskDWord, 0x6FDB25A4); | ||
1961 | ODM_SetBBReg(pDM_Odm, rStandby, bMaskDWord, 0x6FDB25A4); | ||
1962 | ODM_SetBBReg(pDM_Odm, rSleep, bMaskDWord, 0x6FDB25A4); | ||
1963 | ODM_SetBBReg(pDM_Odm, rPMPD_ANAEN, bMaskDWord, 0x6FDB25A4); | ||
1964 | ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_SwitchControl, bMaskDWord, 0x6FDB25A4); | ||
1965 | ODM_SetBBReg(pDM_Odm, rBlue_Tooth, bMaskDWord, 0x6FDB25A4); | ||
1966 | |||
1967 | /* 3 wire Disable */ | ||
1968 | ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord, 0xCCF000C0); | ||
1969 | |||
1970 | /* BB IQK Setting */ | ||
1971 | ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, 0x000800E4); | ||
1972 | ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22208000); | ||
1973 | |||
1974 | /* IQK setting tone@ 4.34Mhz */ | ||
1975 | ODM_SetBBReg(pDM_Odm, rTx_IQK_Tone_A, bMaskDWord, 0x10008C1C); | ||
1976 | ODM_SetBBReg(pDM_Odm, rTx_IQK, bMaskDWord, 0x01007c00); | ||
1977 | |||
1978 | /* Page B init */ | ||
1979 | ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x00080000); | ||
1980 | ODM_SetBBReg(pDM_Odm, rConfig_AntA, bMaskDWord, 0x0f600000); | ||
1981 | ODM_SetBBReg(pDM_Odm, rRx_IQK, bMaskDWord, 0x01004800); | ||
1982 | ODM_SetBBReg(pDM_Odm, rRx_IQK_Tone_A, bMaskDWord, 0x10008c1f); | ||
1983 | ODM_SetBBReg(pDM_Odm, rTx_IQK_PI_A, bMaskDWord, 0x82150008); | ||
1984 | ODM_SetBBReg(pDM_Odm, rRx_IQK_PI_A, bMaskDWord, 0x28150008); | ||
1985 | ODM_SetBBReg(pDM_Odm, rIQK_AGC_Rsp, bMaskDWord, 0x001028d0); | ||
1986 | |||
1987 | /* RF loop Setting */ | ||
1988 | ODM_SetRFReg(pDM_Odm, RF_PATH_A, 0x0, 0xFFFFF, 0x50008); | ||
1989 | |||
1990 | /* IQK Single tone start */ | ||
1991 | ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskDWord, 0x80800000); | ||
1992 | ODM_SetBBReg(pDM_Odm, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); | ||
1993 | udelay(1000); | ||
1994 | PSD_report_tmp = 0x0; | ||
1995 | |||
1996 | for (n = 0; n < 2; n++) { | ||
1997 | PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); | ||
1998 | if (PSD_report_tmp > AntA_report) | ||
1999 | AntA_report = PSD_report_tmp; | ||
2000 | } | ||
2001 | |||
2002 | PSD_report_tmp = 0x0; | ||
2003 | |||
2004 | ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_B); /* change to Antenna B */ | ||
2005 | udelay(10); | ||
2006 | |||
2007 | for (n = 0; n < 2; n++) { | ||
2008 | PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); | ||
2009 | if (PSD_report_tmp > AntB_report) | ||
2010 | AntB_report = PSD_report_tmp; | ||
2011 | } | ||
2012 | |||
2013 | /* change to open case */ | ||
2014 | ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, 0); /* change to Ant A and B all open case */ | ||
2015 | udelay(10); | ||
2016 | |||
2017 | for (n = 0; n < 2; n++) { | ||
2018 | PSD_report_tmp = GetPSDData(pDM_Odm, 14, initial_gain); | ||
2019 | if (PSD_report_tmp > AntO_report) | ||
2020 | AntO_report = PSD_report_tmp; | ||
2021 | } | ||
2022 | |||
2023 | /* Close IQK Single Tone function */ | ||
2024 | ODM_SetBBReg(pDM_Odm, rFPGA0_IQK, bMaskDWord, 0x00000000); | ||
2025 | PSD_report_tmp = 0x0; | ||
2026 | |||
2027 | /* 1 Return to antanna A */ | ||
2028 | ODM_SetBBReg(pDM_Odm, rFPGA0_XA_RFInterfaceOE, 0x300, Antenna_A); | ||
2029 | ODM_SetBBReg(pDM_Odm, rFPGA0_AnalogParameter4, bMaskDWord, Reg88c); | ||
2030 | ODM_SetBBReg(pDM_Odm, rOFDM0_TRMuxPar, bMaskDWord, Regc08); | ||
2031 | ODM_SetBBReg(pDM_Odm, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, Reg874); | ||
2032 | ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, 0x7F, 0x40); | ||
2033 | ODM_SetBBReg(pDM_Odm, rOFDM0_XAAGCCore1, bMaskDWord, Regc50); | ||
2034 | ODM_SetRFReg(pDM_Odm, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, CurrentChannel); | ||
2035 | ODM_SetRFReg(pDM_Odm, RF_PATH_A, 0x00, bRFRegOffsetMask, RfLoopReg); | ||
2036 | |||
2037 | /* Reload AFE Registers */ | ||
2038 | odm_PHY_ReloadAFERegisters(pDM_Odm, AFE_REG_8723A, AFE_Backup, 16); | ||
2039 | |||
2040 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_A[%d]= %d \n", 2416, AntA_report)); | ||
2041 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_B[%d]= %d \n", 2416, AntB_report)); | ||
2042 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("psd_report_O[%d]= %d \n", 2416, AntO_report)); | ||
2043 | |||
2044 | /* 2 Test Ant B based on Ant A is ON */ | ||
2045 | if (mode == ANTTESTB) { | ||
2046 | if (AntA_report >= 100) { | ||
2047 | if (AntB_report > (AntA_report+1)) { | ||
2048 | pDM_SWAT_Table->ANTB_ON = false; | ||
2049 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Single Antenna A\n")); | ||
2050 | } else { | ||
2051 | pDM_SWAT_Table->ANTB_ON = true; | ||
2052 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Dual Antenna is A and B\n")); | ||
2053 | } | ||
2054 | } else { | ||
2055 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Need to check again\n")); | ||
2056 | pDM_SWAT_Table->ANTB_ON = false; /* Set Antenna B off as default */ | ||
2057 | bResult = false; | ||
2058 | } | ||
2059 | } else if (mode == ANTTESTALL) { | ||
2060 | /* 2 Test Ant A and B based on DPDT Open */ | ||
2061 | if ((AntO_report >= 100) & (AntO_report < 118)) { | ||
2062 | if (AntA_report > (AntO_report+1)) { | ||
2063 | pDM_SWAT_Table->ANTA_ON = false; | ||
2064 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Ant A is OFF")); | ||
2065 | } else { | ||
2066 | pDM_SWAT_Table->ANTA_ON = true; | ||
2067 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Ant A is ON")); | ||
2068 | } | ||
2069 | |||
2070 | if (AntB_report > (AntO_report+2)) { | ||
2071 | pDM_SWAT_Table->ANTB_ON = false; | ||
2072 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Ant B is OFF")); | ||
2073 | } else { | ||
2074 | pDM_SWAT_Table->ANTB_ON = true; | ||
2075 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("Ant B is ON")); | ||
2076 | } | ||
2077 | } | ||
2078 | } else { | ||
2079 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_ANT_DIV, ODM_DBG_LOUD, ("ODM_SingleDualAntennaDetection(): Need to check again\n")); | ||
2080 | pDM_SWAT_Table->ANTA_ON = true; /* Set Antenna A on as default */ | ||
2081 | pDM_SWAT_Table->ANTB_ON = false; /* Set Antenna B off as default */ | ||
2082 | bResult = false; | ||
2083 | } | ||
2084 | return bResult; | ||
2085 | } | ||
2086 | |||
2087 | /* Justin: According to the current RRSI to adjust Response Frame TX power, 2012/11/05 */ | ||
2088 | void odm_dtc(struct dm_odm_t *pDM_Odm) | ||
2089 | { | ||
2090 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/odm_HWConfig.c b/drivers/staging/rtl8723au/hal/odm_HWConfig.c new file mode 100644 index 000000000000..72441709697e --- /dev/null +++ b/drivers/staging/rtl8723au/hal/odm_HWConfig.c | |||
@@ -0,0 +1,481 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | /* */ | ||
17 | /* include files */ | ||
18 | /* */ | ||
19 | |||
20 | #include "odm_precomp.h" | ||
21 | |||
22 | #define READ_AND_CONFIG READ_AND_CONFIG_MP | ||
23 | |||
24 | #define READ_AND_CONFIG_MP(ic, txt) (ODM_ReadAndConfig##txt##ic(pDM_Odm)) | ||
25 | #define READ_AND_CONFIG_TC(ic, txt) (ODM_ReadAndConfig_TC##txt##ic(pDM_Odm)) | ||
26 | |||
27 | static u8 odm_QueryRxPwrPercentage(s8 AntPower) | ||
28 | { | ||
29 | if ((AntPower <= -100) || (AntPower >= 20)) | ||
30 | return 0; | ||
31 | else if (AntPower >= 0) | ||
32 | return 100; | ||
33 | else | ||
34 | return 100 + AntPower; | ||
35 | } | ||
36 | |||
37 | static s32 odm_SignalScaleMapping_92CSeries(struct dm_odm_t *pDM_Odm, s32 CurrSig) | ||
38 | { | ||
39 | s32 RetSig = 0; | ||
40 | |||
41 | if ((pDM_Odm->SupportInterface == ODM_ITRF_USB) || (pDM_Odm->SupportInterface == ODM_ITRF_SDIO)) { | ||
42 | if (CurrSig >= 51 && CurrSig <= 100) | ||
43 | RetSig = 100; | ||
44 | else if (CurrSig >= 41 && CurrSig <= 50) | ||
45 | RetSig = 80 + ((CurrSig - 40)*2); | ||
46 | else if (CurrSig >= 31 && CurrSig <= 40) | ||
47 | RetSig = 66 + (CurrSig - 30); | ||
48 | else if (CurrSig >= 21 && CurrSig <= 30) | ||
49 | RetSig = 54 + (CurrSig - 20); | ||
50 | else if (CurrSig >= 10 && CurrSig <= 20) | ||
51 | RetSig = 42 + (((CurrSig - 10) * 2) / 3); | ||
52 | else if (CurrSig >= 5 && CurrSig <= 9) | ||
53 | RetSig = 22 + (((CurrSig - 5) * 3) / 2); | ||
54 | else if (CurrSig >= 1 && CurrSig <= 4) | ||
55 | RetSig = 6 + (((CurrSig - 1) * 3) / 2); | ||
56 | else | ||
57 | RetSig = CurrSig; | ||
58 | } | ||
59 | return RetSig; | ||
60 | } | ||
61 | |||
62 | static s32 odm_SignalScaleMapping(struct dm_odm_t *pDM_Odm, s32 CurrSig) | ||
63 | { | ||
64 | return odm_SignalScaleMapping_92CSeries(pDM_Odm, CurrSig); | ||
65 | } | ||
66 | |||
67 | static u8 | ||
68 | odm_EVMdbToPercentage( | ||
69 | s8 Value | ||
70 | ) | ||
71 | { | ||
72 | /* */ | ||
73 | /* -33dB~0dB to 0%~99% */ | ||
74 | /* */ | ||
75 | s8 ret_val; | ||
76 | |||
77 | ret_val = Value; | ||
78 | |||
79 | if (ret_val >= 0) | ||
80 | ret_val = 0; | ||
81 | if (ret_val <= -33) | ||
82 | ret_val = -33; | ||
83 | |||
84 | ret_val = 0 - ret_val; | ||
85 | ret_val *= 3; | ||
86 | |||
87 | if (ret_val == 99) | ||
88 | ret_val = 100; | ||
89 | |||
90 | return ret_val; | ||
91 | } | ||
92 | |||
93 | static void odm_RxPhyStatus92CSeries_Parsing(struct dm_odm_t *pDM_Odm, | ||
94 | struct odm_phy_info *pPhyInfo, | ||
95 | u8 *pPhyStatus, | ||
96 | struct odm_packet_info *pPktinfo) | ||
97 | { | ||
98 | struct phy_status_rpt *pPhyStaRpt = (struct phy_status_rpt *)pPhyStatus; | ||
99 | u8 i, Max_spatial_stream; | ||
100 | s8 rx_pwr[4], rx_pwr_all = 0; | ||
101 | u8 EVM, PWDB_ALL = 0, PWDB_ALL_BT; | ||
102 | u8 RSSI, total_rssi = 0; | ||
103 | u8 isCCKrate = 0; | ||
104 | u8 rf_rx_num = 0; | ||
105 | u8 cck_highpwr = 0; | ||
106 | |||
107 | isCCKrate = (pPktinfo->Rate <= DESC92C_RATE11M) ? true : false; | ||
108 | pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = -1; | ||
109 | pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1; | ||
110 | |||
111 | if (isCCKrate) { | ||
112 | u8 report; | ||
113 | u8 cck_agc_rpt; | ||
114 | |||
115 | pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK++; | ||
116 | /* (1)Hardware does not provide RSSI for CCK */ | ||
117 | /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */ | ||
118 | |||
119 | cck_highpwr = pDM_Odm->bCckHighPower; | ||
120 | |||
121 | cck_agc_rpt = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a ; | ||
122 | |||
123 | /* The RSSI formula should be modified according to the gain table */ | ||
124 | if (!cck_highpwr) { | ||
125 | report = (cck_agc_rpt & 0xc0)>>6; | ||
126 | switch (report) { | ||
127 | /* Modify the RF RNA gain value to -40, -20, -2, 14 by Jenyu's suggestion */ | ||
128 | /* Note: different RF with the different RNA gain. */ | ||
129 | case 0x3: | ||
130 | rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); | ||
131 | break; | ||
132 | case 0x2: | ||
133 | rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); | ||
134 | break; | ||
135 | case 0x1: | ||
136 | rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); | ||
137 | break; | ||
138 | case 0x0: | ||
139 | rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); | ||
140 | break; | ||
141 | } | ||
142 | } else { | ||
143 | report = (cck_agc_rpt & 0x60)>>5; | ||
144 | switch (report) { | ||
145 | case 0x3: | ||
146 | rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f)<<1) ; | ||
147 | break; | ||
148 | case 0x2: | ||
149 | rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f)<<1); | ||
150 | break; | ||
151 | case 0x1: | ||
152 | rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f)<<1) ; | ||
153 | break; | ||
154 | case 0x0: | ||
155 | rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f)<<1) ; | ||
156 | break; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); | ||
161 | |||
162 | /* Modification for ext-LNA board */ | ||
163 | if (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) { | ||
164 | if ((cck_agc_rpt>>7) == 0) { | ||
165 | PWDB_ALL = (PWDB_ALL > 94) ? 100 : (PWDB_ALL+6); | ||
166 | } else { | ||
167 | if (PWDB_ALL > 38) | ||
168 | PWDB_ALL -= 16; | ||
169 | else | ||
170 | PWDB_ALL = (PWDB_ALL <= 16) ? (PWDB_ALL>>2) : (PWDB_ALL-12); | ||
171 | } | ||
172 | |||
173 | /* CCK modification */ | ||
174 | if (PWDB_ALL > 25 && PWDB_ALL <= 60) | ||
175 | PWDB_ALL += 6; | ||
176 | } else { /* Modification for int-LNA board */ | ||
177 | if (PWDB_ALL > 99) | ||
178 | PWDB_ALL -= 8; | ||
179 | else if (PWDB_ALL > 50 && PWDB_ALL <= 68) | ||
180 | PWDB_ALL += 4; | ||
181 | } | ||
182 | pPhyInfo->RxPWDBAll = PWDB_ALL; | ||
183 | pPhyInfo->BTRxRSSIPercentage = PWDB_ALL; | ||
184 | pPhyInfo->RecvSignalPower = rx_pwr_all; | ||
185 | /* (3) Get Signal Quality (EVM) */ | ||
186 | if (pPktinfo->bPacketMatchBSSID) { | ||
187 | u8 SQ, SQ_rpt; | ||
188 | |||
189 | SQ_rpt = pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all; | ||
190 | |||
191 | if (SQ_rpt > 64) | ||
192 | SQ = 0; | ||
193 | else if (SQ_rpt < 20) | ||
194 | SQ = 100; | ||
195 | else | ||
196 | SQ = ((64-SQ_rpt) * 100) / 44; | ||
197 | |||
198 | pPhyInfo->SignalQuality = SQ; | ||
199 | pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = SQ; | ||
200 | pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1; | ||
201 | } | ||
202 | } else { /* is OFDM rate */ | ||
203 | pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM++; | ||
204 | |||
205 | /* (1)Get RSSI for HT rate */ | ||
206 | |||
207 | for (i = RF_PATH_A; i < RF_PATH_MAX; i++) { | ||
208 | /* 2008/01/30 MH we will judge RF RX path now. */ | ||
209 | if (pDM_Odm->RFPathRxEnable & BIT(i)) | ||
210 | rf_rx_num++; | ||
211 | |||
212 | rx_pwr[i] = ((pPhyStaRpt->path_agc[i].gain & 0x3F)*2) - 110; | ||
213 | |||
214 | pPhyInfo->RxPwr[i] = rx_pwr[i]; | ||
215 | |||
216 | /* Translate DBM to percentage. */ | ||
217 | RSSI = odm_QueryRxPwrPercentage(rx_pwr[i]); | ||
218 | total_rssi += RSSI; | ||
219 | |||
220 | /* Modification for ext-LNA board */ | ||
221 | if (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) { | ||
222 | if ((pPhyStaRpt->path_agc[i].trsw) == 1) | ||
223 | RSSI = (RSSI > 94) ? 100 : (RSSI+6); | ||
224 | else | ||
225 | RSSI = (RSSI <= 16) ? (RSSI>>3) : (RSSI-16); | ||
226 | |||
227 | if ((RSSI <= 34) && (RSSI >= 4)) | ||
228 | RSSI -= 4; | ||
229 | } | ||
230 | |||
231 | pPhyInfo->RxMIMOSignalStrength[i] = (u8) RSSI; | ||
232 | |||
233 | /* Get Rx snr value in DB */ | ||
234 | pPhyInfo->RxSNR[i] = pDM_Odm->PhyDbgInfo.RxSNRdB[i] = (s32)(pPhyStaRpt->path_rxsnr[i]/2); | ||
235 | } | ||
236 | |||
237 | /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */ | ||
238 | rx_pwr_all = (((pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all) >> 1) & 0x7f)-110; | ||
239 | |||
240 | PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all); | ||
241 | PWDB_ALL_BT = PWDB_ALL; | ||
242 | |||
243 | pPhyInfo->RxPWDBAll = PWDB_ALL; | ||
244 | pPhyInfo->BTRxRSSIPercentage = PWDB_ALL_BT; | ||
245 | pPhyInfo->RxPower = rx_pwr_all; | ||
246 | pPhyInfo->RecvSignalPower = rx_pwr_all; | ||
247 | |||
248 | /* (3)EVM of HT rate */ | ||
249 | if (pPktinfo->Rate >= DESC92C_RATEMCS8 && pPktinfo->Rate <= DESC92C_RATEMCS15) | ||
250 | Max_spatial_stream = 2; /* both spatial stream make sense */ | ||
251 | else | ||
252 | Max_spatial_stream = 1; /* only spatial stream 1 makes sense */ | ||
253 | |||
254 | for (i = 0; i < Max_spatial_stream; i++) { | ||
255 | /* Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment */ | ||
256 | /* fill most significant bit to "zero" when doing shifting operation which may change a negative */ | ||
257 | /* value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. */ | ||
258 | EVM = odm_EVMdbToPercentage((pPhyStaRpt->stream_rxevm[i])); /* dbm */ | ||
259 | |||
260 | if (pPktinfo->bPacketMatchBSSID) { | ||
261 | if (i == RF_PATH_A) { | ||
262 | /* Fill value in RFD, Get the first spatial stream only */ | ||
263 | pPhyInfo->SignalQuality = (u8)(EVM & 0xff); | ||
264 | } | ||
265 | pPhyInfo->RxMIMOSignalQuality[i] = (u8)(EVM & 0xff); | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | /* UI BSS List signal strength(in percentage), make it good looking, from 0~100. */ | ||
270 | /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */ | ||
271 | if (isCCKrate) { | ||
272 | pPhyInfo->SignalStrength = (u8)(odm_SignalScaleMapping(pDM_Odm, PWDB_ALL));/* PWDB_ALL; */ | ||
273 | } else { | ||
274 | if (rf_rx_num != 0) | ||
275 | pPhyInfo->SignalStrength = (u8)(odm_SignalScaleMapping(pDM_Odm, total_rssi /= rf_rx_num)); | ||
276 | } | ||
277 | } | ||
278 | |||
279 | void odm_Init_RSSIForDM23a(struct dm_odm_t *pDM_Odm) | ||
280 | { | ||
281 | } | ||
282 | |||
283 | static void odm_Process_RSSIForDM(struct dm_odm_t *pDM_Odm, | ||
284 | struct odm_phy_info *pPhyInfo, | ||
285 | struct odm_packet_info *pPktinfo) | ||
286 | { | ||
287 | s32 UndecoratedSmoothedPWDB, UndecoratedSmoothedCCK; | ||
288 | s32 UndecoratedSmoothedOFDM, RSSI_Ave; | ||
289 | u8 isCCKrate = 0; | ||
290 | u8 RSSI_max, RSSI_min, i; | ||
291 | u32 OFDM_pkt = 0; | ||
292 | u32 Weighting = 0; | ||
293 | struct sta_info *pEntry; | ||
294 | |||
295 | if (pPktinfo->StationID == 0xFF) | ||
296 | return; | ||
297 | |||
298 | pEntry = pDM_Odm->pODM_StaInfo[pPktinfo->StationID]; | ||
299 | if (!IS_STA_VALID(pEntry)) | ||
300 | return; | ||
301 | if ((!pPktinfo->bPacketMatchBSSID)) | ||
302 | return; | ||
303 | |||
304 | isCCKrate = (pPktinfo->Rate <= DESC92C_RATE11M) ? true : false; | ||
305 | |||
306 | /* Smart Antenna Debug Message------------------*/ | ||
307 | |||
308 | UndecoratedSmoothedCCK = pEntry->rssi_stat.UndecoratedSmoothedCCK; | ||
309 | UndecoratedSmoothedOFDM = pEntry->rssi_stat.UndecoratedSmoothedOFDM; | ||
310 | UndecoratedSmoothedPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB; | ||
311 | |||
312 | if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) { | ||
313 | if (!isCCKrate) { /* ofdm rate */ | ||
314 | if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_B] == 0) { | ||
315 | RSSI_Ave = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A]; | ||
316 | } else { | ||
317 | if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_A] > pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]) { | ||
318 | RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A]; | ||
319 | RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]; | ||
320 | } else { | ||
321 | RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]; | ||
322 | RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A]; | ||
323 | } | ||
324 | if ((RSSI_max - RSSI_min) < 3) | ||
325 | RSSI_Ave = RSSI_max; | ||
326 | else if ((RSSI_max - RSSI_min) < 6) | ||
327 | RSSI_Ave = RSSI_max - 1; | ||
328 | else if ((RSSI_max - RSSI_min) < 10) | ||
329 | RSSI_Ave = RSSI_max - 2; | ||
330 | else | ||
331 | RSSI_Ave = RSSI_max - 3; | ||
332 | } | ||
333 | |||
334 | /* 1 Process OFDM RSSI */ | ||
335 | if (UndecoratedSmoothedOFDM <= 0) { | ||
336 | /* initialize */ | ||
337 | UndecoratedSmoothedOFDM = pPhyInfo->RxPWDBAll; | ||
338 | } else { | ||
339 | if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedOFDM) { | ||
340 | UndecoratedSmoothedOFDM = | ||
341 | (((UndecoratedSmoothedOFDM)*(Rx_Smooth_Factor-1)) + | ||
342 | (RSSI_Ave)) / (Rx_Smooth_Factor); | ||
343 | UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM + 1; | ||
344 | } else { | ||
345 | UndecoratedSmoothedOFDM = | ||
346 | (((UndecoratedSmoothedOFDM)*(Rx_Smooth_Factor-1)) + | ||
347 | (RSSI_Ave)) / (Rx_Smooth_Factor); | ||
348 | } | ||
349 | } | ||
350 | pEntry->rssi_stat.PacketMap = (pEntry->rssi_stat.PacketMap<<1) | BIT0; | ||
351 | } else { | ||
352 | RSSI_Ave = pPhyInfo->RxPWDBAll; | ||
353 | |||
354 | /* 1 Process CCK RSSI */ | ||
355 | if (UndecoratedSmoothedCCK <= 0) { | ||
356 | /* initialize */ | ||
357 | UndecoratedSmoothedCCK = pPhyInfo->RxPWDBAll; | ||
358 | } else { | ||
359 | if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedCCK) { | ||
360 | UndecoratedSmoothedCCK = | ||
361 | (((UndecoratedSmoothedCCK)*(Rx_Smooth_Factor-1)) + | ||
362 | (pPhyInfo->RxPWDBAll)) / (Rx_Smooth_Factor); | ||
363 | UndecoratedSmoothedCCK = UndecoratedSmoothedCCK + 1; | ||
364 | } else { | ||
365 | UndecoratedSmoothedCCK = | ||
366 | (((UndecoratedSmoothedCCK)*(Rx_Smooth_Factor-1)) + | ||
367 | (pPhyInfo->RxPWDBAll)) / (Rx_Smooth_Factor); | ||
368 | } | ||
369 | } | ||
370 | pEntry->rssi_stat.PacketMap = pEntry->rssi_stat.PacketMap<<1; | ||
371 | } | ||
372 | |||
373 | /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */ | ||
374 | if (pEntry->rssi_stat.ValidBit >= 64) | ||
375 | pEntry->rssi_stat.ValidBit = 64; | ||
376 | else | ||
377 | pEntry->rssi_stat.ValidBit++; | ||
378 | |||
379 | for (i = 0; i < pEntry->rssi_stat.ValidBit; i++) | ||
380 | OFDM_pkt += (u8)(pEntry->rssi_stat.PacketMap>>i)&BIT0; | ||
381 | |||
382 | if (pEntry->rssi_stat.ValidBit == 64) { | ||
383 | Weighting = ((OFDM_pkt<<4) > 64)?64:(OFDM_pkt<<4); | ||
384 | UndecoratedSmoothedPWDB = (Weighting*UndecoratedSmoothedOFDM+(64-Weighting)*UndecoratedSmoothedCCK)>>6; | ||
385 | } else { | ||
386 | if (pEntry->rssi_stat.ValidBit != 0) | ||
387 | UndecoratedSmoothedPWDB = (OFDM_pkt*UndecoratedSmoothedOFDM+(pEntry->rssi_stat.ValidBit-OFDM_pkt)*UndecoratedSmoothedCCK)/pEntry->rssi_stat.ValidBit; | ||
388 | else | ||
389 | UndecoratedSmoothedPWDB = 0; | ||
390 | } | ||
391 | pEntry->rssi_stat.UndecoratedSmoothedCCK = UndecoratedSmoothedCCK; | ||
392 | pEntry->rssi_stat.UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM; | ||
393 | pEntry->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB; | ||
394 | } | ||
395 | } | ||
396 | |||
397 | /* Endianness before calling this API */ | ||
398 | static void ODM_PhyStatusQuery23a_92CSeries(struct dm_odm_t *pDM_Odm, | ||
399 | struct odm_phy_info *pPhyInfo, | ||
400 | u8 *pPhyStatus, | ||
401 | struct odm_packet_info *pPktinfo) | ||
402 | { | ||
403 | odm_RxPhyStatus92CSeries_Parsing(pDM_Odm, pPhyInfo, | ||
404 | pPhyStatus, pPktinfo); | ||
405 | if (pDM_Odm->RSSI_test) { | ||
406 | /* Select the packets to do RSSI checking for antenna switching. */ | ||
407 | if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) | ||
408 | ODM_SwAntDivChkPerPktRssi(pDM_Odm, pPktinfo->StationID, pPhyInfo); | ||
409 | } else { | ||
410 | odm_Process_RSSIForDM(pDM_Odm, pPhyInfo, pPktinfo); | ||
411 | } | ||
412 | } | ||
413 | |||
414 | void ODM_PhyStatusQuery23a(struct dm_odm_t *pDM_Odm, struct odm_phy_info *pPhyInfo, | ||
415 | u8 *pPhyStatus, struct odm_packet_info *pPktinfo) | ||
416 | { | ||
417 | ODM_PhyStatusQuery23a_92CSeries(pDM_Odm, pPhyInfo, pPhyStatus, pPktinfo); | ||
418 | } | ||
419 | |||
420 | /* For future use. */ | ||
421 | void ODM_MacStatusQuery23a(struct dm_odm_t *pDM_Odm, u8 *pMacStatus, u8 MacID, | ||
422 | bool bPacketMatchBSSID, bool bPacketToSelf, | ||
423 | bool bPacketBeacon) | ||
424 | { | ||
425 | /* 2011/10/19 Driver team will handle in the future. */ | ||
426 | |||
427 | } | ||
428 | |||
429 | enum hal_status | ||
430 | ODM_ConfigRFWithHeaderFile23a( | ||
431 | struct dm_odm_t *pDM_Odm, | ||
432 | enum RF_RADIO_PATH Content, | ||
433 | enum RF_RADIO_PATH eRFPath | ||
434 | ) | ||
435 | { | ||
436 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, | ||
437 | ("===>ODM_ConfigRFWithHeaderFile23a\n")); | ||
438 | if (pDM_Odm->SupportICType == ODM_RTL8723A) { | ||
439 | if (eRFPath == RF_PATH_A) | ||
440 | READ_AND_CONFIG_MP(8723A, _RadioA_1T_); | ||
441 | |||
442 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, | ||
443 | (" ===> ODM_ConfigRFWithHeaderFile23a() Radio_A:Rtl8723RadioA_1TArray\n")); | ||
444 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, | ||
445 | (" ===> ODM_ConfigRFWithHeaderFile23a() Radio_B:Rtl8723RadioB_1TArray\n")); | ||
446 | } | ||
447 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, | ||
448 | ("ODM_ConfigRFWithHeaderFile23a: Radio No %x\n", eRFPath)); | ||
449 | return HAL_STATUS_SUCCESS; | ||
450 | } | ||
451 | |||
452 | enum hal_status | ||
453 | ODM_ConfigBBWithHeaderFile23a( | ||
454 | struct dm_odm_t *pDM_Odm, | ||
455 | enum odm_bb_config_type ConfigType | ||
456 | ) | ||
457 | { | ||
458 | if (pDM_Odm->SupportICType == ODM_RTL8723A) { | ||
459 | if (ConfigType == CONFIG_BB_PHY_REG) | ||
460 | READ_AND_CONFIG_MP(8723A, _PHY_REG_1T_); | ||
461 | else if (ConfigType == CONFIG_BB_AGC_TAB) | ||
462 | READ_AND_CONFIG_MP(8723A, _AGC_TAB_1T_); | ||
463 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, | ||
464 | (" ===> phy_ConfigBBWithHeaderFile() phy:Rtl8723AGCTAB_1TArray\n")); | ||
465 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, | ||
466 | (" ===> phy_ConfigBBWithHeaderFile() agc:Rtl8723PHY_REG_1TArray\n")); | ||
467 | } | ||
468 | return HAL_STATUS_SUCCESS; | ||
469 | } | ||
470 | |||
471 | enum hal_status | ||
472 | ODM_ConfigMACWithHeaderFile23a( | ||
473 | struct dm_odm_t *pDM_Odm | ||
474 | ) | ||
475 | { | ||
476 | u8 result = HAL_STATUS_SUCCESS; | ||
477 | |||
478 | if (pDM_Odm->SupportICType == ODM_RTL8723A) | ||
479 | READ_AND_CONFIG_MP(8723A, _MAC_REG_); | ||
480 | return result; | ||
481 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c b/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c new file mode 100644 index 000000000000..d076e14f36b9 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c | |||
@@ -0,0 +1,162 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | #include "odm_precomp.h" | ||
17 | |||
18 | void | ||
19 | odm_ConfigRFReg_8723A( | ||
20 | struct dm_odm_t *pDM_Odm, | ||
21 | u32 Addr, | ||
22 | u32 Data, | ||
23 | enum RF_RADIO_PATH RF_PATH, | ||
24 | u32 RegAddr | ||
25 | ) | ||
26 | { | ||
27 | if (Addr == 0xfe) { | ||
28 | msleep(50); | ||
29 | } else if (Addr == 0xfd) { | ||
30 | mdelay(5); | ||
31 | } else if (Addr == 0xfc) { | ||
32 | mdelay(1); | ||
33 | } else if (Addr == 0xfb) { | ||
34 | udelay(50); | ||
35 | } else if (Addr == 0xfa) { | ||
36 | udelay(5); | ||
37 | } else if (Addr == 0xf9) { | ||
38 | udelay(1); | ||
39 | } else { | ||
40 | ODM_SetRFReg(pDM_Odm, RF_PATH, RegAddr, bRFRegOffsetMask, Data); | ||
41 | /* Add 1us delay between BB/RF register setting. */ | ||
42 | udelay(1); | ||
43 | } | ||
44 | } | ||
45 | |||
46 | void odm_ConfigRF_RadioA_8723A(struct dm_odm_t *pDM_Odm, | ||
47 | u32 Addr, | ||
48 | u32 Data | ||
49 | ) | ||
50 | { | ||
51 | u32 content = 0x1000; /* RF_Content: radioa_txt */ | ||
52 | u32 maskforPhySet = (u32)(content&0xE000); | ||
53 | |||
54 | odm_ConfigRFReg_8723A(pDM_Odm, Addr, Data, RF_PATH_A, | ||
55 | Addr|maskforPhySet); | ||
56 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, | ||
57 | ("===> ODM_ConfigRFWithHeaderFile23a: [RadioA] %08X %08X\n", | ||
58 | Addr, Data)); | ||
59 | } | ||
60 | |||
61 | void odm_ConfigRF_RadioB_8723A(struct dm_odm_t *pDM_Odm, | ||
62 | u32 Addr, | ||
63 | u32 Data | ||
64 | ) | ||
65 | { | ||
66 | u32 content = 0x1001; /* RF_Content: radiob_txt */ | ||
67 | u32 maskforPhySet = (u32)(content&0xE000); | ||
68 | |||
69 | odm_ConfigRFReg_8723A(pDM_Odm, Addr, Data, RF_PATH_B, | ||
70 | Addr|maskforPhySet); | ||
71 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, | ||
72 | ("===> ODM_ConfigRFWithHeaderFile23a: [RadioB] %08X %08X\n", | ||
73 | Addr, Data)); | ||
74 | } | ||
75 | |||
76 | void odm_ConfigMAC_8723A(struct dm_odm_t *pDM_Odm, | ||
77 | u32 Addr, | ||
78 | u8 Data | ||
79 | ) | ||
80 | { | ||
81 | ODM_Write1Byte(pDM_Odm, Addr, Data); | ||
82 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, | ||
83 | ("===> ODM_ConfigMACWithHeaderFile23a: [MAC_REG] %08X %08X\n", | ||
84 | Addr, Data)); | ||
85 | } | ||
86 | |||
87 | void | ||
88 | odm_ConfigBB_AGC_8723A( | ||
89 | struct dm_odm_t *pDM_Odm, | ||
90 | u32 Addr, | ||
91 | u32 Bitmask, | ||
92 | u32 Data | ||
93 | ) | ||
94 | { | ||
95 | ODM_SetBBReg(pDM_Odm, Addr, Bitmask, Data); | ||
96 | /* Add 1us delay between BB/RF register setting. */ | ||
97 | udelay(1); | ||
98 | |||
99 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, | ||
100 | ("===> ODM_ConfigBBWithHeaderFile23a: [AGC_TAB] %08X %08X\n", | ||
101 | Addr, Data)); | ||
102 | } | ||
103 | |||
104 | void | ||
105 | odm_ConfigBB_PHY_REG_PG_8723A( | ||
106 | struct dm_odm_t *pDM_Odm, | ||
107 | u32 Addr, | ||
108 | u32 Bitmask, | ||
109 | u32 Data | ||
110 | ) | ||
111 | { | ||
112 | if (Addr == 0xfe) | ||
113 | msleep(50); | ||
114 | else if (Addr == 0xfd) | ||
115 | mdelay(5); | ||
116 | else if (Addr == 0xfc) | ||
117 | mdelay(1); | ||
118 | else if (Addr == 0xfb) | ||
119 | udelay(50); | ||
120 | else if (Addr == 0xfa) | ||
121 | udelay(5); | ||
122 | else if (Addr == 0xf9) | ||
123 | udelay(1); | ||
124 | /* TODO: ODM_StorePwrIndexDiffRateOffset(...) */ | ||
125 | /* storePwrIndexDiffRateOffset(Adapter, Addr, Bitmask, Data); */ | ||
126 | |||
127 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, | ||
128 | ("===> ODM_ConfigBBWithHeaderFile23a: [PHY_REG] %08X %08X %08X\n", | ||
129 | Addr, Bitmask, Data)); | ||
130 | } | ||
131 | |||
132 | void | ||
133 | odm_ConfigBB_PHY_8723A( | ||
134 | struct dm_odm_t *pDM_Odm, | ||
135 | u32 Addr, | ||
136 | u32 Bitmask, | ||
137 | u32 Data | ||
138 | ) | ||
139 | { | ||
140 | if (Addr == 0xfe) | ||
141 | msleep(50); | ||
142 | else if (Addr == 0xfd) | ||
143 | mdelay(5); | ||
144 | else if (Addr == 0xfc) | ||
145 | mdelay(1); | ||
146 | else if (Addr == 0xfb) | ||
147 | udelay(50); | ||
148 | else if (Addr == 0xfa) | ||
149 | udelay(5); | ||
150 | else if (Addr == 0xf9) | ||
151 | udelay(1); | ||
152 | else if (Addr == 0xa24) | ||
153 | pDM_Odm->RFCalibrateInfo.RegA24 = Data; | ||
154 | ODM_SetBBReg(pDM_Odm, Addr, Bitmask, Data); | ||
155 | |||
156 | /* Add 1us delay between BB/RF register setting. */ | ||
157 | udelay(1); | ||
158 | |||
159 | ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, | ||
160 | ("===> ODM_ConfigBBWithHeaderFile23a: [PHY_REG] %08X %08X\n", | ||
161 | Addr, Data)); | ||
162 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/odm_debug.c b/drivers/staging/rtl8723au/hal/odm_debug.c new file mode 100644 index 000000000000..c912ab89bc3e --- /dev/null +++ b/drivers/staging/rtl8723au/hal/odm_debug.c | |||
@@ -0,0 +1,24 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | #include "odm_precomp.h" | ||
17 | |||
18 | void ODM_InitDebugSetting23a(struct dm_odm_t *pDM_Odm) | ||
19 | { | ||
20 | pDM_Odm->DebugLevel = ODM_DBG_TRACE; | ||
21 | pDM_Odm->DebugComponents = 0; | ||
22 | } | ||
23 | |||
24 | u32 GlobalDebugLevel23A; | ||
diff --git a/drivers/staging/rtl8723au/hal/odm_interface.c b/drivers/staging/rtl8723au/hal/odm_interface.c new file mode 100644 index 000000000000..bef1269749d0 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/odm_interface.c | |||
@@ -0,0 +1,236 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | /* */ | ||
17 | /* include files */ | ||
18 | /* */ | ||
19 | |||
20 | #include "odm_precomp.h" | ||
21 | /* */ | ||
22 | /* ODM IO Relative API. */ | ||
23 | /* */ | ||
24 | |||
25 | u8 ODM_Read1Byte(struct dm_odm_t *pDM_Odm, | ||
26 | u32 RegAddr | ||
27 | ) | ||
28 | { | ||
29 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
30 | |||
31 | return rtw_read8(Adapter, RegAddr); | ||
32 | } | ||
33 | |||
34 | u16 ODM_Read2Byte(struct dm_odm_t *pDM_Odm, | ||
35 | u32 RegAddr | ||
36 | ) | ||
37 | { | ||
38 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
39 | |||
40 | return rtw_read16(Adapter, RegAddr); | ||
41 | } | ||
42 | |||
43 | u32 ODM_Read4Byte(struct dm_odm_t *pDM_Odm, | ||
44 | u32 RegAddr | ||
45 | ) | ||
46 | { | ||
47 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
48 | |||
49 | return rtw_read32(Adapter, RegAddr); | ||
50 | } | ||
51 | |||
52 | void ODM_Write1Byte( | ||
53 | struct dm_odm_t *pDM_Odm, | ||
54 | u32 RegAddr, | ||
55 | u8 Data | ||
56 | ) | ||
57 | { | ||
58 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
59 | |||
60 | rtw_write8(Adapter, RegAddr, Data); | ||
61 | } | ||
62 | |||
63 | void ODM_Write2Byte( | ||
64 | struct dm_odm_t *pDM_Odm, | ||
65 | u32 RegAddr, | ||
66 | u16 Data | ||
67 | ) | ||
68 | { | ||
69 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
70 | |||
71 | rtw_write16(Adapter, RegAddr, Data); | ||
72 | } | ||
73 | |||
74 | void ODM_Write4Byte( | ||
75 | struct dm_odm_t *pDM_Odm, | ||
76 | u32 RegAddr, | ||
77 | u32 Data | ||
78 | ) | ||
79 | { | ||
80 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
81 | |||
82 | rtw_write32(Adapter, RegAddr, Data); | ||
83 | |||
84 | } | ||
85 | |||
86 | void ODM_SetMACReg( | ||
87 | struct dm_odm_t *pDM_Odm, | ||
88 | u32 RegAddr, | ||
89 | u32 BitMask, | ||
90 | u32 Data | ||
91 | ) | ||
92 | { | ||
93 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
94 | |||
95 | PHY_SetBBReg(Adapter, RegAddr, BitMask, Data); | ||
96 | } | ||
97 | |||
98 | u32 ODM_GetMACReg( | ||
99 | struct dm_odm_t *pDM_Odm, | ||
100 | u32 RegAddr, | ||
101 | u32 BitMask | ||
102 | ) | ||
103 | { | ||
104 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
105 | |||
106 | return PHY_QueryBBReg(Adapter, RegAddr, BitMask); | ||
107 | } | ||
108 | |||
109 | void ODM_SetBBReg( | ||
110 | struct dm_odm_t *pDM_Odm, | ||
111 | u32 RegAddr, | ||
112 | u32 BitMask, | ||
113 | u32 Data | ||
114 | ) | ||
115 | { | ||
116 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
117 | |||
118 | PHY_SetBBReg(Adapter, RegAddr, BitMask, Data); | ||
119 | } | ||
120 | |||
121 | u32 ODM_GetBBReg( | ||
122 | struct dm_odm_t *pDM_Odm, | ||
123 | u32 RegAddr, | ||
124 | u32 BitMask | ||
125 | ) | ||
126 | { | ||
127 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
128 | |||
129 | return PHY_QueryBBReg(Adapter, RegAddr, BitMask); | ||
130 | } | ||
131 | |||
132 | void ODM_SetRFReg( | ||
133 | struct dm_odm_t *pDM_Odm, | ||
134 | enum RF_RADIO_PATH eRFPath, | ||
135 | u32 RegAddr, | ||
136 | u32 BitMask, | ||
137 | u32 Data | ||
138 | ) | ||
139 | { | ||
140 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
141 | |||
142 | PHY_SetRFReg(Adapter, eRFPath, RegAddr, BitMask, Data); | ||
143 | } | ||
144 | |||
145 | u32 ODM_GetRFReg( | ||
146 | struct dm_odm_t *pDM_Odm, | ||
147 | enum RF_RADIO_PATH eRFPath, | ||
148 | u32 RegAddr, | ||
149 | u32 BitMask | ||
150 | ) | ||
151 | { | ||
152 | struct rtw_adapter *Adapter = pDM_Odm->Adapter; | ||
153 | |||
154 | return PHY_QueryRFReg(Adapter, eRFPath, RegAddr, BitMask); | ||
155 | } | ||
156 | |||
157 | /* */ | ||
158 | /* ODM Memory relative API. */ | ||
159 | /* */ | ||
160 | void ODM_AllocateMemory( | ||
161 | struct dm_odm_t *pDM_Odm, | ||
162 | void **pPtr, | ||
163 | u32 length | ||
164 | ) | ||
165 | { | ||
166 | *pPtr = rtw_zvmalloc(length); | ||
167 | } | ||
168 | |||
169 | /* length could be ignored, used to detect memory leakage. */ | ||
170 | void ODM_FreeMemory( | ||
171 | struct dm_odm_t *pDM_Odm, | ||
172 | void *pPtr, | ||
173 | u32 length | ||
174 | ) | ||
175 | { | ||
176 | rtw_vmfree(pPtr, length); | ||
177 | } | ||
178 | |||
179 | /* */ | ||
180 | /* ODM MISC relative API. */ | ||
181 | /* */ | ||
182 | void | ||
183 | ODM_AcquireSpinLock( | ||
184 | struct dm_odm_t *pDM_Odm, | ||
185 | enum rt_spinlock_type type | ||
186 | ) | ||
187 | { | ||
188 | } | ||
189 | |||
190 | void ODM_ReleaseSpinLock( | ||
191 | struct dm_odm_t *pDM_Odm, | ||
192 | enum rt_spinlock_type type | ||
193 | ) | ||
194 | { | ||
195 | } | ||
196 | |||
197 | /* */ | ||
198 | /* Work item relative API. FOr MP driver only~! */ | ||
199 | /* */ | ||
200 | void ODM_InitializeWorkItem( | ||
201 | struct dm_odm_t *pDM_Odm, | ||
202 | void *pRtWorkItem, | ||
203 | RT_WORKITEM_CALL_BACK RtWorkItemCallback, | ||
204 | void *pContext, | ||
205 | const char *szID | ||
206 | ) | ||
207 | { | ||
208 | } | ||
209 | |||
210 | /* */ | ||
211 | /* ODM Timer relative API. */ | ||
212 | /* */ | ||
213 | void ODM_SetTimer(struct dm_odm_t *pDM_Odm, struct timer_list *pTimer, u32 msDelay) | ||
214 | { | ||
215 | mod_timer(pTimer, jiffies + msecs_to_jiffies(msDelay)); /* ms */ | ||
216 | } | ||
217 | |||
218 | void ODM_ReleaseTimer(struct dm_odm_t *pDM_Odm, struct timer_list *pTimer) | ||
219 | { | ||
220 | } | ||
221 | |||
222 | /* */ | ||
223 | /* ODM FW relative API. */ | ||
224 | /* */ | ||
225 | u32 ODM_FillH2CCmd( | ||
226 | u8 *pH2CBuffer, | ||
227 | u32 H2CBufferLen, | ||
228 | u32 CmdNum, | ||
229 | u32 *pElementID, | ||
230 | u32 *pCmdLen, | ||
231 | u8 **pCmbBuffer, | ||
232 | u8 *CmdStartSeq | ||
233 | ) | ||
234 | { | ||
235 | return true; | ||
236 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c new file mode 100644 index 000000000000..2d4135f741eb --- /dev/null +++ b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c | |||
@@ -0,0 +1,11304 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | *published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | #include <drv_types.h> | ||
16 | #include <rtl8723a_hal.h> | ||
17 | #include <rtw_ioctl_set.h> | ||
18 | |||
19 | #define DIS_PS_RX_BCN | ||
20 | |||
21 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
22 | |||
23 | u32 BTCoexDbgLevel = _bt_dbg_off_; | ||
24 | |||
25 | #define RTPRINT(_Comp, _Level, Fmt)\ | ||
26 | do {\ | ||
27 | if ((BTCoexDbgLevel == _bt_dbg_on_)) {\ | ||
28 | printk Fmt;\ | ||
29 | } \ | ||
30 | } while (0) | ||
31 | |||
32 | #define RTPRINT_ADDR(dbgtype, dbgflag, printstr, _Ptr)\ | ||
33 | if ((BTCoexDbgLevel == _bt_dbg_on_)) {\ | ||
34 | u32 __i; \ | ||
35 | u8 *ptr = (u8 *)_Ptr; \ | ||
36 | printk printstr; \ | ||
37 | printk(" "); \ | ||
38 | for (__i = 0; __i < 6; __i++) \ | ||
39 | printk("%02X%s", ptr[__i], (__i == 5)?"":"-"); \ | ||
40 | printk("\n"); \ | ||
41 | } | ||
42 | #define RTPRINT_DATA(dbgtype, dbgflag, _TitleString, _HexData, _HexDataLen)\ | ||
43 | if ((BTCoexDbgLevel == _bt_dbg_on_)) {\ | ||
44 | u32 __i; \ | ||
45 | u8 *ptr = (u8 *)_HexData; \ | ||
46 | printk(_TitleString); \ | ||
47 | for (__i = 0; __i < (u32)_HexDataLen; __i++) { \ | ||
48 | printk("%02X%s", ptr[__i], (((__i + 1) % 4) == 0)?" ":" ");\ | ||
49 | if (((__i + 1) % 16) == 0) \ | ||
50 | printk("\n"); \ | ||
51 | } \ | ||
52 | printk("\n"); \ | ||
53 | } | ||
54 | /* Added by Annie, 2005-11-22. */ | ||
55 | #define MAX_STR_LEN 64 | ||
56 | /* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. */ | ||
57 | #define PRINTABLE(_ch) (_ch >= ' ' && _ch <= '~') | ||
58 | #define RT_PRINT_STR(_Comp, _Level, _TitleString, _Ptr, _Len) \ | ||
59 | { \ | ||
60 | u32 __i; \ | ||
61 | u8 buffer[MAX_STR_LEN]; \ | ||
62 | u32 length = (_Len < MAX_STR_LEN) ? _Len : (MAX_STR_LEN-1);\ | ||
63 | memset(buffer, 0, MAX_STR_LEN); \ | ||
64 | memcpy(buffer, (u8 *)_Ptr, length); \ | ||
65 | for (__i = 0; __i < length; __i++) { \ | ||
66 | if (!PRINTABLE(buffer[__i])) \ | ||
67 | buffer[__i] = '?'; \ | ||
68 | } \ | ||
69 | buffer[length] = '\0'; \ | ||
70 | printk(_TitleString); \ | ||
71 | printk(": %d, <%s>\n", _Len, buffer); \ | ||
72 | } | ||
73 | #endif | ||
74 | |||
75 | #define DCMD_Printf(...) | ||
76 | #define RT_ASSERT(...) | ||
77 | |||
78 | #define rsprintf snprintf | ||
79 | |||
80 | #define GetDefaultAdapter(padapter) padapter | ||
81 | |||
82 | #define PlatformZeroMemory(ptr, sz) memset(ptr, 0, sz) | ||
83 | |||
84 | #define PlatformProcessHCICommands(...) | ||
85 | #define PlatformTxBTQueuedPackets(...) | ||
86 | #define PlatformIndicateBTACLData(...) (RT_STATUS_SUCCESS) | ||
87 | #define PlatformAcquireSpinLock(padapter, type) | ||
88 | #define PlatformReleaseSpinLock(padapter, type) | ||
89 | |||
90 | #define GET_UNDECORATED_AVERAGE_RSSI(padapter) \ | ||
91 | (GET_HAL_DATA(padapter)->dmpriv.EntryMinUndecoratedSmoothedPWDB) | ||
92 | #define RT_RF_CHANGE_SOURCE u32 | ||
93 | |||
94 | enum { | ||
95 | RT_JOIN_INFRA = 1, | ||
96 | RT_JOIN_IBSS = 2, | ||
97 | RT_START_IBSS = 3, | ||
98 | RT_NO_ACTION = 4, | ||
99 | }; | ||
100 | |||
101 | /* power saving */ | ||
102 | |||
103 | #ifdef __BT_C__ /* COMMOM/BT.c */ | ||
104 | /* ===== Below this line is sync from SD7 driver COMMOM/BT.c ===== */ | ||
105 | |||
106 | static u8 BT_Operation(struct rtw_adapter *padapter) | ||
107 | { | ||
108 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
109 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
110 | |||
111 | if (pBtMgnt->BtOperationOn) | ||
112 | return true; | ||
113 | else | ||
114 | return false; | ||
115 | } | ||
116 | |||
117 | static u8 BT_IsLegalChannel(struct rtw_adapter *padapter, u8 channel) | ||
118 | { | ||
119 | struct rt_channel_info *pChanneList = NULL; | ||
120 | u8 channelLen, i; | ||
121 | |||
122 | pChanneList = padapter->mlmeextpriv.channel_set; | ||
123 | channelLen = padapter->mlmeextpriv.max_chan_nums; | ||
124 | |||
125 | for (i = 0; i < channelLen; i++) { | ||
126 | RTPRINT(FIOCTL, IOCTL_STATE, | ||
127 | ("Check if chnl(%d) in channel plan contains bt target chnl(%d) for BT connection\n", | ||
128 | pChanneList[i].ChannelNum, channel)); | ||
129 | if ((channel == pChanneList[i].ChannelNum) || | ||
130 | (channel == pChanneList[i].ChannelNum + 2)) | ||
131 | return channel; | ||
132 | } | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | void BT_SignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi, u8 *rssi_bt) | ||
137 | { | ||
138 | BTDM_SignalCompensation(padapter, rssi_wifi, rssi_bt); | ||
139 | } | ||
140 | |||
141 | void BT_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType) | ||
142 | { | ||
143 | BTHCI_WifiScanNotify(padapter, scanType); | ||
144 | BTDM_CheckAntSelMode(padapter); | ||
145 | BTDM_WifiScanNotify(padapter, scanType); | ||
146 | } | ||
147 | |||
148 | void BT_WifiAssociateNotify(struct rtw_adapter *padapter, u8 action) | ||
149 | { | ||
150 | /* action : */ | ||
151 | /* true = associate start */ | ||
152 | /* false = associate finished */ | ||
153 | if (action) | ||
154 | BTDM_CheckAntSelMode(padapter); | ||
155 | |||
156 | BTDM_WifiAssociateNotify(padapter, action); | ||
157 | } | ||
158 | |||
159 | void BT_WifiMediaStatusNotify(struct rtw_adapter *padapter, enum rt_media_status mstatus) | ||
160 | { | ||
161 | BTDM_MediaStatusNotify(padapter, mstatus); | ||
162 | } | ||
163 | |||
164 | void BT_SpecialPacketNotify(struct rtw_adapter *padapter) | ||
165 | { | ||
166 | BTDM_ForDhcp(padapter); | ||
167 | } | ||
168 | |||
169 | void BT_HaltProcess(struct rtw_adapter *padapter) | ||
170 | { | ||
171 | BTDM_ForHalt(padapter); | ||
172 | } | ||
173 | |||
174 | void BT_LpsLeave(struct rtw_adapter *padapter) | ||
175 | { | ||
176 | BTDM_LpsLeave(padapter); | ||
177 | } | ||
178 | |||
179 | /* ===== End of sync from SD7 driver COMMOM/BT.c ===== */ | ||
180 | #endif | ||
181 | |||
182 | #ifdef __BT_HANDLEPACKET_C__ /* COMMOM/bt_handlepacket.c */ | ||
183 | /* ===== Below this line is sync from SD7 driver COMMOM/bt_handlepacket.c ===== */ | ||
184 | |||
185 | /* ===== End of sync from SD7 driver COMMOM/bt_handlepacket.c ===== */ | ||
186 | #endif | ||
187 | |||
188 | #ifdef __BT_HCI_C__ /* COMMOM/bt_hci.c */ | ||
189 | |||
190 | #define i64fmt "ll" | ||
191 | #define UINT64_C(v) (v) | ||
192 | |||
193 | #define FillOctetString(_os, _octet, _len) \ | ||
194 | (_os).Octet = (u8 *)(_octet); \ | ||
195 | (_os).Length = (_len); | ||
196 | |||
197 | static enum rt_status PlatformIndicateBTEvent( | ||
198 | struct rtw_adapter *padapter, | ||
199 | void *pEvntData, | ||
200 | u32 dataLen | ||
201 | ) | ||
202 | { | ||
203 | enum rt_status rt_status = RT_STATUS_FAILURE; | ||
204 | |||
205 | RTPRINT(FIOCTL, IOCTL_BT_EVENT_DETAIL, ("BT event start, %d bytes data to Transferred!!\n", dataLen)); | ||
206 | RTPRINT_DATA(FIOCTL, IOCTL_BT_EVENT_DETAIL, "To transfer Hex Data :\n", | ||
207 | pEvntData, dataLen); | ||
208 | |||
209 | BT_EventParse(padapter, pEvntData, dataLen); | ||
210 | |||
211 | printk(KERN_WARNING "%s: Linux has no way to report BT event!!\n", __func__); | ||
212 | |||
213 | RTPRINT(FIOCTL, IOCTL_BT_EVENT_DETAIL, ("BT event end, %s\n", | ||
214 | (rt_status == RT_STATUS_SUCCESS) ? "SUCCESS" : "FAIL")); | ||
215 | |||
216 | return rt_status; | ||
217 | } | ||
218 | |||
219 | /* ===== Below this line is sync from SD7 driver COMMOM/bt_hci.c ===== */ | ||
220 | |||
221 | static u8 bthci_GetLocalChannel(struct rtw_adapter *padapter) | ||
222 | { | ||
223 | return padapter->mlmeextpriv.cur_channel; | ||
224 | } | ||
225 | |||
226 | static u8 bthci_GetCurrentEntryNum(struct rtw_adapter *padapter, u8 PhyHandle) | ||
227 | { | ||
228 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
229 | u8 i; | ||
230 | |||
231 | for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) { | ||
232 | if ((pBTInfo->BtAsocEntry[i].bUsed) && | ||
233 | (pBTInfo->BtAsocEntry[i].PhyLinkCmdData.BtPhyLinkhandle == PhyHandle)) | ||
234 | return i; | ||
235 | } | ||
236 | |||
237 | return 0xFF; | ||
238 | } | ||
239 | |||
240 | static void bthci_DecideBTChannel(struct rtw_adapter *padapter, u8 EntryNum) | ||
241 | { | ||
242 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
243 | struct mlme_priv *pmlmepriv; | ||
244 | struct bt_30info *pBTInfo; | ||
245 | struct bt_mgnt *pBtMgnt; | ||
246 | struct bt_hci_info *pBtHciInfo; | ||
247 | struct chnl_txpower_triple *pTriple_subband = NULL; | ||
248 | struct common_triple *pTriple; | ||
249 | u8 i, j, localchnl, firstRemoteLegalChnlInTriplet = 0; | ||
250 | u8 regulatory_skipLen = 0; | ||
251 | u8 subbandTripletCnt = 0; | ||
252 | |||
253 | pmlmepriv = &padapter->mlmepriv; | ||
254 | pBTInfo = GET_BT_INFO(padapter); | ||
255 | pBtMgnt = &pBTInfo->BtMgnt; | ||
256 | pBtHciInfo = &pBTInfo->BtHciInfo; | ||
257 | |||
258 | pBtMgnt->CheckChnlIsSuit = true; | ||
259 | localchnl = bthci_GetLocalChannel(padapter); | ||
260 | |||
261 | pTriple = (struct common_triple *) | ||
262 | &pBtHciInfo->BTPreChnllist[COUNTRY_STR_LEN]; | ||
263 | |||
264 | /* contains country string, len is 3 */ | ||
265 | for (i = 0; i < (pBtHciInfo->BtPreChnlListLen-COUNTRY_STR_LEN); i += 3, pTriple++) { | ||
266 | /* */ | ||
267 | /* check every triplet, an triplet may be */ | ||
268 | /* regulatory extension identifier or sub-band triplet */ | ||
269 | /* */ | ||
270 | if (pTriple->byte_1st == 0xc9) { | ||
271 | /* Regulatory Extension Identifier, skip it */ | ||
272 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), | ||
273 | ("Find Regulatory ID, regulatory class = %d\n", pTriple->byte_2nd)); | ||
274 | regulatory_skipLen += 3; | ||
275 | pTriple_subband = NULL; | ||
276 | continue; | ||
277 | } else { /* Sub-band triplet */ | ||
278 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Find Sub-band triplet \n")); | ||
279 | subbandTripletCnt++; | ||
280 | pTriple_subband = (struct chnl_txpower_triple *)pTriple; | ||
281 | /* if remote first legal channel not found, then find first remote channel */ | ||
282 | /* and it's legal for our channel plan. */ | ||
283 | |||
284 | /* search the sub-band triplet and find if remote channel is legal to our channel plan. */ | ||
285 | for (j = pTriple_subband->FirstChnl; j < (pTriple_subband->FirstChnl+pTriple_subband->NumChnls); j++) { | ||
286 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), (" Check if chnl(%d) is legal\n", j)); | ||
287 | if (BT_IsLegalChannel(padapter, j)) { | ||
288 | /* remote channel is legal for our channel plan. */ | ||
289 | firstRemoteLegalChnlInTriplet = j; | ||
290 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), | ||
291 | ("Find first remote legal channel : %d\n", | ||
292 | firstRemoteLegalChnlInTriplet)); | ||
293 | |||
294 | /* If we find a remote legal channel in the sub-band triplet */ | ||
295 | /* and only BT connection is established(local not connect to any AP or IBSS), */ | ||
296 | /* then we just switch channel to remote channel. */ | ||
297 | if (!(check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_ADHOC_STATE|WIFI_AP_STATE) || | ||
298 | BTHCI_HsConnectionEstablished(padapter))) { | ||
299 | pBtMgnt->BTChannel = firstRemoteLegalChnlInTriplet; | ||
300 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Remote legal channel (%d) is selected, Local not connect to any!!\n", pBtMgnt->BTChannel)); | ||
301 | return; | ||
302 | } else { | ||
303 | if ((localchnl >= firstRemoteLegalChnlInTriplet) && | ||
304 | (localchnl < (pTriple_subband->FirstChnl+pTriple_subband->NumChnls))) { | ||
305 | pBtMgnt->BTChannel = localchnl; | ||
306 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Local channel (%d) is selected, wifi or BT connection exists\n", pBtMgnt->BTChannel)); | ||
307 | return; | ||
308 | } | ||
309 | } | ||
310 | break; | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | } | ||
315 | |||
316 | if (subbandTripletCnt) { | ||
317 | /* if any preferred channel triplet exists */ | ||
318 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("There are %d sub band triplet exists, ", subbandTripletCnt)); | ||
319 | if (firstRemoteLegalChnlInTriplet == 0) { | ||
320 | /* no legal channel is found, reject the connection. */ | ||
321 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("no legal channel is found!!\n")); | ||
322 | } else { | ||
323 | /* Remote Legal channel is found but not match to local */ | ||
324 | /* wifi connection exists), so reject the connection. */ | ||
325 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), | ||
326 | ("Remote Legal channel is found but not match to local(wifi connection exists)!!\n")); | ||
327 | } | ||
328 | pBtMgnt->CheckChnlIsSuit = false; | ||
329 | } else { | ||
330 | /* There are not any preferred channel triplet exists */ | ||
331 | /* Use current legal channel as the bt channel. */ | ||
332 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("No sub band triplet exists!!\n")); | ||
333 | } | ||
334 | pBtMgnt->BTChannel = localchnl; | ||
335 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Local channel (%d) is selected!!\n", pBtMgnt->BTChannel)); | ||
336 | } | ||
337 | |||
338 | /* Success:return true */ | ||
339 | /* Fail:return false */ | ||
340 | static u8 bthci_GetAssocInfo(struct rtw_adapter *padapter, u8 EntryNum) | ||
341 | { | ||
342 | struct bt_30info *pBTInfo; | ||
343 | struct bt_hci_info *pBtHciInfo; | ||
344 | u8 tempBuf[256]; | ||
345 | u8 i = 0; | ||
346 | u8 BaseMemoryShift = 0; | ||
347 | u16 TotalLen = 0; | ||
348 | struct amp_assoc_structure *pAmpAsoc; | ||
349 | |||
350 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("GetAssocInfo start\n")); | ||
351 | pBTInfo = GET_BT_INFO(padapter); | ||
352 | pBtHciInfo = &pBTInfo->BtHciInfo; | ||
353 | |||
354 | if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar == 0) { | ||
355 | if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocRemLen < (MAX_AMP_ASSOC_FRAG_LEN)) | ||
356 | TotalLen = pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocRemLen; | ||
357 | else if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocRemLen == (MAX_AMP_ASSOC_FRAG_LEN)) | ||
358 | TotalLen = MAX_AMP_ASSOC_FRAG_LEN; | ||
359 | } else if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar > 0) | ||
360 | TotalLen = pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar; | ||
361 | |||
362 | while ((pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar >= BaseMemoryShift) || TotalLen > BaseMemoryShift) { | ||
363 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("GetAssocInfo, TotalLen =%d, BaseMemoryShift =%d\n", TotalLen, BaseMemoryShift)); | ||
364 | memcpy(tempBuf, | ||
365 | (u8 *)pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocfragment+BaseMemoryShift, | ||
366 | TotalLen-BaseMemoryShift); | ||
367 | RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_DETAIL, "GetAssocInfo :\n", | ||
368 | tempBuf, TotalLen-BaseMemoryShift); | ||
369 | |||
370 | pAmpAsoc = (struct amp_assoc_structure *)tempBuf; | ||
371 | pAmpAsoc->Length = le16_to_cpu(pAmpAsoc->Length); | ||
372 | BaseMemoryShift += 3 + pAmpAsoc->Length; | ||
373 | |||
374 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("TypeID = 0x%x, ", pAmpAsoc->TypeID)); | ||
375 | RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD, "Hex Data: \n", pAmpAsoc->Data, pAmpAsoc->Length); | ||
376 | switch (pAmpAsoc->TypeID) { | ||
377 | case AMP_MAC_ADDR: | ||
378 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> AMP_MAC_ADDR\n")); | ||
379 | if (pAmpAsoc->Length > 6) | ||
380 | return false; | ||
381 | memcpy(pBTInfo->BtAsocEntry[EntryNum].BTRemoteMACAddr, pAmpAsoc->Data, 6); | ||
382 | RTPRINT_ADDR(FIOCTL, IOCTL_BT_HCICMD, ("Remote Mac address \n"), pBTInfo->BtAsocEntry[EntryNum].BTRemoteMACAddr); | ||
383 | break; | ||
384 | case AMP_PREFERRED_CHANNEL_LIST: | ||
385 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> AMP_PREFERRED_CHANNEL_LIST\n")); | ||
386 | pBtHciInfo->BtPreChnlListLen = pAmpAsoc->Length; | ||
387 | memcpy(pBtHciInfo->BTPreChnllist, | ||
388 | pAmpAsoc->Data, | ||
389 | pBtHciInfo->BtPreChnlListLen); | ||
390 | RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD, "Preferred channel list : \n", pBtHciInfo->BTPreChnllist, pBtHciInfo->BtPreChnlListLen); | ||
391 | bthci_DecideBTChannel(padapter, EntryNum); | ||
392 | break; | ||
393 | case AMP_CONNECTED_CHANNEL: | ||
394 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> AMP_CONNECTED_CHANNEL\n")); | ||
395 | pBtHciInfo->BTConnectChnlListLen = pAmpAsoc->Length; | ||
396 | memcpy(pBtHciInfo->BTConnectChnllist, | ||
397 | pAmpAsoc->Data, | ||
398 | pBtHciInfo->BTConnectChnlListLen); | ||
399 | break; | ||
400 | case AMP_80211_PAL_CAP_LIST: | ||
401 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> AMP_80211_PAL_CAP_LIST\n")); | ||
402 | pBTInfo->BtAsocEntry[EntryNum].BTCapability = *(u32 *)(pAmpAsoc->Data); | ||
403 | if (pBTInfo->BtAsocEntry[EntryNum].BTCapability & 0x00000001) { | ||
404 | /* TODO: */ | ||
405 | |||
406 | /* Signifies PAL capable of utilizing received activity reports. */ | ||
407 | } | ||
408 | if (pBTInfo->BtAsocEntry[EntryNum].BTCapability & 0x00000002) { | ||
409 | /* TODO: */ | ||
410 | /* Signifies PAL is capable of utilizing scheduling information received in an activity reports. */ | ||
411 | } | ||
412 | break; | ||
413 | case AMP_80211_PAL_VISION: | ||
414 | pBtHciInfo->BTPalVersion = *(u8 *)(pAmpAsoc->Data); | ||
415 | pBtHciInfo->BTPalCompanyID = *(u16 *)(((u8 *)(pAmpAsoc->Data))+1); | ||
416 | pBtHciInfo->BTPalsubversion = *(u16 *)(((u8 *)(pAmpAsoc->Data))+3); | ||
417 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("==> AMP_80211_PAL_VISION PalVersion 0x%x, PalCompanyID 0x%x, Palsubversion 0x%x\n", | ||
418 | pBtHciInfo->BTPalVersion, | ||
419 | pBtHciInfo->BTPalCompanyID, | ||
420 | pBtHciInfo->BTPalsubversion)); | ||
421 | break; | ||
422 | default: | ||
423 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> Unsupport TypeID !!\n")); | ||
424 | break; | ||
425 | } | ||
426 | i++; | ||
427 | } | ||
428 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("GetAssocInfo end\n")); | ||
429 | |||
430 | return true; | ||
431 | } | ||
432 | |||
433 | static u8 bthci_AddEntry(struct rtw_adapter *padapter) | ||
434 | { | ||
435 | struct bt_30info *pBTInfo; | ||
436 | struct bt_mgnt *pBtMgnt; | ||
437 | u8 i; | ||
438 | |||
439 | pBTInfo = GET_BT_INFO(padapter); | ||
440 | pBtMgnt = &pBTInfo->BtMgnt; | ||
441 | |||
442 | for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) { | ||
443 | if (pBTInfo->BtAsocEntry[i].bUsed == false) { | ||
444 | pBTInfo->BtAsocEntry[i].bUsed = true; | ||
445 | pBtMgnt->CurrentConnectEntryNum = i; | ||
446 | break; | ||
447 | } | ||
448 | } | ||
449 | |||
450 | if (i == MAX_BT_ASOC_ENTRY_NUM) { | ||
451 | RTPRINT(FIOCTL, IOCTL_STATE, ("bthci_AddEntry(), Add entry fail!!\n")); | ||
452 | return false; | ||
453 | } | ||
454 | return true; | ||
455 | } | ||
456 | |||
457 | static u8 bthci_DiscardTxPackets(struct rtw_adapter *padapter, u16 LLH) | ||
458 | { | ||
459 | return false; | ||
460 | } | ||
461 | |||
462 | static u8 | ||
463 | bthci_CheckLogLinkBehavior( | ||
464 | struct rtw_adapter *padapter, | ||
465 | struct hci_flow_spec TxFlowSpec | ||
466 | ) | ||
467 | { | ||
468 | u8 ID = TxFlowSpec.Identifier; | ||
469 | u8 ServiceType = TxFlowSpec.ServiceType; | ||
470 | u16 MaxSDUSize = TxFlowSpec.MaximumSDUSize; | ||
471 | u32 SDUInterArrivatime = TxFlowSpec.SDUInterArrivalTime; | ||
472 | u8 match = false; | ||
473 | |||
474 | switch (ID) { | ||
475 | case 1: | ||
476 | if (ServiceType == BT_LL_BE) { | ||
477 | match = true; | ||
478 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = TX best effort flowspec\n")); | ||
479 | } else if ((ServiceType == BT_LL_GU) && (MaxSDUSize == 0xffff)) { | ||
480 | match = true; | ||
481 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = RX guaranteed latency flowspec\n")); | ||
482 | } else if ((ServiceType == BT_LL_GU) && (MaxSDUSize == 2500)) { | ||
483 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = RX guaranteed Large latency flowspec\n")); | ||
484 | } | ||
485 | break; | ||
486 | case 2: | ||
487 | if (ServiceType == BT_LL_BE) { | ||
488 | match = true; | ||
489 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = RX best effort flowspec\n")); | ||
490 | |||
491 | } | ||
492 | break; | ||
493 | case 3: | ||
494 | if ((ServiceType == BT_LL_GU) && (MaxSDUSize == 1492)) { | ||
495 | match = true; | ||
496 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = TX guaranteed latency flowspec\n")); | ||
497 | } else if ((ServiceType == BT_LL_GU) && (MaxSDUSize == 2500)) { | ||
498 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = TX guaranteed Large latency flowspec\n")); | ||
499 | } | ||
500 | break; | ||
501 | case 4: | ||
502 | if (ServiceType == BT_LL_BE) { | ||
503 | if ((SDUInterArrivatime == 0xffffffff) && (ServiceType == BT_LL_BE) && (MaxSDUSize == 1492)) { | ||
504 | match = true; | ||
505 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = TX/RX aggregated best effort flowspec\n")); | ||
506 | } | ||
507 | } else if (ServiceType == BT_LL_GU) { | ||
508 | if (SDUInterArrivatime == 100) { | ||
509 | match = true; | ||
510 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = TX/RX guaranteed bandwidth flowspec\n")); | ||
511 | } | ||
512 | } | ||
513 | break; | ||
514 | default: | ||
515 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type = Unknow Type !!!!!!!!\n")); | ||
516 | break; | ||
517 | } | ||
518 | |||
519 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), | ||
520 | ("ID = 0x%x, ServiceType = 0x%x, MaximumSDUSize = 0x%x, SDUInterArrivalTime = 0x%x, AccessLatency = 0x%x, FlushTimeout = 0x%x\n", | ||
521 | TxFlowSpec.Identifier, TxFlowSpec.ServiceType, MaxSDUSize, | ||
522 | SDUInterArrivatime, TxFlowSpec.AccessLatency, TxFlowSpec.FlushTimeout)); | ||
523 | return match; | ||
524 | } | ||
525 | |||
526 | static u16 bthci_AssocMACAddr(struct rtw_adapter *padapter, void *pbuf) | ||
527 | { | ||
528 | struct amp_assoc_structure *pAssoStrc = (struct amp_assoc_structure *)pbuf; | ||
529 | pAssoStrc->TypeID = AMP_MAC_ADDR; | ||
530 | pAssoStrc->Length = 0x06; | ||
531 | memcpy(&pAssoStrc->Data[0], padapter->eeprompriv.mac_addr, 6); | ||
532 | RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), | ||
533 | ("AssocMACAddr : \n"), pAssoStrc, pAssoStrc->Length+3); | ||
534 | |||
535 | return pAssoStrc->Length + 3; | ||
536 | } | ||
537 | |||
538 | static u16 | ||
539 | bthci_PALCapabilities( | ||
540 | struct rtw_adapter *padapter, | ||
541 | void *pbuf | ||
542 | ) | ||
543 | { | ||
544 | struct amp_assoc_structure *pAssoStrc = (struct amp_assoc_structure *)pbuf; | ||
545 | |||
546 | pAssoStrc->TypeID = AMP_80211_PAL_CAP_LIST; | ||
547 | pAssoStrc->Length = 0x04; | ||
548 | |||
549 | pAssoStrc->Data[0] = 0x00; | ||
550 | pAssoStrc->Data[1] = 0x00; | ||
551 | |||
552 | RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("PALCapabilities:\n"), pAssoStrc, pAssoStrc->Length+3); | ||
553 | RTPRINT(FIOCTL, IOCTL_BT_LOGO, ("PALCapabilities \n")); | ||
554 | |||
555 | RTPRINT(FIOCTL, IOCTL_BT_LOGO, (" TypeID = 0x%x,\n Length = 0x%x,\n Content = 0x0000\n", | ||
556 | pAssoStrc->TypeID, | ||
557 | pAssoStrc->Length)); | ||
558 | |||
559 | return pAssoStrc->Length + 3; | ||
560 | } | ||
561 | |||
562 | static u16 bthci_AssocPreferredChannelList(struct rtw_adapter *padapter, | ||
563 | void *pbuf, u8 EntryNum) | ||
564 | { | ||
565 | struct bt_30info *pBTInfo; | ||
566 | struct amp_assoc_structure *pAssoStrc; | ||
567 | struct amp_pref_chnl_regulatory *pReg; | ||
568 | struct chnl_txpower_triple *pTriple; | ||
569 | char ctrString[3] = {'X', 'X', 'X'}; | ||
570 | u32 len = 0; | ||
571 | u8 preferredChnl; | ||
572 | |||
573 | pBTInfo = GET_BT_INFO(padapter); | ||
574 | pAssoStrc = (struct amp_assoc_structure *)pbuf; | ||
575 | pReg = (struct amp_pref_chnl_regulatory *)&pAssoStrc->Data[3]; | ||
576 | |||
577 | preferredChnl = bthci_GetLocalChannel(padapter); | ||
578 | pAssoStrc->TypeID = AMP_PREFERRED_CHANNEL_LIST; | ||
579 | |||
580 | /* locale unknown */ | ||
581 | memcpy(&pAssoStrc->Data[0], &ctrString[0], 3); | ||
582 | pReg->reXId = 201; | ||
583 | pReg->regulatoryClass = 254; | ||
584 | pReg->coverageClass = 0; | ||
585 | len += 6; | ||
586 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD | IOCTL_BT_LOGO), ("PREFERRED_CHNL_LIST\n")); | ||
587 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD | IOCTL_BT_LOGO), ("XXX, 201, 254, 0\n")); | ||
588 | /* at the following, chnl 1~11 should be contained */ | ||
589 | pTriple = (struct chnl_txpower_triple *)&pAssoStrc->Data[len]; | ||
590 | |||
591 | /* (1) if any wifi or bt HS connection exists */ | ||
592 | if ((pBTInfo->BtAsocEntry[EntryNum].AMPRole == AMP_BTAP_CREATOR) || | ||
593 | (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE | | ||
594 | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | | ||
595 | WIFI_AP_STATE)) || | ||
596 | BTHCI_HsConnectionEstablished(padapter)) { | ||
597 | pTriple->FirstChnl = preferredChnl; | ||
598 | pTriple->NumChnls = 1; | ||
599 | pTriple->MaxTxPowerInDbm = 20; | ||
600 | len += 3; | ||
601 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD | IOCTL_BT_LOGO), ("First Channel = %d, Channel Num = %d, MaxDbm = %d\n", | ||
602 | pTriple->FirstChnl, | ||
603 | pTriple->NumChnls, | ||
604 | pTriple->MaxTxPowerInDbm)); | ||
605 | } | ||
606 | |||
607 | pAssoStrc->Length = (u16)len; | ||
608 | RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD, ("AssocPreferredChannelList : \n"), pAssoStrc, pAssoStrc->Length+3); | ||
609 | |||
610 | return pAssoStrc->Length + 3; | ||
611 | } | ||
612 | |||
613 | static u16 bthci_AssocPALVer(struct rtw_adapter *padapter, void *pbuf) | ||
614 | { | ||
615 | struct amp_assoc_structure *pAssoStrc = (struct amp_assoc_structure *)pbuf; | ||
616 | u8 *pu1Tmp; | ||
617 | u16 *pu2Tmp; | ||
618 | |||
619 | pAssoStrc->TypeID = AMP_80211_PAL_VISION; | ||
620 | pAssoStrc->Length = 0x5; | ||
621 | pu1Tmp = &pAssoStrc->Data[0]; | ||
622 | *pu1Tmp = 0x1; /* PAL Version */ | ||
623 | pu2Tmp = (u16 *)&pAssoStrc->Data[1]; | ||
624 | *pu2Tmp = 0x5D; /* SIG Company identifier of 802.11 PAL vendor */ | ||
625 | pu2Tmp = (u16 *)&pAssoStrc->Data[3]; | ||
626 | *pu2Tmp = 0x1; /* PAL Sub-version specifier */ | ||
627 | |||
628 | RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("AssocPALVer : \n"), pAssoStrc, pAssoStrc->Length+3); | ||
629 | RTPRINT(FIOCTL, IOCTL_BT_LOGO, ("AssocPALVer \n")); | ||
630 | |||
631 | RTPRINT(FIOCTL, IOCTL_BT_LOGO, (" TypeID = 0x%x,\n Length = 0x%x,\n PAL Version = 0x01,\n PAL vendor = 0x01,\n PAL Sub-version specifier = 0x01\n", | ||
632 | pAssoStrc->TypeID, | ||
633 | pAssoStrc->Length)); | ||
634 | return pAssoStrc->Length + 3; | ||
635 | } | ||
636 | |||
637 | static u8 bthci_CheckRfStateBeforeConnect(struct rtw_adapter *padapter) | ||
638 | { | ||
639 | struct bt_30info *pBTInfo; | ||
640 | enum rt_rf_power_state RfState; | ||
641 | |||
642 | pBTInfo = GET_BT_INFO(padapter); | ||
643 | |||
644 | RfState = padapter->pwrctrlpriv.rf_pwrstate; | ||
645 | |||
646 | if (RfState != rf_on) { | ||
647 | mod_timer(&pBTInfo->BTPsDisableTimer, | ||
648 | jiffies + msecs_to_jiffies(50)); | ||
649 | return false; | ||
650 | } | ||
651 | return true; | ||
652 | } | ||
653 | |||
654 | static void bthci_ResponderStartToScan(struct rtw_adapter *padapter) | ||
655 | { | ||
656 | } | ||
657 | |||
658 | static u8 bthci_PhyLinkConnectionInProgress(struct rtw_adapter *padapter, u8 PhyLinkHandle) | ||
659 | { | ||
660 | struct bt_30info *pBTInfo; | ||
661 | struct bt_mgnt *pBtMgnt; | ||
662 | |||
663 | pBTInfo = GET_BT_INFO(padapter); | ||
664 | pBtMgnt = &pBTInfo->BtMgnt; | ||
665 | |||
666 | if (pBtMgnt->bPhyLinkInProgress && | ||
667 | (pBtMgnt->BtCurrentPhyLinkhandle == PhyLinkHandle)) | ||
668 | return true; | ||
669 | return false; | ||
670 | } | ||
671 | |||
672 | static void bthci_ResetFlowSpec(struct rtw_adapter *padapter, u8 EntryNum, u8 index) | ||
673 | { | ||
674 | struct bt_30info *pBTinfo; | ||
675 | |||
676 | pBTinfo = GET_BT_INFO(padapter); | ||
677 | |||
678 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].BtLogLinkhandle = 0; | ||
679 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].BtPhyLinkhandle = 0; | ||
680 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].bLLCompleteEventIsSet = false; | ||
681 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].bLLCancelCMDIsSetandComplete = false; | ||
682 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].BtTxFlowSpecID = 0; | ||
683 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].TxPacketCount = 0; | ||
684 | |||
685 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.Identifier = 0x01; | ||
686 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.ServiceType = SERVICE_BEST_EFFORT; | ||
687 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.MaximumSDUSize = 0xffff; | ||
688 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.SDUInterArrivalTime = 0xffffffff; | ||
689 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.AccessLatency = 0xffffffff; | ||
690 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.FlushTimeout = 0xffffffff; | ||
691 | |||
692 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.Identifier = 0x01; | ||
693 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.ServiceType = SERVICE_BEST_EFFORT; | ||
694 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.MaximumSDUSize = 0xffff; | ||
695 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.SDUInterArrivalTime = 0xffffffff; | ||
696 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.AccessLatency = 0xffffffff; | ||
697 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.FlushTimeout = 0xffffffff; | ||
698 | } | ||
699 | |||
700 | static void bthci_ResetEntry(struct rtw_adapter *padapter, u8 EntryNum) | ||
701 | { | ||
702 | struct bt_30info *pBTinfo; | ||
703 | struct bt_mgnt *pBtMgnt; | ||
704 | u8 j; | ||
705 | |||
706 | pBTinfo = GET_BT_INFO(padapter); | ||
707 | pBtMgnt = &pBTinfo->BtMgnt; | ||
708 | |||
709 | pBTinfo->BtAsocEntry[EntryNum].bUsed = false; | ||
710 | pBTinfo->BtAsocEntry[EntryNum].BtCurrentState = HCI_STATE_DISCONNECTED; | ||
711 | pBTinfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTED; | ||
712 | |||
713 | pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocRemLen = 0; | ||
714 | pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.BtPhyLinkhandle = 0; | ||
715 | if (pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocfragment != NULL) | ||
716 | memset(pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocfragment, 0, TOTAL_ALLOCIATE_ASSOC_LEN); | ||
717 | pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar = 0; | ||
718 | |||
719 | pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyType = 0; | ||
720 | pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle = 0; | ||
721 | memset(pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKey, 0, | ||
722 | pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen); | ||
723 | pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen = 0; | ||
724 | |||
725 | /* 0x640; 0.625ms*1600 = 1000ms, 0.625ms*16000 = 10000ms */ | ||
726 | pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.LinkSuperversionTimeout = 0x3e80; | ||
727 | |||
728 | pBTinfo->BtAsocEntry[EntryNum].AMPRole = AMP_BTAP_NONE; | ||
729 | |||
730 | pBTinfo->BtAsocEntry[EntryNum].mAssoc = false; | ||
731 | pBTinfo->BtAsocEntry[EntryNum].b4waySuccess = false; | ||
732 | |||
733 | /* Reset BT WPA */ | ||
734 | pBTinfo->BtAsocEntry[EntryNum].KeyReplayCounter = 0; | ||
735 | pBTinfo->BtAsocEntry[EntryNum].BTWPAAuthState = STATE_WPA_AUTH_UNINITIALIZED; | ||
736 | |||
737 | pBTinfo->BtAsocEntry[EntryNum].bSendSupervisionPacket = false; | ||
738 | pBTinfo->BtAsocEntry[EntryNum].NoRxPktCnt = 0; | ||
739 | pBTinfo->BtAsocEntry[EntryNum].ShortRangeMode = 0; | ||
740 | pBTinfo->BtAsocEntry[EntryNum].rxSuvpPktCnt = 0; | ||
741 | |||
742 | for (j = 0; j < MAX_LOGICAL_LINK_NUM; j++) | ||
743 | bthci_ResetFlowSpec(padapter, EntryNum, j); | ||
744 | |||
745 | pBtMgnt->BTAuthCount = 0; | ||
746 | pBtMgnt->BTAsocCount = 0; | ||
747 | pBtMgnt->BTCurrentConnectType = BT_DISCONNECT; | ||
748 | pBtMgnt->BTReceiveConnectPkt = BT_DISCONNECT; | ||
749 | |||
750 | HALBT_RemoveKey(padapter, EntryNum); | ||
751 | } | ||
752 | |||
753 | static void bthci_RemoveEntryByEntryNum(struct rtw_adapter *padapter, u8 EntryNum) | ||
754 | { | ||
755 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
756 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
757 | |||
758 | bthci_ResetEntry(padapter, EntryNum); | ||
759 | |||
760 | if (pBtMgnt->CurrentBTConnectionCnt > 0) | ||
761 | pBtMgnt->CurrentBTConnectionCnt--; | ||
762 | |||
763 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], CurrentBTConnectionCnt = %d!!\n", | ||
764 | pBtMgnt->CurrentBTConnectionCnt)); | ||
765 | |||
766 | if (pBtMgnt->CurrentBTConnectionCnt > 0) { | ||
767 | pBtMgnt->BtOperationOn = true; | ||
768 | } else { | ||
769 | pBtMgnt->BtOperationOn = false; | ||
770 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], Bt Operation OFF!!\n")); | ||
771 | } | ||
772 | |||
773 | if (!pBtMgnt->BtOperationOn) { | ||
774 | del_timer_sync(&pBTInfo->BTHCIDiscardAclDataTimer); | ||
775 | del_timer_sync(&pBTInfo->BTBeaconTimer); | ||
776 | pBtMgnt->bStartSendSupervisionPkt = false; | ||
777 | } | ||
778 | } | ||
779 | |||
780 | static u8 | ||
781 | bthci_CommandCompleteHeader( | ||
782 | u8 *pbuf, | ||
783 | u16 OGF, | ||
784 | u16 OCF, | ||
785 | enum hci_status status | ||
786 | ) | ||
787 | { | ||
788 | struct packet_irp_hcievent_data *PPacketIrpEvent = (struct packet_irp_hcievent_data *)pbuf; | ||
789 | u8 NumHCI_Comm = 0x1; | ||
790 | |||
791 | PPacketIrpEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE; | ||
792 | PPacketIrpEvent->Data[0] = NumHCI_Comm; /* packet # */ | ||
793 | PPacketIrpEvent->Data[1] = HCIOPCODELOW(OCF, OGF); | ||
794 | PPacketIrpEvent->Data[2] = HCIOPCODEHIGHT(OCF, OGF); | ||
795 | |||
796 | if (OGF == OGF_EXTENSION) { | ||
797 | if (OCF == HCI_SET_RSSI_VALUE) { | ||
798 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT_PERIODICAL), | ||
799 | ("[BT event], CommandComplete, Num_HCI_Comm = 0x%x, Opcode = 0x%02x%02x, status = 0x%x, OGF = 0x%x, OCF = 0x%x\n", | ||
800 | NumHCI_Comm, (HCIOPCODEHIGHT(OCF, OGF)), (HCIOPCODELOW(OCF, OGF)), status, OGF, OCF)); | ||
801 | } else { | ||
802 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_EXT), | ||
803 | ("[BT event], CommandComplete, Num_HCI_Comm = 0x%x, Opcode = 0x%02x%02x, status = 0x%x, OGF = 0x%x, OCF = 0x%x\n", | ||
804 | NumHCI_Comm, (HCIOPCODEHIGHT(OCF, OGF)), (HCIOPCODELOW(OCF, OGF)), status, OGF, OCF)); | ||
805 | } | ||
806 | } else { | ||
807 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), | ||
808 | ("[BT event], CommandComplete, Num_HCI_Comm = 0x%x, Opcode = 0x%02x%02x, status = 0x%x, OGF = 0x%x, OCF = 0x%x\n", | ||
809 | NumHCI_Comm, (HCIOPCODEHIGHT(OCF, OGF)), (HCIOPCODELOW(OCF, OGF)), status, OGF, OCF)); | ||
810 | } | ||
811 | return 3; | ||
812 | } | ||
813 | |||
814 | static u8 bthci_ExtensionEventHeaderRtk(u8 *pbuf, u8 extensionEvent) | ||
815 | { | ||
816 | struct packet_irp_hcievent_data *PPacketIrpEvent = (struct packet_irp_hcievent_data *)pbuf; | ||
817 | PPacketIrpEvent->EventCode = HCI_EVENT_EXTENSION_RTK; | ||
818 | PPacketIrpEvent->Data[0] = extensionEvent; /* extension event code */ | ||
819 | |||
820 | return 1; | ||
821 | } | ||
822 | |||
823 | static enum rt_status | ||
824 | bthci_IndicateEvent( | ||
825 | struct rtw_adapter *padapter, | ||
826 | void *pEvntData, | ||
827 | u32 dataLen | ||
828 | ) | ||
829 | { | ||
830 | enum rt_status rt_status; | ||
831 | |||
832 | rt_status = PlatformIndicateBTEvent(padapter, pEvntData, dataLen); | ||
833 | |||
834 | return rt_status; | ||
835 | } | ||
836 | |||
837 | static void | ||
838 | bthci_EventWriteRemoteAmpAssoc( | ||
839 | struct rtw_adapter *padapter, | ||
840 | enum hci_status status, | ||
841 | u8 PLHandle | ||
842 | ) | ||
843 | { | ||
844 | u8 localBuf[TmpLocalBufSize] = ""; | ||
845 | u8 *pRetPar; | ||
846 | u8 len = 0; | ||
847 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
848 | |||
849 | PlatformZeroMemory(&localBuf[0], TmpLocalBufSize); | ||
850 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
851 | |||
852 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
853 | OGF_STATUS_PARAMETERS, | ||
854 | HCI_WRITE_REMOTE_AMP_ASSOC, | ||
855 | status); | ||
856 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("PhyLinkHandle = 0x%x, status = %d\n", PLHandle, status)); | ||
857 | /* Return parameters starts from here */ | ||
858 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
859 | pRetPar[0] = status; /* status */ | ||
860 | pRetPar[1] = PLHandle; | ||
861 | len += 2; | ||
862 | PPacketIrpEvent->Length = len; | ||
863 | |||
864 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
865 | } | ||
866 | |||
867 | static void | ||
868 | bthci_EventEnhancedFlushComplete( | ||
869 | struct rtw_adapter *padapter, | ||
870 | u16 LLH | ||
871 | ) | ||
872 | { | ||
873 | u8 localBuf[4] = ""; | ||
874 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
875 | |||
876 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("EventEnhancedFlushComplete, LLH = 0x%x\n", LLH)); | ||
877 | |||
878 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
879 | PPacketIrpEvent->EventCode = HCI_EVENT_ENHANCED_FLUSH_COMPLETE; | ||
880 | PPacketIrpEvent->Length = 2; | ||
881 | /* Logical link handle */ | ||
882 | PPacketIrpEvent->Data[0] = TWOBYTE_LOWBYTE(LLH); | ||
883 | PPacketIrpEvent->Data[1] = TWOBYTE_HIGHTBYTE(LLH); | ||
884 | |||
885 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 4); | ||
886 | } | ||
887 | |||
888 | static void | ||
889 | bthci_EventShortRangeModeChangeComplete( | ||
890 | struct rtw_adapter *padapter, | ||
891 | enum hci_status HciStatus, | ||
892 | u8 ShortRangeState, | ||
893 | u8 EntryNum | ||
894 | ) | ||
895 | { | ||
896 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
897 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
898 | u8 localBuf[5] = ""; | ||
899 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
900 | |||
901 | if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_SHORT_RANGE_MODE_CHANGE_COMPLETE)) { | ||
902 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, | ||
903 | ("[BT event], Short Range Mode Change Complete, Ignore to send this event due to event mask page 2\n")); | ||
904 | return; | ||
905 | } | ||
906 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Short Range Mode Change Complete, Status = %d\n , PLH = 0x%x\n, Short_Range_Mode_State = 0x%x\n", | ||
907 | HciStatus, pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle, ShortRangeState)); | ||
908 | |||
909 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
910 | PPacketIrpEvent->EventCode = HCI_EVENT_SHORT_RANGE_MODE_CHANGE_COMPLETE; | ||
911 | PPacketIrpEvent->Length = 3; | ||
912 | PPacketIrpEvent->Data[0] = HciStatus; | ||
913 | PPacketIrpEvent->Data[1] = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle; | ||
914 | PPacketIrpEvent->Data[2] = ShortRangeState; | ||
915 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 5); | ||
916 | } | ||
917 | |||
918 | static void bthci_EventSendFlowSpecModifyComplete(struct rtw_adapter *padapter, | ||
919 | enum hci_status HciStatus, | ||
920 | u16 logicHandle) | ||
921 | { | ||
922 | u8 localBuf[5] = ""; | ||
923 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
924 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
925 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
926 | |||
927 | if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_FLOW_SPEC_MODIFY_COMPLETE)) { | ||
928 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), | ||
929 | ("[BT event], Flow Spec Modify Complete, Ignore to send this event due to event mask page 2\n")); | ||
930 | return; | ||
931 | } | ||
932 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), | ||
933 | ("[BT event], Flow Spec Modify Complete, status = 0x%x, LLH = 0x%x\n", HciStatus, logicHandle)); | ||
934 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
935 | PPacketIrpEvent->EventCode = HCI_EVENT_FLOW_SPEC_MODIFY_COMPLETE; | ||
936 | PPacketIrpEvent->Length = 3; | ||
937 | |||
938 | PPacketIrpEvent->Data[0] = HciStatus; | ||
939 | /* Logical link handle */ | ||
940 | PPacketIrpEvent->Data[1] = TWOBYTE_LOWBYTE(logicHandle); | ||
941 | PPacketIrpEvent->Data[2] = TWOBYTE_HIGHTBYTE(logicHandle); | ||
942 | |||
943 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 5); | ||
944 | } | ||
945 | |||
946 | static void | ||
947 | bthci_EventExtWifiScanNotify( | ||
948 | struct rtw_adapter *padapter, | ||
949 | u8 scanType | ||
950 | ) | ||
951 | { | ||
952 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
953 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
954 | u8 len = 0; | ||
955 | u8 localBuf[7] = ""; | ||
956 | u8 *pRetPar; | ||
957 | u8 *pu1Temp; | ||
958 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
959 | |||
960 | if (!pBtMgnt->BtOperationOn) | ||
961 | return; | ||
962 | |||
963 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
964 | |||
965 | len += bthci_ExtensionEventHeaderRtk(&localBuf[0], HCI_EVENT_EXT_WIFI_SCAN_NOTIFY); | ||
966 | |||
967 | /* Return parameters starts from here */ | ||
968 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
969 | pu1Temp = (u8 *)&pRetPar[0]; | ||
970 | *pu1Temp = scanType; | ||
971 | len += 1; | ||
972 | |||
973 | PPacketIrpEvent->Length = len; | ||
974 | |||
975 | if (bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2) == RT_STATUS_SUCCESS) { | ||
976 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Wifi scan notify, scan type = %d\n", | ||
977 | scanType)); | ||
978 | } | ||
979 | } | ||
980 | |||
981 | static void | ||
982 | bthci_EventAMPReceiverReport( | ||
983 | struct rtw_adapter *padapter, | ||
984 | u8 Reason | ||
985 | ) | ||
986 | { | ||
987 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
988 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
989 | |||
990 | if (pBtHciInfo->bTestNeedReport) { | ||
991 | u8 localBuf[20] = ""; | ||
992 | u32 *pu4Temp; | ||
993 | u16 *pu2Temp; | ||
994 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
995 | |||
996 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), (" HCI_EVENT_AMP_RECEIVER_REPORT\n")); | ||
997 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
998 | PPacketIrpEvent->EventCode = HCI_EVENT_AMP_RECEIVER_REPORT; | ||
999 | PPacketIrpEvent->Length = 2; | ||
1000 | |||
1001 | PPacketIrpEvent->Data[0] = pBtHciInfo->TestCtrType; | ||
1002 | |||
1003 | PPacketIrpEvent->Data[1] = Reason; | ||
1004 | |||
1005 | pu4Temp = (u32 *)&PPacketIrpEvent->Data[2]; | ||
1006 | *pu4Temp = pBtHciInfo->TestEventType; | ||
1007 | |||
1008 | pu2Temp = (u16 *)&PPacketIrpEvent->Data[6]; | ||
1009 | *pu2Temp = pBtHciInfo->TestNumOfFrame; | ||
1010 | |||
1011 | pu2Temp = (u16 *)&PPacketIrpEvent->Data[8]; | ||
1012 | *pu2Temp = pBtHciInfo->TestNumOfErrFrame; | ||
1013 | |||
1014 | pu4Temp = (u32 *)&PPacketIrpEvent->Data[10]; | ||
1015 | *pu4Temp = pBtHciInfo->TestNumOfBits; | ||
1016 | |||
1017 | pu4Temp = (u32 *)&PPacketIrpEvent->Data[14]; | ||
1018 | *pu4Temp = pBtHciInfo->TestNumOfErrBits; | ||
1019 | |||
1020 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 20); | ||
1021 | |||
1022 | /* Return to Idel state with RX and TX off. */ | ||
1023 | |||
1024 | } | ||
1025 | |||
1026 | pBtHciInfo->TestNumOfFrame = 0x00; | ||
1027 | } | ||
1028 | |||
1029 | static void | ||
1030 | bthci_EventChannelSelected( | ||
1031 | struct rtw_adapter *padapter, | ||
1032 | u8 EntryNum | ||
1033 | ) | ||
1034 | { | ||
1035 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
1036 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
1037 | u8 localBuf[3] = ""; | ||
1038 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
1039 | |||
1040 | if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_CHANNEL_SELECT)) { | ||
1041 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, | ||
1042 | ("[BT event], Channel Selected, Ignore to send this event due to event mask page 2\n")); | ||
1043 | return; | ||
1044 | } | ||
1045 | |||
1046 | RTPRINT(FIOCTL, IOCTL_BT_EVENT|IOCTL_STATE, | ||
1047 | ("[BT event], Channel Selected, PhyLinkHandle %d\n", | ||
1048 | pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle)); | ||
1049 | |||
1050 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
1051 | PPacketIrpEvent->EventCode = HCI_EVENT_CHANNEL_SELECT; | ||
1052 | PPacketIrpEvent->Length = 1; | ||
1053 | PPacketIrpEvent->Data[0] = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle; | ||
1054 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 3); | ||
1055 | } | ||
1056 | |||
1057 | static void | ||
1058 | bthci_EventDisconnectPhyLinkComplete( | ||
1059 | struct rtw_adapter *padapter, | ||
1060 | enum hci_status HciStatus, | ||
1061 | enum hci_status Reason, | ||
1062 | u8 EntryNum | ||
1063 | ) | ||
1064 | { | ||
1065 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
1066 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
1067 | u8 localBuf[5] = ""; | ||
1068 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
1069 | |||
1070 | if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_DISCONNECT_PHY_LINK_COMPLETE)) { | ||
1071 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, | ||
1072 | ("[BT event], Disconnect Physical Link Complete, Ignore to send this event due to event mask page 2\n")); | ||
1073 | return; | ||
1074 | } | ||
1075 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, | ||
1076 | ("[BT event], Disconnect Physical Link Complete, Status = 0x%x, PLH = 0x%x Reason = 0x%x\n", | ||
1077 | HciStatus, pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle, Reason)); | ||
1078 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
1079 | PPacketIrpEvent->EventCode = HCI_EVENT_DISCONNECT_PHY_LINK_COMPLETE; | ||
1080 | PPacketIrpEvent->Length = 3; | ||
1081 | PPacketIrpEvent->Data[0] = HciStatus; | ||
1082 | PPacketIrpEvent->Data[1] = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle; | ||
1083 | PPacketIrpEvent->Data[2] = Reason; | ||
1084 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 5); | ||
1085 | } | ||
1086 | |||
1087 | static void | ||
1088 | bthci_EventPhysicalLinkComplete( | ||
1089 | struct rtw_adapter *padapter, | ||
1090 | enum hci_status HciStatus, | ||
1091 | u8 EntryNum, | ||
1092 | u8 PLHandle | ||
1093 | ) | ||
1094 | { | ||
1095 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
1096 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
1097 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
1098 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
1099 | u8 localBuf[4] = ""; | ||
1100 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
1101 | u8 PL_handle; | ||
1102 | |||
1103 | pBtMgnt->bPhyLinkInProgress = false; | ||
1104 | pBtDbg->dbgHciInfo.hciCmdPhyLinkStatus = HciStatus; | ||
1105 | if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_PHY_LINK_COMPLETE)) { | ||
1106 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, | ||
1107 | ("[BT event], Physical Link Complete, Ignore to send this event due to event mask page 2\n")); | ||
1108 | return; | ||
1109 | } | ||
1110 | |||
1111 | if (EntryNum == 0xff) { | ||
1112 | /* connection not started yet, just use the input physical link handle to response. */ | ||
1113 | PL_handle = PLHandle; | ||
1114 | } else { | ||
1115 | /* connection is under progress, use the phy link handle we recorded. */ | ||
1116 | PL_handle = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle; | ||
1117 | pBTInfo->BtAsocEntry[EntryNum].bNeedPhysLinkCompleteEvent = false; | ||
1118 | } | ||
1119 | |||
1120 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Physical Link Complete, Status = 0x%x PhyLinkHandle = 0x%x\n", HciStatus, | ||
1121 | PL_handle)); | ||
1122 | |||
1123 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
1124 | PPacketIrpEvent->EventCode = HCI_EVENT_PHY_LINK_COMPLETE; | ||
1125 | PPacketIrpEvent->Length = 2; | ||
1126 | |||
1127 | PPacketIrpEvent->Data[0] = HciStatus; | ||
1128 | PPacketIrpEvent->Data[1] = PL_handle; | ||
1129 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 4); | ||
1130 | |||
1131 | } | ||
1132 | |||
1133 | static void | ||
1134 | bthci_EventCommandStatus( | ||
1135 | struct rtw_adapter *padapter, | ||
1136 | u8 OGF, | ||
1137 | u16 OCF, | ||
1138 | enum hci_status HciStatus | ||
1139 | ) | ||
1140 | { | ||
1141 | |||
1142 | u8 localBuf[6] = ""; | ||
1143 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
1144 | u8 Num_Hci_Comm = 0x1; | ||
1145 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, | ||
1146 | ("[BT event], CommandStatus, Opcode = 0x%02x%02x, OGF = 0x%x, OCF = 0x%x, Status = 0x%x, Num_HCI_COMM = 0x%x\n", | ||
1147 | (HCIOPCODEHIGHT(OCF, OGF)), (HCIOPCODELOW(OCF, OGF)), OGF, OCF, HciStatus, Num_Hci_Comm)); | ||
1148 | |||
1149 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
1150 | PPacketIrpEvent->EventCode = HCI_EVENT_COMMAND_STATUS; | ||
1151 | PPacketIrpEvent->Length = 4; | ||
1152 | PPacketIrpEvent->Data[0] = HciStatus; /* current pending */ | ||
1153 | PPacketIrpEvent->Data[1] = Num_Hci_Comm; /* packet # */ | ||
1154 | PPacketIrpEvent->Data[2] = HCIOPCODELOW(OCF, OGF); | ||
1155 | PPacketIrpEvent->Data[3] = HCIOPCODEHIGHT(OCF, OGF); | ||
1156 | |||
1157 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 6); | ||
1158 | |||
1159 | } | ||
1160 | |||
1161 | static void | ||
1162 | bthci_EventLogicalLinkComplete( | ||
1163 | struct rtw_adapter *padapter, | ||
1164 | enum hci_status HciStatus, | ||
1165 | u8 PhyLinkHandle, | ||
1166 | u16 LogLinkHandle, | ||
1167 | u8 LogLinkIndex, | ||
1168 | u8 EntryNum | ||
1169 | ) | ||
1170 | { | ||
1171 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
1172 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
1173 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
1174 | u8 localBuf[7] = ""; | ||
1175 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
1176 | |||
1177 | if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_LOGICAL_LINK_COMPLETE)) { | ||
1178 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, | ||
1179 | ("[BT event], Logical Link Complete, Ignore to send this event due to event mask page 2\n")); | ||
1180 | return; | ||
1181 | } | ||
1182 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Logical Link Complete, PhyLinkHandle = 0x%x, LogLinkHandle = 0x%x, Status = 0x%x\n", | ||
1183 | PhyLinkHandle, LogLinkHandle, HciStatus)); | ||
1184 | |||
1185 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
1186 | PPacketIrpEvent->EventCode = HCI_EVENT_LOGICAL_LINK_COMPLETE; | ||
1187 | PPacketIrpEvent->Length = 5; | ||
1188 | |||
1189 | PPacketIrpEvent->Data[0] = HciStatus;/* status code */ | ||
1190 | /* Logical link handle */ | ||
1191 | PPacketIrpEvent->Data[1] = TWOBYTE_LOWBYTE(LogLinkHandle); | ||
1192 | PPacketIrpEvent->Data[2] = TWOBYTE_HIGHTBYTE(LogLinkHandle); | ||
1193 | /* Physical link handle */ | ||
1194 | PPacketIrpEvent->Data[3] = TWOBYTE_LOWBYTE(PhyLinkHandle); | ||
1195 | /* corresponding Tx flow spec ID */ | ||
1196 | if (HciStatus == HCI_STATUS_SUCCESS) { | ||
1197 | PPacketIrpEvent->Data[4] = | ||
1198 | pBTInfo->BtAsocEntry[EntryNum].LogLinkCmdData[LogLinkIndex].Tx_Flow_Spec.Identifier; | ||
1199 | } else { | ||
1200 | PPacketIrpEvent->Data[4] = 0x0; | ||
1201 | } | ||
1202 | |||
1203 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 7); | ||
1204 | } | ||
1205 | |||
1206 | static void | ||
1207 | bthci_EventDisconnectLogicalLinkComplete( | ||
1208 | struct rtw_adapter *padapter, | ||
1209 | enum hci_status HciStatus, | ||
1210 | u16 LogLinkHandle, | ||
1211 | enum hci_status Reason | ||
1212 | ) | ||
1213 | { | ||
1214 | u8 localBuf[6] = ""; | ||
1215 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
1216 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
1217 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
1218 | |||
1219 | if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_DISCONNECT_LOGICAL_LINK_COMPLETE)) { | ||
1220 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Disconnect Logical Link Complete, Ignore to send this event due to event mask page 2\n")); | ||
1221 | return; | ||
1222 | } | ||
1223 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Disconnect Logical Link Complete, Status = 0x%x, LLH = 0x%x Reason = 0x%x\n", HciStatus, LogLinkHandle, Reason)); | ||
1224 | |||
1225 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
1226 | PPacketIrpEvent->EventCode = HCI_EVENT_DISCONNECT_LOGICAL_LINK_COMPLETE; | ||
1227 | PPacketIrpEvent->Length = 4; | ||
1228 | |||
1229 | PPacketIrpEvent->Data[0] = HciStatus; | ||
1230 | /* Logical link handle */ | ||
1231 | PPacketIrpEvent->Data[1] = TWOBYTE_LOWBYTE(LogLinkHandle); | ||
1232 | PPacketIrpEvent->Data[2] = TWOBYTE_HIGHTBYTE(LogLinkHandle); | ||
1233 | /* Disconnect reason */ | ||
1234 | PPacketIrpEvent->Data[3] = Reason; | ||
1235 | |||
1236 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 6); | ||
1237 | } | ||
1238 | |||
1239 | static void | ||
1240 | bthci_EventFlushOccurred( | ||
1241 | struct rtw_adapter *padapter, | ||
1242 | u16 LogLinkHandle | ||
1243 | ) | ||
1244 | { | ||
1245 | u8 localBuf[4] = ""; | ||
1246 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
1247 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("bthci_EventFlushOccurred(), LLH = 0x%x\n", LogLinkHandle)); | ||
1248 | |||
1249 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
1250 | PPacketIrpEvent->EventCode = HCI_EVENT_FLUSH_OCCRUED; | ||
1251 | PPacketIrpEvent->Length = 2; | ||
1252 | /* Logical link handle */ | ||
1253 | PPacketIrpEvent->Data[0] = TWOBYTE_LOWBYTE(LogLinkHandle); | ||
1254 | PPacketIrpEvent->Data[1] = TWOBYTE_HIGHTBYTE(LogLinkHandle); | ||
1255 | |||
1256 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 4); | ||
1257 | } | ||
1258 | |||
1259 | static enum hci_status | ||
1260 | bthci_BuildPhysicalLink( | ||
1261 | struct rtw_adapter *padapter, | ||
1262 | struct packet_irp_hcicmd_data *pHciCmd, | ||
1263 | u16 OCF | ||
1264 | ) | ||
1265 | { | ||
1266 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
1267 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
1268 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
1269 | u8 EntryNum, PLH; | ||
1270 | |||
1271 | /* Send HCI Command status event to AMP. */ | ||
1272 | bthci_EventCommandStatus(padapter, | ||
1273 | LINK_CONTROL_COMMANDS, | ||
1274 | OCF, | ||
1275 | HCI_STATUS_SUCCESS); | ||
1276 | |||
1277 | PLH = *((u8 *)pHciCmd->Data); | ||
1278 | |||
1279 | /* Check if resource or bt connection is under progress, if yes, reject the link creation. */ | ||
1280 | if (!bthci_AddEntry(padapter)) { | ||
1281 | status = HCI_STATUS_CONNECT_RJT_LIMIT_RESOURCE; | ||
1282 | bthci_EventPhysicalLinkComplete(padapter, status, INVALID_ENTRY_NUM, PLH); | ||
1283 | return status; | ||
1284 | } | ||
1285 | |||
1286 | EntryNum = pBtMgnt->CurrentConnectEntryNum; | ||
1287 | pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle = PLH; | ||
1288 | pBtMgnt->BtCurrentPhyLinkhandle = PLH; | ||
1289 | |||
1290 | if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocfragment == NULL) { | ||
1291 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Create/Accept PhysicalLink, AMP controller is busy\n")); | ||
1292 | status = HCI_STATUS_CONTROLLER_BUSY; | ||
1293 | bthci_EventPhysicalLinkComplete(padapter, status, INVALID_ENTRY_NUM, PLH); | ||
1294 | return status; | ||
1295 | } | ||
1296 | |||
1297 | /* Record Key and the info */ | ||
1298 | pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen = (*((u8 *)pHciCmd->Data+1)); | ||
1299 | pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyType = (*((u8 *)pHciCmd->Data+2)); | ||
1300 | memcpy(pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKey, | ||
1301 | (((u8 *)pHciCmd->Data+3)), pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen); | ||
1302 | memcpy(pBTInfo->BtAsocEntry[EntryNum].PMK, pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKey, PMK_LEN); | ||
1303 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("BuildPhysicalLink, EntryNum = %d, PLH = 0x%x KeyLen = 0x%x, KeyType = 0x%x\n", | ||
1304 | EntryNum, pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle, | ||
1305 | pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen, | ||
1306 | pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyType)); | ||
1307 | RTPRINT_DATA(FIOCTL, (IOCTL_BT_LOGO|IOCTL_BT_HCICMD), ("BtAMPKey\n"), pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKey, | ||
1308 | pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen); | ||
1309 | RTPRINT_DATA(FIOCTL, (IOCTL_BT_LOGO|IOCTL_BT_HCICMD), ("PMK\n"), pBTInfo->BtAsocEntry[EntryNum].PMK, | ||
1310 | PMK_LEN); | ||
1311 | |||
1312 | if (OCF == HCI_CREATE_PHYSICAL_LINK) { | ||
1313 | /* These macros require braces */ | ||
1314 | BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_CREATE_PHY_LINK, EntryNum); | ||
1315 | } else if (OCF == HCI_ACCEPT_PHYSICAL_LINK) { | ||
1316 | BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_ACCEPT_PHY_LINK, EntryNum); | ||
1317 | } | ||
1318 | |||
1319 | return status; | ||
1320 | } | ||
1321 | |||
1322 | static void | ||
1323 | bthci_BuildLogicalLink( | ||
1324 | struct rtw_adapter *padapter, | ||
1325 | struct packet_irp_hcicmd_data *pHciCmd, | ||
1326 | u16 OCF | ||
1327 | ) | ||
1328 | { | ||
1329 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
1330 | struct bt_30info *pBTinfo = GET_BT_INFO(padapter); | ||
1331 | struct bt_mgnt *pBtMgnt = &pBTinfo->BtMgnt; | ||
1332 | u8 PhyLinkHandle, EntryNum; | ||
1333 | static u16 AssignLogHandle = 1; | ||
1334 | |||
1335 | struct hci_flow_spec TxFlowSpec; | ||
1336 | struct hci_flow_spec RxFlowSpec; | ||
1337 | u32 MaxSDUSize, ArriveTime, Bandwidth; | ||
1338 | |||
1339 | PhyLinkHandle = *((u8 *)pHciCmd->Data); | ||
1340 | |||
1341 | EntryNum = bthci_GetCurrentEntryNum(padapter, PhyLinkHandle); | ||
1342 | |||
1343 | memcpy(&TxFlowSpec, | ||
1344 | &pHciCmd->Data[1], sizeof(struct hci_flow_spec)); | ||
1345 | memcpy(&RxFlowSpec, | ||
1346 | &pHciCmd->Data[17], sizeof(struct hci_flow_spec)); | ||
1347 | |||
1348 | MaxSDUSize = TxFlowSpec.MaximumSDUSize; | ||
1349 | ArriveTime = TxFlowSpec.SDUInterArrivalTime; | ||
1350 | |||
1351 | if (bthci_CheckLogLinkBehavior(padapter, TxFlowSpec) && bthci_CheckLogLinkBehavior(padapter, RxFlowSpec)) | ||
1352 | Bandwidth = BTTOTALBANDWIDTH; | ||
1353 | else if (MaxSDUSize == 0xffff && ArriveTime == 0xffffffff) | ||
1354 | Bandwidth = BTTOTALBANDWIDTH; | ||
1355 | else | ||
1356 | Bandwidth = MaxSDUSize*8*1000/(ArriveTime+244); | ||
1357 | |||
1358 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, | ||
1359 | ("BuildLogicalLink, PhyLinkHandle = 0x%x, MaximumSDUSize = 0x%x, SDUInterArrivalTime = 0x%x, Bandwidth = 0x%x\n", | ||
1360 | PhyLinkHandle, MaxSDUSize, ArriveTime, Bandwidth)); | ||
1361 | |||
1362 | if (EntryNum == 0xff) { | ||
1363 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Invalid Physical Link handle = 0x%x, status = HCI_STATUS_UNKNOW_CONNECT_ID, return\n", PhyLinkHandle)); | ||
1364 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
1365 | |||
1366 | /* When we receive Create/Accept logical link command, we should send command status event first. */ | ||
1367 | bthci_EventCommandStatus(padapter, | ||
1368 | LINK_CONTROL_COMMANDS, | ||
1369 | OCF, | ||
1370 | status); | ||
1371 | return; | ||
1372 | } | ||
1373 | |||
1374 | if (!pBtMgnt->bLogLinkInProgress) { | ||
1375 | if (bthci_PhyLinkConnectionInProgress(padapter, PhyLinkHandle)) { | ||
1376 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Physical link connection in progress, status = HCI_STATUS_CMD_DISALLOW, return\n")); | ||
1377 | status = HCI_STATUS_CMD_DISALLOW; | ||
1378 | |||
1379 | pBtMgnt->bPhyLinkInProgressStartLL = true; | ||
1380 | /* When we receive Create/Accept logical link command, we should send command status event first. */ | ||
1381 | bthci_EventCommandStatus(padapter, | ||
1382 | LINK_CONTROL_COMMANDS, | ||
1383 | OCF, | ||
1384 | status); | ||
1385 | |||
1386 | return; | ||
1387 | } | ||
1388 | |||
1389 | if (Bandwidth > BTTOTALBANDWIDTH) { | ||
1390 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("status = HCI_STATUS_QOS_REJECT, Bandwidth = 0x%x, return\n", Bandwidth)); | ||
1391 | status = HCI_STATUS_QOS_REJECT; | ||
1392 | |||
1393 | /* When we receive Create/Accept logical link command, we should send command status event first. */ | ||
1394 | bthci_EventCommandStatus(padapter, | ||
1395 | LINK_CONTROL_COMMANDS, | ||
1396 | OCF, | ||
1397 | status); | ||
1398 | } else { | ||
1399 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("status = HCI_STATUS_SUCCESS\n")); | ||
1400 | status = HCI_STATUS_SUCCESS; | ||
1401 | |||
1402 | /* When we receive Create/Accept logical link command, we should send command status event first. */ | ||
1403 | bthci_EventCommandStatus(padapter, | ||
1404 | LINK_CONTROL_COMMANDS, | ||
1405 | OCF, | ||
1406 | status); | ||
1407 | |||
1408 | } | ||
1409 | |||
1410 | if (pBTinfo->BtAsocEntry[EntryNum].BtCurrentState != HCI_STATE_CONNECTED) { | ||
1411 | bthci_EventLogicalLinkComplete(padapter, | ||
1412 | HCI_STATUS_CMD_DISALLOW, 0, 0, 0, EntryNum); | ||
1413 | } else { | ||
1414 | u8 i, find = 0; | ||
1415 | |||
1416 | pBtMgnt->bLogLinkInProgress = true; | ||
1417 | |||
1418 | /* find an unused logical link index and copy the data */ | ||
1419 | for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) { | ||
1420 | if (pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtLogLinkhandle == 0) { | ||
1421 | enum hci_status LogCompEventstatus = HCI_STATUS_SUCCESS; | ||
1422 | |||
1423 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtPhyLinkhandle = *((u8 *)pHciCmd->Data); | ||
1424 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtLogLinkhandle = AssignLogHandle; | ||
1425 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("BuildLogicalLink, EntryNum = %d, physical link handle = 0x%x, logical link handle = 0x%x\n", | ||
1426 | EntryNum, pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle, | ||
1427 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtLogLinkhandle)); | ||
1428 | memcpy(&pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].Tx_Flow_Spec, | ||
1429 | &TxFlowSpec, sizeof(struct hci_flow_spec)); | ||
1430 | memcpy(&pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].Rx_Flow_Spec, | ||
1431 | &RxFlowSpec, sizeof(struct hci_flow_spec)); | ||
1432 | |||
1433 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].bLLCompleteEventIsSet = false; | ||
1434 | |||
1435 | if (pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].bLLCancelCMDIsSetandComplete) | ||
1436 | LogCompEventstatus = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
1437 | bthci_EventLogicalLinkComplete(padapter, | ||
1438 | LogCompEventstatus, | ||
1439 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtPhyLinkhandle, | ||
1440 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtLogLinkhandle, i, EntryNum); | ||
1441 | |||
1442 | pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].bLLCompleteEventIsSet = true; | ||
1443 | |||
1444 | find = 1; | ||
1445 | pBtMgnt->BtCurrentLogLinkhandle = AssignLogHandle; | ||
1446 | AssignLogHandle++; | ||
1447 | break; | ||
1448 | } | ||
1449 | } | ||
1450 | |||
1451 | if (!find) { | ||
1452 | bthci_EventLogicalLinkComplete(padapter, | ||
1453 | HCI_STATUS_CONNECT_RJT_LIMIT_RESOURCE, 0, 0, 0, EntryNum); | ||
1454 | } | ||
1455 | pBtMgnt->bLogLinkInProgress = false; | ||
1456 | } | ||
1457 | } else { | ||
1458 | bthci_EventLogicalLinkComplete(padapter, | ||
1459 | HCI_STATUS_CONTROLLER_BUSY, 0, 0, 0, EntryNum); | ||
1460 | } | ||
1461 | |||
1462 | } | ||
1463 | |||
1464 | static void | ||
1465 | bthci_StartBeaconAndConnect( | ||
1466 | struct rtw_adapter *padapter, | ||
1467 | struct packet_irp_hcicmd_data *pHciCmd, | ||
1468 | u8 CurrentAssocNum | ||
1469 | ) | ||
1470 | { | ||
1471 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
1472 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
1473 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
1474 | |||
1475 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("StartBeaconAndConnect, CurrentAssocNum =%d, AMPRole =%d\n", | ||
1476 | CurrentAssocNum, | ||
1477 | pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole)); | ||
1478 | |||
1479 | if (!pBtMgnt->CheckChnlIsSuit) { | ||
1480 | bthci_EventPhysicalLinkComplete(padapter, HCI_STATUS_CONNECT_REJ_NOT_SUIT_CHNL_FOUND, CurrentAssocNum, INVALID_PL_HANDLE); | ||
1481 | bthci_RemoveEntryByEntryNum(padapter, CurrentAssocNum); | ||
1482 | return; | ||
1483 | } | ||
1484 | |||
1485 | if (pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole == AMP_BTAP_CREATOR) { | ||
1486 | rsprintf((char *)pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsidBuf, 32, "AMP-%02x-%02x-%02x-%02x-%02x-%02x", | ||
1487 | padapter->eeprompriv.mac_addr[0], | ||
1488 | padapter->eeprompriv.mac_addr[1], | ||
1489 | padapter->eeprompriv.mac_addr[2], | ||
1490 | padapter->eeprompriv.mac_addr[3], | ||
1491 | padapter->eeprompriv.mac_addr[4], | ||
1492 | padapter->eeprompriv.mac_addr[5]); | ||
1493 | } else if (pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole == AMP_BTAP_JOINER) { | ||
1494 | rsprintf((char *)pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsidBuf, 32, "AMP-%02x-%02x-%02x-%02x-%02x-%02x", | ||
1495 | pBTInfo->BtAsocEntry[CurrentAssocNum].BTRemoteMACAddr[0], | ||
1496 | pBTInfo->BtAsocEntry[CurrentAssocNum].BTRemoteMACAddr[1], | ||
1497 | pBTInfo->BtAsocEntry[CurrentAssocNum].BTRemoteMACAddr[2], | ||
1498 | pBTInfo->BtAsocEntry[CurrentAssocNum].BTRemoteMACAddr[3], | ||
1499 | pBTInfo->BtAsocEntry[CurrentAssocNum].BTRemoteMACAddr[4], | ||
1500 | pBTInfo->BtAsocEntry[CurrentAssocNum].BTRemoteMACAddr[5]); | ||
1501 | } | ||
1502 | |||
1503 | FillOctetString(pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsid, pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsidBuf, 21); | ||
1504 | pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsid.Length = 21; | ||
1505 | |||
1506 | /* To avoid set the start ap or connect twice, or the original connection will be disconnected. */ | ||
1507 | if (!pBtMgnt->bBTConnectInProgress) { | ||
1508 | pBtMgnt->bBTConnectInProgress = true; | ||
1509 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress ON!!\n")); | ||
1510 | BTHCI_SM_WITH_INFO(padapter, HCI_STATE_STARTING, STATE_CMD_MAC_START_COMPLETE, CurrentAssocNum); | ||
1511 | |||
1512 | /* 20100325 Joseph: Check RF ON/OFF. */ | ||
1513 | /* If RF OFF, it reschedule connecting operation after 50ms. */ | ||
1514 | if (!bthci_CheckRfStateBeforeConnect(padapter)) | ||
1515 | return; | ||
1516 | |||
1517 | if (pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole == AMP_BTAP_CREATOR) { | ||
1518 | /* These macros need braces */ | ||
1519 | BTHCI_SM_WITH_INFO(padapter, HCI_STATE_CONNECTING, STATE_CMD_MAC_CONNECT_COMPLETE, CurrentAssocNum); | ||
1520 | } else if (pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole == AMP_BTAP_JOINER) { | ||
1521 | bthci_ResponderStartToScan(padapter); | ||
1522 | } | ||
1523 | } | ||
1524 | RT_PRINT_STR(_module_rtl871x_mlme_c_, _drv_notice_, | ||
1525 | "StartBeaconAndConnect, SSID:\n", | ||
1526 | pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].BTSsid.Octet, | ||
1527 | pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].BTSsid.Length); | ||
1528 | } | ||
1529 | |||
1530 | static void bthci_ResetBtMgnt(struct bt_mgnt *pBtMgnt) | ||
1531 | { | ||
1532 | pBtMgnt->BtOperationOn = false; | ||
1533 | pBtMgnt->bBTConnectInProgress = false; | ||
1534 | pBtMgnt->bLogLinkInProgress = false; | ||
1535 | pBtMgnt->bPhyLinkInProgress = false; | ||
1536 | pBtMgnt->bPhyLinkInProgressStartLL = false; | ||
1537 | pBtMgnt->DisconnectEntryNum = 0xff; | ||
1538 | pBtMgnt->bStartSendSupervisionPkt = false; | ||
1539 | pBtMgnt->JoinerNeedSendAuth = false; | ||
1540 | pBtMgnt->CurrentBTConnectionCnt = 0; | ||
1541 | pBtMgnt->BTCurrentConnectType = BT_DISCONNECT; | ||
1542 | pBtMgnt->BTReceiveConnectPkt = BT_DISCONNECT; | ||
1543 | pBtMgnt->BTAuthCount = 0; | ||
1544 | pBtMgnt->btLogoTest = 0; | ||
1545 | } | ||
1546 | |||
1547 | static void bthci_ResetBtHciInfo(struct bt_hci_info *pBtHciInfo) | ||
1548 | { | ||
1549 | pBtHciInfo->BTEventMask = 0; | ||
1550 | pBtHciInfo->BTEventMaskPage2 = 0; | ||
1551 | pBtHciInfo->ConnAcceptTimeout = 10000; | ||
1552 | pBtHciInfo->PageTimeout = 0x30; | ||
1553 | pBtHciInfo->LocationDomainAware = 0x0; | ||
1554 | pBtHciInfo->LocationDomain = 0x5858; | ||
1555 | pBtHciInfo->LocationDomainOptions = 0x58; | ||
1556 | pBtHciInfo->LocationOptions = 0x0; | ||
1557 | pBtHciInfo->FlowControlMode = 0x1; /* 0:Packet based data flow control mode(BR/EDR), 1: Data block based data flow control mode(AMP). */ | ||
1558 | |||
1559 | pBtHciInfo->enFlush_LLH = 0; | ||
1560 | pBtHciInfo->FLTO_LLH = 0; | ||
1561 | |||
1562 | /* Test command only */ | ||
1563 | pBtHciInfo->bTestIsEnd = true; | ||
1564 | pBtHciInfo->bInTestMode = false; | ||
1565 | pBtHciInfo->bTestNeedReport = false; | ||
1566 | pBtHciInfo->TestScenario = 0xff; | ||
1567 | pBtHciInfo->TestReportInterval = 0x01; | ||
1568 | pBtHciInfo->TestCtrType = 0x5d; | ||
1569 | pBtHciInfo->TestEventType = 0x00; | ||
1570 | pBtHciInfo->TestNumOfFrame = 0; | ||
1571 | pBtHciInfo->TestNumOfErrFrame = 0; | ||
1572 | pBtHciInfo->TestNumOfBits = 0; | ||
1573 | pBtHciInfo->TestNumOfErrBits = 0; | ||
1574 | } | ||
1575 | |||
1576 | static void bthci_ResetBtSec(struct rtw_adapter *padapter, struct bt_security *pBtSec) | ||
1577 | { | ||
1578 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
1579 | |||
1580 | /* Set BT used HW or SW encrypt !! */ | ||
1581 | if (GET_HAL_DATA(padapter)->bBTMode) | ||
1582 | pBtSec->bUsedHwEncrypt = true; | ||
1583 | else | ||
1584 | pBtSec->bUsedHwEncrypt = false; | ||
1585 | RT_TRACE(_module_rtl871x_security_c_, _drv_info_, ("%s: bUsedHwEncrypt =%d\n", __func__, pBtSec->bUsedHwEncrypt)); | ||
1586 | |||
1587 | pBtSec->RSNIE.Octet = pBtSec->RSNIEBuf; | ||
1588 | } | ||
1589 | |||
1590 | static void bthci_ResetBtExtInfo(struct bt_mgnt *pBtMgnt) | ||
1591 | { | ||
1592 | u8 i; | ||
1593 | |||
1594 | for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) { | ||
1595 | pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle = 0; | ||
1596 | pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = 0; | ||
1597 | pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = 0; | ||
1598 | pBtMgnt->ExtConfig.linkInfo[i].BTProfile = BT_PROFILE_NONE; | ||
1599 | pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec = BT_SPEC_2_1_EDR; | ||
1600 | pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI = 0; | ||
1601 | pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile = BT_PROFILE_NONE; | ||
1602 | pBtMgnt->ExtConfig.linkInfo[i].linkRole = BT_LINK_MASTER; | ||
1603 | } | ||
1604 | |||
1605 | pBtMgnt->ExtConfig.CurrentConnectHandle = 0; | ||
1606 | pBtMgnt->ExtConfig.CurrentIncomingTrafficMode = 0; | ||
1607 | pBtMgnt->ExtConfig.CurrentOutgoingTrafficMode = 0; | ||
1608 | pBtMgnt->ExtConfig.MIN_BT_RSSI = 0; | ||
1609 | pBtMgnt->ExtConfig.NumberOfHandle = 0; | ||
1610 | pBtMgnt->ExtConfig.NumberOfSCO = 0; | ||
1611 | pBtMgnt->ExtConfig.CurrentBTStatus = 0; | ||
1612 | pBtMgnt->ExtConfig.HCIExtensionVer = 0; | ||
1613 | |||
1614 | pBtMgnt->ExtConfig.bManualControl = false; | ||
1615 | pBtMgnt->ExtConfig.bBTBusy = false; | ||
1616 | pBtMgnt->ExtConfig.bBTA2DPBusy = false; | ||
1617 | } | ||
1618 | |||
1619 | static enum hci_status bthci_CmdReset(struct rtw_adapter *_padapter, u8 bNeedSendEvent) | ||
1620 | { | ||
1621 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
1622 | struct rtw_adapter *padapter; | ||
1623 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
1624 | struct bt_30info *pBTInfo; | ||
1625 | struct bt_mgnt *pBtMgnt; | ||
1626 | struct bt_hci_info *pBtHciInfo; | ||
1627 | struct bt_security *pBtSec; | ||
1628 | struct bt_dgb *pBtDbg; | ||
1629 | u8 i; | ||
1630 | |||
1631 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_CmdReset()\n")); | ||
1632 | |||
1633 | padapter = GetDefaultAdapter(_padapter); | ||
1634 | pBTInfo = GET_BT_INFO(padapter); | ||
1635 | pBtMgnt = &pBTInfo->BtMgnt; | ||
1636 | pBtHciInfo = &pBTInfo->BtHciInfo; | ||
1637 | pBtSec = &pBTInfo->BtSec; | ||
1638 | pBtDbg = &pBTInfo->BtDbg; | ||
1639 | |||
1640 | pBTInfo->padapter = padapter; | ||
1641 | |||
1642 | for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) | ||
1643 | bthci_ResetEntry(padapter, i); | ||
1644 | |||
1645 | bthci_ResetBtMgnt(pBtMgnt); | ||
1646 | bthci_ResetBtHciInfo(pBtHciInfo); | ||
1647 | bthci_ResetBtSec(padapter, pBtSec); | ||
1648 | |||
1649 | pBtMgnt->BTChannel = BT_Default_Chnl; | ||
1650 | pBtMgnt->CheckChnlIsSuit = true; | ||
1651 | |||
1652 | pBTInfo->BTBeaconTmrOn = false; | ||
1653 | |||
1654 | pBtMgnt->bCreateSpportQos = true; | ||
1655 | |||
1656 | del_timer_sync(&pBTInfo->BTHCIDiscardAclDataTimer); | ||
1657 | del_timer_sync(&pBTInfo->BTBeaconTimer); | ||
1658 | |||
1659 | HALBT_SetRtsCtsNoLenLimit(padapter); | ||
1660 | /* */ | ||
1661 | /* Maybe we need to take care Group != AES case !! */ | ||
1662 | /* now we Pairwise and Group all used AES !! */ | ||
1663 | |||
1664 | bthci_ResetBtExtInfo(pBtMgnt); | ||
1665 | |||
1666 | /* send command complete event here when all data are received. */ | ||
1667 | if (bNeedSendEvent) { | ||
1668 | u8 localBuf[6] = ""; | ||
1669 | u8 *pRetPar; | ||
1670 | u8 len = 0; | ||
1671 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
1672 | |||
1673 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
1674 | |||
1675 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
1676 | OGF_SET_EVENT_MASK_COMMAND, | ||
1677 | HCI_RESET, | ||
1678 | status); | ||
1679 | |||
1680 | /* Return parameters starts from here */ | ||
1681 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
1682 | pRetPar[0] = status; /* status */ | ||
1683 | len += 1; | ||
1684 | PPacketIrpEvent->Length = len; | ||
1685 | |||
1686 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
1687 | } | ||
1688 | |||
1689 | return status; | ||
1690 | } | ||
1691 | |||
1692 | static enum hci_status | ||
1693 | bthci_CmdWriteRemoteAMPAssoc( | ||
1694 | struct rtw_adapter *padapter, | ||
1695 | struct packet_irp_hcicmd_data *pHciCmd | ||
1696 | ) | ||
1697 | { | ||
1698 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
1699 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
1700 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
1701 | u8 CurrentAssocNum; | ||
1702 | u8 PhyLinkHandle; | ||
1703 | |||
1704 | pBtDbg->dbgHciInfo.hciCmdCntWriteRemoteAmpAssoc++; | ||
1705 | PhyLinkHandle = *((u8 *)pHciCmd->Data); | ||
1706 | CurrentAssocNum = bthci_GetCurrentEntryNum(padapter, PhyLinkHandle); | ||
1707 | |||
1708 | if (CurrentAssocNum == 0xff) { | ||
1709 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("WriteRemoteAMPAssoc, No such Handle in the Entry\n")); | ||
1710 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
1711 | bthci_EventWriteRemoteAmpAssoc(padapter, status, PhyLinkHandle); | ||
1712 | return status; | ||
1713 | } | ||
1714 | |||
1715 | if (pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocfragment == NULL) { | ||
1716 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("WriteRemoteAMPAssoc, AMP controller is busy\n")); | ||
1717 | status = HCI_STATUS_CONTROLLER_BUSY; | ||
1718 | bthci_EventWriteRemoteAmpAssoc(padapter, status, PhyLinkHandle); | ||
1719 | return status; | ||
1720 | } | ||
1721 | |||
1722 | pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.BtPhyLinkhandle = PhyLinkHandle;/* u8 *)pHciCmd->Data); */ | ||
1723 | pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.LenSoFar = *((u16 *)((u8 *)pHciCmd->Data+1)); | ||
1724 | pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen = *((u16 *)((u8 *)pHciCmd->Data+3)); | ||
1725 | |||
1726 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("WriteRemoteAMPAssoc, LenSoFar = 0x%x, AssocRemLen = 0x%x\n", | ||
1727 | pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.LenSoFar, | ||
1728 | pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen)); | ||
1729 | |||
1730 | RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), | ||
1731 | ("WriteRemoteAMPAssoc fragment \n"), | ||
1732 | pHciCmd->Data, | ||
1733 | pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen+5); | ||
1734 | if ((pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen) > MAX_AMP_ASSOC_FRAG_LEN) { | ||
1735 | memcpy(((u8 *)pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocfragment+(pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.LenSoFar*(sizeof(u8)))), | ||
1736 | (u8 *)pHciCmd->Data+5, | ||
1737 | MAX_AMP_ASSOC_FRAG_LEN); | ||
1738 | } else { | ||
1739 | memcpy((u8 *)(pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocfragment)+(pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.LenSoFar*(sizeof(u8))), | ||
1740 | ((u8 *)pHciCmd->Data+5), | ||
1741 | (pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen)); | ||
1742 | |||
1743 | RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), "WriteRemoteAMPAssoc :\n", | ||
1744 | pHciCmd->Data+5, pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen); | ||
1745 | |||
1746 | if (!bthci_GetAssocInfo(padapter, CurrentAssocNum)) | ||
1747 | status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE; | ||
1748 | |||
1749 | bthci_EventWriteRemoteAmpAssoc(padapter, status, PhyLinkHandle); | ||
1750 | |||
1751 | bthci_StartBeaconAndConnect(padapter, pHciCmd, CurrentAssocNum); | ||
1752 | } | ||
1753 | |||
1754 | return status; | ||
1755 | } | ||
1756 | |||
1757 | /* 7.3.13 */ | ||
1758 | static enum hci_status bthci_CmdReadConnectionAcceptTimeout(struct rtw_adapter *padapter) | ||
1759 | { | ||
1760 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
1761 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
1762 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
1763 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
1764 | u8 localBuf[8] = ""; | ||
1765 | u8 *pRetPar; | ||
1766 | u8 len = 0; | ||
1767 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
1768 | u16 *pu2Temp; | ||
1769 | |||
1770 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
1771 | |||
1772 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
1773 | OGF_SET_EVENT_MASK_COMMAND, | ||
1774 | HCI_READ_CONNECTION_ACCEPT_TIMEOUT, | ||
1775 | status); | ||
1776 | |||
1777 | /* Return parameters starts from here */ | ||
1778 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
1779 | pRetPar[0] = status; /* status */ | ||
1780 | pu2Temp = (u16 *)&pRetPar[1]; /* Conn_Accept_Timeout */ | ||
1781 | *pu2Temp = pBtHciInfo->ConnAcceptTimeout; | ||
1782 | len += 3; | ||
1783 | PPacketIrpEvent->Length = len; | ||
1784 | |||
1785 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
1786 | |||
1787 | return status; | ||
1788 | } | ||
1789 | |||
1790 | /* 7.3.3 */ | ||
1791 | static enum hci_status | ||
1792 | bthci_CmdSetEventFilter( | ||
1793 | struct rtw_adapter *padapter, | ||
1794 | struct packet_irp_hcicmd_data *pHciCmd | ||
1795 | ) | ||
1796 | { | ||
1797 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
1798 | |||
1799 | return status; | ||
1800 | } | ||
1801 | |||
1802 | /* 7.3.14 */ | ||
1803 | static enum hci_status | ||
1804 | bthci_CmdWriteConnectionAcceptTimeout( | ||
1805 | struct rtw_adapter *padapter, | ||
1806 | struct packet_irp_hcicmd_data *pHciCmd | ||
1807 | ) | ||
1808 | { | ||
1809 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
1810 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
1811 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
1812 | u16 *pu2Temp; | ||
1813 | u8 localBuf[6] = ""; | ||
1814 | u8 *pRetPar; | ||
1815 | u8 len = 0; | ||
1816 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
1817 | |||
1818 | pu2Temp = (u16 *)&pHciCmd->Data[0]; | ||
1819 | pBtHciInfo->ConnAcceptTimeout = *pu2Temp; | ||
1820 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("ConnAcceptTimeout = 0x%x", | ||
1821 | pBtHciInfo->ConnAcceptTimeout)); | ||
1822 | |||
1823 | /* send command complete event here when all data are received. */ | ||
1824 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
1825 | |||
1826 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
1827 | OGF_SET_EVENT_MASK_COMMAND, | ||
1828 | HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT, | ||
1829 | status); | ||
1830 | |||
1831 | /* Return parameters starts from here */ | ||
1832 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
1833 | pRetPar[0] = status; /* status */ | ||
1834 | len += 1; | ||
1835 | PPacketIrpEvent->Length = len; | ||
1836 | |||
1837 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
1838 | |||
1839 | return status; | ||
1840 | } | ||
1841 | |||
1842 | static enum hci_status | ||
1843 | bthci_CmdReadPageTimeout( | ||
1844 | struct rtw_adapter *padapter, | ||
1845 | struct packet_irp_hcicmd_data *pHciCmd | ||
1846 | ) | ||
1847 | { | ||
1848 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
1849 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
1850 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
1851 | u8 localBuf[8] = ""; | ||
1852 | u8 *pRetPar; | ||
1853 | u8 len = 0; | ||
1854 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
1855 | u16 *pu2Temp; | ||
1856 | |||
1857 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
1858 | |||
1859 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
1860 | OGF_SET_EVENT_MASK_COMMAND, | ||
1861 | HCI_READ_PAGE_TIMEOUT, | ||
1862 | status); | ||
1863 | |||
1864 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Read PageTimeout = 0x%x\n", pBtHciInfo->PageTimeout)); | ||
1865 | /* Return parameters starts from here */ | ||
1866 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
1867 | pRetPar[0] = status; /* status */ | ||
1868 | pu2Temp = (u16 *)&pRetPar[1]; /* Page_Timeout */ | ||
1869 | *pu2Temp = pBtHciInfo->PageTimeout; | ||
1870 | len += 3; | ||
1871 | PPacketIrpEvent->Length = len; | ||
1872 | |||
1873 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
1874 | |||
1875 | return status; | ||
1876 | } | ||
1877 | |||
1878 | static enum hci_status | ||
1879 | bthci_CmdWritePageTimeout( | ||
1880 | struct rtw_adapter *padapter, | ||
1881 | struct packet_irp_hcicmd_data *pHciCmd | ||
1882 | ) | ||
1883 | { | ||
1884 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
1885 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
1886 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
1887 | u16 *pu2Temp; | ||
1888 | |||
1889 | pu2Temp = (u16 *)&pHciCmd->Data[0]; | ||
1890 | pBtHciInfo->PageTimeout = *pu2Temp; | ||
1891 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Write PageTimeout = 0x%x\n", | ||
1892 | pBtHciInfo->PageTimeout)); | ||
1893 | |||
1894 | /* send command complete event here when all data are received. */ | ||
1895 | { | ||
1896 | u8 localBuf[6] = ""; | ||
1897 | u8 *pRetPar; | ||
1898 | u8 len = 0; | ||
1899 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
1900 | |||
1901 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
1902 | |||
1903 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
1904 | OGF_SET_EVENT_MASK_COMMAND, | ||
1905 | HCI_WRITE_PAGE_TIMEOUT, | ||
1906 | status); | ||
1907 | |||
1908 | /* Return parameters starts from here */ | ||
1909 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
1910 | pRetPar[0] = status; /* status */ | ||
1911 | len += 1; | ||
1912 | PPacketIrpEvent->Length = len; | ||
1913 | |||
1914 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
1915 | } | ||
1916 | |||
1917 | return status; | ||
1918 | } | ||
1919 | |||
1920 | static enum hci_status | ||
1921 | bthci_CmdReadLinkSupervisionTimeout( | ||
1922 | struct rtw_adapter *padapter, | ||
1923 | struct packet_irp_hcicmd_data *pHciCmd | ||
1924 | ) | ||
1925 | { | ||
1926 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
1927 | struct bt_30info *pBTinfo = GET_BT_INFO(padapter); | ||
1928 | u8 physicalLinkHandle, EntryNum; | ||
1929 | |||
1930 | physicalLinkHandle = *((u8 *)pHciCmd->Data); | ||
1931 | |||
1932 | EntryNum = bthci_GetCurrentEntryNum(padapter, physicalLinkHandle); | ||
1933 | |||
1934 | if (EntryNum == 0xff) { | ||
1935 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLinkSupervisionTimeout, No such Handle in the Entry\n")); | ||
1936 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
1937 | return status; | ||
1938 | } | ||
1939 | |||
1940 | if (pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle != physicalLinkHandle) | ||
1941 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
1942 | |||
1943 | { | ||
1944 | u8 localBuf[10] = ""; | ||
1945 | u8 *pRetPar; | ||
1946 | u8 len = 0; | ||
1947 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
1948 | u16 *pu2Temp; | ||
1949 | |||
1950 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
1951 | |||
1952 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
1953 | OGF_SET_EVENT_MASK_COMMAND, | ||
1954 | HCI_READ_LINK_SUPERVISION_TIMEOUT, | ||
1955 | status); | ||
1956 | |||
1957 | /* Return parameters starts from here */ | ||
1958 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
1959 | pRetPar[0] = status; | ||
1960 | pRetPar[1] = pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle; | ||
1961 | pRetPar[2] = 0; | ||
1962 | pu2Temp = (u16 *)&pRetPar[3]; /* Conn_Accept_Timeout */ | ||
1963 | *pu2Temp = pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.LinkSuperversionTimeout; | ||
1964 | len += 5; | ||
1965 | PPacketIrpEvent->Length = len; | ||
1966 | |||
1967 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
1968 | } | ||
1969 | |||
1970 | return status; | ||
1971 | } | ||
1972 | |||
1973 | static enum hci_status | ||
1974 | bthci_CmdWriteLinkSupervisionTimeout( | ||
1975 | struct rtw_adapter *padapter, | ||
1976 | struct packet_irp_hcicmd_data *pHciCmd | ||
1977 | ) | ||
1978 | { | ||
1979 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
1980 | struct bt_30info *pBTinfo = GET_BT_INFO(padapter); | ||
1981 | u8 physicalLinkHandle, EntryNum; | ||
1982 | |||
1983 | physicalLinkHandle = *((u8 *)pHciCmd->Data); | ||
1984 | |||
1985 | EntryNum = bthci_GetCurrentEntryNum(padapter, physicalLinkHandle); | ||
1986 | |||
1987 | if (EntryNum == 0xff) { | ||
1988 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("WriteLinkSupervisionTimeout, No such Handle in the Entry\n")); | ||
1989 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
1990 | } else { | ||
1991 | if (pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle != physicalLinkHandle) { | ||
1992 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
1993 | } else { | ||
1994 | pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.LinkSuperversionTimeout = *((u16 *)(((u8 *)pHciCmd->Data)+2)); | ||
1995 | RTPRINT(FIOCTL, IOCTL_STATE, ("BT Write LinkSuperversionTimeout[%d] = 0x%x\n", | ||
1996 | EntryNum, pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.LinkSuperversionTimeout)); | ||
1997 | } | ||
1998 | } | ||
1999 | |||
2000 | { | ||
2001 | u8 localBuf[8] = ""; | ||
2002 | u8 *pRetPar; | ||
2003 | u8 len = 0; | ||
2004 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2005 | |||
2006 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2007 | |||
2008 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2009 | OGF_SET_EVENT_MASK_COMMAND, | ||
2010 | HCI_WRITE_LINK_SUPERVISION_TIMEOUT, | ||
2011 | status); | ||
2012 | |||
2013 | /* Return parameters starts from here */ | ||
2014 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2015 | pRetPar[0] = status; | ||
2016 | pRetPar[1] = pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle; | ||
2017 | pRetPar[2] = 0; | ||
2018 | len += 3; | ||
2019 | PPacketIrpEvent->Length = len; | ||
2020 | |||
2021 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2022 | } | ||
2023 | |||
2024 | return status; | ||
2025 | } | ||
2026 | |||
2027 | static enum hci_status | ||
2028 | bthci_CmdEnhancedFlush( | ||
2029 | struct rtw_adapter *padapter, | ||
2030 | struct packet_irp_hcicmd_data *pHciCmd | ||
2031 | ) | ||
2032 | { | ||
2033 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2034 | struct bt_30info *pBTinfo = GET_BT_INFO(padapter); | ||
2035 | struct bt_hci_info *pBtHciInfo = &pBTinfo->BtHciInfo; | ||
2036 | u16 logicHandle; | ||
2037 | u8 Packet_Type; | ||
2038 | |||
2039 | logicHandle = *((u16 *)&pHciCmd->Data[0]); | ||
2040 | Packet_Type = pHciCmd->Data[2]; | ||
2041 | |||
2042 | if (Packet_Type != 0) | ||
2043 | status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE; | ||
2044 | else | ||
2045 | pBtHciInfo->enFlush_LLH = logicHandle; | ||
2046 | |||
2047 | if (bthci_DiscardTxPackets(padapter, pBtHciInfo->enFlush_LLH)) | ||
2048 | bthci_EventFlushOccurred(padapter, pBtHciInfo->enFlush_LLH); | ||
2049 | |||
2050 | /* should send command status event */ | ||
2051 | bthci_EventCommandStatus(padapter, | ||
2052 | OGF_SET_EVENT_MASK_COMMAND, | ||
2053 | HCI_ENHANCED_FLUSH, | ||
2054 | status); | ||
2055 | |||
2056 | if (pBtHciInfo->enFlush_LLH) { | ||
2057 | bthci_EventEnhancedFlushComplete(padapter, pBtHciInfo->enFlush_LLH); | ||
2058 | pBtHciInfo->enFlush_LLH = 0; | ||
2059 | } | ||
2060 | |||
2061 | return status; | ||
2062 | } | ||
2063 | |||
2064 | static enum hci_status | ||
2065 | bthci_CmdReadLogicalLinkAcceptTimeout( | ||
2066 | struct rtw_adapter *padapter, | ||
2067 | struct packet_irp_hcicmd_data *pHciCmd | ||
2068 | ) | ||
2069 | { | ||
2070 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2071 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
2072 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2073 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
2074 | u8 localBuf[8] = ""; | ||
2075 | u8 *pRetPar; | ||
2076 | u8 len = 0; | ||
2077 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2078 | u16 *pu2Temp; | ||
2079 | |||
2080 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2081 | |||
2082 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2083 | OGF_SET_EVENT_MASK_COMMAND, | ||
2084 | HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT, | ||
2085 | status); | ||
2086 | |||
2087 | /* Return parameters starts from here */ | ||
2088 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2089 | pRetPar[0] = status; | ||
2090 | |||
2091 | pu2Temp = (u16 *)&pRetPar[1]; /* Conn_Accept_Timeout */ | ||
2092 | *pu2Temp = pBtHciInfo->LogicalAcceptTimeout; | ||
2093 | len += 3; | ||
2094 | PPacketIrpEvent->Length = len; | ||
2095 | |||
2096 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2097 | |||
2098 | return status; | ||
2099 | } | ||
2100 | |||
2101 | static enum hci_status | ||
2102 | bthci_CmdWriteLogicalLinkAcceptTimeout( | ||
2103 | struct rtw_adapter *padapter, | ||
2104 | struct packet_irp_hcicmd_data *pHciCmd | ||
2105 | ) | ||
2106 | { | ||
2107 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2108 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
2109 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2110 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
2111 | u8 localBuf[6] = ""; | ||
2112 | u8 *pRetPar; | ||
2113 | u8 len = 0; | ||
2114 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2115 | |||
2116 | pBtHciInfo->LogicalAcceptTimeout = *((u16 *)pHciCmd->Data); | ||
2117 | |||
2118 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2119 | |||
2120 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2121 | OGF_SET_EVENT_MASK_COMMAND, | ||
2122 | HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT, | ||
2123 | status); | ||
2124 | |||
2125 | /* Return parameters starts from here */ | ||
2126 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2127 | pRetPar[0] = status; | ||
2128 | |||
2129 | len += 1; | ||
2130 | PPacketIrpEvent->Length = len; | ||
2131 | |||
2132 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2133 | return status; | ||
2134 | } | ||
2135 | |||
2136 | static enum hci_status | ||
2137 | bthci_CmdSetEventMask( | ||
2138 | struct rtw_adapter *padapter, | ||
2139 | struct packet_irp_hcicmd_data *pHciCmd | ||
2140 | ) | ||
2141 | { | ||
2142 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2143 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
2144 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2145 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
2146 | u8 *pu8Temp; | ||
2147 | u8 localBuf[6] = ""; | ||
2148 | u8 *pRetPar; | ||
2149 | u8 len = 0; | ||
2150 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2151 | |||
2152 | pu8Temp = (u8 *)&pHciCmd->Data[0]; | ||
2153 | pBtHciInfo->BTEventMask = *pu8Temp; | ||
2154 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("BTEventMask = 0x%"i64fmt"x\n", | ||
2155 | pBtHciInfo->BTEventMask)); | ||
2156 | |||
2157 | /* send command complete event here when all data are received. */ | ||
2158 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2159 | |||
2160 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2161 | OGF_SET_EVENT_MASK_COMMAND, | ||
2162 | HCI_SET_EVENT_MASK, | ||
2163 | status); | ||
2164 | |||
2165 | /* Return parameters starts from here */ | ||
2166 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2167 | pRetPar[0] = status; /* status */ | ||
2168 | len += 1; | ||
2169 | PPacketIrpEvent->Length = len; | ||
2170 | |||
2171 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2172 | |||
2173 | return status; | ||
2174 | } | ||
2175 | |||
2176 | /* 7.3.69 */ | ||
2177 | static enum hci_status | ||
2178 | bthci_CmdSetEventMaskPage2( | ||
2179 | struct rtw_adapter *padapter, | ||
2180 | struct packet_irp_hcicmd_data *pHciCmd | ||
2181 | ) | ||
2182 | { | ||
2183 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2184 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2185 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
2186 | u8 *pu8Temp; | ||
2187 | u8 localBuf[6] = ""; | ||
2188 | u8 *pRetPar; | ||
2189 | u8 len = 0; | ||
2190 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2191 | |||
2192 | pu8Temp = (u8 *)&pHciCmd->Data[0]; | ||
2193 | pBtHciInfo->BTEventMaskPage2 = *pu8Temp; | ||
2194 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("BTEventMaskPage2 = 0x%"i64fmt"x\n", | ||
2195 | pBtHciInfo->BTEventMaskPage2)); | ||
2196 | |||
2197 | /* send command complete event here when all data are received. */ | ||
2198 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2199 | |||
2200 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2201 | OGF_SET_EVENT_MASK_COMMAND, | ||
2202 | HCI_SET_EVENT_MASK_PAGE_2, | ||
2203 | status); | ||
2204 | |||
2205 | /* Return parameters starts from here */ | ||
2206 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2207 | pRetPar[0] = status; /* status */ | ||
2208 | len += 1; | ||
2209 | PPacketIrpEvent->Length = len; | ||
2210 | |||
2211 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2212 | |||
2213 | return status; | ||
2214 | } | ||
2215 | |||
2216 | static enum hci_status | ||
2217 | bthci_CmdReadLocationData( | ||
2218 | struct rtw_adapter *padapter, | ||
2219 | struct packet_irp_hcicmd_data *pHciCmd | ||
2220 | ) | ||
2221 | { | ||
2222 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2223 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2224 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
2225 | u8 localBuf[12] = ""; | ||
2226 | u8 *pRetPar; | ||
2227 | u8 len = 0; | ||
2228 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2229 | u16 *pu2Temp; | ||
2230 | |||
2231 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2232 | |||
2233 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2234 | OGF_SET_EVENT_MASK_COMMAND, | ||
2235 | HCI_READ_LOCATION_DATA, | ||
2236 | status); | ||
2237 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DomainAware = 0x%x\n", pBtHciInfo->LocationDomainAware)); | ||
2238 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Domain = 0x%x\n", pBtHciInfo->LocationDomain)); | ||
2239 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DomainOptions = 0x%x\n", pBtHciInfo->LocationDomainOptions)); | ||
2240 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Options = 0x%x\n", pBtHciInfo->LocationOptions)); | ||
2241 | |||
2242 | /* Return parameters starts from here */ | ||
2243 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2244 | pRetPar[0] = status; | ||
2245 | |||
2246 | pRetPar[1] = pBtHciInfo->LocationDomainAware; /* 0x0; Location_Domain_Aware */ | ||
2247 | pu2Temp = (u16 *)&pRetPar[2]; /* Location_Domain */ | ||
2248 | *pu2Temp = pBtHciInfo->LocationDomain; /* 0x5858; */ | ||
2249 | pRetPar[4] = pBtHciInfo->LocationDomainOptions; /* 0x58; Location_Domain_Options */ | ||
2250 | pRetPar[5] = pBtHciInfo->LocationOptions; /* 0x0; Location_Options */ | ||
2251 | len += 6; | ||
2252 | PPacketIrpEvent->Length = len; | ||
2253 | |||
2254 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2255 | return status; | ||
2256 | } | ||
2257 | |||
2258 | static enum hci_status | ||
2259 | bthci_CmdWriteLocationData( | ||
2260 | struct rtw_adapter *padapter, | ||
2261 | struct packet_irp_hcicmd_data *pHciCmd | ||
2262 | ) | ||
2263 | { | ||
2264 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2265 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2266 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
2267 | u16 *pu2Temp; | ||
2268 | u8 localBuf[6] = ""; | ||
2269 | u8 *pRetPar; | ||
2270 | u8 len = 0; | ||
2271 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2272 | |||
2273 | pBtHciInfo->LocationDomainAware = pHciCmd->Data[0]; | ||
2274 | pu2Temp = (u16 *)&pHciCmd->Data[1]; | ||
2275 | pBtHciInfo->LocationDomain = *pu2Temp; | ||
2276 | pBtHciInfo->LocationDomainOptions = pHciCmd->Data[3]; | ||
2277 | pBtHciInfo->LocationOptions = pHciCmd->Data[4]; | ||
2278 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DomainAware = 0x%x\n", pBtHciInfo->LocationDomainAware)); | ||
2279 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Domain = 0x%x\n", pBtHciInfo->LocationDomain)); | ||
2280 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DomainOptions = 0x%x\n", pBtHciInfo->LocationDomainOptions)); | ||
2281 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Options = 0x%x\n", pBtHciInfo->LocationOptions)); | ||
2282 | |||
2283 | /* send command complete event here when all data are received. */ | ||
2284 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2285 | |||
2286 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2287 | OGF_SET_EVENT_MASK_COMMAND, | ||
2288 | HCI_WRITE_LOCATION_DATA, | ||
2289 | status); | ||
2290 | |||
2291 | /* Return parameters starts from here */ | ||
2292 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2293 | pRetPar[0] = status; /* status */ | ||
2294 | len += 1; | ||
2295 | PPacketIrpEvent->Length = len; | ||
2296 | |||
2297 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2298 | |||
2299 | return status; | ||
2300 | } | ||
2301 | |||
2302 | static enum hci_status | ||
2303 | bthci_CmdReadFlowControlMode( | ||
2304 | struct rtw_adapter *padapter, | ||
2305 | struct packet_irp_hcicmd_data *pHciCmd | ||
2306 | ) | ||
2307 | { | ||
2308 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2309 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2310 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
2311 | u8 localBuf[7] = ""; | ||
2312 | u8 *pRetPar; | ||
2313 | u8 len = 0; | ||
2314 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2315 | |||
2316 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2317 | |||
2318 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2319 | OGF_SET_EVENT_MASK_COMMAND, | ||
2320 | HCI_READ_FLOW_CONTROL_MODE, | ||
2321 | status); | ||
2322 | |||
2323 | /* Return parameters starts from here */ | ||
2324 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2325 | pRetPar[0] = status; | ||
2326 | pRetPar[1] = pBtHciInfo->FlowControlMode; /* Flow Control Mode */ | ||
2327 | len += 2; | ||
2328 | PPacketIrpEvent->Length = len; | ||
2329 | |||
2330 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2331 | return status; | ||
2332 | } | ||
2333 | |||
2334 | static enum hci_status | ||
2335 | bthci_CmdWriteFlowControlMode( | ||
2336 | struct rtw_adapter *padapter, | ||
2337 | struct packet_irp_hcicmd_data *pHciCmd | ||
2338 | ) | ||
2339 | { | ||
2340 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2341 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2342 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
2343 | u8 localBuf[6] = ""; | ||
2344 | u8 *pRetPar; | ||
2345 | u8 len = 0; | ||
2346 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2347 | |||
2348 | pBtHciInfo->FlowControlMode = pHciCmd->Data[0]; | ||
2349 | |||
2350 | /* send command complete event here when all data are received. */ | ||
2351 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2352 | |||
2353 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2354 | OGF_SET_EVENT_MASK_COMMAND, | ||
2355 | HCI_WRITE_FLOW_CONTROL_MODE, | ||
2356 | status); | ||
2357 | |||
2358 | /* Return parameters starts from here */ | ||
2359 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2360 | pRetPar[0] = status; /* status */ | ||
2361 | len += 1; | ||
2362 | PPacketIrpEvent->Length = len; | ||
2363 | |||
2364 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2365 | |||
2366 | return status; | ||
2367 | } | ||
2368 | |||
2369 | static enum hci_status | ||
2370 | bthci_CmdReadBestEffortFlushTimeout( | ||
2371 | struct rtw_adapter *padapter, | ||
2372 | struct packet_irp_hcicmd_data *pHciCmd | ||
2373 | ) | ||
2374 | { | ||
2375 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2376 | struct bt_30info *pBTinfo = GET_BT_INFO(padapter); | ||
2377 | u16 i, j, logicHandle; | ||
2378 | u32 BestEffortFlushTimeout = 0xffffffff; | ||
2379 | u8 find = 0; | ||
2380 | |||
2381 | logicHandle = *((u16 *)pHciCmd->Data); | ||
2382 | /* find an matched logical link index and copy the data */ | ||
2383 | for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) { | ||
2384 | for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) { | ||
2385 | if (pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle == logicHandle) { | ||
2386 | BestEffortFlushTimeout = pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BestEffortFlushTimeout; | ||
2387 | find = 1; | ||
2388 | break; | ||
2389 | } | ||
2390 | } | ||
2391 | } | ||
2392 | |||
2393 | if (!find) | ||
2394 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
2395 | |||
2396 | { | ||
2397 | u8 localBuf[10] = ""; | ||
2398 | u8 *pRetPar; | ||
2399 | u8 len = 0; | ||
2400 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2401 | u32 *pu4Temp; | ||
2402 | |||
2403 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2404 | |||
2405 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2406 | OGF_SET_EVENT_MASK_COMMAND, | ||
2407 | HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT, | ||
2408 | status); | ||
2409 | |||
2410 | /* Return parameters starts from here */ | ||
2411 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2412 | pRetPar[0] = status; | ||
2413 | pu4Temp = (u32 *)&pRetPar[1]; /* Best_Effort_Flush_Timeout */ | ||
2414 | *pu4Temp = BestEffortFlushTimeout; | ||
2415 | len += 5; | ||
2416 | PPacketIrpEvent->Length = len; | ||
2417 | |||
2418 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2419 | } | ||
2420 | return status; | ||
2421 | } | ||
2422 | |||
2423 | static enum hci_status | ||
2424 | bthci_CmdWriteBestEffortFlushTimeout( | ||
2425 | struct rtw_adapter *padapter, | ||
2426 | struct packet_irp_hcicmd_data *pHciCmd | ||
2427 | ) | ||
2428 | { | ||
2429 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2430 | struct bt_30info *pBTinfo = GET_BT_INFO(padapter); | ||
2431 | u16 i, j, logicHandle; | ||
2432 | u32 BestEffortFlushTimeout = 0xffffffff; | ||
2433 | u8 find = 0; | ||
2434 | |||
2435 | logicHandle = *((u16 *)pHciCmd->Data); | ||
2436 | BestEffortFlushTimeout = *((u32 *)(pHciCmd->Data+1)); | ||
2437 | |||
2438 | /* find an matched logical link index and copy the data */ | ||
2439 | for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) { | ||
2440 | for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) { | ||
2441 | if (pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle == logicHandle) { | ||
2442 | pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BestEffortFlushTimeout = BestEffortFlushTimeout; | ||
2443 | find = 1; | ||
2444 | break; | ||
2445 | } | ||
2446 | } | ||
2447 | } | ||
2448 | |||
2449 | if (!find) | ||
2450 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
2451 | |||
2452 | { | ||
2453 | u8 localBuf[6] = ""; | ||
2454 | u8 *pRetPar; | ||
2455 | u8 len = 0; | ||
2456 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2457 | |||
2458 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2459 | |||
2460 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2461 | OGF_SET_EVENT_MASK_COMMAND, | ||
2462 | HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT, | ||
2463 | status); | ||
2464 | |||
2465 | /* Return parameters starts from here */ | ||
2466 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2467 | pRetPar[0] = status; | ||
2468 | len += 1; | ||
2469 | PPacketIrpEvent->Length = len; | ||
2470 | |||
2471 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2472 | } | ||
2473 | return status; | ||
2474 | } | ||
2475 | |||
2476 | static enum hci_status | ||
2477 | bthci_CmdShortRangeMode( | ||
2478 | struct rtw_adapter *padapter, | ||
2479 | struct packet_irp_hcicmd_data *pHciCmd | ||
2480 | ) | ||
2481 | { | ||
2482 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2483 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2484 | u8 PhyLinkHandle, EntryNum, ShortRangeMode; | ||
2485 | |||
2486 | PhyLinkHandle = pHciCmd->Data[0]; | ||
2487 | ShortRangeMode = pHciCmd->Data[1]; | ||
2488 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("PLH = 0x%x, Short_Range_Mode = 0x%x\n", PhyLinkHandle, ShortRangeMode)); | ||
2489 | |||
2490 | EntryNum = bthci_GetCurrentEntryNum(padapter, PhyLinkHandle); | ||
2491 | if (EntryNum != 0xff) { | ||
2492 | pBTInfo->BtAsocEntry[EntryNum].ShortRangeMode = ShortRangeMode; | ||
2493 | } else { | ||
2494 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("No such PLH(0x%x)\n", PhyLinkHandle)); | ||
2495 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
2496 | } | ||
2497 | |||
2498 | bthci_EventCommandStatus(padapter, | ||
2499 | OGF_SET_EVENT_MASK_COMMAND, | ||
2500 | HCI_SHORT_RANGE_MODE, | ||
2501 | status); | ||
2502 | |||
2503 | bthci_EventShortRangeModeChangeComplete(padapter, status, ShortRangeMode, EntryNum); | ||
2504 | |||
2505 | return status; | ||
2506 | } | ||
2507 | |||
2508 | static enum hci_status bthci_CmdReadLocalSupportedCommands(struct rtw_adapter *padapter) | ||
2509 | { | ||
2510 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2511 | u8 localBuf[TmpLocalBufSize] = ""; | ||
2512 | u8 *pRetPar, *pSupportedCmds; | ||
2513 | u8 len = 0; | ||
2514 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2515 | |||
2516 | /* send command complete event here when all data are received. */ | ||
2517 | PlatformZeroMemory(&localBuf[0], TmpLocalBufSize); | ||
2518 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2519 | |||
2520 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2521 | OGF_INFORMATIONAL_PARAMETERS, | ||
2522 | HCI_READ_LOCAL_SUPPORTED_COMMANDS, | ||
2523 | status); | ||
2524 | |||
2525 | /* Return parameters starts from here */ | ||
2526 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2527 | pRetPar[0] = status; /* status */ | ||
2528 | len += 1; | ||
2529 | pSupportedCmds = &pRetPar[1]; | ||
2530 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[5]= 0xc0\nBit [6]= Set Event Mask, [7]= Reset\n")); | ||
2531 | pSupportedCmds[5] = 0xc0; | ||
2532 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[6]= 0x01\nBit [0]= Set Event Filter\n")); | ||
2533 | pSupportedCmds[6] = 0x01; | ||
2534 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[7]= 0x0c\nBit [2]= Read Connection Accept Timeout, [3]= Write Connection Accept Timeout\n")); | ||
2535 | pSupportedCmds[7] = 0x0c; | ||
2536 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[10]= 0x80\nBit [7]= Host Number Of Completed Packets\n")); | ||
2537 | pSupportedCmds[10] = 0x80; | ||
2538 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[11]= 0x03\nBit [0]= Read Link Supervision Timeout, [1]= Write Link Supervision Timeout\n")); | ||
2539 | pSupportedCmds[11] = 0x03; | ||
2540 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[14]= 0xa8\nBit [3]= Read Local Version Information, [5]= Read Local Supported Features, [7]= Read Buffer Size\n")); | ||
2541 | pSupportedCmds[14] = 0xa8; | ||
2542 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[15]= 0x1c\nBit [2]= Read Failed Contact Count, [3]= Reset Failed Contact Count, [4]= Get Link Quality\n")); | ||
2543 | pSupportedCmds[15] = 0x1c; | ||
2544 | /* pSupportedCmds[16] = 0x04; */ | ||
2545 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[19]= 0x40\nBit [6]= Enhanced Flush\n")); | ||
2546 | pSupportedCmds[19] = 0x40; | ||
2547 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[21]= 0xff\nBit [0]= Create Physical Link, [1]= Accept Physical Link, [2]= Disconnect Physical Link, [3]= Create Logical Link\n")); | ||
2548 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), (" [4]= Accept Logical Link, [5]= Disconnect Logical Link, [6]= Logical Link Cancel, [7]= Flow Spec Modify\n")); | ||
2549 | pSupportedCmds[21] = 0xff; | ||
2550 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[22]= 0xff\nBit [0]= Read Logical Link Accept Timeout, [1]= Write Logical Link Accept Timeout, [2]= Set Event Mask Page 2, [3]= Read Location Data\n")); | ||
2551 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), (" [4]= Write Location Data, [5]= Read Local AMP Info, [6]= Read Local AMP_ASSOC, [7]= Write Remote AMP_ASSOC\n")); | ||
2552 | pSupportedCmds[22] = 0xff; | ||
2553 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[23]= 0x07\nBit [0]= Read Flow Control Mode, [1]= Write Flow Control Mode, [2]= Read Data Block Size\n")); | ||
2554 | pSupportedCmds[23] = 0x07; | ||
2555 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[24]= 0x1c\nBit [2]= Read Best Effort Flush Timeout, [3]= Write Best Effort Flush Timeout, [4]= Short Range Mode\n")); | ||
2556 | pSupportedCmds[24] = 0x1c; | ||
2557 | len += 64; | ||
2558 | PPacketIrpEvent->Length = len; | ||
2559 | |||
2560 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2561 | |||
2562 | return status; | ||
2563 | } | ||
2564 | |||
2565 | static enum hci_status bthci_CmdReadLocalSupportedFeatures(struct rtw_adapter *padapter) | ||
2566 | { | ||
2567 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2568 | u8 localBuf[TmpLocalBufSize] = ""; | ||
2569 | u8 *pRetPar; | ||
2570 | u8 len = 0; | ||
2571 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2572 | |||
2573 | /* send command complete event here when all data are received. */ | ||
2574 | PlatformZeroMemory(&localBuf[0], TmpLocalBufSize); | ||
2575 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2576 | |||
2577 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2578 | OGF_INFORMATIONAL_PARAMETERS, | ||
2579 | HCI_READ_LOCAL_SUPPORTED_FEATURES, | ||
2580 | status); | ||
2581 | |||
2582 | /* Return parameters starts from here */ | ||
2583 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2584 | pRetPar[0] = status; /* status */ | ||
2585 | len += 9; | ||
2586 | PPacketIrpEvent->Length = len; | ||
2587 | |||
2588 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2589 | return status; | ||
2590 | } | ||
2591 | |||
2592 | static enum hci_status bthci_CmdReadLocalAMPAssoc(struct rtw_adapter *padapter, | ||
2593 | struct packet_irp_hcicmd_data *pHciCmd) | ||
2594 | { | ||
2595 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2596 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2597 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
2598 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
2599 | u8 PhyLinkHandle, EntryNum; | ||
2600 | |||
2601 | pBtDbg->dbgHciInfo.hciCmdCntReadLocalAmpAssoc++; | ||
2602 | PhyLinkHandle = *((u8 *)pHciCmd->Data); | ||
2603 | EntryNum = bthci_GetCurrentEntryNum(padapter, PhyLinkHandle); | ||
2604 | |||
2605 | if ((EntryNum == 0xff) && PhyLinkHandle != 0) { | ||
2606 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLocalAMPAssoc, EntryNum = %d !!!!!, physical link handle = 0x%x\n", | ||
2607 | EntryNum, PhyLinkHandle)); | ||
2608 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
2609 | } else if (pBtMgnt->bPhyLinkInProgressStartLL) { | ||
2610 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
2611 | pBtMgnt->bPhyLinkInProgressStartLL = false; | ||
2612 | } else { | ||
2613 | pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.BtPhyLinkhandle = *((u8 *)pHciCmd->Data); | ||
2614 | pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar = *((u16 *)((u8 *)pHciCmd->Data+1)); | ||
2615 | pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.MaxRemoteASSOCLen = *((u16 *)((u8 *)pHciCmd->Data+3)); | ||
2616 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("ReadLocalAMPAssoc, LenSoFar =%d, MaxRemoteASSOCLen =%d\n", | ||
2617 | pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar, | ||
2618 | pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.MaxRemoteASSOCLen)); | ||
2619 | } | ||
2620 | |||
2621 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLocalAMPAssoc, EntryNum = %d !!!!!, physical link handle = 0x%x, LengthSoFar = %x \n", | ||
2622 | EntryNum, PhyLinkHandle, pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar)); | ||
2623 | |||
2624 | /* send command complete event here when all data are received. */ | ||
2625 | { | ||
2626 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2627 | |||
2628 | /* PVOID buffer = padapter->IrpHCILocalbuf.Ptr; */ | ||
2629 | u8 localBuf[TmpLocalBufSize] = ""; | ||
2630 | u16 *pRemainLen; | ||
2631 | u32 totalLen = 0; | ||
2632 | u16 typeLen = 0, remainLen = 0, ret_index = 0; | ||
2633 | u8 *pRetPar; | ||
2634 | |||
2635 | PlatformZeroMemory(&localBuf[0], TmpLocalBufSize); | ||
2636 | /* PPacketIrpEvent = (struct packet_irp_hcievent_data *)(buffer); */ | ||
2637 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2638 | |||
2639 | totalLen += bthci_CommandCompleteHeader(&localBuf[0], | ||
2640 | OGF_STATUS_PARAMETERS, | ||
2641 | HCI_READ_LOCAL_AMP_ASSOC, | ||
2642 | status); | ||
2643 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLocalAMPAssoc, Remaining_Len =%d \n", remainLen)); | ||
2644 | /* Return parameters starts from here */ | ||
2645 | pRetPar = &PPacketIrpEvent->Data[totalLen]; | ||
2646 | pRetPar[0] = status; /* status */ | ||
2647 | pRetPar[1] = *((u8 *)pHciCmd->Data); | ||
2648 | pRemainLen = (u16 *)&pRetPar[2]; /* AMP_ASSOC_Remaining_Length */ | ||
2649 | totalLen += 4; /* 0]~[3] */ | ||
2650 | ret_index = 4; | ||
2651 | |||
2652 | typeLen = bthci_AssocMACAddr(padapter, &pRetPar[ret_index]); | ||
2653 | totalLen += typeLen; | ||
2654 | remainLen += typeLen; | ||
2655 | ret_index += typeLen; | ||
2656 | typeLen = bthci_AssocPreferredChannelList(padapter, &pRetPar[ret_index], EntryNum); | ||
2657 | totalLen += typeLen; | ||
2658 | remainLen += typeLen; | ||
2659 | ret_index += typeLen; | ||
2660 | typeLen = bthci_PALCapabilities(padapter, &pRetPar[ret_index]); | ||
2661 | totalLen += typeLen; | ||
2662 | remainLen += typeLen; | ||
2663 | ret_index += typeLen; | ||
2664 | typeLen = bthci_AssocPALVer(padapter, &pRetPar[ret_index]); | ||
2665 | totalLen += typeLen; | ||
2666 | remainLen += typeLen; | ||
2667 | PPacketIrpEvent->Length = (u8)totalLen; | ||
2668 | *pRemainLen = remainLen; /* AMP_ASSOC_Remaining_Length */ | ||
2669 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLocalAMPAssoc, Remaining_Len =%d \n", remainLen)); | ||
2670 | RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("AMP_ASSOC_fragment : \n"), PPacketIrpEvent->Data, totalLen); | ||
2671 | |||
2672 | bthci_IndicateEvent(padapter, PPacketIrpEvent, totalLen+2); | ||
2673 | } | ||
2674 | |||
2675 | return status; | ||
2676 | } | ||
2677 | |||
2678 | static enum hci_status bthci_CmdReadFailedContactCounter(struct rtw_adapter *padapter, | ||
2679 | struct packet_irp_hcicmd_data *pHciCmd) | ||
2680 | { | ||
2681 | |||
2682 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2683 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2684 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
2685 | u8 localBuf[TmpLocalBufSize] = ""; | ||
2686 | u8 *pRetPar; | ||
2687 | u8 len = 0; | ||
2688 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2689 | u16 handle; | ||
2690 | |||
2691 | handle = *((u16 *)pHciCmd->Data); | ||
2692 | /* send command complete event here when all data are received. */ | ||
2693 | PlatformZeroMemory(&localBuf[0], TmpLocalBufSize); | ||
2694 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2695 | |||
2696 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2697 | OGF_STATUS_PARAMETERS, | ||
2698 | HCI_READ_FAILED_CONTACT_COUNTER, | ||
2699 | status); | ||
2700 | |||
2701 | /* Return parameters starts from here */ | ||
2702 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2703 | pRetPar[0] = status; /* status */ | ||
2704 | pRetPar[1] = TWOBYTE_LOWBYTE(handle); | ||
2705 | pRetPar[2] = TWOBYTE_HIGHTBYTE(handle); | ||
2706 | pRetPar[3] = TWOBYTE_LOWBYTE(pBtHciInfo->FailContactCount); | ||
2707 | pRetPar[4] = TWOBYTE_HIGHTBYTE(pBtHciInfo->FailContactCount); | ||
2708 | len += 5; | ||
2709 | PPacketIrpEvent->Length = len; | ||
2710 | |||
2711 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2712 | |||
2713 | return status; | ||
2714 | } | ||
2715 | |||
2716 | static enum hci_status | ||
2717 | bthci_CmdResetFailedContactCounter( | ||
2718 | struct rtw_adapter *padapter, | ||
2719 | struct packet_irp_hcicmd_data *pHciCmd | ||
2720 | ) | ||
2721 | { | ||
2722 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2723 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
2724 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2725 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
2726 | u16 handle; | ||
2727 | u8 localBuf[TmpLocalBufSize] = ""; | ||
2728 | u8 *pRetPar; | ||
2729 | u8 len = 0; | ||
2730 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2731 | |||
2732 | handle = *((u16 *)pHciCmd->Data); | ||
2733 | pBtHciInfo->FailContactCount = 0; | ||
2734 | |||
2735 | /* send command complete event here when all data are received. */ | ||
2736 | PlatformZeroMemory(&localBuf[0], TmpLocalBufSize); | ||
2737 | /* PPacketIrpEvent = (struct packet_irp_hcievent_data *)(buffer); */ | ||
2738 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2739 | |||
2740 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2741 | OGF_STATUS_PARAMETERS, | ||
2742 | HCI_RESET_FAILED_CONTACT_COUNTER, | ||
2743 | status); | ||
2744 | |||
2745 | /* Return parameters starts from here */ | ||
2746 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2747 | pRetPar[0] = status; /* status */ | ||
2748 | pRetPar[1] = TWOBYTE_LOWBYTE(handle); | ||
2749 | pRetPar[2] = TWOBYTE_HIGHTBYTE(handle); | ||
2750 | len += 3; | ||
2751 | PPacketIrpEvent->Length = len; | ||
2752 | |||
2753 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2754 | return status; | ||
2755 | } | ||
2756 | |||
2757 | /* */ | ||
2758 | /* BT 3.0+HS [Vol 2] 7.4.1 */ | ||
2759 | /* */ | ||
2760 | static enum hci_status | ||
2761 | bthci_CmdReadLocalVersionInformation( | ||
2762 | struct rtw_adapter *padapter | ||
2763 | ) | ||
2764 | { | ||
2765 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2766 | /* send command complete event here when all data are received. */ | ||
2767 | u8 localBuf[TmpLocalBufSize] = ""; | ||
2768 | u8 *pRetPar; | ||
2769 | u8 len = 0; | ||
2770 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2771 | u16 *pu2Temp; | ||
2772 | |||
2773 | PlatformZeroMemory(&localBuf[0], TmpLocalBufSize); | ||
2774 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2775 | |||
2776 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2777 | OGF_INFORMATIONAL_PARAMETERS, | ||
2778 | HCI_READ_LOCAL_VERSION_INFORMATION, | ||
2779 | status); | ||
2780 | |||
2781 | /* Return parameters starts from here */ | ||
2782 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2783 | pRetPar[0] = status; /* status */ | ||
2784 | pRetPar[1] = 0x05; /* HCI_Version */ | ||
2785 | pu2Temp = (u16 *)&pRetPar[2]; /* HCI_Revision */ | ||
2786 | *pu2Temp = 0x0001; | ||
2787 | pRetPar[4] = 0x05; /* LMP/PAL_Version */ | ||
2788 | pu2Temp = (u16 *)&pRetPar[5]; /* Manufacturer_Name */ | ||
2789 | *pu2Temp = 0x005d; | ||
2790 | pu2Temp = (u16 *)&pRetPar[7]; /* LMP/PAL_Subversion */ | ||
2791 | *pu2Temp = 0x0001; | ||
2792 | len += 9; | ||
2793 | PPacketIrpEvent->Length = len; | ||
2794 | |||
2795 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("LOCAL_VERSION_INFORMATION\n")); | ||
2796 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("Status %x\n", status)); | ||
2797 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("HCI_Version = 0x05\n")); | ||
2798 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("HCI_Revision = 0x0001\n")); | ||
2799 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("LMP/PAL_Version = 0x05\n")); | ||
2800 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("Manufacturer_Name = 0x0001\n")); | ||
2801 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("LMP/PAL_Subversion = 0x0001\n")); | ||
2802 | |||
2803 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2804 | |||
2805 | return status; | ||
2806 | } | ||
2807 | |||
2808 | /* 7.4.7 */ | ||
2809 | static enum hci_status bthci_CmdReadDataBlockSize(struct rtw_adapter *padapter) | ||
2810 | { | ||
2811 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2812 | u8 localBuf[TmpLocalBufSize] = ""; | ||
2813 | u8 *pRetPar; | ||
2814 | u8 len = 0; | ||
2815 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2816 | u16 *pu2Temp; | ||
2817 | |||
2818 | PlatformZeroMemory(&localBuf[0], TmpLocalBufSize); | ||
2819 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2820 | |||
2821 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2822 | OGF_INFORMATIONAL_PARAMETERS, | ||
2823 | HCI_READ_DATA_BLOCK_SIZE, | ||
2824 | status); | ||
2825 | |||
2826 | /* Return parameters starts from here */ | ||
2827 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2828 | pRetPar[0] = HCI_STATUS_SUCCESS; /* status */ | ||
2829 | pu2Temp = (u16 *)&pRetPar[1]; /* Max_ACL_Data_Packet_Length */ | ||
2830 | *pu2Temp = Max80211PALPDUSize; | ||
2831 | |||
2832 | pu2Temp = (u16 *)&pRetPar[3]; /* Data_Block_Length */ | ||
2833 | *pu2Temp = Max80211PALPDUSize; | ||
2834 | pu2Temp = (u16 *)&pRetPar[5]; /* Total_Num_Data_Blocks */ | ||
2835 | *pu2Temp = BTTotalDataBlockNum; | ||
2836 | len += 7; | ||
2837 | PPacketIrpEvent->Length = len; | ||
2838 | |||
2839 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2840 | |||
2841 | return status; | ||
2842 | } | ||
2843 | |||
2844 | /* 7.4.5 */ | ||
2845 | static enum hci_status bthci_CmdReadBufferSize(struct rtw_adapter *padapter) | ||
2846 | { | ||
2847 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2848 | u8 localBuf[TmpLocalBufSize] = ""; | ||
2849 | u8 *pRetPar; | ||
2850 | u8 len = 0; | ||
2851 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2852 | u16 *pu2Temp; | ||
2853 | |||
2854 | PlatformZeroMemory(&localBuf[0], TmpLocalBufSize); | ||
2855 | /* PPacketIrpEvent = (struct packet_irp_hcievent_data *)(buffer); */ | ||
2856 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2857 | |||
2858 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2859 | OGF_INFORMATIONAL_PARAMETERS, | ||
2860 | HCI_READ_BUFFER_SIZE, | ||
2861 | status); | ||
2862 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Synchronous_Data_Packet_Length = 0x%x\n", BTSynDataPacketLength)); | ||
2863 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Total_Num_ACL_Data_Packets = 0x%x\n", BTTotalDataBlockNum)); | ||
2864 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Total_Num_Synchronous_Data_Packets = 0x%x\n", BTTotalDataBlockNum)); | ||
2865 | /* Return parameters starts from here */ | ||
2866 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2867 | pRetPar[0] = status; /* status */ | ||
2868 | pu2Temp = (u16 *)&pRetPar[1]; /* HC_ACL_Data_Packet_Length */ | ||
2869 | *pu2Temp = Max80211PALPDUSize; | ||
2870 | |||
2871 | pRetPar[3] = BTSynDataPacketLength; /* HC_Synchronous_Data_Packet_Length */ | ||
2872 | pu2Temp = (u16 *)&pRetPar[4]; /* HC_Total_Num_ACL_Data_Packets */ | ||
2873 | *pu2Temp = BTTotalDataBlockNum; | ||
2874 | pu2Temp = (u16 *)&pRetPar[6]; /* HC_Total_Num_Synchronous_Data_Packets */ | ||
2875 | *pu2Temp = BTTotalDataBlockNum; | ||
2876 | len += 8; | ||
2877 | PPacketIrpEvent->Length = len; | ||
2878 | |||
2879 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2880 | |||
2881 | return status; | ||
2882 | } | ||
2883 | |||
2884 | static enum hci_status bthci_CmdReadLocalAMPInfo(struct rtw_adapter *padapter) | ||
2885 | { | ||
2886 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2887 | struct pwrctrl_priv *ppwrctrl = &padapter->pwrctrlpriv; | ||
2888 | u8 localBuf[TmpLocalBufSize] = ""; | ||
2889 | u8 *pRetPar; | ||
2890 | u8 len = 0; | ||
2891 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2892 | u16 *pu2Temp; | ||
2893 | u32 *pu4Temp; | ||
2894 | u32 TotalBandwidth = BTTOTALBANDWIDTH, MaxBandGUBandwidth = BTMAXBANDGUBANDWIDTH; | ||
2895 | u8 ControlType = 0x01, AmpStatus = 0x01; | ||
2896 | u32 MaxFlushTimeout = 10000, BestEffortFlushTimeout = 5000; | ||
2897 | u16 MaxPDUSize = Max80211PALPDUSize, PalCap = 0x1, AmpAssocLen = Max80211AMPASSOCLen, MinLatency = 20; | ||
2898 | |||
2899 | if ((ppwrctrl->rfoff_reason & RF_CHANGE_BY_HW) || | ||
2900 | (ppwrctrl->rfoff_reason & RF_CHANGE_BY_SW)) { | ||
2901 | AmpStatus = AMP_STATUS_NO_CAPACITY_FOR_BT; | ||
2902 | } | ||
2903 | |||
2904 | PlatformZeroMemory(&localBuf[0], TmpLocalBufSize); | ||
2905 | /* PPacketIrpEvent = (struct packet_irp_hcievent_data *)(buffer); */ | ||
2906 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2907 | |||
2908 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2909 | OGF_STATUS_PARAMETERS, | ||
2910 | HCI_READ_LOCAL_AMP_INFO, | ||
2911 | status); | ||
2912 | |||
2913 | /* Return parameters starts from here */ | ||
2914 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
2915 | pRetPar[0] = status; /* status */ | ||
2916 | pRetPar[1] = AmpStatus; /* AMP_Status */ | ||
2917 | pu4Temp = (u32 *)&pRetPar[2]; /* Total_Bandwidth */ | ||
2918 | *pu4Temp = TotalBandwidth; /* 0x19bfcc00;0x7530; */ | ||
2919 | pu4Temp = (u32 *)&pRetPar[6]; /* Max_Guaranteed_Bandwidth */ | ||
2920 | *pu4Temp = MaxBandGUBandwidth; /* 0x19bfcc00;0x4e20; */ | ||
2921 | pu4Temp = (u32 *)&pRetPar[10]; /* Min_Latency */ | ||
2922 | *pu4Temp = MinLatency; /* 150; */ | ||
2923 | pu4Temp = (u32 *)&pRetPar[14]; /* Max_PDU_Size */ | ||
2924 | *pu4Temp = MaxPDUSize; | ||
2925 | pRetPar[18] = ControlType; /* Controller_Type */ | ||
2926 | pu2Temp = (u16 *)&pRetPar[19]; /* PAL_Capabilities */ | ||
2927 | *pu2Temp = PalCap; | ||
2928 | pu2Temp = (u16 *)&pRetPar[21]; /* AMP_ASSOC_Length */ | ||
2929 | *pu2Temp = AmpAssocLen; | ||
2930 | pu4Temp = (u32 *)&pRetPar[23]; /* Max_Flush_Timeout */ | ||
2931 | *pu4Temp = MaxFlushTimeout; | ||
2932 | pu4Temp = (u32 *)&pRetPar[27]; /* Best_Effort_Flush_Timeout */ | ||
2933 | *pu4Temp = BestEffortFlushTimeout; | ||
2934 | len += 31; | ||
2935 | PPacketIrpEvent->Length = len; | ||
2936 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("AmpStatus = 0x%x\n", | ||
2937 | AmpStatus)); | ||
2938 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("TotalBandwidth = 0x%x, MaxBandGUBandwidth = 0x%x, MinLatency = 0x%x, \n MaxPDUSize = 0x%x, ControlType = 0x%x\n", | ||
2939 | TotalBandwidth, MaxBandGUBandwidth, MinLatency, MaxPDUSize, ControlType)); | ||
2940 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("PalCap = 0x%x, AmpAssocLen = 0x%x, MaxFlushTimeout = 0x%x, BestEffortFlushTimeout = 0x%x\n", | ||
2941 | PalCap, AmpAssocLen, MaxFlushTimeout, BestEffortFlushTimeout)); | ||
2942 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
2943 | return status; | ||
2944 | } | ||
2945 | |||
2946 | static enum hci_status | ||
2947 | bthci_CmdCreatePhysicalLink( | ||
2948 | struct rtw_adapter *padapter, | ||
2949 | struct packet_irp_hcicmd_data *pHciCmd | ||
2950 | ) | ||
2951 | { | ||
2952 | enum hci_status status; | ||
2953 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2954 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
2955 | |||
2956 | pBtDbg->dbgHciInfo.hciCmdCntCreatePhyLink++; | ||
2957 | |||
2958 | status = bthci_BuildPhysicalLink(padapter, | ||
2959 | pHciCmd, HCI_CREATE_PHYSICAL_LINK); | ||
2960 | |||
2961 | return status; | ||
2962 | } | ||
2963 | |||
2964 | static enum hci_status | ||
2965 | bthci_CmdReadLinkQuality( | ||
2966 | struct rtw_adapter *padapter, | ||
2967 | struct packet_irp_hcicmd_data *pHciCmd | ||
2968 | ) | ||
2969 | { | ||
2970 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
2971 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
2972 | u16 PLH; | ||
2973 | u8 EntryNum, LinkQuality = 0x55; | ||
2974 | |||
2975 | PLH = *((u16 *)&pHciCmd->Data[0]); | ||
2976 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("PLH = 0x%x\n", PLH)); | ||
2977 | |||
2978 | EntryNum = bthci_GetCurrentEntryNum(padapter, (u8)PLH); | ||
2979 | if (EntryNum == 0xff) { | ||
2980 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("No such PLH(0x%x)\n", PLH)); | ||
2981 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
2982 | } | ||
2983 | |||
2984 | { | ||
2985 | u8 localBuf[11] = ""; | ||
2986 | u8 *pRetPar; | ||
2987 | u8 len = 0; | ||
2988 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
2989 | |||
2990 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
2991 | |||
2992 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
2993 | OGF_STATUS_PARAMETERS, | ||
2994 | HCI_READ_LINK_QUALITY, | ||
2995 | status); | ||
2996 | |||
2997 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, (" PLH = 0x%x\n Link Quality = 0x%x\n", PLH, LinkQuality)); | ||
2998 | |||
2999 | /* Return parameters starts from here */ | ||
3000 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3001 | pRetPar[0] = status; /* status */ | ||
3002 | *((u16 *)&pRetPar[1]) = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle; /* Handle */ | ||
3003 | pRetPar[3] = 0x55; /* Link Quailty */ | ||
3004 | len += 4; | ||
3005 | PPacketIrpEvent->Length = len; | ||
3006 | |||
3007 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3008 | } | ||
3009 | |||
3010 | return status; | ||
3011 | } | ||
3012 | |||
3013 | static enum hci_status bthci_CmdReadRSSI(struct rtw_adapter *padapter) | ||
3014 | { | ||
3015 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3016 | return status; | ||
3017 | } | ||
3018 | |||
3019 | static enum hci_status | ||
3020 | bthci_CmdCreateLogicalLink( | ||
3021 | struct rtw_adapter *padapter, | ||
3022 | struct packet_irp_hcicmd_data *pHciCmd | ||
3023 | ) | ||
3024 | { | ||
3025 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3026 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3027 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
3028 | |||
3029 | pBtDbg->dbgHciInfo.hciCmdCntCreateLogLink++; | ||
3030 | |||
3031 | bthci_BuildLogicalLink(padapter, pHciCmd, | ||
3032 | HCI_CREATE_LOGICAL_LINK); | ||
3033 | |||
3034 | return status; | ||
3035 | } | ||
3036 | |||
3037 | static enum hci_status | ||
3038 | bthci_CmdAcceptLogicalLink( | ||
3039 | struct rtw_adapter *padapter, | ||
3040 | struct packet_irp_hcicmd_data *pHciCmd | ||
3041 | ) | ||
3042 | { | ||
3043 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3044 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3045 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
3046 | |||
3047 | pBtDbg->dbgHciInfo.hciCmdCntAcceptLogLink++; | ||
3048 | |||
3049 | bthci_BuildLogicalLink(padapter, pHciCmd, | ||
3050 | HCI_ACCEPT_LOGICAL_LINK); | ||
3051 | |||
3052 | return status; | ||
3053 | } | ||
3054 | |||
3055 | static enum hci_status | ||
3056 | bthci_CmdDisconnectLogicalLink( | ||
3057 | struct rtw_adapter *padapter, | ||
3058 | struct packet_irp_hcicmd_data *pHciCmd | ||
3059 | ) | ||
3060 | { | ||
3061 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3062 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
3063 | struct bt_30info *pBTinfo = GET_BT_INFO(padapter); | ||
3064 | struct bt_mgnt *pBtMgnt = &pBTinfo->BtMgnt; | ||
3065 | struct bt_dgb *pBtDbg = &pBTinfo->BtDbg; | ||
3066 | u16 logicHandle; | ||
3067 | u8 i, j, find = 0, LogLinkCount = 0; | ||
3068 | |||
3069 | pBtDbg->dbgHciInfo.hciCmdCntDisconnectLogLink++; | ||
3070 | |||
3071 | logicHandle = *((u16 *)pHciCmd->Data); | ||
3072 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DisconnectLogicalLink, logicHandle = 0x%x\n", logicHandle)); | ||
3073 | |||
3074 | /* find an created logical link index and clear the data */ | ||
3075 | for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) { | ||
3076 | for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) { | ||
3077 | if (pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle == logicHandle) { | ||
3078 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DisconnectLogicalLink, logicHandle is matched 0x%x\n", logicHandle)); | ||
3079 | bthci_ResetFlowSpec(padapter, j, i); | ||
3080 | find = 1; | ||
3081 | pBtMgnt->DisconnectEntryNum = j; | ||
3082 | break; | ||
3083 | } | ||
3084 | } | ||
3085 | } | ||
3086 | |||
3087 | if (!find) | ||
3088 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
3089 | |||
3090 | /* To check each */ | ||
3091 | for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) { | ||
3092 | if (pBTinfo->BtAsocEntry[pBtMgnt->DisconnectEntryNum].LogLinkCmdData[i].BtLogLinkhandle != 0) | ||
3093 | LogLinkCount++; | ||
3094 | } | ||
3095 | |||
3096 | /* When we receive Create logical link command, we should send command status event first. */ | ||
3097 | bthci_EventCommandStatus(padapter, | ||
3098 | LINK_CONTROL_COMMANDS, | ||
3099 | HCI_DISCONNECT_LOGICAL_LINK, | ||
3100 | status); | ||
3101 | /* */ | ||
3102 | /* When we determines the logical link is established, we should send command complete event. */ | ||
3103 | /* */ | ||
3104 | if (status == HCI_STATUS_SUCCESS) { | ||
3105 | bthci_EventDisconnectLogicalLinkComplete(padapter, status, | ||
3106 | logicHandle, HCI_STATUS_CONNECT_TERMINATE_LOCAL_HOST); | ||
3107 | } | ||
3108 | |||
3109 | if (LogLinkCount == 0) | ||
3110 | mod_timer(&pBTinfo->BTDisconnectPhyLinkTimer, | ||
3111 | jiffies + msecs_to_jiffies(100)); | ||
3112 | |||
3113 | return status; | ||
3114 | } | ||
3115 | |||
3116 | static enum hci_status | ||
3117 | bthci_CmdLogicalLinkCancel(struct rtw_adapter *padapter, | ||
3118 | struct packet_irp_hcicmd_data *pHciCmd) | ||
3119 | { | ||
3120 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3121 | struct bt_30info *pBTinfo = GET_BT_INFO(padapter); | ||
3122 | struct bt_mgnt *pBtMgnt = &pBTinfo->BtMgnt; | ||
3123 | u8 CurrentEntryNum, CurrentLogEntryNum; | ||
3124 | |||
3125 | u8 physicalLinkHandle, TxFlowSpecID, i; | ||
3126 | u16 CurrentLogicalHandle; | ||
3127 | |||
3128 | physicalLinkHandle = *((u8 *)pHciCmd->Data); | ||
3129 | TxFlowSpecID = *(((u8 *)pHciCmd->Data)+1); | ||
3130 | |||
3131 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("LogicalLinkCancel, physicalLinkHandle = 0x%x, TxFlowSpecID = 0x%x\n", | ||
3132 | physicalLinkHandle, TxFlowSpecID)); | ||
3133 | |||
3134 | CurrentEntryNum = pBtMgnt->CurrentConnectEntryNum; | ||
3135 | CurrentLogicalHandle = pBtMgnt->BtCurrentLogLinkhandle; | ||
3136 | |||
3137 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("CurrentEntryNum = 0x%x, CurrentLogicalHandle = 0x%x\n", | ||
3138 | CurrentEntryNum, CurrentLogicalHandle)); | ||
3139 | |||
3140 | CurrentLogEntryNum = 0xff; | ||
3141 | for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) { | ||
3142 | if ((CurrentLogicalHandle == pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[i].BtLogLinkhandle) && | ||
3143 | (physicalLinkHandle == pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[i].BtPhyLinkhandle)) { | ||
3144 | CurrentLogEntryNum = i; | ||
3145 | break; | ||
3146 | } | ||
3147 | } | ||
3148 | |||
3149 | if (CurrentLogEntryNum == 0xff) { | ||
3150 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("LogicalLinkCancel, CurrentLogEntryNum == 0xff !!!!\n")); | ||
3151 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
3152 | return status; | ||
3153 | } else { | ||
3154 | if (pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[CurrentLogEntryNum].bLLCompleteEventIsSet) { | ||
3155 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("LogicalLinkCancel, LLCompleteEventIsSet!!!!\n")); | ||
3156 | status = HCI_STATUS_ACL_CONNECT_EXISTS; | ||
3157 | } | ||
3158 | } | ||
3159 | |||
3160 | { | ||
3161 | u8 localBuf[8] = ""; | ||
3162 | u8 *pRetPar; | ||
3163 | u8 len = 0; | ||
3164 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3165 | |||
3166 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3167 | |||
3168 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3169 | LINK_CONTROL_COMMANDS, | ||
3170 | HCI_LOGICAL_LINK_CANCEL, | ||
3171 | status); | ||
3172 | |||
3173 | /* Return parameters starts from here */ | ||
3174 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3175 | pRetPar[0] = status; /* status */ | ||
3176 | pRetPar[1] = pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[CurrentLogEntryNum].BtPhyLinkhandle; | ||
3177 | pRetPar[2] = pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[CurrentLogEntryNum].BtTxFlowSpecID; | ||
3178 | len += 3; | ||
3179 | PPacketIrpEvent->Length = len; | ||
3180 | |||
3181 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3182 | } | ||
3183 | |||
3184 | pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[CurrentLogEntryNum].bLLCancelCMDIsSetandComplete = true; | ||
3185 | |||
3186 | return status; | ||
3187 | } | ||
3188 | |||
3189 | static enum hci_status | ||
3190 | bthci_CmdFlowSpecModify(struct rtw_adapter *padapter, | ||
3191 | struct packet_irp_hcicmd_data *pHciCmd) | ||
3192 | { | ||
3193 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3194 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
3195 | struct bt_30info *pBTinfo = GET_BT_INFO(padapter); | ||
3196 | u8 i, j, find = 0; | ||
3197 | u16 logicHandle; | ||
3198 | |||
3199 | logicHandle = *((u16 *)pHciCmd->Data); | ||
3200 | /* find an matched logical link index and copy the data */ | ||
3201 | for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) { | ||
3202 | for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) { | ||
3203 | if (pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle == logicHandle) { | ||
3204 | memcpy(&pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].Tx_Flow_Spec, | ||
3205 | &pHciCmd->Data[2], sizeof(struct hci_flow_spec)); | ||
3206 | memcpy(&pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].Rx_Flow_Spec, | ||
3207 | &pHciCmd->Data[18], sizeof(struct hci_flow_spec)); | ||
3208 | |||
3209 | bthci_CheckLogLinkBehavior(padapter, pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].Tx_Flow_Spec); | ||
3210 | find = 1; | ||
3211 | break; | ||
3212 | } | ||
3213 | } | ||
3214 | } | ||
3215 | RTPRINT(FIOCTL, IOCTL_BT_LOGO, ("FlowSpecModify, LLH = 0x%x, \n", logicHandle)); | ||
3216 | |||
3217 | /* When we receive Flow Spec Modify command, we should send command status event first. */ | ||
3218 | bthci_EventCommandStatus(padapter, | ||
3219 | LINK_CONTROL_COMMANDS, | ||
3220 | HCI_FLOW_SPEC_MODIFY, | ||
3221 | HCI_STATUS_SUCCESS); | ||
3222 | |||
3223 | if (!find) | ||
3224 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
3225 | |||
3226 | bthci_EventSendFlowSpecModifyComplete(padapter, status, logicHandle); | ||
3227 | |||
3228 | return status; | ||
3229 | } | ||
3230 | |||
3231 | static enum hci_status | ||
3232 | bthci_CmdAcceptPhysicalLink(struct rtw_adapter *padapter, | ||
3233 | struct packet_irp_hcicmd_data *pHciCmd) | ||
3234 | { | ||
3235 | enum hci_status status; | ||
3236 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3237 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
3238 | |||
3239 | pBtDbg->dbgHciInfo.hciCmdCntAcceptPhyLink++; | ||
3240 | |||
3241 | status = bthci_BuildPhysicalLink(padapter, | ||
3242 | pHciCmd, HCI_ACCEPT_PHYSICAL_LINK); | ||
3243 | |||
3244 | return status; | ||
3245 | } | ||
3246 | |||
3247 | static enum hci_status | ||
3248 | bthci_CmdDisconnectPhysicalLink(struct rtw_adapter *padapter, | ||
3249 | struct packet_irp_hcicmd_data *pHciCmd) | ||
3250 | { | ||
3251 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3252 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3253 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
3254 | u8 PLH, CurrentEntryNum, PhysLinkDisconnectReason; | ||
3255 | |||
3256 | pBtDbg->dbgHciInfo.hciCmdCntDisconnectPhyLink++; | ||
3257 | |||
3258 | PLH = *((u8 *)pHciCmd->Data); | ||
3259 | PhysLinkDisconnectReason = (*((u8 *)pHciCmd->Data+1)); | ||
3260 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_DISCONNECT_PHYSICAL_LINK PhyHandle = 0x%x, Reason = 0x%x\n", | ||
3261 | PLH, PhysLinkDisconnectReason)); | ||
3262 | |||
3263 | CurrentEntryNum = bthci_GetCurrentEntryNum(padapter, PLH); | ||
3264 | |||
3265 | if (CurrentEntryNum == 0xff) { | ||
3266 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, | ||
3267 | ("DisconnectPhysicalLink, No such Handle in the Entry\n")); | ||
3268 | status = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
3269 | } else { | ||
3270 | pBTInfo->BtAsocEntry[CurrentEntryNum].PhyLinkDisconnectReason = | ||
3271 | (enum hci_status)PhysLinkDisconnectReason; | ||
3272 | } | ||
3273 | /* Send HCI Command status event to AMP. */ | ||
3274 | bthci_EventCommandStatus(padapter, LINK_CONTROL_COMMANDS, | ||
3275 | HCI_DISCONNECT_PHYSICAL_LINK, status); | ||
3276 | |||
3277 | if (status != HCI_STATUS_SUCCESS) | ||
3278 | return status; | ||
3279 | |||
3280 | /* The macros below require { and } in the if statement */ | ||
3281 | if (pBTInfo->BtAsocEntry[CurrentEntryNum].BtCurrentState == HCI_STATE_DISCONNECTED) { | ||
3282 | BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_DISCONNECT_PHY_LINK, CurrentEntryNum); | ||
3283 | } else { | ||
3284 | BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTING, STATE_CMD_DISCONNECT_PHY_LINK, CurrentEntryNum); | ||
3285 | } | ||
3286 | return status; | ||
3287 | } | ||
3288 | |||
3289 | static enum hci_status | ||
3290 | bthci_CmdSetACLLinkDataFlowMode(struct rtw_adapter *padapter, | ||
3291 | struct packet_irp_hcicmd_data *pHciCmd) | ||
3292 | { | ||
3293 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3294 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3295 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
3296 | u8 localBuf[8] = ""; | ||
3297 | u8 *pRetPar; | ||
3298 | u8 len = 0; | ||
3299 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3300 | u16 *pu2Temp; | ||
3301 | |||
3302 | pBtMgnt->ExtConfig.CurrentConnectHandle = *((u16 *)pHciCmd->Data); | ||
3303 | pBtMgnt->ExtConfig.CurrentIncomingTrafficMode = *((u8 *)pHciCmd->Data)+2; | ||
3304 | pBtMgnt->ExtConfig.CurrentOutgoingTrafficMode = *((u8 *)pHciCmd->Data)+3; | ||
3305 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("Connection Handle = 0x%x, Incoming Traffic mode = 0x%x, Outgoing Traffic mode = 0x%x", | ||
3306 | pBtMgnt->ExtConfig.CurrentConnectHandle, | ||
3307 | pBtMgnt->ExtConfig.CurrentIncomingTrafficMode, | ||
3308 | pBtMgnt->ExtConfig.CurrentOutgoingTrafficMode)); | ||
3309 | |||
3310 | |||
3311 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3312 | |||
3313 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3314 | OGF_EXTENSION, | ||
3315 | HCI_SET_ACL_LINK_DATA_FLOW_MODE, | ||
3316 | status); | ||
3317 | |||
3318 | /* Return parameters starts from here */ | ||
3319 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3320 | pRetPar[0] = status; /* status */ | ||
3321 | |||
3322 | pu2Temp = (u16 *)&pRetPar[1]; | ||
3323 | *pu2Temp = pBtMgnt->ExtConfig.CurrentConnectHandle; | ||
3324 | len += 3; | ||
3325 | PPacketIrpEvent->Length = len; | ||
3326 | |||
3327 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3328 | return status; | ||
3329 | } | ||
3330 | |||
3331 | static enum hci_status | ||
3332 | bthci_CmdSetACLLinkStatus(struct rtw_adapter *padapter, | ||
3333 | struct packet_irp_hcicmd_data *pHciCmd) | ||
3334 | { | ||
3335 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3336 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3337 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
3338 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
3339 | u8 i; | ||
3340 | u8 *pTriple; | ||
3341 | |||
3342 | pBtDbg->dbgHciInfo.hciCmdCntSetAclLinkStatus++; | ||
3343 | RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "SetACLLinkStatus, Hex Data :\n", | ||
3344 | &pHciCmd->Data[0], pHciCmd->Length); | ||
3345 | |||
3346 | /* Only Core Stack v251 and later version support this command. */ | ||
3347 | pBtMgnt->bSupportProfile = true; | ||
3348 | |||
3349 | pBtMgnt->ExtConfig.NumberOfHandle = *((u8 *)pHciCmd->Data); | ||
3350 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("NumberOfHandle = 0x%x\n", pBtMgnt->ExtConfig.NumberOfHandle)); | ||
3351 | |||
3352 | pTriple = &pHciCmd->Data[1]; | ||
3353 | for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) { | ||
3354 | pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle = *((u16 *)&pTriple[0]); | ||
3355 | pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = pTriple[2]; | ||
3356 | pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = pTriple[3]; | ||
3357 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, | ||
3358 | ("Connection_Handle = 0x%x, Incoming Traffic mode = 0x%x, Outgoing Traffic Mode = 0x%x\n", | ||
3359 | pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle, | ||
3360 | pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode, | ||
3361 | pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode)); | ||
3362 | pTriple += 4; | ||
3363 | } | ||
3364 | |||
3365 | { | ||
3366 | u8 localBuf[6] = ""; | ||
3367 | u8 *pRetPar; | ||
3368 | u8 len = 0; | ||
3369 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3370 | |||
3371 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3372 | |||
3373 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3374 | OGF_EXTENSION, | ||
3375 | HCI_SET_ACL_LINK_STATUS, | ||
3376 | status); | ||
3377 | |||
3378 | /* Return parameters starts from here */ | ||
3379 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3380 | pRetPar[0] = status; /* status */ | ||
3381 | |||
3382 | len += 1; | ||
3383 | PPacketIrpEvent->Length = len; | ||
3384 | |||
3385 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3386 | } | ||
3387 | |||
3388 | return status; | ||
3389 | } | ||
3390 | |||
3391 | static enum hci_status | ||
3392 | bthci_CmdSetSCOLinkStatus( | ||
3393 | struct rtw_adapter *padapter, | ||
3394 | struct packet_irp_hcicmd_data *pHciCmd | ||
3395 | ) | ||
3396 | { | ||
3397 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3398 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3399 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
3400 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
3401 | |||
3402 | pBtDbg->dbgHciInfo.hciCmdCntSetScoLinkStatus++; | ||
3403 | pBtMgnt->ExtConfig.NumberOfSCO = *((u8 *)pHciCmd->Data); | ||
3404 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("NumberOfSCO = 0x%x\n", | ||
3405 | pBtMgnt->ExtConfig.NumberOfSCO)); | ||
3406 | |||
3407 | { | ||
3408 | u8 localBuf[6] = ""; | ||
3409 | u8 *pRetPar; | ||
3410 | u8 len = 0; | ||
3411 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3412 | |||
3413 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3414 | |||
3415 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3416 | OGF_EXTENSION, | ||
3417 | HCI_SET_SCO_LINK_STATUS, | ||
3418 | status); | ||
3419 | |||
3420 | /* Return parameters starts from here */ | ||
3421 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3422 | pRetPar[0] = status; /* status */ | ||
3423 | |||
3424 | len += 1; | ||
3425 | PPacketIrpEvent->Length = len; | ||
3426 | |||
3427 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3428 | } | ||
3429 | |||
3430 | return status; | ||
3431 | } | ||
3432 | |||
3433 | static enum hci_status | ||
3434 | bthci_CmdSetRSSIValue( | ||
3435 | struct rtw_adapter *padapter, | ||
3436 | struct packet_irp_hcicmd_data *pHciCmd | ||
3437 | ) | ||
3438 | { | ||
3439 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3440 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3441 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
3442 | s8 min_bt_rssi = 0; | ||
3443 | u8 i; | ||
3444 | for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) { | ||
3445 | if (pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle == *((u16 *)&pHciCmd->Data[0])) { | ||
3446 | pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI = (s8)(pHciCmd->Data[2]); | ||
3447 | RTPRINT(FIOCTL, IOCTL_BT_EVENT_PERIODICAL, | ||
3448 | ("Connection_Handle = 0x%x, RSSI = %d \n", | ||
3449 | pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle, | ||
3450 | pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI)); | ||
3451 | } | ||
3452 | /* get the minimum bt rssi value */ | ||
3453 | if (pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI <= min_bt_rssi) | ||
3454 | min_bt_rssi = pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI; | ||
3455 | } | ||
3456 | |||
3457 | pBtMgnt->ExtConfig.MIN_BT_RSSI = min_bt_rssi; | ||
3458 | RTPRINT(FBT, BT_TRACE, ("[bt rssi], the min rssi is %d\n", min_bt_rssi)); | ||
3459 | |||
3460 | { | ||
3461 | u8 localBuf[6] = ""; | ||
3462 | u8 *pRetPar; | ||
3463 | u8 len = 0; | ||
3464 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3465 | |||
3466 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3467 | |||
3468 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3469 | OGF_EXTENSION, | ||
3470 | HCI_SET_RSSI_VALUE, | ||
3471 | status); | ||
3472 | |||
3473 | /* Return parameters starts from here */ | ||
3474 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3475 | pRetPar[0] = status; /* status */ | ||
3476 | |||
3477 | len += 1; | ||
3478 | PPacketIrpEvent->Length = len; | ||
3479 | |||
3480 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3481 | } | ||
3482 | |||
3483 | return status; | ||
3484 | } | ||
3485 | |||
3486 | static enum hci_status | ||
3487 | bthci_CmdSetCurrentBluetoothStatus( | ||
3488 | struct rtw_adapter *padapter, | ||
3489 | struct packet_irp_hcicmd_data *pHciCmd | ||
3490 | ) | ||
3491 | { | ||
3492 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3493 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
3494 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3495 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
3496 | |||
3497 | pBtMgnt->ExtConfig.CurrentBTStatus = *((u8 *)&pHciCmd->Data[0]); | ||
3498 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("SetCurrentBluetoothStatus, CurrentBTStatus = 0x%x\n", | ||
3499 | pBtMgnt->ExtConfig.CurrentBTStatus)); | ||
3500 | |||
3501 | { | ||
3502 | u8 localBuf[6] = ""; | ||
3503 | u8 *pRetPar; | ||
3504 | u8 len = 0; | ||
3505 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3506 | |||
3507 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3508 | |||
3509 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3510 | OGF_EXTENSION, | ||
3511 | HCI_SET_CURRENT_BLUETOOTH_STATUS, | ||
3512 | status); | ||
3513 | |||
3514 | /* Return parameters starts from here */ | ||
3515 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3516 | pRetPar[0] = status; /* status */ | ||
3517 | len += 1; | ||
3518 | |||
3519 | PPacketIrpEvent->Length = len; | ||
3520 | |||
3521 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3522 | } | ||
3523 | |||
3524 | return status; | ||
3525 | } | ||
3526 | |||
3527 | static enum hci_status | ||
3528 | bthci_CmdExtensionVersionNotify( | ||
3529 | struct rtw_adapter *padapter, | ||
3530 | struct packet_irp_hcicmd_data *pHciCmd | ||
3531 | ) | ||
3532 | { | ||
3533 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3534 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3535 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
3536 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
3537 | |||
3538 | pBtDbg->dbgHciInfo.hciCmdCntExtensionVersionNotify++; | ||
3539 | RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "ExtensionVersionNotify, Hex Data :\n", | ||
3540 | &pHciCmd->Data[0], pHciCmd->Length); | ||
3541 | |||
3542 | pBtMgnt->ExtConfig.HCIExtensionVer = *((u16 *)&pHciCmd->Data[0]); | ||
3543 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCIExtensionVer = 0x%x\n", pBtMgnt->ExtConfig.HCIExtensionVer)); | ||
3544 | |||
3545 | { | ||
3546 | u8 localBuf[6] = ""; | ||
3547 | u8 *pRetPar; | ||
3548 | u8 len = 0; | ||
3549 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3550 | |||
3551 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3552 | |||
3553 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3554 | OGF_EXTENSION, | ||
3555 | HCI_EXTENSION_VERSION_NOTIFY, | ||
3556 | status); | ||
3557 | |||
3558 | /* Return parameters starts from here */ | ||
3559 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3560 | pRetPar[0] = status; /* status */ | ||
3561 | |||
3562 | len += 1; | ||
3563 | PPacketIrpEvent->Length = len; | ||
3564 | |||
3565 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3566 | } | ||
3567 | |||
3568 | return status; | ||
3569 | } | ||
3570 | |||
3571 | static enum hci_status | ||
3572 | bthci_CmdLinkStatusNotify( | ||
3573 | struct rtw_adapter *padapter, | ||
3574 | struct packet_irp_hcicmd_data *pHciCmd | ||
3575 | ) | ||
3576 | { | ||
3577 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3578 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3579 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
3580 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
3581 | u8 i; | ||
3582 | u8 *pTriple; | ||
3583 | |||
3584 | pBtDbg->dbgHciInfo.hciCmdCntLinkStatusNotify++; | ||
3585 | RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "LinkStatusNotify, Hex Data :\n", | ||
3586 | &pHciCmd->Data[0], pHciCmd->Length); | ||
3587 | |||
3588 | /* Current only RTL8723 support this command. */ | ||
3589 | pBtMgnt->bSupportProfile = true; | ||
3590 | |||
3591 | pBtMgnt->ExtConfig.NumberOfHandle = *((u8 *)pHciCmd->Data); | ||
3592 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("NumberOfHandle = 0x%x\n", pBtMgnt->ExtConfig.NumberOfHandle)); | ||
3593 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCIExtensionVer = %d\n", pBtMgnt->ExtConfig.HCIExtensionVer)); | ||
3594 | |||
3595 | pTriple = &pHciCmd->Data[1]; | ||
3596 | for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) { | ||
3597 | if (pBtMgnt->ExtConfig.HCIExtensionVer < 1) { | ||
3598 | pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle = *((u16 *)&pTriple[0]); | ||
3599 | pBtMgnt->ExtConfig.linkInfo[i].BTProfile = pTriple[2]; | ||
3600 | pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec = pTriple[3]; | ||
3601 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, | ||
3602 | ("Connection_Handle = 0x%x, BTProfile =%d, BTSpec =%d\n", | ||
3603 | pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle, | ||
3604 | pBtMgnt->ExtConfig.linkInfo[i].BTProfile, | ||
3605 | pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec)); | ||
3606 | pTriple += 4; | ||
3607 | } else if (pBtMgnt->ExtConfig.HCIExtensionVer >= 1) { | ||
3608 | pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle = *((u16 *)&pTriple[0]); | ||
3609 | pBtMgnt->ExtConfig.linkInfo[i].BTProfile = pTriple[2]; | ||
3610 | pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec = pTriple[3]; | ||
3611 | pBtMgnt->ExtConfig.linkInfo[i].linkRole = pTriple[4]; | ||
3612 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, | ||
3613 | ("Connection_Handle = 0x%x, BTProfile =%d, BTSpec =%d, LinkRole =%d\n", | ||
3614 | pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle, | ||
3615 | pBtMgnt->ExtConfig.linkInfo[i].BTProfile, | ||
3616 | pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec, | ||
3617 | pBtMgnt->ExtConfig.linkInfo[i].linkRole)); | ||
3618 | pTriple += 5; | ||
3619 | } | ||
3620 | |||
3621 | } | ||
3622 | BTHCI_UpdateBTProfileRTKToMoto(padapter); | ||
3623 | { | ||
3624 | u8 localBuf[6] = ""; | ||
3625 | u8 *pRetPar; | ||
3626 | u8 len = 0; | ||
3627 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3628 | |||
3629 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3630 | |||
3631 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3632 | OGF_EXTENSION, | ||
3633 | HCI_LINK_STATUS_NOTIFY, | ||
3634 | status); | ||
3635 | |||
3636 | /* Return parameters starts from here */ | ||
3637 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3638 | pRetPar[0] = status; /* status */ | ||
3639 | |||
3640 | len += 1; | ||
3641 | PPacketIrpEvent->Length = len; | ||
3642 | |||
3643 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3644 | } | ||
3645 | |||
3646 | return status; | ||
3647 | } | ||
3648 | |||
3649 | static enum hci_status | ||
3650 | bthci_CmdBtOperationNotify( | ||
3651 | struct rtw_adapter *padapter, | ||
3652 | struct packet_irp_hcicmd_data *pHciCmd | ||
3653 | ) | ||
3654 | { | ||
3655 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3656 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3657 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
3658 | |||
3659 | RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "Bt Operation notify, Hex Data :\n", | ||
3660 | &pHciCmd->Data[0], pHciCmd->Length); | ||
3661 | |||
3662 | pBtMgnt->ExtConfig.btOperationCode = *((u8 *)pHciCmd->Data); | ||
3663 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("btOperationCode = 0x%x\n", pBtMgnt->ExtConfig.btOperationCode)); | ||
3664 | switch (pBtMgnt->ExtConfig.btOperationCode) { | ||
3665 | case HCI_BT_OP_NONE: | ||
3666 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Operation None!!\n")); | ||
3667 | break; | ||
3668 | case HCI_BT_OP_INQUIRY_START: | ||
3669 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Inquire start!!\n")); | ||
3670 | break; | ||
3671 | case HCI_BT_OP_INQUIRY_FINISH: | ||
3672 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Inquire finished!!\n")); | ||
3673 | break; | ||
3674 | case HCI_BT_OP_PAGING_START: | ||
3675 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Paging is started!!\n")); | ||
3676 | break; | ||
3677 | case HCI_BT_OP_PAGING_SUCCESS: | ||
3678 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Paging complete successfully!!\n")); | ||
3679 | break; | ||
3680 | case HCI_BT_OP_PAGING_UNSUCCESS: | ||
3681 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Paging complete unsuccessfully!!\n")); | ||
3682 | break; | ||
3683 | case HCI_BT_OP_PAIRING_START: | ||
3684 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Pairing start!!\n")); | ||
3685 | break; | ||
3686 | case HCI_BT_OP_PAIRING_FINISH: | ||
3687 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Pairing finished!!\n")); | ||
3688 | break; | ||
3689 | case HCI_BT_OP_BT_DEV_ENABLE: | ||
3690 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : BT Device is enabled!!\n")); | ||
3691 | break; | ||
3692 | case HCI_BT_OP_BT_DEV_DISABLE: | ||
3693 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : BT Device is disabled!!\n")); | ||
3694 | break; | ||
3695 | default: | ||
3696 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Unknown, error!!\n")); | ||
3697 | break; | ||
3698 | } | ||
3699 | BTDM_AdjustForBtOperation(padapter); | ||
3700 | { | ||
3701 | u8 localBuf[6] = ""; | ||
3702 | u8 *pRetPar; | ||
3703 | u8 len = 0; | ||
3704 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3705 | |||
3706 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3707 | |||
3708 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3709 | OGF_EXTENSION, | ||
3710 | HCI_BT_OPERATION_NOTIFY, | ||
3711 | status); | ||
3712 | |||
3713 | /* Return parameters starts from here */ | ||
3714 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3715 | pRetPar[0] = status; /* status */ | ||
3716 | |||
3717 | len += 1; | ||
3718 | PPacketIrpEvent->Length = len; | ||
3719 | |||
3720 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3721 | } | ||
3722 | |||
3723 | return status; | ||
3724 | } | ||
3725 | |||
3726 | static enum hci_status | ||
3727 | bthci_CmdEnableWifiScanNotify(struct rtw_adapter *padapter, | ||
3728 | struct packet_irp_hcicmd_data *pHciCmd) | ||
3729 | { | ||
3730 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3731 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3732 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
3733 | |||
3734 | RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "Enable Wifi scan notify, Hex Data :\n", | ||
3735 | &pHciCmd->Data[0], pHciCmd->Length); | ||
3736 | |||
3737 | pBtMgnt->ExtConfig.bEnableWifiScanNotify = *((u8 *)pHciCmd->Data); | ||
3738 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("bEnableWifiScanNotify = %d\n", pBtMgnt->ExtConfig.bEnableWifiScanNotify)); | ||
3739 | |||
3740 | { | ||
3741 | u8 localBuf[6] = ""; | ||
3742 | u8 *pRetPar; | ||
3743 | u8 len = 0; | ||
3744 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3745 | |||
3746 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3747 | |||
3748 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3749 | OGF_EXTENSION, | ||
3750 | HCI_ENABLE_WIFI_SCAN_NOTIFY, | ||
3751 | status); | ||
3752 | |||
3753 | /* Return parameters starts from here */ | ||
3754 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3755 | pRetPar[0] = status; /* status */ | ||
3756 | |||
3757 | len += 1; | ||
3758 | PPacketIrpEvent->Length = len; | ||
3759 | |||
3760 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3761 | } | ||
3762 | |||
3763 | return status; | ||
3764 | } | ||
3765 | |||
3766 | static enum hci_status | ||
3767 | bthci_CmdWIFICurrentChannel(struct rtw_adapter *padapter, | ||
3768 | struct packet_irp_hcicmd_data *pHciCmd) | ||
3769 | { | ||
3770 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3771 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; | ||
3772 | u8 chnl = pmlmeext->cur_channel; | ||
3773 | |||
3774 | if (pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) { | ||
3775 | if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) | ||
3776 | chnl += 2; | ||
3777 | else if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) | ||
3778 | chnl -= 2; | ||
3779 | } | ||
3780 | |||
3781 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("Current Channel = 0x%x\n", chnl)); | ||
3782 | |||
3783 | { | ||
3784 | u8 localBuf[8] = ""; | ||
3785 | u8 *pRetPar; | ||
3786 | u8 len = 0; | ||
3787 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3788 | |||
3789 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3790 | |||
3791 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3792 | OGF_EXTENSION, | ||
3793 | HCI_WIFI_CURRENT_CHANNEL, | ||
3794 | status); | ||
3795 | |||
3796 | /* Return parameters starts from here */ | ||
3797 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3798 | pRetPar[0] = status; /* status */ | ||
3799 | pRetPar[1] = chnl; /* current channel */ | ||
3800 | len += 2; | ||
3801 | PPacketIrpEvent->Length = len; | ||
3802 | |||
3803 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3804 | } | ||
3805 | |||
3806 | return status; | ||
3807 | } | ||
3808 | |||
3809 | static enum hci_status | ||
3810 | bthci_CmdWIFICurrentBandwidth(struct rtw_adapter *padapter, | ||
3811 | struct packet_irp_hcicmd_data *pHciCmd) | ||
3812 | { | ||
3813 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3814 | enum ht_channel_width bw; | ||
3815 | u8 CurrentBW = 0; | ||
3816 | |||
3817 | bw = padapter->mlmeextpriv.cur_bwmode; | ||
3818 | |||
3819 | if (bw == HT_CHANNEL_WIDTH_20) | ||
3820 | CurrentBW = 0; | ||
3821 | else if (bw == HT_CHANNEL_WIDTH_40) | ||
3822 | CurrentBW = 1; | ||
3823 | |||
3824 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("Current BW = 0x%x\n", | ||
3825 | CurrentBW)); | ||
3826 | |||
3827 | { | ||
3828 | u8 localBuf[8] = ""; | ||
3829 | u8 *pRetPar; | ||
3830 | u8 len = 0; | ||
3831 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3832 | |||
3833 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3834 | |||
3835 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3836 | OGF_EXTENSION, | ||
3837 | HCI_WIFI_CURRENT_BANDWIDTH, | ||
3838 | status); | ||
3839 | |||
3840 | /* Return parameters starts from here */ | ||
3841 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3842 | pRetPar[0] = status; /* status */ | ||
3843 | pRetPar[1] = CurrentBW; /* current BW */ | ||
3844 | len += 2; | ||
3845 | PPacketIrpEvent->Length = len; | ||
3846 | |||
3847 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3848 | } | ||
3849 | |||
3850 | return status; | ||
3851 | } | ||
3852 | |||
3853 | static enum hci_status | ||
3854 | bthci_CmdWIFIConnectionStatus( | ||
3855 | struct rtw_adapter *padapter, | ||
3856 | struct packet_irp_hcicmd_data *pHciCmd | ||
3857 | ) | ||
3858 | { | ||
3859 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3860 | u8 connectStatus = HCI_WIFI_NOT_CONNECTED; | ||
3861 | |||
3862 | if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE)) { | ||
3863 | if (padapter->stapriv.asoc_sta_count >= 3) | ||
3864 | connectStatus = HCI_WIFI_CONNECTED; | ||
3865 | else | ||
3866 | connectStatus = HCI_WIFI_NOT_CONNECTED; | ||
3867 | } else if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_ASOC_STATE)) { | ||
3868 | connectStatus = HCI_WIFI_CONNECTED; | ||
3869 | } else if (check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING)) { | ||
3870 | connectStatus = HCI_WIFI_CONNECT_IN_PROGRESS; | ||
3871 | } else { | ||
3872 | connectStatus = HCI_WIFI_NOT_CONNECTED; | ||
3873 | } | ||
3874 | |||
3875 | { | ||
3876 | u8 localBuf[8] = ""; | ||
3877 | u8 *pRetPar; | ||
3878 | u8 len = 0; | ||
3879 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3880 | |||
3881 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3882 | |||
3883 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3884 | OGF_EXTENSION, | ||
3885 | HCI_WIFI_CONNECTION_STATUS, | ||
3886 | status); | ||
3887 | |||
3888 | /* Return parameters starts from here */ | ||
3889 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3890 | pRetPar[0] = status; /* status */ | ||
3891 | pRetPar[1] = connectStatus; /* connect status */ | ||
3892 | len += 2; | ||
3893 | PPacketIrpEvent->Length = len; | ||
3894 | |||
3895 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3896 | } | ||
3897 | |||
3898 | return status; | ||
3899 | } | ||
3900 | |||
3901 | static enum hci_status | ||
3902 | bthci_CmdEnableDeviceUnderTestMode( | ||
3903 | struct rtw_adapter *padapter, | ||
3904 | struct packet_irp_hcicmd_data *pHciCmd | ||
3905 | ) | ||
3906 | { | ||
3907 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3908 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3909 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
3910 | |||
3911 | pBtHciInfo->bInTestMode = true; | ||
3912 | pBtHciInfo->bTestIsEnd = false; | ||
3913 | |||
3914 | /* send command complete event here when all data are received. */ | ||
3915 | { | ||
3916 | u8 localBuf[6] = ""; | ||
3917 | u8 *pRetPar; | ||
3918 | u8 len = 0; | ||
3919 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3920 | |||
3921 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3922 | |||
3923 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
3924 | OGF_TESTING_COMMANDS, | ||
3925 | HCI_ENABLE_DEVICE_UNDER_TEST_MODE, | ||
3926 | status); | ||
3927 | |||
3928 | /* Return parameters starts from here */ | ||
3929 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
3930 | pRetPar[0] = status; /* status */ | ||
3931 | len += 1; | ||
3932 | PPacketIrpEvent->Length = len; | ||
3933 | |||
3934 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
3935 | } | ||
3936 | |||
3937 | return status; | ||
3938 | } | ||
3939 | |||
3940 | static enum hci_status | ||
3941 | bthci_CmdAMPTestEnd(struct rtw_adapter *padapter, | ||
3942 | struct packet_irp_hcicmd_data *pHciCmd) | ||
3943 | { | ||
3944 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3945 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3946 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
3947 | u8 bFilterOutNonAssociatedBSSID = true; | ||
3948 | |||
3949 | if (!pBtHciInfo->bInTestMode) { | ||
3950 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Not in Test mode, return status = HCI_STATUS_CMD_DISALLOW\n")); | ||
3951 | status = HCI_STATUS_CMD_DISALLOW; | ||
3952 | return status; | ||
3953 | } | ||
3954 | |||
3955 | pBtHciInfo->bTestIsEnd = true; | ||
3956 | |||
3957 | del_timer_sync(&pBTInfo->BTTestSendPacketTimer); | ||
3958 | |||
3959 | rtw_hal_set_hwreg23a(padapter, HW_VAR_CHECK_BSSID, (u8 *)(&bFilterOutNonAssociatedBSSID)); | ||
3960 | |||
3961 | /* send command complete event here when all data are received. */ | ||
3962 | { | ||
3963 | u8 localBuf[4] = ""; | ||
3964 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
3965 | |||
3966 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("AMP Test End Event \n")); | ||
3967 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
3968 | PPacketIrpEvent->EventCode = HCI_EVENT_AMP_TEST_END; | ||
3969 | PPacketIrpEvent->Length = 2; | ||
3970 | |||
3971 | PPacketIrpEvent->Data[0] = status; | ||
3972 | PPacketIrpEvent->Data[1] = pBtHciInfo->TestScenario; | ||
3973 | |||
3974 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 4); | ||
3975 | } | ||
3976 | |||
3977 | bthci_EventAMPReceiverReport(padapter, 0x01); | ||
3978 | |||
3979 | return status; | ||
3980 | } | ||
3981 | |||
3982 | static enum hci_status | ||
3983 | bthci_CmdAMPTestCommand(struct rtw_adapter *padapter, | ||
3984 | struct packet_irp_hcicmd_data *pHciCmd) | ||
3985 | { | ||
3986 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
3987 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
3988 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
3989 | |||
3990 | if (!pBtHciInfo->bInTestMode) { | ||
3991 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Not in Test mode, return status = HCI_STATUS_CMD_DISALLOW\n")); | ||
3992 | status = HCI_STATUS_CMD_DISALLOW; | ||
3993 | return status; | ||
3994 | } | ||
3995 | |||
3996 | pBtHciInfo->TestScenario = *((u8 *)pHciCmd->Data); | ||
3997 | |||
3998 | if (pBtHciInfo->TestScenario == 0x01) | ||
3999 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("TX Single Test \n")); | ||
4000 | else if (pBtHciInfo->TestScenario == 0x02) | ||
4001 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Receive Frame Test \n")); | ||
4002 | else | ||
4003 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("No Such Test !!!!!!!!!!!!!!!!!! \n")); | ||
4004 | |||
4005 | if (pBtHciInfo->bTestIsEnd) { | ||
4006 | u8 localBuf[5] = ""; | ||
4007 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
4008 | |||
4009 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("AMP Test End Event \n")); | ||
4010 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
4011 | PPacketIrpEvent->EventCode = HCI_EVENT_AMP_TEST_END; | ||
4012 | PPacketIrpEvent->Length = 2; | ||
4013 | |||
4014 | PPacketIrpEvent->Data[0] = status; | ||
4015 | PPacketIrpEvent->Data[1] = pBtHciInfo->TestScenario ; | ||
4016 | |||
4017 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 4); | ||
4018 | |||
4019 | /* Return to Idel state with RX and TX off. */ | ||
4020 | |||
4021 | return status; | ||
4022 | } | ||
4023 | |||
4024 | /* should send command status event */ | ||
4025 | bthci_EventCommandStatus(padapter, | ||
4026 | OGF_TESTING_COMMANDS, | ||
4027 | HCI_AMP_TEST_COMMAND, | ||
4028 | status); | ||
4029 | |||
4030 | /* The HCI_AMP_Start Test Event shall be generated when the */ | ||
4031 | /* HCI_AMP_Test_Command has completed and the first data is ready to be sent */ | ||
4032 | /* or received. */ | ||
4033 | |||
4034 | { | ||
4035 | u8 localBuf[5] = ""; | ||
4036 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
4037 | |||
4038 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), (" HCI_AMP_Start Test Event \n")); | ||
4039 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
4040 | PPacketIrpEvent->EventCode = HCI_EVENT_AMP_START_TEST; | ||
4041 | PPacketIrpEvent->Length = 2; | ||
4042 | |||
4043 | PPacketIrpEvent->Data[0] = status; | ||
4044 | PPacketIrpEvent->Data[1] = pBtHciInfo->TestScenario ; | ||
4045 | |||
4046 | bthci_IndicateEvent(padapter, PPacketIrpEvent, 4); | ||
4047 | |||
4048 | /* Return to Idel state with RX and TX off. */ | ||
4049 | } | ||
4050 | |||
4051 | if (pBtHciInfo->TestScenario == 0x01) { | ||
4052 | /* | ||
4053 | When in a transmitter test scenario and the frames/bursts count have been | ||
4054 | transmitted the HCI_AMP_Test_End event shall be sent. | ||
4055 | */ | ||
4056 | mod_timer(&pBTInfo->BTTestSendPacketTimer, | ||
4057 | jiffies + msecs_to_jiffies(50)); | ||
4058 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("TX Single Test \n")); | ||
4059 | } else if (pBtHciInfo->TestScenario == 0x02) { | ||
4060 | u8 bFilterOutNonAssociatedBSSID = false; | ||
4061 | rtw_hal_set_hwreg23a(padapter, HW_VAR_CHECK_BSSID, (u8 *)(&bFilterOutNonAssociatedBSSID)); | ||
4062 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Receive Frame Test \n")); | ||
4063 | } | ||
4064 | |||
4065 | return status; | ||
4066 | } | ||
4067 | |||
4068 | static enum hci_status | ||
4069 | bthci_CmdEnableAMPReceiverReports(struct rtw_adapter *padapter, | ||
4070 | struct packet_irp_hcicmd_data *pHciCmd) | ||
4071 | { | ||
4072 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
4073 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
4074 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
4075 | |||
4076 | if (!pBtHciInfo->bInTestMode) { | ||
4077 | status = HCI_STATUS_CMD_DISALLOW; | ||
4078 | /* send command complete event here when all data are received. */ | ||
4079 | { | ||
4080 | u8 localBuf[6] = ""; | ||
4081 | u8 *pRetPar; | ||
4082 | u8 len = 0; | ||
4083 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
4084 | |||
4085 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
4086 | |||
4087 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
4088 | OGF_TESTING_COMMANDS, | ||
4089 | HCI_ENABLE_AMP_RECEIVER_REPORTS, | ||
4090 | status); | ||
4091 | |||
4092 | /* Return parameters starts from here */ | ||
4093 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
4094 | pRetPar[0] = status; /* status */ | ||
4095 | len += 1; | ||
4096 | PPacketIrpEvent->Length = len; | ||
4097 | |||
4098 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
4099 | } | ||
4100 | return status; | ||
4101 | } | ||
4102 | |||
4103 | pBtHciInfo->bTestNeedReport = *((u8 *)pHciCmd->Data); | ||
4104 | pBtHciInfo->TestReportInterval = (*((u8 *)pHciCmd->Data+2)); | ||
4105 | |||
4106 | bthci_EventAMPReceiverReport(padapter, 0x00); | ||
4107 | |||
4108 | /* send command complete event here when all data are received. */ | ||
4109 | { | ||
4110 | u8 localBuf[6] = ""; | ||
4111 | u8 *pRetPar; | ||
4112 | u8 len = 0; | ||
4113 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
4114 | |||
4115 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
4116 | |||
4117 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
4118 | OGF_TESTING_COMMANDS, | ||
4119 | HCI_ENABLE_AMP_RECEIVER_REPORTS, | ||
4120 | status); | ||
4121 | |||
4122 | /* Return parameters starts from here */ | ||
4123 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
4124 | pRetPar[0] = status; /* status */ | ||
4125 | len += 1; | ||
4126 | PPacketIrpEvent->Length = len; | ||
4127 | |||
4128 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
4129 | } | ||
4130 | |||
4131 | return status; | ||
4132 | } | ||
4133 | |||
4134 | static enum hci_status | ||
4135 | bthci_CmdHostBufferSize(struct rtw_adapter *padapter, | ||
4136 | struct packet_irp_hcicmd_data *pHciCmd) | ||
4137 | { | ||
4138 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
4139 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
4140 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
4141 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
4142 | u8 localBuf[6] = ""; | ||
4143 | u8 *pRetPar; | ||
4144 | u8 len = 0; | ||
4145 | |||
4146 | pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].ACLPacketsData.ACLDataPacketLen = *((u16 *)pHciCmd->Data); | ||
4147 | pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].SyncDataPacketLen = *((u8 *)(pHciCmd->Data+2)); | ||
4148 | pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].TotalNumACLDataPackets = *((u16 *)(pHciCmd->Data+3)); | ||
4149 | pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].TotalSyncNumDataPackets = *((u16 *)(pHciCmd->Data+5)); | ||
4150 | |||
4151 | /* send command complete event here when all data are received. */ | ||
4152 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
4153 | |||
4154 | len += bthci_CommandCompleteHeader(&localBuf[0], | ||
4155 | OGF_SET_EVENT_MASK_COMMAND, | ||
4156 | HCI_HOST_BUFFER_SIZE, | ||
4157 | status); | ||
4158 | |||
4159 | /* Return parameters starts from here */ | ||
4160 | pRetPar = &PPacketIrpEvent->Data[len]; | ||
4161 | pRetPar[0] = status; /* status */ | ||
4162 | len += 1; | ||
4163 | PPacketIrpEvent->Length = len; | ||
4164 | |||
4165 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
4166 | |||
4167 | return status; | ||
4168 | } | ||
4169 | |||
4170 | static enum hci_status | ||
4171 | bthci_CmdHostNumberOfCompletedPackets(struct rtw_adapter *padapter, | ||
4172 | struct packet_irp_hcicmd_data *pHciCmd) | ||
4173 | { | ||
4174 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
4175 | |||
4176 | return status; | ||
4177 | } | ||
4178 | |||
4179 | static enum hci_status | ||
4180 | bthci_UnknownCMD(struct rtw_adapter *padapter, struct packet_irp_hcicmd_data *pHciCmd) | ||
4181 | { | ||
4182 | enum hci_status status = HCI_STATUS_UNKNOW_HCI_CMD; | ||
4183 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
4184 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
4185 | |||
4186 | pBtDbg->dbgHciInfo.hciCmdCntUnknown++; | ||
4187 | bthci_EventCommandStatus(padapter, | ||
4188 | (u8)pHciCmd->OGF, | ||
4189 | pHciCmd->OCF, | ||
4190 | status); | ||
4191 | |||
4192 | return status; | ||
4193 | } | ||
4194 | |||
4195 | static enum hci_status | ||
4196 | bthci_HandleOGFInformationalParameters(struct rtw_adapter *padapter, | ||
4197 | struct packet_irp_hcicmd_data *pHciCmd) | ||
4198 | { | ||
4199 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
4200 | |||
4201 | switch (pHciCmd->OCF) { | ||
4202 | case HCI_READ_LOCAL_VERSION_INFORMATION: | ||
4203 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_VERSION_INFORMATION\n")); | ||
4204 | status = bthci_CmdReadLocalVersionInformation(padapter); | ||
4205 | break; | ||
4206 | case HCI_READ_LOCAL_SUPPORTED_COMMANDS: | ||
4207 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_SUPPORTED_COMMANDS\n")); | ||
4208 | status = bthci_CmdReadLocalSupportedCommands(padapter); | ||
4209 | break; | ||
4210 | case HCI_READ_LOCAL_SUPPORTED_FEATURES: | ||
4211 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_SUPPORTED_FEATURES\n")); | ||
4212 | status = bthci_CmdReadLocalSupportedFeatures(padapter); | ||
4213 | break; | ||
4214 | case HCI_READ_BUFFER_SIZE: | ||
4215 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_BUFFER_SIZE\n")); | ||
4216 | status = bthci_CmdReadBufferSize(padapter); | ||
4217 | break; | ||
4218 | case HCI_READ_DATA_BLOCK_SIZE: | ||
4219 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_DATA_BLOCK_SIZE\n")); | ||
4220 | status = bthci_CmdReadDataBlockSize(padapter); | ||
4221 | break; | ||
4222 | default: | ||
4223 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_HandleOGFInformationalParameters(), Unknown case = 0x%x\n", pHciCmd->OCF)); | ||
4224 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n")); | ||
4225 | status = bthci_UnknownCMD(padapter, pHciCmd); | ||
4226 | break; | ||
4227 | } | ||
4228 | return status; | ||
4229 | } | ||
4230 | |||
4231 | static enum hci_status | ||
4232 | bthci_HandleOGFSetEventMaskCMD(struct rtw_adapter *padapter, | ||
4233 | struct packet_irp_hcicmd_data *pHciCmd) | ||
4234 | { | ||
4235 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
4236 | |||
4237 | switch (pHciCmd->OCF) { | ||
4238 | case HCI_SET_EVENT_MASK: | ||
4239 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SET_EVENT_MASK\n")); | ||
4240 | status = bthci_CmdSetEventMask(padapter, pHciCmd); | ||
4241 | break; | ||
4242 | case HCI_RESET: | ||
4243 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_RESET\n")); | ||
4244 | status = bthci_CmdReset(padapter, true); | ||
4245 | break; | ||
4246 | case HCI_READ_CONNECTION_ACCEPT_TIMEOUT: | ||
4247 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_CONNECTION_ACCEPT_TIMEOUT\n")); | ||
4248 | status = bthci_CmdReadConnectionAcceptTimeout(padapter); | ||
4249 | break; | ||
4250 | case HCI_SET_EVENT_FILTER: | ||
4251 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SET_EVENT_FILTER\n")); | ||
4252 | status = bthci_CmdSetEventFilter(padapter, pHciCmd); | ||
4253 | break; | ||
4254 | case HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT: | ||
4255 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT\n")); | ||
4256 | status = bthci_CmdWriteConnectionAcceptTimeout(padapter, pHciCmd); | ||
4257 | break; | ||
4258 | case HCI_READ_PAGE_TIMEOUT: | ||
4259 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_PAGE_TIMEOUT\n")); | ||
4260 | status = bthci_CmdReadPageTimeout(padapter, pHciCmd); | ||
4261 | break; | ||
4262 | case HCI_WRITE_PAGE_TIMEOUT: | ||
4263 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_PAGE_TIMEOUT\n")); | ||
4264 | status = bthci_CmdWritePageTimeout(padapter, pHciCmd); | ||
4265 | break; | ||
4266 | case HCI_HOST_NUMBER_OF_COMPLETED_PACKETS: | ||
4267 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_HOST_NUMBER_OF_COMPLETED_PACKETS\n")); | ||
4268 | status = bthci_CmdHostNumberOfCompletedPackets(padapter, pHciCmd); | ||
4269 | break; | ||
4270 | case HCI_READ_LINK_SUPERVISION_TIMEOUT: | ||
4271 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LINK_SUPERVISION_TIMEOUT\n")); | ||
4272 | status = bthci_CmdReadLinkSupervisionTimeout(padapter, pHciCmd); | ||
4273 | break; | ||
4274 | case HCI_WRITE_LINK_SUPERVISION_TIMEOUT: | ||
4275 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_LINK_SUPERVISION_TIMEOUT\n")); | ||
4276 | status = bthci_CmdWriteLinkSupervisionTimeout(padapter, pHciCmd); | ||
4277 | break; | ||
4278 | case HCI_ENHANCED_FLUSH: | ||
4279 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ENHANCED_FLUSH\n")); | ||
4280 | status = bthci_CmdEnhancedFlush(padapter, pHciCmd); | ||
4281 | break; | ||
4282 | case HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT: | ||
4283 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT\n")); | ||
4284 | status = bthci_CmdReadLogicalLinkAcceptTimeout(padapter, pHciCmd); | ||
4285 | break; | ||
4286 | case HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT: | ||
4287 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT\n")); | ||
4288 | status = bthci_CmdWriteLogicalLinkAcceptTimeout(padapter, pHciCmd); | ||
4289 | break; | ||
4290 | case HCI_SET_EVENT_MASK_PAGE_2: | ||
4291 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SET_EVENT_MASK_PAGE_2\n")); | ||
4292 | status = bthci_CmdSetEventMaskPage2(padapter, pHciCmd); | ||
4293 | break; | ||
4294 | case HCI_READ_LOCATION_DATA: | ||
4295 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCATION_DATA\n")); | ||
4296 | status = bthci_CmdReadLocationData(padapter, pHciCmd); | ||
4297 | break; | ||
4298 | case HCI_WRITE_LOCATION_DATA: | ||
4299 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_LOCATION_DATA\n")); | ||
4300 | status = bthci_CmdWriteLocationData(padapter, pHciCmd); | ||
4301 | break; | ||
4302 | case HCI_READ_FLOW_CONTROL_MODE: | ||
4303 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_FLOW_CONTROL_MODE\n")); | ||
4304 | status = bthci_CmdReadFlowControlMode(padapter, pHciCmd); | ||
4305 | break; | ||
4306 | case HCI_WRITE_FLOW_CONTROL_MODE: | ||
4307 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_FLOW_CONTROL_MODE\n")); | ||
4308 | status = bthci_CmdWriteFlowControlMode(padapter, pHciCmd); | ||
4309 | break; | ||
4310 | case HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT: | ||
4311 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT\n")); | ||
4312 | status = bthci_CmdReadBestEffortFlushTimeout(padapter, pHciCmd); | ||
4313 | break; | ||
4314 | case HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT: | ||
4315 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT\n")); | ||
4316 | status = bthci_CmdWriteBestEffortFlushTimeout(padapter, pHciCmd); | ||
4317 | break; | ||
4318 | case HCI_SHORT_RANGE_MODE: | ||
4319 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SHORT_RANGE_MODE\n")); | ||
4320 | status = bthci_CmdShortRangeMode(padapter, pHciCmd); | ||
4321 | break; | ||
4322 | case HCI_HOST_BUFFER_SIZE: | ||
4323 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_HOST_BUFFER_SIZE\n")); | ||
4324 | status = bthci_CmdHostBufferSize(padapter, pHciCmd); | ||
4325 | break; | ||
4326 | default: | ||
4327 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_HandleOGFSetEventMaskCMD(), Unknown case = 0x%x\n", pHciCmd->OCF)); | ||
4328 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n")); | ||
4329 | status = bthci_UnknownCMD(padapter, pHciCmd); | ||
4330 | break; | ||
4331 | } | ||
4332 | return status; | ||
4333 | } | ||
4334 | |||
4335 | static enum hci_status | ||
4336 | bthci_HandleOGFStatusParameters(struct rtw_adapter *padapter, | ||
4337 | struct packet_irp_hcicmd_data *pHciCmd) | ||
4338 | { | ||
4339 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
4340 | |||
4341 | switch (pHciCmd->OCF) { | ||
4342 | case HCI_READ_FAILED_CONTACT_COUNTER: | ||
4343 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_FAILED_CONTACT_COUNTER\n")); | ||
4344 | status = bthci_CmdReadFailedContactCounter(padapter, pHciCmd); | ||
4345 | break; | ||
4346 | case HCI_RESET_FAILED_CONTACT_COUNTER: | ||
4347 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_RESET_FAILED_CONTACT_COUNTER\n")); | ||
4348 | status = bthci_CmdResetFailedContactCounter(padapter, pHciCmd); | ||
4349 | break; | ||
4350 | case HCI_READ_LINK_QUALITY: | ||
4351 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LINK_QUALITY\n")); | ||
4352 | status = bthci_CmdReadLinkQuality(padapter, pHciCmd); | ||
4353 | break; | ||
4354 | case HCI_READ_RSSI: | ||
4355 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_RSSI\n")); | ||
4356 | status = bthci_CmdReadRSSI(padapter); | ||
4357 | break; | ||
4358 | case HCI_READ_LOCAL_AMP_INFO: | ||
4359 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_AMP_INFO\n")); | ||
4360 | status = bthci_CmdReadLocalAMPInfo(padapter); | ||
4361 | break; | ||
4362 | case HCI_READ_LOCAL_AMP_ASSOC: | ||
4363 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_AMP_ASSOC\n")); | ||
4364 | status = bthci_CmdReadLocalAMPAssoc(padapter, pHciCmd); | ||
4365 | break; | ||
4366 | case HCI_WRITE_REMOTE_AMP_ASSOC: | ||
4367 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_REMOTE_AMP_ASSOC\n")); | ||
4368 | status = bthci_CmdWriteRemoteAMPAssoc(padapter, pHciCmd); | ||
4369 | break; | ||
4370 | default: | ||
4371 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_HandleOGFStatusParameters(), Unknown case = 0x%x\n", pHciCmd->OCF)); | ||
4372 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n")); | ||
4373 | status = bthci_UnknownCMD(padapter, pHciCmd); | ||
4374 | break; | ||
4375 | } | ||
4376 | return status; | ||
4377 | } | ||
4378 | |||
4379 | static enum hci_status | ||
4380 | bthci_HandleOGFLinkControlCMD(struct rtw_adapter *padapter, | ||
4381 | struct packet_irp_hcicmd_data *pHciCmd) | ||
4382 | { | ||
4383 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
4384 | |||
4385 | switch (pHciCmd->OCF) { | ||
4386 | case HCI_CREATE_PHYSICAL_LINK: | ||
4387 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_CREATE_PHYSICAL_LINK\n")); | ||
4388 | status = bthci_CmdCreatePhysicalLink(padapter, pHciCmd); | ||
4389 | break; | ||
4390 | case HCI_ACCEPT_PHYSICAL_LINK: | ||
4391 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ACCEPT_PHYSICAL_LINK\n")); | ||
4392 | status = bthci_CmdAcceptPhysicalLink(padapter, pHciCmd); | ||
4393 | break; | ||
4394 | case HCI_DISCONNECT_PHYSICAL_LINK: | ||
4395 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_DISCONNECT_PHYSICAL_LINK\n")); | ||
4396 | status = bthci_CmdDisconnectPhysicalLink(padapter, pHciCmd); | ||
4397 | break; | ||
4398 | case HCI_CREATE_LOGICAL_LINK: | ||
4399 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_CREATE_LOGICAL_LINK\n")); | ||
4400 | status = bthci_CmdCreateLogicalLink(padapter, pHciCmd); | ||
4401 | break; | ||
4402 | case HCI_ACCEPT_LOGICAL_LINK: | ||
4403 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ACCEPT_LOGICAL_LINK\n")); | ||
4404 | status = bthci_CmdAcceptLogicalLink(padapter, pHciCmd); | ||
4405 | break; | ||
4406 | case HCI_DISCONNECT_LOGICAL_LINK: | ||
4407 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_DISCONNECT_LOGICAL_LINK\n")); | ||
4408 | status = bthci_CmdDisconnectLogicalLink(padapter, pHciCmd); | ||
4409 | break; | ||
4410 | case HCI_LOGICAL_LINK_CANCEL: | ||
4411 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_LOGICAL_LINK_CANCEL\n")); | ||
4412 | status = bthci_CmdLogicalLinkCancel(padapter, pHciCmd); | ||
4413 | break; | ||
4414 | case HCI_FLOW_SPEC_MODIFY: | ||
4415 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_FLOW_SPEC_MODIFY\n")); | ||
4416 | status = bthci_CmdFlowSpecModify(padapter, pHciCmd); | ||
4417 | break; | ||
4418 | default: | ||
4419 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_HandleOGFLinkControlCMD(), Unknown case = 0x%x\n", pHciCmd->OCF)); | ||
4420 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n")); | ||
4421 | status = bthci_UnknownCMD(padapter, pHciCmd); | ||
4422 | break; | ||
4423 | } | ||
4424 | return status; | ||
4425 | } | ||
4426 | |||
4427 | static enum hci_status | ||
4428 | bthci_HandleOGFTestingCMD(struct rtw_adapter *padapter, | ||
4429 | struct packet_irp_hcicmd_data *pHciCmd) | ||
4430 | { | ||
4431 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
4432 | switch (pHciCmd->OCF) { | ||
4433 | case HCI_ENABLE_DEVICE_UNDER_TEST_MODE: | ||
4434 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ENABLE_DEVICE_UNDER_TEST_MODE\n")); | ||
4435 | bthci_CmdEnableDeviceUnderTestMode(padapter, pHciCmd); | ||
4436 | break; | ||
4437 | case HCI_AMP_TEST_END: | ||
4438 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_AMP_TEST_END\n")); | ||
4439 | bthci_CmdAMPTestEnd(padapter, pHciCmd); | ||
4440 | break; | ||
4441 | case HCI_AMP_TEST_COMMAND: | ||
4442 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_AMP_TEST_COMMAND\n")); | ||
4443 | bthci_CmdAMPTestCommand(padapter, pHciCmd); | ||
4444 | break; | ||
4445 | case HCI_ENABLE_AMP_RECEIVER_REPORTS: | ||
4446 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ENABLE_AMP_RECEIVER_REPORTS\n")); | ||
4447 | bthci_CmdEnableAMPReceiverReports(padapter, pHciCmd); | ||
4448 | break; | ||
4449 | default: | ||
4450 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n")); | ||
4451 | status = bthci_UnknownCMD(padapter, pHciCmd); | ||
4452 | break; | ||
4453 | } | ||
4454 | return status; | ||
4455 | } | ||
4456 | |||
4457 | static enum hci_status | ||
4458 | bthci_HandleOGFExtension(struct rtw_adapter *padapter, | ||
4459 | struct packet_irp_hcicmd_data *pHciCmd) | ||
4460 | { | ||
4461 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
4462 | switch (pHciCmd->OCF) { | ||
4463 | case HCI_SET_ACL_LINK_DATA_FLOW_MODE: | ||
4464 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_SET_ACL_LINK_DATA_FLOW_MODE\n")); | ||
4465 | status = bthci_CmdSetACLLinkDataFlowMode(padapter, pHciCmd); | ||
4466 | break; | ||
4467 | case HCI_SET_ACL_LINK_STATUS: | ||
4468 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_SET_ACL_LINK_STATUS\n")); | ||
4469 | status = bthci_CmdSetACLLinkStatus(padapter, pHciCmd); | ||
4470 | break; | ||
4471 | case HCI_SET_SCO_LINK_STATUS: | ||
4472 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_SET_SCO_LINK_STATUS\n")); | ||
4473 | status = bthci_CmdSetSCOLinkStatus(padapter, pHciCmd); | ||
4474 | break; | ||
4475 | case HCI_SET_RSSI_VALUE: | ||
4476 | RTPRINT(FIOCTL, IOCTL_BT_EVENT_PERIODICAL, ("HCI_SET_RSSI_VALUE\n")); | ||
4477 | status = bthci_CmdSetRSSIValue(padapter, pHciCmd); | ||
4478 | break; | ||
4479 | case HCI_SET_CURRENT_BLUETOOTH_STATUS: | ||
4480 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_SET_CURRENT_BLUETOOTH_STATUS\n")); | ||
4481 | status = bthci_CmdSetCurrentBluetoothStatus(padapter, pHciCmd); | ||
4482 | break; | ||
4483 | /* The following is for RTK8723 */ | ||
4484 | |||
4485 | case HCI_EXTENSION_VERSION_NOTIFY: | ||
4486 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_EXTENSION_VERSION_NOTIFY\n")); | ||
4487 | status = bthci_CmdExtensionVersionNotify(padapter, pHciCmd); | ||
4488 | break; | ||
4489 | case HCI_LINK_STATUS_NOTIFY: | ||
4490 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_LINK_STATUS_NOTIFY\n")); | ||
4491 | status = bthci_CmdLinkStatusNotify(padapter, pHciCmd); | ||
4492 | break; | ||
4493 | case HCI_BT_OPERATION_NOTIFY: | ||
4494 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_BT_OPERATION_NOTIFY\n")); | ||
4495 | status = bthci_CmdBtOperationNotify(padapter, pHciCmd); | ||
4496 | break; | ||
4497 | case HCI_ENABLE_WIFI_SCAN_NOTIFY: | ||
4498 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_ENABLE_WIFI_SCAN_NOTIFY\n")); | ||
4499 | status = bthci_CmdEnableWifiScanNotify(padapter, pHciCmd); | ||
4500 | break; | ||
4501 | |||
4502 | /* The following is for IVT */ | ||
4503 | case HCI_WIFI_CURRENT_CHANNEL: | ||
4504 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_WIFI_CURRENT_CHANNEL\n")); | ||
4505 | status = bthci_CmdWIFICurrentChannel(padapter, pHciCmd); | ||
4506 | break; | ||
4507 | case HCI_WIFI_CURRENT_BANDWIDTH: | ||
4508 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_WIFI_CURRENT_BANDWIDTH\n")); | ||
4509 | status = bthci_CmdWIFICurrentBandwidth(padapter, pHciCmd); | ||
4510 | break; | ||
4511 | case HCI_WIFI_CONNECTION_STATUS: | ||
4512 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_WIFI_CONNECTION_STATUS\n")); | ||
4513 | status = bthci_CmdWIFIConnectionStatus(padapter, pHciCmd); | ||
4514 | break; | ||
4515 | |||
4516 | default: | ||
4517 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_UNKNOWN_COMMAND\n")); | ||
4518 | status = bthci_UnknownCMD(padapter, pHciCmd); | ||
4519 | break; | ||
4520 | } | ||
4521 | return status; | ||
4522 | } | ||
4523 | |||
4524 | static void | ||
4525 | bthci_StateStarting(struct rtw_adapter *padapter, | ||
4526 | enum hci_state_with_cmd StateCmd, u8 EntryNum) | ||
4527 | { | ||
4528 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
4529 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
4530 | |||
4531 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Starting], ")); | ||
4532 | switch (StateCmd) { | ||
4533 | case STATE_CMD_CONNECT_ACCEPT_TIMEOUT: | ||
4534 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_CONNECT_ACCEPT_TIMEOUT\n")); | ||
4535 | pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_CONNECT_ACCEPT_TIMEOUT; | ||
4536 | pBtMgnt->bNeedNotifyAMPNoCap = true; | ||
4537 | BTHCI_DisconnectPeer(padapter, EntryNum); | ||
4538 | break; | ||
4539 | case STATE_CMD_DISCONNECT_PHY_LINK: | ||
4540 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n")); | ||
4541 | |||
4542 | bthci_EventDisconnectPhyLinkComplete(padapter, | ||
4543 | HCI_STATUS_SUCCESS, | ||
4544 | pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason, | ||
4545 | EntryNum); | ||
4546 | |||
4547 | del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer); | ||
4548 | |||
4549 | pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
4550 | |||
4551 | BTHCI_DisconnectPeer(padapter, EntryNum); | ||
4552 | break; | ||
4553 | case STATE_CMD_MAC_START_COMPLETE: | ||
4554 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_START_COMPLETE\n")); | ||
4555 | if (pBTInfo->BtAsocEntry[EntryNum].AMPRole == AMP_BTAP_CREATOR) | ||
4556 | bthci_EventChannelSelected(padapter, EntryNum); | ||
4557 | break; | ||
4558 | default: | ||
4559 | RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd)); | ||
4560 | break; | ||
4561 | } | ||
4562 | } | ||
4563 | |||
4564 | static void | ||
4565 | bthci_StateConnecting(struct rtw_adapter *padapter, | ||
4566 | enum hci_state_with_cmd StateCmd, u8 EntryNum) | ||
4567 | { | ||
4568 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
4569 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
4570 | |||
4571 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Connecting], ")); | ||
4572 | switch (StateCmd) { | ||
4573 | case STATE_CMD_CONNECT_ACCEPT_TIMEOUT: | ||
4574 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_CONNECT_ACCEPT_TIMEOUT\n")); | ||
4575 | pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_CONNECT_ACCEPT_TIMEOUT; | ||
4576 | pBtMgnt->bNeedNotifyAMPNoCap = true; | ||
4577 | BTHCI_DisconnectPeer(padapter, EntryNum); | ||
4578 | break; | ||
4579 | case STATE_CMD_MAC_CONNECT_COMPLETE: | ||
4580 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_CONNECT_COMPLETE\n")); | ||
4581 | |||
4582 | if (pBTInfo->BtAsocEntry[EntryNum].AMPRole == AMP_BTAP_JOINER) { | ||
4583 | RT_TRACE(_module_rtl871x_security_c_, | ||
4584 | _drv_info_, ("StateConnecting \n")); | ||
4585 | } | ||
4586 | break; | ||
4587 | case STATE_CMD_DISCONNECT_PHY_LINK: | ||
4588 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n")); | ||
4589 | |||
4590 | bthci_EventDisconnectPhyLinkComplete(padapter, | ||
4591 | HCI_STATUS_SUCCESS, | ||
4592 | pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason, | ||
4593 | EntryNum); | ||
4594 | |||
4595 | pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
4596 | |||
4597 | del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer); | ||
4598 | |||
4599 | BTHCI_DisconnectPeer(padapter, EntryNum); | ||
4600 | |||
4601 | break; | ||
4602 | case STATE_CMD_MAC_CONNECT_CANCEL_INDICATE: | ||
4603 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_CONNECT_CANCEL_INDICATE\n")); | ||
4604 | pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_CONTROLLER_BUSY; | ||
4605 | /* Because this state cmd is caused by the BTHCI_EventAMPStatusChange(), */ | ||
4606 | /* we don't need to send event in the following BTHCI_DisconnectPeer() again. */ | ||
4607 | pBtMgnt->bNeedNotifyAMPNoCap = false; | ||
4608 | BTHCI_DisconnectPeer(padapter, EntryNum); | ||
4609 | break; | ||
4610 | default: | ||
4611 | RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd)); | ||
4612 | break; | ||
4613 | } | ||
4614 | } | ||
4615 | |||
4616 | static void | ||
4617 | bthci_StateConnected(struct rtw_adapter *padapter, | ||
4618 | enum hci_state_with_cmd StateCmd, u8 EntryNum) | ||
4619 | { | ||
4620 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
4621 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
4622 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
4623 | |||
4624 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Connected], ")); | ||
4625 | switch (StateCmd) { | ||
4626 | u8 i; | ||
4627 | u16 logicHandle = 0; | ||
4628 | case STATE_CMD_DISCONNECT_PHY_LINK: | ||
4629 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n")); | ||
4630 | |||
4631 | /* When we are trying to disconnect the phy link, we should disconnect log link first, */ | ||
4632 | for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) { | ||
4633 | if (pBTInfo->BtAsocEntry[EntryNum].LogLinkCmdData->BtLogLinkhandle != 0) { | ||
4634 | logicHandle = pBTInfo->BtAsocEntry[EntryNum].LogLinkCmdData->BtLogLinkhandle; | ||
4635 | |||
4636 | bthci_EventDisconnectLogicalLinkComplete(padapter, HCI_STATUS_SUCCESS, | ||
4637 | logicHandle, pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason); | ||
4638 | |||
4639 | pBTInfo->BtAsocEntry[EntryNum].LogLinkCmdData->BtLogLinkhandle = 0; | ||
4640 | } | ||
4641 | } | ||
4642 | |||
4643 | bthci_EventDisconnectPhyLinkComplete(padapter, | ||
4644 | HCI_STATUS_SUCCESS, | ||
4645 | pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason, | ||
4646 | EntryNum); | ||
4647 | |||
4648 | del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer); | ||
4649 | |||
4650 | BTHCI_DisconnectPeer(padapter, EntryNum); | ||
4651 | break; | ||
4652 | |||
4653 | case STATE_CMD_MAC_DISCONNECT_INDICATE: | ||
4654 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_DISCONNECT_INDICATE\n")); | ||
4655 | |||
4656 | bthci_EventDisconnectPhyLinkComplete(padapter, | ||
4657 | HCI_STATUS_SUCCESS, | ||
4658 | /* TODO: Remote Host not local host */ | ||
4659 | HCI_STATUS_CONNECT_TERMINATE_LOCAL_HOST, | ||
4660 | EntryNum); | ||
4661 | BTHCI_DisconnectPeer(padapter, EntryNum); | ||
4662 | |||
4663 | break; | ||
4664 | case STATE_CMD_ENTER_STATE: | ||
4665 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_ENTER_STATE\n")); | ||
4666 | |||
4667 | if (pBtMgnt->bBTConnectInProgress) { | ||
4668 | pBtMgnt->bBTConnectInProgress = false; | ||
4669 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress OFF!!\n")); | ||
4670 | } | ||
4671 | pBTInfo->BtAsocEntry[EntryNum].BtCurrentState = HCI_STATE_CONNECTED; | ||
4672 | pBTInfo->BtAsocEntry[EntryNum].b4waySuccess = true; | ||
4673 | pBtMgnt->bStartSendSupervisionPkt = true; | ||
4674 | |||
4675 | /* for rate adaptive */ | ||
4676 | |||
4677 | if (padapter->HalFunc.UpdateRAMaskHandler) | ||
4678 | padapter->HalFunc.UpdateRAMaskHandler(padapter, MAX_FW_SUPPORT_MACID_NUM-1-EntryNum, 0); | ||
4679 | |||
4680 | rtw_hal_set_hwreg23a(padapter, HW_VAR_BASIC_RATE, padapter->mlmepriv.cur_network.network.SupportedRates); | ||
4681 | BTDM_SetFwChnlInfo(padapter, RT_MEDIA_CONNECT); | ||
4682 | break; | ||
4683 | default: | ||
4684 | RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd)); | ||
4685 | break; | ||
4686 | } | ||
4687 | } | ||
4688 | |||
4689 | static void | ||
4690 | bthci_StateAuth(struct rtw_adapter *padapter, enum hci_state_with_cmd StateCmd, | ||
4691 | u8 EntryNum) | ||
4692 | { | ||
4693 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
4694 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
4695 | |||
4696 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Authenticating], ")); | ||
4697 | switch (StateCmd) { | ||
4698 | case STATE_CMD_CONNECT_ACCEPT_TIMEOUT: | ||
4699 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_CONNECT_ACCEPT_TIMEOUT\n")); | ||
4700 | pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_CONNECT_ACCEPT_TIMEOUT; | ||
4701 | pBtMgnt->bNeedNotifyAMPNoCap = true; | ||
4702 | BTHCI_DisconnectPeer(padapter, EntryNum); | ||
4703 | break; | ||
4704 | case STATE_CMD_DISCONNECT_PHY_LINK: | ||
4705 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n")); | ||
4706 | bthci_EventDisconnectPhyLinkComplete(padapter, | ||
4707 | HCI_STATUS_SUCCESS, | ||
4708 | pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason, | ||
4709 | EntryNum); | ||
4710 | |||
4711 | pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_UNKNOW_CONNECT_ID; | ||
4712 | |||
4713 | del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer); | ||
4714 | |||
4715 | BTHCI_DisconnectPeer(padapter, EntryNum); | ||
4716 | break; | ||
4717 | case STATE_CMD_4WAY_FAILED: | ||
4718 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_4WAY_FAILED\n")); | ||
4719 | |||
4720 | pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_AUTH_FAIL; | ||
4721 | pBtMgnt->bNeedNotifyAMPNoCap = true; | ||
4722 | |||
4723 | BTHCI_DisconnectPeer(padapter, EntryNum); | ||
4724 | |||
4725 | del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer); | ||
4726 | break; | ||
4727 | case STATE_CMD_4WAY_SUCCESSED: | ||
4728 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_4WAY_SUCCESSED\n")); | ||
4729 | |||
4730 | bthci_EventPhysicalLinkComplete(padapter, HCI_STATUS_SUCCESS, EntryNum, INVALID_PL_HANDLE); | ||
4731 | |||
4732 | del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer); | ||
4733 | |||
4734 | BTHCI_SM_WITH_INFO(padapter, HCI_STATE_CONNECTED, STATE_CMD_ENTER_STATE, EntryNum); | ||
4735 | break; | ||
4736 | default: | ||
4737 | RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd)); | ||
4738 | break; | ||
4739 | } | ||
4740 | } | ||
4741 | |||
4742 | static void | ||
4743 | bthci_StateDisconnecting(struct rtw_adapter *padapter, | ||
4744 | enum hci_state_with_cmd StateCmd, u8 EntryNum) | ||
4745 | { | ||
4746 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
4747 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
4748 | |||
4749 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Disconnecting], ")); | ||
4750 | switch (StateCmd) { | ||
4751 | case STATE_CMD_MAC_CONNECT_CANCEL_INDICATE: | ||
4752 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_CONNECT_CANCEL_INDICATE\n")); | ||
4753 | if (pBTInfo->BtAsocEntry[EntryNum].bNeedPhysLinkCompleteEvent) { | ||
4754 | bthci_EventPhysicalLinkComplete(padapter, | ||
4755 | pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus, | ||
4756 | EntryNum, INVALID_PL_HANDLE); | ||
4757 | } | ||
4758 | |||
4759 | if (pBtMgnt->bBTConnectInProgress) { | ||
4760 | pBtMgnt->bBTConnectInProgress = false; | ||
4761 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress OFF!!\n")); | ||
4762 | } | ||
4763 | |||
4764 | BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_ENTER_STATE, EntryNum); | ||
4765 | break; | ||
4766 | case STATE_CMD_DISCONNECT_PHY_LINK: | ||
4767 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n")); | ||
4768 | |||
4769 | bthci_EventDisconnectPhyLinkComplete(padapter, | ||
4770 | HCI_STATUS_SUCCESS, | ||
4771 | pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason, | ||
4772 | EntryNum); | ||
4773 | |||
4774 | del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer); | ||
4775 | |||
4776 | BTHCI_DisconnectPeer(padapter, EntryNum); | ||
4777 | break; | ||
4778 | default: | ||
4779 | RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd)); | ||
4780 | break; | ||
4781 | } | ||
4782 | } | ||
4783 | |||
4784 | static void | ||
4785 | bthci_StateDisconnected(struct rtw_adapter *padapter, | ||
4786 | enum hci_state_with_cmd StateCmd, u8 EntryNum) | ||
4787 | { | ||
4788 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
4789 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
4790 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
4791 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
4792 | |||
4793 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Disconnected], ")); | ||
4794 | switch (StateCmd) { | ||
4795 | case STATE_CMD_CREATE_PHY_LINK: | ||
4796 | case STATE_CMD_ACCEPT_PHY_LINK: | ||
4797 | if (StateCmd == STATE_CMD_CREATE_PHY_LINK) | ||
4798 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_CREATE_PHY_LINK\n")); | ||
4799 | else | ||
4800 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_ACCEPT_PHY_LINK\n")); | ||
4801 | |||
4802 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT PS], Disable IPS and LPS\n")); | ||
4803 | ips_leave23a(padapter); | ||
4804 | LPS_Leave23a(padapter); | ||
4805 | |||
4806 | pBtMgnt->bPhyLinkInProgress = true; | ||
4807 | pBtMgnt->BTCurrentConnectType = BT_DISCONNECT; | ||
4808 | pBtMgnt->CurrentBTConnectionCnt++; | ||
4809 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], CurrentBTConnectionCnt = %d\n", | ||
4810 | pBtMgnt->CurrentBTConnectionCnt)); | ||
4811 | pBtMgnt->BtOperationOn = true; | ||
4812 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], Bt Operation ON!! CurrentConnectEntryNum = %d\n", | ||
4813 | pBtMgnt->CurrentConnectEntryNum)); | ||
4814 | |||
4815 | if (pBtMgnt->bBTConnectInProgress) { | ||
4816 | bthci_EventPhysicalLinkComplete(padapter, HCI_STATUS_CONTROLLER_BUSY, INVALID_ENTRY_NUM, pBtMgnt->BtCurrentPhyLinkhandle); | ||
4817 | bthci_RemoveEntryByEntryNum(padapter, EntryNum); | ||
4818 | return; | ||
4819 | } | ||
4820 | |||
4821 | if (StateCmd == STATE_CMD_CREATE_PHY_LINK) | ||
4822 | pBTInfo->BtAsocEntry[EntryNum].AMPRole = AMP_BTAP_CREATOR; | ||
4823 | else | ||
4824 | pBTInfo->BtAsocEntry[EntryNum].AMPRole = AMP_BTAP_JOINER; | ||
4825 | |||
4826 | /* 1. MAC not yet in selected channel */ | ||
4827 | while (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR)) { | ||
4828 | RTPRINT(FIOCTL, IOCTL_STATE, ("Scan/Roaming/Wifi Link is in Progress, wait 200 ms\n")); | ||
4829 | mdelay(200); | ||
4830 | } | ||
4831 | /* 2. MAC already in selected channel */ | ||
4832 | RTPRINT(FIOCTL, IOCTL_STATE, ("Channel is Ready\n")); | ||
4833 | mod_timer(&pBTInfo->BTHCIJoinTimeoutTimer, | ||
4834 | jiffies + msecs_to_jiffies(pBtHciInfo->ConnAcceptTimeout)); | ||
4835 | |||
4836 | pBTInfo->BtAsocEntry[EntryNum].bNeedPhysLinkCompleteEvent = true; | ||
4837 | break; | ||
4838 | case STATE_CMD_DISCONNECT_PHY_LINK: | ||
4839 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n")); | ||
4840 | |||
4841 | del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer); | ||
4842 | |||
4843 | bthci_EventDisconnectPhyLinkComplete(padapter, | ||
4844 | HCI_STATUS_SUCCESS, | ||
4845 | pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason, | ||
4846 | EntryNum); | ||
4847 | |||
4848 | if (pBTInfo->BtAsocEntry[EntryNum].bNeedPhysLinkCompleteEvent) { | ||
4849 | bthci_EventPhysicalLinkComplete(padapter, | ||
4850 | HCI_STATUS_UNKNOW_CONNECT_ID, | ||
4851 | EntryNum, INVALID_PL_HANDLE); | ||
4852 | } | ||
4853 | |||
4854 | if (pBtMgnt->bBTConnectInProgress) { | ||
4855 | pBtMgnt->bBTConnectInProgress = false; | ||
4856 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress OFF!!\n")); | ||
4857 | } | ||
4858 | BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_ENTER_STATE, EntryNum); | ||
4859 | bthci_RemoveEntryByEntryNum(padapter, EntryNum); | ||
4860 | break; | ||
4861 | case STATE_CMD_ENTER_STATE: | ||
4862 | RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_ENTER_STATE\n")); | ||
4863 | break; | ||
4864 | default: | ||
4865 | RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd)); | ||
4866 | break; | ||
4867 | } | ||
4868 | } | ||
4869 | |||
4870 | void BTHCI_EventParse(struct rtw_adapter *padapter, void *pEvntData, u32 dataLen) | ||
4871 | { | ||
4872 | } | ||
4873 | |||
4874 | u8 BTHCI_HsConnectionEstablished(struct rtw_adapter *padapter) | ||
4875 | { | ||
4876 | u8 bBtConnectionExist = false; | ||
4877 | struct bt_30info *pBtinfo = GET_BT_INFO(padapter); | ||
4878 | u8 i; | ||
4879 | |||
4880 | for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) { | ||
4881 | if (pBtinfo->BtAsocEntry[i].b4waySuccess) { | ||
4882 | bBtConnectionExist = true; | ||
4883 | break; | ||
4884 | } | ||
4885 | } | ||
4886 | |||
4887 | /*RTPRINT(FIOCTL, IOCTL_STATE, (" BTHCI_HsConnectionEstablished(), connection exist = %d\n", bBtConnectionExist)); */ | ||
4888 | |||
4889 | return bBtConnectionExist; | ||
4890 | } | ||
4891 | |||
4892 | static u8 | ||
4893 | BTHCI_CheckProfileExist(struct rtw_adapter *padapter, | ||
4894 | enum bt_traffic_mode_profile Profile) | ||
4895 | { | ||
4896 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
4897 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
4898 | u8 IsPRofile = false; | ||
4899 | u8 i = 0; | ||
4900 | |||
4901 | for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) { | ||
4902 | if (pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile == Profile) { | ||
4903 | IsPRofile = true; | ||
4904 | break; | ||
4905 | } | ||
4906 | } | ||
4907 | |||
4908 | return IsPRofile; | ||
4909 | } | ||
4910 | |||
4911 | void BTHCI_UpdateBTProfileRTKToMoto(struct rtw_adapter *padapter) | ||
4912 | { | ||
4913 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
4914 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
4915 | u8 i = 0; | ||
4916 | |||
4917 | pBtMgnt->ExtConfig.NumberOfSCO = 0; | ||
4918 | |||
4919 | for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) { | ||
4920 | pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile = BT_PROFILE_NONE; | ||
4921 | |||
4922 | if (pBtMgnt->ExtConfig.linkInfo[i].BTProfile == BT_PROFILE_SCO) | ||
4923 | pBtMgnt->ExtConfig.NumberOfSCO++; | ||
4924 | |||
4925 | pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile = pBtMgnt->ExtConfig.linkInfo[i].BTProfile; | ||
4926 | switch (pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile) { | ||
4927 | case BT_PROFILE_SCO: | ||
4928 | break; | ||
4929 | case BT_PROFILE_PAN: | ||
4930 | pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = BT_MOTOR_EXT_BE; | ||
4931 | pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = BT_MOTOR_EXT_BE; | ||
4932 | break; | ||
4933 | case BT_PROFILE_A2DP: | ||
4934 | pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = BT_MOTOR_EXT_GULB; | ||
4935 | pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = BT_MOTOR_EXT_GULB; | ||
4936 | break; | ||
4937 | case BT_PROFILE_HID: | ||
4938 | pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = BT_MOTOR_EXT_GUL; | ||
4939 | pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = BT_MOTOR_EXT_BE; | ||
4940 | break; | ||
4941 | default: | ||
4942 | break; | ||
4943 | } | ||
4944 | } | ||
4945 | |||
4946 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RTK, NumberOfHandle = %d, NumberOfSCO = %d\n", | ||
4947 | pBtMgnt->ExtConfig.NumberOfHandle, pBtMgnt->ExtConfig.NumberOfSCO)); | ||
4948 | } | ||
4949 | |||
4950 | void BTHCI_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType) | ||
4951 | { | ||
4952 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
4953 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
4954 | |||
4955 | if (pBtMgnt->ExtConfig.bEnableWifiScanNotify) | ||
4956 | bthci_EventExtWifiScanNotify(padapter, scanType); | ||
4957 | } | ||
4958 | |||
4959 | void | ||
4960 | BTHCI_StateMachine( | ||
4961 | struct rtw_adapter *padapter, | ||
4962 | u8 StateToEnter, | ||
4963 | enum hci_state_with_cmd StateCmd, | ||
4964 | u8 EntryNum | ||
4965 | ) | ||
4966 | { | ||
4967 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
4968 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
4969 | |||
4970 | if (EntryNum == 0xff) { | ||
4971 | RTPRINT(FIOCTL, IOCTL_STATE, (" StateMachine, error EntryNum = 0x%x \n", EntryNum)); | ||
4972 | return; | ||
4973 | } | ||
4974 | RTPRINT(FIOCTL, IOCTL_STATE, (" StateMachine, EntryNum = 0x%x, CurrentState = 0x%x, BtNextState = 0x%x, StateCmd = 0x%x , StateToEnter = 0x%x\n", | ||
4975 | EntryNum, pBTInfo->BtAsocEntry[EntryNum].BtCurrentState, pBTInfo->BtAsocEntry[EntryNum].BtNextState, StateCmd, StateToEnter)); | ||
4976 | |||
4977 | if (pBTInfo->BtAsocEntry[EntryNum].BtNextState & StateToEnter) { | ||
4978 | pBTInfo->BtAsocEntry[EntryNum].BtCurrentState = StateToEnter; | ||
4979 | |||
4980 | switch (StateToEnter) { | ||
4981 | case HCI_STATE_STARTING: | ||
4982 | pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTING | HCI_STATE_CONNECTING; | ||
4983 | bthci_StateStarting(padapter, StateCmd, EntryNum); | ||
4984 | break; | ||
4985 | case HCI_STATE_CONNECTING: | ||
4986 | pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_CONNECTING | HCI_STATE_DISCONNECTING | HCI_STATE_AUTHENTICATING; | ||
4987 | bthci_StateConnecting(padapter, StateCmd, EntryNum); | ||
4988 | break; | ||
4989 | case HCI_STATE_AUTHENTICATING: | ||
4990 | pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTING | HCI_STATE_CONNECTED; | ||
4991 | bthci_StateAuth(padapter, StateCmd, EntryNum); | ||
4992 | break; | ||
4993 | case HCI_STATE_CONNECTED: | ||
4994 | pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_CONNECTED | HCI_STATE_DISCONNECTING; | ||
4995 | bthci_StateConnected(padapter, StateCmd, EntryNum); | ||
4996 | break; | ||
4997 | case HCI_STATE_DISCONNECTING: | ||
4998 | pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTED | HCI_STATE_DISCONNECTING; | ||
4999 | bthci_StateDisconnecting(padapter, StateCmd, EntryNum); | ||
5000 | break; | ||
5001 | case HCI_STATE_DISCONNECTED: | ||
5002 | pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTED | HCI_STATE_STARTING | HCI_STATE_CONNECTING; | ||
5003 | bthci_StateDisconnected(padapter, StateCmd, EntryNum); | ||
5004 | break; | ||
5005 | default: | ||
5006 | RTPRINT(FIOCTL, IOCTL_STATE, (" StateMachine, Unknown state to enter!!!\n")); | ||
5007 | break; | ||
5008 | } | ||
5009 | } else { | ||
5010 | RTPRINT(FIOCTL, IOCTL_STATE, (" StateMachine, Wrong state to enter\n")); | ||
5011 | } | ||
5012 | |||
5013 | /* 20100325 Joseph: Disable/Enable IPS/LPS according to BT status. */ | ||
5014 | if (!pBtMgnt->bBTConnectInProgress && !pBtMgnt->BtOperationOn) { | ||
5015 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT PS], ips_enter23a()\n")); | ||
5016 | ips_enter23a(padapter); | ||
5017 | } | ||
5018 | } | ||
5019 | |||
5020 | void BTHCI_DisconnectPeer(struct rtw_adapter *padapter, u8 EntryNum) | ||
5021 | { | ||
5022 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
5023 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
5024 | |||
5025 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, (" BTHCI_DisconnectPeer()\n")); | ||
5026 | |||
5027 | BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTING, STATE_CMD_MAC_CONNECT_CANCEL_INDICATE, EntryNum); | ||
5028 | |||
5029 | if (pBTInfo->BtAsocEntry[EntryNum].bUsed) { | ||
5030 | /*BTPKT_SendDeauthentication(padapter, pBTInfo->BtAsocEntry[EntryNum].BTRemoteMACAddr, unspec_reason); not porting yet */ | ||
5031 | } | ||
5032 | |||
5033 | if (pBtMgnt->bBTConnectInProgress) { | ||
5034 | pBtMgnt->bBTConnectInProgress = false; | ||
5035 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress OFF!!\n")); | ||
5036 | } | ||
5037 | |||
5038 | bthci_RemoveEntryByEntryNum(padapter, EntryNum); | ||
5039 | |||
5040 | if (pBtMgnt->bNeedNotifyAMPNoCap) { | ||
5041 | RTPRINT(FIOCTL, IOCTL_STATE, ("[BT AMPStatus], set to invalid in BTHCI_DisconnectPeer()\n")); | ||
5042 | BTHCI_EventAMPStatusChange(padapter, AMP_STATUS_NO_CAPACITY_FOR_BT); | ||
5043 | } | ||
5044 | } | ||
5045 | |||
5046 | void BTHCI_EventNumOfCompletedDataBlocks(struct rtw_adapter *padapter) | ||
5047 | { | ||
5048 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
5049 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
5050 | struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo; | ||
5051 | u8 localBuf[TmpLocalBufSize] = ""; | ||
5052 | u8 *pRetPar, *pTriple; | ||
5053 | u8 len = 0, i, j, handleNum = 0; | ||
5054 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
5055 | u16 *pu2Temp, *pPackets, *pHandle, *pDblocks; | ||
5056 | u8 sent = 0; | ||
5057 | |||
5058 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
5059 | |||
5060 | if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_NUM_OF_COMPLETE_DATA_BLOCKS)) { | ||
5061 | RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Num Of Completed DataBlocks, Ignore to send NumOfCompletedDataBlocksEvent due to event mask page 2\n")); | ||
5062 | return; | ||
5063 | } | ||
5064 | |||
5065 | /* Return parameters starts from here */ | ||
5066 | pRetPar = &PPacketIrpEvent->Data[0]; | ||
5067 | pTriple = &pRetPar[3]; | ||
5068 | for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) { | ||
5069 | |||
5070 | for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) { | ||
5071 | if (pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle) { | ||
5072 | handleNum++; | ||
5073 | pHandle = (u16 *)&pTriple[0]; /* Handle[i] */ | ||
5074 | pPackets = (u16 *)&pTriple[2]; /* Num_Of_Completed_Packets[i] */ | ||
5075 | pDblocks = (u16 *)&pTriple[4]; /* Num_Of_Completed_Blocks[i] */ | ||
5076 | *pHandle = pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle; | ||
5077 | *pPackets = (u16)pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].TxPacketCount; | ||
5078 | *pDblocks = (u16)pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].TxPacketCount; | ||
5079 | if (pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].TxPacketCount) { | ||
5080 | sent = 1; | ||
5081 | RTPRINT(FIOCTL, IOCTL_BT_EVENT_DETAIL, | ||
5082 | ("[BT event], Num Of Completed DataBlocks, Handle = 0x%x, Num_Of_Completed_Packets = 0x%x, Num_Of_Completed_Blocks = 0x%x\n", | ||
5083 | *pHandle, *pPackets, *pDblocks)); | ||
5084 | } | ||
5085 | pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].TxPacketCount = 0; | ||
5086 | len += 6; | ||
5087 | pTriple += len; | ||
5088 | } | ||
5089 | } | ||
5090 | } | ||
5091 | |||
5092 | pRetPar[2] = handleNum; /* Number_of_Handles */ | ||
5093 | len += 1; | ||
5094 | pu2Temp = (u16 *)&pRetPar[0]; | ||
5095 | *pu2Temp = BTTotalDataBlockNum; | ||
5096 | len += 2; | ||
5097 | |||
5098 | PPacketIrpEvent->EventCode = HCI_EVENT_NUM_OF_COMPLETE_DATA_BLOCKS; | ||
5099 | PPacketIrpEvent->Length = len; | ||
5100 | if (handleNum && sent) | ||
5101 | bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2); | ||
5102 | } | ||
5103 | |||
5104 | void BTHCI_EventAMPStatusChange(struct rtw_adapter *padapter, u8 AMP_Status) | ||
5105 | { | ||
5106 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
5107 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
5108 | struct packet_irp_hcievent_data *PPacketIrpEvent; | ||
5109 | u8 len = 0; | ||
5110 | u8 localBuf[7] = ""; | ||
5111 | u8 *pRetPar; | ||
5112 | |||
5113 | if (AMP_Status == AMP_STATUS_NO_CAPACITY_FOR_BT) { | ||
5114 | pBtMgnt->BTNeedAMPStatusChg = true; | ||
5115 | pBtMgnt->bNeedNotifyAMPNoCap = false; | ||
5116 | |||
5117 | BTHCI_DisconnectAll(padapter); | ||
5118 | } else if (AMP_Status == AMP_STATUS_FULL_CAPACITY_FOR_BT) { | ||
5119 | pBtMgnt->BTNeedAMPStatusChg = false; | ||
5120 | } | ||
5121 | |||
5122 | PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]); | ||
5123 | /* Return parameters starts from here */ | ||
5124 | pRetPar = &PPacketIrpEvent->Data[0]; | ||
5125 | |||
5126 | pRetPar[0] = 0; /* Status */ | ||
5127 | len += 1; | ||
5128 | pRetPar[1] = AMP_Status; /* AMP_Status */ | ||
5129 | len += 1; | ||
5130 | |||
5131 | PPacketIrpEvent->EventCode = HCI_EVENT_AMP_STATUS_CHANGE; | ||
5132 | PPacketIrpEvent->Length = len; | ||
5133 | if (bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2) == RT_STATUS_SUCCESS) | ||
5134 | RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_STATE), ("[BT event], AMP Status Change, AMP_Status = %d\n", AMP_Status)); | ||
5135 | } | ||
5136 | |||
5137 | void BTHCI_DisconnectAll(struct rtw_adapter *padapter) | ||
5138 | { | ||
5139 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
5140 | u8 i; | ||
5141 | |||
5142 | RTPRINT(FIOCTL, IOCTL_STATE, (" DisconnectALL()\n")); | ||
5143 | |||
5144 | for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) { | ||
5145 | if (pBTInfo->BtAsocEntry[i].b4waySuccess) { | ||
5146 | BTHCI_SM_WITH_INFO(padapter, HCI_STATE_CONNECTED, STATE_CMD_DISCONNECT_PHY_LINK, i); | ||
5147 | } else if (pBTInfo->BtAsocEntry[i].bUsed) { | ||
5148 | if (pBTInfo->BtAsocEntry[i].BtCurrentState == HCI_STATE_CONNECTING) { | ||
5149 | BTHCI_SM_WITH_INFO(padapter, HCI_STATE_CONNECTING, STATE_CMD_MAC_CONNECT_CANCEL_INDICATE, i); | ||
5150 | } else if (pBTInfo->BtAsocEntry[i].BtCurrentState == HCI_STATE_DISCONNECTING) { | ||
5151 | BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTING, STATE_CMD_MAC_CONNECT_CANCEL_INDICATE, i); | ||
5152 | } | ||
5153 | } | ||
5154 | } | ||
5155 | } | ||
5156 | |||
5157 | enum hci_status | ||
5158 | BTHCI_HandleHCICMD( | ||
5159 | struct rtw_adapter *padapter, | ||
5160 | struct packet_irp_hcicmd_data *pHciCmd | ||
5161 | ) | ||
5162 | { | ||
5163 | enum hci_status status = HCI_STATUS_SUCCESS; | ||
5164 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
5165 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
5166 | |||
5167 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("\n")); | ||
5168 | RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("HCI Command start, OGF = 0x%x, OCF = 0x%x, Length = 0x%x\n", | ||
5169 | pHciCmd->OGF, pHciCmd->OCF, pHciCmd->Length)); | ||
5170 | if (pHciCmd->Length) { | ||
5171 | RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), "HCI Command, Hex Data :\n", | ||
5172 | &pHciCmd->Data[0], pHciCmd->Length); | ||
5173 | } | ||
5174 | if (pHciCmd->OGF == OGF_EXTENSION) { | ||
5175 | if (pHciCmd->OCF == HCI_SET_RSSI_VALUE) | ||
5176 | RTPRINT(FIOCTL, IOCTL_BT_EVENT_PERIODICAL, ("[BT cmd], ")); | ||
5177 | else | ||
5178 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[BT cmd], ")); | ||
5179 | } else { | ||
5180 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("[BT cmd], ")); | ||
5181 | } | ||
5182 | |||
5183 | pBtDbg->dbgHciInfo.hciCmdCnt++; | ||
5184 | |||
5185 | switch (pHciCmd->OGF) { | ||
5186 | case LINK_CONTROL_COMMANDS: | ||
5187 | status = bthci_HandleOGFLinkControlCMD(padapter, pHciCmd); | ||
5188 | break; | ||
5189 | case HOLD_MODE_COMMAND: | ||
5190 | break; | ||
5191 | case OGF_SET_EVENT_MASK_COMMAND: | ||
5192 | status = bthci_HandleOGFSetEventMaskCMD(padapter, pHciCmd); | ||
5193 | break; | ||
5194 | case OGF_INFORMATIONAL_PARAMETERS: | ||
5195 | status = bthci_HandleOGFInformationalParameters(padapter, pHciCmd); | ||
5196 | break; | ||
5197 | case OGF_STATUS_PARAMETERS: | ||
5198 | status = bthci_HandleOGFStatusParameters(padapter, pHciCmd); | ||
5199 | break; | ||
5200 | case OGF_TESTING_COMMANDS: | ||
5201 | status = bthci_HandleOGFTestingCMD(padapter, pHciCmd); | ||
5202 | break; | ||
5203 | case OGF_EXTENSION: | ||
5204 | status = bthci_HandleOGFExtension(padapter, pHciCmd); | ||
5205 | break; | ||
5206 | default: | ||
5207 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI Command(), Unknown OGF = 0x%x\n", pHciCmd->OGF)); | ||
5208 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n")); | ||
5209 | status = bthci_UnknownCMD(padapter, pHciCmd); | ||
5210 | break; | ||
5211 | } | ||
5212 | RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("HCI Command execution end!!\n")); | ||
5213 | |||
5214 | return status; | ||
5215 | } | ||
5216 | |||
5217 | /* ===== End of sync from SD7 driver COMMOM/bt_hci.c ===== */ | ||
5218 | #endif | ||
5219 | |||
5220 | #ifdef __HALBTC87231ANT_C__ /* HAL/BTCoexist/HalBtc87231Ant.c */ | ||
5221 | |||
5222 | static const char *const BtStateString[] = { | ||
5223 | "BT_DISABLED", | ||
5224 | "BT_NO_CONNECTION", | ||
5225 | "BT_CONNECT_IDLE", | ||
5226 | "BT_INQ_OR_PAG", | ||
5227 | "BT_ACL_ONLY_BUSY", | ||
5228 | "BT_SCO_ONLY_BUSY", | ||
5229 | "BT_ACL_SCO_BUSY", | ||
5230 | "BT_ACL_INQ_OR_PAG", | ||
5231 | "BT_STATE_NOT_DEFINED" | ||
5232 | }; | ||
5233 | |||
5234 | /* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc87231Ant.c ===== */ | ||
5235 | |||
5236 | static void btdm_SetFwIgnoreWlanAct(struct rtw_adapter *padapter, u8 bEnable) | ||
5237 | { | ||
5238 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
5239 | u8 H2C_Parameter[1] = {0}; | ||
5240 | |||
5241 | if (bEnable) { | ||
5242 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Ignore Wlan_Act !!\n")); | ||
5243 | H2C_Parameter[0] |= BIT(0); /* function enable */ | ||
5244 | pHalData->bt_coexist.bFWCoexistAllOff = false; | ||
5245 | } else { | ||
5246 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT don't ignore Wlan_Act !!\n")); | ||
5247 | } | ||
5248 | |||
5249 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, write 0x25 = 0x%02x\n", | ||
5250 | H2C_Parameter[0])); | ||
5251 | |||
5252 | FillH2CCmd(padapter, BT_IGNORE_WLAN_ACT_EID, 1, H2C_Parameter); | ||
5253 | } | ||
5254 | |||
5255 | static void btdm_NotifyFwScan(struct rtw_adapter *padapter, u8 scanType) | ||
5256 | { | ||
5257 | u8 H2C_Parameter[1] = {0}; | ||
5258 | |||
5259 | if (scanType == true) | ||
5260 | H2C_Parameter[0] = 0x1; | ||
5261 | |||
5262 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Notify FW for wifi scan, write 0x3b = 0x%02x\n", | ||
5263 | H2C_Parameter[0])); | ||
5264 | |||
5265 | FillH2CCmd(padapter, 0x3b, 1, H2C_Parameter); | ||
5266 | } | ||
5267 | |||
5268 | static void btdm_1AntSetPSMode(struct rtw_adapter *padapter, | ||
5269 | u8 enable, u8 smartps, u8 mode) | ||
5270 | { | ||
5271 | struct pwrctrl_priv *pwrctrl; | ||
5272 | |||
5273 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Current LPS(%s, %d), smartps =%d\n", enable == true?"ON":"OFF", mode, smartps)); | ||
5274 | |||
5275 | pwrctrl = &padapter->pwrctrlpriv; | ||
5276 | |||
5277 | if (enable == true) { | ||
5278 | rtw_set_ps_mode23a(padapter, PS_MODE_MIN, smartps, mode); | ||
5279 | } else { | ||
5280 | rtw_set_ps_mode23a(padapter, PS_MODE_ACTIVE, 0, 0); | ||
5281 | LPS_RF_ON_check23a(padapter, 100); | ||
5282 | } | ||
5283 | } | ||
5284 | |||
5285 | static void btdm_1AntTSFSwitch(struct rtw_adapter *padapter, u8 enable) | ||
5286 | { | ||
5287 | u8 oldVal, newVal; | ||
5288 | |||
5289 | oldVal = rtw_read8(padapter, 0x550); | ||
5290 | |||
5291 | if (enable) | ||
5292 | newVal = oldVal | EN_BCN_FUNCTION; | ||
5293 | else | ||
5294 | newVal = oldVal & ~EN_BCN_FUNCTION; | ||
5295 | |||
5296 | if (oldVal != newVal) | ||
5297 | rtw_write8(padapter, 0x550, newVal); | ||
5298 | } | ||
5299 | |||
5300 | static u8 btdm_Is1AntPsTdmaStateChange(struct rtw_adapter *padapter) | ||
5301 | { | ||
5302 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
5303 | struct btdm_8723a_1ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant; | ||
5304 | |||
5305 | if ((pBtdm8723->bPrePsTdmaOn != pBtdm8723->bCurPsTdmaOn) || | ||
5306 | (pBtdm8723->prePsTdma != pBtdm8723->curPsTdma)) | ||
5307 | return true; | ||
5308 | else | ||
5309 | return false; | ||
5310 | } | ||
5311 | |||
5312 | /* Before enter TDMA, make sure Power Saving is enable! */ | ||
5313 | static void | ||
5314 | btdm_1AntPsTdma( | ||
5315 | struct rtw_adapter *padapter, | ||
5316 | u8 bTurnOn, | ||
5317 | u8 type | ||
5318 | ) | ||
5319 | { | ||
5320 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
5321 | struct btdm_8723a_1ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant; | ||
5322 | |||
5323 | pBtdm8723->bCurPsTdmaOn = bTurnOn; | ||
5324 | pBtdm8723->curPsTdma = type; | ||
5325 | if (bTurnOn) { | ||
5326 | switch (type) { | ||
5327 | case 1: /* A2DP Level-1 or FTP/OPP */ | ||
5328 | default: | ||
5329 | if (btdm_Is1AntPsTdmaStateChange(padapter)) { | ||
5330 | /* wide duration for WiFi */ | ||
5331 | BTDM_SetFw3a(padapter, 0xd3, 0x1a, 0x1a, 0x0, 0x58); | ||
5332 | } | ||
5333 | break; | ||
5334 | case 2: /* A2DP Level-2 */ | ||
5335 | if (btdm_Is1AntPsTdmaStateChange(padapter)) { | ||
5336 | /* normal duration for WiFi */ | ||
5337 | BTDM_SetFw3a(padapter, 0xd3, 0x12, 0x12, 0x0, 0x58); | ||
5338 | } | ||
5339 | break; | ||
5340 | case 3: /* BT FTP/OPP */ | ||
5341 | if (btdm_Is1AntPsTdmaStateChange(padapter)) { | ||
5342 | /* normal duration for WiFi */ | ||
5343 | BTDM_SetFw3a(padapter, 0xd3, 0x30, 0x03, 0x10, 0x58); | ||
5344 | |||
5345 | } | ||
5346 | break; | ||
5347 | case 4: /* for wifi scan & BT is connected */ | ||
5348 | if (btdm_Is1AntPsTdmaStateChange(padapter)) { | ||
5349 | /* protect 3 beacons in 3-beacon period & no Tx pause at BT slot */ | ||
5350 | BTDM_SetFw3a(padapter, 0x93, 0x15, 0x03, 0x14, 0x0); | ||
5351 | } | ||
5352 | break; | ||
5353 | case 5: /* for WiFi connected-busy & BT is Non-Connected-Idle */ | ||
5354 | if (btdm_Is1AntPsTdmaStateChange(padapter)) { | ||
5355 | /* SCO mode, Ant fixed at WiFi, WLAN_Act toggle */ | ||
5356 | BTDM_SetFw3a(padapter, 0x61, 0x15, 0x03, 0x31, 0x00); | ||
5357 | } | ||
5358 | break; | ||
5359 | case 9: /* ACL high-retry type - 2 */ | ||
5360 | if (btdm_Is1AntPsTdmaStateChange(padapter)) { | ||
5361 | /* narrow duration for WiFi */ | ||
5362 | BTDM_SetFw3a(padapter, 0xd3, 0xa, 0xa, 0x0, 0x58); /* narrow duration for WiFi */ | ||
5363 | } | ||
5364 | break; | ||
5365 | case 10: /* for WiFi connect idle & BT ACL busy or WiFi Connected-Busy & BT is Inquiry */ | ||
5366 | if (btdm_Is1AntPsTdmaStateChange(padapter)) | ||
5367 | BTDM_SetFw3a(padapter, 0x13, 0xa, 0xa, 0x0, 0x40); | ||
5368 | break; | ||
5369 | case 11: /* ACL high-retry type - 3 */ | ||
5370 | if (btdm_Is1AntPsTdmaStateChange(padapter)) { | ||
5371 | /* narrow duration for WiFi */ | ||
5372 | BTDM_SetFw3a(padapter, 0xd3, 0x05, 0x05, 0x00, 0x58); | ||
5373 | } | ||
5374 | break; | ||
5375 | case 12: /* for WiFi Connected-Busy & BT is Connected-Idle */ | ||
5376 | if (btdm_Is1AntPsTdmaStateChange(padapter)) { | ||
5377 | /* Allow High-Pri BT */ | ||
5378 | BTDM_SetFw3a(padapter, 0xeb, 0x0a, 0x03, 0x31, 0x18); | ||
5379 | } | ||
5380 | break; | ||
5381 | case 20: /* WiFi only busy , TDMA mode for power saving */ | ||
5382 | if (btdm_Is1AntPsTdmaStateChange(padapter)) | ||
5383 | BTDM_SetFw3a(padapter, 0x13, 0x25, 0x25, 0x00, 0x00); | ||
5384 | break; | ||
5385 | case 27: /* WiFi DHCP/Site Survey & BT SCO busy */ | ||
5386 | if (btdm_Is1AntPsTdmaStateChange(padapter)) | ||
5387 | BTDM_SetFw3a(padapter, 0xa3, 0x25, 0x03, 0x31, 0x98); | ||
5388 | break; | ||
5389 | case 28: /* WiFi DHCP/Site Survey & BT idle */ | ||
5390 | if (btdm_Is1AntPsTdmaStateChange(padapter)) | ||
5391 | BTDM_SetFw3a(padapter, 0x69, 0x25, 0x03, 0x31, 0x00); | ||
5392 | break; | ||
5393 | case 29: /* WiFi DHCP/Site Survey & BT ACL busy */ | ||
5394 | if (btdm_Is1AntPsTdmaStateChange(padapter)) { | ||
5395 | BTDM_SetFw3a(padapter, 0xeb, 0x1a, 0x1a, 0x01, 0x18); | ||
5396 | rtw_write32(padapter, 0x6c0, 0x5afa5afa); | ||
5397 | rtw_write32(padapter, 0x6c4, 0x5afa5afa); | ||
5398 | } | ||
5399 | break; | ||
5400 | case 30: /* WiFi idle & BT Inquiry */ | ||
5401 | if (btdm_Is1AntPsTdmaStateChange(padapter)) | ||
5402 | BTDM_SetFw3a(padapter, 0x93, 0x15, 0x03, 0x14, 0x00); | ||
5403 | break; | ||
5404 | case 31: /* BT HID */ | ||
5405 | if (btdm_Is1AntPsTdmaStateChange(padapter)) | ||
5406 | BTDM_SetFw3a(padapter, 0xd3, 0x1a, 0x1a, 0x00, 0x58); | ||
5407 | break; | ||
5408 | case 32: /* BT SCO & Inquiry */ | ||
5409 | if (btdm_Is1AntPsTdmaStateChange(padapter)) | ||
5410 | BTDM_SetFw3a(padapter, 0xab, 0x0a, 0x03, 0x11, 0x98); | ||
5411 | break; | ||
5412 | case 33: /* BT SCO & WiFi site survey */ | ||
5413 | if (btdm_Is1AntPsTdmaStateChange(padapter)) | ||
5414 | BTDM_SetFw3a(padapter, 0xa3, 0x25, 0x03, 0x30, 0x98); | ||
5415 | break; | ||
5416 | case 34: /* BT HID & WiFi site survey */ | ||
5417 | if (btdm_Is1AntPsTdmaStateChange(padapter)) | ||
5418 | BTDM_SetFw3a(padapter, 0xd3, 0x1a, 0x1a, 0x00, 0x18); | ||
5419 | break; | ||
5420 | case 35: /* BT HID & WiFi Connecting */ | ||
5421 | if (btdm_Is1AntPsTdmaStateChange(padapter)) | ||
5422 | BTDM_SetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0x00, 0x18); | ||
5423 | break; | ||
5424 | } | ||
5425 | } else { | ||
5426 | /* disable PS-TDMA */ | ||
5427 | switch (type) { | ||
5428 | case 8: | ||
5429 | if (btdm_Is1AntPsTdmaStateChange(padapter)) { | ||
5430 | /* Antenna control by PTA, 0x870 = 0x310 */ | ||
5431 | BTDM_SetFw3a(padapter, 0x8, 0x0, 0x0, 0x0, 0x0); | ||
5432 | } | ||
5433 | break; | ||
5434 | case 0: | ||
5435 | default: | ||
5436 | if (btdm_Is1AntPsTdmaStateChange(padapter)) { | ||
5437 | /* Antenna control by PTA, 0x870 = 0x310 */ | ||
5438 | BTDM_SetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0); | ||
5439 | } | ||
5440 | rtw_write16(padapter, 0x860, 0x210); /* Switch Antenna to BT */ | ||
5441 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], 0x860 = 0x210, Switch Antenna to BT\n")); | ||
5442 | break; | ||
5443 | case 9: | ||
5444 | if (btdm_Is1AntPsTdmaStateChange(padapter)) { | ||
5445 | /* Antenna control by PTA, 0x870 = 0x310 */ | ||
5446 | BTDM_SetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0); | ||
5447 | } | ||
5448 | rtw_write16(padapter, 0x860, 0x110); /* Switch Antenna to WiFi */ | ||
5449 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], 0x860 = 0x110, Switch Antenna to WiFi\n")); | ||
5450 | break; | ||
5451 | } | ||
5452 | } | ||
5453 | |||
5454 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Current TDMA(%s, %d)\n", | ||
5455 | pBtdm8723->bCurPsTdmaOn?"ON":"OFF", pBtdm8723->curPsTdma)); | ||
5456 | |||
5457 | /* update pre state */ | ||
5458 | pBtdm8723->bPrePsTdmaOn = pBtdm8723->bCurPsTdmaOn; | ||
5459 | pBtdm8723->prePsTdma = pBtdm8723->curPsTdma; | ||
5460 | } | ||
5461 | |||
5462 | static void | ||
5463 | _btdm_1AntSetPSTDMA(struct rtw_adapter *padapter, u8 bPSEn, u8 smartps, | ||
5464 | u8 psOption, u8 bTDMAOn, u8 tdmaType) | ||
5465 | { | ||
5466 | struct pwrctrl_priv *pwrctrl; | ||
5467 | struct hal_data_8723a *pHalData; | ||
5468 | struct btdm_8723a_1ant *pBtdm8723; | ||
5469 | u8 psMode; | ||
5470 | u8 bSwitchPS; | ||
5471 | |||
5472 | if (!check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) && | ||
5473 | (get_fwstate(&padapter->mlmepriv) != WIFI_NULL_STATE)) { | ||
5474 | btdm_1AntPsTdma(padapter, bTDMAOn, tdmaType); | ||
5475 | return; | ||
5476 | } | ||
5477 | psOption &= ~BIT(0); | ||
5478 | |||
5479 | RTPRINT(FBT, BT_TRACE, | ||
5480 | ("[BTCoex], Set LPS(%s, %d) TDMA(%s, %d)\n", | ||
5481 | bPSEn == true?"ON":"OFF", psOption, | ||
5482 | bTDMAOn == true?"ON":"OFF", tdmaType)); | ||
5483 | |||
5484 | pwrctrl = &padapter->pwrctrlpriv; | ||
5485 | pHalData = GET_HAL_DATA(padapter); | ||
5486 | pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant; | ||
5487 | |||
5488 | if (bPSEn) { | ||
5489 | if (pBtdm8723->bWiFiHalt) { | ||
5490 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Enable PS Fail, WiFi in Halt!!\n")); | ||
5491 | return; | ||
5492 | } | ||
5493 | |||
5494 | if (pwrctrl->bInSuspend) { | ||
5495 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Enable PS Fail, WiFi in Suspend!!\n")); | ||
5496 | return; | ||
5497 | } | ||
5498 | |||
5499 | if (padapter->bDriverStopped) { | ||
5500 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Enable PS Fail, WiFi driver stopped!!\n")); | ||
5501 | return; | ||
5502 | } | ||
5503 | |||
5504 | if (padapter->bSurpriseRemoved) { | ||
5505 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Enable PS Fail, WiFi Surprise Removed!!\n")); | ||
5506 | return; | ||
5507 | } | ||
5508 | |||
5509 | psMode = PS_MODE_MIN; | ||
5510 | } else { | ||
5511 | psMode = PS_MODE_ACTIVE; | ||
5512 | psOption = 0; | ||
5513 | } | ||
5514 | |||
5515 | if (psMode != pwrctrl->pwr_mode) { | ||
5516 | bSwitchPS = true; | ||
5517 | } else if (psMode != PS_MODE_ACTIVE) { | ||
5518 | if (psOption != pwrctrl->bcn_ant_mode) | ||
5519 | bSwitchPS = true; | ||
5520 | else if (smartps != pwrctrl->smart_ps) | ||
5521 | bSwitchPS = true; | ||
5522 | else | ||
5523 | bSwitchPS = false; | ||
5524 | } else { | ||
5525 | bSwitchPS = false; | ||
5526 | } | ||
5527 | |||
5528 | if (bSwitchPS) { | ||
5529 | /* disable TDMA */ | ||
5530 | if (pBtdm8723->bCurPsTdmaOn) { | ||
5531 | if (!bTDMAOn) { | ||
5532 | btdm_1AntPsTdma(padapter, false, tdmaType); | ||
5533 | } else { | ||
5534 | if ((BT_IsBtDisabled(padapter)) || | ||
5535 | (pHalData->bt_coexist.halCoex8723.c2hBtInfo == BT_INFO_STATE_NO_CONNECTION) || | ||
5536 | (pHalData->bt_coexist.halCoex8723.c2hBtInfo == BT_INFO_STATE_CONNECT_IDLE) || | ||
5537 | (tdmaType == 29)) | ||
5538 | btdm_1AntPsTdma(padapter, false, 9); | ||
5539 | else | ||
5540 | btdm_1AntPsTdma(padapter, false, 0); | ||
5541 | } | ||
5542 | } | ||
5543 | |||
5544 | /* change Power Save State */ | ||
5545 | btdm_1AntSetPSMode(padapter, bPSEn, smartps, psOption); | ||
5546 | } | ||
5547 | |||
5548 | btdm_1AntPsTdma(padapter, bTDMAOn, tdmaType); | ||
5549 | } | ||
5550 | |||
5551 | static void | ||
5552 | btdm_1AntSetPSTDMA(struct rtw_adapter *padapter, u8 bPSEn, | ||
5553 | u8 psOption, u8 bTDMAOn, u8 tdmaType) | ||
5554 | { | ||
5555 | _btdm_1AntSetPSTDMA(padapter, bPSEn, 0, psOption, bTDMAOn, tdmaType); | ||
5556 | } | ||
5557 | |||
5558 | static void btdm_1AntWifiParaAdjust(struct rtw_adapter *padapter, u8 bEnable) | ||
5559 | { | ||
5560 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
5561 | struct btdm_8723a_1ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant; | ||
5562 | |||
5563 | if (bEnable) { | ||
5564 | pBtdm8723->curWifiPara = 1; | ||
5565 | if (pBtdm8723->preWifiPara != pBtdm8723->curWifiPara) | ||
5566 | BTDM_SetSwPenaltyTxRateAdaptive(padapter, BT_TX_RATE_ADAPTIVE_LOW_PENALTY); | ||
5567 | } else { | ||
5568 | pBtdm8723->curWifiPara = 2; | ||
5569 | if (pBtdm8723->preWifiPara != pBtdm8723->curWifiPara) | ||
5570 | BTDM_SetSwPenaltyTxRateAdaptive(padapter, BT_TX_RATE_ADAPTIVE_NORMAL); | ||
5571 | } | ||
5572 | |||
5573 | } | ||
5574 | |||
5575 | static void btdm_1AntPtaParaReload(struct rtw_adapter *padapter) | ||
5576 | { | ||
5577 | /* PTA parameter */ | ||
5578 | rtw_write8(padapter, 0x6cc, 0x0); /* 1-Ant coex */ | ||
5579 | rtw_write32(padapter, 0x6c8, 0xffff); /* wifi break table */ | ||
5580 | rtw_write32(padapter, 0x6c4, 0x55555555); /* coex table */ | ||
5581 | |||
5582 | /* Antenna switch control parameter */ | ||
5583 | rtw_write32(padapter, 0x858, 0xaaaaaaaa); | ||
5584 | if (IS_8723A_A_CUT(GET_HAL_DATA(padapter)->VersionID)) { | ||
5585 | rtw_write32(padapter, 0x870, 0x0); /* SPDT(connected with TRSW) control by hardware PTA */ | ||
5586 | rtw_write8(padapter, 0x40, 0x24); | ||
5587 | } else { | ||
5588 | rtw_write8(padapter, 0x40, 0x20); | ||
5589 | rtw_write16(padapter, 0x860, 0x210); /* set antenna at bt side if ANTSW is software control */ | ||
5590 | rtw_write32(padapter, 0x870, 0x300); /* SPDT(connected with TRSW) control by hardware PTA */ | ||
5591 | rtw_write32(padapter, 0x874, 0x22804000); /* ANTSW keep by GNT_BT */ | ||
5592 | } | ||
5593 | |||
5594 | /* coexistence parameters */ | ||
5595 | rtw_write8(padapter, 0x778, 0x1); /* enable RTK mode PTA */ | ||
5596 | |||
5597 | /* BT don't ignore WLAN_Act */ | ||
5598 | btdm_SetFwIgnoreWlanAct(padapter, false); | ||
5599 | } | ||
5600 | |||
5601 | /* | ||
5602 | * Return | ||
5603 | *1: upgrade (add WiFi duration time) | ||
5604 | *0: keep | ||
5605 | *-1: downgrade (add BT duration time) | ||
5606 | */ | ||
5607 | static s8 btdm_1AntTdmaJudgement(struct rtw_adapter *padapter, u8 retry) | ||
5608 | { | ||
5609 | struct hal_data_8723a *pHalData; | ||
5610 | struct btdm_8723a_1ant *pBtdm8723; | ||
5611 | static s8 up, dn, m = 1, n = 3, WaitCount; | ||
5612 | s8 ret; | ||
5613 | |||
5614 | pHalData = GET_HAL_DATA(padapter); | ||
5615 | pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant; | ||
5616 | ret = 0; | ||
5617 | |||
5618 | if (pBtdm8723->psTdmaMonitorCnt == 0) { | ||
5619 | up = 0; | ||
5620 | dn = 0; | ||
5621 | m = 1; | ||
5622 | n = 3; | ||
5623 | WaitCount = 0; | ||
5624 | } else { | ||
5625 | WaitCount++; | ||
5626 | } | ||
5627 | |||
5628 | if (retry == 0) { | ||
5629 | /* no retry in the last 2-second duration */ | ||
5630 | up++; | ||
5631 | dn--; | ||
5632 | if (dn < 0) | ||
5633 | dn = 0; | ||
5634 | if (up >= 3*m) { | ||
5635 | /* retry = 0 in consecutive 3m*(2s), add WiFi duration */ | ||
5636 | ret = 1; | ||
5637 | |||
5638 | n = 3; | ||
5639 | up = 0; | ||
5640 | dn = 0; | ||
5641 | WaitCount = 0; | ||
5642 | } | ||
5643 | } else if (retry <= 3) { | ||
5644 | /* retry<= 3 in the last 2-second duration */ | ||
5645 | up--; | ||
5646 | dn++; | ||
5647 | if (up < 0) | ||
5648 | up = 0; | ||
5649 | |||
5650 | if (dn == 2) { | ||
5651 | /* retry<= 3 in consecutive 2*(2s), minus WiFi duration (add BT duration) */ | ||
5652 | ret = -1; | ||
5653 | |||
5654 | /* record how many time downgrad WiFi duration */ | ||
5655 | if (WaitCount <= 2) | ||
5656 | m++; | ||
5657 | else | ||
5658 | m = 1; | ||
5659 | /* the max number of m is 20 */ | ||
5660 | /* the longest time of upgrade WiFi duration is 20*3*2s = 120s */ | ||
5661 | if (m >= 20) | ||
5662 | m = 20; | ||
5663 | up = 0; | ||
5664 | dn = 0; | ||
5665 | WaitCount = 0; | ||
5666 | } | ||
5667 | } else { | ||
5668 | /* retry count > 3 */ | ||
5669 | /* retry>3, minus WiFi duration (add BT duration) */ | ||
5670 | ret = -1; | ||
5671 | |||
5672 | /* record how many time downgrad WiFi duration */ | ||
5673 | if (WaitCount == 1) | ||
5674 | m++; | ||
5675 | else | ||
5676 | m = 1; | ||
5677 | if (m >= 20) | ||
5678 | m = 20; | ||
5679 | |||
5680 | up = 0; | ||
5681 | dn = 0; | ||
5682 | WaitCount = 0; | ||
5683 | } | ||
5684 | return ret; | ||
5685 | } | ||
5686 | |||
5687 | static void btdm_1AntTdmaDurationAdjustForACL(struct rtw_adapter *padapter) | ||
5688 | { | ||
5689 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
5690 | struct btdm_8723a_1ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant; | ||
5691 | |||
5692 | if (pBtdm8723->psTdmaGlobalCnt != pBtdm8723->psTdmaMonitorCnt) { | ||
5693 | pBtdm8723->psTdmaMonitorCnt = 0; | ||
5694 | pBtdm8723->psTdmaGlobalCnt = 0; | ||
5695 | } | ||
5696 | if (pBtdm8723->psTdmaMonitorCnt == 0) { | ||
5697 | btdm_1AntSetPSTDMA(padapter, true, 0, true, 2); | ||
5698 | pBtdm8723->psTdmaDuAdjType = 2; | ||
5699 | } else { | ||
5700 | /* Now we only have 4 level Ps Tdma, */ | ||
5701 | /* if that's not the following 4 level(will changed by wifi scan, dhcp...), */ | ||
5702 | /* then we have to adjust it back to the previous record one. */ | ||
5703 | if ((pBtdm8723->curPsTdma != 1) && | ||
5704 | (pBtdm8723->curPsTdma != 2) && | ||
5705 | (pBtdm8723->curPsTdma != 9) && | ||
5706 | (pBtdm8723->curPsTdma != 11)) { | ||
5707 | btdm_1AntSetPSTDMA(padapter, true, 0, true, pBtdm8723->psTdmaDuAdjType); | ||
5708 | } else { | ||
5709 | s32 judge = 0; | ||
5710 | |||
5711 | judge = btdm_1AntTdmaJudgement(padapter, pHalData->bt_coexist.halCoex8723.btRetryCnt); | ||
5712 | if (judge == -1) { | ||
5713 | if (pBtdm8723->curPsTdma == 1) { | ||
5714 | /* Decrease WiFi duration for high BT retry */ | ||
5715 | if (pHalData->bt_coexist.halCoex8723.btInfoExt) | ||
5716 | pBtdm8723->psTdmaDuAdjType = 9; | ||
5717 | else | ||
5718 | pBtdm8723->psTdmaDuAdjType = 2; | ||
5719 | btdm_1AntSetPSTDMA(padapter, true, 0, true, pBtdm8723->psTdmaDuAdjType); | ||
5720 | } else if (pBtdm8723->curPsTdma == 2) { | ||
5721 | btdm_1AntSetPSTDMA(padapter, true, 0, true, 9); | ||
5722 | pBtdm8723->psTdmaDuAdjType = 9; | ||
5723 | } else if (pBtdm8723->curPsTdma == 9) { | ||
5724 | btdm_1AntSetPSTDMA(padapter, true, 0, true, 11); | ||
5725 | pBtdm8723->psTdmaDuAdjType = 11; | ||
5726 | } | ||
5727 | } else if (judge == 1) { | ||
5728 | if (pBtdm8723->curPsTdma == 11) { | ||
5729 | btdm_1AntSetPSTDMA(padapter, true, 0, true, 9); | ||
5730 | pBtdm8723->psTdmaDuAdjType = 9; | ||
5731 | } else if (pBtdm8723->curPsTdma == 9) { | ||
5732 | if (pHalData->bt_coexist.halCoex8723.btInfoExt) | ||
5733 | pBtdm8723->psTdmaDuAdjType = 9; | ||
5734 | else | ||
5735 | pBtdm8723->psTdmaDuAdjType = 2; | ||
5736 | btdm_1AntSetPSTDMA(padapter, true, 0, true, pBtdm8723->psTdmaDuAdjType); | ||
5737 | } else if (pBtdm8723->curPsTdma == 2) { | ||
5738 | if (pHalData->bt_coexist.halCoex8723.btInfoExt) | ||
5739 | pBtdm8723->psTdmaDuAdjType = 9; | ||
5740 | else | ||
5741 | pBtdm8723->psTdmaDuAdjType = 1; | ||
5742 | btdm_1AntSetPSTDMA(padapter, true, 0, true, pBtdm8723->psTdmaDuAdjType); | ||
5743 | } | ||
5744 | } | ||
5745 | } | ||
5746 | RTPRINT(FBT, BT_TRACE, | ||
5747 | ("[BTCoex], ACL current TDMA(%s, %d)\n", | ||
5748 | (pBtdm8723->bCurPsTdmaOn ? "ON" : "OFF"), pBtdm8723->curPsTdma)); | ||
5749 | } | ||
5750 | pBtdm8723->psTdmaMonitorCnt++; | ||
5751 | } | ||
5752 | |||
5753 | static void btdm_1AntCoexProcessForWifiConnect(struct rtw_adapter *padapter) | ||
5754 | { | ||
5755 | struct mlme_priv *pmlmepriv; | ||
5756 | struct hal_data_8723a *pHalData; | ||
5757 | struct bt_coexist_8723a *pBtCoex; | ||
5758 | struct btdm_8723a_1ant *pBtdm8723; | ||
5759 | u8 BtState; | ||
5760 | |||
5761 | pmlmepriv = &padapter->mlmepriv; | ||
5762 | pHalData = GET_HAL_DATA(padapter); | ||
5763 | pBtCoex = &pHalData->bt_coexist.halCoex8723; | ||
5764 | pBtdm8723 = &pBtCoex->btdm1Ant; | ||
5765 | BtState = pBtCoex->c2hBtInfo; | ||
5766 | |||
5767 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], WiFi is %s\n", BTDM_IsWifiBusy(padapter)?"Busy":"IDLE")); | ||
5768 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT is %s\n", BtStateString[BtState])); | ||
5769 | |||
5770 | padapter->pwrctrlpriv.btcoex_rfon = false; | ||
5771 | |||
5772 | if ((!BTDM_IsWifiBusy(padapter)) && (!check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE)) && | ||
5773 | ((BtState == BT_INFO_STATE_NO_CONNECTION) || (BtState == BT_INFO_STATE_CONNECT_IDLE))) { | ||
5774 | switch (BtState) { | ||
5775 | case BT_INFO_STATE_NO_CONNECTION: | ||
5776 | _btdm_1AntSetPSTDMA(padapter, true, 2, 0x26, false, 9); | ||
5777 | break; | ||
5778 | case BT_INFO_STATE_CONNECT_IDLE: | ||
5779 | _btdm_1AntSetPSTDMA(padapter, true, 2, 0x26, false, 0); | ||
5780 | break; | ||
5781 | } | ||
5782 | } else { | ||
5783 | switch (BtState) { | ||
5784 | case BT_INFO_STATE_NO_CONNECTION: | ||
5785 | case BT_INFO_STATE_CONNECT_IDLE: | ||
5786 | /* WiFi is Busy */ | ||
5787 | btdm_1AntSetPSTDMA(padapter, false, 0, true, 5); | ||
5788 | rtw_write32(padapter, 0x6c0, 0x5a5a5a5a); | ||
5789 | rtw_write32(padapter, 0x6c4, 0x5a5a5a5a); | ||
5790 | break; | ||
5791 | case BT_INFO_STATE_ACL_INQ_OR_PAG: | ||
5792 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT PROFILE is BT_INFO_STATE_ACL_INQ_OR_PAG\n")); | ||
5793 | case BT_INFO_STATE_INQ_OR_PAG: | ||
5794 | padapter->pwrctrlpriv.btcoex_rfon = true; | ||
5795 | btdm_1AntSetPSTDMA(padapter, true, 0, true, 30); | ||
5796 | break; | ||
5797 | case BT_INFO_STATE_SCO_ONLY_BUSY: | ||
5798 | case BT_INFO_STATE_ACL_SCO_BUSY: | ||
5799 | if (true == pBtCoex->bC2hBtInquiryPage) { | ||
5800 | btdm_1AntSetPSTDMA(padapter, false, 0, true, 32); | ||
5801 | } else { | ||
5802 | #ifdef BTCOEX_CMCC_TEST | ||
5803 | btdm_1AntSetPSTDMA(padapter, false, 0, true, 23); | ||
5804 | #else /* !BTCOEX_CMCC_TEST */ | ||
5805 | btdm_1AntSetPSTDMA(padapter, false, 0, false, 8); | ||
5806 | rtw_write32(padapter, 0x6c0, 0x5a5a5a5a); | ||
5807 | rtw_write32(padapter, 0x6c4, 0x5a5a5a5a); | ||
5808 | #endif /* !BTCOEX_CMCC_TEST */ | ||
5809 | } | ||
5810 | break; | ||
5811 | case BT_INFO_STATE_ACL_ONLY_BUSY: | ||
5812 | padapter->pwrctrlpriv.btcoex_rfon = true; | ||
5813 | if (pBtCoex->c2hBtProfile == BT_INFO_HID) { | ||
5814 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT PROFILE is HID\n")); | ||
5815 | btdm_1AntSetPSTDMA(padapter, true, 0, true, 31); | ||
5816 | } else if (pBtCoex->c2hBtProfile == BT_INFO_FTP) { | ||
5817 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT PROFILE is FTP/OPP\n")); | ||
5818 | btdm_1AntSetPSTDMA(padapter, true, 0, true, 3); | ||
5819 | } else if (pBtCoex->c2hBtProfile == (BT_INFO_A2DP|BT_INFO_FTP)) { | ||
5820 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT PROFILE is A2DP_FTP\n")); | ||
5821 | btdm_1AntSetPSTDMA(padapter, true, 0, true, 11); | ||
5822 | } else { | ||
5823 | if (pBtCoex->c2hBtProfile == BT_INFO_A2DP) | ||
5824 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT PROFILE is A2DP\n")); | ||
5825 | else | ||
5826 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT PROFILE is UNKNOWN(0x%02X)! Use A2DP Profile\n", pBtCoex->c2hBtProfile)); | ||
5827 | btdm_1AntTdmaDurationAdjustForACL(padapter); | ||
5828 | } | ||
5829 | break; | ||
5830 | } | ||
5831 | } | ||
5832 | |||
5833 | pBtdm8723->psTdmaGlobalCnt++; | ||
5834 | } | ||
5835 | |||
5836 | static void btdm_1AntUpdateHalRAMask(struct rtw_adapter *padapter, u32 mac_id, u32 filter) | ||
5837 | { | ||
5838 | u8 init_rate = 0; | ||
5839 | u8 raid; | ||
5840 | u32 mask; | ||
5841 | u8 shortGIrate = false; | ||
5842 | int supportRateNum = 0; | ||
5843 | struct sta_info *psta; | ||
5844 | struct hal_data_8723a *pHalData; | ||
5845 | struct dm_priv *pdmpriv; | ||
5846 | struct mlme_ext_priv *pmlmeext; | ||
5847 | struct mlme_ext_info *pmlmeinfo; | ||
5848 | struct wlan_bssid_ex *cur_network; | ||
5849 | |||
5850 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, MACID =%d, filter = 0x%08x!!\n", __func__, mac_id, filter)); | ||
5851 | |||
5852 | pHalData = GET_HAL_DATA(padapter); | ||
5853 | pdmpriv = &pHalData->dmpriv; | ||
5854 | pmlmeext = &padapter->mlmeextpriv; | ||
5855 | pmlmeinfo = &pmlmeext->mlmext_info; | ||
5856 | cur_network = &pmlmeinfo->network; | ||
5857 | |||
5858 | if (mac_id >= NUM_STA) { /* CAM_SIZE */ | ||
5859 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, MACID =%d illegal!!\n", __func__, mac_id)); | ||
5860 | return; | ||
5861 | } | ||
5862 | |||
5863 | psta = pmlmeinfo->FW_sta_info[mac_id].psta; | ||
5864 | if (psta == NULL) { | ||
5865 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, Can't find station!!\n", __func__)); | ||
5866 | return; | ||
5867 | } | ||
5868 | |||
5869 | raid = psta->raid; | ||
5870 | |||
5871 | switch (mac_id) { | ||
5872 | case 0:/* for infra mode */ | ||
5873 | supportRateNum = rtw_get_rateset_len23a(cur_network->SupportedRates); | ||
5874 | mask = update_supported_rate23a(cur_network->SupportedRates, supportRateNum); | ||
5875 | mask |= (pmlmeinfo->HT_enable) ? update_MSC_rate23a(&pmlmeinfo->HT_caps):0; | ||
5876 | if (support_short_GI23a(padapter, &pmlmeinfo->HT_caps)) | ||
5877 | shortGIrate = true; | ||
5878 | break; | ||
5879 | case 1:/* for broadcast/multicast */ | ||
5880 | supportRateNum = rtw_get_rateset_len23a(pmlmeinfo->FW_sta_info[mac_id].SupportedRates); | ||
5881 | mask = update_basic_rate23a(cur_network->SupportedRates, supportRateNum); | ||
5882 | break; | ||
5883 | default: /* for each sta in IBSS */ | ||
5884 | supportRateNum = rtw_get_rateset_len23a(pmlmeinfo->FW_sta_info[mac_id].SupportedRates); | ||
5885 | mask = update_supported_rate23a(cur_network->SupportedRates, supportRateNum); | ||
5886 | break; | ||
5887 | } | ||
5888 | mask |= ((raid<<28)&0xf0000000); | ||
5889 | mask &= 0xffffffff; | ||
5890 | mask &= ~filter; | ||
5891 | init_rate = get_highest_rate_idx23a(mask)&0x3f; | ||
5892 | |||
5893 | if (pHalData->fw_ractrl) { | ||
5894 | u8 arg = 0; | ||
5895 | |||
5896 | arg = mac_id&0x1f;/* MACID */ | ||
5897 | arg |= BIT(7); | ||
5898 | if (true == shortGIrate) | ||
5899 | arg |= BIT(5); | ||
5900 | |||
5901 | RTPRINT(FBT, BT_TRACE, | ||
5902 | ("[BTCoex], Update FW RAID entry, MASK = 0x%08x, arg = 0x%02x\n", | ||
5903 | mask, arg)); | ||
5904 | |||
5905 | rtl8723a_set_raid_cmd(padapter, mask, arg); | ||
5906 | } else { | ||
5907 | if (shortGIrate) | ||
5908 | init_rate |= BIT(6); | ||
5909 | |||
5910 | rtw_write8(padapter, (REG_INIDATA_RATE_SEL+mac_id), init_rate); | ||
5911 | } | ||
5912 | |||
5913 | psta->init_rate = init_rate; | ||
5914 | pdmpriv->INIDATA_RATE[mac_id] = init_rate; | ||
5915 | } | ||
5916 | |||
5917 | static void btdm_1AntUpdateHalRAMaskForSCO(struct rtw_adapter *padapter, u8 forceUpdate) | ||
5918 | { | ||
5919 | struct btdm_8723a_1ant *pBtdm8723; | ||
5920 | struct sta_priv *pstapriv; | ||
5921 | struct wlan_bssid_ex *cur_network; | ||
5922 | struct sta_info *psta; | ||
5923 | u32 macid; | ||
5924 | u32 filter = 0; | ||
5925 | |||
5926 | pBtdm8723 = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant; | ||
5927 | |||
5928 | if ((pBtdm8723->bRAChanged == true) && (forceUpdate == false)) | ||
5929 | return; | ||
5930 | |||
5931 | pstapriv = &padapter->stapriv; | ||
5932 | cur_network = &padapter->mlmeextpriv.mlmext_info.network; | ||
5933 | psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress); | ||
5934 | macid = psta->mac_id; | ||
5935 | |||
5936 | filter |= BIT(_1M_RATE_); | ||
5937 | filter |= BIT(_2M_RATE_); | ||
5938 | filter |= BIT(_5M_RATE_); | ||
5939 | filter |= BIT(_11M_RATE_); | ||
5940 | filter |= BIT(_6M_RATE_); | ||
5941 | filter |= BIT(_9M_RATE_); | ||
5942 | |||
5943 | btdm_1AntUpdateHalRAMask(padapter, macid, filter); | ||
5944 | |||
5945 | pBtdm8723->bRAChanged = true; | ||
5946 | } | ||
5947 | |||
5948 | static void btdm_1AntRecoverHalRAMask(struct rtw_adapter *padapter) | ||
5949 | { | ||
5950 | struct btdm_8723a_1ant *pBtdm8723; | ||
5951 | struct sta_priv *pstapriv; | ||
5952 | struct wlan_bssid_ex *cur_network; | ||
5953 | struct sta_info *psta; | ||
5954 | |||
5955 | pBtdm8723 = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant; | ||
5956 | |||
5957 | if (pBtdm8723->bRAChanged == false) | ||
5958 | return; | ||
5959 | |||
5960 | pstapriv = &padapter->stapriv; | ||
5961 | cur_network = &padapter->mlmeextpriv.mlmext_info.network; | ||
5962 | psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress); | ||
5963 | |||
5964 | Update_RA_Entry23a(padapter, psta); | ||
5965 | |||
5966 | pBtdm8723->bRAChanged = false; | ||
5967 | } | ||
5968 | |||
5969 | static void | ||
5970 | btdm_1AntBTStateChangeHandler(struct rtw_adapter *padapter, | ||
5971 | enum bt_state_1ant oldState, enum bt_state_1ant newState) | ||
5972 | { | ||
5973 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT state change, %s => %s\n", BtStateString[oldState], BtStateString[newState])); | ||
5974 | |||
5975 | /* BT default ignore wlan active, */ | ||
5976 | /* WiFi MUST disable this when BT is enable */ | ||
5977 | if (newState > BT_INFO_STATE_DISABLED) | ||
5978 | btdm_SetFwIgnoreWlanAct(padapter, false); | ||
5979 | |||
5980 | if ((check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) && | ||
5981 | (BTDM_IsWifiConnectionExist(padapter))) { | ||
5982 | if ((newState == BT_INFO_STATE_SCO_ONLY_BUSY) || | ||
5983 | (newState == BT_INFO_STATE_ACL_SCO_BUSY)) { | ||
5984 | btdm_1AntUpdateHalRAMaskForSCO(padapter, false); | ||
5985 | } else { | ||
5986 | /* Recover original RA setting */ | ||
5987 | btdm_1AntRecoverHalRAMask(padapter); | ||
5988 | } | ||
5989 | } else { | ||
5990 | GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant.bRAChanged = false; | ||
5991 | } | ||
5992 | |||
5993 | if (oldState == newState) | ||
5994 | return; | ||
5995 | |||
5996 | if (oldState == BT_INFO_STATE_ACL_ONLY_BUSY) { | ||
5997 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
5998 | pHalData->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCnt = 0; | ||
5999 | pHalData->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCntForSCO = 0; | ||
6000 | } | ||
6001 | |||
6002 | if ((oldState == BT_INFO_STATE_SCO_ONLY_BUSY) || | ||
6003 | (oldState == BT_INFO_STATE_ACL_SCO_BUSY)) { | ||
6004 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6005 | pHalData->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCntForSCO = 0; | ||
6006 | } | ||
6007 | |||
6008 | /* Active 2Ant mechanism when BT Connected */ | ||
6009 | if ((oldState == BT_INFO_STATE_DISABLED) || | ||
6010 | (oldState == BT_INFO_STATE_NO_CONNECTION)) { | ||
6011 | if ((newState != BT_INFO_STATE_DISABLED) && | ||
6012 | (newState != BT_INFO_STATE_NO_CONNECTION)) { | ||
6013 | BTDM_SetSwRfRxLpfCorner(padapter, BT_RF_RX_LPF_CORNER_SHRINK); | ||
6014 | BTDM_AGCTable(padapter, BT_AGCTABLE_ON); | ||
6015 | BTDM_BBBackOffLevel(padapter, BT_BB_BACKOFF_ON); | ||
6016 | } | ||
6017 | } else { | ||
6018 | if ((newState == BT_INFO_STATE_DISABLED) || | ||
6019 | (newState == BT_INFO_STATE_NO_CONNECTION)) { | ||
6020 | BTDM_SetSwRfRxLpfCorner(padapter, BT_RF_RX_LPF_CORNER_RESUME); | ||
6021 | BTDM_AGCTable(padapter, BT_AGCTABLE_OFF); | ||
6022 | BTDM_BBBackOffLevel(padapter, BT_BB_BACKOFF_OFF); | ||
6023 | } | ||
6024 | } | ||
6025 | } | ||
6026 | |||
6027 | static void btdm_1AntBtCoexistHandler(struct rtw_adapter *padapter) | ||
6028 | { | ||
6029 | struct hal_data_8723a *pHalData; | ||
6030 | struct bt_coexist_8723a *pBtCoex8723; | ||
6031 | struct btdm_8723a_1ant *pBtdm8723; | ||
6032 | |||
6033 | pHalData = GET_HAL_DATA(padapter); | ||
6034 | pBtCoex8723 = &pHalData->bt_coexist.halCoex8723; | ||
6035 | pBtdm8723 = &pBtCoex8723->btdm1Ant; | ||
6036 | padapter->pwrctrlpriv.btcoex_rfon = false; | ||
6037 | if (BT_IsBtDisabled(padapter)) { | ||
6038 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT is disabled\n")); | ||
6039 | |||
6040 | if (BTDM_IsWifiConnectionExist(padapter)) { | ||
6041 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], wifi is connected\n")); | ||
6042 | |||
6043 | if (BTDM_IsWifiBusy(padapter)) { | ||
6044 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Wifi is busy\n")); | ||
6045 | btdm_1AntSetPSTDMA(padapter, false, 0, false, 9); | ||
6046 | } else { | ||
6047 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Wifi is idle\n")); | ||
6048 | _btdm_1AntSetPSTDMA(padapter, true, 2, 1, false, 9); | ||
6049 | } | ||
6050 | } else { | ||
6051 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], wifi is disconnected\n")); | ||
6052 | |||
6053 | btdm_1AntSetPSTDMA(padapter, false, 0, false, 9); | ||
6054 | } | ||
6055 | } else { | ||
6056 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT is enabled\n")); | ||
6057 | |||
6058 | if (BTDM_IsWifiConnectionExist(padapter)) { | ||
6059 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], wifi is connected\n")); | ||
6060 | |||
6061 | btdm_1AntWifiParaAdjust(padapter, true); | ||
6062 | btdm_1AntCoexProcessForWifiConnect(padapter); | ||
6063 | } else { | ||
6064 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], wifi is disconnected\n")); | ||
6065 | |||
6066 | /* Antenna switch at BT side(0x870 = 0x300, 0x860 = 0x210) after PSTDMA off */ | ||
6067 | btdm_1AntWifiParaAdjust(padapter, false); | ||
6068 | btdm_1AntSetPSTDMA(padapter, false, 0, false, 0); | ||
6069 | } | ||
6070 | } | ||
6071 | |||
6072 | btdm_1AntBTStateChangeHandler(padapter, pBtCoex8723->prec2hBtInfo, pBtCoex8723->c2hBtInfo); | ||
6073 | pBtCoex8723->prec2hBtInfo = pBtCoex8723->c2hBtInfo; | ||
6074 | } | ||
6075 | |||
6076 | void BTDM_1AntSignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi, u8 *rssi_bt) | ||
6077 | { | ||
6078 | struct hal_data_8723a *pHalData; | ||
6079 | struct btdm_8723a_1ant *pBtdm8723; | ||
6080 | u8 RSSI_WiFi_Cmpnstn, RSSI_BT_Cmpnstn; | ||
6081 | |||
6082 | pHalData = GET_HAL_DATA(padapter); | ||
6083 | pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant; | ||
6084 | RSSI_WiFi_Cmpnstn = 0; | ||
6085 | RSSI_BT_Cmpnstn = 0; | ||
6086 | |||
6087 | switch (pBtdm8723->curPsTdma) { | ||
6088 | case 1: /* WiFi 52ms */ | ||
6089 | RSSI_WiFi_Cmpnstn = 11; /* 22*0.48 */ | ||
6090 | break; | ||
6091 | case 2: /* WiFi 36ms */ | ||
6092 | RSSI_WiFi_Cmpnstn = 14; /* 22*0.64 */ | ||
6093 | break; | ||
6094 | case 9: /* WiFi 20ms */ | ||
6095 | RSSI_WiFi_Cmpnstn = 18; /* 22*0.80 */ | ||
6096 | break; | ||
6097 | case 11: /* WiFi 10ms */ | ||
6098 | RSSI_WiFi_Cmpnstn = 20; /* 22*0.90 */ | ||
6099 | break; | ||
6100 | case 4: /* WiFi 21ms */ | ||
6101 | RSSI_WiFi_Cmpnstn = 17; /* 22*0.79 */ | ||
6102 | break; | ||
6103 | case 16: /* WiFi 24ms */ | ||
6104 | RSSI_WiFi_Cmpnstn = 18; /* 22*0.76 */ | ||
6105 | break; | ||
6106 | case 18: /* WiFi 37ms */ | ||
6107 | RSSI_WiFi_Cmpnstn = 14; /* 22*0.64 */ | ||
6108 | break; | ||
6109 | case 23: /* Level-1, Antenna switch to BT at all time */ | ||
6110 | case 24: /* Level-2, Antenna switch to BT at all time */ | ||
6111 | case 25: /* Level-3a, Antenna switch to BT at all time */ | ||
6112 | case 26: /* Level-3b, Antenna switch to BT at all time */ | ||
6113 | case 27: /* Level-3b, Antenna switch to BT at all time */ | ||
6114 | case 33: /* BT SCO & WiFi site survey */ | ||
6115 | RSSI_WiFi_Cmpnstn = 22; | ||
6116 | break; | ||
6117 | default: | ||
6118 | break; | ||
6119 | } | ||
6120 | |||
6121 | if (rssi_wifi && RSSI_WiFi_Cmpnstn) { | ||
6122 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1AntSgnlCmpnstn, case %d, WiFiCmpnstn =%d(%d => %d)\n", | ||
6123 | pBtdm8723->curPsTdma, RSSI_WiFi_Cmpnstn, *rssi_wifi, *rssi_wifi+RSSI_WiFi_Cmpnstn)); | ||
6124 | *rssi_wifi += RSSI_WiFi_Cmpnstn; | ||
6125 | } | ||
6126 | |||
6127 | if (rssi_bt && RSSI_BT_Cmpnstn) { | ||
6128 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1AntSgnlCmpnstn, case %d, BTCmpnstn =%d(%d => %d)\n", | ||
6129 | pBtdm8723->curPsTdma, RSSI_BT_Cmpnstn, *rssi_bt, *rssi_bt+RSSI_BT_Cmpnstn)); | ||
6130 | *rssi_bt += RSSI_BT_Cmpnstn; | ||
6131 | } | ||
6132 | } | ||
6133 | |||
6134 | static void BTDM_1AntParaInit(struct rtw_adapter *padapter) | ||
6135 | { | ||
6136 | struct hal_data_8723a *pHalData; | ||
6137 | struct bt_coexist_8723a *pBtCoex; | ||
6138 | struct btdm_8723a_1ant *pBtdm8723; | ||
6139 | |||
6140 | pHalData = GET_HAL_DATA(padapter); | ||
6141 | pBtCoex = &pHalData->bt_coexist.halCoex8723; | ||
6142 | pBtdm8723 = &pBtCoex->btdm1Ant; | ||
6143 | |||
6144 | /* Enable counter statistics */ | ||
6145 | rtw_write8(padapter, 0x76e, 0x4); | ||
6146 | btdm_1AntPtaParaReload(padapter); | ||
6147 | |||
6148 | pBtdm8723->wifiRssiThresh = 48; | ||
6149 | |||
6150 | pBtdm8723->bWiFiHalt = false; | ||
6151 | pBtdm8723->bRAChanged = false; | ||
6152 | |||
6153 | if ((pBtCoex->c2hBtInfo != BT_INFO_STATE_DISABLED) && | ||
6154 | (pBtCoex->c2hBtInfo != BT_INFO_STATE_NO_CONNECTION)) { | ||
6155 | BTDM_SetSwRfRxLpfCorner(padapter, BT_RF_RX_LPF_CORNER_SHRINK); | ||
6156 | BTDM_AGCTable(padapter, BT_AGCTABLE_ON); | ||
6157 | BTDM_BBBackOffLevel(padapter, BT_BB_BACKOFF_ON); | ||
6158 | } | ||
6159 | } | ||
6160 | |||
6161 | static void BTDM_1AntForHalt(struct rtw_adapter *padapter) | ||
6162 | { | ||
6163 | RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for halt\n")); | ||
6164 | |||
6165 | GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant.bWiFiHalt = true; | ||
6166 | |||
6167 | btdm_1AntWifiParaAdjust(padapter, false); | ||
6168 | |||
6169 | /* don't use btdm_1AntSetPSTDMA() here */ | ||
6170 | /* it will call rtw_set_ps_mode23a() and request pwrpriv->lock. */ | ||
6171 | /* This will lead to deadlock, if this function is called in IPS */ | ||
6172 | /* Lucas@20130205 */ | ||
6173 | btdm_1AntPsTdma(padapter, false, 0); | ||
6174 | |||
6175 | btdm_SetFwIgnoreWlanAct(padapter, true); | ||
6176 | } | ||
6177 | |||
6178 | static void BTDM_1AntLpsLeave(struct rtw_adapter *padapter) | ||
6179 | { | ||
6180 | RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for LPS Leave\n")); | ||
6181 | |||
6182 | /* Prevent from entering LPS again */ | ||
6183 | GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant.bWiFiHalt = true; | ||
6184 | |||
6185 | btdm_1AntSetPSTDMA(padapter, false, 0, false, 8); | ||
6186 | /*btdm_1AntPsTdma(padapter, false, 8); */ | ||
6187 | } | ||
6188 | |||
6189 | static void BTDM_1AntWifiAssociateNotify(struct rtw_adapter *padapter, u8 type) | ||
6190 | { | ||
6191 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6192 | |||
6193 | RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for associate, type =%d\n", type)); | ||
6194 | |||
6195 | if (type) { | ||
6196 | rtl8723a_CheckAntenna_Selection(padapter); | ||
6197 | if (BT_IsBtDisabled(padapter)) { | ||
6198 | btdm_1AntSetPSTDMA(padapter, false, 0, false, 9); | ||
6199 | } else { | ||
6200 | struct bt_coexist_8723a *pBtCoex; | ||
6201 | u8 BtState; | ||
6202 | |||
6203 | pBtCoex = &pHalData->bt_coexist.halCoex8723; | ||
6204 | BtState = pBtCoex->c2hBtInfo; | ||
6205 | |||
6206 | btdm_1AntTSFSwitch(padapter, true); | ||
6207 | |||
6208 | if ((BtState == BT_INFO_STATE_NO_CONNECTION) || | ||
6209 | (BtState == BT_INFO_STATE_CONNECT_IDLE)) { | ||
6210 | btdm_1AntSetPSTDMA(padapter, false, 0, true, 28); | ||
6211 | } else if ((BtState == BT_INFO_STATE_SCO_ONLY_BUSY) || | ||
6212 | (BtState == BT_INFO_STATE_ACL_SCO_BUSY)) { | ||
6213 | btdm_1AntSetPSTDMA(padapter, false, 0, false, 8); | ||
6214 | rtw_write32(padapter, 0x6c0, 0x5a5a5a5a); | ||
6215 | rtw_write32(padapter, 0x6c4, 0x5a5a5a5a); | ||
6216 | } else if ((BtState == BT_INFO_STATE_ACL_ONLY_BUSY) || | ||
6217 | (BtState == BT_INFO_STATE_ACL_INQ_OR_PAG)) { | ||
6218 | if (pBtCoex->c2hBtProfile == BT_INFO_HID) | ||
6219 | btdm_1AntSetPSTDMA(padapter, false, 0, true, 35); | ||
6220 | else | ||
6221 | btdm_1AntSetPSTDMA(padapter, false, 0, true, 29); | ||
6222 | } | ||
6223 | } | ||
6224 | } else { | ||
6225 | if (BT_IsBtDisabled(padapter)) { | ||
6226 | if (!BTDM_IsWifiConnectionExist(padapter)) { | ||
6227 | btdm_1AntPsTdma(padapter, false, 0); | ||
6228 | btdm_1AntTSFSwitch(padapter, false); | ||
6229 | } | ||
6230 | } | ||
6231 | |||
6232 | btdm_1AntBtCoexistHandler(padapter); | ||
6233 | } | ||
6234 | } | ||
6235 | |||
6236 | static void | ||
6237 | BTDM_1AntMediaStatusNotify(struct rtw_adapter *padapter, | ||
6238 | enum rt_media_status mstatus) | ||
6239 | { | ||
6240 | struct bt_coexist_8723a *pBtCoex; | ||
6241 | |||
6242 | pBtCoex = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723; | ||
6243 | |||
6244 | RTPRINT(FBT, BT_TRACE, ("\n\n[BTCoex]******************************\n")); | ||
6245 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], MediaStatus, WiFi %s !!\n", | ||
6246 | mstatus == RT_MEDIA_CONNECT?"CONNECT":"DISCONNECT")); | ||
6247 | RTPRINT(FBT, BT_TRACE, ("[BTCoex]******************************\n")); | ||
6248 | |||
6249 | if (RT_MEDIA_CONNECT == mstatus) { | ||
6250 | if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) { | ||
6251 | if ((pBtCoex->c2hBtInfo == BT_INFO_STATE_SCO_ONLY_BUSY) || | ||
6252 | (pBtCoex->c2hBtInfo == BT_INFO_STATE_ACL_SCO_BUSY)) | ||
6253 | btdm_1AntUpdateHalRAMaskForSCO(padapter, true); | ||
6254 | } | ||
6255 | |||
6256 | padapter->pwrctrlpriv.DelayLPSLastTimeStamp = jiffies; | ||
6257 | BTDM_1AntForDhcp(padapter); | ||
6258 | } else { | ||
6259 | /* DBG_8723A("%s rtl8723a_DeinitAntenna_Selection\n", __func__); */ | ||
6260 | rtl8723a_DeinitAntenna_Selection(padapter); | ||
6261 | btdm_1AntBtCoexistHandler(padapter); | ||
6262 | pBtCoex->btdm1Ant.bRAChanged = false; | ||
6263 | } | ||
6264 | } | ||
6265 | |||
6266 | void BTDM_1AntForDhcp(struct rtw_adapter *padapter) | ||
6267 | { | ||
6268 | struct hal_data_8723a *pHalData; | ||
6269 | u8 BtState; | ||
6270 | struct bt_coexist_8723a *pBtCoex; | ||
6271 | struct btdm_8723a_1ant *pBtdm8723; | ||
6272 | |||
6273 | pHalData = GET_HAL_DATA(padapter); | ||
6274 | pBtCoex = &pHalData->bt_coexist.halCoex8723; | ||
6275 | BtState = pBtCoex->c2hBtInfo; | ||
6276 | pBtdm8723 = &pBtCoex->btdm1Ant; | ||
6277 | |||
6278 | RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for DHCP\n")); | ||
6279 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for DHCP, WiFi is %s\n", BTDM_IsWifiBusy(padapter)?"Busy":"IDLE")); | ||
6280 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for DHCP, %s\n", BtStateString[BtState])); | ||
6281 | |||
6282 | BTDM_1AntWifiAssociateNotify(padapter, true); | ||
6283 | } | ||
6284 | |||
6285 | static void BTDM_1AntWifiScanNotify(struct rtw_adapter *padapter, u8 scanType) | ||
6286 | { | ||
6287 | struct hal_data_8723a *pHalData; | ||
6288 | u8 BtState; | ||
6289 | struct bt_coexist_8723a *pBtCoex; | ||
6290 | struct btdm_8723a_1ant *pBtdm8723; | ||
6291 | |||
6292 | pHalData = GET_HAL_DATA(padapter); | ||
6293 | BtState = pHalData->bt_coexist.halCoex8723.c2hBtInfo; | ||
6294 | pBtCoex = &pHalData->bt_coexist.halCoex8723; | ||
6295 | pBtdm8723 = &pBtCoex->btdm1Ant; | ||
6296 | |||
6297 | RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for wifi scan =%d!!\n", scanType)); | ||
6298 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for wifi scan, WiFi is %s\n", BTDM_IsWifiBusy(padapter)?"Busy":"IDLE")); | ||
6299 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for wifi scan, %s\n", BtStateString[BtState])); | ||
6300 | |||
6301 | if (scanType) { | ||
6302 | rtl8723a_CheckAntenna_Selection(padapter); | ||
6303 | if (BT_IsBtDisabled(padapter)) { | ||
6304 | btdm_1AntSetPSTDMA(padapter, false, 0, false, 9); | ||
6305 | } else if (BTDM_IsWifiConnectionExist(padapter) == false) { | ||
6306 | BTDM_1AntWifiAssociateNotify(padapter, true); | ||
6307 | } else { | ||
6308 | if ((BtState == BT_INFO_STATE_SCO_ONLY_BUSY) || | ||
6309 | (BtState == BT_INFO_STATE_ACL_SCO_BUSY)) { | ||
6310 | if (pBtCoex->bC2hBtInquiryPage) { | ||
6311 | btdm_1AntSetPSTDMA(padapter, false, 0, true, 32); | ||
6312 | } else { | ||
6313 | padapter->pwrctrlpriv.btcoex_rfon = true; | ||
6314 | btdm_1AntSetPSTDMA(padapter, true, 0, true, 33); | ||
6315 | } | ||
6316 | } else if (true == pBtCoex->bC2hBtInquiryPage) { | ||
6317 | padapter->pwrctrlpriv.btcoex_rfon = true; | ||
6318 | btdm_1AntSetPSTDMA(padapter, true, 0, true, 30); | ||
6319 | } else if (BtState == BT_INFO_STATE_ACL_ONLY_BUSY) { | ||
6320 | padapter->pwrctrlpriv.btcoex_rfon = true; | ||
6321 | if (pBtCoex->c2hBtProfile == BT_INFO_HID) | ||
6322 | btdm_1AntSetPSTDMA(padapter, true, 0, true, 34); | ||
6323 | else | ||
6324 | btdm_1AntSetPSTDMA(padapter, true, 0, true, 4); | ||
6325 | } else { | ||
6326 | padapter->pwrctrlpriv.btcoex_rfon = true; | ||
6327 | btdm_1AntSetPSTDMA(padapter, true, 0, true, 5); | ||
6328 | } | ||
6329 | } | ||
6330 | |||
6331 | btdm_NotifyFwScan(padapter, 1); | ||
6332 | } else { | ||
6333 | /* WiFi_Finish_Scan */ | ||
6334 | btdm_NotifyFwScan(padapter, 0); | ||
6335 | btdm_1AntBtCoexistHandler(padapter); | ||
6336 | } | ||
6337 | } | ||
6338 | |||
6339 | static void BTDM_1AntFwC2hBtInfo8723A(struct rtw_adapter *padapter) | ||
6340 | { | ||
6341 | struct hal_data_8723a *pHalData; | ||
6342 | struct bt_30info *pBTInfo; | ||
6343 | struct bt_mgnt *pBtMgnt; | ||
6344 | struct bt_coexist_8723a *pBtCoex; | ||
6345 | u8 u1tmp, btState; | ||
6346 | |||
6347 | pHalData = GET_HAL_DATA(padapter); | ||
6348 | pBTInfo = GET_BT_INFO(padapter); | ||
6349 | pBtMgnt = &pBTInfo->BtMgnt; | ||
6350 | pBtCoex = &pHalData->bt_coexist.halCoex8723; | ||
6351 | |||
6352 | u1tmp = pBtCoex->c2hBtInfoOriginal; | ||
6353 | /* sco BUSY bit is not used on voice over PCM platform */ | ||
6354 | btState = u1tmp & 0xF; | ||
6355 | pBtCoex->c2hBtProfile = u1tmp & 0xE0; | ||
6356 | |||
6357 | /* default set bt to idle state. */ | ||
6358 | pBtMgnt->ExtConfig.bBTBusy = false; | ||
6359 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_IDLE; | ||
6360 | |||
6361 | /* check BIT2 first ==> check if bt is under inquiry or page scan */ | ||
6362 | if (btState & BIT(2)) | ||
6363 | pBtCoex->bC2hBtInquiryPage = true; | ||
6364 | else | ||
6365 | pBtCoex->bC2hBtInquiryPage = false; | ||
6366 | btState &= ~BIT(2); | ||
6367 | |||
6368 | if (!(btState & BIT(0))) { | ||
6369 | pBtCoex->c2hBtInfo = BT_INFO_STATE_NO_CONNECTION; | ||
6370 | } else { | ||
6371 | if (btState == 0x1) { | ||
6372 | pBtCoex->c2hBtInfo = BT_INFO_STATE_CONNECT_IDLE; | ||
6373 | } else if (btState == 0x9) { | ||
6374 | if (pBtCoex->bC2hBtInquiryPage == true) | ||
6375 | pBtCoex->c2hBtInfo = BT_INFO_STATE_ACL_INQ_OR_PAG; | ||
6376 | else | ||
6377 | pBtCoex->c2hBtInfo = BT_INFO_STATE_ACL_ONLY_BUSY; | ||
6378 | pBtMgnt->ExtConfig.bBTBusy = true; | ||
6379 | } else if (btState == 0x3) { | ||
6380 | pBtCoex->c2hBtInfo = BT_INFO_STATE_SCO_ONLY_BUSY; | ||
6381 | pBtMgnt->ExtConfig.bBTBusy = true; | ||
6382 | } else if (btState == 0xb) { | ||
6383 | pBtCoex->c2hBtInfo = BT_INFO_STATE_ACL_SCO_BUSY; | ||
6384 | pBtMgnt->ExtConfig.bBTBusy = true; | ||
6385 | } else { | ||
6386 | pBtCoex->c2hBtInfo = BT_INFO_STATE_MAX; | ||
6387 | } | ||
6388 | if (pBtMgnt->ExtConfig.bBTBusy) | ||
6389 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_IDLE; | ||
6390 | } | ||
6391 | |||
6392 | if ((BT_INFO_STATE_NO_CONNECTION == pBtCoex->c2hBtInfo) || | ||
6393 | (BT_INFO_STATE_CONNECT_IDLE == pBtCoex->c2hBtInfo)) { | ||
6394 | if (pBtCoex->bC2hBtInquiryPage) | ||
6395 | pBtCoex->c2hBtInfo = BT_INFO_STATE_INQ_OR_PAG; | ||
6396 | } | ||
6397 | |||
6398 | RTPRINT(FBT, BT_TRACE, ("[BTC2H], %s(%d)\n", | ||
6399 | BtStateString[pBtCoex->c2hBtInfo], pBtCoex->c2hBtInfo)); | ||
6400 | |||
6401 | if (pBtCoex->c2hBtProfile != BT_INFO_HID) | ||
6402 | pBtCoex->c2hBtProfile &= ~BT_INFO_HID; | ||
6403 | } | ||
6404 | |||
6405 | void BTDM_1AntBtCoexist8723A(struct rtw_adapter *padapter) | ||
6406 | { | ||
6407 | struct mlme_priv *pmlmepriv; | ||
6408 | struct hal_data_8723a *pHalData; | ||
6409 | unsigned long delta_time; | ||
6410 | |||
6411 | pmlmepriv = &padapter->mlmepriv; | ||
6412 | pHalData = GET_HAL_DATA(padapter); | ||
6413 | |||
6414 | if (check_fwstate(pmlmepriv, WIFI_SITE_MONITOR)) { | ||
6415 | /* already done in BTDM_1AntForScan() */ | ||
6416 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], wifi is under scan progress!!\n")); | ||
6417 | return; | ||
6418 | } | ||
6419 | |||
6420 | if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) { | ||
6421 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], wifi is under link progress!!\n")); | ||
6422 | return; | ||
6423 | } | ||
6424 | |||
6425 | /* under DHCP(Special packet) */ | ||
6426 | delta_time = jiffies - padapter->pwrctrlpriv.DelayLPSLastTimeStamp; | ||
6427 | delta_time = jiffies_to_msecs(delta_time); | ||
6428 | if (delta_time < 500) { | ||
6429 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], wifi is under DHCP " | ||
6430 | "progress(%li ms)!!\n", delta_time)); | ||
6431 | return; | ||
6432 | } | ||
6433 | |||
6434 | BTDM_CheckWiFiState(padapter); | ||
6435 | |||
6436 | btdm_1AntBtCoexistHandler(padapter); | ||
6437 | } | ||
6438 | |||
6439 | /* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87231Ant.c ===== */ | ||
6440 | #endif | ||
6441 | |||
6442 | #ifdef __HALBTC87232ANT_C__ /* HAL/BTCoexist/HalBtc87232Ant.c */ | ||
6443 | /* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc87232Ant.c ===== */ | ||
6444 | |||
6445 | /* local function start with btdm_ */ | ||
6446 | static u8 btdm_ActionAlgorithm(struct rtw_adapter *padapter) | ||
6447 | { | ||
6448 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
6449 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
6450 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6451 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
6452 | u8 bScoExist = false, bBtLinkExist = false, bBtHsModeExist = false; | ||
6453 | u8 algorithm = BT_2ANT_COEX_ALGO_UNDEFINED; | ||
6454 | |||
6455 | if (pBtMgnt->ExtConfig.NumberOfHandle) | ||
6456 | bBtLinkExist = true; | ||
6457 | if (pBtMgnt->ExtConfig.NumberOfSCO) | ||
6458 | bScoExist = true; | ||
6459 | if (BT_HsConnectionEstablished(padapter)) | ||
6460 | bBtHsModeExist = true; | ||
6461 | |||
6462 | /* here we get BT status first */ | ||
6463 | /* 1) initialize */ | ||
6464 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_IDLE; | ||
6465 | |||
6466 | if ((bScoExist) || (bBtHsModeExist) || | ||
6467 | (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID))) { | ||
6468 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO or HID or HS exists, set BT non-idle !!!\n")); | ||
6469 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE; | ||
6470 | } else { | ||
6471 | /* A2dp profile */ | ||
6472 | if ((pBtMgnt->ExtConfig.NumberOfHandle == 1) && | ||
6473 | (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP))) { | ||
6474 | if (BTDM_BtTxRxCounterL(padapter) < 100) { | ||
6475 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP, low priority tx+rx < 100, set BT connected-idle!!!\n")); | ||
6476 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE; | ||
6477 | } else { | ||
6478 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP, low priority tx+rx >= 100, set BT non-idle!!!\n")); | ||
6479 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE; | ||
6480 | } | ||
6481 | } | ||
6482 | /* Pan profile */ | ||
6483 | if ((pBtMgnt->ExtConfig.NumberOfHandle == 1) && | ||
6484 | (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN))) { | ||
6485 | if (BTDM_BtTxRxCounterL(padapter) < 600) { | ||
6486 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN, low priority tx+rx < 600, set BT connected-idle!!!\n")); | ||
6487 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE; | ||
6488 | } else { | ||
6489 | if (pHalData->bt_coexist.halCoex8723.lowPriorityTx) { | ||
6490 | if ((pHalData->bt_coexist.halCoex8723.lowPriorityRx / | ||
6491 | pHalData->bt_coexist.halCoex8723.lowPriorityTx) > 9) { | ||
6492 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN, low priority rx/tx > 9, set BT connected-idle!!!\n")); | ||
6493 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE; | ||
6494 | } | ||
6495 | } | ||
6496 | } | ||
6497 | if (BT_2ANT_BT_STATUS_CONNECTED_IDLE != pBtdm8723->btStatus) { | ||
6498 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN, set BT non-idle!!!\n")); | ||
6499 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE; | ||
6500 | } | ||
6501 | } | ||
6502 | /* Pan+A2dp profile */ | ||
6503 | if ((pBtMgnt->ExtConfig.NumberOfHandle == 2) && | ||
6504 | (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) && | ||
6505 | (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN))) { | ||
6506 | if (BTDM_BtTxRxCounterL(padapter) < 600) { | ||
6507 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN+A2DP, low priority tx+rx < 600, set BT connected-idle!!!\n")); | ||
6508 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE; | ||
6509 | } else { | ||
6510 | if (pHalData->bt_coexist.halCoex8723.lowPriorityTx) { | ||
6511 | if ((pHalData->bt_coexist.halCoex8723.lowPriorityRx / | ||
6512 | pHalData->bt_coexist.halCoex8723.lowPriorityTx) > 9) { | ||
6513 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN+A2DP, low priority rx/tx > 9, set BT connected-idle!!!\n")); | ||
6514 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE; | ||
6515 | } | ||
6516 | } | ||
6517 | } | ||
6518 | if (BT_2ANT_BT_STATUS_CONNECTED_IDLE != pBtdm8723->btStatus) { | ||
6519 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN+A2DP, set BT non-idle!!!\n")); | ||
6520 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE; | ||
6521 | } | ||
6522 | } | ||
6523 | } | ||
6524 | if (BT_2ANT_BT_STATUS_IDLE != pBtdm8723->btStatus) | ||
6525 | pBtMgnt->ExtConfig.bBTBusy = true; | ||
6526 | else | ||
6527 | pBtMgnt->ExtConfig.bBTBusy = false; | ||
6528 | |||
6529 | if (!bBtLinkExist) { | ||
6530 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], No profile exists!!!\n")); | ||
6531 | return algorithm; | ||
6532 | } | ||
6533 | |||
6534 | if (pBtMgnt->ExtConfig.NumberOfHandle == 1) { | ||
6535 | if (bScoExist) { | ||
6536 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO only\n")); | ||
6537 | algorithm = BT_2ANT_COEX_ALGO_SCO; | ||
6538 | } else { | ||
6539 | if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID)) { | ||
6540 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID only\n")); | ||
6541 | algorithm = BT_2ANT_COEX_ALGO_HID; | ||
6542 | } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) { | ||
6543 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP only\n")); | ||
6544 | algorithm = BT_2ANT_COEX_ALGO_A2DP; | ||
6545 | } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) { | ||
6546 | if (bBtHsModeExist) { | ||
6547 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN(HS) only\n")); | ||
6548 | algorithm = BT_2ANT_COEX_ALGO_PANHS; | ||
6549 | } else { | ||
6550 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN(EDR) only\n")); | ||
6551 | algorithm = BT_2ANT_COEX_ALGO_PANEDR; | ||
6552 | } | ||
6553 | } else { | ||
6554 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d \n", | ||
6555 | pBtMgnt->ExtConfig.NumberOfHandle)); | ||
6556 | } | ||
6557 | } | ||
6558 | } else if (pBtMgnt->ExtConfig.NumberOfHandle == 2) { | ||
6559 | if (bScoExist) { | ||
6560 | if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID)) { | ||
6561 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID\n")); | ||
6562 | algorithm = BT_2ANT_COEX_ALGO_HID; | ||
6563 | } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) { | ||
6564 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP\n")); | ||
6565 | } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) { | ||
6566 | if (bBtHsModeExist) { | ||
6567 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(HS)\n")); | ||
6568 | algorithm = BT_2ANT_COEX_ALGO_SCO; | ||
6569 | } else { | ||
6570 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(EDR)\n")); | ||
6571 | algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID; | ||
6572 | } | ||
6573 | } else { | ||
6574 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO exists but why NO matched ACL profile for NumberOfHandle =%d\n", | ||
6575 | pBtMgnt->ExtConfig.NumberOfHandle)); | ||
6576 | } | ||
6577 | } else { | ||
6578 | if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) && | ||
6579 | BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) { | ||
6580 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP\n")); | ||
6581 | algorithm = BT_2ANT_COEX_ALGO_HID_A2DP; | ||
6582 | } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) && | ||
6583 | BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) { | ||
6584 | if (bBtHsModeExist) { | ||
6585 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(HS)\n")); | ||
6586 | algorithm = BT_2ANT_COEX_ALGO_HID_A2DP; | ||
6587 | } else { | ||
6588 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(EDR)\n")); | ||
6589 | algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID; | ||
6590 | } | ||
6591 | } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) && | ||
6592 | BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) { | ||
6593 | if (bBtHsModeExist) { | ||
6594 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(HS)\n")); | ||
6595 | algorithm = BT_2ANT_COEX_ALGO_A2DP; | ||
6596 | } else { | ||
6597 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n")); | ||
6598 | algorithm = BT_2ANT_COEX_ALGO_PANEDR_A2DP; | ||
6599 | } | ||
6600 | } else { | ||
6601 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d\n", | ||
6602 | pBtMgnt->ExtConfig.NumberOfHandle)); | ||
6603 | } | ||
6604 | } | ||
6605 | } else if (pBtMgnt->ExtConfig.NumberOfHandle == 3) { | ||
6606 | if (bScoExist) { | ||
6607 | if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) && | ||
6608 | BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) { | ||
6609 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP\n")); | ||
6610 | } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) && | ||
6611 | BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) { | ||
6612 | if (bBtHsModeExist) { | ||
6613 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID + PAN(HS)\n")); | ||
6614 | algorithm = BT_2ANT_COEX_ALGO_HID_A2DP; | ||
6615 | } else { | ||
6616 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID + PAN(EDR)\n")); | ||
6617 | algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID; | ||
6618 | } | ||
6619 | } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) && | ||
6620 | BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) { | ||
6621 | if (bBtHsModeExist) { | ||
6622 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP + PAN(HS)\n")); | ||
6623 | algorithm = BT_2ANT_COEX_ALGO_SCO; | ||
6624 | } else { | ||
6625 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP + PAN(EDR)\n")); | ||
6626 | } | ||
6627 | } else { | ||
6628 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO exists but why NO matched profile for NumberOfHandle =%d\n", | ||
6629 | pBtMgnt->ExtConfig.NumberOfHandle)); | ||
6630 | } | ||
6631 | } else { | ||
6632 | if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) && | ||
6633 | BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) && | ||
6634 | BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) { | ||
6635 | if (bBtHsModeExist) { | ||
6636 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n")); | ||
6637 | algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANHS; | ||
6638 | } else { | ||
6639 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n")); | ||
6640 | algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR; | ||
6641 | } | ||
6642 | } else { | ||
6643 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d\n", | ||
6644 | pBtMgnt->ExtConfig.NumberOfHandle)); | ||
6645 | } | ||
6646 | } | ||
6647 | } else if (pBtMgnt->ExtConfig.NumberOfHandle >= 3) { | ||
6648 | if (bScoExist) { | ||
6649 | if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) && | ||
6650 | BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) && | ||
6651 | BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) { | ||
6652 | if (bBtHsModeExist) | ||
6653 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n")); | ||
6654 | else | ||
6655 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(EDR)\n")); | ||
6656 | } else { | ||
6657 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO exists but why NO matched profile for NumberOfHandle =%d\n", | ||
6658 | pBtMgnt->ExtConfig.NumberOfHandle)); | ||
6659 | } | ||
6660 | } else { | ||
6661 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d\n", | ||
6662 | pBtMgnt->ExtConfig.NumberOfHandle)); | ||
6663 | } | ||
6664 | } | ||
6665 | return algorithm; | ||
6666 | } | ||
6667 | |||
6668 | static u8 btdm_NeedToDecBtPwr(struct rtw_adapter *padapter) | ||
6669 | { | ||
6670 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6671 | u8 bRet = false; | ||
6672 | |||
6673 | if (BT_Operation(padapter)) { | ||
6674 | if (pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB > 47) { | ||
6675 | RTPRINT(FBT, BT_TRACE, ("Need to decrease bt power for HS mode!!\n")); | ||
6676 | bRet = true; | ||
6677 | } else { | ||
6678 | RTPRINT(FBT, BT_TRACE, ("NO Need to decrease bt power for HS mode!!\n")); | ||
6679 | } | ||
6680 | } else { | ||
6681 | if (BTDM_IsWifiConnectionExist(padapter)) { | ||
6682 | RTPRINT(FBT, BT_TRACE, ("Need to decrease bt power for Wifi is connected!!\n")); | ||
6683 | bRet = true; | ||
6684 | } | ||
6685 | } | ||
6686 | return bRet; | ||
6687 | } | ||
6688 | |||
6689 | static void | ||
6690 | btdm_SetCoexTable(struct rtw_adapter *padapter, u32 val0x6c0, | ||
6691 | u32 val0x6c8, u8 val0x6cc) | ||
6692 | { | ||
6693 | RTPRINT(FBT, BT_TRACE, ("set coex table, set 0x6c0 = 0x%x\n", val0x6c0)); | ||
6694 | rtw_write32(padapter, 0x6c0, val0x6c0); | ||
6695 | |||
6696 | RTPRINT(FBT, BT_TRACE, ("set coex table, set 0x6c8 = 0x%x\n", val0x6c8)); | ||
6697 | rtw_write32(padapter, 0x6c8, val0x6c8); | ||
6698 | |||
6699 | RTPRINT(FBT, BT_TRACE, ("set coex table, set 0x6cc = 0x%x\n", val0x6cc)); | ||
6700 | rtw_write8(padapter, 0x6cc, val0x6cc); | ||
6701 | } | ||
6702 | |||
6703 | static void | ||
6704 | btdm_SetSwFullTimeDacSwing(struct rtw_adapter *padapter, u8 bSwDacSwingOn, | ||
6705 | u32 swDacSwingLvl) | ||
6706 | { | ||
6707 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6708 | |||
6709 | if (bSwDacSwingOn) { | ||
6710 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], SwDacSwing = 0x%x\n", swDacSwingLvl)); | ||
6711 | PHY_SetBBReg(padapter, 0x880, 0xff000000, swDacSwingLvl); | ||
6712 | pHalData->bt_coexist.bSWCoexistAllOff = false; | ||
6713 | } else { | ||
6714 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], SwDacSwing Off!\n")); | ||
6715 | PHY_SetBBReg(padapter, 0x880, 0xff000000, 0xc0); | ||
6716 | } | ||
6717 | } | ||
6718 | |||
6719 | static void | ||
6720 | btdm_SetFwDacSwingLevel(struct rtw_adapter *padapter, u8 dacSwingLvl) | ||
6721 | { | ||
6722 | u8 H2C_Parameter[1] = {0}; | ||
6723 | |||
6724 | H2C_Parameter[0] = dacSwingLvl; | ||
6725 | |||
6726 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Set Dac Swing Level = 0x%x\n", dacSwingLvl)); | ||
6727 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], write 0x29 = 0x%x\n", H2C_Parameter[0])); | ||
6728 | |||
6729 | FillH2CCmd(padapter, 0x29, 1, H2C_Parameter); | ||
6730 | } | ||
6731 | |||
6732 | static void btdm_2AntDecBtPwr(struct rtw_adapter *padapter, u8 bDecBtPwr) | ||
6733 | { | ||
6734 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6735 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
6736 | |||
6737 | RTPRINT(FBT, BT_TRACE, | ||
6738 | ("[BTCoex], Dec BT power = %s\n", | ||
6739 | ((bDecBtPwr) ? "ON" : "OFF"))); | ||
6740 | pBtdm8723->bCurDecBtPwr = bDecBtPwr; | ||
6741 | |||
6742 | if (pBtdm8723->bPreDecBtPwr == pBtdm8723->bCurDecBtPwr) | ||
6743 | return; | ||
6744 | |||
6745 | BTDM_SetFwDecBtPwr(padapter, pBtdm8723->bCurDecBtPwr); | ||
6746 | |||
6747 | pBtdm8723->bPreDecBtPwr = pBtdm8723->bCurDecBtPwr; | ||
6748 | } | ||
6749 | |||
6750 | static void | ||
6751 | btdm_2AntFwDacSwingLvl(struct rtw_adapter *padapter, u8 fwDacSwingLvl) | ||
6752 | { | ||
6753 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6754 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
6755 | |||
6756 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], set FW Dac Swing level = %d\n", fwDacSwingLvl)); | ||
6757 | pBtdm8723->curFwDacSwingLvl = fwDacSwingLvl; | ||
6758 | |||
6759 | /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], preFwDacSwingLvl =%d, curFwDacSwingLvl =%d\n", */ | ||
6760 | /*pBtdm8723->preFwDacSwingLvl, pBtdm8723->curFwDacSwingLvl)); */ | ||
6761 | |||
6762 | if (pBtdm8723->preFwDacSwingLvl == pBtdm8723->curFwDacSwingLvl) | ||
6763 | return; | ||
6764 | |||
6765 | btdm_SetFwDacSwingLevel(padapter, pBtdm8723->curFwDacSwingLvl); | ||
6766 | |||
6767 | pBtdm8723->preFwDacSwingLvl = pBtdm8723->curFwDacSwingLvl; | ||
6768 | } | ||
6769 | |||
6770 | static void | ||
6771 | btdm_2AntRfShrink(struct rtw_adapter *padapter, u8 bRxRfShrinkOn) | ||
6772 | { | ||
6773 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6774 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
6775 | |||
6776 | RTPRINT(FBT, BT_TRACE, | ||
6777 | ("[BTCoex], turn Rx RF Shrink = %s\n", | ||
6778 | ((bRxRfShrinkOn) ? "ON" : "OFF"))); | ||
6779 | pBtdm8723->bCurRfRxLpfShrink = bRxRfShrinkOn; | ||
6780 | |||
6781 | /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], bPreRfRxLpfShrink =%d, bCurRfRxLpfShrink =%d\n", */ | ||
6782 | /*pBtdm8723->bPreRfRxLpfShrink, pBtdm8723->bCurRfRxLpfShrink)); */ | ||
6783 | |||
6784 | if (pBtdm8723->bPreRfRxLpfShrink == pBtdm8723->bCurRfRxLpfShrink) | ||
6785 | return; | ||
6786 | |||
6787 | BTDM_SetSwRfRxLpfCorner(padapter, (u8)pBtdm8723->bCurRfRxLpfShrink); | ||
6788 | |||
6789 | pBtdm8723->bPreRfRxLpfShrink = pBtdm8723->bCurRfRxLpfShrink; | ||
6790 | } | ||
6791 | |||
6792 | static void | ||
6793 | btdm_2AntLowPenaltyRa(struct rtw_adapter *padapter, u8 bLowPenaltyRa) | ||
6794 | { | ||
6795 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6796 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
6797 | |||
6798 | RTPRINT(FBT, BT_TRACE, | ||
6799 | ("[BTCoex], turn LowPenaltyRA = %s\n", | ||
6800 | ((bLowPenaltyRa) ? "ON" : "OFF"))); | ||
6801 | pBtdm8723->bCurLowPenaltyRa = bLowPenaltyRa; | ||
6802 | |||
6803 | /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], bPreLowPenaltyRa =%d, bCurLowPenaltyRa =%d\n", */ | ||
6804 | /*pBtdm8723->bPreLowPenaltyRa, pBtdm8723->bCurLowPenaltyRa)); */ | ||
6805 | |||
6806 | if (pBtdm8723->bPreLowPenaltyRa == pBtdm8723->bCurLowPenaltyRa) | ||
6807 | return; | ||
6808 | |||
6809 | BTDM_SetSwPenaltyTxRateAdaptive(padapter, (u8)pBtdm8723->bCurLowPenaltyRa); | ||
6810 | |||
6811 | pBtdm8723->bPreLowPenaltyRa = pBtdm8723->bCurLowPenaltyRa; | ||
6812 | } | ||
6813 | |||
6814 | static void | ||
6815 | btdm_2AntDacSwing(struct rtw_adapter *padapter, | ||
6816 | u8 bDacSwingOn, u32 dacSwingLvl) | ||
6817 | { | ||
6818 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6819 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
6820 | |||
6821 | RTPRINT(FBT, BT_TRACE, | ||
6822 | ("[BTCoex], turn DacSwing =%s, dacSwingLvl = 0x%x\n", | ||
6823 | (bDacSwingOn ? "ON" : "OFF"), dacSwingLvl)); | ||
6824 | pBtdm8723->bCurDacSwingOn = bDacSwingOn; | ||
6825 | pBtdm8723->curDacSwingLvl = dacSwingLvl; | ||
6826 | |||
6827 | if ((pBtdm8723->bPreDacSwingOn == pBtdm8723->bCurDacSwingOn) && | ||
6828 | (pBtdm8723->preDacSwingLvl == pBtdm8723->curDacSwingLvl)) | ||
6829 | return; | ||
6830 | |||
6831 | mdelay(30); | ||
6832 | btdm_SetSwFullTimeDacSwing(padapter, bDacSwingOn, dacSwingLvl); | ||
6833 | |||
6834 | pBtdm8723->bPreDacSwingOn = pBtdm8723->bCurDacSwingOn; | ||
6835 | pBtdm8723->preDacSwingLvl = pBtdm8723->curDacSwingLvl; | ||
6836 | } | ||
6837 | |||
6838 | static void btdm_2AntAdcBackOff(struct rtw_adapter *padapter, u8 bAdcBackOff) | ||
6839 | { | ||
6840 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6841 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
6842 | |||
6843 | RTPRINT(FBT, BT_TRACE, | ||
6844 | ("[BTCoex], turn AdcBackOff = %s\n", | ||
6845 | ((bAdcBackOff) ? "ON" : "OFF"))); | ||
6846 | pBtdm8723->bCurAdcBackOff = bAdcBackOff; | ||
6847 | |||
6848 | if (pBtdm8723->bPreAdcBackOff == pBtdm8723->bCurAdcBackOff) | ||
6849 | return; | ||
6850 | |||
6851 | BTDM_BBBackOffLevel(padapter, (u8)pBtdm8723->bCurAdcBackOff); | ||
6852 | |||
6853 | pBtdm8723->bPreAdcBackOff = pBtdm8723->bCurAdcBackOff; | ||
6854 | } | ||
6855 | |||
6856 | static void btdm_2AntAgcTable(struct rtw_adapter *padapter, u8 bAgcTableEn) | ||
6857 | { | ||
6858 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6859 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
6860 | |||
6861 | RTPRINT(FBT, BT_TRACE, | ||
6862 | ("[BTCoex], %s Agc Table\n", ((bAgcTableEn) ? "Enable" : "Disable"))); | ||
6863 | pBtdm8723->bCurAgcTableEn = bAgcTableEn; | ||
6864 | |||
6865 | /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], bPreAgcTableEn =%d, bCurAgcTableEn =%d\n", */ | ||
6866 | /*pBtdm8723->bPreAgcTableEn, pBtdm8723->bCurAgcTableEn)); */ | ||
6867 | |||
6868 | if (pBtdm8723->bPreAgcTableEn == pBtdm8723->bCurAgcTableEn) | ||
6869 | return; | ||
6870 | |||
6871 | BTDM_AGCTable(padapter, (u8)bAgcTableEn); | ||
6872 | |||
6873 | pBtdm8723->bPreAgcTableEn = pBtdm8723->bCurAgcTableEn; | ||
6874 | } | ||
6875 | |||
6876 | static void | ||
6877 | btdm_2AntCoexTable(struct rtw_adapter *padapter, | ||
6878 | u32 val0x6c0, u32 val0x6c8, u8 val0x6cc) | ||
6879 | { | ||
6880 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6881 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
6882 | |||
6883 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], write Coex Table 0x6c0 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n", | ||
6884 | val0x6c0, val0x6c8, val0x6cc)); | ||
6885 | pBtdm8723->curVal0x6c0 = val0x6c0; | ||
6886 | pBtdm8723->curVal0x6c8 = val0x6c8; | ||
6887 | pBtdm8723->curVal0x6cc = val0x6cc; | ||
6888 | |||
6889 | /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], preVal0x6c0 = 0x%x, preVal0x6c8 = 0x%x, preVal0x6cc = 0x%x !!\n", */ | ||
6890 | /*pBtdm8723->preVal0x6c0, pBtdm8723->preVal0x6c8, pBtdm8723->preVal0x6cc)); */ | ||
6891 | /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], curVal0x6c0 = 0x%x, curVal0x6c8 = 0x%x, curVal0x6cc = 0x%x !!\n", */ | ||
6892 | /*pBtdm8723->curVal0x6c0, pBtdm8723->curVal0x6c8, pBtdm8723->curVal0x6cc)); */ | ||
6893 | |||
6894 | if ((pBtdm8723->preVal0x6c0 == pBtdm8723->curVal0x6c0) && | ||
6895 | (pBtdm8723->preVal0x6c8 == pBtdm8723->curVal0x6c8) && | ||
6896 | (pBtdm8723->preVal0x6cc == pBtdm8723->curVal0x6cc)) | ||
6897 | return; | ||
6898 | |||
6899 | btdm_SetCoexTable(padapter, val0x6c0, val0x6c8, val0x6cc); | ||
6900 | |||
6901 | pBtdm8723->preVal0x6c0 = pBtdm8723->curVal0x6c0; | ||
6902 | pBtdm8723->preVal0x6c8 = pBtdm8723->curVal0x6c8; | ||
6903 | pBtdm8723->preVal0x6cc = pBtdm8723->curVal0x6cc; | ||
6904 | } | ||
6905 | |||
6906 | static void btdm_2AntIgnoreWlanAct(struct rtw_adapter *padapter, u8 bEnable) | ||
6907 | { | ||
6908 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6909 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
6910 | |||
6911 | RTPRINT(FBT, BT_TRACE, | ||
6912 | ("[BTCoex], turn Ignore WlanAct %s\n", (bEnable ? "ON" : "OFF"))); | ||
6913 | pBtdm8723->bCurIgnoreWlanAct = bEnable; | ||
6914 | |||
6915 | |||
6916 | if (pBtdm8723->bPreIgnoreWlanAct == pBtdm8723->bCurIgnoreWlanAct) | ||
6917 | return; | ||
6918 | |||
6919 | btdm_SetFwIgnoreWlanAct(padapter, bEnable); | ||
6920 | pBtdm8723->bPreIgnoreWlanAct = pBtdm8723->bCurIgnoreWlanAct; | ||
6921 | } | ||
6922 | |||
6923 | static void | ||
6924 | btdm_2AntSetFw3a(struct rtw_adapter *padapter, u8 byte1, u8 byte2, | ||
6925 | u8 byte3, u8 byte4, u8 byte5) | ||
6926 | { | ||
6927 | u8 H2C_Parameter[5] = {0}; | ||
6928 | |||
6929 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6930 | |||
6931 | /* byte1[1:0] != 0 means enable pstdma */ | ||
6932 | /* for 2Ant bt coexist, if byte1 != 0 means enable pstdma */ | ||
6933 | if (byte1) | ||
6934 | pHalData->bt_coexist.bFWCoexistAllOff = false; | ||
6935 | H2C_Parameter[0] = byte1; | ||
6936 | H2C_Parameter[1] = byte2; | ||
6937 | H2C_Parameter[2] = byte3; | ||
6938 | H2C_Parameter[3] = byte4; | ||
6939 | H2C_Parameter[4] = byte5; | ||
6940 | |||
6941 | pHalData->bt_coexist.fw3aVal[0] = byte1; | ||
6942 | pHalData->bt_coexist.fw3aVal[1] = byte2; | ||
6943 | pHalData->bt_coexist.fw3aVal[2] = byte3; | ||
6944 | pHalData->bt_coexist.fw3aVal[3] = byte4; | ||
6945 | pHalData->bt_coexist.fw3aVal[4] = byte5; | ||
6946 | |||
6947 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], FW write 0x3a(5bytes) = 0x%x%08x\n", | ||
6948 | H2C_Parameter[0], | ||
6949 | H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); | ||
6950 | |||
6951 | FillH2CCmd(padapter, 0x3a, 5, H2C_Parameter); | ||
6952 | } | ||
6953 | |||
6954 | static void btdm_2AntPsTdma(struct rtw_adapter *padapter, u8 bTurnOn, u8 type) | ||
6955 | { | ||
6956 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
6957 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
6958 | u32 btTxRxCnt = 0; | ||
6959 | u8 bTurnOnByCnt = false; | ||
6960 | u8 psTdmaTypeByCnt = 0; | ||
6961 | |||
6962 | btTxRxCnt = BTDM_BtTxRxCounterH(padapter)+BTDM_BtTxRxCounterL(padapter); | ||
6963 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT TxRx Counters = %d\n", btTxRxCnt)); | ||
6964 | if (btTxRxCnt > 3000) { | ||
6965 | bTurnOnByCnt = true; | ||
6966 | psTdmaTypeByCnt = 8; | ||
6967 | |||
6968 | RTPRINT(FBT, BT_TRACE, | ||
6969 | ("[BTCoex], For BTTxRxCounters, turn %s PS TDMA, type =%d\n", | ||
6970 | (bTurnOnByCnt ? "ON" : "OFF"), psTdmaTypeByCnt)); | ||
6971 | pBtdm8723->bCurPsTdmaOn = bTurnOnByCnt; | ||
6972 | pBtdm8723->curPsTdma = psTdmaTypeByCnt; | ||
6973 | } else { | ||
6974 | RTPRINT(FBT, BT_TRACE, | ||
6975 | ("[BTCoex], turn %s PS TDMA, type =%d\n", | ||
6976 | (bTurnOn ? "ON" : "OFF"), type)); | ||
6977 | pBtdm8723->bCurPsTdmaOn = bTurnOn; | ||
6978 | pBtdm8723->curPsTdma = type; | ||
6979 | } | ||
6980 | |||
6981 | if ((pBtdm8723->bPrePsTdmaOn == pBtdm8723->bCurPsTdmaOn) && | ||
6982 | (pBtdm8723->prePsTdma == pBtdm8723->curPsTdma)) | ||
6983 | return; | ||
6984 | |||
6985 | if (bTurnOn) { | ||
6986 | switch (type) { | ||
6987 | case 1: | ||
6988 | default: | ||
6989 | btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0xa1, 0x98); | ||
6990 | break; | ||
6991 | case 2: | ||
6992 | btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0xa1, 0x98); | ||
6993 | break; | ||
6994 | case 3: | ||
6995 | btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0xa1, 0x98); | ||
6996 | break; | ||
6997 | case 4: | ||
6998 | btdm_2AntSetFw3a(padapter, 0xa3, 0x5, 0x5, 0xa1, 0x80); | ||
6999 | break; | ||
7000 | case 5: | ||
7001 | btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0x20, 0x98); | ||
7002 | break; | ||
7003 | case 6: | ||
7004 | btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0x20, 0x98); | ||
7005 | break; | ||
7006 | case 7: | ||
7007 | btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0x20, 0x98); | ||
7008 | break; | ||
7009 | case 8: | ||
7010 | btdm_2AntSetFw3a(padapter, 0xa3, 0x5, 0x5, 0x20, 0x80); | ||
7011 | break; | ||
7012 | case 9: | ||
7013 | btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0xa1, 0x98); | ||
7014 | break; | ||
7015 | case 10: | ||
7016 | btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0xa1, 0x98); | ||
7017 | break; | ||
7018 | case 11: | ||
7019 | btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0xa1, 0x98); | ||
7020 | break; | ||
7021 | case 12: | ||
7022 | btdm_2AntSetFw3a(padapter, 0xe3, 0x5, 0x5, 0xa1, 0x98); | ||
7023 | break; | ||
7024 | case 13: | ||
7025 | btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0x20, 0x98); | ||
7026 | break; | ||
7027 | case 14: | ||
7028 | btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0x20, 0x98); | ||
7029 | break; | ||
7030 | case 15: | ||
7031 | btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0x20, 0x98); | ||
7032 | break; | ||
7033 | case 16: | ||
7034 | btdm_2AntSetFw3a(padapter, 0xe3, 0x5, 0x5, 0x20, 0x98); | ||
7035 | break; | ||
7036 | case 17: | ||
7037 | btdm_2AntSetFw3a(padapter, 0xa3, 0x2f, 0x2f, 0x20, 0x80); | ||
7038 | break; | ||
7039 | case 18: | ||
7040 | btdm_2AntSetFw3a(padapter, 0xe3, 0x5, 0x5, 0xa1, 0x98); | ||
7041 | break; | ||
7042 | case 19: | ||
7043 | btdm_2AntSetFw3a(padapter, 0xe3, 0x25, 0x25, 0xa1, 0x98); | ||
7044 | break; | ||
7045 | case 20: | ||
7046 | btdm_2AntSetFw3a(padapter, 0xe3, 0x25, 0x25, 0x20, 0x98); | ||
7047 | break; | ||
7048 | } | ||
7049 | } else { | ||
7050 | /* disable PS tdma */ | ||
7051 | switch (type) { | ||
7052 | case 0: | ||
7053 | btdm_2AntSetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0); | ||
7054 | break; | ||
7055 | case 1: | ||
7056 | btdm_2AntSetFw3a(padapter, 0x0, 0x0, 0x0, 0x0, 0x0); | ||
7057 | break; | ||
7058 | default: | ||
7059 | btdm_2AntSetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0); | ||
7060 | break; | ||
7061 | } | ||
7062 | } | ||
7063 | |||
7064 | /* update pre state */ | ||
7065 | pBtdm8723->bPrePsTdmaOn = pBtdm8723->bCurPsTdmaOn; | ||
7066 | pBtdm8723->prePsTdma = pBtdm8723->curPsTdma; | ||
7067 | } | ||
7068 | |||
7069 | static void btdm_2AntBtInquiryPage(struct rtw_adapter *padapter) | ||
7070 | { | ||
7071 | btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3); | ||
7072 | btdm_2AntIgnoreWlanAct(padapter, false); | ||
7073 | btdm_2AntPsTdma(padapter, true, 8); | ||
7074 | } | ||
7075 | |||
7076 | static u8 btdm_HoldForBtInqPage(struct rtw_adapter *padapter) | ||
7077 | { | ||
7078 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
7079 | u32 curTime = rtw_get_current_time(); | ||
7080 | |||
7081 | if (pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage) { | ||
7082 | /* bt inquiry or page is started. */ | ||
7083 | if (pHalData->bt_coexist.halCoex8723.btInqPageStartTime == 0) { | ||
7084 | pHalData->bt_coexist.halCoex8723.btInqPageStartTime = curTime; | ||
7085 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Inquiry/page is started at time : 0x%"i64fmt"x \n", | ||
7086 | pHalData->bt_coexist.halCoex8723.btInqPageStartTime)); | ||
7087 | } | ||
7088 | } | ||
7089 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Inquiry/page started time : 0x%"i64fmt"x, curTime : 0x%x \n", | ||
7090 | pHalData->bt_coexist.halCoex8723.btInqPageStartTime, curTime)); | ||
7091 | |||
7092 | if (pHalData->bt_coexist.halCoex8723.btInqPageStartTime) { | ||
7093 | if (((curTime - pHalData->bt_coexist.halCoex8723.btInqPageStartTime)/1000000) >= 10) { | ||
7094 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Inquiry/page >= 10sec!!!")); | ||
7095 | pHalData->bt_coexist.halCoex8723.btInqPageStartTime = 0; | ||
7096 | } | ||
7097 | } | ||
7098 | |||
7099 | if (pHalData->bt_coexist.halCoex8723.btInqPageStartTime) { | ||
7100 | btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3); | ||
7101 | btdm_2AntIgnoreWlanAct(padapter, false); | ||
7102 | btdm_2AntPsTdma(padapter, true, 8); | ||
7103 | return true; | ||
7104 | } else { | ||
7105 | return false; | ||
7106 | } | ||
7107 | } | ||
7108 | |||
7109 | static u8 btdm_Is2Ant8723ACommonAction(struct rtw_adapter *padapter) | ||
7110 | { | ||
7111 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
7112 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
7113 | u8 bCommon = false; | ||
7114 | |||
7115 | RTPRINT(FBT, BT_TRACE, ("%s :BTDM_IsWifiConnectionExist =%x check_fwstate =%x pmlmepriv->fw_state = 0x%x\n", __func__, BTDM_IsWifiConnectionExist(padapter), check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)), padapter->mlmepriv.fw_state)); | ||
7116 | |||
7117 | if ((!BTDM_IsWifiConnectionExist(padapter)) && | ||
7118 | (!check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) && | ||
7119 | (BT_2ANT_BT_STATUS_IDLE == pBtdm8723->btStatus)) { | ||
7120 | RTPRINT(FBT, BT_TRACE, ("Wifi idle + Bt idle!!\n")); | ||
7121 | |||
7122 | btdm_2AntLowPenaltyRa(padapter, false); | ||
7123 | btdm_2AntRfShrink(padapter, false); | ||
7124 | btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3); | ||
7125 | |||
7126 | btdm_2AntIgnoreWlanAct(padapter, false); | ||
7127 | btdm_2AntPsTdma(padapter, false, 0); | ||
7128 | btdm_2AntFwDacSwingLvl(padapter, 0x20); | ||
7129 | btdm_2AntDecBtPwr(padapter, false); | ||
7130 | |||
7131 | btdm_2AntAgcTable(padapter, false); | ||
7132 | btdm_2AntAdcBackOff(padapter, false); | ||
7133 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
7134 | |||
7135 | bCommon = true; | ||
7136 | } else if (((BTDM_IsWifiConnectionExist(padapter)) || | ||
7137 | (check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)))) && | ||
7138 | (BT_2ANT_BT_STATUS_IDLE == pBtdm8723->btStatus)) { | ||
7139 | RTPRINT(FBT, BT_TRACE, ("Wifi non-idle + BT idle!!\n")); | ||
7140 | |||
7141 | btdm_2AntLowPenaltyRa(padapter, true); | ||
7142 | btdm_2AntRfShrink(padapter, false); | ||
7143 | btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3); | ||
7144 | |||
7145 | btdm_2AntIgnoreWlanAct(padapter, false); | ||
7146 | btdm_2AntPsTdma(padapter, false, 0); | ||
7147 | btdm_2AntFwDacSwingLvl(padapter, 0x20); | ||
7148 | btdm_2AntDecBtPwr(padapter, true); | ||
7149 | |||
7150 | btdm_2AntAgcTable(padapter, false); | ||
7151 | btdm_2AntAdcBackOff(padapter, false); | ||
7152 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
7153 | |||
7154 | bCommon = true; | ||
7155 | } else if ((!BTDM_IsWifiConnectionExist(padapter)) && | ||
7156 | (!check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) && | ||
7157 | (BT_2ANT_BT_STATUS_CONNECTED_IDLE == pBtdm8723->btStatus)) { | ||
7158 | RTPRINT(FBT, BT_TRACE, ("Wifi idle + Bt connected idle!!\n")); | ||
7159 | |||
7160 | btdm_2AntLowPenaltyRa(padapter, true); | ||
7161 | btdm_2AntRfShrink(padapter, true); | ||
7162 | btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3); | ||
7163 | |||
7164 | btdm_2AntIgnoreWlanAct(padapter, false); | ||
7165 | btdm_2AntPsTdma(padapter, false, 0); | ||
7166 | btdm_2AntFwDacSwingLvl(padapter, 0x20); | ||
7167 | btdm_2AntDecBtPwr(padapter, false); | ||
7168 | |||
7169 | btdm_2AntAgcTable(padapter, false); | ||
7170 | btdm_2AntAdcBackOff(padapter, false); | ||
7171 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
7172 | |||
7173 | bCommon = true; | ||
7174 | } else if (((BTDM_IsWifiConnectionExist(padapter)) || | ||
7175 | (check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)))) && | ||
7176 | (BT_2ANT_BT_STATUS_CONNECTED_IDLE == pBtdm8723->btStatus)) { | ||
7177 | RTPRINT(FBT, BT_TRACE, ("Wifi non-idle + Bt connected idle!!\n")); | ||
7178 | |||
7179 | btdm_2AntLowPenaltyRa(padapter, true); | ||
7180 | btdm_2AntRfShrink(padapter, true); | ||
7181 | btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3); | ||
7182 | |||
7183 | btdm_2AntIgnoreWlanAct(padapter, false); | ||
7184 | btdm_2AntPsTdma(padapter, false, 0); | ||
7185 | btdm_2AntFwDacSwingLvl(padapter, 0x20); | ||
7186 | btdm_2AntDecBtPwr(padapter, true); | ||
7187 | |||
7188 | btdm_2AntAgcTable(padapter, false); | ||
7189 | btdm_2AntAdcBackOff(padapter, false); | ||
7190 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
7191 | |||
7192 | bCommon = true; | ||
7193 | } else if ((!BTDM_IsWifiConnectionExist(padapter)) && | ||
7194 | (!check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) && | ||
7195 | (BT_2ANT_BT_STATUS_NON_IDLE == pBtdm8723->btStatus)) { | ||
7196 | RTPRINT(FBT, BT_TRACE, ("Wifi idle + BT non-idle!!\n")); | ||
7197 | |||
7198 | btdm_2AntLowPenaltyRa(padapter, true); | ||
7199 | btdm_2AntRfShrink(padapter, true); | ||
7200 | btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3); | ||
7201 | |||
7202 | btdm_2AntIgnoreWlanAct(padapter, false); | ||
7203 | btdm_2AntPsTdma(padapter, false, 0); | ||
7204 | btdm_2AntFwDacSwingLvl(padapter, 0x20); | ||
7205 | btdm_2AntDecBtPwr(padapter, false); | ||
7206 | |||
7207 | btdm_2AntAgcTable(padapter, false); | ||
7208 | btdm_2AntAdcBackOff(padapter, false); | ||
7209 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
7210 | |||
7211 | bCommon = true; | ||
7212 | } else { | ||
7213 | RTPRINT(FBT, BT_TRACE, ("Wifi non-idle + BT non-idle!!\n")); | ||
7214 | btdm_2AntLowPenaltyRa(padapter, true); | ||
7215 | btdm_2AntRfShrink(padapter, true); | ||
7216 | btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3); | ||
7217 | btdm_2AntIgnoreWlanAct(padapter, false); | ||
7218 | btdm_2AntFwDacSwingLvl(padapter, 0x20); | ||
7219 | |||
7220 | bCommon = false; | ||
7221 | } | ||
7222 | return bCommon; | ||
7223 | } | ||
7224 | |||
7225 | static void | ||
7226 | btdm_2AntTdmaDurationAdjust(struct rtw_adapter *padapter, u8 bScoHid, | ||
7227 | u8 bTxPause, u8 maxInterval) | ||
7228 | { | ||
7229 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
7230 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
7231 | static s32 up, dn, m, n, WaitCount; | ||
7232 | s32 result; /* 0: no change, +1: increase WiFi duration, -1: decrease WiFi duration */ | ||
7233 | u8 retryCount = 0; | ||
7234 | |||
7235 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], TdmaDurationAdjust()\n")); | ||
7236 | |||
7237 | if (pBtdm8723->bResetTdmaAdjust) { | ||
7238 | pBtdm8723->bResetTdmaAdjust = false; | ||
7239 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n")); | ||
7240 | if (bScoHid) { | ||
7241 | if (bTxPause) { | ||
7242 | if (maxInterval == 1) { | ||
7243 | btdm_2AntPsTdma(padapter, true, 15); | ||
7244 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7245 | } else if (maxInterval == 2) { | ||
7246 | btdm_2AntPsTdma(padapter, true, 15); | ||
7247 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7248 | } else if (maxInterval == 3) { | ||
7249 | btdm_2AntPsTdma(padapter, true, 15); | ||
7250 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7251 | } else { | ||
7252 | btdm_2AntPsTdma(padapter, true, 15); | ||
7253 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7254 | } | ||
7255 | } else { | ||
7256 | if (maxInterval == 1) { | ||
7257 | btdm_2AntPsTdma(padapter, true, 11); | ||
7258 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7259 | } else if (maxInterval == 2) { | ||
7260 | btdm_2AntPsTdma(padapter, true, 11); | ||
7261 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7262 | } else if (maxInterval == 3) { | ||
7263 | btdm_2AntPsTdma(padapter, true, 11); | ||
7264 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7265 | } else { | ||
7266 | btdm_2AntPsTdma(padapter, true, 11); | ||
7267 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7268 | } | ||
7269 | } | ||
7270 | } else { | ||
7271 | if (bTxPause) { | ||
7272 | if (maxInterval == 1) { | ||
7273 | btdm_2AntPsTdma(padapter, true, 7); | ||
7274 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7275 | } else if (maxInterval == 2) { | ||
7276 | btdm_2AntPsTdma(padapter, true, 7); | ||
7277 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7278 | } else if (maxInterval == 3) { | ||
7279 | btdm_2AntPsTdma(padapter, true, 7); | ||
7280 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7281 | } else { | ||
7282 | btdm_2AntPsTdma(padapter, true, 7); | ||
7283 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7284 | } | ||
7285 | } else { | ||
7286 | if (maxInterval == 1) { | ||
7287 | btdm_2AntPsTdma(padapter, true, 3); | ||
7288 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7289 | } else if (maxInterval == 2) { | ||
7290 | btdm_2AntPsTdma(padapter, true, 3); | ||
7291 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7292 | } else if (maxInterval == 3) { | ||
7293 | btdm_2AntPsTdma(padapter, true, 3); | ||
7294 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7295 | } else { | ||
7296 | btdm_2AntPsTdma(padapter, true, 3); | ||
7297 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7298 | } | ||
7299 | } | ||
7300 | } | ||
7301 | up = 0; | ||
7302 | dn = 0; | ||
7303 | m = 1; | ||
7304 | n = 3; | ||
7305 | result = 0; | ||
7306 | WaitCount = 0; | ||
7307 | } else { | ||
7308 | /* accquire the BT TRx retry count from BT_Info byte2 */ | ||
7309 | retryCount = pHalData->bt_coexist.halCoex8723.btRetryCnt; | ||
7310 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], retryCount = %d\n", retryCount)); | ||
7311 | result = 0; | ||
7312 | WaitCount++; | ||
7313 | |||
7314 | if (retryCount == 0) { /* no retry in the last 2-second duration */ | ||
7315 | up++; | ||
7316 | dn--; | ||
7317 | |||
7318 | if (dn <= 0) | ||
7319 | dn = 0; | ||
7320 | |||
7321 | if (up >= n) { /* if ³sÄò n Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration */ | ||
7322 | WaitCount = 0; | ||
7323 | n = 3; | ||
7324 | up = 0; | ||
7325 | dn = 0; | ||
7326 | result = 1; | ||
7327 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Increase wifi duration!!\n")); | ||
7328 | } | ||
7329 | } else if (retryCount <= 3) { /* <= 3 retry in the last 2-second duration */ | ||
7330 | up--; | ||
7331 | dn++; | ||
7332 | |||
7333 | if (up <= 0) | ||
7334 | up = 0; | ||
7335 | |||
7336 | if (dn == 2) { /* if ³sÄò 2 Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration */ | ||
7337 | if (WaitCount <= 2) | ||
7338 | m++; /* Á×§K¤@ª½¦b¨âÓlevel¤¤¨Ó¦^ */ | ||
7339 | else | ||
7340 | m = 1; | ||
7341 | |||
7342 | if (m >= 20) /* m ³Ì¤jÈ = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. */ | ||
7343 | m = 20; | ||
7344 | |||
7345 | n = 3*m; | ||
7346 | up = 0; | ||
7347 | dn = 0; | ||
7348 | WaitCount = 0; | ||
7349 | result = -1; | ||
7350 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n")); | ||
7351 | } | ||
7352 | } else { /* retry count > 3, ¥un1¦¸ retry count > 3, «h½Õ¯¶WiFi duration */ | ||
7353 | if (WaitCount == 1) | ||
7354 | m++; /* Á×§K¤@ª½¦b¨âÓlevel¤¤¨Ó¦^ */ | ||
7355 | else | ||
7356 | m = 1; | ||
7357 | |||
7358 | if (m >= 20) /* m ³Ì¤jÈ = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. */ | ||
7359 | m = 20; | ||
7360 | n = 3*m; | ||
7361 | up = 0; | ||
7362 | dn = 0; | ||
7363 | WaitCount = 0; | ||
7364 | result = -1; | ||
7365 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n")); | ||
7366 | } | ||
7367 | |||
7368 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], max Interval = %d\n", maxInterval)); | ||
7369 | if (maxInterval == 1) { | ||
7370 | if (bTxPause) { | ||
7371 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 1\n")); | ||
7372 | if (pBtdm8723->curPsTdma == 1) { | ||
7373 | btdm_2AntPsTdma(padapter, true, 5); | ||
7374 | pBtdm8723->psTdmaDuAdjType = 5; | ||
7375 | } else if (pBtdm8723->curPsTdma == 2) { | ||
7376 | btdm_2AntPsTdma(padapter, true, 6); | ||
7377 | pBtdm8723->psTdmaDuAdjType = 6; | ||
7378 | } else if (pBtdm8723->curPsTdma == 3) { | ||
7379 | btdm_2AntPsTdma(padapter, true, 7); | ||
7380 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7381 | } else if (pBtdm8723->curPsTdma == 4) { | ||
7382 | btdm_2AntPsTdma(padapter, true, 8); | ||
7383 | pBtdm8723->psTdmaDuAdjType = 8; | ||
7384 | } | ||
7385 | if (pBtdm8723->curPsTdma == 9) { | ||
7386 | btdm_2AntPsTdma(padapter, true, 13); | ||
7387 | pBtdm8723->psTdmaDuAdjType = 13; | ||
7388 | } else if (pBtdm8723->curPsTdma == 10) { | ||
7389 | btdm_2AntPsTdma(padapter, true, 14); | ||
7390 | pBtdm8723->psTdmaDuAdjType = 14; | ||
7391 | } else if (pBtdm8723->curPsTdma == 11) { | ||
7392 | btdm_2AntPsTdma(padapter, true, 15); | ||
7393 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7394 | } else if (pBtdm8723->curPsTdma == 12) { | ||
7395 | btdm_2AntPsTdma(padapter, true, 16); | ||
7396 | pBtdm8723->psTdmaDuAdjType = 16; | ||
7397 | } | ||
7398 | |||
7399 | if (result == -1) { | ||
7400 | if (pBtdm8723->curPsTdma == 5) { | ||
7401 | btdm_2AntPsTdma(padapter, true, 6); | ||
7402 | pBtdm8723->psTdmaDuAdjType = 6; | ||
7403 | } else if (pBtdm8723->curPsTdma == 6) { | ||
7404 | btdm_2AntPsTdma(padapter, true, 7); | ||
7405 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7406 | } else if (pBtdm8723->curPsTdma == 7) { | ||
7407 | btdm_2AntPsTdma(padapter, true, 8); | ||
7408 | pBtdm8723->psTdmaDuAdjType = 8; | ||
7409 | } else if (pBtdm8723->curPsTdma == 13) { | ||
7410 | btdm_2AntPsTdma(padapter, true, 14); | ||
7411 | pBtdm8723->psTdmaDuAdjType = 14; | ||
7412 | } else if (pBtdm8723->curPsTdma == 14) { | ||
7413 | btdm_2AntPsTdma(padapter, true, 15); | ||
7414 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7415 | } else if (pBtdm8723->curPsTdma == 15) { | ||
7416 | btdm_2AntPsTdma(padapter, true, 16); | ||
7417 | pBtdm8723->psTdmaDuAdjType = 16; | ||
7418 | } | ||
7419 | } else if (result == 1) { | ||
7420 | if (pBtdm8723->curPsTdma == 8) { | ||
7421 | btdm_2AntPsTdma(padapter, true, 7); | ||
7422 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7423 | } else if (pBtdm8723->curPsTdma == 7) { | ||
7424 | btdm_2AntPsTdma(padapter, true, 6); | ||
7425 | pBtdm8723->psTdmaDuAdjType = 6; | ||
7426 | } else if (pBtdm8723->curPsTdma == 6) { | ||
7427 | btdm_2AntPsTdma(padapter, true, 5); | ||
7428 | pBtdm8723->psTdmaDuAdjType = 5; | ||
7429 | } else if (pBtdm8723->curPsTdma == 16) { | ||
7430 | btdm_2AntPsTdma(padapter, true, 15); | ||
7431 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7432 | } else if (pBtdm8723->curPsTdma == 15) { | ||
7433 | btdm_2AntPsTdma(padapter, true, 14); | ||
7434 | pBtdm8723->psTdmaDuAdjType = 14; | ||
7435 | } else if (pBtdm8723->curPsTdma == 14) { | ||
7436 | btdm_2AntPsTdma(padapter, true, 13); | ||
7437 | pBtdm8723->psTdmaDuAdjType = 13; | ||
7438 | } | ||
7439 | } | ||
7440 | } else { | ||
7441 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 0\n")); | ||
7442 | if (pBtdm8723->curPsTdma == 5) { | ||
7443 | btdm_2AntPsTdma(padapter, true, 1); | ||
7444 | pBtdm8723->psTdmaDuAdjType = 1; | ||
7445 | } else if (pBtdm8723->curPsTdma == 6) { | ||
7446 | btdm_2AntPsTdma(padapter, true, 2); | ||
7447 | pBtdm8723->psTdmaDuAdjType = 2; | ||
7448 | } else if (pBtdm8723->curPsTdma == 7) { | ||
7449 | btdm_2AntPsTdma(padapter, true, 3); | ||
7450 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7451 | } else if (pBtdm8723->curPsTdma == 8) { | ||
7452 | btdm_2AntPsTdma(padapter, true, 4); | ||
7453 | pBtdm8723->psTdmaDuAdjType = 4; | ||
7454 | } | ||
7455 | if (pBtdm8723->curPsTdma == 13) { | ||
7456 | btdm_2AntPsTdma(padapter, true, 9); | ||
7457 | pBtdm8723->psTdmaDuAdjType = 9; | ||
7458 | } else if (pBtdm8723->curPsTdma == 14) { | ||
7459 | btdm_2AntPsTdma(padapter, true, 10); | ||
7460 | pBtdm8723->psTdmaDuAdjType = 10; | ||
7461 | } else if (pBtdm8723->curPsTdma == 15) { | ||
7462 | btdm_2AntPsTdma(padapter, true, 11); | ||
7463 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7464 | } else if (pBtdm8723->curPsTdma == 16) { | ||
7465 | btdm_2AntPsTdma(padapter, true, 12); | ||
7466 | pBtdm8723->psTdmaDuAdjType = 12; | ||
7467 | } | ||
7468 | |||
7469 | if (result == -1) { | ||
7470 | if (pBtdm8723->curPsTdma == 1) { | ||
7471 | btdm_2AntPsTdma(padapter, true, 2); | ||
7472 | pBtdm8723->psTdmaDuAdjType = 2; | ||
7473 | } else if (pBtdm8723->curPsTdma == 2) { | ||
7474 | btdm_2AntPsTdma(padapter, true, 3); | ||
7475 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7476 | } else if (pBtdm8723->curPsTdma == 3) { | ||
7477 | btdm_2AntPsTdma(padapter, true, 4); | ||
7478 | pBtdm8723->psTdmaDuAdjType = 4; | ||
7479 | } else if (pBtdm8723->curPsTdma == 9) { | ||
7480 | btdm_2AntPsTdma(padapter, true, 10); | ||
7481 | pBtdm8723->psTdmaDuAdjType = 10; | ||
7482 | } else if (pBtdm8723->curPsTdma == 10) { | ||
7483 | btdm_2AntPsTdma(padapter, true, 11); | ||
7484 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7485 | } else if (pBtdm8723->curPsTdma == 11) { | ||
7486 | btdm_2AntPsTdma(padapter, true, 12); | ||
7487 | pBtdm8723->psTdmaDuAdjType = 12; | ||
7488 | } | ||
7489 | } else if (result == 1) { | ||
7490 | if (pBtdm8723->curPsTdma == 4) { | ||
7491 | btdm_2AntPsTdma(padapter, true, 3); | ||
7492 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7493 | } else if (pBtdm8723->curPsTdma == 3) { | ||
7494 | btdm_2AntPsTdma(padapter, true, 2); | ||
7495 | pBtdm8723->psTdmaDuAdjType = 2; | ||
7496 | } else if (pBtdm8723->curPsTdma == 2) { | ||
7497 | btdm_2AntPsTdma(padapter, true, 1); | ||
7498 | pBtdm8723->psTdmaDuAdjType = 1; | ||
7499 | } else if (pBtdm8723->curPsTdma == 12) { | ||
7500 | btdm_2AntPsTdma(padapter, true, 11); | ||
7501 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7502 | } else if (pBtdm8723->curPsTdma == 11) { | ||
7503 | btdm_2AntPsTdma(padapter, true, 10); | ||
7504 | pBtdm8723->psTdmaDuAdjType = 10; | ||
7505 | } else if (pBtdm8723->curPsTdma == 10) { | ||
7506 | btdm_2AntPsTdma(padapter, true, 9); | ||
7507 | pBtdm8723->psTdmaDuAdjType = 9; | ||
7508 | } | ||
7509 | } | ||
7510 | } | ||
7511 | } else if (maxInterval == 2) { | ||
7512 | if (bTxPause) { | ||
7513 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 1\n")); | ||
7514 | if (pBtdm8723->curPsTdma == 1) { | ||
7515 | btdm_2AntPsTdma(padapter, true, 6); | ||
7516 | pBtdm8723->psTdmaDuAdjType = 6; | ||
7517 | } else if (pBtdm8723->curPsTdma == 2) { | ||
7518 | btdm_2AntPsTdma(padapter, true, 6); | ||
7519 | pBtdm8723->psTdmaDuAdjType = 6; | ||
7520 | } else if (pBtdm8723->curPsTdma == 3) { | ||
7521 | btdm_2AntPsTdma(padapter, true, 7); | ||
7522 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7523 | } else if (pBtdm8723->curPsTdma == 4) { | ||
7524 | btdm_2AntPsTdma(padapter, true, 8); | ||
7525 | pBtdm8723->psTdmaDuAdjType = 8; | ||
7526 | } | ||
7527 | if (pBtdm8723->curPsTdma == 9) { | ||
7528 | btdm_2AntPsTdma(padapter, true, 14); | ||
7529 | pBtdm8723->psTdmaDuAdjType = 14; | ||
7530 | } else if (pBtdm8723->curPsTdma == 10) { | ||
7531 | btdm_2AntPsTdma(padapter, true, 14); | ||
7532 | pBtdm8723->psTdmaDuAdjType = 14; | ||
7533 | } else if (pBtdm8723->curPsTdma == 11) { | ||
7534 | btdm_2AntPsTdma(padapter, true, 15); | ||
7535 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7536 | } else if (pBtdm8723->curPsTdma == 12) { | ||
7537 | btdm_2AntPsTdma(padapter, true, 16); | ||
7538 | pBtdm8723->psTdmaDuAdjType = 16; | ||
7539 | } | ||
7540 | if (result == -1) { | ||
7541 | if (pBtdm8723->curPsTdma == 5) { | ||
7542 | btdm_2AntPsTdma(padapter, true, 6); | ||
7543 | pBtdm8723->psTdmaDuAdjType = 6; | ||
7544 | } else if (pBtdm8723->curPsTdma == 6) { | ||
7545 | btdm_2AntPsTdma(padapter, true, 7); | ||
7546 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7547 | } else if (pBtdm8723->curPsTdma == 7) { | ||
7548 | btdm_2AntPsTdma(padapter, true, 8); | ||
7549 | pBtdm8723->psTdmaDuAdjType = 8; | ||
7550 | } else if (pBtdm8723->curPsTdma == 13) { | ||
7551 | btdm_2AntPsTdma(padapter, true, 14); | ||
7552 | pBtdm8723->psTdmaDuAdjType = 14; | ||
7553 | } else if (pBtdm8723->curPsTdma == 14) { | ||
7554 | btdm_2AntPsTdma(padapter, true, 15); | ||
7555 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7556 | } else if (pBtdm8723->curPsTdma == 15) { | ||
7557 | btdm_2AntPsTdma(padapter, true, 16); | ||
7558 | pBtdm8723->psTdmaDuAdjType = 16; | ||
7559 | } | ||
7560 | } else if (result == 1) { | ||
7561 | if (pBtdm8723->curPsTdma == 8) { | ||
7562 | btdm_2AntPsTdma(padapter, true, 7); | ||
7563 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7564 | } else if (pBtdm8723->curPsTdma == 7) { | ||
7565 | btdm_2AntPsTdma(padapter, true, 6); | ||
7566 | pBtdm8723->psTdmaDuAdjType = 6; | ||
7567 | } else if (pBtdm8723->curPsTdma == 6) { | ||
7568 | btdm_2AntPsTdma(padapter, true, 6); | ||
7569 | pBtdm8723->psTdmaDuAdjType = 6; | ||
7570 | } else if (pBtdm8723->curPsTdma == 16) { | ||
7571 | btdm_2AntPsTdma(padapter, true, 15); | ||
7572 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7573 | } else if (pBtdm8723->curPsTdma == 15) { | ||
7574 | btdm_2AntPsTdma(padapter, true, 14); | ||
7575 | pBtdm8723->psTdmaDuAdjType = 14; | ||
7576 | } else if (pBtdm8723->curPsTdma == 14) { | ||
7577 | btdm_2AntPsTdma(padapter, true, 14); | ||
7578 | pBtdm8723->psTdmaDuAdjType = 14; | ||
7579 | } | ||
7580 | } | ||
7581 | } else { | ||
7582 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 0\n")); | ||
7583 | if (pBtdm8723->curPsTdma == 5) { | ||
7584 | btdm_2AntPsTdma(padapter, true, 2); | ||
7585 | pBtdm8723->psTdmaDuAdjType = 2; | ||
7586 | } else if (pBtdm8723->curPsTdma == 6) { | ||
7587 | btdm_2AntPsTdma(padapter, true, 2); | ||
7588 | pBtdm8723->psTdmaDuAdjType = 2; | ||
7589 | } else if (pBtdm8723->curPsTdma == 7) { | ||
7590 | btdm_2AntPsTdma(padapter, true, 3); | ||
7591 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7592 | } else if (pBtdm8723->curPsTdma == 8) { | ||
7593 | btdm_2AntPsTdma(padapter, true, 4); | ||
7594 | pBtdm8723->psTdmaDuAdjType = 4; | ||
7595 | } | ||
7596 | if (pBtdm8723->curPsTdma == 13) { | ||
7597 | btdm_2AntPsTdma(padapter, true, 10); | ||
7598 | pBtdm8723->psTdmaDuAdjType = 10; | ||
7599 | } else if (pBtdm8723->curPsTdma == 14) { | ||
7600 | btdm_2AntPsTdma(padapter, true, 10); | ||
7601 | pBtdm8723->psTdmaDuAdjType = 10; | ||
7602 | } else if (pBtdm8723->curPsTdma == 15) { | ||
7603 | btdm_2AntPsTdma(padapter, true, 11); | ||
7604 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7605 | } else if (pBtdm8723->curPsTdma == 16) { | ||
7606 | btdm_2AntPsTdma(padapter, true, 12); | ||
7607 | pBtdm8723->psTdmaDuAdjType = 12; | ||
7608 | } | ||
7609 | if (result == -1) { | ||
7610 | if (pBtdm8723->curPsTdma == 1) { | ||
7611 | btdm_2AntPsTdma(padapter, true, 2); | ||
7612 | pBtdm8723->psTdmaDuAdjType = 2; | ||
7613 | } else if (pBtdm8723->curPsTdma == 2) { | ||
7614 | btdm_2AntPsTdma(padapter, true, 3); | ||
7615 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7616 | } else if (pBtdm8723->curPsTdma == 3) { | ||
7617 | btdm_2AntPsTdma(padapter, true, 4); | ||
7618 | pBtdm8723->psTdmaDuAdjType = 4; | ||
7619 | } else if (pBtdm8723->curPsTdma == 9) { | ||
7620 | btdm_2AntPsTdma(padapter, true, 10); | ||
7621 | pBtdm8723->psTdmaDuAdjType = 10; | ||
7622 | } else if (pBtdm8723->curPsTdma == 10) { | ||
7623 | btdm_2AntPsTdma(padapter, true, 11); | ||
7624 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7625 | } else if (pBtdm8723->curPsTdma == 11) { | ||
7626 | btdm_2AntPsTdma(padapter, true, 12); | ||
7627 | pBtdm8723->psTdmaDuAdjType = 12; | ||
7628 | } | ||
7629 | } else if (result == 1) { | ||
7630 | if (pBtdm8723->curPsTdma == 4) { | ||
7631 | btdm_2AntPsTdma(padapter, true, 3); | ||
7632 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7633 | } else if (pBtdm8723->curPsTdma == 3) { | ||
7634 | btdm_2AntPsTdma(padapter, true, 2); | ||
7635 | pBtdm8723->psTdmaDuAdjType = 2; | ||
7636 | } else if (pBtdm8723->curPsTdma == 2) { | ||
7637 | btdm_2AntPsTdma(padapter, true, 2); | ||
7638 | pBtdm8723->psTdmaDuAdjType = 2; | ||
7639 | } else if (pBtdm8723->curPsTdma == 12) { | ||
7640 | btdm_2AntPsTdma(padapter, true, 11); | ||
7641 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7642 | } else if (pBtdm8723->curPsTdma == 11) { | ||
7643 | btdm_2AntPsTdma(padapter, true, 10); | ||
7644 | pBtdm8723->psTdmaDuAdjType = 10; | ||
7645 | } else if (pBtdm8723->curPsTdma == 10) { | ||
7646 | btdm_2AntPsTdma(padapter, true, 10); | ||
7647 | pBtdm8723->psTdmaDuAdjType = 10; | ||
7648 | } | ||
7649 | } | ||
7650 | } | ||
7651 | } else if (maxInterval == 3) { | ||
7652 | if (bTxPause) { | ||
7653 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 1\n")); | ||
7654 | if (pBtdm8723->curPsTdma == 1) { | ||
7655 | btdm_2AntPsTdma(padapter, true, 7); | ||
7656 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7657 | } else if (pBtdm8723->curPsTdma == 2) { | ||
7658 | btdm_2AntPsTdma(padapter, true, 7); | ||
7659 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7660 | } else if (pBtdm8723->curPsTdma == 3) { | ||
7661 | btdm_2AntPsTdma(padapter, true, 7); | ||
7662 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7663 | } else if (pBtdm8723->curPsTdma == 4) { | ||
7664 | btdm_2AntPsTdma(padapter, true, 8); | ||
7665 | pBtdm8723->psTdmaDuAdjType = 8; | ||
7666 | } | ||
7667 | if (pBtdm8723->curPsTdma == 9) { | ||
7668 | btdm_2AntPsTdma(padapter, true, 15); | ||
7669 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7670 | } else if (pBtdm8723->curPsTdma == 10) { | ||
7671 | btdm_2AntPsTdma(padapter, true, 15); | ||
7672 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7673 | } else if (pBtdm8723->curPsTdma == 11) { | ||
7674 | btdm_2AntPsTdma(padapter, true, 15); | ||
7675 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7676 | } else if (pBtdm8723->curPsTdma == 12) { | ||
7677 | btdm_2AntPsTdma(padapter, true, 16); | ||
7678 | pBtdm8723->psTdmaDuAdjType = 16; | ||
7679 | } | ||
7680 | if (result == -1) { | ||
7681 | if (pBtdm8723->curPsTdma == 5) { | ||
7682 | btdm_2AntPsTdma(padapter, true, 7); | ||
7683 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7684 | } else if (pBtdm8723->curPsTdma == 6) { | ||
7685 | btdm_2AntPsTdma(padapter, true, 7); | ||
7686 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7687 | } else if (pBtdm8723->curPsTdma == 7) { | ||
7688 | btdm_2AntPsTdma(padapter, true, 8); | ||
7689 | pBtdm8723->psTdmaDuAdjType = 8; | ||
7690 | } else if (pBtdm8723->curPsTdma == 13) { | ||
7691 | btdm_2AntPsTdma(padapter, true, 15); | ||
7692 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7693 | } else if (pBtdm8723->curPsTdma == 14) { | ||
7694 | btdm_2AntPsTdma(padapter, true, 15); | ||
7695 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7696 | } else if (pBtdm8723->curPsTdma == 15) { | ||
7697 | btdm_2AntPsTdma(padapter, true, 16); | ||
7698 | pBtdm8723->psTdmaDuAdjType = 16; | ||
7699 | } | ||
7700 | } else if (result == 1) { | ||
7701 | if (pBtdm8723->curPsTdma == 8) { | ||
7702 | btdm_2AntPsTdma(padapter, true, 7); | ||
7703 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7704 | } else if (pBtdm8723->curPsTdma == 7) { | ||
7705 | btdm_2AntPsTdma(padapter, true, 7); | ||
7706 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7707 | } else if (pBtdm8723->curPsTdma == 6) { | ||
7708 | btdm_2AntPsTdma(padapter, true, 7); | ||
7709 | pBtdm8723->psTdmaDuAdjType = 7; | ||
7710 | } else if (pBtdm8723->curPsTdma == 16) { | ||
7711 | btdm_2AntPsTdma(padapter, true, 15); | ||
7712 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7713 | } else if (pBtdm8723->curPsTdma == 15) { | ||
7714 | btdm_2AntPsTdma(padapter, true, 15); | ||
7715 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7716 | } else if (pBtdm8723->curPsTdma == 14) { | ||
7717 | btdm_2AntPsTdma(padapter, true, 15); | ||
7718 | pBtdm8723->psTdmaDuAdjType = 15; | ||
7719 | } | ||
7720 | } | ||
7721 | } else { | ||
7722 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 0\n")); | ||
7723 | if (pBtdm8723->curPsTdma == 5) { | ||
7724 | btdm_2AntPsTdma(padapter, true, 3); | ||
7725 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7726 | } else if (pBtdm8723->curPsTdma == 6) { | ||
7727 | btdm_2AntPsTdma(padapter, true, 3); | ||
7728 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7729 | } else if (pBtdm8723->curPsTdma == 7) { | ||
7730 | btdm_2AntPsTdma(padapter, true, 3); | ||
7731 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7732 | } else if (pBtdm8723->curPsTdma == 8) { | ||
7733 | btdm_2AntPsTdma(padapter, true, 4); | ||
7734 | pBtdm8723->psTdmaDuAdjType = 4; | ||
7735 | } | ||
7736 | if (pBtdm8723->curPsTdma == 13) { | ||
7737 | btdm_2AntPsTdma(padapter, true, 11); | ||
7738 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7739 | } else if (pBtdm8723->curPsTdma == 14) { | ||
7740 | btdm_2AntPsTdma(padapter, true, 11); | ||
7741 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7742 | } else if (pBtdm8723->curPsTdma == 15) { | ||
7743 | btdm_2AntPsTdma(padapter, true, 11); | ||
7744 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7745 | } else if (pBtdm8723->curPsTdma == 16) { | ||
7746 | btdm_2AntPsTdma(padapter, true, 12); | ||
7747 | pBtdm8723->psTdmaDuAdjType = 12; | ||
7748 | } | ||
7749 | if (result == -1) { | ||
7750 | if (pBtdm8723->curPsTdma == 1) { | ||
7751 | btdm_2AntPsTdma(padapter, true, 3); | ||
7752 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7753 | } else if (pBtdm8723->curPsTdma == 2) { | ||
7754 | btdm_2AntPsTdma(padapter, true, 3); | ||
7755 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7756 | } else if (pBtdm8723->curPsTdma == 3) { | ||
7757 | btdm_2AntPsTdma(padapter, true, 4); | ||
7758 | pBtdm8723->psTdmaDuAdjType = 4; | ||
7759 | } else if (pBtdm8723->curPsTdma == 9) { | ||
7760 | btdm_2AntPsTdma(padapter, true, 11); | ||
7761 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7762 | } else if (pBtdm8723->curPsTdma == 10) { | ||
7763 | btdm_2AntPsTdma(padapter, true, 11); | ||
7764 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7765 | } else if (pBtdm8723->curPsTdma == 11) { | ||
7766 | btdm_2AntPsTdma(padapter, true, 12); | ||
7767 | pBtdm8723->psTdmaDuAdjType = 12; | ||
7768 | } | ||
7769 | } else if (result == 1) { | ||
7770 | if (pBtdm8723->curPsTdma == 4) { | ||
7771 | btdm_2AntPsTdma(padapter, true, 3); | ||
7772 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7773 | } else if (pBtdm8723->curPsTdma == 3) { | ||
7774 | btdm_2AntPsTdma(padapter, true, 3); | ||
7775 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7776 | } else if (pBtdm8723->curPsTdma == 2) { | ||
7777 | btdm_2AntPsTdma(padapter, true, 3); | ||
7778 | pBtdm8723->psTdmaDuAdjType = 3; | ||
7779 | } else if (pBtdm8723->curPsTdma == 12) { | ||
7780 | btdm_2AntPsTdma(padapter, true, 11); | ||
7781 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7782 | } else if (pBtdm8723->curPsTdma == 11) { | ||
7783 | btdm_2AntPsTdma(padapter, true, 11); | ||
7784 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7785 | } else if (pBtdm8723->curPsTdma == 10) { | ||
7786 | btdm_2AntPsTdma(padapter, true, 11); | ||
7787 | pBtdm8723->psTdmaDuAdjType = 11; | ||
7788 | } | ||
7789 | } | ||
7790 | } | ||
7791 | } | ||
7792 | } | ||
7793 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], PsTdma type : recordPsTdma =%d\n", pBtdm8723->psTdmaDuAdjType)); | ||
7794 | /* if current PsTdma not match with the recorded one (when scan, dhcp...), */ | ||
7795 | /* then we have to adjust it back to the previous record one. */ | ||
7796 | if (pBtdm8723->curPsTdma != pBtdm8723->psTdmaDuAdjType) { | ||
7797 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], PsTdma type dismatch!!!, curPsTdma =%d, recordPsTdma =%d\n", | ||
7798 | pBtdm8723->curPsTdma, pBtdm8723->psTdmaDuAdjType)); | ||
7799 | |||
7800 | if (!check_fwstate(&padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) | ||
7801 | btdm_2AntPsTdma(padapter, true, pBtdm8723->psTdmaDuAdjType); | ||
7802 | else | ||
7803 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n")); | ||
7804 | } | ||
7805 | } | ||
7806 | |||
7807 | /* default Action */ | ||
7808 | /* SCO only or SCO+PAN(HS) */ | ||
7809 | static void btdm_2Ant8723ASCOAction(struct rtw_adapter *padapter) | ||
7810 | { | ||
7811 | u8 btRssiState, btRssiState1; | ||
7812 | |||
7813 | if (btdm_NeedToDecBtPwr(padapter)) | ||
7814 | btdm_2AntDecBtPwr(padapter, true); | ||
7815 | else | ||
7816 | btdm_2AntDecBtPwr(padapter, false); | ||
7817 | |||
7818 | if (BTDM_IsHT40(padapter)) { | ||
7819 | RTPRINT(FBT, BT_TRACE, ("HT40\n")); | ||
7820 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
7821 | /* fw mechanism */ | ||
7822 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
7823 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
7824 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n")); | ||
7825 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
7826 | btdm_2AntPsTdma(padapter, true, 11); | ||
7827 | } else { | ||
7828 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n")); | ||
7829 | btdm_2AntPsTdma(padapter, true, 15); | ||
7830 | } | ||
7831 | |||
7832 | /* sw mechanism */ | ||
7833 | btdm_2AntAgcTable(padapter, false); | ||
7834 | btdm_2AntAdcBackOff(padapter, true); | ||
7835 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
7836 | } else { | ||
7837 | RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n")); | ||
7838 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
7839 | btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0); | ||
7840 | |||
7841 | /* fw mechanism */ | ||
7842 | if ((btRssiState1 == BT_RSSI_STATE_HIGH) || | ||
7843 | (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) { | ||
7844 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n")); | ||
7845 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
7846 | btdm_2AntPsTdma(padapter, true, 11); | ||
7847 | } else { | ||
7848 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n")); | ||
7849 | btdm_2AntPsTdma(padapter, true, 15); | ||
7850 | } | ||
7851 | |||
7852 | /* sw mechanism */ | ||
7853 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
7854 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
7855 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
7856 | btdm_2AntAgcTable(padapter, true); | ||
7857 | btdm_2AntAdcBackOff(padapter, true); | ||
7858 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
7859 | } else { | ||
7860 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
7861 | btdm_2AntAgcTable(padapter, false); | ||
7862 | btdm_2AntAdcBackOff(padapter, false); | ||
7863 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
7864 | } | ||
7865 | } | ||
7866 | } | ||
7867 | |||
7868 | static void btdm_2Ant8723AHIDAction(struct rtw_adapter *padapter) | ||
7869 | { | ||
7870 | u8 btRssiState, btRssiState1; | ||
7871 | |||
7872 | if (btdm_NeedToDecBtPwr(padapter)) | ||
7873 | btdm_2AntDecBtPwr(padapter, true); | ||
7874 | else | ||
7875 | btdm_2AntDecBtPwr(padapter, false); | ||
7876 | |||
7877 | if (BTDM_IsHT40(padapter)) { | ||
7878 | RTPRINT(FBT, BT_TRACE, ("HT40\n")); | ||
7879 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
7880 | /* fw mechanism */ | ||
7881 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
7882 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
7883 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n")); | ||
7884 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
7885 | btdm_2AntPsTdma(padapter, true, 9); | ||
7886 | } else { | ||
7887 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n")); | ||
7888 | btdm_2AntPsTdma(padapter, true, 13); | ||
7889 | } | ||
7890 | |||
7891 | /* sw mechanism */ | ||
7892 | btdm_2AntAgcTable(padapter, false); | ||
7893 | btdm_2AntAdcBackOff(padapter, false); | ||
7894 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
7895 | } else { | ||
7896 | RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n")); | ||
7897 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
7898 | btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0); | ||
7899 | |||
7900 | /* fw mechanism */ | ||
7901 | if ((btRssiState1 == BT_RSSI_STATE_HIGH) || | ||
7902 | (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) { | ||
7903 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n")); | ||
7904 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
7905 | btdm_2AntPsTdma(padapter, true, 9); | ||
7906 | } else { | ||
7907 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n")); | ||
7908 | btdm_2AntPsTdma(padapter, true, 13); | ||
7909 | } | ||
7910 | |||
7911 | /* sw mechanism */ | ||
7912 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
7913 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
7914 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
7915 | btdm_2AntAgcTable(padapter, true); | ||
7916 | btdm_2AntAdcBackOff(padapter, true); | ||
7917 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
7918 | } else { | ||
7919 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
7920 | btdm_2AntAgcTable(padapter, false); | ||
7921 | btdm_2AntAdcBackOff(padapter, false); | ||
7922 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
7923 | } | ||
7924 | } | ||
7925 | } | ||
7926 | |||
7927 | /* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */ | ||
7928 | static void btdm_2Ant8723AA2DPAction(struct rtw_adapter *padapter) | ||
7929 | { | ||
7930 | u8 btRssiState, btRssiState1; | ||
7931 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
7932 | u8 btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt; | ||
7933 | |||
7934 | if (btdm_NeedToDecBtPwr(padapter)) | ||
7935 | btdm_2AntDecBtPwr(padapter, true); | ||
7936 | else | ||
7937 | btdm_2AntDecBtPwr(padapter, false); | ||
7938 | |||
7939 | if (BTDM_IsHT40(padapter)) { | ||
7940 | RTPRINT(FBT, BT_TRACE, ("HT40\n")); | ||
7941 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
7942 | |||
7943 | /* fw mechanism */ | ||
7944 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
7945 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
7946 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
7947 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
7948 | |||
7949 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
7950 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
7951 | btdm_2AntTdmaDurationAdjust(padapter, false, false, 3); | ||
7952 | } else { | ||
7953 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
7954 | btdm_2AntTdmaDurationAdjust(padapter, false, false, 1); | ||
7955 | } | ||
7956 | } else { | ||
7957 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
7958 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
7959 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
7960 | btdm_2AntTdmaDurationAdjust(padapter, false, true, 3); | ||
7961 | } else { | ||
7962 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
7963 | btdm_2AntTdmaDurationAdjust(padapter, false, true, 1); | ||
7964 | } | ||
7965 | } | ||
7966 | |||
7967 | /* sw mechanism */ | ||
7968 | btdm_2AntAgcTable(padapter, false); | ||
7969 | btdm_2AntAdcBackOff(padapter, true); | ||
7970 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
7971 | } else { | ||
7972 | RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n")); | ||
7973 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
7974 | btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0); | ||
7975 | |||
7976 | /* fw mechanism */ | ||
7977 | if ((btRssiState1 == BT_RSSI_STATE_HIGH) || | ||
7978 | (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) { | ||
7979 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n")); | ||
7980 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
7981 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
7982 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
7983 | btdm_2AntTdmaDurationAdjust(padapter, false, false, 3); | ||
7984 | } else { | ||
7985 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
7986 | btdm_2AntTdmaDurationAdjust(padapter, false, false, 1); | ||
7987 | } | ||
7988 | } else { | ||
7989 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n")); | ||
7990 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
7991 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
7992 | btdm_2AntTdmaDurationAdjust(padapter, false, true, 3); | ||
7993 | } else { | ||
7994 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
7995 | btdm_2AntTdmaDurationAdjust(padapter, false, true, 1); | ||
7996 | } | ||
7997 | } | ||
7998 | |||
7999 | /* sw mechanism */ | ||
8000 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8001 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8002 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
8003 | btdm_2AntAgcTable(padapter, true); | ||
8004 | btdm_2AntAdcBackOff(padapter, true); | ||
8005 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8006 | } else { | ||
8007 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
8008 | btdm_2AntAgcTable(padapter, false); | ||
8009 | btdm_2AntAdcBackOff(padapter, false); | ||
8010 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8011 | } | ||
8012 | } | ||
8013 | } | ||
8014 | |||
8015 | static void btdm_2Ant8723APANEDRAction(struct rtw_adapter *padapter) | ||
8016 | { | ||
8017 | u8 btRssiState, btRssiState1; | ||
8018 | |||
8019 | if (btdm_NeedToDecBtPwr(padapter)) | ||
8020 | btdm_2AntDecBtPwr(padapter, true); | ||
8021 | else | ||
8022 | btdm_2AntDecBtPwr(padapter, false); | ||
8023 | |||
8024 | if (BTDM_IsHT40(padapter)) { | ||
8025 | RTPRINT(FBT, BT_TRACE, ("HT40\n")); | ||
8026 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
8027 | |||
8028 | /* fw mechanism */ | ||
8029 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8030 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8031 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
8032 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
8033 | btdm_2AntPsTdma(padapter, true, 2); | ||
8034 | } else { | ||
8035 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
8036 | btdm_2AntPsTdma(padapter, true, 6); | ||
8037 | } | ||
8038 | |||
8039 | /* sw mechanism */ | ||
8040 | btdm_2AntAgcTable(padapter, false); | ||
8041 | btdm_2AntAdcBackOff(padapter, true); | ||
8042 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8043 | } else { | ||
8044 | RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n")); | ||
8045 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
8046 | btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0); | ||
8047 | |||
8048 | /* fw mechanism */ | ||
8049 | if ((btRssiState1 == BT_RSSI_STATE_HIGH) || | ||
8050 | (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) { | ||
8051 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n")); | ||
8052 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
8053 | btdm_2AntPsTdma(padapter, true, 2); | ||
8054 | } else { | ||
8055 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n")); | ||
8056 | btdm_2AntPsTdma(padapter, true, 6); | ||
8057 | } | ||
8058 | |||
8059 | /* sw mechanism */ | ||
8060 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8061 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8062 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
8063 | btdm_2AntAgcTable(padapter, true); | ||
8064 | btdm_2AntAdcBackOff(padapter, true); | ||
8065 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8066 | } else { | ||
8067 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
8068 | btdm_2AntAgcTable(padapter, false); | ||
8069 | btdm_2AntAdcBackOff(padapter, false); | ||
8070 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8071 | } | ||
8072 | } | ||
8073 | } | ||
8074 | |||
8075 | /* PAN(HS) only */ | ||
8076 | static void btdm_2Ant8723APANHSAction(struct rtw_adapter *padapter) | ||
8077 | { | ||
8078 | u8 btRssiState; | ||
8079 | |||
8080 | if (BTDM_IsHT40(padapter)) { | ||
8081 | RTPRINT(FBT, BT_TRACE, ("HT40\n")); | ||
8082 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 47, 0); | ||
8083 | /* fw mechanism */ | ||
8084 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8085 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8086 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
8087 | btdm_2AntDecBtPwr(padapter, true); | ||
8088 | } else { | ||
8089 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
8090 | btdm_2AntDecBtPwr(padapter, false); | ||
8091 | } | ||
8092 | btdm_2AntPsTdma(padapter, false, 0); | ||
8093 | |||
8094 | /* sw mechanism */ | ||
8095 | btdm_2AntAgcTable(padapter, false); | ||
8096 | btdm_2AntAdcBackOff(padapter, true); | ||
8097 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8098 | } else { | ||
8099 | RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n")); | ||
8100 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 47, 0); | ||
8101 | |||
8102 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8103 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8104 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high\n")); | ||
8105 | /* fw mechanism */ | ||
8106 | btdm_2AntDecBtPwr(padapter, true); | ||
8107 | btdm_2AntPsTdma(padapter, false, 0); | ||
8108 | |||
8109 | /* sw mechanism */ | ||
8110 | btdm_2AntAgcTable(padapter, true); | ||
8111 | btdm_2AntAdcBackOff(padapter, true); | ||
8112 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8113 | } else { | ||
8114 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low\n")); | ||
8115 | /* fw mechanism */ | ||
8116 | btdm_2AntDecBtPwr(padapter, false); | ||
8117 | btdm_2AntPsTdma(padapter, false, 0); | ||
8118 | |||
8119 | /* sw mechanism */ | ||
8120 | btdm_2AntAgcTable(padapter, false); | ||
8121 | btdm_2AntAdcBackOff(padapter, false); | ||
8122 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8123 | } | ||
8124 | } | ||
8125 | } | ||
8126 | |||
8127 | /* PAN(EDR)+A2DP */ | ||
8128 | static void btdm_2Ant8723APANEDRA2DPAction(struct rtw_adapter *padapter) | ||
8129 | { | ||
8130 | u8 btRssiState, btRssiState1, btInfoExt; | ||
8131 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
8132 | |||
8133 | btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt; | ||
8134 | |||
8135 | if (btdm_NeedToDecBtPwr(padapter)) | ||
8136 | btdm_2AntDecBtPwr(padapter, true); | ||
8137 | else | ||
8138 | btdm_2AntDecBtPwr(padapter, false); | ||
8139 | |||
8140 | if (BTDM_IsHT40(padapter)) { | ||
8141 | RTPRINT(FBT, BT_TRACE, ("HT40\n")); | ||
8142 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
8143 | |||
8144 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8145 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8146 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
8147 | /* fw mechanism */ | ||
8148 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
8149 | |||
8150 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
8151 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
8152 | btdm_2AntPsTdma(padapter, true, 4); | ||
8153 | } else { | ||
8154 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
8155 | btdm_2AntPsTdma(padapter, true, 2); | ||
8156 | } | ||
8157 | } else { | ||
8158 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
8159 | /* fw mechanism */ | ||
8160 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
8161 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
8162 | btdm_2AntPsTdma(padapter, true, 8); | ||
8163 | } else { | ||
8164 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
8165 | btdm_2AntPsTdma(padapter, true, 6); | ||
8166 | } | ||
8167 | } | ||
8168 | |||
8169 | /* sw mechanism */ | ||
8170 | btdm_2AntAgcTable(padapter, false); | ||
8171 | btdm_2AntAdcBackOff(padapter, true); | ||
8172 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8173 | } else { | ||
8174 | RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n")); | ||
8175 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
8176 | btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0); | ||
8177 | |||
8178 | if ((btRssiState1 == BT_RSSI_STATE_HIGH) || | ||
8179 | (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) { | ||
8180 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n")); | ||
8181 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
8182 | /* fw mechanism */ | ||
8183 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
8184 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
8185 | btdm_2AntPsTdma(padapter, true, 4); | ||
8186 | } else { | ||
8187 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
8188 | btdm_2AntPsTdma(padapter, true, 2); | ||
8189 | } | ||
8190 | } else { | ||
8191 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n")); | ||
8192 | /* fw mechanism */ | ||
8193 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
8194 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
8195 | btdm_2AntPsTdma(padapter, true, 8); | ||
8196 | } else { | ||
8197 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
8198 | btdm_2AntPsTdma(padapter, true, 6); | ||
8199 | } | ||
8200 | } | ||
8201 | |||
8202 | /* sw mechanism */ | ||
8203 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8204 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8205 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
8206 | btdm_2AntAgcTable(padapter, true); | ||
8207 | btdm_2AntAdcBackOff(padapter, true); | ||
8208 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8209 | } else { | ||
8210 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
8211 | btdm_2AntAgcTable(padapter, false); | ||
8212 | btdm_2AntAdcBackOff(padapter, false); | ||
8213 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8214 | } | ||
8215 | } | ||
8216 | } | ||
8217 | |||
8218 | static void btdm_2Ant8723APANEDRHIDAction(struct rtw_adapter *padapter) | ||
8219 | { | ||
8220 | u8 btRssiState, btRssiState1; | ||
8221 | |||
8222 | if (btdm_NeedToDecBtPwr(padapter)) | ||
8223 | btdm_2AntDecBtPwr(padapter, true); | ||
8224 | else | ||
8225 | btdm_2AntDecBtPwr(padapter, false); | ||
8226 | |||
8227 | if (BTDM_IsHT40(padapter)) { | ||
8228 | RTPRINT(FBT, BT_TRACE, ("HT40\n")); | ||
8229 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
8230 | /* fw mechanism */ | ||
8231 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8232 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8233 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
8234 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
8235 | btdm_2AntPsTdma(padapter, true, 10); | ||
8236 | } else { | ||
8237 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
8238 | btdm_2AntPsTdma(padapter, true, 14); | ||
8239 | } | ||
8240 | |||
8241 | /* sw mechanism */ | ||
8242 | btdm_2AntAgcTable(padapter, false); | ||
8243 | btdm_2AntAdcBackOff(padapter, true); | ||
8244 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8245 | } else { | ||
8246 | RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n")); | ||
8247 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
8248 | btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0); | ||
8249 | |||
8250 | /* fw mechanism */ | ||
8251 | if ((btRssiState1 == BT_RSSI_STATE_HIGH) || | ||
8252 | (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) { | ||
8253 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n")); | ||
8254 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
8255 | btdm_2AntPsTdma(padapter, true, 10); | ||
8256 | } else { | ||
8257 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n")); | ||
8258 | btdm_2AntPsTdma(padapter, true, 14); | ||
8259 | } | ||
8260 | |||
8261 | /* sw mechanism */ | ||
8262 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8263 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8264 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
8265 | btdm_2AntAgcTable(padapter, true); | ||
8266 | btdm_2AntAdcBackOff(padapter, true); | ||
8267 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8268 | } else { | ||
8269 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
8270 | btdm_2AntAgcTable(padapter, false); | ||
8271 | btdm_2AntAdcBackOff(padapter, false); | ||
8272 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8273 | } | ||
8274 | } | ||
8275 | } | ||
8276 | |||
8277 | /* HID+A2DP+PAN(EDR) */ | ||
8278 | static void btdm_2Ant8723AHIDA2DPPANEDRAction(struct rtw_adapter *padapter) | ||
8279 | { | ||
8280 | u8 btRssiState, btRssiState1, btInfoExt; | ||
8281 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
8282 | |||
8283 | btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt; | ||
8284 | |||
8285 | if (btdm_NeedToDecBtPwr(padapter)) | ||
8286 | btdm_2AntDecBtPwr(padapter, true); | ||
8287 | else | ||
8288 | btdm_2AntDecBtPwr(padapter, false); | ||
8289 | |||
8290 | if (BTDM_IsHT40(padapter)) { | ||
8291 | RTPRINT(FBT, BT_TRACE, ("HT40\n")); | ||
8292 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
8293 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8294 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8295 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
8296 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
8297 | |||
8298 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
8299 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
8300 | btdm_2AntPsTdma(padapter, true, 12); | ||
8301 | } else { | ||
8302 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
8303 | btdm_2AntPsTdma(padapter, true, 10); | ||
8304 | } | ||
8305 | } else { | ||
8306 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
8307 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
8308 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
8309 | btdm_2AntPsTdma(padapter, true, 16); | ||
8310 | } else { | ||
8311 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
8312 | btdm_2AntPsTdma(padapter, true, 14); | ||
8313 | } | ||
8314 | } | ||
8315 | |||
8316 | /* sw mechanism */ | ||
8317 | btdm_2AntAgcTable(padapter, false); | ||
8318 | btdm_2AntAdcBackOff(padapter, true); | ||
8319 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8320 | } else { | ||
8321 | RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n")); | ||
8322 | btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 37, 0); | ||
8323 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 27, 0); | ||
8324 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8325 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8326 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
8327 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
8328 | |||
8329 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
8330 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
8331 | btdm_2AntPsTdma(padapter, true, 12); | ||
8332 | } else { | ||
8333 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
8334 | btdm_2AntPsTdma(padapter, true, 10); | ||
8335 | } | ||
8336 | } else { | ||
8337 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
8338 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
8339 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
8340 | btdm_2AntPsTdma(padapter, true, 16); | ||
8341 | } else { | ||
8342 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
8343 | btdm_2AntPsTdma(padapter, true, 14); | ||
8344 | } | ||
8345 | } | ||
8346 | |||
8347 | /* sw mechanism */ | ||
8348 | if ((btRssiState1 == BT_RSSI_STATE_HIGH) || | ||
8349 | (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) { | ||
8350 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n")); | ||
8351 | btdm_2AntAgcTable(padapter, true); | ||
8352 | btdm_2AntAdcBackOff(padapter, true); | ||
8353 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8354 | } else { | ||
8355 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n")); | ||
8356 | btdm_2AntAgcTable(padapter, false); | ||
8357 | btdm_2AntAdcBackOff(padapter, false); | ||
8358 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8359 | } | ||
8360 | } | ||
8361 | } | ||
8362 | |||
8363 | static void btdm_2Ant8723AHIDA2DPAction(struct rtw_adapter *padapter) | ||
8364 | { | ||
8365 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
8366 | u8 btRssiState, btRssiState1, btInfoExt; | ||
8367 | |||
8368 | btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt; | ||
8369 | |||
8370 | if (btdm_NeedToDecBtPwr(padapter)) | ||
8371 | btdm_2AntDecBtPwr(padapter, true); | ||
8372 | else | ||
8373 | btdm_2AntDecBtPwr(padapter, false); | ||
8374 | |||
8375 | if (BTDM_IsHT40(padapter)) { | ||
8376 | RTPRINT(FBT, BT_TRACE, ("HT40\n")); | ||
8377 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
8378 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8379 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8380 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
8381 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
8382 | |||
8383 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
8384 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
8385 | btdm_2AntTdmaDurationAdjust(padapter, true, false, 3); | ||
8386 | } else { | ||
8387 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
8388 | btdm_2AntTdmaDurationAdjust(padapter, true, false, 1); | ||
8389 | } | ||
8390 | } else { | ||
8391 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
8392 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
8393 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
8394 | btdm_2AntTdmaDurationAdjust(padapter, true, true, 3); | ||
8395 | } else { | ||
8396 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
8397 | btdm_2AntTdmaDurationAdjust(padapter, true, true, 1); | ||
8398 | } | ||
8399 | } | ||
8400 | /* sw mechanism */ | ||
8401 | btdm_2AntAgcTable(padapter, false); | ||
8402 | btdm_2AntAdcBackOff(padapter, true); | ||
8403 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8404 | } else { | ||
8405 | RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n")); | ||
8406 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
8407 | btRssiState1 = BTDM_CheckCoexRSSIState(padapter, 2, 27, 0); | ||
8408 | |||
8409 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8410 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8411 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
8412 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
8413 | |||
8414 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
8415 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
8416 | btdm_2AntTdmaDurationAdjust(padapter, true, false, 3); | ||
8417 | } else { | ||
8418 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
8419 | btdm_2AntTdmaDurationAdjust(padapter, true, false, 1); | ||
8420 | } | ||
8421 | } else { | ||
8422 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
8423 | if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */ | ||
8424 | RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n")); | ||
8425 | btdm_2AntTdmaDurationAdjust(padapter, true, true, 3); | ||
8426 | } else { | ||
8427 | RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n")); | ||
8428 | btdm_2AntTdmaDurationAdjust(padapter, true, true, 1); | ||
8429 | } | ||
8430 | } | ||
8431 | if ((btRssiState1 == BT_RSSI_STATE_HIGH) || | ||
8432 | (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) { | ||
8433 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n")); | ||
8434 | /* sw mechanism */ | ||
8435 | btdm_2AntAgcTable(padapter, true); | ||
8436 | btdm_2AntAdcBackOff(padapter, true); | ||
8437 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8438 | } else { | ||
8439 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n")); | ||
8440 | /* sw mechanism */ | ||
8441 | btdm_2AntAgcTable(padapter, false); | ||
8442 | btdm_2AntAdcBackOff(padapter, false); | ||
8443 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8444 | } | ||
8445 | } | ||
8446 | } | ||
8447 | |||
8448 | static void btdm_2Ant8723AA2dp(struct rtw_adapter *padapter) | ||
8449 | { | ||
8450 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
8451 | u8 btRssiState, btRssiState1, btInfoExt; | ||
8452 | |||
8453 | btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt; | ||
8454 | |||
8455 | if (btdm_NeedToDecBtPwr(padapter)) | ||
8456 | btdm_2AntDecBtPwr(padapter, true); | ||
8457 | else | ||
8458 | btdm_2AntDecBtPwr(padapter, false); | ||
8459 | /* coex table */ | ||
8460 | btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3); | ||
8461 | btdm_2AntIgnoreWlanAct(padapter, false); | ||
8462 | |||
8463 | if (BTDM_IsHT40(padapter)) { | ||
8464 | RTPRINT(FBT, BT_TRACE, ("HT40\n")); | ||
8465 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0); | ||
8466 | /* fw mechanism */ | ||
8467 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8468 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8469 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n")); | ||
8470 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
8471 | btdm_2AntTdmaDurationAdjust(padapter, false, false, 1); | ||
8472 | } else { | ||
8473 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n")); | ||
8474 | btdm_2AntTdmaDurationAdjust(padapter, false, true, 1); | ||
8475 | } | ||
8476 | |||
8477 | /* sw mechanism */ | ||
8478 | btdm_2AntAgcTable(padapter, false); | ||
8479 | btdm_2AntAdcBackOff(padapter, true); | ||
8480 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8481 | } else { | ||
8482 | RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n")); | ||
8483 | btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 47, 0); | ||
8484 | btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0); | ||
8485 | |||
8486 | /* fw mechanism */ | ||
8487 | if ((btRssiState1 == BT_RSSI_STATE_HIGH) || | ||
8488 | (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) { | ||
8489 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n")); | ||
8490 | PlatformEFIOWrite1Byte(padapter, 0x883, 0x40); | ||
8491 | btdm_2AntTdmaDurationAdjust(padapter, false, false, 1); | ||
8492 | } else { | ||
8493 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n")); | ||
8494 | btdm_2AntTdmaDurationAdjust(padapter, false, true, 1); | ||
8495 | } | ||
8496 | |||
8497 | /* sw mechanism */ | ||
8498 | if ((btRssiState == BT_RSSI_STATE_HIGH) || | ||
8499 | (btRssiState == BT_RSSI_STATE_STAY_HIGH)) { | ||
8500 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n")); | ||
8501 | btdm_2AntAgcTable(padapter, true); | ||
8502 | btdm_2AntAdcBackOff(padapter, true); | ||
8503 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8504 | } else { | ||
8505 | RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n")); | ||
8506 | btdm_2AntAgcTable(padapter, false); | ||
8507 | btdm_2AntAdcBackOff(padapter, false); | ||
8508 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8509 | } | ||
8510 | } | ||
8511 | } | ||
8512 | |||
8513 | /* extern function start with BTDM_ */ | ||
8514 | static void BTDM_2AntParaInit(struct rtw_adapter *padapter) | ||
8515 | { | ||
8516 | |||
8517 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
8518 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
8519 | |||
8520 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], 2Ant Parameter Init!!\n")); | ||
8521 | |||
8522 | /* Enable counter statistics */ | ||
8523 | rtw_write8(padapter, 0x76e, 0x4); | ||
8524 | rtw_write8(padapter, 0x778, 0x3); | ||
8525 | rtw_write8(padapter, 0x40, 0x20); | ||
8526 | |||
8527 | /* force to reset coex mechanism */ | ||
8528 | pBtdm8723->preVal0x6c0 = 0x0; | ||
8529 | btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3); | ||
8530 | |||
8531 | pBtdm8723->bPrePsTdmaOn = true; | ||
8532 | btdm_2AntPsTdma(padapter, false, 0); | ||
8533 | |||
8534 | pBtdm8723->preFwDacSwingLvl = 0x10; | ||
8535 | btdm_2AntFwDacSwingLvl(padapter, 0x20); | ||
8536 | |||
8537 | pBtdm8723->bPreDecBtPwr = true; | ||
8538 | btdm_2AntDecBtPwr(padapter, false); | ||
8539 | |||
8540 | pBtdm8723->bPreAgcTableEn = true; | ||
8541 | btdm_2AntAgcTable(padapter, false); | ||
8542 | |||
8543 | pBtdm8723->bPreAdcBackOff = true; | ||
8544 | btdm_2AntAdcBackOff(padapter, false); | ||
8545 | |||
8546 | pBtdm8723->bPreLowPenaltyRa = true; | ||
8547 | btdm_2AntLowPenaltyRa(padapter, false); | ||
8548 | |||
8549 | pBtdm8723->bPreRfRxLpfShrink = true; | ||
8550 | btdm_2AntRfShrink(padapter, false); | ||
8551 | |||
8552 | pBtdm8723->bPreDacSwingOn = true; | ||
8553 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8554 | |||
8555 | pBtdm8723->bPreIgnoreWlanAct = true; | ||
8556 | btdm_2AntIgnoreWlanAct(padapter, false); | ||
8557 | } | ||
8558 | |||
8559 | static void BTDM_2AntHwCoexAllOff8723A(struct rtw_adapter *padapter) | ||
8560 | { | ||
8561 | btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3); | ||
8562 | } | ||
8563 | |||
8564 | static void BTDM_2AntFwCoexAllOff8723A(struct rtw_adapter *padapter) | ||
8565 | { | ||
8566 | btdm_2AntIgnoreWlanAct(padapter, false); | ||
8567 | btdm_2AntPsTdma(padapter, false, 0); | ||
8568 | btdm_2AntFwDacSwingLvl(padapter, 0x20); | ||
8569 | btdm_2AntDecBtPwr(padapter, false); | ||
8570 | } | ||
8571 | |||
8572 | static void BTDM_2AntSwCoexAllOff8723A(struct rtw_adapter *padapter) | ||
8573 | { | ||
8574 | btdm_2AntAgcTable(padapter, false); | ||
8575 | btdm_2AntAdcBackOff(padapter, false); | ||
8576 | btdm_2AntLowPenaltyRa(padapter, false); | ||
8577 | btdm_2AntRfShrink(padapter, false); | ||
8578 | btdm_2AntDacSwing(padapter, false, 0xc0); | ||
8579 | } | ||
8580 | |||
8581 | static void BTDM_2AntFwC2hBtInfo8723A(struct rtw_adapter *padapter) | ||
8582 | { | ||
8583 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
8584 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
8585 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
8586 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
8587 | u8 btInfo = 0; | ||
8588 | u8 algorithm = BT_2ANT_COEX_ALGO_UNDEFINED; | ||
8589 | u8 bBtLinkExist = false, bBtHsModeExist = false; | ||
8590 | |||
8591 | btInfo = pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal; | ||
8592 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_IDLE; | ||
8593 | |||
8594 | /* check BIT2 first ==> check if bt is under inquiry or page scan */ | ||
8595 | if (btInfo & BIT(2)) { | ||
8596 | if (!pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage) { | ||
8597 | pBtMgnt->ExtConfig.bHoldForBtOperation = true; | ||
8598 | pBtMgnt->ExtConfig.bHoldPeriodCnt = 1; | ||
8599 | btdm_2AntBtInquiryPage(padapter); | ||
8600 | } else { | ||
8601 | pBtMgnt->ExtConfig.bHoldPeriodCnt++; | ||
8602 | btdm_HoldForBtInqPage(padapter); | ||
8603 | } | ||
8604 | pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage = true; | ||
8605 | |||
8606 | } else { | ||
8607 | pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage = false; | ||
8608 | pBtMgnt->ExtConfig.bHoldForBtOperation = false; | ||
8609 | pBtMgnt->ExtConfig.bHoldPeriodCnt = 0; | ||
8610 | |||
8611 | } | ||
8612 | RTPRINT(FBT, BT_TRACE, | ||
8613 | ("[BTC2H], pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage =%x pBtMgnt->ExtConfig.bHoldPeriodCnt =%x pBtMgnt->ExtConfig.bHoldForBtOperation =%x\n", | ||
8614 | pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage, | ||
8615 | pBtMgnt->ExtConfig.bHoldPeriodCnt, | ||
8616 | pBtMgnt->ExtConfig.bHoldForBtOperation)); | ||
8617 | |||
8618 | RTPRINT(FBT, BT_TRACE, | ||
8619 | ("[BTC2H], btInfo =%x pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal =%x\n", | ||
8620 | btInfo, pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal)); | ||
8621 | if (btInfo&BT_INFO_ACL) { | ||
8622 | RTPRINT(FBT, BT_TRACE, ("[BTC2H], BTInfo: bConnect = true btInfo =%x\n", btInfo)); | ||
8623 | bBtLinkExist = true; | ||
8624 | if (((btInfo&(BT_INFO_FTP|BT_INFO_A2DP|BT_INFO_HID|BT_INFO_SCO_BUSY)) != 0) || | ||
8625 | pHalData->bt_coexist.halCoex8723.btRetryCnt > 0) { | ||
8626 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE; | ||
8627 | } else { | ||
8628 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE; | ||
8629 | } | ||
8630 | |||
8631 | if (btInfo&BT_INFO_SCO || btInfo&BT_INFO_SCO_BUSY) { | ||
8632 | if (btInfo&BT_INFO_FTP || btInfo&BT_INFO_A2DP || btInfo&BT_INFO_HID) { | ||
8633 | switch (btInfo&0xe0) { | ||
8634 | case BT_INFO_HID: | ||
8635 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID\n")); | ||
8636 | algorithm = BT_2ANT_COEX_ALGO_HID; | ||
8637 | break; | ||
8638 | case BT_INFO_A2DP: | ||
8639 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP\n")); | ||
8640 | break; | ||
8641 | case BT_INFO_FTP: | ||
8642 | if (bBtHsModeExist) { | ||
8643 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(HS)\n")); | ||
8644 | algorithm = BT_2ANT_COEX_ALGO_SCO; | ||
8645 | } else { | ||
8646 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(EDR)\n")); | ||
8647 | algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID; | ||
8648 | } | ||
8649 | break; | ||
8650 | case (BT_INFO_HID | BT_INFO_A2DP): | ||
8651 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP\n")); | ||
8652 | algorithm = BT_2ANT_COEX_ALGO_HID_A2DP; | ||
8653 | break; | ||
8654 | case (BT_INFO_HID | BT_INFO_FTP): | ||
8655 | if (bBtHsModeExist) { | ||
8656 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(HS)\n")); | ||
8657 | algorithm = BT_2ANT_COEX_ALGO_HID_A2DP; | ||
8658 | } else { | ||
8659 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(EDR)\n")); | ||
8660 | algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID; | ||
8661 | } | ||
8662 | break; | ||
8663 | case (BT_INFO_A2DP | BT_INFO_FTP): | ||
8664 | if (bBtHsModeExist) { | ||
8665 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(HS)\n")); | ||
8666 | algorithm = BT_2ANT_COEX_ALGO_A2DP; | ||
8667 | } else { | ||
8668 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n")); | ||
8669 | algorithm = BT_2ANT_COEX_ALGO_PANEDR_A2DP; | ||
8670 | } | ||
8671 | break; | ||
8672 | case (BT_INFO_HID | BT_INFO_A2DP | BT_INFO_FTP): | ||
8673 | if (bBtHsModeExist) { | ||
8674 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n")); | ||
8675 | algorithm = BT_2ANT_COEX_ALGO_HID_A2DP; | ||
8676 | } else { | ||
8677 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n")); | ||
8678 | algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR; | ||
8679 | } | ||
8680 | break; | ||
8681 | } | ||
8682 | } else { | ||
8683 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO only\n")); | ||
8684 | algorithm = BT_2ANT_COEX_ALGO_SCO; | ||
8685 | } | ||
8686 | } else { | ||
8687 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], non SCO\n")); | ||
8688 | switch (btInfo&0xe0) { | ||
8689 | case BT_INFO_HID: | ||
8690 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID\n")); | ||
8691 | algorithm = BT_2ANT_COEX_ALGO_HID; | ||
8692 | break; | ||
8693 | case BT_INFO_A2DP: | ||
8694 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP\n")); | ||
8695 | algorithm = BT_2ANT_COEX_ALGO_A2DP; | ||
8696 | break; | ||
8697 | case BT_INFO_FTP: | ||
8698 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN(EDR)\n")); | ||
8699 | algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID; | ||
8700 | break; | ||
8701 | case (BT_INFO_HID | BT_INFO_A2DP): | ||
8702 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP\n")); | ||
8703 | algorithm = BT_2ANT_COEX_ALGO_HID_A2DP; | ||
8704 | break; | ||
8705 | case (BT_INFO_HID|BT_INFO_FTP): | ||
8706 | if (bBtHsModeExist) { | ||
8707 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(HS)\n")); | ||
8708 | algorithm = BT_2ANT_COEX_ALGO_HID_A2DP; | ||
8709 | } else { | ||
8710 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(EDR)\n")); | ||
8711 | algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID; | ||
8712 | } | ||
8713 | break; | ||
8714 | case (BT_INFO_A2DP|BT_INFO_FTP): | ||
8715 | if (bBtHsModeExist) { | ||
8716 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(HS)\n")); | ||
8717 | algorithm = BT_2ANT_COEX_ALGO_A2DP; | ||
8718 | } else { | ||
8719 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n")); | ||
8720 | algorithm = BT_2ANT_COEX_ALGO_PANEDR_A2DP; | ||
8721 | } | ||
8722 | break; | ||
8723 | case (BT_INFO_HID|BT_INFO_A2DP|BT_INFO_FTP): | ||
8724 | if (bBtHsModeExist) { | ||
8725 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n")); | ||
8726 | algorithm = BT_2ANT_COEX_ALGO_HID_A2DP; | ||
8727 | } else { | ||
8728 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n")); | ||
8729 | algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR; | ||
8730 | } | ||
8731 | break; | ||
8732 | } | ||
8733 | |||
8734 | } | ||
8735 | } else { | ||
8736 | RTPRINT(FBT, BT_TRACE, ("[BTC2H], BTInfo: bConnect = false\n")); | ||
8737 | pBtdm8723->btStatus = BT_2ANT_BT_STATUS_IDLE; | ||
8738 | } | ||
8739 | |||
8740 | pBtdm8723->curAlgorithm = algorithm; | ||
8741 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Algorithm = %d \n", pBtdm8723->curAlgorithm)); | ||
8742 | |||
8743 | /* From */ | ||
8744 | BTDM_CheckWiFiState(padapter); | ||
8745 | if (pBtMgnt->ExtConfig.bManualControl) { | ||
8746 | RTPRINT(FBT, BT_TRACE, ("Action Manual control, won't execute bt coexist mechanism!!\n")); | ||
8747 | return; | ||
8748 | } | ||
8749 | } | ||
8750 | |||
8751 | void BTDM_2AntBtCoexist8723A(struct rtw_adapter *padapter) | ||
8752 | { | ||
8753 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
8754 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
8755 | struct bt_dgb *pBtDbg = &pBTInfo->BtDbg; | ||
8756 | u8 btInfoOriginal = 0; | ||
8757 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
8758 | struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant; | ||
8759 | |||
8760 | if (BTDM_BtProfileSupport(padapter)) { | ||
8761 | if (pBtMgnt->ExtConfig.bHoldForBtOperation) { | ||
8762 | RTPRINT(FBT, BT_TRACE, ("Action for BT Operation adjust!!\n")); | ||
8763 | return; | ||
8764 | } | ||
8765 | if (pBtMgnt->ExtConfig.bHoldPeriodCnt) { | ||
8766 | RTPRINT(FBT, BT_TRACE, ("Hold BT inquiry/page scan setting (cnt = %d)!!\n", | ||
8767 | pBtMgnt->ExtConfig.bHoldPeriodCnt)); | ||
8768 | if (pBtMgnt->ExtConfig.bHoldPeriodCnt >= 11) { | ||
8769 | pBtMgnt->ExtConfig.bHoldPeriodCnt = 0; | ||
8770 | /* next time the coexist parameters should be reset again. */ | ||
8771 | } else { | ||
8772 | pBtMgnt->ExtConfig.bHoldPeriodCnt++; | ||
8773 | } | ||
8774 | return; | ||
8775 | } | ||
8776 | |||
8777 | if (pBtDbg->dbgCtrl) | ||
8778 | RTPRINT(FBT, BT_TRACE, ("[Dbg control], ")); | ||
8779 | |||
8780 | pBtdm8723->curAlgorithm = btdm_ActionAlgorithm(padapter); | ||
8781 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Algorithm = %d \n", pBtdm8723->curAlgorithm)); | ||
8782 | |||
8783 | if (btdm_Is2Ant8723ACommonAction(padapter)) { | ||
8784 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant common.\n")); | ||
8785 | pBtdm8723->bResetTdmaAdjust = true; | ||
8786 | } else { | ||
8787 | if (pBtdm8723->curAlgorithm != pBtdm8723->preAlgorithm) { | ||
8788 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], preAlgorithm =%d, curAlgorithm =%d\n", | ||
8789 | pBtdm8723->preAlgorithm, pBtdm8723->curAlgorithm)); | ||
8790 | pBtdm8723->bResetTdmaAdjust = true; | ||
8791 | } | ||
8792 | switch (pBtdm8723->curAlgorithm) { | ||
8793 | case BT_2ANT_COEX_ALGO_SCO: | ||
8794 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = SCO.\n")); | ||
8795 | btdm_2Ant8723ASCOAction(padapter); | ||
8796 | break; | ||
8797 | case BT_2ANT_COEX_ALGO_HID: | ||
8798 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID.\n")); | ||
8799 | btdm_2Ant8723AHIDAction(padapter); | ||
8800 | break; | ||
8801 | case BT_2ANT_COEX_ALGO_A2DP: | ||
8802 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = A2DP.\n")); | ||
8803 | btdm_2Ant8723AA2DPAction(padapter); | ||
8804 | break; | ||
8805 | case BT_2ANT_COEX_ALGO_PANEDR: | ||
8806 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR).\n")); | ||
8807 | btdm_2Ant8723APANEDRAction(padapter); | ||
8808 | break; | ||
8809 | case BT_2ANT_COEX_ALGO_PANHS: | ||
8810 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HS mode.\n")); | ||
8811 | btdm_2Ant8723APANHSAction(padapter); | ||
8812 | break; | ||
8813 | case BT_2ANT_COEX_ALGO_PANEDR_A2DP: | ||
8814 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN+A2DP.\n")); | ||
8815 | btdm_2Ant8723APANEDRA2DPAction(padapter); | ||
8816 | break; | ||
8817 | case BT_2ANT_COEX_ALGO_PANEDR_HID: | ||
8818 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR)+HID.\n")); | ||
8819 | btdm_2Ant8723APANEDRHIDAction(padapter); | ||
8820 | break; | ||
8821 | case BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR: | ||
8822 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP+PAN.\n")); | ||
8823 | btdm_2Ant8723AHIDA2DPPANEDRAction(padapter); | ||
8824 | break; | ||
8825 | case BT_2ANT_COEX_ALGO_HID_A2DP: | ||
8826 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP.\n")); | ||
8827 | btdm_2Ant8723AHIDA2DPAction(padapter); | ||
8828 | break; | ||
8829 | default: | ||
8830 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = 0.\n")); | ||
8831 | btdm_2Ant8723AA2DPAction(padapter); | ||
8832 | break; | ||
8833 | } | ||
8834 | pBtdm8723->preAlgorithm = pBtdm8723->curAlgorithm; | ||
8835 | } | ||
8836 | } else { | ||
8837 | RTPRINT(FBT, BT_TRACE, ("[BTCoex] Get bt info by fw!!\n")); | ||
8838 | /* msg shows c2h rsp for bt_info is received or not. */ | ||
8839 | if (pHalData->bt_coexist.halCoex8723.bC2hBtInfoReqSent) | ||
8840 | RTPRINT(FBT, BT_TRACE, ("[BTCoex] c2h for btInfo not rcvd yet!!\n")); | ||
8841 | |||
8842 | btInfoOriginal = pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal; | ||
8843 | |||
8844 | if (pBtMgnt->ExtConfig.bHoldForBtOperation) { | ||
8845 | RTPRINT(FBT, BT_TRACE, ("Action for BT Operation adjust!!\n")); | ||
8846 | return; | ||
8847 | } | ||
8848 | if (pBtMgnt->ExtConfig.bHoldPeriodCnt) { | ||
8849 | RTPRINT(FBT, BT_TRACE, | ||
8850 | ("Hold BT inquiry/page scan setting (cnt = %d)!!\n", | ||
8851 | pBtMgnt->ExtConfig.bHoldPeriodCnt)); | ||
8852 | if (pBtMgnt->ExtConfig.bHoldPeriodCnt >= 11) { | ||
8853 | pBtMgnt->ExtConfig.bHoldPeriodCnt = 0; | ||
8854 | /* next time the coexist parameters should be reset again. */ | ||
8855 | } else { | ||
8856 | pBtMgnt->ExtConfig.bHoldPeriodCnt++; | ||
8857 | } | ||
8858 | return; | ||
8859 | } | ||
8860 | |||
8861 | if (pBtDbg->dbgCtrl) | ||
8862 | RTPRINT(FBT, BT_TRACE, ("[Dbg control], ")); | ||
8863 | if (btdm_Is2Ant8723ACommonAction(padapter)) { | ||
8864 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant common.\n")); | ||
8865 | pBtdm8723->bResetTdmaAdjust = true; | ||
8866 | } else { | ||
8867 | if (pBtdm8723->curAlgorithm != pBtdm8723->preAlgorithm) { | ||
8868 | RTPRINT(FBT, BT_TRACE, | ||
8869 | ("[BTCoex], preAlgorithm =%d, curAlgorithm =%d\n", | ||
8870 | pBtdm8723->preAlgorithm, | ||
8871 | pBtdm8723->curAlgorithm)); | ||
8872 | pBtdm8723->bResetTdmaAdjust = true; | ||
8873 | } | ||
8874 | switch (pBtdm8723->curAlgorithm) { | ||
8875 | case BT_2ANT_COEX_ALGO_SCO: | ||
8876 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = SCO.\n")); | ||
8877 | btdm_2Ant8723ASCOAction(padapter); | ||
8878 | break; | ||
8879 | case BT_2ANT_COEX_ALGO_HID: | ||
8880 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID.\n")); | ||
8881 | btdm_2Ant8723AHIDAction(padapter); | ||
8882 | break; | ||
8883 | case BT_2ANT_COEX_ALGO_A2DP: | ||
8884 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = A2DP.\n")); | ||
8885 | btdm_2Ant8723AA2dp(padapter); | ||
8886 | break; | ||
8887 | case BT_2ANT_COEX_ALGO_PANEDR: | ||
8888 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR).\n")); | ||
8889 | btdm_2Ant8723APANEDRAction(padapter); | ||
8890 | break; | ||
8891 | case BT_2ANT_COEX_ALGO_PANHS: | ||
8892 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HS mode.\n")); | ||
8893 | btdm_2Ant8723APANHSAction(padapter); | ||
8894 | break; | ||
8895 | case BT_2ANT_COEX_ALGO_PANEDR_A2DP: | ||
8896 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN+A2DP.\n")); | ||
8897 | btdm_2Ant8723APANEDRA2DPAction(padapter); | ||
8898 | break; | ||
8899 | case BT_2ANT_COEX_ALGO_PANEDR_HID: | ||
8900 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR)+HID.\n")); | ||
8901 | btdm_2Ant8723APANEDRHIDAction(padapter); | ||
8902 | break; | ||
8903 | case BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR: | ||
8904 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP+PAN.\n")); | ||
8905 | btdm_2Ant8723AHIDA2DPPANEDRAction(padapter); | ||
8906 | break; | ||
8907 | case BT_2ANT_COEX_ALGO_HID_A2DP: | ||
8908 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP.\n")); | ||
8909 | btdm_2Ant8723AHIDA2DPAction(padapter); | ||
8910 | break; | ||
8911 | default: | ||
8912 | RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = 0.\n")); | ||
8913 | btdm_2Ant8723AA2DPAction(padapter); | ||
8914 | break; | ||
8915 | } | ||
8916 | pBtdm8723->preAlgorithm = pBtdm8723->curAlgorithm; | ||
8917 | } | ||
8918 | } | ||
8919 | } | ||
8920 | |||
8921 | /* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87232Ant.c ===== */ | ||
8922 | #endif | ||
8923 | |||
8924 | #ifdef __HALBTC8723_C__ /* HAL/BTCoexist/HalBtc8723.c */ | ||
8925 | /* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc8723.c ===== */ | ||
8926 | |||
8927 | static u8 btCoexDbgBuf[BT_TMP_BUF_SIZE]; | ||
8928 | |||
8929 | static const char *const BtProfileString[] = { | ||
8930 | "NONE", | ||
8931 | "A2DP", | ||
8932 | "PAN", | ||
8933 | "HID", | ||
8934 | "SCO", | ||
8935 | }; | ||
8936 | |||
8937 | static const char *const BtSpecString[] = { | ||
8938 | "1.0b", | ||
8939 | "1.1", | ||
8940 | "1.2", | ||
8941 | "2.0+EDR", | ||
8942 | "2.1+EDR", | ||
8943 | "3.0+HS", | ||
8944 | "4.0", | ||
8945 | }; | ||
8946 | |||
8947 | static const char *const BtLinkRoleString[] = { | ||
8948 | "Master", | ||
8949 | "Slave", | ||
8950 | }; | ||
8951 | |||
8952 | static u8 btdm_BtWifiAntNum(struct rtw_adapter *padapter) | ||
8953 | { | ||
8954 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
8955 | struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723; | ||
8956 | |||
8957 | if (Ant_x2 == pHalData->bt_coexist.BT_Ant_Num) { | ||
8958 | if (Ant_x2 == pBtCoex->TotalAntNum) | ||
8959 | return Ant_x2; | ||
8960 | else | ||
8961 | return Ant_x1; | ||
8962 | } else { | ||
8963 | return Ant_x1; | ||
8964 | } | ||
8965 | return Ant_x2; | ||
8966 | } | ||
8967 | |||
8968 | static void btdm_BtHwCountersMonitor(struct rtw_adapter *padapter) | ||
8969 | { | ||
8970 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
8971 | u32 regHPTxRx, regLPTxRx, u4Tmp; | ||
8972 | u32 regHPTx = 0, regHPRx = 0, regLPTx = 0, regLPRx = 0; | ||
8973 | |||
8974 | regHPTxRx = REG_HIGH_PRIORITY_TXRX; | ||
8975 | regLPTxRx = REG_LOW_PRIORITY_TXRX; | ||
8976 | |||
8977 | u4Tmp = rtw_read32(padapter, regHPTxRx); | ||
8978 | regHPTx = u4Tmp & bMaskLWord; | ||
8979 | regHPRx = (u4Tmp & bMaskHWord)>>16; | ||
8980 | |||
8981 | u4Tmp = rtw_read32(padapter, regLPTxRx); | ||
8982 | regLPTx = u4Tmp & bMaskLWord; | ||
8983 | regLPRx = (u4Tmp & bMaskHWord)>>16; | ||
8984 | |||
8985 | pHalData->bt_coexist.halCoex8723.highPriorityTx = regHPTx; | ||
8986 | pHalData->bt_coexist.halCoex8723.highPriorityRx = regHPRx; | ||
8987 | pHalData->bt_coexist.halCoex8723.lowPriorityTx = regLPTx; | ||
8988 | pHalData->bt_coexist.halCoex8723.lowPriorityRx = regLPRx; | ||
8989 | |||
8990 | RTPRINT(FBT, BT_TRACE, ("High Priority Tx/Rx = %d / %d\n", regHPTx, regHPRx)); | ||
8991 | RTPRINT(FBT, BT_TRACE, ("Low Priority Tx/Rx = %d / %d\n", regLPTx, regLPRx)); | ||
8992 | |||
8993 | /* reset counter */ | ||
8994 | rtw_write8(padapter, 0x76e, 0xc); | ||
8995 | } | ||
8996 | |||
8997 | /* This function check if 8723 bt is disabled */ | ||
8998 | static void btdm_BtEnableDisableCheck8723A(struct rtw_adapter *padapter) | ||
8999 | { | ||
9000 | u8 btAlife = true; | ||
9001 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
9002 | |||
9003 | #ifdef CHECK_BT_EXIST_FROM_REG | ||
9004 | u8 val8; | ||
9005 | |||
9006 | /* ox68[28]= 1 => BT enable; otherwise disable */ | ||
9007 | val8 = rtw_read8(padapter, 0x6B); | ||
9008 | if (!(val8 & BIT(4))) | ||
9009 | btAlife = false; | ||
9010 | |||
9011 | if (btAlife) | ||
9012 | pHalData->bt_coexist.bCurBtDisabled = false; | ||
9013 | else | ||
9014 | pHalData->bt_coexist.bCurBtDisabled = true; | ||
9015 | #else | ||
9016 | if (pHalData->bt_coexist.halCoex8723.highPriorityTx == 0 && | ||
9017 | pHalData->bt_coexist.halCoex8723.highPriorityRx == 0 && | ||
9018 | pHalData->bt_coexist.halCoex8723.lowPriorityTx == 0 && | ||
9019 | pHalData->bt_coexist.halCoex8723.lowPriorityRx == 0) | ||
9020 | btAlife = false; | ||
9021 | if (pHalData->bt_coexist.halCoex8723.highPriorityTx == 0xeaea && | ||
9022 | pHalData->bt_coexist.halCoex8723.highPriorityRx == 0xeaea && | ||
9023 | pHalData->bt_coexist.halCoex8723.lowPriorityTx == 0xeaea && | ||
9024 | pHalData->bt_coexist.halCoex8723.lowPriorityRx == 0xeaea) | ||
9025 | btAlife = false; | ||
9026 | if (pHalData->bt_coexist.halCoex8723.highPriorityTx == 0xffff && | ||
9027 | pHalData->bt_coexist.halCoex8723.highPriorityRx == 0xffff && | ||
9028 | pHalData->bt_coexist.halCoex8723.lowPriorityTx == 0xffff && | ||
9029 | pHalData->bt_coexist.halCoex8723.lowPriorityRx == 0xffff) | ||
9030 | btAlife = false; | ||
9031 | if (btAlife) { | ||
9032 | pHalData->bt_coexist.btActiveZeroCnt = 0; | ||
9033 | pHalData->bt_coexist.bCurBtDisabled = false; | ||
9034 | RTPRINT(FBT, BT_TRACE, ("8723A BT is enabled !!\n")); | ||
9035 | } else { | ||
9036 | pHalData->bt_coexist.btActiveZeroCnt++; | ||
9037 | RTPRINT(FBT, BT_TRACE, ("8723A bt all counters = 0, %d times!!\n", | ||
9038 | pHalData->bt_coexist.btActiveZeroCnt)); | ||
9039 | if (pHalData->bt_coexist.btActiveZeroCnt >= 2) { | ||
9040 | pHalData->bt_coexist.bCurBtDisabled = true; | ||
9041 | RTPRINT(FBT, BT_TRACE, ("8723A BT is disabled !!\n")); | ||
9042 | } | ||
9043 | } | ||
9044 | #endif | ||
9045 | |||
9046 | if (!pHalData->bt_coexist.bCurBtDisabled) { | ||
9047 | if (BTDM_IsWifiConnectionExist(padapter)) | ||
9048 | BTDM_SetFwChnlInfo(padapter, RT_MEDIA_CONNECT); | ||
9049 | else | ||
9050 | BTDM_SetFwChnlInfo(padapter, RT_MEDIA_DISCONNECT); | ||
9051 | } | ||
9052 | |||
9053 | if (pHalData->bt_coexist.bPreBtDisabled != | ||
9054 | pHalData->bt_coexist.bCurBtDisabled) { | ||
9055 | RTPRINT(FBT, BT_TRACE, ("8723A BT is from %s to %s!!\n", | ||
9056 | (pHalData->bt_coexist.bPreBtDisabled ? "disabled":"enabled"), | ||
9057 | (pHalData->bt_coexist.bCurBtDisabled ? "disabled":"enabled"))); | ||
9058 | pHalData->bt_coexist.bPreBtDisabled = pHalData->bt_coexist.bCurBtDisabled; | ||
9059 | } | ||
9060 | } | ||
9061 | |||
9062 | static void btdm_BTCoexist8723AHandler(struct rtw_adapter *padapter) | ||
9063 | { | ||
9064 | struct hal_data_8723a *pHalData; | ||
9065 | |||
9066 | pHalData = GET_HAL_DATA(padapter); | ||
9067 | |||
9068 | if (btdm_BtWifiAntNum(padapter) == Ant_x2) { | ||
9069 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], 2 Ant mechanism\n")); | ||
9070 | BTDM_2AntBtCoexist8723A(padapter); | ||
9071 | } else { | ||
9072 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1 Ant mechanism\n")); | ||
9073 | BTDM_1AntBtCoexist8723A(padapter); | ||
9074 | } | ||
9075 | |||
9076 | if (!BTDM_IsSameCoexistState(padapter)) { | ||
9077 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Coexist State[bitMap] change from 0x%"i64fmt"x to 0x%"i64fmt"x\n", | ||
9078 | pHalData->bt_coexist.PreviousState, | ||
9079 | pHalData->bt_coexist.CurrentState)); | ||
9080 | pHalData->bt_coexist.PreviousState = pHalData->bt_coexist.CurrentState; | ||
9081 | |||
9082 | RTPRINT(FBT, BT_TRACE, ("[")); | ||
9083 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT30) | ||
9084 | RTPRINT(FBT, BT_TRACE, ("BT 3.0, ")); | ||
9085 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_HT20) | ||
9086 | RTPRINT(FBT, BT_TRACE, ("HT20, ")); | ||
9087 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_HT40) | ||
9088 | RTPRINT(FBT, BT_TRACE, ("HT40, ")); | ||
9089 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_LEGACY) | ||
9090 | RTPRINT(FBT, BT_TRACE, ("Legacy, ")); | ||
9091 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_RSSI_LOW) | ||
9092 | RTPRINT(FBT, BT_TRACE, ("Rssi_Low, ")); | ||
9093 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_RSSI_MEDIUM) | ||
9094 | RTPRINT(FBT, BT_TRACE, ("Rssi_Mid, ")); | ||
9095 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_RSSI_HIGH) | ||
9096 | RTPRINT(FBT, BT_TRACE, ("Rssi_High, ")); | ||
9097 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_IDLE) | ||
9098 | RTPRINT(FBT, BT_TRACE, ("Wifi_Idle, ")); | ||
9099 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_UPLINK) | ||
9100 | RTPRINT(FBT, BT_TRACE, ("Wifi_Uplink, ")); | ||
9101 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_DOWNLINK) | ||
9102 | RTPRINT(FBT, BT_TRACE, ("Wifi_Downlink, ")); | ||
9103 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT_IDLE) | ||
9104 | RTPRINT(FBT, BT_TRACE, ("BT_idle, ")); | ||
9105 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_HID) | ||
9106 | RTPRINT(FBT, BT_TRACE, ("PRO_HID, ")); | ||
9107 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_A2DP) | ||
9108 | RTPRINT(FBT, BT_TRACE, ("PRO_A2DP, ")); | ||
9109 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_PAN) | ||
9110 | RTPRINT(FBT, BT_TRACE, ("PRO_PAN, ")); | ||
9111 | if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_SCO) | ||
9112 | RTPRINT(FBT, BT_TRACE, ("PRO_SCO, ")); | ||
9113 | RTPRINT(FBT, BT_TRACE, ("]\n")); | ||
9114 | } | ||
9115 | } | ||
9116 | |||
9117 | /* extern function start with BTDM_ */ | ||
9118 | u32 BTDM_BtTxRxCounterH(struct rtw_adapter *padapter) | ||
9119 | { | ||
9120 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
9121 | u32 counters = 0; | ||
9122 | |||
9123 | counters = pHalData->bt_coexist.halCoex8723.highPriorityTx+ | ||
9124 | pHalData->bt_coexist.halCoex8723.highPriorityRx; | ||
9125 | return counters; | ||
9126 | } | ||
9127 | |||
9128 | u32 BTDM_BtTxRxCounterL(struct rtw_adapter *padapter) | ||
9129 | { | ||
9130 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
9131 | u32 counters = 0; | ||
9132 | |||
9133 | counters = pHalData->bt_coexist.halCoex8723.lowPriorityTx+ | ||
9134 | pHalData->bt_coexist.halCoex8723.lowPriorityRx ; | ||
9135 | return counters; | ||
9136 | } | ||
9137 | |||
9138 | void BTDM_SetFwChnlInfo(struct rtw_adapter *padapter, enum rt_media_status mstatus) | ||
9139 | { | ||
9140 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; | ||
9141 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
9142 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
9143 | u8 H2C_Parameter[3] = {0}; | ||
9144 | u8 chnl; | ||
9145 | |||
9146 | /* opMode */ | ||
9147 | if (RT_MEDIA_CONNECT == mstatus) | ||
9148 | H2C_Parameter[0] = 0x1; /* 0: disconnected, 1:connected */ | ||
9149 | |||
9150 | if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) { | ||
9151 | /* channel */ | ||
9152 | chnl = pmlmeext->cur_channel; | ||
9153 | if (BTDM_IsHT40(padapter)) { | ||
9154 | if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) | ||
9155 | chnl -= 2; | ||
9156 | else if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) | ||
9157 | chnl += 2; | ||
9158 | } | ||
9159 | H2C_Parameter[1] = chnl; | ||
9160 | } else { /* check if HS link is exists */ | ||
9161 | /* channel */ | ||
9162 | if (BT_Operation(padapter)) | ||
9163 | H2C_Parameter[1] = pBtMgnt->BTChannel; | ||
9164 | else | ||
9165 | H2C_Parameter[1] = pmlmeext->cur_channel; | ||
9166 | } | ||
9167 | |||
9168 | if (BTDM_IsHT40(padapter)) | ||
9169 | H2C_Parameter[2] = 0x30; | ||
9170 | else | ||
9171 | H2C_Parameter[2] = 0x20; | ||
9172 | |||
9173 | FillH2CCmd(padapter, 0x19, 3, H2C_Parameter); | ||
9174 | } | ||
9175 | |||
9176 | u8 BTDM_IsWifiConnectionExist(struct rtw_adapter *padapter) | ||
9177 | { | ||
9178 | u8 bRet = false; | ||
9179 | |||
9180 | if (BTHCI_HsConnectionEstablished(padapter)) | ||
9181 | bRet = true; | ||
9182 | |||
9183 | if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == true) | ||
9184 | bRet = true; | ||
9185 | |||
9186 | return bRet; | ||
9187 | } | ||
9188 | |||
9189 | void BTDM_SetFw3a( | ||
9190 | struct rtw_adapter *padapter, | ||
9191 | u8 byte1, | ||
9192 | u8 byte2, | ||
9193 | u8 byte3, | ||
9194 | u8 byte4, | ||
9195 | u8 byte5 | ||
9196 | ) | ||
9197 | { | ||
9198 | u8 H2C_Parameter[5] = {0}; | ||
9199 | |||
9200 | if (BTDM_1Ant8723A(padapter)) { | ||
9201 | if ((!check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) && | ||
9202 | (get_fwstate(&padapter->mlmepriv) != WIFI_NULL_STATE)) { | ||
9203 | /* for softap mode */ | ||
9204 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
9205 | struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723; | ||
9206 | u8 BtState = pBtCoex->c2hBtInfo; | ||
9207 | |||
9208 | if ((BtState != BT_INFO_STATE_NO_CONNECTION) && | ||
9209 | (BtState != BT_INFO_STATE_CONNECT_IDLE)) { | ||
9210 | if (byte1 & BIT(4)) { | ||
9211 | byte1 &= ~BIT(4); | ||
9212 | byte1 |= BIT(5); | ||
9213 | } | ||
9214 | |||
9215 | byte5 |= BIT(5); | ||
9216 | if (byte5 & BIT(6)) | ||
9217 | byte5 &= ~BIT(6); | ||
9218 | } | ||
9219 | } | ||
9220 | } | ||
9221 | |||
9222 | H2C_Parameter[0] = byte1; | ||
9223 | H2C_Parameter[1] = byte2; | ||
9224 | H2C_Parameter[2] = byte3; | ||
9225 | H2C_Parameter[3] = byte4; | ||
9226 | H2C_Parameter[4] = byte5; | ||
9227 | |||
9228 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], FW write 0x3a(5bytes) = 0x%02x%08x\n", | ||
9229 | H2C_Parameter[0], | ||
9230 | H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4])); | ||
9231 | |||
9232 | FillH2CCmd(padapter, 0x3a, 5, H2C_Parameter); | ||
9233 | } | ||
9234 | |||
9235 | void BTDM_QueryBtInformation(struct rtw_adapter *padapter) | ||
9236 | { | ||
9237 | u8 H2C_Parameter[1] = {0}; | ||
9238 | struct hal_data_8723a *pHalData; | ||
9239 | struct bt_coexist_8723a *pBtCoex; | ||
9240 | |||
9241 | pHalData = GET_HAL_DATA(padapter); | ||
9242 | pBtCoex = &pHalData->bt_coexist.halCoex8723; | ||
9243 | |||
9244 | if (BT_IsBtDisabled(padapter)) { | ||
9245 | pBtCoex->c2hBtInfo = BT_INFO_STATE_DISABLED; | ||
9246 | pBtCoex->bC2hBtInfoReqSent = false; | ||
9247 | return; | ||
9248 | } | ||
9249 | |||
9250 | if (pBtCoex->c2hBtInfo == BT_INFO_STATE_DISABLED) | ||
9251 | pBtCoex->c2hBtInfo = BT_INFO_STATE_NO_CONNECTION; | ||
9252 | |||
9253 | if (pBtCoex->bC2hBtInfoReqSent == true) | ||
9254 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], didn't recv previous BtInfo report!\n")); | ||
9255 | else | ||
9256 | pBtCoex->bC2hBtInfoReqSent = true; | ||
9257 | |||
9258 | H2C_Parameter[0] |= BIT(0); /* trigger */ | ||
9259 | |||
9260 | /*RTPRINT(FBT, BT_TRACE, ("[BTCoex], Query Bt information, write 0x38 = 0x%x\n", */ | ||
9261 | /*H2C_Parameter[0])); */ | ||
9262 | |||
9263 | FillH2CCmd(padapter, 0x38, 1, H2C_Parameter); | ||
9264 | } | ||
9265 | |||
9266 | void BTDM_SetSwRfRxLpfCorner(struct rtw_adapter *padapter, u8 type) | ||
9267 | { | ||
9268 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
9269 | |||
9270 | if (BT_RF_RX_LPF_CORNER_SHRINK == type) { | ||
9271 | /* Shrink RF Rx LPF corner */ | ||
9272 | RTPRINT(FBT, BT_TRACE, ("Shrink RF Rx LPF corner!!\n")); | ||
9273 | PHY_SetRFReg(padapter, PathA, 0x1e, bRFRegOffsetMask, 0xf0ff7); | ||
9274 | pHalData->bt_coexist.bSWCoexistAllOff = false; | ||
9275 | } else if (BT_RF_RX_LPF_CORNER_RESUME == type) { | ||
9276 | /* Resume RF Rx LPF corner */ | ||
9277 | RTPRINT(FBT, BT_TRACE, ("Resume RF Rx LPF corner!!\n")); | ||
9278 | PHY_SetRFReg(padapter, PathA, 0x1e, bRFRegOffsetMask, pHalData->bt_coexist.BtRfRegOrigin1E); | ||
9279 | } | ||
9280 | } | ||
9281 | |||
9282 | void | ||
9283 | BTDM_SetSwPenaltyTxRateAdaptive( | ||
9284 | struct rtw_adapter *padapter, | ||
9285 | u8 raType | ||
9286 | ) | ||
9287 | { | ||
9288 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
9289 | u8 tmpU1; | ||
9290 | |||
9291 | tmpU1 = rtw_read8(padapter, 0x4fd); | ||
9292 | tmpU1 |= BIT(0); | ||
9293 | if (BT_TX_RATE_ADAPTIVE_LOW_PENALTY == raType) { | ||
9294 | tmpU1 &= ~BIT(2); | ||
9295 | pHalData->bt_coexist.bSWCoexistAllOff = false; | ||
9296 | } else if (BT_TX_RATE_ADAPTIVE_NORMAL == raType) { | ||
9297 | tmpU1 |= BIT(2); | ||
9298 | } | ||
9299 | |||
9300 | rtw_write8(padapter, 0x4fd, tmpU1); | ||
9301 | } | ||
9302 | |||
9303 | void BTDM_SetFwDecBtPwr(struct rtw_adapter *padapter, u8 bDecBtPwr) | ||
9304 | { | ||
9305 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
9306 | u8 H2C_Parameter[1] = {0}; | ||
9307 | |||
9308 | H2C_Parameter[0] = 0; | ||
9309 | |||
9310 | if (bDecBtPwr) { | ||
9311 | H2C_Parameter[0] |= BIT(1); | ||
9312 | pHalData->bt_coexist.bFWCoexistAllOff = false; | ||
9313 | } | ||
9314 | |||
9315 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], decrease Bt Power : %s, write 0x21 = 0x%x\n", | ||
9316 | (bDecBtPwr ? "Yes!!" : "No!!"), H2C_Parameter[0])); | ||
9317 | |||
9318 | FillH2CCmd(padapter, 0x21, 1, H2C_Parameter); | ||
9319 | } | ||
9320 | |||
9321 | u8 BTDM_BtProfileSupport(struct rtw_adapter *padapter) | ||
9322 | { | ||
9323 | u8 bRet = false; | ||
9324 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
9325 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
9326 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
9327 | |||
9328 | if (pBtMgnt->bSupportProfile && | ||
9329 | !pHalData->bt_coexist.halCoex8723.bForceFwBtInfo) | ||
9330 | bRet = true; | ||
9331 | |||
9332 | return bRet; | ||
9333 | } | ||
9334 | |||
9335 | static void BTDM_AdjustForBtOperation8723A(struct rtw_adapter *padapter) | ||
9336 | { | ||
9337 | /* BTDM_2AntAdjustForBtOperation8723(padapter); */ | ||
9338 | } | ||
9339 | |||
9340 | static void BTDM_FwC2hBtRssi8723A(struct rtw_adapter *padapter, u8 *tmpBuf) | ||
9341 | { | ||
9342 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
9343 | u8 percent = 0, u1tmp = 0; | ||
9344 | |||
9345 | u1tmp = tmpBuf[0]; | ||
9346 | percent = u1tmp*2+10; | ||
9347 | |||
9348 | pHalData->bt_coexist.halCoex8723.btRssi = percent; | ||
9349 | /*RTPRINT(FBT, BT_TRACE, ("[BTC2H], BT RSSI =%d\n", percent)); */ | ||
9350 | } | ||
9351 | |||
9352 | static void | ||
9353 | BTDM_FwC2hBtInfo8723A(struct rtw_adapter *padapter, u8 *tmpBuf, u8 length) | ||
9354 | { | ||
9355 | struct hal_data_8723a *pHalData; | ||
9356 | struct bt_30info *pBTInfo; | ||
9357 | struct bt_mgnt *pBtMgnt; | ||
9358 | struct bt_coexist_8723a *pBtCoex; | ||
9359 | u8 i; | ||
9360 | |||
9361 | pHalData = GET_HAL_DATA(padapter); | ||
9362 | pBTInfo = GET_BT_INFO(padapter); | ||
9363 | pBtMgnt = &pBTInfo->BtMgnt; | ||
9364 | pBtCoex = &pHalData->bt_coexist.halCoex8723; | ||
9365 | |||
9366 | pBtCoex->bC2hBtInfoReqSent = false; | ||
9367 | |||
9368 | RTPRINT(FBT, BT_TRACE, ("[BTC2H], BT info[%d]=[", length)); | ||
9369 | |||
9370 | pBtCoex->btRetryCnt = 0; | ||
9371 | for (i = 0; i < length; i++) { | ||
9372 | switch (i) { | ||
9373 | case 0: | ||
9374 | pBtCoex->c2hBtInfoOriginal = tmpBuf[i]; | ||
9375 | break; | ||
9376 | case 1: | ||
9377 | pBtCoex->btRetryCnt = tmpBuf[i]; | ||
9378 | break; | ||
9379 | case 2: | ||
9380 | BTDM_FwC2hBtRssi8723A(padapter, &tmpBuf[i]); | ||
9381 | break; | ||
9382 | case 3: | ||
9383 | pBtCoex->btInfoExt = tmpBuf[i]&BIT(0); | ||
9384 | break; | ||
9385 | } | ||
9386 | |||
9387 | if (i == length-1) | ||
9388 | RTPRINT(FBT, BT_TRACE, ("0x%02x]\n", tmpBuf[i])); | ||
9389 | else | ||
9390 | RTPRINT(FBT, BT_TRACE, ("0x%02x, ", tmpBuf[i])); | ||
9391 | } | ||
9392 | RTPRINT(FBT, BT_TRACE, ("[BTC2H], BT RSSI =%d\n", pBtCoex->btRssi)); | ||
9393 | if (pBtCoex->btInfoExt) | ||
9394 | RTPRINT(FBT, BT_TRACE, ("[BTC2H], pBtCoex->btInfoExt =%x\n", pBtCoex->btInfoExt)); | ||
9395 | |||
9396 | if (btdm_BtWifiAntNum(padapter) == Ant_x1) | ||
9397 | BTDM_1AntFwC2hBtInfo8723A(padapter); | ||
9398 | else | ||
9399 | BTDM_2AntFwC2hBtInfo8723A(padapter); | ||
9400 | |||
9401 | if (pBtMgnt->ExtConfig.bManualControl) { | ||
9402 | RTPRINT(FBT, BT_TRACE, ("%s: Action Manual control!!\n", __func__)); | ||
9403 | return; | ||
9404 | } | ||
9405 | |||
9406 | btdm_BTCoexist8723AHandler(padapter); | ||
9407 | } | ||
9408 | |||
9409 | static void BTDM_Display8723ABtCoexInfo(struct rtw_adapter *padapter) | ||
9410 | { | ||
9411 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
9412 | struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723; | ||
9413 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
9414 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
9415 | u8 u1Tmp, u1Tmp1, u1Tmp2, i, btInfoExt, psTdmaCase = 0; | ||
9416 | u32 u4Tmp[4]; | ||
9417 | u8 antNum = Ant_x2; | ||
9418 | |||
9419 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============"); | ||
9420 | DCMD_Printf(btCoexDbgBuf); | ||
9421 | |||
9422 | if (!pHalData->bt_coexist.BluetoothCoexist) { | ||
9423 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!"); | ||
9424 | DCMD_Printf(btCoexDbgBuf); | ||
9425 | return; | ||
9426 | } | ||
9427 | |||
9428 | antNum = btdm_BtWifiAntNum(padapter); | ||
9429 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/%d ", "Ant mechanism PG/Now run :", \ | ||
9430 | ((pHalData->bt_coexist.BT_Ant_Num == Ant_x2) ? 2 : 1), ((antNum == Ant_x2) ? 2 : 1)); | ||
9431 | DCMD_Printf(btCoexDbgBuf); | ||
9432 | |||
9433 | if (pBtMgnt->ExtConfig.bManualControl) { | ||
9434 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "[Action Manual control]!!"); | ||
9435 | DCMD_Printf(btCoexDbgBuf); | ||
9436 | } else { | ||
9437 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \ | ||
9438 | ((pBtMgnt->bSupportProfile) ? "Yes" : "No"), pBtMgnt->ExtConfig.HCIExtensionVer); | ||
9439 | DCMD_Printf(btCoexDbgBuf); | ||
9440 | } | ||
9441 | |||
9442 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\n %-35s = / %d", "Dot11 channel / BT channel", \ | ||
9443 | pBtMgnt->BTChannel); | ||
9444 | DCMD_Printf(btCoexDbgBuf); | ||
9445 | |||
9446 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\n %-35s = %d / %d / %d", "Wifi/BT/HS rssi", \ | ||
9447 | BTDM_GetRxSS(padapter), | ||
9448 | pHalData->bt_coexist.halCoex8723.btRssi, | ||
9449 | pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB); | ||
9450 | DCMD_Printf(btCoexDbgBuf); | ||
9451 | |||
9452 | if (!pBtMgnt->ExtConfig.bManualControl) { | ||
9453 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\n %-35s = %s / %s ", "WIfi status", | ||
9454 | ((BTDM_Legacy(padapter)) ? "Legacy" : (((BTDM_IsHT40(padapter)) ? "HT40" : "HT20"))), | ||
9455 | ((!BTDM_IsWifiBusy(padapter)) ? "idle" : ((BTDM_IsWifiUplink(padapter)) ? "uplink" : "downlink"))); | ||
9456 | DCMD_Printf(btCoexDbgBuf); | ||
9457 | |||
9458 | if (pBtMgnt->bSupportProfile) { | ||
9459 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", | ||
9460 | ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_SCO)) ? 1 : 0), | ||
9461 | ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID)) ? 1 : 0), | ||
9462 | ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) ? 1 : 0), | ||
9463 | ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) ? 1 : 0)); | ||
9464 | DCMD_Printf(btCoexDbgBuf); | ||
9465 | |||
9466 | for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) { | ||
9467 | if (pBtMgnt->ExtConfig.HCIExtensionVer >= 1) { | ||
9468 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s", "Bt link type/spec/role", | ||
9469 | BtProfileString[pBtMgnt->ExtConfig.linkInfo[i].BTProfile], | ||
9470 | BtSpecString[pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec], | ||
9471 | BtLinkRoleString[pBtMgnt->ExtConfig.linkInfo[i].linkRole]); | ||
9472 | DCMD_Printf(btCoexDbgBuf); | ||
9473 | |||
9474 | btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt; | ||
9475 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "A2DP rate", \ | ||
9476 | (btInfoExt&BIT0) ? "Basic rate" : "EDR rate"); | ||
9477 | DCMD_Printf(btCoexDbgBuf); | ||
9478 | } else { | ||
9479 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s", "Bt link type/spec", \ | ||
9480 | BtProfileString[pBtMgnt->ExtConfig.linkInfo[i].BTProfile], | ||
9481 | BtSpecString[pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec]); | ||
9482 | DCMD_Printf(btCoexDbgBuf); | ||
9483 | } | ||
9484 | } | ||
9485 | } | ||
9486 | } | ||
9487 | |||
9488 | /* Sw mechanism */ | ||
9489 | if (!pBtMgnt->ExtConfig.bManualControl) { | ||
9490 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw BT Coex mechanism]============"); | ||
9491 | DCMD_Printf(btCoexDbgBuf); | ||
9492 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "AGC Table", \ | ||
9493 | pBtCoex->btdm2Ant.bCurAgcTableEn); | ||
9494 | DCMD_Printf(btCoexDbgBuf); | ||
9495 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "ADC Backoff", \ | ||
9496 | pBtCoex->btdm2Ant.bCurAdcBackOff); | ||
9497 | DCMD_Printf(btCoexDbgBuf); | ||
9498 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "Low penalty RA", \ | ||
9499 | pBtCoex->btdm2Ant.bCurLowPenaltyRa); | ||
9500 | DCMD_Printf(btCoexDbgBuf); | ||
9501 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "RF Rx LPF Shrink", \ | ||
9502 | pBtCoex->btdm2Ant.bCurRfRxLpfShrink); | ||
9503 | DCMD_Printf(btCoexDbgBuf); | ||
9504 | } | ||
9505 | u4Tmp[0] = PHY_QueryRFReg(padapter, PathA, 0x1e, 0xff0); | ||
9506 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "RF-A, 0x1e[11:4]/original val", \ | ||
9507 | u4Tmp[0], pHalData->bt_coexist.BtRfRegOrigin1E); | ||
9508 | DCMD_Printf(btCoexDbgBuf); | ||
9509 | |||
9510 | /* Fw mechanism */ | ||
9511 | if (!pBtMgnt->ExtConfig.bManualControl) { | ||
9512 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw BT Coex mechanism]============"); | ||
9513 | DCMD_Printf(btCoexDbgBuf); | ||
9514 | } | ||
9515 | if (!pBtMgnt->ExtConfig.bManualControl) { | ||
9516 | if (btdm_BtWifiAntNum(padapter) == Ant_x1) | ||
9517 | psTdmaCase = pHalData->bt_coexist.halCoex8723.btdm1Ant.curPsTdma; | ||
9518 | else | ||
9519 | psTdmaCase = pHalData->bt_coexist.halCoex8723.btdm2Ant.curPsTdma; | ||
9520 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d", "PS TDMA(0x3a)", \ | ||
9521 | pHalData->bt_coexist.fw3aVal[0], pHalData->bt_coexist.fw3aVal[1], | ||
9522 | pHalData->bt_coexist.fw3aVal[2], pHalData->bt_coexist.fw3aVal[3], | ||
9523 | pHalData->bt_coexist.fw3aVal[4], psTdmaCase); | ||
9524 | DCMD_Printf(btCoexDbgBuf); | ||
9525 | |||
9526 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "Decrease Bt Power", \ | ||
9527 | pBtCoex->btdm2Ant.bCurDecBtPwr); | ||
9528 | DCMD_Printf(btCoexDbgBuf); | ||
9529 | } | ||
9530 | u1Tmp = rtw_read8(padapter, 0x778); | ||
9531 | u1Tmp1 = rtw_read8(padapter, 0x783); | ||
9532 | u1Tmp2 = rtw_read8(padapter, 0x796); | ||
9533 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x778/ 0x783/ 0x796", \ | ||
9534 | u1Tmp, u1Tmp1, u1Tmp2); | ||
9535 | DCMD_Printf(btCoexDbgBuf); | ||
9536 | |||
9537 | if (!pBtMgnt->ExtConfig.bManualControl) { | ||
9538 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x / 0x%x", "Sw DacSwing Ctrl/Val", \ | ||
9539 | pBtCoex->btdm2Ant.bCurDacSwingOn, pBtCoex->btdm2Ant.curDacSwingLvl); | ||
9540 | DCMD_Printf(btCoexDbgBuf); | ||
9541 | } | ||
9542 | u4Tmp[0] = rtw_read32(padapter, 0x880); | ||
9543 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x880", \ | ||
9544 | u4Tmp[0]); | ||
9545 | DCMD_Printf(btCoexDbgBuf); | ||
9546 | |||
9547 | /* Hw mechanism */ | ||
9548 | if (!pBtMgnt->ExtConfig.bManualControl) { | ||
9549 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw BT Coex mechanism]============"); | ||
9550 | DCMD_Printf(btCoexDbgBuf); | ||
9551 | } | ||
9552 | |||
9553 | u1Tmp = rtw_read8(padapter, 0x40); | ||
9554 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x40", \ | ||
9555 | u1Tmp); | ||
9556 | DCMD_Printf(btCoexDbgBuf); | ||
9557 | |||
9558 | u4Tmp[0] = rtw_read32(padapter, 0x550); | ||
9559 | u1Tmp = rtw_read8(padapter, 0x522); | ||
9560 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x", "0x550(bcn contrl)/0x522", \ | ||
9561 | u4Tmp[0], u1Tmp); | ||
9562 | DCMD_Printf(btCoexDbgBuf); | ||
9563 | |||
9564 | u4Tmp[0] = rtw_read32(padapter, 0x484); | ||
9565 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x484(rate adaptive)", \ | ||
9566 | u4Tmp[0]); | ||
9567 | DCMD_Printf(btCoexDbgBuf); | ||
9568 | |||
9569 | u4Tmp[0] = rtw_read32(padapter, 0x50); | ||
9570 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \ | ||
9571 | u4Tmp[0]); | ||
9572 | DCMD_Printf(btCoexDbgBuf); | ||
9573 | |||
9574 | u4Tmp[0] = rtw_read32(padapter, 0xda0); | ||
9575 | u4Tmp[1] = rtw_read32(padapter, 0xda4); | ||
9576 | u4Tmp[2] = rtw_read32(padapter, 0xda8); | ||
9577 | u4Tmp[3] = rtw_read32(padapter, 0xdac); | ||
9578 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0xda0/0xda4/0xda8/0xdac(FA cnt)", \ | ||
9579 | u4Tmp[0], u4Tmp[1], u4Tmp[2], u4Tmp[3]); | ||
9580 | DCMD_Printf(btCoexDbgBuf); | ||
9581 | |||
9582 | u4Tmp[0] = rtw_read32(padapter, 0x6c0); | ||
9583 | u4Tmp[1] = rtw_read32(padapter, 0x6c4); | ||
9584 | u4Tmp[2] = rtw_read32(padapter, 0x6c8); | ||
9585 | u1Tmp = rtw_read8(padapter, 0x6cc); | ||
9586 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \ | ||
9587 | u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp); | ||
9588 | DCMD_Printf(btCoexDbgBuf); | ||
9589 | |||
9590 | /* u4Tmp = rtw_read32(padapter, 0x770); */ | ||
9591 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d", "0x770(Hi pri Rx[31:16]/Tx[15:0])", \ | ||
9592 | pHalData->bt_coexist.halCoex8723.highPriorityRx, | ||
9593 | pHalData->bt_coexist.halCoex8723.highPriorityTx); | ||
9594 | DCMD_Printf(btCoexDbgBuf); | ||
9595 | /* u4Tmp = rtw_read32(padapter, 0x774); */ | ||
9596 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d", "0x774(Lo pri Rx[31:16]/Tx[15:0])", \ | ||
9597 | pHalData->bt_coexist.halCoex8723.lowPriorityRx, | ||
9598 | pHalData->bt_coexist.halCoex8723.lowPriorityTx); | ||
9599 | DCMD_Printf(btCoexDbgBuf); | ||
9600 | |||
9601 | /* Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang */ | ||
9602 | u1Tmp = rtw_read8(padapter, 0x41b); | ||
9603 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x41b (hang chk == 0xf)", \ | ||
9604 | u1Tmp); | ||
9605 | DCMD_Printf(btCoexDbgBuf); | ||
9606 | rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "lastHMEBoxNum", \ | ||
9607 | pHalData->LastHMEBoxNum); | ||
9608 | DCMD_Printf(btCoexDbgBuf); | ||
9609 | } | ||
9610 | |||
9611 | static void | ||
9612 | BTDM_8723ASignalCompensation(struct rtw_adapter *padapter, | ||
9613 | u8 *rssi_wifi, u8 *rssi_bt) | ||
9614 | { | ||
9615 | if (btdm_BtWifiAntNum(padapter) == Ant_x1) | ||
9616 | BTDM_1AntSignalCompensation(padapter, rssi_wifi, rssi_bt); | ||
9617 | } | ||
9618 | |||
9619 | static void BTDM_8723AInit(struct rtw_adapter *padapter) | ||
9620 | { | ||
9621 | if (btdm_BtWifiAntNum(padapter) == Ant_x2) | ||
9622 | BTDM_2AntParaInit(padapter); | ||
9623 | else | ||
9624 | BTDM_1AntParaInit(padapter); | ||
9625 | } | ||
9626 | |||
9627 | static void BTDM_HWCoexAllOff8723A(struct rtw_adapter *padapter) | ||
9628 | { | ||
9629 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
9630 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
9631 | |||
9632 | if (pBtMgnt->ExtConfig.bManualControl) | ||
9633 | return; | ||
9634 | |||
9635 | if (btdm_BtWifiAntNum(padapter) == Ant_x2) | ||
9636 | BTDM_2AntHwCoexAllOff8723A(padapter); | ||
9637 | } | ||
9638 | |||
9639 | static void BTDM_FWCoexAllOff8723A(struct rtw_adapter *padapter) | ||
9640 | { | ||
9641 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
9642 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
9643 | |||
9644 | if (pBtMgnt->ExtConfig.bManualControl) | ||
9645 | return; | ||
9646 | |||
9647 | if (btdm_BtWifiAntNum(padapter) == Ant_x2) | ||
9648 | BTDM_2AntFwCoexAllOff8723A(padapter); | ||
9649 | } | ||
9650 | |||
9651 | static void BTDM_SWCoexAllOff8723A(struct rtw_adapter *padapter) | ||
9652 | { | ||
9653 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
9654 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
9655 | |||
9656 | if (pBtMgnt->ExtConfig.bManualControl) | ||
9657 | return; | ||
9658 | |||
9659 | if (btdm_BtWifiAntNum(padapter) == Ant_x2) | ||
9660 | BTDM_2AntSwCoexAllOff8723A(padapter); | ||
9661 | } | ||
9662 | |||
9663 | static void | ||
9664 | BTDM_Set8723ABtCoexCurrAntNum(struct rtw_adapter *padapter, u8 antNum) | ||
9665 | { | ||
9666 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
9667 | struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723; | ||
9668 | |||
9669 | if (antNum == 1) | ||
9670 | pBtCoex->TotalAntNum = Ant_x1; | ||
9671 | else if (antNum == 2) | ||
9672 | pBtCoex->TotalAntNum = Ant_x2; | ||
9673 | } | ||
9674 | |||
9675 | void BTDM_LpsLeave(struct rtw_adapter *padapter) | ||
9676 | { | ||
9677 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
9678 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
9679 | |||
9680 | if (pBtMgnt->ExtConfig.bManualControl) | ||
9681 | return; | ||
9682 | |||
9683 | if (btdm_BtWifiAntNum(padapter) == Ant_x1) | ||
9684 | BTDM_1AntLpsLeave(padapter); | ||
9685 | } | ||
9686 | |||
9687 | static void BTDM_ForHalt8723A(struct rtw_adapter *padapter) | ||
9688 | { | ||
9689 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
9690 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
9691 | |||
9692 | if (pBtMgnt->ExtConfig.bManualControl) | ||
9693 | return; | ||
9694 | |||
9695 | if (btdm_BtWifiAntNum(padapter) == Ant_x1) | ||
9696 | BTDM_1AntForHalt(padapter); | ||
9697 | } | ||
9698 | |||
9699 | static void BTDM_WifiScanNotify8723A(struct rtw_adapter *padapter, u8 scanType) | ||
9700 | { | ||
9701 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
9702 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
9703 | |||
9704 | if (pBtMgnt->ExtConfig.bManualControl) | ||
9705 | return; | ||
9706 | |||
9707 | if (btdm_BtWifiAntNum(padapter) == Ant_x1) | ||
9708 | BTDM_1AntWifiScanNotify(padapter, scanType); | ||
9709 | } | ||
9710 | |||
9711 | static void | ||
9712 | BTDM_WifiAssociateNotify8723A(struct rtw_adapter *padapter, u8 action) | ||
9713 | { | ||
9714 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
9715 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
9716 | |||
9717 | if (pBtMgnt->ExtConfig.bManualControl) | ||
9718 | return; | ||
9719 | |||
9720 | if (btdm_BtWifiAntNum(padapter) == Ant_x1) | ||
9721 | BTDM_1AntWifiAssociateNotify(padapter, action); | ||
9722 | } | ||
9723 | |||
9724 | static void | ||
9725 | BTDM_MediaStatusNotify8723A(struct rtw_adapter *padapter, | ||
9726 | enum rt_media_status mstatus) | ||
9727 | { | ||
9728 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
9729 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
9730 | |||
9731 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], MediaStatusNotify, %s\n", | ||
9732 | mstatus?"connect":"disconnect")); | ||
9733 | |||
9734 | BTDM_SetFwChnlInfo(padapter, mstatus); | ||
9735 | |||
9736 | if (pBtMgnt->ExtConfig.bManualControl) | ||
9737 | return; | ||
9738 | |||
9739 | if (btdm_BtWifiAntNum(padapter) == Ant_x1) | ||
9740 | BTDM_1AntMediaStatusNotify(padapter, mstatus); | ||
9741 | } | ||
9742 | |||
9743 | static void BTDM_ForDhcp8723A(struct rtw_adapter *padapter) | ||
9744 | { | ||
9745 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
9746 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
9747 | |||
9748 | if (pBtMgnt->ExtConfig.bManualControl) | ||
9749 | return; | ||
9750 | |||
9751 | if (btdm_BtWifiAntNum(padapter) == Ant_x1) | ||
9752 | BTDM_1AntForDhcp(padapter); | ||
9753 | } | ||
9754 | |||
9755 | u8 BTDM_1Ant8723A(struct rtw_adapter *padapter) | ||
9756 | { | ||
9757 | if (btdm_BtWifiAntNum(padapter) == Ant_x1) | ||
9758 | return true; | ||
9759 | else | ||
9760 | return false; | ||
9761 | } | ||
9762 | |||
9763 | static void BTDM_BTCoexist8723A(struct rtw_adapter *padapter) | ||
9764 | { | ||
9765 | struct hal_data_8723a *pHalData; | ||
9766 | struct bt_30info *pBTInfo; | ||
9767 | struct bt_mgnt *pBtMgnt; | ||
9768 | struct bt_coexist_8723a *pBtCoex; | ||
9769 | |||
9770 | pHalData = GET_HAL_DATA(padapter); | ||
9771 | pBTInfo = GET_BT_INFO(padapter); | ||
9772 | pBtMgnt = &pBTInfo->BtMgnt; | ||
9773 | pBtCoex = &pHalData->bt_coexist.halCoex8723; | ||
9774 | |||
9775 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], beacon RSSI = 0x%x(%d)\n", | ||
9776 | pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB, | ||
9777 | pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB)); | ||
9778 | |||
9779 | btdm_BtHwCountersMonitor(padapter); | ||
9780 | btdm_BtEnableDisableCheck8723A(padapter); | ||
9781 | |||
9782 | if (pBtMgnt->ExtConfig.bManualControl) { | ||
9783 | RTPRINT(FBT, BT_TRACE, ("%s: Action Manual control!!\n", __func__)); | ||
9784 | return; | ||
9785 | } | ||
9786 | |||
9787 | if (pBtCoex->bC2hBtInfoReqSent) { | ||
9788 | if (BT_IsBtDisabled(padapter)) { | ||
9789 | pBtCoex->c2hBtInfo = BT_INFO_STATE_DISABLED; | ||
9790 | } else { | ||
9791 | if (pBtCoex->c2hBtInfo == BT_INFO_STATE_DISABLED) | ||
9792 | pBtCoex->c2hBtInfo = BT_INFO_STATE_NO_CONNECTION; | ||
9793 | } | ||
9794 | |||
9795 | btdm_BTCoexist8723AHandler(padapter); | ||
9796 | } else if (BT_IsBtDisabled(padapter) == true) { | ||
9797 | pBtCoex->c2hBtInfo = BT_INFO_STATE_DISABLED; | ||
9798 | btdm_BTCoexist8723AHandler(padapter); | ||
9799 | } | ||
9800 | |||
9801 | BTDM_QueryBtInformation(padapter); | ||
9802 | } | ||
9803 | |||
9804 | /* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc8723.c ===== */ | ||
9805 | #endif | ||
9806 | |||
9807 | #ifdef __HALBTCCSR1ANT_C__ /* HAL/BTCoexist/HalBtcCsr1Ant.c */ | ||
9808 | /* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtcCsr1Ant.c ===== */ | ||
9809 | |||
9810 | /* local function start with btdm_ */ | ||
9811 | /* extern function start with BTDM_ */ | ||
9812 | |||
9813 | static void BTDM_SetAntenna(struct rtw_adapter *padapter, u8 who) | ||
9814 | { | ||
9815 | } | ||
9816 | |||
9817 | void | ||
9818 | BTDM_SingleAnt( | ||
9819 | struct rtw_adapter *padapter, | ||
9820 | u8 bSingleAntOn, | ||
9821 | u8 bInterruptOn, | ||
9822 | u8 bMultiNAVOn | ||
9823 | ) | ||
9824 | { | ||
9825 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
9826 | u8 H2C_Parameter[3] = {0}; | ||
9827 | |||
9828 | if (pHalData->bt_coexist.BT_Ant_Num != Ant_x1) | ||
9829 | return; | ||
9830 | |||
9831 | H2C_Parameter[2] = 0; | ||
9832 | H2C_Parameter[1] = 0; | ||
9833 | H2C_Parameter[0] = 0; | ||
9834 | |||
9835 | if (bInterruptOn) { | ||
9836 | H2C_Parameter[2] |= 0x02; /* BIT1 */ | ||
9837 | pHalData->bt_coexist.bFWCoexistAllOff = false; | ||
9838 | } | ||
9839 | pHalData->bt_coexist.bInterruptOn = bInterruptOn; | ||
9840 | |||
9841 | if (bSingleAntOn) { | ||
9842 | H2C_Parameter[2] |= 0x10; /* BIT4 */ | ||
9843 | pHalData->bt_coexist.bFWCoexistAllOff = false; | ||
9844 | } | ||
9845 | pHalData->bt_coexist.bSingleAntOn = bSingleAntOn; | ||
9846 | |||
9847 | if (bMultiNAVOn) { | ||
9848 | H2C_Parameter[2] |= 0x20; /* BIT5 */ | ||
9849 | pHalData->bt_coexist.bFWCoexistAllOff = false; | ||
9850 | } | ||
9851 | pHalData->bt_coexist.bMultiNAVOn = bMultiNAVOn; | ||
9852 | |||
9853 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], SingleAntenna =[%s:%s:%s], write 0xe = 0x%x\n", | ||
9854 | bSingleAntOn?"ON":"OFF", bInterruptOn?"ON":"OFF", bMultiNAVOn?"ON":"OFF", | ||
9855 | H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); | ||
9856 | } | ||
9857 | |||
9858 | void BTDM_CheckBTIdleChange1Ant(struct rtw_adapter *padapter) | ||
9859 | { | ||
9860 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
9861 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
9862 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
9863 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
9864 | u8 stateChange = false; | ||
9865 | u32 BT_Polling, Ratio_Act, Ratio_STA; | ||
9866 | u32 BT_Active, BT_State; | ||
9867 | u32 regBTActive = 0, regBTState = 0, regBTPolling = 0; | ||
9868 | |||
9869 | if (!pHalData->bt_coexist.BluetoothCoexist) | ||
9870 | return; | ||
9871 | if (pBtMgnt->ExtConfig.bManualControl) | ||
9872 | return; | ||
9873 | if (pHalData->bt_coexist.BT_CoexistType != BT_CSR_BC8) | ||
9874 | return; | ||
9875 | if (pHalData->bt_coexist.BT_Ant_Num != Ant_x1) | ||
9876 | return; | ||
9877 | |||
9878 | /* The following we only consider CSR BC8 and fw version should be >= 62 */ | ||
9879 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], FirmwareVersion = 0x%x(%d)\n", | ||
9880 | pHalData->FirmwareVersion, pHalData->FirmwareVersion)); | ||
9881 | regBTActive = REG_BT_ACTIVE; | ||
9882 | regBTState = REG_BT_STATE; | ||
9883 | if (pHalData->FirmwareVersion >= FW_VER_BT_REG1) | ||
9884 | regBTPolling = REG_BT_POLLING1; | ||
9885 | else | ||
9886 | regBTPolling = REG_BT_POLLING; | ||
9887 | |||
9888 | BT_Active = rtw_read32(padapter, regBTActive); | ||
9889 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT_Active(0x%x) =%x\n", regBTActive, BT_Active)); | ||
9890 | BT_Active = BT_Active & 0x00ffffff; | ||
9891 | |||
9892 | BT_State = rtw_read32(padapter, regBTState); | ||
9893 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT_State(0x%x) =%x\n", regBTState, BT_State)); | ||
9894 | BT_State = BT_State & 0x00ffffff; | ||
9895 | |||
9896 | BT_Polling = rtw_read32(padapter, regBTPolling); | ||
9897 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT_Polling(0x%x) =%x\n", regBTPolling, BT_Polling)); | ||
9898 | |||
9899 | if (BT_Active == 0xffffffff && BT_State == 0xffffffff && BT_Polling == 0xffffffff) | ||
9900 | return; | ||
9901 | if (BT_Polling == 0) | ||
9902 | return; | ||
9903 | |||
9904 | Ratio_Act = BT_Active*1000/BT_Polling; | ||
9905 | Ratio_STA = BT_State*1000/BT_Polling; | ||
9906 | |||
9907 | pHalData->bt_coexist.Ratio_Tx = Ratio_Act; | ||
9908 | pHalData->bt_coexist.Ratio_PRI = Ratio_STA; | ||
9909 | |||
9910 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], Ratio_Act =%d\n", Ratio_Act)); | ||
9911 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], Ratio_STA =%d\n", Ratio_STA)); | ||
9912 | |||
9913 | if (Ratio_STA < 60 && Ratio_Act < 500) { /* BT PAN idle */ | ||
9914 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_IDLE; | ||
9915 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_DOWNLINK; | ||
9916 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_UPLINK; | ||
9917 | } else { | ||
9918 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_IDLE; | ||
9919 | |||
9920 | if (Ratio_STA) { | ||
9921 | /* Check if BT PAN (under BT 2.1) is uplink or downlink */ | ||
9922 | if ((Ratio_Act/Ratio_STA) < 2) { | ||
9923 | /* BT PAN Uplink */ | ||
9924 | pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic = true; | ||
9925 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_UPLINK; | ||
9926 | pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic = false; | ||
9927 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_DOWNLINK; | ||
9928 | } else { | ||
9929 | /* BT PAN downlink */ | ||
9930 | pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic = false; | ||
9931 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_UPLINK; | ||
9932 | pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic = true; | ||
9933 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_DOWNLINK; | ||
9934 | } | ||
9935 | } else { | ||
9936 | /* BT PAN downlink */ | ||
9937 | pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic = false; | ||
9938 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_UPLINK; | ||
9939 | pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic = true; | ||
9940 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_DOWNLINK; | ||
9941 | } | ||
9942 | } | ||
9943 | |||
9944 | /* Check BT is idle or not */ | ||
9945 | if (pBtMgnt->ExtConfig.NumberOfHandle == 0 && | ||
9946 | pBtMgnt->ExtConfig.NumberOfSCO == 0) { | ||
9947 | pBtMgnt->ExtConfig.bBTBusy = false; | ||
9948 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_IDLE; | ||
9949 | } else { | ||
9950 | if (Ratio_STA < 60) { | ||
9951 | pBtMgnt->ExtConfig.bBTBusy = false; | ||
9952 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_IDLE; | ||
9953 | } else { | ||
9954 | pBtMgnt->ExtConfig.bBTBusy = true; | ||
9955 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_IDLE; | ||
9956 | } | ||
9957 | } | ||
9958 | |||
9959 | if (pBtMgnt->ExtConfig.NumberOfHandle == 0 && | ||
9960 | pBtMgnt->ExtConfig.NumberOfSCO == 0) { | ||
9961 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_RSSI_LOW; | ||
9962 | pBtMgnt->ExtConfig.MIN_BT_RSSI = 0; | ||
9963 | BTDM_SetAntenna(padapter, BTDM_ANT_BT_IDLE); | ||
9964 | } else { | ||
9965 | if (pBtMgnt->ExtConfig.MIN_BT_RSSI <= -5) { | ||
9966 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_RSSI_LOW; | ||
9967 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], core stack notify bt rssi Low\n")); | ||
9968 | } else { | ||
9969 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_RSSI_LOW; | ||
9970 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], core stack notify bt rssi Normal\n")); | ||
9971 | } | ||
9972 | } | ||
9973 | |||
9974 | if (pHalData->bt_coexist.bBTBusyTraffic != pBtMgnt->ExtConfig.bBTBusy) { | ||
9975 | /* BT idle or BT non-idle */ | ||
9976 | pHalData->bt_coexist.bBTBusyTraffic = pBtMgnt->ExtConfig.bBTBusy; | ||
9977 | stateChange = true; | ||
9978 | } | ||
9979 | |||
9980 | if (stateChange) { | ||
9981 | if (!pBtMgnt->ExtConfig.bBTBusy) | ||
9982 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT is idle or disable\n")); | ||
9983 | else | ||
9984 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT is non-idle\n")); | ||
9985 | } | ||
9986 | if (!pBtMgnt->ExtConfig.bBTBusy) { | ||
9987 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT is idle or disable\n")); | ||
9988 | if (check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING|WIFI_SITE_MONITOR) == true) | ||
9989 | BTDM_SetAntenna(padapter, BTDM_ANT_WIFI); | ||
9990 | } | ||
9991 | } | ||
9992 | |||
9993 | /* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr1Ant.c ===== */ | ||
9994 | #endif | ||
9995 | |||
9996 | #ifdef __HALBTCCSR2ANT_C__ /* HAL/BTCoexist/HalBtcCsr2Ant.c */ | ||
9997 | /* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtcCsr2Ant.c ===== */ | ||
9998 | |||
9999 | /* local function start with btdm_ */ | ||
10000 | |||
10001 | /* Note: */ | ||
10002 | /* In the following, FW should be done before SW mechanism. */ | ||
10003 | /* BTDM_Balance(), BTDM_DiminishWiFi(), BT_NAV() should be done */ | ||
10004 | /* before BTDM_AGCTable(), BTDM_BBBackOffLevel(), btdm_DacSwing(). */ | ||
10005 | |||
10006 | /* extern function start with BTDM_ */ | ||
10007 | |||
10008 | void | ||
10009 | BTDM_DiminishWiFi( | ||
10010 | struct rtw_adapter *padapter, | ||
10011 | u8 bDACOn, | ||
10012 | u8 bInterruptOn, | ||
10013 | u8 DACSwingLevel, | ||
10014 | u8 bNAVOn | ||
10015 | ) | ||
10016 | { | ||
10017 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10018 | u8 H2C_Parameter[3] = {0}; | ||
10019 | |||
10020 | if (pHalData->bt_coexist.BT_Ant_Num != Ant_x2) | ||
10021 | return; | ||
10022 | |||
10023 | if ((pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT_RSSI_LOW) && | ||
10024 | (DACSwingLevel == 0x20)) { | ||
10025 | RTPRINT(FBT, BT_TRACE, ("[BT]DiminishWiFi 0x20 original, but set 0x18 for Low RSSI!\n")); | ||
10026 | DACSwingLevel = 0x18; | ||
10027 | } | ||
10028 | |||
10029 | H2C_Parameter[2] = 0; | ||
10030 | H2C_Parameter[1] = DACSwingLevel; | ||
10031 | H2C_Parameter[0] = 0; | ||
10032 | if (bDACOn) { | ||
10033 | H2C_Parameter[2] |= 0x01; /* BIT0 */ | ||
10034 | if (bInterruptOn) | ||
10035 | H2C_Parameter[2] |= 0x02; /* BIT1 */ | ||
10036 | pHalData->bt_coexist.bFWCoexistAllOff = false; | ||
10037 | } | ||
10038 | if (bNAVOn) { | ||
10039 | H2C_Parameter[2] |= 0x08; /* BIT3 */ | ||
10040 | pHalData->bt_coexist.bFWCoexistAllOff = false; | ||
10041 | } | ||
10042 | |||
10043 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], bDACOn = %s, bInterruptOn = %s, write 0xe = 0x%x\n", | ||
10044 | bDACOn?"ON":"OFF", bInterruptOn?"ON":"OFF", | ||
10045 | H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); | ||
10046 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], bNAVOn = %s\n", | ||
10047 | bNAVOn?"ON":"OFF")); | ||
10048 | } | ||
10049 | |||
10050 | /* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr2Ant.c ===== */ | ||
10051 | #endif | ||
10052 | |||
10053 | #ifdef __HALBTCOEXIST_C__ /* HAL/BTCoexist/HalBtCoexist.c */ | ||
10054 | /* ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtCoexist.c ===== */ | ||
10055 | |||
10056 | /* local function */ | ||
10057 | static void btdm_ResetFWCoexState(struct rtw_adapter *padapter) | ||
10058 | { | ||
10059 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10060 | |||
10061 | pHalData->bt_coexist.CurrentState = 0; | ||
10062 | pHalData->bt_coexist.PreviousState = 0; | ||
10063 | } | ||
10064 | |||
10065 | static void btdm_InitBtCoexistDM(struct rtw_adapter *padapter) | ||
10066 | { | ||
10067 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10068 | |||
10069 | /* 20100415 Joseph: Restore RF register 0x1E and 0x1F value for further usage. */ | ||
10070 | pHalData->bt_coexist.BtRfRegOrigin1E = PHY_QueryRFReg(padapter, PathA, RF_RCK1, bRFRegOffsetMask); | ||
10071 | pHalData->bt_coexist.BtRfRegOrigin1F = PHY_QueryRFReg(padapter, PathA, RF_RCK2, 0xf0); | ||
10072 | |||
10073 | pHalData->bt_coexist.CurrentState = 0; | ||
10074 | pHalData->bt_coexist.PreviousState = 0; | ||
10075 | |||
10076 | BTDM_8723AInit(padapter); | ||
10077 | pHalData->bt_coexist.bInitlized = true; | ||
10078 | } | ||
10079 | |||
10080 | /* */ | ||
10081 | /* extern function */ | ||
10082 | /* */ | ||
10083 | void BTDM_CheckAntSelMode(struct rtw_adapter *padapter) | ||
10084 | { | ||
10085 | } | ||
10086 | |||
10087 | void BTDM_FwC2hBtRssi(struct rtw_adapter *padapter, u8 *tmpBuf) | ||
10088 | { | ||
10089 | BTDM_FwC2hBtRssi8723A(padapter, tmpBuf); | ||
10090 | } | ||
10091 | |||
10092 | void BTDM_FwC2hBtInfo(struct rtw_adapter *padapter, u8 *tmpBuf, u8 length) | ||
10093 | { | ||
10094 | BTDM_FwC2hBtInfo8723A(padapter, tmpBuf, length); | ||
10095 | } | ||
10096 | |||
10097 | void BTDM_DisplayBtCoexInfo(struct rtw_adapter *padapter) | ||
10098 | { | ||
10099 | BTDM_Display8723ABtCoexInfo(padapter); | ||
10100 | } | ||
10101 | |||
10102 | void BTDM_RejectAPAggregatedPacket(struct rtw_adapter *padapter, u8 bReject) | ||
10103 | { | ||
10104 | } | ||
10105 | |||
10106 | u8 BTDM_IsHT40(struct rtw_adapter *padapter) | ||
10107 | { | ||
10108 | u8 isht40 = true; | ||
10109 | enum ht_channel_width bw; | ||
10110 | |||
10111 | bw = padapter->mlmeextpriv.cur_bwmode; | ||
10112 | |||
10113 | if (bw == HT_CHANNEL_WIDTH_20) | ||
10114 | isht40 = false; | ||
10115 | else if (bw == HT_CHANNEL_WIDTH_40) | ||
10116 | isht40 = true; | ||
10117 | |||
10118 | return isht40; | ||
10119 | } | ||
10120 | |||
10121 | u8 BTDM_Legacy(struct rtw_adapter *padapter) | ||
10122 | { | ||
10123 | struct mlme_ext_priv *pmlmeext; | ||
10124 | u8 isLegacy = false; | ||
10125 | |||
10126 | pmlmeext = &padapter->mlmeextpriv; | ||
10127 | if ((pmlmeext->cur_wireless_mode == WIRELESS_11B) || | ||
10128 | (pmlmeext->cur_wireless_mode == WIRELESS_11G) || | ||
10129 | (pmlmeext->cur_wireless_mode == WIRELESS_11BG)) | ||
10130 | isLegacy = true; | ||
10131 | |||
10132 | return isLegacy; | ||
10133 | } | ||
10134 | |||
10135 | void BTDM_CheckWiFiState(struct rtw_adapter *padapter) | ||
10136 | { | ||
10137 | struct hal_data_8723a *pHalData; | ||
10138 | struct mlme_priv *pmlmepriv; | ||
10139 | struct bt_30info *pBTInfo; | ||
10140 | struct bt_mgnt *pBtMgnt; | ||
10141 | |||
10142 | pHalData = GET_HAL_DATA(padapter); | ||
10143 | pmlmepriv = &padapter->mlmepriv; | ||
10144 | pBTInfo = GET_BT_INFO(padapter); | ||
10145 | pBtMgnt = &pBTInfo->BtMgnt; | ||
10146 | |||
10147 | if (pmlmepriv->LinkDetectInfo.bBusyTraffic) { | ||
10148 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_IDLE; | ||
10149 | |||
10150 | if (pmlmepriv->LinkDetectInfo.bTxBusyTraffic) | ||
10151 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_UPLINK; | ||
10152 | else | ||
10153 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_UPLINK; | ||
10154 | |||
10155 | if (pmlmepriv->LinkDetectInfo.bRxBusyTraffic) | ||
10156 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_DOWNLINK; | ||
10157 | else | ||
10158 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_DOWNLINK; | ||
10159 | } else { | ||
10160 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_IDLE; | ||
10161 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_UPLINK; | ||
10162 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_DOWNLINK; | ||
10163 | } | ||
10164 | |||
10165 | if (BTDM_Legacy(padapter)) { | ||
10166 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_LEGACY; | ||
10167 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT20; | ||
10168 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT40; | ||
10169 | } else { | ||
10170 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_LEGACY; | ||
10171 | if (BTDM_IsHT40(padapter)) { | ||
10172 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_HT40; | ||
10173 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT20; | ||
10174 | } else { | ||
10175 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_HT20; | ||
10176 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT40; | ||
10177 | } | ||
10178 | } | ||
10179 | |||
10180 | if (pBtMgnt->BtOperationOn) | ||
10181 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT30; | ||
10182 | else | ||
10183 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT30; | ||
10184 | } | ||
10185 | |||
10186 | s32 BTDM_GetRxSS(struct rtw_adapter *padapter) | ||
10187 | { | ||
10188 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
10189 | struct mlme_priv *pmlmepriv; | ||
10190 | struct hal_data_8723a *pHalData; | ||
10191 | s32 UndecoratedSmoothedPWDB = 0; | ||
10192 | |||
10193 | pmlmepriv = &padapter->mlmepriv; | ||
10194 | pHalData = GET_HAL_DATA(padapter); | ||
10195 | |||
10196 | if (check_fwstate(pmlmepriv, _FW_LINKED)) { | ||
10197 | UndecoratedSmoothedPWDB = GET_UNDECORATED_AVERAGE_RSSI(padapter); | ||
10198 | } else { /* associated entry pwdb */ | ||
10199 | UndecoratedSmoothedPWDB = pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB; | ||
10200 | /* pHalData->BT_EntryMinUndecoratedSmoothedPWDB */ | ||
10201 | } | ||
10202 | RTPRINT(FBT, BT_TRACE, ("BTDM_GetRxSS() = %d\n", UndecoratedSmoothedPWDB)); | ||
10203 | return UndecoratedSmoothedPWDB; | ||
10204 | } | ||
10205 | |||
10206 | static s32 BTDM_GetRxBeaconSS(struct rtw_adapter *padapter) | ||
10207 | { | ||
10208 | /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */ | ||
10209 | struct mlme_priv *pmlmepriv; | ||
10210 | struct hal_data_8723a *pHalData; | ||
10211 | s32 pwdbBeacon = 0; | ||
10212 | |||
10213 | pmlmepriv = &padapter->mlmepriv; | ||
10214 | pHalData = GET_HAL_DATA(padapter); | ||
10215 | |||
10216 | if (check_fwstate(pmlmepriv, _FW_LINKED)) { | ||
10217 | /* pwdbBeacon = pHalData->dmpriv.UndecoratedSmoothedBeacon; */ | ||
10218 | pwdbBeacon = pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB; | ||
10219 | } | ||
10220 | RTPRINT(FBT, BT_TRACE, ("BTDM_GetRxBeaconSS() = %d\n", pwdbBeacon)); | ||
10221 | return pwdbBeacon; | ||
10222 | } | ||
10223 | |||
10224 | /* Get beacon rssi state */ | ||
10225 | u8 BTDM_CheckCoexBcnRssiState(struct rtw_adapter *padapter, u8 levelNum, | ||
10226 | u8 RssiThresh, u8 RssiThresh1) | ||
10227 | { | ||
10228 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10229 | s32 pwdbBeacon = 0; | ||
10230 | u8 bcnRssiState = 0; | ||
10231 | |||
10232 | pwdbBeacon = BTDM_GetRxBeaconSS(padapter); | ||
10233 | |||
10234 | if (levelNum == 2) { | ||
10235 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM; | ||
10236 | |||
10237 | if ((pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_LOW) || | ||
10238 | (pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_STAY_LOW)) { | ||
10239 | if (pwdbBeacon >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) { | ||
10240 | bcnRssiState = BT_RSSI_STATE_HIGH; | ||
10241 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH; | ||
10242 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW; | ||
10243 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to High\n")); | ||
10244 | } else { | ||
10245 | bcnRssiState = BT_RSSI_STATE_STAY_LOW; | ||
10246 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at Low\n")); | ||
10247 | } | ||
10248 | } else { | ||
10249 | if (pwdbBeacon < RssiThresh) { | ||
10250 | bcnRssiState = BT_RSSI_STATE_LOW; | ||
10251 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_LOW; | ||
10252 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH; | ||
10253 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Low\n")); | ||
10254 | } else { | ||
10255 | bcnRssiState = BT_RSSI_STATE_STAY_HIGH; | ||
10256 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at High\n")); | ||
10257 | } | ||
10258 | } | ||
10259 | } else if (levelNum == 3) { | ||
10260 | if (RssiThresh > RssiThresh1) { | ||
10261 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON thresh error!!\n")); | ||
10262 | return pHalData->bt_coexist.preRssiStateBeacon; | ||
10263 | } | ||
10264 | |||
10265 | if ((pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_LOW) || | ||
10266 | (pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_STAY_LOW)) { | ||
10267 | if (pwdbBeacon >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) { | ||
10268 | bcnRssiState = BT_RSSI_STATE_MEDIUM; | ||
10269 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM; | ||
10270 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW; | ||
10271 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH; | ||
10272 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Medium\n")); | ||
10273 | } else { | ||
10274 | bcnRssiState = BT_RSSI_STATE_STAY_LOW; | ||
10275 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at Low\n")); | ||
10276 | } | ||
10277 | } else if ((pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_MEDIUM) || | ||
10278 | (pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_STAY_MEDIUM)) { | ||
10279 | if (pwdbBeacon >= (RssiThresh1+BT_FW_COEX_THRESH_TOL)) { | ||
10280 | bcnRssiState = BT_RSSI_STATE_HIGH; | ||
10281 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH; | ||
10282 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW; | ||
10283 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM; | ||
10284 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to High\n")); | ||
10285 | } else if (pwdbBeacon < RssiThresh) { | ||
10286 | bcnRssiState = BT_RSSI_STATE_LOW; | ||
10287 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_LOW; | ||
10288 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH; | ||
10289 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM; | ||
10290 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Low\n")); | ||
10291 | } else { | ||
10292 | bcnRssiState = BT_RSSI_STATE_STAY_MEDIUM; | ||
10293 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at Medium\n")); | ||
10294 | } | ||
10295 | } else { | ||
10296 | if (pwdbBeacon < RssiThresh1) { | ||
10297 | bcnRssiState = BT_RSSI_STATE_MEDIUM; | ||
10298 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM; | ||
10299 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH; | ||
10300 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW; | ||
10301 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Medium\n")); | ||
10302 | } else { | ||
10303 | bcnRssiState = BT_RSSI_STATE_STAY_HIGH; | ||
10304 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at High\n")); | ||
10305 | } | ||
10306 | } | ||
10307 | } | ||
10308 | |||
10309 | pHalData->bt_coexist.preRssiStateBeacon = bcnRssiState; | ||
10310 | |||
10311 | return bcnRssiState; | ||
10312 | } | ||
10313 | |||
10314 | u8 BTDM_CheckCoexRSSIState1(struct rtw_adapter *padapter, u8 levelNum, | ||
10315 | u8 RssiThresh, u8 RssiThresh1) | ||
10316 | { | ||
10317 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10318 | s32 UndecoratedSmoothedPWDB = 0; | ||
10319 | u8 btRssiState = 0; | ||
10320 | |||
10321 | UndecoratedSmoothedPWDB = BTDM_GetRxSS(padapter); | ||
10322 | |||
10323 | if (levelNum == 2) { | ||
10324 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; | ||
10325 | |||
10326 | if ((pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_LOW) || | ||
10327 | (pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_STAY_LOW)) { | ||
10328 | if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) { | ||
10329 | btRssiState = BT_RSSI_STATE_HIGH; | ||
10330 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_HIGH; | ||
10331 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW; | ||
10332 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to High\n")); | ||
10333 | } else { | ||
10334 | btRssiState = BT_RSSI_STATE_STAY_LOW; | ||
10335 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at Low\n")); | ||
10336 | } | ||
10337 | } else { | ||
10338 | if (UndecoratedSmoothedPWDB < RssiThresh) { | ||
10339 | btRssiState = BT_RSSI_STATE_LOW; | ||
10340 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_LOW; | ||
10341 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; | ||
10342 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Low\n")); | ||
10343 | } else { | ||
10344 | btRssiState = BT_RSSI_STATE_STAY_HIGH; | ||
10345 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at High\n")); | ||
10346 | } | ||
10347 | } | ||
10348 | } else if (levelNum == 3) { | ||
10349 | if (RssiThresh > RssiThresh1) { | ||
10350 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 thresh error!!\n")); | ||
10351 | return pHalData->bt_coexist.preRssiState1; | ||
10352 | } | ||
10353 | |||
10354 | if ((pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_LOW) || | ||
10355 | (pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_STAY_LOW)) { | ||
10356 | if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) { | ||
10357 | btRssiState = BT_RSSI_STATE_MEDIUM; | ||
10358 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; | ||
10359 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW; | ||
10360 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; | ||
10361 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Medium\n")); | ||
10362 | } else { | ||
10363 | btRssiState = BT_RSSI_STATE_STAY_LOW; | ||
10364 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at Low\n")); | ||
10365 | } | ||
10366 | } else if ((pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_MEDIUM) || | ||
10367 | (pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_STAY_MEDIUM)) { | ||
10368 | if (UndecoratedSmoothedPWDB >= (RssiThresh1+BT_FW_COEX_THRESH_TOL)) { | ||
10369 | btRssiState = BT_RSSI_STATE_HIGH; | ||
10370 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_HIGH; | ||
10371 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW; | ||
10372 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; | ||
10373 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to High\n")); | ||
10374 | } else if (UndecoratedSmoothedPWDB < RssiThresh) { | ||
10375 | btRssiState = BT_RSSI_STATE_LOW; | ||
10376 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_LOW; | ||
10377 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; | ||
10378 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; | ||
10379 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Low\n")); | ||
10380 | } else { | ||
10381 | btRssiState = BT_RSSI_STATE_STAY_MEDIUM; | ||
10382 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at Medium\n")); | ||
10383 | } | ||
10384 | } else { | ||
10385 | if (UndecoratedSmoothedPWDB < RssiThresh1) { | ||
10386 | btRssiState = BT_RSSI_STATE_MEDIUM; | ||
10387 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; | ||
10388 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; | ||
10389 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW; | ||
10390 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Medium\n")); | ||
10391 | } else { | ||
10392 | btRssiState = BT_RSSI_STATE_STAY_HIGH; | ||
10393 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at High\n")); | ||
10394 | } | ||
10395 | } | ||
10396 | } | ||
10397 | |||
10398 | pHalData->bt_coexist.preRssiState1 = btRssiState; | ||
10399 | |||
10400 | return btRssiState; | ||
10401 | } | ||
10402 | |||
10403 | u8 BTDM_CheckCoexRSSIState(struct rtw_adapter *padapter, u8 levelNum, | ||
10404 | u8 RssiThresh, u8 RssiThresh1) | ||
10405 | { | ||
10406 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10407 | s32 UndecoratedSmoothedPWDB = 0; | ||
10408 | u8 btRssiState = 0; | ||
10409 | |||
10410 | UndecoratedSmoothedPWDB = BTDM_GetRxSS(padapter); | ||
10411 | |||
10412 | if (levelNum == 2) { | ||
10413 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; | ||
10414 | |||
10415 | if ((pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_LOW) || | ||
10416 | (pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_STAY_LOW)) { | ||
10417 | if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) { | ||
10418 | btRssiState = BT_RSSI_STATE_HIGH; | ||
10419 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_HIGH; | ||
10420 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW; | ||
10421 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to High\n")); | ||
10422 | } else { | ||
10423 | btRssiState = BT_RSSI_STATE_STAY_LOW; | ||
10424 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at Low\n")); | ||
10425 | } | ||
10426 | } else { | ||
10427 | if (UndecoratedSmoothedPWDB < RssiThresh) { | ||
10428 | btRssiState = BT_RSSI_STATE_LOW; | ||
10429 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_LOW; | ||
10430 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; | ||
10431 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Low\n")); | ||
10432 | } else { | ||
10433 | btRssiState = BT_RSSI_STATE_STAY_HIGH; | ||
10434 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at High\n")); | ||
10435 | } | ||
10436 | } | ||
10437 | } else if (levelNum == 3) { | ||
10438 | if (RssiThresh > RssiThresh1) { | ||
10439 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI thresh error!!\n")); | ||
10440 | return pHalData->bt_coexist.preRssiState; | ||
10441 | } | ||
10442 | |||
10443 | if ((pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_LOW) || | ||
10444 | (pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_STAY_LOW)) { | ||
10445 | if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) { | ||
10446 | btRssiState = BT_RSSI_STATE_MEDIUM; | ||
10447 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_MEDIUM; | ||
10448 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW; | ||
10449 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; | ||
10450 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Medium\n")); | ||
10451 | } else { | ||
10452 | btRssiState = BT_RSSI_STATE_STAY_LOW; | ||
10453 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at Low\n")); | ||
10454 | } | ||
10455 | } else if ((pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_MEDIUM) || | ||
10456 | (pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_STAY_MEDIUM)) { | ||
10457 | if (UndecoratedSmoothedPWDB >= (RssiThresh1+BT_FW_COEX_THRESH_TOL)) { | ||
10458 | btRssiState = BT_RSSI_STATE_HIGH; | ||
10459 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_HIGH; | ||
10460 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW; | ||
10461 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; | ||
10462 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to High\n")); | ||
10463 | } else if (UndecoratedSmoothedPWDB < RssiThresh) { | ||
10464 | btRssiState = BT_RSSI_STATE_LOW; | ||
10465 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_LOW; | ||
10466 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; | ||
10467 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; | ||
10468 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Low\n")); | ||
10469 | } else { | ||
10470 | btRssiState = BT_RSSI_STATE_STAY_MEDIUM; | ||
10471 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at Medium\n")); | ||
10472 | } | ||
10473 | } else { | ||
10474 | if (UndecoratedSmoothedPWDB < RssiThresh1) { | ||
10475 | btRssiState = BT_RSSI_STATE_MEDIUM; | ||
10476 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_MEDIUM; | ||
10477 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; | ||
10478 | pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW; | ||
10479 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Medium\n")); | ||
10480 | } else { | ||
10481 | btRssiState = BT_RSSI_STATE_STAY_HIGH; | ||
10482 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at High\n")); | ||
10483 | } | ||
10484 | } | ||
10485 | } | ||
10486 | |||
10487 | pHalData->bt_coexist.preRssiState = btRssiState; | ||
10488 | |||
10489 | return btRssiState; | ||
10490 | } | ||
10491 | |||
10492 | u8 BTDM_DisableEDCATurbo(struct rtw_adapter *padapter) | ||
10493 | { | ||
10494 | struct bt_mgnt *pBtMgnt; | ||
10495 | struct hal_data_8723a *pHalData; | ||
10496 | u8 bBtChangeEDCA = false; | ||
10497 | u32 EDCA_BT_BE = 0x5ea42b, cur_EDCA_reg; | ||
10498 | u8 bRet = false; | ||
10499 | |||
10500 | pHalData = GET_HAL_DATA(padapter); | ||
10501 | pBtMgnt = &pHalData->BtInfo.BtMgnt; | ||
10502 | |||
10503 | if (!pHalData->bt_coexist.BluetoothCoexist) { | ||
10504 | bRet = false; | ||
10505 | pHalData->bt_coexist.lastBtEdca = 0; | ||
10506 | return bRet; | ||
10507 | } | ||
10508 | if (!((pBtMgnt->bSupportProfile) || | ||
10509 | (pHalData->bt_coexist.BT_CoexistType == BT_CSR_BC8))) { | ||
10510 | bRet = false; | ||
10511 | pHalData->bt_coexist.lastBtEdca = 0; | ||
10512 | return bRet; | ||
10513 | } | ||
10514 | |||
10515 | if (BT_1Ant(padapter)) { | ||
10516 | bRet = false; | ||
10517 | pHalData->bt_coexist.lastBtEdca = 0; | ||
10518 | return bRet; | ||
10519 | } | ||
10520 | |||
10521 | if (pHalData->bt_coexist.exec_cnt < 3) | ||
10522 | pHalData->bt_coexist.exec_cnt++; | ||
10523 | else | ||
10524 | pHalData->bt_coexist.bEDCAInitialized = true; | ||
10525 | |||
10526 | /* When BT is non idle */ | ||
10527 | if (!(pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT_IDLE)) { | ||
10528 | RTPRINT(FBT, BT_TRACE, ("BT state non idle, set bt EDCA\n")); | ||
10529 | |||
10530 | /* aggr_num = 0x0909; */ | ||
10531 | if (pHalData->odmpriv.DM_EDCA_Table.bCurrentTurboEDCA) { | ||
10532 | bBtChangeEDCA = true; | ||
10533 | pHalData->odmpriv.DM_EDCA_Table.bCurrentTurboEDCA = false; | ||
10534 | pHalData->dmpriv.prv_traffic_idx = 3; | ||
10535 | } | ||
10536 | cur_EDCA_reg = rtw_read32(padapter, REG_EDCA_BE_PARAM); | ||
10537 | |||
10538 | if (cur_EDCA_reg != EDCA_BT_BE) | ||
10539 | bBtChangeEDCA = true; | ||
10540 | if (bBtChangeEDCA || !pHalData->bt_coexist.bEDCAInitialized) { | ||
10541 | rtw_write32(padapter, REG_EDCA_BE_PARAM, EDCA_BT_BE); | ||
10542 | pHalData->bt_coexist.lastBtEdca = EDCA_BT_BE; | ||
10543 | } | ||
10544 | bRet = true; | ||
10545 | } else { | ||
10546 | RTPRINT(FBT, BT_TRACE, ("BT state idle, set original EDCA\n")); | ||
10547 | pHalData->bt_coexist.lastBtEdca = 0; | ||
10548 | bRet = false; | ||
10549 | } | ||
10550 | return bRet; | ||
10551 | } | ||
10552 | |||
10553 | void | ||
10554 | BTDM_Balance( | ||
10555 | struct rtw_adapter *padapter, | ||
10556 | u8 bBalanceOn, | ||
10557 | u8 ms0, | ||
10558 | u8 ms1 | ||
10559 | ) | ||
10560 | { | ||
10561 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10562 | u8 H2C_Parameter[3] = {0}; | ||
10563 | |||
10564 | if (bBalanceOn) { | ||
10565 | H2C_Parameter[2] = 1; | ||
10566 | H2C_Parameter[1] = ms1; | ||
10567 | H2C_Parameter[0] = ms0; | ||
10568 | pHalData->bt_coexist.bFWCoexistAllOff = false; | ||
10569 | } else { | ||
10570 | H2C_Parameter[2] = 0; | ||
10571 | H2C_Parameter[1] = 0; | ||
10572 | H2C_Parameter[0] = 0; | ||
10573 | } | ||
10574 | pHalData->bt_coexist.bBalanceOn = bBalanceOn; | ||
10575 | |||
10576 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], Balance =[%s:%dms:%dms], write 0xc = 0x%x\n", | ||
10577 | bBalanceOn?"ON":"OFF", ms0, ms1, | ||
10578 | H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2])); | ||
10579 | |||
10580 | FillH2CCmd(padapter, 0xc, 3, H2C_Parameter); | ||
10581 | } | ||
10582 | |||
10583 | void BTDM_AGCTable(struct rtw_adapter *padapter, u8 type) | ||
10584 | { | ||
10585 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10586 | if (type == BT_AGCTABLE_OFF) { | ||
10587 | RTPRINT(FBT, BT_TRACE, ("[BT]AGCTable Off!\n")); | ||
10588 | rtw_write32(padapter, 0xc78, 0x641c0001); | ||
10589 | rtw_write32(padapter, 0xc78, 0x631d0001); | ||
10590 | rtw_write32(padapter, 0xc78, 0x621e0001); | ||
10591 | rtw_write32(padapter, 0xc78, 0x611f0001); | ||
10592 | rtw_write32(padapter, 0xc78, 0x60200001); | ||
10593 | |||
10594 | PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x32000); | ||
10595 | PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x71000); | ||
10596 | PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0xb0000); | ||
10597 | PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0xfc000); | ||
10598 | PHY_SetRFReg(padapter, PathA, RF_RX_G1, bRFRegOffsetMask, 0x30355); | ||
10599 | |||
10600 | pHalData->bt_coexist.b8723aAgcTableOn = false; | ||
10601 | } else if (type == BT_AGCTABLE_ON) { | ||
10602 | RTPRINT(FBT, BT_TRACE, ("[BT]AGCTable On!\n")); | ||
10603 | rtw_write32(padapter, 0xc78, 0x4e1c0001); | ||
10604 | rtw_write32(padapter, 0xc78, 0x4d1d0001); | ||
10605 | rtw_write32(padapter, 0xc78, 0x4c1e0001); | ||
10606 | rtw_write32(padapter, 0xc78, 0x4b1f0001); | ||
10607 | rtw_write32(padapter, 0xc78, 0x4a200001); | ||
10608 | |||
10609 | PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0xdc000); | ||
10610 | PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x90000); | ||
10611 | PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x51000); | ||
10612 | PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x12000); | ||
10613 | PHY_SetRFReg(padapter, PathA, RF_RX_G1, bRFRegOffsetMask, 0x00355); | ||
10614 | |||
10615 | pHalData->bt_coexist.b8723aAgcTableOn = true; | ||
10616 | |||
10617 | pHalData->bt_coexist.bSWCoexistAllOff = false; | ||
10618 | } | ||
10619 | } | ||
10620 | |||
10621 | void BTDM_BBBackOffLevel(struct rtw_adapter *padapter, u8 type) | ||
10622 | { | ||
10623 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10624 | |||
10625 | if (type == BT_BB_BACKOFF_OFF) { | ||
10626 | RTPRINT(FBT, BT_TRACE, ("[BT]BBBackOffLevel Off!\n")); | ||
10627 | rtw_write32(padapter, 0xc04, 0x3a05611); | ||
10628 | } else if (type == BT_BB_BACKOFF_ON) { | ||
10629 | RTPRINT(FBT, BT_TRACE, ("[BT]BBBackOffLevel On!\n")); | ||
10630 | rtw_write32(padapter, 0xc04, 0x3a07611); | ||
10631 | pHalData->bt_coexist.bSWCoexistAllOff = false; | ||
10632 | } | ||
10633 | } | ||
10634 | |||
10635 | void BTDM_FWCoexAllOff(struct rtw_adapter *padapter) | ||
10636 | { | ||
10637 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);; | ||
10638 | |||
10639 | RTPRINT(FBT, BT_TRACE, ("BTDM_FWCoexAllOff()\n")); | ||
10640 | if (pHalData->bt_coexist.bFWCoexistAllOff) | ||
10641 | return; | ||
10642 | RTPRINT(FBT, BT_TRACE, ("BTDM_FWCoexAllOff(), real Do\n")); | ||
10643 | |||
10644 | BTDM_FWCoexAllOff8723A(padapter); | ||
10645 | |||
10646 | pHalData->bt_coexist.bFWCoexistAllOff = true; | ||
10647 | } | ||
10648 | |||
10649 | void BTDM_SWCoexAllOff(struct rtw_adapter *padapter) | ||
10650 | { | ||
10651 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);; | ||
10652 | |||
10653 | RTPRINT(FBT, BT_TRACE, ("BTDM_SWCoexAllOff()\n")); | ||
10654 | if (pHalData->bt_coexist.bSWCoexistAllOff) | ||
10655 | return; | ||
10656 | RTPRINT(FBT, BT_TRACE, ("BTDM_SWCoexAllOff(), real Do\n")); | ||
10657 | BTDM_SWCoexAllOff8723A(padapter); | ||
10658 | |||
10659 | pHalData->bt_coexist.bSWCoexistAllOff = true; | ||
10660 | } | ||
10661 | |||
10662 | void BTDM_HWCoexAllOff(struct rtw_adapter *padapter) | ||
10663 | { | ||
10664 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);; | ||
10665 | |||
10666 | RTPRINT(FBT, BT_TRACE, ("BTDM_HWCoexAllOff()\n")); | ||
10667 | if (pHalData->bt_coexist.bHWCoexistAllOff) | ||
10668 | return; | ||
10669 | RTPRINT(FBT, BT_TRACE, ("BTDM_HWCoexAllOff(), real Do\n")); | ||
10670 | |||
10671 | BTDM_HWCoexAllOff8723A(padapter); | ||
10672 | |||
10673 | pHalData->bt_coexist.bHWCoexistAllOff = true; | ||
10674 | } | ||
10675 | |||
10676 | void BTDM_CoexAllOff(struct rtw_adapter *padapter) | ||
10677 | { | ||
10678 | BTDM_FWCoexAllOff(padapter); | ||
10679 | BTDM_SWCoexAllOff(padapter); | ||
10680 | BTDM_HWCoexAllOff(padapter); | ||
10681 | } | ||
10682 | |||
10683 | void BTDM_TurnOffBtCoexistBeforeEnterIPS(struct rtw_adapter *padapter) | ||
10684 | { | ||
10685 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10686 | struct pwrctrl_priv *ppwrctrl = &padapter->pwrctrlpriv; | ||
10687 | |||
10688 | if (!pHalData->bt_coexist.BluetoothCoexist) | ||
10689 | return; | ||
10690 | |||
10691 | /* 8723 1Ant doesn't need to turn off bt coexist mechanism. */ | ||
10692 | if (BTDM_1Ant8723A(padapter)) | ||
10693 | return; | ||
10694 | |||
10695 | /* Before enter IPS, turn off FW BT Co-exist mechanism */ | ||
10696 | if (ppwrctrl->reg_rfoff == rf_on) { | ||
10697 | RTPRINT(FBT, BT_TRACE, ("[BT][DM], Before enter IPS, turn off all Coexist DM\n")); | ||
10698 | btdm_ResetFWCoexState(padapter); | ||
10699 | BTDM_CoexAllOff(padapter); | ||
10700 | BTDM_SetAntenna(padapter, BTDM_ANT_BT); | ||
10701 | } | ||
10702 | } | ||
10703 | |||
10704 | void BTDM_SignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi, u8 *rssi_bt) | ||
10705 | { | ||
10706 | BTDM_8723ASignalCompensation(padapter, rssi_wifi, rssi_bt); | ||
10707 | } | ||
10708 | |||
10709 | void BTDM_Coexist(struct rtw_adapter *padapter) | ||
10710 | { | ||
10711 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10712 | |||
10713 | if (!pHalData->bt_coexist.BluetoothCoexist) { | ||
10714 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT not exists!!\n")); | ||
10715 | return; | ||
10716 | } | ||
10717 | |||
10718 | if (!pHalData->bt_coexist.bInitlized) { | ||
10719 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], btdm_InitBtCoexistDM()\n")); | ||
10720 | btdm_InitBtCoexistDM(padapter); | ||
10721 | } | ||
10722 | |||
10723 | RTPRINT(FBT, BT_TRACE, ("\n\n[DM][BT], BTDM start!!\n")); | ||
10724 | |||
10725 | BTDM_PWDBMonitor(padapter); | ||
10726 | |||
10727 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], HW type is 8723\n")); | ||
10728 | BTDM_BTCoexist8723A(padapter); | ||
10729 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], BTDM end!!\n\n")); | ||
10730 | } | ||
10731 | |||
10732 | void BTDM_UpdateCoexState(struct rtw_adapter *padapter) | ||
10733 | { | ||
10734 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10735 | |||
10736 | if (!BTDM_IsSameCoexistState(padapter)) { | ||
10737 | RTPRINT(FBT, BT_TRACE, ("[BTCoex], Coexist State[bitMap] change from 0x%"i64fmt"x to 0x%"i64fmt"x, changeBits = 0x%"i64fmt"x\n", | ||
10738 | pHalData->bt_coexist.PreviousState, | ||
10739 | pHalData->bt_coexist.CurrentState, | ||
10740 | (pHalData->bt_coexist.PreviousState^pHalData->bt_coexist.CurrentState))); | ||
10741 | pHalData->bt_coexist.PreviousState = pHalData->bt_coexist.CurrentState; | ||
10742 | } | ||
10743 | } | ||
10744 | |||
10745 | u8 BTDM_IsSameCoexistState(struct rtw_adapter *padapter) | ||
10746 | { | ||
10747 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10748 | |||
10749 | if (pHalData->bt_coexist.PreviousState == pHalData->bt_coexist.CurrentState) { | ||
10750 | return true; | ||
10751 | } else { | ||
10752 | RTPRINT(FBT, BT_TRACE, ("[DM][BT], Coexist state changed!!\n")); | ||
10753 | return false; | ||
10754 | } | ||
10755 | } | ||
10756 | |||
10757 | void BTDM_PWDBMonitor(struct rtw_adapter *padapter) | ||
10758 | { | ||
10759 | struct bt_30info *pBTInfo = GET_BT_INFO(GetDefaultAdapter(padapter)); | ||
10760 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
10761 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10762 | u8 H2C_Parameter[3] = {0}; | ||
10763 | s32 tmpBTEntryMaxPWDB = 0, tmpBTEntryMinPWDB = 0xff; | ||
10764 | u8 i; | ||
10765 | |||
10766 | if (pBtMgnt->BtOperationOn) { | ||
10767 | for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) { | ||
10768 | if (pBTInfo->BtAsocEntry[i].bUsed) { | ||
10769 | if (pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB < tmpBTEntryMinPWDB) | ||
10770 | tmpBTEntryMinPWDB = pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB; | ||
10771 | if (pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB > tmpBTEntryMaxPWDB) | ||
10772 | tmpBTEntryMaxPWDB = pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB; | ||
10773 | /* Report every BT connection (HS mode) RSSI to FW */ | ||
10774 | H2C_Parameter[2] = (u8)(pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB & 0xFF); | ||
10775 | H2C_Parameter[0] = (MAX_FW_SUPPORT_MACID_NUM-1-i); | ||
10776 | RTPRINT(FDM, DM_BT30, ("RSSI report for BT[%d], H2C_Par = 0x%x\n", i, H2C_Parameter[0])); | ||
10777 | FillH2CCmd(padapter, RSSI_SETTING_EID, 3, H2C_Parameter); | ||
10778 | RTPRINT_ADDR(FDM, (DM_PWDB|DM_BT30), ("BT_Entry Mac :"), | ||
10779 | pBTInfo->BtAsocEntry[i].BTRemoteMACAddr) | ||
10780 | RTPRINT(FDM, (DM_PWDB|DM_BT30), | ||
10781 | ("BT rx pwdb[%d] = 0x%x(%d)\n", i, | ||
10782 | pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB, | ||
10783 | pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB)); | ||
10784 | } | ||
10785 | } | ||
10786 | if (tmpBTEntryMaxPWDB != 0) { /* If associated entry is found */ | ||
10787 | pHalData->dmpriv.BT_EntryMaxUndecoratedSmoothedPWDB = tmpBTEntryMaxPWDB; | ||
10788 | RTPRINT(FDM, (DM_PWDB|DM_BT30), ("BT_EntryMaxPWDB = 0x%x(%d)\n", | ||
10789 | tmpBTEntryMaxPWDB, tmpBTEntryMaxPWDB)); | ||
10790 | } else { | ||
10791 | pHalData->dmpriv.BT_EntryMaxUndecoratedSmoothedPWDB = 0; | ||
10792 | } | ||
10793 | if (tmpBTEntryMinPWDB != 0xff) { /* If associated entry is found */ | ||
10794 | pHalData->dmpriv.BT_EntryMinUndecoratedSmoothedPWDB = tmpBTEntryMinPWDB; | ||
10795 | RTPRINT(FDM, (DM_PWDB|DM_BT30), ("BT_EntryMinPWDB = 0x%x(%d)\n", | ||
10796 | tmpBTEntryMinPWDB, tmpBTEntryMinPWDB)); | ||
10797 | } else { | ||
10798 | pHalData->dmpriv.BT_EntryMinUndecoratedSmoothedPWDB = 0; | ||
10799 | } | ||
10800 | } | ||
10801 | } | ||
10802 | |||
10803 | u8 BTDM_IsBTBusy(struct rtw_adapter *padapter) | ||
10804 | { | ||
10805 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
10806 | struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt; | ||
10807 | |||
10808 | if (pBtMgnt->ExtConfig.bBTBusy) | ||
10809 | return true; | ||
10810 | else | ||
10811 | return false; | ||
10812 | } | ||
10813 | |||
10814 | u8 BTDM_IsWifiBusy(struct rtw_adapter *padapter) | ||
10815 | { | ||
10816 | /*PMGNT_INFO pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */ | ||
10817 | struct mlme_priv *pmlmepriv = &GetDefaultAdapter(padapter)->mlmepriv; | ||
10818 | struct bt_30info *pBTInfo = GET_BT_INFO(padapter); | ||
10819 | struct bt_traffic *pBtTraffic = &pBTInfo->BtTraffic; | ||
10820 | |||
10821 | if (pmlmepriv->LinkDetectInfo.bBusyTraffic || | ||
10822 | pBtTraffic->Bt30TrafficStatistics.bTxBusyTraffic || | ||
10823 | pBtTraffic->Bt30TrafficStatistics.bRxBusyTraffic) | ||
10824 | return true; | ||
10825 | else | ||
10826 | return false; | ||
10827 | } | ||
10828 | |||
10829 | u8 BTDM_IsCoexistStateChanged(struct rtw_adapter *padapter) | ||
10830 | { | ||
10831 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10832 | |||
10833 | if (pHalData->bt_coexist.PreviousState == pHalData->bt_coexist.CurrentState) | ||
10834 | return false; | ||
10835 | else | ||
10836 | return true; | ||
10837 | } | ||
10838 | |||
10839 | u8 BTDM_IsWifiUplink(struct rtw_adapter *padapter) | ||
10840 | { | ||
10841 | /*PMGNT_INFO pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */ | ||
10842 | struct mlme_priv *pmlmepriv; | ||
10843 | struct bt_30info *pBTInfo; | ||
10844 | struct bt_traffic *pBtTraffic; | ||
10845 | |||
10846 | pmlmepriv = &padapter->mlmepriv; | ||
10847 | pBTInfo = GET_BT_INFO(padapter); | ||
10848 | pBtTraffic = &pBTInfo->BtTraffic; | ||
10849 | |||
10850 | if ((pmlmepriv->LinkDetectInfo.bTxBusyTraffic) || | ||
10851 | (pBtTraffic->Bt30TrafficStatistics.bTxBusyTraffic)) | ||
10852 | return true; | ||
10853 | else | ||
10854 | return false; | ||
10855 | } | ||
10856 | |||
10857 | u8 BTDM_IsWifiDownlink(struct rtw_adapter *padapter) | ||
10858 | { | ||
10859 | /*PMGNT_INFO pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */ | ||
10860 | struct mlme_priv *pmlmepriv; | ||
10861 | struct bt_30info *pBTInfo; | ||
10862 | struct bt_traffic *pBtTraffic; | ||
10863 | |||
10864 | pmlmepriv = &padapter->mlmepriv; | ||
10865 | pBTInfo = GET_BT_INFO(padapter); | ||
10866 | pBtTraffic = &pBTInfo->BtTraffic; | ||
10867 | |||
10868 | if ((pmlmepriv->LinkDetectInfo.bRxBusyTraffic) || | ||
10869 | (pBtTraffic->Bt30TrafficStatistics.bRxBusyTraffic)) | ||
10870 | return true; | ||
10871 | else | ||
10872 | return false; | ||
10873 | } | ||
10874 | |||
10875 | u8 BTDM_IsBTHSMode(struct rtw_adapter *padapter) | ||
10876 | { | ||
10877 | /*PMGNT_INFO pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */ | ||
10878 | struct hal_data_8723a *pHalData; | ||
10879 | struct bt_mgnt *pBtMgnt; | ||
10880 | |||
10881 | pHalData = GET_HAL_DATA(padapter); | ||
10882 | pBtMgnt = &pHalData->BtInfo.BtMgnt; | ||
10883 | |||
10884 | if (pBtMgnt->BtOperationOn) | ||
10885 | return true; | ||
10886 | else | ||
10887 | return false; | ||
10888 | } | ||
10889 | |||
10890 | u8 BTDM_IsBTUplink(struct rtw_adapter *padapter) | ||
10891 | { | ||
10892 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10893 | |||
10894 | if (pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic) | ||
10895 | return true; | ||
10896 | else | ||
10897 | return false; | ||
10898 | } | ||
10899 | |||
10900 | u8 BTDM_IsBTDownlink(struct rtw_adapter *padapter) | ||
10901 | { | ||
10902 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10903 | |||
10904 | if (pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic) | ||
10905 | return true; | ||
10906 | else | ||
10907 | return false; | ||
10908 | } | ||
10909 | |||
10910 | void BTDM_AdjustForBtOperation(struct rtw_adapter *padapter) | ||
10911 | { | ||
10912 | RTPRINT(FBT, BT_TRACE, ("[BT][DM], BTDM_AdjustForBtOperation()\n")); | ||
10913 | BTDM_AdjustForBtOperation8723A(padapter); | ||
10914 | } | ||
10915 | |||
10916 | void BTDM_SetBtCoexCurrAntNum(struct rtw_adapter *padapter, u8 antNum) | ||
10917 | { | ||
10918 | BTDM_Set8723ABtCoexCurrAntNum(padapter, antNum); | ||
10919 | } | ||
10920 | |||
10921 | void BTDM_ForHalt(struct rtw_adapter *padapter) | ||
10922 | { | ||
10923 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10924 | |||
10925 | if (!pHalData->bt_coexist.BluetoothCoexist) | ||
10926 | return; | ||
10927 | |||
10928 | BTDM_ForHalt8723A(padapter); | ||
10929 | GET_HAL_DATA(padapter)->bt_coexist.bInitlized = false; | ||
10930 | } | ||
10931 | |||
10932 | void BTDM_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType) | ||
10933 | { | ||
10934 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10935 | |||
10936 | if (!pHalData->bt_coexist.BluetoothCoexist) | ||
10937 | return; | ||
10938 | |||
10939 | BTDM_WifiScanNotify8723A(padapter, scanType); | ||
10940 | } | ||
10941 | |||
10942 | void BTDM_WifiAssociateNotify(struct rtw_adapter *padapter, u8 action) | ||
10943 | { | ||
10944 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10945 | |||
10946 | if (!pHalData->bt_coexist.BluetoothCoexist) | ||
10947 | return; | ||
10948 | |||
10949 | BTDM_WifiAssociateNotify8723A(padapter, action); | ||
10950 | } | ||
10951 | |||
10952 | void BTDM_MediaStatusNotify(struct rtw_adapter *padapter, enum rt_media_status mstatus) | ||
10953 | { | ||
10954 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10955 | |||
10956 | if (!pHalData->bt_coexist.BluetoothCoexist) | ||
10957 | return; | ||
10958 | |||
10959 | BTDM_MediaStatusNotify8723A(padapter, mstatus); | ||
10960 | } | ||
10961 | |||
10962 | void BTDM_ForDhcp(struct rtw_adapter *padapter) | ||
10963 | { | ||
10964 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10965 | |||
10966 | if (!pHalData->bt_coexist.BluetoothCoexist) | ||
10967 | return; | ||
10968 | |||
10969 | BTDM_ForDhcp8723A(padapter); | ||
10970 | } | ||
10971 | |||
10972 | void BTDM_ResetActionProfileState(struct rtw_adapter *padapter) | ||
10973 | { | ||
10974 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
10975 | |||
10976 | pHalData->bt_coexist.CurrentState &= ~\ | ||
10977 | (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_A2DP| | ||
10978 | BT_COEX_STATE_PROFILE_PAN|BT_COEX_STATE_PROFILE_SCO); | ||
10979 | } | ||
10980 | |||
10981 | u8 BTDM_IsActionSCO(struct rtw_adapter *padapter) | ||
10982 | { | ||
10983 | struct hal_data_8723a *pHalData; | ||
10984 | struct bt_30info *pBTInfo; | ||
10985 | struct bt_mgnt *pBtMgnt; | ||
10986 | struct bt_dgb *pBtDbg; | ||
10987 | u8 bRet; | ||
10988 | |||
10989 | pHalData = GET_HAL_DATA(padapter); | ||
10990 | pBTInfo = GET_BT_INFO(padapter); | ||
10991 | pBtMgnt = &pBTInfo->BtMgnt; | ||
10992 | pBtDbg = &pBTInfo->BtDbg; | ||
10993 | bRet = false; | ||
10994 | |||
10995 | if (pBtDbg->dbgCtrl) { | ||
10996 | if (pBtDbg->dbgProfile == BT_DBG_PROFILE_SCO) { | ||
10997 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_SCO; | ||
10998 | bRet = true; | ||
10999 | } | ||
11000 | } else { | ||
11001 | if (pBtMgnt->ExtConfig.NumberOfSCO > 0) { | ||
11002 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_SCO; | ||
11003 | bRet = true; | ||
11004 | } | ||
11005 | } | ||
11006 | return bRet; | ||
11007 | } | ||
11008 | |||
11009 | u8 BTDM_IsActionHID(struct rtw_adapter *padapter) | ||
11010 | { | ||
11011 | struct bt_30info *pBTInfo; | ||
11012 | struct hal_data_8723a *pHalData; | ||
11013 | struct bt_mgnt *pBtMgnt; | ||
11014 | struct bt_dgb *pBtDbg; | ||
11015 | u8 bRet; | ||
11016 | |||
11017 | pHalData = GET_HAL_DATA(padapter); | ||
11018 | pBTInfo = GET_BT_INFO(padapter); | ||
11019 | pBtMgnt = &pBTInfo->BtMgnt; | ||
11020 | pBtDbg = &pBTInfo->BtDbg; | ||
11021 | bRet = false; | ||
11022 | |||
11023 | if (pBtDbg->dbgCtrl) { | ||
11024 | if (pBtDbg->dbgProfile == BT_DBG_PROFILE_HID) { | ||
11025 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_HID; | ||
11026 | bRet = true; | ||
11027 | } | ||
11028 | } else { | ||
11029 | if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) && | ||
11030 | pBtMgnt->ExtConfig.NumberOfHandle == 1) { | ||
11031 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_HID; | ||
11032 | bRet = true; | ||
11033 | } | ||
11034 | } | ||
11035 | return bRet; | ||
11036 | } | ||
11037 | |||
11038 | u8 BTDM_IsActionA2DP(struct rtw_adapter *padapter) | ||
11039 | { | ||
11040 | struct hal_data_8723a *pHalData; | ||
11041 | struct bt_30info *pBTInfo; | ||
11042 | struct bt_mgnt *pBtMgnt; | ||
11043 | struct bt_dgb *pBtDbg; | ||
11044 | u8 bRet; | ||
11045 | |||
11046 | pHalData = GET_HAL_DATA(padapter); | ||
11047 | pBTInfo = GET_BT_INFO(padapter); | ||
11048 | pBtMgnt = &pBTInfo->BtMgnt; | ||
11049 | pBtDbg = &pBTInfo->BtDbg; | ||
11050 | bRet = false; | ||
11051 | |||
11052 | if (pBtDbg->dbgCtrl) { | ||
11053 | if (pBtDbg->dbgProfile == BT_DBG_PROFILE_A2DP) { | ||
11054 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_A2DP; | ||
11055 | bRet = true; | ||
11056 | } | ||
11057 | } else { | ||
11058 | if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP) && | ||
11059 | pBtMgnt->ExtConfig.NumberOfHandle == 1) { | ||
11060 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_A2DP; | ||
11061 | bRet = true; | ||
11062 | } | ||
11063 | } | ||
11064 | return bRet; | ||
11065 | } | ||
11066 | |||
11067 | u8 BTDM_IsActionPAN(struct rtw_adapter *padapter) | ||
11068 | { | ||
11069 | struct hal_data_8723a *pHalData; | ||
11070 | struct bt_30info *pBTInfo; | ||
11071 | struct bt_mgnt *pBtMgnt; | ||
11072 | struct bt_dgb *pBtDbg; | ||
11073 | u8 bRet; | ||
11074 | |||
11075 | pHalData = GET_HAL_DATA(padapter); | ||
11076 | pBTInfo = GET_BT_INFO(padapter); | ||
11077 | pBtMgnt = &pBTInfo->BtMgnt; | ||
11078 | pBtDbg = &pBTInfo->BtDbg; | ||
11079 | bRet = false; | ||
11080 | |||
11081 | if (pBtDbg->dbgCtrl) { | ||
11082 | if (pBtDbg->dbgProfile == BT_DBG_PROFILE_PAN) { | ||
11083 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_PAN; | ||
11084 | bRet = true; | ||
11085 | } | ||
11086 | } else { | ||
11087 | if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) && | ||
11088 | pBtMgnt->ExtConfig.NumberOfHandle == 1) { | ||
11089 | pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_PAN; | ||
11090 | bRet = true; | ||
11091 | } | ||
11092 | } | ||
11093 | return bRet; | ||
11094 | } | ||
11095 | |||
11096 | u8 BTDM_IsActionHIDA2DP(struct rtw_adapter *padapter) | ||
11097 | { | ||
11098 | struct hal_data_8723a *pHalData; | ||
11099 | struct bt_30info *pBTInfo; | ||
11100 | struct bt_mgnt *pBtMgnt; | ||
11101 | struct bt_dgb *pBtDbg; | ||
11102 | u8 bRet; | ||
11103 | |||
11104 | pHalData = GET_HAL_DATA(padapter); | ||
11105 | pBTInfo = GET_BT_INFO(padapter); | ||
11106 | pBtMgnt = &pBTInfo->BtMgnt; | ||
11107 | pBtDbg = &pBTInfo->BtDbg; | ||
11108 | bRet = false; | ||
11109 | |||
11110 | if (pBtDbg->dbgCtrl) { | ||
11111 | if (pBtDbg->dbgProfile == BT_DBG_PROFILE_HID_A2DP) { | ||
11112 | pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_A2DP); | ||
11113 | bRet = true; | ||
11114 | } | ||
11115 | } else { | ||
11116 | if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) && | ||
11117 | BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) { | ||
11118 | pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_A2DP); | ||
11119 | bRet = true; | ||
11120 | } | ||
11121 | } | ||
11122 | return bRet; | ||
11123 | } | ||
11124 | |||
11125 | u8 BTDM_IsActionHIDPAN(struct rtw_adapter *padapter) | ||
11126 | { | ||
11127 | struct hal_data_8723a *pHalData; | ||
11128 | struct bt_30info *pBTInfo; | ||
11129 | struct bt_dgb *pBtDbg; | ||
11130 | u8 bRet; | ||
11131 | |||
11132 | pHalData = GET_HAL_DATA(padapter); | ||
11133 | pBTInfo = GET_BT_INFO(padapter); | ||
11134 | pBtDbg = &pBTInfo->BtDbg; | ||
11135 | bRet = false; | ||
11136 | |||
11137 | if (pBtDbg->dbgCtrl) { | ||
11138 | if (pBtDbg->dbgProfile == BT_DBG_PROFILE_HID_PAN) { | ||
11139 | pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_PAN); | ||
11140 | bRet = true; | ||
11141 | } | ||
11142 | } else { | ||
11143 | if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) && | ||
11144 | BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) { | ||
11145 | pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_PAN); | ||
11146 | bRet = true; | ||
11147 | } | ||
11148 | } | ||
11149 | return bRet; | ||
11150 | } | ||
11151 | |||
11152 | u8 BTDM_IsActionPANA2DP(struct rtw_adapter *padapter) | ||
11153 | { | ||
11154 | struct hal_data_8723a *pHalData; | ||
11155 | struct bt_30info *pBTInfo; | ||
11156 | struct bt_dgb *pBtDbg; | ||
11157 | u8 bRet; | ||
11158 | |||
11159 | pHalData = GET_HAL_DATA(padapter); | ||
11160 | pBTInfo = GET_BT_INFO(padapter); | ||
11161 | pBtDbg = &pBTInfo->BtDbg; | ||
11162 | bRet = false; | ||
11163 | |||
11164 | if (pBtDbg->dbgCtrl) { | ||
11165 | if (pBtDbg->dbgProfile == BT_DBG_PROFILE_PAN_A2DP) { | ||
11166 | pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_PAN|BT_COEX_STATE_PROFILE_A2DP); | ||
11167 | bRet = true; | ||
11168 | } | ||
11169 | } else { | ||
11170 | if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) && BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) { | ||
11171 | pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_PAN|BT_COEX_STATE_PROFILE_A2DP); | ||
11172 | bRet = true; | ||
11173 | } | ||
11174 | } | ||
11175 | return bRet; | ||
11176 | } | ||
11177 | |||
11178 | u8 BTDM_IsBtDisabled(struct rtw_adapter *padapter) | ||
11179 | { | ||
11180 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
11181 | |||
11182 | if (pHalData->bt_coexist.bCurBtDisabled) | ||
11183 | return true; | ||
11184 | else | ||
11185 | return false; | ||
11186 | } | ||
11187 | |||
11188 | /* ===== End of sync from SD7 driver HAL/BTCoexist/HalBtCoexist.c ===== */ | ||
11189 | #endif | ||
11190 | |||
11191 | #ifdef __HALBT_C__ /* HAL/HalBT.c */ | ||
11192 | /* ===== Below this line is sync from SD7 driver HAL/HalBT.c ===== */ | ||
11193 | |||
11194 | /* */ | ||
11195 | /*local function */ | ||
11196 | /* */ | ||
11197 | |||
11198 | static void halbt_InitHwConfig8723A(struct rtw_adapter *padapter) | ||
11199 | { | ||
11200 | } | ||
11201 | |||
11202 | /* */ | ||
11203 | /*extern function */ | ||
11204 | /* */ | ||
11205 | u8 HALBT_GetPGAntNum(struct rtw_adapter *padapter) | ||
11206 | { | ||
11207 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
11208 | |||
11209 | return pHalData->bt_coexist.BT_Ant_Num; | ||
11210 | } | ||
11211 | |||
11212 | void HALBT_SetKey(struct rtw_adapter *padapter, u8 EntryNum) | ||
11213 | { | ||
11214 | struct bt_30info *pBTinfo; | ||
11215 | struct bt_asoc_entry *pBtAssocEntry; | ||
11216 | u16 usConfig = 0; | ||
11217 | |||
11218 | pBTinfo = GET_BT_INFO(padapter); | ||
11219 | pBtAssocEntry = &pBTinfo->BtAsocEntry[EntryNum]; | ||
11220 | |||
11221 | pBtAssocEntry->HwCAMIndex = BT_HWCAM_STAR + EntryNum; | ||
11222 | |||
11223 | usConfig = CAM_VALID | (CAM_AES << 2); | ||
11224 | write_cam23a(padapter, pBtAssocEntry->HwCAMIndex, usConfig, pBtAssocEntry->BTRemoteMACAddr, pBtAssocEntry->PTK + TKIP_ENC_KEY_POS); | ||
11225 | } | ||
11226 | |||
11227 | void HALBT_RemoveKey(struct rtw_adapter *padapter, u8 EntryNum) | ||
11228 | { | ||
11229 | struct bt_30info *pBTinfo; | ||
11230 | struct bt_asoc_entry *pBtAssocEntry; | ||
11231 | |||
11232 | pBTinfo = GET_BT_INFO(padapter); | ||
11233 | pBtAssocEntry = &pBTinfo->BtAsocEntry[EntryNum]; | ||
11234 | |||
11235 | if (pBTinfo->BtAsocEntry[EntryNum].HwCAMIndex != 0) { | ||
11236 | /* ToDo : add New HALBT_RemoveKey function !! */ | ||
11237 | if (pBtAssocEntry->HwCAMIndex >= BT_HWCAM_STAR && pBtAssocEntry->HwCAMIndex < HALF_CAM_ENTRY) | ||
11238 | CAM_empty_entry23a(padapter, pBtAssocEntry->HwCAMIndex); | ||
11239 | pBTinfo->BtAsocEntry[EntryNum].HwCAMIndex = 0; | ||
11240 | } | ||
11241 | } | ||
11242 | |||
11243 | void HALBT_InitBTVars8723A(struct rtw_adapter *padapter) | ||
11244 | { | ||
11245 | struct hal_data_8723a *pHalData; | ||
11246 | |||
11247 | pHalData = GET_HAL_DATA(padapter); | ||
11248 | |||
11249 | pHalData->bt_coexist.BluetoothCoexist = pHalData->EEPROMBluetoothCoexist; | ||
11250 | pHalData->bt_coexist.BT_Ant_Num = pHalData->EEPROMBluetoothAntNum; | ||
11251 | pHalData->bt_coexist.BT_CoexistType = pHalData->EEPROMBluetoothType; | ||
11252 | pHalData->bt_coexist.BT_Ant_isolation = pHalData->EEPROMBluetoothAntIsolation; | ||
11253 | pHalData->bt_coexist.bt_radiosharedtype = pHalData->EEPROMBluetoothRadioShared; | ||
11254 | |||
11255 | RT_TRACE(_module_hal_init_c_, _drv_info_, ("BT Coexistance = 0x%x\n", pHalData->bt_coexist.BluetoothCoexist)); | ||
11256 | if (pHalData->bt_coexist.BluetoothCoexist) { | ||
11257 | if (pHalData->bt_coexist.BT_Ant_Num == Ant_x2) { | ||
11258 | BTDM_SetBtCoexCurrAntNum(padapter, 2); | ||
11259 | RT_TRACE(_module_hal_init_c_, _drv_info_, ("BlueTooth BT_Ant_Num = Antx2\n")); | ||
11260 | } else if (pHalData->bt_coexist.BT_Ant_Num == Ant_x1) { | ||
11261 | BTDM_SetBtCoexCurrAntNum(padapter, 1); | ||
11262 | RT_TRACE(_module_hal_init_c_, _drv_info_, ("BlueTooth BT_Ant_Num = Antx1\n")); | ||
11263 | } | ||
11264 | pHalData->bt_coexist.bBTBusyTraffic = false; | ||
11265 | pHalData->bt_coexist.bBTTrafficModeSet = false; | ||
11266 | pHalData->bt_coexist.bBTNonTrafficModeSet = false; | ||
11267 | pHalData->bt_coexist.CurrentState = 0; | ||
11268 | pHalData->bt_coexist.PreviousState = 0; | ||
11269 | |||
11270 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
11271 | ("bt_radiosharedType = 0x%x\n", | ||
11272 | pHalData->bt_coexist.bt_radiosharedtype)); | ||
11273 | } | ||
11274 | } | ||
11275 | |||
11276 | u8 HALBT_IsBTExist(struct rtw_adapter *padapter) | ||
11277 | { | ||
11278 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
11279 | |||
11280 | if (pHalData->bt_coexist.BluetoothCoexist) | ||
11281 | return true; | ||
11282 | else | ||
11283 | return false; | ||
11284 | } | ||
11285 | |||
11286 | u8 HALBT_BTChipType(struct rtw_adapter *padapter) | ||
11287 | { | ||
11288 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
11289 | |||
11290 | return pHalData->bt_coexist.BT_CoexistType; | ||
11291 | } | ||
11292 | |||
11293 | void HALBT_InitHwConfig(struct rtw_adapter *padapter) | ||
11294 | { | ||
11295 | halbt_InitHwConfig8723A(padapter); | ||
11296 | BTDM_Coexist(padapter); | ||
11297 | } | ||
11298 | |||
11299 | void HALBT_SetRtsCtsNoLenLimit(struct rtw_adapter *padapter) | ||
11300 | { | ||
11301 | } | ||
11302 | |||
11303 | /* ===== End of sync from SD7 driver HAL/HalBT.c ===== */ | ||
11304 | #endif | ||
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c new file mode 100644 index 000000000000..0b205e1204fc --- /dev/null +++ b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c | |||
@@ -0,0 +1,845 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | #define _RTL8723A_CMD_C_ | ||
16 | |||
17 | #include <osdep_service.h> | ||
18 | #include <drv_types.h> | ||
19 | #include <recv_osdep.h> | ||
20 | #include <cmd_osdep.h> | ||
21 | #include <mlme_osdep.h> | ||
22 | #include <rtw_ioctl_set.h> | ||
23 | #include <rtl8723a_hal.h> | ||
24 | |||
25 | #define RTL92C_MAX_H2C_BOX_NUMS 4 | ||
26 | #define RTL92C_MAX_CMD_LEN 5 | ||
27 | #define MESSAGE_BOX_SIZE 4 | ||
28 | #define EX_MESSAGE_BOX_SIZE 2 | ||
29 | |||
30 | static u8 _is_fw_read_cmd_down(struct rtw_adapter *padapter, u8 msgbox_num) | ||
31 | { | ||
32 | u8 read_down = false; | ||
33 | int retry_cnts = 100; | ||
34 | u8 valid; | ||
35 | |||
36 | do { | ||
37 | valid = rtw_read8(padapter, REG_HMETFR) & BIT(msgbox_num); | ||
38 | if (0 == valid) | ||
39 | read_down = true; | ||
40 | } while ((!read_down) && (retry_cnts--)); | ||
41 | |||
42 | return read_down; | ||
43 | } | ||
44 | |||
45 | /***************************************** | ||
46 | * H2C Msg format : | ||
47 | *| 31 - 8 |7 | 6 - 0 | | ||
48 | *| h2c_msg |Ext_bit |CMD_ID | | ||
49 | * | ||
50 | ******************************************/ | ||
51 | s32 FillH2CCmd(struct rtw_adapter *padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer) | ||
52 | { | ||
53 | u8 bcmd_down = false; | ||
54 | s32 retry_cnts = 100; | ||
55 | u8 h2c_box_num; | ||
56 | u32 msgbox_addr; | ||
57 | u32 msgbox_ex_addr; | ||
58 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
59 | u32 h2c_cmd = 0; | ||
60 | u16 h2c_cmd_ex = 0; | ||
61 | s32 ret = _FAIL; | ||
62 | |||
63 | padapter = GET_PRIMARY_ADAPTER(padapter); | ||
64 | pHalData = GET_HAL_DATA(padapter); | ||
65 | |||
66 | mutex_lock(&adapter_to_dvobj(padapter)->h2c_fwcmd_mutex); | ||
67 | |||
68 | if (!pCmdBuffer) | ||
69 | goto exit; | ||
70 | if (CmdLen > RTL92C_MAX_CMD_LEN) | ||
71 | goto exit; | ||
72 | if (padapter->bSurpriseRemoved == true) | ||
73 | goto exit; | ||
74 | |||
75 | /* pay attention to if race condition happened in H2C cmd setting. */ | ||
76 | do { | ||
77 | h2c_box_num = pHalData->LastHMEBoxNum; | ||
78 | |||
79 | if (!_is_fw_read_cmd_down(padapter, h2c_box_num)) { | ||
80 | DBG_8723A(" fw read cmd failed...\n"); | ||
81 | goto exit; | ||
82 | } | ||
83 | |||
84 | if (CmdLen <= 3) { | ||
85 | memcpy((u8 *)(&h2c_cmd)+1, pCmdBuffer, CmdLen); | ||
86 | } else { | ||
87 | memcpy((u8 *)(&h2c_cmd_ex), pCmdBuffer, EX_MESSAGE_BOX_SIZE); | ||
88 | memcpy((u8 *)(&h2c_cmd)+1, pCmdBuffer+2, (CmdLen-EX_MESSAGE_BOX_SIZE)); | ||
89 | *(u8 *)(&h2c_cmd) |= BIT(7); | ||
90 | } | ||
91 | |||
92 | *(u8 *)(&h2c_cmd) |= ElementID; | ||
93 | |||
94 | if (h2c_cmd & BIT(7)) { | ||
95 | msgbox_ex_addr = REG_HMEBOX_EXT_0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE); | ||
96 | h2c_cmd_ex = le16_to_cpu(h2c_cmd_ex); | ||
97 | rtw_write16(padapter, msgbox_ex_addr, h2c_cmd_ex); | ||
98 | } | ||
99 | msgbox_addr = REG_HMEBOX_0 + (h2c_box_num * MESSAGE_BOX_SIZE); | ||
100 | h2c_cmd = le32_to_cpu(h2c_cmd); | ||
101 | rtw_write32(padapter, msgbox_addr, h2c_cmd); | ||
102 | |||
103 | bcmd_down = true; | ||
104 | |||
105 | pHalData->LastHMEBoxNum = (h2c_box_num+1) % RTL92C_MAX_H2C_BOX_NUMS; | ||
106 | |||
107 | } while ((!bcmd_down) && (retry_cnts--)); | ||
108 | |||
109 | ret = _SUCCESS; | ||
110 | |||
111 | exit: | ||
112 | mutex_unlock(&adapter_to_dvobj(padapter)->h2c_fwcmd_mutex); | ||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | u8 rtl8723a_set_rssi_cmd(struct rtw_adapter *padapter, u8 *param) | ||
117 | { | ||
118 | u8 res = _SUCCESS; | ||
119 | |||
120 | *((u32 *)param) = cpu_to_le32(*((u32 *)param)); | ||
121 | |||
122 | FillH2CCmd(padapter, RSSI_SETTING_EID, 3, param); | ||
123 | |||
124 | return res; | ||
125 | } | ||
126 | |||
127 | u8 rtl8723a_set_raid_cmd(struct rtw_adapter *padapter, u32 mask, u8 arg) | ||
128 | { | ||
129 | u8 buf[5]; | ||
130 | u8 res = _SUCCESS; | ||
131 | |||
132 | memset(buf, 0, 5); | ||
133 | mask = cpu_to_le32(mask); | ||
134 | memcpy(buf, &mask, 4); | ||
135 | buf[4] = arg; | ||
136 | |||
137 | FillH2CCmd(padapter, MACID_CONFIG_EID, 5, buf); | ||
138 | |||
139 | return res; | ||
140 | |||
141 | } | ||
142 | |||
143 | /* bitmap[0:27] = tx_rate_bitmap */ | ||
144 | /* bitmap[28:31]= Rate Adaptive id */ | ||
145 | /* arg[0:4] = macid */ | ||
146 | /* arg[5] = Short GI */ | ||
147 | void rtl8723a_add_rateatid(struct rtw_adapter *pAdapter, u32 bitmap, u8 arg, u8 rssi_level) | ||
148 | { | ||
149 | struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); | ||
150 | u8 macid = arg&0x1f; | ||
151 | u8 raid = (bitmap>>28) & 0x0f; | ||
152 | |||
153 | bitmap &= 0x0fffffff; | ||
154 | if (rssi_level != DM_RATR_STA_INIT) | ||
155 | bitmap = ODM_Get_Rate_Bitmap23a(&pHalData->odmpriv, macid, bitmap, rssi_level); | ||
156 | |||
157 | bitmap |= ((raid<<28)&0xf0000000); | ||
158 | |||
159 | if (pHalData->fw_ractrl == true) { | ||
160 | rtl8723a_set_raid_cmd(pAdapter, bitmap, arg); | ||
161 | } else { | ||
162 | u8 init_rate, shortGIrate = false; | ||
163 | |||
164 | init_rate = get_highest_rate_idx23a(bitmap&0x0fffffff)&0x3f; | ||
165 | |||
166 | shortGIrate = (arg&BIT(5)) ? true:false; | ||
167 | |||
168 | if (shortGIrate == true) | ||
169 | init_rate |= BIT(6); | ||
170 | |||
171 | rtw_write8(pAdapter, (REG_INIDATA_RATE_SEL+macid), (u8)init_rate); | ||
172 | } | ||
173 | } | ||
174 | |||
175 | void rtl8723a_set_FwPwrMode_cmd(struct rtw_adapter *padapter, u8 Mode) | ||
176 | { | ||
177 | struct setpwrmode_parm H2CSetPwrMode; | ||
178 | struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; | ||
179 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
180 | |||
181 | DBG_8723A("%s: Mode =%d SmartPS =%d UAPSD =%d BcnMode = 0x%02x\n", __FUNCTION__, | ||
182 | Mode, pwrpriv->smart_ps, padapter->registrypriv.uapsd_enable, pwrpriv->bcn_ant_mode); | ||
183 | |||
184 | /* Forece leave RF low power mode for 1T1R to | ||
185 | prevent conficting setting in Fw power */ | ||
186 | /* saving sequence. 2010.06.07. Added by tynli. | ||
187 | Suggested by SD3 yschang. */ | ||
188 | if ((Mode != PS_MODE_ACTIVE) && | ||
189 | (!IS_92C_SERIAL(pHalData->VersionID))) { | ||
190 | ODM_RF_Saving23a(&pHalData->odmpriv, true); | ||
191 | } | ||
192 | |||
193 | H2CSetPwrMode.Mode = Mode; | ||
194 | H2CSetPwrMode.SmartPS = pwrpriv->smart_ps; | ||
195 | H2CSetPwrMode.AwakeInterval = 1; | ||
196 | H2CSetPwrMode.bAllQueueUAPSD = padapter->registrypriv.uapsd_enable; | ||
197 | H2CSetPwrMode.BcnAntMode = pwrpriv->bcn_ant_mode; | ||
198 | |||
199 | FillH2CCmd(padapter, SET_PWRMODE_EID, sizeof(H2CSetPwrMode), (u8 *)&H2CSetPwrMode); | ||
200 | |||
201 | } | ||
202 | |||
203 | static void ConstructBeacon(struct rtw_adapter *padapter, u8 *pframe, u32 *pLength) | ||
204 | { | ||
205 | struct ieee80211_hdr *pwlanhdr; | ||
206 | u16 *fctrl; | ||
207 | u32 rate_len, pktlen; | ||
208 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; | ||
209 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; | ||
210 | struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; | ||
211 | u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
212 | |||
213 | /* DBG_8723A("%s\n", __FUNCTION__); */ | ||
214 | |||
215 | pwlanhdr = (struct ieee80211_hdr *)pframe; | ||
216 | |||
217 | fctrl = &pwlanhdr->frame_control; | ||
218 | *(fctrl) = 0; | ||
219 | |||
220 | memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); | ||
221 | memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); | ||
222 | memcpy(pwlanhdr->addr3, get_my_bssid23a(cur_network), ETH_ALEN); | ||
223 | |||
224 | SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); | ||
225 | /* pmlmeext->mgnt_seq++; */ | ||
226 | SetFrameSubType(pframe, WIFI_BEACON); | ||
227 | |||
228 | pframe += sizeof(struct ieee80211_hdr_3addr); | ||
229 | pktlen = sizeof (struct ieee80211_hdr_3addr); | ||
230 | |||
231 | /* timestamp will be inserted by hardware */ | ||
232 | pframe += 8; | ||
233 | pktlen += 8; | ||
234 | |||
235 | /* beacon interval: 2 bytes */ | ||
236 | memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval23a_from_ie(cur_network->IEs)), 2); | ||
237 | |||
238 | pframe += 2; | ||
239 | pktlen += 2; | ||
240 | |||
241 | /* capability info: 2 bytes */ | ||
242 | memcpy(pframe, (unsigned char *)(rtw_get_capability23a_from_ie(cur_network->IEs)), 2); | ||
243 | |||
244 | pframe += 2; | ||
245 | pktlen += 2; | ||
246 | |||
247 | if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) { | ||
248 | /* DBG_8723A("ie len =%d\n", cur_network->IELength); */ | ||
249 | pktlen += cur_network->IELength - sizeof(struct ndis_802_11_fixed_ies); | ||
250 | memcpy(pframe, cur_network->IEs+sizeof(struct ndis_802_11_fixed_ies), pktlen); | ||
251 | |||
252 | goto _ConstructBeacon; | ||
253 | } | ||
254 | |||
255 | /* below for ad-hoc mode */ | ||
256 | |||
257 | /* SSID */ | ||
258 | pframe = rtw_set_ie23a(pframe, _SSID_IE_, cur_network->Ssid.ssid_len, | ||
259 | cur_network->Ssid.ssid, &pktlen); | ||
260 | |||
261 | /* supported rates... */ | ||
262 | rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates); | ||
263 | pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? | ||
264 | 8 : rate_len), cur_network->SupportedRates, &pktlen); | ||
265 | |||
266 | /* DS parameter set */ | ||
267 | pframe = rtw_set_ie23a(pframe, _DSSET_IE_, 1, (unsigned char *)&cur_network->Configuration.DSConfig, &pktlen); | ||
268 | |||
269 | if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) { | ||
270 | u32 ATIMWindow; | ||
271 | /* IBSS Parameter Set... */ | ||
272 | /* ATIMWindow = cur->Configuration.ATIMWindow; */ | ||
273 | ATIMWindow = 0; | ||
274 | pframe = rtw_set_ie23a(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen); | ||
275 | } | ||
276 | |||
277 | /* todo: ERP IE */ | ||
278 | |||
279 | /* EXTERNDED SUPPORTED RATE */ | ||
280 | if (rate_len > 8) | ||
281 | pframe = rtw_set_ie23a(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen); | ||
282 | |||
283 | /* todo:HT for adhoc */ | ||
284 | |||
285 | _ConstructBeacon: | ||
286 | |||
287 | if ((pktlen + TXDESC_SIZE) > 512) { | ||
288 | DBG_8723A("beacon frame too large\n"); | ||
289 | return; | ||
290 | } | ||
291 | |||
292 | *pLength = pktlen; | ||
293 | |||
294 | /* DBG_8723A("%s bcn_sz =%d\n", __FUNCTION__, pktlen); */ | ||
295 | |||
296 | } | ||
297 | |||
298 | static void ConstructPSPoll(struct rtw_adapter *padapter, u8 *pframe, u32 *pLength) | ||
299 | { | ||
300 | struct ieee80211_hdr *pwlanhdr; | ||
301 | u16 *fctrl; | ||
302 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; | ||
303 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; | ||
304 | |||
305 | pwlanhdr = (struct ieee80211_hdr *)pframe; | ||
306 | |||
307 | /* Frame control. */ | ||
308 | fctrl = &pwlanhdr->frame_control; | ||
309 | *(fctrl) = 0; | ||
310 | SetPwrMgt(fctrl); | ||
311 | SetFrameSubType(pframe, WIFI_PSPOLL); | ||
312 | |||
313 | /* AID. */ | ||
314 | SetDuration(pframe, (pmlmeinfo->aid | 0xc000)); | ||
315 | |||
316 | /* BSSID. */ | ||
317 | memcpy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN); | ||
318 | |||
319 | /* TA. */ | ||
320 | memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); | ||
321 | |||
322 | *pLength = 16; | ||
323 | } | ||
324 | |||
325 | static void ConstructNullFunctionData( | ||
326 | struct rtw_adapter *padapter, | ||
327 | u8 *pframe, | ||
328 | u32 *pLength, | ||
329 | u8 *StaAddr, | ||
330 | u8 bQoS, | ||
331 | u8 AC, | ||
332 | u8 bEosp, | ||
333 | u8 bForcePowerSave) | ||
334 | { | ||
335 | struct ieee80211_hdr *pwlanhdr; | ||
336 | u16 *fctrl; | ||
337 | u32 pktlen; | ||
338 | struct mlme_priv *pmlmepriv = &padapter->mlmepriv; | ||
339 | struct wlan_network *cur_network = &pmlmepriv->cur_network; | ||
340 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; | ||
341 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; | ||
342 | |||
343 | pwlanhdr = (struct ieee80211_hdr *)pframe; | ||
344 | |||
345 | fctrl = &pwlanhdr->frame_control; | ||
346 | *(fctrl) = 0; | ||
347 | if (bForcePowerSave) | ||
348 | SetPwrMgt(fctrl); | ||
349 | |||
350 | switch (cur_network->network.InfrastructureMode) { | ||
351 | case Ndis802_11Infrastructure: | ||
352 | SetToDs(fctrl); | ||
353 | memcpy(pwlanhdr->addr1, | ||
354 | get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN); | ||
355 | memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), | ||
356 | ETH_ALEN); | ||
357 | memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN); | ||
358 | break; | ||
359 | case Ndis802_11APMode: | ||
360 | SetFrDs(fctrl); | ||
361 | memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); | ||
362 | memcpy(pwlanhdr->addr2, | ||
363 | get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN); | ||
364 | memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), | ||
365 | ETH_ALEN); | ||
366 | break; | ||
367 | case Ndis802_11IBSS: | ||
368 | default: | ||
369 | memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); | ||
370 | memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); | ||
371 | memcpy(pwlanhdr->addr3, | ||
372 | get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN); | ||
373 | break; | ||
374 | } | ||
375 | |||
376 | SetSeqNum(pwlanhdr, 0); | ||
377 | |||
378 | if (bQoS == true) { | ||
379 | struct ieee80211_qos_hdr *pwlanqoshdr; | ||
380 | |||
381 | SetFrameSubType(pframe, WIFI_QOS_DATA_NULL); | ||
382 | |||
383 | pwlanqoshdr = (struct ieee80211_qos_hdr *)pframe; | ||
384 | SetPriority(&pwlanqoshdr->qos_ctrl, AC); | ||
385 | SetEOSP(&pwlanqoshdr->qos_ctrl, bEosp); | ||
386 | |||
387 | pktlen = sizeof(struct ieee80211_qos_hdr); | ||
388 | } else { | ||
389 | SetFrameSubType(pframe, WIFI_DATA_NULL); | ||
390 | |||
391 | pktlen = sizeof(struct ieee80211_hdr_3addr); | ||
392 | } | ||
393 | |||
394 | *pLength = pktlen; | ||
395 | } | ||
396 | |||
397 | static void ConstructProbeRsp(struct rtw_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, bool bHideSSID) | ||
398 | { | ||
399 | struct ieee80211_hdr *pwlanhdr; | ||
400 | u16 *fctrl; | ||
401 | u8 *mac, *bssid; | ||
402 | u32 pktlen; | ||
403 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; | ||
404 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; | ||
405 | struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; | ||
406 | |||
407 | /* DBG_8723A("%s\n", __FUNCTION__); */ | ||
408 | |||
409 | pwlanhdr = (struct ieee80211_hdr *)pframe; | ||
410 | |||
411 | mac = myid(&padapter->eeprompriv); | ||
412 | bssid = cur_network->MacAddress; | ||
413 | |||
414 | fctrl = &pwlanhdr->frame_control; | ||
415 | *(fctrl) = 0; | ||
416 | memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); | ||
417 | memcpy(pwlanhdr->addr2, mac, ETH_ALEN); | ||
418 | memcpy(pwlanhdr->addr3, bssid, ETH_ALEN); | ||
419 | |||
420 | SetSeqNum(pwlanhdr, 0); | ||
421 | SetFrameSubType(fctrl, WIFI_PROBERSP); | ||
422 | |||
423 | pktlen = sizeof(struct ieee80211_hdr_3addr); | ||
424 | pframe += pktlen; | ||
425 | |||
426 | if (cur_network->IELength > MAX_IE_SZ) | ||
427 | return; | ||
428 | |||
429 | memcpy(pframe, cur_network->IEs, cur_network->IELength); | ||
430 | pframe += cur_network->IELength; | ||
431 | pktlen += cur_network->IELength; | ||
432 | |||
433 | *pLength = pktlen; | ||
434 | } | ||
435 | |||
436 | /* To check if reserved page content is destroyed by beacon beacuse beacon is too large. */ | ||
437 | void CheckFwRsvdPageContent23a(struct rtw_adapter *Adapter) | ||
438 | { | ||
439 | } | ||
440 | |||
441 | /* */ | ||
442 | /* Description: Fill the reserved packets that FW will use to RSVD page. */ | ||
443 | /* Now we just send 4 types packet to rsvd page. */ | ||
444 | /* (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp. */ | ||
445 | /* Input: */ | ||
446 | /* bDLFinished - false: At the first time we will send all the packets as a large packet to Hw, */ | ||
447 | /* so we need to set the packet length to total lengh. */ | ||
448 | /* true: At the second time, we should send the first packet (default:beacon) */ | ||
449 | /* to Hw again and set the lengh in descriptor to the real beacon lengh. */ | ||
450 | /* 2009.10.15 by tynli. */ | ||
451 | static void SetFwRsvdPagePkt(struct rtw_adapter *padapter, bool bDLFinished) | ||
452 | { | ||
453 | struct hal_data_8723a *pHalData; | ||
454 | struct xmit_frame *pmgntframe; | ||
455 | struct pkt_attrib *pattrib; | ||
456 | struct xmit_priv *pxmitpriv; | ||
457 | struct mlme_ext_priv *pmlmeext; | ||
458 | struct mlme_ext_info *pmlmeinfo; | ||
459 | u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength; | ||
460 | u32 NullDataLength, QosNullLength, BTQosNullLength; | ||
461 | u8 *ReservedPagePacket; | ||
462 | u8 PageNum, PageNeed, TxDescLen; | ||
463 | u16 BufIndex; | ||
464 | u32 TotalPacketLen; | ||
465 | struct rsvdpage_loc RsvdPageLoc; | ||
466 | |||
467 | DBG_8723A("%s\n", __FUNCTION__); | ||
468 | |||
469 | ReservedPagePacket = kzalloc(1000, GFP_KERNEL); | ||
470 | if (ReservedPagePacket == NULL) { | ||
471 | DBG_8723A("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__); | ||
472 | return; | ||
473 | } | ||
474 | |||
475 | pHalData = GET_HAL_DATA(padapter); | ||
476 | pxmitpriv = &padapter->xmitpriv; | ||
477 | pmlmeext = &padapter->mlmeextpriv; | ||
478 | pmlmeinfo = &pmlmeext->mlmext_info; | ||
479 | |||
480 | TxDescLen = TXDESC_SIZE; | ||
481 | PageNum = 0; | ||
482 | |||
483 | /* 3 (1) beacon */ | ||
484 | BufIndex = TXDESC_OFFSET; | ||
485 | ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength); | ||
486 | |||
487 | /* When we count the first page size, we need to reserve description size for the RSVD */ | ||
488 | /* packet, it will be filled in front of the packet in TXPKTBUF. */ | ||
489 | PageNeed = (u8)PageNum_128(TxDescLen + BeaconLength); | ||
490 | /* To reserved 2 pages for beacon buffer. 2010.06.24. */ | ||
491 | if (PageNeed == 1) | ||
492 | PageNeed += 1; | ||
493 | PageNum += PageNeed; | ||
494 | pHalData->FwRsvdPageStartOffset = PageNum; | ||
495 | |||
496 | BufIndex += PageNeed*128; | ||
497 | |||
498 | /* 3 (2) ps-poll */ | ||
499 | RsvdPageLoc.LocPsPoll = PageNum; | ||
500 | ConstructPSPoll(padapter, &ReservedPagePacket[BufIndex], &PSPollLength); | ||
501 | rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], PSPollLength, true, false); | ||
502 | |||
503 | PageNeed = (u8)PageNum_128(TxDescLen + PSPollLength); | ||
504 | PageNum += PageNeed; | ||
505 | |||
506 | BufIndex += PageNeed*128; | ||
507 | |||
508 | /* 3 (3) null data */ | ||
509 | RsvdPageLoc.LocNullData = PageNum; | ||
510 | ConstructNullFunctionData( | ||
511 | padapter, | ||
512 | &ReservedPagePacket[BufIndex], | ||
513 | &NullDataLength, | ||
514 | get_my_bssid23a(&pmlmeinfo->network), | ||
515 | false, 0, 0, false); | ||
516 | rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], NullDataLength, false, false); | ||
517 | |||
518 | PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength); | ||
519 | PageNum += PageNeed; | ||
520 | |||
521 | BufIndex += PageNeed*128; | ||
522 | |||
523 | /* 3 (4) probe response */ | ||
524 | RsvdPageLoc.LocProbeRsp = PageNum; | ||
525 | ConstructProbeRsp( | ||
526 | padapter, | ||
527 | &ReservedPagePacket[BufIndex], | ||
528 | &ProbeRspLength, | ||
529 | get_my_bssid23a(&pmlmeinfo->network), | ||
530 | false); | ||
531 | rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, false, false); | ||
532 | |||
533 | PageNeed = (u8)PageNum_128(TxDescLen + ProbeRspLength); | ||
534 | PageNum += PageNeed; | ||
535 | |||
536 | BufIndex += PageNeed*128; | ||
537 | |||
538 | /* 3 (5) Qos null data */ | ||
539 | RsvdPageLoc.LocQosNull = PageNum; | ||
540 | ConstructNullFunctionData( | ||
541 | padapter, | ||
542 | &ReservedPagePacket[BufIndex], | ||
543 | &QosNullLength, | ||
544 | get_my_bssid23a(&pmlmeinfo->network), | ||
545 | true, 0, 0, false); | ||
546 | rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], QosNullLength, false, false); | ||
547 | |||
548 | PageNeed = (u8)PageNum_128(TxDescLen + QosNullLength); | ||
549 | PageNum += PageNeed; | ||
550 | |||
551 | BufIndex += PageNeed*128; | ||
552 | |||
553 | /* 3 (6) BT Qos null data */ | ||
554 | RsvdPageLoc.LocBTQosNull = PageNum; | ||
555 | ConstructNullFunctionData( | ||
556 | padapter, | ||
557 | &ReservedPagePacket[BufIndex], | ||
558 | &BTQosNullLength, | ||
559 | get_my_bssid23a(&pmlmeinfo->network), | ||
560 | true, 0, 0, false); | ||
561 | rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, false, true); | ||
562 | |||
563 | TotalPacketLen = BufIndex + BTQosNullLength; | ||
564 | |||
565 | pmgntframe = alloc_mgtxmitframe23a(pxmitpriv); | ||
566 | if (pmgntframe == NULL) | ||
567 | goto exit; | ||
568 | |||
569 | /* update attribute */ | ||
570 | pattrib = &pmgntframe->attrib; | ||
571 | update_mgntframe_attrib23a(padapter, pattrib); | ||
572 | pattrib->qsel = 0x10; | ||
573 | pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TXDESC_OFFSET; | ||
574 | memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen); | ||
575 | |||
576 | rtw_hal_mgnt_xmit23a(padapter, pmgntframe); | ||
577 | |||
578 | DBG_8723A("%s: Set RSVD page location to Fw\n", __FUNCTION__); | ||
579 | FillH2CCmd(padapter, RSVD_PAGE_EID, sizeof(RsvdPageLoc), (u8 *)&RsvdPageLoc); | ||
580 | |||
581 | exit: | ||
582 | kfree(ReservedPagePacket); | ||
583 | } | ||
584 | |||
585 | void rtl8723a_set_FwJoinBssReport_cmd(struct rtw_adapter *padapter, u8 mstatus) | ||
586 | { | ||
587 | struct joinbssrpt_parm JoinBssRptParm; | ||
588 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
589 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; | ||
590 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; | ||
591 | |||
592 | DBG_8723A("%s mstatus(%x)\n", __FUNCTION__, mstatus); | ||
593 | |||
594 | if (mstatus == 1) { | ||
595 | bool bRecover = false; | ||
596 | u8 v8; | ||
597 | |||
598 | /* We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C. */ | ||
599 | /* Suggested by filen. Added by tynli. */ | ||
600 | rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid)); | ||
601 | /* Do not set TSF again here or vWiFi beacon DMA INT will not work. */ | ||
602 | /* correct_TSF23a(padapter, pmlmeext); */ | ||
603 | /* Hw sequende enable by dedault. 2010.06.23. by tynli. */ | ||
604 | /* rtw_write16(padapter, REG_NQOS_SEQ, ((pmlmeext->mgnt_seq+100)&0xFFF)); */ | ||
605 | /* rtw_write8(padapter, REG_HWSEQ_CTRL, 0xFF); */ | ||
606 | |||
607 | /* set REG_CR bit 8 */ | ||
608 | v8 = rtw_read8(padapter, REG_CR+1); | ||
609 | v8 |= BIT(0); /* ENSWBCN */ | ||
610 | rtw_write8(padapter, REG_CR+1, v8); | ||
611 | |||
612 | /* Disable Hw protection for a time which revserd for Hw sending beacon. */ | ||
613 | /* Fix download reserved page packet fail that access collision with the protection time. */ | ||
614 | /* 2010.05.11. Added by tynli. */ | ||
615 | /* SetBcnCtrlReg23a(padapter, 0, BIT(3)); */ | ||
616 | /* SetBcnCtrlReg23a(padapter, BIT(4), 0); */ | ||
617 | SetBcnCtrlReg23a(padapter, BIT(4), BIT(3)); | ||
618 | |||
619 | /* Set FWHW_TXQ_CTRL 0x422[6]= 0 to tell Hw the packet is not a real beacon frame. */ | ||
620 | if (pHalData->RegFwHwTxQCtrl & BIT(6)) | ||
621 | bRecover = true; | ||
622 | |||
623 | /* To tell Hw the packet is not a real beacon frame. */ | ||
624 | /* U1bTmp = rtw_read8(padapter, REG_FWHW_TXQ_CTRL+2); */ | ||
625 | rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl & ~BIT(6)); | ||
626 | pHalData->RegFwHwTxQCtrl &= ~BIT(6); | ||
627 | SetFwRsvdPagePkt(padapter, 0); | ||
628 | |||
629 | /* 2010.05.11. Added by tynli. */ | ||
630 | SetBcnCtrlReg23a(padapter, BIT(3), BIT(4)); | ||
631 | |||
632 | /* To make sure that if there exists an adapter which would like to send beacon. */ | ||
633 | /* If exists, the origianl value of 0x422[6] will be 1, we should check this to */ | ||
634 | /* prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */ | ||
635 | /* the beacon cannot be sent by HW. */ | ||
636 | /* 2010.06.23. Added by tynli. */ | ||
637 | if (bRecover) { | ||
638 | rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl | BIT(6)); | ||
639 | pHalData->RegFwHwTxQCtrl |= BIT(6); | ||
640 | } | ||
641 | |||
642 | /* Clear CR[8] or beacon packet will not be send to TxBuf anymore. */ | ||
643 | v8 = rtw_read8(padapter, REG_CR+1); | ||
644 | v8 &= ~BIT(0); /* ~ENSWBCN */ | ||
645 | rtw_write8(padapter, REG_CR+1, v8); | ||
646 | } | ||
647 | |||
648 | JoinBssRptParm.OpMode = mstatus; | ||
649 | |||
650 | FillH2CCmd(padapter, JOINBSS_RPT_EID, sizeof(JoinBssRptParm), (u8 *)&JoinBssRptParm); | ||
651 | |||
652 | } | ||
653 | |||
654 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
655 | static void SetFwRsvdPagePkt_BTCoex(struct rtw_adapter *padapter) | ||
656 | { | ||
657 | struct hal_data_8723a *pHalData; | ||
658 | struct xmit_frame *pmgntframe; | ||
659 | struct pkt_attrib *pattrib; | ||
660 | struct xmit_priv *pxmitpriv; | ||
661 | struct mlme_ext_priv *pmlmeext; | ||
662 | struct mlme_ext_info *pmlmeinfo; | ||
663 | u8 fakemac[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x00}; | ||
664 | u32 NullDataLength, BTQosNullLength; | ||
665 | u8 *ReservedPagePacket; | ||
666 | u8 PageNum, PageNeed, TxDescLen; | ||
667 | u16 BufIndex; | ||
668 | u32 TotalPacketLen; | ||
669 | struct rsvdpage_loc RsvdPageLoc; | ||
670 | |||
671 | DBG_8723A("+%s\n", __FUNCTION__); | ||
672 | |||
673 | ReservedPagePacket = kzalloc(1024, GFP_KERNEL); | ||
674 | if (ReservedPagePacket == NULL) { | ||
675 | DBG_8723A("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__); | ||
676 | return; | ||
677 | } | ||
678 | |||
679 | pHalData = GET_HAL_DATA(padapter); | ||
680 | pxmitpriv = &padapter->xmitpriv; | ||
681 | pmlmeext = &padapter->mlmeextpriv; | ||
682 | pmlmeinfo = &pmlmeext->mlmext_info; | ||
683 | |||
684 | TxDescLen = TXDESC_SIZE; | ||
685 | PageNum = 0; | ||
686 | |||
687 | /* 3 (1) beacon */ | ||
688 | BufIndex = TXDESC_OFFSET; | ||
689 | /* skip Beacon Packet */ | ||
690 | PageNeed = 3; | ||
691 | |||
692 | PageNum += PageNeed; | ||
693 | pHalData->FwRsvdPageStartOffset = PageNum; | ||
694 | |||
695 | BufIndex += PageNeed*128; | ||
696 | |||
697 | /* 3 (3) null data */ | ||
698 | RsvdPageLoc.LocNullData = PageNum; | ||
699 | ConstructNullFunctionData( | ||
700 | padapter, | ||
701 | &ReservedPagePacket[BufIndex], | ||
702 | &NullDataLength, | ||
703 | fakemac, | ||
704 | false, 0, 0, false); | ||
705 | rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], NullDataLength, false, false); | ||
706 | |||
707 | PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength); | ||
708 | PageNum += PageNeed; | ||
709 | |||
710 | BufIndex += PageNeed*128; | ||
711 | |||
712 | /* 3 (6) BT Qos null data */ | ||
713 | RsvdPageLoc.LocBTQosNull = PageNum; | ||
714 | ConstructNullFunctionData( | ||
715 | padapter, | ||
716 | &ReservedPagePacket[BufIndex], | ||
717 | &BTQosNullLength, | ||
718 | fakemac, | ||
719 | true, 0, 0, false); | ||
720 | rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, false, true); | ||
721 | |||
722 | TotalPacketLen = BufIndex + BTQosNullLength; | ||
723 | |||
724 | pmgntframe = alloc_mgtxmitframe23a(pxmitpriv); | ||
725 | if (pmgntframe == NULL) | ||
726 | goto exit; | ||
727 | |||
728 | /* update attribute */ | ||
729 | pattrib = &pmgntframe->attrib; | ||
730 | update_mgntframe_attrib23a(padapter, pattrib); | ||
731 | pattrib->qsel = 0x10; | ||
732 | pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TXDESC_OFFSET; | ||
733 | memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen); | ||
734 | |||
735 | rtw_hal_mgnt_xmit23a(padapter, pmgntframe); | ||
736 | |||
737 | DBG_8723A("%s: Set RSVD page location to Fw\n", __FUNCTION__); | ||
738 | FillH2CCmd(padapter, RSVD_PAGE_EID, sizeof(RsvdPageLoc), (u8 *)&RsvdPageLoc); | ||
739 | |||
740 | exit: | ||
741 | kfree(ReservedPagePacket); | ||
742 | } | ||
743 | |||
744 | void rtl8723a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(struct rtw_adapter *padapter) | ||
745 | { | ||
746 | struct hal_data_8723a *pHalData; | ||
747 | u8 bRecover = false; | ||
748 | |||
749 | DBG_8723A("+%s\n", __FUNCTION__); | ||
750 | |||
751 | pHalData = GET_HAL_DATA(padapter); | ||
752 | |||
753 | /* Set FWHW_TXQ_CTRL 0x422[6]= 0 to tell Hw the packet is not a real beacon frame. */ | ||
754 | if (pHalData->RegFwHwTxQCtrl & BIT(6)) | ||
755 | bRecover = true; | ||
756 | |||
757 | /* To tell Hw the packet is not a real beacon frame. */ | ||
758 | pHalData->RegFwHwTxQCtrl &= ~BIT(6); | ||
759 | rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl); | ||
760 | SetFwRsvdPagePkt_BTCoex(padapter); | ||
761 | |||
762 | /* To make sure that if there exists an adapter which would like to send beacon. */ | ||
763 | /* If exists, the origianl value of 0x422[6] will be 1, we should check this to */ | ||
764 | /* prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */ | ||
765 | /* the beacon cannot be sent by HW. */ | ||
766 | /* 2010.06.23. Added by tynli. */ | ||
767 | if (bRecover) { | ||
768 | pHalData->RegFwHwTxQCtrl |= BIT(6); | ||
769 | rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl); | ||
770 | } | ||
771 | } | ||
772 | #endif | ||
773 | |||
774 | #ifdef CONFIG_8723AU_P2P | ||
775 | void rtl8723a_set_p2p_ps_offload_cmd(struct rtw_adapter *padapter, u8 p2p_ps_state) | ||
776 | { | ||
777 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
778 | struct wifidirect_info *pwdinfo = &padapter->wdinfo; | ||
779 | struct P2P_PS_Offload_t *p2p_ps_offload = &pHalData->p2p_ps_offload; | ||
780 | u8 i; | ||
781 | |||
782 | switch (p2p_ps_state) { | ||
783 | case P2P_PS_DISABLE: | ||
784 | DBG_8723A("P2P_PS_DISABLE \n"); | ||
785 | memset(p2p_ps_offload, 0, 1); | ||
786 | break; | ||
787 | case P2P_PS_ENABLE: | ||
788 | DBG_8723A("P2P_PS_ENABLE \n"); | ||
789 | /* update CTWindow value. */ | ||
790 | if (pwdinfo->ctwindow > 0) { | ||
791 | p2p_ps_offload->CTWindow_En = 1; | ||
792 | rtw_write8(padapter, REG_P2P_CTWIN, pwdinfo->ctwindow); | ||
793 | } | ||
794 | |||
795 | /* hw only support 2 set of NoA */ | ||
796 | for (i = 0; i < pwdinfo->noa_num; i++) { | ||
797 | /* To control the register setting for which NOA */ | ||
798 | rtw_write8(padapter, REG_NOA_DESC_SEL, (i << 4)); | ||
799 | if (i == 0) | ||
800 | p2p_ps_offload->NoA0_En = 1; | ||
801 | else | ||
802 | p2p_ps_offload->NoA1_En = 1; | ||
803 | |||
804 | /* config P2P NoA Descriptor Register */ | ||
805 | rtw_write32(padapter, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]); | ||
806 | |||
807 | rtw_write32(padapter, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]); | ||
808 | |||
809 | rtw_write32(padapter, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]); | ||
810 | |||
811 | rtw_write8(padapter, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]); | ||
812 | } | ||
813 | |||
814 | if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) { | ||
815 | /* rst p2p circuit */ | ||
816 | rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4)); | ||
817 | |||
818 | p2p_ps_offload->Offload_En = 1; | ||
819 | |||
820 | if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { | ||
821 | p2p_ps_offload->role = 1; | ||
822 | p2p_ps_offload->AllStaSleep = 0; | ||
823 | } else { | ||
824 | p2p_ps_offload->role = 0; | ||
825 | } | ||
826 | |||
827 | p2p_ps_offload->discovery = 0; | ||
828 | } | ||
829 | break; | ||
830 | case P2P_PS_SCAN: | ||
831 | DBG_8723A("P2P_PS_SCAN \n"); | ||
832 | p2p_ps_offload->discovery = 1; | ||
833 | break; | ||
834 | case P2P_PS_SCAN_DONE: | ||
835 | DBG_8723A("P2P_PS_SCAN_DONE \n"); | ||
836 | p2p_ps_offload->discovery = 0; | ||
837 | pwdinfo->p2p_ps_state = P2P_PS_ENABLE; | ||
838 | break; | ||
839 | default: | ||
840 | break; | ||
841 | } | ||
842 | |||
843 | FillH2CCmd(padapter, P2P_PS_OFFLOAD_EID, 1, (u8 *)p2p_ps_offload); | ||
844 | } | ||
845 | #endif /* CONFIG_8723AU_P2P */ | ||
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c new file mode 100644 index 000000000000..f204ab1714e7 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c | |||
@@ -0,0 +1,273 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | /* */ | ||
16 | /* Description: */ | ||
17 | /* */ | ||
18 | /* This file is for 92CE/92CU dynamic mechanism only */ | ||
19 | /* */ | ||
20 | /* */ | ||
21 | /* */ | ||
22 | #define _RTL8723A_DM_C_ | ||
23 | |||
24 | /* */ | ||
25 | /* include files */ | ||
26 | /* */ | ||
27 | #include <osdep_service.h> | ||
28 | #include <drv_types.h> | ||
29 | |||
30 | #include <rtl8723a_hal.h> | ||
31 | |||
32 | /* */ | ||
33 | /* Global var */ | ||
34 | /* */ | ||
35 | |||
36 | static void dm_CheckStatistics(struct rtw_adapter *Adapter) | ||
37 | { | ||
38 | } | ||
39 | |||
40 | static void dm_CheckPbcGPIO(struct rtw_adapter *padapter) | ||
41 | { | ||
42 | u8 tmp1byte; | ||
43 | u8 bPbcPressed = false; | ||
44 | |||
45 | if (!padapter->registrypriv.hw_wps_pbc) | ||
46 | return; | ||
47 | |||
48 | tmp1byte = rtw_read8(padapter, GPIO_IO_SEL); | ||
49 | tmp1byte |= (HAL_8192C_HW_GPIO_WPS_BIT); | ||
50 | rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); /* enable GPIO[2] as output mode */ | ||
51 | |||
52 | tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT); | ||
53 | rtw_write8(padapter, GPIO_IN, tmp1byte); /* reset the floating voltage level */ | ||
54 | |||
55 | tmp1byte = rtw_read8(padapter, GPIO_IO_SEL); | ||
56 | tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT); | ||
57 | rtw_write8(padapter, GPIO_IO_SEL, tmp1byte); /* enable GPIO[2] as input mode */ | ||
58 | |||
59 | tmp1byte = rtw_read8(padapter, GPIO_IN); | ||
60 | |||
61 | if (tmp1byte == 0xff) | ||
62 | return; | ||
63 | |||
64 | if (tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT) | ||
65 | bPbcPressed = true; | ||
66 | |||
67 | if (bPbcPressed) { | ||
68 | /* Here we only set bPbcPressed to true */ | ||
69 | /* After trigger PBC, the variable will be set to false */ | ||
70 | DBG_8723A("CheckPbcGPIO - PBC is pressed\n"); | ||
71 | |||
72 | if (padapter->pid[0] == 0) { | ||
73 | /* 0 is the default value and it means the application | ||
74 | * monitors the HW PBC doesn't privde its pid to driver. | ||
75 | */ | ||
76 | return; | ||
77 | } | ||
78 | |||
79 | rtw_signal_process(padapter->pid[0], SIGUSR1); | ||
80 | } | ||
81 | } | ||
82 | |||
83 | /* Initialize GPIO setting registers */ | ||
84 | /* functions */ | ||
85 | static void Init_ODM_ComInfo_8723a(struct rtw_adapter *Adapter) | ||
86 | { | ||
87 | |||
88 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
89 | struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; | ||
90 | u8 cut_ver, fab_ver; | ||
91 | |||
92 | /* */ | ||
93 | /* Init Value */ | ||
94 | /* */ | ||
95 | memset(pDM_Odm, 0, sizeof(*pDM_Odm)); | ||
96 | |||
97 | pDM_Odm->Adapter = Adapter; | ||
98 | ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_PLATFORM, 0x04); | ||
99 | ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_INTERFACE, RTW_USB);/* RTL871X_HCI_TYPE */ | ||
100 | |||
101 | ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_IC_TYPE, ODM_RTL8723A); | ||
102 | |||
103 | if (IS_8723A_A_CUT(pHalData->VersionID)) { | ||
104 | fab_ver = ODM_UMC; | ||
105 | cut_ver = ODM_CUT_A; | ||
106 | } else if (IS_8723A_B_CUT(pHalData->VersionID)) { | ||
107 | fab_ver = ODM_UMC; | ||
108 | cut_ver = ODM_CUT_B; | ||
109 | } else { | ||
110 | fab_ver = ODM_TSMC; | ||
111 | cut_ver = ODM_CUT_A; | ||
112 | } | ||
113 | ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_FAB_VER, fab_ver); | ||
114 | ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_CUT_VER, cut_ver); | ||
115 | ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(pHalData->VersionID)); | ||
116 | |||
117 | ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_BOARD_TYPE, pHalData->BoardType); | ||
118 | |||
119 | if (pHalData->BoardType == BOARD_USB_High_PA) { | ||
120 | ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_EXT_LNA, true); | ||
121 | ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_EXT_PA, true); | ||
122 | } | ||
123 | ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_PATCH_ID, pHalData->CustomerID); | ||
124 | ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_BWIFI_TEST, Adapter->registrypriv.wifi_spec); | ||
125 | |||
126 | if (pHalData->rf_type == RF_1T1R) | ||
127 | ODM_CmnInfoUpdate23a(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T1R); | ||
128 | else if (pHalData->rf_type == RF_2T2R) | ||
129 | ODM_CmnInfoUpdate23a(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R); | ||
130 | else if (pHalData->rf_type == RF_1T2R) | ||
131 | ODM_CmnInfoUpdate23a(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T2R); | ||
132 | } | ||
133 | |||
134 | static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter) | ||
135 | { | ||
136 | struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; | ||
137 | struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; | ||
138 | struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv; | ||
139 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
140 | struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; | ||
141 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
142 | int i; | ||
143 | pdmpriv->InitODMFlag = ODM_BB_DIG | | ||
144 | ODM_BB_RA_MASK | | ||
145 | ODM_BB_DYNAMIC_TXPWR | | ||
146 | ODM_BB_FA_CNT | | ||
147 | ODM_BB_RSSI_MONITOR | | ||
148 | ODM_BB_CCK_PD | | ||
149 | ODM_BB_PWR_SAVE | | ||
150 | ODM_MAC_EDCA_TURBO | | ||
151 | ODM_RF_TX_PWR_TRACK | | ||
152 | ODM_RF_CALIBRATION; | ||
153 | /* Pointer reference */ | ||
154 | |||
155 | ODM_CmnInfoUpdate23a(pDM_Odm, ODM_CMNINFO_ABILITY, pdmpriv->InitODMFlag); | ||
156 | |||
157 | ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_TX_UNI, | ||
158 | &Adapter->xmitpriv.tx_bytes); | ||
159 | ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_RX_UNI, | ||
160 | &Adapter->recvpriv.rx_bytes); | ||
161 | ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_WM_MODE, | ||
162 | &pmlmeext->cur_wireless_mode); | ||
163 | ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SEC_CHNL_OFFSET, | ||
164 | &pHalData->nCur40MhzPrimeSC); | ||
165 | ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SEC_MODE, | ||
166 | &Adapter->securitypriv.dot11PrivacyAlgrthm); | ||
167 | ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_BW, | ||
168 | &pHalData->CurrentChannelBW); | ||
169 | ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_CHNL, | ||
170 | &pHalData->CurrentChannel); | ||
171 | ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_NET_CLOSED, &Adapter->net_closed); | ||
172 | |||
173 | ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SCAN, &pmlmepriv->bScanInProcess); | ||
174 | ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_POWER_SAVING, | ||
175 | &pwrctrlpriv->bpower_saving); | ||
176 | |||
177 | for (i = 0; i < NUM_STA; i++) | ||
178 | ODM_CmnInfoPtrArrayHook23a(pDM_Odm, ODM_CMNINFO_STA_STATUS, i, NULL); | ||
179 | } | ||
180 | |||
181 | void rtl8723a_InitHalDm(struct rtw_adapter *Adapter) | ||
182 | { | ||
183 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
184 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
185 | struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; | ||
186 | u8 i; | ||
187 | |||
188 | pdmpriv->DM_Type = DM_Type_ByDriver; | ||
189 | pdmpriv->DMFlag = DYNAMIC_FUNC_DISABLE; | ||
190 | |||
191 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
192 | pdmpriv->DMFlag |= DYNAMIC_FUNC_BT; | ||
193 | #endif | ||
194 | pdmpriv->InitDMFlag = pdmpriv->DMFlag; | ||
195 | |||
196 | Update_ODM_ComInfo_8723a(Adapter); | ||
197 | ODM23a_DMInit(pDM_Odm); | ||
198 | /* Save REG_INIDATA_RATE_SEL value for TXDESC. */ | ||
199 | for (i = 0; i < 32; i++) | ||
200 | pdmpriv->INIDATA_RATE[i] = rtw_read8(Adapter, REG_INIDATA_RATE_SEL+i) & 0x3f; | ||
201 | } | ||
202 | |||
203 | void | ||
204 | rtl8723a_HalDmWatchDog( | ||
205 | struct rtw_adapter *Adapter | ||
206 | ) | ||
207 | { | ||
208 | bool bFwCurrentInPSMode = false; | ||
209 | bool bFwPSAwake = true; | ||
210 | u8 hw_init_completed = false; | ||
211 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
212 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
213 | |||
214 | hw_init_completed = Adapter->hw_init_completed; | ||
215 | |||
216 | if (hw_init_completed == false) | ||
217 | goto skip_dm; | ||
218 | |||
219 | bFwCurrentInPSMode = Adapter->pwrctrlpriv.bFwCurrentInPSMode; | ||
220 | rtw23a_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake)); | ||
221 | |||
222 | #ifdef CONFIG_8723AU_P2P | ||
223 | /* Fw is under p2p powersaving mode, driver should stop dynamic mechanism. */ | ||
224 | /* modifed by thomas. 2011.06.11. */ | ||
225 | if (Adapter->wdinfo.p2p_ps_mode) | ||
226 | bFwPSAwake = false; | ||
227 | #endif /* CONFIG_8723AU_P2P */ | ||
228 | |||
229 | if ((hw_init_completed) && ((!bFwCurrentInPSMode) && bFwPSAwake)) { | ||
230 | /* Calculate Tx/Rx statistics. */ | ||
231 | dm_CheckStatistics(Adapter); | ||
232 | |||
233 | /* Read REG_INIDATA_RATE_SEL value for TXDESC. */ | ||
234 | if (check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE)) { | ||
235 | pdmpriv->INIDATA_RATE[0] = rtw_read8(Adapter, REG_INIDATA_RATE_SEL) & 0x3f; | ||
236 | } else { | ||
237 | u8 i; | ||
238 | for (i = 1 ; i < (Adapter->stapriv.asoc_sta_count + 1); i++) | ||
239 | pdmpriv->INIDATA_RATE[i] = rtw_read8(Adapter, (REG_INIDATA_RATE_SEL+i)) & 0x3f; | ||
240 | } | ||
241 | } | ||
242 | |||
243 | /* ODM */ | ||
244 | if (hw_init_completed == true) { | ||
245 | u8 bLinked = false; | ||
246 | |||
247 | if (rtw_linked_check(Adapter)) | ||
248 | bLinked = true; | ||
249 | |||
250 | ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_LINK, | ||
251 | bLinked); | ||
252 | ODM_DMWatchdog23a(&pHalData->odmpriv); | ||
253 | } | ||
254 | |||
255 | skip_dm: | ||
256 | |||
257 | /* Check GPIO to determine current RF on/off and Pbc status. */ | ||
258 | /* Check Hardware Radio ON/OFF or not */ | ||
259 | dm_CheckPbcGPIO(Adapter); | ||
260 | } | ||
261 | |||
262 | void rtl8723a_init_dm_priv(struct rtw_adapter *Adapter) | ||
263 | { | ||
264 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
265 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
266 | |||
267 | memset(pdmpriv, 0, sizeof(struct dm_priv)); | ||
268 | Init_ODM_ComInfo_8723a(Adapter); | ||
269 | } | ||
270 | |||
271 | void rtl8723a_deinit_dm_priv(struct rtw_adapter *Adapter) | ||
272 | { | ||
273 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c new file mode 100644 index 000000000000..fd00ddb3c951 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c | |||
@@ -0,0 +1,3452 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | #define _HAL_INIT_C_ | ||
16 | |||
17 | #include <linux/firmware.h> | ||
18 | #include <drv_types.h> | ||
19 | #include <rtw_efuse.h> | ||
20 | |||
21 | #include <rtl8723a_hal.h> | ||
22 | |||
23 | static void _FWDownloadEnable(struct rtw_adapter *padapter, bool enable) | ||
24 | { | ||
25 | u8 tmp; | ||
26 | |||
27 | if (enable) { | ||
28 | /* 8051 enable */ | ||
29 | tmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); | ||
30 | rtw_write8(padapter, REG_SYS_FUNC_EN + 1, tmp | 0x04); | ||
31 | |||
32 | /* MCU firmware download enable. */ | ||
33 | tmp = rtw_read8(padapter, REG_MCUFWDL); | ||
34 | rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01); | ||
35 | |||
36 | /* 8051 reset */ | ||
37 | tmp = rtw_read8(padapter, REG_MCUFWDL + 2); | ||
38 | rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7); | ||
39 | } else { | ||
40 | /* MCU firmware download disable. */ | ||
41 | tmp = rtw_read8(padapter, REG_MCUFWDL); | ||
42 | rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe); | ||
43 | |||
44 | /* Reserved for fw extension. */ | ||
45 | rtw_write8(padapter, REG_MCUFWDL + 1, 0x00); | ||
46 | } | ||
47 | } | ||
48 | |||
49 | static int _BlockWrite(struct rtw_adapter *padapter, void *buffer, u32 buffSize) | ||
50 | { | ||
51 | int ret = _SUCCESS; | ||
52 | /* (Default) Phase #1 : PCI muse use 4-byte write to download FW */ | ||
53 | u32 blockSize_p1 = 4; | ||
54 | /* Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */ | ||
55 | u32 blockSize_p2 = 8; | ||
56 | /* Phase #3 : Use 1-byte, the remnant of FW image. */ | ||
57 | u32 blockSize_p3 = 1; | ||
58 | u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0; | ||
59 | u32 remainSize_p1 = 0, remainSize_p2 = 0; | ||
60 | u8 *bufferPtr = (u8 *) buffer; | ||
61 | u32 i = 0, offset = 0; | ||
62 | |||
63 | blockSize_p1 = 254; | ||
64 | |||
65 | /* 3 Phase #1 */ | ||
66 | blockCount_p1 = buffSize / blockSize_p1; | ||
67 | remainSize_p1 = buffSize % blockSize_p1; | ||
68 | |||
69 | if (blockCount_p1) { | ||
70 | RT_TRACE(_module_hal_init_c_, _drv_notice_, | ||
71 | ("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) " | ||
72 | "blockCount_p1(%d) remainSize_p1(%d)\n", | ||
73 | buffSize, blockSize_p1, blockCount_p1, | ||
74 | remainSize_p1)); | ||
75 | } | ||
76 | |||
77 | for (i = 0; i < blockCount_p1; i++) { | ||
78 | ret = rtw_writeN(padapter, | ||
79 | (FW_8723A_START_ADDRESS + i * blockSize_p1), | ||
80 | blockSize_p1, (bufferPtr + i * blockSize_p1)); | ||
81 | if (ret == _FAIL) | ||
82 | goto exit; | ||
83 | } | ||
84 | |||
85 | /* 3 Phase #2 */ | ||
86 | if (remainSize_p1) { | ||
87 | offset = blockCount_p1 * blockSize_p1; | ||
88 | |||
89 | blockCount_p2 = remainSize_p1 / blockSize_p2; | ||
90 | remainSize_p2 = remainSize_p1 % blockSize_p2; | ||
91 | |||
92 | if (blockCount_p2) { | ||
93 | RT_TRACE(_module_hal_init_c_, _drv_notice_, | ||
94 | ("_BlockWrite: [P2] buffSize_p2(%d) " | ||
95 | "blockSize_p2(%d) blockCount_p2(%d) " | ||
96 | "remainSize_p2(%d)\n", | ||
97 | (buffSize - offset), blockSize_p2, | ||
98 | blockCount_p2, remainSize_p2)); | ||
99 | } | ||
100 | |||
101 | for (i = 0; i < blockCount_p2; i++) { | ||
102 | ret = rtw_writeN(padapter, | ||
103 | (FW_8723A_START_ADDRESS + offset + | ||
104 | i * blockSize_p2), blockSize_p2, | ||
105 | (bufferPtr + offset + | ||
106 | i * blockSize_p2)); | ||
107 | |||
108 | if (ret == _FAIL) | ||
109 | goto exit; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | /* 3 Phase #3 */ | ||
114 | if (remainSize_p2) { | ||
115 | offset = (blockCount_p1 * blockSize_p1) + | ||
116 | (blockCount_p2 * blockSize_p2); | ||
117 | |||
118 | blockCount_p3 = remainSize_p2 / blockSize_p3; | ||
119 | |||
120 | RT_TRACE(_module_hal_init_c_, _drv_notice_, | ||
121 | ("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) " | ||
122 | "blockCount_p3(%d)\n", | ||
123 | (buffSize - offset), blockSize_p3, blockCount_p3)); | ||
124 | |||
125 | for (i = 0; i < blockCount_p3; i++) { | ||
126 | ret = rtw_write8(padapter, | ||
127 | (FW_8723A_START_ADDRESS + offset + i), | ||
128 | *(bufferPtr + offset + i)); | ||
129 | |||
130 | if (ret == _FAIL) | ||
131 | goto exit; | ||
132 | } | ||
133 | } | ||
134 | |||
135 | exit: | ||
136 | return ret; | ||
137 | } | ||
138 | |||
139 | static int | ||
140 | _PageWrite(struct rtw_adapter *padapter, u32 page, void *buffer, u32 size) | ||
141 | { | ||
142 | u8 value8; | ||
143 | u8 u8Page = (u8) (page & 0x07); | ||
144 | |||
145 | value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page; | ||
146 | rtw_write8(padapter, REG_MCUFWDL + 2, value8); | ||
147 | |||
148 | return _BlockWrite(padapter, buffer, size); | ||
149 | } | ||
150 | |||
151 | static int _WriteFW(struct rtw_adapter *padapter, void *buffer, u32 size) | ||
152 | { | ||
153 | /* Since we need dynamic decide method of dwonload fw, so we | ||
154 | call this function to get chip version. */ | ||
155 | /* We can remove _ReadChipVersion from ReadpadapterInfo8192C later. */ | ||
156 | int ret = _SUCCESS; | ||
157 | u32 pageNums, remainSize; | ||
158 | u32 page, offset; | ||
159 | u8 *bufferPtr = (u8 *) buffer; | ||
160 | |||
161 | pageNums = size / MAX_PAGE_SIZE; | ||
162 | /* RT_ASSERT((pageNums <= 4), | ||
163 | ("Page numbers should not greater then 4 \n")); */ | ||
164 | remainSize = size % MAX_PAGE_SIZE; | ||
165 | |||
166 | for (page = 0; page < pageNums; page++) { | ||
167 | offset = page * MAX_PAGE_SIZE; | ||
168 | ret = _PageWrite(padapter, page, bufferPtr + offset, | ||
169 | MAX_PAGE_SIZE); | ||
170 | |||
171 | if (ret == _FAIL) | ||
172 | goto exit; | ||
173 | } | ||
174 | if (remainSize) { | ||
175 | offset = pageNums * MAX_PAGE_SIZE; | ||
176 | page = pageNums; | ||
177 | ret = _PageWrite(padapter, page, bufferPtr + offset, | ||
178 | remainSize); | ||
179 | |||
180 | if (ret == _FAIL) | ||
181 | goto exit; | ||
182 | } | ||
183 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
184 | ("_WriteFW Done- for Normal chip.\n")); | ||
185 | |||
186 | exit: | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | static s32 _FWFreeToGo(struct rtw_adapter *padapter) | ||
191 | { | ||
192 | u32 counter = 0; | ||
193 | u32 value32; | ||
194 | |||
195 | /* polling CheckSum report */ | ||
196 | do { | ||
197 | value32 = rtw_read32(padapter, REG_MCUFWDL); | ||
198 | if (value32 & FWDL_ChkSum_rpt) | ||
199 | break; | ||
200 | } while (counter++ < POLLING_READY_TIMEOUT_COUNT); | ||
201 | |||
202 | if (counter >= POLLING_READY_TIMEOUT_COUNT) { | ||
203 | RT_TRACE(_module_hal_init_c_, _drv_err_, | ||
204 | ("%s: chksum report fail! REG_MCUFWDL:0x%08x\n", | ||
205 | __func__, value32)); | ||
206 | return _FAIL; | ||
207 | } | ||
208 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
209 | ("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__, | ||
210 | value32)); | ||
211 | |||
212 | value32 = rtw_read32(padapter, REG_MCUFWDL); | ||
213 | value32 |= MCUFWDL_RDY; | ||
214 | value32 &= ~WINTINI_RDY; | ||
215 | rtw_write32(padapter, REG_MCUFWDL, value32); | ||
216 | |||
217 | /* polling for FW ready */ | ||
218 | counter = 0; | ||
219 | do { | ||
220 | value32 = rtw_read32(padapter, REG_MCUFWDL); | ||
221 | if (value32 & WINTINI_RDY) { | ||
222 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
223 | ("%s: Polling FW ready success!! " | ||
224 | "REG_MCUFWDL:0x%08x\n", | ||
225 | __func__, value32)); | ||
226 | return _SUCCESS; | ||
227 | } | ||
228 | udelay(5); | ||
229 | } while (counter++ < POLLING_READY_TIMEOUT_COUNT); | ||
230 | |||
231 | RT_TRACE(_module_hal_init_c_, _drv_err_, | ||
232 | ("%s: Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", | ||
233 | __func__, value32)); | ||
234 | return _FAIL; | ||
235 | } | ||
236 | |||
237 | #define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0) | ||
238 | |||
239 | void rtl8723a_FirmwareSelfReset(struct rtw_adapter *padapter) | ||
240 | { | ||
241 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
242 | u8 u1bTmp; | ||
243 | u8 Delay = 100; | ||
244 | |||
245 | if (!(IS_FW_81xxC(padapter) && | ||
246 | ((pHalData->FirmwareVersion < 0x21) || | ||
247 | (pHalData->FirmwareVersion == 0x21 && | ||
248 | pHalData->FirmwareSubVersion < 0x01)))) { | ||
249 | /* after 88C Fw v33.1 */ | ||
250 | /* 0x1cf = 0x20. Inform 8051 to reset. 2009.12.25. tynli_test */ | ||
251 | rtw_write8(padapter, REG_HMETFR + 3, 0x20); | ||
252 | |||
253 | u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); | ||
254 | while (u1bTmp & BIT2) { | ||
255 | Delay--; | ||
256 | if (Delay == 0) | ||
257 | break; | ||
258 | udelay(50); | ||
259 | u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); | ||
260 | } | ||
261 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
262 | ("-%s: 8051 reset success (%d)\n", __func__, | ||
263 | Delay)); | ||
264 | |||
265 | if ((Delay == 0)) { | ||
266 | /* force firmware reset */ | ||
267 | u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); | ||
268 | rtw_write8(padapter, REG_SYS_FUNC_EN + 1, | ||
269 | u1bTmp & (~BIT2)); | ||
270 | } | ||
271 | } | ||
272 | } | ||
273 | |||
274 | /* */ | ||
275 | /* Description: */ | ||
276 | /* Download 8192C firmware code. */ | ||
277 | /* */ | ||
278 | /* */ | ||
279 | s32 rtl8723a_FirmwareDownload(struct rtw_adapter *padapter) | ||
280 | { | ||
281 | s32 rtStatus = _SUCCESS; | ||
282 | u8 writeFW_retry = 0; | ||
283 | unsigned long fwdl_start_time; | ||
284 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
285 | struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); | ||
286 | struct device *device = dvobj_to_dev(dvobj); | ||
287 | struct rt_8723a_firmware_hdr *pFwHdr = NULL; | ||
288 | const struct firmware *fw; | ||
289 | char *fw_name; | ||
290 | u8 *firmware_buf = NULL; | ||
291 | u8 *buf; | ||
292 | int fw_size; | ||
293 | static int log_version; | ||
294 | |||
295 | RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __func__)); | ||
296 | |||
297 | if (IS_8723A_A_CUT(pHalData->VersionID)) { | ||
298 | fw_name = "rtlwifi/rtl8723aufw.bin"; | ||
299 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
300 | ("rtl8723a_FirmwareDownload: R8723FwImageArray_UMC " | ||
301 | "for RTL8723A A CUT\n")); | ||
302 | } else if (IS_8723A_B_CUT(pHalData->VersionID)) { | ||
303 | /* WLAN Fw. */ | ||
304 | if (padapter->registrypriv.wifi_spec == 1) { | ||
305 | fw_name = "rtlwifi/rtl8723aufw_B_NoBT.bin"; | ||
306 | DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithoutBT for " | ||
307 | "RTL8723A B CUT\n"); | ||
308 | } else { | ||
309 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
310 | fw_name = "rtlwifi/rtl8723aufw_B.bin"; | ||
311 | DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithBT for " | ||
312 | "RTL8723A B CUT\n"); | ||
313 | #else | ||
314 | fw_name = "rtlwifi/rtl8723aufw_B_NoBT.bin"; | ||
315 | DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithoutBT for " | ||
316 | "RTL8723A B CUT\n"); | ||
317 | #endif | ||
318 | } | ||
319 | } else { | ||
320 | /* <Roger_TODO> We should download proper RAM Code here | ||
321 | to match the ROM code. */ | ||
322 | RT_TRACE(_module_hal_init_c_, _drv_err_, | ||
323 | ("%s: unknow version!\n", __func__)); | ||
324 | rtStatus = _FAIL; | ||
325 | goto Exit; | ||
326 | } | ||
327 | |||
328 | pr_info("rtl8723au: Loading firmware %s\n", fw_name); | ||
329 | if (request_firmware(&fw, fw_name, device)) { | ||
330 | pr_err("rtl8723au: request_firmware load failed\n"); | ||
331 | rtStatus = _FAIL; | ||
332 | goto Exit; | ||
333 | } | ||
334 | if (!fw) { | ||
335 | pr_err("rtl8723au: Firmware %s not available\n", fw_name); | ||
336 | rtStatus = _FAIL; | ||
337 | goto Exit; | ||
338 | } | ||
339 | firmware_buf = kzalloc(fw->size, GFP_KERNEL); | ||
340 | if (!firmware_buf) { | ||
341 | rtStatus = _FAIL; | ||
342 | goto Exit; | ||
343 | } | ||
344 | memcpy(firmware_buf, fw->data, fw->size); | ||
345 | buf = firmware_buf; | ||
346 | fw_size = fw->size; | ||
347 | release_firmware(fw); | ||
348 | |||
349 | /* To Check Fw header. Added by tynli. 2009.12.04. */ | ||
350 | pFwHdr = (struct rt_8723a_firmware_hdr *)firmware_buf; | ||
351 | |||
352 | pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version); | ||
353 | pHalData->FirmwareSubVersion = pFwHdr->Subversion; | ||
354 | pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature); | ||
355 | |||
356 | DBG_8723A("%s: fw_ver =%d fw_subver =%d sig = 0x%x\n", | ||
357 | __func__, pHalData->FirmwareVersion, | ||
358 | pHalData->FirmwareSubVersion, pHalData->FirmwareSignature); | ||
359 | |||
360 | if (!log_version++) | ||
361 | pr_info("%sFirmware Version %d, SubVersion %d, Signature " | ||
362 | "0x%x\n", DRIVER_PREFIX, pHalData->FirmwareVersion, | ||
363 | pHalData->FirmwareSubVersion, | ||
364 | pHalData->FirmwareSignature); | ||
365 | |||
366 | if (IS_FW_HEADER_EXIST(pFwHdr)) { | ||
367 | /* Shift 32 bytes for FW header */ | ||
368 | buf = buf + 32; | ||
369 | fw_size = fw_size - 32; | ||
370 | } | ||
371 | |||
372 | /* Suggested by Filen. If 8051 is running in RAM code, driver should | ||
373 | inform Fw to reset by itself, */ | ||
374 | /* or it will cause download Fw fail. 2010.02.01. by tynli. */ | ||
375 | if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { | ||
376 | /* 8051 RAM code */ | ||
377 | rtl8723a_FirmwareSelfReset(padapter); | ||
378 | rtw_write8(padapter, REG_MCUFWDL, 0x00); | ||
379 | } | ||
380 | |||
381 | _FWDownloadEnable(padapter, true); | ||
382 | fwdl_start_time = jiffies; | ||
383 | while (1) { | ||
384 | /* reset the FWDL chksum */ | ||
385 | rtw_write8(padapter, REG_MCUFWDL, | ||
386 | rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt); | ||
387 | |||
388 | rtStatus = _WriteFW(padapter, buf, fw_size); | ||
389 | |||
390 | if (rtStatus == _SUCCESS || | ||
391 | (rtw_get_passing_time_ms23a(fwdl_start_time) > 500 && | ||
392 | writeFW_retry++ >= 3)) | ||
393 | break; | ||
394 | |||
395 | DBG_8723A("%s writeFW_retry:%u, time after fwdl_start_time:" | ||
396 | "%ums\n", __func__, writeFW_retry, | ||
397 | jiffies_to_msecs(jiffies - fwdl_start_time)); | ||
398 | } | ||
399 | _FWDownloadEnable(padapter, false); | ||
400 | if (_SUCCESS != rtStatus) { | ||
401 | DBG_8723A("DL Firmware failed!\n"); | ||
402 | goto Exit; | ||
403 | } | ||
404 | |||
405 | rtStatus = _FWFreeToGo(padapter); | ||
406 | if (_SUCCESS != rtStatus) { | ||
407 | RT_TRACE(_module_hal_init_c_, _drv_err_, | ||
408 | ("DL Firmware failed!\n")); | ||
409 | goto Exit; | ||
410 | } | ||
411 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
412 | ("Firmware is ready to run!\n")); | ||
413 | |||
414 | Exit: | ||
415 | kfree(firmware_buf); | ||
416 | return rtStatus; | ||
417 | } | ||
418 | |||
419 | void rtl8723a_InitializeFirmwareVars(struct rtw_adapter *padapter) | ||
420 | { | ||
421 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
422 | |||
423 | /* Init Fw LPS related. */ | ||
424 | padapter->pwrctrlpriv.bFwCurrentInPSMode = false; | ||
425 | |||
426 | /* Init H2C counter. by tynli. 2009.12.09. */ | ||
427 | pHalData->LastHMEBoxNum = 0; | ||
428 | } | ||
429 | |||
430 | static void rtl8723a_free_hal_data(struct rtw_adapter *padapter) | ||
431 | { | ||
432 | |||
433 | kfree(padapter->HalData); | ||
434 | padapter->HalData = NULL; | ||
435 | |||
436 | } | ||
437 | |||
438 | /* */ | ||
439 | /* Efuse related code */ | ||
440 | /* */ | ||
441 | static u8 | ||
442 | hal_EfuseSwitchToBank(struct rtw_adapter *padapter, u8 bank) | ||
443 | { | ||
444 | u8 bRet = false; | ||
445 | u32 value32 = 0; | ||
446 | |||
447 | DBG_8723A("%s: Efuse switch bank to %d\n", __func__, bank); | ||
448 | value32 = rtw_read32(padapter, EFUSE_TEST); | ||
449 | bRet = true; | ||
450 | switch (bank) { | ||
451 | case 0: | ||
452 | value32 = (value32 & ~EFUSE_SEL_MASK) | | ||
453 | EFUSE_SEL(EFUSE_WIFI_SEL_0); | ||
454 | break; | ||
455 | case 1: | ||
456 | value32 = (value32 & ~EFUSE_SEL_MASK) | | ||
457 | EFUSE_SEL(EFUSE_BT_SEL_0); | ||
458 | break; | ||
459 | case 2: | ||
460 | value32 = (value32 & ~EFUSE_SEL_MASK) | | ||
461 | EFUSE_SEL(EFUSE_BT_SEL_1); | ||
462 | break; | ||
463 | case 3: | ||
464 | value32 = (value32 & ~EFUSE_SEL_MASK) | | ||
465 | EFUSE_SEL(EFUSE_BT_SEL_2); | ||
466 | break; | ||
467 | default: | ||
468 | value32 = (value32 & ~EFUSE_SEL_MASK) | | ||
469 | EFUSE_SEL(EFUSE_WIFI_SEL_0); | ||
470 | bRet = false; | ||
471 | break; | ||
472 | } | ||
473 | rtw_write32(padapter, EFUSE_TEST, value32); | ||
474 | |||
475 | return bRet; | ||
476 | } | ||
477 | |||
478 | static void | ||
479 | Hal_GetEfuseDefinition(struct rtw_adapter *padapter, | ||
480 | u8 efuseType, u8 type, void *pOut) | ||
481 | { | ||
482 | u8 *pu1Tmp; | ||
483 | u16 *pu2Tmp; | ||
484 | u8 *pMax_section; | ||
485 | |||
486 | switch (type) { | ||
487 | case TYPE_EFUSE_MAX_SECTION: | ||
488 | pMax_section = (u8 *) pOut; | ||
489 | |||
490 | if (efuseType == EFUSE_WIFI) | ||
491 | *pMax_section = EFUSE_MAX_SECTION_8723A; | ||
492 | else | ||
493 | *pMax_section = EFUSE_BT_MAX_SECTION; | ||
494 | break; | ||
495 | |||
496 | case TYPE_EFUSE_REAL_CONTENT_LEN: | ||
497 | pu2Tmp = (u16 *) pOut; | ||
498 | |||
499 | if (efuseType == EFUSE_WIFI) | ||
500 | *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A; | ||
501 | else | ||
502 | *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN; | ||
503 | break; | ||
504 | |||
505 | case TYPE_AVAILABLE_EFUSE_BYTES_BANK: | ||
506 | pu2Tmp = (u16 *) pOut; | ||
507 | |||
508 | if (efuseType == EFUSE_WIFI) | ||
509 | *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A - | ||
510 | EFUSE_OOB_PROTECT_BYTES); | ||
511 | else | ||
512 | *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN - | ||
513 | EFUSE_PROTECT_BYTES_BANK); | ||
514 | break; | ||
515 | |||
516 | case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: | ||
517 | pu2Tmp = (u16 *) pOut; | ||
518 | |||
519 | if (efuseType == EFUSE_WIFI) | ||
520 | *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A - | ||
521 | EFUSE_OOB_PROTECT_BYTES); | ||
522 | else | ||
523 | *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN - | ||
524 | (EFUSE_PROTECT_BYTES_BANK * 3)); | ||
525 | break; | ||
526 | |||
527 | case TYPE_EFUSE_MAP_LEN: | ||
528 | pu2Tmp = (u16 *) pOut; | ||
529 | |||
530 | if (efuseType == EFUSE_WIFI) | ||
531 | *pu2Tmp = EFUSE_MAP_LEN_8723A; | ||
532 | else | ||
533 | *pu2Tmp = EFUSE_BT_MAP_LEN; | ||
534 | break; | ||
535 | |||
536 | case TYPE_EFUSE_PROTECT_BYTES_BANK: | ||
537 | pu1Tmp = (u8 *) pOut; | ||
538 | |||
539 | if (efuseType == EFUSE_WIFI) | ||
540 | *pu1Tmp = EFUSE_OOB_PROTECT_BYTES; | ||
541 | else | ||
542 | *pu1Tmp = EFUSE_PROTECT_BYTES_BANK; | ||
543 | break; | ||
544 | |||
545 | case TYPE_EFUSE_CONTENT_LEN_BANK: | ||
546 | pu2Tmp = (u16 *) pOut; | ||
547 | |||
548 | if (efuseType == EFUSE_WIFI) | ||
549 | *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A; | ||
550 | else | ||
551 | *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN; | ||
552 | break; | ||
553 | |||
554 | default: | ||
555 | pu1Tmp = (u8 *) pOut; | ||
556 | *pu1Tmp = 0; | ||
557 | break; | ||
558 | } | ||
559 | } | ||
560 | |||
561 | #define VOLTAGE_V25 0x03 | ||
562 | #define LDOE25_SHIFT 28 | ||
563 | |||
564 | static void | ||
565 | Hal_EfusePowerSwitch(struct rtw_adapter *padapter, u8 bWrite, u8 PwrState) | ||
566 | { | ||
567 | u8 tempval; | ||
568 | u16 tmpV16; | ||
569 | |||
570 | if (PwrState == true) { | ||
571 | rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); | ||
572 | |||
573 | /* 1.2V Power: From VDDON with Power | ||
574 | Cut(0x0000h[15]), defualt valid */ | ||
575 | tmpV16 = rtw_read16(padapter, REG_SYS_ISO_CTRL); | ||
576 | if (!(tmpV16 & PWC_EV12V)) { | ||
577 | tmpV16 |= PWC_EV12V; | ||
578 | rtw_write16(padapter, REG_SYS_ISO_CTRL, tmpV16); | ||
579 | } | ||
580 | /* Reset: 0x0000h[28], default valid */ | ||
581 | tmpV16 = rtw_read16(padapter, REG_SYS_FUNC_EN); | ||
582 | if (!(tmpV16 & FEN_ELDR)) { | ||
583 | tmpV16 |= FEN_ELDR; | ||
584 | rtw_write16(padapter, REG_SYS_FUNC_EN, tmpV16); | ||
585 | } | ||
586 | |||
587 | /* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock | ||
588 | from ANA, default valid */ | ||
589 | tmpV16 = rtw_read16(padapter, REG_SYS_CLKR); | ||
590 | if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) { | ||
591 | tmpV16 |= (LOADER_CLK_EN | ANA8M); | ||
592 | rtw_write16(padapter, REG_SYS_CLKR, tmpV16); | ||
593 | } | ||
594 | |||
595 | if (bWrite == true) { | ||
596 | /* Enable LDO 2.5V before read/write action */ | ||
597 | tempval = rtw_read8(padapter, EFUSE_TEST + 3); | ||
598 | tempval &= 0x0F; | ||
599 | tempval |= (VOLTAGE_V25 << 4); | ||
600 | rtw_write8(padapter, EFUSE_TEST + 3, (tempval | 0x80)); | ||
601 | } | ||
602 | } else { | ||
603 | rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); | ||
604 | |||
605 | if (bWrite == true) { | ||
606 | /* Disable LDO 2.5V after read/write action */ | ||
607 | tempval = rtw_read8(padapter, EFUSE_TEST + 3); | ||
608 | rtw_write8(padapter, EFUSE_TEST + 3, (tempval & 0x7F)); | ||
609 | } | ||
610 | } | ||
611 | } | ||
612 | |||
613 | static void | ||
614 | hal_ReadEFuse_WiFi(struct rtw_adapter *padapter, | ||
615 | u16 _offset, u16 _size_byte, u8 *pbuf) | ||
616 | { | ||
617 | u8 *efuseTbl = NULL; | ||
618 | u16 eFuse_Addr = 0; | ||
619 | u8 offset, wden; | ||
620 | u8 efuseHeader, efuseExtHdr, efuseData; | ||
621 | u16 i, total, used; | ||
622 | |||
623 | /* Do NOT excess total size of EFuse table. | ||
624 | Added by Roger, 2008.11.10. */ | ||
625 | if ((_offset + _size_byte) > EFUSE_MAP_LEN_8723A) { | ||
626 | DBG_8723A("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", | ||
627 | __func__, _offset, _size_byte); | ||
628 | return; | ||
629 | } | ||
630 | |||
631 | efuseTbl = (u8 *) kmalloc(EFUSE_MAP_LEN_8723A, GFP_KERNEL); | ||
632 | if (efuseTbl == NULL) { | ||
633 | DBG_8723A("%s: alloc efuseTbl fail!\n", __func__); | ||
634 | return; | ||
635 | } | ||
636 | /* 0xff will be efuse default value instead of 0x00. */ | ||
637 | memset(efuseTbl, 0xFF, EFUSE_MAP_LEN_8723A); | ||
638 | |||
639 | /* switch bank back to bank 0 for later BT and wifi use. */ | ||
640 | hal_EfuseSwitchToBank(padapter, 0); | ||
641 | |||
642 | while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) { | ||
643 | ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseHeader); | ||
644 | if (efuseHeader == 0xFF) { | ||
645 | DBG_8723A("%s: data end at address =%#x\n", __func__, | ||
646 | eFuse_Addr); | ||
647 | break; | ||
648 | } | ||
649 | |||
650 | /* Check PG header for section num. */ | ||
651 | if (EXT_HEADER(efuseHeader)) { /* extended header */ | ||
652 | offset = GET_HDR_OFFSET_2_0(efuseHeader); | ||
653 | |||
654 | ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseExtHdr); | ||
655 | if (ALL_WORDS_DISABLED(efuseExtHdr)) { | ||
656 | continue; | ||
657 | } | ||
658 | |||
659 | offset |= ((efuseExtHdr & 0xF0) >> 1); | ||
660 | wden = (efuseExtHdr & 0x0F); | ||
661 | } else { | ||
662 | offset = ((efuseHeader >> 4) & 0x0f); | ||
663 | wden = (efuseHeader & 0x0f); | ||
664 | } | ||
665 | |||
666 | if (offset < EFUSE_MAX_SECTION_8723A) { | ||
667 | u16 addr; | ||
668 | /* Get word enable value from PG header */ | ||
669 | |||
670 | addr = offset * PGPKT_DATA_SIZE; | ||
671 | for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { | ||
672 | /* Check word enable condition in the section */ | ||
673 | if (!(wden & (0x01 << i))) { | ||
674 | ReadEFuseByte23a(padapter, eFuse_Addr++, | ||
675 | &efuseData); | ||
676 | efuseTbl[addr] = efuseData; | ||
677 | |||
678 | ReadEFuseByte23a(padapter, eFuse_Addr++, | ||
679 | &efuseData); | ||
680 | efuseTbl[addr + 1] = efuseData; | ||
681 | } | ||
682 | addr += 2; | ||
683 | } | ||
684 | } else { | ||
685 | DBG_8723A(KERN_ERR "%s: offset(%d) is illegal!!\n", | ||
686 | __func__, offset); | ||
687 | eFuse_Addr += Efuse_CalculateWordCnts23a(wden) * 2; | ||
688 | } | ||
689 | } | ||
690 | |||
691 | /* Copy from Efuse map to output pointer memory!!! */ | ||
692 | for (i = 0; i < _size_byte; i++) | ||
693 | pbuf[i] = efuseTbl[_offset + i]; | ||
694 | |||
695 | /* Calculate Efuse utilization */ | ||
696 | EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI, | ||
697 | TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total); | ||
698 | used = eFuse_Addr - 1; | ||
699 | rtw_hal_set_hwreg23a(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&used); | ||
700 | |||
701 | kfree(efuseTbl); | ||
702 | } | ||
703 | |||
704 | static void | ||
705 | hal_ReadEFuse_BT(struct rtw_adapter *padapter, | ||
706 | u16 _offset, u16 _size_byte, u8 *pbuf) | ||
707 | { | ||
708 | u8 *efuseTbl; | ||
709 | u8 bank; | ||
710 | u16 eFuse_Addr; | ||
711 | u8 efuseHeader, efuseExtHdr, efuseData; | ||
712 | u8 offset, wden; | ||
713 | u16 i, total, used; | ||
714 | |||
715 | /* Do NOT excess total size of EFuse table. | ||
716 | Added by Roger, 2008.11.10. */ | ||
717 | if ((_offset + _size_byte) > EFUSE_BT_MAP_LEN) { | ||
718 | DBG_8723A("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", | ||
719 | __func__, _offset, _size_byte); | ||
720 | return; | ||
721 | } | ||
722 | |||
723 | efuseTbl = kmalloc(EFUSE_BT_MAP_LEN, GFP_KERNEL); | ||
724 | if (efuseTbl == NULL) { | ||
725 | DBG_8723A("%s: efuseTbl malloc fail!\n", __func__); | ||
726 | return; | ||
727 | } | ||
728 | /* 0xff will be efuse default value instead of 0x00. */ | ||
729 | memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN); | ||
730 | |||
731 | EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT, | ||
732 | TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total); | ||
733 | |||
734 | for (bank = 1; bank < EFUSE_MAX_BANK; bank++) { | ||
735 | if (hal_EfuseSwitchToBank(padapter, bank) == false) { | ||
736 | DBG_8723A("%s: hal_EfuseSwitchToBank Fail!!\n", | ||
737 | __func__); | ||
738 | goto exit; | ||
739 | } | ||
740 | |||
741 | eFuse_Addr = 0; | ||
742 | |||
743 | while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) { | ||
744 | ReadEFuseByte23a(padapter, eFuse_Addr++, &efuseHeader); | ||
745 | if (efuseHeader == 0xFF) | ||
746 | break; | ||
747 | |||
748 | /* Check PG header for section num. */ | ||
749 | if (EXT_HEADER(efuseHeader)) { /* extended header */ | ||
750 | offset = GET_HDR_OFFSET_2_0(efuseHeader); | ||
751 | |||
752 | ReadEFuseByte23a(padapter, eFuse_Addr++, | ||
753 | &efuseExtHdr); | ||
754 | if (ALL_WORDS_DISABLED(efuseExtHdr)) { | ||
755 | continue; | ||
756 | } | ||
757 | |||
758 | offset |= ((efuseExtHdr & 0xF0) >> 1); | ||
759 | wden = (efuseExtHdr & 0x0F); | ||
760 | } else { | ||
761 | offset = ((efuseHeader >> 4) & 0x0f); | ||
762 | wden = (efuseHeader & 0x0f); | ||
763 | } | ||
764 | |||
765 | if (offset < EFUSE_BT_MAX_SECTION) { | ||
766 | u16 addr; | ||
767 | |||
768 | /* Get word enable value from PG header */ | ||
769 | |||
770 | addr = offset * PGPKT_DATA_SIZE; | ||
771 | for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { | ||
772 | /* Check word enable condition in | ||
773 | the section */ | ||
774 | if (!(wden & (0x01 << i))) { | ||
775 | ReadEFuseByte23a(padapter, | ||
776 | eFuse_Addr++, | ||
777 | &efuseData); | ||
778 | efuseTbl[addr] = efuseData; | ||
779 | |||
780 | ReadEFuseByte23a(padapter, | ||
781 | eFuse_Addr++, | ||
782 | &efuseData); | ||
783 | efuseTbl[addr + 1] = efuseData; | ||
784 | } | ||
785 | addr += 2; | ||
786 | } | ||
787 | } else { | ||
788 | DBG_8723A(KERN_ERR | ||
789 | "%s: offset(%d) is illegal!!\n", | ||
790 | __func__, offset); | ||
791 | eFuse_Addr += Efuse_CalculateWordCnts23a(wden) * 2; | ||
792 | } | ||
793 | } | ||
794 | |||
795 | if ((eFuse_Addr - 1) < total) { | ||
796 | DBG_8723A("%s: bank(%d) data end at %#x\n", | ||
797 | __func__, bank, eFuse_Addr - 1); | ||
798 | break; | ||
799 | } | ||
800 | } | ||
801 | |||
802 | /* switch bank back to bank 0 for later BT and wifi use. */ | ||
803 | hal_EfuseSwitchToBank(padapter, 0); | ||
804 | |||
805 | /* Copy from Efuse map to output pointer memory!!! */ | ||
806 | for (i = 0; i < _size_byte; i++) | ||
807 | pbuf[i] = efuseTbl[_offset + i]; | ||
808 | |||
809 | /* */ | ||
810 | /* Calculate Efuse utilization. */ | ||
811 | /* */ | ||
812 | EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT, | ||
813 | TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total); | ||
814 | used = (EFUSE_BT_REAL_BANK_CONTENT_LEN * (bank - 1)) + eFuse_Addr - 1; | ||
815 | rtw_hal_set_hwreg23a(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *) &used); | ||
816 | |||
817 | exit: | ||
818 | kfree(efuseTbl); | ||
819 | } | ||
820 | |||
821 | static void | ||
822 | Hal_ReadEFuse(struct rtw_adapter *padapter, | ||
823 | u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf) | ||
824 | { | ||
825 | if (efuseType == EFUSE_WIFI) | ||
826 | hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf); | ||
827 | else | ||
828 | hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf); | ||
829 | } | ||
830 | |||
831 | static u16 | ||
832 | hal_EfuseGetCurrentSize_WiFi(struct rtw_adapter *padapter) | ||
833 | { | ||
834 | u16 efuse_addr = 0; | ||
835 | u8 hoffset = 0, hworden = 0; | ||
836 | u8 efuse_data, word_cnts = 0; | ||
837 | |||
838 | rtw23a_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *) &efuse_addr); | ||
839 | |||
840 | DBG_8723A("%s: start_efuse_addr = 0x%X\n", __func__, efuse_addr); | ||
841 | |||
842 | /* switch bank back to bank 0 for later BT and wifi use. */ | ||
843 | hal_EfuseSwitchToBank(padapter, 0); | ||
844 | |||
845 | while (AVAILABLE_EFUSE_ADDR(efuse_addr)) { | ||
846 | if (efuse_OneByteRead23a(padapter, efuse_addr, &efuse_data) == | ||
847 | false) { | ||
848 | DBG_8723A(KERN_ERR "%s: efuse_OneByteRead23a Fail! " | ||
849 | "addr = 0x%X !!\n", __func__, efuse_addr); | ||
850 | break; | ||
851 | } | ||
852 | |||
853 | if (efuse_data == 0xFF) | ||
854 | break; | ||
855 | |||
856 | if (EXT_HEADER(efuse_data)) { | ||
857 | hoffset = GET_HDR_OFFSET_2_0(efuse_data); | ||
858 | efuse_addr++; | ||
859 | efuse_OneByteRead23a(padapter, efuse_addr, &efuse_data); | ||
860 | if (ALL_WORDS_DISABLED(efuse_data)) { | ||
861 | continue; | ||
862 | } | ||
863 | |||
864 | hoffset |= ((efuse_data & 0xF0) >> 1); | ||
865 | hworden = efuse_data & 0x0F; | ||
866 | } else { | ||
867 | hoffset = (efuse_data >> 4) & 0x0F; | ||
868 | hworden = efuse_data & 0x0F; | ||
869 | } | ||
870 | |||
871 | word_cnts = Efuse_CalculateWordCnts23a(hworden); | ||
872 | efuse_addr += (word_cnts * 2) + 1; | ||
873 | } | ||
874 | |||
875 | rtw_hal_set_hwreg23a(padapter, HW_VAR_EFUSE_BYTES, (u8 *) &efuse_addr); | ||
876 | |||
877 | DBG_8723A("%s: CurrentSize =%d\n", __func__, efuse_addr); | ||
878 | |||
879 | return efuse_addr; | ||
880 | } | ||
881 | |||
882 | static u16 | ||
883 | hal_EfuseGetCurrentSize_BT(struct rtw_adapter *padapter) | ||
884 | { | ||
885 | u16 btusedbytes; | ||
886 | u16 efuse_addr; | ||
887 | u8 bank, startBank; | ||
888 | u8 hoffset = 0, hworden = 0; | ||
889 | u8 efuse_data, word_cnts = 0; | ||
890 | u16 retU2 = 0; | ||
891 | |||
892 | rtw23a_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *) &btusedbytes); | ||
893 | |||
894 | efuse_addr = (u16) ((btusedbytes % EFUSE_BT_REAL_BANK_CONTENT_LEN)); | ||
895 | startBank = (u8) (1 + (btusedbytes / EFUSE_BT_REAL_BANK_CONTENT_LEN)); | ||
896 | |||
897 | DBG_8723A("%s: start from bank =%d addr = 0x%X\n", __func__, startBank, | ||
898 | efuse_addr); | ||
899 | |||
900 | EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT, | ||
901 | TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2); | ||
902 | |||
903 | for (bank = startBank; bank < EFUSE_MAX_BANK; bank++) { | ||
904 | if (hal_EfuseSwitchToBank(padapter, bank) == false) { | ||
905 | DBG_8723A(KERN_ERR "%s: switch bank(%d) Fail!!\n", | ||
906 | __func__, bank); | ||
907 | bank = EFUSE_MAX_BANK; | ||
908 | break; | ||
909 | } | ||
910 | |||
911 | /* only when bank is switched we have to reset | ||
912 | the efuse_addr. */ | ||
913 | if (bank != startBank) | ||
914 | efuse_addr = 0; | ||
915 | |||
916 | while (AVAILABLE_EFUSE_ADDR(efuse_addr)) { | ||
917 | if (efuse_OneByteRead23a(padapter, efuse_addr, | ||
918 | &efuse_data) == false) { | ||
919 | DBG_8723A(KERN_ERR "%s: efuse_OneByteRead23a Fail!" | ||
920 | " addr = 0x%X !!\n", | ||
921 | __func__, efuse_addr); | ||
922 | bank = EFUSE_MAX_BANK; | ||
923 | break; | ||
924 | } | ||
925 | |||
926 | if (efuse_data == 0xFF) | ||
927 | break; | ||
928 | |||
929 | if (EXT_HEADER(efuse_data)) { | ||
930 | hoffset = GET_HDR_OFFSET_2_0(efuse_data); | ||
931 | efuse_addr++; | ||
932 | efuse_OneByteRead23a(padapter, efuse_addr, | ||
933 | &efuse_data); | ||
934 | if (ALL_WORDS_DISABLED(efuse_data)) { | ||
935 | efuse_addr++; | ||
936 | continue; | ||
937 | } | ||
938 | |||
939 | hoffset |= ((efuse_data & 0xF0) >> 1); | ||
940 | hworden = efuse_data & 0x0F; | ||
941 | } else { | ||
942 | hoffset = (efuse_data >> 4) & 0x0F; | ||
943 | hworden = efuse_data & 0x0F; | ||
944 | } | ||
945 | word_cnts = Efuse_CalculateWordCnts23a(hworden); | ||
946 | /* read next header */ | ||
947 | efuse_addr += (word_cnts * 2) + 1; | ||
948 | } | ||
949 | |||
950 | /* Check if we need to check next bank efuse */ | ||
951 | if (efuse_addr < retU2) { | ||
952 | break; /* don't need to check next bank. */ | ||
953 | } | ||
954 | } | ||
955 | |||
956 | retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr; | ||
957 | rtw_hal_set_hwreg23a(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&retU2); | ||
958 | |||
959 | DBG_8723A("%s: CurrentSize =%d\n", __func__, retU2); | ||
960 | return retU2; | ||
961 | } | ||
962 | |||
963 | static u16 | ||
964 | Hal_EfuseGetCurrentSize(struct rtw_adapter *pAdapter, u8 efuseType) | ||
965 | { | ||
966 | u16 ret = 0; | ||
967 | |||
968 | if (efuseType == EFUSE_WIFI) | ||
969 | ret = hal_EfuseGetCurrentSize_WiFi(pAdapter); | ||
970 | else | ||
971 | ret = hal_EfuseGetCurrentSize_BT(pAdapter); | ||
972 | |||
973 | return ret; | ||
974 | } | ||
975 | |||
976 | static u8 | ||
977 | Hal_EfuseWordEnableDataWrite(struct rtw_adapter *padapter, | ||
978 | u16 efuse_addr, u8 word_en, u8 *data) | ||
979 | { | ||
980 | u16 tmpaddr = 0; | ||
981 | u16 start_addr = efuse_addr; | ||
982 | u8 badworden = 0x0F; | ||
983 | u8 tmpdata[PGPKT_DATA_SIZE]; | ||
984 | |||
985 | memset(tmpdata, 0xFF, PGPKT_DATA_SIZE); | ||
986 | |||
987 | if (!(word_en & BIT(0))) { | ||
988 | tmpaddr = start_addr; | ||
989 | efuse_OneByteWrite23a(padapter, start_addr++, data[0]); | ||
990 | efuse_OneByteWrite23a(padapter, start_addr++, data[1]); | ||
991 | |||
992 | efuse_OneByteRead23a(padapter, tmpaddr, &tmpdata[0]); | ||
993 | efuse_OneByteRead23a(padapter, tmpaddr + 1, &tmpdata[1]); | ||
994 | if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1])) { | ||
995 | badworden &= (~BIT(0)); | ||
996 | } | ||
997 | } | ||
998 | if (!(word_en & BIT(1))) { | ||
999 | tmpaddr = start_addr; | ||
1000 | efuse_OneByteWrite23a(padapter, start_addr++, data[2]); | ||
1001 | efuse_OneByteWrite23a(padapter, start_addr++, data[3]); | ||
1002 | |||
1003 | efuse_OneByteRead23a(padapter, tmpaddr, &tmpdata[2]); | ||
1004 | efuse_OneByteRead23a(padapter, tmpaddr + 1, &tmpdata[3]); | ||
1005 | if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3])) { | ||
1006 | badworden &= (~BIT(1)); | ||
1007 | } | ||
1008 | } | ||
1009 | if (!(word_en & BIT(2))) { | ||
1010 | tmpaddr = start_addr; | ||
1011 | efuse_OneByteWrite23a(padapter, start_addr++, data[4]); | ||
1012 | efuse_OneByteWrite23a(padapter, start_addr++, data[5]); | ||
1013 | |||
1014 | efuse_OneByteRead23a(padapter, tmpaddr, &tmpdata[4]); | ||
1015 | efuse_OneByteRead23a(padapter, tmpaddr + 1, &tmpdata[5]); | ||
1016 | if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5])) { | ||
1017 | badworden &= (~BIT(2)); | ||
1018 | } | ||
1019 | } | ||
1020 | if (!(word_en & BIT(3))) { | ||
1021 | tmpaddr = start_addr; | ||
1022 | efuse_OneByteWrite23a(padapter, start_addr++, data[6]); | ||
1023 | efuse_OneByteWrite23a(padapter, start_addr++, data[7]); | ||
1024 | |||
1025 | efuse_OneByteRead23a(padapter, tmpaddr, &tmpdata[6]); | ||
1026 | efuse_OneByteRead23a(padapter, tmpaddr + 1, &tmpdata[7]); | ||
1027 | if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7])) { | ||
1028 | badworden &= (~BIT(3)); | ||
1029 | } | ||
1030 | } | ||
1031 | |||
1032 | return badworden; | ||
1033 | } | ||
1034 | |||
1035 | static s32 | ||
1036 | Hal_EfusePgPacketRead(struct rtw_adapter *padapter, u8 offset, u8 *data) | ||
1037 | { | ||
1038 | u8 efuse_data, word_cnts = 0; | ||
1039 | u16 efuse_addr = 0; | ||
1040 | u8 hoffset = 0, hworden = 0; | ||
1041 | u8 i; | ||
1042 | u8 max_section = 0; | ||
1043 | s32 ret; | ||
1044 | |||
1045 | if (data == NULL) | ||
1046 | return false; | ||
1047 | |||
1048 | EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, | ||
1049 | &max_section); | ||
1050 | if (offset > max_section) { | ||
1051 | DBG_8723A("%s: Packet offset(%d) is illegal(>%d)!\n", | ||
1052 | __func__, offset, max_section); | ||
1053 | return false; | ||
1054 | } | ||
1055 | |||
1056 | memset(data, 0xFF, PGPKT_DATA_SIZE); | ||
1057 | ret = true; | ||
1058 | |||
1059 | /* */ | ||
1060 | /* <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the | ||
1061 | end of Efuse by CP. */ | ||
1062 | /* Skip dummy parts to prevent unexpected data read from Efuse. */ | ||
1063 | /* By pass right now. 2009.02.19. */ | ||
1064 | /* */ | ||
1065 | while (AVAILABLE_EFUSE_ADDR(efuse_addr)) { | ||
1066 | if (efuse_OneByteRead23a(padapter, efuse_addr++, &efuse_data) == | ||
1067 | false) { | ||
1068 | ret = false; | ||
1069 | break; | ||
1070 | } | ||
1071 | |||
1072 | if (efuse_data == 0xFF) | ||
1073 | break; | ||
1074 | |||
1075 | if (EXT_HEADER(efuse_data)) { | ||
1076 | hoffset = GET_HDR_OFFSET_2_0(efuse_data); | ||
1077 | efuse_OneByteRead23a(padapter, efuse_addr++, &efuse_data); | ||
1078 | if (ALL_WORDS_DISABLED(efuse_data)) { | ||
1079 | DBG_8723A("%s: Error!! All words disabled!\n", | ||
1080 | __func__); | ||
1081 | continue; | ||
1082 | } | ||
1083 | |||
1084 | hoffset |= ((efuse_data & 0xF0) >> 1); | ||
1085 | hworden = efuse_data & 0x0F; | ||
1086 | } else { | ||
1087 | hoffset = (efuse_data >> 4) & 0x0F; | ||
1088 | hworden = efuse_data & 0x0F; | ||
1089 | } | ||
1090 | |||
1091 | if (hoffset == offset) { | ||
1092 | for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { | ||
1093 | /* Check word enable condition in the section */ | ||
1094 | if (!(hworden & (0x01 << i))) { | ||
1095 | ReadEFuseByte23a(padapter, efuse_addr++, | ||
1096 | &efuse_data); | ||
1097 | data[i * 2] = efuse_data; | ||
1098 | |||
1099 | ReadEFuseByte23a(padapter, efuse_addr++, | ||
1100 | &efuse_data); | ||
1101 | data[(i * 2) + 1] = efuse_data; | ||
1102 | } | ||
1103 | } | ||
1104 | } else { | ||
1105 | word_cnts = Efuse_CalculateWordCnts23a(hworden); | ||
1106 | efuse_addr += word_cnts * 2; | ||
1107 | } | ||
1108 | } | ||
1109 | |||
1110 | return ret; | ||
1111 | } | ||
1112 | |||
1113 | static u8 | ||
1114 | hal_EfusePgCheckAvailableAddr(struct rtw_adapter *pAdapter, u8 efuseType) | ||
1115 | { | ||
1116 | u16 max_available = 0; | ||
1117 | u16 current_size; | ||
1118 | |||
1119 | EFUSE_GetEfuseDefinition23a(pAdapter, efuseType, | ||
1120 | TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, | ||
1121 | &max_available); | ||
1122 | |||
1123 | current_size = Efuse_GetCurrentSize23a(pAdapter, efuseType); | ||
1124 | if (current_size >= max_available) { | ||
1125 | DBG_8723A("%s: Error!! current_size(%d)>max_available(%d)\n", | ||
1126 | __func__, current_size, max_available); | ||
1127 | return false; | ||
1128 | } | ||
1129 | return true; | ||
1130 | } | ||
1131 | |||
1132 | static void | ||
1133 | hal_EfuseConstructPGPkt(u8 offset, u8 word_en, u8 *pData, | ||
1134 | struct pg_pkt_struct *pTargetPkt) | ||
1135 | { | ||
1136 | memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE); | ||
1137 | pTargetPkt->offset = offset; | ||
1138 | pTargetPkt->word_en = word_en; | ||
1139 | efuse_WordEnableDataRead23a(word_en, pData, pTargetPkt->data); | ||
1140 | pTargetPkt->word_cnts = Efuse_CalculateWordCnts23a(pTargetPkt->word_en); | ||
1141 | } | ||
1142 | |||
1143 | static u8 | ||
1144 | hal_EfusePartialWriteCheck(struct rtw_adapter *padapter, u8 efuseType, | ||
1145 | u16 *pAddr, struct pg_pkt_struct *pTargetPkt) | ||
1146 | { | ||
1147 | u8 bRet = false; | ||
1148 | u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0; | ||
1149 | u8 efuse_data = 0; | ||
1150 | |||
1151 | EFUSE_GetEfuseDefinition23a(padapter, efuseType, | ||
1152 | TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, | ||
1153 | &efuse_max_available_len); | ||
1154 | EFUSE_GetEfuseDefinition23a(padapter, efuseType, | ||
1155 | TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max); | ||
1156 | |||
1157 | if (efuseType == EFUSE_WIFI) { | ||
1158 | rtw23a_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, | ||
1159 | (u8 *) &startAddr); | ||
1160 | } else { | ||
1161 | rtw23a_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, | ||
1162 | (u8 *) &startAddr); | ||
1163 | } | ||
1164 | startAddr %= efuse_max; | ||
1165 | |||
1166 | while (1) { | ||
1167 | if (startAddr >= efuse_max_available_len) { | ||
1168 | bRet = false; | ||
1169 | DBG_8723A("%s: startAddr(%d) >= efuse_max_available_" | ||
1170 | "len(%d)\n", __func__, startAddr, | ||
1171 | efuse_max_available_len); | ||
1172 | break; | ||
1173 | } | ||
1174 | |||
1175 | if (efuse_OneByteRead23a(padapter, startAddr, &efuse_data) && | ||
1176 | (efuse_data != 0xFF)) { | ||
1177 | bRet = false; | ||
1178 | DBG_8723A("%s: Something Wrong! last bytes(%#X = 0x%02X) " | ||
1179 | "is not 0xFF\n", __func__, | ||
1180 | startAddr, efuse_data); | ||
1181 | break; | ||
1182 | } else { | ||
1183 | /* not used header, 0xff */ | ||
1184 | *pAddr = startAddr; | ||
1185 | bRet = true; | ||
1186 | break; | ||
1187 | } | ||
1188 | } | ||
1189 | |||
1190 | return bRet; | ||
1191 | } | ||
1192 | |||
1193 | static u8 | ||
1194 | hal_EfusePgPacketWrite1ByteHeader(struct rtw_adapter *pAdapter, u8 efuseType, | ||
1195 | u16 *pAddr, struct pg_pkt_struct *pTargetPkt) | ||
1196 | { | ||
1197 | u8 pg_header = 0, tmp_header = 0; | ||
1198 | u16 efuse_addr = *pAddr; | ||
1199 | u8 repeatcnt = 0; | ||
1200 | |||
1201 | pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en; | ||
1202 | |||
1203 | do { | ||
1204 | efuse_OneByteWrite23a(pAdapter, efuse_addr, pg_header); | ||
1205 | efuse_OneByteRead23a(pAdapter, efuse_addr, &tmp_header); | ||
1206 | if (tmp_header != 0xFF) | ||
1207 | break; | ||
1208 | if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) { | ||
1209 | DBG_8723A("%s: Repeat over limit for pg_header!!\n", | ||
1210 | __func__); | ||
1211 | return false; | ||
1212 | } | ||
1213 | } while (1); | ||
1214 | |||
1215 | if (tmp_header != pg_header) { | ||
1216 | DBG_8723A(KERN_ERR "%s: PG Header Fail!!(pg = 0x%02X " | ||
1217 | "read = 0x%02X)\n", __func__, | ||
1218 | pg_header, tmp_header); | ||
1219 | return false; | ||
1220 | } | ||
1221 | |||
1222 | *pAddr = efuse_addr; | ||
1223 | |||
1224 | return true; | ||
1225 | } | ||
1226 | |||
1227 | static u8 | ||
1228 | hal_EfusePgPacketWrite2ByteHeader(struct rtw_adapter *padapter, u8 efuseType, | ||
1229 | u16 *pAddr, struct pg_pkt_struct *pTargetPkt) | ||
1230 | { | ||
1231 | u16 efuse_addr, efuse_max_available_len = 0; | ||
1232 | u8 pg_header = 0, tmp_header = 0; | ||
1233 | u8 repeatcnt = 0; | ||
1234 | |||
1235 | EFUSE_GetEfuseDefinition23a(padapter, efuseType, | ||
1236 | TYPE_AVAILABLE_EFUSE_BYTES_BANK, | ||
1237 | &efuse_max_available_len); | ||
1238 | |||
1239 | efuse_addr = *pAddr; | ||
1240 | if (efuse_addr >= efuse_max_available_len) { | ||
1241 | DBG_8723A("%s: addr(%d) over avaliable(%d)!!\n", __func__, | ||
1242 | efuse_addr, efuse_max_available_len); | ||
1243 | return false; | ||
1244 | } | ||
1245 | |||
1246 | pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F; | ||
1247 | |||
1248 | do { | ||
1249 | efuse_OneByteWrite23a(padapter, efuse_addr, pg_header); | ||
1250 | efuse_OneByteRead23a(padapter, efuse_addr, &tmp_header); | ||
1251 | if (tmp_header != 0xFF) | ||
1252 | break; | ||
1253 | if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) { | ||
1254 | DBG_8723A("%s: Repeat over limit for pg_header!!\n", | ||
1255 | __func__); | ||
1256 | return false; | ||
1257 | } | ||
1258 | } while (1); | ||
1259 | |||
1260 | if (tmp_header != pg_header) { | ||
1261 | DBG_8723A(KERN_ERR | ||
1262 | "%s: PG Header Fail!!(pg = 0x%02X read = 0x%02X)\n", | ||
1263 | __func__, pg_header, tmp_header); | ||
1264 | return false; | ||
1265 | } | ||
1266 | |||
1267 | /* to write ext_header */ | ||
1268 | efuse_addr++; | ||
1269 | pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en; | ||
1270 | |||
1271 | do { | ||
1272 | efuse_OneByteWrite23a(padapter, efuse_addr, pg_header); | ||
1273 | efuse_OneByteRead23a(padapter, efuse_addr, &tmp_header); | ||
1274 | if (tmp_header != 0xFF) | ||
1275 | break; | ||
1276 | if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) { | ||
1277 | DBG_8723A("%s: Repeat over limit for ext_header!!\n", | ||
1278 | __func__); | ||
1279 | return false; | ||
1280 | } | ||
1281 | } while (1); | ||
1282 | |||
1283 | if (tmp_header != pg_header) { /* offset PG fail */ | ||
1284 | DBG_8723A(KERN_ERR | ||
1285 | "%s: PG EXT Header Fail!!(pg = 0x%02X read = 0x%02X)\n", | ||
1286 | __func__, pg_header, tmp_header); | ||
1287 | return false; | ||
1288 | } | ||
1289 | |||
1290 | *pAddr = efuse_addr; | ||
1291 | |||
1292 | return true; | ||
1293 | } | ||
1294 | |||
1295 | static u8 | ||
1296 | hal_EfusePgPacketWriteHeader(struct rtw_adapter *padapter, u8 efuseType, | ||
1297 | u16 *pAddr, struct pg_pkt_struct *pTargetPkt) | ||
1298 | { | ||
1299 | u8 bRet = false; | ||
1300 | |||
1301 | if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE) { | ||
1302 | bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, | ||
1303 | pAddr, pTargetPkt); | ||
1304 | } else { | ||
1305 | bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, | ||
1306 | pAddr, pTargetPkt); | ||
1307 | } | ||
1308 | |||
1309 | return bRet; | ||
1310 | } | ||
1311 | |||
1312 | static u8 | ||
1313 | hal_EfusePgPacketWriteData(struct rtw_adapter *pAdapter, u8 efuseType, | ||
1314 | u16 *pAddr, struct pg_pkt_struct *pTargetPkt) | ||
1315 | { | ||
1316 | u16 efuse_addr; | ||
1317 | u8 badworden; | ||
1318 | |||
1319 | efuse_addr = *pAddr; | ||
1320 | badworden = | ||
1321 | Efuse_WordEnableDataWrite23a(pAdapter, efuse_addr + 1, | ||
1322 | pTargetPkt->word_en, pTargetPkt->data); | ||
1323 | if (badworden != 0x0F) { | ||
1324 | DBG_8723A("%s: Fail!!\n", __func__); | ||
1325 | return false; | ||
1326 | } | ||
1327 | |||
1328 | return true; | ||
1329 | } | ||
1330 | |||
1331 | static s32 | ||
1332 | Hal_EfusePgPacketWrite(struct rtw_adapter *padapter, | ||
1333 | u8 offset, u8 word_en, u8 *pData) | ||
1334 | { | ||
1335 | struct pg_pkt_struct targetPkt; | ||
1336 | u16 startAddr = 0; | ||
1337 | u8 efuseType = EFUSE_WIFI; | ||
1338 | |||
1339 | if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType)) | ||
1340 | return false; | ||
1341 | |||
1342 | hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt); | ||
1343 | |||
1344 | if (!hal_EfusePartialWriteCheck(padapter, efuseType, | ||
1345 | &startAddr, &targetPkt)) | ||
1346 | return false; | ||
1347 | |||
1348 | if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, | ||
1349 | &startAddr, &targetPkt)) | ||
1350 | return false; | ||
1351 | |||
1352 | if (!hal_EfusePgPacketWriteData(padapter, efuseType, | ||
1353 | &startAddr, &targetPkt)) | ||
1354 | return false; | ||
1355 | |||
1356 | return true; | ||
1357 | } | ||
1358 | |||
1359 | static bool | ||
1360 | Hal_EfusePgPacketWrite_BT(struct rtw_adapter *pAdapter, | ||
1361 | u8 offset, u8 word_en, u8 *pData) | ||
1362 | { | ||
1363 | struct pg_pkt_struct targetPkt; | ||
1364 | u16 startAddr = 0; | ||
1365 | u8 efuseType = EFUSE_BT; | ||
1366 | |||
1367 | if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType)) | ||
1368 | return false; | ||
1369 | |||
1370 | hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt); | ||
1371 | |||
1372 | if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, | ||
1373 | &startAddr, &targetPkt)) | ||
1374 | return false; | ||
1375 | |||
1376 | if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, | ||
1377 | &startAddr, &targetPkt)) | ||
1378 | return false; | ||
1379 | |||
1380 | if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, | ||
1381 | &startAddr, &targetPkt)) | ||
1382 | return false; | ||
1383 | |||
1384 | return true; | ||
1385 | } | ||
1386 | |||
1387 | static struct hal_version ReadChipVersion8723A(struct rtw_adapter *padapter) | ||
1388 | { | ||
1389 | u32 value32; | ||
1390 | struct hal_version ChipVersion; | ||
1391 | struct hal_data_8723a *pHalData; | ||
1392 | |||
1393 | pHalData = GET_HAL_DATA(padapter); | ||
1394 | |||
1395 | value32 = rtw_read32(padapter, REG_SYS_CFG); | ||
1396 | ChipVersion.ICType = CHIP_8723A; | ||
1397 | ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP); | ||
1398 | ChipVersion.RFType = RF_TYPE_1T1R; | ||
1399 | ChipVersion.VendorType = | ||
1400 | ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC); | ||
1401 | ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /* IC version (CUT) */ | ||
1402 | |||
1403 | /* For regulator mode. by tynli. 2011.01.14 */ | ||
1404 | pHalData->RegulatorMode = ((value32 & SPS_SEL) ? | ||
1405 | RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR); | ||
1406 | |||
1407 | value32 = rtw_read32(padapter, REG_GPIO_OUTSTS); | ||
1408 | /* ROM code version. */ | ||
1409 | ChipVersion.ROMVer = ((value32 & RF_RL_ID) >> 20); | ||
1410 | |||
1411 | /* For multi-function consideration. Added by Roger, 2010.10.06. */ | ||
1412 | pHalData->MultiFunc = RT_MULTI_FUNC_NONE; | ||
1413 | value32 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL); | ||
1414 | pHalData->MultiFunc |= | ||
1415 | ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0); | ||
1416 | pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0); | ||
1417 | pHalData->MultiFunc |= | ||
1418 | ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0); | ||
1419 | pHalData->PolarityCtl = | ||
1420 | ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : | ||
1421 | RT_POLARITY_LOW_ACT); | ||
1422 | dump_chip_info23a(ChipVersion); | ||
1423 | pHalData->VersionID = ChipVersion; | ||
1424 | |||
1425 | if (IS_1T2R(ChipVersion)) | ||
1426 | pHalData->rf_type = RF_1T2R; | ||
1427 | else if (IS_2T2R(ChipVersion)) | ||
1428 | pHalData->rf_type = RF_2T2R; | ||
1429 | else | ||
1430 | pHalData->rf_type = RF_1T1R; | ||
1431 | |||
1432 | MSG_8723A("RF_Type is %x!!\n", pHalData->rf_type); | ||
1433 | |||
1434 | return ChipVersion; | ||
1435 | } | ||
1436 | |||
1437 | static void rtl8723a_read_chip_version(struct rtw_adapter *padapter) | ||
1438 | { | ||
1439 | ReadChipVersion8723A(padapter); | ||
1440 | } | ||
1441 | |||
1442 | /* */ | ||
1443 | /* */ | ||
1444 | /* 20100209 Joseph: */ | ||
1445 | /* This function is used only for 92C to set REG_BCN_CTRL(0x550) register. */ | ||
1446 | /* We just reserve the value of the register in variable | ||
1447 | pHalData->RegBcnCtrlVal and then operate */ | ||
1448 | /* the value of the register via atomic operation. */ | ||
1449 | /* This prevents from race condition when setting this register. */ | ||
1450 | /* The value of pHalData->RegBcnCtrlVal is initialized in | ||
1451 | HwConfigureRTL8192CE() function. */ | ||
1452 | /* */ | ||
1453 | void SetBcnCtrlReg23a(struct rtw_adapter *padapter, u8 SetBits, u8 ClearBits) | ||
1454 | { | ||
1455 | struct hal_data_8723a *pHalData; | ||
1456 | u32 addr; | ||
1457 | u8 *pRegBcnCtrlVal; | ||
1458 | |||
1459 | pHalData = GET_HAL_DATA(padapter); | ||
1460 | pRegBcnCtrlVal = (u8 *)&pHalData->RegBcnCtrlVal; | ||
1461 | |||
1462 | addr = REG_BCN_CTRL; | ||
1463 | |||
1464 | *pRegBcnCtrlVal = rtw_read8(padapter, addr); | ||
1465 | *pRegBcnCtrlVal |= SetBits; | ||
1466 | *pRegBcnCtrlVal &= ~ClearBits; | ||
1467 | |||
1468 | rtw_write8(padapter, addr, *pRegBcnCtrlVal); | ||
1469 | } | ||
1470 | |||
1471 | void rtl8723a_InitBeaconParameters(struct rtw_adapter *padapter) | ||
1472 | { | ||
1473 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
1474 | |||
1475 | rtw_write16(padapter, REG_BCN_CTRL, 0x1010); | ||
1476 | pHalData->RegBcnCtrlVal = 0x1010; | ||
1477 | |||
1478 | /* TODO: Remove these magic number */ | ||
1479 | rtw_write16(padapter, REG_TBTT_PROHIBIT, 0x6404); /* ms */ | ||
1480 | /* Firmware will control REG_DRVERLYINT when power saving is enable, */ | ||
1481 | /* so don't set this register on STA mode. */ | ||
1482 | if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == false) | ||
1483 | rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME); | ||
1484 | /* 2ms */ | ||
1485 | rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); | ||
1486 | |||
1487 | /* Suggested by designer timchen. Change beacon AIFS to the | ||
1488 | largest number beacause test chip does not contension before | ||
1489 | sending beacon. by tynli. 2009.11.03 */ | ||
1490 | rtw_write16(padapter, REG_BCNTCFG, 0x660F); | ||
1491 | } | ||
1492 | |||
1493 | static void ResumeTxBeacon(struct rtw_adapter *padapter) | ||
1494 | { | ||
1495 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
1496 | |||
1497 | /* 2010.03.01. Marked by tynli. No need to call workitem beacause | ||
1498 | we record the value */ | ||
1499 | /* which should be read from register to a global variable. */ | ||
1500 | |||
1501 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n")); | ||
1502 | |||
1503 | pHalData->RegFwHwTxQCtrl |= BIT(6); | ||
1504 | rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl); | ||
1505 | rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0xff); | ||
1506 | pHalData->RegReg542 |= BIT(0); | ||
1507 | rtw_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542); | ||
1508 | } | ||
1509 | |||
1510 | static void StopTxBeacon(struct rtw_adapter *padapter) | ||
1511 | { | ||
1512 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
1513 | |||
1514 | /* 2010.03.01. Marked by tynli. No need to call workitem beacause | ||
1515 | we record the value */ | ||
1516 | /* which should be read from register to a global variable. */ | ||
1517 | |||
1518 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n")); | ||
1519 | |||
1520 | pHalData->RegFwHwTxQCtrl &= ~BIT(6); | ||
1521 | rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, pHalData->RegFwHwTxQCtrl); | ||
1522 | rtw_write8(padapter, REG_TBTT_PROHIBIT + 1, 0x64); | ||
1523 | pHalData->RegReg542 &= ~BIT(0); | ||
1524 | rtw_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542); | ||
1525 | |||
1526 | CheckFwRsvdPageContent23a(padapter); /* 2010.06.23. Added by tynli. */ | ||
1527 | } | ||
1528 | |||
1529 | static void _BeaconFunctionEnable(struct rtw_adapter *padapter, u8 Enable, | ||
1530 | u8 Linked) | ||
1531 | { | ||
1532 | SetBcnCtrlReg23a(padapter, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB, | ||
1533 | 0); | ||
1534 | rtw_write8(padapter, REG_RD_CTRL + 1, 0x6F); | ||
1535 | } | ||
1536 | |||
1537 | static void rtl8723a_SetBeaconRelatedRegisters(struct rtw_adapter *padapter) | ||
1538 | { | ||
1539 | u32 value32; | ||
1540 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; | ||
1541 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; | ||
1542 | |||
1543 | /* reset TSF, enable update TSF, correcting TSF On Beacon */ | ||
1544 | |||
1545 | /* REG_BCN_INTERVAL */ | ||
1546 | /* REG_BCNDMATIM */ | ||
1547 | /* REG_ATIMWND */ | ||
1548 | /* REG_TBTT_PROHIBIT */ | ||
1549 | /* REG_DRVERLYINT */ | ||
1550 | /* REG_BCN_MAX_ERR */ | ||
1551 | /* REG_BCNTCFG (0x510) */ | ||
1552 | /* REG_DUAL_TSF_RST */ | ||
1553 | /* REG_BCN_CTRL (0x550) */ | ||
1554 | |||
1555 | /* */ | ||
1556 | /* ATIM window */ | ||
1557 | /* */ | ||
1558 | rtw_write16(padapter, REG_ATIMWND, 2); | ||
1559 | |||
1560 | /* */ | ||
1561 | /* Beacon interval (in unit of TU). */ | ||
1562 | /* */ | ||
1563 | rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval); | ||
1564 | |||
1565 | rtl8723a_InitBeaconParameters(padapter); | ||
1566 | |||
1567 | rtw_write8(padapter, REG_SLOT, 0x09); | ||
1568 | |||
1569 | /* */ | ||
1570 | /* Reset TSF Timer to zero, added by Roger. 2008.06.24 */ | ||
1571 | /* */ | ||
1572 | value32 = rtw_read32(padapter, REG_TCR); | ||
1573 | value32 &= ~TSFRST; | ||
1574 | rtw_write32(padapter, REG_TCR, value32); | ||
1575 | |||
1576 | value32 |= TSFRST; | ||
1577 | rtw_write32(padapter, REG_TCR, value32); | ||
1578 | |||
1579 | /* NOTE: Fix test chip's bug (about contention windows's randomness) */ | ||
1580 | if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE | | ||
1581 | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE) == true) { | ||
1582 | rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50); | ||
1583 | rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50); | ||
1584 | } | ||
1585 | |||
1586 | _BeaconFunctionEnable(padapter, true, true); | ||
1587 | |||
1588 | ResumeTxBeacon(padapter); | ||
1589 | SetBcnCtrlReg23a(padapter, DIS_BCNQ_SUB, 0); | ||
1590 | } | ||
1591 | |||
1592 | static void rtl8723a_GetHalODMVar(struct rtw_adapter *Adapter, | ||
1593 | enum hal_odm_variable eVariable, | ||
1594 | void *pValue1, bool bSet) | ||
1595 | { | ||
1596 | switch (eVariable) { | ||
1597 | case HAL_ODM_STA_INFO: | ||
1598 | break; | ||
1599 | default: | ||
1600 | break; | ||
1601 | } | ||
1602 | } | ||
1603 | |||
1604 | static void rtl8723a_SetHalODMVar(struct rtw_adapter *Adapter, | ||
1605 | enum hal_odm_variable eVariable, | ||
1606 | void *pValue1, bool bSet) | ||
1607 | { | ||
1608 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1609 | struct dm_odm_t *podmpriv = &pHalData->odmpriv; | ||
1610 | switch (eVariable) { | ||
1611 | case HAL_ODM_STA_INFO: | ||
1612 | { | ||
1613 | struct sta_info *psta = (struct sta_info *)pValue1; | ||
1614 | |||
1615 | if (bSet) { | ||
1616 | DBG_8723A("Set STA_(%d) info\n", psta->mac_id); | ||
1617 | ODM_CmnInfoPtrArrayHook23a(podmpriv, | ||
1618 | ODM_CMNINFO_STA_STATUS, | ||
1619 | psta->mac_id, psta); | ||
1620 | } else { | ||
1621 | DBG_8723A("Clean STA_(%d) info\n", psta->mac_id); | ||
1622 | ODM_CmnInfoPtrArrayHook23a(podmpriv, | ||
1623 | ODM_CMNINFO_STA_STATUS, | ||
1624 | psta->mac_id, NULL); | ||
1625 | } | ||
1626 | } | ||
1627 | break; | ||
1628 | case HAL_ODM_P2P_STATE: | ||
1629 | ODM_CmnInfoUpdate23a(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet); | ||
1630 | break; | ||
1631 | case HAL_ODM_WIFI_DISPLAY_STATE: | ||
1632 | ODM_CmnInfoUpdate23a(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet); | ||
1633 | break; | ||
1634 | default: | ||
1635 | break; | ||
1636 | } | ||
1637 | } | ||
1638 | |||
1639 | static void hal_notch_filter_8723a(struct rtw_adapter *adapter, bool enable) | ||
1640 | { | ||
1641 | if (enable) { | ||
1642 | DBG_8723A("Enable notch filter\n"); | ||
1643 | rtw_write8(adapter, rOFDM0_RxDSP + 1, | ||
1644 | rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT1); | ||
1645 | } else { | ||
1646 | DBG_8723A("Disable notch filter\n"); | ||
1647 | rtw_write8(adapter, rOFDM0_RxDSP + 1, | ||
1648 | rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT1); | ||
1649 | } | ||
1650 | } | ||
1651 | |||
1652 | s32 c2h_id_filter_ccx_8723a(u8 id) | ||
1653 | { | ||
1654 | s32 ret = false; | ||
1655 | if (id == C2H_CCX_TX_RPT) | ||
1656 | ret = true; | ||
1657 | |||
1658 | return ret; | ||
1659 | } | ||
1660 | |||
1661 | static s32 c2h_handler_8723a(struct rtw_adapter *padapter, | ||
1662 | struct c2h_evt_hdr *c2h_evt) | ||
1663 | { | ||
1664 | s32 ret = _SUCCESS; | ||
1665 | u8 i = 0; | ||
1666 | |||
1667 | if (c2h_evt == NULL) { | ||
1668 | DBG_8723A("%s c2h_evt is NULL\n", __func__); | ||
1669 | ret = _FAIL; | ||
1670 | goto exit; | ||
1671 | } | ||
1672 | |||
1673 | switch (c2h_evt->id) { | ||
1674 | case C2H_DBG: | ||
1675 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
1676 | ("C2HCommandHandler: %s\n", c2h_evt->payload)); | ||
1677 | break; | ||
1678 | |||
1679 | case C2H_CCX_TX_RPT: | ||
1680 | handle_txrpt_ccx_8723a(padapter, c2h_evt->payload); | ||
1681 | break; | ||
1682 | case C2H_EXT_RA_RPT: | ||
1683 | break; | ||
1684 | case C2H_HW_INFO_EXCH: | ||
1685 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
1686 | ("[BT], C2H_HW_INFO_EXCH\n")); | ||
1687 | for (i = 0; i < c2h_evt->plen; i++) { | ||
1688 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
1689 | ("[BT], tmpBuf[%d]= 0x%x\n", i, | ||
1690 | c2h_evt->payload[i])); | ||
1691 | } | ||
1692 | break; | ||
1693 | |||
1694 | case C2H_C2H_H2C_TEST: | ||
1695 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
1696 | ("[BT], C2H_H2C_TEST\n")); | ||
1697 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
1698 | ("[BT], tmpBuf[0]/[1]/[2]/[3]/[4]= 0x%x/ 0x%x/ " | ||
1699 | "0x%x/ 0x%x/ 0x%x\n", c2h_evt->payload[0], | ||
1700 | c2h_evt->payload[1], c2h_evt->payload[2], | ||
1701 | c2h_evt->payload[3], c2h_evt->payload[4])); | ||
1702 | break; | ||
1703 | |||
1704 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
1705 | case C2H_BT_INFO: | ||
1706 | DBG_8723A("%s , Got C2H_BT_INFO \n", __func__); | ||
1707 | BT_FwC2hBtInfo(padapter, c2h_evt->payload, c2h_evt->plen); | ||
1708 | break; | ||
1709 | #endif | ||
1710 | |||
1711 | default: | ||
1712 | ret = _FAIL; | ||
1713 | break; | ||
1714 | } | ||
1715 | |||
1716 | exit: | ||
1717 | return ret; | ||
1718 | } | ||
1719 | |||
1720 | void rtl8723a_set_hal_ops(struct hal_ops *pHalFunc) | ||
1721 | { | ||
1722 | pHalFunc->free_hal_data = &rtl8723a_free_hal_data; | ||
1723 | |||
1724 | pHalFunc->dm_init = &rtl8723a_init_dm_priv; | ||
1725 | pHalFunc->dm_deinit = &rtl8723a_deinit_dm_priv; | ||
1726 | |||
1727 | pHalFunc->read_chip_version = &rtl8723a_read_chip_version; | ||
1728 | |||
1729 | pHalFunc->set_bwmode_handler = &PHY_SetBWMode23a8723A; | ||
1730 | pHalFunc->set_channel_handler = &PHY_SwChnl8723A; | ||
1731 | |||
1732 | pHalFunc->hal_dm_watchdog = &rtl8723a_HalDmWatchDog; | ||
1733 | |||
1734 | pHalFunc->SetBeaconRelatedRegistersHandler = | ||
1735 | &rtl8723a_SetBeaconRelatedRegisters; | ||
1736 | |||
1737 | pHalFunc->Add_RateATid = &rtl8723a_add_rateatid; | ||
1738 | pHalFunc->run_thread = &rtl8723a_start_thread; | ||
1739 | pHalFunc->cancel_thread = &rtl8723a_stop_thread; | ||
1740 | |||
1741 | pHalFunc->read_bbreg = &PHY_QueryBBReg; | ||
1742 | pHalFunc->write_bbreg = &PHY_SetBBReg; | ||
1743 | pHalFunc->read_rfreg = &PHY_QueryRFReg; | ||
1744 | pHalFunc->write_rfreg = &PHY_SetRFReg; | ||
1745 | |||
1746 | /* Efuse related function */ | ||
1747 | pHalFunc->EfusePowerSwitch = &Hal_EfusePowerSwitch; | ||
1748 | pHalFunc->ReadEFuse = &Hal_ReadEFuse; | ||
1749 | pHalFunc->EFUSEGetEfuseDefinition = &Hal_GetEfuseDefinition; | ||
1750 | pHalFunc->EfuseGetCurrentSize = &Hal_EfuseGetCurrentSize; | ||
1751 | pHalFunc->Efuse_PgPacketRead23a = &Hal_EfusePgPacketRead; | ||
1752 | pHalFunc->Efuse_PgPacketWrite23a = &Hal_EfusePgPacketWrite; | ||
1753 | pHalFunc->Efuse_WordEnableDataWrite23a = &Hal_EfuseWordEnableDataWrite; | ||
1754 | pHalFunc->Efuse_PgPacketWrite23a_BT = &Hal_EfusePgPacketWrite_BT; | ||
1755 | |||
1756 | pHalFunc->sreset_init_value23a = &sreset_init_value23a; | ||
1757 | pHalFunc->sreset_reset_value23a = &sreset_reset_value23a; | ||
1758 | pHalFunc->silentreset = &sreset_reset; | ||
1759 | pHalFunc->sreset_xmit_status_check = &rtl8723a_sreset_xmit_status_check; | ||
1760 | pHalFunc->sreset_linked_status_check = | ||
1761 | &rtl8723a_sreset_linked_status_check; | ||
1762 | pHalFunc->sreset_get_wifi_status23a = &sreset_get_wifi_status23a; | ||
1763 | pHalFunc->sreset_inprogress = &sreset_inprogress; | ||
1764 | pHalFunc->GetHalODMVarHandler = &rtl8723a_GetHalODMVar; | ||
1765 | pHalFunc->SetHalODMVarHandler = &rtl8723a_SetHalODMVar; | ||
1766 | |||
1767 | pHalFunc->hal_notch_filter = &hal_notch_filter_8723a; | ||
1768 | |||
1769 | pHalFunc->c2h_handler = c2h_handler_8723a; | ||
1770 | pHalFunc->c2h_id_filter_ccx = c2h_id_filter_ccx_8723a; | ||
1771 | } | ||
1772 | |||
1773 | void rtl8723a_InitAntenna_Selection(struct rtw_adapter *padapter) | ||
1774 | { | ||
1775 | struct hal_data_8723a *pHalData; | ||
1776 | u8 val; | ||
1777 | |||
1778 | pHalData = GET_HAL_DATA(padapter); | ||
1779 | |||
1780 | val = rtw_read8(padapter, REG_LEDCFG2); | ||
1781 | /* Let 8051 take control antenna settting */ | ||
1782 | val |= BIT(7); /* DPDT_SEL_EN, 0x4C[23] */ | ||
1783 | rtw_write8(padapter, REG_LEDCFG2, val); | ||
1784 | } | ||
1785 | |||
1786 | void rtl8723a_CheckAntenna_Selection(struct rtw_adapter *padapter) | ||
1787 | { | ||
1788 | struct hal_data_8723a *pHalData; | ||
1789 | u8 val; | ||
1790 | |||
1791 | pHalData = GET_HAL_DATA(padapter); | ||
1792 | |||
1793 | val = rtw_read8(padapter, REG_LEDCFG2); | ||
1794 | /* Let 8051 take control antenna settting */ | ||
1795 | if (!(val & BIT(7))) { | ||
1796 | val |= BIT(7); /* DPDT_SEL_EN, 0x4C[23] */ | ||
1797 | rtw_write8(padapter, REG_LEDCFG2, val); | ||
1798 | } | ||
1799 | } | ||
1800 | |||
1801 | void rtl8723a_DeinitAntenna_Selection(struct rtw_adapter *padapter) | ||
1802 | { | ||
1803 | struct hal_data_8723a *pHalData; | ||
1804 | u8 val; | ||
1805 | |||
1806 | pHalData = GET_HAL_DATA(padapter); | ||
1807 | val = rtw_read8(padapter, REG_LEDCFG2); | ||
1808 | /* Let 8051 take control antenna settting */ | ||
1809 | val &= ~BIT(7); /* DPDT_SEL_EN, clear 0x4C[23] */ | ||
1810 | rtw_write8(padapter, REG_LEDCFG2, val); | ||
1811 | } | ||
1812 | |||
1813 | void rtl8723a_init_default_value(struct rtw_adapter *padapter) | ||
1814 | { | ||
1815 | struct hal_data_8723a *pHalData; | ||
1816 | struct dm_priv *pdmpriv; | ||
1817 | u8 i; | ||
1818 | |||
1819 | pHalData = GET_HAL_DATA(padapter); | ||
1820 | pdmpriv = &pHalData->dmpriv; | ||
1821 | |||
1822 | /* init default value */ | ||
1823 | pHalData->fw_ractrl = false; | ||
1824 | pHalData->bIQKInitialized = false; | ||
1825 | if (!padapter->pwrctrlpriv.bkeepfwalive) | ||
1826 | pHalData->LastHMEBoxNum = 0; | ||
1827 | |||
1828 | pHalData->bIQKInitialized = false; | ||
1829 | |||
1830 | /* init dm default value */ | ||
1831 | pdmpriv->TM_Trigger = 0; /* for IQK */ | ||
1832 | /* pdmpriv->binitialized = false; */ | ||
1833 | /* pdmpriv->prv_traffic_idx = 3; */ | ||
1834 | /* pdmpriv->initialize = 0; */ | ||
1835 | |||
1836 | pdmpriv->ThermalValue_HP_index = 0; | ||
1837 | for (i = 0; i < HP_THERMAL_NUM; i++) | ||
1838 | pdmpriv->ThermalValue_HP[i] = 0; | ||
1839 | |||
1840 | /* init Efuse variables */ | ||
1841 | pHalData->EfuseUsedBytes = 0; | ||
1842 | pHalData->BTEfuseUsedBytes = 0; | ||
1843 | } | ||
1844 | |||
1845 | u8 GetEEPROMSize8723A(struct rtw_adapter *padapter) | ||
1846 | { | ||
1847 | u8 size = 0; | ||
1848 | u32 cr; | ||
1849 | |||
1850 | cr = rtw_read16(padapter, REG_9346CR); | ||
1851 | /* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */ | ||
1852 | size = (cr & BOOT_FROM_EEPROM) ? 6 : 4; | ||
1853 | |||
1854 | MSG_8723A("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46"); | ||
1855 | |||
1856 | return size; | ||
1857 | } | ||
1858 | |||
1859 | /* */ | ||
1860 | /* */ | ||
1861 | /* LLT R/W/Init function */ | ||
1862 | /* */ | ||
1863 | /* */ | ||
1864 | static s32 _LLTWrite(struct rtw_adapter *padapter, u32 address, u32 data) | ||
1865 | { | ||
1866 | s32 status = _SUCCESS; | ||
1867 | s32 count = 0; | ||
1868 | u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | | ||
1869 | _LLT_OP(_LLT_WRITE_ACCESS); | ||
1870 | u16 LLTReg = REG_LLT_INIT; | ||
1871 | |||
1872 | rtw_write32(padapter, LLTReg, value); | ||
1873 | |||
1874 | /* polling */ | ||
1875 | do { | ||
1876 | value = rtw_read32(padapter, LLTReg); | ||
1877 | if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) { | ||
1878 | break; | ||
1879 | } | ||
1880 | |||
1881 | if (count > POLLING_LLT_THRESHOLD) { | ||
1882 | RT_TRACE(_module_hal_init_c_, _drv_err_, | ||
1883 | ("Failed to polling write LLT done at " | ||
1884 | "address %d!\n", address)); | ||
1885 | status = _FAIL; | ||
1886 | break; | ||
1887 | } | ||
1888 | } while (count++); | ||
1889 | |||
1890 | return status; | ||
1891 | } | ||
1892 | |||
1893 | s32 InitLLTTable23a(struct rtw_adapter *padapter, u32 boundary) | ||
1894 | { | ||
1895 | s32 status = _SUCCESS; | ||
1896 | u32 i; | ||
1897 | u32 txpktbuf_bndy = boundary; | ||
1898 | u32 Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER; | ||
1899 | |||
1900 | for (i = 0; i < (txpktbuf_bndy - 1); i++) { | ||
1901 | status = _LLTWrite(padapter, i, i + 1); | ||
1902 | if (_SUCCESS != status) { | ||
1903 | return status; | ||
1904 | } | ||
1905 | } | ||
1906 | |||
1907 | /* end of list */ | ||
1908 | status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF); | ||
1909 | if (_SUCCESS != status) { | ||
1910 | return status; | ||
1911 | } | ||
1912 | |||
1913 | /* Make the other pages as ring buffer */ | ||
1914 | /* This ring buffer is used as beacon buffer if we config this | ||
1915 | MAC as two MAC transfer. */ | ||
1916 | /* Otherwise used as local loopback buffer. */ | ||
1917 | for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) { | ||
1918 | status = _LLTWrite(padapter, i, (i + 1)); | ||
1919 | if (_SUCCESS != status) { | ||
1920 | return status; | ||
1921 | } | ||
1922 | } | ||
1923 | |||
1924 | /* Let last entry point to the start entry of ring buffer */ | ||
1925 | status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy); | ||
1926 | if (_SUCCESS != status) { | ||
1927 | return status; | ||
1928 | } | ||
1929 | |||
1930 | return status; | ||
1931 | } | ||
1932 | |||
1933 | static void _DisableGPIO(struct rtw_adapter *padapter) | ||
1934 | { | ||
1935 | /*************************************** | ||
1936 | j. GPIO_PIN_CTRL 0x44[31:0]= 0x000 | ||
1937 | k.Value = GPIO_PIN_CTRL[7:0] | ||
1938 | l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); write external PIN level | ||
1939 | m. GPIO_MUXCFG 0x42 [15:0] = 0x0780 | ||
1940 | n. LEDCFG 0x4C[15:0] = 0x8080 | ||
1941 | ***************************************/ | ||
1942 | u32 value32; | ||
1943 | u32 u4bTmp; | ||
1944 | |||
1945 | /* 1. Disable GPIO[7:0] */ | ||
1946 | rtw_write16(padapter, REG_GPIO_PIN_CTRL + 2, 0x0000); | ||
1947 | value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF; | ||
1948 | u4bTmp = value32 & 0x000000FF; | ||
1949 | value32 |= ((u4bTmp << 8) | 0x00FF0000); | ||
1950 | rtw_write32(padapter, REG_GPIO_PIN_CTRL, value32); | ||
1951 | |||
1952 | /* */ | ||
1953 | /* <Roger_Notes> For RTL8723u multi-function configuration which | ||
1954 | was autoload from Efuse offset 0x0a and 0x0b, */ | ||
1955 | /* WLAN HW GPIO[9], GPS HW GPIO[10] and BT HW GPIO[11]. */ | ||
1956 | /* Added by Roger, 2010.10.07. */ | ||
1957 | /* */ | ||
1958 | /* 2. Disable GPIO[8] and GPIO[12] */ | ||
1959 | |||
1960 | /* Configure all pins as input mode. */ | ||
1961 | rtw_write16(padapter, REG_GPIO_IO_SEL_2, 0x0000); | ||
1962 | value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL_2) & 0xFFFF001F; | ||
1963 | u4bTmp = value32 & 0x0000001F; | ||
1964 | /* Set pin 8, 10, 11 and pin 12 to output mode. */ | ||
1965 | value32 |= ((u4bTmp << 8) | 0x001D0000); | ||
1966 | rtw_write32(padapter, REG_GPIO_PIN_CTRL_2, value32); | ||
1967 | |||
1968 | /* 3. Disable LED0 & 1 */ | ||
1969 | rtw_write16(padapter, REG_LEDCFG0, 0x8080); | ||
1970 | } /* end of _DisableGPIO() */ | ||
1971 | |||
1972 | static void _DisableRFAFEAndResetBB8192C(struct rtw_adapter *padapter) | ||
1973 | { | ||
1974 | /************************************** | ||
1975 | a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue | ||
1976 | b. RF path 0 offset 0x00 = 0x00 disable RF | ||
1977 | c. APSD_CTRL 0x600[7:0] = 0x40 | ||
1978 | d. SYS_FUNC_EN 0x02[7:0] = 0x16 reset BB state machine | ||
1979 | e. SYS_FUNC_EN 0x02[7:0] = 0x14 reset BB state machine | ||
1980 | ***************************************/ | ||
1981 | u8 eRFPath = 0, value8 = 0; | ||
1982 | |||
1983 | rtw_write8(padapter, REG_TXPAUSE, 0xFF); | ||
1984 | |||
1985 | PHY_SetRFReg(padapter, (enum RF_RADIO_PATH) eRFPath, 0x0, bMaskByte0, 0x0); | ||
1986 | |||
1987 | value8 |= APSDOFF; | ||
1988 | rtw_write8(padapter, REG_APSD_CTRL, value8); /* 0x40 */ | ||
1989 | |||
1990 | /* Set BB reset at first */ | ||
1991 | value8 = 0; | ||
1992 | value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn); | ||
1993 | rtw_write8(padapter, REG_SYS_FUNC_EN, value8); /* 0x16 */ | ||
1994 | |||
1995 | /* Set global reset. */ | ||
1996 | value8 &= ~FEN_BB_GLB_RSTn; | ||
1997 | rtw_write8(padapter, REG_SYS_FUNC_EN, value8); /* 0x14 */ | ||
1998 | |||
1999 | /* 2010/08/12 MH We need to set BB/GLBAL reset to save power | ||
2000 | for SS mode. */ | ||
2001 | |||
2002 | /* RT_TRACE(COMP_INIT, DBG_LOUD, ("======> RF off and reset BB.\n")); */ | ||
2003 | } | ||
2004 | |||
2005 | static void _DisableRFAFEAndResetBB(struct rtw_adapter *padapter) | ||
2006 | { | ||
2007 | _DisableRFAFEAndResetBB8192C(padapter); | ||
2008 | } | ||
2009 | |||
2010 | static void _ResetDigitalProcedure1_92C(struct rtw_adapter *padapter, | ||
2011 | bool bWithoutHWSM) | ||
2012 | { | ||
2013 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
2014 | |||
2015 | if (IS_FW_81xxC(padapter) && (pHalData->FirmwareVersion <= 0x20)) { | ||
2016 | /***************************** | ||
2017 | f. MCUFWDL 0x80[7:0]= 0 reset MCU ready status | ||
2018 | g. SYS_FUNC_EN 0x02[10]= 0 reset MCU register, (8051 reset) | ||
2019 | h. SYS_FUNC_EN 0x02[15-12]= 5 reset MAC register, DCORE | ||
2020 | i. SYS_FUNC_EN 0x02[10]= 1 enable MCU register, | ||
2021 | (8051 enable) | ||
2022 | ******************************/ | ||
2023 | u16 valu16 = 0; | ||
2024 | rtw_write8(padapter, REG_MCUFWDL, 0); | ||
2025 | |||
2026 | valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN); | ||
2027 | /* reset MCU , 8051 */ | ||
2028 | rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 & (~FEN_CPUEN))); | ||
2029 | |||
2030 | valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN) & 0x0FFF; | ||
2031 | rtw_write16(padapter, REG_SYS_FUNC_EN, | ||
2032 | (valu16 | (FEN_HWPDN | FEN_ELDR))); /* reset MAC */ | ||
2033 | |||
2034 | valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN); | ||
2035 | /* enable MCU , 8051 */ | ||
2036 | rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | FEN_CPUEN)); | ||
2037 | } else { | ||
2038 | u8 retry_cnts = 0; | ||
2039 | |||
2040 | /* 2010/08/12 MH For USB SS, we can not stop 8051 when we | ||
2041 | are trying to enter IPS/HW&SW radio off. For | ||
2042 | S3/S4/S5/Disable, we can stop 8051 because */ | ||
2043 | /* we will init FW when power on again. */ | ||
2044 | /* if (!pDevice->RegUsbSS) */ | ||
2045 | /* If we want to SS mode, we can not reset 8051. */ | ||
2046 | if (rtw_read8(padapter, REG_MCUFWDL) & BIT1) { | ||
2047 | /* IF fw in RAM code, do reset */ | ||
2048 | if (padapter->bFWReady) { | ||
2049 | /* 2010/08/25 MH Accordign to RD alfred's | ||
2050 | suggestion, we need to disable other */ | ||
2051 | /* HRCV INT to influence 8051 reset. */ | ||
2052 | rtw_write8(padapter, REG_FWIMR, 0x20); | ||
2053 | /* 2011/02/15 MH According to Alex's | ||
2054 | suggestion, close mask to prevent | ||
2055 | incorrect FW write operation. */ | ||
2056 | rtw_write8(padapter, REG_FTIMR, 0x00); | ||
2057 | rtw_write8(padapter, REG_FSIMR, 0x00); | ||
2058 | |||
2059 | /* 8051 reset by self */ | ||
2060 | rtw_write8(padapter, REG_HMETFR + 3, 0x20); | ||
2061 | |||
2062 | while ((retry_cnts++ < 100) && | ||
2063 | (FEN_CPUEN & | ||
2064 | rtw_read16(padapter, REG_SYS_FUNC_EN))) { | ||
2065 | udelay(50); /* us */ | ||
2066 | } | ||
2067 | |||
2068 | if (retry_cnts >= 100) { | ||
2069 | /* Reset MAC and Enable 8051 */ | ||
2070 | rtw_write8(padapter, | ||
2071 | REG_SYS_FUNC_EN + 1, 0x50); | ||
2072 | mdelay(10); | ||
2073 | } | ||
2074 | } | ||
2075 | } | ||
2076 | /* Reset MAC and Enable 8051 */ | ||
2077 | rtw_write8(padapter, REG_SYS_FUNC_EN + 1, 0x54); | ||
2078 | rtw_write8(padapter, REG_MCUFWDL, 0); | ||
2079 | } | ||
2080 | |||
2081 | if (bWithoutHWSM) { | ||
2082 | /***************************** | ||
2083 | Without HW auto state machine | ||
2084 | g. SYS_CLKR 0x08[15:0] = 0x30A3 disable MAC clock | ||
2085 | h. AFE_PLL_CTRL 0x28[7:0] = 0x80 disable AFE PLL | ||
2086 | i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F gated AFE DIG_CLOCK | ||
2087 | j. SYS_ISO_CTRL 0x00[7:0] = 0xF9 isolated digital to PON | ||
2088 | ******************************/ | ||
2089 | /* modify to 0x70A3 by Scott. */ | ||
2090 | rtw_write16(padapter, REG_SYS_CLKR, 0x70A3); | ||
2091 | rtw_write8(padapter, REG_AFE_PLL_CTRL, 0x80); | ||
2092 | rtw_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F); | ||
2093 | rtw_write8(padapter, REG_SYS_ISO_CTRL, 0xF9); | ||
2094 | } else { | ||
2095 | /* Disable all RF/BB power */ | ||
2096 | rtw_write8(padapter, REG_RF_CTRL, 0x00); | ||
2097 | } | ||
2098 | } | ||
2099 | |||
2100 | static void _ResetDigitalProcedure1(struct rtw_adapter *padapter, | ||
2101 | bool bWithoutHWSM) | ||
2102 | { | ||
2103 | _ResetDigitalProcedure1_92C(padapter, bWithoutHWSM); | ||
2104 | } | ||
2105 | |||
2106 | static void _ResetDigitalProcedure2(struct rtw_adapter *padapter) | ||
2107 | { | ||
2108 | /***************************** | ||
2109 | k. SYS_FUNC_EN 0x03[7:0] = 0x44 disable ELDR runction | ||
2110 | l. SYS_CLKR 0x08[15:0] = 0x3083 disable ELDR clock | ||
2111 | m. SYS_ISO_CTRL 0x01[7:0] = 0x83 isolated ELDR to PON | ||
2112 | ******************************/ | ||
2113 | /* modify to 0x70a3 by Scott. */ | ||
2114 | rtw_write16(padapter, REG_SYS_CLKR, 0x70a3); | ||
2115 | /* modify to 0x82 by Scott. */ | ||
2116 | rtw_write8(padapter, REG_SYS_ISO_CTRL + 1, 0x82); | ||
2117 | } | ||
2118 | |||
2119 | static void _DisableAnalog(struct rtw_adapter *padapter, bool bWithoutHWSM) | ||
2120 | { | ||
2121 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
2122 | u16 value16 = 0; | ||
2123 | u8 value8 = 0; | ||
2124 | |||
2125 | if (bWithoutHWSM) { | ||
2126 | /***************************** | ||
2127 | n. LDOA15_CTRL 0x20[7:0] = 0x04 disable A15 power | ||
2128 | o. LDOV12D_CTRL 0x21[7:0] = 0x54 disable digital core power | ||
2129 | r. When driver call disable, the ASIC will turn off remaining | ||
2130 | clock automatically | ||
2131 | ******************************/ | ||
2132 | |||
2133 | rtw_write8(padapter, REG_LDOA15_CTRL, 0x04); | ||
2134 | /* rtw_write8(padapter, REG_LDOV12D_CTRL, 0x54); */ | ||
2135 | |||
2136 | value8 = rtw_read8(padapter, REG_LDOV12D_CTRL); | ||
2137 | value8 &= (~LDV12_EN); | ||
2138 | rtw_write8(padapter, REG_LDOV12D_CTRL, value8); | ||
2139 | /* RT_TRACE(COMP_INIT, DBG_LOUD, | ||
2140 | (" REG_LDOV12D_CTRL Reg0x21:0x%02x.\n", value8)); */ | ||
2141 | } | ||
2142 | |||
2143 | /***************************** | ||
2144 | h. SPS0_CTRL 0x11[7:0] = 0x23 enter PFM mode | ||
2145 | i. APS_FSMCO 0x04[15:0] = 0x4802 set USB suspend | ||
2146 | ******************************/ | ||
2147 | value8 = 0x23; | ||
2148 | if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)) | ||
2149 | value8 |= BIT3; | ||
2150 | |||
2151 | rtw_write8(padapter, REG_SPS0_CTRL, value8); | ||
2152 | |||
2153 | if (bWithoutHWSM) { | ||
2154 | /* value16 |= (APDM_HOST | FSM_HSUS |/PFM_ALDN); */ | ||
2155 | /* 2010/08/31 According to Filen description, we need to | ||
2156 | use HW to shut down 8051 automatically. */ | ||
2157 | /* Becasue suspend operatione need the asistance of 8051 | ||
2158 | to wait for 3ms. */ | ||
2159 | value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN); | ||
2160 | } else { | ||
2161 | value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN); | ||
2162 | } | ||
2163 | |||
2164 | rtw_write16(padapter, REG_APS_FSMCO, value16); /* 0x4802 */ | ||
2165 | |||
2166 | rtw_write8(padapter, REG_RSV_CTRL, 0x0e); | ||
2167 | } | ||
2168 | |||
2169 | /* HW Auto state machine */ | ||
2170 | s32 CardDisableHWSM(struct rtw_adapter *padapter, u8 resetMCU) | ||
2171 | { | ||
2172 | int rtStatus = _SUCCESS; | ||
2173 | |||
2174 | if (padapter->bSurpriseRemoved) { | ||
2175 | return rtStatus; | ||
2176 | } | ||
2177 | /* RF Off Sequence ==== */ | ||
2178 | _DisableRFAFEAndResetBB(padapter); | ||
2179 | |||
2180 | /* ==== Reset digital sequence ====== */ | ||
2181 | _ResetDigitalProcedure1(padapter, false); | ||
2182 | |||
2183 | /* ==== Pull GPIO PIN to balance level and LED control ====== */ | ||
2184 | _DisableGPIO(padapter); | ||
2185 | |||
2186 | /* ==== Disable analog sequence === */ | ||
2187 | _DisableAnalog(padapter, false); | ||
2188 | |||
2189 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
2190 | ("======> Card disable finished.\n")); | ||
2191 | |||
2192 | return rtStatus; | ||
2193 | } | ||
2194 | |||
2195 | /* without HW Auto state machine */ | ||
2196 | s32 CardDisableWithoutHWSM(struct rtw_adapter *padapter) | ||
2197 | { | ||
2198 | s32 rtStatus = _SUCCESS; | ||
2199 | |||
2200 | /* RT_TRACE(COMP_INIT, DBG_LOUD, | ||
2201 | ("======> Card Disable Without HWSM .\n")); */ | ||
2202 | if (padapter->bSurpriseRemoved) { | ||
2203 | return rtStatus; | ||
2204 | } | ||
2205 | |||
2206 | /* RF Off Sequence ==== */ | ||
2207 | _DisableRFAFEAndResetBB(padapter); | ||
2208 | |||
2209 | /* ==== Reset digital sequence ====== */ | ||
2210 | _ResetDigitalProcedure1(padapter, true); | ||
2211 | |||
2212 | /* ==== Pull GPIO PIN to balance level and LED control ====== */ | ||
2213 | _DisableGPIO(padapter); | ||
2214 | |||
2215 | /* ==== Reset digital sequence ====== */ | ||
2216 | _ResetDigitalProcedure2(padapter); | ||
2217 | |||
2218 | /* ==== Disable analog sequence === */ | ||
2219 | _DisableAnalog(padapter, true); | ||
2220 | |||
2221 | /* RT_TRACE(COMP_INIT, DBG_LOUD, | ||
2222 | ("<====== Card Disable Without HWSM .\n")); */ | ||
2223 | return rtStatus; | ||
2224 | } | ||
2225 | |||
2226 | void Hal_InitPGData(struct rtw_adapter *padapter, u8 *PROMContent) | ||
2227 | { | ||
2228 | struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); | ||
2229 | |||
2230 | if (false == pEEPROM->bautoload_fail_flag) { /* autoload OK. */ | ||
2231 | if (!pEEPROM->EepromOrEfuse) { | ||
2232 | /* Read EFUSE real map to shadow. */ | ||
2233 | EFUSE_ShadowMapUpdate23a(padapter, EFUSE_WIFI); | ||
2234 | memcpy((void *)PROMContent, | ||
2235 | (void *)pEEPROM->efuse_eeprom_data, | ||
2236 | HWSET_MAX_SIZE); | ||
2237 | } | ||
2238 | } else { /* autoload fail */ | ||
2239 | RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, | ||
2240 | ("AutoLoad Fail reported from CR9346!!\n")); | ||
2241 | /* pHalData->AutoloadFailFlag = true; */ | ||
2242 | /* update to default value 0xFF */ | ||
2243 | if (false == pEEPROM->EepromOrEfuse) | ||
2244 | EFUSE_ShadowMapUpdate23a(padapter, EFUSE_WIFI); | ||
2245 | memcpy((void *)PROMContent, (void *)pEEPROM->efuse_eeprom_data, | ||
2246 | HWSET_MAX_SIZE); | ||
2247 | } | ||
2248 | } | ||
2249 | |||
2250 | void Hal_EfuseParseIDCode(struct rtw_adapter *padapter, u8 *hwinfo) | ||
2251 | { | ||
2252 | struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); | ||
2253 | /* struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); */ | ||
2254 | u16 EEPROMId; | ||
2255 | |||
2256 | /* Checl 0x8129 again for making sure autoload status!! */ | ||
2257 | EEPROMId = le16_to_cpu(*((u16 *) hwinfo)); | ||
2258 | if (EEPROMId != RTL_EEPROM_ID) { | ||
2259 | DBG_8723A("EEPROM ID(%#x) is invalid!!\n", EEPROMId); | ||
2260 | pEEPROM->bautoload_fail_flag = true; | ||
2261 | } else { | ||
2262 | pEEPROM->bautoload_fail_flag = false; | ||
2263 | } | ||
2264 | |||
2265 | RT_TRACE(_module_hal_init_c_, _drv_info_, | ||
2266 | ("EEPROM ID = 0x%04x\n", EEPROMId)); | ||
2267 | } | ||
2268 | |||
2269 | static void Hal_EEValueCheck(u8 EEType, void *pInValue, void *pOutValue) | ||
2270 | { | ||
2271 | switch (EEType) { | ||
2272 | case EETYPE_TX_PWR: | ||
2273 | { | ||
2274 | u8 *pIn, *pOut; | ||
2275 | pIn = (u8 *) pInValue; | ||
2276 | pOut = (u8 *) pOutValue; | ||
2277 | if (*pIn >= 0 && *pIn <= 63) { | ||
2278 | *pOut = *pIn; | ||
2279 | } else { | ||
2280 | RT_TRACE(_module_hci_hal_init_c_, _drv_err_, | ||
2281 | ("EETYPE_TX_PWR, value =%d is invalid, set " | ||
2282 | "to default = 0x%x\n", | ||
2283 | *pIn, EEPROM_Default_TxPowerLevel)); | ||
2284 | *pOut = EEPROM_Default_TxPowerLevel; | ||
2285 | } | ||
2286 | } | ||
2287 | break; | ||
2288 | default: | ||
2289 | break; | ||
2290 | } | ||
2291 | } | ||
2292 | |||
2293 | static void | ||
2294 | Hal_ReadPowerValueFromPROM_8723A(struct txpowerinfo *pwrInfo, | ||
2295 | u8 *PROMContent, bool AutoLoadFail) | ||
2296 | { | ||
2297 | u32 rfPath, eeAddr, group, rfPathMax = 1; | ||
2298 | |||
2299 | memset(pwrInfo, 0, sizeof(*pwrInfo)); | ||
2300 | |||
2301 | if (AutoLoadFail) { | ||
2302 | for (group = 0; group < MAX_CHNL_GROUP; group++) { | ||
2303 | for (rfPath = 0; rfPath < rfPathMax; rfPath++) { | ||
2304 | pwrInfo->CCKIndex[rfPath][group] = | ||
2305 | EEPROM_Default_TxPowerLevel; | ||
2306 | pwrInfo->HT40_1SIndex[rfPath][group] = | ||
2307 | EEPROM_Default_TxPowerLevel; | ||
2308 | pwrInfo->HT40_2SIndexDiff[rfPath][group] = | ||
2309 | EEPROM_Default_HT40_2SDiff; | ||
2310 | pwrInfo->HT20IndexDiff[rfPath][group] = | ||
2311 | EEPROM_Default_HT20_Diff; | ||
2312 | pwrInfo->OFDMIndexDiff[rfPath][group] = | ||
2313 | EEPROM_Default_LegacyHTTxPowerDiff; | ||
2314 | pwrInfo->HT40MaxOffset[rfPath][group] = | ||
2315 | EEPROM_Default_HT40_PwrMaxOffset; | ||
2316 | pwrInfo->HT20MaxOffset[rfPath][group] = | ||
2317 | EEPROM_Default_HT20_PwrMaxOffset; | ||
2318 | } | ||
2319 | } | ||
2320 | pwrInfo->TSSI_A[0] = EEPROM_Default_TSSI; | ||
2321 | return; | ||
2322 | } | ||
2323 | |||
2324 | for (rfPath = 0; rfPath < rfPathMax; rfPath++) { | ||
2325 | for (group = 0; group < MAX_CHNL_GROUP; group++) { | ||
2326 | eeAddr = | ||
2327 | EEPROM_CCK_TX_PWR_INX_8723A + (rfPath * 3) + group; | ||
2328 | /* pwrInfo->CCKIndex[rfPath][group] = | ||
2329 | PROMContent[eeAddr]; */ | ||
2330 | Hal_EEValueCheck(EETYPE_TX_PWR, &PROMContent[eeAddr], | ||
2331 | &pwrInfo->CCKIndex[rfPath][group]); | ||
2332 | eeAddr = EEPROM_HT40_1S_TX_PWR_INX_8723A + | ||
2333 | (rfPath * 3) + group; | ||
2334 | /* pwrInfo->HT40_1SIndex[rfPath][group] = | ||
2335 | PROMContent[eeAddr]; */ | ||
2336 | Hal_EEValueCheck(EETYPE_TX_PWR, &PROMContent[eeAddr], | ||
2337 | &pwrInfo->HT40_1SIndex[rfPath][group]); | ||
2338 | } | ||
2339 | } | ||
2340 | |||
2341 | for (group = 0; group < MAX_CHNL_GROUP; group++) { | ||
2342 | for (rfPath = 0; rfPath < rfPathMax; rfPath++) { | ||
2343 | pwrInfo->HT40_2SIndexDiff[rfPath][group] = 0; | ||
2344 | pwrInfo->HT20IndexDiff[rfPath][group] = | ||
2345 | (PROMContent | ||
2346 | [EEPROM_HT20_TX_PWR_INX_DIFF_8723A + | ||
2347 | group] >> (rfPath * 4)) & 0xF; | ||
2348 | /* 4bit sign number to 8 bit sign number */ | ||
2349 | if (pwrInfo->HT20IndexDiff[rfPath][group] & BIT3) | ||
2350 | pwrInfo->HT20IndexDiff[rfPath][group] |= 0xF0; | ||
2351 | |||
2352 | pwrInfo->OFDMIndexDiff[rfPath][group] = | ||
2353 | (PROMContent[EEPROM_OFDM_TX_PWR_INX_DIFF_8723A + | ||
2354 | group] >> (rfPath * 4)) & 0xF; | ||
2355 | |||
2356 | pwrInfo->HT40MaxOffset[rfPath][group] = | ||
2357 | (PROMContent[EEPROM_HT40_MAX_PWR_OFFSET_8723A + | ||
2358 | group] >> (rfPath * 4)) & 0xF; | ||
2359 | |||
2360 | pwrInfo->HT20MaxOffset[rfPath][group] = | ||
2361 | (PROMContent[EEPROM_HT20_MAX_PWR_OFFSET_8723A + | ||
2362 | group] >> (rfPath * 4)) & 0xF; | ||
2363 | } | ||
2364 | } | ||
2365 | |||
2366 | pwrInfo->TSSI_A[0] = PROMContent[EEPROM_TSSI_A_8723A]; | ||
2367 | } | ||
2368 | |||
2369 | static u8 Hal_GetChnlGroup(u8 chnl) | ||
2370 | { | ||
2371 | u8 group = 0; | ||
2372 | |||
2373 | if (chnl < 3) /* Cjanel 1-3 */ | ||
2374 | group = 0; | ||
2375 | else if (chnl < 9) /* Channel 4-9 */ | ||
2376 | group = 1; | ||
2377 | else /* Channel 10-14 */ | ||
2378 | group = 2; | ||
2379 | |||
2380 | return group; | ||
2381 | } | ||
2382 | |||
2383 | void | ||
2384 | Hal_EfuseParsetxpowerinfo_8723A(struct rtw_adapter *padapter, | ||
2385 | u8 *PROMContent, bool AutoLoadFail) | ||
2386 | { | ||
2387 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
2388 | struct txpowerinfo pwrInfo; | ||
2389 | u8 rfPath, ch, group, rfPathMax = 1; | ||
2390 | u8 pwr, diff; | ||
2391 | |||
2392 | Hal_ReadPowerValueFromPROM_8723A(&pwrInfo, PROMContent, AutoLoadFail); | ||
2393 | for (rfPath = 0; rfPath < rfPathMax; rfPath++) { | ||
2394 | for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) { | ||
2395 | group = Hal_GetChnlGroup(ch); | ||
2396 | |||
2397 | pHalData->TxPwrLevelCck[rfPath][ch] = | ||
2398 | pwrInfo.CCKIndex[rfPath][group]; | ||
2399 | pHalData->TxPwrLevelHT40_1S[rfPath][ch] = | ||
2400 | pwrInfo.HT40_1SIndex[rfPath][group]; | ||
2401 | |||
2402 | pHalData->TxPwrHt20Diff[rfPath][ch] = | ||
2403 | pwrInfo.HT20IndexDiff[rfPath][group]; | ||
2404 | pHalData->TxPwrLegacyHtDiff[rfPath][ch] = | ||
2405 | pwrInfo.OFDMIndexDiff[rfPath][group]; | ||
2406 | pHalData->PwrGroupHT20[rfPath][ch] = | ||
2407 | pwrInfo.HT20MaxOffset[rfPath][group]; | ||
2408 | pHalData->PwrGroupHT40[rfPath][ch] = | ||
2409 | pwrInfo.HT40MaxOffset[rfPath][group]; | ||
2410 | |||
2411 | pwr = pwrInfo.HT40_1SIndex[rfPath][group]; | ||
2412 | diff = pwrInfo.HT40_2SIndexDiff[rfPath][group]; | ||
2413 | |||
2414 | pHalData->TxPwrLevelHT40_2S[rfPath][ch] = | ||
2415 | (pwr > diff) ? (pwr - diff) : 0; | ||
2416 | } | ||
2417 | } | ||
2418 | for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) { | ||
2419 | for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) { | ||
2420 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
2421 | ("RF(%u)-Ch(%u) [CCK / HT40_1S / HT40_2S] = " | ||
2422 | "[0x%x / 0x%x / 0x%x]\n", | ||
2423 | rfPath, ch, | ||
2424 | pHalData->TxPwrLevelCck[rfPath][ch], | ||
2425 | pHalData->TxPwrLevelHT40_1S[rfPath][ch], | ||
2426 | pHalData->TxPwrLevelHT40_2S[rfPath][ch])); | ||
2427 | |||
2428 | } | ||
2429 | } | ||
2430 | for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) { | ||
2431 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
2432 | ("RF-A Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch, | ||
2433 | pHalData->TxPwrHt20Diff[RF_PATH_A][ch], | ||
2434 | pHalData->TxPwrHt20Diff[RF_PATH_A][ch])); | ||
2435 | } | ||
2436 | for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) | ||
2437 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
2438 | ("RF-A Legacy to Ht40 Diff[%u] = 0x%x\n", ch, | ||
2439 | pHalData->TxPwrLegacyHtDiff[RF_PATH_A][ch])); | ||
2440 | for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) { | ||
2441 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
2442 | ("RF-B Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch, | ||
2443 | pHalData->TxPwrHt20Diff[RF_PATH_B][ch], | ||
2444 | pHalData->TxPwrHt20Diff[RF_PATH_B][ch])); | ||
2445 | } | ||
2446 | for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) | ||
2447 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
2448 | ("RF-B Legacy to HT40 Diff[%u] = 0x%x\n", ch, | ||
2449 | pHalData->TxPwrLegacyHtDiff[RF_PATH_B][ch])); | ||
2450 | if (!AutoLoadFail) { | ||
2451 | struct registry_priv *registry_par = &padapter->registrypriv; | ||
2452 | if (registry_par->regulatory_tid == 0xff) { | ||
2453 | if (PROMContent[RF_OPTION1_8723A] == 0xff) | ||
2454 | pHalData->EEPROMRegulatory = 0; | ||
2455 | else | ||
2456 | pHalData->EEPROMRegulatory = | ||
2457 | PROMContent[RF_OPTION1_8723A] & 0x7; | ||
2458 | } else { | ||
2459 | pHalData->EEPROMRegulatory = | ||
2460 | registry_par->regulatory_tid; | ||
2461 | } | ||
2462 | } else { | ||
2463 | pHalData->EEPROMRegulatory = 0; | ||
2464 | } | ||
2465 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
2466 | ("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory)); | ||
2467 | |||
2468 | if (!AutoLoadFail) | ||
2469 | pHalData->bTXPowerDataReadFromEEPORM = true; | ||
2470 | } | ||
2471 | |||
2472 | void | ||
2473 | Hal_EfuseParseBTCoexistInfo_8723A(struct rtw_adapter *padapter, | ||
2474 | u8 *hwinfo, bool AutoLoadFail) | ||
2475 | { | ||
2476 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
2477 | u8 tempval; | ||
2478 | u32 tmpu4; | ||
2479 | |||
2480 | if (!AutoLoadFail) { | ||
2481 | tmpu4 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL); | ||
2482 | if (tmpu4 & BT_FUNC_EN) | ||
2483 | pHalData->EEPROMBluetoothCoexist = 1; | ||
2484 | else | ||
2485 | pHalData->EEPROMBluetoothCoexist = 0; | ||
2486 | pHalData->EEPROMBluetoothType = BT_RTL8723A; | ||
2487 | |||
2488 | /* The following need to be checked with newer version of */ | ||
2489 | /* eeprom spec */ | ||
2490 | tempval = hwinfo[RF_OPTION4_8723A]; | ||
2491 | pHalData->EEPROMBluetoothAntNum = (tempval & 0x1); | ||
2492 | pHalData->EEPROMBluetoothAntIsolation = ((tempval & 0x10) >> 4); | ||
2493 | pHalData->EEPROMBluetoothRadioShared = ((tempval & 0x20) >> 5); | ||
2494 | } else { | ||
2495 | pHalData->EEPROMBluetoothCoexist = 0; | ||
2496 | pHalData->EEPROMBluetoothType = BT_RTL8723A; | ||
2497 | pHalData->EEPROMBluetoothAntNum = Ant_x2; | ||
2498 | pHalData->EEPROMBluetoothAntIsolation = 0; | ||
2499 | pHalData->EEPROMBluetoothRadioShared = BT_Radio_Shared; | ||
2500 | } | ||
2501 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
2502 | BT_InitHalVars(padapter); | ||
2503 | #endif | ||
2504 | } | ||
2505 | |||
2506 | void | ||
2507 | Hal_EfuseParseEEPROMVer(struct rtw_adapter *padapter, | ||
2508 | u8 *hwinfo, bool AutoLoadFail) | ||
2509 | { | ||
2510 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
2511 | |||
2512 | if (!AutoLoadFail) | ||
2513 | pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8723A]; | ||
2514 | else | ||
2515 | pHalData->EEPROMVersion = 1; | ||
2516 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
2517 | ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n", | ||
2518 | pHalData->EEPROMVersion)); | ||
2519 | } | ||
2520 | |||
2521 | void | ||
2522 | rtl8723a_EfuseParseChnlPlan(struct rtw_adapter *padapter, | ||
2523 | u8 *hwinfo, bool AutoLoadFail) | ||
2524 | { | ||
2525 | padapter->mlmepriv.ChannelPlan = | ||
2526 | hal_com_get_channel_plan23a(padapter, hwinfo ? | ||
2527 | hwinfo[EEPROM_ChannelPlan_8723A]:0xFF, | ||
2528 | padapter->registrypriv.channel_plan, | ||
2529 | RT_CHANNEL_DOMAIN_WORLD_WIDE_13, | ||
2530 | AutoLoadFail); | ||
2531 | |||
2532 | DBG_8723A("mlmepriv.ChannelPlan = 0x%02x\n", | ||
2533 | padapter->mlmepriv.ChannelPlan); | ||
2534 | } | ||
2535 | |||
2536 | void | ||
2537 | Hal_EfuseParseCustomerID(struct rtw_adapter *padapter, | ||
2538 | u8 *hwinfo, bool AutoLoadFail) | ||
2539 | { | ||
2540 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
2541 | |||
2542 | if (!AutoLoadFail) { | ||
2543 | pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8723A]; | ||
2544 | pHalData->EEPROMSubCustomerID = | ||
2545 | hwinfo[EEPROM_SubCustomID_8723A]; | ||
2546 | } else { | ||
2547 | pHalData->EEPROMCustomerID = 0; | ||
2548 | pHalData->EEPROMSubCustomerID = 0; | ||
2549 | } | ||
2550 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
2551 | ("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID)); | ||
2552 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
2553 | ("EEPROM SubCustomer ID: 0x%02x\n", | ||
2554 | pHalData->EEPROMSubCustomerID)); | ||
2555 | } | ||
2556 | |||
2557 | void | ||
2558 | Hal_EfuseParseAntennaDiversity(struct rtw_adapter *padapter, | ||
2559 | u8 *hwinfo, bool AutoLoadFail) | ||
2560 | { | ||
2561 | } | ||
2562 | |||
2563 | void | ||
2564 | Hal_EfuseParseRateIndicationOption(struct rtw_adapter *padapter, | ||
2565 | u8 *hwinfo, bool AutoLoadFail) | ||
2566 | { | ||
2567 | } | ||
2568 | |||
2569 | void | ||
2570 | Hal_EfuseParseXtal_8723A(struct rtw_adapter *pAdapter, | ||
2571 | u8 *hwinfo, u8 AutoLoadFail) | ||
2572 | { | ||
2573 | struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); | ||
2574 | |||
2575 | if (!AutoLoadFail) { | ||
2576 | pHalData->CrystalCap = hwinfo[EEPROM_XTAL_K_8723A]; | ||
2577 | if (pHalData->CrystalCap == 0xFF) | ||
2578 | pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A; | ||
2579 | } else { | ||
2580 | pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A; | ||
2581 | } | ||
2582 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
2583 | ("%s: CrystalCap = 0x%2x\n", __func__, | ||
2584 | pHalData->CrystalCap)); | ||
2585 | } | ||
2586 | |||
2587 | void | ||
2588 | Hal_EfuseParseThermalMeter_8723A(struct rtw_adapter *padapter, | ||
2589 | u8 *PROMContent, u8 AutoloadFail) | ||
2590 | { | ||
2591 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
2592 | |||
2593 | /* */ | ||
2594 | /* ThermalMeter from EEPROM */ | ||
2595 | /* */ | ||
2596 | if (false == AutoloadFail) | ||
2597 | pHalData->EEPROMThermalMeter = | ||
2598 | PROMContent[EEPROM_THERMAL_METER_8723A]; | ||
2599 | else | ||
2600 | pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter; | ||
2601 | |||
2602 | if ((pHalData->EEPROMThermalMeter == 0xff) || (true == AutoloadFail)) { | ||
2603 | pHalData->bAPKThermalMeterIgnore = true; | ||
2604 | pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter; | ||
2605 | } | ||
2606 | |||
2607 | DBG_8723A("%s: ThermalMeter = 0x%x\n", __func__, | ||
2608 | pHalData->EEPROMThermalMeter); | ||
2609 | } | ||
2610 | |||
2611 | void Hal_InitChannelPlan23a(struct rtw_adapter *padapter) | ||
2612 | { | ||
2613 | } | ||
2614 | |||
2615 | static void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc) | ||
2616 | { | ||
2617 | u16 *usPtr = (u16 *) ptxdesc; | ||
2618 | u32 count = 16; /* (32 bytes / 2 bytes per XOR) => 16 times */ | ||
2619 | u32 index; | ||
2620 | u16 checksum = 0; | ||
2621 | |||
2622 | /* Clear first */ | ||
2623 | ptxdesc->txdw7 &= cpu_to_le32(0xffff0000); | ||
2624 | |||
2625 | for (index = 0; index < count; index++) { | ||
2626 | checksum ^= le16_to_cpu(*(usPtr + index)); | ||
2627 | } | ||
2628 | |||
2629 | ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff); | ||
2630 | } | ||
2631 | |||
2632 | static void fill_txdesc_sectype(struct pkt_attrib *pattrib, | ||
2633 | struct txdesc_8723a *ptxdesc) | ||
2634 | { | ||
2635 | if ((pattrib->encrypt > 0) && !pattrib->bswenc) { | ||
2636 | switch (pattrib->encrypt) { | ||
2637 | /* SEC_TYPE */ | ||
2638 | case _WEP40_: | ||
2639 | case _WEP104_: | ||
2640 | case _TKIP_: | ||
2641 | case _TKIP_WTMIC_: | ||
2642 | ptxdesc->sectype = 1; | ||
2643 | break; | ||
2644 | |||
2645 | case _AES_: | ||
2646 | ptxdesc->sectype = 3; | ||
2647 | break; | ||
2648 | |||
2649 | case _NO_PRIVACY_: | ||
2650 | default: | ||
2651 | break; | ||
2652 | } | ||
2653 | } | ||
2654 | } | ||
2655 | |||
2656 | static void fill_txdesc_vcs(struct pkt_attrib *pattrib, | ||
2657 | struct txdesc_8723a *ptxdesc) | ||
2658 | { | ||
2659 | /* DBG_8723A("cvs_mode =%d\n", pattrib->vcs_mode); */ | ||
2660 | |||
2661 | switch (pattrib->vcs_mode) { | ||
2662 | case RTS_CTS: | ||
2663 | ptxdesc->rtsen = 1; | ||
2664 | break; | ||
2665 | |||
2666 | case CTS_TO_SELF: | ||
2667 | ptxdesc->cts2self = 1; | ||
2668 | break; | ||
2669 | |||
2670 | case NONE_VCS: | ||
2671 | default: | ||
2672 | break; | ||
2673 | } | ||
2674 | |||
2675 | if (pattrib->vcs_mode) { | ||
2676 | ptxdesc->hw_rts_en = 1; /* ENABLE HW RTS */ | ||
2677 | |||
2678 | /* Set RTS BW */ | ||
2679 | if (pattrib->ht_en) { | ||
2680 | if (pattrib->bwmode & HT_CHANNEL_WIDTH_40) | ||
2681 | ptxdesc->rts_bw = 1; | ||
2682 | |||
2683 | switch (pattrib->ch_offset) { | ||
2684 | case HAL_PRIME_CHNL_OFFSET_DONT_CARE: | ||
2685 | ptxdesc->rts_sc = 0; | ||
2686 | break; | ||
2687 | |||
2688 | case HAL_PRIME_CHNL_OFFSET_LOWER: | ||
2689 | ptxdesc->rts_sc = 1; | ||
2690 | break; | ||
2691 | |||
2692 | case HAL_PRIME_CHNL_OFFSET_UPPER: | ||
2693 | ptxdesc->rts_sc = 2; | ||
2694 | break; | ||
2695 | |||
2696 | default: | ||
2697 | ptxdesc->rts_sc = 3; /* Duplicate */ | ||
2698 | break; | ||
2699 | } | ||
2700 | } | ||
2701 | } | ||
2702 | } | ||
2703 | |||
2704 | static void fill_txdesc_phy(struct pkt_attrib *pattrib, | ||
2705 | struct txdesc_8723a *ptxdesc) | ||
2706 | { | ||
2707 | if (pattrib->ht_en) { | ||
2708 | if (pattrib->bwmode & HT_CHANNEL_WIDTH_40) | ||
2709 | ptxdesc->data_bw = 1; | ||
2710 | |||
2711 | switch (pattrib->ch_offset) { | ||
2712 | case HAL_PRIME_CHNL_OFFSET_DONT_CARE: | ||
2713 | ptxdesc->data_sc = 0; | ||
2714 | break; | ||
2715 | |||
2716 | case HAL_PRIME_CHNL_OFFSET_LOWER: | ||
2717 | ptxdesc->data_sc = 1; | ||
2718 | break; | ||
2719 | |||
2720 | case HAL_PRIME_CHNL_OFFSET_UPPER: | ||
2721 | ptxdesc->data_sc = 2; | ||
2722 | break; | ||
2723 | |||
2724 | default: | ||
2725 | ptxdesc->data_sc = 3; /* Duplicate */ | ||
2726 | break; | ||
2727 | } | ||
2728 | } | ||
2729 | } | ||
2730 | |||
2731 | static void rtl8723a_fill_default_txdesc(struct xmit_frame *pxmitframe, | ||
2732 | u8 *pbuf) | ||
2733 | { | ||
2734 | struct rtw_adapter *padapter; | ||
2735 | struct hal_data_8723a *pHalData; | ||
2736 | struct dm_priv *pdmpriv; | ||
2737 | struct mlme_ext_priv *pmlmeext; | ||
2738 | struct mlme_ext_info *pmlmeinfo; | ||
2739 | struct pkt_attrib *pattrib; | ||
2740 | struct txdesc_8723a *ptxdesc; | ||
2741 | s32 bmcst; | ||
2742 | |||
2743 | padapter = pxmitframe->padapter; | ||
2744 | pHalData = GET_HAL_DATA(padapter); | ||
2745 | pdmpriv = &pHalData->dmpriv; | ||
2746 | pmlmeext = &padapter->mlmeextpriv; | ||
2747 | pmlmeinfo = &pmlmeext->mlmext_info; | ||
2748 | |||
2749 | pattrib = &pxmitframe->attrib; | ||
2750 | bmcst = is_multicast_ether_addr(pattrib->ra); | ||
2751 | |||
2752 | ptxdesc = (struct txdesc_8723a *)pbuf; | ||
2753 | |||
2754 | if (pxmitframe->frame_tag == DATA_FRAMETAG) { | ||
2755 | ptxdesc->macid = pattrib->mac_id; /* CAM_ID(MAC_ID) */ | ||
2756 | |||
2757 | if (pattrib->ampdu_en == true) | ||
2758 | ptxdesc->agg_en = 1; /* AGG EN */ | ||
2759 | else | ||
2760 | ptxdesc->bk = 1; /* AGG BK */ | ||
2761 | |||
2762 | ptxdesc->qsel = pattrib->qsel; | ||
2763 | ptxdesc->rate_id = pattrib->raid; | ||
2764 | |||
2765 | fill_txdesc_sectype(pattrib, ptxdesc); | ||
2766 | |||
2767 | ptxdesc->seq = pattrib->seqnum; | ||
2768 | |||
2769 | if ((pattrib->ether_type != 0x888e) && | ||
2770 | (pattrib->ether_type != 0x0806) && | ||
2771 | (pattrib->dhcp_pkt != 1)) { | ||
2772 | /* Non EAP & ARP & DHCP type data packet */ | ||
2773 | |||
2774 | fill_txdesc_vcs(pattrib, ptxdesc); | ||
2775 | fill_txdesc_phy(pattrib, ptxdesc); | ||
2776 | |||
2777 | ptxdesc->rtsrate = 8; /* RTS Rate = 24M */ | ||
2778 | ptxdesc->data_ratefb_lmt = 0x1F; | ||
2779 | ptxdesc->rts_ratefb_lmt = 0xF; | ||
2780 | |||
2781 | /* use REG_INIDATA_RATE_SEL value */ | ||
2782 | ptxdesc->datarate = | ||
2783 | pdmpriv->INIDATA_RATE[pattrib->mac_id]; | ||
2784 | |||
2785 | } else { | ||
2786 | /* EAP data packet and ARP packet. */ | ||
2787 | /* Use the 1M data rate to send the EAP/ARP packet. */ | ||
2788 | /* This will maybe make the handshake smooth. */ | ||
2789 | |||
2790 | ptxdesc->bk = 1; /* AGG BK */ | ||
2791 | ptxdesc->userate = 1; /* driver uses rate */ | ||
2792 | if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) | ||
2793 | ptxdesc->data_short = 1; | ||
2794 | ptxdesc->datarate = MRateToHwRate23a(pmlmeext->tx_rate); | ||
2795 | } | ||
2796 | } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) { | ||
2797 | /* RT_TRACE(_module_hal_xmit_c_, _drv_notice_, | ||
2798 | ("%s: MGNT_FRAMETAG\n", __func__)); */ | ||
2799 | |||
2800 | ptxdesc->macid = pattrib->mac_id; /* CAM_ID(MAC_ID) */ | ||
2801 | ptxdesc->qsel = pattrib->qsel; | ||
2802 | ptxdesc->rate_id = pattrib->raid; /* Rate ID */ | ||
2803 | ptxdesc->seq = pattrib->seqnum; | ||
2804 | ptxdesc->userate = 1; /* driver uses rate, 1M */ | ||
2805 | ptxdesc->rty_lmt_en = 1; /* retry limit enable */ | ||
2806 | ptxdesc->data_rt_lmt = 6; /* retry limit = 6 */ | ||
2807 | |||
2808 | /* CCX-TXRPT ack for xmit mgmt frames. */ | ||
2809 | if (pxmitframe->ack_report) | ||
2810 | ptxdesc->ccx = 1; | ||
2811 | |||
2812 | ptxdesc->datarate = MRateToHwRate23a(pmlmeext->tx_rate); | ||
2813 | } else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) { | ||
2814 | RT_TRACE(_module_hal_xmit_c_, _drv_warning_, | ||
2815 | ("%s: TXAGG_FRAMETAG\n", __func__)); | ||
2816 | } else { | ||
2817 | RT_TRACE(_module_hal_xmit_c_, _drv_warning_, | ||
2818 | ("%s: frame_tag = 0x%x\n", __func__, | ||
2819 | pxmitframe->frame_tag)); | ||
2820 | |||
2821 | ptxdesc->macid = 4; /* CAM_ID(MAC_ID) */ | ||
2822 | ptxdesc->rate_id = 6; /* Rate ID */ | ||
2823 | ptxdesc->seq = pattrib->seqnum; | ||
2824 | ptxdesc->userate = 1; /* driver uses rate */ | ||
2825 | ptxdesc->datarate = MRateToHwRate23a(pmlmeext->tx_rate); | ||
2826 | } | ||
2827 | |||
2828 | ptxdesc->pktlen = pattrib->last_txcmdsz; | ||
2829 | ptxdesc->offset = TXDESC_SIZE + OFFSET_SZ; | ||
2830 | if (bmcst) | ||
2831 | ptxdesc->bmc = 1; | ||
2832 | ptxdesc->ls = 1; | ||
2833 | ptxdesc->fs = 1; | ||
2834 | ptxdesc->own = 1; | ||
2835 | |||
2836 | /* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */ | ||
2837 | /* (1) The sequence number of each non-Qos frame / broadcast / | ||
2838 | * multicast / mgnt frame should be controled by Hw because Fw | ||
2839 | * will also send null data which we cannot control when Fw LPS enable. | ||
2840 | * --> default enable non-Qos data sequense number. | ||
2841 | 2010.06.23. by tynli. */ | ||
2842 | /* (2) Enable HW SEQ control for beacon packet, | ||
2843 | * because we use Hw beacon. */ | ||
2844 | /* (3) Use HW Qos SEQ to control the seq num of Ext port | ||
2845 | * non-Qos packets. */ | ||
2846 | /* 2010.06.23. Added by tynli. */ | ||
2847 | if (!pattrib->qos_en) { | ||
2848 | /* Hw set sequence number */ | ||
2849 | ptxdesc->hwseq_en = 1; /* HWSEQ_EN */ | ||
2850 | ptxdesc->hwseq_sel = 0; /* HWSEQ_SEL */ | ||
2851 | } | ||
2852 | } | ||
2853 | |||
2854 | /* | ||
2855 | * Description: | ||
2856 | * | ||
2857 | * Parameters: | ||
2858 | * pxmitframe xmitframe | ||
2859 | * pbuf where to fill tx desc | ||
2860 | */ | ||
2861 | void rtl8723a_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf) | ||
2862 | { | ||
2863 | struct tx_desc *pdesc; | ||
2864 | |||
2865 | pdesc = (struct tx_desc *)pbuf; | ||
2866 | memset(pdesc, 0, sizeof(struct tx_desc)); | ||
2867 | |||
2868 | rtl8723a_fill_default_txdesc(pxmitframe, pbuf); | ||
2869 | |||
2870 | pdesc->txdw0 = cpu_to_le32(pdesc->txdw0); | ||
2871 | pdesc->txdw1 = cpu_to_le32(pdesc->txdw1); | ||
2872 | pdesc->txdw2 = cpu_to_le32(pdesc->txdw2); | ||
2873 | pdesc->txdw3 = cpu_to_le32(pdesc->txdw3); | ||
2874 | pdesc->txdw4 = cpu_to_le32(pdesc->txdw4); | ||
2875 | pdesc->txdw5 = cpu_to_le32(pdesc->txdw5); | ||
2876 | pdesc->txdw6 = cpu_to_le32(pdesc->txdw6); | ||
2877 | pdesc->txdw7 = cpu_to_le32(pdesc->txdw7); | ||
2878 | rtl8723a_cal_txdesc_chksum(pdesc); | ||
2879 | } | ||
2880 | |||
2881 | /* | ||
2882 | * Description: In normal chip, we should send some packet to Hw which | ||
2883 | * will be used by Fw in FW LPS mode. The function is to fill the Tx | ||
2884 | * descriptor of this packets, then | ||
2885 | */ | ||
2886 | /* Fw can tell Hw to send these packet derectly. */ | ||
2887 | /* Added by tynli. 2009.10.15. */ | ||
2888 | /* */ | ||
2889 | void rtl8723a_fill_fake_txdesc(struct rtw_adapter *padapter, u8 *pDesc, | ||
2890 | u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull) | ||
2891 | { | ||
2892 | struct tx_desc *ptxdesc; | ||
2893 | |||
2894 | /* Clear all status */ | ||
2895 | ptxdesc = (struct tx_desc *)pDesc; | ||
2896 | memset(pDesc, 0, TXDESC_SIZE); | ||
2897 | |||
2898 | /* offset 0 */ | ||
2899 | /* own, bFirstSeg, bLastSeg; */ | ||
2900 | ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); | ||
2901 | |||
2902 | /* 32 bytes for TX Desc */ | ||
2903 | ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << | ||
2904 | OFFSET_SHT) & 0x00ff0000); | ||
2905 | |||
2906 | /* Buffer size + command header */ | ||
2907 | ptxdesc->txdw0 |= cpu_to_le32(BufferLen & 0x0000ffff); | ||
2908 | |||
2909 | /* offset 4 */ | ||
2910 | /* Fixed queue of Mgnt queue */ | ||
2911 | ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT << QSEL_SHT) & 0x00001f00); | ||
2912 | |||
2913 | /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed | ||
2914 | to error vlaue by Hw. */ | ||
2915 | if (IsPsPoll) { | ||
2916 | ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR); | ||
2917 | } else { | ||
2918 | /* Hw set sequence number */ | ||
2919 | ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); | ||
2920 | /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */ | ||
2921 | ptxdesc->txdw3 |= cpu_to_le32((8 << 28)); | ||
2922 | } | ||
2923 | |||
2924 | if (true == IsBTQosNull) { | ||
2925 | ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); /* BT NULL */ | ||
2926 | } | ||
2927 | |||
2928 | /* offset 16 */ | ||
2929 | ptxdesc->txdw4 |= cpu_to_le32(BIT(8)); /* driver uses rate */ | ||
2930 | |||
2931 | /* USB interface drop packet if the checksum of descriptor isn't | ||
2932 | correct. */ | ||
2933 | /* Using this checksum can let hardware recovery from packet bulk | ||
2934 | out error (e.g. Cancel URC, Bulk out error.). */ | ||
2935 | rtl8723a_cal_txdesc_chksum(ptxdesc); | ||
2936 | } | ||
2937 | |||
2938 | static void hw_var_set_opmode(struct rtw_adapter *padapter, u8 mode) | ||
2939 | { | ||
2940 | u8 val8; | ||
2941 | |||
2942 | if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) { | ||
2943 | StopTxBeacon(padapter); | ||
2944 | |||
2945 | /* disable atim wnd */ | ||
2946 | val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM; | ||
2947 | SetBcnCtrlReg23a(padapter, val8, ~val8); | ||
2948 | } else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_) */) { | ||
2949 | ResumeTxBeacon(padapter); | ||
2950 | |||
2951 | val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB; | ||
2952 | SetBcnCtrlReg23a(padapter, val8, ~val8); | ||
2953 | } else if (mode == _HW_STATE_AP_) { | ||
2954 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
2955 | /* add NULL Data and BT NULL Data Packets to FW RSVD Page */ | ||
2956 | rtl8723a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(padapter); | ||
2957 | #endif | ||
2958 | |||
2959 | ResumeTxBeacon(padapter); | ||
2960 | |||
2961 | val8 = DIS_TSF_UDT | DIS_BCNQ_SUB; | ||
2962 | SetBcnCtrlReg23a(padapter, val8, ~val8); | ||
2963 | |||
2964 | /* Set RCR */ | ||
2965 | /* rtw_write32(padapter, REG_RCR, 0x70002a8e); | ||
2966 | CBSSID_DATA must set to 0 */ | ||
2967 | /* CBSSID_DATA must set to 0 */ | ||
2968 | rtw_write32(padapter, REG_RCR, 0x7000228e); | ||
2969 | /* enable to rx data frame */ | ||
2970 | rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF); | ||
2971 | /* enable to rx ps-poll */ | ||
2972 | rtw_write16(padapter, REG_RXFLTMAP1, 0x0400); | ||
2973 | |||
2974 | /* Beacon Control related register for first time */ | ||
2975 | rtw_write8(padapter, REG_BCNDMATIM, 0x02); /* 2ms */ | ||
2976 | rtw_write8(padapter, REG_DRVERLYINT, 0x05); /* 5ms */ | ||
2977 | rtw_write8(padapter, REG_ATIMWND, 0x0a); /* 10ms for port0 */ | ||
2978 | rtw_write16(padapter, REG_BCNTCFG, 0x00); | ||
2979 | rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04); | ||
2980 | /* +32767 (~32ms) */ | ||
2981 | rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff); | ||
2982 | |||
2983 | /* reset TSF */ | ||
2984 | rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0)); | ||
2985 | |||
2986 | /* enable BCN Function */ | ||
2987 | /* don't enable update TSF (due to TSF update when | ||
2988 | beacon/probe rsp are received) */ | ||
2989 | val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | | ||
2990 | EN_TXBCN_RPT | DIS_BCNQ_SUB; | ||
2991 | SetBcnCtrlReg23a(padapter, val8, ~val8); | ||
2992 | } | ||
2993 | |||
2994 | val8 = rtw_read8(padapter, MSR); | ||
2995 | val8 = (val8 & 0xC) | mode; | ||
2996 | rtw_write8(padapter, MSR, val8); | ||
2997 | } | ||
2998 | |||
2999 | static void hw_var_set_macaddr(struct rtw_adapter *padapter, u8 *val) | ||
3000 | { | ||
3001 | u8 idx = 0; | ||
3002 | u32 reg_macid; | ||
3003 | |||
3004 | reg_macid = REG_MACID; | ||
3005 | |||
3006 | for (idx = 0; idx < 6; idx++) | ||
3007 | rtw_write8(padapter, (reg_macid + idx), val[idx]); | ||
3008 | } | ||
3009 | |||
3010 | static void hw_var_set_bssid(struct rtw_adapter *padapter, u8 *val) | ||
3011 | { | ||
3012 | u8 idx = 0; | ||
3013 | u32 reg_bssid; | ||
3014 | |||
3015 | reg_bssid = REG_BSSID; | ||
3016 | |||
3017 | for (idx = 0; idx < 6; idx++) | ||
3018 | rtw_write8(padapter, (reg_bssid + idx), val[idx]); | ||
3019 | } | ||
3020 | |||
3021 | static void hw_var_set_correct_tsf(struct rtw_adapter *padapter) | ||
3022 | { | ||
3023 | u64 tsf; | ||
3024 | u32 reg_tsftr; | ||
3025 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; | ||
3026 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; | ||
3027 | |||
3028 | /* tsf = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue % | ||
3029 | (pmlmeinfo->bcn_interval*1024)) - 1024; us */ | ||
3030 | tsf = pmlmeext->TSFValue - | ||
3031 | rtw_modular6423a(pmlmeext->TSFValue, | ||
3032 | (pmlmeinfo->bcn_interval * 1024)) - 1024; /* us */ | ||
3033 | |||
3034 | if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || | ||
3035 | ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) { | ||
3036 | /* pHalData->RegTxPause |= STOP_BCNQ;BIT(6) */ | ||
3037 | /* rtw_write8(padapter, REG_TXPAUSE, | ||
3038 | (rtw_read8(Adapter, REG_TXPAUSE)|BIT(6))); */ | ||
3039 | StopTxBeacon(padapter); | ||
3040 | } | ||
3041 | |||
3042 | reg_tsftr = REG_TSFTR; | ||
3043 | |||
3044 | /* disable related TSF function */ | ||
3045 | SetBcnCtrlReg23a(padapter, 0, EN_BCN_FUNCTION); | ||
3046 | |||
3047 | rtw_write32(padapter, reg_tsftr, tsf); | ||
3048 | rtw_write32(padapter, reg_tsftr + 4, tsf >> 32); | ||
3049 | |||
3050 | /* enable related TSF function */ | ||
3051 | SetBcnCtrlReg23a(padapter, EN_BCN_FUNCTION, 0); | ||
3052 | |||
3053 | if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || | ||
3054 | ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) | ||
3055 | ResumeTxBeacon(padapter); | ||
3056 | } | ||
3057 | |||
3058 | static void hw_var_set_mlme_disconnect(struct rtw_adapter *padapter) | ||
3059 | { | ||
3060 | /* reject all data frames */ | ||
3061 | rtw_write16(padapter, REG_RXFLTMAP2, 0); | ||
3062 | |||
3063 | /* reset TSF */ | ||
3064 | rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0)); | ||
3065 | |||
3066 | /* disable update TSF */ | ||
3067 | SetBcnCtrlReg23a(padapter, DIS_TSF_UDT, 0); | ||
3068 | } | ||
3069 | |||
3070 | static void hw_var_set_mlme_join(struct rtw_adapter *padapter, u8 type) | ||
3071 | { | ||
3072 | u8 RetryLimit = 0x30; | ||
3073 | |||
3074 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
3075 | struct mlme_priv *pmlmepriv = &padapter->mlmepriv; | ||
3076 | |||
3077 | if (type == 0) { /* prepare to join */ | ||
3078 | u32 v32; | ||
3079 | |||
3080 | /* enable to rx data frame.Accept all data frame */ | ||
3081 | /* rtw_write32(padapter, REG_RCR, | ||
3082 | rtw_read32(padapter, REG_RCR)|RCR_ADF); */ | ||
3083 | rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF); | ||
3084 | |||
3085 | v32 = rtw_read32(padapter, REG_RCR); | ||
3086 | v32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN; | ||
3087 | rtw_write32(padapter, REG_RCR, v32); | ||
3088 | |||
3089 | if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) | ||
3090 | RetryLimit = | ||
3091 | (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48; | ||
3092 | else /* Ad-hoc Mode */ | ||
3093 | RetryLimit = 0x7; | ||
3094 | } else if (type == 1) { /* joinbss_event callback when join res < 0 */ | ||
3095 | /* config RCR to receive different BSSID & not to | ||
3096 | receive data frame during linking */ | ||
3097 | rtw_write16(padapter, REG_RXFLTMAP2, 0); | ||
3098 | } else if (type == 2) { /* sta add event callback */ | ||
3099 | /* enable update TSF */ | ||
3100 | SetBcnCtrlReg23a(padapter, 0, DIS_TSF_UDT); | ||
3101 | |||
3102 | if (check_fwstate(pmlmepriv, | ||
3103 | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) { | ||
3104 | /* fixed beacon issue for 8191su........... */ | ||
3105 | rtw_write8(padapter, 0x542, 0x02); | ||
3106 | RetryLimit = 0x7; | ||
3107 | } | ||
3108 | } | ||
3109 | |||
3110 | rtw_write16(padapter, REG_RL, | ||
3111 | RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << | ||
3112 | RETRY_LIMIT_LONG_SHIFT); | ||
3113 | |||
3114 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
3115 | switch (type) { | ||
3116 | case 0: | ||
3117 | /* prepare to join */ | ||
3118 | BT_WifiAssociateNotify(padapter, true); | ||
3119 | break; | ||
3120 | case 1: | ||
3121 | /* joinbss_event callback when join res < 0 */ | ||
3122 | BT_WifiAssociateNotify(padapter, false); | ||
3123 | break; | ||
3124 | case 2: | ||
3125 | /* sta add event callback */ | ||
3126 | /* BT_WifiMediaStatusNotify(padapter, RT_MEDIA_CONNECT); */ | ||
3127 | break; | ||
3128 | } | ||
3129 | #endif | ||
3130 | } | ||
3131 | |||
3132 | void SetHwReg8723A(struct rtw_adapter *padapter, u8 variable, u8 *val) | ||
3133 | { | ||
3134 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
3135 | u32 *val32 = (u32 *)val; | ||
3136 | |||
3137 | switch (variable) { | ||
3138 | case HW_VAR_MEDIA_STATUS: | ||
3139 | rtl8723a_set_media_status(padapter, *val); | ||
3140 | break; | ||
3141 | |||
3142 | case HW_VAR_MEDIA_STATUS1: | ||
3143 | rtl8723a_set_media_status1(padapter, *val); | ||
3144 | break; | ||
3145 | |||
3146 | case HW_VAR_SET_OPMODE: | ||
3147 | hw_var_set_opmode(padapter, *val); | ||
3148 | break; | ||
3149 | |||
3150 | case HW_VAR_MAC_ADDR: | ||
3151 | hw_var_set_macaddr(padapter, val); | ||
3152 | break; | ||
3153 | |||
3154 | case HW_VAR_BSSID: | ||
3155 | hw_var_set_bssid(padapter, val); | ||
3156 | break; | ||
3157 | |||
3158 | case HW_VAR_BASIC_RATE: | ||
3159 | HalSetBrateCfg23a(padapter, val); | ||
3160 | break; | ||
3161 | |||
3162 | case HW_VAR_TXPAUSE: | ||
3163 | rtl8723a_set_tx_pause(padapter, *val); | ||
3164 | break; | ||
3165 | |||
3166 | case HW_VAR_BCN_FUNC: | ||
3167 | rtl8723a_set_bcn_func(padapter, *val); | ||
3168 | break; | ||
3169 | |||
3170 | case HW_VAR_CORRECT_TSF: | ||
3171 | hw_var_set_correct_tsf(padapter); | ||
3172 | break; | ||
3173 | |||
3174 | case HW_VAR_CHECK_BSSID: | ||
3175 | rtl8723a_check_bssid(padapter, *val); | ||
3176 | break; | ||
3177 | |||
3178 | case HW_VAR_MLME_DISCONNECT: | ||
3179 | hw_var_set_mlme_disconnect(padapter); | ||
3180 | break; | ||
3181 | |||
3182 | case HW_VAR_MLME_SITESURVEY: | ||
3183 | rtl8723a_mlme_sitesurvey(padapter, *val); | ||
3184 | break; | ||
3185 | |||
3186 | case HW_VAR_MLME_JOIN: | ||
3187 | hw_var_set_mlme_join(padapter, *val); | ||
3188 | break; | ||
3189 | |||
3190 | case HW_VAR_ON_RCR_AM: | ||
3191 | rtl8723a_on_rcr_am(padapter); | ||
3192 | break; | ||
3193 | |||
3194 | case HW_VAR_OFF_RCR_AM: | ||
3195 | rtl8723a_off_rcr_am(padapter); | ||
3196 | break; | ||
3197 | |||
3198 | case HW_VAR_BEACON_INTERVAL: | ||
3199 | rtl8723a_set_beacon_interval(padapter, *((u16 *) val)); | ||
3200 | break; | ||
3201 | |||
3202 | case HW_VAR_SLOT_TIME: | ||
3203 | rtl8723a_set_slot_time(padapter, *val); | ||
3204 | break; | ||
3205 | |||
3206 | case HW_VAR_RESP_SIFS: | ||
3207 | rtl8723a_set_resp_sifs(padapter, val[0], val[1], | ||
3208 | val[2], val[3]); | ||
3209 | break; | ||
3210 | |||
3211 | case HW_VAR_ACK_PREAMBLE: | ||
3212 | rtl8723a_ack_preamble(padapter, *val); | ||
3213 | break; | ||
3214 | |||
3215 | case HW_VAR_SEC_CFG: | ||
3216 | rtl8723a_set_sec_cfg(padapter, *val); | ||
3217 | break; | ||
3218 | |||
3219 | case HW_VAR_DM_FLAG: | ||
3220 | rtl8723a_odm_support_ability_write(padapter, *val32); | ||
3221 | break; | ||
3222 | case HW_VAR_DM_FUNC_OP: | ||
3223 | rtl8723a_odm_support_ability_backup(padapter, *val); | ||
3224 | break; | ||
3225 | case HW_VAR_DM_FUNC_SET: | ||
3226 | rtl8723a_odm_support_ability_set(padapter, *val32); | ||
3227 | break; | ||
3228 | |||
3229 | case HW_VAR_DM_FUNC_CLR: | ||
3230 | rtl8723a_odm_support_ability_clr(padapter, *val32); | ||
3231 | break; | ||
3232 | |||
3233 | case HW_VAR_CAM_EMPTY_ENTRY: | ||
3234 | rtl8723a_cam_empty_entry(padapter, *val); | ||
3235 | break; | ||
3236 | |||
3237 | case HW_VAR_CAM_INVALID_ALL: | ||
3238 | rtl8723a_cam_invalid_all(padapter); | ||
3239 | break; | ||
3240 | |||
3241 | case HW_VAR_CAM_WRITE: | ||
3242 | rtl8723a_cam_write(padapter, val32[0], val32[1]); | ||
3243 | break; | ||
3244 | |||
3245 | case HW_VAR_AC_PARAM_VO: | ||
3246 | rtl8723a_set_ac_param_vo(padapter, *val32); | ||
3247 | break; | ||
3248 | |||
3249 | case HW_VAR_AC_PARAM_VI: | ||
3250 | rtl8723a_set_ac_param_vi(padapter, *val32); | ||
3251 | break; | ||
3252 | |||
3253 | case HW_VAR_AC_PARAM_BE: | ||
3254 | rtl8723a_set_ac_param_be(padapter, *val32); | ||
3255 | break; | ||
3256 | |||
3257 | case HW_VAR_AC_PARAM_BK: | ||
3258 | rtl8723a_set_ac_param_bk(padapter, *val32); | ||
3259 | break; | ||
3260 | |||
3261 | case HW_VAR_ACM_CTRL: | ||
3262 | rtl8723a_set_acm_ctrl(padapter, *val); | ||
3263 | break; | ||
3264 | |||
3265 | case HW_VAR_AMPDU_MIN_SPACE: | ||
3266 | rtl8723a_set_ampdu_min_space(padapter, *val); | ||
3267 | break; | ||
3268 | |||
3269 | case HW_VAR_AMPDU_FACTOR: | ||
3270 | rtl8723a_set_ampdu_factor(padapter, *val); | ||
3271 | break; | ||
3272 | |||
3273 | case HW_VAR_RXDMA_AGG_PG_TH: | ||
3274 | rtl8723a_set_rxdma_agg_pg_th(padapter, *val); | ||
3275 | break; | ||
3276 | |||
3277 | case HW_VAR_H2C_FW_PWRMODE: | ||
3278 | rtl8723a_set_FwPwrMode_cmd(padapter, *val); | ||
3279 | break; | ||
3280 | |||
3281 | case HW_VAR_H2C_FW_JOINBSSRPT: | ||
3282 | rtl8723a_set_FwJoinBssReport_cmd(padapter, *val); | ||
3283 | break; | ||
3284 | |||
3285 | #ifdef CONFIG_8723AU_P2P | ||
3286 | case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: | ||
3287 | rtl8723a_set_p2p_ps_offload_cmd(padapter, *val); | ||
3288 | break; | ||
3289 | #endif /* CONFIG_8723AU_P2P */ | ||
3290 | |||
3291 | case HW_VAR_INITIAL_GAIN: | ||
3292 | rtl8723a_set_initial_gain(padapter, *val32); | ||
3293 | break; | ||
3294 | case HW_VAR_EFUSE_BYTES: | ||
3295 | pHalData->EfuseUsedBytes = *((u16 *) val); | ||
3296 | break; | ||
3297 | case HW_VAR_EFUSE_BT_BYTES: | ||
3298 | pHalData->BTEfuseUsedBytes = *((u16 *) val); | ||
3299 | break; | ||
3300 | case HW_VAR_FIFO_CLEARN_UP: | ||
3301 | rtl8723a_fifo_cleanup(padapter); | ||
3302 | break; | ||
3303 | case HW_VAR_CHECK_TXBUF: | ||
3304 | break; | ||
3305 | case HW_VAR_APFM_ON_MAC: | ||
3306 | rtl8723a_set_apfm_on_mac(padapter, *val); | ||
3307 | break; | ||
3308 | |||
3309 | case HW_VAR_NAV_UPPER: | ||
3310 | rtl8723a_set_nav_upper(padapter, *val32); | ||
3311 | break; | ||
3312 | case HW_VAR_BCN_VALID: | ||
3313 | rtl8723a_bcn_valid(padapter); | ||
3314 | break; | ||
3315 | default: | ||
3316 | break; | ||
3317 | } | ||
3318 | |||
3319 | } | ||
3320 | |||
3321 | void GetHwReg8723A(struct rtw_adapter *padapter, u8 variable, u8 *val) | ||
3322 | { | ||
3323 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
3324 | |||
3325 | switch (variable) { | ||
3326 | case HW_VAR_BASIC_RATE: | ||
3327 | *((u16 *) val) = pHalData->BasicRateSet; | ||
3328 | break; | ||
3329 | |||
3330 | case HW_VAR_TXPAUSE: | ||
3331 | *val = rtw_read8(padapter, REG_TXPAUSE); | ||
3332 | break; | ||
3333 | |||
3334 | case HW_VAR_BCN_VALID: | ||
3335 | /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 */ | ||
3336 | val[0] = (BIT0 & rtw_read8(padapter, REG_TDECTRL + 2)) ? true : | ||
3337 | false; | ||
3338 | break; | ||
3339 | |||
3340 | case HW_VAR_RF_TYPE: | ||
3341 | *val = pHalData->rf_type; | ||
3342 | break; | ||
3343 | |||
3344 | case HW_VAR_DM_FLAG: | ||
3345 | { | ||
3346 | struct dm_odm_t *podmpriv = &pHalData->odmpriv; | ||
3347 | *((u32 *) val) = podmpriv->SupportAbility; | ||
3348 | } | ||
3349 | break; | ||
3350 | |||
3351 | case HW_VAR_FWLPS_RF_ON: | ||
3352 | { | ||
3353 | /* When we halt NIC, we should check if FW LPS is leave. */ | ||
3354 | u32 valRCR; | ||
3355 | |||
3356 | if ((padapter->bSurpriseRemoved == true) || | ||
3357 | (padapter->pwrctrlpriv.rf_pwrstate == rf_off)) { | ||
3358 | /* If it is in HW/SW Radio OFF or IPS state, we do | ||
3359 | not check Fw LPS Leave, because Fw is unload. */ | ||
3360 | *val = true; | ||
3361 | } else { | ||
3362 | valRCR = rtw_read32(padapter, REG_RCR); | ||
3363 | valRCR &= 0x00070000; | ||
3364 | if (valRCR) | ||
3365 | *val = false; | ||
3366 | else | ||
3367 | *val = true; | ||
3368 | } | ||
3369 | } | ||
3370 | break; | ||
3371 | case HW_VAR_EFUSE_BYTES: | ||
3372 | *((u16 *) val) = pHalData->EfuseUsedBytes; | ||
3373 | break; | ||
3374 | |||
3375 | case HW_VAR_EFUSE_BT_BYTES: | ||
3376 | *((u16 *) val) = pHalData->BTEfuseUsedBytes; | ||
3377 | break; | ||
3378 | |||
3379 | case HW_VAR_APFM_ON_MAC: | ||
3380 | *val = pHalData->bMacPwrCtrlOn; | ||
3381 | break; | ||
3382 | case HW_VAR_CHK_HI_QUEUE_EMPTY: | ||
3383 | *val = | ||
3384 | ((rtw_read32(padapter, REG_HGQ_INFORMATION) & 0x0000ff00) == | ||
3385 | 0) ? true : false; | ||
3386 | break; | ||
3387 | } | ||
3388 | } | ||
3389 | |||
3390 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
3391 | |||
3392 | void rtl8723a_SingleDualAntennaDetection(struct rtw_adapter *padapter) | ||
3393 | { | ||
3394 | struct hal_data_8723a *pHalData; | ||
3395 | struct dm_odm_t *pDM_Odm; | ||
3396 | struct sw_ant_sw *pDM_SWAT_Table; | ||
3397 | u8 i; | ||
3398 | |||
3399 | pHalData = GET_HAL_DATA(padapter); | ||
3400 | pDM_Odm = &pHalData->odmpriv; | ||
3401 | pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table; | ||
3402 | |||
3403 | /* */ | ||
3404 | /* <Roger_Notes> RTL8723A Single and Dual antenna dynamic detection | ||
3405 | mechanism when RF power state is on. */ | ||
3406 | /* We should take power tracking, IQK, LCK, RCK RF read/write | ||
3407 | operation into consideration. */ | ||
3408 | /* 2011.12.15. */ | ||
3409 | /* */ | ||
3410 | if (!pHalData->bAntennaDetected) { | ||
3411 | u8 btAntNum = BT_GetPGAntNum(padapter); | ||
3412 | |||
3413 | /* Set default antenna B status */ | ||
3414 | if (btAntNum == Ant_x2) | ||
3415 | pDM_SWAT_Table->ANTB_ON = true; | ||
3416 | else if (btAntNum == Ant_x1) | ||
3417 | pDM_SWAT_Table->ANTB_ON = false; | ||
3418 | else | ||
3419 | pDM_SWAT_Table->ANTB_ON = true; | ||
3420 | |||
3421 | if (pHalData->CustomerID != RT_CID_TOSHIBA) { | ||
3422 | for (i = 0; i < MAX_ANTENNA_DETECTION_CNT; i++) { | ||
3423 | if (ODM_SingleDualAntennaDetection | ||
3424 | (&pHalData->odmpriv, ANTTESTALL) == true) | ||
3425 | break; | ||
3426 | } | ||
3427 | |||
3428 | /* Set default antenna number for BT coexistence */ | ||
3429 | if (btAntNum == Ant_x2) | ||
3430 | BT_SetBtCoexCurrAntNum(padapter, | ||
3431 | pDM_SWAT_Table-> | ||
3432 | ANTB_ON ? 2 : 1); | ||
3433 | } | ||
3434 | pHalData->bAntennaDetected = true; | ||
3435 | } | ||
3436 | } | ||
3437 | #endif /* CONFIG_8723AU_BT_COEXIST */ | ||
3438 | |||
3439 | void rtl8723a_clone_haldata(struct rtw_adapter *dst_adapter, | ||
3440 | struct rtw_adapter *src_adapter) | ||
3441 | { | ||
3442 | memcpy(dst_adapter->HalData, src_adapter->HalData, | ||
3443 | dst_adapter->hal_data_sz); | ||
3444 | } | ||
3445 | |||
3446 | void rtl8723a_start_thread(struct rtw_adapter *padapter) | ||
3447 | { | ||
3448 | } | ||
3449 | |||
3450 | void rtl8723a_stop_thread(struct rtw_adapter *padapter) | ||
3451 | { | ||
3452 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c new file mode 100644 index 000000000000..bac3f3bd5311 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c | |||
@@ -0,0 +1,1197 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | #define _RTL8723A_PHYCFG_C_ | ||
16 | |||
17 | #include <osdep_service.h> | ||
18 | #include <drv_types.h> | ||
19 | |||
20 | #include <rtl8723a_hal.h> | ||
21 | |||
22 | /*---------------------------Define Local Constant---------------------------*/ | ||
23 | /* Channel switch:The size of command tables for switch channel*/ | ||
24 | #define MAX_PRECMD_CNT 16 | ||
25 | #define MAX_RFDEPENDCMD_CNT 16 | ||
26 | #define MAX_POSTCMD_CNT 16 | ||
27 | |||
28 | #define MAX_DOZE_WAITING_TIMES_9x 64 | ||
29 | |||
30 | /*---------------------------Define Local Constant---------------------------*/ | ||
31 | |||
32 | /*------------------------Define global variable-----------------------------*/ | ||
33 | |||
34 | /*------------------------Define local variable------------------------------*/ | ||
35 | |||
36 | /*--------------------Define export function prototype-----------------------*/ | ||
37 | /* Please refer to header file */ | ||
38 | /*--------------------Define export function prototype-----------------------*/ | ||
39 | |||
40 | /*----------------------------Function Body----------------------------------*/ | ||
41 | /* */ | ||
42 | /* 1. BB register R/W API */ | ||
43 | /* */ | ||
44 | |||
45 | /** | ||
46 | * Function: phy_CalculateBitShift | ||
47 | * | ||
48 | * OverView: Get shifted position of the BitMask | ||
49 | * | ||
50 | * Input: | ||
51 | * u32 BitMask, | ||
52 | * | ||
53 | * Output: none | ||
54 | * Return: u32 Return the shift bit bit position of the mask | ||
55 | */ | ||
56 | static u32 phy_CalculateBitShift(u32 BitMask) | ||
57 | { | ||
58 | u32 i; | ||
59 | |||
60 | for (i = 0; i <= 31; i++) { | ||
61 | if (((BitMask>>i) & 0x1) == 1) | ||
62 | break; | ||
63 | } | ||
64 | |||
65 | return i; | ||
66 | } | ||
67 | |||
68 | /** | ||
69 | * Function: PHY_QueryBBReg | ||
70 | * | ||
71 | * OverView: Read "sepcific bits" from BB register | ||
72 | * | ||
73 | * Input: | ||
74 | * struct rtw_adapter * Adapter, | ||
75 | * u32 RegAddr, Target address to be readback | ||
76 | * u32 BitMask Target bit position in the | ||
77 | * target address to be readback | ||
78 | * Output: | ||
79 | * None | ||
80 | * Return: | ||
81 | * u32 Data The readback register value | ||
82 | * Note: | ||
83 | * This function is equal to "GetRegSetting" in PHY programming guide | ||
84 | */ | ||
85 | u32 | ||
86 | PHY_QueryBBReg(struct rtw_adapter *Adapter, u32 RegAddr, u32 BitMask) | ||
87 | { | ||
88 | u32 ReturnValue = 0, OriginalValue, BitShift; | ||
89 | |||
90 | OriginalValue = rtw_read32(Adapter, RegAddr); | ||
91 | BitShift = phy_CalculateBitShift(BitMask); | ||
92 | ReturnValue = (OriginalValue & BitMask) >> BitShift; | ||
93 | return ReturnValue; | ||
94 | } | ||
95 | |||
96 | /** | ||
97 | * Function: PHY_SetBBReg | ||
98 | * | ||
99 | * OverView: Write "Specific bits" to BB register (page 8~) | ||
100 | * | ||
101 | * Input: | ||
102 | * struct rtw_adapter * Adapter, | ||
103 | * u32 RegAddr, Target address to be modified | ||
104 | * u32 BitMask Target bit position in the | ||
105 | * target address to be modified | ||
106 | * u32 Data The new register value in the | ||
107 | * target bit position of the | ||
108 | * target address | ||
109 | * | ||
110 | * Output: | ||
111 | * None | ||
112 | * Return: | ||
113 | * None | ||
114 | * Note: | ||
115 | * This function is equal to "PutRegSetting" in PHY programming guide | ||
116 | */ | ||
117 | |||
118 | void | ||
119 | PHY_SetBBReg(struct rtw_adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data) | ||
120 | { | ||
121 | u32 OriginalValue, BitShift; | ||
122 | |||
123 | /* RT_TRACE(COMP_RF, DBG_TRACE, ("--->PHY_SetBBReg(): RegAddr(%#lx), BitMask(%#lx), Data(%#lx)\n", RegAddr, BitMask, Data)); */ | ||
124 | |||
125 | if (BitMask != bMaskDWord) {/* if not "double word" write */ | ||
126 | OriginalValue = rtw_read32(Adapter, RegAddr); | ||
127 | BitShift = phy_CalculateBitShift(BitMask); | ||
128 | Data = ((OriginalValue & (~BitMask)) | (Data << BitShift)); | ||
129 | } | ||
130 | |||
131 | rtw_write32(Adapter, RegAddr, Data); | ||
132 | |||
133 | /* RTPRINT(FPHY, PHY_BBW, ("BBW MASK = 0x%lx Addr[0x%lx]= 0x%lx\n", BitMask, RegAddr, Data)); */ | ||
134 | /* RT_TRACE(COMP_RF, DBG_TRACE, ("<---PHY_SetBBReg(): RegAddr(%#lx), BitMask(%#lx), Data(%#lx)\n", RegAddr, BitMask, Data)); */ | ||
135 | } | ||
136 | |||
137 | /* */ | ||
138 | /* 2. RF register R/W API */ | ||
139 | /* */ | ||
140 | |||
141 | /** | ||
142 | * Function: phy_RFSerialRead | ||
143 | * | ||
144 | * OverView: Read regster from RF chips | ||
145 | * | ||
146 | * Input: | ||
147 | * struct rtw_adapter * Adapter, | ||
148 | * enum RF_RADIO_PATH eRFPath, Radio path of A/B/C/D | ||
149 | * u32 Offset, The target address to be read | ||
150 | * | ||
151 | * Output: None | ||
152 | * Return: u32 reback value | ||
153 | * Note: Threre are three types of serial operations: | ||
154 | * 1. Software serial write | ||
155 | * 2. Hardware LSSI-Low Speed Serial Interface | ||
156 | * 3. Hardware HSSI-High speed | ||
157 | * serial write. Driver need to implement (1) and (2). | ||
158 | * This function is equal to the combination of RF_ReadReg() and | ||
159 | * RFLSSIRead() | ||
160 | */ | ||
161 | static u32 | ||
162 | phy_RFSerialRead(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath, | ||
163 | u32 Offset) | ||
164 | { | ||
165 | u32 retValue = 0; | ||
166 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
167 | struct bb_reg_define *pPhyReg = &pHalData->PHYRegDef[eRFPath]; | ||
168 | u32 NewOffset; | ||
169 | u32 tmplong, tmplong2; | ||
170 | u8 RfPiEnable = 0; | ||
171 | /* */ | ||
172 | /* Make sure RF register offset is correct */ | ||
173 | /* */ | ||
174 | Offset &= 0x3f; | ||
175 | |||
176 | /* */ | ||
177 | /* Switch page for 8256 RF IC */ | ||
178 | /* */ | ||
179 | NewOffset = Offset; | ||
180 | |||
181 | /* 2009/06/17 MH We can not execute IO for power save or | ||
182 | other accident mode. */ | ||
183 | /* if (RT_CANNOT_IO(Adapter)) */ | ||
184 | /* */ | ||
185 | /* RTPRINT(FPHY, PHY_RFR, ("phy_RFSerialRead return all one\n")); */ | ||
186 | /* return 0xFFFFFFFF; */ | ||
187 | /* */ | ||
188 | |||
189 | /* For 92S LSSI Read RFLSSIRead */ | ||
190 | /* For RF A/B write 0x824/82c(does not work in the future) */ | ||
191 | /* We must use 0x824 for RF A and B to execute read trigger */ | ||
192 | tmplong = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord); | ||
193 | if (eRFPath == RF_PATH_A) | ||
194 | tmplong2 = tmplong; | ||
195 | else | ||
196 | tmplong2 = PHY_QueryBBReg(Adapter, pPhyReg->rfHSSIPara2, | ||
197 | bMaskDWord); | ||
198 | |||
199 | tmplong2 = (tmplong2 & ~bLSSIReadAddress) | | ||
200 | (NewOffset << 23) | bLSSIReadEdge; /* T65 RF */ | ||
201 | |||
202 | PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, | ||
203 | bMaskDWord, tmplong & (~bLSSIReadEdge)); | ||
204 | udelay(10);/* PlatformStallExecution(10); */ | ||
205 | |||
206 | PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord, tmplong2); | ||
207 | udelay(100);/* PlatformStallExecution(100); */ | ||
208 | |||
209 | PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord, | ||
210 | tmplong | bLSSIReadEdge); | ||
211 | udelay(10);/* PlatformStallExecution(10); */ | ||
212 | |||
213 | if (eRFPath == RF_PATH_A) | ||
214 | RfPiEnable = (u8)PHY_QueryBBReg(Adapter, | ||
215 | rFPGA0_XA_HSSIParameter1, BIT8); | ||
216 | else if (eRFPath == RF_PATH_B) | ||
217 | RfPiEnable = (u8)PHY_QueryBBReg(Adapter, | ||
218 | rFPGA0_XB_HSSIParameter1, BIT8); | ||
219 | |||
220 | if (RfPiEnable) { | ||
221 | /* Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */ | ||
222 | retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi, | ||
223 | bLSSIReadBackData); | ||
224 | /* DBG_8723A("Readback from RF-PI : 0x%x\n", retValue); */ | ||
225 | } else { | ||
226 | /* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */ | ||
227 | retValue = PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBack, | ||
228 | bLSSIReadBackData); | ||
229 | /* DBG_8723A("Readback from RF-SI : 0x%x\n", retValue); */ | ||
230 | } | ||
231 | /* DBG_8723A("RFR-%d Addr[0x%x]= 0x%x\n", eRFPath, pPhyReg->rfLSSIReadBack, retValue); */ | ||
232 | |||
233 | return retValue; | ||
234 | } | ||
235 | |||
236 | /** | ||
237 | * Function: phy_RFSerialWrite | ||
238 | * | ||
239 | * OverView: Write data to RF register (page 8~) | ||
240 | * | ||
241 | * Input: | ||
242 | * struct rtw_adapter * Adapter, | ||
243 | * enum RF_RADIO_PATH eRFPath, Radio path of A/B/C/D | ||
244 | * u32 Offset, The target address to be read | ||
245 | * u32 Data The new register Data in the target | ||
246 | * bit position of the target to be read | ||
247 | * | ||
248 | * Output: | ||
249 | * None | ||
250 | * Return: | ||
251 | * None | ||
252 | * Note: | ||
253 | * Threre are three types of serial operations: | ||
254 | * 1. Software serial write | ||
255 | * 2. Hardware LSSI-Low Speed Serial Interface | ||
256 | * 3. Hardware HSSI-High speed | ||
257 | * serial write. Driver need to implement (1) and (2). | ||
258 | * This function is equal to the combination of RF_ReadReg() and | ||
259 | * RFLSSIRead() | ||
260 | * | ||
261 | * Note: For RF8256 only | ||
262 | * The total count of RTL8256(Zebra4) register is around 36 bit it only employs | ||
263 | * 4-bit RF address. RTL8256 uses "register mode control bit" | ||
264 | * (Reg00[12], Reg00[10]) to access register address bigger than 0xf. | ||
265 | * See "Appendix-4 in PHY Configuration programming guide" for more details. | ||
266 | * Thus, we define a sub-finction for RTL8526 register address conversion | ||
267 | * =========================================================== | ||
268 | * Register Mode: RegCTL[1] RegCTL[0] Note | ||
269 | * (Reg00[12]) (Reg00[10]) | ||
270 | * =========================================================== | ||
271 | * Reg_Mode0 0 x Reg 0 ~15(0x0 ~ 0xf) | ||
272 | * ------------------------------------------------------------------ | ||
273 | * Reg_Mode1 1 0 Reg 16 ~30(0x1 ~ 0xf) | ||
274 | * ------------------------------------------------------------------ | ||
275 | * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf) | ||
276 | * ------------------------------------------------------------------ | ||
277 | * | ||
278 | * 2008/09/02 MH Add 92S RF definition | ||
279 | */ | ||
280 | static void | ||
281 | phy_RFSerialWrite(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath, | ||
282 | u32 Offset, u32 Data) | ||
283 | { | ||
284 | u32 DataAndAddr = 0; | ||
285 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
286 | struct bb_reg_define *pPhyReg = &pHalData->PHYRegDef[eRFPath]; | ||
287 | u32 NewOffset; | ||
288 | |||
289 | /* 2009/06/17 MH We can not execute IO for power save or | ||
290 | other accident mode. */ | ||
291 | /* if (RT_CANNOT_IO(Adapter)) */ | ||
292 | /* */ | ||
293 | /* RTPRINT(FPHY, PHY_RFW, ("phy_RFSerialWrite stop\n")); */ | ||
294 | /* return; */ | ||
295 | /* */ | ||
296 | |||
297 | Offset &= 0x3f; | ||
298 | |||
299 | /* */ | ||
300 | /* Shadow Update */ | ||
301 | /* */ | ||
302 | /* PHY_RFShadowWrite(Adapter, eRFPath, Offset, Data); */ | ||
303 | |||
304 | /* */ | ||
305 | /* Switch page for 8256 RF IC */ | ||
306 | /* */ | ||
307 | NewOffset = Offset; | ||
308 | |||
309 | /* */ | ||
310 | /* Put write addr in [5:0] and write data in [31:16] */ | ||
311 | /* */ | ||
312 | /* DataAndAddr = (Data<<16) | (NewOffset&0x3f); */ | ||
313 | /* T65 RF */ | ||
314 | DataAndAddr = ((NewOffset<<20) | (Data&0x000fffff)) & 0x0fffffff; | ||
315 | |||
316 | /* */ | ||
317 | /* Write Operation */ | ||
318 | /* */ | ||
319 | PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); | ||
320 | /* RTPRINT(FPHY, PHY_RFW, ("RFW-%d Addr[0x%lx]= 0x%lx\n", eRFPath, pPhyReg->rf3wireOffset, DataAndAddr)); */ | ||
321 | |||
322 | } | ||
323 | |||
324 | /** | ||
325 | * Function: PHY_QueryRFReg | ||
326 | * | ||
327 | * OverView: Query "Specific bits" to RF register (page 8~) | ||
328 | * | ||
329 | * Input: | ||
330 | * struct rtw_adapter * Adapter, | ||
331 | * enum RF_RADIO_PATH eRFPath, Radio path of A/B/C/D | ||
332 | * u32 RegAddr, The target address to be read | ||
333 | * u32BitMask The target bit position in the target | ||
334 | * address to be read | ||
335 | * | ||
336 | * Output: | ||
337 | * None | ||
338 | * Return: | ||
339 | * u32 Readback value | ||
340 | * Note: | ||
341 | * This function is equal to "GetRFRegSetting" in PHY programming guide | ||
342 | */ | ||
343 | u32 | ||
344 | PHY_QueryRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath, | ||
345 | u32 RegAddr, u32 BitMask) | ||
346 | { | ||
347 | u32 Original_Value, Readback_Value, BitShift; | ||
348 | /* struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); */ | ||
349 | /* u8 RFWaitCounter = 0; */ | ||
350 | /* _irqL irqL; */ | ||
351 | |||
352 | Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr); | ||
353 | |||
354 | BitShift = phy_CalculateBitShift(BitMask); | ||
355 | Readback_Value = (Original_Value & BitMask) >> BitShift; | ||
356 | |||
357 | return Readback_Value; | ||
358 | } | ||
359 | |||
360 | /** | ||
361 | * Function: PHY_SetRFReg | ||
362 | * | ||
363 | * OverView: Write "Specific bits" to RF register (page 8~) | ||
364 | * | ||
365 | * Input: | ||
366 | * struct rtw_adapter * Adapter, | ||
367 | * enum RF_RADIO_PATH eRFPath, Radio path of A/B/C/D | ||
368 | * u32 RegAddr, The target address to be modified | ||
369 | * u32 BitMask The target bit position in the target | ||
370 | * address to be modified | ||
371 | * u32 Data The new register Data in the target | ||
372 | * bit position of the target address | ||
373 | * | ||
374 | * Output: | ||
375 | * None | ||
376 | * Return: | ||
377 | * None | ||
378 | * Note: This function is equal to "PutRFRegSetting" in PHY programming guide | ||
379 | */ | ||
380 | void | ||
381 | PHY_SetRFReg(struct rtw_adapter *Adapter, enum RF_RADIO_PATH eRFPath, | ||
382 | u32 RegAddr, u32 BitMask, u32 Data) | ||
383 | { | ||
384 | /* struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); */ | ||
385 | /* u8 RFWaitCounter = 0; */ | ||
386 | u32 Original_Value, BitShift; | ||
387 | |||
388 | /* RF data is 12 bits only */ | ||
389 | if (BitMask != bRFRegOffsetMask) { | ||
390 | Original_Value = phy_RFSerialRead(Adapter, eRFPath, RegAddr); | ||
391 | BitShift = phy_CalculateBitShift(BitMask); | ||
392 | Data = ((Original_Value & (~BitMask)) | (Data << BitShift)); | ||
393 | } | ||
394 | |||
395 | phy_RFSerialWrite(Adapter, eRFPath, RegAddr, Data); | ||
396 | } | ||
397 | |||
398 | /* 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */ | ||
399 | |||
400 | /*----------------------------------------------------------------------------- | ||
401 | * Function: PHY_MACConfig8723A | ||
402 | * | ||
403 | * Overview: Condig MAC by header file or parameter file. | ||
404 | * | ||
405 | * Input: NONE | ||
406 | * | ||
407 | * Output: NONE | ||
408 | * | ||
409 | * Return: NONE | ||
410 | * | ||
411 | * Revised History: | ||
412 | * When Who Remark | ||
413 | * 08/12/2008 MHC Create Version 0. | ||
414 | * | ||
415 | *---------------------------------------------------------------------------*/ | ||
416 | s32 PHY_MACConfig8723A(struct rtw_adapter *Adapter) | ||
417 | { | ||
418 | int rtStatus = _SUCCESS; | ||
419 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
420 | s8 *pszMACRegFile; | ||
421 | s8 sz8723MACRegFile[] = RTL8723_PHY_MACREG; | ||
422 | bool is92C = IS_92C_SERIAL(pHalData->VersionID); | ||
423 | |||
424 | pszMACRegFile = sz8723MACRegFile; | ||
425 | |||
426 | /* */ | ||
427 | /* Config MAC */ | ||
428 | /* */ | ||
429 | if (HAL_STATUS_FAILURE == | ||
430 | ODM_ConfigMACWithHeaderFile23a(&pHalData->odmpriv)) | ||
431 | rtStatus = _FAIL; | ||
432 | |||
433 | /* 2010.07.13 AMPDU aggregation number 9 */ | ||
434 | /* rtw_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); */ | ||
435 | rtw_write8(Adapter, REG_MAX_AGGR_NUM, 0x0A); /* By tynli. 2010.11.18. */ | ||
436 | if (is92C && (BOARD_USB_DONGLE == pHalData->BoardType)) | ||
437 | rtw_write8(Adapter, 0x40, 0x04); | ||
438 | |||
439 | return rtStatus; | ||
440 | } | ||
441 | |||
442 | /** | ||
443 | * Function: phy_InitBBRFRegisterDefinition | ||
444 | * | ||
445 | * OverView: Initialize Register definition offset for Radio Path A/B/C/D | ||
446 | * | ||
447 | * Input: | ||
448 | * struct rtw_adapter * Adapter, | ||
449 | * | ||
450 | * Output: None | ||
451 | * Return: None | ||
452 | * Note: | ||
453 | * The initialization value is constant and it should never be changes | ||
454 | */ | ||
455 | static void | ||
456 | phy_InitBBRFRegisterDefinition(struct rtw_adapter *Adapter) | ||
457 | { | ||
458 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
459 | |||
460 | /* RF Interface Sowrtware Control */ | ||
461 | /* 16 LSBs if read 32-bit from 0x870 */ | ||
462 | pHalData->PHYRegDef[RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; | ||
463 | /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */ | ||
464 | pHalData->PHYRegDef[RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; | ||
465 | /* 16 LSBs if read 32-bit from 0x874 */ | ||
466 | pHalData->PHYRegDef[RF_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW; | ||
467 | /* 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) */ | ||
468 | pHalData->PHYRegDef[RF_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW; | ||
469 | |||
470 | /* RF Interface Readback Value */ | ||
471 | /* 16 LSBs if read 32-bit from 0x8E0 */ | ||
472 | pHalData->PHYRegDef[RF_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; | ||
473 | /* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */ | ||
474 | pHalData->PHYRegDef[RF_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB; | ||
475 | /* 16 LSBs if read 32-bit from 0x8E4 */ | ||
476 | pHalData->PHYRegDef[RF_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB; | ||
477 | /* 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) */ | ||
478 | pHalData->PHYRegDef[RF_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB; | ||
479 | |||
480 | /* RF Interface Output (and Enable) */ | ||
481 | /* 16 LSBs if read 32-bit from 0x860 */ | ||
482 | pHalData->PHYRegDef[RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; | ||
483 | /* 16 LSBs if read 32-bit from 0x864 */ | ||
484 | pHalData->PHYRegDef[RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; | ||
485 | |||
486 | /* RF Interface (Output and) Enable */ | ||
487 | /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */ | ||
488 | pHalData->PHYRegDef[RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; | ||
489 | /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */ | ||
490 | pHalData->PHYRegDef[RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; | ||
491 | |||
492 | /* Addr of LSSI. Wirte RF register by driver */ | ||
493 | pHalData->PHYRegDef[RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; | ||
494 | pHalData->PHYRegDef[RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; | ||
495 | |||
496 | /* RF parameter */ | ||
497 | /* BB Band Select */ | ||
498 | pHalData->PHYRegDef[RF_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; | ||
499 | pHalData->PHYRegDef[RF_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter; | ||
500 | pHalData->PHYRegDef[RF_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter; | ||
501 | pHalData->PHYRegDef[RF_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter; | ||
502 | |||
503 | /* Tx AGC Gain Stage (same for all path. Should we remove this?) */ | ||
504 | pHalData->PHYRegDef[RF_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; | ||
505 | pHalData->PHYRegDef[RF_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; | ||
506 | pHalData->PHYRegDef[RF_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; | ||
507 | pHalData->PHYRegDef[RF_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; | ||
508 | |||
509 | /* Tranceiver A~D HSSI Parameter-1 */ | ||
510 | /* wire control parameter1 */ | ||
511 | pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; | ||
512 | /* wire control parameter1 */ | ||
513 | pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; | ||
514 | |||
515 | /* Tranceiver A~D HSSI Parameter-2 */ | ||
516 | /* wire control parameter2 */ | ||
517 | pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; | ||
518 | /* wire control parameter2 */ | ||
519 | pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; | ||
520 | |||
521 | /* RF switch Control */ | ||
522 | pHalData->PHYRegDef[RF_PATH_A].rfSwitchControl = | ||
523 | rFPGA0_XAB_SwitchControl; /* TR/Ant switch control */ | ||
524 | pHalData->PHYRegDef[RF_PATH_B].rfSwitchControl = | ||
525 | rFPGA0_XAB_SwitchControl; | ||
526 | pHalData->PHYRegDef[RF_PATH_C].rfSwitchControl = | ||
527 | rFPGA0_XCD_SwitchControl; | ||
528 | pHalData->PHYRegDef[RF_PATH_D].rfSwitchControl = | ||
529 | rFPGA0_XCD_SwitchControl; | ||
530 | |||
531 | /* AGC control 1 */ | ||
532 | pHalData->PHYRegDef[RF_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1; | ||
533 | pHalData->PHYRegDef[RF_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1; | ||
534 | pHalData->PHYRegDef[RF_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1; | ||
535 | pHalData->PHYRegDef[RF_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1; | ||
536 | |||
537 | /* AGC control 2 */ | ||
538 | pHalData->PHYRegDef[RF_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2; | ||
539 | pHalData->PHYRegDef[RF_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2; | ||
540 | pHalData->PHYRegDef[RF_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2; | ||
541 | pHalData->PHYRegDef[RF_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2; | ||
542 | |||
543 | /* RX AFE control 1 */ | ||
544 | pHalData->PHYRegDef[RF_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance; | ||
545 | pHalData->PHYRegDef[RF_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance; | ||
546 | pHalData->PHYRegDef[RF_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance; | ||
547 | pHalData->PHYRegDef[RF_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance; | ||
548 | |||
549 | /* RX AFE control 1 */ | ||
550 | pHalData->PHYRegDef[RF_PATH_A].rfRxAFE = rOFDM0_XARxAFE; | ||
551 | pHalData->PHYRegDef[RF_PATH_B].rfRxAFE = rOFDM0_XBRxAFE; | ||
552 | pHalData->PHYRegDef[RF_PATH_C].rfRxAFE = rOFDM0_XCRxAFE; | ||
553 | pHalData->PHYRegDef[RF_PATH_D].rfRxAFE = rOFDM0_XDRxAFE; | ||
554 | |||
555 | /* Tx AFE control 1 */ | ||
556 | pHalData->PHYRegDef[RF_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance; | ||
557 | pHalData->PHYRegDef[RF_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance; | ||
558 | pHalData->PHYRegDef[RF_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance; | ||
559 | pHalData->PHYRegDef[RF_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance; | ||
560 | |||
561 | /* Tx AFE control 2 */ | ||
562 | pHalData->PHYRegDef[RF_PATH_A].rfTxAFE = rOFDM0_XATxAFE; | ||
563 | pHalData->PHYRegDef[RF_PATH_B].rfTxAFE = rOFDM0_XBTxAFE; | ||
564 | pHalData->PHYRegDef[RF_PATH_C].rfTxAFE = rOFDM0_XCTxAFE; | ||
565 | pHalData->PHYRegDef[RF_PATH_D].rfTxAFE = rOFDM0_XDTxAFE; | ||
566 | |||
567 | /* Tranceiver LSSI Readback SI mode */ | ||
568 | pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; | ||
569 | pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; | ||
570 | pHalData->PHYRegDef[RF_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack; | ||
571 | pHalData->PHYRegDef[RF_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack; | ||
572 | |||
573 | /* Tranceiver LSSI Readback PI mode */ | ||
574 | pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi = | ||
575 | TransceiverA_HSPI_Readback; | ||
576 | pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBackPi = | ||
577 | TransceiverB_HSPI_Readback; | ||
578 | /* pHalData->PHYRegDef[RF_PATH_C].rfLSSIReadBackPi = | ||
579 | rFPGA0_XC_LSSIReadBack; */ | ||
580 | /* pHalData->PHYRegDef[RF_PATH_D].rfLSSIReadBackPi = | ||
581 | rFPGA0_XD_LSSIReadBack; */ | ||
582 | |||
583 | } | ||
584 | |||
585 | /* The following is for High Power PA */ | ||
586 | static void | ||
587 | storePwrIndexDiffRateOffset(struct rtw_adapter *Adapter, u32 RegAddr, | ||
588 | u32 BitMask, u32 Data) | ||
589 | { | ||
590 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
591 | |||
592 | if (RegAddr == rTxAGC_A_Rate18_06) { | ||
593 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0] = Data; | ||
594 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
595 | ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%lx\n", | ||
596 | pHalData->pwrGroupCnt, */ | ||
597 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
598 | pHalData->pwrGroupCnt][0])); */ | ||
599 | } | ||
600 | if (RegAddr == rTxAGC_A_Rate54_24) { | ||
601 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1] = Data; | ||
602 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
603 | ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%lx\n", | ||
604 | pHalData->pwrGroupCnt, */ | ||
605 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
606 | pHalData->pwrGroupCnt][1])); */ | ||
607 | } | ||
608 | if (RegAddr == rTxAGC_A_CCK1_Mcs32) { | ||
609 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6] = Data; | ||
610 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
611 | ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%lx\n", | ||
612 | pHalData->pwrGroupCnt, */ | ||
613 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
614 | pHalData->pwrGroupCnt][6])); */ | ||
615 | } | ||
616 | if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0xffffff00) { | ||
617 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7] = Data; | ||
618 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
619 | ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%lx\n", | ||
620 | pHalData->pwrGroupCnt, */ | ||
621 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
622 | pHalData->pwrGroupCnt][7])); */ | ||
623 | } | ||
624 | if (RegAddr == rTxAGC_A_Mcs03_Mcs00) { | ||
625 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2] = Data; | ||
626 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
627 | ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%lx\n", | ||
628 | pHalData->pwrGroupCnt, */ | ||
629 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
630 | pHalData->pwrGroupCnt][2])); */ | ||
631 | } | ||
632 | if (RegAddr == rTxAGC_A_Mcs07_Mcs04) { | ||
633 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3] = Data; | ||
634 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
635 | ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%lx\n", | ||
636 | pHalData->pwrGroupCnt, */ | ||
637 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
638 | pHalData->pwrGroupCnt][3])); */ | ||
639 | } | ||
640 | if (RegAddr == rTxAGC_A_Mcs11_Mcs08) { | ||
641 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4] = Data; | ||
642 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
643 | ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%lx\n", | ||
644 | pHalData->pwrGroupCnt, */ | ||
645 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
646 | pHalData->pwrGroupCnt][4])); */ | ||
647 | } | ||
648 | if (RegAddr == rTxAGC_A_Mcs15_Mcs12) { | ||
649 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5] = Data; | ||
650 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
651 | ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%lx\n", | ||
652 | pHalData->pwrGroupCnt, */ | ||
653 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
654 | pHalData->pwrGroupCnt][5])); */ | ||
655 | } | ||
656 | if (RegAddr == rTxAGC_B_Rate18_06) { | ||
657 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8] = Data; | ||
658 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
659 | ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%lx\n", | ||
660 | pHalData->pwrGroupCnt, */ | ||
661 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
662 | pHalData->pwrGroupCnt][8])); */ | ||
663 | } | ||
664 | if (RegAddr == rTxAGC_B_Rate54_24) { | ||
665 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9] = Data; | ||
666 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
667 | ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%lx\n", | ||
668 | pHalData->pwrGroupCnt, */ | ||
669 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
670 | pHalData->pwrGroupCnt][9])); */ | ||
671 | } | ||
672 | if (RegAddr == rTxAGC_B_CCK1_55_Mcs32) { | ||
673 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14] = Data; | ||
674 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
675 | ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%lx\n", | ||
676 | pHalData->pwrGroupCnt, */ | ||
677 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
678 | pHalData->pwrGroupCnt][14])); */ | ||
679 | } | ||
680 | if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0x000000ff) { | ||
681 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15] = Data; | ||
682 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
683 | ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%lx\n", | ||
684 | pHalData->pwrGroupCnt, */ | ||
685 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
686 | pHalData->pwrGroupCnt][15])); */ | ||
687 | } | ||
688 | if (RegAddr == rTxAGC_B_Mcs03_Mcs00) { | ||
689 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10] = Data; | ||
690 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
691 | ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%lx\n", | ||
692 | pHalData->pwrGroupCnt, */ | ||
693 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
694 | pHalData->pwrGroupCnt][10])); */ | ||
695 | } | ||
696 | if (RegAddr == rTxAGC_B_Mcs07_Mcs04) { | ||
697 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11] = Data; | ||
698 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
699 | ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%lx\n", | ||
700 | pHalData->pwrGroupCnt, */ | ||
701 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
702 | pHalData->pwrGroupCnt][11])); */ | ||
703 | } | ||
704 | if (RegAddr == rTxAGC_B_Mcs11_Mcs08) { | ||
705 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12] = Data; | ||
706 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
707 | ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%lx\n", | ||
708 | pHalData->pwrGroupCnt, */ | ||
709 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
710 | pHalData->pwrGroupCnt][12])); */ | ||
711 | } | ||
712 | if (RegAddr == rTxAGC_B_Mcs15_Mcs12) { | ||
713 | pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13] = Data; | ||
714 | /* RT_TRACE(COMP_INIT, DBG_TRACE, | ||
715 | ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%lx\n", | ||
716 | pHalData->pwrGroupCnt, */ | ||
717 | /* pHalData->MCSTxPowerLevelOriginalOffset[ | ||
718 | pHalData->pwrGroupCnt][13])); */ | ||
719 | pHalData->pwrGroupCnt++; | ||
720 | } | ||
721 | } | ||
722 | |||
723 | /*----------------------------------------------------------------------------- | ||
724 | * Function: phy_ConfigBBWithPgHeaderFile | ||
725 | * | ||
726 | * Overview: Config PHY_REG_PG array | ||
727 | * | ||
728 | * Input: NONE | ||
729 | * | ||
730 | * Output: NONE | ||
731 | * | ||
732 | * Return: NONE | ||
733 | * | ||
734 | * Revised History: | ||
735 | * When Who Remark | ||
736 | * 11/06/2008 MHC Add later!!!!!!.. Please modify for new files!!!! | ||
737 | * 11/10/2008 tynli Modify to mew files. | ||
738 | *---------------------------------------------------------------------------*/ | ||
739 | static int | ||
740 | phy_ConfigBBWithPgHeaderFile(struct rtw_adapter *Adapter, u8 ConfigType) | ||
741 | { | ||
742 | int i; | ||
743 | u32 *Rtl819XPHY_REGArray_Table_PG; | ||
744 | u16 PHY_REGArrayPGLen; | ||
745 | |||
746 | PHY_REGArrayPGLen = Rtl8723_PHY_REG_Array_PGLength; | ||
747 | Rtl819XPHY_REGArray_Table_PG = (u32 *)Rtl8723_PHY_REG_Array_PG; | ||
748 | |||
749 | if (ConfigType == BaseBand_Config_PHY_REG) { | ||
750 | for (i = 0; i < PHY_REGArrayPGLen; i = i + 3) { | ||
751 | storePwrIndexDiffRateOffset(Adapter, | ||
752 | Rtl819XPHY_REGArray_Table_PG[i], | ||
753 | Rtl819XPHY_REGArray_Table_PG[i+1], | ||
754 | Rtl819XPHY_REGArray_Table_PG[i+2]); | ||
755 | } | ||
756 | } | ||
757 | |||
758 | return _SUCCESS; | ||
759 | } /* phy_ConfigBBWithPgHeaderFile */ | ||
760 | |||
761 | static void | ||
762 | phy_BB8192C_Config_1T(struct rtw_adapter *Adapter) | ||
763 | { | ||
764 | /* for path - B */ | ||
765 | PHY_SetBBReg(Adapter, rFPGA0_TxInfo, 0x3, 0x2); | ||
766 | PHY_SetBBReg(Adapter, rFPGA1_TxInfo, 0x300033, 0x200022); | ||
767 | |||
768 | /* 20100519 Joseph: Add for 1T2R config. Suggested by Kevin, | ||
769 | Jenyu and Yunan. */ | ||
770 | PHY_SetBBReg(Adapter, rCCK0_AFESetting, bMaskByte3, 0x45); | ||
771 | PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x23); | ||
772 | /* B path first AGC */ | ||
773 | PHY_SetBBReg(Adapter, rOFDM0_AGCParameter1, 0x30, 0x1); | ||
774 | |||
775 | PHY_SetBBReg(Adapter, 0xe74, 0x0c000000, 0x2); | ||
776 | PHY_SetBBReg(Adapter, 0xe78, 0x0c000000, 0x2); | ||
777 | PHY_SetBBReg(Adapter, 0xe7c, 0x0c000000, 0x2); | ||
778 | PHY_SetBBReg(Adapter, 0xe80, 0x0c000000, 0x2); | ||
779 | PHY_SetBBReg(Adapter, 0xe88, 0x0c000000, 0x2); | ||
780 | } | ||
781 | |||
782 | static int | ||
783 | phy_BB8723a_Config_ParaFile(struct rtw_adapter *Adapter) | ||
784 | { | ||
785 | struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter); | ||
786 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
787 | int rtStatus = _SUCCESS; | ||
788 | |||
789 | u8 sz8723BBRegFile[] = RTL8723_PHY_REG; | ||
790 | u8 sz8723AGCTableFile[] = RTL8723_AGC_TAB; | ||
791 | u8 sz8723BBRegPgFile[] = RTL8723_PHY_REG_PG; | ||
792 | u8 sz8723BBRegMpFile[] = RTL8723_PHY_REG_MP; | ||
793 | |||
794 | u8 *pszBBRegFile = NULL, *pszAGCTableFile = NULL; | ||
795 | u8 *pszBBRegPgFile = NULL, *pszBBRegMpFile = NULL; | ||
796 | |||
797 | /* RT_TRACE(COMP_INIT, DBG_TRACE, ("==>phy_BB8192S_Config_ParaFile\n")); */ | ||
798 | |||
799 | pszBBRegFile = sz8723BBRegFile ; | ||
800 | pszAGCTableFile = sz8723AGCTableFile; | ||
801 | pszBBRegPgFile = sz8723BBRegPgFile; | ||
802 | pszBBRegMpFile = sz8723BBRegMpFile; | ||
803 | |||
804 | /* */ | ||
805 | /* 1. Read PHY_REG.TXT BB INIT!! */ | ||
806 | /* We will seperate as 88C / 92C according to chip version */ | ||
807 | /* */ | ||
808 | if (HAL_STATUS_FAILURE == ODM_ConfigBBWithHeaderFile23a(&pHalData->odmpriv, | ||
809 | CONFIG_BB_PHY_REG)) | ||
810 | rtStatus = _FAIL; | ||
811 | if (rtStatus != _SUCCESS) | ||
812 | goto phy_BB8190_Config_ParaFile_Fail; | ||
813 | |||
814 | /* */ | ||
815 | /* 20100318 Joseph: Config 2T2R to 1T2R if necessary. */ | ||
816 | /* */ | ||
817 | if (pHalData->rf_type == RF_1T2R) { | ||
818 | phy_BB8192C_Config_1T(Adapter); | ||
819 | DBG_8723A("phy_BB8723a_Config_ParaFile():Config to 1T!!\n"); | ||
820 | } | ||
821 | |||
822 | /* */ | ||
823 | /* 2. If EEPROM or EFUSE autoload OK, We must config by | ||
824 | PHY_REG_PG.txt */ | ||
825 | /* */ | ||
826 | if (pEEPROM->bautoload_fail_flag == false) { | ||
827 | pHalData->pwrGroupCnt = 0; | ||
828 | |||
829 | rtStatus = phy_ConfigBBWithPgHeaderFile(Adapter, | ||
830 | BaseBand_Config_PHY_REG); | ||
831 | } | ||
832 | |||
833 | if (rtStatus != _SUCCESS) | ||
834 | goto phy_BB8190_Config_ParaFile_Fail; | ||
835 | |||
836 | /* */ | ||
837 | /* 3. BB AGC table Initialization */ | ||
838 | /* */ | ||
839 | if (HAL_STATUS_FAILURE == ODM_ConfigBBWithHeaderFile23a(&pHalData->odmpriv, | ||
840 | CONFIG_BB_AGC_TAB)) | ||
841 | rtStatus = _FAIL; | ||
842 | |||
843 | phy_BB8190_Config_ParaFile_Fail: | ||
844 | |||
845 | return rtStatus; | ||
846 | } | ||
847 | |||
848 | int | ||
849 | PHY_BBConfig8723A(struct rtw_adapter *Adapter) | ||
850 | { | ||
851 | int rtStatus = _SUCCESS; | ||
852 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
853 | u8 TmpU1B = 0; | ||
854 | u8 CrystalCap; | ||
855 | |||
856 | phy_InitBBRFRegisterDefinition(Adapter); | ||
857 | |||
858 | /* Suggested by Scott. tynli_test. 2010.12.30. */ | ||
859 | /* 1. 0x28[1] = 1 */ | ||
860 | TmpU1B = rtw_read8(Adapter, REG_AFE_PLL_CTRL); | ||
861 | udelay(2); | ||
862 | rtw_write8(Adapter, REG_AFE_PLL_CTRL, (TmpU1B|BIT1)); | ||
863 | udelay(2); | ||
864 | |||
865 | /* 2. 0x29[7:0] = 0xFF */ | ||
866 | rtw_write8(Adapter, REG_AFE_PLL_CTRL+1, 0xff); | ||
867 | udelay(2); | ||
868 | |||
869 | /* 3. 0x02[1:0] = 2b'11 */ | ||
870 | TmpU1B = rtw_read8(Adapter, REG_SYS_FUNC_EN); | ||
871 | rtw_write8(Adapter, REG_SYS_FUNC_EN, | ||
872 | (TmpU1B | FEN_BB_GLB_RSTn | FEN_BBRSTB)); | ||
873 | |||
874 | /* 4. 0x25[6] = 0 */ | ||
875 | TmpU1B = rtw_read8(Adapter, REG_AFE_XTAL_CTRL + 1); | ||
876 | rtw_write8(Adapter, REG_AFE_XTAL_CTRL+1, (TmpU1B & (~BIT6))); | ||
877 | |||
878 | /* 5. 0x24[20] = 0 Advised by SD3 Alex Wang. 2011.02.09. */ | ||
879 | TmpU1B = rtw_read8(Adapter, REG_AFE_XTAL_CTRL+2); | ||
880 | rtw_write8(Adapter, REG_AFE_XTAL_CTRL+2, (TmpU1B & (~BIT4))); | ||
881 | |||
882 | /* 6. 0x1f[7:0] = 0x07 */ | ||
883 | rtw_write8(Adapter, REG_RF_CTRL, 0x07); | ||
884 | |||
885 | /* */ | ||
886 | /* Config BB and AGC */ | ||
887 | /* */ | ||
888 | rtStatus = phy_BB8723a_Config_ParaFile(Adapter); | ||
889 | |||
890 | /* only for B-cut */ | ||
891 | if (pHalData->EEPROMVersion >= 0x01) { | ||
892 | CrystalCap = pHalData->CrystalCap & 0x3F; | ||
893 | PHY_SetBBReg(Adapter, REG_MAC_PHY_CTRL, 0xFFF000, | ||
894 | (CrystalCap | (CrystalCap << 6))); | ||
895 | } | ||
896 | |||
897 | PHY_SetBBReg(Adapter, REG_LDOA15_CTRL, bMaskDWord, 0x01572505); | ||
898 | return rtStatus; | ||
899 | } | ||
900 | |||
901 | int | ||
902 | PHY_RFConfig8723A(struct rtw_adapter *Adapter) | ||
903 | { | ||
904 | int rtStatus = _SUCCESS; | ||
905 | |||
906 | /* */ | ||
907 | /* RF config */ | ||
908 | /* */ | ||
909 | rtStatus = PHY_RF6052_Config8723A(Adapter); | ||
910 | return rtStatus; | ||
911 | } | ||
912 | |||
913 | static void getTxPowerIndex(struct rtw_adapter *Adapter, | ||
914 | u8 channel, u8 *cckPowerLevel, u8 *ofdmPowerLevel) | ||
915 | { | ||
916 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
917 | u8 index = (channel - 1); | ||
918 | /* 1. CCK */ | ||
919 | cckPowerLevel[RF_PATH_A] = pHalData->TxPwrLevelCck[RF_PATH_A][index]; | ||
920 | cckPowerLevel[RF_PATH_B] = pHalData->TxPwrLevelCck[RF_PATH_B][index]; | ||
921 | |||
922 | /* 2. OFDM for 1S or 2S */ | ||
923 | if (GET_RF_TYPE(Adapter) == RF_1T2R || GET_RF_TYPE(Adapter) == RF_1T1R) { | ||
924 | /* Read HT 40 OFDM TX power */ | ||
925 | ofdmPowerLevel[RF_PATH_A] = | ||
926 | pHalData->TxPwrLevelHT40_1S[RF_PATH_A][index]; | ||
927 | ofdmPowerLevel[RF_PATH_B] = | ||
928 | pHalData->TxPwrLevelHT40_1S[RF_PATH_B][index]; | ||
929 | } else if (GET_RF_TYPE(Adapter) == RF_2T2R) { | ||
930 | /* Read HT 40 OFDM TX power */ | ||
931 | ofdmPowerLevel[RF_PATH_A] = | ||
932 | pHalData->TxPwrLevelHT40_2S[RF_PATH_A][index]; | ||
933 | ofdmPowerLevel[RF_PATH_B] = | ||
934 | pHalData->TxPwrLevelHT40_2S[RF_PATH_B][index]; | ||
935 | } | ||
936 | } | ||
937 | |||
938 | static void ccxPowerIndexCheck(struct rtw_adapter *Adapter, u8 channel, | ||
939 | u8 *cckPowerLevel, u8 *ofdmPowerLevel) | ||
940 | { | ||
941 | } | ||
942 | |||
943 | /*----------------------------------------------------------------------------- | ||
944 | * Function: SetTxPowerLevel8723A() | ||
945 | * | ||
946 | * Overview: This function is export to "HalCommon" moudule | ||
947 | * We must consider RF path later!!!!!!! | ||
948 | * | ||
949 | * Input: struct rtw_adapter * Adapter | ||
950 | * u8 channel | ||
951 | * | ||
952 | * Output: NONE | ||
953 | * | ||
954 | * Return: NONE | ||
955 | * | ||
956 | *---------------------------------------------------------------------------*/ | ||
957 | void PHY_SetTxPowerLevel8723A(struct rtw_adapter *Adapter, u8 channel) | ||
958 | { | ||
959 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
960 | u8 cckPowerLevel[2], ofdmPowerLevel[2]; /* [0]:RF-A, [1]:RF-B */ | ||
961 | |||
962 | if (pHalData->bTXPowerDataReadFromEEPORM == false) | ||
963 | return; | ||
964 | |||
965 | getTxPowerIndex(Adapter, channel, &cckPowerLevel[0], | ||
966 | &ofdmPowerLevel[0]); | ||
967 | |||
968 | ccxPowerIndexCheck(Adapter, channel, &cckPowerLevel[0], | ||
969 | &ofdmPowerLevel[0]); | ||
970 | |||
971 | rtl823a_phy_rf6052setccktxpower(Adapter, &cckPowerLevel[0]); | ||
972 | rtl8723a_PHY_RF6052SetOFDMTxPower(Adapter, &ofdmPowerLevel[0], channel); | ||
973 | } | ||
974 | |||
975 | /*----------------------------------------------------------------------------- | ||
976 | * Function: PHY_SetBWMode23aCallback8192C() | ||
977 | * | ||
978 | * Overview: Timer callback function for SetSetBWMode23a | ||
979 | * | ||
980 | * Input: PRT_TIMER pTimer | ||
981 | * | ||
982 | * Output: NONE | ||
983 | * | ||
984 | * Return: NONE | ||
985 | * | ||
986 | * Note: | ||
987 | * (1) We do not take j mode into consideration now | ||
988 | * (2) Will two workitem of "switch channel" and | ||
989 | * "switch channel bandwidth" run concurrently? | ||
990 | *---------------------------------------------------------------------------*/ | ||
991 | static void | ||
992 | _PHY_SetBWMode23a92C(struct rtw_adapter *Adapter) | ||
993 | { | ||
994 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
995 | u8 regBwOpMode; | ||
996 | u8 regRRSR_RSC; | ||
997 | |||
998 | if (pHalData->rf_chip == RF_PSEUDO_11N) | ||
999 | return; | ||
1000 | |||
1001 | /* There is no 40MHz mode in RF_8225. */ | ||
1002 | if (pHalData->rf_chip == RF_8225) | ||
1003 | return; | ||
1004 | |||
1005 | if (Adapter->bDriverStopped) | ||
1006 | return; | ||
1007 | |||
1008 | /* 3 */ | ||
1009 | /* 3<1>Set MAC register */ | ||
1010 | /* 3 */ | ||
1011 | |||
1012 | regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE); | ||
1013 | regRRSR_RSC = rtw_read8(Adapter, REG_RRSR+2); | ||
1014 | |||
1015 | switch (pHalData->CurrentChannelBW) { | ||
1016 | case HT_CHANNEL_WIDTH_20: | ||
1017 | regBwOpMode |= BW_OPMODE_20MHZ; | ||
1018 | rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode); | ||
1019 | break; | ||
1020 | case HT_CHANNEL_WIDTH_40: | ||
1021 | regBwOpMode &= ~BW_OPMODE_20MHZ; | ||
1022 | rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode); | ||
1023 | regRRSR_RSC = (regRRSR_RSC & 0x90) | | ||
1024 | (pHalData->nCur40MhzPrimeSC << 5); | ||
1025 | rtw_write8(Adapter, REG_RRSR+2, regRRSR_RSC); | ||
1026 | break; | ||
1027 | |||
1028 | default: | ||
1029 | break; | ||
1030 | } | ||
1031 | |||
1032 | /* 3 */ | ||
1033 | /* 3<2>Set PHY related register */ | ||
1034 | /* 3 */ | ||
1035 | switch (pHalData->CurrentChannelBW) { | ||
1036 | /* 20 MHz channel*/ | ||
1037 | case HT_CHANNEL_WIDTH_20: | ||
1038 | PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x0); | ||
1039 | PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x0); | ||
1040 | PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT10, 1); | ||
1041 | |||
1042 | break; | ||
1043 | |||
1044 | /* 40 MHz channel*/ | ||
1045 | case HT_CHANNEL_WIDTH_40: | ||
1046 | PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bRFMOD, 0x1); | ||
1047 | PHY_SetBBReg(Adapter, rFPGA1_RFMOD, bRFMOD, 0x1); | ||
1048 | |||
1049 | /* Set Control channel to upper or lower. These settings | ||
1050 | are required only for 40MHz */ | ||
1051 | PHY_SetBBReg(Adapter, rCCK0_System, bCCKSideBand, | ||
1052 | (pHalData->nCur40MhzPrimeSC >> 1)); | ||
1053 | PHY_SetBBReg(Adapter, rOFDM1_LSTF, 0xC00, | ||
1054 | pHalData->nCur40MhzPrimeSC); | ||
1055 | PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, BIT10, 0); | ||
1056 | |||
1057 | PHY_SetBBReg(Adapter, 0x818, (BIT26 | BIT27), | ||
1058 | (pHalData->nCur40MhzPrimeSC == | ||
1059 | HAL_PRIME_CHNL_OFFSET_LOWER) ? 2:1); | ||
1060 | break; | ||
1061 | |||
1062 | default: | ||
1063 | /*RT_TRACE(COMP_DBG, DBG_LOUD, | ||
1064 | ("PHY_SetBWMode23aCallback8192C(): unknown Bandwidth: %#X\n" \ | ||
1065 | , pHalData->CurrentChannelBW));*/ | ||
1066 | break; | ||
1067 | } | ||
1068 | /* Skip over setting of J-mode in BB register here. Default value | ||
1069 | is "None J mode". Emily 20070315 */ | ||
1070 | |||
1071 | /* Added it for 20/40 mhz switch time evaluation by guangan 070531 */ | ||
1072 | /* NowL = PlatformEFIORead4Byte(Adapter, TSFR); */ | ||
1073 | /* NowH = PlatformEFIORead4Byte(Adapter, TSFR+4); */ | ||
1074 | /* EndTime = ((u64)NowH << 32) + NowL; */ | ||
1075 | /* RT_TRACE(COMP_SCAN, DBG_LOUD, ("SetBWMode23aCallback8190Pci: time | ||
1076 | of SetBWMode23a = %I64d us!\n", (EndTime - BeginTime))); */ | ||
1077 | |||
1078 | /* 3<3>Set RF related register */ | ||
1079 | switch (pHalData->rf_chip) { | ||
1080 | case RF_8225: | ||
1081 | /* PHY_SetRF8225Bandwidth(Adapter, | ||
1082 | pHalData->CurrentChannelBW); */ | ||
1083 | break; | ||
1084 | |||
1085 | case RF_8256: | ||
1086 | /* Please implement this function in Hal8190PciPhy8256.c */ | ||
1087 | /* PHY_SetRF8256Bandwidth(Adapter, | ||
1088 | pHalData->CurrentChannelBW); */ | ||
1089 | break; | ||
1090 | |||
1091 | case RF_8258: | ||
1092 | /* Please implement this function in Hal8190PciPhy8258.c */ | ||
1093 | /* PHY_SetRF8258Bandwidth(); */ | ||
1094 | break; | ||
1095 | |||
1096 | case RF_PSEUDO_11N: | ||
1097 | /* Do Nothing */ | ||
1098 | break; | ||
1099 | |||
1100 | case RF_6052: | ||
1101 | rtl8723a_phy_rf6052set_bw(Adapter, pHalData->CurrentChannelBW); | ||
1102 | break; | ||
1103 | |||
1104 | default: | ||
1105 | /* RT_ASSERT(false, ("Unknown RFChipID: %d\n", | ||
1106 | pHalData->RFChipID)); */ | ||
1107 | break; | ||
1108 | } | ||
1109 | |||
1110 | /* pHalData->SetBWMode23aInProgress = false; */ | ||
1111 | |||
1112 | /* RT_TRACE(COMP_SCAN, DBG_LOUD, | ||
1113 | ("<== PHY_SetBWMode23aCallback8192C() \n")); */ | ||
1114 | } | ||
1115 | |||
1116 | /*----------------------------------------------------------------------------- | ||
1117 | * Function: SetBWMode23a8190Pci() | ||
1118 | * | ||
1119 | * Overview: This function is export to "HalCommon" moudule | ||
1120 | * | ||
1121 | * Input: struct rtw_adapter * Adapter | ||
1122 | * enum ht_channel_width Bandwidth 20M or 40M | ||
1123 | * | ||
1124 | * Output: NONE | ||
1125 | * | ||
1126 | * Return: NONE | ||
1127 | * | ||
1128 | * Note: We do not take j mode into consideration now | ||
1129 | *---------------------------------------------------------------------------*/ | ||
1130 | void | ||
1131 | PHY_SetBWMode23a8723A(struct rtw_adapter *Adapter, | ||
1132 | enum ht_channel_width Bandwidth, unsigned char Offset) | ||
1133 | { | ||
1134 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1135 | enum ht_channel_width tmpBW = pHalData->CurrentChannelBW; | ||
1136 | |||
1137 | pHalData->CurrentChannelBW = Bandwidth; | ||
1138 | |||
1139 | pHalData->nCur40MhzPrimeSC = Offset; | ||
1140 | |||
1141 | if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) | ||
1142 | _PHY_SetBWMode23a92C(Adapter); | ||
1143 | else | ||
1144 | pHalData->CurrentChannelBW = tmpBW; | ||
1145 | } | ||
1146 | |||
1147 | static void _PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel) | ||
1148 | { | ||
1149 | u8 eRFPath; | ||
1150 | u32 param1, param2; | ||
1151 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1152 | |||
1153 | if (Adapter->bNotifyChannelChange) | ||
1154 | DBG_8723A("[%s] ch = %d\n", __FUNCTION__, channel); | ||
1155 | |||
1156 | /* s1. pre common command - CmdID_SetTxPowerLevel */ | ||
1157 | PHY_SetTxPowerLevel8723A(Adapter, channel); | ||
1158 | |||
1159 | /* s2. RF dependent command - CmdID_RF_WriteReg, | ||
1160 | param1 = RF_CHNLBW, param2 = channel */ | ||
1161 | param1 = RF_CHNLBW; | ||
1162 | param2 = channel; | ||
1163 | for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) { | ||
1164 | pHalData->RfRegChnlVal[eRFPath] = | ||
1165 | (pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2; | ||
1166 | PHY_SetRFReg(Adapter, (enum RF_RADIO_PATH)eRFPath, param1, | ||
1167 | bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]); | ||
1168 | } | ||
1169 | |||
1170 | /* s3. post common command - CmdID_End, None */ | ||
1171 | } | ||
1172 | |||
1173 | void PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel) | ||
1174 | { | ||
1175 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1176 | u8 tmpchannel = pHalData->CurrentChannel; | ||
1177 | bool result = true; | ||
1178 | |||
1179 | if (pHalData->rf_chip == RF_PSEUDO_11N) { | ||
1180 | /* return immediately if it is peudo-phy */ | ||
1181 | return; | ||
1182 | } | ||
1183 | |||
1184 | if (channel == 0) | ||
1185 | channel = 1; | ||
1186 | |||
1187 | pHalData->CurrentChannel = channel; | ||
1188 | |||
1189 | if ((!Adapter->bDriverStopped) && (!Adapter->bSurpriseRemoved)) { | ||
1190 | _PHY_SwChnl8723A(Adapter, channel); | ||
1191 | |||
1192 | if (!result) | ||
1193 | pHalData->CurrentChannel = tmpchannel; | ||
1194 | } else { | ||
1195 | pHalData->CurrentChannel = tmpchannel; | ||
1196 | } | ||
1197 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c b/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c new file mode 100644 index 000000000000..2a7238bacdc8 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c | |||
@@ -0,0 +1,515 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | /****************************************************************************** | ||
16 | * | ||
17 | * | ||
18 | * Module: rtl8192c_rf6052.c (Source C File) | ||
19 | * | ||
20 | * Note: Provide RF 6052 series relative API. | ||
21 | * | ||
22 | * Function: | ||
23 | * | ||
24 | * Export: | ||
25 | * | ||
26 | * Abbrev: | ||
27 | * | ||
28 | * History: | ||
29 | * Data Who Remark | ||
30 | * | ||
31 | * 09/25/2008 MHC Create initial version. | ||
32 | * 11/05/2008 MHC Add API for tw power setting. | ||
33 | * | ||
34 | * | ||
35 | ******************************************************************************/ | ||
36 | |||
37 | #define _RTL8723A_RF6052_C_ | ||
38 | |||
39 | #include <osdep_service.h> | ||
40 | #include <drv_types.h> | ||
41 | |||
42 | #include <rtl8723a_hal.h> | ||
43 | |||
44 | /*---------------------------Define Local Constant---------------------------*/ | ||
45 | /* Define local structure for debug!!!!! */ | ||
46 | struct rf_shadow_compare_map { | ||
47 | /* Shadow register value */ | ||
48 | u32 Value; | ||
49 | /* Compare or not flag */ | ||
50 | u8 Compare; | ||
51 | /* Record If it had ever modified unpredicted */ | ||
52 | u8 ErrorOrNot; | ||
53 | /* Recorver Flag */ | ||
54 | u8 Recorver; | ||
55 | /* */ | ||
56 | u8 Driver_Write; | ||
57 | }; | ||
58 | |||
59 | /*----------------------------------------------------------------------------- | ||
60 | * Function: PHY_RF6052SetBandwidth() | ||
61 | * | ||
62 | * Overview: This function is called by SetBWMode23aCallback8190Pci() only | ||
63 | * | ||
64 | * Input: struct rtw_adapter * Adapter | ||
65 | * WIRELESS_BANDWIDTH_E Bandwidth 20M or 40M | ||
66 | * | ||
67 | * Output: NONE | ||
68 | * | ||
69 | * Return: NONE | ||
70 | * | ||
71 | * Note: For RF type 0222D | ||
72 | *---------------------------------------------------------------------------*/ | ||
73 | void rtl8723a_phy_rf6052set_bw( | ||
74 | struct rtw_adapter *Adapter, | ||
75 | enum ht_channel_width Bandwidth) /* 20M or 40M */ | ||
76 | { | ||
77 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
78 | |||
79 | switch (Bandwidth) { | ||
80 | case HT_CHANNEL_WIDTH_20: | ||
81 | pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff) | 0x0400); | ||
82 | PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]); | ||
83 | break; | ||
84 | case HT_CHANNEL_WIDTH_40: | ||
85 | pHalData->RfRegChnlVal[0] = ((pHalData->RfRegChnlVal[0] & 0xfffff3ff)); | ||
86 | PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask, pHalData->RfRegChnlVal[0]); | ||
87 | break; | ||
88 | default: | ||
89 | break; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | /*----------------------------------------------------------------------------- | ||
94 | * Function: PHY_RF6052SetCckTxPower | ||
95 | * | ||
96 | * Overview: | ||
97 | * | ||
98 | * Input: NONE | ||
99 | * | ||
100 | * Output: NONE | ||
101 | * | ||
102 | * Return: NONE | ||
103 | * | ||
104 | * Revised History: | ||
105 | * When Who Remark | ||
106 | * 11/05/2008 MHC Simulate 8192series.. | ||
107 | * | ||
108 | *---------------------------------------------------------------------------*/ | ||
109 | |||
110 | void rtl823a_phy_rf6052setccktxpower(struct rtw_adapter *Adapter, u8 *pPowerlevel) | ||
111 | { | ||
112 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
113 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
114 | struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; | ||
115 | u32 TxAGC[2] = {0, 0}, tmpval = 0; | ||
116 | bool TurboScanOff = false; | ||
117 | u8 idx1, idx2; | ||
118 | u8 *ptr; | ||
119 | |||
120 | /* According to SD3 eechou's suggestion, we need to disable turbo scan for RU. */ | ||
121 | /* Otherwise, external PA will be broken if power index > 0x20. */ | ||
122 | if (pHalData->EEPROMRegulatory != 0 || pHalData->ExternalPA) | ||
123 | TurboScanOff = true; | ||
124 | |||
125 | if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { | ||
126 | TxAGC[RF_PATH_A] = 0x3f3f3f3f; | ||
127 | TxAGC[RF_PATH_B] = 0x3f3f3f3f; | ||
128 | |||
129 | TurboScanOff = true;/* disable turbo scan */ | ||
130 | |||
131 | if (TurboScanOff) { | ||
132 | for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) { | ||
133 | TxAGC[idx1] = | ||
134 | pPowerlevel[idx1] | (pPowerlevel[idx1]<<8) | | ||
135 | (pPowerlevel[idx1]<<16) | (pPowerlevel[idx1]<<24); | ||
136 | /* 2010/10/18 MH For external PA module. We need to limit power index to be less than 0x20. */ | ||
137 | if (TxAGC[idx1] > 0x20 && pHalData->ExternalPA) | ||
138 | TxAGC[idx1] = 0x20; | ||
139 | } | ||
140 | } | ||
141 | } else { | ||
142 | /* 20100427 Joseph: Driver dynamic Tx power shall not affect Tx power. It shall be determined by power training mechanism. */ | ||
143 | /* Currently, we cannot fully disable driver dynamic tx power mechanism because it is referenced by BT coexist mechanism. */ | ||
144 | /* In the future, two mechanism shall be separated from each other and maintained independantly. Thanks for Lanhsin's reminder. */ | ||
145 | if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) { | ||
146 | TxAGC[RF_PATH_A] = 0x10101010; | ||
147 | TxAGC[RF_PATH_B] = 0x10101010; | ||
148 | } else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) { | ||
149 | TxAGC[RF_PATH_A] = 0x00000000; | ||
150 | TxAGC[RF_PATH_B] = 0x00000000; | ||
151 | } else { | ||
152 | for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) { | ||
153 | TxAGC[idx1] = | ||
154 | pPowerlevel[idx1] | (pPowerlevel[idx1]<<8) | | ||
155 | (pPowerlevel[idx1]<<16) | (pPowerlevel[idx1]<<24); | ||
156 | } | ||
157 | |||
158 | if (pHalData->EEPROMRegulatory == 0) { | ||
159 | tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][6]) + | ||
160 | (pHalData->MCSTxPowerLevelOriginalOffset[0][7]<<8); | ||
161 | TxAGC[RF_PATH_A] += tmpval; | ||
162 | |||
163 | tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][14]) + | ||
164 | (pHalData->MCSTxPowerLevelOriginalOffset[0][15]<<24); | ||
165 | TxAGC[RF_PATH_B] += tmpval; | ||
166 | } | ||
167 | } | ||
168 | } | ||
169 | |||
170 | for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) { | ||
171 | ptr = (u8 *)(&TxAGC[idx1]); | ||
172 | for (idx2 = 0; idx2 < 4; idx2++) { | ||
173 | if (*ptr > RF6052_MAX_TX_PWR) | ||
174 | *ptr = RF6052_MAX_TX_PWR; | ||
175 | ptr++; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | /* rf-A cck tx power */ | ||
180 | tmpval = TxAGC[RF_PATH_A]&0xff; | ||
181 | PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, tmpval); | ||
182 | tmpval = TxAGC[RF_PATH_A]>>8; | ||
183 | PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); | ||
184 | |||
185 | /* rf-B cck tx power */ | ||
186 | tmpval = TxAGC[RF_PATH_B]>>24; | ||
187 | PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, tmpval); | ||
188 | tmpval = TxAGC[RF_PATH_B]&0x00ffffff; | ||
189 | PHY_SetBBReg(Adapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval); | ||
190 | } /* PHY_RF6052SetCckTxPower */ | ||
191 | |||
192 | /* powerbase0 for OFDM rates */ | ||
193 | /* powerbase1 for HT MCS rates */ | ||
194 | static void getPowerBase( | ||
195 | struct rtw_adapter *Adapter, | ||
196 | u8 *pPowerLevel, | ||
197 | u8 Channel, | ||
198 | u32 *OfdmBase, | ||
199 | u32 *MCSBase | ||
200 | ) | ||
201 | { | ||
202 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
203 | u32 powerBase0, powerBase1; | ||
204 | u8 Legacy_pwrdiff = 0; | ||
205 | s8 HT20_pwrdiff = 0; | ||
206 | u8 i, powerlevel[2]; | ||
207 | |||
208 | for (i = 0; i < 2; i++) { | ||
209 | powerlevel[i] = pPowerLevel[i]; | ||
210 | Legacy_pwrdiff = pHalData->TxPwrLegacyHtDiff[i][Channel-1]; | ||
211 | powerBase0 = powerlevel[i] + Legacy_pwrdiff; | ||
212 | |||
213 | powerBase0 = (powerBase0<<24) | (powerBase0<<16) | (powerBase0<<8) | powerBase0; | ||
214 | *(OfdmBase+i) = powerBase0; | ||
215 | } | ||
216 | |||
217 | for (i = 0; i < 2; i++) { | ||
218 | /* Check HT20 to HT40 diff */ | ||
219 | if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20) { | ||
220 | HT20_pwrdiff = pHalData->TxPwrHt20Diff[i][Channel-1]; | ||
221 | powerlevel[i] += HT20_pwrdiff; | ||
222 | } | ||
223 | powerBase1 = powerlevel[i]; | ||
224 | powerBase1 = (powerBase1<<24) | (powerBase1<<16) | (powerBase1<<8) | powerBase1; | ||
225 | *(MCSBase+i) = powerBase1; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | static void getTxPowerWriteValByRegulatory( | ||
230 | struct rtw_adapter *Adapter, | ||
231 | u8 Channel, | ||
232 | u8 index, | ||
233 | u32 *powerBase0, | ||
234 | u32 *powerBase1, | ||
235 | u32 *pOutWriteVal | ||
236 | ) | ||
237 | { | ||
238 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
239 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
240 | u8 i, chnlGroup = 0, pwr_diff_limit[4]; | ||
241 | u32 writeVal, customer_limit, rf; | ||
242 | |||
243 | /* Index 0 & 1 = legacy OFDM, 2-5 = HT_MCS rate */ | ||
244 | for (rf = 0; rf < 2; rf++) { | ||
245 | switch (pHalData->EEPROMRegulatory) { | ||
246 | case 0: /* Realtek better performance */ | ||
247 | /* increase power diff defined by Realtek for large power */ | ||
248 | chnlGroup = 0; | ||
249 | writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] + | ||
250 | ((index < 2) ? powerBase0[rf] : powerBase1[rf]); | ||
251 | break; | ||
252 | case 1: /* Realtek regulatory */ | ||
253 | /* increase power diff defined by Realtek for regulatory */ | ||
254 | if (pHalData->pwrGroupCnt == 1) | ||
255 | chnlGroup = 0; | ||
256 | if (pHalData->pwrGroupCnt >= 3) { | ||
257 | if (Channel <= 3) | ||
258 | chnlGroup = 0; | ||
259 | else if (Channel >= 4 && Channel <= 9) | ||
260 | chnlGroup = 1; | ||
261 | else if (Channel > 9) | ||
262 | chnlGroup = 2; | ||
263 | |||
264 | if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20) | ||
265 | chnlGroup++; | ||
266 | else | ||
267 | chnlGroup += 4; | ||
268 | } | ||
269 | writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] + | ||
270 | ((index < 2) ? powerBase0[rf] : powerBase1[rf]); | ||
271 | break; | ||
272 | case 2: /* Better regulatory */ | ||
273 | /* don't increase any power diff */ | ||
274 | writeVal = ((index < 2) ? powerBase0[rf] : powerBase1[rf]); | ||
275 | break; | ||
276 | case 3: /* Customer defined power diff. */ | ||
277 | chnlGroup = 0; | ||
278 | |||
279 | for (i = 0; i < 4; i++) { | ||
280 | pwr_diff_limit[i] = (u8)((pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index + | ||
281 | (rf ? 8 : 0)]&(0x7f << (i*8))) >> (i*8)); | ||
282 | if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_40) { | ||
283 | if (pwr_diff_limit[i] > pHalData->PwrGroupHT40[rf][Channel-1]) | ||
284 | pwr_diff_limit[i] = pHalData->PwrGroupHT40[rf][Channel-1]; | ||
285 | } else { | ||
286 | if (pwr_diff_limit[i] > pHalData->PwrGroupHT20[rf][Channel-1]) | ||
287 | pwr_diff_limit[i] = pHalData->PwrGroupHT20[rf][Channel-1]; | ||
288 | } | ||
289 | } | ||
290 | customer_limit = (pwr_diff_limit[3]<<24) | (pwr_diff_limit[2]<<16) | | ||
291 | (pwr_diff_limit[1]<<8) | (pwr_diff_limit[0]); | ||
292 | writeVal = customer_limit + ((index<2)?powerBase0[rf]:powerBase1[rf]); | ||
293 | break; | ||
294 | default: | ||
295 | chnlGroup = 0; | ||
296 | writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] + | ||
297 | ((index < 2) ? powerBase0[rf] : powerBase1[rf]); | ||
298 | break; | ||
299 | } | ||
300 | |||
301 | /* 20100427 Joseph: Driver dynamic Tx power shall not affect Tx power. It shall be determined by power training mechanism. */ | ||
302 | /* Currently, we cannot fully disable driver dynamic tx power mechanism because it is referenced by BT coexist mechanism. */ | ||
303 | /* In the future, two mechanism shall be separated from each other and maintained independantly. Thanks for Lanhsin's reminder. */ | ||
304 | |||
305 | if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) | ||
306 | writeVal = 0x14141414; | ||
307 | else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) | ||
308 | writeVal = 0x00000000; | ||
309 | |||
310 | /* 20100628 Joseph: High power mode for BT-Coexist mechanism. */ | ||
311 | /* This mechanism is only applied when Driver-Highpower-Mechanism is OFF. */ | ||
312 | if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT1) | ||
313 | writeVal = writeVal - 0x06060606; | ||
314 | else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT2) | ||
315 | writeVal = writeVal; | ||
316 | *(pOutWriteVal+rf) = writeVal; | ||
317 | } | ||
318 | } | ||
319 | |||
320 | static void writeOFDMPowerReg(struct rtw_adapter *Adapter, u8 index, u32 *pValue) | ||
321 | { | ||
322 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
323 | u16 RegOffset_A[6] = { | ||
324 | rTxAGC_A_Rate18_06, rTxAGC_A_Rate54_24, | ||
325 | rTxAGC_A_Mcs03_Mcs00, rTxAGC_A_Mcs07_Mcs04, | ||
326 | rTxAGC_A_Mcs11_Mcs08, rTxAGC_A_Mcs15_Mcs12 | ||
327 | }; | ||
328 | u16 RegOffset_B[6] = { | ||
329 | rTxAGC_B_Rate18_06, rTxAGC_B_Rate54_24, | ||
330 | rTxAGC_B_Mcs03_Mcs00, rTxAGC_B_Mcs07_Mcs04, | ||
331 | rTxAGC_B_Mcs11_Mcs08, rTxAGC_B_Mcs15_Mcs12 | ||
332 | }; | ||
333 | u8 i, rf, pwr_val[4]; | ||
334 | u32 writeVal; | ||
335 | u16 RegOffset; | ||
336 | |||
337 | for (rf = 0; rf < 2; rf++) { | ||
338 | writeVal = pValue[rf]; | ||
339 | for (i = 0; i < 4; i++) { | ||
340 | pwr_val[i] = (u8)((writeVal & (0x7f<<(i*8)))>>(i*8)); | ||
341 | if (pwr_val[i] > RF6052_MAX_TX_PWR) | ||
342 | pwr_val[i] = RF6052_MAX_TX_PWR; | ||
343 | } | ||
344 | writeVal = (pwr_val[3]<<24) | (pwr_val[2]<<16) | | ||
345 | (pwr_val[1]<<8) | pwr_val[0]; | ||
346 | |||
347 | if (rf == 0) | ||
348 | RegOffset = RegOffset_A[index]; | ||
349 | else | ||
350 | RegOffset = RegOffset_B[index]; | ||
351 | |||
352 | PHY_SetBBReg(Adapter, RegOffset, bMaskDWord, writeVal); | ||
353 | |||
354 | /* 201005115 Joseph: Set Tx Power diff for Tx power training mechanism. */ | ||
355 | if (((pHalData->rf_type == RF_2T2R) && | ||
356 | (RegOffset == rTxAGC_A_Mcs15_Mcs12 || | ||
357 | RegOffset == rTxAGC_B_Mcs15_Mcs12)) || | ||
358 | ((pHalData->rf_type != RF_2T2R) && | ||
359 | (RegOffset == rTxAGC_A_Mcs07_Mcs04 || | ||
360 | RegOffset == rTxAGC_B_Mcs07_Mcs04))) { | ||
361 | writeVal = pwr_val[3]; | ||
362 | if (RegOffset == rTxAGC_A_Mcs15_Mcs12 || RegOffset == rTxAGC_A_Mcs07_Mcs04) | ||
363 | RegOffset = 0xc90; | ||
364 | if (RegOffset == rTxAGC_B_Mcs15_Mcs12 || RegOffset == rTxAGC_B_Mcs07_Mcs04) | ||
365 | RegOffset = 0xc98; | ||
366 | for (i = 0; i < 3; i++) { | ||
367 | if (i != 2) | ||
368 | writeVal = (writeVal > 8) ? (writeVal-8) : 0; | ||
369 | else | ||
370 | writeVal = (writeVal > 6) ? (writeVal-6) : 0; | ||
371 | rtw_write8(Adapter, (u32)(RegOffset+i), (u8)writeVal); | ||
372 | } | ||
373 | } | ||
374 | } | ||
375 | } | ||
376 | /*----------------------------------------------------------------------------- | ||
377 | * Function: PHY_RF6052SetOFDMTxPower | ||
378 | * | ||
379 | * Overview: For legacy and HY OFDM, we must read EEPROM TX power index for | ||
380 | * different channel and read original value in TX power register area from | ||
381 | * 0xe00. We increase offset and original value to be correct tx pwr. | ||
382 | * | ||
383 | * Input: NONE | ||
384 | * | ||
385 | * Output: NONE | ||
386 | * | ||
387 | * Return: NONE | ||
388 | * | ||
389 | * Revised History: | ||
390 | * When Who Remark | ||
391 | * 11/05/2008 MHC Simulate 8192 series method. | ||
392 | * 01/06/2009 MHC 1. Prevent Path B tx power overflow or underflow dure to | ||
393 | * A/B pwr difference or legacy/HT pwr diff. | ||
394 | * 2. We concern with path B legacy/HT OFDM difference. | ||
395 | * 01/22/2009 MHC Support new EPRO format from SD3. | ||
396 | * | ||
397 | *---------------------------------------------------------------------------*/ | ||
398 | void rtl8723a_PHY_RF6052SetOFDMTxPower(struct rtw_adapter *Adapter, u8 *pPowerLevel, u8 Channel) | ||
399 | { | ||
400 | u32 writeVal[2], powerBase0[2], powerBase1[2]; | ||
401 | u8 index = 0; | ||
402 | |||
403 | getPowerBase(Adapter, pPowerLevel, Channel, &powerBase0[0], &powerBase1[0]); | ||
404 | |||
405 | for (index = 0; index < 6; index++) { | ||
406 | getTxPowerWriteValByRegulatory(Adapter, Channel, index, | ||
407 | &powerBase0[0], &powerBase1[0], &writeVal[0]); | ||
408 | |||
409 | writeOFDMPowerReg(Adapter, index, &writeVal[0]); | ||
410 | } | ||
411 | } | ||
412 | |||
413 | static int phy_RF6052_Config_ParaFile(struct rtw_adapter *Adapter) | ||
414 | { | ||
415 | u32 u4RegValue = 0; | ||
416 | u8 eRFPath; | ||
417 | struct bb_reg_define *pPhyReg; | ||
418 | int rtStatus = _SUCCESS; | ||
419 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
420 | static char sz8723RadioAFile[] = RTL8723_PHY_RADIO_A; | ||
421 | static char sz8723RadioBFile[] = RTL8723_PHY_RADIO_B; | ||
422 | char *pszRadioAFile, *pszRadioBFile; | ||
423 | |||
424 | pszRadioAFile = sz8723RadioAFile; | ||
425 | pszRadioBFile = sz8723RadioBFile; | ||
426 | |||
427 | /* 3----------------------------------------------------------------- */ | ||
428 | /* 3 <2> Initialize RF */ | ||
429 | /* 3----------------------------------------------------------------- */ | ||
430 | for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) { | ||
431 | |||
432 | pPhyReg = &pHalData->PHYRegDef[eRFPath]; | ||
433 | |||
434 | /*----Store original RFENV control type----*/ | ||
435 | switch (eRFPath) { | ||
436 | case RF_PATH_A: | ||
437 | case RF_PATH_C: | ||
438 | u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV); | ||
439 | break; | ||
440 | case RF_PATH_B: | ||
441 | case RF_PATH_D: | ||
442 | u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV<<16); | ||
443 | break; | ||
444 | } | ||
445 | |||
446 | /*----Set RF_ENV enable----*/ | ||
447 | PHY_SetBBReg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1); | ||
448 | udelay(1);/* PlatformStallExecution(1); */ | ||
449 | |||
450 | /*----Set RF_ENV output high----*/ | ||
451 | PHY_SetBBReg(Adapter, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); | ||
452 | udelay(1);/* PlatformStallExecution(1); */ | ||
453 | |||
454 | /* Set bit number of Address and Data for RF register */ | ||
455 | PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); /* Set 1 to 4 bits for 8255 */ | ||
456 | udelay(1);/* PlatformStallExecution(1); */ | ||
457 | |||
458 | PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); /* Set 0 to 12 bits for 8255 */ | ||
459 | udelay(1);/* PlatformStallExecution(1); */ | ||
460 | |||
461 | /*----Initialize RF fom connfiguration file----*/ | ||
462 | switch (eRFPath) { | ||
463 | case RF_PATH_A: | ||
464 | if (HAL_STATUS_FAILURE == ODM_ConfigRFWithHeaderFile23a(&pHalData->odmpriv, (enum RF_RADIO_PATH)eRFPath, (enum RF_RADIO_PATH)eRFPath)) | ||
465 | rtStatus = _FAIL; | ||
466 | break; | ||
467 | case RF_PATH_B: | ||
468 | if (HAL_STATUS_FAILURE == ODM_ConfigRFWithHeaderFile23a(&pHalData->odmpriv, (enum RF_RADIO_PATH)eRFPath, (enum RF_RADIO_PATH)eRFPath)) | ||
469 | rtStatus = _FAIL; | ||
470 | break; | ||
471 | case RF_PATH_C: | ||
472 | break; | ||
473 | case RF_PATH_D: | ||
474 | break; | ||
475 | } | ||
476 | |||
477 | /*----Restore RFENV control type----*/; | ||
478 | switch (eRFPath) { | ||
479 | case RF_PATH_A: | ||
480 | case RF_PATH_C: | ||
481 | PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); | ||
482 | break; | ||
483 | case RF_PATH_B: | ||
484 | case RF_PATH_D: | ||
485 | PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue); | ||
486 | break; | ||
487 | } | ||
488 | |||
489 | if (rtStatus != _SUCCESS) { | ||
490 | /* RT_TRACE(COMP_FPGA, DBG_LOUD, ("phy_RF6052_Config_ParaFile():Radio[%d] Fail!!", eRFPath)); */ | ||
491 | goto phy_RF6052_Config_ParaFile_Fail; | ||
492 | } | ||
493 | } | ||
494 | phy_RF6052_Config_ParaFile_Fail: | ||
495 | return rtStatus; | ||
496 | } | ||
497 | |||
498 | int PHY_RF6052_Config8723A(struct rtw_adapter *Adapter) | ||
499 | { | ||
500 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
501 | int rtStatus = _SUCCESS; | ||
502 | |||
503 | /* Initialize general global value */ | ||
504 | /* TODO: Extend RF_PATH_C and RF_PATH_D in the future */ | ||
505 | if (pHalData->rf_type == RF_1T1R) | ||
506 | pHalData->NumTotalRFPath = 1; | ||
507 | else | ||
508 | pHalData->NumTotalRFPath = 2; | ||
509 | |||
510 | /* Config BB and RF */ | ||
511 | rtStatus = phy_RF6052_Config_ParaFile(Adapter); | ||
512 | return rtStatus; | ||
513 | } | ||
514 | |||
515 | /* End of HalRf6052.c */ | ||
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_rxdesc.c b/drivers/staging/rtl8723au/hal/rtl8723a_rxdesc.c new file mode 100644 index 000000000000..81b5efe649fa --- /dev/null +++ b/drivers/staging/rtl8723au/hal/rtl8723a_rxdesc.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | #define _RTL8723A_REDESC_C_ | ||
16 | |||
17 | #include <osdep_service.h> | ||
18 | #include <drv_types.h> | ||
19 | #include <rtl8723a_hal.h> | ||
20 | |||
21 | static void process_rssi(struct rtw_adapter *padapter, | ||
22 | struct recv_frame *prframe) | ||
23 | { | ||
24 | struct rx_pkt_attrib *pattrib = &prframe->attrib; | ||
25 | struct signal_stat *signal_stat = &padapter->recvpriv.signal_strength_data; | ||
26 | |||
27 | if (signal_stat->update_req) { | ||
28 | signal_stat->total_num = 0; | ||
29 | signal_stat->total_val = 0; | ||
30 | signal_stat->update_req = 0; | ||
31 | } | ||
32 | |||
33 | signal_stat->total_num++; | ||
34 | signal_stat->total_val += pattrib->phy_info.SignalStrength; | ||
35 | signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num; | ||
36 | } | ||
37 | |||
38 | static void process_link_qual(struct rtw_adapter *padapter, | ||
39 | struct recv_frame *prframe) | ||
40 | { | ||
41 | struct rx_pkt_attrib *pattrib; | ||
42 | struct signal_stat *signal_stat; | ||
43 | |||
44 | if (prframe == NULL || padapter == NULL) | ||
45 | return; | ||
46 | |||
47 | pattrib = &prframe->attrib; | ||
48 | signal_stat = &padapter->recvpriv.signal_qual_data; | ||
49 | |||
50 | if (signal_stat->update_req) { | ||
51 | signal_stat->total_num = 0; | ||
52 | signal_stat->total_val = 0; | ||
53 | signal_stat->update_req = 0; | ||
54 | } | ||
55 | |||
56 | signal_stat->total_num++; | ||
57 | signal_stat->total_val += pattrib->phy_info.SignalQuality; | ||
58 | signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num; | ||
59 | } | ||
60 | |||
61 | /* void rtl8723a_process_phy_info(struct rtw_adapter *padapter, union recv_frame *prframe) */ | ||
62 | void rtl8723a_process_phy_info(struct rtw_adapter *padapter, void *prframe) | ||
63 | { | ||
64 | struct recv_frame *precvframe = prframe; | ||
65 | /* Check RSSI */ | ||
66 | process_rssi(padapter, precvframe); | ||
67 | /* Check EVM */ | ||
68 | process_link_qual(padapter, precvframe); | ||
69 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_sreset.c b/drivers/staging/rtl8723au/hal/rtl8723a_sreset.c new file mode 100644 index 000000000000..c0218e734b9e --- /dev/null +++ b/drivers/staging/rtl8723au/hal/rtl8723a_sreset.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | #define _RTL8723A_SRESET_C_ | ||
16 | |||
17 | #include <rtl8723a_sreset.h> | ||
18 | #include <rtl8723a_hal.h> | ||
19 | |||
20 | void rtl8723a_sreset_xmit_status_check(struct rtw_adapter *padapter) | ||
21 | { | ||
22 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
23 | struct sreset_priv *psrtpriv = &pHalData->srestpriv; | ||
24 | |||
25 | unsigned long current_time; | ||
26 | struct xmit_priv *pxmitpriv = &padapter->xmitpriv; | ||
27 | unsigned int diff_time; | ||
28 | u32 txdma_status; | ||
29 | |||
30 | txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS); | ||
31 | if (txdma_status != 0) { | ||
32 | DBG_8723A("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status); | ||
33 | rtw_hal_sreset_reset23a(padapter); | ||
34 | } | ||
35 | |||
36 | current_time = jiffies; | ||
37 | |||
38 | if (0 == pxmitpriv->free_xmitbuf_cnt || 0 == pxmitpriv->free_xmit_extbuf_cnt) { | ||
39 | |||
40 | diff_time = jiffies_to_msecs(jiffies - psrtpriv->last_tx_time); | ||
41 | |||
42 | if (diff_time > 2000) { | ||
43 | if (psrtpriv->last_tx_complete_time == 0) { | ||
44 | psrtpriv->last_tx_complete_time = current_time; | ||
45 | } else { | ||
46 | diff_time = jiffies_to_msecs(jiffies - psrtpriv->last_tx_complete_time); | ||
47 | if (diff_time > 4000) { | ||
48 | /* padapter->Wifi_Error_Status = WIFI_TX_HANG; */ | ||
49 | DBG_8723A("%s tx hang\n", __func__); | ||
50 | rtw_hal_sreset_reset23a(padapter); | ||
51 | } | ||
52 | } | ||
53 | } | ||
54 | } | ||
55 | |||
56 | if (psrtpriv->dbg_trigger_point == SRESET_TGP_XMIT_STATUS) { | ||
57 | psrtpriv->dbg_trigger_point = SRESET_TGP_NULL; | ||
58 | rtw_hal_sreset_reset23a(padapter); | ||
59 | return; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | void rtl8723a_sreset_linked_status_check(struct rtw_adapter *padapter) | ||
64 | { | ||
65 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
66 | struct sreset_priv *psrtpriv = &pHalData->srestpriv; | ||
67 | |||
68 | if (psrtpriv->dbg_trigger_point == SRESET_TGP_LINK_STATUS) { | ||
69 | psrtpriv->dbg_trigger_point = SRESET_TGP_NULL; | ||
70 | rtw_hal_sreset_reset23a(padapter); | ||
71 | return; | ||
72 | } | ||
73 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_xmit.c b/drivers/staging/rtl8723au/hal/rtl8723a_xmit.c new file mode 100644 index 000000000000..d7612ccc47e9 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/rtl8723a_xmit.c | |||
@@ -0,0 +1,52 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | #define _RTL8723A_XMIT_C_ | ||
16 | |||
17 | #include <osdep_service.h> | ||
18 | #include <drv_types.h> | ||
19 | #include <rtl8723a_hal.h> | ||
20 | |||
21 | void dump_txrpt_ccx_8723a(void *buf) | ||
22 | { | ||
23 | struct txrpt_ccx_8723a *txrpt_ccx = buf; | ||
24 | |||
25 | DBG_8723A("%s:\n" | ||
26 | "tag1:%u, rsvd:%u, int_bt:%u, int_tri:%u, int_ccx:%u\n" | ||
27 | "mac_id:%u, pkt_drop:%u, pkt_ok:%u, bmc:%u\n" | ||
28 | "retry_cnt:%u, lifetime_over:%u, retry_over:%u\n" | ||
29 | "ccx_qtime:%u\n" | ||
30 | "final_data_rate:0x%02x\n" | ||
31 | "qsel:%u, sw:0x%03x\n" | ||
32 | , __func__ | ||
33 | , txrpt_ccx->tag1, txrpt_ccx->rsvd, txrpt_ccx->int_bt, txrpt_ccx->int_tri, txrpt_ccx->int_ccx | ||
34 | , txrpt_ccx->mac_id, txrpt_ccx->pkt_drop, txrpt_ccx->pkt_ok, txrpt_ccx->bmc | ||
35 | , txrpt_ccx->retry_cnt, txrpt_ccx->lifetime_over, txrpt_ccx->retry_over | ||
36 | , txrpt_ccx_qtime_8723a(txrpt_ccx) | ||
37 | , txrpt_ccx->final_data_rate | ||
38 | , txrpt_ccx->qsel, txrpt_ccx_sw_8723a(txrpt_ccx) | ||
39 | ); | ||
40 | } | ||
41 | |||
42 | void handle_txrpt_ccx_8723a(struct rtw_adapter *adapter, void *buf) | ||
43 | { | ||
44 | struct txrpt_ccx_8723a *txrpt_ccx = buf; | ||
45 | |||
46 | if (txrpt_ccx->int_ccx) { | ||
47 | if (txrpt_ccx->pkt_ok) | ||
48 | rtw_ack_tx_done23a(&adapter->xmitpriv, RTW_SCTX_DONE_SUCCESS); | ||
49 | else | ||
50 | rtw_ack_tx_done23a(&adapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL); | ||
51 | } | ||
52 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/rtl8723au_led.c b/drivers/staging/rtl8723au/hal/rtl8723au_led.c new file mode 100644 index 000000000000..4d5c909487f8 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/rtl8723au_led.c | |||
@@ -0,0 +1,113 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | #include "drv_types.h" | ||
17 | #include "rtl8723a_hal.h" | ||
18 | #include "rtl8723a_led.h" | ||
19 | |||
20 | /* */ | ||
21 | /* LED object. */ | ||
22 | /* */ | ||
23 | |||
24 | /* */ | ||
25 | /* Prototype of protected function. */ | ||
26 | /* */ | ||
27 | |||
28 | /* */ | ||
29 | /* LED_819xUsb routines. */ | ||
30 | /* */ | ||
31 | |||
32 | /* Description: */ | ||
33 | /* Turn on LED according to LedPin specified. */ | ||
34 | void SwLedOn23a(struct rtw_adapter *padapter, struct led_8723a *pLed) | ||
35 | { | ||
36 | u8 LedCfg = 0; | ||
37 | |||
38 | if ((padapter->bSurpriseRemoved == true) || (padapter->bDriverStopped == true)) | ||
39 | return; | ||
40 | switch (pLed->LedPin) { | ||
41 | case LED_PIN_GPIO0: | ||
42 | break; | ||
43 | case LED_PIN_LED0: | ||
44 | rtw_write8(padapter, REG_LEDCFG0, (LedCfg&0xf0)|BIT5|BIT6); /* SW control led0 on. */ | ||
45 | break; | ||
46 | case LED_PIN_LED1: | ||
47 | rtw_write8(padapter, REG_LEDCFG1, (LedCfg&0x00)|BIT6); /* SW control led1 on. */ | ||
48 | break; | ||
49 | case LED_PIN_LED2: | ||
50 | LedCfg = rtw_read8(padapter, REG_LEDCFG2); | ||
51 | rtw_write8(padapter, REG_LEDCFG2, (LedCfg&0x80)|BIT5); /* SW control led1 on. */ | ||
52 | break; | ||
53 | default: | ||
54 | break; | ||
55 | } | ||
56 | pLed->bLedOn = true; | ||
57 | } | ||
58 | |||
59 | /* Description: */ | ||
60 | /* Turn off LED according to LedPin specified. */ | ||
61 | void SwLedOff23a(struct rtw_adapter *padapter, struct led_8723a *pLed) | ||
62 | { | ||
63 | u8 LedCfg = 0; | ||
64 | /* struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); */ | ||
65 | |||
66 | if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped)) | ||
67 | goto exit; | ||
68 | |||
69 | switch (pLed->LedPin) { | ||
70 | case LED_PIN_GPIO0: | ||
71 | break; | ||
72 | case LED_PIN_LED0: | ||
73 | rtw_write8(padapter, REG_LEDCFG0, (LedCfg&0xf0)|BIT5|BIT6); /* SW control led0 on. */ | ||
74 | break; | ||
75 | case LED_PIN_LED1: | ||
76 | rtw_write8(padapter, REG_LEDCFG1, (LedCfg&0x00)|BIT5|BIT6); /* SW control led1 on. */ | ||
77 | break; | ||
78 | case LED_PIN_LED2: | ||
79 | LedCfg = rtw_read8(padapter, REG_LEDCFG2); | ||
80 | rtw_write8(padapter, REG_LEDCFG2, (LedCfg&0x80)|BIT3|BIT5); /* SW control led1 on. */ | ||
81 | break; | ||
82 | default: | ||
83 | break; | ||
84 | } | ||
85 | exit: | ||
86 | pLed->bLedOn = false; | ||
87 | } | ||
88 | |||
89 | /* Interface to manipulate LED objects. */ | ||
90 | |||
91 | /* Description: */ | ||
92 | /* Initialize all LED_871x objects. */ | ||
93 | void | ||
94 | rtl8723au_InitSwLeds(struct rtw_adapter *padapter) | ||
95 | { | ||
96 | struct led_priv *pledpriv = &padapter->ledpriv; | ||
97 | |||
98 | pledpriv->LedControlHandler = LedControl871x23a; | ||
99 | /* 8723as-vau wifi used led2 */ | ||
100 | InitLed871x23a(padapter, &pledpriv->SwLed0, LED_PIN_LED2); | ||
101 | |||
102 | /* InitLed871x23a(padapter,&pledpriv->SwLed1, LED_PIN_LED2); */ | ||
103 | } | ||
104 | |||
105 | /* Description: */ | ||
106 | /* DeInitialize all LED_819xUsb objects. */ | ||
107 | void | ||
108 | rtl8723au_DeInitSwLeds(struct rtw_adapter *padapter) | ||
109 | { | ||
110 | struct led_priv *ledpriv = &padapter->ledpriv; | ||
111 | |||
112 | DeInitLed871x23a(&ledpriv->SwLed0); | ||
113 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/rtl8723au_recv.c b/drivers/staging/rtl8723au/hal/rtl8723au_recv.c new file mode 100644 index 000000000000..213d1936109d --- /dev/null +++ b/drivers/staging/rtl8723au/hal/rtl8723au_recv.c | |||
@@ -0,0 +1,247 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | #define _RTL8192CU_RECV_C_ | ||
16 | #include <osdep_service.h> | ||
17 | #include <drv_types.h> | ||
18 | #include <recv_osdep.h> | ||
19 | #include <mlme_osdep.h> | ||
20 | #include <linux/ip.h> | ||
21 | #include <linux/if_ether.h> | ||
22 | #include <ethernet.h> | ||
23 | #include <usb_ops.h> | ||
24 | #include <wifi.h> | ||
25 | #include <rtl8723a_hal.h> | ||
26 | |||
27 | void rtl8723au_init_recvbuf(struct rtw_adapter *padapter, | ||
28 | struct recv_buf *precvbuf) | ||
29 | { | ||
30 | } | ||
31 | |||
32 | int rtl8723au_init_recv_priv(struct rtw_adapter *padapter) | ||
33 | { | ||
34 | struct recv_priv *precvpriv = &padapter->recvpriv; | ||
35 | int i, size, res = _SUCCESS; | ||
36 | struct recv_buf *precvbuf; | ||
37 | unsigned long tmpaddr; | ||
38 | unsigned long alignment; | ||
39 | struct sk_buff *pskb; | ||
40 | |||
41 | tasklet_init(&precvpriv->recv_tasklet, | ||
42 | (void(*)(unsigned long))rtl8723au_recv_tasklet, | ||
43 | (unsigned long)padapter); | ||
44 | |||
45 | precvpriv->int_in_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
46 | if (!precvpriv->int_in_urb) | ||
47 | DBG_8723A("alloc_urb for interrupt in endpoint fail !!!!\n"); | ||
48 | precvpriv->int_in_buf = kzalloc(USB_INTR_CONTENT_LENGTH, GFP_KERNEL); | ||
49 | if (!precvpriv->int_in_buf) | ||
50 | DBG_8723A("alloc_mem for interrupt in endpoint fail !!!!\n"); | ||
51 | |||
52 | /* init recv_buf */ | ||
53 | _rtw_init_queue23a(&precvpriv->free_recv_buf_queue); | ||
54 | |||
55 | size = NR_RECVBUFF * sizeof(struct recv_buf); | ||
56 | precvpriv->precv_buf = kzalloc(size, GFP_KERNEL); | ||
57 | if (!precvpriv->precv_buf) { | ||
58 | res = _FAIL; | ||
59 | RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, | ||
60 | ("alloc recv_buf fail!\n")); | ||
61 | goto exit; | ||
62 | } | ||
63 | |||
64 | precvbuf = (struct recv_buf *)precvpriv->precv_buf; | ||
65 | |||
66 | for (i = 0; i < NR_RECVBUFF; i++) { | ||
67 | INIT_LIST_HEAD(&precvbuf->list); | ||
68 | |||
69 | res = rtw_os_recvbuf_resource_alloc23a(padapter, precvbuf); | ||
70 | if (res == _FAIL) | ||
71 | break; | ||
72 | |||
73 | precvbuf->adapter = padapter; | ||
74 | |||
75 | precvbuf++; | ||
76 | } | ||
77 | |||
78 | precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF; | ||
79 | |||
80 | skb_queue_head_init(&precvpriv->rx_skb_queue); | ||
81 | skb_queue_head_init(&precvpriv->free_recv_skb_queue); | ||
82 | |||
83 | for (i = 0; i < NR_PREALLOC_RECV_SKB; i++) { | ||
84 | size = MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ; | ||
85 | pskb = __netdev_alloc_skb(padapter->pnetdev, size, GFP_KERNEL); | ||
86 | |||
87 | if (pskb) { | ||
88 | pskb->dev = padapter->pnetdev; | ||
89 | |||
90 | tmpaddr = (unsigned long)pskb->data; | ||
91 | alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); | ||
92 | skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment)); | ||
93 | |||
94 | skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); | ||
95 | } | ||
96 | |||
97 | pskb = NULL; | ||
98 | } | ||
99 | |||
100 | exit: | ||
101 | return res; | ||
102 | } | ||
103 | |||
104 | void rtl8723au_free_recv_priv(struct rtw_adapter *padapter) | ||
105 | { | ||
106 | int i; | ||
107 | struct recv_buf *precvbuf; | ||
108 | struct recv_priv *precvpriv = &padapter->recvpriv; | ||
109 | |||
110 | precvbuf = (struct recv_buf *)precvpriv->precv_buf; | ||
111 | |||
112 | for (i = 0; i < NR_RECVBUFF; i++) { | ||
113 | rtw_os_recvbuf_resource_free23a(padapter, precvbuf); | ||
114 | precvbuf++; | ||
115 | } | ||
116 | |||
117 | kfree(precvpriv->precv_buf); | ||
118 | |||
119 | usb_free_urb(precvpriv->int_in_urb); | ||
120 | kfree(precvpriv->int_in_buf); | ||
121 | |||
122 | if (skb_queue_len(&precvpriv->rx_skb_queue)) | ||
123 | DBG_8723A(KERN_WARNING "rx_skb_queue not empty\n"); | ||
124 | |||
125 | skb_queue_purge(&precvpriv->rx_skb_queue); | ||
126 | |||
127 | if (skb_queue_len(&precvpriv->free_recv_skb_queue)) { | ||
128 | DBG_8723A(KERN_WARNING "free_recv_skb_queue not empty, %d\n", | ||
129 | skb_queue_len(&precvpriv->free_recv_skb_queue)); | ||
130 | } | ||
131 | |||
132 | skb_queue_purge(&precvpriv->free_recv_skb_queue); | ||
133 | } | ||
134 | |||
135 | void update_recvframe_attrib(struct recv_frame *precvframe, | ||
136 | struct recv_stat *prxstat) | ||
137 | { | ||
138 | struct rx_pkt_attrib *pattrib; | ||
139 | struct recv_stat report; | ||
140 | struct rxreport_8723a *prxreport; | ||
141 | |||
142 | report.rxdw0 = le32_to_cpu(prxstat->rxdw0); | ||
143 | report.rxdw1 = le32_to_cpu(prxstat->rxdw1); | ||
144 | report.rxdw2 = le32_to_cpu(prxstat->rxdw2); | ||
145 | report.rxdw3 = le32_to_cpu(prxstat->rxdw3); | ||
146 | report.rxdw4 = le32_to_cpu(prxstat->rxdw4); | ||
147 | report.rxdw5 = le32_to_cpu(prxstat->rxdw5); | ||
148 | |||
149 | prxreport = (struct rxreport_8723a *)&report; | ||
150 | |||
151 | pattrib = &precvframe->attrib; | ||
152 | memset(pattrib, 0, sizeof(struct rx_pkt_attrib)); | ||
153 | |||
154 | /* update rx report to recv_frame attribute */ | ||
155 | pattrib->pkt_len = (u16)prxreport->pktlen; | ||
156 | pattrib->drvinfo_sz = (u8)(prxreport->drvinfosize << 3); | ||
157 | pattrib->physt = (u8)prxreport->physt; | ||
158 | |||
159 | pattrib->crc_err = (u8)prxreport->crc32; | ||
160 | pattrib->icv_err = (u8)prxreport->icverr; | ||
161 | |||
162 | pattrib->bdecrypted = (u8)(prxreport->swdec ? 0 : 1); | ||
163 | pattrib->encrypt = (u8)prxreport->security; | ||
164 | |||
165 | pattrib->qos = (u8)prxreport->qos; | ||
166 | pattrib->priority = (u8)prxreport->tid; | ||
167 | |||
168 | pattrib->amsdu = (u8)prxreport->amsdu; | ||
169 | |||
170 | pattrib->seq_num = (u16)prxreport->seq; | ||
171 | pattrib->frag_num = (u8)prxreport->frag; | ||
172 | pattrib->mfrag = (u8)prxreport->mf; | ||
173 | pattrib->mdata = (u8)prxreport->md; | ||
174 | |||
175 | pattrib->mcs_rate = (u8)prxreport->rxmcs; | ||
176 | pattrib->rxht = (u8)prxreport->rxht; | ||
177 | } | ||
178 | |||
179 | void update_recvframe_phyinfo(struct recv_frame *precvframe, | ||
180 | struct phy_stat *pphy_status) | ||
181 | { | ||
182 | struct rtw_adapter *padapter = precvframe->adapter; | ||
183 | struct rx_pkt_attrib *pattrib = &precvframe->attrib; | ||
184 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
185 | struct odm_phy_info *pPHYInfo = (struct odm_phy_info *)(&pattrib->phy_info); | ||
186 | struct odm_packet_info pkt_info; | ||
187 | u8 *sa = NULL, *da; | ||
188 | struct sta_priv *pstapriv; | ||
189 | struct sta_info *psta; | ||
190 | struct sk_buff *skb = precvframe->pkt; | ||
191 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
192 | u8 *wlanhdr = skb->data; | ||
193 | |||
194 | pkt_info.bPacketMatchBSSID = false; | ||
195 | pkt_info.bPacketToSelf = false; | ||
196 | pkt_info.bPacketBeacon = false; | ||
197 | |||
198 | pkt_info.bPacketMatchBSSID = | ||
199 | (!ieee80211_is_ctl(hdr->frame_control) && | ||
200 | !pattrib->icv_err && | ||
201 | !pattrib->crc_err && | ||
202 | !memcmp(get_hdr_bssid(wlanhdr), | ||
203 | get_bssid(&padapter->mlmepriv), ETH_ALEN)); | ||
204 | |||
205 | da = ieee80211_get_DA(hdr); | ||
206 | pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && | ||
207 | (!memcmp(da, myid(&padapter->eeprompriv), ETH_ALEN)); | ||
208 | |||
209 | pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && | ||
210 | ieee80211_is_beacon(hdr->frame_control); | ||
211 | |||
212 | pkt_info.StationID = 0xFF; | ||
213 | if (pkt_info.bPacketBeacon) { | ||
214 | if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == true) | ||
215 | sa = padapter->mlmepriv.cur_network.network.MacAddress; | ||
216 | /* to do Ad-hoc */ | ||
217 | } else { | ||
218 | sa = ieee80211_get_SA(hdr); | ||
219 | } | ||
220 | |||
221 | pstapriv = &padapter->stapriv; | ||
222 | psta = rtw_get_stainfo23a(pstapriv, sa); | ||
223 | if (psta) { | ||
224 | pkt_info.StationID = psta->mac_id; | ||
225 | /* printk("%s ==> StationID(%d)\n", __FUNCTION__, pkt_info.StationID); */ | ||
226 | } | ||
227 | pkt_info.Rate = pattrib->mcs_rate; | ||
228 | |||
229 | ODM_PhyStatusQuery23a(&pHalData->odmpriv, pPHYInfo, | ||
230 | (u8 *)pphy_status, &pkt_info); | ||
231 | precvframe->psta = NULL; | ||
232 | if (pkt_info.bPacketMatchBSSID && | ||
233 | (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true)) { | ||
234 | if (psta) { | ||
235 | precvframe->psta = psta; | ||
236 | rtl8723a_process_phy_info(padapter, precvframe); | ||
237 | } | ||
238 | } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) { | ||
239 | if (check_fwstate(&padapter->mlmepriv, | ||
240 | WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == | ||
241 | true) { | ||
242 | if (psta) | ||
243 | precvframe->psta = psta; | ||
244 | } | ||
245 | rtl8723a_process_phy_info(padapter, precvframe); | ||
246 | } | ||
247 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c b/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c new file mode 100644 index 000000000000..3165ff5dfa73 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c | |||
@@ -0,0 +1,548 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | #define _RTL8192C_XMIT_C_ | ||
16 | #include <osdep_service.h> | ||
17 | #include <drv_types.h> | ||
18 | #include <wifi.h> | ||
19 | #include <osdep_intf.h> | ||
20 | #include <usb_ops.h> | ||
21 | /* include <rtl8192c_hal.h> */ | ||
22 | #include <rtl8723a_hal.h> | ||
23 | |||
24 | s32 rtl8723au_init_xmit_priv(struct rtw_adapter *padapter) | ||
25 | { | ||
26 | struct xmit_priv *pxmitpriv = &padapter->xmitpriv; | ||
27 | |||
28 | tasklet_init(&pxmitpriv->xmit_tasklet, | ||
29 | (void(*)(unsigned long))rtl8723au_xmit_tasklet, | ||
30 | (unsigned long)padapter); | ||
31 | return _SUCCESS; | ||
32 | } | ||
33 | |||
34 | void rtl8723au_free_xmit_priv(struct rtw_adapter *padapter) | ||
35 | { | ||
36 | } | ||
37 | |||
38 | static void do_queue_select(struct rtw_adapter *padapter, struct pkt_attrib *pattrib) | ||
39 | { | ||
40 | u8 qsel; | ||
41 | |||
42 | qsel = pattrib->priority; | ||
43 | RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, | ||
44 | ("### do_queue_select priority =%d , qsel = %d\n", | ||
45 | pattrib->priority, qsel)); | ||
46 | |||
47 | pattrib->qsel = qsel; | ||
48 | } | ||
49 | |||
50 | static int urb_zero_packet_chk(struct rtw_adapter *padapter, int sz) | ||
51 | { | ||
52 | int blnSetTxDescOffset; | ||
53 | struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); | ||
54 | |||
55 | if (pdvobj->ishighspeed) { | ||
56 | if (((sz + TXDESC_SIZE) % 512) == 0) | ||
57 | blnSetTxDescOffset = 1; | ||
58 | else | ||
59 | blnSetTxDescOffset = 0; | ||
60 | } else { | ||
61 | if (((sz + TXDESC_SIZE) % 64) == 0) | ||
62 | blnSetTxDescOffset = 1; | ||
63 | else | ||
64 | blnSetTxDescOffset = 0; | ||
65 | } | ||
66 | return blnSetTxDescOffset; | ||
67 | } | ||
68 | |||
69 | static void rtl8192cu_cal_txdesc_chksum(struct tx_desc *ptxdesc) | ||
70 | { | ||
71 | u16 *usPtr = (u16 *)ptxdesc; | ||
72 | u32 count = 16; /* (32 bytes / 2 bytes per XOR) => 16 times */ | ||
73 | u32 index; | ||
74 | u16 checksum = 0; | ||
75 | |||
76 | /* Clear first */ | ||
77 | ptxdesc->txdw7 &= cpu_to_le32(0xffff0000); | ||
78 | |||
79 | for (index = 0 ; index < count ; index++) | ||
80 | checksum = checksum ^ le16_to_cpu(*(usPtr + index)); | ||
81 | |||
82 | ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff&checksum); | ||
83 | } | ||
84 | |||
85 | static void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc) | ||
86 | { | ||
87 | if ((pattrib->encrypt > 0) && !pattrib->bswenc) { | ||
88 | switch (pattrib->encrypt) { | ||
89 | /* SEC_TYPE */ | ||
90 | case _WEP40_: | ||
91 | case _WEP104_: | ||
92 | ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000); | ||
93 | break; | ||
94 | case _TKIP_: | ||
95 | case _TKIP_WTMIC_: | ||
96 | /* ptxdesc->txdw1 |= cpu_to_le32((0x02<<22)&0x00c00000); */ | ||
97 | ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000); | ||
98 | break; | ||
99 | case _AES_: | ||
100 | ptxdesc->txdw1 |= cpu_to_le32((0x03<<22)&0x00c00000); | ||
101 | break; | ||
102 | case _NO_PRIVACY_: | ||
103 | default: | ||
104 | break; | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | |||
109 | static void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw) | ||
110 | { | ||
111 | /* DBG_8723A("cvs_mode =%d\n", pattrib->vcs_mode); */ | ||
112 | |||
113 | switch (pattrib->vcs_mode) { | ||
114 | case RTS_CTS: | ||
115 | *pdw |= cpu_to_le32(BIT(12)); | ||
116 | break; | ||
117 | case CTS_TO_SELF: | ||
118 | *pdw |= cpu_to_le32(BIT(11)); | ||
119 | break; | ||
120 | case NONE_VCS: | ||
121 | default: | ||
122 | break; | ||
123 | } | ||
124 | |||
125 | if (pattrib->vcs_mode) { | ||
126 | *pdw |= cpu_to_le32(BIT(13)); | ||
127 | |||
128 | /* Set RTS BW */ | ||
129 | if (pattrib->ht_en) { | ||
130 | *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(27)) : 0; | ||
131 | |||
132 | if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) | ||
133 | *pdw |= cpu_to_le32((0x01<<28)&0x30000000); | ||
134 | else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) | ||
135 | *pdw |= cpu_to_le32((0x02<<28)&0x30000000); | ||
136 | else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) | ||
137 | *pdw |= 0; | ||
138 | else | ||
139 | *pdw |= cpu_to_le32((0x03<<28)&0x30000000); | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | |||
144 | static void fill_txdesc_phy(struct pkt_attrib *pattrib, u32 *pdw) | ||
145 | { | ||
146 | if (pattrib->ht_en) { | ||
147 | *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(25)) : 0; | ||
148 | |||
149 | if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER) | ||
150 | *pdw |= cpu_to_le32((0x01<<20)&0x003f0000); | ||
151 | else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER) | ||
152 | *pdw |= cpu_to_le32((0x02<<20)&0x003f0000); | ||
153 | else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) | ||
154 | *pdw |= 0; | ||
155 | else | ||
156 | *pdw |= cpu_to_le32((0x03<<20)&0x003f0000); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt) | ||
161 | { | ||
162 | int pull = 0; | ||
163 | uint qsel; | ||
164 | struct rtw_adapter *padapter = pxmitframe->padapter; | ||
165 | struct pkt_attrib *pattrib = &pxmitframe->attrib; | ||
166 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
167 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
168 | struct tx_desc *ptxdesc = (struct tx_desc *)pmem; | ||
169 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; | ||
170 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; | ||
171 | int bmcst = is_multicast_ether_addr(pattrib->ra); | ||
172 | |||
173 | if ((!bagg_pkt) && (urb_zero_packet_chk(padapter, sz) == 0)) { | ||
174 | ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ); | ||
175 | pull = 1; | ||
176 | pxmitframe->pkt_offset--; | ||
177 | } | ||
178 | |||
179 | memset(ptxdesc, 0, sizeof(struct tx_desc)); | ||
180 | |||
181 | if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) { | ||
182 | /* offset 4 */ | ||
183 | ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f); | ||
184 | |||
185 | qsel = (uint)(pattrib->qsel & 0x0000001f); | ||
186 | ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); | ||
187 | |||
188 | ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<<16) & 0x000f0000); | ||
189 | |||
190 | fill_txdesc_sectype(pattrib, ptxdesc); | ||
191 | |||
192 | if (pattrib->ampdu_en) | ||
193 | ptxdesc->txdw1 |= cpu_to_le32(BIT(5));/* AGG EN */ | ||
194 | else | ||
195 | ptxdesc->txdw1 |= cpu_to_le32(BIT(6));/* AGG BK */ | ||
196 | |||
197 | /* offset 8 */ | ||
198 | |||
199 | /* offset 12 */ | ||
200 | ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000); | ||
201 | |||
202 | /* offset 16 , offset 20 */ | ||
203 | if (pattrib->qos_en) | ||
204 | ptxdesc->txdw4 |= cpu_to_le32(BIT(6));/* QoS */ | ||
205 | |||
206 | if ((pattrib->ether_type != 0x888e) && | ||
207 | (pattrib->ether_type != 0x0806) && | ||
208 | (pattrib->dhcp_pkt != 1)) { | ||
209 | /* Non EAP & ARP & DHCP type data packet */ | ||
210 | |||
211 | fill_txdesc_vcs(pattrib, &ptxdesc->txdw4); | ||
212 | fill_txdesc_phy(pattrib, &ptxdesc->txdw4); | ||
213 | |||
214 | ptxdesc->txdw4 |= cpu_to_le32(0x00000008);/* RTS Rate = 24M */ | ||
215 | ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);/* */ | ||
216 | |||
217 | /* use REG_INIDATA_RATE_SEL value */ | ||
218 | ptxdesc->txdw5 |= cpu_to_le32(pdmpriv->INIDATA_RATE[pattrib->mac_id]); | ||
219 | } else { | ||
220 | /* EAP data packet and ARP packet. */ | ||
221 | /* Use the 1M data rate to send the EAP/ARP packet. */ | ||
222 | /* This will maybe make the handshake smooth. */ | ||
223 | |||
224 | ptxdesc->txdw1 |= cpu_to_le32(BIT(6));/* AGG BK */ | ||
225 | |||
226 | ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */ | ||
227 | |||
228 | if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) | ||
229 | ptxdesc->txdw4 |= cpu_to_le32(BIT(24));/* DATA_SHORT */ | ||
230 | |||
231 | ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate23a(pmlmeext->tx_rate)); | ||
232 | } | ||
233 | } else if ((pxmitframe->frame_tag&0x0f) == MGNT_FRAMETAG) { | ||
234 | /* offset 4 */ | ||
235 | ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f); | ||
236 | |||
237 | qsel = (uint)(pattrib->qsel&0x0000001f); | ||
238 | ptxdesc->txdw1 |= cpu_to_le32((qsel<<QSEL_SHT)&0x00001f00); | ||
239 | |||
240 | ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<<16) & 0x000f0000); | ||
241 | |||
242 | /* offset 8 */ | ||
243 | /* CCX-TXRPT ack for xmit mgmt frames. */ | ||
244 | if (pxmitframe->ack_report) | ||
245 | ptxdesc->txdw2 |= cpu_to_le32(BIT(19)); | ||
246 | |||
247 | /* offset 12 */ | ||
248 | ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000); | ||
249 | |||
250 | /* offset 16 */ | ||
251 | ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */ | ||
252 | |||
253 | /* offset 20 */ | ||
254 | ptxdesc->txdw5 |= cpu_to_le32(BIT(17));/* retry limit enable */ | ||
255 | ptxdesc->txdw5 |= cpu_to_le32(0x00180000);/* retry limit = 6 */ | ||
256 | |||
257 | ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate23a(pmlmeext->tx_rate)); | ||
258 | } else if ((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG) { | ||
259 | DBG_8723A("pxmitframe->frame_tag == TXAGG_FRAMETAG\n"); | ||
260 | } else { | ||
261 | DBG_8723A("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag); | ||
262 | |||
263 | /* offset 4 */ | ||
264 | ptxdesc->txdw1 |= cpu_to_le32((4)&0x1f);/* CAM_ID(MAC_ID) */ | ||
265 | |||
266 | ptxdesc->txdw1 |= cpu_to_le32((6<<16) & 0x000f0000);/* raid */ | ||
267 | |||
268 | /* offset 8 */ | ||
269 | |||
270 | /* offset 12 */ | ||
271 | ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000); | ||
272 | |||
273 | /* offset 16 */ | ||
274 | ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */ | ||
275 | |||
276 | /* offset 20 */ | ||
277 | ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate23a(pmlmeext->tx_rate)); | ||
278 | } | ||
279 | |||
280 | /* (1) The sequence number of each non-Qos frame / broadcast / multicast / */ | ||
281 | /* mgnt frame should be controled by Hw because Fw will also send null data */ | ||
282 | /* which we cannot control when Fw LPS enable. */ | ||
283 | /* --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */ | ||
284 | /* (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */ | ||
285 | /* (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. */ | ||
286 | if (!pattrib->qos_en) { | ||
287 | /* Hw set sequence number */ | ||
288 | ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); | ||
289 | /* set bit3 to 1. */ | ||
290 | ptxdesc->txdw3 |= cpu_to_le32((8 << 28)); | ||
291 | } | ||
292 | |||
293 | /* offset 0 */ | ||
294 | ptxdesc->txdw0 |= cpu_to_le32(sz&0x0000ffff); | ||
295 | ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); | ||
296 | ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);/* 32 bytes for TX Desc */ | ||
297 | |||
298 | if (bmcst) | ||
299 | ptxdesc->txdw0 |= cpu_to_le32(BIT(24)); | ||
300 | |||
301 | RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("offset0-txdesc = 0x%x\n", ptxdesc->txdw0)); | ||
302 | |||
303 | /* offset 4 */ | ||
304 | /* pkt_offset, unit:8 bytes padding */ | ||
305 | if (pxmitframe->pkt_offset > 0) | ||
306 | ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000); | ||
307 | |||
308 | rtl8192cu_cal_txdesc_chksum(ptxdesc); | ||
309 | return pull; | ||
310 | } | ||
311 | |||
312 | static s32 rtw_dump_xframe(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe) | ||
313 | { | ||
314 | s32 ret = _SUCCESS; | ||
315 | s32 inner_ret = _SUCCESS; | ||
316 | int t, sz, w_sz, pull = 0; | ||
317 | u8 *mem_addr; | ||
318 | u32 ff_hwaddr; | ||
319 | struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf; | ||
320 | struct pkt_attrib *pattrib = &pxmitframe->attrib; | ||
321 | struct xmit_priv *pxmitpriv = &padapter->xmitpriv; | ||
322 | |||
323 | if ((pxmitframe->frame_tag == DATA_FRAMETAG) && | ||
324 | (pxmitframe->attrib.ether_type != 0x0806) && | ||
325 | (pxmitframe->attrib.ether_type != 0x888e) && | ||
326 | (pxmitframe->attrib.dhcp_pkt != 1)) | ||
327 | rtw_issue_addbareq_cmd23a(padapter, pxmitframe); | ||
328 | |||
329 | mem_addr = pxmitframe->buf_addr; | ||
330 | |||
331 | RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_dump_xframe()\n")); | ||
332 | |||
333 | for (t = 0; t < pattrib->nr_frags; t++) { | ||
334 | if (inner_ret != _SUCCESS && ret == _SUCCESS) | ||
335 | ret = _FAIL; | ||
336 | |||
337 | if (t != (pattrib->nr_frags - 1)) { | ||
338 | RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, | ||
339 | ("pattrib->nr_frags =%d\n", pattrib->nr_frags)); | ||
340 | |||
341 | sz = pxmitpriv->frag_len; | ||
342 | sz = sz - 4 - pattrib->icv_len; | ||
343 | } else { | ||
344 | /* no frag */ | ||
345 | sz = pattrib->last_txcmdsz; | ||
346 | } | ||
347 | |||
348 | pull = update_txdesc(pxmitframe, mem_addr, sz, false); | ||
349 | |||
350 | if (pull) { | ||
351 | mem_addr += PACKET_OFFSET_SZ; /* pull txdesc head */ | ||
352 | |||
353 | pxmitframe->buf_addr = mem_addr; | ||
354 | |||
355 | w_sz = sz + TXDESC_SIZE; | ||
356 | } else { | ||
357 | w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ; | ||
358 | } | ||
359 | |||
360 | ff_hwaddr = rtw_get_ff_hwaddr23a(pxmitframe); | ||
361 | inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, pxmitbuf); | ||
362 | rtw_count_tx_stats23a(padapter, pxmitframe, sz); | ||
363 | |||
364 | RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, | ||
365 | ("rtw_write_port, w_sz =%d\n", w_sz)); | ||
366 | |||
367 | mem_addr += w_sz; | ||
368 | |||
369 | mem_addr = (u8 *)RND4(((unsigned long)(mem_addr))); | ||
370 | } | ||
371 | |||
372 | rtw_free_xmitframe23a(pxmitpriv, pxmitframe); | ||
373 | |||
374 | if (ret != _SUCCESS) | ||
375 | rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN); | ||
376 | |||
377 | return ret; | ||
378 | } | ||
379 | |||
380 | s32 rtl8723au_xmitframe_complete(struct rtw_adapter *padapter, | ||
381 | struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) | ||
382 | { | ||
383 | struct hw_xmit *phwxmits; | ||
384 | struct xmit_frame *pxmitframe; | ||
385 | int hwentry; | ||
386 | int res = _SUCCESS, xcnt = 0; | ||
387 | |||
388 | phwxmits = pxmitpriv->hwxmits; | ||
389 | hwentry = pxmitpriv->hwxmit_entry; | ||
390 | |||
391 | RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("xmitframe_complete()\n")); | ||
392 | |||
393 | if (pxmitbuf == NULL) { | ||
394 | pxmitbuf = rtw_alloc_xmitbuf23a(pxmitpriv); | ||
395 | if (!pxmitbuf) | ||
396 | return false; | ||
397 | } | ||
398 | pxmitframe = rtw_dequeue_xframe23a(pxmitpriv, phwxmits, hwentry); | ||
399 | |||
400 | if (pxmitframe) { | ||
401 | pxmitframe->pxmitbuf = pxmitbuf; | ||
402 | |||
403 | pxmitframe->buf_addr = pxmitbuf->pbuf; | ||
404 | |||
405 | pxmitbuf->priv_data = pxmitframe; | ||
406 | |||
407 | if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) { | ||
408 | if (pxmitframe->attrib.priority <= 15)/* TID0~15 */ | ||
409 | res = rtw_xmitframe_coalesce23a(padapter, pxmitframe->pkt, pxmitframe); | ||
410 | |||
411 | rtw_os_xmit_complete23a(padapter, pxmitframe);/* always return ndis_packet after rtw_xmitframe_coalesce23a */ | ||
412 | } | ||
413 | |||
414 | RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("xmitframe_complete(): rtw_dump_xframe\n")); | ||
415 | |||
416 | if (res == _SUCCESS) { | ||
417 | rtw_dump_xframe(padapter, pxmitframe); | ||
418 | } else { | ||
419 | rtw_free_xmitbuf23a(pxmitpriv, pxmitbuf); | ||
420 | rtw_free_xmitframe23a(pxmitpriv, pxmitframe); | ||
421 | } | ||
422 | xcnt++; | ||
423 | } else { | ||
424 | rtw_free_xmitbuf23a(pxmitpriv, pxmitbuf); | ||
425 | return false; | ||
426 | } | ||
427 | return true; | ||
428 | } | ||
429 | |||
430 | static s32 xmitframe_direct(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe) | ||
431 | { | ||
432 | s32 res = _SUCCESS; | ||
433 | |||
434 | res = rtw_xmitframe_coalesce23a(padapter, pxmitframe->pkt, pxmitframe); | ||
435 | if (res == _SUCCESS) | ||
436 | rtw_dump_xframe(padapter, pxmitframe); | ||
437 | return res; | ||
438 | } | ||
439 | |||
440 | /* | ||
441 | * Return | ||
442 | * true dump packet directly | ||
443 | * false enqueue packet | ||
444 | */ | ||
445 | static s32 pre_xmitframe(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe) | ||
446 | { | ||
447 | s32 res; | ||
448 | struct xmit_buf *pxmitbuf = NULL; | ||
449 | struct xmit_priv *pxmitpriv = &padapter->xmitpriv; | ||
450 | struct pkt_attrib *pattrib = &pxmitframe->attrib; | ||
451 | struct mlme_priv *pmlmepriv = &padapter->mlmepriv; | ||
452 | |||
453 | do_queue_select(padapter, pattrib); | ||
454 | spin_lock_bh(&pxmitpriv->lock); | ||
455 | |||
456 | #ifdef CONFIG_8723AU_AP_MODE | ||
457 | if (xmitframe_enqueue_for_sleeping_sta23a(padapter, pxmitframe)) { | ||
458 | struct sta_info *psta; | ||
459 | struct sta_priv *pstapriv = &padapter->stapriv; | ||
460 | |||
461 | spin_unlock_bh(&pxmitpriv->lock); | ||
462 | |||
463 | if (pattrib->psta) | ||
464 | psta = pattrib->psta; | ||
465 | else | ||
466 | psta = rtw_get_stainfo23a(pstapriv, pattrib->ra); | ||
467 | |||
468 | if (psta) { | ||
469 | if (psta->sleepq_len > (NR_XMITFRAME>>3)) | ||
470 | wakeup_sta_to_xmit23a(padapter, psta); | ||
471 | } | ||
472 | |||
473 | return false; | ||
474 | } | ||
475 | #endif | ||
476 | |||
477 | if (rtw_txframes_sta_ac_pending23a(padapter, pattrib) > 0) | ||
478 | goto enqueue; | ||
479 | |||
480 | if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true) | ||
481 | goto enqueue; | ||
482 | |||
483 | pxmitbuf = rtw_alloc_xmitbuf23a(pxmitpriv); | ||
484 | if (pxmitbuf == NULL) | ||
485 | goto enqueue; | ||
486 | |||
487 | spin_unlock_bh(&pxmitpriv->lock); | ||
488 | |||
489 | pxmitframe->pxmitbuf = pxmitbuf; | ||
490 | pxmitframe->buf_addr = pxmitbuf->pbuf; | ||
491 | pxmitbuf->priv_data = pxmitframe; | ||
492 | |||
493 | if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) { | ||
494 | rtw_free_xmitbuf23a(pxmitpriv, pxmitbuf); | ||
495 | rtw_free_xmitframe23a(pxmitpriv, pxmitframe); | ||
496 | } | ||
497 | return true; | ||
498 | |||
499 | enqueue: | ||
500 | res = rtw_xmitframe_enqueue23a(padapter, pxmitframe); | ||
501 | spin_unlock_bh(&pxmitpriv->lock); | ||
502 | |||
503 | if (res != _SUCCESS) { | ||
504 | RT_TRACE(_module_xmit_osdep_c_, _drv_err_, | ||
505 | ("pre_xmitframe: enqueue xmitframe fail\n")); | ||
506 | rtw_free_xmitframe23a(pxmitpriv, pxmitframe); | ||
507 | |||
508 | /* Trick, make the statistics correct */ | ||
509 | pxmitpriv->tx_pkts--; | ||
510 | pxmitpriv->tx_drop++; | ||
511 | return true; | ||
512 | } | ||
513 | return false; | ||
514 | } | ||
515 | |||
516 | s32 rtl8723au_mgnt_xmit(struct rtw_adapter *padapter, struct xmit_frame *pmgntframe) | ||
517 | { | ||
518 | return rtw_dump_xframe(padapter, pmgntframe); | ||
519 | } | ||
520 | |||
521 | /* | ||
522 | * Return | ||
523 | * true dump packet directly ok | ||
524 | * false temporary can't transmit packets to hardware | ||
525 | */ | ||
526 | s32 rtl8723au_hal_xmit(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe) | ||
527 | { | ||
528 | return pre_xmitframe(padapter, pxmitframe); | ||
529 | } | ||
530 | |||
531 | s32 rtl8723au_hal_xmitframe_enqueue(struct rtw_adapter *padapter, | ||
532 | struct xmit_frame *pxmitframe) | ||
533 | { | ||
534 | struct xmit_priv *pxmitpriv = &padapter->xmitpriv; | ||
535 | s32 err; | ||
536 | |||
537 | err = rtw_xmitframe_enqueue23a(padapter, pxmitframe); | ||
538 | if (err != _SUCCESS) { | ||
539 | rtw_free_xmitframe23a(pxmitpriv, pxmitframe); | ||
540 | |||
541 | /* Trick, make the statistics correct */ | ||
542 | pxmitpriv->tx_pkts--; | ||
543 | pxmitpriv->tx_drop++; | ||
544 | } else { | ||
545 | tasklet_hi_schedule(&pxmitpriv->xmit_tasklet); | ||
546 | } | ||
547 | return err; | ||
548 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c new file mode 100644 index 000000000000..e206829d50fa --- /dev/null +++ b/drivers/staging/rtl8723au/hal/usb_halinit.c | |||
@@ -0,0 +1,1834 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | #define _HCI_HAL_INIT_C_ | ||
16 | |||
17 | #include <osdep_service.h> | ||
18 | #include <drv_types.h> | ||
19 | #include <rtw_efuse.h> | ||
20 | |||
21 | #include <HalPwrSeqCmd.h> | ||
22 | #include <Hal8723PwrSeq.h> | ||
23 | #include <rtl8723a_hal.h> | ||
24 | #include <rtl8723a_led.h> | ||
25 | #include <linux/ieee80211.h> | ||
26 | |||
27 | #include <usb_ops.h> | ||
28 | #include <usb_hal.h> | ||
29 | #include <usb_osintf.h> | ||
30 | |||
31 | static void | ||
32 | _ConfigChipOutEP(struct rtw_adapter *pAdapter, u8 NumOutPipe) | ||
33 | { | ||
34 | u8 value8; | ||
35 | struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); | ||
36 | |||
37 | pHalData->OutEpQueueSel = 0; | ||
38 | pHalData->OutEpNumber = 0; | ||
39 | |||
40 | /* Normal and High queue */ | ||
41 | value8 = rtw_read8(pAdapter, (REG_NORMAL_SIE_EP + 1)); | ||
42 | |||
43 | if (value8 & USB_NORMAL_SIE_EP_MASK) { | ||
44 | pHalData->OutEpQueueSel |= TX_SELE_HQ; | ||
45 | pHalData->OutEpNumber++; | ||
46 | } | ||
47 | |||
48 | if ((value8 >> USB_NORMAL_SIE_EP_SHIFT) & USB_NORMAL_SIE_EP_MASK) { | ||
49 | pHalData->OutEpQueueSel |= TX_SELE_NQ; | ||
50 | pHalData->OutEpNumber++; | ||
51 | } | ||
52 | |||
53 | /* Low queue */ | ||
54 | value8 = rtw_read8(pAdapter, (REG_NORMAL_SIE_EP + 2)); | ||
55 | if (value8 & USB_NORMAL_SIE_EP_MASK) { | ||
56 | pHalData->OutEpQueueSel |= TX_SELE_LQ; | ||
57 | pHalData->OutEpNumber++; | ||
58 | } | ||
59 | |||
60 | /* TODO: Error recovery for this case */ | ||
61 | /* RT_ASSERT((NumOutPipe == pHalData->OutEpNumber), | ||
62 | ("Out EP number isn't match! %d(Descriptor) != %d (SIE reg)\n", | ||
63 | (u32)NumOutPipe, (u32)pHalData->OutEpNumber)); */ | ||
64 | } | ||
65 | |||
66 | static bool rtl8723au_set_queue_pipe_mapping(struct rtw_adapter *pAdapter, | ||
67 | u8 NumInPipe, u8 NumOutPipe) | ||
68 | { | ||
69 | struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); | ||
70 | bool result = false; | ||
71 | |||
72 | _ConfigChipOutEP(pAdapter, NumOutPipe); | ||
73 | |||
74 | /* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */ | ||
75 | if (pHalData->OutEpNumber == 1) { | ||
76 | if (NumInPipe != 1) | ||
77 | return result; | ||
78 | } | ||
79 | |||
80 | result = Hal_MappingOutPipe23a(pAdapter, NumOutPipe); | ||
81 | |||
82 | return result; | ||
83 | } | ||
84 | |||
85 | static void rtl8723au_interface_configure(struct rtw_adapter *padapter) | ||
86 | { | ||
87 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
88 | struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); | ||
89 | |||
90 | if (pdvobjpriv->ishighspeed == true) { | ||
91 | /* 512 bytes */ | ||
92 | pHalData->UsbBulkOutSize = USB_HIGH_SPEED_BULK_SIZE; | ||
93 | } else { | ||
94 | /* 64 bytes */ | ||
95 | pHalData->UsbBulkOutSize = USB_FULL_SPEED_BULK_SIZE; | ||
96 | } | ||
97 | |||
98 | pHalData->interfaceIndex = pdvobjpriv->InterfaceNumber; | ||
99 | |||
100 | rtl8723au_set_queue_pipe_mapping(padapter, | ||
101 | pdvobjpriv->RtNumInPipes, | ||
102 | pdvobjpriv->RtNumOutPipes); | ||
103 | } | ||
104 | |||
105 | static u8 _InitPowerOn(struct rtw_adapter *padapter) | ||
106 | { | ||
107 | u8 status = _SUCCESS; | ||
108 | u16 value16 = 0; | ||
109 | u8 value8 = 0; | ||
110 | |||
111 | /* RSV_CTRL 0x1C[7:0] = 0x00 | ||
112 | unlock ISO/CLK/Power control register */ | ||
113 | rtw_write8(padapter, REG_RSV_CTRL, 0x0); | ||
114 | |||
115 | /* HW Power on sequence */ | ||
116 | if (!HalPwrSeqCmdParsing23a(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, | ||
117 | PWR_INTF_USB_MSK, rtl8723AU_card_enable_flow)) | ||
118 | return _FAIL; | ||
119 | |||
120 | /* 0x04[19] = 1, suggest by Jackie 2011.05.09, reset 8051 */ | ||
121 | value8 = rtw_read8(padapter, REG_APS_FSMCO+2); | ||
122 | rtw_write8(padapter, REG_APS_FSMCO + 2, (value8 | BIT3)); | ||
123 | |||
124 | /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */ | ||
125 | /* Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. | ||
126 | Added by tynli. 2011.08.31. */ | ||
127 | value16 = rtw_read16(padapter, REG_CR); | ||
128 | value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN | | ||
129 | PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN | | ||
130 | ENSEC | CALTMR_EN); | ||
131 | rtw_write16(padapter, REG_CR, value16); | ||
132 | |||
133 | /* for Efuse PG, suggest by Jackie 2011.11.23 */ | ||
134 | PHY_SetBBReg(padapter, REG_EFUSE_CTRL, BIT28|BIT29|BIT30, 0x06); | ||
135 | |||
136 | return status; | ||
137 | } | ||
138 | |||
139 | /* Shall USB interface init this? */ | ||
140 | static void _InitInterrupt(struct rtw_adapter *Adapter) | ||
141 | { | ||
142 | u32 value32; | ||
143 | |||
144 | /* HISR - turn all on */ | ||
145 | value32 = 0xFFFFFFFF; | ||
146 | rtw_write32(Adapter, REG_HISR, value32); | ||
147 | |||
148 | /* HIMR - turn all on */ | ||
149 | rtw_write32(Adapter, REG_HIMR, value32); | ||
150 | } | ||
151 | |||
152 | static void _InitQueueReservedPage(struct rtw_adapter *Adapter) | ||
153 | { | ||
154 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
155 | struct registry_priv *pregistrypriv = &Adapter->registrypriv; | ||
156 | u32 numHQ = 0; | ||
157 | u32 numLQ = 0; | ||
158 | u32 numNQ = 0; | ||
159 | u32 numPubQ; | ||
160 | u32 value32; | ||
161 | u8 value8; | ||
162 | bool bWiFiConfig = pregistrypriv->wifi_spec; | ||
163 | /* u32 txQPageNum, txQPageUnit, txQRemainPage; */ | ||
164 | |||
165 | { /* for WMM */ | ||
166 | /* RT_ASSERT((outEPNum>= 2), ("for WMM , number of out-ep " | ||
167 | "must more than or equal to 2!\n")); */ | ||
168 | |||
169 | numPubQ = bWiFiConfig ? | ||
170 | WMM_NORMAL_PAGE_NUM_PUBQ : NORMAL_PAGE_NUM_PUBQ; | ||
171 | |||
172 | if (pHalData->OutEpQueueSel & TX_SELE_HQ) { | ||
173 | numHQ = bWiFiConfig ? | ||
174 | WMM_NORMAL_PAGE_NUM_HPQ : NORMAL_PAGE_NUM_HPQ; | ||
175 | } | ||
176 | |||
177 | if (pHalData->OutEpQueueSel & TX_SELE_LQ) { | ||
178 | numLQ = bWiFiConfig ? | ||
179 | WMM_NORMAL_PAGE_NUM_LPQ : NORMAL_PAGE_NUM_LPQ; | ||
180 | } | ||
181 | /* NOTE: This step shall be proceed before | ||
182 | writting REG_RQPN. */ | ||
183 | if (pHalData->OutEpQueueSel & TX_SELE_NQ) { | ||
184 | numNQ = bWiFiConfig ? | ||
185 | WMM_NORMAL_PAGE_NUM_NPQ : NORMAL_PAGE_NUM_NPQ; | ||
186 | } | ||
187 | value8 = (u8)_NPQ(numNQ); | ||
188 | rtw_write8(Adapter, REG_RQPN_NPQ, value8); | ||
189 | } | ||
190 | |||
191 | /* TX DMA */ | ||
192 | value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN; | ||
193 | rtw_write32(Adapter, REG_RQPN, value32); | ||
194 | } | ||
195 | |||
196 | static void _InitTxBufferBoundary(struct rtw_adapter *Adapter) | ||
197 | { | ||
198 | struct registry_priv *pregistrypriv = &Adapter->registrypriv; | ||
199 | |||
200 | u8 txpktbuf_bndy; | ||
201 | |||
202 | if (!pregistrypriv->wifi_spec) | ||
203 | txpktbuf_bndy = TX_PAGE_BOUNDARY; | ||
204 | else /* for WMM */ | ||
205 | txpktbuf_bndy = WMM_NORMAL_TX_PAGE_BOUNDARY; | ||
206 | |||
207 | rtw_write8(Adapter, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); | ||
208 | rtw_write8(Adapter, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); | ||
209 | rtw_write8(Adapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy); | ||
210 | rtw_write8(Adapter, REG_TRXFF_BNDY, txpktbuf_bndy); | ||
211 | rtw_write8(Adapter, REG_TDECTRL+1, txpktbuf_bndy); | ||
212 | } | ||
213 | |||
214 | static void _InitPageBoundary(struct rtw_adapter *Adapter) | ||
215 | { | ||
216 | /* RX Page Boundary */ | ||
217 | /* srand(static_cast<unsigned int>(time(NULL))); */ | ||
218 | u16 rxff_bndy = 0x27FF;/* rand() % 1) ? 0x27FF : 0x23FF; */ | ||
219 | |||
220 | rtw_write16(Adapter, (REG_TRXFF_BNDY + 2), rxff_bndy); | ||
221 | |||
222 | /* TODO: ?? shall we set tx boundary? */ | ||
223 | } | ||
224 | |||
225 | static void | ||
226 | _InitNormalChipRegPriority(struct rtw_adapter *Adapter, u16 beQ, u16 bkQ, | ||
227 | u16 viQ, u16 voQ, u16 mgtQ, u16 hiQ) | ||
228 | { | ||
229 | u16 value16 = rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7; | ||
230 | |||
231 | value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) | | ||
232 | _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) | | ||
233 | _TXDMA_MGQ_MAP(mgtQ) | _TXDMA_HIQ_MAP(hiQ); | ||
234 | |||
235 | rtw_write16(Adapter, REG_TRXDMA_CTRL, value16); | ||
236 | } | ||
237 | |||
238 | static void _InitNormalChipOneOutEpPriority(struct rtw_adapter *Adapter) | ||
239 | { | ||
240 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
241 | u16 value = 0; | ||
242 | |||
243 | switch (pHalData->OutEpQueueSel) { | ||
244 | case TX_SELE_HQ: | ||
245 | value = QUEUE_HIGH; | ||
246 | break; | ||
247 | case TX_SELE_LQ: | ||
248 | value = QUEUE_LOW; | ||
249 | break; | ||
250 | case TX_SELE_NQ: | ||
251 | value = QUEUE_NORMAL; | ||
252 | break; | ||
253 | default: | ||
254 | /* RT_ASSERT(false, ("Shall not reach here!\n")); */ | ||
255 | break; | ||
256 | } | ||
257 | |||
258 | _InitNormalChipRegPriority(Adapter, value, value, value, | ||
259 | value, value, value); | ||
260 | } | ||
261 | |||
262 | static void _InitNormalChipTwoOutEpPriority(struct rtw_adapter *Adapter) | ||
263 | { | ||
264 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
265 | struct registry_priv *pregistrypriv = &Adapter->registrypriv; | ||
266 | u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ; | ||
267 | u16 valueHi = 0; | ||
268 | u16 valueLow = 0; | ||
269 | |||
270 | switch (pHalData->OutEpQueueSel) { | ||
271 | case (TX_SELE_HQ | TX_SELE_LQ): | ||
272 | valueHi = QUEUE_HIGH; | ||
273 | valueLow = QUEUE_LOW; | ||
274 | break; | ||
275 | case (TX_SELE_NQ | TX_SELE_LQ): | ||
276 | valueHi = QUEUE_NORMAL; | ||
277 | valueLow = QUEUE_LOW; | ||
278 | break; | ||
279 | case (TX_SELE_HQ | TX_SELE_NQ): | ||
280 | valueHi = QUEUE_HIGH; | ||
281 | valueLow = QUEUE_NORMAL; | ||
282 | break; | ||
283 | default: | ||
284 | /* RT_ASSERT(false, ("Shall not reach here!\n")); */ | ||
285 | break; | ||
286 | } | ||
287 | |||
288 | if (!pregistrypriv->wifi_spec) { | ||
289 | beQ = valueLow; | ||
290 | bkQ = valueLow; | ||
291 | viQ = valueHi; | ||
292 | voQ = valueHi; | ||
293 | mgtQ = valueHi; | ||
294 | hiQ = valueHi; | ||
295 | } else {/* for WMM , CONFIG_OUT_EP_WIFI_MODE */ | ||
296 | beQ = valueLow; | ||
297 | bkQ = valueHi; | ||
298 | viQ = valueHi; | ||
299 | voQ = valueLow; | ||
300 | mgtQ = valueHi; | ||
301 | hiQ = valueHi; | ||
302 | } | ||
303 | |||
304 | _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ); | ||
305 | } | ||
306 | |||
307 | static void _InitNormalChipThreeOutEpPriority(struct rtw_adapter *Adapter) | ||
308 | { | ||
309 | struct registry_priv *pregistrypriv = &Adapter->registrypriv; | ||
310 | u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ; | ||
311 | |||
312 | if (!pregistrypriv->wifi_spec) {/* typical setting */ | ||
313 | beQ = QUEUE_LOW; | ||
314 | bkQ = QUEUE_LOW; | ||
315 | viQ = QUEUE_NORMAL; | ||
316 | voQ = QUEUE_HIGH; | ||
317 | mgtQ = QUEUE_HIGH; | ||
318 | hiQ = QUEUE_HIGH; | ||
319 | } else {/* for WMM */ | ||
320 | beQ = QUEUE_LOW; | ||
321 | bkQ = QUEUE_NORMAL; | ||
322 | viQ = QUEUE_NORMAL; | ||
323 | voQ = QUEUE_HIGH; | ||
324 | mgtQ = QUEUE_HIGH; | ||
325 | hiQ = QUEUE_HIGH; | ||
326 | } | ||
327 | _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ); | ||
328 | } | ||
329 | |||
330 | static void _InitNormalChipQueuePriority(struct rtw_adapter *Adapter) | ||
331 | { | ||
332 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
333 | |||
334 | switch (pHalData->OutEpNumber) { | ||
335 | case 1: | ||
336 | _InitNormalChipOneOutEpPriority(Adapter); | ||
337 | break; | ||
338 | case 2: | ||
339 | _InitNormalChipTwoOutEpPriority(Adapter); | ||
340 | break; | ||
341 | case 3: | ||
342 | _InitNormalChipThreeOutEpPriority(Adapter); | ||
343 | break; | ||
344 | default: | ||
345 | /* RT_ASSERT(false, ("Shall not reach here!\n")); */ | ||
346 | break; | ||
347 | } | ||
348 | } | ||
349 | |||
350 | static void _InitQueuePriority(struct rtw_adapter *Adapter) | ||
351 | { | ||
352 | _InitNormalChipQueuePriority(Adapter); | ||
353 | } | ||
354 | |||
355 | static void _InitNetworkType(struct rtw_adapter *Adapter) | ||
356 | { | ||
357 | u32 value32; | ||
358 | |||
359 | value32 = rtw_read32(Adapter, REG_CR); | ||
360 | |||
361 | /* TODO: use the other function to set network type */ | ||
362 | value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP); | ||
363 | rtw_write32(Adapter, REG_CR, value32); | ||
364 | } | ||
365 | |||
366 | static void _InitTransferPageSize(struct rtw_adapter *Adapter) | ||
367 | { | ||
368 | /* Tx page size is always 128. */ | ||
369 | |||
370 | u8 value8; | ||
371 | value8 = _PSRX(PBP_128) | _PSTX(PBP_128); | ||
372 | rtw_write8(Adapter, REG_PBP, value8); | ||
373 | } | ||
374 | |||
375 | static void _InitDriverInfoSize(struct rtw_adapter *Adapter, u8 drvInfoSize) | ||
376 | { | ||
377 | rtw_write8(Adapter, REG_RX_DRVINFO_SZ, drvInfoSize); | ||
378 | } | ||
379 | |||
380 | static void _InitWMACSetting(struct rtw_adapter *Adapter) | ||
381 | { | ||
382 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
383 | |||
384 | /* don't turn on AAP, it will allow all packets to driver */ | ||
385 | pHalData->ReceiveConfig = RCR_APM | RCR_AM | RCR_AB | RCR_CBSSID_DATA | | ||
386 | RCR_CBSSID_BCN | RCR_APP_ICV | RCR_AMF | | ||
387 | RCR_HTC_LOC_CTRL | RCR_APP_MIC | | ||
388 | RCR_APP_PHYSTS; | ||
389 | |||
390 | /* some REG_RCR will be modified later by | ||
391 | phy_ConfigMACWithHeaderFile() */ | ||
392 | rtw_write32(Adapter, REG_RCR, pHalData->ReceiveConfig); | ||
393 | |||
394 | /* Accept all multicast address */ | ||
395 | rtw_write32(Adapter, REG_MAR, 0xFFFFFFFF); | ||
396 | rtw_write32(Adapter, REG_MAR + 4, 0xFFFFFFFF); | ||
397 | |||
398 | /* Accept all data frames */ | ||
399 | /* value16 = 0xFFFF; */ | ||
400 | /* rtw_write16(Adapter, REG_RXFLTMAP2, value16); */ | ||
401 | |||
402 | /* 2010.09.08 hpfan */ | ||
403 | /* Since ADF is removed from RCR, ps-poll will not be indicate | ||
404 | to driver, */ | ||
405 | /* RxFilterMap should mask ps-poll to gurantee AP mode can | ||
406 | rx ps-poll. */ | ||
407 | /* value16 = 0x400; */ | ||
408 | /* rtw_write16(Adapter, REG_RXFLTMAP1, value16); */ | ||
409 | |||
410 | /* Accept all management frames */ | ||
411 | /* value16 = 0xFFFF; */ | ||
412 | /* rtw_write16(Adapter, REG_RXFLTMAP0, value16); */ | ||
413 | |||
414 | /* enable RX_SHIFT bits */ | ||
415 | /* rtw_write8(Adapter, REG_TRXDMA_CTRL, rtw_read8(Adapter, | ||
416 | REG_TRXDMA_CTRL)|BIT(1)); */ | ||
417 | } | ||
418 | |||
419 | static void _InitAdaptiveCtrl(struct rtw_adapter *Adapter) | ||
420 | { | ||
421 | u16 value16; | ||
422 | u32 value32; | ||
423 | |||
424 | /* Response Rate Set */ | ||
425 | value32 = rtw_read32(Adapter, REG_RRSR); | ||
426 | value32 &= ~RATE_BITMAP_ALL; | ||
427 | value32 |= RATE_RRSR_CCK_ONLY_1M; | ||
428 | rtw_write32(Adapter, REG_RRSR, value32); | ||
429 | |||
430 | /* CF-END Threshold */ | ||
431 | /* m_spIoBase->rtw_write8(REG_CFEND_TH, 0x1); */ | ||
432 | |||
433 | /* SIFS (used in NAV) */ | ||
434 | value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10); | ||
435 | rtw_write16(Adapter, REG_SPEC_SIFS, value16); | ||
436 | |||
437 | /* Retry Limit */ | ||
438 | value16 = _LRL(0x30) | _SRL(0x30); | ||
439 | rtw_write16(Adapter, REG_RL, value16); | ||
440 | } | ||
441 | |||
442 | static void _InitRateFallback(struct rtw_adapter *Adapter) | ||
443 | { | ||
444 | /* Set Data Auto Rate Fallback Retry Count register. */ | ||
445 | rtw_write32(Adapter, REG_DARFRC, 0x00000000); | ||
446 | rtw_write32(Adapter, REG_DARFRC+4, 0x10080404); | ||
447 | rtw_write32(Adapter, REG_RARFRC, 0x04030201); | ||
448 | rtw_write32(Adapter, REG_RARFRC+4, 0x08070605); | ||
449 | } | ||
450 | |||
451 | static void _InitEDCA(struct rtw_adapter *Adapter) | ||
452 | { | ||
453 | /* Set Spec SIFS (used in NAV) */ | ||
454 | rtw_write16(Adapter, REG_SPEC_SIFS, 0x100a); | ||
455 | rtw_write16(Adapter, REG_MAC_SPEC_SIFS, 0x100a); | ||
456 | |||
457 | /* Set SIFS for CCK */ | ||
458 | rtw_write16(Adapter, REG_SIFS_CTX, 0x100a); | ||
459 | |||
460 | /* Set SIFS for OFDM */ | ||
461 | rtw_write16(Adapter, REG_SIFS_TRX, 0x100a); | ||
462 | |||
463 | /* TXOP */ | ||
464 | rtw_write32(Adapter, REG_EDCA_BE_PARAM, 0x005EA42B); | ||
465 | rtw_write32(Adapter, REG_EDCA_BK_PARAM, 0x0000A44F); | ||
466 | rtw_write32(Adapter, REG_EDCA_VI_PARAM, 0x005EA324); | ||
467 | rtw_write32(Adapter, REG_EDCA_VO_PARAM, 0x002FA226); | ||
468 | } | ||
469 | |||
470 | static void _InitHWLed(struct rtw_adapter *Adapter) | ||
471 | { | ||
472 | struct led_priv *pledpriv = &Adapter->ledpriv; | ||
473 | |||
474 | if (pledpriv->LedStrategy != HW_LED) | ||
475 | return; | ||
476 | |||
477 | /* HW led control */ | ||
478 | /* to do .... */ | ||
479 | /* must consider cases of antenna diversity/ commbo card/solo card/mini card */ | ||
480 | } | ||
481 | |||
482 | static void _InitRDGSetting(struct rtw_adapter *Adapter) | ||
483 | { | ||
484 | rtw_write8(Adapter, REG_RD_CTRL, 0xFF); | ||
485 | rtw_write16(Adapter, REG_RD_NAV_NXT, 0x200); | ||
486 | rtw_write8(Adapter, REG_RD_RESP_PKT_TH, 0x05); | ||
487 | } | ||
488 | |||
489 | static void _InitRetryFunction(struct rtw_adapter *Adapter) | ||
490 | { | ||
491 | u8 value8; | ||
492 | |||
493 | value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL); | ||
494 | value8 |= EN_AMPDU_RTY_NEW; | ||
495 | rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8); | ||
496 | |||
497 | /* Set ACK timeout */ | ||
498 | rtw_write8(Adapter, REG_ACKTO, 0x40); | ||
499 | } | ||
500 | |||
501 | /*----------------------------------------------------------------------------- | ||
502 | * Function: usb_AggSettingTxUpdate() | ||
503 | * | ||
504 | * Overview: Seperate TX/RX parameters update independent for TP | ||
505 | * detection and dynamic TX/RX aggreagtion parameters update. | ||
506 | * | ||
507 | * Input: struct rtw_adapter * | ||
508 | * | ||
509 | * Output/Return: NONE | ||
510 | * | ||
511 | * Revised History: | ||
512 | * When Who Remark | ||
513 | * 12/10/2010 MHC Seperate to smaller function. | ||
514 | * | ||
515 | *---------------------------------------------------------------------------*/ | ||
516 | static void usb_AggSettingTxUpdate(struct rtw_adapter *Adapter) | ||
517 | { | ||
518 | } /* usb_AggSettingTxUpdate */ | ||
519 | |||
520 | /*----------------------------------------------------------------------------- | ||
521 | * Function: usb_AggSettingRxUpdate() | ||
522 | * | ||
523 | * Overview: Seperate TX/RX parameters update independent for TP | ||
524 | * detection and dynamic TX/RX aggreagtion parameters update. | ||
525 | * | ||
526 | * Input: struct rtw_adapter * | ||
527 | * | ||
528 | * Output/Return: NONE | ||
529 | * | ||
530 | * Revised History: | ||
531 | * When Who Remark | ||
532 | * 12/10/2010 MHC Seperate to smaller function. | ||
533 | * | ||
534 | *---------------------------------------------------------------------------*/ | ||
535 | static void usb_AggSettingRxUpdate(struct rtw_adapter *Adapter) | ||
536 | { | ||
537 | } /* usb_AggSettingRxUpdate */ | ||
538 | |||
539 | static void InitUsbAggregationSetting(struct rtw_adapter *Adapter) | ||
540 | { | ||
541 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
542 | |||
543 | /* Tx aggregation setting */ | ||
544 | usb_AggSettingTxUpdate(Adapter); | ||
545 | |||
546 | /* Rx aggregation setting */ | ||
547 | usb_AggSettingRxUpdate(Adapter); | ||
548 | |||
549 | /* 201/12/10 MH Add for USB agg mode dynamic switch. */ | ||
550 | pHalData->UsbRxHighSpeedMode = false; | ||
551 | } | ||
552 | |||
553 | static void _InitOperationMode(struct rtw_adapter *Adapter) | ||
554 | { | ||
555 | } | ||
556 | |||
557 | static void _InitRFType(struct rtw_adapter *Adapter) | ||
558 | { | ||
559 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
560 | bool is92CU = IS_92C_SERIAL(pHalData->VersionID); | ||
561 | |||
562 | pHalData->rf_chip = RF_6052; | ||
563 | |||
564 | if (is92CU == false) { | ||
565 | pHalData->rf_type = RF_1T1R; | ||
566 | DBG_8723A("Set RF Chip ID to RF_6052 and RF type to 1T1R.\n"); | ||
567 | return; | ||
568 | } | ||
569 | |||
570 | /* TODO: Consider that EEPROM set 92CU to 1T1R later. */ | ||
571 | /* Force to overwrite setting according to chip version. Ignore | ||
572 | EEPROM setting. */ | ||
573 | /* pHalData->RF_Type = is92CU ? RF_2T2R : RF_1T1R; */ | ||
574 | MSG_8723A("Set RF Chip ID to RF_6052 and RF type to %d.\n", | ||
575 | pHalData->rf_type); | ||
576 | } | ||
577 | |||
578 | /* Set CCK and OFDM Block "ON" */ | ||
579 | static void _BBTurnOnBlock(struct rtw_adapter *Adapter) | ||
580 | { | ||
581 | PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bCCKEn, 0x1); | ||
582 | PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bOFDMEn, 0x1); | ||
583 | } | ||
584 | |||
585 | #define MgntActSet_RF_State(...) | ||
586 | static void _RfPowerSave(struct rtw_adapter *padapter) | ||
587 | { | ||
588 | } | ||
589 | |||
590 | enum { | ||
591 | Antenna_Lfet = 1, | ||
592 | Antenna_Right = 2, | ||
593 | }; | ||
594 | |||
595 | enum rt_rf_power_state RfOnOffDetect23a(struct rtw_adapter *pAdapter) | ||
596 | { | ||
597 | /* struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); */ | ||
598 | u8 val8; | ||
599 | enum rt_rf_power_state rfpowerstate = rf_off; | ||
600 | |||
601 | if (pAdapter->pwrctrlpriv.bHWPowerdown) { | ||
602 | val8 = rtw_read8(pAdapter, REG_HSISR); | ||
603 | DBG_8723A("pwrdown, 0x5c(BIT7) =%02x\n", val8); | ||
604 | rfpowerstate = (val8 & BIT7) ? rf_off : rf_on; | ||
605 | } else { /* rf on/off */ | ||
606 | rtw_write8(pAdapter, REG_MAC_PINMUX_CFG, | ||
607 | rtw_read8(pAdapter, REG_MAC_PINMUX_CFG) & ~BIT3); | ||
608 | val8 = rtw_read8(pAdapter, REG_GPIO_IO_SEL); | ||
609 | DBG_8723A("GPIO_IN =%02x\n", val8); | ||
610 | rfpowerstate = (val8 & BIT3) ? rf_on : rf_off; | ||
611 | } | ||
612 | return rfpowerstate; | ||
613 | } /* HalDetectPwrDownMode */ | ||
614 | |||
615 | void _ps_open_RF23a(struct rtw_adapter *padapter); | ||
616 | |||
617 | static u32 rtl8723au_hal_init(struct rtw_adapter *Adapter) | ||
618 | { | ||
619 | u8 val8 = 0; | ||
620 | u32 boundary, status = _SUCCESS; | ||
621 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
622 | struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv; | ||
623 | struct registry_priv *pregistrypriv = &Adapter->registrypriv; | ||
624 | u32 NavUpper = WiFiNavUpperUs; | ||
625 | |||
626 | unsigned long init_start_time = jiffies; | ||
627 | |||
628 | #define HAL_INIT_PROFILE_TAG(stage) do {} while (0) | ||
629 | |||
630 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BEGIN); | ||
631 | if (Adapter->pwrctrlpriv.bkeepfwalive) { | ||
632 | _ps_open_RF23a(Adapter); | ||
633 | |||
634 | if (pHalData->bIQKInitialized) { | ||
635 | rtl8723a_phy_iq_calibrate(Adapter, true); | ||
636 | } else { | ||
637 | rtl8723a_phy_iq_calibrate(Adapter, false); | ||
638 | pHalData->bIQKInitialized = true; | ||
639 | } | ||
640 | rtl8723a_odm_check_tx_power_tracking(Adapter); | ||
641 | rtl8723a_phy_lc_calibrate(Adapter); | ||
642 | |||
643 | goto exit; | ||
644 | } | ||
645 | |||
646 | /* Check if MAC has already power on. by tynli. 2011.05.27. */ | ||
647 | val8 = rtw_read8(Adapter, REG_CR); | ||
648 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
649 | ("%s: REG_CR 0x100 = 0x%02x\n", __func__, val8)); | ||
650 | /* Fix 92DU-VC S3 hang with the reason is that secondary mac is not | ||
651 | initialized. */ | ||
652 | /* 0x100 value of first mac is 0xEA while 0x100 value of secondary | ||
653 | is 0x00 */ | ||
654 | if (val8 == 0xEA) { | ||
655 | pHalData->bMACFuncEnable = false; | ||
656 | } else { | ||
657 | pHalData->bMACFuncEnable = true; | ||
658 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
659 | ("%s: MAC has already power on\n", __func__)); | ||
660 | } | ||
661 | |||
662 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PW_ON); | ||
663 | status = _InitPowerOn(Adapter); | ||
664 | if (status == _FAIL) { | ||
665 | RT_TRACE(_module_hci_hal_init_c_, _drv_err_, | ||
666 | ("Failed to init power on!\n")); | ||
667 | goto exit; | ||
668 | } | ||
669 | |||
670 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_LLTT); | ||
671 | if (!pregistrypriv->wifi_spec) { | ||
672 | boundary = TX_PAGE_BOUNDARY; | ||
673 | } else { | ||
674 | /* for WMM */ | ||
675 | boundary = WMM_NORMAL_TX_PAGE_BOUNDARY; | ||
676 | } | ||
677 | |||
678 | if (!pHalData->bMACFuncEnable) { | ||
679 | status = InitLLTTable23a(Adapter, boundary); | ||
680 | if (status == _FAIL) { | ||
681 | RT_TRACE(_module_hci_hal_init_c_, _drv_err_, | ||
682 | ("Failed to init LLT table\n")); | ||
683 | goto exit; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC01); | ||
688 | if (pHalData->bRDGEnable) | ||
689 | _InitRDGSetting(Adapter); | ||
690 | |||
691 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_DOWNLOAD_FW); | ||
692 | status = rtl8723a_FirmwareDownload(Adapter); | ||
693 | if (status != _SUCCESS) { | ||
694 | Adapter->bFWReady = false; | ||
695 | pHalData->fw_ractrl = false; | ||
696 | DBG_8723A("fw download fail!\n"); | ||
697 | goto exit; | ||
698 | } else { | ||
699 | Adapter->bFWReady = true; | ||
700 | pHalData->fw_ractrl = true; | ||
701 | DBG_8723A("fw download ok!\n"); | ||
702 | } | ||
703 | |||
704 | rtl8723a_InitializeFirmwareVars(Adapter); | ||
705 | |||
706 | if (pwrctrlpriv->reg_rfoff == true) { | ||
707 | pwrctrlpriv->rf_pwrstate = rf_off; | ||
708 | } | ||
709 | |||
710 | /* 2010/08/09 MH We need to check if we need to turnon or off RF after detecting */ | ||
711 | /* HW GPIO pin. Before PHY_RFConfig8192C. */ | ||
712 | /* HalDetectPwrDownMode(Adapter); */ | ||
713 | /* 2010/08/26 MH If Efuse does not support sective suspend then disable the function. */ | ||
714 | /* HalDetectSelectiveSuspendMode(Adapter); */ | ||
715 | |||
716 | /* Set RF type for BB/RF configuration */ | ||
717 | _InitRFType(Adapter);/* _ReadRFType() */ | ||
718 | |||
719 | /* Save target channel */ | ||
720 | /* <Roger_Notes> Current Channel will be updated again later. */ | ||
721 | pHalData->CurrentChannel = 6;/* default set to 6 */ | ||
722 | |||
723 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MAC); | ||
724 | status = PHY_MACConfig8723A(Adapter); | ||
725 | if (status == _FAIL) { | ||
726 | DBG_8723A("PHY_MACConfig8723A fault !!\n"); | ||
727 | goto exit; | ||
728 | } | ||
729 | |||
730 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BB); | ||
731 | /* */ | ||
732 | /* d. Initialize BB related configurations. */ | ||
733 | /* */ | ||
734 | status = PHY_BBConfig8723A(Adapter); | ||
735 | if (status == _FAIL) { | ||
736 | DBG_8723A("PHY_BBConfig8723A fault !!\n"); | ||
737 | goto exit; | ||
738 | } | ||
739 | |||
740 | /* Add for tx power by rate fine tune. We need to call the function after BB config. */ | ||
741 | /* Because the tx power by rate table is inited in BB config. */ | ||
742 | |||
743 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_RF); | ||
744 | status = PHY_RFConfig8723A(Adapter); | ||
745 | if (status == _FAIL) { | ||
746 | DBG_8723A("PHY_RFConfig8723A fault !!\n"); | ||
747 | goto exit; | ||
748 | } | ||
749 | |||
750 | /* reducing 80M spur */ | ||
751 | PHY_SetBBReg(Adapter, RF_T_METER, bMaskDWord, 0x0381808d); | ||
752 | PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff83); | ||
753 | PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff82); | ||
754 | PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff83); | ||
755 | |||
756 | /* RFSW Control */ | ||
757 | PHY_SetBBReg(Adapter, rFPGA0_TxInfo, bMaskDWord, 0x00000003); /* 0x804[14]= 0 */ | ||
758 | PHY_SetBBReg(Adapter, rFPGA0_XAB_RFInterfaceSW, bMaskDWord, 0x07000760); /* 0x870[6:5]= b'11 */ | ||
759 | PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, bMaskDWord, 0x66F60210); /* 0x860[6:5]= b'00 */ | ||
760 | |||
761 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("%s: 0x870 = value 0x%x\n", __func__, PHY_QueryBBReg(Adapter, 0x870, bMaskDWord))); | ||
762 | |||
763 | /* */ | ||
764 | /* Joseph Note: Keep RfRegChnlVal for later use. */ | ||
765 | /* */ | ||
766 | pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, (enum RF_RADIO_PATH)0, RF_CHNLBW, bRFRegOffsetMask); | ||
767 | pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, (enum RF_RADIO_PATH)1, RF_CHNLBW, bRFRegOffsetMask); | ||
768 | |||
769 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC02); | ||
770 | if (!pHalData->bMACFuncEnable) { | ||
771 | _InitQueueReservedPage(Adapter); | ||
772 | _InitTxBufferBoundary(Adapter); | ||
773 | } | ||
774 | _InitQueuePriority(Adapter); | ||
775 | _InitPageBoundary(Adapter); | ||
776 | _InitTransferPageSize(Adapter); | ||
777 | |||
778 | /* Get Rx PHY status in order to report RSSI and others. */ | ||
779 | _InitDriverInfoSize(Adapter, DRVINFO_SZ); | ||
780 | |||
781 | _InitInterrupt(Adapter); | ||
782 | hal_init_macaddr23a(Adapter);/* set mac_address */ | ||
783 | _InitNetworkType(Adapter);/* set msr */ | ||
784 | _InitWMACSetting(Adapter); | ||
785 | _InitAdaptiveCtrl(Adapter); | ||
786 | _InitEDCA(Adapter); | ||
787 | _InitRateFallback(Adapter); | ||
788 | _InitRetryFunction(Adapter); | ||
789 | InitUsbAggregationSetting(Adapter); | ||
790 | _InitOperationMode(Adapter);/* todo */ | ||
791 | rtl8723a_InitBeaconParameters(Adapter); | ||
792 | |||
793 | _InitHWLed(Adapter); | ||
794 | |||
795 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_TURN_ON_BLOCK); | ||
796 | _BBTurnOnBlock(Adapter); | ||
797 | /* NicIFSetMacAddress(padapter, padapter->PermanentAddress); */ | ||
798 | |||
799 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_SECURITY); | ||
800 | invalidate_cam_all23a(Adapter); | ||
801 | |||
802 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC11); | ||
803 | /* 2010/12/17 MH We need to set TX power according to EFUSE content at first. */ | ||
804 | PHY_SetTxPowerLevel8723A(Adapter, pHalData->CurrentChannel); | ||
805 | |||
806 | rtl8723a_InitAntenna_Selection(Adapter); | ||
807 | |||
808 | /* HW SEQ CTRL */ | ||
809 | /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */ | ||
810 | rtw_write8(Adapter, REG_HWSEQ_CTRL, 0xFF); | ||
811 | |||
812 | /* */ | ||
813 | /* Disable BAR, suggested by Scott */ | ||
814 | /* 2010.04.09 add by hpfan */ | ||
815 | /* */ | ||
816 | rtw_write32(Adapter, REG_BAR_MODE_CTRL, 0x0201ffff); | ||
817 | |||
818 | if (pregistrypriv->wifi_spec) | ||
819 | rtw_write16(Adapter, REG_FAST_EDCA_CTRL, 0); | ||
820 | |||
821 | /* Move by Neo for USB SS from above setp */ | ||
822 | _RfPowerSave(Adapter); | ||
823 | |||
824 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK); | ||
825 | /* 2010/08/26 MH Merge from 8192CE. */ | ||
826 | /* sherry masked that it has been done in _RfPowerSave */ | ||
827 | /* 20110927 */ | ||
828 | /* recovery for 8192cu and 9723Au 20111017 */ | ||
829 | if (pwrctrlpriv->rf_pwrstate == rf_on) { | ||
830 | if (pHalData->bIQKInitialized) { | ||
831 | rtl8723a_phy_iq_calibrate(Adapter, true); | ||
832 | } else { | ||
833 | rtl8723a_phy_iq_calibrate(Adapter, false); | ||
834 | pHalData->bIQKInitialized = true; | ||
835 | } | ||
836 | |||
837 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_PW_TRACK); | ||
838 | rtl8723a_odm_check_tx_power_tracking(Adapter); | ||
839 | |||
840 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_LCK); | ||
841 | rtl8723a_phy_lc_calibrate(Adapter); | ||
842 | |||
843 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
844 | rtl8723a_SingleDualAntennaDetection(Adapter); | ||
845 | #endif | ||
846 | } | ||
847 | |||
848 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC21); | ||
849 | /* fixed USB interface interference issue */ | ||
850 | rtw_write8(Adapter, 0xfe40, 0xe0); | ||
851 | rtw_write8(Adapter, 0xfe41, 0x8d); | ||
852 | rtw_write8(Adapter, 0xfe42, 0x80); | ||
853 | rtw_write32(Adapter, 0x20c, 0xfd0320); | ||
854 | /* Solve too many protocol error on USB bus */ | ||
855 | if (!IS_81xxC_VENDOR_UMC_A_CUT(pHalData->VersionID)) { | ||
856 | /* 0xE6 = 0x94 */ | ||
857 | rtw_write8(Adapter, 0xFE40, 0xE6); | ||
858 | rtw_write8(Adapter, 0xFE41, 0x94); | ||
859 | rtw_write8(Adapter, 0xFE42, 0x80); | ||
860 | |||
861 | /* 0xE0 = 0x19 */ | ||
862 | rtw_write8(Adapter, 0xFE40, 0xE0); | ||
863 | rtw_write8(Adapter, 0xFE41, 0x19); | ||
864 | rtw_write8(Adapter, 0xFE42, 0x80); | ||
865 | |||
866 | /* 0xE5 = 0x91 */ | ||
867 | rtw_write8(Adapter, 0xFE40, 0xE5); | ||
868 | rtw_write8(Adapter, 0xFE41, 0x91); | ||
869 | rtw_write8(Adapter, 0xFE42, 0x80); | ||
870 | |||
871 | /* 0xE2 = 0x81 */ | ||
872 | rtw_write8(Adapter, 0xFE40, 0xE2); | ||
873 | rtw_write8(Adapter, 0xFE41, 0x81); | ||
874 | rtw_write8(Adapter, 0xFE42, 0x80); | ||
875 | |||
876 | } | ||
877 | |||
878 | /* HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PABIAS); */ | ||
879 | /* _InitPABias(Adapter); */ | ||
880 | |||
881 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
882 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BT_COEXIST); | ||
883 | /* Init BT hw config. */ | ||
884 | BT_InitHwConfig(Adapter); | ||
885 | #endif | ||
886 | |||
887 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_HAL_DM); | ||
888 | rtl8723a_InitHalDm(Adapter); | ||
889 | |||
890 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC31); | ||
891 | rtw_hal_set_hwreg23a(Adapter, HW_VAR_NAV_UPPER, (u8 *)&NavUpper); | ||
892 | |||
893 | /* 2011/03/09 MH debug only, UMC-B cut pass 2500 S5 test, but we need to fin root cause. */ | ||
894 | if (((rtw_read32(Adapter, rFPGA0_RFMOD) & 0xFF000000) != 0x83000000)) { | ||
895 | PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(24), 1); | ||
896 | RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("%s: IQK fail recorver\n", __func__)); | ||
897 | } | ||
898 | |||
899 | /* ack for xmit mgmt frames. */ | ||
900 | rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, rtw_read32(Adapter, REG_FWHW_TXQ_CTRL)|BIT(12)); | ||
901 | |||
902 | exit: | ||
903 | HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END); | ||
904 | |||
905 | DBG_8723A("%s in %dms\n", __func__, | ||
906 | jiffies_to_msecs(jiffies - init_start_time)); | ||
907 | return status; | ||
908 | } | ||
909 | |||
910 | static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter, | ||
911 | enum rt_rf_power_state eRFPowerState, | ||
912 | int bRegSSPwrLvl) | ||
913 | { | ||
914 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
915 | u8 value8; | ||
916 | u8 bytetmp; | ||
917 | |||
918 | switch (eRFPowerState) { | ||
919 | case rf_on: | ||
920 | if (bRegSSPwrLvl == 1) { | ||
921 | /* 1. Enable MAC Clock. Can not be enabled now. */ | ||
922 | /* WriteXBYTE(REG_SYS_CLKR+1, | ||
923 | ReadXBYTE(REG_SYS_CLKR+1) | BIT(3)); */ | ||
924 | |||
925 | /* 2. Force PWM, Enable SPS18_LDO_Marco_Block */ | ||
926 | rtw_write8(Adapter, REG_SPS0_CTRL, | ||
927 | rtw_read8(Adapter, REG_SPS0_CTRL) | | ||
928 | (BIT0|BIT3)); | ||
929 | |||
930 | /* 3. restore BB, AFE control register. */ | ||
931 | /* RF */ | ||
932 | if (pHalData->rf_type == RF_2T2R) | ||
933 | PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, | ||
934 | 0x380038, 1); | ||
935 | else | ||
936 | PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, | ||
937 | 0x38, 1); | ||
938 | PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 1); | ||
939 | PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT1, 0); | ||
940 | |||
941 | /* AFE */ | ||
942 | if (pHalData->rf_type == RF_2T2R) | ||
943 | PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, | ||
944 | 0x63DB25A0); | ||
945 | else if (pHalData->rf_type == RF_1T1R) | ||
946 | PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, | ||
947 | 0x631B25A0); | ||
948 | |||
949 | /* 4. issue 3-wire command that RF set to Rx idle | ||
950 | mode. This is used to re-write the RX idle mode. */ | ||
951 | /* We can only prvide a usual value instead and then | ||
952 | HW will modify the value by itself. */ | ||
953 | PHY_SetRFReg(Adapter, RF_PATH_A, 0, | ||
954 | bRFRegOffsetMask, 0x32D95); | ||
955 | if (pHalData->rf_type == RF_2T2R) { | ||
956 | PHY_SetRFReg(Adapter, RF_PATH_B, 0, | ||
957 | bRFRegOffsetMask, 0x32D95); | ||
958 | } | ||
959 | } else { /* Level 2 or others. */ | ||
960 | /* h. AFE_PLL_CTRL 0x28[7:0] = 0x80 | ||
961 | disable AFE PLL */ | ||
962 | rtw_write8(Adapter, REG_AFE_PLL_CTRL, 0x81); | ||
963 | |||
964 | /* i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F | ||
965 | gated AFE DIG_CLOCK */ | ||
966 | rtw_write16(Adapter, REG_AFE_XTAL_CTRL, 0x800F); | ||
967 | mdelay(1); | ||
968 | |||
969 | /* 2. Force PWM, Enable SPS18_LDO_Marco_Block */ | ||
970 | rtw_write8(Adapter, REG_SPS0_CTRL, | ||
971 | rtw_read8(Adapter, REG_SPS0_CTRL) | | ||
972 | (BIT0|BIT3)); | ||
973 | |||
974 | /* 3. restore BB, AFE control register. */ | ||
975 | /* RF */ | ||
976 | if (pHalData->rf_type == RF_2T2R) | ||
977 | PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, | ||
978 | 0x380038, 1); | ||
979 | else | ||
980 | PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, | ||
981 | 0x38, 1); | ||
982 | PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 1); | ||
983 | PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT1, 0); | ||
984 | |||
985 | /* AFE */ | ||
986 | if (pHalData->rf_type == RF_2T2R) | ||
987 | PHY_SetBBReg(Adapter, rRx_Wait_CCA, | ||
988 | bMaskDWord, 0x63DB25A0); | ||
989 | else if (pHalData->rf_type == RF_1T1R) | ||
990 | PHY_SetBBReg(Adapter, rRx_Wait_CCA, | ||
991 | bMaskDWord, 0x631B25A0); | ||
992 | |||
993 | /* 4. issue 3-wire command that RF set to Rx idle | ||
994 | mode. This is used to re-write the RX idle mode. */ | ||
995 | /* We can only prvide a usual value instead and | ||
996 | then HW will modify the value by itself. */ | ||
997 | PHY_SetRFReg(Adapter, RF_PATH_A, 0, | ||
998 | bRFRegOffsetMask, 0x32D95); | ||
999 | if (pHalData->rf_type == RF_2T2R) { | ||
1000 | PHY_SetRFReg(Adapter, RF_PATH_B, 0, | ||
1001 | bRFRegOffsetMask, 0x32D95); | ||
1002 | } | ||
1003 | |||
1004 | /* 5. gated MAC Clock */ | ||
1005 | bytetmp = rtw_read8(Adapter, REG_APSD_CTRL); | ||
1006 | rtw_write8(Adapter, REG_APSD_CTRL, bytetmp & ~BIT6); | ||
1007 | |||
1008 | mdelay(10); | ||
1009 | |||
1010 | /* Set BB reset at first */ | ||
1011 | rtw_write8(Adapter, REG_SYS_FUNC_EN, 0x17); /* 0x16 */ | ||
1012 | |||
1013 | /* Enable TX */ | ||
1014 | rtw_write8(Adapter, REG_TXPAUSE, 0x0); | ||
1015 | } | ||
1016 | break; | ||
1017 | case rf_sleep: | ||
1018 | case rf_off: | ||
1019 | value8 = rtw_read8(Adapter, REG_SPS0_CTRL) ; | ||
1020 | if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID)) | ||
1021 | value8 &= ~(BIT0); | ||
1022 | else | ||
1023 | value8 &= ~(BIT0|BIT3); | ||
1024 | if (bRegSSPwrLvl == 1) { | ||
1025 | RT_TRACE(_module_hal_init_c_, _drv_err_, ("SS LVL1\n")); | ||
1026 | /* Disable RF and BB only for SelectSuspend. */ | ||
1027 | |||
1028 | /* 1. Set BB/RF to shutdown. */ | ||
1029 | /* (1) Reg878[5:3]= 0 RF rx_code for | ||
1030 | preamble power saving */ | ||
1031 | /* (2)Reg878[21:19]= 0 Turn off RF-B */ | ||
1032 | /* (3) RegC04[7:4]= 0 Turn off all paths | ||
1033 | for packet detection */ | ||
1034 | /* (4) Reg800[1] = 1 enable preamble power | ||
1035 | saving */ | ||
1036 | Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] = | ||
1037 | PHY_QueryBBReg(Adapter, rFPGA0_XAB_RFParameter, | ||
1038 | bMaskDWord); | ||
1039 | Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] = | ||
1040 | PHY_QueryBBReg(Adapter, rOFDM0_TRxPathEnable, | ||
1041 | bMaskDWord); | ||
1042 | Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] = | ||
1043 | PHY_QueryBBReg(Adapter, rFPGA0_RFMOD, | ||
1044 | bMaskDWord); | ||
1045 | if (pHalData->rf_type == RF_2T2R) { | ||
1046 | PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, | ||
1047 | 0x380038, 0); | ||
1048 | } else if (pHalData->rf_type == RF_1T1R) { | ||
1049 | PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, | ||
1050 | 0x38, 0); | ||
1051 | } | ||
1052 | PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0); | ||
1053 | PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT1, 1); | ||
1054 | |||
1055 | /* 2 .AFE control register to power down. bit[30:22] */ | ||
1056 | Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] = | ||
1057 | PHY_QueryBBReg(Adapter, rRx_Wait_CCA, | ||
1058 | bMaskDWord); | ||
1059 | if (pHalData->rf_type == RF_2T2R) | ||
1060 | PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, | ||
1061 | 0x00DB25A0); | ||
1062 | else if (pHalData->rf_type == RF_1T1R) | ||
1063 | PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, | ||
1064 | 0x001B25A0); | ||
1065 | |||
1066 | /* 3. issue 3-wire command that RF set to power down.*/ | ||
1067 | PHY_SetRFReg(Adapter, RF_PATH_A, 0, bRFRegOffsetMask, 0); | ||
1068 | if (pHalData->rf_type == RF_2T2R) | ||
1069 | PHY_SetRFReg(Adapter, RF_PATH_B, 0, | ||
1070 | bRFRegOffsetMask, 0); | ||
1071 | |||
1072 | /* 4. Force PFM , disable SPS18_LDO_Marco_Block */ | ||
1073 | rtw_write8(Adapter, REG_SPS0_CTRL, value8); | ||
1074 | } else { /* Level 2 or others. */ | ||
1075 | RT_TRACE(_module_hal_init_c_, _drv_err_, ("SS LVL2\n")); | ||
1076 | { | ||
1077 | u8 eRFPath = RF_PATH_A, value8 = 0; | ||
1078 | rtw_write8(Adapter, REG_TXPAUSE, 0xFF); | ||
1079 | PHY_SetRFReg(Adapter, | ||
1080 | (enum RF_RADIO_PATH)eRFPath, | ||
1081 | 0x0, bMaskByte0, 0x0); | ||
1082 | value8 |= APSDOFF; | ||
1083 | /* 0x40 */ | ||
1084 | rtw_write8(Adapter, REG_APSD_CTRL, value8); | ||
1085 | |||
1086 | /* After switch APSD, we need to delay | ||
1087 | for stability */ | ||
1088 | mdelay(10); | ||
1089 | |||
1090 | /* Set BB reset at first */ | ||
1091 | value8 = 0 ; | ||
1092 | value8 |= (FEN_USBD | FEN_USBA | | ||
1093 | FEN_BB_GLB_RSTn); | ||
1094 | /* 0x16 */ | ||
1095 | rtw_write8(Adapter, REG_SYS_FUNC_EN, value8); | ||
1096 | } | ||
1097 | |||
1098 | /* Disable RF and BB only for SelectSuspend. */ | ||
1099 | |||
1100 | /* 1. Set BB/RF to shutdown. */ | ||
1101 | /* (1) Reg878[5:3]= 0 RF rx_code for | ||
1102 | preamble power saving */ | ||
1103 | /* (2)Reg878[21:19]= 0 Turn off RF-B */ | ||
1104 | /* (3) RegC04[7:4]= 0 Turn off all paths for | ||
1105 | packet detection */ | ||
1106 | /* (4) Reg800[1] = 1 enable preamble power | ||
1107 | saving */ | ||
1108 | Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] = | ||
1109 | PHY_QueryBBReg(Adapter, rFPGA0_XAB_RFParameter, | ||
1110 | bMaskDWord); | ||
1111 | Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] = | ||
1112 | PHY_QueryBBReg(Adapter, rOFDM0_TRxPathEnable, | ||
1113 | bMaskDWord); | ||
1114 | Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] = | ||
1115 | PHY_QueryBBReg(Adapter, rFPGA0_RFMOD, | ||
1116 | bMaskDWord); | ||
1117 | if (pHalData->rf_type == RF_2T2R) | ||
1118 | PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, | ||
1119 | 0x380038, 0); | ||
1120 | else if (pHalData->rf_type == RF_1T1R) | ||
1121 | PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, | ||
1122 | 0x38, 0); | ||
1123 | PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0); | ||
1124 | PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT1, 1); | ||
1125 | |||
1126 | /* 2 .AFE control register to power down. bit[30:22] */ | ||
1127 | Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] = | ||
1128 | PHY_QueryBBReg(Adapter, rRx_Wait_CCA, | ||
1129 | bMaskDWord); | ||
1130 | if (pHalData->rf_type == RF_2T2R) | ||
1131 | PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, | ||
1132 | 0x00DB25A0); | ||
1133 | else if (pHalData->rf_type == RF_1T1R) | ||
1134 | PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord, | ||
1135 | 0x001B25A0); | ||
1136 | |||
1137 | /* 3. issue 3-wire command that RF set to power down. */ | ||
1138 | PHY_SetRFReg(Adapter, RF_PATH_A, 0, bRFRegOffsetMask, 0); | ||
1139 | if (pHalData->rf_type == RF_2T2R) | ||
1140 | PHY_SetRFReg(Adapter, RF_PATH_B, 0, | ||
1141 | bRFRegOffsetMask, 0); | ||
1142 | |||
1143 | /* 4. Force PFM , disable SPS18_LDO_Marco_Block */ | ||
1144 | rtw_write8(Adapter, REG_SPS0_CTRL, value8); | ||
1145 | |||
1146 | /* 2010/10/13 MH/Isaachsu exchange sequence. */ | ||
1147 | /* h. AFE_PLL_CTRL 0x28[7:0] = 0x80 | ||
1148 | disable AFE PLL */ | ||
1149 | rtw_write8(Adapter, REG_AFE_PLL_CTRL, 0x80); | ||
1150 | mdelay(1); | ||
1151 | |||
1152 | /* i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F | ||
1153 | gated AFE DIG_CLOCK */ | ||
1154 | rtw_write16(Adapter, REG_AFE_XTAL_CTRL, 0xA80F); | ||
1155 | } | ||
1156 | break; | ||
1157 | default: | ||
1158 | break; | ||
1159 | } | ||
1160 | |||
1161 | } /* phy_PowerSwitch92CU */ | ||
1162 | |||
1163 | void _ps_open_RF23a(struct rtw_adapter *padapter) | ||
1164 | { | ||
1165 | /* here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified */ | ||
1166 | phy_SsPwrSwitch92CU(padapter, rf_on, 1); | ||
1167 | } | ||
1168 | |||
1169 | static void CardDisableRTL8723U(struct rtw_adapter *Adapter) | ||
1170 | { | ||
1171 | u8 u1bTmp; | ||
1172 | |||
1173 | DBG_8723A("CardDisableRTL8723U\n"); | ||
1174 | /* USB-MF Card Disable Flow */ | ||
1175 | /* 1. Run LPS WL RFOFF flow */ | ||
1176 | HalPwrSeqCmdParsing23a(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, | ||
1177 | PWR_INTF_USB_MSK, rtl8723AU_enter_lps_flow); | ||
1178 | |||
1179 | /* 2. 0x1F[7:0] = 0 turn off RF */ | ||
1180 | rtw_write8(Adapter, REG_RF_CTRL, 0x00); | ||
1181 | |||
1182 | /* ==== Reset digital sequence ====== */ | ||
1183 | if ((rtw_read8(Adapter, REG_MCUFWDL)&BIT7) && | ||
1184 | Adapter->bFWReady) /* 8051 RAM code */ | ||
1185 | rtl8723a_FirmwareSelfReset(Adapter); | ||
1186 | |||
1187 | /* Reset MCU. Suggested by Filen. 2011.01.26. by tynli. */ | ||
1188 | u1bTmp = rtw_read8(Adapter, REG_SYS_FUNC_EN+1); | ||
1189 | rtw_write8(Adapter, REG_SYS_FUNC_EN+1, (u1bTmp & (~BIT2))); | ||
1190 | |||
1191 | /* g. MCUFWDL 0x80[1:0]= 0 reset MCU ready status */ | ||
1192 | rtw_write8(Adapter, REG_MCUFWDL, 0x00); | ||
1193 | |||
1194 | /* ==== Reset digital sequence end ====== */ | ||
1195 | /* Card disable power action flow */ | ||
1196 | HalPwrSeqCmdParsing23a(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, | ||
1197 | PWR_INTF_USB_MSK, | ||
1198 | rtl8723AU_card_disable_flow); | ||
1199 | |||
1200 | /* Reset MCU IO Wrapper, added by Roger, 2011.08.30. */ | ||
1201 | u1bTmp = rtw_read8(Adapter, REG_RSV_CTRL + 1); | ||
1202 | rtw_write8(Adapter, REG_RSV_CTRL+1, (u1bTmp & (~BIT0))); | ||
1203 | u1bTmp = rtw_read8(Adapter, REG_RSV_CTRL + 1); | ||
1204 | rtw_write8(Adapter, REG_RSV_CTRL+1, u1bTmp | BIT0); | ||
1205 | |||
1206 | /* 7. RSV_CTRL 0x1C[7:0] = 0x0E lock ISO/CLK/Power control register */ | ||
1207 | rtw_write8(Adapter, REG_RSV_CTRL, 0x0e); | ||
1208 | } | ||
1209 | |||
1210 | static u32 rtl8723au_hal_deinit(struct rtw_adapter *padapter) | ||
1211 | { | ||
1212 | DBG_8723A("==> %s\n", __func__); | ||
1213 | |||
1214 | #ifdef CONFIG_8723AU_BT_COEXIST | ||
1215 | BT_HaltProcess(padapter); | ||
1216 | #endif | ||
1217 | /* 2011/02/18 To Fix RU LNA power leakage problem. We need to | ||
1218 | execute below below in Adapter init and halt sequence. | ||
1219 | According to EEchou's opinion, we can enable the ability for all */ | ||
1220 | /* IC. Accord to johnny's opinion, only RU need the support. */ | ||
1221 | CardDisableRTL8723U(padapter); | ||
1222 | |||
1223 | return _SUCCESS; | ||
1224 | } | ||
1225 | |||
1226 | static unsigned int rtl8723au_inirp_init(struct rtw_adapter *Adapter) | ||
1227 | { | ||
1228 | u8 i; | ||
1229 | struct recv_buf *precvbuf; | ||
1230 | uint status; | ||
1231 | struct intf_hdl *pintfhdl = &Adapter->iopriv.intf; | ||
1232 | struct recv_priv *precvpriv = &Adapter->recvpriv; | ||
1233 | u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, | ||
1234 | struct recv_buf *rbuf); | ||
1235 | u32 (*_read_interrupt)(struct intf_hdl *pintfhdl, u32 addr); | ||
1236 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1237 | |||
1238 | _read_port = pintfhdl->io_ops._read_port; | ||
1239 | |||
1240 | status = _SUCCESS; | ||
1241 | |||
1242 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("===> usb_inirp_init\n")); | ||
1243 | |||
1244 | precvpriv->ff_hwaddr = RECV_BULK_IN_ADDR; | ||
1245 | |||
1246 | /* issue Rx irp to receive data */ | ||
1247 | precvbuf = (struct recv_buf *)precvpriv->precv_buf; | ||
1248 | for (i = 0; i < NR_RECVBUFF; i++) { | ||
1249 | if (_read_port(pintfhdl, precvpriv->ff_hwaddr, 0, precvbuf) == | ||
1250 | false) { | ||
1251 | RT_TRACE(_module_hci_hal_init_c_, _drv_err_, | ||
1252 | ("usb_rx_init: usb_read_port error\n")); | ||
1253 | status = _FAIL; | ||
1254 | goto exit; | ||
1255 | } | ||
1256 | precvbuf++; | ||
1257 | precvpriv->free_recv_buf_queue_cnt--; | ||
1258 | } | ||
1259 | _read_interrupt = pintfhdl->io_ops._read_interrupt; | ||
1260 | if (_read_interrupt(pintfhdl, RECV_INT_IN_ADDR) == false) { | ||
1261 | RT_TRACE(_module_hci_hal_init_c_, _drv_err_, | ||
1262 | ("usb_rx_init: usb_read_interrupt error\n")); | ||
1263 | status = _FAIL; | ||
1264 | } | ||
1265 | pHalData->IntrMask[0] = rtw_read32(Adapter, REG_USB_HIMR); | ||
1266 | MSG_8723A("pHalData->IntrMask = 0x%04x\n", pHalData->IntrMask[0]); | ||
1267 | pHalData->IntrMask[0] |= UHIMR_C2HCMD|UHIMR_CPWM; | ||
1268 | rtw_write32(Adapter, REG_USB_HIMR, pHalData->IntrMask[0]); | ||
1269 | exit: | ||
1270 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
1271 | ("<=== usb_inirp_init\n")); | ||
1272 | return status; | ||
1273 | } | ||
1274 | |||
1275 | static unsigned int rtl8723au_inirp_deinit(struct rtw_adapter *Adapter) | ||
1276 | { | ||
1277 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1278 | |||
1279 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
1280 | ("\n ===> usb_rx_deinit\n")); | ||
1281 | rtw_read_port_cancel(Adapter); | ||
1282 | pHalData->IntrMask[0] = rtw_read32(Adapter, REG_USB_HIMR); | ||
1283 | MSG_8723A("%s pHalData->IntrMask = 0x%04x\n", __func__, | ||
1284 | pHalData->IntrMask[0]); | ||
1285 | pHalData->IntrMask[0] = 0x0; | ||
1286 | rtw_write32(Adapter, REG_USB_HIMR, pHalData->IntrMask[0]); | ||
1287 | RT_TRACE(_module_hci_hal_init_c_, _drv_info_, | ||
1288 | ("\n <=== usb_rx_deinit\n")); | ||
1289 | return _SUCCESS; | ||
1290 | } | ||
1291 | |||
1292 | static void _ReadBoardType(struct rtw_adapter *Adapter, u8 *PROMContent, | ||
1293 | bool AutoloadFail) | ||
1294 | { | ||
1295 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1296 | u8 boardType = BOARD_USB_DONGLE; | ||
1297 | |||
1298 | if (AutoloadFail) { | ||
1299 | if (IS_8723_SERIES(pHalData->VersionID)) | ||
1300 | pHalData->rf_type = RF_1T1R; | ||
1301 | else | ||
1302 | pHalData->rf_type = RF_2T2R; | ||
1303 | pHalData->BoardType = boardType; | ||
1304 | return; | ||
1305 | } | ||
1306 | |||
1307 | boardType = PROMContent[EEPROM_NORMAL_BoardType]; | ||
1308 | boardType &= BOARD_TYPE_NORMAL_MASK;/* bit[7:5] */ | ||
1309 | boardType >>= 5; | ||
1310 | |||
1311 | pHalData->BoardType = boardType; | ||
1312 | MSG_8723A("_ReadBoardType(%x)\n", pHalData->BoardType); | ||
1313 | |||
1314 | if (boardType == BOARD_USB_High_PA) | ||
1315 | pHalData->ExternalPA = 1; | ||
1316 | } | ||
1317 | |||
1318 | static void _ReadLEDSetting(struct rtw_adapter *Adapter, u8 *PROMContent, | ||
1319 | bool AutoloadFail) | ||
1320 | { | ||
1321 | struct led_priv *pledpriv = &Adapter->ledpriv; | ||
1322 | |||
1323 | pledpriv->LedStrategy = HW_LED; | ||
1324 | } | ||
1325 | |||
1326 | static void Hal_EfuseParsePIDVID_8723AU(struct rtw_adapter *pAdapter, | ||
1327 | u8 *hwinfo, bool AutoLoadFail) | ||
1328 | { | ||
1329 | struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); | ||
1330 | |||
1331 | if (AutoLoadFail) { | ||
1332 | pHalData->EEPROMVID = 0; | ||
1333 | pHalData->EEPROMPID = 0; | ||
1334 | } else { | ||
1335 | /* VID, PID */ | ||
1336 | pHalData->EEPROMVID = | ||
1337 | le16_to_cpu(*(u16 *)&hwinfo[EEPROM_VID_8723AU]); | ||
1338 | pHalData->EEPROMPID = | ||
1339 | le16_to_cpu(*(u16 *)&hwinfo[EEPROM_PID_8723AU]); | ||
1340 | } | ||
1341 | |||
1342 | MSG_8723A("EEPROM VID = 0x%4x\n", pHalData->EEPROMVID); | ||
1343 | MSG_8723A("EEPROM PID = 0x%4x\n", pHalData->EEPROMPID); | ||
1344 | } | ||
1345 | |||
1346 | static void Hal_EfuseParseMACAddr_8723AU(struct rtw_adapter *padapter, | ||
1347 | u8 *hwinfo, bool AutoLoadFail) | ||
1348 | { | ||
1349 | u16 i; | ||
1350 | u8 sMacAddr[ETH_ALEN] = {0x00, 0xE0, 0x4C, 0x87, 0x23, 0x00}; | ||
1351 | struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); | ||
1352 | |||
1353 | if (AutoLoadFail) { | ||
1354 | for (i = 0; i < 6; i++) | ||
1355 | pEEPROM->mac_addr[i] = sMacAddr[i]; | ||
1356 | } else { | ||
1357 | /* Read Permanent MAC address */ | ||
1358 | memcpy(pEEPROM->mac_addr, &hwinfo[EEPROM_MAC_ADDR_8723AU], | ||
1359 | ETH_ALEN); | ||
1360 | } | ||
1361 | |||
1362 | RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, | ||
1363 | ("Hal_EfuseParseMACAddr_8723AU: Permanent Address =%02x:%02x:" | ||
1364 | "%02x:%02x:%02x:%02x\n", | ||
1365 | pEEPROM->mac_addr[0], pEEPROM->mac_addr[1], | ||
1366 | pEEPROM->mac_addr[2], pEEPROM->mac_addr[3], | ||
1367 | pEEPROM->mac_addr[4], pEEPROM->mac_addr[5])); | ||
1368 | } | ||
1369 | |||
1370 | static void readAdapterInfo(struct rtw_adapter *padapter) | ||
1371 | { | ||
1372 | struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); | ||
1373 | /* struct hal_data_8723a * pHalData = GET_HAL_DATA(padapter); */ | ||
1374 | u8 hwinfo[HWSET_MAX_SIZE]; | ||
1375 | |||
1376 | Hal_InitPGData(padapter, hwinfo); | ||
1377 | Hal_EfuseParseIDCode(padapter, hwinfo); | ||
1378 | Hal_EfuseParsePIDVID_8723AU(padapter, hwinfo, | ||
1379 | pEEPROM->bautoload_fail_flag); | ||
1380 | Hal_EfuseParseEEPROMVer(padapter, hwinfo, | ||
1381 | pEEPROM->bautoload_fail_flag); | ||
1382 | Hal_EfuseParseMACAddr_8723AU(padapter, hwinfo, | ||
1383 | pEEPROM->bautoload_fail_flag); | ||
1384 | Hal_EfuseParsetxpowerinfo_8723A(padapter, hwinfo, | ||
1385 | pEEPROM->bautoload_fail_flag); | ||
1386 | _ReadBoardType(padapter, hwinfo, pEEPROM->bautoload_fail_flag); | ||
1387 | Hal_EfuseParseBTCoexistInfo_8723A(padapter, hwinfo, | ||
1388 | pEEPROM->bautoload_fail_flag); | ||
1389 | |||
1390 | rtl8723a_EfuseParseChnlPlan(padapter, hwinfo, | ||
1391 | pEEPROM->bautoload_fail_flag); | ||
1392 | Hal_EfuseParseThermalMeter_8723A(padapter, hwinfo, | ||
1393 | pEEPROM->bautoload_fail_flag); | ||
1394 | _ReadLEDSetting(padapter, hwinfo, pEEPROM->bautoload_fail_flag); | ||
1395 | /* _ReadRFSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); */ | ||
1396 | /* _ReadPSSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); */ | ||
1397 | Hal_EfuseParseAntennaDiversity(padapter, hwinfo, | ||
1398 | pEEPROM->bautoload_fail_flag); | ||
1399 | |||
1400 | Hal_EfuseParseEEPROMVer(padapter, hwinfo, pEEPROM->bautoload_fail_flag); | ||
1401 | Hal_EfuseParseCustomerID(padapter, hwinfo, | ||
1402 | pEEPROM->bautoload_fail_flag); | ||
1403 | Hal_EfuseParseRateIndicationOption(padapter, hwinfo, | ||
1404 | pEEPROM->bautoload_fail_flag); | ||
1405 | Hal_EfuseParseXtal_8723A(padapter, hwinfo, | ||
1406 | pEEPROM->bautoload_fail_flag); | ||
1407 | /* */ | ||
1408 | /* The following part initialize some vars by PG info. */ | ||
1409 | /* */ | ||
1410 | Hal_InitChannelPlan23a(padapter); | ||
1411 | |||
1412 | /* hal_CustomizedBehavior_8723U(Adapter); */ | ||
1413 | |||
1414 | /* Adapter->bDongle = (PROMContent[EEPROM_EASY_REPLACEMENT] == 1)? 0: 1; */ | ||
1415 | DBG_8723A("%s(): REPLACEMENT = %x\n", __func__, padapter->bDongle); | ||
1416 | } | ||
1417 | |||
1418 | static void _ReadPROMContent(struct rtw_adapter *Adapter) | ||
1419 | { | ||
1420 | struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter); | ||
1421 | u8 eeValue; | ||
1422 | |||
1423 | eeValue = rtw_read8(Adapter, REG_9346CR); | ||
1424 | /* To check system boot selection. */ | ||
1425 | pEEPROM->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false; | ||
1426 | pEEPROM->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true; | ||
1427 | |||
1428 | DBG_8723A("Boot from %s, Autoload %s !\n", | ||
1429 | (pEEPROM->EepromOrEfuse ? "EEPROM" : "EFUSE"), | ||
1430 | (pEEPROM->bautoload_fail_flag ? "Fail" : "OK")); | ||
1431 | |||
1432 | readAdapterInfo(Adapter); | ||
1433 | } | ||
1434 | |||
1435 | static void _ReadRFType(struct rtw_adapter *Adapter) | ||
1436 | { | ||
1437 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1438 | |||
1439 | pHalData->rf_chip = RF_6052; | ||
1440 | } | ||
1441 | |||
1442 | static void _ReadSilmComboMode(struct rtw_adapter *Adapter) | ||
1443 | { | ||
1444 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1445 | |||
1446 | pHalData->SlimComboDbg = false; /* Default is not debug mode. */ | ||
1447 | } | ||
1448 | |||
1449 | /* */ | ||
1450 | /* Description: */ | ||
1451 | /* We should set Efuse cell selection to WiFi cell in default. */ | ||
1452 | /* */ | ||
1453 | /* Assumption: */ | ||
1454 | /* PASSIVE_LEVEL */ | ||
1455 | /* */ | ||
1456 | /* Added by Roger, 2010.11.23. */ | ||
1457 | /* */ | ||
1458 | static void hal_EfuseCellSel(struct rtw_adapter *Adapter) | ||
1459 | { | ||
1460 | u32 value32; | ||
1461 | |||
1462 | value32 = rtw_read32(Adapter, EFUSE_TEST); | ||
1463 | value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0); | ||
1464 | rtw_write32(Adapter, EFUSE_TEST, value32); | ||
1465 | } | ||
1466 | |||
1467 | static int _ReadAdapterInfo8723AU(struct rtw_adapter *Adapter) | ||
1468 | { | ||
1469 | /* struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); */ | ||
1470 | unsigned long start = jiffies; | ||
1471 | |||
1472 | MSG_8723A("====> _ReadAdapterInfo8723AU\n"); | ||
1473 | |||
1474 | hal_EfuseCellSel(Adapter); | ||
1475 | |||
1476 | _ReadRFType(Adapter);/* rf_chip -> _InitRFType() */ | ||
1477 | _ReadPROMContent(Adapter); | ||
1478 | |||
1479 | /* 2010/10/25 MH THe function must be called after | ||
1480 | borad_type & IC-Version recognize. */ | ||
1481 | _ReadSilmComboMode(Adapter); | ||
1482 | |||
1483 | /* MSG_8723A("%s()(done), rf_chip = 0x%x, rf_type = 0x%x\n", | ||
1484 | __func__, pHalData->rf_chip, pHalData->rf_type); */ | ||
1485 | |||
1486 | MSG_8723A("<==== _ReadAdapterInfo8723AU in %d ms\n", | ||
1487 | jiffies_to_msecs(jiffies - start)); | ||
1488 | |||
1489 | return _SUCCESS; | ||
1490 | } | ||
1491 | |||
1492 | static void ReadAdapterInfo8723AU(struct rtw_adapter *Adapter) | ||
1493 | { | ||
1494 | /* Read EEPROM size before call any EEPROM function */ | ||
1495 | Adapter->EepromAddressSize = GetEEPROMSize8723A(Adapter); | ||
1496 | |||
1497 | _ReadAdapterInfo8723AU(Adapter); | ||
1498 | } | ||
1499 | |||
1500 | #define GPIO_DEBUG_PORT_NUM 0 | ||
1501 | static void rtl8723au_trigger_gpio_0(struct rtw_adapter *padapter) | ||
1502 | { | ||
1503 | u32 gpioctrl; | ||
1504 | DBG_8723A("==> trigger_gpio_0...\n"); | ||
1505 | rtw_write16_async(padapter, REG_GPIO_PIN_CTRL, 0); | ||
1506 | rtw_write8_async(padapter, REG_GPIO_PIN_CTRL+2, 0xFF); | ||
1507 | gpioctrl = (BIT(GPIO_DEBUG_PORT_NUM) << 24)| | ||
1508 | (BIT(GPIO_DEBUG_PORT_NUM) << 16); | ||
1509 | rtw_write32_async(padapter, REG_GPIO_PIN_CTRL, gpioctrl); | ||
1510 | gpioctrl |= (BIT(GPIO_DEBUG_PORT_NUM)<<8); | ||
1511 | rtw_write32_async(padapter, REG_GPIO_PIN_CTRL, gpioctrl); | ||
1512 | DBG_8723A("<=== trigger_gpio_0...\n"); | ||
1513 | } | ||
1514 | |||
1515 | /* | ||
1516 | * If variable not handled here, | ||
1517 | * some variables will be processed in SetHwReg8723A() | ||
1518 | */ | ||
1519 | static void SetHwReg8723AU(struct rtw_adapter *Adapter, u8 variable, u8 *val) | ||
1520 | { | ||
1521 | switch (variable) { | ||
1522 | case HW_VAR_RXDMA_AGG_PG_TH: | ||
1523 | break; | ||
1524 | case HW_VAR_SET_RPWM: | ||
1525 | rtl8723a_set_rpwm(Adapter, *val); | ||
1526 | break; | ||
1527 | case HW_VAR_TRIGGER_GPIO_0: | ||
1528 | rtl8723au_trigger_gpio_0(Adapter); | ||
1529 | break; | ||
1530 | default: | ||
1531 | SetHwReg8723A(Adapter, variable, val); | ||
1532 | break; | ||
1533 | } | ||
1534 | |||
1535 | } | ||
1536 | |||
1537 | /* | ||
1538 | * If variable not handled here, | ||
1539 | * some variables will be processed in GetHwReg8723A() | ||
1540 | */ | ||
1541 | static void GetHwReg8723AU(struct rtw_adapter *Adapter, u8 variable, u8 *val) | ||
1542 | { | ||
1543 | GetHwReg8723A(Adapter, variable, val); | ||
1544 | } | ||
1545 | |||
1546 | /* */ | ||
1547 | /* Description: */ | ||
1548 | /* Query setting of specified variable. */ | ||
1549 | /* */ | ||
1550 | static u8 GetHalDefVar8192CUsb(struct rtw_adapter *Adapter, | ||
1551 | enum hal_def_variable eVariable, void *pValue) | ||
1552 | { | ||
1553 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1554 | u8 bResult = _SUCCESS; | ||
1555 | |||
1556 | switch (eVariable) { | ||
1557 | case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB: | ||
1558 | *((int *)pValue) = pHalData->dmpriv.UndecoratedSmoothedPWDB; | ||
1559 | break; | ||
1560 | case HAL_DEF_IS_SUPPORT_ANT_DIV: | ||
1561 | break; | ||
1562 | case HAL_DEF_CURRENT_ANTENNA: | ||
1563 | break; | ||
1564 | case HAL_DEF_DRVINFO_SZ: | ||
1565 | *((u32 *)pValue) = DRVINFO_SZ; | ||
1566 | break; | ||
1567 | case HAL_DEF_MAX_RECVBUF_SZ: | ||
1568 | *((u32 *)pValue) = MAX_RECVBUF_SZ; | ||
1569 | break; | ||
1570 | case HAL_DEF_RX_PACKET_OFFSET: | ||
1571 | *((u32 *)pValue) = RXDESC_SIZE + DRVINFO_SZ; | ||
1572 | break; | ||
1573 | case HAL_DEF_DBG_DUMP_RXPKT: | ||
1574 | *((u8 *)pValue) = pHalData->bDumpRxPkt; | ||
1575 | break; | ||
1576 | case HAL_DEF_DBG_DM_FUNC: | ||
1577 | *((u32 *)pValue) = pHalData->odmpriv.SupportAbility; | ||
1578 | break; | ||
1579 | case HW_VAR_MAX_RX_AMPDU_FACTOR: | ||
1580 | *((u32 *)pValue) = IEEE80211_HT_MAX_AMPDU_64K; | ||
1581 | break; | ||
1582 | case HW_DEF_ODM_DBG_FLAG: | ||
1583 | { | ||
1584 | struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; | ||
1585 | printk("pDM_Odm->DebugComponents = 0x%llx\n", | ||
1586 | pDM_Odm->DebugComponents); | ||
1587 | } | ||
1588 | break; | ||
1589 | default: | ||
1590 | /* RT_TRACE(COMP_INIT, DBG_WARNING, ("GetHalDefVar8192CUsb(): " | ||
1591 | "Unkown variable: %d!\n", eVariable)); */ | ||
1592 | bResult = _FAIL; | ||
1593 | break; | ||
1594 | } | ||
1595 | |||
1596 | return bResult; | ||
1597 | } | ||
1598 | |||
1599 | /* Change default setting of specified variable. */ | ||
1600 | static u8 SetHalDefVar8192CUsb(struct rtw_adapter *Adapter, | ||
1601 | enum hal_def_variable eVariable, void *pValue) | ||
1602 | { | ||
1603 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
1604 | u8 bResult = _SUCCESS; | ||
1605 | |||
1606 | switch (eVariable) { | ||
1607 | case HAL_DEF_DBG_DUMP_RXPKT: | ||
1608 | pHalData->bDumpRxPkt = *((u8 *)pValue); | ||
1609 | break; | ||
1610 | case HAL_DEF_DBG_DM_FUNC: | ||
1611 | { | ||
1612 | u8 dm_func = *((u8 *)pValue); | ||
1613 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
1614 | struct dm_odm_t *podmpriv = &pHalData->odmpriv; | ||
1615 | |||
1616 | if (dm_func == 0) { /* disable all dynamic func */ | ||
1617 | podmpriv->SupportAbility = DYNAMIC_FUNC_DISABLE; | ||
1618 | DBG_8723A("==> Disable all dynamic function...\n"); | ||
1619 | } else if (dm_func == 1) {/* disable DIG */ | ||
1620 | podmpriv->SupportAbility &= (~DYNAMIC_BB_DIG); | ||
1621 | DBG_8723A("==> Disable DIG...\n"); | ||
1622 | } else if (dm_func == 2) {/* disable High power */ | ||
1623 | podmpriv->SupportAbility &= (~DYNAMIC_BB_DYNAMIC_TXPWR); | ||
1624 | } else if (dm_func == 3) {/* disable tx power tracking */ | ||
1625 | podmpriv->SupportAbility &= (~DYNAMIC_RF_CALIBRATION); | ||
1626 | DBG_8723A("==> Disable tx power tracking...\n"); | ||
1627 | } else if (dm_func == 4) {/* disable BT coexistence */ | ||
1628 | pdmpriv->DMFlag &= (~DYNAMIC_FUNC_BT); | ||
1629 | } else if (dm_func == 5) {/* disable antenna diversity */ | ||
1630 | podmpriv->SupportAbility &= (~DYNAMIC_BB_ANT_DIV); | ||
1631 | } else if (dm_func == 6) {/* turn on all dynamic func */ | ||
1632 | if (!(podmpriv->SupportAbility & DYNAMIC_BB_DIG)) { | ||
1633 | struct dig_t *pDigTable = | ||
1634 | &podmpriv->DM_DigTable; | ||
1635 | pDigTable->CurIGValue = rtw_read8(Adapter, 0xc50); | ||
1636 | } | ||
1637 | pdmpriv->DMFlag |= DYNAMIC_FUNC_BT; | ||
1638 | podmpriv->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE; | ||
1639 | DBG_8723A("==> Turn on all dynamic function...\n"); | ||
1640 | } | ||
1641 | } | ||
1642 | break; | ||
1643 | case HW_DEF_FA_CNT_DUMP: | ||
1644 | { | ||
1645 | u8 bRSSIDump = *((u8 *)pValue); | ||
1646 | struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; | ||
1647 | if (bRSSIDump) | ||
1648 | pDM_Odm->DebugComponents = ODM_COMP_DIG|ODM_COMP_FA_CNT; | ||
1649 | else | ||
1650 | pDM_Odm->DebugComponents = 0; | ||
1651 | } | ||
1652 | break; | ||
1653 | case HW_DEF_ODM_DBG_FLAG: | ||
1654 | { | ||
1655 | u64 DebugComponents = *((u64 *)pValue); | ||
1656 | struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; | ||
1657 | pDM_Odm->DebugComponents = DebugComponents; | ||
1658 | } | ||
1659 | break; | ||
1660 | default: | ||
1661 | /* RT_TRACE(COMP_INIT, DBG_TRACE, ("SetHalDefVar819xUsb(): " | ||
1662 | "Unkown variable: %d!\n", eVariable)); */ | ||
1663 | bResult = _FAIL; | ||
1664 | break; | ||
1665 | } | ||
1666 | |||
1667 | return bResult; | ||
1668 | } | ||
1669 | |||
1670 | static void UpdateHalRAMask8192CUsb(struct rtw_adapter *padapter, | ||
1671 | u32 mac_id, u8 rssi_level) | ||
1672 | { | ||
1673 | u8 init_rate = 0; | ||
1674 | u8 networkType, raid; | ||
1675 | u32 mask, rate_bitmap; | ||
1676 | u8 shortGIrate = false; | ||
1677 | int supportRateNum = 0; | ||
1678 | struct sta_info *psta; | ||
1679 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
1680 | struct dm_priv *pdmpriv = &pHalData->dmpriv; | ||
1681 | struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; | ||
1682 | struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; | ||
1683 | struct wlan_bssid_ex *cur_network = &pmlmeinfo->network; | ||
1684 | |||
1685 | if (mac_id >= NUM_STA) /* CAM_SIZE */ | ||
1686 | return; | ||
1687 | |||
1688 | psta = pmlmeinfo->FW_sta_info[mac_id].psta; | ||
1689 | if (psta == NULL) | ||
1690 | return; | ||
1691 | |||
1692 | switch (mac_id) { | ||
1693 | case 0:/* for infra mode */ | ||
1694 | supportRateNum = | ||
1695 | rtw_get_rateset_len23a(cur_network->SupportedRates); | ||
1696 | networkType = judge_network_type23a(padapter, | ||
1697 | cur_network->SupportedRates, | ||
1698 | supportRateNum) & 0xf; | ||
1699 | /* pmlmeext->cur_wireless_mode = networkType; */ | ||
1700 | raid = networktype_to_raid23a(networkType); | ||
1701 | |||
1702 | mask = update_supported_rate23a(cur_network->SupportedRates, | ||
1703 | supportRateNum); | ||
1704 | mask |= (pmlmeinfo->HT_enable) ? | ||
1705 | update_MSC_rate23a(&pmlmeinfo->HT_caps) : 0; | ||
1706 | |||
1707 | if (support_short_GI23a(padapter, &pmlmeinfo->HT_caps)) | ||
1708 | shortGIrate = true; | ||
1709 | break; | ||
1710 | |||
1711 | case 1:/* for broadcast/multicast */ | ||
1712 | supportRateNum = rtw_get_rateset_len23a( | ||
1713 | pmlmeinfo->FW_sta_info[mac_id].SupportedRates); | ||
1714 | if (pmlmeext->cur_wireless_mode & WIRELESS_11B) | ||
1715 | networkType = WIRELESS_11B; | ||
1716 | else | ||
1717 | networkType = WIRELESS_11G; | ||
1718 | raid = networktype_to_raid23a(networkType); | ||
1719 | |||
1720 | mask = update_basic_rate23a(cur_network->SupportedRates, | ||
1721 | supportRateNum); | ||
1722 | break; | ||
1723 | |||
1724 | default: /* for each sta in IBSS */ | ||
1725 | supportRateNum = rtw_get_rateset_len23a( | ||
1726 | pmlmeinfo->FW_sta_info[mac_id].SupportedRates); | ||
1727 | networkType = judge_network_type23a(padapter, | ||
1728 | pmlmeinfo->FW_sta_info[mac_id].SupportedRates, | ||
1729 | supportRateNum) & 0xf; | ||
1730 | /* pmlmeext->cur_wireless_mode = networkType; */ | ||
1731 | raid = networktype_to_raid23a(networkType); | ||
1732 | |||
1733 | mask = update_supported_rate23a(cur_network->SupportedRates, | ||
1734 | supportRateNum); | ||
1735 | |||
1736 | /* todo: support HT in IBSS */ | ||
1737 | break; | ||
1738 | } | ||
1739 | |||
1740 | /* mask &= 0x0fffffff; */ | ||
1741 | rate_bitmap = 0x0fffffff; | ||
1742 | rate_bitmap = ODM_Get_Rate_Bitmap23a(&pHalData->odmpriv, | ||
1743 | mac_id, mask, rssi_level); | ||
1744 | printk(KERN_DEBUG "%s => mac_id:%d, networkType:0x%02x, " | ||
1745 | "mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n", | ||
1746 | __func__, | ||
1747 | mac_id, networkType, mask, rssi_level, rate_bitmap); | ||
1748 | |||
1749 | mask &= rate_bitmap; | ||
1750 | mask |= ((raid<<28)&0xf0000000); | ||
1751 | |||
1752 | init_rate = get_highest_rate_idx23a(mask)&0x3f; | ||
1753 | |||
1754 | if (pHalData->fw_ractrl == true) { | ||
1755 | u8 arg = 0; | ||
1756 | |||
1757 | /* arg = (cam_idx-4)&0x1f;MACID */ | ||
1758 | arg = mac_id&0x1f;/* MACID */ | ||
1759 | |||
1760 | arg |= BIT(7); | ||
1761 | |||
1762 | if (shortGIrate == true) | ||
1763 | arg |= BIT(5); | ||
1764 | |||
1765 | DBG_8723A("update raid entry, mask = 0x%x, arg = 0x%x\n", | ||
1766 | mask, arg); | ||
1767 | |||
1768 | rtl8723a_set_raid_cmd(padapter, mask, arg); | ||
1769 | } else { | ||
1770 | if (shortGIrate == true) | ||
1771 | init_rate |= BIT(6); | ||
1772 | |||
1773 | rtw_write8(padapter, (REG_INIDATA_RATE_SEL+mac_id), init_rate); | ||
1774 | } | ||
1775 | |||
1776 | /* set ra_id */ | ||
1777 | psta->raid = raid; | ||
1778 | psta->init_rate = init_rate; | ||
1779 | |||
1780 | /* set correct initial date rate for each mac_id */ | ||
1781 | pdmpriv->INIDATA_RATE[mac_id] = init_rate; | ||
1782 | } | ||
1783 | |||
1784 | static void rtl8723au_init_default_value(struct rtw_adapter *padapter) | ||
1785 | { | ||
1786 | rtl8723a_init_default_value(padapter); | ||
1787 | } | ||
1788 | |||
1789 | static u8 rtl8192cu_ps_func(struct rtw_adapter *Adapter, | ||
1790 | enum hal_intf_ps_func efunc_id, u8 *val) | ||
1791 | { | ||
1792 | return true; | ||
1793 | } | ||
1794 | |||
1795 | int rtl8723au_set_hal_ops(struct rtw_adapter *padapter) | ||
1796 | { | ||
1797 | struct hal_ops *pHalFunc = &padapter->HalFunc; | ||
1798 | |||
1799 | padapter->HalData = kzalloc(sizeof(struct hal_data_8723a), GFP_KERNEL); | ||
1800 | if (!padapter->HalData) { | ||
1801 | DBG_8723A("cannot alloc memory for HAL DATA\n"); | ||
1802 | return -ENOMEM; | ||
1803 | } | ||
1804 | padapter->hal_data_sz = sizeof(struct hal_data_8723a); | ||
1805 | |||
1806 | pHalFunc->hal_init = &rtl8723au_hal_init; | ||
1807 | pHalFunc->hal_deinit = &rtl8723au_hal_deinit; | ||
1808 | |||
1809 | pHalFunc->inirp_init = &rtl8723au_inirp_init; | ||
1810 | pHalFunc->inirp_deinit = &rtl8723au_inirp_deinit; | ||
1811 | |||
1812 | pHalFunc->init_xmit_priv = &rtl8723au_init_xmit_priv; | ||
1813 | pHalFunc->free_xmit_priv = &rtl8723au_free_xmit_priv; | ||
1814 | |||
1815 | pHalFunc->init_recv_priv = &rtl8723au_init_recv_priv; | ||
1816 | pHalFunc->free_recv_priv = &rtl8723au_free_recv_priv; | ||
1817 | pHalFunc->InitSwLeds = NULL; | ||
1818 | pHalFunc->DeInitSwLeds = NULL; | ||
1819 | |||
1820 | pHalFunc->init_default_value = &rtl8723au_init_default_value; | ||
1821 | pHalFunc->intf_chip_configure = &rtl8723au_interface_configure; | ||
1822 | pHalFunc->read_adapter_info = &ReadAdapterInfo8723AU; | ||
1823 | pHalFunc->SetHwRegHandler = &SetHwReg8723AU; | ||
1824 | pHalFunc->GetHwRegHandler = &GetHwReg8723AU; | ||
1825 | pHalFunc->GetHalDefVarHandler = &GetHalDefVar8192CUsb; | ||
1826 | pHalFunc->SetHalDefVarHandler = &SetHalDefVar8192CUsb; | ||
1827 | pHalFunc->UpdateRAMaskHandler = &UpdateHalRAMask8192CUsb; | ||
1828 | pHalFunc->hal_xmit = &rtl8723au_hal_xmit; | ||
1829 | pHalFunc->mgnt_xmit = &rtl8723au_mgnt_xmit; | ||
1830 | pHalFunc->hal_xmitframe_enqueue = &rtl8723au_hal_xmitframe_enqueue; | ||
1831 | pHalFunc->interface_ps_func = &rtl8192cu_ps_func; | ||
1832 | rtl8723a_set_hal_ops(pHalFunc); | ||
1833 | return 0; | ||
1834 | } | ||
diff --git a/drivers/staging/rtl8723au/hal/usb_ops_linux.c b/drivers/staging/rtl8723au/hal/usb_ops_linux.c new file mode 100644 index 000000000000..0311cdf77ff1 --- /dev/null +++ b/drivers/staging/rtl8723au/hal/usb_ops_linux.c | |||
@@ -0,0 +1,848 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | #define _HCI_OPS_OS_C_ | ||
16 | |||
17 | #include <osdep_service.h> | ||
18 | #include <drv_types.h> | ||
19 | #include <osdep_intf.h> | ||
20 | #include <usb_ops.h> | ||
21 | #include <recv_osdep.h> | ||
22 | #include <rtl8723a_hal.h> | ||
23 | #include <rtl8723a_recv.h> | ||
24 | |||
25 | static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype) | ||
26 | { | ||
27 | struct rtw_adapter *padapter = pintfhdl->padapter ; | ||
28 | struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); | ||
29 | struct usb_device *udev = pdvobjpriv->pusbdev; | ||
30 | |||
31 | unsigned int pipe; | ||
32 | int status = 0; | ||
33 | u8 reqtype; | ||
34 | u8 *pIo_buf; | ||
35 | int vendorreq_times = 0; | ||
36 | |||
37 | if ((padapter->bSurpriseRemoved) || (padapter->pwrctrlpriv.pnp_bstop_trx)) { | ||
38 | RT_TRACE(_module_hci_ops_os_c_, _drv_err_, | ||
39 | ("usbctrl_vendorreq:(padapter->bSurpriseRemoved||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n")); | ||
40 | status = -EPERM; | ||
41 | goto exit; | ||
42 | } | ||
43 | |||
44 | if (len > MAX_VENDOR_REQ_CMD_SIZE) { | ||
45 | DBG_8723A("[%s] Buffer len error , vendor request failed\n", __FUNCTION__); | ||
46 | status = -EINVAL; | ||
47 | goto exit; | ||
48 | } | ||
49 | |||
50 | mutex_lock(&pdvobjpriv->usb_vendor_req_mutex); | ||
51 | |||
52 | /* Acquire IO memory for vendorreq */ | ||
53 | pIo_buf = pdvobjpriv->usb_vendor_req_buf; | ||
54 | |||
55 | if (pIo_buf == NULL) { | ||
56 | DBG_8723A("[%s] pIo_buf == NULL \n", __FUNCTION__); | ||
57 | status = -ENOMEM; | ||
58 | goto release_mutex; | ||
59 | } | ||
60 | |||
61 | while (++vendorreq_times <= MAX_USBCTRL_VENDORREQ_TIMES) { | ||
62 | memset(pIo_buf, 0, len); | ||
63 | |||
64 | if (requesttype == 0x01) { | ||
65 | pipe = usb_rcvctrlpipe(udev, 0);/* read_in */ | ||
66 | reqtype = REALTEK_USB_VENQT_READ; | ||
67 | } else { | ||
68 | pipe = usb_sndctrlpipe(udev, 0);/* write_out */ | ||
69 | reqtype = REALTEK_USB_VENQT_WRITE; | ||
70 | memcpy(pIo_buf, pdata, len); | ||
71 | } | ||
72 | |||
73 | status = rtw_usb_control_msg(udev, pipe, request, reqtype, | ||
74 | value, index, pIo_buf, len, | ||
75 | RTW_USB_CONTROL_MSG_TIMEOUT); | ||
76 | |||
77 | if (status == len) { /* Success this control transfer. */ | ||
78 | rtw_reset_continual_urb_error(pdvobjpriv); | ||
79 | if (requesttype == 0x01) { | ||
80 | /* For Control read transfer, we have to copy | ||
81 | * the read data from pIo_buf to pdata. | ||
82 | */ | ||
83 | memcpy(pdata, pIo_buf, len); | ||
84 | } | ||
85 | } else { /* error cases */ | ||
86 | DBG_8723A("reg 0x%x, usb %s %u fail, status:%d value =" | ||
87 | " 0x%x, vendorreq_times:%d\n", | ||
88 | value, (requesttype == 0x01) ? "read" : "write", | ||
89 | len, status, *(u32 *)pdata, vendorreq_times); | ||
90 | |||
91 | if (status < 0) { | ||
92 | if (status == (-ESHUTDOWN) || status == -ENODEV) { | ||
93 | padapter->bSurpriseRemoved = true; | ||
94 | } else { | ||
95 | struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter); | ||
96 | pHalData->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL; | ||
97 | } | ||
98 | } else { /* status != len && status >= 0 */ | ||
99 | if (status > 0) { | ||
100 | if (requesttype == 0x01) { | ||
101 | /* For Control read transfer, we have to copy | ||
102 | * the read data from pIo_buf to pdata. | ||
103 | */ | ||
104 | memcpy(pdata, pIo_buf, len); | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | |||
109 | if (rtw_inc_and_chk_continual_urb_error(pdvobjpriv)) { | ||
110 | padapter->bSurpriseRemoved = true; | ||
111 | break; | ||
112 | } | ||
113 | |||
114 | } | ||
115 | |||
116 | /* firmware download is checksumed, don't retry */ | ||
117 | if ((value >= FW_8723A_START_ADDRESS && value <= FW_8723A_END_ADDRESS) || status == len) | ||
118 | break; | ||
119 | } | ||
120 | |||
121 | release_mutex: | ||
122 | mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex); | ||
123 | exit: | ||
124 | return status; | ||
125 | } | ||
126 | |||
127 | static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr) | ||
128 | { | ||
129 | u8 request; | ||
130 | u8 requesttype; | ||
131 | u16 wvalue; | ||
132 | u16 index; | ||
133 | u16 len; | ||
134 | u8 data = 0; | ||
135 | |||
136 | request = 0x05; | ||
137 | requesttype = 0x01;/* read_in */ | ||
138 | index = 0;/* n/a */ | ||
139 | |||
140 | wvalue = (u16)(addr&0x0000ffff); | ||
141 | len = 1; | ||
142 | |||
143 | usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); | ||
144 | |||
145 | return data; | ||
146 | } | ||
147 | |||
148 | static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr) | ||
149 | { | ||
150 | u8 request; | ||
151 | u8 requesttype; | ||
152 | u16 wvalue; | ||
153 | u16 index; | ||
154 | u16 len; | ||
155 | u16 data = 0; | ||
156 | |||
157 | request = 0x05; | ||
158 | requesttype = 0x01;/* read_in */ | ||
159 | index = 0;/* n/a */ | ||
160 | |||
161 | wvalue = (u16)(addr&0x0000ffff); | ||
162 | len = 2; | ||
163 | |||
164 | usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); | ||
165 | |||
166 | return data; | ||
167 | } | ||
168 | |||
169 | static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr) | ||
170 | { | ||
171 | u8 request; | ||
172 | u8 requesttype; | ||
173 | u16 wvalue; | ||
174 | u16 index; | ||
175 | u16 len; | ||
176 | u32 data = 0; | ||
177 | |||
178 | request = 0x05; | ||
179 | requesttype = 0x01;/* read_in */ | ||
180 | index = 0;/* n/a */ | ||
181 | |||
182 | wvalue = (u16)(addr&0x0000ffff); | ||
183 | len = 4; | ||
184 | |||
185 | usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); | ||
186 | |||
187 | return data; | ||
188 | } | ||
189 | |||
190 | static int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val) | ||
191 | { | ||
192 | u8 request; | ||
193 | u8 requesttype; | ||
194 | u16 wvalue; | ||
195 | u16 index; | ||
196 | u16 len; | ||
197 | u8 data; | ||
198 | int ret; | ||
199 | |||
200 | request = 0x05; | ||
201 | requesttype = 0x00;/* write_out */ | ||
202 | index = 0;/* n/a */ | ||
203 | |||
204 | wvalue = (u16)(addr&0x0000ffff); | ||
205 | len = 1; | ||
206 | |||
207 | data = val; | ||
208 | |||
209 | ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); | ||
210 | |||
211 | return ret; | ||
212 | } | ||
213 | |||
214 | static int usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val) | ||
215 | { | ||
216 | u8 request; | ||
217 | u8 requesttype; | ||
218 | u16 wvalue; | ||
219 | u16 index; | ||
220 | u16 len; | ||
221 | u16 data; | ||
222 | int ret; | ||
223 | |||
224 | request = 0x05; | ||
225 | requesttype = 0x00;/* write_out */ | ||
226 | index = 0;/* n/a */ | ||
227 | |||
228 | wvalue = (u16)(addr&0x0000ffff); | ||
229 | len = 2; | ||
230 | |||
231 | data = val; | ||
232 | |||
233 | ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); | ||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | static int usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val) | ||
238 | { | ||
239 | u8 request; | ||
240 | u8 requesttype; | ||
241 | u16 wvalue; | ||
242 | u16 index; | ||
243 | u16 len; | ||
244 | u32 data; | ||
245 | int ret; | ||
246 | |||
247 | request = 0x05; | ||
248 | requesttype = 0x00;/* write_out */ | ||
249 | index = 0;/* n/a */ | ||
250 | |||
251 | wvalue = (u16)(addr&0x0000ffff); | ||
252 | len = 4; | ||
253 | data = val; | ||
254 | |||
255 | ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype); | ||
256 | |||
257 | return ret; | ||
258 | } | ||
259 | |||
260 | static int usb_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata) | ||
261 | { | ||
262 | u8 request; | ||
263 | u8 requesttype; | ||
264 | u16 wvalue; | ||
265 | u16 index; | ||
266 | u16 len; | ||
267 | u8 buf[VENDOR_CMD_MAX_DATA_LEN] = {0}; | ||
268 | int ret; | ||
269 | |||
270 | request = 0x05; | ||
271 | requesttype = 0x00;/* write_out */ | ||
272 | index = 0;/* n/a */ | ||
273 | |||
274 | wvalue = (u16)(addr&0x0000ffff); | ||
275 | len = length; | ||
276 | memcpy(buf, pdata, len); | ||
277 | |||
278 | ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, buf, len, requesttype); | ||
279 | |||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * Description: | ||
285 | * Recognize the interrupt content by reading the interrupt | ||
286 | * register or content and masking interrupt mask (IMR) | ||
287 | * if it is our NIC's interrupt. After recognizing, we may clear | ||
288 | * the all interrupts (ISR). | ||
289 | * Arguments: | ||
290 | * [in] Adapter - | ||
291 | * The adapter context. | ||
292 | * [in] pContent - | ||
293 | * Under PCI interface, this field is ignord. | ||
294 | * Under USB interface, the content is the interrupt | ||
295 | * content pointer. | ||
296 | * Under SDIO interface, this is the interrupt type which | ||
297 | * is Local interrupt or system interrupt. | ||
298 | * [in] ContentLen - | ||
299 | * The length in byte of pContent. | ||
300 | * Return: | ||
301 | * If any interrupt matches the mask (IMR), return true, and | ||
302 | * return false otherwise. | ||
303 | */ | ||
304 | static bool | ||
305 | InterruptRecognized8723AU(struct rtw_adapter *Adapter, void *pContent, | ||
306 | u32 ContentLen) | ||
307 | { | ||
308 | struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter); | ||
309 | u8 *buffer = (u8 *)pContent; | ||
310 | struct reportpwrstate_parm report; | ||
311 | |||
312 | memcpy(&pHalData->IntArray[0], &buffer[USB_INTR_CONTENT_HISR_OFFSET], | ||
313 | 4); | ||
314 | pHalData->IntArray[0] &= pHalData->IntrMask[0]; | ||
315 | |||
316 | /* For HISR extension. Added by tynli. 2009.10.07. */ | ||
317 | memcpy(&pHalData->IntArray[1], | ||
318 | &buffer[USB_INTR_CONTENT_HISRE_OFFSET], 4); | ||
319 | pHalData->IntArray[1] &= pHalData->IntrMask[1]; | ||
320 | |||
321 | /* We sholud remove this function later because DDK suggest | ||
322 | * not to executing too many operations in MPISR */ | ||
323 | |||
324 | memcpy(&report.state, &buffer[USB_INTR_CPWM_OFFSET], 1); | ||
325 | |||
326 | return ((pHalData->IntArray[0])&pHalData->IntrMask[0]) != 0 || | ||
327 | ((pHalData->IntArray[1])&pHalData->IntrMask[1]) != 0; | ||
328 | } | ||
329 | |||
330 | static void usb_read_interrupt_complete(struct urb *purb, struct pt_regs *regs) | ||
331 | { | ||
332 | int err; | ||
333 | struct rtw_adapter *padapter = (struct rtw_adapter *)purb->context; | ||
334 | |||
335 | if (padapter->bSurpriseRemoved || padapter->bDriverStopped || | ||
336 | padapter->bReadPortCancel) { | ||
337 | DBG_8723A("%s() RX Warning! bDriverStopped(%d) OR " | ||
338 | "bSurpriseRemoved(%d) bReadPortCancel(%d)\n", | ||
339 | __FUNCTION__, padapter->bDriverStopped, | ||
340 | padapter->bSurpriseRemoved, | ||
341 | padapter->bReadPortCancel); | ||
342 | return; | ||
343 | } | ||
344 | |||
345 | if (purb->status == 0) { | ||
346 | struct c2h_evt_hdr *c2h_evt; | ||
347 | |||
348 | c2h_evt = (struct c2h_evt_hdr *)purb->transfer_buffer; | ||
349 | |||
350 | if (purb->actual_length > USB_INTR_CONTENT_LENGTH) { | ||
351 | DBG_8723A("usb_read_interrupt_complete: purb->actual_" | ||
352 | "length > USB_INTR_CONTENT_LENGTH\n"); | ||
353 | goto urb_submit; | ||
354 | } | ||
355 | |||
356 | InterruptRecognized8723AU(padapter, purb->transfer_buffer, | ||
357 | purb->actual_length); | ||
358 | |||
359 | if (c2h_evt_exist(c2h_evt)) { | ||
360 | if (c2h_id_filter_ccx_8723a(c2h_evt->id)) { | ||
361 | /* Handle CCX report here */ | ||
362 | handle_txrpt_ccx_8723a(padapter, (void *)(c2h_evt->payload)); | ||
363 | /* Replace with special pointer to | ||
364 | trigger c2h_evt_clear23a */ | ||
365 | if (rtw_cbuf_push23a(padapter->evtpriv.c2h_queue, | ||
366 | (void *)&padapter->evtpriv) != | ||
367 | _SUCCESS) | ||
368 | DBG_8723A("%s rtw_cbuf_push23a fail\n", | ||
369 | __func__); | ||
370 | schedule_work(&padapter->evtpriv.c2h_wk); | ||
371 | } else if ((c2h_evt = (struct c2h_evt_hdr *) | ||
372 | kmalloc(16, GFP_ATOMIC))) { | ||
373 | memcpy(c2h_evt, purb->transfer_buffer, 16); | ||
374 | if (rtw_cbuf_push23a(padapter->evtpriv.c2h_queue, | ||
375 | (void *)c2h_evt) != _SUCCESS) | ||
376 | DBG_8723A("%s rtw_cbuf_push23a fail\n", | ||
377 | __func__); | ||
378 | schedule_work(&padapter->evtpriv.c2h_wk); | ||
379 | } else { | ||
380 | /* Error handling for malloc fail */ | ||
381 | if (rtw_cbuf_push23a(padapter->evtpriv.c2h_queue, | ||
382 | (void *)NULL) != _SUCCESS) | ||
383 | DBG_8723A("%s rtw_cbuf_push23a fail\n", | ||
384 | __func__); | ||
385 | schedule_work(&padapter->evtpriv.c2h_wk); | ||
386 | } | ||
387 | } | ||
388 | |||
389 | urb_submit: | ||
390 | err = usb_submit_urb(purb, GFP_ATOMIC); | ||
391 | if (err && (err != -EPERM)) { | ||
392 | DBG_8723A("cannot submit interrupt in-token(err = " | ||
393 | "0x%08x), urb_status = %d\n", | ||
394 | err, purb->status); | ||
395 | } | ||
396 | } else { | ||
397 | DBG_8723A("###=> usb_read_interrupt_complete => urb " | ||
398 | "status(%d)\n", purb->status); | ||
399 | |||
400 | switch (purb->status) { | ||
401 | case -EINVAL: | ||
402 | case -EPIPE: | ||
403 | case -ENODEV: | ||
404 | case -ESHUTDOWN: | ||
405 | RT_TRACE(_module_hci_ops_os_c_, _drv_err_, | ||
406 | ("usb_read_port_complete:bSurpriseRemoved =" | ||
407 | "true\n")); | ||
408 | /* Fall Through here */ | ||
409 | case -ENOENT: | ||
410 | padapter->bDriverStopped = true; | ||
411 | RT_TRACE(_module_hci_ops_os_c_, _drv_err_, | ||
412 | ("usb_read_port_complete:bDriverStopped =" | ||
413 | "true\n")); | ||
414 | break; | ||
415 | case -EPROTO: | ||
416 | break; | ||
417 | case -EINPROGRESS: | ||
418 | DBG_8723A("ERROR: URB IS IN PROGRESS!/n"); | ||
419 | break; | ||
420 | default: | ||
421 | break; | ||
422 | } | ||
423 | } | ||
424 | } | ||
425 | |||
426 | static u32 usb_read_interrupt(struct intf_hdl *pintfhdl, u32 addr) | ||
427 | { | ||
428 | int err; | ||
429 | unsigned int pipe; | ||
430 | u32 ret = _SUCCESS; | ||
431 | struct rtw_adapter *adapter = pintfhdl->padapter; | ||
432 | struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); | ||
433 | struct recv_priv *precvpriv = &adapter->recvpriv; | ||
434 | struct usb_device *pusbd = pdvobj->pusbdev; | ||
435 | |||
436 | /* translate DMA FIFO addr to pipehandle */ | ||
437 | pipe = ffaddr2pipehdl23a(pdvobj, addr); | ||
438 | |||
439 | usb_fill_int_urb(precvpriv->int_in_urb, pusbd, pipe, | ||
440 | precvpriv->int_in_buf, USB_INTR_CONTENT_LENGTH, | ||
441 | usb_read_interrupt_complete, adapter, 1); | ||
442 | |||
443 | err = usb_submit_urb(precvpriv->int_in_urb, GFP_ATOMIC); | ||
444 | if (err && (err != -EPERM)) { | ||
445 | DBG_8723A("cannot submit interrupt in-token(err = 0x%08x)," | ||
446 | "urb_status = %d\n", err, | ||
447 | precvpriv->int_in_urb->status); | ||
448 | ret = _FAIL; | ||
449 | } | ||
450 | |||
451 | return ret; | ||
452 | } | ||
453 | |||
454 | static int recvbuf2recvframe(struct rtw_adapter *padapter, struct sk_buff *pskb) | ||
455 | { | ||
456 | u8 *pbuf; | ||
457 | u8 shift_sz = 0; | ||
458 | u16 pkt_cnt; | ||
459 | u32 pkt_offset, skb_len, alloc_sz; | ||
460 | s32 transfer_len; | ||
461 | struct recv_stat *prxstat; | ||
462 | struct phy_stat *pphy_info = NULL; | ||
463 | struct sk_buff *pkt_copy = NULL; | ||
464 | struct recv_frame *precvframe = NULL; | ||
465 | struct rx_pkt_attrib *pattrib = NULL; | ||
466 | struct recv_priv *precvpriv = &padapter->recvpriv; | ||
467 | struct rtw_queue *pfree_recv_queue = &precvpriv->free_recv_queue; | ||
468 | |||
469 | transfer_len = (s32)pskb->len; | ||
470 | pbuf = pskb->data; | ||
471 | |||
472 | prxstat = (struct recv_stat *)pbuf; | ||
473 | pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff; | ||
474 | |||
475 | do { | ||
476 | RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, | ||
477 | ("recvbuf2recvframe: rxdesc = offsset 0:0x%08x, " | ||
478 | "4:0x%08x, 8:0x%08x, C:0x%08x\n", prxstat->rxdw0, | ||
479 | prxstat->rxdw1, prxstat->rxdw2, prxstat->rxdw4)); | ||
480 | |||
481 | prxstat = (struct recv_stat *)pbuf; | ||
482 | |||
483 | precvframe = rtw_alloc_recvframe23a(pfree_recv_queue); | ||
484 | if (!precvframe) { | ||
485 | RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, | ||
486 | ("recvbuf2recvframe: precvframe == NULL\n")); | ||
487 | DBG_8723A("%s()-%d: rtw_alloc_recvframe23a() failed! RX " | ||
488 | "Drop!\n", __FUNCTION__, __LINE__); | ||
489 | goto _exit_recvbuf2recvframe; | ||
490 | } | ||
491 | |||
492 | INIT_LIST_HEAD(&precvframe->list); | ||
493 | |||
494 | update_recvframe_attrib(precvframe, prxstat); | ||
495 | |||
496 | pattrib = &precvframe->attrib; | ||
497 | |||
498 | if (pattrib->crc_err) { | ||
499 | DBG_8723A("%s()-%d: RX Warning! rx CRC ERROR !!\n", | ||
500 | __FUNCTION__, __LINE__); | ||
501 | rtw_free_recvframe23a(precvframe, pfree_recv_queue); | ||
502 | goto _exit_recvbuf2recvframe; | ||
503 | } | ||
504 | |||
505 | pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + | ||
506 | pattrib->shift_sz + pattrib->pkt_len; | ||
507 | |||
508 | if ((pattrib->pkt_len <= 0) || (pkt_offset > transfer_len)) { | ||
509 | RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, | ||
510 | ("recvbuf2recvframe: pkt_len<= 0\n")); | ||
511 | DBG_8723A("%s()-%d: RX Warning!\n", | ||
512 | __FUNCTION__, __LINE__); | ||
513 | rtw_free_recvframe23a(precvframe, pfree_recv_queue); | ||
514 | goto _exit_recvbuf2recvframe; | ||
515 | } | ||
516 | |||
517 | /* Modified by Albert 20101213 */ | ||
518 | /* For 8 bytes IP header alignment. */ | ||
519 | /* Qos data, wireless lan header length is 26 */ | ||
520 | if (pattrib->qos) { | ||
521 | shift_sz = 6; | ||
522 | } else { | ||
523 | shift_sz = 0; | ||
524 | } | ||
525 | |||
526 | skb_len = pattrib->pkt_len; | ||
527 | |||
528 | /* for first fragment packet, driver need allocate | ||
529 | * 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. | ||
530 | * modify alloc_sz for recvive crc error packet | ||
531 | * by thomas 2011-06-02 */ | ||
532 | if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) { | ||
533 | /* alloc_sz = 1664; 1664 is 128 alignment. */ | ||
534 | if (skb_len <= 1650) | ||
535 | alloc_sz = 1664; | ||
536 | else | ||
537 | alloc_sz = skb_len + 14; | ||
538 | } else { | ||
539 | alloc_sz = skb_len; | ||
540 | /* 6 is for IP header 8 bytes alignment in QoS packet case. */ | ||
541 | /* 8 is for skb->data 4 bytes alignment. */ | ||
542 | alloc_sz += 14; | ||
543 | } | ||
544 | |||
545 | pkt_copy = netdev_alloc_skb(padapter->pnetdev, alloc_sz); | ||
546 | if (pkt_copy) { | ||
547 | pkt_copy->dev = padapter->pnetdev; | ||
548 | precvframe->pkt = pkt_copy; | ||
549 | skb_reserve(pkt_copy, 8 - ((unsigned long)(pkt_copy->data) & 7));/* force pkt_copy->data at 8-byte alignment address */ | ||
550 | /*force ip_hdr at 8-byte alignment address according to shift_sz. */ | ||
551 | skb_reserve(pkt_copy, shift_sz); | ||
552 | memcpy(pkt_copy->data, (pbuf + pattrib->shift_sz + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len); | ||
553 | skb_put(pkt_copy, skb_len); | ||
554 | } else { | ||
555 | if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) { | ||
556 | DBG_8723A("recvbuf2recvframe: alloc_skb fail, " | ||
557 | "drop frag frame \n"); | ||
558 | rtw_free_recvframe23a(precvframe, | ||
559 | pfree_recv_queue); | ||
560 | goto _exit_recvbuf2recvframe; | ||
561 | } | ||
562 | |||
563 | precvframe->pkt = skb_clone(pskb, GFP_ATOMIC); | ||
564 | if (!precvframe->pkt) { | ||
565 | DBG_8723A("recvbuf2recvframe: skb_clone " | ||
566 | "fail\n"); | ||
567 | rtw_free_recvframe23a(precvframe, | ||
568 | pfree_recv_queue); | ||
569 | goto _exit_recvbuf2recvframe; | ||
570 | } | ||
571 | } | ||
572 | |||
573 | if (pattrib->physt) { | ||
574 | pphy_info = (struct phy_stat *)(pbuf + RXDESC_OFFSET); | ||
575 | update_recvframe_phyinfo(precvframe, pphy_info); | ||
576 | } | ||
577 | |||
578 | if (rtw_recv_entry23a(precvframe) != _SUCCESS) | ||
579 | RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, | ||
580 | ("recvbuf2recvframe: rtw_recv_entry23a" | ||
581 | "(precvframe) != _SUCCESS\n")); | ||
582 | |||
583 | pkt_cnt--; | ||
584 | transfer_len -= pkt_offset; | ||
585 | pbuf += pkt_offset; | ||
586 | precvframe = NULL; | ||
587 | pkt_copy = NULL; | ||
588 | |||
589 | if (transfer_len > 0 && pkt_cnt == 0) | ||
590 | pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff; | ||
591 | |||
592 | } while ((transfer_len > 0) && (pkt_cnt > 0)); | ||
593 | |||
594 | _exit_recvbuf2recvframe: | ||
595 | |||
596 | return _SUCCESS; | ||
597 | } | ||
598 | |||
599 | void rtl8723au_recv_tasklet(void *priv) | ||
600 | { | ||
601 | struct sk_buff *pskb; | ||
602 | struct rtw_adapter *padapter = (struct rtw_adapter *)priv; | ||
603 | struct recv_priv *precvpriv = &padapter->recvpriv; | ||
604 | |||
605 | while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) { | ||
606 | if ((padapter->bDriverStopped) || | ||
607 | (padapter->bSurpriseRemoved)) { | ||
608 | DBG_8723A("recv_tasklet => bDriverStopped or " | ||
609 | "bSurpriseRemoved \n"); | ||
610 | dev_kfree_skb_any(pskb); | ||
611 | break; | ||
612 | } | ||
613 | |||
614 | recvbuf2recvframe(padapter, pskb); | ||
615 | skb_reset_tail_pointer(pskb); | ||
616 | |||
617 | pskb->len = 0; | ||
618 | |||
619 | skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); | ||
620 | } | ||
621 | } | ||
622 | |||
623 | static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs) | ||
624 | { | ||
625 | struct recv_buf *precvbuf = (struct recv_buf *)purb->context; | ||
626 | struct rtw_adapter *padapter = (struct rtw_adapter *)precvbuf->adapter; | ||
627 | struct recv_priv *precvpriv = &padapter->recvpriv; | ||
628 | struct hal_data_8723a *pHalData; | ||
629 | |||
630 | RT_TRACE(_module_hci_ops_os_c_, _drv_err_, | ||
631 | ("usb_read_port_complete!!!\n")); | ||
632 | |||
633 | precvpriv->rx_pending_cnt--; | ||
634 | |||
635 | if (padapter->bSurpriseRemoved || padapter->bDriverStopped || | ||
636 | padapter->bReadPortCancel) { | ||
637 | RT_TRACE(_module_hci_ops_os_c_, _drv_err_, | ||
638 | ("usb_read_port_complete:bDriverStopped(%d) OR " | ||
639 | "bSurpriseRemoved(%d)\n", padapter->bDriverStopped, | ||
640 | padapter->bSurpriseRemoved)); | ||
641 | |||
642 | DBG_8723A("%s()-%d: RX Warning! bDriverStopped(%d) OR " | ||
643 | "bSurpriseRemoved(%d) bReadPortCancel(%d)\n", | ||
644 | __FUNCTION__, __LINE__, padapter->bDriverStopped, | ||
645 | padapter->bSurpriseRemoved, padapter->bReadPortCancel); | ||
646 | return; | ||
647 | } | ||
648 | |||
649 | if (purb->status == 0) { | ||
650 | if ((purb->actual_length > MAX_RECVBUF_SZ) || | ||
651 | (purb->actual_length < RXDESC_SIZE)) { | ||
652 | RT_TRACE(_module_hci_ops_os_c_, _drv_err_, | ||
653 | ("usb_read_port_complete: (purb->actual_" | ||
654 | "length > MAX_RECVBUF_SZ) || (purb->actual_" | ||
655 | "length < RXDESC_SIZE)\n")); | ||
656 | rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, | ||
657 | precvbuf); | ||
658 | DBG_8723A("%s()-%d: RX Warning!\n", | ||
659 | __FUNCTION__, __LINE__); | ||
660 | } else { | ||
661 | rtw_reset_continual_urb_error( | ||
662 | adapter_to_dvobj(padapter)); | ||
663 | |||
664 | skb_put(precvbuf->pskb, purb->actual_length); | ||
665 | skb_queue_tail(&precvpriv->rx_skb_queue, | ||
666 | precvbuf->pskb); | ||
667 | |||
668 | if (skb_queue_len(&precvpriv->rx_skb_queue) <= 1) | ||
669 | tasklet_schedule(&precvpriv->recv_tasklet); | ||
670 | |||
671 | precvbuf->pskb = NULL; | ||
672 | rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, | ||
673 | precvbuf); | ||
674 | } | ||
675 | } else { | ||
676 | RT_TRACE(_module_hci_ops_os_c_, _drv_err_, | ||
677 | ("usb_read_port_complete : purb->status(%d) != 0 \n", | ||
678 | purb->status)); | ||
679 | skb_put(precvbuf->pskb, purb->actual_length); | ||
680 | precvbuf->pskb = NULL; | ||
681 | |||
682 | DBG_8723A("###=> usb_read_port_complete => urb status(%d)\n", | ||
683 | purb->status); | ||
684 | |||
685 | if (rtw_inc_and_chk_continual_urb_error( | ||
686 | adapter_to_dvobj(padapter))) { | ||
687 | padapter->bSurpriseRemoved = true; | ||
688 | } | ||
689 | |||
690 | switch (purb->status) { | ||
691 | case -EINVAL: | ||
692 | case -EPIPE: | ||
693 | case -ENODEV: | ||
694 | case -ESHUTDOWN: | ||
695 | RT_TRACE(_module_hci_ops_os_c_, _drv_err_, | ||
696 | ("usb_read_port_complete:bSurprise" | ||
697 | "Removed = true\n")); | ||
698 | /* Intentional fall through here */ | ||
699 | case -ENOENT: | ||
700 | padapter->bDriverStopped = true; | ||
701 | RT_TRACE(_module_hci_ops_os_c_, _drv_err_, | ||
702 | ("usb_read_port_complete:" | ||
703 | "bDriverStopped = true\n")); | ||
704 | break; | ||
705 | case -EPROTO: | ||
706 | case -EOVERFLOW: | ||
707 | pHalData = GET_HAL_DATA(padapter); | ||
708 | pHalData->srestpriv.Wifi_Error_Status = | ||
709 | USB_READ_PORT_FAIL; | ||
710 | rtw_read_port(padapter, precvpriv->ff_hwaddr, | ||
711 | 0, precvbuf); | ||
712 | break; | ||
713 | case -EINPROGRESS: | ||
714 | DBG_8723A("ERROR: URB IS IN PROGRESS!/n"); | ||
715 | break; | ||
716 | default: | ||
717 | break; | ||
718 | } | ||
719 | |||
720 | } | ||
721 | } | ||
722 | |||
723 | static u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, | ||
724 | struct recv_buf *precvbuf) | ||
725 | { | ||
726 | int err; | ||
727 | unsigned int pipe; | ||
728 | unsigned long tmpaddr = 0; | ||
729 | unsigned long alignment = 0; | ||
730 | u32 ret = _SUCCESS; | ||
731 | struct urb *purb = NULL; | ||
732 | struct rtw_adapter *adapter = pintfhdl->padapter; | ||
733 | struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter); | ||
734 | struct recv_priv *precvpriv = &adapter->recvpriv; | ||
735 | struct usb_device *pusbd = pdvobj->pusbdev; | ||
736 | |||
737 | if (adapter->bDriverStopped || adapter->bSurpriseRemoved || | ||
738 | adapter->pwrctrlpriv.pnp_bstop_trx) { | ||
739 | RT_TRACE(_module_hci_ops_os_c_, _drv_err_, | ||
740 | ("usb_read_port:(padapter->bDriverStopped ||" | ||
741 | "padapter->bSurpriseRemoved ||adapter->" | ||
742 | "pwrctrlpriv.pnp_bstop_trx)!!!\n")); | ||
743 | return _FAIL; | ||
744 | } | ||
745 | |||
746 | if (!precvbuf) { | ||
747 | RT_TRACE(_module_hci_ops_os_c_, _drv_err_, | ||
748 | ("usb_read_port:precvbuf == NULL\n")); | ||
749 | return _FAIL; | ||
750 | } | ||
751 | |||
752 | if (!precvbuf->pskb) | ||
753 | precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue); | ||
754 | |||
755 | rtl8723au_init_recvbuf(adapter, precvbuf); | ||
756 | |||
757 | /* re-assign for linux based on skb */ | ||
758 | if (!precvbuf->pskb) { | ||
759 | precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); | ||
760 | if (precvbuf->pskb == NULL) { | ||
761 | RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("init_recvbuf(): alloc_skb fail!\n")); | ||
762 | return _FAIL; | ||
763 | } | ||
764 | |||
765 | tmpaddr = (unsigned long)precvbuf->pskb->data; | ||
766 | alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); | ||
767 | skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); | ||
768 | } | ||
769 | |||
770 | precvpriv->rx_pending_cnt++; | ||
771 | |||
772 | purb = precvbuf->purb; | ||
773 | |||
774 | /* translate DMA FIFO addr to pipehandle */ | ||
775 | pipe = ffaddr2pipehdl23a(pdvobj, addr); | ||
776 | |||
777 | usb_fill_bulk_urb(purb, pusbd, pipe, precvbuf->pskb->data, | ||
778 | MAX_RECVBUF_SZ, usb_read_port_complete, | ||
779 | precvbuf);/* context is precvbuf */ | ||
780 | |||
781 | err = usb_submit_urb(purb, GFP_ATOMIC); | ||
782 | if ((err) && (err != -EPERM)) { | ||
783 | RT_TRACE(_module_hci_ops_os_c_, _drv_err_, | ||
784 | ("cannot submit rx in-token(err = 0x%.8x), URB_STATUS " | ||
785 | "= 0x%.8x", err, purb->status)); | ||
786 | DBG_8723A("cannot submit rx in-token(err = 0x%08x), urb_status " | ||
787 | "= %d\n", err, purb->status); | ||
788 | ret = _FAIL; | ||
789 | } | ||
790 | return ret; | ||
791 | } | ||
792 | |||
793 | void rtl8723au_xmit_tasklet(void *priv) | ||
794 | { | ||
795 | int ret = false; | ||
796 | struct rtw_adapter *padapter = (struct rtw_adapter *)priv; | ||
797 | struct xmit_priv *pxmitpriv = &padapter->xmitpriv; | ||
798 | |||
799 | if (check_fwstate(&padapter->mlmepriv, _FW_UNDER_SURVEY)) | ||
800 | return; | ||
801 | |||
802 | while (1) { | ||
803 | if ((padapter->bDriverStopped) || | ||
804 | (padapter->bSurpriseRemoved) || | ||
805 | (padapter->bWritePortCancel)) { | ||
806 | DBG_8723A("xmit_tasklet => bDriverStopped or " | ||
807 | "bSurpriseRemoved or bWritePortCancel\n"); | ||
808 | break; | ||
809 | } | ||
810 | |||
811 | ret = rtl8723au_xmitframe_complete(padapter, pxmitpriv, NULL); | ||
812 | |||
813 | if (!ret) | ||
814 | break; | ||
815 | } | ||
816 | } | ||
817 | |||
818 | void rtl8723au_set_intf_ops(struct _io_ops *pops) | ||
819 | { | ||
820 | |||
821 | memset((u8 *)pops, 0, sizeof(struct _io_ops)); | ||
822 | |||
823 | pops->_read8 = &usb_read8; | ||
824 | pops->_read16 = &usb_read16; | ||
825 | pops->_read32 = &usb_read32; | ||
826 | pops->_read_mem = &usb_read_mem23a; | ||
827 | pops->_read_port = &usb_read_port; | ||
828 | |||
829 | pops->_write8 = &usb_write8; | ||
830 | pops->_write16 = &usb_write16; | ||
831 | pops->_write32 = &usb_write32; | ||
832 | pops->_writeN = &usb_writeN; | ||
833 | |||
834 | pops->_write_mem = &usb_write_mem23a; | ||
835 | pops->_write_port = &usb_write_port23a; | ||
836 | |||
837 | pops->_read_port_cancel = &usb_read_port_cancel23a; | ||
838 | pops->_write_port_cancel = &usb_write_port23a_cancel; | ||
839 | |||
840 | pops->_read_interrupt = &usb_read_interrupt; | ||
841 | } | ||
842 | |||
843 | void rtl8723au_set_hw_type(struct rtw_adapter *padapter) | ||
844 | { | ||
845 | padapter->chip_type = RTL8723A; | ||
846 | padapter->HardwareType = HARDWARE_TYPE_RTL8723AU; | ||
847 | DBG_8723A("CHIP TYPE: RTL8723A\n"); | ||
848 | } | ||