summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ralink/rt2x00
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ralink/rt2x00')
-rw-r--r--drivers/net/wireless/ralink/rt2x00/Kconfig269
-rw-r--r--drivers/net/wireless/ralink/rt2x00/Makefile25
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2400pci.c1850
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2400pci.h961
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2500pci.c2148
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2500pci.h1235
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2500usb.c2001
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2500usb.h855
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800.h2986
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800lib.c8021
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800lib.h232
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800mmio.c871
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800mmio.h163
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800pci.c471
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800pci.h42
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800soc.c260
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800usb.c1462
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800usb.h110
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00.h1478
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00config.c285
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00crypto.c256
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00debug.c800
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00debug.h69
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00dev.c1549
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00dump.h127
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00firmware.c129
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00leds.c244
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00leds.h44
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00lib.h468
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00link.c492
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00mac.c846
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00mmio.c212
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00mmio.h117
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00pci.c221
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00pci.h49
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00queue.c1290
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00queue.h686
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00reg.h277
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00soc.c160
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00soc.h40
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00usb.c884
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00usb.h424
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt61pci.c3111
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt61pci.h1500
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt73usb.c2548
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt73usb.h1079
46 files changed, 43347 insertions, 0 deletions
diff --git a/drivers/net/wireless/ralink/rt2x00/Kconfig b/drivers/net/wireless/ralink/rt2x00/Kconfig
new file mode 100644
index 000000000000..de62f5dcb62f
--- /dev/null
+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
@@ -0,0 +1,269 @@
+menuconfig RT2X00
+ tristate "Ralink driver support"
+ depends on MAC80211 && HAS_DMA
+ ---help---
+ This will enable the support for the Ralink drivers,
+ developed in the rt2x00 project <http://rt2x00.serialmonkey.com>.
+
+ These drivers make use of the mac80211 stack.
+
+ When building one of the individual drivers, the rt2x00 library
+ will also be created. That library (when the driver is built as
+ a module) will be called rt2x00lib.
+
+ Additionally PCI and USB libraries will also be build depending
+ on the types of drivers being selected, these libraries will be
+ called rt2x00pci and rt2x00usb.
+
+if RT2X00
+
+config RT2400PCI
+ tristate "Ralink rt2400 (PCI/PCMCIA) support"
+ depends on PCI
+ select RT2X00_LIB_MMIO
+ select RT2X00_LIB_PCI
+ select EEPROM_93CX6
+ ---help---
+ This adds support for rt2400 wireless chipset family.
+ Supported chips: RT2460.
+
+ When compiled as a module, this driver will be called rt2400pci.
+
+config RT2500PCI
+ tristate "Ralink rt2500 (PCI/PCMCIA) support"
+ depends on PCI
+ select RT2X00_LIB_MMIO
+ select RT2X00_LIB_PCI
+ select EEPROM_93CX6
+ ---help---
+ This adds support for rt2500 wireless chipset family.
+ Supported chips: RT2560.
+
+ When compiled as a module, this driver will be called rt2500pci.
+
+config RT61PCI
+ tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support"
+ depends on PCI
+ select RT2X00_LIB_PCI
+ select RT2X00_LIB_MMIO
+ select RT2X00_LIB_FIRMWARE
+ select RT2X00_LIB_CRYPTO
+ select CRC_ITU_T
+ select EEPROM_93CX6
+ ---help---
+ This adds support for rt2501 wireless chipset family.
+ Supported chips: RT2561, RT2561S & RT2661.
+
+ When compiled as a module, this driver will be called rt61pci.
+
+config RT2800PCI
+ tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support"
+ depends on PCI
+ select RT2800_LIB
+ select RT2800_LIB_MMIO
+ select RT2X00_LIB_MMIO
+ select RT2X00_LIB_PCI
+ select RT2X00_LIB_FIRMWARE
+ select RT2X00_LIB_CRYPTO
+ select CRC_CCITT
+ select EEPROM_93CX6
+ ---help---
+ This adds support for rt27xx/rt28xx/rt30xx wireless chipset family.
+ Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890, RT3052,
+ RT3090, RT3091 & RT3092
+
+ When compiled as a module, this driver will be called "rt2800pci.ko".
+
+if RT2800PCI
+
+config RT2800PCI_RT33XX
+ bool "rt2800pci - Include support for rt33xx devices"
+ default y
+ ---help---
+ This adds support for rt33xx wireless chipset family to the
+ rt2800pci driver.
+ Supported chips: RT3390
+
+config RT2800PCI_RT35XX
+ bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)"
+ default y
+ ---help---
+ This adds support for rt35xx wireless chipset family to the
+ rt2800pci driver.
+ Supported chips: RT3060, RT3062, RT3562, RT3592
+
+
+config RT2800PCI_RT53XX
+ bool "rt2800pci - Include support for rt53xx devices (EXPERIMENTAL)"
+ default y
+ ---help---
+ This adds support for rt53xx wireless chipset family to the
+ rt2800pci driver.
+ Supported chips: RT5390
+
+config RT2800PCI_RT3290
+ bool "rt2800pci - Include support for rt3290 devices (EXPERIMENTAL)"
+ default y
+ ---help---
+ This adds support for rt3290 wireless chipset family to the
+ rt2800pci driver.
+ Supported chips: RT3290
+endif
+
+config RT2500USB
+ tristate "Ralink rt2500 (USB) support"
+ depends on USB
+ select RT2X00_LIB_USB
+ select RT2X00_LIB_CRYPTO
+ ---help---
+ This adds support for rt2500 wireless chipset family.
+ Supported chips: RT2571 & RT2572.
+
+ When compiled as a module, this driver will be called rt2500usb.
+
+config RT73USB
+ tristate "Ralink rt2501/rt73 (USB) support"
+ depends on USB
+ select RT2X00_LIB_USB
+ select RT2X00_LIB_FIRMWARE
+ select RT2X00_LIB_CRYPTO
+ select CRC_ITU_T
+ ---help---
+ This adds support for rt2501 wireless chipset family.
+ Supported chips: RT2571W, RT2573 & RT2671.
+
+ When compiled as a module, this driver will be called rt73usb.
+
+config RT2800USB
+ tristate "Ralink rt27xx/rt28xx/rt30xx (USB) support"
+ depends on USB
+ select RT2800_LIB
+ select RT2X00_LIB_USB
+ select RT2X00_LIB_FIRMWARE
+ select RT2X00_LIB_CRYPTO
+ select CRC_CCITT
+ ---help---
+ This adds support for rt27xx/rt28xx/rt30xx wireless chipset family.
+ Supported chips: RT2770, RT2870 & RT3070, RT3071 & RT3072
+
+ When compiled as a module, this driver will be called "rt2800usb.ko".
+
+if RT2800USB
+
+config RT2800USB_RT33XX
+ bool "rt2800usb - Include support for rt33xx devices"
+ default y
+ ---help---
+ This adds support for rt33xx wireless chipset family to the
+ rt2800usb driver.
+ Supported chips: RT3370
+
+config RT2800USB_RT35XX
+ bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)"
+ default y
+ ---help---
+ This adds support for rt35xx wireless chipset family to the
+ rt2800usb driver.
+ Supported chips: RT3572
+
+config RT2800USB_RT3573
+ bool "rt2800usb - Include support for rt3573 devices (EXPERIMENTAL)"
+ ---help---
+ This enables support for RT3573 chipset based wireless USB devices
+ in the rt2800usb driver.
+
+config RT2800USB_RT53XX
+ bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)"
+ ---help---
+ This adds support for rt53xx wireless chipset family to the
+ rt2800usb driver.
+ Supported chips: RT5370
+
+config RT2800USB_RT55XX
+ bool "rt2800usb - Include support for rt55xx devices (EXPERIMENTAL)"
+ ---help---
+ This adds support for rt55xx wireless chipset family to the
+ rt2800usb driver.
+ Supported chips: RT5572
+
+config RT2800USB_UNKNOWN
+ bool "rt2800usb - Include support for unknown (USB) devices"
+ default n
+ ---help---
+ This adds support for rt2800usb devices that are known to
+ have a rt28xx family compatible chipset, but for which the exact
+ chipset is unknown.
+
+ Support status for these devices is unknown, and enabling these
+ devices may or may not work.
+
+endif
+
+config RT2800SOC
+ tristate "Ralink WiSoC support"
+ depends on SOC_RT288X || SOC_RT305X
+ select RT2X00_LIB_SOC
+ select RT2X00_LIB_MMIO
+ select RT2X00_LIB_CRYPTO
+ select RT2X00_LIB_FIRMWARE
+ select RT2800_LIB
+ select RT2800_LIB_MMIO
+ ---help---
+ This adds support for Ralink WiSoC devices.
+ Supported chips: RT2880, RT3050, RT3052, RT3350, RT3352.
+
+ When compiled as a module, this driver will be called rt2800soc.
+
+
+config RT2800_LIB
+ tristate
+
+config RT2800_LIB_MMIO
+ tristate
+ select RT2X00_LIB_MMIO
+ select RT2800_LIB
+
+config RT2X00_LIB_MMIO
+ tristate
+
+config RT2X00_LIB_PCI
+ tristate
+ select RT2X00_LIB
+
+config RT2X00_LIB_SOC
+ tristate
+ select RT2X00_LIB
+
+config RT2X00_LIB_USB
+ tristate
+ select RT2X00_LIB
+
+config RT2X00_LIB
+ tristate
+
+config RT2X00_LIB_FIRMWARE
+ bool
+ select FW_LOADER
+
+config RT2X00_LIB_CRYPTO
+ bool
+
+config RT2X00_LIB_LEDS
+ bool
+ default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n)
+
+config RT2X00_LIB_DEBUGFS
+ bool "Ralink debugfs support"
+ depends on RT2X00_LIB && MAC80211_DEBUGFS
+ ---help---
+ Enable creation of debugfs files for the rt2x00 drivers.
+ These debugfs files support both reading and writing of the
+ most important register types of the rt2x00 hardware.
+
+config RT2X00_DEBUG
+ bool "Ralink debug output"
+ depends on RT2X00_LIB
+ ---help---
+ Enable debugging output for all rt2x00 modules
+
+endif
diff --git a/drivers/net/wireless/ralink/rt2x00/Makefile b/drivers/net/wireless/ralink/rt2x00/Makefile
new file mode 100644
index 000000000000..24a66015a495
--- /dev/null
+++ b/drivers/net/wireless/ralink/rt2x00/Makefile
@@ -0,0 +1,25 @@
+rt2x00lib-y += rt2x00dev.o
+rt2x00lib-y += rt2x00mac.o
+rt2x00lib-y += rt2x00config.o
+rt2x00lib-y += rt2x00queue.o
+rt2x00lib-y += rt2x00link.o
+rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) += rt2x00debug.o
+rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o
+rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
+rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o
+
+obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o
+obj-$(CONFIG_RT2X00_LIB_MMIO) += rt2x00mmio.o
+obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o
+obj-$(CONFIG_RT2X00_LIB_SOC) += rt2x00soc.o
+obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o
+obj-$(CONFIG_RT2800_LIB) += rt2800lib.o
+obj-$(CONFIG_RT2800_LIB_MMIO) += rt2800mmio.o
+obj-$(CONFIG_RT2400PCI) += rt2400pci.o
+obj-$(CONFIG_RT2500PCI) += rt2500pci.o
+obj-$(CONFIG_RT61PCI) += rt61pci.o
+obj-$(CONFIG_RT2800PCI) += rt2800pci.o
+obj-$(CONFIG_RT2500USB) += rt2500usb.o
+obj-$(CONFIG_RT73USB) += rt73usb.o
+obj-$(CONFIG_RT2800USB) += rt2800usb.o
+obj-$(CONFIG_RT2800SOC) += rt2800soc.o
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
new file mode 100644
index 000000000000..9a3966cd6fbe
--- /dev/null
+++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
@@ -0,0 +1,1850 @@
+/*
+ Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
+ <http://rt2x00.serialmonkey.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ Module: rt2400pci
+ Abstract: rt2400pci device specific routines.
+ Supported chipsets: RT2460.
+ */
+
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/eeprom_93cx6.h>
+#include <linux/slab.h>
+
+#include "rt2x00.h"
+#include "rt2x00mmio.h"
+#include "rt2x00pci.h"
+#include "rt2400pci.h"
+
+/*
+ * Register access.
+ * All access to the CSR registers will go through the methods
+ * rt2x00mmio_register_read and rt2x00mmio_register_write.
+ * BBP and RF register require indirect register access,
+ * and use the CSR registers BBPCSR and RFCSR to achieve this.
+ * These indirect registers work with busy bits,
+ * and we will try maximal REGISTER_BUSY_COUNT times to access
+ * the register while taking a REGISTER_BUSY_DELAY us delay
+ * between each attempt. When the busy bit is still set at that time,
+ * the access attempt is considered to have failed,
+ * and we will print an error.
+ */
+#define WAIT_FOR_BBP(__dev, __reg) \
+ rt2x00mmio_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg))
+#define WAIT_FOR_RF(__dev, __reg) \
+ rt2x00mmio_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg))
+
+static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, const u8 value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the BBP becomes available, afterwards we
+ * can safely write the new data into the register.
+ */
+ if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, BBPCSR_VALUE, value);
+ rt2x00_set_field32(&reg, BBPCSR_REGNUM, word);
+ rt2x00_set_field32(&reg, BBPCSR_BUSY, 1);
+ rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1);
+
+ rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg);
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, u8 *value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the BBP 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_BBP(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, BBPCSR_REGNUM, word);
+ rt2x00_set_field32(&reg, BBPCSR_BUSY, 1);
+ rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 0);
+
+ rt2x00mmio_register_write(rt2x00dev, BBPCSR, reg);
+
+ WAIT_FOR_BBP(rt2x00dev, &reg);
+ }
+
+ *value = rt2x00_get_field32(reg, BBPCSR_VALUE);
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int word, const u32 value)
+{
+ u32 reg;
+
+ mutex_lock(&rt2x00dev->csr_mutex);
+
+ /*
+ * Wait until the RF becomes available, afterwards we
+ * can safely write the new data into the register.
+ */
+ if (WAIT_FOR_RF(rt2x00dev, &reg)) {
+ reg = 0;
+ rt2x00_set_field32(&reg, RFCSR_VALUE, value);
+ rt2x00_set_field32(&reg, RFCSR_NUMBER_OF_BITS, 20);
+ rt2x00_set_field32(&reg, RFCSR_IF_SELECT, 0);
+ rt2x00_set_field32(&reg, RFCSR_BUSY, 1);
+
+ rt2x00mmio_register_write(rt2x00dev, RFCSR, reg);
+ rt2x00_rf_write(rt2x00dev, word, value);
+ }
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
+{
+ struct rt2x00_dev *rt2x00dev = eeprom->data;
+ u32 reg;
+
+ rt2x00mmio_register_read(rt2x00dev, CSR21, &reg);
+
+ eeprom->reg_data_in = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_IN);
+ eeprom->reg_data_out = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_OUT);
+ eeprom->reg_data_clock =
+ !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_CLOCK);
+ eeprom->reg_chip_select =
+ !!rt2x00_get_field32(reg, CSR21_EEPROM_CHIP_SELECT);
+}
+
+static void rt2400pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
+{
+ struct rt2x00_dev *rt2x00dev = eeprom->data;
+ u32 reg = 0;
+
+ rt2x00_set_field32(&reg, CSR21_EEPROM_DATA_IN, !!eeprom->reg_data_in);
+ rt2x00_set_field32(&reg, CSR21_EEPROM_DATA_OUT, !!eeprom->reg_data_out);
+ rt2x00_set_field32(&reg, CSR21_EEPROM_DATA_CLOCK,
+ !!eeprom->reg_data_clock);
+ rt2x00_set_field32(&reg, CSR21_EEPROM_CHIP_SELECT,
+ !!eeprom->reg_chip_select);
+
+ rt2x00mmio_register_write(rt2x00dev, CSR21, reg);
+}
+
+#ifdef CONFIG_RT2X00_LIB_DEBUGFS
+static const struct rt2x00debug rt2400pci_rt2x00debug = {
+ .owner = THIS_MODULE,
+ .csr = {
+ .read = rt2x00mmio_register_read,
+ .write = rt2x00mmio_register_write,
+ .flags = RT2X00DEBUGFS_OFFSET,
+ .word_base = CSR_REG_BASE,
+ .word_size = sizeof(u32),
+ .word_count = CSR_REG_SIZE / sizeof(u32),
+ },
+ .eeprom = {
+ .read = rt2x00_eeprom_read,
+ .write = rt2x00_eeprom_write,
+ .word_base = EEPROM_BASE,
+ .word_size = sizeof(u16),
+ .word_count = EEPROM_SIZE / sizeof(u16),
+ },
+ .bbp = {
+ .read = rt2400pci_bbp_read,
+ .write = rt2400pci_bbp_write,
+ .word_base = BBP_BASE,
+ .word_size = sizeof(u8),
+ .word_count = BBP_SIZE / sizeof(u8),
+ },
+ .rf = {
+ .read = rt2x00_rf_read,
+ .write = rt2400pci_rf_write,
+ .word_base = RF_BASE,
+ .word_size = sizeof(u32),
+ .word_count = RF_SIZE / sizeof(u32),
+ },
+};
+#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+
+static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+
+ rt2x00mmio_register_read(rt2x00dev, GPIOCSR, &reg);
+ return rt2x00_get_field32(reg, GPIOCSR_VAL0);
+}
+
+#ifdef CONFIG_RT2X00_LIB_LEDS
+static void rt2400pci_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct rt2x00_led *led =
+ container_of(led_cdev, struct rt2x00_led, led_dev);
+ unsigned int enabled = brightness != LED_OFF;
+ u32 reg;
+
+ rt2x00mmio_register_read(led->rt2x00dev, LEDCSR, &reg);
+
+ if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC)
+ rt2x00_set_field32(&reg, LEDCSR_LINK, enabled);
+ else if (led->type == LED_TYPE_ACTIVITY)
+ rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, enabled);
+
+ rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg);
+}
+
+static int rt2400pci_blink_set(struct led_classdev *led_cdev,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ struct rt2x00_led *led =
+ container_of(led_cdev, struct rt2x00_led, led_dev);
+ u32 reg;
+
+ rt2x00mmio_register_read(led->rt2x00dev, LEDCSR, &reg);
+ rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, *delay_on);
+ rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, *delay_off);
+ rt2x00mmio_register_write(led->rt2x00dev, LEDCSR, reg);
+
+ return 0;
+}
+
+static void rt2400pci_init_led(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_led *led,
+ enum led_type type)
+{
+ led->rt2x00dev = rt2x00dev;
+ led->type = type;
+ led->led_dev.brightness_set = rt2400pci_brightness_set;
+ led->led_dev.blink_set = rt2400pci_blink_set;
+ led->flags = LED_INITIALIZED;
+}
+#endif /* CONFIG_RT2X00_LIB_LEDS */
+
+/*
+ * Configuration handlers.
+ */
+static void rt2400pci_config_filter(struct rt2x00_dev *rt2x00dev,
+ const unsigned int filter_flags)
+{
+ u32 reg;
+
+ /*
+ * Start configuration steps.
+ * Note that the version error will always be dropped
+ * since there is no filter for it at this time.
+ */
+ rt2x00mmio_register_read(rt2x00dev, RXCSR0, &reg);
+ rt2x00_set_field32(&reg, RXCSR0_DROP_CRC,
+ !(filter_flags & FIF_FCSFAIL));
+ rt2x00_set_field32(&reg, RXCSR0_DROP_PHYSICAL,
+ !(filter_flags & FIF_PLCPFAIL));
+ rt2x00_set_field32(&reg, RXCSR0_DROP_CONTROL,
+ !(filter_flags & FIF_CONTROL));
+ rt2x00_set_field32(&reg, RXCSR0_DROP_NOT_TO_ME, 1);
+ rt2x00_set_field32(&reg, RXCSR0_DROP_TODS,
+ !rt2x00dev->intf_ap_count);
+ rt2x00_set_field32(&reg, RXCSR0_DROP_VERSION_ERROR, 1);
+ rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg);
+}
+
+static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_intf *intf,
+ struct rt2x00intf_conf *conf,
+ const unsigned int flags)
+{
+ unsigned int bcn_preload;
+ u32 reg;
+
+ if (flags & CONFIG_UPDATE_TYPE) {
+ /*
+ * Enable beacon config
+ */
+ bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
+ rt2x00mmio_register_read(rt2x00dev, BCNCSR1, &reg);
+ rt2x00_set_field32(&reg, BCNCSR1_PRELOAD, bcn_preload);
+ rt2x00mmio_register_write(rt2x00dev, BCNCSR1, reg);
+
+ /*
+ * Enable synchronisation.
+ */
+ rt2x00mmio_register_read(rt2x00dev, CSR14, &reg);
+ rt2x00_set_field32(&reg, CSR14_TSF_SYNC, conf->sync);
+ rt2x00mmio_register_write(rt2x00dev, CSR14, reg);
+ }
+
+ if (flags & CONFIG_UPDATE_MAC)
+ rt2x00mmio_register_multiwrite(rt2x00dev, CSR3,
+ conf->mac, sizeof(conf->mac));
+
+ if (flags & CONFIG_UPDATE_BSSID)
+ rt2x00mmio_register_multiwrite(rt2x00dev, CSR5,
+ conf->bssid,
+ sizeof(conf->bssid));
+}
+
+static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_erp *erp,
+ u32 changed)
+{
+ int preamble_mask;
+ u32 reg;
+
+ /*
+ * When short preamble is enabled, we should set bit 0x08
+ */
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ preamble_mask = erp->short_preamble << 3;
+
+ rt2x00mmio_register_read(rt2x00dev, TXCSR1, &reg);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x1ff);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0x13a);
+ rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
+ rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
+ rt2x00mmio_register_write(rt2x00dev, TXCSR1, reg);
+
+ rt2x00mmio_register_read(rt2x00dev, ARCSR2, &reg);
+ rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
+ rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 10));
+ rt2x00mmio_register_write(rt2x00dev, ARCSR2, reg);
+
+ rt2x00mmio_register_read(rt2x00dev, ARCSR3, &reg);
+ rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 20));
+ rt2x00mmio_register_write(rt2x00dev, ARCSR3, reg);
+
+ rt2x00mmio_register_read(rt2x00dev, ARCSR4, &reg);
+ rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 55));
+ rt2x00mmio_register_write(rt2x00dev, ARCSR4, reg);
+
+ rt2x00mmio_register_read(rt2x00dev, ARCSR5, &reg);
+ rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
+ rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
+ rt2x00_set_field32(&reg, ARCSR2_LENGTH,
+ GET_DURATION(ACK_SIZE, 110));
+ rt2x00mmio_register_write(rt2x00dev, ARCSR5, reg);
+ }
+
+ if (changed & BSS_CHANGED_BASIC_RATES)
+ rt2x00mmio_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
+
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ rt2x00mmio_register_read(rt2x00dev, CSR11, &reg);
+ rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
+ rt2x00mmio_register_write(rt2x00dev, CSR11, reg);
+
+ rt2x00mmio_register_read(rt2x00dev, CSR18, &reg);
+ rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
+ rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
+ rt2x00mmio_register_write(rt2x00dev, CSR18, reg);
+
+ rt2x00mmio_register_read(rt2x00dev, CSR19, &reg);
+ rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
+ rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
+ rt2x00mmio_register_write(rt2x00dev, CSR19, reg);
+ }
+
+ if (changed & BSS_CHANGED_BEACON_INT) {
+ rt2x00mmio_register_read(rt2x00dev, CSR12, &reg);
+ rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL,
+ erp->beacon_int * 16);
+ rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION,
+ erp->beacon_int * 16);
+ rt2x00mmio_register_write(rt2x00dev, CSR12, reg);
+ }
+}
+
+static void rt2400pci_config_ant(struct rt2x00_dev *rt2x00dev,
+ struct antenna_setup *ant)
+{
+ u8 r1;
+ u8 r4;
+
+ /*
+ * We should never come here because rt2x00lib is supposed
+ * to catch this and send us the correct antenna explicitely.
+ */
+ BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
+ ant->tx == ANTENNA_SW_DIVERSITY);
+
+ rt2400pci_bbp_read(rt2x00dev, 4, &r4);
+ rt2400pci_bbp_read(rt2x00dev, 1, &r1);
+
+ /*
+ * Configure the TX antenna.
+ */
+ switch (ant->tx) {
+ case ANTENNA_HW_DIVERSITY:
+ rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 1);
+ break;
+ case ANTENNA_A:
+ rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0);
+ break;
+ case ANTENNA_B:
+ default:
+ rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2);