aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2014-03-28 22:37:39 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-04-05 17:51:23 -0400
commitf7c92d2cc2beb3367f244480300eaecdd9502932 (patch)
treea1bcf064ad3699f760a5b1e26adb2e18050d7807
parent5e93f35209578fcabfa855e427354195e54b491f (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>
-rw-r--r--drivers/staging/rtl8723au/hal/Hal8723PwrSeq.c80
-rw-r--r--drivers/staging/rtl8723au/hal/Hal8723UHWImg_CE.c136
-rw-r--r--drivers/staging/rtl8723au/hal/HalDMOutSrc8723A_CE.c1063
-rw-r--r--drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c726
-rw-r--r--drivers/staging/rtl8723au/hal/HalHWImg8723A_MAC.c188
-rw-r--r--drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c259
-rw-r--r--drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c163
-rw-r--r--drivers/staging/rtl8723au/hal/hal_com.c881
-rw-r--r--drivers/staging/rtl8723au/hal/hal_intf.c418
-rw-r--r--drivers/staging/rtl8723au/hal/odm.c2090
-rw-r--r--drivers/staging/rtl8723au/hal/odm_HWConfig.c481
-rw-r--r--drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c162
-rw-r--r--drivers/staging/rtl8723au/hal/odm_debug.c24
-rw-r--r--drivers/staging/rtl8723au/hal/odm_interface.c236
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c11304
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_cmd.c845
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_dm.c273
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c3452
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c1197
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c515
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_rxdesc.c69
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_sreset.c73
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_xmit.c52
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723au_led.c113
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723au_recv.c247
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723au_xmit.c548
-rw-r--r--drivers/staging/rtl8723au/hal/usb_halinit.c1834
-rw-r--r--drivers/staging/rtl8723au/hal/usb_ops_linux.c848
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 */
22struct 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 */
28struct 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 */
34struct 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 */
41struct 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 */
48struct 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 */
55struct 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 */
62struct 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 */
69struct 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 */
76struct 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
19u32 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
134u32 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 */
25static void
26odm_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. */
341static void ODM_TXPowerTracking92CDirectCall(struct rtw_adapter *Adapter)
342{
343 odm_TXPowerTrackingCallback_ThermalMeter_92C(Adapter);
344}
345
346static 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
366void 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
375static 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
429static 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
464static 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
512static 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
553static 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
562static 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
572static 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
581static 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
591static 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
608static 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
620static 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
627static 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/*
637return false => do IQK again
638*/
639static 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
693static 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
856static 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
914void 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
1039void 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
1060void
1061rtl8723a_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
18static 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
48static 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
216void 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
268static 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
465void 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
516static u32 Array_PHY_REG_MP_8723A[] = {
517 0xC30, 0x69E9AC4A,
518 0xC3C, 0x0A979718,
519};
520
521void 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
572static 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
687void 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
18static 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
48static 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
137void 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
18static 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
48static 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
207void 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/*++
16Copyright (c) Realtek Semiconductor Corp. All rights reserved.
17
18Module Name:
19 HalPwrSeqCmd.c
20
21Abstract:
22 Implement HW Power sequence configuration CMD handling routine for
23 Realtek devices.
24
25Major 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/* */
45u8 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
24void 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 */
70u8 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
96u8 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
155void 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
242static 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
257static 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
290static 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
323bool 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
347void 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
359void c2h_evt_clear23a(struct rtw_adapter *adapter)
360{
361 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
362}
363
364s32 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
409clear_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);
416exit:
417 return ret;
418}
419
420void
421rtl8723a_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
456void 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
497void 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
518void 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
527void 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
536void 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
544void 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
555void 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
598void 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
605void 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
613void 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
637void 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
651void rtl8723a_set_sec_cfg(struct rtw_adapter *padapter, u8 sec)
652{
653 rtw_write8(padapter, REG_SECCFG, sec);
654}
655
656void 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
687void rtl8723a_cam_invalid_all(struct rtw_adapter *padapter)
688{
689 rtw_write32(padapter, RWCAM, BIT(31) | BIT(30));
690}
691
692void 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
702void 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
739void 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
747void 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
755void rtl8723a_set_tx_pause(struct rtw_adapter *padapter, u8 pause)
756{
757 rtw_write8(padapter, REG_TXPAUSE, pause);
758}
759
760void rtl8723a_set_beacon_interval(struct rtw_adapter *padapter, u16 interval)
761{
762 rtw_write16(padapter, REG_BCN_INTERVAL, interval);
763}
764
765void 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
781void rtl8723a_set_ac_param_vo(struct rtw_adapter *padapter, u32 vo)
782{
783 rtw_write32(padapter, REG_EDCA_VO_PARAM, vo);
784}
785
786void rtl8723a_set_ac_param_vi(struct rtw_adapter *padapter, u32 vi)
787{
788 rtw_write32(padapter, REG_EDCA_VI_PARAM, vi);
789}
790
791void 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
799void rtl8723a_set_ac_param_bk(struct rtw_adapter *padapter, u32 bk)
800{
801 rtw_write32(padapter, REG_EDCA_BK_PARAM, bk);
802}
803
804void 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
809void 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
827void 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
840void 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
847void 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
859void 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
871void 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
878void 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
24void 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
30void 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
36void 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
42void 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}
47void rtw_hal_free_data23a(struct rtw_adapter *padapter)
48{
49 if (padapter->HalFunc.free_hal_data)
50 padapter->HalFunc.free_hal_data(padapter);
51}
52void rtw_hal_dm_init23a(struct rtw_adapter *padapter)
53{
54 if (padapter->HalFunc.dm_init)
55 padapter->HalFunc.dm_init(padapter);
56}
57void 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}
63void rtw_hal_sw_led_init23a(struct rtw_adapter *padapter)
64{
65 if (padapter->HalFunc.InitSwLeds)
66 padapter->HalFunc.InitSwLeds(padapter);
67}
68
69void rtw_hal_sw_led_deinit23a(struct rtw_adapter *padapter)
70{
71 if (padapter->HalFunc.DeInitSwLeds)
72 padapter->HalFunc.DeInitSwLeds(padapter);
73}
74
75u32 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
82uint 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
107uint 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
120void 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
126void 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
132u8 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}
138u8 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
145void 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}
150void 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
156void 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}
164void 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
173u32 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
183u32 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
193u8 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
200s32 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
208s32 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
216s32 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
224s32 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}
230void 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
236s32 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}
243void 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
249void 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
269void 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 */
276void 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 */
282void rtw_hal_stop_thread23a(struct rtw_adapter *padapter)
283{
284 if (padapter->HalFunc.cancel_thread)
285 padapter->HalFunc.cancel_thread(padapter);
286}
287
288u32 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}
295void 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
301u32 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}
308void 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
314s32 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
321void 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
329void 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
335void 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
341void rtw_hal_bcn_related_reg_setting23a(struct rtw_adapter *padapter)
342{
343 if (padapter->HalFunc.SetBeaconRelatedRegistersHandler)
344 padapter->HalFunc.SetBeaconRelatedRegistersHandler(padapter);
345}
346
347void rtw_hal_sreset_init23a(struct rtw_adapter *padapter)
348{
349 if (padapter->HalFunc.sreset_init_value23a)
350 padapter->HalFunc.sreset_init_value23a(padapter);
351}
352void 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
360void 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
366void 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}
371void 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}
376u8 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
384bool 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
395void 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
401void 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
407s32 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
415c2h_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
18static 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
29static 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 */
45u32 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
91u8 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
127u8 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--------------- */
166void odm_CommonInfoSelfInit23a(struct dm_odm_t *pDM_Odm);
167
168void odm_CommonInfoSelfUpdate23a(struct dm_odm_t *pDM_Odm);
169
170void odm_CmnInfoInit_Debug23a(struct dm_odm_t *pDM_Odm);
171
172void odm_CmnInfoHook_Debug23a(struct dm_odm_t *pDM_Odm);
173
174void odm_CmnInfoUpdate_Debug23a(struct dm_odm_t *pDM_Odm);
175
176/* START---------------DIG--------------------------- */
177void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm);
178
179void odm_DIG23aInit(struct dm_odm_t *pDM_Odm);
180
181void odm_DIG23a(struct dm_odm_t *pDM_Odm);
182
183void odm_CCKPacketDetectionThresh23a(struct dm_odm_t *pDM_Odm);
184/* END---------------DIG--------------------------- */
185
186/* START-------BB POWER SAVE----------------------- */
187void odm23a_DynBBPSInit(struct dm_odm_t *pDM_Odm);
188
189void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm);
190
191void odm_1R_CCA23a(struct dm_odm_t *pDM_Odm);
192/* END---------BB POWER SAVE----------------------- */
193
194void odm_RefreshRateAdaptiveMask23aMP23a(struct dm_odm_t *pDM_Odm);
195
196void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm);
197
198void odm_RefreshRateAdaptiveMask23aAPADSL23a(struct dm_odm_t *pDM_Odm);
199
200void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm);
201
202void odm_DynamicTxPower23aRestorePowerIndex(struct dm_odm_t *pDM_Odm);
203
204void odm_DynamicTxPower23aSavePowerIndex(struct dm_odm_t *pDM_Odm);
205
206void odm_DynamicTxPower23aWritePowerIndex(struct dm_odm_t *pDM_Odm,
207 u8 Value);
208
209void odm_DynamicTxPower23a_92C(struct dm_odm_t *pDM_Odm);
210
211void odm_DynamicTxPower23a_92D(struct dm_odm_t *pDM_Odm);
212
213void odm_RSSIMonitorInit(struct dm_odm_t *pDM_Odm);
214
215void odm_RSSIMonitorCheck23aMP(struct dm_odm_t *pDM_Odm);
216
217void odm_RSSIMonitorCheck23aCE(struct dm_odm_t *pDM_Odm);
218void odm_RSSIMonitorCheck23aAP(struct dm_odm_t *pDM_Odm);
219
220void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm);
221void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm);
222
223void odm_SwAntDivInit(struct dm_odm_t *pDM_Odm);
224
225void odm_SwAntDivInit_NIC(struct dm_odm_t *pDM_Odm);
226
227void odm_SwAntDivChkAntSwitch(struct dm_odm_t *pDM_Odm, u8 Step);
228
229void odm_SwAntDivChkAntSwitchNIC(struct dm_odm_t *pDM_Odm,
230 u8 Step
231 );
232
233void odm_SwAntDivChkAntSwitchCallback23a(unsigned long data);
234
235void odm_GlobalAdapterCheck(void);
236
237void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm);
238
239void ODM_TXPowerTrackingCheck23a(struct dm_odm_t *pDM_Odm);
240
241void odm_TXPowerTrackingCheckAP(struct dm_odm_t *pDM_Odm);
242
243void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm);
244
245void odm_TXPowerTrackingThermalMeterInit23a(struct dm_odm_t *pDM_Odm);
246
247void odm_TXPowerTrackingInit23a(struct dm_odm_t *pDM_Odm);
248
249void odm_TXPowerTrackingCheckMP(struct dm_odm_t *pDM_Odm);
250
251void odm_TXPowerTrackingCheckCE23a(struct dm_odm_t *pDM_Odm);
252
253void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm);
254void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm);
255
256void odm_EdcaTurboCheck23aCE23a(struct dm_odm_t *pDM_Odm);
257
258#define RxDefaultAnt1 0x65a9
259#define RxDefaultAnt2 0x569a
260
261void odm_InitHybridAntDiv23a(struct dm_odm_t *pDM_Odm);
262
263bool 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
271void odm_SetRxIdleAnt(struct dm_odm_t *pDM_Odm,
272 u8 Ant,
273 bool bDualPath
274);
275
276void 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?? */
281void 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. */
306void 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/* */
355void 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
433void 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
508void 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. */
525void 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
563void 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
574void 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
600void 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
620void 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
635void 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
644void 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 */
664void 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
712void 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
746void 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
934void 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
1034void 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
1066void 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 ============================================================ */
1080void 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
1092void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm)
1093{
1094 return;
1095}
1096
1097void 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
1131void 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
1204void 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
1219u32 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 *---------------------------------------------------------------------------*/
1315void 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
1327void odm_RefreshRateAdaptiveMask23aMP23a(struct dm_odm_t *pDM_Odm)
1328{
1329}
1330
1331void 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
1366void odm_RefreshRateAdaptiveMask23aAPADSL23a(struct dm_odm_t *pDM_Odm)
1367{
1368}
1369
1370/* Return Value: bool */
1371/* - true: RATRState is changed. */
1372bool 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
1421void 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
1433void 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
1445void 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
1457void 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
1469void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm)
1470{
1471}
1472
1473void odm_DynamicTxPower23a_92C(struct dm_odm_t *pDM_Odm)
1474{
1475}
1476
1477void odm_DynamicTxPower23a_92D(struct dm_odm_t *pDM_Odm)
1478{
1479}
1480
1481/* 3 ============================================================ */
1482/* 3 RSSI Monitor */
1483/* 3 ============================================================ */
1484
1485void odm_RSSIMonitorInit(struct dm_odm_t *pDM_Odm)
1486{
1487}
1488
1489void 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
1503void odm_RSSIMonitorCheck23aMP(struct dm_odm_t *pDM_Odm)
1504{
1505}
1506
1507static void
1508FindMinimumRSSI(
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
1525void 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
1575void odm_RSSIMonitorCheck23aAP(struct dm_odm_t *pDM_Odm)
1576{
1577}
1578
1579void 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
1585void ODM_CancelAllTimers(struct dm_odm_t *pDM_Odm)
1586{
1587 del_timer_sync(&pDM_Odm->DM_SWAT_Table.SwAntennaSwitchTimer);
1588}
1589
1590void 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
1600void odm_TXPowerTrackingInit23a(struct dm_odm_t *pDM_Odm)
1601{
1602 odm_TXPowerTrackingThermalMeterInit23a(pDM_Odm);
1603}
1604
1605void 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
1620void 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
1631void odm_TXPowerTrackingCheckCE23a(struct dm_odm_t *pDM_Odm)
1632{
1633}
1634
1635void odm_TXPowerTrackingCheckMP(struct dm_odm_t *pDM_Odm)
1636{
1637}
1638
1639void 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 ============================================================ */
1654void odm_SwAntDivInit(struct dm_odm_t *pDM_Odm)
1655{
1656}
1657
1658void ODM_SwAntDivChkPerPktRssi(struct dm_odm_t *pDM_Odm, u8 StationID, struct odm_phy_info *pPhyInfo)
1659{
1660}
1661
1662void odm_SwAntDivChkAntSwitch(struct dm_odm_t *pDM_Odm, u8 Step)
1663{
1664}
1665
1666void ODM_SwAntDivRestAfterLink(struct dm_odm_t *pDM_Odm)
1667{
1668}
1669
1670void odm_SwAntDivChkAntSwitchCallback23a(unsigned long data)
1671{
1672}
1673
1674/* 3 ============================================================ */
1675/* 3 SW Antenna Diversity */
1676/* 3 ============================================================ */
1677
1678void odm_InitHybridAntDiv23a(struct dm_odm_t *pDM_Odm)
1679{
1680}
1681
1682void odm_HwAntDiv23a(struct dm_odm_t *pDM_Odm)
1683{
1684}
1685
1686/* EDCA Turbo */
1687void 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
1702void 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
1720void 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
1792dm_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
1799u32 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
1819u32
1820ConvertTo_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/* */
1850void
1851odm_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/* */
1863void 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
1872static 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
1886static 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. */
1899bool 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 */
2088void 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
27static 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
37static 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
62static s32 odm_SignalScaleMapping(struct dm_odm_t *pDM_Odm, s32 CurrSig)
63{
64 return odm_SignalScaleMapping_92CSeries(pDM_Odm, CurrSig);
65}
66
67static u8
68odm_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
93static 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
279void odm_Init_RSSIForDM23a(struct dm_odm_t *pDM_Odm)
280{
281}
282
283static 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 */
398static 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
414void 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. */
421void 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
429enum hal_status
430ODM_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
452enum hal_status
453ODM_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
471enum hal_status
472ODM_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
18void
19odm_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
46void 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
61void 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
76void 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
87void
88odm_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
104void
105odm_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
132void
133odm_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
18void ODM_InitDebugSetting23a(struct dm_odm_t *pDM_Odm)
19{
20 pDM_Odm->DebugLevel = ODM_DBG_TRACE;
21 pDM_Odm->DebugComponents = 0;
22}
23
24u32 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
25u8 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
34u16 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
43u32 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
52void 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
63void 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
74void 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
86void 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
98u32 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
109void 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
121u32 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
132void 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
145u32 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/* */
160void 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. */
170void 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/* */
182void
183ODM_AcquireSpinLock(
184 struct dm_odm_t *pDM_Odm,
185 enum rt_spinlock_type type
186 )
187{
188}
189
190void 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/* */
200void 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/* */
213void 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
218void ODM_ReleaseTimer(struct dm_odm_t *pDM_Odm, struct timer_list *pTimer)
219{
220}
221
222/* */
223/* ODM FW relative API. */
224/* */
225u32 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
23u32 BTCoexDbgLevel = _bt_dbg_off_;
24
25#define RTPRINT(_Comp, _Level, Fmt)\
26do {\
27 if ((BTCoexDbgLevel == _bt_dbg_on_)) {\
28 printk Fmt;\
29 } \
30} while (0)
31
32#define RTPRINT_ADDR(dbgtype, dbgflag, printstr, _Ptr)\
33if ((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)\
43if ((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
94enum {
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
106static 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
117static 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
136void BT_SignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi, u8 *rssi_bt)
137{
138 BTDM_SignalCompensation(padapter, rssi_wifi, rssi_bt);
139}
140
141void 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
148void 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
159void BT_WifiMediaStatusNotify(struct rtw_adapter *padapter, enum rt_media_status mstatus)
160{
161 BTDM_MediaStatusNotify(padapter, mstatus);
162}
163
164void BT_SpecialPacketNotify(struct rtw_adapter *padapter)
165{
166 BTDM_ForDhcp(padapter);
167}
168
169void BT_HaltProcess(struct rtw_adapter *padapter)
170{
171 BTDM_ForHalt(padapter);
172}
173
174void 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
197static 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
221static u8 bthci_GetLocalChannel(struct rtw_adapter *padapter)
222{
223 return padapter->mlmeextpriv.cur_channel;
224}
225
226static 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
240static 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 */
340static 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
433static 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
457static u8 bthci_DiscardTxPackets(struct rtw_adapter *padapter, u16 LLH)
458{
459 return false;
460}
461
462static u8
463bthci_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
526static 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
538static u16
539bthci_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
562static 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
613static 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
637static 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
654static void bthci_ResponderStartToScan(struct rtw_adapter *padapter)
655{
656}
657
658static 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
672static 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
700static 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
753static 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
780static u8
781bthci_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
814static 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
823static enum rt_status
824bthci_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
837static void
838bthci_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
867static void
868bthci_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
888static void
889bthci_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
918static 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
946static void
947bthci_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
981static void
982bthci_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
1029static void
1030bthci_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
1057static void
1058bthci_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
1087static void
1088bthci_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
1133static void
1134bthci_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
1161static void
1162bthci_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
1206static void
1207bthci_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
1239static void
1240bthci_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
1259static enum hci_status
1260bthci_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
1322static void
1323bthci_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
1464static void
1465bthci_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
1530static 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
1547static 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
1576static 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
1590static 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
1619static 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
1692static enum hci_status
1693bthci_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 */
1758static 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 */
1791static enum hci_status
1792bthci_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 */
1803static enum hci_status
1804bthci_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
1842static enum hci_status
1843bthci_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
1878static enum hci_status
1879bthci_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
1920static enum hci_status
1921bthci_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
1973static enum hci_status
1974bthci_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
2027static enum hci_status
2028bthci_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
2064static enum hci_status
2065bthci_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
2101static enum hci_status
2102bthci_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
2136static enum hci_status
2137bthci_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 */
2177static enum hci_status
2178bthci_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
2216static enum hci_status
2217bthci_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
2258static enum hci_status
2259bthci_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
2302static enum hci_status
2303bthci_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
2334static enum hci_status
2335bthci_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
2369static enum hci_status
2370bthci_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
2423static enum hci_status
2424bthci_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
2476static enum hci_status
2477bthci_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
2508static 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
2565static 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
2592static 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
2678static 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
2716static enum hci_status
2717bthci_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/* */
2760static enum hci_status
2761bthci_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 */
2809static 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 */
2845static 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
2884static 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
2946static enum hci_status
2947bthci_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
2964static enum hci_status
2965bthci_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
3013static enum hci_status bthci_CmdReadRSSI(struct rtw_adapter *padapter)
3014{
3015 enum hci_status status = HCI_STATUS_SUCCESS;
3016 return status;
3017}
3018
3019static enum hci_status
3020bthci_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
3037static enum hci_status
3038bthci_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
3055static enum hci_status
3056bthci_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
3116static enum hci_status
3117bthci_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
3189static enum hci_status
3190bthci_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
3231static enum hci_status
3232bthci_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
3247static enum hci_status
3248bthci_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
3289static enum hci_status
3290bthci_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
3331static enum hci_status
3332bthci_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
3391static enum hci_status
3392bthci_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
3433static enum hci_status
3434bthci_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
3486static enum hci_status
3487bthci_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
3527static enum hci_status
3528bthci_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
3571static enum hci_status
3572bthci_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
3649static enum hci_status
3650bthci_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
3726static enum hci_status
3727bthci_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
3766static enum hci_status
3767bthci_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
3809static enum hci_status
3810bthci_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
3853static enum hci_status
3854bthci_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
3901static enum hci_status
3902bthci_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
3940static enum hci_status
3941bthci_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
3982static enum hci_status
3983bthci_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
4068static enum hci_status
4069bthci_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
4134static enum hci_status
4135bthci_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
4170static enum hci_status
4171bthci_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
4179static enum hci_status
4180bthci_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
4195static enum hci_status
4196bthci_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
4231static enum hci_status
4232bthci_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
4335static enum hci_status
4336bthci_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
4379static enum hci_status
4380bthci_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
4427static enum hci_status
4428bthci_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
4457static enum hci_status
4458bthci_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
4524static void
4525bthci_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
4564static void
4565bthci_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
4616static void
4617bthci_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
4689static void
4690bthci_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
4742static void
4743bthci_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
4784static void
4785bthci_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
4870void BTHCI_EventParse(struct rtw_adapter *padapter, void *pEvntData, u32 dataLen)
4871{
4872}
4873
4874u8 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
4892static u8
4893BTHCI_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
4911void 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
4950void 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
4959void
4960BTHCI_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
5020void 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
5046void 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
5104void 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
5137void 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
5157enum hci_status
5158BTHCI_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
5222static 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
5236static 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
5255static 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
5268static 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
5285static 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
5300static 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! */
5313static void
5314btdm_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
5462static 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
5551static void
5552btdm_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
5558static 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
5575static 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 */
5607static 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
5687static 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
5753static 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
5836static 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
5917static 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
5948static 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
5969static void
5970btdm_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
6027static 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
6076void 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
6134static 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
6161static 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
6178static 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
6189static 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
6236static void
6237BTDM_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
6266void 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
6285static 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
6339static 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
6405void 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_ */
6446static 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
6668static 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
6689static void
6690btdm_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
6703static void
6704btdm_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
6719static void
6720btdm_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
6732static 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
6750static void
6751btdm_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
6770static void
6771btdm_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
6792static void
6793btdm_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
6814static void
6815btdm_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
6838static 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
6856static 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
6876static void
6877btdm_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
6906static 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
6923static void
6924btdm_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
6954static 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
7069static 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
7076static 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
7109static 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
7225static void
7226btdm_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, ¥u­n1¦¸ 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) */
7809static 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
7868static 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) */
7928static 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
8015static 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 */
8076static 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 */
8128static 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
8218static 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) */
8278static 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
8363static 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
8448static 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_ */
8514static 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
8559static void BTDM_2AntHwCoexAllOff8723A(struct rtw_adapter *padapter)
8560{
8561 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
8562}
8563
8564static 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
8572static 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
8581static 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
8751void 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
8927static u8 btCoexDbgBuf[BT_TMP_BUF_SIZE];
8928
8929static const char *const BtProfileString[] = {
8930 "NONE",
8931 "A2DP",
8932 "PAN",
8933 "HID",
8934 "SCO",
8935};
8936
8937static 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
8947static const char *const BtLinkRoleString[] = {
8948 "Master",
8949 "Slave",
8950};
8951
8952static 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
8968static 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 */
8998static 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
9062static 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_ */
9118u32 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
9128u32 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
9138void 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
9176u8 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
9189void 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
9235void 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
9266void 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
9282void
9283BTDM_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
9303void 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
9321u8 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
9335static void BTDM_AdjustForBtOperation8723A(struct rtw_adapter *padapter)
9336{
9337 /* BTDM_2AntAdjustForBtOperation8723(padapter); */
9338}
9339
9340static 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
9352static void
9353BTDM_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
9409static 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
9611static void
9612BTDM_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
9619static 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
9627static 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
9639static 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
9651static 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
9663static void
9664BTDM_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
9675void 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
9687static 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
9699static 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
9711static void
9712BTDM_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
9724static void
9725BTDM_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
9743static 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
9755u8 BTDM_1Ant8723A(struct rtw_adapter *padapter)
9756{
9757 if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9758 return true;
9759 else
9760 return false;
9761}
9762
9763static 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
9813static void BTDM_SetAntenna(struct rtw_adapter *padapter, u8 who)
9814{
9815}
9816
9817void
9818BTDM_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
9858void 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
10008void
10009BTDM_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 */
10057static 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
10065static 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/* */
10083void BTDM_CheckAntSelMode(struct rtw_adapter *padapter)
10084{
10085}
10086
10087void BTDM_FwC2hBtRssi(struct rtw_adapter *padapter, u8 *tmpBuf)
10088{
10089 BTDM_FwC2hBtRssi8723A(padapter, tmpBuf);
10090}
10091
10092void BTDM_FwC2hBtInfo(struct rtw_adapter *padapter, u8 *tmpBuf, u8 length)
10093{
10094 BTDM_FwC2hBtInfo8723A(padapter, tmpBuf, length);
10095}
10096
10097void BTDM_DisplayBtCoexInfo(struct rtw_adapter *padapter)
10098{
10099 BTDM_Display8723ABtCoexInfo(padapter);
10100}
10101
10102void BTDM_RejectAPAggregatedPacket(struct rtw_adapter *padapter, u8 bReject)
10103{
10104}
10105
10106u8 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
10121u8 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
10135void 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
10186s32 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
10206static 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 */
10225u8 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
10314u8 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
10403u8 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
10492u8 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
10553void
10554BTDM_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
10583void 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
10621void 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
10635void 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
10649void 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
10662void 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
10676void BTDM_CoexAllOff(struct rtw_adapter *padapter)
10677{
10678 BTDM_FWCoexAllOff(padapter);
10679 BTDM_SWCoexAllOff(padapter);
10680 BTDM_HWCoexAllOff(padapter);
10681}
10682
10683void 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
10704void BTDM_SignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi, u8 *rssi_bt)
10705{
10706 BTDM_8723ASignalCompensation(padapter, rssi_wifi, rssi_bt);
10707}
10708
10709void 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
10732void 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
10745u8 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
10757void 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
10803u8 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
10814u8 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
10829u8 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
10839u8 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
10857u8 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
10875u8 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
10890u8 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
10900u8 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
10910void BTDM_AdjustForBtOperation(struct rtw_adapter *padapter)
10911{
10912 RTPRINT(FBT, BT_TRACE, ("[BT][DM], BTDM_AdjustForBtOperation()\n"));
10913 BTDM_AdjustForBtOperation8723A(padapter);
10914}
10915
10916void BTDM_SetBtCoexCurrAntNum(struct rtw_adapter *padapter, u8 antNum)
10917{
10918 BTDM_Set8723ABtCoexCurrAntNum(padapter, antNum);
10919}
10920
10921void 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
10932void 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
10942void 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
10952void 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
10962void 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
10972void 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
10981u8 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
11009u8 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
11038u8 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
11067u8 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
11096u8 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
11125u8 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
11152u8 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
11178u8 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
11198static void halbt_InitHwConfig8723A(struct rtw_adapter *padapter)
11199{
11200}
11201
11202/* */
11203/*extern function */
11204/* */
11205u8 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
11212void 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
11227void 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
11243void 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
11276u8 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
11286u8 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
11293void HALBT_InitHwConfig(struct rtw_adapter *padapter)
11294{
11295 halbt_InitHwConfig8723A(padapter);
11296 BTDM_Coexist(padapter);
11297}
11298
11299void 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
30static 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******************************************/
51s32 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
111exit:
112 mutex_unlock(&adapter_to_dvobj(padapter)->h2c_fwcmd_mutex);
113 return ret;
114}
115
116u8 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
127u8 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 */
147void 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
175void 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
203static 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
298static 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
325static 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
397static 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. */
437void 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. */
451static 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
581exit:
582 kfree(ReservedPagePacket);
583}
584
585void 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
655static 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
740exit:
741 kfree(ReservedPagePacket);
742}
743
744void 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
775void 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
36static void dm_CheckStatistics(struct rtw_adapter *Adapter)
37{
38}
39
40static 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 */
85static 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
134static 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
181void 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
203void
204rtl8723a_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
255skip_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
262void 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
271void 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
23static 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
49static 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
135exit:
136 return ret;
137}
138
139static 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
151static 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
186exit:
187 return ret;
188}
189
190static 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
239void 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/* */
279s32 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
414Exit:
415 kfree(firmware_buf);
416 return rtStatus;
417}
418
419void 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
430static 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/* */
441static u8
442hal_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
478static void
479Hal_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
564static void
565Hal_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
613static void
614hal_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
704static void
705hal_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
817exit:
818 kfree(efuseTbl);
819}
820
821static void
822Hal_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
831static u16
832hal_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
882static u16
883hal_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
963static u16
964Hal_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
976static u8
977Hal_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
1035static s32
1036Hal_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
1113static u8
1114hal_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
1132static void
1133hal_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
1143static u8
1144hal_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
1193static u8
1194hal_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
1227static u8
1228hal_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
1295static u8
1296hal_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
1312static u8
1313hal_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
1331static s32
1332Hal_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
1359static bool
1360Hal_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
1387static 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
1437static 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/* */
1453void 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
1471void 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
1493static 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
1510static 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
1529static 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
1537static 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
1592static 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
1604static 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
1639static 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
1652s32 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
1661static 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
1716exit:
1717 return ret;
1718}
1719
1720void 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
1773void 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
1786void 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
1801void 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
1813void 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
1845u8 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/* */
1864static 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
1893s32 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
1933static void _DisableGPIO(struct rtw_adapter *padapter)
1934{
1935/***************************************
1936j. GPIO_PIN_CTRL 0x44[31:0]= 0x000
1937k.Value = GPIO_PIN_CTRL[7:0]
1938l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); write external PIN level
1939m. GPIO_MUXCFG 0x42 [15:0] = 0x0780
1940n. 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
1972static void _DisableRFAFEAndResetBB8192C(struct rtw_adapter *padapter)
1973{
1974/**************************************
1975a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue
1976b. RF path 0 offset 0x00 = 0x00 disable RF
1977c. APSD_CTRL 0x600[7:0] = 0x40
1978d. SYS_FUNC_EN 0x02[7:0] = 0x16 reset BB state machine
1979e. 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
2005static void _DisableRFAFEAndResetBB(struct rtw_adapter *padapter)
2006{
2007 _DisableRFAFEAndResetBB8192C(padapter);
2008}
2009
2010static 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
2100static void _ResetDigitalProcedure1(struct rtw_adapter *padapter,
2101 bool bWithoutHWSM)
2102{
2103 _ResetDigitalProcedure1_92C(padapter, bWithoutHWSM);
2104}
2105
2106static void _ResetDigitalProcedure2(struct rtw_adapter *padapter)
2107{
2108/*****************************
2109k. SYS_FUNC_EN 0x03[7:0] = 0x44 disable ELDR runction
2110l. SYS_CLKR 0x08[15:0] = 0x3083 disable ELDR clock
2111m. 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
2119static 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 */
2170s32 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 */
2196s32 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
2226void 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
2250void 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
2269static 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
2293static void
2294Hal_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
2369static 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
2383void
2384Hal_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
2472void
2473Hal_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
2506void
2507Hal_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
2521void
2522rtl8723a_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
2536void
2537Hal_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
2557void
2558Hal_EfuseParseAntennaDiversity(struct rtw_adapter *padapter,
2559 u8 *hwinfo, bool AutoLoadFail)
2560{
2561}
2562
2563void
2564Hal_EfuseParseRateIndicationOption(struct rtw_adapter *padapter,
2565 u8 *hwinfo, bool AutoLoadFail)
2566{
2567}
2568
2569void
2570Hal_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
2587void
2588Hal_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
2611void Hal_InitChannelPlan23a(struct rtw_adapter *padapter)
2612{
2613}
2614
2615static 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
2632static 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
2656static 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
2704static 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
2731static 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 */
2861void 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/* */
2889void 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
2938static 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
2999static 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
3010static 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
3021static 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
3058static 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
3070static 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
3132void 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
3321void 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
3392void 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
3439void 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
3446void rtl8723a_start_thread(struct rtw_adapter *padapter)
3447{
3448}
3449
3450void 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*/
56static 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*/
85u32
86PHY_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
118void
119PHY_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*/
161static u32
162phy_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*/
280static void
281phy_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*/
343u32
344PHY_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*/
380void
381PHY_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 *---------------------------------------------------------------------------*/
416s32 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*/
455static void
456phy_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 */
586static void
587storePwrIndexDiffRateOffset(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 *---------------------------------------------------------------------------*/
739static int
740phy_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
761static void
762phy_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
782static int
783phy_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
843phy_BB8190_Config_ParaFile_Fail:
844
845 return rtStatus;
846}
847
848int
849PHY_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
901int
902PHY_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
913static 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
938static 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 *---------------------------------------------------------------------------*/
957void 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 *---------------------------------------------------------------------------*/
991static 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 *---------------------------------------------------------------------------*/
1130void
1131PHY_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
1147static 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
1173void 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!!!!! */
46struct 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 *---------------------------------------------------------------------------*/
73void 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
110void 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 */
194static 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
229static 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
320static 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 *---------------------------------------------------------------------------*/
398void 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
413static 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 }
494phy_RF6052_Config_ParaFile_Fail:
495 return rtStatus;
496}
497
498int 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
21static 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
38static 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) */
62void 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
20void 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
63void 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
21void 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
42void 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. */
34void 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. */
61void 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 }
85exit:
86 pLed->bLedOn = false;
87}
88
89/* Interface to manipulate LED objects. */
90
91/* Description: */
92/* Initialize all LED_871x objects. */
93void
94rtl8723au_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. */
107void
108rtl8723au_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
27void rtl8723au_init_recvbuf(struct rtw_adapter *padapter,
28 struct recv_buf *precvbuf)
29{
30}
31
32int 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
100exit:
101 return res;
102}
103
104void 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
135void 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
179void 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
24s32 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
34void rtl8723au_free_xmit_priv(struct rtw_adapter *padapter)
35{
36}
37
38static 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
50static 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
69static 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
85static 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
109static 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
144static 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
160static 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
312static 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
380s32 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
430static 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 */
445static 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
499enqueue:
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
516s32 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 */
526s32 rtl8723au_hal_xmit(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe)
527{
528 return pre_xmitframe(padapter, pxmitframe);
529}
530
531s32 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
31static 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
66static 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
85static 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
105static 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? */
140static 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
152static 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
196static 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
214static 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
225static 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
238static 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
262static 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
307static 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
330static 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
350static void _InitQueuePriority(struct rtw_adapter *Adapter)
351{
352 _InitNormalChipQueuePriority(Adapter);
353}
354
355static 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
366static 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
375static void _InitDriverInfoSize(struct rtw_adapter *Adapter, u8 drvInfoSize)
376{
377 rtw_write8(Adapter, REG_RX_DRVINFO_SZ, drvInfoSize);
378}
379
380static 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
419static 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
442static 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
451static 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
470static 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
482static 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
489static 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 *---------------------------------------------------------------------------*/
516static 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 *---------------------------------------------------------------------------*/
535static void usb_AggSettingRxUpdate(struct rtw_adapter *Adapter)
536{
537} /* usb_AggSettingRxUpdate */
538
539static 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
553static void _InitOperationMode(struct rtw_adapter *Adapter)
554{
555}
556
557static 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" */
579static 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(...)
586static void _RfPowerSave(struct rtw_adapter *padapter)
587{
588}
589
590enum {
591 Antenna_Lfet = 1,
592 Antenna_Right = 2,
593};
594
595enum 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
615void _ps_open_RF23a(struct rtw_adapter *padapter);
616
617static 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
902exit:
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
910static 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
1163void _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
1169static 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
1210static 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
1226static 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]);
1269exit:
1270 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1271 ("<=== usb_inirp_init\n"));
1272 return status;
1273}
1274
1275static 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
1292static 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
1318static 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
1326static 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
1346static 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
1370static 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
1418static 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
1435static 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
1442static 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/* */
1458static 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
1467static 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
1492static 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
1501static 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 */
1519static 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 */
1541static 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/* */
1550static 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. */
1600static 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
1670static 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
1784static void rtl8723au_init_default_value(struct rtw_adapter *padapter)
1785{
1786 rtl8723a_init_default_value(padapter);
1787}
1788
1789static u8 rtl8192cu_ps_func(struct rtw_adapter *Adapter,
1790 enum hal_intf_ps_func efunc_id, u8 *val)
1791{
1792 return true;
1793}
1794
1795int 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
25static 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
121release_mutex:
122 mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex);
123exit:
124 return status;
125}
126
127static 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
148static 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
169static 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
190static 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
214static 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
237static 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
260static 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 */
304static bool
305InterruptRecognized8723AU(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
330static 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
389urb_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
426static 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
454static 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
599void 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
623static 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
723static 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
793void 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
818void 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
843void 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}