Update compat-wireless to 2009-03-18

Removing of include/net/ieee80211_radiotap.h is not needed, because it is only used by this compat-wireless.
There are changes in that file and compat-wireless needs the newest version.

Some more symbols are deactivated in the default config file, this will make building faster.
The rt2800pci patches are up to date now.

SVN-Revision: 14946
master
Hauke Mehrtens 16 years ago
parent 227399122b
commit c84390332f
  1. 5
      package/mac80211/Makefile
  2. 174
      package/mac80211/patches/007-remove_unused_stuff.patch
  3. 494
      package/mac80211/patches/201-ath5k_eeprom.patch
  4. 672
      package/mac80211/patches/202-ath5k_txpower_2413.patch
  5. 150
      package/mac80211/patches/300-rt2x00-Move-Move-pci_dev-specific-access-to-rt2x00p.patch
  6. 4
      package/mac80211/patches/301-rt2x00-Implement-support-for-802.11n.patch
  7. 321
      package/mac80211/patches/302-rt2x00-Implement-support-for-rt2800pci.patch
  8. 46
      package/mac80211/patches/303-rt2x00-Implement-support-for-rt2800usb.patch
  9. 35
      package/mac80211/patches/304-rt2x00-Detect-cypher-type-during-RX-rt2800pci.patch
  10. 25
      package/mac80211/patches/304-rt2x00-rt2x00-Move-Move-pci_dev-specific-access-to.patch
  11. 40
      package/mac80211/patches/305-rt2x00-Detect-cypher-type-during-RX-rt2800usb.patch
  12. 25
      package/mac80211/patches/305-rt2x00-rt2x00-Move-Move-pci_dev-specific-access-to.patch
  13. 36
      package/mac80211/patches/306-rt2x00-Fix-HW-crypto-offset-calculation-rt2800pci.patch
  14. 32
      package/mac80211/patches/306-rt2x00-Fix-module-loading-in-case-of-error-rt2800p.patch
  15. 80
      package/mac80211/patches/307-rt2x00-Add-PM-support-for-SoC-rt2800pci.patch
  16. 35
      package/mac80211/patches/307-rt2x00-Fix-HW-crypto-offset-calculation-rt2800usb.patch
  17. 535
      package/mac80211/patches/308-rt2x00-DMA-fixes-new-chipset-support-rt2800pci.patch
  18. 21
      package/mac80211/patches/308-rt2x00-Fix-fill_rxdone-rt2800pci.patch
  19. 136
      package/mac80211/patches/309-rt2x00-Fix-compile-errors-for-SoC.patch
  20. 4
      package/mac80211/patches/401-ath9k-dont-register-leds-on-ar9100.patch
  21. 8
      package/mac80211/patches/402-ath9k-enable-debug.patch
  22. 2
      package/mac80211/patches/403-ath9k-fix-invalid-mac-address-handling.patch

