diff options
| author | David S. Miller <davem@davemloft.net> | 2010-05-05 18:09:05 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-05-05 18:09:05 -0400 |
| commit | 2861a185e3ac2ebe5958a2039b66062445bf4f7d (patch) | |
| tree | 535546ba778348477c95cb781677432a2bc831c9 /drivers | |
| parent | ec7d2f2cf3a1b76202986519ec4f8ec75b2de232 (diff) | |
| parent | 83163244f845c296a118ce85c653872dbff6abfe (diff) | |
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
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 | } | ||
