aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS10
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile1
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c39
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h104
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c225
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c136
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h44
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c125
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c28
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c215
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h57
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c209
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c213
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c211
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c57
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h18
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c220
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c30
-rw-r--r--drivers/net/wireless/ath/key.c2
-rw-r--r--drivers/net/wireless/ath/regd.c8
-rw-r--r--drivers/net/wireless/b43/b43.h8
-rw-r--r--drivers/net/wireless/b43/main.c8
-rw-r--r--drivers/net/wireless/b43/phy_n.c35
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c71
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c88
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c338
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c304
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h53
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c3
-rw-r--r--drivers/net/wireless/libertas/cfg.c3
-rw-r--r--drivers/net/wireless/rndis_wlan.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c132
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c132
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c78
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h158
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c169
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c133
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c83
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h85
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c35
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h9
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c40
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c239
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h41
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c282
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c159
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h62
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c87
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h36
-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.c493
-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/def.h257
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/dm.c1473
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/dm.h196
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/fw.c804
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/fw.h98
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.c2173
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.h57
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/led.c144
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/led.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/phy.c2676
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/phy.h237
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/reg.h2065
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rf.c523
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rf.h44
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c282
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.h37
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/table.c1224
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/table.h58
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.c1031
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.h714
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h1532
-rw-r--r--drivers/net/wireless/wl1251/sdio.c2
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig10
-rw-r--r--drivers/net/wireless/wl12xx/Makefile3
-rw-r--r--drivers/net/wireless/wl12xx/acx.c4
-rw-r--r--drivers/net/wireless/wl12xx/acx.h9
-rw-r--r--drivers/net/wireless/wl12xx/boot.c17
-rw-r--r--drivers/net/wireless/wl12xx/boot.h1
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c69
-rw-r--r--drivers/net/wireless/wl12xx/cmd.h4
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c192
-rw-r--r--drivers/net/wireless/wl12xx/init.c13
-rw-r--r--drivers/net/wireless/wl12xx/io.c1
-rw-r--r--drivers/net/wireless/wl12xx/main.c119
-rw-r--r--drivers/net/wireless/wl12xx/scan.c4
-rw-r--r--drivers/net/wireless/wl12xx/sdio_test.c520
-rw-r--r--drivers/net/wireless/wl12xx/tx.c60
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h129
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx_80211.h17
-rw-r--r--include/linux/ieee80211.h27
-rw-r--r--include/linux/nl80211.h113
-rw-r--r--include/net/cfg80211.h67
-rw-r--r--include/net/mac80211.h4
-rw-r--r--net/mac80211/agg-tx.c7
-rw-r--r--net/mac80211/cfg.c53
-rw-r--r--net/mac80211/debugfs_key.c37
-rw-r--r--net/mac80211/debugfs_key.h8
-rw-r--r--net/mac80211/debugfs_sta.c2
-rw-r--r--net/mac80211/driver-ops.h2
-rw-r--r--net/mac80211/ieee80211_i.h9
-rw-r--r--net/mac80211/key.c45
-rw-r--r--net/mac80211/key.h3
-rw-r--r--net/mac80211/main.c15
-rw-r--r--net/mac80211/mesh.c52
-rw-r--r--net/mac80211/mesh.h22
-rw-r--r--net/mac80211/mesh_plink.c3
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c2
-rw-r--r--net/mac80211/rx.c50
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/tx.c22
-rw-r--r--net/wireless/core.c22
-rw-r--r--net/wireless/core.h5
-rw-r--r--net/wireless/mesh.c24
-rw-r--r--net/wireless/mlme.c22
-rw-r--r--net/wireless/nl80211.c276
-rw-r--r--net/wireless/nl80211.h6
-rw-r--r--net/wireless/reg.c3
-rw-r--r--net/wireless/scan.c11
-rw-r--r--net/wireless/util.c3
-rw-r--r--net/wireless/wext-compat.c8
177 files changed, 27469 insertions, 3045 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index f5630a5b3f49..52d5d9739a08 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5062,6 +5062,16 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.g
5062S: Maintained 5062S: Maintained
5063F: drivers/net/wireless/rtl818x/rtl8187* 5063F: drivers/net/wireless/rtl818x/rtl8187*
5064 5064
5065RTL8192CE WIRELESS DRIVER
5066M: Larry Finger <Larry.Finger@lwfinger.net>
5067M: Chaoming Li <chaoming_li@realsil.com.cn>
5068L: linux-wireless@vger.kernel.org
5069W: http://linuxwireless.org/
5070T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
5071S: Maintained
5072F: drivers/net/wireless/rtlwifi/
5073F: drivers/net/wireless/rtlwifi/rtl8192ce/
5074
5065S3 SAVAGE FRAMEBUFFER DRIVER 5075S3 SAVAGE FRAMEBUFFER DRIVER
5066M: Antonino Daplas <adaplas@gmail.com> 5076M: Antonino Daplas <adaplas@gmail.com>
5067L: linux-fbdev@vger.kernel.org 5077L: linux-fbdev@vger.kernel.org
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 4de4410cd38e..b4338f389394 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 06f8ca26c5c1..9760561a27a5 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/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 4e3b97c3d7c2..e4ec40c63396 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2351,6 +2351,10 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
2351 BIT(NL80211_IFTYPE_ADHOC) | 2351 BIT(NL80211_IFTYPE_ADHOC) |
2352 BIT(NL80211_IFTYPE_MESH_POINT); 2352 BIT(NL80211_IFTYPE_MESH_POINT);
2353 2353
2354 /* both antennas can be configured as RX or TX */
2355 hw->wiphy->available_antennas_tx = 0x3;
2356 hw->wiphy->available_antennas_rx = 0x3;
2357
2354 hw->extra_tx_headroom = 2; 2358 hw->extra_tx_headroom = 2;
2355 hw->channel_change_time = 5000; 2359 hw->channel_change_time = 5000;
2356 2360
@@ -2654,6 +2658,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
2654 bool skip_pcu) 2658 bool skip_pcu)
2655{ 2659{
2656 struct ath5k_hw *ah = sc->ah; 2660 struct ath5k_hw *ah = sc->ah;
2661 struct ath_common *common = ath5k_hw_common(ah);
2657 int ret, ani_mode; 2662 int ret, ani_mode;
2658 2663
2659 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); 2664 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
@@ -2696,6 +2701,14 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
2696 ah->ah_cal_next_nf = jiffies; 2701 ah->ah_cal_next_nf = jiffies;
2697 ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8); 2702 ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8);
2698 2703
2704 /* clear survey data and cycle counters */
2705 memset(&sc->survey, 0, sizeof(sc->survey));
2706 spin_lock(&common->cc_lock);
2707 ath_hw_cycle_counters_update(common);
2708 memset(&common->cc_survey, 0, sizeof(common->cc_survey));
2709 memset(&common->cc_ani, 0, sizeof(common->cc_ani));
2710 spin_unlock(&common->cc_lock);
2711
2699 /* 2712 /*
2700 * Change channels and update the h/w rate map if we're switching; 2713 * Change channels and update the h/w rate map if we're switching;
2701 * e.g. 11a to 11b/g. 2714 * e.g. 11a to 11b/g.
@@ -3362,25 +3375,27 @@ static int ath5k_get_survey(struct ieee80211_hw *hw, int idx,
3362 if (idx != 0) 3375 if (idx != 0)
3363 return -ENOENT; 3376 return -ENOENT;
3364 3377
3365 survey->channel = conf->channel;
3366 survey->filled = SURVEY_INFO_NOISE_DBM;
3367 survey->noise = sc->ah->ah_noise_floor;
3368
3369 spin_lock_bh(&common->cc_lock); 3378 spin_lock_bh(&common->cc_lock);
3370 ath_hw_cycle_counters_update(common); 3379 ath_hw_cycle_counters_update(common);
3371 if (cc->cycles > 0) { 3380 if (cc->cycles > 0) {
3372 survey->filled |= SURVEY_INFO_CHANNEL_TIME | 3381 sc->survey.channel_time += cc->cycles / div;
3373 SURVEY_INFO_CHANNEL_TIME_BUSY | 3382 sc->survey.channel_time_busy += cc->rx_busy / div;
3374 SURVEY_INFO_CHANNEL_TIME_RX | 3383 sc->survey.channel_time_rx += cc->rx_frame / div;
3375 SURVEY_INFO_CHANNEL_TIME_TX; 3384 sc->survey.channel_time_tx += cc->tx_frame / div;
3376 survey->channel_time += cc->cycles / div;
3377 survey->channel_time_busy += cc->rx_busy / div;
3378 survey->channel_time_rx += cc->rx_frame / div;
3379 survey->channel_time_tx += cc->tx_frame / div;
3380 } 3385 }
3381 memset(cc, 0, sizeof(*cc)); 3386 memset(cc, 0, sizeof(*cc));
3382 spin_unlock_bh(&common->cc_lock); 3387 spin_unlock_bh(&common->cc_lock);
3383 3388
3389 memcpy(survey, &sc->survey, sizeof(*survey));
3390
3391 survey->channel = conf->channel;
3392 survey->noise = sc->ah->ah_noise_floor;
3393 survey->filled = SURVEY_INFO_NOISE_DBM |
3394 SURVEY_INFO_CHANNEL_TIME |
3395 SURVEY_INFO_CHANNEL_TIME_BUSY |
3396 SURVEY_INFO_CHANNEL_TIME_RX |
3397 SURVEY_INFO_CHANNEL_TIME_TX;
3398
3384 return 0; 3399 return 0;
3385} 3400}
3386 3401
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index aa6c32aafb59..6d511476e4d2 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -258,6 +258,8 @@ struct ath5k_softc {
258 struct tasklet_struct ani_tasklet; /* ANI calibration */ 258 struct tasklet_struct ani_tasklet; /* ANI calibration */
259 259
260 struct delayed_work tx_complete_work; 260 struct delayed_work tx_complete_work;
261
262 struct survey_info survey; /* collected survey info */
261}; 263};
262 264
263#define ath5k_hw_hasbssidmask(_ah) \ 265#define ath5k_hw_hasbssidmask(_ah) \
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 059330aac645..ffcf44a4058b 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -961,18 +961,6 @@ static void ar5008_hw_rfbus_done(struct ath_hw *ah)
961 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); 961 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
962} 962}
963 963
964static void ar5008_hw_enable_rfkill(struct ath_hw *ah)
965{
966 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
967 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
968
969 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
970 AR_GPIO_INPUT_MUX2_RFSILENT);
971
972 ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
973 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
974}
975
976static void ar5008_restore_chainmask(struct ath_hw *ah) 964static void ar5008_restore_chainmask(struct ath_hw *ah)
977{ 965{
978 int rx_chainmask = ah->rxchainmask; 966 int rx_chainmask = ah->rxchainmask;
@@ -1629,7 +1617,6 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
1629 priv_ops->set_delta_slope = ar5008_hw_set_delta_slope; 1617 priv_ops->set_delta_slope = ar5008_hw_set_delta_slope;
1630 priv_ops->rfbus_req = ar5008_hw_rfbus_req; 1618 priv_ops->rfbus_req = ar5008_hw_rfbus_req;
1631 priv_ops->rfbus_done = ar5008_hw_rfbus_done; 1619 priv_ops->rfbus_done = ar5008_hw_rfbus_done;
1632 priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
1633 priv_ops->restore_chainmask = ar5008_restore_chainmask; 1620 priv_ops->restore_chainmask = ar5008_restore_chainmask;
1634 priv_ops->set_diversity = ar5008_set_diversity; 1621 priv_ops->set_diversity = ar5008_set_diversity;
1635 priv_ops->do_getnf = ar5008_hw_do_getnf; 1622 priv_ops->do_getnf = ar5008_hw_do_getnf;
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 7d5cb204f938..fdb5a835fdcf 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -26,24 +26,6 @@ MODULE_PARM_DESC(nohwcrypt, "Force new ANI for AR5008, AR9001, AR9002");
26 26
27/* General hardware code for the A5008/AR9001/AR9002 hadware families */ 27/* General hardware code for the A5008/AR9001/AR9002 hadware families */
28 28
29static bool ar9002_hw_macversion_supported(u32 macversion)
30{
31 switch (macversion) {
32 case AR_SREV_VERSION_5416_PCI:
33 case AR_SREV_VERSION_5416_PCIE:
34 case AR_SREV_VERSION_9160:
35 case AR_SREV_VERSION_9100:
36 case AR_SREV_VERSION_9280:
37 case AR_SREV_VERSION_9285:
38 case AR_SREV_VERSION_9287:
39 case AR_SREV_VERSION_9271:
40 return true;
41 default:
42 break;
43 }
44 return false;
45}
46
47static void ar9002_hw_init_mode_regs(struct ath_hw *ah) 29static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
48{ 30{
49 if (AR_SREV_9271(ah)) { 31 if (AR_SREV_9271(ah)) {
@@ -565,7 +547,6 @@ void ar9002_hw_attach_ops(struct ath_hw *ah)
565 547
566 priv_ops->init_mode_regs = ar9002_hw_init_mode_regs; 548 priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
567 priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs; 549 priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs;
568 priv_ops->macversion_supported = ar9002_hw_macversion_supported;
569 550
570 ops->config_pci_powersave = ar9002_hw_configpcipowersave; 551 ops->config_pci_powersave = ar9002_hw_configpcipowersave;
571 552
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index f3f9c589158e..399ab3bb299b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -283,7 +283,6 @@ static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
283{ 283{
284 struct ar5416_desc *ads = AR5416DESC(ds); 284 struct ar5416_desc *ads = AR5416DESC(ds);
285 285
286 txPower += ah->txpower_indexoffset;
287 if (txPower > 63) 286 if (txPower > 63)
288 txPower = 63; 287 txPower = 63;
289 288
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index a14a5e43cf56..81f9cf294dec 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -34,9 +34,9 @@ static const u32 ar9300_2p2_radio_postamble[][5] = {
34 34
35static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { 35static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
36 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 36 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
37 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, 37 {0x0000a2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
38 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, 38 {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
39 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, 39 {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
40 {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 40 {0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
41 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, 41 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
42 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 42 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -56,21 +56,21 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
56 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, 56 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
57 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, 57 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
58 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, 58 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
59 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, 59 {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
60 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, 60 {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
61 {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83}, 61 {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
62 {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84}, 62 {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
63 {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3}, 63 {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
64 {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5}, 64 {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
65 {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9}, 65 {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
66 {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb}, 66 {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
67 {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 67 {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
68 {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 68 {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
69 {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 69 {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
70 {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 70 {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
71 {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 71 {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
72 {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 72 {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
73 {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, 73 {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
74 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, 74 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
75 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, 75 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
76 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, 76 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
@@ -88,44 +88,44 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
88 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, 88 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
89 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, 89 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
90 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, 90 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
91 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, 91 {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
92 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, 92 {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
93 {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83}, 93 {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
94 {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84}, 94 {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
95 {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3}, 95 {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
96 {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5}, 96 {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
97 {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9}, 97 {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
98 {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb}, 98 {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
99 {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 99 {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
100 {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 100 {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
101 {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 101 {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
102 {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 102 {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
103 {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 103 {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
104 {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 104 {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
105 {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, 105 {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
106 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 106 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
107 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 107 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
108 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 108 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
109 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 109 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
110 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 110 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
111 {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, 111 {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
112 {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, 112 {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
113 {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, 113 {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
114 {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, 114 {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
115 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, 115 {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
116 {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, 116 {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
117 {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, 117 {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
118 {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 118 {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
119 {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 119 {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
120 {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 120 {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
121 {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, 121 {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
122 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, 122 {0x0000b2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
123 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, 123 {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
124 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, 124 {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
125 {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 125 {0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
126 {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800}, 126 {0x0000c2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
127 {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000}, 127 {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
128 {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000}, 128 {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
129 {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 129 {0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
130 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, 130 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
131 {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, 131 {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
@@ -638,6 +638,7 @@ static const u32 ar9300_2p2_baseband_postamble[][5] = {
638 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, 638 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
639 {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0}, 639 {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0},
640 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, 640 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
641 {0x0000a22c, 0x01026a2f, 0x01026a2f, 0x01026a2f, 0x01026a2f},
641 {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, 642 {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
642 {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff}, 643 {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
643 {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, 644 {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
@@ -680,7 +681,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
680 {0x0000981c, 0x00020028}, 681 {0x0000981c, 0x00020028},
681 {0x00009834, 0x6400a290}, 682 {0x00009834, 0x6400a290},
682 {0x00009838, 0x0108ecff}, 683 {0x00009838, 0x0108ecff},
683 {0x0000983c, 0x14750600}, 684 {0x0000983c, 0x0d000600},
684 {0x00009880, 0x201fff00}, 685 {0x00009880, 0x201fff00},
685 {0x00009884, 0x00001042}, 686 {0x00009884, 0x00001042},
686 {0x000098a4, 0x00200400}, 687 {0x000098a4, 0x00200400},
@@ -722,7 +723,6 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
722 {0x0000a220, 0x00000000}, 723 {0x0000a220, 0x00000000},
723 {0x0000a224, 0x00000000}, 724 {0x0000a224, 0x00000000},
724 {0x0000a228, 0x10002310}, 725 {0x0000a228, 0x10002310},
725 {0x0000a22c, 0x01036a27},
726 {0x0000a23c, 0x00000000}, 726 {0x0000a23c, 0x00000000},
727 {0x0000a244, 0x0c000000}, 727 {0x0000a244, 0x0c000000},
728 {0x0000a2a0, 0x00000001}, 728 {0x0000a2a0, 0x00000001},
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 7c3334bd396e..4a4cd88429c0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -608,120 +608,6 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
608 return true; 608 return true;
609} 609}
610 610
611static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
612{
613 struct ath_common *common = ath9k_hw_common(ah);
614 static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
615 AR_PHY_TX_IQCAL_STATUS_B0,
616 AR_PHY_TX_IQCAL_STATUS_B1,
617 AR_PHY_TX_IQCAL_STATUS_B2,
618 };
619 static const u32 rx_corr[AR9300_MAX_CHAINS] = {
620 AR_PHY_RX_IQCAL_CORR_B0,
621 AR_PHY_RX_IQCAL_CORR_B1,
622 AR_PHY_RX_IQCAL_CORR_B2,
623 };
624 static const u_int32_t chan_info_tab[] = {
625 AR_PHY_CHAN_INFO_TAB_0,
626 AR_PHY_CHAN_INFO_TAB_1,
627 AR_PHY_CHAN_INFO_TAB_2,
628 };
629 u32 tx_corr_coeff[AR9300_MAX_CHAINS];
630 s32 iq_res[6];
631 s32 iqc_coeff[2];
632 s32 i, j;
633 u32 num_chains = 0;
634
635 tx_corr_coeff[0] = AR_PHY_TX_IQCAL_CORR_COEFF_B0(0);
636 tx_corr_coeff[1] = AR_PHY_TX_IQCAL_CORR_COEFF_B1(0);
637 tx_corr_coeff[2] = AR_PHY_TX_IQCAL_CORR_COEFF_B2(0);
638
639 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
640 if (ah->txchainmask & (1 << i))
641 num_chains++;
642 }
643
644 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
645 AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
646 DELPT);
647 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
648 AR_PHY_TX_IQCAL_START_DO_CAL,
649 AR_PHY_TX_IQCAL_START_DO_CAL);
650
651 if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
652 AR_PHY_TX_IQCAL_START_DO_CAL,
653 0, AH_WAIT_TIMEOUT)) {
654 ath_dbg(common, ATH_DBG_CALIBRATE,
655 "Tx IQ Cal not complete.\n");
656 goto TX_IQ_CAL_FAILED;
657 }
658
659 for (i = 0; i < num_chains; i++) {
660 ath_dbg(common, ATH_DBG_CALIBRATE,
661 "Doing Tx IQ Cal for chain %d.\n", i);
662
663 if (REG_READ(ah, txiqcal_status[i]) &
664 AR_PHY_TX_IQCAL_STATUS_FAILED) {
665 ath_dbg(common, ATH_DBG_CALIBRATE,
666 "Tx IQ Cal failed for chain %d.\n", i);
667 goto TX_IQ_CAL_FAILED;
668 }
669
670 for (j = 0; j < 3; j++) {
671 u_int8_t idx = 2 * j,
672 offset = 4 * j;
673
674 REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
675 AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
676
677 /* 32 bits */
678 iq_res[idx] = REG_READ(ah, chan_info_tab[i] + offset);
679
680 REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
681 AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
682
683 /* 16 bits */
684 iq_res[idx+1] = 0xffff & REG_READ(ah,
685 chan_info_tab[i] +
686 offset);
687
688 ath_dbg(common, ATH_DBG_CALIBRATE,
689 "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
690 idx, iq_res[idx], idx+1, iq_res[idx+1]);
691 }
692
693 if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, iqc_coeff)) {
694 ath_dbg(common, ATH_DBG_CALIBRATE,
695 "Failed in calculation of IQ correction.\n");
696 goto TX_IQ_CAL_FAILED;
697 }
698
699 ath_dbg(common, ATH_DBG_CALIBRATE,
700 "IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n",
701 iqc_coeff[0], iqc_coeff[1]);
702
703 REG_RMW_FIELD(ah, tx_corr_coeff[i],
704 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
705 iqc_coeff[0]);
706 REG_RMW_FIELD(ah, rx_corr[i],
707 AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF,
708 iqc_coeff[1] >> 7);
709 REG_RMW_FIELD(ah, rx_corr[i],
710 AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF,
711 iqc_coeff[1]);
712 }
713
714 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
715 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
716 REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
717 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
718
719 return;
720
721TX_IQ_CAL_FAILED:
722 ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
723}
724
725static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg) 611static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
726{ 612{
727 int diff[MPASS]; 613 int diff[MPASS];
@@ -730,9 +616,9 @@ static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
730 diff[1] = abs(mp_coeff[1] - mp_coeff[2]); 616 diff[1] = abs(mp_coeff[1] - mp_coeff[2]);
731 diff[2] = abs(mp_coeff[2] - mp_coeff[0]); 617 diff[2] = abs(mp_coeff[2] - mp_coeff[0]);
732 618
733 if (diff[0] > MAX_MEASUREMENT && 619 if (diff[0] > MAX_DIFFERENCE &&
734 diff[1] > MAX_MEASUREMENT && 620 diff[1] > MAX_DIFFERENCE &&
735 diff[2] > MAX_MEASUREMENT) 621 diff[2] > MAX_DIFFERENCE)
736 return false; 622 return false;
737 623
738 if (diff[0] <= diff[1] && diff[0] <= diff[2]) 624 if (diff[0] <= diff[1] && diff[0] <= diff[2])
@@ -830,6 +716,111 @@ disable_txiqcal:
830 ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n"); 716 ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n");
831} 717}
832 718
719static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
720{
721 struct ath_common *common = ath9k_hw_common(ah);
722 static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
723 AR_PHY_TX_IQCAL_STATUS_B0,
724 AR_PHY_TX_IQCAL_STATUS_B1,
725 AR_PHY_TX_IQCAL_STATUS_B2,
726 };
727 static const u32 chan_info_tab[] = {
728 AR_PHY_CHAN_INFO_TAB_0,
729 AR_PHY_CHAN_INFO_TAB_1,
730 AR_PHY_CHAN_INFO_TAB_2,
731 };
732 struct coeff coeff;
733 s32 iq_res[6];
734 s32 i, j, ip, im, nmeasurement;
735 u8 nchains = get_streams(common->tx_chainmask);
736
737 for (ip = 0; ip < MPASS; ip++) {
738 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
739 AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
740 DELPT);
741 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
742 AR_PHY_TX_IQCAL_START_DO_CAL,
743 AR_PHY_TX_IQCAL_START_DO_CAL);
744
745 if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
746 AR_PHY_TX_IQCAL_START_DO_CAL,
747 0, AH_WAIT_TIMEOUT)) {
748 ath_dbg(common, ATH_DBG_CALIBRATE,
749 "Tx IQ Cal not complete.\n");
750 goto TX_IQ_CAL_FAILED;
751 }
752
753 nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0,
754 AR_PHY_CALIBRATED_GAINS_0);
755 if (nmeasurement > MAX_MEASUREMENT)
756 nmeasurement = MAX_MEASUREMENT;
757
758 for (i = 0; i < nchains; i++) {
759 ath_dbg(common, ATH_DBG_CALIBRATE,
760 "Doing Tx IQ Cal for chain %d.\n", i);
761 for (im = 0; im < nmeasurement; im++) {
762 if (REG_READ(ah, txiqcal_status[i]) &
763 AR_PHY_TX_IQCAL_STATUS_FAILED) {
764 ath_dbg(common, ATH_DBG_CALIBRATE,
765 "Tx IQ Cal failed for chain %d.\n", i);
766 goto TX_IQ_CAL_FAILED;
767 }
768
769 for (j = 0; j < 3; j++) {
770 u8 idx = 2 * j,
771 offset = 4 * (3 * im + j);
772
773 REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
774 AR_PHY_CHAN_INFO_TAB_S2_READ,
775 0);
776
777 /* 32 bits */
778 iq_res[idx] = REG_READ(ah,
779 chan_info_tab[i] +
780 offset);
781
782 REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
783 AR_PHY_CHAN_INFO_TAB_S2_READ,
784 1);
785
786 /* 16 bits */
787 iq_res[idx+1] = 0xffff & REG_READ(ah,
788 chan_info_tab[i] +
789 offset);
790
791 ath_dbg(common, ATH_DBG_CALIBRATE,
792 "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
793 idx, iq_res[idx], idx+1, iq_res[idx+1]);
794 }
795
796 if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
797 coeff.iqc_coeff)) {
798 ath_dbg(common, ATH_DBG_CALIBRATE,
799 "Failed in calculation of IQ correction.\n");
800 goto TX_IQ_CAL_FAILED;
801 }
802 coeff.mag_coeff[i][im][ip] =
803 coeff.iqc_coeff[0] & 0x7f;
804 coeff.phs_coeff[i][im][ip] =
805 (coeff.iqc_coeff[0] >> 7) & 0x7f;
806
807 if (coeff.mag_coeff[i][im][ip] > 63)
808 coeff.mag_coeff[i][im][ip] -= 128;
809 if (coeff.phs_coeff[i][im][ip] > 63)
810 coeff.phs_coeff[i][im][ip] -= 128;
811
812 }
813 }
814 }
815
816 ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff);
817
818 return;
819
820TX_IQ_CAL_FAILED:
821 ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
822}
823
833static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) 824static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
834{ 825{
835 u8 tx_gain_forced; 826 u8 tx_gain_forced;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index a16b3dae5b34..466d2bf02eab 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -73,7 +73,7 @@ static const struct ar9300_eeprom ar9300_default = {
73 .regDmn = { LE16(0), LE16(0x1f) }, 73 .regDmn = { LE16(0), LE16(0x1f) },
74 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ 74 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
75 .opCapFlags = { 75 .opCapFlags = {
76 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 76 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
77 .eepMisc = 0, 77 .eepMisc = 0,
78 }, 78 },
79 .rfSilent = 0, 79 .rfSilent = 0,
@@ -650,7 +650,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
650 .regDmn = { LE16(0), LE16(0x1f) }, 650 .regDmn = { LE16(0), LE16(0x1f) },
651 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ 651 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
652 .opCapFlags = { 652 .opCapFlags = {
653 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 653 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
654 .eepMisc = 0, 654 .eepMisc = 0,
655 }, 655 },
656 .rfSilent = 0, 656 .rfSilent = 0,
@@ -1228,7 +1228,7 @@ static const struct ar9300_eeprom ar9300_h112 = {
1228 .regDmn = { LE16(0), LE16(0x1f) }, 1228 .regDmn = { LE16(0), LE16(0x1f) },
1229 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ 1229 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1230 .opCapFlags = { 1230 .opCapFlags = {
1231 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 1231 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1232 .eepMisc = 0, 1232 .eepMisc = 0,
1233 }, 1233 },
1234 .rfSilent = 0, 1234 .rfSilent = 0,
@@ -1806,7 +1806,7 @@ static const struct ar9300_eeprom ar9300_x112 = {
1806 .regDmn = { LE16(0), LE16(0x1f) }, 1806 .regDmn = { LE16(0), LE16(0x1f) },
1807 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ 1807 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
1808 .opCapFlags = { 1808 .opCapFlags = {
1809 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 1809 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
1810 .eepMisc = 0, 1810 .eepMisc = 0,
1811 }, 1811 },
1812 .rfSilent = 0, 1812 .rfSilent = 0,
@@ -2383,7 +2383,7 @@ static const struct ar9300_eeprom ar9300_h116 = {
2383 .regDmn = { LE16(0), LE16(0x1f) }, 2383 .regDmn = { LE16(0), LE16(0x1f) },
2384 .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */ 2384 .txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
2385 .opCapFlags = { 2385 .opCapFlags = {
2386 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 2386 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
2387 .eepMisc = 0, 2387 .eepMisc = 0,
2388 }, 2388 },
2389 .rfSilent = 0, 2389 .rfSilent = 0,
@@ -2975,7 +2975,7 @@ static const struct ar9300_eeprom *ar9003_eeprom_struct_find_by_id(int id)
2975 2975
2976static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) 2976static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
2977{ 2977{
2978 if (fbin == AR9300_BCHAN_UNUSED) 2978 if (fbin == AR5416_BCHAN_UNUSED)
2979 return fbin; 2979 return fbin;
2980 2980
2981 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); 2981 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
@@ -3428,18 +3428,6 @@ static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
3428 return 0; 3428 return 0;
3429} 3429}
3430 3430
3431static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
3432 enum ath9k_hal_freq_band freq_band)
3433{
3434 return 1;
3435}
3436
3437static u32 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
3438 struct ath9k_channel *chan)
3439{
3440 return -EINVAL;
3441}
3442
3443static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz) 3431static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
3444{ 3432{
3445 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 3433 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
@@ -4486,7 +4474,7 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
4486 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]); 4474 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
4487 } 4475 }
4488 4476
4489 return AR9300_MAX_RATE_POWER; 4477 return MAX_RATE_POWER;
4490} 4478}
4491 4479
4492/* 4480/*
@@ -4495,7 +4483,7 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
4495static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep, 4483static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4496 u16 freq, int idx, bool is2GHz) 4484 u16 freq, int idx, bool is2GHz)
4497{ 4485{
4498 u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER; 4486 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4499 u8 *ctl_freqbin = is2GHz ? 4487 u8 *ctl_freqbin = is2GHz ?
4500 &eep->ctl_freqbin_2G[idx][0] : 4488 &eep->ctl_freqbin_2G[idx][0] :
4501 &eep->ctl_freqbin_5G[idx][0]; 4489 &eep->ctl_freqbin_5G[idx][0];
@@ -4505,7 +4493,7 @@ static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4505 4493
4506 /* Get the edge power */ 4494 /* Get the edge power */
4507 for (edge = 0; 4495 for (edge = 0;
4508 (edge < num_edges) && (ctl_freqbin[edge] != AR9300_BCHAN_UNUSED); 4496 (edge < num_edges) && (ctl_freqbin[edge] != AR5416_BCHAN_UNUSED);
4509 edge++) { 4497 edge++) {
4510 /* 4498 /*
4511 * If there's an exact channel match or an inband flag set 4499 * If there's an exact channel match or an inband flag set
@@ -4543,9 +4531,9 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4543 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 4531 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
4544 struct ath_common *common = ath9k_hw_common(ah); 4532 struct ath_common *common = ath9k_hw_common(ah);
4545 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep; 4533 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
4546 u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER; 4534 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4547 static const u16 tpScaleReductionTable[5] = { 4535 static const u16 tpScaleReductionTable[5] = {
4548 0, 3, 6, 9, AR9300_MAX_RATE_POWER 4536 0, 3, 6, 9, MAX_RATE_POWER
4549 }; 4537 };
4550 int i; 4538 int i;
4551 int16_t twiceLargestAntenna; 4539 int16_t twiceLargestAntenna;
@@ -4756,6 +4744,16 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4756 } /* end ctl mode checking */ 4744 } /* end ctl mode checking */
4757} 4745}
4758 4746
4747static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
4748{
4749 u8 mod_idx = mcs_idx % 8;
4750
4751 if (mod_idx <= 3)
4752 return mod_idx ? (base_pwridx + 1) : base_pwridx;
4753 else
4754 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
4755}
4756
4759static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, 4757static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4760 struct ath9k_channel *chan, u16 cfgCtl, 4758 struct ath9k_channel *chan, u16 cfgCtl,
4761 u8 twiceAntennaReduction, 4759 u8 twiceAntennaReduction,
@@ -4764,16 +4762,70 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4764{ 4762{
4765 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 4763 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
4766 struct ath_common *common = ath9k_hw_common(ah); 4764 struct ath_common *common = ath9k_hw_common(ah);
4765 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4766 struct ar9300_modal_eep_header *modal_hdr;
4767 u8 targetPowerValT2[ar9300RateSize]; 4767 u8 targetPowerValT2[ar9300RateSize];
4768 unsigned int i = 0; 4768 u8 target_power_val_t2_eep[ar9300RateSize];
4769 unsigned int i = 0, paprd_scale_factor = 0;
4770 u8 pwr_idx, min_pwridx = 0;
4769 4771
4770 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2); 4772 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
4773
4774 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
4775 if (IS_CHAN_2GHZ(chan))
4776 modal_hdr = &eep->modalHeader2G;
4777 else
4778 modal_hdr = &eep->modalHeader5G;
4779
4780 ah->paprd_ratemask =
4781 le32_to_cpu(modal_hdr->papdRateMaskHt20) &
4782 AR9300_PAPRD_RATE_MASK;
4783
4784 ah->paprd_ratemask_ht40 =
4785 le32_to_cpu(modal_hdr->papdRateMaskHt40) &
4786 AR9300_PAPRD_RATE_MASK;
4787
4788 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
4789 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
4790 ALL_TARGET_HT20_0_8_16;
4791
4792 if (!ah->paprd_table_write_done) {
4793 memcpy(target_power_val_t2_eep, targetPowerValT2,
4794 sizeof(targetPowerValT2));
4795 for (i = 0; i < 24; i++) {
4796 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
4797 if (ah->paprd_ratemask & (1 << i)) {
4798 if (targetPowerValT2[pwr_idx] &&
4799 targetPowerValT2[pwr_idx] ==
4800 target_power_val_t2_eep[pwr_idx])
4801 targetPowerValT2[pwr_idx] -=
4802 paprd_scale_factor;
4803 }
4804 }
4805 }
4806 memcpy(target_power_val_t2_eep, targetPowerValT2,
4807 sizeof(targetPowerValT2));
4808 }
4809
4771 ar9003_hw_set_power_per_rate_table(ah, chan, 4810 ar9003_hw_set_power_per_rate_table(ah, chan,
4772 targetPowerValT2, cfgCtl, 4811 targetPowerValT2, cfgCtl,
4773 twiceAntennaReduction, 4812 twiceAntennaReduction,
4774 twiceMaxRegulatoryPower, 4813 twiceMaxRegulatoryPower,
4775 powerLimit); 4814 powerLimit);
4776 4815
4816 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
4817 for (i = 0; i < ar9300RateSize; i++) {
4818 if ((ah->paprd_ratemask & (1 << i)) &&
4819 (abs(targetPowerValT2[i] -
4820 target_power_val_t2_eep[i]) >
4821 paprd_scale_factor)) {
4822 ah->paprd_ratemask &= ~(1 << i);
4823 ath_dbg(common, ATH_DBG_EEPROM,
4824 "paprd disabled for mcs %d\n", i);
4825 }
4826 }
4827 }
4828
4777 regulatory->max_power_level = 0; 4829 regulatory->max_power_level = 0;
4778 for (i = 0; i < ar9300RateSize; i++) { 4830 for (i = 0; i < ar9300RateSize; i++) {
4779 if (targetPowerValT2[i] > regulatory->max_power_level) 4831 if (targetPowerValT2[i] > regulatory->max_power_level)
@@ -4811,6 +4863,19 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4811 /* Write target power array to registers */ 4863 /* Write target power array to registers */
4812 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); 4864 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
4813 ar9003_hw_calibration_apply(ah, chan->channel); 4865 ar9003_hw_calibration_apply(ah, chan->channel);
4866
4867 if (IS_CHAN_2GHZ(chan)) {
4868 if (IS_CHAN_HT40(chan))
4869 i = ALL_TARGET_HT40_0_8_16;
4870 else
4871 i = ALL_TARGET_HT20_0_8_16;
4872 } else {
4873 if (IS_CHAN_HT40(chan))
4874 i = ALL_TARGET_HT40_7;
4875 else
4876 i = ALL_TARGET_HT20_7;
4877 }
4878 ah->paprd_target_power = targetPowerValT2[i];
4814} 4879}
4815 4880
4816static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah, 4881static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
@@ -4843,14 +4908,33 @@ u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz)
4843 return eep->modalHeader5G.spurChans; 4908 return eep->modalHeader5G.spurChans;
4844} 4909}
4845 4910
4911unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
4912 struct ath9k_channel *chan)
4913{
4914 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
4915
4916 if (IS_CHAN_2GHZ(chan))
4917 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
4918 AR9300_PAPRD_SCALE_1);
4919 else {
4920 if (chan->channel >= 5700)
4921 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
4922 AR9300_PAPRD_SCALE_1);
4923 else if (chan->channel >= 5400)
4924 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
4925 AR9300_PAPRD_SCALE_2);
4926 else
4927 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
4928 AR9300_PAPRD_SCALE_1);
4929 }
4930}
4931
4846const struct eeprom_ops eep_ar9300_ops = { 4932const struct eeprom_ops eep_ar9300_ops = {
4847 .check_eeprom = ath9k_hw_ar9300_check_eeprom, 4933 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
4848 .get_eeprom = ath9k_hw_ar9300_get_eeprom, 4934 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
4849 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom, 4935 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
4850 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver, 4936 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
4851 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev, 4937 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
4852 .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
4853 .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
4854 .set_board_values = ath9k_hw_ar9300_set_board_values, 4938 .set_board_values = ath9k_hw_ar9300_set_board_values,
4855 .set_addac = ath9k_hw_ar9300_set_addac, 4939 .set_addac = ath9k_hw_ar9300_set_addac,
4856 .set_txpower = ath9k_hw_ar9300_set_txpower, 4940 .set_txpower = ath9k_hw_ar9300_set_txpower,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 33503217dab3..afb0b5ee1865 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -20,47 +20,22 @@
20/* #define AR9300_NUM_CTLS 21 */ 20/* #define AR9300_NUM_CTLS 21 */
21#define AR9300_NUM_CTLS_5G 9 21#define AR9300_NUM_CTLS_5G 9
22#define AR9300_NUM_CTLS_2G 12 22#define AR9300_NUM_CTLS_2G 12
23#define AR9300_CTL_MODE_M 0xF
24#define AR9300_NUM_BAND_EDGES_5G 8 23#define AR9300_NUM_BAND_EDGES_5G 8
25#define AR9300_NUM_BAND_EDGES_2G 4 24#define AR9300_NUM_BAND_EDGES_2G 4
26#define AR9300_NUM_PD_GAINS 4
27#define AR9300_PD_GAINS_IN_MASK 4
28#define AR9300_PD_GAIN_ICEPTS 5
29#define AR9300_EEPROM_MODAL_SPURS 5
30#define AR9300_MAX_RATE_POWER 63
31#define AR9300_NUM_PDADC_VALUES 128
32#define AR9300_NUM_RATES 16
33#define AR9300_BCHAN_UNUSED 0xFF
34#define AR9300_MAX_PWR_RANGE_IN_HALF_DB 64
35#define AR9300_OPFLAGS_11A 0x01
36#define AR9300_OPFLAGS_11G 0x02
37#define AR9300_OPFLAGS_5G_HT40 0x04
38#define AR9300_OPFLAGS_2G_HT40 0x08
39#define AR9300_OPFLAGS_5G_HT20 0x10
40#define AR9300_OPFLAGS_2G_HT20 0x20
41#define AR9300_EEPMISC_BIG_ENDIAN 0x01 25#define AR9300_EEPMISC_BIG_ENDIAN 0x01
42#define AR9300_EEPMISC_WOW 0x02 26#define AR9300_EEPMISC_WOW 0x02
43#define AR9300_CUSTOMER_DATA_SIZE 20 27#define AR9300_CUSTOMER_DATA_SIZE 20
44 28
45#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
46#define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x)) 29#define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x))
47#define AR9300_MAX_CHAINS 3 30#define AR9300_MAX_CHAINS 3
48#define AR9300_ANT_16S 25 31#define AR9300_ANT_16S 25
49#define AR9300_FUTURE_MODAL_SZ 6 32#define AR9300_FUTURE_MODAL_SZ 6
50 33
51#define AR9300_NUM_ANT_CHAIN_FIELDS 7 34#define AR9300_PAPRD_RATE_MASK 0x01ffffff
52#define AR9300_NUM_ANT_COMMON_FIELDS 4 35#define AR9300_PAPRD_SCALE_1 0x0e000000
53#define AR9300_SIZE_ANT_CHAIN_FIELD 3 36#define AR9300_PAPRD_SCALE_1_S 25
54#define AR9300_SIZE_ANT_COMMON_FIELD 4 37#define AR9300_PAPRD_SCALE_2 0x70000000
55#define AR9300_ANT_CHAIN_MASK 0x7 38#define AR9300_PAPRD_SCALE_2_S 28
56#define AR9300_ANT_COMMON_MASK 0xf
57#define AR9300_CHAIN_0_IDX 0
58#define AR9300_CHAIN_1_IDX 1
59#define AR9300_CHAIN_2_IDX 2
60
61#define AR928X_NUM_ANT_CHAIN_FIELDS 6
62#define AR928X_SIZE_ANT_CHAIN_FIELD 2
63#define AR928X_ANT_CHAIN_MASK 0x3
64 39
65/* Delta from which to start power to pdadc table */ 40/* Delta from which to start power to pdadc table */
66/* This offset is used in both open loop and closed loop power control 41/* This offset is used in both open loop and closed loop power control
@@ -71,12 +46,8 @@
71 */ 46 */
72#define AR9300_PWR_TABLE_OFFSET 0 47#define AR9300_PWR_TABLE_OFFSET 0
73 48
74/* enable flags for voltage and temp compensation */
75#define ENABLE_TEMP_COMPENSATION 0x01
76#define ENABLE_VOLT_COMPENSATION 0x02
77/* byte addressable */ 49/* byte addressable */
78#define AR9300_EEPROM_SIZE (16*1024) 50#define AR9300_EEPROM_SIZE (16*1024)
79#define FIXED_CCA_THRESHOLD 15
80 51
81#define AR9300_BASE_ADDR_4K 0xfff 52#define AR9300_BASE_ADDR_4K 0xfff
82#define AR9300_BASE_ADDR 0x3ff 53#define AR9300_BASE_ADDR 0x3ff
@@ -226,7 +197,7 @@ struct ar9300_modal_eep_header {
226 int8_t tempSlope; 197 int8_t tempSlope;
227 int8_t voltSlope; 198 int8_t voltSlope;
228 /* spur channels in usual fbin coding format */ 199 /* spur channels in usual fbin coding format */
229 u8 spurChans[AR9300_EEPROM_MODAL_SPURS]; 200 u8 spurChans[AR_EEPROM_MODAL_SPURS];
230 /* 3 Check if the register is per chain */ 201 /* 3 Check if the register is per chain */
231 int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS]; 202 int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS];
232 u8 ob[AR9300_MAX_CHAINS]; 203 u8 ob[AR9300_MAX_CHAINS];
@@ -344,4 +315,7 @@ s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah);
344s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah); 315s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah);
345 316
346u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz); 317u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz);
318
319unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
320 struct ath9k_channel *chan);
347#endif 321#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 21a5bfe354a0..6137634e46ca 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -21,18 +21,6 @@
21 21
22/* General hardware code for the AR9003 hadware family */ 22/* General hardware code for the AR9003 hadware family */
23 23
24static bool ar9003_hw_macversion_supported(u32 macversion)
25{
26 switch (macversion) {
27 case AR_SREV_VERSION_9300:
28 case AR_SREV_VERSION_9485:
29 return true;
30 default:
31 break;
32 }
33 return false;
34}
35
36/* 24/*
37 * The AR9003 family uses a new INI format (pre, core, post 25 * The AR9003 family uses a new INI format (pre, core, post
38 * arrays per subsystem). This provides support for the 26 * arrays per subsystem). This provides support for the
@@ -322,7 +310,6 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)
322 310
323 priv_ops->init_mode_regs = ar9003_hw_init_mode_regs; 311 priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
324 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs; 312 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
325 priv_ops->macversion_supported = ar9003_hw_macversion_supported;
326 313
327 ops->config_pci_powersave = ar9003_hw_configpcipowersave; 314 ops->config_pci_powersave = ar9003_hw_configpcipowersave;
328 315
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index bfba6a2b741d..b6e4ee48ef78 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -322,7 +322,6 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
322 if (txpower > ah->txpower_limit) 322 if (txpower > ah->txpower_limit)
323 txpower = ah->txpower_limit; 323 txpower = ah->txpower_limit;
324 324
325 txpower += ah->txpower_indexoffset;
326 if (txpower > 63) 325 if (txpower > 63)
327 txpower = 63; 326 txpower = 63;
328 327
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 74cff4365c43..356d2fd78822 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -19,6 +19,20 @@
19 19
20void ar9003_paprd_enable(struct ath_hw *ah, bool val) 20void ar9003_paprd_enable(struct ath_hw *ah, bool val)
21{ 21{
22 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
23 struct ath9k_channel *chan = ah->curchan;
24
25 if (val) {
26 ah->paprd_table_write_done = true;
27
28 ah->eep_ops->set_txpower(ah, chan,
29 ath9k_regd_get_ctl(regulatory, chan),
30 chan->chan->max_antenna_gain * 2,
31 chan->chan->max_power * 2,
32 min((u32) MAX_RATE_POWER,
33 (u32) regulatory->power_limit), false);
34 }
35
22 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, 36 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
23 AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); 37 AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
24 if (ah->caps.tx_chainmask & BIT(1)) 38 if (ah->caps.tx_chainmask & BIT(1))
@@ -30,10 +44,63 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
30} 44}
31EXPORT_SYMBOL(ar9003_paprd_enable); 45EXPORT_SYMBOL(ar9003_paprd_enable);
32 46
33static void ar9003_paprd_setup_single_table(struct ath_hw *ah) 47static int ar9003_get_training_power_2g(struct ath_hw *ah)
48{
49 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
50 struct ar9300_modal_eep_header *hdr = &eep->modalHeader2G;
51 unsigned int power, scale, delta;
52
53 scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), AR9300_PAPRD_SCALE_1);
54 power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
55 AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
56
57 delta = abs((int) ah->paprd_target_power - (int) power);
58 if (delta > scale)
59 return -1;
60
61 if (delta < 4)
62 power -= 4 - delta;
63
64 return power;
65}
66
67static int ar9003_get_training_power_5g(struct ath_hw *ah)
34{ 68{
69 struct ath_common *common = ath9k_hw_common(ah);
35 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 70 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
36 struct ar9300_modal_eep_header *hdr; 71 struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G;
72 struct ath9k_channel *chan = ah->curchan;
73 unsigned int power, scale, delta;
74
75 if (chan->channel >= 5700)
76 scale = MS(le32_to_cpu(hdr->papdRateMaskHt20),
77 AR9300_PAPRD_SCALE_1);
78 else if (chan->channel >= 5400)
79 scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
80 AR9300_PAPRD_SCALE_2);
81 else
82 scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
83 AR9300_PAPRD_SCALE_1);
84
85 if (IS_CHAN_HT40(chan))
86 power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8,
87 AR_PHY_POWERTX_RATE8_POWERTXHT40_5);
88 else
89 power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE6,
90 AR_PHY_POWERTX_RATE6_POWERTXHT20_5);
91
92 power += scale;
93 delta = abs((int) ah->paprd_target_power - (int) power);
94 if (delta > scale)
95 return -1;
96
97 power += 2 * get_streams(common->tx_chainmask);
98 return power;
99}
100
101static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
102{
103 struct ath_common *common = ath9k_hw_common(ah);
37 static const u32 ctrl0[3] = { 104 static const u32 ctrl0[3] = {
38 AR_PHY_PAPRD_CTRL0_B0, 105 AR_PHY_PAPRD_CTRL0_B0,
39 AR_PHY_PAPRD_CTRL0_B1, 106 AR_PHY_PAPRD_CTRL0_B1,
@@ -44,21 +111,30 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
44 AR_PHY_PAPRD_CTRL1_B1, 111 AR_PHY_PAPRD_CTRL1_B1,
45 AR_PHY_PAPRD_CTRL1_B2 112 AR_PHY_PAPRD_CTRL1_B2
46 }; 113 };
47 u32 am_mask, ht40_mask; 114 int training_power;
48 int i; 115 int i;
49 116
50 if (ah->curchan && IS_CHAN_5GHZ(ah->curchan)) 117 if (IS_CHAN_2GHZ(ah->curchan))
51 hdr = &eep->modalHeader5G; 118 training_power = ar9003_get_training_power_2g(ah);
52 else 119 else
53 hdr = &eep->modalHeader2G; 120 training_power = ar9003_get_training_power_5g(ah);
54
55 am_mask = le32_to_cpu(hdr->papdRateMaskHt20);
56 ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40);
57
58 REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask);
59 REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask);
60 REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask);
61 121
122 if (training_power < 0) {
123 ath_dbg(common, ATH_DBG_CALIBRATE,
124 "PAPRD target power delta out of range");
125 return -ERANGE;
126 }
127 ah->paprd_training_power = training_power;
128 ath_dbg(common, ATH_DBG_CALIBRATE,
129 "Training power: %d, Target power: %d\n",
130 ah->paprd_training_power, ah->paprd_target_power);
131
132 REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
133 ah->paprd_ratemask);
134 REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
135 ah->paprd_ratemask);
136 REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
137 ah->paprd_ratemask_ht40);
62 138
63 for (i = 0; i < ah->caps.max_txchains; i++) { 139 for (i = 0; i < ah->caps.max_txchains; i++) {
64 REG_RMW_FIELD(ah, ctrl0[i], 140 REG_RMW_FIELD(ah, ctrl0[i],
@@ -141,6 +217,7 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
141 AR_PHY_PAPRD_PRE_POST_SCALING, 185706); 217 AR_PHY_PAPRD_PRE_POST_SCALING, 185706);
142 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0, 218 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0,
143 AR_PHY_PAPRD_PRE_POST_SCALING, 175487); 219 AR_PHY_PAPRD_PRE_POST_SCALING, 175487);
220 return 0;
144} 221}
145 222
146static void ar9003_paprd_get_gain_table(struct ath_hw *ah) 223static void ar9003_paprd_get_gain_table(struct ath_hw *ah)
@@ -595,15 +672,10 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah,
595{ 672{
596 u32 *paprd_table_val = caldata->pa_table[chain]; 673 u32 *paprd_table_val = caldata->pa_table[chain];
597 u32 small_signal_gain = caldata->small_signal_gain[chain]; 674 u32 small_signal_gain = caldata->small_signal_gain[chain];
598 u32 training_power; 675 u32 training_power = ah->paprd_training_power;
599 u32 reg = 0; 676 u32 reg = 0;
600 int i; 677 int i;
601 678
602 training_power =
603 REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
604 AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
605 training_power -= 4;
606
607 if (chain == 0) 679 if (chain == 0)
608 reg = AR_PHY_PAPRD_MEM_TAB_B0; 680 reg = AR_PHY_PAPRD_MEM_TAB_B0;
609 else if (chain == 1) 681 else if (chain == 1)
@@ -643,14 +715,8 @@ EXPORT_SYMBOL(ar9003_paprd_populate_single_table);
643 715
644int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) 716int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
645{ 717{
646
647 unsigned int i, desired_gain, gain_index; 718 unsigned int i, desired_gain, gain_index;
648 unsigned int train_power; 719 unsigned int train_power = ah->paprd_training_power;
649
650 train_power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
651 AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
652
653 train_power = train_power - 4;
654 720
655 desired_gain = ar9003_get_desired_gain(ah, chain, train_power); 721 desired_gain = ar9003_get_desired_gain(ah, chain, train_power);
656 722
@@ -716,7 +782,12 @@ EXPORT_SYMBOL(ar9003_paprd_create_curve);
716 782
717int ar9003_paprd_init_table(struct ath_hw *ah) 783int ar9003_paprd_init_table(struct ath_hw *ah)
718{ 784{
719 ar9003_paprd_setup_single_table(ah); 785 int ret;
786
787 ret = ar9003_paprd_setup_single_table(ah);
788 if (ret < 0)
789 return ret;
790
720 ar9003_paprd_get_gain_table(ah); 791 ar9003_paprd_get_gain_table(ah);
721 return 0; 792 return 0;
722} 793}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index da4a571304da..8d60f4f09acc 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -578,10 +578,7 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah,
578 u32 reg = INI_RA(iniArr, i, 0); 578 u32 reg = INI_RA(iniArr, i, 0);
579 u32 val = INI_RA(iniArr, i, column); 579 u32 val = INI_RA(iniArr, i, column);
580 580
581 if (reg >= 0x16000 && reg < 0x17000) 581 REG_WRITE(ah, reg, val);
582 ath9k_hw_analog_shift_regwrite(ah, reg, val);
583 else
584 REG_WRITE(ah, reg, val);
585 582
586 DO_DELAY(regWrites); 583 DO_DELAY(regWrites);
587 } 584 }
@@ -748,28 +745,6 @@ static void ar9003_hw_rfbus_done(struct ath_hw *ah)
748 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); 745 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
749} 746}
750 747
751/*
752 * Set the interrupt and GPIO values so the ISR can disable RF
753 * on a switch signal. Assumes GPIO port and interrupt polarity
754 * are set prior to call.
755 */
756static void ar9003_hw_enable_rfkill(struct ath_hw *ah)
757{
758 /* Connect rfsilent_bb_l to baseband */
759 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
760 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
761 /* Set input mux for rfsilent_bb_l to GPIO #0 */
762 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
763 AR_GPIO_INPUT_MUX2_RFSILENT);
764
765 /*
766 * Configure the desired GPIO port for input and
767 * enable baseband rf silence.
768 */
769 ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
770 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
771}
772
773static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value) 748static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
774{ 749{
775 u32 v = REG_READ(ah, AR_PHY_CCK_DETECT); 750 u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
@@ -1206,7 +1181,6 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1206 priv_ops->set_delta_slope = ar9003_hw_set_delta_slope; 1181 priv_ops->set_delta_slope = ar9003_hw_set_delta_slope;
1207 priv_ops->rfbus_req = ar9003_hw_rfbus_req; 1182 priv_ops->rfbus_req = ar9003_hw_rfbus_req;
1208 priv_ops->rfbus_done = ar9003_hw_rfbus_done; 1183 priv_ops->rfbus_done = ar9003_hw_rfbus_done;
1209 priv_ops->enable_rfkill = ar9003_hw_enable_rfkill;
1210 priv_ops->set_diversity = ar9003_hw_set_diversity; 1184 priv_ops->set_diversity = ar9003_hw_set_diversity;
1211 priv_ops->ani_control = ar9003_hw_ani_control; 1185 priv_ops->ani_control = ar9003_hw_ani_control;
1212 priv_ops->do_getnf = ar9003_hw_do_getnf; 1186 priv_ops->do_getnf = ar9003_hw_do_getnf;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 6f811c7ada05..59bab6bd8a74 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -1090,6 +1090,14 @@
1090#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0 0x3F 1090#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0 0x3F
1091#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S 0 1091#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S 0
1092 1092
1093#define AR_PHY_POWERTX_RATE6 (AR_SM_BASE + 0x1d4)
1094#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5 0x3F00
1095#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5_S 8
1096
1097#define AR_PHY_POWERTX_RATE8 (AR_SM_BASE + 0x1dc)
1098#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5 0x3F00
1099#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S 8
1100
1093void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); 1101void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
1094 1102
1095#endif /* AR9003_PHY_H */ 1103#endif /* AR9003_PHY_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 9b5501f90010..2c31f5142eda 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -57,6 +57,8 @@ struct ath_node;
57 57
58#define A_MAX(a, b) ((a) > (b) ? (a) : (b)) 58#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
59 59
60#define ATH9K_PM_QOS_DEFAULT_VALUE 55
61
60#define TSF_TO_TU(_h,_l) \ 62#define TSF_TO_TU(_h,_l) \
61 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) 63 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
62 64
@@ -187,6 +189,7 @@ struct ath_txq {
187 struct list_head axq_q; 189 struct list_head axq_q;
188 spinlock_t axq_lock; 190 spinlock_t axq_lock;
189 u32 axq_depth; 191 u32 axq_depth;
192 u32 axq_ampdu_depth;
190 bool stopped; 193 bool stopped;
191 bool axq_tx_inprogress; 194 bool axq_tx_inprogress;
192 struct list_head axq_acq; 195 struct list_head axq_acq;
@@ -663,6 +666,7 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
663extern struct ieee80211_ops ath9k_ops; 666extern struct ieee80211_ops ath9k_ops;
664extern int modparam_nohwcrypt; 667extern int modparam_nohwcrypt;
665extern int led_blink; 668extern int led_blink;
669extern int ath9k_pm_qos_value;
666 670
667irqreturn_t ath_isr(int irq, void *dev); 671irqreturn_t ath_isr(int irq, void *dev);
668int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, 672int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
@@ -671,7 +675,6 @@ void ath9k_deinit_device(struct ath_softc *sc);
671void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); 675void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
672void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, 676void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
673 struct ath9k_channel *ichan); 677 struct ath9k_channel *ichan);
674void ath_update_chainmask(struct ath_softc *sc, int is_ht);
675int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, 678int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
676 struct ath9k_channel *hchan); 679 struct ath9k_channel *hchan);
677 680
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index fda533cfd881..d05163159572 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -234,7 +234,7 @@ void ath9k_hw_get_target_powers(struct ath_hw *ah,
234u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, 234u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
235 bool is2GHz, int num_band_edges) 235 bool is2GHz, int num_band_edges)
236{ 236{
237 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 237 u16 twiceMaxEdgePower = MAX_RATE_POWER;
238 int i; 238 int i;
239 239
240 for (i = 0; (i < num_band_edges) && 240 for (i = 0; (i < num_band_edges) &&
@@ -279,6 +279,219 @@ void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
279 } 279 }
280} 280}
281 281
282void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
283 struct ath9k_channel *chan,
284 void *pRawDataSet,
285 u8 *bChans, u16 availPiers,
286 u16 tPdGainOverlap,
287 u16 *pPdGainBoundaries, u8 *pPDADCValues,
288 u16 numXpdGains)
289{
290 int i, j, k;
291 int16_t ss;
292 u16 idxL = 0, idxR = 0, numPiers;
293 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
294 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
295 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
296 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
297 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
298 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
299
300 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
301 u8 minPwrT4[AR5416_NUM_PD_GAINS];
302 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
303 int16_t vpdStep;
304 int16_t tmpVal;
305 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
306 bool match;
307 int16_t minDelta = 0;
308 struct chan_centers centers;
309 int pdgain_boundary_default;
310 struct cal_data_per_freq *data_def = pRawDataSet;
311 struct cal_data_per_freq_4k *data_4k = pRawDataSet;
312 struct cal_data_per_freq_ar9287 *data_9287 = pRawDataSet;
313 bool eeprom_4k = AR_SREV_9285(ah) || AR_SREV_9271(ah);
314 int intercepts;
315
316 if (AR_SREV_9287(ah))
317 intercepts = AR9287_PD_GAIN_ICEPTS;
318 else
319 intercepts = AR5416_PD_GAIN_ICEPTS;
320
321 memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS);
322 ath9k_hw_get_channel_centers(ah, chan, &centers);
323
324 for (numPiers = 0; numPiers < availPiers; numPiers++) {
325 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
326 break;
327 }
328
329 match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
330 IS_CHAN_2GHZ(chan)),
331 bChans, numPiers, &idxL, &idxR);
332
333 if (match) {
334 if (AR_SREV_9287(ah)) {
335 /* FIXME: array overrun? */
336 for (i = 0; i < numXpdGains; i++) {
337 minPwrT4[i] = data_9287[idxL].pwrPdg[i][0];
338 maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4];
339 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
340 data_9287[idxL].pwrPdg[i],
341 data_9287[idxL].vpdPdg[i],
342 intercepts,
343 vpdTableI[i]);
344 }
345 } else if (eeprom_4k) {
346 for (i = 0; i < numXpdGains; i++) {
347 minPwrT4[i] = data_4k[idxL].pwrPdg[i][0];
348 maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4];
349 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
350 data_4k[idxL].pwrPdg[i],
351 data_4k[idxL].vpdPdg[i],
352 intercepts,
353 vpdTableI[i]);
354 }
355 } else {
356 for (i = 0; i < numXpdGains; i++) {
357 minPwrT4[i] = data_def[idxL].pwrPdg[i][0];
358 maxPwrT4[i] = data_def[idxL].pwrPdg[i][4];
359 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
360 data_def[idxL].pwrPdg[i],
361 data_def[idxL].vpdPdg[i],
362 intercepts,
363 vpdTableI[i]);
364 }
365 }
366 } else {
367 for (i = 0; i < numXpdGains; i++) {
368 if (AR_SREV_9287(ah)) {
369 pVpdL = data_9287[idxL].vpdPdg[i];
370 pPwrL = data_9287[idxL].pwrPdg[i];
371 pVpdR = data_9287[idxR].vpdPdg[i];
372 pPwrR = data_9287[idxR].pwrPdg[i];
373 } else if (eeprom_4k) {
374 pVpdL = data_4k[idxL].vpdPdg[i];
375 pPwrL = data_4k[idxL].pwrPdg[i];
376 pVpdR = data_4k[idxR].vpdPdg[i];
377 pPwrR = data_4k[idxR].pwrPdg[i];
378 } else {
379 pVpdL = data_def[idxL].vpdPdg[i];
380 pPwrL = data_def[idxL].pwrPdg[i];
381 pVpdR = data_def[idxR].vpdPdg[i];
382 pPwrR = data_def[idxR].pwrPdg[i];
383 }
384
385 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
386
387 maxPwrT4[i] =
388 min(pPwrL[intercepts - 1],
389 pPwrR[intercepts - 1]);
390
391
392 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
393 pPwrL, pVpdL,
394 intercepts,
395 vpdTableL[i]);
396 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
397 pPwrR, pVpdR,
398 intercepts,
399 vpdTableR[i]);
400
401 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
402 vpdTableI[i][j] =
403 (u8)(ath9k_hw_interpolate((u16)
404 FREQ2FBIN(centers.
405 synth_center,
406 IS_CHAN_2GHZ
407 (chan)),
408 bChans[idxL], bChans[idxR],
409 vpdTableL[i][j], vpdTableR[i][j]));
410 }
411 }
412 }
413
414 k = 0;
415
416 for (i = 0; i < numXpdGains; i++) {
417 if (i == (numXpdGains - 1))
418 pPdGainBoundaries[i] =
419 (u16)(maxPwrT4[i] / 2);
420 else
421 pPdGainBoundaries[i] =
422 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
423
424 pPdGainBoundaries[i] =
425 min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]);
426
427 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
428 minDelta = pPdGainBoundaries[0] - 23;
429 pPdGainBoundaries[0] = 23;
430 } else {
431 minDelta = 0;
432 }
433
434 if (i == 0) {
435 if (AR_SREV_9280_20_OR_LATER(ah))
436 ss = (int16_t)(0 - (minPwrT4[i] / 2));
437 else
438 ss = 0;
439 } else {
440 ss = (int16_t)((pPdGainBoundaries[i - 1] -
441 (minPwrT4[i] / 2)) -
442 tPdGainOverlap + 1 + minDelta);
443 }
444 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
445 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
446
447 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
448 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
449 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
450 ss++;
451 }
452
453 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
454 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
455 (minPwrT4[i] / 2));
456 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
457 tgtIndex : sizeCurrVpdTable;
458
459 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
460 pPDADCValues[k++] = vpdTableI[i][ss++];
461 }
462
463 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
464 vpdTableI[i][sizeCurrVpdTable - 2]);
465 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
466
467 if (tgtIndex >= maxIndex) {
468 while ((ss <= tgtIndex) &&
469 (k < (AR5416_NUM_PDADC_VALUES - 1))) {
470 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
471 (ss - maxIndex + 1) * vpdStep));
472 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
473 255 : tmpVal);
474 ss++;
475 }
476 }
477 }
478
479 if (eeprom_4k)
480 pdgain_boundary_default = 58;
481 else
482 pdgain_boundary_default = pPdGainBoundaries[i - 1];
483
484 while (i < AR5416_PD_GAINS_IN_MASK) {
485 pPdGainBoundaries[i] = pdgain_boundary_default;
486 i++;
487 }
488
489 while (k < AR5416_NUM_PDADC_VALUES) {
490 pPDADCValues[k] = pPDADCValues[k - 1];
491 k++;
492 }
493}
494
282int ath9k_hw_eeprom_init(struct ath_hw *ah) 495int ath9k_hw_eeprom_init(struct ath_hw *ah)
283{ 496{
284 int status; 497 int status;
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 8b9885b5243f..f6f09d1378f4 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -17,6 +17,8 @@
17#ifndef EEPROM_H 17#ifndef EEPROM_H
18#define EEPROM_H 18#define EEPROM_H
19 19
20#define AR_EEPROM_MODAL_SPURS 5
21
20#include "../ath.h" 22#include "../ath.h"
21#include <net/cfg80211.h> 23#include <net/cfg80211.h>
22#include "ar9003_eeprom.h" 24#include "ar9003_eeprom.h"
@@ -149,8 +151,6 @@
149#define AR5416_NUM_PD_GAINS 4 151#define AR5416_NUM_PD_GAINS 4
150#define AR5416_PD_GAINS_IN_MASK 4 152#define AR5416_PD_GAINS_IN_MASK 4
151#define AR5416_PD_GAIN_ICEPTS 5 153#define AR5416_PD_GAIN_ICEPTS 5
152#define AR5416_EEPROM_MODAL_SPURS 5
153#define AR5416_MAX_RATE_POWER 63
154#define AR5416_NUM_PDADC_VALUES 128 154#define AR5416_NUM_PDADC_VALUES 128
155#define AR5416_BCHAN_UNUSED 0xFF 155#define AR5416_BCHAN_UNUSED 0xFF
156#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64 156#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
@@ -175,8 +175,6 @@
175#define AR5416_EEP4K_NUM_CTLS 12 175#define AR5416_EEP4K_NUM_CTLS 12
176#define AR5416_EEP4K_NUM_BAND_EDGES 4 176#define AR5416_EEP4K_NUM_BAND_EDGES 4
177#define AR5416_EEP4K_NUM_PD_GAINS 2 177#define AR5416_EEP4K_NUM_PD_GAINS 2
178#define AR5416_EEP4K_PD_GAINS_IN_MASK 4
179#define AR5416_EEP4K_PD_GAIN_ICEPTS 5
180#define AR5416_EEP4K_MAX_CHAINS 1 178#define AR5416_EEP4K_MAX_CHAINS 1
181 179
182#define AR9280_TX_GAIN_TABLE_SIZE 22 180#define AR9280_TX_GAIN_TABLE_SIZE 22
@@ -198,35 +196,12 @@
198#define AR9287_NUM_2G_40_TARGET_POWERS 3 196#define AR9287_NUM_2G_40_TARGET_POWERS 3
199#define AR9287_NUM_CTLS 12 197#define AR9287_NUM_CTLS 12
200#define AR9287_NUM_BAND_EDGES 4 198#define AR9287_NUM_BAND_EDGES 4
201#define AR9287_NUM_PD_GAINS 4
202#define AR9287_PD_GAINS_IN_MASK 4
203#define AR9287_PD_GAIN_ICEPTS 1 199#define AR9287_PD_GAIN_ICEPTS 1
204#define AR9287_EEPROM_MODAL_SPURS 5
205#define AR9287_MAX_RATE_POWER 63
206#define AR9287_NUM_PDADC_VALUES 128
207#define AR9287_NUM_RATES 16
208#define AR9287_BCHAN_UNUSED 0xFF
209#define AR9287_MAX_PWR_RANGE_IN_HALF_DB 64
210#define AR9287_OPFLAGS_11A 0x01
211#define AR9287_OPFLAGS_11G 0x02
212#define AR9287_OPFLAGS_2G_HT40 0x08
213#define AR9287_OPFLAGS_2G_HT20 0x20
214#define AR9287_OPFLAGS_5G_HT40 0x04
215#define AR9287_OPFLAGS_5G_HT20 0x10
216#define AR9287_EEPMISC_BIG_ENDIAN 0x01 200#define AR9287_EEPMISC_BIG_ENDIAN 0x01
217#define AR9287_EEPMISC_WOW 0x02 201#define AR9287_EEPMISC_WOW 0x02
218#define AR9287_MAX_CHAINS 2 202#define AR9287_MAX_CHAINS 2
219#define AR9287_ANT_16S 32 203#define AR9287_ANT_16S 32
220#define AR9287_custdatasize 20 204
221
222#define AR9287_NUM_ANT_CHAIN_FIELDS 6
223#define AR9287_NUM_ANT_COMMON_FIELDS 4
224#define AR9287_SIZE_ANT_CHAIN_FIELD 2
225#define AR9287_SIZE_ANT_COMMON_FIELD 4
226#define AR9287_ANT_CHAIN_MASK 0x3
227#define AR9287_ANT_COMMON_MASK 0xf
228#define AR9287_CHAIN_0_IDX 0
229#define AR9287_CHAIN_1_IDX 1
230#define AR9287_DATA_SZ 32 205#define AR9287_DATA_SZ 32
231 206
232#define AR9287_PWR_TABLE_OFFSET_DB -5 207#define AR9287_PWR_TABLE_OFFSET_DB -5
@@ -396,7 +371,7 @@ struct modal_eep_header {
396 u16 xpaBiasLvlFreq[3]; 371 u16 xpaBiasLvlFreq[3];
397 u8 futureModal[6]; 372 u8 futureModal[6];
398 373
399 struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; 374 struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
400} __packed; 375} __packed;
401 376
402struct calDataPerFreqOpLoop { 377struct calDataPerFreqOpLoop {
@@ -464,7 +439,7 @@ struct modal_eep_4k_header {
464 u8 db2_4:4, reserved:4; 439 u8 db2_4:4, reserved:4;
465#endif 440#endif
466 u8 futureModal[4]; 441 u8 futureModal[4];
467 struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; 442 struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
468} __packed; 443} __packed;
469 444
470struct base_eep_ar9287_header { 445struct base_eep_ar9287_header {
@@ -522,7 +497,7 @@ struct modal_eep_ar9287_header {
522 u8 ob_qam; 497 u8 ob_qam;
523 u8 ob_pal_off; 498 u8 ob_pal_off;
524 u8 futureModal[30]; 499 u8 futureModal[30];
525 struct spur_chan spurChans[AR9287_EEPROM_MODAL_SPURS]; 500 struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
526} __packed; 501} __packed;
527 502
528struct cal_data_per_freq { 503struct cal_data_per_freq {
@@ -531,8 +506,8 @@ struct cal_data_per_freq {
531} __packed; 506} __packed;
532 507
533struct cal_data_per_freq_4k { 508struct cal_data_per_freq_4k {
534 u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS]; 509 u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
535 u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS]; 510 u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
536} __packed; 511} __packed;
537 512
538struct cal_target_power_leg { 513struct cal_target_power_leg {
@@ -558,8 +533,8 @@ struct cal_data_op_loop_ar9287 {
558} __packed; 533} __packed;
559 534
560struct cal_data_per_freq_ar9287 { 535struct cal_data_per_freq_ar9287 {
561 u8 pwrPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS]; 536 u8 pwrPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
562 u8 vpdPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS]; 537 u8 vpdPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
563} __packed; 538} __packed;
564 539
565union cal_data_per_freq_ar9287_u { 540union cal_data_per_freq_ar9287_u {
@@ -674,10 +649,6 @@ struct eeprom_ops {
674 bool (*fill_eeprom)(struct ath_hw *hw); 649 bool (*fill_eeprom)(struct ath_hw *hw);
675 int (*get_eeprom_ver)(struct ath_hw *hw); 650 int (*get_eeprom_ver)(struct ath_hw *hw);
676 int (*get_eeprom_rev)(struct ath_hw *hw); 651 int (*get_eeprom_rev)(struct ath_hw *hw);
677 u8 (*get_num_ant_config)(struct ath_hw *hw,
678 enum ath9k_hal_freq_band band);
679 u32 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
680 struct ath9k_channel *chan);
681 void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan); 652 void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
682 void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan); 653 void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
683 void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan, 654 void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
@@ -716,6 +687,14 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
716void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah); 687void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah);
717int ath9k_hw_eeprom_init(struct ath_hw *ah); 688int ath9k_hw_eeprom_init(struct ath_hw *ah);
718 689
690void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
691 struct ath9k_channel *chan,
692 void *pRawDataSet,
693 u8 *bChans, u16 availPiers,
694 u16 tPdGainOverlap,
695 u16 *pPdGainBoundaries, u8 *pPDADCValues,
696 u16 numXpdGains);
697
719#define ar5416_get_ntxchains(_txchainmask) \ 698#define ar5416_get_ntxchains(_txchainmask) \
720 (((_txchainmask >> 2) & 1) + \ 699 (((_txchainmask >> 2) & 1) + \
721 ((_txchainmask >> 1) & 1) + (_txchainmask & 1)) 700 ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 939fc7af86f8..fbdff7e47952 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -153,7 +153,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
153 eep->modalHeader.antCtrlChain[i] = integer; 153 eep->modalHeader.antCtrlChain[i] = integer;
154 } 154 }
155 155
156 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { 156 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
157 word = swab16(eep->modalHeader.spurChans[i].spurChan); 157 word = swab16(eep->modalHeader.spurChans[i].spurChan);
158 eep->modalHeader.spurChans[i].spurChan = word; 158 eep->modalHeader.spurChans[i].spurChan = word;
159 } 159 }
@@ -227,173 +227,6 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
227 } 227 }
228} 228}
229 229
230static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
231 struct ath9k_channel *chan,
232 struct cal_data_per_freq_4k *pRawDataSet,
233 u8 *bChans, u16 availPiers,
234 u16 tPdGainOverlap,
235 u16 *pPdGainBoundaries, u8 *pPDADCValues,
236 u16 numXpdGains)
237{
238#define TMP_VAL_VPD_TABLE \
239 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
240 int i, j, k;
241 int16_t ss;
242 u16 idxL = 0, idxR = 0, numPiers;
243 static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
244 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
245 static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
246 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
247 static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
248 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
249
250 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
251 u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
252 u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
253 int16_t vpdStep;
254 int16_t tmpVal;
255 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
256 bool match;
257 int16_t minDelta = 0;
258 struct chan_centers centers;
259#define PD_GAIN_BOUNDARY_DEFAULT 58;
260
261 memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
262 ath9k_hw_get_channel_centers(ah, chan, &centers);
263
264 for (numPiers = 0; numPiers < availPiers; numPiers++) {
265 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
266 break;
267 }
268
269 match = ath9k_hw_get_lower_upper_index(
270 (u8)FREQ2FBIN(centers.synth_center,
271 IS_CHAN_2GHZ(chan)), bChans, numPiers,
272 &idxL, &idxR);
273
274 if (match) {
275 for (i = 0; i < numXpdGains; i++) {
276 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
277 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
278 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
279 pRawDataSet[idxL].pwrPdg[i],
280 pRawDataSet[idxL].vpdPdg[i],
281 AR5416_EEP4K_PD_GAIN_ICEPTS,
282 vpdTableI[i]);
283 }
284 } else {
285 for (i = 0; i < numXpdGains; i++) {
286 pVpdL = pRawDataSet[idxL].vpdPdg[i];
287 pPwrL = pRawDataSet[idxL].pwrPdg[i];
288 pVpdR = pRawDataSet[idxR].vpdPdg[i];
289 pPwrR = pRawDataSet[idxR].pwrPdg[i];
290
291 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
292
293 maxPwrT4[i] =
294 min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1],
295 pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]);
296
297
298 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
299 pPwrL, pVpdL,
300 AR5416_EEP4K_PD_GAIN_ICEPTS,
301 vpdTableL[i]);
302 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
303 pPwrR, pVpdR,
304 AR5416_EEP4K_PD_GAIN_ICEPTS,
305 vpdTableR[i]);
306
307 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
308 vpdTableI[i][j] =
309 (u8)(ath9k_hw_interpolate((u16)
310 FREQ2FBIN(centers.
311 synth_center,
312 IS_CHAN_2GHZ
313 (chan)),
314 bChans[idxL], bChans[idxR],
315 vpdTableL[i][j], vpdTableR[i][j]));
316 }
317 }
318 }
319
320 k = 0;
321
322 for (i = 0; i < numXpdGains; i++) {
323 if (i == (numXpdGains - 1))
324 pPdGainBoundaries[i] =
325 (u16)(maxPwrT4[i] / 2);
326 else
327 pPdGainBoundaries[i] =
328 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
329
330 pPdGainBoundaries[i] =
331 min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
332
333 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
334 minDelta = pPdGainBoundaries[0] - 23;
335 pPdGainBoundaries[0] = 23;
336 } else {
337 minDelta = 0;
338 }
339
340 if (i == 0) {
341 if (AR_SREV_9280_20_OR_LATER(ah))
342 ss = (int16_t)(0 - (minPwrT4[i] / 2));
343 else
344 ss = 0;
345 } else {
346 ss = (int16_t)((pPdGainBoundaries[i - 1] -
347 (minPwrT4[i] / 2)) -
348 tPdGainOverlap + 1 + minDelta);
349 }
350 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
351 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
352
353 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
354 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
355 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
356 ss++;
357 }
358
359 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
360 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
361 (minPwrT4[i] / 2));
362 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
363 tgtIndex : sizeCurrVpdTable;
364
365 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
366 pPDADCValues[k++] = vpdTableI[i][ss++];
367
368 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
369 vpdTableI[i][sizeCurrVpdTable - 2]);
370 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
371
372 if (tgtIndex >= maxIndex) {
373 while ((ss <= tgtIndex) &&
374 (k < (AR5416_NUM_PDADC_VALUES - 1))) {
375 tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
376 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
377 255 : tmpVal);
378 ss++;
379 }
380 }
381 }
382
383 while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) {
384 pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT;
385 i++;
386 }
387
388 while (k < AR5416_NUM_PDADC_VALUES) {
389 pPDADCValues[k] = pPDADCValues[k - 1];
390 k++;
391 }
392
393 return;
394#undef TMP_VAL_VPD_TABLE
395}
396
397static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, 230static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
398 struct ath9k_channel *chan, 231 struct ath9k_channel *chan,
399 int16_t *pTxPowerIndexOffset) 232 int16_t *pTxPowerIndexOffset)
@@ -404,7 +237,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
404 u8 *pCalBChans = NULL; 237 u8 *pCalBChans = NULL;
405 u16 pdGainOverlap_t2; 238 u16 pdGainOverlap_t2;
406 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES]; 239 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
407 u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK]; 240 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
408 u16 numPiers, i, j; 241 u16 numPiers, i, j;
409 u16 numXpdGain, xpdMask; 242 u16 numXpdGain, xpdMask;
410 u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 }; 243 u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
@@ -426,12 +259,12 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
426 259
427 numXpdGain = 0; 260 numXpdGain = 0;
428 261
429 for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) { 262 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
430 if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) { 263 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
431 if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS) 264 if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
432 break; 265 break;
433 xpdGainValues[numXpdGain] = 266 xpdGainValues[numXpdGain] =
434 (u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i); 267 (u16)(AR5416_PD_GAINS_IN_MASK - i);
435 numXpdGain++; 268 numXpdGain++;
436 } 269 }
437 } 270 }
@@ -455,7 +288,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
455 if (pEepData->baseEepHeader.txMask & (1 << i)) { 288 if (pEepData->baseEepHeader.txMask & (1 << i)) {
456 pRawDataset = pEepData->calPierData2G[i]; 289 pRawDataset = pEepData->calPierData2G[i];
457 290
458 ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan, 291 ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
459 pRawDataset, pCalBChans, 292 pRawDataset, pCalBChans,
460 numPiers, pdGainOverlap_t2, 293 numPiers, pdGainOverlap_t2,
461 gainBoundaries, 294 gainBoundaries,
@@ -528,7 +361,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
528 int i; 361 int i;
529 int16_t twiceLargestAntenna; 362 int16_t twiceLargestAntenna;
530 u16 twiceMinEdgePower; 363 u16 twiceMinEdgePower;
531 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 364 u16 twiceMaxEdgePower = MAX_RATE_POWER;
532 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 365 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
533 u16 numCtlModes; 366 u16 numCtlModes;
534 const u16 *pCtlMode; 367 const u16 *pCtlMode;
@@ -537,7 +370,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
537 struct cal_ctl_data_4k *rep; 370 struct cal_ctl_data_4k *rep;
538 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 371 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
539 static const u16 tpScaleReductionTable[5] = 372 static const u16 tpScaleReductionTable[5] =
540 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; 373 { 0, 3, 6, 9, MAX_RATE_POWER };
541 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { 374 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
542 0, { 0, 0, 0, 0} 375 0, { 0, 0, 0, 0}
543 }; 376 };
@@ -613,7 +446,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
613 446
614 if (ah->eep_ops->get_eeprom_ver(ah) == 14 && 447 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
615 ah->eep_ops->get_eeprom_rev(ah) <= 2) 448 ah->eep_ops->get_eeprom_rev(ah) <= 2)
616 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 449 twiceMaxEdgePower = MAX_RATE_POWER;
617 450
618 for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) && 451 for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) &&
619 pEepData->ctlIndex[i]; i++) { 452 pEepData->ctlIndex[i]; i++) {
@@ -752,8 +585,8 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
752 regulatory->max_power_level = 0; 585 regulatory->max_power_level = 0;
753 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 586 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
754 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 587 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
755 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 588 if (ratesArray[i] > MAX_RATE_POWER)
756 ratesArray[i] = AR5416_MAX_RATE_POWER; 589 ratesArray[i] = MAX_RATE_POWER;
757 590
758 if (ratesArray[i] > regulatory->max_power_level) 591 if (ratesArray[i] > regulatory->max_power_level)
759 regulatory->max_power_level = ratesArray[i]; 592 regulatory->max_power_level = ratesArray[i];
@@ -937,8 +770,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
937 pModal = &eep->modalHeader; 770 pModal = &eep->modalHeader;
938 txRxAttenLocal = 23; 771 txRxAttenLocal = 23;
939 772
940 REG_WRITE(ah, AR_PHY_SWITCH_COM, 773 REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
941 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
942 774
943 /* Single chain for 4K EEPROM*/ 775 /* Single chain for 4K EEPROM*/
944 ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal); 776 ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal);
@@ -1154,21 +986,6 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1154 } 986 }
1155} 987}
1156 988
1157static u32 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
1158 struct ath9k_channel *chan)
1159{
1160 struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
1161 struct modal_eep_4k_header *pModal = &eep->modalHeader;
1162
1163 return pModal->antCtrlCommon;
1164}
1165
1166static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
1167 enum ath9k_hal_freq_band freq_band)
1168{
1169 return 1;
1170}
1171
1172static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 989static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1173{ 990{
1174#define EEP_MAP4K_SPURCHAN \ 991#define EEP_MAP4K_SPURCHAN \
@@ -1205,8 +1022,6 @@ const struct eeprom_ops eep_4k_ops = {
1205 .fill_eeprom = ath9k_hw_4k_fill_eeprom, 1022 .fill_eeprom = ath9k_hw_4k_fill_eeprom,
1206 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver, 1023 .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver,
1207 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev, 1024 .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev,
1208 .get_num_ant_config = ath9k_hw_4k_get_num_ant_config,
1209 .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg,
1210 .set_board_values = ath9k_hw_4k_set_board_values, 1025 .set_board_values = ath9k_hw_4k_set_board_values,
1211 .set_addac = ath9k_hw_4k_set_addac, 1026 .set_addac = ath9k_hw_4k_set_addac,
1212 .set_txpower = ath9k_hw_4k_set_txpower, 1027 .set_txpower = ath9k_hw_4k_set_txpower,
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 065402f2e402..9b6bc8a953bc 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -150,7 +150,7 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
150 eep->modalHeader.antCtrlChain[i] = integer; 150 eep->modalHeader.antCtrlChain[i] = integer;
151 } 151 }
152 152
153 for (i = 0; i < AR9287_EEPROM_MODAL_SPURS; i++) { 153 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
154 word = swab16(eep->modalHeader.spurChans[i].spurChan); 154 word = swab16(eep->modalHeader.spurChans[i].spurChan);
155 eep->modalHeader.spurChans[i].spurChan = word; 155 eep->modalHeader.spurChans[i].spurChan = word;
156 } 156 }
@@ -220,163 +220,6 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
220 } 220 }
221} 221}
222 222
223static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah,
224 struct ath9k_channel *chan,
225 struct cal_data_per_freq_ar9287 *pRawDataSet,
226 u8 *bChans, u16 availPiers,
227 u16 tPdGainOverlap,
228 u16 *pPdGainBoundaries,
229 u8 *pPDADCValues,
230 u16 numXpdGains)
231{
232#define TMP_VAL_VPD_TABLE \
233 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
234
235 int i, j, k;
236 int16_t ss;
237 u16 idxL = 0, idxR = 0, numPiers;
238 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
239 u8 minPwrT4[AR9287_NUM_PD_GAINS];
240 u8 maxPwrT4[AR9287_NUM_PD_GAINS];
241 int16_t vpdStep;
242 int16_t tmpVal;
243 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
244 bool match;
245 int16_t minDelta = 0;
246 struct chan_centers centers;
247 static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
248 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
249 static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
250 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
251 static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
252 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
253
254 memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
255 ath9k_hw_get_channel_centers(ah, chan, &centers);
256
257 for (numPiers = 0; numPiers < availPiers; numPiers++) {
258 if (bChans[numPiers] == AR9287_BCHAN_UNUSED)
259 break;
260 }
261
262 match = ath9k_hw_get_lower_upper_index(
263 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
264 bChans, numPiers, &idxL, &idxR);
265
266 if (match) {
267 for (i = 0; i < numXpdGains; i++) {
268 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
269 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
270 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
271 pRawDataSet[idxL].pwrPdg[i],
272 pRawDataSet[idxL].vpdPdg[i],
273 AR9287_PD_GAIN_ICEPTS,
274 vpdTableI[i]);
275 }
276 } else {
277 for (i = 0; i < numXpdGains; i++) {
278 pVpdL = pRawDataSet[idxL].vpdPdg[i];
279 pPwrL = pRawDataSet[idxL].pwrPdg[i];
280 pVpdR = pRawDataSet[idxR].vpdPdg[i];
281 pPwrR = pRawDataSet[idxR].pwrPdg[i];
282
283 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
284
285 maxPwrT4[i] = min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1],
286 pPwrR[AR9287_PD_GAIN_ICEPTS - 1]);
287
288 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
289 pPwrL, pVpdL,
290 AR9287_PD_GAIN_ICEPTS,
291 vpdTableL[i]);
292 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
293 pPwrR, pVpdR,
294 AR9287_PD_GAIN_ICEPTS,
295 vpdTableR[i]);
296
297 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
298 vpdTableI[i][j] = (u8)(ath9k_hw_interpolate(
299 (u16)FREQ2FBIN(centers. synth_center,
300 IS_CHAN_2GHZ(chan)),
301 bChans[idxL], bChans[idxR],
302 vpdTableL[i][j], vpdTableR[i][j]));
303 }
304 }
305 }
306
307 k = 0;
308
309 for (i = 0; i < numXpdGains; i++) {
310 if (i == (numXpdGains - 1))
311 pPdGainBoundaries[i] =
312 (u16)(maxPwrT4[i] / 2);
313 else
314 pPdGainBoundaries[i] =
315 (u16)((maxPwrT4[i] + minPwrT4[i+1]) / 4);
316
317 pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER,
318 pPdGainBoundaries[i]);
319
320
321 minDelta = 0;
322
323 if (i == 0) {
324 if (AR_SREV_9280_20_OR_LATER(ah))
325 ss = (int16_t)(0 - (minPwrT4[i] / 2));
326 else
327 ss = 0;
328 } else {
329 ss = (int16_t)((pPdGainBoundaries[i-1] -
330 (minPwrT4[i] / 2)) -
331 tPdGainOverlap + 1 + minDelta);
332 }
333
334 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
335 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
336
337 while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1))) {
338 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
339 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
340 ss++;
341 }
342
343 sizeCurrVpdTable = (u8)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
344 tgtIndex = (u8)(pPdGainBoundaries[i] +
345 tPdGainOverlap - (minPwrT4[i] / 2));
346 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
347 tgtIndex : sizeCurrVpdTable;
348
349 while ((ss < maxIndex) && (k < (AR9287_NUM_PDADC_VALUES - 1)))
350 pPDADCValues[k++] = vpdTableI[i][ss++];
351
352 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
353 vpdTableI[i][sizeCurrVpdTable - 2]);
354 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
355
356 if (tgtIndex > maxIndex) {
357 while ((ss <= tgtIndex) &&
358 (k < (AR9287_NUM_PDADC_VALUES - 1))) {
359 tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
360 pPDADCValues[k++] =
361 (u8)((tmpVal > 255) ? 255 : tmpVal);
362 ss++;
363 }
364 }
365 }
366
367 while (i < AR9287_PD_GAINS_IN_MASK) {
368 pPdGainBoundaries[i] = pPdGainBoundaries[i-1];
369 i++;
370 }
371
372 while (k < AR9287_NUM_PDADC_VALUES) {
373 pPDADCValues[k] = pPDADCValues[k-1];
374 k++;
375 }
376
377#undef TMP_VAL_VPD_TABLE
378}
379
380static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah, 223static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
381 struct ath9k_channel *chan, 224 struct ath9k_channel *chan,
382 struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop, 225 struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
@@ -389,7 +232,7 @@ static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
389 ath9k_hw_get_channel_centers(ah, chan, &centers); 232 ath9k_hw_get_channel_centers(ah, chan, &centers);
390 233
391 for (numPiers = 0; numPiers < availPiers; numPiers++) { 234 for (numPiers = 0; numPiers < availPiers; numPiers++) {
392 if (pCalChans[numPiers] == AR9287_BCHAN_UNUSED) 235 if (pCalChans[numPiers] == AR5416_BCHAN_UNUSED)
393 break; 236 break;
394 } 237 }
395 238
@@ -455,11 +298,11 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
455 struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop; 298 struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
456 u8 *pCalBChans = NULL; 299 u8 *pCalBChans = NULL;
457 u16 pdGainOverlap_t2; 300 u16 pdGainOverlap_t2;
458 u8 pdadcValues[AR9287_NUM_PDADC_VALUES]; 301 u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
459 u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK]; 302 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
460 u16 numPiers = 0, i, j; 303 u16 numPiers = 0, i, j;
461 u16 numXpdGain, xpdMask; 304 u16 numXpdGain, xpdMask;
462 u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0}; 305 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0};
463 u32 reg32, regOffset, regChainOffset, regval; 306 u32 reg32, regOffset, regChainOffset, regval;
464 int16_t modalIdx, diff = 0; 307 int16_t modalIdx, diff = 0;
465 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; 308 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
@@ -487,12 +330,12 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
487 numXpdGain = 0; 330 numXpdGain = 0;
488 331
489 /* Calculate the value of xpdgains from the xpdGain Mask */ 332 /* Calculate the value of xpdgains from the xpdGain Mask */
490 for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) { 333 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
491 if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) { 334 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
492 if (numXpdGain >= AR9287_NUM_PD_GAINS) 335 if (numXpdGain >= AR5416_NUM_PD_GAINS)
493 break; 336 break;
494 xpdGainValues[numXpdGain] = 337 xpdGainValues[numXpdGain] =
495 (u16)(AR9287_PD_GAINS_IN_MASK-i); 338 (u16)(AR5416_PD_GAINS_IN_MASK-i);
496 numXpdGain++; 339 numXpdGain++;
497 } 340 }
498 } 341 }
@@ -525,7 +368,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
525 (struct cal_data_per_freq_ar9287 *) 368 (struct cal_data_per_freq_ar9287 *)
526 pEepData->calPierData2G[i]; 369 pEepData->calPierData2G[i];
527 370
528 ath9k_hw_get_ar9287_gain_boundaries_pdadcs(ah, chan, 371 ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
529 pRawDataset, 372 pRawDataset,
530 pCalBChans, numPiers, 373 pCalBChans, numPiers,
531 pdGainOverlap_t2, 374 pdGainOverlap_t2,
@@ -561,13 +404,13 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
561 (int32_t)AR9287_PWR_TABLE_OFFSET_DB); 404 (int32_t)AR9287_PWR_TABLE_OFFSET_DB);
562 diff *= 2; 405 diff *= 2;
563 406
564 for (j = 0; j < ((u16)AR9287_NUM_PDADC_VALUES-diff); j++) 407 for (j = 0; j < ((u16)AR5416_NUM_PDADC_VALUES-diff); j++)
565 pdadcValues[j] = pdadcValues[j+diff]; 408 pdadcValues[j] = pdadcValues[j+diff];
566 409
567 for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff); 410 for (j = (u16)(AR5416_NUM_PDADC_VALUES-diff);
568 j < AR9287_NUM_PDADC_VALUES; j++) 411 j < AR5416_NUM_PDADC_VALUES; j++)
569 pdadcValues[j] = 412 pdadcValues[j] =
570 pdadcValues[AR9287_NUM_PDADC_VALUES-diff]; 413 pdadcValues[AR5416_NUM_PDADC_VALUES-diff];
571 } 414 }
572 415
573 if (!ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) { 416 if (!ath9k_hw_ar9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
@@ -610,9 +453,9 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
610#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 453#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
611 454
612 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 455 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
613 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 456 u16 twiceMaxEdgePower = MAX_RATE_POWER;
614 static const u16 tpScaleReductionTable[5] = 457 static const u16 tpScaleReductionTable[5] =
615 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; 458 { 0, 3, 6, 9, MAX_RATE_POWER };
616 int i; 459 int i;
617 int16_t twiceLargestAntenna; 460 int16_t twiceLargestAntenna;
618 struct cal_ctl_data_ar9287 *rep; 461 struct cal_ctl_data_ar9287 *rep;
@@ -877,8 +720,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
877 regulatory->max_power_level = 0; 720 regulatory->max_power_level = 0;
878 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 721 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
879 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 722 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
880 if (ratesArray[i] > AR9287_MAX_RATE_POWER) 723 if (ratesArray[i] > MAX_RATE_POWER)
881 ratesArray[i] = AR9287_MAX_RATE_POWER; 724 ratesArray[i] = MAX_RATE_POWER;
882 725
883 if (ratesArray[i] > regulatory->max_power_level) 726 if (ratesArray[i] > regulatory->max_power_level)
884 regulatory->max_power_level = ratesArray[i]; 727 regulatory->max_power_level = ratesArray[i];
@@ -1023,8 +866,7 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
1023 antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3); 866 antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3);
1024 } 867 }
1025 868
1026 REG_WRITE(ah, AR_PHY_SWITCH_COM, 869 REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
1027 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
1028 870
1029 for (i = 0; i < AR9287_MAX_CHAINS; i++) { 871 for (i = 0; i < AR9287_MAX_CHAINS; i++) {
1030 regChainOffset = i * 0x1000; 872 regChainOffset = i * 0x1000;
@@ -1125,21 +967,6 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
1125 pModal->xpaBiasLvl); 967 pModal->xpaBiasLvl);
1126} 968}
1127 969
1128static u8 ath9k_hw_ar9287_get_num_ant_config(struct ath_hw *ah,
1129 enum ath9k_hal_freq_band freq_band)
1130{
1131 return 1;
1132}
1133
1134static u32 ath9k_hw_ar9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
1135 struct ath9k_channel *chan)
1136{
1137 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
1138 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
1139
1140 return pModal->antCtrlCommon;
1141}
1142
1143static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah, 970static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah,
1144 u16 i, bool is2GHz) 971 u16 i, bool is2GHz)
1145{ 972{
@@ -1177,8 +1004,6 @@ const struct eeprom_ops eep_ar9287_ops = {
1177 .fill_eeprom = ath9k_hw_ar9287_fill_eeprom, 1004 .fill_eeprom = ath9k_hw_ar9287_fill_eeprom,
1178 .get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver, 1005 .get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver,
1179 .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev, 1006 .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev,
1180 .get_num_ant_config = ath9k_hw_ar9287_get_num_ant_config,
1181 .get_eeprom_antenna_cfg = ath9k_hw_ar9287_get_eeprom_antenna_cfg,
1182 .set_board_values = ath9k_hw_ar9287_set_board_values, 1007 .set_board_values = ath9k_hw_ar9287_set_board_values,
1183 .set_addac = ath9k_hw_ar9287_set_addac, 1008 .set_addac = ath9k_hw_ar9287_set_addac,
1184 .set_txpower = ath9k_hw_ar9287_set_txpower, 1009 .set_txpower = ath9k_hw_ar9287_set_txpower,
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 5bfa031545f4..088f141f2006 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -206,7 +206,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
206 pModal->antCtrlChain[i] = integer; 206 pModal->antCtrlChain[i] = integer;
207 } 207 }
208 208
209 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { 209 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
210 word = swab16(pModal->spurChans[i].spurChan); 210 word = swab16(pModal->spurChans[i].spurChan);
211 pModal->spurChans[i].spurChan = word; 211 pModal->spurChans[i].spurChan = word;
212 } 212 }
@@ -374,8 +374,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
374 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); 374 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
375 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; 375 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
376 376
377 REG_WRITE(ah, AR_PHY_SWITCH_COM, 377 REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon & 0xffff);
378 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
379 378
380 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 379 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
381 if (AR_SREV_9280(ah)) { 380 if (AR_SREV_9280(ah)) {
@@ -588,168 +587,6 @@ static void ath9k_hw_def_set_addac(struct ath_hw *ah,
588#undef XPA_LVL_FREQ 587#undef XPA_LVL_FREQ
589} 588}
590 589
591static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
592 struct ath9k_channel *chan,
593 struct cal_data_per_freq *pRawDataSet,
594 u8 *bChans, u16 availPiers,
595 u16 tPdGainOverlap,
596 u16 *pPdGainBoundaries, u8 *pPDADCValues,
597 u16 numXpdGains)
598{
599 int i, j, k;
600 int16_t ss;
601 u16 idxL = 0, idxR = 0, numPiers;
602 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
603 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
604 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
605 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
606 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
607 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
608
609 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
610 u8 minPwrT4[AR5416_NUM_PD_GAINS];
611 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
612 int16_t vpdStep;
613 int16_t tmpVal;
614 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
615 bool match;
616 int16_t minDelta = 0;
617 struct chan_centers centers;
618
619 memset(&minPwrT4, 0, AR9287_NUM_PD_GAINS);
620 ath9k_hw_get_channel_centers(ah, chan, &centers);
621
622 for (numPiers = 0; numPiers < availPiers; numPiers++) {
623 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
624 break;
625 }
626
627 match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
628 IS_CHAN_2GHZ(chan)),
629 bChans, numPiers, &idxL, &idxR);
630
631 if (match) {
632 for (i = 0; i < numXpdGains; i++) {
633 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
634 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
635 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
636 pRawDataSet[idxL].pwrPdg[i],
637 pRawDataSet[idxL].vpdPdg[i],
638 AR5416_PD_GAIN_ICEPTS,
639 vpdTableI[i]);
640 }
641 } else {
642 for (i = 0; i < numXpdGains; i++) {
643 pVpdL = pRawDataSet[idxL].vpdPdg[i];
644 pPwrL = pRawDataSet[idxL].pwrPdg[i];
645 pVpdR = pRawDataSet[idxR].vpdPdg[i];
646 pPwrR = pRawDataSet[idxR].pwrPdg[i];
647
648 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
649
650 maxPwrT4[i] =
651 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
652 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
653
654
655 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
656 pPwrL, pVpdL,
657 AR5416_PD_GAIN_ICEPTS,
658 vpdTableL[i]);
659 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
660 pPwrR, pVpdR,
661 AR5416_PD_GAIN_ICEPTS,
662 vpdTableR[i]);
663
664 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
665 vpdTableI[i][j] =
666 (u8)(ath9k_hw_interpolate((u16)
667 FREQ2FBIN(centers.
668 synth_center,
669 IS_CHAN_2GHZ
670 (chan)),
671 bChans[idxL], bChans[idxR],
672 vpdTableL[i][j], vpdTableR[i][j]));
673 }
674 }
675 }
676
677 k = 0;
678
679 for (i = 0; i < numXpdGains; i++) {
680 if (i == (numXpdGains - 1))
681 pPdGainBoundaries[i] =
682 (u16)(maxPwrT4[i] / 2);
683 else
684 pPdGainBoundaries[i] =
685 (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
686
687 pPdGainBoundaries[i] =
688 min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
689
690 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
691 minDelta = pPdGainBoundaries[0] - 23;
692 pPdGainBoundaries[0] = 23;
693 } else {
694 minDelta = 0;
695 }
696
697 if (i == 0) {
698 if (AR_SREV_9280_20_OR_LATER(ah))
699 ss = (int16_t)(0 - (minPwrT4[i] / 2));
700 else
701 ss = 0;
702 } else {
703 ss = (int16_t)((pPdGainBoundaries[i - 1] -
704 (minPwrT4[i] / 2)) -
705 tPdGainOverlap + 1 + minDelta);
706 }
707 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
708 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
709
710 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
711 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
712 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
713 ss++;
714 }
715
716 sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
717 tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
718 (minPwrT4[i] / 2));
719 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
720 tgtIndex : sizeCurrVpdTable;
721
722 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
723 pPDADCValues[k++] = vpdTableI[i][ss++];
724 }
725
726 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
727 vpdTableI[i][sizeCurrVpdTable - 2]);
728 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
729
730 if (tgtIndex >= maxIndex) {
731 while ((ss <= tgtIndex) &&
732 (k < (AR5416_NUM_PDADC_VALUES - 1))) {
733 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
734 (ss - maxIndex + 1) * vpdStep));
735 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
736 255 : tmpVal);
737 ss++;
738 }
739 }
740 }
741
742 while (i < AR5416_PD_GAINS_IN_MASK) {
743 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
744 i++;
745 }
746
747 while (k < AR5416_NUM_PDADC_VALUES) {
748 pPDADCValues[k] = pPDADCValues[k - 1];
749 k++;
750 }
751}
752
753static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah, 590static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah,
754 u16 *gb, 591 u16 *gb,
755 u16 numXpdGain, 592 u16 numXpdGain,
@@ -782,7 +619,7 @@ static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah,
782 /* Because of a hardware limitation, ensure the gain boundary 619 /* Because of a hardware limitation, ensure the gain boundary
783 * is not larger than (63 - overlap) 620 * is not larger than (63 - overlap)
784 */ 621 */
785 gb_limit = (u16)(AR5416_MAX_RATE_POWER - pdGainOverlap_t2); 622 gb_limit = (u16)(MAX_RATE_POWER - pdGainOverlap_t2);
786 623
787 for (k = 0; k < numXpdGain; k++) 624 for (k = 0; k < numXpdGain; k++)
788 gb[k] = (u16)min(gb_limit, gb[k]); 625 gb[k] = (u16)min(gb_limit, gb[k]);
@@ -916,7 +753,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
916 ath9k_olc_get_pdadcs(ah, pcdacIdx, 753 ath9k_olc_get_pdadcs(ah, pcdacIdx,
917 txPower/2, pdadcValues); 754 txPower/2, pdadcValues);
918 } else { 755 } else {
919 ath9k_hw_get_def_gain_boundaries_pdadcs(ah, 756 ath9k_hw_get_gain_boundaries_pdadcs(ah,
920 chan, pRawDataset, 757 chan, pRawDataset,
921 pCalBChans, numPiers, 758 pCalBChans, numPiers,
922 pdGainOverlap_t2, 759 pdGainOverlap_t2,
@@ -1001,9 +838,9 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
1001 838
1002 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 839 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1003 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 840 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
1004 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 841 u16 twiceMaxEdgePower = MAX_RATE_POWER;
1005 static const u16 tpScaleReductionTable[5] = 842 static const u16 tpScaleReductionTable[5] =
1006 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; 843 { 0, 3, 6, 9, MAX_RATE_POWER };
1007 844
1008 int i; 845 int i;
1009 int16_t twiceLargestAntenna; 846 int16_t twiceLargestAntenna;
@@ -1148,7 +985,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
1148 985
1149 if (ah->eep_ops->get_eeprom_ver(ah) == 14 && 986 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
1150 ah->eep_ops->get_eeprom_rev(ah) <= 2) 987 ah->eep_ops->get_eeprom_rev(ah) <= 2)
1151 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 988 twiceMaxEdgePower = MAX_RATE_POWER;
1152 989
1153 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { 990 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
1154 if ((((cfgCtl & ~CTL_MODE_M) | 991 if ((((cfgCtl & ~CTL_MODE_M) |
@@ -1293,8 +1130,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1293 regulatory->max_power_level = 0; 1130 regulatory->max_power_level = 0;
1294 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 1131 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
1295 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 1132 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
1296 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 1133 if (ratesArray[i] > MAX_RATE_POWER)
1297 ratesArray[i] = AR5416_MAX_RATE_POWER; 1134 ratesArray[i] = MAX_RATE_POWER;
1298 if (ratesArray[i] > regulatory->max_power_level) 1135 if (ratesArray[i] > regulatory->max_power_level)
1299 regulatory->max_power_level = ratesArray[i]; 1136 regulatory->max_power_level = ratesArray[i];
1300 } 1137 }
@@ -1426,34 +1263,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1426 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); 1263 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
1427} 1264}
1428 1265
1429static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
1430 enum ath9k_hal_freq_band freq_band)
1431{
1432 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1433 struct modal_eep_header *pModal =
1434 &(eep->modalHeader[freq_band]);
1435 struct base_eep_header *pBase = &eep->baseEepHeader;
1436 u8 num_ant_config;
1437
1438 num_ant_config = 1;
1439
1440 if (pBase->version >= 0x0E0D &&
1441 (pModal->lna_ctl & LNA_CTL_USE_ANT1))
1442 num_ant_config += 1;
1443
1444 return num_ant_config;
1445}
1446
1447static u32 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
1448 struct ath9k_channel *chan)
1449{
1450 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1451 struct modal_eep_header *pModal =
1452 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
1453
1454 return pModal->antCtrlCommon;
1455}
1456
1457static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) 1266static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
1458{ 1267{
1459#define EEP_DEF_SPURCHAN \ 1268#define EEP_DEF_SPURCHAN \
@@ -1490,8 +1299,6 @@ const struct eeprom_ops eep_def_ops = {
1490 .fill_eeprom = ath9k_hw_def_fill_eeprom, 1299 .fill_eeprom = ath9k_hw_def_fill_eeprom,
1491 .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver, 1300 .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver,
1492 .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev, 1301 .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev,
1493 .get_num_ant_config = ath9k_hw_def_get_num_ant_config,
1494 .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg,
1495 .set_board_values = ath9k_hw_def_set_board_values, 1302 .set_board_values = ath9k_hw_def_set_board_values,
1496 .set_addac = ath9k_hw_def_set_addac, 1303 .set_addac = ath9k_hw_def_set_addac,
1497 .set_txpower = ath9k_hw_def_set_txpower, 1304 .set_txpower = ath9k_hw_def_set_txpower,
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index d0918bd23b8e..22b68b3c8566 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -38,6 +38,7 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
38 { USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */ 38 { USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */
39 { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ 39 { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
40 { USB_DEVICE(0x040D, 0x3801) }, /* VIA */ 40 { USB_DEVICE(0x040D, 0x3801) }, /* VIA */
41 { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
41 42
42 { USB_DEVICE(0x0cf3, 0x7015), 43 { USB_DEVICE(0x0cf3, 0x7015),
43 .driver_info = AR9287_USB }, /* Atheros */ 44 .driver_info = AR9287_USB }, /* Atheros */
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 20ea75a44e52..dd17909bd903 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1170,9 +1170,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
1170 /* setup initial channel */ 1170 /* setup initial channel */
1171 init_channel = ath9k_cmn_get_curchannel(hw, ah); 1171 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1172 1172
1173 /* Reset SERDES registers */
1174 ath9k_hw_configpcipowersave(ah, 0, 0);
1175
1176 ath9k_hw_htc_resetinit(ah); 1173 ath9k_hw_htc_resetinit(ah);
1177 ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false); 1174 ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
1178 if (ret) { 1175 if (ret) {
@@ -1258,7 +1255,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1258 1255
1259 ath9k_hw_phy_disable(ah); 1256 ath9k_hw_phy_disable(ah);
1260 ath9k_hw_disable(ah); 1257 ath9k_hw_disable(ah);
1261 ath9k_hw_configpcipowersave(ah, 1, 1);
1262 ath9k_htc_ps_restore(priv); 1258 ath9k_htc_ps_restore(priv);
1263 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); 1259 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1264 1260
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 31fad82239b3..33f36029fa4f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -251,7 +251,7 @@ void ath9k_tx_tasklet(unsigned long data)
251 ista = (struct ath9k_htc_sta *)sta->drv_priv; 251 ista = (struct ath9k_htc_sta *)sta->drv_priv;
252 252
253 if (ath9k_htc_check_tx_aggr(priv, ista, tid)) { 253 if (ath9k_htc_check_tx_aggr(priv, ista, tid)) {
254 ieee80211_start_tx_ba_session(sta, tid); 254 ieee80211_start_tx_ba_session(sta, tid, 0);
255 spin_lock_bh(&priv->tx_lock); 255 spin_lock_bh(&priv->tx_lock);
256 ista->tid_state[tid] = AGGR_PROGRESS; 256 ista->tid_state[tid] = AGGR_PROGRESS;
257 spin_unlock_bh(&priv->tx_lock); 257 spin_unlock_bh(&priv->tx_lock);
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 0a4ad348b699..c8f254fe0f0b 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -223,11 +223,6 @@ static inline void ath9k_hw_rfbus_done(struct ath_hw *ah)
223 return ath9k_hw_private_ops(ah)->rfbus_done(ah); 223 return ath9k_hw_private_ops(ah)->rfbus_done(ah);
224} 224}
225 225
226static inline void ath9k_enable_rfkill(struct ath_hw *ah)
227{
228 return ath9k_hw_private_ops(ah)->enable_rfkill(ah);
229}
230
231static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah) 226static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah)
232{ 227{
233 if (!ath9k_hw_private_ops(ah)->restore_chainmask) 228 if (!ath9k_hw_private_ops(ah)->restore_chainmask)
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 516227fa668e..4b51ed47fe69 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -54,13 +54,6 @@ static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
54 ath9k_hw_private_ops(ah)->init_mode_regs(ah); 54 ath9k_hw_private_ops(ah)->init_mode_regs(ah);
55} 55}
56 56
57static bool ath9k_hw_macversion_supported(struct ath_hw *ah)
58{
59 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
60
61 return priv_ops->macversion_supported(ah->hw_version.macVersion);
62}
63
64static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah, 57static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
65 struct ath9k_channel *chan) 58 struct ath9k_channel *chan)
66{ 59{
@@ -284,11 +277,9 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
284 277
285static void ath9k_hw_disablepcie(struct ath_hw *ah) 278static void ath9k_hw_disablepcie(struct ath_hw *ah)
286{ 279{
287 if (AR_SREV_9100(ah)) 280 if (!AR_SREV_5416(ah))
288 return; 281 return;
289 282
290 ENABLE_REGWRITE_BUFFER(ah);
291
292 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); 283 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
293 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); 284 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
294 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029); 285 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
@@ -300,8 +291,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
300 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007); 291 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
301 292
302 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); 293 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
303
304 REGWRITE_BUFFER_FLUSH(ah);
305} 294}
306 295
307/* This should work for all families including legacy */ 296/* This should work for all families including legacy */
@@ -418,9 +407,8 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
418 ah->sta_id1_defaults = 407 ah->sta_id1_defaults =
419 AR_STA_ID1_CRPT_MIC_ENABLE | 408 AR_STA_ID1_CRPT_MIC_ENABLE |
420 AR_STA_ID1_MCAST_KSRCH; 409 AR_STA_ID1_MCAST_KSRCH;
421 ah->beacon_interval = 100;
422 ah->enable_32kHz_clock = DONT_USE_32KHZ; 410 ah->enable_32kHz_clock = DONT_USE_32KHZ;
423 ah->slottime = (u32) -1; 411 ah->slottime = 20;
424 ah->globaltxtimeout = (u32) -1; 412 ah->globaltxtimeout = (u32) -1;
425 ah->power_mode = ATH9K_PM_UNDEFINED; 413 ah->power_mode = ATH9K_PM_UNDEFINED;
426} 414}
@@ -538,7 +526,19 @@ static int __ath9k_hw_init(struct ath_hw *ah)
538 else 526 else
539 ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD; 527 ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
540 528
541 if (!ath9k_hw_macversion_supported(ah)) { 529 switch (ah->hw_version.macVersion) {
530 case AR_SREV_VERSION_5416_PCI:
531 case AR_SREV_VERSION_5416_PCIE:
532 case AR_SREV_VERSION_9160:
533 case AR_SREV_VERSION_9100:
534 case AR_SREV_VERSION_9280:
535 case AR_SREV_VERSION_9285:
536 case AR_SREV_VERSION_9287:
537 case AR_SREV_VERSION_9271:
538 case AR_SREV_VERSION_9300:
539 case AR_SREV_VERSION_9485:
540 break;
541 default:
542 ath_err(common, 542 ath_err(common,
543 "Mac Chip Rev 0x%02x.%x is not supported by this driver\n", 543 "Mac Chip Rev 0x%02x.%x is not supported by this driver\n",
544 ah->hw_version.macVersion, ah->hw_version.macRev); 544 ah->hw_version.macVersion, ah->hw_version.macRev);
@@ -808,7 +808,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
808 if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ) 808 if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
809 acktimeout += 64 - sifstime - ah->slottime; 809 acktimeout += 64 - sifstime - ah->slottime;
810 810
811 ath9k_hw_setslottime(ah, slottime); 811 ath9k_hw_setslottime(ah, ah->slottime);
812 ath9k_hw_set_ack_timeout(ah, acktimeout); 812 ath9k_hw_set_ack_timeout(ah, acktimeout);
813 ath9k_hw_set_cts_timeout(ah, acktimeout); 813 ath9k_hw_set_cts_timeout(ah, acktimeout);
814 if (ah->globaltxtimeout != (u32) -1) 814 if (ah->globaltxtimeout != (u32) -1)
@@ -1272,6 +1272,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1272 1272
1273 ath9k_hw_mark_phy_inactive(ah); 1273 ath9k_hw_mark_phy_inactive(ah);
1274 1274
1275 ah->paprd_table_write_done = false;
1276
1275 /* Only required on the first reset */ 1277 /* Only required on the first reset */
1276 if (AR_SREV_9271(ah) && ah->htc_reset_init) { 1278 if (AR_SREV_9271(ah) && ah->htc_reset_init) {
1277 REG_WRITE(ah, 1279 REG_WRITE(ah,
@@ -1383,7 +1385,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1383 ath9k_hw_init_qos(ah); 1385 ath9k_hw_init_qos(ah);
1384 1386
1385 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 1387 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1386 ath9k_enable_rfkill(ah); 1388 ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
1387 1389
1388 ath9k_hw_init_global_settings(ah); 1390 ath9k_hw_init_global_settings(ah);
1389 1391
@@ -1627,17 +1629,9 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
1627{ 1629{
1628 int flags = 0; 1630 int flags = 0;
1629 1631
1630 ah->beacon_interval = beacon_period;
1631
1632 ENABLE_REGWRITE_BUFFER(ah); 1632 ENABLE_REGWRITE_BUFFER(ah);
1633 1633
1634 switch (ah->opmode) { 1634 switch (ah->opmode) {
1635 case NL80211_IFTYPE_STATION:
1636 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
1637 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
1638 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
1639 flags |= AR_TBTT_TIMER_EN;
1640 break;
1641 case NL80211_IFTYPE_ADHOC: 1635 case NL80211_IFTYPE_ADHOC:
1642 case NL80211_IFTYPE_MESH_POINT: 1636 case NL80211_IFTYPE_MESH_POINT:
1643 REG_SET_BIT(ah, AR_TXCFG, 1637 REG_SET_BIT(ah, AR_TXCFG,
@@ -1661,14 +1655,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
1661 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; 1655 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
1662 break; 1656 break;
1663 default: 1657 default:
1664 if (ah->is_monitoring) {
1665 REG_WRITE(ah, AR_NEXT_TBTT_TIMER,
1666 TU_TO_USEC(next_beacon));
1667 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
1668 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
1669 flags |= AR_TBTT_TIMER_EN;
1670 break;
1671 }
1672 ath_dbg(ath9k_hw_common(ah), ATH_DBG_BEACON, 1658 ath_dbg(ath9k_hw_common(ah), ATH_DBG_BEACON,
1673 "%s: unsupported opmode: %d\n", 1659 "%s: unsupported opmode: %d\n",
1674 __func__, ah->opmode); 1660 __func__, ah->opmode);
@@ -1920,11 +1906,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
1920 AR_SREV_5416(ah)) 1906 AR_SREV_5416(ah))
1921 pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND; 1907 pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
1922 1908
1923 pCap->num_antcfg_5ghz =
1924 ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
1925 pCap->num_antcfg_2ghz =
1926 ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
1927
1928 if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) { 1909 if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) {
1929 btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO; 1910 btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
1930 btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO; 1911 btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index d83cc3b4685b..b8ffaa5dc650 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -204,8 +204,6 @@ struct ath9k_hw_capabilities {
204 u16 tx_triglevel_max; 204 u16 tx_triglevel_max;
205 u16 reg_cap; 205 u16 reg_cap;
206 u8 num_gpio_pins; 206 u8 num_gpio_pins;
207 u8 num_antcfg_2ghz;
208 u8 num_antcfg_5ghz;
209 u8 rx_hp_qdepth; 207 u8 rx_hp_qdepth;
210 u8 rx_lp_qdepth; 208 u8 rx_lp_qdepth;
211 u8 rx_status_len; 209 u8 rx_status_len;
@@ -238,7 +236,6 @@ struct ath9k_ops_config {
238#define SPUR_DISABLE 0 236#define SPUR_DISABLE 0
239#define SPUR_ENABLE_IOCTL 1 237#define SPUR_ENABLE_IOCTL 1
240#define SPUR_ENABLE_EEPROM 2 238#define SPUR_ENABLE_EEPROM 2
241#define AR_EEPROM_MODAL_SPURS 5
242#define AR_SPUR_5413_1 1640 239#define AR_SPUR_5413_1 1640
243#define AR_SPUR_5413_2 1200 240#define AR_SPUR_5413_2 1200
244#define AR_NO_SPUR 0x8000 241#define AR_NO_SPUR 0x8000
@@ -535,7 +532,6 @@ struct ath_hw_radar_conf {
535 * 532 *
536 * @init_mode_regs: Initializes mode registers 533 * @init_mode_regs: Initializes mode registers
537 * @init_mode_gain_regs: Initialize TX/RX gain registers 534 * @init_mode_gain_regs: Initialize TX/RX gain registers
538 * @macversion_supported: If this specific mac revision is supported
539 * 535 *
540 * @rf_set_freq: change frequency 536 * @rf_set_freq: change frequency
541 * @spur_mitigate_freq: spur mitigation 537 * @spur_mitigate_freq: spur mitigation
@@ -557,7 +553,6 @@ struct ath_hw_private_ops {
557 553
558 void (*init_mode_regs)(struct ath_hw *ah); 554 void (*init_mode_regs)(struct ath_hw *ah);
559 void (*init_mode_gain_regs)(struct ath_hw *ah); 555 void (*init_mode_gain_regs)(struct ath_hw *ah);
560 bool (*macversion_supported)(u32 macversion);
561 void (*setup_calibration)(struct ath_hw *ah, 556 void (*setup_calibration)(struct ath_hw *ah,
562 struct ath9k_cal_list *currCal); 557 struct ath9k_cal_list *currCal);
563 558
@@ -581,7 +576,6 @@ struct ath_hw_private_ops {
581 void (*set_delta_slope)(struct ath_hw *ah, struct ath9k_channel *chan); 576 void (*set_delta_slope)(struct ath_hw *ah, struct ath9k_channel *chan);
582 bool (*rfbus_req)(struct ath_hw *ah); 577 bool (*rfbus_req)(struct ath_hw *ah);
583 void (*rfbus_done)(struct ath_hw *ah); 578 void (*rfbus_done)(struct ath_hw *ah);
584 void (*enable_rfkill)(struct ath_hw *ah);
585 void (*restore_chainmask)(struct ath_hw *ah); 579 void (*restore_chainmask)(struct ath_hw *ah);
586 void (*set_diversity)(struct ath_hw *ah, bool value); 580 void (*set_diversity)(struct ath_hw *ah, bool value);
587 u32 (*compute_pll_control)(struct ath_hw *ah, 581 u32 (*compute_pll_control)(struct ath_hw *ah,
@@ -767,9 +761,7 @@ struct ath_hw {
767 u32 *bank6Temp; 761 u32 *bank6Temp;
768 762
769 u8 txpower_limit; 763 u8 txpower_limit;
770 int16_t txpower_indexoffset;
771 int coverage_class; 764 int coverage_class;
772 u32 beacon_interval;
773 u32 slottime; 765 u32 slottime;
774 u32 globaltxtimeout; 766 u32 globaltxtimeout;
775 767
@@ -840,6 +832,11 @@ struct ath_hw {
840 u32 bb_watchdog_last_status; 832 u32 bb_watchdog_last_status;
841 u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */ 833 u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */
842 834
835 unsigned int paprd_target_power;
836 unsigned int paprd_training_power;
837 unsigned int paprd_ratemask;
838 unsigned int paprd_ratemask_ht40;
839 bool paprd_table_write_done;
843 u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; 840 u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
844 u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; 841 u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
845 /* 842 /*
@@ -873,6 +870,11 @@ static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah)
873 return &ah->ops; 870 return &ah->ops;
874} 871}
875 872
873static inline u8 get_streams(int mask)
874{
875 return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
876}
877
876/* Initialization, Detach, Reset */ 878/* Initialization, Detach, Reset */
877const char *ath9k_hw_probe(u16 vendorid, u16 devid); 879const char *ath9k_hw_probe(u16 vendorid, u16 devid);
878void ath9k_hw_deinit(struct ath_hw *ah); 880void ath9k_hw_deinit(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index b2983ce19dfb..b0e5e716b167 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -41,9 +41,14 @@ static int ath9k_btcoex_enable;
41module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); 41module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
42MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); 42MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
43 43
44int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE;
45module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH);
46MODULE_PARM_DESC(pmqos, "User specified PM-QOS value");
47
44/* We use the hw_value as an index into our private channel structure */ 48/* We use the hw_value as an index into our private channel structure */
45 49
46#define CHAN2G(_freq, _idx) { \ 50#define CHAN2G(_freq, _idx) { \
51 .band = IEEE80211_BAND_2GHZ, \
47 .center_freq = (_freq), \ 52 .center_freq = (_freq), \
48 .hw_value = (_idx), \ 53 .hw_value = (_idx), \
49 .max_power = 20, \ 54 .max_power = 20, \
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index daa3c9feca66..8a1691db166d 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -320,6 +320,42 @@ static void ath_paprd_activate(struct ath_softc *sc)
320 ath9k_ps_restore(sc); 320 ath9k_ps_restore(sc);
321} 321}
322 322
323static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain)
324{
325 struct ieee80211_hw *hw = sc->hw;
326 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
327 struct ath_tx_control txctl;
328 int time_left;
329
330 memset(&txctl, 0, sizeof(txctl));
331 txctl.txq = sc->tx.txq_map[WME_AC_BE];
332
333 memset(tx_info, 0, sizeof(*tx_info));
334 tx_info->band = hw->conf.channel->band;
335 tx_info->flags |= IEEE80211_TX_CTL_NO_ACK;
336 tx_info->control.rates[0].idx = 0;
337 tx_info->control.rates[0].count = 1;
338 tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS;
339 tx_info->control.rates[1].idx = -1;
340
341 init_completion(&sc->paprd_complete);
342 sc->paprd_pending = true;
343 txctl.paprd = BIT(chain);
344 if (ath_tx_start(hw, skb, &txctl) != 0)
345 return false;
346
347 time_left = wait_for_completion_timeout(&sc->paprd_complete,
348 msecs_to_jiffies(ATH_PAPRD_TIMEOUT));
349 sc->paprd_pending = false;
350
351 if (!time_left)
352 ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE,
353 "Timeout waiting for paprd training on TX chain %d\n",
354 chain);
355
356 return !!time_left;
357}
358
323void ath_paprd_calibrate(struct work_struct *work) 359void ath_paprd_calibrate(struct work_struct *work)
324{ 360{
325 struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); 361 struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work);
@@ -327,28 +363,23 @@ void ath_paprd_calibrate(struct work_struct *work)
327 struct ath_hw *ah = sc->sc_ah; 363 struct ath_hw *ah = sc->sc_ah;
328 struct ieee80211_hdr *hdr; 364 struct ieee80211_hdr *hdr;
329 struct sk_buff *skb = NULL; 365 struct sk_buff *skb = NULL;
330 struct ieee80211_tx_info *tx_info;
331 int band = hw->conf.channel->band;
332 struct ieee80211_supported_band *sband = &sc->sbands[band];
333 struct ath_tx_control txctl;
334 struct ath9k_hw_cal_data *caldata = ah->caldata; 366 struct ath9k_hw_cal_data *caldata = ah->caldata;
335 struct ath_common *common = ath9k_hw_common(ah); 367 struct ath_common *common = ath9k_hw_common(ah);
336 int ftype; 368 int ftype;
337 int chain_ok = 0; 369 int chain_ok = 0;
338 int chain; 370 int chain;
339 int len = 1800; 371 int len = 1800;
340 int time_left;
341 int i;
342 372
343 if (!caldata) 373 if (!caldata)
344 return; 374 return;
345 375
376 if (ar9003_paprd_init_table(ah) < 0)
377 return;
378
346 skb = alloc_skb(len, GFP_KERNEL); 379 skb = alloc_skb(len, GFP_KERNEL);
347 if (!skb) 380 if (!skb)
348 return; 381 return;
349 382
350 tx_info = IEEE80211_SKB_CB(skb);
351
352 skb_put(skb, len); 383 skb_put(skb, len);
353 memset(skb->data, 0, len); 384 memset(skb->data, 0, len);
354 hdr = (struct ieee80211_hdr *)skb->data; 385 hdr = (struct ieee80211_hdr *)skb->data;
@@ -359,40 +390,25 @@ void ath_paprd_calibrate(struct work_struct *work)
359 memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); 390 memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
360 memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); 391 memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
361 392
362 memset(&txctl, 0, sizeof(txctl));
363 txctl.txq = sc->tx.txq_map[WME_AC_BE];
364
365 ath9k_ps_wakeup(sc); 393 ath9k_ps_wakeup(sc);
366 ar9003_paprd_init_table(ah);
367 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { 394 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
368 if (!(common->tx_chainmask & BIT(chain))) 395 if (!(common->tx_chainmask & BIT(chain)))
369 continue; 396 continue;
370 397
371 chain_ok = 0; 398 chain_ok = 0;
372 memset(tx_info, 0, sizeof(*tx_info));
373 tx_info->band = band;
374 399
375 for (i = 0; i < 4; i++) { 400 ath_dbg(common, ATH_DBG_CALIBRATE,
376 tx_info->control.rates[i].idx = sband->n_bitrates - 1; 401 "Sending PAPRD frame for thermal measurement "
377 tx_info->control.rates[i].count = 6; 402 "on chain %d\n", chain);
378 } 403 if (!ath_paprd_send_frame(sc, skb, chain))
404 goto fail_paprd;
379 405
380 init_completion(&sc->paprd_complete);
381 sc->paprd_pending = true;
382 ar9003_paprd_setup_gain_table(ah, chain); 406 ar9003_paprd_setup_gain_table(ah, chain);
383 txctl.paprd = BIT(chain);
384 if (ath_tx_start(hw, skb, &txctl) != 0)
385 break;
386 407
387 time_left = wait_for_completion_timeout(&sc->paprd_complete, 408 ath_dbg(common, ATH_DBG_CALIBRATE,
388 msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); 409 "Sending PAPRD training frame on chain %d\n", chain);
389 sc->paprd_pending = false; 410 if (!ath_paprd_send_frame(sc, skb, chain))
390 if (!time_left) {
391 ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
392 "Timeout waiting for paprd training on TX chain %d\n",
393 chain);
394 goto fail_paprd; 411 goto fail_paprd;
395 }
396 412
397 if (!ar9003_paprd_is_done(ah)) 413 if (!ar9003_paprd_is_done(ah))
398 break; 414 break;
@@ -517,37 +533,11 @@ set_timer:
517 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { 533 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
518 if (!ah->caldata->paprd_done) 534 if (!ah->caldata->paprd_done)
519 ieee80211_queue_work(sc->hw, &sc->paprd_work); 535 ieee80211_queue_work(sc->hw, &sc->paprd_work);
520 else 536 else if (!ah->paprd_table_write_done)
521 ath_paprd_activate(sc); 537 ath_paprd_activate(sc);
522 } 538 }
523} 539}
524 540
525/*
526 * Update tx/rx chainmask. For legacy association,
527 * hard code chainmask to 1x1, for 11n association, use
528 * the chainmask configuration, for bt coexistence, use
529 * the chainmask configuration even in legacy mode.
530 */
531void ath_update_chainmask(struct ath_softc *sc, int is_ht)
532{
533 struct ath_hw *ah = sc->sc_ah;
534 struct ath_common *common = ath9k_hw_common(ah);
535
536 if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht ||
537 (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) {
538 common->tx_chainmask = ah->caps.tx_chainmask;
539 common->rx_chainmask = ah->caps.rx_chainmask;
540 } else {
541 common->tx_chainmask = 1;
542 common->rx_chainmask = 1;
543 }
544
545 ath_dbg(common, ATH_DBG_CONFIG,
546 "tx chmask: %d, rx chmask: %d\n",
547 common->tx_chainmask,
548 common->rx_chainmask);
549}
550
551static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) 541static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
552{ 542{
553 struct ath_node *an; 543 struct ath_node *an;
@@ -900,8 +890,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
900 ath_update_txpow(sc); 890 ath_update_txpow(sc);
901 if (ath_startrecv(sc) != 0) { 891 if (ath_startrecv(sc) != 0) {
902 ath_err(common, "Unable to restart recv logic\n"); 892 ath_err(common, "Unable to restart recv logic\n");
903 spin_unlock_bh(&sc->sc_pcu_lock); 893 goto out;
904 return;
905 } 894 }
906 if (sc->sc_flags & SC_OP_BEACONS) 895 if (sc->sc_flags & SC_OP_BEACONS)
907 ath_beacon_config(sc, NULL); /* restart beacons */ 896 ath_beacon_config(sc, NULL); /* restart beacons */
@@ -915,6 +904,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
915 ath9k_hw_set_gpio(ah, ah->led_pin, 0); 904 ath9k_hw_set_gpio(ah, ah->led_pin, 0);
916 905
917 ieee80211_wake_queues(hw); 906 ieee80211_wake_queues(hw);
907out:
918 spin_unlock_bh(&sc->sc_pcu_lock); 908 spin_unlock_bh(&sc->sc_pcu_lock);
919 909
920 ath9k_ps_restore(sc); 910 ath9k_ps_restore(sc);
@@ -1180,7 +1170,11 @@ static int ath9k_start(struct ieee80211_hw *hw)
1180 ath9k_btcoex_timer_resume(sc); 1170 ath9k_btcoex_timer_resume(sc);
1181 } 1171 }
1182 1172
1183 pm_qos_update_request(&sc->pm_qos_req, 55); 1173 /* User has the option to provide pm-qos value as a module
1174 * parameter rather than using the default value of
1175 * 'ATH9K_PM_QOS_DEFAULT_VALUE'.
1176 */
1177 pm_qos_update_request(&sc->pm_qos_req, ath9k_pm_qos_value);
1184 1178
1185 if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) 1179 if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
1186 common->bus_ops->extn_synch_en(common); 1180 common->bus_ops->extn_synch_en(common);
@@ -1333,8 +1327,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
1333 1327
1334 ath9k_ps_restore(sc); 1328 ath9k_ps_restore(sc);
1335 1329
1336 /* Finally, put the chip in FULL SLEEP mode */ 1330 sc->ps_idle = true;
1337 ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); 1331 ath_radio_disable(sc, hw);
1338 1332
1339 sc->sc_flags |= SC_OP_INVALID; 1333 sc->sc_flags |= SC_OP_INVALID;
1340 1334
@@ -1428,13 +1422,78 @@ out:
1428 return ret; 1422 return ret;
1429} 1423}
1430 1424
1425static void ath9k_reclaim_beacon(struct ath_softc *sc,
1426 struct ieee80211_vif *vif)
1427{
1428 struct ath_vif *avp = (void *)vif->drv_priv;
1429
1430 /* Disable SWBA interrupt */
1431 sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
1432 ath9k_ps_wakeup(sc);
1433 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
1434 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1435 tasklet_kill(&sc->bcon_tasklet);
1436 ath9k_ps_restore(sc);
1437
1438 ath_beacon_return(sc, avp);
1439 sc->sc_flags &= ~SC_OP_BEACONS;
1440
1441 if (sc->nbcnvifs > 0) {
1442 /* Re-enable beaconing */
1443 sc->sc_ah->imask |= ATH9K_INT_SWBA;
1444 ath9k_ps_wakeup(sc);
1445 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
1446 ath9k_ps_restore(sc);
1447 }
1448}
1449
1450static int ath9k_change_interface(struct ieee80211_hw *hw,
1451 struct ieee80211_vif *vif,
1452 enum nl80211_iftype new_type,
1453 bool p2p)
1454{
1455 struct ath_wiphy *aphy = hw->priv;
1456 struct ath_softc *sc = aphy->sc;
1457 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1458
1459 ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n");
1460 mutex_lock(&sc->mutex);
1461
1462 switch (new_type) {
1463 case NL80211_IFTYPE_AP:
1464 case NL80211_IFTYPE_ADHOC:
1465 if (sc->nbcnvifs >= ATH_BCBUF) {
1466 ath_err(common, "No beacon slot available\n");
1467 return -ENOBUFS;
1468 }
1469 break;
1470 case NL80211_IFTYPE_STATION:
1471 /* Stop ANI */
1472 sc->sc_flags &= ~SC_OP_ANI_RUN;
1473 del_timer_sync(&common->ani.timer);
1474 if ((vif->type == NL80211_IFTYPE_AP) ||
1475 (vif->type == NL80211_IFTYPE_ADHOC))
1476 ath9k_reclaim_beacon(sc, vif);
1477 break;
1478 default:
1479 ath_err(common, "Interface type %d not yet supported\n",
1480 vif->type);
1481 mutex_unlock(&sc->mutex);
1482 return -ENOTSUPP;
1483 }
1484 vif->type = new_type;
1485 vif->p2p = p2p;
1486
1487 mutex_unlock(&sc->mutex);
1488 return 0;
1489}
1490
1431static void ath9k_remove_interface(struct ieee80211_hw *hw, 1491static void ath9k_remove_interface(struct ieee80211_hw *hw,
1432 struct ieee80211_vif *vif) 1492 struct ieee80211_vif *vif)
1433{ 1493{
1434 struct ath_wiphy *aphy = hw->priv; 1494 struct ath_wiphy *aphy = hw->priv;
1435 struct ath_softc *sc = aphy->sc; 1495 struct ath_softc *sc = aphy->sc;
1436 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1496 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1437 struct ath_vif *avp = (void *)vif->drv_priv;
1438 1497
1439 ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n"); 1498 ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
1440 1499
@@ -1447,26 +1506,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1447 /* Reclaim beacon resources */ 1506 /* Reclaim beacon resources */
1448 if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || 1507 if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
1449 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || 1508 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
1450 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { 1509 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT))
1451 /* Disable SWBA interrupt */ 1510 ath9k_reclaim_beacon(sc, vif);
1452 sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
1453 ath9k_ps_wakeup(sc);
1454 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
1455 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1456 ath9k_ps_restore(sc);
1457 tasklet_kill(&sc->bcon_tasklet);
1458 }
1459
1460 ath_beacon_return(sc, avp);
1461 sc->sc_flags &= ~SC_OP_BEACONS;
1462
1463 if (sc->nbcnvifs) {
1464 /* Re-enable SWBA interrupt */
1465 sc->sc_ah->imask |= ATH9K_INT_SWBA;
1466 ath9k_ps_wakeup(sc);
1467 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
1468 ath9k_ps_restore(sc);
1469 }
1470 1511
1471 sc->nvifs--; 1512 sc->nvifs--;
1472 1513
@@ -1612,8 +1653,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1612 /* XXX: remove me eventualy */ 1653 /* XXX: remove me eventualy */
1613 ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]); 1654 ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
1614 1655
1615 ath_update_chainmask(sc, conf_is_ht(conf));
1616
1617 /* update survey stats for the old channel before switching */ 1656 /* update survey stats for the old channel before switching */
1618 spin_lock_irqsave(&common->cc_lock, flags); 1657 spin_lock_irqsave(&common->cc_lock, flags);
1619 ath_update_survey_stats(sc); 1658 ath_update_survey_stats(sc);
@@ -1845,10 +1884,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1845 /* Set aggregation protection mode parameters */ 1884 /* Set aggregation protection mode parameters */
1846 sc->config.ath_aggr_prot = 0; 1885 sc->config.ath_aggr_prot = 0;
1847 1886
1848 /* Only legacy IBSS for now */
1849 if (vif->type == NL80211_IFTYPE_ADHOC)
1850 ath_update_chainmask(sc, 0);
1851
1852 ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n", 1887 ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n",
1853 common->curbssid, common->curaid); 1888 common->curbssid, common->curaid);
1854 1889
@@ -1940,7 +1975,9 @@ static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
1940 struct ath_softc *sc = aphy->sc; 1975 struct ath_softc *sc = aphy->sc;
1941 1976
1942 mutex_lock(&sc->mutex); 1977 mutex_lock(&sc->mutex);
1978 ath9k_ps_wakeup(sc);
1943 tsf = ath9k_hw_gettsf64(sc->sc_ah); 1979 tsf = ath9k_hw_gettsf64(sc->sc_ah);
1980 ath9k_ps_restore(sc);
1944 mutex_unlock(&sc->mutex); 1981 mutex_unlock(&sc->mutex);
1945 1982
1946 return tsf; 1983 return tsf;
@@ -1952,7 +1989,9 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1952 struct ath_softc *sc = aphy->sc; 1989 struct ath_softc *sc = aphy->sc;
1953 1990
1954 mutex_lock(&sc->mutex); 1991 mutex_lock(&sc->mutex);
1992 ath9k_ps_wakeup(sc);
1955 ath9k_hw_settsf64(sc->sc_ah, tsf); 1993 ath9k_hw_settsf64(sc->sc_ah, tsf);
1994 ath9k_ps_restore(sc);
1956 mutex_unlock(&sc->mutex); 1995 mutex_unlock(&sc->mutex);
1957} 1996}
1958 1997
@@ -2111,6 +2150,7 @@ struct ieee80211_ops ath9k_ops = {
2111 .start = ath9k_start, 2150 .start = ath9k_start,
2112 .stop = ath9k_stop, 2151 .stop = ath9k_stop,
2113 .add_interface = ath9k_add_interface, 2152 .add_interface = ath9k_add_interface,
2153 .change_interface = ath9k_change_interface,
2114 .remove_interface = ath9k_remove_interface, 2154 .remove_interface = ath9k_remove_interface,
2115 .config = ath9k_config, 2155 .config = ath9k_config,
2116 .configure_filter = ath9k_configure_filter, 2156 .configure_filter = ath9k_configure_filter,
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 747b2871e48f..7ca8499249ec 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -309,6 +309,9 @@ static int ath_pci_resume(struct device *device)
309 AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 309 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
310 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); 310 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
311 311
312 sc->ps_idle = true;
313 ath_radio_disable(sc, hw);
314
312 return 0; 315 return 0;
313} 316}
314 317
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 2061a755a026..896d12986b1e 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1373,7 +1373,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1373 an = (struct ath_node *)sta->drv_priv; 1373 an = (struct ath_node *)sta->drv_priv;
1374 1374
1375 if(ath_tx_aggr_check(sc, an, tid)) 1375 if(ath_tx_aggr_check(sc, an, tid))
1376 ieee80211_start_tx_ba_session(sta, tid); 1376 ieee80211_start_tx_ba_session(sta, tid, 0);
1377 } 1377 }
1378 } 1378 }
1379 1379
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index fbfbc8239971..2dc7095e56d1 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -288,7 +288,6 @@ void ath9k_wiphy_chan_work(struct work_struct *work)
288 /* sync hw configuration for hw code */ 288 /* sync hw configuration for hw code */
289 common->hw = aphy->hw; 289 common->hw = aphy->hw;
290 290
291 ath_update_chainmask(sc, sc->chan_is_ht);
292 if (ath_set_channel(sc, aphy->hw, 291 if (ath_set_channel(sc, aphy->hw,
293 &sc->sc_ah->channels[sc->chan_idx]) < 0) { 292 &sc->sc_ah->channels[sc->chan_idx]) < 0) {
294 printk(KERN_DEBUG "ath9k: Failed to set channel for new " 293 printk(KERN_DEBUG "ath9k: Failed to set channel for new "
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 43c0109f202c..332d1feb5c18 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -838,7 +838,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
838 ath_tx_txqaddbuf(sc, txq, &bf_q); 838 ath_tx_txqaddbuf(sc, txq, &bf_q);
839 TX_STAT_INC(txq->axq_qnum, a_aggr); 839 TX_STAT_INC(txq->axq_qnum, a_aggr);
840 840
841 } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH && 841 } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH &&
842 status != ATH_AGGR_BAW_CLOSED); 842 status != ATH_AGGR_BAW_CLOSED);
843} 843}
844 844
@@ -999,6 +999,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
999 INIT_LIST_HEAD(&txq->axq_acq); 999 INIT_LIST_HEAD(&txq->axq_acq);
1000 spin_lock_init(&txq->axq_lock); 1000 spin_lock_init(&txq->axq_lock);
1001 txq->axq_depth = 0; 1001 txq->axq_depth = 0;
1002 txq->axq_ampdu_depth = 0;
1002 txq->axq_tx_inprogress = false; 1003 txq->axq_tx_inprogress = false;
1003 sc->tx.txqsetup |= 1<<qnum; 1004 sc->tx.txqsetup |= 1<<qnum;
1004 1005
@@ -1068,6 +1069,12 @@ int ath_cabq_update(struct ath_softc *sc)
1068 return 0; 1069 return 0;
1069} 1070}
1070 1071
1072static bool bf_is_ampdu_not_probing(struct ath_buf *bf)
1073{
1074 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu);
1075 return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
1076}
1077
1071/* 1078/*
1072 * Drain a given TX queue (could be Beacon or Data) 1079 * Drain a given TX queue (could be Beacon or Data)
1073 * 1080 *
@@ -1126,7 +1133,8 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1126 } 1133 }
1127 1134
1128 txq->axq_depth--; 1135 txq->axq_depth--;
1129 1136 if (bf_is_ampdu_not_probing(bf))
1137 txq->axq_ampdu_depth--;
1130 spin_unlock_bh(&txq->axq_lock); 1138 spin_unlock_bh(&txq->axq_lock);
1131 1139
1132 if (bf_isampdu(bf)) 1140 if (bf_isampdu(bf))
@@ -1316,6 +1324,8 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
1316 ath9k_hw_txstart(ah, txq->axq_qnum); 1324 ath9k_hw_txstart(ah, txq->axq_qnum);
1317 } 1325 }
1318 txq->axq_depth++; 1326 txq->axq_depth++;
1327 if (bf_is_ampdu_not_probing(bf))
1328 txq->axq_ampdu_depth++;
1319} 1329}
1320 1330
1321static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, 1331static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
@@ -1336,7 +1346,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
1336 */ 1346 */
1337 if (!list_empty(&tid->buf_q) || tid->paused || 1347 if (!list_empty(&tid->buf_q) || tid->paused ||
1338 !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) || 1348 !BAW_WITHIN(tid->seq_start, tid->baw_size, fi->seqno) ||
1339 txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) { 1349 txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) {
1340 /* 1350 /*
1341 * Add this frame to software queue for scheduling later 1351 * Add this frame to software queue for scheduling later
1342 * for aggregation. 1352 * for aggregation.
@@ -1685,17 +1695,20 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
1685 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1695 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1686 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1696 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1687 struct list_head bf_head; 1697 struct list_head bf_head;
1688 struct ath_atx_tid *tid; 1698 struct ath_atx_tid *tid = NULL;
1689 u8 tidno; 1699 u8 tidno;
1690 1700
1691 spin_lock_bh(&txctl->txq->axq_lock); 1701 spin_lock_bh(&txctl->txq->axq_lock);
1692 1702
1693 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && txctl->an) { 1703 if (ieee80211_is_data_qos(hdr->frame_control) && txctl->an) {
1694 tidno = ieee80211_get_qos_ctl(hdr)[0] & 1704 tidno = ieee80211_get_qos_ctl(hdr)[0] &
1695 IEEE80211_QOS_CTL_TID_MASK; 1705 IEEE80211_QOS_CTL_TID_MASK;
1696 tid = ATH_AN_2_TID(txctl->an, tidno); 1706 tid = ATH_AN_2_TID(txctl->an, tidno);
1697 1707
1698 WARN_ON(tid->ac->txq != txctl->txq); 1708 WARN_ON(tid->ac->txq != txctl->txq);
1709 }
1710
1711 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && tid) {
1699 /* 1712 /*
1700 * Try aggregation if it's a unicast data frame 1713 * Try aggregation if it's a unicast data frame
1701 * and the destination is HT capable. 1714 * and the destination is HT capable.
@@ -1712,7 +1725,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
1712 ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, 1725 ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc,
1713 bf->bf_state.bfs_paprd); 1726 bf->bf_state.bfs_paprd);
1714 1727
1715 ath_tx_send_normal(sc, txctl->txq, NULL, &bf_head); 1728 ath_tx_send_normal(sc, txctl->txq, tid, &bf_head);
1716 } 1729 }
1717 1730
1718 spin_unlock_bh(&txctl->txq->axq_lock); 1731 spin_unlock_bh(&txctl->txq->axq_lock);
@@ -2037,6 +2050,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2037 txq->axq_tx_inprogress = false; 2050 txq->axq_tx_inprogress = false;
2038 if (bf_held) 2051 if (bf_held)
2039 list_del(&bf_held->list); 2052 list_del(&bf_held->list);
2053
2054 if (bf_is_ampdu_not_probing(bf))
2055 txq->axq_ampdu_depth--;
2040 spin_unlock_bh(&txq->axq_lock); 2056 spin_unlock_bh(&txq->axq_lock);
2041 2057
2042 if (bf_held) 2058 if (bf_held)
@@ -2165,6 +2181,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2165 INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); 2181 INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH);
2166 txq->axq_depth--; 2182 txq->axq_depth--;
2167 txq->axq_tx_inprogress = false; 2183 txq->axq_tx_inprogress = false;
2184 if (bf_is_ampdu_not_probing(bf))
2185 txq->axq_ampdu_depth--;
2168 spin_unlock_bh(&txq->axq_lock); 2186 spin_unlock_bh(&txq->axq_lock);
2169 2187
2170 txok = !(txs.ts_status & ATH9K_TXERR_MASK); 2188 txok = !(txs.ts_status & ATH9K_TXERR_MASK);
diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c
index 29a2961af5fc..5d465e5fcf24 100644
--- a/drivers/net/wireless/ath/key.c
+++ b/drivers/net/wireless/ath/key.c
@@ -58,6 +58,8 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry)
58 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); 58 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
59 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); 59 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
60 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); 60 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
61 if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)
62 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
61 63
62 } 64 }
63 65
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 3f4244f56ce5..2b14775e6bc6 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -342,6 +342,14 @@ int ath_reg_notifier_apply(struct wiphy *wiphy,
342 /* We always apply this */ 342 /* We always apply this */
343 ath_reg_apply_radar_flags(wiphy); 343 ath_reg_apply_radar_flags(wiphy);
344 344
345 /*
346 * This would happen when we have sent a custom regulatory request
347 * a world regulatory domain and the scheduler hasn't yet processed
348 * any pending requests in the queue.
349 */
350 if (!request)
351 return 0;
352
345 switch (request->initiator) { 353 switch (request->initiator) {
346 case NL80211_REGDOM_SET_BY_DRIVER: 354 case NL80211_REGDOM_SET_BY_DRIVER:
347 case NL80211_REGDOM_SET_BY_CORE: 355 case NL80211_REGDOM_SET_BY_CORE:
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 9aad2ca3c112..bd4cb75b6ca3 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -416,10 +416,10 @@ enum {
416 416
417/* 802.11 core specific TM State Low (SSB_TMSLOW) flags */ 417/* 802.11 core specific TM State Low (SSB_TMSLOW) flags */
418#define B43_TMSLOW_GMODE 0x20000000 /* G Mode Enable */ 418#define B43_TMSLOW_GMODE 0x20000000 /* G Mode Enable */
419#define B43_TMSLOW_PHYCLKSPEED 0x00C00000 /* PHY clock speed mask (N-PHY only) */ 419#define B43_TMSLOW_PHY_BANDWIDTH 0x00C00000 /* PHY band width and clock speed mask (N-PHY only) */
420#define B43_TMSLOW_PHYCLKSPEED_40MHZ 0x00000000 /* 40 MHz PHY */ 420#define B43_TMSLOW_PHY_BANDWIDTH_10MHZ 0x00000000 /* 10 MHz bandwidth, 40 MHz PHY */
421#define B43_TMSLOW_PHYCLKSPEED_80MHZ 0x00400000 /* 80 MHz PHY */ 421#define B43_TMSLOW_PHY_BANDWIDTH_20MHZ 0x00400000 /* 20 MHz bandwidth, 80 MHz PHY */
422#define B43_TMSLOW_PHYCLKSPEED_160MHZ 0x00800000 /* 160 MHz PHY */ 422#define B43_TMSLOW_PHY_BANDWIDTH_40MHZ 0x00800000 /* 40 MHz bandwidth, 160 MHz PHY */
423#define B43_TMSLOW_PLLREFSEL 0x00200000 /* PLL Frequency Reference Select (rev >= 5) */ 423#define B43_TMSLOW_PLLREFSEL 0x00200000 /* PLL Frequency Reference Select (rev >= 5) */
424#define B43_TMSLOW_MACPHYCLKEN 0x00100000 /* MAC PHY Clock Control Enable (rev >= 5) */ 424#define B43_TMSLOW_MACPHYCLKEN 0x00100000 /* MAC PHY Clock Control Enable (rev >= 5) */
425#define B43_TMSLOW_PHYRESET 0x00080000 /* PHY Reset */ 425#define B43_TMSLOW_PHYRESET 0x00080000 /* PHY Reset */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 9ae3f619e98d..1aec160e3d2f 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1150,12 +1150,8 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
1150 1150
1151 flags |= B43_TMSLOW_PHYCLKEN; 1151 flags |= B43_TMSLOW_PHYCLKEN;
1152 flags |= B43_TMSLOW_PHYRESET; 1152 flags |= B43_TMSLOW_PHYRESET;
1153 if (dev->phy.type == B43_PHYTYPE_N) { 1153 if (dev->phy.type == B43_PHYTYPE_N)
1154 if (b43_channel_type_is_40mhz(dev->phy.channel_type)) 1154 flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */
1155 flags |= B43_TMSLOW_PHYCLKSPEED_160MHZ;
1156 else
1157 flags |= B43_TMSLOW_PHYCLKSPEED_80MHZ;
1158 }
1159 ssb_device_enable(dev->dev, flags); 1155 ssb_device_enable(dev->dev, flags);
1160 msleep(2); /* Wait for the PLL to turn on. */ 1156 msleep(2); /* Wait for the PLL to turn on. */
1161 1157
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 61875c888278..a1aa5700b631 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -1209,29 +1209,18 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
1209 b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8); 1209 b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8);
1210 } 1210 }
1211 1211
1212 /* TODO: convert to b43_ntab_write? */ 1212 b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A);
1213 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2000); 1213 b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A);
1214 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A); 1214 b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA);
1215 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2010); 1215 b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA);
1216 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
1217 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2002);
1218 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
1219 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2012);
1220 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
1221 1216
1222 if (dev->phy.rev < 2) { 1217 if (dev->phy.rev < 2) {
1223 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2008); 1218 b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000);
1224 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000); 1219 b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0x0000);
1225 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2018); 1220 b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB);
1226 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000); 1221 b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB);
1227 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2007); 1222 b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x0800);
1228 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB); 1223 b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x0800);
1229 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2017);
1230 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
1231 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2006);
1232 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
1233 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2016);
1234 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
1235 } 1224 }
1236 1225
1237 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); 1226 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
@@ -3278,9 +3267,9 @@ static void b43_nphy_mac_phy_clock_set(struct b43_wldev *dev, bool on)
3278{ 3267{
3279 u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW); 3268 u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
3280 if (on) 3269 if (on)
3281 tmslow |= SSB_TMSLOW_PHYCLK; 3270 tmslow |= B43_TMSLOW_MACPHYCLKEN;
3282 else 3271 else
3283 tmslow &= ~SSB_TMSLOW_PHYCLK; 3272 tmslow &= ~B43_TMSLOW_MACPHYCLKEN;
3284 ssb_write32(dev->dev, SSB_TMSLOW, tmslow); 3273 ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
3285} 3274}
3286 3275
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index df61c1610e39..dc8ef09a8552 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -1835,12 +1835,12 @@ void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev)
1835 /* Volatile tables */ 1835 /* Volatile tables */
1836 ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi); 1836 ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
1837 ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt); 1837 ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt);
1838 ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0);
1839 ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1);
1838 ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0); 1840 ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0);
1839 ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1); 1841 ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1);
1840 ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0); 1842 ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0);
1841 ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1); 1843 ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1);
1842 ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0);
1843 ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1);
1844 ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0); 1844 ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0);
1845 ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1); 1845 ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1);
1846 ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0); 1846 ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0);
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index af85458401a4..ba78bc8a259f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -147,7 +147,11 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
147 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; 147 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
148 148
149 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); 149 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
150 priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); 150 if (priv->cfg->rx_with_siso_diversity)
151 priv->hw_params.rx_chains_num = 1;
152 else
153 priv->hw_params.rx_chains_num =
154 num_of_ant(priv->cfg->valid_rx_ant);
151 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; 155 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
152 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; 156 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
153 157
@@ -272,60 +276,49 @@ static struct iwl_ht_params iwl1000_ht_params = {
272 .use_rts_for_aggregation = true, /* use rts/cts protection */ 276 .use_rts_for_aggregation = true, /* use rts/cts protection */
273}; 277};
274 278
279#define IWL_DEVICE_1000 \
280 .fw_name_pre = IWL1000_FW_PRE, \
281 .ucode_api_max = IWL1000_UCODE_API_MAX, \
282 .ucode_api_min = IWL1000_UCODE_API_MIN, \
283 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
284 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
285 .ops = &iwl1000_ops, \
286 .mod_params = &iwlagn_mod_params, \
287 .base_params = &iwl1000_base_params, \
288 .led_mode = IWL_LED_BLINK
289
275struct iwl_cfg iwl1000_bgn_cfg = { 290struct iwl_cfg iwl1000_bgn_cfg = {
276 .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", 291 .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
277 .fw_name_pre = IWL1000_FW_PRE, 292 IWL_DEVICE_1000,
278 .ucode_api_max = IWL1000_UCODE_API_MAX,
279 .ucode_api_min = IWL1000_UCODE_API_MIN,
280 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
281 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
282 .ops = &iwl1000_ops,
283 .mod_params = &iwlagn_mod_params,
284 .base_params = &iwl1000_base_params,
285 .ht_params = &iwl1000_ht_params, 293 .ht_params = &iwl1000_ht_params,
286 .led_mode = IWL_LED_BLINK,
287}; 294};
288 295
289struct iwl_cfg iwl1000_bg_cfg = { 296struct iwl_cfg iwl1000_bg_cfg = {
290 .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", 297 .name = "Intel(R) Centrino(R) Wireless-N 1000 BG",
291 .fw_name_pre = IWL1000_FW_PRE, 298 IWL_DEVICE_1000,
292 .ucode_api_max = IWL1000_UCODE_API_MAX,
293 .ucode_api_min = IWL1000_UCODE_API_MIN,
294 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
295 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
296 .ops = &iwl1000_ops,
297 .mod_params = &iwlagn_mod_params,
298 .base_params = &iwl1000_base_params,
299 .led_mode = IWL_LED_BLINK,
300}; 299};
301 300
301#define IWL_DEVICE_100 \
302 .fw_name_pre = IWL100_FW_PRE, \
303 .ucode_api_max = IWL100_UCODE_API_MAX, \
304 .ucode_api_min = IWL100_UCODE_API_MIN, \
305 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
306 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
307 .ops = &iwl1000_ops, \
308 .mod_params = &iwlagn_mod_params, \
309 .base_params = &iwl1000_base_params, \
310 .led_mode = IWL_LED_RF_STATE, \
311 .rx_with_siso_diversity = true
312
302struct iwl_cfg iwl100_bgn_cfg = { 313struct iwl_cfg iwl100_bgn_cfg = {
303 .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", 314 .name = "Intel(R) Centrino(R) Wireless-N 100 BGN",
304 .fw_name_pre = IWL100_FW_PRE, 315 IWL_DEVICE_100,
305 .ucode_api_max = IWL100_UCODE_API_MAX,
306 .ucode_api_min = IWL100_UCODE_API_MIN,
307 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
308 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
309 .ops = &iwl1000_ops,
310 .mod_params = &iwlagn_mod_params,
311 .base_params = &iwl1000_base_params,
312 .ht_params = &iwl1000_ht_params, 316 .ht_params = &iwl1000_ht_params,
313 .led_mode = IWL_LED_RF_STATE,
314 .use_new_eeprom_reading = true,
315}; 317};
316 318
317struct iwl_cfg iwl100_bg_cfg = { 319struct iwl_cfg iwl100_bg_cfg = {
318 .name = "Intel(R) Centrino(R) Wireless-N 100 BG", 320 .name = "Intel(R) Centrino(R) Wireless-N 100 BG",
319 .fw_name_pre = IWL100_FW_PRE, 321 IWL_DEVICE_100,
320 .ucode_api_max = IWL100_UCODE_API_MAX,
321 .ucode_api_min = IWL100_UCODE_API_MIN,
322 .eeprom_ver = EEPROM_1000_EEPROM_VERSION,
323 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,
324 .ops = &iwl1000_ops,
325 .mod_params = &iwlagn_mod_params,
326 .base_params = &iwl1000_base_params,
327 .led_mode = IWL_LED_RF_STATE,
328 .use_new_eeprom_reading = true,
329}; 322};
330 323
331MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); 324MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 8435e5a4e69d..79ab0a6b1386 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -520,65 +520,44 @@ static struct iwl_ht_params iwl5000_ht_params = {
520 .use_rts_for_aggregation = true, /* use rts/cts protection */ 520 .use_rts_for_aggregation = true, /* use rts/cts protection */
521}; 521};
522 522
523#define IWL_DEVICE_5000 \
524 .fw_name_pre = IWL5000_FW_PRE, \
525 .ucode_api_max = IWL5000_UCODE_API_MAX, \
526 .ucode_api_min = IWL5000_UCODE_API_MIN, \
527 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \
528 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
529 .ops = &iwl5000_ops, \
530 .mod_params = &iwlagn_mod_params, \
531 .base_params = &iwl5000_base_params, \
532 .led_mode = IWL_LED_BLINK
533
523struct iwl_cfg iwl5300_agn_cfg = { 534struct iwl_cfg iwl5300_agn_cfg = {
524 .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", 535 .name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
525 .fw_name_pre = IWL5000_FW_PRE, 536 IWL_DEVICE_5000,
526 .ucode_api_max = IWL5000_UCODE_API_MAX,
527 .ucode_api_min = IWL5000_UCODE_API_MIN,
528 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
529 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
530 .ops = &iwl5000_ops,
531 .mod_params = &iwlagn_mod_params,
532 .base_params = &iwl5000_base_params,
533 .ht_params = &iwl5000_ht_params, 537 .ht_params = &iwl5000_ht_params,
534 .led_mode = IWL_LED_BLINK,
535}; 538};
536 539
537struct iwl_cfg iwl5100_bgn_cfg = { 540struct iwl_cfg iwl5100_bgn_cfg = {
538 .name = "Intel(R) WiFi Link 5100 BGN", 541 .name = "Intel(R) WiFi Link 5100 BGN",
539 .fw_name_pre = IWL5000_FW_PRE, 542 IWL_DEVICE_5000,
540 .ucode_api_max = IWL5000_UCODE_API_MAX,
541 .ucode_api_min = IWL5000_UCODE_API_MIN,
542 .valid_tx_ant = ANT_B, /* .cfg overwrite */ 543 .valid_tx_ant = ANT_B, /* .cfg overwrite */
543 .valid_rx_ant = ANT_AB, /* .cfg overwrite */ 544 .valid_rx_ant = ANT_AB, /* .cfg overwrite */
544 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
545 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
546 .ops = &iwl5000_ops,
547 .mod_params = &iwlagn_mod_params,
548 .base_params = &iwl5000_base_params,
549 .ht_params = &iwl5000_ht_params, 545 .ht_params = &iwl5000_ht_params,
550 .led_mode = IWL_LED_BLINK,
551}; 546};
552 547
553struct iwl_cfg iwl5100_abg_cfg = { 548struct iwl_cfg iwl5100_abg_cfg = {
554 .name = "Intel(R) WiFi Link 5100 ABG", 549 .name = "Intel(R) WiFi Link 5100 ABG",
555 .fw_name_pre = IWL5000_FW_PRE, 550 IWL_DEVICE_5000,
556 .ucode_api_max = IWL5000_UCODE_API_MAX,
557 .ucode_api_min = IWL5000_UCODE_API_MIN,
558 .valid_tx_ant = ANT_B, /* .cfg overwrite */ 551 .valid_tx_ant = ANT_B, /* .cfg overwrite */
559 .valid_rx_ant = ANT_AB, /* .cfg overwrite */ 552 .valid_rx_ant = ANT_AB, /* .cfg overwrite */
560 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
561 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
562 .ops = &iwl5000_ops,
563 .mod_params = &iwlagn_mod_params,
564 .base_params = &iwl5000_base_params,
565 .led_mode = IWL_LED_BLINK,
566}; 553};
567 554
568struct iwl_cfg iwl5100_agn_cfg = { 555struct iwl_cfg iwl5100_agn_cfg = {
569 .name = "Intel(R) WiFi Link 5100 AGN", 556 .name = "Intel(R) WiFi Link 5100 AGN",
570 .fw_name_pre = IWL5000_FW_PRE, 557 IWL_DEVICE_5000,
571 .ucode_api_max = IWL5000_UCODE_API_MAX,
572 .ucode_api_min = IWL5000_UCODE_API_MIN,
573 .valid_tx_ant = ANT_B, /* .cfg overwrite */ 558 .valid_tx_ant = ANT_B, /* .cfg overwrite */
574 .valid_rx_ant = ANT_AB, /* .cfg overwrite */ 559 .valid_rx_ant = ANT_AB, /* .cfg overwrite */
575 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
576 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
577 .ops = &iwl5000_ops,
578 .mod_params = &iwlagn_mod_params,
579 .base_params = &iwl5000_base_params,
580 .ht_params = &iwl5000_ht_params, 560 .ht_params = &iwl5000_ht_params,
581 .led_mode = IWL_LED_BLINK,
582}; 561};
583 562
584struct iwl_cfg iwl5350_agn_cfg = { 563struct iwl_cfg iwl5350_agn_cfg = {
@@ -593,35 +572,32 @@ struct iwl_cfg iwl5350_agn_cfg = {
593 .base_params = &iwl5000_base_params, 572 .base_params = &iwl5000_base_params,
594 .ht_params = &iwl5000_ht_params, 573 .ht_params = &iwl5000_ht_params,
595 .led_mode = IWL_LED_BLINK, 574 .led_mode = IWL_LED_BLINK,
575 .internal_wimax_coex = true,
596}; 576};
597 577
578#define IWL_DEVICE_5150 \
579 .fw_name_pre = IWL5150_FW_PRE, \
580 .ucode_api_max = IWL5150_UCODE_API_MAX, \
581 .ucode_api_min = IWL5150_UCODE_API_MIN, \
582 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \
583 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
584 .ops = &iwl5150_ops, \
585 .mod_params = &iwlagn_mod_params, \
586 .base_params = &iwl5000_base_params, \
587 .need_dc_calib = true, \
588 .led_mode = IWL_LED_BLINK, \
589 .internal_wimax_coex = true
590
598struct iwl_cfg iwl5150_agn_cfg = { 591struct iwl_cfg iwl5150_agn_cfg = {
599 .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", 592 .name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
600 .fw_name_pre = IWL5150_FW_PRE, 593 IWL_DEVICE_5150,
601 .ucode_api_max = IWL5150_UCODE_API_MAX,
602 .ucode_api_min = IWL5150_UCODE_API_MIN,
603 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
604 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
605 .ops = &iwl5150_ops,
606 .mod_params = &iwlagn_mod_params,
607 .base_params = &iwl5000_base_params,
608 .ht_params = &iwl5000_ht_params, 594 .ht_params = &iwl5000_ht_params,
609 .need_dc_calib = true, 595
610 .led_mode = IWL_LED_BLINK,
611}; 596};
612 597
613struct iwl_cfg iwl5150_abg_cfg = { 598struct iwl_cfg iwl5150_abg_cfg = {
614 .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", 599 .name = "Intel(R) WiMAX/WiFi Link 5150 ABG",
615 .fw_name_pre = IWL5150_FW_PRE, 600 IWL_DEVICE_5150,
616 .ucode_api_max = IWL5150_UCODE_API_MAX,
617 .ucode_api_min = IWL5150_UCODE_API_MIN,
618 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
619 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
620 .ops = &iwl5150_ops,
621 .mod_params = &iwlagn_mod_params,
622 .base_params = &iwl5000_base_params,
623 .need_dc_calib = true,
624 .led_mode = IWL_LED_BLINK,
625}; 601};
626 602
627MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); 603MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index a848ca06dc6f..f4bec3201ef9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -182,7 +182,11 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
182 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; 182 priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
183 183
184 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); 184 priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
185 priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); 185 if (priv->cfg->rx_with_siso_diversity)
186 priv->hw_params.rx_chains_num = 1;
187 else
188 priv->hw_params.rx_chains_num =
189 num_of_ant(priv->cfg->valid_rx_ant);
186 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; 190 priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
187 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; 191 priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
188 192
@@ -511,7 +515,7 @@ static struct iwl_base_params iwl6050_base_params = {
511 .chain_noise_calib_by_driver = true, 515 .chain_noise_calib_by_driver = true,
512 .shadow_reg_enable = true, 516 .shadow_reg_enable = true,
513}; 517};
514static struct iwl_base_params iwl6000_coex_base_params = { 518static struct iwl_base_params iwl6000_g2_base_params = {
515 .eeprom_size = OTP_LOW_IMAGE_SIZE, 519 .eeprom_size = OTP_LOW_IMAGE_SIZE,
516 .num_of_queues = IWLAGN_NUM_QUEUES, 520 .num_of_queues = IWLAGN_NUM_QUEUES,
517 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, 521 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
@@ -520,7 +524,7 @@ static struct iwl_base_params iwl6000_coex_base_params = {
520 .use_bsm = false, 524 .use_bsm = false,
521 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 525 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
522 .shadow_ram_support = true, 526 .shadow_ram_support = true,
523 .led_compensation = 51, 527 .led_compensation = 57,
524 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 528 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
525 .supports_idle = true, 529 .supports_idle = true,
526 .adv_thermal_throttle = true, 530 .adv_thermal_throttle = true,
@@ -550,243 +554,156 @@ static struct iwl_bt_params iwl6000_bt_params = {
550 .bt_sco_disable = true, 554 .bt_sco_disable = true,
551}; 555};
552 556
557#define IWL_DEVICE_6005 \
558 .fw_name_pre = IWL6000G2A_FW_PRE, \
559 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
560 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
561 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \
562 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \
563 .ops = &iwl6000_ops, \
564 .mod_params = &iwlagn_mod_params, \
565 .base_params = &iwl6000_g2_base_params, \
566 .need_dc_calib = true, \
567 .need_temp_offset_calib = true, \
568 .led_mode = IWL_LED_RF_STATE
569
553struct iwl_cfg iwl6005_2agn_cfg = { 570struct iwl_cfg iwl6005_2agn_cfg = {
554 .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", 571 .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN",
555 .fw_name_pre = IWL6000G2A_FW_PRE, 572 IWL_DEVICE_6005,
556 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
557 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
558 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
559 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
560 .ops = &iwl6000_ops,
561 .mod_params = &iwlagn_mod_params,
562 .base_params = &iwl6000_base_params,
563 .ht_params = &iwl6000_ht_params, 573 .ht_params = &iwl6000_ht_params,
564 .need_dc_calib = true,
565 .need_temp_offset_calib = true,
566 .led_mode = IWL_LED_RF_STATE,
567 .use_new_eeprom_reading = true,
568}; 574};
569 575
570struct iwl_cfg iwl6005_2abg_cfg = { 576struct iwl_cfg iwl6005_2abg_cfg = {
571 .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", 577 .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG",
572 .fw_name_pre = IWL6000G2A_FW_PRE, 578 IWL_DEVICE_6005,
573 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
574 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
575 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
576 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
577 .ops = &iwl6000_ops,
578 .mod_params = &iwlagn_mod_params,
579 .base_params = &iwl6000_base_params,
580 .need_dc_calib = true,
581 .need_temp_offset_calib = true,
582 .led_mode = IWL_LED_RF_STATE,
583 .use_new_eeprom_reading = true,
584}; 579};
585 580
586struct iwl_cfg iwl6005_2bg_cfg = { 581struct iwl_cfg iwl6005_2bg_cfg = {
587 .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", 582 .name = "Intel(R) Centrino(R) Advanced-N 6205 BG",
588 .fw_name_pre = IWL6000G2A_FW_PRE, 583 IWL_DEVICE_6005,
589 .ucode_api_max = IWL6000G2_UCODE_API_MAX, 584};
590 .ucode_api_min = IWL6000G2_UCODE_API_MIN, 585
591 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, 586#define IWL_DEVICE_6030 \
592 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 587 .fw_name_pre = IWL6000G2B_FW_PRE, \
593 .ops = &iwl6000_ops, 588 .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
594 .mod_params = &iwlagn_mod_params, 589 .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
595 .base_params = &iwl6000_base_params, 590 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \
596 .need_dc_calib = true, 591 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \
597 .need_temp_offset_calib = true, 592 .ops = &iwl6000g2b_ops, \
598 .led_mode = IWL_LED_RF_STATE, 593 .mod_params = &iwlagn_mod_params, \
599 .use_new_eeprom_reading = true, 594 .base_params = &iwl6000_g2_base_params, \
600}; 595 .bt_params = &iwl6000_bt_params, \
596 .need_dc_calib = true, \
597 .need_temp_offset_calib = true, \
598 .led_mode = IWL_LED_RF_STATE, \
599 .adv_pm = true, \
600 /* \
601 *Due to bluetooth, we transmit 2.4 GHz probes \
602 * only on antenna A \
603 */ \
604 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A
601 605
602struct iwl_cfg iwl6030_2agn_cfg = { 606struct iwl_cfg iwl6030_2agn_cfg = {
603 .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", 607 .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
604 .fw_name_pre = IWL6000G2B_FW_PRE, 608 IWL_DEVICE_6030,
605 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
606 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
607 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
608 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
609 .ops = &iwl6000g2b_ops,
610 .mod_params = &iwlagn_mod_params,
611 .base_params = &iwl6000_coex_base_params,
612 .bt_params = &iwl6000_bt_params,
613 .ht_params = &iwl6000_ht_params, 609 .ht_params = &iwl6000_ht_params,
614 .need_dc_calib = true,
615 .need_temp_offset_calib = true,
616 .led_mode = IWL_LED_RF_STATE,
617 .adv_pm = true,
618 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
619 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
620 .use_new_eeprom_reading = true,
621}; 610};
622 611
623struct iwl_cfg iwl6030_2abg_cfg = { 612struct iwl_cfg iwl6030_2abg_cfg = {
624 .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", 613 .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG",
625 .fw_name_pre = IWL6000G2B_FW_PRE, 614 IWL_DEVICE_6030,
626 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
627 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
628 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
629 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
630 .ops = &iwl6000g2b_ops,
631 .mod_params = &iwlagn_mod_params,
632 .base_params = &iwl6000_coex_base_params,
633 .bt_params = &iwl6000_bt_params,
634 .need_dc_calib = true,
635 .need_temp_offset_calib = true,
636 .led_mode = IWL_LED_RF_STATE,
637 .adv_pm = true,
638 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
639 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
640 .use_new_eeprom_reading = true,
641}; 615};
642 616
643struct iwl_cfg iwl6030_2bgn_cfg = { 617struct iwl_cfg iwl6030_2bgn_cfg = {
644 .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", 618 .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN",
645 .fw_name_pre = IWL6000G2B_FW_PRE, 619 IWL_DEVICE_6030,
646 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
647 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
648 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
649 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
650 .ops = &iwl6000g2b_ops,
651 .mod_params = &iwlagn_mod_params,
652 .base_params = &iwl6000_coex_base_params,
653 .bt_params = &iwl6000_bt_params,
654 .ht_params = &iwl6000_ht_params, 620 .ht_params = &iwl6000_ht_params,
655 .need_dc_calib = true,
656 .need_temp_offset_calib = true,
657 .led_mode = IWL_LED_RF_STATE,
658 .adv_pm = true,
659 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
660 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
661 .use_new_eeprom_reading = true,
662}; 621};
663 622
664struct iwl_cfg iwl6030_2bg_cfg = { 623struct iwl_cfg iwl6030_2bg_cfg = {
665 .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", 624 .name = "Intel(R) Centrino(R) Advanced-N 6230 BG",
666 .fw_name_pre = IWL6000G2B_FW_PRE, 625 IWL_DEVICE_6030,
667 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
668 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
669 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
670 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
671 .ops = &iwl6000g2b_ops,
672 .mod_params = &iwlagn_mod_params,
673 .base_params = &iwl6000_coex_base_params,
674 .bt_params = &iwl6000_bt_params,
675 .need_dc_calib = true,
676 .need_temp_offset_calib = true,
677 .led_mode = IWL_LED_RF_STATE,
678 .adv_pm = true,
679 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
680 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
681 .use_new_eeprom_reading = true,
682}; 626};
683 627
684struct iwl_cfg iwl1030_bgn_cfg = { 628struct iwl_cfg iwl1030_bgn_cfg = {
685 .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", 629 .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN",
686 .fw_name_pre = IWL6000G2B_FW_PRE, 630 IWL_DEVICE_6030,
687 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
688 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
689 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
690 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
691 .ops = &iwl6000g2b_ops,
692 .mod_params = &iwlagn_mod_params,
693 .base_params = &iwl6000_coex_base_params,
694 .bt_params = &iwl6000_bt_params,
695 .ht_params = &iwl6000_ht_params, 631 .ht_params = &iwl6000_ht_params,
696 .need_dc_calib = true,
697 .need_temp_offset_calib = true,
698 .led_mode = IWL_LED_RF_STATE,
699 .adv_pm = true,
700 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
701 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
702 .use_new_eeprom_reading = true,
703}; 632};
704 633
705struct iwl_cfg iwl1030_bg_cfg = { 634struct iwl_cfg iwl1030_bg_cfg = {
706 .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", 635 .name = "Intel(R) Centrino(R) Wireless-N 1030 BG",
707 .fw_name_pre = IWL6000G2B_FW_PRE, 636 IWL_DEVICE_6030,
708 .ucode_api_max = IWL6000G2_UCODE_API_MAX, 637};
709 .ucode_api_min = IWL6000G2_UCODE_API_MIN, 638
710 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, 639struct iwl_cfg iwl130_bgn_cfg = {
711 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, 640 .name = "Intel(R) Centrino(R) Wireless-N 130 BGN",
712 .ops = &iwl6000g2b_ops, 641 IWL_DEVICE_6030,
713 .mod_params = &iwlagn_mod_params, 642 .ht_params = &iwl6000_ht_params,
714 .base_params = &iwl6000_coex_base_params, 643 .rx_with_siso_diversity = true,
715 .bt_params = &iwl6000_bt_params, 644};
716 .need_dc_calib = true, 645
717 .need_temp_offset_calib = true, 646struct iwl_cfg iwl130_bg_cfg = {
718 .led_mode = IWL_LED_RF_STATE, 647 .name = "Intel(R) Centrino(R) Wireless-N 130 BG",
719 .adv_pm = true, 648 IWL_DEVICE_6030,
720 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ 649 .rx_with_siso_diversity = true,
721 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
722 .use_new_eeprom_reading = true,
723}; 650};
724 651
725/* 652/*
726 * "i": Internal configuration, use internal Power Amplifier 653 * "i": Internal configuration, use internal Power Amplifier
727 */ 654 */
655#define IWL_DEVICE_6000i \
656 .fw_name_pre = IWL6000_FW_PRE, \
657 .ucode_api_max = IWL6000_UCODE_API_MAX, \
658 .ucode_api_min = IWL6000_UCODE_API_MIN, \
659 .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \
660 .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \
661 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \
662 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \
663 .ops = &iwl6000_ops, \
664 .mod_params = &iwlagn_mod_params, \
665 .base_params = &iwl6000_base_params, \
666 .pa_type = IWL_PA_INTERNAL, \
667 .led_mode = IWL_LED_BLINK
668
728struct iwl_cfg iwl6000i_2agn_cfg = { 669struct iwl_cfg iwl6000i_2agn_cfg = {
729 .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", 670 .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
730 .fw_name_pre = IWL6000_FW_PRE, 671 IWL_DEVICE_6000i,
731 .ucode_api_max = IWL6000_UCODE_API_MAX,
732 .ucode_api_min = IWL6000_UCODE_API_MIN,
733 .valid_tx_ant = ANT_BC, /* .cfg overwrite */
734 .valid_rx_ant = ANT_BC, /* .cfg overwrite */
735 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
736 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
737 .ops = &iwl6000_ops,
738 .mod_params = &iwlagn_mod_params,
739 .base_params = &iwl6000_base_params,
740 .ht_params = &iwl6000_ht_params, 672 .ht_params = &iwl6000_ht_params,
741 .pa_type = IWL_PA_INTERNAL,
742 .led_mode = IWL_LED_BLINK,
743}; 673};
744 674
745struct iwl_cfg iwl6000i_2abg_cfg = { 675struct iwl_cfg iwl6000i_2abg_cfg = {
746 .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", 676 .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG",
747 .fw_name_pre = IWL6000_FW_PRE, 677 IWL_DEVICE_6000i,
748 .ucode_api_max = IWL6000_UCODE_API_MAX,
749 .ucode_api_min = IWL6000_UCODE_API_MIN,
750 .valid_tx_ant = ANT_BC, /* .cfg overwrite */
751 .valid_rx_ant = ANT_BC, /* .cfg overwrite */
752 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
753 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
754 .ops = &iwl6000_ops,
755 .mod_params = &iwlagn_mod_params,
756 .base_params = &iwl6000_base_params,
757 .pa_type = IWL_PA_INTERNAL,
758 .led_mode = IWL_LED_BLINK,
759}; 678};
760 679
761struct iwl_cfg iwl6000i_2bg_cfg = { 680struct iwl_cfg iwl6000i_2bg_cfg = {
762 .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", 681 .name = "Intel(R) Centrino(R) Advanced-N 6200 BG",
763 .fw_name_pre = IWL6000_FW_PRE, 682 IWL_DEVICE_6000i,
764 .ucode_api_max = IWL6000_UCODE_API_MAX, 683};
765 .ucode_api_min = IWL6000_UCODE_API_MIN, 684
766 .valid_tx_ant = ANT_BC, /* .cfg overwrite */ 685#define IWL_DEVICE_6050 \
767 .valid_rx_ant = ANT_BC, /* .cfg overwrite */ 686 .fw_name_pre = IWL6050_FW_PRE, \
768 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 687 .ucode_api_max = IWL6050_UCODE_API_MAX, \
769 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, 688 .ucode_api_min = IWL6050_UCODE_API_MIN, \
770 .ops = &iwl6000_ops, 689 .ops = &iwl6050_ops, \
771 .mod_params = &iwlagn_mod_params, 690 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \
772 .base_params = &iwl6000_base_params, 691 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \
773 .pa_type = IWL_PA_INTERNAL, 692 .mod_params = &iwlagn_mod_params, \
774 .led_mode = IWL_LED_BLINK, 693 .base_params = &iwl6050_base_params, \
775}; 694 .need_dc_calib = true, \
695 .led_mode = IWL_LED_BLINK, \
696 .internal_wimax_coex = true
776 697
777struct iwl_cfg iwl6050_2agn_cfg = { 698struct iwl_cfg iwl6050_2agn_cfg = {
778 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", 699 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
779 .fw_name_pre = IWL6050_FW_PRE, 700 IWL_DEVICE_6050,
780 .ucode_api_max = IWL6050_UCODE_API_MAX,
781 .ucode_api_min = IWL6050_UCODE_API_MIN,
782 .ops = &iwl6050_ops,
783 .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
784 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
785 .mod_params = &iwlagn_mod_params,
786 .base_params = &iwl6050_base_params,
787 .ht_params = &iwl6000_ht_params, 701 .ht_params = &iwl6000_ht_params,
788 .need_dc_calib = true, 702};
789 .led_mode = IWL_LED_BLINK, 703
704struct iwl_cfg iwl6050_2abg_cfg = {
705 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
706 IWL_DEVICE_6050,
790}; 707};
791 708
792struct iwl_cfg iwl6150_bgn_cfg = { 709struct iwl_cfg iwl6150_bgn_cfg = {
@@ -802,21 +719,7 @@ struct iwl_cfg iwl6150_bgn_cfg = {
802 .ht_params = &iwl6000_ht_params, 719 .ht_params = &iwl6000_ht_params,
803 .need_dc_calib = true, 720 .need_dc_calib = true,
804 .led_mode = IWL_LED_RF_STATE, 721 .led_mode = IWL_LED_RF_STATE,
805 .use_new_eeprom_reading = true, 722 .internal_wimax_coex = true,
806};
807
808struct iwl_cfg iwl6050_2abg_cfg = {
809 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
810 .fw_name_pre = IWL6050_FW_PRE,
811 .ucode_api_max = IWL6050_UCODE_API_MAX,
812 .ucode_api_min = IWL6050_UCODE_API_MIN,
813 .eeprom_ver = EEPROM_6050_EEPROM_VERSION,
814 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,
815 .ops = &iwl6050_ops,
816 .mod_params = &iwlagn_mod_params,
817 .base_params = &iwl6050_base_params,
818 .need_dc_calib = true,
819 .led_mode = IWL_LED_BLINK,
820}; 723};
821 724
822struct iwl_cfg iwl6000_3agn_cfg = { 725struct iwl_cfg iwl6000_3agn_cfg = {
@@ -834,45 +737,6 @@ struct iwl_cfg iwl6000_3agn_cfg = {
834 .led_mode = IWL_LED_BLINK, 737 .led_mode = IWL_LED_BLINK,
835}; 738};
836 739
837struct iwl_cfg iwl130_bgn_cfg = {
838 .name = "Intel(R) Centrino(R) Wireless-N 130 BGN",
839 .fw_name_pre = IWL6000G2B_FW_PRE,
840 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
841 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
842 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
843 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
844 .ops = &iwl6000g2b_ops,
845 .mod_params = &iwlagn_mod_params,
846 .base_params = &iwl6000_coex_base_params,
847 .bt_params = &iwl6000_bt_params,
848 .ht_params = &iwl6000_ht_params,
849 .need_dc_calib = true,
850 .led_mode = IWL_LED_RF_STATE,
851 .adv_pm = true,
852 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
853 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
854 .use_new_eeprom_reading = true,
855};
856
857struct iwl_cfg iwl130_bg_cfg = {
858 .name = "Intel(R) Centrino(R) Wireless-N 130 BG",
859 .fw_name_pre = IWL6000G2B_FW_PRE,
860 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
861 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
862 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
863 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
864 .ops = &iwl6000g2b_ops,
865 .mod_params = &iwlagn_mod_params,
866 .base_params = &iwl6000_coex_base_params,
867 .bt_params = &iwl6000_bt_params,
868 .need_dc_calib = true,
869 .led_mode = IWL_LED_RF_STATE,
870 .adv_pm = true,
871 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
872 .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A,
873 .use_new_eeprom_reading = true,
874};
875
876MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 740MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
877MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); 741MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
878MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); 742MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
index a358d4334a1a..a6dbd8983dac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -856,6 +856,9 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file,
856 if (!iwl_is_alive(priv)) 856 if (!iwl_is_alive(priv))
857 return -EAGAIN; 857 return -EAGAIN;
858 858
859 if (!priv->bt_enable_flag)
860 return -EINVAL;
861
859 /* make request to uCode to retrieve statistics information */ 862 /* make request to uCode to retrieve statistics information */
860 mutex_lock(&priv->mutex); 863 mutex_lock(&priv->mutex);
861 ret = iwl_send_statistics_request(priv, CMD_SYNC, false); 864 ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
index cf9194baadac..97906dd442e6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
@@ -75,109 +75,6 @@
75#include "iwl-agn.h" 75#include "iwl-agn.h"
76#include "iwl-io.h" 76#include "iwl-io.h"
77 77
78/************************** EEPROM BANDS ****************************
79 *
80 * The iwl_eeprom_band definitions below provide the mapping from the
81 * EEPROM contents to the specific channel number supported for each
82 * band.
83 *
84 * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3
85 * definition below maps to physical channel 42 in the 5.2GHz spectrum.
86 * The specific geography and calibration information for that channel
87 * is contained in the eeprom map itself.
88 *
89 * During init, we copy the eeprom information and channel map
90 * information into priv->channel_info_24/52 and priv->channel_map_24/52
91 *
92 * channel_map_24/52 provides the index in the channel_info array for a
93 * given channel. We have to have two separate maps as there is channel
94 * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and
95 * band_2
96 *
97 * A value of 0xff stored in the channel_map indicates that the channel
98 * is not supported by the hardware at all.
99 *
100 * A value of 0xfe in the channel_map indicates that the channel is not
101 * valid for Tx with the current hardware. This means that
102 * while the system can tune and receive on a given channel, it may not
103 * be able to associate or transmit any frames on that
104 * channel. There is no corresponding channel information for that
105 * entry.
106 *
107 *********************************************************************/
108
109/**
110 * struct iwl_txpwr_section: eeprom section information
111 * @offset: indirect address into eeprom image
112 * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section
113 * @band: band type for the section
114 * @is_common - true: common section, false: channel section
115 * @is_cck - true: cck section, false: not cck section
116 * @is_ht_40 - true: all channel in the section are HT40 channel,
117 * false: legacy or HT 20 MHz
118 * ignore if it is common section
119 * @iwl_eeprom_section_channel: channel array in the section,
120 * ignore if common section
121 */
122struct iwl_txpwr_section {
123 u32 offset;
124 u8 count;
125 enum ieee80211_band band;
126 bool is_common;
127 bool is_cck;
128 bool is_ht40;
129 u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS];
130};
131
132/**
133 * section 1 - 3 are regulatory tx power apply to all channels based on
134 * modulation: CCK, OFDM
135 * Band: 2.4GHz, 5.2GHz
136 * section 4 - 10 are regulatory tx power apply to specified channels
137 * For example:
138 * 1L - Channel 1 Legacy
139 * 1HT - Channel 1 HT
140 * (1,+1) - Channel 1 HT40 "_above_"
141 *
142 * Section 1: all CCK channels
143 * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels
144 * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
145 * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT
146 * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1)
147 * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT
148 * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1)
149 * Section 8: 2.4 GHz channel: 13L, 13HT
150 * Section 9: 2.4 GHz channel: 140L, 140HT
151 * Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1)
152 *
153 */
154static const struct iwl_txpwr_section enhinfo[] = {
155 { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false },
156 { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false },
157 { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false },
158 { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ,
159 false, false, false,
160 {1, 1, 2, 2, 10, 10, 11, 11 } },
161 { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ,
162 false, false, true,
163 { 1, 2, 6, 7, 9 } },
164 { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ,
165 false, false, false,
166 { 36, 64, 100, 36, 64, 100 } },
167 { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ,
168 false, false, true,
169 { 36, 60, 100 } },
170 { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ,
171 false, false, false,
172 { 13, 13 } },
173 { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ,
174 false, false, false,
175 { 140, 140 } },
176 { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ,
177 false, false, true,
178 { 132, 44 } },
179};
180
181/****************************************************************************** 78/******************************************************************************
182 * 79 *
183 * EEPROM related functions 80 * EEPROM related functions
@@ -306,15 +203,6 @@ static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
306{ 203{
307 s8 max_txpower_avg = 0; /* (dBm) */ 204 s8 max_txpower_avg = 0; /* (dBm) */
308 205
309 IWL_DEBUG_INFO(priv, "%d - "
310 "chain_a: %d dB chain_b: %d dB "
311 "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n",
312 element,
313 enhanced_txpower[element].chain_a_max >> 1,
314 enhanced_txpower[element].chain_b_max >> 1,
315 enhanced_txpower[element].chain_c_max >> 1,
316 enhanced_txpower[element].mimo2_max >> 1,
317 enhanced_txpower[element].mimo3_max >> 1);
318 /* Take the highest tx power from any valid chains */ 206 /* Take the highest tx power from any valid chains */
319 if ((priv->cfg->valid_tx_ant & ANT_A) && 207 if ((priv->cfg->valid_tx_ant & ANT_A) &&
320 (enhanced_txpower[element].chain_a_max > max_txpower_avg)) 208 (enhanced_txpower[element].chain_a_max > max_txpower_avg))
@@ -344,157 +232,6 @@ static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
344 return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1); 232 return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1);
345} 233}
346 234
347/**
348 * iwl_update_common_txpower: update channel tx power
349 * update tx power per band based on EEPROM enhanced tx power info.
350 */
351static s8 iwl_update_common_txpower(struct iwl_priv *priv,
352 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
353 int section, int element, s8 *max_txpower_in_half_dbm)
354{
355 struct iwl_channel_info *ch_info;
356 int ch;
357 bool is_ht40 = false;
358 s8 max_txpower_avg; /* (dBm) */
359
360 /* it is common section, contain all type (Legacy, HT and HT40)
361 * based on the element in the section to determine
362 * is it HT 40 or not
363 */
364 if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
365 is_ht40 = true;
366 max_txpower_avg =
367 iwl_get_max_txpower_avg(priv, enhanced_txpower,
368 element, max_txpower_in_half_dbm);
369
370 ch_info = priv->channel_info;
371
372 for (ch = 0; ch < priv->channel_count; ch++) {
373 /* find matching band and update tx power if needed */
374 if ((ch_info->band == enhinfo[section].band) &&
375 (ch_info->max_power_avg < max_txpower_avg) &&
376 (!is_ht40)) {
377 /* Update regulatory-based run-time data */
378 ch_info->max_power_avg = ch_info->curr_txpow =
379 max_txpower_avg;
380 ch_info->scan_power = max_txpower_avg;
381 }
382 if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
383 (ch_info->ht40_max_power_avg < max_txpower_avg)) {
384 /* Update regulatory-based run-time data */
385 ch_info->ht40_max_power_avg = max_txpower_avg;
386 }
387 ch_info++;
388 }
389 return max_txpower_avg;
390}
391
392/**
393 * iwl_update_channel_txpower: update channel tx power
394 * update channel tx power based on EEPROM enhanced tx power info.
395 */
396static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
397 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
398 int section, int element, s8 *max_txpower_in_half_dbm)
399{
400 struct iwl_channel_info *ch_info;
401 int ch;
402 u8 channel;
403 s8 max_txpower_avg; /* (dBm) */
404
405 channel = enhinfo[section].iwl_eeprom_section_channel[element];
406 max_txpower_avg =
407 iwl_get_max_txpower_avg(priv, enhanced_txpower,
408 element, max_txpower_in_half_dbm);
409
410 ch_info = priv->channel_info;
411 for (ch = 0; ch < priv->channel_count; ch++) {
412 /* find matching channel and update tx power if needed */
413 if (ch_info->channel == channel) {
414 if ((ch_info->max_power_avg < max_txpower_avg) &&
415 (!enhinfo[section].is_ht40)) {
416 /* Update regulatory-based run-time data */
417 ch_info->max_power_avg = max_txpower_avg;
418 ch_info->curr_txpow = max_txpower_avg;
419 ch_info->scan_power = max_txpower_avg;
420 }
421 if ((enhinfo[section].is_ht40) &&
422 (ch_info->ht40_max_power_avg < max_txpower_avg)) {
423 /* Update regulatory-based run-time data */
424 ch_info->ht40_max_power_avg = max_txpower_avg;
425 }
426 break;
427 }
428 ch_info++;
429 }
430 return max_txpower_avg;
431}
432
433/**
434 * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
435 */
436static void iwlcore_eeprom_enhanced_txpower_old(struct iwl_priv *priv)
437{
438 int eeprom_section_count = 0;
439 int section, element;
440 struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
441 u32 offset;
442 s8 max_txpower_avg; /* (dBm) */
443 s8 max_txpower_in_half_dbm; /* (half-dBm) */
444
445 /* Loop through all the sections
446 * adjust bands and channel's max tx power
447 * Set the tx_power_user_lmt to the highest power
448 * supported by any channels and chains
449 */
450 for (section = 0; section < ARRAY_SIZE(enhinfo); section++) {
451 eeprom_section_count = enhinfo[section].count;
452 offset = enhinfo[section].offset;
453 enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
454 iwl_eeprom_query_addr(priv, offset);
455
456 /*
457 * check for valid entry -
458 * different version of EEPROM might contain different set
459 * of enhanced tx power table
460 * always check for valid entry before process
461 * the information
462 */
463 if (!(enhanced_txpower->flags || enhanced_txpower->channel) ||
464 enhanced_txpower->delta_20_in_40)
465 continue;
466
467 for (element = 0; element < eeprom_section_count; element++) {
468 if (enhinfo[section].is_common)
469 max_txpower_avg =
470 iwl_update_common_txpower(priv,
471 enhanced_txpower, section,
472 element,
473 &max_txpower_in_half_dbm);
474 else
475 max_txpower_avg =
476 iwl_update_channel_txpower(priv,
477 enhanced_txpower, section,
478 element,
479 &max_txpower_in_half_dbm);
480
481 /* Update the tx_power_user_lmt to the highest power
482 * supported by any channel */
483 if (max_txpower_avg > priv->tx_power_user_lmt)
484 priv->tx_power_user_lmt = max_txpower_avg;
485
486 /*
487 * Update the tx_power_lmt_in_half_dbm to
488 * the highest power supported by any channel
489 */
490 if (max_txpower_in_half_dbm >
491 priv->tx_power_lmt_in_half_dbm)
492 priv->tx_power_lmt_in_half_dbm =
493 max_txpower_in_half_dbm;
494 }
495 }
496}
497
498static void 235static void
499iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv, 236iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv,
500 struct iwl_eeprom_enhanced_txpwr *txp, 237 struct iwl_eeprom_enhanced_txpwr *txp,
@@ -533,7 +270,10 @@ iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv,
533#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) 270#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr)
534#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) 271#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE)
535 272
536static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv) 273#define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \
274 ? # x " " : "")
275
276void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
537{ 277{
538 struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; 278 struct iwl_eeprom_enhanced_txpwr *txp_array, *txp;
539 int idx, entries; 279 int idx, entries;
@@ -547,13 +287,39 @@ static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv)
547 entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; 287 entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN;
548 288
549 txp_array = (void *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_OFFS); 289 txp_array = (void *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_OFFS);
290
550 for (idx = 0; idx < entries; idx++) { 291 for (idx = 0; idx < entries; idx++) {
551 txp = &txp_array[idx]; 292 txp = &txp_array[idx];
552
553 /* skip invalid entries */ 293 /* skip invalid entries */
554 if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) 294 if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID))
555 continue; 295 continue;
556 296
297 IWL_DEBUG_EEPROM(priv, "%s %d:\t %s%s%s%s%s%s%s%s (0x%02x)\n",
298 (txp->channel && (txp->flags &
299 IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE)) ?
300 "Common " : (txp->channel) ?
301 "Channel" : "Common",
302 (txp->channel),
303 TXP_CHECK_AND_PRINT(VALID),
304 TXP_CHECK_AND_PRINT(BAND_52G),
305 TXP_CHECK_AND_PRINT(OFDM),
306 TXP_CHECK_AND_PRINT(40MHZ),
307 TXP_CHECK_AND_PRINT(HT_AP),
308 TXP_CHECK_AND_PRINT(RES1),
309 TXP_CHECK_AND_PRINT(RES2),
310 TXP_CHECK_AND_PRINT(COMMON_TYPE),
311 txp->flags);
312 IWL_DEBUG_EEPROM(priv, "\t\t chain_A: 0x%02x "
313 "chain_B: 0X%02x chain_C: 0X%02x\n",
314 txp->chain_a_max, txp->chain_b_max,
315 txp->chain_c_max);
316 IWL_DEBUG_EEPROM(priv, "\t\t MIMO2: 0x%02x "
317 "MIMO3: 0x%02x High 20_on_40: 0x%02x "
318 "Low 20_on_40: 0x%02x\n",
319 txp->mimo2_max, txp->mimo3_max,
320 ((txp->delta_20_in_40 & 0xf0) >> 4),
321 (txp->delta_20_in_40 & 0x0f));
322
557 max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, 323 max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx,
558 &max_txp_avg_halfdbm); 324 &max_txp_avg_halfdbm);
559 325
@@ -569,11 +335,3 @@ static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv)
569 iwlcore_eeprom_enh_txp_read_element(priv, txp, max_txp_avg); 335 iwlcore_eeprom_enh_txp_read_element(priv, txp, max_txp_avg);
570 } 336 }
571} 337}
572
573void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
574{
575 if (priv->cfg->use_new_eeprom_reading)
576 iwlcore_eeprom_enhanced_txpower_new(priv);
577 else
578 iwlcore_eeprom_enhanced_txpower_old(priv);
579}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 7c8010f7ce56..4bc82fcf1652 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1845,6 +1845,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
1845 bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION; 1845 bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION;
1846 IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags); 1846 IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags);
1847 } 1847 }
1848 priv->bt_enable_flag = bt_cmd.flags;
1848 if (priv->bt_full_concurrent) 1849 if (priv->bt_full_concurrent)
1849 memcpy(bt_cmd.bt3_lookup_table, iwlagn_concurrent_lookup, 1850 memcpy(bt_cmd.bt3_lookup_table, iwlagn_concurrent_lookup,
1850 sizeof(iwlagn_concurrent_lookup)); 1851 sizeof(iwlagn_concurrent_lookup));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index f450adc72361..75fcd30a7c13 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -387,7 +387,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
387 if (load > IWL_AGG_LOAD_THRESHOLD) { 387 if (load > IWL_AGG_LOAD_THRESHOLD) {
388 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", 388 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
389 sta->addr, tid); 389 sta->addr, tid);
390 ret = ieee80211_start_tx_ba_session(sta, tid); 390 ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
391 if (ret == -EAGAIN) { 391 if (ret == -EAGAIN) {
392 /* 392 /*
393 * driver and mac80211 is out of sync 393 * driver and mac80211 is out of sync
@@ -2873,6 +2873,10 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
2873 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; 2873 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
2874 lq_sta->is_agg = 0; 2874 lq_sta->is_agg = 0;
2875 2875
2876#ifdef CONFIG_MAC80211_DEBUGFS
2877 lq_sta->dbg_fixed_rate = 0;
2878#endif
2879
2876 rs_initialize_lq(priv, conf, sta, lq_sta); 2880 rs_initialize_lq(priv, conf, sta, lq_sta);
2877} 2881}
2878 2882
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index 4865b82355d7..6d140bd53291 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -518,7 +518,14 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
518 518
519 mutex_lock(&priv->mutex); 519 mutex_lock(&priv->mutex);
520 520
521 if (WARN_ON(!ctx->vif)) { 521 if (unlikely(!iwl_is_ready(priv))) {
522 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
523 mutex_unlock(&priv->mutex);
524 return;
525 }
526
527 if (unlikely(!ctx->vif)) {
528 IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n");
522 mutex_unlock(&priv->mutex); 529 mutex_unlock(&priv->mutex);
523 return; 530 return;
524 } 531 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 72b1f262796c..24a11b8f73bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -1237,7 +1237,6 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1237 int i, sh, ack; 1237 int i, sh, ack;
1238 u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl); 1238 u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
1239 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); 1239 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1240 u64 bitmap, sent_bitmap;
1241 int successes = 0; 1240 int successes = 0;
1242 struct ieee80211_tx_info *info; 1241 struct ieee80211_tx_info *info;
1243 1242
@@ -1278,6 +1277,8 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1278 IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n", 1277 IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
1279 ba_resp->txed, ba_resp->txed_2_done); 1278 ba_resp->txed, ba_resp->txed_2_done);
1280 } else { 1279 } else {
1280 u64 bitmap, sent_bitmap;
1281
1281 /* don't use 64-bit values for now */ 1282 /* don't use 64-bit values for now */
1282 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh; 1283 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1283 1284
@@ -1298,7 +1299,11 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1298 sent_bitmap >>= 1; 1299 sent_bitmap >>= 1;
1299 ++i; 1300 ++i;
1300 } 1301 }
1302
1303 IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n",
1304 (unsigned long long)bitmap);
1301 } 1305 }
1306
1302 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb); 1307 info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb);
1303 memset(&info->status, 0, sizeof(info->status)); 1308 memset(&info->status, 0, sizeof(info->status));
1304 info->flags |= IEEE80211_TX_STAT_ACK; 1309 info->flags |= IEEE80211_TX_STAT_ACK;
@@ -1313,8 +1318,6 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv,
1313 } 1318 }
1314 iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); 1319 iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
1315 1320
1316 IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
1317
1318 return 0; 1321 return 0;
1319} 1322}
1320 1323
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index d62b92518417..efbde1f1a8bf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -957,6 +957,22 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
957 /* Cancel currently queued command. */ 957 /* Cancel currently queued command. */
958 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 958 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
959 959
960 /* W/A for WiFi/WiMAX coex and WiMAX own the RF */
961 if (priv->cfg->internal_wimax_coex &&
962 (!(iwl_read_prph(priv, APMG_CLK_CTRL_REG) &
963 APMS_CLK_VAL_MRB_FUNC_MODE) ||
964 (iwl_read_prph(priv, APMG_PS_CTRL_REG) &
965 APMG_PS_CTRL_VAL_RESET_REQ))) {
966 wake_up_interruptible(&priv->wait_command_queue);
967 /*
968 *Keep the restart process from trying to send host
969 * commands by clearing the INIT status bit
970 */
971 clear_bit(STATUS_READY, &priv->status);
972 IWL_ERR(priv, "RF is used by WiMAX\n");
973 return;
974 }
975
960 IWL_ERR(priv, "Loaded firmware version: %s\n", 976 IWL_ERR(priv, "Loaded firmware version: %s\n",
961 priv->hw->wiphy->fw_version); 977 priv->hw->wiphy->fw_version);
962 978
@@ -1207,6 +1223,7 @@ void iwl_send_bt_config(struct iwl_priv *priv)
1207 else 1223 else
1208 bt_cmd.flags = BT_COEX_ENABLE; 1224 bt_cmd.flags = BT_COEX_ENABLE;
1209 1225
1226 priv->bt_enable_flag = bt_cmd.flags;
1210 IWL_DEBUG_INFO(priv, "BT coex %s\n", 1227 IWL_DEBUG_INFO(priv, "BT coex %s\n",
1211 (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); 1228 (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
1212 1229
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 9df33d6af8bb..f80685ad2674 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -364,6 +364,8 @@ struct iwl_ht_params {
364 * @scan_antennas: available antenna for scan operation 364 * @scan_antennas: available antenna for scan operation
365 * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) 365 * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off)
366 * @adv_pm: advance power management 366 * @adv_pm: advance power management
367 * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
368 * @internal_wimax_coex: internal wifi/wimax combo device
367 * 369 *
368 * We enable the driver to be backward compatible wrt API version. The 370 * We enable the driver to be backward compatible wrt API version. The
369 * driver specifies which APIs it supports (with @ucode_api_max being the 371 * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -412,7 +414,8 @@ struct iwl_cfg {
412 u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; 414 u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
413 enum iwl_led_mode led_mode; 415 enum iwl_led_mode led_mode;
414 const bool adv_pm; 416 const bool adv_pm;
415 const bool use_new_eeprom_reading; /* temporary, remove later */ 417 const bool rx_with_siso_diversity;
418 const bool internal_wimax_coex;
416}; 419};
417 420
418/*************************** 421/***************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 0b961a353ff6..ebdea3be3ef9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -120,6 +120,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
120/* 0x000000F0 - 0x00000010 */ 120/* 0x000000F0 - 0x00000010 */
121#define IWL_DL_MACDUMP (1 << 4) 121#define IWL_DL_MACDUMP (1 << 4)
122#define IWL_DL_HCMD_DUMP (1 << 5) 122#define IWL_DL_HCMD_DUMP (1 << 5)
123#define IWL_DL_EEPROM (1 << 6)
123#define IWL_DL_RADIO (1 << 7) 124#define IWL_DL_RADIO (1 << 7)
124/* 0x00000F00 - 0x00000100 */ 125/* 0x00000F00 - 0x00000100 */
125#define IWL_DL_POWER (1 << 8) 126#define IWL_DL_POWER (1 << 8)
@@ -164,6 +165,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
164#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) 165#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a)
165#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) 166#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a)
166#define IWL_DEBUG_HC_DUMP(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD_DUMP, f, ## a) 167#define IWL_DEBUG_HC_DUMP(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD_DUMP, f, ## a)
168#define IWL_DEBUG_EEPROM(p, f, a...) IWL_DEBUG(p, IWL_DL_EEPROM, f, ## a)
167#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) 169#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a)
168#define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) 170#define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a)
169#define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a) 171#define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index d36836376e6b..6fe80b5e7a15 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1567,6 +1567,13 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file,
1567 const size_t bufsz = sizeof(buf); 1567 const size_t bufsz = sizeof(buf);
1568 ssize_t ret; 1568 ssize_t ret;
1569 1569
1570 if (!priv->bt_enable_flag) {
1571 pos += scnprintf(buf + pos, bufsz - pos, "BT coex disabled\n");
1572 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1573 return ret;
1574 }
1575 pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n",
1576 priv->bt_enable_flag);
1570 pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n", 1577 pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n",
1571 priv->bt_full_concurrent ? "full concurrency" : "3-wire"); 1578 priv->bt_full_concurrent ? "full concurrency" : "3-wire");
1572 pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, " 1579 pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, "
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 836f1816b110..8dda67850af4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1468,6 +1468,7 @@ struct iwl_priv {
1468 }; 1468 };
1469 1469
1470 /* bt coex */ 1470 /* bt coex */
1471 u8 bt_enable_flag;
1471 u8 bt_status; 1472 u8 bt_status;
1472 u8 bt_traffic_load, last_bt_traffic_load; 1473 u8 bt_traffic_load, last_bt_traffic_load;
1473 bool bt_ch_announce; 1474 bool bt_ch_announce;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 87cd10ff285d..358cfd7e5af1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -147,7 +147,7 @@ static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
147 u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; 147 u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
148 int ret = 0; 148 int ret = 0;
149 149
150 IWL_DEBUG_INFO(priv, "EEPROM signature=0x%08x\n", gp); 150 IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp);
151 switch (gp) { 151 switch (gp) {
152 case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: 152 case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP:
153 if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) { 153 if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) {
@@ -354,7 +354,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
354 */ 354 */
355 valid_addr = next_link_addr; 355 valid_addr = next_link_addr;
356 next_link_addr = le16_to_cpu(link_value) * sizeof(u16); 356 next_link_addr = le16_to_cpu(link_value) * sizeof(u16);
357 IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n", 357 IWL_DEBUG_EEPROM(priv, "OTP blocks %d addr 0x%x\n",
358 usedblocks, next_link_addr); 358 usedblocks, next_link_addr);
359 if (iwl_read_otp_word(priv, next_link_addr, &link_value)) 359 if (iwl_read_otp_word(priv, next_link_addr, &link_value))
360 return -EINVAL; 360 return -EINVAL;
@@ -374,7 +374,7 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
374 } while (usedblocks <= priv->cfg->base_params->max_ll_items); 374 } while (usedblocks <= priv->cfg->base_params->max_ll_items);
375 375
376 /* OTP has no valid blocks */ 376 /* OTP has no valid blocks */
377 IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n"); 377 IWL_DEBUG_EEPROM(priv, "OTP has no valid blocks\n");
378 return -EINVAL; 378 return -EINVAL;
379} 379}
380 380
@@ -414,7 +414,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
414 return -ENOENT; 414 return -ENOENT;
415 /* allocate eeprom */ 415 /* allocate eeprom */
416 sz = priv->cfg->base_params->eeprom_size; 416 sz = priv->cfg->base_params->eeprom_size;
417 IWL_DEBUG_INFO(priv, "NVM size = %d\n", sz); 417 IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz);
418 priv->eeprom = kzalloc(sz, GFP_KERNEL); 418 priv->eeprom = kzalloc(sz, GFP_KERNEL);
419 if (!priv->eeprom) { 419 if (!priv->eeprom) {
420 ret = -ENOMEM; 420 ret = -ENOMEM;
@@ -492,7 +492,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
492 } 492 }
493 } 493 }
494 494
495 IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n", 495 IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n",
496 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) 496 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
497 ? "OTP" : "EEPROM", 497 ? "OTP" : "EEPROM",
498 iwl_eeprom_query16(priv, EEPROM_VERSION)); 498 iwl_eeprom_query16(priv, EEPROM_VERSION));
@@ -594,7 +594,7 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
594 if (!is_channel_valid(ch_info)) 594 if (!is_channel_valid(ch_info))
595 return -1; 595 return -1;
596 596
597 IWL_DEBUG_INFO(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):" 597 IWL_DEBUG_EEPROM(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
598 " Ad-Hoc %ssupported\n", 598 " Ad-Hoc %ssupported\n",
599 ch_info->channel, 599 ch_info->channel,
600 is_channel_a_band(ch_info) ? 600 is_channel_a_band(ch_info) ?
@@ -634,11 +634,11 @@ int iwl_init_channel_map(struct iwl_priv *priv)
634 struct iwl_channel_info *ch_info; 634 struct iwl_channel_info *ch_info;
635 635
636 if (priv->channel_count) { 636 if (priv->channel_count) {
637 IWL_DEBUG_INFO(priv, "Channel map already initialized.\n"); 637 IWL_DEBUG_EEPROM(priv, "Channel map already initialized.\n");
638 return 0; 638 return 0;
639 } 639 }
640 640
641 IWL_DEBUG_INFO(priv, "Initializing regulatory info from EEPROM\n"); 641 IWL_DEBUG_EEPROM(priv, "Initializing regulatory info from EEPROM\n");
642 642
643 priv->channel_count = 643 priv->channel_count =
644 ARRAY_SIZE(iwl_eeprom_band_1) + 644 ARRAY_SIZE(iwl_eeprom_band_1) +
@@ -647,7 +647,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
647 ARRAY_SIZE(iwl_eeprom_band_4) + 647 ARRAY_SIZE(iwl_eeprom_band_4) +
648 ARRAY_SIZE(iwl_eeprom_band_5); 648 ARRAY_SIZE(iwl_eeprom_band_5);
649 649
650 IWL_DEBUG_INFO(priv, "Parsing data for %d channels.\n", priv->channel_count); 650 IWL_DEBUG_EEPROM(priv, "Parsing data for %d channels.\n",
651 priv->channel_count);
651 652
652 priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) * 653 priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) *
653 priv->channel_count, GFP_KERNEL); 654 priv->channel_count, GFP_KERNEL);
@@ -686,7 +687,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
686 IEEE80211_CHAN_NO_HT40; 687 IEEE80211_CHAN_NO_HT40;
687 688
688 if (!(is_channel_valid(ch_info))) { 689 if (!(is_channel_valid(ch_info))) {
689 IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - " 690 IWL_DEBUG_EEPROM(priv,
691 "Ch. %d Flags %x [%sGHz] - "
690 "No traffic\n", 692 "No traffic\n",
691 ch_info->channel, 693 ch_info->channel,
692 ch_info->flags, 694 ch_info->flags,
@@ -702,7 +704,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
702 ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; 704 ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
703 ch_info->min_power = 0; 705 ch_info->min_power = 0;
704 706
705 IWL_DEBUG_INFO(priv, "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):" 707 IWL_DEBUG_EEPROM(priv, "Ch. %d [%sGHz] "
708 "%s%s%s%s%s%s(0x%02x %ddBm):"
706 " Ad-Hoc %ssupported\n", 709 " Ad-Hoc %ssupported\n",
707 ch_info->channel, 710 ch_info->channel,
708 is_channel_a_band(ch_info) ? 711 is_channel_a_band(ch_info) ?
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 8994b5b23593..9e6f31355eee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -231,59 +231,6 @@ struct iwl_eeprom_enhanced_txpwr {
231#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\ 231#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\
232 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ 232 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */
233 233
234/* 6000 and up regulatory tx power - indirect access */
235/* max. elements per section */
236#define EEPROM_MAX_TXPOWER_SECTION_ELEMENTS (8)
237#define EEPROM_TXPOWER_COMMON_HT40_INDEX (2)
238
239/**
240 * Partition the enhanced tx power portion of eeprom image into
241 * 10 sections based on band, modulation, frequency and channel
242 *
243 * Section 1: all CCK channels
244 * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40 ) channels
245 * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
246 * Section 4: 2.4 GHz 20MHz channels: 1, 2, 10, 11. Both Legacy and HT
247 * Section 5: 2.4 GHz 40MHz channels: 1, 2, 6, 7, 9, (_above_)
248 * Section 6: 5.2 GHz 20MHz channels: 36, 64, 100, both Legacy and HT
249 * Section 7: 5.2 GHz 40MHz channels: 36, 60, 100 (_above_)
250 * Section 8: 2.4 GHz channel 13, Both Legacy and HT
251 * Section 9: 2.4 GHz channel 140, Both Legacy and HT
252 * Section 10: 2.4 GHz 40MHz channels: 132, 44 (_above_)
253 */
254/* 2.4 GHz band: CCK */
255#define EEPROM_LB_CCK_20_COMMON ((0xA8)\
256 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 8 bytes */
257/* 2.4 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
258#define EEPROM_LB_OFDM_COMMON ((0xB0)\
259 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
260/* 5.2 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
261#define EEPROM_HB_OFDM_COMMON ((0xC8)\
262 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
263/* 2.4GHz band channels:
264 * 1Legacy, 1HT, 2Legacy, 2HT, 10Legacy, 10HT, 11Legacy, 11HT */
265#define EEPROM_LB_OFDM_20_BAND ((0xE0)\
266 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 64 bytes */
267/* 2.4 GHz band HT40 channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) */
268#define EEPROM_LB_OFDM_HT40_BAND ((0x120)\
269 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 40 bytes */
270/* 5.2GHz band channels: 36Legacy, 36HT, 64Legacy, 64HT, 100Legacy, 100HT */
271#define EEPROM_HB_OFDM_20_BAND ((0x148)\
272 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 48 bytes */
273/* 5.2 GHz band HT40 channels: (36,+1) (60,+1) (100,+1) */
274#define EEPROM_HB_OFDM_HT40_BAND ((0x178)\
275 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
276/* 2.4 GHz band, channnel 13: Legacy, HT */
277#define EEPROM_LB_OFDM_20_CHANNEL_13 ((0x190)\
278 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
279/* 5.2 GHz band, channnel 140: Legacy, HT */
280#define EEPROM_HB_OFDM_20_CHANNEL_140 ((0x1A0)\
281 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
282/* 5.2 GHz band, HT40 channnels (132,+1) (44,+1) */
283#define EEPROM_HB_OFDM_HT40_BAND_1 ((0x1B0)\
284 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
285
286
287/* 5050 Specific */ 234/* 5050 Specific */
288#define EEPROM_5050_TX_POWER_VERSION (4) 235#define EEPROM_5050_TX_POWER_VERSION (4)
289#define EEPROM_5050_EEPROM_VERSION (0x21E) 236#define EEPROM_5050_EEPROM_VERSION (0x21E)
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 5469655646ae..86f5123bccda 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -83,10 +83,10 @@
83#define APMG_DIGITAL_SVR_REG (APMG_BASE + 0x0058) 83#define APMG_DIGITAL_SVR_REG (APMG_BASE + 0x0058)
84#define APMG_ANALOG_SVR_REG (APMG_BASE + 0x006C) 84#define APMG_ANALOG_SVR_REG (APMG_BASE + 0x006C)
85 85
86#define APMS_CLK_VAL_MRB_FUNC_MODE (0x00000001)
86#define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200) 87#define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200)
87#define APMG_CLK_VAL_BSM_CLK_RQT (0x00000800) 88#define APMG_CLK_VAL_BSM_CLK_RQT (0x00000800)
88 89
89
90#define APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS (0x00400000) 90#define APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS (0x00400000)
91#define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000) 91#define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000)
92#define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000) 92#define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000)
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index c6c0eff9b5ed..5a4982271e96 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -225,7 +225,8 @@ static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
225 225
226static int iwm_cfg80211_set_default_key(struct wiphy *wiphy, 226static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
227 struct net_device *ndev, 227 struct net_device *ndev,
228 u8 key_index) 228 u8 key_index, bool unicast,
229 bool multicast)
229{ 230{
230 struct iwm_priv *iwm = ndev_to_iwm(ndev); 231 struct iwm_priv *iwm = ndev_to_iwm(ndev);
231 232
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 632c9211e634..698a1f7694ed 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -1422,7 +1422,8 @@ static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
1422 1422
1423static int lbs_cfg_set_default_key(struct wiphy *wiphy, 1423static int lbs_cfg_set_default_key(struct wiphy *wiphy,
1424 struct net_device *netdev, 1424 struct net_device *netdev,
1425 u8 key_index) 1425 u8 key_index, bool unicast,
1426 bool multicast)
1426{ 1427{
1427 struct lbs_private *priv = wiphy_priv(wiphy); 1428 struct lbs_private *priv = wiphy_priv(wiphy);
1428 1429
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 19f3d568f700..4a4f00591447 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -554,7 +554,7 @@ static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
554 u8 key_index, bool pairwise, const u8 *mac_addr); 554 u8 key_index, bool pairwise, const u8 *mac_addr);
555 555
556static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, 556static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
557 u8 key_index); 557 u8 key_index, bool unicast, bool multicast);
558 558
559static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev, 559static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev,
560 u8 *mac, struct station_info *sinfo); 560 u8 *mac, struct station_info *sinfo);
@@ -2381,7 +2381,7 @@ static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
2381} 2381}
2382 2382
2383static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, 2383static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
2384 u8 key_index) 2384 u8 key_index, bool unicast, bool multicast)
2385{ 2385{
2386 struct rndis_wlan_private *priv = wiphy_priv(wiphy); 2386 struct rndis_wlan_private *priv = wiphy_priv(wiphy);
2387 struct usbnet *usbdev = priv->usbdev; 2387 struct usbnet *usbdev = priv->usbdev;
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 9ec6691adf0d..54ca49ad3472 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -633,6 +633,88 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev,
633} 633}
634 634
635/* 635/*
636 * Queue handlers.
637 */
638static void rt2400pci_start_queue(struct data_queue *queue)
639{
640 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
641 u32 reg;
642
643 switch (queue->qid) {
644 case QID_RX:
645 rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
646 rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 0);
647 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
648 break;
649 case QID_BEACON:
650 rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
651 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
652 rt2x00_set_field32(&reg, CSR14_TBCN, 1);
653 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
654 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
655 break;
656 default:
657 break;
658 }
659}
660
661static void rt2400pci_kick_queue(struct data_queue *queue)
662{
663 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
664 u32 reg;
665
666 switch (queue->qid) {
667 case QID_AC_VO:
668 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
669 rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
670 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
671 break;
672 case QID_AC_VI:
673 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
674 rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
675 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
676 break;
677 case QID_ATIM:
678 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
679 rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, 1);
680 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
681 break;
682 default:
683 break;
684 }
685}
686
687static void rt2400pci_stop_queue(struct data_queue *queue)
688{
689 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
690 u32 reg;
691
692 switch (queue->qid) {
693 case QID_AC_VO:
694 case QID_AC_VI:
695 case QID_ATIM:
696 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
697 rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
698 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
699 break;
700 case QID_RX:
701 rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
702 rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 1);
703 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
704 break;
705 case QID_BEACON:
706 rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
707 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
708 rt2x00_set_field32(&reg, CSR14_TBCN, 0);
709 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
710 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
711 break;
712 default:
713 break;
714 }
715}
716
717/*
636 * Initialization functions. 718 * Initialization functions.
637 */ 719 */
638static bool rt2400pci_get_entry_state(struct queue_entry *entry) 720static bool rt2400pci_get_entry_state(struct queue_entry *entry)
@@ -878,17 +960,6 @@ static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev)
878/* 960/*
879 * Device state switch handlers. 961 * Device state switch handlers.
880 */ 962 */
881static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
882 enum dev_state state)
883{
884 u32 reg;
885
886 rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
887 rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX,
888 (state == STATE_RADIO_RX_OFF));
889 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
890}
891
892static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, 963static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
893 enum dev_state state) 964 enum dev_state state)
894{ 965{
@@ -987,10 +1058,6 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
987 case STATE_RADIO_OFF: 1058 case STATE_RADIO_OFF:
988 rt2400pci_disable_radio(rt2x00dev); 1059 rt2400pci_disable_radio(rt2x00dev);
989 break; 1060 break;
990 case STATE_RADIO_RX_ON:
991 case STATE_RADIO_RX_OFF:
992 rt2400pci_toggle_rx(rt2x00dev, state);
993 break;
994 case STATE_RADIO_IRQ_ON: 1061 case STATE_RADIO_IRQ_ON:
995 case STATE_RADIO_IRQ_ON_ISR: 1062 case STATE_RADIO_IRQ_ON_ISR:
996 case STATE_RADIO_IRQ_OFF: 1063 case STATE_RADIO_IRQ_OFF:
@@ -1122,32 +1189,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
1122 rt2x00pci_register_write(rt2x00dev, CSR14, reg); 1189 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1123} 1190}
1124 1191
1125static void rt2400pci_kick_tx_queue(struct data_queue *queue)
1126{
1127 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
1128 u32 reg;
1129
1130 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
1131 rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE));
1132 rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK));
1133 rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM));
1134 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
1135}
1136
1137static void rt2400pci_kill_tx_queue(struct data_queue *queue)
1138{
1139 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
1140 u32 reg;
1141
1142 if (queue->qid == QID_BEACON) {
1143 rt2x00pci_register_write(rt2x00dev, CSR14, 0);
1144 } else {
1145 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
1146 rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
1147 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
1148 }
1149}
1150
1151/* 1192/*
1152 * RX control handlers 1193 * RX control handlers
1153 */ 1194 */
@@ -1281,13 +1322,13 @@ static irqreturn_t rt2400pci_interrupt_thread(int irq, void *dev_instance)
1281 * 4 - Priority ring transmit done interrupt. 1322 * 4 - Priority ring transmit done interrupt.
1282 */ 1323 */
1283 if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING)) 1324 if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))
1284 rt2400pci_txdone(rt2x00dev, QID_AC_BE); 1325 rt2400pci_txdone(rt2x00dev, QID_AC_VO);
1285 1326
1286 /* 1327 /*
1287 * 5 - Tx ring transmit done interrupt. 1328 * 5 - Tx ring transmit done interrupt.
1288 */ 1329 */
1289 if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) 1330 if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
1290 rt2400pci_txdone(rt2x00dev, QID_AC_BK); 1331 rt2400pci_txdone(rt2x00dev, QID_AC_VI);
1291 1332
1292 /* Enable interrupts again. */ 1333 /* Enable interrupts again. */
1293 rt2x00dev->ops->lib->set_device_state(rt2x00dev, 1334 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
@@ -1625,10 +1666,11 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
1625 .link_stats = rt2400pci_link_stats, 1666 .link_stats = rt2400pci_link_stats,
1626 .reset_tuner = rt2400pci_reset_tuner, 1667 .reset_tuner = rt2400pci_reset_tuner,
1627 .link_tuner = rt2400pci_link_tuner, 1668 .link_tuner = rt2400pci_link_tuner,
1669 .start_queue = rt2400pci_start_queue,
1670 .kick_queue = rt2400pci_kick_queue,
1671 .stop_queue = rt2400pci_stop_queue,
1628 .write_tx_desc = rt2400pci_write_tx_desc, 1672 .write_tx_desc = rt2400pci_write_tx_desc,
1629 .write_beacon = rt2400pci_write_beacon, 1673 .write_beacon = rt2400pci_write_beacon,
1630 .kick_tx_queue = rt2400pci_kick_tx_queue,
1631 .kill_tx_queue = rt2400pci_kill_tx_queue,
1632 .fill_rxdone = rt2400pci_fill_rxdone, 1674 .fill_rxdone = rt2400pci_fill_rxdone,
1633 .config_filter = rt2400pci_config_filter, 1675 .config_filter = rt2400pci_config_filter,
1634 .config_intf = rt2400pci_config_intf, 1676 .config_intf = rt2400pci_config_intf,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 3e7f20346243..a9ff26a27724 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -723,6 +723,88 @@ dynamic_cca_tune:
723} 723}
724 724
725/* 725/*
726 * Queue handlers.
727 */
728static void rt2500pci_start_queue(struct data_queue *queue)
729{
730 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
731 u32 reg;
732
733 switch (queue->qid) {
734 case QID_RX:
735 rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
736 rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 0);
737 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
738 break;
739 case QID_BEACON:
740 rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
741 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
742 rt2x00_set_field32(&reg, CSR14_TBCN, 1);
743 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
744 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
745 break;
746 default:
747 break;
748 }
749}
750
751static void rt2500pci_kick_queue(struct data_queue *queue)
752{
753 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
754 u32 reg;
755
756 switch (queue->qid) {
757 case QID_AC_VO:
758 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
759 rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
760 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
761 break;
762 case QID_AC_VI:
763 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
764 rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
765 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
766 break;
767 case QID_ATIM:
768 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
769 rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, 1);
770 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
771 break;
772 default:
773 break;
774 }
775}
776
777static void rt2500pci_stop_queue(struct data_queue *queue)
778{
779 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
780 u32 reg;
781
782 switch (queue->qid) {
783 case QID_AC_VO:
784 case QID_AC_VI:
785 case QID_ATIM:
786 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
787 rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
788 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
789 break;
790 case QID_RX:
791 rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
792 rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX, 1);
793 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
794 break;
795 case QID_BEACON:
796 rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
797 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
798 rt2x00_set_field32(&reg, CSR14_TBCN, 0);
799 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
800 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
801 break;
802 default:
803 break;
804 }
805}
806
807/*
726 * Initialization functions. 808 * Initialization functions.
727 */ 809 */
728static bool rt2500pci_get_entry_state(struct queue_entry *entry) 810static bool rt2500pci_get_entry_state(struct queue_entry *entry)
@@ -1033,17 +1115,6 @@ static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev)
1033/* 1115/*
1034 * Device state switch handlers. 1116 * Device state switch handlers.
1035 */ 1117 */
1036static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
1037 enum dev_state state)
1038{
1039 u32 reg;
1040
1041 rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
1042 rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX,
1043 (state == STATE_RADIO_RX_OFF));
1044 rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
1045}
1046
1047static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, 1118static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
1048 enum dev_state state) 1119 enum dev_state state)
1049{ 1120{
@@ -1142,10 +1213,6 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
1142 case STATE_RADIO_OFF: 1213 case STATE_RADIO_OFF:
1143 rt2500pci_disable_radio(rt2x00dev); 1214 rt2500pci_disable_radio(rt2x00dev);
1144 break; 1215 break;
1145 case STATE_RADIO_RX_ON:
1146 case STATE_RADIO_RX_OFF:
1147 rt2500pci_toggle_rx(rt2x00dev, state);
1148 break;
1149 case STATE_RADIO_IRQ_ON: 1216 case STATE_RADIO_IRQ_ON:
1150 case STATE_RADIO_IRQ_ON_ISR: 1217 case STATE_RADIO_IRQ_ON_ISR:
1151 case STATE_RADIO_IRQ_OFF: 1218 case STATE_RADIO_IRQ_OFF:
@@ -1276,32 +1343,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
1276 rt2x00pci_register_write(rt2x00dev, CSR14, reg); 1343 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1277} 1344}
1278 1345
1279static void rt2500pci_kick_tx_queue(struct data_queue *queue)
1280{
1281 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
1282 u32 reg;
1283
1284 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
1285 rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE));
1286 rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK));
1287 rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM));
1288 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
1289}
1290
1291static void rt2500pci_kill_tx_queue(struct data_queue *queue)
1292{
1293 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
1294 u32 reg;
1295
1296 if (queue->qid == QID_BEACON) {
1297 rt2x00pci_register_write(rt2x00dev, CSR14, 0);
1298 } else {
1299 rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
1300 rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
1301 rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
1302 }
1303}
1304
1305/* 1346/*
1306 * RX control handlers 1347 * RX control handlers
1307 */ 1348 */
@@ -1414,13 +1455,13 @@ static irqreturn_t rt2500pci_interrupt_thread(int irq, void *dev_instance)
1414 * 4 - Priority ring transmit done interrupt. 1455 * 4 - Priority ring transmit done interrupt.
1415 */ 1456 */
1416 if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING)) 1457 if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))
1417 rt2500pci_txdone(rt2x00dev, QID_AC_BE); 1458 rt2500pci_txdone(rt2x00dev, QID_AC_VO);
1418 1459
1419 /* 1460 /*
1420 * 5 - Tx ring transmit done interrupt. 1461 * 5 - Tx ring transmit done interrupt.
1421 */ 1462 */
1422 if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) 1463 if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
1423 rt2500pci_txdone(rt2x00dev, QID_AC_BK); 1464 rt2500pci_txdone(rt2x00dev, QID_AC_VI);
1424 1465
1425 /* Enable interrupts again. */ 1466 /* Enable interrupts again. */
1426 rt2x00dev->ops->lib->set_device_state(rt2x00dev, 1467 rt2x00dev->ops->lib->set_device_state(rt2x00dev,
@@ -1922,10 +1963,11 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
1922 .link_stats = rt2500pci_link_stats, 1963 .link_stats = rt2500pci_link_stats,
1923 .reset_tuner = rt2500pci_reset_tuner, 1964 .reset_tuner = rt2500pci_reset_tuner,
1924 .link_tuner = rt2500pci_link_tuner, 1965 .link_tuner = rt2500pci_link_tuner,
1966 .start_queue = rt2500pci_start_queue,
1967 .kick_queue = rt2500pci_kick_queue,
1968 .stop_queue = rt2500pci_stop_queue,
1925 .write_tx_desc = rt2500pci_write_tx_desc, 1969 .write_tx_desc = rt2500pci_write_tx_desc,
1926 .write_beacon = rt2500pci_write_beacon, 1970 .write_beacon = rt2500pci_write_beacon,
1927 .kick_tx_queue = rt2500pci_kick_tx_queue,
1928 .kill_tx_queue = rt2500pci_kill_tx_queue,
1929 .fill_rxdone = rt2500pci_fill_rxdone, 1971 .fill_rxdone = rt2500pci_fill_rxdone,
1930 .config_filter = rt2500pci_config_filter, 1972 .config_filter = rt2500pci_config_filter,
1931 .config_intf = rt2500pci_config_intf, 1973 .config_intf = rt2500pci_config_intf,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 8152fec31753..6b3b1de46792 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -739,6 +739,55 @@ static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
739} 739}
740 740
741/* 741/*
742 * Queue handlers.
743 */
744static void rt2500usb_start_queue(struct data_queue *queue)
745{
746 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
747 u16 reg;
748
749 switch (queue->qid) {
750 case QID_RX:
751 rt2500usb_register_read(rt2x00dev, TXRX_CSR2, &reg);
752 rt2x00_set_field16(&reg, TXRX_CSR2_DISABLE_RX, 0);
753 rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
754 break;
755 case QID_BEACON:
756 rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
757 rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1);
758 rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1);
759 rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 1);
760 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
761 break;
762 default:
763 break;
764 }
765}
766
767static void rt2500usb_stop_queue(struct data_queue *queue)
768{
769 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
770 u16 reg;
771
772 switch (queue->qid) {
773 case QID_RX:
774 rt2500usb_register_read(rt2x00dev, TXRX_CSR2, &reg);
775 rt2x00_set_field16(&reg, TXRX_CSR2_DISABLE_RX, 1);
776 rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
777 break;
778 case QID_BEACON:
779 rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
780 rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 0);
781 rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 0);
782 rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
783 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
784 break;
785 default:
786 break;
787 }
788}
789
790/*
742 * Initialization functions. 791 * Initialization functions.
743 */ 792 */
744static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) 793static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
@@ -931,17 +980,6 @@ static int rt2500usb_init_bbp(struct rt2x00_dev *rt2x00dev)
931/* 980/*
932 * Device state switch handlers. 981 * Device state switch handlers.
933 */ 982 */
934static void rt2500usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
935 enum dev_state state)
936{
937 u16 reg;
938
939 rt2500usb_register_read(rt2x00dev, TXRX_CSR2, &reg);
940 rt2x00_set_field16(&reg, TXRX_CSR2_DISABLE_RX,
941 (state == STATE_RADIO_RX_OFF));
942 rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
943}
944
945static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev) 983static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev)
946{ 984{
947 /* 985 /*
@@ -1017,10 +1055,6 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
1017 case STATE_RADIO_OFF: 1055 case STATE_RADIO_OFF:
1018 rt2500usb_disable_radio(rt2x00dev); 1056 rt2500usb_disable_radio(rt2x00dev);
1019 break; 1057 break;
1020 case STATE_RADIO_RX_ON:
1021 case STATE_RADIO_RX_OFF:
1022 rt2500usb_toggle_rx(rt2x00dev, state);
1023 break;
1024 case STATE_RADIO_IRQ_ON: 1058 case STATE_RADIO_IRQ_ON:
1025 case STATE_RADIO_IRQ_ON_ISR: 1059 case STATE_RADIO_IRQ_ON_ISR:
1026 case STATE_RADIO_IRQ_OFF: 1060 case STATE_RADIO_IRQ_OFF:
@@ -1203,14 +1237,6 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
1203 return length; 1237 return length;
1204} 1238}
1205 1239
1206static void rt2500usb_kill_tx_queue(struct data_queue *queue)
1207{
1208 if (queue->qid == QID_BEACON)
1209 rt2500usb_register_write(queue->rt2x00dev, TXRX_CSR19, 0);
1210
1211 rt2x00usb_kill_tx_queue(queue);
1212}
1213
1214/* 1240/*
1215 * RX control handlers 1241 * RX control handlers
1216 */ 1242 */
@@ -1811,11 +1837,13 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
1811 .link_stats = rt2500usb_link_stats, 1837 .link_stats = rt2500usb_link_stats,
1812 .reset_tuner = rt2500usb_reset_tuner, 1838 .reset_tuner = rt2500usb_reset_tuner,
1813 .watchdog = rt2x00usb_watchdog, 1839 .watchdog = rt2x00usb_watchdog,
1840 .start_queue = rt2500usb_start_queue,
1841 .kick_queue = rt2x00usb_kick_queue,
1842 .stop_queue = rt2500usb_stop_queue,
1843 .flush_queue = rt2x00usb_flush_queue,
1814 .write_tx_desc = rt2500usb_write_tx_desc, 1844 .write_tx_desc = rt2500usb_write_tx_desc,
1815 .write_beacon = rt2500usb_write_beacon, 1845 .write_beacon = rt2500usb_write_beacon,
1816 .get_tx_data_len = rt2500usb_get_tx_data_len, 1846 .get_tx_data_len = rt2500usb_get_tx_data_len,
1817 .kick_tx_queue = rt2x00usb_kick_tx_queue,
1818 .kill_tx_queue = rt2500usb_kill_tx_queue,
1819 .fill_rxdone = rt2500usb_fill_rxdone, 1847 .fill_rxdone = rt2500usb_fill_rxdone,
1820 .config_shared_key = rt2500usb_config_key, 1848 .config_shared_key = rt2500usb_config_key,
1821 .config_pairwise_key = rt2500usb_config_key, 1849 .config_pairwise_key = rt2500usb_config_key,
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index a81c4371835b..4c55e8525cad 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -46,8 +46,11 @@
46 * RF2020 2.4G B/G 46 * RF2020 2.4G B/G
47 * RF3021 2.4G 1T2R 47 * RF3021 2.4G 1T2R
48 * RF3022 2.4G 2T2R 48 * RF3022 2.4G 2T2R
49 * RF3052 2.4G 2T2R 49 * RF3052 2.4G/5G 2T2R
50 * RF3320 2.4G 1T1R 50 * RF2853 2.4G/5G 3T3R
51 * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
52 * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
53 * RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
51 */ 54 */
52#define RF2820 0x0001 55#define RF2820 0x0001
53#define RF2850 0x0002 56#define RF2850 0x0002
@@ -58,7 +61,10 @@
58#define RF3021 0x0007 61#define RF3021 0x0007
59#define RF3022 0x0008 62#define RF3022 0x0008
60#define RF3052 0x0009 63#define RF3052 0x0009
64#define RF2853 0x000a
61#define RF3320 0x000b 65#define RF3320 0x000b
66#define RF3322 0x000c
67#define RF3853 0x000d
62 68
63/* 69/*
64 * Chipset revisions. 70 * Chipset revisions.
@@ -207,10 +213,10 @@
207 213
208/* 214/*
209 * WMM_AIFSN_CFG: Aifsn for each EDCA AC 215 * WMM_AIFSN_CFG: Aifsn for each EDCA AC
210 * AIFSN0: AC_BE 216 * AIFSN0: AC_VO
211 * AIFSN1: AC_BK 217 * AIFSN1: AC_VI
212 * AIFSN2: AC_VI 218 * AIFSN2: AC_BE
213 * AIFSN3: AC_VO 219 * AIFSN3: AC_BK
214 */ 220 */
215#define WMM_AIFSN_CFG 0x0214 221#define WMM_AIFSN_CFG 0x0214
216#define WMM_AIFSN_CFG_AIFSN0 FIELD32(0x0000000f) 222#define WMM_AIFSN_CFG_AIFSN0 FIELD32(0x0000000f)
@@ -220,10 +226,10 @@
220 226
221/* 227/*
222 * WMM_CWMIN_CSR: CWmin for each EDCA AC 228 * WMM_CWMIN_CSR: CWmin for each EDCA AC
223 * CWMIN0: AC_BE 229 * CWMIN0: AC_VO
224 * CWMIN1: AC_BK 230 * CWMIN1: AC_VI
225 * CWMIN2: AC_VI 231 * CWMIN2: AC_BE
226 * CWMIN3: AC_VO 232 * CWMIN3: AC_BK
227 */ 233 */
228#define WMM_CWMIN_CFG 0x0218 234#define WMM_CWMIN_CFG 0x0218
229#define WMM_CWMIN_CFG_CWMIN0 FIELD32(0x0000000f) 235#define WMM_CWMIN_CFG_CWMIN0 FIELD32(0x0000000f)
@@ -233,10 +239,10 @@
233 239
234/* 240/*
235 * WMM_CWMAX_CSR: CWmax for each EDCA AC 241 * WMM_CWMAX_CSR: CWmax for each EDCA AC
236 * CWMAX0: AC_BE 242 * CWMAX0: AC_VO
237 * CWMAX1: AC_BK 243 * CWMAX1: AC_VI
238 * CWMAX2: AC_VI 244 * CWMAX2: AC_BE
239 * CWMAX3: AC_VO 245 * CWMAX3: AC_BK
240 */ 246 */
241#define WMM_CWMAX_CFG 0x021c 247#define WMM_CWMAX_CFG 0x021c
242#define WMM_CWMAX_CFG_CWMAX0 FIELD32(0x0000000f) 248#define WMM_CWMAX_CFG_CWMAX0 FIELD32(0x0000000f)
@@ -245,18 +251,18 @@
245#define WMM_CWMAX_CFG_CWMAX3 FIELD32(0x0000f000) 251#define WMM_CWMAX_CFG_CWMAX3 FIELD32(0x0000f000)
246 252
247/* 253/*
248 * AC_TXOP0: AC_BK/AC_BE TXOP register 254 * AC_TXOP0: AC_VO/AC_VI TXOP register
249 * AC0TXOP: AC_BK in unit of 32us 255 * AC0TXOP: AC_VO in unit of 32us
250 * AC1TXOP: AC_BE in unit of 32us 256 * AC1TXOP: AC_VI in unit of 32us
251 */ 257 */
252#define WMM_TXOP0_CFG 0x0220 258#define WMM_TXOP0_CFG 0x0220
253#define WMM_TXOP0_CFG_AC0TXOP FIELD32(0x0000ffff) 259#define WMM_TXOP0_CFG_AC0TXOP FIELD32(0x0000ffff)
254#define WMM_TXOP0_CFG_AC1TXOP FIELD32(0xffff0000) 260#define WMM_TXOP0_CFG_AC1TXOP FIELD32(0xffff0000)
255 261
256/* 262/*
257 * AC_TXOP1: AC_VO/AC_VI TXOP register 263 * AC_TXOP1: AC_BE/AC_BK TXOP register
258 * AC2TXOP: AC_VI in unit of 32us 264 * AC2TXOP: AC_BE in unit of 32us
259 * AC3TXOP: AC_VO in unit of 32us 265 * AC3TXOP: AC_BK in unit of 32us
260 */ 266 */
261#define WMM_TXOP1_CFG 0x0224 267#define WMM_TXOP1_CFG 0x0224
262#define WMM_TXOP1_CFG_AC2TXOP FIELD32(0x0000ffff) 268#define WMM_TXOP1_CFG_AC2TXOP FIELD32(0x0000ffff)
@@ -282,7 +288,7 @@
282#define MCU_CMD_CFG 0x022c 288#define MCU_CMD_CFG 0x022c
283 289
284/* 290/*
285 * AC_BK register offsets 291 * AC_VO register offsets
286 */ 292 */
287#define TX_BASE_PTR0 0x0230 293#define TX_BASE_PTR0 0x0230
288#define TX_MAX_CNT0 0x0234 294#define TX_MAX_CNT0 0x0234
@@ -290,7 +296,7 @@
290#define TX_DTX_IDX0 0x023c 296#define TX_DTX_IDX0 0x023c
291 297
292/* 298/*
293 * AC_BE register offsets 299 * AC_VI register offsets
294 */ 300 */
295#define TX_BASE_PTR1 0x0240 301#define TX_BASE_PTR1 0x0240
296#define TX_MAX_CNT1 0x0244 302#define TX_MAX_CNT1 0x0244
@@ -298,7 +304,7 @@
298#define TX_DTX_IDX1 0x024c 304#define TX_DTX_IDX1 0x024c
299 305
300/* 306/*
301 * AC_VI register offsets 307 * AC_BE register offsets
302 */ 308 */
303#define TX_BASE_PTR2 0x0250 309#define TX_BASE_PTR2 0x0250
304#define TX_MAX_CNT2 0x0254 310#define TX_MAX_CNT2 0x0254
@@ -306,7 +312,7 @@
306#define TX_DTX_IDX2 0x025c 312#define TX_DTX_IDX2 0x025c
307 313
308/* 314/*
309 * AC_VO register offsets 315 * AC_BK register offsets
310 */ 316 */
311#define TX_BASE_PTR3 0x0260 317#define TX_BASE_PTR3 0x0260
312#define TX_MAX_CNT3 0x0264 318#define TX_MAX_CNT3 0x0264
@@ -699,8 +705,18 @@
699 705
700/* 706/*
701 * CH_TIME_CFG: count as channel busy 707 * CH_TIME_CFG: count as channel busy
708 * EIFS_BUSY: Count EIFS as channel busy
709 * NAV_BUSY: Count NAS as channel busy
710 * RX_BUSY: Count RX as channel busy
711 * TX_BUSY: Count TX as channel busy
712 * TMR_EN: Enable channel statistics timer
702 */ 713 */
703#define CH_TIME_CFG 0x110c 714#define CH_TIME_CFG 0x110c
715#define CH_TIME_CFG_EIFS_BUSY FIELD32(0x00000010)
716#define CH_TIME_CFG_NAV_BUSY FIELD32(0x00000008)
717#define CH_TIME_CFG_RX_BUSY FIELD32(0x00000004)
718#define CH_TIME_CFG_TX_BUSY FIELD32(0x00000002)
719#define CH_TIME_CFG_TMR_EN FIELD32(0x00000001)
704 720
705/* 721/*
706 * PBF_LIFE_TIMER: TX/RX MPDU timestamp timer (free run) Unit: 1us 722 * PBF_LIFE_TIMER: TX/RX MPDU timestamp timer (free run) Unit: 1us
@@ -1841,32 +1857,51 @@ struct mac_iveiv_entry {
1841#define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) 1857#define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00)
1842 1858
1843/* 1859/*
1844 * EEPROM ANTENNA config 1860 * EEPROM NIC Configuration 0
1845 * RXPATH: 1: 1R, 2: 2R, 3: 3R 1861 * RXPATH: 1: 1R, 2: 2R, 3: 3R
1846 * TXPATH: 1: 1T, 2: 2T 1862 * TXPATH: 1: 1T, 2: 2T, 3: 3T
1847 */ 1863 * RF_TYPE: RFIC type
1848#define EEPROM_ANTENNA 0x001a 1864 */
1849#define EEPROM_ANTENNA_RXPATH FIELD16(0x000f) 1865#define EEPROM_NIC_CONF0 0x001a
1850#define EEPROM_ANTENNA_TXPATH FIELD16(0x00f0) 1866#define EEPROM_NIC_CONF0_RXPATH FIELD16(0x000f)
1851#define EEPROM_ANTENNA_RF_TYPE FIELD16(0x0f00) 1867#define EEPROM_NIC_CONF0_TXPATH FIELD16(0x00f0)
1852 1868#define EEPROM_NIC_CONF0_RF_TYPE FIELD16(0x0f00)
1853/* 1869
1854 * EEPROM NIC config 1870/*
1855 * CARDBUS_ACCEL: 0 - enable, 1 - disable 1871 * EEPROM NIC Configuration 1
1856 */ 1872 * HW_RADIO: 0: disable, 1: enable
1857#define EEPROM_NIC 0x001b 1873 * EXTERNAL_TX_ALC: 0: disable, 1: enable
1858#define EEPROM_NIC_HW_RADIO FIELD16(0x0001) 1874 * EXTERNAL_LNA_2G: 0: disable, 1: enable
1859#define EEPROM_NIC_DYNAMIC_TX_AGC FIELD16(0x0002) 1875 * EXTERNAL_LNA_5G: 0: disable, 1: enable
1860#define EEPROM_NIC_EXTERNAL_LNA_BG FIELD16(0x0004) 1876 * CARDBUS_ACCEL: 0: enable, 1: disable
1861#define EEPROM_NIC_EXTERNAL_LNA_A FIELD16(0x0008) 1877 * BW40M_SB_2G: 0: disable, 1: enable
1862#define EEPROM_NIC_CARDBUS_ACCEL FIELD16(0x0010) 1878 * BW40M_SB_5G: 0: disable, 1: enable
1863#define EEPROM_NIC_BW40M_SB_BG FIELD16(0x0020) 1879 * WPS_PBC: 0: disable, 1: enable
1864#define EEPROM_NIC_BW40M_SB_A FIELD16(0x0040) 1880 * BW40M_2G: 0: enable, 1: disable
1865#define EEPROM_NIC_WPS_PBC FIELD16(0x0080) 1881 * BW40M_5G: 0: enable, 1: disable
1866#define EEPROM_NIC_BW40M_BG FIELD16(0x0100) 1882 * BROADBAND_EXT_LNA: 0: disable, 1: enable
1867#define EEPROM_NIC_BW40M_A FIELD16(0x0200) 1883 * ANT_DIVERSITY: 00: Disable, 01: Diversity,
1868#define EEPROM_NIC_ANT_DIVERSITY FIELD16(0x0800) 1884 * 10: Main antenna, 11: Aux antenna
1869#define EEPROM_NIC_DAC_TEST FIELD16(0x8000) 1885 * INTERNAL_TX_ALC: 0: disable, 1: enable
1886 * BT_COEXIST: 0: disable, 1: enable
1887 * DAC_TEST: 0: disable, 1: enable
1888 */
1889#define EEPROM_NIC_CONF1 0x001b
1890#define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001)
1891#define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002)
1892#define EEPROM_NIC_CONF1_EXTERNAL_LNA_2G FIELD16(0x0004)
1893#define EEPROM_NIC_CONF1_EXTERNAL_LNA_5G FIELD16(0x0008)
1894#define EEPROM_NIC_CONF1_CARDBUS_ACCEL FIELD16(0x0010)
1895#define EEPROM_NIC_CONF1_BW40M_SB_2G FIELD16(0x0020)
1896#define EEPROM_NIC_CONF1_BW40M_SB_5G FIELD16(0x0040)
1897#define EEPROM_NIC_CONF1_WPS_PBC FIELD16(0x0080)
1898#define EEPROM_NIC_CONF1_BW40M_2G FIELD16(0x0100)
1899#define EEPROM_NIC_CONF1_BW40M_5G FIELD16(0x0200)
1900#define EEPROM_NIC_CONF1_BROADBAND_EXT_LNA FIELD16(0x400)
1901#define EEPROM_NIC_CONF1_ANT_DIVERSITY FIELD16(0x1800)
1902#define EEPROM_NIC_CONF1_INTERNAL_TX_ALC FIELD16(0x2000)
1903#define EEPROM_NIC_CONF1_BT_COEXIST FIELD16(0x4000)
1904#define EEPROM_NIC_CONF1_DAC_TEST FIELD16(0x8000)
1870 1905
1871/* 1906/*
1872 * EEPROM frequency 1907 * EEPROM frequency
@@ -1888,9 +1923,9 @@ struct mac_iveiv_entry {
1888 * POLARITY_GPIO_4: Polarity GPIO4 setting. 1923 * POLARITY_GPIO_4: Polarity GPIO4 setting.
1889 * LED_MODE: Led mode. 1924 * LED_MODE: Led mode.
1890 */ 1925 */
1891#define EEPROM_LED1 0x001e 1926#define EEPROM_LED_AG_CONF 0x001e
1892#define EEPROM_LED2 0x001f 1927#define EEPROM_LED_ACT_CONF 0x001f
1893#define EEPROM_LED3 0x0020 1928#define EEPROM_LED_POLARITY 0x0020
1894#define EEPROM_LED_POLARITY_RDY_BG FIELD16(0x0001) 1929#define EEPROM_LED_POLARITY_RDY_BG FIELD16(0x0001)
1895#define EEPROM_LED_POLARITY_RDY_A FIELD16(0x0002) 1930#define EEPROM_LED_POLARITY_RDY_A FIELD16(0x0002)
1896#define EEPROM_LED_POLARITY_ACT FIELD16(0x0004) 1931#define EEPROM_LED_POLARITY_ACT FIELD16(0x0004)
@@ -1902,6 +1937,17 @@ struct mac_iveiv_entry {
1902#define EEPROM_LED_LED_MODE FIELD16(0x1f00) 1937#define EEPROM_LED_LED_MODE FIELD16(0x1f00)
1903 1938
1904/* 1939/*
1940 * EEPROM NIC Configuration 2
1941 * RX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream
1942 * TX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream
1943 * CRYSTAL: 00: Reserved, 01: One crystal, 10: Two crystal, 11: Reserved
1944 */
1945#define EEPROM_NIC_CONF2 0x0021
1946#define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f)
1947#define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0)
1948#define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600)
1949
1950/*
1905 * EEPROM LNA 1951 * EEPROM LNA
1906 */ 1952 */
1907#define EEPROM_LNA 0x0022 1953#define EEPROM_LNA 0x0022
@@ -1951,7 +1997,7 @@ struct mac_iveiv_entry {
1951 1997
1952/* 1998/*
1953 * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power. 1999 * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power.
1954 * This is delta in 40MHZ. 2000 * This is delta in 40MHZ.
1955 * VALUE: Tx Power dalta value (MAX=4) 2001 * VALUE: Tx Power dalta value (MAX=4)
1956 * TYPE: 1: Plus the delta value, 0: minus the delta value 2002 * TYPE: 1: Plus the delta value, 0: minus the delta value
1957 * TXPOWER: Enable: 2003 * TXPOWER: Enable:
@@ -2007,9 +2053,9 @@ struct mac_iveiv_entry {
2007#define MCU_CURRENT 0x36 2053#define MCU_CURRENT 0x36
2008#define MCU_LED 0x50 2054#define MCU_LED 0x50
2009#define MCU_LED_STRENGTH 0x51 2055#define MCU_LED_STRENGTH 0x51
2010#define MCU_LED_1 0x52 2056#define MCU_LED_AG_CONF 0x52
2011#define MCU_LED_2 0x53 2057#define MCU_LED_ACT_CONF 0x53
2012#define MCU_LED_3 0x54 2058#define MCU_LED_LED_POLARITY 0x54
2013#define MCU_RADAR 0x60 2059#define MCU_RADAR 0x60
2014#define MCU_BOOT_SIGNAL 0x72 2060#define MCU_BOOT_SIGNAL 0x72
2015#define MCU_BBP_SIGNAL 0x80 2061#define MCU_BBP_SIGNAL 0x80
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 75631614aba3..54917a281398 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -772,6 +772,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
772 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 772 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
773 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 773 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
774 unsigned int beacon_base; 774 unsigned int beacon_base;
775 unsigned int padding_len;
775 u32 reg; 776 u32 reg;
776 777
777 /* 778 /*
@@ -806,11 +807,13 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
806 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); 807 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
807 808
808 /* 809 /*
809 * Write entire beacon with TXWI to register. 810 * Write entire beacon with TXWI and padding to register.
810 */ 811 */
812 padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
813 skb_pad(entry->skb, padding_len);
811 beacon_base = HW_BEACON_OFFSET(entry->entry_idx); 814 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
812 rt2800_register_multiwrite(rt2x00dev, beacon_base, 815 rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
813 entry->skb->data, entry->skb->len); 816 entry->skb->len + padding_len);
814 817
815 /* 818 /*
816 * Enable beaconing again. 819 * Enable beaconing again.
@@ -1625,6 +1628,13 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
1625 } 1628 }
1626 1629
1627 msleep(1); 1630 msleep(1);
1631
1632 /*
1633 * Clear channel statistic counters
1634 */
1635 rt2800_register_read(rt2x00dev, CH_IDLE_STA, &reg);
1636 rt2800_register_read(rt2x00dev, CH_BUSY_STA, &reg);
1637 rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &reg);
1628} 1638}
1629 1639
1630static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, 1640static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
@@ -1930,8 +1940,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
1930 if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || 1940 if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
1931 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || 1941 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
1932 rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { 1942 rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
1933 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); 1943 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
1934 if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST)) 1944 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
1935 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 1945 rt2800_register_write(rt2x00dev, TX_SW_CFG2,
1936 0x0000002c); 1946 0x0000002c);
1937 else 1947 else
@@ -2259,6 +2269,17 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
2259 rt2x00_set_field32(&reg, INT_TIMER_CFG_PRE_TBTT_TIMER, 6 << 4); 2269 rt2x00_set_field32(&reg, INT_TIMER_CFG_PRE_TBTT_TIMER, 6 << 4);
2260 rt2800_register_write(rt2x00dev, INT_TIMER_CFG, reg); 2270 rt2800_register_write(rt2x00dev, INT_TIMER_CFG, reg);
2261 2271
2272 /*
2273 * Set up channel statistics timer
2274 */
2275 rt2800_register_read(rt2x00dev, CH_TIME_CFG, &reg);
2276 rt2x00_set_field32(&reg, CH_TIME_CFG_EIFS_BUSY, 1);
2277 rt2x00_set_field32(&reg, CH_TIME_CFG_NAV_BUSY, 1);
2278 rt2x00_set_field32(&reg, CH_TIME_CFG_RX_BUSY, 1);
2279 rt2x00_set_field32(&reg, CH_TIME_CFG_TX_BUSY, 1);
2280 rt2x00_set_field32(&reg, CH_TIME_CFG_TMR_EN, 1);
2281 rt2800_register_write(rt2x00dev, CH_TIME_CFG, reg);
2282
2262 return 0; 2283 return 0;
2263} 2284}
2264 2285
@@ -2376,10 +2397,10 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
2376 rt2x00_rt(rt2x00dev, RT3390)) { 2397 rt2x00_rt(rt2x00dev, RT3390)) {
2377 rt2800_bbp_read(rt2x00dev, 138, &value); 2398 rt2800_bbp_read(rt2x00dev, 138, &value);
2378 2399
2379 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); 2400 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
2380 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1) 2401 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
2381 value |= 0x20; 2402 value |= 0x20;
2382 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1) 2403 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
2383 value &= ~0x02; 2404 value &= ~0x02;
2384 2405
2385 rt2800_bbp_write(rt2x00dev, 138, value); 2406 rt2800_bbp_write(rt2x00dev, 138, value);
@@ -2591,8 +2612,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
2591 rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1); 2612 rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
2592 if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || 2613 if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
2593 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) { 2614 rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E)) {
2594 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); 2615 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
2595 if (rt2x00_get_field16(eeprom, EEPROM_NIC_DAC_TEST)) 2616 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_DAC_TEST))
2596 rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3); 2617 rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 3);
2597 else 2618 else
2598 rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 0); 2619 rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 0);
@@ -2665,10 +2686,10 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
2665 if (rt2x00_rt(rt2x00dev, RT3090)) { 2686 if (rt2x00_rt(rt2x00dev, RT3090)) {
2666 rt2800_bbp_read(rt2x00dev, 138, &bbp); 2687 rt2800_bbp_read(rt2x00dev, 138, &bbp);
2667 2688
2668 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); 2689 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
2669 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1) 2690 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
2670 rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0); 2691 rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0);
2671 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1) 2692 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
2672 rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1); 2693 rt2x00_set_field8(&bbp, BBP138_TX_DAC1, 1);
2673 2694
2674 rt2800_bbp_write(rt2x00dev, 138, bbp); 2695 rt2800_bbp_write(rt2x00dev, 138, bbp);
@@ -2767,16 +2788,16 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
2767 /* 2788 /*
2768 * Initialize LED control 2789 * Initialize LED control
2769 */ 2790 */
2770 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); 2791 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_AG_CONF, &word);
2771 rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, 2792 rt2800_mcu_request(rt2x00dev, MCU_LED_AG_CONF, 0xff,
2772 word & 0xff, (word >> 8) & 0xff); 2793 word & 0xff, (word >> 8) & 0xff);
2773 2794
2774 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); 2795 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_ACT_CONF, &word);
2775 rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, 2796 rt2800_mcu_request(rt2x00dev, MCU_LED_ACT_CONF, 0xff,
2776 word & 0xff, (word >> 8) & 0xff); 2797 word & 0xff, (word >> 8) & 0xff);
2777 2798
2778 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); 2799 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED_POLARITY, &word);
2779 rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, 2800 rt2800_mcu_request(rt2x00dev, MCU_LED_LED_POLARITY, 0xff,
2780 word & 0xff, (word >> 8) & 0xff); 2801 word & 0xff, (word >> 8) & 0xff);
2781 2802
2782 return 0; 2803 return 0;
@@ -2870,38 +2891,41 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
2870 EEPROM(rt2x00dev, "MAC: %pM\n", mac); 2891 EEPROM(rt2x00dev, "MAC: %pM\n", mac);
2871 } 2892 }
2872 2893
2873 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); 2894 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word);
2874 if (word == 0xffff) { 2895 if (word == 0xffff) {
2875 rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); 2896 rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
2876 rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1); 2897 rt2x00_set_field16(&word, EEPROM_NIC_CONF0_TXPATH, 1);
2877 rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820); 2898 rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
2878 rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); 2899 rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
2879 EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); 2900 EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
2880 } else if (rt2x00_rt(rt2x00dev, RT2860) || 2901 } else if (rt2x00_rt(rt2x00dev, RT2860) ||
2881 rt2x00_rt(rt2x00dev, RT2872)) { 2902 rt2x00_rt(rt2x00dev, RT2872)) {
2882 /* 2903 /*
2883 * There is a max of 2 RX streams for RT28x0 series 2904 * There is a max of 2 RX streams for RT28x0 series
2884 */ 2905 */
2885 if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2) 2906 if (rt2x00_get_field16(word, EEPROM_NIC_CONF0_RXPATH) > 2)
2886 rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2); 2907 rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RXPATH, 2);
2887 rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); 2908 rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
2888 } 2909 }
2889 2910
2890 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); 2911 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &word);
2891 if (word == 0xffff) { 2912 if (word == 0xffff) {
2892 rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0); 2913 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_HW_RADIO, 0);
2893 rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0); 2914 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC, 0);
2894 rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0); 2915 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G, 0);
2895 rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); 2916 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G, 0);
2896 rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); 2917 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_CARDBUS_ACCEL, 0);
2897 rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0); 2918 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_SB_2G, 0);
2898 rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0); 2919 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_SB_5G, 0);
2899 rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0); 2920 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_WPS_PBC, 0);
2900 rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0); 2921 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_2G, 0);
2901 rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0); 2922 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BW40M_5G, 0);
2902 rt2x00_set_field16(&word, EEPROM_NIC_ANT_DIVERSITY, 0); 2923 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BROADBAND_EXT_LNA, 0);
2903 rt2x00_set_field16(&word, EEPROM_NIC_DAC_TEST, 0); 2924 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_ANT_DIVERSITY, 0);
2904 rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); 2925 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_INTERNAL_TX_ALC, 0);
2926 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_BT_COEXIST, 0);
2927 rt2x00_set_field16(&word, EEPROM_NIC_CONF1_DAC_TEST, 0);
2928 rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC_CONF1, word);
2905 EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); 2929 EEPROM(rt2x00dev, "NIC: 0x%04x\n", word);
2906 } 2930 }
2907 2931
@@ -2916,9 +2940,9 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
2916 LED_MODE_TXRX_ACTIVITY); 2940 LED_MODE_TXRX_ACTIVITY);
2917 rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0); 2941 rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
2918 rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); 2942 rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
2919 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555); 2943 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_AG_CONF, 0x5555);
2920 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221); 2944 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_ACT_CONF, 0x2221);
2921 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8); 2945 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED_POLARITY, 0xa9f8);
2922 EEPROM(rt2x00dev, "Led Mode: 0x%04x\n", word); 2946 EEPROM(rt2x00dev, "Led Mode: 0x%04x\n", word);
2923 } 2947 }
2924 2948
@@ -2982,12 +3006,12 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
2982 /* 3006 /*
2983 * Read EEPROM word for configuration. 3007 * Read EEPROM word for configuration.
2984 */ 3008 */
2985 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); 3009 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
2986 3010
2987 /* 3011 /*
2988 * Identify RF chipset. 3012 * Identify RF chipset.
2989 */ 3013 */
2990 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); 3014 value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
2991 rt2800_register_read(rt2x00dev, MAC_CSR0, &reg); 3015 rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
2992 3016
2993 rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), 3017 rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
@@ -3023,9 +3047,9 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
3023 * Identify default antenna configuration. 3047 * Identify default antenna configuration.
3024 */ 3048 */
3025 rt2x00dev->default_ant.tx = 3049 rt2x00dev->default_ant.tx =
3026 rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH); 3050 rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH);
3027 rt2x00dev->default_ant.rx = 3051 rt2x00dev->default_ant.rx =
3028 rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH); 3052 rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH);
3029 3053
3030 /* 3054 /*
3031 * Read frequency offset and RF programming sequence. 3055 * Read frequency offset and RF programming sequence.
@@ -3036,17 +3060,17 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
3036 /* 3060 /*
3037 * Read external LNA informations. 3061 * Read external LNA informations.
3038 */ 3062 */
3039 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); 3063 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
3040 3064
3041 if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A)) 3065 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G))
3042 __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); 3066 __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
3043 if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) 3067 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G))
3044 __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); 3068 __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
3045 3069
3046 /* 3070 /*
3047 * Detect if this device has an hardware controlled radio. 3071 * Detect if this device has an hardware controlled radio.
3048 */ 3072 */
3049 if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO)) 3073 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_HW_RADIO))
3050 __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); 3074 __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
3051 3075
3052 /* 3076 /*
@@ -3258,7 +3282,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
3258 rt2x00dev->hw->max_report_rates = 7; 3282 rt2x00dev->hw->max_report_rates = 7;
3259 rt2x00dev->hw->max_rate_tries = 1; 3283 rt2x00dev->hw->max_rate_tries = 1;
3260 3284
3261 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); 3285 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
3262 3286
3263 /* 3287 /*
3264 * Initialize hw_mode information. 3288 * Initialize hw_mode information.
@@ -3302,11 +3326,11 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
3302 IEEE80211_HT_CAP_SGI_20 | 3326 IEEE80211_HT_CAP_SGI_20 |
3303 IEEE80211_HT_CAP_SGI_40; 3327 IEEE80211_HT_CAP_SGI_40;
3304 3328
3305 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) >= 2) 3329 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) >= 2)
3306 spec->ht.cap |= IEEE80211_HT_CAP_TX_STBC; 3330 spec->ht.cap |= IEEE80211_HT_CAP_TX_STBC;
3307 3331
3308 spec->ht.cap |= 3332 spec->ht.cap |=
3309 rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) << 3333 rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) <<
3310 IEEE80211_HT_CAP_RX_STBC_SHIFT; 3334 IEEE80211_HT_CAP_RX_STBC_SHIFT;
3311 3335
3312 spec->ht.ampdu_factor = 3; 3336 spec->ht.ampdu_factor = 3;
@@ -3314,10 +3338,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
3314 spec->ht.mcs.tx_params = 3338 spec->ht.mcs.tx_params =
3315 IEEE80211_HT_MCS_TX_DEFINED | 3339 IEEE80211_HT_MCS_TX_DEFINED |
3316 IEEE80211_HT_MCS_TX_RX_DIFF | 3340 IEEE80211_HT_MCS_TX_RX_DIFF |
3317 ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) << 3341 ((rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) - 1) <<
3318 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); 3342 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
3319 3343
3320 switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) { 3344 switch (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH)) {
3321 case 3: 3345 case 3:
3322 spec->ht.mcs.rx_mask[2] = 0xff; 3346 spec->ht.mcs.rx_mask[2] = 0xff;
3323 case 2: 3347 case 2:
@@ -3536,6 +3560,37 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3536} 3560}
3537EXPORT_SYMBOL_GPL(rt2800_ampdu_action); 3561EXPORT_SYMBOL_GPL(rt2800_ampdu_action);
3538 3562
3563int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
3564 struct survey_info *survey)
3565{
3566 struct rt2x00_dev *rt2x00dev = hw->priv;
3567 struct ieee80211_conf *conf = &hw->conf;
3568 u32 idle, busy, busy_ext;
3569
3570 if (idx != 0)
3571 return -ENOENT;
3572
3573 survey->channel = conf->channel;
3574
3575 rt2800_register_read(rt2x00dev, CH_IDLE_STA, &idle);
3576 rt2800_register_read(rt2x00dev, CH_BUSY_STA, &busy);
3577 rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &busy_ext);
3578
3579 if (idle || busy) {
3580 survey->filled = SURVEY_INFO_CHANNEL_TIME |
3581 SURVEY_INFO_CHANNEL_TIME_BUSY |
3582 SURVEY_INFO_CHANNEL_TIME_EXT_BUSY;
3583
3584 survey->channel_time = (idle + busy) / 1000;
3585 survey->channel_time_busy = busy / 1000;
3586 survey->channel_time_ext_busy = busy_ext / 1000;
3587 }
3588
3589 return 0;
3590
3591}
3592EXPORT_SYMBOL_GPL(rt2800_get_survey);
3593
3539MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz"); 3594MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz");
3540MODULE_VERSION(DRV_VERSION); 3595MODULE_VERSION(DRV_VERSION);
3541MODULE_DESCRIPTION("Ralink RT2800 library"); 3596MODULE_DESCRIPTION("Ralink RT2800 library");
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 81cbc92e7857..e3c995a9dec4 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -199,5 +199,7 @@ u64 rt2800_get_tsf(struct ieee80211_hw *hw);
199int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 199int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
200 enum ieee80211_ampdu_mlme_action action, 200 enum ieee80211_ampdu_mlme_action action,
201 struct ieee80211_sta *sta, u16 tid, u16 *ssn); 201 struct ieee80211_sta *sta, u16 tid, u16 *ssn);
202int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
203 struct survey_info *survey);
202 204
203#endif /* RT2800LIB_H */ 205#endif /* RT2800LIB_H */
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index b989b0d3ed49..baa1468a56a8 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -186,6 +186,77 @@ static inline void rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
186#endif /* CONFIG_PCI */ 186#endif /* CONFIG_PCI */
187 187
188/* 188/*
189 * Queue handlers.
190 */
191static void rt2800pci_start_queue(struct data_queue *queue)
192{
193 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
194 u32 reg;
195
196 switch (queue->qid) {
197 case QID_RX:
198 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
199 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
200 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
201 break;
202 case QID_BEACON:
203 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
204 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
205 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
206 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
207 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
208 break;
209 default:
210 break;
211 };
212}
213
214static void rt2800pci_kick_queue(struct data_queue *queue)
215{
216 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
217 struct queue_entry *entry;
218
219 switch (queue->qid) {
220 case QID_AC_VO:
221 case QID_AC_VI:
222 case QID_AC_BE:
223 case QID_AC_BK:
224 entry = rt2x00queue_get_entry(queue, Q_INDEX);
225 rt2800_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), entry->entry_idx);
226 break;
227 case QID_MGMT:
228 entry = rt2x00queue_get_entry(queue, Q_INDEX);
229 rt2800_register_write(rt2x00dev, TX_CTX_IDX(5), entry->entry_idx);
230 break;
231 default:
232 break;
233 }
234}
235
236static void rt2800pci_stop_queue(struct data_queue *queue)
237{
238 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
239 u32 reg;
240
241 switch (queue->qid) {
242 case QID_RX:
243 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
244 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
245 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
246 break;
247 case QID_BEACON:
248 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
249 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
250 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
251 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
252 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
253 break;
254 default:
255 break;
256 }
257}
258
259/*
189 * Firmware functions 260 * Firmware functions
190 */ 261 */
191static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) 262static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
@@ -323,17 +394,6 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
323/* 394/*
324 * Device state switch handlers. 395 * Device state switch handlers.
325 */ 396 */
326static void rt2800pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
327 enum dev_state state)
328{
329 u32 reg;
330
331 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
332 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
333 (state == STATE_RADIO_RX_ON));
334 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
335}
336
337static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, 397static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
338 enum dev_state state) 398 enum dev_state state)
339{ 399{
@@ -477,10 +537,6 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
477 rt2800pci_disable_radio(rt2x00dev); 537 rt2800pci_disable_radio(rt2x00dev);
478 rt2800pci_set_state(rt2x00dev, STATE_SLEEP); 538 rt2800pci_set_state(rt2x00dev, STATE_SLEEP);
479 break; 539 break;
480 case STATE_RADIO_RX_ON:
481 case STATE_RADIO_RX_OFF:
482 rt2800pci_toggle_rx(rt2x00dev, state);
483 break;
484 case STATE_RADIO_IRQ_ON: 540 case STATE_RADIO_IRQ_ON:
485 case STATE_RADIO_IRQ_ON_ISR: 541 case STATE_RADIO_IRQ_ON_ISR:
486 case STATE_RADIO_IRQ_OFF: 542 case STATE_RADIO_IRQ_OFF:
@@ -566,41 +622,6 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry,
566} 622}
567 623
568/* 624/*
569 * TX data initialization
570 */
571static void rt2800pci_kick_tx_queue(struct data_queue *queue)
572{
573 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
574 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
575 unsigned int qidx;
576
577 if (queue->qid == QID_MGMT)
578 qidx = 5;
579 else
580 qidx = queue->qid;
581
582 rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), entry->entry_idx);
583}
584
585static void rt2800pci_kill_tx_queue(struct data_queue *queue)
586{
587 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
588 u32 reg;
589
590 if (queue->qid == QID_BEACON) {
591 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0);
592 return;
593 }
594
595 rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
596 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, (queue->qid == QID_AC_BE));
597 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, (queue->qid == QID_AC_BK));
598 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, (queue->qid == QID_AC_VI));
599 rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, (queue->qid == QID_AC_VO));
600 rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
601}
602
603/*
604 * RX control handlers 625 * RX control handlers
605 */ 626 */
606static void rt2800pci_fill_rxdone(struct queue_entry *entry, 627static void rt2800pci_fill_rxdone(struct queue_entry *entry,
@@ -682,7 +703,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
682 * this tx status. 703 * this tx status.
683 */ 704 */
684 WARNING(rt2x00dev, "Got TX status report with " 705 WARNING(rt2x00dev, "Got TX status report with "
685 "unexpected pid %u, dropping", qid); 706 "unexpected pid %u, dropping\n", qid);
686 break; 707 break;
687 } 708 }
688 709
@@ -693,7 +714,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
693 * processing here and drop the tx status 714 * processing here and drop the tx status
694 */ 715 */
695 WARNING(rt2x00dev, "Got TX status for an unavailable " 716 WARNING(rt2x00dev, "Got TX status for an unavailable "
696 "queue %u, dropping", qid); 717 "queue %u, dropping\n", qid);
697 break; 718 break;
698 } 719 }
699 720
@@ -703,7 +724,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
703 * and drop the tx status. 724 * and drop the tx status.
704 */ 725 */
705 WARNING(rt2x00dev, "Got TX status for an empty " 726 WARNING(rt2x00dev, "Got TX status for an empty "
706 "queue %u, dropping", qid); 727 "queue %u, dropping\n", qid);
707 break; 728 break;
708 } 729 }
709 730
@@ -944,6 +965,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = {
944 .rfkill_poll = rt2x00mac_rfkill_poll, 965 .rfkill_poll = rt2x00mac_rfkill_poll,
945 .ampdu_action = rt2800_ampdu_action, 966 .ampdu_action = rt2800_ampdu_action,
946 .flush = rt2x00mac_flush, 967 .flush = rt2x00mac_flush,
968 .get_survey = rt2800_get_survey,
947}; 969};
948 970
949static const struct rt2800_ops rt2800pci_rt2800_ops = { 971static const struct rt2800_ops rt2800pci_rt2800_ops = {
@@ -976,11 +998,12 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
976 .link_stats = rt2800_link_stats, 998 .link_stats = rt2800_link_stats,
977 .reset_tuner = rt2800_reset_tuner, 999 .reset_tuner = rt2800_reset_tuner,
978 .link_tuner = rt2800_link_tuner, 1000 .link_tuner = rt2800_link_tuner,
1001 .start_queue = rt2800pci_start_queue,
1002 .kick_queue = rt2800pci_kick_queue,
1003 .stop_queue = rt2800pci_stop_queue,
979 .write_tx_desc = rt2800pci_write_tx_desc, 1004 .write_tx_desc = rt2800pci_write_tx_desc,
980 .write_tx_data = rt2800_write_tx_data, 1005 .write_tx_data = rt2800_write_tx_data,
981 .write_beacon = rt2800_write_beacon, 1006 .write_beacon = rt2800_write_beacon,
982 .kick_tx_queue = rt2800pci_kick_tx_queue,
983 .kill_tx_queue = rt2800pci_kill_tx_queue,
984 .fill_rxdone = rt2800pci_fill_rxdone, 1007 .fill_rxdone = rt2800pci_fill_rxdone,
985 .config_shared_key = rt2800_config_shared_key, 1008 .config_shared_key = rt2800_config_shared_key,
986 .config_pairwise_key = rt2800_config_pairwise_key, 1009 .config_pairwise_key = rt2800_config_pairwise_key,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 935b76d3ce4f..3e0205ddf7b4 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -50,6 +50,55 @@ module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
50MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 50MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
51 51
52/* 52/*
53 * Queue handlers.
54 */
55static void rt2800usb_start_queue(struct data_queue *queue)
56{
57 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
58 u32 reg;
59
60 switch (queue->qid) {
61 case QID_RX:
62 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
63 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
64 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
65 break;
66 case QID_BEACON:
67 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
68 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
69 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
70 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
71 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
72 break;
73 default:
74 break;
75 }
76}
77
78static void rt2800usb_stop_queue(struct data_queue *queue)
79{
80 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
81 u32 reg;
82
83 switch (queue->qid) {
84 case QID_RX:
85 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
86 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
87 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
88 break;
89 case QID_BEACON:
90 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
91 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
92 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
93 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
94 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
95 break;
96 default:
97 break;
98 }
99}
100
101/*
53 * Firmware functions 102 * Firmware functions
54 */ 103 */
55static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) 104static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
@@ -107,17 +156,6 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
107/* 156/*
108 * Device state switch handlers. 157 * Device state switch handlers.
109 */ 158 */
110static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
111 enum dev_state state)
112{
113 u32 reg;
114
115 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
116 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
117 (state == STATE_RADIO_RX_ON));
118 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
119}
120
121static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) 159static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
122{ 160{
123 u32 reg; 161 u32 reg;
@@ -214,10 +252,6 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
214 rt2800usb_disable_radio(rt2x00dev); 252 rt2800usb_disable_radio(rt2x00dev);
215 rt2800usb_set_state(rt2x00dev, STATE_SLEEP); 253 rt2800usb_set_state(rt2x00dev, STATE_SLEEP);
216 break; 254 break;
217 case STATE_RADIO_RX_ON:
218 case STATE_RADIO_RX_OFF:
219 rt2800usb_toggle_rx(rt2x00dev, state);
220 break;
221 case STATE_RADIO_IRQ_ON: 255 case STATE_RADIO_IRQ_ON:
222 case STATE_RADIO_IRQ_ON_ISR: 256 case STATE_RADIO_IRQ_ON_ISR:
223 case STATE_RADIO_IRQ_OFF: 257 case STATE_RADIO_IRQ_OFF:
@@ -253,7 +287,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
253 rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg); 287 rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
254 if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) { 288 if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) {
255 WARNING(rt2x00dev, "TX HW queue 0 timed out," 289 WARNING(rt2x00dev, "TX HW queue 0 timed out,"
256 " invoke forced kick"); 290 " invoke forced kick\n");
257 291
258 rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012); 292 rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012);
259 293
@@ -269,7 +303,7 @@ static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
269 rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg); 303 rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
270 if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) { 304 if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) {
271 WARNING(rt2x00dev, "TX HW queue 1 timed out," 305 WARNING(rt2x00dev, "TX HW queue 1 timed out,"
272 " invoke forced kick"); 306 " invoke forced kick\n");
273 307
274 rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a); 308 rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a);
275 309
@@ -389,14 +423,6 @@ static void rt2800usb_work_txdone(struct work_struct *work)
389 } 423 }
390} 424}
391 425
392static void rt2800usb_kill_tx_queue(struct data_queue *queue)
393{
394 if (queue->qid == QID_BEACON)
395 rt2x00usb_register_write(queue->rt2x00dev, BCN_TIME_CFG, 0);
396
397 rt2x00usb_kill_tx_queue(queue);
398}
399
400/* 426/*
401 * RX control handlers 427 * RX control handlers
402 */ 428 */
@@ -562,6 +588,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = {
562 .rfkill_poll = rt2x00mac_rfkill_poll, 588 .rfkill_poll = rt2x00mac_rfkill_poll,
563 .ampdu_action = rt2800_ampdu_action, 589 .ampdu_action = rt2800_ampdu_action,
564 .flush = rt2x00mac_flush, 590 .flush = rt2x00mac_flush,
591 .get_survey = rt2800_get_survey,
565}; 592};
566 593
567static const struct rt2800_ops rt2800usb_rt2800_ops = { 594static const struct rt2800_ops rt2800usb_rt2800_ops = {
@@ -591,12 +618,14 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
591 .reset_tuner = rt2800_reset_tuner, 618 .reset_tuner = rt2800_reset_tuner,
592 .link_tuner = rt2800_link_tuner, 619 .link_tuner = rt2800_link_tuner,
593 .watchdog = rt2800usb_watchdog, 620 .watchdog = rt2800usb_watchdog,
621 .start_queue = rt2800usb_start_queue,
622 .kick_queue = rt2x00usb_kick_queue,
623 .stop_queue = rt2800usb_stop_queue,
624 .flush_queue = rt2x00usb_flush_queue,
594 .write_tx_desc = rt2800usb_write_tx_desc, 625 .write_tx_desc = rt2800usb_write_tx_desc,
595 .write_tx_data = rt2800usb_write_tx_data, 626 .write_tx_data = rt2800usb_write_tx_data,
596 .write_beacon = rt2800_write_beacon, 627 .write_beacon = rt2800_write_beacon,
597 .get_tx_data_len = rt2800usb_get_tx_data_len, 628 .get_tx_data_len = rt2800usb_get_tx_data_len,
598 .kick_tx_queue = rt2x00usb_kick_tx_queue,
599 .kill_tx_queue = rt2800usb_kill_tx_queue,
600 .fill_rxdone = rt2800usb_fill_rxdone, 629 .fill_rxdone = rt2800usb_fill_rxdone,
601 .config_shared_key = rt2800_config_shared_key, 630 .config_shared_key = rt2800_config_shared_key,
602 .config_pairwise_key = rt2800_config_pairwise_key, 631 .config_pairwise_key = rt2800_config_pairwise_key,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index e72117f3fdf5..c254d5a62c7d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -66,7 +66,7 @@
66 66
67#ifdef CONFIG_RT2X00_DEBUG 67#ifdef CONFIG_RT2X00_DEBUG
68#define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ 68#define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \
69 DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args); 69 DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args)
70#else 70#else
71#define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ 71#define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \
72 do { } while (0) 72 do { } while (0)
@@ -567,7 +567,15 @@ struct rt2x00lib_ops {
567 struct link_qual *qual); 567 struct link_qual *qual);
568 void (*link_tuner) (struct rt2x00_dev *rt2x00dev, 568 void (*link_tuner) (struct rt2x00_dev *rt2x00dev,
569 struct link_qual *qual, const u32 count); 569 struct link_qual *qual, const u32 count);
570
571 /*
572 * Data queue handlers.
573 */
570 void (*watchdog) (struct rt2x00_dev *rt2x00dev); 574 void (*watchdog) (struct rt2x00_dev *rt2x00dev);
575 void (*start_queue) (struct data_queue *queue);
576 void (*kick_queue) (struct data_queue *queue);
577 void (*stop_queue) (struct data_queue *queue);
578 void (*flush_queue) (struct data_queue *queue);
571 579
572 /* 580 /*
573 * TX control handlers 581 * TX control handlers
@@ -579,8 +587,6 @@ struct rt2x00lib_ops {
579 void (*write_beacon) (struct queue_entry *entry, 587 void (*write_beacon) (struct queue_entry *entry,
580 struct txentry_desc *txdesc); 588 struct txentry_desc *txdesc);
581 int (*get_tx_data_len) (struct queue_entry *entry); 589 int (*get_tx_data_len) (struct queue_entry *entry);
582 void (*kick_tx_queue) (struct data_queue *queue);
583 void (*kill_tx_queue) (struct data_queue *queue);
584 590
585 /* 591 /*
586 * RX control handlers 592 * RX control handlers
@@ -1068,6 +1074,78 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
1068struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, 1074struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
1069 enum queue_index index); 1075 enum queue_index index);
1070 1076
1077/**
1078 * rt2x00queue_pause_queue - Pause a data queue
1079 * @queue: Pointer to &struct data_queue.
1080 *
1081 * This function will pause the data queue locally, preventing
1082 * new frames to be added to the queue (while the hardware is
1083 * still allowed to run).
1084 */
1085void rt2x00queue_pause_queue(struct data_queue *queue);
1086
1087/**
1088 * rt2x00queue_unpause_queue - unpause a data queue
1089 * @queue: Pointer to &struct data_queue.
1090 *
1091 * This function will unpause the data queue locally, allowing
1092 * new frames to be added to the queue again.
1093 */
1094void rt2x00queue_unpause_queue(struct data_queue *queue);
1095
1096/**
1097 * rt2x00queue_start_queue - Start a data queue
1098 * @queue: Pointer to &struct data_queue.
1099 *
1100 * This function will start handling all pending frames in the queue.
1101 */
1102void rt2x00queue_start_queue(struct data_queue *queue);
1103
1104/**
1105 * rt2x00queue_stop_queue - Halt a data queue
1106 * @queue: Pointer to &struct data_queue.
1107 *
1108 * This function will stop all pending frames in the queue.
1109 */
1110void rt2x00queue_stop_queue(struct data_queue *queue);
1111
1112/**
1113 * rt2x00queue_flush_queue - Flush a data queue
1114 * @queue: Pointer to &struct data_queue.
1115 * @drop: True to drop all pending frames.
1116 *
1117 * This function will flush the queue. After this call
1118 * the queue is guarenteed to be empty.
1119 */
1120void rt2x00queue_flush_queue(struct data_queue *queue, bool drop);
1121
1122/**
1123 * rt2x00queue_start_queues - Start all data queues
1124 * @rt2x00dev: Pointer to &struct rt2x00_dev.
1125 *
1126 * This function will loop through all available queues to start them
1127 */
1128void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev);
1129
1130/**
1131 * rt2x00queue_stop_queues - Halt all data queues
1132 * @rt2x00dev: Pointer to &struct rt2x00_dev.
1133 *
1134 * This function will loop through all available queues to stop
1135 * any pending frames.
1136 */
1137void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);
1138
1139/**
1140 * rt2x00queue_flush_queues - Flush all data queues
1141 * @rt2x00dev: Pointer to &struct rt2x00_dev.
1142 * @drop: True to drop all pending frames.
1143 *
1144 * This function will loop through all available queues to flush
1145 * any pending frames.
1146 */
1147void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop);
1148
1071/* 1149/*
1072 * Debugfs handlers. 1150 * Debugfs handlers.
1073 */ 1151 */
@@ -1093,6 +1171,7 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
1093 */ 1171 */
1094void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); 1172void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
1095void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev); 1173void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev);
1174void rt2x00lib_dmastart(struct queue_entry *entry);
1096void rt2x00lib_dmadone(struct queue_entry *entry); 1175void rt2x00lib_dmadone(struct queue_entry *entry);
1097void rt2x00lib_txdone(struct queue_entry *entry, 1176void rt2x00lib_txdone(struct queue_entry *entry,
1098 struct txdone_entry_desc *txdesc); 1177 struct txdone_entry_desc *txdesc);
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index a238e908c854..70ca9379833b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -146,8 +146,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
146 * else the changes will be ignored by the device. 146 * else the changes will be ignored by the device.
147 */ 147 */
148 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) 148 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
149 rt2x00dev->ops->lib->set_device_state(rt2x00dev, 149 rt2x00queue_stop_queue(rt2x00dev->rx);
150 STATE_RADIO_RX_OFF);
151 150
152 /* 151 /*
153 * Write new antenna setup to device and reset the link tuner. 152 * Write new antenna setup to device and reset the link tuner.
@@ -161,8 +160,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
161 memcpy(active, &config, sizeof(config)); 160 memcpy(active, &config, sizeof(config));
162 161
163 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) 162 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
164 rt2x00dev->ops->lib->set_device_state(rt2x00dev, 163 rt2x00queue_start_queue(rt2x00dev->rx);
165 STATE_RADIO_RX_ON);
166} 164}
167 165
168void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, 166void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 64dfb1f6823e..c92db3264741 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -339,12 +339,13 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
339 return -ENOMEM; 339 return -ENOMEM;
340 340
341 temp = data + 341 temp = data +
342 sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n"); 342 sprintf(data, "qid\tflags\t\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
343 343
344 queue_for_each(intf->rt2x00dev, queue) { 344 queue_for_each(intf->rt2x00dev, queue) {
345 spin_lock_irqsave(&queue->index_lock, irqflags); 345 spin_lock_irqsave(&queue->index_lock, irqflags);
346 346
347 temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, 347 temp += sprintf(temp, "%d\t0x%.8x\t%d\t%d\t%d\t%d\t%d\t\t%d\n",
348 queue->qid, (unsigned int)queue->flags,
348 queue->count, queue->limit, queue->length, 349 queue->count, queue->limit, queue->length,
349 queue->index[Q_INDEX], 350 queue->index[Q_INDEX],
350 queue->index[Q_INDEX_DMA_DONE], 351 queue->index[Q_INDEX_DMA_DONE],
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index bd3afc92f434..fa74acdd271f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -66,9 +66,9 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
66 set_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags); 66 set_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags);
67 67
68 /* 68 /*
69 * Enable RX. 69 * Enable queues.
70 */ 70 */
71 rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON); 71 rt2x00queue_start_queues(rt2x00dev);
72 rt2x00link_start_tuner(rt2x00dev); 72 rt2x00link_start_tuner(rt2x00dev);
73 73
74 /* 74 /*
@@ -76,11 +76,6 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
76 */ 76 */
77 rt2x00link_start_watchdog(rt2x00dev); 77 rt2x00link_start_watchdog(rt2x00dev);
78 78
79 /*
80 * Start the TX queues.
81 */
82 ieee80211_wake_queues(rt2x00dev->hw);
83
84 return 0; 79 return 0;
85} 80}
86 81
@@ -90,21 +85,16 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
90 return; 85 return;
91 86
92 /* 87 /*
93 * Stop the TX queues in mac80211.
94 */
95 ieee80211_stop_queues(rt2x00dev->hw);
96 rt2x00queue_stop_queues(rt2x00dev);
97
98 /*
99 * Stop watchdog monitoring. 88 * Stop watchdog monitoring.
100 */ 89 */
101 rt2x00link_stop_watchdog(rt2x00dev); 90 rt2x00link_stop_watchdog(rt2x00dev);
102 91
103 /* 92 /*
104 * Disable RX. 93 * Stop all queues
105 */ 94 */
106 rt2x00link_stop_tuner(rt2x00dev); 95 rt2x00link_stop_tuner(rt2x00dev);
107 rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF); 96 rt2x00queue_stop_queues(rt2x00dev);
97 rt2x00queue_flush_queues(rt2x00dev, true);
108 98
109 /* 99 /*
110 * Disable radio. 100 * Disable radio.
@@ -236,8 +226,16 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev)
236} 226}
237EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); 227EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
238 228
229void rt2x00lib_dmastart(struct queue_entry *entry)
230{
231 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
232 rt2x00queue_index_inc(entry->queue, Q_INDEX);
233}
234EXPORT_SYMBOL_GPL(rt2x00lib_dmastart);
235
239void rt2x00lib_dmadone(struct queue_entry *entry) 236void rt2x00lib_dmadone(struct queue_entry *entry)
240{ 237{
238 set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags);
241 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 239 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
242 rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); 240 rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
243} 241}
@@ -249,7 +247,6 @@ void rt2x00lib_txdone(struct queue_entry *entry,
249 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 247 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
250 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); 248 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
251 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 249 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
252 enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
253 unsigned int header_length, i; 250 unsigned int header_length, i;
254 u8 rate_idx, rate_flags, retry_rates; 251 u8 rate_idx, rate_flags, retry_rates;
255 u8 skbdesc_flags = skbdesc->flags; 252 u8 skbdesc_flags = skbdesc->flags;
@@ -403,7 +400,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
403 * is reenabled when the txdone handler has finished. 400 * is reenabled when the txdone handler has finished.
404 */ 401 */
405 if (!rt2x00queue_threshold(entry->queue)) 402 if (!rt2x00queue_threshold(entry->queue))
406 ieee80211_wake_queue(rt2x00dev->hw, qid); 403 rt2x00queue_unpause_queue(entry->queue);
407} 404}
408EXPORT_SYMBOL_GPL(rt2x00lib_txdone); 405EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
409 406
@@ -566,10 +563,8 @@ submit_entry:
566 entry->flags = 0; 563 entry->flags = 0;
567 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); 564 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
568 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && 565 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
569 test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) { 566 test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
570 rt2x00dev->ops->lib->clear_entry(entry); 567 rt2x00dev->ops->lib->clear_entry(entry);
571 rt2x00queue_index_inc(entry->queue, Q_INDEX);
572 }
573} 568}
574EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); 569EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
575 570
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 2cf68f82674b..a105c500627b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -178,15 +178,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
178void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); 178void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
179 179
180/** 180/**
181 * rt2x00queue_stop_queues - Halt all data queues
182 * @rt2x00dev: Pointer to &struct rt2x00_dev.
183 *
184 * This function will loop through all available queues to stop
185 * any pending outgoing frames.
186 */
187void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);
188
189/**
190 * rt2x00queue_init_queues - Initialize all data queues 181 * rt2x00queue_init_queues - Initialize all data queues
191 * @rt2x00dev: Pointer to &struct rt2x00_dev. 182 * @rt2x00dev: Pointer to &struct rt2x00_dev.
192 * 183 *
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 829bf4be9bc3..4cac7ad60f47 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -104,7 +104,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
104 struct rt2x00_dev *rt2x00dev = hw->priv; 104 struct rt2x00_dev *rt2x00dev = hw->priv;
105 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 105 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
106 enum data_queue_qid qid = skb_get_queue_mapping(skb); 106 enum data_queue_qid qid = skb_get_queue_mapping(skb);
107 struct data_queue *queue; 107 struct data_queue *queue = NULL;
108 108
109 /* 109 /*
110 * Mac80211 might be calling this function while we are trying 110 * Mac80211 might be calling this function while we are trying
@@ -153,7 +153,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
153 goto exit_fail; 153 goto exit_fail;
154 154
155 if (rt2x00queue_threshold(queue)) 155 if (rt2x00queue_threshold(queue))
156 ieee80211_stop_queue(rt2x00dev->hw, qid); 156 rt2x00queue_pause_queue(queue);
157 157
158 return NETDEV_TX_OK; 158 return NETDEV_TX_OK;
159 159
@@ -352,7 +352,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
352 * if for any reason the link tuner must be reset, this will be 352 * if for any reason the link tuner must be reset, this will be
353 * handled by rt2x00lib_config(). 353 * handled by rt2x00lib_config().
354 */ 354 */
355 rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_OFF); 355 rt2x00queue_stop_queue(rt2x00dev->rx);
356 356
357 /* 357 /*
358 * When we've just turned on the radio, we want to reprogram 358 * When we've just turned on the radio, we want to reprogram
@@ -370,7 +370,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
370 rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant); 370 rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant);
371 371
372 /* Turn RX back on */ 372 /* Turn RX back on */
373 rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_RX_ON); 373 rt2x00queue_start_queue(rt2x00dev->rx);
374 374
375 return 0; 375 return 0;
376} 376}
@@ -718,36 +718,8 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
718{ 718{
719 struct rt2x00_dev *rt2x00dev = hw->priv; 719 struct rt2x00_dev *rt2x00dev = hw->priv;
720 struct data_queue *queue; 720 struct data_queue *queue;
721 unsigned int i = 0;
722
723 ieee80211_stop_queues(hw);
724
725 /*
726 * Run over all queues to kick them, this will force
727 * any pending frames to be transmitted.
728 */
729 tx_queue_for_each(rt2x00dev, queue) {
730 rt2x00dev->ops->lib->kick_tx_queue(queue);
731 }
732
733 /**
734 * All queues have been kicked, now wait for each queue
735 * to become empty. With a bit of luck, we only have to wait
736 * for the first queue to become empty, because while waiting
737 * for the that queue, the other queues will have transmitted
738 * all their frames as well (since they were already kicked).
739 */
740 tx_queue_for_each(rt2x00dev, queue) {
741 for (i = 0; i < 10; i++) {
742 if (rt2x00queue_empty(queue))
743 break;
744 msleep(100);
745 }
746
747 if (!rt2x00queue_empty(queue))
748 WARNING(rt2x00dev, "Failed to flush queue %d", queue->qid);
749 }
750 721
751 ieee80211_wake_queues(hw); 722 tx_queue_for_each(rt2x00dev, queue)
723 rt2x00queue_flush_queue(queue, drop);
752} 724}
753EXPORT_SYMBOL_GPL(rt2x00mac_flush); 725EXPORT_SYMBOL_GPL(rt2x00mac_flush);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 868ca19b13ea..28e6ff1a6694 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -82,6 +82,13 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
82 skbdesc->desc_len = entry->queue->desc_size; 82 skbdesc->desc_len = entry->queue->desc_size;
83 83
84 /* 84 /*
85 * DMA is already done, notify rt2x00lib that
86 * it finished successfully.
87 */
88 rt2x00lib_dmastart(entry);
89 rt2x00lib_dmadone(entry);
90
91 /*
85 * Send the frame to rt2x00lib for further processing. 92 * Send the frame to rt2x00lib for further processing.
86 */ 93 */
87 rt2x00lib_rxdone(entry); 94 rt2x00lib_rxdone(entry);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index b854d62ff99b..746ce8fe8cf4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -64,7 +64,7 @@ static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
64 const void *value, 64 const void *value,
65 const u32 length) 65 const u32 length)
66{ 66{
67 memcpy_toio(rt2x00dev->csr.base + offset, value, length); 67 __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2);
68} 68}
69 69
70/** 70/**
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index a3d79c7a21c6..ca82b3a91697 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -199,15 +199,18 @@ void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
199 199
200void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) 200void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
201{ 201{
202 unsigned int l2pad = L2PAD_SIZE(header_length); 202 /*
203 * L2 padding is only present if the skb contains more than just the
204 * IEEE 802.11 header.
205 */
206 unsigned int l2pad = (skb->len > header_length) ?
207 L2PAD_SIZE(header_length) : 0;
203 208
204 if (!l2pad) 209 if (!l2pad)
205 return; 210 return;
206 211
207 memmove(skb->data + header_length, skb->data + header_length + l2pad, 212 memmove(skb->data + l2pad, skb->data, header_length);
208 skb->len - header_length - l2pad); 213 skb_pull(skb, l2pad);
209
210 skb_trim(skb, skb->len - l2pad);
211} 214}
212 215
213static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, 216static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
@@ -468,7 +471,7 @@ static void rt2x00queue_kick_tx_queue(struct data_queue *queue,
468 */ 471 */
469 if (rt2x00queue_threshold(queue) || 472 if (rt2x00queue_threshold(queue) ||
470 !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) 473 !test_bit(ENTRY_TXD_BURST, &txdesc->flags))
471 queue->rt2x00dev->ops->lib->kick_tx_queue(queue); 474 queue->rt2x00dev->ops->lib->kick_queue(queue);
472} 475}
473 476
474int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, 477int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
@@ -582,7 +585,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
582 rt2x00queue_free_skb(intf->beacon); 585 rt2x00queue_free_skb(intf->beacon);
583 586
584 if (!enable_beacon) { 587 if (!enable_beacon) {
585 rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue); 588 rt2x00queue_stop_queue(intf->beacon->queue);
586 mutex_unlock(&intf->beacon_skb_mutex); 589 mutex_unlock(&intf->beacon_skb_mutex);
587 return 0; 590 return 0;
588 } 591 }
@@ -735,6 +738,210 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
735 spin_unlock_irqrestore(&queue->index_lock, irqflags); 738 spin_unlock_irqrestore(&queue->index_lock, irqflags);
736} 739}
737 740
741void rt2x00queue_pause_queue(struct data_queue *queue)
742{
743 if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
744 !test_bit(QUEUE_STARTED, &queue->flags) ||
745 test_and_set_bit(QUEUE_PAUSED, &queue->flags))
746 return;
747
748 switch (queue->qid) {
749 case QID_AC_VO:
750 case QID_AC_VI:
751 case QID_AC_BE:
752 case QID_AC_BK:
753 /*
754 * For TX queues, we have to disable the queue
755 * inside mac80211.
756 */
757 ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid);
758 break;
759 default:
760 break;
761 }
762}
763EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue);
764
765void rt2x00queue_unpause_queue(struct data_queue *queue)
766{
767 if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
768 !test_bit(QUEUE_STARTED, &queue->flags) ||
769 !test_and_clear_bit(QUEUE_PAUSED, &queue->flags))
770 return;
771
772 switch (queue->qid) {
773 case QID_AC_VO:
774 case QID_AC_VI:
775 case QID_AC_BE:
776 case QID_AC_BK:
777 /*
778 * For TX queues, we have to enable the queue
779 * inside mac80211.
780 */
781 ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid);
782 break;
783 case QID_RX:
784 /*
785 * For RX we need to kick the queue now in order to
786 * receive frames.
787 */
788 queue->rt2x00dev->ops->lib->kick_queue(queue);
789 default:
790 break;
791 }
792}
793EXPORT_SYMBOL_GPL(rt2x00queue_unpause_queue);
794
795void rt2x00queue_start_queue(struct data_queue *queue)
796{
797 mutex_lock(&queue->status_lock);
798
799 if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
800 test_and_set_bit(QUEUE_STARTED, &queue->flags)) {
801 mutex_unlock(&queue->status_lock);
802 return;
803 }
804
805 set_bit(QUEUE_PAUSED, &queue->flags);
806
807 queue->rt2x00dev->ops->lib->start_queue(queue);
808
809 rt2x00queue_unpause_queue(queue);
810
811 mutex_unlock(&queue->status_lock);
812}
813EXPORT_SYMBOL_GPL(rt2x00queue_start_queue);
814
815void rt2x00queue_stop_queue(struct data_queue *queue)
816{
817 mutex_lock(&queue->status_lock);
818
819 if (!test_and_clear_bit(QUEUE_STARTED, &queue->flags)) {
820 mutex_unlock(&queue->status_lock);
821 return;
822 }
823
824 rt2x00queue_pause_queue(queue);
825
826 queue->rt2x00dev->ops->lib->stop_queue(queue);
827
828 mutex_unlock(&queue->status_lock);
829}
830EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue);
831
832void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
833{
834 unsigned int i;
835 bool started;
836 bool tx_queue =
837 (queue->qid == QID_AC_VO) ||
838 (queue->qid == QID_AC_VI) ||
839 (queue->qid == QID_AC_BE) ||
840 (queue->qid == QID_AC_BK);
841
842 mutex_lock(&queue->status_lock);
843
844 /*
845 * If the queue has been started, we must stop it temporarily
846 * to prevent any new frames to be queued on the device. If
847 * we are not dropping the pending frames, the queue must
848 * only be stopped in the software and not the hardware,
849 * otherwise the queue will never become empty on its own.
850 */
851 started = test_bit(QUEUE_STARTED, &queue->flags);
852 if (started) {
853 /*
854 * Pause the queue
855 */
856 rt2x00queue_pause_queue(queue);
857
858 /*
859 * If we are not supposed to drop any pending
860 * frames, this means we must force a start (=kick)
861 * to the queue to make sure the hardware will
862 * start transmitting.
863 */
864 if (!drop && tx_queue)
865 queue->rt2x00dev->ops->lib->kick_queue(queue);
866 }
867
868 /*
869 * Check if driver supports flushing, we can only guarentee
870 * full support for flushing if the driver is able
871 * to cancel all pending frames (drop = true).
872 */
873 if (drop && queue->rt2x00dev->ops->lib->flush_queue)
874 queue->rt2x00dev->ops->lib->flush_queue(queue);
875
876 /*
877 * When we don't want to drop any frames, or when
878 * the driver doesn't fully flush the queue correcly,
879 * we must wait for the queue to become empty.
880 */
881 for (i = 0; !rt2x00queue_empty(queue) && i < 100; i++)
882 msleep(10);
883
884 /*
885 * The queue flush has failed...
886 */
887 if (unlikely(!rt2x00queue_empty(queue)))
888 WARNING(queue->rt2x00dev, "Queue %d failed to flush", queue->qid);
889
890 /*
891 * Restore the queue to the previous status
892 */
893 if (started)
894 rt2x00queue_unpause_queue(queue);
895
896 mutex_unlock(&queue->status_lock);
897}
898EXPORT_SYMBOL_GPL(rt2x00queue_flush_queue);
899
900void rt2x00queue_start_queues(struct rt2x00_dev *rt2x00dev)
901{
902 struct data_queue *queue;
903
904 /*
905 * rt2x00queue_start_queue will call ieee80211_wake_queue
906 * for each queue after is has been properly initialized.
907 */
908 tx_queue_for_each(rt2x00dev, queue)
909 rt2x00queue_start_queue(queue);
910
911 rt2x00queue_start_queue(rt2x00dev->rx);
912}
913EXPORT_SYMBOL_GPL(rt2x00queue_start_queues);
914
915void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
916{
917 struct data_queue *queue;
918
919 /*
920 * rt2x00queue_stop_queue will call ieee80211_stop_queue
921 * as well, but we are completely shutting doing everything
922 * now, so it is much safer to stop all TX queues at once,
923 * and use rt2x00queue_stop_queue for cleaning up.
924 */
925 ieee80211_stop_queues(rt2x00dev->hw);
926
927 tx_queue_for_each(rt2x00dev, queue)
928 rt2x00queue_stop_queue(queue);
929
930 rt2x00queue_stop_queue(rt2x00dev->rx);
931}
932EXPORT_SYMBOL_GPL(rt2x00queue_stop_queues);
933
934void rt2x00queue_flush_queues(struct rt2x00_dev *rt2x00dev, bool drop)
935{
936 struct data_queue *queue;
937
938 tx_queue_for_each(rt2x00dev, queue)
939 rt2x00queue_flush_queue(queue, drop);
940
941 rt2x00queue_flush_queue(rt2x00dev->rx, drop);
942}
943EXPORT_SYMBOL_GPL(rt2x00queue_flush_queues);
944
738static void rt2x00queue_reset(struct data_queue *queue) 945static void rt2x00queue_reset(struct data_queue *queue)
739{ 946{
740 unsigned long irqflags; 947 unsigned long irqflags;
@@ -753,14 +960,6 @@ static void rt2x00queue_reset(struct data_queue *queue)
753 spin_unlock_irqrestore(&queue->index_lock, irqflags); 960 spin_unlock_irqrestore(&queue->index_lock, irqflags);
754} 961}
755 962
756void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
757{
758 struct data_queue *queue;
759
760 txall_queue_for_each(rt2x00dev, queue)
761 rt2x00dev->ops->lib->kill_tx_queue(queue);
762}
763
764void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) 963void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
765{ 964{
766 struct data_queue *queue; 965 struct data_queue *queue;
@@ -769,11 +968,8 @@ void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
769 queue_for_each(rt2x00dev, queue) { 968 queue_for_each(rt2x00dev, queue) {
770 rt2x00queue_reset(queue); 969 rt2x00queue_reset(queue);
771 970
772 for (i = 0; i < queue->limit; i++) { 971 for (i = 0; i < queue->limit; i++)
773 rt2x00dev->ops->lib->clear_entry(&queue->entries[i]); 972 rt2x00dev->ops->lib->clear_entry(&queue->entries[i]);
774 if (queue->qid == QID_RX)
775 rt2x00queue_index_inc(queue, Q_INDEX);
776 }
777 } 973 }
778} 974}
779 975
@@ -902,6 +1098,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
902static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, 1098static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev,
903 struct data_queue *queue, enum data_queue_qid qid) 1099 struct data_queue *queue, enum data_queue_qid qid)
904{ 1100{
1101 mutex_init(&queue->status_lock);
905 spin_lock_init(&queue->index_lock); 1102 spin_lock_init(&queue->index_lock);
906 1103
907 queue->rt2x00dev = rt2x00dev; 1104 queue->rt2x00dev = rt2x00dev;
@@ -944,7 +1141,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
944 /* 1141 /*
945 * Initialize queue parameters. 1142 * Initialize queue parameters.
946 * RX: qid = QID_RX 1143 * RX: qid = QID_RX
947 * TX: qid = QID_AC_BE + index 1144 * TX: qid = QID_AC_VO + index
948 * TX: cw_min: 2^5 = 32. 1145 * TX: cw_min: 2^5 = 32.
949 * TX: cw_max: 2^10 = 1024. 1146 * TX: cw_max: 2^10 = 1024.
950 * BCN: qid = QID_BEACON 1147 * BCN: qid = QID_BEACON
@@ -952,7 +1149,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
952 */ 1149 */
953 rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX); 1150 rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX);
954 1151
955 qid = QID_AC_BE; 1152 qid = QID_AC_VO;
956 tx_queue_for_each(rt2x00dev, queue) 1153 tx_queue_for_each(rt2x00dev, queue)
957 rt2x00queue_init(rt2x00dev, queue, qid++); 1154 rt2x00queue_init(rt2x00dev, queue, qid++);
958 1155
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 29b051ac6401..fab8e2687f29 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -45,10 +45,10 @@
45/** 45/**
46 * enum data_queue_qid: Queue identification 46 * enum data_queue_qid: Queue identification
47 * 47 *
48 * @QID_AC_VO: AC VO queue
49 * @QID_AC_VI: AC VI queue
48 * @QID_AC_BE: AC BE queue 50 * @QID_AC_BE: AC BE queue
49 * @QID_AC_BK: AC BK queue 51 * @QID_AC_BK: AC BK queue
50 * @QID_AC_VI: AC VI queue
51 * @QID_AC_VO: AC VO queue
52 * @QID_HCCA: HCCA queue 52 * @QID_HCCA: HCCA queue
53 * @QID_MGMT: MGMT queue (prio queue) 53 * @QID_MGMT: MGMT queue (prio queue)
54 * @QID_RX: RX queue 54 * @QID_RX: RX queue
@@ -57,10 +57,10 @@
57 * @QID_ATIM: Atim queue (value unspeficied, don't send it to device) 57 * @QID_ATIM: Atim queue (value unspeficied, don't send it to device)
58 */ 58 */
59enum data_queue_qid { 59enum data_queue_qid {
60 QID_AC_BE = 0, 60 QID_AC_VO = 0,
61 QID_AC_BK = 1, 61 QID_AC_VI = 1,
62 QID_AC_VI = 2, 62 QID_AC_BE = 2,
63 QID_AC_VO = 3, 63 QID_AC_BK = 3,
64 QID_HCCA = 4, 64 QID_HCCA = 4,
65 QID_MGMT = 13, 65 QID_MGMT = 13,
66 QID_RX = 14, 66 QID_RX = 14,
@@ -340,12 +340,16 @@ struct txentry_desc {
340 * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured 340 * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured
341 * while transfering the data to the hardware. No TX status report will 341 * while transfering the data to the hardware. No TX status report will
342 * be expected from the hardware. 342 * be expected from the hardware.
343 * @ENTRY_DATA_STATUS_PENDING: The entry has been send to the device and
344 * returned. It is now waiting for the status reporting before the
345 * entry can be reused again.
343 */ 346 */
344enum queue_entry_flags { 347enum queue_entry_flags {
345 ENTRY_BCN_ASSIGNED, 348 ENTRY_BCN_ASSIGNED,
346 ENTRY_OWNER_DEVICE_DATA, 349 ENTRY_OWNER_DEVICE_DATA,
347 ENTRY_DATA_PENDING, 350 ENTRY_DATA_PENDING,
348 ENTRY_DATA_IO_FAILED 351 ENTRY_DATA_IO_FAILED,
352 ENTRY_DATA_STATUS_PENDING,
349}; 353};
350 354
351/** 355/**
@@ -392,12 +396,32 @@ enum queue_index {
392}; 396};
393 397
394/** 398/**
399 * enum data_queue_flags: Status flags for data queues
400 *
401 * @QUEUE_STARTED: The queue has been started. Fox RX queues this means the
402 * device might be DMA'ing skbuffers. TX queues will accept skbuffers to
403 * be transmitted and beacon queues will start beaconing the configured
404 * beacons.
405 * @QUEUE_PAUSED: The queue has been started but is currently paused.
406 * When this bit is set, the queue has been stopped in mac80211,
407 * preventing new frames to be enqueued. However, a few frames
408 * might still appear shortly after the pausing...
409 */
410enum data_queue_flags {
411 QUEUE_STARTED,
412 QUEUE_PAUSED,
413};
414
415/**
395 * struct data_queue: Data queue 416 * struct data_queue: Data queue
396 * 417 *
397 * @rt2x00dev: Pointer to main &struct rt2x00dev where this queue belongs to. 418 * @rt2x00dev: Pointer to main &struct rt2x00dev where this queue belongs to.
398 * @entries: Base address of the &struct queue_entry which are 419 * @entries: Base address of the &struct queue_entry which are
399 * part of this queue. 420 * part of this queue.
400 * @qid: The queue identification, see &enum data_queue_qid. 421 * @qid: The queue identification, see &enum data_queue_qid.
422 * @flags: Entry flags, see &enum queue_entry_flags.
423 * @status_lock: The mutex for protecting the start/stop/flush
424 * handling on this queue.
401 * @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or 425 * @index_lock: Spinlock to protect index handling. Whenever @index, @index_done or
402 * @index_crypt needs to be changed this lock should be grabbed to prevent 426 * @index_crypt needs to be changed this lock should be grabbed to prevent
403 * index corruption due to concurrency. 427 * index corruption due to concurrency.
@@ -421,8 +445,11 @@ struct data_queue {
421 struct queue_entry *entries; 445 struct queue_entry *entries;
422 446
423 enum data_queue_qid qid; 447 enum data_queue_qid qid;
448 unsigned long flags;
424 449
450 struct mutex status_lock;
425 spinlock_t index_lock; 451 spinlock_t index_lock;
452
426 unsigned int count; 453 unsigned int count;
427 unsigned short limit; 454 unsigned short limit;
428 unsigned short threshold; 455 unsigned short threshold;
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index ed71be95136d..e8259ae48ced 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -83,8 +83,6 @@ enum dev_state {
83 */ 83 */
84 STATE_RADIO_ON, 84 STATE_RADIO_ON,
85 STATE_RADIO_OFF, 85 STATE_RADIO_OFF,
86 STATE_RADIO_RX_ON,
87 STATE_RADIO_RX_OFF,
88 STATE_RADIO_IRQ_ON, 86 STATE_RADIO_IRQ_ON,
89 STATE_RADIO_IRQ_OFF, 87 STATE_RADIO_IRQ_OFF,
90 STATE_RADIO_IRQ_ON_ISR, 88 STATE_RADIO_IRQ_ON_ISR,
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 9ac14598e2a0..1a9937d5aff6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -195,7 +195,8 @@ static void rt2x00usb_work_txdone(struct work_struct *work)
195 while (!rt2x00queue_empty(queue)) { 195 while (!rt2x00queue_empty(queue)) {
196 entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); 196 entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
197 197
198 if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) 198 if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
199 !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
199 break; 200 break;
200 201
201 rt2x00usb_work_txdone_entry(entry); 202 rt2x00usb_work_txdone_entry(entry);
@@ -235,8 +236,10 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
235 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); 236 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
236 struct queue_entry_priv_usb *entry_priv = entry->priv_data; 237 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
237 u32 length; 238 u32 length;
239 int status;
238 240
239 if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) 241 if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) ||
242 test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
240 return; 243 return;
241 244
242 /* 245 /*
@@ -251,106 +254,15 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
251 entry->skb->data, length, 254 entry->skb->data, length,
252 rt2x00usb_interrupt_txdone, entry); 255 rt2x00usb_interrupt_txdone, entry);
253 256
254 if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) { 257 status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
258 if (status) {
259 if (status == -ENODEV)
260 clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
255 set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); 261 set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
256 rt2x00lib_dmadone(entry); 262 rt2x00lib_dmadone(entry);
257 } 263 }
258} 264}
259 265
260void rt2x00usb_kick_tx_queue(struct data_queue *queue)
261{
262 rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
263 rt2x00usb_kick_tx_entry);
264}
265EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
266
267static void rt2x00usb_kill_tx_entry(struct queue_entry *entry)
268{
269 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
270 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
271 struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
272
273 if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
274 return;
275
276 usb_kill_urb(entry_priv->urb);
277
278 /*
279 * Kill guardian urb (if required by driver).
280 */
281 if ((entry->queue->qid == QID_BEACON) &&
282 (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
283 usb_kill_urb(bcn_priv->guardian_urb);
284}
285
286void rt2x00usb_kill_tx_queue(struct data_queue *queue)
287{
288 rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
289 rt2x00usb_kill_tx_entry);
290}
291EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue);
292
293static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
294{
295 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
296 unsigned short threshold = queue->threshold;
297
298 WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
299 " invoke forced forced reset", queue->qid);
300
301 /*
302 * Temporarily disable the TX queue, this will force mac80211
303 * to use the other queues until this queue has been restored.
304 *
305 * Set the queue threshold to the queue limit. This prevents the
306 * queue from being enabled during the txdone handler.
307 */
308 queue->threshold = queue->limit;
309 ieee80211_stop_queue(rt2x00dev->hw, queue->qid);
310
311 /*
312 * Kill all entries in the queue, afterwards we need to
313 * wait a bit for all URBs to be cancelled.
314 */
315 rt2x00usb_kill_tx_queue(queue);
316
317 /*
318 * In case that a driver has overriden the txdone_work
319 * function, we invoke the TX done through there.
320 */
321 rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work);
322
323 /*
324 * The queue has been reset, and mac80211 is allowed to use the
325 * queue again.
326 */
327 queue->threshold = threshold;
328 ieee80211_wake_queue(rt2x00dev->hw, queue->qid);
329}
330
331static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
332{
333 WARNING(queue->rt2x00dev, "TX queue %d status timed out,"
334 " invoke forced tx handler", queue->qid);
335
336 ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work);
337}
338
339void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
340{
341 struct data_queue *queue;
342
343 tx_queue_for_each(rt2x00dev, queue) {
344 if (!rt2x00queue_empty(queue)) {
345 if (rt2x00queue_dma_timeout(queue))
346 rt2x00usb_watchdog_tx_dma(queue);
347 if (rt2x00queue_status_timeout(queue))
348 rt2x00usb_watchdog_tx_status(queue);
349 }
350 }
351}
352EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
353
354/* 266/*
355 * RX data handlers. 267 * RX data handlers.
356 */ 268 */
@@ -365,7 +277,8 @@ static void rt2x00usb_work_rxdone(struct work_struct *work)
365 while (!rt2x00queue_empty(rt2x00dev->rx)) { 277 while (!rt2x00queue_empty(rt2x00dev->rx)) {
366 entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE); 278 entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE);
367 279
368 if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) 280 if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
281 !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
369 break; 282 break;
370 283
371 /* 284 /*
@@ -410,6 +323,154 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
410 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); 323 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work);
411} 324}
412 325
326static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
327{
328 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
329 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
330 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
331 int status;
332
333 if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
334 test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
335 return;
336
337 rt2x00lib_dmastart(entry);
338
339 usb_fill_bulk_urb(entry_priv->urb, usb_dev,
340 usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint),
341 entry->skb->data, entry->skb->len,
342 rt2x00usb_interrupt_rxdone, entry);
343
344 status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
345 if (status) {
346 if (status == -ENODEV)
347 clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
348 set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
349 rt2x00lib_dmadone(entry);
350 }
351}
352
353void rt2x00usb_kick_queue(struct data_queue *queue)
354{
355 switch (queue->qid) {
356 case QID_AC_VO:
357 case QID_AC_VI:
358 case QID_AC_BE:
359 case QID_AC_BK:
360 if (!rt2x00queue_empty(queue))
361 rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
362 rt2x00usb_kick_tx_entry);
363 break;
364 case QID_RX:
365 if (!rt2x00queue_full(queue))
366 rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
367 rt2x00usb_kick_rx_entry);
368 break;
369 default:
370 break;
371 }
372}
373EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue);
374
375static void rt2x00usb_flush_entry(struct queue_entry *entry)
376{
377 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
378 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
379 struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
380
381 if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
382 return;
383
384 usb_kill_urb(entry_priv->urb);
385
386 /*
387 * Kill guardian urb (if required by driver).
388 */
389 if ((entry->queue->qid == QID_BEACON) &&
390 (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
391 usb_kill_urb(bcn_priv->guardian_urb);
392}
393
394void rt2x00usb_flush_queue(struct data_queue *queue)
395{
396 struct work_struct *completion;
397 unsigned int i;
398
399 rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
400 rt2x00usb_flush_entry);
401
402 /*
403 * Obtain the queue completion handler
404 */
405 switch (queue->qid) {
406 case QID_AC_VO:
407 case QID_AC_VI:
408 case QID_AC_BE:
409 case QID_AC_BK:
410 completion = &queue->rt2x00dev->txdone_work;
411 break;
412 case QID_RX:
413 completion = &queue->rt2x00dev->rxdone_work;
414 break;
415 default:
416 return;
417 }
418
419 for (i = 0; i < 20; i++) {
420 /*
421 * Check if the driver is already done, otherwise we
422 * have to sleep a little while to give the driver/hw
423 * the oppurtunity to complete interrupt process itself.
424 */
425 if (rt2x00queue_empty(queue))
426 break;
427
428 /*
429 * Schedule the completion handler manually, when this
430 * worker function runs, it should cleanup the queue.
431 */
432 ieee80211_queue_work(queue->rt2x00dev->hw, completion);
433
434 /*
435 * Wait for a little while to give the driver
436 * the oppurtunity to recover itself.
437 */
438 msleep(10);
439 }
440}
441EXPORT_SYMBOL_GPL(rt2x00usb_flush_queue);
442
443static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue)
444{
445 WARNING(queue->rt2x00dev, "TX queue %d DMA timed out,"
446 " invoke forced forced reset\n", queue->qid);
447
448 rt2x00queue_flush_queue(queue, true);
449}
450
451static void rt2x00usb_watchdog_tx_status(struct data_queue *queue)
452{
453 WARNING(queue->rt2x00dev, "TX queue %d status timed out,"
454 " invoke forced tx handler\n", queue->qid);
455
456 ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work);
457}
458
459void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
460{
461 struct data_queue *queue;
462
463 tx_queue_for_each(rt2x00dev, queue) {
464 if (!rt2x00queue_empty(queue)) {
465 if (rt2x00queue_dma_timeout(queue))
466 rt2x00usb_watchdog_tx_dma(queue);
467 if (rt2x00queue_status_timeout(queue))
468 rt2x00usb_watchdog_tx_status(queue);
469 }
470 }
471}
472EXPORT_SYMBOL_GPL(rt2x00usb_watchdog);
473
413/* 474/*
414 * Radio handlers 475 * Radio handlers
415 */ 476 */
@@ -417,12 +478,6 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
417{ 478{
418 rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0, 479 rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0,
419 REGISTER_TIMEOUT); 480 REGISTER_TIMEOUT);
420
421 /*
422 * The USB version of kill_tx_queue also works
423 * on the RX queue.
424 */
425 rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev->rx);
426} 481}
427EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); 482EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
428 483
@@ -431,25 +486,10 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
431 */ 486 */
432void rt2x00usb_clear_entry(struct queue_entry *entry) 487void rt2x00usb_clear_entry(struct queue_entry *entry)
433{ 488{
434 struct usb_device *usb_dev =
435 to_usb_device_intf(entry->queue->rt2x00dev->dev);
436 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
437 int pipe;
438
439 entry->flags = 0; 489 entry->flags = 0;
440 490
441 if (entry->queue->qid == QID_RX) { 491 if (entry->queue->qid == QID_RX)
442 pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint); 492 rt2x00usb_kick_rx_entry(entry);
443 usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe,
444 entry->skb->data, entry->skb->len,
445 rt2x00usb_interrupt_rxdone, entry);
446
447 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
448 if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) {
449 set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
450 rt2x00lib_dmadone(entry);
451 }
452 }
453} 493}
454EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); 494EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
455 495
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index c2d997f67b3e..6aaf51fc7ad8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -378,22 +378,22 @@ struct queue_entry_priv_usb_bcn {
378}; 378};
379 379
380/** 380/**
381 * rt2x00usb_kick_tx_queue - Kick data queue 381 * rt2x00usb_kick_queue - Kick data queue
382 * @queue: Data queue to kick 382 * @queue: Data queue to kick
383 * 383 *
384 * This will walk through all entries of the queue and push all pending 384 * This will walk through all entries of the queue and push all pending
385 * frames to the hardware as a single burst. 385 * frames to the hardware as a single burst.
386 */ 386 */
387void rt2x00usb_kick_tx_queue(struct data_queue *queue); 387void rt2x00usb_kick_queue(struct data_queue *queue);
388 388
389/** 389/**
390 * rt2x00usb_kill_tx_queue - Kill data queue 390 * rt2x00usb_flush_queue - Flush data queue
391 * @queue: Data queue to kill 391 * @queue: Data queue to stop
392 * 392 *
393 * This will walk through all entries of the queue and kill all 393 * This will walk through all entries of the queue and kill all
394 * previously kicked frames before they can be send. 394 * URB's which were send to the device.
395 */ 395 */
396void rt2x00usb_kill_tx_queue(struct data_queue *queue); 396void rt2x00usb_flush_queue(struct data_queue *queue);
397 397
398/** 398/**
399 * rt2x00usb_watchdog - Watchdog for USB communication 399 * rt2x00usb_watchdog - Watchdog for USB communication
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 6b09b01f634f..8de44dd401e0 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1140,6 +1140,106 @@ dynamic_cca_tune:
1140} 1140}
1141 1141
1142/* 1142/*
1143 * Queue handlers.
1144 */
1145static void rt61pci_start_queue(struct data_queue *queue)
1146{
1147 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
1148 u32 reg;
1149
1150 switch (queue->qid) {
1151 case QID_RX:
1152 rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
1153 rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX, 0);
1154 rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
1155 break;
1156 case QID_BEACON:
1157 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
1158 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
1159 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
1160 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
1161 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
1162 break;
1163 default:
1164 break;
1165 }
1166}
1167
1168static void rt61pci_kick_queue(struct data_queue *queue)
1169{
1170 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
1171 u32 reg;
1172
1173 switch (queue->qid) {
1174 case QID_AC_VO:
1175 rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
1176 rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, 1);
1177 rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
1178 break;
1179 case QID_AC_VI:
1180 rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
1181 rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, 1);
1182 rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
1183 break;
1184 case QID_AC_BE:
1185 rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
1186 rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2, 1);
1187 rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
1188 break;
1189 case QID_AC_BK:
1190 rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
1191 rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3, 1);
1192 rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
1193 break;
1194 default:
1195 break;
1196 }
1197}
1198
1199static void rt61pci_stop_queue(struct data_queue *queue)
1200{
1201 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
1202 u32 reg;
1203
1204 switch (queue->qid) {
1205 case QID_AC_VO:
1206 rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
1207 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, 1);
1208 rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
1209 break;
1210 case QID_AC_VI:
1211 rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
1212 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, 1);
1213 rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
1214 break;
1215 case QID_AC_BE:
1216 rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
1217 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, 1);
1218 rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
1219 break;
1220 case QID_AC_BK:
1221 rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
1222 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, 1);
1223 rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
1224 break;
1225 case QID_RX:
1226 rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
1227 rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX, 1);
1228 rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
1229 break;
1230 case QID_BEACON:
1231 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
1232 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
1233 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
1234 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
1235 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
1236 break;
1237 default:
1238 break;
1239 }
1240}
1241
1242/*
1143 * Firmware functions 1243 * Firmware functions
1144 */ 1244 */
1145static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) 1245static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
@@ -1616,17 +1716,6 @@ static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev)
1616/* 1716/*
1617 * Device state switch handlers. 1717 * Device state switch handlers.
1618 */ 1718 */
1619static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
1620 enum dev_state state)
1621{
1622 u32 reg;
1623
1624 rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
1625 rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX,
1626 (state == STATE_RADIO_RX_OFF));
1627 rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
1628}
1629
1630static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, 1719static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
1631 enum dev_state state) 1720 enum dev_state state)
1632{ 1721{
@@ -1743,10 +1832,6 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
1743 case STATE_RADIO_OFF: 1832 case STATE_RADIO_OFF:
1744 rt61pci_disable_radio(rt2x00dev); 1833 rt61pci_disable_radio(rt2x00dev);
1745 break; 1834 break;
1746 case STATE_RADIO_RX_ON:
1747 case STATE_RADIO_RX_OFF:
1748 rt61pci_toggle_rx(rt2x00dev, state);
1749 break;
1750 case STATE_RADIO_IRQ_ON: 1835 case STATE_RADIO_IRQ_ON:
1751 case STATE_RADIO_IRQ_ON_ISR: 1836 case STATE_RADIO_IRQ_ON_ISR:
1752 case STATE_RADIO_IRQ_OFF: 1837 case STATE_RADIO_IRQ_OFF:
@@ -1876,6 +1961,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
1876 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 1961 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1877 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 1962 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
1878 unsigned int beacon_base; 1963 unsigned int beacon_base;
1964 unsigned int padding_len;
1879 u32 reg; 1965 u32 reg;
1880 1966
1881 /* 1967 /*
@@ -1897,13 +1983,16 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
1897 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); 1983 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
1898 1984
1899 /* 1985 /*
1900 * Write entire beacon with descriptor to register. 1986 * Write entire beacon with descriptor and padding to register.
1901 */ 1987 */
1988 padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
1989 skb_pad(entry->skb, padding_len);
1902 beacon_base = HW_BEACON_OFFSET(entry->entry_idx); 1990 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
1903 rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, 1991 rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
1904 entry_priv->desc, TXINFO_SIZE); 1992 entry_priv->desc, TXINFO_SIZE);
1905 rt2x00pci_register_multiwrite(rt2x00dev, beacon_base + TXINFO_SIZE, 1993 rt2x00pci_register_multiwrite(rt2x00dev, beacon_base + TXINFO_SIZE,
1906 entry->skb->data, entry->skb->len); 1994 entry->skb->data,
1995 entry->skb->len + padding_len);
1907 1996
1908 /* 1997 /*
1909 * Enable beaconing again. 1998 * Enable beaconing again.
@@ -1925,37 +2014,6 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
1925 entry->skb = NULL; 2014 entry->skb = NULL;
1926} 2015}
1927 2016
1928static void rt61pci_kick_tx_queue(struct data_queue *queue)
1929{
1930 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
1931 u32 reg;
1932
1933 rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
1934 rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, (queue->qid == QID_AC_BE));
1935 rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, (queue->qid == QID_AC_BK));
1936 rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2, (queue->qid == QID_AC_VI));
1937 rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3, (queue->qid == QID_AC_VO));
1938 rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
1939}
1940
1941static void rt61pci_kill_tx_queue(struct data_queue *queue)
1942{
1943 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
1944 u32 reg;
1945
1946 if (queue->qid == QID_BEACON) {
1947 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
1948 return;
1949 }
1950
1951 rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
1952 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, (queue->qid == QID_AC_BE));
1953 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, (queue->qid == QID_AC_BK));
1954 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, (queue->qid == QID_AC_VI));
1955 rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, (queue->qid == QID_AC_VO));
1956 rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
1957}
1958
1959/* 2017/*
1960 * RX control handlers 2018 * RX control handlers
1961 */ 2019 */
@@ -2840,10 +2898,11 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
2840 .link_stats = rt61pci_link_stats, 2898 .link_stats = rt61pci_link_stats,
2841 .reset_tuner = rt61pci_reset_tuner, 2899 .reset_tuner = rt61pci_reset_tuner,
2842 .link_tuner = rt61pci_link_tuner, 2900 .link_tuner = rt61pci_link_tuner,
2901 .start_queue = rt61pci_start_queue,
2902 .kick_queue = rt61pci_kick_queue,
2903 .stop_queue = rt61pci_stop_queue,
2843 .write_tx_desc = rt61pci_write_tx_desc, 2904 .write_tx_desc = rt61pci_write_tx_desc,
2844 .write_beacon = rt61pci_write_beacon, 2905 .write_beacon = rt61pci_write_beacon,
2845 .kick_tx_queue = rt61pci_kick_tx_queue,
2846 .kill_tx_queue = rt61pci_kill_tx_queue,
2847 .fill_rxdone = rt61pci_fill_rxdone, 2906 .fill_rxdone = rt61pci_fill_rxdone,
2848 .config_shared_key = rt61pci_config_shared_key, 2907 .config_shared_key = rt61pci_config_shared_key,
2849 .config_pairwise_key = rt61pci_config_pairwise_key, 2908 .config_pairwise_key = rt61pci_config_pairwise_key,
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index afc803b7959f..e3cd6db76b0e 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -784,25 +784,25 @@ struct hw_pairwise_ta_entry {
784 */ 784 */
785 785
786/* 786/*
787 * AC0_BASE_CSR: AC_BK base address. 787 * AC0_BASE_CSR: AC_VO base address.
788 */ 788 */
789#define AC0_BASE_CSR 0x3400 789#define AC0_BASE_CSR 0x3400
790#define AC0_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) 790#define AC0_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
791 791
792/* 792/*
793 * AC1_BASE_CSR: AC_BE base address. 793 * AC1_BASE_CSR: AC_VI base address.
794 */ 794 */
795#define AC1_BASE_CSR 0x3404 795#define AC1_BASE_CSR 0x3404
796#define AC1_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) 796#define AC1_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
797 797
798/* 798/*
799 * AC2_BASE_CSR: AC_VI base address. 799 * AC2_BASE_CSR: AC_BE base address.
800 */ 800 */
801#define AC2_BASE_CSR 0x3408 801#define AC2_BASE_CSR 0x3408
802#define AC2_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) 802#define AC2_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
803 803
804/* 804/*
805 * AC3_BASE_CSR: AC_VO base address. 805 * AC3_BASE_CSR: AC_BK base address.
806 */ 806 */
807#define AC3_BASE_CSR 0x340c 807#define AC3_BASE_CSR 0x340c
808#define AC3_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) 808#define AC3_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
@@ -814,7 +814,7 @@ struct hw_pairwise_ta_entry {
814#define MGMT_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) 814#define MGMT_BASE_CSR_RING_REGISTER FIELD32(0xffffffff)
815 815
816/* 816/*
817 * TX_RING_CSR0: TX Ring size for AC_BK, AC_BE, AC_VI, AC_VO. 817 * TX_RING_CSR0: TX Ring size for AC_VO, AC_VI, AC_BE, AC_BK.
818 */ 818 */
819#define TX_RING_CSR0 0x3418 819#define TX_RING_CSR0 0x3418
820#define TX_RING_CSR0_AC0_RING_SIZE FIELD32(0x000000ff) 820#define TX_RING_CSR0_AC0_RING_SIZE FIELD32(0x000000ff)
@@ -833,10 +833,10 @@ struct hw_pairwise_ta_entry {
833 833
834/* 834/*
835 * AIFSN_CSR: AIFSN for each EDCA AC. 835 * AIFSN_CSR: AIFSN for each EDCA AC.
836 * AIFSN0: For AC_BK. 836 * AIFSN0: For AC_VO.
837 * AIFSN1: For AC_BE. 837 * AIFSN1: For AC_VI.
838 * AIFSN2: For AC_VI. 838 * AIFSN2: For AC_BE.
839 * AIFSN3: For AC_VO. 839 * AIFSN3: For AC_BK.
840 */ 840 */
841#define AIFSN_CSR 0x3420 841#define AIFSN_CSR 0x3420
842#define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f) 842#define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f)
@@ -846,10 +846,10 @@ struct hw_pairwise_ta_entry {
846 846
847/* 847/*
848 * CWMIN_CSR: CWmin for each EDCA AC. 848 * CWMIN_CSR: CWmin for each EDCA AC.
849 * CWMIN0: For AC_BK. 849 * CWMIN0: For AC_VO.
850 * CWMIN1: For AC_BE. 850 * CWMIN1: For AC_VI.
851 * CWMIN2: For AC_VI. 851 * CWMIN2: For AC_BE.
852 * CWMIN3: For AC_VO. 852 * CWMIN3: For AC_BK.
853 */ 853 */
854#define CWMIN_CSR 0x3424 854#define CWMIN_CSR 0x3424
855#define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f) 855#define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f)
@@ -859,10 +859,10 @@ struct hw_pairwise_ta_entry {
859 859
860/* 860/*
861 * CWMAX_CSR: CWmax for each EDCA AC. 861 * CWMAX_CSR: CWmax for each EDCA AC.
862 * CWMAX0: For AC_BK. 862 * CWMAX0: For AC_VO.
863 * CWMAX1: For AC_BE. 863 * CWMAX1: For AC_VI.
864 * CWMAX2: For AC_VI. 864 * CWMAX2: For AC_BE.
865 * CWMAX3: For AC_VO. 865 * CWMAX3: For AC_BK.
866 */ 866 */
867#define CWMAX_CSR 0x3428 867#define CWMAX_CSR 0x3428
868#define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f) 868#define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f)
@@ -883,14 +883,14 @@ struct hw_pairwise_ta_entry {
883 883
884/* 884/*
885 * TX_CNTL_CSR: KICK/Abort TX. 885 * TX_CNTL_CSR: KICK/Abort TX.
886 * KICK_TX_AC0: For AC_BK. 886 * KICK_TX_AC0: For AC_VO.
887 * KICK_TX_AC1: For AC_BE. 887 * KICK_TX_AC1: For AC_VI.
888 * KICK_TX_AC2: For AC_VI. 888 * KICK_TX_AC2: For AC_BE.
889 * KICK_TX_AC3: For AC_VO. 889 * KICK_TX_AC3: For AC_BK.
890 * ABORT_TX_AC0: For AC_BK. 890 * ABORT_TX_AC0: For AC_VO.
891 * ABORT_TX_AC1: For AC_BE. 891 * ABORT_TX_AC1: For AC_VI.
892 * ABORT_TX_AC2: For AC_VI. 892 * ABORT_TX_AC2: For AC_BE.
893 * ABORT_TX_AC3: For AC_VO. 893 * ABORT_TX_AC3: For AC_BK.
894 */ 894 */
895#define TX_CNTL_CSR 0x3430 895#define TX_CNTL_CSR 0x3430
896#define TX_CNTL_CSR_KICK_TX_AC0 FIELD32(0x00000001) 896#define TX_CNTL_CSR_KICK_TX_AC0 FIELD32(0x00000001)
@@ -1010,18 +1010,18 @@ struct hw_pairwise_ta_entry {
1010#define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040) 1010#define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040)
1011 1011
1012/* 1012/*
1013 * AC_TXOP_CSR0: AC_BK/AC_BE TXOP register. 1013 * AC_TXOP_CSR0: AC_VO/AC_VI TXOP register.
1014 * AC0_TX_OP: For AC_BK, in unit of 32us. 1014 * AC0_TX_OP: For AC_VO, in unit of 32us.
1015 * AC1_TX_OP: For AC_BE, in unit of 32us. 1015 * AC1_TX_OP: For AC_VI, in unit of 32us.
1016 */ 1016 */
1017#define AC_TXOP_CSR0 0x3474 1017#define AC_TXOP_CSR0 0x3474
1018#define AC_TXOP_CSR0_AC0_TX_OP FIELD32(0x0000ffff) 1018#define AC_TXOP_CSR0_AC0_TX_OP FIELD32(0x0000ffff)
1019#define AC_TXOP_CSR0_AC1_TX_OP FIELD32(0xffff0000) 1019#define AC_TXOP_CSR0_AC1_TX_OP FIELD32(0xffff0000)
1020 1020
1021/* 1021/*
1022 * AC_TXOP_CSR1: AC_VO/AC_VI TXOP register. 1022 * AC_TXOP_CSR1: AC_BE/AC_BK TXOP register.
1023 * AC2_TX_OP: For AC_VI, in unit of 32us. 1023 * AC2_TX_OP: For AC_BE, in unit of 32us.
1024 * AC3_TX_OP: For AC_VO, in unit of 32us. 1024 * AC3_TX_OP: For AC_BK, in unit of 32us.
1025 */ 1025 */
1026#define AC_TXOP_CSR1 0x3478 1026#define AC_TXOP_CSR1 0x3478
1027#define AC_TXOP_CSR1_AC2_TX_OP FIELD32(0x0000ffff) 1027#define AC_TXOP_CSR1_AC2_TX_OP FIELD32(0x0000ffff)
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 6f04552f5819..0b4e8590cbb7 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1031,6 +1031,55 @@ dynamic_cca_tune:
1031} 1031}
1032 1032
1033/* 1033/*
1034 * Queue handlers.
1035 */
1036static void rt73usb_start_queue(struct data_queue *queue)
1037{
1038 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
1039 u32 reg;
1040
1041 switch (queue->qid) {
1042 case QID_RX:
1043 rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
1044 rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX, 0);
1045 rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
1046 break;
1047 case QID_BEACON:
1048 rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
1049 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
1050 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
1051 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
1052 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
1053 break;
1054 default:
1055 break;
1056 }
1057}
1058
1059static void rt73usb_stop_queue(struct data_queue *queue)
1060{
1061 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
1062 u32 reg;
1063
1064 switch (queue->qid) {
1065 case QID_RX:
1066 rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
1067 rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX, 1);
1068 rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
1069 break;
1070 case QID_BEACON:
1071 rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
1072 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
1073 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
1074 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
1075 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
1076 break;
1077 default:
1078 break;
1079 }
1080}
1081
1082/*
1034 * Firmware functions 1083 * Firmware functions
1035 */ 1084 */
1036static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) 1085static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
@@ -1324,17 +1373,6 @@ static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev)
1324/* 1373/*
1325 * Device state switch handlers. 1374 * Device state switch handlers.
1326 */ 1375 */
1327static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
1328 enum dev_state state)
1329{
1330 u32 reg;
1331
1332 rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
1333 rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX,
1334 (state == STATE_RADIO_RX_OFF));
1335 rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
1336}
1337
1338static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev) 1376static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev)
1339{ 1377{
1340 /* 1378 /*
@@ -1401,10 +1439,6 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
1401 case STATE_RADIO_OFF: 1439 case STATE_RADIO_OFF:
1402 rt73usb_disable_radio(rt2x00dev); 1440 rt73usb_disable_radio(rt2x00dev);
1403 break; 1441 break;
1404 case STATE_RADIO_RX_ON:
1405 case STATE_RADIO_RX_OFF:
1406 rt73usb_toggle_rx(rt2x00dev, state);
1407 break;
1408 case STATE_RADIO_IRQ_ON: 1442 case STATE_RADIO_IRQ_ON:
1409 case STATE_RADIO_IRQ_ON_ISR: 1443 case STATE_RADIO_IRQ_ON_ISR:
1410 case STATE_RADIO_IRQ_OFF: 1444 case STATE_RADIO_IRQ_OFF:
@@ -1512,6 +1546,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
1512{ 1546{
1513 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 1547 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1514 unsigned int beacon_base; 1548 unsigned int beacon_base;
1549 unsigned int padding_len;
1515 u32 reg; 1550 u32 reg;
1516 1551
1517 /* 1552 /*
@@ -1539,11 +1574,13 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
1539 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); 1574 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
1540 1575
1541 /* 1576 /*
1542 * Write entire beacon with descriptor to register. 1577 * Write entire beacon with descriptor and padding to register.
1543 */ 1578 */
1579 padding_len = roundup(entry->skb->len, 4) - entry->skb->len;
1580 skb_pad(entry->skb, padding_len);
1544 beacon_base = HW_BEACON_OFFSET(entry->entry_idx); 1581 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
1545 rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, 1582 rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
1546 entry->skb->data, entry->skb->len); 1583 entry->skb->len + padding_len);
1547 1584
1548 /* 1585 /*
1549 * Enable beaconing again. 1586 * Enable beaconing again.
@@ -1579,14 +1616,6 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry)
1579 return length; 1616 return length;
1580} 1617}
1581 1618
1582static void rt73usb_kill_tx_queue(struct data_queue *queue)
1583{
1584 if (queue->qid == QID_BEACON)
1585 rt2x00usb_register_write(queue->rt2x00dev, TXRX_CSR9, 0);
1586
1587 rt2x00usb_kill_tx_queue(queue);
1588}
1589
1590/* 1619/*
1591 * RX control handlers 1620 * RX control handlers
1592 */ 1621 */
@@ -2278,11 +2307,13 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
2278 .reset_tuner = rt73usb_reset_tuner, 2307 .reset_tuner = rt73usb_reset_tuner,
2279 .link_tuner = rt73usb_link_tuner, 2308 .link_tuner = rt73usb_link_tuner,
2280 .watchdog = rt2x00usb_watchdog, 2309 .watchdog = rt2x00usb_watchdog,
2310 .start_queue = rt73usb_start_queue,
2311 .kick_queue = rt2x00usb_kick_queue,
2312 .stop_queue = rt73usb_stop_queue,
2313 .flush_queue = rt2x00usb_flush_queue,
2281 .write_tx_desc = rt73usb_write_tx_desc, 2314 .write_tx_desc = rt73usb_write_tx_desc,
2282 .write_beacon = rt73usb_write_beacon, 2315 .write_beacon = rt73usb_write_beacon,
2283 .get_tx_data_len = rt73usb_get_tx_data_len, 2316 .get_tx_data_len = rt73usb_get_tx_data_len,
2284 .kick_tx_queue = rt2x00usb_kick_tx_queue,
2285 .kill_tx_queue = rt73usb_kill_tx_queue,
2286 .fill_rxdone = rt73usb_fill_rxdone, 2317 .fill_rxdone = rt73usb_fill_rxdone,
2287 .config_shared_key = rt73usb_config_shared_key, 2318 .config_shared_key = rt73usb_config_shared_key,
2288 .config_pairwise_key = rt73usb_config_pairwise_key, 2319 .config_pairwise_key = rt73usb_config_pairwise_key,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 1315ce5c992f..9f6b470414d3 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -689,10 +689,10 @@ struct hw_pairwise_ta_entry {
689 689
690/* 690/*
691 * AIFSN_CSR: AIFSN for each EDCA AC. 691 * AIFSN_CSR: AIFSN for each EDCA AC.
692 * AIFSN0: For AC_BK. 692 * AIFSN0: For AC_VO.
693 * AIFSN1: For AC_BE. 693 * AIFSN1: For AC_VI.
694 * AIFSN2: For AC_VI. 694 * AIFSN2: For AC_BE.
695 * AIFSN3: For AC_VO. 695 * AIFSN3: For AC_BK.
696 */ 696 */
697#define AIFSN_CSR 0x0400 697#define AIFSN_CSR 0x0400
698#define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f) 698#define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f)
@@ -702,10 +702,10 @@ struct hw_pairwise_ta_entry {
702 702
703/* 703/*
704 * CWMIN_CSR: CWmin for each EDCA AC. 704 * CWMIN_CSR: CWmin for each EDCA AC.
705 * CWMIN0: For AC_BK. 705 * CWMIN0: For AC_VO.
706 * CWMIN1: For AC_BE. 706 * CWMIN1: For AC_VI.
707 * CWMIN2: For AC_VI. 707 * CWMIN2: For AC_BE.
708 * CWMIN3: For AC_VO. 708 * CWMIN3: For AC_BK.
709 */ 709 */
710#define CWMIN_CSR 0x0404 710#define CWMIN_CSR 0x0404
711#define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f) 711#define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f)
@@ -715,10 +715,10 @@ struct hw_pairwise_ta_entry {
715 715
716/* 716/*
717 * CWMAX_CSR: CWmax for each EDCA AC. 717 * CWMAX_CSR: CWmax for each EDCA AC.
718 * CWMAX0: For AC_BK. 718 * CWMAX0: For AC_VO.
719 * CWMAX1: For AC_BE. 719 * CWMAX1: For AC_VI.
720 * CWMAX2: For AC_VI. 720 * CWMAX2: For AC_BE.
721 * CWMAX3: For AC_VO. 721 * CWMAX3: For AC_BK.
722 */ 722 */
723#define CWMAX_CSR 0x0408 723#define CWMAX_CSR 0x0408
724#define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f) 724#define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f)
@@ -727,18 +727,18 @@ struct hw_pairwise_ta_entry {
727#define CWMAX_CSR_CWMAX3 FIELD32(0x0000f000) 727#define CWMAX_CSR_CWMAX3 FIELD32(0x0000f000)
728 728
729/* 729/*
730 * AC_TXOP_CSR0: AC_BK/AC_BE TXOP register. 730 * AC_TXOP_CSR0: AC_VO/AC_VI TXOP register.
731 * AC0_TX_OP: For AC_BK, in unit of 32us. 731 * AC0_TX_OP: For AC_VO, in unit of 32us.
732 * AC1_TX_OP: For AC_BE, in unit of 32us. 732 * AC1_TX_OP: For AC_VI, in unit of 32us.
733 */ 733 */
734#define AC_TXOP_CSR0 0x040c 734#define AC_TXOP_CSR0 0x040c
735#define AC_TXOP_CSR0_AC0_TX_OP FIELD32(0x0000ffff) 735#define AC_TXOP_CSR0_AC0_TX_OP FIELD32(0x0000ffff)
736#define AC_TXOP_CSR0_AC1_TX_OP FIELD32(0xffff0000) 736#define AC_TXOP_CSR0_AC1_TX_OP FIELD32(0xffff0000)
737 737
738/* 738/*
739 * AC_TXOP_CSR1: AC_VO/AC_VI TXOP register. 739 * AC_TXOP_CSR1: AC_BE/AC_BK TXOP register.
740 * AC2_TX_OP: For AC_VI, in unit of 32us. 740 * AC2_TX_OP: For AC_BE, in unit of 32us.
741 * AC3_TX_OP: For AC_VO, in unit of 32us. 741 * AC3_TX_OP: For AC_BK, in unit of 32us.
742 */ 742 */
743#define AC_TXOP_CSR1 0x0410 743#define AC_TXOP_CSR1 0x0410
744#define AC_TXOP_CSR1_AC2_TX_OP FIELD32(0x0000ffff) 744#define AC_TXOP_CSR1_AC2_TX_OP FIELD32(0x0000ffff)
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig
new file mode 100644
index 000000000000..7f6573f7f470
--- /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 called rtl8192ce
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 000000000000..2a7a4384f8ee
--- /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 000000000000..f6cc07369d75
--- /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 = alloc_workqueue(rtlpriv->cfg->name, 0, 0);
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 mutex_init(&rtlpriv->locks.conf_mutex);
313 spin_lock_init(&rtlpriv->locks.ips_lock);
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 000000000000..3de5a14745f1
--- /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 000000000000..52c9c1367cac
--- /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 000000000000..dd82f057d53d
--- /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 000000000000..d6a924a05654
--- /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 mutex_lock(&rtlpriv->locks.conf_mutex);
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 mutex_unlock(&rtlpriv->locks.conf_mutex);
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 mutex_lock(&rtlpriv->locks.conf_mutex);
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 mutex_unlock(&rtlpriv->locks.conf_mutex);
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 mutex_lock(&rtlpriv->locks.conf_mutex);
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 mutex_unlock(&rtlpriv->locks.conf_mutex);
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 mutex_lock(&rtlpriv->locks.conf_mutex);
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 mutex_unlock(&rtlpriv->locks.conf_mutex);
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 mutex_lock(&rtlpriv->locks.conf_mutex);
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 mutex_unlock(&rtlpriv->locks.conf_mutex);
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 mutex_lock(&rtlpriv->locks.conf_mutex);
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 mutex_unlock(&rtlpriv->locks.conf_mutex);
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 mutex_lock(&rtlpriv->locks.conf_mutex);
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 mutex_unlock(&rtlpriv->locks.conf_mutex);
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 mutex_lock(&rtlpriv->locks.conf_mutex);
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 mutex_unlock(&rtlpriv->locks.conf_mutex);
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 000000000000..0ef31c3c6196
--- /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 000000000000..5fa73852cb66
--- /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 000000000000..08bdec2ceda4
--- /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 000000000000..b8433f3a9bc2
--- /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 000000000000..2d39a4df181b
--- /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 000000000000..bf3b5748ee19
--- /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 000000000000..d36a66939958
--- /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} __packed;
135
136struct rtl_tx_desc {
137 u32 dword[16];
138} __packed;
139
140struct rtl_tx_cmd_desc {
141 u32 dword[16];
142} __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 000000000000..d2326c13449e
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -0,0 +1,493 @@
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 unsigned long flags;
290
291 spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags);
292
293 if (ppsc->b_inactiveps) {
294 rtstate = ppsc->rfpwr_state;
295
296 if (rtstate != ERFON &&
297 !ppsc->b_swrf_processing &&
298 ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) {
299
300 ppsc->inactive_pwrstate = ERFON;
301 ppsc->b_in_powersavemode = false;
302
303 _rtl_ps_inactive_ps(hw);
304 }
305 }
306
307 spin_unlock_irqrestore(&rtlpriv->locks.ips_lock, flags);
308}
309
310/*for FW LPS*/
311
312/*
313 *Determine if we can set Fw into PS mode
314 *in current condition.Return TRUE if it
315 *can enter PS mode.
316 */
317static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw)
318{
319 struct rtl_priv *rtlpriv = rtl_priv(hw);
320 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
321 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
322 u32 ps_timediff;
323
324 ps_timediff = jiffies_to_msecs(jiffies -
325 ppsc->last_delaylps_stamp_jiffies);
326
327 if (ps_timediff < 2000) {
328 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
329 ("Delay enter Fw LPS for DHCP, ARP,"
330 " or EAPOL exchanging state.\n"));
331 return false;
332 }
333
334 if (mac->link_state != MAC80211_LINKED)
335 return false;
336
337 if (mac->opmode == NL80211_IFTYPE_ADHOC)
338 return false;
339
340 return true;
341}
342
343/* Change current and default preamble mode.*/
344static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
345{
346 struct rtl_priv *rtlpriv = rtl_priv(hw);
347 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
348 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
349 u8 rpwm_val, fw_pwrmode;
350
351 if (mac->opmode == NL80211_IFTYPE_ADHOC)
352 return;
353
354 if (mac->link_state != MAC80211_LINKED)
355 return;
356
357 if (ppsc->dot11_psmode == rt_psmode)
358 return;
359
360 /* Update power save mode configured. */
361 ppsc->dot11_psmode = rt_psmode;
362
363 /*
364 *<FW control LPS>
365 *1. Enter PS mode
366 * Set RPWM to Fw to turn RF off and send H2C fw_pwrmode
367 * cmd to set Fw into PS mode.
368 *2. Leave PS mode
369 * Send H2C fw_pwrmode cmd to Fw to set Fw into Active
370 * mode and set RPWM to turn RF on.
371 */
372
373 if ((ppsc->b_fwctrl_lps) && (ppsc->b_leisure_ps) &&
374 ppsc->report_linked) {
375 bool b_fw_current_inps;
376 if (ppsc->dot11_psmode == EACTIVE) {
377 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
378 ("FW LPS leave ps_mode:%x\n",
379 FW_PS_ACTIVE_MODE));
380
381 rpwm_val = 0x0C; /* RF on */
382 fw_pwrmode = FW_PS_ACTIVE_MODE;
383 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
384 (u8 *) (&rpwm_val));
385 rtlpriv->cfg->ops->set_hw_reg(hw,
386 HW_VAR_H2C_FW_PWRMODE,
387 (u8 *) (&fw_pwrmode));
388 b_fw_current_inps = false;
389
390 rtlpriv->cfg->ops->set_hw_reg(hw,
391 HW_VAR_FW_PSMODE_STATUS,
392 (u8 *) (&b_fw_current_inps));
393
394 } else {
395 if (rtl_get_fwlps_doze(hw)) {
396 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
397 ("FW LPS enter ps_mode:%x\n",
398 ppsc->fwctrl_psmode));
399
400 rpwm_val = 0x02; /* RF off */
401 b_fw_current_inps = true;
402 rtlpriv->cfg->ops->set_hw_reg(hw,
403 HW_VAR_FW_PSMODE_STATUS,
404 (u8 *) (&b_fw_current_inps));
405 rtlpriv->cfg->ops->set_hw_reg(hw,
406 HW_VAR_H2C_FW_PWRMODE,
407 (u8 *) (&ppsc->fwctrl_psmode));
408
409 rtlpriv->cfg->ops->set_hw_reg(hw,
410 HW_VAR_SET_RPWM,
411 (u8 *) (&rpwm_val));
412 } else {
413 /* Reset the power save related parameters. */
414 ppsc->dot11_psmode = EACTIVE;
415 }
416 }
417 }
418}
419
420/*Enter the leisure power save mode.*/
421void rtl_lps_enter(struct ieee80211_hw *hw)
422{
423 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
424 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
425 struct rtl_priv *rtlpriv = rtl_priv(hw);
426 unsigned long flag;
427
428 if (!(ppsc->b_fwctrl_lps && ppsc->b_leisure_ps))
429 return;
430
431 if (rtlpriv->sec.being_setkey)
432 return;
433
434 if (rtlpriv->link_info.b_busytraffic)
435 return;
436
437 /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
438 if (mac->cnt_after_linked < 5)
439 return;
440
441 if (mac->opmode == NL80211_IFTYPE_ADHOC)
442 return;
443
444 if (mac->link_state != MAC80211_LINKED)
445 return;
446
447 spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
448
449 if (ppsc->b_leisure_ps) {
450 /* Idle for a while if we connect to AP a while ago. */
451 if (mac->cnt_after_linked >= 2) {
452 if (ppsc->dot11_psmode == EACTIVE) {
453 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
454 ("Enter 802.11 power save mode...\n"));
455
456 rtl_lps_set_psmode(hw, EAUTOPS);
457 }
458 }
459 }
460 spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
461}
462
463/*Leave the leisure power save mode.*/
464void rtl_lps_leave(struct ieee80211_hw *hw)
465{
466 struct rtl_priv *rtlpriv = rtl_priv(hw);
467 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
468 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
469 unsigned long flag;
470
471 spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
472
473 if (ppsc->b_fwctrl_lps && ppsc->b_leisure_ps) {
474 if (ppsc->dot11_psmode != EACTIVE) {
475
476 /*FIX ME */
477 rtlpriv->cfg->ops->enable_interrupt(hw);
478
479 if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
480 RT_IN_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM) &&
481 rtlhal->interface == INTF_PCI) {
482 rtlpriv->intf_ops->disable_aspm(hw);
483 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM);
484 }
485
486 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
487 ("Busy Traffic,Leave 802.11 power save..\n"));
488
489 rtl_lps_set_psmode(hw, EACTIVE);
490 }
491 }
492 spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
493}
diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h
new file mode 100644
index 000000000000..ae56da801a23
--- /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 000000000000..91634107434a
--- /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, 5000);
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 000000000000..b4667c035f0b
--- /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 000000000000..3336ca999dfd
--- /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 000000000000..4cdbc4ae76d4
--- /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 000000000000..0f0be7c763b8
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile
@@ -0,0 +1,12 @@
1rtl8192ce-objs := \
2 dm.o \
3 fw.o \
4 hw.o \
5 led.o \
6 phy.o \
7 rf.o \
8 sw.o \
9 table.o \
10 trx.o
11
12obj-$(CONFIG_RTL8192CE) += rtl8192ce.o
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
new file mode 100644
index 000000000000..83cd64895292
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
new file mode 100644
index 000000000000..62e7c64e087b
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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 "reg.h"
33#include "def.h"
34#include "phy.h"
35#include "dm.h"
36#include "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/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
new file mode 100644
index 000000000000..463439e4074c
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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/fw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c
new file mode 100644
index 000000000000..11dd22b987e7
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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 "reg.h"
35#include "def.h"
36#include "fw.h"
37#include "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/fw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.h
new file mode 100644
index 000000000000..3db33bd14666
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
new file mode 100644
index 000000000000..1266dbe44176
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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 "reg.h"
37#include "def.h"
38#include "phy.h"
39#include "dm.h"
40#include "fw.h"
41#include "led.h"
42#include "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/hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
new file mode 100644
index 000000000000..305c819c8c78
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
new file mode 100644
index 000000000000..78a0569208ea
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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 "reg.h"
33#include "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/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
new file mode 100644
index 000000000000..10da3018f4b7
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
new file mode 100644
index 000000000000..45044117139a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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 "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "rf.h"
37#include "dm.h"
38#include "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/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
new file mode 100644
index 000000000000..ca4daee6e9a8
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
new file mode 100644
index 000000000000..875d51465225
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
new file mode 100644
index 000000000000..ffd8e04c4028
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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 "reg.h"
32#include "def.h"
33#include "phy.h"
34#include "rf.h"
35#include "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/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
new file mode 100644
index 000000000000..d3014f99bb7b
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
new file mode 100644
index 000000000000..b366e8862929
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -0,0 +1,282 @@
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/vmalloc.h>
31
32#include "../wifi.h"
33#include "../core.h"
34#include "../pci.h"
35#include "reg.h"
36#include "def.h"
37#include "phy.h"
38#include "dm.h"
39#include "hw.h"
40#include "sw.h"
41#include "trx.h"
42#include "led.h"
43
44int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
45{
46 struct rtl_priv *rtlpriv = rtl_priv(hw);
47 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
48
49 rtlpriv->dm.b_dm_initialgain_enable = 1;
50 rtlpriv->dm.dm_flag = 0;
51 rtlpriv->dm.b_disable_framebursting = 0;;
52 rtlpriv->dm.thermalvalue = 0;
53 rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
54
55 rtlpci->receive_config = (RCR_APPFCS |
56 RCR_AMF |
57 RCR_ADF |
58 RCR_APP_MIC |
59 RCR_APP_ICV |
60 RCR_AICV |
61 RCR_ACRC32 |
62 RCR_AB |
63 RCR_AM |
64 RCR_APM |
65 RCR_APP_PHYST_RXFF | RCR_HTC_LOC_CTRL | 0);
66
67 rtlpci->irq_mask[0] =
68 (u32) (IMR_ROK |
69 IMR_VODOK |
70 IMR_VIDOK |
71 IMR_BEDOK |
72 IMR_BKDOK |
73 IMR_MGNTDOK |
74 IMR_HIGHDOK | IMR_BDOK | IMR_RDU | IMR_RXFOVW | 0);
75
76 rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0);
77
78 rtlpriv->rtlhal.pfirmware = (u8 *) vmalloc(0x4000);
79 if (!rtlpriv->rtlhal.pfirmware) {
80 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
81 ("Can't alloc buffer for fw.\n"));
82 return 1;
83 }
84
85 return 0;
86}
87
88void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw)
89{
90 struct rtl_priv *rtlpriv = rtl_priv(hw);
91
92 if (rtlpriv->rtlhal.pfirmware) {
93 vfree(rtlpriv->rtlhal.pfirmware);
94 rtlpriv->rtlhal.pfirmware = NULL;
95 }
96}
97
98static struct rtl_hal_ops rtl8192ce_hal_ops = {
99 .init_sw_vars = rtl92c_init_sw_vars,
100 .deinit_sw_vars = rtl92c_deinit_sw_vars,
101 .read_eeprom_info = rtl92ce_read_eeprom_info,
102 .interrupt_recognized = rtl92ce_interrupt_recognized,
103 .hw_init = rtl92ce_hw_init,
104 .hw_disable = rtl92ce_card_disable,
105 .enable_interrupt = rtl92ce_enable_interrupt,
106 .disable_interrupt = rtl92ce_disable_interrupt,
107 .set_network_type = rtl92ce_set_network_type,
108 .set_qos = rtl92ce_set_qos,
109 .set_bcn_reg = rtl92ce_set_beacon_related_registers,
110 .set_bcn_intv = rtl92ce_set_beacon_interval,
111 .update_interrupt_mask = rtl92ce_update_interrupt_mask,
112 .get_hw_reg = rtl92ce_get_hw_reg,
113 .set_hw_reg = rtl92ce_set_hw_reg,
114 .update_rate_table = rtl92ce_update_hal_rate_table,
115 .update_rate_mask = rtl92ce_update_hal_rate_mask,
116 .fill_tx_desc = rtl92ce_tx_fill_desc,
117 .fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc,
118 .query_rx_desc = rtl92ce_rx_query_desc,
119 .set_channel_access = rtl92ce_update_channel_access_setting,
120 .radio_onoff_checking = rtl92ce_gpio_radio_on_off_checking,
121 .set_bw_mode = rtl92c_phy_set_bw_mode,
122 .switch_channel = rtl92c_phy_sw_chnl,
123 .dm_watchdog = rtl92c_dm_watchdog,
124 .scan_operation_backup = rtl92c_phy_scan_operation_backup,
125 .set_rf_power_state = rtl92c_phy_set_rf_power_state,
126 .led_control = rtl92ce_led_control,
127 .set_desc = rtl92ce_set_desc,
128 .get_desc = rtl92ce_get_desc,
129 .tx_polling = rtl92ce_tx_polling,
130 .enable_hw_sec = rtl92ce_enable_hw_security_config,
131 .set_key = rtl92ce_set_key,
132 .init_sw_leds = rtl92ce_init_sw_leds,
133 .deinit_sw_leds = rtl92ce_deinit_sw_leds,
134 .get_bbreg = rtl92c_phy_query_bb_reg,
135 .set_bbreg = rtl92c_phy_set_bb_reg,
136 .get_rfreg = rtl92c_phy_query_rf_reg,
137 .set_rfreg = rtl92c_phy_set_rf_reg,
138};
139
140static struct rtl_mod_params rtl92ce_mod_params = {
141 .sw_crypto = 0,
142};
143
144static struct rtl_hal_cfg rtl92ce_hal_cfg = {
145 .name = "rtl92c_pci",
146 .fw_name = "rtlwifi/rtl8192cfw.bin",
147 .ops = &rtl8192ce_hal_ops,
148 .mod_params = &rtl92ce_mod_params,
149
150 .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
151 .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
152 .maps[SYS_CLK] = REG_SYS_CLKR,
153 .maps[MAC_RCR_AM] = AM,
154 .maps[MAC_RCR_AB] = AB,
155 .maps[MAC_RCR_ACRC32] = ACRC32,
156 .maps[MAC_RCR_ACF] = ACF,
157 .maps[MAC_RCR_AAP] = AAP,
158
159 .maps[EFUSE_TEST] = REG_EFUSE_TEST,
160 .maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
161 .maps[EFUSE_CLK] = 0,
162 .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
163 .maps[EFUSE_PWC_EV12V] = PWC_EV12V,
164 .maps[EFUSE_FEN_ELDR] = FEN_ELDR,
165 .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
166 .maps[EFUSE_ANA8M] = EFUSE_ANA8M,
167 .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
168
169 .maps[RWCAM] = REG_CAMCMD,
170 .maps[WCAMI] = REG_CAMWRITE,
171 .maps[RCAMO] = REG_CAMREAD,
172 .maps[CAMDBG] = REG_CAMDBG,
173 .maps[SECR] = REG_SECCFG,
174 .maps[SEC_CAM_NONE] = CAM_NONE,
175 .maps[SEC_CAM_WEP40] = CAM_WEP40,
176 .maps[SEC_CAM_TKIP] = CAM_TKIP,
177 .maps[SEC_CAM_AES] = CAM_AES,
178 .maps[SEC_CAM_WEP104] = CAM_WEP104,
179
180 .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
181 .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
182 .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
183 .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
184 .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
185 .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
186 .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
187 .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
188 .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
189 .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
190 .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
191 .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
192 .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
193 .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
194 .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
195 .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
196
197 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
198 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
199 .maps[RTL_IMR_BcnInt] = IMR_BCNINT,
200 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
201 .maps[RTL_IMR_RDU] = IMR_RDU,
202 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
203 .maps[RTL_IMR_BDOK] = IMR_BDOK,
204 .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
205 .maps[RTL_IMR_TBDER] = IMR_TBDER,
206 .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
207 .maps[RTL_IMR_TBDOK] = IMR_TBDOK,
208 .maps[RTL_IMR_BKDOK] = IMR_BKDOK,
209 .maps[RTL_IMR_BEDOK] = IMR_BEDOK,
210 .maps[RTL_IMR_VIDOK] = IMR_VIDOK,
211 .maps[RTL_IMR_VODOK] = IMR_VODOK,
212 .maps[RTL_IMR_ROK] = IMR_ROK,
213 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
214
215 .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M,
216 .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M,
217 .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M,
218 .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M,
219 .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M,
220 .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M,
221 .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M,
222 .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M,
223 .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M,
224 .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M,
225 .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M,
226 .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M,
227
228 .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7,
229 .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15,
230};
231
232static struct pci_device_id rtl92ce_pci_ids[] __devinitdata = {
233 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)},
234 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)},
235 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)},
236 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8176, rtl92ce_hal_cfg)},
237 {},
238};
239
240MODULE_DEVICE_TABLE(pci, rtl92ce_pci_ids);
241
242MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
243MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
244MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
245MODULE_LICENSE("GPL");
246MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless");
247MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin");
248
249module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444);
250MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
251
252static struct pci_driver rtl92ce_driver = {
253 .name = KBUILD_MODNAME,
254 .id_table = rtl92ce_pci_ids,
255 .probe = rtl_pci_probe,
256 .remove = rtl_pci_disconnect,
257
258#ifdef CONFIG_PM
259 .suspend = rtl_pci_suspend,
260 .resume = rtl_pci_resume,
261#endif
262
263};
264
265static int __init rtl92ce_module_init(void)
266{
267 int ret;
268
269 ret = pci_register_driver(&rtl92ce_driver);
270 if (ret)
271 RT_ASSERT(false, (": No device found\n"));
272
273 return ret;
274}
275
276static void __exit rtl92ce_module_exit(void)
277{
278 pci_unregister_driver(&rtl92ce_driver);
279}
280
281module_init(rtl92ce_module_init);
282module_exit(rtl92ce_module_exit);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
new file mode 100644
index 000000000000..de1198c38d4e
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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/table.c b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c
new file mode 100644
index 000000000000..ba938b91aa6f
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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 "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/table.h b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h
new file mode 100644
index 000000000000..3a6e8b6aeee0
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
new file mode 100644
index 000000000000..bf5852f2d634
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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 "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "trx.h"
37#include "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/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
new file mode 100644
index 000000000000..53d0e0a5af5c
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/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} __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} __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} __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 000000000000..d44d79613d2d
--- /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} __packed;
555
556struct rtl_info_element {
557 u8 id;
558 u8 len;
559 u8 data[0];
560} __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} __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} __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 /* mutex */
1196 struct mutex conf_mutex;
1197
1198 /*spin lock */
1199 spinlock_t ips_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
diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c
index 596d90ecba33..d550b5e68d3c 100644
--- a/drivers/net/wireless/wl1251/sdio.c
+++ b/drivers/net/wireless/wl1251/sdio.c
@@ -252,7 +252,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
252 wl->if_ops = &wl1251_sdio_ops; 252 wl->if_ops = &wl1251_sdio_ops;
253 253
254 wl12xx_board_data = wl12xx_get_platform_data(); 254 wl12xx_board_data = wl12xx_get_platform_data();
255 if (wl12xx_board_data != NULL) { 255 if (!IS_ERR(wl12xx_board_data)) {
256 wl->set_power = wl12xx_board_data->set_power; 256 wl->set_power = wl12xx_board_data->set_power;
257 wl->irq = wl12xx_board_data->irq; 257 wl->irq = wl12xx_board_data->irq;
258 wl->use_eeprom = wl12xx_board_data->use_eeprom; 258 wl->use_eeprom = wl12xx_board_data->use_eeprom;
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index d2adeb1f72b7..0e65bce457d6 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -52,6 +52,16 @@ config WL12XX_SDIO
52 If you choose to build a module, it'll be called wl12xx_sdio. 52 If you choose to build a module, it'll be called wl12xx_sdio.
53 Say N if unsure. 53 Say N if unsure.
54 54
55config WL12XX_SDIO_TEST
56 tristate "TI wl12xx SDIO testing support"
57 depends on WL12XX && MMC
58 default n
59 ---help---
60 This module adds support for the SDIO bus testing with the
61 TI wl12xx chipsets. You probably don't want this unless you are
62 testing a new hardware platform. Select this if you want to test the
63 SDIO bus which is connected to the wl12xx chip.
64
55config WL12XX_PLATFORM_DATA 65config WL12XX_PLATFORM_DATA
56 bool 66 bool
57 depends on WL12XX_SDIO != n || WL1251_SDIO != n 67 depends on WL12XX_SDIO != n || WL1251_SDIO != n
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index 005a758174d9..521c0414e52e 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -3,11 +3,14 @@ wl12xx-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \
3 3
4wl12xx_spi-objs = spi.o 4wl12xx_spi-objs = spi.o
5wl12xx_sdio-objs = sdio.o 5wl12xx_sdio-objs = sdio.o
6wl12xx_sdio_test-objs = sdio_test.o
6 7
7wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o 8wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
8obj-$(CONFIG_WL12XX) += wl12xx.o 9obj-$(CONFIG_WL12XX) += wl12xx.o
9obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o 10obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o
10obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o 11obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o
11 12
13obj-$(CONFIG_WL12XX_SDIO_TEST) += wl12xx_sdio_test.o
14
12# small builtin driver bit 15# small builtin driver bit
13obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o 16obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index 7cbaeb6d2a37..cc4068d2b4a8 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -1041,7 +1041,7 @@ out:
1041 return ret; 1041 return ret;
1042} 1042}
1043 1043
1044int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address) 1044int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 enable, __be32 address)
1045{ 1045{
1046 struct wl1271_acx_arp_filter *acx; 1046 struct wl1271_acx_arp_filter *acx;
1047 int ret; 1047 int ret;
@@ -1057,7 +1057,7 @@ int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address)
1057 acx->version = ACX_IPV4_VERSION; 1057 acx->version = ACX_IPV4_VERSION;
1058 acx->enable = enable; 1058 acx->enable = enable;
1059 1059
1060 if (enable == true) 1060 if (enable)
1061 memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE); 1061 memcpy(acx->address, &address, ACX_IPV4_ADDR_SIZE);
1062 1062
1063 ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER, 1063 ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER,
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index 75a6306ff554..9cbc3f40c8dd 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -868,10 +868,15 @@ struct wl1271_acx_bet_enable {
868#define ACX_IPV4_VERSION 4 868#define ACX_IPV4_VERSION 4
869#define ACX_IPV6_VERSION 6 869#define ACX_IPV6_VERSION 6
870#define ACX_IPV4_ADDR_SIZE 4 870#define ACX_IPV4_ADDR_SIZE 4
871
872/* bitmap of enabled arp_filter features */
873#define ACX_ARP_FILTER_ARP_FILTERING BIT(0)
874#define ACX_ARP_FILTER_AUTO_ARP BIT(1)
875
871struct wl1271_acx_arp_filter { 876struct wl1271_acx_arp_filter {
872 struct acx_header header; 877 struct acx_header header;
873 u8 version; /* ACX_IPV4_VERSION, ACX_IPV6_VERSION */ 878 u8 version; /* ACX_IPV4_VERSION, ACX_IPV6_VERSION */
874 u8 enable; /* 1 to enable ARP filtering, 0 to disable */ 879 u8 enable; /* bitmap of enabled ARP filtering features */
875 u8 padding[2]; 880 u8 padding[2];
876 u8 address[16]; /* The configured device IP address - all ARP 881 u8 address[16]; /* The configured device IP address - all ARP
877 requests directed to this IP address will pass 882 requests directed to this IP address will pass
@@ -1168,7 +1173,7 @@ int wl1271_acx_init_mem_config(struct wl1271 *wl);
1168int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); 1173int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
1169int wl1271_acx_smart_reflex(struct wl1271 *wl); 1174int wl1271_acx_smart_reflex(struct wl1271 *wl);
1170int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable); 1175int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
1171int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address); 1176int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 enable, __be32 address);
1172int wl1271_acx_pm_config(struct wl1271 *wl); 1177int wl1271_acx_pm_config(struct wl1271 *wl);
1173int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable); 1178int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable);
1174int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid); 1179int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid);
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
index 1eafb8175832..4a9f929725fd 100644
--- a/drivers/net/wireless/wl12xx/boot.c
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -467,7 +467,8 @@ static void wl1271_boot_hw_version(struct wl1271 *wl)
467 wl->hw_pg_ver = (s8)fuse; 467 wl->hw_pg_ver = (s8)fuse;
468} 468}
469 469
470int wl1271_boot(struct wl1271 *wl) 470/* uploads NVS and firmware */
471int wl1271_load_firmware(struct wl1271 *wl)
471{ 472{
472 int ret = 0; 473 int ret = 0;
473 u32 tmp, clk, pause; 474 u32 tmp, clk, pause;
@@ -572,6 +573,20 @@ int wl1271_boot(struct wl1271 *wl)
572 if (ret < 0) 573 if (ret < 0)
573 goto out; 574 goto out;
574 575
576out:
577 return ret;
578}
579EXPORT_SYMBOL_GPL(wl1271_load_firmware);
580
581int wl1271_boot(struct wl1271 *wl)
582{
583 int ret;
584
585 /* upload NVS and firmware */
586 ret = wl1271_load_firmware(wl);
587 if (ret)
588 return ret;
589
575 /* 10.5 start firmware */ 590 /* 10.5 start firmware */
576 ret = wl1271_boot_run_firmware(wl); 591 ret = wl1271_boot_run_firmware(wl);
577 if (ret < 0) 592 if (ret < 0)
diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h
index c7d771959f3a..d67dcffa31eb 100644
--- a/drivers/net/wireless/wl12xx/boot.h
+++ b/drivers/net/wireless/wl12xx/boot.h
@@ -27,6 +27,7 @@
27#include "wl12xx.h" 27#include "wl12xx.h"
28 28
29int wl1271_boot(struct wl1271 *wl); 29int wl1271_boot(struct wl1271 *wl);
30int wl1271_load_firmware(struct wl1271 *wl);
30 31
31#define WL1271_NO_SUBBANDS 8 32#define WL1271_NO_SUBBANDS 8
32#define WL1271_NO_POWER_LEVELS 4 33#define WL1271_NO_POWER_LEVELS 4
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index f3d0541aaad6..0106628aa5a2 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -611,6 +611,75 @@ out:
611 return ret; 611 return ret;
612} 612}
613 613
614struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
615 struct sk_buff *skb)
616{
617 int ret;
618
619 if (!skb)
620 skb = ieee80211_ap_probereq_get(wl->hw, wl->vif);
621 if (!skb)
622 goto out;
623
624 wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len);
625
626 if (wl->band == IEEE80211_BAND_2GHZ)
627 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
628 skb->data, skb->len, 0,
629 wl->conf.tx.basic_rate);
630 else
631 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
632 skb->data, skb->len, 0,
633 wl->conf.tx.basic_rate_5);
634
635 if (ret < 0)
636 wl1271_error("Unable to set ap probe request template.");
637
638out:
639 return skb;
640}
641
642int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, __be32 ip_addr)
643{
644 int ret;
645 struct wl12xx_arp_rsp_template tmpl;
646 struct ieee80211_hdr_3addr *hdr;
647 struct arphdr *arp_hdr;
648
649 memset(&tmpl, 0, sizeof(tmpl));
650
651 /* mac80211 header */
652 hdr = &tmpl.hdr;
653 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
654 IEEE80211_STYPE_DATA |
655 IEEE80211_FCTL_TODS);
656 memcpy(hdr->addr1, wl->vif->bss_conf.bssid, ETH_ALEN);
657 memcpy(hdr->addr2, wl->vif->addr, ETH_ALEN);
658 memset(hdr->addr3, 0xff, ETH_ALEN);
659
660 /* llc layer */
661 memcpy(tmpl.llc_hdr, rfc1042_header, sizeof(rfc1042_header));
662 tmpl.llc_type = htons(ETH_P_ARP);
663
664 /* arp header */
665 arp_hdr = &tmpl.arp_hdr;
666 arp_hdr->ar_hrd = htons(ARPHRD_ETHER);
667 arp_hdr->ar_pro = htons(ETH_P_IP);
668 arp_hdr->ar_hln = ETH_ALEN;
669 arp_hdr->ar_pln = 4;
670 arp_hdr->ar_op = htons(ARPOP_REPLY);
671
672 /* arp payload */
673 memcpy(tmpl.sender_hw, wl->vif->addr, ETH_ALEN);
674 tmpl.sender_ip = ip_addr;
675
676 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP,
677 &tmpl, sizeof(tmpl), 0,
678 wl->basic_rate);
679
680 return ret;
681}
682
614int wl1271_build_qos_null_data(struct wl1271 *wl) 683int wl1271_build_qos_null_data(struct wl1271 *wl)
615{ 684{
616 struct ieee80211_qos_hdr template; 685 struct ieee80211_qos_hdr template;
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
index 16d1bf814e76..2a1d9db7ceb8 100644
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -49,6 +49,9 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid);
49int wl1271_cmd_build_probe_req(struct wl1271 *wl, 49int wl1271_cmd_build_probe_req(struct wl1271 *wl,
50 const u8 *ssid, size_t ssid_len, 50 const u8 *ssid, size_t ssid_len,
51 const u8 *ie, size_t ie_len, u8 band); 51 const u8 *ie, size_t ie_len, u8 band);
52struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
53 struct sk_buff *skb);
54int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, __be32 ip_addr);
52int wl1271_build_qos_null_data(struct wl1271 *wl); 55int wl1271_build_qos_null_data(struct wl1271 *wl);
53int wl1271_cmd_build_klv_null_data(struct wl1271 *wl); 56int wl1271_cmd_build_klv_null_data(struct wl1271 *wl);
54int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); 57int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id);
@@ -122,6 +125,7 @@ enum cmd_templ {
122 CMD_TEMPL_CTS, /* 125 CMD_TEMPL_CTS, /*
123 * For CTS-to-self (FastCTS) mechanism 126 * For CTS-to-self (FastCTS) mechanism
124 * for BT/WLAN coexistence (SoftGemini). */ 127 * for BT/WLAN coexistence (SoftGemini). */
128 CMD_TEMPL_ARP_RSP,
125 CMD_TEMPL_MAX = 0xff 129 CMD_TEMPL_MAX = 0xff
126}; 130};
127 131
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index dd71b7d2105c..ec6077760157 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -66,19 +66,10 @@ static const struct file_operations name## _ops = { \
66}; 66};
67 67
68#define DEBUGFS_ADD(name, parent) \ 68#define DEBUGFS_ADD(name, parent) \
69 wl->debugfs.name = debugfs_create_file(#name, 0400, parent, \ 69 entry = debugfs_create_file(#name, 0400, parent, \
70 wl, &name## _ops); \ 70 wl, &name## _ops); \
71 if (IS_ERR(wl->debugfs.name)) { \ 71 if (!entry || IS_ERR(entry)) \
72 ret = PTR_ERR(wl->debugfs.name); \ 72 goto err; \
73 wl->debugfs.name = NULL; \
74 goto out; \
75 }
76
77#define DEBUGFS_DEL(name) \
78 do { \
79 debugfs_remove(wl->debugfs.name); \
80 wl->debugfs.name = NULL; \
81 } while (0)
82 73
83#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \ 74#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \
84static ssize_t sub## _ ##name## _read(struct file *file, \ 75static ssize_t sub## _ ##name## _read(struct file *file, \
@@ -100,10 +91,7 @@ static const struct file_operations sub## _ ##name## _ops = { \
100}; 91};
101 92
102#define DEBUGFS_FWSTATS_ADD(sub, name) \ 93#define DEBUGFS_FWSTATS_ADD(sub, name) \
103 DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics) 94 DEBUGFS_ADD(sub## _ ##name, stats)
104
105#define DEBUGFS_FWSTATS_DEL(sub, name) \
106 DEBUGFS_DEL(sub## _ ##name)
107 95
108static void wl1271_debugfs_update_stats(struct wl1271 *wl) 96static void wl1271_debugfs_update_stats(struct wl1271 *wl)
109{ 97{
@@ -237,7 +225,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
237 char buf[20]; 225 char buf[20];
238 int res; 226 int res;
239 227
240 queue_len = skb_queue_len(&wl->tx_queue); 228 queue_len = wl->tx_queue_count;
241 229
242 res = scnprintf(buf, sizeof(buf), "%u\n", queue_len); 230 res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
243 return simple_read_from_buffer(userbuf, count, ppos, buf, res); 231 return simple_read_from_buffer(userbuf, count, ppos, buf, res);
@@ -305,109 +293,16 @@ static const struct file_operations gpio_power_ops = {
305 .llseek = default_llseek, 293 .llseek = default_llseek,
306}; 294};
307 295
308static void wl1271_debugfs_delete_files(struct wl1271 *wl)
309{
310 DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
311
312 DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
313 DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
314 DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
315 DEBUGFS_FWSTATS_DEL(rx, dropped);
316 DEBUGFS_FWSTATS_DEL(rx, fcs_err);
317 DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
318 DEBUGFS_FWSTATS_DEL(rx, path_reset);
319 DEBUGFS_FWSTATS_DEL(rx, reset_counter);
320
321 DEBUGFS_FWSTATS_DEL(dma, rx_requested);
322 DEBUGFS_FWSTATS_DEL(dma, rx_errors);
323 DEBUGFS_FWSTATS_DEL(dma, tx_requested);
324 DEBUGFS_FWSTATS_DEL(dma, tx_errors);
325
326 DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
327 DEBUGFS_FWSTATS_DEL(isr, fiqs);
328 DEBUGFS_FWSTATS_DEL(isr, rx_headers);
329 DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
330 DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
331 DEBUGFS_FWSTATS_DEL(isr, irqs);
332 DEBUGFS_FWSTATS_DEL(isr, tx_procs);
333 DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
334 DEBUGFS_FWSTATS_DEL(isr, dma0_done);
335 DEBUGFS_FWSTATS_DEL(isr, dma1_done);
336 DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
337 DEBUGFS_FWSTATS_DEL(isr, commands);
338 DEBUGFS_FWSTATS_DEL(isr, rx_procs);
339 DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
340 DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
341 DEBUGFS_FWSTATS_DEL(isr, pci_pm);
342 DEBUGFS_FWSTATS_DEL(isr, wakeups);
343 DEBUGFS_FWSTATS_DEL(isr, low_rssi);
344
345 DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
346 DEBUGFS_FWSTATS_DEL(wep, default_key_count);
347 /* skipping wep.reserved */
348 DEBUGFS_FWSTATS_DEL(wep, key_not_found);
349 DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
350 DEBUGFS_FWSTATS_DEL(wep, packets);
351 DEBUGFS_FWSTATS_DEL(wep, interrupt);
352
353 DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
354 DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
355 DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
356 DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
357 DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
358 DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
359 DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
360 DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
361 DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
362 DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
363 DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
364 DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
365 /* skipping cont_miss_bcns_spread for now */
366 DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
367
368 DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
369 DEBUGFS_FWSTATS_DEL(mic, calc_failure);
370
371 DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
372 DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
373 DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
374 DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
375 DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
376 DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
377
378 DEBUGFS_FWSTATS_DEL(event, heart_beat);
379 DEBUGFS_FWSTATS_DEL(event, calibration);
380 DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
381 DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
382 DEBUGFS_FWSTATS_DEL(event, rx_pool);
383 DEBUGFS_FWSTATS_DEL(event, oom_late);
384 DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
385 DEBUGFS_FWSTATS_DEL(event, tx_stuck);
386
387 DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
388 DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
389 DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
390 DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
391 DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
392 DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
393 DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
394
395 DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
396 DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
397 DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
398 DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
399 DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
400
401 DEBUGFS_DEL(tx_queue_len);
402 DEBUGFS_DEL(retry_count);
403 DEBUGFS_DEL(excessive_retries);
404
405 DEBUGFS_DEL(gpio_power);
406}
407
408static int wl1271_debugfs_add_files(struct wl1271 *wl) 296static int wl1271_debugfs_add_files(struct wl1271 *wl)
409{ 297{
410 int ret = 0; 298 int ret = 0;
299 struct dentry *entry, *stats;
300
301 stats = debugfs_create_dir("fw-statistics", wl->rootdir);
302 if (!stats || IS_ERR(stats)) {
303 entry = stats;
304 goto err;
305 }
411 306
412 DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow); 307 DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
413 308
@@ -500,21 +395,33 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl)
500 DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data); 395 DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
501 DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); 396 DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
502 397
503 DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir); 398 DEBUGFS_ADD(tx_queue_len, wl->rootdir);
504 DEBUGFS_ADD(retry_count, wl->debugfs.rootdir); 399 DEBUGFS_ADD(retry_count, wl->rootdir);
505 DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir); 400 DEBUGFS_ADD(excessive_retries, wl->rootdir);
506 401
507 DEBUGFS_ADD(gpio_power, wl->debugfs.rootdir); 402 DEBUGFS_ADD(gpio_power, wl->rootdir);
508 403
509out: 404 entry = debugfs_create_x32("debug_level", 0600, wl->rootdir,
510 if (ret < 0) 405 &wl12xx_debug_level);
511 wl1271_debugfs_delete_files(wl); 406 if (!entry || IS_ERR(entry))
407 goto err;
408
409 return 0;
410
411err:
412 if (IS_ERR(entry))
413 ret = PTR_ERR(entry);
414 else
415 ret = -ENOMEM;
512 416
513 return ret; 417 return ret;
514} 418}
515 419
516void wl1271_debugfs_reset(struct wl1271 *wl) 420void wl1271_debugfs_reset(struct wl1271 *wl)
517{ 421{
422 if (!wl->rootdir)
423 return;
424
518 memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); 425 memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
519 wl->stats.retry_count = 0; 426 wl->stats.retry_count = 0;
520 wl->stats.excessive_retries = 0; 427 wl->stats.excessive_retries = 0;
@@ -524,23 +431,15 @@ int wl1271_debugfs_init(struct wl1271 *wl)
524{ 431{
525 int ret; 432 int ret;
526 433
527 wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); 434 wl->rootdir = debugfs_create_dir(KBUILD_MODNAME,
435 wl->hw->wiphy->debugfsdir);
528 436
529 if (IS_ERR(wl->debugfs.rootdir)) { 437 if (IS_ERR(wl->rootdir)) {
530 ret = PTR_ERR(wl->debugfs.rootdir); 438 ret = PTR_ERR(wl->rootdir);
531 wl->debugfs.rootdir = NULL; 439 wl->rootdir = NULL;
532 goto err; 440 goto err;
533 } 441 }
534 442
535 wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
536 wl->debugfs.rootdir);
537
538 if (IS_ERR(wl->debugfs.fw_statistics)) {
539 ret = PTR_ERR(wl->debugfs.fw_statistics);
540 wl->debugfs.fw_statistics = NULL;
541 goto err_root;
542 }
543
544 wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats), 443 wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
545 GFP_KERNEL); 444 GFP_KERNEL);
546 445
@@ -563,12 +462,8 @@ err_file:
563 wl->stats.fw_stats = NULL; 462 wl->stats.fw_stats = NULL;
564 463
565err_fw: 464err_fw:
566 debugfs_remove(wl->debugfs.fw_statistics); 465 debugfs_remove_recursive(wl->rootdir);
567 wl->debugfs.fw_statistics = NULL; 466 wl->rootdir = NULL;
568
569err_root:
570 debugfs_remove(wl->debugfs.rootdir);
571 wl->debugfs.rootdir = NULL;
572 467
573err: 468err:
574 return ret; 469 return ret;
@@ -576,15 +471,10 @@ err:
576 471
577void wl1271_debugfs_exit(struct wl1271 *wl) 472void wl1271_debugfs_exit(struct wl1271 *wl)
578{ 473{
579 wl1271_debugfs_delete_files(wl);
580
581 kfree(wl->stats.fw_stats); 474 kfree(wl->stats.fw_stats);
582 wl->stats.fw_stats = NULL; 475 wl->stats.fw_stats = NULL;
583 476
584 debugfs_remove(wl->debugfs.fw_statistics); 477 debugfs_remove_recursive(wl->rootdir);
585 wl->debugfs.fw_statistics = NULL; 478 wl->rootdir = NULL;
586
587 debugfs_remove(wl->debugfs.rootdir);
588 wl->debugfs.rootdir = NULL;
589 479
590} 480}
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
index 7949d346aadb..785a5304bfc4 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -53,18 +53,16 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl)
53int wl1271_init_templates_config(struct wl1271 *wl) 53int wl1271_init_templates_config(struct wl1271 *wl)
54{ 54{
55 int ret, i; 55 int ret, i;
56 size_t size;
57 56
58 /* send empty templates for fw memory reservation */ 57 /* send empty templates for fw memory reservation */
59 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, 58 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
60 sizeof(struct wl12xx_probe_req_template), 59 WL1271_CMD_TEMPL_MAX_SIZE,
61 0, WL1271_RATE_AUTOMATIC); 60 0, WL1271_RATE_AUTOMATIC);
62 if (ret < 0) 61 if (ret < 0)
63 return ret; 62 return ret;
64 63
65 size = sizeof(struct wl12xx_probe_req_template);
66 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 64 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
67 NULL, size, 0, 65 NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0,
68 WL1271_RATE_AUTOMATIC); 66 WL1271_RATE_AUTOMATIC);
69 if (ret < 0) 67 if (ret < 0)
70 return ret; 68 return ret;
@@ -102,6 +100,13 @@ int wl1271_init_templates_config(struct wl1271 *wl)
102 if (ret < 0) 100 if (ret < 0)
103 return ret; 101 return ret;
104 102
103 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, NULL,
104 sizeof
105 (struct wl12xx_arp_rsp_template),
106 0, WL1271_RATE_AUTOMATIC);
107 if (ret < 0)
108 return ret;
109
105 for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { 110 for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
106 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL, 111 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL,
107 WL1271_CMD_TEMPL_MAX_SIZE, i, 112 WL1271_CMD_TEMPL_MAX_SIZE, i,
diff --git a/drivers/net/wireless/wl12xx/io.c b/drivers/net/wireless/wl12xx/io.c
index 35c2f1aca6ba..d557f73e7c19 100644
--- a/drivers/net/wireless/wl12xx/io.c
+++ b/drivers/net/wireless/wl12xx/io.c
@@ -113,6 +113,7 @@ int wl1271_set_partition(struct wl1271 *wl,
113 113
114 return 0; 114 return 0;
115} 115}
116EXPORT_SYMBOL_GPL(wl1271_set_partition);
116 117
117void wl1271_io_reset(struct wl1271 *wl) 118void wl1271_io_reset(struct wl1271 *wl)
118{ 119{
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 708ffe304c6d..062247ef3ad2 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -336,7 +336,8 @@ out:
336} 336}
337 337
338static int wl1271_reg_notify(struct wiphy *wiphy, 338static int wl1271_reg_notify(struct wiphy *wiphy,
339 struct regulatory_request *request) { 339 struct regulatory_request *request)
340{
340 struct ieee80211_supported_band *band; 341 struct ieee80211_supported_band *band;
341 struct ieee80211_channel *ch; 342 struct ieee80211_channel *ch;
342 int i; 343 int i;
@@ -569,7 +570,7 @@ static void wl1271_irq_work(struct work_struct *work)
569 570
570 /* Check if any tx blocks were freed */ 571 /* Check if any tx blocks were freed */
571 if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && 572 if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
572 !skb_queue_empty(&wl->tx_queue)) { 573 wl->tx_queue_count) {
573 /* 574 /*
574 * In order to avoid starvation of the TX path, 575 * In order to avoid starvation of the TX path,
575 * call the work function directly. 576 * call the work function directly.
@@ -890,6 +891,7 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
890 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); 891 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
891 struct ieee80211_sta *sta = txinfo->control.sta; 892 struct ieee80211_sta *sta = txinfo->control.sta;
892 unsigned long flags; 893 unsigned long flags;
894 int q;
893 895
894 /* 896 /*
895 * peek into the rates configured in the STA entry. 897 * peek into the rates configured in the STA entry.
@@ -917,10 +919,12 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
917 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); 919 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
918 } 920 }
919#endif 921#endif
922 wl->tx_queue_count++;
920 spin_unlock_irqrestore(&wl->wl_lock, flags); 923 spin_unlock_irqrestore(&wl->wl_lock, flags);
921 924
922 /* queue the packet */ 925 /* queue the packet */
923 skb_queue_tail(&wl->tx_queue, skb); 926 q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
927 skb_queue_tail(&wl->tx_queue[q], skb);
924 928
925 /* 929 /*
926 * The chip specific setup must run before the first TX packet - 930 * The chip specific setup must run before the first TX packet -
@@ -934,7 +938,7 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
934 * The workqueue is slow to process the tx_queue and we need stop 938 * The workqueue is slow to process the tx_queue and we need stop
935 * the queue here, otherwise the queue will get too long. 939 * the queue here, otherwise the queue will get too long.
936 */ 940 */
937 if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_HIGH_WATERMARK) { 941 if (wl->tx_queue_count >= WL1271_TX_QUEUE_HIGH_WATERMARK) {
938 wl1271_debug(DEBUG_TX, "op_tx: stopping queues"); 942 wl1271_debug(DEBUG_TX, "op_tx: stopping queues");
939 943
940 spin_lock_irqsave(&wl->wl_lock, flags); 944 spin_lock_irqsave(&wl->wl_lock, flags);
@@ -1064,6 +1068,16 @@ power_off:
1064 strncpy(wiphy->fw_version, wl->chip.fw_ver, 1068 strncpy(wiphy->fw_version, wl->chip.fw_ver,
1065 sizeof(wiphy->fw_version)); 1069 sizeof(wiphy->fw_version));
1066 1070
1071 /*
1072 * Now we know if 11a is supported (info from the NVS), so disable
1073 * 11a channels if not supported
1074 */
1075 if (!wl->enable_11a)
1076 wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels = 0;
1077
1078 wl1271_debug(DEBUG_MAC80211, "11a is %ssupported",
1079 wl->enable_11a ? "" : "not ");
1080
1067out: 1081out:
1068 mutex_unlock(&wl->mutex); 1082 mutex_unlock(&wl->mutex);
1069 1083
@@ -1157,10 +1171,16 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1157 struct wl1271 *wl = hw->priv; 1171 struct wl1271 *wl = hw->priv;
1158 1172
1159 mutex_lock(&wl->mutex); 1173 mutex_lock(&wl->mutex);
1160 WARN_ON(wl->vif != vif); 1174 /*
1161 __wl1271_op_remove_interface(wl); 1175 * wl->vif can be null here if someone shuts down the interface
1162 mutex_unlock(&wl->mutex); 1176 * just when hardware recovery has been started.
1177 */
1178 if (wl->vif) {
1179 WARN_ON(wl->vif != vif);
1180 __wl1271_op_remove_interface(wl);
1181 }
1163 1182
1183 mutex_unlock(&wl->mutex);
1164 cancel_work_sync(&wl->recovery_work); 1184 cancel_work_sync(&wl->recovery_work);
1165} 1185}
1166 1186
@@ -1801,21 +1821,21 @@ out:
1801 return ret; 1821 return ret;
1802} 1822}
1803 1823
1804static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *beacon) 1824static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb,
1825 int offset)
1805{ 1826{
1806 u8 *ptr = beacon->data + 1827 u8 *ptr = skb->data + offset;
1807 offsetof(struct ieee80211_mgmt, u.beacon.variable);
1808 1828
1809 /* find the location of the ssid in the beacon */ 1829 /* find the location of the ssid in the beacon */
1810 while (ptr < beacon->data + beacon->len) { 1830 while (ptr < skb->data + skb->len) {
1811 if (ptr[0] == WLAN_EID_SSID) { 1831 if (ptr[0] == WLAN_EID_SSID) {
1812 wl->ssid_len = ptr[1]; 1832 wl->ssid_len = ptr[1];
1813 memcpy(wl->ssid, ptr+2, wl->ssid_len); 1833 memcpy(wl->ssid, ptr+2, wl->ssid_len);
1814 return; 1834 return;
1815 } 1835 }
1816 ptr += ptr[1]; 1836 ptr += (ptr[1] + 2);
1817 } 1837 }
1818 wl1271_error("ad-hoc beacon template has no SSID!\n"); 1838 wl1271_error("No SSID in IEs!\n");
1819} 1839}
1820 1840
1821static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, 1841static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
@@ -1858,8 +1878,11 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1858 1878
1859 if (beacon) { 1879 if (beacon) {
1860 struct ieee80211_hdr *hdr; 1880 struct ieee80211_hdr *hdr;
1881 int ieoffset = offsetof(struct ieee80211_mgmt,
1882 u.beacon.variable);
1883
1884 wl1271_ssid_set(wl, beacon, ieoffset);
1861 1885
1862 wl1271_ssid_set(wl, beacon);
1863 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, 1886 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
1864 beacon->data, 1887 beacon->data,
1865 beacon->len, 0, 1888 beacon->len, 0,
@@ -1939,6 +1962,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1939 if (changed & BSS_CHANGED_ASSOC) { 1962 if (changed & BSS_CHANGED_ASSOC) {
1940 if (bss_conf->assoc) { 1963 if (bss_conf->assoc) {
1941 u32 rates; 1964 u32 rates;
1965 int ieoffset;
1942 wl->aid = bss_conf->aid; 1966 wl->aid = bss_conf->aid;
1943 set_assoc = true; 1967 set_assoc = true;
1944 1968
@@ -1967,13 +1991,13 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1967 goto out_sleep; 1991 goto out_sleep;
1968 1992
1969 /* 1993 /*
1970 * The SSID is intentionally set to NULL here - the 1994 * Get a template for hardware connection maintenance
1971 * firmware will set the probe request with a
1972 * broadcast SSID regardless of what we set in the
1973 * template.
1974 */ 1995 */
1975 ret = wl1271_cmd_build_probe_req(wl, NULL, 0, 1996 dev_kfree_skb(wl->probereq);
1976 NULL, 0, wl->band); 1997 wl->probereq = wl1271_cmd_build_ap_probe_req(wl, NULL);
1998 ieoffset = offsetof(struct ieee80211_mgmt,
1999 u.probe_req.variable);
2000 wl1271_ssid_set(wl, wl->probereq, ieoffset);
1977 2001
1978 /* enable the connection monitoring feature */ 2002 /* enable the connection monitoring feature */
1979 ret = wl1271_acx_conn_monit_params(wl, true); 2003 ret = wl1271_acx_conn_monit_params(wl, true);
@@ -1996,6 +2020,10 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1996 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); 2020 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1997 wl->aid = 0; 2021 wl->aid = 0;
1998 2022
2023 /* free probe-request template */
2024 dev_kfree_skb(wl->probereq);
2025 wl->probereq = NULL;
2026
1999 /* re-enable dynamic ps - just in case */ 2027 /* re-enable dynamic ps - just in case */
2000 ieee80211_enable_dyn_ps(wl->vif); 2028 ieee80211_enable_dyn_ps(wl->vif);
2001 2029
@@ -2085,10 +2113,26 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
2085 __be32 addr = bss_conf->arp_addr_list[0]; 2113 __be32 addr = bss_conf->arp_addr_list[0];
2086 WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); 2114 WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
2087 2115
2088 if (bss_conf->arp_addr_cnt == 1 && bss_conf->arp_filter_enabled) 2116 if (bss_conf->arp_addr_cnt == 1 &&
2089 ret = wl1271_acx_arp_ip_filter(wl, true, addr); 2117 bss_conf->arp_filter_enabled) {
2090 else 2118 /*
2091 ret = wl1271_acx_arp_ip_filter(wl, false, addr); 2119 * The template should have been configured only upon
2120 * association. however, it seems that the correct ip
2121 * isn't being set (when sending), so we have to
2122 * reconfigure the template upon every ip change.
2123 */
2124 ret = wl1271_cmd_build_arp_rsp(wl, addr);
2125 if (ret < 0) {
2126 wl1271_warning("build arp rsp failed: %d", ret);
2127 goto out_sleep;
2128 }
2129
2130 ret = wl1271_acx_arp_ip_filter(wl,
2131 (ACX_ARP_FILTER_ARP_FILTERING |
2132 ACX_ARP_FILTER_AUTO_ARP),
2133 addr);
2134 } else
2135 ret = wl1271_acx_arp_ip_filter(wl, 0, addr);
2092 2136
2093 if (ret < 0) 2137 if (ret < 0)
2094 goto out_sleep; 2138 goto out_sleep;
@@ -2353,14 +2397,6 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = {
2353 2397
2354/* 5 GHz band channels for WL1273 */ 2398/* 5 GHz band channels for WL1273 */
2355static struct ieee80211_channel wl1271_channels_5ghz[] = { 2399static struct ieee80211_channel wl1271_channels_5ghz[] = {
2356 { .hw_value = 183, .center_freq = 4915},
2357 { .hw_value = 184, .center_freq = 4920},
2358 { .hw_value = 185, .center_freq = 4925},
2359 { .hw_value = 187, .center_freq = 4935},
2360 { .hw_value = 188, .center_freq = 4940},
2361 { .hw_value = 189, .center_freq = 4945},
2362 { .hw_value = 192, .center_freq = 4960},
2363 { .hw_value = 196, .center_freq = 4980},
2364 { .hw_value = 7, .center_freq = 5035}, 2400 { .hw_value = 7, .center_freq = 5035},
2365 { .hw_value = 8, .center_freq = 5040}, 2401 { .hw_value = 8, .center_freq = 5040},
2366 { .hw_value = 9, .center_freq = 5045}, 2402 { .hw_value = 9, .center_freq = 5045},
@@ -2581,6 +2617,8 @@ int wl1271_register_hw(struct wl1271 *wl)
2581 2617
2582 wl->mac80211_registered = true; 2618 wl->mac80211_registered = true;
2583 2619
2620 wl1271_debugfs_init(wl);
2621
2584 register_netdevice_notifier(&wl1271_dev_notifier); 2622 register_netdevice_notifier(&wl1271_dev_notifier);
2585 2623
2586 wl1271_notice("loaded"); 2624 wl1271_notice("loaded");
@@ -2631,6 +2669,13 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
2631 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 2669 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2632 BIT(NL80211_IFTYPE_ADHOC); 2670 BIT(NL80211_IFTYPE_ADHOC);
2633 wl->hw->wiphy->max_scan_ssids = 1; 2671 wl->hw->wiphy->max_scan_ssids = 1;
2672 /*
2673 * Maximum length of elements in scanning probe request templates
2674 * should be the maximum length possible for a template, without
2675 * the IEEE80211 header of the template
2676 */
2677 wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
2678 sizeof(struct ieee80211_header);
2634 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz; 2679 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz;
2635 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; 2680 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
2636 2681
@@ -2677,7 +2722,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2677 wl->hw = hw; 2722 wl->hw = hw;
2678 wl->plat_dev = plat_dev; 2723 wl->plat_dev = plat_dev;
2679 2724
2680 skb_queue_head_init(&wl->tx_queue); 2725 for (i = 0; i < NUM_TX_QUEUES; i++)
2726 skb_queue_head_init(&wl->tx_queue[i]);
2681 2727
2682 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); 2728 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
2683 INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); 2729 INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work);
@@ -2715,8 +2761,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2715 /* Apply default driver configuration. */ 2761 /* Apply default driver configuration. */
2716 wl1271_conf_init(wl); 2762 wl1271_conf_init(wl);
2717 2763
2718 wl1271_debugfs_init(wl);
2719
2720 order = get_order(WL1271_AGGR_BUFFER_SIZE); 2764 order = get_order(WL1271_AGGR_BUFFER_SIZE);
2721 wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); 2765 wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
2722 if (!wl->aggr_buf) { 2766 if (!wl->aggr_buf) {
@@ -2793,6 +2837,11 @@ int wl1271_free_hw(struct wl1271 *wl)
2793} 2837}
2794EXPORT_SYMBOL_GPL(wl1271_free_hw); 2838EXPORT_SYMBOL_GPL(wl1271_free_hw);
2795 2839
2840u32 wl12xx_debug_level;
2841EXPORT_SYMBOL_GPL(wl12xx_debug_level);
2842module_param_named(debug_level, wl12xx_debug_level, uint, DEBUG_NONE);
2843MODULE_PARM_DESC(debug_level, "wl12xx debugging level");
2844
2796MODULE_LICENSE("GPL"); 2845MODULE_LICENSE("GPL");
2797MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); 2846MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
2798MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); 2847MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c
index f3f2c5b011ee..6f897b9d90ca 100644
--- a/drivers/net/wireless/wl12xx/scan.c
+++ b/drivers/net/wireless/wl12xx/scan.c
@@ -51,6 +51,10 @@ void wl1271_scan_complete_work(struct work_struct *work)
51 wl->scan.req = NULL; 51 wl->scan.req = NULL;
52 ieee80211_scan_completed(wl->hw, false); 52 ieee80211_scan_completed(wl->hw, false);
53 53
54 /* restore hardware connection monitoring template */
55 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
56 wl1271_cmd_build_ap_probe_req(wl, wl->probereq);
57
54 if (wl->scan.failed) { 58 if (wl->scan.failed) {
55 wl1271_info("Scan completed due to error."); 59 wl1271_info("Scan completed due to error.");
56 ieee80211_queue_work(wl->hw, &wl->recovery_work); 60 ieee80211_queue_work(wl->hw, &wl->recovery_work);
diff --git a/drivers/net/wireless/wl12xx/sdio_test.c b/drivers/net/wireless/wl12xx/sdio_test.c
new file mode 100644
index 000000000000..9fcbd3dd8490
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/sdio_test.c
@@ -0,0 +1,520 @@
1/*
2 * SDIO testing driver for wl12xx
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contact: Roger Quadros <roger.quadros@nokia.com>
7 *
8 * wl12xx read/write routines taken from the main module
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#include <linux/irq.h>
27#include <linux/module.h>
28#include <linux/crc7.h>
29#include <linux/vmalloc.h>
30#include <linux/mmc/sdio_func.h>
31#include <linux/mmc/sdio_ids.h>
32#include <linux/mmc/card.h>
33#include <linux/gpio.h>
34#include <linux/wl12xx.h>
35#include <linux/kthread.h>
36#include <linux/firmware.h>
37#include <linux/pm_runtime.h>
38
39#include "wl12xx.h"
40#include "io.h"
41#include "boot.h"
42
43#ifndef SDIO_VENDOR_ID_TI
44#define SDIO_VENDOR_ID_TI 0x0097
45#endif
46
47#ifndef SDIO_DEVICE_ID_TI_WL1271
48#define SDIO_DEVICE_ID_TI_WL1271 0x4076
49#endif
50
51static bool rx, tx;
52
53module_param(rx, bool, S_IRUGO | S_IWUSR);
54MODULE_PARM_DESC(rx, "Perform rx test. Default (0). "
55 "This test continuously reads data from the SDIO device.\n");
56
57module_param(tx, bool, S_IRUGO | S_IWUSR);
58MODULE_PARM_DESC(tx, "Perform tx test. Default (0). "
59 "This test continuously writes data to the SDIO device.\n");
60
61struct wl1271_test {
62 struct wl1271 wl;
63 struct task_struct *test_task;
64};
65
66static const struct sdio_device_id wl1271_devices[] = {
67 { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) },
68 {}
69};
70
71static inline struct sdio_func *wl_to_func(struct wl1271 *wl)
72{
73 return wl->if_priv;
74}
75
76static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl)
77{
78 return &(wl_to_func(wl)->dev);
79}
80
81static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
82 size_t len, bool fixed)
83{
84 int ret = 0;
85 struct sdio_func *func = wl_to_func(wl);
86
87 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
88 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
89 wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x",
90 addr, ((u8 *)buf)[0]);
91 } else {
92 if (fixed)
93 ret = sdio_readsb(func, buf, addr, len);
94 else
95 ret = sdio_memcpy_fromio(func, buf, addr, len);
96
97 wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %zu bytes",
98 addr, len);
99 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
100 }
101
102 if (ret)
103 wl1271_error("sdio read failed (%d)", ret);
104}
105
106static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
107 size_t len, bool fixed)
108{
109 int ret = 0;
110 struct sdio_func *func = wl_to_func(wl);
111
112 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
113 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
114 wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x",
115 addr, ((u8 *)buf)[0]);
116 } else {
117 wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes",
118 addr, len);
119 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
120
121 if (fixed)
122 ret = sdio_writesb(func, addr, buf, len);
123 else
124 ret = sdio_memcpy_toio(func, addr, buf, len);
125 }
126 if (ret)
127 wl1271_error("sdio write failed (%d)", ret);
128
129}
130
131static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
132{
133 struct sdio_func *func = wl_to_func(wl);
134 int ret;
135
136 /* Let the SDIO stack handle wlan_enable control, so we
137 * keep host claimed while wlan is in use to keep wl1271
138 * alive.
139 */
140 if (enable) {
141 /* Power up the card */
142 ret = pm_runtime_get_sync(&func->dev);
143 if (ret < 0)
144 goto out;
145 sdio_claim_host(func);
146 sdio_enable_func(func);
147 sdio_release_host(func);
148 } else {
149 sdio_claim_host(func);
150 sdio_disable_func(func);
151 sdio_release_host(func);
152
153 /* Power down the card */
154 ret = pm_runtime_put_sync(&func->dev);
155 }
156
157out:
158 return ret;
159}
160
161static void wl1271_sdio_disable_interrupts(struct wl1271 *wl)
162{
163}
164
165static void wl1271_sdio_enable_interrupts(struct wl1271 *wl)
166{
167}
168
169
170static struct wl1271_if_operations sdio_ops = {
171 .read = wl1271_sdio_raw_read,
172 .write = wl1271_sdio_raw_write,
173 .power = wl1271_sdio_set_power,
174 .dev = wl1271_sdio_wl_to_dev,
175 .enable_irq = wl1271_sdio_enable_interrupts,
176 .disable_irq = wl1271_sdio_disable_interrupts,
177};
178
179static void wl1271_fw_wakeup(struct wl1271 *wl)
180{
181 u32 elp_reg;
182
183 elp_reg = ELPCTRL_WAKE_UP;
184 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
185}
186
187static int wl1271_fetch_firmware(struct wl1271 *wl)
188{
189 const struct firmware *fw;
190 int ret;
191
192 ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl));
193
194 if (ret < 0) {
195 wl1271_error("could not get firmware: %d", ret);
196 return ret;
197 }
198
199 if (fw->size % 4) {
200 wl1271_error("firmware size is not multiple of 32 bits: %zu",
201 fw->size);
202 ret = -EILSEQ;
203 goto out;
204 }
205
206 wl->fw_len = fw->size;
207 wl->fw = vmalloc(wl->fw_len);
208
209 if (!wl->fw) {
210 wl1271_error("could not allocate memory for the firmware");
211 ret = -ENOMEM;
212 goto out;
213 }
214
215 memcpy(wl->fw, fw->data, wl->fw_len);
216
217 ret = 0;
218
219out:
220 release_firmware(fw);
221
222 return ret;
223}
224
225static int wl1271_fetch_nvs(struct wl1271 *wl)
226{
227 const struct firmware *fw;
228 int ret;
229
230 ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl));
231
232 if (ret < 0) {
233 wl1271_error("could not get nvs file: %d", ret);
234 return ret;
235 }
236
237 wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL);
238
239 if (!wl->nvs) {
240 wl1271_error("could not allocate memory for the nvs file");
241 ret = -ENOMEM;
242 goto out;
243 }
244
245 wl->nvs_len = fw->size;
246
247out:
248 release_firmware(fw);
249
250 return ret;
251}
252
253static int wl1271_chip_wakeup(struct wl1271 *wl)
254{
255 struct wl1271_partition_set partition;
256 int ret;
257
258 msleep(WL1271_PRE_POWER_ON_SLEEP);
259 ret = wl1271_power_on(wl);
260 if (ret)
261 return ret;
262
263 msleep(WL1271_POWER_ON_SLEEP);
264
265 /* We don't need a real memory partition here, because we only want
266 * to use the registers at this point. */
267 memset(&partition, 0, sizeof(partition));
268 partition.reg.start = REGISTERS_BASE;
269 partition.reg.size = REGISTERS_DOWN_SIZE;
270 wl1271_set_partition(wl, &partition);
271
272 /* ELP module wake up */
273 wl1271_fw_wakeup(wl);
274
275 /* whal_FwCtrl_BootSm() */
276
277 /* 0. read chip id from CHIP_ID */
278 wl->chip.id = wl1271_read32(wl, CHIP_ID_B);
279
280 /* 1. check if chip id is valid */
281
282 switch (wl->chip.id) {
283 case CHIP_ID_1271_PG10:
284 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
285 wl->chip.id);
286 break;
287 case CHIP_ID_1271_PG20:
288 wl1271_notice("chip id 0x%x (1271 PG20)",
289 wl->chip.id);
290 break;
291 default:
292 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
293 return -ENODEV;
294 }
295
296 return ret;
297}
298
299static struct wl1271_partition_set part_down = {
300 .mem = {
301 .start = 0x00000000,
302 .size = 0x000177c0
303 },
304 .reg = {
305 .start = REGISTERS_BASE,
306 .size = 0x00008800
307 },
308 .mem2 = {
309 .start = 0x00000000,
310 .size = 0x00000000
311 },
312 .mem3 = {
313 .start = 0x00000000,
314 .size = 0x00000000
315 },
316};
317
318static int tester(void *data)
319{
320 struct wl1271 *wl = data;
321 struct sdio_func *func = wl_to_func(wl);
322 struct device *pdev = &func->dev;
323 int ret = 0;
324 bool rx_started = 0;
325 bool tx_started = 0;
326 uint8_t *tx_buf, *rx_buf;
327 int test_size = PAGE_SIZE;
328 u32 addr = 0;
329 struct wl1271_partition_set partition;
330
331 /* We assume chip is powered up and firmware fetched */
332
333 memcpy(&partition, &part_down, sizeof(partition));
334 partition.mem.start = addr;
335 wl1271_set_partition(wl, &partition);
336
337 tx_buf = kmalloc(test_size, GFP_KERNEL);
338 rx_buf = kmalloc(test_size, GFP_KERNEL);
339 if (!tx_buf || !rx_buf) {
340 dev_err(pdev,
341 "Could not allocate memory. Test will not run.\n");
342 ret = -ENOMEM;
343 goto free;
344 }
345
346 memset(tx_buf, 0x5a, test_size);
347
348 /* write something in data area so we can read it back */
349 wl1271_write(wl, addr, tx_buf, test_size, false);
350
351 while (!kthread_should_stop()) {
352 if (rx && !rx_started) {
353 dev_info(pdev, "starting rx test\n");
354 rx_started = 1;
355 } else if (!rx && rx_started) {
356 dev_info(pdev, "stopping rx test\n");
357 rx_started = 0;
358 }
359
360 if (tx && !tx_started) {
361 dev_info(pdev, "starting tx test\n");
362 tx_started = 1;
363 } else if (!tx && tx_started) {
364 dev_info(pdev, "stopping tx test\n");
365 tx_started = 0;
366 }
367
368 if (rx_started)
369 wl1271_read(wl, addr, rx_buf, test_size, false);
370
371 if (tx_started)
372 wl1271_write(wl, addr, tx_buf, test_size, false);
373
374 if (!rx_started && !tx_started)
375 msleep(100);
376 }
377
378free:
379 kfree(tx_buf);
380 kfree(rx_buf);
381 return ret;
382}
383
384static int __devinit wl1271_probe(struct sdio_func *func,
385 const struct sdio_device_id *id)
386{
387 const struct wl12xx_platform_data *wlan_data;
388 struct wl1271 *wl;
389 struct wl1271_test *wl_test;
390 int ret = 0;
391
392 /* wl1271 has 2 sdio functions we handle just the wlan part */
393 if (func->num != 0x02)
394 return -ENODEV;
395
396 wl_test = kzalloc(sizeof(struct wl1271_test), GFP_KERNEL);
397 if (!wl_test) {
398 dev_err(&func->dev, "Could not allocate memory\n");
399 return -ENOMEM;
400 }
401
402 wl = &wl_test->wl;
403
404 wl->if_priv = func;
405 wl->if_ops = &sdio_ops;
406
407 /* Grab access to FN0 for ELP reg. */
408 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
409
410 wlan_data = wl12xx_get_platform_data();
411 if (IS_ERR(wlan_data)) {
412 ret = PTR_ERR(wlan_data);
413 dev_err(&func->dev, "missing wlan platform data: %d\n", ret);
414 goto out_free;
415 }
416
417 wl->irq = wlan_data->irq;
418 wl->ref_clock = wlan_data->board_ref_clock;
419
420 sdio_set_drvdata(func, wl_test);
421
422
423 /* power up the device */
424 ret = wl1271_chip_wakeup(wl);
425 if (ret) {
426 dev_err(&func->dev, "could not wake up chip\n");
427 goto out_free;
428 }
429
430 if (wl->fw == NULL) {
431 ret = wl1271_fetch_firmware(wl);
432 if (ret < 0) {
433 dev_err(&func->dev, "firmware fetch error\n");
434 goto out_off;
435 }
436 }
437
438 /* fetch NVS */
439 if (wl->nvs == NULL) {
440 ret = wl1271_fetch_nvs(wl);
441 if (ret < 0) {
442 dev_err(&func->dev, "NVS fetch error\n");
443 goto out_off;
444 }
445 }
446
447 ret = wl1271_load_firmware(wl);
448 if (ret < 0) {
449 dev_err(&func->dev, "firmware load error: %d\n", ret);
450 goto out_free;
451 }
452
453 dev_info(&func->dev, "initialized\n");
454
455 /* I/O testing will be done in the tester thread */
456
457 wl_test->test_task = kthread_run(tester, wl, "sdio_tester");
458 if (IS_ERR(wl_test->test_task)) {
459 dev_err(&func->dev, "unable to create kernel thread\n");
460 ret = PTR_ERR(wl_test->test_task);
461 goto out_free;
462 }
463
464 return 0;
465
466out_off:
467 /* power off the chip */
468 wl1271_power_off(wl);
469
470out_free:
471 kfree(wl_test);
472 return ret;
473}
474
475static void __devexit wl1271_remove(struct sdio_func *func)
476{
477 struct wl1271_test *wl_test = sdio_get_drvdata(func);
478
479 /* stop the I/O test thread */
480 kthread_stop(wl_test->test_task);
481
482 /* power off the chip */
483 wl1271_power_off(&wl_test->wl);
484
485 vfree(wl_test->wl.fw);
486 wl_test->wl.fw = NULL;
487 kfree(wl_test->wl.nvs);
488 wl_test->wl.nvs = NULL;
489
490 kfree(wl_test);
491}
492
493static struct sdio_driver wl1271_sdio_driver = {
494 .name = "wl12xx_sdio_test",
495 .id_table = wl1271_devices,
496 .probe = wl1271_probe,
497 .remove = __devexit_p(wl1271_remove),
498};
499
500static int __init wl1271_init(void)
501{
502 int ret;
503
504 ret = sdio_register_driver(&wl1271_sdio_driver);
505 if (ret < 0)
506 pr_err("failed to register sdio driver: %d\n", ret);
507
508 return ret;
509}
510module_init(wl1271_init);
511
512static void __exit wl1271_exit(void)
513{
514 sdio_unregister_driver(&wl1271_sdio_driver);
515}
516module_exit(wl1271_exit);
517
518MODULE_LICENSE("GPL");
519MODULE_AUTHOR("Roger Quadros <roger.quadros@nokia.com>");
520
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index d332b3f6d0fa..b44c75cd8c1e 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -125,7 +125,6 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
125 /* queue (we use same identifiers for tid's and ac's */ 125 /* queue (we use same identifiers for tid's and ac's */
126 ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); 126 ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
127 desc->tid = ac; 127 desc->tid = ac;
128
129 desc->aid = TX_HW_DEFAULT_AID; 128 desc->aid = TX_HW_DEFAULT_AID;
130 desc->reserved = 0; 129 desc->reserved = 0;
131 130
@@ -228,7 +227,7 @@ static void handle_tx_low_watermark(struct wl1271 *wl)
228 unsigned long flags; 227 unsigned long flags;
229 228
230 if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && 229 if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) &&
231 skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) { 230 wl->tx_queue_count <= WL1271_TX_QUEUE_LOW_WATERMARK) {
232 /* firmware buffer has space, restart queues */ 231 /* firmware buffer has space, restart queues */
233 spin_lock_irqsave(&wl->wl_lock, flags); 232 spin_lock_irqsave(&wl->wl_lock, flags);
234 ieee80211_wake_queues(wl->hw); 233 ieee80211_wake_queues(wl->hw);
@@ -237,6 +236,43 @@ static void handle_tx_low_watermark(struct wl1271 *wl)
237 } 236 }
238} 237}
239 238
239static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
240{
241 struct sk_buff *skb = NULL;
242 unsigned long flags;
243
244 skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VO]);
245 if (skb)
246 goto out;
247 skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_VI]);
248 if (skb)
249 goto out;
250 skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BE]);
251 if (skb)
252 goto out;
253 skb = skb_dequeue(&wl->tx_queue[CONF_TX_AC_BK]);
254
255out:
256 if (skb) {
257 spin_lock_irqsave(&wl->wl_lock, flags);
258 wl->tx_queue_count--;
259 spin_unlock_irqrestore(&wl->wl_lock, flags);
260 }
261
262 return skb;
263}
264
265static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb)
266{
267 unsigned long flags;
268 int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
269
270 skb_queue_head(&wl->tx_queue[q], skb);
271 spin_lock_irqsave(&wl->wl_lock, flags);
272 wl->tx_queue_count++;
273 spin_unlock_irqrestore(&wl->wl_lock, flags);
274}
275
240void wl1271_tx_work_locked(struct wl1271 *wl) 276void wl1271_tx_work_locked(struct wl1271 *wl)
241{ 277{
242 struct sk_buff *skb; 278 struct sk_buff *skb;
@@ -270,7 +306,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
270 wl1271_acx_rate_policies(wl); 306 wl1271_acx_rate_policies(wl);
271 } 307 }
272 308
273 while ((skb = skb_dequeue(&wl->tx_queue))) { 309 while ((skb = wl1271_skb_dequeue(wl))) {
274 if (!woken_up) { 310 if (!woken_up) {
275 ret = wl1271_ps_elp_wakeup(wl, false); 311 ret = wl1271_ps_elp_wakeup(wl, false);
276 if (ret < 0) 312 if (ret < 0)
@@ -284,9 +320,9 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
284 * Aggregation buffer is full. 320 * Aggregation buffer is full.
285 * Flush buffer and try again. 321 * Flush buffer and try again.
286 */ 322 */
287 skb_queue_head(&wl->tx_queue, skb); 323 wl1271_skb_queue_head(wl, skb);
288 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, 324 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
289 buf_offset, true); 325 buf_offset, true);
290 sent_packets = true; 326 sent_packets = true;
291 buf_offset = 0; 327 buf_offset = 0;
292 continue; 328 continue;
@@ -295,7 +331,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
295 * Firmware buffer is full. 331 * Firmware buffer is full.
296 * Queue back last skb, and stop aggregating. 332 * Queue back last skb, and stop aggregating.
297 */ 333 */
298 skb_queue_head(&wl->tx_queue, skb); 334 wl1271_skb_queue_head(wl, skb);
299 /* No work left, avoid scheduling redundant tx work */ 335 /* No work left, avoid scheduling redundant tx work */
300 set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); 336 set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
301 goto out_ack; 337 goto out_ack;
@@ -440,10 +476,13 @@ void wl1271_tx_reset(struct wl1271 *wl)
440 struct sk_buff *skb; 476 struct sk_buff *skb;
441 477
442 /* TX failure */ 478 /* TX failure */
443 while ((skb = skb_dequeue(&wl->tx_queue))) { 479 for (i = 0; i < NUM_TX_QUEUES; i++) {
444 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); 480 while ((skb = skb_dequeue(&wl->tx_queue[i]))) {
445 ieee80211_tx_status(wl->hw, skb); 481 wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
482 ieee80211_tx_status(wl->hw, skb);
483 }
446 } 484 }
485 wl->tx_queue_count = 0;
447 486
448 /* 487 /*
449 * Make sure the driver is at a consistent state, in case this 488 * Make sure the driver is at a consistent state, in case this
@@ -472,8 +511,7 @@ void wl1271_tx_flush(struct wl1271 *wl)
472 mutex_lock(&wl->mutex); 511 mutex_lock(&wl->mutex);
473 wl1271_debug(DEBUG_TX, "flushing tx buffer: %d", 512 wl1271_debug(DEBUG_TX, "flushing tx buffer: %d",
474 wl->tx_frames_cnt); 513 wl->tx_frames_cnt);
475 if ((wl->tx_frames_cnt == 0) && 514 if ((wl->tx_frames_cnt == 0) && (wl->tx_queue_count == 0)) {
476 skb_queue_empty(&wl->tx_queue)) {
477 mutex_unlock(&wl->mutex); 515 mutex_unlock(&wl->mutex);
478 return; 516 return;
479 } 517 }
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 3c836e6063e6..ce3d31f98c55 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -60,31 +60,32 @@ enum {
60 DEBUG_ALL = ~0, 60 DEBUG_ALL = ~0,
61}; 61};
62 62
63#define DEBUG_LEVEL (DEBUG_NONE) 63extern u32 wl12xx_debug_level;
64 64
65#define DEBUG_DUMP_LIMIT 1024 65#define DEBUG_DUMP_LIMIT 1024
66 66
67#define wl1271_error(fmt, arg...) \ 67#define wl1271_error(fmt, arg...) \
68 printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg) 68 pr_err(DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
69 69
70#define wl1271_warning(fmt, arg...) \ 70#define wl1271_warning(fmt, arg...) \
71 printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg) 71 pr_warning(DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
72 72
73#define wl1271_notice(fmt, arg...) \ 73#define wl1271_notice(fmt, arg...) \
74 printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg) 74 pr_info(DRIVER_PREFIX fmt "\n", ##arg)
75 75
76#define wl1271_info(fmt, arg...) \ 76#define wl1271_info(fmt, arg...) \
77 printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg) 77 pr_info(DRIVER_PREFIX fmt "\n", ##arg)
78 78
79#define wl1271_debug(level, fmt, arg...) \ 79#define wl1271_debug(level, fmt, arg...) \
80 do { \ 80 do { \
81 if (level & DEBUG_LEVEL) \ 81 if (level & wl12xx_debug_level) \
82 printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \ 82 pr_debug(DRIVER_PREFIX fmt "\n", ##arg); \
83 } while (0) 83 } while (0)
84 84
85/* TODO: use pr_debug_hex_dump when it will be available */
85#define wl1271_dump(level, prefix, buf, len) \ 86#define wl1271_dump(level, prefix, buf, len) \
86 do { \ 87 do { \
87 if (level & DEBUG_LEVEL) \ 88 if (level & wl12xx_debug_level) \
88 print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ 89 print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
89 DUMP_PREFIX_OFFSET, 16, 1, \ 90 DUMP_PREFIX_OFFSET, 16, 1, \
90 buf, \ 91 buf, \
@@ -94,7 +95,7 @@ enum {
94 95
95#define wl1271_dump_ascii(level, prefix, buf, len) \ 96#define wl1271_dump_ascii(level, prefix, buf, len) \
96 do { \ 97 do { \
97 if (level & DEBUG_LEVEL) \ 98 if (level & wl12xx_debug_level) \
98 print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \ 99 print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
99 DUMP_PREFIX_OFFSET, 16, 1, \ 100 DUMP_PREFIX_OFFSET, 16, 1, \
100 buf, \ 101 buf, \
@@ -174,108 +175,6 @@ struct wl1271_stats {
174 unsigned int excessive_retries; 175 unsigned int excessive_retries;
175}; 176};
176 177
177struct wl1271_debugfs {
178 struct dentry *rootdir;
179 struct dentry *fw_statistics;
180
181 struct dentry *tx_internal_desc_overflow;
182
183 struct dentry *rx_out_of_mem;
184 struct dentry *rx_hdr_overflow;
185 struct dentry *rx_hw_stuck;
186 struct dentry *rx_dropped;
187 struct dentry *rx_fcs_err;
188 struct dentry *rx_xfr_hint_trig;
189 struct dentry *rx_path_reset;
190 struct dentry *rx_reset_counter;
191
192 struct dentry *dma_rx_requested;
193 struct dentry *dma_rx_errors;
194 struct dentry *dma_tx_requested;
195 struct dentry *dma_tx_errors;
196
197 struct dentry *isr_cmd_cmplt;
198 struct dentry *isr_fiqs;
199 struct dentry *isr_rx_headers;
200 struct dentry *isr_rx_mem_overflow;
201 struct dentry *isr_rx_rdys;
202 struct dentry *isr_irqs;
203 struct dentry *isr_tx_procs;
204 struct dentry *isr_decrypt_done;
205 struct dentry *isr_dma0_done;
206 struct dentry *isr_dma1_done;
207 struct dentry *isr_tx_exch_complete;
208 struct dentry *isr_commands;
209 struct dentry *isr_rx_procs;
210 struct dentry *isr_hw_pm_mode_changes;
211 struct dentry *isr_host_acknowledges;
212 struct dentry *isr_pci_pm;
213 struct dentry *isr_wakeups;
214 struct dentry *isr_low_rssi;
215
216 struct dentry *wep_addr_key_count;
217 struct dentry *wep_default_key_count;
218 /* skipping wep.reserved */
219 struct dentry *wep_key_not_found;
220 struct dentry *wep_decrypt_fail;
221 struct dentry *wep_packets;
222 struct dentry *wep_interrupt;
223
224 struct dentry *pwr_ps_enter;
225 struct dentry *pwr_elp_enter;
226 struct dentry *pwr_missing_bcns;
227 struct dentry *pwr_wake_on_host;
228 struct dentry *pwr_wake_on_timer_exp;
229 struct dentry *pwr_tx_with_ps;
230 struct dentry *pwr_tx_without_ps;
231 struct dentry *pwr_rcvd_beacons;
232 struct dentry *pwr_power_save_off;
233 struct dentry *pwr_enable_ps;
234 struct dentry *pwr_disable_ps;
235 struct dentry *pwr_fix_tsf_ps;
236 /* skipping cont_miss_bcns_spread for now */
237 struct dentry *pwr_rcvd_awake_beacons;
238
239 struct dentry *mic_rx_pkts;
240 struct dentry *mic_calc_failure;
241
242 struct dentry *aes_encrypt_fail;
243 struct dentry *aes_decrypt_fail;
244 struct dentry *aes_encrypt_packets;
245 struct dentry *aes_decrypt_packets;
246 struct dentry *aes_encrypt_interrupt;
247 struct dentry *aes_decrypt_interrupt;
248
249 struct dentry *event_heart_beat;
250 struct dentry *event_calibration;
251 struct dentry *event_rx_mismatch;
252 struct dentry *event_rx_mem_empty;
253 struct dentry *event_rx_pool;
254 struct dentry *event_oom_late;
255 struct dentry *event_phy_transmit_error;
256 struct dentry *event_tx_stuck;
257
258 struct dentry *ps_pspoll_timeouts;
259 struct dentry *ps_upsd_timeouts;
260 struct dentry *ps_upsd_max_sptime;
261 struct dentry *ps_upsd_max_apturn;
262 struct dentry *ps_pspoll_max_apturn;
263 struct dentry *ps_pspoll_utilization;
264 struct dentry *ps_upsd_utilization;
265
266 struct dentry *rxpipe_rx_prep_beacon_drop;
267 struct dentry *rxpipe_descr_host_int_trig_rx_data;
268 struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data;
269 struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data;
270 struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
271
272 struct dentry *tx_queue_len;
273
274 struct dentry *retry_count;
275 struct dentry *excessive_retries;
276 struct dentry *gpio_power;
277};
278
279#define NUM_TX_QUEUES 4 178#define NUM_TX_QUEUES 4
280#define NUM_RX_PKT_DESC 8 179#define NUM_RX_PKT_DESC 8
281 180
@@ -393,7 +292,8 @@ struct wl1271 {
393 int session_counter; 292 int session_counter;
394 293
395 /* Frames scheduled for transmission, not handled yet */ 294 /* Frames scheduled for transmission, not handled yet */
396 struct sk_buff_head tx_queue; 295 struct sk_buff_head tx_queue[NUM_TX_QUEUES];
296 int tx_queue_count;
397 297
398 struct work_struct tx_work; 298 struct work_struct tx_work;
399 299
@@ -431,6 +331,9 @@ struct wl1271 {
431 struct wl1271_scan scan; 331 struct wl1271_scan scan;
432 struct delayed_work scan_complete_work; 332 struct delayed_work scan_complete_work;
433 333
334 /* probe-req template for the current AP */
335 struct sk_buff *probereq;
336
434 /* Our association ID */ 337 /* Our association ID */
435 u16 aid; 338 u16 aid;
436 339
@@ -475,7 +378,7 @@ struct wl1271 {
475 int last_rssi_event; 378 int last_rssi_event;
476 379
477 struct wl1271_stats stats; 380 struct wl1271_stats stats;
478 struct wl1271_debugfs debugfs; 381 struct dentry *rootdir;
479 382
480 __le32 buffer_32; 383 __le32 buffer_32;
481 u32 buffer_cmd; 384 u32 buffer_cmd;
diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h
index 184628027213..be21032f4dc1 100644
--- a/drivers/net/wireless/wl12xx/wl12xx_80211.h
+++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h
@@ -2,6 +2,7 @@
2#define __WL12XX_80211_H__ 2#define __WL12XX_80211_H__
3 3
4#include <linux/if_ether.h> /* ETH_ALEN */ 4#include <linux/if_ether.h> /* ETH_ALEN */
5#include <linux/if_arp.h>
5 6
6/* RATES */ 7/* RATES */
7#define IEEE80211_CCK_RATE_1MB 0x02 8#define IEEE80211_CCK_RATE_1MB 0x02
@@ -133,11 +134,17 @@ struct wl12xx_qos_null_data_template {
133 __le16 qos_ctl; 134 __le16 qos_ctl;
134} __packed; 135} __packed;
135 136
136struct wl12xx_probe_req_template { 137struct wl12xx_arp_rsp_template {
137 struct ieee80211_header header; 138 struct ieee80211_hdr_3addr hdr;
138 struct wl12xx_ie_ssid ssid; 139
139 struct wl12xx_ie_rates rates; 140 u8 llc_hdr[sizeof(rfc1042_header)];
140 struct wl12xx_ie_rates ext_rates; 141 u16 llc_type;
142
143 struct arphdr arp_hdr;
144 u8 sender_hw[ETH_ALEN];
145 u32 sender_ip;
146 u8 target_hw[ETH_ALEN];
147 u32 target_ip;
141} __packed; 148} __packed;
142 149
143 150
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 351c0ab4e284..6042228954a7 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -122,6 +122,7 @@
122 122
123/* U-APSD queue for WMM IEs sent by AP */ 123/* U-APSD queue for WMM IEs sent by AP */
124#define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD (1<<7) 124#define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD (1<<7)
125#define IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK 0x0f
125 126
126/* U-APSD queues for WMM IEs sent by STA */ 127/* U-APSD queues for WMM IEs sent by STA */
127#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VO (1<<0) 128#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VO (1<<0)
@@ -535,7 +536,6 @@ struct ieee80211s_hdr {
535 __le32 seqnum; 536 __le32 seqnum;
536 u8 eaddr1[6]; 537 u8 eaddr1[6];
537 u8 eaddr2[6]; 538 u8 eaddr2[6];
538 u8 eaddr3[6];
539} __attribute__ ((packed)); 539} __attribute__ ((packed));
540 540
541/* Mesh flags */ 541/* Mesh flags */
@@ -1290,6 +1290,31 @@ enum ieee80211_key_len {
1290 WLAN_KEY_LEN_AES_CMAC = 16, 1290 WLAN_KEY_LEN_AES_CMAC = 16,
1291}; 1291};
1292 1292
1293/**
1294 * enum - mesh path selection protocol identifier
1295 *
1296 * @IEEE80211_PATH_PROTOCOL_HWMP: the default path selection protocol
1297 * @IEEE80211_PATH_PROTOCOL_VENDOR: a vendor specific protocol that will
1298 * be specified in a vendor specific information element
1299 */
1300enum {
1301 IEEE80211_PATH_PROTOCOL_HWMP = 0,
1302 IEEE80211_PATH_PROTOCOL_VENDOR = 255,
1303};
1304
1305/**
1306 * enum - mesh path selection metric identifier
1307 *
1308 * @IEEE80211_PATH_METRIC_AIRTIME: the default path selection metric
1309 * @IEEE80211_PATH_METRIC_VENDOR: a vendor specific metric that will be
1310 * specified in a vendor specific information element
1311 */
1312enum {
1313 IEEE80211_PATH_METRIC_AIRTIME = 0,
1314 IEEE80211_PATH_METRIC_VENDOR = 255,
1315};
1316
1317
1293/* 1318/*
1294 * IEEE 802.11-2007 7.3.2.9 Country information element 1319 * IEEE 802.11-2007 7.3.2.9 Country information element
1295 * 1320 *
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 380421253d16..2b89b712565b 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -172,10 +172,10 @@
172 * to the specified ISO/IEC 3166-1 alpha2 country code. The core will 172 * to the specified ISO/IEC 3166-1 alpha2 country code. The core will
173 * store this as a valid request and then query userspace for it. 173 * store this as a valid request and then query userspace for it.
174 * 174 *
175 * @NL80211_CMD_GET_MESH_PARAMS: Get mesh networking properties for the 175 * @NL80211_CMD_GET_MESH_CONFIG: Get mesh networking properties for the
176 * interface identified by %NL80211_ATTR_IFINDEX 176 * interface identified by %NL80211_ATTR_IFINDEX
177 * 177 *
178 * @NL80211_CMD_SET_MESH_PARAMS: Set mesh networking properties for the 178 * @NL80211_CMD_SET_MESH_CONFIG: Set mesh networking properties for the
179 * interface identified by %NL80211_ATTR_IFINDEX 179 * interface identified by %NL80211_ATTR_IFINDEX
180 * 180 *
181 * @NL80211_CMD_SET_MGMT_EXTRA_IE: Set extra IEs for management frames. The 181 * @NL80211_CMD_SET_MGMT_EXTRA_IE: Set extra IEs for management frames. The
@@ -399,6 +399,13 @@
399 * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the 399 * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the
400 * network is determined by the network interface. 400 * network is determined by the network interface.
401 * 401 *
402 * @NL80211_CMD_UNPROT_DEAUTHENTICATE: Unprotected deauthentication frame
403 * notification. This event is used to indicate that an unprotected
404 * deauthentication frame was dropped when MFP is in use.
405 * @NL80211_CMD_UNPROT_DISASSOCIATE: Unprotected disassociation frame
406 * notification. This event is used to indicate that an unprotected
407 * disassociation frame was dropped when MFP is in use.
408 *
402 * @NL80211_CMD_MAX: highest used command number 409 * @NL80211_CMD_MAX: highest used command number
403 * @__NL80211_CMD_AFTER_LAST: internal use 410 * @__NL80211_CMD_AFTER_LAST: internal use
404 */ 411 */
@@ -441,8 +448,8 @@ enum nl80211_commands {
441 NL80211_CMD_SET_REG, 448 NL80211_CMD_SET_REG,
442 NL80211_CMD_REQ_SET_REG, 449 NL80211_CMD_REQ_SET_REG,
443 450
444 NL80211_CMD_GET_MESH_PARAMS, 451 NL80211_CMD_GET_MESH_CONFIG,
445 NL80211_CMD_SET_MESH_PARAMS, 452 NL80211_CMD_SET_MESH_CONFIG,
446 453
447 NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */, 454 NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */,
448 455
@@ -508,6 +515,9 @@ enum nl80211_commands {
508 NL80211_CMD_JOIN_MESH, 515 NL80211_CMD_JOIN_MESH,
509 NL80211_CMD_LEAVE_MESH, 516 NL80211_CMD_LEAVE_MESH,
510 517
518 NL80211_CMD_UNPROT_DEAUTHENTICATE,
519 NL80211_CMD_UNPROT_DISASSOCIATE,
520
511 /* add new commands above here */ 521 /* add new commands above here */
512 522
513 /* used to define NL80211_CMD_MAX below */ 523 /* used to define NL80211_CMD_MAX below */
@@ -528,6 +538,10 @@ enum nl80211_commands {
528#define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE 538#define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE
529#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT 539#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT
530 540
541/* source-level API compatibility */
542#define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG
543#define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG
544
531/** 545/**
532 * enum nl80211_attrs - nl80211 netlink attributes 546 * enum nl80211_attrs - nl80211 netlink attributes
533 * 547 *
@@ -773,6 +787,9 @@ enum nl80211_commands {
773 * cache, a wiphy attribute. 787 * cache, a wiphy attribute.
774 * 788 *
775 * @NL80211_ATTR_DURATION: Duration of an operation in milliseconds, u32. 789 * @NL80211_ATTR_DURATION: Duration of an operation in milliseconds, u32.
790 * @NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION: Device attribute that
791 * specifies the maximum duration that can be requested with the
792 * remain-on-channel operation, in milliseconds, u32.
776 * 793 *
777 * @NL80211_ATTR_COOKIE: Generic 64-bit cookie to identify objects. 794 * @NL80211_ATTR_COOKIE: Generic 64-bit cookie to identify objects.
778 * 795 *
@@ -841,6 +858,12 @@ enum nl80211_commands {
841 * the hardware should not be configured to receive on this antenna. 858 * the hardware should not be configured to receive on this antenna.
842 * For a more detailed descripton see @NL80211_ATTR_WIPHY_ANTENNA_TX. 859 * For a more detailed descripton see @NL80211_ATTR_WIPHY_ANTENNA_TX.
843 * 860 *
861 * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX: Bitmap of antennas which are available
862 * for configuration as TX antennas via the above parameters.
863 *
864 * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX: Bitmap of antennas which are available
865 * for configuration as RX antennas via the above parameters.
866 *
844 * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS 867 * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS
845 * 868 *
846 * @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be 869 * @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be
@@ -851,6 +874,13 @@ enum nl80211_commands {
851 * 874 *
852 * @NL80211_ATTR_BSS_HTOPMODE: HT operation mode (u16) 875 * @NL80211_ATTR_BSS_HTOPMODE: HT operation mode (u16)
853 * 876 *
877 * @NL80211_ATTR_KEY_DEFAULT_TYPES: A nested attribute containing flags
878 * attributes, specifying what a key should be set as default as.
879 * See &enum nl80211_key_default_types.
880 *
881 * @NL80211_ATTR_MESH_SETUP: Optional mesh setup parameters. These cannot be
882 * changed once the mesh is active.
883 *
854 * @NL80211_ATTR_MAX: highest attribute number currently defined 884 * @NL80211_ATTR_MAX: highest attribute number currently defined
855 * @__NL80211_ATTR_AFTER_LAST: internal use 885 * @__NL80211_ATTR_AFTER_LAST: internal use
856 */ 886 */
@@ -905,7 +935,7 @@ enum nl80211_attrs {
905 NL80211_ATTR_REG_ALPHA2, 935 NL80211_ATTR_REG_ALPHA2,
906 NL80211_ATTR_REG_RULES, 936 NL80211_ATTR_REG_RULES,
907 937
908 NL80211_ATTR_MESH_PARAMS, 938 NL80211_ATTR_MESH_CONFIG,
909 939
910 NL80211_ATTR_BSS_BASIC_RATES, 940 NL80211_ATTR_BSS_BASIC_RATES,
911 941
@@ -1029,6 +1059,15 @@ enum nl80211_attrs {
1029 1059
1030 NL80211_ATTR_BSS_HT_OPMODE, 1060 NL80211_ATTR_BSS_HT_OPMODE,
1031 1061
1062 NL80211_ATTR_KEY_DEFAULT_TYPES,
1063
1064 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1065
1066 NL80211_ATTR_MESH_SETUP,
1067
1068 NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1069 NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1070
1032 /* add attributes here, update the policy in nl80211.c */ 1071 /* add attributes here, update the policy in nl80211.c */
1033 1072
1034 __NL80211_ATTR_AFTER_LAST, 1073 __NL80211_ATTR_AFTER_LAST,
@@ -1037,6 +1076,7 @@ enum nl80211_attrs {
1037 1076
1038/* source-level API compatibility */ 1077/* source-level API compatibility */
1039#define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION 1078#define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION
1079#define NL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG
1040 1080
1041/* 1081/*
1042 * Allow user space programs to use #ifdef on new attributes by defining them 1082 * Allow user space programs to use #ifdef on new attributes by defining them
@@ -1538,7 +1578,8 @@ enum nl80211_mntr_flags {
1538/** 1578/**
1539 * enum nl80211_meshconf_params - mesh configuration parameters 1579 * enum nl80211_meshconf_params - mesh configuration parameters
1540 * 1580 *
1541 * Mesh configuration parameters 1581 * Mesh configuration parameters. These can be changed while the mesh is
1582 * active.
1542 * 1583 *
1543 * @__NL80211_MESHCONF_INVALID: internal use 1584 * @__NL80211_MESHCONF_INVALID: internal use
1544 * 1585 *
@@ -1561,9 +1602,6 @@ enum nl80211_mntr_flags {
1561 * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh 1602 * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh
1562 * point. 1603 * point.
1563 * 1604 *
1564 * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a
1565 * source mesh point for path selection elements.
1566 *
1567 * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically 1605 * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically
1568 * open peer links when we detect compatible mesh peers. 1606 * open peer links when we detect compatible mesh peers.
1569 * 1607 *
@@ -1590,6 +1628,9 @@ enum nl80211_mntr_flags {
1590 * 1628 *
1591 * @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not 1629 * @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not
1592 * 1630 *
1631 * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a
1632 * source mesh point for path selection elements.
1633 *
1593 * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute 1634 * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
1594 * 1635 *
1595 * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use 1636 * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -1618,6 +1659,39 @@ enum nl80211_meshconf_params {
1618}; 1659};
1619 1660
1620/** 1661/**
1662 * enum nl80211_mesh_setup_params - mesh setup parameters
1663 *
1664 * Mesh setup parameters. These are used to start/join a mesh and cannot be
1665 * changed while the mesh is active.
1666 *
1667 * @__NL80211_MESH_SETUP_INVALID: Internal use
1668 *
1669 * @NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL: Enable this option to use a
1670 * vendor specific path selection algorithm or disable it to use the default
1671 * HWMP.
1672 *
1673 * @NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC: Enable this option to use a
1674 * vendor specific path metric or disable it to use the default Airtime
1675 * metric.
1676 *
1677 * @NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE: A vendor specific information
1678 * element that vendors will use to identify the path selection methods and
1679 * metrics in use.
1680 *
1681 * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
1682 */
1683enum nl80211_mesh_setup_params {
1684 __NL80211_MESH_SETUP_INVALID,
1685 NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL,
1686 NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC,
1687 NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE,
1688
1689 /* keep last */
1690 __NL80211_MESH_SETUP_ATTR_AFTER_LAST,
1691 NL80211_MESH_SETUP_ATTR_MAX = __NL80211_MESH_SETUP_ATTR_AFTER_LAST - 1
1692};
1693
1694/**
1621 * enum nl80211_txq_attr - TX queue parameter attributes 1695 * enum nl80211_txq_attr - TX queue parameter attributes
1622 * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved 1696 * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved
1623 * @NL80211_TXQ_ATTR_QUEUE: TX queue identifier (NL80211_TXQ_Q_*) 1697 * @NL80211_TXQ_ATTR_QUEUE: TX queue identifier (NL80211_TXQ_Q_*)
@@ -1775,6 +1849,23 @@ enum nl80211_wpa_versions {
1775}; 1849};
1776 1850
1777/** 1851/**
1852 * enum nl80211_key_default_types - key default types
1853 * @__NL80211_KEY_DEFAULT_TYPE_INVALID: invalid
1854 * @NL80211_KEY_DEFAULT_TYPE_UNICAST: key should be used as default
1855 * unicast key
1856 * @NL80211_KEY_DEFAULT_TYPE_MULTICAST: key should be used as default
1857 * multicast key
1858 * @NUM_NL80211_KEY_DEFAULT_TYPES: number of default types
1859 */
1860enum nl80211_key_default_types {
1861 __NL80211_KEY_DEFAULT_TYPE_INVALID,
1862 NL80211_KEY_DEFAULT_TYPE_UNICAST,
1863 NL80211_KEY_DEFAULT_TYPE_MULTICAST,
1864
1865 NUM_NL80211_KEY_DEFAULT_TYPES
1866};
1867
1868/**
1778 * enum nl80211_key_attributes - key attributes 1869 * enum nl80211_key_attributes - key attributes
1779 * @__NL80211_KEY_INVALID: invalid 1870 * @__NL80211_KEY_INVALID: invalid
1780 * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of 1871 * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of
@@ -1790,6 +1881,9 @@ enum nl80211_wpa_versions {
1790 * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not 1881 * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not
1791 * specified the default depends on whether a MAC address was 1882 * specified the default depends on whether a MAC address was
1792 * given with the command using the key or not (u32) 1883 * given with the command using the key or not (u32)
1884 * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags
1885 * attributes, specifying what a key should be set as default as.
1886 * See &enum nl80211_key_default_types.
1793 * @__NL80211_KEY_AFTER_LAST: internal 1887 * @__NL80211_KEY_AFTER_LAST: internal
1794 * @NL80211_KEY_MAX: highest key attribute 1888 * @NL80211_KEY_MAX: highest key attribute
1795 */ 1889 */
@@ -1802,6 +1896,7 @@ enum nl80211_key_attributes {
1802 NL80211_KEY_DEFAULT, 1896 NL80211_KEY_DEFAULT,
1803 NL80211_KEY_DEFAULT_MGMT, 1897 NL80211_KEY_DEFAULT_MGMT,
1804 NL80211_KEY_TYPE, 1898 NL80211_KEY_TYPE,
1899 NL80211_KEY_DEFAULT_TYPES,
1805 1900
1806 /* keep last */ 1901 /* keep last */
1807 __NL80211_KEY_AFTER_LAST, 1902 __NL80211_KEY_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0d5979924be3..bcc9f448ec4e 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -649,12 +649,20 @@ struct mesh_config {
649 * struct mesh_setup - 802.11s mesh setup configuration 649 * struct mesh_setup - 802.11s mesh setup configuration
650 * @mesh_id: the mesh ID 650 * @mesh_id: the mesh ID
651 * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes 651 * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes
652 * @path_sel_proto: which path selection protocol to use
653 * @path_metric: which metric to use
654 * @vendor_ie: vendor information elements (optional)
655 * @vendor_ie_len: length of vendor information elements
652 * 656 *
653 * These parameters are fixed when the mesh is created. 657 * These parameters are fixed when the mesh is created.
654 */ 658 */
655struct mesh_setup { 659struct mesh_setup {
656 const u8 *mesh_id; 660 const u8 *mesh_id;
657 u8 mesh_id_len; 661 u8 mesh_id_len;
662 u8 path_sel_proto;
663 u8 path_metric;
664 const u8 *vendor_ie;
665 u8 vendor_ie_len;
658}; 666};
659 667
660/** 668/**
@@ -1096,9 +1104,9 @@ struct cfg80211_pmksa {
1096 * @get_mpath: get a mesh path for the given parameters 1104 * @get_mpath: get a mesh path for the given parameters
1097 * @dump_mpath: dump mesh path callback -- resume dump at index @idx 1105 * @dump_mpath: dump mesh path callback -- resume dump at index @idx
1098 * 1106 *
1099 * @get_mesh_params: Put the current mesh parameters into *params 1107 * @get_mesh_config: Get the current mesh configuration
1100 * 1108 *
1101 * @update_mesh_params: Update mesh parameters on a running mesh. 1109 * @update_mesh_config: Update mesh parameters on a running mesh.
1102 * The mask is a bitfield which tells us which parameters to 1110 * The mask is a bitfield which tells us which parameters to
1103 * set, and which to leave alone. 1111 * set, and which to leave alone.
1104 * 1112 *
@@ -1211,7 +1219,7 @@ struct cfg80211_ops {
1211 u8 key_index, bool pairwise, const u8 *mac_addr); 1219 u8 key_index, bool pairwise, const u8 *mac_addr);
1212 int (*set_default_key)(struct wiphy *wiphy, 1220 int (*set_default_key)(struct wiphy *wiphy,
1213 struct net_device *netdev, 1221 struct net_device *netdev,
1214 u8 key_index); 1222 u8 key_index, bool unicast, bool multicast);
1215 int (*set_default_mgmt_key)(struct wiphy *wiphy, 1223 int (*set_default_mgmt_key)(struct wiphy *wiphy,
1216 struct net_device *netdev, 1224 struct net_device *netdev,
1217 u8 key_index); 1225 u8 key_index);
@@ -1246,10 +1254,10 @@ struct cfg80211_ops {
1246 int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, 1254 int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev,
1247 int idx, u8 *dst, u8 *next_hop, 1255 int idx, u8 *dst, u8 *next_hop,
1248 struct mpath_info *pinfo); 1256 struct mpath_info *pinfo);
1249 int (*get_mesh_params)(struct wiphy *wiphy, 1257 int (*get_mesh_config)(struct wiphy *wiphy,
1250 struct net_device *dev, 1258 struct net_device *dev,
1251 struct mesh_config *conf); 1259 struct mesh_config *conf);
1252 int (*update_mesh_params)(struct wiphy *wiphy, 1260 int (*update_mesh_config)(struct wiphy *wiphy,
1253 struct net_device *dev, u32 mask, 1261 struct net_device *dev, u32 mask,
1254 const struct mesh_config *nconf); 1262 const struct mesh_config *nconf);
1255 int (*join_mesh)(struct wiphy *wiphy, struct net_device *dev, 1263 int (*join_mesh)(struct wiphy *wiphy, struct net_device *dev,
@@ -1393,6 +1401,8 @@ struct cfg80211_ops {
1393 * control port protocol ethertype. The device also honours the 1401 * control port protocol ethertype. The device also honours the
1394 * control_port_no_encrypt flag. 1402 * control_port_no_encrypt flag.
1395 * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. 1403 * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN.
1404 * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate
1405 * unicast and multicast TX keys.
1396 */ 1406 */
1397enum wiphy_flags { 1407enum wiphy_flags {
1398 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), 1408 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -1404,6 +1414,7 @@ enum wiphy_flags {
1404 WIPHY_FLAG_4ADDR_STATION = BIT(6), 1414 WIPHY_FLAG_4ADDR_STATION = BIT(6),
1405 WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), 1415 WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7),
1406 WIPHY_FLAG_IBSS_RSN = BIT(8), 1416 WIPHY_FLAG_IBSS_RSN = BIT(8),
1417 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9),
1407}; 1418};
1408 1419
1409struct mac_address { 1420struct mac_address {
@@ -1416,7 +1427,9 @@ struct ieee80211_txrx_stypes {
1416 1427
1417/** 1428/**
1418 * struct wiphy - wireless hardware description 1429 * struct wiphy - wireless hardware description
1419 * @reg_notifier: the driver's regulatory notification callback 1430 * @reg_notifier: the driver's regulatory notification callback,
1431 * note that if your driver uses wiphy_apply_custom_regulatory()
1432 * the reg_notifier's request can be passed as NULL
1420 * @regd: the driver's regulatory domain, if one was requested via 1433 * @regd: the driver's regulatory domain, if one was requested via
1421 * the regulatory_hint() API. This can be used by the driver 1434 * the regulatory_hint() API. This can be used by the driver
1422 * on the reg_notifier() if it chooses to ignore future 1435 * on the reg_notifier() if it chooses to ignore future
@@ -1468,6 +1481,17 @@ struct ieee80211_txrx_stypes {
1468 * @mgmt_stypes: bitmasks of frame subtypes that can be subscribed to or 1481 * @mgmt_stypes: bitmasks of frame subtypes that can be subscribed to or
1469 * transmitted through nl80211, points to an array indexed by interface 1482 * transmitted through nl80211, points to an array indexed by interface
1470 * type 1483 * type
1484 *
1485 * @available_antennas_tx: bitmap of antennas which are available to be
1486 * configured as TX antennas. Antenna configuration commands will be
1487 * rejected unless this or @available_antennas_rx is set.
1488 *
1489 * @available_antennas_rx: bitmap of antennas which are available to be
1490 * configured as RX antennas. Antenna configuration commands will be
1491 * rejected unless this or @available_antennas_tx is set.
1492 *
1493 * @max_remain_on_channel_duration: Maximum time a remain-on-channel operation
1494 * may request, if implemented.
1471 */ 1495 */
1472struct wiphy { 1496struct wiphy {
1473 /* assign these fields before you register the wiphy */ 1497 /* assign these fields before you register the wiphy */
@@ -1505,8 +1529,13 @@ struct wiphy {
1505 char fw_version[ETHTOOL_BUSINFO_LEN]; 1529 char fw_version[ETHTOOL_BUSINFO_LEN];
1506 u32 hw_version; 1530 u32 hw_version;
1507 1531
1532 u16 max_remain_on_channel_duration;
1533
1508 u8 max_num_pmkids; 1534 u8 max_num_pmkids;
1509 1535
1536 u32 available_antennas_tx;
1537 u32 available_antennas_rx;
1538
1510 /* If multiple wiphys are registered and you're handed e.g. 1539 /* If multiple wiphys are registered and you're handed e.g.
1511 * a regular netdev with assigned ieee80211_ptr, you won't 1540 * a regular netdev with assigned ieee80211_ptr, you won't
1512 * know whether it points to a wiphy your driver has registered 1541 * know whether it points to a wiphy your driver has registered
@@ -2347,6 +2376,32 @@ void __cfg80211_send_disassoc(struct net_device *dev, const u8 *buf,
2347 size_t len); 2376 size_t len);
2348 2377
2349/** 2378/**
2379 * cfg80211_send_unprot_deauth - notification of unprotected deauthentication
2380 * @dev: network device
2381 * @buf: deauthentication frame (header + body)
2382 * @len: length of the frame data
2383 *
2384 * This function is called whenever a received Deauthentication frame has been
2385 * dropped in station mode because of MFP being used but the Deauthentication
2386 * frame was not protected. This function may sleep.
2387 */
2388void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
2389 size_t len);
2390
2391/**
2392 * cfg80211_send_unprot_disassoc - notification of unprotected disassociation
2393 * @dev: network device
2394 * @buf: disassociation frame (header + body)
2395 * @len: length of the frame data
2396 *
2397 * This function is called whenever a received Disassociation frame has been
2398 * dropped in station mode because of MFP being used but the Disassociation
2399 * frame was not protected. This function may sleep.
2400 */
2401void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
2402 size_t len);
2403
2404/**
2350 * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP) 2405 * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP)
2351 * @dev: network device 2406 * @dev: network device
2352 * @addr: The source MAC address of the frame 2407 * @addr: The source MAC address of the frame
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index e411cf87fb41..69ded1ee49ce 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2435,6 +2435,7 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
2435 * ieee80211_start_tx_ba_session - Start a tx Block Ack session. 2435 * ieee80211_start_tx_ba_session - Start a tx Block Ack session.
2436 * @sta: the station for which to start a BA session 2436 * @sta: the station for which to start a BA session
2437 * @tid: the TID to BA on. 2437 * @tid: the TID to BA on.
2438 * @timeout: session timeout value (in TUs)
2438 * 2439 *
2439 * Return: success if addBA request was sent, failure otherwise 2440 * Return: success if addBA request was sent, failure otherwise
2440 * 2441 *
@@ -2442,7 +2443,8 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
2442 * the need to start aggregation on a certain RA/TID, the session level 2443 * the need to start aggregation on a certain RA/TID, the session level
2443 * will be managed by the mac80211. 2444 * will be managed by the mac80211.
2444 */ 2445 */
2445int ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, u16 tid); 2446int ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, u16 tid,
2447 u16 timeout);
2446 2448
2447/** 2449/**
2448 * ieee80211_start_tx_ba_cb_irqsafe - low level driver ready to aggregate. 2450 * ieee80211_start_tx_ba_cb_irqsafe - low level driver ready to aggregate.
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index d4679b265ba8..9cc472c6a6a5 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -342,10 +342,11 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
342 /* send AddBA request */ 342 /* send AddBA request */
343 ieee80211_send_addba_request(sdata, sta->sta.addr, tid, 343 ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
344 tid_tx->dialog_token, start_seq_num, 344 tid_tx->dialog_token, start_seq_num,
345 0x40, 5000); 345 0x40, tid_tx->timeout);
346} 346}
347 347
348int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) 348int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
349 u16 timeout)
349{ 350{
350 struct sta_info *sta = container_of(pubsta, struct sta_info, sta); 351 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
351 struct ieee80211_sub_if_data *sdata = sta->sdata; 352 struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -420,6 +421,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
420 skb_queue_head_init(&tid_tx->pending); 421 skb_queue_head_init(&tid_tx->pending);
421 __set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); 422 __set_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
422 423
424 tid_tx->timeout = timeout;
425
423 /* Tx timer */ 426 /* Tx timer */
424 tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired; 427 tid_tx->addba_resp_timer.function = sta_addba_resp_timer_expired;
425 tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid]; 428 tid_tx->addba_resp_timer.data = (unsigned long)&sta->timer_to_tid[tid];
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c30b8b72eedb..5892b0302454 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -295,11 +295,12 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
295 295
296static int ieee80211_config_default_key(struct wiphy *wiphy, 296static int ieee80211_config_default_key(struct wiphy *wiphy,
297 struct net_device *dev, 297 struct net_device *dev,
298 u8 key_idx) 298 u8 key_idx, bool uni,
299 bool multi)
299{ 300{
300 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 301 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
301 302
302 ieee80211_set_default_key(sdata, key_idx); 303 ieee80211_set_default_key(sdata, key_idx, uni, multi);
303 304
304 return 0; 305 return 0;
305} 306}
@@ -983,7 +984,7 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
983 return 0; 984 return 0;
984} 985}
985 986
986static int ieee80211_get_mesh_params(struct wiphy *wiphy, 987static int ieee80211_get_mesh_config(struct wiphy *wiphy,
987 struct net_device *dev, 988 struct net_device *dev,
988 struct mesh_config *conf) 989 struct mesh_config *conf)
989{ 990{
@@ -999,7 +1000,37 @@ static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
999 return (mask >> (parm-1)) & 0x1; 1000 return (mask >> (parm-1)) & 0x1;
1000} 1001}
1001 1002
1002static int ieee80211_update_mesh_params(struct wiphy *wiphy, 1003static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
1004 const struct mesh_setup *setup)
1005{
1006 u8 *new_ie;
1007 const u8 *old_ie;
1008
1009 /* first allocate the new vendor information element */
1010 new_ie = NULL;
1011 old_ie = ifmsh->vendor_ie;
1012
1013 ifmsh->vendor_ie_len = setup->vendor_ie_len;
1014 if (setup->vendor_ie_len) {
1015 new_ie = kmemdup(setup->vendor_ie, setup->vendor_ie_len,
1016 GFP_KERNEL);
1017 if (!new_ie)
1018 return -ENOMEM;
1019 }
1020
1021 /* now copy the rest of the setup parameters */
1022 ifmsh->mesh_id_len = setup->mesh_id_len;
1023 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
1024 ifmsh->mesh_pp_id = setup->path_sel_proto;
1025 ifmsh->mesh_pm_id = setup->path_metric;
1026 ifmsh->vendor_ie = new_ie;
1027
1028 kfree(old_ie);
1029
1030 return 0;
1031}
1032
1033static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1003 struct net_device *dev, u32 mask, 1034 struct net_device *dev, u32 mask,
1004 const struct mesh_config *nconf) 1035 const struct mesh_config *nconf)
1005{ 1036{
@@ -1058,11 +1089,12 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
1058{ 1089{
1059 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1090 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1060 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 1091 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
1092 int err;
1061 1093
1062 memcpy(&sdata->u.mesh.mshcfg, conf, sizeof(struct mesh_config)); 1094 memcpy(&ifmsh->mshcfg, conf, sizeof(struct mesh_config));
1063 ifmsh->mesh_id_len = setup->mesh_id_len; 1095 err = copy_mesh_setup(ifmsh, setup);
1064 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); 1096 if (err)
1065 1097 return err;
1066 ieee80211_start_mesh(sdata); 1098 ieee80211_start_mesh(sdata);
1067 1099
1068 return 0; 1100 return 0;
@@ -1638,6 +1670,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1638 case NL80211_IFTYPE_AP: 1670 case NL80211_IFTYPE_AP:
1639 case NL80211_IFTYPE_AP_VLAN: 1671 case NL80211_IFTYPE_AP_VLAN:
1640 case NL80211_IFTYPE_P2P_GO: 1672 case NL80211_IFTYPE_P2P_GO:
1673 case NL80211_IFTYPE_MESH_POINT:
1641 if (!ieee80211_is_action(mgmt->frame_control) || 1674 if (!ieee80211_is_action(mgmt->frame_control) ||
1642 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) 1675 mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
1643 break; 1676 break;
@@ -1786,8 +1819,8 @@ struct cfg80211_ops mac80211_config_ops = {
1786 .change_mpath = ieee80211_change_mpath, 1819 .change_mpath = ieee80211_change_mpath,
1787 .get_mpath = ieee80211_get_mpath, 1820 .get_mpath = ieee80211_get_mpath,
1788 .dump_mpath = ieee80211_dump_mpath, 1821 .dump_mpath = ieee80211_dump_mpath,
1789 .update_mesh_params = ieee80211_update_mesh_params, 1822 .update_mesh_config = ieee80211_update_mesh_config,
1790 .get_mesh_params = ieee80211_get_mesh_params, 1823 .get_mesh_config = ieee80211_get_mesh_config,
1791 .join_mesh = ieee80211_join_mesh, 1824 .join_mesh = ieee80211_join_mesh,
1792 .leave_mesh = ieee80211_leave_mesh, 1825 .leave_mesh = ieee80211_leave_mesh,
1793#endif 1826#endif
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 5822a6ce7671..f7ef3477c24a 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -274,7 +274,8 @@ void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
274 debugfs_remove_recursive(key->debugfs.dir); 274 debugfs_remove_recursive(key->debugfs.dir);
275 key->debugfs.dir = NULL; 275 key->debugfs.dir = NULL;
276} 276}
277void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata) 277
278void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
278{ 279{
279 char buf[50]; 280 char buf[50];
280 struct ieee80211_key *key; 281 struct ieee80211_key *key;
@@ -282,25 +283,29 @@ void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
282 if (!sdata->debugfs.dir) 283 if (!sdata->debugfs.dir)
283 return; 284 return;
284 285
285 /* this is running under the key lock */ 286 lockdep_assert_held(&sdata->local->key_mtx);
286 287
287 key = sdata->default_key; 288 if (sdata->default_unicast_key) {
288 if (key) { 289 key = sdata->default_unicast_key;
289 sprintf(buf, "../keys/%d", key->debugfs.cnt); 290 sprintf(buf, "../keys/%d", key->debugfs.cnt);
290 sdata->debugfs.default_key = 291 sdata->debugfs.default_unicast_key =
291 debugfs_create_symlink("default_key", 292 debugfs_create_symlink("default_unicast_key",
292 sdata->debugfs.dir, buf); 293 sdata->debugfs.dir, buf);
293 } else 294 } else {
294 ieee80211_debugfs_key_remove_default(sdata); 295 debugfs_remove(sdata->debugfs.default_unicast_key);
295} 296 sdata->debugfs.default_unicast_key = NULL;
296 297 }
297void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
298{
299 if (!sdata)
300 return;
301 298
302 debugfs_remove(sdata->debugfs.default_key); 299 if (sdata->default_multicast_key) {
303 sdata->debugfs.default_key = NULL; 300 key = sdata->default_multicast_key;
301 sprintf(buf, "../keys/%d", key->debugfs.cnt);
302 sdata->debugfs.default_multicast_key =
303 debugfs_create_symlink("default_multicast_key",
304 sdata->debugfs.dir, buf);
305 } else {
306 debugfs_remove(sdata->debugfs.default_multicast_key);
307 sdata->debugfs.default_multicast_key = NULL;
308 }
304} 309}
305 310
306void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata) 311void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/debugfs_key.h b/net/mac80211/debugfs_key.h
index 54717b4e1371..32adc77e9c77 100644
--- a/net/mac80211/debugfs_key.h
+++ b/net/mac80211/debugfs_key.h
@@ -4,8 +4,7 @@
4#ifdef CONFIG_MAC80211_DEBUGFS 4#ifdef CONFIG_MAC80211_DEBUGFS
5void ieee80211_debugfs_key_add(struct ieee80211_key *key); 5void ieee80211_debugfs_key_add(struct ieee80211_key *key);
6void ieee80211_debugfs_key_remove(struct ieee80211_key *key); 6void ieee80211_debugfs_key_remove(struct ieee80211_key *key);
7void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata); 7void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata);
8void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata);
9void ieee80211_debugfs_key_add_mgmt_default( 8void ieee80211_debugfs_key_add_mgmt_default(
10 struct ieee80211_sub_if_data *sdata); 9 struct ieee80211_sub_if_data *sdata);
11void ieee80211_debugfs_key_remove_mgmt_default( 10void ieee80211_debugfs_key_remove_mgmt_default(
@@ -17,10 +16,7 @@ static inline void ieee80211_debugfs_key_add(struct ieee80211_key *key)
17{} 16{}
18static inline void ieee80211_debugfs_key_remove(struct ieee80211_key *key) 17static inline void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
19{} 18{}
20static inline void ieee80211_debugfs_key_add_default( 19static inline void ieee80211_debugfs_key_update_default(
21 struct ieee80211_sub_if_data *sdata)
22{}
23static inline void ieee80211_debugfs_key_remove_default(
24 struct ieee80211_sub_if_data *sdata) 20 struct ieee80211_sub_if_data *sdata)
25{} 21{}
26static inline void ieee80211_debugfs_key_add_mgmt_default( 22static inline void ieee80211_debugfs_key_add_mgmt_default(
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 8bb5af85f469..c04a1396cf8d 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -189,7 +189,7 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu
189 189
190 if (tx) { 190 if (tx) {
191 if (start) 191 if (start)
192 ret = ieee80211_start_tx_ba_session(&sta->sta, tid); 192 ret = ieee80211_start_tx_ba_session(&sta->sta, tid, 5000);
193 else 193 else
194 ret = ieee80211_stop_tx_ba_session(&sta->sta, tid); 194 ret = ieee80211_stop_tx_ba_session(&sta->sta, tid);
195 } else { 195 } else {
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 4244554d218a..af0c4398cceb 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -367,7 +367,7 @@ static inline void drv_reset_tsf(struct ieee80211_local *local)
367 367
368static inline int drv_tx_last_beacon(struct ieee80211_local *local) 368static inline int drv_tx_last_beacon(struct ieee80211_local *local)
369{ 369{
370 int ret = 1; 370 int ret = 0; /* default unsuported op for less congestion */
371 371
372 might_sleep(); 372 might_sleep();
373 373
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 72499fe5fc36..eadaa243a3da 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -484,6 +484,8 @@ struct ieee80211_if_mesh {
484 struct mesh_config mshcfg; 484 struct mesh_config mshcfg;
485 u32 mesh_seqnum; 485 u32 mesh_seqnum;
486 bool accepting_plinks; 486 bool accepting_plinks;
487 const u8 *vendor_ie;
488 u8 vendor_ie_len;
487}; 489};
488 490
489#ifdef CONFIG_MAC80211_MESH 491#ifdef CONFIG_MAC80211_MESH
@@ -557,7 +559,7 @@ struct ieee80211_sub_if_data {
557 unsigned int fragment_next; 559 unsigned int fragment_next;
558 560
559 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; 561 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
560 struct ieee80211_key *default_key; 562 struct ieee80211_key *default_unicast_key, *default_multicast_key;
561 struct ieee80211_key *default_mgmt_key; 563 struct ieee80211_key *default_mgmt_key;
562 564
563 u16 sequence_number; 565 u16 sequence_number;
@@ -585,9 +587,7 @@ struct ieee80211_sub_if_data {
585 struct ieee80211_if_vlan vlan; 587 struct ieee80211_if_vlan vlan;
586 struct ieee80211_if_managed mgd; 588 struct ieee80211_if_managed mgd;
587 struct ieee80211_if_ibss ibss; 589 struct ieee80211_if_ibss ibss;
588#ifdef CONFIG_MAC80211_MESH
589 struct ieee80211_if_mesh mesh; 590 struct ieee80211_if_mesh mesh;
590#endif
591 u32 mntr_flags; 591 u32 mntr_flags;
592 } u; 592 } u;
593 593
@@ -595,7 +595,8 @@ struct ieee80211_sub_if_data {
595 struct { 595 struct {
596 struct dentry *dir; 596 struct dentry *dir;
597 struct dentry *subdir_stations; 597 struct dentry *subdir_stations;
598 struct dentry *default_key; 598 struct dentry *default_unicast_key;
599 struct dentry *default_multicast_key;
599 struct dentry *default_mgmt_key; 600 struct dentry *default_mgmt_key;
600 } debugfs; 601 } debugfs;
601#endif 602#endif
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 72df1ca7299b..84cf9196820f 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -178,7 +178,7 @@ void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
178EXPORT_SYMBOL_GPL(ieee80211_key_removed); 178EXPORT_SYMBOL_GPL(ieee80211_key_removed);
179 179
180static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, 180static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
181 int idx) 181 int idx, bool uni, bool multi)
182{ 182{
183 struct ieee80211_key *key = NULL; 183 struct ieee80211_key *key = NULL;
184 184
@@ -187,18 +187,19 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
187 if (idx >= 0 && idx < NUM_DEFAULT_KEYS) 187 if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
188 key = sdata->keys[idx]; 188 key = sdata->keys[idx];
189 189
190 rcu_assign_pointer(sdata->default_key, key); 190 if (uni)
191 rcu_assign_pointer(sdata->default_unicast_key, key);
192 if (multi)
193 rcu_assign_pointer(sdata->default_multicast_key, key);
191 194
192 if (key) { 195 ieee80211_debugfs_key_update_default(sdata);
193 ieee80211_debugfs_key_remove_default(key->sdata);
194 ieee80211_debugfs_key_add_default(key->sdata);
195 }
196} 196}
197 197
198void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx) 198void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
199 bool uni, bool multi)
199{ 200{
200 mutex_lock(&sdata->local->key_mtx); 201 mutex_lock(&sdata->local->key_mtx);
201 __ieee80211_set_default_key(sdata, idx); 202 __ieee80211_set_default_key(sdata, idx, uni, multi);
202 mutex_unlock(&sdata->local->key_mtx); 203 mutex_unlock(&sdata->local->key_mtx);
203} 204}
204 205
@@ -215,10 +216,7 @@ __ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
215 216
216 rcu_assign_pointer(sdata->default_mgmt_key, key); 217 rcu_assign_pointer(sdata->default_mgmt_key, key);
217 218
218 if (key) { 219 ieee80211_debugfs_key_update_default(sdata);
219 ieee80211_debugfs_key_remove_mgmt_default(key->sdata);
220 ieee80211_debugfs_key_add_mgmt_default(key->sdata);
221 }
222} 220}
223 221
224void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, 222void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
@@ -236,7 +234,8 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
236 struct ieee80211_key *old, 234 struct ieee80211_key *old,
237 struct ieee80211_key *new) 235 struct ieee80211_key *new)
238{ 236{
239 int idx, defkey, defmgmtkey; 237 int idx;
238 bool defunikey, defmultikey, defmgmtkey;
240 239
241 if (new) 240 if (new)
242 list_add(&new->list, &sdata->key_list); 241 list_add(&new->list, &sdata->key_list);
@@ -257,17 +256,24 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
257 else 256 else
258 idx = new->conf.keyidx; 257 idx = new->conf.keyidx;
259 258
260 defkey = old && sdata->default_key == old; 259 defunikey = old && sdata->default_unicast_key == old;
260 defmultikey = old && sdata->default_multicast_key == old;
261 defmgmtkey = old && sdata->default_mgmt_key == old; 261 defmgmtkey = old && sdata->default_mgmt_key == old;
262 262
263 if (defkey && !new) 263 if (defunikey && !new)
264 __ieee80211_set_default_key(sdata, -1); 264 __ieee80211_set_default_key(sdata, -1, true, false);
265 if (defmultikey && !new)
266 __ieee80211_set_default_key(sdata, -1, false, true);
265 if (defmgmtkey && !new) 267 if (defmgmtkey && !new)
266 __ieee80211_set_default_mgmt_key(sdata, -1); 268 __ieee80211_set_default_mgmt_key(sdata, -1);
267 269
268 rcu_assign_pointer(sdata->keys[idx], new); 270 rcu_assign_pointer(sdata->keys[idx], new);
269 if (defkey && new) 271 if (defunikey && new)
270 __ieee80211_set_default_key(sdata, new->conf.keyidx); 272 __ieee80211_set_default_key(sdata, new->conf.keyidx,
273 true, false);
274 if (defmultikey && new)
275 __ieee80211_set_default_key(sdata, new->conf.keyidx,
276 false, true);
271 if (defmgmtkey && new) 277 if (defmgmtkey && new)
272 __ieee80211_set_default_mgmt_key(sdata, 278 __ieee80211_set_default_mgmt_key(sdata,
273 new->conf.keyidx); 279 new->conf.keyidx);
@@ -509,11 +515,12 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
509 515
510 mutex_lock(&sdata->local->key_mtx); 516 mutex_lock(&sdata->local->key_mtx);
511 517
512 ieee80211_debugfs_key_remove_default(sdata);
513 ieee80211_debugfs_key_remove_mgmt_default(sdata); 518 ieee80211_debugfs_key_remove_mgmt_default(sdata);
514 519
515 list_for_each_entry_safe(key, tmp, &sdata->key_list, list) 520 list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
516 __ieee80211_key_free(key); 521 __ieee80211_key_free(key);
517 522
523 ieee80211_debugfs_key_update_default(sdata);
524
518 mutex_unlock(&sdata->local->key_mtx); 525 mutex_unlock(&sdata->local->key_mtx);
519} 526}
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 0db1c0f5f697..8106aa1b7466 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -138,7 +138,8 @@ int __must_check ieee80211_key_link(struct ieee80211_key *key,
138 struct sta_info *sta); 138 struct sta_info *sta);
139void ieee80211_key_free(struct ieee80211_local *local, 139void ieee80211_key_free(struct ieee80211_local *local,
140 struct ieee80211_key *key); 140 struct ieee80211_key *key);
141void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); 141void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
142 bool uni, bool multi);
142void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, 143void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
143 int idx); 144 int idx);
144void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata); 145void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 973fee9f7d69..a21d049caf19 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -484,6 +484,10 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
484 BIT(IEEE80211_STYPE_DEAUTH >> 4) | 484 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
485 BIT(IEEE80211_STYPE_ACTION >> 4), 485 BIT(IEEE80211_STYPE_ACTION >> 4),
486 }, 486 },
487 [NL80211_IFTYPE_MESH_POINT] = {
488 .tx = 0xffff,
489 .rx = BIT(IEEE80211_STYPE_ACTION >> 4),
490 },
487}; 491};
488 492
489struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, 493struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
@@ -517,10 +521,15 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
517 521
518 wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes; 522 wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes;
519 523
524 wiphy->privid = mac80211_wiphy_privid;
525
520 wiphy->flags |= WIPHY_FLAG_NETNS_OK | 526 wiphy->flags |= WIPHY_FLAG_NETNS_OK |
521 WIPHY_FLAG_4ADDR_AP | 527 WIPHY_FLAG_4ADDR_AP |
522 WIPHY_FLAG_4ADDR_STATION; 528 WIPHY_FLAG_4ADDR_STATION |
523 wiphy->privid = mac80211_wiphy_privid; 529 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
530
531 if (!ops->set_key)
532 wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
524 533
525 wiphy->bss_priv_size = sizeof(struct ieee80211_bss); 534 wiphy->bss_priv_size = sizeof(struct ieee80211_bss);
526 535
@@ -740,6 +749,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
740 } 749 }
741 } 750 }
742 751
752 local->hw.wiphy->max_remain_on_channel_duration = 5000;
753
743 result = wiphy_register(local->hw.wiphy); 754 result = wiphy_register(local->hw.wiphy);
744 if (result < 0) 755 if (result < 0)
745 goto fail_wiphy_register; 756 goto fail_wiphy_register;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 63e1188d5062..ca3af4685b0a 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -124,15 +124,6 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
124 ieee80211_mesh_housekeeping_timer((unsigned long) sdata); 124 ieee80211_mesh_housekeeping_timer((unsigned long) sdata);
125} 125}
126 126
127void mesh_ids_set_default(struct ieee80211_if_mesh *sta)
128{
129 sta->mesh_pp_id = 0; /* HWMP */
130 sta->mesh_pm_id = 0; /* Airtime */
131 sta->mesh_cc_id = 0; /* Disabled */
132 sta->mesh_sp_id = 0; /* Neighbor Offset */
133 sta->mesh_auth_id = 0; /* Disabled */
134}
135
136int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 127int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
137{ 128{
138 int i; 129 int i;
@@ -287,6 +278,13 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
287 *pos++ |= sdata->u.mesh.accepting_plinks ? 278 *pos++ |= sdata->u.mesh.accepting_plinks ?
288 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 279 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
289 *pos++ = 0x00; 280 *pos++ = 0x00;
281
282 if (sdata->u.mesh.vendor_ie) {
283 int len = sdata->u.mesh.vendor_ie_len;
284 const u8 *data = sdata->u.mesh.vendor_ie;
285 if (skb_tailroom(skb) > len)
286 memcpy(skb_put(skb, len), data, len);
287 }
290} 288}
291 289
292u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl) 290u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl)
@@ -412,39 +410,33 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
412 * ieee80211_new_mesh_header - create a new mesh header 410 * ieee80211_new_mesh_header - create a new mesh header
413 * @meshhdr: uninitialized mesh header 411 * @meshhdr: uninitialized mesh header
414 * @sdata: mesh interface to be used 412 * @sdata: mesh interface to be used
415 * @addr4: addr4 of the mesh frame (1st in ae header) 413 * @addr4or5: 1st address in the ae header, which may correspond to address 4
416 * may be NULL 414 * (if addr6 is NULL) or address 5 (if addr6 is present). It may
417 * @addr5: addr5 of the mesh frame (1st or 2nd in ae header) 415 * be NULL.
418 * may be NULL unless addr6 is present 416 * @addr6: 2nd address in the ae header, which corresponds to addr6 of the
419 * @addr6: addr6 of the mesh frame (2nd or 3rd in ae header) 417 * mesh frame
420 * may be NULL unless addr5 is present
421 * 418 *
422 * Return the header length. 419 * Return the header length.
423 */ 420 */
424int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 421int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
425 struct ieee80211_sub_if_data *sdata, char *addr4, 422 struct ieee80211_sub_if_data *sdata, char *addr4or5,
426 char *addr5, char *addr6) 423 char *addr6)
427{ 424{
428 int aelen = 0; 425 int aelen = 0;
426 BUG_ON(!addr4or5 && addr6);
429 memset(meshhdr, 0, sizeof(*meshhdr)); 427 memset(meshhdr, 0, sizeof(*meshhdr));
430 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; 428 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
431 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); 429 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
432 sdata->u.mesh.mesh_seqnum++; 430 sdata->u.mesh.mesh_seqnum++;
433 if (addr4) { 431 if (addr4or5 && !addr6) {
434 meshhdr->flags |= MESH_FLAGS_AE_A4; 432 meshhdr->flags |= MESH_FLAGS_AE_A4;
435 aelen += ETH_ALEN; 433 aelen += ETH_ALEN;
436 memcpy(meshhdr->eaddr1, addr4, ETH_ALEN); 434 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
437 } 435 } else if (addr4or5 && addr6) {
438 if (addr5 && addr6) {
439 meshhdr->flags |= MESH_FLAGS_AE_A5_A6; 436 meshhdr->flags |= MESH_FLAGS_AE_A5_A6;
440 aelen += 2 * ETH_ALEN; 437 aelen += 2 * ETH_ALEN;
441 if (!addr4) { 438 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
442 memcpy(meshhdr->eaddr1, addr5, ETH_ALEN); 439 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
443 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
444 } else {
445 memcpy(meshhdr->eaddr2, addr5, ETH_ALEN);
446 memcpy(meshhdr->eaddr3, addr6, ETH_ALEN);
447 }
448 } 440 }
449 return 6 + aelen; 441 return 6 + aelen;
450} 442}
@@ -518,6 +510,9 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
518 atomic_inc(&local->iff_allmultis); 510 atomic_inc(&local->iff_allmultis);
519 ieee80211_configure_filter(local); 511 ieee80211_configure_filter(local);
520 512
513 ifmsh->mesh_cc_id = 0; /* Disabled */
514 ifmsh->mesh_sp_id = 0; /* Neighbor Offset */
515 ifmsh->mesh_auth_id = 0; /* Disabled */
521 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); 516 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
522 ieee80211_mesh_root_setup(ifmsh); 517 ieee80211_mesh_root_setup(ifmsh);
523 ieee80211_queue_work(&local->hw, &sdata->work); 518 ieee80211_queue_work(&local->hw, &sdata->work);
@@ -688,7 +683,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
688 /* Allocate all mesh structures when creating the first mesh interface. */ 683 /* Allocate all mesh structures when creating the first mesh interface. */
689 if (!mesh_allocated) 684 if (!mesh_allocated)
690 ieee80211s_init(); 685 ieee80211s_init();
691 mesh_ids_set_default(ifmsh);
692 setup_timer(&ifmsh->mesh_path_timer, 686 setup_timer(&ifmsh->mesh_path_timer,
693 ieee80211_mesh_path_timer, 687 ieee80211_mesh_path_timer,
694 (unsigned long) sdata); 688 (unsigned long) sdata);
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 039d7fa0af74..b99e230fe31c 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -164,17 +164,6 @@ struct mesh_rmc {
164}; 164};
165 165
166 166
167/*
168 * MESH_CFG_COMP_LEN Includes:
169 * - Active path selection protocol ID.
170 * - Active path selection metric ID.
171 * - Congestion control mode identifier.
172 * - Channel precedence.
173 * Does not include mesh capabilities, which may vary across nodes in the same
174 * mesh
175 */
176#define MESH_CFG_CMP_LEN (IEEE80211_MESH_CONFIG_LEN - 2)
177
178#define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */ 167#define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units */
179 168
180#define MESH_PATH_EXPIRE (600 * HZ) 169#define MESH_PATH_EXPIRE (600 * HZ)
@@ -198,8 +187,8 @@ struct mesh_rmc {
198int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, 187int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
199 const u8 *da, const u8 *sa); 188 const u8 *da, const u8 *sa);
200int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 189int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
201 struct ieee80211_sub_if_data *sdata, char *addr4, 190 struct ieee80211_sub_if_data *sdata, char *addr4or5,
202 char *addr5, char *addr6); 191 char *addr6);
203int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr, 192int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
204 struct ieee80211_sub_if_data *sdata); 193 struct ieee80211_sub_if_data *sdata);
205bool mesh_matches_local(struct ieee802_11_elems *ie, 194bool mesh_matches_local(struct ieee802_11_elems *ie,
@@ -295,6 +284,11 @@ static inline void mesh_path_activate(struct mesh_path *mpath)
295 mpath->flags |= MESH_PATH_ACTIVE | MESH_PATH_RESOLVED; 284 mpath->flags |= MESH_PATH_ACTIVE | MESH_PATH_RESOLVED;
296} 285}
297 286
287static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
288{
289 return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
290}
291
298#define for_each_mesh_entry(x, p, node, i) \ 292#define for_each_mesh_entry(x, p, node, i) \
299 for (i = 0; i <= x->hash_mask; i++) \ 293 for (i = 0; i <= x->hash_mask; i++) \
300 hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list) 294 hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list)
@@ -315,6 +309,8 @@ static inline void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
315{} 309{}
316static inline void mesh_plink_quiesce(struct sta_info *sta) {} 310static inline void mesh_plink_quiesce(struct sta_info *sta) {}
317static inline void mesh_plink_restart(struct sta_info *sta) {} 311static inline void mesh_plink_restart(struct sta_info *sta) {}
312static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
313{ return false; }
318#endif 314#endif
319 315
320#endif /* IEEE80211S_H */ 316#endif /* IEEE80211S_H */
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 1c91f0f3c307..44b53931ba5e 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -160,7 +160,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
160 enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid, 160 enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid,
161 __le16 reason) { 161 __le16 reason) {
162 struct ieee80211_local *local = sdata->local; 162 struct ieee80211_local *local = sdata->local;
163 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 163 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
164 sdata->u.mesh.vendor_ie_len);
164 struct ieee80211_mgmt *mgmt; 165 struct ieee80211_mgmt *mgmt;
165 bool include_plid = false; 166 bool include_plid = false;
166 static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A }; 167 static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A };
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 4ad7a362fcc1..165a4518bb48 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -374,7 +374,7 @@ minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, stru
374 if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) 374 if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
375 return; 375 return;
376 376
377 ieee80211_start_tx_ba_session(pubsta, tid); 377 ieee80211_start_tx_ba_session(pubsta, tid, 5000);
378} 378}
379 379
380static void 380static void
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 2fe8f5f86499..7c5d1b2ec453 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -955,12 +955,31 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
955 * have been expected. 955 * have been expected.
956 */ 956 */
957 struct ieee80211_key *key = NULL; 957 struct ieee80211_key *key = NULL;
958 struct ieee80211_sub_if_data *sdata = rx->sdata;
959 int i;
960
958 if (ieee80211_is_mgmt(fc) && 961 if (ieee80211_is_mgmt(fc) &&
959 is_multicast_ether_addr(hdr->addr1) && 962 is_multicast_ether_addr(hdr->addr1) &&
960 (key = rcu_dereference(rx->sdata->default_mgmt_key))) 963 (key = rcu_dereference(rx->sdata->default_mgmt_key)))
961 rx->key = key; 964 rx->key = key;
962 else if ((key = rcu_dereference(rx->sdata->default_key))) 965 else {
963 rx->key = key; 966 if (rx->sta) {
967 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
968 key = rcu_dereference(rx->sta->gtk[i]);
969 if (key)
970 break;
971 }
972 }
973 if (!key) {
974 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
975 key = rcu_dereference(sdata->keys[i]);
976 if (key)
977 break;
978 }
979 }
980 if (key)
981 rx->key = key;
982 }
964 return RX_CONTINUE; 983 return RX_CONTINUE;
965 } else { 984 } else {
966 u8 keyid; 985 u8 keyid;
@@ -1521,12 +1540,30 @@ ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
1521 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) { 1540 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
1522 if (unlikely(!ieee80211_has_protected(fc) && 1541 if (unlikely(!ieee80211_has_protected(fc) &&
1523 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && 1542 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
1524 rx->key)) 1543 rx->key)) {
1544 if (ieee80211_is_deauth(fc))
1545 cfg80211_send_unprot_deauth(rx->sdata->dev,
1546 rx->skb->data,
1547 rx->skb->len);
1548 else if (ieee80211_is_disassoc(fc))
1549 cfg80211_send_unprot_disassoc(rx->sdata->dev,
1550 rx->skb->data,
1551 rx->skb->len);
1525 return -EACCES; 1552 return -EACCES;
1553 }
1526 /* BIP does not use Protected field, so need to check MMIE */ 1554 /* BIP does not use Protected field, so need to check MMIE */
1527 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) && 1555 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
1528 ieee80211_get_mmie_keyidx(rx->skb) < 0)) 1556 ieee80211_get_mmie_keyidx(rx->skb) < 0)) {
1557 if (ieee80211_is_deauth(fc))
1558 cfg80211_send_unprot_deauth(rx->sdata->dev,
1559 rx->skb->data,
1560 rx->skb->len);
1561 else if (ieee80211_is_disassoc(fc))
1562 cfg80211_send_unprot_disassoc(rx->sdata->dev,
1563 rx->skb->data,
1564 rx->skb->len);
1529 return -EACCES; 1565 return -EACCES;
1566 }
1530 /* 1567 /*
1531 * When using MFP, Action frames are not allowed prior to 1568 * When using MFP, Action frames are not allowed prior to
1532 * having configured keys. 1569 * having configured keys.
@@ -2124,10 +2161,13 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2124 } 2161 }
2125 break; 2162 break;
2126 case WLAN_CATEGORY_MESH_PLINK: 2163 case WLAN_CATEGORY_MESH_PLINK:
2127 case WLAN_CATEGORY_MESH_PATH_SEL:
2128 if (!ieee80211_vif_is_mesh(&sdata->vif)) 2164 if (!ieee80211_vif_is_mesh(&sdata->vif))
2129 break; 2165 break;
2130 goto queue; 2166 goto queue;
2167 case WLAN_CATEGORY_MESH_PATH_SEL:
2168 if (!mesh_path_sel_is_hwmp(sdata))
2169 break;
2170 goto queue;
2131 } 2171 }
2132 2172
2133 return RX_CONTINUE; 2173 return RX_CONTINUE;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index fdca52cf88de..bbdd2a86a94b 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -78,6 +78,7 @@ enum ieee80211_sta_info_flags {
78 * @addba_resp_timer: timer for peer's response to addba request 78 * @addba_resp_timer: timer for peer's response to addba request
79 * @pending: pending frames queue -- use sta's spinlock to protect 79 * @pending: pending frames queue -- use sta's spinlock to protect
80 * @dialog_token: dialog token for aggregation session 80 * @dialog_token: dialog token for aggregation session
81 * @timeout: session timeout value to be filled in ADDBA requests
81 * @state: session state (see above) 82 * @state: session state (see above)
82 * @stop_initiator: initiator of a session stop 83 * @stop_initiator: initiator of a session stop
83 * @tx_stop: TX DelBA frame when stopping 84 * @tx_stop: TX DelBA frame when stopping
@@ -96,6 +97,7 @@ struct tid_ampdu_tx {
96 struct timer_list addba_resp_timer; 97 struct timer_list addba_resp_timer;
97 struct sk_buff_head pending; 98 struct sk_buff_head pending;
98 unsigned long state; 99 unsigned long state;
100 u16 timeout;
99 u8 dialog_token; 101 u8 dialog_token;
100 u8 stop_initiator; 102 u8 stop_initiator;
101 bool tx_stop; 103 bool tx_stop;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 0ee56bb0ea7e..d2b4b67a7b53 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -539,7 +539,11 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
539 ieee80211_is_robust_mgmt_frame(hdr) && 539 ieee80211_is_robust_mgmt_frame(hdr) &&
540 (key = rcu_dereference(tx->sdata->default_mgmt_key))) 540 (key = rcu_dereference(tx->sdata->default_mgmt_key)))
541 tx->key = key; 541 tx->key = key;
542 else if ((key = rcu_dereference(tx->sdata->default_key))) 542 else if (is_multicast_ether_addr(hdr->addr1) &&
543 (key = rcu_dereference(tx->sdata->default_multicast_key)))
544 tx->key = key;
545 else if (!is_multicast_ether_addr(hdr->addr1) &&
546 (key = rcu_dereference(tx->sdata->default_unicast_key)))
543 tx->key = key; 547 tx->key = key;
544 else if (tx->sdata->drop_unencrypted && 548 else if (tx->sdata->drop_unencrypted &&
545 (tx->skb->protocol != tx->sdata->control_port_protocol) && 549 (tx->skb->protocol != tx->sdata->control_port_protocol) &&
@@ -1542,8 +1546,10 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
1542 1546
1543 if (skb_header_cloned(skb)) 1547 if (skb_header_cloned(skb))
1544 I802_DEBUG_INC(local->tx_expand_skb_head_cloned); 1548 I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
1545 else 1549 else if (head_need || tail_need)
1546 I802_DEBUG_INC(local->tx_expand_skb_head); 1550 I802_DEBUG_INC(local->tx_expand_skb_head);
1551 else
1552 return 0;
1547 1553
1548 if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) { 1554 if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) {
1549 wiphy_debug(local->hw.wiphy, 1555 wiphy_debug(local->hw.wiphy,
@@ -1735,7 +1741,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1735{ 1741{
1736 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1742 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1737 struct ieee80211_local *local = sdata->local; 1743 struct ieee80211_local *local = sdata->local;
1738 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1744 struct ieee80211_tx_info *info;
1739 int ret = NETDEV_TX_BUSY, head_need; 1745 int ret = NETDEV_TX_BUSY, head_need;
1740 u16 ethertype, hdrlen, meshhdrlen = 0; 1746 u16 ethertype, hdrlen, meshhdrlen = 0;
1741 __le16 fc; 1747 __le16 fc;
@@ -1807,7 +1813,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1807 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, 1813 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
1808 skb->data, skb->data + ETH_ALEN); 1814 skb->data, skb->data + ETH_ALEN);
1809 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, 1815 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
1810 sdata, NULL, NULL, NULL); 1816 sdata, NULL, NULL);
1811 } else { 1817 } else {
1812 /* packet from other interface */ 1818 /* packet from other interface */
1813 struct mesh_path *mppath; 1819 struct mesh_path *mppath;
@@ -1840,13 +1846,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1840 ieee80211_new_mesh_header(&mesh_hdr, 1846 ieee80211_new_mesh_header(&mesh_hdr,
1841 sdata, 1847 sdata,
1842 skb->data + ETH_ALEN, 1848 skb->data + ETH_ALEN,
1843 NULL,
1844 NULL); 1849 NULL);
1845 else 1850 else
1846 meshhdrlen = 1851 meshhdrlen =
1847 ieee80211_new_mesh_header(&mesh_hdr, 1852 ieee80211_new_mesh_header(&mesh_hdr,
1848 sdata, 1853 sdata,
1849 NULL,
1850 skb->data, 1854 skb->data,
1851 skb->data + ETH_ALEN); 1855 skb->data + ETH_ALEN);
1852 1856
@@ -1930,7 +1934,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1930 */ 1934 */
1931 if (skb_shared(skb)) { 1935 if (skb_shared(skb)) {
1932 tmp_skb = skb; 1936 tmp_skb = skb;
1933 skb = skb_copy(skb, GFP_ATOMIC); 1937 skb = skb_clone(skb, GFP_ATOMIC);
1934 kfree_skb(tmp_skb); 1938 kfree_skb(tmp_skb);
1935 1939
1936 if (!skb) { 1940 if (!skb) {
@@ -2026,6 +2030,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
2026 skb_set_network_header(skb, nh_pos); 2030 skb_set_network_header(skb, nh_pos);
2027 skb_set_transport_header(skb, h_pos); 2031 skb_set_transport_header(skb, h_pos);
2028 2032
2033 info = IEEE80211_SKB_CB(skb);
2029 memset(info, 0, sizeof(*info)); 2034 memset(info, 0, sizeof(*info));
2030 2035
2031 dev->trans_start = jiffies; 2036 dev->trans_start = jiffies;
@@ -2286,7 +2291,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2286 u8 *pos; 2291 u8 *pos;
2287 2292
2288 /* headroom, head length, tail length and maximum TIM length */ 2293 /* headroom, head length, tail length and maximum TIM length */
2289 skb = dev_alloc_skb(local->tx_headroom + 400); 2294 skb = dev_alloc_skb(local->tx_headroom + 400 +
2295 sdata->u.mesh.vendor_ie_len);
2290 if (!skb) 2296 if (!skb)
2291 goto out; 2297 goto out;
2292 2298
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 79772fcc37bc..e9a5f8ca4c27 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -789,13 +789,23 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
789 cfg80211_mgd_wext_connect(rdev, wdev); 789 cfg80211_mgd_wext_connect(rdev, wdev);
790 break; 790 break;
791#endif 791#endif
792#ifdef CONFIG_MAC80211_MESH
792 case NL80211_IFTYPE_MESH_POINT: 793 case NL80211_IFTYPE_MESH_POINT:
793 /* backward compat code ... */ 794 {
794 if (wdev->mesh_id_up_len) 795 /* backward compat code... */
795 __cfg80211_join_mesh(rdev, dev, wdev->ssid, 796 struct mesh_setup setup;
796 wdev->mesh_id_up_len, 797 memcpy(&setup, &default_mesh_setup,
797 &default_mesh_config); 798 sizeof(setup));
798 break; 799 /* back compat only needed for mesh_id */
800 setup.mesh_id = wdev->ssid;
801 setup.mesh_id_len = wdev->mesh_id_up_len;
802 if (wdev->mesh_id_up_len)
803 __cfg80211_join_mesh(rdev, dev,
804 &setup,
805 &default_mesh_config);
806 break;
807 }
808#endif
799 default: 809 default:
800 break; 810 break;
801 } 811 }
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 743203bb61ac..26a0a084e16b 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -287,13 +287,14 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
287 287
288/* mesh */ 288/* mesh */
289extern const struct mesh_config default_mesh_config; 289extern const struct mesh_config default_mesh_config;
290extern const struct mesh_setup default_mesh_setup;
290int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 291int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
291 struct net_device *dev, 292 struct net_device *dev,
292 const u8 *mesh_id, u8 mesh_id_len, 293 const struct mesh_setup *setup,
293 const struct mesh_config *conf); 294 const struct mesh_config *conf);
294int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 295int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
295 struct net_device *dev, 296 struct net_device *dev,
296 const u8 *mesh_id, u8 mesh_id_len, 297 const struct mesh_setup *setup,
297 const struct mesh_config *conf); 298 const struct mesh_config *conf);
298int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, 299int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
299 struct net_device *dev); 300 struct net_device *dev);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index e0b9747fe50a..73e39c171ffb 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -50,17 +50,19 @@ const struct mesh_config default_mesh_config = {
50 .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT, 50 .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
51}; 51};
52 52
53const struct mesh_setup default_mesh_setup = {
54 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
55 .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
56 .vendor_ie = NULL,
57 .vendor_ie_len = 0,
58};
53 59
54int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 60int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
55 struct net_device *dev, 61 struct net_device *dev,
56 const u8 *mesh_id, u8 mesh_id_len, 62 const struct mesh_setup *setup,
57 const struct mesh_config *conf) 63 const struct mesh_config *conf)
58{ 64{
59 struct wireless_dev *wdev = dev->ieee80211_ptr; 65 struct wireless_dev *wdev = dev->ieee80211_ptr;
60 struct mesh_setup setup = {
61 .mesh_id = mesh_id,
62 .mesh_id_len = mesh_id_len,
63 };
64 int err; 66 int err;
65 67
66 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); 68 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN);
@@ -73,16 +75,16 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
73 if (wdev->mesh_id_len) 75 if (wdev->mesh_id_len)
74 return -EALREADY; 76 return -EALREADY;
75 77
76 if (!mesh_id_len) 78 if (!setup->mesh_id_len)
77 return -EINVAL; 79 return -EINVAL;
78 80
79 if (!rdev->ops->join_mesh) 81 if (!rdev->ops->join_mesh)
80 return -EOPNOTSUPP; 82 return -EOPNOTSUPP;
81 83
82 err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, &setup); 84 err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup);
83 if (!err) { 85 if (!err) {
84 memcpy(wdev->ssid, mesh_id, mesh_id_len); 86 memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len);
85 wdev->mesh_id_len = mesh_id_len; 87 wdev->mesh_id_len = setup->mesh_id_len;
86 } 88 }
87 89
88 return err; 90 return err;
@@ -90,14 +92,14 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
90 92
91int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, 93int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
92 struct net_device *dev, 94 struct net_device *dev,
93 const u8 *mesh_id, u8 mesh_id_len, 95 const struct mesh_setup *setup,
94 const struct mesh_config *conf) 96 const struct mesh_config *conf)
95{ 97{
96 struct wireless_dev *wdev = dev->ieee80211_ptr; 98 struct wireless_dev *wdev = dev->ieee80211_ptr;
97 int err; 99 int err;
98 100
99 wdev_lock(wdev); 101 wdev_lock(wdev);
100 err = __cfg80211_join_mesh(rdev, dev, mesh_id, mesh_id_len, conf); 102 err = __cfg80211_join_mesh(rdev, dev, setup, conf);
101 wdev_unlock(wdev); 103 wdev_unlock(wdev);
102 104
103 return err; 105 return err;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index d7680f2a4c5b..aa5df8865ff7 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -263,6 +263,28 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
263} 263}
264EXPORT_SYMBOL(cfg80211_send_disassoc); 264EXPORT_SYMBOL(cfg80211_send_disassoc);
265 265
266void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
267 size_t len)
268{
269 struct wireless_dev *wdev = dev->ieee80211_ptr;
270 struct wiphy *wiphy = wdev->wiphy;
271 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
272
273 nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC);
274}
275EXPORT_SYMBOL(cfg80211_send_unprot_deauth);
276
277void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
278 size_t len)
279{
280 struct wireless_dev *wdev = dev->ieee80211_ptr;
281 struct wiphy *wiphy = wdev->wiphy;
282 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
283
284 nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC);
285}
286EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
287
266static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr) 288static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr)
267{ 289{
268 int i; 290 int i;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c3f80e565365..9b62710891a2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -123,7 +123,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
123 .len = NL80211_MAX_SUPP_RATES }, 123 .len = NL80211_MAX_SUPP_RATES },
124 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, 124 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
125 125
126 [NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED }, 126 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
127 127
128 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, 128 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
129 .len = NL80211_HT_CAPABILITY_LEN }, 129 .len = NL80211_HT_CAPABILITY_LEN },
@@ -171,6 +171,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
171 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 }, 171 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
172 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 }, 172 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
173 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG }, 173 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
174 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
174}; 175};
175 176
176/* policy for the key attributes */ 177/* policy for the key attributes */
@@ -182,6 +183,14 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
182 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, 183 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
183 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, 184 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
184 [NL80211_KEY_TYPE] = { .type = NLA_U32 }, 185 [NL80211_KEY_TYPE] = { .type = NLA_U32 },
186 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
187};
188
189/* policy for the key default flags */
190static const struct nla_policy
191nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
192 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
193 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
185}; 194};
186 195
187/* ifidx get helper */ 196/* ifidx get helper */
@@ -314,6 +323,7 @@ struct key_parse {
314 int idx; 323 int idx;
315 int type; 324 int type;
316 bool def, defmgmt; 325 bool def, defmgmt;
326 bool def_uni, def_multi;
317}; 327};
318 328
319static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k) 329static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
@@ -327,6 +337,13 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
327 k->def = !!tb[NL80211_KEY_DEFAULT]; 337 k->def = !!tb[NL80211_KEY_DEFAULT];
328 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT]; 338 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
329 339
340 if (k->def) {
341 k->def_uni = true;
342 k->def_multi = true;
343 }
344 if (k->defmgmt)
345 k->def_multi = true;
346
330 if (tb[NL80211_KEY_IDX]) 347 if (tb[NL80211_KEY_IDX])
331 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]); 348 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
332 349
@@ -349,6 +366,19 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
349 return -EINVAL; 366 return -EINVAL;
350 } 367 }
351 368
369 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
370 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
371 int err = nla_parse_nested(kdt,
372 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
373 tb[NL80211_KEY_DEFAULT_TYPES],
374 nl80211_key_default_policy);
375 if (err)
376 return err;
377
378 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
379 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
380 }
381
352 return 0; 382 return 0;
353} 383}
354 384
@@ -373,12 +403,32 @@ static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
373 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT]; 403 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
374 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]; 404 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
375 405
406 if (k->def) {
407 k->def_uni = true;
408 k->def_multi = true;
409 }
410 if (k->defmgmt)
411 k->def_multi = true;
412
376 if (info->attrs[NL80211_ATTR_KEY_TYPE]) { 413 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
377 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); 414 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
378 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) 415 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
379 return -EINVAL; 416 return -EINVAL;
380 } 417 }
381 418
419 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
420 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
421 int err = nla_parse_nested(
422 kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
423 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
424 nl80211_key_default_policy);
425 if (err)
426 return err;
427
428 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
429 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
430 }
431
382 return 0; 432 return 0;
383} 433}
384 434
@@ -401,6 +451,11 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
401 if (k->def && k->defmgmt) 451 if (k->def && k->defmgmt)
402 return -EINVAL; 452 return -EINVAL;
403 453
454 if (k->defmgmt) {
455 if (k->def_uni || !k->def_multi)
456 return -EINVAL;
457 }
458
404 if (k->idx != -1) { 459 if (k->idx != -1) {
405 if (k->defmgmt) { 460 if (k->defmgmt) {
406 if (k->idx < 4 || k->idx > 5) 461 if (k->idx < 4 || k->idx > 5)
@@ -450,6 +505,8 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
450 goto error; 505 goto error;
451 def = 1; 506 def = 1;
452 result->def = parse.idx; 507 result->def = parse.idx;
508 if (!parse.def_uni || !parse.def_multi)
509 goto error;
453 } else if (parse.defmgmt) 510 } else if (parse.defmgmt)
454 goto error; 511 goto error;
455 err = cfg80211_validate_key_settings(rdev, &parse.p, 512 err = cfg80211_validate_key_settings(rdev, &parse.p,
@@ -548,7 +605,13 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
548 if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) 605 if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL)
549 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); 606 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE);
550 607
551 if (dev->ops->get_antenna) { 608 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
609 dev->wiphy.available_antennas_tx);
610 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
611 dev->wiphy.available_antennas_rx);
612
613 if ((dev->wiphy.available_antennas_tx ||
614 dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) {
552 u32 tx_ant = 0, rx_ant = 0; 615 u32 tx_ant = 0, rx_ant = 0;
553 int res; 616 int res;
554 res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); 617 res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant);
@@ -662,7 +725,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
662 CMD(add_beacon, NEW_BEACON); 725 CMD(add_beacon, NEW_BEACON);
663 CMD(add_station, NEW_STATION); 726 CMD(add_station, NEW_STATION);
664 CMD(add_mpath, NEW_MPATH); 727 CMD(add_mpath, NEW_MPATH);
665 CMD(update_mesh_params, SET_MESH_PARAMS); 728 CMD(update_mesh_config, SET_MESH_CONFIG);
666 CMD(change_bss, SET_BSS); 729 CMD(change_bss, SET_BSS);
667 CMD(auth, AUTHENTICATE); 730 CMD(auth, AUTHENTICATE);
668 CMD(assoc, ASSOCIATE); 731 CMD(assoc, ASSOCIATE);
@@ -698,6 +761,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
698 761
699 nla_nest_end(msg, nl_cmds); 762 nla_nest_end(msg, nl_cmds);
700 763
764 if (dev->ops->remain_on_channel)
765 NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
766 dev->wiphy.max_remain_on_channel_duration);
767
701 /* for now at least assume all drivers have it */ 768 /* for now at least assume all drivers have it */
702 if (dev->ops->mgmt_tx) 769 if (dev->ops->mgmt_tx)
703 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); 770 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
@@ -1046,7 +1113,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1046 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && 1113 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
1047 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { 1114 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
1048 u32 tx_ant, rx_ant; 1115 u32 tx_ant, rx_ant;
1049 if (!rdev->ops->set_antenna) { 1116 if ((!rdev->wiphy.available_antennas_tx &&
1117 !rdev->wiphy.available_antennas_rx) ||
1118 !rdev->ops->set_antenna) {
1050 result = -EOPNOTSUPP; 1119 result = -EOPNOTSUPP;
1051 goto bad_res; 1120 goto bad_res;
1052 } 1121 }
@@ -1054,6 +1123,17 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1054 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]); 1123 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
1055 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]); 1124 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
1056 1125
1126 /* reject antenna configurations which don't match the
1127 * available antenna masks, except for the "all" mask */
1128 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
1129 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) {
1130 result = -EINVAL;
1131 goto bad_res;
1132 }
1133
1134 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
1135 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
1136
1057 result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); 1137 result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant);
1058 if (result) 1138 if (result)
1059 goto bad_res; 1139 goto bad_res;
@@ -1575,8 +1655,6 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1575 struct key_parse key; 1655 struct key_parse key;
1576 int err; 1656 int err;
1577 struct net_device *dev = info->user_ptr[1]; 1657 struct net_device *dev = info->user_ptr[1];
1578 int (*func)(struct wiphy *wiphy, struct net_device *netdev,
1579 u8 key_index);
1580 1658
1581 err = nl80211_parse_key(info, &key); 1659 err = nl80211_parse_key(info, &key);
1582 if (err) 1660 if (err)
@@ -1589,27 +1667,61 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1589 if (!key.def && !key.defmgmt) 1667 if (!key.def && !key.defmgmt)
1590 return -EINVAL; 1668 return -EINVAL;
1591 1669
1592 if (key.def) 1670 wdev_lock(dev->ieee80211_ptr);
1593 func = rdev->ops->set_default_key;
1594 else
1595 func = rdev->ops->set_default_mgmt_key;
1596 1671
1597 if (!func) 1672 if (key.def) {
1598 return -EOPNOTSUPP; 1673 if (!rdev->ops->set_default_key) {
1674 err = -EOPNOTSUPP;
1675 goto out;
1676 }
1599 1677
1600 wdev_lock(dev->ieee80211_ptr); 1678 err = nl80211_key_allowed(dev->ieee80211_ptr);
1601 err = nl80211_key_allowed(dev->ieee80211_ptr); 1679 if (err)
1602 if (!err) 1680 goto out;
1603 err = func(&rdev->wiphy, dev, key.idx); 1681
1682 if (!(rdev->wiphy.flags &
1683 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS)) {
1684 if (!key.def_uni || !key.def_multi) {
1685 err = -EOPNOTSUPP;
1686 goto out;
1687 }
1688 }
1689
1690 err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx,
1691 key.def_uni, key.def_multi);
1692
1693 if (err)
1694 goto out;
1604 1695
1605#ifdef CONFIG_CFG80211_WEXT 1696#ifdef CONFIG_CFG80211_WEXT
1606 if (!err) { 1697 dev->ieee80211_ptr->wext.default_key = key.idx;
1607 if (func == rdev->ops->set_default_key)
1608 dev->ieee80211_ptr->wext.default_key = key.idx;
1609 else
1610 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
1611 }
1612#endif 1698#endif
1699 } else {
1700 if (key.def_uni || !key.def_multi) {
1701 err = -EINVAL;
1702 goto out;
1703 }
1704
1705 if (!rdev->ops->set_default_mgmt_key) {
1706 err = -EOPNOTSUPP;
1707 goto out;
1708 }
1709
1710 err = nl80211_key_allowed(dev->ieee80211_ptr);
1711 if (err)
1712 goto out;
1713
1714 err = rdev->ops->set_default_mgmt_key(&rdev->wiphy,
1715 dev, key.idx);
1716 if (err)
1717 goto out;
1718
1719#ifdef CONFIG_CFG80211_WEXT
1720 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
1721#endif
1722 }
1723
1724 out:
1613 wdev_unlock(dev->ieee80211_ptr); 1725 wdev_unlock(dev->ieee80211_ptr);
1614 1726
1615 return err; 1727 return err;
@@ -2569,7 +2681,7 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
2569 return r; 2681 return r;
2570} 2682}
2571 2683
2572static int nl80211_get_mesh_params(struct sk_buff *skb, 2684static int nl80211_get_mesh_config(struct sk_buff *skb,
2573 struct genl_info *info) 2685 struct genl_info *info)
2574{ 2686{
2575 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2687 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2584,7 +2696,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2584 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) 2696 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
2585 return -EOPNOTSUPP; 2697 return -EOPNOTSUPP;
2586 2698
2587 if (!rdev->ops->get_mesh_params) 2699 if (!rdev->ops->get_mesh_config)
2588 return -EOPNOTSUPP; 2700 return -EOPNOTSUPP;
2589 2701
2590 wdev_lock(wdev); 2702 wdev_lock(wdev);
@@ -2592,7 +2704,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2592 if (!wdev->mesh_id_len) 2704 if (!wdev->mesh_id_len)
2593 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params)); 2705 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
2594 else 2706 else
2595 err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, 2707 err = rdev->ops->get_mesh_config(&rdev->wiphy, dev,
2596 &cur_params); 2708 &cur_params);
2597 wdev_unlock(wdev); 2709 wdev_unlock(wdev);
2598 2710
@@ -2604,10 +2716,10 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2604 if (!msg) 2716 if (!msg)
2605 return -ENOMEM; 2717 return -ENOMEM;
2606 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, 2718 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2607 NL80211_CMD_GET_MESH_PARAMS); 2719 NL80211_CMD_GET_MESH_CONFIG);
2608 if (!hdr) 2720 if (!hdr)
2609 goto nla_put_failure; 2721 goto nla_put_failure;
2610 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS); 2722 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
2611 if (!pinfoattr) 2723 if (!pinfoattr)
2612 goto nla_put_failure; 2724 goto nla_put_failure;
2613 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 2725 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
@@ -2669,7 +2781,15 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
2669 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, 2781 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
2670}; 2782};
2671 2783
2672static int nl80211_parse_mesh_params(struct genl_info *info, 2784static const struct nla_policy
2785 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
2786 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
2787 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
2788 [NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE] = { .type = NLA_BINARY,
2789 .len = IEEE80211_MAX_DATA_LEN },
2790};
2791
2792static int nl80211_parse_mesh_config(struct genl_info *info,
2673 struct mesh_config *cfg, 2793 struct mesh_config *cfg,
2674 u32 *mask_out) 2794 u32 *mask_out)
2675{ 2795{
@@ -2685,10 +2805,10 @@ do {\
2685} while (0);\ 2805} while (0);\
2686 2806
2687 2807
2688 if (!info->attrs[NL80211_ATTR_MESH_PARAMS]) 2808 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
2689 return -EINVAL; 2809 return -EINVAL;
2690 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX, 2810 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
2691 info->attrs[NL80211_ATTR_MESH_PARAMS], 2811 info->attrs[NL80211_ATTR_MESH_CONFIG],
2692 nl80211_meshconf_params_policy)) 2812 nl80211_meshconf_params_policy))
2693 return -EINVAL; 2813 return -EINVAL;
2694 2814
@@ -2735,15 +2855,51 @@ do {\
2735 dot11MeshHWMPRootMode, mask, 2855 dot11MeshHWMPRootMode, mask,
2736 NL80211_MESHCONF_HWMP_ROOTMODE, 2856 NL80211_MESHCONF_HWMP_ROOTMODE,
2737 nla_get_u8); 2857 nla_get_u8);
2738
2739 if (mask_out) 2858 if (mask_out)
2740 *mask_out = mask; 2859 *mask_out = mask;
2860
2741 return 0; 2861 return 0;
2742 2862
2743#undef FILL_IN_MESH_PARAM_IF_SET 2863#undef FILL_IN_MESH_PARAM_IF_SET
2744} 2864}
2745 2865
2746static int nl80211_update_mesh_params(struct sk_buff *skb, 2866static int nl80211_parse_mesh_setup(struct genl_info *info,
2867 struct mesh_setup *setup)
2868{
2869 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
2870
2871 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
2872 return -EINVAL;
2873 if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
2874 info->attrs[NL80211_ATTR_MESH_SETUP],
2875 nl80211_mesh_setup_params_policy))
2876 return -EINVAL;
2877
2878 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
2879 setup->path_sel_proto =
2880 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
2881 IEEE80211_PATH_PROTOCOL_VENDOR :
2882 IEEE80211_PATH_PROTOCOL_HWMP;
2883
2884 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
2885 setup->path_metric =
2886 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
2887 IEEE80211_PATH_METRIC_VENDOR :
2888 IEEE80211_PATH_METRIC_AIRTIME;
2889
2890 if (tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE]) {
2891 struct nlattr *ieattr =
2892 tb[NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE];
2893 if (!is_valid_ie_attr(ieattr))
2894 return -EINVAL;
2895 setup->vendor_ie = nla_data(ieattr);
2896 setup->vendor_ie_len = nla_len(ieattr);
2897 }
2898
2899 return 0;
2900}
2901
2902static int nl80211_update_mesh_config(struct sk_buff *skb,
2747 struct genl_info *info) 2903 struct genl_info *info)
2748{ 2904{
2749 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2905 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -2756,10 +2912,10 @@ static int nl80211_update_mesh_params(struct sk_buff *skb,
2756 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) 2912 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
2757 return -EOPNOTSUPP; 2913 return -EOPNOTSUPP;
2758 2914
2759 if (!rdev->ops->update_mesh_params) 2915 if (!rdev->ops->update_mesh_config)
2760 return -EOPNOTSUPP; 2916 return -EOPNOTSUPP;
2761 2917
2762 err = nl80211_parse_mesh_params(info, &cfg, &mask); 2918 err = nl80211_parse_mesh_config(info, &cfg, &mask);
2763 if (err) 2919 if (err)
2764 return err; 2920 return err;
2765 2921
@@ -2768,7 +2924,7 @@ static int nl80211_update_mesh_params(struct sk_buff *skb,
2768 err = -ENOLINK; 2924 err = -ENOLINK;
2769 2925
2770 if (!err) 2926 if (!err)
2771 err = rdev->ops->update_mesh_params(&rdev->wiphy, dev, 2927 err = rdev->ops->update_mesh_config(&rdev->wiphy, dev,
2772 mask, &cfg); 2928 mask, &cfg);
2773 2929
2774 wdev_unlock(wdev); 2930 wdev_unlock(wdev);
@@ -4128,7 +4284,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
4128 * We should be on that channel for at least one jiffie, 4284 * We should be on that channel for at least one jiffie,
4129 * and more than 5 seconds seems excessive. 4285 * and more than 5 seconds seems excessive.
4130 */ 4286 */
4131 if (!duration || !msecs_to_jiffies(duration) || duration > 5000) 4287 if (!duration || !msecs_to_jiffies(duration) ||
4288 duration > rdev->wiphy.max_remain_on_channel_duration)
4132 return -EINVAL; 4289 return -EINVAL;
4133 4290
4134 if (!rdev->ops->remain_on_channel) 4291 if (!rdev->ops->remain_on_channel)
@@ -4296,6 +4453,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
4296 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && 4453 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4297 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 4454 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4298 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 4455 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4456 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4299 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 4457 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4300 return -EOPNOTSUPP; 4458 return -EOPNOTSUPP;
4301 4459
@@ -4336,6 +4494,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
4336 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && 4494 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
4337 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 4495 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4338 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && 4496 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
4497 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4339 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 4498 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4340 return -EOPNOTSUPP; 4499 return -EOPNOTSUPP;
4341 4500
@@ -4562,14 +4721,16 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
4562 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4721 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4563 struct net_device *dev = info->user_ptr[1]; 4722 struct net_device *dev = info->user_ptr[1];
4564 struct mesh_config cfg; 4723 struct mesh_config cfg;
4724 struct mesh_setup setup;
4565 int err; 4725 int err;
4566 4726
4567 /* start with default */ 4727 /* start with default */
4568 memcpy(&cfg, &default_mesh_config, sizeof(cfg)); 4728 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
4729 memcpy(&setup, &default_mesh_setup, sizeof(setup));
4569 4730
4570 if (info->attrs[NL80211_ATTR_MESH_PARAMS]) { 4731 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
4571 /* and parse parameters if given */ 4732 /* and parse parameters if given */
4572 err = nl80211_parse_mesh_params(info, &cfg, NULL); 4733 err = nl80211_parse_mesh_config(info, &cfg, NULL);
4573 if (err) 4734 if (err)
4574 return err; 4735 return err;
4575 } 4736 }
@@ -4578,10 +4739,17 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
4578 !nla_len(info->attrs[NL80211_ATTR_MESH_ID])) 4739 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
4579 return -EINVAL; 4740 return -EINVAL;
4580 4741
4581 return cfg80211_join_mesh(rdev, dev, 4742 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
4582 nla_data(info->attrs[NL80211_ATTR_MESH_ID]), 4743 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
4583 nla_len(info->attrs[NL80211_ATTR_MESH_ID]), 4744
4584 &cfg); 4745 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
4746 /* parse additional setup parameters if given */
4747 err = nl80211_parse_mesh_setup(info, &setup);
4748 if (err)
4749 return err;
4750 }
4751
4752 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
4585} 4753}
4586 4754
4587static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) 4755static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
@@ -4847,16 +5015,16 @@ static struct genl_ops nl80211_ops[] = {
4847 .flags = GENL_ADMIN_PERM, 5015 .flags = GENL_ADMIN_PERM,
4848 }, 5016 },
4849 { 5017 {
4850 .cmd = NL80211_CMD_GET_MESH_PARAMS, 5018 .cmd = NL80211_CMD_GET_MESH_CONFIG,
4851 .doit = nl80211_get_mesh_params, 5019 .doit = nl80211_get_mesh_config,
4852 .policy = nl80211_policy, 5020 .policy = nl80211_policy,
4853 /* can be retrieved by unprivileged users */ 5021 /* can be retrieved by unprivileged users */
4854 .internal_flags = NL80211_FLAG_NEED_NETDEV | 5022 .internal_flags = NL80211_FLAG_NEED_NETDEV |
4855 NL80211_FLAG_NEED_RTNL, 5023 NL80211_FLAG_NEED_RTNL,
4856 }, 5024 },
4857 { 5025 {
4858 .cmd = NL80211_CMD_SET_MESH_PARAMS, 5026 .cmd = NL80211_CMD_SET_MESH_CONFIG,
4859 .doit = nl80211_update_mesh_params, 5027 .doit = nl80211_update_mesh_config,
4860 .policy = nl80211_policy, 5028 .policy = nl80211_policy,
4861 .flags = GENL_ADMIN_PERM, 5029 .flags = GENL_ADMIN_PERM,
4862 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 5030 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
@@ -5368,6 +5536,22 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
5368 NL80211_CMD_DISASSOCIATE, gfp); 5536 NL80211_CMD_DISASSOCIATE, gfp);
5369} 5537}
5370 5538
5539void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
5540 struct net_device *netdev, const u8 *buf,
5541 size_t len, gfp_t gfp)
5542{
5543 nl80211_send_mlme_event(rdev, netdev, buf, len,
5544 NL80211_CMD_UNPROT_DEAUTHENTICATE, gfp);
5545}
5546
5547void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
5548 struct net_device *netdev, const u8 *buf,
5549 size_t len, gfp_t gfp)
5550{
5551 nl80211_send_mlme_event(rdev, netdev, buf, len,
5552 NL80211_CMD_UNPROT_DISASSOCIATE, gfp);
5553}
5554
5371static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, 5555static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
5372 struct net_device *netdev, int cmd, 5556 struct net_device *netdev, int cmd,
5373 const u8 *addr, gfp_t gfp) 5557 const u8 *addr, gfp_t gfp)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 16c2f7190768..e3f7fa886966 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -25,6 +25,12 @@ void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
25void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, 25void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
26 struct net_device *netdev, 26 struct net_device *netdev,
27 const u8 *buf, size_t len, gfp_t gfp); 27 const u8 *buf, size_t len, gfp_t gfp);
28void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
29 struct net_device *netdev,
30 const u8 *buf, size_t len, gfp_t gfp);
31void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
32 struct net_device *netdev,
33 const u8 *buf, size_t len, gfp_t gfp);
28void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev, 34void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
29 struct net_device *netdev, 35 struct net_device *netdev,
30 const u8 *addr, gfp_t gfp); 36 const u8 *addr, gfp_t gfp);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 5ed615f94e0c..99d41831d76e 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -661,7 +661,8 @@ static int freq_reg_info_regd(struct wiphy *wiphy,
661 * Follow the driver's regulatory domain, if present, unless a country 661 * Follow the driver's regulatory domain, if present, unless a country
662 * IE has been processed or a user wants to help complaince further 662 * IE has been processed or a user wants to help complaince further
663 */ 663 */
664 if (last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && 664 if (!custom_regd &&
665 last_request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
665 last_request->initiator != NL80211_REGDOM_SET_BY_USER && 666 last_request->initiator != NL80211_REGDOM_SET_BY_USER &&
666 wiphy->regd) 667 wiphy->regd)
667 regd = wiphy->regd; 668 regd = wiphy->regd;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 503ebb86ba18..ea427f418f64 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -464,6 +464,9 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
464 if (res->pub.beacon_ies) { 464 if (res->pub.beacon_ies) {
465 size_t used = dev->wiphy.bss_priv_size + sizeof(*res); 465 size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
466 size_t ielen = res->pub.len_beacon_ies; 466 size_t ielen = res->pub.len_beacon_ies;
467 bool information_elements_is_beacon_ies =
468 (found->pub.information_elements ==
469 found->pub.beacon_ies);
467 470
468 if (found->pub.beacon_ies && 471 if (found->pub.beacon_ies &&
469 !found->beacon_ies_allocated && 472 !found->beacon_ies_allocated &&
@@ -487,6 +490,14 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
487 found->pub.len_beacon_ies = ielen; 490 found->pub.len_beacon_ies = ielen;
488 } 491 }
489 } 492 }
493
494 /* Override IEs if they were from a beacon before */
495 if (information_elements_is_beacon_ies) {
496 found->pub.information_elements =
497 found->pub.beacon_ies;
498 found->pub.len_information_elements =
499 found->pub.len_beacon_ies;
500 }
490 } 501 }
491 502
492 kref_put(&res->ref, bss_release); 503 kref_put(&res->ref, bss_release);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4de624ca4c63..7620ae2fcf18 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -689,7 +689,8 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
689 continue; 689 continue;
690 } 690 }
691 if (wdev->connect_keys->def == i) 691 if (wdev->connect_keys->def == i)
692 if (rdev->ops->set_default_key(wdev->wiphy, dev, i)) { 692 if (rdev->ops->set_default_key(wdev->wiphy, dev,
693 i, true, true)) {
693 netdev_err(dev, "failed to set defkey %d\n", i); 694 netdev_err(dev, "failed to set defkey %d\n", i);
694 continue; 695 continue;
695 } 696 }
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 12222ee6ebf2..3e5dbd4e4cd5 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -548,8 +548,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
548 __cfg80211_leave_ibss(rdev, wdev->netdev, true); 548 __cfg80211_leave_ibss(rdev, wdev->netdev, true);
549 rejoin = true; 549 rejoin = true;
550 } 550 }
551 err = rdev->ops->set_default_key(&rdev->wiphy, 551 err = rdev->ops->set_default_key(&rdev->wiphy, dev,
552 dev, idx); 552 idx, true, true);
553 } 553 }
554 if (!err) { 554 if (!err) {
555 wdev->wext.default_key = idx; 555 wdev->wext.default_key = idx;
@@ -627,8 +627,8 @@ int cfg80211_wext_siwencode(struct net_device *dev,
627 err = 0; 627 err = 0;
628 wdev_lock(wdev); 628 wdev_lock(wdev);
629 if (wdev->current_bss) 629 if (wdev->current_bss)
630 err = rdev->ops->set_default_key(&rdev->wiphy, 630 err = rdev->ops->set_default_key(&rdev->wiphy, dev,
631 dev, idx); 631 idx, true, true);
632 if (!err) 632 if (!err)
633 wdev->wext.default_key = idx; 633 wdev->wext.default_key = idx;
634 wdev_unlock(wdev); 634 wdev_unlock(wdev);