@ -17,12 +17,12 @@ ifneq ($(CONFIG_LINUX_2_6_21)$(CONFIG_LINUX_2_6_23)$(CONFIG_LINUX_2_6_24)$(CONFI
PKG_MD5SUM:=9563ceeed86bca0859ad5f010623277c
PATCH_DIR:=./patches-old
else
PKG_VERSION:=2009-03-13
PKG_VERSION:=2009-03-18
PKG_RELEASE:=1
PKG_SOURCE_URL:= \
http://www.orbit-lab.org/kernel/compat-wireless-2.6/2009/03 \
http://wireless.kernel.org/download/compat-wireless-2.6
PKG_MD5SUM:=bc924e8914a78d5a40ce4c17e5d28447
PKG_MD5SUM:=d46d230f62aed9bdec7a1f168feb221b
endif
PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
@ -428,7 +428,6 @@ define Build/Prepare
$(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2
rm -rf $(PKG_BUILD_DIR)/include/linux/ssb
rm -f $(PKG_BUILD_DIR)/include/net/ieee80211.h
rm $(PKG_BUILD_DIR)/include/net/ieee80211_radiotap.h
rm $(PKG_BUILD_DIR)/include/linux/eeprom_93cx6.h
endef

@ -1,10 +1,8 @@
Index: compat-wireless-2009-03-13/config.mk
===================================================================
--- compat-wireless-2009-03-13.orig/config.mk 2009-03-17 23:34:31.000000000 +0100
+++ compat-wireless-2009-03-13/config.mk 2009-03-17 23:40:08.000000000 +0100
@@ -91,10 +91,10 @@ CONFIG_MAC80211_MESH=y
--- a/config.mk
+++ b/config.mk
@@ -104,10 +104,10 @@ CONFIG_MAC80211_MESH=y
CONFIG_CFG80211=m
# CONFIG_CFG80211_REG_DEBUG is not set
# CONFIG_CFG80211_REG_DEBUG=y
-CONFIG_LIB80211=m
-CONFIG_LIB80211_CRYPT_WEP=m
@ -14,47 +12,80 @@ Index: compat-wireless-2009-03-13/config.mk
+# CONFIG_LIB80211_CRYPT_WEP=m
+# CONFIG_LIB80211_CRYPT_CCMP=m
+# CONFIG_LIB80211_CRYPT_TKIP=m
# CONFIG_LIB80211_DEBUG=y
CONFIG_NL80211=y
@@ -128,54 +128,54 @@ CONFIG_ATH9K=m
# CONFIG_ATH9K_DEBUG=y
@@ -129,18 +129,18 @@ CONFIG_IWL3945_LEDS=y
-CONFIG_IWLWIFI=m
-CONFIG_IWLWIFI_LEDS=y
+# CONFIG_IWLWIFI=m
+# CONFIG_IWLWIFI_LEDS=y
# CONFIG_IWLWIFI_RFKILL=y
-CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT=y
+# CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT=y
# CONFIG_IWLWIFI_DEBUG=y
# CONFIG_IWLWIFI_DEBUGFS=y
-CONFIG_IWLAGN=m
-CONFIG_IWL4965=y
-CONFIG_IWL5000=y
-CONFIG_IWL3945=m
-CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y
+# CONFIG_IWLAGN=m
+# CONFIG_IWL4965=y
+# CONFIG_IWL5000=y
+# CONFIG_IWL3945=m
+# CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y
CONFIG_B43=m
-CONFIG_B43=m
-CONFIG_B43_PCI_AUTOSELECT=y
-CONFIG_B43_PCICORE_AUTOSELECT=y
-CONFIG_B43_PCMCIA=y
-CONFIG_B43_PIO=y
-CONFIG_B43_LEDS=y
+# CONFIG_B43=m
+# CONFIG_B43_PCI_AUTOSELECT=y
+# CONFIG_B43_PCICORE_AUTOSELECT=y
+# CONFIG_B43_PCMCIA=y
+# CONFIG_B43_PIO=y
+# CONFIG_B43_LEDS=y
# CONFIG_B43_RFKILL=y
# CONFIG_B43_DEBUG is not set
# CONFIG_B43_DEBUG=y
# CONFIG_B43_FORCE_PIO=y
CONFIG_B43LEGACY=m
CONFIG_B43LEGACY_PCI_AUTOSELECT=y
CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y
-CONFIG_B43LEGACY=m
-CONFIG_B43LEGACY_PCI_AUTOSELECT=y
-CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y
-CONFIG_B43LEGACY_LEDS=y
+# CONFIG_B43LEGACY=m
+# CONFIG_B43LEGACY_PCI_AUTOSELECT=y
+# CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y
+# CONFIG_B43LEGACY_LEDS=y
# CONFIG_B43LEGACY_RFKILL=y
# CONFIG_B43LEGACY_DEBUG=y
CONFIG_B43LEGACY_DMA=y
@@ -150,17 +150,17 @@ CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
# CONFIG_B43LEGACY_PIO_MODE is not set
-CONFIG_B43LEGACY_DMA=y
-CONFIG_B43LEGACY_PIO=y
-CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
+# CONFIG_B43LEGACY_DMA=y
+# CONFIG_B43LEGACY_PIO=y
+# CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
# CONFIG_B43LEGACY_DMA_MODE=y
# CONFIG_B43LEGACY_PIO_MODE=y
# The Intel ipws
-CONFIG_LIBIPW=m
+# CONFIG_LIBIPW=m
# CONFIG_LIBIPW_DEBUG is not set
# CONFIG_LIBIPW_DEBUG=y
-CONFIG_IPW2100=m
-CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW2100=m
+# CONFIG_IPW2100_MONITOR=y
# CONFIG_IPW2100_DEBUG is not set
# CONFIG_IPW2100_DEBUG=y
-CONFIG_IPW2200=m
-CONFIG_IPW2200_MONITOR=y
-CONFIG_IPW2200_RADIOTAP=y
@ -65,52 +96,119 @@ Index: compat-wireless-2009-03-13/config.mk
+# CONFIG_IPW2200_RADIOTAP=y
+# CONFIG_IPW2200_PROMISCUOUS=y
+# CONFIG_IPW2200_QOS=y
# CONFIG_IPW2200_DEBUG is not set
# CONFIG_IPW2200_DEBUG=y
# The above enables use a second interface prefixed 'rtap'.
# Example usage:
@@ -176,13 +176,13 @@ CONFIG_IPW2200_QOS=y
@@ -190,27 +190,27 @@ CONFIG_IPW2200_QOS=y
#
# % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
CONFIG_SSB_BLOCKIO=y
-CONFIG_SSB_BLOCKIO=y
-CONFIG_SSB_PCIHOST_POSSIBLE=y
-CONFIG_SSB_PCIHOST=y
+# CONFIG_SSB_PCIHOST_POSSIBLE=y
+# CONFIG_SSB_PCIHOST=y
CONFIG_SSB_B43_PCI_BRIDGE=y
-CONFIG_SSB_B43_PCI_BRIDGE=y
-CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
-CONFIG_SSB_PCMCIAHOST=y
-CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
-CONFIG_SSB_DRIVER_PCICORE=y
+# CONFIG_SSB_BLOCKIO=y
+# CONFIG_SSB_PCIHOST_POSSIBLE=y
+# CONFIG_SSB_PCIHOST=y
+# CONFIG_SSB_B43_PCI_BRIDGE=y
+# CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
+# CONFIG_SSB_PCMCIAHOST=y
# CONFIG_SSB_DEBUG=y
-CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
-CONFIG_SSB_DRIVER_PCICORE=y
+# CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
+# CONFIG_SSB_DRIVER_PCICORE=y
CONFIG_P54_PCI=m
@@ -277,21 +277,21 @@ CONFIG_P54_COMMON=m
-CONFIG_B44=m
-CONFIG_B44_PCI_AUTOSELECT=y
-CONFIG_B44_PCICORE_AUTOSELECT=y
-CONFIG_B44_PCI=y
+# CONFIG_B44=m
+# CONFIG_B44_PCI_AUTOSELECT=y
+# CONFIG_B44_PCICORE_AUTOSELECT=y
+# CONFIG_B44_PCI=y
-CONFIG_RTL8180=m
+# CONFIG_RTL8180=m
-CONFIG_ADM8211=m
-CONFIG_PCMCIA_ATMEL=m
+# CONFIG_ADM8211=m
+# CONFIG_PCMCIA_ATMEL=m
CONFIG_RT2X00_LIB_PCI=m
CONFIG_RT2400PCI=m
@@ -226,16 +226,16 @@ CONFIG_RT61PCI=m
NEED_RT2X00_FIRMWARE=y
endif
-CONFIG_ATMEL=m
-CONFIG_PCI_ATMEL=m
+# CONFIG_ATMEL=m
+# CONFIG_PCI_ATMEL=m
-CONFIG_MWL8K=m
+# CONFIG_MWL8K=m
endif
## end of PCI
# This is required for some cards
-CONFIG_EEPROM_93CX6=m
+# CONFIG_EEPROM_93CX6=m
# USB Drivers
ifneq ($(CONFIG_USB),)
@@ -249,15 +249,15 @@ CONFIG_ZD1211RW=m
# is only wireless RNDIS chip known to date.
# Note: this depends on CONFIG_USB_NET_RNDIS_HOST and CONFIG_USB_NET_CDCETHER
# it also requires new RNDIS_HOST and CDC_ETHER modules which we add
-CONFIG_USB_NET_RNDIS_HOST=m
-CONFIG_USB_NET_RNDIS_WLAN=m
-CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_RNDIS_HOST=m
+# CONFIG_USB_NET_RNDIS_WLAN=m
+# CONFIG_USB_NET_CDCETHER=m
CONFIG_P54_USB=m
-CONFIG_RTL8187=m
+# CONFIG_RTL8187=m
-CONFIG_AT76C50X_USB=m
+# CONFIG_AT76C50X_USB=m
# RT2500USB does not require firmware
CONFIG_RT2500USB=m
@@ -294,20 +294,20 @@ CONFIG_P54_COMMON=m
# Sonics Silicon Backplane
CONFIG_SSB_POSSIBLE=y
CONFIG_SSB=m
-CONFIG_SSB_POSSIBLE=y
-CONFIG_SSB=m
-CONFIG_SSB_SPROM=y
+# CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB=m
+# CONFIG_SSB_SPROM=y
# CONFIG_SSB_DEBUG is not set
# CONFIG_SSB_DEBUG=y
ifneq ($(CONFIG_USB),)
ifneq ($(CONFIG_LIBERTAS_THINFIRM_USB),m)
CONFIG_LIBERTAS_USB=m
-CONFIG_LIBERTAS_USB=m
-NEED_LIBERTAS=y
+#NEED_LIBERTAS=y
+# CONFIG_LIBERTAS_USB=m
+# NEED_LIBERTAS=y
endif
endif
ifneq ($(CONFIG_PCMCIA),)
CONFIG_LIBERTAS_CS=m
-CONFIG_LIBERTAS_CS=m
-NEED_LIBERTAS=y
+#NEED_LIBERTAS=y
+# CONFIG_LIBERTAS_CS=m
+# NEED_LIBERTAS=y
endif
ifeq ($(NEED_LIBERTAS),y)
-CONFIG_LIBERTAS=m
+#CONFIG_LIBERTAS=m
# Libertas uses the old stack but not fully, it will soon
# be cleaned.
endif
CONFIG_LIBERTAS=m

@ -1,494 +0,0 @@
Clean up the eeprom parsing code and prepare the pdgain
data for 2413, which will be required for power calibration code.
Also clean up some ugly line wrapping to make the code easier on
the eyes.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
--- a/drivers/net/wireless/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath5k/eeprom.c
@@ -541,31 +541,30 @@ ath5k_eeprom_read_freq_list(struct ath5k
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
int o = *offset;
- int i = 0;
+ int i = 0 ;
u8 freq1, freq2;
int ret;
u16 val;
+ ee->ee_n_piers[mode] = 0;
while(i < max) {
AR5K_EEPROM_READ(o++, val);
- freq1 = (val >> 8) & 0xff;
- freq2 = val & 0xff;
+ freq1 = val & 0xff;
+ if (!freq1)
+ break;
- if (freq1) {
- pc[i++].freq = ath5k_eeprom_bin2freq(ee,
- freq1, mode);
- ee->ee_n_piers[mode]++;
- }
+ pc[i++].freq = ath5k_eeprom_bin2freq(ee,
+ freq1, mode);
+ ee->ee_n_piers[mode]++;
- if (freq2) {
- pc[i++].freq = ath5k_eeprom_bin2freq(ee,
- freq2, mode);
- ee->ee_n_piers[mode]++;
- }
-
- if (!freq1 || !freq2)
+ freq2 = (val >> 8) & 0xff;
+ if (!freq2)
break;
+
+ pc[i++].freq = ath5k_eeprom_bin2freq(ee,
+ freq2, mode);
+ ee->ee_n_piers[mode]++;
}
/* return new offset */
@@ -918,84 +917,46 @@ ath5k_cal_data_offset_2413(struct ath5k_
* curves on eeprom. The final curve (higher power) has an extra
* point for better accuracy like RF5112.
*/
+
static int
-ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
+ath5k_eeprom_parse_pcal_info_2413(struct ath5k_hw *ah, int mode, u32 offset,
+ struct ath5k_chan_pcal_info *chinfo)
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- struct ath5k_chan_pcal_info_rf2413 *chan_pcal_info;
- struct ath5k_chan_pcal_info *gen_chan_info;
- unsigned int i, c;
- u32 offset;
+ struct ath5k_chan_pcal_info_rf2413 *pcinfo;
+ unsigned int i;
int ret;
u16 val;
- u8 pd_gains = 0;
-
- if (ee->ee_x_gain[mode] & 0x1) pd_gains++;
- if ((ee->ee_x_gain[mode] >> 1) & 0x1) pd_gains++;
- if ((ee->ee_x_gain[mode] >> 2) & 0x1) pd_gains++;
- if ((ee->ee_x_gain[mode] >> 3) & 0x1) pd_gains++;
- ee->ee_pd_gains[mode] = pd_gains;
-
- offset = ath5k_cal_data_offset_2413(ee, mode);
- ee->ee_n_piers[mode] = 0;
- switch (mode) {
- case AR5K_EEPROM_MODE_11A:
- if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
- return 0;
-
- ath5k_eeprom_init_11a_pcal_freq(ah, offset);
- offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
- gen_chan_info = ee->ee_pwr_cal_a;
- break;
- case AR5K_EEPROM_MODE_11B:
- if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
- return 0;
+ u8 pd_gains;
- ath5k_eeprom_init_11bg_2413(ah, mode, offset);
- offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
- gen_chan_info = ee->ee_pwr_cal_b;
- break;
- case AR5K_EEPROM_MODE_11G:
- if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
- return 0;
-
- ath5k_eeprom_init_11bg_2413(ah, mode, offset);
- offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
- gen_chan_info = ee->ee_pwr_cal_g;
- break;
- default:
- return -EINVAL;
- }
+ pd_gains = ee->ee_pd_gains[mode];
if (pd_gains == 0)
return 0;
for (i = 0; i < ee->ee_n_piers[mode]; i++) {
- chan_pcal_info = &gen_chan_info[i].rf2413_info;
+ pcinfo = &chinfo[i].rf2413_info;
/*
* Read pwr_i, pddac_i and the first
* 2 pd points (pwr, pddac)
*/
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr_i[0] = val & 0x1f;
- chan_pcal_info->pddac_i[0] = (val >> 5) & 0x7f;
- chan_pcal_info->pwr[0][0] =
- (val >> 12) & 0xf;
+ pcinfo->pwr_i[0] = val & 0x1f;
+ pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
+ pcinfo->pwr[0][0] = (val >> 12) & 0xf;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac[0][0] = val & 0x3f;
- chan_pcal_info->pwr[0][1] = (val >> 6) & 0xf;
- chan_pcal_info->pddac[0][1] =
- (val >> 10) & 0x3f;
+ pcinfo->pddac[0][0] = val & 0x3f;
+ pcinfo->pwr[0][1] = (val >> 6) & 0xf;
+ pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr[0][2] = val & 0xf;
- chan_pcal_info->pddac[0][2] =
- (val >> 4) & 0x3f;
+ pcinfo->pwr[0][2] = val & 0xf;
+ pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
- chan_pcal_info->pwr[0][3] = 0;
- chan_pcal_info->pddac[0][3] = 0;
+ pcinfo->pwr[0][3] = 0;
+ pcinfo->pddac[0][3] = 0;
if (pd_gains > 1) {
/*
@@ -1003,44 +964,36 @@ ath5k_eeprom_read_pcal_info_2413(struct
* so it only has 2 pd points.
* Continue wih pd gain 1.
*/
- chan_pcal_info->pwr_i[1] = (val >> 10) & 0x1f;
+ pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
- chan_pcal_info->pddac_i[1] = (val >> 15) & 0x1;
+ pcinfo->pddac_i[1] = (val >> 15) & 0x1;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac_i[1] |= (val & 0x3F) << 1;
+ pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
- chan_pcal_info->pwr[1][0] = (val >> 6) & 0xf;
- chan_pcal_info->pddac[1][0] =
- (val >> 10) & 0x3f;
+ pcinfo->pwr[1][0] = (val >> 6) & 0xf;
+ pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr[1][1] = val & 0xf;
- chan_pcal_info->pddac[1][1] =
- (val >> 4) & 0x3f;
- chan_pcal_info->pwr[1][2] =
- (val >> 10) & 0xf;
+ pcinfo->pwr[1][1] = val & 0xf;
+ pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
+ pcinfo->pwr[1][2] = (val >> 10) & 0xf;
- chan_pcal_info->pddac[1][2] =
- (val >> 14) & 0x3;
+ pcinfo->pddac[1][2] = (val >> 14) & 0x3;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac[1][2] |=
- (val & 0xF) << 2;
+ pcinfo->pddac[1][2] |= (val & 0xF) << 2;
- chan_pcal_info->pwr[1][3] = 0;
- chan_pcal_info->pddac[1][3] = 0;
+ pcinfo->pwr[1][3] = 0;
+ pcinfo->pddac[1][3] = 0;
} else if (pd_gains == 1) {
/*
* Pd gain 0 is the last one so
* read the extra point.
*/
- chan_pcal_info->pwr[0][3] =
- (val >> 10) & 0xf;
+ pcinfo->pwr[0][3] = (val >> 10) & 0xf;
- chan_pcal_info->pddac[0][3] =
- (val >> 14) & 0x3;
+ pcinfo->pddac[0][3] = (val >> 14) & 0x3;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac[0][3] |=
- (val & 0xF) << 2;
+ pcinfo->pddac[0][3] |= (val & 0xF) << 2;
}
/*
@@ -1048,105 +1001,159 @@ ath5k_eeprom_read_pcal_info_2413(struct
* as above.
*/
if (pd_gains > 2) {
- chan_pcal_info->pwr_i[2] = (val >> 4) & 0x1f;
- chan_pcal_info->pddac_i[2] = (val >> 9) & 0x7f;
+ pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
+ pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr[2][0] =
- (val >> 0) & 0xf;
- chan_pcal_info->pddac[2][0] =
- (val >> 4) & 0x3f;
- chan_pcal_info->pwr[2][1] =
- (val >> 10) & 0xf;
-
- chan_pcal_info->pddac[2][1] =
- (val >> 14) & 0x3;
- AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac[2][1] |=
- (val & 0xF) << 2;
-
- chan_pcal_info->pwr[2][2] =
- (val >> 4) & 0xf;
- chan_pcal_info->pddac[2][2] =
- (val >> 8) & 0x3f;
+ pcinfo->pwr[2][0] = (val >> 0) & 0xf;
+ pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
+ pcinfo->pwr[2][1] = (val >> 10) & 0xf;
- chan_pcal_info->pwr[2][3] = 0;
- chan_pcal_info->pddac[2][3] = 0;
+ pcinfo->pddac[2][1] = (val >> 14) & 0x3;
+ AR5K_EEPROM_READ(offset++, val);
+ pcinfo->pddac[2][1] |= (val & 0xF) << 2;
+
+ pcinfo->pwr[2][2] = (val >> 4) & 0xf;
+ pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
+
+ pcinfo->pwr[2][3] = 0;
+ pcinfo->pddac[2][3] = 0;
} else if (pd_gains == 2) {
- chan_pcal_info->pwr[1][3] =
- (val >> 4) & 0xf;
- chan_pcal_info->pddac[1][3] =
- (val >> 8) & 0x3f;
+ pcinfo->pwr[1][3] = (val >> 4) & 0xf;
+ pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
}
if (pd_gains > 3) {
- chan_pcal_info->pwr_i[3] = (val >> 14) & 0x3;
+ pcinfo->pwr_i[3] = (val >> 14) & 0x3;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
+ pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
- chan_pcal_info->pddac_i[3] = (val >> 3) & 0x7f;
- chan_pcal_info->pwr[3][0] =
- (val >> 10) & 0xf;
- chan_pcal_info->pddac[3][0] =
- (val >> 14) & 0x3;
+ pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
+ pcinfo->pwr[3][0] = (val >> 10) & 0xf;
+ pcinfo->pddac[3][0] = (val >> 14) & 0x3;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac[3][0] |=
- (val & 0xF) << 2;
- chan_pcal_info->pwr[3][1] =
- (val >> 4) & 0xf;
- chan_pcal_info->pddac[3][1] =
- (val >> 8) & 0x3f;
+ pcinfo->pddac[3][0] |= (val & 0xF) << 2;
+ pcinfo->pwr[3][1] = (val >> 4) & 0xf;
+ pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
- chan_pcal_info->pwr[3][2] =
- (val >> 14) & 0x3;
+ pcinfo->pwr[3][2] = (val >> 14) & 0x3;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr[3][2] |=
- ((val >> 0) & 0x3) << 2;
+ pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
- chan_pcal_info->pddac[3][2] =
- (val >> 2) & 0x3f;
- chan_pcal_info->pwr[3][3] =
- (val >> 8) & 0xf;
+ pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
+ pcinfo->pwr[3][3] = (val >> 8) & 0xf;
- chan_pcal_info->pddac[3][3] =
- (val >> 12) & 0xF;
+ pcinfo->pddac[3][3] = (val >> 12) & 0xF;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac[3][3] |=
- ((val >> 0) & 0x3) << 4;
+ pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
} else if (pd_gains == 3) {
- chan_pcal_info->pwr[2][3] =
- (val >> 14) & 0x3;
+ pcinfo->pwr[2][3] = (val >> 14) & 0x3;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr[2][3] |=
- ((val >> 0) & 0x3) << 2;
+ pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
- chan_pcal_info->pddac[2][3] =
- (val >> 2) & 0x3f;
+ pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
}
+ }
+ return 0;
+}
+
+static int
+ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
+ struct ath5k_chan_pcal_info *chinfo,
+ unsigned int *xgains)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ struct ath5k_chan_pcal_info_rf2413 *pcinfo;
+ unsigned int i, j, k;
- for (c = 0; c < pd_gains; c++) {
- /* Recreate pwr table for this channel using pwr steps */
- chan_pcal_info->pwr[c][0] += chan_pcal_info->pwr_i[c] * 2;
- chan_pcal_info->pwr[c][1] += chan_pcal_info->pwr[c][0];
- chan_pcal_info->pwr[c][2] += chan_pcal_info->pwr[c][1];
- chan_pcal_info->pwr[c][3] += chan_pcal_info->pwr[c][2];
- if (chan_pcal_info->pwr[c][3] == chan_pcal_info->pwr[c][2])
- chan_pcal_info->pwr[c][3] = 0;
-
- /* Recreate pddac table for this channel using pddac steps */
- chan_pcal_info->pddac[c][0] += chan_pcal_info->pddac_i[c];
- chan_pcal_info->pddac[c][1] += chan_pcal_info->pddac[c][0];
- chan_pcal_info->pddac[c][2] += chan_pcal_info->pddac[c][1];
- chan_pcal_info->pddac[c][3] += chan_pcal_info->pddac[c][2];
- if (chan_pcal_info->pddac[c][3] == chan_pcal_info->pddac[c][2])
- chan_pcal_info->pddac[c][3] = 0;
+ /* prepare the raw values */
+ for (i = 0; i < ee->ee_n_piers[mode]; i++) {
+ pcinfo = &chinfo[i].rf2413_info;
+ for (j = 0; j < ee->ee_pd_gains[mode]; j++) {
+ unsigned int idx = xgains[j];
+ struct ath5k_pdgain_info *pd = &pcinfo->pdgains[idx];
+
+ /* one more point for the highest power (lowest gain) */
+ if (j == ee->ee_pd_gains[mode] - 1) {
+ pd->n_vpd = AR5K_EEPROM_N_PD_POINTS;
+ } else {
+ pd->n_vpd = AR5K_EEPROM_N_PD_POINTS - 1;
+ }
+
+ pd->vpd[0] = pcinfo->pddac_i[j];
+ pd->pwr_t4[0] = 4 * pcinfo->pwr_i[j];
+ for (k = 1; k < pd->n_vpd; k++) {
+ pd->pwr_t4[k] = pd->pwr_t4[k - 1] + 2 * pcinfo->pwr[j][k - 1];
+ pd->vpd[k] = pd->vpd[k - 1] + pcinfo->pddac[j][k - 1];
+ }
}
}
return 0;
}
+static int
+ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ struct ath5k_chan_pcal_info *chinfo;
+ unsigned int xgains[AR5K_EEPROM_N_PD_GAINS];
+ u32 offset;
+ u8 pd_gains = 0;
+ int i, ret;
+
+ memset(xgains, 0, sizeof(xgains));
+ for (i = 0; i < AR5K_EEPROM_N_PD_GAINS; i++) {
+ int idx = AR5K_EEPROM_N_PD_GAINS - i - 1;
+
+ if ((ee->ee_x_gain[mode] >> idx) & 0x1)
+ xgains[pd_gains++] = idx;
+ }
+ ee->ee_pd_gains[mode] = pd_gains;
+
+ offset = ath5k_cal_data_offset_2413(ee, mode);
+ switch (mode) {
+ case AR5K_EEPROM_MODE_11A:
+ if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
+ return 0;
+
+ ath5k_eeprom_init_11a_pcal_freq(ah, offset);
+ offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
+ chinfo = ee->ee_pwr_cal_a;
+ break;
+ case AR5K_EEPROM_MODE_11B:
+ if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
+ return 0;
+
+ ath5k_eeprom_init_11bg_2413(ah, mode, offset);
+ offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
+ chinfo = ee->ee_pwr_cal_b;
+ break;
+ case AR5K_EEPROM_MODE_11G:
+ if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
+ return 0;
+
+ ath5k_eeprom_init_11bg_2413(ah, mode, offset);
+ offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
+ chinfo = ee->ee_pwr_cal_g;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+
+ ret = ath5k_eeprom_parse_pcal_info_2413(ah, mode, offset, chinfo);
+ if (ret)
+ return ret;
+
+ ret = ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo, xgains);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
/*
* Read per rate target power (this is the maximum tx power
* supported by the card). This info is used when setting
@@ -1264,6 +1271,7 @@ ath5k_eeprom_read_pcal_info(struct ath5k
else
read_pcal = ath5k_eeprom_read_pcal_info_5111;
+
for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
err = read_pcal(ah, mode);
if (err)
--- a/drivers/net/wireless/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath5k/eeprom.h
@@ -266,15 +266,27 @@ struct ath5k_chan_pcal_info_rf5112 {
u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
};
+
+struct ath5k_pdgain_info {
+ u16 n_vpd;
+ u16 vpd[AR5K_EEPROM_N_PD_POINTS];
+ s16 pwr_t4[AR5K_EEPROM_N_PD_POINTS];
+};
+
struct ath5k_chan_pcal_info_rf2413 {
+ /* --- EEPROM VALUES --- */
/* Starting pwr/pddac values */
- s8 pwr_i[AR5K_EEPROM_N_PD_GAINS];
- u8 pddac_i[AR5K_EEPROM_N_PD_GAINS];
+ s8 pwr_i[AR5K_EEPROM_N_PD_GAINS];
+ u8 pddac_i[AR5K_EEPROM_N_PD_GAINS];
/* (pwr,pddac) points */
- s8 pwr[AR5K_EEPROM_N_PD_GAINS]
- [AR5K_EEPROM_N_PD_POINTS];
- u8 pddac[AR5K_EEPROM_N_PD_GAINS]
- [AR5K_EEPROM_N_PD_POINTS];
+ s8 pwr[AR5K_EEPROM_N_PD_GAINS]
+ [AR5K_EEPROM_N_PD_POINTS];
+ u8 pddac[AR5K_EEPROM_N_PD_GAINS]
+ [AR5K_EEPROM_N_PD_POINTS];
+
+ /* --- RAW VALUES --- */
+ struct ath5k_pdgain_info pdgains
+ [AR5K_EEPROM_N_PD_GAINS];
};
struct ath5k_chan_pcal_info {

@ -1,672 +0,0 @@
Implement the power curve interpolation, which is required for
proper tx on 2413 and newer RF designs.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -4,6 +4,7 @@
* Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
* Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
* Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -1438,31 +1439,449 @@ unsigned int ath5k_hw_get_def_antenna(st
*/
/*
- * Initialize the tx power table (not fully implemented)
+ * find the lower and upper index of the values in the table surrounding the target value
*/
-static void ath5k_txpower_table(struct ath5k_hw *ah,
- struct ieee80211_channel *channel, s16 max_power)
+static void
+ath5k_get_table_index(const u16 *tbl, unsigned int tbl_sz, u16 target,
+ unsigned int idx[2])
{
- unsigned int i, min, max, n;
- u16 txpower, *rates;
+ const u16 *ti;
- rates = ah->ah_txpower.txp_rates;
+ if (target < tbl[0]) {
+ idx[0] = idx[1] = 0;
+ return;
+ }
+
+ if (target > tbl[tbl_sz - 1]) {
+ idx[0] = idx[1] = tbl_sz - 1;
+ return;
+ }
+
+ /* look for the surrounding values */
+ for (ti = tbl; ti < &tbl[tbl_sz - 1]; ti++) {
+
+ /* if the value is equal to the target, set lo = hi = index */
+ if (*ti == target) {
+ idx[0] = idx[1] = ti - tbl;
+ return;
+ }
+
+ /* if the target is between the current value and the next one,
+ * set lo = cur, hi = lo + 1 */
+ if (target < ti[1]) {
+ idx[0] = ti - tbl;
+ idx[1] = idx[0] + 1;
+ return;
+ }
+ }
+}
+
+/* find the lower and upper frequency info */
+static void
+ath5k_get_freq_tables(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+ struct ath5k_chan_pcal_info **pcinfo_l,
+ struct ath5k_chan_pcal_info **pcinfo_r,
+ struct ath5k_rate_pcal_info *rates)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ struct ath5k_chan_pcal_info *pcinfo;
+ unsigned int idx_l, idx_r;
+ int mode, max, i;
+ unsigned int target = channel->center_freq;
+ struct ath5k_rate_pcal_info *rpinfo;
+
+ if (!(channel->hw_value & CHANNEL_OFDM)) {
+ pcinfo = ee->ee_pwr_cal_b;
+ rpinfo = ee->ee_rate_tpwr_b;
+ mode = AR5K_EEPROM_MODE_11B;
+ } else if (channel->hw_value & CHANNEL_2GHZ) {
+ pcinfo = ee->ee_pwr_cal_g;
+ rpinfo = ee->ee_rate_tpwr_g;
+ mode = AR5K_EEPROM_MODE_11G;
+ } else {
+ pcinfo = ee->ee_pwr_cal_a;
+ rpinfo = ee->ee_rate_tpwr_a;
+ mode = AR5K_EEPROM_MODE_11A;
+ }
+ max = ee->ee_n_piers[mode] - 1;
+
+ if (target < pcinfo[0].freq) {
+ idx_l = idx_r = 0;
+ goto done;
+ }
+
+ if (target > pcinfo[max].freq) {
+ idx_l = idx_r = max;
+ goto done;
+ }
+
+ /* look for the surrounding values */
+ for (i = 0; i <= max; i++) {
+
+ /* if the value is equal to the target, set lo = hi = index */
+ if (pcinfo[i].freq == target) {
+ idx_l = idx_r = i;
+ goto done;
+ }
+
+ /* if the target is between the current value and the next one,
+ * set lo = cur, hi = lo + 1 */
+ if (target < pcinfo[i].freq) {
+ idx_l = i;
+ idx_r = idx_l + 1;
+ goto done;
+ }
+ }
+
+done:
+ *pcinfo_l = &pcinfo[idx_l];
+ *pcinfo_r = &pcinfo[idx_r];
+
+ if (!rates)
+ return;
+
+ /* rate info minimum values */
+ rates->freq = channel->center_freq;
+ rates->target_power_6to24 =
+ min(rpinfo[idx_l].target_power_6to24,
+ rpinfo[idx_r].target_power_6to24);
+ rates->target_power_36 =
+ min(rpinfo[idx_l].target_power_36,
+ rpinfo[idx_r].target_power_36);
+ rates->target_power_48 =
+ min(rpinfo[idx_l].target_power_48,
+ rpinfo[idx_r].target_power_48);
+ rates->target_power_54 =
+ min(rpinfo[idx_l].target_power_54,
+ rpinfo[idx_r].target_power_54);
+}
+
+
+/* Fill the VPD table for all indices between pmin and pmax */
+static void
+ath5k_fill_vpdtable(s16 pmin, s16 pmax, const s16 *pwr,
+ const u16 *vpd, unsigned int intercepts,
+ u16 vpdtable[AR5K_EEPROM_POWER_TABLE_SIZE])
+{
+ unsigned int idx[2] = { 0, 0 };
+ s16 cur_pwr = 2 * pmin;
+ int i;
+
+ if (intercepts < 2)
+ return;
+
+ for(i = 0; i <= (pmax - pmin); i++) {
+ ath5k_get_table_index(pwr, intercepts, cur_pwr, idx);
+
+ if (!idx[1])
+ idx[1] = 1;
+
+ if (idx[0] == intercepts - 1)
+ idx[0] = intercepts - 2;
+
+ if (pwr[idx[0]] == pwr[idx[1]])
+ vpdtable[i] = vpd[idx[0]];
+ else
+ vpdtable[i] = (((cur_pwr - pwr[idx[0]]) * vpd[idx[1]] +
+ (pwr[idx[1]] - cur_pwr) * vpd[idx[0]]) /
+ (pwr[idx[1]] - pwr[idx[0]]));
+
+ cur_pwr += 2;
+ }
+}
+
+static inline s16
+ath5k_interpolate_signed(u16 ref, u16 ref_l, u16 ref_r, s16 val_l, s16 val_r)
+{
+ if (ref_l == ref_r)
+ return val_l;
+
+ return ((ref - ref_l)*val_r + (ref_r - ref)*val_l) / (ref_r - ref_l);
+}
+
+static inline s16
+ath5k_get_min_power_2413(struct ath5k_chan_pcal_info *pcinfo)
+{
+ struct ath5k_pdgain_info *pd;
+ int i;
+
+ /* backwards - highest pdgain == lowest power */
+ for (i = AR5K_EEPROM_N_PD_GAINS - 1; i >= 0; i--) {
+ pd = &pcinfo->rf2413_info.pdgains[i];
+ if (!pd->n_vpd)
+ continue;
+
+ return pd->pwr_t4[0];
+ }
+ return 0;
+}
+
+static inline s16
+ath5k_get_max_power_2413(struct ath5k_chan_pcal_info *pcinfo)
+{
+ struct ath5k_pdgain_info *pd;
+ int i;
+
+ /* forwards: lowest pdgain == highest power */
+ for (i = 0; i < AR5K_EEPROM_N_PD_GAINS; i++) {
+ pd = &pcinfo->rf2413_info.pdgains[i];
+ if (!pd->n_vpd)
+ continue;
+
+ return pd->pwr_t4[pd->n_vpd];
+ }
+ return 0;
+}
+
+
+
+static int
+ath5k_txpower_table_2413(struct ath5k_hw *ah, struct ieee80211_channel *ch,
+ struct ath5k_chan_pcal_info *pcinfo_l,
+ struct ath5k_chan_pcal_info *pcinfo_r)
+{
+ struct ath5k_pdgain_info *pd_l, *pd_r;
+ u16 gain_boundaries[4];
+ u16 *xpd = ah->ah_txpower.txp_xpd;
+ int n_xpd = 0;
+ s16 pmin_t2[AR5K_EEPROM_N_PD_GAINS];
+ s16 pmax_t2[AR5K_EEPROM_N_PD_GAINS];
+ u16 *pdadc_out = ah->ah_txpower.txp_pcdac;
+ unsigned int gain_overlap;
+ unsigned int vpd_size, target_idx, max_idx;
+ unsigned int n_pdadc = 0;
+ u16 vpd_step;
+ u16 *pcdacL;
+ u16 *pcdacR;
+ int i, j, s;
+ u32 reg;
+ s16 ch_pmin, ch_pmax;
+
+ gain_overlap = ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG5) &
+ AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP;
+
+ /* loop backwards over pdgains (highest pdgain == lowest power) */
+ for (i = AR5K_EEPROM_N_PD_GAINS - 1; i >= 0; i--) {
+ pd_l = &pcinfo_l->rf2413_info.pdgains[i];
+ pd_r = &pcinfo_r->rf2413_info.pdgains[i];
+ pcdacL = ah->ah_txpower.txp_rfdata.rf2413.pcdacL[n_xpd];
+ pcdacR = ah->ah_txpower.txp_rfdata.rf2413.pcdacR[n_xpd];
+
+ if (!pd_l->n_vpd)
+ continue;
+
+ xpd[n_xpd] = i;
+
+ pmin_t2[n_xpd] = min(pd_l->pwr_t4[0], pd_r->pwr_t4[0]) / 2;
+ pmax_t2[n_xpd] = min(pd_l->pwr_t4[pd_l->n_vpd - 1],
+ pd_r->pwr_t4[pd_r->n_vpd - 1]) / 2;
+
+ if ((u16) (pmax_t2[n_xpd] - pmin_t2[n_xpd]) > 64)
+ continue;
+
+ /* fill vpd tables for left and right frequency info */
+ ath5k_fill_vpdtable(pmin_t2[n_xpd], pmax_t2[n_xpd],
+ pd_l->pwr_t4, pd_l->vpd, pd_l->n_vpd, pcdacL);
+
+ /* check if interpolation is necessary */
+ if (pcinfo_l == pcinfo_r)
+ continue;
+
+ ath5k_fill_vpdtable(pmin_t2[n_xpd], pmax_t2[n_xpd],
+ pd_r->pwr_t4, pd_r->vpd, pd_r->n_vpd, pcdacR);
+
+ /* interpolate pcdac values,
+ * reuse pcdacL table for interpolation output */
+ for (j = 0; j < (u16) (pmax_t2[n_xpd] - pmin_t2[n_xpd]); j++) {
+ pcdacL[j] = ath5k_interpolate_signed(ch->center_freq,
+ pcinfo_l->freq, pcinfo_r->freq,
+ (s16) pcdacL[j], (s16) pcdacR[j]);
+ }
+ n_xpd++;
+ }
+
+ if (!n_xpd)
+ return 0;
+
+ /* create final table */
+ for (i = 0, n_pdadc = 0; i < n_xpd; i++) {
+ pcdacL = ah->ah_txpower.txp_rfdata.rf2413.pcdacL[i];
+
+ if (i == n_xpd - 1) {
+ /* 2 db boundary stretch */
+ gain_boundaries[i] = pmax_t2[i] + 4;
+ } else {
+ gain_boundaries[i] = (pmax_t2[i] + pmin_t2[i + 1]) / 2;
+ }
+
+ if (gain_boundaries[i] > AR5K_TUNE_MAX_TXPOWER)
+ gain_boundaries[i] = AR5K_TUNE_MAX_TXPOWER;
+
+ /* find starting index */
+ if (i == 0)
+ s = 0;
+ else
+ s = (gain_boundaries[i - 1] - pmin_t2[i]) -
+ gain_overlap;
+
+ if (pcdacL[1] > pcdacL[0])
+ vpd_step = pcdacL[1] - pcdacL[0];
+ else
+ vpd_step = 1;
+
+ /* if s is below 0, we need to extrapolate below this pdgain */
+ while ((s < 0) && (n_pdadc < 128)) {
+ s16 tmp = pcdacL[0] + s * vpd_step;
+ pdadc_out[n_pdadc++] = (u16) ((tmp < 0) ? 0 : tmp);
+ s++;
+ }
+
+ vpd_size = pmax_t2[i] - pmin_t2[i];
+ target_idx = gain_boundaries[i] + gain_overlap - pmin_t2[i];
+ max_idx = (target_idx < vpd_size) ? target_idx : vpd_size;
+
+ while ((s < (s16) max_idx) && (n_pdadc < 128))
+ pdadc_out[n_pdadc++] = pcdacL[s++];
+
+ /* need to extrapolate above this pdgain? */
+ if (target_idx <= max_idx)
+ continue;
- txpower = AR5K_TUNE_DEFAULT_TXPOWER * 2;
- if (max_power > txpower)
- txpower = max_power > AR5K_TUNE_MAX_TXPOWER ?
- AR5K_TUNE_MAX_TXPOWER : max_power;
+ if (pcdacL[vpd_size - 1] > pcdacL[vpd_size - 2])
+ vpd_step = pcdacL[vpd_size - 1] - pcdacL[vpd_size - 2];
+ else
+ vpd_step = 1;
- for (i = 0; i < AR5K_MAX_RATES; i++)
- rates[i] = txpower;
+ while ((s < (s16) target_idx) && (n_pdadc < 128)) {
+ int tmp = pcdacL[vpd_size - 1] +
+ (s - max_idx) * vpd_step;
+ pdadc_out[n_pdadc++] = (tmp > 127) ? 127 : tmp;
+ s++;
+ }
+ }
- /* XXX setup target powers by rate */
+ while (i < AR5K_EEPROM_N_PD_GAINS) {
+ gain_boundaries[i] = gain_boundaries[i - 1];
+ i++;
+ }
+
+ while (n_pdadc < 128) {
+ pdadc_out[n_pdadc] = pdadc_out[n_pdadc - 1];
+ n_pdadc++;
+ }
+
+ /* select the right xpdgain curves */
+ reg = ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG1);
+ reg &= ~(AR5K_PHY_TPC_RG1_PDGAIN_1 |
+ AR5K_PHY_TPC_RG1_PDGAIN_2 |
+ AR5K_PHY_TPC_RG1_PDGAIN_3 |
+ AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
+ reg |= AR5K_REG_SM(n_xpd, AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
+ switch(n_xpd) {
+ case 3:
+ reg |= AR5K_REG_SM(xpd[2], AR5K_PHY_TPC_RG1_PDGAIN_3);
+ /* fall through */
+ case 2:
+ reg |= AR5K_REG_SM(xpd[1], AR5K_PHY_TPC_RG1_PDGAIN_2);
+ /* fall through */
+ case 1:
+ reg |= AR5K_REG_SM(xpd[0], AR5K_PHY_TPC_RG1_PDGAIN_1);
+ break;
+ }
+ ath5k_hw_reg_write(ah, reg, AR5K_PHY_TPC_RG1);
+ /*
+ * Write TX power values
+ */
+ reg = AR5K_PHY_PDADC_TXPOWER_BASE;
+ for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
+ ath5k_hw_reg_write(ah,
+ ((pdadc_out[4*i + 0] & 0xff) << 0) |
+ ((pdadc_out[4*i + 1] & 0xff) << 8) |
+ ((pdadc_out[4*i + 2] & 0xff) << 16) |
+ ((pdadc_out[4*i + 3] & 0xff) << 24), reg);
+ reg += 4;
+ }
+
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_SM(gain_overlap,
+ AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP) |
+ AR5K_REG_SM(gain_boundaries[0],
+ AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1) |
+ AR5K_REG_SM(gain_boundaries[1],
+ AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2) |
+ AR5K_REG_SM(gain_boundaries[2],
+ AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3) |
+ AR5K_REG_SM(gain_boundaries[3],
+ AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4),
+ AR5K_PHY_TPC_RG5);
+
+ ah->ah_txpower.txp_offset = pmin_t2[0];
+
+ /* look up power boundaries for this channel */
+ ch_pmin = ath5k_get_min_power_2413(pcinfo_l);
+ ch_pmax = ath5k_get_max_power_2413(pcinfo_l);
+
+ if (pcinfo_l != pcinfo_r) {
+ s16 pwr_r;
+
+ pwr_r = ath5k_get_min_power_2413(pcinfo_r);
+ ch_pmin = ath5k_interpolate_signed(ch->center_freq,
+ pcinfo_l->freq, pcinfo_r->freq,
+ ch_pmin, pwr_r);
+
+ pwr_r = ath5k_get_max_power_2413(pcinfo_r);
+ ch_pmax = ath5k_interpolate_signed(ch->center_freq,
+ pcinfo_l->freq, pcinfo_r->freq,
+ ch_pmax, pwr_r);
+ }
+ ah->ah_txpower.txp_min = ch_pmin;
+ ah->ah_txpower.txp_max = ch_pmax;
+
+ return 0;
+}
+
+static void
+ath5k_setup_rate_table(struct ath5k_hw *ah, u16 max_pwr,
+ struct ath5k_rate_pcal_info *rate_info)
+{
+ unsigned int i;
+ u16 *rates;
+
+ max_pwr *= 2;
+ max_pwr = min(max_pwr, (u16) ah->ah_txpower.txp_max);
+
+ /* apply rate limits */
+ rates = ah->ah_txpower.txp_rates;
+ for (i = 0; i < 5; i++) {
+ rates[i] = min(max_pwr, rate_info->target_power_6to24);
+ }
+ rates[5] = min(rates[0], rate_info->target_power_36);
+ rates[6] = min(rates[0], rate_info->target_power_48);
+ rates[7] = min(rates[0], rate_info->target_power_54);
+ rates[8] = min(rates[0], rate_info->target_power_6to24);
+ rates[9] = min(rates[0], rate_info->target_power_36);
+ rates[10] = min(rates[0], rate_info->target_power_36);
+ rates[11] = min(rates[0], rate_info->target_power_48);
+ rates[12] = min(rates[0], rate_info->target_power_48);
+ rates[13] = min(rates[0], rate_info->target_power_54);
+ rates[14] = min(rates[0], rate_info->target_power_54);
+
+ ah->ah_txpower.txp_tpc = max_pwr;
ah->ah_txpower.txp_min = rates[7];
- ah->ah_txpower.txp_max = rates[0];
- ah->ah_txpower.txp_ofdm = rates[0];
+ ah->ah_txpower.txp_max = min(ah->ah_txpower.txp_max,
+ (s16) rate_info->target_power_36);
+ ah->ah_txpower.txp_ofdm = ah->ah_txpower.txp_max;
+}
+
+static int
+ath5k_txpower_table(struct ath5k_hw *ah, struct ieee80211_channel *ch,
+ struct ath5k_chan_pcal_info *pcinfo_l,
+ struct ath5k_chan_pcal_info *pcinfo_r,
+ u16 max_pwr)
+{
+ unsigned int i, min, max, n;
- /* Calculate the power table */
n = ARRAY_SIZE(ah->ah_txpower.txp_pcdac);
min = AR5K_EEPROM_PCDAC_START;
max = AR5K_EEPROM_PCDAC_STOP;
@@ -1473,51 +1892,64 @@ static void ath5k_txpower_table(struct a
#else
min;
#endif
+
+ /*
+ * Write TX power values
+ */
+ for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
+ ath5k_hw_reg_write(ah,
+ ((((ah->ah_txpower.txp_pcdac[(i << 1) + 1] << 8) |
+ 0xff) & 0xffff) << 16) |
+ (((ah->ah_txpower.txp_pcdac[(i << 1) ] << 8) |
+ 0xff) & 0xffff),
+ AR5K_PHY_PCDAC_TXPOWER(i));
+ }
+ return 0;
}
+
/*
* Set transmition power
*/
-int /*O.K. - txpower_table is unimplemented so this doesn't work*/
+int
ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
unsigned int txpower)
{
+ struct ath5k_chan_pcal_info *pcinfo_l, *pcinfo_r;
+ struct ath5k_rate_pcal_info rate_info;
bool tpc = ah->ah_txpower.txp_tpc;
- unsigned int i;
ATH5K_TRACE(ah->ah_sc);
if (txpower > AR5K_TUNE_MAX_TXPOWER) {
ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
return -EINVAL;
}
-
- /*
- * RF2413 for some reason can't
- * transmit anything if we call
- * this funtion, so we skip it
- * until we fix txpower.
- *
- * XXX: Assume same for RF2425
- * to be safe.
- */
- if ((ah->ah_radio == AR5K_RF2413) || (ah->ah_radio == AR5K_RF2425))
- return 0;
+ if (txpower == 0)
+ txpower = AR5K_TUNE_MAX_TXPOWER;
/* Reset TX power values */
memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
ah->ah_txpower.txp_tpc = tpc;
+ ah->ah_txpower.txp_min = 0;
+ ah->ah_txpower.txp_max = AR5K_TUNE_MAX_TXPOWER;
- /* Initialize TX power table */
- ath5k_txpower_table(ah, channel, txpower);
+ /* find matching frequency info */
+ ath5k_get_freq_tables(ah, channel, &pcinfo_l, &pcinfo_r, &rate_info);
+ ath5k_setup_rate_table(ah, txpower, &rate_info);
- /*
- * Write TX power values
- */
- for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
- ath5k_hw_reg_write(ah,
- ((((ah->ah_txpower.txp_pcdac[(i << 1) + 1] << 8) | 0xff) & 0xffff) << 16) |
- (((ah->ah_txpower.txp_pcdac[(i << 1) ] << 8) | 0xff) & 0xffff),
- AR5K_PHY_PCDAC_TXPOWER(i));
+ /* Initialize TX power table */
+ switch(ah->ah_radio) {
+ case AR5K_RF2413:
+ case AR5K_RF5413:
+ ath5k_txpower_table_2413(ah, channel, pcinfo_l, pcinfo_r);
+ break;
+ case AR5K_RF2425:
+ /* unimplemented */
+ return 0;
+ default:
+ /* Default power table */
+ ath5k_txpower_table(ah, channel, pcinfo_l, pcinfo_r, txpower);
+ break;
}
ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) |
@@ -1536,12 +1968,19 @@ ath5k_hw_txpower(struct ath5k_hw *ah, st
AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4);
- if (ah->ah_txpower.txp_tpc)
+ if (ah->ah_txpower.txp_tpc) {
ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
- else
+
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_ACK) |
+ AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CTS) |
+ AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP),
+ AR5K_TPC);
+ } else {
ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX |
AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
+ }
return 0;
}
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -204,7 +204,7 @@
#define AR5K_TUNE_CWMAX_11B 1023
#define AR5K_TUNE_CWMAX_XR 7
#define AR5K_TUNE_NOISE_FLOOR -72
-#define AR5K_TUNE_MAX_TXPOWER 60
+#define AR5K_TUNE_MAX_TXPOWER 63
#define AR5K_TUNE_DEFAULT_TXPOWER 30
#define AR5K_TUNE_TPC_TXPOWER true
#define AR5K_TUNE_ANT_DIVERSITY true
@@ -1085,11 +1085,23 @@ struct ath5k_hw {
struct ath5k_gain ah_gain;
u8 ah_offset[AR5K_MAX_RF_BANKS];
+
struct {
- u16 txp_pcdac[AR5K_EEPROM_POWER_TABLE_SIZE];
+ union {
+ struct {
+ /* Temporary PCDAC tables for interpolation */
+ u16 pcdacL[AR5K_EEPROM_N_PD_GAINS]
+ [AR5K_EEPROM_POWER_TABLE_SIZE];
+ u16 pcdacR[AR5K_EEPROM_N_PD_GAINS]
+ [AR5K_EEPROM_POWER_TABLE_SIZE];
+ } rf2413;
+ } txp_rfdata;
+ u16 txp_xpd[AR5K_EEPROM_N_XPD_PER_CHANNEL];
+ u16 txp_pcdac[AR5K_EEPROM_POWER_TABLE_SIZE * 2];
u16 txp_rates[AR5K_MAX_RATES];
s16 txp_min;
s16 txp_max;
+ s16 txp_offset;
bool txp_tpc;
s16 txp_ofdm;
} ah_txpower;
--- a/drivers/net/wireless/ath5k/reg.h
+++ b/drivers/net/wireless/ath5k/reg.h
@@ -1552,6 +1552,15 @@
/*===5212 Specific PCU registers===*/
+#define AR5K_TPC 0x80e8
+#define AR5K_TPC_ACK 0x0000003f /* ack frames */
+#define AR5K_TPC_ACK_S 0
+#define AR5K_TPC_CTS 0x00003f00 /* cts frames */
+#define AR5K_TPC_CTS_S 8
+#define AR5K_TPC_CHIRP 0x003f0000 /* chirp frames */
+#define AR5K_TPC_CHIRP_S 16
+#define AR5K_TPC_DOPPLER 0x0f000000 /* doppler chirp span */
+#define AR5K_TPC_DOPPLER_S 24
/*
* XR (eXtended Range) mode register
@@ -2550,6 +2559,12 @@
#define AR5K_PHY_TPC_RG1 0xa258
#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN 0x0000c000
#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S 14
+#define AR5K_PHY_TPC_RG1_PDGAIN_1 0x00030000
+#define AR5K_PHY_TPC_RG1_PDGAIN_1_S 16
+#define AR5K_PHY_TPC_RG1_PDGAIN_2 0x000c0000
+#define AR5K_PHY_TPC_RG1_PDGAIN_2_S 18
+#define AR5K_PHY_TPC_RG1_PDGAIN_3 0x00300000
+#define AR5K_PHY_TPC_RG1_PDGAIN_3_S 20
#define AR5K_PHY_TPC_RG5 0xa26C
#define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP 0x0000000F
--- a/drivers/net/wireless/ath5k/desc.c
+++ b/drivers/net/wireless/ath5k/desc.c
@@ -194,6 +194,10 @@ static int ath5k_hw_setup_4word_tx_desc(
return -EINVAL;
}
+ tx_power += ah->ah_txpower.txp_offset;
+ if (tx_power > AR5K_TUNE_MAX_TXPOWER)
+ tx_power = AR5K_TUNE_MAX_TXPOWER;
+
/* Clear descriptor */
memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));

