diff options
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 | |||
5062 | S: Maintained | 5062 | S: Maintained |
5063 | F: drivers/net/wireless/rtl818x/rtl8187* | 5063 | F: drivers/net/wireless/rtl818x/rtl8187* |
5064 | 5064 | ||
5065 | RTL8192CE WIRELESS DRIVER | ||
5066 | M: Larry Finger <Larry.Finger@lwfinger.net> | ||
5067 | M: Chaoming Li <chaoming_li@realsil.com.cn> | ||
5068 | L: linux-wireless@vger.kernel.org | ||
5069 | W: http://linuxwireless.org/ | ||
5070 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git | ||
5071 | S: Maintained | ||
5072 | F: drivers/net/wireless/rtlwifi/ | ||
5073 | F: drivers/net/wireless/rtlwifi/rtl8192ce/ | ||
5074 | |||
5065 | S3 SAVAGE FRAMEBUFFER DRIVER | 5075 | S3 SAVAGE FRAMEBUFFER DRIVER |
5066 | M: Antonino Daplas <adaplas@gmail.com> | 5076 | M: Antonino Daplas <adaplas@gmail.com> |
5067 | L: linux-fbdev@vger.kernel.org | 5077 | L: 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" | |||
279 | source "drivers/net/wireless/orinoco/Kconfig" | 279 | source "drivers/net/wireless/orinoco/Kconfig" |
280 | source "drivers/net/wireless/p54/Kconfig" | 280 | source "drivers/net/wireless/p54/Kconfig" |
281 | source "drivers/net/wireless/rt2x00/Kconfig" | 281 | source "drivers/net/wireless/rt2x00/Kconfig" |
282 | source "drivers/net/wireless/rtlwifi/Kconfig" | ||
282 | source "drivers/net/wireless/wl1251/Kconfig" | 283 | source "drivers/net/wireless/wl1251/Kconfig" |
283 | source "drivers/net/wireless/wl12xx/Kconfig" | 284 | source "drivers/net/wireless/wl12xx/Kconfig" |
284 | source "drivers/net/wireless/zd1211rw/Kconfig" | 285 | source "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/ | |||
24 | obj-$(CONFIG_ZD1211RW) += zd1211rw/ | 24 | obj-$(CONFIG_ZD1211RW) += zd1211rw/ |
25 | obj-$(CONFIG_RTL8180) += rtl818x/ | 25 | obj-$(CONFIG_RTL8180) += rtl818x/ |
26 | obj-$(CONFIG_RTL8187) += rtl818x/ | 26 | obj-$(CONFIG_RTL8187) += rtl818x/ |
27 | obj-$(CONFIG_RTL8192CE) += rtlwifi/ | ||
27 | 28 | ||
28 | # 16-bit wireless PCMCIA client drivers | 29 | # 16-bit wireless PCMCIA client drivers |
29 | obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o | 30 | obj-$(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 | ||
964 | static 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 | |||
976 | static void ar5008_restore_chainmask(struct ath_hw *ah) | 964 | static 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 | ||
29 | static 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 | |||
47 | static void ar9002_hw_init_mode_regs(struct ath_hw *ah) | 29 | static 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 | ||
35 | static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = { | 35 | static 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 | ||
611 | static 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 | |||
721 | TX_IQ_CAL_FAILED: | ||
722 | ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); | ||
723 | } | ||
724 | |||
725 | static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg) | 611 | static 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 | ||
719 | static 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 | |||
820 | TX_IQ_CAL_FAILED: | ||
821 | ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); | ||
822 | } | ||
823 | |||
833 | static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) | 824 | static 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 | ||
2976 | static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) | 2976 | static 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 | ||
3431 | static 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 | |||
3437 | static u32 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah, | ||
3438 | struct ath9k_channel *chan) | ||
3439 | { | ||
3440 | return -EINVAL; | ||
3441 | } | ||
3442 | |||
3443 | static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz) | 3431 | static 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, | |||
4495 | static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep, | 4483 | static 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 | ||
4747 | static 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 | |||
4759 | static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, | 4757 | static 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 | ||
4816 | static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah, | 4881 | static 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 | ||
4911 | unsigned 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 | |||
4846 | const struct eeprom_ops eep_ar9300_ops = { | 4932 | const 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); | |||
344 | s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah); | 315 | s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah); |
345 | 316 | ||
346 | u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz); | 317 | u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz); |
318 | |||
319 | unsigned 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 | ||
24 | static 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 | ||
20 | void ar9003_paprd_enable(struct ath_hw *ah, bool val) | 20 | void 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 | } |
31 | EXPORT_SYMBOL(ar9003_paprd_enable); | 45 | EXPORT_SYMBOL(ar9003_paprd_enable); |
32 | 46 | ||
33 | static void ar9003_paprd_setup_single_table(struct ath_hw *ah) | 47 | static 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 | |||
67 | static 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 | |||
101 | static 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 | ||
146 | static void ar9003_paprd_get_gain_table(struct ath_hw *ah) | 223 | static 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 | ||
644 | int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) | 716 | int 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 | ||
717 | int ar9003_paprd_init_table(struct ath_hw *ah) | 783 | int 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 | */ | ||
756 | static 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 | |||
773 | static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value) | 748 | static 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 | |||
1093 | void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); | 1101 | void 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) | |||
663 | extern struct ieee80211_ops ath9k_ops; | 666 | extern struct ieee80211_ops ath9k_ops; |
664 | extern int modparam_nohwcrypt; | 667 | extern int modparam_nohwcrypt; |
665 | extern int led_blink; | 668 | extern int led_blink; |
669 | extern int ath9k_pm_qos_value; | ||
666 | 670 | ||
667 | irqreturn_t ath_isr(int irq, void *dev); | 671 | irqreturn_t ath_isr(int irq, void *dev); |
668 | int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | 672 | int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, |
@@ -671,7 +675,6 @@ void ath9k_deinit_device(struct ath_softc *sc); | |||
671 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); | 675 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); |
672 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | 676 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, |
673 | struct ath9k_channel *ichan); | 677 | struct ath9k_channel *ichan); |
674 | void ath_update_chainmask(struct ath_softc *sc, int is_ht); | ||
675 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | 678 | int 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, | |||
234 | u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, | 234 | u16 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 | ||
282 | void 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, ¢ers); | ||
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 | |||
282 | int ath9k_hw_eeprom_init(struct ath_hw *ah) | 495 | int 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 | ||
402 | struct calDataPerFreqOpLoop { | 377 | struct 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 | ||
470 | struct base_eep_ar9287_header { | 445 | struct 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 | ||
528 | struct cal_data_per_freq { | 503 | struct cal_data_per_freq { |
@@ -531,8 +506,8 @@ struct cal_data_per_freq { | |||
531 | } __packed; | 506 | } __packed; |
532 | 507 | ||
533 | struct cal_data_per_freq_4k { | 508 | struct 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 | ||
538 | struct cal_target_power_leg { | 513 | struct cal_target_power_leg { |
@@ -558,8 +533,8 @@ struct cal_data_op_loop_ar9287 { | |||
558 | } __packed; | 533 | } __packed; |
559 | 534 | ||
560 | struct cal_data_per_freq_ar9287 { | 535 | struct 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 | ||
565 | union cal_data_per_freq_ar9287_u { | 540 | union 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, | |||
716 | void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah); | 687 | void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah); |
717 | int ath9k_hw_eeprom_init(struct ath_hw *ah); | 688 | int ath9k_hw_eeprom_init(struct ath_hw *ah); |
718 | 689 | ||
690 | void 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 | ||
230 | static 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, ¢ers); | ||
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 | |||
397 | static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, | 230 | static 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 | ||
1157 | static 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 | |||
1166 | static 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 | |||
1172 | static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) | 989 | static 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 | ||
223 | static 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, ¢ers); | ||
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 | |||
380 | static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah, | 223 | static 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, ¢ers); | 232 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); |
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 | ||
1128 | static 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 | |||
1134 | static 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 | |||
1143 | static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah, | 970 | static 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 | ||
591 | static 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, ¢ers); | ||
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 | |||
753 | static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah, | 590 | static 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 | ||
1429 | static 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 | |||
1447 | static 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 | |||
1457 | static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) | 1266 | static 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 | ||
226 | static inline void ath9k_enable_rfkill(struct ath_hw *ah) | ||
227 | { | ||
228 | return ath9k_hw_private_ops(ah)->enable_rfkill(ah); | ||
229 | } | ||
230 | |||
231 | static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah) | 226 | static 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 | ||
57 | static 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 | |||
64 | static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah, | 57 | static 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 | ||
285 | static void ath9k_hw_disablepcie(struct ath_hw *ah) | 278 | static 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 | ||
873 | static 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 */ |
877 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); | 879 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); |
878 | void ath9k_hw_deinit(struct ath_hw *ah); | 880 | void 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; | |||
41 | module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); | 41 | module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); |
42 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); | 42 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); |
43 | 43 | ||
44 | int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE; | ||
45 | module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH); | ||
46 | MODULE_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 | ||
323 | static 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 | |||
323 | void ath_paprd_calibrate(struct work_struct *work) | 359 | void 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 | */ | ||
531 | void 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 | |||
551 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) | 541 | static 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); |
907 | out: | ||
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 | ||
1425 | static 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 | |||
1450 | static 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 | |||
1431 | static void ath9k_remove_interface(struct ieee80211_hw *hw, | 1491 | static 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 | ||
1072 | static 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 | ||
1321 | static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | 1331 | static 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 | |||
275 | struct iwl_cfg iwl1000_bgn_cfg = { | 290 | struct 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 | ||
289 | struct iwl_cfg iwl1000_bg_cfg = { | 296 | struct 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 | |||
302 | struct iwl_cfg iwl100_bgn_cfg = { | 313 | struct 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 | ||
317 | struct iwl_cfg iwl100_bg_cfg = { | 319 | struct 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 | ||
331 | MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); | 324 | MODULE_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 | |||
523 | struct iwl_cfg iwl5300_agn_cfg = { | 534 | struct 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 | ||
537 | struct iwl_cfg iwl5100_bgn_cfg = { | 540 | struct 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 | ||
553 | struct iwl_cfg iwl5100_abg_cfg = { | 548 | struct 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 | ||
568 | struct iwl_cfg iwl5100_agn_cfg = { | 555 | struct 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 | ||
584 | struct iwl_cfg iwl5350_agn_cfg = { | 563 | struct 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 | |||
598 | struct iwl_cfg iwl5150_agn_cfg = { | 591 | struct 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 | ||
613 | struct iwl_cfg iwl5150_abg_cfg = { | 598 | struct 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 | ||
627 | MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); | 603 | MODULE_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 | }; |
514 | static struct iwl_base_params iwl6000_coex_base_params = { | 518 | static 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 | |||
553 | struct iwl_cfg iwl6005_2agn_cfg = { | 570 | struct 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 | ||
570 | struct iwl_cfg iwl6005_2abg_cfg = { | 576 | struct 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 | ||
586 | struct iwl_cfg iwl6005_2bg_cfg = { | 581 | struct 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 | ||
602 | struct iwl_cfg iwl6030_2agn_cfg = { | 606 | struct 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 | ||
623 | struct iwl_cfg iwl6030_2abg_cfg = { | 612 | struct 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 | ||
643 | struct iwl_cfg iwl6030_2bgn_cfg = { | 617 | struct 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 | ||
664 | struct iwl_cfg iwl6030_2bg_cfg = { | 623 | struct 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 | ||
684 | struct iwl_cfg iwl1030_bgn_cfg = { | 628 | struct 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 | ||
705 | struct iwl_cfg iwl1030_bg_cfg = { | 634 | struct 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, | 639 | struct 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, | 646 | struct 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 | |||
728 | struct iwl_cfg iwl6000i_2agn_cfg = { | 669 | struct 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 | ||
745 | struct iwl_cfg iwl6000i_2abg_cfg = { | 675 | struct 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 | ||
761 | struct iwl_cfg iwl6000i_2bg_cfg = { | 680 | struct 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 | ||
777 | struct iwl_cfg iwl6050_2agn_cfg = { | 698 | struct 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 | |
704 | struct iwl_cfg iwl6050_2abg_cfg = { | ||
705 | .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", | ||
706 | IWL_DEVICE_6050, | ||
790 | }; | 707 | }; |
791 | 708 | ||
792 | struct iwl_cfg iwl6150_bgn_cfg = { | 709 | struct 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 | |||
808 | struct 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 | ||
822 | struct iwl_cfg iwl6000_3agn_cfg = { | 725 | struct 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 | ||
837 | struct 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 | |||
857 | struct 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 | |||
876 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); | 740 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); |
877 | MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); | 741 | MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); |
878 | MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); | 742 | MODULE_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 | */ | ||
122 | struct 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 | */ | ||
154 | static 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 | */ | ||
351 | static 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 | */ | ||
396 | static 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 | */ | ||
436 | static 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 | |||
498 | static void | 235 | static void |
499 | iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv, | 236 | iwlcore_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 | ||
536 | static 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 | |||
276 | void 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 | |||
573 | void 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 | ||
226 | static int iwm_cfg80211_set_default_key(struct wiphy *wiphy, | 226 | static 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 | ||
1423 | static int lbs_cfg_set_default_key(struct wiphy *wiphy, | 1423 | static 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 | ||
556 | static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, | 556 | static 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 | ||
559 | static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev, | 559 | static 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 | ||
2383 | static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, | 2383 | static 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 | */ | ||
638 | static 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, ®); | ||
646 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0); | ||
647 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
648 | break; | ||
649 | case QID_BEACON: | ||
650 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
651 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
652 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
653 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | ||
654 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
655 | break; | ||
656 | default: | ||
657 | break; | ||
658 | } | ||
659 | } | ||
660 | |||
661 | static 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, ®); | ||
669 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); | ||
670 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
671 | break; | ||
672 | case QID_AC_VI: | ||
673 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | ||
674 | rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); | ||
675 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
676 | break; | ||
677 | case QID_ATIM: | ||
678 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | ||
679 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); | ||
680 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
681 | break; | ||
682 | default: | ||
683 | break; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | static 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, ®); | ||
697 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); | ||
698 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
699 | break; | ||
700 | case QID_RX: | ||
701 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
702 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1); | ||
703 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
704 | break; | ||
705 | case QID_BEACON: | ||
706 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
707 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
708 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
709 | rt2x00_set_field32(®, 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 | */ |
638 | static bool rt2400pci_get_entry_state(struct queue_entry *entry) | 720 | static 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 | */ |
881 | static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev, | ||
882 | enum dev_state state) | ||
883 | { | ||
884 | u32 reg; | ||
885 | |||
886 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
887 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, | ||
888 | (state == STATE_RADIO_RX_OFF)); | ||
889 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
890 | } | ||
891 | |||
892 | static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | 963 | static 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 | ||
1125 | static 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, ®); | ||
1131 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE)); | ||
1132 | rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK)); | ||
1133 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM)); | ||
1134 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
1135 | } | ||
1136 | |||
1137 | static 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, ®); | ||
1146 | rt2x00_set_field32(®, 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 | */ | ||
728 | static 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, ®); | ||
736 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0); | ||
737 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
738 | break; | ||
739 | case QID_BEACON: | ||
740 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
741 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
742 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
743 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | ||
744 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
745 | break; | ||
746 | default: | ||
747 | break; | ||
748 | } | ||
749 | } | ||
750 | |||
751 | static 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, ®); | ||
759 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); | ||
760 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
761 | break; | ||
762 | case QID_AC_VI: | ||
763 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | ||
764 | rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); | ||
765 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
766 | break; | ||
767 | case QID_ATIM: | ||
768 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | ||
769 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); | ||
770 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
771 | break; | ||
772 | default: | ||
773 | break; | ||
774 | } | ||
775 | } | ||
776 | |||
777 | static 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, ®); | ||
787 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); | ||
788 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
789 | break; | ||
790 | case QID_RX: | ||
791 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
792 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1); | ||
793 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
794 | break; | ||
795 | case QID_BEACON: | ||
796 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
797 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 0); | ||
798 | rt2x00_set_field32(®, CSR14_TBCN, 0); | ||
799 | rt2x00_set_field32(®, 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 | */ |
728 | static bool rt2500pci_get_entry_state(struct queue_entry *entry) | 810 | static 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 | */ |
1036 | static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev, | ||
1037 | enum dev_state state) | ||
1038 | { | ||
1039 | u32 reg; | ||
1040 | |||
1041 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
1042 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, | ||
1043 | (state == STATE_RADIO_RX_OFF)); | ||
1044 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
1045 | } | ||
1046 | |||
1047 | static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | 1118 | static 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 | ||
1279 | static 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, ®); | ||
1285 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE)); | ||
1286 | rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK)); | ||
1287 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM)); | ||
1288 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
1289 | } | ||
1290 | |||
1291 | static 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, ®); | ||
1300 | rt2x00_set_field32(®, 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 | */ | ||
744 | static 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, ®); | ||
752 | rt2x00_set_field16(®, 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, ®); | ||
757 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | ||
758 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1); | ||
759 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 1); | ||
760 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
761 | break; | ||
762 | default: | ||
763 | break; | ||
764 | } | ||
765 | } | ||
766 | |||
767 | static 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, ®); | ||
775 | rt2x00_set_field16(®, 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, ®); | ||
780 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 0); | ||
781 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 0); | ||
782 | rt2x00_set_field16(®, 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 | */ |
744 | static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) | 793 | static 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 | */ |
934 | static 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, ®); | ||
940 | rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX, | ||
941 | (state == STATE_RADIO_RX_OFF)); | ||
942 | rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); | ||
943 | } | ||
944 | |||
945 | static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev) | 983 | static 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 | ||
1206 | static 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, ®); | ||
1636 | rt2800_register_read(rt2x00dev, CH_BUSY_STA, ®); | ||
1637 | rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, ®); | ||
1628 | } | 1638 | } |
1629 | 1639 | ||
1630 | static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, | 1640 | static 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(®, INT_TIMER_CFG_PRE_TBTT_TIMER, 6 << 4); | 2269 | rt2x00_set_field32(®, 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, ®); | ||
2276 | rt2x00_set_field32(®, CH_TIME_CFG_EIFS_BUSY, 1); | ||
2277 | rt2x00_set_field32(®, CH_TIME_CFG_NAV_BUSY, 1); | ||
2278 | rt2x00_set_field32(®, CH_TIME_CFG_RX_BUSY, 1); | ||
2279 | rt2x00_set_field32(®, CH_TIME_CFG_TX_BUSY, 1); | ||
2280 | rt2x00_set_field32(®, 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(®, LDO_CFG0_BGSEL, 1); | 2612 | rt2x00_set_field32(®, 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(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); | 2617 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); |
2597 | else | 2618 | else |
2598 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); | 2619 | rt2x00_set_field32(®, 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, ®); | 3015 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); |
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 | } |
3537 | EXPORT_SYMBOL_GPL(rt2800_ampdu_action); | 3561 | EXPORT_SYMBOL_GPL(rt2800_ampdu_action); |
3538 | 3562 | ||
3563 | int 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 | } | ||
3592 | EXPORT_SYMBOL_GPL(rt2800_get_survey); | ||
3593 | |||
3539 | MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz"); | 3594 | MODULE_AUTHOR(DRV_PROJECT ", Bartlomiej Zolnierkiewicz"); |
3540 | MODULE_VERSION(DRV_VERSION); | 3595 | MODULE_VERSION(DRV_VERSION); |
3541 | MODULE_DESCRIPTION("Ralink RT2800 library"); | 3596 | MODULE_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); | |||
199 | int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 199 | int 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); |
202 | int 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 | */ | ||
191 | static 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, ®); | ||
199 | rt2x00_set_field32(®, 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, ®); | ||
204 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
205 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
206 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | ||
207 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
208 | break; | ||
209 | default: | ||
210 | break; | ||
211 | }; | ||
212 | } | ||
213 | |||
214 | static 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 | |||
236 | static 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, ®); | ||
244 | rt2x00_set_field32(®, 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, ®); | ||
249 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); | ||
250 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); | ||
251 | rt2x00_set_field32(®, 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 | */ |
191 | static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) | 262 | static 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 | */ |
326 | static 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, ®); | ||
332 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, | ||
333 | (state == STATE_RADIO_RX_ON)); | ||
334 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
335 | } | ||
336 | |||
337 | static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | 397 | static 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 | */ | ||
571 | static 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 | |||
585 | static 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, ®); | ||
596 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, (queue->qid == QID_AC_BE)); | ||
597 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, (queue->qid == QID_AC_BK)); | ||
598 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, (queue->qid == QID_AC_VI)); | ||
599 | rt2x00_set_field32(®, 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 | */ |
606 | static void rt2800pci_fill_rxdone(struct queue_entry *entry, | 627 | static 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 | ||
949 | static const struct rt2800_ops rt2800pci_rt2800_ops = { | 971 | static 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); | |||
50 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 50 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * Queue handlers. | ||
54 | */ | ||
55 | static 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, ®); | ||
63 | rt2x00_set_field32(®, 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, ®); | ||
68 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
69 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
70 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | ||
71 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
72 | break; | ||
73 | default: | ||
74 | break; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | static 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, ®); | ||
86 | rt2x00_set_field32(®, 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, ®); | ||
91 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); | ||
92 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); | ||
93 | rt2x00_set_field32(®, 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 | */ |
55 | static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) | 104 | static 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 | */ |
110 | static 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, ®); | ||
116 | rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, | ||
117 | (state == STATE_RADIO_RX_ON)); | ||
118 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
119 | } | ||
120 | |||
121 | static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) | 159 | static 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, ®); | 287 | rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®); |
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, ®); | 303 | rt2800_register_read(rt2x00dev, TXRXQ_PCNT, ®); |
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 | ||
392 | static 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 | ||
567 | static const struct rt2800_ops rt2800usb_rt2800_ops = { | 594 | static 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, | |||
1068 | struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, | 1074 | struct 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 | */ | ||
1085 | void 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 | */ | ||
1094 | void 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 | */ | ||
1102 | void 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 | */ | ||
1110 | void 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 | */ | ||
1120 | void 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 | */ | ||
1128 | void 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 | */ | ||
1137 | void 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 | */ | ||
1147 | void 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 | */ |
1094 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); | 1172 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); |
1095 | void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev); | 1173 | void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev); |
1174 | void rt2x00lib_dmastart(struct queue_entry *entry); | ||
1096 | void rt2x00lib_dmadone(struct queue_entry *entry); | 1175 | void rt2x00lib_dmadone(struct queue_entry *entry); |
1097 | void rt2x00lib_txdone(struct queue_entry *entry, | 1176 | void 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 | ||
168 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 166 | void 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 | } |
237 | EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); | 227 | EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); |
238 | 228 | ||
229 | void 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 | } | ||
234 | EXPORT_SYMBOL_GPL(rt2x00lib_dmastart); | ||
235 | |||
239 | void rt2x00lib_dmadone(struct queue_entry *entry) | 236 | void 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 | } |
408 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 405 | EXPORT_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 | } |
574 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); | 569 | EXPORT_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, | |||
178 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); | 178 | void 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 | */ | ||
187 | void 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 | } |
753 | EXPORT_SYMBOL_GPL(rt2x00mac_flush); | 725 | EXPORT_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 | ||
200 | void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) | 200 | void 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 | ||
213 | static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, | 216 | static 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 | ||
474 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | 477 | int 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 | ||
741 | void 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 | } | ||
763 | EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue); | ||
764 | |||
765 | void 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 | } | ||
793 | EXPORT_SYMBOL_GPL(rt2x00queue_unpause_queue); | ||
794 | |||
795 | void 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 | } | ||
813 | EXPORT_SYMBOL_GPL(rt2x00queue_start_queue); | ||
814 | |||
815 | void 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 | } | ||
830 | EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue); | ||
831 | |||
832 | void 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 | } | ||
898 | EXPORT_SYMBOL_GPL(rt2x00queue_flush_queue); | ||
899 | |||
900 | void 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 | } | ||
913 | EXPORT_SYMBOL_GPL(rt2x00queue_start_queues); | ||
914 | |||
915 | void 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 | } | ||
932 | EXPORT_SYMBOL_GPL(rt2x00queue_stop_queues); | ||
933 | |||
934 | void 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 | } | ||
943 | EXPORT_SYMBOL_GPL(rt2x00queue_flush_queues); | ||
944 | |||
738 | static void rt2x00queue_reset(struct data_queue *queue) | 945 | static 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 | ||
756 | void 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 | |||
764 | void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) | 963 | void 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) | |||
902 | static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, | 1098 | static 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 | */ |
59 | enum data_queue_qid { | 59 | enum 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 | */ |
344 | enum queue_entry_flags { | 347 | enum 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 | */ | ||
410 | enum 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 | ||
260 | void 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 | } | ||
265 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); | ||
266 | |||
267 | static 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 | |||
286 | void 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 | } | ||
291 | EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); | ||
292 | |||
293 | static 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 | |||
331 | static 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 | |||
339 | void 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 | } | ||
352 | EXPORT_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 | ||
326 | static 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 | |||
353 | void 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 | } | ||
373 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue); | ||
374 | |||
375 | static 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 | |||
394 | void 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 | } | ||
441 | EXPORT_SYMBOL_GPL(rt2x00usb_flush_queue); | ||
442 | |||
443 | static 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 | |||
451 | static 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 | |||
459 | void 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 | } | ||
472 | EXPORT_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 | } |
427 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | 482 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); |
428 | 483 | ||
@@ -431,25 +486,10 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | |||
431 | */ | 486 | */ |
432 | void rt2x00usb_clear_entry(struct queue_entry *entry) | 487 | void 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 | } |
454 | EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); | 494 | EXPORT_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 | */ |
387 | void rt2x00usb_kick_tx_queue(struct data_queue *queue); | 387 | void 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 | */ |
396 | void rt2x00usb_kill_tx_queue(struct data_queue *queue); | 396 | void 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 | */ | ||
1145 | static 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, ®); | ||
1153 | rt2x00_set_field32(®, 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, ®); | ||
1158 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
1159 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
1160 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | ||
1161 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1162 | break; | ||
1163 | default: | ||
1164 | break; | ||
1165 | } | ||
1166 | } | ||
1167 | |||
1168 | static 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, ®); | ||
1176 | rt2x00_set_field32(®, 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, ®); | ||
1181 | rt2x00_set_field32(®, 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, ®); | ||
1186 | rt2x00_set_field32(®, 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, ®); | ||
1191 | rt2x00_set_field32(®, 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 | |||
1199 | static 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, ®); | ||
1207 | rt2x00_set_field32(®, 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, ®); | ||
1212 | rt2x00_set_field32(®, 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, ®); | ||
1217 | rt2x00_set_field32(®, 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, ®); | ||
1222 | rt2x00_set_field32(®, 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, ®); | ||
1227 | rt2x00_set_field32(®, 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, ®); | ||
1232 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1233 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
1234 | rt2x00_set_field32(®, 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 | */ |
1145 | static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) | 1245 | static 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 | */ |
1619 | static 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, ®); | ||
1625 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, | ||
1626 | (state == STATE_RADIO_RX_OFF)); | ||
1627 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
1628 | } | ||
1629 | |||
1630 | static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | 1719 | static 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 | ||
1928 | static 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, ®); | ||
1934 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue->qid == QID_AC_BE)); | ||
1935 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue->qid == QID_AC_BK)); | ||
1936 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue->qid == QID_AC_VI)); | ||
1937 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue->qid == QID_AC_VO)); | ||
1938 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | ||
1939 | } | ||
1940 | |||
1941 | static 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, ®); | ||
1952 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (queue->qid == QID_AC_BE)); | ||
1953 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (queue->qid == QID_AC_BK)); | ||
1954 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (queue->qid == QID_AC_VI)); | ||
1955 | rt2x00_set_field32(®, 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 | */ | ||
1036 | static 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, ®); | ||
1044 | rt2x00_set_field32(®, 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, ®); | ||
1049 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
1050 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
1051 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | ||
1052 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1053 | break; | ||
1054 | default: | ||
1055 | break; | ||
1056 | } | ||
1057 | } | ||
1058 | |||
1059 | static 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, ®); | ||
1067 | rt2x00_set_field32(®, 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, ®); | ||
1072 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1073 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
1074 | rt2x00_set_field32(®, 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 | */ |
1036 | static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) | 1085 | static 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 | */ |
1327 | static 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, ®); | ||
1333 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, | ||
1334 | (state == STATE_RADIO_RX_OFF)); | ||
1335 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
1336 | } | ||
1337 | |||
1338 | static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev) | 1376 | static 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 | ||
1582 | static 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 @@ | |||
1 | config 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 | |||
12 | config 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 @@ | |||
1 | obj-$(CONFIG_RTLWIFI) += rtlwifi.o | ||
2 | rtlwifi-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 | |||
13 | obj-$(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 | *********************************************************/ | ||
62 | static 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 | |||
79 | static 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 | |||
94 | static 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 | |||
106 | static 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 | |||
160 | static 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 | |||
217 | static 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 | |||
236 | void 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 | |||
246 | void 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 | |||
273 | void rtl_deinit_rfkill(struct ieee80211_hw *hw) | ||
274 | { | ||
275 | wiphy_rfkill_stop_polling(hw->wiphy); | ||
276 | } | ||
277 | |||
278 | int 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 | |||
328 | void rtl_deinit_core(struct ieee80211_hw *hw) | ||
329 | { | ||
330 | /*RC*/ | ||
331 | rtl_rate_control_unregister(); | ||
332 | } | ||
333 | |||
334 | void 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 | *********************************************************/ | ||
353 | static 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 | |||
371 | static 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 | |||
396 | static 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 | |||
424 | static 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 | |||
460 | static 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 | |||
481 | static 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 | |||
495 | void 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 | } | ||
568 | EXPORT_SYMBOL(rtl_get_tcb_desc); | ||
569 | |||
570 | bool 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 | |||
587 | bool 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*/ | ||
632 | u8 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 | |||
699 | end: | ||
700 | return false; | ||
701 | } | ||
702 | |||
703 | /********************************************************* | ||
704 | * | ||
705 | * functions called by core.c | ||
706 | * | ||
707 | *********************************************************/ | ||
708 | int 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 | |||
738 | int 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 | *********************************************************/ | ||
772 | void 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 | |||
874 | void 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 | *********************************************************/ | ||
891 | static 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 | |||
900 | static 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 | |||
921 | static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, | ||
922 | rtl_show_debug_level, rtl_store_debug_level); | ||
923 | |||
924 | static 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 | */ | ||
937 | struct attribute_group rtl_attribute_group = { | ||
938 | .name = "rtlsysfs", | ||
939 | .attrs = rtl_sysfs_entries, | ||
940 | }; | ||
941 | |||
942 | MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>"); | ||
943 | MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>"); | ||
944 | MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>"); | ||
945 | MODULE_LICENSE("GPL"); | ||
946 | MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); | ||
947 | |||
948 | static int __init rtl_core_module_init(void) | ||
949 | { | ||
950 | return 0; | ||
951 | } | ||
952 | |||
953 | static void __exit rtl_core_module_exit(void) | ||
954 | { | ||
955 | } | ||
956 | |||
957 | module_init(rtl_core_module_init); | ||
958 | module_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 | |||
96 | int rtl_init_core(struct ieee80211_hw *hw); | ||
97 | void rtl_deinit_core(struct ieee80211_hw *hw); | ||
98 | void rtl_init_rx_config(struct ieee80211_hw *hw); | ||
99 | void rtl_init_rfkill(struct ieee80211_hw *hw); | ||
100 | void rtl_deinit_rfkill(struct ieee80211_hw *hw); | ||
101 | |||
102 | void rtl_watch_dog_timer_callback(unsigned long data); | ||
103 | void rtl_deinit_deferred_work(struct ieee80211_hw *hw); | ||
104 | |||
105 | bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); | ||
106 | bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
107 | u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); | ||
108 | |||
109 | void rtl_watch_dog_timer_callback(unsigned long data); | ||
110 | int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, | ||
111 | u16 tid, u16 *ssn); | ||
112 | int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid); | ||
113 | void rtl_watchdog_wq_callback(void *data); | ||
114 | |||
115 | void 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 | |||
119 | extern 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 | |||
31 | void 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 | |||
43 | static 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 | |||
129 | u8 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 | } | ||
162 | EXPORT_SYMBOL(rtl_cam_add_one_entry); | ||
163 | |||
164 | int 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 | } | ||
186 | EXPORT_SYMBOL(rtl_cam_delete_one_entry); | ||
187 | |||
188 | void 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 | } | ||
196 | EXPORT_SYMBOL(rtl_cam_reset_all_entry); | ||
197 | |||
198 | void 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 | } | ||
237 | EXPORT_SYMBOL(rtl_cam_mark_invalid); | ||
238 | |||
239 | void 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 | } | ||
291 | EXPORT_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 | |||
43 | extern void rtl_cam_reset_all_entry(struct ieee80211_hw *hw); | ||
44 | extern 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); | ||
47 | int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, | ||
48 | u32 ul_key_id); | ||
49 | void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index); | ||
50 | void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index); | ||
51 | void 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. */ | ||
36 | static 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); | ||
51 | out: | ||
52 | mutex_unlock(&rtlpriv->locks.conf_mutex); | ||
53 | return err; | ||
54 | } | ||
55 | |||
56 | static 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 | |||
85 | static 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 | |||
102 | err_free: | ||
103 | dev_kfree_skb_any(skb); | ||
104 | return NETDEV_TX_OK; | ||
105 | } | ||
106 | |||
107 | static 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 | |||
158 | out: | ||
159 | mutex_unlock(&rtlpriv->locks.conf_mutex); | ||
160 | return err; | ||
161 | } | ||
162 | |||
163 | static 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 | |||
197 | static 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 | |||
311 | static 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 | |||
394 | static 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 | */ | ||
422 | static 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 | |||
445 | static 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 | |||
702 | out: | ||
703 | mutex_unlock(&rtlpriv->locks.conf_mutex); | ||
704 | } | ||
705 | |||
706 | static 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 | |||
715 | static 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 | |||
725 | static 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 | |||
733 | static 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 | |||
748 | static 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 | |||
786 | static 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 | |||
805 | static 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 | |||
829 | static 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 | } | ||
972 | out_unlock: | ||
973 | mutex_unlock(&rtlpriv->locks.conf_mutex); | ||
974 | rtlpriv->sec.being_setkey = false; | ||
975 | return err; | ||
976 | } | ||
977 | |||
978 | static 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 | |||
1010 | const 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 | |||
41 | extern 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 | |||
31 | void 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 | |||
135 | enum 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 | |||
211 | void 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 | |||
33 | static const u8 MAX_PGPKT_SIZE = 9; | ||
34 | static const u8 PGPKT_DATA_SIZE = 8; | ||
35 | static const int EFUSE_MAX_SIZE = 512; | ||
36 | |||
37 | static const u8 EFUSE_OOB_PROTECT_BYTES = 15; | ||
38 | |||
39 | static 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 | |||
55 | static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, | ||
56 | u8 *pbuf); | ||
57 | static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset, | ||
58 | u8 *value); | ||
59 | static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset, | ||
60 | u16 *value); | ||
61 | static void efuse_shadow_read_4byte(struct ieee80211_hw *hw, u16 offset, | ||
62 | u32 *value); | ||
63 | static void efuse_shadow_write_1byte(struct ieee80211_hw *hw, u16 offset, | ||
64 | u8 value); | ||
65 | static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, u16 offset, | ||
66 | u16 value); | ||
67 | static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset, | ||
68 | u32 value); | ||
69 | static int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, | ||
70 | u8 *data); | ||
71 | static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, | ||
72 | u8 data); | ||
73 | static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse); | ||
74 | static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, | ||
75 | u8 *data); | ||
76 | static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset, | ||
77 | u8 word_en, u8 *data); | ||
78 | static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata, | ||
79 | u8 *targetdata); | ||
80 | static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, | ||
81 | u16 efuse_addr, u8 word_en, u8 *data); | ||
82 | static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, | ||
83 | u8 pwrstate); | ||
84 | static u16 efuse_get_current_size(struct ieee80211_hw *hw); | ||
85 | static u8 efuse_calculate_word_cnts(u8 word_en); | ||
86 | |||
87 | void 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 | |||
111 | u8 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 | } | ||
153 | EXPORT_SYMBOL(efuse_read_1byte); | ||
154 | |||
155 | void 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 | |||
201 | static 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 | |||
232 | void 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 | |||
335 | bool 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 | |||
377 | void 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 | |||
389 | void 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 | |||
401 | bool 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 | |||
476 | void 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 | } | ||
492 | EXPORT_SYMBOL(rtl_efuse_shadow_map_update); | ||
493 | |||
494 | void 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 | |||
506 | void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx) | ||
507 | { | ||
508 | } | ||
509 | |||
510 | static 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 | |||
517 | static 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 | |||
527 | static 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 | |||
538 | static 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 | |||
546 | static 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 | |||
556 | static 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 | |||
572 | static 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 | |||
604 | static 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 | |||
637 | static 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 | |||
644 | static 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 | |||
681 | static 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 | |||
728 | static 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 | |||
833 | static 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 | |||
897 | static 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 | |||
992 | static 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 | |||
1016 | static 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 | |||
1076 | static 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 | |||
1136 | static 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 | |||
1158 | static 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 | |||
1172 | void 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 | |||
1186 | bool 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 | |||
56 | struct efuse_map { | ||
57 | u8 offset; | ||
58 | u8 word_start; | ||
59 | u8 byte_start; | ||
60 | u8 byte_cnts; | ||
61 | }; | ||
62 | |||
63 | struct pgpkt_struct { | ||
64 | u8 offset; | ||
65 | u8 word_en; | ||
66 | u8 data[8]; | ||
67 | }; | ||
68 | |||
69 | enum 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 | |||
85 | enum { | ||
86 | VOLTAGE_V25 = 0x03, | ||
87 | LDOE25_SHIFT = 28, | ||
88 | }; | ||
89 | |||
90 | struct 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 | |||
106 | extern void efuse_initialize(struct ieee80211_hw *hw); | ||
107 | extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address); | ||
108 | extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value); | ||
109 | extern void read_efuse(struct ieee80211_hw *hw, u16 _offset, | ||
110 | u16 _size_byte, u8 *pbuf); | ||
111 | extern void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, | ||
112 | u16 offset, u32 *value); | ||
113 | extern void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, | ||
114 | u16 offset, u32 value); | ||
115 | extern bool efuse_shadow_update(struct ieee80211_hw *hw); | ||
116 | extern bool efuse_shadow_update_chk(struct ieee80211_hw *hw); | ||
117 | extern void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw); | ||
118 | extern void efuse_force_write_vendor_Id(struct ieee80211_hw *hw); | ||
119 | extern void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx); | ||
120 | extern bool efuse_program_map(struct ieee80211_hw *hw, | ||
121 | char *p_filename, u8 tabletype); | ||
122 | extern 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 | |||
36 | static 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*/ | ||
44 | static 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 | |||
150 | static 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.*/ | ||
165 | static 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*/ | ||
180 | static 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 | */ | ||
236 | static 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 | |||
299 | static 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 | |||
327 | static 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 | |||
345 | static 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 | |||
372 | static 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 | |||
386 | static 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 | |||
432 | static 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 | |||
449 | static void _rtl_pci_io_handler_release(struct ieee80211_hw *hw) | ||
450 | { | ||
451 | } | ||
452 | |||
453 | static 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 | |||
524 | static 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 | } | ||
649 | done: | ||
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 | |||
674 | void _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 | |||
743 | static 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 | |||
854 | done: | ||
855 | spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); | ||
856 | return IRQ_HANDLED; | ||
857 | } | ||
858 | |||
859 | static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw) | ||
860 | { | ||
861 | _rtl_pci_rx_interrupt(hw); | ||
862 | } | ||
863 | |||
864 | static 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 | |||
903 | static 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 | |||
928 | static 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 | |||
978 | static 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 | |||
1020 | static 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 | |||
1093 | static 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 | |||
1119 | static 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 | |||
1149 | static 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 | |||
1168 | err_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 | |||
1178 | static 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 | |||
1193 | int 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 | |||
1257 | unsigned 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 | |||
1292 | out: | ||
1293 | return hw_queue_index; | ||
1294 | } | ||
1295 | |||
1296 | int 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 | |||
1413 | void 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 | |||
1428 | int 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 | |||
1445 | int 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 | |||
1480 | void 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 | |||
1522 | static 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 | |||
1652 | int __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 | |||
1815 | fail3: | ||
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 | |||
1824 | fail2: | ||
1825 | pci_release_regions(pdev); | ||
1826 | |||
1827 | fail1: | ||
1828 | |||
1829 | pci_disable_device(pdev); | ||
1830 | |||
1831 | return -ENODEV; | ||
1832 | |||
1833 | } | ||
1834 | EXPORT_SYMBOL(rtl_pci_probe); | ||
1835 | |||
1836 | void 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 | } | ||
1881 | EXPORT_SYMBOL(rtl_pci_disconnect); | ||
1882 | |||
1883 | /*************************************** | ||
1884 | kernel pci power state define: | ||
1885 | PCI_D0 ((pci_power_t __force) 0) | ||
1886 | PCI_D1 ((pci_power_t __force) 1) | ||
1887 | PCI_D2 ((pci_power_t __force) 2) | ||
1888 | PCI_D3hot ((pci_power_t __force) 3) | ||
1889 | PCI_D3cold ((pci_power_t __force) 4) | ||
1890 | PCI_UNKNOWN ((pci_power_t __force) 5) | ||
1891 | |||
1892 | This function is called when system | ||
1893 | goes into suspend state mac80211 will | ||
1894 | call rtl_mac_stop() from the mac80211 | ||
1895 | suspend function first, So there is | ||
1896 | no need to call hw_disable here. | ||
1897 | ****************************************/ | ||
1898 | int 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 | } | ||
1906 | EXPORT_SYMBOL(rtl_pci_suspend); | ||
1907 | |||
1908 | int 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 | } | ||
1923 | EXPORT_SYMBOL(rtl_pci_resume); | ||
1924 | |||
1925 | struct 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 | /* | ||
35 | 1: MSDU packet queue, | ||
36 | 2: 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 | |||
123 | enum 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 | |||
132 | struct rtl_rx_desc { | ||
133 | u32 dword[8]; | ||
134 | } __packed; | ||
135 | |||
136 | struct rtl_tx_desc { | ||
137 | u32 dword[16]; | ||
138 | } __packed; | ||
139 | |||
140 | struct rtl_tx_cmd_desc { | ||
141 | u32 dword[16]; | ||
142 | } __packed; | ||
143 | |||
144 | struct 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 | |||
152 | struct 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 | |||
159 | struct 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 | |||
202 | struct 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 | |||
226 | struct 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 | |||
235 | int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw); | ||
236 | |||
237 | extern struct rtl_intf_ops rtl_pci_ops; | ||
238 | |||
239 | int __devinit rtl_pci_probe(struct pci_dev *pdev, | ||
240 | const struct pci_device_id *id); | ||
241 | void rtl_pci_disconnect(struct pci_dev *pdev); | ||
242 | int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state); | ||
243 | int rtl_pci_resume(struct pci_dev *pdev); | ||
244 | |||
245 | static 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 | |||
250 | static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr) | ||
251 | { | ||
252 | return readw((u8 *) rtlpriv->io.pci_mem_start + addr); | ||
253 | } | ||
254 | |||
255 | static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr) | ||
256 | { | ||
257 | return readl((u8 *) rtlpriv->io.pci_mem_start + addr); | ||
258 | } | ||
259 | |||
260 | static 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 | |||
265 | static 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 | |||
271 | static 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 | |||
277 | static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val) | ||
278 | { | ||
279 | outl(val, port); | ||
280 | } | ||
281 | |||
282 | static inline void rtl_pci_raw_write_port_uchar(u32 port, u8 val) | ||
283 | { | ||
284 | outb(val, port); | ||
285 | } | ||
286 | |||
287 | static inline void rtl_pci_raw_read_port_uchar(u32 port, u8 *pval) | ||
288 | { | ||
289 | *pval = inb(port); | ||
290 | } | ||
291 | |||
292 | static inline void rtl_pci_raw_read_port_ushort(u32 port, u16 *pval) | ||
293 | { | ||
294 | *pval = inw(port); | ||
295 | } | ||
296 | |||
297 | static 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 | |||
34 | bool 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 | } | ||
62 | EXPORT_SYMBOL(rtl_ps_enable_nic); | ||
63 | |||
64 | bool 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 | } | ||
80 | EXPORT_SYMBOL(rtl_ps_disable_nic); | ||
81 | |||
82 | bool 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 | |||
134 | no_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 | } | ||
186 | EXPORT_SYMBOL(rtl_ps_set_rf_state); | ||
187 | |||
188 | static 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 | |||
219 | void 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 | |||
271 | void 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 | |||
284 | void 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 | */ | ||
317 | static 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.*/ | ||
344 | static 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.*/ | ||
421 | void 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.*/ | ||
464 | void 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 | |||
33 | bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, | ||
34 | enum rf_pwrstate state_toset, u32 changesource, | ||
35 | bool protect_or_not); | ||
36 | bool rtl_ps_enable_nic(struct ieee80211_hw *hw); | ||
37 | bool rtl_ps_disable_nic(struct ieee80211_hw *hw); | ||
38 | void rtl_ips_nic_off(struct ieee80211_hw *hw); | ||
39 | void rtl_ips_nic_on(struct ieee80211_hw *hw); | ||
40 | void rtl_ips_nic_off_wq_callback(void *data); | ||
41 | void rtl_lps_enter(struct ieee80211_hw *hw); | ||
42 | void 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 | */ | ||
40 | static 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 | |||
70 | static 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 | |||
93 | static 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 | |||
122 | static 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*/ | ||
139 | static 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 | |||
177 | static 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 | |||
220 | static 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 | |||
271 | static 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 | |||
278 | static void rtl_rate_free(void *rtlpriv) | ||
279 | { | ||
280 | return; | ||
281 | } | ||
282 | |||
283 | static 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 | |||
301 | static 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 | |||
308 | static 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 | |||
321 | int rtl_rate_control_register(void) | ||
322 | { | ||
323 | return ieee80211_rate_control_register(&rtl_rate_ops); | ||
324 | } | ||
325 | |||
326 | void 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 | |||
33 | struct rtl_rate_priv { | ||
34 | u8 cur_ratetab_idx; | ||
35 | u8 ht_cap; | ||
36 | }; | ||
37 | |||
38 | int rtl_rate_control_register(void); | ||
39 | void 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 | |||
33 | static 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 | |||
69 | static 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 | |||
77 | static 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 | |||
87 | static 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 | |||
96 | static bool _rtl_is_radar_freq(u16 center_freq) | ||
97 | { | ||
98 | return (center_freq >= 5260 && center_freq <= 5700); | ||
99 | } | ||
100 | |||
101 | static 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, ®_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 */ | ||
155 | static 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, ®_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, ®_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 | */ | ||
209 | static 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 | |||
243 | static 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 | |||
252 | static 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 | |||
268 | static 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 | |||
290 | static 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 | |||
317 | static 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 | |||
336 | static 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 | |||
347 | int 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 | |||
392 | int 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 | |||
33 | struct country_code_to_enum_rd { | ||
34 | u16 countrycode; | ||
35 | const char *isoName; | ||
36 | }; | ||
37 | |||
38 | enum 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 | |||
57 | int rtl_regd_init(struct ieee80211_hw *hw, | ||
58 | int (*reg_notifier) (struct wiphy *wiphy, | ||
59 | struct regulatory_request *request)); | ||
60 | int 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 @@ | |||
1 | rtl8192ce-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 | |||
12 | obj-$(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 | |||
124 | enum 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 | |||
135 | enum 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 | |||
142 | enum rf_optype { | ||
143 | RF_OP_BY_SW_3WIRE = 0, | ||
144 | RF_OP_BY_FW, | ||
145 | RF_OP_MAX | ||
146 | }; | ||
147 | |||
148 | enum rf_power_state { | ||
149 | RF_ON, | ||
150 | RF_OFF, | ||
151 | RF_SLEEP, | ||
152 | RF_SHUT_DOWN, | ||
153 | }; | ||
154 | |||
155 | enum power_save_mode { | ||
156 | POWER_SAVE_MODE_ACTIVE, | ||
157 | POWER_SAVE_MODE_SAVE, | ||
158 | }; | ||
159 | |||
160 | enum power_polocy_config { | ||
161 | POWERCFG_MAX_POWER_SAVINGS, | ||
162 | POWERCFG_GLOBAL_POWER_SAVINGS, | ||
163 | POWERCFG_LOCAL_POWER_SAVINGS, | ||
164 | POWERCFG_LENOVO, | ||
165 | }; | ||
166 | |||
167 | enum 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 | |||
174 | enum 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 | |||
199 | enum 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 | |||
210 | enum 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 | |||
245 | struct phy_sts_cck_8192s_t { | ||
246 | u8 adc_pwdb_X[4]; | ||
247 | u8 sq_rpt; | ||
248 | u8 cck_agc_rpt; | ||
249 | }; | ||
250 | |||
251 | struct 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 | |||
38 | struct dig_t dm_digtable; | ||
39 | static struct ps_t dm_pstable; | ||
40 | |||
41 | static 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 | |||
81 | static 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 | |||
117 | static 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 | |||
153 | static 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 | |||
175 | static 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 | |||
201 | static 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 | |||
250 | static 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 | |||
274 | static 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 | |||
311 | static 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 | |||
362 | static 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 | |||
391 | static 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 | |||
463 | static 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 | |||
486 | static 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 | |||
499 | static 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 | |||
509 | static 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 | |||
587 | void 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 | |||
607 | static 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 | |||
636 | void 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 | |||
644 | static 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 | |||
703 | dm_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 | |||
709 | static 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 | |||
1140 | static 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 | |||
1153 | static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) | ||
1154 | { | ||
1155 | rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw); | ||
1156 | } | ||
1157 | |||
1158 | static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw) | ||
1159 | { | ||
1160 | rtl92c_dm_txpower_tracking_callback_thermalmeter(hw); | ||
1161 | } | ||
1162 | |||
1163 | static 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 | |||
1187 | void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw) | ||
1188 | { | ||
1189 | rtl92c_dm_check_txpower_tracking_thermal_meter(hw); | ||
1190 | } | ||
1191 | |||
1192 | void 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 | |||
1207 | static 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 | |||
1275 | static 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 | |||
1284 | static 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 | |||
1329 | void 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 | |||
1396 | static 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 | |||
1436 | void 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 | |||
1449 | void 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 | |||
89 | struct 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 | |||
97 | struct 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 | |||
123 | struct 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 | |||
133 | enum 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 | |||
144 | enum 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 | |||
152 | enum dm_1r_cca_e { | ||
153 | CCA_1R = 0, | ||
154 | CCA_2R = 1, | ||
155 | CCA_MAX = 2, | ||
156 | }; | ||
157 | |||
158 | enum dm_rf_e { | ||
159 | RF_SAVE = 0, | ||
160 | RF_NORMAL = 1, | ||
161 | RF_MAX = 2, | ||
162 | }; | ||
163 | |||
164 | enum dm_sw_ant_switch_e { | ||
165 | ANS_ANTENNA_B = 1, | ||
166 | ANS_ANTENNA_A = 2, | ||
167 | ANS_ANTENNA_MAX = 3, | ||
168 | }; | ||
169 | |||
170 | enum 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 | |||
178 | enum 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 | |||
187 | extern struct dig_t dm_digtable; | ||
188 | void rtl92c_dm_init(struct ieee80211_hw *hw); | ||
189 | void rtl92c_dm_watchdog(struct ieee80211_hw *hw); | ||
190 | void rtl92c_dm_write_dig(struct ieee80211_hw *hw); | ||
191 | void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw); | ||
192 | void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); | ||
193 | void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); | ||
194 | void 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 | |||
39 | static 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 | |||
74 | static 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 | |||
102 | static 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 | |||
115 | static 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 | |||
131 | static 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 | |||
174 | static 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 | |||
221 | exit: | ||
222 | return err; | ||
223 | } | ||
224 | |||
225 | int 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 | |||
285 | static 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 | |||
299 | static 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 | |||
504 | void 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 | |||
523 | void 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 | |||
543 | void 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 | |||
563 | static 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 | |||
603 | static 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 | |||
713 | void 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 | |||
797 | void 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 | |||
44 | struct 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 | |||
63 | enum 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 | |||
90 | int rtl92c_download_fw(struct ieee80211_hw *hw); | ||
91 | void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, | ||
92 | u32 cmd_len, u8 *p_cmdbuffer); | ||
93 | void rtl92c_firmware_selfreset(struct ieee80211_hw *hw); | ||
94 | void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); | ||
95 | void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); | ||
96 | void 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 | |||
46 | static 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 | |||
58 | static 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 | |||
71 | static 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 | |||
84 | static void _rtl92ce_enable_bcn_sub_func(struct ieee80211_hw *hw) | ||
85 | { | ||
86 | _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(1)); | ||
87 | } | ||
88 | |||
89 | static void _rtl92ce_disable_bcn_sub_func(struct ieee80211_hw *hw) | ||
90 | { | ||
91 | _rtl92ce_set_bcn_ctrl_reg(hw, BIT(1), 0); | ||
92 | } | ||
93 | |||
94 | void 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 | |||
157 | void 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 | |||
565 | static 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 | |||
592 | static 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 | |||
665 | static 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 | |||
684 | static 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 | |||
791 | static 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 | |||
862 | static 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 | |||
880 | void 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 | |||
914 | int 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 | |||
1017 | static 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 | |||
1080 | static 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 | |||
1141 | static 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 *) (®_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 *) (®_rcr)); | ||
1169 | } | ||
1170 | } | ||
1171 | |||
1172 | int 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 | |||
1180 | void 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 | |||
1218 | void 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 | |||
1228 | void 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 | |||
1238 | static 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 | |||
1268 | void 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 | |||
1286 | void 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 | |||
1301 | void 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 | |||
1320 | void 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 | |||
1333 | void 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 | |||
1349 | static 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 | |||
1362 | static 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 | |||
1589 | static 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 | |||
1674 | static 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 | |||
1697 | void 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 | |||
1732 | void 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 | |||
1812 | void 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 | |||
1932 | void 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 | |||
1947 | bool 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 | |||
2046 | void 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 | |||
33 | void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | ||
34 | void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw); | ||
35 | void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, | ||
36 | u32 *p_inta, u32 *p_intb); | ||
37 | int rtl92ce_hw_init(struct ieee80211_hw *hw); | ||
38 | void rtl92ce_card_disable(struct ieee80211_hw *hw); | ||
39 | void rtl92ce_enable_interrupt(struct ieee80211_hw *hw); | ||
40 | void rtl92ce_disable_interrupt(struct ieee80211_hw *hw); | ||
41 | int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); | ||
42 | void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci); | ||
43 | void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw); | ||
44 | void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw); | ||
45 | void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, | ||
46 | u32 add_msr, u32 rm_msr); | ||
47 | void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | ||
48 | void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw); | ||
49 | void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level); | ||
50 | void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw); | ||
51 | bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); | ||
52 | void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw); | ||
53 | void 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 | |||
35 | void 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 | |||
63 | void 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 | |||
98 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) | ||
99 | { | ||
100 | } | ||
101 | |||
102 | void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw) | ||
103 | { | ||
104 | } | ||
105 | |||
106 | void _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 | |||
125 | void 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 | |||
33 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw); | ||
34 | void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw); | ||
35 | void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); | ||
36 | void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); | ||
37 | void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); | ||
38 | void _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 | |||
40 | static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, | ||
41 | enum radio_path rfpath, u32 offset); | ||
42 | static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, | ||
43 | enum radio_path rfpath, u32 offset, | ||
44 | u32 data); | ||
45 | static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, | ||
46 | enum radio_path rfpath, u32 offset); | ||
47 | static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, | ||
48 | enum radio_path rfpath, u32 offset, | ||
49 | u32 data); | ||
50 | static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); | ||
51 | static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); | ||
52 | static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); | ||
53 | static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | ||
54 | u8 configtype); | ||
55 | static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | ||
56 | u8 configtype); | ||
57 | static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); | ||
58 | static 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); | ||
62 | static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | ||
63 | u8 channel, u8 *stage, u8 *step, | ||
64 | u32 *delay); | ||
65 | static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | ||
66 | enum wireless_mode wirelessmode, | ||
67 | long power_indbm); | ||
68 | static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, | ||
69 | enum radio_path rfpath); | ||
70 | static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, | ||
71 | enum wireless_mode wirelessmode, | ||
72 | u8 txpwridx); | ||
73 | u32 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 | |||
93 | void 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 | |||
117 | u32 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 | |||
152 | void 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 | |||
200 | static 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 | |||
207 | static 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 | |||
214 | static 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 | |||
264 | static 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 | |||
287 | static 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 | |||
298 | static 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 | |||
312 | bool 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 | |||
324 | bool 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 | |||
350 | bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) | ||
351 | { | ||
352 | return rtl92c_phy_rf6052_config(hw); | ||
353 | } | ||
354 | |||
355 | static 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 | |||
394 | static 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 | |||
411 | void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw) | ||
412 | { | ||
413 | } | ||
414 | |||
415 | static 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 | |||
475 | static 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 | |||
643 | static 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 | |||
682 | static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, | ||
683 | enum radio_path rfpath) | ||
684 | { | ||
685 | return true; | ||
686 | } | ||
687 | |||
688 | bool 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 | |||
779 | void 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 | |||
811 | static 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 | |||
916 | void 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 | |||
945 | static 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 | |||
970 | static 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 | |||
981 | void 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 | |||
997 | bool 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 | |||
1031 | void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) | ||
1032 | { | ||
1033 | } | ||
1034 | |||
1035 | static 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 | |||
1066 | static 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 | |||
1089 | void 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 | |||
1118 | void 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 | |||
1186 | void 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 | |||
1207 | void 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 | |||
1235 | u8 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 | |||
1264 | static 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 | |||
1370 | static 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 | |||
1393 | bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) | ||
1394 | { | ||
1395 | return true; | ||
1396 | } | ||
1397 | |||
1398 | static 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 | |||
1441 | static 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 | |||
1468 | static 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 | |||
1508 | static 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 | |||
1548 | static 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 | |||
1558 | static 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 | |||
1569 | static 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 | |||
1579 | static 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 | |||
1590 | static 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 | |||
1608 | static 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 | |||
1622 | static 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 | |||
1629 | static 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 | |||
1638 | static 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 | |||
1698 | static 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 | |||
1824 | static 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 | |||
1869 | static 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 | |||
2232 | static 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 | |||
2260 | void 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 | |||
2383 | void 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 | |||
2396 | void 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 | |||
2410 | void 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 | |||
2420 | bool 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 | |||
2458 | void 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 | |||
2487 | void 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 | |||
2499 | static 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 | |||
2529 | static 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 | |||
2666 | bool 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 | |||
84 | enum 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 | |||
94 | struct swchnlcmd { | ||
95 | enum swchnlcmd_id cmdid; | ||
96 | u32 para1; | ||
97 | u32 para2; | ||
98 | u32 msdelay; | ||
99 | }; | ||
100 | |||
101 | enum 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 | |||
109 | enum baseband_config_type { | ||
110 | BASEBAND_CONFIG_PHY_REG = 0, | ||
111 | BASEBAND_CONFIG_AGC_TAB = 1, | ||
112 | }; | ||
113 | |||
114 | enum 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 | |||
124 | enum 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 | |||
143 | struct 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 | |||
155 | struct 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 | |||
161 | struct 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 | |||
178 | struct 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 | |||
191 | extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, | ||
192 | u32 regaddr, u32 bitmask); | ||
193 | extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, | ||
194 | u32 regaddr, u32 bitmask, u32 data); | ||
195 | extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, | ||
196 | enum radio_path rfpath, u32 regaddr, | ||
197 | u32 bitmask); | ||
198 | extern void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, | ||
199 | enum radio_path rfpath, u32 regaddr, | ||
200 | u32 bitmask, u32 data); | ||
201 | extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); | ||
202 | extern bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); | ||
203 | extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); | ||
204 | extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, | ||
205 | enum radio_path rfpath); | ||
206 | extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); | ||
207 | extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, | ||
208 | long *powerlevel); | ||
209 | extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); | ||
210 | extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, | ||
211 | long power_indbm); | ||
212 | extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, | ||
213 | u8 operation); | ||
214 | extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw); | ||
215 | extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, | ||
216 | enum nl80211_channel_type ch_type); | ||
217 | extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); | ||
218 | extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); | ||
219 | extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); | ||
220 | extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, | ||
221 | u16 beaconinterval); | ||
222 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); | ||
223 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); | ||
224 | void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); | ||
225 | bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | ||
226 | enum radio_path rfpath); | ||
227 | extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, | ||
228 | u32 rfpath); | ||
229 | bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); | ||
230 | extern bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, | ||
231 | enum rf_pwrstate rfpwr_state); | ||
232 | void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw); | ||
233 | void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); | ||
234 | bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); | ||
235 | void 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 | |||
37 | static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw); | ||
38 | |||
39 | void 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 | |||
64 | void 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 | |||
155 | static 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 | |||
196 | static 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 | |||
348 | static 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 | |||
413 | void 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 | |||
433 | bool 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 | |||
446 | static 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 | |||
37 | extern void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, | ||
38 | u8 bandwidth); | ||
39 | extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | ||
40 | u8 *ppowerlevel); | ||
41 | extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, | ||
42 | u8 *ppowerlevel, u8 channel); | ||
43 | extern 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 | |||
44 | int 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 | |||
88 | void 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 | |||
98 | static 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 | |||
140 | static struct rtl_mod_params rtl92ce_mod_params = { | ||
141 | .sw_crypto = 0, | ||
142 | }; | ||
143 | |||
144 | static 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 | |||
232 | static 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 | |||
240 | MODULE_DEVICE_TABLE(pci, rtl92ce_pci_ids); | ||
241 | |||
242 | MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>"); | ||
243 | MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>"); | ||
244 | MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>"); | ||
245 | MODULE_LICENSE("GPL"); | ||
246 | MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless"); | ||
247 | MODULE_FIRMWARE("rtlwifi/rtl8192cfw.bin"); | ||
248 | |||
249 | module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444); | ||
250 | MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); | ||
251 | |||
252 | static 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 | |||
265 | static 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 | |||
276 | static void __exit rtl92ce_module_exit(void) | ||
277 | { | ||
278 | pci_unregister_driver(&rtl92ce_driver); | ||
279 | } | ||
280 | |||
281 | module_init(rtl92ce_module_init); | ||
282 | module_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 | |||
33 | int rtl92c_init_sw_vars(struct ieee80211_hw *hw); | ||
34 | void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw); | ||
35 | void 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 | |||
35 | u32 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 | |||
225 | u32 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 | |||
415 | u32 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 | |||
482 | u32 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 | |||
626 | u32 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 | |||
668 | u32 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 | |||
812 | u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH] = { | ||
813 | 0x0, | ||
814 | }; | ||
815 | |||
816 | u32 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 | |||
900 | u32 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 | |||
1063 | u32 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 | ||
38 | extern u32 RTL8192CEPHY_REG_2TARRAY[PHY_REG_2TARRAY_LENGTH]; | ||
39 | #define PHY_REG_1TARRAY_LENGTH 374 | ||
40 | extern u32 RTL8192CEPHY_REG_1TARRAY[PHY_REG_1TARRAY_LENGTH]; | ||
41 | #define PHY_REG_ARRAY_PGLENGTH 192 | ||
42 | extern u32 RTL8192CEPHY_REG_ARRAY_PG[PHY_REG_ARRAY_PGLENGTH]; | ||
43 | #define RADIOA_2TARRAYLENGTH 282 | ||
44 | extern u32 RTL8192CERADIOA_2TARRAY[RADIOA_2TARRAYLENGTH]; | ||
45 | #define RADIOB_2TARRAYLENGTH 78 | ||
46 | extern u32 RTL8192CE_RADIOB_2TARRAY[RADIOB_2TARRAYLENGTH]; | ||
47 | #define RADIOA_1TARRAYLENGTH 282 | ||
48 | extern u32 RTL8192CE_RADIOA_1TARRAY[RADIOA_1TARRAYLENGTH]; | ||
49 | #define RADIOB_1TARRAYLENGTH 1 | ||
50 | extern u32 RTL8192CE_RADIOB_1TARRAY[RADIOB_1TARRAYLENGTH]; | ||
51 | #define MAC_2T_ARRAYLENGTH 162 | ||
52 | extern u32 RTL8192CEMAC_2T_ARRAY[MAC_2T_ARRAYLENGTH]; | ||
53 | #define AGCTAB_2TARRAYLENGTH 320 | ||
54 | extern u32 RTL8192CEAGCTAB_2TARRAY[AGCTAB_2TARRAYLENGTH]; | ||
55 | #define AGCTAB_1TARRAYLENGTH 320 | ||
56 | extern 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 | |||
39 | static 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 | |||
77 | static 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 | |||
175 | static 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 | |||
185 | static 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 | |||
205 | static 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 | |||
215 | static 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 | |||
244 | static 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 | |||
388 | static 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 | |||
462 | static 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 | |||
482 | static 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 | |||
521 | static 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 | |||
593 | static 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 | |||
607 | static 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 | |||
652 | bool 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 | |||
721 | void 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 | |||
891 | void 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 | |||
950 | void 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 | |||
987 | u32 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 | |||
1022 | void 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) \ | ||
509 | do { \ | ||
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 | |||
522 | struct 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 | |||
540 | struct 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 | |||
642 | struct 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 | |||
700 | void 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); | ||
704 | bool 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); | ||
708 | void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); | ||
709 | u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name); | ||
710 | void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue); | ||
711 | void 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 | |||
85 | enum intf_type { | ||
86 | INTF_PCI = 0, | ||
87 | INTF_USB = 1, | ||
88 | }; | ||
89 | |||
90 | enum radio_path { | ||
91 | RF90_PATH_A = 0, | ||
92 | RF90_PATH_B = 1, | ||
93 | RF90_PATH_C = 2, | ||
94 | RF90_PATH_D = 3, | ||
95 | }; | ||
96 | |||
97 | enum rt_eeprom_type { | ||
98 | EEPROM_93C46, | ||
99 | EEPROM_93C56, | ||
100 | EEPROM_BOOT_EFUSE, | ||
101 | }; | ||
102 | |||
103 | enum rtl_status { | ||
104 | RTL_STATUS_INTERFACE_START = 0, | ||
105 | }; | ||
106 | |||
107 | enum 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 | |||
121 | enum scan_operation_backup_opt { | ||
122 | SCAN_OPT_BACKUP = 0, | ||
123 | SCAN_OPT_RESTORE, | ||
124 | SCAN_OPT_MAX | ||
125 | }; | ||
126 | |||
127 | /*RF state.*/ | ||
128 | enum rf_pwrstate { | ||
129 | ERFON, | ||
130 | ERFSLEEP, | ||
131 | ERFOFF | ||
132 | }; | ||
133 | |||
134 | struct 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 | |||
155 | enum io_type { | ||
156 | IO_CMD_PAUSE_DM_BY_SCAN = 0, | ||
157 | IO_CMD_RESUME_DM_BY_SCAN = 1, | ||
158 | }; | ||
159 | |||
160 | enum 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 | |||
258 | enum _RT_MEDIA_STATUS { | ||
259 | RT_MEDIA_DISCONNECT = 0, | ||
260 | RT_MEDIA_CONNECT = 1 | ||
261 | }; | ||
262 | |||
263 | enum 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 | |||
298 | enum 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 | |||
308 | enum prime_sc { | ||
309 | PRIME_CHNL_OFFSET_DONT_CARE = 0, | ||
310 | PRIME_CHNL_OFFSET_LOWER = 1, | ||
311 | PRIME_CHNL_OFFSET_UPPER = 2, | ||
312 | }; | ||
313 | |||
314 | enum rf_type { | ||
315 | RF_1T1R = 0, | ||
316 | RF_1T2R = 1, | ||
317 | RF_2T2R = 2, | ||
318 | }; | ||
319 | |||
320 | enum 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 | ||
326 | Cipher Suites Encryption Algorithms */ | ||
327 | enum 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 | |||
336 | enum rtl_hal_state { | ||
337 | _HAL_STATE_STOP = 0, | ||
338 | _HAL_STATE_START = 1, | ||
339 | }; | ||
340 | |||
341 | enum 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.*/ | ||
434 | enum _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 | |||
448 | enum 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.*/ | ||
456 | enum 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 | |||
469 | enum 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.*/ | ||
478 | enum acm_method { | ||
479 | eAcmWay0_SwAndHw = 0, | ||
480 | eAcmWay1_HW = 1, | ||
481 | eAcmWay2_SW = 2, | ||
482 | }; | ||
483 | |||
484 | /*aci/aifsn Field. | ||
485 | Ref: WMM spec 2.2.2: WME Parameter Element, p.12.*/ | ||
486 | union 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.*/ | ||
498 | enum 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 | |||
508 | enum 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 | |||
520 | enum rtl_link_state { | ||
521 | MAC80211_NOLINK = 0, | ||
522 | MAC80211_LINKING = 1, | ||
523 | MAC80211_LINKED = 2, | ||
524 | MAC80211_LINKED_SCANNING = 3, | ||
525 | }; | ||
526 | |||
527 | enum 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 | |||
535 | enum ba_action { | ||
536 | ACT_ADDBAREQ = 0, | ||
537 | ACT_ADDBARSP = 1, | ||
538 | ACT_DELBA = 2, | ||
539 | }; | ||
540 | |||
541 | struct octet_string { | ||
542 | u8 *octet; | ||
543 | u16 length; | ||
544 | }; | ||
545 | |||
546 | struct 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 | |||
556 | struct rtl_info_element { | ||
557 | u8 id; | ||
558 | u8 len; | ||
559 | u8 data[0]; | ||
560 | } __packed; | ||
561 | |||
562 | struct 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.*/ | ||
574 | struct rtl_led { | ||
575 | void *hw; | ||
576 | enum rtl_led_pin ledpin; | ||
577 | bool b_ledon; | ||
578 | }; | ||
579 | |||
580 | struct rtl_led_ctl { | ||
581 | bool bled_opendrain; | ||
582 | struct rtl_led sw_led0; | ||
583 | struct rtl_led sw_led1; | ||
584 | }; | ||
585 | |||
586 | struct rtl_qos_parameters { | ||
587 | __le16 cw_min; | ||
588 | __le16 cw_max; | ||
589 | u8 aifs; | ||
590 | u8 flag; | ||
591 | __le16 tx_op; | ||
592 | } __packed; | ||
593 | |||
594 | struct 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 | |||
601 | struct 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 | |||
611 | struct init_gain { | ||
612 | u8 xaagccore1; | ||
613 | u8 xbagccore1; | ||
614 | u8 xcagccore1; | ||
615 | u8 xdagccore1; | ||
616 | u8 cca; | ||
617 | |||
618 | }; | ||
619 | |||
620 | struct 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 | |||
646 | struct 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 | |||
672 | struct regd_pair_mapping { | ||
673 | u16 reg_dmnenum; | ||
674 | u16 reg_5ghz_ctl; | ||
675 | u16 reg_2ghz_ctl; | ||
676 | }; | ||
677 | |||
678 | struct 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 | |||
689 | struct rtl_rfkill { | ||
690 | bool rfkill_state; /*0 is off, 1 is on */ | ||
691 | }; | ||
692 | |||
693 | struct 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 | |||
754 | struct 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 | |||
763 | struct rtl_tid_data { | ||
764 | u16 seq_number; | ||
765 | struct rtl_ht_agg agg; | ||
766 | }; | ||
767 | |||
768 | struct rtl_priv; | ||
769 | struct 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 | |||
789 | struct 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 | |||
850 | struct 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 | |||
868 | struct 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 | |||
889 | struct 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 | |||
921 | struct 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 | |||
971 | struct 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 | |||
1018 | struct 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 | |||
1065 | struct 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 | |||
1077 | struct 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 | |||
1101 | struct 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 | |||
1162 | struct 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 | |||
1177 | struct rtl_mod_params { | ||
1178 | /* default: 0 = using hardware encryption */ | ||
1179 | int sw_crypto; | ||
1180 | }; | ||
1181 | |||
1182 | struct 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 | |||
1194 | struct 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 | |||
1207 | struct 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 | |||
1223 | struct rtl_debug { | ||
1224 | u32 dbgp_type[DBGP_TYPE_MAX]; | ||
1225 | u32 global_debuglevel; | ||
1226 | u64 global_debugcomponents; | ||
1227 | }; | ||
1228 | |||
1229 | struct 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: | ||
1309 | BIT_LEN_MASK_32(0) => 0x00000000 | ||
1310 | BIT_LEN_MASK_32(1) => 0x00000001 | ||
1311 | BIT_LEN_MASK_32(2) => 0x00000003 | ||
1312 | BIT_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: | ||
1321 | BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 | ||
1322 | BIT_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: | ||
1331 | Return 4-byte value in host byte ordering from | ||
1332 | 4-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: | ||
1341 | Translate subfield (continuous bits in little-endian) of 4-byte | ||
1342 | value 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: | ||
1360 | Mask subfield (continuous bits in little-endian) of 4-byte value | ||
1361 | and 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: | ||
1379 | Set 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 | |||
1445 | static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr) | ||
1446 | { | ||
1447 | return rtlpriv->io.read8_sync(rtlpriv, addr); | ||
1448 | } | ||
1449 | |||
1450 | static inline u16 rtl_read_word(struct rtl_priv *rtlpriv, u32 addr) | ||
1451 | { | ||
1452 | return rtlpriv->io.read16_sync(rtlpriv, addr); | ||
1453 | } | ||
1454 | |||
1455 | static inline u32 rtl_read_dword(struct rtl_priv *rtlpriv, u32 addr) | ||
1456 | { | ||
1457 | return rtlpriv->io.read32_sync(rtlpriv, addr); | ||
1458 | } | ||
1459 | |||
1460 | static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8) | ||
1461 | { | ||
1462 | rtlpriv->io.write8_async(rtlpriv, addr, val8); | ||
1463 | } | ||
1464 | |||
1465 | static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16) | ||
1466 | { | ||
1467 | rtlpriv->io.write16_async(rtlpriv, addr, val16); | ||
1468 | } | ||
1469 | |||
1470 | static 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 | |||
1476 | static 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 | |||
1484 | static 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 | |||
1493 | static 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 | |||
1503 | static 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 | |||
1512 | static inline bool is_hal_stop(struct rtl_hal *rtlhal) | ||
1513 | { | ||
1514 | return (_HAL_STATE_STOP == rtlhal->state); | ||
1515 | } | ||
1516 | |||
1517 | static inline void set_hal_start(struct rtl_hal *rtlhal) | ||
1518 | { | ||
1519 | rtlhal->state = _HAL_STATE_START; | ||
1520 | } | ||
1521 | |||
1522 | static inline void set_hal_stop(struct rtl_hal *rtlhal) | ||
1523 | { | ||
1524 | rtlhal->state = _HAL_STATE_STOP; | ||
1525 | } | ||
1526 | |||
1527 | static 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 | ||
55 | config 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 | |||
55 | config WL12XX_PLATFORM_DATA | 65 | config 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 | ||
4 | wl12xx_spi-objs = spi.o | 4 | wl12xx_spi-objs = spi.o |
5 | wl12xx_sdio-objs = sdio.o | 5 | wl12xx_sdio-objs = sdio.o |
6 | wl12xx_sdio_test-objs = sdio_test.o | ||
6 | 7 | ||
7 | wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o | 8 | wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o |
8 | obj-$(CONFIG_WL12XX) += wl12xx.o | 9 | obj-$(CONFIG_WL12XX) += wl12xx.o |
9 | obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o | 10 | obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o |
10 | obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o | 11 | obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o |
11 | 12 | ||
13 | obj-$(CONFIG_WL12XX_SDIO_TEST) += wl12xx_sdio_test.o | ||
14 | |||
12 | # small builtin driver bit | 15 | # small builtin driver bit |
13 | obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o | 16 | obj-$(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 | ||
1044 | int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address) | 1044 | int 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 | |||
871 | struct wl1271_acx_arp_filter { | 876 | struct 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); | |||
1168 | int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); | 1173 | int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); |
1169 | int wl1271_acx_smart_reflex(struct wl1271 *wl); | 1174 | int wl1271_acx_smart_reflex(struct wl1271 *wl); |
1170 | int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable); | 1175 | int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable); |
1171 | int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address); | 1176 | int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 enable, __be32 address); |
1172 | int wl1271_acx_pm_config(struct wl1271 *wl); | 1177 | int wl1271_acx_pm_config(struct wl1271 *wl); |
1173 | int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable); | 1178 | int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable); |
1174 | int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid); | 1179 | int 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 | ||
470 | int wl1271_boot(struct wl1271 *wl) | 470 | /* uploads NVS and firmware */ |
471 | int 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 | ||
576 | out: | ||
577 | return ret; | ||
578 | } | ||
579 | EXPORT_SYMBOL_GPL(wl1271_load_firmware); | ||
580 | |||
581 | int 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 | ||
29 | int wl1271_boot(struct wl1271 *wl); | 29 | int wl1271_boot(struct wl1271 *wl); |
30 | int 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 | ||
614 | struct 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 | |||
638 | out: | ||
639 | return skb; | ||
640 | } | ||
641 | |||
642 | int 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 | |||
614 | int wl1271_build_qos_null_data(struct wl1271 *wl) | 683 | int 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); | |||
49 | int wl1271_cmd_build_probe_req(struct wl1271 *wl, | 49 | int 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); |
52 | struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, | ||
53 | struct sk_buff *skb); | ||
54 | int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, __be32 ip_addr); | ||
52 | int wl1271_build_qos_null_data(struct wl1271 *wl); | 55 | int wl1271_build_qos_null_data(struct wl1271 *wl); |
53 | int wl1271_cmd_build_klv_null_data(struct wl1271 *wl); | 56 | int wl1271_cmd_build_klv_null_data(struct wl1271 *wl); |
54 | int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); | 57 | int 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) \ |
84 | static ssize_t sub## _ ##name## _read(struct file *file, \ | 75 | static 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 | ||
108 | static void wl1271_debugfs_update_stats(struct wl1271 *wl) | 96 | static 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 | ||
308 | static 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 | |||
408 | static int wl1271_debugfs_add_files(struct wl1271 *wl) | 296 | static 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 | ||
509 | out: | 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 | |||
411 | err: | ||
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 | ||
516 | void wl1271_debugfs_reset(struct wl1271 *wl) | 420 | void 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 | ||
565 | err_fw: | 464 | err_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 | |||
569 | err_root: | ||
570 | debugfs_remove(wl->debugfs.rootdir); | ||
571 | wl->debugfs.rootdir = NULL; | ||
572 | 467 | ||
573 | err: | 468 | err: |
574 | return ret; | 469 | return ret; |
@@ -576,15 +471,10 @@ err: | |||
576 | 471 | ||
577 | void wl1271_debugfs_exit(struct wl1271 *wl) | 472 | void 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) | |||
53 | int wl1271_init_templates_config(struct wl1271 *wl) | 53 | int 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 | } |
116 | EXPORT_SYMBOL_GPL(wl1271_set_partition); | ||
116 | 117 | ||
117 | void wl1271_io_reset(struct wl1271 *wl) | 118 | void 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 | ||
338 | static int wl1271_reg_notify(struct wiphy *wiphy, | 338 | static 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 | |||
1067 | out: | 1081 | out: |
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 | ||
1804 | static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *beacon) | 1824 | static 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 | ||
1821 | static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | 1841 | static 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 */ |
2355 | static struct ieee80211_channel wl1271_channels_5ghz[] = { | 2399 | static 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 | } |
2794 | EXPORT_SYMBOL_GPL(wl1271_free_hw); | 2838 | EXPORT_SYMBOL_GPL(wl1271_free_hw); |
2795 | 2839 | ||
2840 | u32 wl12xx_debug_level; | ||
2841 | EXPORT_SYMBOL_GPL(wl12xx_debug_level); | ||
2842 | module_param_named(debug_level, wl12xx_debug_level, uint, DEBUG_NONE); | ||
2843 | MODULE_PARM_DESC(debug_level, "wl12xx debugging level"); | ||
2844 | |||
2796 | MODULE_LICENSE("GPL"); | 2845 | MODULE_LICENSE("GPL"); |
2797 | MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); | 2846 | MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); |
2798 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | 2847 | MODULE_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 | |||
51 | static bool rx, tx; | ||
52 | |||
53 | module_param(rx, bool, S_IRUGO | S_IWUSR); | ||
54 | MODULE_PARM_DESC(rx, "Perform rx test. Default (0). " | ||
55 | "This test continuously reads data from the SDIO device.\n"); | ||
56 | |||
57 | module_param(tx, bool, S_IRUGO | S_IWUSR); | ||
58 | MODULE_PARM_DESC(tx, "Perform tx test. Default (0). " | ||
59 | "This test continuously writes data to the SDIO device.\n"); | ||
60 | |||
61 | struct wl1271_test { | ||
62 | struct wl1271 wl; | ||
63 | struct task_struct *test_task; | ||
64 | }; | ||
65 | |||
66 | static const struct sdio_device_id wl1271_devices[] = { | ||
67 | { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, | ||
68 | {} | ||
69 | }; | ||
70 | |||
71 | static inline struct sdio_func *wl_to_func(struct wl1271 *wl) | ||
72 | { | ||
73 | return wl->if_priv; | ||
74 | } | ||
75 | |||
76 | static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl) | ||
77 | { | ||
78 | return &(wl_to_func(wl)->dev); | ||
79 | } | ||
80 | |||
81 | static 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 | |||
106 | static 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 | |||
131 | static 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 | |||
157 | out: | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) | ||
162 | { | ||
163 | } | ||
164 | |||
165 | static void wl1271_sdio_enable_interrupts(struct wl1271 *wl) | ||
166 | { | ||
167 | } | ||
168 | |||
169 | |||
170 | static 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 | |||
179 | static 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 | |||
187 | static 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 | |||
219 | out: | ||
220 | release_firmware(fw); | ||
221 | |||
222 | return ret; | ||
223 | } | ||
224 | |||
225 | static 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 | |||
247 | out: | ||
248 | release_firmware(fw); | ||
249 | |||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | static 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 | |||
299 | static 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 | |||
318 | static 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 | |||
378 | free: | ||
379 | kfree(tx_buf); | ||
380 | kfree(rx_buf); | ||
381 | return ret; | ||
382 | } | ||
383 | |||
384 | static 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 | |||
466 | out_off: | ||
467 | /* power off the chip */ | ||
468 | wl1271_power_off(wl); | ||
469 | |||
470 | out_free: | ||
471 | kfree(wl_test); | ||
472 | return ret; | ||
473 | } | ||
474 | |||
475 | static 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 | |||
493 | static 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 | |||
500 | static 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 | } | ||
510 | module_init(wl1271_init); | ||
511 | |||
512 | static void __exit wl1271_exit(void) | ||
513 | { | ||
514 | sdio_unregister_driver(&wl1271_sdio_driver); | ||
515 | } | ||
516 | module_exit(wl1271_exit); | ||
517 | |||
518 | MODULE_LICENSE("GPL"); | ||
519 | MODULE_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 | ||
239 | static 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 | |||
255 | out: | ||
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 | |||
265 | static 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 | |||
240 | void wl1271_tx_work_locked(struct wl1271 *wl) | 276 | void 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) | 63 | extern 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 | ||
177 | struct 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 | ||
136 | struct wl12xx_probe_req_template { | 137 | struct 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 | */ | ||
1300 | enum { | ||
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 | */ | ||
1312 | enum { | ||
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 | */ | ||
1683 | enum 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 | */ | ||
1860 | enum 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 | */ |
655 | struct mesh_setup { | 659 | struct 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 | */ |
1397 | enum wiphy_flags { | 1407 | enum 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 | ||
1409 | struct mac_address { | 1420 | struct 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 | */ |
1472 | struct wiphy { | 1496 | struct 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 | */ | ||
2388 | void 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 | */ | ||
2401 | void 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 | */ |
2445 | int ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, u16 tid); | 2446 | int 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 | ||
348 | int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) | 348 | int 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 | ||
296 | static int ieee80211_config_default_key(struct wiphy *wiphy, | 296 | static 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 | ||
986 | static int ieee80211_get_mesh_params(struct wiphy *wiphy, | 987 | static 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 | ||
1002 | static int ieee80211_update_mesh_params(struct wiphy *wiphy, | 1003 | static 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 | |||
1033 | static 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 | } |
277 | void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata) | 277 | |
278 | void 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 | } | |
297 | void 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 | ||
306 | void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata) | 311 | void 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 |
5 | void ieee80211_debugfs_key_add(struct ieee80211_key *key); | 5 | void ieee80211_debugfs_key_add(struct ieee80211_key *key); |
6 | void ieee80211_debugfs_key_remove(struct ieee80211_key *key); | 6 | void ieee80211_debugfs_key_remove(struct ieee80211_key *key); |
7 | void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata); | 7 | void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata); |
8 | void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata); | ||
9 | void ieee80211_debugfs_key_add_mgmt_default( | 8 | void ieee80211_debugfs_key_add_mgmt_default( |
10 | struct ieee80211_sub_if_data *sdata); | 9 | struct ieee80211_sub_if_data *sdata); |
11 | void ieee80211_debugfs_key_remove_mgmt_default( | 10 | void ieee80211_debugfs_key_remove_mgmt_default( |
@@ -17,10 +16,7 @@ static inline void ieee80211_debugfs_key_add(struct ieee80211_key *key) | |||
17 | {} | 16 | {} |
18 | static inline void ieee80211_debugfs_key_remove(struct ieee80211_key *key) | 17 | static inline void ieee80211_debugfs_key_remove(struct ieee80211_key *key) |
19 | {} | 18 | {} |
20 | static inline void ieee80211_debugfs_key_add_default( | 19 | static inline void ieee80211_debugfs_key_update_default( |
21 | struct ieee80211_sub_if_data *sdata) | ||
22 | {} | ||
23 | static inline void ieee80211_debugfs_key_remove_default( | ||
24 | struct ieee80211_sub_if_data *sdata) | 20 | struct ieee80211_sub_if_data *sdata) |
25 | {} | 21 | {} |
26 | static inline void ieee80211_debugfs_key_add_mgmt_default( | 22 | static 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 | ||
368 | static inline int drv_tx_last_beacon(struct ieee80211_local *local) | 368 | static 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) | |||
178 | EXPORT_SYMBOL_GPL(ieee80211_key_removed); | 178 | EXPORT_SYMBOL_GPL(ieee80211_key_removed); |
179 | 179 | ||
180 | static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, | 180 | static 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 | ||
198 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx) | 198 | void 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 | ||
224 | void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, | 222 | void 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); |
139 | void ieee80211_key_free(struct ieee80211_local *local, | 139 | void ieee80211_key_free(struct ieee80211_local *local, |
140 | struct ieee80211_key *key); | 140 | struct ieee80211_key *key); |
141 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); | 141 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx, |
142 | bool uni, bool multi); | ||
142 | void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, | 143 | void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, |
143 | int idx); | 144 | int idx); |
144 | void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata); | 145 | void 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 | ||
489 | struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | 493 | struct 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 | ||
127 | void 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 | |||
136 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) | 127 | int 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 | ||
292 | u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl) | 290 | u32 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 | */ |
424 | int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, | 421 | int 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 { | |||
198 | int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, | 187 | int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, |
199 | const u8 *da, const u8 *sa); | 188 | const u8 *da, const u8 *sa); |
200 | int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, | 189 | int 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); |
203 | int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr, | 192 | int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr, |
204 | struct ieee80211_sub_if_data *sdata); | 193 | struct ieee80211_sub_if_data *sdata); |
205 | bool mesh_matches_local(struct ieee802_11_elems *ie, | 194 | bool 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 | ||
287 | static 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 | {} |
316 | static inline void mesh_plink_quiesce(struct sta_info *sta) {} | 310 | static inline void mesh_plink_quiesce(struct sta_info *sta) {} |
317 | static inline void mesh_plink_restart(struct sta_info *sta) {} | 311 | static inline void mesh_plink_restart(struct sta_info *sta) {} |
312 | static 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 | ||
380 | static void | 380 | static 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 */ |
289 | extern const struct mesh_config default_mesh_config; | 289 | extern const struct mesh_config default_mesh_config; |
290 | extern const struct mesh_setup default_mesh_setup; | ||
290 | int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | 291 | int __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); |
294 | int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | 295 | int 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); |
298 | int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | 299 | int 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 | ||
53 | const 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 | ||
54 | int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | 60 | int __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 | ||
91 | int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | 93 | int 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 | } |
264 | EXPORT_SYMBOL(cfg80211_send_disassoc); | 264 | EXPORT_SYMBOL(cfg80211_send_disassoc); |
265 | 265 | ||
266 | void 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 | } | ||
275 | EXPORT_SYMBOL(cfg80211_send_unprot_deauth); | ||
276 | |||
277 | void 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 | } | ||
286 | EXPORT_SYMBOL(cfg80211_send_unprot_disassoc); | ||
287 | |||
266 | static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr) | 288 | static 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 */ | ||
190 | static const struct nla_policy | ||
191 | nl80211_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 | ||
319 | static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k) | 329 | static 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 | ||
2572 | static int nl80211_get_mesh_params(struct sk_buff *skb, | 2684 | static 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 | ||
2672 | static int nl80211_parse_mesh_params(struct genl_info *info, | 2784 | static 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 | |||
2792 | static 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 | ||
2746 | static int nl80211_update_mesh_params(struct sk_buff *skb, | 2866 | static 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 | |||
2902 | static 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 | ||
4587 | static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) | 4755 | static 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 | ||
5539 | void 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 | |||
5547 | void 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 | |||
5371 | static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, | 5555 | static 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, | |||
25 | void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, | 25 | void 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); |
28 | void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev, | ||
29 | struct net_device *netdev, | ||
30 | const u8 *buf, size_t len, gfp_t gfp); | ||
31 | void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev, | ||
32 | struct net_device *netdev, | ||
33 | const u8 *buf, size_t len, gfp_t gfp); | ||
28 | void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev, | 34 | void 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); |