aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile1
-rw-r--r--drivers/net/wireless/rtlwifi/Kconfig15
-rw-r--r--drivers/net/wireless/rtlwifi/Makefile13
-rw-r--r--drivers/net/wireless/rtlwifi/base.c958
-rw-r--r--drivers/net/wireless/rtlwifi/base.h120
-rw-r--r--drivers/net/wireless/rtlwifi/cam.c291
-rw-r--r--drivers/net/wireless/rtlwifi/cam.h53
-rw-r--r--drivers/net/wireless/rtlwifi/core.c1029
-rw-r--r--drivers/net/wireless/rtlwifi/core.h42
-rw-r--r--drivers/net/wireless/rtlwifi/debug.c50
-rw-r--r--drivers/net/wireless/rtlwifi/debug.h212
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.c1189
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.h124
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c1933
-rw-r--r--drivers/net/wireless/rtlwifi/pci.h302
-rw-r--r--drivers/net/wireless/rtlwifi/ps.c492
-rw-r--r--drivers/net/wireless/rtlwifi/ps.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rc.c329
-rw-r--r--drivers/net/wireless/rtlwifi/rc.h40
-rw-r--r--drivers/net/wireless/rtlwifi/regd.c400
-rw-r--r--drivers/net/wireless/rtlwifi/regd.h61
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/Makefile12
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h257
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c1473
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h196
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c804
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h98
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c2173
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h57
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c144
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c2676
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h237
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h2065
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c523
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h44
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c280
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h37
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c1224
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h58
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c1031
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h714
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h1532
44 files changed, 23374 insertions, 0 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 4de4410cd38..b4338f38939 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -279,6 +279,7 @@ source "drivers/net/wireless/libertas/Kconfig"
279source "drivers/net/wireless/orinoco/Kconfig" 279source "drivers/net/wireless/orinoco/Kconfig"
280source "drivers/net/wireless/p54/Kconfig" 280source "drivers/net/wireless/p54/Kconfig"
281source "drivers/net/wireless/rt2x00/Kconfig" 281source "drivers/net/wireless/rt2x00/Kconfig"
282source "drivers/net/wireless/rtlwifi/Kconfig"
282source "drivers/net/wireless/wl1251/Kconfig" 283source "drivers/net/wireless/wl1251/Kconfig"
283source "drivers/net/wireless/wl12xx/Kconfig" 284source "drivers/net/wireless/wl12xx/Kconfig"
284source "drivers/net/wireless/zd1211rw/Kconfig" 285source "drivers/net/wireless/zd1211rw/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 06f8ca26c5c..9760561a27a 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_B43LEGACY) += b43legacy/
24obj-$(CONFIG_ZD1211RW) += zd1211rw/ 24obj-$(CONFIG_ZD1211RW) += zd1211rw/
25obj-$(CONFIG_RTL8180) += rtl818x/ 25obj-$(CONFIG_RTL8180) += rtl818x/
26obj-$(CONFIG_RTL8187) += rtl818x/ 26obj-$(CONFIG_RTL8187) += rtl818x/
27obj-$(CONFIG_RTL8192CE) += rtlwifi/
27 28
28# 16-bit wireless PCMCIA client drivers 29# 16-bit wireless PCMCIA client drivers
29obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o 30obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig
new file mode 100644
index 00000000000..d712026eb76
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/Kconfig
@@ -0,0 +1,15 @@
1config RTL8192CE
2 tristate "Realtek RTL8192CE/RTL8188SE Wireless Network Adapter"
3 depends on MAC80211 && EXPERIMENTAL
4 select FW_LOADER
5 select RTLWIFI
6 ---help---
7 This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe
8 wireless network adapters.
9
10 If you choose to build it as a module, it will be calledrtl8192ce.
11
12config RTLWIFI
13 tristate
14 depends on RTL8192CE
15 default m
diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile
new file mode 100644
index 00000000000..2a7a4384f8e
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/Makefile
@@ -0,0 +1,13 @@
1obj-$(CONFIG_RTLWIFI) += rtlwifi.o
2rtlwifi-objs := \
3 base.o \
4 cam.o \
5 core.o \
6 debug.o \
7 efuse.o \
8 pci.o \
9 ps.o \
10 rc.o \
11 regd.o
12
13obj-$(CONFIG_RTL8192CE) += rtl8192ce/
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
new file mode 100644
index 00000000000..9e860ff30b5
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -0,0 +1,958 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include <linux/ip.h>
31#include "wifi.h"
32#include "rc.h"
33#include "base.h"
34#include "efuse.h"
35#include "cam.h"
36#include "ps.h"
37#include "regd.h"
38
39/*
40 *NOTICE!!!: This file will be very big, we hsould
41 *keep it clear under follwing roles:
42 *
43 *This file include follwing part, so, if you add new
44 *functions into this file, please check which part it
45 *should includes. or check if you should add new part
46 *for this file:
47 *
48 *1) mac80211 init functions
49 *2) tx information functions
50 *3) functions called by core.c
51 *4) wq & timer callback functions
52 *5) frame process functions
53 *6) sysfs functions
54 *7) ...
55 */
56
57/*********************************************************
58 *
59 * mac80211 init functions
60 *
61 *********************************************************/
62static struct ieee80211_channel rtl_channeltable[] = {
63 {.center_freq = 2412, .hw_value = 1,},
64 {.center_freq = 2417, .hw_value = 2,},
65 {.center_freq = 2422, .hw_value = 3,},
66 {.center_freq = 2427, .hw_value = 4,},
67 {.center_freq = 2432, .hw_value = 5,},
68 {.center_freq = 2437, .hw_value = 6,},
69 {.center_freq = 2442, .hw_value = 7,},
70 {.center_freq = 2447, .hw_value = 8,},
71 {.center_freq = 2452, .hw_value = 9,},
72 {.center_freq = 2457, .hw_value = 10,},
73 {.center_freq = 2462, .hw_value = 11,},
74 {.center_freq = 2467, .hw_value = 12,},
75 {.center_freq = 2472, .hw_value = 13,},
76 {.center_freq = 2484, .hw_value = 14,},
77};
78
79static struct ieee80211_rate rtl_ratetable[] = {
80 {.bitrate = 10, .hw_value = 0x00,},
81 {.bitrate = 20, .hw_value = 0x01,},
82 {.bitrate = 55, .hw_value = 0x02,},
83 {.bitrate = 110, .hw_value = 0x03,},
84 {.bitrate = 60, .hw_value = 0x04,},
85 {.bitrate = 90, .hw_value = 0x05,},
86 {.bitrate = 120, .hw_value = 0x06,},
87 {.bitrate = 180, .hw_value = 0x07,},
88 {.bitrate = 240, .hw_value = 0x08,},
89 {.bitrate = 360, .hw_value = 0x09,},
90 {.bitrate = 480, .hw_value = 0x0a,},
91 {.bitrate = 540, .hw_value = 0x0b,},
92};
93
94static const struct ieee80211_supported_band rtl_band_2ghz = {
95 .band = IEEE80211_BAND_2GHZ,
96
97 .channels = rtl_channeltable,
98 .n_channels = ARRAY_SIZE(rtl_channeltable),
99
100 .bitrates = rtl_ratetable,
101 .n_bitrates = ARRAY_SIZE(rtl_ratetable),
102
103 .ht_cap = {0},
104};
105
106static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
107 struct ieee80211_sta_ht_cap *ht_cap)
108{
109 struct rtl_priv *rtlpriv = rtl_priv(hw);
110 struct rtl_phy *rtlphy = &(rtlpriv->phy);
111
112 ht_cap->ht_supported = true;
113 ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
114 IEEE80211_HT_CAP_SGI_40 |
115 IEEE80211_HT_CAP_SGI_20 |
116 IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
117
118 /*
119 *Maximum length of AMPDU that the STA can receive.
120 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
121 */
122 ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
123
124 /*Minimum MPDU start spacing , */
125 ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
126
127 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
128
129 /*
130 *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
131 *base on ant_num
132 *rx_mask: RX mask
133 *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
134 *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
135 *if rx_ant >=3 rx_mask[2]=0xff;
136 *if BW_40 rx_mask[4]=0x01;
137 *highest supported RX rate
138 */
139 if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) {
140
141 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T2R or 2T2R\n"));
142
143 ht_cap->mcs.rx_mask[0] = 0xFF;
144 ht_cap->mcs.rx_mask[1] = 0xFF;
145 ht_cap->mcs.rx_mask[4] = 0x01;
146
147 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
148 } else if (get_rf_type(rtlphy) == RF_1T1R) {
149
150 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n"));
151
152 ht_cap->mcs.rx_mask[0] = 0xFF;
153 ht_cap->mcs.rx_mask[1] = 0x00;
154 ht_cap->mcs.rx_mask[4] = 0x01;
155
156 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
157 }
158}
159
160static void _rtl_init_mac80211(struct ieee80211_hw *hw)
161{
162 struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
163 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
164 struct ieee80211_supported_band *sband;
165
166 /* <1> use mac->bands as mem for hw->wiphy->bands */
167 sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
168
169 /*
170 * <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
171 * to default value(1T1R)
172 */
173 memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz,
174 sizeof(struct ieee80211_supported_band));
175
176 /* <3> init ht cap base on ant_num */
177 _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
178
179 /* <4> set mac->sband to wiphy->sband */
180 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
181
182 /* <5> set hw caps */
183 hw->flags = IEEE80211_HW_SIGNAL_DBM |
184 IEEE80211_HW_RX_INCLUDES_FCS |
185 IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | /*PS*/
186 /*IEEE80211_HW_SUPPORTS_PS | */
187 /*IEEE80211_HW_PS_NULLFUNC_STACK | */
188 /*IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */
189 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0;
190
191 hw->wiphy->interface_modes =
192 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
193
194 hw->wiphy->rts_threshold = 2347;
195
196 hw->queues = AC_MAX;
197 hw->extra_tx_headroom = RTL_TX_HEADER_SIZE;
198
199 /* TODO: Correct this value for our hw */
200 /* TODO: define these hard code value */
201 hw->channel_change_time = 100;
202 hw->max_listen_interval = 5;
203 hw->max_rate_tries = 4;
204 /* hw->max_rates = 1; */
205
206 /* <6> mac address */
207 if (is_valid_ether_addr(rtlefuse->dev_addr)) {
208 SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr);
209 } else {
210 u8 rtlmac[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 };
211 get_random_bytes((rtlmac + (ETH_ALEN - 1)), 1);
212 SET_IEEE80211_PERM_ADDR(hw, rtlmac);
213 }
214
215}
216
217static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
218{
219 struct rtl_priv *rtlpriv = rtl_priv(hw);
220
221 /* <1> timer */
222 init_timer(&rtlpriv->works.watchdog_timer);
223 setup_timer(&rtlpriv->works.watchdog_timer,
224 rtl_watch_dog_timer_callback, (unsigned long)hw);
225
226 /* <2> work queue */
227 rtlpriv->works.hw = hw;
228 rtlpriv->works.rtl_wq = create_workqueue(rtlpriv->cfg->name);
229 INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
230 (void *)rtl_watchdog_wq_callback);
231 INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
232 (void *)rtl_ips_nic_off_wq_callback);
233
234}
235
236void rtl_deinit_deferred_work(struct ieee80211_hw *hw)
237{
238 struct rtl_priv *rtlpriv = rtl_priv(hw);
239
240 del_timer_sync(&rtlpriv->works.watchdog_timer);
241
242 cancel_delayed_work(&rtlpriv->works.watchdog_wq);
243 cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq);
244}
245
246void rtl_init_rfkill(struct ieee80211_hw *hw)
247{
248 struct rtl_priv *rtlpriv = rtl_priv(hw);
249
250 bool radio_state;
251 bool blocked;
252 u8 valid = 0;
253
254 /*set init state to rf on */
255 rtlpriv->rfkill.rfkill_state = 1;
256
257 radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
258
259 if (valid) {
260 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
261 (KERN_INFO "wireless switch is %s\n",
262 rtlpriv->rfkill.rfkill_state ? "on" : "off"));
263
264 rtlpriv->rfkill.rfkill_state = radio_state;
265
266 blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
267 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
268 }
269
270 wiphy_rfkill_start_polling(hw->wiphy);
271}
272
273void rtl_deinit_rfkill(struct ieee80211_hw *hw)
274{
275 wiphy_rfkill_stop_polling(hw->wiphy);
276}
277
278int rtl_init_core(struct ieee80211_hw *hw)
279{
280 struct rtl_priv *rtlpriv = rtl_priv(hw);
281 struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
282
283 /* <1> init mac80211 */
284 _rtl_init_mac80211(hw);
285 rtlmac->hw = hw;
286
287 /* <2> rate control register */
288 if (rtl_rate_control_register()) {
289 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
290 ("rtl: Unable to register rtl_rc,"
291 "use default RC !!\n"));
292 } else {
293 hw->rate_control_algorithm = "rtl_rc";
294 }
295
296 /*
297 * <3> init CRDA must come after init
298 * mac80211 hw in _rtl_init_mac80211.
299 */
300 if (rtl_regd_init(hw, rtl_reg_notifier)) {
301 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("REGD init failed\n"));
302 return 1;
303 } else {
304 /* CRDA regd hint must after init CRDA */
305 if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) {
306 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
307 ("regulatory_hint fail\n"));
308 }
309 }
310
311 /* <4> locks */
312 sema_init(&rtlpriv->locks.ips_sem, 1);
313 sema_init(&rtlpriv->locks.conf_sem, 1);
314 spin_lock_init(&rtlpriv->locks.irq_th_lock);
315 spin_lock_init(&rtlpriv->locks.h2c_lock);
316 spin_lock_init(&rtlpriv->locks.rf_ps_lock);
317 spin_lock_init(&rtlpriv->locks.rf_lock);
318 spin_lock_init(&rtlpriv->locks.lps_lock);
319
320 rtlmac->link_state = MAC80211_NOLINK;
321
322 /* <5> init deferred work */
323 _rtl_init_deferred_work(hw);
324
325 return 0;
326}
327
328void rtl_deinit_core(struct ieee80211_hw *hw)
329{
330 /*RC*/
331 rtl_rate_control_unregister();
332}
333
334void rtl_init_rx_config(struct ieee80211_hw *hw)
335{
336 struct rtl_priv *rtlpriv = rtl_priv(hw);
337 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
338
339 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
340 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MGT_FILTER,
341 (u8 *) (&mac->rx_mgt_filter));
342 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CTRL_FILTER,
343 (u8 *) (&mac->rx_ctrl_filter));
344 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_DATA_FILTER,
345 (u8 *) (&mac->rx_data_filter));
346}
347
348/*********************************************************
349 *
350 * tx information functions
351 *
352 *********************************************************/
353static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw,
354 struct rtl_tcb_desc *tcb_desc,
355 struct ieee80211_tx_info *info)
356{
357 struct rtl_priv *rtlpriv = rtl_priv(hw);
358 u8 rate_flag = info->control.rates[0].flags;
359
360 tcb_desc->use_shortpreamble = false;
361
362 /* 1M can only use Long Preamble. 11B spec */
363 if (tcb_desc->hw_rate == rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M])
364 return;
365 else if (rate_flag & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
366 tcb_desc->use_shortpreamble = true;
367
368 return;
369}
370
371static void _rtl_query_shortgi(struct ieee80211_hw *hw,
372 struct rtl_tcb_desc *tcb_desc,
373 struct ieee80211_tx_info *info)
374{
375 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
376 u8 rate_flag = info->control.rates[0].flags;
377
378 tcb_desc->use_shortgi = false;
379
380 if (!mac->ht_enable)
381 return;
382
383 if (!mac->sgi_40 && !mac->sgi_20)
384 return;
385
386 if ((mac->bw_40 == true) && mac->sgi_40)
387 tcb_desc->use_shortgi = true;
388 else if ((mac->bw_40 == false) && mac->sgi_20)
389 tcb_desc->use_shortgi = true;
390
391 if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI))
392 tcb_desc->use_shortgi = false;
393
394}
395
396static void _rtl_query_protection_mode(struct ieee80211_hw *hw,
397 struct rtl_tcb_desc *tcb_desc,
398 struct ieee80211_tx_info *info)
399{
400 struct rtl_priv *rtlpriv = rtl_priv(hw);
401 u8 rate_flag = info->control.rates[0].flags;
402
403 /* Common Settings */
404 tcb_desc->b_rts_stbc = false;
405 tcb_desc->b_cts_enable = false;
406 tcb_desc->rts_sc = 0;
407 tcb_desc->b_rts_bw = false;
408 tcb_desc->b_rts_use_shortpreamble = false;
409 tcb_desc->b_rts_use_shortgi = false;
410
411 if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) {
412 /* Use CTS-to-SELF in protection mode. */
413 tcb_desc->b_rts_enable = true;
414 tcb_desc->b_cts_enable = true;
415 tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
416 } else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
417 /* Use RTS-CTS in protection mode. */
418 tcb_desc->b_rts_enable = true;
419 tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
420 }
421
422}
423
424static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
425 struct rtl_tcb_desc *tcb_desc)
426{
427 struct rtl_priv *rtlpriv = rtl_priv(hw);
428 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
429
430 if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) {
431 if (mac->opmode == NL80211_IFTYPE_STATION)
432 tcb_desc->ratr_index = 0;
433 else if (mac->opmode == NL80211_IFTYPE_ADHOC) {
434 if (tcb_desc->b_multicast || tcb_desc->b_broadcast) {
435 tcb_desc->hw_rate =
436 rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M];
437 tcb_desc->use_driver_rate = 1;
438 } else {
439 /* TODO */
440 }
441 }
442 }
443
444 if (rtlpriv->dm.b_useramask) {
445 /* TODO we will differentiate adhoc and station futrue */
446 tcb_desc->mac_id = 0;
447
448 if ((mac->mode == WIRELESS_MODE_N_24G) ||
449 (mac->mode == WIRELESS_MODE_N_5G)) {
450 tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB;
451 } else if (mac->mode & WIRELESS_MODE_G) {
452 tcb_desc->ratr_index = RATR_INX_WIRELESS_GB;
453 } else if (mac->mode & WIRELESS_MODE_B) {
454 tcb_desc->ratr_index = RATR_INX_WIRELESS_B;
455 }
456 }
457
458}
459
460static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw,
461 struct rtl_tcb_desc *tcb_desc)
462{
463 struct rtl_priv *rtlpriv = rtl_priv(hw);
464 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
465
466 tcb_desc->b_packet_bw = false;
467
468 if (!mac->bw_40 || !mac->ht_enable)
469 return;
470
471 if (tcb_desc->b_multicast || tcb_desc->b_broadcast)
472 return;
473
474 /*use legency rate, shall use 20MHz */
475 if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M])
476 return;
477
478 tcb_desc->b_packet_bw = true;
479}
480
481static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw)
482{
483 struct rtl_priv *rtlpriv = rtl_priv(hw);
484 struct rtl_phy *rtlphy = &(rtlpriv->phy);
485 u8 hw_rate;
486
487 if (get_rf_type(rtlphy) == RF_2T2R)
488 hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15];
489 else
490 hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7];
491
492 return hw_rate;
493}
494
495void rtl_get_tcb_desc(struct ieee80211_hw *hw,
496 struct ieee80211_tx_info *info,
497 struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc)
498{
499 struct rtl_priv *rtlpriv = rtl_priv(hw);
500 struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
501 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
502 struct ieee80211_rate *txrate;
503 u16 fc = le16_to_cpu(hdr->frame_control);
504
505 memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc));
506
507 if (ieee80211_is_data(fc)) {
508 txrate = ieee80211_get_tx_rate(hw, info);
509 tcb_desc->hw_rate = txrate->hw_value;
510
511 /*
512 *we set data rate RTL_RC_CCK_RATE1M
513 *in rtl_rc.c if skb is special data or
514 *mgt which need low data rate.
515 */
516
517 /*
518 *So tcb_desc->hw_rate is just used for
519 *special data and mgt frames
520 */
521 if (tcb_desc->hw_rate < rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]) {
522 tcb_desc->use_driver_rate = true;
523 tcb_desc->ratr_index = 7;
524
525 tcb_desc->hw_rate =
526 rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
527 tcb_desc->disable_ratefallback = 1;
528 } else {
529 /*
530 *because hw will nerver use hw_rate
531 *when tcb_desc->use_driver_rate = false
532 *so we never set highest N rate here,
533 *and N rate will all be controled by FW
534 *when tcb_desc->use_driver_rate = false
535 */
536 if (rtlmac->ht_enable) {
537 tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw);
538 } else {
539 if (rtlmac->mode == WIRELESS_MODE_B) {
540 tcb_desc->hw_rate =
541 rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
542 } else {
543 tcb_desc->hw_rate =
544 rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
545 }
546 }
547 }
548
549 if (is_multicast_ether_addr(ieee80211_get_DA(hdr)))
550 tcb_desc->b_multicast = 1;
551 else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
552 tcb_desc->b_broadcast = 1;
553
554 _rtl_txrate_selectmode(hw, tcb_desc);
555 _rtl_query_bandwidth_mode(hw, tcb_desc);
556 _rtl_qurey_shortpreamble_mode(hw, tcb_desc, info);
557 _rtl_query_shortgi(hw, tcb_desc, info);
558 _rtl_query_protection_mode(hw, tcb_desc, info);
559 } else {
560 tcb_desc->use_driver_rate = true;
561 tcb_desc->ratr_index = 7;
562 tcb_desc->disable_ratefallback = 1;
563 tcb_desc->mac_id = 0;
564
565 tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
566 }
567}
568EXPORT_SYMBOL(rtl_get_tcb_desc);
569
570bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
571{
572 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
573 struct rtl_priv *rtlpriv = rtl_priv(hw);
574 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
575 u16 fc = le16_to_cpu(hdr->frame_control);
576
577 if (ieee80211_is_auth(fc)) {
578 RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
579 rtl_ips_nic_on(hw);
580
581 mac->link_state = MAC80211_LINKING;
582 }
583
584 return true;
585}
586
587bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
588{
589 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
590 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
591 struct rtl_priv *rtlpriv = rtl_priv(hw);
592 u16 fc = le16_to_cpu(hdr->frame_control);
593 u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN));
594 u8 category;
595
596 if (!ieee80211_is_action(fc))
597 return true;
598
599 category = *act;
600 act++;
601 switch (category) {
602 case ACT_CAT_BA:
603 switch (*act) {
604 case ACT_ADDBAREQ:
605 if (mac->act_scanning)
606 return false;
607
608 RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
609 ("%s ACT_ADDBAREQ From :" MAC_FMT "\n",
610 is_tx ? "Tx" : "Rx", MAC_ARG(hdr->addr2)));
611 break;
612 case ACT_ADDBARSP:
613 RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
614 ("%s ACT_ADDBARSP From :" MAC_FMT "\n",
615 is_tx ? "Tx" : "Rx", MAC_ARG(hdr->addr2)));
616 break;
617 case ACT_DELBA:
618 RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
619 ("ACT_ADDBADEL From :" MAC_FMT "\n",
620 MAC_ARG(hdr->addr2)));
621 break;
622 }
623 break;
624 default:
625 break;
626 }
627
628 return true;
629}
630
631/*should call before software enc*/
632u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
633{
634 struct rtl_priv *rtlpriv = rtl_priv(hw);
635 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
636 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
637 u16 fc = le16_to_cpu(hdr->frame_control);
638 u16 ether_type;
639 u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);
640 const struct iphdr *ip;
641
642 if (!ieee80211_is_data(fc))
643 goto end;
644
645 if (ieee80211_is_nullfunc(fc))
646 return true;
647
648 ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len +
649 SNAP_SIZE + PROTOC_TYPE_SIZE);
650 ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE);
651 ether_type = ntohs(ether_type);
652
653 if (ETH_P_IP == ether_type) {
654 if (IPPROTO_UDP == ip->protocol) {
655 struct udphdr *udp = (struct udphdr *)((u8 *) ip +
656 (ip->ihl << 2));
657 if (((((u8 *) udp)[1] == 68) &&
658 (((u8 *) udp)[3] == 67)) ||
659 ((((u8 *) udp)[1] == 67) &&
660 (((u8 *) udp)[3] == 68))) {
661 /*
662 * 68 : UDP BOOTP client
663 * 67 : UDP BOOTP server
664 */
665 RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV),
666 DBG_DMESG, ("dhcp %s !!\n",
667 (is_tx) ? "Tx" : "Rx"));
668
669 if (is_tx) {
670 rtl_lps_leave(hw);
671 ppsc->last_delaylps_stamp_jiffies =
672 jiffies;
673 }
674
675 return true;
676 }
677 }
678 } else if (ETH_P_ARP == ether_type) {
679 if (is_tx) {
680 rtl_lps_leave(hw);
681 ppsc->last_delaylps_stamp_jiffies = jiffies;
682 }
683
684 return true;
685 } else if (ETH_P_PAE == ether_type) {
686 RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
687 ("802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"));
688
689 if (is_tx) {
690 rtl_lps_leave(hw);
691 ppsc->last_delaylps_stamp_jiffies = jiffies;
692 }
693
694 return true;
695 } else if (0x86DD == ether_type) {
696 return true;
697 }
698
699end:
700 return false;
701}
702
703/*********************************************************
704 *
705 * functions called by core.c
706 *
707 *********************************************************/
708int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, u16 tid, u16 *ssn)
709{
710 struct rtl_priv *rtlpriv = rtl_priv(hw);
711 struct rtl_tid_data *tid_data;
712 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
713
714 RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
715 ("on ra = %pM tid = %d\n", ra, tid));
716
717 if (unlikely(tid >= MAX_TID_COUNT))
718 return -EINVAL;
719
720 if (mac->tids[tid].agg.agg_state != RTL_AGG_OFF) {
721 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
722 ("Start AGG when state is not RTL_AGG_OFF !\n"));
723 return -ENXIO;
724 }
725
726 tid_data = &mac->tids[tid];
727 *ssn = SEQ_TO_SN(tid_data->seq_number);
728
729 RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
730 ("HW queue is empty tid:%d\n", tid));
731 tid_data->agg.agg_state = RTL_AGG_ON;
732
733 ieee80211_start_tx_ba_cb_irqsafe(mac->vif, ra, tid);
734
735 return 0;
736}
737
738int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 * ra, u16 tid)
739{
740 int ssn = -1;
741 struct rtl_priv *rtlpriv = rtl_priv(hw);
742 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
743 struct rtl_tid_data *tid_data;
744
745 if (!ra) {
746 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
747 return -EINVAL;
748 }
749
750 if (unlikely(tid >= MAX_TID_COUNT))
751 return -EINVAL;
752
753 if (mac->tids[tid].agg.agg_state != RTL_AGG_ON)
754 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
755 ("Stopping AGG while state not ON or starting\n"));
756
757 tid_data = &mac->tids[tid];
758 ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
759
760 mac->tids[tid].agg.agg_state = RTL_AGG_OFF;
761
762 ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, ra, tid);
763
764 return 0;
765}
766
767/*********************************************************
768 *
769 * wq & timer callback functions
770 *
771 *********************************************************/
772void rtl_watchdog_wq_callback(void *data)
773{
774 struct rtl_works *rtlworks = container_of_dwork_rtl(data,
775 struct rtl_works,
776 watchdog_wq);
777 struct ieee80211_hw *hw = rtlworks->hw;
778 struct rtl_priv *rtlpriv = rtl_priv(hw);
779 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
780 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
781
782 bool b_busytraffic = false;
783 bool b_higher_busytraffic = false;
784 bool b_higher_busyrxtraffic = false;
785 bool b_higher_busytxtraffic = false;
786
787 u8 idx = 0;
788 u32 rx_cnt_inp4eriod = 0;
789 u32 tx_cnt_inp4eriod = 0;
790 u32 aver_rx_cnt_inperiod = 0;
791 u32 aver_tx_cnt_inperiod = 0;
792
793 bool benter_ps = false;
794
795 if (is_hal_stop(rtlhal))
796 return;
797
798 /* <1> Determine if action frame is allowed */
799 if (mac->link_state > MAC80211_NOLINK) {
800 if (mac->cnt_after_linked < 20)
801 mac->cnt_after_linked++;
802 } else {
803 mac->cnt_after_linked = 0;
804 }
805
806 /* <2> DM */
807 rtlpriv->cfg->ops->dm_watchdog(hw);
808
809 /*
810 *<3> to check if traffic busy, if
811 * busytraffic we don't change channel
812 */
813 if (mac->link_state >= MAC80211_LINKED) {
814
815 /* (1) get aver_rx_cnt_inperiod & aver_tx_cnt_inperiod */
816 for (idx = 0; idx <= 2; idx++) {
817 rtlpriv->link_info.num_rx_in4period[idx] =
818 rtlpriv->link_info.num_rx_in4period[idx + 1];
819 rtlpriv->link_info.num_tx_in4period[idx] =
820 rtlpriv->link_info.num_tx_in4period[idx + 1];
821 }
822 rtlpriv->link_info.num_rx_in4period[3] =
823 rtlpriv->link_info.num_rx_inperiod;
824 rtlpriv->link_info.num_tx_in4period[3] =
825 rtlpriv->link_info.num_tx_inperiod;
826 for (idx = 0; idx <= 3; idx++) {
827 rx_cnt_inp4eriod +=
828 rtlpriv->link_info.num_rx_in4period[idx];
829 tx_cnt_inp4eriod +=
830 rtlpriv->link_info.num_tx_in4period[idx];
831 }
832 aver_rx_cnt_inperiod = rx_cnt_inp4eriod / 4;
833 aver_tx_cnt_inperiod = tx_cnt_inp4eriod / 4;
834
835 /* (2) check traffic busy */
836 if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100)
837 b_busytraffic = true;
838
839 /* Higher Tx/Rx data. */
840 if (aver_rx_cnt_inperiod > 4000 ||
841 aver_tx_cnt_inperiod > 4000) {
842 b_higher_busytraffic = true;
843
844 /* Extremely high Rx data. */
845 if (aver_rx_cnt_inperiod > 5000)
846 b_higher_busyrxtraffic = true;
847 else
848 b_higher_busytxtraffic = false;
849 }
850
851 if (((rtlpriv->link_info.num_rx_inperiod +
852 rtlpriv->link_info.num_tx_inperiod) > 8) ||
853 (rtlpriv->link_info.num_rx_inperiod > 2))
854 benter_ps = false;
855 else
856 benter_ps = true;
857
858 /* LeisurePS only work in infra mode. */
859 if (benter_ps)
860 rtl_lps_enter(hw);
861 else
862 rtl_lps_leave(hw);
863 }
864
865 rtlpriv->link_info.num_rx_inperiod = 0;
866 rtlpriv->link_info.num_tx_inperiod = 0;
867
868 rtlpriv->link_info.b_busytraffic = b_busytraffic;
869 rtlpriv->link_info.b_higher_busytraffic = b_higher_busytraffic;
870 rtlpriv->link_info.b_higher_busyrxtraffic = b_higher_busyrxtraffic;
871
872}
873
874void rtl_watch_dog_timer_callback(unsigned long data)
875{
876 struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
877 struct rtl_priv *rtlpriv = rtl_priv(hw);
878
879 queue_delayed_work(rtlpriv->works.rtl_wq,
880 &rtlpriv->works.watchdog_wq, 0);
881
882 mod_timer(&rtlpriv->works.watchdog_timer,
883 jiffies + MSECS(RTL_WATCH_DOG_TIME));
884}
885
886/*********************************************************
887 *
888 * sysfs functions
889 *
890 *********************************************************/
891static ssize_t rtl_show_debug_level(struct device *d,
892 struct device_attribute *attr, char *buf)
893{
894 struct ieee80211_hw *hw = dev_get_drvdata(d);
895 struct rtl_priv *rtlpriv = rtl_priv(hw);
896
897 return sprintf(buf, "0x%08X\n", rtlpriv->dbg.global_debuglevel);
898}
899
900static ssize_t rtl_store_debug_level(struct device *d,
901 struct device_attribute *attr,
902 const char *buf, size_t count)
903{
904 struct ieee80211_hw *hw = dev_get_drvdata(d);
905 struct rtl_priv *rtlpriv = rtl_priv(hw);
906 unsigned long val;
907 int ret;
908
909 ret = strict_strtoul(buf, 0, &val);
910 if (ret) {
911 printk(KERN_DEBUG "%s is not in hex or decimal form.\n", buf);
912 } else {
913 rtlpriv->dbg.global_debuglevel = val;
914 printk(KERN_DEBUG "debuglevel:%x\n",
915 rtlpriv->dbg.global_debuglevel);
916 }
917
918 return strnlen(buf, count);
919}
920
921static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
922 rtl_show_debug_level, rtl_store_debug_level);
923
924static struct attribute *rtl_sysfs_entries[] = {
925
926 &dev_attr_debug_level.attr,
927
928 NULL
929};
930
931/*
932 * "name" is folder name witch will be
933 * put in device directory like :
934 * sys/devices/pci0000:00/0000:00:1c.4/
935 * 0000:06:00.0/rtl_sysfs
936 */
937struct attribute_group rtl_attribute_group = {
938 .name = "rtlsysfs",
939 .attrs = rtl_sysfs_entries,
940};
941
942MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
943MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
944MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
945MODULE_LICENSE("GPL");
946MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
947
948static int __init rtl_core_module_init(void)
949{
950 return 0;
951}
952
953static void __exit rtl_core_module_exit(void)
954{
955}
956
957module_init(rtl_core_module_init);
958module_exit(rtl_core_module_exit);
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
new file mode 100644
index 00000000000..3de5a14745f
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -0,0 +1,120 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *****************************************************************************/
28
29#ifndef __RTL_BASE_H__
30#define __RTL_BASE_H__
31
32#define RTL_DUMMY_OFFSET 0
33#define RTL_DUMMY_UNIT 8
34#define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT)
35#define RTL_TX_DESC_SIZE 32
36#define RTL_TX_HEADER_SIZE (RTL_TX_DESC_SIZE + RTL_TX_DUMMY_SIZE)
37
38#define HT_AMSDU_SIZE_4K 3839
39#define HT_AMSDU_SIZE_8K 7935
40
41#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
42#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
43
44#define RTL_RATE_COUNT_LEGACY 12
45#define RTL_CHANNEL_COUNT 14
46
47#define FRAME_OFFSET_FRAME_CONTROL 0
48#define FRAME_OFFSET_DURATION 2
49#define FRAME_OFFSET_ADDRESS1 4
50#define FRAME_OFFSET_ADDRESS2 10
51#define FRAME_OFFSET_ADDRESS3 16
52#define FRAME_OFFSET_SEQUENCE 22
53#define FRAME_OFFSET_ADDRESS4 24
54
55#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \
56 WRITEEF2BYTE(_hdr, _val)
57#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \
58 WRITEEF1BYTE(_hdr, _val)
59#define SET_80211_HDR_PWR_MGNT(_hdr, _val) \
60 SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val)
61#define SET_80211_HDR_TO_DS(_hdr, _val) \
62 SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)
63
64#define SET_80211_PS_POLL_AID(_hdr, _val) \
65 WRITEEF2BYTE(((u8 *)(_hdr)) + 2, _val)
66#define SET_80211_PS_POLL_BSSID(_hdr, _val) \
67 CP_MACADDR(((u8 *)(_hdr)) + 4, (u8 *)(_val))
68#define SET_80211_PS_POLL_TA(_hdr, _val) \
69 CP_MACADDR(((u8 *)(_hdr)) + 10, (u8 *)(_val))
70
71#define SET_80211_HDR_DURATION(_hdr, _val) \
72 WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_DURATION, _val)
73#define SET_80211_HDR_ADDRESS1(_hdr, _val) \
74 CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val))
75#define SET_80211_HDR_ADDRESS2(_hdr, _val) \
76 CP_MACADDR((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val))
77#define SET_80211_HDR_ADDRESS3(_hdr, _val) \
78 CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val))
79#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \
80 WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val)
81
82#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \
83 WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val)
84#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \
85 WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val)
86#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \
87 WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val)
88#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \
89 READEF2BYTE(((u8 *)(__phdr)) + 34)
90#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
91 WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val)
92#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
93 SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \
94 (GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val))))
95
96int rtl_init_core(struct ieee80211_hw *hw);
97void rtl_deinit_core(struct ieee80211_hw *hw);
98void rtl_init_rx_config(struct ieee80211_hw *hw);
99void rtl_init_rfkill(struct ieee80211_hw *hw);
100void rtl_deinit_rfkill(struct ieee80211_hw *hw);
101
102void rtl_watch_dog_timer_callback(unsigned long data);
103void rtl_deinit_deferred_work(struct ieee80211_hw *hw);
104
105bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
106bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
107u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
108
109void rtl_watch_dog_timer_callback(unsigned long data);
110int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra,
111 u16 tid, u16 *ssn);
112int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid);
113void rtl_watchdog_wq_callback(void *data);
114
115void rtl_get_tcb_desc(struct ieee80211_hw *hw,
116 struct ieee80211_tx_info *info,
117 struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc);
118
119extern struct attribute_group rtl_attribute_group;
120#endif
diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c
new file mode 100644
index 00000000000..52c9c1367ca
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/cam.c
@@ -0,0 +1,291 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 *****************************************************************************/
27
28#include "wifi.h"
29#include "cam.h"
30
31void rtl_cam_reset_sec_info(struct ieee80211_hw *hw)
32{
33 struct rtl_priv *rtlpriv = rtl_priv(hw);
34
35 rtlpriv->sec.use_defaultkey = false;
36 rtlpriv->sec.pairwise_enc_algorithm = NO_ENCRYPTION;
37 rtlpriv->sec.group_enc_algorithm = NO_ENCRYPTION;
38 memset(rtlpriv->sec.key_buf, 0, KEY_BUF_SIZE * MAX_KEY_LEN);
39 memset(rtlpriv->sec.key_len, 0, KEY_BUF_SIZE);
40 rtlpriv->sec.pairwise_key = NULL;
41}
42
43static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
44 u8 *mac_addr, u8 *key_cont_128, u16 us_config)
45{
46 struct rtl_priv *rtlpriv = rtl_priv(hw);
47
48 u32 target_command;
49 u32 target_content = 0;
50 u8 entry_i;
51
52 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
53 ("key_cont_128:\n %x:%x:%x:%x:%x:%x\n",
54 key_cont_128[0], key_cont_128[1],
55 key_cont_128[2], key_cont_128[3],
56 key_cont_128[4], key_cont_128[5]));
57
58 for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
59 target_command = entry_i + CAM_CONTENT_COUNT * entry_no;
60 target_command = target_command | BIT(31) | BIT(16);
61
62 if (entry_i == 0) {
63 target_content = (u32) (*(mac_addr + 0)) << 16 |
64 (u32) (*(mac_addr + 1)) << 24 | (u32) us_config;
65
66 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
67 target_content);
68 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
69 target_command);
70
71 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
72 ("rtl_cam_program_entry(): "
73 "WRITE %x: %x\n",
74 rtlpriv->cfg->maps[WCAMI], target_content));
75 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
76 ("The Key ID is %d\n", entry_no));
77 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
78 ("rtl_cam_program_entry(): "
79 "WRITE %x: %x\n",
80 rtlpriv->cfg->maps[RWCAM], target_command));
81
82 } else if (entry_i == 1) {
83
84 target_content = (u32) (*(mac_addr + 5)) << 24 |
85 (u32) (*(mac_addr + 4)) << 16 |
86 (u32) (*(mac_addr + 3)) << 8 |
87 (u32) (*(mac_addr + 2));
88
89 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
90 target_content);
91 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
92 target_command);
93
94 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
95 ("rtl_cam_program_entry(): WRITE A4: %x\n",
96 target_content));
97 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
98 ("rtl_cam_program_entry(): WRITE A0: %x\n",
99 target_command));
100
101 } else {
102
103 target_content =
104 (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 3)) <<
105 24 | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 2))
106 << 16 |
107 (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 1)) << 8
108 | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 0));
109
110 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
111 target_content);
112 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
113 target_command);
114 udelay(100);
115
116 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
117 ("rtl_cam_program_entry(): WRITE A4: %x\n",
118 target_content));
119 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
120 ("rtl_cam_program_entry(): WRITE A0: %x\n",
121 target_command));
122 }
123 }
124
125 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
126 ("after set key, usconfig:%x\n", us_config));
127}
128
129u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
130 u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
131 u32 ul_default_key, u8 *key_content)
132{
133 u32 us_config;
134 struct rtl_priv *rtlpriv = rtl_priv(hw);
135
136 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
137 ("EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, "
138 "ulUseDK=%x MacAddr" MAC_FMT "\n",
139 ul_entry_idx, ul_key_id, ul_enc_alg,
140 ul_default_key, MAC_ARG(mac_addr)));
141
142 if (ul_key_id == TOTAL_CAM_ENTRY) {
143 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
144 ("<=== ulKeyId exceed!\n"));
145 return 0;
146 }
147
148 if (ul_default_key == 1) {
149 us_config = CFG_VALID | ((u16) (ul_enc_alg) << 2);
150 } else {
151 us_config = CFG_VALID | ((ul_enc_alg) << 2) | ul_key_id;
152 }
153
154 rtl_cam_program_entry(hw, ul_entry_idx, mac_addr,
155 (u8 *) key_content, us_config);
156
157 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("<===\n"));
158
159 return 1;
160
161}
162EXPORT_SYMBOL(rtl_cam_add_one_entry);
163
164int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
165 u8 *mac_addr, u32 ul_key_id)
166{
167 u32 ul_command;
168 struct rtl_priv *rtlpriv = rtl_priv(hw);
169
170 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("key_idx:%d\n", ul_key_id));
171
172 ul_command = ul_key_id * CAM_CONTENT_COUNT;
173 ul_command = ul_command | BIT(31) | BIT(16);
174
175 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], 0);
176 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
177
178 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
179 ("rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0));
180 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
181 ("rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command));
182
183 return 0;
184
185}
186EXPORT_SYMBOL(rtl_cam_delete_one_entry);
187
188void rtl_cam_reset_all_entry(struct ieee80211_hw *hw)
189{
190 u32 ul_command;
191 struct rtl_priv *rtlpriv = rtl_priv(hw);
192
193 ul_command = BIT(31) | BIT(30);
194 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
195}
196EXPORT_SYMBOL(rtl_cam_reset_all_entry);
197
198void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index)
199{
200 struct rtl_priv *rtlpriv = rtl_priv(hw);
201
202 u32 ul_command;
203 u32 ul_content;
204 u32 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
205
206 switch (rtlpriv->sec.pairwise_enc_algorithm) {
207 case WEP40_ENCRYPTION:
208 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
209 break;
210 case WEP104_ENCRYPTION:
211 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
212 break;
213 case TKIP_ENCRYPTION:
214 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
215 break;
216 case AESCCMP_ENCRYPTION:
217 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
218 break;
219 default:
220 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
221 }
222
223 ul_content = (uc_index & 3) | ((u16) (ul_enc_algo) << 2);
224
225 ul_content |= BIT(15);
226 ul_command = CAM_CONTENT_COUNT * uc_index;
227 ul_command = ul_command | BIT(31) | BIT(16);
228
229 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
230 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
231
232 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
233 ("rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content));
234 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
235 ("rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command));
236}
237EXPORT_SYMBOL(rtl_cam_mark_invalid);
238
239void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)
240{
241 struct rtl_priv *rtlpriv = rtl_priv(hw);
242
243 u32 ul_command;
244 u32 ul_content;
245 u32 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
246 u8 entry_i;
247
248 switch (rtlpriv->sec.pairwise_enc_algorithm) {
249 case WEP40_ENCRYPTION:
250 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
251 break;
252 case WEP104_ENCRYPTION:
253 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
254 break;
255 case TKIP_ENCRYPTION:
256 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
257 break;
258 case AESCCMP_ENCRYPTION:
259 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
260 break;
261 default:
262 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
263 }
264
265 for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
266
267 if (entry_i == 0) {
268 ul_content =
269 (uc_index & 0x03) | ((u16) (ul_encalgo) << 2);
270 ul_content |= BIT(15);
271
272 } else {
273 ul_content = 0;
274 }
275
276 ul_command = CAM_CONTENT_COUNT * uc_index + entry_i;
277 ul_command = ul_command | BIT(31) | BIT(16);
278
279 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
280 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
281
282 RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
283 ("rtl_cam_empty_entry(): WRITE A4: %x\n",
284 ul_content));
285 RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
286 ("rtl_cam_empty_entry(): WRITE A0: %x\n",
287 ul_command));
288 }
289
290}
291EXPORT_SYMBOL(rtl_cam_empty_entry);
diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h
new file mode 100644
index 00000000000..dd82f057d53
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/cam.h
@@ -0,0 +1,53 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 *****************************************************************************/
27
28#ifndef __RTL_CAM_H_
29#define __RTL_CAM_H_
30
31#define TOTAL_CAM_ENTRY 32
32#define CAM_CONTENT_COUNT 8
33
34#define CFG_DEFAULT_KEY BIT(5)
35#define CFG_VALID BIT(15)
36
37#define PAIRWISE_KEYIDX 0
38#define CAM_PAIRWISE_KEY_POSITION 4
39
40#define CAM_CONFIG_USEDK 1
41#define CAM_CONFIG_NO_USEDK 0
42
43extern void rtl_cam_reset_all_entry(struct ieee80211_hw *hw);
44extern u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
45 u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
46 u32 ul_default_key, u8 *key_content);
47int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
48 u32 ul_key_id);
49void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index);
50void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index);
51void rtl_cam_reset_sec_info(struct ieee80211_hw *hw);
52
53#endif
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
new file mode 100644
index 00000000000..81b290ff8a9
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -0,0 +1,1029 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *****************************************************************************/
28
29#include "wifi.h"
30#include "core.h"
31#include "cam.h"
32#include "base.h"
33#include "ps.h"
34
35/*mutex for start & stop is must here. */
36static int rtl_op_start(struct ieee80211_hw *hw)
37{
38 int err = 0;
39 struct rtl_priv *rtlpriv = rtl_priv(hw);
40 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
41
42 if (!is_hal_stop(rtlhal))
43 return 0;
44 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
45 return 0;
46 down(&rtlpriv->locks.conf_sem);
47 err = rtlpriv->intf_ops->adapter_start(hw);
48 if (err)
49 goto out;
50 rtl_watch_dog_timer_callback((unsigned long)hw);
51out:
52 up(&rtlpriv->locks.conf_sem);
53 return err;
54}
55
56static void rtl_op_stop(struct ieee80211_hw *hw)
57{
58 struct rtl_priv *rtlpriv = rtl_priv(hw);
59 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
60 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
61 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
62
63 if (is_hal_stop(rtlhal))
64 return;
65
66 if (unlikely(ppsc->rfpwr_state == ERFOFF)) {
67 rtl_ips_nic_on(hw);
68 mdelay(1);
69 }
70
71 down(&rtlpriv->locks.conf_sem);
72
73 mac->link_state = MAC80211_NOLINK;
74 memset(mac->bssid, 0, 6);
75
76 /*reset sec info */
77 rtl_cam_reset_sec_info(hw);
78
79 rtl_deinit_deferred_work(hw);
80 rtlpriv->intf_ops->adapter_stop(hw);
81
82 up(&rtlpriv->locks.conf_sem);
83}
84
85static int rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
86{
87 struct rtl_priv *rtlpriv = rtl_priv(hw);
88 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
89 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
90
91 if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
92 goto err_free;
93
94 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
95 goto err_free;
96
97
98 rtlpriv->intf_ops->adapter_tx(hw, skb);
99
100 return NETDEV_TX_OK;
101
102err_free:
103 dev_kfree_skb_any(skb);
104 return NETDEV_TX_OK;
105}
106
107static int rtl_op_add_interface(struct ieee80211_hw *hw,
108 struct ieee80211_vif *vif)
109{
110 struct rtl_priv *rtlpriv = rtl_priv(hw);
111 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
112 int err = 0;
113
114 if (mac->vif) {
115 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
116 ("vif has been set!! mac->vif = 0x%p\n", mac->vif));
117 return -EOPNOTSUPP;
118 }
119
120 rtl_ips_nic_on(hw);
121
122 down(&rtlpriv->locks.conf_sem);
123 switch (vif->type) {
124 case NL80211_IFTYPE_STATION:
125 if (mac->beacon_enabled == 1) {
126 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
127 ("NL80211_IFTYPE_STATION\n"));
128 mac->beacon_enabled = 0;
129 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
130 rtlpriv->cfg->maps
131 [RTL_IBSS_INT_MASKS]);
132 }
133 break;
134 case NL80211_IFTYPE_ADHOC:
135 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
136 ("NL80211_IFTYPE_ADHOC\n"));
137
138 mac->link_state = MAC80211_LINKED;
139 rtlpriv->cfg->ops->set_bcn_reg(hw);
140 break;
141 case NL80211_IFTYPE_AP:
142 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
143 ("NL80211_IFTYPE_AP\n"));
144 break;
145 default:
146 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
147 ("operation mode %d is not support!\n", vif->type));
148 err = -EOPNOTSUPP;
149 goto out;
150 }
151
152 mac->vif = vif;
153 mac->opmode = vif->type;
154 rtlpriv->cfg->ops->set_network_type(hw, vif->type);
155 memcpy(mac->mac_addr, vif->addr, ETH_ALEN);
156 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
157
158out:
159 up(&rtlpriv->locks.conf_sem);
160 return err;
161}
162
163static void rtl_op_remove_interface(struct ieee80211_hw *hw,
164 struct ieee80211_vif *vif)
165{
166 struct rtl_priv *rtlpriv = rtl_priv(hw);
167 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
168
169 down(&rtlpriv->locks.conf_sem);
170
171 /* Free beacon resources */
172 if ((mac->opmode == NL80211_IFTYPE_AP) ||
173 (mac->opmode == NL80211_IFTYPE_ADHOC) ||
174 (mac->opmode == NL80211_IFTYPE_MESH_POINT)) {
175 if (mac->beacon_enabled == 1) {
176 mac->beacon_enabled = 0;
177 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
178 rtlpriv->cfg->maps
179 [RTL_IBSS_INT_MASKS]);
180 }
181 }
182
183 /*
184 *Note: We assume NL80211_IFTYPE_UNSPECIFIED as
185 *NO LINK for our hardware.
186 */
187 mac->vif = NULL;
188 mac->link_state = MAC80211_NOLINK;
189 memset(mac->bssid, 0, 6);
190 mac->opmode = NL80211_IFTYPE_UNSPECIFIED;
191 rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
192
193 up(&rtlpriv->locks.conf_sem);
194}
195
196
197static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
198{
199 struct rtl_priv *rtlpriv = rtl_priv(hw);
200 struct rtl_phy *rtlphy = &(rtlpriv->phy);
201 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
202 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
203 struct ieee80211_conf *conf = &hw->conf;
204
205 down(&rtlpriv->locks.conf_sem);
206 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /*BIT(2)*/
207 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
208 ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"));
209 }
210
211 /*For IPS */
212 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
213 if (hw->conf.flags & IEEE80211_CONF_IDLE)
214 rtl_ips_nic_off(hw);
215 else
216 rtl_ips_nic_on(hw);
217 } else {
218 /*
219 *although rfoff may not cause by ips, but we will
220 *check the reason in set_rf_power_state function
221 */
222 if (unlikely(ppsc->rfpwr_state == ERFOFF))
223 rtl_ips_nic_on(hw);
224 }
225
226 /*For LPS */
227 if (changed & IEEE80211_CONF_CHANGE_PS) {
228 if (conf->flags & IEEE80211_CONF_PS)
229 rtl_lps_enter(hw);
230 else
231 rtl_lps_leave(hw);
232 }
233
234 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
235 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
236 ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
237 hw->conf.long_frame_max_tx_count));
238 mac->retry_long = hw->conf.long_frame_max_tx_count;
239 mac->retry_short = hw->conf.long_frame_max_tx_count;
240 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
241 (u8 *) (&hw->conf.
242 long_frame_max_tx_count));
243 }
244
245 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
246 struct ieee80211_channel *channel = hw->conf.channel;
247 u8 wide_chan = (u8) channel->hw_value;
248
249 /*
250 *because we should back channel to
251 *current_network.chan in in scanning,
252 *So if set_chan == current_network.chan
253 *we should set it.
254 *because mac80211 tell us wrong bw40
255 *info for cisco1253 bw20, so we modify
256 *it here based on UPPER & LOWER
257 */
258 switch (hw->conf.channel_type) {
259 case NL80211_CHAN_HT20:
260 case NL80211_CHAN_NO_HT:
261 /* SC */
262 mac->cur_40_prime_sc =
263 PRIME_CHNL_OFFSET_DONT_CARE;
264 rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20;
265 mac->bw_40 = false;
266 break;
267 case NL80211_CHAN_HT40MINUS:
268 /* SC */
269 mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER;
270 rtlphy->current_chan_bw =
271 HT_CHANNEL_WIDTH_20_40;
272 mac->bw_40 = true;
273
274 /*wide channel */
275 wide_chan -= 2;
276
277 break;
278 case NL80211_CHAN_HT40PLUS:
279 /* SC */
280 mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER;
281 rtlphy->current_chan_bw =
282 HT_CHANNEL_WIDTH_20_40;
283 mac->bw_40 = true;
284
285 /*wide channel */
286 wide_chan += 2;
287
288 break;
289 default:
290 mac->bw_40 = false;
291 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
292 ("switch case not processed\n"));
293 break;
294 }
295
296 if (wide_chan <= 0)
297 wide_chan = 1;
298 rtlphy->current_channel = wide_chan;
299
300 rtlpriv->cfg->ops->set_channel_access(hw);
301 rtlpriv->cfg->ops->switch_channel(hw);
302 rtlpriv->cfg->ops->set_bw_mode(hw,
303 hw->conf.channel_type);
304 }
305
306 up(&rtlpriv->locks.conf_sem);
307
308 return 0;
309}
310
311static void rtl_op_configure_filter(struct ieee80211_hw *hw,
312 unsigned int changed_flags,
313 unsigned int *new_flags, u64 multicast)
314{
315 struct rtl_priv *rtlpriv = rtl_priv(hw);
316 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
317
318 *new_flags &= RTL_SUPPORTED_FILTERS;
319 if (!changed_flags)
320 return;
321
322 /*TODO: we disable broadcase now, so enable here */
323 if (changed_flags & FIF_ALLMULTI) {
324 if (*new_flags & FIF_ALLMULTI) {
325 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] |
326 rtlpriv->cfg->maps[MAC_RCR_AB];
327 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
328 ("Enable receive multicast frame.\n"));
329 } else {
330 mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] |
331 rtlpriv->cfg->maps[MAC_RCR_AB]);
332 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
333 ("Disable receive multicast frame.\n"));
334 }
335 }
336
337 if (changed_flags & FIF_FCSFAIL) {
338 if (*new_flags & FIF_FCSFAIL) {
339 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32];
340 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
341 ("Enable receive FCS error frame.\n"));
342 } else {
343 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];
344 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
345 ("Disable receive FCS error frame.\n"));
346 }
347 }
348
349 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
350 /*
351 *TODO: BIT(5) is probe response BIT(8) is beacon
352 *TODO: Use define for BIT(5) and BIT(8)
353 */
354 if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
355 mac->rx_mgt_filter |= (BIT(5) | BIT(8));
356 else
357 mac->rx_mgt_filter &= ~(BIT(5) | BIT(8));
358 }
359
360 if (changed_flags & FIF_CONTROL) {
361 if (*new_flags & FIF_CONTROL) {
362 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
363 mac->rx_ctrl_filter |= RTL_SUPPORTED_CTRL_FILTER;
364
365 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
366 ("Enable receive control frame.\n"));
367 } else {
368 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
369 mac->rx_ctrl_filter &= ~RTL_SUPPORTED_CTRL_FILTER;
370 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
371 ("Disable receive control frame.\n"));
372 }
373 }
374
375 if (changed_flags & FIF_OTHER_BSS) {
376 if (*new_flags & FIF_OTHER_BSS) {
377 mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP];
378 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
379 ("Enable receive other BSS's frame.\n"));
380 } else {
381 mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP];
382 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
383 ("Disable receive other BSS's frame.\n"));
384 }
385 }
386
387 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
388 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MGT_FILTER,
389 (u8 *) (&mac->rx_mgt_filter));
390 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CTRL_FILTER,
391 (u8 *) (&mac->rx_ctrl_filter));
392}
393
394static int _rtl_get_hal_qnum(u16 queue)
395{
396 int qnum;
397
398 switch (queue) {
399 case 0:
400 qnum = AC3_VO;
401 break;
402 case 1:
403 qnum = AC2_VI;
404 break;
405 case 2:
406 qnum = AC0_BE;
407 break;
408 case 3:
409 qnum = AC1_BK;
410 break;
411 default:
412 qnum = AC0_BE;
413 break;
414 }
415 return qnum;
416}
417
418/*
419 *for mac80211 VO=0, VI=1, BE=2, BK=3
420 *for rtl819x BE=0, BK=1, VI=2, VO=3
421 */
422static int rtl_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
423 const struct ieee80211_tx_queue_params *param)
424{
425 struct rtl_priv *rtlpriv = rtl_priv(hw);
426 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
427 int aci;
428
429 if (queue >= AC_MAX) {
430 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
431 ("queue number %d is incorrect!\n", queue));
432 return -EINVAL;
433 }
434
435 aci = _rtl_get_hal_qnum(queue);
436 mac->ac[aci].aifs = param->aifs;
437 mac->ac[aci].cw_min = param->cw_min;
438 mac->ac[aci].cw_max = param->cw_max;
439 mac->ac[aci].tx_op = param->txop;
440 memcpy(&mac->edca_param[aci], param, sizeof(*param));
441 rtlpriv->cfg->ops->set_qos(hw, aci);
442 return 0;
443}
444
445static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
446 struct ieee80211_vif *vif,
447 struct ieee80211_bss_conf *bss_conf, u32 changed)
448{
449 struct rtl_priv *rtlpriv = rtl_priv(hw);
450 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
451 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
452
453 down(&rtlpriv->locks.conf_sem);
454
455 if ((vif->type == NL80211_IFTYPE_ADHOC) ||
456 (vif->type == NL80211_IFTYPE_AP) ||
457 (vif->type == NL80211_IFTYPE_MESH_POINT)) {
458
459 if ((changed & BSS_CHANGED_BEACON) ||
460 (changed & BSS_CHANGED_BEACON_ENABLED &&
461 bss_conf->enable_beacon)) {
462
463 if (mac->beacon_enabled == 0) {
464 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
465 ("BSS_CHANGED_BEACON_ENABLED\n"));
466
467 /*start hw beacon interrupt. */
468 /*rtlpriv->cfg->ops->set_bcn_reg(hw); */
469 mac->beacon_enabled = 1;
470 rtlpriv->cfg->ops->update_interrupt_mask(hw,
471 rtlpriv->cfg->maps
472 [RTL_IBSS_INT_MASKS],
473 0);
474 }
475 } else {
476 if (mac->beacon_enabled == 1) {
477 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
478 ("ADHOC DISABLE BEACON\n"));
479
480 mac->beacon_enabled = 0;
481 rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
482 rtlpriv->cfg->maps
483 [RTL_IBSS_INT_MASKS]);
484 }
485 }
486
487 if (changed & BSS_CHANGED_BEACON_INT) {
488 RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE,
489 ("BSS_CHANGED_BEACON_INT\n"));
490 mac->beacon_interval = bss_conf->beacon_int;
491 rtlpriv->cfg->ops->set_bcn_intv(hw);
492 }
493 }
494
495 /*TODO: reference to enum ieee80211_bss_change */
496 if (changed & BSS_CHANGED_ASSOC) {
497 if (bss_conf->assoc) {
498 mac->link_state = MAC80211_LINKED;
499 mac->cnt_after_linked = 0;
500 mac->assoc_id = bss_conf->aid;
501 memcpy(mac->bssid, bss_conf->bssid, 6);
502
503 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
504 ("BSS_CHANGED_ASSOC\n"));
505 } else {
506 if (mac->link_state == MAC80211_LINKED)
507 rtl_lps_leave(hw);
508
509 mac->link_state = MAC80211_NOLINK;
510 memset(mac->bssid, 0, 6);
511
512 /* reset sec info */
513 rtl_cam_reset_sec_info(hw);
514
515 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
516 ("BSS_CHANGED_UN_ASSOC\n"));
517 }
518 }
519
520 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
521 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
522 ("BSS_CHANGED_ERP_CTS_PROT\n"));
523 mac->use_cts_protect = bss_conf->use_cts_prot;
524 }
525
526 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
527 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
528 ("BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n",
529 bss_conf->use_short_preamble));
530
531 mac->short_preamble = bss_conf->use_short_preamble;
532 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE,
533 (u8 *) (&mac->short_preamble));
534 }
535
536 if (changed & BSS_CHANGED_ERP_SLOT) {
537 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
538 ("BSS_CHANGED_ERP_SLOT\n"));
539
540 if (bss_conf->use_short_slot)
541 mac->slot_time = RTL_SLOT_TIME_9;
542 else
543 mac->slot_time = RTL_SLOT_TIME_20;
544
545 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
546 (u8 *) (&mac->slot_time));
547 }
548
549 if (changed & BSS_CHANGED_HT) {
550 struct ieee80211_sta *sta = NULL;
551
552 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
553 ("BSS_CHANGED_HT\n"));
554
555 sta = ieee80211_find_sta(mac->vif, mac->bssid);
556
557 if (sta) {
558 if (sta->ht_cap.ampdu_density >
559 mac->current_ampdu_density)
560 mac->current_ampdu_density =
561 sta->ht_cap.ampdu_density;
562 if (sta->ht_cap.ampdu_factor <
563 mac->current_ampdu_factor)
564 mac->current_ampdu_factor =
565 sta->ht_cap.ampdu_factor;
566 }
567
568 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY,
569 (u8 *) (&mac->max_mss_density));
570 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR,
571 &mac->current_ampdu_factor);
572 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE,
573 &mac->current_ampdu_density);
574 }
575
576 if (changed & BSS_CHANGED_BSSID) {
577 struct ieee80211_sta *sta = NULL;
578 u32 basic_rates;
579 u8 i;
580
581 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,
582 (u8 *) bss_conf->bssid);
583
584 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
585 (MAC_FMT "\n", MAC_ARG(bss_conf->bssid)));
586
587 memcpy(mac->bssid, bss_conf->bssid, 6);
588 if (is_valid_ether_addr(bss_conf->bssid)) {
589 switch (vif->type) {
590 case NL80211_IFTYPE_UNSPECIFIED:
591 break;
592 case NL80211_IFTYPE_ADHOC:
593 break;
594 case NL80211_IFTYPE_STATION:
595 break;
596 case NL80211_IFTYPE_AP:
597 break;
598 default:
599 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
600 ("switch case not process\n"));
601 break;
602 }
603 rtlpriv->cfg->ops->set_network_type(hw, vif->type);
604 } else
605 rtlpriv->cfg->ops->set_network_type(hw,
606 NL80211_IFTYPE_UNSPECIFIED);
607
608 memset(mac->mcs, 0, 16);
609 mac->ht_enable = false;
610 mac->sgi_40 = false;
611 mac->sgi_20 = false;
612
613 if (!bss_conf->use_short_slot)
614 mac->mode = WIRELESS_MODE_B;
615 else
616 mac->mode = WIRELESS_MODE_G;
617
618 sta = ieee80211_find_sta(mac->vif, mac->bssid);
619
620 if (sta) {
621 if (sta->ht_cap.ht_supported) {
622 mac->mode = WIRELESS_MODE_N_24G;
623 mac->ht_enable = true;
624 }
625
626 if (mac->ht_enable) {
627 u16 ht_cap = sta->ht_cap.cap;
628 memcpy(mac->mcs, (u8 *) (&sta->ht_cap.mcs), 16);
629
630 for (i = 0; i < 16; i++)
631 RT_TRACE(rtlpriv, COMP_MAC80211,
632 DBG_LOUD, ("%x ",
633 mac->mcs[i]));
634 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
635 ("\n"));
636
637 if (ht_cap & IEEE80211_HT_CAP_SGI_40)
638 mac->sgi_40 = true;
639
640 if (ht_cap & IEEE80211_HT_CAP_SGI_20)
641 mac->sgi_20 = true;
642
643 /*
644 * for cisco 1252 bw20 it's wrong
645 * if (ht_cap &
646 * IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
647 * mac->bw_40 = true;
648 * }
649 */
650 }
651 }
652
653 /*mac80211 just give us CCK rates any time
654 *So we add G rate in basic rates when
655 not in B mode*/
656 if (changed & BSS_CHANGED_BASIC_RATES) {
657 if (mac->mode == WIRELESS_MODE_B)
658 basic_rates = bss_conf->basic_rates | 0x00f;
659 else
660 basic_rates = bss_conf->basic_rates | 0xff0;
661
662 if (!vif)
663 goto out;
664
665 mac->basic_rates = basic_rates;
666 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
667 (u8 *) (&basic_rates));
668
669 if (rtlpriv->dm.b_useramask)
670 rtlpriv->cfg->ops->update_rate_mask(hw, 0);
671 else
672 rtlpriv->cfg->ops->update_rate_table(hw);
673
674 }
675 }
676
677 /*
678 * For FW LPS:
679 * To tell firmware we have connected
680 * to an AP. For 92SE/CE power save v2.
681 */
682 if (changed & BSS_CHANGED_ASSOC) {
683 if (bss_conf->assoc) {
684 if (ppsc->b_fwctrl_lps) {
685 u8 mstatus = RT_MEDIA_CONNECT;
686 rtlpriv->cfg->ops->set_hw_reg(hw,
687 HW_VAR_H2C_FW_JOINBSSRPT,
688 (u8 *) (&mstatus));
689 ppsc->report_linked = true;
690 }
691 } else {
692 if (ppsc->b_fwctrl_lps) {
693 u8 mstatus = RT_MEDIA_DISCONNECT;
694 rtlpriv->cfg->ops->set_hw_reg(hw,
695 HW_VAR_H2C_FW_JOINBSSRPT,
696 (u8 *)(&mstatus));
697 ppsc->report_linked = false;
698 }
699 }
700 }
701
702out:
703 up(&rtlpriv->locks.conf_sem);
704}
705
706static u64 rtl_op_get_tsf(struct ieee80211_hw *hw)
707{
708 struct rtl_priv *rtlpriv = rtl_priv(hw);
709 u64 tsf;
710
711 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&tsf));
712 return tsf;
713}
714
715static void rtl_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
716{
717 struct rtl_priv *rtlpriv = rtl_priv(hw);
718 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
719 u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;;
720
721 mac->tsf = tsf;
722 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&bibss));
723}
724
725static void rtl_op_reset_tsf(struct ieee80211_hw *hw)
726{
727 struct rtl_priv *rtlpriv = rtl_priv(hw);
728 u8 tmp = 0;
729
730 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, (u8 *) (&tmp));
731}
732
733static void rtl_op_sta_notify(struct ieee80211_hw *hw,
734 struct ieee80211_vif *vif,
735 enum sta_notify_cmd cmd,
736 struct ieee80211_sta *sta)
737{
738 switch (cmd) {
739 case STA_NOTIFY_SLEEP:
740 break;
741 case STA_NOTIFY_AWAKE:
742 break;
743 default:
744 break;
745 }
746}
747
748static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
749 struct ieee80211_vif *vif,
750 enum ieee80211_ampdu_mlme_action action,
751 struct ieee80211_sta *sta, u16 tid, u16 * ssn)
752{
753 struct rtl_priv *rtlpriv = rtl_priv(hw);
754
755 switch (action) {
756 case IEEE80211_AMPDU_TX_START:
757 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
758 ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid));
759 return rtl_tx_agg_start(hw, sta->addr, tid, ssn);
760 break;
761 case IEEE80211_AMPDU_TX_STOP:
762 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
763 ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid));
764 return rtl_tx_agg_stop(hw, sta->addr, tid);
765 break;
766 case IEEE80211_AMPDU_TX_OPERATIONAL:
767 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
768 ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid));
769 break;
770 case IEEE80211_AMPDU_RX_START:
771 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
772 ("IEEE80211_AMPDU_RX_START:TID:%d\n", tid));
773 break;
774 case IEEE80211_AMPDU_RX_STOP:
775 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
776 ("IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid));
777 break;
778 default:
779 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
780 ("IEEE80211_AMPDU_ERR!!!!:\n"));
781 return -EOPNOTSUPP;
782 }
783 return 0;
784}
785
786static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)
787{
788 struct rtl_priv *rtlpriv = rtl_priv(hw);
789 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
790
791 mac->act_scanning = true;
792
793 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n"));
794
795 if (mac->link_state == MAC80211_LINKED) {
796 rtl_lps_leave(hw);
797 mac->link_state = MAC80211_LINKED_SCANNING;
798 } else
799 rtl_ips_nic_on(hw);
800
801 rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY);
802 rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP);
803}
804
805static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
806{
807 struct rtl_priv *rtlpriv = rtl_priv(hw);
808 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
809
810 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n"));
811
812 rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
813 mac->act_scanning = false;
814 if (mac->link_state == MAC80211_LINKED_SCANNING) {
815 mac->link_state = MAC80211_LINKED;
816
817 /* fix fwlps issue */
818 rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
819
820 if (rtlpriv->dm.b_useramask)
821 rtlpriv->cfg->ops->update_rate_mask(hw, 0);
822 else
823 rtlpriv->cfg->ops->update_rate_table(hw);
824
825 }
826
827}
828
829static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
830 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
831 struct ieee80211_key_conf *key)
832{
833 struct rtl_priv *rtlpriv = rtl_priv(hw);
834 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
835 u8 key_type = NO_ENCRYPTION;
836 u8 key_idx;
837 bool group_key = false;
838 bool wep_only = false;
839 int err = 0;
840 u8 mac_addr[ETH_ALEN];
841 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
842 u8 zero_addr[ETH_ALEN] = { 0 };
843
844 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
845 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
846 ("not open hw encryption\n"));
847 return -ENOSPC; /*User disabled HW-crypto */
848 }
849 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
850 ("%s hardware based encryption for keyidx: %d, mac: %pM\n",
851 cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
852 sta ? sta->addr : bcast_addr));
853 rtlpriv->sec.being_setkey = true;
854 rtl_ips_nic_on(hw);
855 down(&rtlpriv->locks.conf_sem);
856 /* <1> get encryption alg */
857 switch (key->cipher) {
858 case WLAN_CIPHER_SUITE_WEP40:
859 key_type = WEP40_ENCRYPTION;
860 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n"));
861 rtlpriv->sec.use_defaultkey = true;
862 break;
863 case WLAN_CIPHER_SUITE_WEP104:
864 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
865 ("alg:WEP104\n"));
866 key_type = WEP104_ENCRYPTION;
867 rtlpriv->sec.use_defaultkey = true;
868 break;
869 case WLAN_CIPHER_SUITE_TKIP:
870 key_type = TKIP_ENCRYPTION;
871 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
872 if (mac->opmode == NL80211_IFTYPE_ADHOC)
873 rtlpriv->sec.use_defaultkey = true;
874 break;
875 case WLAN_CIPHER_SUITE_CCMP:
876 key_type = AESCCMP_ENCRYPTION;
877 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
878 if (mac->opmode == NL80211_IFTYPE_ADHOC)
879 rtlpriv->sec.use_defaultkey = true;
880 break;
881 default:
882 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
883 ("alg_err:%x!!!!:\n", key->cipher));
884 goto out_unlock;
885 }
886 /* <2> get key_idx */
887 key_idx = (u8) (key->keyidx);
888 if (key_idx > 3)
889 goto out_unlock;
890 /* <3> if pairwise key enable_hw_sec */
891 group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
892 if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) ||
893 rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {
894 if (rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION &&
895 (key_type == WEP40_ENCRYPTION ||
896 key_type == WEP104_ENCRYPTION))
897 wep_only = true;
898 rtlpriv->sec.pairwise_enc_algorithm = key_type;
899 rtlpriv->cfg->ops->enable_hw_sec(hw);
900 }
901 /* <4> set key based on cmd */
902 switch (cmd) {
903 case SET_KEY:
904 if (wep_only) {
905 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
906 ("set WEP(group/pairwise) key\n"));
907 /* Pairwise key with an assigned MAC address. */
908 rtlpriv->sec.pairwise_enc_algorithm = key_type;
909 rtlpriv->sec.group_enc_algorithm = key_type;
910 /*set local buf about wep key. */
911 memcpy(rtlpriv->sec.key_buf[key_idx],
912 key->key, key->keylen);
913 rtlpriv->sec.key_len[key_idx] = key->keylen;
914 memcpy(mac_addr, zero_addr, ETH_ALEN);
915 } else if (group_key) { /* group key */
916 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
917 ("set group key\n"));
918 /* group key */
919 rtlpriv->sec.group_enc_algorithm = key_type;
920 /*set local buf about group key. */
921 memcpy(rtlpriv->sec.key_buf[key_idx],
922 key->key, key->keylen);
923 rtlpriv->sec.key_len[key_idx] = key->keylen;
924 memcpy(mac_addr, bcast_addr, ETH_ALEN);
925 } else { /* pairwise key */
926 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
927 ("set pairwise key\n"));
928 if (!sta) {
929 RT_ASSERT(false, ("pairwise key withnot"
930 "mac_addr\n"));
931 err = -EOPNOTSUPP;
932 goto out_unlock;
933 }
934 /* Pairwise key with an assigned MAC address. */
935 rtlpriv->sec.pairwise_enc_algorithm = key_type;
936 /*set local buf about pairwise key. */
937 memcpy(rtlpriv->sec.key_buf[PAIRWISE_KEYIDX],
938 key->key, key->keylen);
939 rtlpriv->sec.key_len[PAIRWISE_KEYIDX] = key->keylen;
940 rtlpriv->sec.pairwise_key =
941 rtlpriv->sec.key_buf[PAIRWISE_KEYIDX];
942 memcpy(mac_addr, sta->addr, ETH_ALEN);
943 }
944 rtlpriv->cfg->ops->set_key(hw, key_idx, mac_addr,
945 group_key, key_type, wep_only,
946 false);
947 /* <5> tell mac80211 do something: */
948 /*must use sw generate IV, or can not work !!!!. */
949 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
950 key->hw_key_idx = key_idx;
951 if (key_type == TKIP_ENCRYPTION)
952 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
953 break;
954 case DISABLE_KEY:
955 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
956 ("disable key delete one entry\n"));
957 /*set local buf about wep key. */
958 memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen);
959 rtlpriv->sec.key_len[key_idx] = 0;
960 memcpy(mac_addr, zero_addr, ETH_ALEN);
961 /*
962 *mac80211 will delete entrys one by one,
963 *so don't use rtl_cam_reset_all_entry
964 *or clear all entry here.
965 */
966 rtl_cam_delete_one_entry(hw, mac_addr, key_idx);
967 break;
968 default:
969 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
970 ("cmd_err:%x!!!!:\n", cmd));
971 }
972out_unlock:
973 up(&rtlpriv->locks.conf_sem);
974 rtlpriv->sec.being_setkey = false;
975 return err;
976}
977
978static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
979{
980 struct rtl_priv *rtlpriv = rtl_priv(hw);
981
982 bool radio_state;
983 bool blocked;
984 u8 valid = 0;
985
986 if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
987 return;
988
989 down(&rtlpriv->locks.conf_sem);
990
991 /*if Radio On return true here */
992 radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
993
994 if (valid) {
995 if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) {
996 rtlpriv->rfkill.rfkill_state = radio_state;
997
998 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
999 (KERN_INFO "wireless radio switch turned %s\n",
1000 radio_state ? "on" : "off"));
1001
1002 blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
1003 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1004 }
1005 }
1006
1007 up(&rtlpriv->locks.conf_sem);
1008}
1009
1010const struct ieee80211_ops rtl_ops = {
1011 .start = rtl_op_start,
1012 .stop = rtl_op_stop,
1013 .tx = rtl_op_tx,
1014 .add_interface = rtl_op_add_interface,
1015 .remove_interface = rtl_op_remove_interface,
1016 .config = rtl_op_config,
1017 .configure_filter = rtl_op_configure_filter,
1018 .set_key = rtl_op_set_key,
1019 .conf_tx = rtl_op_conf_tx,
1020 .bss_info_changed = rtl_op_bss_info_changed,
1021 .get_tsf = rtl_op_get_tsf,
1022 .set_tsf = rtl_op_set_tsf,
1023 .reset_tsf = rtl_op_reset_tsf,
1024 .sta_notify = rtl_op_sta_notify,
1025 .ampdu_action = rtl_op_ampdu_action,
1026 .sw_scan_start = rtl_op_sw_scan_start,
1027 .sw_scan_complete = rtl_op_sw_scan_complete,
1028 .rfkill_poll = rtl_op_rfkill_poll,
1029};
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h
new file mode 100644
index 00000000000..0ef31c3c619
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -0,0 +1,42 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * Tmis 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 * Tmis 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 * You should have received a copy of the GNU General Public License along with
15 * tmis program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * Tme full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *****************************************************************************/
28
29#ifndef __RTL_CORE_H__
30#define __RTL_CORE_H__
31
32#define RTL_SUPPORTED_FILTERS \
33 (FIF_PROMISC_IN_BSS | \
34 FIF_ALLMULTI | FIF_CONTROL | \
35 FIF_OTHER_BSS | \
36 FIF_FCSFAIL | \
37 FIF_BCN_PRBRESP_PROMISC)
38
39#define RTL_SUPPORTED_CTRL_FILTER 0xFF
40
41extern const struct ieee80211_ops rtl_ops;
42#endif
diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/rtlwifi/debug.c
new file mode 100644
index 00000000000..5fa73852cb6
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/debug.c
@@ -0,0 +1,50 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * Tmis 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 * Tmis 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 * You should have received a copy of the GNU General Public License along with
15 * tmis program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * Tme full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *****************************************************************************/
28
29#include "wifi.h"
30
31void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
32{
33 struct rtl_priv *rtlpriv = rtl_priv(hw);
34 u8 i;
35
36 rtlpriv->dbg.global_debuglevel = DBG_EMERG;
37
38 rtlpriv->dbg.global_debugcomponents =
39 COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND |
40 COMP_MLME | COMP_SCAN | COMP_INTR | COMP_LED | COMP_SEC |
41 COMP_BEACON | COMP_RATE | COMP_RXDESC | COMP_DIG | COMP_TXAGC |
42 COMP_POWER | COMP_POWER_TRACKING | COMP_BB_POWERSAVING | COMP_SWAS |
43 COMP_RF | COMP_TURBO | COMP_RATR | COMP_CMD |
44 COMP_EFUSE | COMP_QOS | COMP_MAC80211 | COMP_REGD | COMP_CHAN;
45
46 for (i = 0; i < DBGP_TYPE_MAX; i++)
47 rtlpriv->dbg.dbgp_type[i] = 0;
48
49 /*Init Debug flag enable condition */
50}
diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h
new file mode 100644
index 00000000000..08bdec2ceda
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/debug.h
@@ -0,0 +1,212 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * Tmis 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 * Tmis 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 * You should have received a copy of the GNU General Public License along with
15 * tmis program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * Tme full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *****************************************************************************/
28
29#ifndef __RTL_DEBUG_H__
30#define __RTL_DEBUG_H__
31
32/*--------------------------------------------------------------
33 Debug level
34--------------------------------------------------------------*/
35/*
36 *Fatal bug.
37 *For example, Tx/Rx/IO locked up,
38 *memory access violation,
39 *resource allocation failed,
40 *unexpected HW behavior, HW BUG
41 *and so on.
42 */
43#define DBG_EMERG 0
44
45/*
46 *Abnormal, rare, or unexpeted cases.
47 *For example, Packet/IO Ctl canceled,
48 *device suprisely unremoved and so on.
49 */
50#define DBG_WARNING 2
51
52/*
53 *Normal case driver developer should
54 *open, we can see link status like
55 *assoc/AddBA/DHCP/adapter start and
56 *so on basic and useful infromations.
57 */
58#define DBG_DMESG 3
59
60/*
61 *Normal case with useful information
62 *about current SW or HW state.
63 *For example, Tx/Rx descriptor to fill,
64 *Tx/Rx descriptor completed status,
65 *SW protocol state change, dynamic
66 *mechanism state change and so on.
67 */
68#define DBG_LOUD 4
69
70/*
71 *Normal case with detail execution
72 *flow or information.
73 */
74#define DBG_TRACE 5
75
76/*--------------------------------------------------------------
77 Define the rt_trace components
78--------------------------------------------------------------*/
79#define COMP_ERR BIT(0)
80#define COMP_FW BIT(1)
81#define COMP_INIT BIT(2) /*For init/deinit */
82#define COMP_RECV BIT(3) /*For Rx. */
83#define COMP_SEND BIT(4) /*For Tx. */
84#define COMP_MLME BIT(5) /*For MLME. */
85#define COMP_SCAN BIT(6) /*For Scan. */
86#define COMP_INTR BIT(7) /*For interrupt Related. */
87#define COMP_LED BIT(8) /*For LED. */
88#define COMP_SEC BIT(9) /*For sec. */
89#define COMP_BEACON BIT(10) /*For beacon. */
90#define COMP_RATE BIT(11) /*For rate. */
91#define COMP_RXDESC BIT(12) /*For rx desc. */
92#define COMP_DIG BIT(13) /*For DIG */
93#define COMP_TXAGC BIT(14) /*For Tx power */
94#define COMP_HIPWR BIT(15) /*For High Power Mechanism */
95#define COMP_POWER BIT(16) /*For lps/ips/aspm. */
96#define COMP_POWER_TRACKING BIT(17) /*For TX POWER TRACKING */
97#define COMP_BB_POWERSAVING BIT(18)
98#define COMP_SWAS BIT(19) /*For SW Antenna Switch */
99#define COMP_RF BIT(20) /*For RF. */
100#define COMP_TURBO BIT(21) /*For EDCA TURBO. */
101#define COMP_RATR BIT(22)
102#define COMP_CMD BIT(23)
103#define COMP_EFUSE BIT(24)
104#define COMP_QOS BIT(25)
105#define COMP_MAC80211 BIT(26)
106#define COMP_REGD BIT(27)
107#define COMP_CHAN BIT(28)
108
109/*--------------------------------------------------------------
110 Define the rt_print components
111--------------------------------------------------------------*/
112/* Define EEPROM and EFUSE check module bit*/
113#define EEPROM_W BIT(0)
114#define EFUSE_PG BIT(1)
115#define EFUSE_READ_ALL BIT(2)
116
117/* Define init check for module bit*/
118#define INIT_EEPROM BIT(0)
119#define INIT_TxPower BIT(1)
120#define INIT_IQK BIT(2)
121#define INIT_RF BIT(3)
122
123/* Define PHY-BB/RF/MAC check module bit */
124#define PHY_BBR BIT(0)
125#define PHY_BBW BIT(1)
126#define PHY_RFR BIT(2)
127#define PHY_RFW BIT(3)
128#define PHY_MACR BIT(4)
129#define PHY_MACW BIT(5)
130#define PHY_ALLR BIT(6)
131#define PHY_ALLW BIT(7)
132#define PHY_TXPWR BIT(8)
133#define PHY_PWRDIFF BIT(9)
134
135enum dbgp_flag_e {
136 FQOS = 0,
137 FTX = 1,
138 FRX = 2,
139 FSEC = 3,
140 FMGNT = 4,
141 FMLME = 5,
142 FRESOURCE = 6,
143 FBEACON = 7,
144 FISR = 8,
145 FPHY = 9,
146 FMP = 10,
147 FEEPROM = 11,
148 FPWR = 12,
149 FDM = 13,
150 FDBGCtrl = 14,
151 FC2H = 15,
152 FBT = 16,
153 FINIT = 17,
154 FIOCTL = 18,
155 DBGP_TYPE_MAX
156};
157
158#define RT_ASSERT(_exp, fmt) \
159 do { \
160 if (!(_exp)) { \
161 printk(KERN_DEBUG "%s:%s(): ", KBUILD_MODNAME, \
162 __func__); \
163 printk fmt; \
164 } \
165 } while (0);
166
167#define RT_TRACE(rtlpriv, comp, level, fmt)\
168 do { \
169 if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \
170 ((level) <= rtlpriv->dbg.global_debuglevel))) {\
171 printk(KERN_DEBUG "%s:%s():<%lx-%x> ", KBUILD_MODNAME, \
172 __func__, in_interrupt(), in_atomic()); \
173 printk fmt; \
174 } \
175 } while (0);
176
177#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr) \
178 do { \
179 if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \
180 printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \
181 printk printstr; \
182 } \
183 } while (0);
184
185#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \
186 _hexdatalen) \
187 do {\
188 if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) &&\
189 (_level <= rtlpriv->dbg.global_debuglevel))) { \
190 int __i; \
191 u8* ptr = (u8 *)_hexdata; \
192 printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \
193 printk("In process \"%s\" (pid %i):", current->comm,\
194 current->pid); \
195 printk(_titlestring); \
196 for (__i = 0; __i < (int)_hexdatalen; __i++) { \
197 printk("%02X%s", ptr[__i], (((__i + 1) % 4)\
198 == 0) ? " " : " ");\
199 if (((__i + 1) % 16) == 0) \
200 printk("\n"); \
201 } \
202 printk(KERN_DEBUG "\n"); \
203 } \
204 } while (0);
205
206#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
207#define MAC_ARG(x) \
208 ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2],\
209 ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
210
211void rtl_dbgp_flag_init(struct ieee80211_hw *hw);
212#endif
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c
new file mode 100644
index 00000000000..b8433f3a9bc
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/efuse.c
@@ -0,0 +1,1189 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * Tmis 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 * Tmis 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 * You should have received a copy of the GNU General Public License along with
15 * tmis program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * Tme full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "wifi.h"
31#include "efuse.h"
32
33static const u8 MAX_PGPKT_SIZE = 9;
34static const u8 PGPKT_DATA_SIZE = 8;
35static const int EFUSE_MAX_SIZE = 512;
36
37static const u8 EFUSE_OOB_PROTECT_BYTES = 15;
38
39static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = {
40 {0, 0, 0, 2},
41 {0, 1, 0, 2},
42 {0, 2, 0, 2},
43 {1, 0, 0, 1},
44 {1, 0, 1, 1},
45 {1, 1, 0, 1},
46 {1, 1, 1, 3},
47 {1, 3, 0, 17},
48 {3, 3, 1, 48},
49 {10, 0, 0, 6},
50 {10, 3, 0, 1},
51 {10, 3, 1, 1},
52 {11, 0, 0, 28}
53};
54
55static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset,
56 u8 *pbuf);
57static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset,
58 u8 *value);
59static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset,
60 u16 *value);
61static void efuse_shadow_read_4byte(struct ieee80211_hw *hw, u16 offset,
62 u32 *value);
63static void efuse_shadow_write_1byte(struct ieee80211_hw *hw, u16 offset,
64 u8 value);
65static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, u16 offset,
66 u16 value);
67static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset,
68 u32 value);
69static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr,
70 u8 *data);
71static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr,
72 u8 data);
73static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse);
74static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset,
75 u8 *data);
76static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset,
77 u8 word_en, u8 *data);
78static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata,
79 u8 *targetdata);
80static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
81 u16 efuse_addr, u8 word_en, u8 *data);
82static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite,
83 u8 pwrstate);
84static u16 efuse_get_current_size(struct ieee80211_hw *hw);
85static u8 efuse_calculate_word_cnts(u8 word_en);
86
87void efuse_initialize(struct ieee80211_hw *hw)
88{
89 struct rtl_priv *rtlpriv = rtl_priv(hw);
90 u8 bytetemp;
91 u8 temp;
92
93 bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1);
94 temp = bytetemp | 0x20;
95 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1, temp);
96
97 bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1);
98 temp = bytetemp & 0xFE;
99 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1, temp);
100
101 bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3);
102 temp = bytetemp | 0x80;
103 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3, temp);
104
105 rtl_write_byte(rtlpriv, 0x2F8, 0x3);
106
107 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
108
109}
110
111u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address)
112{
113 struct rtl_priv *rtlpriv = rtl_priv(hw);
114 u8 data;
115 u8 bytetemp;
116 u8 temp;
117 u32 k = 0;
118
119 if (address < EFUSE_REAL_CONTENT_LEN) {
120 temp = address & 0xFF;
121 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
122 temp);
123 bytetemp = rtl_read_byte(rtlpriv,
124 rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
125 temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
126 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
127 temp);
128
129 bytetemp = rtl_read_byte(rtlpriv,
130 rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
131 temp = bytetemp & 0x7F;
132 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
133 temp);
134
135 bytetemp = rtl_read_byte(rtlpriv,
136 rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
137 while (!(bytetemp & 0x80)) {
138 bytetemp = rtl_read_byte(rtlpriv,
139 rtlpriv->cfg->
140 maps[EFUSE_CTRL] + 3);
141 k++;
142 if (k == 1000) {
143 k = 0;
144 break;
145 }
146 }
147 data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
148 return data;
149 } else
150 return 0xFF;
151
152}
153EXPORT_SYMBOL(efuse_read_1byte);
154
155void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
156{
157 struct rtl_priv *rtlpriv = rtl_priv(hw);
158 u8 bytetemp;
159 u8 temp;
160 u32 k = 0;
161
162 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
163 ("Addr=%x Data =%x\n", address, value));
164
165 if (address < EFUSE_REAL_CONTENT_LEN) {
166 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);
167
168 temp = address & 0xFF;
169 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
170 temp);
171 bytetemp = rtl_read_byte(rtlpriv,
172 rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
173
174 temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
175 rtl_write_byte(rtlpriv,
176 rtlpriv->cfg->maps[EFUSE_CTRL] + 2, temp);
177
178 bytetemp = rtl_read_byte(rtlpriv,
179 rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
180 temp = bytetemp | 0x80;
181 rtl_write_byte(rtlpriv,
182 rtlpriv->cfg->maps[EFUSE_CTRL] + 3, temp);
183
184 bytetemp = rtl_read_byte(rtlpriv,
185 rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
186
187 while (bytetemp & 0x80) {
188 bytetemp = rtl_read_byte(rtlpriv,
189 rtlpriv->cfg->
190 maps[EFUSE_CTRL] + 3);
191 k++;
192 if (k == 100) {
193 k = 0;
194 break;
195 }
196 }
197 }
198
199}
200
201static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
202{
203 struct rtl_priv *rtlpriv = rtl_priv(hw);
204 u32 value32;
205 u8 readbyte;
206 u16 retry;
207
208 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
209 (_offset & 0xff));
210 readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
211 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
212 ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
213
214 readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
215 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
216 (readbyte & 0x7f));
217
218 retry = 0;
219 value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
220 while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
221 value32 = rtl_read_dword(rtlpriv,
222 rtlpriv->cfg->maps[EFUSE_CTRL]);
223 retry++;
224 }
225
226 udelay(50);
227 value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
228
229 *pbuf = (u8) (value32 & 0xff);
230}
231
232void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
233{
234 struct rtl_priv *rtlpriv = rtl_priv(hw);
235 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
236 u8 efuse_tbl[EFUSE_MAP_LEN];
237 u8 rtemp8[1];
238 u16 efuse_addr = 0;
239 u8 offset, wren;
240 u16 i;
241 u16 j;
242 u16 efuse_word[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT];
243 u16 efuse_utilized = 0;
244 u8 efuse_usage;
245
246 if ((_offset + _size_byte) > EFUSE_MAP_LEN) {
247 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
248 ("read_efuse(): Invalid offset(%#x) with read "
249 "bytes(%#x)!!\n", _offset, _size_byte));
250 return;
251 }
252
253 for (i = 0; i < EFUSE_MAX_SECTION; i++)
254 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
255 efuse_word[i][j] = 0xFFFF;
256
257 read_efuse_byte(hw, efuse_addr, rtemp8);
258 if (*rtemp8 != 0xFF) {
259 efuse_utilized++;
260 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
261 ("Addr=%d\n", efuse_addr));
262 efuse_addr++;
263 }
264
265 while ((*rtemp8 != 0xFF) && (efuse_addr < EFUSE_REAL_CONTENT_LEN)) {
266 offset = ((*rtemp8 >> 4) & 0x0f);
267
268 if (offset < EFUSE_MAX_SECTION) {
269 wren = (*rtemp8 & 0x0f);
270 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
271 ("offset-%d Worden=%x\n", offset, wren));
272
273 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
274 if (!(wren & 0x01)) {
275 RTPRINT(rtlpriv, FEEPROM,
276 EFUSE_READ_ALL, ("Addr=%d\n",
277 efuse_addr));
278
279 read_efuse_byte(hw, efuse_addr, rtemp8);
280 efuse_addr++;
281 efuse_utilized++;
282 efuse_word[offset][i] = (*rtemp8 & 0xff);
283
284 if (efuse_addr >= EFUSE_REAL_CONTENT_LEN)
285 break;
286
287 RTPRINT(rtlpriv, FEEPROM,
288 EFUSE_READ_ALL, ("Addr=%d\n",
289 efuse_addr));
290
291 read_efuse_byte(hw, efuse_addr, rtemp8);
292 efuse_addr++;
293 efuse_utilized++;
294 efuse_word[offset][i] |=
295 (((u16)*rtemp8 << 8) & 0xff00);
296
297 if (efuse_addr >= EFUSE_REAL_CONTENT_LEN)
298 break;
299 }
300
301 wren >>= 1;
302 }
303 }
304
305 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
306 ("Addr=%d\n", efuse_addr));
307 read_efuse_byte(hw, efuse_addr, rtemp8);
308 if (*rtemp8 != 0xFF && (efuse_addr < 512)) {
309 efuse_utilized++;
310 efuse_addr++;
311 }
312 }
313
314 for (i = 0; i < EFUSE_MAX_SECTION; i++) {
315 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
316 efuse_tbl[(i * 8) + (j * 2)] =
317 (efuse_word[i][j] & 0xff);
318 efuse_tbl[(i * 8) + ((j * 2) + 1)] =
319 ((efuse_word[i][j] >> 8) & 0xff);
320 }
321 }
322
323 for (i = 0; i < _size_byte; i++)
324 pbuf[i] = efuse_tbl[_offset + i];
325
326 rtlefuse->efuse_usedbytes = efuse_utilized;
327 efuse_usage = (u8)((efuse_utilized * 100) / EFUSE_REAL_CONTENT_LEN);
328 rtlefuse->efuse_usedpercentage = efuse_usage;
329 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES,
330 (u8 *)&efuse_utilized);
331 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE,
332 (u8 *)&efuse_usage);
333}
334
335bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
336{
337 struct rtl_priv *rtlpriv = rtl_priv(hw);
338 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
339 u8 section_idx, i, Base;
340 u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used;
341 bool bwordchanged, bresult = true;
342
343 for (section_idx = 0; section_idx < 16; section_idx++) {
344 Base = section_idx * 8;
345 bwordchanged = false;
346
347 for (i = 0; i < 8; i = i + 2) {
348 if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i] !=
349 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i]) ||
350 (rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i + 1] !=
351 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i +
352 1])) {
353 words_need++;
354 bwordchanged = true;
355 }
356 }
357
358 if (bwordchanged == true)
359 hdr_num++;
360 }
361
362 totalbytes = hdr_num + words_need * 2;
363 efuse_used = rtlefuse->efuse_usedbytes;
364
365 if ((totalbytes + efuse_used) >=
366 (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))
367 bresult = false;
368
369 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
370 ("efuse_shadow_update_chk(): totalbytes(%#x), "
371 "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
372 totalbytes, hdr_num, words_need, efuse_used));
373
374 return bresult;
375}
376
377void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
378 u16 offset, u32 *value)
379{
380 if (type == 1)
381 efuse_shadow_read_1byte(hw, offset, (u8 *) value);
382 else if (type == 2)
383 efuse_shadow_read_2byte(hw, offset, (u16 *) value);
384 else if (type == 4)
385 efuse_shadow_read_4byte(hw, offset, (u32 *) value);
386
387}
388
389void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset,
390 u32 value)
391{
392 if (type == 1)
393 efuse_shadow_write_1byte(hw, offset, (u8) value);
394 else if (type == 2)
395 efuse_shadow_write_2byte(hw, offset, (u16) value);
396 else if (type == 4)
397 efuse_shadow_write_4byte(hw, offset, (u32) value);
398
399}
400
401bool efuse_shadow_update(struct ieee80211_hw *hw)
402{
403 struct rtl_priv *rtlpriv = rtl_priv(hw);
404 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
405 u16 i, offset, base;
406 u8 word_en = 0x0F;
407 u8 first_pg = false;
408
409 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("--->\n"));
410
411 if (!efuse_shadow_update_chk(hw)) {
412 efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
413 memcpy((void *)&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
414 (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
415 rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
416
417 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
418 ("<---efuse out of capacity!!\n"));
419 return false;
420 }
421 efuse_power_switch(hw, true, true);
422
423 for (offset = 0; offset < 16; offset++) {
424
425 word_en = 0x0F;
426 base = offset * 8;
427
428 for (i = 0; i < 8; i++) {
429 if (first_pg == true) {
430
431 word_en &= ~(BIT(i / 2));
432
433 rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
434 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
435 } else {
436
437 if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] !=
438 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]) {
439 word_en &= ~(BIT(i / 2));
440
441 rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
442 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
443 }
444 }
445 }
446
447 if (word_en != 0x0F) {
448 u8 tmpdata[8];
449 memcpy((void *)tmpdata,
450 (void *)(&rtlefuse->
451 efuse_map[EFUSE_MODIFY_MAP][base]), 8);
452 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD,
453 ("U-efuse\n"), tmpdata, 8);
454
455 if (!efuse_pg_packet_write(hw, (u8) offset, word_en,
456 tmpdata)) {
457 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
458 ("PG section(%#x) fail!!\n", offset));
459 break;
460 }
461 }
462
463 }
464
465 efuse_power_switch(hw, true, false);
466 efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
467
468 memcpy((void *)&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
469 (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
470 rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
471
472 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("<---\n"));
473 return true;
474}
475
476void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw)
477{
478 struct rtl_priv *rtlpriv = rtl_priv(hw);
479 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
480
481 if (rtlefuse->autoload_failflag == true) {
482 memset((void *)(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0]), 128,
483 0xFF);
484 } else
485 efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
486
487 memcpy((void *)&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
488 (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
489 rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
490
491}
492EXPORT_SYMBOL(rtl_efuse_shadow_map_update);
493
494void efuse_force_write_vendor_Id(struct ieee80211_hw *hw)
495{
496 u8 tmpdata[8] = { 0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF };
497
498 efuse_power_switch(hw, true, true);
499
500 efuse_pg_packet_write(hw, 1, 0xD, tmpdata);
501
502 efuse_power_switch(hw, true, false);
503
504}
505
506void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx)
507{
508}
509
510static void efuse_shadow_read_1byte(struct ieee80211_hw *hw,
511 u16 offset, u8 *value)
512{
513 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
514 *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
515}
516
517static void efuse_shadow_read_2byte(struct ieee80211_hw *hw,
518 u16 offset, u16 *value)
519{
520 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
521
522 *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
523 *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
524
525}
526
527static void efuse_shadow_read_4byte(struct ieee80211_hw *hw,
528 u16 offset, u32 *value)
529{
530 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
531
532 *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
533 *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
534 *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] << 16;
535 *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] << 24;
536}
537
538static void efuse_shadow_write_1byte(struct ieee80211_hw *hw,
539 u16 offset, u8 value)
540{
541 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
542
543 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value;
544}
545
546static void efuse_shadow_write_2byte(struct ieee80211_hw *hw,
547 u16 offset, u16 value)
548{
549 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
550
551 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value & 0x00FF;
552 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = value >> 8;
553
554}
555
556static void efuse_shadow_write_4byte(struct ieee80211_hw *hw,
557 u16 offset, u32 value)
558{
559 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
560
561 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] =
562 (u8) (value & 0x000000FF);
563 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] =
564 (u8) ((value >> 8) & 0x0000FF);
565 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] =
566 (u8) ((value >> 16) & 0x00FF);
567 rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] =
568 (u8) ((value >> 24) & 0xFF);
569
570}
571
572static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data)
573{
574 struct rtl_priv *rtlpriv = rtl_priv(hw);
575 u8 tmpidx = 0;
576 int bresult;
577
578 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
579 (u8) (addr & 0xff));
580 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
581 ((u8) ((addr >> 8) & 0x03)) |
582 (rtl_read_byte(rtlpriv,
583 rtlpriv->cfg->maps[EFUSE_CTRL] + 2) &
584 0xFC));
585
586 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
587
588 while (!(0x80 & rtl_read_byte(rtlpriv,
589 rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
590 && (tmpidx < 100)) {
591 tmpidx++;
592 }
593
594 if (tmpidx < 100) {
595 *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
596 bresult = true;
597 } else {
598 *data = 0xff;
599 bresult = false;
600 }
601 return bresult;
602}
603
604static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
605{
606 struct rtl_priv *rtlpriv = rtl_priv(hw);
607 u8 tmpidx = 0;
608 bool bresult;
609
610 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
611 ("Addr = %x Data=%x\n", addr, data));
612
613 rtl_write_byte(rtlpriv,
614 rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff));
615 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
616 (rtl_read_byte(rtlpriv,
617 rtlpriv->cfg->maps[EFUSE_CTRL] +
618 2) & 0xFC) | (u8) ((addr >> 8) & 0x03));
619
620 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], data);
621 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0xF2);
622
623 while ((0x80 & rtl_read_byte(rtlpriv,
624 rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
625 && (tmpidx < 100)) {
626 tmpidx++;
627 }
628
629 if (tmpidx < 100)
630 bresult = true;
631 else
632 bresult = false;
633
634 return bresult;
635}
636
637static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse)
638{
639 efuse_power_switch(hw, false, true);
640 read_efuse(hw, 0, 128, efuse);
641 efuse_power_switch(hw, false, false);
642}
643
644static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
645 u8 efuse_data, u8 offset, u8 *tmpdata,
646 u8 *readstate)
647{
648 bool bdataempty = true;
649 u8 hoffset;
650 u8 tmpidx;
651 u8 hworden;
652 u8 word_cnts;
653
654 hoffset = (efuse_data >> 4) & 0x0F;
655 hworden = efuse_data & 0x0F;
656 word_cnts = efuse_calculate_word_cnts(hworden);
657
658 if (hoffset == offset) {
659 for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) {
660 if (efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx,
661 &efuse_data)) {
662 tmpdata[tmpidx] = efuse_data;
663 if (efuse_data != 0xff)
664 bdataempty = true;
665 }
666 }
667
668 if (bdataempty == true)
669 *readstate = PG_STATE_DATA;
670 else {
671 *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
672 *readstate = PG_STATE_HEADER;
673 }
674
675 } else {
676 *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
677 *readstate = PG_STATE_HEADER;
678 }
679}
680
681static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
682{
683 u8 readstate = PG_STATE_HEADER;
684
685 bool bcontinual = true;
686
687 u8 efuse_data, word_cnts = 0;
688 u16 efuse_addr = 0;
689 u8 hworden;
690 u8 tmpdata[8];
691
692 if (data == NULL)
693 return false;
694 if (offset > 15)
695 return false;
696
697 memset((void *)data, PGPKT_DATA_SIZE * sizeof(u8), 0xff);
698 memset((void *)tmpdata, PGPKT_DATA_SIZE * sizeof(u8), 0xff);
699
700 while (bcontinual && (efuse_addr < EFUSE_MAX_SIZE)) {
701 if (readstate & PG_STATE_HEADER) {
702 if (efuse_one_byte_read(hw, efuse_addr, &efuse_data)
703 && (efuse_data != 0xFF))
704 efuse_read_data_case1(hw, &efuse_addr,
705 efuse_data,
706 offset, tmpdata,
707 &readstate);
708 else
709 bcontinual = false;
710 } else if (readstate & PG_STATE_DATA) {
711 efuse_word_enable_data_read(hworden, tmpdata, data);
712 efuse_addr = efuse_addr + (word_cnts * 2) + 1;
713 readstate = PG_STATE_HEADER;
714 }
715
716 }
717
718 if ((data[0] == 0xff) && (data[1] == 0xff) &&
719 (data[2] == 0xff) && (data[3] == 0xff) &&
720 (data[4] == 0xff) && (data[5] == 0xff) &&
721 (data[6] == 0xff) && (data[7] == 0xff))
722 return false;
723 else
724 return true;
725
726}
727
728static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
729 u8 efuse_data, u8 offset, int *bcontinual,
730 u8 *write_state, struct pgpkt_struct target_pkt,
731 int *repeat_times, int *bresult, u8 word_en)
732{
733 struct rtl_priv *rtlpriv = rtl_priv(hw);
734 struct pgpkt_struct tmp_pkt;
735 int bdataempty = true;
736 u8 originaldata[8 * sizeof(u8)];
737 u8 badworden = 0x0F;
738 u8 match_word_en, tmp_word_en;
739 u8 tmpindex;
740 u8 tmp_header = efuse_data;
741 u8 tmp_word_cnts;
742
743 tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
744 tmp_pkt.word_en = tmp_header & 0x0F;
745 tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
746
747 if (tmp_pkt.offset != target_pkt.offset) {
748 efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1;
749 *write_state = PG_STATE_HEADER;
750 } else {
751 for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) {
752 u16 address = *efuse_addr + 1 + tmpindex;
753 if (efuse_one_byte_read(hw, address,
754 &efuse_data) && (efuse_data != 0xFF))
755 bdataempty = false;
756 }
757
758 if (bdataempty == false) {
759 efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1;
760 *write_state = PG_STATE_HEADER;
761 } else {
762 match_word_en = 0x0F;
763 if (!((target_pkt.word_en & BIT(0)) |
764 (tmp_pkt.word_en & BIT(0))))
765 match_word_en &= (~BIT(0));
766
767 if (!((target_pkt.word_en & BIT(1)) |
768 (tmp_pkt.word_en & BIT(1))))
769 match_word_en &= (~BIT(1));
770
771 if (!((target_pkt.word_en & BIT(2)) |
772 (tmp_pkt.word_en & BIT(2))))
773 match_word_en &= (~BIT(2));
774
775 if (!((target_pkt.word_en & BIT(3)) |
776 (tmp_pkt.word_en & BIT(3))))
777 match_word_en &= (~BIT(3));
778
779 if ((match_word_en & 0x0F) != 0x0F) {
780 badworden = efuse_word_enable_data_write(
781 hw, *efuse_addr + 1,
782 tmp_pkt.word_en,
783 target_pkt.data);
784
785 if (0x0F != (badworden & 0x0F)) {
786 u8 reorg_offset = offset;
787 u8 reorg_worden = badworden;
788 efuse_pg_packet_write(hw, reorg_offset,
789 reorg_worden,
790 originaldata);
791 }
792
793 tmp_word_en = 0x0F;
794 if ((target_pkt.word_en & BIT(0)) ^
795 (match_word_en & BIT(0)))
796 tmp_word_en &= (~BIT(0));
797
798 if ((target_pkt.word_en & BIT(1)) ^
799 (match_word_en & BIT(1)))
800 tmp_word_en &= (~BIT(1));
801
802 if ((target_pkt.word_en & BIT(2)) ^
803 (match_word_en & BIT(2)))
804 tmp_word_en &= (~BIT(2));
805
806 if ((target_pkt.word_en & BIT(3)) ^
807 (match_word_en & BIT(3)))
808 tmp_word_en &= (~BIT(3));
809
810 if ((tmp_word_en & 0x0F) != 0x0F) {
811 *efuse_addr = efuse_get_current_size(hw);
812 target_pkt.offset = offset;
813 target_pkt.word_en = tmp_word_en;
814 } else
815 *bcontinual = false;
816 *write_state = PG_STATE_HEADER;
817 *repeat_times += 1;
818 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
819 *bcontinual = false;
820 *bresult = false;
821 }
822 } else {
823 *efuse_addr += (2 * tmp_word_cnts) + 1;
824 target_pkt.offset = offset;
825 target_pkt.word_en = word_en;
826 *write_state = PG_STATE_HEADER;
827 }
828 }
829 }
830 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER-1\n"));
831}
832
833static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
834 int *bcontinual, u8 *write_state,
835 struct pgpkt_struct target_pkt,
836 int *repeat_times, int *bresult)
837{
838 struct rtl_priv *rtlpriv = rtl_priv(hw);
839 struct pgpkt_struct tmp_pkt;
840 u8 pg_header;
841 u8 tmp_header;
842 u8 originaldata[8 * sizeof(u8)];
843 u8 tmp_word_cnts;
844 u8 badworden = 0x0F;
845
846 pg_header = ((target_pkt.offset << 4) & 0xf0) | target_pkt.word_en;
847 efuse_one_byte_write(hw, *efuse_addr, pg_header);
848 efuse_one_byte_read(hw, *efuse_addr, &tmp_header);
849
850 if (tmp_header == pg_header)
851 *write_state = PG_STATE_DATA;
852 else if (tmp_header == 0xFF) {
853 *write_state = PG_STATE_HEADER;
854 *repeat_times += 1;
855 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
856 *bcontinual = false;
857 *bresult = false;
858 }
859 } else {
860 tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
861 tmp_pkt.word_en = tmp_header & 0x0F;
862
863 tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
864
865 memset((void *)originaldata, 8 * sizeof(u8), 0xff);
866
867 if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) {
868 badworden = efuse_word_enable_data_write(hw,
869 *efuse_addr + 1, tmp_pkt.word_en,
870 originaldata);
871
872 if (0x0F != (badworden & 0x0F)) {
873 u8 reorg_offset = tmp_pkt.offset;
874 u8 reorg_worden = badworden;
875 efuse_pg_packet_write(hw, reorg_offset,
876 reorg_worden,
877 originaldata);
878 *efuse_addr = efuse_get_current_size(hw);
879 } else
880 *efuse_addr = *efuse_addr + (tmp_word_cnts * 2)
881 + 1;
882 } else
883 *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
884
885 *write_state = PG_STATE_HEADER;
886 *repeat_times += 1;
887 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
888 *bcontinual = false;
889 *bresult = false;
890 }
891
892 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
893 ("efuse PG_STATE_HEADER-2\n"));
894 }
895}
896
897static int efuse_pg_packet_write(struct ieee80211_hw *hw,
898 u8 offset, u8 word_en, u8 *data)
899{
900 struct rtl_priv *rtlpriv = rtl_priv(hw);
901 struct pgpkt_struct target_pkt;
902 u8 write_state = PG_STATE_HEADER;
903 int bcontinual = true, bdataempty = true, bresult = true;
904 u16 efuse_addr = 0;
905 u8 efuse_data;
906 u8 target_word_cnts = 0;
907 u8 badworden = 0x0F;
908 static int repeat_times;
909
910 if (efuse_get_current_size(hw) >=
911 (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) {
912 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
913 ("efuse_pg_packet_write error\n"));
914 return false;
915 }
916
917 target_pkt.offset = offset;
918 target_pkt.word_en = word_en;
919
920 memset((void *)target_pkt.data, 8 * sizeof(u8), 0xFF);
921
922 efuse_word_enable_data_read(word_en, data, target_pkt.data);
923 target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en);
924
925 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n"));
926
927 while (bcontinual && (efuse_addr <
928 (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) {
929
930 if (write_state == PG_STATE_HEADER) {
931 bdataempty = true;
932 badworden = 0x0F;
933 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
934 ("efuse PG_STATE_HEADER\n"));
935
936 if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
937 (efuse_data != 0xFF))
938 efuse_write_data_case1(hw, &efuse_addr,
939 efuse_data, offset,
940 &bcontinual,
941 &write_state, target_pkt,
942 &repeat_times, &bresult,
943 word_en);
944 else
945 efuse_write_data_case2(hw, &efuse_addr,
946 &bcontinual,
947 &write_state,
948 target_pkt,
949 &repeat_times,
950 &bresult);
951
952 } else if (write_state == PG_STATE_DATA) {
953 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
954 ("efuse PG_STATE_DATA\n"));
955 badworden = 0x0f;
956 badworden =
957 efuse_word_enable_data_write(hw, efuse_addr + 1,
958 target_pkt.word_en,
959 target_pkt.data);
960
961 if ((badworden & 0x0F) == 0x0F) {
962 bcontinual = false;
963 } else {
964 efuse_addr =
965 efuse_addr + (2 * target_word_cnts) + 1;
966
967 target_pkt.offset = offset;
968 target_pkt.word_en = badworden;
969 target_word_cnts =
970 efuse_calculate_word_cnts(target_pkt.
971 word_en);
972 write_state = PG_STATE_HEADER;
973 repeat_times++;
974 if (repeat_times > EFUSE_REPEAT_THRESHOLD_) {
975 bcontinual = false;
976 bresult = false;
977 }
978 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
979 ("efuse PG_STATE_HEADER-3\n"));
980 }
981 }
982 }
983
984 if (efuse_addr >= (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) {
985 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
986 ("efuse_addr(%#x) Out of size!!\n", efuse_addr));
987 }
988
989 return true;
990}
991
992static void efuse_word_enable_data_read(u8 word_en,
993 u8 *sourdata, u8 *targetdata)
994{
995 if (!(word_en & BIT(0))) {
996 targetdata[0] = sourdata[0];
997 targetdata[1] = sourdata[1];
998 }
999
1000 if (!(word_en & BIT(1))) {
1001 targetdata[2] = sourdata[2];
1002 targetdata[3] = sourdata[3];
1003 }
1004
1005 if (!(word_en & BIT(2))) {
1006 targetdata[4] = sourdata[4];
1007 targetdata[5] = sourdata[5];
1008 }
1009
1010 if (!(word_en & BIT(3))) {
1011 targetdata[6] = sourdata[6];
1012 targetdata[7] = sourdata[7];
1013 }
1014}
1015
1016static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
1017 u16 efuse_addr, u8 word_en, u8 *data)
1018{
1019 struct rtl_priv *rtlpriv = rtl_priv(hw);
1020 u16 tmpaddr;
1021 u16 start_addr = efuse_addr;
1022 u8 badworden = 0x0F;
1023 u8 tmpdata[8];
1024
1025 memset((void *)tmpdata, PGPKT_DATA_SIZE, 0xff);
1026 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
1027 ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr));
1028
1029 if (!(word_en & BIT(0))) {
1030 tmpaddr = start_addr;
1031 efuse_one_byte_write(hw, start_addr++, data[0]);
1032 efuse_one_byte_write(hw, start_addr++, data[1]);
1033
1034 efuse_one_byte_read(hw, tmpaddr, &tmpdata[0]);
1035 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[1]);
1036 if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
1037 badworden &= (~BIT(0));
1038 }
1039
1040 if (!(word_en & BIT(1))) {
1041 tmpaddr = start_addr;
1042 efuse_one_byte_write(hw, start_addr++, data[2]);
1043 efuse_one_byte_write(hw, start_addr++, data[3]);
1044
1045 efuse_one_byte_read(hw, tmpaddr, &tmpdata[2]);
1046 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[3]);
1047 if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
1048 badworden &= (~BIT(1));
1049 }
1050
1051 if (!(word_en & BIT(2))) {
1052 tmpaddr = start_addr;
1053 efuse_one_byte_write(hw, start_addr++, data[4]);
1054 efuse_one_byte_write(hw, start_addr++, data[5]);
1055
1056 efuse_one_byte_read(hw, tmpaddr, &tmpdata[4]);
1057 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[5]);
1058 if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
1059 badworden &= (~BIT(2));
1060 }
1061
1062 if (!(word_en & BIT(3))) {
1063 tmpaddr = start_addr;
1064 efuse_one_byte_write(hw, start_addr++, data[6]);
1065 efuse_one_byte_write(hw, start_addr++, data[7]);
1066
1067 efuse_one_byte_read(hw, tmpaddr, &tmpdata[6]);
1068 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[7]);
1069 if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
1070 badworden &= (~BIT(3));
1071 }
1072
1073 return badworden;
1074}
1075
1076static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate)
1077{
1078 struct rtl_priv *rtlpriv = rtl_priv(hw);
1079 u8 tempval;
1080 u16 tmpV16;
1081
1082 if (pwrstate == true) {
1083 tmpV16 = rtl_read_word(rtlpriv,
1084 rtlpriv->cfg->maps[SYS_ISO_CTRL]);
1085 if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) {
1086 tmpV16 |= rtlpriv->cfg->maps[EFUSE_PWC_EV12V];
1087 rtl_write_word(rtlpriv,
1088 rtlpriv->cfg->maps[SYS_ISO_CTRL],
1089 tmpV16);
1090 }
1091
1092 tmpV16 = rtl_read_word(rtlpriv,
1093 rtlpriv->cfg->maps[SYS_FUNC_EN]);
1094 if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_FEN_ELDR])) {
1095 tmpV16 |= rtlpriv->cfg->maps[EFUSE_FEN_ELDR];
1096 rtl_write_word(rtlpriv,
1097 rtlpriv->cfg->maps[SYS_FUNC_EN], tmpV16);
1098 }
1099
1100 tmpV16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_CLK]);
1101 if ((!(tmpV16 & rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN])) ||
1102 (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_ANA8M]))) {
1103 tmpV16 |= (rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN] |
1104 rtlpriv->cfg->maps[EFUSE_ANA8M]);
1105 rtl_write_word(rtlpriv,
1106 rtlpriv->cfg->maps[SYS_CLK], tmpV16);
1107 }
1108 }
1109
1110 if (pwrstate == true) {
1111 if (bwrite == true) {
1112 tempval = rtl_read_byte(rtlpriv,
1113 rtlpriv->cfg->maps[EFUSE_TEST] +
1114 3);
1115 tempval &= 0x0F;
1116 tempval |= (VOLTAGE_V25 << 4);
1117 rtl_write_byte(rtlpriv,
1118 rtlpriv->cfg->maps[EFUSE_TEST] + 3,
1119 (tempval | 0x80));
1120 }
1121
1122 } else {
1123 if (bwrite == true) {
1124 tempval = rtl_read_byte(rtlpriv,
1125 rtlpriv->cfg->maps[EFUSE_TEST] +
1126 3);
1127 rtl_write_byte(rtlpriv,
1128 rtlpriv->cfg->maps[EFUSE_TEST] + 3,
1129 (tempval & 0x7F));
1130 }
1131
1132 }
1133
1134}
1135
1136static u16 efuse_get_current_size(struct ieee80211_hw *hw)
1137{
1138 int bcontinual = true;
1139 u16 efuse_addr = 0;
1140 u8 hoffset, hworden;
1141 u8 efuse_data, word_cnts;
1142
1143 while (bcontinual && efuse_one_byte_read(hw, efuse_addr, &efuse_data)
1144 && (efuse_addr < EFUSE_MAX_SIZE)) {
1145 if (efuse_data != 0xFF) {
1146 hoffset = (efuse_data >> 4) & 0x0F;
1147 hworden = efuse_data & 0x0F;
1148 word_cnts = efuse_calculate_word_cnts(hworden);
1149 efuse_addr = efuse_addr + (word_cnts * 2) + 1;
1150 } else {
1151 bcontinual = false;
1152 }
1153 }
1154
1155 return efuse_addr;
1156}
1157
1158static u8 efuse_calculate_word_cnts(u8 word_en)
1159{
1160 u8 word_cnts = 0;
1161 if (!(word_en & BIT(0)))
1162 word_cnts++;
1163 if (!(word_en & BIT(1)))
1164 word_cnts++;
1165 if (!(word_en & BIT(2)))
1166 word_cnts++;
1167 if (!(word_en & BIT(3)))
1168 word_cnts++;
1169 return word_cnts;
1170}
1171
1172void efuse_reset_loader(struct ieee80211_hw *hw)
1173{
1174 struct rtl_priv *rtlpriv = rtl_priv(hw);
1175 u16 tmp_u2b;
1176
1177 tmp_u2b = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN]);
1178 rtl_write_word(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN],
1179 (tmp_u2b & ~(BIT(12))));
1180 udelay(10000);
1181 rtl_write_word(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN],
1182 (tmp_u2b | BIT(12)));
1183 udelay(10000);
1184}
1185
1186bool efuse_program_map(struct ieee80211_hw *hw, char *p_filename, u8 tabletype)
1187{
1188 return true;
1189}
diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h
new file mode 100644
index 00000000000..2d39a4df181
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/efuse.h
@@ -0,0 +1,124 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL_EFUSE_H_
31#define __RTL_EFUSE_H_
32
33#define EFUSE_REAL_CONTENT_LEN 512
34#define EFUSE_MAP_LEN 128
35#define EFUSE_MAX_SECTION 16
36#define EFUSE_MAX_WORD_UNIT 4
37
38#define EFUSE_INIT_MAP 0
39#define EFUSE_MODIFY_MAP 1
40
41#define PG_STATE_HEADER 0x01
42#define PG_STATE_WORD_0 0x02
43#define PG_STATE_WORD_1 0x04
44#define PG_STATE_WORD_2 0x08
45#define PG_STATE_WORD_3 0x10
46#define PG_STATE_DATA 0x20
47
48#define PG_SWBYTE_H 0x01
49#define PG_SWBYTE_L 0x02
50
51#define _POWERON_DELAY_
52#define _PRE_EXECUTE_READ_CMD_
53
54#define EFUSE_REPEAT_THRESHOLD_ 3
55
56struct efuse_map {
57 u8 offset;
58 u8 word_start;
59 u8 byte_start;
60 u8 byte_cnts;
61};
62
63struct pgpkt_struct {
64 u8 offset;
65 u8 word_en;
66 u8 data[8];
67};
68
69enum efuse_data_item {
70 EFUSE_CHIP_ID = 0,
71 EFUSE_LDO_SETTING,
72 EFUSE_CLK_SETTING,
73 EFUSE_SDIO_SETTING,
74 EFUSE_CCCR,
75 EFUSE_SDIO_MODE,
76 EFUSE_OCR,
77 EFUSE_F0CIS,
78 EFUSE_F1CIS,
79 EFUSE_MAC_ADDR,
80 EFUSE_EEPROM_VER,
81 EFUSE_CHAN_PLAN,
82 EFUSE_TXPW_TAB
83};
84
85enum {
86 VOLTAGE_V25 = 0x03,
87 LDOE25_SHIFT = 28,
88};
89
90struct efuse_priv {
91 u8 id[2];
92 u8 ldo_setting[2];
93 u8 clk_setting[2];
94 u8 cccr;
95 u8 sdio_mode;
96 u8 ocr[3];
97 u8 cis0[17];
98 u8 cis1[48];
99 u8 mac_addr[6];
100 u8 eeprom_verno;
101 u8 channel_plan;
102 u8 tx_power_b[14];
103 u8 tx_power_g[14];
104};
105
106extern void efuse_initialize(struct ieee80211_hw *hw);
107extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address);
108extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value);
109extern void read_efuse(struct ieee80211_hw *hw, u16 _offset,
110 u16 _size_byte, u8 *pbuf);
111extern void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
112 u16 offset, u32 *value);
113extern void efuse_shadow_write(struct ieee80211_hw *hw, u8 type,
114 u16 offset, u32 value);
115extern bool efuse_shadow_update(struct ieee80211_hw *hw);
116extern bool efuse_shadow_update_chk(struct ieee80211_hw *hw);
117extern void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw);
118extern void efuse_force_write_vendor_Id(struct ieee80211_hw *hw);
119extern void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx);
120extern bool efuse_program_map(struct ieee80211_hw *hw,
121 char *p_filename, u8 tabletype);
122extern void efuse_reset_loader(struct ieee80211_hw *hw);
123
124#endif
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
new file mode 100644
index 00000000000..bf3b5748ee1
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -0,0 +1,1933 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "core.h"
31#include "wifi.h"
32#include "pci.h"
33#include "base.h"
34#include "ps.h"
35
36static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
37 INTEL_VENDOR_ID,
38 ATI_VENDOR_ID,
39 AMD_VENDOR_ID,
40 SIS_VENDOR_ID
41};
42
43/* Update PCI dependent default settings*/
44static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
45{
46 struct rtl_priv *rtlpriv = rtl_priv(hw);
47 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
48 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
49 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
50 u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
51
52 ppsc->reg_rfps_level = 0;
53 ppsc->b_support_aspm = 0;
54
55 /*Update PCI ASPM setting */
56 ppsc->const_amdpci_aspm = rtlpci->const_amdpci_aspm;
57 switch (rtlpci->const_pci_aspm) {
58 case 0:
59 /*No ASPM */
60 break;
61
62 case 1:
63 /*ASPM dynamically enabled/disable. */
64 ppsc->reg_rfps_level |= RT_RF_LPS_LEVEL_ASPM;
65 break;
66
67 case 2:
68 /*ASPM with Clock Req dynamically enabled/disable. */
69 ppsc->reg_rfps_level |= (RT_RF_LPS_LEVEL_ASPM |
70 RT_RF_OFF_LEVL_CLK_REQ);
71 break;
72
73 case 3:
74 /*
75 * Always enable ASPM and Clock Req
76 * from initialization to halt.
77 * */
78 ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM);
79 ppsc->reg_rfps_level |= (RT_RF_PS_LEVEL_ALWAYS_ASPM |
80 RT_RF_OFF_LEVL_CLK_REQ);
81 break;
82
83 case 4:
84 /*
85 * Always enable ASPM without Clock Req
86 * from initialization to halt.
87 * */
88 ppsc->reg_rfps_level &= ~(RT_RF_LPS_LEVEL_ASPM |
89 RT_RF_OFF_LEVL_CLK_REQ);
90 ppsc->reg_rfps_level |= RT_RF_PS_LEVEL_ALWAYS_ASPM;
91 break;
92 }
93
94 ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC;
95
96 /*Update Radio OFF setting */
97 switch (rtlpci->const_hwsw_rfoff_d3) {
98 case 1:
99 if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM)
100 ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM;
101 break;
102
103 case 2:
104 if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM)
105 ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_ASPM;
106 ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_HALT_NIC;
107 break;
108
109 case 3:
110 ppsc->reg_rfps_level |= RT_RF_OFF_LEVL_PCI_D3;
111 break;
112 }
113
114 /*Set HW definition to determine if it supports ASPM. */
115 switch (rtlpci->const_support_pciaspm) {
116 case 0:{
117 /*Not support ASPM. */
118 bool b_support_aspm = false;
119 ppsc->b_support_aspm = b_support_aspm;
120 break;
121 }
122 case 1:{
123 /*Support ASPM. */
124 bool b_support_aspm = true;
125 bool b_support_backdoor = true;
126 ppsc->b_support_aspm = b_support_aspm;
127
128 /*if(priv->oem_id == RT_CID_TOSHIBA &&
129 !priv->ndis_adapter.amd_l1_patch)
130 b_support_backdoor = false; */
131
132 ppsc->b_support_backdoor = b_support_backdoor;
133
134 break;
135 }
136 case 2:
137 /*ASPM value set by chipset. */
138 if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) {
139 bool b_support_aspm = true;
140 ppsc->b_support_aspm = b_support_aspm;
141 }
142 break;
143 default:
144 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
145 ("switch case not process\n"));
146 break;
147 }
148}
149
150static bool _rtl_pci_platform_switch_device_pci_aspm(
151 struct ieee80211_hw *hw,
152 u8 value)
153{
154 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
155 bool bresult = false;
156
157 value |= 0x40;
158
159 pci_write_config_byte(rtlpci->pdev, 0x80, value);
160
161 return bresult;
162}
163
164/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/
165static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
166{
167 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
168 u8 buffer;
169 bool bresult = false;
170
171 buffer = value;
172
173 pci_write_config_byte(rtlpci->pdev, 0x81, value);
174 bresult = true;
175
176 return bresult;
177}
178
179/*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/
180static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
181{
182 struct rtl_priv *rtlpriv = rtl_priv(hw);
183 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
184 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
185 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
186 u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
187 u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
188 u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
189 /*Retrieve original configuration settings. */
190 u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg;
191 u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter.
192 pcibridge_linkctrlreg;
193 u16 aspmlevel = 0;
194
195 if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
196 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
197 ("PCI(Bridge) UNKNOWN.\n"));
198
199 return;
200 }
201
202 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) {
203 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);
204 _rtl_pci_switch_clk_req(hw, 0x0);
205 }
206
207 if (1) {
208 /*for promising device will in L0 state after an I/O. */
209 u8 tmp_u1b;
210 pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b);
211 }
212
213 /*Set corresponding value. */
214 aspmlevel |= BIT(0) | BIT(1);
215 linkctrl_reg &= ~aspmlevel;
216 pcibridge_linkctrlreg &= ~(BIT(0) | BIT(1));
217
218 _rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg);
219 udelay(50);
220
221 /*4 Disable Pci Bridge ASPM */
222 rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
223 pcicfg_addrport + (num4bytes << 2));
224 rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, pcibridge_linkctrlreg);
225
226 udelay(50);
227
228}
229
230/*
231 *Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for
232 *power saving We should follow the sequence to enable
233 *RTL8192SE first then enable Pci Bridge ASPM
234 *or the system will show bluescreen.
235 */
236static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
237{
238 struct rtl_priv *rtlpriv = rtl_priv(hw);
239 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
240 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
241 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
242 u8 pcibridge_busnum = pcipriv->ndis_adapter.pcibridge_busnum;
243 u8 pcibridge_devnum = pcipriv->ndis_adapter.pcibridge_devnum;
244 u8 pcibridge_funcnum = pcipriv->ndis_adapter.pcibridge_funcnum;
245 u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
246 u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
247 u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
248 u16 aspmlevel;
249 u8 u_pcibridge_aspmsetting;
250 u8 u_device_aspmsetting;
251
252 if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
253 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
254 ("PCI(Bridge) UNKNOWN.\n"));
255 return;
256 }
257
258 /*4 Enable Pci Bridge ASPM */
259 rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
260 pcicfg_addrport + (num4bytes << 2));
261
262 u_pcibridge_aspmsetting =
263 pcipriv->ndis_adapter.pcibridge_linkctrlreg |
264 rtlpci->const_hostpci_aspm_setting;
265
266 if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL)
267 u_pcibridge_aspmsetting &= ~BIT(0);
268
269 rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, u_pcibridge_aspmsetting);
270
271 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
272 ("PlatformEnableASPM():PciBridge busnumber[%x], "
273 "DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n",
274 pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum,
275 (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10),
276 u_pcibridge_aspmsetting));
277
278 udelay(50);
279
280 /*Get ASPM level (with/without Clock Req) */
281 aspmlevel = rtlpci->const_devicepci_aspm_setting;
282 u_device_aspmsetting = pcipriv->ndis_adapter.linkctrl_reg;
283
284 /*_rtl_pci_platform_switch_device_pci_aspm(dev,*/
285 /*(priv->ndis_adapter.linkctrl_reg | ASPMLevel)); */
286
287 u_device_aspmsetting |= aspmlevel;
288
289 _rtl_pci_platform_switch_device_pci_aspm(hw, u_device_aspmsetting);
290
291 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) {
292 _rtl_pci_switch_clk_req(hw, (ppsc->reg_rfps_level &
293 RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0);
294 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);
295 }
296 udelay(200);
297}
298
299static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
300{
301 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
302 u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
303
304 bool status = false;
305 u8 offset_e0;
306 unsigned offset_e4;
307
308 rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
309 pcicfg_addrport + 0xE0);
310 rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, 0xA0);
311
312 rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
313 pcicfg_addrport + 0xE0);
314 rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &offset_e0);
315
316 if (offset_e0 == 0xA0) {
317 rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
318 pcicfg_addrport + 0xE4);
319 rtl_pci_raw_read_port_ulong(PCI_CONF_DATA, &offset_e4);
320 if (offset_e4 & BIT(23))
321 status = true;
322 }
323
324 return status;
325}
326
327static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw)
328{
329 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
330 u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset;
331 u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
332 u8 linkctrl_reg;
333 u8 num4bBytes;
334
335 num4bBytes = (capabilityoffset + 0x10) / 4;
336
337 /*Read Link Control Register */
338 rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
339 pcicfg_addrport + (num4bBytes << 2));
340 rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &linkctrl_reg);
341
342 pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg;
343}
344
345static void rtl_pci_parse_configuration(struct pci_dev *pdev,
346 struct ieee80211_hw *hw)
347{
348 struct rtl_priv *rtlpriv = rtl_priv(hw);
349 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
350
351 u8 tmp;
352 int pos;
353 u8 linkctrl_reg;
354
355 /*Link Control Register */
356 pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
357 pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg);
358 pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg;
359
360 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
361 ("Link Control Register =%x\n",
362 pcipriv->ndis_adapter.linkctrl_reg));
363
364 pci_read_config_byte(pdev, 0x98, &tmp);
365 tmp |= BIT(4);
366 pci_write_config_byte(pdev, 0x98, tmp);
367
368 tmp = 0x17;
369 pci_write_config_byte(pdev, 0x70f, tmp);
370}
371
372static void _rtl_pci_initialize_adapter_common(struct ieee80211_hw *hw)
373{
374 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
375
376 _rtl_pci_update_default_setting(hw);
377
378 if (ppsc->reg_rfps_level & RT_RF_PS_LEVEL_ALWAYS_ASPM) {
379 /*Always enable ASPM & Clock Req. */
380 rtl_pci_enable_aspm(hw);
381 RT_SET_PS_LEVEL(ppsc, RT_RF_PS_LEVEL_ALWAYS_ASPM);
382 }
383
384}
385
386static void rtl_pci_init_aspm(struct ieee80211_hw *hw)
387{
388 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
389
390 /*close ASPM for AMD defaultly */
391 rtlpci->const_amdpci_aspm = 0;
392
393 /*
394 * ASPM PS mode.
395 * 0 - Disable ASPM,
396 * 1 - Enable ASPM without Clock Req,
397 * 2 - Enable ASPM with Clock Req,
398 * 3 - Alwyas Enable ASPM with Clock Req,
399 * 4 - Always Enable ASPM without Clock Req.
400 * set defult to RTL8192CE:3 RTL8192E:2
401 * */
402 rtlpci->const_pci_aspm = 3;
403
404 /*Setting for PCI-E device */
405 rtlpci->const_devicepci_aspm_setting = 0x03;
406
407 /*Setting for PCI-E bridge */
408 rtlpci->const_hostpci_aspm_setting = 0x02;
409
410 /*
411 * In Hw/Sw Radio Off situation.
412 * 0 - Default,
413 * 1 - From ASPM setting without low Mac Pwr,
414 * 2 - From ASPM setting with low Mac Pwr,
415 * 3 - Bus D3
416 * set default to RTL8192CE:0 RTL8192SE:2
417 */
418 rtlpci->const_hwsw_rfoff_d3 = 0;
419
420 /*
421 * This setting works for those device with
422 * backdoor ASPM setting such as EPHY setting.
423 * 0 - Not support ASPM,
424 * 1 - Support ASPM,
425 * 2 - According to chipset.
426 */
427 rtlpci->const_support_pciaspm = 1;
428
429 _rtl_pci_initialize_adapter_common(hw);
430}
431
432static void _rtl_pci_io_handler_init(struct device *dev,
433 struct ieee80211_hw *hw)
434{
435 struct rtl_priv *rtlpriv = rtl_priv(hw);
436
437 rtlpriv->io.dev = dev;
438
439 rtlpriv->io.write8_async = pci_write8_async;
440 rtlpriv->io.write16_async = pci_write16_async;
441 rtlpriv->io.write32_async = pci_write32_async;
442
443 rtlpriv->io.read8_sync = pci_read8_sync;
444 rtlpriv->io.read16_sync = pci_read16_sync;
445 rtlpriv->io.read32_sync = pci_read32_sync;
446
447}
448
449static void _rtl_pci_io_handler_release(struct ieee80211_hw *hw)
450{
451}
452
453static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
454{
455 struct rtl_priv *rtlpriv = rtl_priv(hw);
456 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
457
458 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio];
459
460 while (skb_queue_len(&ring->queue)) {
461 struct rtl_tx_desc *entry = &ring->desc[ring->idx];
462 struct sk_buff *skb;
463 struct ieee80211_tx_info *info;
464
465 u8 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) entry, true,
466 HW_DESC_OWN);
467
468 /*
469 *beacon packet will only use the first
470 *descriptor defautly,and the own may not
471 *be cleared by the hardware
472 */
473 if (own)
474 return;
475 ring->idx = (ring->idx + 1) % ring->entries;
476
477 skb = __skb_dequeue(&ring->queue);
478 pci_unmap_single(rtlpci->pdev,
479 le32_to_cpu(rtlpriv->cfg->ops->
480 get_desc((u8 *) entry, true,
481 HW_DESC_TXBUFF_ADDR)),
482 skb->len, PCI_DMA_TODEVICE);
483
484 RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE,
485 ("new ring->idx:%d, "
486 "free: skb_queue_len:%d, free: seq:%x\n",
487 ring->idx,
488 skb_queue_len(&ring->queue),
489 *(u16 *) (skb->data + 22)));
490
491 info = IEEE80211_SKB_CB(skb);
492 ieee80211_tx_info_clear_status(info);
493
494 info->flags |= IEEE80211_TX_STAT_ACK;
495 /*info->status.rates[0].count = 1; */
496
497 ieee80211_tx_status_irqsafe(hw, skb);
498
499 if ((ring->entries - skb_queue_len(&ring->queue))
500 == 2) {
501
502 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
503 ("more desc left, wake"
504 "skb_queue@%d,ring->idx = %d,"
505 "skb_queue_len = 0x%d\n",
506 prio, ring->idx,
507 skb_queue_len(&ring->queue)));
508
509 ieee80211_wake_queue(hw,
510 skb_get_queue_mapping
511 (skb));
512 }
513
514 skb = NULL;
515 }
516
517 if (((rtlpriv->link_info.num_rx_inperiod +
518 rtlpriv->link_info.num_tx_inperiod) > 8) ||
519 (rtlpriv->link_info.num_rx_inperiod > 2)) {
520 rtl_lps_leave(hw);
521 }
522}
523
524static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
525{
526 struct rtl_priv *rtlpriv = rtl_priv(hw);
527 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
528 int rx_queue_idx = RTL_PCI_RX_MPDU_QUEUE;
529
530 struct ieee80211_rx_status rx_status = { 0 };
531 unsigned int count = rtlpci->rxringcount;
532 u8 own;
533 u8 tmp_one;
534 u32 bufferaddress;
535 bool unicast = false;
536
537 struct rtl_stats stats = {
538 .signal = 0,
539 .noise = -98,
540 .rate = 0,
541 };
542
543 /*RX NORMAL PKT */
544 while (count--) {
545 /*rx descriptor */
546 struct rtl_rx_desc *pdesc = &rtlpci->rx_ring[rx_queue_idx].desc[
547 rtlpci->rx_ring[rx_queue_idx].idx];
548 /*rx pkt */
549 struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[
550 rtlpci->rx_ring[rx_queue_idx].idx];
551
552 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
553 false, HW_DESC_OWN);
554
555 if (own) {
556 /*wait data to be filled by hardware */
557 return;
558 } else {
559 struct ieee80211_hdr *hdr;
560 u16 fc;
561 struct sk_buff *new_skb = NULL;
562
563 rtlpriv->cfg->ops->query_rx_desc(hw, &stats,
564 &rx_status,
565 (u8 *) pdesc, skb);
566
567 pci_unmap_single(rtlpci->pdev,
568 *((dma_addr_t *) skb->cb),
569 rtlpci->rxbuffersize,
570 PCI_DMA_FROMDEVICE);
571
572 skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
573 false,
574 HW_DESC_RXPKT_LEN));
575 skb_reserve(skb,
576 stats.rx_drvinfo_size + stats.rx_bufshift);
577
578 /*
579 *NOTICE This can not be use for mac80211,
580 *this is done in mac80211 code,
581 *if you done here sec DHCP will fail
582 *skb_trim(skb, skb->len - 4);
583 */
584
585 hdr = (struct ieee80211_hdr *)(skb->data);
586 fc = le16_to_cpu(hdr->frame_control);
587
588 if (!stats.b_crc) {
589 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
590 sizeof(rx_status));
591
592 if (is_broadcast_ether_addr(hdr->addr1))
593 ;/*TODO*/
594 else {
595 if (is_multicast_ether_addr(hdr->addr1))
596 ;/*TODO*/
597 else {
598 unicast = true;
599 rtlpriv->stats.rxbytesunicast +=
600 skb->len;
601 }
602 }
603
604 rtl_is_special_data(hw, skb, false);
605
606 if (ieee80211_is_data(fc)) {
607 rtlpriv->cfg->ops->led_control(hw,
608 LED_CTL_RX);
609
610 if (unicast)
611 rtlpriv->link_info.
612 num_rx_inperiod++;
613 }
614
615 if (unlikely(!rtl_action_proc(hw, skb, false)))
616 dev_kfree_skb_any(skb);
617 else
618 ieee80211_rx_irqsafe(hw, skb);
619 } else {
620 dev_kfree_skb_any(skb);
621 }
622
623 if (((rtlpriv->link_info.num_rx_inperiod +
624 rtlpriv->link_info.num_tx_inperiod) > 8) ||
625 (rtlpriv->link_info.num_rx_inperiod > 2)) {
626 rtl_lps_leave(hw);
627 }
628
629 new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
630 if (unlikely(!new_skb)) {
631 RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
632 DBG_DMESG,
633 ("can't alloc skb for rx\n"));
634 goto done;
635 }
636 skb = new_skb;
637 /*skb->dev = dev; */
638
639 rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci->
640 rx_ring
641 [rx_queue_idx].
642 idx] = skb;
643 *((dma_addr_t *) skb->cb) =
644 pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
645 rtlpci->rxbuffersize,
646 PCI_DMA_FROMDEVICE);
647
648 }
649done:
650 bufferaddress = cpu_to_le32(*((dma_addr_t *) skb->cb));
651 tmp_one = 1;
652 rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
653 HW_DESC_RXBUFF_ADDR,
654 (u8 *)&bufferaddress);
655 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN,
656 (u8 *)&tmp_one);
657 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
658 HW_DESC_RXPKT_LEN,
659 (u8 *)&rtlpci->rxbuffersize);
660
661 if (rtlpci->rx_ring[rx_queue_idx].idx ==
662 rtlpci->rxringcount - 1)
663 rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false,
664 HW_DESC_RXERO,
665 (u8 *)&tmp_one);
666
667 rtlpci->rx_ring[rx_queue_idx].idx =
668 (rtlpci->rx_ring[rx_queue_idx].idx + 1) %
669 rtlpci->rxringcount;
670 }
671
672}
673
674void _rtl_pci_tx_interrupt(struct ieee80211_hw *hw)
675{
676 struct rtl_priv *rtlpriv = rtl_priv(hw);
677 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
678 int prio;
679
680 for (prio = 0; prio < RTL_PCI_MAX_TX_QUEUE_COUNT; prio++) {
681 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio];
682
683 while (skb_queue_len(&ring->queue)) {
684 struct rtl_tx_desc *entry = &ring->desc[ring->idx];
685 struct sk_buff *skb;
686 struct ieee80211_tx_info *info;
687 u8 own;
688
689 /*
690 *beacon packet will only use the first
691 *descriptor defautly, and the own may not
692 *be cleared by the hardware, and
693 *beacon will free in prepare beacon
694 */
695 if (prio == BEACON_QUEUE || prio == TXCMD_QUEUE ||
696 prio == HCCA_QUEUE)
697 break;
698
699 own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)entry,
700 true,
701 HW_DESC_OWN);
702
703 if (own)
704 break;
705
706 skb = __skb_dequeue(&ring->queue);
707 pci_unmap_single(rtlpci->pdev,
708 le32_to_cpu(rtlpriv->cfg->ops->
709 get_desc((u8 *) entry,
710 true,
711 HW_DESC_TXBUFF_ADDR)),
712 skb->len, PCI_DMA_TODEVICE);
713
714 ring->idx = (ring->idx + 1) % ring->entries;
715
716 info = IEEE80211_SKB_CB(skb);
717 ieee80211_tx_info_clear_status(info);
718
719 info->flags |= IEEE80211_TX_STAT_ACK;
720 /*info->status.rates[0].count = 1; */
721
722 ieee80211_tx_status_irqsafe(hw, skb);
723
724 if ((ring->entries - skb_queue_len(&ring->queue))
725 == 2 && prio != BEACON_QUEUE) {
726 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
727 ("more desc left, wake "
728 "skb_queue@%d,ring->idx = %d,"
729 "skb_queue_len = 0x%d\n",
730 prio, ring->idx,
731 skb_queue_len(&ring->queue)));
732
733 ieee80211_wake_queue(hw,
734 skb_get_queue_mapping
735 (skb));
736 }
737
738 skb = NULL;
739 }
740 }
741}
742
743static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
744{
745 struct ieee80211_hw *hw = dev_id;
746 struct rtl_priv *rtlpriv = rtl_priv(hw);
747 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
748 unsigned long flags;
749 u32 inta = 0;
750 u32 intb = 0;
751
752 if (rtlpci->irq_enabled == 0)
753 return IRQ_HANDLED;
754
755 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
756
757 /*read ISR: 4/8bytes */
758 rtlpriv->cfg->ops->interrupt_recognized(hw, &inta, &intb);
759
760 /*Shared IRQ or HW disappared */
761 if (!inta || inta == 0xffff)
762 goto done;
763
764 /*<1> beacon related */
765 if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) {
766 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
767 ("beacon ok interrupt!\n"));
768 }
769
770 if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) {
771 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
772 ("beacon err interrupt!\n"));
773 }
774
775 if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) {
776 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
777 ("beacon interrupt!\n"));
778 }
779
780 if (inta & rtlpriv->cfg->maps[RTL_IMR_BcnInt]) {
781 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
782 ("prepare beacon for interrupt!\n"));
783 tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet);
784 }
785
786 /*<3> Tx related */
787 if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TXFOVW]))
788 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("IMR_TXFOVW!\n"));
789
790 if (inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) {
791 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
792 ("Manage ok interrupt!\n"));
793 _rtl_pci_tx_isr(hw, MGNT_QUEUE);
794 }
795
796 if (inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) {
797 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
798 ("HIGH_QUEUE ok interrupt!\n"));
799 _rtl_pci_tx_isr(hw, HIGH_QUEUE);
800 }
801
802 if (inta & rtlpriv->cfg->maps[RTL_IMR_BKDOK]) {
803 rtlpriv->link_info.num_tx_inperiod++;
804
805 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
806 ("BK Tx OK interrupt!\n"));
807 _rtl_pci_tx_isr(hw, BK_QUEUE);
808 }
809
810 if (inta & rtlpriv->cfg->maps[RTL_IMR_BEDOK]) {
811 rtlpriv->link_info.num_tx_inperiod++;
812
813 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
814 ("BE TX OK interrupt!\n"));
815 _rtl_pci_tx_isr(hw, BE_QUEUE);
816 }
817
818 if (inta & rtlpriv->cfg->maps[RTL_IMR_VIDOK]) {
819 rtlpriv->link_info.num_tx_inperiod++;
820
821 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
822 ("VI TX OK interrupt!\n"));
823 _rtl_pci_tx_isr(hw, VI_QUEUE);
824 }
825
826 if (inta & rtlpriv->cfg->maps[RTL_IMR_VODOK]) {
827 rtlpriv->link_info.num_tx_inperiod++;
828
829 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
830 ("Vo TX OK interrupt!\n"));
831 _rtl_pci_tx_isr(hw, VO_QUEUE);
832 }
833
834 /*<2> Rx related */
835 if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) {
836 RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n"));
837 tasklet_schedule(&rtlpriv->works.irq_tasklet);
838 }
839
840 if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) {
841 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
842 ("rx descriptor unavailable!\n"));
843 tasklet_schedule(&rtlpriv->works.irq_tasklet);
844 }
845
846 if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) {
847 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n"));
848 tasklet_schedule(&rtlpriv->works.irq_tasklet);
849 }
850
851 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
852 return IRQ_HANDLED;
853
854done:
855 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
856 return IRQ_HANDLED;
857}
858
859static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)
860{
861 _rtl_pci_rx_interrupt(hw);
862}
863
864static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
865{
866 struct rtl_priv *rtlpriv = rtl_priv(hw);
867 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
868 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
869 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
870 struct ieee80211_hdr *hdr = NULL;
871 struct ieee80211_tx_info *info = NULL;
872 struct sk_buff *pskb = NULL;
873 struct rtl_tx_desc *pdesc = NULL;
874 unsigned int queue_index;
875 u8 temp_one = 1;
876
877 ring = &rtlpci->tx_ring[BEACON_QUEUE];
878 pskb = __skb_dequeue(&ring->queue);
879 if (pskb)
880 kfree_skb(pskb);
881
882 /*NB: the beacon data buffer must be 32-bit aligned. */
883 pskb = ieee80211_beacon_get(hw, mac->vif);
884 if (pskb == NULL)
885 return;
886 hdr = (struct ieee80211_hdr *)(pskb->data);
887 info = IEEE80211_SKB_CB(pskb);
888
889 queue_index = BEACON_QUEUE;
890
891 pdesc = &ring->desc[0];
892 rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc,
893 info, pskb, queue_index);
894
895 __skb_queue_tail(&ring->queue, pskb);
896
897 rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true, HW_DESC_OWN,
898 (u8 *)&temp_one);
899
900 return;
901}
902
903static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw)
904{
905 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
906 u8 i;
907
908 for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++)
909 rtlpci->txringcount[i] = RT_TXDESC_NUM;
910
911 /*
912 *we just alloc 2 desc for beacon queue,
913 *because we just need first desc in hw beacon.
914 */
915 rtlpci->txringcount[BEACON_QUEUE] = 2;
916
917 /*
918 *BE queue need more descriptor for performance
919 *consideration or, No more tx desc will happen,
920 *and may cause mac80211 mem leakage.
921 */
922 rtlpci->txringcount[BE_QUEUE] = RT_TXDESC_NUM_BE_QUEUE;
923
924 rtlpci->rxbuffersize = 9100; /*2048/1024; */
925 rtlpci->rxringcount = RTL_PCI_MAX_RX_COUNT; /*64; */
926}
927
928static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
929 struct pci_dev *pdev)
930{
931 struct rtl_priv *rtlpriv = rtl_priv(hw);
932 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
933 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
934 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
935 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
936
937 rtlpci->up_first_time = true;
938 rtlpci->being_init_adapter = false;
939
940 rtlhal->hw = hw;
941 rtlpci->pdev = pdev;
942
943 ppsc->b_inactiveps = false;
944 ppsc->b_leisure_ps = true;
945 ppsc->b_fwctrl_lps = true;
946 ppsc->b_reg_fwctrl_lps = 3;
947 ppsc->reg_max_lps_awakeintvl = 5;
948
949 if (ppsc->b_reg_fwctrl_lps == 1)
950 ppsc->fwctrl_psmode = FW_PS_MIN_MODE;
951 else if (ppsc->b_reg_fwctrl_lps == 2)
952 ppsc->fwctrl_psmode = FW_PS_MAX_MODE;
953 else if (ppsc->b_reg_fwctrl_lps == 3)
954 ppsc->fwctrl_psmode = FW_PS_DTIM_MODE;
955
956 /*Tx/Rx related var */
957 _rtl_pci_init_trx_var(hw);
958
959 /*IBSS*/ mac->beacon_interval = 100;
960
961 /*AMPDU*/ mac->min_space_cfg = 0;
962 mac->max_mss_density = 0;
963 /*set sane AMPDU defaults */
964 mac->current_ampdu_density = 7;
965 mac->current_ampdu_factor = 3;
966
967 /*QOS*/ rtlpci->acm_method = eAcmWay2_SW;
968
969 /*task */
970 tasklet_init(&rtlpriv->works.irq_tasklet,
971 (void (*)(unsigned long))_rtl_pci_irq_tasklet,
972 (unsigned long)hw);
973 tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet,
974 (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet,
975 (unsigned long)hw);
976}
977
978static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
979 unsigned int prio, unsigned int entries)
980{
981 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
982 struct rtl_priv *rtlpriv = rtl_priv(hw);
983 struct rtl_tx_desc *ring;
984 dma_addr_t dma;
985 u32 nextdescaddress;
986 int i;
987
988 ring = pci_alloc_consistent(rtlpci->pdev,
989 sizeof(*ring) * entries, &dma);
990
991 if (!ring || (unsigned long)ring & 0xFF) {
992 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
993 ("Cannot allocate TX ring (prio = %d)\n", prio));
994 return -ENOMEM;
995 }
996
997 memset(ring, 0, sizeof(*ring) * entries);
998 rtlpci->tx_ring[prio].desc = ring;
999 rtlpci->tx_ring[prio].dma = dma;
1000 rtlpci->tx_ring[prio].idx = 0;
1001 rtlpci->tx_ring[prio].entries = entries;
1002 skb_queue_head_init(&rtlpci->tx_ring[prio].queue);
1003
1004 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1005 ("queue:%d, ring_addr:%p\n", prio, ring));
1006
1007 for (i = 0; i < entries; i++) {
1008 nextdescaddress = cpu_to_le32((u32) dma +
1009 ((i + 1) % entries) *
1010 sizeof(*ring));
1011
1012 rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]),
1013 true, HW_DESC_TX_NEXTDESC_ADDR,
1014 (u8 *)&nextdescaddress);
1015 }
1016
1017 return 0;
1018}
1019
1020static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
1021{
1022 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1023 struct rtl_priv *rtlpriv = rtl_priv(hw);
1024 struct rtl_rx_desc *entry = NULL;
1025 int i, rx_queue_idx;
1026 u8 tmp_one = 1;
1027
1028 /*
1029 *rx_queue_idx 0:RX_MPDU_QUEUE
1030 *rx_queue_idx 1:RX_CMD_QUEUE
1031 */
1032 for (rx_queue_idx = 0; rx_queue_idx < RTL_PCI_MAX_RX_QUEUE;
1033 rx_queue_idx++) {
1034 rtlpci->rx_ring[rx_queue_idx].desc =
1035 pci_alloc_consistent(rtlpci->pdev,
1036 sizeof(*rtlpci->rx_ring[rx_queue_idx].
1037 desc) * rtlpci->rxringcount,
1038 &rtlpci->rx_ring[rx_queue_idx].dma);
1039
1040 if (!rtlpci->rx_ring[rx_queue_idx].desc ||
1041 (unsigned long)rtlpci->rx_ring[rx_queue_idx].desc & 0xFF) {
1042 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1043 ("Cannot allocate RX ring\n"));
1044 return -ENOMEM;
1045 }
1046
1047 memset(rtlpci->rx_ring[rx_queue_idx].desc, 0,
1048 sizeof(*rtlpci->rx_ring[rx_queue_idx].desc) *
1049 rtlpci->rxringcount);
1050
1051 rtlpci->rx_ring[rx_queue_idx].idx = 0;
1052
1053 for (i = 0; i < rtlpci->rxringcount; i++) {
1054 struct sk_buff *skb =
1055 dev_alloc_skb(rtlpci->rxbuffersize);
1056 u32 bufferaddress;
1057 entry = &rtlpci->rx_ring[rx_queue_idx].desc[i];
1058 if (!skb)
1059 return 0;
1060
1061 /*skb->dev = dev; */
1062
1063 rtlpci->rx_ring[rx_queue_idx].rx_buf[i] = skb;
1064
1065 /*
1066 *just set skb->cb to mapping addr
1067 *for pci_unmap_single use
1068 */
1069 *((dma_addr_t *) skb->cb) =
1070 pci_map_single(rtlpci->pdev, skb_tail_pointer(skb),
1071 rtlpci->rxbuffersize,
1072 PCI_DMA_FROMDEVICE);
1073
1074 bufferaddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
1075 rtlpriv->cfg->ops->set_desc((u8 *)entry, false,
1076 HW_DESC_RXBUFF_ADDR,
1077 (u8 *)&bufferaddress);
1078 rtlpriv->cfg->ops->set_desc((u8 *)entry, false,
1079 HW_DESC_RXPKT_LEN,
1080 (u8 *)&rtlpci->
1081 rxbuffersize);
1082 rtlpriv->cfg->ops->set_desc((u8 *) entry, false,
1083 HW_DESC_RXOWN,
1084 (u8 *)&tmp_one);
1085 }
1086
1087 rtlpriv->cfg->ops->set_desc((u8 *) entry, false,
1088 HW_DESC_RXERO, (u8 *)&tmp_one);
1089 }
1090 return 0;
1091}
1092
1093static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw,
1094 unsigned int prio)
1095{
1096 struct rtl_priv *rtlpriv = rtl_priv(hw);
1097 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1098 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio];
1099
1100 while (skb_queue_len(&ring->queue)) {
1101 struct rtl_tx_desc *entry = &ring->desc[ring->idx];
1102 struct sk_buff *skb = __skb_dequeue(&ring->queue);
1103
1104 pci_unmap_single(rtlpci->pdev,
1105 le32_to_cpu(rtlpriv->cfg->
1106 ops->get_desc((u8 *) entry, true,
1107 HW_DESC_TXBUFF_ADDR)),
1108 skb->len, PCI_DMA_TODEVICE);
1109 kfree_skb(skb);
1110 ring->idx = (ring->idx + 1) % ring->entries;
1111 }
1112
1113 pci_free_consistent(rtlpci->pdev,
1114 sizeof(*ring->desc) * ring->entries,
1115 ring->desc, ring->dma);
1116 ring->desc = NULL;
1117}
1118
1119static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci)
1120{
1121 int i, rx_queue_idx;
1122
1123 /*rx_queue_idx 0:RX_MPDU_QUEUE */
1124 /*rx_queue_idx 1:RX_CMD_QUEUE */
1125 for (rx_queue_idx = 0; rx_queue_idx < RTL_PCI_MAX_RX_QUEUE;
1126 rx_queue_idx++) {
1127 for (i = 0; i < rtlpci->rxringcount; i++) {
1128 struct sk_buff *skb =
1129 rtlpci->rx_ring[rx_queue_idx].rx_buf[i];
1130 if (!skb)
1131 continue;
1132
1133 pci_unmap_single(rtlpci->pdev,
1134 *((dma_addr_t *) skb->cb),
1135 rtlpci->rxbuffersize,
1136 PCI_DMA_FROMDEVICE);
1137 kfree_skb(skb);
1138 }
1139
1140 pci_free_consistent(rtlpci->pdev,
1141 sizeof(*rtlpci->rx_ring[rx_queue_idx].
1142 desc) * rtlpci->rxringcount,
1143 rtlpci->rx_ring[rx_queue_idx].desc,
1144 rtlpci->rx_ring[rx_queue_idx].dma);
1145 rtlpci->rx_ring[rx_queue_idx].desc = NULL;
1146 }
1147}
1148
1149static int _rtl_pci_init_trx_ring(struct ieee80211_hw *hw)
1150{
1151 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1152 int ret;
1153 int i;
1154
1155 ret = _rtl_pci_init_rx_ring(hw);
1156 if (ret)
1157 return ret;
1158
1159 for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) {
1160 ret = _rtl_pci_init_tx_ring(hw, i,
1161 rtlpci->txringcount[i]);
1162 if (ret)
1163 goto err_free_rings;
1164 }
1165
1166 return 0;
1167
1168err_free_rings:
1169 _rtl_pci_free_rx_ring(rtlpci);
1170
1171 for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++)
1172 if (rtlpci->tx_ring[i].desc)
1173 _rtl_pci_free_tx_ring(hw, i);
1174
1175 return 1;
1176}
1177
1178static int _rtl_pci_deinit_trx_ring(struct ieee80211_hw *hw)
1179{
1180 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1181 u32 i;
1182
1183 /*free rx rings */
1184 _rtl_pci_free_rx_ring(rtlpci);
1185
1186 /*free tx rings */
1187 for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++)
1188 _rtl_pci_free_tx_ring(hw, i);
1189
1190 return 0;
1191}
1192
1193int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
1194{
1195 struct rtl_priv *rtlpriv = rtl_priv(hw);
1196 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1197 int i, rx_queue_idx;
1198 unsigned long flags;
1199 u8 tmp_one = 1;
1200
1201 /*rx_queue_idx 0:RX_MPDU_QUEUE */
1202 /*rx_queue_idx 1:RX_CMD_QUEUE */
1203 for (rx_queue_idx = 0; rx_queue_idx < RTL_PCI_MAX_RX_QUEUE;
1204 rx_queue_idx++) {
1205 /*
1206 *force the rx_ring[RX_MPDU_QUEUE/
1207 *RX_CMD_QUEUE].idx to the first one
1208 */
1209 if (rtlpci->rx_ring[rx_queue_idx].desc) {
1210 struct rtl_rx_desc *entry = NULL;
1211
1212 for (i = 0; i < rtlpci->rxringcount; i++) {
1213 entry = &rtlpci->rx_ring[rx_queue_idx].desc[i];
1214 rtlpriv->cfg->ops->set_desc((u8 *) entry,
1215 false,
1216 HW_DESC_RXOWN,
1217 (u8 *)&tmp_one);
1218 }
1219 rtlpci->rx_ring[rx_queue_idx].idx = 0;
1220 }
1221 }
1222
1223 /*
1224 *after reset, release previous pending packet,
1225 *and force the tx idx to the first one
1226 */
1227 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
1228 for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) {
1229 if (rtlpci->tx_ring[i].desc) {
1230 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[i];
1231
1232 while (skb_queue_len(&ring->queue)) {
1233 struct rtl_tx_desc *entry =
1234 &ring->desc[ring->idx];
1235 struct sk_buff *skb =
1236 __skb_dequeue(&ring->queue);
1237
1238 pci_unmap_single(rtlpci->pdev,
1239 le32_to_cpu(rtlpriv->cfg->ops->
1240 get_desc((u8 *)
1241 entry,
1242 true,
1243 HW_DESC_TXBUFF_ADDR)),
1244 skb->len, PCI_DMA_TODEVICE);
1245 kfree_skb(skb);
1246 ring->idx = (ring->idx + 1) % ring->entries;
1247 }
1248 ring->idx = 0;
1249 }
1250 }
1251
1252 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
1253
1254 return 0;
1255}
1256
1257unsigned int _rtl_mac_to_hwqueue(u16 fc,
1258 unsigned int mac80211_queue_index)
1259{
1260 unsigned int hw_queue_index;
1261
1262 if (unlikely(ieee80211_is_beacon(fc))) {
1263 hw_queue_index = BEACON_QUEUE;
1264 goto out;
1265 }
1266
1267 if (ieee80211_is_mgmt(fc)) {
1268 hw_queue_index = MGNT_QUEUE;
1269 goto out;
1270 }
1271
1272 switch (mac80211_queue_index) {
1273 case 0:
1274 hw_queue_index = VO_QUEUE;
1275 break;
1276 case 1:
1277 hw_queue_index = VI_QUEUE;
1278 break;
1279 case 2:
1280 hw_queue_index = BE_QUEUE;;
1281 break;
1282 case 3:
1283 hw_queue_index = BK_QUEUE;
1284 break;
1285 default:
1286 hw_queue_index = BE_QUEUE;
1287 RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n",
1288 mac80211_queue_index));
1289 break;
1290 }
1291
1292out:
1293 return hw_queue_index;
1294}
1295
1296int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1297{
1298 struct rtl_priv *rtlpriv = rtl_priv(hw);
1299 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1300 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1301 struct rtl8192_tx_ring *ring;
1302 struct rtl_tx_desc *pdesc;
1303 u8 idx;
1304 unsigned int queue_index, hw_queue;
1305 unsigned long flags;
1306 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
1307 u16 fc = le16_to_cpu(hdr->frame_control);
1308 u8 *pda_addr = hdr->addr1;
1309 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1310 /*ssn */
1311 u8 *qc = NULL;
1312 u8 tid = 0;
1313 u16 seq_number = 0;
1314 u8 own;
1315 u8 temp_one = 1;
1316
1317 if (ieee80211_is_mgmt(fc))
1318 rtl_tx_mgmt_proc(hw, skb);
1319 rtl_action_proc(hw, skb, true);
1320
1321 queue_index = skb_get_queue_mapping(skb);
1322 hw_queue = _rtl_mac_to_hwqueue(fc, queue_index);
1323
1324 if (is_multicast_ether_addr(pda_addr))
1325 rtlpriv->stats.txbytesmulticast += skb->len;
1326 else if (is_broadcast_ether_addr(pda_addr))
1327 rtlpriv->stats.txbytesbroadcast += skb->len;
1328 else
1329 rtlpriv->stats.txbytesunicast += skb->len;
1330
1331 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
1332
1333 ring = &rtlpci->tx_ring[hw_queue];
1334 if (hw_queue != BEACON_QUEUE)
1335 idx = (ring->idx + skb_queue_len(&ring->queue)) %
1336 ring->entries;
1337 else
1338 idx = 0;
1339
1340 pdesc = &ring->desc[idx];
1341 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc,
1342 true, HW_DESC_OWN);
1343
1344 if ((own == 1) && (hw_queue != BEACON_QUEUE)) {
1345 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1346 ("No more TX desc@%d, ring->idx = %d,"
1347 "idx = %d, skb_queue_len = 0x%d\n",
1348 hw_queue, ring->idx, idx,
1349 skb_queue_len(&ring->queue)));
1350
1351 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
1352 return skb->len;
1353 }
1354
1355 /*
1356 *if(ieee80211_is_nullfunc(fc)) {
1357 * spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
1358 * return 1;
1359 *}
1360 */
1361
1362 if (ieee80211_is_data_qos(fc)) {
1363 qc = ieee80211_get_qos_ctl(hdr);
1364 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
1365
1366 seq_number = mac->tids[tid].seq_number;
1367 seq_number &= IEEE80211_SCTL_SEQ;
1368 /*
1369 *hdr->seq_ctrl = hdr->seq_ctrl &
1370 *cpu_to_le16(IEEE80211_SCTL_FRAG);
1371 *hdr->seq_ctrl |= cpu_to_le16(seq_number);
1372 */
1373
1374 seq_number += 1;
1375 }
1376
1377 if (ieee80211_is_data(fc))
1378 rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX);
1379
1380 rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc,
1381 info, skb, hw_queue);
1382
1383 __skb_queue_tail(&ring->queue, skb);
1384
1385 rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true,
1386 HW_DESC_OWN, (u8 *)&temp_one);
1387
1388 if (!ieee80211_has_morefrags(hdr->frame_control)) {
1389 if (qc)
1390 mac->tids[tid].seq_number = seq_number;
1391 }
1392
1393 if ((ring->entries - skb_queue_len(&ring->queue)) < 2 &&
1394 hw_queue != BEACON_QUEUE) {
1395
1396 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1397 ("less desc left, stop skb_queue@%d, "
1398 "ring->idx = %d,"
1399 "idx = %d, skb_queue_len = 0x%d\n",
1400 hw_queue, ring->idx, idx,
1401 skb_queue_len(&ring->queue)));
1402
1403 ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
1404 }
1405
1406 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
1407
1408 rtlpriv->cfg->ops->tx_polling(hw, hw_queue);
1409
1410 return 0;
1411}
1412
1413void rtl_pci_deinit(struct ieee80211_hw *hw)
1414{
1415 struct rtl_priv *rtlpriv = rtl_priv(hw);
1416 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1417
1418 _rtl_pci_deinit_trx_ring(hw);
1419
1420 synchronize_irq(rtlpci->pdev->irq);
1421 tasklet_kill(&rtlpriv->works.irq_tasklet);
1422
1423 flush_workqueue(rtlpriv->works.rtl_wq);
1424 destroy_workqueue(rtlpriv->works.rtl_wq);
1425
1426}
1427
1428int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
1429{
1430 struct rtl_priv *rtlpriv = rtl_priv(hw);
1431 int err;
1432
1433 _rtl_pci_init_struct(hw, pdev);
1434
1435 err = _rtl_pci_init_trx_ring(hw);
1436 if (err) {
1437 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1438 ("tx ring initialization failed"));
1439 return err;
1440 }
1441
1442 return 1;
1443}
1444
1445int rtl_pci_start(struct ieee80211_hw *hw)
1446{
1447 struct rtl_priv *rtlpriv = rtl_priv(hw);
1448 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1449 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1450 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1451
1452 int err;
1453
1454 rtl_pci_reset_trx_ring(hw);
1455
1456 rtlpci->driver_is_goingto_unload = false;
1457 err = rtlpriv->cfg->ops->hw_init(hw);
1458 if (err) {
1459 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1460 ("Failed to config hardware!\n"));
1461 return err;
1462 }
1463
1464 rtlpriv->cfg->ops->enable_interrupt(hw);
1465 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable_interrupt OK\n"));
1466
1467 rtl_init_rx_config(hw);
1468
1469 /*should after adapter start and interrupt enable. */
1470 set_hal_start(rtlhal);
1471
1472 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1473
1474 rtlpci->up_first_time = false;
1475
1476 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n"));
1477 return 0;
1478}
1479
1480void rtl_pci_stop(struct ieee80211_hw *hw)
1481{
1482 struct rtl_priv *rtlpriv = rtl_priv(hw);
1483 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1484 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1485 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1486 unsigned long flags;
1487 u8 RFInProgressTimeOut = 0;
1488
1489 /*
1490 *should before disable interrrupt&adapter
1491 *and will do it immediately.
1492 */
1493 set_hal_stop(rtlhal);
1494
1495 rtlpriv->cfg->ops->disable_interrupt(hw);
1496
1497 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
1498 while (ppsc->rfchange_inprogress) {
1499 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags);
1500 if (RFInProgressTimeOut > 100) {
1501 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
1502 break;
1503 }
1504 mdelay(1);
1505 RFInProgressTimeOut++;
1506 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
1507 }
1508 ppsc->rfchange_inprogress = true;
1509 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags);
1510
1511 rtlpci->driver_is_goingto_unload = true;
1512 rtlpriv->cfg->ops->hw_disable(hw);
1513 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1514
1515 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
1516 ppsc->rfchange_inprogress = false;
1517 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flags);
1518
1519 rtl_pci_enable_aspm(hw);
1520}
1521
1522static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
1523 struct ieee80211_hw *hw)
1524{
1525 struct rtl_priv *rtlpriv = rtl_priv(hw);
1526 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1527 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1528 struct pci_dev *bridge_pdev = pdev->bus->self;
1529 u16 venderid;
1530 u16 deviceid;
1531 u8 revisionid;
1532 u16 irqline;
1533 u8 tmp;
1534
1535 venderid = pdev->vendor;
1536 deviceid = pdev->device;
1537 pci_read_config_byte(pdev, 0x8, &revisionid);
1538 pci_read_config_word(pdev, 0x3C, &irqline);
1539
1540 if (deviceid == RTL_PCI_8192_DID ||
1541 deviceid == RTL_PCI_0044_DID ||
1542 deviceid == RTL_PCI_0047_DID ||
1543 deviceid == RTL_PCI_8192SE_DID ||
1544 deviceid == RTL_PCI_8174_DID ||
1545 deviceid == RTL_PCI_8173_DID ||
1546 deviceid == RTL_PCI_8172_DID ||
1547 deviceid == RTL_PCI_8171_DID) {
1548 switch (revisionid) {
1549 case RTL_PCI_REVISION_ID_8192PCIE:
1550 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1551 ("8192 PCI-E is found - "
1552 "vid/did=%x/%x\n", venderid, deviceid));
1553 rtlhal->hw_type = HARDWARE_TYPE_RTL8192E;
1554 break;
1555 case RTL_PCI_REVISION_ID_8192SE:
1556 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1557 ("8192SE is found - "
1558 "vid/did=%x/%x\n", venderid, deviceid));
1559 rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
1560 break;
1561 default:
1562 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1563 ("Err: Unknown device - "
1564 "vid/did=%x/%x\n", venderid, deviceid));
1565 rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
1566 break;
1567
1568 }
1569 } else if (deviceid == RTL_PCI_8192CET_DID ||
1570 deviceid == RTL_PCI_8192CE_DID ||
1571 deviceid == RTL_PCI_8191CE_DID ||
1572 deviceid == RTL_PCI_8188CE_DID) {
1573 rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE;
1574 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1575 ("8192C PCI-E is found - "
1576 "vid/did=%x/%x\n", venderid, deviceid));
1577 } else {
1578 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1579 ("Err: Unknown device -"
1580 " vid/did=%x/%x\n", venderid, deviceid));
1581
1582 rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE;
1583 }
1584
1585 /*find bus info */
1586 pcipriv->ndis_adapter.busnumber = pdev->bus->number;
1587 pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn);
1588 pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn);
1589
1590 /*find bridge info */
1591 pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor;
1592 for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) {
1593 if (bridge_pdev->vendor == pcibridge_vendors[tmp]) {
1594 pcipriv->ndis_adapter.pcibridge_vendor = tmp;
1595 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1596 ("Pci Bridge Vendor is found index: %d\n",
1597 tmp));
1598 break;
1599 }
1600 }
1601
1602 if (pcipriv->ndis_adapter.pcibridge_vendor !=
1603 PCI_BRIDGE_VENDOR_UNKNOWN) {
1604 pcipriv->ndis_adapter.pcibridge_busnum =
1605 bridge_pdev->bus->number;
1606 pcipriv->ndis_adapter.pcibridge_devnum =
1607 PCI_SLOT(bridge_pdev->devfn);
1608 pcipriv->ndis_adapter.pcibridge_funcnum =
1609 PCI_FUNC(bridge_pdev->devfn);
1610 pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
1611 bridge_pdev->pcie_cap;
1612 pcipriv->ndis_adapter.pcicfg_addrport =
1613 (pcipriv->ndis_adapter.pcibridge_busnum << 16) |
1614 (pcipriv->ndis_adapter.pcibridge_devnum << 11) |
1615 (pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31);
1616 pcipriv->ndis_adapter.num4bytes =
1617 (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4;
1618
1619 rtl_pci_get_linkcontrol_field(hw);
1620
1621 if (pcipriv->ndis_adapter.pcibridge_vendor ==
1622 PCI_BRIDGE_VENDOR_AMD) {
1623 pcipriv->ndis_adapter.amd_l1_patch =
1624 rtl_pci_get_amd_l1_patch(hw);
1625 }
1626 }
1627
1628 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1629 ("pcidev busnumber:devnumber:funcnumber:"
1630 "vendor:link_ctl %d:%d:%d:%x:%x\n",
1631 pcipriv->ndis_adapter.busnumber,
1632 pcipriv->ndis_adapter.devnumber,
1633 pcipriv->ndis_adapter.funcnumber,
1634 pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg));
1635
1636 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1637 ("pci_bridge busnumber:devnumber:funcnumber:vendor:"
1638 "pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n",
1639 pcipriv->ndis_adapter.pcibridge_busnum,
1640 pcipriv->ndis_adapter.pcibridge_devnum,
1641 pcipriv->ndis_adapter.pcibridge_funcnum,
1642 pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor],
1643 pcipriv->ndis_adapter.pcibridge_pciehdr_offset,
1644 pcipriv->ndis_adapter.pcibridge_linkctrlreg,
1645 pcipriv->ndis_adapter.amd_l1_patch));
1646
1647 rtl_pci_parse_configuration(pdev, hw);
1648
1649 return true;
1650}
1651
1652int __devinit rtl_pci_probe(struct pci_dev *pdev,
1653 const struct pci_device_id *id)
1654{
1655 struct ieee80211_hw *hw = NULL;
1656
1657 struct rtl_priv *rtlpriv = NULL;
1658 struct rtl_pci_priv *pcipriv = NULL;
1659 struct rtl_pci *rtlpci;
1660 unsigned long pmem_start, pmem_len, pmem_flags;
1661 int err;
1662
1663 err = pci_enable_device(pdev);
1664 if (err) {
1665 RT_ASSERT(false,
1666 ("%s : Cannot enable new PCI device\n",
1667 pci_name(pdev)));
1668 return err;
1669 }
1670
1671 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
1672 if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1673 RT_ASSERT(false, ("Unable to obtain 32bit DMA "
1674 "for consistent allocations\n"));
1675 pci_disable_device(pdev);
1676 return -ENOMEM;
1677 }
1678 }
1679
1680 pci_set_master(pdev);
1681
1682 hw = ieee80211_alloc_hw(sizeof(struct rtl_pci_priv) +
1683 sizeof(struct rtl_priv), &rtl_ops);
1684 if (!hw) {
1685 RT_ASSERT(false,
1686 ("%s : ieee80211 alloc failed\n", pci_name(pdev)));
1687 err = -ENOMEM;
1688 goto fail1;
1689 }
1690
1691 SET_IEEE80211_DEV(hw, &pdev->dev);
1692 pci_set_drvdata(pdev, hw);
1693
1694 rtlpriv = hw->priv;
1695 pcipriv = (void *)rtlpriv->priv;
1696 pcipriv->dev.pdev = pdev;
1697
1698 /*
1699 *init dbgp flags before all
1700 *other functions, because we will
1701 *use it in other funtions like
1702 *RT_TRACE/RT_PRINT/RTL_PRINT_DATA
1703 *you can not use these macro
1704 *before this
1705 */
1706 rtl_dbgp_flag_init(hw);
1707
1708 /* MEM map */
1709 err = pci_request_regions(pdev, KBUILD_MODNAME);
1710 if (err) {
1711 RT_ASSERT(false, ("Can't obtain PCI resources\n"));
1712 return err;
1713 }
1714
1715 pmem_start = pci_resource_start(pdev, 2);
1716 pmem_len = pci_resource_len(pdev, 2);
1717 pmem_flags = pci_resource_flags(pdev, 2);
1718
1719 /*shared mem start */
1720 rtlpriv->io.pci_mem_start =
1721 (unsigned long)pci_iomap(pdev, 2, pmem_len);
1722 if (rtlpriv->io.pci_mem_start == 0) {
1723 RT_ASSERT(false, ("Can't map PCI mem\n"));
1724 goto fail2;
1725 }
1726
1727 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1728 ("mem mapped space: start: 0x%08lx len:%08lx "
1729 "flags:%08lx, after map:0x%08lx\n",
1730 pmem_start, pmem_len, pmem_flags,
1731 rtlpriv->io.pci_mem_start));
1732
1733 /* Disable Clk Request */
1734 pci_write_config_byte(pdev, 0x81, 0);
1735 /* leave D3 mode */
1736 pci_write_config_byte(pdev, 0x44, 0);
1737 pci_write_config_byte(pdev, 0x04, 0x06);
1738 pci_write_config_byte(pdev, 0x04, 0x07);
1739
1740 /* init cfg & intf_ops */
1741 rtlpriv->rtlhal.interface = INTF_PCI;
1742 rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
1743 rtlpriv->intf_ops = &rtl_pci_ops;
1744
1745 /* find adapter */
1746 _rtl_pci_find_adapter(pdev, hw);
1747
1748 /* Init IO handler */
1749 _rtl_pci_io_handler_init(&pdev->dev, hw);
1750
1751 /*like read eeprom and so on */
1752 rtlpriv->cfg->ops->read_eeprom_info(hw);
1753
1754 if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
1755 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1756 ("Can't init_sw_vars.\n"));
1757 goto fail3;
1758 }
1759
1760 rtlpriv->cfg->ops->init_sw_leds(hw);
1761
1762 /*aspm */
1763 rtl_pci_init_aspm(hw);
1764
1765 /* Init mac80211 sw */
1766 err = rtl_init_core(hw);
1767 if (err) {
1768 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1769 ("Can't allocate sw for mac80211.\n"));
1770 goto fail3;
1771 }
1772
1773 /* Init PCI sw */
1774 err = !rtl_pci_init(hw, pdev);
1775 if (err) {
1776 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1777 ("Failed to init PCI.\n"));
1778 goto fail3;
1779 }
1780
1781 err = ieee80211_register_hw(hw);
1782 if (err) {
1783 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1784 ("Can't register mac80211 hw.\n"));
1785 goto fail3;
1786 } else {
1787 rtlpriv->mac80211.mac80211_registered = 1;
1788 }
1789
1790 err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
1791 if (err) {
1792 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1793 ("failed to create sysfs device attributes\n"));
1794 goto fail3;
1795 }
1796
1797 /*init rfkill */
1798 rtl_init_rfkill(hw);
1799
1800 rtlpci = rtl_pcidev(pcipriv);
1801 err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
1802 IRQF_SHARED, KBUILD_MODNAME, hw);
1803 if (err) {
1804 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1805 ("%s: failed to register IRQ handler\n",
1806 wiphy_name(hw->wiphy)));
1807 goto fail3;
1808 } else {
1809 rtlpci->irq_alloc = 1;
1810 }
1811
1812 set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
1813 return 0;
1814
1815fail3:
1816 pci_set_drvdata(pdev, NULL);
1817 rtl_deinit_core(hw);
1818 _rtl_pci_io_handler_release(hw);
1819 ieee80211_free_hw(hw);
1820
1821 if (rtlpriv->io.pci_mem_start != 0)
1822 pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
1823
1824fail2:
1825 pci_release_regions(pdev);
1826
1827fail1:
1828
1829 pci_disable_device(pdev);
1830
1831 return -ENODEV;
1832
1833}
1834EXPORT_SYMBOL(rtl_pci_probe);
1835
1836void rtl_pci_disconnect(struct pci_dev *pdev)
1837{
1838 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
1839 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1840 struct rtl_priv *rtlpriv = rtl_priv(hw);
1841 struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
1842 struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
1843
1844 clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
1845
1846 sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group);
1847
1848 /*ieee80211_unregister_hw will call ops_stop */
1849 if (rtlmac->mac80211_registered == 1) {
1850 ieee80211_unregister_hw(hw);
1851 rtlmac->mac80211_registered = 0;
1852 } else {
1853 rtl_deinit_deferred_work(hw);
1854 rtlpriv->intf_ops->adapter_stop(hw);
1855 }
1856
1857 /*deinit rfkill */
1858 rtl_deinit_rfkill(hw);
1859
1860 rtl_pci_deinit(hw);
1861 rtl_deinit_core(hw);
1862 rtlpriv->cfg->ops->deinit_sw_leds(hw);
1863 _rtl_pci_io_handler_release(hw);
1864 rtlpriv->cfg->ops->deinit_sw_vars(hw);
1865
1866 if (rtlpci->irq_alloc) {
1867 free_irq(rtlpci->pdev->irq, hw);
1868 rtlpci->irq_alloc = 0;
1869 }
1870
1871 if (rtlpriv->io.pci_mem_start != 0) {
1872 pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start);
1873 pci_release_regions(pdev);
1874 }
1875
1876 pci_disable_device(pdev);
1877 pci_set_drvdata(pdev, NULL);
1878
1879 ieee80211_free_hw(hw);
1880}
1881EXPORT_SYMBOL(rtl_pci_disconnect);
1882
1883/***************************************
1884kernel pci power state define:
1885PCI_D0 ((pci_power_t __force) 0)
1886PCI_D1 ((pci_power_t __force) 1)
1887PCI_D2 ((pci_power_t __force) 2)
1888PCI_D3hot ((pci_power_t __force) 3)
1889PCI_D3cold ((pci_power_t __force) 4)
1890PCI_UNKNOWN ((pci_power_t __force) 5)
1891
1892This function is called when system
1893goes into suspend state mac80211 will
1894call rtl_mac_stop() from the mac80211
1895suspend function first, So there is
1896no need to call hw_disable here.
1897****************************************/
1898int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
1899{
1900 pci_save_state(pdev);
1901 pci_disable_device(pdev);
1902 pci_set_power_state(pdev, PCI_D3hot);
1903
1904 return 0;
1905}
1906EXPORT_SYMBOL(rtl_pci_suspend);
1907
1908int rtl_pci_resume(struct pci_dev *pdev)
1909{
1910 int ret;
1911
1912 pci_set_power_state(pdev, PCI_D0);
1913 ret = pci_enable_device(pdev);
1914 if (ret) {
1915 RT_ASSERT(false, ("ERR: <======\n"));
1916 return ret;
1917 }
1918
1919 pci_restore_state(pdev);
1920
1921 return 0;
1922}
1923EXPORT_SYMBOL(rtl_pci_resume);
1924
1925struct rtl_intf_ops rtl_pci_ops = {
1926 .adapter_start = rtl_pci_start,
1927 .adapter_stop = rtl_pci_stop,
1928 .adapter_tx = rtl_pci_tx,
1929 .reset_trx_ring = rtl_pci_reset_trx_ring,
1930
1931 .disable_aspm = rtl_pci_disable_aspm,
1932 .enable_aspm = rtl_pci_enable_aspm,
1933};
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
new file mode 100644
index 00000000000..cdde8583ad3
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -0,0 +1,302 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL_PCI_H__
31#define __RTL_PCI_H__
32
33#include <linux/pci.h>
34/*
351: MSDU packet queue,
362: Rx Command Queue
37*/
38#define RTL_PCI_RX_MPDU_QUEUE 0
39#define RTL_PCI_RX_CMD_QUEUE 1
40#define RTL_PCI_MAX_RX_QUEUE 2
41
42#define RTL_PCI_MAX_RX_COUNT 64
43#define RTL_PCI_MAX_TX_QUEUE_COUNT 9
44
45#define RT_TXDESC_NUM 128
46#define RT_TXDESC_NUM_BE_QUEUE 256
47
48#define BK_QUEUE 0
49#define BE_QUEUE 1
50#define VI_QUEUE 2
51#define VO_QUEUE 3
52#define BEACON_QUEUE 4
53#define TXCMD_QUEUE 5
54#define MGNT_QUEUE 6
55#define HIGH_QUEUE 7
56#define HCCA_QUEUE 8
57
58#define RTL_PCI_DEVICE(vend, dev, cfg) \
59 .vendor = (vend), \
60 .device = (dev), \
61 .subvendor = PCI_ANY_ID, \
62 .subdevice = PCI_ANY_ID,\
63 .driver_data = (kernel_ulong_t)&(cfg)
64
65#define INTEL_VENDOR_ID 0x8086
66#define SIS_VENDOR_ID 0x1039
67#define ATI_VENDOR_ID 0x1002
68#define ATI_DEVICE_ID 0x7914
69#define AMD_VENDOR_ID 0x1022
70
71#define PCI_MAX_BRIDGE_NUMBER 255
72#define PCI_MAX_DEVICES 32
73#define PCI_MAX_FUNCTION 8
74
75#define PCI_CONF_ADDRESS 0x0CF8 /*PCI Configuration Space Address */
76#define PCI_CONF_DATA 0x0CFC /*PCI Configuration Space Data */
77
78#define PCI_CLASS_BRIDGE_DEV 0x06
79#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04
80#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10
81#define PCI_CAP_ID_EXP 0x10
82
83#define U1DONTCARE 0xFF
84#define U2DONTCARE 0xFFFF
85#define U4DONTCARE 0xFFFFFFFF
86
87#define RTL_PCI_8192_DID 0x8192 /*8192 PCI-E */
88#define RTL_PCI_8192SE_DID 0x8192 /*8192 SE */
89#define RTL_PCI_8174_DID 0x8174 /*8192 SE */
90#define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */
91#define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */
92#define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */
93#define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */
94#define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */
95#define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */
96#define RTL_PCI_0047_DID 0x0047 /*8192e Express Card for Ceraga */
97#define RTL_PCI_700F_DID 0x700F
98#define RTL_PCI_701F_DID 0x701F
99#define RTL_PCI_DLINK_DID 0x3304
100#define RTL_PCI_8192CET_DID 0x8191 /*8192ce */
101#define RTL_PCI_8192CE_DID 0x8178 /*8192ce */
102#define RTL_PCI_8191CE_DID 0x8177 /*8192ce */
103#define RTL_PCI_8188CE_DID 0x8176 /*8192ce */
104#define RTL_PCI_8192CU_DID 0x8191 /*8192ce */
105#define RTL_PCI_8192DE_DID 0x092D /*8192ce */
106#define RTL_PCI_8192DU_DID 0x092D /*8192ce */
107
108/*8192 support 16 pages of IO registers*/
109#define RTL_MEM_MAPPED_IO_RANGE_8190PCI 0x1000
110#define RTL_MEM_MAPPED_IO_RANGE_8192PCIE 0x4000
111#define RTL_MEM_MAPPED_IO_RANGE_8192SE 0x4000
112#define RTL_MEM_MAPPED_IO_RANGE_8192CE 0x4000
113#define RTL_MEM_MAPPED_IO_RANGE_8192DE 0x4000
114
115#define RTL_PCI_REVISION_ID_8190PCI 0x00
116#define RTL_PCI_REVISION_ID_8192PCIE 0x01
117#define RTL_PCI_REVISION_ID_8192SE 0x10
118#define RTL_PCI_REVISION_ID_8192CE 0x1
119#define RTL_PCI_REVISION_ID_8192DE 0x0
120
121#define RTL_DEFAULT_HARDWARE_TYPE HARDWARE_TYPE_RTL8192CE
122
123enum pci_bridge_vendor {
124 PCI_BRIDGE_VENDOR_INTEL = 0x0, /*0b'0000,0001 */
125 PCI_BRIDGE_VENDOR_ATI, /*0b'0000,0010*/
126 PCI_BRIDGE_VENDOR_AMD, /*0b'0000,0100*/
127 PCI_BRIDGE_VENDOR_SIS, /*0b'0000,1000*/
128 PCI_BRIDGE_VENDOR_UNKNOWN, /*0b'0100,0000*/
129 PCI_BRIDGE_VENDOR_MAX,
130};
131
132struct rtl_rx_desc {
133 u32 dword[8];
134} __attribute__ ((packed));
135
136struct rtl_tx_desc {
137 u32 dword[16];
138} __attribute__ ((packed));
139
140struct rtl_tx_cmd_desc {
141 u32 dword[16];
142} __attribute__ ((packed));
143
144struct rtl8192_tx_ring {
145 struct rtl_tx_desc *desc;
146 dma_addr_t dma;
147 unsigned int idx;
148 unsigned int entries;
149 struct sk_buff_head queue;
150};
151
152struct rtl8192_rx_ring {
153 struct rtl_rx_desc *desc;
154 dma_addr_t dma;
155 unsigned int idx;
156 struct sk_buff *rx_buf[RTL_PCI_MAX_RX_COUNT];
157};
158
159struct rtl_pci {
160 struct pci_dev *pdev;
161
162 bool driver_is_goingto_unload;
163 bool up_first_time;
164 bool being_init_adapter;
165 bool irq_enabled;
166
167 /*Tx */
168 struct rtl8192_tx_ring tx_ring[RTL_PCI_MAX_TX_QUEUE_COUNT];
169 int txringcount[RTL_PCI_MAX_TX_QUEUE_COUNT];
170 u32 transmit_config;
171
172 /*Rx */
173 struct rtl8192_rx_ring rx_ring[RTL_PCI_MAX_RX_QUEUE];
174 int rxringcount;
175 u16 rxbuffersize;
176 u32 receive_config;
177
178 /*irq */
179 u8 irq_alloc;
180 u32 irq_mask[2];
181
182 /*Bcn control register setting */
183 u32 reg_bcn_ctrl_val;
184
185 /*ASPM*/ u8 const_pci_aspm;
186 u8 const_amdpci_aspm;
187 u8 const_hwsw_rfoff_d3;
188 u8 const_support_pciaspm;
189 /*pci-e bridge */
190 u8 const_hostpci_aspm_setting;
191 /*pci-e device */
192 u8 const_devicepci_aspm_setting;
193 /*If it supports ASPM, Offset[560h] = 0x40,
194 otherwise Offset[560h] = 0x00. */
195 bool b_support_aspm;
196 bool b_support_backdoor;
197
198 /*QOS & EDCA */
199 enum acm_method acm_method;
200};
201
202struct mp_adapter {
203 u8 linkctrl_reg;
204
205 u8 busnumber;
206 u8 devnumber;
207 u8 funcnumber;
208
209 u8 pcibridge_busnum;
210 u8 pcibridge_devnum;
211 u8 pcibridge_funcnum;
212
213 u8 pcibridge_vendor;
214 u16 pcibridge_vendorid;
215 u16 pcibridge_deviceid;
216
217 u32 pcicfg_addrport;
218 u8 num4bytes;
219
220 u8 pcibridge_pciehdr_offset;
221 u8 pcibridge_linkctrlreg;
222
223 bool amd_l1_patch;
224};
225
226struct rtl_pci_priv {
227 struct rtl_pci dev;
228 struct mp_adapter ndis_adapter;
229 struct rtl_led_ctl ledctl;
230};
231
232#define rtl_pcipriv(hw) (((struct rtl_pci_priv *)(rtl_priv(hw))->priv))
233#define rtl_pcidev(pcipriv) (&((pcipriv)->dev))
234
235int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw);
236
237extern struct rtl_intf_ops rtl_pci_ops;
238
239int __devinit rtl_pci_probe(struct pci_dev *pdev,
240 const struct pci_device_id *id);
241void rtl_pci_disconnect(struct pci_dev *pdev);
242int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
243int rtl_pci_resume(struct pci_dev *pdev);
244
245static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
246{
247 return 0xff & readb((u8 *) rtlpriv->io.pci_mem_start + addr);
248}
249
250static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr)
251{
252 return readw((u8 *) rtlpriv->io.pci_mem_start + addr);
253}
254
255static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr)
256{
257 return readl((u8 *) rtlpriv->io.pci_mem_start + addr);
258}
259
260static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val)
261{
262 writeb(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
263}
264
265static inline void pci_write16_async(struct rtl_priv *rtlpriv,
266 u32 addr, u16 val)
267{
268 writew(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
269}
270
271static inline void pci_write32_async(struct rtl_priv *rtlpriv,
272 u32 addr, u32 val)
273{
274 writel(val, (u8 *) rtlpriv->io.pci_mem_start + addr);
275}
276
277static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val)
278{
279 outl(val, port);
280}
281
282static inline void rtl_pci_raw_write_port_uchar(u32 port, u8 val)
283{
284 outb(val, port);
285}
286
287static inline void rtl_pci_raw_read_port_uchar(u32 port, u8 *pval)
288{
289 *pval = inb(port);
290}
291
292static inline void rtl_pci_raw_read_port_ushort(u32 port, u16 *pval)
293{
294 *pval = inw(port);
295}
296
297static inline void rtl_pci_raw_read_port_ulong(u32 port, u32 *pval)
298{
299 *pval = inl(port);
300}
301
302#endif
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c
new file mode 100644
index 00000000000..fd77cd508f5
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -0,0 +1,492 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "wifi.h"
31#include "base.h"
32#include "ps.h"
33
34bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
35{
36 struct rtl_priv *rtlpriv = rtl_priv(hw);
37 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
38 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
39 bool init_status = true;
40
41 /*<1> reset trx ring */
42 if (rtlhal->interface == INTF_PCI)
43 rtlpriv->intf_ops->reset_trx_ring(hw);
44
45 if (is_hal_stop(rtlhal))
46 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
47 ("Driver is already down!\n"));
48
49 /*<2> Enable Adapter */
50 rtlpriv->cfg->ops->hw_init(hw);
51 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
52 /*init_status = false; */
53
54 /*<3> Enable Interrupt */
55 rtlpriv->cfg->ops->enable_interrupt(hw);
56
57 /*<enable timer> */
58 rtl_watch_dog_timer_callback((unsigned long)hw);
59
60 return init_status;
61}
62EXPORT_SYMBOL(rtl_ps_enable_nic);
63
64bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
65{
66 bool status = true;
67 struct rtl_priv *rtlpriv = rtl_priv(hw);
68
69 /*<1> Stop all timer */
70 rtl_deinit_deferred_work(hw);
71
72 /*<2> Disable Interrupt */
73 rtlpriv->cfg->ops->disable_interrupt(hw);
74
75 /*<3> Disable Adapter */
76 rtlpriv->cfg->ops->hw_disable(hw);
77
78 return status;
79}
80EXPORT_SYMBOL(rtl_ps_disable_nic);
81
82bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
83 enum rf_pwrstate state_toset,
84 u32 changesource, bool protect_or_not)
85{
86 struct rtl_priv *rtlpriv = rtl_priv(hw);
87 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
88 enum rf_pwrstate rtstate;
89 bool b_actionallowed = false;
90 u16 rfwait_cnt = 0;
91 unsigned long flag;
92
93 /*protect_or_not = true; */
94
95 if (protect_or_not)
96 goto no_protect;
97
98 /*
99 *Only one thread can change
100 *the RF state at one time, and others
101 *should wait to be executed.
102 */
103 while (true) {
104 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
105 if (ppsc->rfchange_inprogress) {
106 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock,
107 flag);
108
109 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
110 ("RF Change in progress!"
111 "Wait to set..state_toset(%d).\n",
112 state_toset));
113
114 /* Set RF after the previous action is done. */
115 while (ppsc->rfchange_inprogress) {
116 rfwait_cnt++;
117 mdelay(1);
118
119 /*
120 *Wait too long, return false to avoid
121 *to be stuck here.
122 */
123 if (rfwait_cnt > 100)
124 return false;
125 }
126 } else {
127 ppsc->rfchange_inprogress = true;
128 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock,
129 flag);
130 break;
131 }
132 }
133
134no_protect:
135 rtstate = ppsc->rfpwr_state;
136
137 switch (state_toset) {
138 case ERFON:
139 ppsc->rfoff_reason &= (~changesource);
140
141 if ((changesource == RF_CHANGE_BY_HW) &&
142 (ppsc->b_hwradiooff == true)) {
143 ppsc->b_hwradiooff = false;
144 }
145
146 if (!ppsc->rfoff_reason) {
147 ppsc->rfoff_reason = 0;
148 b_actionallowed = true;
149 }
150
151 break;
152
153 case ERFOFF:
154
155 if ((changesource == RF_CHANGE_BY_HW)
156 && (ppsc->b_hwradiooff == false)) {
157 ppsc->b_hwradiooff = true;
158 }
159
160 ppsc->rfoff_reason |= changesource;
161 b_actionallowed = true;
162 break;
163
164 case ERFSLEEP:
165 ppsc->rfoff_reason |= changesource;
166 b_actionallowed = true;
167 break;
168
169 default:
170 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
171 ("switch case not process\n"));
172 break;
173 }
174
175 if (b_actionallowed)
176 rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset);
177
178 if (!protect_or_not) {
179 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
180 ppsc->rfchange_inprogress = false;
181 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
182 }
183
184 return b_actionallowed;
185}
186EXPORT_SYMBOL(rtl_ps_set_rf_state);
187
188static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
189{
190 struct rtl_priv *rtlpriv = rtl_priv(hw);
191 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
192 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
193
194 ppsc->b_swrf_processing = true;
195
196 if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) {
197 if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
198 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM) &&
199 rtlhal->interface == INTF_PCI) {
200 rtlpriv->intf_ops->disable_aspm(hw);
201 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
202 }
203 }
204
205 rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate,
206 RF_CHANGE_BY_IPS, false);
207
208 if (ppsc->inactive_pwrstate == ERFOFF &&
209 rtlhal->interface == INTF_PCI) {
210 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
211 rtlpriv->intf_ops->enable_aspm(hw);
212 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
213 }
214 }
215
216 ppsc->b_swrf_processing = false;
217}
218
219void rtl_ips_nic_off_wq_callback(void *data)
220{
221 struct rtl_works *rtlworks =
222 container_of_dwork_rtl(data, struct rtl_works, ips_nic_off_wq);
223 struct ieee80211_hw *hw = rtlworks->hw;
224 struct rtl_priv *rtlpriv = rtl_priv(hw);
225 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
226 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
227 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
228 enum rf_pwrstate rtstate;
229
230 if (mac->opmode != NL80211_IFTYPE_STATION) {
231 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
232 ("not station return\n"));
233 return;
234 }
235
236 if (is_hal_stop(rtlhal))
237 return;
238
239 if (rtlpriv->sec.being_setkey)
240 return;
241
242 if (ppsc->b_inactiveps) {
243 rtstate = ppsc->rfpwr_state;
244
245 /*
246 *Do not enter IPS in the following conditions:
247 *(1) RF is already OFF or Sleep
248 *(2) b_swrf_processing (indicates the IPS is still under going)
249 *(3) Connectted (only disconnected can trigger IPS)
250 *(4) IBSS (send Beacon)
251 *(5) AP mode (send Beacon)
252 *(6) monitor mode (rcv packet)
253 */
254
255 if (rtstate == ERFON &&
256 !ppsc->b_swrf_processing &&
257 (mac->link_state == MAC80211_NOLINK) &&
258 !mac->act_scanning) {
259 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
260 ("IPSEnter(): Turn off RF.\n"));
261
262 ppsc->inactive_pwrstate = ERFOFF;
263 ppsc->b_in_powersavemode = true;
264
265 /*rtl_pci_reset_trx_ring(hw); */
266 _rtl_ps_inactive_ps(hw);
267 }
268 }
269}
270
271void rtl_ips_nic_off(struct ieee80211_hw *hw)
272{
273 struct rtl_priv *rtlpriv = rtl_priv(hw);
274
275 /*
276 *because when link with ap, mac80211 will ask us
277 *to disable nic quickly after scan before linking,
278 *this will cause link failed, so we delay 100ms here
279 */
280 queue_delayed_work(rtlpriv->works.rtl_wq,
281 &rtlpriv->works.ips_nic_off_wq, MSECS(100));
282}
283
284void rtl_ips_nic_on(struct ieee80211_hw *hw)
285{
286 struct rtl_priv *rtlpriv = rtl_priv(hw);
287 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
288 enum rf_pwrstate rtstate;
289
290 down(&rtlpriv->locks.ips_sem);
291
292 if (ppsc->b_inactiveps) {
293 rtstate = ppsc->rfpwr_state;
294
295 if (rtstate != ERFON &&
296 !ppsc->b_swrf_processing &&
297 ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) {
298
299 ppsc->inactive_pwrstate = ERFON;
300 ppsc->b_in_powersavemode = false;
301
302 _rtl_ps_inactive_ps(hw);
303 }
304 }
305
306 up(&rtlpriv->locks.ips_sem);
307}
308
309/*for FW LPS*/
310
311/*
312 *Determine if we can set Fw into PS mode
313 *in current condition.Return TRUE if it
314 *can enter PS mode.
315 */
316static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw)
317{
318 struct rtl_priv *rtlpriv = rtl_priv(hw);
319 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
320 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
321 u32 ps_timediff;
322
323 ps_timediff = jiffies_to_msecs(jiffies -
324 ppsc->last_delaylps_stamp_jiffies);
325
326 if (ps_timediff < 2000) {
327 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
328 ("Delay enter Fw LPS for DHCP, ARP,"
329 " or EAPOL exchanging state.\n"));
330 return false;
331 }
332
333 if (mac->link_state != MAC80211_LINKED)
334 return false;
335
336 if (mac->opmode == NL80211_IFTYPE_ADHOC)
337 return false;
338
339 return true;
340}
341
342/* Change current and default preamble mode.*/
343static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
344{
345 struct rtl_priv *rtlpriv = rtl_priv(hw);
346 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
347 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
348 u8 rpwm_val, fw_pwrmode;
349
350 if (mac->opmode == NL80211_IFTYPE_ADHOC)
351 return;
352
353 if (mac->link_state != MAC80211_LINKED)
354 return;
355
356 if (ppsc->dot11_psmode == rt_psmode)
357 return;
358
359 /* Update power save mode configured. */
360 ppsc->dot11_psmode = rt_psmode;
361
362 /*
363 *<FW control LPS>
364 *1. Enter PS mode
365 * Set RPWM to Fw to turn RF off and send H2C fw_pwrmode
366 * cmd to set Fw into PS mode.
367 *2. Leave PS mode
368 * Send H2C fw_pwrmode cmd to Fw to set Fw into Active
369 * mode and set RPWM to turn RF on.
370 */
371
372 if ((ppsc->b_fwctrl_lps) && (ppsc->b_leisure_ps) &&
373 ppsc->report_linked) {
374 bool b_fw_current_inps;
375 if (ppsc->dot11_psmode == EACTIVE) {
376 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
377 ("FW LPS leave ps_mode:%x\n",
378 FW_PS_ACTIVE_MODE));
379
380 rpwm_val = 0x0C; /* RF on */
381 fw_pwrmode = FW_PS_ACTIVE_MODE;
382 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
383 (u8 *) (&rpwm_val));
384 rtlpriv->cfg->ops->set_hw_reg(hw,
385 HW_VAR_H2C_FW_PWRMODE,
386 (u8 *) (&fw_pwrmode));
387 b_fw_current_inps = false;
388
389 rtlpriv->cfg->ops->set_hw_reg(hw,
390 HW_VAR_FW_PSMODE_STATUS,
391 (u8 *) (&b_fw_current_inps));
392
393 } else {
394 if (rtl_get_fwlps_doze(hw)) {
395 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
396 ("FW LPS enter ps_mode:%x\n",
397 ppsc->fwctrl_psmode));
398
399 rpwm_val = 0x02; /* RF off */
400 b_fw_current_inps = true;
401 rtlpriv->cfg->ops->set_hw_reg(hw,
402 HW_VAR_FW_PSMODE_STATUS,
403 (u8 *) (&b_fw_current_inps));
404 rtlpriv->cfg->ops->set_hw_reg(hw,
405 HW_VAR_H2C_FW_PWRMODE,
406 (u8 *) (&ppsc->fwctrl_psmode));
407
408 rtlpriv->cfg->ops->set_hw_reg(hw,
409 HW_VAR_SET_RPWM,
410 (u8 *) (&rpwm_val));
411 } else {
412 /* Reset the power save related parameters. */
413 ppsc->dot11_psmode = EACTIVE;
414 }
415 }
416 }
417}
418
419/*Enter the leisure power save mode.*/
420void rtl_lps_enter(struct ieee80211_hw *hw)
421{
422 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
423 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
424 struct rtl_priv *rtlpriv = rtl_priv(hw);
425 unsigned long flag;
426
427 if (!(ppsc->b_fwctrl_lps && ppsc->b_leisure_ps))
428 return;
429
430 if (rtlpriv->sec.being_setkey)
431 return;
432
433 if (rtlpriv->link_info.b_busytraffic)
434 return;
435
436 /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
437 if (mac->cnt_after_linked < 5)
438 return;
439
440 if (mac->opmode == NL80211_IFTYPE_ADHOC)
441 return;
442
443 if (mac->link_state != MAC80211_LINKED)
444 return;
445
446 spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
447
448 if (ppsc->b_leisure_ps) {
449 /* Idle for a while if we connect to AP a while ago. */
450 if (mac->cnt_after_linked >= 2) {
451 if (ppsc->dot11_psmode == EACTIVE) {
452 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
453 ("Enter 802.11 power save mode...\n"));
454
455 rtl_lps_set_psmode(hw, EAUTOPS);
456 }
457 }
458 }
459 spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
460}
461
462/*Leave the leisure power save mode.*/
463void rtl_lps_leave(struct ieee80211_hw *hw)
464{
465 struct rtl_priv *rtlpriv = rtl_priv(hw);
466 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
467 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
468 unsigned long flag;
469
470 spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
471
472 if (ppsc->b_fwctrl_lps && ppsc->b_leisure_ps) {
473 if (ppsc->dot11_psmode != EACTIVE) {
474
475 /*FIX ME */
476 rtlpriv->cfg->ops->enable_interrupt(hw);
477
478 if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
479 RT_IN_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM) &&
480 rtlhal->interface == INTF_PCI) {
481 rtlpriv->intf_ops->disable_aspm(hw);
482 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM);
483 }
484
485 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
486 ("Busy Traffic,Leave 802.11 power save..\n"));
487
488 rtl_lps_set_psmode(hw, EACTIVE);
489 }
490 }
491 spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
492}
diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h
new file mode 100644
index 00000000000..ae56da801a2
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/ps.h
@@ -0,0 +1,43 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __REALTEK_RTL_PCI_PS_H__
31#define __REALTEK_RTL_PCI_PS_H__
32
33bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
34 enum rf_pwrstate state_toset, u32 changesource,
35 bool protect_or_not);
36bool rtl_ps_enable_nic(struct ieee80211_hw *hw);
37bool rtl_ps_disable_nic(struct ieee80211_hw *hw);
38void rtl_ips_nic_off(struct ieee80211_hw *hw);
39void rtl_ips_nic_on(struct ieee80211_hw *hw);
40void rtl_ips_nic_off_wq_callback(void *data);
41void rtl_lps_enter(struct ieee80211_hw *hw);
42void rtl_lps_leave(struct ieee80211_hw *hw);
43#endif
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c
new file mode 100644
index 00000000000..904b8fd01f6
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rc.c
@@ -0,0 +1,329 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "wifi.h"
31#include "base.h"
32#include "rc.h"
33
34/*
35 *Finds the highest rate index we can use
36 *if skb is special data like DHCP/EAPOL, we set should
37 *it to lowest rate CCK_1M, otherwise we set rate to
38 *CCK11M or OFDM_54M based on wireless mode.
39 */
40static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
41 struct sk_buff *skb, bool not_data)
42{
43 struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
44
45 /*
46 *mgt use 1M, although we have check it
47 *before this function use rate_control_send_low,
48 *we still check it here
49 */
50 if (not_data)
51 return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
52
53 /*
54 *this rate is no use for true rate, firmware
55 *will control rate at all it just used for
56 *1.show in iwconfig in B/G mode
57 *2.in rtl_get_tcb_desc when we check rate is
58 * 1M we will not use FW rate but user rate.
59 */
60 if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true)) {
61 return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
62 } else {
63 if (rtlmac->mode == WIRELESS_MODE_B)
64 return rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
65 else
66 return rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
67 }
68}
69
70static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv,
71 struct ieee80211_tx_rate *rate,
72 struct ieee80211_tx_rate_control *txrc,
73 u8 tries, u8 rix, int rtsctsenable,
74 bool not_data)
75{
76 struct rtl_mac *mac = rtl_mac(rtlpriv);
77
78 rate->count = tries;
79 rate->idx = (rix > 0x2) ? rix : 0x2;
80
81 if (!not_data) {
82 if (txrc->short_preamble)
83 rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
84 if (mac->bw_40)
85 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
86 if (mac->sgi_20 || mac->sgi_40)
87 rate->flags |= IEEE80211_TX_RC_SHORT_GI;
88 if (mac->ht_enable)
89 rate->flags |= IEEE80211_TX_RC_MCS;
90 }
91}
92
93static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta,
94 void *priv_sta, struct ieee80211_tx_rate_control *txrc)
95{
96 struct rtl_priv *rtlpriv = ppriv;
97 struct sk_buff *skb = txrc->skb;
98 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
99 struct ieee80211_tx_rate *rates = tx_info->control.rates;
100 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
101 __le16 fc = hdr->frame_control;
102 u8 try_per_rate, i, rix;
103 bool not_data = !ieee80211_is_data(fc);
104
105 if (rate_control_send_low(sta, priv_sta, txrc))
106 return;
107
108 rix = _rtl_rc_get_highest_rix(rtlpriv, skb, not_data);
109
110 try_per_rate = 1;
111 _rtl_rc_rate_set_series(rtlpriv, &rates[0], txrc,
112 try_per_rate, rix, 1, not_data);
113
114 if (!not_data) {
115 for (i = 1; i < 4; i++)
116 _rtl_rc_rate_set_series(rtlpriv, &rates[i],
117 txrc, i, (rix - i), 1,
118 not_data);
119 }
120}
121
122static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, u16 tid)
123{
124 struct rtl_mac *mac = rtl_mac(rtlpriv);
125
126 if (mac->act_scanning)
127 return false;
128
129 if (mac->cnt_after_linked < 3)
130 return false;
131
132 if (mac->tids[tid].agg.agg_state == RTL_AGG_OFF)
133 return true;
134
135 return false;
136}
137
138/*mac80211 Rate Control callbacks*/
139static void rtl_tx_status(void *ppriv,
140 struct ieee80211_supported_band *sband,
141 struct ieee80211_sta *sta, void *priv_sta,
142 struct sk_buff *skb)
143{
144 struct rtl_priv *rtlpriv = ppriv;
145 struct rtl_mac *mac = rtl_mac(rtlpriv);
146 struct ieee80211_hdr *hdr;
147 __le16 fc;
148
149 hdr = (struct ieee80211_hdr *)skb->data;
150 fc = hdr->frame_control;
151
152 if (!priv_sta || !ieee80211_is_data(fc))
153 return;
154
155 if (rtl_is_special_data(mac->hw, skb, true))
156 return;
157
158 if (is_multicast_ether_addr(ieee80211_get_DA(hdr))
159 || is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
160 return;
161
162 /* Check if aggregation has to be enabled for this tid */
163 if (conf_is_ht(&mac->hw->conf) &&
164 !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
165 if (ieee80211_is_data_qos(fc)) {
166 u8 *qc, tid;
167
168 qc = ieee80211_get_qos_ctl(hdr);
169 tid = qc[0] & 0xf;
170
171 if (_rtl_tx_aggr_check(rtlpriv, tid))
172 ieee80211_start_tx_ba_session(sta, tid);
173 }
174 }
175}
176
177static void rtl_rate_init(void *ppriv,
178 struct ieee80211_supported_band *sband,
179 struct ieee80211_sta *sta, void *priv_sta)
180{
181 struct rtl_priv *rtlpriv = ppriv;
182 struct rtl_mac *mac = rtl_mac(rtlpriv);
183 u8 is_ht = conf_is_ht(&mac->hw->conf);
184
185 if ((mac->opmode == NL80211_IFTYPE_STATION) ||
186 (mac->opmode == NL80211_IFTYPE_MESH_POINT) ||
187 (mac->opmode == NL80211_IFTYPE_ADHOC)) {
188
189 switch (sband->band) {
190 case IEEE80211_BAND_2GHZ:
191 rtlpriv->rate_priv->cur_ratetab_idx =
192 RATR_INX_WIRELESS_G;
193 if (is_ht)
194 rtlpriv->rate_priv->cur_ratetab_idx =
195 RATR_INX_WIRELESS_NGB;
196 break;
197 case IEEE80211_BAND_5GHZ:
198 rtlpriv->rate_priv->cur_ratetab_idx =
199 RATR_INX_WIRELESS_A;
200 if (is_ht)
201 rtlpriv->rate_priv->cur_ratetab_idx =
202 RATR_INX_WIRELESS_NGB;
203 break;
204 default:
205 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
206 ("Invalid band\n"));
207 rtlpriv->rate_priv->cur_ratetab_idx =
208 RATR_INX_WIRELESS_NGB;
209 break;
210 }
211
212 RT_TRACE(rtlpriv, COMP_RATE, DBG_DMESG,
213 ("Choosing rate table index: %d\n",
214 rtlpriv->rate_priv->cur_ratetab_idx));
215
216 }
217
218}
219
220static void rtl_rate_update(void *ppriv,
221 struct ieee80211_supported_band *sband,
222 struct ieee80211_sta *sta, void *priv_sta,
223 u32 changed,
224 enum nl80211_channel_type oper_chan_type)
225{
226 struct rtl_priv *rtlpriv = ppriv;
227 struct rtl_mac *mac = rtl_mac(rtlpriv);
228 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
229 bool oper_cw40 = false, oper_sgi40;
230 bool local_cw40 = mac->bw_40;
231 bool local_sgi40 = mac->sgi_40;
232 u8 is_ht = conf_is_ht(&mac->hw->conf);
233
234 if (changed & IEEE80211_RC_HT_CHANGED) {
235 if (mac->opmode != NL80211_IFTYPE_STATION)
236 return;
237
238 if (rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
239 rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
240 oper_cw40 = true;
241
242 oper_sgi40 = mac->sgi_40;
243
244 if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
245 switch (sband->band) {
246 case IEEE80211_BAND_2GHZ:
247 rtlpriv->rate_priv->cur_ratetab_idx =
248 RATR_INX_WIRELESS_G;
249 if (is_ht)
250 rtlpriv->rate_priv->cur_ratetab_idx =
251 RATR_INX_WIRELESS_NGB;
252 break;
253 case IEEE80211_BAND_5GHZ:
254 rtlpriv->rate_priv->cur_ratetab_idx =
255 RATR_INX_WIRELESS_A;
256 if (is_ht)
257 rtlpriv->rate_priv->cur_ratetab_idx =
258 RATR_INX_WIRELESS_NGB;
259 break;
260 default:
261 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
262 ("Invalid band\n"));
263 rtlpriv->rate_priv->cur_ratetab_idx =
264 RATR_INX_WIRELESS_NGB;
265 break;
266 }
267 }
268 }
269}
270
271static void *rtl_rate_alloc(struct ieee80211_hw *hw,
272 struct dentry *debugfsdir)
273{
274 struct rtl_priv *rtlpriv = rtl_priv(hw);
275 return rtlpriv;
276}
277
278static void rtl_rate_free(void *rtlpriv)
279{
280 return;
281}
282
283static void *rtl_rate_alloc_sta(void *ppriv,
284 struct ieee80211_sta *sta, gfp_t gfp)
285{
286 struct rtl_priv *rtlpriv = ppriv;
287 struct rtl_rate_priv *rate_priv;
288
289 rate_priv = kzalloc(sizeof(struct rtl_rate_priv), gfp);
290 if (!rate_priv) {
291 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
292 ("Unable to allocate private rc structure\n"));
293 return NULL;
294 }
295
296 rtlpriv->rate_priv = rate_priv;
297
298 return rate_priv;
299}
300
301static void rtl_rate_free_sta(void *rtlpriv,
302 struct ieee80211_sta *sta, void *priv_sta)
303{
304 struct rtl_rate_priv *rate_priv = priv_sta;
305 kfree(rate_priv);
306}
307
308static struct rate_control_ops rtl_rate_ops = {
309 .module = NULL,
310 .name = "rtl_rc",
311 .alloc = rtl_rate_alloc,
312 .free = rtl_rate_free,
313 .alloc_sta = rtl_rate_alloc_sta,
314 .free_sta = rtl_rate_free_sta,
315 .rate_init = rtl_rate_init,
316 .rate_update = rtl_rate_update,
317 .tx_status = rtl_tx_status,
318 .get_rate = rtl_get_rate,
319};
320
321int rtl_rate_control_register(void)
322{
323 return ieee80211_rate_control_register(&rtl_rate_ops);
324}
325
326void rtl_rate_control_unregister(void)
327{
328 ieee80211_rate_control_unregister(&rtl_rate_ops);
329}
diff --git a/drivers/net/wireless/rtlwifi/rc.h b/drivers/net/wireless/rtlwifi/rc.h
new file mode 100644
index 00000000000..b4667c035f0
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rc.h
@@ -0,0 +1,40 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL_RC_H__
31#define __RTL_RC_H__
32
33struct rtl_rate_priv {
34 u8 cur_ratetab_idx;
35 u8 ht_cap;
36};
37
38int rtl_rate_control_register(void);
39void rtl_rate_control_unregister(void);
40#endif
diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c
new file mode 100644
index 00000000000..3336ca999df
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/regd.c
@@ -0,0 +1,400 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "wifi.h"
31#include "regd.h"
32
33static struct country_code_to_enum_rd allCountries[] = {
34 {COUNTRY_CODE_FCC, "US"},
35 {COUNTRY_CODE_IC, "US"},
36 {COUNTRY_CODE_ETSI, "EC"},
37 {COUNTRY_CODE_SPAIN, "EC"},
38 {COUNTRY_CODE_FRANCE, "EC"},
39 {COUNTRY_CODE_MKK, "JP"},
40 {COUNTRY_CODE_MKK1, "JP"},
41 {COUNTRY_CODE_ISRAEL, "EC"},
42 {COUNTRY_CODE_TELEC, "JP"},
43 {COUNTRY_CODE_MIC, "JP"},
44 {COUNTRY_CODE_GLOBAL_DOMAIN, "JP"},
45 {COUNTRY_CODE_WORLD_WIDE_13, "EC"},
46 {COUNTRY_CODE_TELEC_NETGEAR, "EC"},
47};
48
49/*
50 *Only these channels all allow active
51 *scan on all world regulatory domains
52 */
53#define RTL819x_2GHZ_CH01_11 \
54 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
55
56/*
57 *We enable active scan on these a case
58 *by case basis by regulatory domain
59 */
60#define RTL819x_2GHZ_CH12_13 \
61 REG_RULE(2467-10, 2472+10, 40, 0, 20,\
62 NL80211_RRF_PASSIVE_SCAN)
63
64#define RTL819x_2GHZ_CH14 \
65 REG_RULE(2484-10, 2484+10, 40, 0, 20, \
66 NL80211_RRF_PASSIVE_SCAN | \
67 NL80211_RRF_NO_OFDM)
68
69static const struct ieee80211_regdomain rtl_regdom_11 = {
70 .n_reg_rules = 1,
71 .alpha2 = "99",
72 .reg_rules = {
73 RTL819x_2GHZ_CH01_11,
74 }
75};
76
77static const struct ieee80211_regdomain rtl_regdom_global = {
78 .n_reg_rules = 3,
79 .alpha2 = "99",
80 .reg_rules = {
81 RTL819x_2GHZ_CH01_11,
82 RTL819x_2GHZ_CH12_13,
83 RTL819x_2GHZ_CH14,
84 }
85};
86
87static const struct ieee80211_regdomain rtl_regdom_world = {
88 .n_reg_rules = 2,
89 .alpha2 = "99",
90 .reg_rules = {
91 RTL819x_2GHZ_CH01_11,
92 RTL819x_2GHZ_CH12_13,
93 }
94};
95
96static bool _rtl_is_radar_freq(u16 center_freq)
97{
98 return (center_freq >= 5260 && center_freq <= 5700);
99}
100
101static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
102 enum nl80211_reg_initiator initiator)
103{
104 enum ieee80211_band band;
105 struct ieee80211_supported_band *sband;
106 const struct ieee80211_reg_rule *reg_rule;
107 struct ieee80211_channel *ch;
108 unsigned int i;
109 u32 bandwidth = 0;
110 int r;
111
112 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
113
114 if (!wiphy->bands[band])
115 continue;
116
117 sband = wiphy->bands[band];
118
119 for (i = 0; i < sband->n_channels; i++) {
120 ch = &sband->channels[i];
121 if (_rtl_is_radar_freq(ch->center_freq) ||
122 (ch->flags & IEEE80211_CHAN_RADAR))
123 continue;
124 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
125 r = freq_reg_info(wiphy, ch->center_freq,
126 bandwidth, &reg_rule);
127 if (r)
128 continue;
129
130 /*
131 *If 11d had a rule for this channel ensure
132 *we enable adhoc/beaconing if it allows us to
133 *use it. Note that we would have disabled it
134 *by applying our static world regdomain by
135 *default during init, prior to calling our
136 *regulatory_hint().
137 */
138
139 if (!(reg_rule->flags & NL80211_RRF_NO_IBSS))
140 ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
141 if (!(reg_rule->
142 flags & NL80211_RRF_PASSIVE_SCAN))
143 ch->flags &=
144 ~IEEE80211_CHAN_PASSIVE_SCAN;
145 } else {
146 if (ch->beacon_found)
147 ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
148 IEEE80211_CHAN_PASSIVE_SCAN);
149 }
150 }
151 }
152}
153
154/* Allows active scan scan on Ch 12 and 13 */
155static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
156 enum nl80211_reg_initiator
157 initiator)
158{
159 struct ieee80211_supported_band *sband;
160 struct ieee80211_channel *ch;
161 const struct ieee80211_reg_rule *reg_rule;
162 u32 bandwidth = 0;
163 int r;
164
165 sband = wiphy->bands[IEEE80211_BAND_2GHZ];
166
167 /*
168 *If no country IE has been received always enable active scan
169 *on these channels. This is only done for specific regulatory SKUs
170 */
171 if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
172 ch = &sband->channels[11]; /* CH 12 */
173 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
174 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
175 ch = &sband->channels[12]; /* CH 13 */
176 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
177 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
178 return;
179 }
180
181 /*
182 *If a country IE has been recieved check its rule for this
183 *channel first before enabling active scan. The passive scan
184 *would have been enforced by the initial processing of our
185 *custom regulatory domain.
186 */
187
188 ch = &sband->channels[11]; /* CH 12 */
189 r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
190 if (!r) {
191 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
192 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
193 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
194 }
195
196 ch = &sband->channels[12]; /* CH 13 */
197 r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
198 if (!r) {
199 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
200 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
201 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
202 }
203}
204
205/*
206 *Always apply Radar/DFS rules on
207 *freq range 5260 MHz - 5700 MHz
208 */
209static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy)
210{
211 struct ieee80211_supported_band *sband;
212 struct ieee80211_channel *ch;
213 unsigned int i;
214
215 if (!wiphy->bands[IEEE80211_BAND_5GHZ])
216 return;
217
218 sband = wiphy->bands[IEEE80211_BAND_5GHZ];
219
220 for (i = 0; i < sband->n_channels; i++) {
221 ch = &sband->channels[i];
222 if (!_rtl_is_radar_freq(ch->center_freq))
223 continue;
224
225 /*
226 *We always enable radar detection/DFS on this
227 *frequency range. Additionally we also apply on
228 *this frequency range:
229 *- If STA mode does not yet have DFS supports disable
230 * active scanning
231 *- If adhoc mode does not support DFS yet then disable
232 * adhoc in the frequency.
233 *- If AP mode does not yet support radar detection/DFS
234 *do not allow AP mode
235 */
236 if (!(ch->flags & IEEE80211_CHAN_DISABLED))
237 ch->flags |= IEEE80211_CHAN_RADAR |
238 IEEE80211_CHAN_NO_IBSS |
239 IEEE80211_CHAN_PASSIVE_SCAN;
240 }
241}
242
243static void _rtl_reg_apply_world_flags(struct wiphy *wiphy,
244 enum nl80211_reg_initiator initiator,
245 struct rtl_regulatory *reg)
246{
247 _rtl_reg_apply_beaconing_flags(wiphy, initiator);
248 _rtl_reg_apply_active_scan_flags(wiphy, initiator);
249 return;
250}
251
252static void _rtl_dump_channel_map(struct wiphy *wiphy)
253{
254 enum ieee80211_band band;
255 struct ieee80211_supported_band *sband;
256 struct ieee80211_channel *ch;
257 unsigned int i;
258
259 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
260 if (!wiphy->bands[band])
261 continue;
262 sband = wiphy->bands[band];
263 for (i = 0; i < sband->n_channels; i++)
264 ch = &sband->channels[i];
265 }
266}
267
268static int _rtl_reg_notifier_apply(struct wiphy *wiphy,
269 struct regulatory_request *request,
270 struct rtl_regulatory *reg)
271{
272 /* We always apply this */
273 _rtl_reg_apply_radar_flags(wiphy);
274
275 switch (request->initiator) {
276 case NL80211_REGDOM_SET_BY_DRIVER:
277 case NL80211_REGDOM_SET_BY_CORE:
278 case NL80211_REGDOM_SET_BY_USER:
279 break;
280 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
281 _rtl_reg_apply_world_flags(wiphy, request->initiator, reg);
282 break;
283 }
284
285 _rtl_dump_channel_map(wiphy);
286
287 return 0;
288}
289
290static const struct ieee80211_regdomain *_rtl_regdomain_select(
291 struct rtl_regulatory *reg)
292{
293 switch (reg->country_code) {
294 case COUNTRY_CODE_FCC:
295 case COUNTRY_CODE_IC:
296 return &rtl_regdom_11;
297 case COUNTRY_CODE_ETSI:
298 case COUNTRY_CODE_SPAIN:
299 case COUNTRY_CODE_FRANCE:
300 case COUNTRY_CODE_ISRAEL:
301 case COUNTRY_CODE_TELEC_NETGEAR:
302 return &rtl_regdom_world;
303 case COUNTRY_CODE_MKK:
304 case COUNTRY_CODE_MKK1:
305 case COUNTRY_CODE_TELEC:
306 case COUNTRY_CODE_MIC:
307 return &rtl_regdom_global;
308 case COUNTRY_CODE_GLOBAL_DOMAIN:
309 return &rtl_regdom_global;
310 case COUNTRY_CODE_WORLD_WIDE_13:
311 return &rtl_regdom_world;
312 default:
313 return &rtl_regdom_world;
314 }
315}
316
317static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
318 struct wiphy *wiphy,
319 int (*reg_notifier) (struct wiphy *wiphy,
320 struct regulatory_request *
321 request))
322{
323 const struct ieee80211_regdomain *regd;
324
325 wiphy->reg_notifier = reg_notifier;
326 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
327 wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY;
328 wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS;
329 regd = _rtl_regdomain_select(reg);
330 wiphy_apply_custom_regulatory(wiphy, regd);
331 _rtl_reg_apply_radar_flags(wiphy);
332 _rtl_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
333 return 0;
334}
335
336static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode)
337{
338 int i;
339
340 for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
341 if (allCountries[i].countrycode == countrycode)
342 return &allCountries[i];
343 }
344 return NULL;
345}
346
347int rtl_regd_init(struct ieee80211_hw *hw,
348 int (*reg_notifier) (struct wiphy *wiphy,
349 struct regulatory_request *request))
350{
351 struct rtl_priv *rtlpriv = rtl_priv(hw);
352 struct wiphy *wiphy = hw->wiphy;
353 struct country_code_to_enum_rd *country = NULL;
354
355 if (wiphy == NULL || &rtlpriv->regd == NULL)
356 return -EINVAL;
357
358 /* force the channel plan to world wide 13 */
359 rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
360
361 RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
362 (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n",
363 rtlpriv->regd.country_code));
364
365 if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) {
366 RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG,
367 (KERN_DEBUG "rtl: EEPROM indicates invalid contry code"
368 "world wide 13 should be used\n"));
369
370 rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
371 }
372
373 country = _rtl_regd_find_country(rtlpriv->regd.country_code);
374
375 if (country) {
376 rtlpriv->regd.alpha2[0] = country->isoName[0];
377 rtlpriv->regd.alpha2[1] = country->isoName[1];
378 } else {
379 rtlpriv->regd.alpha2[0] = '0';
380 rtlpriv->regd.alpha2[1] = '0';
381 }
382
383 RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
384 (KERN_DEBUG "rtl: Country alpha2 being used: %c%c\n",
385 rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]));
386
387 _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier);
388
389 return 0;
390}
391
392int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
393{
394 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
395 struct rtl_priv *rtlpriv = rtl_priv(hw);
396
397 RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, ("\n"));
398
399 return _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd);
400}
diff --git a/drivers/net/wireless/rtlwifi/regd.h b/drivers/net/wireless/rtlwifi/regd.h
new file mode 100644
index 00000000000..4cdbc4ae76d
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/regd.h
@@ -0,0 +1,61 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL_REGD_H__
31#define __RTL_REGD_H__
32
33struct country_code_to_enum_rd {
34 u16 countrycode;
35 const char *isoName;
36};
37
38enum country_code_type_t {
39 COUNTRY_CODE_FCC = 0,
40 COUNTRY_CODE_IC = 1,
41 COUNTRY_CODE_ETSI = 2,
42 COUNTRY_CODE_SPAIN = 3,
43 COUNTRY_CODE_FRANCE = 4,
44 COUNTRY_CODE_MKK = 5,
45 COUNTRY_CODE_MKK1 = 6,
46 COUNTRY_CODE_ISRAEL = 7,
47 COUNTRY_CODE_TELEC = 8,
48 COUNTRY_CODE_MIC = 9,
49 COUNTRY_CODE_GLOBAL_DOMAIN = 10,
50 COUNTRY_CODE_WORLD_WIDE_13 = 11,
51 COUNTRY_CODE_TELEC_NETGEAR = 12,
52
53 /*add new channel plan above this line */
54 COUNTRY_CODE_MAX
55};
56
57int rtl_regd_init(struct ieee80211_hw *hw,
58 int (*reg_notifier) (struct wiphy *wiphy,
59 struct regulatory_request *request));
60int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
61#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile
new file mode 100644
index 00000000000..f3d7682ff08
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile
@@ -0,0 +1,12 @@
1rtl8192ce-objs := \
2 rtl8192c-dm.o \
3 rtl8192c-fw.o \
4 rtl8192c-hw.o \
5 rtl8192c-led.o \
6 rtl8192c-phy.o \
7 rtl8192c-rf.o \
8 rtl8192c-sw.o \
9 rtl8192c-table.o \
10 rtl8192c-trx.o
11
12obj-$(CONFIG_RTL8192CE) += rtl8192ce.o
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h
new file mode 100644
index 00000000000..83cd6489529
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-def.h
@@ -0,0 +1,257 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92C_DEF_H__
31#define __RTL92C_DEF_H__
32
33#define HAL_RETRY_LIMIT_INFRA 48
34#define HAL_RETRY_LIMIT_AP_ADHOC 7
35
36#define PHY_RSSI_SLID_WIN_MAX 100
37#define PHY_LINKQUALITY_SLID_WIN_MAX 20
38#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
39
40#define RESET_DELAY_8185 20
41
42#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
43#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
44
45#define NUM_OF_FIRMWARE_QUEUE 10
46#define NUM_OF_PAGES_IN_FW 0x100
47#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
48#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
49#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
50#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
51#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
52#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
53#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
54#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
55#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
56#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
57
58#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
59#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
60#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
61#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
62#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
63
64#define MAX_LINES_HWCONFIG_TXT 1000
65#define MAX_BYTES_LINE_HWCONFIG_TXT 256
66
67#define SW_THREE_WIRE 0
68#define HW_THREE_WIRE 2
69
70#define BT_DEMO_BOARD 0
71#define BT_QA_BOARD 1
72#define BT_FPGA 2
73
74#define RX_SMOOTH_FACTOR 20
75
76#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
77#define HAL_PRIME_CHNL_OFFSET_LOWER 1
78#define HAL_PRIME_CHNL_OFFSET_UPPER 2
79
80#define MAX_H2C_QUEUE_NUM 10
81
82#define RX_MPDU_QUEUE 0
83#define RX_CMD_QUEUE 1
84#define RX_MAX_QUEUE 2
85#define AC2QUEUEID(_AC) (_AC)
86
87#define C2H_RX_CMD_HDR_LEN 8
88#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
89 LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
90#define GET_C2H_CMD_ELEMENT_ID(__prxhdr) \
91 LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
92#define GET_C2H_CMD_CMD_SEQ(__prxhdr) \
93 LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
94#define GET_C2H_CMD_CONTINUE(__prxhdr) \
95 LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
96#define GET_C2H_CMD_CONTENT(__prxhdr) \
97 ((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
98
99#define GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr) \
100 LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
101#define GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr) \
102 LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
103#define GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr) \
104 LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
105#define GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr) \
106 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
107#define GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr) \
108 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
109#define GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
110 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
111#define GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr) \
112 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
113#define GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr) \
114 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
115#define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \
116 LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
117
118#define CHIP_VER_B BIT(4)
119#define CHIP_92C_BITMASK BIT(0)
120#define CHIP_92C_1T2R 0x03
121#define CHIP_92C 0x01
122#define CHIP_88C 0x00
123
124enum version_8192c {
125 VERSION_A_CHIP_92C = 0x01,
126 VERSION_A_CHIP_88C = 0x00,
127 VERSION_B_CHIP_92C = 0x11,
128 VERSION_B_CHIP_88C = 0x10,
129 VERSION_UNKNOWN = 0x88,
130};
131
132#define IS_CHIP_VER_B(version) ((version & CHIP_VER_B) ? true : false)
133#define IS_92C_SERIAL(version) ((version & CHIP_92C_BITMASK) ? true : false)
134
135enum rtl819x_loopback_e {
136 RTL819X_NO_LOOPBACK = 0,
137 RTL819X_MAC_LOOPBACK = 1,
138 RTL819X_DMA_LOOPBACK = 2,
139 RTL819X_CCK_LOOPBACK = 3,
140};
141
142enum rf_optype {
143 RF_OP_BY_SW_3WIRE = 0,
144 RF_OP_BY_FW,
145 RF_OP_MAX
146};
147
148enum rf_power_state {
149 RF_ON,
150 RF_OFF,
151 RF_SLEEP,
152 RF_SHUT_DOWN,
153};
154
155enum power_save_mode {
156 POWER_SAVE_MODE_ACTIVE,
157 POWER_SAVE_MODE_SAVE,
158};
159
160enum power_polocy_config {
161 POWERCFG_MAX_POWER_SAVINGS,
162 POWERCFG_GLOBAL_POWER_SAVINGS,
163 POWERCFG_LOCAL_POWER_SAVINGS,
164 POWERCFG_LENOVO,
165};
166
167enum interface_select_pci {
168 INTF_SEL1_MINICARD = 0,
169 INTF_SEL0_PCIE = 1,
170 INTF_SEL2_RSV = 2,
171 INTF_SEL3_RSV = 3,
172};
173
174enum hal_fw_c2h_cmd_id {
175 HAL_FW_C2H_CMD_Read_MACREG = 0,
176 HAL_FW_C2H_CMD_Read_BBREG = 1,
177 HAL_FW_C2H_CMD_Read_RFREG = 2,
178 HAL_FW_C2H_CMD_Read_EEPROM = 3,
179 HAL_FW_C2H_CMD_Read_EFUSE = 4,
180 HAL_FW_C2H_CMD_Read_CAM = 5,
181 HAL_FW_C2H_CMD_Get_BasicRate = 6,
182 HAL_FW_C2H_CMD_Get_DataRate = 7,
183 HAL_FW_C2H_CMD_Survey = 8,
184 HAL_FW_C2H_CMD_SurveyDone = 9,
185 HAL_FW_C2H_CMD_JoinBss = 10,
186 HAL_FW_C2H_CMD_AddSTA = 11,
187 HAL_FW_C2H_CMD_DelSTA = 12,
188 HAL_FW_C2H_CMD_AtimDone = 13,
189 HAL_FW_C2H_CMD_TX_Report = 14,
190 HAL_FW_C2H_CMD_CCX_Report = 15,
191 HAL_FW_C2H_CMD_DTM_Report = 16,
192 HAL_FW_C2H_CMD_TX_Rate_Statistics = 17,
193 HAL_FW_C2H_CMD_C2HLBK = 18,
194 HAL_FW_C2H_CMD_C2HDBG = 19,
195 HAL_FW_C2H_CMD_C2HFEEDBACK = 20,
196 HAL_FW_C2H_CMD_MAX
197};
198
199enum rtl_desc_qsel {
200 QSLT_BK = 0x2,
201 QSLT_BE = 0x0,
202 QSLT_VI = 0x5,
203 QSLT_VO = 0x7,
204 QSLT_BEACON = 0x10,
205 QSLT_HIGH = 0x11,
206 QSLT_MGNT = 0x12,
207 QSLT_CMD = 0x13,
208};
209
210enum rtl_desc92c_rate {
211 DESC92C_RATE1M = 0x00,
212 DESC92C_RATE2M = 0x01,
213 DESC92C_RATE5_5M = 0x02,
214 DESC92C_RATE11M = 0x03,
215
216 DESC92C_RATE6M = 0x04,
217 DESC92C_RATE9M = 0x05,
218 DESC92C_RATE12M = 0x06,
219 DESC92C_RATE18M = 0x07,
220 DESC92C_RATE24M = 0x08,
221 DESC92C_RATE36M = 0x09,
222 DESC92C_RATE48M = 0x0a,
223 DESC92C_RATE54M = 0x0b,
224
225 DESC92C_RATEMCS0 = 0x0c,
226 DESC92C_RATEMCS1 = 0x0d,
227 DESC92C_RATEMCS2 = 0x0e,
228 DESC92C_RATEMCS3 = 0x0f,
229 DESC92C_RATEMCS4 = 0x10,
230 DESC92C_RATEMCS5 = 0x11,
231 DESC92C_RATEMCS6 = 0x12,
232 DESC92C_RATEMCS7 = 0x13,
233 DESC92C_RATEMCS8 = 0x14,
234 DESC92C_RATEMCS9 = 0x15,
235 DESC92C_RATEMCS10 = 0x16,
236 DESC92C_RATEMCS11 = 0x17,
237 DESC92C_RATEMCS12 = 0x18,
238 DESC92C_RATEMCS13 = 0x19,
239 DESC92C_RATEMCS14 = 0x1a,
240 DESC92C_RATEMCS15 = 0x1b,
241 DESC92C_RATEMCS15_SG = 0x1c,
242 DESC92C_RATEMCS32 = 0x20,
243};
244
245struct phy_sts_cck_8192s_t {
246 u8 adc_pwdb_X[4];
247 u8 sq_rpt;
248 u8 cck_agc_rpt;
249};
250
251struct h2c_cmd_8192c {
252 u8 element_id;
253 u32 cmd_len;
254 u8 *p_cmdbuffer;
255};
256
257#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c
new file mode 100644
index 00000000000..4896899394a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.c
@@ -0,0 +1,1473 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../base.h"
32#include "rtl8192c-reg.h"
33#include "rtl8192c-def.h"
34#include "rtl8192c-phy.h"
35#include "rtl8192c-dm.h"
36#include "rtl8192c-fw.h"
37
38struct dig_t dm_digtable;
39static struct ps_t dm_pstable;
40
41static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
42 0x7f8001fe,
43 0x788001e2,
44 0x71c001c7,
45 0x6b8001ae,
46 0x65400195,
47 0x5fc0017f,
48 0x5a400169,
49 0x55400155,
50 0x50800142,
51 0x4c000130,
52 0x47c0011f,
53 0x43c0010f,
54 0x40000100,
55 0x3c8000f2,
56 0x390000e4,
57 0x35c000d7,
58 0x32c000cb,
59 0x300000c0,
60 0x2d4000b5,
61 0x2ac000ab,
62 0x288000a2,
63 0x26000098,
64 0x24000090,
65 0x22000088,
66 0x20000080,
67 0x1e400079,
68 0x1c800072,
69 0x1b00006c,
70 0x19800066,
71 0x18000060,
72 0x16c0005b,
73 0x15800056,
74 0x14400051,
75 0x1300004c,
76 0x12000048,
77 0x11000044,
78 0x10000040,
79};
80
81static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
82 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
83 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
84 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
85 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
86 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
87 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
88 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
89 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
90 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
91 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
92 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
93 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
94 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
95 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
96 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
97 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
98 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
99 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
100 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
101 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
102 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
103 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
104 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},
105 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},
106 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},
107 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},
108 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},
109 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
110 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},
111 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},
112 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},
113 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},
114 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}
115};
116
117static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
118 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
119 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
120 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
121 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},
122 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
123 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},
124 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
125 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
126 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
127 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
128 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
129 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
130 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
131 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
132 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
133 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
134 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
135 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
136 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
137 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
138 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
139 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
140 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},
141 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
142 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
143 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},
144 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
145 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
146 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
147 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
148 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
149 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
150 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
151};
152
153static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
154{
155 dm_digtable.dig_enable_flag = true;
156 dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
157 dm_digtable.cur_igvalue = 0x20;
158 dm_digtable.pre_igvalue = 0x0;
159 dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
160 dm_digtable.presta_connectstate = DIG_STA_DISCONNECT;
161 dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT;
162 dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW;
163 dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH;
164 dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
165 dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
166 dm_digtable.rx_gain_range_max = DM_DIG_MAX;
167 dm_digtable.rx_gain_range_min = DM_DIG_MIN;
168 dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT;
169 dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX;
170 dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN;
171 dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_MAX;
172 dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX;
173}
174
175static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
176{
177 struct rtl_priv *rtlpriv = rtl_priv(hw);
178 long rssi_val_min = 0;
179
180 if ((dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) &&
181 (dm_digtable.cursta_connectctate == DIG_STA_CONNECT)) {
182 if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0)
183 rssi_val_min =
184 (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb >
185 rtlpriv->dm.undecorated_smoothed_pwdb) ?
186 rtlpriv->dm.undecorated_smoothed_pwdb :
187 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
188 else
189 rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb;
190 } else if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT ||
191 dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT) {
192 rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb;
193 } else if (dm_digtable.curmultista_connectstate ==
194 DIG_MULTISTA_CONNECT) {
195 rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
196 }
197
198 return (u8) rssi_val_min;
199}
200
201static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
202{
203 u32 ret_value;
204 struct rtl_priv *rtlpriv = rtl_priv(hw);
205 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
206
207 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
208 falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
209
210 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
211 falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
212 falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
213
214 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
215 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
216 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
217 falsealm_cnt->cnt_rate_illegal +
218 falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail;
219
220 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
221 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
222 falsealm_cnt->cnt_cck_fail = ret_value;
223
224 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
225 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
226 falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail +
227 falsealm_cnt->cnt_rate_illegal +
228 falsealm_cnt->cnt_crc8_fail +
229 falsealm_cnt->cnt_mcs_fail +
230 falsealm_cnt->cnt_cck_fail);
231
232 rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
233 rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
234 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
235 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
236
237 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
238 ("cnt_parity_fail = %d, cnt_rate_illegal = %d, "
239 "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
240 falsealm_cnt->cnt_parity_fail,
241 falsealm_cnt->cnt_rate_illegal,
242 falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail));
243
244 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
245 ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
246 falsealm_cnt->cnt_ofdm_fail,
247 falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all));
248}
249
250static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
251{
252 struct rtl_priv *rtlpriv = rtl_priv(hw);
253 u8 value_igi = dm_digtable.cur_igvalue;
254
255 if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
256 value_igi--;
257 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
258 value_igi += 0;
259 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2)
260 value_igi++;
261 else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)
262 value_igi += 2;
263 if (value_igi > DM_DIG_FA_UPPER)
264 value_igi = DM_DIG_FA_UPPER;
265 else if (value_igi < DM_DIG_FA_LOWER)
266 value_igi = DM_DIG_FA_LOWER;
267 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
268 value_igi = 0x32;
269
270 dm_digtable.cur_igvalue = value_igi;
271 rtl92c_dm_write_dig(hw);
272}
273
274static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
275{
276 struct rtl_priv *rtlpriv = rtl_priv(hw);
277
278 if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable.fa_highthresh) {
279 if ((dm_digtable.backoff_val - 2) <
280 dm_digtable.backoff_val_range_min)
281 dm_digtable.backoff_val =
282 dm_digtable.backoff_val_range_min;
283 else
284 dm_digtable.backoff_val -= 2;
285 } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable.fa_lowthresh) {
286 if ((dm_digtable.backoff_val + 2) >
287 dm_digtable.backoff_val_range_max)
288 dm_digtable.backoff_val =
289 dm_digtable.backoff_val_range_max;
290 else
291 dm_digtable.backoff_val += 2;
292 }
293
294 if ((dm_digtable.rssi_val_min + 10 - dm_digtable.backoff_val) >
295 dm_digtable.rx_gain_range_max)
296 dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_max;
297 else if ((dm_digtable.rssi_val_min + 10 -
298 dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
299 dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_min;
300 else
301 dm_digtable.cur_igvalue = dm_digtable.rssi_val_min + 10 -
302 dm_digtable.backoff_val;
303
304 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
305 ("rssi_val_min = %x backoff_val %x\n",
306 dm_digtable.rssi_val_min, dm_digtable.backoff_val));
307
308 rtl92c_dm_write_dig(hw);
309}
310
311static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
312{
313 static u8 binitialized; /* initialized to false */
314 struct rtl_priv *rtlpriv = rtl_priv(hw);
315 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
316 long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
317 bool b_multi_sta = false;
318
319 if (mac->opmode == NL80211_IFTYPE_ADHOC)
320 b_multi_sta = true;
321
322 if ((b_multi_sta == false) || (dm_digtable.cursta_connectctate !=
323 DIG_STA_DISCONNECT)) {
324 binitialized = false;
325 dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
326 return;
327 } else if (binitialized == false) {
328 binitialized = true;
329 dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
330 dm_digtable.cur_igvalue = 0x20;
331 rtl92c_dm_write_dig(hw);
332 }
333
334 if (dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) {
335 if ((rssi_strength < dm_digtable.rssi_lowthresh) &&
336 (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) {
337
338 if (dm_digtable.dig_ext_port_stage ==
339 DIG_EXT_PORT_STAGE_2) {
340 dm_digtable.cur_igvalue = 0x20;
341 rtl92c_dm_write_dig(hw);
342 }
343
344 dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_1;
345 } else if (rssi_strength > dm_digtable.rssi_highthresh) {
346 dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_2;
347 rtl92c_dm_ctrl_initgain_by_fa(hw);
348 }
349 } else if (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) {
350 dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
351 dm_digtable.cur_igvalue = 0x20;
352 rtl92c_dm_write_dig(hw);
353 }
354
355 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
356 ("curmultista_connectstate = "
357 "%x dig_ext_port_stage %x\n",
358 dm_digtable.curmultista_connectstate,
359 dm_digtable.dig_ext_port_stage));
360}
361
362static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
363{
364 struct rtl_priv *rtlpriv = rtl_priv(hw);
365
366 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
367 ("presta_connectstate = %x,"
368 " cursta_connectctate = %x\n",
369 dm_digtable.presta_connectstate,
370 dm_digtable.cursta_connectctate));
371
372 if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate
373 || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT
374 || dm_digtable.cursta_connectctate == DIG_STA_CONNECT) {
375
376 if (dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) {
377 dm_digtable.rssi_val_min =
378 rtl92c_dm_initial_gain_min_pwdb(hw);
379 rtl92c_dm_ctrl_initgain_by_rssi(hw);
380 }
381 } else {
382 dm_digtable.rssi_val_min = 0;
383 dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
384 dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT;
385 dm_digtable.cur_igvalue = 0x20;
386 dm_digtable.pre_igvalue = 0;
387 rtl92c_dm_write_dig(hw);
388 }
389}
390
391static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
392{
393 struct rtl_priv *rtlpriv = rtl_priv(hw);
394 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
395
396 if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) {
397 dm_digtable.rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw);
398
399 if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LowRssi) {
400 if (dm_digtable.rssi_val_min <= 25)
401 dm_digtable.cur_cck_pd_state =
402 CCK_PD_STAGE_LowRssi;
403 else
404 dm_digtable.cur_cck_pd_state =
405 CCK_PD_STAGE_HighRssi;
406 } else {
407 if (dm_digtable.rssi_val_min <= 20)
408 dm_digtable.cur_cck_pd_state =
409 CCK_PD_STAGE_LowRssi;
410 else
411 dm_digtable.cur_cck_pd_state =
412 CCK_PD_STAGE_HighRssi;
413 }
414 } else {
415 dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX;
416 }
417
418 if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) {
419 if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LowRssi) {
420 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800)
421 dm_digtable.cur_cck_fa_state =
422 CCK_FA_STAGE_High;
423 else
424 dm_digtable.cur_cck_fa_state = CCK_FA_STAGE_Low;
425
426 if (dm_digtable.pre_cck_fa_state !=
427 dm_digtable.cur_cck_fa_state) {
428 if (dm_digtable.cur_cck_fa_state ==
429 CCK_FA_STAGE_Low)
430 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
431 0x83);
432 else
433 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
434 0xcd);
435
436 dm_digtable.pre_cck_fa_state =
437 dm_digtable.cur_cck_fa_state;
438 }
439
440 rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
441
442 if (IS_92C_SERIAL(rtlhal->version))
443 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
444 MASKBYTE2, 0xd7);
445 } else {
446 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
447 rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
448
449 if (IS_92C_SERIAL(rtlhal->version))
450 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
451 MASKBYTE2, 0xd3);
452 }
453 dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state;
454 }
455
456 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
457 ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state));
458
459 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
460 ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version)));
461}
462
463static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
464{
465 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
466
467 if (mac->act_scanning == true)
468 return;
469
470 if ((mac->link_state > MAC80211_NOLINK) &&
471 (mac->link_state < MAC80211_LINKED))
472 dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT;
473 else if (mac->link_state >= MAC80211_LINKED)
474 dm_digtable.cursta_connectctate = DIG_STA_CONNECT;
475 else
476 dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
477
478 rtl92c_dm_initial_gain_sta(hw);
479 rtl92c_dm_initial_gain_multi_sta(hw);
480 rtl92c_dm_cck_packet_detection_thresh(hw);
481
482 dm_digtable.presta_connectstate = dm_digtable.cursta_connectctate;
483
484}
485
486static void rtl92c_dm_dig(struct ieee80211_hw *hw)
487{
488 struct rtl_priv *rtlpriv = rtl_priv(hw);
489
490 if (rtlpriv->dm.b_dm_initialgain_enable == false)
491 return;
492 if (dm_digtable.dig_enable_flag == false)
493 return;
494
495 rtl92c_dm_ctrl_initgain_by_twoport(hw);
496
497}
498
499static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
500{
501 struct rtl_priv *rtlpriv = rtl_priv(hw);
502
503 rtlpriv->dm.bdynamic_txpower_enable = false;
504
505 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
506 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
507}
508
509static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
510{
511 struct rtl_priv *rtlpriv = rtl_priv(hw);
512 struct rtl_phy *rtlphy = &(rtlpriv->phy);
513 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
514 long undecorated_smoothed_pwdb;
515
516 if (!rtlpriv->dm.bdynamic_txpower_enable)
517 return;
518
519 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
520 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
521 return;
522 }
523
524 if ((mac->link_state < MAC80211_LINKED) &&
525 (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
526 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
527 ("Not connected to any\n"));
528
529 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
530
531 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
532 return;
533 }
534
535 if (mac->link_state >= MAC80211_LINKED) {
536 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
537 undecorated_smoothed_pwdb =
538 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
539 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
540 ("AP Client PWDB = 0x%lx\n",
541 undecorated_smoothed_pwdb));
542 } else {
543 undecorated_smoothed_pwdb =
544 rtlpriv->dm.undecorated_smoothed_pwdb;
545 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
546 ("STA Default Port PWDB = 0x%lx\n",
547 undecorated_smoothed_pwdb));
548 }
549 } else {
550 undecorated_smoothed_pwdb =
551 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
552
553 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
554 ("AP Ext Port PWDB = 0x%lx\n",
555 undecorated_smoothed_pwdb));
556 }
557
558 if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
559 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
560 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
561 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
562 } else if ((undecorated_smoothed_pwdb <
563 (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
564 (undecorated_smoothed_pwdb >=
565 TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
566
567 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
568 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
569 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
570 } else if (undecorated_smoothed_pwdb <
571 (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
572 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
573 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
574 ("TXHIGHPWRLEVEL_NORMAL\n"));
575 }
576
577 if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
578 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
579 ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
580 rtlphy->current_channel));
581 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
582 }
583
584 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
585}
586
587void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
588{
589 struct rtl_priv *rtlpriv = rtl_priv(hw);
590
591 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
592 ("cur_igvalue = 0x%x, "
593 "pre_igvalue = 0x%x, backoff_val = %d\n",
594 dm_digtable.cur_igvalue, dm_digtable.pre_igvalue,
595 dm_digtable.backoff_val));
596
597 if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) {
598 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
599 dm_digtable.cur_igvalue);
600 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
601 dm_digtable.cur_igvalue);
602
603 dm_digtable.pre_igvalue = dm_digtable.cur_igvalue;
604 }
605}
606
607static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw)
608{
609 struct rtl_priv *rtlpriv = rtl_priv(hw);
610 long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff;
611
612 u8 h2c_parameter[3] = { 0 };
613
614 return;
615
616 if (tmpentry_max_pwdb != 0) {
617 rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb =
618 tmpentry_max_pwdb;
619 } else {
620 rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0;
621 }
622
623 if (tmpentry_min_pwdb != 0xff) {
624 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb =
625 tmpentry_min_pwdb;
626 } else {
627 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0;
628 }
629
630 h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF);
631 h2c_parameter[0] = 0;
632
633 rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter);
634}
635
636void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw)
637{
638 struct rtl_priv *rtlpriv = rtl_priv(hw);
639 rtlpriv->dm.bcurrent_turbo_edca = false;
640 rtlpriv->dm.bis_any_nonbepkts = false;
641 rtlpriv->dm.bis_cur_rdlstate = false;
642}
643
644static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)
645{
646 struct rtl_priv *rtlpriv = rtl_priv(hw);
647 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
648 static u64 last_txok_cnt;
649 static u64 last_rxok_cnt;
650 u64 cur_txok_cnt;
651 u64 cur_rxok_cnt;
652 u32 edca_be_ul = 0x5ea42b;
653 u32 edca_be_dl = 0x5ea42b;
654
655 if (mac->opmode == NL80211_IFTYPE_ADHOC)
656 goto dm_checkedcaturbo_exit;
657
658 if (mac->link_state != MAC80211_LINKED) {
659 rtlpriv->dm.bcurrent_turbo_edca = false;
660 return;
661 }
662
663 if (!mac->ht_enable) { /*FIX MERGE */
664 if (!(edca_be_ul & 0xffff0000))
665 edca_be_ul |= 0x005e0000;
666
667 if (!(edca_be_dl & 0xffff0000))
668 edca_be_dl |= 0x005e0000;
669 }
670
671 if ((!rtlpriv->dm.bis_any_nonbepkts) &&
672 (!rtlpriv->dm.b_disable_framebursting)) {
673 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
674 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
675 if (cur_rxok_cnt > 4 * cur_txok_cnt) {
676 if (!rtlpriv->dm.bis_cur_rdlstate ||
677 !rtlpriv->dm.bcurrent_turbo_edca) {
678 rtl_write_dword(rtlpriv,
679 REG_EDCA_BE_PARAM,
680 edca_be_dl);
681 rtlpriv->dm.bis_cur_rdlstate = true;
682 }
683 } else {
684 if (rtlpriv->dm.bis_cur_rdlstate ||
685 !rtlpriv->dm.bcurrent_turbo_edca) {
686 rtl_write_dword(rtlpriv,
687 REG_EDCA_BE_PARAM,
688 edca_be_ul);
689 rtlpriv->dm.bis_cur_rdlstate = false;
690 }
691 }
692 rtlpriv->dm.bcurrent_turbo_edca = true;
693 } else {
694 if (rtlpriv->dm.bcurrent_turbo_edca) {
695 u8 tmp = AC0_BE;
696 rtlpriv->cfg->ops->set_hw_reg(hw,
697 HW_VAR_AC_PARAM,
698 (u8 *) (&tmp));
699 rtlpriv->dm.bcurrent_turbo_edca = false;
700 }
701 }
702
703dm_checkedcaturbo_exit:
704 rtlpriv->dm.bis_any_nonbepkts = false;
705 last_txok_cnt = rtlpriv->stats.txbytesunicast;
706 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
707}
708
709static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
710 *hw)
711{
712 struct rtl_priv *rtlpriv = rtl_priv(hw);
713 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
714 struct rtl_phy *rtlphy = &(rtlpriv->phy);
715 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
716 u8 thermalvalue, delta, delta_lck, delta_iqk;
717 long ele_a, ele_d, temp_cck, val_x, value32;
718 long val_y, ele_c;
719 u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old;
720 int i;
721 bool is2t = IS_92C_SERIAL(rtlhal->version);
722 u8 txpwr_level[2] = {0, 0};
723 u8 ofdm_min_index = 6, rf;
724
725 rtlpriv->dm.btxpower_trackingInit = true;
726 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
727 ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n"));
728
729 thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
730
731 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
732 ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
733 "eeprom_thermalmeter 0x%x\n",
734 thermalvalue, rtlpriv->dm.thermalvalue,
735 rtlefuse->eeprom_thermalmeter));
736
737 rtl92c_phy_ap_calibrate(hw, (thermalvalue -
738 rtlefuse->eeprom_thermalmeter));
739 if (is2t)
740 rf = 2;
741 else
742 rf = 1;
743
744 if (thermalvalue) {
745 ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
746 MASKDWORD) & MASKOFDM_D;
747
748 for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
749 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
750 ofdm_index_old[0] = (u8) i;
751
752 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
753 ("Initial pathA ele_d reg0x%x = 0x%lx, "
754 "ofdm_index=0x%x\n",
755 ROFDM0_XATXIQIMBALANCE,
756 ele_d, ofdm_index_old[0]));
757 break;
758 }
759 }
760
761 if (is2t) {
762 ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
763 MASKDWORD) & MASKOFDM_D;
764
765 for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
766 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
767 ofdm_index_old[1] = (u8) i;
768
769 RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
770 DBG_LOUD,
771 ("Initial pathB ele_d reg0x%x = "
772 "0x%lx, ofdm_index=0x%x\n",
773 ROFDM0_XBTXIQIMBALANCE, ele_d,
774 ofdm_index_old[1]));
775 break;
776 }
777 }
778 }
779
780 temp_cck =
781 rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK;
782
783 for (i = 0; i < CCK_TABLE_LENGTH; i++) {
784 if (rtlpriv->dm.b_cck_inch14) {
785 if (memcmp((void *)&temp_cck,
786 (void *)&cckswing_table_ch14[i][2],
787 4) == 0) {
788 cck_index_old = (u8) i;
789
790 RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
791 DBG_LOUD,
792 ("Initial reg0x%x = 0x%lx, "
793 "cck_index=0x%x, ch 14 %d\n",
794 RCCK0_TXFILTER2, temp_cck,
795 cck_index_old,
796 rtlpriv->dm.b_cck_inch14));
797 break;
798 }
799 } else {
800 if (memcmp((void *)&temp_cck,
801 (void *)
802 &cckswing_table_ch1ch13[i][2],
803 4) == 0) {
804 cck_index_old = (u8) i;
805
806 RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
807 DBG_LOUD,
808 ("Initial reg0x%x = 0x%lx, "
809 "cck_index=0x%x, ch14 %d\n",
810 RCCK0_TXFILTER2, temp_cck,
811 cck_index_old,
812 rtlpriv->dm.b_cck_inch14));
813 break;
814 }
815 }
816 }
817
818 if (!rtlpriv->dm.thermalvalue) {
819 rtlpriv->dm.thermalvalue =
820 rtlefuse->eeprom_thermalmeter;
821 rtlpriv->dm.thermalvalue_lck = thermalvalue;
822 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
823 for (i = 0; i < rf; i++)
824 rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
825 rtlpriv->dm.cck_index = cck_index_old;
826 }
827
828 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
829 (thermalvalue - rtlpriv->dm.thermalvalue) :
830 (rtlpriv->dm.thermalvalue - thermalvalue);
831
832 delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
833 (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
834 (rtlpriv->dm.thermalvalue_lck - thermalvalue);
835
836 delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
837 (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
838 (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
839
840 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
841 ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
842 "eeprom_thermalmeter 0x%x delta 0x%x "
843 "delta_lck 0x%x delta_iqk 0x%x\n",
844 thermalvalue, rtlpriv->dm.thermalvalue,
845 rtlefuse->eeprom_thermalmeter, delta, delta_lck,
846 delta_iqk));
847
848 if (delta_lck > 1) {
849 rtlpriv->dm.thermalvalue_lck = thermalvalue;
850 rtl92c_phy_lc_calibrate(hw);
851 }
852
853 if (delta > 0 && rtlpriv->dm.txpower_track_control) {
854 if (thermalvalue > rtlpriv->dm.thermalvalue) {
855 for (i = 0; i < rf; i++)
856 rtlpriv->dm.ofdm_index[i] -= delta;
857 rtlpriv->dm.cck_index -= delta;
858 } else {
859 for (i = 0; i < rf; i++)
860 rtlpriv->dm.ofdm_index[i] += delta;
861 rtlpriv->dm.cck_index += delta;
862 }
863
864 if (is2t) {
865 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
866 ("temp OFDM_A_index=0x%x, "
867 "OFDM_B_index=0x%x,"
868 "cck_index=0x%x\n",
869 rtlpriv->dm.ofdm_index[0],
870 rtlpriv->dm.ofdm_index[1],
871 rtlpriv->dm.cck_index));
872 } else {
873 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
874 ("temp OFDM_A_index=0x%x,"
875 "cck_index=0x%x\n",
876 rtlpriv->dm.ofdm_index[0],
877 rtlpriv->dm.cck_index));
878 }
879
880 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
881 for (i = 0; i < rf; i++)
882 ofdm_index[i] =
883 rtlpriv->dm.ofdm_index[i]
884 + 1;
885 cck_index = rtlpriv->dm.cck_index + 1;
886 } else {
887 for (i = 0; i < rf; i++)
888 ofdm_index[i] =
889 rtlpriv->dm.ofdm_index[i];
890 cck_index = rtlpriv->dm.cck_index;
891 }
892
893 for (i = 0; i < rf; i++) {
894 if (txpwr_level[i] >= 0 &&
895 txpwr_level[i] <= 26) {
896 if (thermalvalue >
897 rtlefuse->eeprom_thermalmeter) {
898 if (delta < 5)
899 ofdm_index[i] -= 1;
900
901 else
902 ofdm_index[i] -= 2;
903 } else if (delta > 5 && thermalvalue <
904 rtlefuse->
905 eeprom_thermalmeter) {
906 ofdm_index[i] += 1;
907 }
908 } else if (txpwr_level[i] >= 27 &&
909 txpwr_level[i] <= 32
910 && thermalvalue >
911 rtlefuse->eeprom_thermalmeter) {
912 if (delta < 5)
913 ofdm_index[i] -= 1;
914
915 else
916 ofdm_index[i] -= 2;
917 } else if (txpwr_level[i] >= 32 &&
918 txpwr_level[i] <= 38 &&
919 thermalvalue >
920 rtlefuse->eeprom_thermalmeter
921 && delta > 5) {
922 ofdm_index[i] -= 1;
923 }
924 }
925
926 if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) {
927 if (thermalvalue >
928 rtlefuse->eeprom_thermalmeter) {
929 if (delta < 5)
930 cck_index -= 1;
931
932 else
933 cck_index -= 2;
934 } else if (delta > 5 && thermalvalue <
935 rtlefuse->eeprom_thermalmeter) {
936 cck_index += 1;
937 }
938 } else if (txpwr_level[i] >= 27 &&
939 txpwr_level[i] <= 32 &&
940 thermalvalue >
941 rtlefuse->eeprom_thermalmeter) {
942 if (delta < 5)
943 cck_index -= 1;
944
945 else
946 cck_index -= 2;
947 } else if (txpwr_level[i] >= 32 &&
948 txpwr_level[i] <= 38 &&
949 thermalvalue > rtlefuse->eeprom_thermalmeter
950 && delta > 5) {
951 cck_index -= 1;
952 }
953
954 for (i = 0; i < rf; i++) {
955 if (ofdm_index[i] > OFDM_TABLE_SIZE - 1)
956 ofdm_index[i] = OFDM_TABLE_SIZE - 1;
957
958 else if (ofdm_index[i] < ofdm_min_index)
959 ofdm_index[i] = ofdm_min_index;
960 }
961
962 if (cck_index > CCK_TABLE_SIZE - 1)
963 cck_index = CCK_TABLE_SIZE - 1;
964 else if (cck_index < 0)
965 cck_index = 0;
966
967 if (is2t) {
968 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
969 ("new OFDM_A_index=0x%x, "
970 "OFDM_B_index=0x%x,"
971 "cck_index=0x%x\n",
972 ofdm_index[0], ofdm_index[1],
973 cck_index));
974 } else {
975 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
976 ("new OFDM_A_index=0x%x,"
977 "cck_index=0x%x\n",
978 ofdm_index[0], cck_index));
979 }
980 }
981
982 if (rtlpriv->dm.txpower_track_control && delta != 0) {
983 ele_d =
984 (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22;
985 val_x = rtlphy->reg_e94;
986 val_y = rtlphy->reg_e9c;
987
988 if (val_x != 0) {
989 if ((val_x & 0x00000200) != 0)
990 val_x = val_x | 0xFFFFFC00;
991 ele_a = ((val_x * ele_d) >> 8) & 0x000003FF;
992
993 if ((val_y & 0x00000200) != 0)
994 val_y = val_y | 0xFFFFFC00;
995 ele_c = ((val_y * ele_d) >> 8) & 0x000003FF;
996
997 value32 = (ele_d << 22) |
998 ((ele_c & 0x3F) << 16) | ele_a;
999
1000 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1001 MASKDWORD, value32);
1002
1003 value32 = (ele_c & 0x000003C0) >> 6;
1004 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
1005 value32);
1006
1007 value32 = ((val_x * ele_d) >> 7) & 0x01;
1008 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1009 BIT(31), value32);
1010
1011 value32 = ((val_y * ele_d) >> 7) & 0x01;
1012 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1013 BIT(29), value32);
1014 } else {
1015 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1016 MASKDWORD,
1017 ofdmswing_table[ofdm_index[0]]);
1018
1019 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
1020 0x00);
1021 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1022 BIT(31) | BIT(29), 0x00);
1023 }
1024
1025 if (!rtlpriv->dm.b_cck_inch14) {
1026 rtl_write_byte(rtlpriv, 0xa22,
1027 cckswing_table_ch1ch13[cck_index]
1028 [0]);
1029 rtl_write_byte(rtlpriv, 0xa23,
1030 cckswing_table_ch1ch13[cck_index]
1031 [1]);
1032 rtl_write_byte(rtlpriv, 0xa24,
1033 cckswing_table_ch1ch13[cck_index]
1034 [2]);
1035 rtl_write_byte(rtlpriv, 0xa25,
1036 cckswing_table_ch1ch13[cck_index]
1037 [3]);
1038 rtl_write_byte(rtlpriv, 0xa26,
1039 cckswing_table_ch1ch13[cck_index]
1040 [4]);
1041 rtl_write_byte(rtlpriv, 0xa27,
1042 cckswing_table_ch1ch13[cck_index]
1043 [5]);
1044 rtl_write_byte(rtlpriv, 0xa28,
1045 cckswing_table_ch1ch13[cck_index]
1046 [6]);
1047 rtl_write_byte(rtlpriv, 0xa29,
1048 cckswing_table_ch1ch13[cck_index]
1049 [7]);
1050 } else {
1051 rtl_write_byte(rtlpriv, 0xa22,
1052 cckswing_table_ch14[cck_index]
1053 [0]);
1054 rtl_write_byte(rtlpriv, 0xa23,
1055 cckswing_table_ch14[cck_index]
1056 [1]);
1057 rtl_write_byte(rtlpriv, 0xa24,
1058 cckswing_table_ch14[cck_index]
1059 [2]);
1060 rtl_write_byte(rtlpriv, 0xa25,
1061 cckswing_table_ch14[cck_index]
1062 [3]);
1063 rtl_write_byte(rtlpriv, 0xa26,
1064 cckswing_table_ch14[cck_index]
1065 [4]);
1066 rtl_write_byte(rtlpriv, 0xa27,
1067 cckswing_table_ch14[cck_index]
1068 [5]);
1069 rtl_write_byte(rtlpriv, 0xa28,
1070 cckswing_table_ch14[cck_index]
1071 [6]);
1072 rtl_write_byte(rtlpriv, 0xa29,
1073 cckswing_table_ch14[cck_index]
1074 [7]);
1075 }
1076
1077 if (is2t) {
1078 ele_d = (ofdmswing_table[ofdm_index[1]] &
1079 0xFFC00000) >> 22;
1080
1081 val_x = rtlphy->reg_eb4;
1082 val_y = rtlphy->reg_ebc;
1083
1084 if (val_x != 0) {
1085 if ((val_x & 0x00000200) != 0)
1086 val_x = val_x | 0xFFFFFC00;
1087 ele_a = ((val_x * ele_d) >> 8) &
1088 0x000003FF;
1089
1090 if ((val_y & 0x00000200) != 0)
1091 val_y = val_y | 0xFFFFFC00;
1092 ele_c = ((val_y * ele_d) >> 8) &
1093 0x00003FF;
1094
1095 value32 = (ele_d << 22) |
1096 ((ele_c & 0x3F) << 16) | ele_a;
1097 rtl_set_bbreg(hw,
1098 ROFDM0_XBTXIQIMBALANCE,
1099 MASKDWORD, value32);
1100
1101 value32 = (ele_c & 0x000003C0) >> 6;
1102 rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
1103 MASKH4BITS, value32);
1104
1105 value32 = ((val_x * ele_d) >> 7) & 0x01;
1106 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1107 BIT(27), value32);
1108
1109 value32 = ((val_y * ele_d) >> 7) & 0x01;
1110 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1111 BIT(25), value32);
1112 } else {
1113 rtl_set_bbreg(hw,
1114 ROFDM0_XBTXIQIMBALANCE,
1115 MASKDWORD,
1116 ofdmswing_table[ofdm_index
1117 [1]]);
1118 rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
1119 MASKH4BITS, 0x00);
1120 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1121 BIT(27) | BIT(25), 0x00);
1122 }
1123
1124 }
1125 }
1126
1127 if (delta_iqk > 3) {
1128 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
1129 rtl92c_phy_iq_calibrate(hw, false);
1130 }
1131
1132 if (rtlpriv->dm.txpower_track_control)
1133 rtlpriv->dm.thermalvalue = thermalvalue;
1134 }
1135
1136 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n"));
1137
1138}
1139
1140static void rtl92c_dm_initialize_txpower_tracking_thermalmeter(
1141 struct ieee80211_hw *hw)
1142{
1143 struct rtl_priv *rtlpriv = rtl_priv(hw);
1144
1145 rtlpriv->dm.btxpower_tracking = true;
1146 rtlpriv->dm.btxpower_trackingInit = false;
1147
1148 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1149 ("pMgntInfo->btxpower_tracking = %d\n",
1150 rtlpriv->dm.btxpower_tracking));
1151}
1152
1153static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
1154{
1155 rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw);
1156}
1157
1158static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw)
1159{
1160 rtl92c_dm_txpower_tracking_callback_thermalmeter(hw);
1161}
1162
1163static void rtl92c_dm_check_txpower_tracking_thermal_meter(
1164 struct ieee80211_hw *hw)
1165{
1166 struct rtl_priv *rtlpriv = rtl_priv(hw);
1167 static u8 tm_trigger;
1168
1169 if (!rtlpriv->dm.btxpower_tracking)
1170 return;
1171
1172 if (!tm_trigger) {
1173 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK,
1174 0x60);
1175 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1176 ("Trigger 92S Thermal Meter!!\n"));
1177 tm_trigger = 1;
1178 return;
1179 } else {
1180 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1181 ("Schedule TxPowerTracking direct call!!\n"));
1182 rtl92c_dm_txpower_tracking_directcall(hw);
1183 tm_trigger = 0;
1184 }
1185}
1186
1187void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw)
1188{
1189 rtl92c_dm_check_txpower_tracking_thermal_meter(hw);
1190}
1191
1192void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
1193{
1194 struct rtl_priv *rtlpriv = rtl_priv(hw);
1195 struct rate_adaptive *p_ra = &(rtlpriv->ra);
1196
1197 p_ra->ratr_state = DM_RATR_STA_INIT;
1198 p_ra->pre_ratr_state = DM_RATR_STA_INIT;
1199
1200 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
1201 rtlpriv->dm.b_useramask = true;
1202 else
1203 rtlpriv->dm.b_useramask = false;
1204
1205}
1206
1207static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
1208{
1209 struct rtl_priv *rtlpriv = rtl_priv(hw);
1210 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1211 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1212 struct rate_adaptive *p_ra = &(rtlpriv->ra);
1213 u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
1214
1215 if (is_hal_stop(rtlhal)) {
1216 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1217 ("<---- driver is going to unload\n"));
1218 return;
1219 }
1220
1221 if (!rtlpriv->dm.b_useramask) {
1222 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1223 ("<---- driver does not control rate adaptive mask\n"));
1224 return;
1225 }
1226
1227 if (mac->link_state == MAC80211_LINKED) {
1228
1229 switch (p_ra->pre_ratr_state) {
1230 case DM_RATR_STA_HIGH:
1231 high_rssithresh_for_ra = 50;
1232 low_rssithresh_for_ra = 20;
1233 break;
1234 case DM_RATR_STA_MIDDLE:
1235 high_rssithresh_for_ra = 55;
1236 low_rssithresh_for_ra = 20;
1237 break;
1238 case DM_RATR_STA_LOW:
1239 high_rssithresh_for_ra = 50;
1240 low_rssithresh_for_ra = 25;
1241 break;
1242 default:
1243 high_rssithresh_for_ra = 50;
1244 low_rssithresh_for_ra = 20;
1245 break;
1246 }
1247
1248 if (rtlpriv->dm.undecorated_smoothed_pwdb >
1249 (long)high_rssithresh_for_ra)
1250 p_ra->ratr_state = DM_RATR_STA_HIGH;
1251 else if (rtlpriv->dm.undecorated_smoothed_pwdb >
1252 (long)low_rssithresh_for_ra)
1253 p_ra->ratr_state = DM_RATR_STA_MIDDLE;
1254 else
1255 p_ra->ratr_state = DM_RATR_STA_LOW;
1256
1257 if (p_ra->pre_ratr_state != p_ra->ratr_state) {
1258 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1259 ("RSSI = %ld\n",
1260 rtlpriv->dm.undecorated_smoothed_pwdb));
1261 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1262 ("RSSI_LEVEL = %d\n", p_ra->ratr_state));
1263 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1264 ("PreState = %d, CurState = %d\n",
1265 p_ra->pre_ratr_state, p_ra->ratr_state));
1266
1267 rtlpriv->cfg->ops->update_rate_mask(hw,
1268 p_ra->ratr_state);
1269
1270 p_ra->pre_ratr_state = p_ra->ratr_state;
1271 }
1272 }
1273}
1274
1275static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1276{
1277 dm_pstable.pre_ccastate = CCA_MAX;
1278 dm_pstable.cur_ccasate = CCA_MAX;
1279 dm_pstable.pre_rfstate = RF_MAX;
1280 dm_pstable.cur_rfstate = RF_MAX;
1281 dm_pstable.rssi_val_min = 0;
1282}
1283
1284static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw)
1285{
1286 struct rtl_priv *rtlpriv = rtl_priv(hw);
1287 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1288
1289 if (dm_pstable.rssi_val_min != 0) {
1290 if (dm_pstable.pre_ccastate == CCA_2R) {
1291 if (dm_pstable.rssi_val_min >= 35)
1292 dm_pstable.cur_ccasate = CCA_1R;
1293 else
1294 dm_pstable.cur_ccasate = CCA_2R;
1295 } else {
1296 if (dm_pstable.rssi_val_min <= 30)
1297 dm_pstable.cur_ccasate = CCA_2R;
1298 else
1299 dm_pstable.cur_ccasate = CCA_1R;
1300 }
1301 } else {
1302 dm_pstable.cur_ccasate = CCA_MAX;
1303 }
1304
1305 if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) {
1306 if (dm_pstable.cur_ccasate == CCA_1R) {
1307 if (get_rf_type(rtlphy) == RF_2T2R) {
1308 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
1309 MASKBYTE0, 0x13);
1310 rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20);
1311 } else {
1312 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
1313 MASKBYTE0, 0x23);
1314 rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c);
1315 }
1316 } else {
1317 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0,
1318 0x33);
1319 rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63);
1320 }
1321 dm_pstable.pre_ccastate = dm_pstable.cur_ccasate;
1322 }
1323
1324 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n",
1325 (dm_pstable.cur_ccasate ==
1326 0) ? "1RCCA" : "2RCCA"));
1327}
1328
1329void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
1330{
1331 static u8 initialize;
1332 static u32 reg_874, reg_c70, reg_85c, reg_a74;
1333
1334 if (initialize == 0) {
1335 reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1336 MASKDWORD) & 0x1CC000) >> 14;
1337
1338 reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
1339 MASKDWORD) & BIT(3)) >> 3;
1340
1341 reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
1342 MASKDWORD) & 0xFF000000) >> 24;
1343
1344 reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12;
1345
1346 initialize = 1;
1347 }
1348
1349 if (!bforce_in_normal) {
1350 if (dm_pstable.rssi_val_min != 0) {
1351 if (dm_pstable.pre_rfstate == RF_NORMAL) {
1352 if (dm_pstable.rssi_val_min >= 30)
1353 dm_pstable.cur_rfstate = RF_SAVE;
1354 else
1355 dm_pstable.cur_rfstate = RF_NORMAL;
1356 } else {
1357 if (dm_pstable.rssi_val_min <= 25)
1358 dm_pstable.cur_rfstate = RF_NORMAL;
1359 else
1360 dm_pstable.cur_rfstate = RF_SAVE;
1361 }
1362 } else {
1363 dm_pstable.cur_rfstate = RF_MAX;
1364 }
1365 } else {
1366 dm_pstable.cur_rfstate = RF_NORMAL;
1367 }
1368
1369 if (dm_pstable.pre_rfstate != dm_pstable.cur_rfstate) {
1370 if (dm_pstable.cur_rfstate == RF_SAVE) {
1371 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1372 0x1C0000, 0x2);
1373 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0);
1374 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
1375 0xFF000000, 0x63);
1376 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1377 0xC000, 0x2);
1378 rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3);
1379 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
1380 rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
1381 } else {
1382 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1383 0x1CC000, reg_874);
1384 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
1385 reg_c70);
1386 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
1387 reg_85c);
1388 rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74);
1389 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
1390 }
1391
1392 dm_pstable.pre_rfstate = dm_pstable.cur_rfstate;
1393 }
1394}
1395
1396static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1397{
1398 struct rtl_priv *rtlpriv = rtl_priv(hw);
1399 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1400 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1401
1402 if (((mac->link_state == MAC80211_NOLINK)) &&
1403 (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
1404 dm_pstable.rssi_val_min = 0;
1405 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
1406 ("Not connected to any\n"));
1407 }
1408
1409 if (mac->link_state == MAC80211_LINKED) {
1410 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
1411 dm_pstable.rssi_val_min =
1412 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
1413 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
1414 ("AP Client PWDB = 0x%lx\n",
1415 dm_pstable.rssi_val_min));
1416 } else {
1417 dm_pstable.rssi_val_min =
1418 rtlpriv->dm.undecorated_smoothed_pwdb;
1419 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
1420 ("STA Default Port PWDB = 0x%lx\n",
1421 dm_pstable.rssi_val_min));
1422 }
1423 } else {
1424 dm_pstable.rssi_val_min =
1425 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
1426
1427 RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
1428 ("AP Ext Port PWDB = 0x%lx\n",
1429 dm_pstable.rssi_val_min));
1430 }
1431
1432 if (IS_92C_SERIAL(rtlhal->version))
1433 rtl92c_dm_1r_cca(hw);
1434}
1435
1436void rtl92c_dm_init(struct ieee80211_hw *hw)
1437{
1438 struct rtl_priv *rtlpriv = rtl_priv(hw);
1439
1440 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1441 rtl92c_dm_diginit(hw);
1442 rtl92c_dm_init_dynamic_txpower(hw);
1443 rtl92c_dm_init_edca_turbo(hw);
1444 rtl92c_dm_init_rate_adaptive_mask(hw);
1445 rtl92c_dm_initialize_txpower_tracking(hw);
1446 rtl92c_dm_init_dynamic_bb_powersaving(hw);
1447}
1448
1449void rtl92c_dm_watchdog(struct ieee80211_hw *hw)
1450{
1451 struct rtl_priv *rtlpriv = rtl_priv(hw);
1452 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1453 bool b_fw_current_inpsmode = false;
1454 bool b_fw_ps_awake = true;
1455
1456 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1457 (u8 *) (&b_fw_current_inpsmode));
1458 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1459 (u8 *) (&b_fw_ps_awake));
1460
1461 if ((ppsc->rfpwr_state == ERFON) && ((!b_fw_current_inpsmode) &&
1462 b_fw_ps_awake)
1463 && (!ppsc->rfchange_inprogress)) {
1464 rtl92c_dm_pwdb_monitor(hw);
1465 rtl92c_dm_dig(hw);
1466 rtl92c_dm_false_alarm_counter_statistics(hw);
1467 rtl92c_dm_dynamic_bb_powersaving(hw);
1468 rtl92c_dm_dynamic_txpower(hw);
1469 rtl92c_dm_check_txpower_tracking(hw);
1470 rtl92c_dm_refresh_rate_adaptive_mask(hw);
1471 rtl92c_dm_check_edca_turbo(hw);
1472 }
1473}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h
new file mode 100644
index 00000000000..463439e4074
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-dm.h
@@ -0,0 +1,196 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92C_DM_H__
31#define __RTL92C_DM_H__
32
33#define HAL_DM_DIG_DISABLE BIT(0)
34#define HAL_DM_HIPWR_DISABLE BIT(1)
35
36#define OFDM_TABLE_LENGTH 37
37#define CCK_TABLE_LENGTH 33
38
39#define OFDM_TABLE_SIZE 37
40#define CCK_TABLE_SIZE 33
41
42#define BW_AUTO_SWITCH_HIGH_LOW 25
43#define BW_AUTO_SWITCH_LOW_HIGH 30
44
45#define DM_DIG_THRESH_HIGH 40
46#define DM_DIG_THRESH_LOW 35
47
48#define DM_FALSEALARM_THRESH_LOW 400
49#define DM_FALSEALARM_THRESH_HIGH 1000
50
51#define DM_DIG_MAX 0x3e
52#define DM_DIG_MIN 0x1e
53
54#define DM_DIG_FA_UPPER 0x32
55#define DM_DIG_FA_LOWER 0x20
56#define DM_DIG_FA_TH0 0x20
57#define DM_DIG_FA_TH1 0x100
58#define DM_DIG_FA_TH2 0x200
59
60#define DM_DIG_BACKOFF_MAX 12
61#define DM_DIG_BACKOFF_MIN -4
62#define DM_DIG_BACKOFF_DEFAULT 10
63
64#define RXPATHSELECTION_SS_TH_lOW 30
65#define RXPATHSELECTION_DIFF_TH 18
66
67#define DM_RATR_STA_INIT 0
68#define DM_RATR_STA_HIGH 1
69#define DM_RATR_STA_MIDDLE 2
70#define DM_RATR_STA_LOW 3
71
72#define CTS2SELF_THVAL 30
73#define REGC38_TH 20
74
75#define WAIOTTHVal 25
76
77#define TXHIGHPWRLEVEL_NORMAL 0
78#define TXHIGHPWRLEVEL_LEVEL1 1
79#define TXHIGHPWRLEVEL_LEVEL2 2
80#define TXHIGHPWRLEVEL_BT1 3
81#define TXHIGHPWRLEVEL_BT2 4
82
83#define DM_TYPE_BYFW 0
84#define DM_TYPE_BYDRIVER 1
85
86#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
87#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
88
89struct ps_t {
90 u8 pre_ccastate;
91 u8 cur_ccasate;
92 u8 pre_rfstate;
93 u8 cur_rfstate;
94 long rssi_val_min;
95};
96
97struct dig_t {
98 u8 dig_enable_flag;
99 u8 dig_ext_port_stage;
100 u32 rssi_lowthresh;
101 u32 rssi_highthresh;
102 u32 fa_lowthresh;
103 u32 fa_highthresh;
104 u8 cursta_connectctate;
105 u8 presta_connectstate;
106 u8 curmultista_connectstate;
107 u8 pre_igvalue;
108 u8 cur_igvalue;
109 char backoff_val;
110 char backoff_val_range_max;
111 char backoff_val_range_min;
112 u8 rx_gain_range_max;
113 u8 rx_gain_range_min;
114 u8 rssi_val_min;
115 u8 pre_cck_pd_state;
116 u8 cur_cck_pd_state;
117 u8 pre_cck_fa_state;
118 u8 cur_cck_fa_state;
119 u8 pre_ccastate;
120 u8 cur_ccasate;
121};
122
123struct swat_t {
124 u8 failure_cnt;
125 u8 try_flag;
126 u8 stop_trying;
127 long pre_rssi;
128 long trying_threshold;
129 u8 cur_antenna;
130 u8 pre_antenna;
131};
132
133enum tag_dynamic_init_gain_operation_type_definition {
134 DIG_TYPE_THRESH_HIGH = 0,
135 DIG_TYPE_THRESH_LOW = 1,
136 DIG_TYPE_BACKOFF = 2,
137 DIG_TYPE_RX_GAIN_MIN = 3,
138 DIG_TYPE_RX_GAIN_MAX = 4,
139 DIG_TYPE_ENABLE = 5,
140 DIG_TYPE_DISABLE = 6,
141 DIG_OP_TYPE_MAX
142};
143
144enum tag_cck_packet_detection_threshold_type_definition {
145 CCK_PD_STAGE_LowRssi = 0,
146 CCK_PD_STAGE_HighRssi = 1,
147 CCK_FA_STAGE_Low = 2,
148 CCK_FA_STAGE_High = 3,
149 CCK_PD_STAGE_MAX = 4,
150};
151
152enum dm_1r_cca_e {
153 CCA_1R = 0,
154 CCA_2R = 1,
155 CCA_MAX = 2,
156};
157
158enum dm_rf_e {
159 RF_SAVE = 0,
160 RF_NORMAL = 1,
161 RF_MAX = 2,
162};
163
164enum dm_sw_ant_switch_e {
165 ANS_ANTENNA_B = 1,
166 ANS_ANTENNA_A = 2,
167 ANS_ANTENNA_MAX = 3,
168};
169
170enum dm_dig_ext_port_alg_e {
171 DIG_EXT_PORT_STAGE_0 = 0,
172 DIG_EXT_PORT_STAGE_1 = 1,
173 DIG_EXT_PORT_STAGE_2 = 2,
174 DIG_EXT_PORT_STAGE_3 = 3,
175 DIG_EXT_PORT_STAGE_MAX = 4,
176};
177
178enum dm_dig_connect_e {
179 DIG_STA_DISCONNECT = 0,
180 DIG_STA_CONNECT = 1,
181 DIG_STA_BEFORE_CONNECT = 2,
182 DIG_MULTISTA_DISCONNECT = 3,
183 DIG_MULTISTA_CONNECT = 4,
184 DIG_CONNECT_MAX
185};
186
187extern struct dig_t dm_digtable;
188void rtl92c_dm_init(struct ieee80211_hw *hw);
189void rtl92c_dm_watchdog(struct ieee80211_hw *hw);
190void rtl92c_dm_write_dig(struct ieee80211_hw *hw);
191void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw);
192void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw);
193void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
194void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);
195
196#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c
new file mode 100644
index 00000000000..80ee6ff9d2b
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.c
@@ -0,0 +1,804 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include <linux/firmware.h>
31#include "../wifi.h"
32#include "../pci.h"
33#include "../base.h"
34#include "rtl8192c-reg.h"
35#include "rtl8192c-def.h"
36#include "rtl8192c-fw.h"
37#include "rtl8192c-table.h"
38
39static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
40{
41 struct rtl_priv *rtlpriv = rtl_priv(hw);
42 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
43
44 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) {
45 u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
46 if (enable)
47 value32 |= MCUFWDL_EN;
48 else
49 value32 &= ~MCUFWDL_EN;
50 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
51 } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) {
52 u8 tmp;
53 if (enable) {
54
55 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
56 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1,
57 tmp | 0x04);
58
59 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
60 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
61
62 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
63 rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
64 } else {
65
66 tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
67 rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
68
69 rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);
70 }
71 }
72}
73
74static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
75 const u8 *buffer, u32 size)
76{
77 struct rtl_priv *rtlpriv = rtl_priv(hw);
78 u32 blockSize = sizeof(u32);
79 u8 *bufferPtr = (u8 *) buffer;
80 u32 *pu4BytePtr = (u32 *) buffer;
81 u32 i, offset, blockCount, remainSize;
82
83 blockCount = size / blockSize;
84 remainSize = size % blockSize;
85
86 for (i = 0; i < blockCount; i++) {
87 offset = i * blockSize;
88 rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
89 *(pu4BytePtr + i));
90 }
91
92 if (remainSize) {
93 offset = blockCount * blockSize;
94 bufferPtr += offset;
95 for (i = 0; i < remainSize; i++) {
96 rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
97 offset + i), *(bufferPtr + i));
98 }
99 }
100}
101
102static void _rtl92c_fw_page_write(struct ieee80211_hw *hw,
103 u32 page, const u8 *buffer, u32 size)
104{
105 struct rtl_priv *rtlpriv = rtl_priv(hw);
106 u8 value8;
107 u8 u8page = (u8) (page & 0x07);
108
109 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
110
111 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
112 _rtl92c_fw_block_write(hw, buffer, size);
113}
114
115static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
116{
117 u32 fwlen = *pfwlen;
118 u8 remain = (u8) (fwlen % 4);
119
120 remain = (remain == 0) ? 0 : (4 - remain);
121
122 while (remain > 0) {
123 pfwbuf[fwlen] = 0;
124 fwlen++;
125 remain--;
126 }
127
128 *pfwlen = fwlen;
129}
130
131static void _rtl92c_write_fw(struct ieee80211_hw *hw,
132 enum version_8192c version, u8 *buffer, u32 size)
133{
134 struct rtl_priv *rtlpriv = rtl_priv(hw);
135 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
136 bool is_version_b;
137 u8 *bufferPtr = (u8 *) buffer;
138
139 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
140
141 is_version_b = IS_CHIP_VER_B(version);
142 if (is_version_b) {
143 u32 pageNums, remainSize;
144 u32 page, offset;
145
146 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE)
147 _rtl92c_fill_dummy(bufferPtr, &size);
148
149 pageNums = size / FW_8192C_PAGE_SIZE;
150 remainSize = size % FW_8192C_PAGE_SIZE;
151
152 if (pageNums > 4) {
153 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
154 ("Page numbers should not greater then 4\n"));
155 }
156
157 for (page = 0; page < pageNums; page++) {
158 offset = page * FW_8192C_PAGE_SIZE;
159 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
160 FW_8192C_PAGE_SIZE);
161 }
162
163 if (remainSize) {
164 offset = pageNums * FW_8192C_PAGE_SIZE;
165 page = pageNums;
166 _rtl92c_fw_page_write(hw, page, (bufferPtr + offset),
167 remainSize);
168 }
169 } else {
170 _rtl92c_fw_block_write(hw, buffer, size);
171 }
172}
173
174static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
175{
176 struct rtl_priv *rtlpriv = rtl_priv(hw);
177 int err = -EIO;
178 u32 counter = 0;
179 u32 value32;
180
181 do {
182 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
183 } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) &&
184 (!(value32 & FWDL_ChkSum_rpt)));
185
186 if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
187 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
188 ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
189 value32));
190 goto exit;
191 }
192
193 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
194 ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
195
196 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
197 value32 |= MCUFWDL_RDY;
198 value32 &= ~WINTINI_RDY;
199 rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
200
201 counter = 0;
202
203 do {
204 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
205 if (value32 & WINTINI_RDY) {
206 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
207 ("Polling FW ready success!!"
208 " REG_MCUFWDL:0x%08x .\n",
209 value32));
210 err = 0;
211 goto exit;
212 }
213
214 mdelay(FW_8192C_POLLING_DELAY);
215
216 } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
217
218 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
219 ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
220
221exit:
222 return err;
223}
224
225int rtl92c_download_fw(struct ieee80211_hw *hw)
226{
227 struct rtl_priv *rtlpriv = rtl_priv(hw);
228 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
229 struct rtl92c_firmware_header *pfwheader;
230 u8 *pfwdata;
231 u32 fwsize;
232 int err;
233 enum version_8192c version = rtlhal->version;
234
235 const struct firmware *firmware = NULL;
236
237 err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
238 rtlpriv->io.dev);
239 if (err) {
240 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
241 ("Failed to request firmware!\n"));
242 return 1;
243 }
244
245 if (firmware->size > 0x4000) {
246 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
247 ("Firmware is too big!\n"));
248 release_firmware(firmware);
249 return 1;
250 }
251
252 memcpy(rtlhal->pfirmware, firmware->data, firmware->size);
253 fwsize = firmware->size;
254 release_firmware(firmware);
255
256 pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
257 pfwdata = (u8 *) rtlhal->pfirmware;
258
259 if (IS_FW_HEADER_EXIST(pfwheader)) {
260 RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
261 ("Firmware Version(%d), Signature(%#x),Size(%d)\n",
262 pfwheader->version, pfwheader->signature,
263 (uint)sizeof(struct rtl92c_firmware_header)));
264
265 pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
266 fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
267 }
268
269 _rtl92c_enable_fw_download(hw, true);
270 _rtl92c_write_fw(hw, version, pfwdata, fwsize);
271 _rtl92c_enable_fw_download(hw, false);
272
273 err = _rtl92c_fw_free_to_go(hw);
274 if (err) {
275 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
276 ("Firmware is not ready to run!\n"));
277 } else {
278 RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
279 ("Firmware is ready to run!\n"));
280 }
281
282 return 0;
283}
284
285static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
286{
287 struct rtl_priv *rtlpriv = rtl_priv(hw);
288 u8 val_hmetfr, val_mcutst_1;
289 bool result = false;
290
291 val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
292 val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum));
293
294 if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0)
295 result = true;
296 return result;
297}
298
299static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
300 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
301{
302 struct rtl_priv *rtlpriv = rtl_priv(hw);
303 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
304 u8 boxnum;
305 u16 box_reg, box_extreg;
306 u8 u1b_tmp;
307 bool isfw_read = false;
308 u8 buf_index;
309 bool bwrite_sucess = false;
310 u8 wait_h2c_limmit = 100;
311 u8 wait_writeh2c_limmit = 100;
312 u8 boxcontent[4], boxextcontent[2];
313 u32 h2c_waitcounter = 0;
314 unsigned long flag;
315 u8 idx;
316
317 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
318
319 while (true) {
320 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
321 if (rtlhal->b_h2c_setinprogress) {
322 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
323 ("H2C set in progress! Wait to set.."
324 "element_id(%d).\n", element_id));
325
326 while (rtlhal->b_h2c_setinprogress) {
327 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
328 flag);
329 h2c_waitcounter++;
330 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
331 ("Wait 100 us (%d times)...\n",
332 h2c_waitcounter));
333 udelay(100);
334
335 if (h2c_waitcounter > 1000)
336 return;
337 spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
338 flag);
339 }
340 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
341 } else {
342 rtlhal->b_h2c_setinprogress = true;
343 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
344 break;
345 }
346 }
347
348 while (!bwrite_sucess) {
349 wait_writeh2c_limmit--;
350 if (wait_writeh2c_limmit == 0) {
351 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
352 ("Write H2C fail because no trigger "
353 "for FW INT!\n"));
354 break;
355 }
356
357 boxnum = rtlhal->last_hmeboxnum;
358 switch (boxnum) {
359 case 0:
360 box_reg = REG_HMEBOX_0;
361 box_extreg = REG_HMEBOX_EXT_0;
362 break;
363 case 1:
364 box_reg = REG_HMEBOX_1;
365 box_extreg = REG_HMEBOX_EXT_1;
366 break;
367 case 2:
368 box_reg = REG_HMEBOX_2;
369 box_extreg = REG_HMEBOX_EXT_2;
370 break;
371 case 3:
372 box_reg = REG_HMEBOX_3;
373 box_extreg = REG_HMEBOX_EXT_3;
374 break;
375 default:
376 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
377 ("switch case not process\n"));
378 break;
379 }
380
381 isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
382 while (!isfw_read) {
383
384 wait_h2c_limmit--;
385 if (wait_h2c_limmit == 0) {
386 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
387 ("Wating too long for FW read "
388 "clear HMEBox(%d)!\n", boxnum));
389 break;
390 }
391
392 udelay(10);
393
394 isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
395 u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
396 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
397 ("Wating for FW read clear HMEBox(%d)!!! "
398 "0x1BF = %2x\n", boxnum, u1b_tmp));
399 }
400
401 if (!isfw_read) {
402 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
403 ("Write H2C register BOX[%d] fail!!!!! "
404 "Fw do not read.\n", boxnum));
405 break;
406 }
407
408 memset(boxcontent, 0, sizeof(boxcontent));
409 memset(boxextcontent, 0, sizeof(boxextcontent));
410 boxcontent[0] = element_id;
411 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
412 ("Write element_id box_reg(%4x) = %2x\n",
413 box_reg, element_id));
414
415 switch (cmd_len) {
416 case 1:
417 boxcontent[0] &= ~(BIT(7));
418 memcpy((u8 *) (boxcontent) + 1,
419 p_cmdbuffer + buf_index, 1);
420
421 for (idx = 0; idx < 4; idx++) {
422 rtl_write_byte(rtlpriv, box_reg + idx,
423 boxcontent[idx]);
424 }
425 break;
426 case 2:
427 boxcontent[0] &= ~(BIT(7));
428 memcpy((u8 *) (boxcontent) + 1,
429 p_cmdbuffer + buf_index, 2);
430
431 for (idx = 0; idx < 4; idx++) {
432 rtl_write_byte(rtlpriv, box_reg + idx,
433 boxcontent[idx]);
434 }
435 break;
436 case 3:
437 boxcontent[0] &= ~(BIT(7));
438 memcpy((u8 *) (boxcontent) + 1,
439 p_cmdbuffer + buf_index, 3);
440
441 for (idx = 0; idx < 4; idx++) {
442 rtl_write_byte(rtlpriv, box_reg + idx,
443 boxcontent[idx]);
444 }
445 break;
446 case 4:
447 boxcontent[0] |= (BIT(7));
448 memcpy((u8 *) (boxextcontent),
449 p_cmdbuffer + buf_index, 2);
450 memcpy((u8 *) (boxcontent) + 1,
451 p_cmdbuffer + buf_index + 2, 2);
452
453 for (idx = 0; idx < 2; idx++) {
454 rtl_write_byte(rtlpriv, box_extreg + idx,
455 boxextcontent[idx]);
456 }
457
458 for (idx = 0; idx < 4; idx++) {
459 rtl_write_byte(rtlpriv, box_reg + idx,
460 boxcontent[idx]);
461 }
462 break;
463 case 5:
464 boxcontent[0] |= (BIT(7));
465 memcpy((u8 *) (boxextcontent),
466 p_cmdbuffer + buf_index, 2);
467 memcpy((u8 *) (boxcontent) + 1,
468 p_cmdbuffer + buf_index + 2, 3);
469
470 for (idx = 0; idx < 2; idx++) {
471 rtl_write_byte(rtlpriv, box_extreg + idx,
472 boxextcontent[idx]);
473 }
474
475 for (idx = 0; idx < 4; idx++) {
476 rtl_write_byte(rtlpriv, box_reg + idx,
477 boxcontent[idx]);
478 }
479 break;
480 default:
481 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
482 ("switch case not process\n"));
483 break;
484 }
485
486 bwrite_sucess = true;
487
488 rtlhal->last_hmeboxnum = boxnum + 1;
489 if (rtlhal->last_hmeboxnum == 4)
490 rtlhal->last_hmeboxnum = 0;
491
492 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
493 ("pHalData->last_hmeboxnum = %d\n",
494 rtlhal->last_hmeboxnum));
495 }
496
497 spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
498 rtlhal->b_h2c_setinprogress = false;
499 spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
500
501 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
502}
503
504void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
505 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
506{
507 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
508 u32 tmp_cmdbuf[2];
509
510 if (rtlhal->bfw_ready == false) {
511 RT_ASSERT(false, ("return H2C cmd because of Fw "
512 "download fail!!!\n"));
513 return;
514 }
515
516 memset(tmp_cmdbuf, 0, 8);
517 memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
518 _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
519
520 return;
521}
522
523void rtl92c_firmware_selfreset(struct ieee80211_hw *hw)
524{
525 u8 u1b_tmp;
526 u8 delay = 100;
527 struct rtl_priv *rtlpriv = rtl_priv(hw);
528
529 rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
530 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
531
532 while (u1b_tmp & BIT(2)) {
533 delay--;
534 if (delay == 0) {
535 RT_ASSERT(false, ("8051 reset fail.\n"));
536 break;
537 }
538 udelay(50);
539 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
540 }
541}
542
543void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
544{
545 struct rtl_priv *rtlpriv = rtl_priv(hw);
546 u8 u1_h2c_set_pwrmode[3] = {0};
547 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
548
549 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
550
551 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
552 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
553 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
554 ppsc->reg_max_lps_awakeintvl);
555
556 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
557 "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
558 u1_h2c_set_pwrmode, 3);
559 rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
560
561}
562
563static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
564 struct sk_buff *skb)
565{
566 struct rtl_priv *rtlpriv = rtl_priv(hw);
567 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
568 struct rtl8192_tx_ring *ring;
569 struct rtl_tx_desc *pdesc;
570 u8 own;
571 unsigned long flags;
572 struct sk_buff *pskb = NULL;
573
574 ring = &rtlpci->tx_ring[BEACON_QUEUE];
575
576 pskb = __skb_dequeue(&ring->queue);
577 if (pskb)
578 kfree_skb(pskb);
579
580 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
581
582 pdesc = &ring->desc[0];
583 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
584
585 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
586
587 __skb_queue_tail(&ring->queue, skb);
588
589 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
590
591 rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
592
593 return true;
594}
595
596#define BEACON_PG 0 /*->1*/
597#define PSPOLL_PG 2
598#define NULL_PG 3
599#define PROBERSP_PG 4 /*->5*/
600
601#define TOTAL_RESERVED_PKT_LEN 768
602
603static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
604 /* page 0 beacon */
605 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
606 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
607 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
610 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
611 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
612 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
613 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
614 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
615 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
616 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
619 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621
622 /* page 1 beacon */
623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639
640 /* page 2 ps-poll */
641 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
642 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
655 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657
658 /* page 3 null */
659 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
660 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
661 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
666 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
667 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
668 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
673 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675
676 /* page 4 probe_resp */
677 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
678 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
679 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
680 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
681 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
682 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
683 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
684 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
685 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
686 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
687 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
691 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693
694 /* page 5 probe_resp */
695 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
708 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711};
712
713void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
714{
715 struct rtl_priv *rtlpriv = rtl_priv(hw);
716 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
717 struct sk_buff *skb = NULL;
718
719 u32 totalpacketlen;
720 bool rtstatus;
721 u8 u1RsvdPageLoc[3] = {0};
722 bool b_dlok = false;
723
724 u8 *beacon;
725 u8 *p_pspoll;
726 u8 *nullfunc;
727 u8 *p_probersp;
728 /*---------------------------------------------------------
729 (1) beacon
730 ---------------------------------------------------------*/
731 beacon = &reserved_page_packet[BEACON_PG * 128];
732 SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
733 SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
734
735 /*-------------------------------------------------------
736 (2) ps-poll
737 --------------------------------------------------------*/
738 p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
739 SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
740 SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
741 SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
742
743 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
744
745 /*--------------------------------------------------------
746 (3) null data
747 ---------------------------------------------------------*/
748 nullfunc = &reserved_page_packet[NULL_PG * 128];
749 SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
750 SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
751 SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
752
753 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
754
755 /*---------------------------------------------------------
756 (4) probe response
757 ----------------------------------------------------------*/
758 p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
759 SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
760 SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
761 SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
762
763 SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
764
765 totalpacketlen = TOTAL_RESERVED_PKT_LEN;
766
767 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
768 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
769 &reserved_page_packet[0], totalpacketlen);
770 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
771 "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
772 u1RsvdPageLoc, 3);
773
774
775 skb = dev_alloc_skb(totalpacketlen);
776 memcpy((u8 *) skb_put(skb, totalpacketlen),
777 &reserved_page_packet, totalpacketlen);
778
779 rtstatus = _rtl92c_cmd_send_packet(hw, skb);
780
781 if (rtstatus)
782 b_dlok = true;
783
784 if (b_dlok) {
785 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
786 ("Set RSVD page location to Fw.\n"));
787 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
788 "H2C_RSVDPAGE:\n",
789 u1RsvdPageLoc, 3);
790 rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE,
791 sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
792 } else
793 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
794 ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
795}
796
797void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
798{
799 u8 u1_joinbssrpt_parm[1] = {0};
800
801 SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
802
803 rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
804}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h
new file mode 100644
index 00000000000..3db33bd1466
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-fw.h
@@ -0,0 +1,98 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92C__FW__H__
31#define __RTL92C__FW__H__
32
33#define FW_8192C_SIZE 0x3000
34#define FW_8192C_START_ADDRESS 0x1000
35#define FW_8192C_END_ADDRESS 0x3FFF
36#define FW_8192C_PAGE_SIZE 4096
37#define FW_8192C_POLLING_DELAY 5
38#define FW_8192C_POLLING_TIMEOUT_COUNT 100
39
40#define IS_FW_HEADER_EXIST(_pfwhdr) \
41 ((_pfwhdr->signature&0xFFF0) == 0x92C0 ||\
42 (_pfwhdr->signature&0xFFF0) == 0x88C0)
43
44struct rtl92c_firmware_header {
45 u16 signature;
46 u8 category;
47 u8 function;
48 u16 version;
49 u8 subversion;
50 u8 rsvd1;
51 u8 month;
52 u8 date;
53 u8 hour;
54 u8 minute;
55 u16 ramcodeSize;
56 u16 rsvd2;
57 u32 svnindex;
58 u32 rsvd3;
59 u32 rsvd4;
60 u32 rsvd5;
61};
62
63enum rtl8192c_h2c_cmd {
64 H2C_AP_OFFLOAD = 0,
65 H2C_SETPWRMODE = 1,
66 H2C_JOINBSSRPT = 2,
67 H2C_RSVDPAGE = 3,
68 H2C_RSSI_REPORT = 5,
69 H2C_RA_MASK = 6,
70 MAX_H2CCMD
71};
72
73#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0))
74
75#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \
76 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
77#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \
78 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
79#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \
80 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
81#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \
82 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
83#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \
84 SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
85#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \
86 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val)
87#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \
88 SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val)
89
90int rtl92c_download_fw(struct ieee80211_hw *hw);
91void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
92 u32 cmd_len, u8 *p_cmdbuffer);
93void rtl92c_firmware_selfreset(struct ieee80211_hw *hw);
94void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
95void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
96void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
97
98#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c
new file mode 100644
index 00000000000..c649f655575
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.c
@@ -0,0 +1,2173 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../efuse.h"
32#include "../base.h"
33#include "../cam.h"
34#include "../ps.h"
35#include "../pci.h"
36#include "rtl8192c-reg.h"
37#include "rtl8192c-def.h"
38#include "rtl8192c-phy.h"
39#include "rtl8192c-dm.h"
40#include "rtl8192c-fw.h"
41#include "rtl8192c-led.h"
42#include "rtl8192c-hw.h"
43
44#define LLT_CONFIG 5
45
46static void _rtl92ce_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
47 u8 set_bits, u8 clear_bits)
48{
49 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
50 struct rtl_priv *rtlpriv = rtl_priv(hw);
51
52 rtlpci->reg_bcn_ctrl_val |= set_bits;
53 rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
54
55 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
56}
57
58static void _rtl92ce_stop_tx_beacon(struct ieee80211_hw *hw)
59{
60 struct rtl_priv *rtlpriv = rtl_priv(hw);
61 u8 tmp1byte;
62
63 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
64 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
65 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
66 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
67 tmp1byte &= ~(BIT(0));
68 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
69}
70
71static void _rtl92ce_resume_tx_beacon(struct ieee80211_hw *hw)
72{
73 struct rtl_priv *rtlpriv = rtl_priv(hw);
74 u8 tmp1byte;
75
76 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
77 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
78 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
79 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
80 tmp1byte |= BIT(0);
81 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
82}
83
84static void _rtl92ce_enable_bcn_sub_func(struct ieee80211_hw *hw)
85{
86 _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(1));
87}
88
89static void _rtl92ce_disable_bcn_sub_func(struct ieee80211_hw *hw)
90{
91 _rtl92ce_set_bcn_ctrl_reg(hw, BIT(1), 0);
92}
93
94void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
95{
96 struct rtl_priv *rtlpriv = rtl_priv(hw);
97 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
98 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
99
100 switch (variable) {
101 case HW_VAR_RCR:
102 *((u32 *) (val)) = rtlpci->receive_config;
103 break;
104 case HW_VAR_RF_STATE:
105 *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
106 break;
107 case HW_VAR_FWLPS_RF_ON:{
108 enum rf_pwrstate rfState;
109 u32 val_rcr;
110
111 rtlpriv->cfg->ops->get_hw_reg(hw,
112 HW_VAR_RF_STATE,
113 (u8 *) (&rfState));
114 if (rfState == ERFOFF) {
115 *((bool *) (val)) = true;
116 } else {
117 val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
118 val_rcr &= 0x00070000;
119 if (val_rcr)
120 *((bool *) (val)) = false;
121 else
122 *((bool *) (val)) = true;
123 }
124 break;
125 }
126 case HW_VAR_FW_PSMODE_STATUS:
127 *((bool *) (val)) = ppsc->b_fw_current_inpsmode;
128 break;
129 case HW_VAR_CORRECT_TSF:{
130 u64 tsf;
131 u32 *ptsf_low = (u32 *)&tsf;
132 u32 *ptsf_high = ((u32 *)&tsf) + 1;
133
134 *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
135 *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
136
137 *((u64 *) (val)) = tsf;
138
139 break;
140 }
141 case HW_VAR_MGT_FILTER:
142 *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0);
143 break;
144 case HW_VAR_CTRL_FILTER:
145 *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1);
146 break;
147 case HW_VAR_DATA_FILTER:
148 *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2);
149 break;
150 default:
151 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
152 ("switch case not process\n"));
153 break;
154 }
155}
156
157void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
158{
159 struct rtl_priv *rtlpriv = rtl_priv(hw);
160 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
161 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
162 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
163 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
164 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
165 u8 idx;
166
167 switch (variable) {
168 case HW_VAR_ETHER_ADDR:{
169 for (idx = 0; idx < ETH_ALEN; idx++) {
170 rtl_write_byte(rtlpriv, (REG_MACID + idx),
171 val[idx]);
172 }
173 break;
174 }
175 case HW_VAR_BASIC_RATE:{
176 u16 b_rate_cfg = ((u16 *) val)[0];
177 u8 rate_index = 0;
178 b_rate_cfg = b_rate_cfg & 0x15f;
179 b_rate_cfg |= 0x01;
180 rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff);
181 rtl_write_byte(rtlpriv, REG_RRSR + 1,
182 (b_rate_cfg >> 8)&0xff);
183 while (b_rate_cfg > 0x1) {
184 b_rate_cfg = (b_rate_cfg >> 1);
185 rate_index++;
186 }
187 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL,
188 rate_index);
189 break;
190 }
191 case HW_VAR_BSSID:{
192 for (idx = 0; idx < ETH_ALEN; idx++) {
193 rtl_write_byte(rtlpriv, (REG_BSSID + idx),
194 val[idx]);
195 }
196 break;
197 }
198 case HW_VAR_SIFS:{
199 rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
200 rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
201
202 rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
203 rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
204
205 if (!mac->ht_enable)
206 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
207 0x0e0e);
208 else
209 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
210 *((u16 *) val));
211 break;
212 }
213 case HW_VAR_SLOT_TIME:{
214 u8 e_aci;
215
216 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
217 ("HW_VAR_SLOT_TIME %x\n", val[0]));
218
219 rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
220
221 for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
222 rtlpriv->cfg->ops->set_hw_reg(hw,
223 HW_VAR_AC_PARAM,
224 (u8 *) (&e_aci));
225 }
226 break;
227 }
228 case HW_VAR_ACK_PREAMBLE:{
229 u8 reg_tmp;
230 u8 short_preamble = (bool) (*(u8 *) val);
231 reg_tmp = (mac->cur_40_prime_sc) << 5;
232 if (short_preamble)
233 reg_tmp |= 0x80;
234
235 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp);
236 break;
237 }
238 case HW_VAR_AMPDU_MIN_SPACE:{
239 u8 min_spacing_to_set;
240 u8 sec_min_space;
241
242 min_spacing_to_set = *((u8 *) val);
243 if (min_spacing_to_set <= 7) {
244 sec_min_space = 0;
245
246 if (min_spacing_to_set < sec_min_space)
247 min_spacing_to_set = sec_min_space;
248
249 mac->min_space_cfg = ((mac->min_space_cfg &
250 0xf8) |
251 min_spacing_to_set);
252
253 *val = min_spacing_to_set;
254
255 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
256 ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
257 mac->min_space_cfg));
258
259 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
260 mac->min_space_cfg);
261 }
262 break;
263 }
264 case HW_VAR_SHORTGI_DENSITY:{
265 u8 density_to_set;
266
267 density_to_set = *((u8 *) val);
268 mac->min_space_cfg |= (density_to_set << 3);
269
270 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
271 ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
272 mac->min_space_cfg));
273
274 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
275 mac->min_space_cfg);
276
277 break;
278 }
279 case HW_VAR_AMPDU_FACTOR:{
280 u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 };
281
282 u8 factor_toset;
283 u8 *p_regtoset = NULL;
284 u8 index = 0;
285
286 p_regtoset = regtoset_normal;
287
288 factor_toset = *((u8 *) val);
289 if (factor_toset <= 3) {
290 factor_toset = (1 << (factor_toset + 2));
291 if (factor_toset > 0xf)
292 factor_toset = 0xf;
293
294 for (index = 0; index < 4; index++) {
295 if ((p_regtoset[index] & 0xf0) >
296 (factor_toset << 4))
297 p_regtoset[index] =
298 (p_regtoset[index] & 0x0f) |
299 (factor_toset << 4);
300
301 if ((p_regtoset[index] & 0x0f) >
302 factor_toset)
303 p_regtoset[index] =
304 (p_regtoset[index] & 0xf0) |
305 (factor_toset);
306
307 rtl_write_byte(rtlpriv,
308 (REG_AGGLEN_LMT + index),
309 p_regtoset[index]);
310
311 }
312
313 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
314 ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
315 factor_toset));
316 }
317 break;
318 }
319 case HW_VAR_AC_PARAM:{
320 u8 e_aci = *((u8 *) val);
321 u32 u4b_ac_param = 0;
322
323 u4b_ac_param |= (u32) mac->ac[e_aci].aifs;
324 u4b_ac_param |= ((u32) mac->ac[e_aci].cw_min
325 & 0xF) << AC_PARAM_ECW_MIN_OFFSET;
326 u4b_ac_param |= ((u32) mac->ac[e_aci].cw_max &
327 0xF) << AC_PARAM_ECW_MAX_OFFSET;
328 u4b_ac_param |= (u32) mac->ac[e_aci].tx_op
329 << AC_PARAM_TXOP_LIMIT_OFFSET;
330
331 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
332 ("queue:%x, ac_param:%x\n", e_aci,
333 u4b_ac_param));
334
335 switch (e_aci) {
336 case AC1_BK:
337 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM,
338 u4b_ac_param);
339 break;
340 case AC0_BE:
341 rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM,
342 u4b_ac_param);
343 break;
344 case AC2_VI:
345 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM,
346 u4b_ac_param);
347 break;
348 case AC3_VO:
349 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM,
350 u4b_ac_param);
351 break;
352 default:
353 RT_ASSERT(false,
354 ("SetHwReg8185(): invalid aci: %d !\n",
355 e_aci));
356 break;
357 }
358
359 if (rtlpci->acm_method != eAcmWay2_SW)
360 rtlpriv->cfg->ops->set_hw_reg(hw,
361 HW_VAR_ACM_CTRL,
362 (u8 *) (&e_aci));
363 break;
364 }
365 case HW_VAR_ACM_CTRL:{
366 u8 e_aci = *((u8 *) val);
367 union aci_aifsn *p_aci_aifsn =
368 (union aci_aifsn *)(&(mac->ac[0].aifs));
369 u8 acm = p_aci_aifsn->f.acm;
370 u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
371
372 acm_ctrl =
373 acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
374
375 if (acm) {
376 switch (e_aci) {
377 case AC0_BE:
378 acm_ctrl |= AcmHw_BeqEn;
379 break;
380 case AC2_VI:
381 acm_ctrl |= AcmHw_ViqEn;
382 break;
383 case AC3_VO:
384 acm_ctrl |= AcmHw_VoqEn;
385 break;
386 default:
387 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
388 ("HW_VAR_ACM_CTRL acm set "
389 "failed: eACI is %d\n", acm));
390 break;
391 }
392 } else {
393 switch (e_aci) {
394 case AC0_BE:
395 acm_ctrl &= (~AcmHw_BeqEn);
396 break;
397 case AC2_VI:
398 acm_ctrl &= (~AcmHw_ViqEn);
399 break;
400 case AC3_VO:
401 acm_ctrl &= (~AcmHw_BeqEn);
402 break;
403 default:
404 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
405 ("switch case not process\n"));
406 break;
407 }
408 }
409
410 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
411 ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] "
412 "Write 0x%X\n", acm_ctrl));
413 rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
414 break;
415 }
416 case HW_VAR_RCR:{
417 rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]);
418 rtlpci->receive_config = ((u32 *) (val))[0];
419 break;
420 }
421 case HW_VAR_RETRY_LIMIT:{
422 u8 retry_limit = ((u8 *) (val))[0];
423
424 rtl_write_word(rtlpriv, REG_RL,
425 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
426 retry_limit << RETRY_LIMIT_LONG_SHIFT);
427 break;
428 }
429 case HW_VAR_DUAL_TSF_RST:
430 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
431 break;
432 case HW_VAR_EFUSE_BYTES:
433 rtlefuse->efuse_usedbytes = *((u16 *) val);
434 break;
435 case HW_VAR_EFUSE_USAGE:
436 rtlefuse->efuse_usedpercentage = *((u8 *) val);
437 break;
438 case HW_VAR_IO_CMD:
439 rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val));
440 break;
441 case HW_VAR_WPA_CONFIG:
442 rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val));
443 break;
444 case HW_VAR_SET_RPWM:{
445 u8 rpwm_val;
446
447 rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
448 udelay(1);
449
450 if (rpwm_val & BIT(7)) {
451 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
452 (*(u8 *) val));
453 } else {
454 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
455 ((*(u8 *) val) | BIT(7)));
456 }
457
458 break;
459 }
460 case HW_VAR_H2C_FW_PWRMODE:{
461 u8 psmode = (*(u8 *) val);
462
463 if ((psmode != FW_PS_ACTIVE_MODE) &&
464 (!IS_92C_SERIAL(rtlhal->version))) {
465 rtl92c_dm_rf_saving(hw, true);
466 }
467
468 rtl92c_set_fw_pwrmode_cmd(hw, (*(u8 *) val));
469 break;
470 }
471 case HW_VAR_FW_PSMODE_STATUS:
472 ppsc->b_fw_current_inpsmode = *((bool *) val);
473 break;
474 case HW_VAR_H2C_FW_JOINBSSRPT:{
475 u8 mstatus = (*(u8 *) val);
476 u8 tmp_regcr, tmp_reg422;
477 bool b_recover = false;
478
479 if (mstatus == RT_MEDIA_CONNECT) {
480 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID,
481 NULL);
482
483 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
484 rtl_write_byte(rtlpriv, REG_CR + 1,
485 (tmp_regcr | BIT(0)));
486
487 _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3));
488 _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0);
489
490 tmp_reg422 =
491 rtl_read_byte(rtlpriv,
492 REG_FWHW_TXQ_CTRL + 2);
493 if (tmp_reg422 & BIT(6))
494 b_recover = true;
495 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
496 tmp_reg422 & (~BIT(6)));
497
498 rtl92c_set_fw_rsvdpagepkt(hw, 0);
499
500 _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0);
501 _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4));
502
503 if (b_recover) {
504 rtl_write_byte(rtlpriv,
505 REG_FWHW_TXQ_CTRL + 2,
506 tmp_reg422);
507 }
508
509 rtl_write_byte(rtlpriv, REG_CR + 1,
510 (tmp_regcr & ~(BIT(0))));
511 }
512 rtl92c_set_fw_joinbss_report_cmd(hw, (*(u8 *) val));
513
514 break;
515 }
516 case HW_VAR_AID:{
517 u16 u2btmp;
518 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
519 u2btmp &= 0xC000;
520 rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp |
521 mac->assoc_id));
522
523 break;
524 }
525 case HW_VAR_CORRECT_TSF:{
526 u8 btype_ibss = ((u8 *) (val))[0];
527
528 /*btype_ibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ?
529 1 : 0;*/
530
531 if (btype_ibss == true)
532 _rtl92ce_stop_tx_beacon(hw);
533
534 _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(3));
535
536 rtl_write_dword(rtlpriv, REG_TSFTR,
537 (u32) (mac->tsf & 0xffffffff));
538 rtl_write_dword(rtlpriv, REG_TSFTR + 4,
539 (u32) ((mac->tsf >> 32)&0xffffffff));
540
541 _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0);
542
543 if (btype_ibss == true)
544 _rtl92ce_resume_tx_beacon(hw);
545
546 break;
547
548 }
549 case HW_VAR_MGT_FILTER:
550 rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *) val);
551 break;
552 case HW_VAR_CTRL_FILTER:
553 rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *) val);
554 break;
555 case HW_VAR_DATA_FILTER:
556 rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *) val);
557 break;
558 default:
559 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
560 "not process\n"));
561 break;
562 }
563}
564
565static bool _rtl92ce_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
566{
567 struct rtl_priv *rtlpriv = rtl_priv(hw);
568 bool status = true;
569 long count = 0;
570 u32 value = _LLT_INIT_ADDR(address) |
571 _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
572
573 rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
574
575 do {
576 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
577 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
578 break;
579
580 if (count > POLLING_LLT_THRESHOLD) {
581 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
582 ("Failed to polling write LLT done at "
583 "address %d!\n", address));
584 status = false;
585 break;
586 }
587 } while (++count);
588
589 return status;
590}
591
592static bool _rtl92ce_llt_table_init(struct ieee80211_hw *hw)
593{
594 struct rtl_priv *rtlpriv = rtl_priv(hw);
595 unsigned short i;
596 u8 txpktbuf_bndy;
597 u8 maxPage;
598 bool status;
599
600#if LLT_CONFIG == 1
601 maxPage = 255;
602 txpktbuf_bndy = 252;
603#elif LLT_CONFIG == 2
604 maxPage = 127;
605 txpktbuf_bndy = 124;
606#elif LLT_CONFIG == 3
607 maxPage = 255;
608 txpktbuf_bndy = 174;
609#elif LLT_CONFIG == 4
610 maxPage = 255;
611 txpktbuf_bndy = 246;
612#elif LLT_CONFIG == 5
613 maxPage = 255;
614 txpktbuf_bndy = 246;
615#endif
616
617#if LLT_CONFIG == 1
618 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x1c);
619 rtl_write_dword(rtlpriv, REG_RQPN, 0x80a71c1c);
620#elif LLT_CONFIG == 2
621 rtl_write_dword(rtlpriv, REG_RQPN, 0x845B1010);
622#elif LLT_CONFIG == 3
623 rtl_write_dword(rtlpriv, REG_RQPN, 0x84838484);
624#elif LLT_CONFIG == 4
625 rtl_write_dword(rtlpriv, REG_RQPN, 0x80bd1c1c);
626#elif LLT_CONFIG == 5
627 rtl_write_word(rtlpriv, REG_RQPN_NPQ, 0x0000);
628
629 rtl_write_dword(rtlpriv, REG_RQPN, 0x80b01c29);
630#endif
631
632 rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x27FF0000 | txpktbuf_bndy));
633 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
634
635 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
636 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
637
638 rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
639 rtl_write_byte(rtlpriv, REG_PBP, 0x11);
640 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
641
642 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
643 status = _rtl92ce_llt_write(hw, i, i + 1);
644 if (true != status)
645 return status;
646 }
647
648 status = _rtl92ce_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
649 if (true != status)
650 return status;
651
652 for (i = txpktbuf_bndy; i < maxPage; i++) {
653 status = _rtl92ce_llt_write(hw, i, (i + 1));
654 if (true != status)
655 return status;
656 }
657
658 status = _rtl92ce_llt_write(hw, maxPage, txpktbuf_bndy);
659 if (true != status)
660 return status;
661
662 return true;
663}
664
665static void _rtl92ce_gen_refresh_led_state(struct ieee80211_hw *hw)
666{
667 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
668 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
669 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
670 struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
671
672 if (rtlpci->up_first_time)
673 return;
674
675 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
676 rtl92ce_sw_led_on(hw, pLed0);
677 else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
678 rtl92ce_sw_led_on(hw, pLed0);
679 else
680 rtl92ce_sw_led_off(hw, pLed0);
681
682}
683
684static bool _rtl92ce_init_mac(struct ieee80211_hw *hw)
685{
686 struct rtl_priv *rtlpriv = rtl_priv(hw);
687 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
688 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
689
690 unsigned char bytetmp;
691 unsigned short wordtmp;
692 u16 retry;
693
694 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
695 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
696 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F);
697
698 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0);
699 udelay(2);
700
701 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
702 udelay(2);
703
704 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
705 udelay(2);
706
707 retry = 0;
708 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n",
709 rtl_read_dword(rtlpriv, 0xEC),
710 bytetmp));
711
712 while ((bytetmp & BIT(0)) && retry < 1000) {
713 retry++;
714 udelay(50);
715 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
716 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n",
717 rtl_read_dword(rtlpriv,
718 0xEC),
719 bytetmp));
720 udelay(50);
721 }
722
723 rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x1012);
724
725 rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82);
726 udelay(2);
727
728 rtl_write_word(rtlpriv, REG_CR, 0x2ff);
729
730 if (_rtl92ce_llt_table_init(hw) == false)
731 return false;;
732
733 rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
734 rtl_write_byte(rtlpriv, REG_HISRE, 0xff);
735
736 rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x27ff);
737
738 wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
739 wordtmp &= 0xf;
740 wordtmp |= 0xF771;
741 rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
742
743 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
744 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
745 rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
746
747 rtl_write_byte(rtlpriv, 0x4d0, 0x0);
748
749 rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
750 ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
751 DMA_BIT_MASK(32));
752 rtl_write_dword(rtlpriv, REG_MGQ_DESA,
753 (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
754 DMA_BIT_MASK(32));
755 rtl_write_dword(rtlpriv, REG_VOQ_DESA,
756 (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
757 rtl_write_dword(rtlpriv, REG_VIQ_DESA,
758 (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
759 rtl_write_dword(rtlpriv, REG_BEQ_DESA,
760 (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
761 rtl_write_dword(rtlpriv, REG_BKQ_DESA,
762 (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
763 rtl_write_dword(rtlpriv, REG_HQ_DESA,
764 (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
765 DMA_BIT_MASK(32));
766 rtl_write_dword(rtlpriv, REG_RX_DESA,
767 (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
768 DMA_BIT_MASK(32));
769
770 if (IS_92C_SERIAL(rtlhal->version))
771 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x77);
772 else
773 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x22);
774
775 rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
776
777 bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
778 rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6));
779 do {
780 retry++;
781 bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
782 } while ((retry < 200) && (bytetmp & BIT(7)));
783
784 _rtl92ce_gen_refresh_led_state(hw);
785
786 rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
787
788 return true;;
789}
790
791static void _rtl92ce_hw_configure(struct ieee80211_hw *hw)
792{
793 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
794 struct rtl_priv *rtlpriv = rtl_priv(hw);
795 u8 reg_bw_opmode;
796 u32 reg_ratr, reg_prsr;
797
798 reg_bw_opmode = BW_OPMODE_20MHZ;
799 reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG |
800 RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
801 reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
802
803 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8);
804
805 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
806
807 rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr);
808
809 rtl_write_byte(rtlpriv, REG_SLOT, 0x09);
810
811 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0);
812
813 rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80);
814
815 rtl_write_word(rtlpriv, REG_RL, 0x0707);
816
817 rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802);
818
819 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF);
820
821 rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
822 rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
823 rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
824 rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
825
826 rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841);
827
828 rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2);
829
830 rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff);
831
832 rtlpci->reg_bcn_ctrl_val = 0x1f;
833 rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
834
835 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
836
837 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
838
839 rtl_write_byte(rtlpriv, REG_PIFS, 0x1C);
840 rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
841
842 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
843
844 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
845
846 rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666);
847
848 rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
849
850 rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010);
851 rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010);
852
853 rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010);
854
855 rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010);
856
857 rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff);
858 rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff);
859
860}
861
862static void _rtl92ce_enable_aspm_back_door(struct ieee80211_hw *hw)
863{
864 struct rtl_priv *rtlpriv = rtl_priv(hw);
865 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
866
867 rtl_write_byte(rtlpriv, 0x34b, 0x93);
868 rtl_write_word(rtlpriv, 0x350, 0x870c);
869 rtl_write_byte(rtlpriv, 0x352, 0x1);
870
871 if (ppsc->b_support_backdoor)
872 rtl_write_byte(rtlpriv, 0x349, 0x1b);
873 else
874 rtl_write_byte(rtlpriv, 0x349, 0x03);
875
876 rtl_write_word(rtlpriv, 0x350, 0x2718);
877 rtl_write_byte(rtlpriv, 0x352, 0x1);
878}
879
880void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw)
881{
882 struct rtl_priv *rtlpriv = rtl_priv(hw);
883 u8 sec_reg_value;
884
885 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
886 ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
887 rtlpriv->sec.pairwise_enc_algorithm,
888 rtlpriv->sec.group_enc_algorithm));
889
890 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
891 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("not open "
892 "hw encryption\n"));
893 return;
894 }
895
896 sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable;
897
898 if (rtlpriv->sec.use_defaultkey) {
899 sec_reg_value |= SCR_TxUseDK;
900 sec_reg_value |= SCR_RxUseDK;
901 }
902
903 sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
904
905 rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
906
907 RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
908 ("The SECR-value %x\n", sec_reg_value));
909
910 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
911
912}
913
914int rtl92ce_hw_init(struct ieee80211_hw *hw)
915{
916 struct rtl_priv *rtlpriv = rtl_priv(hw);
917 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
918 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
919 struct rtl_phy *rtlphy = &(rtlpriv->phy);
920 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
921 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
922 static bool iqk_initialized; /* initialized to false */
923 bool rtstatus = true;
924 bool is92c;
925 int err;
926 u8 tmp_u1b;
927
928 rtlpci->being_init_adapter = true;
929 rtlpriv->intf_ops->disable_aspm(hw);
930 rtstatus = _rtl92ce_init_mac(hw);
931 if (rtstatus != true) {
932 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n"));
933 err = 1;
934 return err;
935 }
936
937 err = rtl92c_download_fw(hw);
938 if (err) {
939 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
940 ("Failed to download FW. Init HW "
941 "without FW now..\n"));
942 err = 1;
943 rtlhal->bfw_ready = false;
944 return err;
945 } else {
946 rtlhal->bfw_ready = true;
947 }
948
949 rtlhal->last_hmeboxnum = 0;
950 rtl92c_phy_mac_config(hw);
951 rtl92c_phy_bb_config(hw);
952 rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
953 rtl92c_phy_rf_config(hw);
954 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
955 RF_CHNLBW, RFREG_OFFSET_MASK);
956 rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
957 RF_CHNLBW, RFREG_OFFSET_MASK);
958 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
959 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
960 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
961 _rtl92ce_hw_configure(hw);
962 rtl_cam_reset_all_entry(hw);
963 rtl92ce_enable_hw_security_config(hw);
964 ppsc->rfpwr_state = ERFON;
965 tmp_u1b = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG)&(~BIT(3));
966 rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, tmp_u1b);
967 tmp_u1b = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL);
968 ppsc->rfoff_reason |= (tmp_u1b & BIT(3)) ? 0 : RF_CHANGE_BY_HW;
969 if (ppsc->rfoff_reason > RF_CHANGE_BY_PS)
970 rtl_ps_set_rf_state(hw, ERFOFF, ppsc->rfoff_reason, true);
971 else {
972 ppsc->rfpwr_state = ERFON;
973 ppsc->rfoff_reason = 0;
974 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON);
975 }
976 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
977 _rtl92ce_enable_aspm_back_door(hw);
978 rtlpriv->intf_ops->enable_aspm(hw);
979 if (ppsc->rfpwr_state == ERFON) {
980 rtl92c_phy_set_rfpath_switch(hw, 1);
981 if (iqk_initialized)
982 rtl92c_phy_iq_calibrate(hw, true);
983 else {
984 rtl92c_phy_iq_calibrate(hw, false);
985 iqk_initialized = true;
986 }
987
988 rtl92c_dm_check_txpower_tracking(hw);
989 rtl92c_phy_lc_calibrate(hw);
990 }
991
992 is92c = IS_92C_SERIAL(rtlhal->version);
993 tmp_u1b = efuse_read_1byte(hw, 0x1FA);
994 if (!(tmp_u1b & BIT(0))) {
995 rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05);
996 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path A\n"));
997 }
998
999 if (!(tmp_u1b & BIT(1)) && is92c) {
1000 rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05);
1001 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path B\n"));
1002 }
1003
1004 if (!(tmp_u1b & BIT(4))) {
1005 tmp_u1b = rtl_read_byte(rtlpriv, 0x16);
1006 tmp_u1b &= 0x0F;
1007 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80);
1008 udelay(10);
1009 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90);
1010 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("under 1.5V\n"));
1011 }
1012 rtl92c_dm_init(hw);
1013 rtlpci->being_init_adapter = false;
1014 return err;
1015}
1016
1017static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw)
1018{
1019 struct rtl_priv *rtlpriv = rtl_priv(hw);
1020 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1021 enum version_8192c version = VERSION_UNKNOWN;
1022 u32 value32;
1023
1024 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
1025 if (value32 & TRP_VAUX_EN) {
1026 version = (value32 & TYPE_ID) ? VERSION_A_CHIP_92C :
1027 VERSION_A_CHIP_88C;
1028 } else {
1029 version = (value32 & TYPE_ID) ? VERSION_B_CHIP_92C :
1030 VERSION_B_CHIP_88C;
1031 }
1032
1033 switch (version) {
1034 case VERSION_B_CHIP_92C:
1035 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1036 ("Chip Version ID: VERSION_B_CHIP_92C.\n"));
1037 break;
1038 case VERSION_B_CHIP_88C:
1039 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1040 ("Chip Version ID: VERSION_B_CHIP_88C.\n"));
1041 break;
1042 case VERSION_A_CHIP_92C:
1043 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1044 ("Chip Version ID: VERSION_A_CHIP_92C.\n"));
1045 break;
1046 case VERSION_A_CHIP_88C:
1047 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1048 ("Chip Version ID: VERSION_A_CHIP_88C.\n"));
1049 break;
1050 default:
1051 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1052 ("Chip Version ID: Unknown. Bug?\n"));
1053 break;
1054 }
1055
1056 switch (version & 0x3) {
1057 case CHIP_88C:
1058 rtlphy->rf_type = RF_1T1R;
1059 break;
1060 case CHIP_92C:
1061 rtlphy->rf_type = RF_2T2R;
1062 break;
1063 case CHIP_92C_1T2R:
1064 rtlphy->rf_type = RF_1T2R;
1065 break;
1066 default:
1067 rtlphy->rf_type = RF_1T1R;
1068 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1069 ("ERROR RF_Type is set!!"));
1070 break;
1071 }
1072
1073 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1074 ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
1075 "RF_2T2R" : "RF_1T1R"));
1076
1077 return version;
1078}
1079
1080static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
1081 enum nl80211_iftype type)
1082{
1083 struct rtl_priv *rtlpriv = rtl_priv(hw);
1084 u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
1085 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
1086 bt_msr &= 0xfc;
1087
1088 if (type == NL80211_IFTYPE_UNSPECIFIED ||
1089 type == NL80211_IFTYPE_STATION) {
1090 _rtl92ce_stop_tx_beacon(hw);
1091 _rtl92ce_enable_bcn_sub_func(hw);
1092 } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) {
1093 _rtl92ce_resume_tx_beacon(hw);
1094 _rtl92ce_disable_bcn_sub_func(hw);
1095 } else {
1096 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1097 ("Set HW_VAR_MEDIA_STATUS: "
1098 "No such media status(%x).\n", type));
1099 }
1100
1101 switch (type) {
1102 case NL80211_IFTYPE_UNSPECIFIED:
1103 bt_msr |= MSR_NOLINK;
1104 ledaction = LED_CTL_LINK;
1105 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1106 ("Set Network type to NO LINK!\n"));
1107 break;
1108 case NL80211_IFTYPE_ADHOC:
1109 bt_msr |= MSR_ADHOC;
1110 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1111 ("Set Network type to Ad Hoc!\n"));
1112 break;
1113 case NL80211_IFTYPE_STATION:
1114 bt_msr |= MSR_INFRA;
1115 ledaction = LED_CTL_LINK;
1116 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1117 ("Set Network type to STA!\n"));
1118 break;
1119 case NL80211_IFTYPE_AP:
1120 bt_msr |= MSR_AP;
1121 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1122 ("Set Network type to AP!\n"));
1123 break;
1124 default:
1125 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1126 ("Network type %d not support!\n", type));
1127 return 1;
1128 break;
1129
1130 }
1131
1132 rtl_write_byte(rtlpriv, (MSR), bt_msr);
1133 rtlpriv->cfg->ops->led_control(hw, ledaction);
1134 if ((bt_msr & 0xfc) == MSR_AP)
1135 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1136 else
1137 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1138 return 0;
1139}
1140
1141static void _rtl92ce_set_check_bssid(struct ieee80211_hw *hw,
1142 enum nl80211_iftype type)
1143{
1144 struct rtl_priv *rtlpriv = rtl_priv(hw);
1145 u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
1146 u8 filterout_non_associated_bssid = false;
1147
1148 switch (type) {
1149 case NL80211_IFTYPE_ADHOC:
1150 case NL80211_IFTYPE_STATION:
1151 filterout_non_associated_bssid = true;
1152 break;
1153 case NL80211_IFTYPE_UNSPECIFIED:
1154 case NL80211_IFTYPE_AP:
1155 default:
1156 break;
1157 }
1158
1159 if (filterout_non_associated_bssid == true) {
1160 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1161 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1162 (u8 *) (&reg_rcr));
1163 _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4));
1164 } else if (filterout_non_associated_bssid == false) {
1165 reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1166 _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0);
1167 rtlpriv->cfg->ops->set_hw_reg(hw,
1168 HW_VAR_RCR, (u8 *) (&reg_rcr));
1169 }
1170}
1171
1172int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
1173{
1174 if (_rtl92ce_set_media_status(hw, type))
1175 return -EOPNOTSUPP;
1176 _rtl92ce_set_check_bssid(hw, type);
1177 return 0;
1178}
1179
1180void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci)
1181{
1182 struct rtl_priv *rtlpriv = rtl_priv(hw);
1183 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1184
1185 u32 u4b_ac_param;
1186
1187 rtl92c_dm_init_edca_turbo(hw);
1188
1189 u4b_ac_param = (u32) mac->ac[aci].aifs;
1190 u4b_ac_param |=
1191 ((u32) mac->ac[aci].cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET;
1192 u4b_ac_param |=
1193 ((u32) mac->ac[aci].cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET;
1194 u4b_ac_param |= (u32) mac->ac[aci].tx_op << AC_PARAM_TXOP_LIMIT_OFFSET;
1195 RT_TRACE(rtlpriv, COMP_QOS, DBG_DMESG,
1196 ("queue:%x, ac_param:%x aifs:%x cwmin:%x cwmax:%x txop:%x\n",
1197 aci, u4b_ac_param, mac->ac[aci].aifs, mac->ac[aci].cw_min,
1198 mac->ac[aci].cw_max, mac->ac[aci].tx_op));
1199 switch (aci) {
1200 case AC1_BK:
1201 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param);
1202 break;
1203 case AC0_BE:
1204 rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param);
1205 break;
1206 case AC2_VI:
1207 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, u4b_ac_param);
1208 break;
1209 case AC3_VO:
1210 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param);
1211 break;
1212 default:
1213 RT_ASSERT(false, ("invalid aci: %d !\n", aci));
1214 break;
1215 }
1216}
1217
1218void rtl92ce_enable_interrupt(struct ieee80211_hw *hw)
1219{
1220 struct rtl_priv *rtlpriv = rtl_priv(hw);
1221 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1222
1223 rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1224 rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1225 rtlpci->irq_enabled = true;
1226}
1227
1228void rtl92ce_disable_interrupt(struct ieee80211_hw *hw)
1229{
1230 struct rtl_priv *rtlpriv = rtl_priv(hw);
1231 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1232
1233 rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED);
1234 rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED);
1235 rtlpci->irq_enabled = false;
1236}
1237
1238static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
1239{
1240 struct rtl_priv *rtlpriv = rtl_priv(hw);
1241 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1242 u8 u1b_tmp;
1243
1244 rtlpriv->intf_ops->enable_aspm(hw);
1245 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1246 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1247 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
1248 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1249 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1250 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0);
1251 if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->bfw_ready)
1252 rtl92c_firmware_selfreset(hw);
1253 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51);
1254 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1255 rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000);
1256 u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL);
1257 rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 |
1258 (u1b_tmp << 8));
1259 rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790);
1260 rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080);
1261 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80);
1262 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);
1263 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e);
1264 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1265 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10);
1266}
1267
1268void rtl92ce_card_disable(struct ieee80211_hw *hw)
1269{
1270 struct rtl_priv *rtlpriv = rtl_priv(hw);
1271 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1272 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1273 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1274 enum nl80211_iftype opmode;
1275
1276 mac->link_state = MAC80211_NOLINK;
1277 opmode = NL80211_IFTYPE_UNSPECIFIED;
1278 _rtl92ce_set_media_status(hw, opmode);
1279 if (rtlpci->driver_is_goingto_unload ||
1280 ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1281 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1282 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1283 _rtl92ce_poweroff_adapter(hw);
1284}
1285
1286void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw,
1287 u32 *p_inta, u32 *p_intb)
1288{
1289 struct rtl_priv *rtlpriv = rtl_priv(hw);
1290 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1291
1292 *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
1293 rtl_write_dword(rtlpriv, ISR, *p_inta);
1294
1295 /*
1296 * *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1];
1297 * rtl_write_dword(rtlpriv, ISR + 4, *p_intb);
1298 */
1299}
1300
1301void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw)
1302{
1303
1304 struct rtl_priv *rtlpriv = rtl_priv(hw);
1305 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1306 u16 bcn_interval, atim_window;
1307
1308 bcn_interval = mac->beacon_interval;
1309 atim_window = 2; /*FIX MERGE */
1310 rtl92ce_disable_interrupt(hw);
1311 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1312 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1313 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1314 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
1315 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
1316 rtl_write_byte(rtlpriv, 0x606, 0x30);
1317 rtl92ce_enable_interrupt(hw);
1318}
1319
1320void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw)
1321{
1322 struct rtl_priv *rtlpriv = rtl_priv(hw);
1323 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1324 u16 bcn_interval = mac->beacon_interval;
1325
1326 RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
1327 ("beacon_interval:%d\n", bcn_interval));
1328 rtl92ce_disable_interrupt(hw);
1329 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1330 rtl92ce_enable_interrupt(hw);
1331}
1332
1333void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
1334 u32 add_msr, u32 rm_msr)
1335{
1336 struct rtl_priv *rtlpriv = rtl_priv(hw);
1337 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1338
1339 RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
1340 ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
1341 if (add_msr)
1342 rtlpci->irq_mask[0] |= add_msr;
1343 if (rm_msr)
1344 rtlpci->irq_mask[0] &= (~rm_msr);
1345 rtl92ce_disable_interrupt(hw);
1346 rtl92ce_enable_interrupt(hw);
1347}
1348
1349static u8 _rtl92c_get_chnl_group(u8 chnl)
1350{
1351 u8 group;
1352
1353 if (chnl < 3)
1354 group = 0;
1355 else if (chnl < 9)
1356 group = 1;
1357 else
1358 group = 2;
1359 return group;
1360}
1361
1362static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1363 bool autoload_fail,
1364 u8 *hwinfo)
1365{
1366 struct rtl_priv *rtlpriv = rtl_priv(hw);
1367 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1368 u8 rf_path, index, tempval;
1369 u16 i;
1370
1371 for (rf_path = 0; rf_path < 2; rf_path++) {
1372 for (i = 0; i < 3; i++) {
1373 if (!autoload_fail) {
1374 rtlefuse->
1375 eeprom_chnlarea_txpwr_cck[rf_path][i] =
1376 hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i];
1377 rtlefuse->
1378 eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] =
1379 hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 +
1380 i];
1381 } else {
1382 rtlefuse->
1383 eeprom_chnlarea_txpwr_cck[rf_path][i] =
1384 EEPROM_DEFAULT_TXPOWERLEVEL;
1385 rtlefuse->
1386 eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] =
1387 EEPROM_DEFAULT_TXPOWERLEVEL;
1388 }
1389 }
1390 }
1391
1392 for (i = 0; i < 3; i++) {
1393 if (!autoload_fail)
1394 tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i];
1395 else
1396 tempval = EEPROM_DEFAULT_HT40_2SDIFF;
1397 rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] =
1398 (tempval & 0xf);
1399 rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] =
1400 ((tempval & 0xf0) >> 4);
1401 }
1402
1403 for (rf_path = 0; rf_path < 2; rf_path++)
1404 for (i = 0; i < 3; i++)
1405 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1406 ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path,
1407 i,
1408 rtlefuse->
1409 eeprom_chnlarea_txpwr_cck[rf_path][i]));
1410 for (rf_path = 0; rf_path < 2; rf_path++)
1411 for (i = 0; i < 3; i++)
1412 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1413 ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
1414 rf_path, i,
1415 rtlefuse->
1416 eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]));
1417 for (rf_path = 0; rf_path < 2; rf_path++)
1418 for (i = 0; i < 3; i++)
1419 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1420 ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
1421 rf_path, i,
1422 rtlefuse->
1423 eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path]
1424 [i]));
1425
1426 for (rf_path = 0; rf_path < 2; rf_path++) {
1427 for (i = 0; i < 14; i++) {
1428 index = _rtl92c_get_chnl_group((u8) i);
1429
1430 rtlefuse->txpwrlevel_cck[rf_path][i] =
1431 rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][index];
1432 rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1433 rtlefuse->
1434 eeprom_chnlarea_txpwr_ht40_1s[rf_path][index];
1435
1436 if ((rtlefuse->
1437 eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] -
1438 rtlefuse->
1439 eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index])
1440 > 0) {
1441 rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
1442 rtlefuse->
1443 eeprom_chnlarea_txpwr_ht40_1s[rf_path]
1444 [index] -
1445 rtlefuse->
1446 eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path]
1447 [index];
1448 } else {
1449 rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0;
1450 }
1451 }
1452
1453 for (i = 0; i < 14; i++) {
1454 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1455 ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
1456 "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
1457 rtlefuse->txpwrlevel_cck[rf_path][i],
1458 rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
1459 rtlefuse->txpwrlevel_ht40_2s[rf_path][i]));
1460 }
1461 }
1462
1463 for (i = 0; i < 3; i++) {
1464 if (!autoload_fail) {
1465 rtlefuse->eeprom_pwrlimit_ht40[i] =
1466 hwinfo[EEPROM_TXPWR_GROUP + i];
1467 rtlefuse->eeprom_pwrlimit_ht20[i] =
1468 hwinfo[EEPROM_TXPWR_GROUP + 3 + i];
1469 } else {
1470 rtlefuse->eeprom_pwrlimit_ht40[i] = 0;
1471 rtlefuse->eeprom_pwrlimit_ht20[i] = 0;
1472 }
1473 }
1474
1475 for (rf_path = 0; rf_path < 2; rf_path++) {
1476 for (i = 0; i < 14; i++) {
1477 index = _rtl92c_get_chnl_group((u8) i);
1478
1479 if (rf_path == RF90_PATH_A) {
1480 rtlefuse->pwrgroup_ht20[rf_path][i] =
1481 (rtlefuse->eeprom_pwrlimit_ht20[index]
1482 & 0xf);
1483 rtlefuse->pwrgroup_ht40[rf_path][i] =
1484 (rtlefuse->eeprom_pwrlimit_ht40[index]
1485 & 0xf);
1486 } else if (rf_path == RF90_PATH_B) {
1487 rtlefuse->pwrgroup_ht20[rf_path][i] =
1488 ((rtlefuse->eeprom_pwrlimit_ht20[index]
1489 & 0xf0) >> 4);
1490 rtlefuse->pwrgroup_ht40[rf_path][i] =
1491 ((rtlefuse->eeprom_pwrlimit_ht40[index]
1492 & 0xf0) >> 4);
1493 }
1494
1495 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1496 ("RF-%d pwrgroup_ht20[%d] = 0x%x\n",
1497 rf_path, i,
1498 rtlefuse->pwrgroup_ht20[rf_path][i]));
1499 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1500 ("RF-%d pwrgroup_ht40[%d] = 0x%x\n",
1501 rf_path, i,
1502 rtlefuse->pwrgroup_ht40[rf_path][i]));
1503 }
1504 }
1505
1506 for (i = 0; i < 14; i++) {
1507 index = _rtl92c_get_chnl_group((u8) i);
1508
1509 if (!autoload_fail)
1510 tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index];
1511 else
1512 tempval = EEPROM_DEFAULT_HT20_DIFF;
1513
1514 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF);
1515 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] =
1516 ((tempval >> 4) & 0xF);
1517
1518 if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3))
1519 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0;
1520
1521 if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3))
1522 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0;
1523
1524 index = _rtl92c_get_chnl_group((u8) i);
1525
1526 if (!autoload_fail)
1527 tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index];
1528 else
1529 tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF;
1530
1531 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF);
1532 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] =
1533 ((tempval >> 4) & 0xF);
1534 }
1535
1536 rtlefuse->legacy_ht_txpowerdiff =
1537 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7];
1538
1539 for (i = 0; i < 14; i++)
1540 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1541 ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
1542 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]));
1543 for (i = 0; i < 14; i++)
1544 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1545 ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
1546 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]));
1547 for (i = 0; i < 14; i++)
1548 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1549 ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
1550 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]));
1551 for (i = 0; i < 14; i++)
1552 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1553 ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
1554 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]));
1555
1556 if (!autoload_fail)
1557 rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7);
1558 else
1559 rtlefuse->eeprom_regulatory = 0;
1560 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1561 ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
1562
1563 if (!autoload_fail) {
1564 rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A];
1565 rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B];
1566 } else {
1567 rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI;
1568 rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI;
1569 }
1570 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1571 ("TSSI_A = 0x%x, TSSI_B = 0x%x\n",
1572 rtlefuse->eeprom_tssi[RF90_PATH_A],
1573 rtlefuse->eeprom_tssi[RF90_PATH_B]));
1574
1575 if (!autoload_fail)
1576 tempval = hwinfo[EEPROM_THERMAL_METER];
1577 else
1578 tempval = EEPROM_DEFAULT_THERMALMETER;
1579 rtlefuse->eeprom_thermalmeter = (tempval & 0x1f);
1580
1581 if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail)
1582 rtlefuse->b_apk_thermalmeterignore = true;
1583
1584 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
1585 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1586 ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter));
1587}
1588
1589static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
1590{
1591 struct rtl_priv *rtlpriv = rtl_priv(hw);
1592 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1593 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1594 u16 i, usvalue;
1595 u8 hwinfo[HWSET_MAX_SIZE];
1596 u16 eeprom_id;
1597
1598 if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
1599 rtl_efuse_shadow_map_update(hw);
1600
1601 memcpy((void *)hwinfo,
1602 (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
1603 HWSET_MAX_SIZE);
1604 } else if (rtlefuse->epromtype == EEPROM_93C46) {
1605 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1606 ("RTL819X Not boot from eeprom, check it !!"));
1607 }
1608
1609 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"),
1610 hwinfo, HWSET_MAX_SIZE);
1611
1612 eeprom_id = *((u16 *)&hwinfo[0]);
1613 if (eeprom_id != RTL8190_EEPROM_ID) {
1614 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1615 ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
1616 rtlefuse->autoload_failflag = true;
1617 } else {
1618 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
1619 rtlefuse->autoload_failflag = false;
1620 }
1621
1622 if (rtlefuse->autoload_failflag == true)
1623 return;
1624
1625 for (i = 0; i < 6; i += 2) {
1626 usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
1627 *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
1628 }
1629
1630 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1631 (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr)));
1632
1633 _rtl92ce_read_txpower_info_from_hwpg(hw,
1634 rtlefuse->autoload_failflag,
1635 hwinfo);
1636
1637 rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
1638 rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
1639 rtlefuse->b_txpwr_fromeprom = true;
1640 rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
1641
1642 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1643 ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid));
1644
1645 if (rtlhal->oem_id == RT_CID_DEFAULT) {
1646 switch (rtlefuse->eeprom_oemid) {
1647 case EEPROM_CID_DEFAULT:
1648 if (rtlefuse->eeprom_did == 0x8176) {
1649 if ((rtlefuse->eeprom_svid == 0x103C &&
1650 rtlefuse->eeprom_smid == 0x1629))
1651 rtlhal->oem_id = RT_CID_819x_HP;
1652 else
1653 rtlhal->oem_id = RT_CID_DEFAULT;
1654 } else {
1655 rtlhal->oem_id = RT_CID_DEFAULT;
1656 }
1657 break;
1658 case EEPROM_CID_TOSHIBA:
1659 rtlhal->oem_id = RT_CID_TOSHIBA;
1660 break;
1661 case EEPROM_CID_QMI:
1662 rtlhal->oem_id = RT_CID_819x_QMI;
1663 break;
1664 case EEPROM_CID_WHQL:
1665 default:
1666 rtlhal->oem_id = RT_CID_DEFAULT;
1667 break;
1668
1669 }
1670 }
1671
1672}
1673
1674static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw)
1675{
1676 struct rtl_priv *rtlpriv = rtl_priv(hw);
1677 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1678 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1679
1680 switch (rtlhal->oem_id) {
1681 case RT_CID_819x_HP:
1682 pcipriv->ledctl.bled_opendrain = true;
1683 break;
1684 case RT_CID_819x_Lenovo:
1685 case RT_CID_DEFAULT:
1686 case RT_CID_TOSHIBA:
1687 case RT_CID_CCX:
1688 case RT_CID_819x_Acer:
1689 case RT_CID_WHQL:
1690 default:
1691 break;
1692 }
1693 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1694 ("RT Customized ID: 0x%02X\n", rtlhal->oem_id));
1695}
1696
1697void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw)
1698{
1699 struct rtl_priv *rtlpriv = rtl_priv(hw);
1700 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1701 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1702 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1703 u8 tmp_u1b;
1704
1705 rtlhal->version = _rtl92ce_read_chip_version(hw);
1706 if (get_rf_type(rtlphy) == RF_1T1R)
1707 rtlpriv->dm.brfpath_rxenable[0] = true;
1708 else
1709 rtlpriv->dm.brfpath_rxenable[0] =
1710 rtlpriv->dm.brfpath_rxenable[1] = true;
1711 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n",
1712 rtlhal->version));
1713 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
1714 if (tmp_u1b & BIT(4)) {
1715 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n"));
1716 rtlefuse->epromtype = EEPROM_93C46;
1717 } else {
1718 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n"));
1719 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
1720 }
1721 if (tmp_u1b & BIT(5)) {
1722 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
1723 rtlefuse->autoload_failflag = false;
1724 _rtl92ce_read_adapter_info(hw);
1725 } else {
1726 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
1727 }
1728
1729 _rtl92ce_hal_customized_behavior(hw);
1730}
1731
1732void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw)
1733{
1734 struct rtl_priv *rtlpriv = rtl_priv(hw);
1735 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1736 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1737
1738 u32 ratr_value = (u32) mac->basic_rates;
1739 u8 *p_mcsrate = mac->mcs;
1740 u8 ratr_index = 0;
1741 u8 b_nmode = mac->ht_enable;
1742 u8 mimo_ps = 1;
1743 u16 shortgi_rate;
1744 u32 tmp_ratr_value;
1745 u8 b_curtxbw_40mhz = mac->bw_40;
1746 u8 b_curshortgi_40mhz = mac->sgi_40;
1747 u8 b_curshortgi_20mhz = mac->sgi_20;
1748 enum wireless_mode wirelessmode = mac->mode;
1749
1750 ratr_value |= EF2BYTE((*(u16 *) (p_mcsrate))) << 12;
1751
1752 switch (wirelessmode) {
1753 case WIRELESS_MODE_B:
1754 if (ratr_value & 0x0000000c)
1755 ratr_value &= 0x0000000d;
1756 else
1757 ratr_value &= 0x0000000f;
1758 break;
1759 case WIRELESS_MODE_G:
1760 ratr_value &= 0x00000FF5;
1761 break;
1762 case WIRELESS_MODE_N_24G:
1763 case WIRELESS_MODE_N_5G:
1764 b_nmode = 1;
1765 if (mimo_ps == 0) {
1766 ratr_value &= 0x0007F005;
1767 } else {
1768 u32 ratr_mask;
1769
1770 if (get_rf_type(rtlphy) == RF_1T2R ||
1771 get_rf_type(rtlphy) == RF_1T1R)
1772 ratr_mask = 0x000ff005;
1773 else
1774 ratr_mask = 0x0f0ff005;
1775
1776 ratr_value &= ratr_mask;
1777 }
1778 break;
1779 default:
1780 if (rtlphy->rf_type == RF_1T2R)
1781 ratr_value &= 0x000ff0ff;
1782 else
1783 ratr_value &= 0x0f0ff0ff;
1784
1785 break;
1786 }
1787
1788 ratr_value &= 0x0FFFFFFF;
1789
1790 if (b_nmode && ((b_curtxbw_40mhz &&
1791 b_curshortgi_40mhz) || (!b_curtxbw_40mhz &&
1792 b_curshortgi_20mhz))) {
1793
1794 ratr_value |= 0x10000000;
1795 tmp_ratr_value = (ratr_value >> 12);
1796
1797 for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
1798 if ((1 << shortgi_rate) & tmp_ratr_value)
1799 break;
1800 }
1801
1802 shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
1803 (shortgi_rate << 4) | (shortgi_rate);
1804 }
1805
1806 rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
1807
1808 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
1809 ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)));
1810}
1811
1812void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
1813{
1814 struct rtl_priv *rtlpriv = rtl_priv(hw);
1815 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1816 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1817 u32 ratr_bitmap = (u32) mac->basic_rates;
1818 u8 *p_mcsrate = mac->mcs;
1819 u8 ratr_index;
1820 u8 b_curtxbw_40mhz = mac->bw_40;
1821 u8 b_curshortgi_40mhz = mac->sgi_40;
1822 u8 b_curshortgi_20mhz = mac->sgi_20;
1823 enum wireless_mode wirelessmode = mac->mode;
1824 bool b_shortgi = false;
1825 u8 rate_mask[5];
1826 u8 macid = 0;
1827 u8 mimops = 1;
1828
1829 ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12);
1830 switch (wirelessmode) {
1831 case WIRELESS_MODE_B:
1832 ratr_index = RATR_INX_WIRELESS_B;
1833 if (ratr_bitmap & 0x0000000c)
1834 ratr_bitmap &= 0x0000000d;
1835 else
1836 ratr_bitmap &= 0x0000000f;
1837 break;
1838 case WIRELESS_MODE_G:
1839 ratr_index = RATR_INX_WIRELESS_GB;
1840
1841 if (rssi_level == 1)
1842 ratr_bitmap &= 0x00000f00;
1843 else if (rssi_level == 2)
1844 ratr_bitmap &= 0x00000ff0;
1845 else
1846 ratr_bitmap &= 0x00000ff5;
1847 break;
1848 case WIRELESS_MODE_A:
1849 ratr_index = RATR_INX_WIRELESS_A;
1850 ratr_bitmap &= 0x00000ff0;
1851 break;
1852 case WIRELESS_MODE_N_24G:
1853 case WIRELESS_MODE_N_5G:
1854 ratr_index = RATR_INX_WIRELESS_NGB;
1855
1856 if (mimops == 0) {
1857 if (rssi_level == 1)
1858 ratr_bitmap &= 0x00070000;
1859 else if (rssi_level == 2)
1860 ratr_bitmap &= 0x0007f000;
1861 else
1862 ratr_bitmap &= 0x0007f005;
1863 } else {
1864 if (rtlphy->rf_type == RF_1T2R ||
1865 rtlphy->rf_type == RF_1T1R) {
1866 if (b_curtxbw_40mhz) {
1867 if (rssi_level == 1)
1868 ratr_bitmap &= 0x000f0000;
1869 else if (rssi_level == 2)
1870 ratr_bitmap &= 0x000ff000;
1871 else
1872 ratr_bitmap &= 0x000ff015;
1873 } else {
1874 if (rssi_level == 1)
1875 ratr_bitmap &= 0x000f0000;
1876 else if (rssi_level == 2)
1877 ratr_bitmap &= 0x000ff000;
1878 else
1879 ratr_bitmap &= 0x000ff005;
1880 }
1881 } else {
1882 if (b_curtxbw_40mhz) {
1883 if (rssi_level == 1)
1884 ratr_bitmap &= 0x0f0f0000;
1885 else if (rssi_level == 2)
1886 ratr_bitmap &= 0x0f0ff000;
1887 else
1888 ratr_bitmap &= 0x0f0ff015;
1889 } else {
1890 if (rssi_level == 1)
1891 ratr_bitmap &= 0x0f0f0000;
1892 else if (rssi_level == 2)
1893 ratr_bitmap &= 0x0f0ff000;
1894 else
1895 ratr_bitmap &= 0x0f0ff005;
1896 }
1897 }
1898 }
1899
1900 if ((b_curtxbw_40mhz && b_curshortgi_40mhz) ||
1901 (!b_curtxbw_40mhz && b_curshortgi_20mhz)) {
1902
1903 if (macid == 0)
1904 b_shortgi = true;
1905 else if (macid == 1)
1906 b_shortgi = false;
1907 }
1908 break;
1909 default:
1910 ratr_index = RATR_INX_WIRELESS_NGB;
1911
1912 if (rtlphy->rf_type == RF_1T2R)
1913 ratr_bitmap &= 0x000ff0ff;
1914 else
1915 ratr_bitmap &= 0x0f0ff0ff;
1916 break;
1917 }
1918 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
1919 ("ratr_bitmap :%x\n", ratr_bitmap));
1920 *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) |
1921 (ratr_index << 28));
1922 rate_mask[4] = macid | (b_shortgi ? 0x20 : 0x00) | 0x80;
1923 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, "
1924 "ratr_val:%x, %x:%x:%x:%x:%x\n",
1925 ratr_index, ratr_bitmap,
1926 rate_mask[0], rate_mask[1],
1927 rate_mask[2], rate_mask[3],
1928 rate_mask[4]));
1929 rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
1930}
1931
1932void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw)
1933{
1934 struct rtl_priv *rtlpriv = rtl_priv(hw);
1935 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1936 u16 sifs_timer;
1937
1938 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
1939 (u8 *)&mac->slot_time);
1940 if (!mac->ht_enable)
1941 sifs_timer = 0x0a0a;
1942 else
1943 sifs_timer = 0x1010;
1944 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
1945}
1946
1947bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
1948{
1949 struct rtl_priv *rtlpriv = rtl_priv(hw);
1950 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1951 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1952 enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
1953 u8 u1tmp;
1954 bool b_actuallyset = false;
1955 unsigned long flag;
1956
1957 if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter))
1958 return false;
1959
1960 if (ppsc->b_swrf_processing)
1961 return false;
1962
1963 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
1964 if (ppsc->rfchange_inprogress) {
1965 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
1966 return false;
1967 } else {
1968 ppsc->rfchange_inprogress = true;
1969 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
1970 }
1971
1972 cur_rfstate = ppsc->rfpwr_state;
1973
1974 if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
1975 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) {
1976 rtlpriv->intf_ops->disable_aspm(hw);
1977 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
1978 }
1979
1980 rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv,
1981 REG_MAC_PINMUX_CFG)&~(BIT(3)));
1982
1983 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL);
1984 e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF;
1985
1986 if ((ppsc->b_hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) {
1987 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1988 ("GPIOChangeRF - HW Radio ON, RF ON\n"));
1989
1990 e_rfpowerstate_toset = ERFON;
1991 ppsc->b_hwradiooff = false;
1992 b_actuallyset = true;
1993 } else if ((ppsc->b_hwradiooff == false)
1994 && (e_rfpowerstate_toset == ERFOFF)) {
1995 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
1996 ("GPIOChangeRF - HW Radio OFF, RF OFF\n"));
1997
1998 e_rfpowerstate_toset = ERFOFF;
1999 ppsc->b_hwradiooff = true;
2000 b_actuallyset = true;
2001 }
2002
2003 if (b_actuallyset) {
2004 if (e_rfpowerstate_toset == ERFON) {
2005 if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
2006 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) {
2007 rtlpriv->intf_ops->disable_aspm(hw);
2008 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
2009 }
2010 }
2011
2012 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
2013 ppsc->rfchange_inprogress = false;
2014 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2015
2016 if (e_rfpowerstate_toset == ERFOFF) {
2017 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
2018 rtlpriv->intf_ops->enable_aspm(hw);
2019 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
2020 }
2021 }
2022
2023 } else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) {
2024 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2025 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2026
2027 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
2028 rtlpriv->intf_ops->enable_aspm(hw);
2029 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
2030 }
2031
2032 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
2033 ppsc->rfchange_inprogress = false;
2034 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2035 } else {
2036 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
2037 ppsc->rfchange_inprogress = false;
2038 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2039 }
2040
2041 *valid = 1;
2042 return !ppsc->b_hwradiooff;
2043
2044}
2045
2046void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
2047 u8 *p_macaddr, bool is_group, u8 enc_algo,
2048 bool is_wepkey, bool clear_all)
2049{
2050 struct rtl_priv *rtlpriv = rtl_priv(hw);
2051 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2052 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2053 u8 *macaddr = p_macaddr;
2054 u32 entry_id = 0;
2055 bool is_pairwise = false;
2056
2057 static u8 cam_const_addr[4][6] = {
2058 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2059 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2060 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2061 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2062 };
2063 static u8 cam_const_broad[] = {
2064 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2065 };
2066
2067 if (clear_all) {
2068 u8 idx = 0;
2069 u8 cam_offset = 0;
2070 u8 clear_number = 5;
2071
2072 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
2073
2074 for (idx = 0; idx < clear_number; idx++) {
2075 rtl_cam_mark_invalid(hw, cam_offset + idx);
2076 rtl_cam_empty_entry(hw, cam_offset + idx);
2077
2078 if (idx < 5) {
2079 memset(rtlpriv->sec.key_buf[idx], 0,
2080 MAX_KEY_LEN);
2081 rtlpriv->sec.key_len[idx] = 0;
2082 }
2083 }
2084
2085 } else {
2086 switch (enc_algo) {
2087 case WEP40_ENCRYPTION:
2088 enc_algo = CAM_WEP40;
2089 break;
2090 case WEP104_ENCRYPTION:
2091 enc_algo = CAM_WEP104;
2092 break;
2093 case TKIP_ENCRYPTION:
2094 enc_algo = CAM_TKIP;
2095 break;
2096 case AESCCMP_ENCRYPTION:
2097 enc_algo = CAM_AES;
2098 break;
2099 default:
2100 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
2101 "not process\n"));
2102 enc_algo = CAM_TKIP;
2103 break;
2104 }
2105
2106 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2107 macaddr = cam_const_addr[key_index];
2108 entry_id = key_index;
2109 } else {
2110 if (is_group) {
2111 macaddr = cam_const_broad;
2112 entry_id = key_index;
2113 } else {
2114 key_index = PAIRWISE_KEYIDX;
2115 entry_id = CAM_PAIRWISE_KEY_POSITION;
2116 is_pairwise = true;
2117 }
2118 }
2119
2120 if (rtlpriv->sec.key_len[key_index] == 0) {
2121 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2122 ("delete one entry\n"));
2123 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2124 } else {
2125 RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
2126 ("The insert KEY length is %d\n",
2127 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
2128 RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
2129 ("The insert KEY is %x %x\n",
2130 rtlpriv->sec.key_buf[0][0],
2131 rtlpriv->sec.key_buf[0][1]));
2132
2133 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2134 ("add one entry\n"));
2135 if (is_pairwise) {
2136 RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
2137 "Pairwiase Key content :",
2138 rtlpriv->sec.pairwise_key,
2139 rtlpriv->sec.
2140 key_len[PAIRWISE_KEYIDX]);
2141
2142 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2143 ("set Pairwiase key\n"));
2144
2145 rtl_cam_add_one_entry(hw, macaddr, key_index,
2146 entry_id, enc_algo,
2147 CAM_CONFIG_NO_USEDK,
2148 rtlpriv->sec.
2149 key_buf[key_index]);
2150 } else {
2151 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2152 ("set group key\n"));
2153
2154 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2155 rtl_cam_add_one_entry(hw,
2156 rtlefuse->dev_addr,
2157 PAIRWISE_KEYIDX,
2158 CAM_PAIRWISE_KEY_POSITION,
2159 enc_algo,
2160 CAM_CONFIG_NO_USEDK,
2161 rtlpriv->sec.key_buf
2162 [entry_id]);
2163 }
2164
2165 rtl_cam_add_one_entry(hw, macaddr, key_index,
2166 entry_id, enc_algo,
2167 CAM_CONFIG_NO_USEDK,
2168 rtlpriv->sec.key_buf[entry_id]);
2169 }
2170
2171 }
2172 }
2173}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h
new file mode 100644
index 00000000000..305c819c8c7
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-hw.h
@@ -0,0 +1,57 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92CE_HW_H__
31#define __RTL92CE_HW_H__
32
33void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
34void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw);
35void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw,
36 u32 *p_inta, u32 *p_intb);
37int rtl92ce_hw_init(struct ieee80211_hw *hw);
38void rtl92ce_card_disable(struct ieee80211_hw *hw);
39void rtl92ce_enable_interrupt(struct ieee80211_hw *hw);
40void rtl92ce_disable_interrupt(struct ieee80211_hw *hw);
41int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
42void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci);
43void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw);
44void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw);
45void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
46 u32 add_msr, u32 rm_msr);
47void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
48void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw);
49void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);
50void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw);
51bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
52void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw);
53void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
54 u8 *p_macaddr, bool is_group, u8 enc_algo,
55 bool is_wepkey, bool clear_all);
56
57#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c
new file mode 100644
index 00000000000..60910842157
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.c
@@ -0,0 +1,144 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "rtl8192c-reg.h"
33#include "rtl8192c-led.h"
34
35void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
36{
37 u8 ledcfg;
38 struct rtl_priv *rtlpriv = rtl_priv(hw);
39
40 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
41 ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
42
43 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
44
45 switch (pled->ledpin) {
46 case LED_PIN_GPIO0:
47 break;
48 case LED_PIN_LED0:
49 rtl_write_byte(rtlpriv,
50 REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6));
51 break;
52 case LED_PIN_LED1:
53 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5));
54 break;
55 default:
56 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
57 ("switch case not process\n"));
58 break;
59 }
60 pled->b_ledon = true;
61}
62
63void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
64{
65 struct rtl_priv *rtlpriv = rtl_priv(hw);
66 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
67 u8 ledcfg;
68
69 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
70 ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
71
72 ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
73
74 switch (pled->ledpin) {
75 case LED_PIN_GPIO0:
76 break;
77 case LED_PIN_LED0:
78 ledcfg &= 0xf0;
79 if (pcipriv->ledctl.bled_opendrain == true)
80 rtl_write_byte(rtlpriv, REG_LEDCFG2,
81 (ledcfg | BIT(1) | BIT(5) | BIT(6)));
82 else
83 rtl_write_byte(rtlpriv, REG_LEDCFG2,
84 (ledcfg | BIT(3) | BIT(5) | BIT(6)));
85 break;
86 case LED_PIN_LED1:
87 ledcfg &= 0x0f;
88 rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3)));
89 break;
90 default:
91 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
92 ("switch case not process\n"));
93 break;
94 }
95 pled->b_ledon = false;
96}
97
98void rtl92ce_init_sw_leds(struct ieee80211_hw *hw)
99{
100}
101
102void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw)
103{
104}
105
106void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
107 enum led_ctl_mode ledaction)
108{
109 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
110 struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
111 switch (ledaction) {
112 case LED_CTL_POWER_ON:
113 case LED_CTL_LINK:
114 case LED_CTL_NO_LINK:
115 rtl92ce_sw_led_on(hw, pLed0);
116 break;
117 case LED_CTL_POWER_OFF:
118 rtl92ce_sw_led_off(hw, pLed0);
119 break;
120 default:
121 break;
122 }
123}
124
125void rtl92ce_led_control(struct ieee80211_hw *hw,
126 enum led_ctl_mode ledaction)
127{
128 struct rtl_priv *rtlpriv = rtl_priv(hw);
129 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
130
131 if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
132 (ledaction == LED_CTL_TX ||
133 ledaction == LED_CTL_RX ||
134 ledaction == LED_CTL_SITE_SURVEY ||
135 ledaction == LED_CTL_LINK ||
136 ledaction == LED_CTL_NO_LINK ||
137 ledaction == LED_CTL_START_TO_LINK ||
138 ledaction == LED_CTL_POWER_ON)) {
139 return;
140 }
141 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n",
142 ledaction));
143 _rtl92ce_sw_led_control(hw, ledaction);
144}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h
new file mode 100644
index 00000000000..10da3018f4b
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-led.h
@@ -0,0 +1,41 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92CE_LED_H__
31#define __RTL92CE_LED_H__
32
33void rtl92ce_init_sw_leds(struct ieee80211_hw *hw);
34void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw);
35void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
36void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
37void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
38void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
39 enum led_ctl_mode ledaction);
40
41#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c
new file mode 100644
index 00000000000..13d7b387a96
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.c
@@ -0,0 +1,2676 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "../ps.h"
33#include "rtl8192c-reg.h"
34#include "rtl8192c-def.h"
35#include "rtl8192c-phy.h"
36#include "rtl8192c-rf.h"
37#include "rtl8192c-dm.h"
38#include "rtl8192c-table.h"
39
40static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
41 enum radio_path rfpath, u32 offset);
42static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
43 enum radio_path rfpath, u32 offset,
44 u32 data);
45static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
46 enum radio_path rfpath, u32 offset);
47static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
48 enum radio_path rfpath, u32 offset,
49 u32 data);
50static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask);
51static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
52static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
53static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
54 u8 configtype);
55static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
56 u8 configtype);
57static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
58static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
59 u32 cmdtableidx, u32 cmdtablesz,
60 enum swchnlcmd_id cmdid, u32 para1,
61 u32 para2, u32 msdelay);
62static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
63 u8 channel, u8 *stage, u8 *step,
64 u32 *delay);
65static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
66 enum wireless_mode wirelessmode,
67 long power_indbm);
68static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw,
69 enum radio_path rfpath);
70static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
71 enum wireless_mode wirelessmode,
72 u8 txpwridx);
73u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
74{
75 struct rtl_priv *rtlpriv = rtl_priv(hw);
76 u32 returnvalue, originalvalue, bitshift;
77
78 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
79 "bitmask(%#x)\n", regaddr,
80 bitmask));
81 originalvalue = rtl_read_dword(rtlpriv, regaddr);
82 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
83 returnvalue = (originalvalue & bitmask) >> bitshift;
84
85 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x "
86 "Addr[0x%x]=0x%x\n", bitmask,
87 regaddr, originalvalue));
88
89 return returnvalue;
90
91}
92
93void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
94 u32 regaddr, u32 bitmask, u32 data)
95{
96 struct rtl_priv *rtlpriv = rtl_priv(hw);
97 u32 originalvalue, bitshift;
98
99 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
100 " data(%#x)\n", regaddr, bitmask,
101 data));
102
103 if (bitmask != MASKDWORD) {
104 originalvalue = rtl_read_dword(rtlpriv, regaddr);
105 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
106 data = ((originalvalue & (~bitmask)) | (data << bitshift));
107 }
108
109 rtl_write_dword(rtlpriv, regaddr, data);
110
111 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
112 " data(%#x)\n", regaddr, bitmask,
113 data));
114
115}
116
117u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
118 enum radio_path rfpath, u32 regaddr, u32 bitmask)
119{
120 struct rtl_priv *rtlpriv = rtl_priv(hw);
121 u32 original_value, readback_value, bitshift;
122 struct rtl_phy *rtlphy = &(rtlpriv->phy);
123 unsigned long flags;
124
125 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
126 "rfpath(%#x), bitmask(%#x)\n",
127 regaddr, rfpath, bitmask));
128
129 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
130
131 if (rtlphy->rf_mode != RF_OP_BY_FW) {
132 original_value = _rtl92c_phy_rf_serial_read(hw,
133 rfpath, regaddr);
134 } else {
135 original_value = _rtl92c_phy_fw_rf_serial_read(hw,
136 rfpath, regaddr);
137 }
138
139 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
140 readback_value = (original_value & bitmask) >> bitshift;
141
142 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
143
144 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
145 ("regaddr(%#x), rfpath(%#x), "
146 "bitmask(%#x), original_value(%#x)\n",
147 regaddr, rfpath, bitmask, original_value));
148
149 return readback_value;
150}
151
152void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw,
153 enum radio_path rfpath,
154 u32 regaddr, u32 bitmask, u32 data)
155{
156 struct rtl_priv *rtlpriv = rtl_priv(hw);
157 struct rtl_phy *rtlphy = &(rtlpriv->phy);
158 u32 original_value, bitshift;
159 unsigned long flags;
160
161 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
162 ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
163 regaddr, bitmask, data, rfpath));
164
165 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
166
167 if (rtlphy->rf_mode != RF_OP_BY_FW) {
168 if (bitmask != RFREG_OFFSET_MASK) {
169 original_value = _rtl92c_phy_rf_serial_read(hw,
170 rfpath,
171 regaddr);
172 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
173 data =
174 ((original_value & (~bitmask)) |
175 (data << bitshift));
176 }
177
178 _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data);
179 } else {
180 if (bitmask != RFREG_OFFSET_MASK) {
181 original_value = _rtl92c_phy_fw_rf_serial_read(hw,
182 rfpath,
183 regaddr);
184 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
185 data =
186 ((original_value & (~bitmask)) |
187 (data << bitshift));
188 }
189 _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
190 }
191
192 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
193
194 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
195 "bitmask(%#x), data(%#x), "
196 "rfpath(%#x)\n", regaddr,
197 bitmask, data, rfpath));
198}
199
200static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
201 enum radio_path rfpath, u32 offset)
202{
203 RT_ASSERT(false, ("deprecated!\n"));
204 return 0;
205}
206
207static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
208 enum radio_path rfpath, u32 offset,
209 u32 data)
210{
211 RT_ASSERT(false, ("deprecated!\n"));
212}
213
214static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
215 enum radio_path rfpath, u32 offset)
216{
217 struct rtl_priv *rtlpriv = rtl_priv(hw);
218 struct rtl_phy *rtlphy = &(rtlpriv->phy);
219 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
220 u32 newoffset;
221 u32 tmplong, tmplong2;
222 u8 rfpi_enable = 0;
223 u32 retvalue;
224
225 offset &= 0x3f;
226 newoffset = offset;
227 if (RT_CANNOT_IO(hw)) {
228 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n"));
229 return 0xFFFFFFFF;
230 }
231 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
232 if (rfpath == RF90_PATH_A)
233 tmplong2 = tmplong;
234 else
235 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
236 tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
237 (newoffset << 23) | BLSSIREADEDGE;
238 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
239 tmplong & (~BLSSIREADEDGE));
240 mdelay(1);
241 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
242 mdelay(1);
243 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
244 tmplong | BLSSIREADEDGE);
245 mdelay(1);
246 if (rfpath == RF90_PATH_A)
247 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
248 BIT(8));
249 else if (rfpath == RF90_PATH_B)
250 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
251 BIT(8));
252 if (rfpi_enable)
253 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi,
254 BLSSIREADBACKDATA);
255 else
256 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
257 BLSSIREADBACKDATA);
258 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
259 rfpath, pphyreg->rflssi_readback,
260 retvalue));
261 return retvalue;
262}
263
264static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
265 enum radio_path rfpath, u32 offset,
266 u32 data)
267{
268 u32 data_and_addr;
269 u32 newoffset;
270 struct rtl_priv *rtlpriv = rtl_priv(hw);
271 struct rtl_phy *rtlphy = &(rtlpriv->phy);
272 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
273
274 if (RT_CANNOT_IO(hw)) {
275 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n"));
276 return;
277 }
278 offset &= 0x3f;
279 newoffset = offset;
280 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
281 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
282 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
283 rfpath, pphyreg->rf3wire_offset,
284 data_and_addr));
285}
286
287static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask)
288{
289 u32 i;
290
291 for (i = 0; i <= 31; i++) {
292 if (((bitmask >> i) & 0x1) == 1)
293 break;
294 }
295 return i;
296}
297
298static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw)
299{
300 rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
301 rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
302 rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
303 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
304 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
305 rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
306 rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
307 rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
308 rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
309 rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
310}
311
312bool rtl92c_phy_mac_config(struct ieee80211_hw *hw)
313{
314 struct rtl_priv *rtlpriv = rtl_priv(hw);
315 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
316 bool is92c = IS_92C_SERIAL(rtlhal->version);
317 bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw);
318
319 if (is92c)
320 rtl_write_byte(rtlpriv, 0x14, 0x71);
321 return rtstatus;
322}
323
324bool rtl92c_phy_bb_config(struct ieee80211_hw *hw)
325{
326 bool rtstatus = true;
327 struct rtl_priv *rtlpriv = rtl_priv(hw);
328 u16 regval;
329 u32 regvaldw;
330 u8 b_reg_hwparafile = 1;
331
332 _rtl92c_phy_init_bb_rf_register_definition(hw);
333 regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
334 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
335 regval | BIT(13) | BIT(0) | BIT(1));
336 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
337 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
338 rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
339 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
340 FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
341 FEN_BB_GLB_RSTn | FEN_BBRSTB);
342 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
343 regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
344 rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
345 if (b_reg_hwparafile == 1)
346 rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
347 return rtstatus;
348}
349
350bool rtl92c_phy_rf_config(struct ieee80211_hw *hw)
351{
352 return rtl92c_phy_rf6052_config(hw);
353}
354
355static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
356{
357 struct rtl_priv *rtlpriv = rtl_priv(hw);
358 struct rtl_phy *rtlphy = &(rtlpriv->phy);
359 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
360 bool rtstatus;
361
362 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n"));
363 rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw,
364 BASEBAND_CONFIG_PHY_REG);
365 if (rtstatus != true) {
366 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!"));
367 return false;
368 }
369 if (rtlphy->rf_type == RF_1T2R) {
370 _rtl92c_phy_bb_config_1t(hw);
371 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n"));
372 }
373 if (rtlefuse->autoload_failflag == false) {
374 rtlphy->pwrgroup_cnt = 0;
375 rtstatus = _rtl92c_phy_config_bb_with_pgheaderfile(hw,
376 BASEBAND_CONFIG_PHY_REG);
377 }
378 if (rtstatus != true) {
379 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!"));
380 return false;
381 }
382 rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw,
383 BASEBAND_CONFIG_AGC_TAB);
384 if (rtstatus != true) {
385 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n"));
386 return false;
387 }
388 rtlphy->bcck_high_power = (bool) (rtl_get_bbreg(hw,
389 RFPGA0_XA_HSSIPARAMETER2,
390 0x200));
391 return true;
392}
393
394static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
395{
396 struct rtl_priv *rtlpriv = rtl_priv(hw);
397 u32 i;
398 u32 arraylength;
399 u32 *ptrarray;
400
401 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n"));
402 arraylength = MAC_2T_ARRAYLENGTH;
403 ptrarray = RTL8192CEMAC_2T_ARRAY;
404 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
405 ("Img:RTL8192CEMAC_2T_ARRAY\n"));
406 for (i = 0; i < arraylength; i = i + 2)
407 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
408 return true;
409}
410
411void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw)
412{
413}
414
415static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
416 u8 configtype)
417{
418 int i;
419 u32 *phy_regarray_table;
420 u32 *agctab_array_table;
421 u16 phy_reg_arraylen, agctab_arraylen;
422 struct rtl_priv *rtlpriv = rtl_priv(hw);
423 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
424
425 if (IS_92C_SERIAL(rtlhal->version)) {
426 agctab_arraylen = AGCTAB_2TARRAYLENGTH;
427 agctab_array_table = RTL8192CEAGCTAB_2TARRAY;
428 phy_reg_arraylen = PHY_REG_2TARRAY_LENGTH;
429 phy_regarray_table = RTL8192CEPHY_REG_2TARRAY;
430 } else {
431 agctab_arraylen = AGCTAB_1TARRAYLENGTH;
432 agctab_array_table = RTL8192CEAGCTAB_1TARRAY;
433 phy_reg_arraylen = PHY_REG_1TARRAY_LENGTH;
434 phy_regarray_table = RTL8192CEPHY_REG_1TARRAY;
435 }
436 if (configtype == BASEBAND_CONFIG_PHY_REG) {
437 for (i = 0; i < phy_reg_arraylen; i = i + 2) {
438 if (phy_regarray_table[i] == 0xfe)
439 mdelay(50);
440 else if (phy_regarray_table[i] == 0xfd)
441 mdelay(5);
442 else if (phy_regarray_table[i] == 0xfc)
443 mdelay(1);
444 else if (phy_regarray_table[i] == 0xfb)
445 udelay(50);
446 else if (phy_regarray_table[i] == 0xfa)
447 udelay(5);
448 else if (phy_regarray_table[i] == 0xf9)
449 udelay(1);
450 rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
451 phy_regarray_table[i + 1]);
452 udelay(1);
453 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
454 ("The phy_regarray_table[0] is %x"
455 " Rtl819XPHY_REGArray[1] is %x\n",
456 phy_regarray_table[i],
457 phy_regarray_table[i + 1]));
458 }
459 rtl92c_phy_config_bb_external_pa(hw);
460 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
461 for (i = 0; i < agctab_arraylen; i = i + 2) {
462 rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
463 agctab_array_table[i + 1]);
464 udelay(1);
465 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
466 ("The agctab_array_table[0] is "
467 "%x Rtl819XPHY_REGArray[1] is %x\n",
468 agctab_array_table[i],
469 agctab_array_table[i + 1]));
470 }
471 }
472 return true;
473}
474
475static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
476 u32 regaddr, u32 bitmask,
477 u32 data)
478{
479 struct rtl_priv *rtlpriv = rtl_priv(hw);
480 struct rtl_phy *rtlphy = &(rtlpriv->phy);
481
482 if (regaddr == RTXAGC_A_RATE18_06) {
483 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
484 data;
485 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
486 ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
487 rtlphy->pwrgroup_cnt,
488 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
489 pwrgroup_cnt][0]));
490 }
491 if (regaddr == RTXAGC_A_RATE54_24) {
492 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
493 data;
494 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
495 ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
496 rtlphy->pwrgroup_cnt,
497 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
498 pwrgroup_cnt][1]));
499 }
500 if (regaddr == RTXAGC_A_CCK1_MCS32) {
501 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
502 data;
503 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
504 ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
505 rtlphy->pwrgroup_cnt,
506 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
507 pwrgroup_cnt][6]));
508 }
509 if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
510 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] =
511 data;
512 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
513 ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
514 rtlphy->pwrgroup_cnt,
515 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
516 pwrgroup_cnt][7]));
517 }
518 if (regaddr == RTXAGC_A_MCS03_MCS00) {
519 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
520 data;
521 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
522 ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
523 rtlphy->pwrgroup_cnt,
524 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
525 pwrgroup_cnt][2]));
526 }
527 if (regaddr == RTXAGC_A_MCS07_MCS04) {
528 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
529 data;
530 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
531 ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
532 rtlphy->pwrgroup_cnt,
533 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
534 pwrgroup_cnt][3]));
535 }
536 if (regaddr == RTXAGC_A_MCS11_MCS08) {
537 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
538 data;
539 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
540 ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
541 rtlphy->pwrgroup_cnt,
542 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
543 pwrgroup_cnt][4]));
544 }
545 if (regaddr == RTXAGC_A_MCS15_MCS12) {
546 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
547 data;
548 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
549 ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
550 rtlphy->pwrgroup_cnt,
551 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
552 pwrgroup_cnt][5]));
553 }
554 if (regaddr == RTXAGC_B_RATE18_06) {
555 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] =
556 data;
557 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
558 ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
559 rtlphy->pwrgroup_cnt,
560 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
561 pwrgroup_cnt][8]));
562 }
563 if (regaddr == RTXAGC_B_RATE54_24) {
564 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] =
565 data;
566
567 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
568 ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
569 rtlphy->pwrgroup_cnt,
570 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
571 pwrgroup_cnt][9]));
572 }
573
574 if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
575 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] =
576 data;
577
578 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
579 ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
580 rtlphy->pwrgroup_cnt,
581 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
582 pwrgroup_cnt][14]));
583 }
584
585 if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
586 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] =
587 data;
588
589 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
590 ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
591 rtlphy->pwrgroup_cnt,
592 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
593 pwrgroup_cnt][15]));
594 }
595
596 if (regaddr == RTXAGC_B_MCS03_MCS00) {
597 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] =
598 data;
599
600 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
601 ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
602 rtlphy->pwrgroup_cnt,
603 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
604 pwrgroup_cnt][10]));
605 }
606
607 if (regaddr == RTXAGC_B_MCS07_MCS04) {
608 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] =
609 data;
610
611 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
612 ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
613 rtlphy->pwrgroup_cnt,
614 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
615 pwrgroup_cnt][11]));
616 }
617
618 if (regaddr == RTXAGC_B_MCS11_MCS08) {
619 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] =
620 data;
621
622 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
623 ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
624 rtlphy->pwrgroup_cnt,
625 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
626 pwrgroup_cnt][12]));
627 }
628
629 if (regaddr == RTXAGC_B_MCS15_MCS12) {
630 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] =
631 data;
632
633 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
634 ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
635 rtlphy->pwrgroup_cnt,
636 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
637 pwrgroup_cnt][13]));
638
639 rtlphy->pwrgroup_cnt++;
640 }
641}
642
643static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
644 u8 configtype)
645{
646 struct rtl_priv *rtlpriv = rtl_priv(hw);
647 int i;
648 u32 *phy_regarray_table_pg;
649 u16 phy_regarray_pg_len;
650
651 phy_regarray_pg_len = PHY_REG_ARRAY_PGLENGTH;
652 phy_regarray_table_pg = RTL8192CEPHY_REG_ARRAY_PG;
653
654 if (configtype == BASEBAND_CONFIG_PHY_REG) {
655 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
656 if (phy_regarray_table_pg[i] == 0xfe)
657 mdelay(50);
658 else if (phy_regarray_table_pg[i] == 0xfd)
659 mdelay(5);
660 else if (phy_regarray_table_pg[i] == 0xfc)
661 mdelay(1);
662 else if (phy_regarray_table_pg[i] == 0xfb)
663 udelay(50);
664 else if (phy_regarray_table_pg[i] == 0xfa)
665 udelay(5);
666 else if (phy_regarray_table_pg[i] == 0xf9)
667 udelay(1);
668
669 _rtl92c_store_pwrIndex_diffrate_offset(hw,
670 phy_regarray_table_pg[i],
671 phy_regarray_table_pg[i + 1],
672 phy_regarray_table_pg[i + 2]);
673 }
674 } else {
675
676 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
677 ("configtype != BaseBand_Config_PHY_REG\n"));
678 }
679 return true;
680}
681
682static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw,
683 enum radio_path rfpath)
684{
685 return true;
686}
687
688bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
689 enum radio_path rfpath)
690{
691
692 int i;
693 bool rtstatus = true;
694 u32 *radioa_array_table;
695 u32 *radiob_array_table;
696 u16 radioa_arraylen, radiob_arraylen;
697 struct rtl_priv *rtlpriv = rtl_priv(hw);
698 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
699
700 if (IS_92C_SERIAL(rtlhal->version)) {
701 radioa_arraylen = RADIOA_2TARRAYLENGTH;
702 radioa_array_table = RTL8192CERADIOA_2TARRAY;
703 radiob_arraylen = RADIOB_2TARRAYLENGTH;
704 radiob_array_table = RTL8192CE_RADIOB_2TARRAY;
705 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
706 ("Radio_A:RTL8192CERADIOA_2TARRAY\n"));
707 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
708 ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n"));
709 } else {
710 radioa_arraylen = RADIOA_1TARRAYLENGTH;
711 radioa_array_table = RTL8192CE_RADIOA_1TARRAY;
712 radiob_arraylen = RADIOB_1TARRAYLENGTH;
713 radiob_array_table = RTL8192CE_RADIOB_1TARRAY;
714 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
715 ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n"));
716 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
717 ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n"));
718 }
719 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath));
720 rtstatus = true;
721 switch (rfpath) {
722 case RF90_PATH_A:
723 for (i = 0; i < radioa_arraylen; i = i + 2) {
724 if (radioa_array_table[i] == 0xfe)
725 mdelay(50);
726 else if (radioa_array_table[i] == 0xfd)
727 mdelay(5);
728 else if (radioa_array_table[i] == 0xfc)
729 mdelay(1);
730 else if (radioa_array_table[i] == 0xfb)
731 udelay(50);
732 else if (radioa_array_table[i] == 0xfa)
733 udelay(5);
734 else if (radioa_array_table[i] == 0xf9)
735 udelay(1);
736 else {
737 rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
738 RFREG_OFFSET_MASK,
739 radioa_array_table[i + 1]);
740 udelay(1);
741 }
742 }
743 _rtl92c_phy_config_rf_external_pa(hw, rfpath);
744 break;
745 case RF90_PATH_B:
746 for (i = 0; i < radiob_arraylen; i = i + 2) {
747 if (radiob_array_table[i] == 0xfe) {
748 mdelay(50);
749 } else if (radiob_array_table[i] == 0xfd)
750 mdelay(5);
751 else if (radiob_array_table[i] == 0xfc)
752 mdelay(1);
753 else if (radiob_array_table[i] == 0xfb)
754 udelay(50);
755 else if (radiob_array_table[i] == 0xfa)
756 udelay(5);
757 else if (radiob_array_table[i] == 0xf9)
758 udelay(1);
759 else {
760 rtl_set_rfreg(hw, rfpath, radiob_array_table[i],
761 RFREG_OFFSET_MASK,
762 radiob_array_table[i + 1]);
763 udelay(1);
764 }
765 }
766 break;
767 case RF90_PATH_C:
768 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
769 ("switch case not process\n"));
770 break;
771 case RF90_PATH_D:
772 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
773 ("switch case not process\n"));
774 break;
775 }
776 return true;
777}
778
779void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
780{
781 struct rtl_priv *rtlpriv = rtl_priv(hw);
782 struct rtl_phy *rtlphy = &(rtlpriv->phy);
783
784 rtlphy->default_initialgain[0] =
785 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
786 rtlphy->default_initialgain[1] =
787 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
788 rtlphy->default_initialgain[2] =
789 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
790 rtlphy->default_initialgain[3] =
791 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
792
793 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
794 ("Default initial gain (c50=0x%x, "
795 "c58=0x%x, c60=0x%x, c68=0x%x\n",
796 rtlphy->default_initialgain[0],
797 rtlphy->default_initialgain[1],
798 rtlphy->default_initialgain[2],
799 rtlphy->default_initialgain[3]));
800
801 rtlphy->framesync = (u8) rtl_get_bbreg(hw,
802 ROFDM0_RXDETECTOR3, MASKBYTE0);
803 rtlphy->framesync_c34 = rtl_get_bbreg(hw,
804 ROFDM0_RXDETECTOR2, MASKDWORD);
805
806 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
807 ("Default framesync (0x%x) = 0x%x\n",
808 ROFDM0_RXDETECTOR3, rtlphy->framesync));
809}
810
811static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
812{
813 struct rtl_priv *rtlpriv = rtl_priv(hw);
814 struct rtl_phy *rtlphy = &(rtlpriv->phy);
815
816 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
817 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
818 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
819 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
820
821 rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
822 rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
823 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
824 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
825
826 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
827 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
828
829 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
830 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
831
832 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
833 RFPGA0_XA_LSSIPARAMETER;
834 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
835 RFPGA0_XB_LSSIPARAMETER;
836
837 rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER;
838 rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER;
839 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER;
840 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER;
841
842 rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
843 rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
844 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
845 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
846
847 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
848 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
849
850 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
851 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
852
853 rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control =
854 RFPGA0_XAB_SWITCHCONTROL;
855 rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control =
856 RFPGA0_XAB_SWITCHCONTROL;
857 rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control =
858 RFPGA0_XCD_SWITCHCONTROL;
859 rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control =
860 RFPGA0_XCD_SWITCHCONTROL;
861
862 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
863 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
864 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
865 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
866
867 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
868 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
869 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
870 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
871
872 rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance =
873 ROFDM0_XARXIQIMBALANCE;
874 rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance =
875 ROFDM0_XBRXIQIMBALANCE;
876 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance =
877 ROFDM0_XCRXIQIMBANLANCE;
878 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance =
879 ROFDM0_XDRXIQIMBALANCE;
880
881 rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
882 rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
883 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
884 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
885
886 rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance =
887 ROFDM0_XATXIQIMBALANCE;
888 rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance =
889 ROFDM0_XBTXIQIMBALANCE;
890 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance =
891 ROFDM0_XCTXIQIMBALANCE;
892 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance =
893 ROFDM0_XDTXIQIMBALANCE;
894
895 rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
896 rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
897 rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
898 rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
899
900 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback =
901 RFPGA0_XA_LSSIREADBACK;
902 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback =
903 RFPGA0_XB_LSSIREADBACK;
904 rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback =
905 RFPGA0_XC_LSSIREADBACK;
906 rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback =
907 RFPGA0_XD_LSSIREADBACK;
908
909 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi =
910 TRANSCEIVEA_HSPI_READBACK;
911 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi =
912 TRANSCEIVEB_HSPI_READBACK;
913
914}
915
916void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
917{
918 struct rtl_priv *rtlpriv = rtl_priv(hw);
919 struct rtl_phy *rtlphy = &(rtlpriv->phy);
920 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
921 u8 txpwr_level;
922 long txpwr_dbm;
923
924 txpwr_level = rtlphy->cur_cck_txpwridx;
925 txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw,
926 WIRELESS_MODE_B, txpwr_level);
927 txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
928 rtlefuse->legacy_ht_txpowerdiff;
929 if (_rtl92c_phy_txpwr_idx_to_dbm(hw,
930 WIRELESS_MODE_G,
931 txpwr_level) > txpwr_dbm)
932 txpwr_dbm =
933 _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
934 txpwr_level);
935 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
936 if (_rtl92c_phy_txpwr_idx_to_dbm(hw,
937 WIRELESS_MODE_N_24G,
938 txpwr_level) > txpwr_dbm)
939 txpwr_dbm =
940 _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
941 txpwr_level);
942 *powerlevel = txpwr_dbm;
943}
944
945static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
946 u8 *cckpowerlevel, u8 *ofdmpowerlevel)
947{
948 struct rtl_priv *rtlpriv = rtl_priv(hw);
949 struct rtl_phy *rtlphy = &(rtlpriv->phy);
950 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
951 u8 index = (channel - 1);
952
953 cckpowerlevel[RF90_PATH_A] =
954 rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
955 cckpowerlevel[RF90_PATH_B] =
956 rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
957 if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
958 ofdmpowerlevel[RF90_PATH_A] =
959 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
960 ofdmpowerlevel[RF90_PATH_B] =
961 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
962 } else if (get_rf_type(rtlphy) == RF_2T2R) {
963 ofdmpowerlevel[RF90_PATH_A] =
964 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
965 ofdmpowerlevel[RF90_PATH_B] =
966 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
967 }
968}
969
970static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw,
971 u8 channel, u8 *cckpowerlevel,
972 u8 *ofdmpowerlevel)
973{
974 struct rtl_priv *rtlpriv = rtl_priv(hw);
975 struct rtl_phy *rtlphy = &(rtlpriv->phy);
976
977 rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
978 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
979}
980
981void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
982{
983 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
984 u8 cckpowerlevel[2], ofdmpowerlevel[2];
985
986 if (rtlefuse->b_txpwr_fromeprom == false)
987 return;
988 _rtl92c_get_txpower_index(hw, channel,
989 &cckpowerlevel[0], &ofdmpowerlevel[0]);
990 _rtl92c_ccxpower_index_check(hw,
991 channel, &cckpowerlevel[0],
992 &ofdmpowerlevel[0]);
993 rtl92c_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
994 rtl92c_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
995}
996
997bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
998{
999 struct rtl_priv *rtlpriv = rtl_priv(hw);
1000 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1001 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1002 u8 idx;
1003 u8 rf_path;
1004
1005 u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw,
1006 WIRELESS_MODE_B,
1007 power_indbm);
1008 u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw,
1009 WIRELESS_MODE_N_24G,
1010 power_indbm);
1011 if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
1012 ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
1013 else
1014 ofdmtxpwridx = 0;
1015 RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
1016 ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
1017 power_indbm, ccktxpwridx, ofdmtxpwridx));
1018 for (idx = 0; idx < 14; idx++) {
1019 for (rf_path = 0; rf_path < 2; rf_path++) {
1020 rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
1021 rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
1022 ofdmtxpwridx;
1023 rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
1024 ofdmtxpwridx;
1025 }
1026 }
1027 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
1028 return true;
1029}
1030
1031void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval)
1032{
1033}
1034
1035static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
1036 enum wireless_mode wirelessmode,
1037 long power_indbm)
1038{
1039 u8 txpwridx;
1040 long offset;
1041
1042 switch (wirelessmode) {
1043 case WIRELESS_MODE_B:
1044 offset = -7;
1045 break;
1046 case WIRELESS_MODE_G:
1047 case WIRELESS_MODE_N_24G:
1048 offset = -8;
1049 break;
1050 default:
1051 offset = -8;
1052 break;
1053 }
1054
1055 if ((power_indbm - offset) > 0)
1056 txpwridx = (u8) ((power_indbm - offset) * 2);
1057 else
1058 txpwridx = 0;
1059
1060 if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
1061 txpwridx = MAX_TXPWR_IDX_NMODE_92S;
1062
1063 return txpwridx;
1064}
1065
1066static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
1067 enum wireless_mode wirelessmode,
1068 u8 txpwridx)
1069{
1070 long offset;
1071 long pwrout_dbm;
1072
1073 switch (wirelessmode) {
1074 case WIRELESS_MODE_B:
1075 offset = -7;
1076 break;
1077 case WIRELESS_MODE_G:
1078 case WIRELESS_MODE_N_24G:
1079 offset = -8;
1080 break;
1081 default:
1082 offset = -8;
1083 break;
1084 }
1085 pwrout_dbm = txpwridx / 2 + offset;
1086 return pwrout_dbm;
1087}
1088
1089void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1090{
1091 struct rtl_priv *rtlpriv = rtl_priv(hw);
1092 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1093 enum io_type iotype;
1094
1095 if (!is_hal_stop(rtlhal)) {
1096 switch (operation) {
1097 case SCAN_OPT_BACKUP:
1098 iotype = IO_CMD_PAUSE_DM_BY_SCAN;
1099 rtlpriv->cfg->ops->set_hw_reg(hw,
1100 HW_VAR_IO_CMD,
1101 (u8 *)&iotype);
1102
1103 break;
1104 case SCAN_OPT_RESTORE:
1105 iotype = IO_CMD_RESUME_DM_BY_SCAN;
1106 rtlpriv->cfg->ops->set_hw_reg(hw,
1107 HW_VAR_IO_CMD,
1108 (u8 *)&iotype);
1109 break;
1110 default:
1111 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1112 ("Unknown Scan Backup operation.\n"));
1113 break;
1114 }
1115 }
1116}
1117
1118void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1119{
1120 struct rtl_priv *rtlpriv = rtl_priv(hw);
1121 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1122 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1123 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1124 u8 reg_bw_opmode;
1125 u8 reg_prsr_rsc;
1126
1127 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1128 ("Switch to %s bandwidth\n",
1129 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1130 "20MHz" : "40MHz"))
1131
1132 if (is_hal_stop(rtlhal))
1133 return;
1134
1135 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1136 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1137
1138 switch (rtlphy->current_chan_bw) {
1139 case HT_CHANNEL_WIDTH_20:
1140 reg_bw_opmode |= BW_OPMODE_20MHZ;
1141 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1142 break;
1143
1144 case HT_CHANNEL_WIDTH_20_40:
1145 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1146 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1147
1148 reg_prsr_rsc =
1149 (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
1150 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1151 break;
1152
1153 default:
1154 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1155 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
1156 break;
1157 }
1158
1159 switch (rtlphy->current_chan_bw) {
1160 case HT_CHANNEL_WIDTH_20:
1161 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1162 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1163 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
1164 break;
1165 case HT_CHANNEL_WIDTH_20_40:
1166 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1167 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1168 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1169 (mac->cur_40_prime_sc >> 1));
1170 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1171 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
1172 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1173 (mac->cur_40_prime_sc ==
1174 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1175 break;
1176 default:
1177 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1178 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
1179 break;
1180 }
1181 rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1182 rtlphy->set_bwmode_inprogress = false;
1183 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
1184}
1185
1186void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
1187 enum nl80211_channel_type ch_type)
1188{
1189 struct rtl_priv *rtlpriv = rtl_priv(hw);
1190 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1191 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1192 u8 tmp_bw = rtlphy->current_chan_bw;
1193
1194 if (rtlphy->set_bwmode_inprogress)
1195 return;
1196 rtlphy->set_bwmode_inprogress = true;
1197 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
1198 rtl92c_phy_set_bw_mode_callback(hw);
1199 else {
1200 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1201 ("FALSE driver sleep or unload\n"));
1202 rtlphy->set_bwmode_inprogress = false;
1203 rtlphy->current_chan_bw = tmp_bw;
1204 }
1205}
1206
1207void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1208{
1209 struct rtl_priv *rtlpriv = rtl_priv(hw);
1210 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1211 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1212 u32 delay;
1213
1214 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1215 ("switch to channel%d\n", rtlphy->current_channel));
1216 if (is_hal_stop(rtlhal))
1217 return;
1218 do {
1219 if (!rtlphy->sw_chnl_inprogress)
1220 break;
1221 if (!_rtl92c_phy_sw_chnl_step_by_step
1222 (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
1223 &rtlphy->sw_chnl_step, &delay)) {
1224 if (delay > 0)
1225 mdelay(delay);
1226 else
1227 continue;
1228 } else
1229 rtlphy->sw_chnl_inprogress = false;
1230 break;
1231 } while (true);
1232 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
1233}
1234
1235u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw)
1236{
1237 struct rtl_priv *rtlpriv = rtl_priv(hw);
1238 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1239 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1240
1241 if (rtlphy->sw_chnl_inprogress)
1242 return 0;
1243 if (rtlphy->set_bwmode_inprogress)
1244 return 0;
1245 RT_ASSERT((rtlphy->current_channel <= 14),
1246 ("WIRELESS_MODE_G but channel>14"));
1247 rtlphy->sw_chnl_inprogress = true;
1248 rtlphy->sw_chnl_stage = 0;
1249 rtlphy->sw_chnl_step = 0;
1250 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1251 rtl92c_phy_sw_chnl_callback(hw);
1252 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1253 ("sw_chnl_inprogress false schdule workitem\n"));
1254 rtlphy->sw_chnl_inprogress = false;
1255 } else {
1256 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1257 ("sw_chnl_inprogress false driver sleep or"
1258 " unload\n"));
1259 rtlphy->sw_chnl_inprogress = false;
1260 }
1261 return 1;
1262}
1263
1264static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1265 u8 channel, u8 *stage, u8 *step,
1266 u32 *delay)
1267{
1268 struct rtl_priv *rtlpriv = rtl_priv(hw);
1269 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1270 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1271 u32 precommoncmdcnt;
1272 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1273 u32 postcommoncmdcnt;
1274 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1275 u32 rfdependcmdcnt;
1276 struct swchnlcmd *currentcmd = NULL;
1277 u8 rfpath;
1278 u8 num_total_rfpath = rtlphy->num_total_rfpath;
1279
1280 precommoncmdcnt = 0;
1281 _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1282 MAX_PRECMD_CNT,
1283 CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
1284 _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1285 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1286
1287 postcommoncmdcnt = 0;
1288
1289 _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1290 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
1291
1292 rfdependcmdcnt = 0;
1293
1294 RT_ASSERT((channel >= 1 && channel <= 14),
1295 ("illegal channel for Zebra: %d\n", channel));
1296
1297 _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1298 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
1299 RF_CHNLBW, channel, 10);
1300
1301 _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1302 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0,
1303 0);
1304
1305 do {
1306 switch (*stage) {
1307 case 0:
1308 currentcmd = &precommoncmd[*step];
1309 break;
1310 case 1:
1311 currentcmd = &rfdependcmd[*step];
1312 break;
1313 case 2:
1314 currentcmd = &postcommoncmd[*step];
1315 break;
1316 }
1317
1318 if (currentcmd->cmdid == CMDID_END) {
1319 if ((*stage) == 2) {
1320 return true;
1321 } else {
1322 (*stage)++;
1323 (*step) = 0;
1324 continue;
1325 }
1326 }
1327
1328 switch (currentcmd->cmdid) {
1329 case CMDID_SET_TXPOWEROWER_LEVEL:
1330 rtl92c_phy_set_txpower_level(hw, channel);
1331 break;
1332 case CMDID_WRITEPORT_ULONG:
1333 rtl_write_dword(rtlpriv, currentcmd->para1,
1334 currentcmd->para2);
1335 break;
1336 case CMDID_WRITEPORT_USHORT:
1337 rtl_write_word(rtlpriv, currentcmd->para1,
1338 (u16) currentcmd->para2);
1339 break;
1340 case CMDID_WRITEPORT_UCHAR:
1341 rtl_write_byte(rtlpriv, currentcmd->para1,
1342 (u8) currentcmd->para2);
1343 break;
1344 case CMDID_RF_WRITEREG:
1345 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1346 rtlphy->rfreg_chnlval[rfpath] =
1347 ((rtlphy->rfreg_chnlval[rfpath] &
1348 0xfffffc00) | currentcmd->para2);
1349
1350 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1351 currentcmd->para1,
1352 RFREG_OFFSET_MASK,
1353 rtlphy->rfreg_chnlval[rfpath]);
1354 }
1355 break;
1356 default:
1357 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1358 ("switch case not process\n"));
1359 break;
1360 }
1361
1362 break;
1363 } while (true);
1364
1365 (*delay) = currentcmd->msdelay;
1366 (*step)++;
1367 return false;
1368}
1369
1370static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
1371 u32 cmdtableidx, u32 cmdtablesz,
1372 enum swchnlcmd_id cmdid,
1373 u32 para1, u32 para2, u32 msdelay)
1374{
1375 struct swchnlcmd *pcmd;
1376
1377 if (cmdtable == NULL) {
1378 RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
1379 return false;
1380 }
1381
1382 if (cmdtableidx >= cmdtablesz)
1383 return false;
1384
1385 pcmd = cmdtable + cmdtableidx;
1386 pcmd->cmdid = cmdid;
1387 pcmd->para1 = para1;
1388 pcmd->para2 = para2;
1389 pcmd->msdelay = msdelay;
1390 return true;
1391}
1392
1393bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath)
1394{
1395 return true;
1396}
1397
1398static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1399{
1400 u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
1401 u8 result = 0x00;
1402
1403 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
1404 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
1405 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
1406 rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
1407 config_pathb ? 0x28160202 : 0x28160502);
1408
1409 if (config_pathb) {
1410 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
1411 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
1412 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
1413 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
1414 }
1415
1416 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
1417 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1418 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1419
1420 mdelay(IQK_DELAY_TIME);
1421
1422 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1423 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1424 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1425 reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1426
1427 if (!(reg_eac & BIT(28)) &&
1428 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1429 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1430 result |= 0x01;
1431 else
1432 return result;
1433
1434 if (!(reg_eac & BIT(27)) &&
1435 (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1436 (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1437 result |= 0x02;
1438 return result;
1439}
1440
1441static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw)
1442{
1443 u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
1444 u8 result = 0x00;
1445
1446 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
1447 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
1448 mdelay(IQK_DELAY_TIME);
1449 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1450 reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
1451 reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
1452 reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
1453 reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
1454 if (!(reg_eac & BIT(31)) &&
1455 (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
1456 (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
1457 result |= 0x01;
1458 else
1459 return result;
1460
1461 if (!(reg_eac & BIT(30)) &&
1462 (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
1463 (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
1464 result |= 0x02;
1465 return result;
1466}
1467
1468static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
1469 bool b_iqk_ok, long result[][8],
1470 u8 final_candidate, bool btxonly)
1471{
1472 u32 oldval_0, x, tx0_a, reg;
1473 long y, tx0_c;
1474
1475 if (final_candidate == 0xFF)
1476 return;
1477 else if (b_iqk_ok) {
1478 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1479 MASKDWORD) >> 22) & 0x3FF;
1480 x = result[final_candidate][0];
1481 if ((x & 0x00000200) != 0)
1482 x = x | 0xFFFFFC00;
1483 tx0_a = (x * oldval_0) >> 8;
1484 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
1485 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
1486 ((x * oldval_0 >> 7) & 0x1));
1487 y = result[final_candidate][1];
1488 if ((y & 0x00000200) != 0)
1489 y = y | 0xFFFFFC00;
1490 tx0_c = (y * oldval_0) >> 8;
1491 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
1492 ((tx0_c & 0x3C0) >> 6));
1493 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
1494 (tx0_c & 0x3F));
1495 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
1496 ((y * oldval_0 >> 7) & 0x1));
1497 if (btxonly)
1498 return;
1499 reg = result[final_candidate][2];
1500 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
1501 reg = result[final_candidate][3] & 0x3F;
1502 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
1503 reg = (result[final_candidate][3] >> 6) & 0xF;
1504 rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
1505 }
1506}
1507
1508static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1509 bool b_iqk_ok, long result[][8],
1510 u8 final_candidate, bool btxonly)
1511{
1512 u32 oldval_1, x, tx1_a, reg;
1513 long y, tx1_c;
1514
1515 if (final_candidate == 0xFF)
1516 return;
1517 else if (b_iqk_ok) {
1518 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1519 MASKDWORD) >> 22) & 0x3FF;
1520 x = result[final_candidate][4];
1521 if ((x & 0x00000200) != 0)
1522 x = x | 0xFFFFFC00;
1523 tx1_a = (x * oldval_1) >> 8;
1524 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1525 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1526 ((x * oldval_1 >> 7) & 0x1));
1527 y = result[final_candidate][5];
1528 if ((y & 0x00000200) != 0)
1529 y = y | 0xFFFFFC00;
1530 tx1_c = (y * oldval_1) >> 8;
1531 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1532 ((tx1_c & 0x3C0) >> 6));
1533 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1534 (tx1_c & 0x3F));
1535 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1536 ((y * oldval_1 >> 7) & 0x1));
1537 if (btxonly)
1538 return;
1539 reg = result[final_candidate][6];
1540 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1541 reg = result[final_candidate][7] & 0x3F;
1542 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1543 reg = (result[final_candidate][7] >> 6) & 0xF;
1544 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg);
1545 }
1546}
1547
1548static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw,
1549 u32 *addareg, u32 *addabackup,
1550 u32 registernum)
1551{
1552 u32 i;
1553
1554 for (i = 0; i < registernum; i++)
1555 addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
1556}
1557
1558static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw,
1559 u32 *macreg, u32 *macbackup)
1560{
1561 struct rtl_priv *rtlpriv = rtl_priv(hw);
1562 u32 i;
1563
1564 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1565 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1566 macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1567}
1568
1569static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw,
1570 u32 *addareg, u32 *addabackup,
1571 u32 regiesternum)
1572{
1573 u32 i;
1574
1575 for (i = 0; i < regiesternum; i++)
1576 rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
1577}
1578
1579static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw,
1580 u32 *macreg, u32 *macbackup)
1581{
1582 struct rtl_priv *rtlpriv = rtl_priv(hw);
1583 u32 i;
1584
1585 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1586 rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
1587 rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
1588}
1589
1590static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw,
1591 u32 *addareg, bool is_patha_on, bool is2t)
1592{
1593 u32 pathOn;
1594 u32 i;
1595
1596 pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
1597 if (false == is2t) {
1598 pathOn = 0x0bdb25a0;
1599 rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
1600 } else {
1601 rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn);
1602 }
1603
1604 for (i = 1; i < IQK_ADDA_REG_NUM; i++)
1605 rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn);
1606}
1607
1608static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1609 u32 *macreg, u32 *macbackup)
1610{
1611 struct rtl_priv *rtlpriv = rtl_priv(hw);
1612 u32 i;
1613
1614 rtl_write_byte(rtlpriv, macreg[0], 0x3F);
1615
1616 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1617 rtl_write_byte(rtlpriv, macreg[i],
1618 (u8) (macbackup[i] & (~BIT(3))));
1619 rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
1620}
1621
1622static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw)
1623{
1624 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
1625 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1626 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1627}
1628
1629static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
1630{
1631 u32 mode;
1632
1633 mode = pi_mode ? 0x01000100 : 0x01000000;
1634 rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
1635 rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
1636}
1637
1638static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw,
1639 long result[][8], u8 c1, u8 c2)
1640{
1641 u32 i, j, diff, simularity_bitmap, bound;
1642 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1643
1644 u8 final_candidate[2] = { 0xFF, 0xFF };
1645 bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1646
1647 if (is2t)
1648 bound = 8;
1649 else
1650 bound = 4;
1651
1652 simularity_bitmap = 0;
1653
1654 for (i = 0; i < bound; i++) {
1655 diff = (result[c1][i] > result[c2][i]) ?
1656 (result[c1][i] - result[c2][i]) :
1657 (result[c2][i] - result[c1][i]);
1658
1659 if (diff > MAX_TOLERANCE) {
1660 if ((i == 2 || i == 6) && !simularity_bitmap) {
1661 if (result[c1][i] + result[c1][i + 1] == 0)
1662 final_candidate[(i / 4)] = c2;
1663 else if (result[c2][i] + result[c2][i + 1] == 0)
1664 final_candidate[(i / 4)] = c1;
1665 else
1666 simularity_bitmap = simularity_bitmap |
1667 (1 << i);
1668 } else
1669 simularity_bitmap =
1670 simularity_bitmap | (1 << i);
1671 }
1672 }
1673
1674 if (simularity_bitmap == 0) {
1675 for (i = 0; i < (bound / 4); i++) {
1676 if (final_candidate[i] != 0xFF) {
1677 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1678 result[3][j] =
1679 result[final_candidate[i]][j];
1680 bresult = false;
1681 }
1682 }
1683 return bresult;
1684 } else if (!(simularity_bitmap & 0x0F)) {
1685 for (i = 0; i < 4; i++)
1686 result[3][i] = result[c1][i];
1687 return false;
1688 } else if (!(simularity_bitmap & 0xF0) && is2t) {
1689 for (i = 4; i < 8; i++)
1690 result[3][i] = result[c1][i];
1691 return false;
1692 } else {
1693 return false;
1694 }
1695
1696}
1697
1698static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1699 long result[][8], u8 t, bool is2t)
1700{
1701 struct rtl_priv *rtlpriv = rtl_priv(hw);
1702 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1703 u32 i;
1704 u8 patha_ok, pathb_ok;
1705 u32 adda_reg[IQK_ADDA_REG_NUM] = {
1706 0x85c, 0xe6c, 0xe70, 0xe74,
1707 0xe78, 0xe7c, 0xe80, 0xe84,
1708 0xe88, 0xe8c, 0xed0, 0xed4,
1709 0xed8, 0xedc, 0xee0, 0xeec
1710 };
1711
1712 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1713 0x522, 0x550, 0x551, 0x040
1714 };
1715
1716 const u32 retrycount = 2;
1717
1718 u32 bbvalue;
1719
1720 if (t == 0) {
1721 bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD);
1722
1723 _rtl92c_phy_save_adda_registers(hw, adda_reg,
1724 rtlphy->adda_backup, 16);
1725 _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg,
1726 rtlphy->iqk_mac_backup);
1727 }
1728 _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t);
1729 if (t == 0) {
1730 rtlphy->b_rfpi_enable = (u8) rtl_get_bbreg(hw,
1731 RFPGA0_XA_HSSIPARAMETER1,
1732 BIT(8));
1733 }
1734 if (!rtlphy->b_rfpi_enable)
1735 _rtl92c_phy_pi_mode_switch(hw, true);
1736 if (t == 0) {
1737 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
1738 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
1739 rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1740 }
1741 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1742 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1743 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1744 if (is2t) {
1745 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1746 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1747 }
1748 _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg,
1749 rtlphy->iqk_mac_backup);
1750 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
1751 if (is2t)
1752 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
1753 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1754 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1755 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
1756 for (i = 0; i < retrycount; i++) {
1757 patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t);
1758 if (patha_ok == 0x03) {
1759 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1760 0x3FF0000) >> 16;
1761 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1762 0x3FF0000) >> 16;
1763 result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1764 0x3FF0000) >> 16;
1765 result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1766 0x3FF0000) >> 16;
1767 break;
1768 } else if (i == (retrycount - 1) && patha_ok == 0x01)
1769 result[t][0] = (rtl_get_bbreg(hw, 0xe94,
1770 MASKDWORD) & 0x3FF0000) >>
1771 16;
1772 result[t][1] =
1773 (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
1774
1775 }
1776
1777 if (is2t) {
1778 _rtl92c_phy_path_a_standby(hw);
1779 _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t);
1780 for (i = 0; i < retrycount; i++) {
1781 pathb_ok = _rtl92c_phy_path_b_iqk(hw);
1782 if (pathb_ok == 0x03) {
1783 result[t][4] = (rtl_get_bbreg(hw,
1784 0xeb4,
1785 MASKDWORD) &
1786 0x3FF0000) >> 16;
1787 result[t][5] =
1788 (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1789 0x3FF0000) >> 16;
1790 result[t][6] =
1791 (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1792 0x3FF0000) >> 16;
1793 result[t][7] =
1794 (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1795 0x3FF0000) >> 16;
1796 break;
1797 } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1798 result[t][4] = (rtl_get_bbreg(hw,
1799 0xeb4,
1800 MASKDWORD) &
1801 0x3FF0000) >> 16;
1802 }
1803 result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1804 0x3FF0000) >> 16;
1805 }
1806 }
1807 rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
1808 rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1809 rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1810 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1811 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1812 if (is2t)
1813 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1814 if (t != 0) {
1815 if (!rtlphy->b_rfpi_enable)
1816 _rtl92c_phy_pi_mode_switch(hw, false);
1817 _rtl92c_phy_reload_adda_registers(hw, adda_reg,
1818 rtlphy->adda_backup, 16);
1819 _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg,
1820 rtlphy->iqk_mac_backup);
1821 }
1822}
1823
1824static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1825{
1826 u8 tmpreg;
1827 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1828 struct rtl_priv *rtlpriv = rtl_priv(hw);
1829
1830 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1831
1832 if ((tmpreg & 0x70) != 0)
1833 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1834 else
1835 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1836
1837 if ((tmpreg & 0x70) != 0) {
1838 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1839
1840 if (is2t)
1841 rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1842 MASK12BITS);
1843
1844 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1845 (rf_a_mode & 0x8FFFF) | 0x10000);
1846
1847 if (is2t)
1848 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1849 (rf_b_mode & 0x8FFFF) | 0x10000);
1850 }
1851 lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1852
1853 rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
1854
1855 mdelay(100);
1856
1857 if ((tmpreg & 0x70) != 0) {
1858 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1859 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1860
1861 if (is2t)
1862 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1863 rf_b_mode);
1864 } else {
1865 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1866 }
1867}
1868
1869static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,
1870 char delta, bool is2t)
1871{
1872 /* This routine is deliberately dummied out for later fixes */
1873#if 0
1874 struct rtl_priv *rtlpriv = rtl_priv(hw);
1875 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1876 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1877
1878 u32 reg_d[PATH_NUM];
1879 u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound;
1880
1881 u32 bb_backup[APK_BB_REG_NUM];
1882 u32 bb_reg[APK_BB_REG_NUM] = {
1883 0x904, 0xc04, 0x800, 0xc08, 0x874
1884 };
1885 u32 bb_ap_mode[APK_BB_REG_NUM] = {
1886 0x00000020, 0x00a05430, 0x02040000,
1887 0x000800e4, 0x00204000
1888 };
1889 u32 bb_normal_ap_mode[APK_BB_REG_NUM] = {
1890 0x00000020, 0x00a05430, 0x02040000,
1891 0x000800e4, 0x22204000
1892 };
1893
1894 u32 afe_backup[APK_AFE_REG_NUM];
1895 u32 afe_reg[APK_AFE_REG_NUM] = {
1896 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78,
1897 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c,
1898 0xed0, 0xed4, 0xed8, 0xedc, 0xee0,
1899 0xeec
1900 };
1901
1902 u32 mac_backup[IQK_MAC_REG_NUM];
1903 u32 mac_reg[IQK_MAC_REG_NUM] = {
1904 0x522, 0x550, 0x551, 0x040
1905 };
1906
1907 u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = {
1908 {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c},
1909 {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e}
1910 };
1911
1912 u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = {
1913 {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c},
1914 {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c}
1915 };
1916
1917 u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = {
1918 {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d},
1919 {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050}
1920 };
1921
1922 u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = {
1923 {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a},
1924 {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}
1925 };
1926
1927 u32 afe_on_off[PATH_NUM] = {
1928 0x04db25a4, 0x0b1b25a4
1929 };
1930
1931 u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c };
1932
1933 u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 };
1934
1935 u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 };
1936
1937 u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 };
1938
1939 const char apk_delta_mapping[APK_BB_REG_NUM][13] = {
1940 {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1941 {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1942 {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1943 {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1944 {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0}
1945 };
1946
1947 const u32 apk_normal_setting_value_1[13] = {
1948 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28,
1949 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3,
1950 0x12680000, 0x00880000, 0x00880000
1951 };
1952
1953 const u32 apk_normal_setting_value_2[16] = {
1954 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3,
1955 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025,
1956 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008,
1957 0x00050006
1958 };
1959
1960 const u32 apk_result[PATH_NUM][APK_BB_REG_NUM];
1961
1962 long bb_offset, delta_v, delta_offset;
1963
1964 if (!is2t)
1965 pathbound = 1;
1966
1967 for (index = 0; index < PATH_NUM; index++) {
1968 apk_offset[index] = apk_normal_offset[index];
1969 apk_value[index] = apk_normal_value[index];
1970 afe_on_off[index] = 0x6fdb25a4;
1971 }
1972
1973 for (index = 0; index < APK_BB_REG_NUM; index++) {
1974 for (path = 0; path < pathbound; path++) {
1975 apk_rf_init_value[path][index] =
1976 apk_normal_rf_init_value[path][index];
1977 apk_rf_value_0[path][index] =
1978 apk_normal_rf_value_0[path][index];
1979 }
1980 bb_ap_mode[index] = bb_normal_ap_mode[index];
1981
1982 apkbound = 6;
1983 }
1984
1985 for (index = 0; index < APK_BB_REG_NUM; index++) {
1986 if (index == 0)
1987 continue;
1988 bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD);
1989 }
1990
1991 _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup);
1992
1993 _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16);
1994
1995 for (path = 0; path < pathbound; path++) {
1996 if (path == RF90_PATH_A) {
1997 offset = 0xb00;
1998 for (index = 0; index < 11; index++) {
1999 rtl_set_bbreg(hw, offset, MASKDWORD,
2000 apk_normal_setting_value_1
2001 [index]);
2002
2003 offset += 0x04;
2004 }
2005
2006 rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000);
2007
2008 offset = 0xb68;
2009 for (; index < 13; index++) {
2010 rtl_set_bbreg(hw, offset, MASKDWORD,
2011 apk_normal_setting_value_1
2012 [index]);
2013
2014 offset += 0x04;
2015 }
2016
2017 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000);
2018
2019 offset = 0xb00;
2020 for (index = 0; index < 16; index++) {
2021 rtl_set_bbreg(hw, offset, MASKDWORD,
2022 apk_normal_setting_value_2
2023 [index]);
2024
2025 offset += 0x04;
2026 }
2027 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
2028 } else if (path == RF90_PATH_B) {
2029 offset = 0xb70;
2030 for (index = 0; index < 10; index++) {
2031 rtl_set_bbreg(hw, offset, MASKDWORD,
2032 apk_normal_setting_value_1
2033 [index]);
2034
2035 offset += 0x04;
2036 }
2037 rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000);
2038 rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000);
2039
2040 offset = 0xb68;
2041 index = 11;
2042 for (; index < 13; index++) {
2043 rtl_set_bbreg(hw, offset, MASKDWORD,
2044 apk_normal_setting_value_1
2045 [index]);
2046
2047 offset += 0x04;
2048 }
2049
2050 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000);
2051
2052 offset = 0xb60;
2053 for (index = 0; index < 16; index++) {
2054 rtl_set_bbreg(hw, offset, MASKDWORD,
2055 apk_normal_setting_value_2
2056 [index]);
2057
2058 offset += 0x04;
2059 }
2060 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
2061 }
2062
2063 reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path,
2064 0xd, MASKDWORD);
2065
2066 for (index = 0; index < APK_AFE_REG_NUM; index++)
2067 rtl_set_bbreg(hw, afe_reg[index], MASKDWORD,
2068 afe_on_off[path]);
2069
2070 if (path == RF90_PATH_A) {
2071 for (index = 0; index < APK_BB_REG_NUM; index++) {
2072 if (index == 0)
2073 continue;
2074 rtl_set_bbreg(hw, bb_reg[index], MASKDWORD,
2075 bb_ap_mode[index]);
2076 }
2077 }
2078
2079 _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup);
2080
2081 if (path == 0) {
2082 rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000);
2083 } else {
2084 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD,
2085 0x10000);
2086 rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD,
2087 0x1000f);
2088 rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD,
2089 0x20103);
2090 }
2091
2092 delta_offset = ((delta + 14) / 2);
2093 if (delta_offset < 0)
2094 delta_offset = 0;
2095 else if (delta_offset > 12)
2096 delta_offset = 12;
2097
2098 for (index = 0; index < APK_BB_REG_NUM; index++) {
2099 if (index != 1)
2100 continue;
2101
2102 tmpreg = apk_rf_init_value[path][index];
2103
2104 if (!rtlefuse->b_apk_thermalmeterignore) {
2105 bb_offset = (tmpreg & 0xF0000) >> 16;
2106
2107 if (!(tmpreg & BIT(15)))
2108 bb_offset = -bb_offset;
2109
2110 delta_v =
2111 apk_delta_mapping[index][delta_offset];
2112
2113 bb_offset += delta_v;
2114
2115 if (bb_offset < 0) {
2116 tmpreg = tmpreg & (~BIT(15));
2117 bb_offset = -bb_offset;
2118 } else {
2119 tmpreg = tmpreg | BIT(15);
2120 }
2121
2122 tmpreg =
2123 (tmpreg & 0xFFF0FFFF) | (bb_offset << 16);
2124 }
2125
2126 rtl_set_rfreg(hw, (enum radio_path)path, 0xc,
2127 MASKDWORD, 0x8992e);
2128 rtl_set_rfreg(hw, (enum radio_path)path, 0x0,
2129 MASKDWORD, apk_rf_value_0[path][index]);
2130 rtl_set_rfreg(hw, (enum radio_path)path, 0xd,
2131 MASKDWORD, tmpreg);
2132
2133 i = 0;
2134 do {
2135 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000);
2136 rtl_set_bbreg(hw, apk_offset[path],
2137 MASKDWORD, apk_value[0]);
2138 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2139 ("PHY_APCalibrate() offset 0x%x "
2140 "value 0x%x\n",
2141 apk_offset[path],
2142 rtl_get_bbreg(hw, apk_offset[path],
2143 MASKDWORD)));
2144
2145 mdelay(3);
2146
2147 rtl_set_bbreg(hw, apk_offset[path],
2148 MASKDWORD, apk_value[1]);
2149 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2150 ("PHY_APCalibrate() offset 0x%x "
2151 "value 0x%x\n",
2152 apk_offset[path],
2153 rtl_get_bbreg(hw, apk_offset[path],
2154 MASKDWORD)));
2155
2156 mdelay(20);
2157
2158 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
2159
2160 if (path == RF90_PATH_A)
2161 tmpreg = rtl_get_bbreg(hw, 0xbd8,
2162 0x03E00000);
2163 else
2164 tmpreg = rtl_get_bbreg(hw, 0xbd8,
2165 0xF8000000);
2166
2167 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2168 ("PHY_APCalibrate() offset "
2169 "0xbd8[25:21] %x\n", tmpreg));
2170
2171 i++;
2172
2173 } while (tmpreg > apkbound && i < 4);
2174
2175 apk_result[path][index] = tmpreg;
2176 }
2177 }
2178
2179 _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup);
2180
2181 for (index = 0; index < APK_BB_REG_NUM; index++) {
2182 if (index == 0)
2183 continue;
2184 rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]);
2185 }
2186
2187 _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16);
2188
2189 for (path = 0; path < pathbound; path++) {
2190 rtl_set_rfreg(hw, (enum radio_path)path, 0xd,
2191 MASKDWORD, reg_d[path]);
2192
2193 if (path == RF90_PATH_B) {
2194 rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD,
2195 0x1000f);
2196 rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD,
2197 0x20101);
2198 }
2199
2200 if (apk_result[path][1] > 6)
2201 apk_result[path][1] = 6;
2202 }
2203
2204 for (path = 0; path < pathbound; path++) {
2205 rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD,
2206 ((apk_result[path][1] << 15) |
2207 (apk_result[path][1] << 10) |
2208 (apk_result[path][1] << 5) |
2209 apk_result[path][1]));
2210
2211 if (path == RF90_PATH_A)
2212 rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD,
2213 ((apk_result[path][1] << 15) |
2214 (apk_result[path][1] << 10) |
2215 (0x00 << 5) | 0x05));
2216 else
2217 rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD,
2218 ((apk_result[path][1] << 15) |
2219 (apk_result[path][1] << 10) |
2220 (0x02 << 5) | 0x05));
2221
2222 rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD,
2223 ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) |
2224 0x08));
2225
2226 }
2227
2228 rtlphy->b_apk_done = true;
2229#endif
2230}
2231
2232static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw,
2233 bool bmain, bool is2t)
2234{
2235 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2236
2237 if (is_hal_stop(rtlhal)) {
2238 rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
2239 rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
2240 }
2241 if (is2t) {
2242 if (bmain)
2243 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2244 BIT(5) | BIT(6), 0x1);
2245 else
2246 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2247 BIT(5) | BIT(6), 0x2);
2248 } else {
2249 if (bmain)
2250 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
2251 else
2252 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
2253
2254 }
2255}
2256
2257#undef IQK_ADDA_REG_NUM
2258#undef IQK_DELAY_TIME
2259
2260void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
2261{
2262 struct rtl_priv *rtlpriv = rtl_priv(hw);
2263 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2264 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2265
2266 long result[4][8];
2267 u8 i, final_candidate;
2268 bool b_patha_ok, b_pathb_ok;
2269 long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
2270 reg_ecc, reg_tmp = 0;
2271 bool is12simular, is13simular, is23simular;
2272 bool b_start_conttx = false, b_singletone = false;
2273 u32 iqk_bb_reg[10] = {
2274 ROFDM0_XARXIQIMBALANCE,
2275 ROFDM0_XBRXIQIMBALANCE,
2276 ROFDM0_ECCATHRESHOLD,
2277 ROFDM0_AGCRSSITABLE,
2278 ROFDM0_XATXIQIMBALANCE,
2279 ROFDM0_XBTXIQIMBALANCE,
2280 ROFDM0_XCTXIQIMBALANCE,
2281 ROFDM0_XCTXAFE,
2282 ROFDM0_XDTXAFE,
2283 ROFDM0_RXIQEXTANTA
2284 };
2285
2286 if (b_recovery) {
2287 _rtl92c_phy_reload_adda_registers(hw,
2288 iqk_bb_reg,
2289 rtlphy->iqk_bb_backup, 10);
2290 return;
2291 }
2292 if (b_start_conttx || b_singletone)
2293 return;
2294 for (i = 0; i < 8; i++) {
2295 result[0][i] = 0;
2296 result[1][i] = 0;
2297 result[2][i] = 0;
2298 result[3][i] = 0;
2299 }
2300 final_candidate = 0xff;
2301 b_patha_ok = false;
2302 b_pathb_ok = false;
2303 is12simular = false;
2304 is23simular = false;
2305 is13simular = false;
2306 for (i = 0; i < 3; i++) {
2307 if (IS_92C_SERIAL(rtlhal->version))
2308 _rtl92c_phy_iq_calibrate(hw, result, i, true);
2309 else
2310 _rtl92c_phy_iq_calibrate(hw, result, i, false);
2311 if (i == 1) {
2312 is12simular = _rtl92c_phy_simularity_compare(hw,
2313 result, 0,
2314 1);
2315 if (is12simular) {
2316 final_candidate = 0;
2317 break;
2318 }
2319 }
2320 if (i == 2) {
2321 is13simular = _rtl92c_phy_simularity_compare(hw,
2322 result, 0,
2323 2);
2324 if (is13simular) {
2325 final_candidate = 0;
2326 break;
2327 }
2328 is23simular = _rtl92c_phy_simularity_compare(hw,
2329 result, 1,
2330 2);
2331 if (is23simular)
2332 final_candidate = 1;
2333 else {
2334 for (i = 0; i < 8; i++)
2335 reg_tmp += result[3][i];
2336
2337 if (reg_tmp != 0)
2338 final_candidate = 3;
2339 else
2340 final_candidate = 0xFF;
2341 }
2342 }
2343 }
2344 for (i = 0; i < 4; i++) {
2345 reg_e94 = result[i][0];
2346 reg_e9c = result[i][1];
2347 reg_ea4 = result[i][2];
2348 reg_eac = result[i][3];
2349 reg_eb4 = result[i][4];
2350 reg_ebc = result[i][5];
2351 reg_ec4 = result[i][6];
2352 reg_ecc = result[i][7];
2353 }
2354 if (final_candidate != 0xff) {
2355 rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
2356 rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
2357 reg_ea4 = result[final_candidate][2];
2358 reg_eac = result[final_candidate][3];
2359 rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
2360 rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
2361 reg_ec4 = result[final_candidate][6];
2362 reg_ecc = result[final_candidate][7];
2363 b_patha_ok = b_pathb_ok = true;
2364 } else {
2365 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
2366 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
2367 }
2368 if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
2369 _rtl92c_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
2370 final_candidate,
2371 (reg_ea4 == 0));
2372 if (IS_92C_SERIAL(rtlhal->version)) {
2373 if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */
2374 _rtl92c_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok,
2375 result,
2376 final_candidate,
2377 (reg_ec4 == 0));
2378 }
2379 _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg,
2380 rtlphy->iqk_bb_backup, 10);
2381}
2382
2383void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw)
2384{
2385 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2386 bool b_start_conttx = false, b_singletone = false;
2387
2388 if (b_start_conttx || b_singletone)
2389 return;
2390 if (IS_92C_SERIAL(rtlhal->version))
2391 _rtl92c_phy_lc_calibrate(hw, true);
2392 else
2393 _rtl92c_phy_lc_calibrate(hw, false);
2394}
2395
2396void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
2397{
2398 struct rtl_priv *rtlpriv = rtl_priv(hw);
2399 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2400 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2401
2402 if (rtlphy->b_apk_done)
2403 return;
2404 if (IS_92C_SERIAL(rtlhal->version))
2405 _rtl92c_phy_ap_calibrate(hw, delta, true);
2406 else
2407 _rtl92c_phy_ap_calibrate(hw, delta, false);
2408}
2409
2410void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2411{
2412 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2413
2414 if (IS_92C_SERIAL(rtlhal->version))
2415 _rtl92c_phy_set_rfpath_switch(hw, bmain, true);
2416 else
2417 _rtl92c_phy_set_rfpath_switch(hw, bmain, false);
2418}
2419
2420bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2421{
2422 struct rtl_priv *rtlpriv = rtl_priv(hw);
2423 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2424 bool b_postprocessing = false;
2425
2426 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2427 ("-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2428 iotype, rtlphy->set_io_inprogress));
2429 do {
2430 switch (iotype) {
2431 case IO_CMD_RESUME_DM_BY_SCAN:
2432 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2433 ("[IO CMD] Resume DM after scan.\n"));
2434 b_postprocessing = true;
2435 break;
2436 case IO_CMD_PAUSE_DM_BY_SCAN:
2437 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2438 ("[IO CMD] Pause DM before scan.\n"));
2439 b_postprocessing = true;
2440 break;
2441 default:
2442 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2443 ("switch case not process\n"));
2444 break;
2445 }
2446 } while (false);
2447 if (b_postprocessing && !rtlphy->set_io_inprogress) {
2448 rtlphy->set_io_inprogress = true;
2449 rtlphy->current_io_type = iotype;
2450 } else {
2451 return false;
2452 }
2453 rtl92c_phy_set_io(hw);
2454 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype));
2455 return true;
2456}
2457
2458void rtl92c_phy_set_io(struct ieee80211_hw *hw)
2459{
2460 struct rtl_priv *rtlpriv = rtl_priv(hw);
2461 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2462
2463 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2464 ("--->Cmd(%#x), set_io_inprogress(%d)\n",
2465 rtlphy->current_io_type, rtlphy->set_io_inprogress));
2466 switch (rtlphy->current_io_type) {
2467 case IO_CMD_RESUME_DM_BY_SCAN:
2468 dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1;
2469 rtl92c_dm_write_dig(hw);
2470 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
2471 break;
2472 case IO_CMD_PAUSE_DM_BY_SCAN:
2473 rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue;
2474 dm_digtable.cur_igvalue = 0x17;
2475 rtl92c_dm_write_dig(hw);
2476 break;
2477 default:
2478 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2479 ("switch case not process\n"));
2480 break;
2481 }
2482 rtlphy->set_io_inprogress = false;
2483 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2484 ("<---(%#x)\n", rtlphy->current_io_type));
2485}
2486
2487void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw)
2488{
2489 struct rtl_priv *rtlpriv = rtl_priv(hw);
2490
2491 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2492 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2493 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
2494 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2495 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2496 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2497}
2498
2499static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw)
2500{
2501 u32 u4b_tmp;
2502 u8 delay = 5;
2503 struct rtl_priv *rtlpriv = rtl_priv(hw);
2504
2505 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2506 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2507 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
2508 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
2509 while (u4b_tmp != 0 && delay > 0) {
2510 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
2511 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2512 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
2513 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
2514 delay--;
2515 }
2516 if (delay == 0) {
2517 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
2518 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2519 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2520 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2521 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
2522 ("Switch RF timeout !!!.\n"));
2523 return;
2524 }
2525 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2526 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2527}
2528
2529static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
2530 enum rf_pwrstate rfpwr_state)
2531{
2532 struct rtl_priv *rtlpriv = rtl_priv(hw);
2533 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2534 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2535 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2536 bool bresult = true;
2537 u8 i, queue_id;
2538 struct rtl8192_tx_ring *ring = NULL;
2539
2540 ppsc->set_rfpowerstate_inprogress = true;
2541 switch (rfpwr_state) {
2542 case ERFON:{
2543 if ((ppsc->rfpwr_state == ERFOFF) &&
2544 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2545 bool rtstatus;
2546 u32 InitializeCount = 0;
2547 do {
2548 InitializeCount++;
2549 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2550 ("IPS Set eRf nic enable\n"));
2551 rtstatus = rtl_ps_enable_nic(hw);
2552 } while ((rtstatus != true)
2553 && (InitializeCount < 10));
2554 RT_CLEAR_PS_LEVEL(ppsc,
2555 RT_RF_OFF_LEVL_HALT_NIC);
2556 } else {
2557 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2558 ("Set ERFON sleeped:%d ms\n",
2559 jiffies_to_msecs(jiffies -
2560 ppsc->
2561 last_sleep_jiffies)));
2562 ppsc->last_awake_jiffies = jiffies;
2563 rtl92ce_phy_set_rf_on(hw);
2564 }
2565 if (mac->link_state == MAC80211_LINKED) {
2566 rtlpriv->cfg->ops->led_control(hw,
2567 LED_CTL_LINK);
2568 } else {
2569 rtlpriv->cfg->ops->led_control(hw,
2570 LED_CTL_NO_LINK);
2571 }
2572 break;
2573 }
2574 case ERFOFF:{
2575 for (queue_id = 0, i = 0;
2576 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2577 ring = &pcipriv->dev.tx_ring[queue_id];
2578 if (skb_queue_len(&ring->queue) == 0 ||
2579 queue_id == BEACON_QUEUE) {
2580 queue_id++;
2581 continue;
2582 } else {
2583 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2584 ("eRf Off/Sleep: %d times "
2585 "TcbBusyQueue[%d] "
2586 "=%d before doze!\n", (i + 1),
2587 queue_id,
2588 skb_queue_len(&ring->queue)));
2589 udelay(10);
2590 i++;
2591 }
2592 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2593 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2594 ("\nERFOFF: %d times "
2595 "TcbBusyQueue[%d] = %d !\n",
2596 MAX_DOZE_WAITING_TIMES_9x,
2597 queue_id,
2598 skb_queue_len(&ring->queue)));
2599 break;
2600 }
2601 }
2602 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2603 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2604 ("IPS Set eRf nic disable\n"));
2605 rtl_ps_disable_nic(hw);
2606 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2607 } else {
2608 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2609 rtlpriv->cfg->ops->led_control(hw,
2610 LED_CTL_NO_LINK);
2611 } else {
2612 rtlpriv->cfg->ops->led_control(hw,
2613 LED_CTL_POWER_OFF);
2614 }
2615 }
2616 break;
2617 }
2618 case ERFSLEEP:{
2619 if (ppsc->rfpwr_state == ERFOFF)
2620 break;
2621 for (queue_id = 0, i = 0;
2622 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2623 ring = &pcipriv->dev.tx_ring[queue_id];
2624 if (skb_queue_len(&ring->queue) == 0) {
2625 queue_id++;
2626 continue;
2627 } else {
2628 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2629 ("eRf Off/Sleep: %d times "
2630 "TcbBusyQueue[%d] =%d before "
2631 "doze!\n", (i + 1), queue_id,
2632 skb_queue_len(&ring->queue)));
2633 udelay(10);
2634 i++;
2635 }
2636 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2637 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2638 ("\n ERFSLEEP: %d times "
2639 "TcbBusyQueue[%d] = %d !\n",
2640 MAX_DOZE_WAITING_TIMES_9x,
2641 queue_id,
2642 skb_queue_len(&ring->queue)));
2643 break;
2644 }
2645 }
2646 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2647 ("Set ERFSLEEP awaked:%d ms\n",
2648 jiffies_to_msecs(jiffies -
2649 ppsc->last_awake_jiffies)));
2650 ppsc->last_sleep_jiffies = jiffies;
2651 _rtl92ce_phy_set_rf_sleep(hw);
2652 break;
2653 }
2654 default:
2655 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2656 ("switch case not process\n"));
2657 bresult = false;
2658 break;
2659 }
2660 if (bresult)
2661 ppsc->rfpwr_state = rfpwr_state;
2662 ppsc->set_rfpowerstate_inprogress = false;
2663 return bresult;
2664}
2665
2666bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
2667 enum rf_pwrstate rfpwr_state)
2668{
2669 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2670 bool bresult = false;
2671
2672 if (rfpwr_state == ppsc->rfpwr_state)
2673 return bresult;
2674 bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state);
2675 return bresult;
2676}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h
new file mode 100644
index 00000000000..ca4daee6e9a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-phy.h
@@ -0,0 +1,237 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92C_PHY_H__
31#define __RTL92C_PHY_H__
32
33#define MAX_PRECMD_CNT 16
34#define MAX_RFDEPENDCMD_CNT 16
35#define MAX_POSTCMD_CNT 16
36
37#define MAX_DOZE_WAITING_TIMES_9x 64
38
39#define RT_CANNOT_IO(hw) false
40#define HIGHPOWER_RADIOA_ARRAYLEN 22
41
42#define MAX_TOLERANCE 5
43#define IQK_DELAY_TIME 1
44
45#define APK_BB_REG_NUM 5
46#define APK_AFE_REG_NUM 16
47#define APK_CURVE_REG_NUM 4
48#define PATH_NUM 2
49
50#define LOOP_LIMIT 5
51#define MAX_STALL_TIME 50
52#define AntennaDiversityValue 0x80
53#define MAX_TXPWR_IDX_NMODE_92S 63
54#define Reset_Cnt_Limit 3
55
56#define IQK_ADDA_REG_NUM 16
57#define IQK_MAC_REG_NUM 4
58
59#define RF90_PATH_MAX 2
60#define CHANNEL_MAX_NUMBER 14
61#define CHANNEL_GROUP_MAX 3
62
63#define CT_OFFSET_MAC_ADDR 0X16
64
65#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A
66#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60
67#define CT_OFFSET_HT402S_TX_PWR_IDX_DIF 0x66
68#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69
69#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C
70
71#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F
72#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72
73
74#define CT_OFFSET_CHANNEL_PLAH 0x75
75#define CT_OFFSET_THERMAL_METER 0x78
76#define CT_OFFSET_RF_OPTION 0x79
77#define CT_OFFSET_VERSION 0x7E
78#define CT_OFFSET_CUSTOMER_ID 0x7F
79
80#define RTL92C_MAX_PATH_NUM 2
81#define CHANNEL_MAX_NUMBER 14
82#define CHANNEL_GROUP_MAX 3
83
84enum swchnlcmd_id {
85 CMDID_END,
86 CMDID_SET_TXPOWEROWER_LEVEL,
87 CMDID_BBREGWRITE10,
88 CMDID_WRITEPORT_ULONG,
89 CMDID_WRITEPORT_USHORT,
90 CMDID_WRITEPORT_UCHAR,
91 CMDID_RF_WRITEREG,
92};
93
94struct swchnlcmd {
95 enum swchnlcmd_id cmdid;
96 u32 para1;
97 u32 para2;
98 u32 msdelay;
99};
100
101enum hw90_block_e {
102 HW90_BLOCK_MAC = 0,
103 HW90_BLOCK_PHY0 = 1,
104 HW90_BLOCK_PHY1 = 2,
105 HW90_BLOCK_RF = 3,
106 HW90_BLOCK_MAXIMUM = 4,
107};
108
109enum baseband_config_type {
110 BASEBAND_CONFIG_PHY_REG = 0,
111 BASEBAND_CONFIG_AGC_TAB = 1,
112};
113
114enum ra_offset_area {
115 RA_OFFSET_LEGACY_OFDM1,
116 RA_OFFSET_LEGACY_OFDM2,
117 RA_OFFSET_HT_OFDM1,
118 RA_OFFSET_HT_OFDM2,
119 RA_OFFSET_HT_OFDM3,
120 RA_OFFSET_HT_OFDM4,
121 RA_OFFSET_HT_CCK,
122};
123
124enum antenna_path {
125 ANTENNA_NONE,
126 ANTENNA_D,
127 ANTENNA_C,
128 ANTENNA_CD,
129 ANTENNA_B,
130 ANTENNA_BD,
131 ANTENNA_BC,
132 ANTENNA_BCD,
133 ANTENNA_A,
134 ANTENNA_AD,
135 ANTENNA_AC,
136 ANTENNA_ACD,
137 ANTENNA_AB,
138 ANTENNA_ABD,
139 ANTENNA_ABC,
140 ANTENNA_ABCD
141};
142
143struct r_antenna_select_ofdm {
144 u32 r_tx_antenna:4;
145 u32 r_ant_l:4;
146 u32 r_ant_non_ht:4;
147 u32 r_ant_ht1:4;
148 u32 r_ant_ht2:4;
149 u32 r_ant_ht_s1:4;
150 u32 r_ant_non_ht_s1:4;
151 u32 ofdm_txsc:2;
152 u32 reserved:2;
153};
154
155struct r_antenna_select_cck {
156 u8 r_cckrx_enable_2:2;
157 u8 r_cckrx_enable:2;
158 u8 r_ccktx_enable:4;
159};
160
161struct efuse_contents {
162 u8 mac_addr[ETH_ALEN];
163 u8 cck_tx_power_idx[6];
164 u8 ht40_1s_tx_power_idx[6];
165 u8 ht40_2s_tx_power_idx_diff[3];
166 u8 ht20_tx_power_idx_diff[3];
167 u8 ofdm_tx_power_idx_diff[3];
168 u8 ht40_max_power_offset[3];
169 u8 ht20_max_power_offset[3];
170 u8 channel_plan;
171 u8 thermal_meter;
172 u8 rf_option[5];
173 u8 version;
174 u8 oem_id;
175 u8 regulatory;
176};
177
178struct tx_power_struct {
179 u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
180 u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
181 u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
182 u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
183 u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
184 u8 legacy_ht_txpowerdiff;
185 u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
186 u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER];
187 u8 pwrgroup_cnt;
188 u32 mcs_original_offset[4][16];
189};
190
191extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,
192 u32 regaddr, u32 bitmask);
193extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
194 u32 regaddr, u32 bitmask, u32 data);
195extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
196 enum radio_path rfpath, u32 regaddr,
197 u32 bitmask);
198extern void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw,
199 enum radio_path rfpath, u32 regaddr,
200 u32 bitmask, u32 data);
201extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);
202extern bool rtl92c_phy_bb_config(struct ieee80211_hw *hw);
203extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
204extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
205 enum radio_path rfpath);
206extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
207extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
208 long *powerlevel);
209extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
210extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
211 long power_indbm);
212extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,
213 u8 operation);
214extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
215extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
216 enum nl80211_channel_type ch_type);
217extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
218extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
219extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
220extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,
221 u16 beaconinterval);
222void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
223void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
224void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
225bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
226 enum radio_path rfpath);
227extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
228 u32 rfpath);
229bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
230extern bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
231 enum rf_pwrstate rfpwr_state);
232void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw);
233void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw);
234bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
235void rtl92c_phy_set_io(struct ieee80211_hw *hw);
236
237#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h
new file mode 100644
index 00000000000..875d5146522
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-reg.h
@@ -0,0 +1,2065 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92C_REG_H__
31#define __RTL92C_REG_H__
32
33#define REG_SYS_ISO_CTRL 0x0000
34#define REG_SYS_FUNC_EN 0x0002
35#define REG_APS_FSMCO 0x0004
36#define REG_SYS_CLKR 0x0008
37#define REG_9346CR 0x000A
38#define REG_EE_VPD 0x000C
39#define REG_AFE_MISC 0x0010
40#define REG_SPS0_CTRL 0x0011
41#define REG_SPS_OCP_CFG 0x0018
42#define REG_RSV_CTRL 0x001C
43#define REG_RF_CTRL 0x001F
44#define REG_LDOA15_CTRL 0x0020
45#define REG_LDOV12D_CTRL 0x0021
46#define REG_LDOHCI12_CTRL 0x0022
47#define REG_LPLDO_CTRL 0x0023
48#define REG_AFE_XTAL_CTRL 0x0024
49#define REG_AFE_PLL_CTRL 0x0028
50#define REG_EFUSE_CTRL 0x0030
51#define REG_EFUSE_TEST 0x0034
52#define REG_PWR_DATA 0x0038
53#define REG_CAL_TIMER 0x003C
54#define REG_ACLK_MON 0x003E
55#define REG_GPIO_MUXCFG 0x0040
56#define REG_GPIO_IO_SEL 0x0042
57#define REG_MAC_PINMUX_CFG 0x0043
58#define REG_GPIO_PIN_CTRL 0x0044
59#define REG_GPIO_INTM 0x0048
60#define REG_LEDCFG0 0x004C
61#define REG_LEDCFG1 0x004D
62#define REG_LEDCFG2 0x004E
63#define REG_LEDCFG3 0x004F
64#define REG_FSIMR 0x0050
65#define REG_FSISR 0x0054
66
67#define REG_MCUFWDL 0x0080
68
69#define REG_HMEBOX_EXT_0 0x0088
70#define REG_HMEBOX_EXT_1 0x008A
71#define REG_HMEBOX_EXT_2 0x008C
72#define REG_HMEBOX_EXT_3 0x008E
73
74#define REG_BIST_SCAN 0x00D0
75#define REG_BIST_RPT 0x00D4
76#define REG_BIST_ROM_RPT 0x00D8
77#define REG_USB_SIE_INTF 0x00E0
78#define REG_PCIE_MIO_INTF 0x00E4
79#define REG_PCIE_MIO_INTD 0x00E8
80#define REG_HPON_FSM 0x00EC
81#define REG_SYS_CFG 0x00F0
82
83#define REG_CR 0x0100
84#define REG_PBP 0x0104
85#define REG_TRXDMA_CTRL 0x010C
86#define REG_TRXFF_BNDY 0x0114
87#define REG_TRXFF_STATUS 0x0118
88#define REG_RXFF_PTR 0x011C
89#define REG_HIMR 0x0120
90#define REG_HISR 0x0124
91#define REG_HIMRE 0x0128
92#define REG_HISRE 0x012C
93#define REG_CPWM 0x012F
94#define REG_FWIMR 0x0130
95#define REG_FWISR 0x0134
96#define REG_PKTBUF_DBG_CTRL 0x0140
97#define REG_PKTBUF_DBG_DATA_L 0x0144
98#define REG_PKTBUF_DBG_DATA_H 0x0148
99
100#define REG_TC0_CTRL 0x0150
101#define REG_TC1_CTRL 0x0154
102#define REG_TC2_CTRL 0x0158
103#define REG_TC3_CTRL 0x015C
104#define REG_TC4_CTRL 0x0160
105#define REG_TCUNIT_BASE 0x0164
106#define REG_MBIST_START 0x0174
107#define REG_MBIST_DONE 0x0178
108#define REG_MBIST_FAIL 0x017C
109#define REG_C2HEVT_MSG_NORMAL 0x01A0
110#define REG_C2HEVT_MSG_TEST 0x01B8
111#define REG_C2HEVT_CLEAR 0x01BF
112#define REG_MCUTST_1 0x01c0
113#define REG_FMETHR 0x01C8
114#define REG_HMETFR 0x01CC
115#define REG_HMEBOX_0 0x01D0
116#define REG_HMEBOX_1 0x01D4
117#define REG_HMEBOX_2 0x01D8
118#define REG_HMEBOX_3 0x01DC
119
120#define REG_LLT_INIT 0x01E0
121#define REG_BB_ACCEESS_CTRL 0x01E8
122#define REG_BB_ACCESS_DATA 0x01EC
123
124#define REG_RQPN 0x0200
125#define REG_FIFOPAGE 0x0204
126#define REG_TDECTRL 0x0208
127#define REG_TXDMA_OFFSET_CHK 0x020C
128#define REG_TXDMA_STATUS 0x0210
129#define REG_RQPN_NPQ 0x0214
130
131#define REG_RXDMA_AGG_PG_TH 0x0280
132#define REG_RXPKT_NUM 0x0284
133#define REG_RXDMA_STATUS 0x0288
134
135#define REG_PCIE_CTRL_REG 0x0300
136#define REG_INT_MIG 0x0304
137#define REG_BCNQ_DESA 0x0308
138#define REG_HQ_DESA 0x0310
139#define REG_MGQ_DESA 0x0318
140#define REG_VOQ_DESA 0x0320
141#define REG_VIQ_DESA 0x0328
142#define REG_BEQ_DESA 0x0330
143#define REG_BKQ_DESA 0x0338
144#define REG_RX_DESA 0x0340
145#define REG_DBI 0x0348
146#define REG_MDIO 0x0354
147#define REG_DBG_SEL 0x0360
148#define REG_PCIE_HRPWM 0x0361
149#define REG_PCIE_HCPWM 0x0363
150#define REG_UART_CTRL 0x0364
151#define REG_UART_TX_DESA 0x0370
152#define REG_UART_RX_DESA 0x0378
153
154#define REG_HDAQ_DESA_NODEF 0x0000
155#define REG_CMDQ_DESA_NODEF 0x0000
156
157#define REG_VOQ_INFORMATION 0x0400
158#define REG_VIQ_INFORMATION 0x0404
159#define REG_BEQ_INFORMATION 0x0408
160#define REG_BKQ_INFORMATION 0x040C
161#define REG_MGQ_INFORMATION 0x0410
162#define REG_HGQ_INFORMATION 0x0414
163#define REG_BCNQ_INFORMATION 0x0418
164
165#define REG_CPU_MGQ_INFORMATION 0x041C
166#define REG_FWHW_TXQ_CTRL 0x0420
167#define REG_HWSEQ_CTRL 0x0423
168#define REG_TXPKTBUF_BCNQ_BDNY 0x0424
169#define REG_TXPKTBUF_MGQ_BDNY 0x0425
170#define REG_MULTI_BCNQ_EN 0x0426
171#define REG_MULTI_BCNQ_OFFSET 0x0427
172#define REG_SPEC_SIFS 0x0428
173#define REG_RL 0x042A
174#define REG_DARFRC 0x0430
175#define REG_RARFRC 0x0438
176#define REG_RRSR 0x0440
177#define REG_ARFR0 0x0444
178#define REG_ARFR1 0x0448
179#define REG_ARFR2 0x044C
180#define REG_ARFR3 0x0450
181#define REG_AGGLEN_LMT 0x0458
182#define REG_AMPDU_MIN_SPACE 0x045C
183#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D
184#define REG_FAST_EDCA_CTRL 0x0460
185#define REG_RD_RESP_PKT_TH 0x0463
186#define REG_INIRTS_RATE_SEL 0x0480
187#define REG_INIDATA_RATE_SEL 0x0484
188#define REG_POWER_STATUS 0x04A4
189#define REG_POWER_STAGE1 0x04B4
190#define REG_POWER_STAGE2 0x04B8
191#define REG_PKT_LIFE_TIME 0x04C0
192#define REG_STBC_SETTING 0x04C4
193#define REG_PROT_MODE_CTRL 0x04C8
194#define REG_BAR_MODE_CTRL 0x04CC
195#define REG_RA_TRY_RATE_AGG_LMT 0x04CF
196#define REG_NQOS_SEQ 0x04DC
197#define REG_QOS_SEQ 0x04DE
198#define REG_NEED_CPU_HANDLE 0x04E0
199#define REG_PKT_LOSE_RPT 0x04E1
200#define REG_PTCL_ERR_STATUS 0x04E2
201#define REG_DUMMY 0x04FC
202
203#define REG_EDCA_VO_PARAM 0x0500
204#define REG_EDCA_VI_PARAM 0x0504
205#define REG_EDCA_BE_PARAM 0x0508
206#define REG_EDCA_BK_PARAM 0x050C
207#define REG_BCNTCFG 0x0510
208#define REG_PIFS 0x0512
209#define REG_RDG_PIFS 0x0513
210#define REG_SIFS_CTX 0x0514
211#define REG_SIFS_TRX 0x0516
212#define REG_AGGR_BREAK_TIME 0x051A
213#define REG_SLOT 0x051B
214#define REG_TX_PTCL_CTRL 0x0520
215#define REG_TXPAUSE 0x0522
216#define REG_DIS_TXREQ_CLR 0x0523
217#define REG_RD_CTRL 0x0524
218#define REG_TBTT_PROHIBIT 0x0540
219#define REG_RD_NAV_NXT 0x0544
220#define REG_NAV_PROT_LEN 0x0546
221#define REG_BCN_CTRL 0x0550
222#define REG_USTIME_TSF 0x0551
223#define REG_MBID_NUM 0x0552
224#define REG_DUAL_TSF_RST 0x0553
225#define REG_BCN_INTERVAL 0x0554
226#define REG_MBSSID_BCN_SPACE 0x0554
227#define REG_DRVERLYINT 0x0558
228#define REG_BCNDMATIM 0x0559
229#define REG_ATIMWND 0x055A
230#define REG_BCN_MAX_ERR 0x055D
231#define REG_RXTSF_OFFSET_CCK 0x055E
232#define REG_RXTSF_OFFSET_OFDM 0x055F
233#define REG_TSFTR 0x0560
234#define REG_INIT_TSFTR 0x0564
235#define REG_PSTIMER 0x0580
236#define REG_TIMER0 0x0584
237#define REG_TIMER1 0x0588
238#define REG_ACMHWCTRL 0x05C0
239#define REG_ACMRSTCTRL 0x05C1
240#define REG_ACMAVG 0x05C2
241#define REG_VO_ADMTIME 0x05C4
242#define REG_VI_ADMTIME 0x05C6
243#define REG_BE_ADMTIME 0x05C8
244#define REG_EDCA_RANDOM_GEN 0x05CC
245#define REG_SCH_TXCMD 0x05D0
246
247#define REG_APSD_CTRL 0x0600
248#define REG_BWOPMODE 0x0603
249#define REG_TCR 0x0604
250#define REG_RCR 0x0608
251#define REG_RX_PKT_LIMIT 0x060C
252#define REG_RX_DLK_TIME 0x060D
253#define REG_RX_DRVINFO_SZ 0x060F
254
255#define REG_MACID 0x0610
256#define REG_BSSID 0x0618
257#define REG_MAR 0x0620
258#define REG_MBIDCAMCFG 0x0628
259
260#define REG_USTIME_EDCA 0x0638
261#define REG_MAC_SPEC_SIFS 0x063A
262#define REG_RESP_SIFS_CCK 0x063C
263#define REG_RESP_SIFS_OFDM 0x063E
264#define REG_ACKTO 0x0640
265#define REG_CTS2TO 0x0641
266#define REG_EIFS 0x0642
267
268#define REG_NAV_CTRL 0x0650
269#define REG_BACAMCMD 0x0654
270#define REG_BACAMCONTENT 0x0658
271#define REG_LBDLY 0x0660
272#define REG_FWDLY 0x0661
273#define REG_RXERR_RPT 0x0664
274#define REG_WMAC_TRXPTCL_CTL 0x0668
275
276#define REG_CAMCMD 0x0670
277#define REG_CAMWRITE 0x0674
278#define REG_CAMREAD 0x0678
279#define REG_CAMDBG 0x067C
280#define REG_SECCFG 0x0680
281
282#define REG_WOW_CTRL 0x0690
283#define REG_PSSTATUS 0x0691
284#define REG_PS_RX_INFO 0x0692
285#define REG_LPNAV_CTRL 0x0694
286#define REG_WKFMCAM_CMD 0x0698
287#define REG_WKFMCAM_RWD 0x069C
288#define REG_RXFLTMAP0 0x06A0
289#define REG_RXFLTMAP1 0x06A2
290#define REG_RXFLTMAP2 0x06A4
291#define REG_BCN_PSR_RPT 0x06A8
292#define REG_CALB32K_CTRL 0x06AC
293#define REG_PKT_MON_CTRL 0x06B4
294#define REG_BT_COEX_TABLE 0x06C0
295#define REG_WMAC_RESP_TXINFO 0x06D8
296
297#define REG_USB_INFO 0xFE17
298#define REG_USB_SPECIAL_OPTION 0xFE55
299#define REG_USB_DMA_AGG_TO 0xFE5B
300#define REG_USB_AGG_TO 0xFE5C
301#define REG_USB_AGG_TH 0xFE5D
302
303#define REG_TEST_USB_TXQS 0xFE48
304#define REG_TEST_SIE_VID 0xFE60
305#define REG_TEST_SIE_PID 0xFE62
306#define REG_TEST_SIE_OPTIONAL 0xFE64
307#define REG_TEST_SIE_CHIRP_K 0xFE65
308#define REG_TEST_SIE_PHY 0xFE66
309#define REG_TEST_SIE_MAC_ADDR 0xFE70
310#define REG_TEST_SIE_STRING 0xFE80
311
312#define REG_NORMAL_SIE_VID 0xFE60
313#define REG_NORMAL_SIE_PID 0xFE62
314#define REG_NORMAL_SIE_OPTIONAL 0xFE64
315#define REG_NORMAL_SIE_EP 0xFE65
316#define REG_NORMAL_SIE_PHY 0xFE68
317#define REG_NORMAL_SIE_MAC_ADDR 0xFE70
318#define REG_NORMAL_SIE_STRING 0xFE80
319
320#define CR9346 REG_9346CR
321#define MSR (REG_CR + 2)
322#define ISR REG_HISR
323#define TSFR REG_TSFTR
324
325#define MACIDR0 REG_MACID
326#define MACIDR4 (REG_MACID + 4)
327
328#define PBP REG_PBP
329
330#define IDR0 MACIDR0
331#define IDR4 MACIDR4
332
333#define UNUSED_REGISTER 0x1BF
334#define DCAM UNUSED_REGISTER
335#define PSR UNUSED_REGISTER
336#define BBADDR UNUSED_REGISTER
337#define PHYDATAR UNUSED_REGISTER
338
339#define INVALID_BBRF_VALUE 0x12345678
340
341#define MAX_MSS_DENSITY_2T 0x13
342#define MAX_MSS_DENSITY_1T 0x0A
343
344#define CMDEEPROM_EN BIT(5)
345#define CMDEEPROM_SEL BIT(4)
346#define CMD9346CR_9356SEL BIT(4)
347#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL)
348#define AUTOLOAD_EFUSE CMDEEPROM_EN
349
350#define GPIOSEL_GPIO 0
351#define GPIOSEL_ENBT BIT(5)
352
353#define GPIO_IN REG_GPIO_PIN_CTRL
354#define GPIO_OUT (REG_GPIO_PIN_CTRL+1)
355#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2)
356#define GPIO_MOD (REG_GPIO_PIN_CTRL+3)
357
358#define MSR_NOLINK 0x00
359#define MSR_ADHOC 0x01
360#define MSR_INFRA 0x02
361#define MSR_AP 0x03
362
363#define RRSR_RSC_OFFSET 21
364#define RRSR_SHORT_OFFSET 23
365#define RRSR_RSC_BW_40M 0x600000
366#define RRSR_RSC_UPSUBCHNL 0x400000
367#define RRSR_RSC_LOWSUBCHNL 0x200000
368#define RRSR_SHORT 0x800000
369#define RRSR_1M BIT(0)
370#define RRSR_2M BIT(1)
371#define RRSR_5_5M BIT(2)
372#define RRSR_11M BIT(3)
373#define RRSR_6M BIT(4)
374#define RRSR_9M BIT(5)
375#define RRSR_12M BIT(6)
376#define RRSR_18M BIT(7)
377#define RRSR_24M BIT(8)
378#define RRSR_36M BIT(9)
379#define RRSR_48M BIT(10)
380#define RRSR_54M BIT(11)
381#define RRSR_MCS0 BIT(12)
382#define RRSR_MCS1 BIT(13)
383#define RRSR_MCS2 BIT(14)
384#define RRSR_MCS3 BIT(15)
385#define RRSR_MCS4 BIT(16)
386#define RRSR_MCS5 BIT(17)
387#define RRSR_MCS6 BIT(18)
388#define RRSR_MCS7 BIT(19)
389#define BRSR_ACKSHORTPMB BIT(23)
390
391#define RATR_1M 0x00000001
392#define RATR_2M 0x00000002
393#define RATR_55M 0x00000004
394#define RATR_11M 0x00000008
395#define RATR_6M 0x00000010
396#define RATR_9M 0x00000020
397#define RATR_12M 0x00000040
398#define RATR_18M 0x00000080
399#define RATR_24M 0x00000100
400#define RATR_36M 0x00000200
401#define RATR_48M 0x00000400
402#define RATR_54M 0x00000800
403#define RATR_MCS0 0x00001000
404#define RATR_MCS1 0x00002000
405#define RATR_MCS2 0x00004000
406#define RATR_MCS3 0x00008000
407#define RATR_MCS4 0x00010000
408#define RATR_MCS5 0x00020000
409#define RATR_MCS6 0x00040000
410#define RATR_MCS7 0x00080000
411#define RATR_MCS8 0x00100000
412#define RATR_MCS9 0x00200000
413#define RATR_MCS10 0x00400000
414#define RATR_MCS11 0x00800000
415#define RATR_MCS12 0x01000000
416#define RATR_MCS13 0x02000000
417#define RATR_MCS14 0x04000000
418#define RATR_MCS15 0x08000000
419
420#define RATE_1M BIT(0)
421#define RATE_2M BIT(1)
422#define RATE_5_5M BIT(2)
423#define RATE_11M BIT(3)
424#define RATE_6M BIT(4)
425#define RATE_9M BIT(5)
426#define RATE_12M BIT(6)
427#define RATE_18M BIT(7)
428#define RATE_24M BIT(8)
429#define RATE_36M BIT(9)
430#define RATE_48M BIT(10)
431#define RATE_54M BIT(11)
432#define RATE_MCS0 BIT(12)
433#define RATE_MCS1 BIT(13)
434#define RATE_MCS2 BIT(14)
435#define RATE_MCS3 BIT(15)
436#define RATE_MCS4 BIT(16)
437#define RATE_MCS5 BIT(17)
438#define RATE_MCS6 BIT(18)
439#define RATE_MCS7 BIT(19)
440#define RATE_MCS8 BIT(20)
441#define RATE_MCS9 BIT(21)
442#define RATE_MCS10 BIT(22)
443#define RATE_MCS11 BIT(23)
444#define RATE_MCS12 BIT(24)
445#define RATE_MCS13 BIT(25)
446#define RATE_MCS14 BIT(26)
447#define RATE_MCS15 BIT(27)
448
449#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M)
450#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M \
451 | RATR_24M | RATR_36M | RATR_48M | RATR_54M)
452#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \
453 RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \
454 RATR_MCS6 | RATR_MCS7)
455#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \
456 RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \
457 RATR_MCS14 | RATR_MCS15)
458
459#define BW_OPMODE_20MHZ BIT(2)
460#define BW_OPMODE_5G BIT(1)
461#define BW_OPMODE_11J BIT(0)
462
463#define CAM_VALID BIT(15)
464#define CAM_NOTVALID 0x0000
465#define CAM_USEDK BIT(5)
466
467#define CAM_NONE 0x0
468#define CAM_WEP40 0x01
469#define CAM_TKIP 0x02
470#define CAM_AES 0x04
471#define CAM_WEP104 0x05
472
473#define TOTAL_CAM_ENTRY 32
474#define HALF_CAM_ENTRY 16
475
476#define CAM_WRITE BIT(16)
477#define CAM_READ 0x00000000
478#define CAM_POLLINIG BIT(31)
479
480#define SCR_USEDK 0x01
481#define SCR_TXSEC_ENABLE 0x02
482#define SCR_RXSEC_ENABLE 0x04
483
484#define WOW_PMEN BIT(0)
485#define WOW_WOMEN BIT(1)
486#define WOW_MAGIC BIT(2)
487#define WOW_UWF BIT(3)
488
489#define IMR8190_DISABLED 0x0
490#define IMR_BCNDMAINT6 BIT(31)
491#define IMR_BCNDMAINT5 BIT(30)
492#define IMR_BCNDMAINT4 BIT(29)
493#define IMR_BCNDMAINT3 BIT(28)
494#define IMR_BCNDMAINT2 BIT(27)
495#define IMR_BCNDMAINT1 BIT(26)
496#define IMR_BCNDOK8 BIT(25)
497#define IMR_BCNDOK7 BIT(24)
498#define IMR_BCNDOK6 BIT(23)
499#define IMR_BCNDOK5 BIT(22)
500#define IMR_BCNDOK4 BIT(21)
501#define IMR_BCNDOK3 BIT(20)
502#define IMR_BCNDOK2 BIT(19)
503#define IMR_BCNDOK1 BIT(18)
504#define IMR_TIMEOUT2 BIT(17)
505#define IMR_TIMEOUT1 BIT(16)
506#define IMR_TXFOVW BIT(15)
507#define IMR_PSTIMEOUT BIT(14)
508#define IMR_BCNINT BIT(13)
509#define IMR_RXFOVW BIT(12)
510#define IMR_RDU BIT(11)
511#define IMR_ATIMEND BIT(10)
512#define IMR_BDOK BIT(9)
513#define IMR_HIGHDOK BIT(8)
514#define IMR_TBDOK BIT(7)
515#define IMR_MGNTDOK BIT(6)
516#define IMR_TBDER BIT(5)
517#define IMR_BKDOK BIT(4)
518#define IMR_BEDOK BIT(3)
519#define IMR_VIDOK BIT(2)
520#define IMR_VODOK BIT(1)
521#define IMR_ROK BIT(0)
522
523#define IMR_TXERR BIT(11)
524#define IMR_RXERR BIT(10)
525#define IMR_C2HCMD BIT(9)
526#define IMR_CPWM BIT(8)
527#define IMR_OCPINT BIT(1)
528#define IMR_WLANOFF BIT(0)
529
530#define HWSET_MAX_SIZE 128
531
532#define EEPROM_DEFAULT_TSSI 0x0
533#define EEPROM_DEFAULT_TXPOWERDIFF 0x0
534#define EEPROM_DEFAULT_CRYSTALCAP 0x5
535#define EEPROM_DEFAULT_BOARDTYPE 0x02
536#define EEPROM_DEFAULT_TXPOWER 0x1010
537#define EEPROM_DEFAULT_HT2T_TXPWR 0x10
538
539#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
540#define EEPROM_DEFAULT_THERMALMETER 0x12
541#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0
542#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5
543#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22
544#define EEPROM_DEFAULT_HT40_2SDIFF 0x0
545#define EEPROM_DEFAULT_HT20_DIFF 2
546#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
547#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0
548#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0
549
550#define RF_OPTION1 0x79
551#define RF_OPTION2 0x7A
552#define RF_OPTION3 0x7B
553#define RF_OPTION4 0x7C
554
555#define EEPROM_DEFAULT_PID 0x1234
556#define EEPROM_DEFAULT_VID 0x5678
557#define EEPROM_DEFAULT_CUSTOMERID 0xAB
558#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD
559#define EEPROM_DEFAULT_VERSION 0
560
561#define EEPROM_CHANNEL_PLAN_FCC 0x0
562#define EEPROM_CHANNEL_PLAN_IC 0x1
563#define EEPROM_CHANNEL_PLAN_ETSI 0x2
564#define EEPROM_CHANNEL_PLAN_SPAIN 0x3
565#define EEPROM_CHANNEL_PLAN_FRANCE 0x4
566#define EEPROM_CHANNEL_PLAN_MKK 0x5
567#define EEPROM_CHANNEL_PLAN_MKK1 0x6
568#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7
569#define EEPROM_CHANNEL_PLAN_TELEC 0x8
570#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9
571#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA
572#define EEPROM_CHANNEL_PLAN_NCC 0xB
573#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
574
575#define EEPROM_CID_DEFAULT 0x0
576#define EEPROM_CID_TOSHIBA 0x4
577#define EEPROM_CID_CCX 0x10
578#define EEPROM_CID_QMI 0x0D
579#define EEPROM_CID_WHQL 0xFE
580
581#define RTL8192_EEPROM_ID 0x8129
582
583#define RTL8190_EEPROM_ID 0x8129
584#define EEPROM_HPON 0x02
585#define EEPROM_CLK 0x06
586#define EEPROM_TESTR 0x08
587
588#define EEPROM_VID 0x0A
589#define EEPROM_DID 0x0C
590#define EEPROM_SVID 0x0E
591#define EEPROM_SMID 0x10
592
593#define EEPROM_MAC_ADDR 0x16
594
595#define EEPROM_CCK_TX_PWR_INX 0x5A
596#define EEPROM_HT40_1S_TX_PWR_INX 0x60
597#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66
598#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69
599#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C
600#define EEPROM_HT40_MAX_PWR_OFFSET 0x6F
601#define EEPROM_HT20_MAX_PWR_OFFSET 0x72
602
603#define EEPROM_TSSI_A 0x76
604#define EEPROM_TSSI_B 0x77
605#define EEPROM_THERMAL_METER 0x78
606#define EEPROM_XTAL_K 0x78
607#define EEPROM_RF_OPT1 0x79
608#define EEPROM_RF_OPT2 0x7A
609#define EEPROM_RF_OPT3 0x7B
610#define EEPROM_RF_OPT4 0x7C
611#define EEPROM_CHANNEL_PLAN 0x7D
612#define EEPROM_VERSION 0x7E
613#define EEPROM_CUSTOMER_ID 0x7F
614
615#define EEPROM_PWRDIFF 0x54
616
617#define EEPROM_TXPOWERCCK 0x5A
618#define EEPROM_TXPOWERHT40_1S 0x60
619#define EEPROM_TXPOWERHT40_2SDIFF 0x66
620#define EEPROM_TXPOWERHT20DIFF 0x69
621#define EEPROM_TXPOWER_OFDMDIFF 0x6C
622
623#define EEPROM_TXPWR_GROUP 0x6F
624
625#define EEPROM_TSSI_A 0x76
626#define EEPROM_TSSI_B 0x77
627#define EEPROM_THERMAL_METER 0x78
628
629#define EEPROM_CHANNELPLAN 0x75
630
631#define RF_OPTION1 0x79
632#define RF_OPTION2 0x7A
633#define RF_OPTION3 0x7B
634#define RF_OPTION4 0x7C
635
636#define STOPBECON BIT(6)
637#define STOPHIGHT BIT(5)
638#define STOPMGT BIT(4)
639#define STOPVO BIT(3)
640#define STOPVI BIT(2)
641#define STOPBE BIT(1)
642#define STOPBK BIT(0)
643
644#define RCR_APPFCS BIT(31)
645#define RCR_APP_MIC BIT(30)
646#define RCR_APP_ICV BIT(29)
647#define RCR_APP_PHYST_RXFF BIT(28)
648#define RCR_APP_BA_SSN BIT(27)
649#define RCR_ENMBID BIT(24)
650#define RCR_LSIGEN BIT(23)
651#define RCR_MFBEN BIT(22)
652#define RCR_HTC_LOC_CTRL BIT(14)
653#define RCR_AMF BIT(13)
654#define RCR_ACF BIT(12)
655#define RCR_ADF BIT(11)
656#define RCR_AICV BIT(9)
657#define RCR_ACRC32 BIT(8)
658#define RCR_CBSSID_BCN BIT(7)
659#define RCR_CBSSID_DATA BIT(6)
660#define RCR_CBSSID RCR_CBSSID_DATA
661#define RCR_APWRMGT BIT(5)
662#define RCR_ADD3 BIT(4)
663#define RCR_AB BIT(3)
664#define RCR_AM BIT(2)
665#define RCR_APM BIT(1)
666#define RCR_AAP BIT(0)
667#define RCR_MXDMA_OFFSET 8
668#define RCR_FIFO_OFFSET 13
669
670#define RSV_CTRL 0x001C
671#define RD_CTRL 0x0524
672
673#define REG_USB_INFO 0xFE17
674#define REG_USB_SPECIAL_OPTION 0xFE55
675#define REG_USB_DMA_AGG_TO 0xFE5B
676#define REG_USB_AGG_TO 0xFE5C
677#define REG_USB_AGG_TH 0xFE5D
678
679#define REG_USB_VID 0xFE60
680#define REG_USB_PID 0xFE62
681#define REG_USB_OPTIONAL 0xFE64
682#define REG_USB_CHIRP_K 0xFE65
683#define REG_USB_PHY 0xFE66
684#define REG_USB_MAC_ADDR 0xFE70
685#define REG_USB_HRPWM 0xFE58
686#define REG_USB_HCPWM 0xFE57
687
688#define SW18_FPWM BIT(3)
689
690#define ISO_MD2PP BIT(0)
691#define ISO_UA2USB BIT(1)
692#define ISO_UD2CORE BIT(2)
693#define ISO_PA2PCIE BIT(3)
694#define ISO_PD2CORE BIT(4)
695#define ISO_IP2MAC BIT(5)
696#define ISO_DIOP BIT(6)
697#define ISO_DIOE BIT(7)
698#define ISO_EB2CORE BIT(8)
699#define ISO_DIOR BIT(9)
700
701#define PWC_EV25V BIT(14)
702#define PWC_EV12V BIT(15)
703
704#define FEN_BBRSTB BIT(0)
705#define FEN_BB_GLB_RSTn BIT(1)
706#define FEN_USBA BIT(2)
707#define FEN_UPLL BIT(3)
708#define FEN_USBD BIT(4)
709#define FEN_DIO_PCIE BIT(5)
710#define FEN_PCIEA BIT(6)
711#define FEN_PPLL BIT(7)
712#define FEN_PCIED BIT(8)
713#define FEN_DIOE BIT(9)
714#define FEN_CPUEN BIT(10)
715#define FEN_DCORE BIT(11)
716#define FEN_ELDR BIT(12)
717#define FEN_DIO_RF BIT(13)
718#define FEN_HWPDN BIT(14)
719#define FEN_MREGEN BIT(15)
720
721#define PFM_LDALL BIT(0)
722#define PFM_ALDN BIT(1)
723#define PFM_LDKP BIT(2)
724#define PFM_WOWL BIT(3)
725#define EnPDN BIT(4)
726#define PDN_PL BIT(5)
727#define APFM_ONMAC BIT(8)
728#define APFM_OFF BIT(9)
729#define APFM_RSM BIT(10)
730#define AFSM_HSUS BIT(11)
731#define AFSM_PCIE BIT(12)
732#define APDM_MAC BIT(13)
733#define APDM_HOST BIT(14)
734#define APDM_HPDN BIT(15)
735#define RDY_MACON BIT(16)
736#define SUS_HOST BIT(17)
737#define ROP_ALD BIT(20)
738#define ROP_PWR BIT(21)
739#define ROP_SPS BIT(22)
740#define SOP_MRST BIT(25)
741#define SOP_FUSE BIT(26)
742#define SOP_ABG BIT(27)
743#define SOP_AMB BIT(28)
744#define SOP_RCK BIT(29)
745#define SOP_A8M BIT(30)
746#define XOP_BTCK BIT(31)
747
748#define ANAD16V_EN BIT(0)
749#define ANA8M BIT(1)
750#define MACSLP BIT(4)
751#define LOADER_CLK_EN BIT(5)
752#define _80M_SSC_DIS BIT(7)
753#define _80M_SSC_EN_HO BIT(8)
754#define PHY_SSC_RSTB BIT(9)
755#define SEC_CLK_EN BIT(10)
756#define MAC_CLK_EN BIT(11)
757#define SYS_CLK_EN BIT(12)
758#define RING_CLK_EN BIT(13)
759
760#define BOOT_FROM_EEPROM BIT(4)
761#define EEPROM_EN BIT(5)
762
763#define AFE_BGEN BIT(0)
764#define AFE_MBEN BIT(1)
765#define MAC_ID_EN BIT(7)
766
767#define WLOCK_ALL BIT(0)
768#define WLOCK_00 BIT(1)
769#define WLOCK_04 BIT(2)
770#define WLOCK_08 BIT(3)
771#define WLOCK_40 BIT(4)
772#define R_DIS_PRST_0 BIT(5)
773#define R_DIS_PRST_1 BIT(6)
774#define LOCK_ALL_EN BIT(7)
775
776#define RF_EN BIT(0)
777#define RF_RSTB BIT(1)
778#define RF_SDMRSTB BIT(2)
779
780#define LDA15_EN BIT(0)
781#define LDA15_STBY BIT(1)
782#define LDA15_OBUF BIT(2)
783#define LDA15_REG_VOS BIT(3)
784#define _LDA15_VOADJ(x) (((x) & 0x7) << 4)
785
786#define LDV12_EN BIT(0)
787#define LDV12_SDBY BIT(1)
788#define LPLDO_HSM BIT(2)
789#define LPLDO_LSM_DIS BIT(3)
790#define _LDV12_VADJ(x) (((x) & 0xF) << 4)
791
792#define XTAL_EN BIT(0)
793#define XTAL_BSEL BIT(1)
794#define _XTAL_BOSC(x) (((x) & 0x3) << 2)
795#define _XTAL_CADJ(x) (((x) & 0xF) << 4)
796#define XTAL_GATE_USB BIT(8)
797#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9)
798#define XTAL_GATE_AFE BIT(11)
799#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12)
800#define XTAL_RF_GATE BIT(14)
801#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15)
802#define XTAL_GATE_DIG BIT(17)
803#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18)
804#define XTAL_BT_GATE BIT(20)
805#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21)
806#define _XTAL_GPIO(x) (((x) & 0x7) << 23)
807
808#define CKDLY_AFE BIT(26)
809#define CKDLY_USB BIT(27)
810#define CKDLY_DIG BIT(28)
811#define CKDLY_BT BIT(29)
812
813#define APLL_EN BIT(0)
814#define APLL_320_EN BIT(1)
815#define APLL_FREF_SEL BIT(2)
816#define APLL_EDGE_SEL BIT(3)
817#define APLL_WDOGB BIT(4)
818#define APLL_LPFEN BIT(5)
819
820#define APLL_REF_CLK_13MHZ 0x1
821#define APLL_REF_CLK_19_2MHZ 0x2
822#define APLL_REF_CLK_20MHZ 0x3
823#define APLL_REF_CLK_25MHZ 0x4
824#define APLL_REF_CLK_26MHZ 0x5
825#define APLL_REF_CLK_38_4MHZ 0x6
826#define APLL_REF_CLK_40MHZ 0x7
827
828#define APLL_320EN BIT(14)
829#define APLL_80EN BIT(15)
830#define APLL_1MEN BIT(24)
831
832#define ALD_EN BIT(18)
833#define EF_PD BIT(19)
834#define EF_FLAG BIT(31)
835
836#define EF_TRPT BIT(7)
837#define LDOE25_EN BIT(31)
838
839#define RSM_EN BIT(0)
840#define Timer_EN BIT(4)
841
842#define TRSW0EN BIT(2)
843#define TRSW1EN BIT(3)
844#define EROM_EN BIT(4)
845#define EnBT BIT(5)
846#define EnUart BIT(8)
847#define Uart_910 BIT(9)
848#define EnPMAC BIT(10)
849#define SIC_SWRST BIT(11)
850#define EnSIC BIT(12)
851#define SIC_23 BIT(13)
852#define EnHDP BIT(14)
853#define SIC_LBK BIT(15)
854
855#define LED0PL BIT(4)
856#define LED1PL BIT(12)
857#define LED0DIS BIT(7)
858
859#define MCUFWDL_EN BIT(0)
860#define MCUFWDL_RDY BIT(1)
861#define FWDL_ChkSum_rpt BIT(2)
862#define MACINI_RDY BIT(3)
863#define BBINI_RDY BIT(4)
864#define RFINI_RDY BIT(5)
865#define WINTINI_RDY BIT(6)
866#define CPRST BIT(23)
867
868#define XCLK_VLD BIT(0)
869#define ACLK_VLD BIT(1)
870#define UCLK_VLD BIT(2)
871#define PCLK_VLD BIT(3)
872#define PCIRSTB BIT(4)
873#define V15_VLD BIT(5)
874#define TRP_B15V_EN BIT(7)
875#define SIC_IDLE BIT(8)
876#define BD_MAC2 BIT(9)
877#define BD_MAC1 BIT(10)
878#define IC_MACPHY_MODE BIT(11)
879#define PAD_HWPD_IDN BIT(22)
880#define TRP_VAUX_EN BIT(23)
881#define TRP_BT_EN BIT(24)
882#define BD_PKG_SEL BIT(25)
883#define BD_HCI_SEL BIT(26)
884#define TYPE_ID BIT(27)
885
886#define CHIP_VER_RTL_MASK 0xF000
887#define CHIP_VER_RTL_SHIFT 12
888
889#define REG_LBMODE (REG_CR + 3)
890
891#define HCI_TXDMA_EN BIT(0)
892#define HCI_RXDMA_EN BIT(1)
893#define TXDMA_EN BIT(2)
894#define RXDMA_EN BIT(3)
895#define PROTOCOL_EN BIT(4)
896#define SCHEDULE_EN BIT(5)
897#define MACTXEN BIT(6)
898#define MACRXEN BIT(7)
899#define ENSWBCN BIT(8)
900#define ENSEC BIT(9)
901
902#define _NETTYPE(x) (((x) & 0x3) << 16)
903#define MASK_NETTYPE 0x30000
904#define NT_NO_LINK 0x0
905#define NT_LINK_AD_HOC 0x1
906#define NT_LINK_AP 0x2
907#define NT_AS_AP 0x3
908
909#define _LBMODE(x) (((x) & 0xF) << 24)
910#define MASK_LBMODE 0xF000000
911#define LOOPBACK_NORMAL 0x0
912#define LOOPBACK_IMMEDIATELY 0xB
913#define LOOPBACK_MAC_DELAY 0x3
914#define LOOPBACK_PHY 0x1
915#define LOOPBACK_DMA 0x7
916
917#define GET_RX_PAGE_SIZE(value) ((value) & 0xF)
918#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4)
919#define _PSRX_MASK 0xF
920#define _PSTX_MASK 0xF0
921#define _PSRX(x) (x)
922#define _PSTX(x) ((x) << 4)
923
924#define PBP_64 0x0
925#define PBP_128 0x1
926#define PBP_256 0x2
927#define PBP_512 0x3
928#define PBP_1024 0x4
929
930#define RXDMA_ARBBW_EN BIT(0)
931#define RXSHFT_EN BIT(1)
932#define RXDMA_AGG_EN BIT(2)
933#define QS_VO_QUEUE BIT(8)
934#define QS_VI_QUEUE BIT(9)
935#define QS_BE_QUEUE BIT(10)
936#define QS_BK_QUEUE BIT(11)
937#define QS_MANAGER_QUEUE BIT(12)
938#define QS_HIGH_QUEUE BIT(13)
939
940#define HQSEL_VOQ BIT(0)
941#define HQSEL_VIQ BIT(1)
942#define HQSEL_BEQ BIT(2)
943#define HQSEL_BKQ BIT(3)
944#define HQSEL_MGTQ BIT(4)
945#define HQSEL_HIQ BIT(5)
946
947#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14)
948#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12)
949#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10)
950#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8)
951#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6)
952#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4)
953
954#define QUEUE_LOW 1
955#define QUEUE_NORMAL 2
956#define QUEUE_HIGH 3
957
958#define _LLT_NO_ACTIVE 0x0
959#define _LLT_WRITE_ACCESS 0x1
960#define _LLT_READ_ACCESS 0x2
961
962#define _LLT_INIT_DATA(x) ((x) & 0xFF)
963#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8)
964#define _LLT_OP(x) (((x) & 0x3) << 30)
965#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3)
966
967#define BB_WRITE_READ_MASK (BIT(31) | BIT(30))
968#define BB_WRITE_EN BIT(30)
969#define BB_READ_EN BIT(31)
970
971#define _HPQ(x) ((x) & 0xFF)
972#define _LPQ(x) (((x) & 0xFF) << 8)
973#define _PUBQ(x) (((x) & 0xFF) << 16)
974#define _NPQ(x) ((x) & 0xFF)
975
976#define HPQ_PUBLIC_DIS BIT(24)
977#define LPQ_PUBLIC_DIS BIT(25)
978#define LD_RQPN BIT(31)
979
980#define BCN_VALID BIT(16)
981#define BCN_HEAD(x) (((x) & 0xFF) << 8)
982#define BCN_HEAD_MASK 0xFF00
983
984#define BLK_DESC_NUM_SHIFT 4
985#define BLK_DESC_NUM_MASK 0xF
986
987#define DROP_DATA_EN BIT(9)
988
989#define EN_AMPDU_RTY_NEW BIT(7)
990
991#define _INIRTSMCS_SEL(x) ((x) & 0x3F)
992
993#define _SPEC_SIFS_CCK(x) ((x) & 0xFF)
994#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8)
995
996#define RATE_REG_BITMAP_ALL 0xFFFFF
997
998#define _RRSC_BITMAP(x) ((x) & 0xFFFFF)
999
1000#define _RRSR_RSC(x) (((x) & 0x3) << 21)
1001#define RRSR_RSC_RESERVED 0x0
1002#define RRSR_RSC_UPPER_SUBCHANNEL 0x1
1003#define RRSR_RSC_LOWER_SUBCHANNEL 0x2
1004#define RRSR_RSC_DUPLICATE_MODE 0x3
1005
1006#define USE_SHORT_G1 BIT(20)
1007
1008#define _AGGLMT_MCS0(x) ((x) & 0xF)
1009#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4)
1010#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8)
1011#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12)
1012#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16)
1013#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20)
1014#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24)
1015#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28)
1016
1017#define RETRY_LIMIT_SHORT_SHIFT 8
1018#define RETRY_LIMIT_LONG_SHIFT 0
1019
1020#define _DARF_RC1(x) ((x) & 0x1F)
1021#define _DARF_RC2(x) (((x) & 0x1F) << 8)
1022#define _DARF_RC3(x) (((x) & 0x1F) << 16)
1023#define _DARF_RC4(x) (((x) & 0x1F) << 24)
1024#define _DARF_RC5(x) ((x) & 0x1F)
1025#define _DARF_RC6(x) (((x) & 0x1F) << 8)
1026#define _DARF_RC7(x) (((x) & 0x1F) << 16)
1027#define _DARF_RC8(x) (((x) & 0x1F) << 24)
1028
1029#define _RARF_RC1(x) ((x) & 0x1F)
1030#define _RARF_RC2(x) (((x) & 0x1F) << 8)
1031#define _RARF_RC3(x) (((x) & 0x1F) << 16)
1032#define _RARF_RC4(x) (((x) & 0x1F) << 24)
1033#define _RARF_RC5(x) ((x) & 0x1F)
1034#define _RARF_RC6(x) (((x) & 0x1F) << 8)
1035#define _RARF_RC7(x) (((x) & 0x1F) << 16)
1036#define _RARF_RC8(x) (((x) & 0x1F) << 24)
1037
1038#define AC_PARAM_TXOP_LIMIT_OFFSET 16
1039#define AC_PARAM_ECW_MAX_OFFSET 12
1040#define AC_PARAM_ECW_MIN_OFFSET 8
1041#define AC_PARAM_AIFS_OFFSET 0
1042
1043#define _AIFS(x) (x)
1044#define _ECW_MAX_MIN(x) ((x) << 8)
1045#define _TXOP_LIMIT(x) ((x) << 16)
1046
1047#define _BCNIFS(x) ((x) & 0xFF)
1048#define _BCNECW(x) ((((x) & 0xF)) << 8)
1049
1050#define _LRL(x) ((x) & 0x3F)
1051#define _SRL(x) (((x) & 0x3F) << 8)
1052
1053#define _SIFS_CCK_CTX(x) ((x) & 0xFF)
1054#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8);
1055
1056#define _SIFS_OFDM_CTX(x) ((x) & 0xFF)
1057#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8);
1058
1059#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8)
1060
1061#define DIS_EDCA_CNT_DWN BIT(11)
1062
1063#define EN_MBSSID BIT(1)
1064#define EN_TXBCN_RPT BIT(2)
1065#define EN_BCN_FUNCTION BIT(3)
1066
1067#define TSFTR_RST BIT(0)
1068#define TSFTR1_RST BIT(1)
1069
1070#define STOP_BCNQ BIT(6)
1071
1072#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4)
1073#define DIS_TSF_UDT0_TEST_CHIP BIT(5)
1074
1075#define AcmHw_HwEn BIT(0)
1076#define AcmHw_BeqEn BIT(1)
1077#define AcmHw_ViqEn BIT(2)
1078#define AcmHw_VoqEn BIT(3)
1079#define AcmHw_BeqStatus BIT(4)
1080#define AcmHw_ViqStatus BIT(5)
1081#define AcmHw_VoqStatus BIT(6)
1082
1083#define APSDOFF BIT(6)
1084#define APSDOFF_STATUS BIT(7)
1085
1086#define BW_20MHZ BIT(2)
1087
1088#define RATE_BITMAP_ALL 0xFFFFF
1089
1090#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1
1091
1092#define TSFRST BIT(0)
1093#define DIS_GCLK BIT(1)
1094#define PAD_SEL BIT(2)
1095#define PWR_ST BIT(6)
1096#define PWRBIT_OW_EN BIT(7)
1097#define ACRC BIT(8)
1098#define CFENDFORM BIT(9)
1099#define ICV BIT(10)
1100
1101#define AAP BIT(0)
1102#define APM BIT(1)
1103#define AM BIT(2)
1104#define AB BIT(3)
1105#define ADD3 BIT(4)
1106#define APWRMGT BIT(5)
1107#define CBSSID BIT(6)
1108#define CBSSID_DATA BIT(6)
1109#define CBSSID_BCN BIT(7)
1110#define ACRC32 BIT(8)
1111#define AICV BIT(9)
1112#define ADF BIT(11)
1113#define ACF BIT(12)
1114#define AMF BIT(13)
1115#define HTC_LOC_CTRL BIT(14)
1116#define UC_DATA_EN BIT(16)
1117#define BM_DATA_EN BIT(17)
1118#define MFBEN BIT(22)
1119#define LSIGEN BIT(23)
1120#define EnMBID BIT(24)
1121#define APP_BASSN BIT(27)
1122#define APP_PHYSTS BIT(28)
1123#define APP_ICV BIT(29)
1124#define APP_MIC BIT(30)
1125#define APP_FCS BIT(31)
1126
1127#define _MIN_SPACE(x) ((x) & 0x7)
1128#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3)
1129
1130#define RXERR_TYPE_OFDM_PPDU 0
1131#define RXERR_TYPE_OFDM_FALSE_ALARM 1
1132#define RXERR_TYPE_OFDM_MPDU_OK 2
1133#define RXERR_TYPE_OFDM_MPDU_FAIL 3
1134#define RXERR_TYPE_CCK_PPDU 4
1135#define RXERR_TYPE_CCK_FALSE_ALARM 5
1136#define RXERR_TYPE_CCK_MPDU_OK 6
1137#define RXERR_TYPE_CCK_MPDU_FAIL 7
1138#define RXERR_TYPE_HT_PPDU 8
1139#define RXERR_TYPE_HT_FALSE_ALARM 9
1140#define RXERR_TYPE_HT_MPDU_TOTAL 10
1141#define RXERR_TYPE_HT_MPDU_OK 11
1142#define RXERR_TYPE_HT_MPDU_FAIL 12
1143#define RXERR_TYPE_RX_FULL_DROP 15
1144
1145#define RXERR_COUNTER_MASK 0xFFFFF
1146#define RXERR_RPT_RST BIT(27)
1147#define _RXERR_RPT_SEL(type) ((type) << 28)
1148
1149#define SCR_TxUseDK BIT(0)
1150#define SCR_RxUseDK BIT(1)
1151#define SCR_TxEncEnable BIT(2)
1152#define SCR_RxDecEnable BIT(3)
1153#define SCR_SKByA2 BIT(4)
1154#define SCR_NoSKMC BIT(5)
1155#define SCR_TXBCUSEDK BIT(6)
1156#define SCR_RXBCUSEDK BIT(7)
1157
1158#define USB_IS_HIGH_SPEED 0
1159#define USB_IS_FULL_SPEED 1
1160#define USB_SPEED_MASK BIT(5)
1161
1162#define USB_NORMAL_SIE_EP_MASK 0xF
1163#define USB_NORMAL_SIE_EP_SHIFT 4
1164
1165#define USB_TEST_EP_MASK 0x30
1166#define USB_TEST_EP_SHIFT 4
1167
1168#define USB_AGG_EN BIT(3)
1169
1170#define MAC_ADDR_LEN 6
1171#define LAST_ENTRY_OF_TX_PKT_BUFFER 255
1172
1173#define POLLING_LLT_THRESHOLD 20
1174#define POLLING_READY_TIMEOUT_COUNT 1000
1175
1176#define MAX_MSS_DENSITY_2T 0x13
1177#define MAX_MSS_DENSITY_1T 0x0A
1178
1179#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
1180#define EPROM_CMD_CONFIG 0x3
1181#define EPROM_CMD_LOAD 1
1182
1183#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE
1184
1185#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2)
1186
1187#define RPMAC_RESET 0x100
1188#define RPMAC_TXSTART 0x104
1189#define RPMAC_TXLEGACYSIG 0x108
1190#define RPMAC_TXHTSIG1 0x10c
1191#define RPMAC_TXHTSIG2 0x110
1192#define RPMAC_PHYDEBUG 0x114
1193#define RPMAC_TXPACKETNUM 0x118
1194#define RPMAC_TXIDLE 0x11c
1195#define RPMAC_TXMACHEADER0 0x120
1196#define RPMAC_TXMACHEADER1 0x124
1197#define RPMAC_TXMACHEADER2 0x128
1198#define RPMAC_TXMACHEADER3 0x12c
1199#define RPMAC_TXMACHEADER4 0x130
1200#define RPMAC_TXMACHEADER5 0x134
1201#define RPMAC_TXDADATYPE 0x138
1202#define RPMAC_TXRANDOMSEED 0x13c
1203#define RPMAC_CCKPLCPPREAMBLE 0x140
1204#define RPMAC_CCKPLCPHEADER 0x144
1205#define RPMAC_CCKCRC16 0x148
1206#define RPMAC_OFDMRXCRC32OK 0x170
1207#define RPMAC_OFDMRXCRC32Er 0x174
1208#define RPMAC_OFDMRXPARITYER 0x178
1209#define RPMAC_OFDMRXCRC8ER 0x17c
1210#define RPMAC_CCKCRXRC16ER 0x180
1211#define RPMAC_CCKCRXRC32ER 0x184
1212#define RPMAC_CCKCRXRC32OK 0x188
1213#define RPMAC_TXSTATUS 0x18c
1214
1215#define RFPGA0_RFMOD 0x800
1216
1217#define RFPGA0_TXINFO 0x804
1218#define RFPGA0_PSDFUNCTION 0x808
1219
1220#define RFPGA0_TXGAINSTAGE 0x80c
1221
1222#define RFPGA0_RFTIMING1 0x810
1223#define RFPGA0_RFTIMING2 0x814
1224
1225#define RFPGA0_XA_HSSIPARAMETER1 0x820
1226#define RFPGA0_XA_HSSIPARAMETER2 0x824
1227#define RFPGA0_XB_HSSIPARAMETER1 0x828
1228#define RFPGA0_XB_HSSIPARAMETER2 0x82c
1229
1230#define RFPGA0_XA_LSSIPARAMETER 0x840
1231#define RFPGA0_XB_LSSIPARAMETER 0x844
1232
1233#define RFPGA0_RFWAKEUPPARAMETER 0x850
1234#define RFPGA0_RFSLEEPUPPARAMETER 0x854
1235
1236#define RFPGA0_XAB_SWITCHCONTROL 0x858
1237#define RFPGA0_XCD_SWITCHCONTROL 0x85c
1238
1239#define RFPGA0_XA_RFINTERFACEOE 0x860
1240#define RFPGA0_XB_RFINTERFACEOE 0x864
1241
1242#define RFPGA0_XAB_RFINTERFACESW 0x870
1243#define RFPGA0_XCD_RFINTERFACESW 0x874
1244
1245#define rFPGA0_XAB_RFPARAMETER 0x878
1246#define rFPGA0_XCD_RFPARAMETER 0x87c
1247
1248#define RFPGA0_ANALOGPARAMETER1 0x880
1249#define RFPGA0_ANALOGPARAMETER2 0x884
1250#define RFPGA0_ANALOGPARAMETER3 0x888
1251#define RFPGA0_ANALOGPARAMETER4 0x88c
1252
1253#define RFPGA0_XA_LSSIREADBACK 0x8a0
1254#define RFPGA0_XB_LSSIREADBACK 0x8a4
1255#define RFPGA0_XC_LSSIREADBACK 0x8a8
1256#define RFPGA0_XD_LSSIREADBACK 0x8ac
1257
1258#define RFPGA0_PSDREPORT 0x8b4
1259#define TRANSCEIVEA_HSPI_READBACK 0x8b8
1260#define TRANSCEIVEB_HSPI_READBACK 0x8bc
1261#define RFPGA0_XAB_RFINTERFACERB 0x8e0
1262#define RFPGA0_XCD_RFINTERFACERB 0x8e4
1263
1264#define RFPGA1_RFMOD 0x900
1265
1266#define RFPGA1_TXBLOCK 0x904
1267#define RFPGA1_DEBUGSELECT 0x908
1268#define RFPGA1_TXINFO 0x90c
1269
1270#define RCCK0_SYSTEM 0xa00
1271
1272#define RCCK0_AFESETTING 0xa04
1273#define RCCK0_CCA 0xa08
1274
1275#define RCCK0_RXAGC1 0xa0c
1276#define RCCK0_RXAGC2 0xa10
1277
1278#define RCCK0_RXHP 0xa14
1279
1280#define RCCK0_DSPPARAMETER1 0xa18
1281#define RCCK0_DSPPARAMETER2 0xa1c
1282
1283#define RCCK0_TXFILTER1 0xa20
1284#define RCCK0_TXFILTER2 0xa24
1285#define RCCK0_DEBUGPORT 0xa28
1286#define RCCK0_FALSEALARMREPORT 0xa2c
1287#define RCCK0_TRSSIREPORT 0xa50
1288#define RCCK0_RXREPORT 0xa54
1289#define RCCK0_FACOUNTERLOWER 0xa5c
1290#define RCCK0_FACOUNTERUPPER 0xa58
1291
1292#define ROFDM0_LSTF 0xc00
1293
1294#define ROFDM0_TRXPATHENABLE 0xc04
1295#define ROFDM0_TRMUXPAR 0xc08
1296#define ROFDM0_TRSWISOLATION 0xc0c
1297
1298#define ROFDM0_XARXAFE 0xc10
1299#define ROFDM0_XARXIQIMBALANCE 0xc14
1300#define ROFDM0_XBRXAFE 0xc18
1301#define ROFDM0_XBRXIQIMBALANCE 0xc1c
1302#define ROFDM0_XCRXAFE 0xc20
1303#define ROFDM0_XCRXIQIMBANLANCE 0xc24
1304#define ROFDM0_XDRXAFE 0xc28
1305#define ROFDM0_XDRXIQIMBALANCE 0xc2c
1306
1307#define ROFDM0_RXDETECTOR1 0xc30
1308#define ROFDM0_RXDETECTOR2 0xc34
1309#define ROFDM0_RXDETECTOR3 0xc38
1310#define ROFDM0_RXDETECTOR4 0xc3c
1311
1312#define ROFDM0_RXDSP 0xc40
1313#define ROFDM0_CFOANDDAGC 0xc44
1314#define ROFDM0_CCADROPTHRESHOLD 0xc48
1315#define ROFDM0_ECCATHRESHOLD 0xc4c
1316
1317#define ROFDM0_XAAGCCORE1 0xc50
1318#define ROFDM0_XAAGCCORE2 0xc54
1319#define ROFDM0_XBAGCCORE1 0xc58
1320#define ROFDM0_XBAGCCORE2 0xc5c
1321#define ROFDM0_XCAGCCORE1 0xc60
1322#define ROFDM0_XCAGCCORE2 0xc64
1323#define ROFDM0_XDAGCCORE1 0xc68
1324#define ROFDM0_XDAGCCORE2 0xc6c
1325
1326#define ROFDM0_AGCPARAMETER1 0xc70
1327#define ROFDM0_AGCPARAMETER2 0xc74
1328#define ROFDM0_AGCRSSITABLE 0xc78
1329#define ROFDM0_HTSTFAGC 0xc7c
1330
1331#define ROFDM0_XATXIQIMBALANCE 0xc80
1332#define ROFDM0_XATXAFE 0xc84
1333#define ROFDM0_XBTXIQIMBALANCE 0xc88
1334#define ROFDM0_XBTXAFE 0xc8c
1335#define ROFDM0_XCTXIQIMBALANCE 0xc90
1336#define ROFDM0_XCTXAFE 0xc94
1337#define ROFDM0_XDTXIQIMBALANCE 0xc98
1338#define ROFDM0_XDTXAFE 0xc9c
1339
1340#define ROFDM0_RXIQEXTANTA 0xca0
1341
1342#define ROFDM0_RXHPPARAMETER 0xce0
1343#define ROFDM0_TXPSEUDONOISEWGT 0xce4
1344#define ROFDM0_FRAMESYNC 0xcf0
1345#define ROFDM0_DFSREPORT 0xcf4
1346#define ROFDM0_TXCOEFF1 0xca4
1347#define ROFDM0_TXCOEFF2 0xca8
1348#define ROFDM0_TXCOEFF3 0xcac
1349#define ROFDM0_TXCOEFF4 0xcb0
1350#define ROFDM0_TXCOEFF5 0xcb4
1351#define ROFDM0_TXCOEFF6 0xcb8
1352
1353#define ROFDM1_LSTF 0xd00
1354#define ROFDM1_TRXPATHENABLE 0xd04
1355
1356#define ROFDM1_CF0 0xd08
1357#define ROFDM1_CSI1 0xd10
1358#define ROFDM1_SBD 0xd14
1359#define ROFDM1_CSI2 0xd18
1360#define ROFDM1_CFOTRACKING 0xd2c
1361#define ROFDM1_TRXMESAURE1 0xd34
1362#define ROFDM1_INTFDET 0xd3c
1363#define ROFDM1_PSEUDONOISESTATEAB 0xd50
1364#define ROFDM1_PSEUDONOISESTATECD 0xd54
1365#define ROFDM1_RXPSEUDONOISEWGT 0xd58
1366
1367#define ROFDM_PHYCOUNTER1 0xda0
1368#define ROFDM_PHYCOUNTER2 0xda4
1369#define ROFDM_PHYCOUNTER3 0xda8
1370
1371#define ROFDM_SHORTCFOAB 0xdac
1372#define ROFDM_SHORTCFOCD 0xdb0
1373#define ROFDM_LONGCFOAB 0xdb4
1374#define ROFDM_LONGCFOCD 0xdb8
1375#define ROFDM_TAILCF0AB 0xdbc
1376#define ROFDM_TAILCF0CD 0xdc0
1377#define ROFDM_PWMEASURE1 0xdc4
1378#define ROFDM_PWMEASURE2 0xdc8
1379#define ROFDM_BWREPORT 0xdcc
1380#define ROFDM_AGCREPORT 0xdd0
1381#define ROFDM_RXSNR 0xdd4
1382#define ROFDM_RXEVMCSI 0xdd8
1383#define ROFDM_SIGREPORT 0xddc
1384
1385#define RTXAGC_A_RATE18_06 0xe00
1386#define RTXAGC_A_RATE54_24 0xe04
1387#define RTXAGC_A_CCK1_MCS32 0xe08
1388#define RTXAGC_A_MCS03_MCS00 0xe10
1389#define RTXAGC_A_MCS07_MCS04 0xe14
1390#define RTXAGC_A_MCS11_MCS08 0xe18
1391#define RTXAGC_A_MCS15_MCS12 0xe1c
1392
1393#define RTXAGC_B_RATE18_06 0x830
1394#define RTXAGC_B_RATE54_24 0x834
1395#define RTXAGC_B_CCK1_55_MCS32 0x838
1396#define RTXAGC_B_MCS03_MCS00 0x83c
1397#define RTXAGC_B_MCS07_MCS04 0x848
1398#define RTXAGC_B_MCS11_MCS08 0x84c
1399#define RTXAGC_B_MCS15_MCS12 0x868
1400#define RTXAGC_B_CCK11_A_CCK2_11 0x86c
1401
1402#define RZEBRA1_HSSIENABLE 0x0
1403#define RZEBRA1_TRXENABLE1 0x1
1404#define RZEBRA1_TRXENABLE2 0x2
1405#define RZEBRA1_AGC 0x4
1406#define RZEBRA1_CHARGEPUMP 0x5
1407#define RZEBRA1_CHANNEL 0x7
1408
1409#define RZEBRA1_TXGAIN 0x8
1410#define RZEBRA1_TXLPF 0x9
1411#define RZEBRA1_RXLPF 0xb
1412#define RZEBRA1_RXHPFCORNER 0xc
1413
1414#define RGLOBALCTRL 0
1415#define RRTL8256_TXLPF 19
1416#define RRTL8256_RXLPF 11
1417#define RRTL8258_TXLPF 0x11
1418#define RRTL8258_RXLPF 0x13
1419#define RRTL8258_RSSILPF 0xa
1420
1421#define RF_AC 0x00
1422
1423#define RF_IQADJ_G1 0x01
1424#define RF_IQADJ_G2 0x02
1425#define RF_POW_TRSW 0x05
1426
1427#define RF_GAIN_RX 0x06
1428#define RF_GAIN_TX 0x07
1429
1430#define RF_TXM_IDAC 0x08
1431#define RF_BS_IQGEN 0x0F
1432
1433#define RF_MODE1 0x10
1434#define RF_MODE2 0x11
1435
1436#define RF_RX_AGC_HP 0x12
1437#define RF_TX_AGC 0x13
1438#define RF_BIAS 0x14
1439#define RF_IPA 0x15
1440#define RF_POW_ABILITY 0x17
1441#define RF_MODE_AG 0x18
1442#define RRFCHANNEL 0x18
1443#define RF_CHNLBW 0x18
1444#define RF_TOP 0x19
1445
1446#define RF_RX_G1 0x1A
1447#define RF_RX_G2 0x1B
1448
1449#define RF_RX_BB2 0x1C
1450#define RF_RX_BB1 0x1D
1451
1452#define RF_RCK1 0x1E
1453#define RF_RCK2 0x1F
1454
1455#define RF_TX_G1 0x20
1456#define RF_TX_G2 0x21
1457#define RF_TX_G3 0x22
1458
1459#define RF_TX_BB1 0x23
1460#define RF_T_METER 0x24
1461
1462#define RF_SYN_G1 0x25
1463#define RF_SYN_G2 0x26
1464#define RF_SYN_G3 0x27
1465#define RF_SYN_G4 0x28
1466#define RF_SYN_G5 0x29
1467#define RF_SYN_G6 0x2A
1468#define RF_SYN_G7 0x2B
1469#define RF_SYN_G8 0x2C
1470
1471#define RF_RCK_OS 0x30
1472#define RF_TXPA_G1 0x31
1473#define RF_TXPA_G2 0x32
1474#define RF_TXPA_G3 0x33
1475
1476#define BBBRESETB 0x100
1477#define BGLOBALRESETB 0x200
1478#define BOFDMTXSTART 0x4
1479#define BCCKTXSTART 0x8
1480#define BCRC32DEBUG 0x100
1481#define BPMACLOOPBACK 0x10
1482#define BTXLSIG 0xffffff
1483#define BOFDMTXRATE 0xf
1484#define BOFDMTXRESERVED 0x10
1485#define BOFDMTXLENGTH 0x1ffe0
1486#define BOFDMTXPARITY 0x20000
1487#define BTXHTSIG1 0xffffff
1488#define BTXHTMCSRATE 0x7f
1489#define BTXHTBW 0x80
1490#define BTXHTLENGTH 0xffff00
1491#define BTXHTSIG2 0xffffff
1492#define BTXHTSMOOTHING 0x1
1493#define BTXHTSOUNDING 0x2
1494#define BTXHTRESERVED 0x4
1495#define BTXHTAGGREATION 0x8
1496#define BTXHTSTBC 0x30
1497#define BTXHTADVANCECODING 0x40
1498#define BTXHTSHORTGI 0x80
1499#define BTXHTNUMBERHT_LT F 0x300
1500#define BTXHTCRC8 0x3fc00
1501#define BCOUNTERRESET 0x10000
1502#define BNUMOFOFDMTX 0xffff
1503#define BNUMOFCCKTX 0xffff0000
1504#define BTXIDLEINTERVAL 0xffff
1505#define BOFDMSERVICE 0xffff0000
1506#define BTXMACHEADER 0xffffffff
1507#define BTXDATAINIT 0xff
1508#define BTXHTMODE 0x100
1509#define BTXDATATYPE 0x30000
1510#define BTXRANDOMSEED 0xffffffff
1511#define BCCKTXPREAMBLE 0x1
1512#define BCCKTXSFD 0xffff0000
1513#define BCCKTXSIG 0xff
1514#define BCCKTXSERVICE 0xff00
1515#define BCCKLENGTHEXT 0x8000
1516#define BCCKTXLENGHT 0xffff0000
1517#define BCCKTXCRC16 0xffff
1518#define BCCKTXSTATUS 0x1
1519#define BOFDMTXSTATUS 0x2
1520#define IS_BB_REG_OFFSET_92S(_Offset) \
1521 ((_Offset >= 0x800) && (_Offset <= 0xfff))
1522
1523#define BRFMOD 0x1
1524#define BJAPANMODE 0x2
1525#define BCCKTXSC 0x30
1526#define BCCKEN 0x1000000
1527#define BOFDMEN 0x2000000
1528
1529#define BOFDMRXADCPHASE 0x10000
1530#define BOFDMTXDACPHASE 0x40000
1531#define BXATXAGC 0x3f
1532
1533#define BXBTXAGC 0xf00
1534#define BXCTXAGC 0xf000
1535#define BXDTXAGC 0xf0000
1536
1537#define BPASTART 0xf0000000
1538#define BTRSTART 0x00f00000
1539#define BRFSTART 0x0000f000
1540#define BBBSTART 0x000000f0
1541#define BBBCCKSTART 0x0000000f
1542#define BPAEND 0xf
1543#define BTREND 0x0f000000
1544#define BRFEND 0x000f0000
1545#define BCCAMASK 0x000000f0
1546#define BR2RCCAMASK 0x00000f00
1547#define BHSSI_R2TDELAY 0xf8000000
1548#define BHSSI_T2RDELAY 0xf80000
1549#define BCONTXHSSI 0x400
1550#define BIGFROMCCK 0x200
1551#define BAGCADDRESS 0x3f
1552#define BRXHPTX 0x7000
1553#define BRXHP2RX 0x38000
1554#define BRXHPCCKINI 0xc0000
1555#define BAGCTXCODE 0xc00000
1556#define BAGCRXCODE 0x300000
1557
1558#define B3WIREDATALENGTH 0x800
1559#define B3WIREADDREAALENGTH 0x400
1560
1561#define B3WIRERFPOWERDOWN 0x1
1562#define B5GPAPEPOLARITY 0x40000000
1563#define B2GPAPEPOLARITY 0x80000000
1564#define BRFSW_TXDEFAULTANT 0x3
1565#define BRFSW_TXOPTIONANT 0x30
1566#define BRFSW_RXDEFAULTANT 0x300
1567#define BRFSW_RXOPTIONANT 0x3000
1568#define BRFSI_3WIREDATA 0x1
1569#define BRFSI_3WIRECLOCK 0x2
1570#define BRFSI_3WIRELOAD 0x4
1571#define BRFSI_3WIRERW 0x8
1572#define BRFSI_3WIRE 0xf
1573
1574#define BRFSI_RFENV 0x10
1575
1576#define BRFSI_TRSW 0x20
1577#define BRFSI_TRSWB 0x40
1578#define BRFSI_ANTSW 0x100
1579#define BRFSI_ANTSWB 0x200
1580#define BRFSI_PAPE 0x400
1581#define BRFSI_PAPE5G 0x800
1582#define BBANDSELECT 0x1
1583#define BHTSIG2_GI 0x80
1584#define BHTSIG2_SMOOTHING 0x01
1585#define BHTSIG2_SOUNDING 0x02
1586#define BHTSIG2_AGGREATON 0x08
1587#define BHTSIG2_STBC 0x30
1588#define BHTSIG2_ADVCODING 0x40
1589#define BHTSIG2_NUMOFHTLTF 0x300
1590#define BHTSIG2_CRC8 0x3fc
1591#define BHTSIG1_MCS 0x7f
1592#define BHTSIG1_BANDWIDTH 0x80
1593#define BHTSIG1_HTLENGTH 0xffff
1594#define BLSIG_RATE 0xf
1595#define BLSIG_RESERVED 0x10
1596#define BLSIG_LENGTH 0x1fffe
1597#define BLSIG_PARITY 0x20
1598#define BCCKRXPHASE 0x4
1599
1600#define BLSSIREADADDRESS 0x7f800000
1601#define BLSSIREADEDGE 0x80000000
1602
1603#define BLSSIREADBACKDATA 0xfffff
1604
1605#define BLSSIREADOKFLAG 0x1000
1606#define BCCKSAMPLERATE 0x8
1607#define BREGULATOR0STANDBY 0x1
1608#define BREGULATORPLLSTANDBY 0x2
1609#define BREGULATOR1STANDBY 0x4
1610#define BPLLPOWERUP 0x8
1611#define BDPLLPOWERUP 0x10
1612#define BDA10POWERUP 0x20
1613#define BAD7POWERUP 0x200
1614#define BDA6POWERUP 0x2000
1615#define BXTALPOWERUP 0x4000
1616#define B40MDCLKPOWERUP 0x8000
1617#define BDA6DEBUGMODE 0x20000
1618#define BDA6SWING 0x380000
1619
1620#define BADCLKPHASE 0x4000000
1621#define B80MCLKDELAY 0x18000000
1622#define BAFEWATCHDOGENABLE 0x20000000
1623
1624#define BXTALCAP01 0xc0000000
1625#define BXTALCAP23 0x3
1626#define BXTALCAP92X 0x0f000000
1627#define BXTALCAP 0x0f000000
1628
1629#define BINTDIFCLKENABLE 0x400
1630#define BEXTSIGCLKENABLE 0x800
1631#define BBANDGAP_MBIAS_POWERUP 0x10000
1632#define BAD11SH_GAIN 0xc0000
1633#define BAD11NPUT_RANGE 0x700000
1634#define BAD110P_CURRENT 0x3800000
1635#define BLPATH_LOOPBACK 0x4000000
1636#define BQPATH_LOOPBACK 0x8000000
1637#define BAFE_LOOPBACK 0x10000000
1638#define BDA10_SWING 0x7e0
1639#define BDA10_REVERSE 0x800
1640#define BDA_CLK_SOURCE 0x1000
1641#define BDA7INPUT_RANGE 0x6000
1642#define BDA7_GAIN 0x38000
1643#define BDA7OUTPUT_CM_MODE 0x40000
1644#define BDA7INPUT_CM_MODE 0x380000
1645#define BDA7CURRENT 0xc00000
1646#define BREGULATOR_ADJUST 0x7000000
1647#define BAD11POWERUP_ATTX 0x1
1648#define BDA10PS_ATTX 0x10
1649#define BAD11POWERUP_ATRX 0x100
1650#define BDA10PS_ATRX 0x1000
1651#define BCCKRX_AGC_FORMAT 0x200
1652#define BPSDFFT_SAMPLE_POINT 0xc000
1653#define BPSD_AVERAGE_NUM 0x3000
1654#define BIQPATH_CONTROL 0xc00
1655#define BPSD_FREQ 0x3ff
1656#define BPSD_ANTENNA_PATH 0x30
1657#define BPSD_IQ_SWITCH 0x40
1658#define BPSD_RX_TRIGGER 0x400000
1659#define BPSD_TX_TRIGGER 0x80000000
1660#define BPSD_SINE_TONE_SCALE 0x7f000000
1661#define BPSD_REPORT 0xffff
1662
1663#define BOFDM_TXSC 0x30000000
1664#define BCCK_TXON 0x1
1665#define BOFDM_TXON 0x2
1666#define BDEBUG_PAGE 0xfff
1667#define BDEBUG_ITEM 0xff
1668#define BANTL 0x10
1669#define BANT_NONHT 0x100
1670#define BANT_HT1 0x1000
1671#define BANT_HT2 0x10000
1672#define BANT_HT1S1 0x100000
1673#define BANT_NONHTS1 0x1000000
1674
1675#define BCCK_BBMODE 0x3
1676#define BCCK_TXPOWERSAVING 0x80
1677#define BCCK_RXPOWERSAVING 0x40
1678
1679#define BCCK_SIDEBAND 0x10
1680
1681#define BCCK_SCRAMBLE 0x8
1682#define BCCK_ANTDIVERSITY 0x8000
1683#define BCCK_CARRIER_RECOVERY 0x4000
1684#define BCCK_TXRATE 0x3000
1685#define BCCK_DCCANCEL 0x0800
1686#define BCCK_ISICANCEL 0x0400
1687#define BCCK_MATCH_FILTER 0x0200
1688#define BCCK_EQUALIZER 0x0100
1689#define BCCK_PREAMBLE_DETECT 0x800000
1690#define BCCK_FAST_FALSECCA 0x400000
1691#define BCCK_CH_ESTSTART 0x300000
1692#define BCCK_CCA_COUNT 0x080000
1693#define BCCK_CS_LIM 0x070000
1694#define BCCK_BIST_MODE 0x80000000
1695#define BCCK_CCAMASK 0x40000000
1696#define BCCK_TX_DAC_PHASE 0x4
1697#define BCCK_RX_ADC_PHASE 0x20000000
1698#define BCCKR_CP_MODE 0x0100
1699#define BCCK_TXDC_OFFSET 0xf0
1700#define BCCK_RXDC_OFFSET 0xf
1701#define BCCK_CCA_MODE 0xc000
1702#define BCCK_FALSECS_LIM 0x3f00
1703#define BCCK_CS_RATIO 0xc00000
1704#define BCCK_CORGBIT_SEL 0x300000
1705#define BCCK_PD_LIM 0x0f0000
1706#define BCCK_NEWCCA 0x80000000
1707#define BCCK_RXHP_OF_IG 0x8000
1708#define BCCK_RXIG 0x7f00
1709#define BCCK_LNA_POLARITY 0x800000
1710#define BCCK_RX1ST_BAIN 0x7f0000
1711#define BCCK_RF_EXTEND 0x20000000
1712#define BCCK_RXAGC_SATLEVEL 0x1f000000
1713#define BCCK_RXAGC_SATCOUNT 0xe0
1714#define bCCKRxRFSettle 0x1f
1715#define BCCK_FIXED_RXAGC 0x8000
1716#define BCCK_ANTENNA_POLARITY 0x2000
1717#define BCCK_TXFILTER_TYPE 0x0c00
1718#define BCCK_RXAGC_REPORTTYPE 0x0300
1719#define BCCK_RXDAGC_EN 0x80000000
1720#define BCCK_RXDAGC_PERIOD 0x20000000
1721#define BCCK_RXDAGC_SATLEVEL 0x1f000000
1722#define BCCK_TIMING_RECOVERY 0x800000
1723#define BCCK_TXC0 0x3f0000
1724#define BCCK_TXC1 0x3f000000
1725#define BCCK_TXC2 0x3f
1726#define BCCK_TXC3 0x3f00
1727#define BCCK_TXC4 0x3f0000
1728#define BCCK_TXC5 0x3f000000
1729#define BCCK_TXC6 0x3f
1730#define BCCK_TXC7 0x3f00
1731#define BCCK_DEBUGPORT 0xff0000
1732#define BCCK_DAC_DEBUG 0x0f000000
1733#define BCCK_FALSEALARM_ENABLE 0x8000
1734#define BCCK_FALSEALARM_READ 0x4000
1735#define BCCK_TRSSI 0x7f
1736#define BCCK_RXAGC_REPORT 0xfe
1737#define BCCK_RXREPORT_ANTSEL 0x80000000
1738#define BCCK_RXREPORT_MFOFF 0x40000000
1739#define BCCK_RXREPORT_SQLOSS 0x20000000
1740#define BCCK_RXREPORT_PKTLOSS 0x10000000
1741#define BCCK_RXREPORT_LOCKEDBIT 0x08000000
1742#define BCCK_RXREPORT_RATEERROR 0x04000000
1743#define BCCK_RXREPORT_RXRATE 0x03000000
1744#define BCCK_RXFA_COUNTER_LOWER 0xff
1745#define BCCK_RXFA_COUNTER_UPPER 0xff000000
1746#define BCCK_RXHPAGC_START 0xe000
1747#define BCCK_RXHPAGC_FINAL 0x1c00
1748#define BCCK_RXFALSEALARM_ENABLE 0x8000
1749#define BCCK_FACOUNTER_FREEZE 0x4000
1750#define BCCK_TXPATH_SEL 0x10000000
1751#define BCCK_DEFAULT_RXPATH 0xc000000
1752#define BCCK_OPTION_RXPATH 0x3000000
1753
1754#define BNUM_OFSTF 0x3
1755#define BSHIFT_L 0xc0
1756#define BGI_TH 0xc
1757#define BRXPATH_A 0x1
1758#define BRXPATH_B 0x2
1759#define BRXPATH_C 0x4
1760#define BRXPATH_D 0x8
1761#define BTXPATH_A 0x1
1762#define BTXPATH_B 0x2
1763#define BTXPATH_C 0x4
1764#define BTXPATH_D 0x8
1765#define BTRSSI_FREQ 0x200
1766#define BADC_BACKOFF 0x3000
1767#define BDFIR_BACKOFF 0xc000
1768#define BTRSSI_LATCH_PHASE 0x10000
1769#define BRX_LDC_OFFSET 0xff
1770#define BRX_QDC_OFFSET 0xff00
1771#define BRX_DFIR_MODE 0x1800000
1772#define BRX_DCNF_TYPE 0xe000000
1773#define BRXIQIMB_A 0x3ff
1774#define BRXIQIMB_B 0xfc00
1775#define BRXIQIMB_C 0x3f0000
1776#define BRXIQIMB_D 0xffc00000
1777#define BDC_DC_NOTCH 0x60000
1778#define BRXNB_NOTCH 0x1f000000
1779#define BPD_TH 0xf
1780#define BPD_TH_OPT2 0xc000
1781#define BPWED_TH 0x700
1782#define BIFMF_WIN_L 0x800
1783#define BPD_OPTION 0x1000
1784#define BMF_WIN_L 0xe000
1785#define BBW_SEARCH_L 0x30000
1786#define BWIN_ENH_L 0xc0000
1787#define BBW_TH 0x700000
1788#define BED_TH2 0x3800000
1789#define BBW_OPTION 0x4000000
1790#define BRADIO_TH 0x18000000
1791#define BWINDOW_L 0xe0000000
1792#define BSBD_OPTION 0x1
1793#define BFRAME_TH 0x1c
1794#define BFS_OPTION 0x60
1795#define BDC_SLOPE_CHECK 0x80
1796#define BFGUARD_COUNTER_DC_L 0xe00
1797#define BFRAME_WEIGHT_SHORT 0x7000
1798#define BSUB_TUNE 0xe00000
1799#define BFRAME_DC_LENGTH 0xe000000
1800#define BSBD_START_OFFSET 0x30000000
1801#define BFRAME_TH_2 0x7
1802#define BFRAME_GI2_TH 0x38
1803#define BGI2_SYNC_EN 0x40
1804#define BSARCH_SHORT_EARLY 0x300
1805#define BSARCH_SHORT_LATE 0xc00
1806#define BSARCH_GI2_LATE 0x70000
1807#define BCFOANTSUM 0x1
1808#define BCFOACC 0x2
1809#define BCFOSTARTOFFSET 0xc
1810#define BCFOLOOPBACK 0x70
1811#define BCFOSUMWEIGHT 0x80
1812#define BDAGCENABLE 0x10000
1813#define BTXIQIMB_A 0x3ff
1814#define BTXIQIMB_b 0xfc00
1815#define BTXIQIMB_C 0x3f0000
1816#define BTXIQIMB_D 0xffc00000
1817#define BTXIDCOFFSET 0xff
1818#define BTXIQDCOFFSET 0xff00
1819#define BTXDFIRMODE 0x10000
1820#define BTXPESUDO_NOISEON 0x4000000
1821#define BTXPESUDO_NOISE_A 0xff
1822#define BTXPESUDO_NOISE_B 0xff00
1823#define BTXPESUDO_NOISE_C 0xff0000
1824#define BTXPESUDO_NOISE_D 0xff000000
1825#define BCCA_DROPOPTION 0x20000
1826#define BCCA_DROPTHRES 0xfff00000
1827#define BEDCCA_H 0xf
1828#define BEDCCA_L 0xf0
1829#define BLAMBDA_ED 0x300
1830#define BRX_INITIALGAIN 0x7f
1831#define BRX_ANTDIV_EN 0x80
1832#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00
1833#define BRX_HIGHPOWER_FLOW 0x8000
1834#define BRX_AGC_FREEZE_THRES 0xc0000
1835#define BRX_FREEZESTEP_AGC1 0x300000
1836#define BRX_FREEZESTEP_AGC2 0xc00000
1837#define BRX_FREEZESTEP_AGC3 0x3000000
1838#define BRX_FREEZESTEP_AGC0 0xc000000
1839#define BRXRSSI_CMP_EN 0x10000000
1840#define BRXQUICK_AGCEN 0x20000000
1841#define BRXAGC_FREEZE_THRES_MODE 0x40000000
1842#define BRX_OVERFLOW_CHECKTYPE 0x80000000
1843#define BRX_AGCSHIFT 0x7f
1844#define BTRSW_TRI_ONLY 0x80
1845#define BPOWER_THRES 0x300
1846#define BRXAGC_EN 0x1
1847#define BRXAGC_TOGETHER_EN 0x2
1848#define BRXAGC_MIN 0x4
1849#define BRXHP_INI 0x7
1850#define BRXHP_TRLNA 0x70
1851#define BRXHP_RSSI 0x700
1852#define BRXHP_BBP1 0x7000
1853#define BRXHP_BBP2 0x70000
1854#define BRXHP_BBP3 0x700000
1855#define BRSSI_H 0x7f0000
1856#define BRSSI_GEN 0x7f000000
1857#define BRXSETTLE_TRSW 0x7
1858#define BRXSETTLE_LNA 0x38
1859#define BRXSETTLE_RSSI 0x1c0
1860#define BRXSETTLE_BBP 0xe00
1861#define BRXSETTLE_RXHP 0x7000
1862#define BRXSETTLE_ANTSW_RSSI 0x38000
1863#define BRXSETTLE_ANTSW 0xc0000
1864#define BRXPROCESS_TIME_DAGC 0x300000
1865#define BRXSETTLE_HSSI 0x400000
1866#define BRXPROCESS_TIME_BBPPW 0x800000
1867#define BRXANTENNA_POWER_SHIFT 0x3000000
1868#define BRSSI_TABLE_SELECT 0xc000000
1869#define BRXHP_FINAL 0x7000000
1870#define BRXHPSETTLE_BBP 0x7
1871#define BRXHTSETTLE_HSSI 0x8
1872#define BRXHTSETTLE_RXHP 0x70
1873#define BRXHTSETTLE_BBPPW 0x80
1874#define BRXHTSETTLE_IDLE 0x300
1875#define BRXHTSETTLE_RESERVED 0x1c00
1876#define BRXHT_RXHP_EN 0x8000
1877#define BRXAGC_FREEZE_THRES 0x30000
1878#define BRXAGC_TOGETHEREN 0x40000
1879#define BRXHTAGC_MIN 0x80000
1880#define BRXHTAGC_EN 0x100000
1881#define BRXHTDAGC_EN 0x200000
1882#define BRXHT_RXHP_BBP 0x1c00000
1883#define BRXHT_RXHP_FINAL 0xe0000000
1884#define BRXPW_RADIO_TH 0x3
1885#define BRXPW_RADIO_EN 0x4
1886#define BRXMF_HOLD 0x3800
1887#define BRXPD_DELAY_TH1 0x38
1888#define BRXPD_DELAY_TH2 0x1c0
1889#define BRXPD_DC_COUNT_MAX 0x600
1890#define BRXPD_DELAY_TH 0x8000
1891#define BRXPROCESS_DELAY 0xf0000
1892#define BRXSEARCHRANGE_GI2_EARLY 0x700000
1893#define BRXFRAME_FUARD_COUNTER_L 0x3800000
1894#define BRXSGI_GUARD_L 0xc000000
1895#define BRXSGI_SEARCH_L 0x30000000
1896#define BRXSGI_TH 0xc0000000
1897#define BDFSCNT0 0xff
1898#define BDFSCNT1 0xff00
1899#define BDFSFLAG 0xf0000
1900#define BMF_WEIGHT_SUM 0x300000
1901#define BMINIDX_TH 0x7f000000
1902#define BDAFORMAT 0x40000
1903#define BTXCH_EMU_ENABLE 0x01000000
1904#define BTRSW_ISOLATION_A 0x7f
1905#define BTRSW_ISOLATION_B 0x7f00
1906#define BTRSW_ISOLATION_C 0x7f0000
1907#define BTRSW_ISOLATION_D 0x7f000000
1908#define BEXT_LNA_GAIN 0x7c00
1909
1910#define BSTBC_EN 0x4
1911#define BANTENNA_MAPPING 0x10
1912#define BNSS 0x20
1913#define BCFO_ANTSUM_ID 0x200
1914#define BPHY_COUNTER_RESET 0x8000000
1915#define BCFO_REPORT_GET 0x4000000
1916#define BOFDM_CONTINUE_TX 0x10000000
1917#define BOFDM_SINGLE_CARRIER 0x20000000
1918#define BOFDM_SINGLE_TONE 0x40000000
1919#define BHT_DETECT 0x100
1920#define BCFOEN 0x10000
1921#define BCFOVALUE 0xfff00000
1922#define BSIGTONE_RE 0x3f
1923#define BSIGTONE_IM 0x7f00
1924#define BCOUNTER_CCA 0xffff
1925#define BCOUNTER_PARITYFAIL 0xffff0000
1926#define BCOUNTER_RATEILLEGAL 0xffff
1927#define BCOUNTER_CRC8FAIL 0xffff0000
1928#define BCOUNTER_MCSNOSUPPORT 0xffff
1929#define BCOUNTER_FASTSYNC 0xffff
1930#define BSHORTCFO 0xfff
1931#define BSHORTCFOT_LENGTH 12
1932#define BSHORTCFOF_LENGTH 11
1933#define BLONGCFO 0x7ff
1934#define BLONGCFOT_LENGTH 11
1935#define BLONGCFOF_LENGTH 11
1936#define BTAILCFO 0x1fff
1937#define BTAILCFOT_LENGTH 13
1938#define BTAILCFOF_LENGTH 12
1939#define BNOISE_EN_PWDB 0xffff
1940#define BCC_POWER_DB 0xffff0000
1941#define BMOISE_PWDB 0xffff
1942#define BPOWERMEAST_LENGTH 10
1943#define BPOWERMEASF_LENGTH 3
1944#define BRX_HT_BW 0x1
1945#define BRXSC 0x6
1946#define BRX_HT 0x8
1947#define BNB_INTF_DET_ON 0x1
1948#define BINTF_WIN_LEN_CFG 0x30
1949#define BNB_INTF_TH_CFG 0x1c0
1950#define BRFGAIN 0x3f
1951#define BTABLESEL 0x40
1952#define BTRSW 0x80
1953#define BRXSNR_A 0xff
1954#define BRXSNR_B 0xff00
1955#define BRXSNR_C 0xff0000
1956#define BRXSNR_D 0xff000000
1957#define BSNR_EVMT_LENGTH 8
1958#define BSNR_EVMF_LENGTH 1
1959#define BCSI1ST 0xff
1960#define BCSI2ND 0xff00
1961#define BRXEVM1ST 0xff0000
1962#define BRXEVM2ND 0xff000000
1963#define BSIGEVM 0xff
1964#define BPWDB 0xff00
1965#define BSGIEN 0x10000
1966
1967#define BSFACTOR_QMA1 0xf
1968#define BSFACTOR_QMA2 0xf0
1969#define BSFACTOR_QMA3 0xf00
1970#define BSFACTOR_QMA4 0xf000
1971#define BSFACTOR_QMA5 0xf0000
1972#define BSFACTOR_QMA6 0xf0000
1973#define BSFACTOR_QMA7 0xf00000
1974#define BSFACTOR_QMA8 0xf000000
1975#define BSFACTOR_QMA9 0xf0000000
1976#define BCSI_SCHEME 0x100000
1977
1978#define BNOISE_LVL_TOP_SET 0x3
1979#define BCHSMOOTH 0x4
1980#define BCHSMOOTH_CFG1 0x38
1981#define BCHSMOOTH_CFG2 0x1c0
1982#define BCHSMOOTH_CFG3 0xe00
1983#define BCHSMOOTH_CFG4 0x7000
1984#define BMRCMODE 0x800000
1985#define BTHEVMCFG 0x7000000
1986
1987#define BLOOP_FIT_TYPE 0x1
1988#define BUPD_CFO 0x40
1989#define BUPD_CFO_OFFDATA 0x80
1990#define BADV_UPD_CFO 0x100
1991#define BADV_TIME_CTRL 0x800
1992#define BUPD_CLKO 0x1000
1993#define BFC 0x6000
1994#define BTRACKING_MODE 0x8000
1995#define BPHCMP_ENABLE 0x10000
1996#define BUPD_CLKO_LTF 0x20000
1997#define BCOM_CH_CFO 0x40000
1998#define BCSI_ESTI_MODE 0x80000
1999#define BADV_UPD_EQZ 0x100000
2000#define BUCHCFG 0x7000000
2001#define BUPDEQZ 0x8000000
2002
2003#define BRX_PESUDO_NOISE_ON 0x20000000
2004#define BRX_PESUDO_NOISE_A 0xff
2005#define BRX_PESUDO_NOISE_B 0xff00
2006#define BRX_PESUDO_NOISE_C 0xff0000
2007#define BRX_PESUDO_NOISE_D 0xff000000
2008#define BRX_PESUDO_NOISESTATE_A 0xffff
2009#define BRX_PESUDO_NOISESTATE_B 0xffff0000
2010#define BRX_PESUDO_NOISESTATE_C 0xffff
2011#define BRX_PESUDO_NOISESTATE_D 0xffff0000
2012
2013#define BZEBRA1_HSSIENABLE 0x8
2014#define BZEBRA1_TRXCONTROL 0xc00
2015#define BZEBRA1_TRXGAINSETTING 0x07f
2016#define BZEBRA1_RXCOUNTER 0xc00
2017#define BZEBRA1_TXCHANGEPUMP 0x38
2018#define BZEBRA1_RXCHANGEPUMP 0x7
2019#define BZEBRA1_CHANNEL_NUM 0xf80
2020#define BZEBRA1_TXLPFBW 0x400
2021#define BZEBRA1_RXLPFBW 0x600
2022
2023#define BRTL8256REG_MODE_CTRL1 0x100
2024#define BRTL8256REG_MODE_CTRL0 0x40
2025#define BRTL8256REG_TXLPFBW 0x18
2026#define BRTL8256REG_RXLPFBW 0x600
2027
2028#define BRTL8258_TXLPFBW 0xc
2029#define BRTL8258_RXLPFBW 0xc00
2030#define BRTL8258_RSSILPFBW 0xc0
2031
2032#define BBYTE0 0x1
2033#define BBYTE1 0x2
2034#define BBYTE2 0x4
2035#define BBYTE3 0x8
2036#define BWORD0 0x3
2037#define BWORD1 0xc
2038#define BWORD 0xf
2039
2040#define MASKBYTE0 0xff
2041#define MASKBYTE1 0xff00
2042#define MASKBYTE2 0xff0000
2043#define MASKBYTE3 0xff000000
2044#define MASKHWORD 0xffff0000
2045#define MASKLWORD 0x0000ffff
2046#define MASKDWORD 0xffffffff
2047#define MASK12BITS 0xfff
2048#define MASKH4BITS 0xf0000000
2049#define MASKOFDM_D 0xffc00000
2050#define MASKCCK 0x3f3f3f3f
2051
2052#define MASK4BITS 0x0f
2053#define MASK20BITS 0xfffff
2054#define RFREG_OFFSET_MASK 0xfffff
2055
2056#define BENABLE 0x1
2057#define BDISABLE 0x0
2058
2059#define LEFT_ANTENNA 0x0
2060#define RIGHT_ANTENNA 0x1
2061
2062#define TCHECK_TXSTATUS 500
2063#define TUPDATE_RXCOUNTER 100
2064
2065#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c
new file mode 100644
index 00000000000..a2d58df5d3a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.c
@@ -0,0 +1,523 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "rtl8192c-reg.h"
32#include "rtl8192c-def.h"
33#include "rtl8192c-phy.h"
34#include "rtl8192c-rf.h"
35#include "rtl8192c-dm.h"
36
37static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
38
39void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
40{
41 struct rtl_priv *rtlpriv = rtl_priv(hw);
42 struct rtl_phy *rtlphy = &(rtlpriv->phy);
43
44 switch (bandwidth) {
45 case HT_CHANNEL_WIDTH_20:
46 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
47 0xfffff3ff) | 0x0400);
48 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
49 rtlphy->rfreg_chnlval[0]);
50 break;
51 case HT_CHANNEL_WIDTH_20_40:
52 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
53 0xfffff3ff));
54 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
55 rtlphy->rfreg_chnlval[0]);
56 break;
57 default:
58 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
59 ("unknown bandwidth: %#X\n", bandwidth));
60 break;
61 }
62}
63
64void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
65 u8 *ppowerlevel)
66{
67 struct rtl_priv *rtlpriv = rtl_priv(hw);
68 struct rtl_phy *rtlphy = &(rtlpriv->phy);
69 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
70 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
71 u32 tx_agc[2] = {0, 0}, tmpval;
72 bool turbo_scanoff = false;
73 u8 idx1, idx2;
74 u8 *ptr;
75
76 if (rtlefuse->eeprom_regulatory != 0)
77 turbo_scanoff = true;
78
79 if (mac->act_scanning == true) {
80 tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
81 tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
82
83 if (turbo_scanoff) {
84 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
85 tx_agc[idx1] = ppowerlevel[idx1] |
86 (ppowerlevel[idx1] << 8) |
87 (ppowerlevel[idx1] << 16) |
88 (ppowerlevel[idx1] << 24);
89 }
90 }
91 } else {
92 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
93 tx_agc[idx1] = ppowerlevel[idx1] |
94 (ppowerlevel[idx1] << 8) |
95 (ppowerlevel[idx1] << 16) |
96 (ppowerlevel[idx1] << 24);
97 }
98
99 if (rtlefuse->eeprom_regulatory == 0) {
100 tmpval =
101 (rtlphy->mcs_txpwrlevel_origoffset[0][6]) +
102 (rtlphy->mcs_txpwrlevel_origoffset[0][7] <<
103 8);
104 tx_agc[RF90_PATH_A] += tmpval;
105
106 tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) +
107 (rtlphy->mcs_txpwrlevel_origoffset[0][15] <<
108 24);
109 tx_agc[RF90_PATH_B] += tmpval;
110 }
111 }
112
113 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
114 ptr = (u8 *) (&(tx_agc[idx1]));
115 for (idx2 = 0; idx2 < 4; idx2++) {
116 if (*ptr > RF6052_MAX_TX_PWR)
117 *ptr = RF6052_MAX_TX_PWR;
118 ptr++;
119 }
120 }
121
122 tmpval = tx_agc[RF90_PATH_A] & 0xff;
123 rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
124
125 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
126 ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
127 RTXAGC_A_CCK1_MCS32));
128
129 tmpval = tx_agc[RF90_PATH_A] >> 8;
130
131 if (mac->mode == WIRELESS_MODE_B)
132 tmpval = tmpval & 0xff00ffff;
133
134 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
135
136 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
137 ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
138 RTXAGC_B_CCK11_A_CCK2_11));
139
140 tmpval = tx_agc[RF90_PATH_B] >> 24;
141 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
142
143 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
144 ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
145 RTXAGC_B_CCK11_A_CCK2_11));
146
147 tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
148 rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
149
150 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
151 ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
152 RTXAGC_B_CCK1_55_MCS32));
153}
154
155static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
156 u8 *ppowerlevel, u8 channel,
157 u32 *ofdmbase, u32 *mcsbase)
158{
159 struct rtl_priv *rtlpriv = rtl_priv(hw);
160 struct rtl_phy *rtlphy = &(rtlpriv->phy);
161 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
162 u32 powerBase0, powerBase1;
163 u8 legacy_pwrdiff, ht20_pwrdiff;
164 u8 i, powerlevel[2];
165
166 for (i = 0; i < 2; i++) {
167 powerlevel[i] = ppowerlevel[i];
168 legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
169 powerBase0 = powerlevel[i] + legacy_pwrdiff;
170
171 powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) |
172 (powerBase0 << 8) | powerBase0;
173 *(ofdmbase + i) = powerBase0;
174 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
175 (" [OFDM power base index rf(%c) = 0x%x]\n",
176 ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)));
177 }
178
179 for (i = 0; i < 2; i++) {
180 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
181 ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
182 powerlevel[i] += ht20_pwrdiff;
183 }
184 powerBase1 = powerlevel[i];
185 powerBase1 = (powerBase1 << 24) |
186 (powerBase1 << 16) | (powerBase1 << 8) | powerBase1;
187
188 *(mcsbase + i) = powerBase1;
189
190 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
191 (" [MCS power base index rf(%c) = 0x%x]\n",
192 ((i == 0) ? 'A' : 'B'), *(mcsbase + i)));
193 }
194}
195
196static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
197 u8 channel, u8 index,
198 u32 *powerBase0,
199 u32 *powerBase1,
200 u32 *p_outwriteval)
201{
202 struct rtl_priv *rtlpriv = rtl_priv(hw);
203 struct rtl_phy *rtlphy = &(rtlpriv->phy);
204 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
205 u8 i, chnlgroup, pwr_diff_limit[4];
206 u32 writeVal, customer_limit, rf;
207
208 for (rf = 0; rf < 2; rf++) {
209 switch (rtlefuse->eeprom_regulatory) {
210 case 0:
211 chnlgroup = 0;
212
213 writeVal =
214 rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index +
215 (rf ? 8 : 0)]
216 + ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
217
218 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
219 ("RTK better performance, "
220 "writeVal(%c) = 0x%x\n",
221 ((rf == 0) ? 'A' : 'B'), writeVal));
222 break;
223 case 1:
224 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
225 writeVal = ((index < 2) ? powerBase0[rf] :
226 powerBase1[rf]);
227
228 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
229 ("Realtek regulatory, 40MHz, "
230 "writeVal(%c) = 0x%x\n",
231 ((rf == 0) ? 'A' : 'B'), writeVal));
232 } else {
233 if (rtlphy->pwrgroup_cnt == 1)
234 chnlgroup = 0;
235 if (rtlphy->pwrgroup_cnt >= 3) {
236 if (channel <= 3)
237 chnlgroup = 0;
238 else if (channel >= 4 && channel <= 9)
239 chnlgroup = 1;
240 else if (channel > 9)
241 chnlgroup = 2;
242 if (rtlphy->pwrgroup_cnt == 4)
243 chnlgroup++;
244 }
245
246 writeVal =
247 rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
248 [index + (rf ? 8 : 0)] + ((index < 2) ?
249 powerBase0[rf] :
250 powerBase1[rf]);
251
252 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
253 ("Realtek regulatory, 20MHz, "
254 "writeVal(%c) = 0x%x\n",
255 ((rf == 0) ? 'A' : 'B'), writeVal));
256 }
257 break;
258 case 2:
259 writeVal =
260 ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
261
262 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
263 ("Better regulatory, "
264 "writeVal(%c) = 0x%x\n",
265 ((rf == 0) ? 'A' : 'B'), writeVal));
266 break;
267 case 3:
268 chnlgroup = 0;
269
270 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
271 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
272 ("customer's limit, 40MHz "
273 "rf(%c) = 0x%x\n",
274 ((rf == 0) ? 'A' : 'B'),
275 rtlefuse->pwrgroup_ht40[rf][channel -
276 1]));
277 } else {
278 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
279 ("customer's limit, 20MHz "
280 "rf(%c) = 0x%x\n",
281 ((rf == 0) ? 'A' : 'B'),
282 rtlefuse->pwrgroup_ht20[rf][channel -
283 1]));
284 }
285 for (i = 0; i < 4; i++) {
286 pwr_diff_limit[i] =
287 (u8) ((rtlphy->mcs_txpwrlevel_origoffset
288 [chnlgroup][index +
289 (rf ? 8 : 0)] & (0x7f << (i * 8))) >>
290 (i * 8));
291
292 if (rtlphy->current_chan_bw ==
293 HT_CHANNEL_WIDTH_20_40) {
294 if (pwr_diff_limit[i] >
295 rtlefuse->
296 pwrgroup_ht40[rf][channel - 1])
297 pwr_diff_limit[i] =
298 rtlefuse->pwrgroup_ht40[rf]
299 [channel - 1];
300 } else {
301 if (pwr_diff_limit[i] >
302 rtlefuse->
303 pwrgroup_ht20[rf][channel - 1])
304 pwr_diff_limit[i] =
305 rtlefuse->pwrgroup_ht20[rf]
306 [channel - 1];
307 }
308 }
309
310 customer_limit = (pwr_diff_limit[3] << 24) |
311 (pwr_diff_limit[2] << 16) |
312 (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
313
314 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
315 ("Customer's limit rf(%c) = 0x%x\n",
316 ((rf == 0) ? 'A' : 'B'), customer_limit));
317
318 writeVal = customer_limit +
319 ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
320
321 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
322 ("Customer, writeVal rf(%c)= 0x%x\n",
323 ((rf == 0) ? 'A' : 'B'), writeVal));
324 break;
325 default:
326 chnlgroup = 0;
327 writeVal =
328 rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
329 [index + (rf ? 8 : 0)]
330 + ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
331
332 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
333 ("RTK better performance, writeVal "
334 "rf(%c) = 0x%x\n",
335 ((rf == 0) ? 'A' : 'B'), writeVal));
336 break;
337 }
338
339 if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
340 writeVal = writeVal - 0x06060606;
341 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
342 TXHIGHPWRLEVEL_BT2)
343 writeVal = writeVal - 0x0c0c0c0c;
344 *(p_outwriteval + rf) = writeVal;
345 }
346}
347
348static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
349 u8 index, u32 *pValue)
350{
351 struct rtl_priv *rtlpriv = rtl_priv(hw);
352 struct rtl_phy *rtlphy = &(rtlpriv->phy);
353
354 u16 regoffset_a[6] = {
355 RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
356 RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
357 RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
358 };
359 u16 regoffset_b[6] = {
360 RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
361 RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
362 RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
363 };
364 u8 i, rf, pwr_val[4];
365 u32 writeVal;
366 u16 regoffset;
367
368 for (rf = 0; rf < 2; rf++) {
369 writeVal = pValue[rf];
370 for (i = 0; i < 4; i++) {
371 pwr_val[i] = (u8) ((writeVal & (0x7f <<
372 (i * 8))) >> (i * 8));
373
374 if (pwr_val[i] > RF6052_MAX_TX_PWR)
375 pwr_val[i] = RF6052_MAX_TX_PWR;
376 }
377 writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
378 (pwr_val[1] << 8) | pwr_val[0];
379
380 if (rf == 0)
381 regoffset = regoffset_a[index];
382 else
383 regoffset = regoffset_b[index];
384 rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal);
385
386 RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
387 ("Set 0x%x = %08x\n", regoffset, writeVal));
388
389 if (((get_rf_type(rtlphy) == RF_2T2R) &&
390 (regoffset == RTXAGC_A_MCS15_MCS12 ||
391 regoffset == RTXAGC_B_MCS15_MCS12)) ||
392 ((get_rf_type(rtlphy) != RF_2T2R) &&
393 (regoffset == RTXAGC_A_MCS07_MCS04 ||
394 regoffset == RTXAGC_B_MCS07_MCS04))) {
395
396 writeVal = pwr_val[3];
397 if (regoffset == RTXAGC_A_MCS15_MCS12 ||
398 regoffset == RTXAGC_A_MCS07_MCS04)
399 regoffset = 0xc90;
400 if (regoffset == RTXAGC_B_MCS15_MCS12 ||
401 regoffset == RTXAGC_B_MCS07_MCS04)
402 regoffset = 0xc98;
403
404 for (i = 0; i < 3; i++) {
405 writeVal = (writeVal > 6) ? (writeVal - 6) : 0;
406 rtl_write_byte(rtlpriv, (u32) (regoffset + i),
407 (u8) writeVal);
408 }
409 }
410 }
411}
412
413void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
414 u8 *ppowerlevel, u8 channel)
415{
416 u32 writeVal[2], powerBase0[2], powerBase1[2];
417 u8 index;
418
419 rtl92c_phy_get_power_base(hw, ppowerlevel,
420 channel, &powerBase0[0], &powerBase1[0]);
421
422 for (index = 0; index < 6; index++) {
423 _rtl92c_get_txpower_writeval_by_regulatory(hw,
424 channel, index,
425 &powerBase0[0],
426 &powerBase1[0],
427 &writeVal[0]);
428
429 _rtl92c_write_ofdm_power_reg(hw, index, &writeVal[0]);
430 }
431}
432
433bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw)
434{
435 struct rtl_priv *rtlpriv = rtl_priv(hw);
436 struct rtl_phy *rtlphy = &(rtlpriv->phy);
437
438 if (rtlphy->rf_type == RF_1T1R)
439 rtlphy->num_total_rfpath = 1;
440 else
441 rtlphy->num_total_rfpath = 2;
442
443 return _rtl92c_phy_rf6052_config_parafile(hw);
444}
445
446static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
447{
448 struct rtl_priv *rtlpriv = rtl_priv(hw);
449 struct rtl_phy *rtlphy = &(rtlpriv->phy);
450 u32 u4_regvalue;
451 u8 rfpath;
452 bool rtstatus;
453 struct bb_reg_def *pphyreg;
454
455 for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
456
457 pphyreg = &rtlphy->phyreg_def[rfpath];
458
459 switch (rfpath) {
460 case RF90_PATH_A:
461 case RF90_PATH_C:
462 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
463 BRFSI_RFENV);
464 break;
465 case RF90_PATH_B:
466 case RF90_PATH_D:
467 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
468 BRFSI_RFENV << 16);
469 break;
470 }
471
472 rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
473 udelay(1);
474
475 rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
476 udelay(1);
477
478 rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
479 B3WIREADDREAALENGTH, 0x0);
480 udelay(1);
481
482 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
483 udelay(1);
484
485 switch (rfpath) {
486 case RF90_PATH_A:
487 rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
488 (enum radio_path) rfpath);
489 break;
490 case RF90_PATH_B:
491 rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
492 (enum radio_path) rfpath);
493 break;
494 case RF90_PATH_C:
495 break;
496 case RF90_PATH_D:
497 break;
498 }
499
500 switch (rfpath) {
501 case RF90_PATH_A:
502 case RF90_PATH_C:
503 rtl_set_bbreg(hw, pphyreg->rfintfs,
504 BRFSI_RFENV, u4_regvalue);
505 break;
506 case RF90_PATH_B:
507 case RF90_PATH_D:
508 rtl_set_bbreg(hw, pphyreg->rfintfs,
509 BRFSI_RFENV << 16, u4_regvalue);
510 break;
511 }
512
513 if (rtstatus != true) {
514 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
515 ("Radio[%d] Fail!!", rfpath));
516 return false;
517 }
518
519 }
520
521 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n"));
522 return rtstatus;
523}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h
new file mode 100644
index 00000000000..d3014f99bb7
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-rf.h
@@ -0,0 +1,44 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92C_RF_H__
31#define __RTL92C_RF_H__
32
33#define RF6052_MAX_TX_PWR 0x3F
34#define RF6052_MAX_REG 0x3F
35#define RF6052_MAX_PATH 2
36
37extern void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
38 u8 bandwidth);
39extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
40 u8 *ppowerlevel);
41extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
42 u8 *ppowerlevel, u8 channel);
43extern bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw);
44#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c
new file mode 100644
index 00000000000..3cdca006be2
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.c
@@ -0,0 +1,280 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../core.h"
32#include "../pci.h"
33#include "rtl8192c-reg.h"
34#include "rtl8192c-def.h"
35#include "rtl8192c-phy.h"
36#include "rtl8192c-dm.h"
37#include "rtl8192c-hw.h"
38#include "rtl8192c-sw.h"
39#include "rtl8192c-trx.h"
40#include "rtl8192c-led.h"
41
42int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
43{
44 struct rtl_priv *rtlpriv = rtl_priv(hw);
45 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
46
47 rtlpriv->dm.b_dm_initialgain_enable = 1;
48 rtlpriv->dm.dm_flag = 0;
49 rtlpriv->dm.b_disable_framebursting = 0;;
50 rtlpriv->dm.thermalvalue = 0;
51 rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
52
53 rtlpci->receive_config = (RCR_APPFCS |
54 RCR_AMF |
55 RCR_ADF |
56 RCR_APP_MIC |
57 RCR_APP_ICV |
58 RCR_AICV |
59 RCR_ACRC32 |
60 RCR_AB |
61 RCR_AM |
62 RCR_APM |
63 RCR_APP_PHYST_RXFF | RCR_HTC_LOC_CTRL | 0);
64
65 rtlpci->irq_mask[0] =
66 (u32) (IMR_ROK |
67 IMR_VODOK |
68 IMR_VIDOK |
69 IMR_BEDOK |
70 IMR_BKDOK |
71 IMR_MGNTDOK |
72 IMR_HIGHDOK | IMR_BDOK | IMR_RDU | IMR_RXFOVW | 0);
73
74 rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0);
75
76 rtlpriv->rtlhal.pfirmware = (u8 *) vmalloc(0x4000);
77 if (!rtlpriv->rtlhal.pfirmware) {
78 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
79 ("Can't alloc buffer for fw.\n"));
80 return 1;
81 }
82
83 return 0;
84}
85
86void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw)
87{
88 struct rtl_priv *rtlpriv = rtl_priv(hw);
89
90 if (rtlpriv->rtlhal.pfirmware) {
91 vfree(rtlpriv->rtlhal.pfirmware);
92 rtlpriv->rtlhal.pfirmware = NULL;
93 }
94}
95
96static struct rtl_hal_ops rtl8192ce_hal_ops = {
97 .init_sw_vars = rtl92c_init_sw_vars,
98 .deinit_sw_vars = rtl92c_deinit_sw_vars,
99 .read_eeprom_info = rtl92ce_read_eeprom_info,
100 .interrupt_recognized = rtl92ce_interrupt_recognized,
101 .hw_init = rtl92ce_hw_init,
102 .hw_disable = rtl92ce_card_disable,
103 .enable_interrupt = rtl92ce_enable_interrupt,
104 .disable_interrupt = rtl92ce_disable_interrupt,
105 .set_network_type = rtl92ce_set_network_type,
106 .set_qos = rtl92ce_set_qos,
107 .set_bcn_reg = rtl92ce_set_beacon_related_registers,
108 .set_bcn_intv = rtl92ce_set_beacon_interval,
109 .update_interrupt_mask = rtl92ce_update_interrupt_mask,
110 .get_hw_reg = rtl92ce_get_hw_reg,
111 .set_hw_reg = rtl92ce_set_hw_reg,
112 .update_rate_table = rtl92ce_update_hal_rate_table,
113 .update_rate_mask = rtl92ce_update_hal_rate_mask,
114 .fill_tx_desc = rtl92ce_tx_fill_desc,
115 .fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc,
116 .query_rx_desc = rtl92ce_rx_query_desc,
117 .set_channel_access = rtl92ce_update_channel_access_setting,
118 .radio_onoff_checking = rtl92ce_gpio_radio_on_off_checking,
119 .set_bw_mode = rtl92c_phy_set_bw_mode,
120 .switch_channel = rtl92c_phy_sw_chnl,
121 .dm_watchdog = rtl92c_dm_watchdog,
122 .scan_operation_backup = rtl92c_phy_scan_operation_backup,
123 .set_rf_power_state = rtl92c_phy_set_rf_power_state,
124 .led_control = rtl92ce_led_control,
125 .set_desc = rtl92ce_set_desc,
126 .get_desc = rtl92ce_get_desc,
127 .tx_polling = rtl92ce_tx_polling,
128 .enable_hw_sec = rtl92ce_enable_hw_security_config,
129 .set_key = rtl92ce_set_key,
130 .init_sw_leds = rtl92ce_init_sw_leds,
131 .deinit_sw_leds = rtl92ce_deinit_sw_leds,
132 .get_bbreg = rtl92c_phy_query_bb_reg,
133 .set_bbreg = rtl92c_phy_set_bb_reg,
134 .get_rfreg = rtl92c_phy_query_rf_reg,
135 .set_rfreg = rtl92c_phy_set_rf_reg,
136};
137
138static struct rtl_mod_params rtl92ce_mod_params = {
139 .sw_crypto = 0,
140};
141
142static struct rtl_hal_cfg rtl92ce_hal_cfg = {
143 .name = "rtl92c_pci",
144 .fw_name = "rtlwifi/rtl8192cfw.bin",
145 .ops = &rtl8192ce_hal_ops,
146 .mod_params = &rtl92ce_mod_params,
147
148 .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
149 .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
150 .maps[SYS_CLK] = REG_SYS_CLKR,
151 .maps[MAC_RCR_AM] = AM,
152 .maps[MAC_RCR_AB] = AB,
153 .maps[MAC_RCR_ACRC32] = ACRC32,
154 .maps[MAC_RCR_ACF] = ACF,
155 .maps[MAC_RCR_AAP] = AAP,
156
157 .maps[EFUSE_TEST] = REG_EFUSE_TEST,
158 .maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
159 .maps[EFUSE_CLK] = 0,
160 .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
161 .maps[EFUSE_PWC_EV12V] = PWC_EV12V,
162 .maps[EFUSE_FEN_ELDR] = FEN_ELDR,
163 .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
164 .maps[EFUSE_ANA8M] = EFUSE_ANA8M,
165 .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
166
167 .maps[RWCAM] = REG_CAMCMD,
168 .maps[WCAMI] = REG_CAMWRITE,
169 .maps[RCAMO] = REG_CAMREAD,
170 .maps[CAMDBG] = REG_CAMDBG,
171 .maps[SECR] = REG_SECCFG,
172 .maps[SEC_CAM_NONE] = CAM_NONE,
173 .maps[SEC_CAM_WEP40] = CAM_WEP40,
174 .maps[SEC_CAM_TKIP] = CAM_TKIP,
175 .maps[SEC_CAM_AES] = CAM_AES,
176 .maps[SEC_CAM_WEP104] = CAM_WEP104,
177
178 .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
179 .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
180 .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
181 .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
182 .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
183 .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
184 .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
185 .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
186 .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
187 .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
188 .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
189 .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
190 .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
191 .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
192 .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
193 .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
194
195 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
196 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
197 .maps[RTL_IMR_BcnInt] = IMR_BCNINT,
198 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
199 .maps[RTL_IMR_RDU] = IMR_RDU,
200 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
201 .maps[RTL_IMR_BDOK] = IMR_BDOK,
202 .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
203 .maps[RTL_IMR_TBDER] = IMR_TBDER,
204 .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
205 .maps[RTL_IMR_TBDOK] = IMR_TBDOK,
206 .maps[RTL_IMR_BKDOK] = IMR_BKDOK,
207 .maps[RTL_IMR_BEDOK] = IMR_BEDOK,
208 .maps[RTL_IMR_VIDOK] = IMR_VIDOK,
209 .maps[RTL_IMR_VODOK] = IMR_VODOK,
210 .maps[RTL_IMR_ROK] = IMR_ROK,
211 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
212
213 .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M,
214 .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M,
215 .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M,
216 .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M,
217 .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M,
218 .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M,
219 .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M,
220 .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M,
221 .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M,
222 .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M,
223 .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M,
224 .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M,
225
226 .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7,
227 .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15,
228};
229
230static struct pci_device_id rtl92ce_pci_ids[] __devinitdata = {
231 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)},
232 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)},
233 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)},
234 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8176, rtl92ce_hal_cfg)},
235 {},
236};
237
238MODULE_DEVICE_TABLE(pci, rtl92ce_pci_ids);
239
240MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
241MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
242MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
243MODULE_LICENSE("GPL");
244MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless");
245MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin");
246
247module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444);
248MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
249
250static struct pci_driver rtl92ce_driver = {
251 .name = KBUILD_MODNAME,
252 .id_table = rtl92ce_pci_ids,
253 .probe = rtl_pci_probe,
254 .remove = rtl_pci_disconnect,
255
256#ifdef CONFIG_PM
257 .suspend = rtl_pci_suspend,
258 .resume = rtl_pci_resume,
259#endif
260
261};
262
263static int __init rtl92ce_module_init(void)
264{
265 int ret;
266
267 ret = pci_register_driver(&rtl92ce_driver);
268 if (ret)
269 RT_ASSERT(false, (": No device found\n"));
270
271 return ret;
272}
273
274static void __exit rtl92ce_module_exit(void)
275{
276 pci_unregister_driver(&rtl92ce_driver);
277}
278
279module_init(rtl92ce_module_init);
280module_exit(rtl92ce_module_exit);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h
new file mode 100644
index 00000000000..de1198c38d4
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-sw.h
@@ -0,0 +1,37 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92CE_SW_H__
31#define __RTL92CE_SW_H__
32
33int rtl92c_init_sw_vars(struct ieee80211_hw *hw);
34void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw);
35void rtl92c_init_var_map(struct ieee80211_hw *hw);
36
37#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c
new file mode 100644
index 00000000000..2a9bbbe691a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.c
@@ -0,0 +1,1224 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Created on 2010/ 5/18, 1:41
27 *
28 * Larry Finger <Larry.Finger@lwfinger.net>
29 *
30 *****************************************************************************/
31
32#include "rtl8192c-table.h"
33
34
35u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH] = {
36 0x024, 0x0011800f,
37 0x028, 0x00ffdb83,
38 0x800, 0x80040002,
39 0x804, 0x00000003,
40 0x808, 0x0000fc00,
41 0x80c, 0x0000000a,
42 0x810, 0x10005388,
43 0x814, 0x020c3d10,
44 0x818, 0x02200385,
45 0x81c, 0x00000000,
46 0x820, 0x01000100,
47 0x824, 0x00390004,
48 0x828, 0x01000100,
49 0x82c, 0x00390004,
50 0x830, 0x27272727,
51 0x834, 0x27272727,
52 0x838, 0x27272727,
53 0x83c, 0x27272727,
54 0x840, 0x00010000,
55 0x844, 0x00010000,
56 0x848, 0x27272727,
57 0x84c, 0x27272727,
58 0x850, 0x00000000,
59 0x854, 0x00000000,
60 0x858, 0x569a569a,
61 0x85c, 0x0c1b25a4,
62 0x860, 0x66e60230,
63 0x864, 0x061f0130,
64 0x868, 0x27272727,
65 0x86c, 0x2b2b2b27,
66 0x870, 0x07000700,
67 0x874, 0x22184000,
68 0x878, 0x08080808,
69 0x87c, 0x00000000,
70 0x880, 0xc0083070,
71 0x884, 0x000004d5,
72 0x888, 0x00000000,
73 0x88c, 0xcc0000c0,
74 0x890, 0x00000800,
75 0x894, 0xfffffffe,
76 0x898, 0x40302010,
77 0x89c, 0x00706050,
78 0x900, 0x00000000,
79 0x904, 0x00000023,
80 0x908, 0x00000000,
81 0x90c, 0x81121313,
82 0xa00, 0x00d047c8,
83 0xa04, 0x80ff000c,
84 0xa08, 0x8c838300,
85 0xa0c, 0x2e68120f,
86 0xa10, 0x9500bb78,
87 0xa14, 0x11144028,
88 0xa18, 0x00881117,
89 0xa1c, 0x89140f00,
90 0xa20, 0x1a1b0000,
91 0xa24, 0x090e1317,
92 0xa28, 0x00000204,
93 0xa2c, 0x00d30000,
94 0xa70, 0x101fbf00,
95 0xa74, 0x00000007,
96 0xc00, 0x48071d40,
97 0xc04, 0x03a05633,
98 0xc08, 0x000000e4,
99 0xc0c, 0x6c6c6c6c,
100 0xc10, 0x08800000,
101 0xc14, 0x40000100,
102 0xc18, 0x08800000,
103 0xc1c, 0x40000100,
104 0xc20, 0x00000000,
105 0xc24, 0x00000000,
106 0xc28, 0x00000000,
107 0xc2c, 0x00000000,
108 0xc30, 0x69e9ac44,
109 0xc34, 0x469652cf,
110 0xc38, 0x49795994,
111 0xc3c, 0x0a97971c,
112 0xc40, 0x1f7c403f,
113 0xc44, 0x000100b7,
114 0xc48, 0xec020107,
115 0xc4c, 0x007f037f,
116 0xc50, 0x69543420,
117 0xc54, 0x43bc0094,
118 0xc58, 0x69543420,
119 0xc5c, 0x433c0094,
120 0xc60, 0x00000000,
121 0xc64, 0x5116848b,
122 0xc68, 0x47c00bff,
123 0xc6c, 0x00000036,
124 0xc70, 0x2c7f000d,
125 0xc74, 0x018610db,
126 0xc78, 0x0000001f,
127 0xc7c, 0x00b91612,
128 0xc80, 0x40000100,
129 0xc84, 0x20f60000,
130 0xc88, 0x40000100,
131 0xc8c, 0x20200000,
132 0xc90, 0x00121820,
133 0xc94, 0x00000000,
134 0xc98, 0x00121820,
135 0xc9c, 0x00007f7f,
136 0xca0, 0x00000000,
137 0xca4, 0x00000080,
138 0xca8, 0x00000000,
139 0xcac, 0x00000000,
140 0xcb0, 0x00000000,
141 0xcb4, 0x00000000,
142 0xcb8, 0x00000000,
143 0xcbc, 0x28000000,
144 0xcc0, 0x00000000,
145 0xcc4, 0x00000000,
146 0xcc8, 0x00000000,
147 0xccc, 0x00000000,
148 0xcd0, 0x00000000,
149 0xcd4, 0x00000000,
150 0xcd8, 0x64b22427,
151 0xcdc, 0x00766932,
152 0xce0, 0x00222222,
153 0xce4, 0x00000000,
154 0xce8, 0x37644302,
155 0xcec, 0x2f97d40c,
156 0xd00, 0x00080740,
157 0xd04, 0x00020403,
158 0xd08, 0x0000907f,
159 0xd0c, 0x20010201,
160 0xd10, 0xa0633333,
161 0xd14, 0x3333bc43,
162 0xd18, 0x7a8f5b6b,
163 0xd2c, 0xcc979975,
164 0xd30, 0x00000000,
165 0xd34, 0x80608000,
166 0xd38, 0x00000000,
167 0xd3c, 0x00027293,
168 0xd40, 0x00000000,
169 0xd44, 0x00000000,
170 0xd48, 0x00000000,
171 0xd4c, 0x00000000,
172 0xd50, 0x6437140a,
173 0xd54, 0x00000000,
174 0xd58, 0x00000000,
175 0xd5c, 0x30032064,
176 0xd60, 0x4653de68,
177 0xd64, 0x04518a3c,
178 0xd68, 0x00002101,
179 0xd6c, 0x2a201c16,
180 0xd70, 0x1812362e,
181 0xd74, 0x322c2220,
182 0xd78, 0x000e3c24,
183 0xe00, 0x2a2a2a2a,
184 0xe04, 0x2a2a2a2a,
185 0xe08, 0x03902a2a,
186 0xe10, 0x2a2a2a2a,
187 0xe14, 0x2a2a2a2a,
188 0xe18, 0x2a2a2a2a,
189 0xe1c, 0x2a2a2a2a,
190 0xe28, 0x00000000,
191 0xe30, 0x1000dc1f,
192 0xe34, 0x10008c1f,
193 0xe38, 0x02140102,
194 0xe3c, 0x681604c2,
195 0xe40, 0x01007c00,
196 0xe44, 0x01004800,
197 0xe48, 0xfb000000,
198 0xe4c, 0x000028d1,
199 0xe50, 0x1000dc1f,
200 0xe54, 0x10008c1f,
201 0xe58, 0x02140102,
202 0xe5c, 0x28160d05,
203 0xe60, 0x00000010,
204 0xe68, 0x001b25a4,
205 0xe6c, 0x63db25a4,
206 0xe70, 0x63db25a4,
207 0xe74, 0x0c1b25a4,
208 0xe78, 0x0c1b25a4,
209 0xe7c, 0x0c1b25a4,
210 0xe80, 0x0c1b25a4,
211 0xe84, 0x63db25a4,
212 0xe88, 0x0c1b25a4,
213 0xe8c, 0x63db25a4,
214 0xed0, 0x63db25a4,
215 0xed4, 0x63db25a4,
216 0xed8, 0x63db25a4,
217 0xedc, 0x001b25a4,
218 0xee0, 0x001b25a4,
219 0xeec, 0x6fdb25a4,
220 0xf14, 0x00000003,
221 0xf4c, 0x00000000,
222 0xf00, 0x00000300,
223};
224
225u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH] = {
226 0x024, 0x0011800f,
227 0x028, 0x00ffdb83,
228 0x800, 0x80040000,
229 0x804, 0x00000001,
230 0x808, 0x0000fc00,
231 0x80c, 0x0000000a,
232 0x810, 0x10005388,
233 0x814, 0x020c3d10,
234 0x818, 0x02200385,
235 0x81c, 0x00000000,
236 0x820, 0x01000100,
237 0x824, 0x00390004,
238 0x828, 0x00000000,
239 0x82c, 0x00000000,
240 0x830, 0x00000000,
241 0x834, 0x00000000,
242 0x838, 0x00000000,
243 0x83c, 0x00000000,
244 0x840, 0x00010000,
245 0x844, 0x00000000,
246 0x848, 0x00000000,
247 0x84c, 0x00000000,
248 0x850, 0x00000000,
249 0x854, 0x00000000,
250 0x858, 0x569a569a,
251 0x85c, 0x001b25a4,
252 0x860, 0x66e60230,
253 0x864, 0x061f0130,
254 0x868, 0x00000000,
255 0x86c, 0x32323200,
256 0x870, 0x07000700,
257 0x874, 0x22004000,
258 0x878, 0x00000808,
259 0x87c, 0x00000000,
260 0x880, 0xc0083070,
261 0x884, 0x000004d5,
262 0x888, 0x00000000,
263 0x88c, 0xccc000c0,
264 0x890, 0x00000800,
265 0x894, 0xfffffffe,
266 0x898, 0x40302010,
267 0x89c, 0x00706050,
268 0x900, 0x00000000,
269 0x904, 0x00000023,
270 0x908, 0x00000000,
271 0x90c, 0x81121111,
272 0xa00, 0x00d047c8,
273 0xa04, 0x80ff000c,
274 0xa08, 0x8c838300,
275 0xa0c, 0x2e68120f,
276 0xa10, 0x9500bb78,
277 0xa14, 0x11144028,
278 0xa18, 0x00881117,
279 0xa1c, 0x89140f00,
280 0xa20, 0x1a1b0000,
281 0xa24, 0x090e1317,
282 0xa28, 0x00000204,
283 0xa2c, 0x00d30000,
284 0xa70, 0x101fbf00,
285 0xa74, 0x00000007,
286 0xc00, 0x48071d40,
287 0xc04, 0x03a05611,
288 0xc08, 0x000000e4,
289 0xc0c, 0x6c6c6c6c,
290 0xc10, 0x08800000,
291 0xc14, 0x40000100,
292 0xc18, 0x08800000,
293 0xc1c, 0x40000100,
294 0xc20, 0x00000000,
295 0xc24, 0x00000000,
296 0xc28, 0x00000000,
297 0xc2c, 0x00000000,
298 0xc30, 0x69e9ac44,
299 0xc34, 0x469652cf,
300 0xc38, 0x49795994,
301 0xc3c, 0x0a97971c,
302 0xc40, 0x1f7c403f,
303 0xc44, 0x000100b7,
304 0xc48, 0xec020107,
305 0xc4c, 0x007f037f,
306 0xc50, 0x69543420,
307 0xc54, 0x43bc0094,
308 0xc58, 0x69543420,
309 0xc5c, 0x433c0094,
310 0xc60, 0x00000000,
311 0xc64, 0x5116848b,
312 0xc68, 0x47c00bff,
313 0xc6c, 0x00000036,
314 0xc70, 0x2c7f000d,
315 0xc74, 0x018610db,
316 0xc78, 0x0000001f,
317 0xc7c, 0x00b91612,
318 0xc80, 0x40000100,
319 0xc84, 0x20f60000,
320 0xc88, 0x40000100,
321 0xc8c, 0x20200000,
322 0xc90, 0x00121820,
323 0xc94, 0x00000000,
324 0xc98, 0x00121820,
325 0xc9c, 0x00007f7f,
326 0xca0, 0x00000000,
327 0xca4, 0x00000080,
328 0xca8, 0x00000000,
329 0xcac, 0x00000000,
330 0xcb0, 0x00000000,
331 0xcb4, 0x00000000,
332 0xcb8, 0x00000000,
333 0xcbc, 0x28000000,
334 0xcc0, 0x00000000,
335 0xcc4, 0x00000000,
336 0xcc8, 0x00000000,
337 0xccc, 0x00000000,
338 0xcd0, 0x00000000,
339 0xcd4, 0x00000000,
340 0xcd8, 0x64b22427,
341 0xcdc, 0x00766932,
342 0xce0, 0x00222222,
343 0xce4, 0x00000000,
344 0xce8, 0x37644302,
345 0xcec, 0x2f97d40c,
346 0xd00, 0x00080740,
347 0xd04, 0x00020401,
348 0xd08, 0x0000907f,
349 0xd0c, 0x20010201,
350 0xd10, 0xa0633333,
351 0xd14, 0x3333bc43,
352 0xd18, 0x7a8f5b6b,
353 0xd2c, 0xcc979975,
354 0xd30, 0x00000000,
355 0xd34, 0x80608000,
356 0xd38, 0x00000000,
357 0xd3c, 0x00027293,
358 0xd40, 0x00000000,
359 0xd44, 0x00000000,
360 0xd48, 0x00000000,
361 0xd4c, 0x00000000,
362 0xd50, 0x6437140a,
363 0xd54, 0x00000000,
364 0xd58, 0x00000000,
365 0xd5c, 0x30032064,
366 0xd60, 0x4653de68,
367 0xd64, 0x04518a3c,
368 0xd68, 0x00002101,
369 0xd6c, 0x2a201c16,
370 0xd70, 0x1812362e,
371 0xd74, 0x322c2220,
372 0xd78, 0x000e3c24,
373 0xe00, 0x2a2a2a2a,
374 0xe04, 0x2a2a2a2a,
375 0xe08, 0x03902a2a,
376 0xe10, 0x2a2a2a2a,
377 0xe14, 0x2a2a2a2a,
378 0xe18, 0x2a2a2a2a,
379 0xe1c, 0x2a2a2a2a,
380 0xe28, 0x00000000,
381 0xe30, 0x1000dc1f,
382 0xe34, 0x10008c1f,
383 0xe38, 0x02140102,
384 0xe3c, 0x681604c2,
385 0xe40, 0x01007c00,
386 0xe44, 0x01004800,
387 0xe48, 0xfb000000,
388 0xe4c, 0x000028d1,
389 0xe50, 0x1000dc1f,
390 0xe54, 0x10008c1f,
391 0xe58, 0x02140102,
392 0xe5c, 0x28160d05,
393 0xe60, 0x00000010,
394 0xe68, 0x001b25a4,
395 0xe6c, 0x631b25a0,
396 0xe70, 0x631b25a0,
397 0xe74, 0x081b25a0,
398 0xe78, 0x081b25a0,
399 0xe7c, 0x081b25a0,
400 0xe80, 0x081b25a0,
401 0xe84, 0x631b25a0,
402 0xe88, 0x081b25a0,
403 0xe8c, 0x631b25a0,
404 0xed0, 0x631b25a0,
405 0xed4, 0x631b25a0,
406 0xed8, 0x631b25a0,
407 0xedc, 0x001b25a0,
408 0xee0, 0x001b25a0,
409 0xeec, 0x6b1b25a0,
410 0xf14, 0x00000003,
411 0xf4c, 0x00000000,
412 0xf00, 0x00000300,
413};
414
415u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH] = {
416 0xe00, 0xffffffff, 0x0a0c0c0c,
417 0xe04, 0xffffffff, 0x02040608,
418 0xe08, 0x0000ff00, 0x00000000,
419 0x86c, 0xffffff00, 0x00000000,
420 0xe10, 0xffffffff, 0x0a0c0d0e,
421 0xe14, 0xffffffff, 0x02040608,
422 0xe18, 0xffffffff, 0x0a0c0d0e,
423 0xe1c, 0xffffffff, 0x02040608,
424 0x830, 0xffffffff, 0x0a0c0c0c,
425 0x834, 0xffffffff, 0x02040608,
426 0x838, 0xffffff00, 0x00000000,
427 0x86c, 0x000000ff, 0x00000000,
428 0x83c, 0xffffffff, 0x0a0c0d0e,
429 0x848, 0xffffffff, 0x02040608,
430 0x84c, 0xffffffff, 0x0a0c0d0e,
431 0x868, 0xffffffff, 0x02040608,
432 0xe00, 0xffffffff, 0x00000000,
433 0xe04, 0xffffffff, 0x00000000,
434 0xe08, 0x0000ff00, 0x00000000,
435 0x86c, 0xffffff00, 0x00000000,
436 0xe10, 0xffffffff, 0x00000000,
437 0xe14, 0xffffffff, 0x00000000,
438 0xe18, 0xffffffff, 0x00000000,
439 0xe1c, 0xffffffff, 0x00000000,
440 0x830, 0xffffffff, 0x00000000,
441 0x834, 0xffffffff, 0x00000000,
442 0x838, 0xffffff00, 0x00000000,
443 0x86c, 0x000000ff, 0x00000000,
444 0x83c, 0xffffffff, 0x00000000,
445 0x848, 0xffffffff, 0x00000000,
446 0x84c, 0xffffffff, 0x00000000,
447 0x868, 0xffffffff, 0x00000000,
448 0xe00, 0xffffffff, 0x04040404,
449 0xe04, 0xffffffff, 0x00020204,
450 0xe08, 0x0000ff00, 0x00000000,
451 0x86c, 0xffffff00, 0x00000000,
452 0xe10, 0xffffffff, 0x06060606,
453 0xe14, 0xffffffff, 0x00020406,
454 0xe18, 0xffffffff, 0x06060606,
455 0xe1c, 0xffffffff, 0x00020406,
456 0x830, 0xffffffff, 0x04040404,
457 0x834, 0xffffffff, 0x00020204,
458 0x838, 0xffffff00, 0x00000000,
459 0x86c, 0x000000ff, 0x00000000,
460 0x83c, 0xffffffff, 0x06060606,
461 0x848, 0xffffffff, 0x00020406,
462 0x84c, 0xffffffff, 0x06060606,
463 0x868, 0xffffffff, 0x00020406,
464 0xe00, 0xffffffff, 0x00000000,
465 0xe04, 0xffffffff, 0x00000000,
466 0xe08, 0x0000ff00, 0x00000000,
467 0x86c, 0xffffff00, 0x00000000,
468 0xe10, 0xffffffff, 0x00000000,
469 0xe14, 0xffffffff, 0x00000000,
470 0xe18, 0xffffffff, 0x00000000,
471 0xe1c, 0xffffffff, 0x00000000,
472 0x830, 0xffffffff, 0x00000000,
473 0x834, 0xffffffff, 0x00000000,
474 0x838, 0xffffff00, 0x00000000,
475 0x86c, 0x000000ff, 0x00000000,
476 0x83c, 0xffffffff, 0x00000000,
477 0x848, 0xffffffff, 0x00000000,
478 0x84c, 0xffffffff, 0x00000000,
479 0x868, 0xffffffff, 0x00000000,
480};
481
482u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH] = {
483 0x000, 0x00030159,
484 0x001, 0x00031284,
485 0x002, 0x00098000,
486 0x003, 0x00018c63,
487 0x004, 0x000210e7,
488 0x009, 0x0002044f,
489 0x00a, 0x0001adb0,
490 0x00b, 0x00054867,
491 0x00c, 0x0008992e,
492 0x00d, 0x0000e52c,
493 0x00e, 0x00039ce7,
494 0x00f, 0x00000451,
495 0x019, 0x00000000,
496 0x01a, 0x00010255,
497 0x01b, 0x00060a00,
498 0x01c, 0x000fc378,
499 0x01d, 0x000a1250,
500 0x01e, 0x0004445f,
501 0x01f, 0x00080001,
502 0x020, 0x0000b614,
503 0x021, 0x0006c000,
504 0x022, 0x00000000,
505 0x023, 0x00001558,
506 0x024, 0x00000060,
507 0x025, 0x00000483,
508 0x026, 0x0004f000,
509 0x027, 0x000ec7d9,
510 0x028, 0x000977c0,
511 0x029, 0x00004783,
512 0x02a, 0x00000001,
513 0x02b, 0x00021334,
514 0x02a, 0x00000000,
515 0x02b, 0x00000054,
516 0x02a, 0x00000001,
517 0x02b, 0x00000808,
518 0x02b, 0x00053333,
519 0x02c, 0x0000000c,
520 0x02a, 0x00000002,
521 0x02b, 0x00000808,
522 0x02b, 0x0005b333,
523 0x02c, 0x0000000d,
524 0x02a, 0x00000003,
525 0x02b, 0x00000808,
526 0x02b, 0x00063333,
527 0x02c, 0x0000000d,
528 0x02a, 0x00000004,
529 0x02b, 0x00000808,
530 0x02b, 0x0006b333,
531 0x02c, 0x0000000d,
532 0x02a, 0x00000005,
533 0x02b, 0x00000808,
534 0x02b, 0x00073333,
535 0x02c, 0x0000000d,
536 0x02a, 0x00000006,
537 0x02b, 0x00000709,
538 0x02b, 0x0005b333,
539 0x02c, 0x0000000d,
540 0x02a, 0x00000007,
541 0x02b, 0x00000709,
542 0x02b, 0x00063333,
543 0x02c, 0x0000000d,
544 0x02a, 0x00000008,
545 0x02b, 0x0000060a,
546 0x02b, 0x0004b333,
547 0x02c, 0x0000000d,
548 0x02a, 0x00000009,
549 0x02b, 0x0000060a,
550 0x02b, 0x00053333,
551 0x02c, 0x0000000d,
552 0x02a, 0x0000000a,
553 0x02b, 0x0000060a,
554 0x02b, 0x0005b333,
555 0x02c, 0x0000000d,
556 0x02a, 0x0000000b,
557 0x02b, 0x0000060a,
558 0x02b, 0x00063333,
559 0x02c, 0x0000000d,
560 0x02a, 0x0000000c,
561 0x02b, 0x0000060a,
562 0x02b, 0x0006b333,
563 0x02c, 0x0000000d,
564 0x02a, 0x0000000d,
565 0x02b, 0x0000060a,
566 0x02b, 0x00073333,
567 0x02c, 0x0000000d,
568 0x02a, 0x0000000e,
569 0x02b, 0x0000050b,
570 0x02b, 0x00066666,
571 0x02c, 0x0000001a,
572 0x02a, 0x000e0000,
573 0x010, 0x0004000f,
574 0x011, 0x000e31fc,
575 0x010, 0x0006000f,
576 0x011, 0x000ff9f8,
577 0x010, 0x0002000f,
578 0x011, 0x000203f9,
579 0x010, 0x0003000f,
580 0x011, 0x000ff500,
581 0x010, 0x00000000,
582 0x011, 0x00000000,
583 0x010, 0x0008000f,
584 0x011, 0x0003f100,
585 0x010, 0x0009000f,
586 0x011, 0x00023100,
587 0x012, 0x00032000,
588 0x012, 0x00071000,
589 0x012, 0x000b0000,
590 0x012, 0x000fc000,
591 0x013, 0x000287af,
592 0x013, 0x000244b7,
593 0x013, 0x000204ab,
594 0x013, 0x0001c49f,
595 0x013, 0x00018493,
596 0x013, 0x00014297,
597 0x013, 0x00010295,
598 0x013, 0x0000c298,
599 0x013, 0x0000819c,
600 0x013, 0x000040a8,
601 0x013, 0x0000001c,
602 0x014, 0x0001944c,
603 0x014, 0x00059444,
604 0x014, 0x0009944c,
605 0x014, 0x000d9444,
606 0x015, 0x0000f424,
607 0x015, 0x0004f424,
608 0x015, 0x0008f424,
609 0x015, 0x000cf424,
610 0x016, 0x000e0330,
611 0x016, 0x000a0330,
612 0x016, 0x00060330,
613 0x016, 0x00020330,
614 0x000, 0x00010159,
615 0x018, 0x0000f401,
616 0x0fe, 0x00000000,
617 0x0fe, 0x00000000,
618 0x01f, 0x00080003,
619 0x0fe, 0x00000000,
620 0x0fe, 0x00000000,
621 0x01e, 0x00044457,
622 0x01f, 0x00080000,
623 0x000, 0x00030159,
624};
625
626u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH] = {
627 0x000, 0x00030159,
628 0x001, 0x00031284,
629 0x002, 0x00098000,
630 0x003, 0x00018c63,
631 0x004, 0x000210e7,
632 0x009, 0x0002044f,
633 0x00a, 0x0001adb0,
634 0x00b, 0x00054867,
635 0x00c, 0x0008992e,
636 0x00d, 0x0000e52c,
637 0x00e, 0x00039ce7,
638 0x00f, 0x00000451,
639 0x012, 0x00032000,
640 0x012, 0x00071000,
641 0x012, 0x000b0000,
642 0x012, 0x000fc000,
643 0x013, 0x000287af,
644 0x013, 0x000244b7,
645 0x013, 0x000204ab,
646 0x013, 0x0001c49f,
647 0x013, 0x00018493,
648 0x013, 0x00014297,
649 0x013, 0x00010295,
650 0x013, 0x0000c298,
651 0x013, 0x0000819c,
652 0x013, 0x000040a8,
653 0x013, 0x0000001c,
654 0x014, 0x0001944c,
655 0x014, 0x00059444,
656 0x014, 0x0009944c,
657 0x014, 0x000d9444,
658 0x015, 0x0000f424,
659 0x015, 0x0004f424,
660 0x015, 0x0008f424,
661 0x015, 0x000cf424,
662 0x016, 0x000e0330,
663 0x016, 0x000a0330,
664 0x016, 0x00060330,
665 0x016, 0x00020330,
666};
667
668u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH] = {
669 0x000, 0x00030159,
670 0x001, 0x00031284,
671 0x002, 0x00098000,
672 0x003, 0x00018c63,
673 0x004, 0x000210e7,
674 0x009, 0x0002044f,
675 0x00a, 0x0001adb0,
676 0x00b, 0x00054867,
677 0x00c, 0x0008992e,
678 0x00d, 0x0000e52c,
679 0x00e, 0x00039ce7,
680 0x00f, 0x00000451,
681 0x019, 0x00000000,
682 0x01a, 0x00010255,
683 0x01b, 0x00060a00,
684 0x01c, 0x000fc378,
685 0x01d, 0x000a1250,
686 0x01e, 0x0004445f,
687 0x01f, 0x00080001,
688 0x020, 0x0000b614,
689 0x021, 0x0006c000,
690 0x022, 0x00000000,
691 0x023, 0x00001558,
692 0x024, 0x00000060,
693 0x025, 0x00000483,
694 0x026, 0x0004f000,
695 0x027, 0x000ec7d9,
696 0x028, 0x000977c0,
697 0x029, 0x00004783,
698 0x02a, 0x00000001,
699 0x02b, 0x00021334,
700 0x02a, 0x00000000,
701 0x02b, 0x00000054,
702 0x02a, 0x00000001,
703 0x02b, 0x00000808,
704 0x02b, 0x00053333,
705 0x02c, 0x0000000c,
706 0x02a, 0x00000002,
707 0x02b, 0x00000808,
708 0x02b, 0x0005b333,
709 0x02c, 0x0000000d,
710 0x02a, 0x00000003,
711 0x02b, 0x00000808,
712 0x02b, 0x00063333,
713 0x02c, 0x0000000d,
714 0x02a, 0x00000004,
715 0x02b, 0x00000808,
716 0x02b, 0x0006b333,
717 0x02c, 0x0000000d,
718 0x02a, 0x00000005,
719 0x02b, 0x00000808,
720 0x02b, 0x00073333,
721 0x02c, 0x0000000d,
722 0x02a, 0x00000006,
723 0x02b, 0x00000709,
724 0x02b, 0x0005b333,
725 0x02c, 0x0000000d,
726 0x02a, 0x00000007,
727 0x02b, 0x00000709,
728 0x02b, 0x00063333,
729 0x02c, 0x0000000d,
730 0x02a, 0x00000008,
731 0x02b, 0x0000060a,
732 0x02b, 0x0004b333,
733 0x02c, 0x0000000d,
734 0x02a, 0x00000009,
735 0x02b, 0x0000060a,
736 0x02b, 0x00053333,
737 0x02c, 0x0000000d,
738 0x02a, 0x0000000a,
739 0x02b, 0x0000060a,
740 0x02b, 0x0005b333,
741 0x02c, 0x0000000d,
742 0x02a, 0x0000000b,
743 0x02b, 0x0000060a,
744 0x02b, 0x00063333,
745 0x02c, 0x0000000d,
746 0x02a, 0x0000000c,
747 0x02b, 0x0000060a,
748 0x02b, 0x0006b333,
749 0x02c, 0x0000000d,
750 0x02a, 0x0000000d,
751 0x02b, 0x0000060a,
752 0x02b, 0x00073333,
753 0x02c, 0x0000000d,
754 0x02a, 0x0000000e,
755 0x02b, 0x0000050b,
756 0x02b, 0x00066666,
757 0x02c, 0x0000001a,
758 0x02a, 0x000e0000,
759 0x010, 0x0004000f,
760 0x011, 0x000e31fc,
761 0x010, 0x0006000f,
762 0x011, 0x000ff9f8,
763 0x010, 0x0002000f,
764 0x011, 0x000203f9,
765 0x010, 0x0003000f,
766 0x011, 0x000ff500,
767 0x010, 0x00000000,
768 0x011, 0x00000000,
769 0x010, 0x0008000f,
770 0x011, 0x0003f100,
771 0x010, 0x0009000f,
772 0x011, 0x00023100,
773 0x012, 0x00032000,
774 0x012, 0x00071000,
775 0x012, 0x000b0000,
776 0x012, 0x000fc000,
777 0x013, 0x000287af,
778 0x013, 0x000244b7,
779 0x013, 0x000204ab,
780 0x013, 0x0001c49f,
781 0x013, 0x00018493,
782 0x013, 0x00014297,
783 0x013, 0x00010295,
784 0x013, 0x0000c298,
785 0x013, 0x0000819c,
786 0x013, 0x000040a8,
787 0x013, 0x0000001c,
788 0x014, 0x0001944c,
789 0x014, 0x00059444,
790 0x014, 0x0009944c,
791 0x014, 0x000d9444,
792 0x015, 0x0000f424,
793 0x015, 0x0004f424,
794 0x015, 0x0008f424,
795 0x015, 0x000cf424,
796 0x016, 0x000e0330,
797 0x016, 0x000a0330,
798 0x016, 0x00060330,
799 0x016, 0x00020330,
800 0x000, 0x00010159,
801 0x018, 0x0000f401,
802 0x0fe, 0x00000000,
803 0x0fe, 0x00000000,
804 0x01f, 0x00080003,
805 0x0fe, 0x00000000,
806 0x0fe, 0x00000000,
807 0x01e, 0x00044457,
808 0x01f, 0x00080000,
809 0x000, 0x00030159,
810};
811
812u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH] = {
813 0x0,
814};
815
816u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH] = {
817 0x420, 0x00000080,
818 0x423, 0x00000000,
819 0x430, 0x00000000,
820 0x431, 0x00000000,
821 0x432, 0x00000000,
822 0x433, 0x00000001,
823 0x434, 0x00000004,
824 0x435, 0x00000005,
825 0x436, 0x00000006,
826 0x437, 0x00000007,
827 0x438, 0x00000000,
828 0x439, 0x00000000,
829 0x43a, 0x00000000,
830 0x43b, 0x00000001,
831 0x43c, 0x00000004,
832 0x43d, 0x00000005,
833 0x43e, 0x00000006,
834 0x43f, 0x00000007,
835 0x440, 0x0000005d,
836 0x441, 0x00000001,
837 0x442, 0x00000000,
838 0x444, 0x00000015,
839 0x445, 0x000000f0,
840 0x446, 0x0000000f,
841 0x447, 0x00000000,
842 0x458, 0x00000041,
843 0x459, 0x000000a8,
844 0x45a, 0x00000072,
845 0x45b, 0x000000b9,
846 0x460, 0x00000088,
847 0x461, 0x00000088,
848 0x462, 0x00000006,
849 0x463, 0x00000003,
850 0x4c8, 0x00000004,
851 0x4c9, 0x00000008,
852 0x4cc, 0x00000002,
853 0x4cd, 0x00000028,
854 0x4ce, 0x00000001,
855 0x500, 0x00000026,
856 0x501, 0x000000a2,
857 0x502, 0x0000002f,
858 0x503, 0x00000000,
859 0x504, 0x00000028,
860 0x505, 0x000000a3,
861 0x506, 0x0000005e,
862 0x507, 0x00000000,
863 0x508, 0x0000002b,
864 0x509, 0x000000a4,
865 0x50a, 0x0000005e,
866 0x50b, 0x00000000,
867 0x50c, 0x0000004f,
868 0x50d, 0x000000a4,
869 0x50e, 0x00000000,
870 0x50f, 0x00000000,
871 0x512, 0x0000001c,
872 0x514, 0x0000000a,
873 0x515, 0x00000010,
874 0x516, 0x0000000a,
875 0x517, 0x00000010,
876 0x51a, 0x00000016,
877 0x524, 0x0000000f,
878 0x525, 0x0000004f,
879 0x546, 0x00000020,
880 0x547, 0x00000000,
881 0x559, 0x00000002,
882 0x55a, 0x00000002,
883 0x55d, 0x000000ff,
884 0x605, 0x00000030,
885 0x608, 0x0000000e,
886 0x609, 0x0000002a,
887 0x652, 0x00000020,
888 0x63c, 0x0000000a,
889 0x63d, 0x0000000a,
890 0x700, 0x00000021,
891 0x701, 0x00000043,
892 0x702, 0x00000065,
893 0x703, 0x00000087,
894 0x708, 0x00000021,
895 0x709, 0x00000043,
896 0x70a, 0x00000065,
897 0x70b, 0x00000087,
898};
899
900u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH] = {
901 0xc78, 0x7b000001,
902 0xc78, 0x7b010001,
903 0xc78, 0x7b020001,
904 0xc78, 0x7b030001,
905 0xc78, 0x7b040001,
906 0xc78, 0x7b050001,
907 0xc78, 0x7a060001,
908 0xc78, 0x79070001,
909 0xc78, 0x78080001,
910 0xc78, 0x77090001,
911 0xc78, 0x760a0001,
912 0xc78, 0x750b0001,
913 0xc78, 0x740c0001,
914 0xc78, 0x730d0001,
915 0xc78, 0x720e0001,
916 0xc78, 0x710f0001,
917 0xc78, 0x70100001,
918 0xc78, 0x6f110001,
919 0xc78, 0x6e120001,
920 0xc78, 0x6d130001,
921 0xc78, 0x6c140001,
922 0xc78, 0x6b150001,
923 0xc78, 0x6a160001,
924 0xc78, 0x69170001,
925 0xc78, 0x68180001,
926 0xc78, 0x67190001,
927 0xc78, 0x661a0001,
928 0xc78, 0x651b0001,
929 0xc78, 0x641c0001,
930 0xc78, 0x631d0001,
931 0xc78, 0x621e0001,
932 0xc78, 0x611f0001,
933 0xc78, 0x60200001,
934 0xc78, 0x49210001,
935 0xc78, 0x48220001,
936 0xc78, 0x47230001,
937 0xc78, 0x46240001,
938 0xc78, 0x45250001,
939 0xc78, 0x44260001,
940 0xc78, 0x43270001,
941 0xc78, 0x42280001,
942 0xc78, 0x41290001,
943 0xc78, 0x402a0001,
944 0xc78, 0x262b0001,
945 0xc78, 0x252c0001,
946 0xc78, 0x242d0001,
947 0xc78, 0x232e0001,
948 0xc78, 0x222f0001,
949 0xc78, 0x21300001,
950 0xc78, 0x20310001,
951 0xc78, 0x06320001,
952 0xc78, 0x05330001,
953 0xc78, 0x04340001,
954 0xc78, 0x03350001,
955 0xc78, 0x02360001,
956 0xc78, 0x01370001,
957 0xc78, 0x00380001,
958 0xc78, 0x00390001,
959 0xc78, 0x003a0001,
960 0xc78, 0x003b0001,
961 0xc78, 0x003c0001,
962 0xc78, 0x003d0001,
963 0xc78, 0x003e0001,
964 0xc78, 0x003f0001,
965 0xc78, 0x7b400001,
966 0xc78, 0x7b410001,
967 0xc78, 0x7b420001,
968 0xc78, 0x7b430001,
969 0xc78, 0x7b440001,
970 0xc78, 0x7b450001,
971 0xc78, 0x7a460001,
972 0xc78, 0x79470001,
973 0xc78, 0x78480001,
974 0xc78, 0x77490001,
975 0xc78, 0x764a0001,
976 0xc78, 0x754b0001,
977 0xc78, 0x744c0001,
978 0xc78, 0x734d0001,
979 0xc78, 0x724e0001,
980 0xc78, 0x714f0001,
981 0xc78, 0x70500001,
982 0xc78, 0x6f510001,
983 0xc78, 0x6e520001,
984 0xc78, 0x6d530001,
985 0xc78, 0x6c540001,
986 0xc78, 0x6b550001,
987 0xc78, 0x6a560001,
988 0xc78, 0x69570001,
989 0xc78, 0x68580001,
990 0xc78, 0x67590001,
991 0xc78, 0x665a0001,
992 0xc78, 0x655b0001,
993 0xc78, 0x645c0001,
994 0xc78, 0x635d0001,
995 0xc78, 0x625e0001,
996 0xc78, 0x615f0001,
997 0xc78, 0x60600001,
998 0xc78, 0x49610001,
999 0xc78, 0x48620001,
1000 0xc78, 0x47630001,
1001 0xc78, 0x46640001,
1002 0xc78, 0x45650001,
1003 0xc78, 0x44660001,
1004 0xc78, 0x43670001,
1005 0xc78, 0x42680001,
1006 0xc78, 0x41690001,
1007 0xc78, 0x406a0001,
1008 0xc78, 0x266b0001,
1009 0xc78, 0x256c0001,
1010 0xc78, 0x246d0001,
1011 0xc78, 0x236e0001,
1012 0xc78, 0x226f0001,
1013 0xc78, 0x21700001,
1014 0xc78, 0x20710001,
1015 0xc78, 0x06720001,
1016 0xc78, 0x05730001,
1017 0xc78, 0x04740001,
1018 0xc78, 0x03750001,
1019 0xc78, 0x02760001,
1020 0xc78, 0x01770001,
1021 0xc78, 0x00780001,
1022 0xc78, 0x00790001,
1023 0xc78, 0x007a0001,
1024 0xc78, 0x007b0001,
1025 0xc78, 0x007c0001,
1026 0xc78, 0x007d0001,
1027 0xc78, 0x007e0001,
1028 0xc78, 0x007f0001,
1029 0xc78, 0x3800001e,
1030 0xc78, 0x3801001e,
1031 0xc78, 0x3802001e,
1032 0xc78, 0x3803001e,
1033 0xc78, 0x3804001e,
1034 0xc78, 0x3805001e,
1035 0xc78, 0x3806001e,
1036 0xc78, 0x3807001e,
1037 0xc78, 0x3808001e,
1038 0xc78, 0x3c09001e,
1039 0xc78, 0x3e0a001e,
1040 0xc78, 0x400b001e,
1041 0xc78, 0x440c001e,
1042 0xc78, 0x480d001e,
1043 0xc78, 0x4c0e001e,
1044 0xc78, 0x500f001e,
1045 0xc78, 0x5210001e,
1046 0xc78, 0x5611001e,
1047 0xc78, 0x5a12001e,
1048 0xc78, 0x5e13001e,
1049 0xc78, 0x6014001e,
1050 0xc78, 0x6015001e,
1051 0xc78, 0x6016001e,
1052 0xc78, 0x6217001e,
1053 0xc78, 0x6218001e,
1054 0xc78, 0x6219001e,
1055 0xc78, 0x621a001e,
1056 0xc78, 0x621b001e,
1057 0xc78, 0x621c001e,
1058 0xc78, 0x621d001e,
1059 0xc78, 0x621e001e,
1060 0xc78, 0x621f001e,
1061};
1062
1063u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH] = {
1064 0xc78, 0x7b000001,
1065 0xc78, 0x7b010001,
1066 0xc78, 0x7b020001,
1067 0xc78, 0x7b030001,
1068 0xc78, 0x7b040001,
1069 0xc78, 0x7b050001,
1070 0xc78, 0x7a060001,
1071 0xc78, 0x79070001,
1072 0xc78, 0x78080001,
1073 0xc78, 0x77090001,
1074 0xc78, 0x760a0001,
1075 0xc78, 0x750b0001,
1076 0xc78, 0x740c0001,
1077 0xc78, 0x730d0001,
1078 0xc78, 0x720e0001,
1079 0xc78, 0x710f0001,
1080 0xc78, 0x70100001,
1081 0xc78, 0x6f110001,
1082 0xc78, 0x6e120001,
1083 0xc78, 0x6d130001,
1084 0xc78, 0x6c140001,
1085 0xc78, 0x6b150001,
1086 0xc78, 0x6a160001,
1087 0xc78, 0x69170001,
1088 0xc78, 0x68180001,
1089 0xc78, 0x67190001,
1090 0xc78, 0x661a0001,
1091 0xc78, 0x651b0001,
1092 0xc78, 0x641c0001,
1093 0xc78, 0x631d0001,
1094 0xc78, 0x621e0001,
1095 0xc78, 0x611f0001,
1096 0xc78, 0x60200001,
1097 0xc78, 0x49210001,
1098 0xc78, 0x48220001,
1099 0xc78, 0x47230001,
1100 0xc78, 0x46240001,
1101 0xc78, 0x45250001,
1102 0xc78, 0x44260001,
1103 0xc78, 0x43270001,
1104 0xc78, 0x42280001,
1105 0xc78, 0x41290001,
1106 0xc78, 0x402a0001,
1107 0xc78, 0x262b0001,
1108 0xc78, 0x252c0001,
1109 0xc78, 0x242d0001,
1110 0xc78, 0x232e0001,
1111 0xc78, 0x222f0001,
1112 0xc78, 0x21300001,
1113 0xc78, 0x20310001,
1114 0xc78, 0x06320001,
1115 0xc78, 0x05330001,
1116 0xc78, 0x04340001,
1117 0xc78, 0x03350001,
1118 0xc78, 0x02360001,
1119 0xc78, 0x01370001,
1120 0xc78, 0x00380001,
1121 0xc78, 0x00390001,
1122 0xc78, 0x003a0001,
1123 0xc78, 0x003b0001,
1124 0xc78, 0x003c0001,
1125 0xc78, 0x003d0001,
1126 0xc78, 0x003e0001,
1127 0xc78, 0x003f0001,
1128 0xc78, 0x7b400001,
1129 0xc78, 0x7b410001,
1130 0xc78, 0x7b420001,
1131 0xc78, 0x7b430001,
1132 0xc78, 0x7b440001,
1133 0xc78, 0x7b450001,
1134 0xc78, 0x7a460001,
1135 0xc78, 0x79470001,
1136 0xc78, 0x78480001,
1137 0xc78, 0x77490001,
1138 0xc78, 0x764a0001,
1139 0xc78, 0x754b0001,
1140 0xc78, 0x744c0001,
1141 0xc78, 0x734d0001,
1142 0xc78, 0x724e0001,
1143 0xc78, 0x714f0001,
1144 0xc78, 0x70500001,
1145 0xc78, 0x6f510001,
1146 0xc78, 0x6e520001,
1147 0xc78, 0x6d530001,
1148 0xc78, 0x6c540001,
1149 0xc78, 0x6b550001,
1150 0xc78, 0x6a560001,
1151 0xc78, 0x69570001,
1152 0xc78, 0x68580001,
1153 0xc78, 0x67590001,
1154 0xc78, 0x665a0001,
1155 0xc78, 0x655b0001,
1156 0xc78, 0x645c0001,
1157 0xc78, 0x635d0001,
1158 0xc78, 0x625e0001,
1159 0xc78, 0x615f0001,
1160 0xc78, 0x60600001,
1161 0xc78, 0x49610001,
1162 0xc78, 0x48620001,
1163 0xc78, 0x47630001,
1164 0xc78, 0x46640001,
1165 0xc78, 0x45650001,
1166 0xc78, 0x44660001,
1167 0xc78, 0x43670001,
1168 0xc78, 0x42680001,
1169 0xc78, 0x41690001,
1170 0xc78, 0x406a0001,
1171 0xc78, 0x266b0001,
1172 0xc78, 0x256c0001,
1173 0xc78, 0x246d0001,
1174 0xc78, 0x236e0001,
1175 0xc78, 0x226f0001,
1176 0xc78, 0x21700001,
1177 0xc78, 0x20710001,
1178 0xc78, 0x06720001,
1179 0xc78, 0x05730001,
1180 0xc78, 0x04740001,
1181 0xc78, 0x03750001,
1182 0xc78, 0x02760001,
1183 0xc78, 0x01770001,
1184 0xc78, 0x00780001,
1185 0xc78, 0x00790001,
1186 0xc78, 0x007a0001,
1187 0xc78, 0x007b0001,
1188 0xc78, 0x007c0001,
1189 0xc78, 0x007d0001,
1190 0xc78, 0x007e0001,
1191 0xc78, 0x007f0001,
1192 0xc78, 0x3800001e,
1193 0xc78, 0x3801001e,
1194 0xc78, 0x3802001e,
1195 0xc78, 0x3803001e,
1196 0xc78, 0x3804001e,
1197 0xc78, 0x3805001e,
1198 0xc78, 0x3806001e,
1199 0xc78, 0x3807001e,
1200 0xc78, 0x3808001e,
1201 0xc78, 0x3c09001e,
1202 0xc78, 0x3e0a001e,
1203 0xc78, 0x400b001e,
1204 0xc78, 0x440c001e,
1205 0xc78, 0x480d001e,
1206 0xc78, 0x4c0e001e,
1207 0xc78, 0x500f001e,
1208 0xc78, 0x5210001e,
1209 0xc78, 0x5611001e,
1210 0xc78, 0x5a12001e,
1211 0xc78, 0x5e13001e,
1212 0xc78, 0x6014001e,
1213 0xc78, 0x6015001e,
1214 0xc78, 0x6016001e,
1215 0xc78, 0x6217001e,
1216 0xc78, 0x6218001e,
1217 0xc78, 0x6219001e,
1218 0xc78, 0x621a001e,
1219 0xc78, 0x621b001e,
1220 0xc78, 0x621c001e,
1221 0xc78, 0x621d001e,
1222 0xc78, 0x621e001e,
1223 0xc78, 0x621f001e,
1224};
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h
new file mode 100644
index 00000000000..3a6e8b6aeee
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-table.h
@@ -0,0 +1,58 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Created on 2010/ 5/18, 1:41
27 *
28 * Larry Finger <Larry.Finger@lwfinger.net>
29 *
30 *****************************************************************************/
31
32#ifndef __RTL92CE_TABLE__H_
33#define __RTL92CE_TABLE__H_
34
35#include <linux/types.h>
36
37#define PHY_REG_2TARRAY_LENGTH 374
38extern u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH];
39#define PHY_REG_1TARRAY_LENGTH 374
40extern u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH];
41#define PHY_REG_ARRAY_PGLENGTH 192
42extern u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH];
43#define RADIOA_2TARRAYLENGTH 282
44extern u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH];
45#define RADIOB_2TARRAYLENGTH 78
46extern u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH];
47#define RADIOA_1TARRAYLENGTH 282
48extern u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH];
49#define RADIOB_1TARRAYLENGTH 1
50extern u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH];
51#define MAC_2T_ARRAYLENGTH 162
52extern u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH];
53#define AGCTAB_2TARRAYLENGTH 320
54extern u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH];
55#define AGCTAB_1TARRAYLENGTH 320
56extern u32 RTL8192CEAGCTAB_1TARRAY[AGCTAB_1TARRAYLENGTH];
57
58#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c
new file mode 100644
index 00000000000..cf35418c8af
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.c
@@ -0,0 +1,1031 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "../base.h"
33#include "rtl8192c-reg.h"
34#include "rtl8192c-def.h"
35#include "rtl8192c-phy.h"
36#include "rtl8192c-trx.h"
37#include "rtl8192c-led.h"
38
39static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(u16 fc,
40 unsigned int
41 skb_queue)
42{
43 enum rtl_desc_qsel qsel;
44
45 if (unlikely(ieee80211_is_beacon(fc))) {
46 qsel = QSLT_BEACON;
47 return qsel;
48 }
49
50 if (ieee80211_is_mgmt(fc)) {
51 qsel = QSLT_MGNT;
52 return qsel;
53 }
54
55 switch (skb_queue) {
56 case VO_QUEUE:
57 qsel = QSLT_VO;
58 break;
59 case VI_QUEUE:
60 qsel = QSLT_VI;
61 break;
62 case BE_QUEUE:
63 qsel = QSLT_BE;
64 break;
65 case BK_QUEUE:
66 qsel = QSLT_BK;
67 break;
68 default:
69 qsel = QSLT_BE;
70 RT_ASSERT(false, ("BE queue, skb_queue:%d,"
71 " set qsel = 0x%X\n", skb_queue, QSLT_BE));
72 break;
73 }
74 return qsel;
75}
76
77static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
78{
79 int rate_idx;
80
81 if (first_ampdu) {
82 if (false == isht) {
83 switch (desc_rate) {
84 case DESC92C_RATE1M:
85 rate_idx = 0;
86 break;
87 case DESC92C_RATE2M:
88 rate_idx = 1;
89 break;
90 case DESC92C_RATE5_5M:
91 rate_idx = 2;
92 break;
93 case DESC92C_RATE11M:
94 rate_idx = 3;
95 break;
96 case DESC92C_RATE6M:
97 rate_idx = 4;
98 break;
99 case DESC92C_RATE9M:
100 rate_idx = 5;
101 break;
102 case DESC92C_RATE12M:
103 rate_idx = 6;
104 break;
105 case DESC92C_RATE18M:
106 rate_idx = 7;
107 break;
108 case DESC92C_RATE24M:
109 rate_idx = 8;
110 break;
111 case DESC92C_RATE36M:
112 rate_idx = 9;
113 break;
114 case DESC92C_RATE48M:
115 rate_idx = 10;
116 break;
117 case DESC92C_RATE54M:
118 rate_idx = 11;
119 break;
120 default:
121 rate_idx = 0;
122 break;
123 }
124 } else {
125 rate_idx = 11;
126 }
127
128 return rate_idx;
129 }
130
131 switch (desc_rate) {
132 case DESC92C_RATE1M:
133 rate_idx = 0;
134 break;
135 case DESC92C_RATE2M:
136 rate_idx = 1;
137 break;
138 case DESC92C_RATE5_5M:
139 rate_idx = 2;
140 break;
141 case DESC92C_RATE11M:
142 rate_idx = 3;
143 break;
144 case DESC92C_RATE6M:
145 rate_idx = 4;
146 break;
147 case DESC92C_RATE9M:
148 rate_idx = 5;
149 break;
150 case DESC92C_RATE12M:
151 rate_idx = 6;
152 break;
153 case DESC92C_RATE18M:
154 rate_idx = 7;
155 break;
156 case DESC92C_RATE24M:
157 rate_idx = 8;
158 break;
159 case DESC92C_RATE36M:
160 rate_idx = 9;
161 break;
162 case DESC92C_RATE48M:
163 rate_idx = 10;
164 break;
165 case DESC92C_RATE54M:
166 rate_idx = 11;
167 break;
168 default:
169 rate_idx = 11;
170 break;
171 }
172 return rate_idx;
173}
174
175static u8 _rtl92c_query_rxpwrpercentage(char antpower)
176{
177 if ((antpower <= -100) || (antpower >= 20))
178 return 0;
179 else if (antpower >= 0)
180 return 100;
181 else
182 return 100 + antpower;
183}
184
185static u8 _rtl92c_evm_db_to_percentage(char value)
186{
187 char ret_val;
188 ret_val = value;
189
190 if (ret_val >= 0)
191 ret_val = 0;
192
193 if (ret_val <= -33)
194 ret_val = -33;
195
196 ret_val = 0 - ret_val;
197 ret_val *= 3;
198
199 if (ret_val == 99)
200 ret_val = 100;
201
202 return ret_val;
203}
204
205static long _rtl92ce_translate_todbm(struct ieee80211_hw *hw,
206 u8 signal_strength_index)
207{
208 long signal_power;
209
210 signal_power = (long)((signal_strength_index + 1) >> 1);
211 signal_power -= 95;
212 return signal_power;
213}
214
215static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw,
216 long currsig)
217{
218 long retsig;
219
220 if (currsig >= 61 && currsig <= 100)
221 retsig = 90 + ((currsig - 60) / 4);
222 else if (currsig >= 41 && currsig <= 60)
223 retsig = 78 + ((currsig - 40) / 2);
224 else if (currsig >= 31 && currsig <= 40)
225 retsig = 66 + (currsig - 30);
226 else if (currsig >= 21 && currsig <= 30)
227 retsig = 54 + (currsig - 20);
228 else if (currsig >= 5 && currsig <= 20)
229 retsig = 42 + (((currsig - 5) * 2) / 3);
230 else if (currsig == 4)
231 retsig = 36;
232 else if (currsig == 3)
233 retsig = 27;
234 else if (currsig == 2)
235 retsig = 18;
236 else if (currsig == 1)
237 retsig = 9;
238 else
239 retsig = currsig;
240
241 return retsig;
242}
243
244static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
245 struct rtl_stats *pstats,
246 struct rx_desc_92c *pdesc,
247 struct rx_fwinfo_92c *p_drvinfo,
248 bool bpacket_match_bssid,
249 bool bpacket_toself,
250 bool b_packet_beacon)
251{
252 struct rtl_priv *rtlpriv = rtl_priv(hw);
253 struct phy_sts_cck_8192s_t *cck_buf;
254 s8 rx_pwr_all, rx_pwr[4];
255 u8 rf_rx_num, evm, pwdb_all;
256 u8 i, max_spatial_stream;
257 u32 rssi, total_rssi;
258 bool is_cck_rate;
259
260 is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
261 pstats->b_packet_matchbssid = bpacket_match_bssid;
262 pstats->b_packet_toself = bpacket_toself;
263 pstats->b_is_cck = is_cck_rate;
264 pstats->b_packet_beacon = b_packet_beacon;
265 pstats->b_is_cck = is_cck_rate;
266 pstats->rx_mimo_signalquality[0] = -1;
267 pstats->rx_mimo_signalquality[1] = -1;
268
269 if (is_cck_rate) {
270 u8 report, cck_highpwr;
271 cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
272
273 cck_highpwr = (u8) rtl_get_bbreg(hw,
274 RFPGA0_XA_HSSIPARAMETER2,
275 BIT(9));
276 if (!cck_highpwr) {
277 u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
278 report = cck_buf->cck_agc_rpt & 0xc0;
279 report = report >> 6;
280 switch (report) {
281 case 0x3:
282 rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
283 break;
284 case 0x2:
285 rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
286 break;
287 case 0x1:
288 rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
289 break;
290 case 0x0:
291 rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
292 break;
293 }
294 } else {
295 u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
296 report = p_drvinfo->cfosho[0] & 0x60;
297 report = report >> 5;
298 switch (report) {
299 case 0x3:
300 rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
301 break;
302 case 0x2:
303 rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
304 break;
305 case 0x1:
306 rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
307 break;
308 case 0x0:
309 rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
310 break;
311 }
312 }
313
314 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
315 pstats->rx_pwdb_all = pwdb_all;
316 pstats->recvsignalpower = rx_pwr_all;
317
318 if (bpacket_match_bssid) {
319 u8 sq;
320 if (pstats->rx_pwdb_all > 40)
321 sq = 100;
322 else {
323 sq = cck_buf->sq_rpt;
324 if (sq > 64)
325 sq = 0;
326 else if (sq < 20)
327 sq = 100;
328 else
329 sq = ((64 - sq) * 100) / 44;
330 }
331
332 pstats->signalquality = sq;
333 pstats->rx_mimo_signalquality[0] = sq;
334 pstats->rx_mimo_signalquality[1] = -1;
335 }
336 } else {
337 rtlpriv->dm.brfpath_rxenable[0] =
338 rtlpriv->dm.brfpath_rxenable[1] = true;
339 for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
340 if (rtlpriv->dm.brfpath_rxenable[i])
341 rf_rx_num++;
342
343 rx_pwr[i] =
344 ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
345 rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
346 total_rssi += rssi;
347 rtlpriv->stats.rx_snr_db[i] =
348 (long)(p_drvinfo->rxsnr[i] / 2);
349
350 if (bpacket_match_bssid)
351 pstats->rx_mimo_signalstrength[i] = (u8) rssi;
352 }
353
354 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
355 pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
356 pstats->rx_pwdb_all = pwdb_all;
357 pstats->rxpower = rx_pwr_all;
358 pstats->recvsignalpower = rx_pwr_all;
359
360 if (pdesc->rxht && pdesc->rxmcs >= DESC92C_RATEMCS8 &&
361 pdesc->rxmcs <= DESC92C_RATEMCS15)
362 max_spatial_stream = 2;
363 else
364 max_spatial_stream = 1;
365
366 for (i = 0; i < max_spatial_stream; i++) {
367 evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
368
369 if (bpacket_match_bssid) {
370 if (i == 0)
371 pstats->signalquality =
372 (u8) (evm & 0xff);
373 pstats->rx_mimo_signalquality[i] =
374 (u8) (evm & 0xff);
375 }
376 }
377 }
378
379 if (is_cck_rate)
380 pstats->signalstrength =
381 (u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all));
382 else if (rf_rx_num != 0)
383 pstats->signalstrength =
384 (u8) (_rtl92ce_signal_scale_mapping
385 (hw, total_rssi /= rf_rx_num));
386}
387
388static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,
389 struct rtl_stats *pstats)
390{
391 struct rtl_priv *rtlpriv = rtl_priv(hw);
392 struct rtl_phy *rtlphy = &(rtlpriv->phy);
393 u8 rfpath;
394 u32 last_rssi, tmpval;
395
396 if (pstats->b_packet_toself || pstats->b_packet_beacon) {
397 rtlpriv->stats.rssi_calculate_cnt++;
398
399 if (rtlpriv->stats.ui_rssi.total_num++ >=
400 PHY_RSSI_SLID_WIN_MAX) {
401 rtlpriv->stats.ui_rssi.total_num =
402 PHY_RSSI_SLID_WIN_MAX;
403 last_rssi =
404 rtlpriv->stats.ui_rssi.elements[rtlpriv->
405 stats.ui_rssi.index];
406 rtlpriv->stats.ui_rssi.total_val -= last_rssi;
407 }
408
409 rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
410 rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.
411 index++] =
412 pstats->signalstrength;
413
414 if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
415 rtlpriv->stats.ui_rssi.index = 0;
416
417 tmpval = rtlpriv->stats.ui_rssi.total_val /
418 rtlpriv->stats.ui_rssi.total_num;
419 rtlpriv->stats.signal_strength =
420 _rtl92ce_translate_todbm(hw, (u8) tmpval);
421 pstats->rssi = rtlpriv->stats.signal_strength;
422 }
423
424 if (!pstats->b_is_cck && pstats->b_packet_toself) {
425 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
426 rfpath++) {
427
428 if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath))
429 continue;
430
431 if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
432 rtlpriv->stats.rx_rssi_percentage[rfpath] =
433 pstats->rx_mimo_signalstrength[rfpath];
434
435 }
436
437 if (pstats->rx_mimo_signalstrength[rfpath] >
438 rtlpriv->stats.rx_rssi_percentage[rfpath]) {
439 rtlpriv->stats.rx_rssi_percentage[rfpath] =
440 ((rtlpriv->stats.
441 rx_rssi_percentage[rfpath] *
442 (RX_SMOOTH_FACTOR - 1)) +
443 (pstats->rx_mimo_signalstrength[rfpath])) /
444 (RX_SMOOTH_FACTOR);
445
446 rtlpriv->stats.rx_rssi_percentage[rfpath] =
447 rtlpriv->stats.rx_rssi_percentage[rfpath] +
448 1;
449 } else {
450 rtlpriv->stats.rx_rssi_percentage[rfpath] =
451 ((rtlpriv->stats.
452 rx_rssi_percentage[rfpath] *
453 (RX_SMOOTH_FACTOR - 1)) +
454 (pstats->rx_mimo_signalstrength[rfpath])) /
455 (RX_SMOOTH_FACTOR);
456 }
457
458 }
459 }
460}
461
462static void _rtl92ce_update_rxsignalstatistics(struct ieee80211_hw *hw,
463 struct rtl_stats *pstats)
464{
465 struct rtl_priv *rtlpriv = rtl_priv(hw);
466 int weighting;
467
468 if (rtlpriv->stats.recv_signal_power == 0)
469 rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
470
471 if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
472 weighting = 5;
473
474 else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
475 weighting = (-5);
476
477 rtlpriv->stats.recv_signal_power =
478 (rtlpriv->stats.recv_signal_power * 5 +
479 pstats->recvsignalpower + weighting) / 6;
480}
481
482static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw,
483 struct rtl_stats *pstats)
484{
485 struct rtl_priv *rtlpriv = rtl_priv(hw);
486 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
487 long undecorated_smoothed_pwdb;
488
489 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
490 return;
491 } else {
492 undecorated_smoothed_pwdb =
493 rtlpriv->dm.undecorated_smoothed_pwdb;
494 }
495
496 if (pstats->b_packet_toself || pstats->b_packet_beacon) {
497 if (undecorated_smoothed_pwdb < 0)
498 undecorated_smoothed_pwdb = pstats->rx_pwdb_all;
499
500 if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) {
501 undecorated_smoothed_pwdb =
502 (((undecorated_smoothed_pwdb) *
503 (RX_SMOOTH_FACTOR - 1)) +
504 (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
505
506 undecorated_smoothed_pwdb = undecorated_smoothed_pwdb
507 + 1;
508 } else {
509 undecorated_smoothed_pwdb =
510 (((undecorated_smoothed_pwdb) *
511 (RX_SMOOTH_FACTOR - 1)) +
512 (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
513 }
514
515 rtlpriv->dm.undecorated_smoothed_pwdb =
516 undecorated_smoothed_pwdb;
517 _rtl92ce_update_rxsignalstatistics(hw, pstats);
518 }
519}
520
521static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw,
522 struct rtl_stats *pstats)
523{
524 struct rtl_priv *rtlpriv = rtl_priv(hw);
525 u32 last_evm, n_spatialstream, tmpval;
526
527 if (pstats->signalquality != 0) {
528 if (pstats->b_packet_toself || pstats->b_packet_beacon) {
529
530 if (rtlpriv->stats.ui_link_quality.total_num++ >=
531 PHY_LINKQUALITY_SLID_WIN_MAX) {
532 rtlpriv->stats.ui_link_quality.total_num =
533 PHY_LINKQUALITY_SLID_WIN_MAX;
534 last_evm =
535 rtlpriv->stats.
536 ui_link_quality.elements[rtlpriv->
537 stats.ui_link_quality.
538 index];
539 rtlpriv->stats.ui_link_quality.total_val -=
540 last_evm;
541 }
542
543 rtlpriv->stats.ui_link_quality.total_val +=
544 pstats->signalquality;
545 rtlpriv->stats.ui_link_quality.elements[rtlpriv->stats.
546 ui_link_quality.
547 index++] =
548 pstats->signalquality;
549
550 if (rtlpriv->stats.ui_link_quality.index >=
551 PHY_LINKQUALITY_SLID_WIN_MAX)
552 rtlpriv->stats.ui_link_quality.index = 0;
553
554 tmpval = rtlpriv->stats.ui_link_quality.total_val /
555 rtlpriv->stats.ui_link_quality.total_num;
556 rtlpriv->stats.signal_quality = tmpval;
557
558 rtlpriv->stats.last_sigstrength_inpercent = tmpval;
559
560 for (n_spatialstream = 0; n_spatialstream < 2;
561 n_spatialstream++) {
562 if (pstats->
563 rx_mimo_signalquality[n_spatialstream] !=
564 -1) {
565 if (rtlpriv->stats.
566 rx_evm_percentage[n_spatialstream]
567 == 0) {
568 rtlpriv->stats.
569 rx_evm_percentage
570 [n_spatialstream] =
571 pstats->rx_mimo_signalquality
572 [n_spatialstream];
573 }
574
575 rtlpriv->stats.
576 rx_evm_percentage[n_spatialstream] =
577 ((rtlpriv->
578 stats.rx_evm_percentage
579 [n_spatialstream] *
580 (RX_SMOOTH_FACTOR - 1)) +
581 (pstats->
582 rx_mimo_signalquality
583 [n_spatialstream] * 1)) /
584 (RX_SMOOTH_FACTOR);
585 }
586 }
587 }
588 } else {
589 ;
590 }
591}
592
593static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw,
594 u8 *buffer,
595 struct rtl_stats *pcurrent_stats)
596{
597
598 if (!pcurrent_stats->b_packet_matchbssid &&
599 !pcurrent_stats->b_packet_beacon)
600 return;
601
602 _rtl92ce_process_ui_rssi(hw, pcurrent_stats);
603 _rtl92ce_process_pwdb(hw, pcurrent_stats);
604 _rtl92ce_process_ui_link_quality(hw, pcurrent_stats);
605}
606
607static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
608 struct sk_buff *skb,
609 struct rtl_stats *pstats,
610 struct rx_desc_92c *pdesc,
611 struct rx_fwinfo_92c *p_drvinfo)
612{
613 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
614 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
615
616 struct ieee80211_hdr *hdr;
617 u8 *tmp_buf;
618 u8 *praddr;
619 u8 *psaddr;
620 u16 fc, type;
621 bool b_packet_matchbssid, b_packet_toself, b_packet_beacon;
622
623 tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
624
625 hdr = (struct ieee80211_hdr *)tmp_buf;
626 fc = le16_to_cpu(hdr->frame_control);
627 type = WLAN_FC_GET_TYPE(fc);
628 praddr = hdr->addr1;
629 psaddr = hdr->addr2;
630
631 b_packet_matchbssid =
632 ((IEEE80211_FTYPE_CTL != type) &&
633 (!compare_ether_addr(mac->bssid,
634 (fc & IEEE80211_FCTL_TODS) ?
635 hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ?
636 hdr->addr2 : hdr->addr3)) &&
637 (!pstats->b_hwerror) && (!pstats->b_crc) && (!pstats->b_icv));
638
639 b_packet_toself = b_packet_matchbssid &&
640 (!compare_ether_addr(praddr, rtlefuse->dev_addr));
641
642 if (ieee80211_is_beacon(fc))
643 b_packet_beacon = true;
644
645 _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
646 b_packet_matchbssid, b_packet_toself,
647 b_packet_beacon);
648
649 _rtl92ce_process_phyinfo(hw, tmp_buf, pstats);
650}
651
652bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
653 struct rtl_stats *stats,
654 struct ieee80211_rx_status *rx_status,
655 u8 *p_desc, struct sk_buff *skb)
656{
657 struct rx_fwinfo_92c *p_drvinfo;
658 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
659
660 u32 phystatus = GET_RX_DESC_PHYST(pdesc);
661 stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
662 stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
663 RX_DRV_INFO_SIZE_UNIT;
664 stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
665 stats->b_icv = (u16) GET_RX_DESC_ICV(pdesc);
666 stats->b_crc = (u16) GET_RX_DESC_CRC32(pdesc);
667 stats->b_hwerror = (stats->b_crc | stats->b_icv);
668 stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
669 stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
670 stats->b_shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
671 stats->b_isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
672 stats->b_isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
673 && (GET_RX_DESC_FAGGR(pdesc) == 1));
674 stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
675 stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
676
677 rx_status->freq = hw->conf.channel->center_freq;
678 rx_status->band = hw->conf.channel->band;
679
680 if (GET_RX_DESC_CRC32(pdesc))
681 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
682
683 if (!GET_RX_DESC_SWDEC(pdesc))
684 rx_status->flag |= RX_FLAG_DECRYPTED;
685
686 if (GET_RX_DESC_BW(pdesc))
687 rx_status->flag |= RX_FLAG_40MHZ;
688
689 if (GET_RX_DESC_RXHT(pdesc))
690 rx_status->flag |= RX_FLAG_HT;
691
692 rx_status->flag |= RX_FLAG_TSFT;
693
694 if (stats->decrypted)
695 rx_status->flag |= RX_FLAG_DECRYPTED;
696
697 rx_status->rate_idx = _rtl92ce_rate_mapping((bool)
698 GET_RX_DESC_RXHT(pdesc),
699 (u8)
700 GET_RX_DESC_RXMCS(pdesc),
701 (bool)
702 GET_RX_DESC_PAGGR(pdesc));
703
704 rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
705 if (phystatus == true) {
706 p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
707 stats->rx_bufshift);
708
709 _rtl92ce_translate_rx_signal_stuff(hw,
710 skb, stats, pdesc,
711 p_drvinfo);
712 }
713
714 /*rx_status->qual = stats->signal; */
715 rx_status->signal = stats->rssi + 10;
716 /*rx_status->noise = -stats->noise; */
717
718 return true;
719}
720
721void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
722 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
723 struct ieee80211_tx_info *info, struct sk_buff *skb,
724 unsigned int queue_index)
725{
726 struct rtl_priv *rtlpriv = rtl_priv(hw);
727 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
728 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
729 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
730 bool b_defaultadapter = true;
731
732 struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid);
733
734 u8 *pdesc = (u8 *) pdesc_tx;
735 struct rtl_tcb_desc tcb_desc;
736 u8 *qc = ieee80211_get_qos_ctl(hdr);
737 u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
738 u16 seq_number;
739 u16 fc = le16_to_cpu(hdr->frame_control);
740 u8 rate_flag = info->control.rates[0].flags;
741
742 enum rtl_desc_qsel fw_qsel =
743 _rtl92ce_map_hwqueue_to_fwqueue(le16_to_cpu(hdr->frame_control),
744 queue_index);
745
746 bool b_firstseg = ((hdr->seq_ctrl &
747 cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
748
749 bool b_lastseg = ((hdr->frame_control &
750 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
751
752 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
753 skb->data, skb->len,
754 PCI_DMA_TODEVICE);
755
756 seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
757
758 rtl_get_tcb_desc(hw, info, skb, &tcb_desc);
759
760 CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
761
762 if (b_firstseg) {
763 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
764
765 SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate);
766
767 if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble)
768 SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
769
770 if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
771 info->flags & IEEE80211_TX_CTL_AMPDU) {
772 SET_TX_DESC_AGG_BREAK(pdesc, 1);
773 SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
774 }
775 SET_TX_DESC_SEQ(pdesc, seq_number);
776
777 SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.b_rts_enable &&
778 !tcb_desc.
779 b_cts_enable) ? 1 : 0));
780 SET_TX_DESC_HW_RTS_ENABLE(pdesc,
781 ((tcb_desc.b_rts_enable
782 || tcb_desc.b_cts_enable) ? 1 : 0));
783 SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.b_cts_enable) ? 1 : 0));
784 SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.b_rts_stbc) ? 1 : 0));
785
786 SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate);
787 SET_TX_DESC_RTS_BW(pdesc, 0);
788 SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc);
789 SET_TX_DESC_RTS_SHORT(pdesc,
790 ((tcb_desc.rts_rate <= DESC92C_RATE54M) ?
791 (tcb_desc.b_rts_use_shortpreamble ? 1 : 0)
792 : (tcb_desc.b_rts_use_shortgi ? 1 : 0)));
793
794 if (mac->bw_40) {
795 if (tcb_desc.b_packet_bw) {
796 SET_TX_DESC_DATA_BW(pdesc, 1);
797 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
798 } else {
799 SET_TX_DESC_DATA_BW(pdesc, 0);
800
801 if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
802 SET_TX_DESC_TX_SUB_CARRIER(pdesc,
803 mac->cur_40_prime_sc);
804 }
805 }
806 } else {
807 SET_TX_DESC_DATA_BW(pdesc, 0);
808 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
809 }
810
811 SET_TX_DESC_LINIP(pdesc, 0);
812 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
813
814 if (sta) {
815 u8 ampdu_density = sta->ht_cap.ampdu_density;
816 SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
817 }
818
819 if (info->control.hw_key) {
820 struct ieee80211_key_conf *keyconf =
821 info->control.hw_key;
822
823 switch (keyconf->cipher) {
824 case WLAN_CIPHER_SUITE_WEP40:
825 case WLAN_CIPHER_SUITE_WEP104:
826 case WLAN_CIPHER_SUITE_TKIP:
827 SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
828 break;
829 case WLAN_CIPHER_SUITE_CCMP:
830 SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
831 break;
832 default:
833 SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
834 break;
835
836 }
837 }
838
839 SET_TX_DESC_PKT_ID(pdesc, 0);
840 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
841
842 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
843 SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
844 SET_TX_DESC_DISABLE_FB(pdesc, 0);
845 SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0);
846
847 if (ieee80211_is_data_qos(fc)) {
848 if (mac->rdg_en) {
849 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
850 ("Enable RDG function.\n"));
851 SET_TX_DESC_RDG_ENABLE(pdesc, 1);
852 SET_TX_DESC_HTC(pdesc, 1);
853 }
854 }
855 }
856
857 SET_TX_DESC_FIRST_SEG(pdesc, (b_firstseg ? 1 : 0));
858 SET_TX_DESC_LAST_SEG(pdesc, (b_lastseg ? 1 : 0));
859
860 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
861
862 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
863
864 if (rtlpriv->dm.b_useramask) {
865 SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index);
866 SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id);
867 } else {
868 SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index);
869 SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index);
870 }
871
872 if ((!ieee80211_is_data_qos(fc)) && ppsc->b_leisure_ps &&
873 ppsc->b_fwctrl_lps) {
874 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
875 SET_TX_DESC_PKT_ID(pdesc, 8);
876
877 if (!b_defaultadapter)
878 SET_TX_DESC_QOS(pdesc, 1);
879 }
880
881 SET_TX_DESC_MORE_FRAG(pdesc, (b_lastseg ? 0 : 1));
882
883 if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
884 is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
885 SET_TX_DESC_BMC(pdesc, 1);
886 }
887
888 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
889}
890
891void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
892 u8 *pdesc, bool b_firstseg,
893 bool b_lastseg, struct sk_buff *skb)
894{
895 struct rtl_priv *rtlpriv = rtl_priv(hw);
896 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
897 u8 fw_queue = QSLT_BEACON;
898
899 dma_addr_t mapping = pci_map_single(rtlpci->pdev,
900 skb->data, skb->len,
901 PCI_DMA_TODEVICE);
902
903 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
904 u16 fc = le16_to_cpu(hdr->frame_control);
905
906 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
907
908 if (b_firstseg)
909 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
910
911 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
912
913 SET_TX_DESC_SEQ(pdesc, 0);
914
915 SET_TX_DESC_LINIP(pdesc, 0);
916
917 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
918
919 SET_TX_DESC_FIRST_SEG(pdesc, 1);
920 SET_TX_DESC_LAST_SEG(pdesc, 1);
921
922 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
923
924 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
925
926 SET_TX_DESC_RATE_ID(pdesc, 7);
927 SET_TX_DESC_MACID(pdesc, 0);
928
929 SET_TX_DESC_OWN(pdesc, 1);
930
931 SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
932
933 SET_TX_DESC_FIRST_SEG(pdesc, 1);
934 SET_TX_DESC_LAST_SEG(pdesc, 1);
935
936 SET_TX_DESC_OFFSET(pdesc, 0x20);
937
938 SET_TX_DESC_USE_RATE(pdesc, 1);
939
940 if (!ieee80211_is_data_qos(fc)) {
941 SET_TX_DESC_HWSEQ_EN(pdesc, 1);
942 SET_TX_DESC_PKT_ID(pdesc, 8);
943 }
944
945 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
946 "H2C Tx Cmd Content\n",
947 pdesc, TX_DESC_SIZE);
948}
949
950void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
951{
952 if (istx == true) {
953 switch (desc_name) {
954 case HW_DESC_OWN:
955 SET_TX_DESC_OWN(pdesc, 1);
956 break;
957 case HW_DESC_TX_NEXTDESC_ADDR:
958 SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
959 break;
960 default:
961 RT_ASSERT(false, ("ERR txdesc :%d"
962 " not process\n", desc_name));
963 break;
964 }
965 } else {
966 switch (desc_name) {
967 case HW_DESC_RXOWN:
968 SET_RX_DESC_OWN(pdesc, 1);
969 break;
970 case HW_DESC_RXBUFF_ADDR:
971 SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
972 break;
973 case HW_DESC_RXPKT_LEN:
974 SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
975 break;
976 case HW_DESC_RXERO:
977 SET_RX_DESC_EOR(pdesc, 1);
978 break;
979 default:
980 RT_ASSERT(false, ("ERR rxdesc :%d "
981 "not process\n", desc_name));
982 break;
983 }
984 }
985}
986
987u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
988{
989 u32 ret = 0;
990
991 if (istx == true) {
992 switch (desc_name) {
993 case HW_DESC_OWN:
994 ret = GET_TX_DESC_OWN(p_desc);
995 break;
996 case HW_DESC_TXBUFF_ADDR:
997 ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
998 break;
999 default:
1000 RT_ASSERT(false, ("ERR txdesc :%d "
1001 "not process\n", desc_name));
1002 break;
1003 }
1004 } else {
1005 struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
1006 switch (desc_name) {
1007 case HW_DESC_OWN:
1008 ret = GET_RX_DESC_OWN(pdesc);
1009 break;
1010 case HW_DESC_RXPKT_LEN:
1011 ret = GET_RX_DESC_PKT_LEN(pdesc);
1012 break;
1013 default:
1014 RT_ASSERT(false, ("ERR rxdesc :%d "
1015 "not process\n", desc_name));
1016 break;
1017 }
1018 }
1019 return ret;
1020}
1021
1022void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue)
1023{
1024 struct rtl_priv *rtlpriv = rtl_priv(hw);
1025 if (hw_queue == BEACON_QUEUE) {
1026 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
1027 } else {
1028 rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
1029 BIT(0) << (hw_queue));
1030 }
1031}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h
new file mode 100644
index 00000000000..91e13c33351
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192c-trx.h
@@ -0,0 +1,714 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL92CE_TRX_H__
31#define __RTL92CE_TRX_H__
32
33#define TX_DESC_SIZE 64
34#define TX_DESC_AGGR_SUBFRAME_SIZE 32
35
36#define RX_DESC_SIZE 32
37#define RX_DRV_INFO_SIZE_UNIT 8
38
39#define TX_DESC_NEXT_DESC_OFFSET 40
40#define USB_HWDESC_HEADER_LEN 32
41#define CRCLENGTH 4
42
43#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
44 SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val)
45#define SET_TX_DESC_OFFSET(__pdesc, __val) \
46 SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val)
47#define SET_TX_DESC_BMC(__pdesc, __val) \
48 SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val)
49#define SET_TX_DESC_HTC(__pdesc, __val) \
50 SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val)
51#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
52 SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val)
53#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
54 SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val)
55#define SET_TX_DESC_LINIP(__pdesc, __val) \
56 SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val)
57#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
58 SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val)
59#define SET_TX_DESC_GF(__pdesc, __val) \
60 SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
61#define SET_TX_DESC_OWN(__pdesc, __val) \
62 SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
63
64#define GET_TX_DESC_PKT_SIZE(__pdesc) \
65 LE_BITS_TO_4BYTE(__pdesc, 0, 16)
66#define GET_TX_DESC_OFFSET(__pdesc) \
67 LE_BITS_TO_4BYTE(__pdesc, 16, 8)
68#define GET_TX_DESC_BMC(__pdesc) \
69 LE_BITS_TO_4BYTE(__pdesc, 24, 1)
70#define GET_TX_DESC_HTC(__pdesc) \
71 LE_BITS_TO_4BYTE(__pdesc, 25, 1)
72#define GET_TX_DESC_LAST_SEG(__pdesc) \
73 LE_BITS_TO_4BYTE(__pdesc, 26, 1)
74#define GET_TX_DESC_FIRST_SEG(__pdesc) \
75 LE_BITS_TO_4BYTE(__pdesc, 27, 1)
76#define GET_TX_DESC_LINIP(__pdesc) \
77 LE_BITS_TO_4BYTE(__pdesc, 28, 1)
78#define GET_TX_DESC_NO_ACM(__pdesc) \
79 LE_BITS_TO_4BYTE(__pdesc, 29, 1)
80#define GET_TX_DESC_GF(__pdesc) \
81 LE_BITS_TO_4BYTE(__pdesc, 30, 1)
82#define GET_TX_DESC_OWN(__pdesc) \
83 LE_BITS_TO_4BYTE(__pdesc, 31, 1)
84
85#define SET_TX_DESC_MACID(__pdesc, __val) \
86 SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val)
87#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
88 SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val)
89#define SET_TX_DESC_BK(__pdesc, __val) \
90 SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val)
91#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \
92 SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val)
93#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
94 SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val)
95#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \
96 SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val)
97#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \
98 SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val)
99#define SET_TX_DESC_PIFS(__pdesc, __val) \
100 SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val)
101#define SET_TX_DESC_RATE_ID(__pdesc, __val) \
102 SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val)
103#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \
104 SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val)
105#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
106 SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val)
107#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
108 SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val)
109#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
110 SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val)
111
112#define GET_TX_DESC_MACID(__pdesc) \
113 LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
114#define GET_TX_DESC_AGG_ENABLE(__pdesc) \
115 LE_BITS_TO_4BYTE(__pdesc+4, 5, 1)
116#define GET_TX_DESC_AGG_BREAK(__pdesc) \
117 LE_BITS_TO_4BYTE(__pdesc+4, 6, 1)
118#define GET_TX_DESC_RDG_ENABLE(__pdesc) \
119 LE_BITS_TO_4BYTE(__pdesc+4, 7, 1)
120#define GET_TX_DESC_QUEUE_SEL(__pdesc) \
121 LE_BITS_TO_4BYTE(__pdesc+4, 8, 5)
122#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \
123 LE_BITS_TO_4BYTE(__pdesc+4, 13, 1)
124#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \
125 LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
126#define GET_TX_DESC_PIFS(__pdesc) \
127 LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
128#define GET_TX_DESC_RATE_ID(__pdesc) \
129 LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
130#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \
131 LE_BITS_TO_4BYTE(__pdesc+4, 20, 1)
132#define GET_TX_DESC_EN_DESC_ID(__pdesc) \
133 LE_BITS_TO_4BYTE(__pdesc+4, 21, 1)
134#define GET_TX_DESC_SEC_TYPE(__pdesc) \
135 LE_BITS_TO_4BYTE(__pdesc+4, 22, 2)
136#define GET_TX_DESC_PKT_OFFSET(__pdesc) \
137 LE_BITS_TO_4BYTE(__pdesc+4, 24, 8)
138
139#define SET_TX_DESC_RTS_RC(__pdesc, __val) \
140 SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val)
141#define SET_TX_DESC_DATA_RC(__pdesc, __val) \
142 SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val)
143#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \
144 SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val)
145#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
146 SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val)
147#define SET_TX_DESC_RAW(__pdesc, __val) \
148 SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val)
149#define SET_TX_DESC_CCX(__pdesc, __val) \
150 SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val)
151#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \
152 SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val)
153#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
154 SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val)
155#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
156 SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val)
157#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \
158 SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val)
159#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \
160 SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val)
161#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \
162 SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val)
163
164#define GET_TX_DESC_RTS_RC(__pdesc) \
165 LE_BITS_TO_4BYTE(__pdesc+8, 0, 6)
166#define GET_TX_DESC_DATA_RC(__pdesc) \
167 LE_BITS_TO_4BYTE(__pdesc+8, 6, 6)
168#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \
169 LE_BITS_TO_4BYTE(__pdesc+8, 14, 2)
170#define GET_TX_DESC_MORE_FRAG(__pdesc) \
171 LE_BITS_TO_4BYTE(__pdesc+8, 17, 1)
172#define GET_TX_DESC_RAW(__pdesc) \
173 LE_BITS_TO_4BYTE(__pdesc+8, 18, 1)
174#define GET_TX_DESC_CCX(__pdesc) \
175 LE_BITS_TO_4BYTE(__pdesc+8, 19, 1)
176#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \
177 LE_BITS_TO_4BYTE(__pdesc+8, 20, 3)
178#define GET_TX_DESC_ANTSEL_A(__pdesc) \
179 LE_BITS_TO_4BYTE(__pdesc+8, 24, 1)
180#define GET_TX_DESC_ANTSEL_B(__pdesc) \
181 LE_BITS_TO_4BYTE(__pdesc+8, 25, 1)
182#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \
183 LE_BITS_TO_4BYTE(__pdesc+8, 26, 2)
184#define GET_TX_DESC_TX_ANTL(__pdesc) \
185 LE_BITS_TO_4BYTE(__pdesc+8, 28, 2)
186#define GET_TX_DESC_TX_ANT_HT(__pdesc) \
187 LE_BITS_TO_4BYTE(__pdesc+8, 30, 2)
188
189#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \
190 SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val)
191#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \
192 SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val)
193#define SET_TX_DESC_SEQ(__pdesc, __val) \
194 SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val)
195#define SET_TX_DESC_PKT_ID(__pdesc, __val) \
196 SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val)
197
198#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \
199 LE_BITS_TO_4BYTE(__pdesc+12, 0, 8)
200#define GET_TX_DESC_TAIL_PAGE(__pdesc) \
201 LE_BITS_TO_4BYTE(__pdesc+12, 8, 8)
202#define GET_TX_DESC_SEQ(__pdesc) \
203 LE_BITS_TO_4BYTE(__pdesc+12, 16, 12)
204#define GET_TX_DESC_PKT_ID(__pdesc) \
205 LE_BITS_TO_4BYTE(__pdesc+12, 28, 4)
206
207#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
208 SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val)
209#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \
210 SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val)
211#define SET_TX_DESC_QOS(__pdesc, __val) \
212 SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val)
213#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \
214 SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val)
215#define SET_TX_DESC_USE_RATE(__pdesc, __val) \
216 SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val)
217#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
218 SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val)
219#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
220 SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val)
221#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \
222 SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val)
223#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
224 SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val)
225#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \
226 SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val)
227#define SET_TX_DESC_PORT_ID(__pdesc, __val) \
228 SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val)
229#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \
230 SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val)
231#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \
232 SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val)
233#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
234 SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val)
235#define SET_TX_DESC_TX_STBC(__pdesc, __val) \
236 SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val)
237#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \
238 SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val)
239#define SET_TX_DESC_DATA_BW(__pdesc, __val) \
240 SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val)
241#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
242 SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val)
243#define SET_TX_DESC_RTS_BW(__pdesc, __val) \
244 SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val)
245#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
246 SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val)
247#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \
248 SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val)
249
250#define GET_TX_DESC_RTS_RATE(__pdesc) \
251 LE_BITS_TO_4BYTE(__pdesc+16, 0, 5)
252#define GET_TX_DESC_AP_DCFE(__pdesc) \
253 LE_BITS_TO_4BYTE(__pdesc+16, 5, 1)
254#define GET_TX_DESC_QOS(__pdesc) \
255 LE_BITS_TO_4BYTE(__pdesc+16, 6, 1)
256#define GET_TX_DESC_HWSEQ_EN(__pdesc) \
257 LE_BITS_TO_4BYTE(__pdesc+16, 7, 1)
258#define GET_TX_DESC_USE_RATE(__pdesc) \
259 LE_BITS_TO_4BYTE(__pdesc+16, 8, 1)
260#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \
261 LE_BITS_TO_4BYTE(__pdesc+16, 9, 1)
262#define GET_TX_DESC_DISABLE_FB(__pdesc) \
263 LE_BITS_TO_4BYTE(__pdesc+16, 10, 1)
264#define GET_TX_DESC_CTS2SELF(__pdesc) \
265 LE_BITS_TO_4BYTE(__pdesc+16, 11, 1)
266#define GET_TX_DESC_RTS_ENABLE(__pdesc) \
267 LE_BITS_TO_4BYTE(__pdesc+16, 12, 1)
268#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \
269 LE_BITS_TO_4BYTE(__pdesc+16, 13, 1)
270#define GET_TX_DESC_PORT_ID(__pdesc) \
271 LE_BITS_TO_4BYTE(__pdesc+16, 14, 1)
272#define GET_TX_DESC_WAIT_DCTS(__pdesc) \
273 LE_BITS_TO_4BYTE(__pdesc+16, 18, 1)
274#define GET_TX_DESC_CTS2AP_EN(__pdesc) \
275 LE_BITS_TO_4BYTE(__pdesc+16, 19, 1)
276#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \
277 LE_BITS_TO_4BYTE(__pdesc+16, 20, 2)
278#define GET_TX_DESC_TX_STBC(__pdesc) \
279 LE_BITS_TO_4BYTE(__pdesc+16, 22, 2)
280#define GET_TX_DESC_DATA_SHORT(__pdesc) \
281 LE_BITS_TO_4BYTE(__pdesc+16, 24, 1)
282#define GET_TX_DESC_DATA_BW(__pdesc) \
283 LE_BITS_TO_4BYTE(__pdesc+16, 25, 1)
284#define GET_TX_DESC_RTS_SHORT(__pdesc) \
285 LE_BITS_TO_4BYTE(__pdesc+16, 26, 1)
286#define GET_TX_DESC_RTS_BW(__pdesc) \
287 LE_BITS_TO_4BYTE(__pdesc+16, 27, 1)
288#define GET_TX_DESC_RTS_SC(__pdesc) \
289 LE_BITS_TO_4BYTE(__pdesc+16, 28, 2)
290#define GET_TX_DESC_RTS_STBC(__pdesc) \
291 LE_BITS_TO_4BYTE(__pdesc+16, 30, 2)
292
293#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
294 SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val)
295#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \
296 SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val)
297#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \
298 SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val)
299#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
300 SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val)
301#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
302 SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)
303#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
304 SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val)
305#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
306 SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val)
307#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \
308 SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val)
309
310#define GET_TX_DESC_TX_RATE(__pdesc) \
311 LE_BITS_TO_4BYTE(__pdesc+20, 0, 6)
312#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \
313 LE_BITS_TO_4BYTE(__pdesc+20, 6, 1)
314#define GET_TX_DESC_CCX_TAG(__pdesc) \
315 LE_BITS_TO_4BYTE(__pdesc+20, 7, 1)
316#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \
317 LE_BITS_TO_4BYTE(__pdesc+20, 8, 5)
318#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \
319 LE_BITS_TO_4BYTE(__pdesc+20, 13, 4)
320#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \
321 LE_BITS_TO_4BYTE(__pdesc+20, 17, 1)
322#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \
323 LE_BITS_TO_4BYTE(__pdesc+20, 18, 6)
324#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \
325 LE_BITS_TO_4BYTE(__pdesc+20, 24, 8)
326
327#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \
328 SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val)
329#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \
330 SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val)
331#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \
332 SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val)
333#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \
334 SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val)
335#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \
336 SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val)
337#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \
338 SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val)
339#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \
340 SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val)
341#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \
342 SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val)
343
344#define GET_TX_DESC_TXAGC_A(__pdesc) \
345 LE_BITS_TO_4BYTE(__pdesc+24, 0, 5)
346#define GET_TX_DESC_TXAGC_B(__pdesc) \
347 LE_BITS_TO_4BYTE(__pdesc+24, 5, 5)
348#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \
349 LE_BITS_TO_4BYTE(__pdesc+24, 10, 1)
350#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \
351 LE_BITS_TO_4BYTE(__pdesc+24, 11, 5)
352#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \
353 LE_BITS_TO_4BYTE(__pdesc+24, 16, 4)
354#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \
355 LE_BITS_TO_4BYTE(__pdesc+24, 20, 4)
356#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \
357 LE_BITS_TO_4BYTE(__pdesc+24, 24, 4)
358#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \
359 LE_BITS_TO_4BYTE(__pdesc+24, 28, 4)
360
361#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
362 SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
363#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \
364 SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val)
365#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \
366 SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val)
367#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \
368 SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val)
369#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \
370 SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val)
371
372#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \
373 LE_BITS_TO_4BYTE(__pdesc+28, 0, 16)
374#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \
375 LE_BITS_TO_4BYTE(__pdesc+28, 16, 4)
376#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \
377 LE_BITS_TO_4BYTE(__pdesc+28, 20, 4)
378#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \
379 LE_BITS_TO_4BYTE(__pdesc+28, 24, 4)
380#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \
381 LE_BITS_TO_4BYTE(__pdesc+28, 28, 4)
382
383#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
384 SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val)
385#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \
386 SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val)
387
388#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
389 LE_BITS_TO_4BYTE(__pdesc+32, 0, 32)
390#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \
391 LE_BITS_TO_4BYTE(__pdesc+36, 0, 32)
392
393#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
394 SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val)
395#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \
396 SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val)
397
398#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \
399 LE_BITS_TO_4BYTE(__pdesc+40, 0, 32)
400#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \
401 LE_BITS_TO_4BYTE(__pdesc+44, 0, 32)
402
403#define GET_RX_DESC_PKT_LEN(__pdesc) \
404 LE_BITS_TO_4BYTE(__pdesc, 0, 14)
405#define GET_RX_DESC_CRC32(__pdesc) \
406 LE_BITS_TO_4BYTE(__pdesc, 14, 1)
407#define GET_RX_DESC_ICV(__pdesc) \
408 LE_BITS_TO_4BYTE(__pdesc, 15, 1)
409#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \
410 LE_BITS_TO_4BYTE(__pdesc, 16, 4)
411#define GET_RX_DESC_SECURITY(__pdesc) \
412 LE_BITS_TO_4BYTE(__pdesc, 20, 3)
413#define GET_RX_DESC_QOS(__pdesc) \
414 LE_BITS_TO_4BYTE(__pdesc, 23, 1)
415#define GET_RX_DESC_SHIFT(__pdesc) \
416 LE_BITS_TO_4BYTE(__pdesc, 24, 2)
417#define GET_RX_DESC_PHYST(__pdesc) \
418 LE_BITS_TO_4BYTE(__pdesc, 26, 1)
419#define GET_RX_DESC_SWDEC(__pdesc) \
420 LE_BITS_TO_4BYTE(__pdesc, 27, 1)
421#define GET_RX_DESC_LS(__pdesc) \
422 LE_BITS_TO_4BYTE(__pdesc, 28, 1)
423#define GET_RX_DESC_FS(__pdesc) \
424 LE_BITS_TO_4BYTE(__pdesc, 29, 1)
425#define GET_RX_DESC_EOR(__pdesc) \
426 LE_BITS_TO_4BYTE(__pdesc, 30, 1)
427#define GET_RX_DESC_OWN(__pdesc) \
428 LE_BITS_TO_4BYTE(__pdesc, 31, 1)
429
430#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \
431 SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val)
432#define SET_RX_DESC_EOR(__pdesc, __val) \
433 SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val)
434#define SET_RX_DESC_OWN(__pdesc, __val) \
435 SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val)
436
437#define GET_RX_DESC_MACID(__pdesc) \
438 LE_BITS_TO_4BYTE(__pdesc+4, 0, 5)
439#define GET_RX_DESC_TID(__pdesc) \
440 LE_BITS_TO_4BYTE(__pdesc+4, 5, 4)
441#define GET_RX_DESC_HWRSVD(__pdesc) \
442 LE_BITS_TO_4BYTE(__pdesc+4, 9, 5)
443#define GET_RX_DESC_PAGGR(__pdesc) \
444 LE_BITS_TO_4BYTE(__pdesc+4, 14, 1)
445#define GET_RX_DESC_FAGGR(__pdesc) \
446 LE_BITS_TO_4BYTE(__pdesc+4, 15, 1)
447#define GET_RX_DESC_A1_FIT(__pdesc) \
448 LE_BITS_TO_4BYTE(__pdesc+4, 16, 4)
449#define GET_RX_DESC_A2_FIT(__pdesc) \
450 LE_BITS_TO_4BYTE(__pdesc+4, 20, 4)
451#define GET_RX_DESC_PAM(__pdesc) \
452 LE_BITS_TO_4BYTE(__pdesc+4, 24, 1)
453#define GET_RX_DESC_PWR(__pdesc) \
454 LE_BITS_TO_4BYTE(__pdesc+4, 25, 1)
455#define GET_RX_DESC_MD(__pdesc) \
456 LE_BITS_TO_4BYTE(__pdesc+4, 26, 1)
457#define GET_RX_DESC_MF(__pdesc) \
458 LE_BITS_TO_4BYTE(__pdesc+4, 27, 1)
459#define GET_RX_DESC_TYPE(__pdesc) \
460 LE_BITS_TO_4BYTE(__pdesc+4, 28, 2)
461#define GET_RX_DESC_MC(__pdesc) \
462 LE_BITS_TO_4BYTE(__pdesc+4, 30, 1)
463#define GET_RX_DESC_BC(__pdesc) \
464 LE_BITS_TO_4BYTE(__pdesc+4, 31, 1)
465#define GET_RX_DESC_SEQ(__pdesc) \
466 LE_BITS_TO_4BYTE(__pdesc+8, 0, 12)
467#define GET_RX_DESC_FRAG(__pdesc) \
468 LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
469#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \
470 LE_BITS_TO_4BYTE(__pdesc+8, 16, 14)
471#define GET_RX_DESC_NEXT_IND(__pdesc) \
472 LE_BITS_TO_4BYTE(__pdesc+8, 30, 1)
473#define GET_RX_DESC_RSVD(__pdesc) \
474 LE_BITS_TO_4BYTE(__pdesc+8, 31, 1)
475
476#define GET_RX_DESC_RXMCS(__pdesc) \
477 LE_BITS_TO_4BYTE(__pdesc+12, 0, 6)
478#define GET_RX_DESC_RXHT(__pdesc) \
479 LE_BITS_TO_4BYTE(__pdesc+12, 6, 1)
480#define GET_RX_DESC_SPLCP(__pdesc) \
481 LE_BITS_TO_4BYTE(__pdesc+12, 8, 1)
482#define GET_RX_DESC_BW(__pdesc) \
483 LE_BITS_TO_4BYTE(__pdesc+12, 9, 1)
484#define GET_RX_DESC_HTC(__pdesc) \
485 LE_BITS_TO_4BYTE(__pdesc+12, 10, 1)
486#define GET_RX_DESC_HWPC_ERR(__pdesc) \
487 LE_BITS_TO_4BYTE(__pdesc+12, 14, 1)
488#define GET_RX_DESC_HWPC_IND(__pdesc) \
489 LE_BITS_TO_4BYTE(__pdesc+12, 15, 1)
490#define GET_RX_DESC_IV0(__pdesc) \
491 LE_BITS_TO_4BYTE(__pdesc+12, 16, 16)
492
493#define GET_RX_DESC_IV1(__pdesc) \
494 LE_BITS_TO_4BYTE(__pdesc+16, 0, 32)
495#define GET_RX_DESC_TSFL(__pdesc) \
496 LE_BITS_TO_4BYTE(__pdesc+20, 0, 32)
497
498#define GET_RX_DESC_BUFF_ADDR(__pdesc) \
499 LE_BITS_TO_4BYTE(__pdesc+24, 0, 32)
500#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \
501 LE_BITS_TO_4BYTE(__pdesc+28, 0, 32)
502
503#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \
504 SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val)
505#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \
506 SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val)
507
508#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
509do { \
510 if (_size > TX_DESC_NEXT_DESC_OFFSET) \
511 memset((void *)__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
512 else \
513 memset((void *)__pdesc, 0, _size); \
514} while (0);
515
516#define RX_HAL_IS_CCK_RATE(_pdesc)\
517 (_pdesc->rxmcs == DESC92C_RATE1M || \
518 _pdesc->rxmcs == DESC92C_RATE2M || \
519 _pdesc->rxmcs == DESC92C_RATE5_5M || \
520 _pdesc->rxmcs == DESC92C_RATE11M)
521
522struct rx_fwinfo_92c {
523 u8 gain_trsw[4];
524 u8 pwdb_all;
525 u8 cfosho[4];
526 u8 cfotail[4];
527 char rxevm[2];
528 char rxsnr[4];
529 u8 pdsnr[2];
530 u8 csi_current[2];
531 u8 csi_target[2];
532 u8 sigevm;
533 u8 max_ex_pwr;
534 u8 ex_intf_flag:1;
535 u8 sgi_en:1;
536 u8 rxsc:2;
537 u8 reserve:4;
538} __attribute__ ((packed));
539
540struct tx_desc_92c {
541 u32 pktsize:16;
542 u32 offset:8;
543 u32 bmc:1;
544 u32 htc:1;
545 u32 lastseg:1;
546 u32 firstseg:1;
547 u32 linip:1;
548 u32 noacm:1;
549 u32 gf:1;
550 u32 own:1;
551
552 u32 macid:5;
553 u32 agg_en:1;
554 u32 bk:1;
555 u32 rdg_en:1;
556 u32 queuesel:5;
557 u32 rd_nav_ext:1;
558 u32 lsig_txop_en:1;
559 u32 pifs:1;
560 u32 rateid:4;
561 u32 nav_usehdr:1;
562 u32 en_descid:1;
563 u32 sectype:2;
564 u32 pktoffset:8;
565
566 u32 rts_rc:6;
567 u32 data_rc:6;
568 u32 rsvd0:2;
569 u32 bar_retryht:2;
570 u32 rsvd1:1;
571 u32 morefrag:1;
572 u32 raw:1;
573 u32 ccx:1;
574 u32 ampdudensity:3;
575 u32 rsvd2:1;
576 u32 ant_sela:1;
577 u32 ant_selb:1;
578 u32 txant_cck:2;
579 u32 txant_l:2;
580 u32 txant_ht:2;
581
582 u32 nextheadpage:8;
583 u32 tailpage:8;
584 u32 seq:12;
585 u32 pktid:4;
586
587 u32 rtsrate:5;
588 u32 apdcfe:1;
589 u32 qos:1;
590 u32 hwseq_enable:1;
591 u32 userrate:1;
592 u32 dis_rtsfb:1;
593 u32 dis_datafb:1;
594 u32 cts2self:1;
595 u32 rts_en:1;
596 u32 hwrts_en:1;
597 u32 portid:1;
598 u32 rsvd3:3;
599 u32 waitdcts:1;
600 u32 cts2ap_en:1;
601 u32 txsc:2;
602 u32 stbc:2;
603 u32 txshort:1;
604 u32 txbw:1;
605 u32 rtsshort:1;
606 u32 rtsbw:1;
607 u32 rtssc:2;
608 u32 rtsstbc:2;
609
610 u32 txrate:6;
611 u32 shortgi:1;
612 u32 ccxt:1;
613 u32 txrate_fb_lmt:5;
614 u32 rtsrate_fb_lmt:4;
615 u32 retrylmt_en:1;
616 u32 txretrylmt:6;
617 u32 usb_txaggnum:8;
618
619 u32 txagca:5;
620 u32 txagcb:5;
621 u32 usemaxlen:1;
622 u32 maxaggnum:5;
623 u32 mcsg1maxlen:4;
624 u32 mcsg2maxlen:4;
625 u32 mcsg3maxlen:4;
626 u32 mcs7sgimaxlen:4;
627
628 u32 txbuffersize:16;
629 u32 mcsg4maxlen:4;
630 u32 mcsg5maxlen:4;
631 u32 mcsg6maxlen:4;
632 u32 mcsg15sgimaxlen:4;
633
634 u32 txbuffaddr;
635 u32 txbufferaddr64;
636 u32 nextdescaddress;
637 u32 nextdescaddress64;
638
639 u32 reserve_pass_pcie_mm_limit[4];
640} __attribute__ ((packed));
641
642struct rx_desc_92c {
643 u32 length:14;
644 u32 crc32:1;
645 u32 icverror:1;
646 u32 drv_infosize:4;
647 u32 security:3;
648 u32 qos:1;
649 u32 shift:2;
650 u32 phystatus:1;
651 u32 swdec:1;
652 u32 lastseg:1;
653 u32 firstseg:1;
654 u32 eor:1;
655 u32 own:1;
656
657 u32 macid:5;
658 u32 tid:4;
659 u32 hwrsvd:5;
660 u32 paggr:1;
661 u32 faggr:1;
662 u32 a1_fit:4;
663 u32 a2_fit:4;
664 u32 pam:1;
665 u32 pwr:1;
666 u32 moredata:1;
667 u32 morefrag:1;
668 u32 type:2;
669 u32 mc:1;
670 u32 bc:1;
671
672 u32 seq:12;
673 u32 frag:4;
674 u32 nextpktlen:14;
675 u32 nextind:1;
676 u32 rsvd:1;
677
678 u32 rxmcs:6;
679 u32 rxht:1;
680 u32 amsdu:1;
681 u32 splcp:1;
682 u32 bandwidth:1;
683 u32 htc:1;
684 u32 tcpchk_rpt:1;
685 u32 ipcchk_rpt:1;
686 u32 tcpchk_valid:1;
687 u32 hwpcerr:1;
688 u32 hwpcind:1;
689 u32 iv0:16;
690
691 u32 iv1;
692
693 u32 tsfl;
694
695 u32 bufferaddress;
696 u32 bufferaddress64;
697
698} __attribute__ ((packed));
699
700void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
701 struct ieee80211_hdr *hdr,
702 u8 *pdesc, struct ieee80211_tx_info *info,
703 struct sk_buff *skb, unsigned int qsel);
704bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
705 struct rtl_stats *stats,
706 struct ieee80211_rx_status *rx_status,
707 u8 *pdesc, struct sk_buff *skb);
708void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);
709u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name);
710void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue);
711void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
712 bool b_firstseg, bool b_lastseg,
713 struct sk_buff *skb);
714#endif
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
new file mode 100644
index 00000000000..0dd6824b194
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -0,0 +1,1532 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#ifndef __RTL_WIFI_H__
31#define __RTL_WIFI_H__
32
33#include <linux/sched.h>
34#include <linux/firmware.h>
35#include <linux/version.h>
36#include <linux/etherdevice.h>
37#include <net/mac80211.h>
38#include "debug.h"
39
40#define RF_CHANGE_BY_INIT 0
41#define RF_CHANGE_BY_IPS BIT(28)
42#define RF_CHANGE_BY_PS BIT(29)
43#define RF_CHANGE_BY_HW BIT(30)
44#define RF_CHANGE_BY_SW BIT(31)
45
46#define IQK_ADDA_REG_NUM 16
47#define IQK_MAC_REG_NUM 4
48
49#define MAX_KEY_LEN 61
50#define KEY_BUF_SIZE 5
51
52/* QoS related. */
53/*aci: 0x00 Best Effort*/
54/*aci: 0x01 Background*/
55/*aci: 0x10 Video*/
56/*aci: 0x11 Voice*/
57/*Max: define total number.*/
58#define AC0_BE 0
59#define AC1_BK 1
60#define AC2_VI 2
61#define AC3_VO 3
62#define AC_MAX 4
63#define QOS_QUEUE_NUM 4
64#define RTL_MAC80211_NUM_QUEUE 5
65
66#define QBSS_LOAD_SIZE 5
67#define MAX_WMMELE_LENGTH 64
68
69/*slot time for 11g. */
70#define RTL_SLOT_TIME_9 9
71#define RTL_SLOT_TIME_20 20
72
73/*related with tcp/ip. */
74/*if_ehther.h*/
75#define ETH_P_PAE 0x888E /*Port Access Entity (IEEE 802.1X) */
76#define ETH_P_IP 0x0800 /*Internet Protocol packet */
77#define ETH_P_ARP 0x0806 /*Address Resolution packet */
78#define SNAP_SIZE 6
79#define PROTOC_TYPE_SIZE 2
80
81/*related with 802.11 frame*/
82#define MAC80211_3ADDR_LEN 24
83#define MAC80211_4ADDR_LEN 30
84
85enum intf_type {
86 INTF_PCI = 0,
87 INTF_USB = 1,
88};
89
90enum radio_path {
91 RF90_PATH_A = 0,
92 RF90_PATH_B = 1,
93 RF90_PATH_C = 2,
94 RF90_PATH_D = 3,
95};
96
97enum rt_eeprom_type {
98 EEPROM_93C46,
99 EEPROM_93C56,
100 EEPROM_BOOT_EFUSE,
101};
102
103enum rtl_status {
104 RTL_STATUS_INTERFACE_START = 0,
105};
106
107enum hardware_type {
108 HARDWARE_TYPE_RTL8192E,
109 HARDWARE_TYPE_RTL8192U,
110 HARDWARE_TYPE_RTL8192SE,
111 HARDWARE_TYPE_RTL8192SU,
112 HARDWARE_TYPE_RTL8192CE,
113 HARDWARE_TYPE_RTL8192CU,
114 HARDWARE_TYPE_RTL8192DE,
115 HARDWARE_TYPE_RTL8192DU,
116
117 /*keep it last*/
118 HARDWARE_TYPE_NUM
119};
120
121enum scan_operation_backup_opt {
122 SCAN_OPT_BACKUP = 0,
123 SCAN_OPT_RESTORE,
124 SCAN_OPT_MAX
125};
126
127/*RF state.*/
128enum rf_pwrstate {
129 ERFON,
130 ERFSLEEP,
131 ERFOFF
132};
133
134struct bb_reg_def {
135 u32 rfintfs;
136 u32 rfintfi;
137 u32 rfintfo;
138 u32 rfintfe;
139 u32 rf3wire_offset;
140 u32 rflssi_select;
141 u32 rftxgain_stage;
142 u32 rfhssi_para1;
143 u32 rfhssi_para2;
144 u32 rfswitch_control;
145 u32 rfagc_control1;
146 u32 rfagc_control2;
147 u32 rfrxiq_imbalance;
148 u32 rfrx_afe;
149 u32 rftxiq_imbalance;
150 u32 rftx_afe;
151 u32 rflssi_readback;
152 u32 rflssi_readbackpi;
153};
154
155enum io_type {
156 IO_CMD_PAUSE_DM_BY_SCAN = 0,
157 IO_CMD_RESUME_DM_BY_SCAN = 1,
158};
159
160enum hw_variables {
161 HW_VAR_ETHER_ADDR,
162 HW_VAR_MULTICAST_REG,
163 HW_VAR_BASIC_RATE,
164 HW_VAR_BSSID,
165 HW_VAR_MEDIA_STATUS,
166 HW_VAR_SECURITY_CONF,
167 HW_VAR_BEACON_INTERVAL,
168 HW_VAR_ATIM_WINDOW,
169 HW_VAR_LISTEN_INTERVAL,
170 HW_VAR_CS_COUNTER,
171 HW_VAR_DEFAULTKEY0,
172 HW_VAR_DEFAULTKEY1,
173 HW_VAR_DEFAULTKEY2,
174 HW_VAR_DEFAULTKEY3,
175 HW_VAR_SIFS,
176 HW_VAR_DIFS,
177 HW_VAR_EIFS,
178 HW_VAR_SLOT_TIME,
179 HW_VAR_ACK_PREAMBLE,
180 HW_VAR_CW_CONFIG,
181 HW_VAR_CW_VALUES,
182 HW_VAR_RATE_FALLBACK_CONTROL,
183 HW_VAR_CONTENTION_WINDOW,
184 HW_VAR_RETRY_COUNT,
185 HW_VAR_TR_SWITCH,
186 HW_VAR_COMMAND,
187 HW_VAR_WPA_CONFIG,
188 HW_VAR_AMPDU_MIN_SPACE,
189 HW_VAR_SHORTGI_DENSITY,
190 HW_VAR_AMPDU_FACTOR,
191 HW_VAR_MCS_RATE_AVAILABLE,
192 HW_VAR_AC_PARAM,
193 HW_VAR_ACM_CTRL,
194 HW_VAR_DIS_Req_Qsize,
195 HW_VAR_CCX_CHNL_LOAD,
196 HW_VAR_CCX_NOISE_HISTOGRAM,
197 HW_VAR_CCX_CLM_NHM,
198 HW_VAR_TxOPLimit,
199 HW_VAR_TURBO_MODE,
200 HW_VAR_RF_STATE,
201 HW_VAR_RF_OFF_BY_HW,
202 HW_VAR_BUS_SPEED,
203 HW_VAR_SET_DEV_POWER,
204
205 HW_VAR_RCR,
206 HW_VAR_RATR_0,
207 HW_VAR_RRSR,
208 HW_VAR_CPU_RST,
209 HW_VAR_CECHK_BSSID,
210 HW_VAR_LBK_MODE,
211 HW_VAR_AES_11N_FIX,
212 HW_VAR_USB_RX_AGGR,
213 HW_VAR_USER_CONTROL_TURBO_MODE,
214 HW_VAR_RETRY_LIMIT,
215 HW_VAR_INIT_TX_RATE,
216 HW_VAR_TX_RATE_REG,
217 HW_VAR_EFUSE_USAGE,
218 HW_VAR_EFUSE_BYTES,
219 HW_VAR_AUTOLOAD_STATUS,
220 HW_VAR_RF_2R_DISABLE,
221 HW_VAR_SET_RPWM,
222 HW_VAR_H2C_FW_PWRMODE,
223 HW_VAR_H2C_FW_JOINBSSRPT,
224 HW_VAR_FW_PSMODE_STATUS,
225 HW_VAR_1X1_RECV_COMBINE,
226 HW_VAR_STOP_SEND_BEACON,
227 HW_VAR_TSF_TIMER,
228 HW_VAR_IO_CMD,
229
230 HW_VAR_RF_RECOVERY,
231 HW_VAR_H2C_FW_UPDATE_GTK,
232 HW_VAR_WF_MASK,
233 HW_VAR_WF_CRC,
234 HW_VAR_WF_IS_MAC_ADDR,
235 HW_VAR_H2C_FW_OFFLOAD,
236 HW_VAR_RESET_WFCRC,
237
238 HW_VAR_HANDLE_FW_C2H,
239 HW_VAR_DL_FW_RSVD_PAGE,
240 HW_VAR_AID,
241 HW_VAR_HW_SEQ_ENABLE,
242 HW_VAR_CORRECT_TSF,
243 HW_VAR_BCN_VALID,
244 HW_VAR_FWLPS_RF_ON,
245 HW_VAR_DUAL_TSF_RST,
246 HW_VAR_SWITCH_EPHY_WoWLAN,
247 HW_VAR_INT_MIGRATION,
248 HW_VAR_INT_AC,
249 HW_VAR_RF_TIMING,
250
251 HW_VAR_MRC,
252
253 HW_VAR_MGT_FILTER,
254 HW_VAR_CTRL_FILTER,
255 HW_VAR_DATA_FILTER,
256};
257
258enum _RT_MEDIA_STATUS {
259 RT_MEDIA_DISCONNECT = 0,
260 RT_MEDIA_CONNECT = 1
261};
262
263enum rt_oem_id {
264 RT_CID_DEFAULT = 0,
265 RT_CID_8187_ALPHA0 = 1,
266 RT_CID_8187_SERCOMM_PS = 2,
267 RT_CID_8187_HW_LED = 3,
268 RT_CID_8187_NETGEAR = 4,
269 RT_CID_WHQL = 5,
270 RT_CID_819x_CAMEO = 6,
271 RT_CID_819x_RUNTOP = 7,
272 RT_CID_819x_Senao = 8,
273 RT_CID_TOSHIBA = 9,
274 RT_CID_819x_Netcore = 10,
275 RT_CID_Nettronix = 11,
276 RT_CID_DLINK = 12,
277 RT_CID_PRONET = 13,
278 RT_CID_COREGA = 14,
279 RT_CID_819x_ALPHA = 15,
280 RT_CID_819x_Sitecom = 16,
281 RT_CID_CCX = 17,
282 RT_CID_819x_Lenovo = 18,
283 RT_CID_819x_QMI = 19,
284 RT_CID_819x_Edimax_Belkin = 20,
285 RT_CID_819x_Sercomm_Belkin = 21,
286 RT_CID_819x_CAMEO1 = 22,
287 RT_CID_819x_MSI = 23,
288 RT_CID_819x_Acer = 24,
289 RT_CID_819x_HP = 27,
290 RT_CID_819x_CLEVO = 28,
291 RT_CID_819x_Arcadyan_Belkin = 29,
292 RT_CID_819x_SAMSUNG = 30,
293 RT_CID_819x_WNC_COREGA = 31,
294 RT_CID_819x_Foxcoon = 32,
295 RT_CID_819x_DELL = 33,
296};
297
298enum hw_descs {
299 HW_DESC_OWN,
300 HW_DESC_RXOWN,
301 HW_DESC_TX_NEXTDESC_ADDR,
302 HW_DESC_TXBUFF_ADDR,
303 HW_DESC_RXBUFF_ADDR,
304 HW_DESC_RXPKT_LEN,
305 HW_DESC_RXERO,
306};
307
308enum prime_sc {
309 PRIME_CHNL_OFFSET_DONT_CARE = 0,
310 PRIME_CHNL_OFFSET_LOWER = 1,
311 PRIME_CHNL_OFFSET_UPPER = 2,
312};
313
314enum rf_type {
315 RF_1T1R = 0,
316 RF_1T2R = 1,
317 RF_2T2R = 2,
318};
319
320enum ht_channel_width {
321 HT_CHANNEL_WIDTH_20 = 0,
322 HT_CHANNEL_WIDTH_20_40 = 1,
323};
324
325/* Ref: 802.11i sepc D10.0 7.3.2.25.1
326Cipher Suites Encryption Algorithms */
327enum rt_enc_alg {
328 NO_ENCRYPTION = 0,
329 WEP40_ENCRYPTION = 1,
330 TKIP_ENCRYPTION = 2,
331 RSERVED_ENCRYPTION = 3,
332 AESCCMP_ENCRYPTION = 4,
333 WEP104_ENCRYPTION = 5,
334};
335
336enum rtl_hal_state {
337 _HAL_STATE_STOP = 0,
338 _HAL_STATE_START = 1,
339};
340
341enum rtl_var_map {
342 /*reg map */
343 SYS_ISO_CTRL = 0,
344 SYS_FUNC_EN,
345 SYS_CLK,
346 MAC_RCR_AM,
347 MAC_RCR_AB,
348 MAC_RCR_ACRC32,
349 MAC_RCR_ACF,
350 MAC_RCR_AAP,
351
352 /*efuse map */
353 EFUSE_TEST,
354 EFUSE_CTRL,
355 EFUSE_CLK,
356 EFUSE_CLK_CTRL,
357 EFUSE_PWC_EV12V,
358 EFUSE_FEN_ELDR,
359 EFUSE_LOADER_CLK_EN,
360 EFUSE_ANA8M,
361 EFUSE_HWSET_MAX_SIZE,
362
363 /*CAM map */
364 RWCAM,
365 WCAMI,
366 RCAMO,
367 CAMDBG,
368 SECR,
369 SEC_CAM_NONE,
370 SEC_CAM_WEP40,
371 SEC_CAM_TKIP,
372 SEC_CAM_AES,
373 SEC_CAM_WEP104,
374
375 /*IMR map */
376 RTL_IMR_BCNDMAINT6, /*Beacon DMA Interrupt 6 */
377 RTL_IMR_BCNDMAINT5, /*Beacon DMA Interrupt 5 */
378 RTL_IMR_BCNDMAINT4, /*Beacon DMA Interrupt 4 */
379 RTL_IMR_BCNDMAINT3, /*Beacon DMA Interrupt 3 */
380 RTL_IMR_BCNDMAINT2, /*Beacon DMA Interrupt 2 */
381 RTL_IMR_BCNDMAINT1, /*Beacon DMA Interrupt 1 */
382 RTL_IMR_BCNDOK8, /*Beacon Queue DMA OK Interrup 8 */
383 RTL_IMR_BCNDOK7, /*Beacon Queue DMA OK Interrup 7 */
384 RTL_IMR_BCNDOK6, /*Beacon Queue DMA OK Interrup 6 */
385 RTL_IMR_BCNDOK5, /*Beacon Queue DMA OK Interrup 5 */
386 RTL_IMR_BCNDOK4, /*Beacon Queue DMA OK Interrup 4 */
387 RTL_IMR_BCNDOK3, /*Beacon Queue DMA OK Interrup 3 */
388 RTL_IMR_BCNDOK2, /*Beacon Queue DMA OK Interrup 2 */
389 RTL_IMR_BCNDOK1, /*Beacon Queue DMA OK Interrup 1 */
390 RTL_IMR_TIMEOUT2, /*Timeout interrupt 2 */
391 RTL_IMR_TIMEOUT1, /*Timeout interrupt 1 */
392 RTL_IMR_TXFOVW, /*Transmit FIFO Overflow */
393 RTL_IMR_PSTIMEOUT, /*Power save time out interrupt */
394 RTL_IMR_BcnInt, /*Beacon DMA Interrupt 0 */
395 RTL_IMR_RXFOVW, /*Receive FIFO Overflow */
396 RTL_IMR_RDU, /*Receive Descriptor Unavailable */
397 RTL_IMR_ATIMEND, /*For 92C,ATIM Window End Interrupt */
398 RTL_IMR_BDOK, /*Beacon Queue DMA OK Interrup */
399 RTL_IMR_HIGHDOK, /*High Queue DMA OK Interrupt */
400 RTL_IMR_TBDOK, /*Transmit Beacon OK interrup */
401 RTL_IMR_MGNTDOK, /*Management Queue DMA OK Interrupt */
402 RTL_IMR_TBDER, /*For 92C,Transmit Beacon Error Interrupt */
403 RTL_IMR_BKDOK, /*AC_BK DMA OK Interrupt */
404 RTL_IMR_BEDOK, /*AC_BE DMA OK Interrupt */
405 RTL_IMR_VIDOK, /*AC_VI DMA OK Interrupt */
406 RTL_IMR_VODOK, /*AC_VO DMA Interrupt */
407 RTL_IMR_ROK, /*Receive DMA OK Interrupt */
408 RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt|RTL_IMR_TBDOK|RTL_IMR_TBDER)*/
409
410 /*CCK Rates, TxHT = 0 */
411 RTL_RC_CCK_RATE1M,
412 RTL_RC_CCK_RATE2M,
413 RTL_RC_CCK_RATE5_5M,
414 RTL_RC_CCK_RATE11M,
415
416 /*OFDM Rates, TxHT = 0 */
417 RTL_RC_OFDM_RATE6M,
418 RTL_RC_OFDM_RATE9M,
419 RTL_RC_OFDM_RATE12M,
420 RTL_RC_OFDM_RATE18M,
421 RTL_RC_OFDM_RATE24M,
422 RTL_RC_OFDM_RATE36M,
423 RTL_RC_OFDM_RATE48M,
424 RTL_RC_OFDM_RATE54M,
425
426 RTL_RC_HT_RATEMCS7,
427 RTL_RC_HT_RATEMCS15,
428
429 /*keep it last */
430 RTL_VAR_MAP_MAX,
431};
432
433/*Firmware PS mode for control LPS.*/
434enum _fw_ps_mode {
435 FW_PS_ACTIVE_MODE = 0,
436 FW_PS_MIN_MODE = 1,
437 FW_PS_MAX_MODE = 2,
438 FW_PS_DTIM_MODE = 3,
439 FW_PS_VOIP_MODE = 4,
440 FW_PS_UAPSD_WMM_MODE = 5,
441 FW_PS_UAPSD_MODE = 6,
442 FW_PS_IBSS_MODE = 7,
443 FW_PS_WWLAN_MODE = 8,
444 FW_PS_PM_Radio_Off = 9,
445 FW_PS_PM_Card_Disable = 10,
446};
447
448enum rt_psmode {
449 EACTIVE, /*Active/Continuous access. */
450 EMAXPS, /*Max power save mode. */
451 EFASTPS, /*Fast power save mode. */
452 EAUTOPS, /*Auto power save mode. */
453};
454
455/*LED related.*/
456enum led_ctl_mode {
457 LED_CTL_POWER_ON = 1,
458 LED_CTL_LINK = 2,
459 LED_CTL_NO_LINK = 3,
460 LED_CTL_TX = 4,
461 LED_CTL_RX = 5,
462 LED_CTL_SITE_SURVEY = 6,
463 LED_CTL_POWER_OFF = 7,
464 LED_CTL_START_TO_LINK = 8,
465 LED_CTL_START_WPS = 9,
466 LED_CTL_STOP_WPS = 10,
467};
468
469enum rtl_led_pin {
470 LED_PIN_GPIO0,
471 LED_PIN_LED0,
472 LED_PIN_LED1,
473 LED_PIN_LED2
474};
475
476/*QoS related.*/
477/*acm implementation method.*/
478enum acm_method {
479 eAcmWay0_SwAndHw = 0,
480 eAcmWay1_HW = 1,
481 eAcmWay2_SW = 2,
482};
483
484/*aci/aifsn Field.
485Ref: WMM spec 2.2.2: WME Parameter Element, p.12.*/
486union aci_aifsn {
487 u8 char_data;
488
489 struct {
490 u8 aifsn:4;
491 u8 acm:1;
492 u8 aci:2;
493 u8 reserved:1;
494 } f; /* Field */
495};
496
497/*mlme related.*/
498enum wireless_mode {
499 WIRELESS_MODE_UNKNOWN = 0x00,
500 WIRELESS_MODE_A = 0x01,
501 WIRELESS_MODE_B = 0x02,
502 WIRELESS_MODE_G = 0x04,
503 WIRELESS_MODE_AUTO = 0x08,
504 WIRELESS_MODE_N_24G = 0x10,
505 WIRELESS_MODE_N_5G = 0x20
506};
507
508enum ratr_table_mode {
509 RATR_INX_WIRELESS_NGB = 0,
510 RATR_INX_WIRELESS_NG = 1,
511 RATR_INX_WIRELESS_NB = 2,
512 RATR_INX_WIRELESS_N = 3,
513 RATR_INX_WIRELESS_GB = 4,
514 RATR_INX_WIRELESS_G = 5,
515 RATR_INX_WIRELESS_B = 6,
516 RATR_INX_WIRELESS_MC = 7,
517 RATR_INX_WIRELESS_A = 8,
518};
519
520enum rtl_link_state {
521 MAC80211_NOLINK = 0,
522 MAC80211_LINKING = 1,
523 MAC80211_LINKED = 2,
524 MAC80211_LINKED_SCANNING = 3,
525};
526
527enum act_category {
528 ACT_CAT_QOS = 1,
529 ACT_CAT_DLS = 2,
530 ACT_CAT_BA = 3,
531 ACT_CAT_HT = 7,
532 ACT_CAT_WMM = 17,
533};
534
535enum ba_action {
536 ACT_ADDBAREQ = 0,
537 ACT_ADDBARSP = 1,
538 ACT_DELBA = 2,
539};
540
541struct octet_string {
542 u8 *octet;
543 u16 length;
544};
545
546struct rtl_hdr_3addr {
547 __le16 frame_ctl;
548 __le16 duration_id;
549 u8 addr1[ETH_ALEN];
550 u8 addr2[ETH_ALEN];
551 u8 addr3[ETH_ALEN];
552 __le16 seq_ctl;
553 u8 payload[0];
554} __attribute__ ((packed));
555
556struct rtl_info_element {
557 u8 id;
558 u8 len;
559 u8 data[0];
560} __attribute__ ((packed));
561
562struct rtl_probe_rsp {
563 struct rtl_hdr_3addr header;
564 u32 time_stamp[2];
565 __le16 beacon_interval;
566 __le16 capability;
567 /*SSID, supported rates, FH params, DS params,
568 CF params, IBSS params, TIM (if beacon), RSN */
569 struct rtl_info_element info_element[0];
570} __attribute__ ((packed));
571
572/*LED related.*/
573/*ledpin Identify how to implement this SW led.*/
574struct rtl_led {
575 void *hw;
576 enum rtl_led_pin ledpin;
577 bool b_ledon;
578};
579
580struct rtl_led_ctl {
581 bool bled_opendrain;
582 struct rtl_led sw_led0;
583 struct rtl_led sw_led1;
584};
585
586struct rtl_qos_parameters {
587 __le16 cw_min;
588 __le16 cw_max;
589 u8 aifs;
590 u8 flag;
591 __le16 tx_op;
592} __attribute__ ((packed));
593
594struct rt_smooth_data {
595 u32 elements[100]; /*array to store values */
596 u32 index; /*index to current array to store */
597 u32 total_num; /*num of valid elements */
598 u32 total_val; /*sum of valid elements */
599};
600
601struct false_alarm_statistics {
602 u32 cnt_parity_fail;
603 u32 cnt_rate_illegal;
604 u32 cnt_crc8_fail;
605 u32 cnt_mcs_fail;
606 u32 cnt_ofdm_fail;
607 u32 cnt_cck_fail;
608 u32 cnt_all;
609};
610
611struct init_gain {
612 u8 xaagccore1;
613 u8 xbagccore1;
614 u8 xcagccore1;
615 u8 xdagccore1;
616 u8 cca;
617
618};
619
620struct wireless_stats {
621 unsigned long txbytesunicast;
622 unsigned long txbytesmulticast;
623 unsigned long txbytesbroadcast;
624 unsigned long rxbytesunicast;
625
626 long rx_snr_db[4];
627 /*Correct smoothed ss in Dbm, only used
628 in driver to report real power now. */
629 long recv_signal_power;
630 long signal_quality;
631 long last_sigstrength_inpercent;
632
633 u32 rssi_calculate_cnt;
634
635 /*Transformed, in dbm. Beautified signal
636 strength for UI, not correct. */
637 long signal_strength;
638
639 u8 rx_rssi_percentage[4];
640 u8 rx_evm_percentage[2];
641
642 struct rt_smooth_data ui_rssi;
643 struct rt_smooth_data ui_link_quality;
644};
645
646struct rate_adaptive {
647 u8 rate_adaptive_disabled;
648 u8 ratr_state;
649 u16 reserve;
650
651 u32 high_rssi_thresh_for_ra;
652 u32 high2low_rssi_thresh_for_ra;
653 u8 low2high_rssi_thresh_for_ra40m;
654 u32 low_rssi_thresh_for_ra40M;
655 u8 low2high_rssi_thresh_for_ra20m;
656 u32 low_rssi_thresh_for_ra20M;
657 u32 upper_rssi_threshold_ratr;
658 u32 middleupper_rssi_threshold_ratr;
659 u32 middle_rssi_threshold_ratr;
660 u32 middlelow_rssi_threshold_ratr;
661 u32 low_rssi_threshold_ratr;
662 u32 ultralow_rssi_threshold_ratr;
663 u32 low_rssi_threshold_ratr_40m;
664 u32 low_rssi_threshold_ratr_20m;
665 u8 ping_rssi_enable;
666 u32 ping_rssi_ratr;
667 u32 ping_rssi_thresh_for_ra;
668 u32 last_ratr;
669 u8 pre_ratr_state;
670};
671
672struct regd_pair_mapping {
673 u16 reg_dmnenum;
674 u16 reg_5ghz_ctl;
675 u16 reg_2ghz_ctl;
676};
677
678struct rtl_regulatory {
679 char alpha2[2];
680 u16 country_code;
681 u16 max_power_level;
682 u32 tp_scale;
683 u16 current_rd;
684 u16 current_rd_ext;
685 int16_t power_limit;
686 struct regd_pair_mapping *regpair;
687};
688
689struct rtl_rfkill {
690 bool rfkill_state; /*0 is off, 1 is on */
691};
692
693struct rtl_phy {
694 struct bb_reg_def phyreg_def[4]; /*Radio A/B/C/D */
695 struct init_gain initgain_backup;
696 enum io_type current_io_type;
697
698 u8 rf_mode;
699 u8 rf_type;
700 u8 current_chan_bw;
701 u8 set_bwmode_inprogress;
702 u8 sw_chnl_inprogress;
703 u8 sw_chnl_stage;
704 u8 sw_chnl_step;
705 u8 current_channel;
706 u8 h2c_box_num;
707 u8 set_io_inprogress;
708
709 /*record for power tracking*/
710 s32 reg_e94;
711 s32 reg_e9c;
712 s32 reg_ea4;
713 s32 reg_eac;
714 s32 reg_eb4;
715 s32 reg_ebc;
716 s32 reg_ec4;
717 s32 reg_ecc;
718 u8 rfpienable;
719 u8 reserve_0;
720 u16 reserve_1;
721 u32 reg_c04, reg_c08, reg_874;
722 u32 adda_backup[16];
723 u32 iqk_mac_backup[IQK_MAC_REG_NUM];
724 u32 iqk_bb_backup[10];
725
726 bool b_rfpi_enable;
727
728 u8 pwrgroup_cnt;
729 u8 bcck_high_power;
730 /* 3 groups of pwr diff by rates*/
731 u32 mcs_txpwrlevel_origoffset[4][16];
732 u8 default_initialgain[4];
733
734 /*the current Tx power level*/
735 u8 cur_cck_txpwridx;
736 u8 cur_ofdm24g_txpwridx;
737
738 u32 rfreg_chnlval[2];
739 bool b_apk_done;
740
741 /*fsync*/
742 u8 framesync;
743 u32 framesync_c34;
744
745 u8 num_total_rfpath;
746};
747
748#define MAX_TID_COUNT 9
749#define RTL_AGG_OFF 0
750#define RTL_AGG_ON 1
751#define RTL_AGG_EMPTYING_HW_QUEUE_ADDBA 2
752#define RTL_AGG_EMPTYING_HW_QUEUE_DELBA 3
753
754struct rtl_ht_agg {
755 u16 txq_id;
756 u16 wait_for_ba;
757 u16 start_idx;
758 u64 bitmap;
759 u32 rate_n_flags;
760 u8 agg_state;
761};
762
763struct rtl_tid_data {
764 u16 seq_number;
765 struct rtl_ht_agg agg;
766};
767
768struct rtl_priv;
769struct rtl_io {
770 struct device *dev;
771
772 /*PCI MEM map */
773 unsigned long pci_mem_end; /*shared mem end */
774 unsigned long pci_mem_start; /*shared mem start */
775
776 /*PCI IO map */
777 unsigned long pci_base_addr; /*device I/O address */
778
779 void (*write8_async) (struct rtl_priv *rtlpriv, u32 addr, u8 val);
780 void (*write16_async) (struct rtl_priv *rtlpriv, u32 addr, u16 val);
781 void (*write32_async) (struct rtl_priv *rtlpriv, u32 addr, u32 val);
782
783 u8(*read8_sync) (struct rtl_priv *rtlpriv, u32 addr);
784 u16(*read16_sync) (struct rtl_priv *rtlpriv, u32 addr);
785 u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr);
786
787};
788
789struct rtl_mac {
790 u8 mac_addr[ETH_ALEN];
791 u8 mac80211_registered;
792 u8 beacon_enabled;
793
794 u32 tx_ss_num;
795 u32 rx_ss_num;
796
797 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
798 struct ieee80211_hw *hw;
799 struct ieee80211_vif *vif;
800 enum nl80211_iftype opmode;
801
802 /*Probe Beacon management */
803 struct rtl_tid_data tids[MAX_TID_COUNT];
804 enum rtl_link_state link_state;
805
806 int n_channels;
807 int n_bitrates;
808
809 /*filters */
810 u32 rx_conf;
811 u16 rx_mgt_filter;
812 u16 rx_ctrl_filter;
813 u16 rx_data_filter;
814
815 bool act_scanning;
816 u8 cnt_after_linked;
817
818 /*RDG*/ bool rdg_en;
819
820 /*AP*/ u8 bssid[6];
821 u8 mcs[16]; /*16 bytes mcs for HT rates.*/
822 u32 basic_rates; /*b/g rates*/
823 u8 ht_enable;
824 u8 sgi_40;
825 u8 sgi_20;
826 u8 bw_40;
827 u8 mode; /*wireless mode*/
828 u8 slot_time;
829 u8 short_preamble;
830 u8 use_cts_protect;
831 u8 cur_40_prime_sc;
832 u8 cur_40_prime_sc_bk;
833 u64 tsf;
834 u8 retry_short;
835 u8 retry_long;
836 u16 assoc_id;
837
838 /*IBSS*/ int beacon_interval;
839
840 /*AMPDU*/ u8 min_space_cfg; /*For Min spacing configurations */
841 u8 max_mss_density;
842 u8 current_ampdu_factor;
843 u8 current_ampdu_density;
844
845 /*QOS & EDCA */
846 struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE];
847 struct rtl_qos_parameters ac[AC_MAX];
848};
849
850struct rtl_hal {
851 struct ieee80211_hw *hw;
852
853 enum intf_type interface;
854 u16 hw_type; /*92c or 92d or 92s and so on */
855 u8 oem_id;
856 u8 version; /*version of chip */
857 u8 state; /*stop 0, start 1 */
858
859 /*firmware */
860 u8 *pfirmware;
861 bool b_h2c_setinprogress;
862 u8 last_hmeboxnum;
863 bool bfw_ready;
864 /*Reserve page start offset except beacon in TxQ. */
865 u8 fw_rsvdpage_startoffset;
866};
867
868struct rtl_security {
869 /*default 0 */
870 bool use_sw_sec;
871
872 bool being_setkey;
873 bool use_defaultkey;
874 /*Encryption Algorithm for Unicast Packet */
875 enum rt_enc_alg pairwise_enc_algorithm;
876 /*Encryption Algorithm for Brocast/Multicast */
877 enum rt_enc_alg group_enc_algorithm;
878
879 /*local Key buffer, indx 0 is for
880 pairwise key 1-4 is for agoup key. */
881 u8 key_buf[KEY_BUF_SIZE][MAX_KEY_LEN];
882 u8 key_len[KEY_BUF_SIZE];
883
884 /*The pointer of Pairwise Key,
885 it always points to KeyBuf[4] */
886 u8 *pairwise_key;
887};
888
889struct rtl_dm {
890 /*PHY status for DM */
891 long entry_min_undecoratedsmoothed_pwdb;
892 long undecorated_smoothed_pwdb; /*out dm */
893 long entry_max_undecoratedsmoothed_pwdb;
894 bool b_dm_initialgain_enable;
895 bool bdynamic_txpower_enable;
896 bool bcurrent_turbo_edca;
897 bool bis_any_nonbepkts; /*out dm */
898 bool bis_cur_rdlstate;
899 bool btxpower_trackingInit;
900 bool b_disable_framebursting;
901 bool b_cck_inch14;
902 bool btxpower_tracking;
903 bool b_useramask;
904 bool brfpath_rxenable[4];
905
906 u8 thermalvalue_iqk;
907 u8 thermalvalue_lck;
908 u8 thermalvalue;
909 u8 last_dtp_lvl;
910 u8 dynamic_txhighpower_lvl; /*Tx high power level */
911 u8 dm_flag; /*Indicate if each dynamic mechanism's status. */
912 u8 dm_type;
913 u8 txpower_track_control;
914
915 char ofdm_index[2];
916 char cck_index;
917};
918
919#define EFUSE_MAX_LOGICAL_SIZE 128
920
921struct rtl_efuse {
922 bool bautoLoad_ok;
923 bool bootfromefuse;
924 u16 max_physical_size;
925 u8 contents[EFUSE_MAX_LOGICAL_SIZE];
926
927 u8 efuse_map[2][EFUSE_MAX_LOGICAL_SIZE];
928 u16 efuse_usedbytes;
929 u8 efuse_usedpercentage;
930
931 u8 autoload_failflag;
932
933 short epromtype;
934 u16 eeprom_vid;
935 u16 eeprom_did;
936 u16 eeprom_svid;
937 u16 eeprom_smid;
938 u8 eeprom_oemid;
939 u16 eeprom_channelplan;
940 u8 eeprom_version;
941
942 u8 dev_addr[6];
943
944 bool b_txpwr_fromeprom;
945 u8 eeprom_tssi[2];
946 u8 eeprom_pwrlimit_ht20[3];
947 u8 eeprom_pwrlimit_ht40[3];
948 u8 eeprom_chnlarea_txpwr_cck[2][3];
949 u8 eeprom_chnlarea_txpwr_ht40_1s[2][3];
950 u8 eeprom_chnlarea_txpwr_ht40_2sdiif[2][3];
951 u8 txpwrlevel_cck[2][14];
952 u8 txpwrlevel_ht40_1s[2][14]; /*For HT 40MHZ pwr */
953 u8 txpwrlevel_ht40_2s[2][14]; /*For HT 40MHZ pwr */
954
955 /*For power group */
956 u8 pwrgroup_ht20[2][14];
957 u8 pwrgroup_ht40[2][14];
958
959 char txpwr_ht20diff[2][14]; /*HT 20<->40 Pwr diff */
960 u8 txpwr_legacyhtdiff[2][14]; /*For HT<->legacy pwr diff */
961
962 u8 eeprom_regulatory;
963 u8 eeprom_thermalmeter;
964 /*ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 */
965 u8 thermalmeter[2];
966
967 u8 legacy_ht_txpowerdiff; /*Legacy to HT rate power diff */
968 bool b_apk_thermalmeterignore;
969};
970
971struct rtl_ps_ctl {
972 bool set_rfpowerstate_inprogress;
973 bool b_in_powersavemode;
974 bool rfchange_inprogress;
975 bool b_swrf_processing;
976 bool b_hwradiooff;
977
978 u32 last_sleep_jiffies;
979 u32 last_awake_jiffies;
980 u32 last_delaylps_stamp_jiffies;
981
982 /*
983 * just for PCIE ASPM
984 * If it supports ASPM, Offset[560h] = 0x40,
985 * otherwise Offset[560h] = 0x00.
986 * */
987 bool b_support_aspm;
988 bool b_support_backdoor;
989
990 /*for LPS */
991 enum rt_psmode dot11_psmode; /*Power save mode configured. */
992 bool b_leisure_ps;
993 bool b_fwctrl_lps;
994 u8 fwctrl_psmode;
995 /*For Fw control LPS mode */
996 u8 b_reg_fwctrl_lps;
997 /*Record Fw PS mode status. */
998 bool b_fw_current_inpsmode;
999 u8 reg_max_lps_awakeintvl;
1000 bool report_linked;
1001
1002 /*for IPS */
1003 bool b_inactiveps;
1004
1005 u32 rfoff_reason;
1006
1007 /*RF OFF Level */
1008 u32 cur_ps_level;
1009 u32 reg_rfps_level;
1010
1011 /*just for PCIE ASPM */
1012 u8 const_amdpci_aspm;
1013
1014 enum rf_pwrstate inactive_pwrstate;
1015 enum rf_pwrstate rfpwr_state; /*cur power state */
1016};
1017
1018struct rtl_stats {
1019 u32 mac_time[2];
1020 s8 rssi;
1021 u8 signal;
1022 u8 noise;
1023 u16 rate; /*in 100 kbps */
1024 u8 received_channel;
1025 u8 control;
1026 u8 mask;
1027 u8 freq;
1028 u16 len;
1029 u64 tsf;
1030 u32 beacon_time;
1031 u8 nic_type;
1032 u16 length;
1033 u8 signalquality; /*in 0-100 index. */
1034 /*
1035 * Real power in dBm for this packet,
1036 * no beautification and aggregation.
1037 * */
1038 s32 recvsignalpower;
1039 s8 rxpower; /*in dBm Translate from PWdB */
1040 u8 signalstrength; /*in 0-100 index. */
1041 u16 b_hwerror:1;
1042 u16 b_crc:1;
1043 u16 b_icv:1;
1044 u16 b_shortpreamble:1;
1045 u16 antenna:1;
1046 u16 decrypted:1;
1047 u16 wakeup:1;
1048 u32 timestamp_low;
1049 u32 timestamp_high;
1050
1051 u8 rx_drvinfo_size;
1052 u8 rx_bufshift;
1053 bool b_isampdu;
1054 bool rx_is40Mhzpacket;
1055 u32 rx_pwdb_all;
1056 u8 rx_mimo_signalstrength[4]; /*in 0~100 index */
1057 s8 rx_mimo_signalquality[2];
1058 bool b_packet_matchbssid;
1059 bool b_is_cck;
1060 bool b_packet_toself;
1061 bool b_packet_beacon; /*for rssi */
1062 char cck_adc_pwdb[4]; /*for rx path selection */
1063};
1064
1065struct rt_link_detect {
1066 u32 num_tx_in4period[4];
1067 u32 num_rx_in4period[4];
1068
1069 u32 num_tx_inperiod;
1070 u32 num_rx_inperiod;
1071
1072 bool b_busytraffic;
1073 bool b_higher_busytraffic;
1074 bool b_higher_busyrxtraffic;
1075};
1076
1077struct rtl_tcb_desc {
1078 u8 b_packet_bw:1;
1079 u8 b_multicast:1;
1080 u8 b_broadcast:1;
1081
1082 u8 b_rts_stbc:1;
1083 u8 b_rts_enable:1;
1084 u8 b_cts_enable:1;
1085 u8 b_rts_use_shortpreamble:1;
1086 u8 b_rts_use_shortgi:1;
1087 u8 rts_sc:1;
1088 u8 b_rts_bw:1;
1089 u8 rts_rate;
1090
1091 u8 use_shortgi:1;
1092 u8 use_shortpreamble:1;
1093 u8 use_driver_rate:1;
1094 u8 disable_ratefallback:1;
1095
1096 u8 ratr_index;
1097 u8 mac_id;
1098 u8 hw_rate;
1099};
1100
1101struct rtl_hal_ops {
1102 int (*init_sw_vars) (struct ieee80211_hw *hw);
1103 void (*deinit_sw_vars) (struct ieee80211_hw *hw);
1104 void (*read_eeprom_info) (struct ieee80211_hw *hw);
1105 void (*interrupt_recognized) (struct ieee80211_hw *hw,
1106 u32 *p_inta, u32 *p_intb);
1107 int (*hw_init) (struct ieee80211_hw *hw);
1108 void (*hw_disable) (struct ieee80211_hw *hw);
1109 void (*enable_interrupt) (struct ieee80211_hw *hw);
1110 void (*disable_interrupt) (struct ieee80211_hw *hw);
1111 int (*set_network_type) (struct ieee80211_hw *hw,
1112 enum nl80211_iftype type);
1113 void (*set_bw_mode) (struct ieee80211_hw *hw,
1114 enum nl80211_channel_type ch_type);
1115 u8(*switch_channel) (struct ieee80211_hw *hw);
1116 void (*set_qos) (struct ieee80211_hw *hw, int aci);
1117 void (*set_bcn_reg) (struct ieee80211_hw *hw);
1118 void (*set_bcn_intv) (struct ieee80211_hw *hw);
1119 void (*update_interrupt_mask) (struct ieee80211_hw *hw,
1120 u32 add_msr, u32 rm_msr);
1121 void (*get_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val);
1122 void (*set_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val);
1123 void (*update_rate_table) (struct ieee80211_hw *hw);
1124 void (*update_rate_mask) (struct ieee80211_hw *hw, u8 rssi_level);
1125 void (*fill_tx_desc) (struct ieee80211_hw *hw,
1126 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
1127 struct ieee80211_tx_info *info,
1128 struct sk_buff *skb, unsigned int queue_index);
1129 void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc,
1130 bool b_firstseg, bool b_lastseg,
1131 struct sk_buff *skb);
1132 bool(*query_rx_desc) (struct ieee80211_hw *hw,
1133 struct rtl_stats *stats,
1134 struct ieee80211_rx_status *rx_status,
1135 u8 *pdesc, struct sk_buff *skb);
1136 void (*set_channel_access) (struct ieee80211_hw *hw);
1137 bool(*radio_onoff_checking) (struct ieee80211_hw *hw, u8 *valid);
1138 void (*dm_watchdog) (struct ieee80211_hw *hw);
1139 void (*scan_operation_backup) (struct ieee80211_hw *hw, u8 operation);
1140 bool(*set_rf_power_state) (struct ieee80211_hw *hw,
1141 enum rf_pwrstate rfpwr_state);
1142 void (*led_control) (struct ieee80211_hw *hw,
1143 enum led_ctl_mode ledaction);
1144 void (*set_desc) (u8 *pdesc, bool istx, u8 desc_name, u8 *val);
1145 u32(*get_desc) (u8 *pdesc, bool istx, u8 desc_name);
1146 void (*tx_polling) (struct ieee80211_hw *hw, unsigned int hw_queue);
1147 void (*enable_hw_sec) (struct ieee80211_hw *hw);
1148 void (*set_key) (struct ieee80211_hw *hw, u32 key_index,
1149 u8 *p_macaddr, bool is_group, u8 enc_algo,
1150 bool is_wepkey, bool clear_all);
1151 void (*init_sw_leds) (struct ieee80211_hw *hw);
1152 void (*deinit_sw_leds) (struct ieee80211_hw *hw);
1153 u32(*get_bbreg) (struct ieee80211_hw *hw, u32 regaddr, u32 bitmask);
1154 void (*set_bbreg) (struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
1155 u32 data);
1156 u32(*get_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath,
1157 u32 regaddr, u32 bitmask);
1158 void (*set_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath,
1159 u32 regaddr, u32 bitmask, u32 data);
1160};
1161
1162struct rtl_intf_ops {
1163 /*com */
1164 int (*adapter_start) (struct ieee80211_hw *hw);
1165 void (*adapter_stop) (struct ieee80211_hw *hw);
1166
1167 int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb);
1168 int (*reset_trx_ring) (struct ieee80211_hw *hw);
1169
1170 /*pci */
1171 void (*disable_aspm) (struct ieee80211_hw *hw);
1172 void (*enable_aspm) (struct ieee80211_hw *hw);
1173
1174 /*usb */
1175};
1176
1177struct rtl_mod_params {
1178 /* default: 0 = using hardware encryption */
1179 int sw_crypto;
1180};
1181
1182struct rtl_hal_cfg {
1183 char *name;
1184 char *fw_name;
1185 struct rtl_hal_ops *ops;
1186 struct rtl_mod_params *mod_params;
1187
1188 /*this map used for some registers or vars
1189 defined int HAL but used in MAIN */
1190 u32 maps[RTL_VAR_MAP_MAX];
1191
1192};
1193
1194struct rtl_locks {
1195 /*sem */
1196 struct semaphore ips_sem;
1197 struct semaphore conf_sem;
1198
1199 /*spin lock */
1200 spinlock_t irq_th_lock;
1201 spinlock_t h2c_lock;
1202 spinlock_t rf_ps_lock;
1203 spinlock_t rf_lock;
1204 spinlock_t lps_lock;
1205};
1206
1207struct rtl_works {
1208 struct ieee80211_hw *hw;
1209
1210 /*timer */
1211 struct timer_list watchdog_timer;
1212
1213 /*task */
1214 struct tasklet_struct irq_tasklet;
1215 struct tasklet_struct irq_prepare_bcn_tasklet;
1216
1217 /*work queue */
1218 struct workqueue_struct *rtl_wq;
1219 struct delayed_work watchdog_wq;
1220 struct delayed_work ips_nic_off_wq;
1221};
1222
1223struct rtl_debug {
1224 u32 dbgp_type[DBGP_TYPE_MAX];
1225 u32 global_debuglevel;
1226 u64 global_debugcomponents;
1227};
1228
1229struct rtl_priv {
1230 struct rtl_locks locks;
1231 struct rtl_works works;
1232 struct rtl_mac mac80211;
1233 struct rtl_hal rtlhal;
1234 struct rtl_regulatory regd;
1235 struct rtl_rfkill rfkill;
1236 struct rtl_io io;
1237 struct rtl_phy phy;
1238 struct rtl_dm dm;
1239 struct rtl_security sec;
1240 struct rtl_efuse efuse;
1241
1242 struct rtl_ps_ctl psc;
1243 struct rate_adaptive ra;
1244 struct wireless_stats stats;
1245 struct rt_link_detect link_info;
1246 struct false_alarm_statistics falsealm_cnt;
1247
1248 struct rtl_rate_priv *rate_priv;
1249
1250 struct rtl_debug dbg;
1251
1252 /*
1253 *hal_cfg : for diff cards
1254 *intf_ops : for diff interrface usb/pcie
1255 */
1256 struct rtl_hal_cfg *cfg;
1257 struct rtl_intf_ops *intf_ops;
1258
1259 /*this var will be set by set_bit,
1260 and was used to indicate status of
1261 interface or hardware */
1262 unsigned long status;
1263
1264 /*This must be the last item so
1265 that it points to the data allocated
1266 beyond this structure like:
1267 rtl_pci_priv or rtl_usb_priv */
1268 u8 priv[0];
1269};
1270
1271#define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv))
1272#define rtl_mac(rtlpriv) (&((rtlpriv)->mac80211))
1273#define rtl_hal(rtlpriv) (&((rtlpriv)->rtlhal))
1274#define rtl_efuse(rtlpriv) (&((rtlpriv)->efuse))
1275#define rtl_psc(rtlpriv) (&((rtlpriv)->psc))
1276
1277/****************************************
1278 mem access macro define start
1279 Call endian free function when
1280 1. Read/write packet content.
1281 2. Before write integer to IO.
1282 3. After read integer from IO.
1283****************************************/
1284/* Convert little data endian to host */
1285#define EF1BYTE(_val) \
1286 ((u8)(_val))
1287#define EF2BYTE(_val) \
1288 (le16_to_cpu(_val))
1289#define EF4BYTE(_val) \
1290 (le32_to_cpu(_val))
1291
1292/* Read data from memory */
1293#define READEF1BYTE(_ptr) \
1294 EF1BYTE(*((u8 *)(_ptr)))
1295#define READEF2BYTE(_ptr) \
1296 EF2BYTE(*((u16 *)(_ptr)))
1297#define READEF4BYTE(_ptr) \
1298 EF4BYTE(*((u32 *)(_ptr)))
1299
1300/* Write data to memory */
1301#define WRITEEF1BYTE(_ptr, _val) \
1302 (*((u8 *)(_ptr))) = EF1BYTE(_val)
1303#define WRITEEF2BYTE(_ptr, _val) \
1304 (*((u16 *)(_ptr))) = EF2BYTE(_val)
1305#define WRITEEF4BYTE(_ptr, _val) \
1306 (*((u32 *)(_ptr))) = EF4BYTE(_val)
1307
1308/*Example:
1309BIT_LEN_MASK_32(0) => 0x00000000
1310BIT_LEN_MASK_32(1) => 0x00000001
1311BIT_LEN_MASK_32(2) => 0x00000003
1312BIT_LEN_MASK_32(32) => 0xFFFFFFFF*/
1313#define BIT_LEN_MASK_32(__bitlen) \
1314 (0xFFFFFFFF >> (32 - (__bitlen)))
1315#define BIT_LEN_MASK_16(__bitlen) \
1316 (0xFFFF >> (16 - (__bitlen)))
1317#define BIT_LEN_MASK_8(__bitlen) \
1318 (0xFF >> (8 - (__bitlen)))
1319
1320/*Example:
1321BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003
1322BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000*/
1323#define BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen) \
1324 (BIT_LEN_MASK_32(__bitlen) << (__bitoffset))
1325#define BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen) \
1326 (BIT_LEN_MASK_16(__bitlen) << (__bitoffset))
1327#define BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen) \
1328 (BIT_LEN_MASK_8(__bitlen) << (__bitoffset))
1329
1330/*Description:
1331Return 4-byte value in host byte ordering from
13324-byte pointer in little-endian system.*/
1333#define LE_P4BYTE_TO_HOST_4BYTE(__pstart) \
1334 (EF4BYTE(*((u32 *)(__pstart))))
1335#define LE_P2BYTE_TO_HOST_2BYTE(__pstart) \
1336 (EF2BYTE(*((u16 *)(__pstart))))
1337#define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \
1338 (EF1BYTE(*((u8 *)(__pstart))))
1339
1340/*Description:
1341Translate subfield (continuous bits in little-endian) of 4-byte
1342value to host byte ordering.*/
1343#define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \
1344 ( \
1345 (LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset)) & \
1346 BIT_LEN_MASK_32(__bitlen) \
1347 )
1348#define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \
1349 ( \
1350 (LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \
1351 BIT_LEN_MASK_16(__bitlen) \
1352 )
1353#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \
1354 ( \
1355 (LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \
1356 BIT_LEN_MASK_8(__bitlen) \
1357 )
1358
1359/*Description:
1360Mask subfield (continuous bits in little-endian) of 4-byte value
1361and return the result in 4-byte value in host byte ordering.*/
1362#define LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) \
1363 ( \
1364 LE_P4BYTE_TO_HOST_4BYTE(__pstart) & \
1365 (~BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen)) \
1366 )
1367#define LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) \
1368 ( \
1369 LE_P2BYTE_TO_HOST_2BYTE(__pstart) & \
1370 (~BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen)) \
1371 )
1372#define LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) \
1373 ( \
1374 LE_P1BYTE_TO_HOST_1BYTE(__pstart) & \
1375 (~BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen)) \
1376 )
1377
1378/*Description:
1379Set subfield of little-endian 4-byte value to specified value. */
1380#define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \
1381 *((u32 *)(__pstart)) = EF4BYTE \
1382 ( \
1383 LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \
1384 ((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \
1385 );
1386#define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \
1387 *((u16 *)(__pstart)) = EF2BYTE \
1388 ( \
1389 LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \
1390 ((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \
1391 );
1392#define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \
1393 *((u8 *)(__pstart)) = EF1BYTE \
1394 ( \
1395 LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) | \
1396 ((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \
1397 );
1398
1399/****************************************
1400 mem access macro define end
1401****************************************/
1402
1403#define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC)
1404#define RTL_WATCH_DOG_TIME 2000
1405#define MSECS(t) msecs_to_jiffies(t)
1406#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
1407#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
1408#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
1409#define WLAN_FC_MORE_DATA(fc) ((fc) & IEEE80211_FCTL_MOREDATA)
1410#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
1411#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
1412#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
1413
1414#define RT_RF_OFF_LEVL_ASPM BIT(0) /*PCI ASPM */
1415#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /*PCI clock request */
1416#define RT_RF_OFF_LEVL_PCI_D3 BIT(2) /*PCI D3 mode */
1417/*NIC halt, re-initialize hw parameters*/
1418#define RT_RF_OFF_LEVL_HALT_NIC BIT(3)
1419#define RT_RF_OFF_LEVL_FREE_FW BIT(4) /*FW free, re-download the FW */
1420#define RT_RF_OFF_LEVL_FW_32K BIT(5) /*FW in 32k */
1421/*Always enable ASPM and Clock Req in initialization.*/
1422#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6)
1423/*When LPS is on, disable 2R if no packet is received or transmittd.*/
1424#define RT_RF_LPS_DISALBE_2R BIT(30)
1425#define RT_RF_LPS_LEVEL_ASPM BIT(31) /*LPS with ASPM */
1426#define RT_IN_PS_LEVEL(ppsc, _ps_flg) \
1427 ((ppsc->cur_ps_level & _ps_flg) ? true : false)
1428#define RT_CLEAR_PS_LEVEL(ppsc, _ps_flg) \
1429 (ppsc->cur_ps_level &= (~(_ps_flg)))
1430#define RT_SET_PS_LEVEL(ppsc, _ps_flg) \
1431 (ppsc->cur_ps_level |= _ps_flg)
1432
1433#define container_of_dwork_rtl(x, y, z) \
1434 container_of(container_of(x, struct delayed_work, work), y, z)
1435
1436#define FILL_OCTET_STRING(_os, _octet, _len) \
1437 (_os).octet = (u8 *)(_octet); \
1438 (_os).length = (_len);
1439
1440#define CP_MACADDR(des, src) \
1441 ((des)[0] = (src)[0], (des)[1] = (src)[1],\
1442 (des)[2] = (src)[2], (des)[3] = (src)[3],\
1443 (des)[4] = (src)[4], (des)[5] = (src)[5])
1444
1445static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr)
1446{
1447 return rtlpriv->io.read8_sync(rtlpriv, addr);
1448}
1449
1450static inline u16 rtl_read_word(struct rtl_priv *rtlpriv, u32 addr)
1451{
1452 return rtlpriv->io.read16_sync(rtlpriv, addr);
1453}
1454
1455static inline u32 rtl_read_dword(struct rtl_priv *rtlpriv, u32 addr)
1456{
1457 return rtlpriv->io.read32_sync(rtlpriv, addr);
1458}
1459
1460static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8)
1461{
1462 rtlpriv->io.write8_async(rtlpriv, addr, val8);
1463}
1464
1465static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16)
1466{
1467 rtlpriv->io.write16_async(rtlpriv, addr, val16);
1468}
1469
1470static inline void rtl_write_dword(struct rtl_priv *rtlpriv,
1471 u32 addr, u32 val32)
1472{
1473 rtlpriv->io.write32_async(rtlpriv, addr, val32);
1474}
1475
1476static inline u32 rtl_get_bbreg(struct ieee80211_hw *hw,
1477 u32 regaddr, u32 bitmask)
1478{
1479 return ((struct rtl_priv *)(hw)->priv)->cfg->ops->get_bbreg(hw,
1480 regaddr,
1481 bitmask);
1482}
1483
1484static inline void rtl_set_bbreg(struct ieee80211_hw *hw, u32 regaddr,
1485 u32 bitmask, u32 data)
1486{
1487 ((struct rtl_priv *)(hw)->priv)->cfg->ops->set_bbreg(hw,
1488 regaddr, bitmask,
1489 data);
1490
1491}
1492
1493static inline u32 rtl_get_rfreg(struct ieee80211_hw *hw,
1494 enum radio_path rfpath, u32 regaddr,
1495 u32 bitmask)
1496{
1497 return ((struct rtl_priv *)(hw)->priv)->cfg->ops->get_rfreg(hw,
1498 rfpath,
1499 regaddr,
1500 bitmask);
1501}
1502
1503static inline void rtl_set_rfreg(struct ieee80211_hw *hw,
1504 enum radio_path rfpath, u32 regaddr,
1505 u32 bitmask, u32 data)
1506{
1507 ((struct rtl_priv *)(hw)->priv)->cfg->ops->set_rfreg(hw,
1508 rfpath, regaddr,
1509 bitmask, data);
1510}
1511
1512static inline bool is_hal_stop(struct rtl_hal *rtlhal)
1513{
1514 return (_HAL_STATE_STOP == rtlhal->state);
1515}
1516
1517static inline void set_hal_start(struct rtl_hal *rtlhal)
1518{
1519 rtlhal->state = _HAL_STATE_START;
1520}
1521
1522static inline void set_hal_stop(struct rtl_hal *rtlhal)
1523{
1524 rtlhal->state = _HAL_STATE_STOP;
1525}
1526
1527static inline u8 get_rf_type(struct rtl_phy *rtlphy)
1528{
1529 return rtlphy->rf_type;
1530}
1531
1532#endif