@ -0,0 +1,150 @@
From 313314263fda19db8eed94a7d7259b595634212e Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Sat, 14 Mar 2009 20:02:51 +0100
Subject: [PATCH] rt2x00: Move Move pci_dev specific access to rt2x00pci
pci_dev->irq and pci_name(pci_dev) access should be limited
to rt2x00pci only. This is more generic and allows a rt2x00 pci
driver to be controlled as PCI device but also as platform driver
(needed for rt2800pci SoC support).
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 2 +-
drivers/net/wireless/rt2x00/rt2500pci.c | 2 +-
drivers/net/wireless/rt2x00/rt2x00.h | 18 ++++++++++++++++++
drivers/net/wireless/rt2x00/rt2x00pci.c | 16 ++++++++++++----
drivers/net/wireless/rt2x00/rt61pci.c | 7 +------
5 files changed, 33 insertions(+), 12 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1361,7 +1361,7 @@ static int rt2400pci_init_eeprom(struct
*/
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
- rt2x00_set_chip(rt2x00dev, RT2460, value, reg);
+ rt2x00_set_chip_rf(rt2x00dev, value, reg);
if (!rt2x00_rf(&rt2x00dev->chip, RF2420) &&
!rt2x00_rf(&rt2x00dev->chip, RF2421)) {
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1525,7 +1525,7 @@ static int rt2500pci_init_eeprom(struct
*/
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
- rt2x00_set_chip(rt2x00dev, RT2560, value, reg);
+ rt2x00_set_chip_rf(rt2x00dev, value, reg);
if (!rt2x00_rf(&rt2x00dev->chip, RF2522) &&
!rt2x00_rf(&rt2x00dev->chip, RF2523) &&
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -672,6 +672,12 @@ struct rt2x00_dev {
unsigned long flags;
/*
+ * Device information, Bus IRQ and name (PCI, SoC)
+ */
+ int irq;
+ const char *name;
+
+ /*
* Chipset identification.
*/
struct rt2x00_chip chip;
@@ -860,6 +866,18 @@ static inline void rt2x00_set_chip(struc
rt2x00dev->chip.rev = rev;
}
+static inline void rt2x00_set_chip_rt(struct rt2x00_dev *rt2x00dev,
+ const u16 rt)
+{
+ rt2x00dev->chip.rt = rt;
+}
+
+static inline void rt2x00_set_chip_rf(struct rt2x00_dev *rt2x00dev,
+ const u16 rf, const u32 rev)
+{
+ rt2x00_set_chip(rt2x00dev, rt2x00dev->chip.rt, rf, rev);
+}
+
static inline char rt2x00_rt(const struct rt2x00_chip *chipset, const u16 chip)
{
return (chipset->rt == chip);
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -170,7 +170,6 @@ static void rt2x00pci_free_queue_dma(str
int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
{
- struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev);
struct data_queue *queue;
int status;
@@ -186,11 +185,11 @@ int rt2x00pci_initialize(struct rt2x00_d
/*
* Register interrupt handler.
*/
- status = request_irq(pci_dev->irq, rt2x00dev->ops->lib->irq_handler,
- IRQF_SHARED, pci_name(pci_dev), rt2x00dev);
+ status = request_irq(rt2x00dev->irq, rt2x00dev->ops->lib->irq_handler,
+ IRQF_SHARED, rt2x00dev->name, rt2x00dev);
if (status) {
ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
- pci_dev->irq, status);
+ rt2x00dev->irq, status);
goto exit;
}
@@ -270,6 +269,7 @@ int rt2x00pci_probe(struct pci_dev *pci_
struct ieee80211_hw *hw;
struct rt2x00_dev *rt2x00dev;
int retval;
+ u16 chip;
retval = pci_request_regions(pci_dev, pci_name(pci_dev));
if (retval) {
@@ -307,6 +307,14 @@ int rt2x00pci_probe(struct pci_dev *pci_
rt2x00dev->dev = &pci_dev->dev;
rt2x00dev->ops = ops;
rt2x00dev->hw = hw;
+ rt2x00dev->irq = pci_dev->irq;
+ rt2x00dev->name = pci_name(pci_dev);
+
+ /*
+ * Determine RT chipset by reading PCI header.
+ */
+ pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip);
+ rt2x00_set_chip_rt(rt2x00dev, chip);
retval = rt2x00pci_alloc_reg(rt2x00dev);
if (retval)
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2308,7 +2308,6 @@ static int rt61pci_init_eeprom(struct rt
u32 reg;
u16 value;
u16 eeprom;
- u16 device;
/*
* Read EEPROM word for configuration.
@@ -2317,14 +2316,10 @@ static int rt61pci_init_eeprom(struct rt
/*
* Identify RF chipset.
- * To determine the RT chip we have to read the
- * PCI header of the device.
*/
- pci_read_config_word(to_pci_dev(rt2x00dev->dev),
- PCI_CONFIG_HEADER_DEVICE, &device);
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
rt2x00pci_register_read(rt2x00dev, MAC_CSR0, &reg);
- rt2x00_set_chip(rt2x00dev, device, value, reg);
+ rt2x00_set_chip_rf(rt2x00dev, value, reg);
if (!rt2x00_rf(&rt2x00dev->chip, RF5225) &&
!rt2x00_rf(&rt2x00dev->chip, RF5325) &&

@ -1,6 +1,6 @@
From 48eba0e802443d417a4b011202f956b9e5a74bfb Mon Sep 17 00:00:00 2001
From 827327792c4b0d4d4909ec27bd56cb3ba8f2b754 Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Tue, 3 Mar 2009 19:14:51 +0100
Date: Sat, 14 Mar 2009 20:06:48 +0100
Subject: [PATCH] rt2x00: Implement support for 802.11n
Extend rt2x00lib capabilities to support 802.11n,

@ -1,6 +1,6 @@
From b11cae133872a0ff531a1d2646f1e46378510fe0 Mon Sep 17 00:00:00 2001
From a34c288f7214637f214ec17fb2b35dd5d20b0634 Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Tue, 3 Mar 2009 19:18:56 +0100
Date: Sat, 14 Mar 2009 20:41:58 +0100
Subject: [PATCH] rt2x00: Implement support for rt2800pci
Add support for the rt2800pci chipset.
@ -15,10 +15,10 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/Kconfig | 15 +
drivers/net/wireless/rt2x00/Makefile | 1 +
drivers/net/wireless/rt2x00/rt2800pci.c | 2831 +++++++++++++++++++++++++++++++
drivers/net/wireless/rt2x00/rt2800pci.h | 1867 ++++++++++++++++++++
drivers/net/wireless/rt2x00/rt2x00.h | 4 +
5 files changed, 4718 insertions(+), 0 deletions(-)
drivers/net/wireless/rt2x00/rt2800pci.c | 3035 +++++++++++++++++++++++++++++++
drivers/net/wireless/rt2x00/rt2800pci.h | 1880 +++++++++++++++++++
drivers/net/wireless/rt2x00/rt2x00.h | 6 +
5 files changed, 4937 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/wireless/rt2x00/rt2800pci.c
create mode 100644 drivers/net/wireless/rt2x00/rt2800pci.h
@ -33,7 +33,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
obj-$(CONFIG_RT73USB) += rt73usb.o
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -0,0 +1,2831 @@
@@ -0,0 +1,3035 @@
+/*
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.com>
@ -67,12 +67,21 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/eeprom_93cx6.h>
+
+#include "rt2x00.h"
+#include "rt2x00pci.h"
+#include "rt2800pci.h"
+
+/* FIXME: Make Kconfig dependent */
+#ifdef CONFIG_PCI
+#define CONFIG_RT2800PCI_PCI
+#endif
+#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
+#define CONFIG_RT2800PCI_WISOC
+#endif
+
+/*
+ * Allow hardware encryption to be disabled.
+ */
@ -208,6 +217,44 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
+{
+ unsigned int i;
+ u32 reg;
+
+ for (i = 0; i < 200; i++) {
+ rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
+
+ if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) ||
+ (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) ||
+ (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD2) == token) ||
+ (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD3) == token))
+ break;
+
+ udelay(REGISTER_BUSY_DELAY);
+ }
+
+ if (i == 200)
+ ERROR(rt2x00dev, "MCU request failed, no response from hardware\n");
+
+ rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+ rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+}
+
+#ifdef CONFIG_RT2800PCI_WISOC
+static void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
+{
+ u32 *base_addr = (u32 *) KSEG1ADDR(0x1F040000); /* XXX for RT3052 */
+
+ memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
+}
+#else
+static inline void rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
+{
+}
+#endif /* CONFIG_RT2800PCI_WISOC */
+
+#ifdef CONFIG_RT2800PCI_PCI
+static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
+{
+ struct rt2x00_dev *rt2x00dev = eeprom->data;
@ -238,6 +285,32 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg);
+}
+
+static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
+{
+ struct eeprom_93cx6 eeprom;
+ u32 reg;
+
+ rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, &reg);
+
+ eeprom.data = rt2x00dev;
+ eeprom.register_read = rt2800pci_eepromregister_read;
+ eeprom.register_write = rt2800pci_eepromregister_write;
+ eeprom.width = !rt2x00_get_field32(reg, E2PROM_CSR_TYPE) ?
+ PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66;
+ eeprom.reg_data_in = 0;
+ eeprom.reg_data_out = 0;
+ eeprom.reg_data_clock = 0;
+ eeprom.reg_chip_select = 0;
+
+ eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom,
+ EEPROM_SIZE / sizeof(u16));
+}
+#else
+static inline void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
+{
+}
+#endif /* CONFIG_RT2800PCI_PCI */
+
+#ifdef CONFIG_RT2X00_LIB_DEBUGFS
+static const struct rt2x00debug rt2800pci_rt2x00debug = {
+ .owner = THIS_MODULE,
@ -372,10 +445,11 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ rt2x00pci_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
+ !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE));
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER, crypto->cipher);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER,
+ (crypto->cmd == SET_KEY) * crypto->cipher);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX,
+ (crypto->cmd == SET_KEY) * crypto->bssidx);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
+ rt2x00pci_register_write(rt2x00dev, offset, reg);
+
+ offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
@ -429,10 +503,11 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ * Using the correct defines correctly will cause overhead,
+ * so just calculate the correct offset.
+ */
+ field.bit_offset = (4 * key->keyidx) + (16 * (crypto->bssidx & 1));
+ field.bit_offset = 4 * (key->hw_key_idx % 8);
+ field.bit_mask = 0x7 << field.bit_offset;
+
+ offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 2);
+ offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
+
+ rt2x00pci_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, field,
+ (crypto->cmd == SET_KEY) * crypto->cipher);
@ -456,9 +531,14 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ if (crypto->cmd == SET_KEY) {
+ /*
+ * 1 pairwise key is possible per AID, this means that the AID
+ * equals our hw_key_idx.
+ * equals our hw_key_idx. Make sure the WCID starts _after_ the
+ * last possible shared key entry.
+ */
+ key->hw_key_idx = crypto->aid;
+ if (crypto->aid > (256 - 32))
+ return -ENOSPC;
+
+ key->hw_key_idx = 32 + crypto->aid;
+
+
+ memcpy(key_entry.key, crypto->key,
+ sizeof(key_entry.key));
@ -929,9 +1009,9 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 1);
+ rt2x00pci_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
+
+ rt2800pci_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 0);
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+ } else {
+ rt2800pci_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+
+ rt2x00pci_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg);
+ rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 0);
@ -1530,8 +1610,8 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ * BBP was enabled after firmware was loaded,
+ * but we need to reactivate it now.
+ */
+ rt2x00pci_register_write(rt2x00dev, H2M_BBP_AGENT, 0x00000000);
+ rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0x00000000);
+ rt2x00pci_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+ rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+ msleep(1);
+
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
@ -1747,9 +1827,10 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+{
+ rt2x00pci_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0);
+
+ if (state == STATE_AWAKE)
+ rt2800pci_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
+ else
+ if (state == STATE_AWAKE) {
+ rt2800pci_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0);
+ rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKUP);
+ } else
+ rt2800pci_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2);
+
+ return 0;
@ -2016,7 +2097,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ * decryption. This prevents us from correct providing
+ * correct statistics through debugfs.
+ */
+ rxdesc->cipher = CIPHER_NONE;
+ rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
+ rxdesc->cipher_status =
+ rt2x00_get_field32(rxd3, RXD_W3_CIPHER_ERROR);
+ }
@ -2055,7 +2136,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ /*
+ * Mask of 0x8 bit to remove the short preamble flag.
+ */
+ if (rxdesc->dev_flags == RATE_MODE_CCK)
+ if (rxdesc->rate_mode == RATE_MODE_CCK)
+ rxdesc->signal &= ~0x8;
+
+ rxdesc->rssi =
@ -2071,7 +2152,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ /*
+ * Remove TXWI descriptor from start of buffer.
+ */
+ skb_pull(entry->skb, TXWI_DESC_SIZE);
+ skb_pull(entry->skb, RXWI_DESC_SIZE);
+ skb_trim(entry->skb, rxdesc->size);
+}
+
@ -2195,26 +2276,22 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ */
+static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
+{
+ struct eeprom_93cx6 eeprom;
+ u32 reg;
+ u16 word;
+ u8 *mac;
+ u8 default_lna_gain;
+
+ rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, &reg);
+
+ eeprom.data = rt2x00dev;
+ eeprom.register_read = rt2800pci_eepromregister_read;
+ eeprom.register_write = rt2800pci_eepromregister_write;
+ eeprom.width = !rt2x00_get_field32(reg, E2PROM_CSR_TYPE) ?
+ PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66;
+ eeprom.reg_data_in = 0;
+ eeprom.reg_data_out = 0;
+ eeprom.reg_data_clock = 0;
+ eeprom.reg_chip_select = 0;
+
+ eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom,
+ EEPROM_SIZE / sizeof(u16));
+ /*
+ * Read EEPROM into buffer
+ */
+ switch(rt2x00dev->chip.rt) {
+ case RT2880:
+ case RT3052:
+ rt2800pci_read_eeprom_soc(rt2x00dev);
+ break;
+ default:
+ rt2800pci_read_eeprom_pci(rt2x00dev);
+ break;
+ }
+
+ /*
+ * Start validation of the data that has been read.
@ -2320,7 +2397,6 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ u32 reg;
+ u16 value;
+ u16 eeprom;
+ u16 device;
+
+ /*
+ * Read EEPROM word for configuration.
@ -2329,21 +2405,18 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+
+ /*
+ * Identify RF chipset.
+ * To determine the RT chip we have to read the
+ * PCI header of the device.
+ */
+ pci_read_config_word(to_pci_dev(rt2x00dev->dev),
+ PCI_CONFIG_HEADER_DEVICE, &device);
+ value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
+ rt2x00pci_register_read(rt2x00dev, MAC_CSR0, &reg);
+ rt2x00_set_chip(rt2x00dev, device, value, reg);
+ rt2x00_set_chip_rf(rt2x00dev, value, reg);
+
+ if (!rt2x00_rf(&rt2x00dev->chip, RF2820) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF2850) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF2720) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF2750) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF3020) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF2020)) {
+ !rt2x00_rf(&rt2x00dev->chip, RF2020) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF3052)) {
+ ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
+ return -ENODEV;
+ }
@ -2490,7 +2563,8 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
+
+ if (rt2x00_rf(&rt2x00dev->chip, RF2820) ||
+ rt2x00_rf(&rt2x00dev->chip, RF2720)) {
+ rt2x00_rf(&rt2x00dev->chip, RF2720) ||
+ rt2x00_rf(&rt2x00dev->chip, RF3052)) {
+ spec->num_channels = 14;
+ spec->channels = rf_vals;
+ } else if (rt2x00_rf(&rt2x00dev->chip, RF2850) ||
@ -2824,6 +2898,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+/*
+ * RT2800pci module information.
+ */
+#ifdef CONFIG_RT2800PCI_PCI
+static struct pci_device_id rt2800pci_device_table[] = {
+ { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) },
@ -2835,15 +2910,130 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ { PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
+#endif /* CONFIG_RT2800PCI_PCI */
+
+MODULE_AUTHOR(DRV_PROJECT);
+MODULE_VERSION(DRV_VERSION);
+MODULE_DESCRIPTION("Ralink RT2800 PCI & PCMCIA Wireless LAN driver.");
+MODULE_SUPPORTED_DEVICE("Ralink RT2860 PCI & PCMCIA chipset based cards");
+MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
+MODULE_FIRMWARE(FIRMWARE_RT2860);
+MODULE_LICENSE("GPL");
+
+#ifdef CONFIG_RT2800PCI_WISOC
+
+#ifdef CONFIG_RALINK_RT288X
+#define WSOC_RT_CHIPSET RT2880
+#endif /* CONFIG_RALINK_RT288X */
+
+#ifdef CONFIG_RALINK_RT305X
+#define WSOC_RT_CHIPSET RT3052
+#endif /* CONFIG_RALINK_RT305X */
+
+static void rt2800soc_free_reg(struct rt2x00_dev *rt2x00dev)
+{
+ kfree(rt2x00dev->rf);
+ rt2x00dev->rf = NULL;
+
+ kfree(rt2x00dev->eeprom);
+ rt2x00dev->eeprom = NULL;
+}
+
+static int rt2800soc_alloc_reg(struct rt2x00_dev *rt2x00dev)
+{
+ struct platform_device *pdev = to_platform_device(rt2x00dev->dev);
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ ERROR_PROBE("Failed to get MMIO resource\n");
+ return -ENODEV;
+ }
+
+ rt2x00dev->csr.base = (void __iomem *) KSEG1ADDR(res->start);
+ rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
+ if (!rt2x00dev->eeprom)
+ goto exit;
+
+ rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL);
+ if (!rt2x00dev->rf)
+ goto exit;
+
+ return 0;
+
+exit:
+ ERROR_PROBE("Failed to allocate registers.\n");
+ rt2800soc_free_reg(rt2x00dev);
+
+ return -ENOMEM;
+}
+
+static int rt2800soc_probe(struct platform_device *pdev)
+{
+ const struct rt2x00_ops *ops = &rt2800pci_ops;
+ struct ieee80211_hw *hw;
+ struct rt2x00_dev *rt2x00dev;
+ int retval;
+
+ hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw);
+ if (!hw) {
+ ERROR_PROBE("Failed to allocate hardware.\n");
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, hw);
+
+ rt2x00dev = hw->priv;
+ rt2x00dev->dev = &pdev->dev;
+ rt2x00dev->ops = ops;
+ rt2x00dev->hw = hw;
+ rt2x00dev->irq = platform_get_irq(pdev, 0);
+ rt2x00dev->name = pdev->dev.driver->name;
+
+ rt2x00_set_chip_rt(rt2x00dev, WSOC_RT_CHIPSET);
+
+ retval = rt2800soc_alloc_reg(rt2x00dev);
+ if (retval)
+ goto exit_free_device;
+
+ retval = rt2x00lib_probe_dev(rt2x00dev);
+ if (retval)
+ goto exit_free_reg;
+
+ return 0;
+
+exit_free_reg:
+ rt2800soc_free_reg(rt2x00dev);
+
+exit_free_device:
+ ieee80211_free_hw(hw);
+
+ return retval;
+}
+
+static int rt2800soc_remove(struct platform_device *pdev)
+{
+ struct ieee80211_hw *hw = platform_get_drvdata(pdev);
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+
+ /*
+ * Free all allocated data.
+ */
+ rt2x00lib_remove_dev(rt2x00dev);
+ rt2800soc_free_reg(rt2x00dev);
+ ieee80211_free_hw(hw);
+
+ return 0;
+}
+
+static struct platform_driver rt2800soc_driver = {
+ .driver.name = "rt2800_wmac",
+ .probe = rt2800soc_probe,
+ .remove = rt2800soc_remove,
+};
+#endif /* CONFIG_RT2800PCI_WISOC */
+
+#ifdef CONFIG_RT2800PCI_PCI
+static struct pci_driver rt2800pci_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = rt2800pci_device_table,
@ -2852,22 +3042,36 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ .suspend = rt2x00pci_suspend,
+ .resume = rt2x00pci_resume,
+};
+#endif /* CONFIG_RT2800PCI_PCI */
+
+static int __init rt2800pci_init(void)
+{
+ return pci_register_driver(&rt2800pci_driver);
+ int ret = 0;
+
+#ifdef CONFIG_RT2800PCI_WISOC
+ ret = platform_driver_register(&rt2800soc_driver);
+#endif
+#ifdef CONFIG_RT2800PCI_PCI
+ ret = pci_register_driver(&rt2800pci_driver);
+#endif
+ return ret;
+}
+
+static void __exit rt2800pci_exit(void)
+{
+#ifdef CONFIG_RT2800PCI_PCI
+ pci_unregister_driver(&rt2800pci_driver);
+#endif
+#ifdef CONFIG_RT2800PCI_WISOC
+ platform_driver_unregister(&rt2800soc_driver);
+#endif
+}
+
+module_init(rt2800pci_init);
+module_exit(rt2800pci_exit);
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2800pci.h
@@ -0,0 +1,1867 @@
@@ -0,0 +1,1880 @@
+/*
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.com>
@ -2906,6 +3110,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ * RF2750 2.4G/5G 1T2R
+ * RF3020 2.4G 1T1R
+ * RF2020 2.4G B/G
+ * RF3052 2.4G 2T2R
+ */
+#define RF2820 0x0001
+#define RF2850 0x0002
@ -2913,6 +3118,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+#define RF2750 0x0004
+#define RF3020 0x0005
+#define RF2020 0x0006
+#define RF3052 0x0008
+
+/*
+ * RT2860 version
@ -4233,6 +4439,10 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ * H2M_MAILBOX_CID:
+ */
+#define H2M_MAILBOX_CID 0x7014
+#define H2M_MAILBOX_CID_CMD0 FIELD32(0x000000ff)
+#define H2M_MAILBOX_CID_CMD1 FIELD32(0x0000ff00)
+#define H2M_MAILBOX_CID_CMD2 FIELD32(0x00ff0000)
+#define H2M_MAILBOX_CID_CMD3 FIELD32(0xff000000)
+
+/*
+ * H2M_MAILBOX_STATUS:
@ -4530,6 +4740,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ */
+#define MCU_SLEEP 0x30
+#define MCU_WAKEUP 0x31
+#define MCU_RADIO_OFF 0x35
+#define MCU_LED 0x50
+#define MCU_LED_STRENGTH 0x51
+#define MCU_LED_1 0x52
@ -4537,6 +4748,12 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+#define MCU_LED_3 0x54
+#define MCU_RADAR 0x60
+#define MCU_BOOT_SIGNAL 0x72
+#define MCU_BBP_SIGNAL 0x80
+
+/*
+ * MCU mailbox tokens
+ */
+#define TOKEN_WAKUP 3
+
+/*
+ * DMA descriptor defines.
@ -4737,7 +4954,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+#endif /* RT2800PCI_H */
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -138,6 +138,10 @@ struct rt2x00_chip {
@@ -138,6 +138,12 @@ struct rt2x00_chip {
#define RT2561 0x0302
#define RT2661 0x0401
#define RT2571 0x1300
@ -4745,6 +4962,8 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+#define RT2860D 0x0681 /* 2.4GHz, 5GHz PCI/CB */
+#define RT2890 0x0701 /* 2.4GHz PCIe */
+#define RT2890D 0x0781 /* 2.4GHz, 5GHz PCIe */
+#define RT2880 0x2880 /* WSOC */
+#define RT3052 0x3052 /* WSOC */
u16 rf;
u32 rev;

@ -1,6 +1,6 @@
From b249bc450f982cd2491448c91faf797ed37b69b8 Mon Sep 17 00:00:00 2001
From 101b65d221593c1bdeacf0c6085d885ea5447c4c Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Tue, 3 Mar 2009 19:25:49 +0100
Date: Sat, 14 Mar 2009 20:46:40 +0100
Subject: [PATCH] rt2x00: Implement support for rt2800usb
Add support for the rt2800usb chipset.
@ -16,9 +16,9 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
drivers/net/wireless/rt2x00/Kconfig | 14 +
drivers/net/wireless/rt2x00/Makefile | 1 +
drivers/net/wireless/rt2x00/rt2800usb.c | 3032 +++++++++++++++++++++++++++++++
drivers/net/wireless/rt2x00/rt2800usb.h | 1932 ++++++++++++++++++++
drivers/net/wireless/rt2x00/rt2800usb.h | 1934 ++++++++++++++++++++
drivers/net/wireless/rt2x00/rt2x00.h | 7 +
5 files changed, 4986 insertions(+), 0 deletions(-)
5 files changed, 4988 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/wireless/rt2x00/rt2800usb.c
create mode 100644 drivers/net/wireless/rt2x00/rt2800usb.h
@ -397,10 +397,11 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ rt2x00usb_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
+ !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE));
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER, crypto->cipher);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER,
+ (crypto->cmd == SET_KEY) * crypto->cipher);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX,
+ (crypto->cmd == SET_KEY) * crypto->bssidx);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
+ rt2x00usb_register_write(rt2x00dev, offset, reg);
+
+ offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
@ -459,10 +460,10 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ * Using the correct defines correctly will cause overhead,
+ * so just calculate the correct offset.
+ */
+ field.bit_offset = (4 * key->keyidx) + (16 * (crypto->bssidx & 1));
+ field.bit_offset = 4 * (key->hw_key_idx % 8);
+ field.bit_mask = 0x7 << field.bit_offset;
+
+ offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 2);
+ offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
+
+ rt2x00usb_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, field,
@ -488,9 +489,13 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ if (crypto->cmd == SET_KEY) {
+ /*
+ * 1 pairwise key is possible per AID, this means that the AID
+ * equals our hw_key_idx.
+ * equals our hw_key_idx. Make sure the WCID starts _after_ the
+ * last possible shared key entry.
+ */
+ key->hw_key_idx = crypto->aid;
+ if (crypto->aid > (256 - 32))
+ return -ENOSPC;
+
+ key->hw_key_idx = 32 + crypto->aid;
+
+ memcpy(key_entry.key, crypto->key,
+ sizeof(key_entry.key));
@ -2183,12 +2188,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
+
+ if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
+ /*
+ * Unfortunately we don't know the cipher type used during
+ * decryption. This prevents us from correct providing
+ * correct statistics through debugfs.
+ */
+ rxdesc->cipher = CIPHER_NONE;
+ rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
+ rxdesc->cipher_status =
+ rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
+ }
@ -2227,7 +2227,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ /*
+ * Mask of 0x8 bit to remove the short preamble flag.
+ */
+ if (rxdesc->dev_flags == RATE_MODE_CCK)
+ if (rxdesc->rate_mode == RATE_MODE_CCK)
+ rxdesc->signal &= ~0x8;
+
+ rxdesc->rssi =
@ -3066,7 +3066,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+module_exit(rt2800usb_exit);
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -0,0 +1,1932 @@
@@ -0,0 +1,1934 @@
+/*
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.com>
@ -4783,6 +4783,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+ */
+#define MCU_SLEEP 0x30
+#define MCU_WAKEUP 0x31
+#define MCU_RADIO_OFF 0x35
+#define MCU_LED 0x50
+#define MCU_LED_STRENGTH 0x51
+#define MCU_LED_1 0x52
@ -4790,6 +4791,7 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+#define MCU_LED_3 0x54
+#define MCU_RADAR 0x60
+#define MCU_BOOT_SIGNAL 0x72
+#define MCU_BBP_SIGNAL 0x80
+
+/*
+ * DMA descriptor defines.
@ -5001,15 +5003,15 @@ Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+#endif /* RT2800USB_H */
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -142,6 +142,7 @@ struct rt2x00_chip {
#define RT2860D 0x0681 /* 2.4GHz, 5GHz PCI/CB */
#define RT2890 0x0701 /* 2.4GHz PCIe */
@@ -144,6 +144,7 @@ struct rt2x00_chip {
#define RT2890D 0x0781 /* 2.4GHz, 5GHz PCIe */
#define RT2880 0x2880 /* WSOC */
#define RT3052 0x3052 /* WSOC */
+#define RT2870 0x1600
u16 rf;
u32 rev;
@@ -780,6 +781,12 @@ struct rt2x00_dev {
@@ -788,6 +789,12 @@ struct rt2x00_dev {
u8 freq_offset;
/*

@ -1,35 +0,0 @@
From f23c3d3175e55ebac81d6e29f1c1415491a78d60 Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Tue, 3 Mar 2009 20:12:44 +0100
Subject: [PATCH] rt2x00: Detect cypher type during RX (rt2800pci)
Use UDF field in WCID entry to pass the cipher type
to the RXWI fields. This will allow keeping track of
the number of frames received with a particular cipher type
which is exported through debugfs.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800pci.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -339,7 +339,7 @@ static void rt2800pci_config_wcid_attr(s
rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER, crypto->cipher);
rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX,
(crypto->cmd == SET_KEY) * crypto->bssidx);
- rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
rt2x00pci_register_write(rt2x00dev, offset, reg);
offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
@@ -1980,7 +1980,7 @@ static void rt2800pci_fill_rxdone(struct
* decryption. This prevents us from correct providing
* correct statistics through debugfs.
*/
- rxdesc->cipher = CIPHER_NONE;
+ rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
rxdesc->cipher_status =
rt2x00_get_field32(rxd3, RXD_W3_CIPHER_ERROR);
}

@ -0,0 +1,25 @@
From 6bdf6a86854bdeab9557f0ce25c3f5401c18f629 Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Sat, 14 Mar 2009 20:57:27 +0100
Subject: [PATCH] rt2x00: rt2x00: Move Move pci_dev specific access to rt2x00pci - part 2
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt61pci.h | 6 ------
1 files changed, 0 insertions(+), 6 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -63,12 +63,6 @@
*/
/*
- * PCI Configuration Header
- */
-#define PCI_CONFIG_HEADER_VENDOR 0x0000
-#define PCI_CONFIG_HEADER_DEVICE 0x0002
-
-/*
* HOST_CMD_CSR: For HOST to interrupt embedded processor
*/
#define HOST_CMD_CSR 0x0008

@ -1,40 +0,0 @@
From 35c7358f5f7ba03daeecdf1fdceabd48ebcd029a Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Tue, 3 Mar 2009 20:15:17 +0100
Subject: [PATCH] rt2x00: Detect cypher type during RX (rt2800usb)
Use UDF field in WCID entry to pass the cipher type
to the RXWI fields. This will allow keeping track of
the number of frames received with a particular cipher type
which is exported through debugfs.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800usb.c | 9 ++-------
1 files changed, 2 insertions(+), 7 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -366,7 +366,7 @@ static void rt2800usb_config_wcid_attr(s
rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER, crypto->cipher);
rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX,
(crypto->cmd == SET_KEY) * crypto->bssidx);
- rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
rt2x00usb_register_write(rt2x00dev, offset, reg);
offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
@@ -2149,12 +2149,7 @@ static void rt2800usb_fill_rxdone(struct
rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
- /*
- * Unfortunately we don't know the cipher type used during
- * decryption. This prevents us from correct providing
- * correct statistics through debugfs.
- */
- rxdesc->cipher = CIPHER_NONE;
+ rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
rxdesc->cipher_status =
rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
}

@ -0,0 +1,25 @@
From a3334c89fbed644bb12ee27e2d9c1dc70b1512ab Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Sat, 14 Mar 2009 20:58:12 +0100
Subject: [PATCH] rt2x00: rt2x00: Move Move pci_dev specific access to rt2x00pci - part 2 (rt2800pci)
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800pci.h | 6 ------
1 files changed, 0 insertions(+), 6 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt2800pci.h
+++ b/drivers/net/wireless/rt2x00/rt2800pci.h
@@ -83,12 +83,6 @@
*/
/*
- * PCI Configuration Header
- */
-#define PCI_CONFIG_HEADER_VENDOR 0x0000
-#define PCI_CONFIG_HEADER_DEVICE 0x0002
-
-/*
* E2PROM_CSR: EEPROM control register.
* RELOAD: Write 1 to reload eeprom content.
* TYPE: 0: 93c46, 1:93c66.

@ -1,36 +0,0 @@
From e63585e28192e854707c549547645c669e6daa2a Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Wed, 4 Mar 2009 20:25:43 +0100
Subject: [PATCH] rt2x00: Fix HW crypto offset calculation (rt2800pci)
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800pci.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -336,7 +336,8 @@ static void rt2800pci_config_wcid_attr(s
rt2x00pci_register_read(rt2x00dev, offset, &reg);
rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
!!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE));
- rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER, crypto->cipher);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER,
+ (crypto->cmd == SET_KEY) * crypto->cipher);
rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX,
(crypto->cmd == SET_KEY) * crypto->bssidx);
rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
@@ -393,10 +394,11 @@ static int rt2800pci_config_shared_key(s
* Using the correct defines correctly will cause overhead,
* so just calculate the correct offset.
*/
- field.bit_offset = (4 * key->keyidx) + (16 * (crypto->bssidx & 1));
+ field.bit_offset = 4 * (key->hw_key_idx % 8);
field.bit_mask = 0x7 << field.bit_offset;
- offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 2);
+ offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
+
rt2x00pci_register_read(rt2x00dev, offset, &reg);
rt2x00_set_field32(&reg, field,
(crypto->cmd == SET_KEY) * crypto->cipher);

@ -0,0 +1,32 @@
From 14f870b27b836acee5f04809287175016ca16b05 Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Sun, 15 Mar 2009 15:13:58 +0100
Subject: [PATCH] rt2x00: Fix module loading in case of error (rt2800pci)
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800pci.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -3014,10 +3014,19 @@ static int __init rt2800pci_init(void)
#ifdef CONFIG_RT2800PCI_WISOC
ret = platform_driver_register(&rt2800soc_driver);
+ if (ret)
+ return ret;
#endif
#ifdef CONFIG_RT2800PCI_PCI
ret = pci_register_driver(&rt2800pci_driver);
+ if (ret) {
+#ifdef CONFIG_RT2800PCI_WISOC
+ platform_driver_unregister(&rt2800soc_driver);
+#endif
+ return ret;
+ }
#endif
+
return ret;
}

