diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-05-05 16:14:16 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-05-05 16:14:16 -0400 |
commit | 83163244f845c296a118ce85c653872dbff6abfe (patch) | |
tree | ce2eac695a1c198f23d537e20ed86c16ece21f7e /drivers | |
parent | 0a12761bcd5646691c5d16dd93df84d1b8849285 (diff) | |
parent | adfba3c7c026a6a5560d2a43fefc9b198cb74462 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts:
drivers/net/wireless/libertas_tf/cmd.c
drivers/net/wireless/libertas_tf/main.c
Diffstat (limited to 'drivers')
117 files changed, 4369 insertions, 1175 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 77500cb7fd26..2fbe9b4506c0 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -38,6 +38,12 @@ config LIBERTAS_THINFIRM | |||
38 | ---help--- | 38 | ---help--- |
39 | A library for Marvell Libertas 8xxx devices using thinfirm. | 39 | A library for Marvell Libertas 8xxx devices using thinfirm. |
40 | 40 | ||
41 | config LIBERTAS_THINFIRM_DEBUG | ||
42 | bool "Enable full debugging output in the Libertas thin firmware module." | ||
43 | depends on LIBERTAS_THINFIRM | ||
44 | ---help--- | ||
45 | Debugging support. | ||
46 | |||
41 | config LIBERTAS_THINFIRM_USB | 47 | config LIBERTAS_THINFIRM_USB |
42 | tristate "Marvell Libertas 8388 USB 802.11b/g cards with thin firmware" | 48 | tristate "Marvell Libertas 8388 USB 802.11b/g cards with thin firmware" |
43 | depends on LIBERTAS_THINFIRM && USB | 49 | depends on LIBERTAS_THINFIRM && USB |
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 0fb419936dff..7a626d4e100f 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
@@ -1889,6 +1889,7 @@ static void at76_dwork_hw_scan(struct work_struct *work) | |||
1889 | } | 1889 | } |
1890 | 1890 | ||
1891 | static int at76_hw_scan(struct ieee80211_hw *hw, | 1891 | static int at76_hw_scan(struct ieee80211_hw *hw, |
1892 | struct ieee80211_vif *vif, | ||
1892 | struct cfg80211_scan_request *req) | 1893 | struct cfg80211_scan_request *req) |
1893 | { | 1894 | { |
1894 | struct at76_priv *priv = hw->priv; | 1895 | struct at76_priv *priv = hw->priv; |
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 0312cee39570..2e9b330f6413 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -927,7 +927,6 @@ static void ar9170_rx_phy_status(struct ar9170 *ar, | |||
927 | 927 | ||
928 | /* TODO: we could do something with phy_errors */ | 928 | /* TODO: we could do something with phy_errors */ |
929 | status->signal = ar->noise[0] + phy->rssi_combined; | 929 | status->signal = ar->noise[0] + phy->rssi_combined; |
930 | status->noise = ar->noise[0]; | ||
931 | } | 930 | } |
932 | 931 | ||
933 | static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len) | 932 | static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len) |
@@ -2548,8 +2547,7 @@ void *ar9170_alloc(size_t priv_size) | |||
2548 | BIT(NL80211_IFTYPE_ADHOC); | 2547 | BIT(NL80211_IFTYPE_ADHOC); |
2549 | ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | | 2548 | ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | |
2550 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 2549 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
2551 | IEEE80211_HW_SIGNAL_DBM | | 2550 | IEEE80211_HW_SIGNAL_DBM; |
2552 | IEEE80211_HW_NOISE_DBM; | ||
2553 | 2551 | ||
2554 | if (modparam_ht) { | 2552 | if (modparam_ht) { |
2555 | ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; | 2553 | ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index c274979ada3a..7f5953fac434 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -548,8 +548,7 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
548 | SET_IEEE80211_DEV(hw, &pdev->dev); | 548 | SET_IEEE80211_DEV(hw, &pdev->dev); |
549 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 549 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
550 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 550 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
551 | IEEE80211_HW_SIGNAL_DBM | | 551 | IEEE80211_HW_SIGNAL_DBM; |
552 | IEEE80211_HW_NOISE_DBM; | ||
553 | 552 | ||
554 | hw->wiphy->interface_modes = | 553 | hw->wiphy->interface_modes = |
555 | BIT(NL80211_IFTYPE_AP) | | 554 | BIT(NL80211_IFTYPE_AP) | |
@@ -2030,8 +2029,7 @@ accept: | |||
2030 | rxs->freq = sc->curchan->center_freq; | 2029 | rxs->freq = sc->curchan->center_freq; |
2031 | rxs->band = sc->curband->band; | 2030 | rxs->band = sc->curband->band; |
2032 | 2031 | ||
2033 | rxs->noise = sc->ah->ah_noise_floor; | 2032 | rxs->signal = sc->ah->ah_noise_floor + rs.rs_rssi; |
2034 | rxs->signal = rxs->noise + rs.rs_rssi; | ||
2035 | 2033 | ||
2036 | rxs->antenna = rs.rs_antenna; | 2034 | rxs->antenna = rs.rs_antenna; |
2037 | 2035 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index cec62d311c78..ba8b20f01594 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c | |||
@@ -657,12 +657,3 @@ void ath9k_hw_ani_init(struct ath_hw *ah) | |||
657 | if (ah->config.enable_ani) | 657 | if (ah->config.enable_ani) |
658 | ah->proc_phyerr |= HAL_PROCESS_ANI; | 658 | ah->proc_phyerr |= HAL_PROCESS_ANI; |
659 | } | 659 | } |
660 | |||
661 | void ath9k_hw_ani_disable(struct ath_hw *ah) | ||
662 | { | ||
663 | ath_print(ath9k_hw_common(ah), ATH_DBG_ANI, "Disabling ANI\n"); | ||
664 | |||
665 | ath9k_hw_disable_mib_counters(ah); | ||
666 | REG_WRITE(ah, AR_PHY_ERR_1, 0); | ||
667 | REG_WRITE(ah, AR_PHY_ERR_2, 0); | ||
668 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index 4e1ab94a5153..3356762ea384 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h | |||
@@ -118,6 +118,5 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, | |||
118 | void ath9k_hw_procmibevent(struct ath_hw *ah); | 118 | void ath9k_hw_procmibevent(struct ath_hw *ah); |
119 | void ath9k_hw_ani_setup(struct ath_hw *ah); | 119 | void ath9k_hw_ani_setup(struct ath_hw *ah); |
120 | void ath9k_hw_ani_init(struct ath_hw *ah); | 120 | void ath9k_hw_ani_init(struct ath_hw *ah); |
121 | void ath9k_hw_ani_disable(struct ath_hw *ah); | ||
122 | 121 | ||
123 | #endif /* ANI_H */ | 122 | #endif /* ANI_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h index cd953f6c4628..025c31ac6146 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h | |||
@@ -249,7 +249,7 @@ static const u32 ar5416Common[][2] = { | |||
249 | { 0x00008258, 0x00000000 }, | 249 | { 0x00008258, 0x00000000 }, |
250 | { 0x0000825c, 0x400000ff }, | 250 | { 0x0000825c, 0x400000ff }, |
251 | { 0x00008260, 0x00080922 }, | 251 | { 0x00008260, 0x00080922 }, |
252 | { 0x00008264, 0xa8000010 }, | 252 | { 0x00008264, 0x88000010 }, |
253 | { 0x00008270, 0x00000000 }, | 253 | { 0x00008270, 0x00000000 }, |
254 | { 0x00008274, 0x40000000 }, | 254 | { 0x00008274, 0x40000000 }, |
255 | { 0x00008278, 0x003e4180 }, | 255 | { 0x00008278, 0x003e4180 }, |
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index de8ce1291a46..b2c17c98bb38 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
@@ -850,7 +850,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, | |||
850 | 850 | ||
851 | REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); | 851 | REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); |
852 | 852 | ||
853 | if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) { | 853 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) { |
854 | REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, | 854 | REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, |
855 | regWrites); | 855 | regWrites); |
856 | } | 856 | } |
@@ -892,8 +892,7 @@ static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan) | |||
892 | rfMode |= (IS_CHAN_5GHZ(chan)) ? | 892 | rfMode |= (IS_CHAN_5GHZ(chan)) ? |
893 | AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; | 893 | AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; |
894 | 894 | ||
895 | if ((AR_SREV_9280_20(ah) || AR_SREV_9300_20_OR_LATER(ah)) | 895 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) |
896 | && IS_CHAN_A_5MHZ_SPACED(chan)) | ||
897 | rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); | 896 | rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); |
898 | 897 | ||
899 | REG_WRITE(ah, AR_PHY_MODE, rfMode); | 898 | REG_WRITE(ah, AR_PHY_MODE, rfMode); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index adb33b34a56d..a8a8cdc04afa 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |||
@@ -408,6 +408,8 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, | |||
408 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | 408 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); |
409 | 409 | ||
410 | } else { | 410 | } else { |
411 | ENABLE_REGWRITE_BUFFER(ah); | ||
412 | |||
411 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); | 413 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); |
412 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); | 414 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); |
413 | 415 | ||
@@ -428,6 +430,9 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, | |||
428 | 430 | ||
429 | /* Load the new settings */ | 431 | /* Load the new settings */ |
430 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | 432 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); |
433 | |||
434 | REGWRITE_BUFFER_FLUSH(ah); | ||
435 | DISABLE_REGWRITE_BUFFER(ah); | ||
431 | } | 436 | } |
432 | 437 | ||
433 | udelay(1000); | 438 | udelay(1000); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h index f06313d3bad6..dae7f3304eb8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h | |||
@@ -793,7 +793,7 @@ static const u32 ar9280Common_9280_2[][2] = { | |||
793 | { 0x00008258, 0x00000000 }, | 793 | { 0x00008258, 0x00000000 }, |
794 | { 0x0000825c, 0x400000ff }, | 794 | { 0x0000825c, 0x400000ff }, |
795 | { 0x00008260, 0x00080922 }, | 795 | { 0x00008260, 0x00080922 }, |
796 | { 0x00008264, 0xa8a00010 }, | 796 | { 0x00008264, 0x88a00010 }, |
797 | { 0x00008270, 0x00000000 }, | 797 | { 0x00008270, 0x00000000 }, |
798 | { 0x00008274, 0x40000000 }, | 798 | { 0x00008274, 0x40000000 }, |
799 | { 0x00008278, 0x003e4180 }, | 799 | { 0x00008278, 0x003e4180 }, |
@@ -1963,7 +1963,7 @@ static const u32 ar9285Common_9285[][2] = { | |||
1963 | { 0x00008258, 0x00000000 }, | 1963 | { 0x00008258, 0x00000000 }, |
1964 | { 0x0000825c, 0x400000ff }, | 1964 | { 0x0000825c, 0x400000ff }, |
1965 | { 0x00008260, 0x00080922 }, | 1965 | { 0x00008260, 0x00080922 }, |
1966 | { 0x00008264, 0xa8a00010 }, | 1966 | { 0x00008264, 0x88a00010 }, |
1967 | { 0x00008270, 0x00000000 }, | 1967 | { 0x00008270, 0x00000000 }, |
1968 | { 0x00008274, 0x40000000 }, | 1968 | { 0x00008274, 0x40000000 }, |
1969 | { 0x00008278, 0x003e4180 }, | 1969 | { 0x00008278, 0x003e4180 }, |
@@ -3185,7 +3185,7 @@ static const u32 ar9287Common_9287_1_0[][2] = { | |||
3185 | { 0x00008258, 0x00000000 }, | 3185 | { 0x00008258, 0x00000000 }, |
3186 | { 0x0000825c, 0x400000ff }, | 3186 | { 0x0000825c, 0x400000ff }, |
3187 | { 0x00008260, 0x00080922 }, | 3187 | { 0x00008260, 0x00080922 }, |
3188 | { 0x00008264, 0xa8a00010 }, | 3188 | { 0x00008264, 0x88a00010 }, |
3189 | { 0x00008270, 0x00000000 }, | 3189 | { 0x00008270, 0x00000000 }, |
3190 | { 0x00008274, 0x40000000 }, | 3190 | { 0x00008274, 0x40000000 }, |
3191 | { 0x00008278, 0x003e4180 }, | 3191 | { 0x00008278, 0x003e4180 }, |
@@ -4973,7 +4973,7 @@ static const u32 ar9271Common_9271[][2] = { | |||
4973 | { 0x00008258, 0x00000000 }, | 4973 | { 0x00008258, 0x00000000 }, |
4974 | { 0x0000825c, 0x400000ff }, | 4974 | { 0x0000825c, 0x400000ff }, |
4975 | { 0x00008260, 0x00080922 }, | 4975 | { 0x00008260, 0x00080922 }, |
4976 | { 0x00008264, 0xa8a00010 }, | 4976 | { 0x00008264, 0x88a00010 }, |
4977 | { 0x00008270, 0x00000000 }, | 4977 | { 0x00008270, 0x00000000 }, |
4978 | { 0x00008274, 0x40000000 }, | 4978 | { 0x00008274, 0x40000000 }, |
4979 | { 0x00008278, 0x003e4180 }, | 4979 | { 0x00008278, 0x003e4180 }, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index 18cfe1a9781c..ed314e89bfe1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c | |||
@@ -455,16 +455,12 @@ static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah, | |||
455 | pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL); | 455 | pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL); |
456 | 456 | ||
457 | if (chan && IS_CHAN_5GHZ(chan)) { | 457 | if (chan && IS_CHAN_5GHZ(chan)) { |
458 | pll |= SM(0x28, AR_RTC_9160_PLL_DIV); | 458 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) |
459 | 459 | pll = 0x142c; | |
460 | 460 | else if (AR_SREV_9280_20(ah)) | |
461 | if (AR_SREV_9280_20(ah)) { | 461 | pll = 0x2850; |
462 | if (((chan->channel % 20) == 0) | 462 | else |
463 | || ((chan->channel % 10) == 0)) | 463 | pll |= SM(0x28, AR_RTC_9160_PLL_DIV); |
464 | pll = 0x2850; | ||
465 | else | ||
466 | pll = 0x142c; | ||
467 | } | ||
468 | } else { | 464 | } else { |
469 | pll |= SM(0x2c, AR_RTC_9160_PLL_DIV); | 465 | pll |= SM(0x2c, AR_RTC_9160_PLL_DIV); |
470 | } | 466 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 5e20b4860c7f..5fcafb460877 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -755,7 +755,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
755 | } | 755 | } |
756 | 756 | ||
757 | /* Do Tx IQ Calibration */ | 757 | /* Do Tx IQ Calibration */ |
758 | ar9003_hw_tx_iq_cal(ah); | 758 | if (ah->config.tx_iq_calibration) |
759 | ar9003_hw_tx_iq_cal(ah); | ||
759 | 760 | ||
760 | /* Revert chainmasks to their original values before NF cal */ | 761 | /* Revert chainmasks to their original values before NF cal */ |
761 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); | 762 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 5d92be47c5a5..8a79550dff71 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -659,6 +659,9 @@ static void ar9300_swap_eeprom(struct ar9300_eeprom *eep) | |||
659 | word = swab16(eep->baseEepHeader.regDmn[1]); | 659 | word = swab16(eep->baseEepHeader.regDmn[1]); |
660 | eep->baseEepHeader.regDmn[1] = word; | 660 | eep->baseEepHeader.regDmn[1] = word; |
661 | 661 | ||
662 | dword = swab32(eep->baseEepHeader.swreg); | ||
663 | eep->baseEepHeader.swreg = dword; | ||
664 | |||
662 | dword = swab32(eep->modalHeader2G.antCtrlCommon); | 665 | dword = swab32(eep->modalHeader2G.antCtrlCommon); |
663 | eep->modalHeader2G.antCtrlCommon = dword; | 666 | eep->modalHeader2G.antCtrlCommon = dword; |
664 | 667 | ||
@@ -1200,7 +1203,7 @@ static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah, | |||
1200 | u8 *pFreqBin; | 1203 | u8 *pFreqBin; |
1201 | 1204 | ||
1202 | if (is2GHz) { | 1205 | if (is2GHz) { |
1203 | numPiers = AR9300_NUM_5G_20_TARGET_POWERS; | 1206 | numPiers = AR9300_NUM_2G_20_TARGET_POWERS; |
1204 | pEepromTargetPwr = eep->calTargetPower2G; | 1207 | pEepromTargetPwr = eep->calTargetPower2G; |
1205 | pFreqBin = eep->calTarget_freqbin_2G; | 1208 | pFreqBin = eep->calTarget_freqbin_2G; |
1206 | } else { | 1209 | } else { |
@@ -1236,7 +1239,7 @@ static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah, | |||
1236 | u8 *pFreqBin; | 1239 | u8 *pFreqBin; |
1237 | 1240 | ||
1238 | if (is2GHz) { | 1241 | if (is2GHz) { |
1239 | numPiers = AR9300_NUM_5G_20_TARGET_POWERS; | 1242 | numPiers = AR9300_NUM_2G_20_TARGET_POWERS; |
1240 | pEepromTargetPwr = eep->calTargetPower2GHT20; | 1243 | pEepromTargetPwr = eep->calTargetPower2GHT20; |
1241 | pFreqBin = eep->calTarget_freqbin_2GHT20; | 1244 | pFreqBin = eep->calTarget_freqbin_2GHT20; |
1242 | } else { | 1245 | } else { |
@@ -1817,6 +1820,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, | |||
1817 | u8 twiceMaxRegulatoryPower, | 1820 | u8 twiceMaxRegulatoryPower, |
1818 | u8 powerLimit) | 1821 | u8 powerLimit) |
1819 | { | 1822 | { |
1823 | ah->txpower_limit = powerLimit; | ||
1820 | ar9003_hw_set_target_power_eeprom(ah, chan->channel); | 1824 | ar9003_hw_set_target_power_eeprom(ah, chan->channel); |
1821 | ar9003_hw_calibration_apply(ah, chan->channel); | 1825 | ar9003_hw_calibration_apply(ah, chan->channel); |
1822 | } | 1826 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 5fe335e22c89..d8c0318f416f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | |||
@@ -265,7 +265,7 @@ struct cal_ctl_edge_pwr { | |||
265 | } __packed; | 265 | } __packed; |
266 | 266 | ||
267 | struct cal_ctl_data_2g { | 267 | struct cal_ctl_data_2g { |
268 | struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G]; | 268 | struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_2G]; |
269 | } __packed; | 269 | } __packed; |
270 | 270 | ||
271 | struct cal_ctl_data_5g { | 271 | struct cal_ctl_data_5g { |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_initvals.h index e0391b12e533..a131cd10ef29 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_initvals.h | |||
@@ -31,7 +31,7 @@ static const u32 ar9300_2p0_radio_postamble[][5] = { | |||
31 | 31 | ||
32 | static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][5] = { | 32 | static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][5] = { |
33 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 33 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
34 | {0x0000a410, 0x000050da, 0x000050da, 0x000050da, 0x000050da}, | 34 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, |
35 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 35 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
36 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | 36 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, |
37 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | 37 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, |
@@ -545,7 +545,7 @@ static const u32 ar9300_2p0_soc_postamble[][5] = { | |||
545 | }; | 545 | }; |
546 | 546 | ||
547 | static const u32 ar9200_merlin_2p0_radio_core[][2] = { | 547 | static const u32 ar9200_merlin_2p0_radio_core[][2] = { |
548 | /* Addr common */ | 548 | /* Addr allmodes */ |
549 | {0x00007800, 0x00040000}, | 549 | {0x00007800, 0x00040000}, |
550 | {0x00007804, 0xdb005012}, | 550 | {0x00007804, 0xdb005012}, |
551 | {0x00007808, 0x04924914}, | 551 | {0x00007808, 0x04924914}, |
@@ -835,71 +835,71 @@ static const u32 ar9300_2p0_baseband_core[][2] = { | |||
835 | 835 | ||
836 | static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { | 836 | static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { |
837 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 837 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
838 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050da, 0x000050da}, | 838 | {0x0000a410, 0x000050db, 0x000050db, 0x000050d9, 0x000050d9}, |
839 | {0x0000a500, 0x00020220, 0x00020220, 0x00000000, 0x00000000}, | 839 | {0x0000a500, 0x00020220, 0x00020220, 0x00000000, 0x00000000}, |
840 | {0x0000a504, 0x06020223, 0x06020223, 0x04000002, 0x04000002}, | 840 | {0x0000a504, 0x06020223, 0x06020223, 0x04000002, 0x04000002}, |
841 | {0x0000a508, 0x0b022220, 0x0b022220, 0x08000004, 0x08000004}, | 841 | {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, |
842 | {0x0000a50c, 0x10022223, 0x10022223, 0x0b000200, 0x0b000200}, | 842 | {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, |
843 | {0x0000a510, 0x17022620, 0x17022620, 0x0f000202, 0x0f000202}, | 843 | {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, |
844 | {0x0000a514, 0x1b022622, 0x1b022622, 0x11000400, 0x11000400}, | 844 | {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, |
845 | {0x0000a518, 0x1f022822, 0x1f022822, 0x15000402, 0x15000402}, | 845 | {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, |
846 | {0x0000a51c, 0x24022842, 0x24022842, 0x19000404, 0x19000404}, | 846 | {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, |
847 | {0x0000a520, 0x28042840, 0x28042840, 0x1b000603, 0x1b000603}, | 847 | {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, |
848 | {0x0000a524, 0x2c042842, 0x2c042842, 0x1f000a02, 0x1f000a02}, | 848 | {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, |
849 | {0x0000a528, 0x30042844, 0x30042844, 0x23000a04, 0x23000a04}, | 849 | {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, |
850 | {0x0000a52c, 0x34042846, 0x34042846, 0x26000a20, 0x26000a20}, | 850 | {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, |
851 | {0x0000a530, 0x39042869, 0x39042869, 0x2a000e20, 0x2a000e20}, | 851 | {0x0000a530, 0x34043643, 0x34043643, 0x2a000e20, 0x2a000e20}, |
852 | {0x0000a534, 0x3d062869, 0x3d062869, 0x2e000e22, 0x2e000e22}, | 852 | {0x0000a534, 0x38043a44, 0x38043a44, 0x2e000e22, 0x2e000e22}, |
853 | {0x0000a538, 0x44062c69, 0x44062c69, 0x31000e24, 0x31000e24}, | 853 | {0x0000a538, 0x3b043e45, 0x3b043e45, 0x31000e24, 0x31000e24}, |
854 | {0x0000a53c, 0x48063069, 0x48063069, 0x34001640, 0x34001640}, | 854 | {0x0000a53c, 0x40063e46, 0x40063e46, 0x34001640, 0x34001640}, |
855 | {0x0000a540, 0x4c0a3065, 0x4c0a3065, 0x38001660, 0x38001660}, | 855 | {0x0000a540, 0x44083e46, 0x44083e46, 0x38001660, 0x38001660}, |
856 | {0x0000a544, 0x500a3069, 0x500a3069, 0x3b001861, 0x3b001861}, | 856 | {0x0000a544, 0x46083e66, 0x46083e66, 0x3b001861, 0x3b001861}, |
857 | {0x0000a548, 0x530a3469, 0x530a3469, 0x3e001a81, 0x3e001a81}, | 857 | {0x0000a548, 0x4b0a3e69, 0x4b0a3e69, 0x3e001a81, 0x3e001a81}, |
858 | {0x0000a54c, 0x590a7464, 0x590a7464, 0x42001a83, 0x42001a83}, | 858 | {0x0000a54c, 0x4f0a5e66, 0x4f0a5e66, 0x42001a83, 0x42001a83}, |
859 | {0x0000a550, 0x5e0a7865, 0x5e0a7865, 0x44001c84, 0x44001c84}, | 859 | {0x0000a550, 0x540a7e66, 0x540a7e66, 0x44001c84, 0x44001c84}, |
860 | {0x0000a554, 0x630a7e66, 0x630a7e66, 0x48001ce3, 0x48001ce3}, | 860 | {0x0000a554, 0x570a7e89, 0x570a7e89, 0x48001ce3, 0x48001ce3}, |
861 | {0x0000a558, 0x680a7e89, 0x680a7e89, 0x4c001ce5, 0x4c001ce5}, | 861 | {0x0000a558, 0x5c0e7e8a, 0x5c0e7e8a, 0x4c001ce5, 0x4c001ce5}, |
862 | {0x0000a55c, 0x6e0a7e8c, 0x6e0a7e8c, 0x50001ce9, 0x50001ce9}, | 862 | {0x0000a55c, 0x60127e8b, 0x60127e8b, 0x50001ce9, 0x50001ce9}, |
863 | {0x0000a560, 0x730e7e8c, 0x730e7e8c, 0x54001ceb, 0x54001ceb}, | 863 | {0x0000a560, 0x65127ecc, 0x65127ecc, 0x54001ceb, 0x54001ceb}, |
864 | {0x0000a564, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 864 | {0x0000a564, 0x6b169ecd, 0x6b169ecd, 0x56001eec, 0x56001eec}, |
865 | {0x0000a568, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 865 | {0x0000a568, 0x70169f0e, 0x70169f0e, 0x56001eec, 0x56001eec}, |
866 | {0x0000a56c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 866 | {0x0000a56c, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, |
867 | {0x0000a570, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 867 | {0x0000a570, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, |
868 | {0x0000a574, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 868 | {0x0000a574, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, |
869 | {0x0000a578, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 869 | {0x0000a578, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, |
870 | {0x0000a57c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 870 | {0x0000a57c, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, |
871 | {0x0000a580, 0x00820220, 0x00820220, 0x00800000, 0x00800000}, | 871 | {0x0000a580, 0x00820220, 0x00820220, 0x00800000, 0x00800000}, |
872 | {0x0000a584, 0x06820223, 0x06820223, 0x04800002, 0x04800002}, | 872 | {0x0000a584, 0x06820223, 0x06820223, 0x04800002, 0x04800002}, |
873 | {0x0000a588, 0x0b822220, 0x0b822220, 0x08800004, 0x08800004}, | 873 | {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, |
874 | {0x0000a58c, 0x10822223, 0x10822223, 0x0b800200, 0x0b800200}, | 874 | {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, |
875 | {0x0000a590, 0x17822620, 0x17822620, 0x0f800202, 0x0f800202}, | 875 | {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, |
876 | {0x0000a594, 0x1b822622, 0x1b822622, 0x11800400, 0x11800400}, | 876 | {0x0000a594, 0x18822622, 0x18822622, 0x11800400, 0x11800400}, |
877 | {0x0000a598, 0x1f822822, 0x1f822822, 0x15800402, 0x15800402}, | 877 | {0x0000a598, 0x1b822822, 0x1b822822, 0x15800402, 0x15800402}, |
878 | {0x0000a59c, 0x24822842, 0x24822842, 0x19800404, 0x19800404}, | 878 | {0x0000a59c, 0x20822842, 0x20822842, 0x19800404, 0x19800404}, |
879 | {0x0000a5a0, 0x28842840, 0x28842840, 0x1b800603, 0x1b800603}, | 879 | {0x0000a5a0, 0x22822c41, 0x22822c41, 0x1b800603, 0x1b800603}, |
880 | {0x0000a5a4, 0x2c842842, 0x2c842842, 0x1f800a02, 0x1f800a02}, | 880 | {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, |
881 | {0x0000a5a8, 0x30842844, 0x30842844, 0x23800a04, 0x23800a04}, | 881 | {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, |
882 | {0x0000a5ac, 0x34842846, 0x34842846, 0x26800a20, 0x26800a20}, | 882 | {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, |
883 | {0x0000a5b0, 0x39842869, 0x39842869, 0x2a800e20, 0x2a800e20}, | 883 | {0x0000a5b0, 0x34843643, 0x34843643, 0x2a800e20, 0x2a800e20}, |
884 | {0x0000a5b4, 0x3d862869, 0x3d862869, 0x2e800e22, 0x2e800e22}, | 884 | {0x0000a5b4, 0x38843a44, 0x38843a44, 0x2e800e22, 0x2e800e22}, |
885 | {0x0000a5b8, 0x44862c69, 0x44862c69, 0x31800e24, 0x31800e24}, | 885 | {0x0000a5b8, 0x3b843e45, 0x3b843e45, 0x31800e24, 0x31800e24}, |
886 | {0x0000a5bc, 0x48863069, 0x48863069, 0x34801640, 0x34801640}, | 886 | {0x0000a5bc, 0x40863e46, 0x40863e46, 0x34801640, 0x34801640}, |
887 | {0x0000a5c0, 0x4c8a3065, 0x4c8a3065, 0x38801660, 0x38801660}, | 887 | {0x0000a5c0, 0x4c8a3065, 0x44883e46, 0x44883e46, 0x38801660}, |
888 | {0x0000a5c4, 0x508a3069, 0x508a3069, 0x3b801861, 0x3b801861}, | 888 | {0x0000a5c4, 0x46883e66, 0x46883e66, 0x3b801861, 0x3b801861}, |
889 | {0x0000a5c8, 0x538a3469, 0x538a3469, 0x3e801a81, 0x3e801a81}, | 889 | {0x0000a5c8, 0x4b8a3e69, 0x4b8a3e69, 0x3e801a81, 0x3e801a81}, |
890 | {0x0000a5cc, 0x598a7464, 0x598a7464, 0x42801a83, 0x42801a83}, | 890 | {0x0000a5cc, 0x4f8a5e66, 0x4f8a5e66, 0x42801a83, 0x42801a83}, |
891 | {0x0000a5d0, 0x5e8a7865, 0x5e8a7865, 0x44801c84, 0x44801c84}, | 891 | {0x0000a5d0, 0x548a7e66, 0x548a7e66, 0x44801c84, 0x44801c84}, |
892 | {0x0000a5d4, 0x638a7e66, 0x638a7e66, 0x48801ce3, 0x48801ce3}, | 892 | {0x0000a5d4, 0x578a7e89, 0x578a7e89, 0x48801ce3, 0x48801ce3}, |
893 | {0x0000a5d8, 0x688a7e89, 0x688a7e89, 0x4c801ce5, 0x4c801ce5}, | 893 | {0x0000a5d8, 0x5c8e7e8a, 0x5c8e7e8a, 0x4c801ce5, 0x4c801ce5}, |
894 | {0x0000a5dc, 0x6e8a7e8c, 0x6e8a7e8c, 0x50801ce9, 0x50801ce9}, | 894 | {0x0000a5dc, 0x60927e8b, 0x60927e8b, 0x50801ce9, 0x50801ce9}, |
895 | {0x0000a5e0, 0x738e7e8c, 0x738e7e8c, 0x54801ceb, 0x54801ceb}, | 895 | {0x0000a5e0, 0x65927ecc, 0x65927ecc, 0x54801ceb, 0x54801ceb}, |
896 | {0x0000a5e4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 896 | {0x0000a5e4, 0x6b969ecd, 0x6b969ecd, 0x56801eec, 0x56801eec}, |
897 | {0x0000a5e8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 897 | {0x0000a5e8, 0x70969f0e, 0x70969f0e, 0x56801eec, 0x56801eec}, |
898 | {0x0000a5ec, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 898 | {0x0000a5ec, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, |
899 | {0x0000a5f0, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 899 | {0x0000a5f0, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, |
900 | {0x0000a5f4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 900 | {0x0000a5f4, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, |
901 | {0x0000a5f8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 901 | {0x0000a5f8, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, |
902 | {0x0000a5fc, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 902 | {0x0000a5fc, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, |
903 | {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, | 903 | {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, |
904 | {0x00016048, 0xad241a61, 0xad241a61, 0xad241a61, 0xad241a61}, | 904 | {0x00016048, 0xad241a61, 0xad241a61, 0xad241a61, 0xad241a61}, |
905 | {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, | 905 | {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, |
@@ -913,71 +913,71 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { | |||
913 | 913 | ||
914 | static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = { | 914 | static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = { |
915 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 915 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
916 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050da, 0x000050da}, | 916 | {0x0000a410, 0x000050db, 0x000050db, 0x000050d9, 0x000050d9}, |
917 | {0x0000a500, 0x00020220, 0x00020220, 0x00000000, 0x00000000}, | 917 | {0x0000a500, 0x00020220, 0x00020220, 0x00000000, 0x00000000}, |
918 | {0x0000a504, 0x06020223, 0x06020223, 0x04000002, 0x04000002}, | 918 | {0x0000a504, 0x06020223, 0x06020223, 0x04000002, 0x04000002}, |
919 | {0x0000a508, 0x0b022220, 0x0b022220, 0x08000004, 0x08000004}, | 919 | {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, |
920 | {0x0000a50c, 0x10022223, 0x10022223, 0x0b000200, 0x0b000200}, | 920 | {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, |
921 | {0x0000a510, 0x17022620, 0x17022620, 0x0f000202, 0x0f000202}, | 921 | {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, |
922 | {0x0000a514, 0x1b022622, 0x1b022622, 0x11000400, 0x11000400}, | 922 | {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, |
923 | {0x0000a518, 0x1f022822, 0x1f022822, 0x15000402, 0x15000402}, | 923 | {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, |
924 | {0x0000a51c, 0x24022842, 0x24022842, 0x19000404, 0x19000404}, | 924 | {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, |
925 | {0x0000a520, 0x28042840, 0x28042840, 0x1b000603, 0x1b000603}, | 925 | {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, |
926 | {0x0000a524, 0x2c042842, 0x2c042842, 0x1f000a02, 0x1f000a02}, | 926 | {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, |
927 | {0x0000a528, 0x30042844, 0x30042844, 0x23000a04, 0x23000a04}, | 927 | {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, |
928 | {0x0000a52c, 0x34042846, 0x34042846, 0x26000a20, 0x26000a20}, | 928 | {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, |
929 | {0x0000a530, 0x39042869, 0x39042869, 0x2a000e20, 0x2a000e20}, | 929 | {0x0000a530, 0x34043643, 0x34043643, 0x2a000e20, 0x2a000e20}, |
930 | {0x0000a534, 0x3d062869, 0x3d062869, 0x2e000e22, 0x2e000e22}, | 930 | {0x0000a534, 0x38043a44, 0x38043a44, 0x2e000e22, 0x2e000e22}, |
931 | {0x0000a538, 0x44062c69, 0x44062c69, 0x31000e24, 0x31000e24}, | 931 | {0x0000a538, 0x3b043e45, 0x3b043e45, 0x31000e24, 0x31000e24}, |
932 | {0x0000a53c, 0x48063069, 0x48063069, 0x34001640, 0x34001640}, | 932 | {0x0000a53c, 0x40063e46, 0x40063e46, 0x34001640, 0x34001640}, |
933 | {0x0000a540, 0x4c0a3065, 0x4c0a3065, 0x38001660, 0x38001660}, | 933 | {0x0000a540, 0x44083e46, 0x44083e46, 0x38001660, 0x38001660}, |
934 | {0x0000a544, 0x500a3069, 0x500a3069, 0x3b001861, 0x3b001861}, | 934 | {0x0000a544, 0x46083e66, 0x46083e66, 0x3b001861, 0x3b001861}, |
935 | {0x0000a548, 0x530a3469, 0x530a3469, 0x3e001a81, 0x3e001a81}, | 935 | {0x0000a548, 0x4b0a3e69, 0x4b0a3e69, 0x3e001a81, 0x3e001a81}, |
936 | {0x0000a54c, 0x590a7464, 0x590a7464, 0x42001a83, 0x42001a83}, | 936 | {0x0000a54c, 0x4f0a5e66, 0x4f0a5e66, 0x42001a83, 0x42001a83}, |
937 | {0x0000a550, 0x5e0a7865, 0x5e0a7865, 0x44001c84, 0x44001c84}, | 937 | {0x0000a550, 0x540a7e66, 0x540a7e66, 0x44001c84, 0x44001c84}, |
938 | {0x0000a554, 0x630a7e66, 0x630a7e66, 0x48001ce3, 0x48001ce3}, | 938 | {0x0000a554, 0x570a7e89, 0x570a7e89, 0x48001ce3, 0x48001ce3}, |
939 | {0x0000a558, 0x680a7e89, 0x680a7e89, 0x4c001ce5, 0x4c001ce5}, | 939 | {0x0000a558, 0x5c0e7e8a, 0x5c0e7e8a, 0x4c001ce5, 0x4c001ce5}, |
940 | {0x0000a55c, 0x6e0a7e8c, 0x6e0a7e8c, 0x50001ce9, 0x50001ce9}, | 940 | {0x0000a55c, 0x60127e8b, 0x60127e8b, 0x50001ce9, 0x50001ce9}, |
941 | {0x0000a560, 0x730e7e8c, 0x730e7e8c, 0x54001ceb, 0x54001ceb}, | 941 | {0x0000a560, 0x65127ecc, 0x65127ecc, 0x54001ceb, 0x54001ceb}, |
942 | {0x0000a564, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 942 | {0x0000a564, 0x6b169ecd, 0x6b169ecd, 0x56001eec, 0x56001eec}, |
943 | {0x0000a568, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 943 | {0x0000a568, 0x70169f0e, 0x70169f0e, 0x56001eec, 0x56001eec}, |
944 | {0x0000a56c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 944 | {0x0000a56c, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, |
945 | {0x0000a570, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 945 | {0x0000a570, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, |
946 | {0x0000a574, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 946 | {0x0000a574, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, |
947 | {0x0000a578, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 947 | {0x0000a578, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, |
948 | {0x0000a57c, 0x730e7e8c, 0x730e7e8c, 0x56001eec, 0x56001eec}, | 948 | {0x0000a57c, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, |
949 | {0x0000a580, 0x00820220, 0x00820220, 0x00800000, 0x00800000}, | 949 | {0x0000a580, 0x00820220, 0x00820220, 0x00800000, 0x00800000}, |
950 | {0x0000a584, 0x06820223, 0x06820223, 0x04800002, 0x04800002}, | 950 | {0x0000a584, 0x06820223, 0x06820223, 0x04800002, 0x04800002}, |
951 | {0x0000a588, 0x0b822220, 0x0b822220, 0x08800004, 0x08800004}, | 951 | {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, |
952 | {0x0000a58c, 0x10822223, 0x10822223, 0x0b800200, 0x0b800200}, | 952 | {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, |
953 | {0x0000a590, 0x17822620, 0x17822620, 0x0f800202, 0x0f800202}, | 953 | {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, |
954 | {0x0000a594, 0x1b822622, 0x1b822622, 0x11800400, 0x11800400}, | 954 | {0x0000a594, 0x18822622, 0x18822622, 0x11800400, 0x11800400}, |
955 | {0x0000a598, 0x1f822822, 0x1f822822, 0x15800402, 0x15800402}, | 955 | {0x0000a598, 0x1b822822, 0x1b822822, 0x15800402, 0x15800402}, |
956 | {0x0000a59c, 0x24822842, 0x24822842, 0x19800404, 0x19800404}, | 956 | {0x0000a59c, 0x20822842, 0x20822842, 0x19800404, 0x19800404}, |
957 | {0x0000a5a0, 0x28842840, 0x28842840, 0x1b800603, 0x1b800603}, | 957 | {0x0000a5a0, 0x22822c41, 0x22822c41, 0x1b800603, 0x1b800603}, |
958 | {0x0000a5a4, 0x2c842842, 0x2c842842, 0x1f800a02, 0x1f800a02}, | 958 | {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, |
959 | {0x0000a5a8, 0x30842844, 0x30842844, 0x23800a04, 0x23800a04}, | 959 | {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, |
960 | {0x0000a5ac, 0x34842846, 0x34842846, 0x26800a20, 0x26800a20}, | 960 | {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, |
961 | {0x0000a5b0, 0x39842869, 0x39842869, 0x2a800e20, 0x2a800e20}, | 961 | {0x0000a5b0, 0x34843643, 0x34843643, 0x2a800e20, 0x2a800e20}, |
962 | {0x0000a5b4, 0x3d862869, 0x3d862869, 0x2e800e22, 0x2e800e22}, | 962 | {0x0000a5b4, 0x38843a44, 0x38843a44, 0x2e800e22, 0x2e800e22}, |
963 | {0x0000a5b8, 0x44862c69, 0x44862c69, 0x31800e24, 0x31800e24}, | 963 | {0x0000a5b8, 0x3b843e45, 0x3b843e45, 0x31800e24, 0x31800e24}, |
964 | {0x0000a5bc, 0x48863069, 0x48863069, 0x34801640, 0x34801640}, | 964 | {0x0000a5bc, 0x40863e46, 0x40863e46, 0x34801640, 0x34801640}, |
965 | {0x0000a5c0, 0x4c8a3065, 0x4c8a3065, 0x38801660, 0x38801660}, | 965 | {0x0000a5c0, 0x44883e46, 0x44883e46, 0x38801660, 0x38801660}, |
966 | {0x0000a5c4, 0x508a3069, 0x508a3069, 0x3b801861, 0x3b801861}, | 966 | {0x0000a5c4, 0x46883e66, 0x46883e66, 0x3b801861, 0x3b801861}, |
967 | {0x0000a5c8, 0x538a3469, 0x538a3469, 0x3e801a81, 0x3e801a81}, | 967 | {0x0000a5c8, 0x4b8a3e69, 0x4b8a3e69, 0x3e801a81, 0x3e801a81}, |
968 | {0x0000a5cc, 0x598a7464, 0x598a7464, 0x42801a83, 0x42801a83}, | 968 | {0x0000a5cc, 0x4f8a5e66, 0x4f8a5e66, 0x42801a83, 0x42801a83}, |
969 | {0x0000a5d0, 0x5e8a7865, 0x5e8a7865, 0x44801c84, 0x44801c84}, | 969 | {0x0000a5d0, 0x548a7e66, 0x548a7e66, 0x44801c84, 0x44801c84}, |
970 | {0x0000a5d4, 0x638a7e66, 0x638a7e66, 0x48801ce3, 0x48801ce3}, | 970 | {0x0000a5d4, 0x578a7e89, 0x578a7e89, 0x48801ce3, 0x48801ce3}, |
971 | {0x0000a5d8, 0x688a7e89, 0x688a7e89, 0x4c801ce5, 0x4c801ce5}, | 971 | {0x0000a5d8, 0x5c8e7e8a, 0x5c8e7e8a, 0x4c801ce5, 0x4c801ce5}, |
972 | {0x0000a5dc, 0x6e8a7e8c, 0x6e8a7e8c, 0x50801ce9, 0x50801ce9}, | 972 | {0x0000a5dc, 0x60927e8b, 0x60927e8b, 0x50801ce9, 0x50801ce9}, |
973 | {0x0000a5e0, 0x738e7e8c, 0x738e7e8c, 0x54801ceb, 0x54801ceb}, | 973 | {0x0000a5e0, 0x65927ecc, 0x65927ecc, 0x54801ceb, 0x54801ceb}, |
974 | {0x0000a5e4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 974 | {0x0000a5e4, 0x6b969ecd, 0x6b969ecd, 0x56801eec, 0x56801eec}, |
975 | {0x0000a5e8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 975 | {0x0000a5e8, 0x70969f0e, 0x70969f0e, 0x56801eec, 0x56801eec}, |
976 | {0x0000a5ec, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 976 | {0x0000a5ec, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, |
977 | {0x0000a5f0, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 977 | {0x0000a5f0, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, |
978 | {0x0000a5f4, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 978 | {0x0000a5f4, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, |
979 | {0x0000a5f8, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 979 | {0x0000a5f8, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, |
980 | {0x0000a5fc, 0x738e7e8c, 0x738e7e8c, 0x56801eec, 0x56801eec}, | 980 | {0x0000a5fc, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, |
981 | {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, | 981 | {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, |
982 | {0x00016048, 0x8c001a61, 0x8c001a61, 0x8c001a61, 0x8c001a61}, | 982 | {0x00016048, 0x8c001a61, 0x8c001a61, 0x8c001a61, 0x8c001a61}, |
983 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 983 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
@@ -1251,7 +1251,7 @@ static const u32 ar9300Common_rx_gain_table_2p0[][2] = { | |||
1251 | 1251 | ||
1252 | static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p0[][5] = { | 1252 | static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p0[][5] = { |
1253 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 1253 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
1254 | {0x0000a410, 0x000050da, 0x000050da, 0x000050da, 0x000050da}, | 1254 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, |
1255 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 1255 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
1256 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | 1256 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, |
1257 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | 1257 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, |
@@ -1760,31 +1760,22 @@ static const u32 ar9300_2p0_soc_preamble[][2] = { | |||
1760 | {0x00007038, 0x000004c2}, | 1760 | {0x00007038, 0x000004c2}, |
1761 | }; | 1761 | }; |
1762 | 1762 | ||
1763 | /* | ||
1764 | * PCIE-PHY programming array, to be used prior to entering | ||
1765 | * full sleep (holding RTC in reset, PLL is ON in L1 mode) | ||
1766 | */ | ||
1767 | static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0[][2] = { | 1763 | static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0[][2] = { |
1764 | /* Addr allmodes */ | ||
1768 | {0x00004040, 0x08212e5e}, | 1765 | {0x00004040, 0x08212e5e}, |
1769 | {0x00004040, 0x0008003b}, | 1766 | {0x00004040, 0x0008003b}, |
1770 | {0x00004044, 0x00000000}, | 1767 | {0x00004044, 0x00000000}, |
1771 | }; | 1768 | }; |
1772 | 1769 | ||
1773 | /* | ||
1774 | * PCIE-PHY programming array, to be used when not in | ||
1775 | * full sleep (holding RTC in reset) | ||
1776 | */ | ||
1777 | static const u32 ar9300PciePhy_clkreq_enable_L1_2p0[][2] = { | 1770 | static const u32 ar9300PciePhy_clkreq_enable_L1_2p0[][2] = { |
1771 | /* Addr allmodes */ | ||
1778 | {0x00004040, 0x08253e5e}, | 1772 | {0x00004040, 0x08253e5e}, |
1779 | {0x00004040, 0x0008003b}, | 1773 | {0x00004040, 0x0008003b}, |
1780 | {0x00004044, 0x00000000}, | 1774 | {0x00004044, 0x00000000}, |
1781 | }; | 1775 | }; |
1782 | 1776 | ||
1783 | /* | ||
1784 | * PCIE-PHY programming array, to be used prior to entering | ||
1785 | * full sleep (holding RTC in reset) | ||
1786 | */ | ||
1787 | static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = { | 1777 | static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = { |
1778 | /* Addr allmodes */ | ||
1788 | {0x00004040, 0x08213e5e}, | 1779 | {0x00004040, 0x08213e5e}, |
1789 | {0x00004040, 0x0008003b}, | 1780 | {0x00004040, 0x0008003b}, |
1790 | {0x00004044, 0x00000000}, | 1781 | {0x00004044, 0x00000000}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 7d111fbf8bc5..37ba37481a47 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
@@ -311,6 +311,9 @@ static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | |||
311 | { | 311 | { |
312 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | 312 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; |
313 | 313 | ||
314 | if (txpower > ah->txpower_limit) | ||
315 | txpower = ah->txpower_limit; | ||
316 | |||
314 | txpower += ah->txpower_indexoffset; | 317 | txpower += ah->txpower_indexoffset; |
315 | if (txpower > 63) | 318 | if (txpower > 63) |
316 | txpower = 63; | 319 | txpower = 63; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 137543b2d739..80431a2f6dc1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -375,16 +375,7 @@ static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah, | |||
375 | else if (chan && IS_CHAN_QUARTER_RATE(chan)) | 375 | else if (chan && IS_CHAN_QUARTER_RATE(chan)) |
376 | pll |= SM(0x2, AR_RTC_9300_PLL_CLKSEL); | 376 | pll |= SM(0x2, AR_RTC_9300_PLL_CLKSEL); |
377 | 377 | ||
378 | if (chan && IS_CHAN_5GHZ(chan)) { | 378 | pll |= SM(0x2c, AR_RTC_9300_PLL_DIV); |
379 | pll |= SM(0x28, AR_RTC_9300_PLL_DIV); | ||
380 | |||
381 | /* | ||
382 | * When doing fast clock, set PLL to 0x142c | ||
383 | */ | ||
384 | if (IS_CHAN_A_5MHZ_SPACED(chan)) | ||
385 | pll = 0x142c; | ||
386 | } else | ||
387 | pll |= SM(0x2c, AR_RTC_9300_PLL_DIV); | ||
388 | 379 | ||
389 | return pll; | 380 | return pll; |
390 | } | 381 | } |
@@ -592,7 +583,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
592 | * For 5GHz channels requiring Fast Clock, apply | 583 | * For 5GHz channels requiring Fast Clock, apply |
593 | * different modal values. | 584 | * different modal values. |
594 | */ | 585 | */ |
595 | if (IS_CHAN_A_5MHZ_SPACED(chan)) | 586 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) |
596 | REG_WRITE_ARRAY(&ah->iniModesAdditional, | 587 | REG_WRITE_ARRAY(&ah->iniModesAdditional, |
597 | modesIndex, regWrites); | 588 | modesIndex, regWrites); |
598 | 589 | ||
@@ -622,7 +613,7 @@ static void ar9003_hw_set_rfmode(struct ath_hw *ah, | |||
622 | rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) | 613 | rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) |
623 | ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; | 614 | ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; |
624 | 615 | ||
625 | if (IS_CHAN_A_5MHZ_SPACED(chan)) | 616 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) |
626 | rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); | 617 | rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); |
627 | 618 | ||
628 | REG_WRITE(ah, AR_PHY_MODE, rfMode); | 619 | REG_WRITE(ah, AR_PHY_MODE, rfMode); |
@@ -1102,6 +1093,7 @@ static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) | |||
1102 | ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf " | 1093 | ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf " |
1103 | "to load: AR_PHY_AGC_CONTROL=0x%x\n", | 1094 | "to load: AR_PHY_AGC_CONTROL=0x%x\n", |
1104 | REG_READ(ah, AR_PHY_AGC_CONTROL)); | 1095 | REG_READ(ah, AR_PHY_AGC_CONTROL)); |
1096 | return; | ||
1105 | } | 1097 | } |
1106 | 1098 | ||
1107 | /* | 1099 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 09effdedc8c0..b4424a623cf5 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c | |||
@@ -212,7 +212,6 @@ int ath9k_cmn_rx_skb_preprocess(struct ath_common *common, | |||
212 | rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp); | 212 | rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp); |
213 | rx_status->band = hw->conf.channel->band; | 213 | rx_status->band = hw->conf.channel->band; |
214 | rx_status->freq = hw->conf.channel->center_freq; | 214 | rx_status->freq = hw->conf.channel->center_freq; |
215 | rx_status->noise = common->ani.noise_floor; | ||
216 | rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; | 215 | rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; |
217 | rx_status->antenna = rx_stats->rs_antenna; | 216 | rx_status->antenna = rx_stats->rs_antenna; |
218 | rx_status->flag |= RX_FLAG_TSFT; | 217 | rx_status->flag |= RX_FLAG_TSFT; |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index fb9c8c92eabe..21354c15a9a9 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -300,7 +300,8 @@ struct base_eep_header { | |||
300 | u32 binBuildNumber; | 300 | u32 binBuildNumber; |
301 | u8 deviceType; | 301 | u8 deviceType; |
302 | u8 pwdclkind; | 302 | u8 pwdclkind; |
303 | u8 futureBase_1[2]; | 303 | u8 fastClk5g; |
304 | u8 divChain; | ||
304 | u8 rxGainType; | 305 | u8 rxGainType; |
305 | u8 dacHiPwrMode_5G; | 306 | u8 dacHiPwrMode_5G; |
306 | u8 openLoopPwrCntl; | 307 | u8 openLoopPwrCntl; |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index cf59799ef307..e591ad6016e5 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
@@ -274,6 +274,8 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah, | |||
274 | return pBase->txMask; | 274 | return pBase->txMask; |
275 | case EEP_RX_MASK: | 275 | case EEP_RX_MASK: |
276 | return pBase->rxMask; | 276 | return pBase->rxMask; |
277 | case EEP_FSTCLK_5G: | ||
278 | return pBase->fastClk5g; | ||
277 | case EEP_RXGAIN_TYPE: | 279 | case EEP_RXGAIN_TYPE: |
278 | return pBase->rxGainType; | 280 | return pBase->rxGainType; |
279 | case EEP_TXGAIN_TYPE: | 281 | case EEP_TXGAIN_TYPE: |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 3091bb3cef9b..74872ca76f9a 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -93,14 +93,24 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, | |||
93 | return ret; | 93 | return ret; |
94 | } | 94 | } |
95 | 95 | ||
96 | static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, | ||
97 | struct sk_buff_head *list) | ||
98 | { | ||
99 | struct sk_buff *skb; | ||
100 | |||
101 | while ((skb = __skb_dequeue(list)) != NULL) { | ||
102 | dev_kfree_skb_any(skb); | ||
103 | TX_STAT_INC(skb_dropped); | ||
104 | } | ||
105 | } | ||
106 | |||
96 | static void hif_usb_tx_cb(struct urb *urb) | 107 | static void hif_usb_tx_cb(struct urb *urb) |
97 | { | 108 | { |
98 | struct tx_buf *tx_buf = (struct tx_buf *) urb->context; | 109 | struct tx_buf *tx_buf = (struct tx_buf *) urb->context; |
99 | struct hif_device_usb *hif_dev = tx_buf->hif_dev; | 110 | struct hif_device_usb *hif_dev = tx_buf->hif_dev; |
100 | struct sk_buff *skb; | 111 | struct sk_buff *skb; |
101 | bool drop, flush; | ||
102 | 112 | ||
103 | if (!hif_dev) | 113 | if (!hif_dev || !tx_buf) |
104 | return; | 114 | return; |
105 | 115 | ||
106 | switch (urb->status) { | 116 | switch (urb->status) { |
@@ -108,57 +118,47 @@ static void hif_usb_tx_cb(struct urb *urb) | |||
108 | break; | 118 | break; |
109 | case -ENOENT: | 119 | case -ENOENT: |
110 | case -ECONNRESET: | 120 | case -ECONNRESET: |
111 | break; | ||
112 | case -ENODEV: | 121 | case -ENODEV: |
113 | case -ESHUTDOWN: | 122 | case -ESHUTDOWN: |
123 | /* | ||
124 | * The URB has been killed, free the SKBs | ||
125 | * and return. | ||
126 | */ | ||
127 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
114 | return; | 128 | return; |
115 | default: | 129 | default: |
116 | break; | 130 | break; |
117 | } | 131 | } |
118 | 132 | ||
119 | if (tx_buf) { | 133 | /* Check if TX has been stopped */ |
120 | spin_lock(&hif_dev->tx.tx_lock); | 134 | spin_lock(&hif_dev->tx.tx_lock); |
121 | drop = !!(hif_dev->tx.flags & HIF_USB_TX_STOP); | 135 | if (hif_dev->tx.flags & HIF_USB_TX_STOP) { |
122 | flush = !!(hif_dev->tx.flags & HIF_USB_TX_FLUSH); | ||
123 | spin_unlock(&hif_dev->tx.tx_lock); | ||
124 | |||
125 | while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) { | ||
126 | if (!drop && !flush) { | ||
127 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
128 | skb, 1); | ||
129 | TX_STAT_INC(skb_completed); | ||
130 | } else { | ||
131 | dev_kfree_skb_any(skb); | ||
132 | TX_STAT_INC(skb_dropped); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | if (flush) | ||
137 | return; | ||
138 | |||
139 | tx_buf->len = tx_buf->offset = 0; | ||
140 | __skb_queue_head_init(&tx_buf->skb_queue); | ||
141 | |||
142 | spin_lock(&hif_dev->tx.tx_lock); | ||
143 | list_del(&tx_buf->list); | ||
144 | list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf); | ||
145 | hif_dev->tx.tx_buf_cnt++; | ||
146 | if (!drop) | ||
147 | __hif_usb_tx(hif_dev); /* Check for pending SKBs */ | ||
148 | TX_STAT_INC(buf_completed); | ||
149 | spin_unlock(&hif_dev->tx.tx_lock); | 136 | spin_unlock(&hif_dev->tx.tx_lock); |
150 | } | 137 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); |
151 | } | 138 | goto add_free; |
152 | 139 | } | |
153 | static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, | 140 | spin_unlock(&hif_dev->tx.tx_lock); |
154 | struct sk_buff_head *list) | 141 | |
155 | { | 142 | /* Complete the queued SKBs. */ |
156 | struct sk_buff *skb; | 143 | while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) { |
157 | 144 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | |
158 | while ((skb = __skb_dequeue(list)) != NULL) { | 145 | skb, 1); |
159 | dev_kfree_skb_any(skb); | 146 | TX_STAT_INC(skb_completed); |
160 | TX_STAT_INC(skb_dropped); | 147 | } |
161 | } | 148 | |
149 | add_free: | ||
150 | /* Re-initialize the SKB queue */ | ||
151 | tx_buf->len = tx_buf->offset = 0; | ||
152 | __skb_queue_head_init(&tx_buf->skb_queue); | ||
153 | |||
154 | /* Add this TX buffer to the free list */ | ||
155 | spin_lock(&hif_dev->tx.tx_lock); | ||
156 | list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); | ||
157 | hif_dev->tx.tx_buf_cnt++; | ||
158 | if (!(hif_dev->tx.flags & HIF_USB_TX_STOP)) | ||
159 | __hif_usb_tx(hif_dev); /* Check for pending SKBs */ | ||
160 | TX_STAT_INC(buf_completed); | ||
161 | spin_unlock(&hif_dev->tx.tx_lock); | ||
162 | } | 162 | } |
163 | 163 | ||
164 | /* TX lock has to be taken */ | 164 | /* TX lock has to be taken */ |
@@ -178,8 +178,7 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) | |||
178 | return 0; | 178 | return 0; |
179 | 179 | ||
180 | tx_buf = list_first_entry(&hif_dev->tx.tx_buf, struct tx_buf, list); | 180 | tx_buf = list_first_entry(&hif_dev->tx.tx_buf, struct tx_buf, list); |
181 | list_del(&tx_buf->list); | 181 | list_move_tail(&tx_buf->list, &hif_dev->tx.tx_pending); |
182 | list_add_tail(&tx_buf->list, &hif_dev->tx.tx_pending); | ||
183 | hif_dev->tx.tx_buf_cnt--; | 182 | hif_dev->tx.tx_buf_cnt--; |
184 | 183 | ||
185 | tx_skb_cnt = min_t(u16, hif_dev->tx.tx_skb_cnt, MAX_TX_AGGR_NUM); | 184 | tx_skb_cnt = min_t(u16, hif_dev->tx.tx_skb_cnt, MAX_TX_AGGR_NUM); |
@@ -511,9 +510,18 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) | |||
511 | if (likely(urb->actual_length != 0)) { | 510 | if (likely(urb->actual_length != 0)) { |
512 | skb_put(skb, urb->actual_length); | 511 | skb_put(skb, urb->actual_length); |
513 | 512 | ||
513 | /* Process the command first */ | ||
514 | ath9k_htc_rx_msg(hif_dev->htc_handle, skb, | ||
515 | skb->len, USB_REG_IN_PIPE); | ||
516 | |||
517 | |||
514 | nskb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC); | 518 | nskb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC); |
515 | if (!nskb) | 519 | if (!nskb) { |
516 | goto resubmit; | 520 | dev_err(&hif_dev->udev->dev, |
521 | "ath9k_htc: REG_IN memory allocation failure\n"); | ||
522 | urb->context = NULL; | ||
523 | return; | ||
524 | } | ||
517 | 525 | ||
518 | usb_fill_int_urb(urb, hif_dev->udev, | 526 | usb_fill_int_urb(urb, hif_dev->udev, |
519 | usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), | 527 | usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), |
@@ -523,12 +531,9 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) | |||
523 | ret = usb_submit_urb(urb, GFP_ATOMIC); | 531 | ret = usb_submit_urb(urb, GFP_ATOMIC); |
524 | if (ret) { | 532 | if (ret) { |
525 | kfree_skb(nskb); | 533 | kfree_skb(nskb); |
526 | goto free; | 534 | urb->context = NULL; |
527 | } | 535 | } |
528 | 536 | ||
529 | ath9k_htc_rx_msg(hif_dev->htc_handle, skb, | ||
530 | skb->len, USB_REG_IN_PIPE); | ||
531 | |||
532 | return; | 537 | return; |
533 | } | 538 | } |
534 | 539 | ||
@@ -548,20 +553,17 @@ free: | |||
548 | 553 | ||
549 | static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) | 554 | static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) |
550 | { | 555 | { |
551 | unsigned long flags; | ||
552 | struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; | 556 | struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; |
553 | 557 | ||
554 | list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_buf, list) { | 558 | list_for_each_entry_safe(tx_buf, tx_buf_tmp, |
559 | &hif_dev->tx.tx_buf, list) { | ||
560 | usb_kill_urb(tx_buf->urb); | ||
555 | list_del(&tx_buf->list); | 561 | list_del(&tx_buf->list); |
556 | usb_free_urb(tx_buf->urb); | 562 | usb_free_urb(tx_buf->urb); |
557 | kfree(tx_buf->buf); | 563 | kfree(tx_buf->buf); |
558 | kfree(tx_buf); | 564 | kfree(tx_buf); |
559 | } | 565 | } |
560 | 566 | ||
561 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | ||
562 | hif_dev->tx.flags |= HIF_USB_TX_FLUSH; | ||
563 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | ||
564 | |||
565 | list_for_each_entry_safe(tx_buf, tx_buf_tmp, | 567 | list_for_each_entry_safe(tx_buf, tx_buf_tmp, |
566 | &hif_dev->tx.tx_pending, list) { | 568 | &hif_dev->tx.tx_pending, list) { |
567 | usb_kill_urb(tx_buf->urb); | 569 | usb_kill_urb(tx_buf->urb); |
@@ -570,10 +572,6 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) | |||
570 | kfree(tx_buf->buf); | 572 | kfree(tx_buf->buf); |
571 | kfree(tx_buf); | 573 | kfree(tx_buf); |
572 | } | 574 | } |
573 | |||
574 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | ||
575 | hif_dev->tx.flags &= ~HIF_USB_TX_FLUSH; | ||
576 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | ||
577 | } | 575 | } |
578 | 576 | ||
579 | static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) | 577 | static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) |
@@ -897,6 +895,26 @@ err_alloc: | |||
897 | return ret; | 895 | return ret; |
898 | } | 896 | } |
899 | 897 | ||
898 | static void ath9k_hif_usb_reboot(struct usb_device *udev) | ||
899 | { | ||
900 | u32 reboot_cmd = 0xffffffff; | ||
901 | void *buf; | ||
902 | int ret; | ||
903 | |||
904 | buf = kmalloc(4, GFP_KERNEL); | ||
905 | if (!buf) | ||
906 | return; | ||
907 | |||
908 | memcpy(buf, &reboot_cmd, 4); | ||
909 | |||
910 | ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, USB_REG_OUT_PIPE), | ||
911 | buf, 4, NULL, HZ); | ||
912 | if (ret) | ||
913 | dev_err(&udev->dev, "ath9k_htc: USB reboot failed\n"); | ||
914 | |||
915 | kfree(buf); | ||
916 | } | ||
917 | |||
900 | static void ath9k_hif_usb_disconnect(struct usb_interface *interface) | 918 | static void ath9k_hif_usb_disconnect(struct usb_interface *interface) |
901 | { | 919 | { |
902 | struct usb_device *udev = interface_to_usbdev(interface); | 920 | struct usb_device *udev = interface_to_usbdev(interface); |
@@ -904,14 +922,15 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) | |||
904 | (struct hif_device_usb *) usb_get_intfdata(interface); | 922 | (struct hif_device_usb *) usb_get_intfdata(interface); |
905 | 923 | ||
906 | if (hif_dev) { | 924 | if (hif_dev) { |
907 | ath9k_htc_hw_deinit(hif_dev->htc_handle, true); | 925 | ath9k_htc_hw_deinit(hif_dev->htc_handle, |
926 | (udev->state == USB_STATE_NOTATTACHED) ? true : false); | ||
908 | ath9k_htc_hw_free(hif_dev->htc_handle); | 927 | ath9k_htc_hw_free(hif_dev->htc_handle); |
909 | ath9k_hif_usb_dev_deinit(hif_dev); | 928 | ath9k_hif_usb_dev_deinit(hif_dev); |
910 | usb_set_intfdata(interface, NULL); | 929 | usb_set_intfdata(interface, NULL); |
911 | } | 930 | } |
912 | 931 | ||
913 | if (hif_dev->flags & HIF_USB_START) | 932 | if (hif_dev->flags & HIF_USB_START) |
914 | usb_reset_device(udev); | 933 | ath9k_hif_usb_reboot(udev); |
915 | 934 | ||
916 | kfree(hif_dev); | 935 | kfree(hif_dev); |
917 | dev_info(&udev->dev, "ath9k_htc: USB layer deinitialized\n"); | 936 | dev_info(&udev->dev, "ath9k_htc: USB layer deinitialized\n"); |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 7d49a8af420e..0aca49b6fcb6 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h | |||
@@ -61,7 +61,6 @@ struct tx_buf { | |||
61 | }; | 61 | }; |
62 | 62 | ||
63 | #define HIF_USB_TX_STOP BIT(0) | 63 | #define HIF_USB_TX_STOP BIT(0) |
64 | #define HIF_USB_TX_FLUSH BIT(1) | ||
65 | 64 | ||
66 | struct hif_usb_tx { | 65 | struct hif_usb_tx { |
67 | u8 flags; | 66 | u8 flags; |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index c765ff4a505c..1ae18bbc4d9e 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -329,6 +329,7 @@ struct htc_beacon_config { | |||
329 | #define OP_ASSOCIATED BIT(8) | 329 | #define OP_ASSOCIATED BIT(8) |
330 | #define OP_ENABLE_BEACON BIT(9) | 330 | #define OP_ENABLE_BEACON BIT(9) |
331 | #define OP_LED_DEINIT BIT(10) | 331 | #define OP_LED_DEINIT BIT(10) |
332 | #define OP_UNPLUGGED BIT(11) | ||
332 | 333 | ||
333 | struct ath9k_htc_priv { | 334 | struct ath9k_htc_priv { |
334 | struct device *dev; | 335 | struct device *dev; |
@@ -378,6 +379,7 @@ struct ath9k_htc_priv { | |||
378 | struct mutex htc_pm_lock; | 379 | struct mutex htc_pm_lock; |
379 | unsigned long ps_usecount; | 380 | unsigned long ps_usecount; |
380 | bool ps_enabled; | 381 | bool ps_enabled; |
382 | bool ps_idle; | ||
381 | 383 | ||
382 | struct ath_led radio_led; | 384 | struct ath_led radio_led; |
383 | struct ath_led assoc_led; | 385 | struct ath_led assoc_led; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index a86189629d92..701f2ef5a440 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -744,6 +744,9 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, | |||
744 | if (ret) | 744 | if (ret) |
745 | goto err_init; | 745 | goto err_init; |
746 | 746 | ||
747 | /* The device may have been unplugged earlier. */ | ||
748 | priv->op_flags &= ~OP_UNPLUGGED; | ||
749 | |||
747 | ret = ath9k_init_device(priv, devid); | 750 | ret = ath9k_init_device(priv, devid); |
748 | if (ret) | 751 | if (ret) |
749 | goto err_init; | 752 | goto err_init; |
@@ -760,6 +763,11 @@ err_free: | |||
760 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) | 763 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) |
761 | { | 764 | { |
762 | if (htc_handle->drv_priv) { | 765 | if (htc_handle->drv_priv) { |
766 | |||
767 | /* Check if the device has been yanked out. */ | ||
768 | if (hotunplug) | ||
769 | htc_handle->drv_priv->op_flags |= OP_UNPLUGGED; | ||
770 | |||
763 | ath9k_deinit_device(htc_handle->drv_priv); | 771 | ath9k_deinit_device(htc_handle->drv_priv); |
764 | ath9k_deinit_wmi(htc_handle->drv_priv); | 772 | ath9k_deinit_wmi(htc_handle->drv_priv); |
765 | ieee80211_free_hw(htc_handle->drv_priv->hw); | 773 | ieee80211_free_hw(htc_handle->drv_priv->hw); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ec7bcc8696ec..ca7f3a78eb11 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -94,8 +94,11 @@ void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv) | |||
94 | if (--priv->ps_usecount != 0) | 94 | if (--priv->ps_usecount != 0) |
95 | goto unlock; | 95 | goto unlock; |
96 | 96 | ||
97 | if (priv->ps_enabled) | 97 | if (priv->ps_idle) |
98 | ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP); | ||
99 | else if (priv->ps_enabled) | ||
98 | ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP); | 100 | ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP); |
101 | |||
99 | unlock: | 102 | unlock: |
100 | mutex_unlock(&priv->htc_pm_lock); | 103 | mutex_unlock(&priv->htc_pm_lock); |
101 | } | 104 | } |
@@ -153,7 +156,6 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
153 | ath_print(common, ATH_DBG_FATAL, | 156 | ath_print(common, ATH_DBG_FATAL, |
154 | "Unable to reset channel (%u Mhz) " | 157 | "Unable to reset channel (%u Mhz) " |
155 | "reset status %d\n", channel->center_freq, ret); | 158 | "reset status %d\n", channel->center_freq, ret); |
156 | ath9k_htc_ps_restore(priv); | ||
157 | goto err; | 159 | goto err; |
158 | } | 160 | } |
159 | 161 | ||
@@ -1097,7 +1099,7 @@ fail_tx: | |||
1097 | return 0; | 1099 | return 0; |
1098 | } | 1100 | } |
1099 | 1101 | ||
1100 | static int ath9k_htc_start(struct ieee80211_hw *hw) | 1102 | static int ath9k_htc_radio_enable(struct ieee80211_hw *hw) |
1101 | { | 1103 | { |
1102 | struct ath9k_htc_priv *priv = hw->priv; | 1104 | struct ath9k_htc_priv *priv = hw->priv; |
1103 | struct ath_hw *ah = priv->ah; | 1105 | struct ath_hw *ah = priv->ah; |
@@ -1113,8 +1115,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
1113 | "Starting driver with initial channel: %d MHz\n", | 1115 | "Starting driver with initial channel: %d MHz\n", |
1114 | curchan->center_freq); | 1116 | curchan->center_freq); |
1115 | 1117 | ||
1116 | mutex_lock(&priv->mutex); | ||
1117 | |||
1118 | /* setup initial channel */ | 1118 | /* setup initial channel */ |
1119 | init_channel = ath9k_cmn_get_curchannel(hw, ah); | 1119 | init_channel = ath9k_cmn_get_curchannel(hw, ah); |
1120 | 1120 | ||
@@ -1127,7 +1127,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
1127 | ath_print(common, ATH_DBG_FATAL, | 1127 | ath_print(common, ATH_DBG_FATAL, |
1128 | "Unable to reset hardware; reset status %d " | 1128 | "Unable to reset hardware; reset status %d " |
1129 | "(freq %u MHz)\n", ret, curchan->center_freq); | 1129 | "(freq %u MHz)\n", ret, curchan->center_freq); |
1130 | goto mutex_unlock; | 1130 | return ret; |
1131 | } | 1131 | } |
1132 | 1132 | ||
1133 | ath_update_txpow(priv); | 1133 | ath_update_txpow(priv); |
@@ -1135,16 +1135,8 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
1135 | mode = ath9k_htc_get_curmode(priv, init_channel); | 1135 | mode = ath9k_htc_get_curmode(priv, init_channel); |
1136 | htc_mode = cpu_to_be16(mode); | 1136 | htc_mode = cpu_to_be16(mode); |
1137 | WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode); | 1137 | WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode); |
1138 | if (ret) | ||
1139 | goto mutex_unlock; | ||
1140 | |||
1141 | WMI_CMD(WMI_ATH_INIT_CMDID); | 1138 | WMI_CMD(WMI_ATH_INIT_CMDID); |
1142 | if (ret) | ||
1143 | goto mutex_unlock; | ||
1144 | |||
1145 | WMI_CMD(WMI_START_RECV_CMDID); | 1139 | WMI_CMD(WMI_START_RECV_CMDID); |
1146 | if (ret) | ||
1147 | goto mutex_unlock; | ||
1148 | 1140 | ||
1149 | ath9k_host_rx_init(priv); | 1141 | ath9k_host_rx_init(priv); |
1150 | 1142 | ||
@@ -1157,12 +1149,22 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
1157 | 1149 | ||
1158 | ieee80211_wake_queues(hw); | 1150 | ieee80211_wake_queues(hw); |
1159 | 1151 | ||
1160 | mutex_unlock: | 1152 | return ret; |
1153 | } | ||
1154 | |||
1155 | static int ath9k_htc_start(struct ieee80211_hw *hw) | ||
1156 | { | ||
1157 | struct ath9k_htc_priv *priv = hw->priv; | ||
1158 | int ret = 0; | ||
1159 | |||
1160 | mutex_lock(&priv->mutex); | ||
1161 | ret = ath9k_htc_radio_enable(hw); | ||
1161 | mutex_unlock(&priv->mutex); | 1162 | mutex_unlock(&priv->mutex); |
1163 | |||
1162 | return ret; | 1164 | return ret; |
1163 | } | 1165 | } |
1164 | 1166 | ||
1165 | static void ath9k_htc_stop(struct ieee80211_hw *hw) | 1167 | static void ath9k_htc_radio_disable(struct ieee80211_hw *hw) |
1166 | { | 1168 | { |
1167 | struct ath9k_htc_priv *priv = hw->priv; | 1169 | struct ath9k_htc_priv *priv = hw->priv; |
1168 | struct ath_hw *ah = priv->ah; | 1170 | struct ath_hw *ah = priv->ah; |
@@ -1170,14 +1172,18 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1170 | int ret = 0; | 1172 | int ret = 0; |
1171 | u8 cmd_rsp; | 1173 | u8 cmd_rsp; |
1172 | 1174 | ||
1173 | mutex_lock(&priv->mutex); | ||
1174 | |||
1175 | if (priv->op_flags & OP_INVALID) { | 1175 | if (priv->op_flags & OP_INVALID) { |
1176 | ath_print(common, ATH_DBG_ANY, "Device not present\n"); | 1176 | ath_print(common, ATH_DBG_ANY, "Device not present\n"); |
1177 | mutex_unlock(&priv->mutex); | ||
1178 | return; | 1177 | return; |
1179 | } | 1178 | } |
1180 | 1179 | ||
1180 | /* Cancel all the running timers/work .. */ | ||
1181 | cancel_work_sync(&priv->ps_work); | ||
1182 | cancel_delayed_work_sync(&priv->ath9k_ani_work); | ||
1183 | cancel_delayed_work_sync(&priv->ath9k_aggr_work); | ||
1184 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | ||
1185 | ath9k_led_stop_brightness(priv); | ||
1186 | |||
1181 | ath9k_htc_ps_wakeup(priv); | 1187 | ath9k_htc_ps_wakeup(priv); |
1182 | htc_stop(priv->htc); | 1188 | htc_stop(priv->htc); |
1183 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 1189 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
@@ -1189,11 +1195,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1189 | ath9k_htc_ps_restore(priv); | 1195 | ath9k_htc_ps_restore(priv); |
1190 | ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); | 1196 | ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); |
1191 | 1197 | ||
1192 | cancel_work_sync(&priv->ps_work); | ||
1193 | cancel_delayed_work_sync(&priv->ath9k_ani_work); | ||
1194 | cancel_delayed_work_sync(&priv->ath9k_aggr_work); | ||
1195 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | ||
1196 | ath9k_led_stop_brightness(priv); | ||
1197 | skb_queue_purge(&priv->tx_queue); | 1198 | skb_queue_purge(&priv->tx_queue); |
1198 | 1199 | ||
1199 | /* Remove monitor interface here */ | 1200 | /* Remove monitor interface here */ |
@@ -1207,11 +1208,20 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1207 | } | 1208 | } |
1208 | 1209 | ||
1209 | priv->op_flags |= OP_INVALID; | 1210 | priv->op_flags |= OP_INVALID; |
1210 | mutex_unlock(&priv->mutex); | ||
1211 | 1211 | ||
1212 | ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); | 1212 | ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); |
1213 | } | 1213 | } |
1214 | 1214 | ||
1215 | static void ath9k_htc_stop(struct ieee80211_hw *hw) | ||
1216 | { | ||
1217 | struct ath9k_htc_priv *priv = hw->priv; | ||
1218 | |||
1219 | mutex_lock(&priv->mutex); | ||
1220 | ath9k_htc_radio_disable(hw); | ||
1221 | mutex_unlock(&priv->mutex); | ||
1222 | } | ||
1223 | |||
1224 | |||
1215 | static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | 1225 | static int ath9k_htc_add_interface(struct ieee80211_hw *hw, |
1216 | struct ieee80211_vif *vif) | 1226 | struct ieee80211_vif *vif) |
1217 | { | 1227 | { |
@@ -1325,6 +1335,23 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | |||
1325 | 1335 | ||
1326 | mutex_lock(&priv->mutex); | 1336 | mutex_lock(&priv->mutex); |
1327 | 1337 | ||
1338 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { | ||
1339 | bool enable_radio = false; | ||
1340 | bool idle = !!(conf->flags & IEEE80211_CONF_IDLE); | ||
1341 | |||
1342 | if (!idle && priv->ps_idle) | ||
1343 | enable_radio = true; | ||
1344 | |||
1345 | priv->ps_idle = idle; | ||
1346 | |||
1347 | if (enable_radio) { | ||
1348 | ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); | ||
1349 | ath9k_htc_radio_enable(hw); | ||
1350 | ath_print(common, ATH_DBG_CONFIG, | ||
1351 | "not-idle: enabling radio\n"); | ||
1352 | } | ||
1353 | } | ||
1354 | |||
1328 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 1355 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
1329 | struct ieee80211_channel *curchan = hw->conf.channel; | 1356 | struct ieee80211_channel *curchan = hw->conf.channel; |
1330 | int pos = curchan->hw_value; | 1357 | int pos = curchan->hw_value; |
@@ -1368,6 +1395,13 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | |||
1368 | } | 1395 | } |
1369 | } | 1396 | } |
1370 | 1397 | ||
1398 | if (priv->ps_idle) { | ||
1399 | ath_print(common, ATH_DBG_CONFIG, | ||
1400 | "idle: disabling radio\n"); | ||
1401 | ath9k_htc_radio_disable(hw); | ||
1402 | } | ||
1403 | |||
1404 | |||
1371 | mutex_unlock(&priv->mutex); | 1405 | mutex_unlock(&priv->mutex); |
1372 | 1406 | ||
1373 | return 0; | 1407 | return 0; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 2c3c51007dd3..28abc7d5e909 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -244,16 +244,25 @@ void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, | |||
244 | enum htc_endpoint_id ep_id, bool txok) | 244 | enum htc_endpoint_id ep_id, bool txok) |
245 | { | 245 | { |
246 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; | 246 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; |
247 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
247 | struct ieee80211_tx_info *tx_info; | 248 | struct ieee80211_tx_info *tx_info; |
248 | 249 | ||
249 | if (!skb) | 250 | if (!skb) |
250 | return; | 251 | return; |
251 | 252 | ||
252 | if (ep_id == priv->mgmt_ep) | 253 | if (ep_id == priv->mgmt_ep) { |
253 | skb_pull(skb, sizeof(struct tx_mgmt_hdr)); | 254 | skb_pull(skb, sizeof(struct tx_mgmt_hdr)); |
254 | else | 255 | } else if ((ep_id == priv->data_bk_ep) || |
255 | /* TODO: Check for cab/uapsd/data */ | 256 | (ep_id == priv->data_be_ep) || |
257 | (ep_id == priv->data_vi_ep) || | ||
258 | (ep_id == priv->data_vo_ep)) { | ||
256 | skb_pull(skb, sizeof(struct tx_frame_hdr)); | 259 | skb_pull(skb, sizeof(struct tx_frame_hdr)); |
260 | } else { | ||
261 | ath_print(common, ATH_DBG_FATAL, | ||
262 | "Unsupported TX EPID: %d\n", ep_id); | ||
263 | dev_kfree_skb_any(skb); | ||
264 | return; | ||
265 | } | ||
257 | 266 | ||
258 | tx_info = IEEE80211_SKB_CB(skb); | 267 | tx_info = IEEE80211_SKB_CB(skb); |
259 | 268 | ||
@@ -439,10 +448,32 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
439 | struct ieee80211_hw *hw = priv->hw; | 448 | struct ieee80211_hw *hw = priv->hw; |
440 | struct sk_buff *skb = rxbuf->skb; | 449 | struct sk_buff *skb = rxbuf->skb; |
441 | struct ath_common *common = ath9k_hw_common(priv->ah); | 450 | struct ath_common *common = ath9k_hw_common(priv->ah); |
451 | struct ath_htc_rx_status *rxstatus; | ||
442 | int hdrlen, padpos, padsize; | 452 | int hdrlen, padpos, padsize; |
443 | int last_rssi = ATH_RSSI_DUMMY_MARKER; | 453 | int last_rssi = ATH_RSSI_DUMMY_MARKER; |
444 | __le16 fc; | 454 | __le16 fc; |
445 | 455 | ||
456 | if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) { | ||
457 | ath_print(common, ATH_DBG_FATAL, | ||
458 | "Corrupted RX frame, dropping\n"); | ||
459 | goto rx_next; | ||
460 | } | ||
461 | |||
462 | rxstatus = (struct ath_htc_rx_status *)skb->data; | ||
463 | |||
464 | if (be16_to_cpu(rxstatus->rs_datalen) - | ||
465 | (skb->len - HTC_RX_FRAME_HEADER_SIZE) != 0) { | ||
466 | ath_print(common, ATH_DBG_FATAL, | ||
467 | "Corrupted RX data len, dropping " | ||
468 | "(dlen: %d, skblen: %d)\n", | ||
469 | rxstatus->rs_datalen, skb->len); | ||
470 | goto rx_next; | ||
471 | } | ||
472 | |||
473 | /* Get the RX status information */ | ||
474 | memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); | ||
475 | skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); | ||
476 | |||
446 | hdr = (struct ieee80211_hdr *)skb->data; | 477 | hdr = (struct ieee80211_hdr *)skb->data; |
447 | fc = hdr->frame_control; | 478 | fc = hdr->frame_control; |
448 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 479 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
@@ -607,8 +638,6 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb, | |||
607 | struct ath_hw *ah = priv->ah; | 638 | struct ath_hw *ah = priv->ah; |
608 | struct ath_common *common = ath9k_hw_common(ah); | 639 | struct ath_common *common = ath9k_hw_common(ah); |
609 | struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL; | 640 | struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL; |
610 | struct ath_htc_rx_status *rxstatus; | ||
611 | u32 len = 0; | ||
612 | 641 | ||
613 | spin_lock(&priv->rx.rxbuflock); | 642 | spin_lock(&priv->rx.rxbuflock); |
614 | list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) { | 643 | list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) { |
@@ -625,27 +654,7 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb, | |||
625 | goto err; | 654 | goto err; |
626 | } | 655 | } |
627 | 656 | ||
628 | len = skb->len; | ||
629 | if (len <= HTC_RX_FRAME_HEADER_SIZE) { | ||
630 | ath_print(common, ATH_DBG_FATAL, | ||
631 | "Corrupted RX frame, dropping\n"); | ||
632 | goto err; | ||
633 | } | ||
634 | |||
635 | rxstatus = (struct ath_htc_rx_status *)skb->data; | ||
636 | |||
637 | if (be16_to_cpu(rxstatus->rs_datalen) - | ||
638 | (len - HTC_RX_FRAME_HEADER_SIZE) != 0) { | ||
639 | ath_print(common, ATH_DBG_FATAL, | ||
640 | "Corrupted RX data len, dropping " | ||
641 | "(epid: %d, dlen: %d, skblen: %d)\n", | ||
642 | ep_id, rxstatus->rs_datalen, len); | ||
643 | goto err; | ||
644 | } | ||
645 | |||
646 | spin_lock(&priv->rx.rxbuflock); | 657 | spin_lock(&priv->rx.rxbuflock); |
647 | memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); | ||
648 | skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); | ||
649 | rxbuf->skb = skb; | 658 | rxbuf->skb = skb; |
650 | rxbuf->in_process = true; | 659 | rxbuf->in_process = true; |
651 | spin_unlock(&priv->rx.rxbuflock); | 660 | spin_unlock(&priv->rx.rxbuflock); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index f2dca258bdc2..7bf6ce1e7e2e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c | |||
@@ -341,8 +341,9 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, | |||
341 | skb_pull(skb, sizeof(struct htc_frame_hdr)); | 341 | skb_pull(skb, sizeof(struct htc_frame_hdr)); |
342 | 342 | ||
343 | if (endpoint->ep_callbacks.tx) { | 343 | if (endpoint->ep_callbacks.tx) { |
344 | endpoint->ep_callbacks.tx(htc_handle->drv_priv, skb, | 344 | endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv, |
345 | htc_hdr->endpoint_id, txok); | 345 | skb, htc_hdr->endpoint_id, |
346 | txok); | ||
346 | } | 347 | } |
347 | } | 348 | } |
348 | 349 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 5a29048db3b1..559019262d30 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #define ATH9K_CLOCK_RATE_CCK 22 | 26 | #define ATH9K_CLOCK_RATE_CCK 22 |
27 | #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 | 27 | #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 |
28 | #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 | 28 | #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 |
29 | #define ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM 44 | ||
29 | 30 | ||
30 | static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); | 31 | static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); |
31 | 32 | ||
@@ -91,7 +92,11 @@ static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) | |||
91 | return usecs *ATH9K_CLOCK_RATE_CCK; | 92 | return usecs *ATH9K_CLOCK_RATE_CCK; |
92 | if (conf->channel->band == IEEE80211_BAND_2GHZ) | 93 | if (conf->channel->band == IEEE80211_BAND_2GHZ) |
93 | return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM; | 94 | return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM; |
94 | return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM; | 95 | |
96 | if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK) | ||
97 | return usecs * ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; | ||
98 | else | ||
99 | return usecs * ATH9K_CLOCK_RATE_5GHZ_OFDM; | ||
95 | } | 100 | } |
96 | 101 | ||
97 | static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) | 102 | static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) |
@@ -387,6 +392,12 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
387 | ah->config.rx_intr_mitigation = true; | 392 | ah->config.rx_intr_mitigation = true; |
388 | 393 | ||
389 | /* | 394 | /* |
395 | * Tx IQ Calibration (ah->config.tx_iq_calibration) is only | ||
396 | * used by AR9003, but it is showing reliability issues. | ||
397 | * It will take a while to fix so this is currently disabled. | ||
398 | */ | ||
399 | |||
400 | /* | ||
390 | * We need this for PCI devices only (Cardbus, PCI, miniPCI) | 401 | * We need this for PCI devices only (Cardbus, PCI, miniPCI) |
391 | * _and_ if on non-uniprocessor systems (Multiprocessor/HT). | 402 | * _and_ if on non-uniprocessor systems (Multiprocessor/HT). |
392 | * This means we use it for all AR5416 devices, and the few | 403 | * This means we use it for all AR5416 devices, and the few |
@@ -819,9 +830,6 @@ void ath9k_hw_deinit(struct ath_hw *ah) | |||
819 | if (common->state < ATH_HW_INITIALIZED) | 830 | if (common->state < ATH_HW_INITIALIZED) |
820 | goto free_hw; | 831 | goto free_hw; |
821 | 832 | ||
822 | if (!AR_SREV_9100(ah)) | ||
823 | ath9k_hw_ani_disable(ah); | ||
824 | |||
825 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); | 833 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); |
826 | 834 | ||
827 | free_hw: | 835 | free_hw: |
@@ -1221,8 +1229,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1221 | (chan->channel != ah->curchan->channel) && | 1229 | (chan->channel != ah->curchan->channel) && |
1222 | ((chan->channelFlags & CHANNEL_ALL) == | 1230 | ((chan->channelFlags & CHANNEL_ALL) == |
1223 | (ah->curchan->channelFlags & CHANNEL_ALL)) && | 1231 | (ah->curchan->channelFlags & CHANNEL_ALL)) && |
1224 | !(AR_SREV_9280(ah) || IS_CHAN_A_5MHZ_SPACED(chan) || | 1232 | !AR_SREV_9280(ah)) { |
1225 | IS_CHAN_A_5MHZ_SPACED(ah->curchan))) { | ||
1226 | 1233 | ||
1227 | if (ath9k_hw_channel_change(ah, chan)) { | 1234 | if (ath9k_hw_channel_change(ah, chan)) { |
1228 | ath9k_hw_loadnf(ah, ah->curchan); | 1235 | ath9k_hw_loadnf(ah, ah->curchan); |
@@ -2186,7 +2193,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2186 | } | 2193 | } |
2187 | 2194 | ||
2188 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 2195 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
2189 | pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_LDPC; | 2196 | pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_LDPC | |
2197 | ATH9K_HW_CAP_FASTCLOCK; | ||
2190 | pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH; | 2198 | pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH; |
2191 | pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH; | 2199 | pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH; |
2192 | pCap->rx_status_len = sizeof(struct ar9003_rxs); | 2200 | pCap->rx_status_len = sizeof(struct ar9003_rxs); |
@@ -2194,6 +2202,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2194 | pCap->txs_len = sizeof(struct ar9003_txs); | 2202 | pCap->txs_len = sizeof(struct ar9003_txs); |
2195 | } else { | 2203 | } else { |
2196 | pCap->tx_desc_len = sizeof(struct ath_desc); | 2204 | pCap->tx_desc_len = sizeof(struct ath_desc); |
2205 | if (AR_SREV_9280_20(ah) && | ||
2206 | ((ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) <= | ||
2207 | AR5416_EEP_MINOR_VER_16) || | ||
2208 | ah->eep_ops->get_eeprom(ah, EEP_FSTCLK_5G))) | ||
2209 | pCap->hw_caps |= ATH9K_HW_CAP_FASTCLOCK; | ||
2197 | } | 2210 | } |
2198 | 2211 | ||
2199 | if (AR_SREV_9300_20_OR_LATER(ah)) | 2212 | if (AR_SREV_9300_20_OR_LATER(ah)) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index a78e09bab431..77245dff5993 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -198,6 +198,7 @@ enum ath9k_hw_caps { | |||
198 | ATH9K_HW_CAP_EDMA = BIT(17), | 198 | ATH9K_HW_CAP_EDMA = BIT(17), |
199 | ATH9K_HW_CAP_RAC_SUPPORTED = BIT(18), | 199 | ATH9K_HW_CAP_RAC_SUPPORTED = BIT(18), |
200 | ATH9K_HW_CAP_LDPC = BIT(19), | 200 | ATH9K_HW_CAP_LDPC = BIT(19), |
201 | ATH9K_HW_CAP_FASTCLOCK = BIT(20), | ||
201 | }; | 202 | }; |
202 | 203 | ||
203 | enum ath9k_capability_type { | 204 | enum ath9k_capability_type { |
@@ -261,6 +262,7 @@ struct ath9k_ops_config { | |||
261 | #define AR_BASE_FREQ_5GHZ 4900 | 262 | #define AR_BASE_FREQ_5GHZ 4900 |
262 | #define AR_SPUR_FEEQ_BOUND_HT40 19 | 263 | #define AR_SPUR_FEEQ_BOUND_HT40 19 |
263 | #define AR_SPUR_FEEQ_BOUND_HT20 10 | 264 | #define AR_SPUR_FEEQ_BOUND_HT20 10 |
265 | bool tx_iq_calibration; /* Only available for >= AR9003 */ | ||
264 | int spurmode; | 266 | int spurmode; |
265 | u16 spurchans[AR_EEPROM_MODAL_SPURS][2]; | 267 | u16 spurchans[AR_EEPROM_MODAL_SPURS][2]; |
266 | u8 max_txtrig_level; | 268 | u8 max_txtrig_level; |
@@ -367,10 +369,9 @@ struct ath9k_channel { | |||
367 | #define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0) | 369 | #define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0) |
368 | #define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0) | 370 | #define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0) |
369 | #define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0) | 371 | #define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0) |
370 | #define IS_CHAN_A_5MHZ_SPACED(_c) \ | 372 | #define IS_CHAN_A_FAST_CLOCK(_ah, _c) \ |
371 | ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \ | 373 | ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \ |
372 | (((_c)->channel % 20) != 0) && \ | 374 | ((_ah)->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)) |
373 | (((_c)->channel % 10) != 0)) | ||
374 | 375 | ||
375 | /* These macros check chanmode and not channelFlags */ | 376 | /* These macros check chanmode and not channelFlags */ |
376 | #define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B) | 377 | #define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B) |
@@ -718,6 +719,7 @@ struct ath_hw { | |||
718 | u32 *addac5416_21; | 719 | u32 *addac5416_21; |
719 | u32 *bank6Temp; | 720 | u32 *bank6Temp; |
720 | 721 | ||
722 | u8 txpower_limit; | ||
721 | int16_t txpower_indexoffset; | 723 | int16_t txpower_indexoffset; |
722 | int coverage_class; | 724 | int coverage_class; |
723 | u32 beacon_interval; | 725 | u32 beacon_interval; |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 7bbf502563bc..0e425cb4bbb1 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -878,10 +878,12 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, | |||
878 | if (ints & ATH9K_INT_TX) { | 878 | if (ints & ATH9K_INT_TX) { |
879 | if (ah->config.tx_intr_mitigation) | 879 | if (ah->config.tx_intr_mitigation) |
880 | mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM; | 880 | mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM; |
881 | if (ah->txok_interrupt_mask) | 881 | else { |
882 | mask |= AR_IMR_TXOK; | 882 | if (ah->txok_interrupt_mask) |
883 | if (ah->txdesc_interrupt_mask) | 883 | mask |= AR_IMR_TXOK; |
884 | mask |= AR_IMR_TXDESC; | 884 | if (ah->txdesc_interrupt_mask) |
885 | mask |= AR_IMR_TXDESC; | ||
886 | } | ||
885 | if (ah->txerr_interrupt_mask) | 887 | if (ah->txerr_interrupt_mask) |
886 | mask |= AR_IMR_TXERR; | 888 | mask |= AR_IMR_TXERR; |
887 | if (ah->txeol_interrupt_mask) | 889 | if (ah->txeol_interrupt_mask) |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index aad370a7f95b..893b552981a0 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -2044,6 +2044,25 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
2044 | return ret; | 2044 | return ret; |
2045 | } | 2045 | } |
2046 | 2046 | ||
2047 | static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, | ||
2048 | struct survey_info *survey) | ||
2049 | { | ||
2050 | struct ath_wiphy *aphy = hw->priv; | ||
2051 | struct ath_softc *sc = aphy->sc; | ||
2052 | struct ath_hw *ah = sc->sc_ah; | ||
2053 | struct ath_common *common = ath9k_hw_common(ah); | ||
2054 | struct ieee80211_conf *conf = &hw->conf; | ||
2055 | |||
2056 | if (idx != 0) | ||
2057 | return -ENOENT; | ||
2058 | |||
2059 | survey->channel = conf->channel; | ||
2060 | survey->filled = SURVEY_INFO_NOISE_DBM; | ||
2061 | survey->noise = common->ani.noise_floor; | ||
2062 | |||
2063 | return 0; | ||
2064 | } | ||
2065 | |||
2047 | static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | 2066 | static void ath9k_sw_scan_start(struct ieee80211_hw *hw) |
2048 | { | 2067 | { |
2049 | struct ath_wiphy *aphy = hw->priv; | 2068 | struct ath_wiphy *aphy = hw->priv; |
@@ -2115,6 +2134,7 @@ struct ieee80211_ops ath9k_ops = { | |||
2115 | .set_tsf = ath9k_set_tsf, | 2134 | .set_tsf = ath9k_set_tsf, |
2116 | .reset_tsf = ath9k_reset_tsf, | 2135 | .reset_tsf = ath9k_reset_tsf, |
2117 | .ampdu_action = ath9k_ampdu_action, | 2136 | .ampdu_action = ath9k_ampdu_action, |
2137 | .get_survey = ath9k_get_survey, | ||
2118 | .sw_scan_start = ath9k_sw_scan_start, | 2138 | .sw_scan_start = ath9k_sw_scan_start, |
2119 | .sw_scan_complete = ath9k_sw_scan_complete, | 2139 | .sw_scan_complete = ath9k_sw_scan_complete, |
2120 | .rfkill_poll = ath9k_rfkill_poll_state, | 2140 | .rfkill_poll = ath9k_rfkill_poll_state, |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index dc6c6fc2e095..e23172c9caaf 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c | |||
@@ -276,6 +276,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | |||
276 | int time_left, ret = 0; | 276 | int time_left, ret = 0; |
277 | unsigned long flags; | 277 | unsigned long flags; |
278 | 278 | ||
279 | if (wmi->drv_priv->op_flags & OP_UNPLUGGED) | ||
280 | return 0; | ||
281 | |||
279 | if (!wmi) | 282 | if (!wmi) |
280 | return -EINVAL; | 283 | return -EINVAL; |
281 | 284 | ||
@@ -302,14 +305,14 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | |||
302 | wmi->cmd_rsp_buf = rsp_buf; | 305 | wmi->cmd_rsp_buf = rsp_buf; |
303 | wmi->cmd_rsp_len = rsp_len; | 306 | wmi->cmd_rsp_len = rsp_len; |
304 | 307 | ||
305 | ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len); | ||
306 | if (ret) | ||
307 | goto out; | ||
308 | |||
309 | spin_lock_irqsave(&wmi->wmi_lock, flags); | 308 | spin_lock_irqsave(&wmi->wmi_lock, flags); |
310 | wmi->last_cmd_id = cmd_id; | 309 | wmi->last_cmd_id = cmd_id; |
311 | spin_unlock_irqrestore(&wmi->wmi_lock, flags); | 310 | spin_unlock_irqrestore(&wmi->wmi_lock, flags); |
312 | 311 | ||
312 | ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len); | ||
313 | if (ret) | ||
314 | goto out; | ||
315 | |||
313 | time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout); | 316 | time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout); |
314 | if (!time_left) { | 317 | if (!time_left) { |
315 | ath_print(common, ATH_DBG_WMI, | 318 | ath_print(common, ATH_DBG_WMI, |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 167e15c50062..765db5faa2d3 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h | |||
@@ -126,14 +126,14 @@ void ath9k_wmi_tasklet(unsigned long data); | |||
126 | do { \ | 126 | do { \ |
127 | ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0, \ | 127 | ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0, \ |
128 | (u8 *) &cmd_rsp, \ | 128 | (u8 *) &cmd_rsp, \ |
129 | sizeof(cmd_rsp), HZ); \ | 129 | sizeof(cmd_rsp), HZ*2); \ |
130 | } while (0) | 130 | } while (0) |
131 | 131 | ||
132 | #define WMI_CMD_BUF(_wmi_cmd, _buf) \ | 132 | #define WMI_CMD_BUF(_wmi_cmd, _buf) \ |
133 | do { \ | 133 | do { \ |
134 | ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, \ | 134 | ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, \ |
135 | (u8 *) _buf, sizeof(*_buf), \ | 135 | (u8 *) _buf, sizeof(*_buf), \ |
136 | &cmd_rsp, sizeof(cmd_rsp), HZ); \ | 136 | &cmd_rsp, sizeof(cmd_rsp), HZ*2); \ |
137 | } while (0) | 137 | } while (0) |
138 | 138 | ||
139 | #endif /* WMI_H */ | 139 | #endif /* WMI_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index b0d345a675fe..3db19172b43b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2290,6 +2290,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2290 | ath_tx_complete_buf(sc, bf, txq, &bf_head, | 2290 | ath_tx_complete_buf(sc, bf, txq, &bf_head, |
2291 | &txs, txok, 0); | 2291 | &txs, txok, 0); |
2292 | 2292 | ||
2293 | ath_wake_mac80211_queue(sc, txq); | ||
2294 | |||
2293 | spin_lock_bh(&txq->axq_lock); | 2295 | spin_lock_bh(&txq->axq_lock); |
2294 | if (!list_empty(&txq->txq_fifo_pending)) { | 2296 | if (!list_empty(&txq->txq_fifo_pending)) { |
2295 | INIT_LIST_HEAD(&bf_head); | 2297 | INIT_LIST_HEAD(&bf_head); |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 997303bcf4ae..7965b70efbab 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -4571,6 +4571,23 @@ static void b43_op_sw_scan_complete_notifier(struct ieee80211_hw *hw) | |||
4571 | mutex_unlock(&wl->mutex); | 4571 | mutex_unlock(&wl->mutex); |
4572 | } | 4572 | } |
4573 | 4573 | ||
4574 | static int b43_op_get_survey(struct ieee80211_hw *hw, int idx, | ||
4575 | struct survey_info *survey) | ||
4576 | { | ||
4577 | struct b43_wl *wl = hw_to_b43_wl(hw); | ||
4578 | struct b43_wldev *dev = wl->current_dev; | ||
4579 | struct ieee80211_conf *conf = &hw->conf; | ||
4580 | |||
4581 | if (idx != 0) | ||
4582 | return -ENOENT; | ||
4583 | |||
4584 | survey->channel = conf->channel; | ||
4585 | survey->filled = SURVEY_INFO_NOISE_DBM; | ||
4586 | survey->noise = dev->stats.link_noise; | ||
4587 | |||
4588 | return 0; | ||
4589 | } | ||
4590 | |||
4574 | static const struct ieee80211_ops b43_hw_ops = { | 4591 | static const struct ieee80211_ops b43_hw_ops = { |
4575 | .tx = b43_op_tx, | 4592 | .tx = b43_op_tx, |
4576 | .conf_tx = b43_op_conf_tx, | 4593 | .conf_tx = b43_op_conf_tx, |
@@ -4590,6 +4607,7 @@ static const struct ieee80211_ops b43_hw_ops = { | |||
4590 | .sta_notify = b43_op_sta_notify, | 4607 | .sta_notify = b43_op_sta_notify, |
4591 | .sw_scan_start = b43_op_sw_scan_start_notifier, | 4608 | .sw_scan_start = b43_op_sw_scan_start_notifier, |
4592 | .sw_scan_complete = b43_op_sw_scan_complete_notifier, | 4609 | .sw_scan_complete = b43_op_sw_scan_complete_notifier, |
4610 | .get_survey = b43_op_get_survey, | ||
4593 | .rfkill_poll = b43_rfkill_poll, | 4611 | .rfkill_poll = b43_rfkill_poll, |
4594 | }; | 4612 | }; |
4595 | 4613 | ||
@@ -4905,8 +4923,7 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4905 | 4923 | ||
4906 | /* fill hw info */ | 4924 | /* fill hw info */ |
4907 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 4925 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
4908 | IEEE80211_HW_SIGNAL_DBM | | 4926 | IEEE80211_HW_SIGNAL_DBM; |
4909 | IEEE80211_HW_NOISE_DBM; | ||
4910 | 4927 | ||
4911 | hw->wiphy->interface_modes = | 4928 | hw->wiphy->interface_modes = |
4912 | BIT(NL80211_IFTYPE_AP) | | 4929 | BIT(NL80211_IFTYPE_AP) | |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index eda06529ef5f..e6b0528f3b52 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -610,7 +610,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
610 | } | 610 | } |
611 | 611 | ||
612 | /* Link quality statistics */ | 612 | /* Link quality statistics */ |
613 | status.noise = dev->stats.link_noise; | ||
614 | if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) { | 613 | if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) { |
615 | // s8 rssi = max(rxhdr->power0, rxhdr->power1); | 614 | // s8 rssi = max(rxhdr->power0, rxhdr->power1); |
616 | //TODO: Find out what the rssi value is (dBm or percentage?) | 615 | //TODO: Find out what the rssi value is (dBm or percentage?) |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index bb2dd9329aa0..1713f5f7a58b 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -3482,6 +3482,23 @@ static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw, | |||
3482 | return 0; | 3482 | return 0; |
3483 | } | 3483 | } |
3484 | 3484 | ||
3485 | static int b43legacy_op_get_survey(struct ieee80211_hw *hw, int idx, | ||
3486 | struct survey_info *survey) | ||
3487 | { | ||
3488 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); | ||
3489 | struct b43legacy_wldev *dev = wl->current_dev; | ||
3490 | struct ieee80211_conf *conf = &hw->conf; | ||
3491 | |||
3492 | if (idx != 0) | ||
3493 | return -ENOENT; | ||
3494 | |||
3495 | survey->channel = conf->channel; | ||
3496 | survey->filled = SURVEY_INFO_NOISE_DBM; | ||
3497 | survey->noise = dev->stats.link_noise; | ||
3498 | |||
3499 | return 0; | ||
3500 | } | ||
3501 | |||
3485 | static const struct ieee80211_ops b43legacy_hw_ops = { | 3502 | static const struct ieee80211_ops b43legacy_hw_ops = { |
3486 | .tx = b43legacy_op_tx, | 3503 | .tx = b43legacy_op_tx, |
3487 | .conf_tx = b43legacy_op_conf_tx, | 3504 | .conf_tx = b43legacy_op_conf_tx, |
@@ -3494,6 +3511,7 @@ static const struct ieee80211_ops b43legacy_hw_ops = { | |||
3494 | .start = b43legacy_op_start, | 3511 | .start = b43legacy_op_start, |
3495 | .stop = b43legacy_op_stop, | 3512 | .stop = b43legacy_op_stop, |
3496 | .set_tim = b43legacy_op_beacon_set_tim, | 3513 | .set_tim = b43legacy_op_beacon_set_tim, |
3514 | .get_survey = b43legacy_op_get_survey, | ||
3497 | .rfkill_poll = b43legacy_rfkill_poll, | 3515 | .rfkill_poll = b43legacy_rfkill_poll, |
3498 | }; | 3516 | }; |
3499 | 3517 | ||
@@ -3769,8 +3787,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev) | |||
3769 | 3787 | ||
3770 | /* fill hw info */ | 3788 | /* fill hw info */ |
3771 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 3789 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
3772 | IEEE80211_HW_SIGNAL_DBM | | 3790 | IEEE80211_HW_SIGNAL_DBM; |
3773 | IEEE80211_HW_NOISE_DBM; | ||
3774 | hw->wiphy->interface_modes = | 3791 | hw->wiphy->interface_modes = |
3775 | BIT(NL80211_IFTYPE_AP) | | 3792 | BIT(NL80211_IFTYPE_AP) | |
3776 | BIT(NL80211_IFTYPE_STATION) | | 3793 | BIT(NL80211_IFTYPE_STATION) | |
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index 9c8882d9275e..7d177d97f1f7 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -548,7 +548,6 @@ void b43legacy_rx(struct b43legacy_wldev *dev, | |||
548 | (phystat0 & B43legacy_RX_PHYST0_OFDM), | 548 | (phystat0 & B43legacy_RX_PHYST0_OFDM), |
549 | (phystat0 & B43legacy_RX_PHYST0_GAINCTL), | 549 | (phystat0 & B43legacy_RX_PHYST0_GAINCTL), |
550 | (phystat3 & B43legacy_RX_PHYST3_TRSTATE)); | 550 | (phystat3 & B43legacy_RX_PHYST3_TRSTATE)); |
551 | status.noise = dev->stats.link_noise; | ||
552 | /* change to support A PHY */ | 551 | /* change to support A PHY */ |
553 | if (phystat0 & B43legacy_RX_PHYST0_OFDM) | 552 | if (phystat0 & B43legacy_RX_PHYST0_OFDM) |
554 | status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false); | 553 | status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false); |
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 5ed2dcbe6d01..7c7235385513 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -22,5 +22,6 @@ iwlagn-$(CONFIG_IWL5000) += iwl-1000.o | |||
22 | # 3945 | 22 | # 3945 |
23 | obj-$(CONFIG_IWL3945) += iwl3945.o | 23 | obj-$(CONFIG_IWL3945) += iwl3945.o |
24 | iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o | 24 | iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o |
25 | iwl3945-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-3945-debugfs.o | ||
25 | 26 | ||
26 | ccflags-y += -D__CHECK_ENDIAN__ | 27 | ccflags-y += -D__CHECK_ENDIAN__ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 8431ffce37d3..fb59af2d41c6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -282,7 +282,6 @@ struct iwl_cfg iwl1000_bg_cfg = { | |||
282 | .use_bsm = false, | 282 | .use_bsm = false, |
283 | .max_ll_items = OTP_MAX_LL_ITEMS_1000, | 283 | .max_ll_items = OTP_MAX_LL_ITEMS_1000, |
284 | .shadow_ram_support = false, | 284 | .shadow_ram_support = false, |
285 | .ht_greenfield_support = true, | ||
286 | .led_compensation = 51, | 285 | .led_compensation = 51, |
287 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 286 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
288 | .support_ct_kill_exit = true, | 287 | .support_ct_kill_exit = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c new file mode 100644 index 000000000000..6a9c64a50e36 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c | |||
@@ -0,0 +1,500 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * GPL LICENSE SUMMARY | ||
4 | * | ||
5 | * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of version 2 of the GNU General Public License as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
19 | * USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution | ||
22 | * in the file called LICENSE.GPL. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | *****************************************************************************/ | ||
28 | |||
29 | #include "iwl-3945-debugfs.h" | ||
30 | |||
31 | ssize_t iwl3945_ucode_rx_stats_read(struct file *file, | ||
32 | char __user *user_buf, | ||
33 | size_t count, loff_t *ppos) | ||
34 | { | ||
35 | struct iwl_priv *priv = file->private_data; | ||
36 | int pos = 0; | ||
37 | char *buf; | ||
38 | int bufsz = sizeof(struct iwl39_statistics_rx_phy) * 40 + | ||
39 | sizeof(struct iwl39_statistics_rx_non_phy) * 40 + 400; | ||
40 | ssize_t ret; | ||
41 | struct iwl39_statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm; | ||
42 | struct iwl39_statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck; | ||
43 | struct iwl39_statistics_rx_non_phy *general, *accum_general; | ||
44 | struct iwl39_statistics_rx_non_phy *delta_general, *max_general; | ||
45 | |||
46 | if (!iwl_is_alive(priv)) | ||
47 | return -EAGAIN; | ||
48 | |||
49 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
50 | if (!buf) { | ||
51 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
52 | return -ENOMEM; | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | * The statistic information display here is based on | ||
57 | * the last statistics notification from uCode | ||
58 | * might not reflect the current uCode activity | ||
59 | */ | ||
60 | ofdm = &priv->_3945.statistics.rx.ofdm; | ||
61 | cck = &priv->_3945.statistics.rx.cck; | ||
62 | general = &priv->_3945.statistics.rx.general; | ||
63 | accum_ofdm = &priv->_3945.accum_statistics.rx.ofdm; | ||
64 | accum_cck = &priv->_3945.accum_statistics.rx.cck; | ||
65 | accum_general = &priv->_3945.accum_statistics.rx.general; | ||
66 | delta_ofdm = &priv->_3945.delta_statistics.rx.ofdm; | ||
67 | delta_cck = &priv->_3945.delta_statistics.rx.cck; | ||
68 | delta_general = &priv->_3945.delta_statistics.rx.general; | ||
69 | max_ofdm = &priv->_3945.max_delta.rx.ofdm; | ||
70 | max_cck = &priv->_3945.max_delta.rx.cck; | ||
71 | max_general = &priv->_3945.max_delta.rx.general; | ||
72 | |||
73 | pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); | ||
74 | pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" | ||
75 | "acumulative delta max\n", | ||
76 | "Statistics_Rx - OFDM:"); | ||
77 | pos += scnprintf(buf + pos, bufsz - pos, | ||
78 | " %-30s %10u %10u %10u %10u\n", | ||
79 | "ina_cnt:", le32_to_cpu(ofdm->ina_cnt), | ||
80 | accum_ofdm->ina_cnt, | ||
81 | delta_ofdm->ina_cnt, max_ofdm->ina_cnt); | ||
82 | pos += scnprintf(buf + pos, bufsz - pos, | ||
83 | " %-30s %10u %10u %10u %10u\n", | ||
84 | "fina_cnt:", | ||
85 | le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt, | ||
86 | delta_ofdm->fina_cnt, max_ofdm->fina_cnt); | ||
87 | pos += scnprintf(buf + pos, bufsz - pos, | ||
88 | " %-30s %10u %10u %10u %10u\n", "plcp_err:", | ||
89 | le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err, | ||
90 | delta_ofdm->plcp_err, max_ofdm->plcp_err); | ||
91 | pos += scnprintf(buf + pos, bufsz - pos, | ||
92 | " %-30s %10u %10u %10u %10u\n", "crc32_err:", | ||
93 | le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err, | ||
94 | delta_ofdm->crc32_err, max_ofdm->crc32_err); | ||
95 | pos += scnprintf(buf + pos, bufsz - pos, | ||
96 | " %-30s %10u %10u %10u %10u\n", "overrun_err:", | ||
97 | le32_to_cpu(ofdm->overrun_err), | ||
98 | accum_ofdm->overrun_err, delta_ofdm->overrun_err, | ||
99 | max_ofdm->overrun_err); | ||
100 | pos += scnprintf(buf + pos, bufsz - pos, | ||
101 | " %-30s %10u %10u %10u %10u\n", | ||
102 | "early_overrun_err:", | ||
103 | le32_to_cpu(ofdm->early_overrun_err), | ||
104 | accum_ofdm->early_overrun_err, | ||
105 | delta_ofdm->early_overrun_err, | ||
106 | max_ofdm->early_overrun_err); | ||
107 | pos += scnprintf(buf + pos, bufsz - pos, | ||
108 | " %-30s %10u %10u %10u %10u\n", | ||
109 | "crc32_good:", le32_to_cpu(ofdm->crc32_good), | ||
110 | accum_ofdm->crc32_good, delta_ofdm->crc32_good, | ||
111 | max_ofdm->crc32_good); | ||
112 | pos += scnprintf(buf + pos, bufsz - pos, | ||
113 | " %-30s %10u %10u %10u %10u\n", "false_alarm_cnt:", | ||
114 | le32_to_cpu(ofdm->false_alarm_cnt), | ||
115 | accum_ofdm->false_alarm_cnt, | ||
116 | delta_ofdm->false_alarm_cnt, | ||
117 | max_ofdm->false_alarm_cnt); | ||
118 | pos += scnprintf(buf + pos, bufsz - pos, | ||
119 | " %-30s %10u %10u %10u %10u\n", | ||
120 | "fina_sync_err_cnt:", | ||
121 | le32_to_cpu(ofdm->fina_sync_err_cnt), | ||
122 | accum_ofdm->fina_sync_err_cnt, | ||
123 | delta_ofdm->fina_sync_err_cnt, | ||
124 | max_ofdm->fina_sync_err_cnt); | ||
125 | pos += scnprintf(buf + pos, bufsz - pos, | ||
126 | " %-30s %10u %10u %10u %10u\n", | ||
127 | "sfd_timeout:", | ||
128 | le32_to_cpu(ofdm->sfd_timeout), | ||
129 | accum_ofdm->sfd_timeout, | ||
130 | delta_ofdm->sfd_timeout, | ||
131 | max_ofdm->sfd_timeout); | ||
132 | pos += scnprintf(buf + pos, bufsz - pos, | ||
133 | " %-30s %10u %10u %10u %10u\n", | ||
134 | "fina_timeout:", | ||
135 | le32_to_cpu(ofdm->fina_timeout), | ||
136 | accum_ofdm->fina_timeout, | ||
137 | delta_ofdm->fina_timeout, | ||
138 | max_ofdm->fina_timeout); | ||
139 | pos += scnprintf(buf + pos, bufsz - pos, | ||
140 | " %-30s %10u %10u %10u %10u\n", | ||
141 | "unresponded_rts:", | ||
142 | le32_to_cpu(ofdm->unresponded_rts), | ||
143 | accum_ofdm->unresponded_rts, | ||
144 | delta_ofdm->unresponded_rts, | ||
145 | max_ofdm->unresponded_rts); | ||
146 | pos += scnprintf(buf + pos, bufsz - pos, | ||
147 | " %-30s %10u %10u %10u %10u\n", | ||
148 | "rxe_frame_lmt_ovrun:", | ||
149 | le32_to_cpu(ofdm->rxe_frame_limit_overrun), | ||
150 | accum_ofdm->rxe_frame_limit_overrun, | ||
151 | delta_ofdm->rxe_frame_limit_overrun, | ||
152 | max_ofdm->rxe_frame_limit_overrun); | ||
153 | pos += scnprintf(buf + pos, bufsz - pos, | ||
154 | " %-30s %10u %10u %10u %10u\n", | ||
155 | "sent_ack_cnt:", | ||
156 | le32_to_cpu(ofdm->sent_ack_cnt), | ||
157 | accum_ofdm->sent_ack_cnt, | ||
158 | delta_ofdm->sent_ack_cnt, | ||
159 | max_ofdm->sent_ack_cnt); | ||
160 | pos += scnprintf(buf + pos, bufsz - pos, | ||
161 | " %-30s %10u %10u %10u %10u\n", | ||
162 | "sent_cts_cnt:", | ||
163 | le32_to_cpu(ofdm->sent_cts_cnt), | ||
164 | accum_ofdm->sent_cts_cnt, | ||
165 | delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt); | ||
166 | |||
167 | pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" | ||
168 | "acumulative delta max\n", | ||
169 | "Statistics_Rx - CCK:"); | ||
170 | pos += scnprintf(buf + pos, bufsz - pos, | ||
171 | " %-30s %10u %10u %10u %10u\n", | ||
172 | "ina_cnt:", | ||
173 | le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt, | ||
174 | delta_cck->ina_cnt, max_cck->ina_cnt); | ||
175 | pos += scnprintf(buf + pos, bufsz - pos, | ||
176 | " %-30s %10u %10u %10u %10u\n", | ||
177 | "fina_cnt:", | ||
178 | le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt, | ||
179 | delta_cck->fina_cnt, max_cck->fina_cnt); | ||
180 | pos += scnprintf(buf + pos, bufsz - pos, | ||
181 | " %-30s %10u %10u %10u %10u\n", | ||
182 | "plcp_err:", | ||
183 | le32_to_cpu(cck->plcp_err), accum_cck->plcp_err, | ||
184 | delta_cck->plcp_err, max_cck->plcp_err); | ||
185 | pos += scnprintf(buf + pos, bufsz - pos, | ||
186 | " %-30s %10u %10u %10u %10u\n", | ||
187 | "crc32_err:", | ||
188 | le32_to_cpu(cck->crc32_err), accum_cck->crc32_err, | ||
189 | delta_cck->crc32_err, max_cck->crc32_err); | ||
190 | pos += scnprintf(buf + pos, bufsz - pos, | ||
191 | " %-30s %10u %10u %10u %10u\n", | ||
192 | "overrun_err:", | ||
193 | le32_to_cpu(cck->overrun_err), | ||
194 | accum_cck->overrun_err, | ||
195 | delta_cck->overrun_err, max_cck->overrun_err); | ||
196 | pos += scnprintf(buf + pos, bufsz - pos, | ||
197 | " %-30s %10u %10u %10u %10u\n", | ||
198 | "early_overrun_err:", | ||
199 | le32_to_cpu(cck->early_overrun_err), | ||
200 | accum_cck->early_overrun_err, | ||
201 | delta_cck->early_overrun_err, | ||
202 | max_cck->early_overrun_err); | ||
203 | pos += scnprintf(buf + pos, bufsz - pos, | ||
204 | " %-30s %10u %10u %10u %10u\n", | ||
205 | "crc32_good:", | ||
206 | le32_to_cpu(cck->crc32_good), accum_cck->crc32_good, | ||
207 | delta_cck->crc32_good, | ||
208 | max_cck->crc32_good); | ||
209 | pos += scnprintf(buf + pos, bufsz - pos, | ||
210 | " %-30s %10u %10u %10u %10u\n", | ||
211 | "false_alarm_cnt:", | ||
212 | le32_to_cpu(cck->false_alarm_cnt), | ||
213 | accum_cck->false_alarm_cnt, | ||
214 | delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt); | ||
215 | pos += scnprintf(buf + pos, bufsz - pos, | ||
216 | " %-30s %10u %10u %10u %10u\n", | ||
217 | "fina_sync_err_cnt:", | ||
218 | le32_to_cpu(cck->fina_sync_err_cnt), | ||
219 | accum_cck->fina_sync_err_cnt, | ||
220 | delta_cck->fina_sync_err_cnt, | ||
221 | max_cck->fina_sync_err_cnt); | ||
222 | pos += scnprintf(buf + pos, bufsz - pos, | ||
223 | " %-30s %10u %10u %10u %10u\n", | ||
224 | "sfd_timeout:", | ||
225 | le32_to_cpu(cck->sfd_timeout), | ||
226 | accum_cck->sfd_timeout, | ||
227 | delta_cck->sfd_timeout, max_cck->sfd_timeout); | ||
228 | pos += scnprintf(buf + pos, bufsz - pos, | ||
229 | " %-30s %10u %10u %10u %10u\n", | ||
230 | "fina_timeout:", | ||
231 | le32_to_cpu(cck->fina_timeout), | ||
232 | accum_cck->fina_timeout, | ||
233 | delta_cck->fina_timeout, max_cck->fina_timeout); | ||
234 | pos += scnprintf(buf + pos, bufsz - pos, | ||
235 | " %-30s %10u %10u %10u %10u\n", | ||
236 | "unresponded_rts:", | ||
237 | le32_to_cpu(cck->unresponded_rts), | ||
238 | accum_cck->unresponded_rts, | ||
239 | delta_cck->unresponded_rts, | ||
240 | max_cck->unresponded_rts); | ||
241 | pos += scnprintf(buf + pos, bufsz - pos, | ||
242 | " %-30s %10u %10u %10u %10u\n", | ||
243 | "rxe_frame_lmt_ovrun:", | ||
244 | le32_to_cpu(cck->rxe_frame_limit_overrun), | ||
245 | accum_cck->rxe_frame_limit_overrun, | ||
246 | delta_cck->rxe_frame_limit_overrun, | ||
247 | max_cck->rxe_frame_limit_overrun); | ||
248 | pos += scnprintf(buf + pos, bufsz - pos, | ||
249 | " %-30s %10u %10u %10u %10u\n", | ||
250 | "sent_ack_cnt:", | ||
251 | le32_to_cpu(cck->sent_ack_cnt), | ||
252 | accum_cck->sent_ack_cnt, | ||
253 | delta_cck->sent_ack_cnt, | ||
254 | max_cck->sent_ack_cnt); | ||
255 | pos += scnprintf(buf + pos, bufsz - pos, | ||
256 | " %-30s %10u %10u %10u %10u\n", | ||
257 | "sent_cts_cnt:", | ||
258 | le32_to_cpu(cck->sent_cts_cnt), | ||
259 | accum_cck->sent_cts_cnt, | ||
260 | delta_cck->sent_cts_cnt, | ||
261 | max_cck->sent_cts_cnt); | ||
262 | |||
263 | pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" | ||
264 | "acumulative delta max\n", | ||
265 | "Statistics_Rx - GENERAL:"); | ||
266 | pos += scnprintf(buf + pos, bufsz - pos, | ||
267 | " %-30s %10u %10u %10u %10u\n", | ||
268 | "bogus_cts:", | ||
269 | le32_to_cpu(general->bogus_cts), | ||
270 | accum_general->bogus_cts, | ||
271 | delta_general->bogus_cts, max_general->bogus_cts); | ||
272 | pos += scnprintf(buf + pos, bufsz - pos, | ||
273 | " %-30s %10u %10u %10u %10u\n", | ||
274 | "bogus_ack:", | ||
275 | le32_to_cpu(general->bogus_ack), | ||
276 | accum_general->bogus_ack, | ||
277 | delta_general->bogus_ack, max_general->bogus_ack); | ||
278 | pos += scnprintf(buf + pos, bufsz - pos, | ||
279 | " %-30s %10u %10u %10u %10u\n", | ||
280 | "non_bssid_frames:", | ||
281 | le32_to_cpu(general->non_bssid_frames), | ||
282 | accum_general->non_bssid_frames, | ||
283 | delta_general->non_bssid_frames, | ||
284 | max_general->non_bssid_frames); | ||
285 | pos += scnprintf(buf + pos, bufsz - pos, | ||
286 | " %-30s %10u %10u %10u %10u\n", | ||
287 | "filtered_frames:", | ||
288 | le32_to_cpu(general->filtered_frames), | ||
289 | accum_general->filtered_frames, | ||
290 | delta_general->filtered_frames, | ||
291 | max_general->filtered_frames); | ||
292 | pos += scnprintf(buf + pos, bufsz - pos, | ||
293 | " %-30s %10u %10u %10u %10u\n", | ||
294 | "non_channel_beacons:", | ||
295 | le32_to_cpu(general->non_channel_beacons), | ||
296 | accum_general->non_channel_beacons, | ||
297 | delta_general->non_channel_beacons, | ||
298 | max_general->non_channel_beacons); | ||
299 | |||
300 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
301 | kfree(buf); | ||
302 | return ret; | ||
303 | } | ||
304 | |||
305 | ssize_t iwl3945_ucode_tx_stats_read(struct file *file, | ||
306 | char __user *user_buf, | ||
307 | size_t count, loff_t *ppos) | ||
308 | { | ||
309 | struct iwl_priv *priv = file->private_data; | ||
310 | int pos = 0; | ||
311 | char *buf; | ||
312 | int bufsz = (sizeof(struct iwl39_statistics_tx) * 48) + 250; | ||
313 | ssize_t ret; | ||
314 | struct iwl39_statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; | ||
315 | |||
316 | if (!iwl_is_alive(priv)) | ||
317 | return -EAGAIN; | ||
318 | |||
319 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
320 | if (!buf) { | ||
321 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
322 | return -ENOMEM; | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * The statistic information display here is based on | ||
327 | * the last statistics notification from uCode | ||
328 | * might not reflect the current uCode activity | ||
329 | */ | ||
330 | tx = &priv->_3945.statistics.tx; | ||
331 | accum_tx = &priv->_3945.accum_statistics.tx; | ||
332 | delta_tx = &priv->_3945.delta_statistics.tx; | ||
333 | max_tx = &priv->_3945.max_delta.tx; | ||
334 | pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); | ||
335 | pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" | ||
336 | "acumulative delta max\n", | ||
337 | "Statistics_Tx:"); | ||
338 | pos += scnprintf(buf + pos, bufsz - pos, | ||
339 | " %-30s %10u %10u %10u %10u\n", | ||
340 | "preamble:", | ||
341 | le32_to_cpu(tx->preamble_cnt), | ||
342 | accum_tx->preamble_cnt, | ||
343 | delta_tx->preamble_cnt, max_tx->preamble_cnt); | ||
344 | pos += scnprintf(buf + pos, bufsz - pos, | ||
345 | " %-30s %10u %10u %10u %10u\n", | ||
346 | "rx_detected_cnt:", | ||
347 | le32_to_cpu(tx->rx_detected_cnt), | ||
348 | accum_tx->rx_detected_cnt, | ||
349 | delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt); | ||
350 | pos += scnprintf(buf + pos, bufsz - pos, | ||
351 | " %-30s %10u %10u %10u %10u\n", | ||
352 | "bt_prio_defer_cnt:", | ||
353 | le32_to_cpu(tx->bt_prio_defer_cnt), | ||
354 | accum_tx->bt_prio_defer_cnt, | ||
355 | delta_tx->bt_prio_defer_cnt, | ||
356 | max_tx->bt_prio_defer_cnt); | ||
357 | pos += scnprintf(buf + pos, bufsz - pos, | ||
358 | " %-30s %10u %10u %10u %10u\n", | ||
359 | "bt_prio_kill_cnt:", | ||
360 | le32_to_cpu(tx->bt_prio_kill_cnt), | ||
361 | accum_tx->bt_prio_kill_cnt, | ||
362 | delta_tx->bt_prio_kill_cnt, | ||
363 | max_tx->bt_prio_kill_cnt); | ||
364 | pos += scnprintf(buf + pos, bufsz - pos, | ||
365 | " %-30s %10u %10u %10u %10u\n", | ||
366 | "few_bytes_cnt:", | ||
367 | le32_to_cpu(tx->few_bytes_cnt), | ||
368 | accum_tx->few_bytes_cnt, | ||
369 | delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt); | ||
370 | pos += scnprintf(buf + pos, bufsz - pos, | ||
371 | " %-30s %10u %10u %10u %10u\n", | ||
372 | "cts_timeout:", | ||
373 | le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout, | ||
374 | delta_tx->cts_timeout, max_tx->cts_timeout); | ||
375 | pos += scnprintf(buf + pos, bufsz - pos, | ||
376 | " %-30s %10u %10u %10u %10u\n", | ||
377 | "ack_timeout:", | ||
378 | le32_to_cpu(tx->ack_timeout), | ||
379 | accum_tx->ack_timeout, | ||
380 | delta_tx->ack_timeout, max_tx->ack_timeout); | ||
381 | pos += scnprintf(buf + pos, bufsz - pos, | ||
382 | " %-30s %10u %10u %10u %10u\n", | ||
383 | "expected_ack_cnt:", | ||
384 | le32_to_cpu(tx->expected_ack_cnt), | ||
385 | accum_tx->expected_ack_cnt, | ||
386 | delta_tx->expected_ack_cnt, | ||
387 | max_tx->expected_ack_cnt); | ||
388 | pos += scnprintf(buf + pos, bufsz - pos, | ||
389 | " %-30s %10u %10u %10u %10u\n", | ||
390 | "actual_ack_cnt:", | ||
391 | le32_to_cpu(tx->actual_ack_cnt), | ||
392 | accum_tx->actual_ack_cnt, | ||
393 | delta_tx->actual_ack_cnt, | ||
394 | max_tx->actual_ack_cnt); | ||
395 | |||
396 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
397 | kfree(buf); | ||
398 | return ret; | ||
399 | } | ||
400 | |||
401 | ssize_t iwl3945_ucode_general_stats_read(struct file *file, | ||
402 | char __user *user_buf, | ||
403 | size_t count, loff_t *ppos) | ||
404 | { | ||
405 | struct iwl_priv *priv = file->private_data; | ||
406 | int pos = 0; | ||
407 | char *buf; | ||
408 | int bufsz = sizeof(struct iwl39_statistics_general) * 10 + 300; | ||
409 | ssize_t ret; | ||
410 | struct iwl39_statistics_general *general, *accum_general; | ||
411 | struct iwl39_statistics_general *delta_general, *max_general; | ||
412 | struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; | ||
413 | struct iwl39_statistics_div *div, *accum_div, *delta_div, *max_div; | ||
414 | |||
415 | if (!iwl_is_alive(priv)) | ||
416 | return -EAGAIN; | ||
417 | |||
418 | buf = kzalloc(bufsz, GFP_KERNEL); | ||
419 | if (!buf) { | ||
420 | IWL_ERR(priv, "Can not allocate Buffer\n"); | ||
421 | return -ENOMEM; | ||
422 | } | ||
423 | |||
424 | /* | ||
425 | * The statistic information display here is based on | ||
426 | * the last statistics notification from uCode | ||
427 | * might not reflect the current uCode activity | ||
428 | */ | ||
429 | general = &priv->_3945.statistics.general; | ||
430 | dbg = &priv->_3945.statistics.general.dbg; | ||
431 | div = &priv->_3945.statistics.general.div; | ||
432 | accum_general = &priv->_3945.accum_statistics.general; | ||
433 | delta_general = &priv->_3945.delta_statistics.general; | ||
434 | max_general = &priv->_3945.max_delta.general; | ||
435 | accum_dbg = &priv->_3945.accum_statistics.general.dbg; | ||
436 | delta_dbg = &priv->_3945.delta_statistics.general.dbg; | ||
437 | max_dbg = &priv->_3945.max_delta.general.dbg; | ||
438 | accum_div = &priv->_3945.accum_statistics.general.div; | ||
439 | delta_div = &priv->_3945.delta_statistics.general.div; | ||
440 | max_div = &priv->_3945.max_delta.general.div; | ||
441 | pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); | ||
442 | pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" | ||
443 | "acumulative delta max\n", | ||
444 | "Statistics_General:"); | ||
445 | pos += scnprintf(buf + pos, bufsz - pos, | ||
446 | " %-30s %10u %10u %10u %10u\n", | ||
447 | "burst_check:", | ||
448 | le32_to_cpu(dbg->burst_check), | ||
449 | accum_dbg->burst_check, | ||
450 | delta_dbg->burst_check, max_dbg->burst_check); | ||
451 | pos += scnprintf(buf + pos, bufsz - pos, | ||
452 | " %-30s %10u %10u %10u %10u\n", | ||
453 | "burst_count:", | ||
454 | le32_to_cpu(dbg->burst_count), | ||
455 | accum_dbg->burst_count, | ||
456 | delta_dbg->burst_count, max_dbg->burst_count); | ||
457 | pos += scnprintf(buf + pos, bufsz - pos, | ||
458 | " %-30s %10u %10u %10u %10u\n", | ||
459 | "sleep_time:", | ||
460 | le32_to_cpu(general->sleep_time), | ||
461 | accum_general->sleep_time, | ||
462 | delta_general->sleep_time, max_general->sleep_time); | ||
463 | pos += scnprintf(buf + pos, bufsz - pos, | ||
464 | " %-30s %10u %10u %10u %10u\n", | ||
465 | "slots_out:", | ||
466 | le32_to_cpu(general->slots_out), | ||
467 | accum_general->slots_out, | ||
468 | delta_general->slots_out, max_general->slots_out); | ||
469 | pos += scnprintf(buf + pos, bufsz - pos, | ||
470 | " %-30s %10u %10u %10u %10u\n", | ||
471 | "slots_idle:", | ||
472 | le32_to_cpu(general->slots_idle), | ||
473 | accum_general->slots_idle, | ||
474 | delta_general->slots_idle, max_general->slots_idle); | ||
475 | pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", | ||
476 | le32_to_cpu(general->ttl_timestamp)); | ||
477 | pos += scnprintf(buf + pos, bufsz - pos, | ||
478 | " %-30s %10u %10u %10u %10u\n", | ||
479 | "tx_on_a:", | ||
480 | le32_to_cpu(div->tx_on_a), accum_div->tx_on_a, | ||
481 | delta_div->tx_on_a, max_div->tx_on_a); | ||
482 | pos += scnprintf(buf + pos, bufsz - pos, | ||
483 | " %-30s %10u %10u %10u %10u\n", | ||
484 | "tx_on_b:", | ||
485 | le32_to_cpu(div->tx_on_b), accum_div->tx_on_b, | ||
486 | delta_div->tx_on_b, max_div->tx_on_b); | ||
487 | pos += scnprintf(buf + pos, bufsz - pos, | ||
488 | " %-30s %10u %10u %10u %10u\n", | ||
489 | "exec_time:", | ||
490 | le32_to_cpu(div->exec_time), accum_div->exec_time, | ||
491 | delta_div->exec_time, max_div->exec_time); | ||
492 | pos += scnprintf(buf + pos, bufsz - pos, | ||
493 | " %-30s %10u %10u %10u %10u\n", | ||
494 | "probe_time:", | ||
495 | le32_to_cpu(div->probe_time), accum_div->probe_time, | ||
496 | delta_div->probe_time, max_div->probe_time); | ||
497 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
498 | kfree(buf); | ||
499 | return ret; | ||
500 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h new file mode 100644 index 000000000000..70809c53c215 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h | |||
@@ -0,0 +1,60 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * GPL LICENSE SUMMARY | ||
4 | * | ||
5 | * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of version 2 of the GNU General Public License as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
19 | * USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution | ||
22 | * in the file called LICENSE.GPL. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | *****************************************************************************/ | ||
28 | |||
29 | #include "iwl-dev.h" | ||
30 | #include "iwl-core.h" | ||
31 | #include "iwl-debug.h" | ||
32 | |||
33 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
34 | ssize_t iwl3945_ucode_rx_stats_read(struct file *file, char __user *user_buf, | ||
35 | size_t count, loff_t *ppos); | ||
36 | ssize_t iwl3945_ucode_tx_stats_read(struct file *file, char __user *user_buf, | ||
37 | size_t count, loff_t *ppos); | ||
38 | ssize_t iwl3945_ucode_general_stats_read(struct file *file, | ||
39 | char __user *user_buf, size_t count, | ||
40 | loff_t *ppos); | ||
41 | #else | ||
42 | static ssize_t iwl3945_ucode_rx_stats_read(struct file *file, | ||
43 | char __user *user_buf, size_t count, | ||
44 | loff_t *ppos) | ||
45 | { | ||
46 | return 0; | ||
47 | } | ||
48 | static ssize_t iwl3945_ucode_tx_stats_read(struct file *file, | ||
49 | char __user *user_buf, size_t count, | ||
50 | loff_t *ppos) | ||
51 | { | ||
52 | return 0; | ||
53 | } | ||
54 | static ssize_t iwl3945_ucode_general_stats_read(struct file *file, | ||
55 | char __user *user_buf, | ||
56 | size_t count, loff_t *ppos) | ||
57 | { | ||
58 | return 0; | ||
59 | } | ||
60 | #endif | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 59af2594c9c5..17197a78d894 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include "iwl-helpers.h" | 50 | #include "iwl-helpers.h" |
51 | #include "iwl-led.h" | 51 | #include "iwl-led.h" |
52 | #include "iwl-3945-led.h" | 52 | #include "iwl-3945-led.h" |
53 | #include "iwl-3945-debugfs.h" | ||
53 | 54 | ||
54 | #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ | 55 | #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ |
55 | [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ | 56 | [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ |
@@ -293,7 +294,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, | |||
293 | * iwl3945_rx_reply_tx - Handle Tx response | 294 | * iwl3945_rx_reply_tx - Handle Tx response |
294 | */ | 295 | */ |
295 | static void iwl3945_rx_reply_tx(struct iwl_priv *priv, | 296 | static void iwl3945_rx_reply_tx(struct iwl_priv *priv, |
296 | struct iwl_rx_mem_buffer *rxb) | 297 | struct iwl_rx_mem_buffer *rxb) |
297 | { | 298 | { |
298 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 299 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
299 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 300 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
@@ -351,18 +352,81 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv, | |||
351 | * RX handler implementations | 352 | * RX handler implementations |
352 | * | 353 | * |
353 | *****************************************************************************/ | 354 | *****************************************************************************/ |
355 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
356 | /* | ||
357 | * based on the assumption of all statistics counter are in DWORD | ||
358 | * FIXME: This function is for debugging, do not deal with | ||
359 | * the case of counters roll-over. | ||
360 | */ | ||
361 | static void iwl3945_accumulative_statistics(struct iwl_priv *priv, | ||
362 | __le32 *stats) | ||
363 | { | ||
364 | int i; | ||
365 | __le32 *prev_stats; | ||
366 | u32 *accum_stats; | ||
367 | u32 *delta, *max_delta; | ||
368 | |||
369 | prev_stats = (__le32 *)&priv->_3945.statistics; | ||
370 | accum_stats = (u32 *)&priv->_3945.accum_statistics; | ||
371 | delta = (u32 *)&priv->_3945.delta_statistics; | ||
372 | max_delta = (u32 *)&priv->_3945.max_delta; | ||
373 | |||
374 | for (i = sizeof(__le32); i < sizeof(struct iwl3945_notif_statistics); | ||
375 | i += sizeof(__le32), stats++, prev_stats++, delta++, | ||
376 | max_delta++, accum_stats++) { | ||
377 | if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { | ||
378 | *delta = (le32_to_cpu(*stats) - | ||
379 | le32_to_cpu(*prev_stats)); | ||
380 | *accum_stats += *delta; | ||
381 | if (*delta > *max_delta) | ||
382 | *max_delta = *delta; | ||
383 | } | ||
384 | } | ||
385 | |||
386 | /* reset accumulative statistics for "no-counter" type statistics */ | ||
387 | priv->_3945.accum_statistics.general.temperature = | ||
388 | priv->_3945.statistics.general.temperature; | ||
389 | priv->_3945.accum_statistics.general.ttl_timestamp = | ||
390 | priv->_3945.statistics.general.ttl_timestamp; | ||
391 | } | ||
392 | #endif | ||
354 | 393 | ||
355 | void iwl3945_hw_rx_statistics(struct iwl_priv *priv, | 394 | void iwl3945_hw_rx_statistics(struct iwl_priv *priv, |
356 | struct iwl_rx_mem_buffer *rxb) | 395 | struct iwl_rx_mem_buffer *rxb) |
357 | { | 396 | { |
358 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 397 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
398 | |||
359 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", | 399 | IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", |
360 | (int)sizeof(struct iwl3945_notif_statistics), | 400 | (int)sizeof(struct iwl3945_notif_statistics), |
361 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); | 401 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); |
402 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
403 | iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); | ||
404 | #endif | ||
362 | 405 | ||
363 | memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); | 406 | memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); |
364 | } | 407 | } |
365 | 408 | ||
409 | void iwl3945_reply_statistics(struct iwl_priv *priv, | ||
410 | struct iwl_rx_mem_buffer *rxb) | ||
411 | { | ||
412 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||
413 | __le32 *flag = (__le32 *)&pkt->u.raw; | ||
414 | |||
415 | if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) { | ||
416 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
417 | memset(&priv->_3945.accum_statistics, 0, | ||
418 | sizeof(struct iwl3945_notif_statistics)); | ||
419 | memset(&priv->_3945.delta_statistics, 0, | ||
420 | sizeof(struct iwl3945_notif_statistics)); | ||
421 | memset(&priv->_3945.max_delta, 0, | ||
422 | sizeof(struct iwl3945_notif_statistics)); | ||
423 | #endif | ||
424 | IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); | ||
425 | } | ||
426 | iwl3945_hw_rx_statistics(priv, rxb); | ||
427 | } | ||
428 | |||
429 | |||
366 | /****************************************************************************** | 430 | /****************************************************************************** |
367 | * | 431 | * |
368 | * Misc. internal state and helper functions | 432 | * Misc. internal state and helper functions |
@@ -2736,6 +2800,12 @@ static struct iwl_lib_ops iwl3945_lib = { | |||
2736 | .isr = iwl_isr_legacy, | 2800 | .isr = iwl_isr_legacy, |
2737 | .config_ap = iwl3945_config_ap, | 2801 | .config_ap = iwl3945_config_ap, |
2738 | .add_bcast_station = iwl3945_add_bcast_station, | 2802 | .add_bcast_station = iwl3945_add_bcast_station, |
2803 | |||
2804 | .debugfs_ops = { | ||
2805 | .rx_stats_read = iwl3945_ucode_rx_stats_read, | ||
2806 | .tx_stats_read = iwl3945_ucode_tx_stats_read, | ||
2807 | .general_stats_read = iwl3945_ucode_general_stats_read, | ||
2808 | }, | ||
2739 | }; | 2809 | }; |
2740 | 2810 | ||
2741 | static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { | 2811 | static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index e9674f0a1e94..643adb644bb8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -264,6 +264,8 @@ extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv); | |||
264 | extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); | 264 | extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); |
265 | extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, | 265 | extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, |
266 | struct iwl_rx_mem_buffer *rxb); | 266 | struct iwl_rx_mem_buffer *rxb); |
267 | void iwl3945_reply_statistics(struct iwl_priv *priv, | ||
268 | struct iwl_rx_mem_buffer *rxb); | ||
267 | extern void iwl3945_disable_events(struct iwl_priv *priv); | 269 | extern void iwl3945_disable_events(struct iwl_priv *priv); |
268 | extern int iwl4965_get_temperature(const struct iwl_priv *priv); | 270 | extern int iwl4965_get_temperature(const struct iwl_priv *priv); |
269 | extern void iwl3945_post_associate(struct iwl_priv *priv); | 271 | extern void iwl3945_post_associate(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index e43493685271..115d3ea1142f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -200,26 +200,57 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
200 | 200 | ||
201 | /* Set initial sensitivity parameters */ | 201 | /* Set initial sensitivity parameters */ |
202 | /* Set initial calibration set */ | 202 | /* Set initial calibration set */ |
203 | switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { | 203 | priv->hw_params.sens = &iwl5000_sensitivity; |
204 | case CSR_HW_REV_TYPE_5150: | 204 | priv->hw_params.calib_init_cfg = |
205 | priv->hw_params.sens = &iwl5150_sensitivity; | 205 | BIT(IWL_CALIB_XTAL) | |
206 | priv->hw_params.calib_init_cfg = | 206 | BIT(IWL_CALIB_LO) | |
207 | BIT(IWL_CALIB_DC) | | 207 | BIT(IWL_CALIB_TX_IQ) | |
208 | BIT(IWL_CALIB_LO) | | 208 | BIT(IWL_CALIB_TX_IQ_PERD) | |
209 | BIT(IWL_CALIB_TX_IQ) | | 209 | BIT(IWL_CALIB_BASE_BAND); |
210 | BIT(IWL_CALIB_BASE_BAND); | 210 | |
211 | 211 | return 0; | |
212 | break; | 212 | } |
213 | default: | 213 | |
214 | priv->hw_params.sens = &iwl5000_sensitivity; | 214 | static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) |
215 | priv->hw_params.calib_init_cfg = | 215 | { |
216 | BIT(IWL_CALIB_XTAL) | | 216 | if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && |
217 | BIT(IWL_CALIB_LO) | | 217 | priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) |
218 | BIT(IWL_CALIB_TX_IQ) | | 218 | priv->cfg->num_of_queues = |
219 | BIT(IWL_CALIB_TX_IQ_PERD) | | 219 | priv->cfg->mod_params->num_of_queues; |
220 | BIT(IWL_CALIB_BASE_BAND); | 220 | |
221 | break; | 221 | priv->hw_params.max_txq_num = priv->cfg->num_of_queues; |
222 | } | 222 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; |
223 | priv->hw_params.scd_bc_tbls_size = | ||
224 | priv->cfg->num_of_queues * | ||
225 | sizeof(struct iwlagn_scd_bc_tbl); | ||
226 | priv->hw_params.tfd_size = sizeof(struct iwl_tfd); | ||
227 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; | ||
228 | priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; | ||
229 | |||
230 | priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; | ||
231 | priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; | ||
232 | |||
233 | priv->hw_params.max_bsm_size = 0; | ||
234 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
235 | BIT(IEEE80211_BAND_5GHZ); | ||
236 | priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; | ||
237 | |||
238 | priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); | ||
239 | priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); | ||
240 | priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; | ||
241 | priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; | ||
242 | |||
243 | if (priv->cfg->ops->lib->temp_ops.set_ct_kill) | ||
244 | priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); | ||
245 | |||
246 | /* Set initial sensitivity parameters */ | ||
247 | /* Set initial calibration set */ | ||
248 | priv->hw_params.sens = &iwl5150_sensitivity; | ||
249 | priv->hw_params.calib_init_cfg = | ||
250 | BIT(IWL_CALIB_DC) | | ||
251 | BIT(IWL_CALIB_LO) | | ||
252 | BIT(IWL_CALIB_TX_IQ) | | ||
253 | BIT(IWL_CALIB_BASE_BAND); | ||
223 | 254 | ||
224 | return 0; | 255 | return 0; |
225 | } | 256 | } |
@@ -332,7 +363,7 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
332 | }; | 363 | }; |
333 | 364 | ||
334 | static struct iwl_lib_ops iwl5150_lib = { | 365 | static struct iwl_lib_ops iwl5150_lib = { |
335 | .set_hw_params = iwl5000_hw_set_hw_params, | 366 | .set_hw_params = iwl5150_hw_set_hw_params, |
336 | .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, | 367 | .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, |
337 | .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, | 368 | .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, |
338 | .txq_set_sched = iwlagn_txq_set_sched, | 369 | .txq_set_sched = iwlagn_txq_set_sched, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 7da23d3ff7b6..7acef703253a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -176,24 +176,56 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) | |||
176 | /* Set initial sensitivity parameters */ | 176 | /* Set initial sensitivity parameters */ |
177 | /* Set initial calibration set */ | 177 | /* Set initial calibration set */ |
178 | priv->hw_params.sens = &iwl6000_sensitivity; | 178 | priv->hw_params.sens = &iwl6000_sensitivity; |
179 | switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { | 179 | priv->hw_params.calib_init_cfg = |
180 | case CSR_HW_REV_TYPE_6x50: | 180 | BIT(IWL_CALIB_XTAL) | |
181 | priv->hw_params.calib_init_cfg = | 181 | BIT(IWL_CALIB_LO) | |
182 | BIT(IWL_CALIB_XTAL) | | 182 | BIT(IWL_CALIB_TX_IQ) | |
183 | BIT(IWL_CALIB_DC) | | 183 | BIT(IWL_CALIB_BASE_BAND); |
184 | BIT(IWL_CALIB_LO) | | 184 | |
185 | BIT(IWL_CALIB_TX_IQ) | | 185 | return 0; |
186 | BIT(IWL_CALIB_BASE_BAND); | 186 | } |
187 | 187 | ||
188 | break; | 188 | static int iwl6050_hw_set_hw_params(struct iwl_priv *priv) |
189 | default: | 189 | { |
190 | priv->hw_params.calib_init_cfg = | 190 | if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && |
191 | BIT(IWL_CALIB_XTAL) | | 191 | priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) |
192 | BIT(IWL_CALIB_LO) | | 192 | priv->cfg->num_of_queues = |
193 | BIT(IWL_CALIB_TX_IQ) | | 193 | priv->cfg->mod_params->num_of_queues; |
194 | BIT(IWL_CALIB_BASE_BAND); | 194 | |
195 | break; | 195 | priv->hw_params.max_txq_num = priv->cfg->num_of_queues; |
196 | } | 196 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; |
197 | priv->hw_params.scd_bc_tbls_size = | ||
198 | priv->cfg->num_of_queues * | ||
199 | sizeof(struct iwlagn_scd_bc_tbl); | ||
200 | priv->hw_params.tfd_size = sizeof(struct iwl_tfd); | ||
201 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; | ||
202 | priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; | ||
203 | |||
204 | priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; | ||
205 | priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; | ||
206 | |||
207 | priv->hw_params.max_bsm_size = 0; | ||
208 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
209 | BIT(IEEE80211_BAND_5GHZ); | ||
210 | priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; | ||
211 | |||
212 | priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); | ||
213 | priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); | ||
214 | priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; | ||
215 | priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; | ||
216 | |||
217 | if (priv->cfg->ops->lib->temp_ops.set_ct_kill) | ||
218 | priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); | ||
219 | |||
220 | /* Set initial sensitivity parameters */ | ||
221 | /* Set initial calibration set */ | ||
222 | priv->hw_params.sens = &iwl6000_sensitivity; | ||
223 | priv->hw_params.calib_init_cfg = | ||
224 | BIT(IWL_CALIB_XTAL) | | ||
225 | BIT(IWL_CALIB_DC) | | ||
226 | BIT(IWL_CALIB_LO) | | ||
227 | BIT(IWL_CALIB_TX_IQ) | | ||
228 | BIT(IWL_CALIB_BASE_BAND); | ||
197 | 229 | ||
198 | return 0; | 230 | return 0; |
199 | } | 231 | } |
@@ -304,7 +336,7 @@ static const struct iwl_ops iwl6000_ops = { | |||
304 | }; | 336 | }; |
305 | 337 | ||
306 | static struct iwl_lib_ops iwl6050_lib = { | 338 | static struct iwl_lib_ops iwl6050_lib = { |
307 | .set_hw_params = iwl6000_hw_set_hw_params, | 339 | .set_hw_params = iwl6050_hw_set_hw_params, |
308 | .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, | 340 | .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, |
309 | .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, | 341 | .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, |
310 | .txq_set_sched = iwlagn_txq_set_sched, | 342 | .txq_set_sched = iwlagn_txq_set_sched, |
@@ -468,7 +500,6 @@ struct iwl_cfg iwl6000i_2abg_cfg = { | |||
468 | .pa_type = IWL_PA_INTERNAL, | 500 | .pa_type = IWL_PA_INTERNAL, |
469 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 501 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
470 | .shadow_ram_support = true, | 502 | .shadow_ram_support = true, |
471 | .ht_greenfield_support = true, | ||
472 | .led_compensation = 51, | 503 | .led_compensation = 51, |
473 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 504 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
474 | .supports_idle = true, | 505 | .supports_idle = true, |
@@ -501,7 +532,6 @@ struct iwl_cfg iwl6000i_2bg_cfg = { | |||
501 | .pa_type = IWL_PA_INTERNAL, | 532 | .pa_type = IWL_PA_INTERNAL, |
502 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 533 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
503 | .shadow_ram_support = true, | 534 | .shadow_ram_support = true, |
504 | .ht_greenfield_support = true, | ||
505 | .led_compensation = 51, | 535 | .led_compensation = 51, |
506 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 536 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
507 | .supports_idle = true, | 537 | .supports_idle = true, |
@@ -568,7 +598,6 @@ struct iwl_cfg iwl6050_2abg_cfg = { | |||
568 | .pa_type = IWL_PA_SYSTEM, | 598 | .pa_type = IWL_PA_SYSTEM, |
569 | .max_ll_items = OTP_MAX_LL_ITEMS_6x50, | 599 | .max_ll_items = OTP_MAX_LL_ITEMS_6x50, |
570 | .shadow_ram_support = true, | 600 | .shadow_ram_support = true, |
571 | .ht_greenfield_support = true, | ||
572 | .led_compensation = 51, | 601 | .led_compensation = 51, |
573 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 602 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
574 | .supports_idle = true, | 603 | .supports_idle = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 4bd0aecc7713..a27347425968 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -1395,16 +1395,29 @@ void iwlagn_request_scan(struct iwl_priv *priv) | |||
1395 | rate = IWL_RATE_1M_PLCP; | 1395 | rate = IWL_RATE_1M_PLCP; |
1396 | rate_flags = RATE_MCS_CCK_MSK; | 1396 | rate_flags = RATE_MCS_CCK_MSK; |
1397 | } | 1397 | } |
1398 | scan->good_CRC_th = 0; | 1398 | scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED; |
1399 | break; | 1399 | break; |
1400 | case IEEE80211_BAND_5GHZ: | 1400 | case IEEE80211_BAND_5GHZ: |
1401 | rate = IWL_RATE_6M_PLCP; | 1401 | rate = IWL_RATE_6M_PLCP; |
1402 | /* | 1402 | /* |
1403 | * If active scaning is requested but a certain channel | 1403 | * If active scanning is requested but a certain channel is |
1404 | * is marked passive, we can do active scanning if we | 1404 | * marked passive, we can do active scanning if we detect |
1405 | * detect transmissions. | 1405 | * transmissions. |
1406 | * | ||
1407 | * There is an issue with some firmware versions that triggers | ||
1408 | * a sysassert on a "good CRC threshold" of zero (== disabled), | ||
1409 | * on a radar channel even though this means that we should NOT | ||
1410 | * send probes. | ||
1411 | * | ||
1412 | * The "good CRC threshold" is the number of frames that we | ||
1413 | * need to receive during our dwell time on a channel before | ||
1414 | * sending out probes -- setting this to a huge value will | ||
1415 | * mean we never reach it, but at the same time work around | ||
1416 | * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER | ||
1417 | * here instead of IWL_GOOD_CRC_TH_DISABLED. | ||
1406 | */ | 1418 | */ |
1407 | scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0; | 1419 | scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : |
1420 | IWL_GOOD_CRC_TH_NEVER; | ||
1408 | break; | 1421 | break; |
1409 | default: | 1422 | default: |
1410 | IWL_WARN(priv, "Invalid scan band count\n"); | 1423 | IWL_WARN(priv, "Invalid scan band count\n"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 0e6161d7c764..bfcac5608d87 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -868,14 +868,14 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
868 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, | 868 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, |
869 | &rs_index); | 869 | &rs_index); |
870 | rs_collect_tx_data(curr_tbl, rs_index, | 870 | rs_collect_tx_data(curr_tbl, rs_index, |
871 | info->status.ampdu_ack_len, | 871 | info->status.ampdu_len, |
872 | info->status.ampdu_ack_map); | 872 | info->status.ampdu_ack_len); |
873 | 873 | ||
874 | /* Update success/fail counts if not searching for new mode */ | 874 | /* Update success/fail counts if not searching for new mode */ |
875 | if (lq_sta->stay_in_tbl) { | 875 | if (lq_sta->stay_in_tbl) { |
876 | lq_sta->total_success += info->status.ampdu_ack_map; | 876 | lq_sta->total_success += info->status.ampdu_ack_len; |
877 | lq_sta->total_failed += (info->status.ampdu_ack_len - | 877 | lq_sta->total_failed += (info->status.ampdu_len - |
878 | info->status.ampdu_ack_map); | 878 | info->status.ampdu_ack_len); |
879 | } | 879 | } |
880 | } else { | 880 | } else { |
881 | /* | 881 | /* |
@@ -2078,10 +2078,12 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2078 | } | 2078 | } |
2079 | /* Else we have enough samples; calculate estimate of | 2079 | /* Else we have enough samples; calculate estimate of |
2080 | * actual average throughput */ | 2080 | * actual average throughput */ |
2081 | 2081 | if (window->average_tpt != ((window->success_ratio * | |
2082 | /* Sanity-check TPT calculations */ | 2082 | tbl->expected_tpt[index] + 64) / 128)) { |
2083 | BUG_ON(window->average_tpt != ((window->success_ratio * | 2083 | IWL_ERR(priv, "expected_tpt should have been calculated by now\n"); |
2084 | tbl->expected_tpt[index] + 64) / 128)); | 2084 | window->average_tpt = ((window->success_ratio * |
2085 | tbl->expected_tpt[index] + 64) / 128); | ||
2086 | } | ||
2085 | 2087 | ||
2086 | /* If we are searching for better modulation mode, check success. */ | 2088 | /* If we are searching for better modulation mode, check success. */ |
2087 | if (lq_sta->search_better_tbl && | 2089 | if (lq_sta->search_better_tbl && |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 11661fa28f21..c2a5c85542bf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -83,6 +83,15 @@ static inline int get_fifo_from_ac(u8 ac) | |||
83 | return ac_to_fifo[ac]; | 83 | return ac_to_fifo[ac]; |
84 | } | 84 | } |
85 | 85 | ||
86 | static inline int get_ac_from_tid(u16 tid) | ||
87 | { | ||
88 | if (likely(tid < ARRAY_SIZE(tid_to_ac))) | ||
89 | return tid_to_ac[tid]; | ||
90 | |||
91 | /* no support for TIDs 8-15 yet */ | ||
92 | return -EINVAL; | ||
93 | } | ||
94 | |||
86 | static inline int get_fifo_from_tid(u16 tid) | 95 | static inline int get_fifo_from_tid(u16 tid) |
87 | { | 96 | { |
88 | if (likely(tid < ARRAY_SIZE(tid_to_ac))) | 97 | if (likely(tid < ARRAY_SIZE(tid_to_ac))) |
@@ -991,7 +1000,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn) | |||
991 | tid_data = &priv->stations[sta_id].tid[tid]; | 1000 | tid_data = &priv->stations[sta_id].tid[tid]; |
992 | *ssn = SEQ_TO_SN(tid_data->seq_number); | 1001 | *ssn = SEQ_TO_SN(tid_data->seq_number); |
993 | tid_data->agg.txq_id = txq_id; | 1002 | tid_data->agg.txq_id = txq_id; |
994 | priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(tx_fifo, txq_id); | 1003 | priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(get_ac_from_tid(tid), txq_id); |
995 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 1004 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
996 | 1005 | ||
997 | ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo, | 1006 | ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo, |
@@ -1224,8 +1233,9 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, | |||
1224 | memset(&info->status, 0, sizeof(info->status)); | 1233 | memset(&info->status, 0, sizeof(info->status)); |
1225 | info->flags |= IEEE80211_TX_STAT_ACK; | 1234 | info->flags |= IEEE80211_TX_STAT_ACK; |
1226 | info->flags |= IEEE80211_TX_STAT_AMPDU; | 1235 | info->flags |= IEEE80211_TX_STAT_AMPDU; |
1227 | info->status.ampdu_ack_map = successes; | 1236 | info->status.ampdu_ack_len = successes; |
1228 | info->status.ampdu_ack_len = agg->frame_count; | 1237 | info->status.ampdu_ack_map = bitmap; |
1238 | info->status.ampdu_len = agg->frame_count; | ||
1229 | iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); | 1239 | iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); |
1230 | 1240 | ||
1231 | IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap); | 1241 | IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 00344d64635c..a672d3379cfd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -2654,7 +2654,6 @@ static int iwl_mac_setup_register(struct iwl_priv *priv) | |||
2654 | 2654 | ||
2655 | /* Tell mac80211 our characteristics */ | 2655 | /* Tell mac80211 our characteristics */ |
2656 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | 2656 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
2657 | IEEE80211_HW_NOISE_DBM | | ||
2658 | IEEE80211_HW_AMPDU_AGGREGATION | | 2657 | IEEE80211_HW_AMPDU_AGGREGATION | |
2659 | IEEE80211_HW_SPECTRUM_MGMT; | 2658 | IEEE80211_HW_SPECTRUM_MGMT; |
2660 | 2659 | ||
@@ -3002,18 +3001,6 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, | |||
3002 | return 0; | 3001 | return 0; |
3003 | } | 3002 | } |
3004 | 3003 | ||
3005 | static int iwl_mac_get_stats(struct ieee80211_hw *hw, | ||
3006 | struct ieee80211_low_level_stats *stats) | ||
3007 | { | ||
3008 | struct iwl_priv *priv = hw->priv; | ||
3009 | |||
3010 | priv = hw->priv; | ||
3011 | IWL_DEBUG_MAC80211(priv, "enter\n"); | ||
3012 | IWL_DEBUG_MAC80211(priv, "leave\n"); | ||
3013 | |||
3014 | return 0; | ||
3015 | } | ||
3016 | |||
3017 | static void iwl_mac_sta_notify(struct ieee80211_hw *hw, | 3004 | static void iwl_mac_sta_notify(struct ieee80211_hw *hw, |
3018 | struct ieee80211_vif *vif, | 3005 | struct ieee80211_vif *vif, |
3019 | enum sta_notify_cmd cmd, | 3006 | enum sta_notify_cmd cmd, |
@@ -3391,7 +3378,6 @@ static struct ieee80211_ops iwl_hw_ops = { | |||
3391 | .configure_filter = iwl_configure_filter, | 3378 | .configure_filter = iwl_configure_filter, |
3392 | .set_key = iwl_mac_set_key, | 3379 | .set_key = iwl_mac_set_key, |
3393 | .update_tkip_key = iwl_mac_update_tkip_key, | 3380 | .update_tkip_key = iwl_mac_update_tkip_key, |
3394 | .get_stats = iwl_mac_get_stats, | ||
3395 | .conf_tx = iwl_mac_conf_tx, | 3381 | .conf_tx = iwl_mac_conf_tx, |
3396 | .reset_tsf = iwl_mac_reset_tsf, | 3382 | .reset_tsf = iwl_mac_reset_tsf, |
3397 | .bss_info_changed = iwl_bss_info_changed, | 3383 | .bss_info_changed = iwl_bss_info_changed, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 67c723cc32d2..0086019b7a15 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -2663,7 +2663,9 @@ struct iwl_ssid_ie { | |||
2663 | #define PROBE_OPTION_MAX_3945 4 | 2663 | #define PROBE_OPTION_MAX_3945 4 |
2664 | #define PROBE_OPTION_MAX 20 | 2664 | #define PROBE_OPTION_MAX 20 |
2665 | #define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF) | 2665 | #define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF) |
2666 | #define IWL_GOOD_CRC_TH cpu_to_le16(1) | 2666 | #define IWL_GOOD_CRC_TH_DISABLED 0 |
2667 | #define IWL_GOOD_CRC_TH_DEFAULT cpu_to_le16(1) | ||
2668 | #define IWL_GOOD_CRC_TH_NEVER cpu_to_le16(0xffff) | ||
2667 | #define IWL_MAX_SCAN_SIZE 1024 | 2669 | #define IWL_MAX_SCAN_SIZE 1024 |
2668 | #define IWL_MAX_CMD_SIZE 4096 | 2670 | #define IWL_MAX_CMD_SIZE 4096 |
2669 | #define IWL_MAX_PROBE_REQUEST 200 | 2671 | #define IWL_MAX_PROBE_REQUEST 200 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 56a9f1741419..4cdf4d3a9ddb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -2117,10 +2117,6 @@ EXPORT_SYMBOL(iwl_mac_remove_interface); | |||
2117 | 2117 | ||
2118 | /** | 2118 | /** |
2119 | * iwl_mac_config - mac80211 config callback | 2119 | * iwl_mac_config - mac80211 config callback |
2120 | * | ||
2121 | * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to | ||
2122 | * be set inappropriately and the driver currently sets the hardware up to | ||
2123 | * use it whenever needed. | ||
2124 | */ | 2120 | */ |
2125 | int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | 2121 | int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) |
2126 | { | 2122 | { |
@@ -2935,6 +2931,12 @@ int iwl_pci_resume(struct pci_dev *pdev) | |||
2935 | struct iwl_priv *priv = pci_get_drvdata(pdev); | 2931 | struct iwl_priv *priv = pci_get_drvdata(pdev); |
2936 | int ret; | 2932 | int ret; |
2937 | 2933 | ||
2934 | /* | ||
2935 | * We disable the RETRY_TIMEOUT register (0x41) to keep | ||
2936 | * PCI Tx retries from interfering with C3 CPU state. | ||
2937 | */ | ||
2938 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | ||
2939 | |||
2938 | pci_set_power_state(pdev, PCI_D0); | 2940 | pci_set_power_state(pdev, PCI_D0); |
2939 | ret = pci_enable_device(pdev); | 2941 | ret = pci_enable_device(pdev); |
2940 | if (ret) | 2942 | if (ret) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index a0cc11ecbe93..727360944859 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -512,7 +512,9 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) | |||
512 | void iwl_init_scan_params(struct iwl_priv *priv); | 512 | void iwl_init_scan_params(struct iwl_priv *priv); |
513 | int iwl_scan_cancel(struct iwl_priv *priv); | 513 | int iwl_scan_cancel(struct iwl_priv *priv); |
514 | int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); | 514 | int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); |
515 | int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); | 515 | int iwl_mac_hw_scan(struct ieee80211_hw *hw, |
516 | struct ieee80211_vif *vif, | ||
517 | struct cfg80211_scan_request *req); | ||
516 | void iwl_internal_short_hw_scan(struct iwl_priv *priv); | 518 | void iwl_internal_short_hw_scan(struct iwl_priv *priv); |
517 | int iwl_force_reset(struct iwl_priv *priv, int mode); | 519 | int iwl_force_reset(struct iwl_priv *priv, int mode); |
518 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, | 520 | u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 61faf2dd7fbe..4aabb542fcbe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -1059,10 +1059,8 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, | |||
1059 | size_t count, loff_t *ppos) | 1059 | size_t count, loff_t *ppos) |
1060 | { | 1060 | { |
1061 | struct iwl_priv *priv = file->private_data; | 1061 | struct iwl_priv *priv = file->private_data; |
1062 | if (priv->cfg->ops->lib->debugfs_ops.rx_stats_read) | 1062 | return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file, |
1063 | return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file, | 1063 | user_buf, count, ppos); |
1064 | user_buf, count, ppos); | ||
1065 | return 0; | ||
1066 | } | 1064 | } |
1067 | 1065 | ||
1068 | static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | 1066 | static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, |
@@ -1070,10 +1068,8 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1070 | size_t count, loff_t *ppos) | 1068 | size_t count, loff_t *ppos) |
1071 | { | 1069 | { |
1072 | struct iwl_priv *priv = file->private_data; | 1070 | struct iwl_priv *priv = file->private_data; |
1073 | if (priv->cfg->ops->lib->debugfs_ops.tx_stats_read) | 1071 | return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file, |
1074 | return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file, | 1072 | user_buf, count, ppos); |
1075 | user_buf, count, ppos); | ||
1076 | return 0; | ||
1077 | } | 1073 | } |
1078 | 1074 | ||
1079 | static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | 1075 | static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, |
@@ -1081,10 +1077,8 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, | |||
1081 | size_t count, loff_t *ppos) | 1077 | size_t count, loff_t *ppos) |
1082 | { | 1078 | { |
1083 | struct iwl_priv *priv = file->private_data; | 1079 | struct iwl_priv *priv = file->private_data; |
1084 | if (priv->cfg->ops->lib->debugfs_ops.general_stats_read) | 1080 | return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file, |
1085 | return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file, | 1081 | user_buf, count, ppos); |
1086 | user_buf, count, ppos); | ||
1087 | return 0; | ||
1088 | } | 1082 | } |
1089 | 1083 | ||
1090 | static ssize_t iwl_dbgfs_sensitivity_read(struct file *file, | 1084 | static ssize_t iwl_dbgfs_sensitivity_read(struct file *file, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index bdc60aae75ec..58c69a5798d4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1202,6 +1202,11 @@ struct iwl_priv { | |||
1202 | struct delayed_work rfkill_poll; | 1202 | struct delayed_work rfkill_poll; |
1203 | 1203 | ||
1204 | struct iwl3945_notif_statistics statistics; | 1204 | struct iwl3945_notif_statistics statistics; |
1205 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1206 | struct iwl3945_notif_statistics accum_statistics; | ||
1207 | struct iwl3945_notif_statistics delta_statistics; | ||
1208 | struct iwl3945_notif_statistics max_delta; | ||
1209 | #endif | ||
1205 | 1210 | ||
1206 | u32 sta_supp_rates; | 1211 | u32 sta_supp_rates; |
1207 | int last_rx_rssi; /* From Rx packet statistics */ | 1212 | int last_rx_rssi; /* From Rx packet statistics */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index f4b897804a80..d12fd5553846 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -313,7 +313,8 @@ static int iwl_scan_initiate(struct iwl_priv *priv) | |||
313 | } | 313 | } |
314 | 314 | ||
315 | int iwl_mac_hw_scan(struct ieee80211_hw *hw, | 315 | int iwl_mac_hw_scan(struct ieee80211_hw *hw, |
316 | struct cfg80211_scan_request *req) | 316 | struct ieee80211_vif *vif, |
317 | struct cfg80211_scan_request *req) | ||
317 | { | 318 | { |
318 | struct iwl_priv *priv = hw->priv; | 319 | struct iwl_priv *priv = hw->priv; |
319 | int ret; | 320 | int ret; |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index a41ba72ceb00..c7e1d7d09e02 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -957,7 +957,7 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv) | |||
957 | * statistics request from the host as well as for the periodic | 957 | * statistics request from the host as well as for the periodic |
958 | * statistics notifications (after received beacons) from the uCode. | 958 | * statistics notifications (after received beacons) from the uCode. |
959 | */ | 959 | */ |
960 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics; | 960 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_reply_statistics; |
961 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; | 961 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; |
962 | 962 | ||
963 | iwl_setup_rx_scan_handlers(priv); | 963 | iwl_setup_rx_scan_handlers(priv); |
@@ -2939,7 +2939,8 @@ void iwl3945_request_scan(struct iwl_priv *priv) | |||
2939 | * is marked passive, we can do active scanning if we | 2939 | * is marked passive, we can do active scanning if we |
2940 | * detect transmissions. | 2940 | * detect transmissions. |
2941 | */ | 2941 | */ |
2942 | scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0; | 2942 | scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : |
2943 | IWL_GOOD_CRC_TH_DISABLED; | ||
2943 | band = IEEE80211_BAND_5GHZ; | 2944 | band = IEEE80211_BAND_5GHZ; |
2944 | break; | 2945 | break; |
2945 | default: | 2946 | default: |
@@ -3873,7 +3874,6 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) | |||
3873 | 3874 | ||
3874 | /* Tell mac80211 our characteristics */ | 3875 | /* Tell mac80211 our characteristics */ |
3875 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | 3876 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
3876 | IEEE80211_HW_NOISE_DBM | | ||
3877 | IEEE80211_HW_SPECTRUM_MGMT; | 3877 | IEEE80211_HW_SPECTRUM_MGMT; |
3878 | 3878 | ||
3879 | if (!priv->cfg->broken_powersave) | 3879 | if (!priv->cfg->broken_powersave) |
diff --git a/drivers/net/wireless/iwmc3200wifi/bus.h b/drivers/net/wireless/iwmc3200wifi/bus.h index 836663eec257..62edd5888a7b 100644 --- a/drivers/net/wireless/iwmc3200wifi/bus.h +++ b/drivers/net/wireless/iwmc3200wifi/bus.h | |||
@@ -31,7 +31,7 @@ struct iwm_if_ops { | |||
31 | int (*disable)(struct iwm_priv *iwm); | 31 | int (*disable)(struct iwm_priv *iwm); |
32 | int (*send_chunk)(struct iwm_priv *iwm, u8* buf, int count); | 32 | int (*send_chunk)(struct iwm_priv *iwm, u8* buf, int count); |
33 | 33 | ||
34 | int (*debugfs_init)(struct iwm_priv *iwm, struct dentry *parent_dir); | 34 | void (*debugfs_init)(struct iwm_priv *iwm, struct dentry *parent_dir); |
35 | void (*debugfs_exit)(struct iwm_priv *iwm); | 35 | void (*debugfs_exit)(struct iwm_priv *iwm); |
36 | 36 | ||
37 | const char *umac_name; | 37 | const char *umac_name; |
diff --git a/drivers/net/wireless/iwmc3200wifi/debug.h b/drivers/net/wireless/iwmc3200wifi/debug.h index e35c9b693d1f..a0c13a49ab3c 100644 --- a/drivers/net/wireless/iwmc3200wifi/debug.h +++ b/drivers/net/wireless/iwmc3200wifi/debug.h | |||
@@ -113,13 +113,10 @@ struct iwm_debugfs { | |||
113 | }; | 113 | }; |
114 | 114 | ||
115 | #ifdef CONFIG_IWM_DEBUG | 115 | #ifdef CONFIG_IWM_DEBUG |
116 | int iwm_debugfs_init(struct iwm_priv *iwm); | 116 | void iwm_debugfs_init(struct iwm_priv *iwm); |
117 | void iwm_debugfs_exit(struct iwm_priv *iwm); | 117 | void iwm_debugfs_exit(struct iwm_priv *iwm); |
118 | #else | 118 | #else |
119 | static inline int iwm_debugfs_init(struct iwm_priv *iwm) | 119 | static inline void iwm_debugfs_init(struct iwm_priv *iwm) {} |
120 | { | ||
121 | return 0; | ||
122 | } | ||
123 | static inline void iwm_debugfs_exit(struct iwm_priv *iwm) {} | 120 | static inline void iwm_debugfs_exit(struct iwm_priv *iwm) {} |
124 | #endif | 121 | #endif |
125 | 122 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c index 724441368a18..53b0b7711f02 100644 --- a/drivers/net/wireless/iwmc3200wifi/debugfs.c +++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c | |||
@@ -48,12 +48,11 @@ static struct { | |||
48 | 48 | ||
49 | #define add_dbg_module(dbg, name, id, initlevel) \ | 49 | #define add_dbg_module(dbg, name, id, initlevel) \ |
50 | do { \ | 50 | do { \ |
51 | struct dentry *d; \ | ||
52 | dbg.dbg_module[id] = (initlevel); \ | 51 | dbg.dbg_module[id] = (initlevel); \ |
53 | d = debugfs_create_x8(name, 0600, dbg.dbgdir, \ | 52 | dbg.dbg_module_dentries[id] = \ |
54 | &(dbg.dbg_module[id])); \ | 53 | debugfs_create_x8(name, 0600, \ |
55 | if (!IS_ERR(d)) \ | 54 | dbg.dbgdir, \ |
56 | dbg.dbg_module_dentries[id] = d; \ | 55 | &(dbg.dbg_module[id])); \ |
57 | } while (0) | 56 | } while (0) |
58 | 57 | ||
59 | static int iwm_debugfs_u32_read(void *data, u64 *val) | 58 | static int iwm_debugfs_u32_read(void *data, u64 *val) |
@@ -423,89 +422,29 @@ static const struct file_operations iwm_debugfs_fw_err_fops = { | |||
423 | .read = iwm_debugfs_fw_err_read, | 422 | .read = iwm_debugfs_fw_err_read, |
424 | }; | 423 | }; |
425 | 424 | ||
426 | int iwm_debugfs_init(struct iwm_priv *iwm) | 425 | void iwm_debugfs_init(struct iwm_priv *iwm) |
427 | { | 426 | { |
428 | int i, result; | 427 | int i; |
429 | char devdir[16]; | ||
430 | 428 | ||
431 | iwm->dbg.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); | 429 | iwm->dbg.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); |
432 | result = PTR_ERR(iwm->dbg.rootdir); | 430 | iwm->dbg.devdir = debugfs_create_dir(wiphy_name(iwm_to_wiphy(iwm)), |
433 | if (!result || IS_ERR(iwm->dbg.rootdir)) { | 431 | iwm->dbg.rootdir); |
434 | if (result == -ENODEV) { | ||
435 | IWM_ERR(iwm, "DebugFS (CONFIG_DEBUG_FS) not " | ||
436 | "enabled in kernel config\n"); | ||
437 | result = 0; /* No debugfs support */ | ||
438 | } | ||
439 | IWM_ERR(iwm, "Couldn't create rootdir: %d\n", result); | ||
440 | goto error; | ||
441 | } | ||
442 | |||
443 | snprintf(devdir, sizeof(devdir), "%s", wiphy_name(iwm_to_wiphy(iwm))); | ||
444 | |||
445 | iwm->dbg.devdir = debugfs_create_dir(devdir, iwm->dbg.rootdir); | ||
446 | result = PTR_ERR(iwm->dbg.devdir); | ||
447 | if (IS_ERR(iwm->dbg.devdir) && (result != -ENODEV)) { | ||
448 | IWM_ERR(iwm, "Couldn't create devdir: %d\n", result); | ||
449 | goto error; | ||
450 | } | ||
451 | |||
452 | iwm->dbg.dbgdir = debugfs_create_dir("debug", iwm->dbg.devdir); | 432 | iwm->dbg.dbgdir = debugfs_create_dir("debug", iwm->dbg.devdir); |
453 | result = PTR_ERR(iwm->dbg.dbgdir); | ||
454 | if (IS_ERR(iwm->dbg.dbgdir) && (result != -ENODEV)) { | ||
455 | IWM_ERR(iwm, "Couldn't create dbgdir: %d\n", result); | ||
456 | goto error; | ||
457 | } | ||
458 | |||
459 | iwm->dbg.rxdir = debugfs_create_dir("rx", iwm->dbg.devdir); | 433 | iwm->dbg.rxdir = debugfs_create_dir("rx", iwm->dbg.devdir); |
460 | result = PTR_ERR(iwm->dbg.rxdir); | ||
461 | if (IS_ERR(iwm->dbg.rxdir) && (result != -ENODEV)) { | ||
462 | IWM_ERR(iwm, "Couldn't create rx dir: %d\n", result); | ||
463 | goto error; | ||
464 | } | ||
465 | |||
466 | iwm->dbg.txdir = debugfs_create_dir("tx", iwm->dbg.devdir); | 434 | iwm->dbg.txdir = debugfs_create_dir("tx", iwm->dbg.devdir); |
467 | result = PTR_ERR(iwm->dbg.txdir); | ||
468 | if (IS_ERR(iwm->dbg.txdir) && (result != -ENODEV)) { | ||
469 | IWM_ERR(iwm, "Couldn't create tx dir: %d\n", result); | ||
470 | goto error; | ||
471 | } | ||
472 | |||
473 | iwm->dbg.busdir = debugfs_create_dir("bus", iwm->dbg.devdir); | 435 | iwm->dbg.busdir = debugfs_create_dir("bus", iwm->dbg.devdir); |
474 | result = PTR_ERR(iwm->dbg.busdir); | 436 | if (iwm->bus_ops->debugfs_init) |
475 | if (IS_ERR(iwm->dbg.busdir) && (result != -ENODEV)) { | 437 | iwm->bus_ops->debugfs_init(iwm, iwm->dbg.busdir); |
476 | IWM_ERR(iwm, "Couldn't create bus dir: %d\n", result); | ||
477 | goto error; | ||
478 | } | ||
479 | |||
480 | if (iwm->bus_ops->debugfs_init) { | ||
481 | result = iwm->bus_ops->debugfs_init(iwm, iwm->dbg.busdir); | ||
482 | if (result < 0) { | ||
483 | IWM_ERR(iwm, "Couldn't create bus entry: %d\n", result); | ||
484 | goto error; | ||
485 | } | ||
486 | } | ||
487 | |||
488 | 438 | ||
489 | iwm->dbg.dbg_level = IWM_DL_NONE; | 439 | iwm->dbg.dbg_level = IWM_DL_NONE; |
490 | iwm->dbg.dbg_level_dentry = | 440 | iwm->dbg.dbg_level_dentry = |
491 | debugfs_create_file("level", 0200, iwm->dbg.dbgdir, iwm, | 441 | debugfs_create_file("level", 0200, iwm->dbg.dbgdir, iwm, |
492 | &fops_iwm_dbg_level); | 442 | &fops_iwm_dbg_level); |
493 | result = PTR_ERR(iwm->dbg.dbg_level_dentry); | ||
494 | if (IS_ERR(iwm->dbg.dbg_level_dentry) && (result != -ENODEV)) { | ||
495 | IWM_ERR(iwm, "Couldn't create dbg_level: %d\n", result); | ||
496 | goto error; | ||
497 | } | ||
498 | |||
499 | 443 | ||
500 | iwm->dbg.dbg_modules = IWM_DM_DEFAULT; | 444 | iwm->dbg.dbg_modules = IWM_DM_DEFAULT; |
501 | iwm->dbg.dbg_modules_dentry = | 445 | iwm->dbg.dbg_modules_dentry = |
502 | debugfs_create_file("modules", 0200, iwm->dbg.dbgdir, iwm, | 446 | debugfs_create_file("modules", 0200, iwm->dbg.dbgdir, iwm, |
503 | &fops_iwm_dbg_modules); | 447 | &fops_iwm_dbg_modules); |
504 | result = PTR_ERR(iwm->dbg.dbg_modules_dentry); | ||
505 | if (IS_ERR(iwm->dbg.dbg_modules_dentry) && (result != -ENODEV)) { | ||
506 | IWM_ERR(iwm, "Couldn't create dbg_modules: %d\n", result); | ||
507 | goto error; | ||
508 | } | ||
509 | 448 | ||
510 | for (i = 0; i < __IWM_DM_NR; i++) | 449 | for (i = 0; i < __IWM_DM_NR; i++) |
511 | add_dbg_module(iwm->dbg, iwm_debug_module[i].name, | 450 | add_dbg_module(iwm->dbg, iwm_debug_module[i].name, |
@@ -514,44 +453,15 @@ int iwm_debugfs_init(struct iwm_priv *iwm) | |||
514 | iwm->dbg.txq_dentry = debugfs_create_file("queues", 0200, | 453 | iwm->dbg.txq_dentry = debugfs_create_file("queues", 0200, |
515 | iwm->dbg.txdir, iwm, | 454 | iwm->dbg.txdir, iwm, |
516 | &iwm_debugfs_txq_fops); | 455 | &iwm_debugfs_txq_fops); |
517 | result = PTR_ERR(iwm->dbg.txq_dentry); | ||
518 | if (IS_ERR(iwm->dbg.txq_dentry) && (result != -ENODEV)) { | ||
519 | IWM_ERR(iwm, "Couldn't create tx queue: %d\n", result); | ||
520 | goto error; | ||
521 | } | ||
522 | |||
523 | iwm->dbg.tx_credit_dentry = debugfs_create_file("credits", 0200, | 456 | iwm->dbg.tx_credit_dentry = debugfs_create_file("credits", 0200, |
524 | iwm->dbg.txdir, iwm, | 457 | iwm->dbg.txdir, iwm, |
525 | &iwm_debugfs_tx_credit_fops); | 458 | &iwm_debugfs_tx_credit_fops); |
526 | result = PTR_ERR(iwm->dbg.tx_credit_dentry); | ||
527 | if (IS_ERR(iwm->dbg.tx_credit_dentry) && (result != -ENODEV)) { | ||
528 | IWM_ERR(iwm, "Couldn't create tx credit: %d\n", result); | ||
529 | goto error; | ||
530 | } | ||
531 | |||
532 | iwm->dbg.rx_ticket_dentry = debugfs_create_file("tickets", 0200, | 459 | iwm->dbg.rx_ticket_dentry = debugfs_create_file("tickets", 0200, |
533 | iwm->dbg.rxdir, iwm, | 460 | iwm->dbg.rxdir, iwm, |
534 | &iwm_debugfs_rx_ticket_fops); | 461 | &iwm_debugfs_rx_ticket_fops); |
535 | result = PTR_ERR(iwm->dbg.rx_ticket_dentry); | ||
536 | if (IS_ERR(iwm->dbg.rx_ticket_dentry) && (result != -ENODEV)) { | ||
537 | IWM_ERR(iwm, "Couldn't create rx ticket: %d\n", result); | ||
538 | goto error; | ||
539 | } | ||
540 | |||
541 | iwm->dbg.fw_err_dentry = debugfs_create_file("last_fw_err", 0200, | 462 | iwm->dbg.fw_err_dentry = debugfs_create_file("last_fw_err", 0200, |
542 | iwm->dbg.dbgdir, iwm, | 463 | iwm->dbg.dbgdir, iwm, |
543 | &iwm_debugfs_fw_err_fops); | 464 | &iwm_debugfs_fw_err_fops); |
544 | result = PTR_ERR(iwm->dbg.fw_err_dentry); | ||
545 | if (IS_ERR(iwm->dbg.fw_err_dentry) && (result != -ENODEV)) { | ||
546 | IWM_ERR(iwm, "Couldn't create last FW err: %d\n", result); | ||
547 | goto error; | ||
548 | } | ||
549 | |||
550 | |||
551 | return 0; | ||
552 | |||
553 | error: | ||
554 | return result; | ||
555 | } | 465 | } |
556 | 466 | ||
557 | void iwm_debugfs_exit(struct iwm_priv *iwm) | 467 | void iwm_debugfs_exit(struct iwm_priv *iwm) |
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c index 1eafd6dec3fd..1acea37f39f8 100644 --- a/drivers/net/wireless/iwmc3200wifi/sdio.c +++ b/drivers/net/wireless/iwmc3200wifi/sdio.c | |||
@@ -366,21 +366,13 @@ static const struct file_operations iwm_debugfs_sdio_fops = { | |||
366 | .read = iwm_debugfs_sdio_read, | 366 | .read = iwm_debugfs_sdio_read, |
367 | }; | 367 | }; |
368 | 368 | ||
369 | static int if_sdio_debugfs_init(struct iwm_priv *iwm, struct dentry *parent_dir) | 369 | static void if_sdio_debugfs_init(struct iwm_priv *iwm, struct dentry *parent_dir) |
370 | { | 370 | { |
371 | int result; | ||
372 | struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm); | 371 | struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm); |
373 | 372 | ||
374 | hw->cccr_dentry = debugfs_create_file("cccr", 0200, | 373 | hw->cccr_dentry = debugfs_create_file("cccr", 0200, |
375 | parent_dir, iwm, | 374 | parent_dir, iwm, |
376 | &iwm_debugfs_sdio_fops); | 375 | &iwm_debugfs_sdio_fops); |
377 | result = PTR_ERR(hw->cccr_dentry); | ||
378 | if (IS_ERR(hw->cccr_dentry) && (result != -ENODEV)) { | ||
379 | IWM_ERR(iwm, "Couldn't create CCCR entry: %d\n", result); | ||
380 | return result; | ||
381 | } | ||
382 | |||
383 | return 0; | ||
384 | } | 376 | } |
385 | 377 | ||
386 | static void if_sdio_debugfs_exit(struct iwm_priv *iwm) | 378 | static void if_sdio_debugfs_exit(struct iwm_priv *iwm) |
@@ -440,11 +432,7 @@ static int iwm_sdio_probe(struct sdio_func *func, | |||
440 | hw = iwm_private(iwm); | 432 | hw = iwm_private(iwm); |
441 | hw->iwm = iwm; | 433 | hw->iwm = iwm; |
442 | 434 | ||
443 | ret = iwm_debugfs_init(iwm); | 435 | iwm_debugfs_init(iwm); |
444 | if (ret < 0) { | ||
445 | IWM_ERR(iwm, "Debugfs registration failed\n"); | ||
446 | goto if_free; | ||
447 | } | ||
448 | 436 | ||
449 | sdio_set_drvdata(func, hw); | 437 | sdio_set_drvdata(func, hw); |
450 | 438 | ||
@@ -473,7 +461,6 @@ static int iwm_sdio_probe(struct sdio_func *func, | |||
473 | destroy_workqueue(hw->isr_wq); | 461 | destroy_workqueue(hw->isr_wq); |
474 | debugfs_exit: | 462 | debugfs_exit: |
475 | iwm_debugfs_exit(iwm); | 463 | iwm_debugfs_exit(iwm); |
476 | if_free: | ||
477 | iwm_if_free(iwm); | 464 | iwm_if_free(iwm); |
478 | return ret; | 465 | return ret; |
479 | } | 466 | } |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 13dfeda742bc..64dd345d30f5 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -324,7 +324,9 @@ static int if_sdio_wait_status(struct if_sdio_card *card, const u8 condition) | |||
324 | timeout = jiffies + HZ; | 324 | timeout = jiffies + HZ; |
325 | while (1) { | 325 | while (1) { |
326 | status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); | 326 | status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); |
327 | if (ret || (status & condition)) | 327 | if (ret) |
328 | return ret; | ||
329 | if ((status & condition) == condition) | ||
328 | break; | 330 | break; |
329 | if (time_after(jiffies, timeout)) | 331 | if (time_after(jiffies, timeout)) |
330 | return -ETIMEDOUT; | 332 | return -ETIMEDOUT; |
diff --git a/drivers/net/wireless/libertas_tf/cmd.c b/drivers/net/wireless/libertas_tf/cmd.c index b620daf59ef7..8945afd6ce3e 100644 --- a/drivers/net/wireless/libertas_tf/cmd.c +++ b/drivers/net/wireless/libertas_tf/cmd.c | |||
@@ -7,6 +7,8 @@ | |||
7 | * the Free Software Foundation; either version 2 of the License, or (at | 7 | * the Free Software Foundation; either version 2 of the License, or (at |
8 | * your option) any later version. | 8 | * your option) any later version. |
9 | */ | 9 | */ |
10 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
11 | |||
10 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
11 | 13 | ||
12 | #include "libertas_tf.h" | 14 | #include "libertas_tf.h" |
@@ -82,6 +84,8 @@ int lbtf_update_hw_spec(struct lbtf_private *priv) | |||
82 | int ret = -1; | 84 | int ret = -1; |
83 | u32 i; | 85 | u32 i; |
84 | 86 | ||
87 | lbtf_deb_enter(LBTF_DEB_CMD); | ||
88 | |||
85 | memset(&cmd, 0, sizeof(cmd)); | 89 | memset(&cmd, 0, sizeof(cmd)); |
86 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | 90 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); |
87 | memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN); | 91 | memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN); |
@@ -104,6 +108,8 @@ int lbtf_update_hw_spec(struct lbtf_private *priv) | |||
104 | priv->fwrelease >> 8 & 0xff, | 108 | priv->fwrelease >> 8 & 0xff, |
105 | priv->fwrelease & 0xff, | 109 | priv->fwrelease & 0xff, |
106 | priv->fwcapinfo); | 110 | priv->fwcapinfo); |
111 | lbtf_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n", | ||
112 | cmd.hwifversion, cmd.version); | ||
107 | 113 | ||
108 | /* Clamp region code to 8-bit since FW spec indicates that it should | 114 | /* Clamp region code to 8-bit since FW spec indicates that it should |
109 | * only ever be 8-bit, even though the field size is 16-bit. Some | 115 | * only ever be 8-bit, even though the field size is 16-bit. Some |
@@ -118,8 +124,10 @@ int lbtf_update_hw_spec(struct lbtf_private *priv) | |||
118 | } | 124 | } |
119 | 125 | ||
120 | /* if it's unidentified region code, use the default (USA) */ | 126 | /* if it's unidentified region code, use the default (USA) */ |
121 | if (i >= MRVDRV_MAX_REGION_CODE) | 127 | if (i >= MRVDRV_MAX_REGION_CODE) { |
122 | priv->regioncode = 0x10; | 128 | priv->regioncode = 0x10; |
129 | pr_info("unidentified region code; using the default (USA)\n"); | ||
130 | } | ||
123 | 131 | ||
124 | if (priv->current_addr[0] == 0xff) | 132 | if (priv->current_addr[0] == 0xff) |
125 | memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN); | 133 | memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN); |
@@ -128,6 +136,7 @@ int lbtf_update_hw_spec(struct lbtf_private *priv) | |||
128 | 136 | ||
129 | lbtf_geo_init(priv); | 137 | lbtf_geo_init(priv); |
130 | out: | 138 | out: |
139 | lbtf_deb_leave(LBTF_DEB_CMD); | ||
131 | return ret; | 140 | return ret; |
132 | } | 141 | } |
133 | 142 | ||
@@ -141,13 +150,18 @@ out: | |||
141 | */ | 150 | */ |
142 | int lbtf_set_channel(struct lbtf_private *priv, u8 channel) | 151 | int lbtf_set_channel(struct lbtf_private *priv, u8 channel) |
143 | { | 152 | { |
153 | int ret = 0; | ||
144 | struct cmd_ds_802_11_rf_channel cmd; | 154 | struct cmd_ds_802_11_rf_channel cmd; |
145 | 155 | ||
156 | lbtf_deb_enter(LBTF_DEB_CMD); | ||
157 | |||
146 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | 158 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); |
147 | cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET); | 159 | cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET); |
148 | cmd.channel = cpu_to_le16(channel); | 160 | cmd.channel = cpu_to_le16(channel); |
149 | 161 | ||
150 | return lbtf_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd); | 162 | ret = lbtf_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd); |
163 | lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret); | ||
164 | return ret; | ||
151 | } | 165 | } |
152 | 166 | ||
153 | int lbtf_beacon_set(struct lbtf_private *priv, struct sk_buff *beacon) | 167 | int lbtf_beacon_set(struct lbtf_private *priv, struct sk_buff *beacon) |
@@ -155,20 +169,28 @@ int lbtf_beacon_set(struct lbtf_private *priv, struct sk_buff *beacon) | |||
155 | struct cmd_ds_802_11_beacon_set cmd; | 169 | struct cmd_ds_802_11_beacon_set cmd; |
156 | int size; | 170 | int size; |
157 | 171 | ||
158 | if (beacon->len > MRVL_MAX_BCN_SIZE) | 172 | lbtf_deb_enter(LBTF_DEB_CMD); |
173 | |||
174 | if (beacon->len > MRVL_MAX_BCN_SIZE) { | ||
175 | lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", -1); | ||
159 | return -1; | 176 | return -1; |
177 | } | ||
160 | size = sizeof(cmd) - sizeof(cmd.beacon) + beacon->len; | 178 | size = sizeof(cmd) - sizeof(cmd.beacon) + beacon->len; |
161 | cmd.hdr.size = cpu_to_le16(size); | 179 | cmd.hdr.size = cpu_to_le16(size); |
162 | cmd.len = cpu_to_le16(beacon->len); | 180 | cmd.len = cpu_to_le16(beacon->len); |
163 | memcpy(cmd.beacon, (u8 *) beacon->data, beacon->len); | 181 | memcpy(cmd.beacon, (u8 *) beacon->data, beacon->len); |
164 | 182 | ||
165 | lbtf_cmd_async(priv, CMD_802_11_BEACON_SET, &cmd.hdr, size); | 183 | lbtf_cmd_async(priv, CMD_802_11_BEACON_SET, &cmd.hdr, size); |
184 | |||
185 | lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", 0); | ||
166 | return 0; | 186 | return 0; |
167 | } | 187 | } |
168 | 188 | ||
169 | int lbtf_beacon_ctrl(struct lbtf_private *priv, bool beacon_enable, | 189 | int lbtf_beacon_ctrl(struct lbtf_private *priv, bool beacon_enable, |
170 | int beacon_int) { | 190 | int beacon_int) |
191 | { | ||
171 | struct cmd_ds_802_11_beacon_control cmd; | 192 | struct cmd_ds_802_11_beacon_control cmd; |
193 | lbtf_deb_enter(LBTF_DEB_CMD); | ||
172 | 194 | ||
173 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | 195 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); |
174 | cmd.action = cpu_to_le16(CMD_ACT_SET); | 196 | cmd.action = cpu_to_le16(CMD_ACT_SET); |
@@ -176,6 +198,8 @@ int lbtf_beacon_ctrl(struct lbtf_private *priv, bool beacon_enable, | |||
176 | cmd.beacon_period = cpu_to_le16(beacon_int); | 198 | cmd.beacon_period = cpu_to_le16(beacon_int); |
177 | 199 | ||
178 | lbtf_cmd_async(priv, CMD_802_11_BEACON_CTRL, &cmd.hdr, sizeof(cmd)); | 200 | lbtf_cmd_async(priv, CMD_802_11_BEACON_CTRL, &cmd.hdr, sizeof(cmd)); |
201 | |||
202 | lbtf_deb_leave(LBTF_DEB_CMD); | ||
179 | return 0; | 203 | return 0; |
180 | } | 204 | } |
181 | 205 | ||
@@ -183,17 +207,28 @@ static void lbtf_queue_cmd(struct lbtf_private *priv, | |||
183 | struct cmd_ctrl_node *cmdnode) | 207 | struct cmd_ctrl_node *cmdnode) |
184 | { | 208 | { |
185 | unsigned long flags; | 209 | unsigned long flags; |
210 | lbtf_deb_enter(LBTF_DEB_HOST); | ||
186 | 211 | ||
187 | if (!cmdnode) | 212 | if (!cmdnode) { |
188 | return; | 213 | lbtf_deb_host("QUEUE_CMD: cmdnode is NULL\n"); |
214 | goto qcmd_done; | ||
215 | } | ||
189 | 216 | ||
190 | if (!cmdnode->cmdbuf->size) | 217 | if (!cmdnode->cmdbuf->size) { |
191 | return; | 218 | lbtf_deb_host("DNLD_CMD: cmd size is zero\n"); |
219 | goto qcmd_done; | ||
220 | } | ||
192 | 221 | ||
193 | cmdnode->result = 0; | 222 | cmdnode->result = 0; |
194 | spin_lock_irqsave(&priv->driver_lock, flags); | 223 | spin_lock_irqsave(&priv->driver_lock, flags); |
195 | list_add_tail(&cmdnode->list, &priv->cmdpendingq); | 224 | list_add_tail(&cmdnode->list, &priv->cmdpendingq); |
196 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 225 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
226 | |||
227 | lbtf_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n", | ||
228 | le16_to_cpu(cmdnode->cmdbuf->command)); | ||
229 | |||
230 | qcmd_done: | ||
231 | lbtf_deb_leave(LBTF_DEB_HOST); | ||
197 | } | 232 | } |
198 | 233 | ||
199 | static void lbtf_submit_command(struct lbtf_private *priv, | 234 | static void lbtf_submit_command(struct lbtf_private *priv, |
@@ -206,22 +241,33 @@ static void lbtf_submit_command(struct lbtf_private *priv, | |||
206 | int timeo = 5 * HZ; | 241 | int timeo = 5 * HZ; |
207 | int ret; | 242 | int ret; |
208 | 243 | ||
244 | lbtf_deb_enter(LBTF_DEB_HOST); | ||
245 | |||
209 | cmd = cmdnode->cmdbuf; | 246 | cmd = cmdnode->cmdbuf; |
210 | 247 | ||
211 | spin_lock_irqsave(&priv->driver_lock, flags); | 248 | spin_lock_irqsave(&priv->driver_lock, flags); |
212 | priv->cur_cmd = cmdnode; | 249 | priv->cur_cmd = cmdnode; |
213 | cmdsize = le16_to_cpu(cmd->size); | 250 | cmdsize = le16_to_cpu(cmd->size); |
214 | command = le16_to_cpu(cmd->command); | 251 | command = le16_to_cpu(cmd->command); |
252 | |||
253 | lbtf_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n", | ||
254 | command, le16_to_cpu(cmd->seqnum), cmdsize); | ||
255 | lbtf_deb_hex(LBTF_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize); | ||
256 | |||
215 | ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); | 257 | ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); |
216 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 258 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
217 | 259 | ||
218 | if (ret) | 260 | if (ret) { |
261 | pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret); | ||
219 | /* Let the timer kick in and retry, and potentially reset | 262 | /* Let the timer kick in and retry, and potentially reset |
220 | the whole thing if the condition persists */ | 263 | the whole thing if the condition persists */ |
221 | timeo = HZ; | 264 | timeo = HZ; |
265 | } | ||
222 | 266 | ||
223 | /* Setup the timer after transmit command */ | 267 | /* Setup the timer after transmit command */ |
224 | mod_timer(&priv->command_timer, jiffies + timeo); | 268 | mod_timer(&priv->command_timer, jiffies + timeo); |
269 | |||
270 | lbtf_deb_leave(LBTF_DEB_HOST); | ||
225 | } | 271 | } |
226 | 272 | ||
227 | /** | 273 | /** |
@@ -231,8 +277,10 @@ static void lbtf_submit_command(struct lbtf_private *priv, | |||
231 | static void __lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv, | 277 | static void __lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv, |
232 | struct cmd_ctrl_node *cmdnode) | 278 | struct cmd_ctrl_node *cmdnode) |
233 | { | 279 | { |
280 | lbtf_deb_enter(LBTF_DEB_HOST); | ||
281 | |||
234 | if (!cmdnode) | 282 | if (!cmdnode) |
235 | return; | 283 | goto cl_ins_out; |
236 | 284 | ||
237 | cmdnode->callback = NULL; | 285 | cmdnode->callback = NULL; |
238 | cmdnode->callback_arg = 0; | 286 | cmdnode->callback_arg = 0; |
@@ -240,6 +288,9 @@ static void __lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv, | |||
240 | memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE); | 288 | memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE); |
241 | 289 | ||
242 | list_add_tail(&cmdnode->list, &priv->cmdfreeq); | 290 | list_add_tail(&cmdnode->list, &priv->cmdfreeq); |
291 | |||
292 | cl_ins_out: | ||
293 | lbtf_deb_leave(LBTF_DEB_HOST); | ||
243 | } | 294 | } |
244 | 295 | ||
245 | static void lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv, | 296 | static void lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv, |
@@ -268,29 +319,41 @@ int lbtf_cmd_set_mac_multicast_addr(struct lbtf_private *priv) | |||
268 | { | 319 | { |
269 | struct cmd_ds_mac_multicast_addr cmd; | 320 | struct cmd_ds_mac_multicast_addr cmd; |
270 | 321 | ||
322 | lbtf_deb_enter(LBTF_DEB_CMD); | ||
323 | |||
271 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | 324 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); |
272 | cmd.action = cpu_to_le16(CMD_ACT_SET); | 325 | cmd.action = cpu_to_le16(CMD_ACT_SET); |
273 | 326 | ||
274 | cmd.nr_of_adrs = cpu_to_le16((u16) priv->nr_of_multicastmacaddr); | 327 | cmd.nr_of_adrs = cpu_to_le16((u16) priv->nr_of_multicastmacaddr); |
328 | |||
329 | lbtf_deb_cmd("MULTICAST_ADR: setting %d addresses\n", cmd.nr_of_adrs); | ||
330 | |||
275 | memcpy(cmd.maclist, priv->multicastlist, | 331 | memcpy(cmd.maclist, priv->multicastlist, |
276 | priv->nr_of_multicastmacaddr * ETH_ALEN); | 332 | priv->nr_of_multicastmacaddr * ETH_ALEN); |
277 | 333 | ||
278 | lbtf_cmd_async(priv, CMD_MAC_MULTICAST_ADR, &cmd.hdr, sizeof(cmd)); | 334 | lbtf_cmd_async(priv, CMD_MAC_MULTICAST_ADR, &cmd.hdr, sizeof(cmd)); |
335 | |||
336 | lbtf_deb_leave(LBTF_DEB_CMD); | ||
279 | return 0; | 337 | return 0; |
280 | } | 338 | } |
281 | 339 | ||
282 | void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode) | 340 | void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode) |
283 | { | 341 | { |
284 | struct cmd_ds_set_mode cmd; | 342 | struct cmd_ds_set_mode cmd; |
343 | lbtf_deb_enter(LBTF_DEB_WEXT); | ||
285 | 344 | ||
286 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | 345 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); |
287 | cmd.mode = cpu_to_le16(mode); | 346 | cmd.mode = cpu_to_le16(mode); |
347 | lbtf_deb_wext("Switching to mode: 0x%x\n", mode); | ||
288 | lbtf_cmd_async(priv, CMD_802_11_SET_MODE, &cmd.hdr, sizeof(cmd)); | 348 | lbtf_cmd_async(priv, CMD_802_11_SET_MODE, &cmd.hdr, sizeof(cmd)); |
349 | |||
350 | lbtf_deb_leave(LBTF_DEB_WEXT); | ||
289 | } | 351 | } |
290 | 352 | ||
291 | void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid) | 353 | void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid) |
292 | { | 354 | { |
293 | struct cmd_ds_set_bssid cmd; | 355 | struct cmd_ds_set_bssid cmd; |
356 | lbtf_deb_enter(LBTF_DEB_CMD); | ||
294 | 357 | ||
295 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | 358 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); |
296 | cmd.activate = activate ? 1 : 0; | 359 | cmd.activate = activate ? 1 : 0; |
@@ -298,11 +361,13 @@ void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid) | |||
298 | memcpy(cmd.bssid, bssid, ETH_ALEN); | 361 | memcpy(cmd.bssid, bssid, ETH_ALEN); |
299 | 362 | ||
300 | lbtf_cmd_async(priv, CMD_802_11_SET_BSSID, &cmd.hdr, sizeof(cmd)); | 363 | lbtf_cmd_async(priv, CMD_802_11_SET_BSSID, &cmd.hdr, sizeof(cmd)); |
364 | lbtf_deb_leave(LBTF_DEB_CMD); | ||
301 | } | 365 | } |
302 | 366 | ||
303 | int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr) | 367 | int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr) |
304 | { | 368 | { |
305 | struct cmd_ds_802_11_mac_address cmd; | 369 | struct cmd_ds_802_11_mac_address cmd; |
370 | lbtf_deb_enter(LBTF_DEB_CMD); | ||
306 | 371 | ||
307 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | 372 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); |
308 | cmd.action = cpu_to_le16(CMD_ACT_SET); | 373 | cmd.action = cpu_to_le16(CMD_ACT_SET); |
@@ -310,6 +375,7 @@ int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr) | |||
310 | memcpy(cmd.macadd, mac_addr, ETH_ALEN); | 375 | memcpy(cmd.macadd, mac_addr, ETH_ALEN); |
311 | 376 | ||
312 | lbtf_cmd_async(priv, CMD_802_11_MAC_ADDRESS, &cmd.hdr, sizeof(cmd)); | 377 | lbtf_cmd_async(priv, CMD_802_11_MAC_ADDRESS, &cmd.hdr, sizeof(cmd)); |
378 | lbtf_deb_leave(LBTF_DEB_CMD); | ||
313 | return 0; | 379 | return 0; |
314 | } | 380 | } |
315 | 381 | ||
@@ -318,6 +384,8 @@ int lbtf_set_radio_control(struct lbtf_private *priv) | |||
318 | int ret = 0; | 384 | int ret = 0; |
319 | struct cmd_ds_802_11_radio_control cmd; | 385 | struct cmd_ds_802_11_radio_control cmd; |
320 | 386 | ||
387 | lbtf_deb_enter(LBTF_DEB_CMD); | ||
388 | |||
321 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | 389 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); |
322 | cmd.action = cpu_to_le16(CMD_ACT_SET); | 390 | cmd.action = cpu_to_le16(CMD_ACT_SET); |
323 | 391 | ||
@@ -341,19 +409,28 @@ int lbtf_set_radio_control(struct lbtf_private *priv) | |||
341 | else | 409 | else |
342 | cmd.control &= cpu_to_le16(~TURN_ON_RF); | 410 | cmd.control &= cpu_to_le16(~TURN_ON_RF); |
343 | 411 | ||
412 | lbtf_deb_cmd("RADIO_SET: radio %d, preamble %d\n", priv->radioon, | ||
413 | priv->preamble); | ||
414 | |||
344 | ret = lbtf_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd); | 415 | ret = lbtf_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd); |
416 | |||
417 | lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret); | ||
345 | return ret; | 418 | return ret; |
346 | } | 419 | } |
347 | 420 | ||
348 | void lbtf_set_mac_control(struct lbtf_private *priv) | 421 | void lbtf_set_mac_control(struct lbtf_private *priv) |
349 | { | 422 | { |
350 | struct cmd_ds_mac_control cmd; | 423 | struct cmd_ds_mac_control cmd; |
424 | lbtf_deb_enter(LBTF_DEB_CMD); | ||
425 | |||
351 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); | 426 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); |
352 | cmd.action = cpu_to_le16(priv->mac_control); | 427 | cmd.action = cpu_to_le16(priv->mac_control); |
353 | cmd.reserved = 0; | 428 | cmd.reserved = 0; |
354 | 429 | ||
355 | lbtf_cmd_async(priv, CMD_MAC_CONTROL, | 430 | lbtf_cmd_async(priv, CMD_MAC_CONTROL, |
356 | &cmd.hdr, sizeof(cmd)); | 431 | &cmd.hdr, sizeof(cmd)); |
432 | |||
433 | lbtf_deb_leave(LBTF_DEB_CMD); | ||
357 | } | 434 | } |
358 | 435 | ||
359 | /** | 436 | /** |
@@ -365,29 +442,43 @@ void lbtf_set_mac_control(struct lbtf_private *priv) | |||
365 | */ | 442 | */ |
366 | int lbtf_allocate_cmd_buffer(struct lbtf_private *priv) | 443 | int lbtf_allocate_cmd_buffer(struct lbtf_private *priv) |
367 | { | 444 | { |
445 | int ret = 0; | ||
368 | u32 bufsize; | 446 | u32 bufsize; |
369 | u32 i; | 447 | u32 i; |
370 | struct cmd_ctrl_node *cmdarray; | 448 | struct cmd_ctrl_node *cmdarray; |
371 | 449 | ||
450 | lbtf_deb_enter(LBTF_DEB_HOST); | ||
451 | |||
372 | /* Allocate and initialize the command array */ | 452 | /* Allocate and initialize the command array */ |
373 | bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS; | 453 | bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS; |
374 | cmdarray = kzalloc(bufsize, GFP_KERNEL); | 454 | cmdarray = kzalloc(bufsize, GFP_KERNEL); |
375 | if (!cmdarray) | 455 | if (!cmdarray) { |
376 | return -1; | 456 | lbtf_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n"); |
457 | ret = -1; | ||
458 | goto done; | ||
459 | } | ||
377 | priv->cmd_array = cmdarray; | 460 | priv->cmd_array = cmdarray; |
378 | 461 | ||
379 | /* Allocate and initialize each command buffer in the command array */ | 462 | /* Allocate and initialize each command buffer in the command array */ |
380 | for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { | 463 | for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { |
381 | cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL); | 464 | cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL); |
382 | if (!cmdarray[i].cmdbuf) | 465 | if (!cmdarray[i].cmdbuf) { |
383 | return -1; | 466 | lbtf_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n"); |
467 | ret = -1; | ||
468 | goto done; | ||
469 | } | ||
384 | } | 470 | } |
385 | 471 | ||
386 | for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { | 472 | for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { |
387 | init_waitqueue_head(&cmdarray[i].cmdwait_q); | 473 | init_waitqueue_head(&cmdarray[i].cmdwait_q); |
388 | lbtf_cleanup_and_insert_cmd(priv, &cmdarray[i]); | 474 | lbtf_cleanup_and_insert_cmd(priv, &cmdarray[i]); |
389 | } | 475 | } |
390 | return 0; | 476 | |
477 | ret = 0; | ||
478 | |||
479 | done: | ||
480 | lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %d", ret); | ||
481 | return ret; | ||
391 | } | 482 | } |
392 | 483 | ||
393 | /** | 484 | /** |
@@ -402,9 +493,13 @@ int lbtf_free_cmd_buffer(struct lbtf_private *priv) | |||
402 | struct cmd_ctrl_node *cmdarray; | 493 | struct cmd_ctrl_node *cmdarray; |
403 | unsigned int i; | 494 | unsigned int i; |
404 | 495 | ||
496 | lbtf_deb_enter(LBTF_DEB_HOST); | ||
497 | |||
405 | /* need to check if cmd array is allocated or not */ | 498 | /* need to check if cmd array is allocated or not */ |
406 | if (priv->cmd_array == NULL) | 499 | if (priv->cmd_array == NULL) { |
407 | return 0; | 500 | lbtf_deb_host("FREE_CMD_BUF: cmd_array is NULL\n"); |
501 | goto done; | ||
502 | } | ||
408 | 503 | ||
409 | cmdarray = priv->cmd_array; | 504 | cmdarray = priv->cmd_array; |
410 | 505 | ||
@@ -418,6 +513,8 @@ int lbtf_free_cmd_buffer(struct lbtf_private *priv) | |||
418 | kfree(priv->cmd_array); | 513 | kfree(priv->cmd_array); |
419 | priv->cmd_array = NULL; | 514 | priv->cmd_array = NULL; |
420 | 515 | ||
516 | done: | ||
517 | lbtf_deb_leave(LBTF_DEB_HOST); | ||
421 | return 0; | 518 | return 0; |
422 | } | 519 | } |
423 | 520 | ||
@@ -433,6 +530,8 @@ static struct cmd_ctrl_node *lbtf_get_cmd_ctrl_node(struct lbtf_private *priv) | |||
433 | struct cmd_ctrl_node *tempnode; | 530 | struct cmd_ctrl_node *tempnode; |
434 | unsigned long flags; | 531 | unsigned long flags; |
435 | 532 | ||
533 | lbtf_deb_enter(LBTF_DEB_HOST); | ||
534 | |||
436 | if (!priv) | 535 | if (!priv) |
437 | return NULL; | 536 | return NULL; |
438 | 537 | ||
@@ -442,11 +541,14 @@ static struct cmd_ctrl_node *lbtf_get_cmd_ctrl_node(struct lbtf_private *priv) | |||
442 | tempnode = list_first_entry(&priv->cmdfreeq, | 541 | tempnode = list_first_entry(&priv->cmdfreeq, |
443 | struct cmd_ctrl_node, list); | 542 | struct cmd_ctrl_node, list); |
444 | list_del(&tempnode->list); | 543 | list_del(&tempnode->list); |
445 | } else | 544 | } else { |
545 | lbtf_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n"); | ||
446 | tempnode = NULL; | 546 | tempnode = NULL; |
547 | } | ||
447 | 548 | ||
448 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 549 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
449 | 550 | ||
551 | lbtf_deb_leave(LBTF_DEB_HOST); | ||
450 | return tempnode; | 552 | return tempnode; |
451 | } | 553 | } |
452 | 554 | ||
@@ -462,16 +564,20 @@ int lbtf_execute_next_command(struct lbtf_private *priv) | |||
462 | struct cmd_ctrl_node *cmdnode = NULL; | 564 | struct cmd_ctrl_node *cmdnode = NULL; |
463 | struct cmd_header *cmd; | 565 | struct cmd_header *cmd; |
464 | unsigned long flags; | 566 | unsigned long flags; |
567 | int ret = 0; | ||
465 | 568 | ||
466 | /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the | 569 | /* Debug group is lbtf_deb_THREAD and not lbtf_deb_HOST, because the |
467 | * only caller to us is lbtf_thread() and we get even when a | 570 | * only caller to us is lbtf_thread() and we get even when a |
468 | * data packet is received */ | 571 | * data packet is received */ |
572 | lbtf_deb_enter(LBTF_DEB_THREAD); | ||
469 | 573 | ||
470 | spin_lock_irqsave(&priv->driver_lock, flags); | 574 | spin_lock_irqsave(&priv->driver_lock, flags); |
471 | 575 | ||
472 | if (priv->cur_cmd) { | 576 | if (priv->cur_cmd) { |
577 | pr_alert("EXEC_NEXT_CMD: already processing command!\n"); | ||
473 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 578 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
474 | return -1; | 579 | ret = -1; |
580 | goto done; | ||
475 | } | 581 | } |
476 | 582 | ||
477 | if (!list_empty(&priv->cmdpendingq)) { | 583 | if (!list_empty(&priv->cmdpendingq)) { |
@@ -483,11 +589,17 @@ int lbtf_execute_next_command(struct lbtf_private *priv) | |||
483 | cmd = cmdnode->cmdbuf; | 589 | cmd = cmdnode->cmdbuf; |
484 | 590 | ||
485 | list_del(&cmdnode->list); | 591 | list_del(&cmdnode->list); |
592 | lbtf_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n", | ||
593 | le16_to_cpu(cmd->command)); | ||
486 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 594 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
487 | lbtf_submit_command(priv, cmdnode); | 595 | lbtf_submit_command(priv, cmdnode); |
488 | } else | 596 | } else |
489 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 597 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
490 | return 0; | 598 | |
599 | ret = 0; | ||
600 | done: | ||
601 | lbtf_deb_leave(LBTF_DEB_THREAD); | ||
602 | return ret; | ||
491 | } | 603 | } |
492 | 604 | ||
493 | static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv, | 605 | static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv, |
@@ -498,14 +610,22 @@ static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv, | |||
498 | { | 610 | { |
499 | struct cmd_ctrl_node *cmdnode; | 611 | struct cmd_ctrl_node *cmdnode; |
500 | 612 | ||
501 | if (priv->surpriseremoved) | 613 | lbtf_deb_enter(LBTF_DEB_HOST); |
502 | return ERR_PTR(-ENOENT); | 614 | |
615 | if (priv->surpriseremoved) { | ||
616 | lbtf_deb_host("PREP_CMD: card removed\n"); | ||
617 | cmdnode = ERR_PTR(-ENOENT); | ||
618 | goto done; | ||
619 | } | ||
503 | 620 | ||
504 | cmdnode = lbtf_get_cmd_ctrl_node(priv); | 621 | cmdnode = lbtf_get_cmd_ctrl_node(priv); |
505 | if (cmdnode == NULL) { | 622 | if (cmdnode == NULL) { |
623 | lbtf_deb_host("PREP_CMD: cmdnode is NULL\n"); | ||
624 | |||
506 | /* Wake up main thread to execute next command */ | 625 | /* Wake up main thread to execute next command */ |
507 | queue_work(lbtf_wq, &priv->cmd_work); | 626 | queue_work(lbtf_wq, &priv->cmd_work); |
508 | return ERR_PTR(-ENOBUFS); | 627 | cmdnode = ERR_PTR(-ENOBUFS); |
628 | goto done; | ||
509 | } | 629 | } |
510 | 630 | ||
511 | cmdnode->callback = callback; | 631 | cmdnode->callback = callback; |
@@ -520,17 +640,24 @@ static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv, | |||
520 | cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); | 640 | cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); |
521 | cmdnode->cmdbuf->seqnum = cpu_to_le16(priv->seqnum); | 641 | cmdnode->cmdbuf->seqnum = cpu_to_le16(priv->seqnum); |
522 | cmdnode->cmdbuf->result = 0; | 642 | cmdnode->cmdbuf->result = 0; |
643 | |||
644 | lbtf_deb_host("PREP_CMD: command 0x%04x\n", command); | ||
645 | |||
523 | cmdnode->cmdwaitqwoken = 0; | 646 | cmdnode->cmdwaitqwoken = 0; |
524 | lbtf_queue_cmd(priv, cmdnode); | 647 | lbtf_queue_cmd(priv, cmdnode); |
525 | queue_work(lbtf_wq, &priv->cmd_work); | 648 | queue_work(lbtf_wq, &priv->cmd_work); |
526 | 649 | ||
650 | done: | ||
651 | lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %p", cmdnode); | ||
527 | return cmdnode; | 652 | return cmdnode; |
528 | } | 653 | } |
529 | 654 | ||
530 | void lbtf_cmd_async(struct lbtf_private *priv, uint16_t command, | 655 | void lbtf_cmd_async(struct lbtf_private *priv, uint16_t command, |
531 | struct cmd_header *in_cmd, int in_cmd_size) | 656 | struct cmd_header *in_cmd, int in_cmd_size) |
532 | { | 657 | { |
658 | lbtf_deb_enter(LBTF_DEB_CMD); | ||
533 | __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size, NULL, 0); | 659 | __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size, NULL, 0); |
660 | lbtf_deb_leave(LBTF_DEB_CMD); | ||
534 | } | 661 | } |
535 | 662 | ||
536 | int __lbtf_cmd(struct lbtf_private *priv, uint16_t command, | 663 | int __lbtf_cmd(struct lbtf_private *priv, uint16_t command, |
@@ -543,30 +670,35 @@ int __lbtf_cmd(struct lbtf_private *priv, uint16_t command, | |||
543 | unsigned long flags; | 670 | unsigned long flags; |
544 | int ret = 0; | 671 | int ret = 0; |
545 | 672 | ||
673 | lbtf_deb_enter(LBTF_DEB_HOST); | ||
674 | |||
546 | cmdnode = __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size, | 675 | cmdnode = __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size, |
547 | callback, callback_arg); | 676 | callback, callback_arg); |
548 | if (IS_ERR(cmdnode)) | 677 | if (IS_ERR(cmdnode)) { |
549 | return PTR_ERR(cmdnode); | 678 | ret = PTR_ERR(cmdnode); |
679 | goto done; | ||
680 | } | ||
550 | 681 | ||
551 | might_sleep(); | 682 | might_sleep(); |
552 | ret = wait_event_interruptible(cmdnode->cmdwait_q, | 683 | ret = wait_event_interruptible(cmdnode->cmdwait_q, |
553 | cmdnode->cmdwaitqwoken); | 684 | cmdnode->cmdwaitqwoken); |
554 | if (ret) { | 685 | if (ret) { |
555 | printk(KERN_DEBUG | 686 | pr_info("PREP_CMD: command 0x%04x interrupted by signal: %d\n", |
556 | "libertastf: command 0x%04x interrupted by signal", | 687 | command, ret); |
557 | command); | 688 | goto done; |
558 | return ret; | ||
559 | } | 689 | } |
560 | 690 | ||
561 | spin_lock_irqsave(&priv->driver_lock, flags); | 691 | spin_lock_irqsave(&priv->driver_lock, flags); |
562 | ret = cmdnode->result; | 692 | ret = cmdnode->result; |
563 | if (ret) | 693 | if (ret) |
564 | printk(KERN_DEBUG "libertastf: command 0x%04x failed: %d\n", | 694 | pr_info("PREP_CMD: command 0x%04x failed: %d\n", |
565 | command, ret); | 695 | command, ret); |
566 | 696 | ||
567 | __lbtf_cleanup_and_insert_cmd(priv, cmdnode); | 697 | __lbtf_cleanup_and_insert_cmd(priv, cmdnode); |
568 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 698 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
569 | 699 | ||
700 | done: | ||
701 | lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %d", ret); | ||
570 | return ret; | 702 | return ret; |
571 | } | 703 | } |
572 | EXPORT_SYMBOL_GPL(__lbtf_cmd); | 704 | EXPORT_SYMBOL_GPL(__lbtf_cmd); |
@@ -587,6 +719,8 @@ int lbtf_process_rx_command(struct lbtf_private *priv) | |||
587 | unsigned long flags; | 719 | unsigned long flags; |
588 | uint16_t result; | 720 | uint16_t result; |
589 | 721 | ||
722 | lbtf_deb_enter(LBTF_DEB_CMD); | ||
723 | |||
590 | mutex_lock(&priv->lock); | 724 | mutex_lock(&priv->lock); |
591 | spin_lock_irqsave(&priv->driver_lock, flags); | 725 | spin_lock_irqsave(&priv->driver_lock, flags); |
592 | 726 | ||
@@ -602,7 +736,7 @@ int lbtf_process_rx_command(struct lbtf_private *priv) | |||
602 | result = le16_to_cpu(resp->result); | 736 | result = le16_to_cpu(resp->result); |
603 | 737 | ||
604 | if (net_ratelimit()) | 738 | if (net_ratelimit()) |
605 | printk(KERN_DEBUG "libertastf: cmd response 0x%04x, seq %d, size %d\n", | 739 | pr_info("libertastf: cmd response 0x%04x, seq %d, size %d\n", |
606 | respcmd, le16_to_cpu(resp->seqnum), | 740 | respcmd, le16_to_cpu(resp->seqnum), |
607 | le16_to_cpu(resp->size)); | 741 | le16_to_cpu(resp->size)); |
608 | 742 | ||
@@ -639,7 +773,7 @@ int lbtf_process_rx_command(struct lbtf_private *priv) | |||
639 | switch (respcmd) { | 773 | switch (respcmd) { |
640 | case CMD_RET(CMD_GET_HW_SPEC): | 774 | case CMD_RET(CMD_GET_HW_SPEC): |
641 | case CMD_RET(CMD_802_11_RESET): | 775 | case CMD_RET(CMD_802_11_RESET): |
642 | printk(KERN_DEBUG "libertastf: reset failed\n"); | 776 | pr_info("libertastf: reset failed\n"); |
643 | break; | 777 | break; |
644 | 778 | ||
645 | } | 779 | } |
@@ -666,5 +800,6 @@ int lbtf_process_rx_command(struct lbtf_private *priv) | |||
666 | 800 | ||
667 | done: | 801 | done: |
668 | mutex_unlock(&priv->lock); | 802 | mutex_unlock(&priv->lock); |
803 | lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret); | ||
669 | return ret; | 804 | return ret; |
670 | } | 805 | } |
diff --git a/drivers/net/wireless/libertas_tf/deb_defs.h b/drivers/net/wireless/libertas_tf/deb_defs.h new file mode 100644 index 000000000000..ae753962d8b5 --- /dev/null +++ b/drivers/net/wireless/libertas_tf/deb_defs.h | |||
@@ -0,0 +1,104 @@ | |||
1 | /** | ||
2 | * This header file contains global constant/enum definitions, | ||
3 | * global variable declaration. | ||
4 | */ | ||
5 | #ifndef _LBS_DEB_DEFS_H_ | ||
6 | #define _LBS_DEB_EFS_H_ | ||
7 | |||
8 | #ifndef DRV_NAME | ||
9 | #define DRV_NAME "libertas_tf" | ||
10 | #endif | ||
11 | |||
12 | #include <linux/spinlock.h> | ||
13 | |||
14 | #ifdef CONFIG_LIBERTAS_THINFIRM_DEBUG | ||
15 | #define DEBUG | ||
16 | #define PROC_DEBUG | ||
17 | #endif | ||
18 | |||
19 | #define LBTF_DEB_ENTER 0x00000001 | ||
20 | #define LBTF_DEB_LEAVE 0x00000002 | ||
21 | #define LBTF_DEB_MAIN 0x00000004 | ||
22 | #define LBTF_DEB_NET 0x00000008 | ||
23 | #define LBTF_DEB_MESH 0x00000010 | ||
24 | #define LBTF_DEB_WEXT 0x00000020 | ||
25 | #define LBTF_DEB_IOCTL 0x00000040 | ||
26 | #define LBTF_DEB_SCAN 0x00000080 | ||
27 | #define LBTF_DEB_ASSOC 0x00000100 | ||
28 | #define LBTF_DEB_JOIN 0x00000200 | ||
29 | #define LBTF_DEB_11D 0x00000400 | ||
30 | #define LBTF_DEB_DEBUGFS 0x00000800 | ||
31 | #define LBTF_DEB_ETHTOOL 0x00001000 | ||
32 | #define LBTF_DEB_HOST 0x00002000 | ||
33 | #define LBTF_DEB_CMD 0x00004000 | ||
34 | #define LBTF_DEB_RX 0x00008000 | ||
35 | #define LBTF_DEB_TX 0x00010000 | ||
36 | #define LBTF_DEB_USB 0x00020000 | ||
37 | #define LBTF_DEB_CS 0x00040000 | ||
38 | #define LBTF_DEB_FW 0x00080000 | ||
39 | #define LBTF_DEB_THREAD 0x00100000 | ||
40 | #define LBTF_DEB_HEX 0x00200000 | ||
41 | #define LBTF_DEB_SDIO 0x00400000 | ||
42 | #define LBTF_DEB_MACOPS 0x00800000 | ||
43 | |||
44 | extern unsigned int lbtf_debug; | ||
45 | |||
46 | |||
47 | #ifdef DEBUG | ||
48 | #define LBTF_DEB_LL(grp, grpnam, fmt, args...) \ | ||
49 | do { if ((lbtf_debug & (grp)) == (grp)) \ | ||
50 | printk(KERN_DEBUG DRV_NAME grpnam "%s: " fmt, \ | ||
51 | in_interrupt() ? " (INT)" : "", ## args); } while (0) | ||
52 | #else | ||
53 | #define LBTF_DEB_LL(grp, grpnam, fmt, args...) do {} while (0) | ||
54 | #endif | ||
55 | |||
56 | #define lbtf_deb_enter(grp) \ | ||
57 | LBTF_DEB_LL(grp | LBTF_DEB_ENTER, " enter", "%s()\n", __func__); | ||
58 | #define lbtf_deb_enter_args(grp, fmt, args...) \ | ||
59 | LBTF_DEB_LL(grp | LBTF_DEB_ENTER, " enter", "%s(" fmt ")\n", __func__, ## args); | ||
60 | #define lbtf_deb_leave(grp) \ | ||
61 | LBTF_DEB_LL(grp | LBTF_DEB_LEAVE, " leave", "%s()\n", __func__); | ||
62 | #define lbtf_deb_leave_args(grp, fmt, args...) \ | ||
63 | LBTF_DEB_LL(grp | LBTF_DEB_LEAVE, " leave", "%s(), " fmt "\n", \ | ||
64 | __func__, ##args); | ||
65 | #define lbtf_deb_main(fmt, args...) LBTF_DEB_LL(LBTF_DEB_MAIN, " main", fmt, ##args) | ||
66 | #define lbtf_deb_net(fmt, args...) LBTF_DEB_LL(LBTF_DEB_NET, " net", fmt, ##args) | ||
67 | #define lbtf_deb_mesh(fmt, args...) LBTF_DEB_LL(LBTF_DEB_MESH, " mesh", fmt, ##args) | ||
68 | #define lbtf_deb_wext(fmt, args...) LBTF_DEB_LL(LBTF_DEB_WEXT, " wext", fmt, ##args) | ||
69 | #define lbtf_deb_ioctl(fmt, args...) LBTF_DEB_LL(LBTF_DEB_IOCTL, " ioctl", fmt, ##args) | ||
70 | #define lbtf_deb_scan(fmt, args...) LBTF_DEB_LL(LBTF_DEB_SCAN, " scan", fmt, ##args) | ||
71 | #define lbtf_deb_assoc(fmt, args...) LBTF_DEB_LL(LBTF_DEB_ASSOC, " assoc", fmt, ##args) | ||
72 | #define lbtf_deb_join(fmt, args...) LBTF_DEB_LL(LBTF_DEB_JOIN, " join", fmt, ##args) | ||
73 | #define lbtf_deb_11d(fmt, args...) LBTF_DEB_LL(LBTF_DEB_11D, " 11d", fmt, ##args) | ||
74 | #define lbtf_deb_debugfs(fmt, args...) LBTF_DEB_LL(LBTF_DEB_DEBUGFS, " debugfs", fmt, ##args) | ||
75 | #define lbtf_deb_ethtool(fmt, args...) LBTF_DEB_LL(LBTF_DEB_ETHTOOL, " ethtool", fmt, ##args) | ||
76 | #define lbtf_deb_host(fmt, args...) LBTF_DEB_LL(LBTF_DEB_HOST, " host", fmt, ##args) | ||
77 | #define lbtf_deb_cmd(fmt, args...) LBTF_DEB_LL(LBTF_DEB_CMD, " cmd", fmt, ##args) | ||
78 | #define lbtf_deb_rx(fmt, args...) LBTF_DEB_LL(LBTF_DEB_RX, " rx", fmt, ##args) | ||
79 | #define lbtf_deb_tx(fmt, args...) LBTF_DEB_LL(LBTF_DEB_TX, " tx", fmt, ##args) | ||
80 | #define lbtf_deb_fw(fmt, args...) LBTF_DEB_LL(LBTF_DEB_FW, " fw", fmt, ##args) | ||
81 | #define lbtf_deb_usb(fmt, args...) LBTF_DEB_LL(LBTF_DEB_USB, " usb", fmt, ##args) | ||
82 | #define lbtf_deb_usbd(dev, fmt, args...) LBTF_DEB_LL(LBTF_DEB_USB, " usbd", "%s:" fmt, dev_name(dev), ##args) | ||
83 | #define lbtf_deb_cs(fmt, args...) LBTF_DEB_LL(LBTF_DEB_CS, " cs", fmt, ##args) | ||
84 | #define lbtf_deb_thread(fmt, args...) LBTF_DEB_LL(LBTF_DEB_THREAD, " thread", fmt, ##args) | ||
85 | #define lbtf_deb_sdio(fmt, args...) LBTF_DEB_LL(LBTF_DEB_SDIO, " thread", fmt, ##args) | ||
86 | #define lbtf_deb_macops(fmt, args...) LBTF_DEB_LL(LBTF_DEB_MACOPS, " thread", fmt, ##args) | ||
87 | |||
88 | #ifdef DEBUG | ||
89 | static inline void lbtf_deb_hex(unsigned int grp, const char *prompt, u8 *buf, int len) | ||
90 | { | ||
91 | char newprompt[32]; | ||
92 | |||
93 | if (len && | ||
94 | (lbtf_debug & LBTF_DEB_HEX) && | ||
95 | (lbtf_debug & grp)) { | ||
96 | snprintf(newprompt, sizeof(newprompt), DRV_NAME " %s: ", prompt); | ||
97 | print_hex_dump_bytes(prompt, DUMP_PREFIX_NONE, buf, len); | ||
98 | } | ||
99 | } | ||
100 | #else | ||
101 | #define lbtf_deb_hex(grp, prompt, buf, len) do {} while (0) | ||
102 | #endif | ||
103 | |||
104 | #endif | ||
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index 8cc9db60c14b..4412c279ca94 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c | |||
@@ -7,6 +7,13 @@ | |||
7 | * the Free Software Foundation; either version 2 of the License, or (at | 7 | * the Free Software Foundation; either version 2 of the License, or (at |
8 | * your option) any later version. | 8 | * your option) any later version. |
9 | */ | 9 | */ |
10 | #define DRV_NAME "lbtf_usb" | ||
11 | |||
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
13 | |||
14 | #include "libertas_tf.h" | ||
15 | #include "if_usb.h" | ||
16 | |||
10 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
11 | #include <linux/moduleparam.h> | 18 | #include <linux/moduleparam.h> |
12 | #include <linux/firmware.h> | 19 | #include <linux/firmware.h> |
@@ -14,10 +21,8 @@ | |||
14 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
15 | #include <linux/usb.h> | 22 | #include <linux/usb.h> |
16 | 23 | ||
17 | #define DRV_NAME "lbtf_usb" | 24 | #define INSANEDEBUG 0 |
18 | 25 | #define lbtf_deb_usb2(...) do { if (INSANEDEBUG) lbtf_deb_usbd(__VA_ARGS__); } while (0) | |
19 | #include "libertas_tf.h" | ||
20 | #include "if_usb.h" | ||
21 | 26 | ||
22 | #define MESSAGE_HEADER_LEN 4 | 27 | #define MESSAGE_HEADER_LEN 4 |
23 | 28 | ||
@@ -53,9 +58,14 @@ static int if_usb_reset_device(struct if_usb_card *cardp); | |||
53 | */ | 58 | */ |
54 | static void if_usb_write_bulk_callback(struct urb *urb) | 59 | static void if_usb_write_bulk_callback(struct urb *urb) |
55 | { | 60 | { |
56 | if (urb->status != 0) | 61 | if (urb->status != 0) { |
57 | printk(KERN_INFO "libertastf: URB in failure status: %d\n", | 62 | /* print the failure status number for debug */ |
58 | urb->status); | 63 | pr_info("URB in failure status: %d\n", urb->status); |
64 | } else { | ||
65 | lbtf_deb_usb2(&urb->dev->dev, "URB status is successful\n"); | ||
66 | lbtf_deb_usb2(&urb->dev->dev, "Actual length transmitted %d\n", | ||
67 | urb->actual_length); | ||
68 | } | ||
59 | } | 69 | } |
60 | 70 | ||
61 | /** | 71 | /** |
@@ -65,6 +75,8 @@ static void if_usb_write_bulk_callback(struct urb *urb) | |||
65 | */ | 75 | */ |
66 | static void if_usb_free(struct if_usb_card *cardp) | 76 | static void if_usb_free(struct if_usb_card *cardp) |
67 | { | 77 | { |
78 | lbtf_deb_enter(LBTF_DEB_USB); | ||
79 | |||
68 | /* Unlink tx & rx urb */ | 80 | /* Unlink tx & rx urb */ |
69 | usb_kill_urb(cardp->tx_urb); | 81 | usb_kill_urb(cardp->tx_urb); |
70 | usb_kill_urb(cardp->rx_urb); | 82 | usb_kill_urb(cardp->rx_urb); |
@@ -81,6 +93,8 @@ static void if_usb_free(struct if_usb_card *cardp) | |||
81 | 93 | ||
82 | kfree(cardp->ep_out_buf); | 94 | kfree(cardp->ep_out_buf); |
83 | cardp->ep_out_buf = NULL; | 95 | cardp->ep_out_buf = NULL; |
96 | |||
97 | lbtf_deb_leave(LBTF_DEB_USB); | ||
84 | } | 98 | } |
85 | 99 | ||
86 | static void if_usb_setup_firmware(struct lbtf_private *priv) | 100 | static void if_usb_setup_firmware(struct lbtf_private *priv) |
@@ -88,23 +102,33 @@ static void if_usb_setup_firmware(struct lbtf_private *priv) | |||
88 | struct if_usb_card *cardp = priv->card; | 102 | struct if_usb_card *cardp = priv->card; |
89 | struct cmd_ds_set_boot2_ver b2_cmd; | 103 | struct cmd_ds_set_boot2_ver b2_cmd; |
90 | 104 | ||
105 | lbtf_deb_enter(LBTF_DEB_USB); | ||
106 | |||
91 | if_usb_submit_rx_urb(cardp); | 107 | if_usb_submit_rx_urb(cardp); |
92 | b2_cmd.hdr.size = cpu_to_le16(sizeof(b2_cmd)); | 108 | b2_cmd.hdr.size = cpu_to_le16(sizeof(b2_cmd)); |
93 | b2_cmd.action = 0; | 109 | b2_cmd.action = 0; |
94 | b2_cmd.version = cardp->boot2_version; | 110 | b2_cmd.version = cardp->boot2_version; |
95 | 111 | ||
96 | if (lbtf_cmd_with_response(priv, CMD_SET_BOOT2_VER, &b2_cmd)) | 112 | if (lbtf_cmd_with_response(priv, CMD_SET_BOOT2_VER, &b2_cmd)) |
97 | printk(KERN_INFO "libertastf: setting boot2 version failed\n"); | 113 | lbtf_deb_usb("Setting boot2 version failed\n"); |
114 | |||
115 | lbtf_deb_leave(LBTF_DEB_USB); | ||
98 | } | 116 | } |
99 | 117 | ||
100 | static void if_usb_fw_timeo(unsigned long priv) | 118 | static void if_usb_fw_timeo(unsigned long priv) |
101 | { | 119 | { |
102 | struct if_usb_card *cardp = (void *)priv; | 120 | struct if_usb_card *cardp = (void *)priv; |
103 | 121 | ||
104 | if (!cardp->fwdnldover) | 122 | lbtf_deb_enter(LBTF_DEB_USB); |
123 | if (!cardp->fwdnldover) { | ||
105 | /* Download timed out */ | 124 | /* Download timed out */ |
106 | cardp->priv->surpriseremoved = 1; | 125 | cardp->priv->surpriseremoved = 1; |
126 | pr_err("Download timed out\n"); | ||
127 | } else { | ||
128 | lbtf_deb_usb("Download complete, no event. Assuming success\n"); | ||
129 | } | ||
107 | wake_up(&cardp->fw_wq); | 130 | wake_up(&cardp->fw_wq); |
131 | lbtf_deb_leave(LBTF_DEB_USB); | ||
108 | } | 132 | } |
109 | 133 | ||
110 | /** | 134 | /** |
@@ -125,11 +149,14 @@ static int if_usb_probe(struct usb_interface *intf, | |||
125 | struct if_usb_card *cardp; | 149 | struct if_usb_card *cardp; |
126 | int i; | 150 | int i; |
127 | 151 | ||
152 | lbtf_deb_enter(LBTF_DEB_USB); | ||
128 | udev = interface_to_usbdev(intf); | 153 | udev = interface_to_usbdev(intf); |
129 | 154 | ||
130 | cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); | 155 | cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); |
131 | if (!cardp) | 156 | if (!cardp) { |
157 | pr_err("Out of memory allocating private data.\n"); | ||
132 | goto error; | 158 | goto error; |
159 | } | ||
133 | 160 | ||
134 | setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp); | 161 | setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp); |
135 | init_waitqueue_head(&cardp->fw_wq); | 162 | init_waitqueue_head(&cardp->fw_wq); |
@@ -137,38 +164,62 @@ static int if_usb_probe(struct usb_interface *intf, | |||
137 | cardp->udev = udev; | 164 | cardp->udev = udev; |
138 | iface_desc = intf->cur_altsetting; | 165 | iface_desc = intf->cur_altsetting; |
139 | 166 | ||
167 | lbtf_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X" | ||
168 | " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n", | ||
169 | le16_to_cpu(udev->descriptor.bcdUSB), | ||
170 | udev->descriptor.bDeviceClass, | ||
171 | udev->descriptor.bDeviceSubClass, | ||
172 | udev->descriptor.bDeviceProtocol); | ||
173 | |||
140 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | 174 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { |
141 | endpoint = &iface_desc->endpoint[i].desc; | 175 | endpoint = &iface_desc->endpoint[i].desc; |
142 | if (usb_endpoint_is_bulk_in(endpoint)) { | 176 | if (usb_endpoint_is_bulk_in(endpoint)) { |
143 | cardp->ep_in_size = | 177 | cardp->ep_in_size = |
144 | le16_to_cpu(endpoint->wMaxPacketSize); | 178 | le16_to_cpu(endpoint->wMaxPacketSize); |
145 | cardp->ep_in = usb_endpoint_num(endpoint); | 179 | cardp->ep_in = usb_endpoint_num(endpoint); |
180 | |||
181 | lbtf_deb_usbd(&udev->dev, "in_endpoint = %d\n", cardp->ep_in); | ||
182 | lbtf_deb_usbd(&udev->dev, "Bulk in size is %d\n", cardp->ep_in_size); | ||
146 | } else if (usb_endpoint_is_bulk_out(endpoint)) { | 183 | } else if (usb_endpoint_is_bulk_out(endpoint)) { |
147 | cardp->ep_out_size = | 184 | cardp->ep_out_size = |
148 | le16_to_cpu(endpoint->wMaxPacketSize); | 185 | le16_to_cpu(endpoint->wMaxPacketSize); |
149 | cardp->ep_out = usb_endpoint_num(endpoint); | 186 | cardp->ep_out = usb_endpoint_num(endpoint); |
187 | |||
188 | lbtf_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out); | ||
189 | lbtf_deb_usbd(&udev->dev, "Bulk out size is %d\n", | ||
190 | cardp->ep_out_size); | ||
150 | } | 191 | } |
151 | } | 192 | } |
152 | if (!cardp->ep_out_size || !cardp->ep_in_size) | 193 | if (!cardp->ep_out_size || !cardp->ep_in_size) { |
194 | lbtf_deb_usbd(&udev->dev, "Endpoints not found\n"); | ||
153 | /* Endpoints not found */ | 195 | /* Endpoints not found */ |
154 | goto dealloc; | 196 | goto dealloc; |
197 | } | ||
155 | 198 | ||
156 | cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL); | 199 | cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL); |
157 | if (!cardp->rx_urb) | 200 | if (!cardp->rx_urb) { |
201 | lbtf_deb_usbd(&udev->dev, "Rx URB allocation failed\n"); | ||
158 | goto dealloc; | 202 | goto dealloc; |
203 | } | ||
159 | 204 | ||
160 | cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL); | 205 | cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL); |
161 | if (!cardp->tx_urb) | 206 | if (!cardp->tx_urb) { |
207 | lbtf_deb_usbd(&udev->dev, "Tx URB allocation failed\n"); | ||
162 | goto dealloc; | 208 | goto dealloc; |
209 | } | ||
163 | 210 | ||
164 | cardp->cmd_urb = usb_alloc_urb(0, GFP_KERNEL); | 211 | cardp->cmd_urb = usb_alloc_urb(0, GFP_KERNEL); |
165 | if (!cardp->cmd_urb) | 212 | if (!cardp->cmd_urb) { |
213 | lbtf_deb_usbd(&udev->dev, "Cmd URB allocation failed\n"); | ||
166 | goto dealloc; | 214 | goto dealloc; |
215 | } | ||
167 | 216 | ||
168 | cardp->ep_out_buf = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, | 217 | cardp->ep_out_buf = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, |
169 | GFP_KERNEL); | 218 | GFP_KERNEL); |
170 | if (!cardp->ep_out_buf) | 219 | if (!cardp->ep_out_buf) { |
220 | lbtf_deb_usbd(&udev->dev, "Could not allocate buffer\n"); | ||
171 | goto dealloc; | 221 | goto dealloc; |
222 | } | ||
172 | 223 | ||
173 | priv = lbtf_add_card(cardp, &udev->dev); | 224 | priv = lbtf_add_card(cardp, &udev->dev); |
174 | if (!priv) | 225 | if (!priv) |
@@ -189,6 +240,7 @@ static int if_usb_probe(struct usb_interface *intf, | |||
189 | dealloc: | 240 | dealloc: |
190 | if_usb_free(cardp); | 241 | if_usb_free(cardp); |
191 | error: | 242 | error: |
243 | lbtf_deb_leave(LBTF_DEB_MAIN); | ||
192 | return -ENOMEM; | 244 | return -ENOMEM; |
193 | } | 245 | } |
194 | 246 | ||
@@ -202,6 +254,8 @@ static void if_usb_disconnect(struct usb_interface *intf) | |||
202 | struct if_usb_card *cardp = usb_get_intfdata(intf); | 254 | struct if_usb_card *cardp = usb_get_intfdata(intf); |
203 | struct lbtf_private *priv = (struct lbtf_private *) cardp->priv; | 255 | struct lbtf_private *priv = (struct lbtf_private *) cardp->priv; |
204 | 256 | ||
257 | lbtf_deb_enter(LBTF_DEB_MAIN); | ||
258 | |||
205 | if_usb_reset_device(cardp); | 259 | if_usb_reset_device(cardp); |
206 | 260 | ||
207 | if (priv) | 261 | if (priv) |
@@ -212,6 +266,8 @@ static void if_usb_disconnect(struct usb_interface *intf) | |||
212 | 266 | ||
213 | usb_set_intfdata(intf, NULL); | 267 | usb_set_intfdata(intf, NULL); |
214 | usb_put_dev(interface_to_usbdev(intf)); | 268 | usb_put_dev(interface_to_usbdev(intf)); |
269 | |||
270 | lbtf_deb_leave(LBTF_DEB_MAIN); | ||
215 | } | 271 | } |
216 | 272 | ||
217 | /** | 273 | /** |
@@ -226,6 +282,8 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp) | |||
226 | struct fwdata *fwdata = cardp->ep_out_buf; | 282 | struct fwdata *fwdata = cardp->ep_out_buf; |
227 | u8 *firmware = (u8 *) cardp->fw->data; | 283 | u8 *firmware = (u8 *) cardp->fw->data; |
228 | 284 | ||
285 | lbtf_deb_enter(LBTF_DEB_FW); | ||
286 | |||
229 | /* If we got a CRC failure on the last block, back | 287 | /* If we got a CRC failure on the last block, back |
230 | up and retry it */ | 288 | up and retry it */ |
231 | if (!cardp->CRC_OK) { | 289 | if (!cardp->CRC_OK) { |
@@ -233,6 +291,9 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp) | |||
233 | cardp->fwseqnum--; | 291 | cardp->fwseqnum--; |
234 | } | 292 | } |
235 | 293 | ||
294 | lbtf_deb_usb2(&cardp->udev->dev, "totalbytes = %d\n", | ||
295 | cardp->totalbytes); | ||
296 | |||
236 | /* struct fwdata (which we sent to the card) has an | 297 | /* struct fwdata (which we sent to the card) has an |
237 | extra __le32 field in between the header and the data, | 298 | extra __le32 field in between the header and the data, |
238 | which is not in the struct fwheader in the actual | 299 | which is not in the struct fwheader in the actual |
@@ -246,18 +307,33 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp) | |||
246 | memcpy(fwdata->data, &firmware[cardp->totalbytes], | 307 | memcpy(fwdata->data, &firmware[cardp->totalbytes], |
247 | le32_to_cpu(fwdata->hdr.datalength)); | 308 | le32_to_cpu(fwdata->hdr.datalength)); |
248 | 309 | ||
310 | lbtf_deb_usb2(&cardp->udev->dev, "Data length = %d\n", | ||
311 | le32_to_cpu(fwdata->hdr.datalength)); | ||
312 | |||
249 | fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum); | 313 | fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum); |
250 | cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength); | 314 | cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength); |
251 | 315 | ||
252 | usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) + | 316 | usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) + |
253 | le32_to_cpu(fwdata->hdr.datalength), 0); | 317 | le32_to_cpu(fwdata->hdr.datalength), 0); |
254 | 318 | ||
255 | if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) | 319 | if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) { |
320 | lbtf_deb_usb2(&cardp->udev->dev, "There are data to follow\n"); | ||
321 | lbtf_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n", | ||
322 | cardp->fwseqnum, cardp->totalbytes); | ||
323 | } else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) { | ||
324 | lbtf_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n"); | ||
325 | lbtf_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n"); | ||
326 | |||
256 | /* Host has finished FW downloading | 327 | /* Host has finished FW downloading |
257 | * Donwloading FW JUMP BLOCK | 328 | * Donwloading FW JUMP BLOCK |
258 | */ | 329 | */ |
259 | cardp->fwfinalblk = 1; | 330 | cardp->fwfinalblk = 1; |
331 | } | ||
260 | 332 | ||
333 | lbtf_deb_usb2(&cardp->udev->dev, "Firmware download done; size %d\n", | ||
334 | cardp->totalbytes); | ||
335 | |||
336 | lbtf_deb_leave(LBTF_DEB_FW); | ||
261 | return 0; | 337 | return 0; |
262 | } | 338 | } |
263 | 339 | ||
@@ -266,6 +342,8 @@ static int if_usb_reset_device(struct if_usb_card *cardp) | |||
266 | struct cmd_ds_802_11_reset *cmd = cardp->ep_out_buf + 4; | 342 | struct cmd_ds_802_11_reset *cmd = cardp->ep_out_buf + 4; |
267 | int ret; | 343 | int ret; |
268 | 344 | ||
345 | lbtf_deb_enter(LBTF_DEB_USB); | ||
346 | |||
269 | *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST); | 347 | *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST); |
270 | 348 | ||
271 | cmd->hdr.command = cpu_to_le16(CMD_802_11_RESET); | 349 | cmd->hdr.command = cpu_to_le16(CMD_802_11_RESET); |
@@ -280,6 +358,8 @@ static int if_usb_reset_device(struct if_usb_card *cardp) | |||
280 | ret = usb_reset_device(cardp->udev); | 358 | ret = usb_reset_device(cardp->udev); |
281 | msleep(100); | 359 | msleep(100); |
282 | 360 | ||
361 | lbtf_deb_leave_args(LBTF_DEB_USB, "ret %d", ret); | ||
362 | |||
283 | return ret; | 363 | return ret; |
284 | } | 364 | } |
285 | EXPORT_SYMBOL_GPL(if_usb_reset_device); | 365 | EXPORT_SYMBOL_GPL(if_usb_reset_device); |
@@ -297,11 +377,15 @@ EXPORT_SYMBOL_GPL(if_usb_reset_device); | |||
297 | static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, | 377 | static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, |
298 | uint16_t nb, u8 data) | 378 | uint16_t nb, u8 data) |
299 | { | 379 | { |
380 | int ret = -1; | ||
300 | struct urb *urb; | 381 | struct urb *urb; |
301 | 382 | ||
383 | lbtf_deb_enter(LBTF_DEB_USB); | ||
302 | /* check if device is removed */ | 384 | /* check if device is removed */ |
303 | if (cardp->priv->surpriseremoved) | 385 | if (cardp->priv->surpriseremoved) { |
304 | return -1; | 386 | lbtf_deb_usbd(&cardp->udev->dev, "Device removed\n"); |
387 | goto tx_ret; | ||
388 | } | ||
305 | 389 | ||
306 | if (data) | 390 | if (data) |
307 | urb = cardp->tx_urb; | 391 | urb = cardp->tx_urb; |
@@ -315,19 +399,34 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, | |||
315 | 399 | ||
316 | urb->transfer_flags |= URB_ZERO_PACKET; | 400 | urb->transfer_flags |= URB_ZERO_PACKET; |
317 | 401 | ||
318 | if (usb_submit_urb(urb, GFP_ATOMIC)) | 402 | if (usb_submit_urb(urb, GFP_ATOMIC)) { |
319 | return -1; | 403 | lbtf_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret); |
320 | return 0; | 404 | goto tx_ret; |
405 | } | ||
406 | |||
407 | lbtf_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n"); | ||
408 | |||
409 | ret = 0; | ||
410 | |||
411 | tx_ret: | ||
412 | lbtf_deb_leave(LBTF_DEB_USB); | ||
413 | return ret; | ||
321 | } | 414 | } |
322 | 415 | ||
323 | static int __if_usb_submit_rx_urb(struct if_usb_card *cardp, | 416 | static int __if_usb_submit_rx_urb(struct if_usb_card *cardp, |
324 | void (*callbackfn)(struct urb *urb)) | 417 | void (*callbackfn)(struct urb *urb)) |
325 | { | 418 | { |
326 | struct sk_buff *skb; | 419 | struct sk_buff *skb; |
420 | int ret = -1; | ||
421 | |||
422 | lbtf_deb_enter(LBTF_DEB_USB); | ||
327 | 423 | ||
328 | skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE); | 424 | skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE); |
329 | if (!skb) | 425 | if (!skb) { |
426 | pr_err("No free skb\n"); | ||
427 | lbtf_deb_leave(LBTF_DEB_USB); | ||
330 | return -1; | 428 | return -1; |
429 | } | ||
331 | 430 | ||
332 | cardp->rx_skb = skb; | 431 | cardp->rx_skb = skb; |
333 | 432 | ||
@@ -339,12 +438,19 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp, | |||
339 | 438 | ||
340 | cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET; | 439 | cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET; |
341 | 440 | ||
342 | if (usb_submit_urb(cardp->rx_urb, GFP_ATOMIC)) { | 441 | lbtf_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); |
442 | ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC); | ||
443 | if (ret) { | ||
444 | lbtf_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret); | ||
343 | kfree_skb(skb); | 445 | kfree_skb(skb); |
344 | cardp->rx_skb = NULL; | 446 | cardp->rx_skb = NULL; |
447 | lbtf_deb_leave(LBTF_DEB_USB); | ||
345 | return -1; | 448 | return -1; |
346 | } else | 449 | } else { |
450 | lbtf_deb_usb2(&cardp->udev->dev, "Submit Rx URB success\n"); | ||
451 | lbtf_deb_leave(LBTF_DEB_USB); | ||
347 | return 0; | 452 | return 0; |
453 | } | ||
348 | } | 454 | } |
349 | 455 | ||
350 | static int if_usb_submit_rx_urb_fwload(struct if_usb_card *cardp) | 456 | static int if_usb_submit_rx_urb_fwload(struct if_usb_card *cardp) |
@@ -364,8 +470,12 @@ static void if_usb_receive_fwload(struct urb *urb) | |||
364 | struct fwsyncheader *syncfwheader; | 470 | struct fwsyncheader *syncfwheader; |
365 | struct bootcmdresp bcmdresp; | 471 | struct bootcmdresp bcmdresp; |
366 | 472 | ||
473 | lbtf_deb_enter(LBTF_DEB_USB); | ||
367 | if (urb->status) { | 474 | if (urb->status) { |
475 | lbtf_deb_usbd(&cardp->udev->dev, | ||
476 | "URB status is failed during fw load\n"); | ||
368 | kfree_skb(skb); | 477 | kfree_skb(skb); |
478 | lbtf_deb_leave(LBTF_DEB_USB); | ||
369 | return; | 479 | return; |
370 | } | 480 | } |
371 | 481 | ||
@@ -373,12 +483,17 @@ static void if_usb_receive_fwload(struct urb *urb) | |||
373 | __le32 *tmp = (__le32 *)(skb->data); | 483 | __le32 *tmp = (__le32 *)(skb->data); |
374 | 484 | ||
375 | if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) && | 485 | if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) && |
376 | tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) | 486 | tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) { |
377 | /* Firmware ready event received */ | 487 | /* Firmware ready event received */ |
488 | pr_info("Firmware ready event received\n"); | ||
378 | wake_up(&cardp->fw_wq); | 489 | wake_up(&cardp->fw_wq); |
379 | else | 490 | } else { |
491 | lbtf_deb_usb("Waiting for confirmation; got %x %x\n", | ||
492 | le32_to_cpu(tmp[0]), le32_to_cpu(tmp[1])); | ||
380 | if_usb_submit_rx_urb_fwload(cardp); | 493 | if_usb_submit_rx_urb_fwload(cardp); |
494 | } | ||
381 | kfree_skb(skb); | 495 | kfree_skb(skb); |
496 | lbtf_deb_leave(LBTF_DEB_USB); | ||
382 | return; | 497 | return; |
383 | } | 498 | } |
384 | if (cardp->bootcmdresp <= 0) { | 499 | if (cardp->bootcmdresp <= 0) { |
@@ -389,34 +504,60 @@ static void if_usb_receive_fwload(struct urb *urb) | |||
389 | if_usb_submit_rx_urb_fwload(cardp); | 504 | if_usb_submit_rx_urb_fwload(cardp); |
390 | cardp->bootcmdresp = 1; | 505 | cardp->bootcmdresp = 1; |
391 | /* Received valid boot command response */ | 506 | /* Received valid boot command response */ |
507 | lbtf_deb_usbd(&cardp->udev->dev, | ||
508 | "Received valid boot command response\n"); | ||
509 | lbtf_deb_leave(LBTF_DEB_USB); | ||
392 | return; | 510 | return; |
393 | } | 511 | } |
394 | if (bcmdresp.magic != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) { | 512 | if (bcmdresp.magic != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) { |
395 | if (bcmdresp.magic == cpu_to_le32(CMD_TYPE_REQUEST) || | 513 | if (bcmdresp.magic == cpu_to_le32(CMD_TYPE_REQUEST) || |
396 | bcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) || | 514 | bcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) || |
397 | bcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) | 515 | bcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) { |
516 | if (!cardp->bootcmdresp) | ||
517 | pr_info("Firmware already seems alive; resetting\n"); | ||
398 | cardp->bootcmdresp = -1; | 518 | cardp->bootcmdresp = -1; |
399 | } else if (bcmdresp.cmd == BOOT_CMD_FW_BY_USB && | 519 | } else { |
400 | bcmdresp.result == BOOT_CMD_RESP_OK) | 520 | pr_info("boot cmd response wrong magic number (0x%x)\n", |
521 | le32_to_cpu(bcmdresp.magic)); | ||
522 | } | ||
523 | } else if (bcmdresp.cmd != BOOT_CMD_FW_BY_USB) { | ||
524 | pr_info("boot cmd response cmd_tag error (%d)\n", | ||
525 | bcmdresp.cmd); | ||
526 | } else if (bcmdresp.result != BOOT_CMD_RESP_OK) { | ||
527 | pr_info("boot cmd response result error (%d)\n", | ||
528 | bcmdresp.result); | ||
529 | } else { | ||
401 | cardp->bootcmdresp = 1; | 530 | cardp->bootcmdresp = 1; |
531 | lbtf_deb_usbd(&cardp->udev->dev, | ||
532 | "Received valid boot command response\n"); | ||
533 | } | ||
402 | 534 | ||
403 | kfree_skb(skb); | 535 | kfree_skb(skb); |
404 | if_usb_submit_rx_urb_fwload(cardp); | 536 | if_usb_submit_rx_urb_fwload(cardp); |
537 | lbtf_deb_leave(LBTF_DEB_USB); | ||
405 | return; | 538 | return; |
406 | } | 539 | } |
407 | 540 | ||
408 | syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC); | 541 | syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC); |
409 | if (!syncfwheader) { | 542 | if (!syncfwheader) { |
543 | lbtf_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n"); | ||
410 | kfree_skb(skb); | 544 | kfree_skb(skb); |
545 | lbtf_deb_leave(LBTF_DEB_USB); | ||
411 | return; | 546 | return; |
412 | } | 547 | } |
413 | 548 | ||
414 | memcpy(syncfwheader, skb->data, sizeof(struct fwsyncheader)); | 549 | memcpy(syncfwheader, skb->data, sizeof(struct fwsyncheader)); |
415 | 550 | ||
416 | if (!syncfwheader->cmd) | 551 | if (!syncfwheader->cmd) { |
552 | lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n"); | ||
553 | lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n", | ||
554 | le32_to_cpu(syncfwheader->seqnum)); | ||
417 | cardp->CRC_OK = 1; | 555 | cardp->CRC_OK = 1; |
418 | else | 556 | } else { |
557 | lbtf_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n"); | ||
419 | cardp->CRC_OK = 0; | 558 | cardp->CRC_OK = 0; |
559 | } | ||
560 | |||
420 | kfree_skb(skb); | 561 | kfree_skb(skb); |
421 | 562 | ||
422 | /* reschedule timer for 200ms hence */ | 563 | /* reschedule timer for 200ms hence */ |
@@ -434,6 +575,7 @@ static void if_usb_receive_fwload(struct urb *urb) | |||
434 | 575 | ||
435 | kfree(syncfwheader); | 576 | kfree(syncfwheader); |
436 | 577 | ||
578 | lbtf_deb_leave(LBTF_DEB_USB); | ||
437 | return; | 579 | return; |
438 | } | 580 | } |
439 | 581 | ||
@@ -445,6 +587,7 @@ static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb, | |||
445 | { | 587 | { |
446 | if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN | 588 | if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN |
447 | || recvlength < MRVDRV_MIN_PKT_LEN) { | 589 | || recvlength < MRVDRV_MIN_PKT_LEN) { |
590 | lbtf_deb_usbd(&cardp->udev->dev, "Packet length is Invalid\n"); | ||
448 | kfree_skb(skb); | 591 | kfree_skb(skb); |
449 | return; | 592 | return; |
450 | } | 593 | } |
@@ -460,6 +603,8 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, | |||
460 | struct lbtf_private *priv) | 603 | struct lbtf_private *priv) |
461 | { | 604 | { |
462 | if (recvlength > LBS_CMD_BUFFER_SIZE) { | 605 | if (recvlength > LBS_CMD_BUFFER_SIZE) { |
606 | lbtf_deb_usbd(&cardp->udev->dev, | ||
607 | "The receive buffer is too large\n"); | ||
463 | kfree_skb(skb); | 608 | kfree_skb(skb); |
464 | return; | 609 | return; |
465 | } | 610 | } |
@@ -489,16 +634,24 @@ static void if_usb_receive(struct urb *urb) | |||
489 | uint32_t recvtype = 0; | 634 | uint32_t recvtype = 0; |
490 | __le32 *pkt = (__le32 *) skb->data; | 635 | __le32 *pkt = (__le32 *) skb->data; |
491 | 636 | ||
637 | lbtf_deb_enter(LBTF_DEB_USB); | ||
638 | |||
492 | if (recvlength) { | 639 | if (recvlength) { |
493 | if (urb->status) { | 640 | if (urb->status) { |
641 | lbtf_deb_usbd(&cardp->udev->dev, "RX URB failed: %d\n", | ||
642 | urb->status); | ||
494 | kfree_skb(skb); | 643 | kfree_skb(skb); |
495 | goto setup_for_next; | 644 | goto setup_for_next; |
496 | } | 645 | } |
497 | 646 | ||
498 | recvbuff = skb->data; | 647 | recvbuff = skb->data; |
499 | recvtype = le32_to_cpu(pkt[0]); | 648 | recvtype = le32_to_cpu(pkt[0]); |
649 | lbtf_deb_usbd(&cardp->udev->dev, | ||
650 | "Recv length = 0x%x, Recv type = 0x%X\n", | ||
651 | recvlength, recvtype); | ||
500 | } else if (urb->status) { | 652 | } else if (urb->status) { |
501 | kfree_skb(skb); | 653 | kfree_skb(skb); |
654 | lbtf_deb_leave(LBTF_DEB_USB); | ||
502 | return; | 655 | return; |
503 | } | 656 | } |
504 | 657 | ||
@@ -515,6 +668,7 @@ static void if_usb_receive(struct urb *urb) | |||
515 | { | 668 | { |
516 | /* Event cause handling */ | 669 | /* Event cause handling */ |
517 | u32 event_cause = le32_to_cpu(pkt[1]); | 670 | u32 event_cause = le32_to_cpu(pkt[1]); |
671 | lbtf_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n", event_cause); | ||
518 | 672 | ||
519 | /* Icky undocumented magic special case */ | 673 | /* Icky undocumented magic special case */ |
520 | if (event_cause & 0xffff0000) { | 674 | if (event_cause & 0xffff0000) { |
@@ -529,21 +683,22 @@ static void if_usb_receive(struct urb *urb) | |||
529 | } else if (event_cause == LBTF_EVENT_BCN_SENT) | 683 | } else if (event_cause == LBTF_EVENT_BCN_SENT) |
530 | lbtf_bcn_sent(priv); | 684 | lbtf_bcn_sent(priv); |
531 | else | 685 | else |
532 | printk(KERN_DEBUG | 686 | lbtf_deb_usbd(&cardp->udev->dev, |
533 | "Unsupported notification %d received\n", | 687 | "Unsupported notification %d received\n", |
534 | event_cause); | 688 | event_cause); |
535 | kfree_skb(skb); | 689 | kfree_skb(skb); |
536 | break; | 690 | break; |
537 | } | 691 | } |
538 | default: | 692 | default: |
539 | printk(KERN_DEBUG "libertastf: unknown command type 0x%X\n", | 693 | lbtf_deb_usbd(&cardp->udev->dev, |
540 | recvtype); | 694 | "libertastf: unknown command type 0x%X\n", recvtype); |
541 | kfree_skb(skb); | 695 | kfree_skb(skb); |
542 | break; | 696 | break; |
543 | } | 697 | } |
544 | 698 | ||
545 | setup_for_next: | 699 | setup_for_next: |
546 | if_usb_submit_rx_urb(cardp); | 700 | if_usb_submit_rx_urb(cardp); |
701 | lbtf_deb_leave(LBTF_DEB_USB); | ||
547 | } | 702 | } |
548 | 703 | ||
549 | /** | 704 | /** |
@@ -562,6 +717,9 @@ static int if_usb_host_to_card(struct lbtf_private *priv, uint8_t type, | |||
562 | struct if_usb_card *cardp = priv->card; | 717 | struct if_usb_card *cardp = priv->card; |
563 | u8 data = 0; | 718 | u8 data = 0; |
564 | 719 | ||
720 | lbtf_deb_usbd(&cardp->udev->dev, "*** type = %u\n", type); | ||
721 | lbtf_deb_usbd(&cardp->udev->dev, "size after = %d\n", nb); | ||
722 | |||
565 | if (type == MVMS_CMD) { | 723 | if (type == MVMS_CMD) { |
566 | *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST); | 724 | *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST); |
567 | } else { | 725 | } else { |
@@ -639,8 +797,10 @@ static int check_fwfile_format(const u8 *data, u32 totlen) | |||
639 | } while (!exit); | 797 | } while (!exit); |
640 | 798 | ||
641 | if (ret) | 799 | if (ret) |
642 | printk(KERN_INFO | 800 | pr_err("firmware file format check FAIL\n"); |
643 | "libertastf: firmware file format check failed\n"); | 801 | else |
802 | lbtf_deb_fw("firmware file format check PASS\n"); | ||
803 | |||
644 | return ret; | 804 | return ret; |
645 | } | 805 | } |
646 | 806 | ||
@@ -651,10 +811,12 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp) | |||
651 | static int reset_count = 10; | 811 | static int reset_count = 10; |
652 | int ret = 0; | 812 | int ret = 0; |
653 | 813 | ||
814 | lbtf_deb_enter(LBTF_DEB_USB); | ||
815 | |||
654 | ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev); | 816 | ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev); |
655 | if (ret < 0) { | 817 | if (ret < 0) { |
656 | printk(KERN_INFO "libertastf: firmware %s not found\n", | 818 | pr_err("request_firmware() failed with %#x\n", ret); |
657 | lbtf_fw_name); | 819 | pr_err("firmware %s not found\n", lbtf_fw_name); |
658 | goto done; | 820 | goto done; |
659 | } | 821 | } |
660 | 822 | ||
@@ -663,6 +825,7 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp) | |||
663 | 825 | ||
664 | restart: | 826 | restart: |
665 | if (if_usb_submit_rx_urb_fwload(cardp) < 0) { | 827 | if (if_usb_submit_rx_urb_fwload(cardp) < 0) { |
828 | lbtf_deb_usbd(&cardp->udev->dev, "URB submission is failed\n"); | ||
666 | ret = -1; | 829 | ret = -1; |
667 | goto release_fw; | 830 | goto release_fw; |
668 | } | 831 | } |
@@ -709,14 +872,13 @@ restart: | |||
709 | usb_kill_urb(cardp->rx_urb); | 872 | usb_kill_urb(cardp->rx_urb); |
710 | 873 | ||
711 | if (!cardp->fwdnldover) { | 874 | if (!cardp->fwdnldover) { |
712 | printk(KERN_INFO "libertastf: failed to load fw," | 875 | pr_info("failed to load fw, resetting device!\n"); |
713 | " resetting device!\n"); | ||
714 | if (--reset_count >= 0) { | 876 | if (--reset_count >= 0) { |
715 | if_usb_reset_device(cardp); | 877 | if_usb_reset_device(cardp); |
716 | goto restart; | 878 | goto restart; |
717 | } | 879 | } |
718 | 880 | ||
719 | printk(KERN_INFO "libertastf: fw download failure\n"); | 881 | pr_info("FW download failure, time = %d ms\n", i * 100); |
720 | ret = -1; | 882 | ret = -1; |
721 | goto release_fw; | 883 | goto release_fw; |
722 | } | 884 | } |
@@ -730,6 +892,7 @@ restart: | |||
730 | if_usb_setup_firmware(cardp->priv); | 892 | if_usb_setup_firmware(cardp->priv); |
731 | 893 | ||
732 | done: | 894 | done: |
895 | lbtf_deb_leave_args(LBTF_DEB_USB, "ret %d", ret); | ||
733 | return ret; | 896 | return ret; |
734 | } | 897 | } |
735 | EXPORT_SYMBOL_GPL(if_usb_prog_firmware); | 898 | EXPORT_SYMBOL_GPL(if_usb_prog_firmware); |
@@ -751,13 +914,19 @@ static int __init if_usb_init_module(void) | |||
751 | { | 914 | { |
752 | int ret = 0; | 915 | int ret = 0; |
753 | 916 | ||
917 | lbtf_deb_enter(LBTF_DEB_MAIN); | ||
918 | |||
754 | ret = usb_register(&if_usb_driver); | 919 | ret = usb_register(&if_usb_driver); |
920 | |||
921 | lbtf_deb_leave_args(LBTF_DEB_MAIN, "ret %d", ret); | ||
755 | return ret; | 922 | return ret; |
756 | } | 923 | } |
757 | 924 | ||
758 | static void __exit if_usb_exit_module(void) | 925 | static void __exit if_usb_exit_module(void) |
759 | { | 926 | { |
927 | lbtf_deb_enter(LBTF_DEB_MAIN); | ||
760 | usb_deregister(&if_usb_driver); | 928 | usb_deregister(&if_usb_driver); |
929 | lbtf_deb_leave(LBTF_DEB_MAIN); | ||
761 | } | 930 | } |
762 | 931 | ||
763 | module_init(if_usb_init_module); | 932 | module_init(if_usb_init_module); |
diff --git a/drivers/net/wireless/libertas_tf/libertas_tf.h b/drivers/net/wireless/libertas_tf/libertas_tf.h index 4cc42dd5a005..fbbaaae7a1ae 100644 --- a/drivers/net/wireless/libertas_tf/libertas_tf.h +++ b/drivers/net/wireless/libertas_tf/libertas_tf.h | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <linux/kthread.h> | 13 | #include <linux/kthread.h> |
14 | #include <net/mac80211.h> | 14 | #include <net/mac80211.h> |
15 | 15 | ||
16 | #include "deb_defs.h" | ||
17 | |||
16 | #ifndef DRV_NAME | 18 | #ifndef DRV_NAME |
17 | #define DRV_NAME "libertas_tf" | 19 | #define DRV_NAME "libertas_tf" |
18 | #endif | 20 | #endif |
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index 7533a23e0500..60787de56f3a 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c | |||
@@ -7,10 +7,12 @@ | |||
7 | * the Free Software Foundation; either version 2 of the License, or (at | 7 | * the Free Software Foundation; either version 2 of the License, or (at |
8 | * your option) any later version. | 8 | * your option) any later version. |
9 | */ | 9 | */ |
10 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
11 | |||
10 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
11 | 13 | ||
14 | #include <linux/etherdevice.h> | ||
12 | #include "libertas_tf.h" | 15 | #include "libertas_tf.h" |
13 | #include "linux/etherdevice.h" | ||
14 | 16 | ||
15 | #define DRIVER_RELEASE_VERSION "004.p0" | 17 | #define DRIVER_RELEASE_VERSION "004.p0" |
16 | /* thinfirm version: 5.132.X.pX */ | 18 | /* thinfirm version: 5.132.X.pX */ |
@@ -18,7 +20,17 @@ | |||
18 | #define LBTF_FW_VER_MAX 0x0584ffff | 20 | #define LBTF_FW_VER_MAX 0x0584ffff |
19 | #define QOS_CONTROL_LEN 2 | 21 | #define QOS_CONTROL_LEN 2 |
20 | 22 | ||
21 | static const char lbtf_driver_version[] = "THINFIRM-USB8388-" DRIVER_RELEASE_VERSION; | 23 | /* Module parameters */ |
24 | unsigned int lbtf_debug; | ||
25 | EXPORT_SYMBOL_GPL(lbtf_debug); | ||
26 | module_param_named(libertas_tf_debug, lbtf_debug, int, 0644); | ||
27 | |||
28 | static const char lbtf_driver_version[] = "THINFIRM-USB8388-" DRIVER_RELEASE_VERSION | ||
29 | #ifdef DEBUG | ||
30 | "-dbg" | ||
31 | #endif | ||
32 | ""; | ||
33 | |||
22 | struct workqueue_struct *lbtf_wq; | 34 | struct workqueue_struct *lbtf_wq; |
23 | 35 | ||
24 | static const struct ieee80211_channel lbtf_channels[] = { | 36 | static const struct ieee80211_channel lbtf_channels[] = { |
@@ -81,6 +93,9 @@ static void lbtf_cmd_work(struct work_struct *work) | |||
81 | { | 93 | { |
82 | struct lbtf_private *priv = container_of(work, struct lbtf_private, | 94 | struct lbtf_private *priv = container_of(work, struct lbtf_private, |
83 | cmd_work); | 95 | cmd_work); |
96 | |||
97 | lbtf_deb_enter(LBTF_DEB_CMD); | ||
98 | |||
84 | spin_lock_irq(&priv->driver_lock); | 99 | spin_lock_irq(&priv->driver_lock); |
85 | /* command response? */ | 100 | /* command response? */ |
86 | if (priv->cmd_response_rxed) { | 101 | if (priv->cmd_response_rxed) { |
@@ -108,11 +123,16 @@ static void lbtf_cmd_work(struct work_struct *work) | |||
108 | priv->cmd_timed_out = 0; | 123 | priv->cmd_timed_out = 0; |
109 | spin_unlock_irq(&priv->driver_lock); | 124 | spin_unlock_irq(&priv->driver_lock); |
110 | 125 | ||
111 | if (!priv->fw_ready) | 126 | if (!priv->fw_ready) { |
127 | lbtf_deb_leave_args(LBTF_DEB_CMD, "fw not ready"); | ||
112 | return; | 128 | return; |
129 | } | ||
130 | |||
113 | /* Execute the next command */ | 131 | /* Execute the next command */ |
114 | if (!priv->cur_cmd) | 132 | if (!priv->cur_cmd) |
115 | lbtf_execute_next_command(priv); | 133 | lbtf_execute_next_command(priv); |
134 | |||
135 | lbtf_deb_leave(LBTF_DEB_CMD); | ||
116 | } | 136 | } |
117 | 137 | ||
118 | /** | 138 | /** |
@@ -126,6 +146,7 @@ static int lbtf_setup_firmware(struct lbtf_private *priv) | |||
126 | { | 146 | { |
127 | int ret = -1; | 147 | int ret = -1; |
128 | 148 | ||
149 | lbtf_deb_enter(LBTF_DEB_FW); | ||
129 | /* | 150 | /* |
130 | * Read priv address from HW | 151 | * Read priv address from HW |
131 | */ | 152 | */ |
@@ -141,6 +162,7 @@ static int lbtf_setup_firmware(struct lbtf_private *priv) | |||
141 | 162 | ||
142 | ret = 0; | 163 | ret = 0; |
143 | done: | 164 | done: |
165 | lbtf_deb_leave_args(LBTF_DEB_FW, "ret: %d", ret); | ||
144 | return ret; | 166 | return ret; |
145 | } | 167 | } |
146 | 168 | ||
@@ -152,6 +174,7 @@ static void command_timer_fn(unsigned long data) | |||
152 | { | 174 | { |
153 | struct lbtf_private *priv = (struct lbtf_private *)data; | 175 | struct lbtf_private *priv = (struct lbtf_private *)data; |
154 | unsigned long flags; | 176 | unsigned long flags; |
177 | lbtf_deb_enter(LBTF_DEB_CMD); | ||
155 | 178 | ||
156 | spin_lock_irqsave(&priv->driver_lock, flags); | 179 | spin_lock_irqsave(&priv->driver_lock, flags); |
157 | 180 | ||
@@ -168,10 +191,12 @@ static void command_timer_fn(unsigned long data) | |||
168 | queue_work(lbtf_wq, &priv->cmd_work); | 191 | queue_work(lbtf_wq, &priv->cmd_work); |
169 | out: | 192 | out: |
170 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 193 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
194 | lbtf_deb_leave(LBTF_DEB_CMD); | ||
171 | } | 195 | } |
172 | 196 | ||
173 | static int lbtf_init_adapter(struct lbtf_private *priv) | 197 | static int lbtf_init_adapter(struct lbtf_private *priv) |
174 | { | 198 | { |
199 | lbtf_deb_enter(LBTF_DEB_MAIN); | ||
175 | memset(priv->current_addr, 0xff, ETH_ALEN); | 200 | memset(priv->current_addr, 0xff, ETH_ALEN); |
176 | mutex_init(&priv->lock); | 201 | mutex_init(&priv->lock); |
177 | 202 | ||
@@ -188,13 +213,16 @@ static int lbtf_init_adapter(struct lbtf_private *priv) | |||
188 | if (lbtf_allocate_cmd_buffer(priv)) | 213 | if (lbtf_allocate_cmd_buffer(priv)) |
189 | return -1; | 214 | return -1; |
190 | 215 | ||
216 | lbtf_deb_leave(LBTF_DEB_MAIN); | ||
191 | return 0; | 217 | return 0; |
192 | } | 218 | } |
193 | 219 | ||
194 | static void lbtf_free_adapter(struct lbtf_private *priv) | 220 | static void lbtf_free_adapter(struct lbtf_private *priv) |
195 | { | 221 | { |
222 | lbtf_deb_enter(LBTF_DEB_MAIN); | ||
196 | lbtf_free_cmd_buffer(priv); | 223 | lbtf_free_cmd_buffer(priv); |
197 | del_timer(&priv->command_timer); | 224 | del_timer(&priv->command_timer); |
225 | lbtf_deb_leave(LBTF_DEB_MAIN); | ||
198 | } | 226 | } |
199 | 227 | ||
200 | static int lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 228 | static int lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
@@ -221,14 +249,18 @@ static void lbtf_tx_work(struct work_struct *work) | |||
221 | struct sk_buff *skb = NULL; | 249 | struct sk_buff *skb = NULL; |
222 | int err; | 250 | int err; |
223 | 251 | ||
252 | lbtf_deb_enter(LBTF_DEB_MACOPS | LBTF_DEB_TX); | ||
253 | |||
224 | if ((priv->vif->type == NL80211_IFTYPE_AP) && | 254 | if ((priv->vif->type == NL80211_IFTYPE_AP) && |
225 | (!skb_queue_empty(&priv->bc_ps_buf))) | 255 | (!skb_queue_empty(&priv->bc_ps_buf))) |
226 | skb = skb_dequeue(&priv->bc_ps_buf); | 256 | skb = skb_dequeue(&priv->bc_ps_buf); |
227 | else if (priv->skb_to_tx) { | 257 | else if (priv->skb_to_tx) { |
228 | skb = priv->skb_to_tx; | 258 | skb = priv->skb_to_tx; |
229 | priv->skb_to_tx = NULL; | 259 | priv->skb_to_tx = NULL; |
230 | } else | 260 | } else { |
261 | lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX); | ||
231 | return; | 262 | return; |
263 | } | ||
232 | 264 | ||
233 | len = skb->len; | 265 | len = skb->len; |
234 | info = IEEE80211_SKB_CB(skb); | 266 | info = IEEE80211_SKB_CB(skb); |
@@ -236,6 +268,7 @@ static void lbtf_tx_work(struct work_struct *work) | |||
236 | 268 | ||
237 | if (priv->surpriseremoved) { | 269 | if (priv->surpriseremoved) { |
238 | dev_kfree_skb_any(skb); | 270 | dev_kfree_skb_any(skb); |
271 | lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX); | ||
239 | return; | 272 | return; |
240 | } | 273 | } |
241 | 274 | ||
@@ -249,6 +282,7 @@ static void lbtf_tx_work(struct work_struct *work) | |||
249 | ETH_ALEN); | 282 | ETH_ALEN); |
250 | txpd->tx_packet_length = cpu_to_le16(len); | 283 | txpd->tx_packet_length = cpu_to_le16(len); |
251 | txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd)); | 284 | txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd)); |
285 | lbtf_deb_hex(LBTF_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100)); | ||
252 | BUG_ON(priv->tx_skb); | 286 | BUG_ON(priv->tx_skb); |
253 | spin_lock_irq(&priv->driver_lock); | 287 | spin_lock_irq(&priv->driver_lock); |
254 | priv->tx_skb = skb; | 288 | priv->tx_skb = skb; |
@@ -257,7 +291,9 @@ static void lbtf_tx_work(struct work_struct *work) | |||
257 | if (err) { | 291 | if (err) { |
258 | dev_kfree_skb_any(skb); | 292 | dev_kfree_skb_any(skb); |
259 | priv->tx_skb = NULL; | 293 | priv->tx_skb = NULL; |
294 | pr_err("TX error: %d", err); | ||
260 | } | 295 | } |
296 | lbtf_deb_leave(LBTF_DEB_MACOPS | LBTF_DEB_TX); | ||
261 | } | 297 | } |
262 | 298 | ||
263 | static int lbtf_op_start(struct ieee80211_hw *hw) | 299 | static int lbtf_op_start(struct ieee80211_hw *hw) |
@@ -266,6 +302,8 @@ static int lbtf_op_start(struct ieee80211_hw *hw) | |||
266 | void *card = priv->card; | 302 | void *card = priv->card; |
267 | int ret = -1; | 303 | int ret = -1; |
268 | 304 | ||
305 | lbtf_deb_enter(LBTF_DEB_MACOPS); | ||
306 | |||
269 | if (!priv->fw_ready) | 307 | if (!priv->fw_ready) |
270 | /* Upload firmware */ | 308 | /* Upload firmware */ |
271 | if (priv->hw_prog_firmware(card)) | 309 | if (priv->hw_prog_firmware(card)) |
@@ -286,10 +324,12 @@ static int lbtf_op_start(struct ieee80211_hw *hw) | |||
286 | } | 324 | } |
287 | 325 | ||
288 | printk(KERN_INFO "libertastf: Marvell WLAN 802.11 thinfirm adapter\n"); | 326 | printk(KERN_INFO "libertastf: Marvell WLAN 802.11 thinfirm adapter\n"); |
327 | lbtf_deb_leave(LBTF_DEB_MACOPS); | ||
289 | return 0; | 328 | return 0; |
290 | 329 | ||
291 | err_prog_firmware: | 330 | err_prog_firmware: |
292 | priv->hw_reset_device(card); | 331 | priv->hw_reset_device(card); |
332 | lbtf_deb_leave_args(LBTF_DEB_MACOPS, "error programing fw; ret=%d", ret); | ||
293 | return ret; | 333 | return ret; |
294 | } | 334 | } |
295 | 335 | ||
@@ -300,6 +340,9 @@ static void lbtf_op_stop(struct ieee80211_hw *hw) | |||
300 | struct sk_buff *skb; | 340 | struct sk_buff *skb; |
301 | 341 | ||
302 | struct cmd_ctrl_node *cmdnode; | 342 | struct cmd_ctrl_node *cmdnode; |
343 | |||
344 | lbtf_deb_enter(LBTF_DEB_MACOPS); | ||
345 | |||
303 | /* Flush pending command nodes */ | 346 | /* Flush pending command nodes */ |
304 | spin_lock_irqsave(&priv->driver_lock, flags); | 347 | spin_lock_irqsave(&priv->driver_lock, flags); |
305 | list_for_each_entry(cmdnode, &priv->cmdpendingq, list) { | 348 | list_for_each_entry(cmdnode, &priv->cmdpendingq, list) { |
@@ -316,6 +359,7 @@ static void lbtf_op_stop(struct ieee80211_hw *hw) | |||
316 | priv->radioon = RADIO_OFF; | 359 | priv->radioon = RADIO_OFF; |
317 | lbtf_set_radio_control(priv); | 360 | lbtf_set_radio_control(priv); |
318 | 361 | ||
362 | lbtf_deb_leave(LBTF_DEB_MACOPS); | ||
319 | return; | 363 | return; |
320 | } | 364 | } |
321 | 365 | ||
@@ -323,6 +367,7 @@ static int lbtf_op_add_interface(struct ieee80211_hw *hw, | |||
323 | struct ieee80211_vif *vif) | 367 | struct ieee80211_vif *vif) |
324 | { | 368 | { |
325 | struct lbtf_private *priv = hw->priv; | 369 | struct lbtf_private *priv = hw->priv; |
370 | lbtf_deb_enter(LBTF_DEB_MACOPS); | ||
326 | if (priv->vif != NULL) | 371 | if (priv->vif != NULL) |
327 | return -EOPNOTSUPP; | 372 | return -EOPNOTSUPP; |
328 | 373 | ||
@@ -340,6 +385,7 @@ static int lbtf_op_add_interface(struct ieee80211_hw *hw, | |||
340 | return -EOPNOTSUPP; | 385 | return -EOPNOTSUPP; |
341 | } | 386 | } |
342 | lbtf_set_mac_address(priv, (u8 *) vif->addr); | 387 | lbtf_set_mac_address(priv, (u8 *) vif->addr); |
388 | lbtf_deb_leave(LBTF_DEB_MACOPS); | ||
343 | return 0; | 389 | return 0; |
344 | } | 390 | } |
345 | 391 | ||
@@ -347,6 +393,7 @@ static void lbtf_op_remove_interface(struct ieee80211_hw *hw, | |||
347 | struct ieee80211_vif *vif) | 393 | struct ieee80211_vif *vif) |
348 | { | 394 | { |
349 | struct lbtf_private *priv = hw->priv; | 395 | struct lbtf_private *priv = hw->priv; |
396 | lbtf_deb_enter(LBTF_DEB_MACOPS); | ||
350 | 397 | ||
351 | if (priv->vif->type == NL80211_IFTYPE_AP || | 398 | if (priv->vif->type == NL80211_IFTYPE_AP || |
352 | priv->vif->type == NL80211_IFTYPE_MESH_POINT) | 399 | priv->vif->type == NL80211_IFTYPE_MESH_POINT) |
@@ -354,17 +401,20 @@ static void lbtf_op_remove_interface(struct ieee80211_hw *hw, | |||
354 | lbtf_set_mode(priv, LBTF_PASSIVE_MODE); | 401 | lbtf_set_mode(priv, LBTF_PASSIVE_MODE); |
355 | lbtf_set_bssid(priv, 0, NULL); | 402 | lbtf_set_bssid(priv, 0, NULL); |
356 | priv->vif = NULL; | 403 | priv->vif = NULL; |
404 | lbtf_deb_leave(LBTF_DEB_MACOPS); | ||
357 | } | 405 | } |
358 | 406 | ||
359 | static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed) | 407 | static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed) |
360 | { | 408 | { |
361 | struct lbtf_private *priv = hw->priv; | 409 | struct lbtf_private *priv = hw->priv; |
362 | struct ieee80211_conf *conf = &hw->conf; | 410 | struct ieee80211_conf *conf = &hw->conf; |
411 | lbtf_deb_enter(LBTF_DEB_MACOPS); | ||
363 | 412 | ||
364 | if (conf->channel->center_freq != priv->cur_freq) { | 413 | if (conf->channel->center_freq != priv->cur_freq) { |
365 | priv->cur_freq = conf->channel->center_freq; | 414 | priv->cur_freq = conf->channel->center_freq; |
366 | lbtf_set_channel(priv, conf->channel->hw_value); | 415 | lbtf_set_channel(priv, conf->channel->hw_value); |
367 | } | 416 | } |
417 | lbtf_deb_leave(LBTF_DEB_MACOPS); | ||
368 | return 0; | 418 | return 0; |
369 | } | 419 | } |
370 | 420 | ||
@@ -395,11 +445,16 @@ static void lbtf_op_configure_filter(struct ieee80211_hw *hw, | |||
395 | { | 445 | { |
396 | struct lbtf_private *priv = hw->priv; | 446 | struct lbtf_private *priv = hw->priv; |
397 | int old_mac_control = priv->mac_control; | 447 | int old_mac_control = priv->mac_control; |
448 | |||
449 | lbtf_deb_enter(LBTF_DEB_MACOPS); | ||
450 | |||
398 | changed_flags &= SUPPORTED_FIF_FLAGS; | 451 | changed_flags &= SUPPORTED_FIF_FLAGS; |
399 | *new_flags &= SUPPORTED_FIF_FLAGS; | 452 | *new_flags &= SUPPORTED_FIF_FLAGS; |
400 | 453 | ||
401 | if (!changed_flags) | 454 | if (!changed_flags) { |
455 | lbtf_deb_leave(LBTF_DEB_MACOPS); | ||
402 | return; | 456 | return; |
457 | } | ||
403 | 458 | ||
404 | if (*new_flags & (FIF_PROMISC_IN_BSS)) | 459 | if (*new_flags & (FIF_PROMISC_IN_BSS)) |
405 | priv->mac_control |= CMD_ACT_MAC_PROMISCUOUS_ENABLE; | 460 | priv->mac_control |= CMD_ACT_MAC_PROMISCUOUS_ENABLE; |
@@ -425,6 +480,8 @@ static void lbtf_op_configure_filter(struct ieee80211_hw *hw, | |||
425 | 480 | ||
426 | if (priv->mac_control != old_mac_control) | 481 | if (priv->mac_control != old_mac_control) |
427 | lbtf_set_mac_control(priv); | 482 | lbtf_set_mac_control(priv); |
483 | |||
484 | lbtf_deb_leave(LBTF_DEB_MACOPS); | ||
428 | } | 485 | } |
429 | 486 | ||
430 | static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw, | 487 | static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw, |
@@ -434,6 +491,7 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw, | |||
434 | { | 491 | { |
435 | struct lbtf_private *priv = hw->priv; | 492 | struct lbtf_private *priv = hw->priv; |
436 | struct sk_buff *beacon; | 493 | struct sk_buff *beacon; |
494 | lbtf_deb_enter(LBTF_DEB_MACOPS); | ||
437 | 495 | ||
438 | if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_INT)) { | 496 | if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_INT)) { |
439 | switch (priv->vif->type) { | 497 | switch (priv->vif->type) { |
@@ -464,6 +522,8 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw, | |||
464 | priv->preamble = CMD_TYPE_LONG_PREAMBLE; | 522 | priv->preamble = CMD_TYPE_LONG_PREAMBLE; |
465 | lbtf_set_radio_control(priv); | 523 | lbtf_set_radio_control(priv); |
466 | } | 524 | } |
525 | |||
526 | lbtf_deb_leave(LBTF_DEB_MACOPS); | ||
467 | } | 527 | } |
468 | 528 | ||
469 | static const struct ieee80211_ops lbtf_ops = { | 529 | static const struct ieee80211_ops lbtf_ops = { |
@@ -486,6 +546,8 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) | |||
486 | unsigned int flags; | 546 | unsigned int flags; |
487 | struct ieee80211_hdr *hdr; | 547 | struct ieee80211_hdr *hdr; |
488 | 548 | ||
549 | lbtf_deb_enter(LBTF_DEB_RX); | ||
550 | |||
489 | prxpd = (struct rxpd *) skb->data; | 551 | prxpd = (struct rxpd *) skb->data; |
490 | 552 | ||
491 | stats.flag = 0; | 553 | stats.flag = 0; |
@@ -494,7 +556,6 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) | |||
494 | stats.freq = priv->cur_freq; | 556 | stats.freq = priv->cur_freq; |
495 | stats.band = IEEE80211_BAND_2GHZ; | 557 | stats.band = IEEE80211_BAND_2GHZ; |
496 | stats.signal = prxpd->snr; | 558 | stats.signal = prxpd->snr; |
497 | stats.noise = prxpd->nf; | ||
498 | /* Marvell rate index has a hole at value 4 */ | 559 | /* Marvell rate index has a hole at value 4 */ |
499 | if (prxpd->rx_rate > 4) | 560 | if (prxpd->rx_rate > 4) |
500 | --prxpd->rx_rate; | 561 | --prxpd->rx_rate; |
@@ -516,7 +577,15 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) | |||
516 | } | 577 | } |
517 | 578 | ||
518 | memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats)); | 579 | memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats)); |
580 | |||
581 | lbtf_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n", | ||
582 | skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); | ||
583 | lbtf_deb_hex(LBTF_DEB_RX, "RX Data", skb->data, | ||
584 | min_t(unsigned int, skb->len, 100)); | ||
585 | |||
519 | ieee80211_rx_irqsafe(priv->hw, skb); | 586 | ieee80211_rx_irqsafe(priv->hw, skb); |
587 | |||
588 | lbtf_deb_leave(LBTF_DEB_RX); | ||
520 | return 0; | 589 | return 0; |
521 | } | 590 | } |
522 | EXPORT_SYMBOL_GPL(lbtf_rx); | 591 | EXPORT_SYMBOL_GPL(lbtf_rx); |
@@ -533,6 +602,8 @@ struct lbtf_private *lbtf_add_card(void *card, struct device *dmdev) | |||
533 | struct ieee80211_hw *hw; | 602 | struct ieee80211_hw *hw; |
534 | struct lbtf_private *priv = NULL; | 603 | struct lbtf_private *priv = NULL; |
535 | 604 | ||
605 | lbtf_deb_enter(LBTF_DEB_MAIN); | ||
606 | |||
536 | hw = ieee80211_alloc_hw(sizeof(struct lbtf_private), &lbtf_ops); | 607 | hw = ieee80211_alloc_hw(sizeof(struct lbtf_private), &lbtf_ops); |
537 | if (!hw) | 608 | if (!hw) |
538 | goto done; | 609 | goto done; |
@@ -575,6 +646,7 @@ err_init_adapter: | |||
575 | priv = NULL; | 646 | priv = NULL; |
576 | 647 | ||
577 | done: | 648 | done: |
649 | lbtf_deb_leave_args(LBTF_DEB_MAIN, "priv %p", priv); | ||
578 | return priv; | 650 | return priv; |
579 | } | 651 | } |
580 | EXPORT_SYMBOL_GPL(lbtf_add_card); | 652 | EXPORT_SYMBOL_GPL(lbtf_add_card); |
@@ -584,6 +656,8 @@ int lbtf_remove_card(struct lbtf_private *priv) | |||
584 | { | 656 | { |
585 | struct ieee80211_hw *hw = priv->hw; | 657 | struct ieee80211_hw *hw = priv->hw; |
586 | 658 | ||
659 | lbtf_deb_enter(LBTF_DEB_MAIN); | ||
660 | |||
587 | priv->surpriseremoved = 1; | 661 | priv->surpriseremoved = 1; |
588 | del_timer(&priv->command_timer); | 662 | del_timer(&priv->command_timer); |
589 | lbtf_free_adapter(priv); | 663 | lbtf_free_adapter(priv); |
@@ -591,6 +665,7 @@ int lbtf_remove_card(struct lbtf_private *priv) | |||
591 | ieee80211_unregister_hw(hw); | 665 | ieee80211_unregister_hw(hw); |
592 | ieee80211_free_hw(hw); | 666 | ieee80211_free_hw(hw); |
593 | 667 | ||
668 | lbtf_deb_leave(LBTF_DEB_MAIN); | ||
594 | return 0; | 669 | return 0; |
595 | } | 670 | } |
596 | EXPORT_SYMBOL_GPL(lbtf_remove_card); | 671 | EXPORT_SYMBOL_GPL(lbtf_remove_card); |
@@ -649,17 +724,21 @@ EXPORT_SYMBOL_GPL(lbtf_bcn_sent); | |||
649 | 724 | ||
650 | static int __init lbtf_init_module(void) | 725 | static int __init lbtf_init_module(void) |
651 | { | 726 | { |
727 | lbtf_deb_enter(LBTF_DEB_MAIN); | ||
652 | lbtf_wq = create_workqueue("libertastf"); | 728 | lbtf_wq = create_workqueue("libertastf"); |
653 | if (lbtf_wq == NULL) { | 729 | if (lbtf_wq == NULL) { |
654 | printk(KERN_ERR "libertastf: couldn't create workqueue\n"); | 730 | printk(KERN_ERR "libertastf: couldn't create workqueue\n"); |
655 | return -ENOMEM; | 731 | return -ENOMEM; |
656 | } | 732 | } |
733 | lbtf_deb_leave(LBTF_DEB_MAIN); | ||
657 | return 0; | 734 | return 0; |
658 | } | 735 | } |
659 | 736 | ||
660 | static void __exit lbtf_exit_module(void) | 737 | static void __exit lbtf_exit_module(void) |
661 | { | 738 | { |
739 | lbtf_deb_enter(LBTF_DEB_MAIN); | ||
662 | destroy_workqueue(lbtf_wq); | 740 | destroy_workqueue(lbtf_wq); |
741 | lbtf_deb_leave(LBTF_DEB_MAIN); | ||
663 | } | 742 | } |
664 | 743 | ||
665 | module_init(lbtf_init_module); | 744 | module_init(lbtf_init_module); |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 6f0d8c9fa933..9fd2beadb6f5 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -974,6 +974,7 @@ static void hw_scan_done(struct work_struct *work) | |||
974 | } | 974 | } |
975 | 975 | ||
976 | static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, | 976 | static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, |
977 | struct ieee80211_vif *vif, | ||
977 | struct cfg80211_scan_request *req) | 978 | struct cfg80211_scan_request *req) |
978 | { | 979 | { |
979 | struct hw_scan_done *hsd = kzalloc(sizeof(*hsd), GFP_KERNEL); | 980 | struct hw_scan_done *hsd = kzalloc(sizeof(*hsd), GFP_KERNEL); |
@@ -1020,7 +1021,7 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw) | |||
1020 | mutex_lock(&hwsim->mutex); | 1021 | mutex_lock(&hwsim->mutex); |
1021 | 1022 | ||
1022 | printk(KERN_DEBUG "hwsim sw_scan_complete\n"); | 1023 | printk(KERN_DEBUG "hwsim sw_scan_complete\n"); |
1023 | hwsim->scanning = true; | 1024 | hwsim->scanning = false; |
1024 | 1025 | ||
1025 | mutex_unlock(&hwsim->mutex); | 1026 | mutex_unlock(&hwsim->mutex); |
1026 | } | 1027 | } |
@@ -1299,7 +1300,8 @@ static int __init init_mac80211_hwsim(void) | |||
1299 | hw->flags = IEEE80211_HW_MFP_CAPABLE | | 1300 | hw->flags = IEEE80211_HW_MFP_CAPABLE | |
1300 | IEEE80211_HW_SIGNAL_DBM | | 1301 | IEEE80211_HW_SIGNAL_DBM | |
1301 | IEEE80211_HW_SUPPORTS_STATIC_SMPS | | 1302 | IEEE80211_HW_SUPPORTS_STATIC_SMPS | |
1302 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS; | 1303 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | |
1304 | IEEE80211_HW_AMPDU_AGGREGATION; | ||
1303 | 1305 | ||
1304 | /* ask mac80211 to reserve space for magic */ | 1306 | /* ask mac80211 to reserve space for magic */ |
1305 | hw->vif_data_size = sizeof(struct hwsim_vif_priv); | 1307 | hw->vif_data_size = sizeof(struct hwsim_vif_priv); |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 73bbd080c6e7..808adb909095 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -750,7 +750,6 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, | |||
750 | memset(status, 0, sizeof(*status)); | 750 | memset(status, 0, sizeof(*status)); |
751 | 751 | ||
752 | status->signal = -rxd->rssi; | 752 | status->signal = -rxd->rssi; |
753 | status->noise = -rxd->noise_floor; | ||
754 | 753 | ||
755 | if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) { | 754 | if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) { |
756 | status->flag |= RX_FLAG_HT; | 755 | status->flag |= RX_FLAG_HT; |
@@ -852,7 +851,6 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, | |||
852 | memset(status, 0, sizeof(*status)); | 851 | memset(status, 0, sizeof(*status)); |
853 | 852 | ||
854 | status->signal = -rxd->rssi; | 853 | status->signal = -rxd->rssi; |
855 | status->noise = -rxd->noise_level; | ||
856 | status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info); | 854 | status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info); |
857 | status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info); | 855 | status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info); |
858 | 856 | ||
@@ -3984,8 +3982,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3984 | 3982 | ||
3985 | hw->queues = MWL8K_TX_QUEUES; | 3983 | hw->queues = MWL8K_TX_QUEUES; |
3986 | 3984 | ||
3987 | /* Set rssi and noise values to dBm */ | 3985 | /* Set rssi values to dBm */ |
3988 | hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; | 3986 | hw->flags |= IEEE80211_HW_SIGNAL_DBM; |
3989 | hw->vif_data_size = sizeof(struct mwl8k_vif); | 3987 | hw->vif_data_size = sizeof(struct mwl8k_vif); |
3990 | hw->sta_data_size = sizeof(struct mwl8k_sta); | 3988 | hw->sta_data_size = sizeof(struct mwl8k_sta); |
3991 | 3989 | ||
diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig index 6116b546861d..60819bcf4377 100644 --- a/drivers/net/wireless/orinoco/Kconfig +++ b/drivers/net/wireless/orinoco/Kconfig | |||
@@ -132,3 +132,10 @@ config PCMCIA_SPECTRUM | |||
132 | This driver requires firmware download on startup. Utilities | 132 | This driver requires firmware download on startup. Utilities |
133 | for downloading Symbol firmware are available at | 133 | for downloading Symbol firmware are available at |
134 | <http://sourceforge.net/projects/orinoco/> | 134 | <http://sourceforge.net/projects/orinoco/> |
135 | |||
136 | config ORINOCO_USB | ||
137 | tristate "Agere Orinoco USB support" | ||
138 | depends on USB && HERMES | ||
139 | select FW_LOADER | ||
140 | ---help--- | ||
141 | This driver is for USB versions of the Agere Orinoco card. | ||
diff --git a/drivers/net/wireless/orinoco/Makefile b/drivers/net/wireless/orinoco/Makefile index e6452698eba9..bfdefb85abcd 100644 --- a/drivers/net/wireless/orinoco/Makefile +++ b/drivers/net/wireless/orinoco/Makefile | |||
@@ -11,6 +11,7 @@ obj-$(CONFIG_PCI_HERMES) += orinoco_pci.o | |||
11 | obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o | 11 | obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o |
12 | obj-$(CONFIG_NORTEL_HERMES) += orinoco_nortel.o | 12 | obj-$(CONFIG_NORTEL_HERMES) += orinoco_nortel.o |
13 | obj-$(CONFIG_PCMCIA_SPECTRUM) += spectrum_cs.o | 13 | obj-$(CONFIG_PCMCIA_SPECTRUM) += spectrum_cs.o |
14 | obj-$(CONFIG_ORINOCO_USB) += orinoco_usb.o | ||
14 | 15 | ||
15 | # Orinoco should be endian clean. | 16 | # Orinoco should be endian clean. |
16 | ccflags-y += -D__CHECK_ENDIAN__ | 17 | ccflags-y += -D__CHECK_ENDIAN__ |
diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c index c60df2c1aca3..9bcee10c9308 100644 --- a/drivers/net/wireless/orinoco/airport.c +++ b/drivers/net/wireless/orinoco/airport.c | |||
@@ -77,9 +77,9 @@ airport_resume(struct macio_dev *mdev) | |||
77 | 77 | ||
78 | enable_irq(card->irq); | 78 | enable_irq(card->irq); |
79 | 79 | ||
80 | spin_lock_irqsave(&priv->lock, flags); | 80 | priv->hw.ops->lock_irqsave(&priv->lock, &flags); |
81 | err = orinoco_up(priv); | 81 | err = orinoco_up(priv); |
82 | spin_unlock_irqrestore(&priv->lock, flags); | 82 | priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); |
83 | 83 | ||
84 | return err; | 84 | return err; |
85 | } | 85 | } |
@@ -195,7 +195,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
195 | ssleep(1); | 195 | ssleep(1); |
196 | 196 | ||
197 | /* Reset it before we get the interrupt */ | 197 | /* Reset it before we get the interrupt */ |
198 | hermes_init(hw); | 198 | hw->ops->init(hw); |
199 | 199 | ||
200 | if (request_irq(card->irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) { | 200 | if (request_irq(card->irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) { |
201 | printk(KERN_ERR PFX "Couldn't get IRQ %d\n", card->irq); | 201 | printk(KERN_ERR PFX "Couldn't get IRQ %d\n", card->irq); |
@@ -210,7 +210,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match) | |||
210 | } | 210 | } |
211 | 211 | ||
212 | /* Register an interface with the stack */ | 212 | /* Register an interface with the stack */ |
213 | if (orinoco_if_add(priv, phys_addr, card->irq) != 0) { | 213 | if (orinoco_if_add(priv, phys_addr, card->irq, NULL) != 0) { |
214 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); | 214 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); |
215 | goto failed; | 215 | goto failed; |
216 | } | 216 | } |
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c index 90dd4d0595c3..81d228de9e5d 100644 --- a/drivers/net/wireless/orinoco/cfg.c +++ b/drivers/net/wireless/orinoco/cfg.c | |||
@@ -189,7 +189,7 @@ static int orinoco_set_channel(struct wiphy *wiphy, | |||
189 | if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { | 189 | if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { |
190 | /* Fast channel change - no commit if successful */ | 190 | /* Fast channel change - no commit if successful */ |
191 | hermes_t *hw = &priv->hw; | 191 | hermes_t *hw = &priv->hw; |
192 | err = hermes_docmd_wait(hw, HERMES_CMD_TEST | | 192 | err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST | |
193 | HERMES_TEST_SET_CHANNEL, | 193 | HERMES_TEST_SET_CHANNEL, |
194 | channel, NULL); | 194 | channel, NULL); |
195 | } | 195 | } |
diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c index 5ea0f7cf85b1..3e1947d097ca 100644 --- a/drivers/net/wireless/orinoco/fw.c +++ b/drivers/net/wireless/orinoco/fw.c | |||
@@ -122,7 +122,7 @@ orinoco_dl_firmware(struct orinoco_private *priv, | |||
122 | dev_dbg(dev, "Attempting to download firmware %s\n", firmware); | 122 | dev_dbg(dev, "Attempting to download firmware %s\n", firmware); |
123 | 123 | ||
124 | /* Read current plug data */ | 124 | /* Read current plug data */ |
125 | err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0); | 125 | err = hw->ops->read_pda(hw, pda, fw->pda_addr, fw->pda_size); |
126 | dev_dbg(dev, "Read PDA returned %d\n", err); | 126 | dev_dbg(dev, "Read PDA returned %d\n", err); |
127 | if (err) | 127 | if (err) |
128 | goto free; | 128 | goto free; |
@@ -149,7 +149,7 @@ orinoco_dl_firmware(struct orinoco_private *priv, | |||
149 | } | 149 | } |
150 | 150 | ||
151 | /* Enable aux port to allow programming */ | 151 | /* Enable aux port to allow programming */ |
152 | err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point)); | 152 | err = hw->ops->program_init(hw, le32_to_cpu(hdr->entry_point)); |
153 | dev_dbg(dev, "Program init returned %d\n", err); | 153 | dev_dbg(dev, "Program init returned %d\n", err); |
154 | if (err != 0) | 154 | if (err != 0) |
155 | goto abort; | 155 | goto abort; |
@@ -177,7 +177,7 @@ orinoco_dl_firmware(struct orinoco_private *priv, | |||
177 | goto abort; | 177 | goto abort; |
178 | 178 | ||
179 | /* Tell card we've finished */ | 179 | /* Tell card we've finished */ |
180 | err = hermesi_program_end(hw); | 180 | err = hw->ops->program_end(hw); |
181 | dev_dbg(dev, "Program end returned %d\n", err); | 181 | dev_dbg(dev, "Program end returned %d\n", err); |
182 | if (err != 0) | 182 | if (err != 0) |
183 | goto abort; | 183 | goto abort; |
@@ -224,7 +224,7 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw, | |||
224 | if (!pda) | 224 | if (!pda) |
225 | return -ENOMEM; | 225 | return -ENOMEM; |
226 | 226 | ||
227 | ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1); | 227 | ret = hw->ops->read_pda(hw, pda, fw->pda_addr, fw->pda_size); |
228 | if (ret) | 228 | if (ret) |
229 | goto free; | 229 | goto free; |
230 | } | 230 | } |
@@ -260,7 +260,7 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw, | |||
260 | } | 260 | } |
261 | 261 | ||
262 | /* Reset hermes chip and make sure it responds */ | 262 | /* Reset hermes chip and make sure it responds */ |
263 | ret = hermes_init(hw); | 263 | ret = hw->ops->init(hw); |
264 | 264 | ||
265 | /* hermes_reset() should return 0 with the secondary firmware */ | 265 | /* hermes_reset() should return 0 with the secondary firmware */ |
266 | if (secondary && ret != 0) | 266 | if (secondary && ret != 0) |
diff --git a/drivers/net/wireless/orinoco/hermes.c b/drivers/net/wireless/orinoco/hermes.c index 1a2fca76fd3c..6c6a23e08df6 100644 --- a/drivers/net/wireless/orinoco/hermes.c +++ b/drivers/net/wireless/orinoco/hermes.c | |||
@@ -52,6 +52,26 @@ | |||
52 | #define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */ | 52 | #define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */ |
53 | 53 | ||
54 | /* | 54 | /* |
55 | * AUX port access. To unlock the AUX port write the access keys to the | ||
56 | * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL | ||
57 | * register. Then read it and make sure it's HERMES_AUX_ENABLED. | ||
58 | */ | ||
59 | #define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */ | ||
60 | #define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */ | ||
61 | #define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */ | ||
62 | #define HERMES_AUX_DISABLED 0x0000 /* Auxiliary port is closed */ | ||
63 | |||
64 | #define HERMES_AUX_PW0 0xFE01 | ||
65 | #define HERMES_AUX_PW1 0xDC23 | ||
66 | #define HERMES_AUX_PW2 0xBA45 | ||
67 | |||
68 | /* HERMES_CMD_DOWNLD */ | ||
69 | #define HERMES_PROGRAM_DISABLE (0x0000 | HERMES_CMD_DOWNLD) | ||
70 | #define HERMES_PROGRAM_ENABLE_VOLATILE (0x0100 | HERMES_CMD_DOWNLD) | ||
71 | #define HERMES_PROGRAM_ENABLE_NON_VOLATILE (0x0200 | HERMES_CMD_DOWNLD) | ||
72 | #define HERMES_PROGRAM_NON_VOLATILE (0x0300 | HERMES_CMD_DOWNLD) | ||
73 | |||
74 | /* | ||
55 | * Debugging helpers | 75 | * Debugging helpers |
56 | */ | 76 | */ |
57 | 77 | ||
@@ -70,6 +90,7 @@ | |||
70 | 90 | ||
71 | #endif /* ! HERMES_DEBUG */ | 91 | #endif /* ! HERMES_DEBUG */ |
72 | 92 | ||
93 | static const struct hermes_ops hermes_ops_local; | ||
73 | 94 | ||
74 | /* | 95 | /* |
75 | * Internal functions | 96 | * Internal functions |
@@ -111,9 +132,9 @@ static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0, | |||
111 | */ | 132 | */ |
112 | 133 | ||
113 | /* For doing cmds that wipe the magic constant in SWSUPPORT0 */ | 134 | /* For doing cmds that wipe the magic constant in SWSUPPORT0 */ |
114 | int hermes_doicmd_wait(hermes_t *hw, u16 cmd, | 135 | static int hermes_doicmd_wait(hermes_t *hw, u16 cmd, |
115 | u16 parm0, u16 parm1, u16 parm2, | 136 | u16 parm0, u16 parm1, u16 parm2, |
116 | struct hermes_response *resp) | 137 | struct hermes_response *resp) |
117 | { | 138 | { |
118 | int err = 0; | 139 | int err = 0; |
119 | int k; | 140 | int k; |
@@ -163,17 +184,18 @@ int hermes_doicmd_wait(hermes_t *hw, u16 cmd, | |||
163 | out: | 184 | out: |
164 | return err; | 185 | return err; |
165 | } | 186 | } |
166 | EXPORT_SYMBOL(hermes_doicmd_wait); | ||
167 | 187 | ||
168 | void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing) | 188 | void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing) |
169 | { | 189 | { |
170 | hw->iobase = address; | 190 | hw->iobase = address; |
171 | hw->reg_spacing = reg_spacing; | 191 | hw->reg_spacing = reg_spacing; |
172 | hw->inten = 0x0; | 192 | hw->inten = 0x0; |
193 | hw->eeprom_pda = false; | ||
194 | hw->ops = &hermes_ops_local; | ||
173 | } | 195 | } |
174 | EXPORT_SYMBOL(hermes_struct_init); | 196 | EXPORT_SYMBOL(hermes_struct_init); |
175 | 197 | ||
176 | int hermes_init(hermes_t *hw) | 198 | static int hermes_init(hermes_t *hw) |
177 | { | 199 | { |
178 | u16 reg; | 200 | u16 reg; |
179 | int err = 0; | 201 | int err = 0; |
@@ -217,7 +239,6 @@ int hermes_init(hermes_t *hw) | |||
217 | 239 | ||
218 | return err; | 240 | return err; |
219 | } | 241 | } |
220 | EXPORT_SYMBOL(hermes_init); | ||
221 | 242 | ||
222 | /* Issue a command to the chip, and (busy!) wait for it to | 243 | /* Issue a command to the chip, and (busy!) wait for it to |
223 | * complete. | 244 | * complete. |
@@ -228,8 +249,8 @@ EXPORT_SYMBOL(hermes_init); | |||
228 | * > 0 on error returned by the firmware | 249 | * > 0 on error returned by the firmware |
229 | * | 250 | * |
230 | * Callable from any context, but locking is your problem. */ | 251 | * Callable from any context, but locking is your problem. */ |
231 | int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, | 252 | static int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, |
232 | struct hermes_response *resp) | 253 | struct hermes_response *resp) |
233 | { | 254 | { |
234 | int err; | 255 | int err; |
235 | int k; | 256 | int k; |
@@ -291,9 +312,8 @@ int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, | |||
291 | out: | 312 | out: |
292 | return err; | 313 | return err; |
293 | } | 314 | } |
294 | EXPORT_SYMBOL(hermes_docmd_wait); | ||
295 | 315 | ||
296 | int hermes_allocate(hermes_t *hw, u16 size, u16 *fid) | 316 | static int hermes_allocate(hermes_t *hw, u16 size, u16 *fid) |
297 | { | 317 | { |
298 | int err = 0; | 318 | int err = 0; |
299 | int k; | 319 | int k; |
@@ -333,7 +353,6 @@ int hermes_allocate(hermes_t *hw, u16 size, u16 *fid) | |||
333 | 353 | ||
334 | return 0; | 354 | return 0; |
335 | } | 355 | } |
336 | EXPORT_SYMBOL(hermes_allocate); | ||
337 | 356 | ||
338 | /* Set up a BAP to read a particular chunk of data from card's internal buffer. | 357 | /* Set up a BAP to read a particular chunk of data from card's internal buffer. |
339 | * | 358 | * |
@@ -403,8 +422,8 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset) | |||
403 | * 0 on success | 422 | * 0 on success |
404 | * > 0 on error from firmware | 423 | * > 0 on error from firmware |
405 | */ | 424 | */ |
406 | int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len, | 425 | static int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len, |
407 | u16 id, u16 offset) | 426 | u16 id, u16 offset) |
408 | { | 427 | { |
409 | int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; | 428 | int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; |
410 | int err = 0; | 429 | int err = 0; |
@@ -422,7 +441,6 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len, | |||
422 | out: | 441 | out: |
423 | return err; | 442 | return err; |
424 | } | 443 | } |
425 | EXPORT_SYMBOL(hermes_bap_pread); | ||
426 | 444 | ||
427 | /* Write a block of data to the chip's buffer, via the | 445 | /* Write a block of data to the chip's buffer, via the |
428 | * BAP. Synchronization/serialization is the caller's problem. | 446 | * BAP. Synchronization/serialization is the caller's problem. |
@@ -432,8 +450,8 @@ EXPORT_SYMBOL(hermes_bap_pread); | |||
432 | * 0 on success | 450 | * 0 on success |
433 | * > 0 on error from firmware | 451 | * > 0 on error from firmware |
434 | */ | 452 | */ |
435 | int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len, | 453 | static int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len, |
436 | u16 id, u16 offset) | 454 | u16 id, u16 offset) |
437 | { | 455 | { |
438 | int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; | 456 | int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; |
439 | int err = 0; | 457 | int err = 0; |
@@ -451,7 +469,6 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len, | |||
451 | out: | 469 | out: |
452 | return err; | 470 | return err; |
453 | } | 471 | } |
454 | EXPORT_SYMBOL(hermes_bap_pwrite); | ||
455 | 472 | ||
456 | /* Read a Length-Type-Value record from the card. | 473 | /* Read a Length-Type-Value record from the card. |
457 | * | 474 | * |
@@ -461,8 +478,8 @@ EXPORT_SYMBOL(hermes_bap_pwrite); | |||
461 | * practice. | 478 | * practice. |
462 | * | 479 | * |
463 | * Callable from user or bh context. */ | 480 | * Callable from user or bh context. */ |
464 | int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize, | 481 | static int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize, |
465 | u16 *length, void *buf) | 482 | u16 *length, void *buf) |
466 | { | 483 | { |
467 | int err = 0; | 484 | int err = 0; |
468 | int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; | 485 | int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; |
@@ -505,10 +522,9 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize, | |||
505 | 522 | ||
506 | return 0; | 523 | return 0; |
507 | } | 524 | } |
508 | EXPORT_SYMBOL(hermes_read_ltv); | ||
509 | 525 | ||
510 | int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, | 526 | static int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, |
511 | u16 length, const void *value) | 527 | u16 length, const void *value) |
512 | { | 528 | { |
513 | int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; | 529 | int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; |
514 | int err = 0; | 530 | int err = 0; |
@@ -533,4 +549,228 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, | |||
533 | 549 | ||
534 | return err; | 550 | return err; |
535 | } | 551 | } |
536 | EXPORT_SYMBOL(hermes_write_ltv); | 552 | |
553 | /*** Hermes AUX control ***/ | ||
554 | |||
555 | static inline void | ||
556 | hermes_aux_setaddr(hermes_t *hw, u32 addr) | ||
557 | { | ||
558 | hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7)); | ||
559 | hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F)); | ||
560 | } | ||
561 | |||
562 | static inline int | ||
563 | hermes_aux_control(hermes_t *hw, int enabled) | ||
564 | { | ||
565 | int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED; | ||
566 | int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE; | ||
567 | int i; | ||
568 | |||
569 | /* Already open? */ | ||
570 | if (hermes_read_reg(hw, HERMES_CONTROL) == desired_state) | ||
571 | return 0; | ||
572 | |||
573 | hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0); | ||
574 | hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1); | ||
575 | hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2); | ||
576 | hermes_write_reg(hw, HERMES_CONTROL, action); | ||
577 | |||
578 | for (i = 0; i < 20; i++) { | ||
579 | udelay(10); | ||
580 | if (hermes_read_reg(hw, HERMES_CONTROL) == | ||
581 | desired_state) | ||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | return -EBUSY; | ||
586 | } | ||
587 | |||
588 | /*** Hermes programming ***/ | ||
589 | |||
590 | /* About to start programming data (Hermes I) | ||
591 | * offset is the entry point | ||
592 | * | ||
593 | * Spectrum_cs' Symbol fw does not require this | ||
594 | * wl_lkm Agere fw does | ||
595 | * Don't know about intersil | ||
596 | */ | ||
597 | static int hermesi_program_init(hermes_t *hw, u32 offset) | ||
598 | { | ||
599 | int err; | ||
600 | |||
601 | /* Disable interrupts?*/ | ||
602 | /*hw->inten = 0x0;*/ | ||
603 | /*hermes_write_regn(hw, INTEN, 0);*/ | ||
604 | /*hermes_set_irqmask(hw, 0);*/ | ||
605 | |||
606 | /* Acknowledge any outstanding command */ | ||
607 | hermes_write_regn(hw, EVACK, 0xFFFF); | ||
608 | |||
609 | /* Using init_cmd_wait rather than cmd_wait */ | ||
610 | err = hw->ops->init_cmd_wait(hw, | ||
611 | 0x0100 | HERMES_CMD_INIT, | ||
612 | 0, 0, 0, NULL); | ||
613 | if (err) | ||
614 | return err; | ||
615 | |||
616 | err = hw->ops->init_cmd_wait(hw, | ||
617 | 0x0000 | HERMES_CMD_INIT, | ||
618 | 0, 0, 0, NULL); | ||
619 | if (err) | ||
620 | return err; | ||
621 | |||
622 | err = hermes_aux_control(hw, 1); | ||
623 | pr_debug("AUX enable returned %d\n", err); | ||
624 | |||
625 | if (err) | ||
626 | return err; | ||
627 | |||
628 | pr_debug("Enabling volatile, EP 0x%08x\n", offset); | ||
629 | err = hw->ops->init_cmd_wait(hw, | ||
630 | HERMES_PROGRAM_ENABLE_VOLATILE, | ||
631 | offset & 0xFFFFu, | ||
632 | offset >> 16, | ||
633 | 0, | ||
634 | NULL); | ||
635 | pr_debug("PROGRAM_ENABLE returned %d\n", err); | ||
636 | |||
637 | return err; | ||
638 | } | ||
639 | |||
640 | /* Done programming data (Hermes I) | ||
641 | * | ||
642 | * Spectrum_cs' Symbol fw does not require this | ||
643 | * wl_lkm Agere fw does | ||
644 | * Don't know about intersil | ||
645 | */ | ||
646 | static int hermesi_program_end(hermes_t *hw) | ||
647 | { | ||
648 | struct hermes_response resp; | ||
649 | int rc = 0; | ||
650 | int err; | ||
651 | |||
652 | rc = hw->ops->cmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp); | ||
653 | |||
654 | pr_debug("PROGRAM_DISABLE returned %d, " | ||
655 | "r0 0x%04x, r1 0x%04x, r2 0x%04x\n", | ||
656 | rc, resp.resp0, resp.resp1, resp.resp2); | ||
657 | |||
658 | if ((rc == 0) && | ||
659 | ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD)) | ||
660 | rc = -EIO; | ||
661 | |||
662 | err = hermes_aux_control(hw, 0); | ||
663 | pr_debug("AUX disable returned %d\n", err); | ||
664 | |||
665 | /* Acknowledge any outstanding command */ | ||
666 | hermes_write_regn(hw, EVACK, 0xFFFF); | ||
667 | |||
668 | /* Reinitialise, ignoring return */ | ||
669 | (void) hw->ops->init_cmd_wait(hw, 0x0000 | HERMES_CMD_INIT, | ||
670 | 0, 0, 0, NULL); | ||
671 | |||
672 | return rc ? rc : err; | ||
673 | } | ||
674 | |||
675 | static int hermes_program_bytes(struct hermes *hw, const char *data, | ||
676 | u32 addr, u32 len) | ||
677 | { | ||
678 | /* wl lkm splits the programming into chunks of 2000 bytes. | ||
679 | * This restriction appears to come from USB. The PCMCIA | ||
680 | * adapters can program the whole lot in one go */ | ||
681 | hermes_aux_setaddr(hw, addr); | ||
682 | hermes_write_bytes(hw, HERMES_AUXDATA, data, len); | ||
683 | return 0; | ||
684 | } | ||
685 | |||
686 | /* Read PDA from the adapter */ | ||
687 | static int hermes_read_pda(hermes_t *hw, __le16 *pda, u32 pda_addr, u16 pda_len) | ||
688 | { | ||
689 | int ret; | ||
690 | u16 pda_size; | ||
691 | u16 data_len = pda_len; | ||
692 | __le16 *data = pda; | ||
693 | |||
694 | if (hw->eeprom_pda) { | ||
695 | /* PDA of spectrum symbol is in eeprom */ | ||
696 | |||
697 | /* Issue command to read EEPROM */ | ||
698 | ret = hw->ops->cmd_wait(hw, HERMES_CMD_READMIF, 0, NULL); | ||
699 | if (ret) | ||
700 | return ret; | ||
701 | } else { | ||
702 | /* wl_lkm does not include PDA size in the PDA area. | ||
703 | * We will pad the information into pda, so other routines | ||
704 | * don't have to be modified */ | ||
705 | pda[0] = cpu_to_le16(pda_len - 2); | ||
706 | /* Includes CFG_PROD_DATA but not itself */ | ||
707 | pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */ | ||
708 | data_len = pda_len - 4; | ||
709 | data = pda + 2; | ||
710 | } | ||
711 | |||
712 | /* Open auxiliary port */ | ||
713 | ret = hermes_aux_control(hw, 1); | ||
714 | pr_debug("AUX enable returned %d\n", ret); | ||
715 | if (ret) | ||
716 | return ret; | ||
717 | |||
718 | /* Read PDA */ | ||
719 | hermes_aux_setaddr(hw, pda_addr); | ||
720 | hermes_read_words(hw, HERMES_AUXDATA, data, data_len / 2); | ||
721 | |||
722 | /* Close aux port */ | ||
723 | ret = hermes_aux_control(hw, 0); | ||
724 | pr_debug("AUX disable returned %d\n", ret); | ||
725 | |||
726 | /* Check PDA length */ | ||
727 | pda_size = le16_to_cpu(pda[0]); | ||
728 | pr_debug("Actual PDA length %d, Max allowed %d\n", | ||
729 | pda_size, pda_len); | ||
730 | if (pda_size > pda_len) | ||
731 | return -EINVAL; | ||
732 | |||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | static void hermes_lock_irqsave(spinlock_t *lock, | ||
737 | unsigned long *flags) __acquires(lock) | ||
738 | { | ||
739 | spin_lock_irqsave(lock, *flags); | ||
740 | } | ||
741 | |||
742 | static void hermes_unlock_irqrestore(spinlock_t *lock, | ||
743 | unsigned long *flags) __releases(lock) | ||
744 | { | ||
745 | spin_unlock_irqrestore(lock, *flags); | ||
746 | } | ||
747 | |||
748 | static void hermes_lock_irq(spinlock_t *lock) __acquires(lock) | ||
749 | { | ||
750 | spin_lock_irq(lock); | ||
751 | } | ||
752 | |||
753 | static void hermes_unlock_irq(spinlock_t *lock) __releases(lock) | ||
754 | { | ||
755 | spin_unlock_irq(lock); | ||
756 | } | ||
757 | |||
758 | /* Hermes operations for local buses */ | ||
759 | static const struct hermes_ops hermes_ops_local = { | ||
760 | .init = hermes_init, | ||
761 | .cmd_wait = hermes_docmd_wait, | ||
762 | .init_cmd_wait = hermes_doicmd_wait, | ||
763 | .allocate = hermes_allocate, | ||
764 | .read_ltv = hermes_read_ltv, | ||
765 | .write_ltv = hermes_write_ltv, | ||
766 | .bap_pread = hermes_bap_pread, | ||
767 | .bap_pwrite = hermes_bap_pwrite, | ||
768 | .read_pda = hermes_read_pda, | ||
769 | .program_init = hermesi_program_init, | ||
770 | .program_end = hermesi_program_end, | ||
771 | .program = hermes_program_bytes, | ||
772 | .lock_irqsave = hermes_lock_irqsave, | ||
773 | .unlock_irqrestore = hermes_unlock_irqrestore, | ||
774 | .lock_irq = hermes_lock_irq, | ||
775 | .unlock_irq = hermes_unlock_irq, | ||
776 | }; | ||
diff --git a/drivers/net/wireless/orinoco/hermes.h b/drivers/net/wireless/orinoco/hermes.h index 2dddbb597c4d..9ca34e722b45 100644 --- a/drivers/net/wireless/orinoco/hermes.h +++ b/drivers/net/wireless/orinoco/hermes.h | |||
@@ -374,6 +374,37 @@ struct hermes_multicast { | |||
374 | /* Timeouts */ | 374 | /* Timeouts */ |
375 | #define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */ | 375 | #define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */ |
376 | 376 | ||
377 | struct hermes; | ||
378 | |||
379 | /* Functions to access hardware */ | ||
380 | struct hermes_ops { | ||
381 | int (*init)(struct hermes *hw); | ||
382 | int (*cmd_wait)(struct hermes *hw, u16 cmd, u16 parm0, | ||
383 | struct hermes_response *resp); | ||
384 | int (*init_cmd_wait)(struct hermes *hw, u16 cmd, | ||
385 | u16 parm0, u16 parm1, u16 parm2, | ||
386 | struct hermes_response *resp); | ||
387 | int (*allocate)(struct hermes *hw, u16 size, u16 *fid); | ||
388 | int (*read_ltv)(struct hermes *hw, int bap, u16 rid, unsigned buflen, | ||
389 | u16 *length, void *buf); | ||
390 | int (*write_ltv)(struct hermes *hw, int bap, u16 rid, | ||
391 | u16 length, const void *value); | ||
392 | int (*bap_pread)(struct hermes *hw, int bap, void *buf, int len, | ||
393 | u16 id, u16 offset); | ||
394 | int (*bap_pwrite)(struct hermes *hw, int bap, const void *buf, | ||
395 | int len, u16 id, u16 offset); | ||
396 | int (*read_pda)(struct hermes *hw, __le16 *pda, | ||
397 | u32 pda_addr, u16 pda_len); | ||
398 | int (*program_init)(struct hermes *hw, u32 entry_point); | ||
399 | int (*program_end)(struct hermes *hw); | ||
400 | int (*program)(struct hermes *hw, const char *buf, | ||
401 | u32 addr, u32 len); | ||
402 | void (*lock_irqsave)(spinlock_t *lock, unsigned long *flags); | ||
403 | void (*unlock_irqrestore)(spinlock_t *lock, unsigned long *flags); | ||
404 | void (*lock_irq)(spinlock_t *lock); | ||
405 | void (*unlock_irq)(spinlock_t *lock); | ||
406 | }; | ||
407 | |||
377 | /* Basic control structure */ | 408 | /* Basic control structure */ |
378 | typedef struct hermes { | 409 | typedef struct hermes { |
379 | void __iomem *iobase; | 410 | void __iomem *iobase; |
@@ -381,6 +412,9 @@ typedef struct hermes { | |||
381 | #define HERMES_16BIT_REGSPACING 0 | 412 | #define HERMES_16BIT_REGSPACING 0 |
382 | #define HERMES_32BIT_REGSPACING 1 | 413 | #define HERMES_32BIT_REGSPACING 1 |
383 | u16 inten; /* Which interrupts should be enabled? */ | 414 | u16 inten; /* Which interrupts should be enabled? */ |
415 | bool eeprom_pda; | ||
416 | const struct hermes_ops *ops; | ||
417 | void *priv; | ||
384 | } hermes_t; | 418 | } hermes_t; |
385 | 419 | ||
386 | /* Register access convenience macros */ | 420 | /* Register access convenience macros */ |
@@ -394,22 +428,6 @@ typedef struct hermes { | |||
394 | 428 | ||
395 | /* Function prototypes */ | 429 | /* Function prototypes */ |
396 | void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing); | 430 | void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing); |
397 | int hermes_init(hermes_t *hw); | ||
398 | int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, | ||
399 | struct hermes_response *resp); | ||
400 | int hermes_doicmd_wait(hermes_t *hw, u16 cmd, | ||
401 | u16 parm0, u16 parm1, u16 parm2, | ||
402 | struct hermes_response *resp); | ||
403 | int hermes_allocate(hermes_t *hw, u16 size, u16 *fid); | ||
404 | |||
405 | int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len, | ||
406 | u16 id, u16 offset); | ||
407 | int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len, | ||
408 | u16 id, u16 offset); | ||
409 | int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen, | ||
410 | u16 *length, void *buf); | ||
411 | int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, | ||
412 | u16 length, const void *value); | ||
413 | 431 | ||
414 | /* Inline functions */ | 432 | /* Inline functions */ |
415 | 433 | ||
@@ -426,13 +444,13 @@ static inline void hermes_set_irqmask(hermes_t *hw, u16 events) | |||
426 | 444 | ||
427 | static inline int hermes_enable_port(hermes_t *hw, int port) | 445 | static inline int hermes_enable_port(hermes_t *hw, int port) |
428 | { | 446 | { |
429 | return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8), | 447 | return hw->ops->cmd_wait(hw, HERMES_CMD_ENABLE | (port << 8), |
430 | 0, NULL); | 448 | 0, NULL); |
431 | } | 449 | } |
432 | 450 | ||
433 | static inline int hermes_disable_port(hermes_t *hw, int port) | 451 | static inline int hermes_disable_port(hermes_t *hw, int port) |
434 | { | 452 | { |
435 | return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), | 453 | return hw->ops->cmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), |
436 | 0, NULL); | 454 | 0, NULL); |
437 | } | 455 | } |
438 | 456 | ||
@@ -440,7 +458,7 @@ static inline int hermes_disable_port(hermes_t *hw, int port) | |||
440 | * information frame in __orinoco_ev_info() */ | 458 | * information frame in __orinoco_ev_info() */ |
441 | static inline int hermes_inquire(hermes_t *hw, u16 rid) | 459 | static inline int hermes_inquire(hermes_t *hw, u16 rid) |
442 | { | 460 | { |
443 | return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL); | 461 | return hw->ops->cmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL); |
444 | } | 462 | } |
445 | 463 | ||
446 | #define HERMES_BYTES_TO_RECLEN(n) ((((n)+1)/2) + 1) | 464 | #define HERMES_BYTES_TO_RECLEN(n) ((((n)+1)/2) + 1) |
@@ -475,10 +493,10 @@ static inline void hermes_clear_words(struct hermes *hw, int off, | |||
475 | } | 493 | } |
476 | 494 | ||
477 | #define HERMES_READ_RECORD(hw, bap, rid, buf) \ | 495 | #define HERMES_READ_RECORD(hw, bap, rid, buf) \ |
478 | (hermes_read_ltv((hw), (bap), (rid), sizeof(*buf), NULL, (buf))) | 496 | (hw->ops->read_ltv((hw), (bap), (rid), sizeof(*buf), NULL, (buf))) |
479 | #define HERMES_WRITE_RECORD(hw, bap, rid, buf) \ | 497 | #define HERMES_WRITE_RECORD(hw, bap, rid, buf) \ |
480 | (hermes_write_ltv((hw), (bap), (rid), \ | 498 | (hw->ops->write_ltv((hw), (bap), (rid), \ |
481 | HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf))) | 499 | HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf))) |
482 | 500 | ||
483 | static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word) | 501 | static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word) |
484 | { | 502 | { |
diff --git a/drivers/net/wireless/orinoco/hermes_dld.c b/drivers/net/wireless/orinoco/hermes_dld.c index fb157eb889ca..6da85e75fce0 100644 --- a/drivers/net/wireless/orinoco/hermes_dld.c +++ b/drivers/net/wireless/orinoco/hermes_dld.c | |||
@@ -46,37 +46,11 @@ | |||
46 | 46 | ||
47 | #define PFX "hermes_dld: " | 47 | #define PFX "hermes_dld: " |
48 | 48 | ||
49 | /* | ||
50 | * AUX port access. To unlock the AUX port write the access keys to the | ||
51 | * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL | ||
52 | * register. Then read it and make sure it's HERMES_AUX_ENABLED. | ||
53 | */ | ||
54 | #define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */ | ||
55 | #define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */ | ||
56 | #define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */ | ||
57 | #define HERMES_AUX_DISABLED 0x0000 /* Auxiliary port is closed */ | ||
58 | |||
59 | #define HERMES_AUX_PW0 0xFE01 | ||
60 | #define HERMES_AUX_PW1 0xDC23 | ||
61 | #define HERMES_AUX_PW2 0xBA45 | ||
62 | |||
63 | /* HERMES_CMD_DOWNLD */ | ||
64 | #define HERMES_PROGRAM_DISABLE (0x0000 | HERMES_CMD_DOWNLD) | ||
65 | #define HERMES_PROGRAM_ENABLE_VOLATILE (0x0100 | HERMES_CMD_DOWNLD) | ||
66 | #define HERMES_PROGRAM_ENABLE_NON_VOLATILE (0x0200 | HERMES_CMD_DOWNLD) | ||
67 | #define HERMES_PROGRAM_NON_VOLATILE (0x0300 | HERMES_CMD_DOWNLD) | ||
68 | |||
69 | /* End markers used in dblocks */ | 49 | /* End markers used in dblocks */ |
70 | #define PDI_END 0x00000000 /* End of PDA */ | 50 | #define PDI_END 0x00000000 /* End of PDA */ |
71 | #define BLOCK_END 0xFFFFFFFF /* Last image block */ | 51 | #define BLOCK_END 0xFFFFFFFF /* Last image block */ |
72 | #define TEXT_END 0x1A /* End of text header */ | 52 | #define TEXT_END 0x1A /* End of text header */ |
73 | 53 | ||
74 | /* Limit the amout we try to download in a single shot. | ||
75 | * Size is in bytes. | ||
76 | */ | ||
77 | #define MAX_DL_SIZE 1024 | ||
78 | #define LIMIT_PROGRAM_SIZE 0 | ||
79 | |||
80 | /* | 54 | /* |
81 | * The following structures have little-endian fields denoted by | 55 | * The following structures have little-endian fields denoted by |
82 | * the leading underscore. Don't access them directly - use inline | 56 | * the leading underscore. Don't access them directly - use inline |
@@ -165,41 +139,6 @@ pdi_len(const struct pdi *pdi) | |||
165 | return 2 * (le16_to_cpu(pdi->len) - 1); | 139 | return 2 * (le16_to_cpu(pdi->len) - 1); |
166 | } | 140 | } |
167 | 141 | ||
168 | /*** Hermes AUX control ***/ | ||
169 | |||
170 | static inline void | ||
171 | hermes_aux_setaddr(hermes_t *hw, u32 addr) | ||
172 | { | ||
173 | hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7)); | ||
174 | hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F)); | ||
175 | } | ||
176 | |||
177 | static inline int | ||
178 | hermes_aux_control(hermes_t *hw, int enabled) | ||
179 | { | ||
180 | int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED; | ||
181 | int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE; | ||
182 | int i; | ||
183 | |||
184 | /* Already open? */ | ||
185 | if (hermes_read_reg(hw, HERMES_CONTROL) == desired_state) | ||
186 | return 0; | ||
187 | |||
188 | hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0); | ||
189 | hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1); | ||
190 | hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2); | ||
191 | hermes_write_reg(hw, HERMES_CONTROL, action); | ||
192 | |||
193 | for (i = 0; i < 20; i++) { | ||
194 | udelay(10); | ||
195 | if (hermes_read_reg(hw, HERMES_CONTROL) == | ||
196 | desired_state) | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | return -EBUSY; | ||
201 | } | ||
202 | |||
203 | /*** Plug Data Functions ***/ | 142 | /*** Plug Data Functions ***/ |
204 | 143 | ||
205 | /* | 144 | /* |
@@ -271,62 +210,7 @@ hermes_plug_pdi(hermes_t *hw, const struct pdr *first_pdr, | |||
271 | return -EINVAL; | 210 | return -EINVAL; |
272 | 211 | ||
273 | /* do the actual plugging */ | 212 | /* do the actual plugging */ |
274 | hermes_aux_setaddr(hw, pdr_addr(pdr)); | 213 | hw->ops->program(hw, pdi->data, pdr_addr(pdr), pdi_len(pdi)); |
275 | hermes_write_bytes(hw, HERMES_AUXDATA, pdi->data, pdi_len(pdi)); | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | /* Read PDA from the adapter */ | ||
281 | int hermes_read_pda(hermes_t *hw, | ||
282 | __le16 *pda, | ||
283 | u32 pda_addr, | ||
284 | u16 pda_len, | ||
285 | int use_eeprom) /* can we get this into hw? */ | ||
286 | { | ||
287 | int ret; | ||
288 | u16 pda_size; | ||
289 | u16 data_len = pda_len; | ||
290 | __le16 *data = pda; | ||
291 | |||
292 | if (use_eeprom) { | ||
293 | /* PDA of spectrum symbol is in eeprom */ | ||
294 | |||
295 | /* Issue command to read EEPROM */ | ||
296 | ret = hermes_docmd_wait(hw, HERMES_CMD_READMIF, 0, NULL); | ||
297 | if (ret) | ||
298 | return ret; | ||
299 | } else { | ||
300 | /* wl_lkm does not include PDA size in the PDA area. | ||
301 | * We will pad the information into pda, so other routines | ||
302 | * don't have to be modified */ | ||
303 | pda[0] = cpu_to_le16(pda_len - 2); | ||
304 | /* Includes CFG_PROD_DATA but not itself */ | ||
305 | pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */ | ||
306 | data_len = pda_len - 4; | ||
307 | data = pda + 2; | ||
308 | } | ||
309 | |||
310 | /* Open auxiliary port */ | ||
311 | ret = hermes_aux_control(hw, 1); | ||
312 | pr_debug(PFX "AUX enable returned %d\n", ret); | ||
313 | if (ret) | ||
314 | return ret; | ||
315 | |||
316 | /* read PDA from EEPROM */ | ||
317 | hermes_aux_setaddr(hw, pda_addr); | ||
318 | hermes_read_words(hw, HERMES_AUXDATA, data, data_len / 2); | ||
319 | |||
320 | /* Close aux port */ | ||
321 | ret = hermes_aux_control(hw, 0); | ||
322 | pr_debug(PFX "AUX disable returned %d\n", ret); | ||
323 | |||
324 | /* Check PDA length */ | ||
325 | pda_size = le16_to_cpu(pda[0]); | ||
326 | pr_debug(PFX "Actual PDA length %d, Max allowed %d\n", | ||
327 | pda_size, pda_len); | ||
328 | if (pda_size > pda_len) | ||
329 | return -EINVAL; | ||
330 | 214 | ||
331 | return 0; | 215 | return 0; |
332 | } | 216 | } |
@@ -389,101 +273,13 @@ hermes_blocks_length(const char *first_block, const void *end) | |||
389 | 273 | ||
390 | /*** Hermes programming ***/ | 274 | /*** Hermes programming ***/ |
391 | 275 | ||
392 | /* About to start programming data (Hermes I) | ||
393 | * offset is the entry point | ||
394 | * | ||
395 | * Spectrum_cs' Symbol fw does not require this | ||
396 | * wl_lkm Agere fw does | ||
397 | * Don't know about intersil | ||
398 | */ | ||
399 | int hermesi_program_init(hermes_t *hw, u32 offset) | ||
400 | { | ||
401 | int err; | ||
402 | |||
403 | /* Disable interrupts?*/ | ||
404 | /*hw->inten = 0x0;*/ | ||
405 | /*hermes_write_regn(hw, INTEN, 0);*/ | ||
406 | /*hermes_set_irqmask(hw, 0);*/ | ||
407 | |||
408 | /* Acknowledge any outstanding command */ | ||
409 | hermes_write_regn(hw, EVACK, 0xFFFF); | ||
410 | |||
411 | /* Using doicmd_wait rather than docmd_wait */ | ||
412 | err = hermes_doicmd_wait(hw, | ||
413 | 0x0100 | HERMES_CMD_INIT, | ||
414 | 0, 0, 0, NULL); | ||
415 | if (err) | ||
416 | return err; | ||
417 | |||
418 | err = hermes_doicmd_wait(hw, | ||
419 | 0x0000 | HERMES_CMD_INIT, | ||
420 | 0, 0, 0, NULL); | ||
421 | if (err) | ||
422 | return err; | ||
423 | |||
424 | err = hermes_aux_control(hw, 1); | ||
425 | pr_debug(PFX "AUX enable returned %d\n", err); | ||
426 | |||
427 | if (err) | ||
428 | return err; | ||
429 | |||
430 | pr_debug(PFX "Enabling volatile, EP 0x%08x\n", offset); | ||
431 | err = hermes_doicmd_wait(hw, | ||
432 | HERMES_PROGRAM_ENABLE_VOLATILE, | ||
433 | offset & 0xFFFFu, | ||
434 | offset >> 16, | ||
435 | 0, | ||
436 | NULL); | ||
437 | pr_debug(PFX "PROGRAM_ENABLE returned %d\n", err); | ||
438 | |||
439 | return err; | ||
440 | } | ||
441 | |||
442 | /* Done programming data (Hermes I) | ||
443 | * | ||
444 | * Spectrum_cs' Symbol fw does not require this | ||
445 | * wl_lkm Agere fw does | ||
446 | * Don't know about intersil | ||
447 | */ | ||
448 | int hermesi_program_end(hermes_t *hw) | ||
449 | { | ||
450 | struct hermes_response resp; | ||
451 | int rc = 0; | ||
452 | int err; | ||
453 | |||
454 | rc = hermes_docmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp); | ||
455 | |||
456 | pr_debug(PFX "PROGRAM_DISABLE returned %d, " | ||
457 | "r0 0x%04x, r1 0x%04x, r2 0x%04x\n", | ||
458 | rc, resp.resp0, resp.resp1, resp.resp2); | ||
459 | |||
460 | if ((rc == 0) && | ||
461 | ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD)) | ||
462 | rc = -EIO; | ||
463 | |||
464 | err = hermes_aux_control(hw, 0); | ||
465 | pr_debug(PFX "AUX disable returned %d\n", err); | ||
466 | |||
467 | /* Acknowledge any outstanding command */ | ||
468 | hermes_write_regn(hw, EVACK, 0xFFFF); | ||
469 | |||
470 | /* Reinitialise, ignoring return */ | ||
471 | (void) hermes_doicmd_wait(hw, 0x0000 | HERMES_CMD_INIT, | ||
472 | 0, 0, 0, NULL); | ||
473 | |||
474 | return rc ? rc : err; | ||
475 | } | ||
476 | |||
477 | /* Program the data blocks */ | 276 | /* Program the data blocks */ |
478 | int hermes_program(hermes_t *hw, const char *first_block, const void *end) | 277 | int hermes_program(hermes_t *hw, const char *first_block, const void *end) |
479 | { | 278 | { |
480 | const struct dblock *blk; | 279 | const struct dblock *blk; |
481 | u32 blkaddr; | 280 | u32 blkaddr; |
482 | u32 blklen; | 281 | u32 blklen; |
483 | #if LIMIT_PROGRAM_SIZE | 282 | int err = 0; |
484 | u32 addr; | ||
485 | u32 len; | ||
486 | #endif | ||
487 | 283 | ||
488 | blk = (const struct dblock *) first_block; | 284 | blk = (const struct dblock *) first_block; |
489 | 285 | ||
@@ -498,30 +294,10 @@ int hermes_program(hermes_t *hw, const char *first_block, const void *end) | |||
498 | pr_debug(PFX "Programming block of length %d " | 294 | pr_debug(PFX "Programming block of length %d " |
499 | "to address 0x%08x\n", blklen, blkaddr); | 295 | "to address 0x%08x\n", blklen, blkaddr); |
500 | 296 | ||
501 | #if !LIMIT_PROGRAM_SIZE | 297 | err = hw->ops->program(hw, blk->data, blkaddr, blklen); |
502 | /* wl_lkm driver splits this into writes of 2000 bytes */ | 298 | if (err) |
503 | hermes_aux_setaddr(hw, blkaddr); | 299 | break; |
504 | hermes_write_bytes(hw, HERMES_AUXDATA, blk->data, | 300 | |
505 | blklen); | ||
506 | #else | ||
507 | len = (blklen < MAX_DL_SIZE) ? blklen : MAX_DL_SIZE; | ||
508 | addr = blkaddr; | ||
509 | |||
510 | while (addr < (blkaddr + blklen)) { | ||
511 | pr_debug(PFX "Programming subblock of length %d " | ||
512 | "to address 0x%08x. Data @ %p\n", | ||
513 | len, addr, &blk->data[addr - blkaddr]); | ||
514 | |||
515 | hermes_aux_setaddr(hw, addr); | ||
516 | hermes_write_bytes(hw, HERMES_AUXDATA, | ||
517 | &blk->data[addr - blkaddr], | ||
518 | len); | ||
519 | |||
520 | addr += len; | ||
521 | len = ((blkaddr + blklen - addr) < MAX_DL_SIZE) ? | ||
522 | (blkaddr + blklen - addr) : MAX_DL_SIZE; | ||
523 | } | ||
524 | #endif | ||
525 | blk = (const struct dblock *) &blk->data[blklen]; | 301 | blk = (const struct dblock *) &blk->data[blklen]; |
526 | 302 | ||
527 | if ((void *) blk > (end - sizeof(*blk))) | 303 | if ((void *) blk > (end - sizeof(*blk))) |
@@ -530,7 +306,7 @@ int hermes_program(hermes_t *hw, const char *first_block, const void *end) | |||
530 | blkaddr = dblock_addr(blk); | 306 | blkaddr = dblock_addr(blk); |
531 | blklen = dblock_len(blk); | 307 | blklen = dblock_len(blk); |
532 | } | 308 | } |
533 | return 0; | 309 | return err; |
534 | } | 310 | } |
535 | 311 | ||
536 | /*** Default plugging data for Hermes I ***/ | 312 | /*** Default plugging data for Hermes I ***/ |
@@ -690,9 +466,8 @@ int hermes_apply_pda_with_defaults(hermes_t *hw, | |||
690 | if ((pdi_len(pdi) == pdr_len(pdr)) && | 466 | if ((pdi_len(pdi) == pdr_len(pdr)) && |
691 | ((void *) pdi->data + pdi_len(pdi) < pda_end)) { | 467 | ((void *) pdi->data + pdi_len(pdi) < pda_end)) { |
692 | /* do the actual plugging */ | 468 | /* do the actual plugging */ |
693 | hermes_aux_setaddr(hw, pdr_addr(pdr)); | 469 | hw->ops->program(hw, pdi->data, pdr_addr(pdr), |
694 | hermes_write_bytes(hw, HERMES_AUXDATA, | 470 | pdi_len(pdi)); |
695 | pdi->data, pdi_len(pdi)); | ||
696 | } | 471 | } |
697 | } | 472 | } |
698 | 473 | ||
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index 741f8cea95b9..6fbd78850123 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c | |||
@@ -177,9 +177,9 @@ int determine_fw_capabilities(struct orinoco_private *priv, | |||
177 | /* 3Com MAC : 00:50:DA:* */ | 177 | /* 3Com MAC : 00:50:DA:* */ |
178 | memset(tmp, 0, sizeof(tmp)); | 178 | memset(tmp, 0, sizeof(tmp)); |
179 | /* Get the Symbol firmware version */ | 179 | /* Get the Symbol firmware version */ |
180 | err = hermes_read_ltv(hw, USER_BAP, | 180 | err = hw->ops->read_ltv(hw, USER_BAP, |
181 | HERMES_RID_SECONDARYVERSION_SYMBOL, | 181 | HERMES_RID_SECONDARYVERSION_SYMBOL, |
182 | SYMBOL_MAX_VER_LEN, NULL, &tmp); | 182 | SYMBOL_MAX_VER_LEN, NULL, &tmp); |
183 | if (err) { | 183 | if (err) { |
184 | dev_warn(dev, "Error %d reading Symbol firmware info. " | 184 | dev_warn(dev, "Error %d reading Symbol firmware info. " |
185 | "Wildly guessing capabilities...\n", err); | 185 | "Wildly guessing capabilities...\n", err); |
@@ -286,8 +286,8 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr) | |||
286 | u16 reclen; | 286 | u16 reclen; |
287 | 287 | ||
288 | /* Get the MAC address */ | 288 | /* Get the MAC address */ |
289 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, | 289 | err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, |
290 | ETH_ALEN, NULL, dev_addr); | 290 | ETH_ALEN, NULL, dev_addr); |
291 | if (err) { | 291 | if (err) { |
292 | dev_warn(dev, "Failed to read MAC address!\n"); | 292 | dev_warn(dev, "Failed to read MAC address!\n"); |
293 | goto out; | 293 | goto out; |
@@ -296,8 +296,8 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr) | |||
296 | dev_dbg(dev, "MAC address %pM\n", dev_addr); | 296 | dev_dbg(dev, "MAC address %pM\n", dev_addr); |
297 | 297 | ||
298 | /* Get the station name */ | 298 | /* Get the station name */ |
299 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, | 299 | err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, |
300 | sizeof(nickbuf), &reclen, &nickbuf); | 300 | sizeof(nickbuf), &reclen, &nickbuf); |
301 | if (err) { | 301 | if (err) { |
302 | dev_err(dev, "failed to read station name\n"); | 302 | dev_err(dev, "failed to read station name\n"); |
303 | goto out; | 303 | goto out; |
@@ -413,11 +413,11 @@ int orinoco_hw_allocate_fid(struct orinoco_private *priv) | |||
413 | struct hermes *hw = &priv->hw; | 413 | struct hermes *hw = &priv->hw; |
414 | int err; | 414 | int err; |
415 | 415 | ||
416 | err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); | 416 | err = hw->ops->allocate(hw, priv->nicbuf_size, &priv->txfid); |
417 | if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) { | 417 | if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) { |
418 | /* Try workaround for old Symbol firmware bug */ | 418 | /* Try workaround for old Symbol firmware bug */ |
419 | priv->nicbuf_size = TX_NICBUF_SIZE_BUG; | 419 | priv->nicbuf_size = TX_NICBUF_SIZE_BUG; |
420 | err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); | 420 | err = hw->ops->allocate(hw, priv->nicbuf_size, &priv->txfid); |
421 | 421 | ||
422 | dev_warn(dev, "Firmware ALLOC bug detected " | 422 | dev_warn(dev, "Firmware ALLOC bug detected " |
423 | "(old Symbol firmware?). Work around %s\n", | 423 | "(old Symbol firmware?). Work around %s\n", |
@@ -463,8 +463,9 @@ int orinoco_hw_program_rids(struct orinoco_private *priv) | |||
463 | struct hermes_idstring idbuf; | 463 | struct hermes_idstring idbuf; |
464 | 464 | ||
465 | /* Set the MAC address */ | 465 | /* Set the MAC address */ |
466 | err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, | 466 | err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, |
467 | HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr); | 467 | HERMES_BYTES_TO_RECLEN(ETH_ALEN), |
468 | dev->dev_addr); | ||
468 | if (err) { | 469 | if (err) { |
469 | printk(KERN_ERR "%s: Error %d setting MAC address\n", | 470 | printk(KERN_ERR "%s: Error %d setting MAC address\n", |
470 | dev->name, err); | 471 | dev->name, err); |
@@ -527,7 +528,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv) | |||
527 | idbuf.len = cpu_to_le16(strlen(priv->desired_essid)); | 528 | idbuf.len = cpu_to_le16(strlen(priv->desired_essid)); |
528 | memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val)); | 529 | memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val)); |
529 | /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */ | 530 | /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */ |
530 | err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID, | 531 | err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID, |
531 | HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), | 532 | HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), |
532 | &idbuf); | 533 | &idbuf); |
533 | if (err) { | 534 | if (err) { |
@@ -535,7 +536,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv) | |||
535 | dev->name, err); | 536 | dev->name, err); |
536 | return err; | 537 | return err; |
537 | } | 538 | } |
538 | err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID, | 539 | err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID, |
539 | HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), | 540 | HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), |
540 | &idbuf); | 541 | &idbuf); |
541 | if (err) { | 542 | if (err) { |
@@ -547,9 +548,9 @@ int orinoco_hw_program_rids(struct orinoco_private *priv) | |||
547 | /* Set the station name */ | 548 | /* Set the station name */ |
548 | idbuf.len = cpu_to_le16(strlen(priv->nick)); | 549 | idbuf.len = cpu_to_le16(strlen(priv->nick)); |
549 | memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val)); | 550 | memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val)); |
550 | err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, | 551 | err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, |
551 | HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2), | 552 | HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2), |
552 | &idbuf); | 553 | &idbuf); |
553 | if (err) { | 554 | if (err) { |
554 | printk(KERN_ERR "%s: Error %d setting nickname\n", | 555 | printk(KERN_ERR "%s: Error %d setting nickname\n", |
555 | dev->name, err); | 556 | dev->name, err); |
@@ -664,12 +665,12 @@ int orinoco_hw_program_rids(struct orinoco_private *priv) | |||
664 | if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { | 665 | if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { |
665 | /* Enable monitor mode */ | 666 | /* Enable monitor mode */ |
666 | dev->type = ARPHRD_IEEE80211; | 667 | dev->type = ARPHRD_IEEE80211; |
667 | err = hermes_docmd_wait(hw, HERMES_CMD_TEST | | 668 | err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST | |
668 | HERMES_TEST_MONITOR, 0, NULL); | 669 | HERMES_TEST_MONITOR, 0, NULL); |
669 | } else { | 670 | } else { |
670 | /* Disable monitor mode */ | 671 | /* Disable monitor mode */ |
671 | dev->type = ARPHRD_ETHER; | 672 | dev->type = ARPHRD_ETHER; |
672 | err = hermes_docmd_wait(hw, HERMES_CMD_TEST | | 673 | err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST | |
673 | HERMES_TEST_STOP, 0, NULL); | 674 | HERMES_TEST_STOP, 0, NULL); |
674 | } | 675 | } |
675 | if (err) | 676 | if (err) |
@@ -695,8 +696,8 @@ int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc) | |||
695 | if ((key < 0) || (key >= 4)) | 696 | if ((key < 0) || (key >= 4)) |
696 | return -EINVAL; | 697 | return -EINVAL; |
697 | 698 | ||
698 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV, | 699 | err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV, |
699 | sizeof(tsc_arr), NULL, &tsc_arr); | 700 | sizeof(tsc_arr), NULL, &tsc_arr); |
700 | if (!err) | 701 | if (!err) |
701 | memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0])); | 702 | memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0])); |
702 | 703 | ||
@@ -875,7 +876,7 @@ int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv) | |||
875 | memcpy(key, priv->keys[i].key, | 876 | memcpy(key, priv->keys[i].key, |
876 | priv->keys[i].key_len); | 877 | priv->keys[i].key_len); |
877 | 878 | ||
878 | err = hermes_write_ltv(hw, USER_BAP, | 879 | err = hw->ops->write_ltv(hw, USER_BAP, |
879 | HERMES_RID_CNFDEFAULTKEY0 + i, | 880 | HERMES_RID_CNFDEFAULTKEY0 + i, |
880 | HERMES_BYTES_TO_RECLEN(keylen), | 881 | HERMES_BYTES_TO_RECLEN(keylen), |
881 | key); | 882 | key); |
@@ -1092,7 +1093,7 @@ int __orinoco_hw_set_multicast_list(struct orinoco_private *priv, | |||
1092 | memcpy(mclist.addr[i++], ha->addr, ETH_ALEN); | 1093 | memcpy(mclist.addr[i++], ha->addr, ETH_ALEN); |
1093 | } | 1094 | } |
1094 | 1095 | ||
1095 | err = hermes_write_ltv(hw, USER_BAP, | 1096 | err = hw->ops->write_ltv(hw, USER_BAP, |
1096 | HERMES_RID_CNFGROUPADDRESSES, | 1097 | HERMES_RID_CNFGROUPADDRESSES, |
1097 | HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN), | 1098 | HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN), |
1098 | &mclist); | 1099 | &mclist); |
@@ -1134,15 +1135,15 @@ int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, | |||
1134 | rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID : | 1135 | rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID : |
1135 | HERMES_RID_CNFDESIREDSSID; | 1136 | HERMES_RID_CNFDESIREDSSID; |
1136 | 1137 | ||
1137 | err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf), | 1138 | err = hw->ops->read_ltv(hw, USER_BAP, rid, sizeof(essidbuf), |
1138 | NULL, &essidbuf); | 1139 | NULL, &essidbuf); |
1139 | if (err) | 1140 | if (err) |
1140 | goto fail_unlock; | 1141 | goto fail_unlock; |
1141 | } else { | 1142 | } else { |
1142 | *active = 0; | 1143 | *active = 0; |
1143 | 1144 | ||
1144 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID, | 1145 | err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID, |
1145 | sizeof(essidbuf), NULL, &essidbuf); | 1146 | sizeof(essidbuf), NULL, &essidbuf); |
1146 | if (err) | 1147 | if (err) |
1147 | goto fail_unlock; | 1148 | goto fail_unlock; |
1148 | } | 1149 | } |
@@ -1213,8 +1214,8 @@ int orinoco_hw_get_bitratelist(struct orinoco_private *priv, | |||
1213 | if (orinoco_lock(priv, &flags) != 0) | 1214 | if (orinoco_lock(priv, &flags) != 0) |
1214 | return -EBUSY; | 1215 | return -EBUSY; |
1215 | 1216 | ||
1216 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES, | 1217 | err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES, |
1217 | sizeof(list), NULL, &list); | 1218 | sizeof(list), NULL, &list); |
1218 | orinoco_unlock(priv, &flags); | 1219 | orinoco_unlock(priv, &flags); |
1219 | 1220 | ||
1220 | if (err) | 1221 | if (err) |
@@ -1281,7 +1282,7 @@ int orinoco_hw_trigger_scan(struct orinoco_private *priv, | |||
1281 | idbuf.len = cpu_to_le16(len); | 1282 | idbuf.len = cpu_to_le16(len); |
1282 | memcpy(idbuf.val, ssid->ssid, len); | 1283 | memcpy(idbuf.val, ssid->ssid, len); |
1283 | 1284 | ||
1284 | err = hermes_write_ltv(hw, USER_BAP, | 1285 | err = hw->ops->write_ltv(hw, USER_BAP, |
1285 | HERMES_RID_CNFSCANSSID_AGERE, | 1286 | HERMES_RID_CNFSCANSSID_AGERE, |
1286 | HERMES_BYTES_TO_RECLEN(len + 2), | 1287 | HERMES_BYTES_TO_RECLEN(len + 2), |
1287 | &idbuf); | 1288 | &idbuf); |
@@ -1345,8 +1346,8 @@ int orinoco_hw_get_current_bssid(struct orinoco_private *priv, | |||
1345 | hermes_t *hw = &priv->hw; | 1346 | hermes_t *hw = &priv->hw; |
1346 | int err; | 1347 | int err; |
1347 | 1348 | ||
1348 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, | 1349 | err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, |
1349 | ETH_ALEN, NULL, addr); | 1350 | ETH_ALEN, NULL, addr); |
1350 | 1351 | ||
1351 | return err; | 1352 | return err; |
1352 | } | 1353 | } |
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index 413e9ab6cab3..1d60c7e4392a 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c | |||
@@ -254,7 +254,7 @@ void set_port_type(struct orinoco_private *priv) | |||
254 | /* Device methods */ | 254 | /* Device methods */ |
255 | /********************************************************************/ | 255 | /********************************************************************/ |
256 | 256 | ||
257 | static int orinoco_open(struct net_device *dev) | 257 | int orinoco_open(struct net_device *dev) |
258 | { | 258 | { |
259 | struct orinoco_private *priv = ndev_priv(dev); | 259 | struct orinoco_private *priv = ndev_priv(dev); |
260 | unsigned long flags; | 260 | unsigned long flags; |
@@ -272,8 +272,9 @@ static int orinoco_open(struct net_device *dev) | |||
272 | 272 | ||
273 | return err; | 273 | return err; |
274 | } | 274 | } |
275 | EXPORT_SYMBOL(orinoco_open); | ||
275 | 276 | ||
276 | static int orinoco_stop(struct net_device *dev) | 277 | int orinoco_stop(struct net_device *dev) |
277 | { | 278 | { |
278 | struct orinoco_private *priv = ndev_priv(dev); | 279 | struct orinoco_private *priv = ndev_priv(dev); |
279 | int err = 0; | 280 | int err = 0; |
@@ -281,25 +282,27 @@ static int orinoco_stop(struct net_device *dev) | |||
281 | /* We mustn't use orinoco_lock() here, because we need to be | 282 | /* We mustn't use orinoco_lock() here, because we need to be |
282 | able to close the interface even if hw_unavailable is set | 283 | able to close the interface even if hw_unavailable is set |
283 | (e.g. as we're released after a PC Card removal) */ | 284 | (e.g. as we're released after a PC Card removal) */ |
284 | spin_lock_irq(&priv->lock); | 285 | orinoco_lock_irq(priv); |
285 | 286 | ||
286 | priv->open = 0; | 287 | priv->open = 0; |
287 | 288 | ||
288 | err = __orinoco_down(priv); | 289 | err = __orinoco_down(priv); |
289 | 290 | ||
290 | spin_unlock_irq(&priv->lock); | 291 | orinoco_unlock_irq(priv); |
291 | 292 | ||
292 | return err; | 293 | return err; |
293 | } | 294 | } |
295 | EXPORT_SYMBOL(orinoco_stop); | ||
294 | 296 | ||
295 | static struct net_device_stats *orinoco_get_stats(struct net_device *dev) | 297 | struct net_device_stats *orinoco_get_stats(struct net_device *dev) |
296 | { | 298 | { |
297 | struct orinoco_private *priv = ndev_priv(dev); | 299 | struct orinoco_private *priv = ndev_priv(dev); |
298 | 300 | ||
299 | return &priv->stats; | 301 | return &priv->stats; |
300 | } | 302 | } |
303 | EXPORT_SYMBOL(orinoco_get_stats); | ||
301 | 304 | ||
302 | static void orinoco_set_multicast_list(struct net_device *dev) | 305 | void orinoco_set_multicast_list(struct net_device *dev) |
303 | { | 306 | { |
304 | struct orinoco_private *priv = ndev_priv(dev); | 307 | struct orinoco_private *priv = ndev_priv(dev); |
305 | unsigned long flags; | 308 | unsigned long flags; |
@@ -313,8 +316,9 @@ static void orinoco_set_multicast_list(struct net_device *dev) | |||
313 | __orinoco_set_multicast_list(dev); | 316 | __orinoco_set_multicast_list(dev); |
314 | orinoco_unlock(priv, &flags); | 317 | orinoco_unlock(priv, &flags); |
315 | } | 318 | } |
319 | EXPORT_SYMBOL(orinoco_set_multicast_list); | ||
316 | 320 | ||
317 | static int orinoco_change_mtu(struct net_device *dev, int new_mtu) | 321 | int orinoco_change_mtu(struct net_device *dev, int new_mtu) |
318 | { | 322 | { |
319 | struct orinoco_private *priv = ndev_priv(dev); | 323 | struct orinoco_private *priv = ndev_priv(dev); |
320 | 324 | ||
@@ -330,6 +334,7 @@ static int orinoco_change_mtu(struct net_device *dev, int new_mtu) | |||
330 | 334 | ||
331 | return 0; | 335 | return 0; |
332 | } | 336 | } |
337 | EXPORT_SYMBOL(orinoco_change_mtu); | ||
333 | 338 | ||
334 | /********************************************************************/ | 339 | /********************************************************************/ |
335 | /* Tx path */ | 340 | /* Tx path */ |
@@ -400,8 +405,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
400 | memset(&desc, 0, sizeof(desc)); | 405 | memset(&desc, 0, sizeof(desc)); |
401 | 406 | ||
402 | *txcntl = cpu_to_le16(tx_control); | 407 | *txcntl = cpu_to_le16(tx_control); |
403 | err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), | 408 | err = hw->ops->bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), |
404 | txfid, 0); | 409 | txfid, 0); |
405 | if (err) { | 410 | if (err) { |
406 | if (net_ratelimit()) | 411 | if (net_ratelimit()) |
407 | printk(KERN_ERR "%s: Error %d writing Tx " | 412 | printk(KERN_ERR "%s: Error %d writing Tx " |
@@ -414,8 +419,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
414 | memset(&desc, 0, sizeof(desc)); | 419 | memset(&desc, 0, sizeof(desc)); |
415 | 420 | ||
416 | desc.tx_control = cpu_to_le16(tx_control); | 421 | desc.tx_control = cpu_to_le16(tx_control); |
417 | err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), | 422 | err = hw->ops->bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), |
418 | txfid, 0); | 423 | txfid, 0); |
419 | if (err) { | 424 | if (err) { |
420 | if (net_ratelimit()) | 425 | if (net_ratelimit()) |
421 | printk(KERN_ERR "%s: Error %d writing Tx " | 426 | printk(KERN_ERR "%s: Error %d writing Tx " |
@@ -458,8 +463,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
458 | memcpy(eh, &hdr, sizeof(hdr)); | 463 | memcpy(eh, &hdr, sizeof(hdr)); |
459 | } | 464 | } |
460 | 465 | ||
461 | err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len, | 466 | err = hw->ops->bap_pwrite(hw, USER_BAP, skb->data, skb->len, |
462 | txfid, HERMES_802_3_OFFSET); | 467 | txfid, HERMES_802_3_OFFSET); |
463 | if (err) { | 468 | if (err) { |
464 | printk(KERN_ERR "%s: Error %d writing packet to BAP\n", | 469 | printk(KERN_ERR "%s: Error %d writing packet to BAP\n", |
465 | dev->name, err); | 470 | dev->name, err); |
@@ -490,8 +495,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
490 | skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic); | 495 | skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic); |
491 | 496 | ||
492 | /* Write the MIC */ | 497 | /* Write the MIC */ |
493 | err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len, | 498 | err = hw->ops->bap_pwrite(hw, USER_BAP, &mic_buf[0], len, |
494 | txfid, HERMES_802_3_OFFSET + offset); | 499 | txfid, HERMES_802_3_OFFSET + offset); |
495 | if (err) { | 500 | if (err) { |
496 | printk(KERN_ERR "%s: Error %d writing MIC to BAP\n", | 501 | printk(KERN_ERR "%s: Error %d writing MIC to BAP\n", |
497 | dev->name, err); | 502 | dev->name, err); |
@@ -502,7 +507,7 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
502 | /* Finally, we actually initiate the send */ | 507 | /* Finally, we actually initiate the send */ |
503 | netif_stop_queue(dev); | 508 | netif_stop_queue(dev); |
504 | 509 | ||
505 | err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, | 510 | err = hw->ops->cmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, |
506 | txfid, NULL); | 511 | txfid, NULL); |
507 | if (err) { | 512 | if (err) { |
508 | netif_start_queue(dev); | 513 | netif_start_queue(dev); |
@@ -572,9 +577,9 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw) | |||
572 | return; /* Nothing's really happened */ | 577 | return; /* Nothing's really happened */ |
573 | 578 | ||
574 | /* Read part of the frame header - we need status and addr1 */ | 579 | /* Read part of the frame header - we need status and addr1 */ |
575 | err = hermes_bap_pread(hw, IRQ_BAP, &hdr, | 580 | err = hw->ops->bap_pread(hw, IRQ_BAP, &hdr, |
576 | sizeof(struct hermes_txexc_data), | 581 | sizeof(struct hermes_txexc_data), |
577 | fid, 0); | 582 | fid, 0); |
578 | 583 | ||
579 | hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); | 584 | hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); |
580 | stats->tx_errors++; | 585 | stats->tx_errors++; |
@@ -615,7 +620,7 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw) | |||
615 | netif_wake_queue(dev); | 620 | netif_wake_queue(dev); |
616 | } | 621 | } |
617 | 622 | ||
618 | static void orinoco_tx_timeout(struct net_device *dev) | 623 | void orinoco_tx_timeout(struct net_device *dev) |
619 | { | 624 | { |
620 | struct orinoco_private *priv = ndev_priv(dev); | 625 | struct orinoco_private *priv = ndev_priv(dev); |
621 | struct net_device_stats *stats = &priv->stats; | 626 | struct net_device_stats *stats = &priv->stats; |
@@ -630,6 +635,7 @@ static void orinoco_tx_timeout(struct net_device *dev) | |||
630 | 635 | ||
631 | schedule_work(&priv->reset_work); | 636 | schedule_work(&priv->reset_work); |
632 | } | 637 | } |
638 | EXPORT_SYMBOL(orinoco_tx_timeout); | ||
633 | 639 | ||
634 | /********************************************************************/ | 640 | /********************************************************************/ |
635 | /* Rx path (data frames) */ | 641 | /* Rx path (data frames) */ |
@@ -764,9 +770,9 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, | |||
764 | 770 | ||
765 | /* If any, copy the data from the card to the skb */ | 771 | /* If any, copy the data from the card to the skb */ |
766 | if (datalen > 0) { | 772 | if (datalen > 0) { |
767 | err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen), | 773 | err = hw->ops->bap_pread(hw, IRQ_BAP, skb_put(skb, datalen), |
768 | ALIGN(datalen, 2), rxfid, | 774 | ALIGN(datalen, 2), rxfid, |
769 | HERMES_802_2_OFFSET); | 775 | HERMES_802_2_OFFSET); |
770 | if (err) { | 776 | if (err) { |
771 | printk(KERN_ERR "%s: error %d reading monitor frame\n", | 777 | printk(KERN_ERR "%s: error %d reading monitor frame\n", |
772 | dev->name, err); | 778 | dev->name, err); |
@@ -792,7 +798,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid, | |||
792 | stats->rx_dropped++; | 798 | stats->rx_dropped++; |
793 | } | 799 | } |
794 | 800 | ||
795 | static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) | 801 | void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) |
796 | { | 802 | { |
797 | struct orinoco_private *priv = ndev_priv(dev); | 803 | struct orinoco_private *priv = ndev_priv(dev); |
798 | struct net_device_stats *stats = &priv->stats; | 804 | struct net_device_stats *stats = &priv->stats; |
@@ -814,8 +820,8 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) | |||
814 | 820 | ||
815 | rxfid = hermes_read_regn(hw, RXFID); | 821 | rxfid = hermes_read_regn(hw, RXFID); |
816 | 822 | ||
817 | err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc), | 823 | err = hw->ops->bap_pread(hw, IRQ_BAP, desc, sizeof(*desc), |
818 | rxfid, 0); | 824 | rxfid, 0); |
819 | if (err) { | 825 | if (err) { |
820 | printk(KERN_ERR "%s: error %d reading Rx descriptor. " | 826 | printk(KERN_ERR "%s: error %d reading Rx descriptor. " |
821 | "Frame dropped.\n", dev->name, err); | 827 | "Frame dropped.\n", dev->name, err); |
@@ -882,9 +888,9 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) | |||
882 | nothing is removed. 2 is for aligning the IP header. */ | 888 | nothing is removed. 2 is for aligning the IP header. */ |
883 | skb_reserve(skb, ETH_HLEN + 2); | 889 | skb_reserve(skb, ETH_HLEN + 2); |
884 | 890 | ||
885 | err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length), | 891 | err = hw->ops->bap_pread(hw, IRQ_BAP, skb_put(skb, length), |
886 | ALIGN(length, 2), rxfid, | 892 | ALIGN(length, 2), rxfid, |
887 | HERMES_802_2_OFFSET); | 893 | HERMES_802_2_OFFSET); |
888 | if (err) { | 894 | if (err) { |
889 | printk(KERN_ERR "%s: error %d reading frame. " | 895 | printk(KERN_ERR "%s: error %d reading frame. " |
890 | "Frame dropped.\n", dev->name, err); | 896 | "Frame dropped.\n", dev->name, err); |
@@ -913,6 +919,7 @@ update_stats: | |||
913 | out: | 919 | out: |
914 | kfree(desc); | 920 | kfree(desc); |
915 | } | 921 | } |
922 | EXPORT_SYMBOL(__orinoco_ev_rx); | ||
916 | 923 | ||
917 | static void orinoco_rx(struct net_device *dev, | 924 | static void orinoco_rx(struct net_device *dev, |
918 | struct hermes_rx_descriptor *desc, | 925 | struct hermes_rx_descriptor *desc, |
@@ -1145,9 +1152,9 @@ static void orinoco_join_ap(struct work_struct *work) | |||
1145 | goto out; | 1152 | goto out; |
1146 | 1153 | ||
1147 | /* Read scan results from the firmware */ | 1154 | /* Read scan results from the firmware */ |
1148 | err = hermes_read_ltv(hw, USER_BAP, | 1155 | err = hw->ops->read_ltv(hw, USER_BAP, |
1149 | HERMES_RID_SCANRESULTSTABLE, | 1156 | HERMES_RID_SCANRESULTSTABLE, |
1150 | MAX_SCAN_LEN, &len, buf); | 1157 | MAX_SCAN_LEN, &len, buf); |
1151 | if (err) { | 1158 | if (err) { |
1152 | printk(KERN_ERR "%s: Cannot read scan results\n", | 1159 | printk(KERN_ERR "%s: Cannot read scan results\n", |
1153 | dev->name); | 1160 | dev->name); |
@@ -1194,8 +1201,8 @@ static void orinoco_send_bssid_wevent(struct orinoco_private *priv) | |||
1194 | union iwreq_data wrqu; | 1201 | union iwreq_data wrqu; |
1195 | int err; | 1202 | int err; |
1196 | 1203 | ||
1197 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, | 1204 | err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, |
1198 | ETH_ALEN, NULL, wrqu.ap_addr.sa_data); | 1205 | ETH_ALEN, NULL, wrqu.ap_addr.sa_data); |
1199 | if (err != 0) | 1206 | if (err != 0) |
1200 | return; | 1207 | return; |
1201 | 1208 | ||
@@ -1217,8 +1224,8 @@ static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv) | |||
1217 | if (!priv->has_wpa) | 1224 | if (!priv->has_wpa) |
1218 | return; | 1225 | return; |
1219 | 1226 | ||
1220 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO, | 1227 | err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO, |
1221 | sizeof(buf), NULL, &buf); | 1228 | sizeof(buf), NULL, &buf); |
1222 | if (err != 0) | 1229 | if (err != 0) |
1223 | return; | 1230 | return; |
1224 | 1231 | ||
@@ -1247,8 +1254,9 @@ static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv) | |||
1247 | if (!priv->has_wpa) | 1254 | if (!priv->has_wpa) |
1248 | return; | 1255 | return; |
1249 | 1256 | ||
1250 | err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO, | 1257 | err = hw->ops->read_ltv(hw, USER_BAP, |
1251 | sizeof(buf), NULL, &buf); | 1258 | HERMES_RID_CURRENT_ASSOC_RESP_INFO, |
1259 | sizeof(buf), NULL, &buf); | ||
1252 | if (err != 0) | 1260 | if (err != 0) |
1253 | return; | 1261 | return; |
1254 | 1262 | ||
@@ -1353,7 +1361,7 @@ static void orinoco_process_scan_results(struct work_struct *work) | |||
1353 | spin_unlock_irqrestore(&priv->scan_lock, flags); | 1361 | spin_unlock_irqrestore(&priv->scan_lock, flags); |
1354 | } | 1362 | } |
1355 | 1363 | ||
1356 | static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | 1364 | void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) |
1357 | { | 1365 | { |
1358 | struct orinoco_private *priv = ndev_priv(dev); | 1366 | struct orinoco_private *priv = ndev_priv(dev); |
1359 | u16 infofid; | 1367 | u16 infofid; |
@@ -1371,8 +1379,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1371 | infofid = hermes_read_regn(hw, INFOFID); | 1379 | infofid = hermes_read_regn(hw, INFOFID); |
1372 | 1380 | ||
1373 | /* Read the info frame header - don't try too hard */ | 1381 | /* Read the info frame header - don't try too hard */ |
1374 | err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info), | 1382 | err = hw->ops->bap_pread(hw, IRQ_BAP, &info, sizeof(info), |
1375 | infofid, 0); | 1383 | infofid, 0); |
1376 | if (err) { | 1384 | if (err) { |
1377 | printk(KERN_ERR "%s: error %d reading info frame. " | 1385 | printk(KERN_ERR "%s: error %d reading info frame. " |
1378 | "Frame dropped.\n", dev->name, err); | 1386 | "Frame dropped.\n", dev->name, err); |
@@ -1393,8 +1401,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1393 | len = sizeof(tallies); | 1401 | len = sizeof(tallies); |
1394 | } | 1402 | } |
1395 | 1403 | ||
1396 | err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len, | 1404 | err = hw->ops->bap_pread(hw, IRQ_BAP, &tallies, len, |
1397 | infofid, sizeof(info)); | 1405 | infofid, sizeof(info)); |
1398 | if (err) | 1406 | if (err) |
1399 | break; | 1407 | break; |
1400 | 1408 | ||
@@ -1429,8 +1437,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1429 | break; | 1437 | break; |
1430 | } | 1438 | } |
1431 | 1439 | ||
1432 | err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len, | 1440 | err = hw->ops->bap_pread(hw, IRQ_BAP, &linkstatus, len, |
1433 | infofid, sizeof(info)); | 1441 | infofid, sizeof(info)); |
1434 | if (err) | 1442 | if (err) |
1435 | break; | 1443 | break; |
1436 | newstatus = le16_to_cpu(linkstatus.linkstatus); | 1444 | newstatus = le16_to_cpu(linkstatus.linkstatus); |
@@ -1494,8 +1502,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1494 | } | 1502 | } |
1495 | 1503 | ||
1496 | /* Read scan data */ | 1504 | /* Read scan data */ |
1497 | err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len, | 1505 | err = hw->ops->bap_pread(hw, IRQ_BAP, (void *) buf, len, |
1498 | infofid, sizeof(info)); | 1506 | infofid, sizeof(info)); |
1499 | if (err) { | 1507 | if (err) { |
1500 | kfree(buf); | 1508 | kfree(buf); |
1501 | qabort_scan(priv); | 1509 | qabort_scan(priv); |
@@ -1547,8 +1555,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1547 | break; | 1555 | break; |
1548 | 1556 | ||
1549 | /* Read scan data */ | 1557 | /* Read scan data */ |
1550 | err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len, | 1558 | err = hw->ops->bap_pread(hw, IRQ_BAP, (void *) bss, len, |
1551 | infofid, sizeof(info)); | 1559 | infofid, sizeof(info)); |
1552 | if (err) | 1560 | if (err) |
1553 | kfree(bss); | 1561 | kfree(bss); |
1554 | else | 1562 | else |
@@ -1571,6 +1579,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1571 | 1579 | ||
1572 | return; | 1580 | return; |
1573 | } | 1581 | } |
1582 | EXPORT_SYMBOL(__orinoco_ev_info); | ||
1574 | 1583 | ||
1575 | static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw) | 1584 | static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw) |
1576 | { | 1585 | { |
@@ -1647,7 +1656,7 @@ static int orinoco_reinit_firmware(struct orinoco_private *priv) | |||
1647 | struct hermes *hw = &priv->hw; | 1656 | struct hermes *hw = &priv->hw; |
1648 | int err; | 1657 | int err; |
1649 | 1658 | ||
1650 | err = hermes_init(hw); | 1659 | err = hw->ops->init(hw); |
1651 | if (priv->do_fw_download && !err) { | 1660 | if (priv->do_fw_download && !err) { |
1652 | err = orinoco_download(priv); | 1661 | err = orinoco_download(priv); |
1653 | if (err) | 1662 | if (err) |
@@ -1735,7 +1744,7 @@ void orinoco_reset(struct work_struct *work) | |||
1735 | } | 1744 | } |
1736 | 1745 | ||
1737 | /* This has to be called from user context */ | 1746 | /* This has to be called from user context */ |
1738 | spin_lock_irq(&priv->lock); | 1747 | orinoco_lock_irq(priv); |
1739 | 1748 | ||
1740 | priv->hw_unavailable--; | 1749 | priv->hw_unavailable--; |
1741 | 1750 | ||
@@ -1750,7 +1759,7 @@ void orinoco_reset(struct work_struct *work) | |||
1750 | dev->trans_start = jiffies; | 1759 | dev->trans_start = jiffies; |
1751 | } | 1760 | } |
1752 | 1761 | ||
1753 | spin_unlock_irq(&priv->lock); | 1762 | orinoco_unlock_irq(priv); |
1754 | 1763 | ||
1755 | return; | 1764 | return; |
1756 | disable: | 1765 | disable: |
@@ -1984,7 +1993,7 @@ int orinoco_init(struct orinoco_private *priv) | |||
1984 | priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN; | 1993 | priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN; |
1985 | 1994 | ||
1986 | /* Initialize the firmware */ | 1995 | /* Initialize the firmware */ |
1987 | err = hermes_init(hw); | 1996 | err = hw->ops->init(hw); |
1988 | if (err != 0) { | 1997 | if (err != 0) { |
1989 | dev_err(dev, "Failed to initialize firmware (err = %d)\n", | 1998 | dev_err(dev, "Failed to initialize firmware (err = %d)\n", |
1990 | err); | 1999 | err); |
@@ -2067,9 +2076,9 @@ int orinoco_init(struct orinoco_private *priv) | |||
2067 | 2076 | ||
2068 | /* Make the hardware available, as long as it hasn't been | 2077 | /* Make the hardware available, as long as it hasn't been |
2069 | * removed elsewhere (e.g. by PCMCIA hot unplug) */ | 2078 | * removed elsewhere (e.g. by PCMCIA hot unplug) */ |
2070 | spin_lock_irq(&priv->lock); | 2079 | orinoco_lock_irq(priv); |
2071 | priv->hw_unavailable--; | 2080 | priv->hw_unavailable--; |
2072 | spin_unlock_irq(&priv->lock); | 2081 | orinoco_unlock_irq(priv); |
2073 | 2082 | ||
2074 | dev_dbg(dev, "Ready\n"); | 2083 | dev_dbg(dev, "Ready\n"); |
2075 | 2084 | ||
@@ -2192,7 +2201,8 @@ EXPORT_SYMBOL(alloc_orinocodev); | |||
2192 | */ | 2201 | */ |
2193 | int orinoco_if_add(struct orinoco_private *priv, | 2202 | int orinoco_if_add(struct orinoco_private *priv, |
2194 | unsigned long base_addr, | 2203 | unsigned long base_addr, |
2195 | unsigned int irq) | 2204 | unsigned int irq, |
2205 | const struct net_device_ops *ops) | ||
2196 | { | 2206 | { |
2197 | struct wiphy *wiphy = priv_to_wiphy(priv); | 2207 | struct wiphy *wiphy = priv_to_wiphy(priv); |
2198 | struct wireless_dev *wdev; | 2208 | struct wireless_dev *wdev; |
@@ -2211,12 +2221,17 @@ int orinoco_if_add(struct orinoco_private *priv, | |||
2211 | 2221 | ||
2212 | /* Setup / override net_device fields */ | 2222 | /* Setup / override net_device fields */ |
2213 | dev->ieee80211_ptr = wdev; | 2223 | dev->ieee80211_ptr = wdev; |
2214 | dev->netdev_ops = &orinoco_netdev_ops; | ||
2215 | dev->watchdog_timeo = HZ; /* 1 second timeout */ | 2224 | dev->watchdog_timeo = HZ; /* 1 second timeout */ |
2216 | dev->wireless_handlers = &orinoco_handler_def; | 2225 | dev->wireless_handlers = &orinoco_handler_def; |
2217 | #ifdef WIRELESS_SPY | 2226 | #ifdef WIRELESS_SPY |
2218 | dev->wireless_data = &priv->wireless_data; | 2227 | dev->wireless_data = &priv->wireless_data; |
2219 | #endif | 2228 | #endif |
2229 | /* Default to standard ops if not set */ | ||
2230 | if (ops) | ||
2231 | dev->netdev_ops = ops; | ||
2232 | else | ||
2233 | dev->netdev_ops = &orinoco_netdev_ops; | ||
2234 | |||
2220 | /* we use the default eth_mac_addr for setting the MAC addr */ | 2235 | /* we use the default eth_mac_addr for setting the MAC addr */ |
2221 | 2236 | ||
2222 | /* Reserve space in skb for the SNAP header */ | 2237 | /* Reserve space in skb for the SNAP header */ |
@@ -2305,7 +2320,7 @@ int orinoco_up(struct orinoco_private *priv) | |||
2305 | unsigned long flags; | 2320 | unsigned long flags; |
2306 | int err; | 2321 | int err; |
2307 | 2322 | ||
2308 | spin_lock_irqsave(&priv->lock, flags); | 2323 | priv->hw.ops->lock_irqsave(&priv->lock, &flags); |
2309 | 2324 | ||
2310 | err = orinoco_reinit_firmware(priv); | 2325 | err = orinoco_reinit_firmware(priv); |
2311 | if (err) { | 2326 | if (err) { |
@@ -2325,7 +2340,7 @@ int orinoco_up(struct orinoco_private *priv) | |||
2325 | } | 2340 | } |
2326 | 2341 | ||
2327 | exit: | 2342 | exit: |
2328 | spin_unlock_irqrestore(&priv->lock, flags); | 2343 | priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); |
2329 | 2344 | ||
2330 | return 0; | 2345 | return 0; |
2331 | } | 2346 | } |
@@ -2337,7 +2352,7 @@ void orinoco_down(struct orinoco_private *priv) | |||
2337 | unsigned long flags; | 2352 | unsigned long flags; |
2338 | int err; | 2353 | int err; |
2339 | 2354 | ||
2340 | spin_lock_irqsave(&priv->lock, flags); | 2355 | priv->hw.ops->lock_irqsave(&priv->lock, &flags); |
2341 | err = __orinoco_down(priv); | 2356 | err = __orinoco_down(priv); |
2342 | if (err) | 2357 | if (err) |
2343 | printk(KERN_WARNING "%s: Error %d downing interface\n", | 2358 | printk(KERN_WARNING "%s: Error %d downing interface\n", |
@@ -2345,7 +2360,7 @@ void orinoco_down(struct orinoco_private *priv) | |||
2345 | 2360 | ||
2346 | netif_device_detach(dev); | 2361 | netif_device_detach(dev); |
2347 | priv->hw_unavailable++; | 2362 | priv->hw_unavailable++; |
2348 | spin_unlock_irqrestore(&priv->lock, flags); | 2363 | priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); |
2349 | } | 2364 | } |
2350 | EXPORT_SYMBOL(orinoco_down); | 2365 | EXPORT_SYMBOL(orinoco_down); |
2351 | 2366 | ||
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h index ff6b7b1d421d..e9f415a56d4d 100644 --- a/drivers/net/wireless/orinoco/orinoco.h +++ b/drivers/net/wireless/orinoco/orinoco.h | |||
@@ -190,12 +190,24 @@ extern void free_orinocodev(struct orinoco_private *priv); | |||
190 | extern int orinoco_init(struct orinoco_private *priv); | 190 | extern int orinoco_init(struct orinoco_private *priv); |
191 | extern int orinoco_if_add(struct orinoco_private *priv, | 191 | extern int orinoco_if_add(struct orinoco_private *priv, |
192 | unsigned long base_addr, | 192 | unsigned long base_addr, |
193 | unsigned int irq); | 193 | unsigned int irq, |
194 | const struct net_device_ops *ops); | ||
194 | extern void orinoco_if_del(struct orinoco_private *priv); | 195 | extern void orinoco_if_del(struct orinoco_private *priv); |
195 | extern int orinoco_up(struct orinoco_private *priv); | 196 | extern int orinoco_up(struct orinoco_private *priv); |
196 | extern void orinoco_down(struct orinoco_private *priv); | 197 | extern void orinoco_down(struct orinoco_private *priv); |
197 | extern irqreturn_t orinoco_interrupt(int irq, void *dev_id); | 198 | extern irqreturn_t orinoco_interrupt(int irq, void *dev_id); |
198 | 199 | ||
200 | extern void __orinoco_ev_info(struct net_device *dev, hermes_t *hw); | ||
201 | extern void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw); | ||
202 | |||
203 | /* Common ndo functions exported for reuse by orinoco_usb */ | ||
204 | int orinoco_open(struct net_device *dev); | ||
205 | int orinoco_stop(struct net_device *dev); | ||
206 | struct net_device_stats *orinoco_get_stats(struct net_device *dev); | ||
207 | void orinoco_set_multicast_list(struct net_device *dev); | ||
208 | int orinoco_change_mtu(struct net_device *dev, int new_mtu); | ||
209 | void orinoco_tx_timeout(struct net_device *dev); | ||
210 | |||
199 | /********************************************************************/ | 211 | /********************************************************************/ |
200 | /* Locking and synchronization functions */ | 212 | /* Locking and synchronization functions */ |
201 | /********************************************************************/ | 213 | /********************************************************************/ |
@@ -203,11 +215,11 @@ extern irqreturn_t orinoco_interrupt(int irq, void *dev_id); | |||
203 | static inline int orinoco_lock(struct orinoco_private *priv, | 215 | static inline int orinoco_lock(struct orinoco_private *priv, |
204 | unsigned long *flags) | 216 | unsigned long *flags) |
205 | { | 217 | { |
206 | spin_lock_irqsave(&priv->lock, *flags); | 218 | priv->hw.ops->lock_irqsave(&priv->lock, flags); |
207 | if (priv->hw_unavailable) { | 219 | if (priv->hw_unavailable) { |
208 | DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n", | 220 | DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n", |
209 | priv->ndev); | 221 | priv->ndev); |
210 | spin_unlock_irqrestore(&priv->lock, *flags); | 222 | priv->hw.ops->unlock_irqrestore(&priv->lock, flags); |
211 | return -EBUSY; | 223 | return -EBUSY; |
212 | } | 224 | } |
213 | return 0; | 225 | return 0; |
@@ -216,7 +228,17 @@ static inline int orinoco_lock(struct orinoco_private *priv, | |||
216 | static inline void orinoco_unlock(struct orinoco_private *priv, | 228 | static inline void orinoco_unlock(struct orinoco_private *priv, |
217 | unsigned long *flags) | 229 | unsigned long *flags) |
218 | { | 230 | { |
219 | spin_unlock_irqrestore(&priv->lock, *flags); | 231 | priv->hw.ops->unlock_irqrestore(&priv->lock, flags); |
232 | } | ||
233 | |||
234 | static inline void orinoco_lock_irq(struct orinoco_private *priv) | ||
235 | { | ||
236 | priv->hw.ops->lock_irq(&priv->lock); | ||
237 | } | ||
238 | |||
239 | static inline void orinoco_unlock_irq(struct orinoco_private *priv) | ||
240 | { | ||
241 | priv->hw.ops->unlock_irq(&priv->lock); | ||
220 | } | 242 | } |
221 | 243 | ||
222 | /*** Navigate from net_device to orinoco_private ***/ | 244 | /*** Navigate from net_device to orinoco_private ***/ |
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index fdc961379170..f99b13ba92b3 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c | |||
@@ -296,7 +296,7 @@ orinoco_cs_config(struct pcmcia_device *link) | |||
296 | 296 | ||
297 | /* Register an interface with the stack */ | 297 | /* Register an interface with the stack */ |
298 | if (orinoco_if_add(priv, link->io.BasePort1, | 298 | if (orinoco_if_add(priv, link->io.BasePort1, |
299 | link->irq.AssignedIRQ) != 0) { | 299 | link->irq.AssignedIRQ, NULL) != 0) { |
300 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); | 300 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); |
301 | goto failed; | 301 | goto failed; |
302 | } | 302 | } |
@@ -327,9 +327,9 @@ orinoco_cs_release(struct pcmcia_device *link) | |||
327 | 327 | ||
328 | /* We're committed to taking the device away now, so mark the | 328 | /* We're committed to taking the device away now, so mark the |
329 | * hardware as unavailable */ | 329 | * hardware as unavailable */ |
330 | spin_lock_irqsave(&priv->lock, flags); | 330 | priv->hw.ops->lock_irqsave(&priv->lock, &flags); |
331 | priv->hw_unavailable++; | 331 | priv->hw_unavailable++; |
332 | spin_unlock_irqrestore(&priv->lock, flags); | 332 | priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); |
333 | 333 | ||
334 | pcmcia_disable_device(link); | 334 | pcmcia_disable_device(link); |
335 | if (priv->hw.iobase) | 335 | if (priv->hw.iobase) |
diff --git a/drivers/net/wireless/orinoco/orinoco_nortel.c b/drivers/net/wireless/orinoco/orinoco_nortel.c index 075f446b3139..bc3ea0b67a4f 100644 --- a/drivers/net/wireless/orinoco/orinoco_nortel.c +++ b/drivers/net/wireless/orinoco/orinoco_nortel.c | |||
@@ -220,7 +220,7 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev, | |||
220 | goto fail; | 220 | goto fail; |
221 | } | 221 | } |
222 | 222 | ||
223 | err = orinoco_if_add(priv, 0, 0); | 223 | err = orinoco_if_add(priv, 0, 0, NULL); |
224 | if (err) { | 224 | if (err) { |
225 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); | 225 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); |
226 | goto fail; | 226 | goto fail; |
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c index bda5317cc596..468197f86673 100644 --- a/drivers/net/wireless/orinoco/orinoco_pci.c +++ b/drivers/net/wireless/orinoco/orinoco_pci.c | |||
@@ -170,7 +170,7 @@ static int orinoco_pci_init_one(struct pci_dev *pdev, | |||
170 | goto fail; | 170 | goto fail; |
171 | } | 171 | } |
172 | 172 | ||
173 | err = orinoco_if_add(priv, 0, 0); | 173 | err = orinoco_if_add(priv, 0, 0, NULL); |
174 | if (err) { | 174 | if (err) { |
175 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); | 175 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); |
176 | goto fail; | 176 | goto fail; |
diff --git a/drivers/net/wireless/orinoco/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c index e0d5874ab42f..9358f4d2307b 100644 --- a/drivers/net/wireless/orinoco/orinoco_plx.c +++ b/drivers/net/wireless/orinoco/orinoco_plx.c | |||
@@ -259,7 +259,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, | |||
259 | goto fail; | 259 | goto fail; |
260 | } | 260 | } |
261 | 261 | ||
262 | err = orinoco_if_add(priv, 0, 0); | 262 | err = orinoco_if_add(priv, 0, 0, NULL); |
263 | if (err) { | 263 | if (err) { |
264 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); | 264 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); |
265 | goto fail; | 265 | goto fail; |
diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c index 88cbc7902aa0..784605f0af15 100644 --- a/drivers/net/wireless/orinoco/orinoco_tmd.c +++ b/drivers/net/wireless/orinoco/orinoco_tmd.c | |||
@@ -156,7 +156,7 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev, | |||
156 | goto fail; | 156 | goto fail; |
157 | } | 157 | } |
158 | 158 | ||
159 | err = orinoco_if_add(priv, 0, 0); | 159 | err = orinoco_if_add(priv, 0, 0, NULL); |
160 | if (err) { | 160 | if (err) { |
161 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); | 161 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); |
162 | goto fail; | 162 | goto fail; |
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c new file mode 100644 index 000000000000..e22093359f3e --- /dev/null +++ b/drivers/net/wireless/orinoco/orinoco_usb.c | |||
@@ -0,0 +1,1800 @@ | |||
1 | /* | ||
2 | * USB Orinoco driver | ||
3 | * | ||
4 | * Copyright (c) 2003 Manuel Estrada Sainz | ||
5 | * | ||
6 | * The contents of this file are subject to the Mozilla Public License | ||
7 | * Version 1.1 (the "License"); you may not use this file except in | ||
8 | * compliance with the License. You may obtain a copy of the License | ||
9 | * at http://www.mozilla.org/MPL/ | ||
10 | * | ||
11 | * Software distributed under the License is distributed on an "AS IS" | ||
12 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See | ||
13 | * the License for the specific language governing rights and | ||
14 | * limitations under the License. | ||
15 | * | ||
16 | * Alternatively, the contents of this file may be used under the | ||
17 | * terms of the GNU General Public License version 2 (the "GPL"), in | ||
18 | * which case the provisions of the GPL are applicable instead of the | ||
19 | * above. If you wish to allow the use of your version of this file | ||
20 | * only under the terms of the GPL and not to allow others to use your | ||
21 | * version of this file under the MPL, indicate your decision by | ||
22 | * deleting the provisions above and replace them with the notice and | ||
23 | * other provisions required by the GPL. If you do not delete the | ||
24 | * provisions above, a recipient may use your version of this file | ||
25 | * under either the MPL or the GPL. | ||
26 | * | ||
27 | * Queueing code based on linux-wlan-ng 0.2.1-pre5 | ||
28 | * | ||
29 | * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. | ||
30 | * | ||
31 | * The license is the same as above. | ||
32 | * | ||
33 | * Initialy based on USB Skeleton driver - 0.7 | ||
34 | * | ||
35 | * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) | ||
36 | * | ||
37 | * This program is free software; you can redistribute it and/or | ||
38 | * modify it under the terms of the GNU General Public License as | ||
39 | * published by the Free Software Foundation; either version 2 of | ||
40 | * the License, or (at your option) any later version. | ||
41 | * | ||
42 | * NOTE: The original USB Skeleton driver is GPL, but all that code is | ||
43 | * gone so MPL/GPL applies. | ||
44 | */ | ||
45 | |||
46 | #define DRIVER_NAME "orinoco_usb" | ||
47 | #define PFX DRIVER_NAME ": " | ||
48 | |||
49 | #include <linux/module.h> | ||
50 | #include <linux/kernel.h> | ||
51 | #include <linux/sched.h> | ||
52 | #include <linux/signal.h> | ||
53 | #include <linux/errno.h> | ||
54 | #include <linux/poll.h> | ||
55 | #include <linux/init.h> | ||
56 | #include <linux/slab.h> | ||
57 | #include <linux/fcntl.h> | ||
58 | #include <linux/spinlock.h> | ||
59 | #include <linux/list.h> | ||
60 | #include <linux/smp_lock.h> | ||
61 | #include <linux/usb.h> | ||
62 | #include <linux/timer.h> | ||
63 | |||
64 | #include <linux/netdevice.h> | ||
65 | #include <linux/if_arp.h> | ||
66 | #include <linux/etherdevice.h> | ||
67 | #include <linux/wireless.h> | ||
68 | #include <linux/firmware.h> | ||
69 | |||
70 | #include "orinoco.h" | ||
71 | |||
72 | #ifndef URB_ASYNC_UNLINK | ||
73 | #define URB_ASYNC_UNLINK 0 | ||
74 | #endif | ||
75 | |||
76 | /* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */ | ||
77 | static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; | ||
78 | #define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2) | ||
79 | |||
80 | struct header_struct { | ||
81 | /* 802.3 */ | ||
82 | u8 dest[ETH_ALEN]; | ||
83 | u8 src[ETH_ALEN]; | ||
84 | __be16 len; | ||
85 | /* 802.2 */ | ||
86 | u8 dsap; | ||
87 | u8 ssap; | ||
88 | u8 ctrl; | ||
89 | /* SNAP */ | ||
90 | u8 oui[3]; | ||
91 | __be16 ethertype; | ||
92 | } __attribute__ ((packed)); | ||
93 | |||
94 | struct ez_usb_fw { | ||
95 | u16 size; | ||
96 | const u8 *code; | ||
97 | }; | ||
98 | |||
99 | static struct ez_usb_fw firmware = { | ||
100 | .size = 0, | ||
101 | .code = NULL, | ||
102 | }; | ||
103 | |||
104 | #ifdef CONFIG_USB_DEBUG | ||
105 | static int debug = 1; | ||
106 | #else | ||
107 | static int debug; | ||
108 | #endif | ||
109 | |||
110 | /* Debugging macros */ | ||
111 | #undef dbg | ||
112 | #define dbg(format, arg...) \ | ||
113 | do { if (debug) printk(KERN_DEBUG PFX "%s: " format "\n", \ | ||
114 | __func__ , ## arg); } while (0) | ||
115 | #undef err | ||
116 | #define err(format, arg...) \ | ||
117 | do { printk(KERN_ERR PFX format "\n", ## arg); } while (0) | ||
118 | |||
119 | /* Module paramaters */ | ||
120 | module_param(debug, int, 0644); | ||
121 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
122 | |||
123 | MODULE_FIRMWARE("orinoco_ezusb_fw"); | ||
124 | |||
125 | /* | ||
126 | * Under some conditions, the card gets stuck and stops paying attention | ||
127 | * to the world (i.e. data communication stalls) until we do something to | ||
128 | * it. Sending an INQ_TALLIES command seems to be enough and should be | ||
129 | * harmless otherwise. This behaviour has been observed when using the | ||
130 | * driver on a systemimager client during installation. In the past a | ||
131 | * timer was used to send INQ_TALLIES commands when there was no other | ||
132 | * activity, but it was troublesome and was removed. | ||
133 | */ | ||
134 | |||
135 | #define USB_COMPAQ_VENDOR_ID 0x049f /* Compaq Computer Corp. */ | ||
136 | #define USB_COMPAQ_WL215_ID 0x001f /* Compaq WL215 USB Adapter */ | ||
137 | #define USB_COMPAQ_W200_ID 0x0076 /* Compaq W200 USB Adapter */ | ||
138 | #define USB_HP_WL215_ID 0x0082 /* Compaq WL215 USB Adapter */ | ||
139 | |||
140 | #define USB_MELCO_VENDOR_ID 0x0411 | ||
141 | #define USB_BUFFALO_L11_ID 0x0006 /* BUFFALO WLI-USB-L11 */ | ||
142 | #define USB_BUFFALO_L11G_WR_ID 0x000B /* BUFFALO WLI-USB-L11G-WR */ | ||
143 | #define USB_BUFFALO_L11G_ID 0x000D /* BUFFALO WLI-USB-L11G */ | ||
144 | |||
145 | #define USB_LUCENT_VENDOR_ID 0x047E /* Lucent Technologies */ | ||
146 | #define USB_LUCENT_ORINOCO_ID 0x0300 /* Lucent/Agere Orinoco USB Client */ | ||
147 | |||
148 | #define USB_AVAYA8_VENDOR_ID 0x0D98 | ||
149 | #define USB_AVAYAE_VENDOR_ID 0x0D9E | ||
150 | #define USB_AVAYA_WIRELESS_ID 0x0300 /* Avaya Wireless USB Card */ | ||
151 | |||
152 | #define USB_AGERE_VENDOR_ID 0x0D4E /* Agere Systems */ | ||
153 | #define USB_AGERE_MODEL0801_ID 0x1000 /* Wireless USB Card Model 0801 */ | ||
154 | #define USB_AGERE_MODEL0802_ID 0x1001 /* Wireless USB Card Model 0802 */ | ||
155 | #define USB_AGERE_REBRANDED_ID 0x047A /* WLAN USB Card */ | ||
156 | |||
157 | #define USB_ELSA_VENDOR_ID 0x05CC | ||
158 | #define USB_ELSA_AIRLANCER_ID 0x3100 /* ELSA AirLancer USB-11 */ | ||
159 | |||
160 | #define USB_LEGEND_VENDOR_ID 0x0E7C | ||
161 | #define USB_LEGEND_JOYNET_ID 0x0300 /* Joynet WLAN USB Card */ | ||
162 | |||
163 | #define USB_SAMSUNG_VENDOR_ID 0x04E8 | ||
164 | #define USB_SAMSUNG_SEW2001U1_ID 0x5002 /* Samsung SEW-2001u Card */ | ||
165 | #define USB_SAMSUNG_SEW2001U2_ID 0x5B11 /* Samsung SEW-2001u Card */ | ||
166 | #define USB_SAMSUNG_SEW2003U_ID 0x7011 /* Samsung SEW-2003U Card */ | ||
167 | |||
168 | #define USB_IGATE_VENDOR_ID 0x0681 | ||
169 | #define USB_IGATE_IGATE_11M_ID 0x0012 /* I-GATE 11M USB Card */ | ||
170 | |||
171 | #define USB_FUJITSU_VENDOR_ID 0x0BF8 | ||
172 | #define USB_FUJITSU_E1100_ID 0x1002 /* connect2AIR WLAN E-1100 USB */ | ||
173 | |||
174 | #define USB_2WIRE_VENDOR_ID 0x1630 | ||
175 | #define USB_2WIRE_WIRELESS_ID 0xff81 /* 2Wire Wireless USB adapter */ | ||
176 | |||
177 | |||
178 | #define EZUSB_REQUEST_FW_TRANS 0xA0 | ||
179 | #define EZUSB_REQUEST_TRIGER 0xAA | ||
180 | #define EZUSB_REQUEST_TRIG_AC 0xAC | ||
181 | #define EZUSB_CPUCS_REG 0x7F92 | ||
182 | |||
183 | #define EZUSB_RID_TX 0x0700 | ||
184 | #define EZUSB_RID_RX 0x0701 | ||
185 | #define EZUSB_RID_INIT1 0x0702 | ||
186 | #define EZUSB_RID_ACK 0x0710 | ||
187 | #define EZUSB_RID_READ_PDA 0x0800 | ||
188 | #define EZUSB_RID_PROG_INIT 0x0852 | ||
189 | #define EZUSB_RID_PROG_SET_ADDR 0x0853 | ||
190 | #define EZUSB_RID_PROG_BYTES 0x0854 | ||
191 | #define EZUSB_RID_PROG_END 0x0855 | ||
192 | #define EZUSB_RID_DOCMD 0x0860 | ||
193 | |||
194 | /* Recognize info frames */ | ||
195 | #define EZUSB_IS_INFO(id) ((id >= 0xF000) && (id <= 0xF2FF)) | ||
196 | |||
197 | #define EZUSB_MAGIC 0x0210 | ||
198 | |||
199 | #define EZUSB_FRAME_DATA 1 | ||
200 | #define EZUSB_FRAME_CONTROL 2 | ||
201 | |||
202 | #define DEF_TIMEOUT (3*HZ) | ||
203 | |||
204 | #define BULK_BUF_SIZE 2048 | ||
205 | |||
206 | #define MAX_DL_SIZE (BULK_BUF_SIZE - sizeof(struct ezusb_packet)) | ||
207 | |||
208 | #define FW_BUF_SIZE 64 | ||
209 | #define FW_VAR_OFFSET_PTR 0x359 | ||
210 | #define FW_VAR_VALUE 0 | ||
211 | #define FW_HOLE_START 0x100 | ||
212 | #define FW_HOLE_END 0x300 | ||
213 | |||
214 | struct ezusb_packet { | ||
215 | __le16 magic; /* 0x0210 */ | ||
216 | u8 req_reply_count; | ||
217 | u8 ans_reply_count; | ||
218 | __le16 frame_type; /* 0x01 for data frames, 0x02 otherwise */ | ||
219 | __le16 size; /* transport size */ | ||
220 | __le16 crc; /* CRC up to here */ | ||
221 | __le16 hermes_len; | ||
222 | __le16 hermes_rid; | ||
223 | u8 data[0]; | ||
224 | } __attribute__ ((packed)); | ||
225 | |||
226 | /* Table of devices that work or may work with this driver */ | ||
227 | static struct usb_device_id ezusb_table[] = { | ||
228 | {USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_COMPAQ_WL215_ID)}, | ||
229 | {USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_HP_WL215_ID)}, | ||
230 | {USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_COMPAQ_W200_ID)}, | ||
231 | {USB_DEVICE(USB_MELCO_VENDOR_ID, USB_BUFFALO_L11_ID)}, | ||
232 | {USB_DEVICE(USB_MELCO_VENDOR_ID, USB_BUFFALO_L11G_WR_ID)}, | ||
233 | {USB_DEVICE(USB_MELCO_VENDOR_ID, USB_BUFFALO_L11G_ID)}, | ||
234 | {USB_DEVICE(USB_LUCENT_VENDOR_ID, USB_LUCENT_ORINOCO_ID)}, | ||
235 | {USB_DEVICE(USB_AVAYA8_VENDOR_ID, USB_AVAYA_WIRELESS_ID)}, | ||
236 | {USB_DEVICE(USB_AVAYAE_VENDOR_ID, USB_AVAYA_WIRELESS_ID)}, | ||
237 | {USB_DEVICE(USB_AGERE_VENDOR_ID, USB_AGERE_MODEL0801_ID)}, | ||
238 | {USB_DEVICE(USB_AGERE_VENDOR_ID, USB_AGERE_MODEL0802_ID)}, | ||
239 | {USB_DEVICE(USB_ELSA_VENDOR_ID, USB_ELSA_AIRLANCER_ID)}, | ||
240 | {USB_DEVICE(USB_LEGEND_VENDOR_ID, USB_LEGEND_JOYNET_ID)}, | ||
241 | {USB_DEVICE_VER(USB_SAMSUNG_VENDOR_ID, USB_SAMSUNG_SEW2001U1_ID, | ||
242 | 0, 0)}, | ||
243 | {USB_DEVICE(USB_SAMSUNG_VENDOR_ID, USB_SAMSUNG_SEW2001U2_ID)}, | ||
244 | {USB_DEVICE(USB_SAMSUNG_VENDOR_ID, USB_SAMSUNG_SEW2003U_ID)}, | ||
245 | {USB_DEVICE(USB_IGATE_VENDOR_ID, USB_IGATE_IGATE_11M_ID)}, | ||
246 | {USB_DEVICE(USB_FUJITSU_VENDOR_ID, USB_FUJITSU_E1100_ID)}, | ||
247 | {USB_DEVICE(USB_2WIRE_VENDOR_ID, USB_2WIRE_WIRELESS_ID)}, | ||
248 | {USB_DEVICE(USB_AGERE_VENDOR_ID, USB_AGERE_REBRANDED_ID)}, | ||
249 | {} /* Terminating entry */ | ||
250 | }; | ||
251 | |||
252 | MODULE_DEVICE_TABLE(usb, ezusb_table); | ||
253 | |||
254 | /* Structure to hold all of our device specific stuff */ | ||
255 | struct ezusb_priv { | ||
256 | struct usb_device *udev; | ||
257 | struct net_device *dev; | ||
258 | struct mutex mtx; | ||
259 | spinlock_t req_lock; | ||
260 | struct list_head req_pending; | ||
261 | struct list_head req_active; | ||
262 | spinlock_t reply_count_lock; | ||
263 | u16 hermes_reg_fake[0x40]; | ||
264 | u8 *bap_buf; | ||
265 | struct urb *read_urb; | ||
266 | int read_pipe; | ||
267 | int write_pipe; | ||
268 | u8 reply_count; | ||
269 | }; | ||
270 | |||
271 | enum ezusb_state { | ||
272 | EZUSB_CTX_START, | ||
273 | EZUSB_CTX_QUEUED, | ||
274 | EZUSB_CTX_REQ_SUBMITTED, | ||
275 | EZUSB_CTX_REQ_COMPLETE, | ||
276 | EZUSB_CTX_RESP_RECEIVED, | ||
277 | EZUSB_CTX_REQ_TIMEOUT, | ||
278 | EZUSB_CTX_REQ_FAILED, | ||
279 | EZUSB_CTX_RESP_TIMEOUT, | ||
280 | EZUSB_CTX_REQSUBMIT_FAIL, | ||
281 | EZUSB_CTX_COMPLETE, | ||
282 | }; | ||
283 | |||
284 | struct request_context { | ||
285 | struct list_head list; | ||
286 | atomic_t refcount; | ||
287 | struct completion done; /* Signals that CTX is dead */ | ||
288 | int killed; | ||
289 | struct urb *outurb; /* OUT for req pkt */ | ||
290 | struct ezusb_priv *upriv; | ||
291 | struct ezusb_packet *buf; | ||
292 | int buf_length; | ||
293 | struct timer_list timer; /* Timeout handling */ | ||
294 | enum ezusb_state state; /* Current state */ | ||
295 | /* the RID that we will wait for */ | ||
296 | u16 out_rid; | ||
297 | u16 in_rid; | ||
298 | }; | ||
299 | |||
300 | |||
301 | /* Forward declarations */ | ||
302 | static void ezusb_ctx_complete(struct request_context *ctx); | ||
303 | static void ezusb_req_queue_run(struct ezusb_priv *upriv); | ||
304 | static void ezusb_bulk_in_callback(struct urb *urb); | ||
305 | |||
306 | static inline u8 ezusb_reply_inc(u8 count) | ||
307 | { | ||
308 | if (count < 0x7F) | ||
309 | return count + 1; | ||
310 | else | ||
311 | return 1; | ||
312 | } | ||
313 | |||
314 | static void ezusb_request_context_put(struct request_context *ctx) | ||
315 | { | ||
316 | if (!atomic_dec_and_test(&ctx->refcount)) | ||
317 | return; | ||
318 | |||
319 | WARN_ON(!ctx->done.done); | ||
320 | BUG_ON(ctx->outurb->status == -EINPROGRESS); | ||
321 | BUG_ON(timer_pending(&ctx->timer)); | ||
322 | usb_free_urb(ctx->outurb); | ||
323 | kfree(ctx->buf); | ||
324 | kfree(ctx); | ||
325 | } | ||
326 | |||
327 | static inline void ezusb_mod_timer(struct ezusb_priv *upriv, | ||
328 | struct timer_list *timer, | ||
329 | unsigned long expire) | ||
330 | { | ||
331 | if (!upriv->udev) | ||
332 | return; | ||
333 | mod_timer(timer, expire); | ||
334 | } | ||
335 | |||
336 | static void ezusb_request_timerfn(u_long _ctx) | ||
337 | { | ||
338 | struct request_context *ctx = (void *) _ctx; | ||
339 | |||
340 | ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK; | ||
341 | if (usb_unlink_urb(ctx->outurb) == -EINPROGRESS) { | ||
342 | ctx->state = EZUSB_CTX_REQ_TIMEOUT; | ||
343 | } else { | ||
344 | ctx->state = EZUSB_CTX_RESP_TIMEOUT; | ||
345 | dbg("couldn't unlink"); | ||
346 | atomic_inc(&ctx->refcount); | ||
347 | ctx->killed = 1; | ||
348 | ezusb_ctx_complete(ctx); | ||
349 | ezusb_request_context_put(ctx); | ||
350 | } | ||
351 | }; | ||
352 | |||
353 | static struct request_context *ezusb_alloc_ctx(struct ezusb_priv *upriv, | ||
354 | u16 out_rid, u16 in_rid) | ||
355 | { | ||
356 | struct request_context *ctx; | ||
357 | |||
358 | ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC); | ||
359 | if (!ctx) | ||
360 | return NULL; | ||
361 | |||
362 | memset(ctx, 0, sizeof(*ctx)); | ||
363 | |||
364 | ctx->buf = kmalloc(BULK_BUF_SIZE, GFP_ATOMIC); | ||
365 | if (!ctx->buf) { | ||
366 | kfree(ctx); | ||
367 | return NULL; | ||
368 | } | ||
369 | ctx->outurb = usb_alloc_urb(0, GFP_ATOMIC); | ||
370 | if (!ctx->outurb) { | ||
371 | kfree(ctx->buf); | ||
372 | kfree(ctx); | ||
373 | return NULL; | ||
374 | } | ||
375 | |||
376 | ctx->upriv = upriv; | ||
377 | ctx->state = EZUSB_CTX_START; | ||
378 | ctx->out_rid = out_rid; | ||
379 | ctx->in_rid = in_rid; | ||
380 | |||
381 | atomic_set(&ctx->refcount, 1); | ||
382 | init_completion(&ctx->done); | ||
383 | |||
384 | init_timer(&ctx->timer); | ||
385 | ctx->timer.function = ezusb_request_timerfn; | ||
386 | ctx->timer.data = (u_long) ctx; | ||
387 | return ctx; | ||
388 | } | ||
389 | |||
390 | |||
391 | /* Hopefully the real complete_all will soon be exported, in the mean | ||
392 | * while this should work. */ | ||
393 | static inline void ezusb_complete_all(struct completion *comp) | ||
394 | { | ||
395 | complete(comp); | ||
396 | complete(comp); | ||
397 | complete(comp); | ||
398 | complete(comp); | ||
399 | } | ||
400 | |||
401 | static void ezusb_ctx_complete(struct request_context *ctx) | ||
402 | { | ||
403 | struct ezusb_priv *upriv = ctx->upriv; | ||
404 | unsigned long flags; | ||
405 | |||
406 | spin_lock_irqsave(&upriv->req_lock, flags); | ||
407 | |||
408 | list_del_init(&ctx->list); | ||
409 | if (upriv->udev) { | ||
410 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
411 | ezusb_req_queue_run(upriv); | ||
412 | spin_lock_irqsave(&upriv->req_lock, flags); | ||
413 | } | ||
414 | |||
415 | switch (ctx->state) { | ||
416 | case EZUSB_CTX_COMPLETE: | ||
417 | case EZUSB_CTX_REQSUBMIT_FAIL: | ||
418 | case EZUSB_CTX_REQ_FAILED: | ||
419 | case EZUSB_CTX_REQ_TIMEOUT: | ||
420 | case EZUSB_CTX_RESP_TIMEOUT: | ||
421 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
422 | |||
423 | if ((ctx->out_rid == EZUSB_RID_TX) && upriv->dev) { | ||
424 | struct net_device *dev = upriv->dev; | ||
425 | struct orinoco_private *priv = ndev_priv(dev); | ||
426 | struct net_device_stats *stats = &priv->stats; | ||
427 | |||
428 | if (ctx->state != EZUSB_CTX_COMPLETE) | ||
429 | stats->tx_errors++; | ||
430 | else | ||
431 | stats->tx_packets++; | ||
432 | |||
433 | netif_wake_queue(dev); | ||
434 | } | ||
435 | ezusb_complete_all(&ctx->done); | ||
436 | ezusb_request_context_put(ctx); | ||
437 | break; | ||
438 | |||
439 | default: | ||
440 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
441 | if (!upriv->udev) { | ||
442 | /* This is normal, as all request contexts get flushed | ||
443 | * when the device is disconnected */ | ||
444 | err("Called, CTX not terminating, but device gone"); | ||
445 | ezusb_complete_all(&ctx->done); | ||
446 | ezusb_request_context_put(ctx); | ||
447 | break; | ||
448 | } | ||
449 | |||
450 | err("Called, CTX not in terminating state."); | ||
451 | /* Things are really bad if this happens. Just leak | ||
452 | * the CTX because it may still be linked to the | ||
453 | * queue or the OUT urb may still be active. | ||
454 | * Just leaking at least prevents an Oops or Panic. | ||
455 | */ | ||
456 | break; | ||
457 | } | ||
458 | } | ||
459 | |||
460 | /** | ||
461 | * ezusb_req_queue_run: | ||
462 | * Description: | ||
463 | * Note: Only one active CTX at any one time, because there's no | ||
464 | * other (reliable) way to match the response URB to the correct | ||
465 | * CTX. | ||
466 | **/ | ||
467 | static void ezusb_req_queue_run(struct ezusb_priv *upriv) | ||
468 | { | ||
469 | unsigned long flags; | ||
470 | struct request_context *ctx; | ||
471 | int result; | ||
472 | |||
473 | spin_lock_irqsave(&upriv->req_lock, flags); | ||
474 | |||
475 | if (!list_empty(&upriv->req_active)) | ||
476 | goto unlock; | ||
477 | |||
478 | if (list_empty(&upriv->req_pending)) | ||
479 | goto unlock; | ||
480 | |||
481 | ctx = | ||
482 | list_entry(upriv->req_pending.next, struct request_context, | ||
483 | list); | ||
484 | |||
485 | if (!ctx->upriv->udev) | ||
486 | goto unlock; | ||
487 | |||
488 | /* We need to split this off to avoid a race condition */ | ||
489 | list_move_tail(&ctx->list, &upriv->req_active); | ||
490 | |||
491 | if (ctx->state == EZUSB_CTX_QUEUED) { | ||
492 | atomic_inc(&ctx->refcount); | ||
493 | result = usb_submit_urb(ctx->outurb, GFP_ATOMIC); | ||
494 | if (result) { | ||
495 | ctx->state = EZUSB_CTX_REQSUBMIT_FAIL; | ||
496 | |||
497 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
498 | |||
499 | err("Fatal, failed to submit command urb." | ||
500 | " error=%d\n", result); | ||
501 | |||
502 | ezusb_ctx_complete(ctx); | ||
503 | ezusb_request_context_put(ctx); | ||
504 | goto done; | ||
505 | } | ||
506 | |||
507 | ctx->state = EZUSB_CTX_REQ_SUBMITTED; | ||
508 | ezusb_mod_timer(ctx->upriv, &ctx->timer, | ||
509 | jiffies + DEF_TIMEOUT); | ||
510 | } | ||
511 | |||
512 | unlock: | ||
513 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
514 | |||
515 | done: | ||
516 | return; | ||
517 | } | ||
518 | |||
519 | static void ezusb_req_enqueue_run(struct ezusb_priv *upriv, | ||
520 | struct request_context *ctx) | ||
521 | { | ||
522 | unsigned long flags; | ||
523 | |||
524 | spin_lock_irqsave(&upriv->req_lock, flags); | ||
525 | |||
526 | if (!ctx->upriv->udev) { | ||
527 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
528 | goto done; | ||
529 | } | ||
530 | atomic_inc(&ctx->refcount); | ||
531 | list_add_tail(&ctx->list, &upriv->req_pending); | ||
532 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
533 | |||
534 | ctx->state = EZUSB_CTX_QUEUED; | ||
535 | ezusb_req_queue_run(upriv); | ||
536 | |||
537 | done: | ||
538 | return; | ||
539 | } | ||
540 | |||
541 | static void ezusb_request_out_callback(struct urb *urb) | ||
542 | { | ||
543 | unsigned long flags; | ||
544 | enum ezusb_state state; | ||
545 | struct request_context *ctx = urb->context; | ||
546 | struct ezusb_priv *upriv = ctx->upriv; | ||
547 | |||
548 | spin_lock_irqsave(&upriv->req_lock, flags); | ||
549 | |||
550 | del_timer(&ctx->timer); | ||
551 | |||
552 | if (ctx->killed) { | ||
553 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
554 | pr_warning("interrupt called with dead ctx"); | ||
555 | goto out; | ||
556 | } | ||
557 | |||
558 | state = ctx->state; | ||
559 | |||
560 | if (urb->status == 0) { | ||
561 | switch (state) { | ||
562 | case EZUSB_CTX_REQ_SUBMITTED: | ||
563 | if (ctx->in_rid) { | ||
564 | ctx->state = EZUSB_CTX_REQ_COMPLETE; | ||
565 | /* reply URB still pending */ | ||
566 | ezusb_mod_timer(upriv, &ctx->timer, | ||
567 | jiffies + DEF_TIMEOUT); | ||
568 | spin_unlock_irqrestore(&upriv->req_lock, | ||
569 | flags); | ||
570 | break; | ||
571 | } | ||
572 | /* fall through */ | ||
573 | case EZUSB_CTX_RESP_RECEIVED: | ||
574 | /* IN already received before this OUT-ACK */ | ||
575 | ctx->state = EZUSB_CTX_COMPLETE; | ||
576 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
577 | ezusb_ctx_complete(ctx); | ||
578 | break; | ||
579 | |||
580 | default: | ||
581 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
582 | err("Unexpected state(0x%x, %d) in OUT URB", | ||
583 | state, urb->status); | ||
584 | break; | ||
585 | } | ||
586 | } else { | ||
587 | /* If someone cancels the OUT URB then its status | ||
588 | * should be either -ECONNRESET or -ENOENT. | ||
589 | */ | ||
590 | switch (state) { | ||
591 | case EZUSB_CTX_REQ_SUBMITTED: | ||
592 | case EZUSB_CTX_RESP_RECEIVED: | ||
593 | ctx->state = EZUSB_CTX_REQ_FAILED; | ||
594 | /* fall through */ | ||
595 | |||
596 | case EZUSB_CTX_REQ_FAILED: | ||
597 | case EZUSB_CTX_REQ_TIMEOUT: | ||
598 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
599 | |||
600 | ezusb_ctx_complete(ctx); | ||
601 | break; | ||
602 | |||
603 | default: | ||
604 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
605 | |||
606 | err("Unexpected state(0x%x, %d) in OUT URB", | ||
607 | state, urb->status); | ||
608 | break; | ||
609 | } | ||
610 | } | ||
611 | out: | ||
612 | ezusb_request_context_put(ctx); | ||
613 | } | ||
614 | |||
615 | static void ezusb_request_in_callback(struct ezusb_priv *upriv, | ||
616 | struct urb *urb) | ||
617 | { | ||
618 | struct ezusb_packet *ans = urb->transfer_buffer; | ||
619 | struct request_context *ctx = NULL; | ||
620 | enum ezusb_state state; | ||
621 | unsigned long flags; | ||
622 | |||
623 | /* Find the CTX on the active queue that requested this URB */ | ||
624 | spin_lock_irqsave(&upriv->req_lock, flags); | ||
625 | if (upriv->udev) { | ||
626 | struct list_head *item; | ||
627 | |||
628 | list_for_each(item, &upriv->req_active) { | ||
629 | struct request_context *c; | ||
630 | int reply_count; | ||
631 | |||
632 | c = list_entry(item, struct request_context, list); | ||
633 | reply_count = | ||
634 | ezusb_reply_inc(c->buf->req_reply_count); | ||
635 | if ((ans->ans_reply_count == reply_count) | ||
636 | && (le16_to_cpu(ans->hermes_rid) == c->in_rid)) { | ||
637 | ctx = c; | ||
638 | break; | ||
639 | } | ||
640 | dbg("Skipped (0x%x/0x%x) (%d/%d)", | ||
641 | le16_to_cpu(ans->hermes_rid), | ||
642 | c->in_rid, ans->ans_reply_count, reply_count); | ||
643 | } | ||
644 | } | ||
645 | |||
646 | if (ctx == NULL) { | ||
647 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
648 | err("%s: got unexpected RID: 0x%04X", __func__, | ||
649 | le16_to_cpu(ans->hermes_rid)); | ||
650 | ezusb_req_queue_run(upriv); | ||
651 | return; | ||
652 | } | ||
653 | |||
654 | /* The data we want is in the in buffer, exchange */ | ||
655 | urb->transfer_buffer = ctx->buf; | ||
656 | ctx->buf = (void *) ans; | ||
657 | ctx->buf_length = urb->actual_length; | ||
658 | |||
659 | state = ctx->state; | ||
660 | switch (state) { | ||
661 | case EZUSB_CTX_REQ_SUBMITTED: | ||
662 | /* We have received our response URB before | ||
663 | * our request has been acknowledged. Do NOT | ||
664 | * destroy our CTX yet, because our OUT URB | ||
665 | * is still alive ... | ||
666 | */ | ||
667 | ctx->state = EZUSB_CTX_RESP_RECEIVED; | ||
668 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
669 | |||
670 | /* Let the machine continue running. */ | ||
671 | break; | ||
672 | |||
673 | case EZUSB_CTX_REQ_COMPLETE: | ||
674 | /* This is the usual path: our request | ||
675 | * has already been acknowledged, and | ||
676 | * we have now received the reply. | ||
677 | */ | ||
678 | ctx->state = EZUSB_CTX_COMPLETE; | ||
679 | |||
680 | /* Stop the intimer */ | ||
681 | del_timer(&ctx->timer); | ||
682 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
683 | |||
684 | /* Call the completion handler */ | ||
685 | ezusb_ctx_complete(ctx); | ||
686 | break; | ||
687 | |||
688 | default: | ||
689 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
690 | |||
691 | pr_warning("Matched IN URB, unexpected context state(0x%x)", | ||
692 | state); | ||
693 | /* Throw this CTX away and try submitting another */ | ||
694 | del_timer(&ctx->timer); | ||
695 | ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK; | ||
696 | usb_unlink_urb(ctx->outurb); | ||
697 | ezusb_req_queue_run(upriv); | ||
698 | break; | ||
699 | } /* switch */ | ||
700 | } | ||
701 | |||
702 | |||
703 | static void ezusb_req_ctx_wait(struct ezusb_priv *upriv, | ||
704 | struct request_context *ctx) | ||
705 | { | ||
706 | switch (ctx->state) { | ||
707 | case EZUSB_CTX_QUEUED: | ||
708 | case EZUSB_CTX_REQ_SUBMITTED: | ||
709 | case EZUSB_CTX_REQ_COMPLETE: | ||
710 | case EZUSB_CTX_RESP_RECEIVED: | ||
711 | if (in_softirq()) { | ||
712 | /* If we get called from a timer, timeout timers don't | ||
713 | * get the chance to run themselves. So we make sure | ||
714 | * that we don't sleep for ever */ | ||
715 | int msecs = DEF_TIMEOUT * (1000 / HZ); | ||
716 | while (!ctx->done.done && msecs--) | ||
717 | udelay(1000); | ||
718 | } else { | ||
719 | wait_event_interruptible(ctx->done.wait, | ||
720 | ctx->done.done); | ||
721 | } | ||
722 | break; | ||
723 | default: | ||
724 | /* Done or failed - nothing to wait for */ | ||
725 | break; | ||
726 | } | ||
727 | } | ||
728 | |||
729 | static inline u16 build_crc(struct ezusb_packet *data) | ||
730 | { | ||
731 | u16 crc = 0; | ||
732 | u8 *bytes = (u8 *)data; | ||
733 | int i; | ||
734 | |||
735 | for (i = 0; i < 8; i++) | ||
736 | crc = (crc << 1) + bytes[i]; | ||
737 | |||
738 | return crc; | ||
739 | } | ||
740 | |||
741 | /** | ||
742 | * ezusb_fill_req: | ||
743 | * | ||
744 | * if data == NULL and length > 0 the data is assumed to be already in | ||
745 | * the target buffer and only the header is filled. | ||
746 | * | ||
747 | */ | ||
748 | static int ezusb_fill_req(struct ezusb_packet *req, u16 length, u16 rid, | ||
749 | const void *data, u16 frame_type, u8 reply_count) | ||
750 | { | ||
751 | int total_size = sizeof(*req) + length; | ||
752 | |||
753 | BUG_ON(total_size > BULK_BUF_SIZE); | ||
754 | |||
755 | req->magic = cpu_to_le16(EZUSB_MAGIC); | ||
756 | req->req_reply_count = reply_count; | ||
757 | req->ans_reply_count = 0; | ||
758 | req->frame_type = cpu_to_le16(frame_type); | ||
759 | req->size = cpu_to_le16(length + 4); | ||
760 | req->crc = cpu_to_le16(build_crc(req)); | ||
761 | req->hermes_len = cpu_to_le16(HERMES_BYTES_TO_RECLEN(length)); | ||
762 | req->hermes_rid = cpu_to_le16(rid); | ||
763 | if (data) | ||
764 | memcpy(req->data, data, length); | ||
765 | return total_size; | ||
766 | } | ||
767 | |||
768 | static int ezusb_submit_in_urb(struct ezusb_priv *upriv) | ||
769 | { | ||
770 | int retval = 0; | ||
771 | void *cur_buf = upriv->read_urb->transfer_buffer; | ||
772 | |||
773 | if (upriv->read_urb->status == -EINPROGRESS) { | ||
774 | dbg("urb busy, not resubmiting"); | ||
775 | retval = -EBUSY; | ||
776 | goto exit; | ||
777 | } | ||
778 | usb_fill_bulk_urb(upriv->read_urb, upriv->udev, upriv->read_pipe, | ||
779 | cur_buf, BULK_BUF_SIZE, | ||
780 | ezusb_bulk_in_callback, upriv); | ||
781 | upriv->read_urb->transfer_flags = 0; | ||
782 | retval = usb_submit_urb(upriv->read_urb, GFP_ATOMIC); | ||
783 | if (retval) | ||
784 | err("%s submit failed %d", __func__, retval); | ||
785 | |||
786 | exit: | ||
787 | return retval; | ||
788 | } | ||
789 | |||
790 | static inline int ezusb_8051_cpucs(struct ezusb_priv *upriv, int reset) | ||
791 | { | ||
792 | u8 res_val = reset; /* avoid argument promotion */ | ||
793 | |||
794 | if (!upriv->udev) { | ||
795 | err("%s: !upriv->udev", __func__); | ||
796 | return -EFAULT; | ||
797 | } | ||
798 | return usb_control_msg(upriv->udev, | ||
799 | usb_sndctrlpipe(upriv->udev, 0), | ||
800 | EZUSB_REQUEST_FW_TRANS, | ||
801 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | | ||
802 | USB_DIR_OUT, EZUSB_CPUCS_REG, 0, &res_val, | ||
803 | sizeof(res_val), DEF_TIMEOUT); | ||
804 | } | ||
805 | |||
806 | static int ezusb_firmware_download(struct ezusb_priv *upriv, | ||
807 | struct ez_usb_fw *fw) | ||
808 | { | ||
809 | u8 fw_buffer[FW_BUF_SIZE]; | ||
810 | int retval, addr; | ||
811 | int variant_offset; | ||
812 | |||
813 | /* | ||
814 | * This byte is 1 and should be replaced with 0. The offset is | ||
815 | * 0x10AD in version 0.0.6. The byte in question should follow | ||
816 | * the end of the code pointed to by the jump in the beginning | ||
817 | * of the firmware. Also, it is read by code located at 0x358. | ||
818 | */ | ||
819 | variant_offset = be16_to_cpup((__be16 *) &fw->code[FW_VAR_OFFSET_PTR]); | ||
820 | if (variant_offset >= fw->size) { | ||
821 | printk(KERN_ERR PFX "Invalid firmware variant offset: " | ||
822 | "0x%04x\n", variant_offset); | ||
823 | retval = -EINVAL; | ||
824 | goto fail; | ||
825 | } | ||
826 | |||
827 | retval = ezusb_8051_cpucs(upriv, 1); | ||
828 | if (retval < 0) | ||
829 | goto fail; | ||
830 | for (addr = 0; addr < fw->size; addr += FW_BUF_SIZE) { | ||
831 | /* 0x100-0x300 should be left alone, it contains card | ||
832 | * specific data, like USB enumeration information */ | ||
833 | if ((addr >= FW_HOLE_START) && (addr < FW_HOLE_END)) | ||
834 | continue; | ||
835 | |||
836 | memcpy(fw_buffer, &fw->code[addr], FW_BUF_SIZE); | ||
837 | if (variant_offset >= addr && | ||
838 | variant_offset < addr + FW_BUF_SIZE) { | ||
839 | dbg("Patching card_variant byte at 0x%04X", | ||
840 | variant_offset); | ||
841 | fw_buffer[variant_offset - addr] = FW_VAR_VALUE; | ||
842 | } | ||
843 | retval = usb_control_msg(upriv->udev, | ||
844 | usb_sndctrlpipe(upriv->udev, 0), | ||
845 | EZUSB_REQUEST_FW_TRANS, | ||
846 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | ||
847 | | USB_DIR_OUT, | ||
848 | addr, 0x0, | ||
849 | fw_buffer, FW_BUF_SIZE, | ||
850 | DEF_TIMEOUT); | ||
851 | |||
852 | if (retval < 0) | ||
853 | goto fail; | ||
854 | } | ||
855 | retval = ezusb_8051_cpucs(upriv, 0); | ||
856 | if (retval < 0) | ||
857 | goto fail; | ||
858 | |||
859 | goto exit; | ||
860 | fail: | ||
861 | printk(KERN_ERR PFX "Firmware download failed, error %d\n", | ||
862 | retval); | ||
863 | exit: | ||
864 | return retval; | ||
865 | } | ||
866 | |||
867 | static int ezusb_access_ltv(struct ezusb_priv *upriv, | ||
868 | struct request_context *ctx, | ||
869 | u16 length, const void *data, u16 frame_type, | ||
870 | void *ans_buff, int ans_size, u16 *ans_length) | ||
871 | { | ||
872 | int req_size; | ||
873 | int retval = 0; | ||
874 | enum ezusb_state state; | ||
875 | |||
876 | BUG_ON(in_irq()); | ||
877 | |||
878 | if (!upriv->udev) { | ||
879 | dbg("Device disconnected"); | ||
880 | return -ENODEV; | ||
881 | } | ||
882 | |||
883 | if (upriv->read_urb->status != -EINPROGRESS) | ||
884 | err("%s: in urb not pending", __func__); | ||
885 | |||
886 | /* protect upriv->reply_count, guarantee sequential numbers */ | ||
887 | spin_lock_bh(&upriv->reply_count_lock); | ||
888 | req_size = ezusb_fill_req(ctx->buf, length, ctx->out_rid, data, | ||
889 | frame_type, upriv->reply_count); | ||
890 | usb_fill_bulk_urb(ctx->outurb, upriv->udev, upriv->write_pipe, | ||
891 | ctx->buf, req_size, | ||
892 | ezusb_request_out_callback, ctx); | ||
893 | |||
894 | if (ctx->in_rid) | ||
895 | upriv->reply_count = ezusb_reply_inc(upriv->reply_count); | ||
896 | |||
897 | ezusb_req_enqueue_run(upriv, ctx); | ||
898 | |||
899 | spin_unlock_bh(&upriv->reply_count_lock); | ||
900 | |||
901 | if (ctx->in_rid) | ||
902 | ezusb_req_ctx_wait(upriv, ctx); | ||
903 | |||
904 | state = ctx->state; | ||
905 | switch (state) { | ||
906 | case EZUSB_CTX_COMPLETE: | ||
907 | retval = ctx->outurb->status; | ||
908 | break; | ||
909 | |||
910 | case EZUSB_CTX_QUEUED: | ||
911 | case EZUSB_CTX_REQ_SUBMITTED: | ||
912 | if (!ctx->in_rid) | ||
913 | break; | ||
914 | default: | ||
915 | err("%s: Unexpected context state %d", __func__, | ||
916 | state); | ||
917 | /* fall though */ | ||
918 | case EZUSB_CTX_REQ_TIMEOUT: | ||
919 | case EZUSB_CTX_REQ_FAILED: | ||
920 | case EZUSB_CTX_RESP_TIMEOUT: | ||
921 | case EZUSB_CTX_REQSUBMIT_FAIL: | ||
922 | printk(KERN_ERR PFX "Access failed, resetting (state %d," | ||
923 | " reply_count %d)\n", state, upriv->reply_count); | ||
924 | upriv->reply_count = 0; | ||
925 | if (state == EZUSB_CTX_REQ_TIMEOUT | ||
926 | || state == EZUSB_CTX_RESP_TIMEOUT) { | ||
927 | printk(KERN_ERR PFX "ctx timed out\n"); | ||
928 | retval = -ETIMEDOUT; | ||
929 | } else { | ||
930 | printk(KERN_ERR PFX "ctx failed\n"); | ||
931 | retval = -EFAULT; | ||
932 | } | ||
933 | goto exit; | ||
934 | break; | ||
935 | } | ||
936 | if (ctx->in_rid) { | ||
937 | struct ezusb_packet *ans = ctx->buf; | ||
938 | int exp_len; | ||
939 | |||
940 | if (ans->hermes_len != 0) | ||
941 | exp_len = le16_to_cpu(ans->hermes_len) * 2 + 12; | ||
942 | else | ||
943 | exp_len = 14; | ||
944 | |||
945 | if (exp_len != ctx->buf_length) { | ||
946 | err("%s: length mismatch for RID 0x%04x: " | ||
947 | "expected %d, got %d", __func__, | ||
948 | ctx->in_rid, exp_len, ctx->buf_length); | ||
949 | retval = -EIO; | ||
950 | goto exit; | ||
951 | } | ||
952 | |||
953 | if (ans_buff) | ||
954 | memcpy(ans_buff, ans->data, | ||
955 | min_t(int, exp_len, ans_size)); | ||
956 | if (ans_length) | ||
957 | *ans_length = le16_to_cpu(ans->hermes_len); | ||
958 | } | ||
959 | exit: | ||
960 | ezusb_request_context_put(ctx); | ||
961 | return retval; | ||
962 | } | ||
963 | |||
964 | static int ezusb_write_ltv(hermes_t *hw, int bap, u16 rid, | ||
965 | u16 length, const void *data) | ||
966 | { | ||
967 | struct ezusb_priv *upriv = hw->priv; | ||
968 | u16 frame_type; | ||
969 | struct request_context *ctx; | ||
970 | |||
971 | if (length == 0) | ||
972 | return -EINVAL; | ||
973 | |||
974 | length = HERMES_RECLEN_TO_BYTES(length); | ||
975 | |||
976 | /* On memory mapped devices HERMES_RID_CNFGROUPADDRESSES can be | ||
977 | * set to be empty, but the USB bridge doesn't like it */ | ||
978 | if (length == 0) | ||
979 | return 0; | ||
980 | |||
981 | ctx = ezusb_alloc_ctx(upriv, rid, EZUSB_RID_ACK); | ||
982 | if (!ctx) | ||
983 | return -ENOMEM; | ||
984 | |||
985 | if (rid == EZUSB_RID_TX) | ||
986 | frame_type = EZUSB_FRAME_DATA; | ||
987 | else | ||
988 | frame_type = EZUSB_FRAME_CONTROL; | ||
989 | |||
990 | return ezusb_access_ltv(upriv, ctx, length, data, frame_type, | ||
991 | NULL, 0, NULL); | ||
992 | } | ||
993 | |||
994 | static int ezusb_read_ltv(hermes_t *hw, int bap, u16 rid, | ||
995 | unsigned bufsize, u16 *length, void *buf) | ||
996 | { | ||
997 | struct ezusb_priv *upriv = hw->priv; | ||
998 | struct request_context *ctx; | ||
999 | |||
1000 | if ((bufsize < 0) || (bufsize % 2)) | ||
1001 | return -EINVAL; | ||
1002 | |||
1003 | ctx = ezusb_alloc_ctx(upriv, rid, rid); | ||
1004 | if (!ctx) | ||
1005 | return -ENOMEM; | ||
1006 | |||
1007 | return ezusb_access_ltv(upriv, ctx, 0, NULL, EZUSB_FRAME_CONTROL, | ||
1008 | buf, bufsize, length); | ||
1009 | } | ||
1010 | |||
1011 | static int ezusb_doicmd_wait(hermes_t *hw, u16 cmd, u16 parm0, u16 parm1, | ||
1012 | u16 parm2, struct hermes_response *resp) | ||
1013 | { | ||
1014 | struct ezusb_priv *upriv = hw->priv; | ||
1015 | struct request_context *ctx; | ||
1016 | |||
1017 | __le16 data[4] = { | ||
1018 | cpu_to_le16(cmd), | ||
1019 | cpu_to_le16(parm0), | ||
1020 | cpu_to_le16(parm1), | ||
1021 | cpu_to_le16(parm2), | ||
1022 | }; | ||
1023 | dbg("0x%04X, parm0 0x%04X, parm1 0x%04X, parm2 0x%04X", | ||
1024 | cmd, parm0, parm1, parm2); | ||
1025 | ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_DOCMD, EZUSB_RID_ACK); | ||
1026 | if (!ctx) | ||
1027 | return -ENOMEM; | ||
1028 | |||
1029 | return ezusb_access_ltv(upriv, ctx, sizeof(data), &data, | ||
1030 | EZUSB_FRAME_CONTROL, NULL, 0, NULL); | ||
1031 | } | ||
1032 | |||
1033 | static int ezusb_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, | ||
1034 | struct hermes_response *resp) | ||
1035 | { | ||
1036 | struct ezusb_priv *upriv = hw->priv; | ||
1037 | struct request_context *ctx; | ||
1038 | |||
1039 | __le16 data[4] = { | ||
1040 | cpu_to_le16(cmd), | ||
1041 | cpu_to_le16(parm0), | ||
1042 | 0, | ||
1043 | 0, | ||
1044 | }; | ||
1045 | dbg("0x%04X, parm0 0x%04X", cmd, parm0); | ||
1046 | ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_DOCMD, EZUSB_RID_ACK); | ||
1047 | if (!ctx) | ||
1048 | return -ENOMEM; | ||
1049 | |||
1050 | return ezusb_access_ltv(upriv, ctx, sizeof(data), &data, | ||
1051 | EZUSB_FRAME_CONTROL, NULL, 0, NULL); | ||
1052 | } | ||
1053 | |||
1054 | static int ezusb_bap_pread(struct hermes *hw, int bap, | ||
1055 | void *buf, int len, u16 id, u16 offset) | ||
1056 | { | ||
1057 | struct ezusb_priv *upriv = hw->priv; | ||
1058 | struct ezusb_packet *ans = (void *) upriv->read_urb->transfer_buffer; | ||
1059 | int actual_length = upriv->read_urb->actual_length; | ||
1060 | |||
1061 | if (id == EZUSB_RID_RX) { | ||
1062 | if ((sizeof(*ans) + offset + len) > actual_length) { | ||
1063 | printk(KERN_ERR PFX "BAP read beyond buffer end " | ||
1064 | "in rx frame\n"); | ||
1065 | return -EINVAL; | ||
1066 | } | ||
1067 | memcpy(buf, ans->data + offset, len); | ||
1068 | return 0; | ||
1069 | } | ||
1070 | |||
1071 | if (EZUSB_IS_INFO(id)) { | ||
1072 | /* Include 4 bytes for length/type */ | ||
1073 | if ((sizeof(*ans) + offset + len - 4) > actual_length) { | ||
1074 | printk(KERN_ERR PFX "BAP read beyond buffer end " | ||
1075 | "in info frame\n"); | ||
1076 | return -EFAULT; | ||
1077 | } | ||
1078 | memcpy(buf, ans->data + offset - 4, len); | ||
1079 | } else { | ||
1080 | printk(KERN_ERR PFX "Unexpected fid 0x%04x\n", id); | ||
1081 | return -EINVAL; | ||
1082 | } | ||
1083 | |||
1084 | return 0; | ||
1085 | } | ||
1086 | |||
1087 | static int ezusb_read_pda(struct hermes *hw, __le16 *pda, | ||
1088 | u32 pda_addr, u16 pda_len) | ||
1089 | { | ||
1090 | struct ezusb_priv *upriv = hw->priv; | ||
1091 | struct request_context *ctx; | ||
1092 | __le16 data[] = { | ||
1093 | cpu_to_le16(pda_addr & 0xffff), | ||
1094 | cpu_to_le16(pda_len - 4) | ||
1095 | }; | ||
1096 | ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_READ_PDA, EZUSB_RID_READ_PDA); | ||
1097 | if (!ctx) | ||
1098 | return -ENOMEM; | ||
1099 | |||
1100 | /* wl_lkm does not include PDA size in the PDA area. | ||
1101 | * We will pad the information into pda, so other routines | ||
1102 | * don't have to be modified */ | ||
1103 | pda[0] = cpu_to_le16(pda_len - 2); | ||
1104 | /* Includes CFG_PROD_DATA but not itself */ | ||
1105 | pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */ | ||
1106 | |||
1107 | return ezusb_access_ltv(upriv, ctx, sizeof(data), &data, | ||
1108 | EZUSB_FRAME_CONTROL, &pda[2], pda_len - 4, | ||
1109 | NULL); | ||
1110 | } | ||
1111 | |||
1112 | static int ezusb_program_init(struct hermes *hw, u32 entry_point) | ||
1113 | { | ||
1114 | struct ezusb_priv *upriv = hw->priv; | ||
1115 | struct request_context *ctx; | ||
1116 | __le32 data = cpu_to_le32(entry_point); | ||
1117 | |||
1118 | ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_INIT, EZUSB_RID_ACK); | ||
1119 | if (!ctx) | ||
1120 | return -ENOMEM; | ||
1121 | |||
1122 | return ezusb_access_ltv(upriv, ctx, sizeof(data), &data, | ||
1123 | EZUSB_FRAME_CONTROL, NULL, 0, NULL); | ||
1124 | } | ||
1125 | |||
1126 | static int ezusb_program_end(struct hermes *hw) | ||
1127 | { | ||
1128 | struct ezusb_priv *upriv = hw->priv; | ||
1129 | struct request_context *ctx; | ||
1130 | |||
1131 | ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_END, EZUSB_RID_ACK); | ||
1132 | if (!ctx) | ||
1133 | return -ENOMEM; | ||
1134 | |||
1135 | return ezusb_access_ltv(upriv, ctx, 0, NULL, | ||
1136 | EZUSB_FRAME_CONTROL, NULL, 0, NULL); | ||
1137 | } | ||
1138 | |||
1139 | static int ezusb_program_bytes(struct hermes *hw, const char *buf, | ||
1140 | u32 addr, u32 len) | ||
1141 | { | ||
1142 | struct ezusb_priv *upriv = hw->priv; | ||
1143 | struct request_context *ctx; | ||
1144 | __le32 data = cpu_to_le32(addr); | ||
1145 | int err; | ||
1146 | |||
1147 | ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_SET_ADDR, EZUSB_RID_ACK); | ||
1148 | if (!ctx) | ||
1149 | return -ENOMEM; | ||
1150 | |||
1151 | err = ezusb_access_ltv(upriv, ctx, sizeof(data), &data, | ||
1152 | EZUSB_FRAME_CONTROL, NULL, 0, NULL); | ||
1153 | if (err) | ||
1154 | return err; | ||
1155 | |||
1156 | ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_BYTES, EZUSB_RID_ACK); | ||
1157 | if (!ctx) | ||
1158 | return -ENOMEM; | ||
1159 | |||
1160 | return ezusb_access_ltv(upriv, ctx, len, buf, | ||
1161 | EZUSB_FRAME_CONTROL, NULL, 0, NULL); | ||
1162 | } | ||
1163 | |||
1164 | static int ezusb_program(struct hermes *hw, const char *buf, | ||
1165 | u32 addr, u32 len) | ||
1166 | { | ||
1167 | u32 ch_addr; | ||
1168 | u32 ch_len; | ||
1169 | int err = 0; | ||
1170 | |||
1171 | /* We can only send 2048 bytes out of the bulk xmit at a time, | ||
1172 | * so we have to split any programming into chunks of <2048 | ||
1173 | * bytes. */ | ||
1174 | |||
1175 | ch_len = (len < MAX_DL_SIZE) ? len : MAX_DL_SIZE; | ||
1176 | ch_addr = addr; | ||
1177 | |||
1178 | while (ch_addr < (addr + len)) { | ||
1179 | pr_debug("Programming subblock of length %d " | ||
1180 | "to address 0x%08x. Data @ %p\n", | ||
1181 | ch_len, ch_addr, &buf[ch_addr - addr]); | ||
1182 | |||
1183 | err = ezusb_program_bytes(hw, &buf[ch_addr - addr], | ||
1184 | ch_addr, ch_len); | ||
1185 | if (err) | ||
1186 | break; | ||
1187 | |||
1188 | ch_addr += ch_len; | ||
1189 | ch_len = ((addr + len - ch_addr) < MAX_DL_SIZE) ? | ||
1190 | (addr + len - ch_addr) : MAX_DL_SIZE; | ||
1191 | } | ||
1192 | |||
1193 | return err; | ||
1194 | } | ||
1195 | |||
1196 | static netdev_tx_t ezusb_xmit(struct sk_buff *skb, struct net_device *dev) | ||
1197 | { | ||
1198 | struct orinoco_private *priv = ndev_priv(dev); | ||
1199 | struct net_device_stats *stats = &priv->stats; | ||
1200 | struct ezusb_priv *upriv = priv->card; | ||
1201 | int err = 0; | ||
1202 | char *p; | ||
1203 | struct ethhdr *eh; | ||
1204 | int len, data_len, data_off; | ||
1205 | __le16 tx_control; | ||
1206 | unsigned long flags; | ||
1207 | struct request_context *ctx; | ||
1208 | u8 *buf; | ||
1209 | int tx_size; | ||
1210 | |||
1211 | if (!netif_running(dev)) { | ||
1212 | printk(KERN_ERR "%s: Tx on stopped device!\n", | ||
1213 | dev->name); | ||
1214 | return NETDEV_TX_BUSY; | ||
1215 | } | ||
1216 | |||
1217 | if (netif_queue_stopped(dev)) { | ||
1218 | printk(KERN_DEBUG "%s: Tx while transmitter busy!\n", | ||
1219 | dev->name); | ||
1220 | return NETDEV_TX_BUSY; | ||
1221 | } | ||
1222 | |||
1223 | if (orinoco_lock(priv, &flags) != 0) { | ||
1224 | printk(KERN_ERR | ||
1225 | "%s: orinoco_xmit() called while hw_unavailable\n", | ||
1226 | dev->name); | ||
1227 | return NETDEV_TX_BUSY; | ||
1228 | } | ||
1229 | |||
1230 | if (!netif_carrier_ok(dev) || | ||
1231 | (priv->iw_mode == NL80211_IFTYPE_MONITOR)) { | ||
1232 | /* Oops, the firmware hasn't established a connection, | ||
1233 | silently drop the packet (this seems to be the | ||
1234 | safest approach). */ | ||
1235 | stats->tx_errors++; | ||
1236 | orinoco_unlock(priv, &flags); | ||
1237 | dev_kfree_skb(skb); | ||
1238 | return NETDEV_TX_OK; | ||
1239 | } | ||
1240 | |||
1241 | ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_TX, 0); | ||
1242 | if (!ctx) | ||
1243 | goto fail; | ||
1244 | |||
1245 | memset(ctx->buf, 0, BULK_BUF_SIZE); | ||
1246 | buf = ctx->buf->data; | ||
1247 | |||
1248 | /* Length of the packet body */ | ||
1249 | /* FIXME: what if the skb is smaller than this? */ | ||
1250 | len = max_t(int, skb->len - ETH_HLEN, ETH_ZLEN - ETH_HLEN); | ||
1251 | |||
1252 | eh = (struct ethhdr *) skb->data; | ||
1253 | |||
1254 | tx_control = cpu_to_le16(0); | ||
1255 | memcpy(buf, &tx_control, sizeof(tx_control)); | ||
1256 | buf += sizeof(tx_control); | ||
1257 | /* Encapsulate Ethernet-II frames */ | ||
1258 | if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */ | ||
1259 | struct header_struct *hdr = (void *) buf; | ||
1260 | buf += sizeof(*hdr); | ||
1261 | data_len = len; | ||
1262 | data_off = sizeof(tx_control) + sizeof(*hdr); | ||
1263 | p = skb->data + ETH_HLEN; | ||
1264 | |||
1265 | /* 802.3 header */ | ||
1266 | memcpy(hdr->dest, eh->h_dest, ETH_ALEN); | ||
1267 | memcpy(hdr->src, eh->h_source, ETH_ALEN); | ||
1268 | hdr->len = htons(data_len + ENCAPS_OVERHEAD); | ||
1269 | |||
1270 | /* 802.2 header */ | ||
1271 | memcpy(&hdr->dsap, &encaps_hdr, sizeof(encaps_hdr)); | ||
1272 | |||
1273 | hdr->ethertype = eh->h_proto; | ||
1274 | } else { /* IEEE 802.3 frame */ | ||
1275 | data_len = len + ETH_HLEN; | ||
1276 | data_off = sizeof(tx_control); | ||
1277 | p = skb->data; | ||
1278 | } | ||
1279 | |||
1280 | memcpy(buf, p, data_len); | ||
1281 | buf += data_len; | ||
1282 | |||
1283 | /* Finally, we actually initiate the send */ | ||
1284 | netif_stop_queue(dev); | ||
1285 | |||
1286 | /* The card may behave better if we send evenly sized usb transfers */ | ||
1287 | tx_size = ALIGN(buf - ctx->buf->data, 2); | ||
1288 | |||
1289 | err = ezusb_access_ltv(upriv, ctx, tx_size, NULL, | ||
1290 | EZUSB_FRAME_DATA, NULL, 0, NULL); | ||
1291 | |||
1292 | if (err) { | ||
1293 | netif_start_queue(dev); | ||
1294 | if (net_ratelimit()) | ||
1295 | printk(KERN_ERR "%s: Error %d transmitting packet\n", | ||
1296 | dev->name, err); | ||
1297 | stats->tx_errors++; | ||
1298 | goto fail; | ||
1299 | } | ||
1300 | |||
1301 | dev->trans_start = jiffies; | ||
1302 | stats->tx_bytes += data_off + data_len; | ||
1303 | |||
1304 | orinoco_unlock(priv, &flags); | ||
1305 | |||
1306 | dev_kfree_skb(skb); | ||
1307 | |||
1308 | return NETDEV_TX_OK; | ||
1309 | |||
1310 | fail: | ||
1311 | orinoco_unlock(priv, &flags); | ||
1312 | return NETDEV_TX_BUSY; | ||
1313 | } | ||
1314 | |||
1315 | static int ezusb_allocate(struct hermes *hw, u16 size, u16 *fid) | ||
1316 | { | ||
1317 | *fid = EZUSB_RID_TX; | ||
1318 | return 0; | ||
1319 | } | ||
1320 | |||
1321 | |||
1322 | static int ezusb_hard_reset(struct orinoco_private *priv) | ||
1323 | { | ||
1324 | struct ezusb_priv *upriv = priv->card; | ||
1325 | int retval = ezusb_8051_cpucs(upriv, 1); | ||
1326 | |||
1327 | if (retval < 0) { | ||
1328 | err("Failed to reset"); | ||
1329 | return retval; | ||
1330 | } | ||
1331 | |||
1332 | retval = ezusb_8051_cpucs(upriv, 0); | ||
1333 | if (retval < 0) { | ||
1334 | err("Failed to unreset"); | ||
1335 | return retval; | ||
1336 | } | ||
1337 | |||
1338 | dbg("sending control message"); | ||
1339 | retval = usb_control_msg(upriv->udev, | ||
1340 | usb_sndctrlpipe(upriv->udev, 0), | ||
1341 | EZUSB_REQUEST_TRIGER, | ||
1342 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | | ||
1343 | USB_DIR_OUT, 0x0, 0x0, NULL, 0, | ||
1344 | DEF_TIMEOUT); | ||
1345 | if (retval < 0) { | ||
1346 | err("EZUSB_REQUEST_TRIGER failed retval %d", retval); | ||
1347 | return retval; | ||
1348 | } | ||
1349 | #if 0 | ||
1350 | dbg("Sending EZUSB_REQUEST_TRIG_AC"); | ||
1351 | retval = usb_control_msg(upriv->udev, | ||
1352 | usb_sndctrlpipe(upriv->udev, 0), | ||
1353 | EZUSB_REQUEST_TRIG_AC, | ||
1354 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | | ||
1355 | USB_DIR_OUT, 0x00FA, 0x0, NULL, 0, | ||
1356 | DEF_TIMEOUT); | ||
1357 | if (retval < 0) { | ||
1358 | err("EZUSB_REQUEST_TRIG_AC failed retval %d", retval); | ||
1359 | return retval; | ||
1360 | } | ||
1361 | #endif | ||
1362 | |||
1363 | return 0; | ||
1364 | } | ||
1365 | |||
1366 | |||
1367 | static int ezusb_init(hermes_t *hw) | ||
1368 | { | ||
1369 | struct ezusb_priv *upriv = hw->priv; | ||
1370 | int retval; | ||
1371 | |||
1372 | BUG_ON(in_interrupt()); | ||
1373 | BUG_ON(!upriv); | ||
1374 | |||
1375 | upriv->reply_count = 0; | ||
1376 | /* Write the MAGIC number on the simulated registers to keep | ||
1377 | * orinoco.c happy */ | ||
1378 | hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC); | ||
1379 | hermes_write_regn(hw, RXFID, EZUSB_RID_RX); | ||
1380 | |||
1381 | usb_kill_urb(upriv->read_urb); | ||
1382 | ezusb_submit_in_urb(upriv); | ||
1383 | |||
1384 | retval = ezusb_write_ltv(hw, 0, EZUSB_RID_INIT1, | ||
1385 | HERMES_BYTES_TO_RECLEN(2), "\x10\x00"); | ||
1386 | if (retval < 0) { | ||
1387 | printk(KERN_ERR PFX "EZUSB_RID_INIT1 error %d\n", retval); | ||
1388 | return retval; | ||
1389 | } | ||
1390 | |||
1391 | retval = ezusb_docmd_wait(hw, HERMES_CMD_INIT, 0, NULL); | ||
1392 | if (retval < 0) { | ||
1393 | printk(KERN_ERR PFX "HERMES_CMD_INIT error %d\n", retval); | ||
1394 | return retval; | ||
1395 | } | ||
1396 | |||
1397 | return 0; | ||
1398 | } | ||
1399 | |||
1400 | static void ezusb_bulk_in_callback(struct urb *urb) | ||
1401 | { | ||
1402 | struct ezusb_priv *upriv = (struct ezusb_priv *) urb->context; | ||
1403 | struct ezusb_packet *ans = urb->transfer_buffer; | ||
1404 | u16 crc; | ||
1405 | u16 hermes_rid; | ||
1406 | |||
1407 | if (upriv->udev == NULL) { | ||
1408 | dbg("disconnected"); | ||
1409 | return; | ||
1410 | } | ||
1411 | |||
1412 | if (urb->status == -ETIMEDOUT) { | ||
1413 | /* When a device gets unplugged we get this every time | ||
1414 | * we resubmit, flooding the logs. Since we don't use | ||
1415 | * USB timeouts, it shouldn't happen any other time*/ | ||
1416 | pr_warning("%s: urb timed out, not resubmiting", __func__); | ||
1417 | return; | ||
1418 | } | ||
1419 | if (urb->status == -ECONNABORTED) { | ||
1420 | pr_warning("%s: connection abort, resubmiting urb", | ||
1421 | __func__); | ||
1422 | goto resubmit; | ||
1423 | } | ||
1424 | if ((urb->status == -EILSEQ) | ||
1425 | || (urb->status == -ENOENT) | ||
1426 | || (urb->status == -ECONNRESET)) { | ||
1427 | dbg("status %d, not resubmiting", urb->status); | ||
1428 | return; | ||
1429 | } | ||
1430 | if (urb->status) | ||
1431 | dbg("status: %d length: %d", | ||
1432 | urb->status, urb->actual_length); | ||
1433 | if (urb->actual_length < sizeof(*ans)) { | ||
1434 | err("%s: short read, ignoring", __func__); | ||
1435 | goto resubmit; | ||
1436 | } | ||
1437 | crc = build_crc(ans); | ||
1438 | if (le16_to_cpu(ans->crc) != crc) { | ||
1439 | err("CRC error, ignoring packet"); | ||
1440 | goto resubmit; | ||
1441 | } | ||
1442 | |||
1443 | hermes_rid = le16_to_cpu(ans->hermes_rid); | ||
1444 | if ((hermes_rid != EZUSB_RID_RX) && !EZUSB_IS_INFO(hermes_rid)) { | ||
1445 | ezusb_request_in_callback(upriv, urb); | ||
1446 | } else if (upriv->dev) { | ||
1447 | struct net_device *dev = upriv->dev; | ||
1448 | struct orinoco_private *priv = ndev_priv(dev); | ||
1449 | hermes_t *hw = &priv->hw; | ||
1450 | |||
1451 | if (hermes_rid == EZUSB_RID_RX) { | ||
1452 | __orinoco_ev_rx(dev, hw); | ||
1453 | } else { | ||
1454 | hermes_write_regn(hw, INFOFID, | ||
1455 | le16_to_cpu(ans->hermes_rid)); | ||
1456 | __orinoco_ev_info(dev, hw); | ||
1457 | } | ||
1458 | } | ||
1459 | |||
1460 | resubmit: | ||
1461 | if (upriv->udev) | ||
1462 | ezusb_submit_in_urb(upriv); | ||
1463 | } | ||
1464 | |||
1465 | static inline void ezusb_delete(struct ezusb_priv *upriv) | ||
1466 | { | ||
1467 | struct net_device *dev; | ||
1468 | struct list_head *item; | ||
1469 | struct list_head *tmp_item; | ||
1470 | unsigned long flags; | ||
1471 | |||
1472 | BUG_ON(in_interrupt()); | ||
1473 | BUG_ON(!upriv); | ||
1474 | |||
1475 | dev = upriv->dev; | ||
1476 | mutex_lock(&upriv->mtx); | ||
1477 | |||
1478 | upriv->udev = NULL; /* No timer will be rearmed from here */ | ||
1479 | |||
1480 | usb_kill_urb(upriv->read_urb); | ||
1481 | |||
1482 | spin_lock_irqsave(&upriv->req_lock, flags); | ||
1483 | list_for_each_safe(item, tmp_item, &upriv->req_active) { | ||
1484 | struct request_context *ctx; | ||
1485 | int err; | ||
1486 | |||
1487 | ctx = list_entry(item, struct request_context, list); | ||
1488 | atomic_inc(&ctx->refcount); | ||
1489 | |||
1490 | ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK; | ||
1491 | err = usb_unlink_urb(ctx->outurb); | ||
1492 | |||
1493 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
1494 | if (err == -EINPROGRESS) | ||
1495 | wait_for_completion(&ctx->done); | ||
1496 | |||
1497 | del_timer_sync(&ctx->timer); | ||
1498 | /* FIXME: there is an slight chance for the irq handler to | ||
1499 | * be running */ | ||
1500 | if (!list_empty(&ctx->list)) | ||
1501 | ezusb_ctx_complete(ctx); | ||
1502 | |||
1503 | ezusb_request_context_put(ctx); | ||
1504 | spin_lock_irqsave(&upriv->req_lock, flags); | ||
1505 | } | ||
1506 | spin_unlock_irqrestore(&upriv->req_lock, flags); | ||
1507 | |||
1508 | list_for_each_safe(item, tmp_item, &upriv->req_pending) | ||
1509 | ezusb_ctx_complete(list_entry(item, | ||
1510 | struct request_context, list)); | ||
1511 | |||
1512 | if (upriv->read_urb->status == -EINPROGRESS) | ||
1513 | printk(KERN_ERR PFX "Some URB in progress\n"); | ||
1514 | |||
1515 | mutex_unlock(&upriv->mtx); | ||
1516 | |||
1517 | kfree(upriv->read_urb->transfer_buffer); | ||
1518 | if (upriv->bap_buf != NULL) | ||
1519 | kfree(upriv->bap_buf); | ||
1520 | if (upriv->read_urb != NULL) | ||
1521 | usb_free_urb(upriv->read_urb); | ||
1522 | if (upriv->dev) { | ||
1523 | struct orinoco_private *priv = ndev_priv(upriv->dev); | ||
1524 | orinoco_if_del(priv); | ||
1525 | free_orinocodev(priv); | ||
1526 | } | ||
1527 | } | ||
1528 | |||
1529 | static void ezusb_lock_irqsave(spinlock_t *lock, | ||
1530 | unsigned long *flags) __acquires(lock) | ||
1531 | { | ||
1532 | spin_lock_bh(lock); | ||
1533 | } | ||
1534 | |||
1535 | static void ezusb_unlock_irqrestore(spinlock_t *lock, | ||
1536 | unsigned long *flags) __releases(lock) | ||
1537 | { | ||
1538 | spin_unlock_bh(lock); | ||
1539 | } | ||
1540 | |||
1541 | static void ezusb_lock_irq(spinlock_t *lock) __acquires(lock) | ||
1542 | { | ||
1543 | spin_lock_bh(lock); | ||
1544 | } | ||
1545 | |||
1546 | static void ezusb_unlock_irq(spinlock_t *lock) __releases(lock) | ||
1547 | { | ||
1548 | spin_unlock_bh(lock); | ||
1549 | } | ||
1550 | |||
1551 | static const struct hermes_ops ezusb_ops = { | ||
1552 | .init = ezusb_init, | ||
1553 | .cmd_wait = ezusb_docmd_wait, | ||
1554 | .init_cmd_wait = ezusb_doicmd_wait, | ||
1555 | .allocate = ezusb_allocate, | ||
1556 | .read_ltv = ezusb_read_ltv, | ||
1557 | .write_ltv = ezusb_write_ltv, | ||
1558 | .bap_pread = ezusb_bap_pread, | ||
1559 | .read_pda = ezusb_read_pda, | ||
1560 | .program_init = ezusb_program_init, | ||
1561 | .program_end = ezusb_program_end, | ||
1562 | .program = ezusb_program, | ||
1563 | .lock_irqsave = ezusb_lock_irqsave, | ||
1564 | .unlock_irqrestore = ezusb_unlock_irqrestore, | ||
1565 | .lock_irq = ezusb_lock_irq, | ||
1566 | .unlock_irq = ezusb_unlock_irq, | ||
1567 | }; | ||
1568 | |||
1569 | static const struct net_device_ops ezusb_netdev_ops = { | ||
1570 | .ndo_open = orinoco_open, | ||
1571 | .ndo_stop = orinoco_stop, | ||
1572 | .ndo_start_xmit = ezusb_xmit, | ||
1573 | .ndo_set_multicast_list = orinoco_set_multicast_list, | ||
1574 | .ndo_change_mtu = orinoco_change_mtu, | ||
1575 | .ndo_set_mac_address = eth_mac_addr, | ||
1576 | .ndo_validate_addr = eth_validate_addr, | ||
1577 | .ndo_tx_timeout = orinoco_tx_timeout, | ||
1578 | .ndo_get_stats = orinoco_get_stats, | ||
1579 | }; | ||
1580 | |||
1581 | static int ezusb_probe(struct usb_interface *interface, | ||
1582 | const struct usb_device_id *id) | ||
1583 | { | ||
1584 | struct usb_device *udev = interface_to_usbdev(interface); | ||
1585 | struct orinoco_private *priv; | ||
1586 | hermes_t *hw; | ||
1587 | struct ezusb_priv *upriv = NULL; | ||
1588 | struct usb_interface_descriptor *iface_desc; | ||
1589 | struct usb_endpoint_descriptor *ep; | ||
1590 | const struct firmware *fw_entry; | ||
1591 | int retval = 0; | ||
1592 | int i; | ||
1593 | |||
1594 | priv = alloc_orinocodev(sizeof(*upriv), &udev->dev, | ||
1595 | ezusb_hard_reset, NULL); | ||
1596 | if (!priv) { | ||
1597 | err("Couldn't allocate orinocodev"); | ||
1598 | goto exit; | ||
1599 | } | ||
1600 | |||
1601 | hw = &priv->hw; | ||
1602 | |||
1603 | upriv = priv->card; | ||
1604 | |||
1605 | mutex_init(&upriv->mtx); | ||
1606 | spin_lock_init(&upriv->reply_count_lock); | ||
1607 | |||
1608 | spin_lock_init(&upriv->req_lock); | ||
1609 | INIT_LIST_HEAD(&upriv->req_pending); | ||
1610 | INIT_LIST_HEAD(&upriv->req_active); | ||
1611 | |||
1612 | upriv->udev = udev; | ||
1613 | |||
1614 | hw->iobase = (void __force __iomem *) &upriv->hermes_reg_fake; | ||
1615 | hw->reg_spacing = HERMES_16BIT_REGSPACING; | ||
1616 | hw->priv = upriv; | ||
1617 | hw->ops = &ezusb_ops; | ||
1618 | |||
1619 | /* set up the endpoint information */ | ||
1620 | /* check out the endpoints */ | ||
1621 | |||
1622 | iface_desc = &interface->altsetting[0].desc; | ||
1623 | for (i = 0; i < iface_desc->bNumEndpoints; ++i) { | ||
1624 | ep = &interface->altsetting[0].endpoint[i].desc; | ||
1625 | |||
1626 | if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | ||
1627 | == USB_DIR_IN) && | ||
1628 | ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
1629 | == USB_ENDPOINT_XFER_BULK)) { | ||
1630 | /* we found a bulk in endpoint */ | ||
1631 | if (upriv->read_urb != NULL) { | ||
1632 | pr_warning("Found a second bulk in ep, ignored"); | ||
1633 | continue; | ||
1634 | } | ||
1635 | |||
1636 | upriv->read_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
1637 | if (!upriv->read_urb) { | ||
1638 | err("No free urbs available"); | ||
1639 | goto error; | ||
1640 | } | ||
1641 | if (le16_to_cpu(ep->wMaxPacketSize) != 64) | ||
1642 | pr_warning("bulk in: wMaxPacketSize!= 64"); | ||
1643 | if (ep->bEndpointAddress != (2 | USB_DIR_IN)) | ||
1644 | pr_warning("bulk in: bEndpointAddress: %d", | ||
1645 | ep->bEndpointAddress); | ||
1646 | upriv->read_pipe = usb_rcvbulkpipe(udev, | ||
1647 | ep-> | ||
1648 | bEndpointAddress); | ||
1649 | upriv->read_urb->transfer_buffer = | ||
1650 | kmalloc(BULK_BUF_SIZE, GFP_KERNEL); | ||
1651 | if (!upriv->read_urb->transfer_buffer) { | ||
1652 | err("Couldn't allocate IN buffer"); | ||
1653 | goto error; | ||
1654 | } | ||
1655 | } | ||
1656 | |||
1657 | if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | ||
1658 | == USB_DIR_OUT) && | ||
1659 | ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
1660 | == USB_ENDPOINT_XFER_BULK)) { | ||
1661 | /* we found a bulk out endpoint */ | ||
1662 | if (upriv->bap_buf != NULL) { | ||
1663 | pr_warning("Found a second bulk out ep, ignored"); | ||
1664 | continue; | ||
1665 | } | ||
1666 | |||
1667 | if (le16_to_cpu(ep->wMaxPacketSize) != 64) | ||
1668 | pr_warning("bulk out: wMaxPacketSize != 64"); | ||
1669 | if (ep->bEndpointAddress != 2) | ||
1670 | pr_warning("bulk out: bEndpointAddress: %d", | ||
1671 | ep->bEndpointAddress); | ||
1672 | upriv->write_pipe = usb_sndbulkpipe(udev, | ||
1673 | ep-> | ||
1674 | bEndpointAddress); | ||
1675 | upriv->bap_buf = kmalloc(BULK_BUF_SIZE, GFP_KERNEL); | ||
1676 | if (!upriv->bap_buf) { | ||
1677 | err("Couldn't allocate bulk_out_buffer"); | ||
1678 | goto error; | ||
1679 | } | ||
1680 | } | ||
1681 | } | ||
1682 | if (!upriv->bap_buf || !upriv->read_urb) { | ||
1683 | err("Didn't find the required bulk endpoints"); | ||
1684 | goto error; | ||
1685 | } | ||
1686 | |||
1687 | if (request_firmware(&fw_entry, "orinoco_ezusb_fw", | ||
1688 | &interface->dev) == 0) { | ||
1689 | firmware.size = fw_entry->size; | ||
1690 | firmware.code = fw_entry->data; | ||
1691 | } | ||
1692 | if (firmware.size && firmware.code) { | ||
1693 | ezusb_firmware_download(upriv, &firmware); | ||
1694 | } else { | ||
1695 | err("No firmware to download"); | ||
1696 | goto error; | ||
1697 | } | ||
1698 | |||
1699 | if (ezusb_hard_reset(priv) < 0) { | ||
1700 | err("Cannot reset the device"); | ||
1701 | goto error; | ||
1702 | } | ||
1703 | |||
1704 | /* If the firmware is already downloaded orinoco.c will call | ||
1705 | * ezusb_init but if the firmware is not already there, that will make | ||
1706 | * the kernel very unstable, so we try initializing here and quit in | ||
1707 | * case of error */ | ||
1708 | if (ezusb_init(hw) < 0) { | ||
1709 | err("Couldn't initialize the device"); | ||
1710 | err("Firmware may not be downloaded or may be wrong."); | ||
1711 | goto error; | ||
1712 | } | ||
1713 | |||
1714 | /* Initialise the main driver */ | ||
1715 | if (orinoco_init(priv) != 0) { | ||
1716 | err("orinoco_init() failed\n"); | ||
1717 | goto error; | ||
1718 | } | ||
1719 | |||
1720 | if (orinoco_if_add(priv, 0, 0, &ezusb_netdev_ops) != 0) { | ||
1721 | upriv->dev = NULL; | ||
1722 | err("%s: orinoco_if_add() failed", __func__); | ||
1723 | goto error; | ||
1724 | } | ||
1725 | upriv->dev = priv->ndev; | ||
1726 | |||
1727 | goto exit; | ||
1728 | |||
1729 | error: | ||
1730 | ezusb_delete(upriv); | ||
1731 | if (upriv->dev) { | ||
1732 | /* upriv->dev was 0, so ezusb_delete() didn't free it */ | ||
1733 | free_orinocodev(priv); | ||
1734 | } | ||
1735 | upriv = NULL; | ||
1736 | retval = -EFAULT; | ||
1737 | exit: | ||
1738 | if (fw_entry) { | ||
1739 | firmware.code = NULL; | ||
1740 | firmware.size = 0; | ||
1741 | release_firmware(fw_entry); | ||
1742 | } | ||
1743 | usb_set_intfdata(interface, upriv); | ||
1744 | return retval; | ||
1745 | } | ||
1746 | |||
1747 | |||
1748 | static void ezusb_disconnect(struct usb_interface *intf) | ||
1749 | { | ||
1750 | struct ezusb_priv *upriv = usb_get_intfdata(intf); | ||
1751 | usb_set_intfdata(intf, NULL); | ||
1752 | ezusb_delete(upriv); | ||
1753 | printk(KERN_INFO PFX "Disconnected\n"); | ||
1754 | } | ||
1755 | |||
1756 | |||
1757 | /* usb specific object needed to register this driver with the usb subsystem */ | ||
1758 | static struct usb_driver orinoco_driver = { | ||
1759 | .name = DRIVER_NAME, | ||
1760 | .probe = ezusb_probe, | ||
1761 | .disconnect = ezusb_disconnect, | ||
1762 | .id_table = ezusb_table, | ||
1763 | }; | ||
1764 | |||
1765 | /* Can't be declared "const" or the whole __initdata section will | ||
1766 | * become const */ | ||
1767 | static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION | ||
1768 | " (Manuel Estrada Sainz)"; | ||
1769 | |||
1770 | static int __init ezusb_module_init(void) | ||
1771 | { | ||
1772 | int err; | ||
1773 | |||
1774 | printk(KERN_DEBUG "%s\n", version); | ||
1775 | |||
1776 | /* register this driver with the USB subsystem */ | ||
1777 | err = usb_register(&orinoco_driver); | ||
1778 | if (err < 0) { | ||
1779 | printk(KERN_ERR PFX "usb_register failed, error %d\n", | ||
1780 | err); | ||
1781 | return err; | ||
1782 | } | ||
1783 | |||
1784 | return 0; | ||
1785 | } | ||
1786 | |||
1787 | static void __exit ezusb_module_exit(void) | ||
1788 | { | ||
1789 | /* deregister this driver with the USB subsystem */ | ||
1790 | usb_deregister(&orinoco_driver); | ||
1791 | } | ||
1792 | |||
1793 | |||
1794 | module_init(ezusb_module_init); | ||
1795 | module_exit(ezusb_module_exit); | ||
1796 | |||
1797 | MODULE_AUTHOR("Manuel Estrada Sainz"); | ||
1798 | MODULE_DESCRIPTION | ||
1799 | ("Driver for Orinoco wireless LAN cards using EZUSB bridge"); | ||
1800 | MODULE_LICENSE("Dual MPL/GPL"); | ||
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index 59bda240fdc2..9b1af4976bf5 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c | |||
@@ -349,6 +349,7 @@ spectrum_cs_config(struct pcmcia_device *link) | |||
349 | goto failed; | 349 | goto failed; |
350 | 350 | ||
351 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); | 351 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); |
352 | hw->eeprom_pda = true; | ||
352 | 353 | ||
353 | /* | 354 | /* |
354 | * This actually configures the PCMCIA socket -- setting up | 355 | * This actually configures the PCMCIA socket -- setting up |
@@ -374,7 +375,7 @@ spectrum_cs_config(struct pcmcia_device *link) | |||
374 | 375 | ||
375 | /* Register an interface with the stack */ | 376 | /* Register an interface with the stack */ |
376 | if (orinoco_if_add(priv, link->io.BasePort1, | 377 | if (orinoco_if_add(priv, link->io.BasePort1, |
377 | link->irq.AssignedIRQ) != 0) { | 378 | link->irq.AssignedIRQ, NULL) != 0) { |
378 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); | 379 | printk(KERN_ERR PFX "orinoco_if_add() failed\n"); |
379 | goto failed; | 380 | goto failed; |
380 | } | 381 | } |
@@ -405,9 +406,9 @@ spectrum_cs_release(struct pcmcia_device *link) | |||
405 | 406 | ||
406 | /* We're committed to taking the device away now, so mark the | 407 | /* We're committed to taking the device away now, so mark the |
407 | * hardware as unavailable */ | 408 | * hardware as unavailable */ |
408 | spin_lock_irqsave(&priv->lock, flags); | 409 | priv->hw.ops->lock_irqsave(&priv->lock, &flags); |
409 | priv->hw_unavailable++; | 410 | priv->hw_unavailable++; |
410 | spin_unlock_irqrestore(&priv->lock, flags); | 411 | priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); |
411 | 412 | ||
412 | pcmcia_disable_device(link); | 413 | pcmcia_disable_device(link); |
413 | if (priv->hw.iobase) | 414 | if (priv->hw.iobase) |
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index a1006bf430cc..5775124e2aee 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c | |||
@@ -458,7 +458,7 @@ static int orinoco_ioctl_setfreq(struct net_device *dev, | |||
458 | if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { | 458 | if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { |
459 | /* Fast channel change - no commit if successful */ | 459 | /* Fast channel change - no commit if successful */ |
460 | hermes_t *hw = &priv->hw; | 460 | hermes_t *hw = &priv->hw; |
461 | err = hermes_docmd_wait(hw, HERMES_CMD_TEST | | 461 | err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST | |
462 | HERMES_TEST_SET_CHANNEL, | 462 | HERMES_TEST_SET_CHANNEL, |
463 | chan, NULL); | 463 | chan, NULL); |
464 | } | 464 | } |
@@ -1273,8 +1273,8 @@ static int orinoco_ioctl_getrid(struct net_device *dev, | |||
1273 | if (orinoco_lock(priv, &flags) != 0) | 1273 | if (orinoco_lock(priv, &flags) != 0) |
1274 | return -EBUSY; | 1274 | return -EBUSY; |
1275 | 1275 | ||
1276 | err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length, | 1276 | err = hw->ops->read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length, |
1277 | extra); | 1277 | extra); |
1278 | if (err) | 1278 | if (err) |
1279 | goto out; | 1279 | goto out; |
1280 | 1280 | ||
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 7bbd9d3bba60..c072f41747ca 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -546,8 +546,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
546 | IEEE80211_HW_SUPPORTS_PS | | 546 | IEEE80211_HW_SUPPORTS_PS | |
547 | IEEE80211_HW_PS_NULLFUNC_STACK | | 547 | IEEE80211_HW_PS_NULLFUNC_STACK | |
548 | IEEE80211_HW_BEACON_FILTER | | 548 | IEEE80211_HW_BEACON_FILTER | |
549 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 549 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; |
550 | IEEE80211_HW_NOISE_DBM; | ||
551 | 550 | ||
552 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | 551 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
553 | BIT(NL80211_IFTYPE_ADHOC) | | 552 | BIT(NL80211_IFTYPE_ADHOC) | |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index ca42ccb23d76..07c4528f6e6b 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
@@ -277,6 +277,14 @@ static void p54p_tasklet(unsigned long dev_id) | |||
277 | struct p54p_priv *priv = dev->priv; | 277 | struct p54p_priv *priv = dev->priv; |
278 | struct p54p_ring_control *ring_control = priv->ring_control; | 278 | struct p54p_ring_control *ring_control = priv->ring_control; |
279 | 279 | ||
280 | p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 3, ring_control->tx_mgmt, | ||
281 | ARRAY_SIZE(ring_control->tx_mgmt), | ||
282 | priv->tx_buf_mgmt); | ||
283 | |||
284 | p54p_check_tx_ring(dev, &priv->tx_idx_data, 1, ring_control->tx_data, | ||
285 | ARRAY_SIZE(ring_control->tx_data), | ||
286 | priv->tx_buf_data); | ||
287 | |||
280 | p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt, | 288 | p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt, |
281 | ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt); | 289 | ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt); |
282 | 290 | ||
@@ -285,14 +293,6 @@ static void p54p_tasklet(unsigned long dev_id) | |||
285 | 293 | ||
286 | wmb(); | 294 | wmb(); |
287 | P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE)); | 295 | P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE)); |
288 | |||
289 | p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 3, ring_control->tx_mgmt, | ||
290 | ARRAY_SIZE(ring_control->tx_mgmt), | ||
291 | priv->tx_buf_mgmt); | ||
292 | |||
293 | p54p_check_tx_ring(dev, &priv->tx_idx_data, 1, ring_control->tx_data, | ||
294 | ARRAY_SIZE(ring_control->tx_data), | ||
295 | priv->tx_buf_data); | ||
296 | } | 296 | } |
297 | 297 | ||
298 | static irqreturn_t p54p_interrupt(int irq, void *dev_id) | 298 | static irqreturn_t p54p_interrupt(int irq, void *dev_id) |
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 2ceff5480355..4e6891099d43 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c | |||
@@ -350,7 +350,6 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb) | |||
350 | rx_status->flag |= RX_FLAG_MMIC_ERROR; | 350 | rx_status->flag |= RX_FLAG_MMIC_ERROR; |
351 | 351 | ||
352 | rx_status->signal = p54_rssi_to_dbm(priv, hdr->rssi); | 352 | rx_status->signal = p54_rssi_to_dbm(priv, hdr->rssi); |
353 | rx_status->noise = priv->noise; | ||
354 | if (hdr->rate & 0x10) | 353 | if (hdr->rate & 0x10) |
355 | rx_status->flag |= RX_FLAG_SHORTPRE; | 354 | rx_status->flag |= RX_FLAG_SHORTPRE; |
356 | if (priv->hw->conf.channel->band == IEEE80211_BAND_5GHZ) | 355 | if (priv->hw->conf.channel->band == IEEE80211_BAND_5GHZ) |
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 5239e082cd0f..eea1ef2f502b 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -87,7 +87,7 @@ if RT2800PCI | |||
87 | 87 | ||
88 | config RT2800PCI_RT30XX | 88 | config RT2800PCI_RT30XX |
89 | bool "rt2800pci - Include support for rt30xx (PCI/PCIe/PCMCIA) devices" | 89 | bool "rt2800pci - Include support for rt30xx (PCI/PCIe/PCMCIA) devices" |
90 | default n | 90 | default y |
91 | ---help--- | 91 | ---help--- |
92 | This adds support for rt30xx wireless chipset family to the | 92 | This adds support for rt30xx wireless chipset family to the |
93 | rt2800pci driver. | 93 | rt2800pci driver. |
@@ -156,7 +156,7 @@ if RT2800USB | |||
156 | 156 | ||
157 | config RT2800USB_RT30XX | 157 | config RT2800USB_RT30XX |
158 | bool "rt2800usb - Include support for rt30xx (USB) devices" | 158 | bool "rt2800usb - Include support for rt30xx (USB) devices" |
159 | default n | 159 | default y |
160 | ---help--- | 160 | ---help--- |
161 | This adds support for rt30xx wireless chipset family to the | 161 | This adds support for rt30xx wireless chipset family to the |
162 | rt2800usb driver. | 162 | rt2800usb driver. |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index cdbf59108ef9..06b92f8b7a55 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1018,8 +1018,8 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1018 | rt2x00_desc_write(entry_priv->desc, 1, word); | 1018 | rt2x00_desc_write(entry_priv->desc, 1, word); |
1019 | 1019 | ||
1020 | rt2x00_desc_read(txd, 2, &word); | 1020 | rt2x00_desc_read(txd, 2, &word); |
1021 | rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, skb->len); | 1021 | rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, txdesc->length); |
1022 | rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skb->len); | 1022 | rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, txdesc->length); |
1023 | rt2x00_desc_write(txd, 2, word); | 1023 | rt2x00_desc_write(txd, 2, word); |
1024 | 1024 | ||
1025 | rt2x00_desc_read(txd, 3, &word); | 1025 | rt2x00_desc_read(txd, 3, &word); |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 89e986f449da..ae8e205df269 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1209,7 +1209,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1209 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1209 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1210 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1210 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1211 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); | 1211 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
1212 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); | 1212 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); |
1213 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1213 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
1214 | rt2x00_desc_write(txd, 0, word); | 1214 | rt2x00_desc_write(txd, 0, word); |
1215 | } | 1215 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 7185cb05f257..41d9996c80e6 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1072,7 +1072,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1072 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, | 1072 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, |
1073 | test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); | 1073 | test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); |
1074 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1074 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1075 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); | 1075 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); |
1076 | rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher); | 1076 | rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher); |
1077 | rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx); | 1077 | rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx); |
1078 | rt2x00_desc_write(txd, 0, word); | 1078 | rt2x00_desc_write(txd, 0, word); |
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index ec893721cc80..2aa03751c341 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -107,7 +107,7 @@ | |||
107 | /* | 107 | /* |
108 | * INT_SOURCE_CSR: Interrupt source register. | 108 | * INT_SOURCE_CSR: Interrupt source register. |
109 | * Write one to clear corresponding bit. | 109 | * Write one to clear corresponding bit. |
110 | * TX_FIFO_STATUS: FIFO Statistics is full, sw should read 0x171c | 110 | * TX_FIFO_STATUS: FIFO Statistics is full, sw should read TX_STA_FIFO |
111 | */ | 111 | */ |
112 | #define INT_SOURCE_CSR 0x0200 | 112 | #define INT_SOURCE_CSR 0x0200 |
113 | #define INT_SOURCE_CSR_RXDELAYINT FIELD32(0x00000001) | 113 | #define INT_SOURCE_CSR_RXDELAYINT FIELD32(0x00000001) |
@@ -845,7 +845,7 @@ | |||
845 | * TX_BAND_CFG: 0x1 use upper 20MHz, 0x0 use lower 20MHz | 845 | * TX_BAND_CFG: 0x1 use upper 20MHz, 0x0 use lower 20MHz |
846 | */ | 846 | */ |
847 | #define TX_BAND_CFG 0x132c | 847 | #define TX_BAND_CFG 0x132c |
848 | #define TX_BAND_CFG_HT40_PLUS FIELD32(0x00000001) | 848 | #define TX_BAND_CFG_HT40_MINUS FIELD32(0x00000001) |
849 | #define TX_BAND_CFG_A FIELD32(0x00000002) | 849 | #define TX_BAND_CFG_A FIELD32(0x00000002) |
850 | #define TX_BAND_CFG_BG FIELD32(0x00000004) | 850 | #define TX_BAND_CFG_BG FIELD32(0x00000004) |
851 | 851 | ||
@@ -1519,7 +1519,7 @@ struct mac_iveiv_entry { | |||
1519 | * BBP 3: RX Antenna | 1519 | * BBP 3: RX Antenna |
1520 | */ | 1520 | */ |
1521 | #define BBP3_RX_ANTENNA FIELD8(0x18) | 1521 | #define BBP3_RX_ANTENNA FIELD8(0x18) |
1522 | #define BBP3_HT40_PLUS FIELD8(0x20) | 1522 | #define BBP3_HT40_MINUS FIELD8(0x20) |
1523 | 1523 | ||
1524 | /* | 1524 | /* |
1525 | * BBP 4: Bandwidth | 1525 | * BBP 4: Bandwidth |
@@ -1566,6 +1566,11 @@ struct mac_iveiv_entry { | |||
1566 | #define RFCSR12_TX_POWER FIELD8(0x1f) | 1566 | #define RFCSR12_TX_POWER FIELD8(0x1f) |
1567 | 1567 | ||
1568 | /* | 1568 | /* |
1569 | * RFCSR 13: | ||
1570 | */ | ||
1571 | #define RFCSR13_TX_POWER FIELD8(0x1f) | ||
1572 | |||
1573 | /* | ||
1569 | * RFCSR 15: | 1574 | * RFCSR 15: |
1570 | */ | 1575 | */ |
1571 | #define RFCSR15_TX_LO2_EN FIELD8(0x08) | 1576 | #define RFCSR15_TX_LO2_EN FIELD8(0x08) |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 2648f315a934..e37bbeab9233 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -41,9 +41,6 @@ | |||
41 | #if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE) | 41 | #if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE) |
42 | #include "rt2x00usb.h" | 42 | #include "rt2x00usb.h" |
43 | #endif | 43 | #endif |
44 | #if defined(CONFIG_RT2X00_LIB_PCI) || defined(CONFIG_RT2X00_LIB_PCI_MODULE) | ||
45 | #include "rt2x00pci.h" | ||
46 | #endif | ||
47 | #include "rt2800lib.h" | 44 | #include "rt2800lib.h" |
48 | #include "rt2800.h" | 45 | #include "rt2800.h" |
49 | #include "rt2800usb.h" | 46 | #include "rt2800usb.h" |
@@ -76,6 +73,23 @@ MODULE_LICENSE("GPL"); | |||
76 | rt2800_regbusy_read((__dev), H2M_MAILBOX_CSR, \ | 73 | rt2800_regbusy_read((__dev), H2M_MAILBOX_CSR, \ |
77 | H2M_MAILBOX_CSR_OWNER, (__reg)) | 74 | H2M_MAILBOX_CSR_OWNER, (__reg)) |
78 | 75 | ||
76 | static inline bool rt2800_is_305x_soc(struct rt2x00_dev *rt2x00dev) | ||
77 | { | ||
78 | /* check for rt2872 on SoC */ | ||
79 | if (!rt2x00_is_soc(rt2x00dev) || | ||
80 | !rt2x00_rt(rt2x00dev, RT2872)) | ||
81 | return false; | ||
82 | |||
83 | /* we know for sure that these rf chipsets are used on rt305x boards */ | ||
84 | if (rt2x00_rf(rt2x00dev, RF3020) || | ||
85 | rt2x00_rf(rt2x00dev, RF3021) || | ||
86 | rt2x00_rf(rt2x00dev, RF3022)) | ||
87 | return true; | ||
88 | |||
89 | NOTICE(rt2x00dev, "Unknown RF chipset on rt305x\n"); | ||
90 | return false; | ||
91 | } | ||
92 | |||
79 | static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev, | 93 | static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev, |
80 | const unsigned int word, const u8 value) | 94 | const unsigned int word, const u8 value) |
81 | { | 95 | { |
@@ -794,6 +808,11 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, | |||
794 | TXPOWER_G_TO_DEV(info->tx_power1)); | 808 | TXPOWER_G_TO_DEV(info->tx_power1)); |
795 | rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); | 809 | rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); |
796 | 810 | ||
811 | rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); | ||
812 | rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, | ||
813 | TXPOWER_G_TO_DEV(info->tx_power2)); | ||
814 | rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); | ||
815 | |||
797 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); | 816 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); |
798 | rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); | 817 | rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); |
799 | rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); | 818 | rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); |
@@ -849,7 +868,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
849 | } | 868 | } |
850 | 869 | ||
851 | rt2800_register_read(rt2x00dev, TX_BAND_CFG, ®); | 870 | rt2800_register_read(rt2x00dev, TX_BAND_CFG, ®); |
852 | rt2x00_set_field32(®, TX_BAND_CFG_HT40_PLUS, conf_is_ht40_plus(conf)); | 871 | rt2x00_set_field32(®, TX_BAND_CFG_HT40_MINUS, conf_is_ht40_minus(conf)); |
853 | rt2x00_set_field32(®, TX_BAND_CFG_A, rf->channel > 14); | 872 | rt2x00_set_field32(®, TX_BAND_CFG_A, rf->channel > 14); |
854 | rt2x00_set_field32(®, TX_BAND_CFG_BG, rf->channel <= 14); | 873 | rt2x00_set_field32(®, TX_BAND_CFG_BG, rf->channel <= 14); |
855 | rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg); | 874 | rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg); |
@@ -882,7 +901,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
882 | rt2800_bbp_write(rt2x00dev, 4, bbp); | 901 | rt2800_bbp_write(rt2x00dev, 4, bbp); |
883 | 902 | ||
884 | rt2800_bbp_read(rt2x00dev, 3, &bbp); | 903 | rt2800_bbp_read(rt2x00dev, 3, &bbp); |
885 | rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf)); | 904 | rt2x00_set_field8(&bbp, BBP3_HT40_MINUS, conf_is_ht40_minus(conf)); |
886 | rt2800_bbp_write(rt2x00dev, 3, bbp); | 905 | rt2800_bbp_write(rt2x00dev, 3, bbp); |
887 | 906 | ||
888 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { | 907 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { |
@@ -1551,6 +1570,9 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
1551 | rt2800_wait_bbp_ready(rt2x00dev))) | 1570 | rt2800_wait_bbp_ready(rt2x00dev))) |
1552 | return -EACCES; | 1571 | return -EACCES; |
1553 | 1572 | ||
1573 | if (rt2800_is_305x_soc(rt2x00dev)) | ||
1574 | rt2800_bbp_write(rt2x00dev, 31, 0x08); | ||
1575 | |||
1554 | rt2800_bbp_write(rt2x00dev, 65, 0x2c); | 1576 | rt2800_bbp_write(rt2x00dev, 65, 0x2c); |
1555 | rt2800_bbp_write(rt2x00dev, 66, 0x38); | 1577 | rt2800_bbp_write(rt2x00dev, 66, 0x38); |
1556 | 1578 | ||
@@ -1571,6 +1593,9 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
1571 | rt2800_bbp_write(rt2x00dev, 79, 0x13); | 1593 | rt2800_bbp_write(rt2x00dev, 79, 0x13); |
1572 | rt2800_bbp_write(rt2x00dev, 80, 0x05); | 1594 | rt2800_bbp_write(rt2x00dev, 80, 0x05); |
1573 | rt2800_bbp_write(rt2x00dev, 81, 0x33); | 1595 | rt2800_bbp_write(rt2x00dev, 81, 0x33); |
1596 | } else if (rt2800_is_305x_soc(rt2x00dev)) { | ||
1597 | rt2800_bbp_write(rt2x00dev, 78, 0x0e); | ||
1598 | rt2800_bbp_write(rt2x00dev, 80, 0x08); | ||
1574 | } else { | 1599 | } else { |
1575 | rt2800_bbp_write(rt2x00dev, 81, 0x37); | 1600 | rt2800_bbp_write(rt2x00dev, 81, 0x37); |
1576 | } | 1601 | } |
@@ -1591,12 +1616,16 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
1591 | if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || | 1616 | if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || |
1592 | rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || | 1617 | rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || |
1593 | rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || | 1618 | rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || |
1594 | rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E)) | 1619 | rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || |
1620 | rt2800_is_305x_soc(rt2x00dev)) | ||
1595 | rt2800_bbp_write(rt2x00dev, 103, 0xc0); | 1621 | rt2800_bbp_write(rt2x00dev, 103, 0xc0); |
1596 | else | 1622 | else |
1597 | rt2800_bbp_write(rt2x00dev, 103, 0x00); | 1623 | rt2800_bbp_write(rt2x00dev, 103, 0x00); |
1598 | 1624 | ||
1599 | rt2800_bbp_write(rt2x00dev, 105, 0x05); | 1625 | if (rt2800_is_305x_soc(rt2x00dev)) |
1626 | rt2800_bbp_write(rt2x00dev, 105, 0x01); | ||
1627 | else | ||
1628 | rt2800_bbp_write(rt2x00dev, 105, 0x05); | ||
1600 | rt2800_bbp_write(rt2x00dev, 106, 0x35); | 1629 | rt2800_bbp_write(rt2x00dev, 106, 0x35); |
1601 | 1630 | ||
1602 | if (rt2x00_rt(rt2x00dev, RT3071) || | 1631 | if (rt2x00_rt(rt2x00dev, RT3071) || |
@@ -1613,11 +1642,6 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
1613 | rt2800_bbp_write(rt2x00dev, 138, value); | 1642 | rt2800_bbp_write(rt2x00dev, 138, value); |
1614 | } | 1643 | } |
1615 | 1644 | ||
1616 | if (rt2x00_rt(rt2x00dev, RT2872)) { | ||
1617 | rt2800_bbp_write(rt2x00dev, 31, 0x08); | ||
1618 | rt2800_bbp_write(rt2x00dev, 78, 0x0e); | ||
1619 | rt2800_bbp_write(rt2x00dev, 80, 0x08); | ||
1620 | } | ||
1621 | 1645 | ||
1622 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 1646 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
1623 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 1647 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
@@ -1703,7 +1727,8 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
1703 | if (!rt2x00_rt(rt2x00dev, RT3070) && | 1727 | if (!rt2x00_rt(rt2x00dev, RT3070) && |
1704 | !rt2x00_rt(rt2x00dev, RT3071) && | 1728 | !rt2x00_rt(rt2x00dev, RT3071) && |
1705 | !rt2x00_rt(rt2x00dev, RT3090) && | 1729 | !rt2x00_rt(rt2x00dev, RT3090) && |
1706 | !rt2x00_rt(rt2x00dev, RT3390)) | 1730 | !rt2x00_rt(rt2x00dev, RT3390) && |
1731 | !rt2800_is_305x_soc(rt2x00dev)) | ||
1707 | return 0; | 1732 | return 0; |
1708 | 1733 | ||
1709 | /* | 1734 | /* |
@@ -1771,6 +1796,40 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
1771 | rt2800_rfcsr_write(rt2x00dev, 29, 0x8f); | 1796 | rt2800_rfcsr_write(rt2x00dev, 29, 0x8f); |
1772 | rt2800_rfcsr_write(rt2x00dev, 30, 0x20); | 1797 | rt2800_rfcsr_write(rt2x00dev, 30, 0x20); |
1773 | rt2800_rfcsr_write(rt2x00dev, 31, 0x0f); | 1798 | rt2800_rfcsr_write(rt2x00dev, 31, 0x0f); |
1799 | } else if (rt2800_is_305x_soc(rt2x00dev)) { | ||
1800 | rt2800_rfcsr_write(rt2x00dev, 0, 0x50); | ||
1801 | rt2800_rfcsr_write(rt2x00dev, 1, 0x01); | ||
1802 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf7); | ||
1803 | rt2800_rfcsr_write(rt2x00dev, 3, 0x75); | ||
1804 | rt2800_rfcsr_write(rt2x00dev, 4, 0x40); | ||
1805 | rt2800_rfcsr_write(rt2x00dev, 5, 0x03); | ||
1806 | rt2800_rfcsr_write(rt2x00dev, 6, 0x02); | ||
1807 | rt2800_rfcsr_write(rt2x00dev, 7, 0x50); | ||
1808 | rt2800_rfcsr_write(rt2x00dev, 8, 0x39); | ||
1809 | rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); | ||
1810 | rt2800_rfcsr_write(rt2x00dev, 10, 0x60); | ||
1811 | rt2800_rfcsr_write(rt2x00dev, 11, 0x21); | ||
1812 | rt2800_rfcsr_write(rt2x00dev, 12, 0x75); | ||
1813 | rt2800_rfcsr_write(rt2x00dev, 13, 0x75); | ||
1814 | rt2800_rfcsr_write(rt2x00dev, 14, 0x90); | ||
1815 | rt2800_rfcsr_write(rt2x00dev, 15, 0x58); | ||
1816 | rt2800_rfcsr_write(rt2x00dev, 16, 0xb3); | ||
1817 | rt2800_rfcsr_write(rt2x00dev, 17, 0x92); | ||
1818 | rt2800_rfcsr_write(rt2x00dev, 18, 0x2c); | ||
1819 | rt2800_rfcsr_write(rt2x00dev, 19, 0x02); | ||
1820 | rt2800_rfcsr_write(rt2x00dev, 20, 0xba); | ||
1821 | rt2800_rfcsr_write(rt2x00dev, 21, 0xdb); | ||
1822 | rt2800_rfcsr_write(rt2x00dev, 22, 0x00); | ||
1823 | rt2800_rfcsr_write(rt2x00dev, 23, 0x31); | ||
1824 | rt2800_rfcsr_write(rt2x00dev, 24, 0x08); | ||
1825 | rt2800_rfcsr_write(rt2x00dev, 25, 0x01); | ||
1826 | rt2800_rfcsr_write(rt2x00dev, 26, 0x25); | ||
1827 | rt2800_rfcsr_write(rt2x00dev, 27, 0x23); | ||
1828 | rt2800_rfcsr_write(rt2x00dev, 28, 0x13); | ||
1829 | rt2800_rfcsr_write(rt2x00dev, 29, 0x83); | ||
1830 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); | ||
1831 | rt2800_rfcsr_write(rt2x00dev, 31, 0x00); | ||
1832 | return 0; | ||
1774 | } | 1833 | } |
1775 | 1834 | ||
1776 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { | 1835 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { |
@@ -1986,7 +2045,6 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1986 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | 2045 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); |
1987 | } else if (rt2x00_rt(rt2x00dev, RT2860) || | 2046 | } else if (rt2x00_rt(rt2x00dev, RT2860) || |
1988 | rt2x00_rt(rt2x00dev, RT2870) || | 2047 | rt2x00_rt(rt2x00dev, RT2870) || |
1989 | rt2x00_rt(rt2x00dev, RT2872) || | ||
1990 | rt2x00_rt(rt2x00dev, RT2872)) { | 2048 | rt2x00_rt(rt2x00dev, RT2872)) { |
1991 | /* | 2049 | /* |
1992 | * There is a max of 2 RX streams for RT28x0 series | 2050 | * There is a max of 2 RX streams for RT28x0 series |
@@ -2318,8 +2376,11 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2318 | else | 2376 | else |
2319 | spec->ht.ht_supported = false; | 2377 | spec->ht.ht_supported = false; |
2320 | 2378 | ||
2379 | /* | ||
2380 | * Don't set IEEE80211_HT_CAP_SUP_WIDTH_20_40 for now as it causes | ||
2381 | * reception problems with HT40 capable 11n APs | ||
2382 | */ | ||
2321 | spec->ht.cap = | 2383 | spec->ht.cap = |
2322 | IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
2323 | IEEE80211_HT_CAP_GRN_FLD | | 2384 | IEEE80211_HT_CAP_GRN_FLD | |
2324 | IEEE80211_HT_CAP_SGI_20 | | 2385 | IEEE80211_HT_CAP_SGI_20 | |
2325 | IEEE80211_HT_CAP_SGI_40 | | 2386 | IEEE80211_HT_CAP_SGI_40 | |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 0e52f174896c..f08b6a37bf2d 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -663,7 +663,7 @@ static int rt2800pci_write_tx_data(struct queue_entry* entry, | |||
663 | test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? | 663 | test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? |
664 | txdesc->key_idx : 0xff); | 664 | txdesc->key_idx : 0xff); |
665 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, | 665 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, |
666 | skb->len - txdesc->l2pad); | 666 | txdesc->length); |
667 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, | 667 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, |
668 | skbdesc->entry->queue->qid + 1); | 668 | skbdesc->entry->queue->qid + 1); |
669 | rt2x00_desc_write(txwi, 1, word); | 669 | rt2x00_desc_write(txwi, 1, word); |
@@ -895,10 +895,6 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, | |||
895 | (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) + | 895 | (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) + |
896 | rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2; | 896 | rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2; |
897 | 897 | ||
898 | rxdesc->noise = | ||
899 | (rt2x00_get_field32(rxwi3, RXWI_W3_SNR0) + | ||
900 | rt2x00_get_field32(rxwi3, RXWI_W3_SNR1)) / 2; | ||
901 | |||
902 | rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT); | 898 | rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT); |
903 | 899 | ||
904 | /* | 900 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 95c8a6134ff8..e3f3a97db807 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -437,7 +437,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
437 | test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? | 437 | test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? |
438 | txdesc->key_idx : 0xff); | 438 | txdesc->key_idx : 0xff); |
439 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, | 439 | rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, |
440 | skb->len - txdesc->l2pad); | 440 | txdesc->length); |
441 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, | 441 | rt2x00_set_field32(&word, TXWI_W1_PACKETID, |
442 | skbdesc->entry->queue->qid + 1); | 442 | skbdesc->entry->queue->qid + 1); |
443 | rt2x00_desc_write(txwi, 1, word); | 443 | rt2x00_desc_write(txwi, 1, word); |
@@ -645,10 +645,6 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
645 | (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) + | 645 | (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) + |
646 | rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2; | 646 | rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2; |
647 | 647 | ||
648 | rxdesc->noise = | ||
649 | (rt2x00_get_field32(rxwi3, RXWI_W3_SNR0) + | ||
650 | rt2x00_get_field32(rxwi3, RXWI_W3_SNR1)) / 2; | ||
651 | |||
652 | rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT); | 648 | rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT); |
653 | 649 | ||
654 | /* | 650 | /* |
@@ -1027,7 +1023,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1027 | #ifdef CONFIG_RT2800USB_UNKNOWN | 1023 | #ifdef CONFIG_RT2800USB_UNKNOWN |
1028 | /* | 1024 | /* |
1029 | * Unclear what kind of devices these are (they aren't supported by the | 1025 | * Unclear what kind of devices these are (they aren't supported by the |
1030 | * vendor driver). | 1026 | * vendor linux driver). |
1031 | */ | 1027 | */ |
1032 | /* Amigo */ | 1028 | /* Amigo */ |
1033 | { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1029 | { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) }, |
@@ -1040,6 +1036,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1040 | /* AzureWave */ | 1036 | /* AzureWave */ |
1041 | { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1037 | { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1042 | { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1038 | { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1039 | { USB_DEVICE(0x13d3, 0x3322), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
1043 | /* Belkin */ | 1040 | /* Belkin */ |
1044 | { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1041 | { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1045 | /* Buffalo */ | 1042 | /* Buffalo */ |
@@ -1058,6 +1055,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1058 | { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1055 | { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1059 | { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1056 | { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1060 | { USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1057 | { USB_DEVICE(0x07d1, 0x3c15), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1058 | { USB_DEVICE(0x07d1, 0x3c17), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
1061 | /* Encore */ | 1059 | /* Encore */ |
1062 | { USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1060 | { USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1063 | /* Gemtek */ | 1061 | /* Gemtek */ |
@@ -1074,11 +1072,13 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1074 | /* Motorola */ | 1072 | /* Motorola */ |
1075 | { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1073 | { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1076 | /* Ovislink */ | 1074 | /* Ovislink */ |
1075 | { USB_DEVICE(0x1b75, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
1077 | { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1076 | { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1078 | /* Pegatron */ | 1077 | /* Pegatron */ |
1079 | { USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1078 | { USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1080 | { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1079 | { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1081 | { USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1080 | { USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1081 | { USB_DEVICE(0x1d4d, 0x0011), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
1082 | /* Planex */ | 1082 | /* Planex */ |
1083 | { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1083 | { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1084 | /* Qcom */ | 1084 | /* Qcom */ |
@@ -1087,6 +1087,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1087 | { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1087 | { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1088 | { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1088 | { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1089 | { USB_DEVICE(0x083a, 0xd522), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1089 | { USB_DEVICE(0x083a, 0xd522), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1090 | { USB_DEVICE(0x083a, 0xf511), USB_DEVICE_DATA(&rt2800usb_ops) }, | ||
1090 | /* Sweex */ | 1091 | /* Sweex */ |
1091 | { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1092 | { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) }, |
1092 | { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) }, | 1093 | { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) }, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index eda73ba735a6..3ae468c4d760 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -435,7 +435,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, | |||
435 | rx_status->mactime = rxdesc.timestamp; | 435 | rx_status->mactime = rxdesc.timestamp; |
436 | rx_status->rate_idx = rate_idx; | 436 | rx_status->rate_idx = rate_idx; |
437 | rx_status->signal = rxdesc.rssi; | 437 | rx_status->signal = rxdesc.rssi; |
438 | rx_status->noise = rxdesc.noise; | ||
439 | rx_status->flag = rxdesc.flags; | 438 | rx_status->flag = rxdesc.flags; |
440 | rx_status->antenna = rt2x00dev->link.ant.active.rx; | 439 | rx_status->antenna = rt2x00dev->link.ant.active.rx; |
441 | 440 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 91b7fb99ceb4..e22029fcf411 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -334,12 +334,10 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
334 | txdesc->aifs = entry->queue->aifs; | 334 | txdesc->aifs = entry->queue->aifs; |
335 | 335 | ||
336 | /* | 336 | /* |
337 | * Header and alignment information. | 337 | * Header and frame information. |
338 | */ | 338 | */ |
339 | txdesc->length = entry->skb->len; | ||
339 | txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb); | 340 | txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb); |
340 | if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags) && | ||
341 | (entry->skb->len > txdesc->header_length)) | ||
342 | txdesc->l2pad = L2PAD_SIZE(txdesc->header_length); | ||
343 | 341 | ||
344 | /* | 342 | /* |
345 | * Check whether this frame is to be acked. | 343 | * Check whether this frame is to be acked. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index c1e482bb37b3..94a48c174d67 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -183,7 +183,6 @@ enum rxdone_entry_desc_flags { | |||
183 | * @timestamp: RX Timestamp | 183 | * @timestamp: RX Timestamp |
184 | * @signal: Signal of the received frame. | 184 | * @signal: Signal of the received frame. |
185 | * @rssi: RSSI of the received frame. | 185 | * @rssi: RSSI of the received frame. |
186 | * @noise: Measured noise during frame reception. | ||
187 | * @size: Data size of the received frame. | 186 | * @size: Data size of the received frame. |
188 | * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags). | 187 | * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags). |
189 | * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags). | 188 | * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags). |
@@ -197,7 +196,6 @@ struct rxdone_entry_desc { | |||
197 | u64 timestamp; | 196 | u64 timestamp; |
198 | int signal; | 197 | int signal; |
199 | int rssi; | 198 | int rssi; |
200 | int noise; | ||
201 | int size; | 199 | int size; |
202 | int flags; | 200 | int flags; |
203 | int dev_flags; | 201 | int dev_flags; |
@@ -287,8 +285,8 @@ enum txentry_desc_flags { | |||
287 | * | 285 | * |
288 | * @flags: Descriptor flags (See &enum queue_entry_flags). | 286 | * @flags: Descriptor flags (See &enum queue_entry_flags). |
289 | * @queue: Queue identification (See &enum data_queue_qid). | 287 | * @queue: Queue identification (See &enum data_queue_qid). |
288 | * @length: Length of the entire frame. | ||
290 | * @header_length: Length of 802.11 header. | 289 | * @header_length: Length of 802.11 header. |
291 | * @l2pad: Amount of padding to align 802.11 payload to 4-byte boundrary. | ||
292 | * @length_high: PLCP length high word. | 290 | * @length_high: PLCP length high word. |
293 | * @length_low: PLCP length low word. | 291 | * @length_low: PLCP length low word. |
294 | * @signal: PLCP signal. | 292 | * @signal: PLCP signal. |
@@ -313,8 +311,8 @@ struct txentry_desc { | |||
313 | 311 | ||
314 | enum data_queue_qid queue; | 312 | enum data_queue_qid queue; |
315 | 313 | ||
314 | u16 length; | ||
316 | u16 header_length; | 315 | u16 header_length; |
317 | u16 l2pad; | ||
318 | 316 | ||
319 | u16 length_high; | 317 | u16 length_high; |
320 | u16 length_low; | 318 | u16 length_low; |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index b9885981f3a8..26ee7911fba9 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1809,7 +1809,8 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1809 | 1809 | ||
1810 | if (skbdesc->desc_len > TXINFO_SIZE) { | 1810 | if (skbdesc->desc_len > TXINFO_SIZE) { |
1811 | rt2x00_desc_read(txd, 11, &word); | 1811 | rt2x00_desc_read(txd, 11, &word); |
1812 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skb->len); | 1812 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, |
1813 | txdesc->length); | ||
1813 | rt2x00_desc_write(txd, 11, word); | 1814 | rt2x00_desc_write(txd, 11, word); |
1814 | } | 1815 | } |
1815 | 1816 | ||
@@ -1832,7 +1833,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1832 | rt2x00_set_field32(&word, TXD_W0_KEY_TABLE, | 1833 | rt2x00_set_field32(&word, TXD_W0_KEY_TABLE, |
1833 | test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags)); | 1834 | test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags)); |
1834 | rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx); | 1835 | rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx); |
1835 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); | 1836 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); |
1836 | rt2x00_set_field32(&word, TXD_W0_BURST, | 1837 | rt2x00_set_field32(&word, TXD_W0_BURST, |
1837 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); | 1838 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1838 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher); | 1839 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher); |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 576ea9dd2824..39b3c6d04af4 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1495,7 +1495,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1495 | rt2x00_set_field32(&word, TXD_W0_KEY_TABLE, | 1495 | rt2x00_set_field32(&word, TXD_W0_KEY_TABLE, |
1496 | test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags)); | 1496 | test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags)); |
1497 | rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx); | 1497 | rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx); |
1498 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); | 1498 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); |
1499 | rt2x00_set_field32(&word, TXD_W0_BURST2, | 1499 | rt2x00_set_field32(&word, TXD_W0_BURST2, |
1500 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); | 1500 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1501 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher); | 1501 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher); |
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index 6b46329b732f..21307f2412b8 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c | |||
@@ -188,6 +188,7 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) | |||
188 | info->flags |= IEEE80211_TX_STAT_ACK; | 188 | info->flags |= IEEE80211_TX_STAT_ACK; |
189 | 189 | ||
190 | info->status.rates[0].count = (flags & 0xFF) + 1; | 190 | info->status.rates[0].count = (flags & 0xFF) + 1; |
191 | info->status.rates[1].idx = -1; | ||
191 | 192 | ||
192 | ieee80211_tx_status_irqsafe(dev, skb); | 193 | ieee80211_tx_status_irqsafe(dev, skb); |
193 | if (ring->entries - skb_queue_len(&ring->queue) == 2) | 194 | if (ring->entries - skb_queue_len(&ring->queue) == 2) |
@@ -297,7 +298,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
297 | entry->flags = cpu_to_le32(tx_flags); | 298 | entry->flags = cpu_to_le32(tx_flags); |
298 | __skb_queue_tail(&ring->queue, skb); | 299 | __skb_queue_tail(&ring->queue, skb); |
299 | if (ring->entries - skb_queue_len(&ring->queue) < 2) | 300 | if (ring->entries - skb_queue_len(&ring->queue) < 2) |
300 | ieee80211_stop_queue(dev, skb_get_queue_mapping(skb)); | 301 | ieee80211_stop_queue(dev, prio); |
301 | spin_unlock_irqrestore(&priv->lock, flags); | 302 | spin_unlock_irqrestore(&priv->lock, flags); |
302 | 303 | ||
303 | rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); | 304 | rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); |
@@ -827,6 +828,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
827 | const char *chip_name, *rf_name = NULL; | 828 | const char *chip_name, *rf_name = NULL; |
828 | u32 reg; | 829 | u32 reg; |
829 | u16 eeprom_val; | 830 | u16 eeprom_val; |
831 | u8 mac_addr[ETH_ALEN]; | ||
830 | 832 | ||
831 | err = pci_enable_device(pdev); | 833 | err = pci_enable_device(pdev); |
832 | if (err) { | 834 | if (err) { |
@@ -987,12 +989,13 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
987 | eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam); | 989 | eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam); |
988 | } | 990 | } |
989 | 991 | ||
990 | eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)dev->wiphy->perm_addr, 3); | 992 | eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)mac_addr, 3); |
991 | if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { | 993 | if (!is_valid_ether_addr(mac_addr)) { |
992 | printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using" | 994 | printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using" |
993 | " randomly generated MAC addr\n", pci_name(pdev)); | 995 | " randomly generated MAC addr\n", pci_name(pdev)); |
994 | random_ether_addr(dev->wiphy->perm_addr); | 996 | random_ether_addr(mac_addr); |
995 | } | 997 | } |
998 | SET_IEEE80211_PERM_ADDR(dev, mac_addr); | ||
996 | 999 | ||
997 | /* CCK TX power */ | 1000 | /* CCK TX power */ |
998 | for (i = 0; i < 14; i += 2) { | 1001 | for (i = 0; i < 14; i += 2) { |
@@ -1024,7 +1027,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
1024 | } | 1027 | } |
1025 | 1028 | ||
1026 | printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n", | 1029 | printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n", |
1027 | wiphy_name(dev->wiphy), dev->wiphy->perm_addr, | 1030 | wiphy_name(dev->wiphy), mac_addr, |
1028 | chip_name, priv->rf->name); | 1031 | chip_name, priv->rf->name); |
1029 | 1032 | ||
1030 | return 0; | 1033 | return 0; |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 738921fda027..891b8490e349 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c | |||
@@ -1333,6 +1333,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1333 | u16 txpwr, reg; | 1333 | u16 txpwr, reg; |
1334 | u16 product_id = le16_to_cpu(udev->descriptor.idProduct); | 1334 | u16 product_id = le16_to_cpu(udev->descriptor.idProduct); |
1335 | int err, i; | 1335 | int err, i; |
1336 | u8 mac_addr[ETH_ALEN]; | ||
1336 | 1337 | ||
1337 | dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops); | 1338 | dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops); |
1338 | if (!dev) { | 1339 | if (!dev) { |
@@ -1390,12 +1391,13 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1390 | udelay(10); | 1391 | udelay(10); |
1391 | 1392 | ||
1392 | eeprom_93cx6_multiread(&eeprom, RTL8187_EEPROM_MAC_ADDR, | 1393 | eeprom_93cx6_multiread(&eeprom, RTL8187_EEPROM_MAC_ADDR, |
1393 | (__le16 __force *)dev->wiphy->perm_addr, 3); | 1394 | (__le16 __force *)mac_addr, 3); |
1394 | if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { | 1395 | if (!is_valid_ether_addr(mac_addr)) { |
1395 | printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly " | 1396 | printk(KERN_WARNING "rtl8187: Invalid hwaddr! Using randomly " |
1396 | "generated MAC address\n"); | 1397 | "generated MAC address\n"); |
1397 | random_ether_addr(dev->wiphy->perm_addr); | 1398 | random_ether_addr(mac_addr); |
1398 | } | 1399 | } |
1400 | SET_IEEE80211_PERM_ADDR(dev, mac_addr); | ||
1399 | 1401 | ||
1400 | channel = priv->channels; | 1402 | channel = priv->channels; |
1401 | for (i = 0; i < 3; i++) { | 1403 | for (i = 0; i < 3; i++) { |
@@ -1526,7 +1528,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1526 | skb_queue_head_init(&priv->b_tx_status.queue); | 1528 | skb_queue_head_init(&priv->b_tx_status.queue); |
1527 | 1529 | ||
1528 | printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n", | 1530 | printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n", |
1529 | wiphy_name(dev->wiphy), dev->wiphy->perm_addr, | 1531 | wiphy_name(dev->wiphy), mac_addr, |
1530 | chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask); | 1532 | chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask); |
1531 | 1533 | ||
1532 | #ifdef CONFIG_RTL8187_LEDS | 1534 | #ifdef CONFIG_RTL8187_LEDS |
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index 51614d181ccb..00b24282fc73 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c | |||
@@ -857,6 +857,7 @@ out: | |||
857 | } | 857 | } |
858 | 858 | ||
859 | static int wl1251_op_hw_scan(struct ieee80211_hw *hw, | 859 | static int wl1251_op_hw_scan(struct ieee80211_hw *hw, |
860 | struct ieee80211_vif *vif, | ||
860 | struct cfg80211_scan_request *req) | 861 | struct cfg80211_scan_request *req) |
861 | { | 862 | { |
862 | struct wl1251 *wl = hw->priv; | 863 | struct wl1251 *wl = hw->priv; |
@@ -1291,7 +1292,6 @@ int wl1251_init_ieee80211(struct wl1251 *wl) | |||
1291 | wl->hw->channel_change_time = 10000; | 1292 | wl->hw->channel_change_time = 10000; |
1292 | 1293 | ||
1293 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | | 1294 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | |
1294 | IEEE80211_HW_NOISE_DBM | | ||
1295 | IEEE80211_HW_SUPPORTS_PS | | 1295 | IEEE80211_HW_SUPPORTS_PS | |
1296 | IEEE80211_HW_BEACON_FILTER | | 1296 | IEEE80211_HW_BEACON_FILTER | |
1297 | IEEE80211_HW_SUPPORTS_UAPSD; | 1297 | IEEE80211_HW_SUPPORTS_UAPSD; |
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c index 6f229e0990f4..af5c67b4da95 100644 --- a/drivers/net/wireless/wl12xx/wl1251_rx.c +++ b/drivers/net/wireless/wl12xx/wl1251_rx.c | |||
@@ -74,12 +74,6 @@ static void wl1251_rx_status(struct wl1251 *wl, | |||
74 | 74 | ||
75 | status->signal = desc->rssi; | 75 | status->signal = desc->rssi; |
76 | 76 | ||
77 | /* | ||
78 | * FIXME: guessing that snr needs to be divided by two, otherwise | ||
79 | * the values don't make any sense | ||
80 | */ | ||
81 | status->noise = desc->rssi - desc->snr / 2; | ||
82 | |||
83 | status->freq = ieee80211_channel_to_frequency(desc->channel); | 77 | status->freq = ieee80211_channel_to_frequency(desc->channel); |
84 | 78 | ||
85 | status->flag |= RX_FLAG_TSFT; | 79 | status->flag |= RX_FLAG_TSFT; |
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c index 2ad086efe06e..e19e2f8f1e52 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.c +++ b/drivers/net/wireless/wl12xx/wl1271_acx.c | |||
@@ -590,7 +590,7 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl) | |||
590 | 590 | ||
591 | /* BT-WLAN coext parameters */ | 591 | /* BT-WLAN coext parameters */ |
592 | for (i = 0; i < CONF_SG_PARAMS_MAX; i++) | 592 | for (i = 0; i < CONF_SG_PARAMS_MAX; i++) |
593 | param->params[i] = c->params[i]; | 593 | param->params[i] = cpu_to_le32(c->params[i]); |
594 | param->param_idx = CONF_SG_PARAMS_ALL; | 594 | param->param_idx = CONF_SG_PARAMS_ALL; |
595 | 595 | ||
596 | ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); | 596 | ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); |
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index 8087dc17f29d..acb1d9e6b7d2 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c | |||
@@ -351,7 +351,7 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl) | |||
351 | static int wl1271_boot_run_firmware(struct wl1271 *wl) | 351 | static int wl1271_boot_run_firmware(struct wl1271 *wl) |
352 | { | 352 | { |
353 | int loop, ret; | 353 | int loop, ret; |
354 | u32 chip_id, interrupt; | 354 | u32 chip_id, intr; |
355 | 355 | ||
356 | wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); | 356 | wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); |
357 | 357 | ||
@@ -368,15 +368,15 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl) | |||
368 | loop = 0; | 368 | loop = 0; |
369 | while (loop++ < INIT_LOOP) { | 369 | while (loop++ < INIT_LOOP) { |
370 | udelay(INIT_LOOP_DELAY); | 370 | udelay(INIT_LOOP_DELAY); |
371 | interrupt = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); | 371 | intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); |
372 | 372 | ||
373 | if (interrupt == 0xffffffff) { | 373 | if (intr == 0xffffffff) { |
374 | wl1271_error("error reading hardware complete " | 374 | wl1271_error("error reading hardware complete " |
375 | "init indication"); | 375 | "init indication"); |
376 | return -EIO; | 376 | return -EIO; |
377 | } | 377 | } |
378 | /* check that ACX_INTR_INIT_COMPLETE is enabled */ | 378 | /* check that ACX_INTR_INIT_COMPLETE is enabled */ |
379 | else if (interrupt & WL1271_ACX_INTR_INIT_COMPLETE) { | 379 | else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) { |
380 | wl1271_write32(wl, ACX_REG_INTERRUPT_ACK, | 380 | wl1271_write32(wl, ACX_REG_INTERRUPT_ACK, |
381 | WL1271_ACX_INTR_INIT_COMPLETE); | 381 | WL1271_ACX_INTR_INIT_COMPLETE); |
382 | break; | 382 | break; |
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index 6b5ba8ec94c9..62c11af1d8e2 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include "wl1271_cmd.h" | 37 | #include "wl1271_cmd.h" |
38 | #include "wl1271_event.h" | 38 | #include "wl1271_event.h" |
39 | 39 | ||
40 | #define WL1271_CMD_POLL_COUNT 5 | 40 | #define WL1271_CMD_FAST_POLL_COUNT 50 |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * send command to firmware | 43 | * send command to firmware |
@@ -77,11 +77,11 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, | |||
77 | goto out; | 77 | goto out; |
78 | } | 78 | } |
79 | 79 | ||
80 | udelay(10); | ||
81 | poll_count++; | 80 | poll_count++; |
82 | if (poll_count == WL1271_CMD_POLL_COUNT) | 81 | if (poll_count < WL1271_CMD_FAST_POLL_COUNT) |
83 | wl1271_info("cmd polling took over %d cycles", | 82 | udelay(10); |
84 | poll_count); | 83 | else |
84 | msleep(1); | ||
85 | 85 | ||
86 | intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); | 86 | intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); |
87 | } | 87 | } |
@@ -318,7 +318,7 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) | |||
318 | join->rx_config_options = cpu_to_le32(wl->rx_config); | 318 | join->rx_config_options = cpu_to_le32(wl->rx_config); |
319 | join->rx_filter_options = cpu_to_le32(wl->rx_filter); | 319 | join->rx_filter_options = cpu_to_le32(wl->rx_filter); |
320 | join->bss_type = bss_type; | 320 | join->bss_type = bss_type; |
321 | join->basic_rate_set = wl->basic_rate_set; | 321 | join->basic_rate_set = cpu_to_le32(wl->basic_rate_set); |
322 | 322 | ||
323 | if (wl->band == IEEE80211_BAND_5GHZ) | 323 | if (wl->band == IEEE80211_BAND_5GHZ) |
324 | join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; | 324 | join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; |
@@ -615,7 +615,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, | |||
615 | params->params.scan_options = cpu_to_le16(scan_options); | 615 | params->params.scan_options = cpu_to_le16(scan_options); |
616 | 616 | ||
617 | params->params.num_probe_requests = probe_requests; | 617 | params->params.num_probe_requests = probe_requests; |
618 | params->params.tx_rate = rate; | 618 | params->params.tx_rate = cpu_to_le32(rate); |
619 | params->params.tid_trigger = 0; | 619 | params->params.tid_trigger = 0; |
620 | params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; | 620 | params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; |
621 | 621 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h index c44307c4bcf8..d046d044b5bd 100644 --- a/drivers/net/wireless/wl12xx/wl1271_conf.h +++ b/drivers/net/wireless/wl12xx/wl1271_conf.h | |||
@@ -401,7 +401,7 @@ enum { | |||
401 | }; | 401 | }; |
402 | 402 | ||
403 | struct conf_sg_settings { | 403 | struct conf_sg_settings { |
404 | __le32 params[CONF_SG_PARAMS_MAX]; | 404 | u32 params[CONF_SG_PARAMS_MAX]; |
405 | u8 state; | 405 | u8 state; |
406 | }; | 406 | }; |
407 | 407 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index e47a58d2cc19..62e544041d0d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c | |||
@@ -1118,14 +1118,13 @@ static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters) | |||
1118 | } | 1118 | } |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | static int wl1271_join_channel(struct wl1271 *wl, int channel) | 1121 | static int wl1271_dummy_join(struct wl1271 *wl) |
1122 | { | 1122 | { |
1123 | int ret = 0; | 1123 | int ret = 0; |
1124 | /* we need to use a dummy BSSID for now */ | 1124 | /* we need to use a dummy BSSID for now */ |
1125 | static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, | 1125 | static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, |
1126 | 0xad, 0xbe, 0xef }; | 1126 | 0xad, 0xbe, 0xef }; |
1127 | 1127 | ||
1128 | wl->channel = channel; | ||
1129 | memcpy(wl->bssid, dummy_bssid, ETH_ALEN); | 1128 | memcpy(wl->bssid, dummy_bssid, ETH_ALEN); |
1130 | 1129 | ||
1131 | /* pass through frames from all BSS */ | 1130 | /* pass through frames from all BSS */ |
@@ -1141,7 +1140,47 @@ out: | |||
1141 | return ret; | 1140 | return ret; |
1142 | } | 1141 | } |
1143 | 1142 | ||
1144 | static int wl1271_unjoin_channel(struct wl1271 *wl) | 1143 | static int wl1271_join(struct wl1271 *wl) |
1144 | { | ||
1145 | int ret; | ||
1146 | |||
1147 | ret = wl1271_cmd_join(wl, wl->set_bss_type); | ||
1148 | if (ret < 0) | ||
1149 | goto out; | ||
1150 | |||
1151 | set_bit(WL1271_FLAG_JOINED, &wl->flags); | ||
1152 | |||
1153 | if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) | ||
1154 | goto out; | ||
1155 | |||
1156 | /* | ||
1157 | * The join command disable the keep-alive mode, shut down its process, | ||
1158 | * and also clear the template config, so we need to reset it all after | ||
1159 | * the join. The acx_aid starts the keep-alive process, and the order | ||
1160 | * of the commands below is relevant. | ||
1161 | */ | ||
1162 | ret = wl1271_acx_keep_alive_mode(wl, true); | ||
1163 | if (ret < 0) | ||
1164 | goto out; | ||
1165 | |||
1166 | ret = wl1271_acx_aid(wl, wl->aid); | ||
1167 | if (ret < 0) | ||
1168 | goto out; | ||
1169 | |||
1170 | ret = wl1271_cmd_build_klv_null_data(wl); | ||
1171 | if (ret < 0) | ||
1172 | goto out; | ||
1173 | |||
1174 | ret = wl1271_acx_keep_alive_config(wl, CMD_TEMPL_KLV_IDX_NULL_DATA, | ||
1175 | ACX_KEEP_ALIVE_TPL_VALID); | ||
1176 | if (ret < 0) | ||
1177 | goto out; | ||
1178 | |||
1179 | out: | ||
1180 | return ret; | ||
1181 | } | ||
1182 | |||
1183 | static int wl1271_unjoin(struct wl1271 *wl) | ||
1145 | { | 1184 | { |
1146 | int ret; | 1185 | int ret; |
1147 | 1186 | ||
@@ -1231,7 +1270,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
1231 | "failed %d", ret); | 1270 | "failed %d", ret); |
1232 | 1271 | ||
1233 | if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { | 1272 | if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { |
1234 | ret = wl1271_cmd_join(wl, wl->set_bss_type); | 1273 | ret = wl1271_join(wl); |
1235 | if (ret < 0) | 1274 | if (ret < 0) |
1236 | wl1271_warning("cmd join to update channel " | 1275 | wl1271_warning("cmd join to update channel " |
1237 | "failed %d", ret); | 1276 | "failed %d", ret); |
@@ -1241,9 +1280,9 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
1241 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { | 1280 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { |
1242 | if (conf->flags & IEEE80211_CONF_IDLE && | 1281 | if (conf->flags & IEEE80211_CONF_IDLE && |
1243 | test_bit(WL1271_FLAG_JOINED, &wl->flags)) | 1282 | test_bit(WL1271_FLAG_JOINED, &wl->flags)) |
1244 | wl1271_unjoin_channel(wl); | 1283 | wl1271_unjoin(wl); |
1245 | else if (!(conf->flags & IEEE80211_CONF_IDLE)) | 1284 | else if (!(conf->flags & IEEE80211_CONF_IDLE)) |
1246 | wl1271_join_channel(wl, channel); | 1285 | wl1271_dummy_join(wl); |
1247 | 1286 | ||
1248 | if (conf->flags & IEEE80211_CONF_IDLE) { | 1287 | if (conf->flags & IEEE80211_CONF_IDLE) { |
1249 | wl->rate_set = wl1271_min_rate_get(wl); | 1288 | wl->rate_set = wl1271_min_rate_get(wl); |
@@ -1519,6 +1558,7 @@ out: | |||
1519 | } | 1558 | } |
1520 | 1559 | ||
1521 | static int wl1271_op_hw_scan(struct ieee80211_hw *hw, | 1560 | static int wl1271_op_hw_scan(struct ieee80211_hw *hw, |
1561 | struct ieee80211_vif *vif, | ||
1522 | struct cfg80211_scan_request *req) | 1562 | struct cfg80211_scan_request *req) |
1523 | { | 1563 | { |
1524 | struct wl1271 *wl = hw->priv; | 1564 | struct wl1271 *wl = hw->priv; |
@@ -1607,7 +1647,6 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1607 | enum wl1271_cmd_ps_mode mode; | 1647 | enum wl1271_cmd_ps_mode mode; |
1608 | struct wl1271 *wl = hw->priv; | 1648 | struct wl1271 *wl = hw->priv; |
1609 | bool do_join = false; | 1649 | bool do_join = false; |
1610 | bool do_keepalive = false; | ||
1611 | int ret; | 1650 | int ret; |
1612 | 1651 | ||
1613 | wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); | 1652 | wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); |
@@ -1702,6 +1741,10 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1702 | if (ret < 0) | 1741 | if (ret < 0) |
1703 | goto out_sleep; | 1742 | goto out_sleep; |
1704 | 1743 | ||
1744 | ret = wl1271_build_qos_null_data(wl); | ||
1745 | if (ret < 0) | ||
1746 | goto out_sleep; | ||
1747 | |||
1705 | /* filter out all packets not from this BSSID */ | 1748 | /* filter out all packets not from this BSSID */ |
1706 | wl1271_configure_filters(wl, 0); | 1749 | wl1271_configure_filters(wl, 0); |
1707 | 1750 | ||
@@ -1746,19 +1789,6 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1746 | ret = wl1271_cmd_build_probe_req(wl, NULL, 0, | 1789 | ret = wl1271_cmd_build_probe_req(wl, NULL, 0, |
1747 | NULL, 0, wl->band); | 1790 | NULL, 0, wl->band); |
1748 | 1791 | ||
1749 | /* Enable the keep-alive feature */ | ||
1750 | ret = wl1271_acx_keep_alive_mode(wl, true); | ||
1751 | if (ret < 0) | ||
1752 | goto out_sleep; | ||
1753 | |||
1754 | /* | ||
1755 | * This is awkward. The keep-alive configs must be done | ||
1756 | * *after* the join command, because otherwise it will | ||
1757 | * not work, but it must only be done *once* because | ||
1758 | * otherwise the firmware will start complaining. | ||
1759 | */ | ||
1760 | do_keepalive = true; | ||
1761 | |||
1762 | /* enable the connection monitoring feature */ | 1792 | /* enable the connection monitoring feature */ |
1763 | ret = wl1271_acx_conn_monit_params(wl, true); | 1793 | ret = wl1271_acx_conn_monit_params(wl, true); |
1764 | if (ret < 0) | 1794 | if (ret < 0) |
@@ -1826,35 +1856,11 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1826 | } | 1856 | } |
1827 | 1857 | ||
1828 | if (do_join) { | 1858 | if (do_join) { |
1829 | ret = wl1271_cmd_join(wl, wl->set_bss_type); | 1859 | ret = wl1271_join(wl); |
1830 | if (ret < 0) { | 1860 | if (ret < 0) { |
1831 | wl1271_warning("cmd join failed %d", ret); | 1861 | wl1271_warning("cmd join failed %d", ret); |
1832 | goto out_sleep; | 1862 | goto out_sleep; |
1833 | } | 1863 | } |
1834 | set_bit(WL1271_FLAG_JOINED, &wl->flags); | ||
1835 | } | ||
1836 | |||
1837 | /* | ||
1838 | * The JOIN operation shuts down the firmware keep-alive as a side | ||
1839 | * effect, and the ACX_AID will start the keep-alive as a side effect. | ||
1840 | * Hence, for non-IBSS, the ACX_AID must always happen *after* the | ||
1841 | * JOIN operation, and the template config after the ACX_AID. | ||
1842 | */ | ||
1843 | if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { | ||
1844 | ret = wl1271_acx_aid(wl, wl->aid); | ||
1845 | if (ret < 0) | ||
1846 | goto out_sleep; | ||
1847 | } | ||
1848 | |||
1849 | if (do_keepalive) { | ||
1850 | ret = wl1271_cmd_build_klv_null_data(wl); | ||
1851 | if (ret < 0) | ||
1852 | goto out_sleep; | ||
1853 | ret = wl1271_acx_keep_alive_config( | ||
1854 | wl, CMD_TEMPL_KLV_IDX_NULL_DATA, | ||
1855 | ACX_KEEP_ALIVE_TPL_VALID); | ||
1856 | if (ret < 0) | ||
1857 | goto out_sleep; | ||
1858 | } | 1864 | } |
1859 | 1865 | ||
1860 | out_sleep: | 1866 | out_sleep: |
@@ -2265,7 +2271,6 @@ int wl1271_init_ieee80211(struct wl1271 *wl) | |||
2265 | wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval; | 2271 | wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval; |
2266 | 2272 | ||
2267 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | | 2273 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | |
2268 | IEEE80211_HW_NOISE_DBM | | ||
2269 | IEEE80211_HW_BEACON_FILTER | | 2274 | IEEE80211_HW_BEACON_FILTER | |
2270 | IEEE80211_HW_SUPPORTS_PS | | 2275 | IEEE80211_HW_SUPPORTS_PS | |
2271 | IEEE80211_HW_SUPPORTS_UAPSD | | 2276 | IEEE80211_HW_SUPPORTS_UAPSD | |
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 59c3c0fdbecd..59ae76bace14 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c | |||
@@ -233,6 +233,8 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc) | |||
233 | { | 233 | { |
234 | if (!cc->dev) | 234 | if (!cc->dev) |
235 | return; /* We don't have a ChipCommon */ | 235 | return; /* We don't have a ChipCommon */ |
236 | if (cc->dev->id.revision >= 11) | ||
237 | cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); | ||
236 | ssb_pmu_init(cc); | 238 | ssb_pmu_init(cc); |
237 | chipco_powercontrol_init(cc); | 239 | chipco_powercontrol_init(cc); |
238 | ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); | 240 | ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); |
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 80ff7d9e60de..7e5b8a8a64cc 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c | |||
@@ -834,6 +834,9 @@ int ssb_bus_pcibus_register(struct ssb_bus *bus, | |||
834 | if (!err) { | 834 | if (!err) { |
835 | ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " | 835 | ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " |
836 | "PCI device %s\n", dev_name(&host_pci->dev)); | 836 | "PCI device %s\n", dev_name(&host_pci->dev)); |
837 | } else { | ||
838 | ssb_printk(KERN_ERR PFX "Failed to register PCI version" | ||
839 | " of SSB with error %d\n", err); | ||
837 | } | 840 | } |
838 | 841 | ||
839 | return err; | 842 | return err; |
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index a8dbb06623c9..989e2752cc36 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
@@ -168,7 +168,7 @@ err_pci: | |||
168 | } | 168 | } |
169 | 169 | ||
170 | /* Get the word-offset for a SSB_SPROM_XXX define. */ | 170 | /* Get the word-offset for a SSB_SPROM_XXX define. */ |
171 | #define SPOFF(offset) (((offset) - SSB_SPROM_BASE) / sizeof(u16)) | 171 | #define SPOFF(offset) ((offset) / sizeof(u16)) |
172 | /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */ | 172 | /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */ |
173 | #define SPEX16(_outvar, _offset, _mask, _shift) \ | 173 | #define SPEX16(_outvar, _offset, _mask, _shift) \ |
174 | out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift)) | 174 | out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift)) |
@@ -254,7 +254,7 @@ static int sprom_do_read(struct ssb_bus *bus, u16 *sprom) | |||
254 | int i; | 254 | int i; |
255 | 255 | ||
256 | for (i = 0; i < bus->sprom_size; i++) | 256 | for (i = 0; i < bus->sprom_size; i++) |
257 | sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2)); | 257 | sprom[i] = ioread16(bus->mmio + bus->sprom_offset + (i * 2)); |
258 | 258 | ||
259 | return 0; | 259 | return 0; |
260 | } | 260 | } |
@@ -285,7 +285,7 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom) | |||
285 | ssb_printk("75%%"); | 285 | ssb_printk("75%%"); |
286 | else if (i % 2) | 286 | else if (i % 2) |
287 | ssb_printk("."); | 287 | ssb_printk("."); |
288 | writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2)); | 288 | writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2)); |
289 | mmiowb(); | 289 | mmiowb(); |
290 | msleep(20); | 290 | msleep(20); |
291 | } | 291 | } |
@@ -621,6 +621,14 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, | |||
621 | int err = -ENOMEM; | 621 | int err = -ENOMEM; |
622 | u16 *buf; | 622 | u16 *buf; |
623 | 623 | ||
624 | if (!ssb_is_sprom_available(bus)) { | ||
625 | ssb_printk(KERN_ERR PFX "No SPROM available!\n"); | ||
626 | return -ENODEV; | ||
627 | } | ||
628 | |||
629 | bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ? | ||
630 | SSB_SPROM_BASE1 : SSB_SPROM_BASE31; | ||
631 | |||
624 | buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); | 632 | buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); |
625 | if (!buf) | 633 | if (!buf) |
626 | goto out; | 634 | goto out; |
diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c index f2f920fef10d..007bc3a03486 100644 --- a/drivers/ssb/sprom.c +++ b/drivers/ssb/sprom.c | |||
@@ -176,3 +176,17 @@ const struct ssb_sprom *ssb_get_fallback_sprom(void) | |||
176 | { | 176 | { |
177 | return fallback_sprom; | 177 | return fallback_sprom; |
178 | } | 178 | } |
179 | |||
180 | /* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ | ||
181 | bool ssb_is_sprom_available(struct ssb_bus *bus) | ||
182 | { | ||
183 | /* status register only exists on chipcomon rev >= 11 and we need check | ||
184 | for >= 31 only */ | ||
185 | /* this routine differs from specs as we do not access SPROM directly | ||
186 | on PCMCIA */ | ||
187 | if (bus->bustype == SSB_BUSTYPE_PCI && | ||
188 | bus->chipco.dev->id.revision >= 31) | ||
189 | return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM; | ||
190 | |||
191 | return true; | ||
192 | } | ||