@ -0,0 +1,80 @@
From aef81259a944186a120d51e4462a5f974de99fb8 Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Sun, 15 Mar 2009 15:37:29 +0100
Subject: [PATCH] rt2x00: Add PM support for SoC (rt2800pci)
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800pci.c | 52 +++++++++++++++++++++++++++++--
1 files changed, 49 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -2934,7 +2934,7 @@ exit:
static int rt2800soc_probe(struct platform_device *pdev)
{
- const struct rt2x00_ops *ops = &rt2800pci_ops;
+ struct rt2x00_ops *ops = (struct rt2x00_ops *)pdev->driver->p;
struct ieee80211_hw *hw;
struct rt2x00_dev *rt2x00dev;
int retval;
@@ -2990,10 +2990,56 @@ static int rt2800soc_remove(struct platf
return 0;
}
+#ifdef CONFIG_PM
+int rt2x00soc_suspend(struct device *dev, pm_message_t state)
+{
+ struct ieee80211_hw *hw = dev_get_drvdata(dev);
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ int retval;
+
+ retval = rt2x00lib_suspend(rt2x00dev, state);
+ if (retval)
+ return retval;
+
+ rt2800soc_free_reg(rt2x00dev);
+
+ return 0;
+}
+
+int rt2x00soc_resume(struct device *dev)
+{
+ struct ieee80211_hw *hw = dev_get_drvdata(dev);
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ int retval;
+
+ retval = rt2x00soc_alloc_reg(rt2x00dev);
+ if (retval)
+ return retval;
+
+ retval = rt2x00lib_resume(rt2x00dev);
+ if (retval)
+ goto exit_free_reg;
+
+ return 0;
+
+exit_free_reg:
+ rt2x00pci_free_reg(rt2x00dev);
+
+ return retval;
+}
+#endif /* CONFIG_PM */
+
static struct platform_driver rt2800soc_driver = {
- .driver.name = "rt2800_wmac",
+ .driver = {
+ .name = "rt2800_wmac",
+ .owner = THIS_MODULE,
+ .mod_name = KBUILD_MODNAME,
+ .p = &rt2800pci_ops;
+ }
.probe = rt2800soc_probe,
- .remove = rt2800soc_remove,
+ .remove = __devexit_p(rt2800soc_remove),
+ .suspend = rt2x00soc_suspend,
+ .resume = rt2x00soc_resume,
};
#endif /* CONFIG_RT2800PCI_WISOC */

@ -1,35 +0,0 @@
From d6368d8b77bb8568aa0c92adf1e507fb4198ff41 Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Wed, 4 Mar 2009 20:26:27 +0100
Subject: [PATCH] rt2x00: Fix HW crypto offset calculation (rt2800usb)
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800usb.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -363,7 +363,8 @@ static void rt2800usb_config_wcid_attr(s
rt2x00usb_register_read(rt2x00dev, offset, &reg);
rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
!!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE));
- rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER, crypto->cipher);
+ rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER,
+ (crypto->cmd == SET_KEY) * crypto->cipher);
rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX,
(crypto->cmd == SET_KEY) * crypto->bssidx);
rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
@@ -425,10 +426,10 @@ static int rt2800usb_config_shared_key(s
* Using the correct defines correctly will cause overhead,
* so just calculate the correct offset.
*/
- field.bit_offset = (4 * key->keyidx) + (16 * (crypto->bssidx & 1));
+ field.bit_offset = 4 * (key->hw_key_idx % 8);
field.bit_mask = 0x7 << field.bit_offset;
- offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 2);
+ offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
rt2x00usb_register_read(rt2x00dev, offset, &reg);
rt2x00_set_field32(&reg, field,

@ -0,0 +1,535 @@
From bfa282e0f525b074ec9a21372ab906156ce0aa20 Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Mon, 16 Mar 2009 20:16:59 +0100
Subject: [PATCH] rt2x00: DMA fixes & new chipset support (rt2800pci)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800pci.c | 320 +++++++++++++++++++++++++++++--
drivers/net/wireless/rt2x00/rt2800pci.h | 57 ++++++-
2 files changed, 361 insertions(+), 16 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -66,6 +66,8 @@ MODULE_PARM_DESC(nohwcrypt, "Disable har
*/
#define WAIT_FOR_BBP(__dev, __reg) \
rt2x00pci_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg))
+#define WAIT_FOR_RFCSR(__dev, __reg) \
+ rt2x00pci_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg))
#define WAIT_FOR_RF(__dev, __reg) \
rt2x00pci_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg))
#define WAIT_FOR_MCU(__dev, __reg) \
@@ -129,6 +131,61 @@ static void rt2800pci_bbp_read(struct rt
mutex_unlock(&rt2x00dev->csr_mutex);
}
+static void rt2800pci_rfcsr_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, const u8 value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the RFCSR becomes available, afterwards we
+ * can safely write the new data into the register.
+ */
+ if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, RF_CSR_CFG_DATA, value);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 1);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
+
+ rt2x00pci_register_write(rt2x00dev, RF_CSR_CFG, reg);
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800pci_rfcsr_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, u8 *value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the RFCSR becomes available, afterwards we
+ * can safely write the read request into the register.
+ * After the data has been written, we wait until hardware
+ * returns the correct value, if at any time the register
+ * doesn't become available in time, reg will be 0xffffffff
+ * which means we return 0xff to the caller.
+ */
+ if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 0);
+ rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
+
+ rt2x00pci_register_write(rt2x00dev, RF_CSR_CFG, reg);
+
+ WAIT_FOR_RFCSR(rt2x00dev, &reg);
+ }
+
+ *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA);
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
static void rt2800pci_rf_write(struct rt2x00_dev *rt2x00dev,
const unsigned int word, const u32 value)
{
@@ -160,6 +217,13 @@ static void rt2800pci_mcu_request(struct
{
u32 reg;
+ /*
+ * RT2880 and RT3052 don't support MCU requests.
+ */
+ if (rt2x00_rt(&rt2x00dev->chip, RT2880) ||
+ rt2x00_rt(&rt2x00dev->chip, RT3052))
+ return;
+
mutex_lock(&rt2x00dev->csr_mutex);
/*
@@ -729,13 +793,11 @@ static void rt2800pci_config_lna_gain(st
rt2x00dev->lna_gain = lna_gain;
}
-static void rt2800pci_config_channel(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_conf *conf,
- struct rf_channel *rf,
- struct channel_info *info)
+static void rt2800pci_config_channel_rt2x(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+ struct channel_info *info)
{
- u32 reg;
- unsigned int tx_pin;
u16 eeprom;
rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
@@ -745,9 +807,8 @@ static void rt2800pci_config_channel(str
*/
rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
- if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1) {
+ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) == 1)
rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1);
- }
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH) == 1) {
rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1);
@@ -806,6 +867,62 @@ static void rt2800pci_config_channel(str
rt2800pci_rf_write(rt2x00dev, 2, rf->rf2);
rt2800pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
rt2800pci_rf_write(rt2x00dev, 4, rf->rf4);
+}
+
+static void rt2800pci_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+ struct channel_info *info)
+{
+ u8 rfcsr;
+
+ rt2800pci_rfcsr_write(rt2x00dev, 2, rf->rf1);
+ rt2800pci_rfcsr_write(rt2x00dev, 2, rf->rf3);
+
+ rt2800pci_rfcsr_read(rt2x00dev, 6, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR6_R, rf->rf2);
+ rt2800pci_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+ rt2800pci_rfcsr_read(rt2x00dev, 12, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
+ TXPOWER_G_TO_DEV(info->tx_power1));
+ rt2800pci_rfcsr_write(rt2x00dev, 12, rfcsr);
+
+ rt2800pci_rfcsr_read(rt2x00dev, 23, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
+ rt2800pci_rfcsr_write(rt2x00dev, 23, rfcsr);
+
+ if (conf_is_ht40(conf))
+ rt2800pci_rfcsr_write(rt2x00dev, 24,
+ rt2x00dev->calibration_bw40);
+ else
+ rt2800pci_rfcsr_write(rt2x00dev, 24,
+ rt2x00dev->calibration_bw20);
+
+ rt2800pci_rfcsr_read(rt2x00dev, 23, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
+ rt2800pci_rfcsr_write(rt2x00dev, 23, rfcsr);
+}
+
+static void rt2800pci_config_channel(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf,
+ struct rf_channel *rf,
+ struct channel_info *info)
+{
+ u32 reg;
+ unsigned int tx_pin;
+ u16 eeprom;
+ u8 bbp;
+
+ /*
+ * Determine antenna settings from EEPROM
+ */
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+
+ if (rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
+ rt2800pci_config_channel_rt2x(rt2x00dev, conf, rf, info);
+ else
+ rt2800pci_config_channel_rt3x(rt2x00dev, conf, rf, info);
/*
* Change BBP settings
@@ -861,6 +978,26 @@ static void rt2800pci_config_channel(str
rt2x00pci_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
+ rt2800pci_bbp_read(rt2x00dev, 4, &bbp);
+ rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
+ rt2800pci_bbp_write(rt2x00dev, 4, bbp);
+
+ rt2800pci_bbp_read(rt2x00dev, 3, &bbp);
+ rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf));
+ rt2800pci_bbp_write(rt2x00dev, 3, bbp);
+
+ if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
+ if (conf_is_ht40(conf)) {
+ rt2800pci_bbp_write(rt2x00dev, 69, 0x1a);
+ rt2800pci_bbp_write(rt2x00dev, 70, 0x0a);
+ rt2800pci_bbp_write(rt2x00dev, 73, 0x16);
+ } else {
+ rt2800pci_bbp_write(rt2x00dev, 69, 0x16);
+ rt2800pci_bbp_write(rt2x00dev, 70, 0x08);
+ rt2800pci_bbp_write(rt2x00dev, 73, 0x11);
+ }
+ }
+
msleep(1);
}
@@ -1265,7 +1402,7 @@ static int rt2800pci_init_queues(struct
entry_priv = rt2x00dev->rx->entries[0].priv_data;
rt2x00pci_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, RX_MAX_CNT, rt2x00dev->rx[0].limit);
- rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX, 0);
+ rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX, rt2x00dev->rx[0].limit - 1);
rt2x00pci_register_write(rt2x00dev, RX_DRX_IDX, 0);
/*
@@ -1613,7 +1750,7 @@ static int rt2800pci_init_bbp(struct rt2
rt2800pci_bbp_write(rt2x00dev, 91, 0x04);
rt2800pci_bbp_write(rt2x00dev, 92, 0x00);
rt2800pci_bbp_write(rt2x00dev, 103, 0x00);
- rt2800pci_bbp_write(rt2x00dev, 105, 0x05);
+ rt2800pci_bbp_write(rt2x00dev, 105, 0x01);
if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
rt2800pci_bbp_write(rt2x00dev, 69, 0x16);
@@ -1623,6 +1760,12 @@ static int rt2800pci_init_bbp(struct rt2
if (rt2x00_rev(&rt2x00dev->chip) > RT2860D_VERSION)
rt2800pci_bbp_write(rt2x00dev, 84, 0x19);
+ if (rt2x00_rt(&rt2x00dev->chip, RT3052)) {
+ rt2800pci_bbp_write(rt2x00dev, 31, 0x08);
+ rt2800pci_bbp_write(rt2x00dev, 78, 0x0e);
+ rt2800pci_bbp_write(rt2x00dev, 80, 0x08);
+ }
+
for (i = 0; i < EEPROM_BBP_SIZE; i++) {
rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
@@ -1636,6 +1779,144 @@ static int rt2800pci_init_bbp(struct rt2
return 0;
}
+static u8 rt2800pci_init_rx_filter(struct rt2x00_dev *rt2x00dev,
+ bool bw40, u8 rfcsr24, u8 filter_target)
+{
+ unsigned int i;
+ u8 bbp;
+ u8 rfcsr;
+ u8 passband;
+ u8 stopband;
+ u8 overtuned = 0;
+
+ rt2800pci_rfcsr_write(rt2x00dev, 24, rfcsr24);
+
+ rt2800pci_bbp_read(rt2x00dev, 4, &bbp);
+ rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * bw40);
+ rt2800pci_bbp_write(rt2x00dev, 4, bbp);
+
+ rt2800pci_rfcsr_read(rt2x00dev, 22, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 1);
+ rt2800pci_rfcsr_write(rt2x00dev, 22, rfcsr);
+
+ /*
+ * Set power & frequency of passband test tone
+ */
+ rt2800pci_bbp_write(rt2x00dev, 24, 0);
+
+ for (i = 0; i < 100; i++) {
+ rt2800pci_bbp_write(rt2x00dev, 25, 0x90);
+ msleep(1);
+
+ rt2800pci_bbp_read(rt2x00dev, 55, &passband);
+ if (passband)
+ break;
+ }
+
+ /*
+ * Set power & frequency of stopband test tone
+ */
+ rt2800pci_bbp_write(rt2x00dev, 24, 0x06);
+
+ for (i = 0; i < 100; i++) {
+ rt2800pci_bbp_write(rt2x00dev, 25, 0x90);
+ msleep(1);
+
+ rt2800pci_bbp_read(rt2x00dev, 55, &stopband);
+
+ if ((passband - stopband) <= filter_target) {
+ rfcsr24++;
+ overtuned += ((passband - stopband) == filter_target);
+ } else
+ break;
+
+ rt2800pci_rfcsr_write(rt2x00dev, 24, rfcsr24);
+ }
+
+ rfcsr24 -= !!overtuned;
+
+ rt2800pci_rfcsr_write(rt2x00dev, 24, rfcsr24);
+ return rfcsr24;
+}
+
+static int rt2800pci_init_rfcsr(struct rt2x00_dev *rt2x00dev)
+{
+ u8 rfcsr;
+ u8 bbp;
+
+ if (!rt2x00_rf(&rt2x00dev->chip, RF3020) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF3021) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF3022))
+ return 0;
+
+ /*
+ * Init RF calibration.
+ */
+ rt2800pci_rfcsr_read(rt2x00dev, 30, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
+ rt2800pci_rfcsr_write(rt2x00dev, 30, rfcsr);
+ msleep(1);
+ rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
+ rt2800pci_rfcsr_write(rt2x00dev, 30, rfcsr);
+
+ rt2800pci_rfcsr_write(rt2x00dev, 0, 0x50);
+ rt2800pci_rfcsr_write(rt2x00dev, 1, 0x01);
+ rt2800pci_rfcsr_write(rt2x00dev, 2, 0xf7);
+ rt2800pci_rfcsr_write(rt2x00dev, 3, 0x75);
+ rt2800pci_rfcsr_write(rt2x00dev, 4, 0x40);
+ rt2800pci_rfcsr_write(rt2x00dev, 5, 0x03);
+ rt2800pci_rfcsr_write(rt2x00dev, 6, 0x02);
+ rt2800pci_rfcsr_write(rt2x00dev, 7, 0x50);
+ rt2800pci_rfcsr_write(rt2x00dev, 8, 0x39);
+ rt2800pci_rfcsr_write(rt2x00dev, 9, 0x0f);
+ rt2800pci_rfcsr_write(rt2x00dev, 10, 0x60);
+ rt2800pci_rfcsr_write(rt2x00dev, 11, 0x21);
+ rt2800pci_rfcsr_write(rt2x00dev, 12, 0x75);
+ rt2800pci_rfcsr_write(rt2x00dev, 13, 0x75);
+ rt2800pci_rfcsr_write(rt2x00dev, 14, 0x90);
+ rt2800pci_rfcsr_write(rt2x00dev, 15, 0x58);
+ rt2800pci_rfcsr_write(rt2x00dev, 16, 0xb3);
+ rt2800pci_rfcsr_write(rt2x00dev, 17, 0x92);
+ rt2800pci_rfcsr_write(rt2x00dev, 18, 0x2c);
+ rt2800pci_rfcsr_write(rt2x00dev, 19, 0x02);
+ rt2800pci_rfcsr_write(rt2x00dev, 20, 0xba);
+ rt2800pci_rfcsr_write(rt2x00dev, 21, 0xdb);
+ rt2800pci_rfcsr_write(rt2x00dev, 22, 0x00);
+ rt2800pci_rfcsr_write(rt2x00dev, 23, 0x31);
+ rt2800pci_rfcsr_write(rt2x00dev, 24, 0x08);
+ rt2800pci_rfcsr_write(rt2x00dev, 25, 0x01);
+ rt2800pci_rfcsr_write(rt2x00dev, 26, 0x25);
+ rt2800pci_rfcsr_write(rt2x00dev, 27, 0x23);
+ rt2800pci_rfcsr_write(rt2x00dev, 28, 0x13);
+ rt2800pci_rfcsr_write(rt2x00dev, 29, 0x83);
+
+ /*
+ * Set RX Filter calibration for 20MHz and 40MHz
+ */
+ rt2x00dev->calibration_bw20 =
+ rt2800pci_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
+ rt2x00dev->calibration_bw40 =
+ rt2800pci_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
+
+ /*
+ * Set back to initial state
+ */
+ rt2800pci_bbp_write(rt2x00dev, 24, 0);
+
+ rt2800pci_rfcsr_read(rt2x00dev, 22, &rfcsr);
+ rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0);
+ rt2800pci_rfcsr_write(rt2x00dev, 22, rfcsr);
+
+ /*
+ * set BBP back to BW20
+ */
+ rt2800pci_bbp_read(rt2x00dev, 4, &bbp);
+ rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
+ rt2800pci_bbp_write(rt2x00dev, 4, bbp);
+
+ return 0;
+}
+
/*
* Device state switch handlers.
*/
@@ -1718,7 +1999,8 @@ static int rt2800pci_enable_radio(struct
rt2800pci_init_queues(rt2x00dev) ||
rt2800pci_init_registers(rt2x00dev) ||
rt2800pci_wait_wpdma_ready(rt2x00dev) ||
- rt2800pci_init_bbp(rt2x00dev)))
+ rt2800pci_init_bbp(rt2x00dev) ||
+ rt2800pci_init_rfcsr(rt2x00dev)))
return -EIO;
/*
@@ -2114,6 +2396,12 @@ static void rt2800pci_fill_rxdone(struct
rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT);
/*
+ * Set RX IDX in register to inform hardware that we have handled
+ * this entry and it is available for reuse again.
+ */
+ rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX, entry->entry_idx);
+
+ /*
* Remove TXWI descriptor from start of buffer.
*/
skb_pull(entry->skb, RXWI_DESC_SIZE);
@@ -2380,7 +2668,8 @@ static int rt2800pci_init_eeprom(struct
!rt2x00_rf(&rt2x00dev->chip, RF2750) &&
!rt2x00_rf(&rt2x00dev->chip, RF3020) &&
!rt2x00_rf(&rt2x00dev->chip, RF2020) &&
- !rt2x00_rf(&rt2x00dev->chip, RF3052)) {
+ !rt2x00_rf(&rt2x00dev->chip, RF3021) &&
+ !rt2x00_rf(&rt2x00dev->chip, RF3022)) {
ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
return -ENODEV;
}
@@ -2528,7 +2817,8 @@ static int rt2800pci_probe_hw_mode(struc
if (rt2x00_rf(&rt2x00dev->chip, RF2820) ||
rt2x00_rf(&rt2x00dev->chip, RF2720) ||
- rt2x00_rf(&rt2x00dev->chip, RF3052)) {
+ rt2x00_rf(&rt2x00dev->chip, RF3021) ||
+ rt2x00_rf(&rt2x00dev->chip, RF3022)) {
spec->num_channels = 14;
spec->channels = rf_vals;
} else if (rt2x00_rf(&rt2x00dev->chip, RF2850) ||
@@ -2624,7 +2914,9 @@ static int rt2800pci_probe_hw(struct rt2
/*
* This device requires firmware.
*/
- __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
+ if (!rt2x00_rt(&rt2x00dev->chip, RT2880) &&
+ !rt2x00_rt(&rt2x00dev->chip, RT3052))
+ __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
if (!modparam_nohwcrypt)
__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
--- a/drivers/net/wireless/rt2x00/rt2800pci.h
+++ b/drivers/net/wireless/rt2x00/rt2800pci.h
@@ -36,7 +36,8 @@
* RF2750 2.4G/5G 1T2R
* RF3020 2.4G 1T1R
* RF2020 2.4G B/G
- * RF3052 2.4G 2T2R
+ * RF3021 2.4G 1T2R
+ * RF3022 2.4G 2T2R
*/
#define RF2820 0x0001
#define RF2850 0x0002
@@ -44,7 +45,8 @@
#define RF2750 0x0004
#define RF3020 0x0005
#define RF2020 0x0006
-#define RF3052 0x0008
+#define RF3021 0x0007
+#define RF3022 0x0008
/*
* RT2860 version
@@ -373,6 +375,15 @@
#define PBF_DBG 0x043c
/*
+ * RF registers
+ */
+#define RF_CSR_CFG 0x0500
+#define RF_CSR_CFG_DATA FIELD32(0x000000ff)
+#define RF_CSR_CFG_REGNUM FIELD32(0x00001f00)
+#define RF_CSR_CFG_WRITE FIELD32(0x00010000)
+#define RF_CSR_CFG_BUSY FIELD32(0x00020000)
+
+/*
* MAC Control/Status Registers(CSR).
* Some values are set in TU, whereas 1 TU == 1024 us.
*/
@@ -1465,6 +1476,48 @@ struct mac_iveiv_entry {
* BBP 3: RX Antenna
*/
#define BBP3_RX_ANTENNA FIELD8(0x18)
+#define BBP3_HT40_PLUS FIELD8(0x20)
+
+/*
+ * BBP 4: Bandwidth
+ */
+#define BBP4_TX_BF FIELD8(0x01)
+#define BBP4_BANDWIDTH FIELD8(0x18)
+
+/*
+ * RFCSR registers
+ * The wordsize of the RFCSR is 8 bits.
+ */
+
+/*
+ * RFCSR 6:
+ */
+#define RFCSR6_R FIELD8(0x03)
+
+/*
+ * RFCSR 7:
+ */
+#define RFCSR7_RF_TUNING FIELD8(0x01)
+
+/*
+ * RFCSR 12:
+ */
+#define RFCSR12_TX_POWER FIELD8(0x1f)
+
+/*
+ * RFCSR 22:
+ */
+#define RFCSR22_BASEBAND_LOOPBACK FIELD8(0x01)
+
+/*
+ * RFCSR 23:
+ */
+#define RFCSR23_FREQ_OFFSET FIELD8(0x7f)
+
+/*
+ * RFCSR 30:
+ */
+#define RFCSR30_RF_CALIBRATION FIELD8(0x80)
/*
* RF registers

@ -1,21 +0,0 @@
From 89950075234deb1f98ff52b225487ffc5b8199b0 Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Sun, 8 Mar 2009 16:47:28 +0100
Subject: [PATCH] rt2x00: Fix fill_rxdone (rt2800pci)
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800pci.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -2037,7 +2037,7 @@ static void rt2800pci_fill_rxdone(struct
/*
* Remove TXWI descriptor from start of buffer.
*/
- skb_pull(entry->skb, TXWI_DESC_SIZE);
+ skb_pull(entry->skb, RXWI_DESC_SIZE);
skb_trim(entry->skb, rxdesc->size);
}

@ -0,0 +1,136 @@
From e6cbd7e05f7c1fe0a737526d20f39b4a52e03ae8 Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Tue, 17 Mar 2009 14:01:29 +0100
Subject: [PATCH] rt2x00: Fix compile errors for SoC
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800pci.c | 37 +++++++++++++++----------------
1 files changed, 18 insertions(+), 19 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -3186,7 +3186,7 @@ MODULE_LICENSE("GPL");
#define WSOC_RT_CHIPSET RT3052
#endif /* CONFIG_RALINK_RT305X */
-static void rt2800soc_free_reg(struct rt2x00_dev *rt2x00dev)
+static void rt2x00soc_free_reg(struct rt2x00_dev *rt2x00dev)
{
kfree(rt2x00dev->rf);
rt2x00dev->rf = NULL;
@@ -3195,7 +3195,7 @@ static void rt2800soc_free_reg(struct rt
rt2x00dev->eeprom = NULL;
}
-static int rt2800soc_alloc_reg(struct rt2x00_dev *rt2x00dev)
+static int rt2x00soc_alloc_reg(struct rt2x00_dev *rt2x00dev)
{
struct platform_device *pdev = to_platform_device(rt2x00dev->dev);
struct resource *res;
@@ -3219,14 +3219,14 @@ static int rt2800soc_alloc_reg(struct rt
exit:
ERROR_PROBE("Failed to allocate registers.\n");
- rt2800soc_free_reg(rt2x00dev);
+ rt2x00soc_free_reg(rt2x00dev);
return -ENOMEM;
}
-static int rt2800soc_probe(struct platform_device *pdev)
+static int rt2x00soc_probe(struct platform_device *pdev)
{
- struct rt2x00_ops *ops = (struct rt2x00_ops *)pdev->driver->p;
+ const struct rt2x00_ops *ops = &rt2800pci_ops;
struct ieee80211_hw *hw;
struct rt2x00_dev *rt2x00dev;
int retval;
@@ -3248,7 +3248,7 @@ static int rt2800soc_probe(struct platfo
rt2x00_set_chip_rt(rt2x00dev, WSOC_RT_CHIPSET);
- retval = rt2800soc_alloc_reg(rt2x00dev);
+ retval = rt2x00soc_alloc_reg(rt2x00dev);
if (retval)
goto exit_free_device;
@@ -3259,7 +3259,7 @@ static int rt2800soc_probe(struct platfo
return 0;
exit_free_reg:
- rt2800soc_free_reg(rt2x00dev);
+ rt2x00soc_free_reg(rt2x00dev);
exit_free_device:
ieee80211_free_hw(hw);
@@ -3267,7 +3267,7 @@ exit_free_device:
return retval;
}
-static int rt2800soc_remove(struct platform_device *pdev)
+static int rt2x00soc_remove(struct platform_device *pdev)
{
struct ieee80211_hw *hw = platform_get_drvdata(pdev);
struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -3276,16 +3276,16 @@ static int rt2800soc_remove(struct platf
* Free all allocated data.
*/
rt2x00lib_remove_dev(rt2x00dev);
- rt2800soc_free_reg(rt2x00dev);
+ rt2x00soc_free_reg(rt2x00dev);
ieee80211_free_hw(hw);
return 0;
}
#ifdef CONFIG_PM
-int rt2x00soc_suspend(struct device *dev, pm_message_t state)
+int rt2x00soc_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct ieee80211_hw *hw = dev_get_drvdata(dev);
+ struct ieee80211_hw *hw = platform_get_drvdata(pdev);
struct rt2x00_dev *rt2x00dev = hw->priv;
int retval;
@@ -3293,14 +3293,14 @@ int rt2x00soc_suspend(struct device *dev
if (retval)
return retval;
- rt2800soc_free_reg(rt2x00dev);
+ rt2x00soc_free_reg(rt2x00dev);
return 0;
}
-int rt2x00soc_resume(struct device *dev)
+int rt2x00soc_resume(struct platform_device *pdev)
{
- struct ieee80211_hw *hw = dev_get_drvdata(dev);
+ struct ieee80211_hw *hw = platform_get_drvdata(pdev);
struct rt2x00_dev *rt2x00dev = hw->priv;
int retval;
@@ -3315,7 +3315,7 @@ int rt2x00soc_resume(struct device *dev)
return 0;
exit_free_reg:
- rt2x00pci_free_reg(rt2x00dev);
+ rt2x00soc_free_reg(rt2x00dev);
return retval;
}
@@ -3326,10 +3326,9 @@ static struct platform_driver rt2800soc_
.name = "rt2800_wmac",
.owner = THIS_MODULE,
.mod_name = KBUILD_MODNAME,
- .p = &rt2800pci_ops;
- }
- .probe = rt2800soc_probe,
- .remove = __devexit_p(rt2800soc_remove),
+ },
+ .probe = rt2x00soc_probe,
+ .remove = __devexit_p(rt2x00soc_remove),
.suspend = rt2x00soc_suspend,
.resume = rt2x00soc_resume,
};

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -1024,6 +1024,9 @@ static void ath_unregister_led(struct at
@@ -1031,6 +1031,9 @@ static void ath_unregister_led(struct at
static void ath_deinit_leds(struct ath_softc *sc)
{
@ -10,7 +10,7 @@
cancel_delayed_work_sync(&sc->ath_led_blink_work);
ath_unregister_led(&sc->assoc_led);
sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
@@ -1038,6 +1041,9 @@ static void ath_init_leds(struct ath_sof
@@ -1045,6 +1048,9 @@ static void ath_init_leds(struct ath_sof
char *trigger;
int ret;

@ -1,11 +1,11 @@
--- a/config.mk
+++ b/config.mk
@@ -111,7 +111,7 @@ ifneq ($(CONFIG_PCI),)
@@ -125,7 +125,7 @@ ifneq ($(CONFIG_PCI),)
CONFIG_ATH5K=m
# CONFIG_ATH5K_DEBUG is not set
# CONFIG_ATH5K_DEBUG=y
CONFIG_ATH9K=m
-# CONFIG_ATH9K_DEBUG is not set
-# CONFIG_ATH9K_DEBUG=y
+CONFIG_ATH9K_DEBUG=y
CONFIG_IWLWIFI=m
# CONFIG_IWLWIFI=m

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -494,11 +494,18 @@ static int ath9k_hw_init_macaddr(struct
@@ -513,11 +513,18 @@ static int ath9k_hw_init_macaddr(struct
ah->macaddr[2 * i] = eeval >> 8;
ah->macaddr[2 * i + 1] = eeval & 0xff;
}

Loading…
Cancel
Save