diff options
| author | Ivo van Doorn <IvDoorn@gmail.com> | 2007-09-25 20:57:13 -0400 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:51:39 -0400 |
| commit | 95ea36275f3c9a1d3d04c217b4b576c657c4e70e (patch) | |
| tree | 55477b946a46aa871a087857a1dc698d74fe79d2 | |
| parent | b481de9ca074528fe8c429604e2777db8b89806a (diff) | |
[RT2x00]: add driver for Ralink wireless hardware
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
31 files changed, 21174 insertions, 0 deletions
| @@ -665,6 +665,11 @@ D: Minor updates to SCSI types, added /proc/pid/maps protection | |||
| 665 | S: (ask for current address) | 665 | S: (ask for current address) |
| 666 | S: USA | 666 | S: USA |
| 667 | 667 | ||
| 668 | N: Robin Cornelius | ||
| 669 | E: robincornelius@users.sourceforge.net | ||
| 670 | D: Ralink rt2x00 WLAN driver | ||
| 671 | S: Cornwall, U.K. | ||
| 672 | |||
| 668 | N: Mark Corner | 673 | N: Mark Corner |
| 669 | E: mcorner@umich.edu | 674 | E: mcorner@umich.edu |
| 670 | W: http://www.eecs.umich.edu/~mcorner/ | 675 | W: http://www.eecs.umich.edu/~mcorner/ |
| @@ -679,6 +684,11 @@ D: Kernel module SMART utilities | |||
| 679 | S: Santa Cruz, California | 684 | S: Santa Cruz, California |
| 680 | S: USA | 685 | S: USA |
| 681 | 686 | ||
| 687 | N: Luis Correia | ||
| 688 | E: lfcorreia@users.sf.net | ||
| 689 | D: Ralink rt2x00 WLAN driver | ||
| 690 | S: Belas, Portugal | ||
| 691 | |||
| 682 | N: Alan Cox | 692 | N: Alan Cox |
| 683 | W: http://www.linux.org.uk/diary/ | 693 | W: http://www.linux.org.uk/diary/ |
| 684 | D: Linux Networking (0.99.10->2.0.29) | 694 | D: Linux Networking (0.99.10->2.0.29) |
| @@ -833,6 +843,12 @@ S: Lancs | |||
| 833 | S: PR4 6AX | 843 | S: PR4 6AX |
| 834 | S: United Kingdom | 844 | S: United Kingdom |
| 835 | 845 | ||
| 846 | N: Ivo van Doorn | ||
| 847 | E: IvDoorn@gmail.com | ||
| 848 | W: http://www.mendiosus.nl | ||
| 849 | D: Ralink rt2x00 WLAN driver | ||
| 850 | S: Haarlem, The Netherlands | ||
| 851 | |||
| 836 | N: John G Dorsey | 852 | N: John G Dorsey |
| 837 | E: john+@cs.cmu.edu | 853 | E: john+@cs.cmu.edu |
| 838 | D: ARM Linux ports to Assabet/Neponset, Spot | 854 | D: ARM Linux ports to Assabet/Neponset, Spot |
| @@ -3517,6 +3533,12 @@ S: Maastrichterweg 63 | |||
| 3517 | S: 5554 GG Valkenswaard | 3533 | S: 5554 GG Valkenswaard |
| 3518 | S: The Netherlands | 3534 | S: The Netherlands |
| 3519 | 3535 | ||
| 3536 | N: Mark Wallis | ||
| 3537 | E: mwallis@serialmonkey.com | ||
| 3538 | W: http://mark.serialmonkey.com | ||
| 3539 | D: Ralink rt2x00 WLAN driver | ||
| 3540 | S: Newcastle, Australia | ||
| 3541 | |||
| 3520 | N: Peter Shaobo Wang | 3542 | N: Peter Shaobo Wang |
| 3521 | E: pwang@mmdcorp.com | 3543 | E: pwang@mmdcorp.com |
| 3522 | W: http://www.mmdcorp.com/pw/linux | 3544 | W: http://www.mmdcorp.com/pw/linux |
| @@ -3651,6 +3673,15 @@ S: Alte Regensburger Str. 11a | |||
| 3651 | S: 93149 Nittenau | 3673 | S: 93149 Nittenau |
| 3652 | S: Germany | 3674 | S: Germany |
| 3653 | 3675 | ||
| 3676 | N: Gertjan van Wingerde | ||
| 3677 | E: gwingerde@home.nl | ||
| 3678 | D: Ralink rt2x00 WLAN driver | ||
| 3679 | D: Minix V2 file-system | ||
| 3680 | D: Misc fixes | ||
| 3681 | S: Geessinkweg 177 | ||
| 3682 | S: 7544 TX Enschede | ||
| 3683 | S: The Netherlands | ||
| 3684 | |||
| 3654 | N: Lars Wirzenius | 3685 | N: Lars Wirzenius |
| 3655 | E: liw@iki.fi | 3686 | E: liw@iki.fi |
| 3656 | D: Linux System Administrator's Guide, author, former maintainer | 3687 | D: Linux System Administrator's Guide, author, former maintainer |
diff --git a/MAINTAINERS b/MAINTAINERS index 934afd3dfa4..6ae2b997526 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -3147,6 +3147,14 @@ M: corey@world.std.com | |||
| 3147 | L: linux-wireless@vger.kernel.org | 3147 | L: linux-wireless@vger.kernel.org |
| 3148 | S: Maintained | 3148 | S: Maintained |
| 3149 | 3149 | ||
| 3150 | RALINK RT2X00 WLAN DRIVER | ||
| 3151 | P: rt2x00 project | ||
| 3152 | L: linux-wireless@vger.kernel.org | ||
| 3153 | L: rt2400-devel@lists.sourceforge.net | ||
| 3154 | W: http://rt2x00.serialmonkey.com/ | ||
| 3155 | S: Maintained | ||
| 3156 | F: drivers/net/wireless/rt2x00/ | ||
| 3157 | |||
| 3150 | RANDOM NUMBER DRIVER | 3158 | RANDOM NUMBER DRIVER |
| 3151 | P: Matt Mackall | 3159 | P: Matt Mackall |
| 3152 | M: mpm@selenic.com | 3160 | M: mpm@selenic.com |
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 085ba132835..f481c757e22 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
| @@ -583,5 +583,6 @@ source "drivers/net/wireless/bcm43xx/Kconfig" | |||
| 583 | source "drivers/net/wireless/b43/Kconfig" | 583 | source "drivers/net/wireless/b43/Kconfig" |
| 584 | source "drivers/net/wireless/b43legacy/Kconfig" | 584 | source "drivers/net/wireless/b43legacy/Kconfig" |
| 585 | source "drivers/net/wireless/zd1211rw/Kconfig" | 585 | source "drivers/net/wireless/zd1211rw/Kconfig" |
| 586 | source "drivers/net/wireless/rt2x00/Kconfig" | ||
| 586 | 587 | ||
| 587 | endmenu | 588 | endmenu |
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 351024f2fe7..a7a15e3509e 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile | |||
| @@ -53,3 +53,4 @@ obj-$(CONFIG_RTL8187) += rtl8187.o | |||
| 53 | obj-$(CONFIG_ADM8211) += adm8211.o | 53 | obj-$(CONFIG_ADM8211) += adm8211.o |
| 54 | 54 | ||
| 55 | obj-$(CONFIG_IWLWIFI) += iwlwifi/ | 55 | obj-$(CONFIG_IWLWIFI) += iwlwifi/ |
| 56 | obj-$(CONFIG_RT2X00) += rt2x00/ | ||
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig new file mode 100644 index 00000000000..da05b1faf60 --- /dev/null +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | config RT2X00 | ||
| 2 | tristate "Ralink driver support" | ||
| 3 | depends on MAC80211 && WLAN_80211 && EXPERIMENTAL | ||
| 4 | ---help--- | ||
| 5 | This will enable the experimental support for the Ralink drivers, | ||
| 6 | developed in the rt2x00 project <http://rt2x00.serialmonkey.com>. | ||
| 7 | |||
| 8 | These drivers will make use of the Devicescape ieee80211 stack. | ||
| 9 | |||
| 10 | When building one of the individual drivers, the rt2x00 library | ||
| 11 | will also be created. That library (when the driver is built as | ||
| 12 | a module) will be called "rt2x00lib.ko". | ||
| 13 | |||
| 14 | config RT2X00_LIB | ||
| 15 | tristate | ||
| 16 | depends on RT2X00 | ||
| 17 | |||
| 18 | config RT2X00_LIB_PCI | ||
| 19 | tristate | ||
| 20 | depends on RT2X00 | ||
| 21 | select RT2X00_LIB | ||
| 22 | |||
| 23 | config RT2X00_LIB_USB | ||
| 24 | tristate | ||
| 25 | depends on RT2X00 | ||
| 26 | select RT2X00_LIB | ||
| 27 | |||
| 28 | config RT2X00_LIB_FIRMWARE | ||
| 29 | boolean | ||
| 30 | depends on RT2X00_LIB | ||
| 31 | select CRC_ITU_T | ||
| 32 | select FW_LOADER | ||
| 33 | |||
| 34 | config RT2X00_LIB_RFKILL | ||
| 35 | boolean | ||
| 36 | depends on RT2X00_LIB | ||
| 37 | select RFKILL | ||
| 38 | select INPUT_POLLDEV | ||
| 39 | |||
| 40 | config RT2400PCI | ||
| 41 | tristate "Ralink rt2400 pci/pcmcia support" | ||
| 42 | depends on RT2X00 && PCI | ||
| 43 | select RT2X00_LIB_PCI | ||
| 44 | select EEPROM_93CX6 | ||
| 45 | ---help--- | ||
| 46 | This is an experimental driver for the Ralink rt2400 wireless chip. | ||
| 47 | |||
| 48 | When compiled as a module, this driver will be called "rt2400pci.ko". | ||
| 49 | |||
| 50 | config RT2400PCI_RFKILL | ||
| 51 | bool "RT2400 rfkill support" | ||
| 52 | depends on RT2400PCI | ||
| 53 | select RT2X00_LIB_RFKILL | ||
| 54 | ---help--- | ||
| 55 | This adds support for integrated rt2400 devices that feature a | ||
| 56 | hardware button to control the radio state. | ||
| 57 | This feature depends on the RF switch subsystem rfkill. | ||
| 58 | |||
| 59 | config RT2500PCI | ||
| 60 | tristate "Ralink rt2500 pci/pcmcia support" | ||
| 61 | depends on RT2X00 && PCI | ||
| 62 | select RT2X00_LIB_PCI | ||
| 63 | select EEPROM_93CX6 | ||
| 64 | ---help--- | ||
| 65 | This is an experimental driver for the Ralink rt2500 wireless chip. | ||
| 66 | |||
| 67 | When compiled as a module, this driver will be called "rt2500pci.ko". | ||
| 68 | |||
| 69 | config RT2500PCI_RFKILL | ||
| 70 | bool "RT2500 rfkill support" | ||
| 71 | depends on RT2500PCI | ||
| 72 | select RT2X00_LIB_RFKILL | ||
| 73 | ---help--- | ||
| 74 | This adds support for integrated rt2500 devices that feature a | ||
| 75 | hardware button to control the radio state. | ||
| 76 | This feature depends on the RF switch subsystem rfkill. | ||
| 77 | |||
| 78 | config RT61PCI | ||
| 79 | tristate "Ralink rt61 pci/pcmcia support" | ||
| 80 | depends on RT2X00 && PCI | ||
| 81 | select RT2X00_LIB_PCI | ||
| 82 | select RT2X00_LIB_FIRMWARE | ||
| 83 | select EEPROM_93CX6 | ||
| 84 | ---help--- | ||
| 85 | This is an experimental driver for the Ralink rt61 wireless chip. | ||
| 86 | |||
| 87 | When compiled as a module, this driver will be called "rt61pci.ko". | ||
| 88 | |||
| 89 | config RT61PCI_RFKILL | ||
| 90 | bool "RT61 rfkill support" | ||
| 91 | depends on RT61PCI | ||
| 92 | select RT2X00_LIB_RFKILL | ||
| 93 | ---help--- | ||
| 94 | This adds support for integrated rt61 devices that feature a | ||
| 95 | hardware button to control the radio state. | ||
| 96 | This feature depends on the RF switch subsystem rfkill. | ||
| 97 | |||
| 98 | config RT2500USB | ||
| 99 | tristate "Ralink rt2500 usb support" | ||
| 100 | depends on RT2X00 && USB | ||
| 101 | select RT2X00_LIB_USB | ||
| 102 | ---help--- | ||
| 103 | This is an experimental driver for the Ralink rt2500 wireless chip. | ||
| 104 | |||
| 105 | When compiled as a module, this driver will be called "rt2500usb.ko". | ||
| 106 | |||
| 107 | config RT73USB | ||
| 108 | tristate "Ralink rt73 usb support" | ||
| 109 | depends on RT2X00 && USB | ||
| 110 | select RT2X00_LIB_USB | ||
| 111 | select RT2X00_LIB_FIRMWARE | ||
| 112 | ---help--- | ||
| 113 | This is an experimental driver for the Ralink rt73 wireless chip. | ||
| 114 | |||
| 115 | When compiled as a module, this driver will be called "rt73usb.ko". | ||
| 116 | |||
| 117 | config RT2X00_LIB_DEBUGFS | ||
| 118 | bool "Ralink debugfs support" | ||
| 119 | depends on RT2X00_LIB && MAC80211_DEBUGFS | ||
| 120 | ---help--- | ||
| 121 | Enable creation of debugfs files for the rt2x00 drivers. | ||
| 122 | These debugfs files support both reading and writing of the | ||
| 123 | most important register types of the rt2x00 devices. | ||
| 124 | |||
| 125 | config RT2X00_DEBUG | ||
| 126 | bool "Ralink debug output" | ||
| 127 | depends on RT2X00_LIB | ||
| 128 | ---help--- | ||
| 129 | Enable debugging output for all rt2x00 modules | ||
| 130 | |||
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile new file mode 100644 index 00000000000..30d654a42ee --- /dev/null +++ b/drivers/net/wireless/rt2x00/Makefile | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | rt2x00lib-objs := rt2x00dev.o rt2x00mac.o rt2x00config.o | ||
| 2 | |||
| 3 | ifeq ($(CONFIG_RT2X00_LIB_DEBUGFS),y) | ||
| 4 | rt2x00lib-objs += rt2x00debug.o | ||
| 5 | endif | ||
| 6 | |||
| 7 | ifeq ($(CONFIG_RT2X00_LIB_RFKILL),y) | ||
| 8 | rt2x00lib-objs += rt2x00rfkill.o | ||
| 9 | endif | ||
| 10 | |||
| 11 | ifeq ($(CONFIG_RT2X00_LIB_FIRMWARE),y) | ||
| 12 | rt2x00lib-objs += rt2x00firmware.o | ||
| 13 | endif | ||
| 14 | |||
| 15 | obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o | ||
| 16 | obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o | ||
| 17 | obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o | ||
| 18 | obj-$(CONFIG_RT2400PCI) += rt2400pci.o | ||
| 19 | obj-$(CONFIG_RT2500PCI) += rt2500pci.o | ||
| 20 | obj-$(CONFIG_RT61PCI) += rt61pci.o | ||
| 21 | obj-$(CONFIG_RT2500USB) += rt2500usb.o | ||
| 22 | obj-$(CONFIG_RT73USB) += rt73usb.o | ||
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c new file mode 100644 index 00000000000..38e2188937c --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
| @@ -0,0 +1,1689 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2400pci | ||
| 23 | Abstract: rt2400pci device specific routines. | ||
| 24 | Supported chipsets: RT2460. | ||
| 25 | */ | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Set enviroment defines for rt2x00.h | ||
| 29 | */ | ||
| 30 | #define DRV_NAME "rt2400pci" | ||
| 31 | |||
| 32 | #include <linux/delay.h> | ||
| 33 | #include <linux/etherdevice.h> | ||
| 34 | #include <linux/init.h> | ||
| 35 | #include <linux/kernel.h> | ||
| 36 | #include <linux/module.h> | ||
| 37 | #include <linux/pci.h> | ||
| 38 | #include <linux/eeprom_93cx6.h> | ||
| 39 | |||
| 40 | #include "rt2x00.h" | ||
| 41 | #include "rt2x00pci.h" | ||
| 42 | #include "rt2400pci.h" | ||
| 43 | |||
| 44 | /* | ||
| 45 | * Register access. | ||
| 46 | * All access to the CSR registers will go through the methods | ||
| 47 | * rt2x00pci_register_read and rt2x00pci_register_write. | ||
| 48 | * BBP and RF register require indirect register access, | ||
| 49 | * and use the CSR registers BBPCSR and RFCSR to achieve this. | ||
| 50 | * These indirect registers work with busy bits, | ||
| 51 | * and we will try maximal REGISTER_BUSY_COUNT times to access | ||
| 52 | * the register while taking a REGISTER_BUSY_DELAY us delay | ||
| 53 | * between each attampt. When the busy bit is still set at that time, | ||
| 54 | * the access attempt is considered to have failed, | ||
| 55 | * and we will print an error. | ||
| 56 | */ | ||
| 57 | static u32 rt2400pci_bbp_check(const struct rt2x00_dev *rt2x00dev) | ||
| 58 | { | ||
| 59 | u32 reg; | ||
| 60 | unsigned int i; | ||
| 61 | |||
| 62 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 63 | rt2x00pci_register_read(rt2x00dev, BBPCSR, ®); | ||
| 64 | if (!rt2x00_get_field32(reg, BBPCSR_BUSY)) | ||
| 65 | break; | ||
| 66 | udelay(REGISTER_BUSY_DELAY); | ||
| 67 | } | ||
| 68 | |||
| 69 | return reg; | ||
| 70 | } | ||
| 71 | |||
| 72 | static void rt2400pci_bbp_write(const struct rt2x00_dev *rt2x00dev, | ||
| 73 | const unsigned int word, const u8 value) | ||
| 74 | { | ||
| 75 | u32 reg; | ||
| 76 | |||
| 77 | /* | ||
| 78 | * Wait until the BBP becomes ready. | ||
| 79 | */ | ||
| 80 | reg = rt2400pci_bbp_check(rt2x00dev); | ||
| 81 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { | ||
| 82 | ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n"); | ||
| 83 | return; | ||
| 84 | } | ||
| 85 | |||
| 86 | /* | ||
| 87 | * Write the data into the BBP. | ||
| 88 | */ | ||
| 89 | reg = 0; | ||
| 90 | rt2x00_set_field32(®, BBPCSR_VALUE, value); | ||
| 91 | rt2x00_set_field32(®, BBPCSR_REGNUM, word); | ||
| 92 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | ||
| 93 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); | ||
| 94 | |||
| 95 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); | ||
| 96 | } | ||
| 97 | |||
| 98 | static void rt2400pci_bbp_read(const struct rt2x00_dev *rt2x00dev, | ||
| 99 | const unsigned int word, u8 *value) | ||
| 100 | { | ||
| 101 | u32 reg; | ||
| 102 | |||
| 103 | /* | ||
| 104 | * Wait until the BBP becomes ready. | ||
| 105 | */ | ||
| 106 | reg = rt2400pci_bbp_check(rt2x00dev); | ||
| 107 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { | ||
| 108 | ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); | ||
| 109 | return; | ||
| 110 | } | ||
| 111 | |||
| 112 | /* | ||
| 113 | * Write the request into the BBP. | ||
| 114 | */ | ||
| 115 | reg = 0; | ||
| 116 | rt2x00_set_field32(®, BBPCSR_REGNUM, word); | ||
| 117 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | ||
| 118 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 0); | ||
| 119 | |||
| 120 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); | ||
| 121 | |||
| 122 | /* | ||
| 123 | * Wait until the BBP becomes ready. | ||
| 124 | */ | ||
| 125 | reg = rt2400pci_bbp_check(rt2x00dev); | ||
| 126 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { | ||
| 127 | ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); | ||
| 128 | *value = 0xff; | ||
| 129 | return; | ||
| 130 | } | ||
| 131 | |||
| 132 | *value = rt2x00_get_field32(reg, BBPCSR_VALUE); | ||
| 133 | } | ||
| 134 | |||
| 135 | static void rt2400pci_rf_write(const struct rt2x00_dev *rt2x00dev, | ||
| 136 | const unsigned int word, const u32 value) | ||
| 137 | { | ||
| 138 | u32 reg; | ||
| 139 | unsigned int i; | ||
| 140 | |||
| 141 | if (!word) | ||
| 142 | return; | ||
| 143 | |||
| 144 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 145 | rt2x00pci_register_read(rt2x00dev, RFCSR, ®); | ||
| 146 | if (!rt2x00_get_field32(reg, RFCSR_BUSY)) | ||
| 147 | goto rf_write; | ||
| 148 | udelay(REGISTER_BUSY_DELAY); | ||
| 149 | } | ||
| 150 | |||
| 151 | ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n"); | ||
| 152 | return; | ||
| 153 | |||
| 154 | rf_write: | ||
| 155 | reg = 0; | ||
| 156 | rt2x00_set_field32(®, RFCSR_VALUE, value); | ||
| 157 | rt2x00_set_field32(®, RFCSR_NUMBER_OF_BITS, 20); | ||
| 158 | rt2x00_set_field32(®, RFCSR_IF_SELECT, 0); | ||
| 159 | rt2x00_set_field32(®, RFCSR_BUSY, 1); | ||
| 160 | |||
| 161 | rt2x00pci_register_write(rt2x00dev, RFCSR, reg); | ||
| 162 | rt2x00_rf_write(rt2x00dev, word, value); | ||
| 163 | } | ||
| 164 | |||
| 165 | static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | ||
| 166 | { | ||
| 167 | struct rt2x00_dev *rt2x00dev = eeprom->data; | ||
| 168 | u32 reg; | ||
| 169 | |||
| 170 | rt2x00pci_register_read(rt2x00dev, CSR21, ®); | ||
| 171 | |||
| 172 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_IN); | ||
| 173 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_OUT); | ||
| 174 | eeprom->reg_data_clock = | ||
| 175 | !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_CLOCK); | ||
| 176 | eeprom->reg_chip_select = | ||
| 177 | !!rt2x00_get_field32(reg, CSR21_EEPROM_CHIP_SELECT); | ||
| 178 | } | ||
| 179 | |||
| 180 | static void rt2400pci_eepromregister_write(struct eeprom_93cx6 *eeprom) | ||
| 181 | { | ||
| 182 | struct rt2x00_dev *rt2x00dev = eeprom->data; | ||
| 183 | u32 reg = 0; | ||
| 184 | |||
| 185 | rt2x00_set_field32(®, CSR21_EEPROM_DATA_IN, !!eeprom->reg_data_in); | ||
| 186 | rt2x00_set_field32(®, CSR21_EEPROM_DATA_OUT, !!eeprom->reg_data_out); | ||
| 187 | rt2x00_set_field32(®, CSR21_EEPROM_DATA_CLOCK, | ||
| 188 | !!eeprom->reg_data_clock); | ||
| 189 | rt2x00_set_field32(®, CSR21_EEPROM_CHIP_SELECT, | ||
| 190 | !!eeprom->reg_chip_select); | ||
| 191 | |||
| 192 | rt2x00pci_register_write(rt2x00dev, CSR21, reg); | ||
| 193 | } | ||
| 194 | |||
| 195 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
| 196 | #define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) ) | ||
| 197 | |||
| 198 | static void rt2400pci_read_csr(const struct rt2x00_dev *rt2x00dev, | ||
| 199 | const unsigned int word, u32 *data) | ||
| 200 | { | ||
| 201 | rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data); | ||
| 202 | } | ||
| 203 | |||
| 204 | static void rt2400pci_write_csr(const struct rt2x00_dev *rt2x00dev, | ||
| 205 | const unsigned int word, u32 data) | ||
| 206 | { | ||
| 207 | rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data); | ||
| 208 | } | ||
| 209 | |||
| 210 | static const struct rt2x00debug rt2400pci_rt2x00debug = { | ||
| 211 | .owner = THIS_MODULE, | ||
| 212 | .csr = { | ||
| 213 | .read = rt2400pci_read_csr, | ||
| 214 | .write = rt2400pci_write_csr, | ||
| 215 | .word_size = sizeof(u32), | ||
| 216 | .word_count = CSR_REG_SIZE / sizeof(u32), | ||
| 217 | }, | ||
| 218 | .eeprom = { | ||
| 219 | .read = rt2x00_eeprom_read, | ||
| 220 | .write = rt2x00_eeprom_write, | ||
| 221 | .word_size = sizeof(u16), | ||
| 222 | .word_count = EEPROM_SIZE / sizeof(u16), | ||
| 223 | }, | ||
| 224 | .bbp = { | ||
| 225 | .read = rt2400pci_bbp_read, | ||
| 226 | .write = rt2400pci_bbp_write, | ||
| 227 | .word_size = sizeof(u8), | ||
| 228 | .word_count = BBP_SIZE / sizeof(u8), | ||
| 229 | }, | ||
| 230 | .rf = { | ||
| 231 | .read = rt2x00_rf_read, | ||
| 232 | .write = rt2400pci_rf_write, | ||
| 233 | .word_size = sizeof(u32), | ||
| 234 | .word_count = RF_SIZE / sizeof(u32), | ||
| 235 | }, | ||
| 236 | }; | ||
| 237 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
| 238 | |||
| 239 | #ifdef CONFIG_RT2400PCI_RFKILL | ||
| 240 | static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | ||
| 241 | { | ||
| 242 | u32 reg; | ||
| 243 | |||
| 244 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | ||
| 245 | return rt2x00_get_field32(reg, GPIOCSR_BIT0); | ||
| 246 | } | ||
| 247 | #endif /* CONFIG_RT2400PCI_RFKILL */ | ||
| 248 | |||
| 249 | /* | ||
| 250 | * Configuration handlers. | ||
| 251 | */ | ||
| 252 | static void rt2400pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *addr) | ||
| 253 | { | ||
| 254 | __le32 reg[2]; | ||
| 255 | |||
| 256 | memset(®, 0, sizeof(reg)); | ||
| 257 | memcpy(®, addr, ETH_ALEN); | ||
| 258 | |||
| 259 | /* | ||
| 260 | * The MAC address is passed to us as an array of bytes, | ||
| 261 | * that array is little endian, so no need for byte ordering. | ||
| 262 | */ | ||
| 263 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, ®, sizeof(reg)); | ||
| 264 | } | ||
| 265 | |||
| 266 | static void rt2400pci_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) | ||
| 267 | { | ||
| 268 | __le32 reg[2]; | ||
| 269 | |||
| 270 | memset(®, 0, sizeof(reg)); | ||
| 271 | memcpy(®, bssid, ETH_ALEN); | ||
| 272 | |||
| 273 | /* | ||
| 274 | * The BSSID is passed to us as an array of bytes, | ||
| 275 | * that array is little endian, so no need for byte ordering. | ||
| 276 | */ | ||
| 277 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, ®, sizeof(reg)); | ||
| 278 | } | ||
| 279 | |||
| 280 | static void rt2400pci_config_packet_filter(struct rt2x00_dev *rt2x00dev, | ||
| 281 | const unsigned int filter) | ||
| 282 | { | ||
| 283 | int promisc = !!(filter & IFF_PROMISC); | ||
| 284 | u32 reg; | ||
| 285 | |||
| 286 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
| 287 | rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, !promisc); | ||
| 288 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
| 289 | } | ||
| 290 | |||
| 291 | static void rt2400pci_config_type(struct rt2x00_dev *rt2x00dev, int type) | ||
| 292 | { | ||
| 293 | u32 reg; | ||
| 294 | |||
| 295 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
| 296 | |||
| 297 | /* | ||
| 298 | * Apply hardware packet filter. | ||
| 299 | */ | ||
| 300 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
| 301 | |||
| 302 | if (!is_monitor_present(&rt2x00dev->interface) && | ||
| 303 | (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_STA)) | ||
| 304 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, 1); | ||
| 305 | else | ||
| 306 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, 0); | ||
| 307 | |||
| 308 | /* | ||
| 309 | * If there is a non-monitor interface present | ||
| 310 | * the packet should be strict (even if a monitor interface is present!). | ||
| 311 | * When there is only 1 interface present which is in monitor mode | ||
| 312 | * we should start accepting _all_ frames. | ||
| 313 | */ | ||
| 314 | if (is_interface_present(&rt2x00dev->interface)) { | ||
| 315 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, 1); | ||
| 316 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, 1); | ||
| 317 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, 1); | ||
| 318 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); | ||
| 319 | } else if (is_monitor_present(&rt2x00dev->interface)) { | ||
| 320 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, 0); | ||
| 321 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, 0); | ||
| 322 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, 0); | ||
| 323 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 0); | ||
| 324 | } | ||
| 325 | |||
| 326 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
| 327 | |||
| 328 | /* | ||
| 329 | * Enable beacon config | ||
| 330 | */ | ||
| 331 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | ||
| 332 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, | ||
| 333 | PREAMBLE + get_duration(IEEE80211_HEADER, 2)); | ||
| 334 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | ||
| 335 | |||
| 336 | /* | ||
| 337 | * Enable synchronisation. | ||
| 338 | */ | ||
| 339 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
| 340 | if (is_interface_present(&rt2x00dev->interface)) { | ||
| 341 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
| 342 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
| 343 | } | ||
| 344 | |||
| 345 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
| 346 | if (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_AP) | ||
| 347 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 2); | ||
| 348 | else if (type == IEEE80211_IF_TYPE_STA) | ||
| 349 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 1); | ||
| 350 | else if (is_monitor_present(&rt2x00dev->interface) && | ||
| 351 | !is_interface_present(&rt2x00dev->interface)) | ||
| 352 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); | ||
| 353 | |||
| 354 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
| 355 | } | ||
| 356 | |||
| 357 | static void rt2400pci_config_rate(struct rt2x00_dev *rt2x00dev, const int rate) | ||
| 358 | { | ||
| 359 | struct ieee80211_conf *conf = &rt2x00dev->hw->conf; | ||
| 360 | u32 reg; | ||
| 361 | u32 preamble; | ||
| 362 | u16 value; | ||
| 363 | |||
| 364 | if (DEVICE_GET_RATE_FIELD(rate, PREAMBLE)) | ||
| 365 | preamble = SHORT_PREAMBLE; | ||
| 366 | else | ||
| 367 | preamble = PREAMBLE; | ||
| 368 | |||
| 369 | reg = DEVICE_GET_RATE_FIELD(rate, RATEMASK) & DEV_BASIC_RATEMASK; | ||
| 370 | rt2x00pci_register_write(rt2x00dev, ARCSR1, reg); | ||
| 371 | |||
| 372 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); | ||
| 373 | value = ((conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) ? | ||
| 374 | SHORT_DIFS : DIFS) + | ||
| 375 | PLCP + preamble + get_duration(ACK_SIZE, 10); | ||
| 376 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, value); | ||
| 377 | value = SIFS + PLCP + preamble + get_duration(ACK_SIZE, 10); | ||
| 378 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, value); | ||
| 379 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | ||
| 380 | |||
| 381 | preamble = DEVICE_GET_RATE_FIELD(rate, PREAMBLE) ? 0x08 : 0x00; | ||
| 382 | |||
| 383 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | ||
| 384 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00 | preamble); | ||
| 385 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); | ||
| 386 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10)); | ||
| 387 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); | ||
| 388 | |||
| 389 | rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); | ||
| 390 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble); | ||
| 391 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); | ||
| 392 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 20)); | ||
| 393 | rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); | ||
| 394 | |||
| 395 | rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); | ||
| 396 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble); | ||
| 397 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); | ||
| 398 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 55)); | ||
| 399 | rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); | ||
| 400 | |||
| 401 | rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); | ||
| 402 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble); | ||
| 403 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | ||
| 404 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | ||
| 405 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | ||
| 406 | } | ||
| 407 | |||
| 408 | static void rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev, | ||
| 409 | const int phymode) | ||
| 410 | { | ||
| 411 | struct ieee80211_hw_mode *mode; | ||
| 412 | struct ieee80211_rate *rate; | ||
| 413 | |||
| 414 | rt2x00dev->curr_hwmode = HWMODE_B; | ||
| 415 | |||
| 416 | mode = &rt2x00dev->hwmodes[rt2x00dev->curr_hwmode]; | ||
| 417 | rate = &mode->rates[mode->num_rates - 1]; | ||
| 418 | |||
| 419 | rt2400pci_config_rate(rt2x00dev, rate->val2); | ||
| 420 | } | ||
| 421 | |||
| 422 | static void rt2400pci_config_channel(struct rt2x00_dev *rt2x00dev, | ||
| 423 | const int index, const int channel) | ||
| 424 | { | ||
| 425 | struct rf_channel reg; | ||
| 426 | |||
| 427 | /* | ||
| 428 | * Fill rf_reg structure. | ||
| 429 | */ | ||
| 430 | memcpy(®, &rt2x00dev->spec.channels[index], sizeof(reg)); | ||
| 431 | |||
| 432 | /* | ||
| 433 | * Switch on tuning bits. | ||
| 434 | */ | ||
| 435 | rt2x00_set_field32(®.rf1, RF1_TUNER, 1); | ||
| 436 | rt2x00_set_field32(®.rf3, RF3_TUNER, 1); | ||
| 437 | |||
| 438 | rt2400pci_rf_write(rt2x00dev, 1, reg.rf1); | ||
| 439 | rt2400pci_rf_write(rt2x00dev, 2, reg.rf2); | ||
| 440 | rt2400pci_rf_write(rt2x00dev, 3, reg.rf3); | ||
| 441 | |||
| 442 | /* | ||
| 443 | * RF2420 chipset don't need any additional actions. | ||
| 444 | */ | ||
| 445 | if (rt2x00_rf(&rt2x00dev->chip, RF2420)) | ||
| 446 | return; | ||
| 447 | |||
| 448 | /* | ||
| 449 | * For the RT2421 chipsets we need to write an invalid | ||
| 450 | * reference clock rate to activate auto_tune. | ||
| 451 | * After that we set the value back to the correct channel. | ||
| 452 | */ | ||
| 453 | rt2400pci_rf_write(rt2x00dev, 1, reg.rf1); | ||
| 454 | rt2400pci_rf_write(rt2x00dev, 2, 0x000c2a32); | ||
| 455 | rt2400pci_rf_write(rt2x00dev, 3, reg.rf3); | ||
| 456 | |||
| 457 | msleep(1); | ||
| 458 | |||
| 459 | rt2400pci_rf_write(rt2x00dev, 1, reg.rf1); | ||
| 460 | rt2400pci_rf_write(rt2x00dev, 2, reg.rf2); | ||
| 461 | rt2400pci_rf_write(rt2x00dev, 3, reg.rf3); | ||
| 462 | |||
| 463 | msleep(1); | ||
| 464 | |||
| 465 | /* | ||
| 466 | * Switch off tuning bits. | ||
| 467 | */ | ||
| 468 | rt2x00_set_field32(®.rf1, RF1_TUNER, 0); | ||
| 469 | rt2x00_set_field32(®.rf3, RF3_TUNER, 0); | ||
| 470 | |||
| 471 | rt2400pci_rf_write(rt2x00dev, 1, reg.rf1); | ||
| 472 | rt2400pci_rf_write(rt2x00dev, 3, reg.rf3); | ||
| 473 | |||
| 474 | /* | ||
| 475 | * Clear false CRC during channel switch. | ||
| 476 | */ | ||
| 477 | rt2x00pci_register_read(rt2x00dev, CNT0, ®.rf1); | ||
| 478 | } | ||
| 479 | |||
| 480 | static void rt2400pci_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower) | ||
| 481 | { | ||
| 482 | rt2400pci_bbp_write(rt2x00dev, 3, TXPOWER_TO_DEV(txpower)); | ||
| 483 | } | ||
| 484 | |||
| 485 | static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, | ||
| 486 | int antenna_tx, int antenna_rx) | ||
| 487 | { | ||
| 488 | u8 r1; | ||
| 489 | u8 r4; | ||
| 490 | |||
| 491 | rt2400pci_bbp_read(rt2x00dev, 4, &r4); | ||
| 492 | rt2400pci_bbp_read(rt2x00dev, 1, &r1); | ||
| 493 | |||
| 494 | /* | ||
| 495 | * Configure the TX antenna. | ||
| 496 | */ | ||
| 497 | switch (antenna_tx) { | ||
| 498 | case ANTENNA_SW_DIVERSITY: | ||
| 499 | case ANTENNA_HW_DIVERSITY: | ||
| 500 | rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 1); | ||
| 501 | break; | ||
| 502 | case ANTENNA_A: | ||
| 503 | rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0); | ||
| 504 | break; | ||
| 505 | case ANTENNA_B: | ||
| 506 | rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2); | ||
| 507 | break; | ||
| 508 | } | ||
| 509 | |||
| 510 | /* | ||
| 511 | * Configure the RX antenna. | ||
| 512 | */ | ||
| 513 | switch (antenna_rx) { | ||
| 514 | case ANTENNA_SW_DIVERSITY: | ||
| 515 | case ANTENNA_HW_DIVERSITY: | ||
| 516 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
| 517 | break; | ||
| 518 | case ANTENNA_A: | ||
| 519 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0); | ||
| 520 | break; | ||
| 521 | case ANTENNA_B: | ||
| 522 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | ||
| 523 | break; | ||
| 524 | } | ||
| 525 | |||
| 526 | rt2400pci_bbp_write(rt2x00dev, 4, r4); | ||
| 527 | rt2400pci_bbp_write(rt2x00dev, 1, r1); | ||
| 528 | } | ||
| 529 | |||
| 530 | static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev, | ||
| 531 | int short_slot_time, int beacon_int) | ||
| 532 | { | ||
| 533 | u32 reg; | ||
| 534 | |||
| 535 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | ||
| 536 | rt2x00_set_field32(®, CSR11_SLOT_TIME, | ||
| 537 | short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME); | ||
| 538 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | ||
| 539 | |||
| 540 | rt2x00pci_register_read(rt2x00dev, CSR18, ®); | ||
| 541 | rt2x00_set_field32(®, CSR18_SIFS, SIFS); | ||
| 542 | rt2x00_set_field32(®, CSR18_PIFS, | ||
| 543 | short_slot_time ? SHORT_PIFS : PIFS); | ||
| 544 | rt2x00pci_register_write(rt2x00dev, CSR18, reg); | ||
| 545 | |||
| 546 | rt2x00pci_register_read(rt2x00dev, CSR19, ®); | ||
| 547 | rt2x00_set_field32(®, CSR19_DIFS, | ||
| 548 | short_slot_time ? SHORT_DIFS : DIFS); | ||
| 549 | rt2x00_set_field32(®, CSR19_EIFS, EIFS); | ||
| 550 | rt2x00pci_register_write(rt2x00dev, CSR19, reg); | ||
| 551 | |||
| 552 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); | ||
| 553 | rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); | ||
| 554 | rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); | ||
| 555 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | ||
| 556 | |||
| 557 | rt2x00pci_register_read(rt2x00dev, CSR12, ®); | ||
| 558 | rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, beacon_int * 16); | ||
| 559 | rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, beacon_int * 16); | ||
| 560 | rt2x00pci_register_write(rt2x00dev, CSR12, reg); | ||
| 561 | } | ||
| 562 | |||
| 563 | static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, | ||
| 564 | const unsigned int flags, | ||
| 565 | struct ieee80211_conf *conf) | ||
| 566 | { | ||
| 567 | int short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME; | ||
| 568 | |||
| 569 | if (flags & CONFIG_UPDATE_PHYMODE) | ||
| 570 | rt2400pci_config_phymode(rt2x00dev, conf->phymode); | ||
| 571 | if (flags & CONFIG_UPDATE_CHANNEL) | ||
| 572 | rt2400pci_config_channel(rt2x00dev, conf->channel_val, | ||
| 573 | conf->channel); | ||
| 574 | if (flags & CONFIG_UPDATE_TXPOWER) | ||
| 575 | rt2400pci_config_txpower(rt2x00dev, conf->power_level); | ||
| 576 | if (flags & CONFIG_UPDATE_ANTENNA) | ||
| 577 | rt2400pci_config_antenna(rt2x00dev, conf->antenna_sel_tx, | ||
| 578 | conf->antenna_sel_rx); | ||
| 579 | if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) | ||
| 580 | rt2400pci_config_duration(rt2x00dev, short_slot_time, | ||
| 581 | conf->beacon_int); | ||
| 582 | } | ||
| 583 | |||
| 584 | static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev, | ||
| 585 | struct ieee80211_tx_queue_params *params) | ||
| 586 | { | ||
| 587 | u32 reg; | ||
| 588 | |||
| 589 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | ||
| 590 | rt2x00_set_field32(®, CSR11_CWMIN, params->cw_min); | ||
| 591 | rt2x00_set_field32(®, CSR11_CWMAX, params->cw_max); | ||
| 592 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | ||
| 593 | } | ||
| 594 | |||
| 595 | /* | ||
| 596 | * LED functions. | ||
| 597 | */ | ||
| 598 | static void rt2400pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
| 599 | { | ||
| 600 | u32 reg; | ||
| 601 | |||
| 602 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
| 603 | |||
| 604 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
| 605 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
| 606 | |||
| 607 | if (rt2x00dev->led_mode == LED_MODE_TXRX_ACTIVITY) { | ||
| 608 | rt2x00_set_field32(®, LEDCSR_LINK, 1); | ||
| 609 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); | ||
| 610 | } else if (rt2x00dev->led_mode == LED_MODE_ASUS) { | ||
| 611 | rt2x00_set_field32(®, LEDCSR_LINK, 0); | ||
| 612 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1); | ||
| 613 | } else { | ||
| 614 | rt2x00_set_field32(®, LEDCSR_LINK, 1); | ||
| 615 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1); | ||
| 616 | } | ||
| 617 | |||
| 618 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
| 619 | } | ||
| 620 | |||
| 621 | static void rt2400pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
| 622 | { | ||
| 623 | u32 reg; | ||
| 624 | |||
| 625 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
| 626 | rt2x00_set_field32(®, LEDCSR_LINK, 0); | ||
| 627 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); | ||
| 628 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
| 629 | } | ||
| 630 | |||
| 631 | /* | ||
| 632 | * Link tuning | ||
| 633 | */ | ||
| 634 | static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev) | ||
| 635 | { | ||
| 636 | u32 reg; | ||
| 637 | u8 bbp; | ||
| 638 | |||
| 639 | /* | ||
| 640 | * Update FCS error count from register. | ||
| 641 | */ | ||
| 642 | rt2x00pci_register_read(rt2x00dev, CNT0, ®); | ||
| 643 | rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR); | ||
| 644 | |||
| 645 | /* | ||
| 646 | * Update False CCA count from register. | ||
| 647 | */ | ||
| 648 | rt2400pci_bbp_read(rt2x00dev, 39, &bbp); | ||
| 649 | rt2x00dev->link.false_cca = bbp; | ||
| 650 | } | ||
| 651 | |||
| 652 | static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev) | ||
| 653 | { | ||
| 654 | rt2400pci_bbp_write(rt2x00dev, 13, 0x08); | ||
| 655 | rt2x00dev->link.vgc_level = 0x08; | ||
| 656 | } | ||
| 657 | |||
| 658 | static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev) | ||
| 659 | { | ||
| 660 | u8 reg; | ||
| 661 | |||
| 662 | /* | ||
| 663 | * The link tuner should not run longer then 60 seconds, | ||
| 664 | * and should run once every 2 seconds. | ||
| 665 | */ | ||
| 666 | if (rt2x00dev->link.count > 60 || !(rt2x00dev->link.count & 1)) | ||
| 667 | return; | ||
| 668 | |||
| 669 | /* | ||
| 670 | * Base r13 link tuning on the false cca count. | ||
| 671 | */ | ||
| 672 | rt2400pci_bbp_read(rt2x00dev, 13, ®); | ||
| 673 | |||
| 674 | if (rt2x00dev->link.false_cca > 512 && reg < 0x20) { | ||
| 675 | rt2400pci_bbp_write(rt2x00dev, 13, ++reg); | ||
| 676 | rt2x00dev->link.vgc_level = reg; | ||
| 677 | } else if (rt2x00dev->link.false_cca < 100 && reg > 0x08) { | ||
| 678 | rt2400pci_bbp_write(rt2x00dev, 13, --reg); | ||
| 679 | rt2x00dev->link.vgc_level = reg; | ||
| 680 | } | ||
| 681 | } | ||
| 682 | |||
| 683 | /* | ||
| 684 | * Initialization functions. | ||
| 685 | */ | ||
| 686 | static void rt2400pci_init_rxring(struct rt2x00_dev *rt2x00dev) | ||
| 687 | { | ||
| 688 | struct data_ring *ring = rt2x00dev->rx; | ||
| 689 | struct data_desc *rxd; | ||
| 690 | unsigned int i; | ||
| 691 | u32 word; | ||
| 692 | |||
| 693 | memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring)); | ||
| 694 | |||
| 695 | for (i = 0; i < ring->stats.limit; i++) { | ||
| 696 | rxd = ring->entry[i].priv; | ||
| 697 | |||
| 698 | rt2x00_desc_read(rxd, 2, &word); | ||
| 699 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, | ||
| 700 | ring->data_size); | ||
| 701 | rt2x00_desc_write(rxd, 2, word); | ||
| 702 | |||
| 703 | rt2x00_desc_read(rxd, 1, &word); | ||
| 704 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, | ||
| 705 | ring->entry[i].data_dma); | ||
| 706 | rt2x00_desc_write(rxd, 1, word); | ||
| 707 | |||
| 708 | rt2x00_desc_read(rxd, 0, &word); | ||
| 709 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | ||
| 710 | rt2x00_desc_write(rxd, 0, word); | ||
| 711 | } | ||
| 712 | |||
| 713 | rt2x00_ring_index_clear(rt2x00dev->rx); | ||
| 714 | } | ||
| 715 | |||
| 716 | static void rt2400pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue) | ||
| 717 | { | ||
| 718 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | ||
| 719 | struct data_desc *txd; | ||
| 720 | unsigned int i; | ||
| 721 | u32 word; | ||
| 722 | |||
| 723 | memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring)); | ||
| 724 | |||
| 725 | for (i = 0; i < ring->stats.limit; i++) { | ||
| 726 | txd = ring->entry[i].priv; | ||
| 727 | |||
| 728 | rt2x00_desc_read(txd, 1, &word); | ||
| 729 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, | ||
| 730 | ring->entry[i].data_dma); | ||
| 731 | rt2x00_desc_write(txd, 1, word); | ||
| 732 | |||
| 733 | rt2x00_desc_read(txd, 2, &word); | ||
| 734 | rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, | ||
| 735 | ring->data_size); | ||
| 736 | rt2x00_desc_write(txd, 2, word); | ||
| 737 | |||
| 738 | rt2x00_desc_read(txd, 0, &word); | ||
| 739 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | ||
| 740 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | ||
| 741 | rt2x00_desc_write(txd, 0, word); | ||
| 742 | } | ||
| 743 | |||
| 744 | rt2x00_ring_index_clear(ring); | ||
| 745 | } | ||
| 746 | |||
| 747 | static int rt2400pci_init_rings(struct rt2x00_dev *rt2x00dev) | ||
| 748 | { | ||
| 749 | u32 reg; | ||
| 750 | |||
| 751 | /* | ||
| 752 | * Initialize rings. | ||
| 753 | */ | ||
| 754 | rt2400pci_init_rxring(rt2x00dev); | ||
| 755 | rt2400pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0); | ||
| 756 | rt2400pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA1); | ||
| 757 | rt2400pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | ||
| 758 | rt2400pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
| 759 | |||
| 760 | /* | ||
| 761 | * Initialize registers. | ||
| 762 | */ | ||
| 763 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | ||
| 764 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, | ||
| 765 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size); | ||
| 766 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, | ||
| 767 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | ||
| 768 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, | ||
| 769 | rt2x00dev->bcn[1].stats.limit); | ||
| 770 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, | ||
| 771 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | ||
| 772 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); | ||
| 773 | |||
| 774 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); | ||
| 775 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, | ||
| 776 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | ||
| 777 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); | ||
| 778 | |||
| 779 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); | ||
| 780 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, | ||
| 781 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | ||
| 782 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | ||
| 783 | |||
| 784 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | ||
| 785 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | ||
| 786 | rt2x00dev->bcn[1].data_dma); | ||
| 787 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | ||
| 788 | |||
| 789 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | ||
| 790 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | ||
| 791 | rt2x00dev->bcn[0].data_dma); | ||
| 792 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); | ||
| 793 | |||
| 794 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); | ||
| 795 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); | ||
| 796 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->stats.limit); | ||
| 797 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); | ||
| 798 | |||
| 799 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); | ||
| 800 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, | ||
| 801 | rt2x00dev->rx->data_dma); | ||
| 802 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); | ||
| 803 | |||
| 804 | return 0; | ||
| 805 | } | ||
| 806 | |||
| 807 | static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev) | ||
| 808 | { | ||
| 809 | u32 reg; | ||
| 810 | |||
| 811 | rt2x00pci_register_write(rt2x00dev, PSCSR0, 0x00020002); | ||
| 812 | rt2x00pci_register_write(rt2x00dev, PSCSR1, 0x00000002); | ||
| 813 | rt2x00pci_register_write(rt2x00dev, PSCSR2, 0x00023f20); | ||
| 814 | rt2x00pci_register_write(rt2x00dev, PSCSR3, 0x00000002); | ||
| 815 | |||
| 816 | rt2x00pci_register_read(rt2x00dev, TIMECSR, ®); | ||
| 817 | rt2x00_set_field32(®, TIMECSR_US_COUNT, 33); | ||
| 818 | rt2x00_set_field32(®, TIMECSR_US_64_COUNT, 63); | ||
| 819 | rt2x00_set_field32(®, TIMECSR_BEACON_EXPECT, 0); | ||
| 820 | rt2x00pci_register_write(rt2x00dev, TIMECSR, reg); | ||
| 821 | |||
| 822 | rt2x00pci_register_read(rt2x00dev, CSR9, ®); | ||
| 823 | rt2x00_set_field32(®, CSR9_MAX_FRAME_UNIT, | ||
| 824 | (rt2x00dev->rx->data_size / 128)); | ||
| 825 | rt2x00pci_register_write(rt2x00dev, CSR9, reg); | ||
| 826 | |||
| 827 | rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000); | ||
| 828 | |||
| 829 | rt2x00pci_register_read(rt2x00dev, ARCSR0, ®); | ||
| 830 | rt2x00_set_field32(®, ARCSR0_AR_BBP_DATA0, 133); | ||
| 831 | rt2x00_set_field32(®, ARCSR0_AR_BBP_ID0, 134); | ||
| 832 | rt2x00_set_field32(®, ARCSR0_AR_BBP_DATA1, 136); | ||
| 833 | rt2x00_set_field32(®, ARCSR0_AR_BBP_ID1, 135); | ||
| 834 | rt2x00pci_register_write(rt2x00dev, ARCSR0, reg); | ||
| 835 | |||
| 836 | rt2x00pci_register_read(rt2x00dev, RXCSR3, ®); | ||
| 837 | rt2x00_set_field32(®, RXCSR3_BBP_ID0, 3); /* Tx power.*/ | ||
| 838 | rt2x00_set_field32(®, RXCSR3_BBP_ID0_VALID, 1); | ||
| 839 | rt2x00_set_field32(®, RXCSR3_BBP_ID1, 32); /* Signal */ | ||
| 840 | rt2x00_set_field32(®, RXCSR3_BBP_ID1_VALID, 1); | ||
| 841 | rt2x00_set_field32(®, RXCSR3_BBP_ID2, 36); /* Rssi */ | ||
| 842 | rt2x00_set_field32(®, RXCSR3_BBP_ID2_VALID, 1); | ||
| 843 | rt2x00pci_register_write(rt2x00dev, RXCSR3, reg); | ||
| 844 | |||
| 845 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0x3f3b3100); | ||
| 846 | |||
| 847 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) | ||
| 848 | return -EBUSY; | ||
| 849 | |||
| 850 | rt2x00pci_register_write(rt2x00dev, MACCSR0, 0x00217223); | ||
| 851 | rt2x00pci_register_write(rt2x00dev, MACCSR1, 0x00235518); | ||
| 852 | |||
| 853 | rt2x00pci_register_read(rt2x00dev, MACCSR2, ®); | ||
| 854 | rt2x00_set_field32(®, MACCSR2_DELAY, 64); | ||
| 855 | rt2x00pci_register_write(rt2x00dev, MACCSR2, reg); | ||
| 856 | |||
| 857 | rt2x00pci_register_read(rt2x00dev, RALINKCSR, ®); | ||
| 858 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA0, 17); | ||
| 859 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID0, 154); | ||
| 860 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA1, 0); | ||
| 861 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID1, 154); | ||
| 862 | rt2x00pci_register_write(rt2x00dev, RALINKCSR, reg); | ||
| 863 | |||
| 864 | rt2x00pci_register_read(rt2x00dev, CSR1, ®); | ||
| 865 | rt2x00_set_field32(®, CSR1_SOFT_RESET, 1); | ||
| 866 | rt2x00_set_field32(®, CSR1_BBP_RESET, 0); | ||
| 867 | rt2x00_set_field32(®, CSR1_HOST_READY, 0); | ||
| 868 | rt2x00pci_register_write(rt2x00dev, CSR1, reg); | ||
| 869 | |||
| 870 | rt2x00pci_register_read(rt2x00dev, CSR1, ®); | ||
| 871 | rt2x00_set_field32(®, CSR1_SOFT_RESET, 0); | ||
| 872 | rt2x00_set_field32(®, CSR1_HOST_READY, 1); | ||
| 873 | rt2x00pci_register_write(rt2x00dev, CSR1, reg); | ||
| 874 | |||
| 875 | /* | ||
| 876 | * We must clear the FCS and FIFO error count. | ||
| 877 | * These registers are cleared on read, | ||
| 878 | * so we may pass a useless variable to store the value. | ||
| 879 | */ | ||
| 880 | rt2x00pci_register_read(rt2x00dev, CNT0, ®); | ||
| 881 | rt2x00pci_register_read(rt2x00dev, CNT4, ®); | ||
| 882 | |||
| 883 | return 0; | ||
| 884 | } | ||
| 885 | |||
| 886 | static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev) | ||
| 887 | { | ||
| 888 | unsigned int i; | ||
| 889 | u16 eeprom; | ||
| 890 | u8 reg_id; | ||
| 891 | u8 value; | ||
| 892 | |||
| 893 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 894 | rt2400pci_bbp_read(rt2x00dev, 0, &value); | ||
| 895 | if ((value != 0xff) && (value != 0x00)) | ||
| 896 | goto continue_csr_init; | ||
| 897 | NOTICE(rt2x00dev, "Waiting for BBP register.\n"); | ||
| 898 | udelay(REGISTER_BUSY_DELAY); | ||
| 899 | } | ||
| 900 | |||
| 901 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | ||
| 902 | return -EACCES; | ||
| 903 | |||
| 904 | continue_csr_init: | ||
| 905 | rt2400pci_bbp_write(rt2x00dev, 1, 0x00); | ||
| 906 | rt2400pci_bbp_write(rt2x00dev, 3, 0x27); | ||
| 907 | rt2400pci_bbp_write(rt2x00dev, 4, 0x08); | ||
| 908 | rt2400pci_bbp_write(rt2x00dev, 10, 0x0f); | ||
| 909 | rt2400pci_bbp_write(rt2x00dev, 15, 0x72); | ||
| 910 | rt2400pci_bbp_write(rt2x00dev, 16, 0x74); | ||
| 911 | rt2400pci_bbp_write(rt2x00dev, 17, 0x20); | ||
| 912 | rt2400pci_bbp_write(rt2x00dev, 18, 0x72); | ||
| 913 | rt2400pci_bbp_write(rt2x00dev, 19, 0x0b); | ||
| 914 | rt2400pci_bbp_write(rt2x00dev, 20, 0x00); | ||
| 915 | rt2400pci_bbp_write(rt2x00dev, 28, 0x11); | ||
| 916 | rt2400pci_bbp_write(rt2x00dev, 29, 0x04); | ||
| 917 | rt2400pci_bbp_write(rt2x00dev, 30, 0x21); | ||
| 918 | rt2400pci_bbp_write(rt2x00dev, 31, 0x00); | ||
| 919 | |||
| 920 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
| 921 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | ||
| 922 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | ||
| 923 | |||
| 924 | if (eeprom != 0xffff && eeprom != 0x0000) { | ||
| 925 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | ||
| 926 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | ||
| 927 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
| 928 | reg_id, value); | ||
| 929 | rt2400pci_bbp_write(rt2x00dev, reg_id, value); | ||
| 930 | } | ||
| 931 | } | ||
| 932 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
| 933 | |||
| 934 | return 0; | ||
| 935 | } | ||
| 936 | |||
| 937 | /* | ||
| 938 | * Device state switch handlers. | ||
| 939 | */ | ||
| 940 | static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev, | ||
| 941 | enum dev_state state) | ||
| 942 | { | ||
| 943 | u32 reg; | ||
| 944 | |||
| 945 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
| 946 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, | ||
| 947 | state == STATE_RADIO_RX_OFF); | ||
| 948 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
| 949 | } | ||
| 950 | |||
| 951 | static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | ||
| 952 | enum dev_state state) | ||
| 953 | { | ||
| 954 | int mask = (state == STATE_RADIO_IRQ_OFF); | ||
| 955 | u32 reg; | ||
| 956 | |||
| 957 | /* | ||
| 958 | * When interrupts are being enabled, the interrupt registers | ||
| 959 | * should clear the register to assure a clean state. | ||
| 960 | */ | ||
| 961 | if (state == STATE_RADIO_IRQ_ON) { | ||
| 962 | rt2x00pci_register_read(rt2x00dev, CSR7, ®); | ||
| 963 | rt2x00pci_register_write(rt2x00dev, CSR7, reg); | ||
| 964 | } | ||
| 965 | |||
| 966 | /* | ||
| 967 | * Only toggle the interrupts bits we are going to use. | ||
| 968 | * Non-checked interrupt bits are disabled by default. | ||
| 969 | */ | ||
| 970 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | ||
| 971 | rt2x00_set_field32(®, CSR8_TBCN_EXPIRE, mask); | ||
| 972 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, mask); | ||
| 973 | rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, mask); | ||
| 974 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, mask); | ||
| 975 | rt2x00_set_field32(®, CSR8_RXDONE, mask); | ||
| 976 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | ||
| 977 | } | ||
| 978 | |||
| 979 | static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 980 | { | ||
| 981 | /* | ||
| 982 | * Initialize all registers. | ||
| 983 | */ | ||
| 984 | if (rt2400pci_init_rings(rt2x00dev) || | ||
| 985 | rt2400pci_init_registers(rt2x00dev) || | ||
| 986 | rt2400pci_init_bbp(rt2x00dev)) { | ||
| 987 | ERROR(rt2x00dev, "Register initialization failed.\n"); | ||
| 988 | return -EIO; | ||
| 989 | } | ||
| 990 | |||
| 991 | /* | ||
| 992 | * Enable interrupts. | ||
| 993 | */ | ||
| 994 | rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | ||
| 995 | |||
| 996 | /* | ||
| 997 | * Enable LED | ||
| 998 | */ | ||
| 999 | rt2400pci_enable_led(rt2x00dev); | ||
| 1000 | |||
| 1001 | return 0; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 1005 | { | ||
| 1006 | u32 reg; | ||
| 1007 | |||
| 1008 | /* | ||
| 1009 | * Disable LED | ||
| 1010 | */ | ||
| 1011 | rt2400pci_disable_led(rt2x00dev); | ||
| 1012 | |||
| 1013 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | ||
| 1014 | |||
| 1015 | /* | ||
| 1016 | * Disable synchronisation. | ||
| 1017 | */ | ||
| 1018 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
| 1019 | |||
| 1020 | /* | ||
| 1021 | * Cancel RX and TX. | ||
| 1022 | */ | ||
| 1023 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | ||
| 1024 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); | ||
| 1025 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
| 1026 | |||
| 1027 | /* | ||
| 1028 | * Disable interrupts. | ||
| 1029 | */ | ||
| 1030 | rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF); | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, | ||
| 1034 | enum dev_state state) | ||
| 1035 | { | ||
| 1036 | u32 reg; | ||
| 1037 | unsigned int i; | ||
| 1038 | char put_to_sleep; | ||
| 1039 | char bbp_state; | ||
| 1040 | char rf_state; | ||
| 1041 | |||
| 1042 | put_to_sleep = (state != STATE_AWAKE); | ||
| 1043 | |||
| 1044 | rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®); | ||
| 1045 | rt2x00_set_field32(®, PWRCSR1_SET_STATE, 1); | ||
| 1046 | rt2x00_set_field32(®, PWRCSR1_BBP_DESIRE_STATE, state); | ||
| 1047 | rt2x00_set_field32(®, PWRCSR1_RF_DESIRE_STATE, state); | ||
| 1048 | rt2x00_set_field32(®, PWRCSR1_PUT_TO_SLEEP, put_to_sleep); | ||
| 1049 | rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg); | ||
| 1050 | |||
| 1051 | /* | ||
| 1052 | * Device is not guaranteed to be in the requested state yet. | ||
| 1053 | * We must wait until the register indicates that the | ||
| 1054 | * device has entered the correct state. | ||
| 1055 | */ | ||
| 1056 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 1057 | rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®); | ||
| 1058 | bbp_state = rt2x00_get_field32(reg, PWRCSR1_BBP_CURR_STATE); | ||
| 1059 | rf_state = rt2x00_get_field32(reg, PWRCSR1_RF_CURR_STATE); | ||
| 1060 | if (bbp_state == state && rf_state == state) | ||
| 1061 | return 0; | ||
| 1062 | msleep(10); | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | NOTICE(rt2x00dev, "Device failed to enter state %d, " | ||
| 1066 | "current device state: bbp %d and rf %d.\n", | ||
| 1067 | state, bbp_state, rf_state); | ||
| 1068 | |||
| 1069 | return -EBUSY; | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, | ||
| 1073 | enum dev_state state) | ||
| 1074 | { | ||
| 1075 | int retval = 0; | ||
| 1076 | |||
| 1077 | switch (state) { | ||
| 1078 | case STATE_RADIO_ON: | ||
| 1079 | retval = rt2400pci_enable_radio(rt2x00dev); | ||
| 1080 | break; | ||
| 1081 | case STATE_RADIO_OFF: | ||
| 1082 | rt2400pci_disable_radio(rt2x00dev); | ||
| 1083 | break; | ||
| 1084 | case STATE_RADIO_RX_ON: | ||
| 1085 | case STATE_RADIO_RX_OFF: | ||
| 1086 | rt2400pci_toggle_rx(rt2x00dev, state); | ||
| 1087 | break; | ||
| 1088 | case STATE_DEEP_SLEEP: | ||
| 1089 | case STATE_SLEEP: | ||
| 1090 | case STATE_STANDBY: | ||
| 1091 | case STATE_AWAKE: | ||
| 1092 | retval = rt2400pci_set_state(rt2x00dev, state); | ||
| 1093 | break; | ||
| 1094 | default: | ||
| 1095 | retval = -ENOTSUPP; | ||
| 1096 | break; | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | return retval; | ||
| 1100 | } | ||
| 1101 | |||
| 1102 | /* | ||
| 1103 | * TX descriptor initialization | ||
| 1104 | */ | ||
| 1105 | static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | ||
| 1106 | struct data_desc *txd, | ||
| 1107 | struct data_entry_desc *desc, | ||
| 1108 | struct ieee80211_hdr *ieee80211hdr, | ||
| 1109 | unsigned int length, | ||
| 1110 | struct ieee80211_tx_control *control) | ||
| 1111 | { | ||
| 1112 | u32 word; | ||
| 1113 | u32 signal = 0; | ||
| 1114 | u32 service = 0; | ||
| 1115 | u32 length_high = 0; | ||
| 1116 | u32 length_low = 0; | ||
| 1117 | |||
| 1118 | /* | ||
| 1119 | * The PLCP values should be treated as if they | ||
| 1120 | * were BBP values. | ||
| 1121 | */ | ||
| 1122 | rt2x00_set_field32(&signal, BBPCSR_VALUE, desc->signal); | ||
| 1123 | rt2x00_set_field32(&signal, BBPCSR_REGNUM, 5); | ||
| 1124 | rt2x00_set_field32(&signal, BBPCSR_BUSY, 1); | ||
| 1125 | |||
| 1126 | rt2x00_set_field32(&service, BBPCSR_VALUE, desc->service); | ||
| 1127 | rt2x00_set_field32(&service, BBPCSR_REGNUM, 6); | ||
| 1128 | rt2x00_set_field32(&service, BBPCSR_BUSY, 1); | ||
| 1129 | |||
| 1130 | rt2x00_set_field32(&length_high, BBPCSR_VALUE, desc->length_high); | ||
| 1131 | rt2x00_set_field32(&length_high, BBPCSR_REGNUM, 7); | ||
| 1132 | rt2x00_set_field32(&length_high, BBPCSR_BUSY, 1); | ||
| 1133 | |||
| 1134 | rt2x00_set_field32(&length_low, BBPCSR_VALUE, desc->length_low); | ||
| 1135 | rt2x00_set_field32(&length_low, BBPCSR_REGNUM, 8); | ||
| 1136 | rt2x00_set_field32(&length_low, BBPCSR_BUSY, 1); | ||
| 1137 | |||
| 1138 | /* | ||
| 1139 | * Start writing the descriptor words. | ||
| 1140 | */ | ||
| 1141 | rt2x00_desc_read(txd, 2, &word); | ||
| 1142 | rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, length); | ||
| 1143 | rt2x00_desc_write(txd, 2, word); | ||
| 1144 | |||
| 1145 | rt2x00_desc_read(txd, 3, &word); | ||
| 1146 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, signal); | ||
| 1147 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, service); | ||
| 1148 | rt2x00_desc_write(txd, 3, word); | ||
| 1149 | |||
| 1150 | rt2x00_desc_read(txd, 4, &word); | ||
| 1151 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, length_low); | ||
| 1152 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, length_high); | ||
| 1153 | rt2x00_desc_write(txd, 4, word); | ||
| 1154 | |||
| 1155 | rt2x00_desc_read(txd, 0, &word); | ||
| 1156 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | ||
| 1157 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | ||
| 1158 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | ||
| 1159 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | ||
| 1160 | rt2x00_set_field32(&word, TXD_W0_ACK, | ||
| 1161 | !(control->flags & IEEE80211_TXCTL_NO_ACK)); | ||
| 1162 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | ||
| 1163 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | ||
| 1164 | rt2x00_set_field32(&word, TXD_W0_RTS, | ||
| 1165 | test_bit(ENTRY_TXD_RTS_FRAME, &desc->flags)); | ||
| 1166 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | ||
| 1167 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | ||
| 1168 | !!(control->flags & | ||
| 1169 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | ||
| 1170 | rt2x00_desc_write(txd, 0, word); | ||
| 1171 | } | ||
| 1172 | |||
| 1173 | /* | ||
| 1174 | * TX data initialization | ||
| 1175 | */ | ||
| 1176 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
| 1177 | unsigned int queue) | ||
| 1178 | { | ||
| 1179 | u32 reg; | ||
| 1180 | |||
| 1181 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | ||
| 1182 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
| 1183 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | ||
| 1184 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | ||
| 1185 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
| 1186 | } | ||
| 1187 | return; | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | ||
| 1191 | if (queue == IEEE80211_TX_QUEUE_DATA0) | ||
| 1192 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); | ||
| 1193 | else if (queue == IEEE80211_TX_QUEUE_DATA1) | ||
| 1194 | rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); | ||
| 1195 | else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON) | ||
| 1196 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); | ||
| 1197 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | /* | ||
| 1201 | * RX control handlers | ||
| 1202 | */ | ||
| 1203 | static int rt2400pci_fill_rxdone(struct data_entry *entry, | ||
| 1204 | int *signal, int *rssi, int *ofdm, int *size) | ||
| 1205 | { | ||
| 1206 | struct data_desc *rxd = entry->priv; | ||
| 1207 | u32 word0; | ||
| 1208 | u32 word2; | ||
| 1209 | |||
| 1210 | rt2x00_desc_read(rxd, 0, &word0); | ||
| 1211 | rt2x00_desc_read(rxd, 2, &word2); | ||
| 1212 | |||
| 1213 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR) || | ||
| 1214 | rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | ||
| 1215 | return -EINVAL; | ||
| 1216 | |||
| 1217 | /* | ||
| 1218 | * Obtain the status about this packet. | ||
| 1219 | */ | ||
| 1220 | *signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | ||
| 1221 | *rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | ||
| 1222 | entry->ring->rt2x00dev->rssi_offset; | ||
| 1223 | *ofdm = 0; | ||
| 1224 | *size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
| 1225 | |||
| 1226 | return 0; | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | /* | ||
| 1230 | * Interrupt functions. | ||
| 1231 | */ | ||
| 1232 | static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | ||
| 1233 | { | ||
| 1234 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | ||
| 1235 | struct data_entry *entry; | ||
| 1236 | struct data_desc *txd; | ||
| 1237 | u32 word; | ||
| 1238 | int tx_status; | ||
| 1239 | int retry; | ||
| 1240 | |||
| 1241 | while (!rt2x00_ring_empty(ring)) { | ||
| 1242 | entry = rt2x00_get_data_entry_done(ring); | ||
| 1243 | txd = entry->priv; | ||
| 1244 | rt2x00_desc_read(txd, 0, &word); | ||
| 1245 | |||
| 1246 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | ||
| 1247 | !rt2x00_get_field32(word, TXD_W0_VALID)) | ||
| 1248 | break; | ||
| 1249 | |||
| 1250 | /* | ||
| 1251 | * Obtain the status about this packet. | ||
| 1252 | */ | ||
| 1253 | tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); | ||
| 1254 | retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | ||
| 1255 | |||
| 1256 | rt2x00lib_txdone(entry, tx_status, retry); | ||
| 1257 | |||
| 1258 | /* | ||
| 1259 | * Make this entry available for reuse. | ||
| 1260 | */ | ||
| 1261 | entry->flags = 0; | ||
| 1262 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | ||
| 1263 | rt2x00_desc_write(txd, 0, word); | ||
| 1264 | rt2x00_ring_index_done_inc(ring); | ||
| 1265 | } | ||
| 1266 | |||
| 1267 | /* | ||
| 1268 | * If the data ring was full before the txdone handler | ||
| 1269 | * we must make sure the packet queue in the mac80211 stack | ||
| 1270 | * is reenabled when the txdone handler has finished. | ||
| 1271 | */ | ||
| 1272 | entry = ring->entry; | ||
| 1273 | if (!rt2x00_ring_full(ring)) | ||
| 1274 | ieee80211_wake_queue(rt2x00dev->hw, | ||
| 1275 | entry->tx_status.control.queue); | ||
| 1276 | } | ||
| 1277 | |||
| 1278 | static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) | ||
| 1279 | { | ||
| 1280 | struct rt2x00_dev *rt2x00dev = dev_instance; | ||
| 1281 | u32 reg; | ||
| 1282 | |||
| 1283 | /* | ||
| 1284 | * Get the interrupt sources & saved to local variable. | ||
| 1285 | * Write register value back to clear pending interrupts. | ||
| 1286 | */ | ||
| 1287 | rt2x00pci_register_read(rt2x00dev, CSR7, ®); | ||
| 1288 | rt2x00pci_register_write(rt2x00dev, CSR7, reg); | ||
| 1289 | |||
| 1290 | if (!reg) | ||
| 1291 | return IRQ_NONE; | ||
| 1292 | |||
| 1293 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
| 1294 | return IRQ_HANDLED; | ||
| 1295 | |||
| 1296 | /* | ||
| 1297 | * Handle interrupts, walk through all bits | ||
| 1298 | * and run the tasks, the bits are checked in order of | ||
| 1299 | * priority. | ||
| 1300 | */ | ||
| 1301 | |||
| 1302 | /* | ||
| 1303 | * 1 - Beacon timer expired interrupt. | ||
| 1304 | */ | ||
| 1305 | if (rt2x00_get_field32(reg, CSR7_TBCN_EXPIRE)) | ||
| 1306 | rt2x00lib_beacondone(rt2x00dev); | ||
| 1307 | |||
| 1308 | /* | ||
| 1309 | * 2 - Rx ring done interrupt. | ||
| 1310 | */ | ||
| 1311 | if (rt2x00_get_field32(reg, CSR7_RXDONE)) | ||
| 1312 | rt2x00pci_rxdone(rt2x00dev); | ||
| 1313 | |||
| 1314 | /* | ||
| 1315 | * 3 - Atim ring transmit done interrupt. | ||
| 1316 | */ | ||
| 1317 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) | ||
| 1318 | rt2400pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | ||
| 1319 | |||
| 1320 | /* | ||
| 1321 | * 4 - Priority ring transmit done interrupt. | ||
| 1322 | */ | ||
| 1323 | if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING)) | ||
| 1324 | rt2400pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_DATA0); | ||
| 1325 | |||
| 1326 | /* | ||
| 1327 | * 5 - Tx ring transmit done interrupt. | ||
| 1328 | */ | ||
| 1329 | if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) | ||
| 1330 | rt2400pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_DATA1); | ||
| 1331 | |||
| 1332 | return IRQ_HANDLED; | ||
| 1333 | } | ||
| 1334 | |||
| 1335 | /* | ||
| 1336 | * Device probe functions. | ||
| 1337 | */ | ||
| 1338 | static int rt2400pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | ||
| 1339 | { | ||
| 1340 | struct eeprom_93cx6 eeprom; | ||
| 1341 | u32 reg; | ||
| 1342 | u16 word; | ||
| 1343 | u8 *mac; | ||
| 1344 | |||
| 1345 | rt2x00pci_register_read(rt2x00dev, CSR21, ®); | ||
| 1346 | |||
| 1347 | eeprom.data = rt2x00dev; | ||
| 1348 | eeprom.register_read = rt2400pci_eepromregister_read; | ||
| 1349 | eeprom.register_write = rt2400pci_eepromregister_write; | ||
| 1350 | eeprom.width = rt2x00_get_field32(reg, CSR21_TYPE_93C46) ? | ||
| 1351 | PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66; | ||
| 1352 | eeprom.reg_data_in = 0; | ||
| 1353 | eeprom.reg_data_out = 0; | ||
| 1354 | eeprom.reg_data_clock = 0; | ||
| 1355 | eeprom.reg_chip_select = 0; | ||
| 1356 | |||
| 1357 | eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom, | ||
| 1358 | EEPROM_SIZE / sizeof(u16)); | ||
| 1359 | |||
| 1360 | /* | ||
| 1361 | * Start validation of the data that has been read. | ||
| 1362 | */ | ||
| 1363 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | ||
| 1364 | if (!is_valid_ether_addr(mac)) { | ||
| 1365 | random_ether_addr(mac); | ||
| 1366 | EEPROM(rt2x00dev, "MAC: " MAC_FMT "\n", MAC_ARG(mac)); | ||
| 1367 | } | ||
| 1368 | |||
| 1369 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | ||
| 1370 | if (word == 0xffff) { | ||
| 1371 | ERROR(rt2x00dev, "Invalid EEPROM data detected.\n"); | ||
| 1372 | return -EINVAL; | ||
| 1373 | } | ||
| 1374 | |||
| 1375 | return 0; | ||
| 1376 | } | ||
| 1377 | |||
| 1378 | static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | ||
| 1379 | { | ||
| 1380 | u32 reg; | ||
| 1381 | u16 value; | ||
| 1382 | u16 eeprom; | ||
| 1383 | |||
| 1384 | /* | ||
| 1385 | * Read EEPROM word for configuration. | ||
| 1386 | */ | ||
| 1387 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
| 1388 | |||
| 1389 | /* | ||
| 1390 | * Identify RF chipset. | ||
| 1391 | */ | ||
| 1392 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | ||
| 1393 | rt2x00pci_register_read(rt2x00dev, CSR0, ®); | ||
| 1394 | rt2x00_set_chip(rt2x00dev, RT2460, value, reg); | ||
| 1395 | |||
| 1396 | if (!rt2x00_rf(&rt2x00dev->chip, RF2420) && | ||
| 1397 | !rt2x00_rf(&rt2x00dev->chip, RF2421)) { | ||
| 1398 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | ||
| 1399 | return -ENODEV; | ||
| 1400 | } | ||
| 1401 | |||
| 1402 | /* | ||
| 1403 | * Identify default antenna configuration. | ||
| 1404 | */ | ||
| 1405 | rt2x00dev->hw->conf.antenna_sel_tx = | ||
| 1406 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT); | ||
| 1407 | rt2x00dev->hw->conf.antenna_sel_rx = | ||
| 1408 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT); | ||
| 1409 | |||
| 1410 | /* | ||
| 1411 | * Store led mode, for correct led behaviour. | ||
| 1412 | */ | ||
| 1413 | rt2x00dev->led_mode = | ||
| 1414 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | ||
| 1415 | |||
| 1416 | /* | ||
| 1417 | * Detect if this device has an hardware controlled radio. | ||
| 1418 | */ | ||
| 1419 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) | ||
| 1420 | __set_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | ||
| 1421 | |||
| 1422 | /* | ||
| 1423 | * Check if the BBP tuning should be enabled. | ||
| 1424 | */ | ||
| 1425 | if (!rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_AGCVGC_TUNING)) | ||
| 1426 | __set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags); | ||
| 1427 | |||
| 1428 | return 0; | ||
| 1429 | } | ||
| 1430 | |||
| 1431 | /* | ||
| 1432 | * RF value list for RF2420 & RF2421 | ||
| 1433 | * Supports: 2.4 GHz | ||
| 1434 | */ | ||
| 1435 | static const struct rf_channel rf_vals_bg[] = { | ||
| 1436 | { 1, 0x00022058, 0x000c1fda, 0x00000101, 0 }, | ||
| 1437 | { 2, 0x00022058, 0x000c1fee, 0x00000101, 0 }, | ||
| 1438 | { 3, 0x00022058, 0x000c2002, 0x00000101, 0 }, | ||
| 1439 | { 4, 0x00022058, 0x000c2016, 0x00000101, 0 }, | ||
| 1440 | { 5, 0x00022058, 0x000c202a, 0x00000101, 0 }, | ||
| 1441 | { 6, 0x00022058, 0x000c203e, 0x00000101, 0 }, | ||
| 1442 | { 7, 0x00022058, 0x000c2052, 0x00000101, 0 }, | ||
| 1443 | { 8, 0x00022058, 0x000c2066, 0x00000101, 0 }, | ||
| 1444 | { 9, 0x00022058, 0x000c207a, 0x00000101, 0 }, | ||
| 1445 | { 10, 0x00022058, 0x000c208e, 0x00000101, 0 }, | ||
| 1446 | { 11, 0x00022058, 0x000c20a2, 0x00000101, 0 }, | ||
| 1447 | { 12, 0x00022058, 0x000c20b6, 0x00000101, 0 }, | ||
| 1448 | { 13, 0x00022058, 0x000c20ca, 0x00000101, 0 }, | ||
| 1449 | { 14, 0x00022058, 0x000c20fa, 0x00000101, 0 }, | ||
| 1450 | }; | ||
| 1451 | |||
| 1452 | static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | ||
| 1453 | { | ||
| 1454 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
| 1455 | u8 *txpower; | ||
| 1456 | unsigned int i; | ||
| 1457 | |||
| 1458 | /* | ||
| 1459 | * Initialize all hw fields. | ||
| 1460 | */ | ||
| 1461 | rt2x00dev->hw->flags = | ||
| 1462 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
| 1463 | IEEE80211_HW_MONITOR_DURING_OPER | | ||
| 1464 | IEEE80211_HW_NO_PROBE_FILTERING; | ||
| 1465 | rt2x00dev->hw->extra_tx_headroom = 0; | ||
| 1466 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | ||
| 1467 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | ||
| 1468 | rt2x00dev->hw->queues = 2; | ||
| 1469 | |||
| 1470 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | ||
| 1471 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | ||
| 1472 | rt2x00_eeprom_addr(rt2x00dev, | ||
| 1473 | EEPROM_MAC_ADDR_0)); | ||
| 1474 | |||
| 1475 | /* | ||
| 1476 | * Convert tx_power array in eeprom. | ||
| 1477 | */ | ||
| 1478 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); | ||
| 1479 | for (i = 0; i < 14; i++) | ||
| 1480 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | ||
| 1481 | |||
| 1482 | /* | ||
| 1483 | * Initialize hw_mode information. | ||
| 1484 | */ | ||
| 1485 | spec->num_modes = 1; | ||
| 1486 | spec->num_rates = 4; | ||
| 1487 | spec->tx_power_a = NULL; | ||
| 1488 | spec->tx_power_bg = txpower; | ||
| 1489 | spec->tx_power_default = DEFAULT_TXPOWER; | ||
| 1490 | |||
| 1491 | spec->num_channels = ARRAY_SIZE(rf_vals_bg); | ||
| 1492 | spec->channels = rf_vals_bg; | ||
| 1493 | } | ||
| 1494 | |||
| 1495 | static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | ||
| 1496 | { | ||
| 1497 | int retval; | ||
| 1498 | |||
| 1499 | /* | ||
| 1500 | * Allocate eeprom data. | ||
| 1501 | */ | ||
| 1502 | retval = rt2400pci_validate_eeprom(rt2x00dev); | ||
| 1503 | if (retval) | ||
| 1504 | return retval; | ||
| 1505 | |||
| 1506 | retval = rt2400pci_init_eeprom(rt2x00dev); | ||
| 1507 | if (retval) | ||
| 1508 | return retval; | ||
| 1509 | |||
| 1510 | /* | ||
| 1511 | * Initialize hw specifications. | ||
| 1512 | */ | ||
| 1513 | rt2400pci_probe_hw_mode(rt2x00dev); | ||
| 1514 | |||
| 1515 | /* | ||
| 1516 | * This device requires the beacon ring | ||
| 1517 | */ | ||
| 1518 | __set_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags); | ||
| 1519 | |||
| 1520 | /* | ||
| 1521 | * Set the rssi offset. | ||
| 1522 | */ | ||
| 1523 | rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET; | ||
| 1524 | |||
| 1525 | return 0; | ||
| 1526 | } | ||
| 1527 | |||
| 1528 | /* | ||
| 1529 | * IEEE80211 stack callback functions. | ||
| 1530 | */ | ||
| 1531 | static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw, | ||
| 1532 | u32 short_retry, u32 long_retry) | ||
| 1533 | { | ||
| 1534 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1535 | u32 reg; | ||
| 1536 | |||
| 1537 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | ||
| 1538 | rt2x00_set_field32(®, CSR11_LONG_RETRY, long_retry); | ||
| 1539 | rt2x00_set_field32(®, CSR11_SHORT_RETRY, short_retry); | ||
| 1540 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | ||
| 1541 | |||
| 1542 | return 0; | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | static int rt2400pci_conf_tx(struct ieee80211_hw *hw, | ||
| 1546 | int queue, | ||
| 1547 | const struct ieee80211_tx_queue_params *params) | ||
| 1548 | { | ||
| 1549 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1550 | |||
| 1551 | /* | ||
| 1552 | * We don't support variating cw_min and cw_max variables | ||
| 1553 | * per queue. So by default we only configure the TX queue, | ||
| 1554 | * and ignore all other configurations. | ||
| 1555 | */ | ||
| 1556 | if (queue != IEEE80211_TX_QUEUE_DATA0) | ||
| 1557 | return -EINVAL; | ||
| 1558 | |||
| 1559 | if (rt2x00mac_conf_tx(hw, queue, params)) | ||
| 1560 | return -EINVAL; | ||
| 1561 | |||
| 1562 | /* | ||
| 1563 | * Write configuration to register. | ||
| 1564 | */ | ||
| 1565 | rt2400pci_config_cw(rt2x00dev, &rt2x00dev->tx->tx_params); | ||
| 1566 | |||
| 1567 | return 0; | ||
| 1568 | } | ||
| 1569 | |||
| 1570 | static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw) | ||
| 1571 | { | ||
| 1572 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1573 | u64 tsf; | ||
| 1574 | u32 reg; | ||
| 1575 | |||
| 1576 | rt2x00pci_register_read(rt2x00dev, CSR17, ®); | ||
| 1577 | tsf = (u64) rt2x00_get_field32(reg, CSR17_HIGH_TSFTIMER) << 32; | ||
| 1578 | rt2x00pci_register_read(rt2x00dev, CSR16, ®); | ||
| 1579 | tsf |= rt2x00_get_field32(reg, CSR16_LOW_TSFTIMER); | ||
| 1580 | |||
| 1581 | return tsf; | ||
| 1582 | } | ||
| 1583 | |||
| 1584 | static void rt2400pci_reset_tsf(struct ieee80211_hw *hw) | ||
| 1585 | { | ||
| 1586 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1587 | |||
| 1588 | rt2x00pci_register_write(rt2x00dev, CSR16, 0); | ||
| 1589 | rt2x00pci_register_write(rt2x00dev, CSR17, 0); | ||
| 1590 | } | ||
| 1591 | |||
| 1592 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) | ||
| 1593 | { | ||
| 1594 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1595 | u32 reg; | ||
| 1596 | |||
| 1597 | rt2x00pci_register_read(rt2x00dev, CSR15, ®); | ||
| 1598 | return rt2x00_get_field32(reg, CSR15_BEACON_SENT); | ||
| 1599 | } | ||
| 1600 | |||
| 1601 | static const struct ieee80211_ops rt2400pci_mac80211_ops = { | ||
| 1602 | .tx = rt2x00mac_tx, | ||
| 1603 | .add_interface = rt2x00mac_add_interface, | ||
| 1604 | .remove_interface = rt2x00mac_remove_interface, | ||
| 1605 | .config = rt2x00mac_config, | ||
| 1606 | .config_interface = rt2x00mac_config_interface, | ||
| 1607 | .set_multicast_list = rt2x00mac_set_multicast_list, | ||
| 1608 | .get_stats = rt2x00mac_get_stats, | ||
| 1609 | .set_retry_limit = rt2400pci_set_retry_limit, | ||
| 1610 | .conf_tx = rt2400pci_conf_tx, | ||
| 1611 | .get_tx_stats = rt2x00mac_get_tx_stats, | ||
| 1612 | .get_tsf = rt2400pci_get_tsf, | ||
| 1613 | .reset_tsf = rt2400pci_reset_tsf, | ||
| 1614 | .beacon_update = rt2x00pci_beacon_update, | ||
| 1615 | .tx_last_beacon = rt2400pci_tx_last_beacon, | ||
| 1616 | }; | ||
| 1617 | |||
| 1618 | static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | ||
| 1619 | .irq_handler = rt2400pci_interrupt, | ||
| 1620 | .probe_hw = rt2400pci_probe_hw, | ||
| 1621 | .initialize = rt2x00pci_initialize, | ||
| 1622 | .uninitialize = rt2x00pci_uninitialize, | ||
| 1623 | .set_device_state = rt2400pci_set_device_state, | ||
| 1624 | #ifdef CONFIG_RT2400PCI_RFKILL | ||
| 1625 | .rfkill_poll = rt2400pci_rfkill_poll, | ||
| 1626 | #endif /* CONFIG_RT2400PCI_RFKILL */ | ||
| 1627 | .link_stats = rt2400pci_link_stats, | ||
| 1628 | .reset_tuner = rt2400pci_reset_tuner, | ||
| 1629 | .link_tuner = rt2400pci_link_tuner, | ||
| 1630 | .write_tx_desc = rt2400pci_write_tx_desc, | ||
| 1631 | .write_tx_data = rt2x00pci_write_tx_data, | ||
| 1632 | .kick_tx_queue = rt2400pci_kick_tx_queue, | ||
| 1633 | .fill_rxdone = rt2400pci_fill_rxdone, | ||
| 1634 | .config_mac_addr = rt2400pci_config_mac_addr, | ||
| 1635 | .config_bssid = rt2400pci_config_bssid, | ||
| 1636 | .config_packet_filter = rt2400pci_config_packet_filter, | ||
| 1637 | .config_type = rt2400pci_config_type, | ||
| 1638 | .config = rt2400pci_config, | ||
| 1639 | }; | ||
| 1640 | |||
| 1641 | static const struct rt2x00_ops rt2400pci_ops = { | ||
| 1642 | .name = DRV_NAME, | ||
| 1643 | .rxd_size = RXD_DESC_SIZE, | ||
| 1644 | .txd_size = TXD_DESC_SIZE, | ||
| 1645 | .eeprom_size = EEPROM_SIZE, | ||
| 1646 | .rf_size = RF_SIZE, | ||
| 1647 | .lib = &rt2400pci_rt2x00_ops, | ||
| 1648 | .hw = &rt2400pci_mac80211_ops, | ||
| 1649 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
| 1650 | .debugfs = &rt2400pci_rt2x00debug, | ||
| 1651 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
| 1652 | }; | ||
| 1653 | |||
| 1654 | /* | ||
| 1655 | * RT2400pci module information. | ||
| 1656 | */ | ||
| 1657 | static struct pci_device_id rt2400pci_device_table[] = { | ||
| 1658 | { PCI_DEVICE(0x1814, 0x0101), PCI_DEVICE_DATA(&rt2400pci_ops) }, | ||
| 1659 | { 0, } | ||
| 1660 | }; | ||
| 1661 | |||
| 1662 | MODULE_AUTHOR(DRV_PROJECT); | ||
| 1663 | MODULE_VERSION(DRV_VERSION); | ||
| 1664 | MODULE_DESCRIPTION("Ralink RT2400 PCI & PCMCIA Wireless LAN driver."); | ||
| 1665 | MODULE_SUPPORTED_DEVICE("Ralink RT2460 PCI & PCMCIA chipset based cards"); | ||
| 1666 | MODULE_DEVICE_TABLE(pci, rt2400pci_device_table); | ||
| 1667 | MODULE_LICENSE("GPL"); | ||
| 1668 | |||
| 1669 | static struct pci_driver rt2400pci_driver = { | ||
| 1670 | .name = DRV_NAME, | ||
| 1671 | .id_table = rt2400pci_device_table, | ||
| 1672 | .probe = rt2x00pci_probe, | ||
| 1673 | .remove = __devexit_p(rt2x00pci_remove), | ||
| 1674 | .suspend = rt2x00pci_suspend, | ||
| 1675 | .resume = rt2x00pci_resume, | ||
| 1676 | }; | ||
| 1677 | |||
| 1678 | static int __init rt2400pci_init(void) | ||
| 1679 | { | ||
| 1680 | return pci_register_driver(&rt2400pci_driver); | ||
| 1681 | } | ||
| 1682 | |||
| 1683 | static void __exit rt2400pci_exit(void) | ||
| 1684 | { | ||
| 1685 | pci_unregister_driver(&rt2400pci_driver); | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | module_init(rt2400pci_init); | ||
| 1689 | module_exit(rt2400pci_exit); | ||
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h new file mode 100644 index 00000000000..ae22501f085 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2400pci.h | |||
| @@ -0,0 +1,943 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2400pci | ||
| 23 | Abstract: Data structures and registers for the rt2400pci module. | ||
| 24 | Supported chipsets: RT2460. | ||
| 25 | */ | ||
| 26 | |||
| 27 | #ifndef RT2400PCI_H | ||
| 28 | #define RT2400PCI_H | ||
| 29 | |||
| 30 | /* | ||
| 31 | * RF chip defines. | ||
| 32 | */ | ||
| 33 | #define RF2420 0x0000 | ||
| 34 | #define RF2421 0x0001 | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Signal information. | ||
| 38 | * Defaul offset is required for RSSI <-> dBm conversion. | ||
| 39 | */ | ||
| 40 | #define MAX_SIGNAL 100 | ||
| 41 | #define MAX_RX_SSI -1 | ||
| 42 | #define DEFAULT_RSSI_OFFSET 100 | ||
| 43 | |||
| 44 | /* | ||
| 45 | * Register layout information. | ||
| 46 | */ | ||
| 47 | #define CSR_REG_BASE 0x0000 | ||
| 48 | #define CSR_REG_SIZE 0x014c | ||
| 49 | #define EEPROM_BASE 0x0000 | ||
| 50 | #define EEPROM_SIZE 0x0100 | ||
| 51 | #define BBP_SIZE 0x0020 | ||
| 52 | #define RF_SIZE 0x0010 | ||
| 53 | |||
| 54 | /* | ||
| 55 | * Control/Status Registers(CSR). | ||
| 56 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 57 | */ | ||
| 58 | |||
| 59 | /* | ||
| 60 | * CSR0: ASIC revision number. | ||
| 61 | */ | ||
| 62 | #define CSR0 0x0000 | ||
| 63 | |||
| 64 | /* | ||
| 65 | * CSR1: System control register. | ||
| 66 | * SOFT_RESET: Software reset, 1: reset, 0: normal. | ||
| 67 | * BBP_RESET: Hardware reset, 1: reset, 0, release. | ||
| 68 | * HOST_READY: Host ready after initialization. | ||
| 69 | */ | ||
| 70 | #define CSR1 0x0004 | ||
| 71 | #define CSR1_SOFT_RESET FIELD32(0x00000001) | ||
| 72 | #define CSR1_BBP_RESET FIELD32(0x00000002) | ||
| 73 | #define CSR1_HOST_READY FIELD32(0x00000004) | ||
| 74 | |||
| 75 | /* | ||
| 76 | * CSR2: System admin status register (invalid). | ||
| 77 | */ | ||
| 78 | #define CSR2 0x0008 | ||
| 79 | |||
| 80 | /* | ||
| 81 | * CSR3: STA MAC address register 0. | ||
| 82 | */ | ||
| 83 | #define CSR3 0x000c | ||
| 84 | #define CSR3_BYTE0 FIELD32(0x000000ff) | ||
| 85 | #define CSR3_BYTE1 FIELD32(0x0000ff00) | ||
| 86 | #define CSR3_BYTE2 FIELD32(0x00ff0000) | ||
| 87 | #define CSR3_BYTE3 FIELD32(0xff000000) | ||
| 88 | |||
| 89 | /* | ||
| 90 | * CSR4: STA MAC address register 1. | ||
| 91 | */ | ||
| 92 | #define CSR4 0x0010 | ||
| 93 | #define CSR4_BYTE4 FIELD32(0x000000ff) | ||
| 94 | #define CSR4_BYTE5 FIELD32(0x0000ff00) | ||
| 95 | |||
| 96 | /* | ||
| 97 | * CSR5: BSSID register 0. | ||
| 98 | */ | ||
| 99 | #define CSR5 0x0014 | ||
| 100 | #define CSR5_BYTE0 FIELD32(0x000000ff) | ||
| 101 | #define CSR5_BYTE1 FIELD32(0x0000ff00) | ||
| 102 | #define CSR5_BYTE2 FIELD32(0x00ff0000) | ||
| 103 | #define CSR5_BYTE3 FIELD32(0xff000000) | ||
| 104 | |||
| 105 | /* | ||
| 106 | * CSR6: BSSID register 1. | ||
| 107 | */ | ||
| 108 | #define CSR6 0x0018 | ||
| 109 | #define CSR6_BYTE4 FIELD32(0x000000ff) | ||
| 110 | #define CSR6_BYTE5 FIELD32(0x0000ff00) | ||
| 111 | |||
| 112 | /* | ||
| 113 | * CSR7: Interrupt source register. | ||
| 114 | * Write 1 to clear interrupt. | ||
| 115 | * TBCN_EXPIRE: Beacon timer expired interrupt. | ||
| 116 | * TWAKE_EXPIRE: Wakeup timer expired interrupt. | ||
| 117 | * TATIMW_EXPIRE: Timer of atim window expired interrupt. | ||
| 118 | * TXDONE_TXRING: Tx ring transmit done interrupt. | ||
| 119 | * TXDONE_ATIMRING: Atim ring transmit done interrupt. | ||
| 120 | * TXDONE_PRIORING: Priority ring transmit done interrupt. | ||
| 121 | * RXDONE: Receive done interrupt. | ||
| 122 | */ | ||
| 123 | #define CSR7 0x001c | ||
| 124 | #define CSR7_TBCN_EXPIRE FIELD32(0x00000001) | ||
| 125 | #define CSR7_TWAKE_EXPIRE FIELD32(0x00000002) | ||
| 126 | #define CSR7_TATIMW_EXPIRE FIELD32(0x00000004) | ||
| 127 | #define CSR7_TXDONE_TXRING FIELD32(0x00000008) | ||
| 128 | #define CSR7_TXDONE_ATIMRING FIELD32(0x00000010) | ||
| 129 | #define CSR7_TXDONE_PRIORING FIELD32(0x00000020) | ||
| 130 | #define CSR7_RXDONE FIELD32(0x00000040) | ||
| 131 | |||
| 132 | /* | ||
| 133 | * CSR8: Interrupt mask register. | ||
| 134 | * Write 1 to mask interrupt. | ||
| 135 | * TBCN_EXPIRE: Beacon timer expired interrupt. | ||
| 136 | * TWAKE_EXPIRE: Wakeup timer expired interrupt. | ||
| 137 | * TATIMW_EXPIRE: Timer of atim window expired interrupt. | ||
| 138 | * TXDONE_TXRING: Tx ring transmit done interrupt. | ||
| 139 | * TXDONE_ATIMRING: Atim ring transmit done interrupt. | ||
| 140 | * TXDONE_PRIORING: Priority ring transmit done interrupt. | ||
| 141 | * RXDONE: Receive done interrupt. | ||
| 142 | */ | ||
| 143 | #define CSR8 0x0020 | ||
| 144 | #define CSR8_TBCN_EXPIRE FIELD32(0x00000001) | ||
| 145 | #define CSR8_TWAKE_EXPIRE FIELD32(0x00000002) | ||
| 146 | #define CSR8_TATIMW_EXPIRE FIELD32(0x00000004) | ||
| 147 | #define CSR8_TXDONE_TXRING FIELD32(0x00000008) | ||
| 148 | #define CSR8_TXDONE_ATIMRING FIELD32(0x00000010) | ||
| 149 | #define CSR8_TXDONE_PRIORING FIELD32(0x00000020) | ||
| 150 | #define CSR8_RXDONE FIELD32(0x00000040) | ||
| 151 | |||
| 152 | /* | ||
| 153 | * CSR9: Maximum frame length register. | ||
| 154 | * MAX_FRAME_UNIT: Maximum frame length in 128b unit, default: 12. | ||
| 155 | */ | ||
| 156 | #define CSR9 0x0024 | ||
| 157 | #define CSR9_MAX_FRAME_UNIT FIELD32(0x00000f80) | ||
| 158 | |||
| 159 | /* | ||
| 160 | * CSR11: Back-off control register. | ||
| 161 | * CWMIN: CWmin. Default cwmin is 31 (2^5 - 1). | ||
| 162 | * CWMAX: CWmax. Default cwmax is 1023 (2^10 - 1). | ||
| 163 | * SLOT_TIME: Slot time, default is 20us for 802.11b. | ||
| 164 | * LONG_RETRY: Long retry count. | ||
| 165 | * SHORT_RETRY: Short retry count. | ||
| 166 | */ | ||
| 167 | #define CSR11 0x002c | ||
| 168 | #define CSR11_CWMIN FIELD32(0x0000000f) | ||
| 169 | #define CSR11_CWMAX FIELD32(0x000000f0) | ||
| 170 | #define CSR11_SLOT_TIME FIELD32(0x00001f00) | ||
| 171 | #define CSR11_LONG_RETRY FIELD32(0x00ff0000) | ||
| 172 | #define CSR11_SHORT_RETRY FIELD32(0xff000000) | ||
| 173 | |||
| 174 | /* | ||
| 175 | * CSR12: Synchronization configuration register 0. | ||
| 176 | * All units in 1/16 TU. | ||
| 177 | * BEACON_INTERVAL: Beacon interval, default is 100 TU. | ||
| 178 | * CFPMAX_DURATION: Cfp maximum duration, default is 100 TU. | ||
| 179 | */ | ||
| 180 | #define CSR12 0x0030 | ||
| 181 | #define CSR12_BEACON_INTERVAL FIELD32(0x0000ffff) | ||
| 182 | #define CSR12_CFP_MAX_DURATION FIELD32(0xffff0000) | ||
| 183 | |||
| 184 | /* | ||
| 185 | * CSR13: Synchronization configuration register 1. | ||
| 186 | * All units in 1/16 TU. | ||
| 187 | * ATIMW_DURATION: Atim window duration. | ||
| 188 | * CFP_PERIOD: Cfp period, default is 0 TU. | ||
| 189 | */ | ||
| 190 | #define CSR13 0x0034 | ||
| 191 | #define CSR13_ATIMW_DURATION FIELD32(0x0000ffff) | ||
| 192 | #define CSR13_CFP_PERIOD FIELD32(0x00ff0000) | ||
| 193 | |||
| 194 | /* | ||
| 195 | * CSR14: Synchronization control register. | ||
| 196 | * TSF_COUNT: Enable tsf auto counting. | ||
| 197 | * TSF_SYNC: Tsf sync, 0: disable, 1: infra, 2: ad-hoc/master mode. | ||
| 198 | * TBCN: Enable tbcn with reload value. | ||
| 199 | * TCFP: Enable tcfp & cfp / cp switching. | ||
| 200 | * TATIMW: Enable tatimw & atim window switching. | ||
| 201 | * BEACON_GEN: Enable beacon generator. | ||
| 202 | * CFP_COUNT_PRELOAD: Cfp count preload value. | ||
| 203 | * TBCM_PRELOAD: Tbcn preload value in units of 64us. | ||
| 204 | */ | ||
| 205 | #define CSR14 0x0038 | ||
| 206 | #define CSR14_TSF_COUNT FIELD32(0x00000001) | ||
| 207 | #define CSR14_TSF_SYNC FIELD32(0x00000006) | ||
| 208 | #define CSR14_TBCN FIELD32(0x00000008) | ||
| 209 | #define CSR14_TCFP FIELD32(0x00000010) | ||
| 210 | #define CSR14_TATIMW FIELD32(0x00000020) | ||
| 211 | #define CSR14_BEACON_GEN FIELD32(0x00000040) | ||
| 212 | #define CSR14_CFP_COUNT_PRELOAD FIELD32(0x0000ff00) | ||
| 213 | #define CSR14_TBCM_PRELOAD FIELD32(0xffff0000) | ||
| 214 | |||
| 215 | /* | ||
| 216 | * CSR15: Synchronization status register. | ||
| 217 | * CFP: ASIC is in contention-free period. | ||
| 218 | * ATIMW: ASIC is in ATIM window. | ||
| 219 | * BEACON_SENT: Beacon is send. | ||
| 220 | */ | ||
| 221 | #define CSR15 0x003c | ||
| 222 | #define CSR15_CFP FIELD32(0x00000001) | ||
| 223 | #define CSR15_ATIMW FIELD32(0x00000002) | ||
| 224 | #define CSR15_BEACON_SENT FIELD32(0x00000004) | ||
| 225 | |||
| 226 | /* | ||
| 227 | * CSR16: TSF timer register 0. | ||
| 228 | */ | ||
| 229 | #define CSR16 0x0040 | ||
| 230 | #define CSR16_LOW_TSFTIMER FIELD32(0xffffffff) | ||
| 231 | |||
| 232 | /* | ||
| 233 | * CSR17: TSF timer register 1. | ||
| 234 | */ | ||
| 235 | #define CSR17 0x0044 | ||
| 236 | #define CSR17_HIGH_TSFTIMER FIELD32(0xffffffff) | ||
| 237 | |||
| 238 | /* | ||
| 239 | * CSR18: IFS timer register 0. | ||
| 240 | * SIFS: Sifs, default is 10 us. | ||
| 241 | * PIFS: Pifs, default is 30 us. | ||
| 242 | */ | ||
| 243 | #define CSR18 0x0048 | ||
| 244 | #define CSR18_SIFS FIELD32(0x0000ffff) | ||
| 245 | #define CSR18_PIFS FIELD32(0xffff0000) | ||
| 246 | |||
| 247 | /* | ||
| 248 | * CSR19: IFS timer register 1. | ||
| 249 | * DIFS: Difs, default is 50 us. | ||
| 250 | * EIFS: Eifs, default is 364 us. | ||
| 251 | */ | ||
| 252 | #define CSR19 0x004c | ||
| 253 | #define CSR19_DIFS FIELD32(0x0000ffff) | ||
| 254 | #define CSR19_EIFS FIELD32(0xffff0000) | ||
| 255 | |||
| 256 | /* | ||
| 257 | * CSR20: Wakeup timer register. | ||
| 258 | * DELAY_AFTER_TBCN: Delay after tbcn expired in units of 1/16 TU. | ||
| 259 | * TBCN_BEFORE_WAKEUP: Number of beacon before wakeup. | ||
| 260 | * AUTOWAKE: Enable auto wakeup / sleep mechanism. | ||
| 261 | */ | ||
| 262 | #define CSR20 0x0050 | ||
| 263 | #define CSR20_DELAY_AFTER_TBCN FIELD32(0x0000ffff) | ||
| 264 | #define CSR20_TBCN_BEFORE_WAKEUP FIELD32(0x00ff0000) | ||
| 265 | #define CSR20_AUTOWAKE FIELD32(0x01000000) | ||
| 266 | |||
| 267 | /* | ||
| 268 | * CSR21: EEPROM control register. | ||
| 269 | * RELOAD: Write 1 to reload eeprom content. | ||
| 270 | * TYPE_93C46: 1: 93c46, 0:93c66. | ||
| 271 | */ | ||
| 272 | #define CSR21 0x0054 | ||
| 273 | #define CSR21_RELOAD FIELD32(0x00000001) | ||
| 274 | #define CSR21_EEPROM_DATA_CLOCK FIELD32(0x00000002) | ||
| 275 | #define CSR21_EEPROM_CHIP_SELECT FIELD32(0x00000004) | ||
| 276 | #define CSR21_EEPROM_DATA_IN FIELD32(0x00000008) | ||
| 277 | #define CSR21_EEPROM_DATA_OUT FIELD32(0x00000010) | ||
| 278 | #define CSR21_TYPE_93C46 FIELD32(0x00000020) | ||
| 279 | |||
| 280 | /* | ||
| 281 | * CSR22: CFP control register. | ||
| 282 | * CFP_DURATION_REMAIN: Cfp duration remain, in units of TU. | ||
| 283 | * RELOAD_CFP_DURATION: Write 1 to reload cfp duration remain. | ||
| 284 | */ | ||
| 285 | #define CSR22 0x0058 | ||
| 286 | #define CSR22_CFP_DURATION_REMAIN FIELD32(0x0000ffff) | ||
| 287 | #define CSR22_RELOAD_CFP_DURATION FIELD32(0x00010000) | ||
| 288 | |||
| 289 | /* | ||
| 290 | * Transmit related CSRs. | ||
| 291 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 292 | */ | ||
| 293 | |||
| 294 | /* | ||
| 295 | * TXCSR0: TX Control Register. | ||
| 296 | * KICK_TX: Kick tx ring. | ||
| 297 | * KICK_ATIM: Kick atim ring. | ||
| 298 | * KICK_PRIO: Kick priority ring. | ||
| 299 | * ABORT: Abort all transmit related ring operation. | ||
| 300 | */ | ||
| 301 | #define TXCSR0 0x0060 | ||
| 302 | #define TXCSR0_KICK_TX FIELD32(0x00000001) | ||
| 303 | #define TXCSR0_KICK_ATIM FIELD32(0x00000002) | ||
| 304 | #define TXCSR0_KICK_PRIO FIELD32(0x00000004) | ||
| 305 | #define TXCSR0_ABORT FIELD32(0x00000008) | ||
| 306 | |||
| 307 | /* | ||
| 308 | * TXCSR1: TX Configuration Register. | ||
| 309 | * ACK_TIMEOUT: Ack timeout, default = sifs + 2*slottime + acktime @ 1mbps. | ||
| 310 | * ACK_CONSUME_TIME: Ack consume time, default = sifs + acktime @ 1mbps. | ||
| 311 | * TSF_OFFSET: Insert tsf offset. | ||
| 312 | * AUTORESPONDER: Enable auto responder which include ack & cts. | ||
| 313 | */ | ||
| 314 | #define TXCSR1 0x0064 | ||
| 315 | #define TXCSR1_ACK_TIMEOUT FIELD32(0x000001ff) | ||
| 316 | #define TXCSR1_ACK_CONSUME_TIME FIELD32(0x0003fe00) | ||
| 317 | #define TXCSR1_TSF_OFFSET FIELD32(0x00fc0000) | ||
| 318 | #define TXCSR1_AUTORESPONDER FIELD32(0x01000000) | ||
| 319 | |||
| 320 | /* | ||
| 321 | * TXCSR2: Tx descriptor configuration register. | ||
| 322 | * TXD_SIZE: Tx descriptor size, default is 48. | ||
| 323 | * NUM_TXD: Number of tx entries in ring. | ||
| 324 | * NUM_ATIM: Number of atim entries in ring. | ||
| 325 | * NUM_PRIO: Number of priority entries in ring. | ||
| 326 | */ | ||
| 327 | #define TXCSR2 0x0068 | ||
| 328 | #define TXCSR2_TXD_SIZE FIELD32(0x000000ff) | ||
| 329 | #define TXCSR2_NUM_TXD FIELD32(0x0000ff00) | ||
| 330 | #define TXCSR2_NUM_ATIM FIELD32(0x00ff0000) | ||
| 331 | #define TXCSR2_NUM_PRIO FIELD32(0xff000000) | ||
| 332 | |||
| 333 | /* | ||
| 334 | * TXCSR3: TX Ring Base address register. | ||
| 335 | */ | ||
| 336 | #define TXCSR3 0x006c | ||
| 337 | #define TXCSR3_TX_RING_REGISTER FIELD32(0xffffffff) | ||
| 338 | |||
| 339 | /* | ||
| 340 | * TXCSR4: TX Atim Ring Base address register. | ||
| 341 | */ | ||
| 342 | #define TXCSR4 0x0070 | ||
| 343 | #define TXCSR4_ATIM_RING_REGISTER FIELD32(0xffffffff) | ||
| 344 | |||
| 345 | /* | ||
| 346 | * TXCSR5: TX Prio Ring Base address register. | ||
| 347 | */ | ||
| 348 | #define TXCSR5 0x0074 | ||
| 349 | #define TXCSR5_PRIO_RING_REGISTER FIELD32(0xffffffff) | ||
| 350 | |||
| 351 | /* | ||
| 352 | * TXCSR6: Beacon Base address register. | ||
| 353 | */ | ||
| 354 | #define TXCSR6 0x0078 | ||
| 355 | #define TXCSR6_BEACON_RING_REGISTER FIELD32(0xffffffff) | ||
| 356 | |||
| 357 | /* | ||
| 358 | * TXCSR7: Auto responder control register. | ||
| 359 | * AR_POWERMANAGEMENT: Auto responder power management bit. | ||
| 360 | */ | ||
| 361 | #define TXCSR7 0x007c | ||
| 362 | #define TXCSR7_AR_POWERMANAGEMENT FIELD32(0x00000001) | ||
| 363 | |||
| 364 | /* | ||
| 365 | * Receive related CSRs. | ||
| 366 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 367 | */ | ||
| 368 | |||
| 369 | /* | ||
| 370 | * RXCSR0: RX Control Register. | ||
| 371 | * DISABLE_RX: Disable rx engine. | ||
| 372 | * DROP_CRC: Drop crc error. | ||
| 373 | * DROP_PHYSICAL: Drop physical error. | ||
| 374 | * DROP_CONTROL: Drop control frame. | ||
| 375 | * DROP_NOT_TO_ME: Drop not to me unicast frame. | ||
| 376 | * DROP_TODS: Drop frame tods bit is true. | ||
| 377 | * DROP_VERSION_ERROR: Drop version error frame. | ||
| 378 | * PASS_CRC: Pass all packets with crc attached. | ||
| 379 | */ | ||
| 380 | #define RXCSR0 0x0080 | ||
| 381 | #define RXCSR0_DISABLE_RX FIELD32(0x00000001) | ||
| 382 | #define RXCSR0_DROP_CRC FIELD32(0x00000002) | ||
| 383 | #define RXCSR0_DROP_PHYSICAL FIELD32(0x00000004) | ||
| 384 | #define RXCSR0_DROP_CONTROL FIELD32(0x00000008) | ||
| 385 | #define RXCSR0_DROP_NOT_TO_ME FIELD32(0x00000010) | ||
| 386 | #define RXCSR0_DROP_TODS FIELD32(0x00000020) | ||
| 387 | #define RXCSR0_DROP_VERSION_ERROR FIELD32(0x00000040) | ||
| 388 | #define RXCSR0_PASS_CRC FIELD32(0x00000080) | ||
| 389 | |||
| 390 | /* | ||
| 391 | * RXCSR1: RX descriptor configuration register. | ||
| 392 | * RXD_SIZE: Rx descriptor size, default is 32b. | ||
| 393 | * NUM_RXD: Number of rx entries in ring. | ||
| 394 | */ | ||
| 395 | #define RXCSR1 0x0084 | ||
| 396 | #define RXCSR1_RXD_SIZE FIELD32(0x000000ff) | ||
| 397 | #define RXCSR1_NUM_RXD FIELD32(0x0000ff00) | ||
| 398 | |||
| 399 | /* | ||
| 400 | * RXCSR2: RX Ring base address register. | ||
| 401 | */ | ||
| 402 | #define RXCSR2 0x0088 | ||
| 403 | #define RXCSR2_RX_RING_REGISTER FIELD32(0xffffffff) | ||
| 404 | |||
| 405 | /* | ||
| 406 | * RXCSR3: BBP ID register for Rx operation. | ||
| 407 | * BBP_ID#: BBP register # id. | ||
| 408 | * BBP_ID#_VALID: BBP register # id is valid or not. | ||
| 409 | */ | ||
| 410 | #define RXCSR3 0x0090 | ||
| 411 | #define RXCSR3_BBP_ID0 FIELD32(0x0000007f) | ||
| 412 | #define RXCSR3_BBP_ID0_VALID FIELD32(0x00000080) | ||
| 413 | #define RXCSR3_BBP_ID1 FIELD32(0x00007f00) | ||
| 414 | #define RXCSR3_BBP_ID1_VALID FIELD32(0x00008000) | ||
| 415 | #define RXCSR3_BBP_ID2 FIELD32(0x007f0000) | ||
| 416 | #define RXCSR3_BBP_ID2_VALID FIELD32(0x00800000) | ||
| 417 | #define RXCSR3_BBP_ID3 FIELD32(0x7f000000) | ||
| 418 | #define RXCSR3_BBP_ID3_VALID FIELD32(0x80000000) | ||
| 419 | |||
| 420 | /* | ||
| 421 | * RXCSR4: BBP ID register for Rx operation. | ||
| 422 | * BBP_ID#: BBP register # id. | ||
| 423 | * BBP_ID#_VALID: BBP register # id is valid or not. | ||
| 424 | */ | ||
| 425 | #define RXCSR4 0x0094 | ||
| 426 | #define RXCSR4_BBP_ID4 FIELD32(0x0000007f) | ||
| 427 | #define RXCSR4_BBP_ID4_VALID FIELD32(0x00000080) | ||
| 428 | #define RXCSR4_BBP_ID5 FIELD32(0x00007f00) | ||
| 429 | #define RXCSR4_BBP_ID5_VALID FIELD32(0x00008000) | ||
| 430 | |||
| 431 | /* | ||
| 432 | * ARCSR0: Auto Responder PLCP config register 0. | ||
| 433 | * ARCSR0_AR_BBP_DATA#: Auto responder BBP register # data. | ||
| 434 | * ARCSR0_AR_BBP_ID#: Auto responder BBP register # Id. | ||
| 435 | */ | ||
| 436 | #define ARCSR0 0x0098 | ||
| 437 | #define ARCSR0_AR_BBP_DATA0 FIELD32(0x000000ff) | ||
| 438 | #define ARCSR0_AR_BBP_ID0 FIELD32(0x0000ff00) | ||
| 439 | #define ARCSR0_AR_BBP_DATA1 FIELD32(0x00ff0000) | ||
| 440 | #define ARCSR0_AR_BBP_ID1 FIELD32(0xff000000) | ||
| 441 | |||
| 442 | /* | ||
| 443 | * ARCSR1: Auto Responder PLCP config register 1. | ||
| 444 | * ARCSR0_AR_BBP_DATA#: Auto responder BBP register # data. | ||
| 445 | * ARCSR0_AR_BBP_ID#: Auto responder BBP register # Id. | ||
| 446 | */ | ||
| 447 | #define ARCSR1 0x009c | ||
| 448 | #define ARCSR1_AR_BBP_DATA2 FIELD32(0x000000ff) | ||
| 449 | #define ARCSR1_AR_BBP_ID2 FIELD32(0x0000ff00) | ||
| 450 | #define ARCSR1_AR_BBP_DATA3 FIELD32(0x00ff0000) | ||
| 451 | #define ARCSR1_AR_BBP_ID3 FIELD32(0xff000000) | ||
| 452 | |||
| 453 | /* | ||
| 454 | * Miscellaneous Registers. | ||
| 455 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 456 | */ | ||
| 457 | |||
| 458 | /* | ||
| 459 | * PCICSR: PCI control register. | ||
| 460 | * BIG_ENDIAN: 1: big endian, 0: little endian. | ||
| 461 | * RX_TRESHOLD: Rx threshold in dw to start pci access | ||
| 462 | * 0: 16dw (default), 1: 8dw, 2: 4dw, 3: 32dw. | ||
| 463 | * TX_TRESHOLD: Tx threshold in dw to start pci access | ||
| 464 | * 0: 0dw (default), 1: 1dw, 2: 4dw, 3: forward. | ||
| 465 | * BURST_LENTH: Pci burst length 0: 4dw (default, 1: 8dw, 2: 16dw, 3:32dw. | ||
| 466 | * ENABLE_CLK: Enable clk_run, pci clock can't going down to non-operational. | ||
| 467 | */ | ||
| 468 | #define PCICSR 0x008c | ||
| 469 | #define PCICSR_BIG_ENDIAN FIELD32(0x00000001) | ||
| 470 | #define PCICSR_RX_TRESHOLD FIELD32(0x00000006) | ||
| 471 | #define PCICSR_TX_TRESHOLD FIELD32(0x00000018) | ||
| 472 | #define PCICSR_BURST_LENTH FIELD32(0x00000060) | ||
| 473 | #define PCICSR_ENABLE_CLK FIELD32(0x00000080) | ||
| 474 | |||
| 475 | /* | ||
| 476 | * CNT0: FCS error count. | ||
| 477 | * FCS_ERROR: FCS error count, cleared when read. | ||
| 478 | */ | ||
| 479 | #define CNT0 0x00a0 | ||
| 480 | #define CNT0_FCS_ERROR FIELD32(0x0000ffff) | ||
| 481 | |||
| 482 | /* | ||
| 483 | * Statistic Register. | ||
| 484 | * CNT1: PLCP error count. | ||
| 485 | * CNT2: Long error count. | ||
| 486 | * CNT3: CCA false alarm count. | ||
| 487 | * CNT4: Rx FIFO overflow count. | ||
| 488 | * CNT5: Tx FIFO underrun count. | ||
| 489 | */ | ||
| 490 | #define TIMECSR2 0x00a8 | ||
| 491 | #define CNT1 0x00ac | ||
| 492 | #define CNT2 0x00b0 | ||
| 493 | #define TIMECSR3 0x00b4 | ||
| 494 | #define CNT3 0x00b8 | ||
| 495 | #define CNT4 0x00bc | ||
| 496 | #define CNT5 0x00c0 | ||
| 497 | |||
| 498 | /* | ||
| 499 | * Baseband Control Register. | ||
| 500 | */ | ||
| 501 | |||
| 502 | /* | ||
| 503 | * PWRCSR0: Power mode configuration register. | ||
| 504 | */ | ||
| 505 | #define PWRCSR0 0x00c4 | ||
| 506 | |||
| 507 | /* | ||
| 508 | * Power state transition time registers. | ||
| 509 | */ | ||
| 510 | #define PSCSR0 0x00c8 | ||
| 511 | #define PSCSR1 0x00cc | ||
| 512 | #define PSCSR2 0x00d0 | ||
| 513 | #define PSCSR3 0x00d4 | ||
| 514 | |||
| 515 | /* | ||
| 516 | * PWRCSR1: Manual power control / status register. | ||
| 517 | * Allowed state: 0 deep_sleep, 1: sleep, 2: standby, 3: awake. | ||
| 518 | * SET_STATE: Set state. Write 1 to trigger, self cleared. | ||
| 519 | * BBP_DESIRE_STATE: BBP desired state. | ||
| 520 | * RF_DESIRE_STATE: RF desired state. | ||
| 521 | * BBP_CURR_STATE: BBP current state. | ||
| 522 | * RF_CURR_STATE: RF current state. | ||
| 523 | * PUT_TO_SLEEP: Put to sleep. Write 1 to trigger, self cleared. | ||
| 524 | */ | ||
| 525 | #define PWRCSR1 0x00d8 | ||
| 526 | #define PWRCSR1_SET_STATE FIELD32(0x00000001) | ||
| 527 | #define PWRCSR1_BBP_DESIRE_STATE FIELD32(0x00000006) | ||
| 528 | #define PWRCSR1_RF_DESIRE_STATE FIELD32(0x00000018) | ||
| 529 | #define PWRCSR1_BBP_CURR_STATE FIELD32(0x00000060) | ||
| 530 | #define PWRCSR1_RF_CURR_STATE FIELD32(0x00000180) | ||
| 531 | #define PWRCSR1_PUT_TO_SLEEP FIELD32(0x00000200) | ||
| 532 | |||
| 533 | /* | ||
| 534 | * TIMECSR: Timer control register. | ||
| 535 | * US_COUNT: 1 us timer count in units of clock cycles. | ||
| 536 | * US_64_COUNT: 64 us timer count in units of 1 us timer. | ||
| 537 | * BEACON_EXPECT: Beacon expect window. | ||
| 538 | */ | ||
| 539 | #define TIMECSR 0x00dc | ||
| 540 | #define TIMECSR_US_COUNT FIELD32(0x000000ff) | ||
| 541 | #define TIMECSR_US_64_COUNT FIELD32(0x0000ff00) | ||
| 542 | #define TIMECSR_BEACON_EXPECT FIELD32(0x00070000) | ||
| 543 | |||
| 544 | /* | ||
| 545 | * MACCSR0: MAC configuration register 0. | ||
| 546 | */ | ||
| 547 | #define MACCSR0 0x00e0 | ||
| 548 | |||
| 549 | /* | ||
| 550 | * MACCSR1: MAC configuration register 1. | ||
| 551 | * KICK_RX: Kick one-shot rx in one-shot rx mode. | ||
| 552 | * ONESHOT_RXMODE: Enable one-shot rx mode for debugging. | ||
| 553 | * BBPRX_RESET_MODE: Ralink bbp rx reset mode. | ||
| 554 | * AUTO_TXBBP: Auto tx logic access bbp control register. | ||
| 555 | * AUTO_RXBBP: Auto rx logic access bbp control register. | ||
| 556 | * LOOPBACK: Loopback mode. 0: normal, 1: internal, 2: external, 3:rsvd. | ||
| 557 | * INTERSIL_IF: Intersil if calibration pin. | ||
| 558 | */ | ||
| 559 | #define MACCSR1 0x00e4 | ||
| 560 | #define MACCSR1_KICK_RX FIELD32(0x00000001) | ||
| 561 | #define MACCSR1_ONESHOT_RXMODE FIELD32(0x00000002) | ||
| 562 | #define MACCSR1_BBPRX_RESET_MODE FIELD32(0x00000004) | ||
| 563 | #define MACCSR1_AUTO_TXBBP FIELD32(0x00000008) | ||
| 564 | #define MACCSR1_AUTO_RXBBP FIELD32(0x00000010) | ||
| 565 | #define MACCSR1_LOOPBACK FIELD32(0x00000060) | ||
| 566 | #define MACCSR1_INTERSIL_IF FIELD32(0x00000080) | ||
| 567 | |||
| 568 | /* | ||
| 569 | * RALINKCSR: Ralink Rx auto-reset BBCR. | ||
| 570 | * AR_BBP_DATA#: Auto reset BBP register # data. | ||
| 571 | * AR_BBP_ID#: Auto reset BBP register # id. | ||
| 572 | */ | ||
| 573 | #define RALINKCSR 0x00e8 | ||
| 574 | #define RALINKCSR_AR_BBP_DATA0 FIELD32(0x000000ff) | ||
| 575 | #define RALINKCSR_AR_BBP_ID0 FIELD32(0x0000ff00) | ||
| 576 | #define RALINKCSR_AR_BBP_DATA1 FIELD32(0x00ff0000) | ||
| 577 | #define RALINKCSR_AR_BBP_ID1 FIELD32(0xff000000) | ||
| 578 | |||
| 579 | /* | ||
| 580 | * BCNCSR: Beacon interval control register. | ||
| 581 | * CHANGE: Write one to change beacon interval. | ||
| 582 | * DELTATIME: The delta time value. | ||
| 583 | * NUM_BEACON: Number of beacon according to mode. | ||
| 584 | * MODE: Please refer to asic specs. | ||
| 585 | * PLUS: Plus or minus delta time value. | ||
| 586 | */ | ||
| 587 | #define BCNCSR 0x00ec | ||
| 588 | #define BCNCSR_CHANGE FIELD32(0x00000001) | ||
| 589 | #define BCNCSR_DELTATIME FIELD32(0x0000001e) | ||
| 590 | #define BCNCSR_NUM_BEACON FIELD32(0x00001fe0) | ||
| 591 | #define BCNCSR_MODE FIELD32(0x00006000) | ||
| 592 | #define BCNCSR_PLUS FIELD32(0x00008000) | ||
| 593 | |||
| 594 | /* | ||
| 595 | * BBP / RF / IF Control Register. | ||
| 596 | */ | ||
| 597 | |||
| 598 | /* | ||
| 599 | * BBPCSR: BBP serial control register. | ||
| 600 | * VALUE: Register value to program into BBP. | ||
| 601 | * REGNUM: Selected BBP register. | ||
| 602 | * BUSY: 1: asic is busy execute BBP programming. | ||
| 603 | * WRITE_CONTROL: 1: write BBP, 0: read BBP. | ||
| 604 | */ | ||
| 605 | #define BBPCSR 0x00f0 | ||
| 606 | #define BBPCSR_VALUE FIELD32(0x000000ff) | ||
| 607 | #define BBPCSR_REGNUM FIELD32(0x00007f00) | ||
| 608 | #define BBPCSR_BUSY FIELD32(0x00008000) | ||
| 609 | #define BBPCSR_WRITE_CONTROL FIELD32(0x00010000) | ||
| 610 | |||
| 611 | /* | ||
| 612 | * RFCSR: RF serial control register. | ||
| 613 | * VALUE: Register value + id to program into rf/if. | ||
| 614 | * NUMBER_OF_BITS: Number of bits used in value (i:20, rfmd:22). | ||
| 615 | * IF_SELECT: Chip to program: 0: rf, 1: if. | ||
| 616 | * PLL_LD: Rf pll_ld status. | ||
| 617 | * BUSY: 1: asic is busy execute rf programming. | ||
| 618 | */ | ||
| 619 | #define RFCSR 0x00f4 | ||
| 620 | #define RFCSR_VALUE FIELD32(0x00ffffff) | ||
| 621 | #define RFCSR_NUMBER_OF_BITS FIELD32(0x1f000000) | ||
| 622 | #define RFCSR_IF_SELECT FIELD32(0x20000000) | ||
| 623 | #define RFCSR_PLL_LD FIELD32(0x40000000) | ||
| 624 | #define RFCSR_BUSY FIELD32(0x80000000) | ||
| 625 | |||
| 626 | /* | ||
| 627 | * LEDCSR: LED control register. | ||
| 628 | * ON_PERIOD: On period, default 70ms. | ||
| 629 | * OFF_PERIOD: Off period, default 30ms. | ||
| 630 | * LINK: 0: linkoff, 1: linkup. | ||
| 631 | * ACTIVITY: 0: idle, 1: active. | ||
| 632 | */ | ||
| 633 | #define LEDCSR 0x00f8 | ||
| 634 | #define LEDCSR_ON_PERIOD FIELD32(0x000000ff) | ||
| 635 | #define LEDCSR_OFF_PERIOD FIELD32(0x0000ff00) | ||
| 636 | #define LEDCSR_LINK FIELD32(0x00010000) | ||
| 637 | #define LEDCSR_ACTIVITY FIELD32(0x00020000) | ||
| 638 | |||
| 639 | /* | ||
| 640 | * ASIC pointer information. | ||
| 641 | * RXPTR: Current RX ring address. | ||
| 642 | * TXPTR: Current Tx ring address. | ||
| 643 | * PRIPTR: Current Priority ring address. | ||
| 644 | * ATIMPTR: Current ATIM ring address. | ||
| 645 | */ | ||
| 646 | #define RXPTR 0x0100 | ||
| 647 | #define TXPTR 0x0104 | ||
| 648 | #define PRIPTR 0x0108 | ||
| 649 | #define ATIMPTR 0x010c | ||
| 650 | |||
| 651 | /* | ||
| 652 | * GPIO and others. | ||
| 653 | */ | ||
| 654 | |||
| 655 | /* | ||
| 656 | * GPIOCSR: GPIO control register. | ||
| 657 | */ | ||
| 658 | #define GPIOCSR 0x0120 | ||
| 659 | #define GPIOCSR_BIT0 FIELD32(0x00000001) | ||
| 660 | #define GPIOCSR_BIT1 FIELD32(0x00000002) | ||
| 661 | #define GPIOCSR_BIT2 FIELD32(0x00000004) | ||
| 662 | #define GPIOCSR_BIT3 FIELD32(0x00000008) | ||
| 663 | #define GPIOCSR_BIT4 FIELD32(0x00000010) | ||
| 664 | #define GPIOCSR_BIT5 FIELD32(0x00000020) | ||
| 665 | #define GPIOCSR_BIT6 FIELD32(0x00000040) | ||
| 666 | #define GPIOCSR_BIT7 FIELD32(0x00000080) | ||
| 667 | |||
| 668 | /* | ||
| 669 | * BBPPCSR: BBP Pin control register. | ||
| 670 | */ | ||
| 671 | #define BBPPCSR 0x0124 | ||
| 672 | |||
| 673 | /* | ||
| 674 | * BCNCSR1: Tx BEACON offset time control register. | ||
| 675 | * PRELOAD: Beacon timer offset in units of usec. | ||
| 676 | */ | ||
| 677 | #define BCNCSR1 0x0130 | ||
| 678 | #define BCNCSR1_PRELOAD FIELD32(0x0000ffff) | ||
| 679 | |||
| 680 | /* | ||
| 681 | * MACCSR2: TX_PE to RX_PE turn-around time control register | ||
| 682 | * DELAY: RX_PE low width, in units of pci clock cycle. | ||
| 683 | */ | ||
| 684 | #define MACCSR2 0x0134 | ||
| 685 | #define MACCSR2_DELAY FIELD32(0x000000ff) | ||
| 686 | |||
| 687 | /* | ||
| 688 | * ARCSR2: 1 Mbps ACK/CTS PLCP. | ||
| 689 | */ | ||
| 690 | #define ARCSR2 0x013c | ||
| 691 | #define ARCSR2_SIGNAL FIELD32(0x000000ff) | ||
| 692 | #define ARCSR2_SERVICE FIELD32(0x0000ff00) | ||
| 693 | #define ARCSR2_LENGTH_LOW FIELD32(0x00ff0000) | ||
| 694 | #define ARCSR2_LENGTH FIELD32(0xffff0000) | ||
| 695 | |||
| 696 | /* | ||
| 697 | * ARCSR3: 2 Mbps ACK/CTS PLCP. | ||
| 698 | */ | ||
| 699 | #define ARCSR3 0x0140 | ||
| 700 | #define ARCSR3_SIGNAL FIELD32(0x000000ff) | ||
| 701 | #define ARCSR3_SERVICE FIELD32(0x0000ff00) | ||
| 702 | #define ARCSR3_LENGTH FIELD32(0xffff0000) | ||
| 703 | |||
| 704 | /* | ||
| 705 | * ARCSR4: 5.5 Mbps ACK/CTS PLCP. | ||
| 706 | */ | ||
| 707 | #define ARCSR4 0x0144 | ||
| 708 | #define ARCSR4_SIGNAL FIELD32(0x000000ff) | ||
| 709 | #define ARCSR4_SERVICE FIELD32(0x0000ff00) | ||
| 710 | #define ARCSR4_LENGTH FIELD32(0xffff0000) | ||
| 711 | |||
| 712 | /* | ||
| 713 | * ARCSR5: 11 Mbps ACK/CTS PLCP. | ||
| 714 | */ | ||
| 715 | #define ARCSR5 0x0148 | ||
| 716 | #define ARCSR5_SIGNAL FIELD32(0x000000ff) | ||
| 717 | #define ARCSR5_SERVICE FIELD32(0x0000ff00) | ||
| 718 | #define ARCSR5_LENGTH FIELD32(0xffff0000) | ||
| 719 | |||
| 720 | /* | ||
| 721 | * BBP registers. | ||
| 722 | * The wordsize of the BBP is 8 bits. | ||
| 723 | */ | ||
| 724 | |||
| 725 | /* | ||
| 726 | * R1: TX antenna control | ||
| 727 | */ | ||
| 728 | #define BBP_R1_TX_ANTENNA FIELD8(0x03) | ||
| 729 | |||
| 730 | /* | ||
| 731 | * R4: RX antenna control | ||
| 732 | */ | ||
| 733 | #define BBP_R4_RX_ANTENNA FIELD8(0x06) | ||
| 734 | |||
| 735 | /* | ||
| 736 | * RF registers | ||
| 737 | */ | ||
| 738 | |||
| 739 | /* | ||
| 740 | * RF 1 | ||
| 741 | */ | ||
| 742 | #define RF1_TUNER FIELD32(0x00020000) | ||
| 743 | |||
| 744 | /* | ||
| 745 | * RF 3 | ||
| 746 | */ | ||
| 747 | #define RF3_TUNER FIELD32(0x00000100) | ||
| 748 | #define RF3_TXPOWER FIELD32(0x00003e00) | ||
| 749 | |||
| 750 | /* | ||
| 751 | * EEPROM content. | ||
| 752 | * The wordsize of the EEPROM is 16 bits. | ||
| 753 | */ | ||
| 754 | |||
| 755 | /* | ||
| 756 | * HW MAC address. | ||
| 757 | */ | ||
| 758 | #define EEPROM_MAC_ADDR_0 0x0002 | ||
| 759 | #define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff) | ||
| 760 | #define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00) | ||
| 761 | #define EEPROM_MAC_ADDR1 0x0003 | ||
| 762 | #define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff) | ||
| 763 | #define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00) | ||
| 764 | #define EEPROM_MAC_ADDR_2 0x0004 | ||
| 765 | #define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff) | ||
| 766 | #define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) | ||
| 767 | |||
| 768 | /* | ||
| 769 | * EEPROM antenna. | ||
| 770 | * ANTENNA_NUM: Number of antenna's. | ||
| 771 | * TX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B. | ||
| 772 | * RX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B. | ||
| 773 | * RF_TYPE: Rf_type of this adapter. | ||
| 774 | * LED_MODE: 0: default, 1: TX/RX activity,2: Single (ignore link), 3: rsvd. | ||
| 775 | * RX_AGCVGC: 0: disable, 1:enable BBP R13 tuning. | ||
| 776 | * HARDWARE_RADIO: 1: Hardware controlled radio. Read GPIO0. | ||
| 777 | */ | ||
| 778 | #define EEPROM_ANTENNA 0x0b | ||
| 779 | #define EEPROM_ANTENNA_NUM FIELD16(0x0003) | ||
| 780 | #define EEPROM_ANTENNA_TX_DEFAULT FIELD16(0x000c) | ||
| 781 | #define EEPROM_ANTENNA_RX_DEFAULT FIELD16(0x0030) | ||
| 782 | #define EEPROM_ANTENNA_RF_TYPE FIELD16(0x0040) | ||
| 783 | #define EEPROM_ANTENNA_LED_MODE FIELD16(0x0180) | ||
| 784 | #define EEPROM_ANTENNA_RX_AGCVGC_TUNING FIELD16(0x0200) | ||
| 785 | #define EEPROM_ANTENNA_HARDWARE_RADIO FIELD16(0x0400) | ||
| 786 | |||
| 787 | /* | ||
| 788 | * EEPROM BBP. | ||
| 789 | */ | ||
| 790 | #define EEPROM_BBP_START 0x0c | ||
| 791 | #define EEPROM_BBP_SIZE 7 | ||
| 792 | #define EEPROM_BBP_VALUE FIELD16(0x00ff) | ||
| 793 | #define EEPROM_BBP_REG_ID FIELD16(0xff00) | ||
| 794 | |||
| 795 | /* | ||
| 796 | * EEPROM TXPOWER | ||
| 797 | */ | ||
| 798 | #define EEPROM_TXPOWER_START 0x13 | ||
| 799 | #define EEPROM_TXPOWER_SIZE 7 | ||
| 800 | #define EEPROM_TXPOWER_1 FIELD16(0x00ff) | ||
| 801 | #define EEPROM_TXPOWER_2 FIELD16(0xff00) | ||
| 802 | |||
| 803 | /* | ||
| 804 | * DMA descriptor defines. | ||
| 805 | */ | ||
| 806 | #define TXD_DESC_SIZE ( 8 * sizeof(struct data_desc) ) | ||
| 807 | #define RXD_DESC_SIZE ( 8 * sizeof(struct data_desc) ) | ||
| 808 | |||
| 809 | /* | ||
| 810 | * TX descriptor format for TX, PRIO, ATIM and Beacon Ring. | ||
| 811 | */ | ||
| 812 | |||
| 813 | /* | ||
| 814 | * Word0 | ||
| 815 | */ | ||
| 816 | #define TXD_W0_OWNER_NIC FIELD32(0x00000001) | ||
| 817 | #define TXD_W0_VALID FIELD32(0x00000002) | ||
| 818 | #define TXD_W0_RESULT FIELD32(0x0000001c) | ||
| 819 | #define TXD_W0_RETRY_COUNT FIELD32(0x000000e0) | ||
| 820 | #define TXD_W0_MORE_FRAG FIELD32(0x00000100) | ||
| 821 | #define TXD_W0_ACK FIELD32(0x00000200) | ||
| 822 | #define TXD_W0_TIMESTAMP FIELD32(0x00000400) | ||
| 823 | #define TXD_W0_RTS FIELD32(0x00000800) | ||
| 824 | #define TXD_W0_IFS FIELD32(0x00006000) | ||
| 825 | #define TXD_W0_RETRY_MODE FIELD32(0x00008000) | ||
| 826 | #define TXD_W0_AGC FIELD32(0x00ff0000) | ||
| 827 | #define TXD_W0_R2 FIELD32(0xff000000) | ||
| 828 | |||
| 829 | /* | ||
| 830 | * Word1 | ||
| 831 | */ | ||
| 832 | #define TXD_W1_BUFFER_ADDRESS FIELD32(0xffffffff) | ||
| 833 | |||
| 834 | /* | ||
| 835 | * Word2 | ||
| 836 | */ | ||
| 837 | #define TXD_W2_BUFFER_LENGTH FIELD32(0x0000ffff) | ||
| 838 | #define TXD_W2_DATABYTE_COUNT FIELD32(0xffff0000) | ||
| 839 | |||
| 840 | /* | ||
| 841 | * Word3 & 4: PLCP information | ||
| 842 | */ | ||
| 843 | #define TXD_W3_PLCP_SIGNAL FIELD32(0x0000ffff) | ||
| 844 | #define TXD_W3_PLCP_SERVICE FIELD32(0xffff0000) | ||
| 845 | #define TXD_W4_PLCP_LENGTH_LOW FIELD32(0x0000ffff) | ||
| 846 | #define TXD_W4_PLCP_LENGTH_HIGH FIELD32(0xffff0000) | ||
| 847 | |||
| 848 | /* | ||
| 849 | * Word5 | ||
| 850 | */ | ||
| 851 | #define TXD_W5_BBCR4 FIELD32(0x0000ffff) | ||
| 852 | #define TXD_W5_AGC_REG FIELD32(0x007f0000) | ||
| 853 | #define TXD_W5_AGC_REG_VALID FIELD32(0x00800000) | ||
| 854 | #define TXD_W5_XXX_REG FIELD32(0x7f000000) | ||
| 855 | #define TXD_W5_XXX_REG_VALID FIELD32(0x80000000) | ||
| 856 | |||
| 857 | /* | ||
| 858 | * Word6 | ||
| 859 | */ | ||
| 860 | #define TXD_W6_SK_BUFF FIELD32(0xffffffff) | ||
| 861 | |||
| 862 | /* | ||
| 863 | * Word7 | ||
| 864 | */ | ||
| 865 | #define TXD_W7_RESERVED FIELD32(0xffffffff) | ||
| 866 | |||
| 867 | /* | ||
| 868 | * RX descriptor format for RX Ring. | ||
| 869 | */ | ||
| 870 | |||
| 871 | /* | ||
| 872 | * Word0 | ||
| 873 | */ | ||
| 874 | #define RXD_W0_OWNER_NIC FIELD32(0x00000001) | ||
| 875 | #define RXD_W0_UNICAST_TO_ME FIELD32(0x00000002) | ||
| 876 | #define RXD_W0_MULTICAST FIELD32(0x00000004) | ||
| 877 | #define RXD_W0_BROADCAST FIELD32(0x00000008) | ||
| 878 | #define RXD_W0_MY_BSS FIELD32(0x00000010) | ||
| 879 | #define RXD_W0_CRC_ERROR FIELD32(0x00000020) | ||
| 880 | #define RXD_W0_PHYSICAL_ERROR FIELD32(0x00000080) | ||
| 881 | #define RXD_W0_DATABYTE_COUNT FIELD32(0xffff0000) | ||
| 882 | |||
| 883 | /* | ||
| 884 | * Word1 | ||
| 885 | */ | ||
| 886 | #define RXD_W1_BUFFER_ADDRESS FIELD32(0xffffffff) | ||
| 887 | |||
| 888 | /* | ||
| 889 | * Word2 | ||
| 890 | */ | ||
| 891 | #define RXD_W2_BUFFER_LENGTH FIELD32(0x0000ffff) | ||
| 892 | #define RXD_W2_SIGNAL FIELD32(0x00ff0000) | ||
| 893 | #define RXD_W2_RSSI FIELD32(0xff000000) | ||
| 894 | |||
| 895 | /* | ||
| 896 | * Word3 | ||
| 897 | */ | ||
| 898 | #define RXD_W3_BBR2 FIELD32(0x000000ff) | ||
| 899 | #define RXD_W3_BBR3 FIELD32(0x0000ff00) | ||
| 900 | #define RXD_W3_BBR4 FIELD32(0x00ff0000) | ||
| 901 | #define RXD_W3_BBR5 FIELD32(0xff000000) | ||
| 902 | |||
| 903 | /* | ||
| 904 | * Word4 | ||
| 905 | */ | ||
| 906 | #define RXD_W4_RX_END_TIME FIELD32(0xffffffff) | ||
| 907 | |||
| 908 | /* | ||
| 909 | * Word5 & 6 & 7: Reserved | ||
| 910 | */ | ||
| 911 | #define RXD_W5_RESERVED FIELD32(0xffffffff) | ||
| 912 | #define RXD_W6_RESERVED FIELD32(0xffffffff) | ||
| 913 | #define RXD_W7_RESERVED FIELD32(0xffffffff) | ||
| 914 | |||
| 915 | /* | ||
| 916 | * Macro's for converting txpower from EEPROM to dscape value | ||
| 917 | * and from dscape value to register value. | ||
| 918 | * NOTE: Logics in rt2400pci for txpower are reversed | ||
| 919 | * compared to the other rt2x00 drivers. A higher txpower | ||
| 920 | * value means that the txpower must be lowered. This is | ||
| 921 | * important when converting the value coming from the | ||
| 922 | * dscape stack to the rt2400 acceptable value. | ||
| 923 | */ | ||
| 924 | #define MIN_TXPOWER 31 | ||
| 925 | #define MAX_TXPOWER 62 | ||
| 926 | #define DEFAULT_TXPOWER 39 | ||
| 927 | |||
| 928 | #define TXPOWER_FROM_DEV(__txpower) \ | ||
| 929 | ({ \ | ||
| 930 | ((__txpower) > MAX_TXPOWER) ? DEFAULT_TXPOWER - MIN_TXPOWER : \ | ||
| 931 | ((__txpower) < MIN_TXPOWER) ? DEFAULT_TXPOWER - MIN_TXPOWER : \ | ||
| 932 | (((__txpower) - MAX_TXPOWER) + MIN_TXPOWER); \ | ||
| 933 | }) | ||
| 934 | |||
| 935 | #define TXPOWER_TO_DEV(__txpower) \ | ||
| 936 | ({ \ | ||
| 937 | (__txpower) += MIN_TXPOWER; \ | ||
| 938 | ((__txpower) <= MIN_TXPOWER) ? MAX_TXPOWER : \ | ||
| 939 | (((__txpower) >= MAX_TXPOWER) ? MIN_TXPOWER : \ | ||
| 940 | (MAX_TXPOWER - ((__txpower) - MIN_TXPOWER))); \ | ||
| 941 | }) | ||
| 942 | |||
| 943 | #endif /* RT2400PCI_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c new file mode 100644 index 00000000000..f6115c626fa --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
| @@ -0,0 +1,2000 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2500pci | ||
| 23 | Abstract: rt2500pci device specific routines. | ||
| 24 | Supported chipsets: RT2560. | ||
| 25 | */ | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Set enviroment defines for rt2x00.h | ||
| 29 | */ | ||
| 30 | #define DRV_NAME "rt2500pci" | ||
| 31 | |||
| 32 | #include <linux/delay.h> | ||
| 33 | #include <linux/etherdevice.h> | ||
| 34 | #include <linux/init.h> | ||
| 35 | #include <linux/kernel.h> | ||
| 36 | #include <linux/module.h> | ||
| 37 | #include <linux/pci.h> | ||
| 38 | #include <linux/eeprom_93cx6.h> | ||
| 39 | |||
| 40 | #include "rt2x00.h" | ||
| 41 | #include "rt2x00pci.h" | ||
| 42 | #include "rt2500pci.h" | ||
| 43 | |||
| 44 | /* | ||
| 45 | * Register access. | ||
| 46 | * All access to the CSR registers will go through the methods | ||
| 47 | * rt2x00pci_register_read and rt2x00pci_register_write. | ||
| 48 | * BBP and RF register require indirect register access, | ||
| 49 | * and use the CSR registers BBPCSR and RFCSR to achieve this. | ||
| 50 | * These indirect registers work with busy bits, | ||
| 51 | * and we will try maximal REGISTER_BUSY_COUNT times to access | ||
| 52 | * the register while taking a REGISTER_BUSY_DELAY us delay | ||
| 53 | * between each attampt. When the busy bit is still set at that time, | ||
| 54 | * the access attempt is considered to have failed, | ||
| 55 | * and we will print an error. | ||
| 56 | */ | ||
| 57 | static u32 rt2500pci_bbp_check(const struct rt2x00_dev *rt2x00dev) | ||
| 58 | { | ||
| 59 | u32 reg; | ||
| 60 | unsigned int i; | ||
| 61 | |||
| 62 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 63 | rt2x00pci_register_read(rt2x00dev, BBPCSR, ®); | ||
| 64 | if (!rt2x00_get_field32(reg, BBPCSR_BUSY)) | ||
| 65 | break; | ||
| 66 | udelay(REGISTER_BUSY_DELAY); | ||
| 67 | } | ||
| 68 | |||
| 69 | return reg; | ||
| 70 | } | ||
| 71 | |||
| 72 | static void rt2500pci_bbp_write(const struct rt2x00_dev *rt2x00dev, | ||
| 73 | const unsigned int word, const u8 value) | ||
| 74 | { | ||
| 75 | u32 reg; | ||
| 76 | |||
| 77 | /* | ||
| 78 | * Wait until the BBP becomes ready. | ||
| 79 | */ | ||
| 80 | reg = rt2500pci_bbp_check(rt2x00dev); | ||
| 81 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { | ||
| 82 | ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n"); | ||
| 83 | return; | ||
| 84 | } | ||
| 85 | |||
| 86 | /* | ||
| 87 | * Write the data into the BBP. | ||
| 88 | */ | ||
| 89 | reg = 0; | ||
| 90 | rt2x00_set_field32(®, BBPCSR_VALUE, value); | ||
| 91 | rt2x00_set_field32(®, BBPCSR_REGNUM, word); | ||
| 92 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | ||
| 93 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); | ||
| 94 | |||
| 95 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); | ||
| 96 | } | ||
| 97 | |||
| 98 | static void rt2500pci_bbp_read(const struct rt2x00_dev *rt2x00dev, | ||
| 99 | const unsigned int word, u8 *value) | ||
| 100 | { | ||
| 101 | u32 reg; | ||
| 102 | |||
| 103 | /* | ||
| 104 | * Wait until the BBP becomes ready. | ||
| 105 | */ | ||
| 106 | reg = rt2500pci_bbp_check(rt2x00dev); | ||
| 107 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { | ||
| 108 | ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); | ||
| 109 | return; | ||
| 110 | } | ||
| 111 | |||
| 112 | /* | ||
| 113 | * Write the request into the BBP. | ||
| 114 | */ | ||
| 115 | reg = 0; | ||
| 116 | rt2x00_set_field32(®, BBPCSR_REGNUM, word); | ||
| 117 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | ||
| 118 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 0); | ||
| 119 | |||
| 120 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); | ||
| 121 | |||
| 122 | /* | ||
| 123 | * Wait until the BBP becomes ready. | ||
| 124 | */ | ||
| 125 | reg = rt2500pci_bbp_check(rt2x00dev); | ||
| 126 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { | ||
| 127 | ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); | ||
| 128 | *value = 0xff; | ||
| 129 | return; | ||
| 130 | } | ||
| 131 | |||
| 132 | *value = rt2x00_get_field32(reg, BBPCSR_VALUE); | ||
| 133 | } | ||
| 134 | |||
| 135 | static void rt2500pci_rf_write(const struct rt2x00_dev *rt2x00dev, | ||
| 136 | const unsigned int word, const u32 value) | ||
| 137 | { | ||
| 138 | u32 reg; | ||
| 139 | unsigned int i; | ||
| 140 | |||
| 141 | if (!word) | ||
| 142 | return; | ||
| 143 | |||
| 144 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 145 | rt2x00pci_register_read(rt2x00dev, RFCSR, ®); | ||
| 146 | if (!rt2x00_get_field32(reg, RFCSR_BUSY)) | ||
| 147 | goto rf_write; | ||
| 148 | udelay(REGISTER_BUSY_DELAY); | ||
| 149 | } | ||
| 150 | |||
| 151 | ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n"); | ||
| 152 | return; | ||
| 153 | |||
| 154 | rf_write: | ||
| 155 | reg = 0; | ||
| 156 | rt2x00_set_field32(®, RFCSR_VALUE, value); | ||
| 157 | rt2x00_set_field32(®, RFCSR_NUMBER_OF_BITS, 20); | ||
| 158 | rt2x00_set_field32(®, RFCSR_IF_SELECT, 0); | ||
| 159 | rt2x00_set_field32(®, RFCSR_BUSY, 1); | ||
| 160 | |||
| 161 | rt2x00pci_register_write(rt2x00dev, RFCSR, reg); | ||
| 162 | rt2x00_rf_write(rt2x00dev, word, value); | ||
| 163 | } | ||
| 164 | |||
| 165 | static void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | ||
| 166 | { | ||
| 167 | struct rt2x00_dev *rt2x00dev = eeprom->data; | ||
| 168 | u32 reg; | ||
| 169 | |||
| 170 | rt2x00pci_register_read(rt2x00dev, CSR21, ®); | ||
| 171 | |||
| 172 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_IN); | ||
| 173 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_OUT); | ||
| 174 | eeprom->reg_data_clock = | ||
| 175 | !!rt2x00_get_field32(reg, CSR21_EEPROM_DATA_CLOCK); | ||
| 176 | eeprom->reg_chip_select = | ||
| 177 | !!rt2x00_get_field32(reg, CSR21_EEPROM_CHIP_SELECT); | ||
| 178 | } | ||
| 179 | |||
| 180 | static void rt2500pci_eepromregister_write(struct eeprom_93cx6 *eeprom) | ||
| 181 | { | ||
| 182 | struct rt2x00_dev *rt2x00dev = eeprom->data; | ||
| 183 | u32 reg = 0; | ||
| 184 | |||
| 185 | rt2x00_set_field32(®, CSR21_EEPROM_DATA_IN, !!eeprom->reg_data_in); | ||
| 186 | rt2x00_set_field32(®, CSR21_EEPROM_DATA_OUT, !!eeprom->reg_data_out); | ||
| 187 | rt2x00_set_field32(®, CSR21_EEPROM_DATA_CLOCK, | ||
| 188 | !!eeprom->reg_data_clock); | ||
| 189 | rt2x00_set_field32(®, CSR21_EEPROM_CHIP_SELECT, | ||
| 190 | !!eeprom->reg_chip_select); | ||
| 191 | |||
| 192 | rt2x00pci_register_write(rt2x00dev, CSR21, reg); | ||
| 193 | } | ||
| 194 | |||
| 195 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
| 196 | #define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) ) | ||
| 197 | |||
| 198 | static void rt2500pci_read_csr(const struct rt2x00_dev *rt2x00dev, | ||
| 199 | const unsigned int word, u32 *data) | ||
| 200 | { | ||
| 201 | rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data); | ||
| 202 | } | ||
| 203 | |||
| 204 | static void rt2500pci_write_csr(const struct rt2x00_dev *rt2x00dev, | ||
| 205 | const unsigned int word, u32 data) | ||
| 206 | { | ||
| 207 | rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data); | ||
| 208 | } | ||
| 209 | |||
| 210 | static const struct rt2x00debug rt2500pci_rt2x00debug = { | ||
| 211 | .owner = THIS_MODULE, | ||
| 212 | .csr = { | ||
| 213 | .read = rt2500pci_read_csr, | ||
| 214 | .write = rt2500pci_write_csr, | ||
| 215 | .word_size = sizeof(u32), | ||
| 216 | .word_count = CSR_REG_SIZE / sizeof(u32), | ||
| 217 | }, | ||
| 218 | .eeprom = { | ||
| 219 | .read = rt2x00_eeprom_read, | ||
| 220 | .write = rt2x00_eeprom_write, | ||
| 221 | .word_size = sizeof(u16), | ||
| 222 | .word_count = EEPROM_SIZE / sizeof(u16), | ||
| 223 | }, | ||
| 224 | .bbp = { | ||
| 225 | .read = rt2500pci_bbp_read, | ||
| 226 | .write = rt2500pci_bbp_write, | ||
| 227 | .word_size = sizeof(u8), | ||
| 228 | .word_count = BBP_SIZE / sizeof(u8), | ||
| 229 | }, | ||
| 230 | .rf = { | ||
| 231 | .read = rt2x00_rf_read, | ||
| 232 | .write = rt2500pci_rf_write, | ||
| 233 | .word_size = sizeof(u32), | ||
| 234 | .word_count = RF_SIZE / sizeof(u32), | ||
| 235 | }, | ||
| 236 | }; | ||
| 237 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
| 238 | |||
| 239 | #ifdef CONFIG_RT2500PCI_RFKILL | ||
| 240 | static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | ||
| 241 | { | ||
| 242 | u32 reg; | ||
| 243 | |||
| 244 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | ||
| 245 | return rt2x00_get_field32(reg, GPIOCSR_BIT0); | ||
| 246 | } | ||
| 247 | #endif /* CONFIG_RT2400PCI_RFKILL */ | ||
| 248 | |||
| 249 | /* | ||
| 250 | * Configuration handlers. | ||
| 251 | */ | ||
| 252 | static void rt2500pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *addr) | ||
| 253 | { | ||
| 254 | __le32 reg[2]; | ||
| 255 | |||
| 256 | memset(®, 0, sizeof(reg)); | ||
| 257 | memcpy(®, addr, ETH_ALEN); | ||
| 258 | |||
| 259 | /* | ||
| 260 | * The MAC address is passed to us as an array of bytes, | ||
| 261 | * that array is little endian, so no need for byte ordering. | ||
| 262 | */ | ||
| 263 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, ®, sizeof(reg)); | ||
| 264 | } | ||
| 265 | |||
| 266 | static void rt2500pci_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) | ||
| 267 | { | ||
| 268 | __le32 reg[2]; | ||
| 269 | |||
| 270 | memset(®, 0, sizeof(reg)); | ||
| 271 | memcpy(®, bssid, ETH_ALEN); | ||
| 272 | |||
| 273 | /* | ||
| 274 | * The BSSID is passed to us as an array of bytes, | ||
| 275 | * that array is little endian, so no need for byte ordering. | ||
| 276 | */ | ||
| 277 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, ®, sizeof(reg)); | ||
| 278 | } | ||
| 279 | |||
| 280 | static void rt2500pci_config_packet_filter(struct rt2x00_dev *rt2x00dev, | ||
| 281 | const unsigned int filter) | ||
| 282 | { | ||
| 283 | int promisc = !!(filter & IFF_PROMISC); | ||
| 284 | int multicast = !!(filter & IFF_MULTICAST); | ||
| 285 | int broadcast = !!(filter & IFF_BROADCAST); | ||
| 286 | u32 reg; | ||
| 287 | |||
| 288 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
| 289 | rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, !promisc); | ||
| 290 | rt2x00_set_field32(®, RXCSR0_DROP_MCAST, !multicast); | ||
| 291 | rt2x00_set_field32(®, RXCSR0_DROP_BCAST, !broadcast); | ||
| 292 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
| 293 | } | ||
| 294 | |||
| 295 | static void rt2500pci_config_type(struct rt2x00_dev *rt2x00dev, const int type) | ||
| 296 | { | ||
| 297 | u32 reg; | ||
| 298 | |||
| 299 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
| 300 | |||
| 301 | /* | ||
| 302 | * Apply hardware packet filter. | ||
| 303 | */ | ||
| 304 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
| 305 | |||
| 306 | if (!is_monitor_present(&rt2x00dev->interface) && | ||
| 307 | (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_STA)) | ||
| 308 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, 1); | ||
| 309 | else | ||
| 310 | rt2x00_set_field32(®, RXCSR0_DROP_TODS, 0); | ||
| 311 | |||
| 312 | /* | ||
| 313 | * If there is a non-monitor interface present | ||
| 314 | * the packet should be strict (even if a monitor interface is present!). | ||
| 315 | * When there is only 1 interface present which is in monitor mode | ||
| 316 | * we should start accepting _all_ frames. | ||
| 317 | */ | ||
| 318 | if (is_interface_present(&rt2x00dev->interface)) { | ||
| 319 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, 1); | ||
| 320 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, 1); | ||
| 321 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, 1); | ||
| 322 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); | ||
| 323 | } else if (is_monitor_present(&rt2x00dev->interface)) { | ||
| 324 | rt2x00_set_field32(®, RXCSR0_DROP_CRC, 0); | ||
| 325 | rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, 0); | ||
| 326 | rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, 0); | ||
| 327 | rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 0); | ||
| 328 | } | ||
| 329 | |||
| 330 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
| 331 | |||
| 332 | /* | ||
| 333 | * Enable beacon config | ||
| 334 | */ | ||
| 335 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | ||
| 336 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, | ||
| 337 | PREAMBLE + get_duration(IEEE80211_HEADER, 2)); | ||
| 338 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, | ||
| 339 | rt2x00lib_get_ring(rt2x00dev, | ||
| 340 | IEEE80211_TX_QUEUE_BEACON) | ||
| 341 | ->tx_params.cw_min); | ||
| 342 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | ||
| 343 | |||
| 344 | /* | ||
| 345 | * Enable synchronisation. | ||
| 346 | */ | ||
| 347 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
| 348 | if (is_interface_present(&rt2x00dev->interface)) { | ||
| 349 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
| 350 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
| 351 | } | ||
| 352 | |||
| 353 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
| 354 | if (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_AP) | ||
| 355 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 2); | ||
| 356 | else if (type == IEEE80211_IF_TYPE_STA) | ||
| 357 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 1); | ||
| 358 | else if (is_monitor_present(&rt2x00dev->interface) && | ||
| 359 | !is_interface_present(&rt2x00dev->interface)) | ||
| 360 | rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); | ||
| 361 | |||
| 362 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
| 363 | } | ||
| 364 | |||
| 365 | static void rt2500pci_config_rate(struct rt2x00_dev *rt2x00dev, const int rate) | ||
| 366 | { | ||
| 367 | struct ieee80211_conf *conf = &rt2x00dev->hw->conf; | ||
| 368 | u32 reg; | ||
| 369 | u32 preamble; | ||
| 370 | u16 value; | ||
| 371 | |||
| 372 | if (DEVICE_GET_RATE_FIELD(rate, PREAMBLE)) | ||
| 373 | preamble = SHORT_PREAMBLE; | ||
| 374 | else | ||
| 375 | preamble = PREAMBLE; | ||
| 376 | |||
| 377 | reg = DEVICE_GET_RATE_FIELD(rate, RATEMASK) & DEV_BASIC_RATEMASK; | ||
| 378 | rt2x00pci_register_write(rt2x00dev, ARCSR1, reg); | ||
| 379 | |||
| 380 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); | ||
| 381 | value = ((conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) ? | ||
| 382 | SHORT_DIFS : DIFS) + | ||
| 383 | PLCP + preamble + get_duration(ACK_SIZE, 10); | ||
| 384 | rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, value); | ||
| 385 | value = SIFS + PLCP + preamble + get_duration(ACK_SIZE, 10); | ||
| 386 | rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, value); | ||
| 387 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | ||
| 388 | |||
| 389 | preamble = DEVICE_GET_RATE_FIELD(rate, PREAMBLE) ? 0x08 : 0x00; | ||
| 390 | |||
| 391 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | ||
| 392 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00 | preamble); | ||
| 393 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); | ||
| 394 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10)); | ||
| 395 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); | ||
| 396 | |||
| 397 | rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); | ||
| 398 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble); | ||
| 399 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); | ||
| 400 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 20)); | ||
| 401 | rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); | ||
| 402 | |||
| 403 | rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); | ||
| 404 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble); | ||
| 405 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); | ||
| 406 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 55)); | ||
| 407 | rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); | ||
| 408 | |||
| 409 | rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); | ||
| 410 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble); | ||
| 411 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | ||
| 412 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | ||
| 413 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | ||
| 414 | } | ||
| 415 | |||
| 416 | static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, | ||
| 417 | const int phymode) | ||
| 418 | { | ||
| 419 | struct ieee80211_hw_mode *mode; | ||
| 420 | struct ieee80211_rate *rate; | ||
| 421 | |||
| 422 | if (phymode == MODE_IEEE80211A) | ||
| 423 | rt2x00dev->curr_hwmode = HWMODE_A; | ||
| 424 | else if (phymode == MODE_IEEE80211B) | ||
| 425 | rt2x00dev->curr_hwmode = HWMODE_B; | ||
| 426 | else | ||
| 427 | rt2x00dev->curr_hwmode = HWMODE_G; | ||
| 428 | |||
| 429 | mode = &rt2x00dev->hwmodes[rt2x00dev->curr_hwmode]; | ||
| 430 | rate = &mode->rates[mode->num_rates - 1]; | ||
| 431 | |||
| 432 | rt2500pci_config_rate(rt2x00dev, rate->val2); | ||
| 433 | } | ||
| 434 | |||
| 435 | static void rt2500pci_config_channel(struct rt2x00_dev *rt2x00dev, | ||
| 436 | const int index, const int channel, | ||
| 437 | const int txpower) | ||
| 438 | { | ||
| 439 | struct rf_channel reg; | ||
| 440 | u8 r70; | ||
| 441 | |||
| 442 | /* | ||
| 443 | * Fill rf_reg structure. | ||
| 444 | */ | ||
| 445 | memcpy(®, &rt2x00dev->spec.channels[index], sizeof(reg)); | ||
| 446 | |||
| 447 | /* | ||
| 448 | * Set TXpower. | ||
| 449 | */ | ||
| 450 | rt2x00_set_field32(®.rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower)); | ||
| 451 | |||
| 452 | /* | ||
| 453 | * Switch on tuning bits. | ||
| 454 | * For RT2523 devices we do not need to update the R1 register. | ||
| 455 | */ | ||
| 456 | if (!rt2x00_rf(&rt2x00dev->chip, RF2523)) | ||
| 457 | rt2x00_set_field32(®.rf1, RF1_TUNER, 1); | ||
| 458 | rt2x00_set_field32(®.rf3, RF3_TUNER, 1); | ||
| 459 | |||
| 460 | /* | ||
| 461 | * For RT2525 we should first set the channel to half band higher. | ||
| 462 | */ | ||
| 463 | if (rt2x00_rf(&rt2x00dev->chip, RF2525)) { | ||
| 464 | static const u32 vals[] = { | ||
| 465 | 0x00080cbe, 0x00080d02, 0x00080d06, 0x00080d0a, | ||
| 466 | 0x00080d0e, 0x00080d12, 0x00080d16, 0x00080d1a, | ||
| 467 | 0x00080d1e, 0x00080d22, 0x00080d26, 0x00080d2a, | ||
| 468 | 0x00080d2e, 0x00080d3a | ||
| 469 | }; | ||
| 470 | |||
| 471 | rt2500pci_rf_write(rt2x00dev, 1, reg.rf1); | ||
| 472 | rt2500pci_rf_write(rt2x00dev, 2, vals[channel - 1]); | ||
| 473 | rt2500pci_rf_write(rt2x00dev, 3, reg.rf3); | ||
| 474 | if (reg.rf4) | ||
| 475 | rt2500pci_rf_write(rt2x00dev, 4, reg.rf4); | ||
| 476 | } | ||
| 477 | |||
| 478 | rt2500pci_rf_write(rt2x00dev, 1, reg.rf1); | ||
| 479 | rt2500pci_rf_write(rt2x00dev, 2, reg.rf2); | ||
| 480 | rt2500pci_rf_write(rt2x00dev, 3, reg.rf3); | ||
| 481 | if (reg.rf4) | ||
| 482 | rt2500pci_rf_write(rt2x00dev, 4, reg.rf4); | ||
| 483 | |||
| 484 | /* | ||
| 485 | * Channel 14 requires the Japan filter bit to be set. | ||
| 486 | */ | ||
| 487 | r70 = 0x46; | ||
| 488 | rt2x00_set_field8(&r70, BBP_R70_JAPAN_FILTER, channel == 14); | ||
| 489 | rt2500pci_bbp_write(rt2x00dev, 70, r70); | ||
| 490 | |||
| 491 | msleep(1); | ||
| 492 | |||
| 493 | /* | ||
| 494 | * Switch off tuning bits. | ||
| 495 | * For RT2523 devices we do not need to update the R1 register. | ||
| 496 | */ | ||
| 497 | if (!rt2x00_rf(&rt2x00dev->chip, RF2523)) { | ||
| 498 | rt2x00_set_field32(®.rf1, RF1_TUNER, 0); | ||
| 499 | rt2500pci_rf_write(rt2x00dev, 1, reg.rf1); | ||
| 500 | } | ||
| 501 | |||
| 502 | rt2x00_set_field32(®.rf3, RF3_TUNER, 0); | ||
| 503 | rt2500pci_rf_write(rt2x00dev, 3, reg.rf3); | ||
| 504 | |||
| 505 | /* | ||
| 506 | * Clear false CRC during channel switch. | ||
| 507 | */ | ||
| 508 | rt2x00pci_register_read(rt2x00dev, CNT0, ®.rf1); | ||
| 509 | } | ||
| 510 | |||
| 511 | static void rt2500pci_config_txpower(struct rt2x00_dev *rt2x00dev, | ||
| 512 | const int txpower) | ||
| 513 | { | ||
| 514 | u32 rf3; | ||
| 515 | |||
| 516 | rt2x00_rf_read(rt2x00dev, 3, &rf3); | ||
| 517 | rt2x00_set_field32(&rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower)); | ||
| 518 | rt2500pci_rf_write(rt2x00dev, 3, rf3); | ||
| 519 | } | ||
| 520 | |||
| 521 | static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, | ||
| 522 | const int antenna_tx, const int antenna_rx) | ||
| 523 | { | ||
| 524 | u32 reg; | ||
| 525 | u8 r14; | ||
| 526 | u8 r2; | ||
| 527 | |||
| 528 | rt2x00pci_register_read(rt2x00dev, BBPCSR1, ®); | ||
| 529 | rt2500pci_bbp_read(rt2x00dev, 14, &r14); | ||
| 530 | rt2500pci_bbp_read(rt2x00dev, 2, &r2); | ||
| 531 | |||
| 532 | /* | ||
| 533 | * Configure the TX antenna. | ||
| 534 | */ | ||
| 535 | switch (antenna_tx) { | ||
| 536 | case ANTENNA_SW_DIVERSITY: | ||
| 537 | case ANTENNA_HW_DIVERSITY: | ||
| 538 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); | ||
| 539 | rt2x00_set_field32(®, BBPCSR1_CCK, 2); | ||
| 540 | rt2x00_set_field32(®, BBPCSR1_OFDM, 2); | ||
| 541 | break; | ||
| 542 | case ANTENNA_A: | ||
| 543 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 0); | ||
| 544 | rt2x00_set_field32(®, BBPCSR1_CCK, 0); | ||
| 545 | rt2x00_set_field32(®, BBPCSR1_OFDM, 0); | ||
| 546 | break; | ||
| 547 | case ANTENNA_B: | ||
| 548 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); | ||
| 549 | rt2x00_set_field32(®, BBPCSR1_CCK, 2); | ||
| 550 | rt2x00_set_field32(®, BBPCSR1_OFDM, 2); | ||
| 551 | break; | ||
| 552 | } | ||
| 553 | |||
| 554 | /* | ||
| 555 | * Configure the RX antenna. | ||
| 556 | */ | ||
| 557 | switch (antenna_rx) { | ||
| 558 | case ANTENNA_SW_DIVERSITY: | ||
| 559 | case ANTENNA_HW_DIVERSITY: | ||
| 560 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); | ||
| 561 | break; | ||
| 562 | case ANTENNA_A: | ||
| 563 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); | ||
| 564 | break; | ||
| 565 | case ANTENNA_B: | ||
| 566 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); | ||
| 567 | break; | ||
| 568 | } | ||
| 569 | |||
| 570 | /* | ||
| 571 | * RT2525E and RT5222 need to flip TX I/Q | ||
| 572 | */ | ||
| 573 | if (rt2x00_rf(&rt2x00dev->chip, RF2525E) || | ||
| 574 | rt2x00_rf(&rt2x00dev->chip, RF5222)) { | ||
| 575 | rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1); | ||
| 576 | rt2x00_set_field32(®, BBPCSR1_CCK_FLIP, 1); | ||
| 577 | rt2x00_set_field32(®, BBPCSR1_OFDM_FLIP, 1); | ||
| 578 | |||
| 579 | /* | ||
| 580 | * RT2525E does not need RX I/Q Flip. | ||
| 581 | */ | ||
| 582 | if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) | ||
| 583 | rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0); | ||
| 584 | } else { | ||
| 585 | rt2x00_set_field32(®, BBPCSR1_CCK_FLIP, 0); | ||
| 586 | rt2x00_set_field32(®, BBPCSR1_OFDM_FLIP, 0); | ||
| 587 | } | ||
| 588 | |||
| 589 | rt2x00pci_register_write(rt2x00dev, BBPCSR1, reg); | ||
| 590 | rt2500pci_bbp_write(rt2x00dev, 14, r14); | ||
| 591 | rt2500pci_bbp_write(rt2x00dev, 2, r2); | ||
| 592 | } | ||
| 593 | |||
| 594 | static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev, | ||
| 595 | const int short_slot_time, | ||
| 596 | const int beacon_int) | ||
| 597 | { | ||
| 598 | u32 reg; | ||
| 599 | |||
| 600 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | ||
| 601 | rt2x00_set_field32(®, CSR11_SLOT_TIME, | ||
| 602 | short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME); | ||
| 603 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | ||
| 604 | |||
| 605 | rt2x00pci_register_read(rt2x00dev, CSR18, ®); | ||
| 606 | rt2x00_set_field32(®, CSR18_SIFS, SIFS); | ||
| 607 | rt2x00_set_field32(®, CSR18_PIFS, | ||
| 608 | short_slot_time ? SHORT_PIFS : PIFS); | ||
| 609 | rt2x00pci_register_write(rt2x00dev, CSR18, reg); | ||
| 610 | |||
| 611 | rt2x00pci_register_read(rt2x00dev, CSR19, ®); | ||
| 612 | rt2x00_set_field32(®, CSR19_DIFS, | ||
| 613 | short_slot_time ? SHORT_DIFS : DIFS); | ||
| 614 | rt2x00_set_field32(®, CSR19_EIFS, EIFS); | ||
| 615 | rt2x00pci_register_write(rt2x00dev, CSR19, reg); | ||
| 616 | |||
| 617 | rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); | ||
| 618 | rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); | ||
| 619 | rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); | ||
| 620 | rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); | ||
| 621 | |||
| 622 | rt2x00pci_register_read(rt2x00dev, CSR12, ®); | ||
| 623 | rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, beacon_int * 16); | ||
| 624 | rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, beacon_int * 16); | ||
| 625 | rt2x00pci_register_write(rt2x00dev, CSR12, reg); | ||
| 626 | } | ||
| 627 | |||
| 628 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | ||
| 629 | const unsigned int flags, | ||
| 630 | struct ieee80211_conf *conf) | ||
| 631 | { | ||
| 632 | int short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME; | ||
| 633 | |||
| 634 | if (flags & CONFIG_UPDATE_PHYMODE) | ||
| 635 | rt2500pci_config_phymode(rt2x00dev, conf->phymode); | ||
| 636 | if (flags & CONFIG_UPDATE_CHANNEL) | ||
| 637 | rt2500pci_config_channel(rt2x00dev, conf->channel_val, | ||
| 638 | conf->channel, conf->power_level); | ||
| 639 | if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL)) | ||
| 640 | rt2500pci_config_txpower(rt2x00dev, conf->power_level); | ||
| 641 | if (flags & CONFIG_UPDATE_ANTENNA) | ||
| 642 | rt2500pci_config_antenna(rt2x00dev, conf->antenna_sel_tx, | ||
| 643 | conf->antenna_sel_rx); | ||
| 644 | if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) | ||
| 645 | rt2500pci_config_duration(rt2x00dev, short_slot_time, | ||
| 646 | conf->beacon_int); | ||
| 647 | } | ||
| 648 | |||
| 649 | /* | ||
| 650 | * LED functions. | ||
| 651 | */ | ||
| 652 | static void rt2500pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
| 653 | { | ||
| 654 | u32 reg; | ||
| 655 | |||
| 656 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
| 657 | |||
| 658 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
| 659 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
| 660 | |||
| 661 | if (rt2x00dev->led_mode == LED_MODE_TXRX_ACTIVITY) { | ||
| 662 | rt2x00_set_field32(®, LEDCSR_LINK, 1); | ||
| 663 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); | ||
| 664 | } else if (rt2x00dev->led_mode == LED_MODE_ASUS) { | ||
| 665 | rt2x00_set_field32(®, LEDCSR_LINK, 0); | ||
| 666 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1); | ||
| 667 | } else { | ||
| 668 | rt2x00_set_field32(®, LEDCSR_LINK, 1); | ||
| 669 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1); | ||
| 670 | } | ||
| 671 | |||
| 672 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
| 673 | } | ||
| 674 | |||
| 675 | static void rt2500pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
| 676 | { | ||
| 677 | u32 reg; | ||
| 678 | |||
| 679 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
| 680 | rt2x00_set_field32(®, LEDCSR_LINK, 0); | ||
| 681 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); | ||
| 682 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
| 683 | } | ||
| 684 | |||
| 685 | /* | ||
| 686 | * Link tuning | ||
| 687 | */ | ||
| 688 | static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev) | ||
| 689 | { | ||
| 690 | u32 reg; | ||
| 691 | |||
| 692 | /* | ||
| 693 | * Update FCS error count from register. | ||
| 694 | */ | ||
| 695 | rt2x00pci_register_read(rt2x00dev, CNT0, ®); | ||
| 696 | rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR); | ||
| 697 | |||
| 698 | /* | ||
| 699 | * Update False CCA count from register. | ||
| 700 | */ | ||
| 701 | rt2x00pci_register_read(rt2x00dev, CNT3, ®); | ||
| 702 | rt2x00dev->link.false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA); | ||
| 703 | } | ||
| 704 | |||
| 705 | static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev) | ||
| 706 | { | ||
| 707 | rt2500pci_bbp_write(rt2x00dev, 17, 0x48); | ||
| 708 | rt2x00dev->link.vgc_level = 0x48; | ||
| 709 | } | ||
| 710 | |||
| 711 | static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | ||
| 712 | { | ||
| 713 | int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); | ||
| 714 | u8 r17; | ||
| 715 | |||
| 716 | /* | ||
| 717 | * To prevent collisions with MAC ASIC on chipsets | ||
| 718 | * up to version C the link tuning should halt after 20 | ||
| 719 | * seconds. | ||
| 720 | */ | ||
| 721 | if (rt2x00_get_rev(&rt2x00dev->chip) < RT2560_VERSION_D && | ||
| 722 | rt2x00dev->link.count > 20) | ||
| 723 | return; | ||
| 724 | |||
| 725 | rt2500pci_bbp_read(rt2x00dev, 17, &r17); | ||
| 726 | |||
| 727 | /* | ||
| 728 | * Chipset versions C and lower should directly continue | ||
| 729 | * to the dynamic CCA tuning. | ||
| 730 | */ | ||
| 731 | if (rt2x00_get_rev(&rt2x00dev->chip) < RT2560_VERSION_D) | ||
| 732 | goto dynamic_cca_tune; | ||
| 733 | |||
| 734 | /* | ||
| 735 | * A too low RSSI will cause too much false CCA which will | ||
| 736 | * then corrupt the R17 tuning. To remidy this the tuning should | ||
| 737 | * be stopped (While making sure the R17 value will not exceed limits) | ||
| 738 | */ | ||
| 739 | if (rssi < -80 && rt2x00dev->link.count > 20) { | ||
| 740 | if (r17 >= 0x41) { | ||
| 741 | r17 = rt2x00dev->link.vgc_level; | ||
| 742 | rt2500pci_bbp_write(rt2x00dev, 17, r17); | ||
| 743 | } | ||
| 744 | return; | ||
| 745 | } | ||
| 746 | |||
| 747 | /* | ||
| 748 | * Special big-R17 for short distance | ||
| 749 | */ | ||
| 750 | if (rssi >= -58) { | ||
| 751 | if (r17 != 0x50) | ||
| 752 | rt2500pci_bbp_write(rt2x00dev, 17, 0x50); | ||
| 753 | return; | ||
| 754 | } | ||
| 755 | |||
| 756 | /* | ||
| 757 | * Special mid-R17 for middle distance | ||
| 758 | */ | ||
| 759 | if (rssi >= -74) { | ||
| 760 | if (r17 != 0x41) | ||
| 761 | rt2500pci_bbp_write(rt2x00dev, 17, 0x41); | ||
| 762 | return; | ||
| 763 | } | ||
| 764 | |||
| 765 | /* | ||
| 766 | * Leave short or middle distance condition, restore r17 | ||
| 767 | * to the dynamic tuning range. | ||
| 768 | */ | ||
| 769 | if (r17 >= 0x41) { | ||
| 770 | rt2500pci_bbp_write(rt2x00dev, 17, rt2x00dev->link.vgc_level); | ||
| 771 | return; | ||
| 772 | } | ||
| 773 | |||
| 774 | dynamic_cca_tune: | ||
| 775 | |||
| 776 | /* | ||
| 777 | * R17 is inside the dynamic tuning range, | ||
| 778 | * start tuning the link based on the false cca counter. | ||
| 779 | */ | ||
| 780 | if (rt2x00dev->link.false_cca > 512 && r17 < 0x40) { | ||
| 781 | rt2500pci_bbp_write(rt2x00dev, 17, ++r17); | ||
| 782 | rt2x00dev->link.vgc_level = r17; | ||
| 783 | } else if (rt2x00dev->link.false_cca < 100 && r17 > 0x32) { | ||
| 784 | rt2500pci_bbp_write(rt2x00dev, 17, --r17); | ||
| 785 | rt2x00dev->link.vgc_level = r17; | ||
| 786 | } | ||
| 787 | } | ||
| 788 | |||
| 789 | /* | ||
| 790 | * Initialization functions. | ||
| 791 | */ | ||
| 792 | static void rt2500pci_init_rxring(struct rt2x00_dev *rt2x00dev) | ||
| 793 | { | ||
| 794 | struct data_ring *ring = rt2x00dev->rx; | ||
| 795 | struct data_desc *rxd; | ||
| 796 | unsigned int i; | ||
| 797 | u32 word; | ||
| 798 | |||
| 799 | memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring)); | ||
| 800 | |||
| 801 | for (i = 0; i < ring->stats.limit; i++) { | ||
| 802 | rxd = ring->entry[i].priv; | ||
| 803 | |||
| 804 | rt2x00_desc_read(rxd, 1, &word); | ||
| 805 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, | ||
| 806 | ring->entry[i].data_dma); | ||
| 807 | rt2x00_desc_write(rxd, 1, word); | ||
| 808 | |||
| 809 | rt2x00_desc_read(rxd, 0, &word); | ||
| 810 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | ||
| 811 | rt2x00_desc_write(rxd, 0, word); | ||
| 812 | } | ||
| 813 | |||
| 814 | rt2x00_ring_index_clear(rt2x00dev->rx); | ||
| 815 | } | ||
| 816 | |||
| 817 | static void rt2500pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue) | ||
| 818 | { | ||
| 819 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | ||
| 820 | struct data_desc *txd; | ||
| 821 | unsigned int i; | ||
| 822 | u32 word; | ||
| 823 | |||
| 824 | memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring)); | ||
| 825 | |||
| 826 | for (i = 0; i < ring->stats.limit; i++) { | ||
| 827 | txd = ring->entry[i].priv; | ||
| 828 | |||
| 829 | rt2x00_desc_read(txd, 1, &word); | ||
| 830 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, | ||
| 831 | ring->entry[i].data_dma); | ||
| 832 | rt2x00_desc_write(txd, 1, word); | ||
| 833 | |||
| 834 | rt2x00_desc_read(txd, 0, &word); | ||
| 835 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | ||
| 836 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | ||
| 837 | rt2x00_desc_write(txd, 0, word); | ||
| 838 | } | ||
| 839 | |||
| 840 | rt2x00_ring_index_clear(ring); | ||
| 841 | } | ||
| 842 | |||
| 843 | static int rt2500pci_init_rings(struct rt2x00_dev *rt2x00dev) | ||
| 844 | { | ||
| 845 | u32 reg; | ||
| 846 | |||
| 847 | /* | ||
| 848 | * Initialize rings. | ||
| 849 | */ | ||
| 850 | rt2500pci_init_rxring(rt2x00dev); | ||
| 851 | rt2500pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0); | ||
| 852 | rt2500pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA1); | ||
| 853 | rt2500pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | ||
| 854 | rt2500pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
| 855 | |||
| 856 | /* | ||
| 857 | * Initialize registers. | ||
| 858 | */ | ||
| 859 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | ||
| 860 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, | ||
| 861 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size); | ||
| 862 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, | ||
| 863 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | ||
| 864 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, | ||
| 865 | rt2x00dev->bcn[1].stats.limit); | ||
| 866 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, | ||
| 867 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | ||
| 868 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); | ||
| 869 | |||
| 870 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); | ||
| 871 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, | ||
| 872 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | ||
| 873 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); | ||
| 874 | |||
| 875 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); | ||
| 876 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, | ||
| 877 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | ||
| 878 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | ||
| 879 | |||
| 880 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | ||
| 881 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | ||
| 882 | rt2x00dev->bcn[1].data_dma); | ||
| 883 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | ||
| 884 | |||
| 885 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | ||
| 886 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | ||
| 887 | rt2x00dev->bcn[0].data_dma); | ||
| 888 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); | ||
| 889 | |||
| 890 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); | ||
| 891 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); | ||
| 892 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->stats.limit); | ||
| 893 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); | ||
| 894 | |||
| 895 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); | ||
| 896 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, | ||
| 897 | rt2x00dev->rx->data_dma); | ||
| 898 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); | ||
| 899 | |||
| 900 | return 0; | ||
| 901 | } | ||
| 902 | |||
| 903 | static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) | ||
| 904 | { | ||
| 905 | u32 reg; | ||
| 906 | |||
| 907 | rt2x00pci_register_write(rt2x00dev, PSCSR0, 0x00020002); | ||
| 908 | rt2x00pci_register_write(rt2x00dev, PSCSR1, 0x00000002); | ||
| 909 | rt2x00pci_register_write(rt2x00dev, PSCSR2, 0x00020002); | ||
| 910 | rt2x00pci_register_write(rt2x00dev, PSCSR3, 0x00000002); | ||
| 911 | |||
| 912 | rt2x00pci_register_read(rt2x00dev, TIMECSR, ®); | ||
| 913 | rt2x00_set_field32(®, TIMECSR_US_COUNT, 33); | ||
| 914 | rt2x00_set_field32(®, TIMECSR_US_64_COUNT, 63); | ||
| 915 | rt2x00_set_field32(®, TIMECSR_BEACON_EXPECT, 0); | ||
| 916 | rt2x00pci_register_write(rt2x00dev, TIMECSR, reg); | ||
| 917 | |||
| 918 | rt2x00pci_register_read(rt2x00dev, CSR9, ®); | ||
| 919 | rt2x00_set_field32(®, CSR9_MAX_FRAME_UNIT, | ||
| 920 | rt2x00dev->rx->data_size / 128); | ||
| 921 | rt2x00pci_register_write(rt2x00dev, CSR9, reg); | ||
| 922 | |||
| 923 | /* | ||
| 924 | * Always use CWmin and CWmax set in descriptor. | ||
| 925 | */ | ||
| 926 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | ||
| 927 | rt2x00_set_field32(®, CSR11_CW_SELECT, 0); | ||
| 928 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | ||
| 929 | |||
| 930 | rt2x00pci_register_write(rt2x00dev, CNT3, 0); | ||
| 931 | |||
| 932 | rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); | ||
| 933 | rt2x00_set_field32(®, TXCSR8_BBP_ID0, 10); | ||
| 934 | rt2x00_set_field32(®, TXCSR8_BBP_ID0_VALID, 1); | ||
| 935 | rt2x00_set_field32(®, TXCSR8_BBP_ID1, 11); | ||
| 936 | rt2x00_set_field32(®, TXCSR8_BBP_ID1_VALID, 1); | ||
| 937 | rt2x00_set_field32(®, TXCSR8_BBP_ID2, 13); | ||
| 938 | rt2x00_set_field32(®, TXCSR8_BBP_ID2_VALID, 1); | ||
| 939 | rt2x00_set_field32(®, TXCSR8_BBP_ID3, 12); | ||
| 940 | rt2x00_set_field32(®, TXCSR8_BBP_ID3_VALID, 1); | ||
| 941 | rt2x00pci_register_write(rt2x00dev, TXCSR8, reg); | ||
| 942 | |||
| 943 | rt2x00pci_register_read(rt2x00dev, ARTCSR0, ®); | ||
| 944 | rt2x00_set_field32(®, ARTCSR0_ACK_CTS_1MBS, 112); | ||
| 945 | rt2x00_set_field32(®, ARTCSR0_ACK_CTS_2MBS, 56); | ||
| 946 | rt2x00_set_field32(®, ARTCSR0_ACK_CTS_5_5MBS, 20); | ||
| 947 | rt2x00_set_field32(®, ARTCSR0_ACK_CTS_11MBS, 10); | ||
| 948 | rt2x00pci_register_write(rt2x00dev, ARTCSR0, reg); | ||
| 949 | |||
| 950 | rt2x00pci_register_read(rt2x00dev, ARTCSR1, ®); | ||
| 951 | rt2x00_set_field32(®, ARTCSR1_ACK_CTS_6MBS, 45); | ||
| 952 | rt2x00_set_field32(®, ARTCSR1_ACK_CTS_9MBS, 37); | ||
| 953 | rt2x00_set_field32(®, ARTCSR1_ACK_CTS_12MBS, 33); | ||
| 954 | rt2x00_set_field32(®, ARTCSR1_ACK_CTS_18MBS, 29); | ||
| 955 | rt2x00pci_register_write(rt2x00dev, ARTCSR1, reg); | ||
| 956 | |||
| 957 | rt2x00pci_register_read(rt2x00dev, ARTCSR2, ®); | ||
| 958 | rt2x00_set_field32(®, ARTCSR2_ACK_CTS_24MBS, 29); | ||
| 959 | rt2x00_set_field32(®, ARTCSR2_ACK_CTS_36MBS, 25); | ||
| 960 | rt2x00_set_field32(®, ARTCSR2_ACK_CTS_48MBS, 25); | ||
| 961 | rt2x00_set_field32(®, ARTCSR2_ACK_CTS_54MBS, 25); | ||
| 962 | rt2x00pci_register_write(rt2x00dev, ARTCSR2, reg); | ||
| 963 | |||
| 964 | rt2x00pci_register_read(rt2x00dev, RXCSR3, ®); | ||
| 965 | rt2x00_set_field32(®, RXCSR3_BBP_ID0, 47); /* CCK Signal */ | ||
| 966 | rt2x00_set_field32(®, RXCSR3_BBP_ID0_VALID, 1); | ||
| 967 | rt2x00_set_field32(®, RXCSR3_BBP_ID1, 51); /* Rssi */ | ||
| 968 | rt2x00_set_field32(®, RXCSR3_BBP_ID1_VALID, 1); | ||
| 969 | rt2x00_set_field32(®, RXCSR3_BBP_ID2, 42); /* OFDM Rate */ | ||
| 970 | rt2x00_set_field32(®, RXCSR3_BBP_ID2_VALID, 1); | ||
| 971 | rt2x00_set_field32(®, RXCSR3_BBP_ID3, 51); /* RSSI */ | ||
| 972 | rt2x00_set_field32(®, RXCSR3_BBP_ID3_VALID, 1); | ||
| 973 | rt2x00pci_register_write(rt2x00dev, RXCSR3, reg); | ||
| 974 | |||
| 975 | rt2x00pci_register_read(rt2x00dev, PCICSR, ®); | ||
| 976 | rt2x00_set_field32(®, PCICSR_BIG_ENDIAN, 0); | ||
| 977 | rt2x00_set_field32(®, PCICSR_RX_TRESHOLD, 0); | ||
| 978 | rt2x00_set_field32(®, PCICSR_TX_TRESHOLD, 3); | ||
| 979 | rt2x00_set_field32(®, PCICSR_BURST_LENTH, 1); | ||
| 980 | rt2x00_set_field32(®, PCICSR_ENABLE_CLK, 1); | ||
| 981 | rt2x00_set_field32(®, PCICSR_READ_MULTIPLE, 1); | ||
| 982 | rt2x00_set_field32(®, PCICSR_WRITE_INVALID, 1); | ||
| 983 | rt2x00pci_register_write(rt2x00dev, PCICSR, reg); | ||
| 984 | |||
| 985 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0x3f3b3100); | ||
| 986 | |||
| 987 | rt2x00pci_register_write(rt2x00dev, GPIOCSR, 0x0000ff00); | ||
| 988 | rt2x00pci_register_write(rt2x00dev, TESTCSR, 0x000000f0); | ||
| 989 | |||
| 990 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) | ||
| 991 | return -EBUSY; | ||
| 992 | |||
| 993 | rt2x00pci_register_write(rt2x00dev, MACCSR0, 0x00213223); | ||
| 994 | rt2x00pci_register_write(rt2x00dev, MACCSR1, 0x00235518); | ||
| 995 | |||
| 996 | rt2x00pci_register_read(rt2x00dev, MACCSR2, ®); | ||
| 997 | rt2x00_set_field32(®, MACCSR2_DELAY, 64); | ||
| 998 | rt2x00pci_register_write(rt2x00dev, MACCSR2, reg); | ||
| 999 | |||
| 1000 | rt2x00pci_register_read(rt2x00dev, RALINKCSR, ®); | ||
| 1001 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA0, 17); | ||
| 1002 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID0, 26); | ||
| 1003 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_VALID0, 1); | ||
| 1004 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_DATA1, 0); | ||
| 1005 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID1, 26); | ||
| 1006 | rt2x00_set_field32(®, RALINKCSR_AR_BBP_VALID1, 1); | ||
| 1007 | rt2x00pci_register_write(rt2x00dev, RALINKCSR, reg); | ||
| 1008 | |||
| 1009 | rt2x00pci_register_write(rt2x00dev, BBPCSR1, 0x82188200); | ||
| 1010 | |||
| 1011 | rt2x00pci_register_write(rt2x00dev, TXACKCSR0, 0x00000020); | ||
| 1012 | |||
| 1013 | rt2x00pci_register_read(rt2x00dev, CSR1, ®); | ||
| 1014 | rt2x00_set_field32(®, CSR1_SOFT_RESET, 1); | ||
| 1015 | rt2x00_set_field32(®, CSR1_BBP_RESET, 0); | ||
| 1016 | rt2x00_set_field32(®, CSR1_HOST_READY, 0); | ||
| 1017 | rt2x00pci_register_write(rt2x00dev, CSR1, reg); | ||
| 1018 | |||
| 1019 | rt2x00pci_register_read(rt2x00dev, CSR1, ®); | ||
| 1020 | rt2x00_set_field32(®, CSR1_SOFT_RESET, 0); | ||
| 1021 | rt2x00_set_field32(®, CSR1_HOST_READY, 1); | ||
| 1022 | rt2x00pci_register_write(rt2x00dev, CSR1, reg); | ||
| 1023 | |||
| 1024 | /* | ||
| 1025 | * We must clear the FCS and FIFO error count. | ||
| 1026 | * These registers are cleared on read, | ||
| 1027 | * so we may pass a useless variable to store the value. | ||
| 1028 | */ | ||
| 1029 | rt2x00pci_register_read(rt2x00dev, CNT0, ®); | ||
| 1030 | rt2x00pci_register_read(rt2x00dev, CNT4, ®); | ||
| 1031 | |||
| 1032 | return 0; | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev) | ||
| 1036 | { | ||
| 1037 | unsigned int i; | ||
| 1038 | u16 eeprom; | ||
| 1039 | u8 reg_id; | ||
| 1040 | u8 value; | ||
| 1041 | |||
| 1042 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 1043 | rt2500pci_bbp_read(rt2x00dev, 0, &value); | ||
| 1044 | if ((value != 0xff) && (value != 0x00)) | ||
| 1045 | goto continue_csr_init; | ||
| 1046 | NOTICE(rt2x00dev, "Waiting for BBP register.\n"); | ||
| 1047 | udelay(REGISTER_BUSY_DELAY); | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | ||
| 1051 | return -EACCES; | ||
| 1052 | |||
| 1053 | continue_csr_init: | ||
| 1054 | rt2500pci_bbp_write(rt2x00dev, 3, 0x02); | ||
| 1055 | rt2500pci_bbp_write(rt2x00dev, 4, 0x19); | ||
| 1056 | rt2500pci_bbp_write(rt2x00dev, 14, 0x1c); | ||
| 1057 | rt2500pci_bbp_write(rt2x00dev, 15, 0x30); | ||
| 1058 | rt2500pci_bbp_write(rt2x00dev, 16, 0xac); | ||
| 1059 | rt2500pci_bbp_write(rt2x00dev, 18, 0x18); | ||
| 1060 | rt2500pci_bbp_write(rt2x00dev, 19, 0xff); | ||
| 1061 | rt2500pci_bbp_write(rt2x00dev, 20, 0x1e); | ||
| 1062 | rt2500pci_bbp_write(rt2x00dev, 21, 0x08); | ||
| 1063 | rt2500pci_bbp_write(rt2x00dev, 22, 0x08); | ||
| 1064 | rt2500pci_bbp_write(rt2x00dev, 23, 0x08); | ||
| 1065 | rt2500pci_bbp_write(rt2x00dev, 24, 0x70); | ||
| 1066 | rt2500pci_bbp_write(rt2x00dev, 25, 0x40); | ||
| 1067 | rt2500pci_bbp_write(rt2x00dev, 26, 0x08); | ||
| 1068 | rt2500pci_bbp_write(rt2x00dev, 27, 0x23); | ||
| 1069 | rt2500pci_bbp_write(rt2x00dev, 30, 0x10); | ||
| 1070 | rt2500pci_bbp_write(rt2x00dev, 31, 0x2b); | ||
| 1071 | rt2500pci_bbp_write(rt2x00dev, 32, 0xb9); | ||
| 1072 | rt2500pci_bbp_write(rt2x00dev, 34, 0x12); | ||
| 1073 | rt2500pci_bbp_write(rt2x00dev, 35, 0x50); | ||
| 1074 | rt2500pci_bbp_write(rt2x00dev, 39, 0xc4); | ||
| 1075 | rt2500pci_bbp_write(rt2x00dev, 40, 0x02); | ||
| 1076 | rt2500pci_bbp_write(rt2x00dev, 41, 0x60); | ||
| 1077 | rt2500pci_bbp_write(rt2x00dev, 53, 0x10); | ||
| 1078 | rt2500pci_bbp_write(rt2x00dev, 54, 0x18); | ||
| 1079 | rt2500pci_bbp_write(rt2x00dev, 56, 0x08); | ||
| 1080 | rt2500pci_bbp_write(rt2x00dev, 57, 0x10); | ||
| 1081 | rt2500pci_bbp_write(rt2x00dev, 58, 0x08); | ||
| 1082 | rt2500pci_bbp_write(rt2x00dev, 61, 0x6d); | ||
| 1083 | rt2500pci_bbp_write(rt2x00dev, 62, 0x10); | ||
| 1084 | |||
| 1085 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
| 1086 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | ||
| 1087 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | ||
| 1088 | |||
| 1089 | if (eeprom != 0xffff && eeprom != 0x0000) { | ||
| 1090 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | ||
| 1091 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | ||
| 1092 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
| 1093 | reg_id, value); | ||
| 1094 | rt2500pci_bbp_write(rt2x00dev, reg_id, value); | ||
| 1095 | } | ||
| 1096 | } | ||
| 1097 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
| 1098 | |||
| 1099 | return 0; | ||
| 1100 | } | ||
| 1101 | |||
| 1102 | /* | ||
| 1103 | * Device state switch handlers. | ||
| 1104 | */ | ||
| 1105 | static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev, | ||
| 1106 | enum dev_state state) | ||
| 1107 | { | ||
| 1108 | u32 reg; | ||
| 1109 | |||
| 1110 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | ||
| 1111 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, | ||
| 1112 | state == STATE_RADIO_RX_OFF); | ||
| 1113 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | ||
| 1117 | enum dev_state state) | ||
| 1118 | { | ||
| 1119 | int mask = (state == STATE_RADIO_IRQ_OFF); | ||
| 1120 | u32 reg; | ||
| 1121 | |||
| 1122 | /* | ||
| 1123 | * When interrupts are being enabled, the interrupt registers | ||
| 1124 | * should clear the register to assure a clean state. | ||
| 1125 | */ | ||
| 1126 | if (state == STATE_RADIO_IRQ_ON) { | ||
| 1127 | rt2x00pci_register_read(rt2x00dev, CSR7, ®); | ||
| 1128 | rt2x00pci_register_write(rt2x00dev, CSR7, reg); | ||
| 1129 | } | ||
| 1130 | |||
| 1131 | /* | ||
| 1132 | * Only toggle the interrupts bits we are going to use. | ||
| 1133 | * Non-checked interrupt bits are disabled by default. | ||
| 1134 | */ | ||
| 1135 | rt2x00pci_register_read(rt2x00dev, CSR8, ®); | ||
| 1136 | rt2x00_set_field32(®, CSR8_TBCN_EXPIRE, mask); | ||
| 1137 | rt2x00_set_field32(®, CSR8_TXDONE_TXRING, mask); | ||
| 1138 | rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, mask); | ||
| 1139 | rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, mask); | ||
| 1140 | rt2x00_set_field32(®, CSR8_RXDONE, mask); | ||
| 1141 | rt2x00pci_register_write(rt2x00dev, CSR8, reg); | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 1145 | { | ||
| 1146 | /* | ||
| 1147 | * Initialize all registers. | ||
| 1148 | */ | ||
| 1149 | if (rt2500pci_init_rings(rt2x00dev) || | ||
| 1150 | rt2500pci_init_registers(rt2x00dev) || | ||
| 1151 | rt2500pci_init_bbp(rt2x00dev)) { | ||
| 1152 | ERROR(rt2x00dev, "Register initialization failed.\n"); | ||
| 1153 | return -EIO; | ||
| 1154 | } | ||
| 1155 | |||
| 1156 | /* | ||
| 1157 | * Enable interrupts. | ||
| 1158 | */ | ||
| 1159 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | ||
| 1160 | |||
| 1161 | /* | ||
| 1162 | * Enable LED | ||
| 1163 | */ | ||
| 1164 | rt2500pci_enable_led(rt2x00dev); | ||
| 1165 | |||
| 1166 | return 0; | ||
| 1167 | } | ||
| 1168 | |||
| 1169 | static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 1170 | { | ||
| 1171 | u32 reg; | ||
| 1172 | |||
| 1173 | /* | ||
| 1174 | * Disable LED | ||
| 1175 | */ | ||
| 1176 | rt2500pci_disable_led(rt2x00dev); | ||
| 1177 | |||
| 1178 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | ||
| 1179 | |||
| 1180 | /* | ||
| 1181 | * Disable synchronisation. | ||
| 1182 | */ | ||
| 1183 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
| 1184 | |||
| 1185 | /* | ||
| 1186 | * Cancel RX and TX. | ||
| 1187 | */ | ||
| 1188 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | ||
| 1189 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); | ||
| 1190 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
| 1191 | |||
| 1192 | /* | ||
| 1193 | * Disable interrupts. | ||
| 1194 | */ | ||
| 1195 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF); | ||
| 1196 | } | ||
| 1197 | |||
| 1198 | static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, | ||
| 1199 | enum dev_state state) | ||
| 1200 | { | ||
| 1201 | u32 reg; | ||
| 1202 | unsigned int i; | ||
| 1203 | char put_to_sleep; | ||
| 1204 | char bbp_state; | ||
| 1205 | char rf_state; | ||
| 1206 | |||
| 1207 | put_to_sleep = (state != STATE_AWAKE); | ||
| 1208 | |||
| 1209 | rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®); | ||
| 1210 | rt2x00_set_field32(®, PWRCSR1_SET_STATE, 1); | ||
| 1211 | rt2x00_set_field32(®, PWRCSR1_BBP_DESIRE_STATE, state); | ||
| 1212 | rt2x00_set_field32(®, PWRCSR1_RF_DESIRE_STATE, state); | ||
| 1213 | rt2x00_set_field32(®, PWRCSR1_PUT_TO_SLEEP, put_to_sleep); | ||
| 1214 | rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg); | ||
| 1215 | |||
| 1216 | /* | ||
| 1217 | * Device is not guaranteed to be in the requested state yet. | ||
| 1218 | * We must wait until the register indicates that the | ||
| 1219 | * device has entered the correct state. | ||
| 1220 | */ | ||
| 1221 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 1222 | rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®); | ||
| 1223 | bbp_state = rt2x00_get_field32(reg, PWRCSR1_BBP_CURR_STATE); | ||
| 1224 | rf_state = rt2x00_get_field32(reg, PWRCSR1_RF_CURR_STATE); | ||
| 1225 | if (bbp_state == state && rf_state == state) | ||
| 1226 | return 0; | ||
| 1227 | msleep(10); | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | NOTICE(rt2x00dev, "Device failed to enter state %d, " | ||
| 1231 | "current device state: bbp %d and rf %d.\n", | ||
| 1232 | state, bbp_state, rf_state); | ||
| 1233 | |||
| 1234 | return -EBUSY; | ||
| 1235 | } | ||
| 1236 | |||
| 1237 | static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, | ||
| 1238 | enum dev_state state) | ||
| 1239 | { | ||
| 1240 | int retval = 0; | ||
| 1241 | |||
| 1242 | switch (state) { | ||
| 1243 | case STATE_RADIO_ON: | ||
| 1244 | retval = rt2500pci_enable_radio(rt2x00dev); | ||
| 1245 | break; | ||
| 1246 | case STATE_RADIO_OFF: | ||
| 1247 | rt2500pci_disable_radio(rt2x00dev); | ||
| 1248 | break; | ||
| 1249 | case STATE_RADIO_RX_ON: | ||
| 1250 | case STATE_RADIO_RX_OFF: | ||
| 1251 | rt2500pci_toggle_rx(rt2x00dev, state); | ||
| 1252 | break; | ||
| 1253 | case STATE_DEEP_SLEEP: | ||
| 1254 | case STATE_SLEEP: | ||
| 1255 | case STATE_STANDBY: | ||
| 1256 | case STATE_AWAKE: | ||
| 1257 | retval = rt2500pci_set_state(rt2x00dev, state); | ||
| 1258 | break; | ||
| 1259 | default: | ||
| 1260 | retval = -ENOTSUPP; | ||
| 1261 | break; | ||
| 1262 | } | ||
| 1263 | |||
| 1264 | return retval; | ||
| 1265 | } | ||
| 1266 | |||
| 1267 | /* | ||
| 1268 | * TX descriptor initialization | ||
| 1269 | */ | ||
| 1270 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | ||
| 1271 | struct data_desc *txd, | ||
| 1272 | struct data_entry_desc *desc, | ||
| 1273 | struct ieee80211_hdr *ieee80211hdr, | ||
| 1274 | unsigned int length, | ||
| 1275 | struct ieee80211_tx_control *control) | ||
| 1276 | { | ||
| 1277 | u32 word; | ||
| 1278 | |||
| 1279 | /* | ||
| 1280 | * Start writing the descriptor words. | ||
| 1281 | */ | ||
| 1282 | rt2x00_desc_read(txd, 2, &word); | ||
| 1283 | rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); | ||
| 1284 | rt2x00_set_field32(&word, TXD_W2_AIFS, desc->aifs); | ||
| 1285 | rt2x00_set_field32(&word, TXD_W2_CWMIN, desc->cw_min); | ||
| 1286 | rt2x00_set_field32(&word, TXD_W2_CWMAX, desc->cw_max); | ||
| 1287 | rt2x00_desc_write(txd, 2, word); | ||
| 1288 | |||
| 1289 | rt2x00_desc_read(txd, 3, &word); | ||
| 1290 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, desc->signal); | ||
| 1291 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, desc->service); | ||
| 1292 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, desc->length_low); | ||
| 1293 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, desc->length_high); | ||
| 1294 | rt2x00_desc_write(txd, 3, word); | ||
| 1295 | |||
| 1296 | rt2x00_desc_read(txd, 10, &word); | ||
| 1297 | rt2x00_set_field32(&word, TXD_W10_RTS, | ||
| 1298 | test_bit(ENTRY_TXD_RTS_FRAME, &desc->flags)); | ||
| 1299 | rt2x00_desc_write(txd, 10, word); | ||
| 1300 | |||
| 1301 | rt2x00_desc_read(txd, 0, &word); | ||
| 1302 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | ||
| 1303 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | ||
| 1304 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | ||
| 1305 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | ||
| 1306 | rt2x00_set_field32(&word, TXD_W0_ACK, | ||
| 1307 | !(control->flags & IEEE80211_TXCTL_NO_ACK)); | ||
| 1308 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | ||
| 1309 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | ||
| 1310 | rt2x00_set_field32(&word, TXD_W0_OFDM, | ||
| 1311 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | ||
| 1312 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); | ||
| 1313 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | ||
| 1314 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | ||
| 1315 | !!(control->flags & | ||
| 1316 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | ||
| 1317 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length); | ||
| 1318 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | ||
| 1319 | rt2x00_desc_write(txd, 0, word); | ||
| 1320 | } | ||
| 1321 | |||
| 1322 | /* | ||
| 1323 | * TX data initialization | ||
| 1324 | */ | ||
| 1325 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
| 1326 | unsigned int queue) | ||
| 1327 | { | ||
| 1328 | u32 reg; | ||
| 1329 | |||
| 1330 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | ||
| 1331 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
| 1332 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | ||
| 1333 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | ||
| 1334 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
| 1335 | } | ||
| 1336 | return; | ||
| 1337 | } | ||
| 1338 | |||
| 1339 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | ||
| 1340 | if (queue == IEEE80211_TX_QUEUE_DATA0) | ||
| 1341 | rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); | ||
| 1342 | else if (queue == IEEE80211_TX_QUEUE_DATA1) | ||
| 1343 | rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); | ||
| 1344 | else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON) | ||
| 1345 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); | ||
| 1346 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | ||
| 1347 | } | ||
| 1348 | |||
| 1349 | /* | ||
| 1350 | * RX control handlers | ||
| 1351 | */ | ||
| 1352 | static int rt2500pci_fill_rxdone(struct data_entry *entry, | ||
| 1353 | int *signal, int *rssi, int *ofdm, int *size) | ||
| 1354 | { | ||
| 1355 | struct data_desc *rxd = entry->priv; | ||
| 1356 | u32 word0; | ||
| 1357 | u32 word2; | ||
| 1358 | |||
| 1359 | rt2x00_desc_read(rxd, 0, &word0); | ||
| 1360 | rt2x00_desc_read(rxd, 2, &word2); | ||
| 1361 | |||
| 1362 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR) || | ||
| 1363 | rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR) || | ||
| 1364 | rt2x00_get_field32(word0, RXD_W0_ICV_ERROR)) | ||
| 1365 | return -EINVAL; | ||
| 1366 | |||
| 1367 | *signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | ||
| 1368 | *rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | ||
| 1369 | entry->ring->rt2x00dev->rssi_offset; | ||
| 1370 | *ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | ||
| 1371 | *size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
| 1372 | |||
| 1373 | return 0; | ||
| 1374 | } | ||
| 1375 | |||
| 1376 | /* | ||
| 1377 | * Interrupt functions. | ||
| 1378 | */ | ||
| 1379 | static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | ||
| 1380 | { | ||
| 1381 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | ||
| 1382 | struct data_entry *entry; | ||
| 1383 | struct data_desc *txd; | ||
| 1384 | u32 word; | ||
| 1385 | int tx_status; | ||
| 1386 | int retry; | ||
| 1387 | |||
| 1388 | while (!rt2x00_ring_empty(ring)) { | ||
| 1389 | entry = rt2x00_get_data_entry_done(ring); | ||
| 1390 | txd = entry->priv; | ||
| 1391 | rt2x00_desc_read(txd, 0, &word); | ||
| 1392 | |||
| 1393 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | ||
| 1394 | !rt2x00_get_field32(word, TXD_W0_VALID)) | ||
| 1395 | break; | ||
| 1396 | |||
| 1397 | /* | ||
| 1398 | * Obtain the status about this packet. | ||
| 1399 | */ | ||
| 1400 | tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); | ||
| 1401 | retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | ||
| 1402 | |||
| 1403 | rt2x00lib_txdone(entry, tx_status, retry); | ||
| 1404 | |||
| 1405 | /* | ||
| 1406 | * Make this entry available for reuse. | ||
| 1407 | */ | ||
| 1408 | entry->flags = 0; | ||
| 1409 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | ||
| 1410 | rt2x00_desc_write(txd, 0, word); | ||
| 1411 | rt2x00_ring_index_done_inc(ring); | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | /* | ||
| 1415 | * If the data ring was full before the txdone handler | ||
| 1416 | * we must make sure the packet queue in the mac80211 stack | ||
| 1417 | * is reenabled when the txdone handler has finished. | ||
| 1418 | */ | ||
| 1419 | entry = ring->entry; | ||
| 1420 | if (!rt2x00_ring_full(ring)) | ||
| 1421 | ieee80211_wake_queue(rt2x00dev->hw, | ||
| 1422 | entry->tx_status.control.queue); | ||
| 1423 | } | ||
| 1424 | |||
| 1425 | static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) | ||
| 1426 | { | ||
| 1427 | struct rt2x00_dev *rt2x00dev = dev_instance; | ||
| 1428 | u32 reg; | ||
| 1429 | |||
| 1430 | /* | ||
| 1431 | * Get the interrupt sources & saved to local variable. | ||
| 1432 | * Write register value back to clear pending interrupts. | ||
| 1433 | */ | ||
| 1434 | rt2x00pci_register_read(rt2x00dev, CSR7, ®); | ||
| 1435 | rt2x00pci_register_write(rt2x00dev, CSR7, reg); | ||
| 1436 | |||
| 1437 | if (!reg) | ||
| 1438 | return IRQ_NONE; | ||
| 1439 | |||
| 1440 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
| 1441 | return IRQ_HANDLED; | ||
| 1442 | |||
| 1443 | /* | ||
| 1444 | * Handle interrupts, walk through all bits | ||
| 1445 | * and run the tasks, the bits are checked in order of | ||
| 1446 | * priority. | ||
| 1447 | */ | ||
| 1448 | |||
| 1449 | /* | ||
| 1450 | * 1 - Beacon timer expired interrupt. | ||
| 1451 | */ | ||
| 1452 | if (rt2x00_get_field32(reg, CSR7_TBCN_EXPIRE)) | ||
| 1453 | rt2x00lib_beacondone(rt2x00dev); | ||
| 1454 | |||
| 1455 | /* | ||
| 1456 | * 2 - Rx ring done interrupt. | ||
| 1457 | */ | ||
| 1458 | if (rt2x00_get_field32(reg, CSR7_RXDONE)) | ||
| 1459 | rt2x00pci_rxdone(rt2x00dev); | ||
| 1460 | |||
| 1461 | /* | ||
| 1462 | * 3 - Atim ring transmit done interrupt. | ||
| 1463 | */ | ||
| 1464 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) | ||
| 1465 | rt2500pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | ||
| 1466 | |||
| 1467 | /* | ||
| 1468 | * 4 - Priority ring transmit done interrupt. | ||
| 1469 | */ | ||
| 1470 | if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING)) | ||
| 1471 | rt2500pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_DATA0); | ||
| 1472 | |||
| 1473 | /* | ||
| 1474 | * 5 - Tx ring transmit done interrupt. | ||
| 1475 | */ | ||
| 1476 | if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) | ||
| 1477 | rt2500pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_DATA1); | ||
| 1478 | |||
| 1479 | return IRQ_HANDLED; | ||
| 1480 | } | ||
| 1481 | |||
| 1482 | /* | ||
| 1483 | * Device probe functions. | ||
| 1484 | */ | ||
| 1485 | static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | ||
| 1486 | { | ||
| 1487 | struct eeprom_93cx6 eeprom; | ||
| 1488 | u32 reg; | ||
| 1489 | u16 word; | ||
| 1490 | u8 *mac; | ||
| 1491 | |||
| 1492 | rt2x00pci_register_read(rt2x00dev, CSR21, ®); | ||
| 1493 | |||
| 1494 | eeprom.data = rt2x00dev; | ||
| 1495 | eeprom.register_read = rt2500pci_eepromregister_read; | ||
| 1496 | eeprom.register_write = rt2500pci_eepromregister_write; | ||
| 1497 | eeprom.width = rt2x00_get_field32(reg, CSR21_TYPE_93C46) ? | ||
| 1498 | PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66; | ||
| 1499 | eeprom.reg_data_in = 0; | ||
| 1500 | eeprom.reg_data_out = 0; | ||
| 1501 | eeprom.reg_data_clock = 0; | ||
| 1502 | eeprom.reg_chip_select = 0; | ||
| 1503 | |||
| 1504 | eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom, | ||
| 1505 | EEPROM_SIZE / sizeof(u16)); | ||
| 1506 | |||
| 1507 | /* | ||
| 1508 | * Start validation of the data that has been read. | ||
| 1509 | */ | ||
| 1510 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | ||
| 1511 | if (!is_valid_ether_addr(mac)) { | ||
| 1512 | random_ether_addr(mac); | ||
| 1513 | EEPROM(rt2x00dev, "MAC: " MAC_FMT "\n", MAC_ARG(mac)); | ||
| 1514 | } | ||
| 1515 | |||
| 1516 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | ||
| 1517 | if (word == 0xffff) { | ||
| 1518 | rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2); | ||
| 1519 | rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 0); | ||
| 1520 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 0); | ||
| 1521 | rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE, 0); | ||
| 1522 | rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0); | ||
| 1523 | rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); | ||
| 1524 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522); | ||
| 1525 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | ||
| 1526 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | ||
| 1527 | } | ||
| 1528 | |||
| 1529 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | ||
| 1530 | if (word == 0xffff) { | ||
| 1531 | rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); | ||
| 1532 | rt2x00_set_field16(&word, EEPROM_NIC_DYN_BBP_TUNE, 0); | ||
| 1533 | rt2x00_set_field16(&word, EEPROM_NIC_CCK_TX_POWER, 0); | ||
| 1534 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | ||
| 1535 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | ||
| 1536 | } | ||
| 1537 | |||
| 1538 | rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &word); | ||
| 1539 | if (word == 0xffff) { | ||
| 1540 | rt2x00_set_field16(&word, EEPROM_CALIBRATE_OFFSET_RSSI, | ||
| 1541 | DEFAULT_RSSI_OFFSET); | ||
| 1542 | rt2x00_eeprom_write(rt2x00dev, EEPROM_CALIBRATE_OFFSET, word); | ||
| 1543 | EEPROM(rt2x00dev, "Calibrate offset: 0x%04x\n", word); | ||
| 1544 | } | ||
| 1545 | |||
| 1546 | return 0; | ||
| 1547 | } | ||
| 1548 | |||
| 1549 | static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | ||
| 1550 | { | ||
| 1551 | u32 reg; | ||
| 1552 | u16 value; | ||
| 1553 | u16 eeprom; | ||
| 1554 | |||
| 1555 | /* | ||
| 1556 | * Read EEPROM word for configuration. | ||
| 1557 | */ | ||
| 1558 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
| 1559 | |||
| 1560 | /* | ||
| 1561 | * Identify RF chipset. | ||
| 1562 | */ | ||
| 1563 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | ||
| 1564 | rt2x00pci_register_read(rt2x00dev, CSR0, ®); | ||
| 1565 | rt2x00_set_chip(rt2x00dev, RT2560, value, reg); | ||
| 1566 | |||
| 1567 | if (!rt2x00_rf(&rt2x00dev->chip, RF2522) && | ||
| 1568 | !rt2x00_rf(&rt2x00dev->chip, RF2523) && | ||
| 1569 | !rt2x00_rf(&rt2x00dev->chip, RF2524) && | ||
| 1570 | !rt2x00_rf(&rt2x00dev->chip, RF2525) && | ||
| 1571 | !rt2x00_rf(&rt2x00dev->chip, RF2525E) && | ||
| 1572 | !rt2x00_rf(&rt2x00dev->chip, RF5222)) { | ||
| 1573 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | ||
| 1574 | return -ENODEV; | ||
| 1575 | } | ||
| 1576 | |||
| 1577 | /* | ||
| 1578 | * Identify default antenna configuration. | ||
| 1579 | */ | ||
| 1580 | rt2x00dev->hw->conf.antenna_sel_tx = | ||
| 1581 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT); | ||
| 1582 | rt2x00dev->hw->conf.antenna_sel_rx = | ||
| 1583 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT); | ||
| 1584 | |||
| 1585 | /* | ||
| 1586 | * Store led mode, for correct led behaviour. | ||
| 1587 | */ | ||
| 1588 | rt2x00dev->led_mode = | ||
| 1589 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | ||
| 1590 | |||
| 1591 | /* | ||
| 1592 | * Detect if this device has an hardware controlled radio. | ||
| 1593 | */ | ||
| 1594 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) | ||
| 1595 | __set_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | ||
| 1596 | |||
| 1597 | /* | ||
| 1598 | * Check if the BBP tuning should be enabled. | ||
| 1599 | */ | ||
| 1600 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | ||
| 1601 | |||
| 1602 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_DYN_BBP_TUNE)) | ||
| 1603 | __set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags); | ||
| 1604 | |||
| 1605 | /* | ||
| 1606 | * Read the RSSI <-> dBm offset information. | ||
| 1607 | */ | ||
| 1608 | rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &eeprom); | ||
| 1609 | rt2x00dev->rssi_offset = | ||
| 1610 | rt2x00_get_field16(eeprom, EEPROM_CALIBRATE_OFFSET_RSSI); | ||
| 1611 | |||
| 1612 | return 0; | ||
| 1613 | } | ||
| 1614 | |||
| 1615 | /* | ||
| 1616 | * RF value list for RF2522 | ||
| 1617 | * Supports: 2.4 GHz | ||
| 1618 | */ | ||
| 1619 | static const struct rf_channel rf_vals_bg_2522[] = { | ||
| 1620 | { 1, 0x00002050, 0x000c1fda, 0x00000101, 0 }, | ||
| 1621 | { 2, 0x00002050, 0x000c1fee, 0x00000101, 0 }, | ||
| 1622 | { 3, 0x00002050, 0x000c2002, 0x00000101, 0 }, | ||
| 1623 | { 4, 0x00002050, 0x000c2016, 0x00000101, 0 }, | ||
| 1624 | { 5, 0x00002050, 0x000c202a, 0x00000101, 0 }, | ||
| 1625 | { 6, 0x00002050, 0x000c203e, 0x00000101, 0 }, | ||
| 1626 | { 7, 0x00002050, 0x000c2052, 0x00000101, 0 }, | ||
| 1627 | { 8, 0x00002050, 0x000c2066, 0x00000101, 0 }, | ||
| 1628 | { 9, 0x00002050, 0x000c207a, 0x00000101, 0 }, | ||
| 1629 | { 10, 0x00002050, 0x000c208e, 0x00000101, 0 }, | ||
| 1630 | { 11, 0x00002050, 0x000c20a2, 0x00000101, 0 }, | ||
| 1631 | { 12, 0x00002050, 0x000c20b6, 0x00000101, 0 }, | ||
| 1632 | { 13, 0x00002050, 0x000c20ca, 0x00000101, 0 }, | ||
| 1633 | { 14, 0x00002050, 0x000c20fa, 0x00000101, 0 }, | ||
| 1634 | }; | ||
| 1635 | |||
| 1636 | /* | ||
| 1637 | * RF value list for RF2523 | ||
| 1638 | * Supports: 2.4 GHz | ||
| 1639 | */ | ||
| 1640 | static const struct rf_channel rf_vals_bg_2523[] = { | ||
| 1641 | { 1, 0x00022010, 0x00000c9e, 0x000e0111, 0x00000a1b }, | ||
| 1642 | { 2, 0x00022010, 0x00000ca2, 0x000e0111, 0x00000a1b }, | ||
| 1643 | { 3, 0x00022010, 0x00000ca6, 0x000e0111, 0x00000a1b }, | ||
| 1644 | { 4, 0x00022010, 0x00000caa, 0x000e0111, 0x00000a1b }, | ||
| 1645 | { 5, 0x00022010, 0x00000cae, 0x000e0111, 0x00000a1b }, | ||
| 1646 | { 6, 0x00022010, 0x00000cb2, 0x000e0111, 0x00000a1b }, | ||
| 1647 | { 7, 0x00022010, 0x00000cb6, 0x000e0111, 0x00000a1b }, | ||
| 1648 | { 8, 0x00022010, 0x00000cba, 0x000e0111, 0x00000a1b }, | ||
| 1649 | { 9, 0x00022010, 0x00000cbe, 0x000e0111, 0x00000a1b }, | ||
| 1650 | { 10, 0x00022010, 0x00000d02, 0x000e0111, 0x00000a1b }, | ||
| 1651 | { 11, 0x00022010, 0x00000d06, 0x000e0111, 0x00000a1b }, | ||
| 1652 | { 12, 0x00022010, 0x00000d0a, 0x000e0111, 0x00000a1b }, | ||
| 1653 | { 13, 0x00022010, 0x00000d0e, 0x000e0111, 0x00000a1b }, | ||
| 1654 | { 14, 0x00022010, 0x00000d1a, 0x000e0111, 0x00000a03 }, | ||
| 1655 | }; | ||
| 1656 | |||
| 1657 | /* | ||
| 1658 | * RF value list for RF2524 | ||
| 1659 | * Supports: 2.4 GHz | ||
| 1660 | */ | ||
| 1661 | static const struct rf_channel rf_vals_bg_2524[] = { | ||
| 1662 | { 1, 0x00032020, 0x00000c9e, 0x00000101, 0x00000a1b }, | ||
| 1663 | { 2, 0x00032020, 0x00000ca2, 0x00000101, 0x00000a1b }, | ||
| 1664 | { 3, 0x00032020, 0x00000ca6, 0x00000101, 0x00000a1b }, | ||
| 1665 | { 4, 0x00032020, 0x00000caa, 0x00000101, 0x00000a1b }, | ||
| 1666 | { 5, 0x00032020, 0x00000cae, 0x00000101, 0x00000a1b }, | ||
| 1667 | { 6, 0x00032020, 0x00000cb2, 0x00000101, 0x00000a1b }, | ||
| 1668 | { 7, 0x00032020, 0x00000cb6, 0x00000101, 0x00000a1b }, | ||
| 1669 | { 8, 0x00032020, 0x00000cba, 0x00000101, 0x00000a1b }, | ||
| 1670 | { 9, 0x00032020, 0x00000cbe, 0x00000101, 0x00000a1b }, | ||
| 1671 | { 10, 0x00032020, 0x00000d02, 0x00000101, 0x00000a1b }, | ||
| 1672 | { 11, 0x00032020, 0x00000d06, 0x00000101, 0x00000a1b }, | ||
| 1673 | { 12, 0x00032020, 0x00000d0a, 0x00000101, 0x00000a1b }, | ||
| 1674 | { 13, 0x00032020, 0x00000d0e, 0x00000101, 0x00000a1b }, | ||
| 1675 | { 14, 0x00032020, 0x00000d1a, 0x00000101, 0x00000a03 }, | ||
| 1676 | }; | ||
| 1677 | |||
| 1678 | /* | ||
| 1679 | * RF value list for RF2525 | ||
| 1680 | * Supports: 2.4 GHz | ||
| 1681 | */ | ||
| 1682 | static const struct rf_channel rf_vals_bg_2525[] = { | ||
| 1683 | { 1, 0x00022020, 0x00080c9e, 0x00060111, 0x00000a1b }, | ||
| 1684 | { 2, 0x00022020, 0x00080ca2, 0x00060111, 0x00000a1b }, | ||
| 1685 | { 3, 0x00022020, 0x00080ca6, 0x00060111, 0x00000a1b }, | ||
| 1686 | { 4, 0x00022020, 0x00080caa, 0x00060111, 0x00000a1b }, | ||
| 1687 | { 5, 0x00022020, 0x00080cae, 0x00060111, 0x00000a1b }, | ||
| 1688 | { 6, 0x00022020, 0x00080cb2, 0x00060111, 0x00000a1b }, | ||
| 1689 | { 7, 0x00022020, 0x00080cb6, 0x00060111, 0x00000a1b }, | ||
| 1690 | { 8, 0x00022020, 0x00080cba, 0x00060111, 0x00000a1b }, | ||
| 1691 | { 9, 0x00022020, 0x00080cbe, 0x00060111, 0x00000a1b }, | ||
| 1692 | { 10, 0x00022020, 0x00080d02, 0x00060111, 0x00000a1b }, | ||
| 1693 | { 11, 0x00022020, 0x00080d06, 0x00060111, 0x00000a1b }, | ||
| 1694 | { 12, 0x00022020, 0x00080d0a, 0x00060111, 0x00000a1b }, | ||
| 1695 | { 13, 0x00022020, 0x00080d0e, 0x00060111, 0x00000a1b }, | ||
| 1696 | { 14, 0x00022020, 0x00080d1a, 0x00060111, 0x00000a03 }, | ||
| 1697 | }; | ||
| 1698 | |||
| 1699 | /* | ||
| 1700 | * RF value list for RF2525e | ||
| 1701 | * Supports: 2.4 GHz | ||
| 1702 | */ | ||
| 1703 | static const struct rf_channel rf_vals_bg_2525e[] = { | ||
| 1704 | { 1, 0x00022020, 0x00081136, 0x00060111, 0x00000a0b }, | ||
| 1705 | { 2, 0x00022020, 0x0008113a, 0x00060111, 0x00000a0b }, | ||
| 1706 | { 3, 0x00022020, 0x0008113e, 0x00060111, 0x00000a0b }, | ||
| 1707 | { 4, 0x00022020, 0x00081182, 0x00060111, 0x00000a0b }, | ||
| 1708 | { 5, 0x00022020, 0x00081186, 0x00060111, 0x00000a0b }, | ||
| 1709 | { 6, 0x00022020, 0x0008118a, 0x00060111, 0x00000a0b }, | ||
| 1710 | { 7, 0x00022020, 0x0008118e, 0x00060111, 0x00000a0b }, | ||
| 1711 | { 8, 0x00022020, 0x00081192, 0x00060111, 0x00000a0b }, | ||
| 1712 | { 9, 0x00022020, 0x00081196, 0x00060111, 0x00000a0b }, | ||
| 1713 | { 10, 0x00022020, 0x0008119a, 0x00060111, 0x00000a0b }, | ||
| 1714 | { 11, 0x00022020, 0x0008119e, 0x00060111, 0x00000a0b }, | ||
| 1715 | { 12, 0x00022020, 0x000811a2, 0x00060111, 0x00000a0b }, | ||
| 1716 | { 13, 0x00022020, 0x000811a6, 0x00060111, 0x00000a0b }, | ||
| 1717 | { 14, 0x00022020, 0x000811ae, 0x00060111, 0x00000a1b }, | ||
| 1718 | }; | ||
| 1719 | |||
| 1720 | /* | ||
| 1721 | * RF value list for RF5222 | ||
| 1722 | * Supports: 2.4 GHz & 5.2 GHz | ||
| 1723 | */ | ||
| 1724 | static const struct rf_channel rf_vals_5222[] = { | ||
| 1725 | { 1, 0x00022020, 0x00001136, 0x00000101, 0x00000a0b }, | ||
| 1726 | { 2, 0x00022020, 0x0000113a, 0x00000101, 0x00000a0b }, | ||
| 1727 | { 3, 0x00022020, 0x0000113e, 0x00000101, 0x00000a0b }, | ||
| 1728 | { 4, 0x00022020, 0x00001182, 0x00000101, 0x00000a0b }, | ||
| 1729 | { 5, 0x00022020, 0x00001186, 0x00000101, 0x00000a0b }, | ||
| 1730 | { 6, 0x00022020, 0x0000118a, 0x00000101, 0x00000a0b }, | ||
| 1731 | { 7, 0x00022020, 0x0000118e, 0x00000101, 0x00000a0b }, | ||
| 1732 | { 8, 0x00022020, 0x00001192, 0x00000101, 0x00000a0b }, | ||
| 1733 | { 9, 0x00022020, 0x00001196, 0x00000101, 0x00000a0b }, | ||
| 1734 | { 10, 0x00022020, 0x0000119a, 0x00000101, 0x00000a0b }, | ||
| 1735 | { 11, 0x00022020, 0x0000119e, 0x00000101, 0x00000a0b }, | ||
| 1736 | { 12, 0x00022020, 0x000011a2, 0x00000101, 0x00000a0b }, | ||
| 1737 | { 13, 0x00022020, 0x000011a6, 0x00000101, 0x00000a0b }, | ||
| 1738 | { 14, 0x00022020, 0x000011ae, 0x00000101, 0x00000a1b }, | ||
| 1739 | |||
| 1740 | /* 802.11 UNI / HyperLan 2 */ | ||
| 1741 | { 36, 0x00022010, 0x00018896, 0x00000101, 0x00000a1f }, | ||
| 1742 | { 40, 0x00022010, 0x0001889a, 0x00000101, 0x00000a1f }, | ||
| 1743 | { 44, 0x00022010, 0x0001889e, 0x00000101, 0x00000a1f }, | ||
| 1744 | { 48, 0x00022010, 0x000188a2, 0x00000101, 0x00000a1f }, | ||
| 1745 | { 52, 0x00022010, 0x000188a6, 0x00000101, 0x00000a1f }, | ||
| 1746 | { 66, 0x00022010, 0x000188aa, 0x00000101, 0x00000a1f }, | ||
| 1747 | { 60, 0x00022010, 0x000188ae, 0x00000101, 0x00000a1f }, | ||
| 1748 | { 64, 0x00022010, 0x000188b2, 0x00000101, 0x00000a1f }, | ||
| 1749 | |||
| 1750 | /* 802.11 HyperLan 2 */ | ||
| 1751 | { 100, 0x00022010, 0x00008802, 0x00000101, 0x00000a0f }, | ||
| 1752 | { 104, 0x00022010, 0x00008806, 0x00000101, 0x00000a0f }, | ||
| 1753 | { 108, 0x00022010, 0x0000880a, 0x00000101, 0x00000a0f }, | ||
| 1754 | { 112, 0x00022010, 0x0000880e, 0x00000101, 0x00000a0f }, | ||
| 1755 | { 116, 0x00022010, 0x00008812, 0x00000101, 0x00000a0f }, | ||
| 1756 | { 120, 0x00022010, 0x00008816, 0x00000101, 0x00000a0f }, | ||
| 1757 | { 124, 0x00022010, 0x0000881a, 0x00000101, 0x00000a0f }, | ||
| 1758 | { 128, 0x00022010, 0x0000881e, 0x00000101, 0x00000a0f }, | ||
| 1759 | { 132, 0x00022010, 0x00008822, 0x00000101, 0x00000a0f }, | ||
| 1760 | { 136, 0x00022010, 0x00008826, 0x00000101, 0x00000a0f }, | ||
| 1761 | |||
| 1762 | /* 802.11 UNII */ | ||
| 1763 | { 140, 0x00022010, 0x0000882a, 0x00000101, 0x00000a0f }, | ||
| 1764 | { 149, 0x00022020, 0x000090a6, 0x00000101, 0x00000a07 }, | ||
| 1765 | { 153, 0x00022020, 0x000090ae, 0x00000101, 0x00000a07 }, | ||
| 1766 | { 157, 0x00022020, 0x000090b6, 0x00000101, 0x00000a07 }, | ||
| 1767 | { 161, 0x00022020, 0x000090be, 0x00000101, 0x00000a07 }, | ||
| 1768 | }; | ||
| 1769 | |||
| 1770 | static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | ||
| 1771 | { | ||
| 1772 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
| 1773 | u8 *txpower; | ||
| 1774 | unsigned int i; | ||
| 1775 | |||
| 1776 | /* | ||
| 1777 | * Initialize all hw fields. | ||
| 1778 | */ | ||
| 1779 | rt2x00dev->hw->flags = | ||
| 1780 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
| 1781 | IEEE80211_HW_MONITOR_DURING_OPER | | ||
| 1782 | IEEE80211_HW_NO_PROBE_FILTERING; | ||
| 1783 | rt2x00dev->hw->extra_tx_headroom = 0; | ||
| 1784 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | ||
| 1785 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | ||
| 1786 | rt2x00dev->hw->queues = 2; | ||
| 1787 | |||
| 1788 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | ||
| 1789 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | ||
| 1790 | rt2x00_eeprom_addr(rt2x00dev, | ||
| 1791 | EEPROM_MAC_ADDR_0)); | ||
| 1792 | |||
| 1793 | /* | ||
| 1794 | * Convert tx_power array in eeprom. | ||
| 1795 | */ | ||
| 1796 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); | ||
| 1797 | for (i = 0; i < 14; i++) | ||
| 1798 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | ||
| 1799 | |||
| 1800 | /* | ||
| 1801 | * Initialize hw_mode information. | ||
| 1802 | */ | ||
| 1803 | spec->num_modes = 2; | ||
| 1804 | spec->num_rates = 12; | ||
| 1805 | spec->tx_power_a = NULL; | ||
| 1806 | spec->tx_power_bg = txpower; | ||
| 1807 | spec->tx_power_default = DEFAULT_TXPOWER; | ||
| 1808 | |||
| 1809 | if (rt2x00_rf(&rt2x00dev->chip, RF2522)) { | ||
| 1810 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522); | ||
| 1811 | spec->channels = rf_vals_bg_2522; | ||
| 1812 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2523)) { | ||
| 1813 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523); | ||
| 1814 | spec->channels = rf_vals_bg_2523; | ||
| 1815 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2524)) { | ||
| 1816 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524); | ||
| 1817 | spec->channels = rf_vals_bg_2524; | ||
| 1818 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2525)) { | ||
| 1819 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525); | ||
| 1820 | spec->channels = rf_vals_bg_2525; | ||
| 1821 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) { | ||
| 1822 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); | ||
| 1823 | spec->channels = rf_vals_bg_2525e; | ||
| 1824 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { | ||
| 1825 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); | ||
| 1826 | spec->channels = rf_vals_5222; | ||
| 1827 | spec->num_modes = 3; | ||
| 1828 | } | ||
| 1829 | } | ||
| 1830 | |||
| 1831 | static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | ||
| 1832 | { | ||
| 1833 | int retval; | ||
| 1834 | |||
| 1835 | /* | ||
| 1836 | * Allocate eeprom data. | ||
| 1837 | */ | ||
| 1838 | retval = rt2500pci_validate_eeprom(rt2x00dev); | ||
| 1839 | if (retval) | ||
| 1840 | return retval; | ||
| 1841 | |||
| 1842 | retval = rt2500pci_init_eeprom(rt2x00dev); | ||
| 1843 | if (retval) | ||
| 1844 | return retval; | ||
| 1845 | |||
| 1846 | /* | ||
| 1847 | * Initialize hw specifications. | ||
| 1848 | */ | ||
| 1849 | rt2500pci_probe_hw_mode(rt2x00dev); | ||
| 1850 | |||
| 1851 | /* | ||
| 1852 | * This device requires the beacon ring | ||
| 1853 | */ | ||
| 1854 | __set_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags); | ||
| 1855 | |||
| 1856 | /* | ||
| 1857 | * Set the rssi offset. | ||
| 1858 | */ | ||
| 1859 | rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET; | ||
| 1860 | |||
| 1861 | return 0; | ||
| 1862 | } | ||
| 1863 | |||
| 1864 | /* | ||
| 1865 | * IEEE80211 stack callback functions. | ||
| 1866 | */ | ||
| 1867 | static int rt2500pci_set_retry_limit(struct ieee80211_hw *hw, | ||
| 1868 | u32 short_retry, u32 long_retry) | ||
| 1869 | { | ||
| 1870 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1871 | u32 reg; | ||
| 1872 | |||
| 1873 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | ||
| 1874 | rt2x00_set_field32(®, CSR11_LONG_RETRY, long_retry); | ||
| 1875 | rt2x00_set_field32(®, CSR11_SHORT_RETRY, short_retry); | ||
| 1876 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | ||
| 1877 | |||
| 1878 | return 0; | ||
| 1879 | } | ||
| 1880 | |||
| 1881 | static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw) | ||
| 1882 | { | ||
| 1883 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1884 | u64 tsf; | ||
| 1885 | u32 reg; | ||
| 1886 | |||
| 1887 | rt2x00pci_register_read(rt2x00dev, CSR17, ®); | ||
| 1888 | tsf = (u64) rt2x00_get_field32(reg, CSR17_HIGH_TSFTIMER) << 32; | ||
| 1889 | rt2x00pci_register_read(rt2x00dev, CSR16, ®); | ||
| 1890 | tsf |= rt2x00_get_field32(reg, CSR16_LOW_TSFTIMER); | ||
| 1891 | |||
| 1892 | return tsf; | ||
| 1893 | } | ||
| 1894 | |||
| 1895 | static void rt2500pci_reset_tsf(struct ieee80211_hw *hw) | ||
| 1896 | { | ||
| 1897 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1898 | |||
| 1899 | rt2x00pci_register_write(rt2x00dev, CSR16, 0); | ||
| 1900 | rt2x00pci_register_write(rt2x00dev, CSR17, 0); | ||
| 1901 | } | ||
| 1902 | |||
| 1903 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) | ||
| 1904 | { | ||
| 1905 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1906 | u32 reg; | ||
| 1907 | |||
| 1908 | rt2x00pci_register_read(rt2x00dev, CSR15, ®); | ||
| 1909 | return rt2x00_get_field32(reg, CSR15_BEACON_SENT); | ||
| 1910 | } | ||
| 1911 | |||
| 1912 | static const struct ieee80211_ops rt2500pci_mac80211_ops = { | ||
| 1913 | .tx = rt2x00mac_tx, | ||
| 1914 | .add_interface = rt2x00mac_add_interface, | ||
| 1915 | .remove_interface = rt2x00mac_remove_interface, | ||
| 1916 | .config = rt2x00mac_config, | ||
| 1917 | .config_interface = rt2x00mac_config_interface, | ||
| 1918 | .set_multicast_list = rt2x00mac_set_multicast_list, | ||
| 1919 | .get_stats = rt2x00mac_get_stats, | ||
| 1920 | .set_retry_limit = rt2500pci_set_retry_limit, | ||
| 1921 | .conf_tx = rt2x00mac_conf_tx, | ||
| 1922 | .get_tx_stats = rt2x00mac_get_tx_stats, | ||
| 1923 | .get_tsf = rt2500pci_get_tsf, | ||
| 1924 | .reset_tsf = rt2500pci_reset_tsf, | ||
| 1925 | .beacon_update = rt2x00pci_beacon_update, | ||
| 1926 | .tx_last_beacon = rt2500pci_tx_last_beacon, | ||
| 1927 | }; | ||
| 1928 | |||
| 1929 | static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | ||
| 1930 | .irq_handler = rt2500pci_interrupt, | ||
| 1931 | .probe_hw = rt2500pci_probe_hw, | ||
| 1932 | .initialize = rt2x00pci_initialize, | ||
| 1933 | .uninitialize = rt2x00pci_uninitialize, | ||
| 1934 | .set_device_state = rt2500pci_set_device_state, | ||
| 1935 | #ifdef CONFIG_RT2500PCI_RFKILL | ||
| 1936 | .rfkill_poll = rt2500pci_rfkill_poll, | ||
| 1937 | #endif /* CONFIG_RT2500PCI_RFKILL */ | ||
| 1938 | .link_stats = rt2500pci_link_stats, | ||
| 1939 | .reset_tuner = rt2500pci_reset_tuner, | ||
| 1940 | .link_tuner = rt2500pci_link_tuner, | ||
| 1941 | .write_tx_desc = rt2500pci_write_tx_desc, | ||
| 1942 | .write_tx_data = rt2x00pci_write_tx_data, | ||
| 1943 | .kick_tx_queue = rt2500pci_kick_tx_queue, | ||
| 1944 | .fill_rxdone = rt2500pci_fill_rxdone, | ||
| 1945 | .config_mac_addr = rt2500pci_config_mac_addr, | ||
| 1946 | .config_bssid = rt2500pci_config_bssid, | ||
| 1947 | .config_packet_filter = rt2500pci_config_packet_filter, | ||
| 1948 | .config_type = rt2500pci_config_type, | ||
| 1949 | .config = rt2500pci_config, | ||
| 1950 | }; | ||
| 1951 | |||
| 1952 | static const struct rt2x00_ops rt2500pci_ops = { | ||
| 1953 | .name = DRV_NAME, | ||
| 1954 | .rxd_size = RXD_DESC_SIZE, | ||
| 1955 | .txd_size = TXD_DESC_SIZE, | ||
| 1956 | .eeprom_size = EEPROM_SIZE, | ||
| 1957 | .rf_size = RF_SIZE, | ||
| 1958 | .lib = &rt2500pci_rt2x00_ops, | ||
| 1959 | .hw = &rt2500pci_mac80211_ops, | ||
| 1960 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
| 1961 | .debugfs = &rt2500pci_rt2x00debug, | ||
| 1962 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
| 1963 | }; | ||
| 1964 | |||
| 1965 | /* | ||
| 1966 | * RT2500pci module information. | ||
| 1967 | */ | ||
| 1968 | static struct pci_device_id rt2500pci_device_table[] = { | ||
| 1969 | { PCI_DEVICE(0x1814, 0x0201), PCI_DEVICE_DATA(&rt2500pci_ops) }, | ||
| 1970 | { 0, } | ||
| 1971 | }; | ||
| 1972 | |||
| 1973 | MODULE_AUTHOR(DRV_PROJECT); | ||
| 1974 | MODULE_VERSION(DRV_VERSION); | ||
| 1975 | MODULE_DESCRIPTION("Ralink RT2500 PCI & PCMCIA Wireless LAN driver."); | ||
| 1976 | MODULE_SUPPORTED_DEVICE("Ralink RT2560 PCI & PCMCIA chipset based cards"); | ||
| 1977 | MODULE_DEVICE_TABLE(pci, rt2500pci_device_table); | ||
| 1978 | MODULE_LICENSE("GPL"); | ||
| 1979 | |||
| 1980 | static struct pci_driver rt2500pci_driver = { | ||
| 1981 | .name = DRV_NAME, | ||
| 1982 | .id_table = rt2500pci_device_table, | ||
| 1983 | .probe = rt2x00pci_probe, | ||
| 1984 | .remove = __devexit_p(rt2x00pci_remove), | ||
| 1985 | .suspend = rt2x00pci_suspend, | ||
| 1986 | .resume = rt2x00pci_resume, | ||
| 1987 | }; | ||
| 1988 | |||
| 1989 | static int __init rt2500pci_init(void) | ||
| 1990 | { | ||
| 1991 | return pci_register_driver(&rt2500pci_driver); | ||
| 1992 | } | ||
| 1993 | |||
| 1994 | static void __exit rt2500pci_exit(void) | ||
| 1995 | { | ||
| 1996 | pci_unregister_driver(&rt2500pci_driver); | ||
| 1997 | } | ||
| 1998 | |||
| 1999 | module_init(rt2500pci_init); | ||
| 2000 | module_exit(rt2500pci_exit); | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h new file mode 100644 index 00000000000..d92aa56b2f4 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2500pci.h | |||
| @@ -0,0 +1,1236 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2500pci | ||
| 23 | Abstract: Data structures and registers for the rt2500pci module. | ||
| 24 | Supported chipsets: RT2560. | ||
| 25 | */ | ||
| 26 | |||
| 27 | #ifndef RT2500PCI_H | ||
| 28 | #define RT2500PCI_H | ||
| 29 | |||
| 30 | /* | ||
| 31 | * RF chip defines. | ||
| 32 | */ | ||
| 33 | #define RF2522 0x0000 | ||
| 34 | #define RF2523 0x0001 | ||
| 35 | #define RF2524 0x0002 | ||
| 36 | #define RF2525 0x0003 | ||
| 37 | #define RF2525E 0x0004 | ||
| 38 | #define RF5222 0x0010 | ||
| 39 | |||
| 40 | /* | ||
| 41 | * RT2560 version | ||
| 42 | */ | ||
| 43 | #define RT2560_VERSION_B 2 | ||
| 44 | #define RT2560_VERSION_C 3 | ||
| 45 | #define RT2560_VERSION_D 4 | ||
| 46 | |||
| 47 | /* | ||
| 48 | * Signal information. | ||
| 49 | * Defaul offset is required for RSSI <-> dBm conversion. | ||
| 50 | */ | ||
| 51 | #define MAX_SIGNAL 100 | ||
| 52 | #define MAX_RX_SSI -1 | ||
| 53 | #define DEFAULT_RSSI_OFFSET 121 | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Register layout information. | ||
| 57 | */ | ||
| 58 | #define CSR_REG_BASE 0x0000 | ||
| 59 | #define CSR_REG_SIZE 0x0174 | ||
| 60 | #define EEPROM_BASE 0x0000 | ||
| 61 | #define EEPROM_SIZE 0x0200 | ||
| 62 | #define BBP_SIZE 0x0040 | ||
| 63 | #define RF_SIZE 0x0014 | ||
| 64 | |||
| 65 | /* | ||
| 66 | * Control/Status Registers(CSR). | ||
| 67 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 68 | */ | ||
| 69 | |||
| 70 | /* | ||
| 71 | * CSR0: ASIC revision number. | ||
| 72 | */ | ||
| 73 | #define CSR0 0x0000 | ||
| 74 | |||
| 75 | /* | ||
| 76 | * CSR1: System control register. | ||
| 77 | * SOFT_RESET: Software reset, 1: reset, 0: normal. | ||
| 78 | * BBP_RESET: Hardware reset, 1: reset, 0, release. | ||
| 79 | * HOST_READY: Host ready after initialization. | ||
| 80 | */ | ||
| 81 | #define CSR1 0x0004 | ||
| 82 | #define CSR1_SOFT_RESET FIELD32(0x00000001) | ||
| 83 | #define CSR1_BBP_RESET FIELD32(0x00000002) | ||
| 84 | #define CSR1_HOST_READY FIELD32(0x00000004) | ||
| 85 | |||
| 86 | /* | ||
| 87 | * CSR2: System admin status register (invalid). | ||
| 88 | */ | ||
| 89 | #define CSR2 0x0008 | ||
| 90 | |||
| 91 | /* | ||
| 92 | * CSR3: STA MAC address register 0. | ||
| 93 | */ | ||
| 94 | #define CSR3 0x000c | ||
| 95 | #define CSR3_BYTE0 FIELD32(0x000000ff) | ||
| 96 | #define CSR3_BYTE1 FIELD32(0x0000ff00) | ||
| 97 | #define CSR3_BYTE2 FIELD32(0x00ff0000) | ||
| 98 | #define CSR3_BYTE3 FIELD32(0xff000000) | ||
| 99 | |||
| 100 | /* | ||
| 101 | * CSR4: STA MAC address register 1. | ||
| 102 | */ | ||
| 103 | #define CSR4 0x0010 | ||
| 104 | #define CSR4_BYTE4 FIELD32(0x000000ff) | ||
| 105 | #define CSR4_BYTE5 FIELD32(0x0000ff00) | ||
| 106 | |||
| 107 | /* | ||
| 108 | * CSR5: BSSID register 0. | ||
| 109 | */ | ||
| 110 | #define CSR5 0x0014 | ||
| 111 | #define CSR5_BYTE0 FIELD32(0x000000ff) | ||
| 112 | #define CSR5_BYTE1 FIELD32(0x0000ff00) | ||
| 113 | #define CSR5_BYTE2 FIELD32(0x00ff0000) | ||
| 114 | #define CSR5_BYTE3 FIELD32(0xff000000) | ||
| 115 | |||
| 116 | /* | ||
| 117 | * CSR6: BSSID register 1. | ||
| 118 | */ | ||
| 119 | #define CSR6 0x0018 | ||
| 120 | #define CSR6_BYTE4 FIELD32(0x000000ff) | ||
| 121 | #define CSR6_BYTE5 FIELD32(0x0000ff00) | ||
| 122 | |||
| 123 | /* | ||
| 124 | * CSR7: Interrupt source register. | ||
| 125 | * Write 1 to clear. | ||
| 126 | * TBCN_EXPIRE: Beacon timer expired interrupt. | ||
| 127 | * TWAKE_EXPIRE: Wakeup timer expired interrupt. | ||
| 128 | * TATIMW_EXPIRE: Timer of atim window expired interrupt. | ||
| 129 | * TXDONE_TXRING: Tx ring transmit done interrupt. | ||
| 130 | * TXDONE_ATIMRING: Atim ring transmit done interrupt. | ||
| 131 | * TXDONE_PRIORING: Priority ring transmit done interrupt. | ||
| 132 | * RXDONE: Receive done interrupt. | ||
| 133 | * DECRYPTION_DONE: Decryption done interrupt. | ||
| 134 | * ENCRYPTION_DONE: Encryption done interrupt. | ||
| 135 | * UART1_TX_TRESHOLD: UART1 TX reaches threshold. | ||
| 136 | * UART1_RX_TRESHOLD: UART1 RX reaches threshold. | ||
| 137 | * UART1_IDLE_TRESHOLD: UART1 IDLE over threshold. | ||
| 138 | * UART1_TX_BUFF_ERROR: UART1 TX buffer error. | ||
| 139 | * UART1_RX_BUFF_ERROR: UART1 RX buffer error. | ||
| 140 | * UART2_TX_TRESHOLD: UART2 TX reaches threshold. | ||
| 141 | * UART2_RX_TRESHOLD: UART2 RX reaches threshold. | ||
| 142 | * UART2_IDLE_TRESHOLD: UART2 IDLE over threshold. | ||
| 143 | * UART2_TX_BUFF_ERROR: UART2 TX buffer error. | ||
| 144 | * UART2_RX_BUFF_ERROR: UART2 RX buffer error. | ||
| 145 | * TIMER_CSR3_EXPIRE: TIMECSR3 timer expired (802.1H quiet period). | ||
| 146 | |||
| 147 | */ | ||
| 148 | #define CSR7 0x001c | ||
| 149 | #define CSR7_TBCN_EXPIRE FIELD32(0x00000001) | ||
| 150 | #define CSR7_TWAKE_EXPIRE FIELD32(0x00000002) | ||
| 151 | #define CSR7_TATIMW_EXPIRE FIELD32(0x00000004) | ||
| 152 | #define CSR7_TXDONE_TXRING FIELD32(0x00000008) | ||
| 153 | #define CSR7_TXDONE_ATIMRING FIELD32(0x00000010) | ||
| 154 | #define CSR7_TXDONE_PRIORING FIELD32(0x00000020) | ||
| 155 | #define CSR7_RXDONE FIELD32(0x00000040) | ||
| 156 | #define CSR7_DECRYPTION_DONE FIELD32(0x00000080) | ||
| 157 | #define CSR7_ENCRYPTION_DONE FIELD32(0x00000100) | ||
| 158 | #define CSR7_UART1_TX_TRESHOLD FIELD32(0x00000200) | ||
| 159 | #define CSR7_UART1_RX_TRESHOLD FIELD32(0x00000400) | ||
| 160 | #define CSR7_UART1_IDLE_TRESHOLD FIELD32(0x00000800) | ||
| 161 | #define CSR7_UART1_TX_BUFF_ERROR FIELD32(0x00001000) | ||
| 162 | #define CSR7_UART1_RX_BUFF_ERROR FIELD32(0x00002000) | ||
| 163 | #define CSR7_UART2_TX_TRESHOLD FIELD32(0x00004000) | ||
| 164 | #define CSR7_UART2_RX_TRESHOLD FIELD32(0x00008000) | ||
| 165 | #define CSR7_UART2_IDLE_TRESHOLD FIELD32(0x00010000) | ||
| 166 | #define CSR7_UART2_TX_BUFF_ERROR FIELD32(0x00020000) | ||
| 167 | #define CSR7_UART2_RX_BUFF_ERROR FIELD32(0x00040000) | ||
| 168 | #define CSR7_TIMER_CSR3_EXPIRE FIELD32(0x00080000) | ||
| 169 | |||
| 170 | /* | ||
| 171 | * CSR8: Interrupt mask register. | ||
| 172 | * Write 1 to mask interrupt. | ||
| 173 | * TBCN_EXPIRE: Beacon timer expired interrupt. | ||
| 174 | * TWAKE_EXPIRE: Wakeup timer expired interrupt. | ||
| 175 | * TATIMW_EXPIRE: Timer of atim window expired interrupt. | ||
| 176 | * TXDONE_TXRING: Tx ring transmit done interrupt. | ||
| 177 | * TXDONE_ATIMRING: Atim ring transmit done interrupt. | ||
| 178 | * TXDONE_PRIORING: Priority ring transmit done interrupt. | ||
| 179 | * RXDONE: Receive done interrupt. | ||
| 180 | * DECRYPTION_DONE: Decryption done interrupt. | ||
| 181 | * ENCRYPTION_DONE: Encryption done interrupt. | ||
| 182 | * UART1_TX_TRESHOLD: UART1 TX reaches threshold. | ||
| 183 | * UART1_RX_TRESHOLD: UART1 RX reaches threshold. | ||
| 184 | * UART1_IDLE_TRESHOLD: UART1 IDLE over threshold. | ||
| 185 | * UART1_TX_BUFF_ERROR: UART1 TX buffer error. | ||
| 186 | * UART1_RX_BUFF_ERROR: UART1 RX buffer error. | ||
| 187 | * UART2_TX_TRESHOLD: UART2 TX reaches threshold. | ||
| 188 | * UART2_RX_TRESHOLD: UART2 RX reaches threshold. | ||
| 189 | * UART2_IDLE_TRESHOLD: UART2 IDLE over threshold. | ||
| 190 | * UART2_TX_BUFF_ERROR: UART2 TX buffer error. | ||
| 191 | * UART2_RX_BUFF_ERROR: UART2 RX buffer error. | ||
| 192 | * TIMER_CSR3_EXPIRE: TIMECSR3 timer expired (802.1H quiet period). | ||
| 193 | */ | ||
| 194 | #define CSR8 0x0020 | ||
| 195 | #define CSR8_TBCN_EXPIRE FIELD32(0x00000001) | ||
| 196 | #define CSR8_TWAKE_EXPIRE FIELD32(0x00000002) | ||
| 197 | #define CSR8_TATIMW_EXPIRE FIELD32(0x00000004) | ||
| 198 | #define CSR8_TXDONE_TXRING FIELD32(0x00000008) | ||
| 199 | #define CSR8_TXDONE_ATIMRING FIELD32(0x00000010) | ||
| 200 | #define CSR8_TXDONE_PRIORING FIELD32(0x00000020) | ||
| 201 | #define CSR8_RXDONE FIELD32(0x00000040) | ||
| 202 | #define CSR8_DECRYPTION_DONE FIELD32(0x00000080) | ||
| 203 | #define CSR8_ENCRYPTION_DONE FIELD32(0x00000100) | ||
| 204 | #define CSR8_UART1_TX_TRESHOLD FIELD32(0x00000200) | ||
| 205 | #define CSR8_UART1_RX_TRESHOLD FIELD32(0x00000400) | ||
| 206 | #define CSR8_UART1_IDLE_TRESHOLD FIELD32(0x00000800) | ||
| 207 | #define CSR8_UART1_TX_BUFF_ERROR FIELD32(0x00001000) | ||
| 208 | #define CSR8_UART1_RX_BUFF_ERROR FIELD32(0x00002000) | ||
| 209 | #define CSR8_UART2_TX_TRESHOLD FIELD32(0x00004000) | ||
| 210 | #define CSR8_UART2_RX_TRESHOLD FIELD32(0x00008000) | ||
| 211 | #define CSR8_UART2_IDLE_TRESHOLD FIELD32(0x00010000) | ||
| 212 | #define CSR8_UART2_TX_BUFF_ERROR FIELD32(0x00020000) | ||
| 213 | #define CSR8_UART2_RX_BUFF_ERROR FIELD32(0x00040000) | ||
| 214 | #define CSR8_TIMER_CSR3_EXPIRE FIELD32(0x00080000) | ||
| 215 | |||
| 216 | /* | ||
| 217 | * CSR9: Maximum frame length register. | ||
| 218 | * MAX_FRAME_UNIT: Maximum frame length in 128b unit, default: 12. | ||
| 219 | */ | ||
| 220 | #define CSR9 0x0024 | ||
| 221 | #define CSR9_MAX_FRAME_UNIT FIELD32(0x00000f80) | ||
| 222 | |||
| 223 | /* | ||
| 224 | * SECCSR0: WEP control register. | ||
| 225 | * KICK_DECRYPT: Kick decryption engine, self-clear. | ||
| 226 | * ONE_SHOT: 0: ring mode, 1: One shot only mode. | ||
| 227 | * DESC_ADDRESS: Descriptor physical address of frame. | ||
| 228 | */ | ||
| 229 | #define SECCSR0 0x0028 | ||
| 230 | #define SECCSR0_KICK_DECRYPT FIELD32(0x00000001) | ||
| 231 | #define SECCSR0_ONE_SHOT FIELD32(0x00000002) | ||
| 232 | #define SECCSR0_DESC_ADDRESS FIELD32(0xfffffffc) | ||
| 233 | |||
| 234 | /* | ||
| 235 | * CSR11: Back-off control register. | ||
| 236 | * CWMIN: CWmin. Default cwmin is 31 (2^5 - 1). | ||
| 237 | * CWMAX: CWmax. Default cwmax is 1023 (2^10 - 1). | ||
| 238 | * SLOT_TIME: Slot time, default is 20us for 802.11b | ||
| 239 | * CW_SELECT: CWmin/CWmax selection, 1: Register, 0: TXD. | ||
| 240 | * LONG_RETRY: Long retry count. | ||
| 241 | * SHORT_RETRY: Short retry count. | ||
| 242 | */ | ||
| 243 | #define CSR11 0x002c | ||
| 244 | #define CSR11_CWMIN FIELD32(0x0000000f) | ||
| 245 | #define CSR11_CWMAX FIELD32(0x000000f0) | ||
| 246 | #define CSR11_SLOT_TIME FIELD32(0x00001f00) | ||
| 247 | #define CSR11_CW_SELECT FIELD32(0x00002000) | ||
| 248 | #define CSR11_LONG_RETRY FIELD32(0x00ff0000) | ||
| 249 | #define CSR11_SHORT_RETRY FIELD32(0xff000000) | ||
| 250 | |||
| 251 | /* | ||
| 252 | * CSR12: Synchronization configuration register 0. | ||
| 253 | * All units in 1/16 TU. | ||
| 254 | * BEACON_INTERVAL: Beacon interval, default is 100 TU. | ||
| 255 | * CFP_MAX_DURATION: Cfp maximum duration, default is 100 TU. | ||
| 256 | */ | ||
| 257 | #define CSR12 0x0030 | ||
| 258 | #define CSR12_BEACON_INTERVAL FIELD32(0x0000ffff) | ||
| 259 | #define CSR12_CFP_MAX_DURATION FIELD32(0xffff0000) | ||
| 260 | |||
| 261 | /* | ||
| 262 | * CSR13: Synchronization configuration register 1. | ||
| 263 | * All units in 1/16 TU. | ||
| 264 | * ATIMW_DURATION: Atim window duration. | ||
| 265 | * CFP_PERIOD: Cfp period, default is 0 TU. | ||
| 266 | */ | ||
| 267 | #define CSR13 0x0034 | ||
| 268 | #define CSR13_ATIMW_DURATION FIELD32(0x0000ffff) | ||
| 269 | #define CSR13_CFP_PERIOD FIELD32(0x00ff0000) | ||
| 270 | |||
| 271 | /* | ||
| 272 | * CSR14: Synchronization control register. | ||
| 273 | * TSF_COUNT: Enable tsf auto counting. | ||
| 274 | * TSF_SYNC: Tsf sync, 0: disable, 1: infra, 2: ad-hoc/master mode. | ||
| 275 | * TBCN: Enable tbcn with reload value. | ||
| 276 | * TCFP: Enable tcfp & cfp / cp switching. | ||
| 277 | * TATIMW: Enable tatimw & atim window switching. | ||
| 278 | * BEACON_GEN: Enable beacon generator. | ||
| 279 | * CFP_COUNT_PRELOAD: Cfp count preload value. | ||
| 280 | * TBCM_PRELOAD: Tbcn preload value in units of 64us. | ||
| 281 | */ | ||
| 282 | #define CSR14 0x0038 | ||
| 283 | #define CSR14_TSF_COUNT FIELD32(0x00000001) | ||
| 284 | #define CSR14_TSF_SYNC FIELD32(0x00000006) | ||
| 285 | #define CSR14_TBCN FIELD32(0x00000008) | ||
| 286 | #define CSR14_TCFP FIELD32(0x00000010) | ||
| 287 | #define CSR14_TATIMW FIELD32(0x00000020) | ||
| 288 | #define CSR14_BEACON_GEN FIELD32(0x00000040) | ||
| 289 | #define CSR14_CFP_COUNT_PRELOAD FIELD32(0x0000ff00) | ||
| 290 | #define CSR14_TBCM_PRELOAD FIELD32(0xffff0000) | ||
| 291 | |||
| 292 | /* | ||
| 293 | * CSR15: Synchronization status register. | ||
| 294 | * CFP: ASIC is in contention-free period. | ||
| 295 | * ATIMW: ASIC is in ATIM window. | ||
| 296 | * BEACON_SENT: Beacon is send. | ||
| 297 | */ | ||
| 298 | #define CSR15 0x003c | ||
| 299 | #define CSR15_CFP FIELD32(0x00000001) | ||
| 300 | #define CSR15_ATIMW FIELD32(0x00000002) | ||
| 301 | #define CSR15_BEACON_SENT FIELD32(0x00000004) | ||
| 302 | |||
| 303 | /* | ||
| 304 | * CSR16: TSF timer register 0. | ||
| 305 | */ | ||
| 306 | #define CSR16 0x0040 | ||
| 307 | #define CSR16_LOW_TSFTIMER FIELD32(0xffffffff) | ||
| 308 | |||
| 309 | /* | ||
| 310 | * CSR17: TSF timer register 1. | ||
| 311 | */ | ||
| 312 | #define CSR17 0x0044 | ||
| 313 | #define CSR17_HIGH_TSFTIMER FIELD32(0xffffffff) | ||
| 314 | |||
| 315 | /* | ||
| 316 | * CSR18: IFS timer register 0. | ||
| 317 | * SIFS: Sifs, default is 10 us. | ||
| 318 | * PIFS: Pifs, default is 30 us. | ||
| 319 | */ | ||
| 320 | #define CSR18 0x0048 | ||
| 321 | #define CSR18_SIFS FIELD32(0x000001ff) | ||
| 322 | #define CSR18_PIFS FIELD32(0x001f0000) | ||
| 323 | |||
| 324 | /* | ||
| 325 | * CSR19: IFS timer register 1. | ||
| 326 | * DIFS: Difs, default is 50 us. | ||
| 327 | * EIFS: Eifs, default is 364 us. | ||
| 328 | */ | ||
| 329 | #define CSR19 0x004c | ||
| 330 | #define CSR19_DIFS FIELD32(0x0000ffff) | ||
| 331 | #define CSR19_EIFS FIELD32(0xffff0000) | ||
| 332 | |||
| 333 | /* | ||
| 334 | * CSR20: Wakeup timer register. | ||
| 335 | * DELAY_AFTER_TBCN: Delay after tbcn expired in units of 1/16 TU. | ||
| 336 | * TBCN_BEFORE_WAKEUP: Number of beacon before wakeup. | ||
| 337 | * AUTOWAKE: Enable auto wakeup / sleep mechanism. | ||
| 338 | */ | ||
| 339 | #define CSR20 0x0050 | ||
| 340 | #define CSR20_DELAY_AFTER_TBCN FIELD32(0x0000ffff) | ||
| 341 | #define CSR20_TBCN_BEFORE_WAKEUP FIELD32(0x00ff0000) | ||
| 342 | #define CSR20_AUTOWAKE FIELD32(0x01000000) | ||
| 343 | |||
| 344 | /* | ||
| 345 | * CSR21: EEPROM control register. | ||
| 346 | * RELOAD: Write 1 to reload eeprom content. | ||
| 347 | * TYPE_93C46: 1: 93c46, 0:93c66. | ||
| 348 | */ | ||
| 349 | #define CSR21 0x0054 | ||
| 350 | #define CSR21_RELOAD FIELD32(0x00000001) | ||
| 351 | #define CSR21_EEPROM_DATA_CLOCK FIELD32(0x00000002) | ||
| 352 | #define CSR21_EEPROM_CHIP_SELECT FIELD32(0x00000004) | ||
| 353 | #define CSR21_EEPROM_DATA_IN FIELD32(0x00000008) | ||
| 354 | #define CSR21_EEPROM_DATA_OUT FIELD32(0x00000010) | ||
| 355 | #define CSR21_TYPE_93C46 FIELD32(0x00000020) | ||
| 356 | |||
| 357 | /* | ||
| 358 | * CSR22: CFP control register. | ||
| 359 | * CFP_DURATION_REMAIN: Cfp duration remain, in units of TU. | ||
| 360 | * RELOAD_CFP_DURATION: Write 1 to reload cfp duration remain. | ||
| 361 | */ | ||
| 362 | #define CSR22 0x0058 | ||
| 363 | #define CSR22_CFP_DURATION_REMAIN FIELD32(0x0000ffff) | ||
| 364 | #define CSR22_RELOAD_CFP_DURATION FIELD32(0x00010000) | ||
| 365 | |||
| 366 | /* | ||
| 367 | * Transmit related CSRs. | ||
| 368 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 369 | */ | ||
| 370 | |||
| 371 | /* | ||
| 372 | * TXCSR0: TX Control Register. | ||
| 373 | * KICK_TX: Kick tx ring. | ||
| 374 | * KICK_ATIM: Kick atim ring. | ||
| 375 | * KICK_PRIO: Kick priority ring. | ||
| 376 | * ABORT: Abort all transmit related ring operation. | ||
| 377 | */ | ||
| 378 | #define TXCSR0 0x0060 | ||
| 379 | #define TXCSR0_KICK_TX FIELD32(0x00000001) | ||
| 380 | #define TXCSR0_KICK_ATIM FIELD32(0x00000002) | ||
| 381 | #define TXCSR0_KICK_PRIO FIELD32(0x00000004) | ||
| 382 | #define TXCSR0_ABORT FIELD32(0x00000008) | ||
| 383 | |||
| 384 | /* | ||
| 385 | * TXCSR1: TX Configuration Register. | ||
| 386 | * ACK_TIMEOUT: Ack timeout, default = sifs + 2*slottime + acktime @ 1mbps. | ||
| 387 | * ACK_CONSUME_TIME: Ack consume time, default = sifs + acktime @ 1mbps. | ||
| 388 | * TSF_OFFSET: Insert tsf offset. | ||
| 389 | * AUTORESPONDER: Enable auto responder which include ack & cts. | ||
| 390 | */ | ||
| 391 | #define TXCSR1 0x0064 | ||
| 392 | #define TXCSR1_ACK_TIMEOUT FIELD32(0x000001ff) | ||
| 393 | #define TXCSR1_ACK_CONSUME_TIME FIELD32(0x0003fe00) | ||
| 394 | #define TXCSR1_TSF_OFFSET FIELD32(0x00fc0000) | ||
| 395 | #define TXCSR1_AUTORESPONDER FIELD32(0x01000000) | ||
| 396 | |||
| 397 | /* | ||
| 398 | * TXCSR2: Tx descriptor configuration register. | ||
| 399 | * TXD_SIZE: Tx descriptor size, default is 48. | ||
| 400 | * NUM_TXD: Number of tx entries in ring. | ||
| 401 | * NUM_ATIM: Number of atim entries in ring. | ||
| 402 | * NUM_PRIO: Number of priority entries in ring. | ||
| 403 | */ | ||
| 404 | #define TXCSR2 0x0068 | ||
| 405 | #define TXCSR2_TXD_SIZE FIELD32(0x000000ff) | ||
| 406 | #define TXCSR2_NUM_TXD FIELD32(0x0000ff00) | ||
| 407 | #define TXCSR2_NUM_ATIM FIELD32(0x00ff0000) | ||
| 408 | #define TXCSR2_NUM_PRIO FIELD32(0xff000000) | ||
| 409 | |||
| 410 | /* | ||
| 411 | * TXCSR3: TX Ring Base address register. | ||
| 412 | */ | ||
| 413 | #define TXCSR3 0x006c | ||
| 414 | #define TXCSR3_TX_RING_REGISTER FIELD32(0xffffffff) | ||
| 415 | |||
| 416 | /* | ||
| 417 | * TXCSR4: TX Atim Ring Base address register. | ||
| 418 | */ | ||
| 419 | #define TXCSR4 0x0070 | ||
| 420 | #define TXCSR4_ATIM_RING_REGISTER FIELD32(0xffffffff) | ||
| 421 | |||
| 422 | /* | ||
| 423 | * TXCSR5: TX Prio Ring Base address register. | ||
| 424 | */ | ||
| 425 | #define TXCSR5 0x0074 | ||
| 426 | #define TXCSR5_PRIO_RING_REGISTER FIELD32(0xffffffff) | ||
| 427 | |||
| 428 | /* | ||
| 429 | * TXCSR6: Beacon Base address register. | ||
| 430 | */ | ||
| 431 | #define TXCSR6 0x0078 | ||
| 432 | #define TXCSR6_BEACON_RING_REGISTER FIELD32(0xffffffff) | ||
| 433 | |||
| 434 | /* | ||
| 435 | * TXCSR7: Auto responder control register. | ||
| 436 | * AR_POWERMANAGEMENT: Auto responder power management bit. | ||
| 437 | */ | ||
| 438 | #define TXCSR7 0x007c | ||
| 439 | #define TXCSR7_AR_POWERMANAGEMENT FIELD32(0x00000001) | ||
| 440 | |||
| 441 | /* | ||
| 442 | * TXCSR8: CCK Tx BBP register. | ||
| 443 | */ | ||
| 444 | #define TXCSR8 0x0098 | ||
| 445 | #define TXCSR8_BBP_ID0 FIELD32(0x0000007f) | ||
| 446 | #define TXCSR8_BBP_ID0_VALID FIELD32(0x00000080) | ||
| 447 | #define TXCSR8_BBP_ID1 FIELD32(0x00007f00) | ||
| 448 | #define TXCSR8_BBP_ID1_VALID FIELD32(0x00008000) | ||
| 449 | #define TXCSR8_BBP_ID2 FIELD32(0x007f0000) | ||
| 450 | #define TXCSR8_BBP_ID2_VALID FIELD32(0x00800000) | ||
| 451 | #define TXCSR8_BBP_ID3 FIELD32(0x7f000000) | ||
| 452 | #define TXCSR8_BBP_ID3_VALID FIELD32(0x80000000) | ||
| 453 | |||
| 454 | /* | ||
| 455 | * TXCSR9: OFDM TX BBP registers | ||
| 456 | * OFDM_SIGNAL: BBP rate field address for OFDM. | ||
| 457 | * OFDM_SERVICE: BBP service field address for OFDM. | ||
| 458 | * OFDM_LENGTH_LOW: BBP length low byte address for OFDM. | ||
| 459 | * OFDM_LENGTH_HIGH: BBP length high byte address for OFDM. | ||
| 460 | */ | ||
| 461 | #define TXCSR9 0x0094 | ||
| 462 | #define TXCSR9_OFDM_RATE FIELD32(0x000000ff) | ||
| 463 | #define TXCSR9_OFDM_SERVICE FIELD32(0x0000ff00) | ||
| 464 | #define TXCSR9_OFDM_LENGTH_LOW FIELD32(0x00ff0000) | ||
| 465 | #define TXCSR9_OFDM_LENGTH_HIGH FIELD32(0xff000000) | ||
| 466 | |||
| 467 | /* | ||
| 468 | * Receive related CSRs. | ||
| 469 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 470 | */ | ||
| 471 | |||
| 472 | /* | ||
| 473 | * RXCSR0: RX Control Register. | ||
| 474 | * DISABLE_RX: Disable rx engine. | ||
| 475 | * DROP_CRC: Drop crc error. | ||
| 476 | * DROP_PHYSICAL: Drop physical error. | ||
| 477 | * DROP_CONTROL: Drop control frame. | ||
| 478 | * DROP_NOT_TO_ME: Drop not to me unicast frame. | ||
| 479 | * DROP_TODS: Drop frame tods bit is true. | ||
| 480 | * DROP_VERSION_ERROR: Drop version error frame. | ||
| 481 | * PASS_CRC: Pass all packets with crc attached. | ||
| 482 | * PASS_CRC: Pass all packets with crc attached. | ||
| 483 | * PASS_PLCP: Pass all packets with 4 bytes PLCP attached. | ||
| 484 | * DROP_MCAST: Drop multicast frames. | ||
| 485 | * DROP_BCAST: Drop broadcast frames. | ||
| 486 | * ENABLE_QOS: Accept QOS data frame and parse QOS field. | ||
| 487 | */ | ||
| 488 | #define RXCSR0 0x0080 | ||
| 489 | #define RXCSR0_DISABLE_RX FIELD32(0x00000001) | ||
| 490 | #define RXCSR0_DROP_CRC FIELD32(0x00000002) | ||
| 491 | #define RXCSR0_DROP_PHYSICAL FIELD32(0x00000004) | ||
| 492 | #define RXCSR0_DROP_CONTROL FIELD32(0x00000008) | ||
| 493 | #define RXCSR0_DROP_NOT_TO_ME FIELD32(0x00000010) | ||
| 494 | #define RXCSR0_DROP_TODS FIELD32(0x00000020) | ||
| 495 | #define RXCSR0_DROP_VERSION_ERROR FIELD32(0x00000040) | ||
| 496 | #define RXCSR0_PASS_CRC FIELD32(0x00000080) | ||
| 497 | #define RXCSR0_PASS_PLCP FIELD32(0x00000100) | ||
| 498 | #define RXCSR0_DROP_MCAST FIELD32(0x00000200) | ||
| 499 | #define RXCSR0_DROP_BCAST FIELD32(0x00000400) | ||
| 500 | #define RXCSR0_ENABLE_QOS FIELD32(0x00000800) | ||
| 501 | |||
| 502 | /* | ||
| 503 | * RXCSR1: RX descriptor configuration register. | ||
| 504 | * RXD_SIZE: Rx descriptor size, default is 32b. | ||
| 505 | * NUM_RXD: Number of rx entries in ring. | ||
| 506 | */ | ||
| 507 | #define RXCSR1 0x0084 | ||
| 508 | #define RXCSR1_RXD_SIZE FIELD32(0x000000ff) | ||
| 509 | #define RXCSR1_NUM_RXD FIELD32(0x0000ff00) | ||
| 510 | |||
| 511 | /* | ||
| 512 | * RXCSR2: RX Ring base address register. | ||
| 513 | */ | ||
| 514 | #define RXCSR2 0x0088 | ||
| 515 | #define RXCSR2_RX_RING_REGISTER FIELD32(0xffffffff) | ||
| 516 | |||
| 517 | /* | ||
| 518 | * RXCSR3: BBP ID register for Rx operation. | ||
| 519 | * BBP_ID#: BBP register # id. | ||
| 520 | * BBP_ID#_VALID: BBP register # id is valid or not. | ||
| 521 | */ | ||
| 522 | #define RXCSR3 0x0090 | ||
| 523 | #define RXCSR3_BBP_ID0 FIELD32(0x0000007f) | ||
| 524 | #define RXCSR3_BBP_ID0_VALID FIELD32(0x00000080) | ||
| 525 | #define RXCSR3_BBP_ID1 FIELD32(0x00007f00) | ||
| 526 | #define RXCSR3_BBP_ID1_VALID FIELD32(0x00008000) | ||
| 527 | #define RXCSR3_BBP_ID2 FIELD32(0x007f0000) | ||
| 528 | #define RXCSR3_BBP_ID2_VALID FIELD32(0x00800000) | ||
| 529 | #define RXCSR3_BBP_ID3 FIELD32(0x7f000000) | ||
| 530 | #define RXCSR3_BBP_ID3_VALID FIELD32(0x80000000) | ||
| 531 | |||
| 532 | /* | ||
| 533 | * ARCSR1: Auto Responder PLCP config register 1. | ||
| 534 | * AR_BBP_DATA#: Auto responder BBP register # data. | ||
| 535 | * AR_BBP_ID#: Auto responder BBP register # Id. | ||
| 536 | */ | ||
| 537 | #define ARCSR1 0x009c | ||
| 538 | #define ARCSR1_AR_BBP_DATA2 FIELD32(0x000000ff) | ||
| 539 | #define ARCSR1_AR_BBP_ID2 FIELD32(0x0000ff00) | ||
| 540 | #define ARCSR1_AR_BBP_DATA3 FIELD32(0x00ff0000) | ||
| 541 | #define ARCSR1_AR_BBP_ID3 FIELD32(0xff000000) | ||
| 542 | |||
| 543 | /* | ||
| 544 | * Miscellaneous Registers. | ||
| 545 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 546 | |||
| 547 | */ | ||
| 548 | |||
| 549 | /* | ||
| 550 | * PCICSR: PCI control register. | ||
| 551 | * BIG_ENDIAN: 1: big endian, 0: little endian. | ||
| 552 | * RX_TRESHOLD: Rx threshold in dw to start pci access | ||
| 553 | * 0: 16dw (default), 1: 8dw, 2: 4dw, 3: 32dw. | ||
| 554 | * TX_TRESHOLD: Tx threshold in dw to start pci access | ||
| 555 | * 0: 0dw (default), 1: 1dw, 2: 4dw, 3: forward. | ||
| 556 | * BURST_LENTH: Pci burst length 0: 4dw (default, 1: 8dw, 2: 16dw, 3:32dw. | ||
| 557 | * ENABLE_CLK: Enable clk_run, pci clock can't going down to non-operational. | ||
| 558 | * READ_MULTIPLE: Enable memory read multiple. | ||
| 559 | * WRITE_INVALID: Enable memory write & invalid. | ||
| 560 | */ | ||
| 561 | #define PCICSR 0x008c | ||
| 562 | #define PCICSR_BIG_ENDIAN FIELD32(0x00000001) | ||
| 563 | #define PCICSR_RX_TRESHOLD FIELD32(0x00000006) | ||
| 564 | #define PCICSR_TX_TRESHOLD FIELD32(0x00000018) | ||
| 565 | #define PCICSR_BURST_LENTH FIELD32(0x00000060) | ||
| 566 | #define PCICSR_ENABLE_CLK FIELD32(0x00000080) | ||
| 567 | #define PCICSR_READ_MULTIPLE FIELD32(0x00000100) | ||
| 568 | #define PCICSR_WRITE_INVALID FIELD32(0x00000200) | ||
| 569 | |||
| 570 | /* | ||
| 571 | * CNT0: FCS error count. | ||
| 572 | * FCS_ERROR: FCS error count, cleared when read. | ||
| 573 | */ | ||
| 574 | #define CNT0 0x00a0 | ||
| 575 | #define CNT0_FCS_ERROR FIELD32(0x0000ffff) | ||
| 576 | |||
| 577 | /* | ||
| 578 | * Statistic Register. | ||
| 579 | * CNT1: PLCP error count. | ||
| 580 | * CNT2: Long error count. | ||
| 581 | */ | ||
| 582 | #define TIMECSR2 0x00a8 | ||
| 583 | #define CNT1 0x00ac | ||
| 584 | #define CNT2 0x00b0 | ||
| 585 | #define TIMECSR3 0x00b4 | ||
| 586 | |||
| 587 | /* | ||
| 588 | * CNT3: CCA false alarm count. | ||
| 589 | */ | ||
| 590 | #define CNT3 0x00b8 | ||
| 591 | #define CNT3_FALSE_CCA FIELD32(0x0000ffff) | ||
| 592 | |||
| 593 | /* | ||
| 594 | * Statistic Register. | ||
| 595 | * CNT4: Rx FIFO overflow count. | ||
| 596 | * CNT5: Tx FIFO underrun count. | ||
| 597 | */ | ||
| 598 | #define CNT4 0x00bc | ||
| 599 | #define CNT5 0x00c0 | ||
| 600 | |||
| 601 | /* | ||
| 602 | * Baseband Control Register. | ||
| 603 | */ | ||
| 604 | |||
| 605 | /* | ||
| 606 | * PWRCSR0: Power mode configuration register. | ||
| 607 | */ | ||
| 608 | #define PWRCSR0 0x00c4 | ||
| 609 | |||
| 610 | /* | ||
| 611 | * Power state transition time registers. | ||
| 612 | */ | ||
| 613 | #define PSCSR0 0x00c8 | ||
| 614 | #define PSCSR1 0x00cc | ||
| 615 | #define PSCSR2 0x00d0 | ||
| 616 | #define PSCSR3 0x00d4 | ||
| 617 | |||
| 618 | /* | ||
| 619 | * PWRCSR1: Manual power control / status register. | ||
| 620 | * Allowed state: 0 deep_sleep, 1: sleep, 2: standby, 3: awake. | ||
| 621 | * SET_STATE: Set state. Write 1 to trigger, self cleared. | ||
| 622 | * BBP_DESIRE_STATE: BBP desired state. | ||
| 623 | * RF_DESIRE_STATE: RF desired state. | ||
| 624 | * BBP_CURR_STATE: BBP current state. | ||
| 625 | * RF_CURR_STATE: RF current state. | ||
| 626 | * PUT_TO_SLEEP: Put to sleep. Write 1 to trigger, self cleared. | ||
| 627 | */ | ||
| 628 | #define PWRCSR1 0x00d8 | ||
| 629 | #define PWRCSR1_SET_STATE FIELD32(0x00000001) | ||
| 630 | #define PWRCSR1_BBP_DESIRE_STATE FIELD32(0x00000006) | ||
| 631 | #define PWRCSR1_RF_DESIRE_STATE FIELD32(0x00000018) | ||
| 632 | #define PWRCSR1_BBP_CURR_STATE FIELD32(0x00000060) | ||
| 633 | #define PWRCSR1_RF_CURR_STATE FIELD32(0x00000180) | ||
| 634 | #define PWRCSR1_PUT_TO_SLEEP FIELD32(0x00000200) | ||
| 635 | |||
| 636 | /* | ||
| 637 | * TIMECSR: Timer control register. | ||
| 638 | * US_COUNT: 1 us timer count in units of clock cycles. | ||
| 639 | * US_64_COUNT: 64 us timer count in units of 1 us timer. | ||
| 640 | * BEACON_EXPECT: Beacon expect window. | ||
| 641 | */ | ||
| 642 | #define TIMECSR 0x00dc | ||
| 643 | #define TIMECSR_US_COUNT FIELD32(0x000000ff) | ||
| 644 | #define TIMECSR_US_64_COUNT FIELD32(0x0000ff00) | ||
| 645 | #define TIMECSR_BEACON_EXPECT FIELD32(0x00070000) | ||
| 646 | |||
| 647 | /* | ||
| 648 | * MACCSR0: MAC configuration register 0. | ||
| 649 | */ | ||
| 650 | #define MACCSR0 0x00e0 | ||
| 651 | |||
| 652 | /* | ||
| 653 | * MACCSR1: MAC configuration register 1. | ||
| 654 | * KICK_RX: Kick one-shot rx in one-shot rx mode. | ||
| 655 | * ONESHOT_RXMODE: Enable one-shot rx mode for debugging. | ||
| 656 | * BBPRX_RESET_MODE: Ralink bbp rx reset mode. | ||
| 657 | * AUTO_TXBBP: Auto tx logic access bbp control register. | ||
| 658 | * AUTO_RXBBP: Auto rx logic access bbp control register. | ||
| 659 | * LOOPBACK: Loopback mode. 0: normal, 1: internal, 2: external, 3:rsvd. | ||
| 660 | * INTERSIL_IF: Intersil if calibration pin. | ||
| 661 | */ | ||
| 662 | #define MACCSR1 0x00e4 | ||
| 663 | #define MACCSR1_KICK_RX FIELD32(0x00000001) | ||
| 664 | #define MACCSR1_ONESHOT_RXMODE FIELD32(0x00000002) | ||
| 665 | #define MACCSR1_BBPRX_RESET_MODE FIELD32(0x00000004) | ||
| 666 | #define MACCSR1_AUTO_TXBBP FIELD32(0x00000008) | ||
| 667 | #define MACCSR1_AUTO_RXBBP FIELD32(0x00000010) | ||
| 668 | #define MACCSR1_LOOPBACK FIELD32(0x00000060) | ||
| 669 | #define MACCSR1_INTERSIL_IF FIELD32(0x00000080) | ||
| 670 | |||
| 671 | /* | ||
| 672 | * RALINKCSR: Ralink Rx auto-reset BBCR. | ||
| 673 | * AR_BBP_DATA#: Auto reset BBP register # data. | ||
| 674 | * AR_BBP_ID#: Auto reset BBP register # id. | ||
| 675 | */ | ||
| 676 | #define RALINKCSR 0x00e8 | ||
| 677 | #define RALINKCSR_AR_BBP_DATA0 FIELD32(0x000000ff) | ||
| 678 | #define RALINKCSR_AR_BBP_ID0 FIELD32(0x00007f00) | ||
| 679 | #define RALINKCSR_AR_BBP_VALID0 FIELD32(0x00008000) | ||
| 680 | #define RALINKCSR_AR_BBP_DATA1 FIELD32(0x00ff0000) | ||
| 681 | #define RALINKCSR_AR_BBP_ID1 FIELD32(0x7f000000) | ||
| 682 | #define RALINKCSR_AR_BBP_VALID1 FIELD32(0x80000000) | ||
| 683 | |||
| 684 | /* | ||
| 685 | * BCNCSR: Beacon interval control register. | ||
| 686 | * CHANGE: Write one to change beacon interval. | ||
| 687 | * DELTATIME: The delta time value. | ||
| 688 | * NUM_BEACON: Number of beacon according to mode. | ||
| 689 | * MODE: Please refer to asic specs. | ||
| 690 | * PLUS: Plus or minus delta time value. | ||
| 691 | */ | ||
| 692 | #define BCNCSR 0x00ec | ||
| 693 | #define BCNCSR_CHANGE FIELD32(0x00000001) | ||
| 694 | #define BCNCSR_DELTATIME FIELD32(0x0000001e) | ||
| 695 | #define BCNCSR_NUM_BEACON FIELD32(0x00001fe0) | ||
| 696 | #define BCNCSR_MODE FIELD32(0x00006000) | ||
| 697 | #define BCNCSR_PLUS FIELD32(0x00008000) | ||
| 698 | |||
| 699 | /* | ||
| 700 | * BBP / RF / IF Control Register. | ||
| 701 | */ | ||
| 702 | |||
| 703 | /* | ||
| 704 | * BBPCSR: BBP serial control register. | ||
| 705 | * VALUE: Register value to program into BBP. | ||
| 706 | * REGNUM: Selected BBP register. | ||
| 707 | * BUSY: 1: asic is busy execute BBP programming. | ||
| 708 | * WRITE_CONTROL: 1: write BBP, 0: read BBP. | ||
| 709 | */ | ||
| 710 | #define BBPCSR 0x00f0 | ||
| 711 | #define BBPCSR_VALUE FIELD32(0x000000ff) | ||
| 712 | #define BBPCSR_REGNUM FIELD32(0x00007f00) | ||
| 713 | #define BBPCSR_BUSY FIELD32(0x00008000) | ||
| 714 | #define BBPCSR_WRITE_CONTROL FIELD32(0x00010000) | ||
| 715 | |||
| 716 | /* | ||
| 717 | * RFCSR: RF serial control register. | ||
| 718 | * VALUE: Register value + id to program into rf/if. | ||
| 719 | * NUMBER_OF_BITS: Number of bits used in value (i:20, rfmd:22). | ||
| 720 | * IF_SELECT: Chip to program: 0: rf, 1: if. | ||
| 721 | * PLL_LD: Rf pll_ld status. | ||
| 722 | * BUSY: 1: asic is busy execute rf programming. | ||
| 723 | */ | ||
| 724 | #define RFCSR 0x00f4 | ||
| 725 | #define RFCSR_VALUE FIELD32(0x00ffffff) | ||
| 726 | #define RFCSR_NUMBER_OF_BITS FIELD32(0x1f000000) | ||
| 727 | #define RFCSR_IF_SELECT FIELD32(0x20000000) | ||
| 728 | #define RFCSR_PLL_LD FIELD32(0x40000000) | ||
| 729 | #define RFCSR_BUSY FIELD32(0x80000000) | ||
| 730 | |||
| 731 | /* | ||
| 732 | * LEDCSR: LED control register. | ||
| 733 | * ON_PERIOD: On period, default 70ms. | ||
| 734 | * OFF_PERIOD: Off period, default 30ms. | ||
| 735 | * LINK: 0: linkoff, 1: linkup. | ||
| 736 | * ACTIVITY: 0: idle, 1: active. | ||
| 737 | * LINK_POLARITY: 0: active low, 1: active high. | ||
| 738 | * ACTIVITY_POLARITY: 0: active low, 1: active high. | ||
| 739 | * LED_DEFAULT: LED state for "enable" 0: ON, 1: OFF. | ||
| 740 | */ | ||
| 741 | #define LEDCSR 0x00f8 | ||
| 742 | #define LEDCSR_ON_PERIOD FIELD32(0x000000ff) | ||
| 743 | #define LEDCSR_OFF_PERIOD FIELD32(0x0000ff00) | ||
| 744 | #define LEDCSR_LINK FIELD32(0x00010000) | ||
| 745 | #define LEDCSR_ACTIVITY FIELD32(0x00020000) | ||
| 746 | #define LEDCSR_LINK_POLARITY FIELD32(0x00040000) | ||
| 747 | #define LEDCSR_ACTIVITY_POLARITY FIELD32(0x00080000) | ||
| 748 | #define LEDCSR_LED_DEFAULT FIELD32(0x00100000) | ||
| 749 | |||
| 750 | /* | ||
| 751 | * AES control register. | ||
| 752 | */ | ||
| 753 | #define SECCSR3 0x00fc | ||
| 754 | |||
| 755 | /* | ||
| 756 | * ASIC pointer information. | ||
| 757 | * RXPTR: Current RX ring address. | ||
| 758 | * TXPTR: Current Tx ring address. | ||
| 759 | * PRIPTR: Current Priority ring address. | ||
| 760 | * ATIMPTR: Current ATIM ring address. | ||
| 761 | */ | ||
| 762 | #define RXPTR 0x0100 | ||
| 763 | #define TXPTR 0x0104 | ||
| 764 | #define PRIPTR 0x0108 | ||
| 765 | #define ATIMPTR 0x010c | ||
| 766 | |||
| 767 | /* | ||
| 768 | * TXACKCSR0: TX ACK timeout. | ||
| 769 | */ | ||
| 770 | #define TXACKCSR0 0x0110 | ||
| 771 | |||
| 772 | /* | ||
| 773 | * ACK timeout count registers. | ||
| 774 | * ACKCNT0: TX ACK timeout count. | ||
| 775 | * ACKCNT1: RX ACK timeout count. | ||
| 776 | */ | ||
| 777 | #define ACKCNT0 0x0114 | ||
| 778 | #define ACKCNT1 0x0118 | ||
| 779 | |||
| 780 | /* | ||
| 781 | * GPIO and others. | ||
| 782 | */ | ||
| 783 | |||
| 784 | /* | ||
| 785 | * GPIOCSR: GPIO control register. | ||
| 786 | */ | ||
| 787 | #define GPIOCSR 0x0120 | ||
| 788 | #define GPIOCSR_BIT0 FIELD32(0x00000001) | ||
| 789 | #define GPIOCSR_BIT1 FIELD32(0x00000002) | ||
| 790 | #define GPIOCSR_BIT2 FIELD32(0x00000004) | ||
| 791 | #define GPIOCSR_BIT3 FIELD32(0x00000008) | ||
| 792 | #define GPIOCSR_BIT4 FIELD32(0x00000010) | ||
| 793 | #define GPIOCSR_BIT5 FIELD32(0x00000020) | ||
| 794 | #define GPIOCSR_BIT6 FIELD32(0x00000040) | ||
| 795 | #define GPIOCSR_BIT7 FIELD32(0x00000080) | ||
| 796 | #define GPIOCSR_DIR0 FIELD32(0x00000100) | ||
| 797 | #define GPIOCSR_DIR1 FIELD32(0x00000200) | ||
| 798 | #define GPIOCSR_DIR2 FIELD32(0x00000400) | ||
| 799 | #define GPIOCSR_DIR3 FIELD32(0x00000800) | ||
| 800 | #define GPIOCSR_DIR4 FIELD32(0x00001000) | ||
| 801 | #define GPIOCSR_DIR5 FIELD32(0x00002000) | ||
| 802 | #define GPIOCSR_DIR6 FIELD32(0x00004000) | ||
| 803 | #define GPIOCSR_DIR7 FIELD32(0x00008000) | ||
| 804 | |||
| 805 | /* | ||
| 806 | * FIFO pointer registers. | ||
| 807 | * FIFOCSR0: TX FIFO pointer. | ||
| 808 | * FIFOCSR1: RX FIFO pointer. | ||
| 809 | */ | ||
| 810 | #define FIFOCSR0 0x0128 | ||
| 811 | #define FIFOCSR1 0x012c | ||
| 812 | |||
| 813 | /* | ||
| 814 | * BCNCSR1: Tx BEACON offset time control register. | ||
| 815 | * PRELOAD: Beacon timer offset in units of usec. | ||
| 816 | * BEACON_CWMIN: 2^CwMin. | ||
| 817 | */ | ||
| 818 | #define BCNCSR1 0x0130 | ||
| 819 | #define BCNCSR1_PRELOAD FIELD32(0x0000ffff) | ||
| 820 | #define BCNCSR1_BEACON_CWMIN FIELD32(0x000f0000) | ||
| 821 | |||
| 822 | /* | ||
| 823 | * MACCSR2: TX_PE to RX_PE turn-around time control register | ||
| 824 | * DELAY: RX_PE low width, in units of pci clock cycle. | ||
| 825 | */ | ||
| 826 | #define MACCSR2 0x0134 | ||
| 827 | #define MACCSR2_DELAY FIELD32(0x000000ff) | ||
| 828 | |||
| 829 | /* | ||
| 830 | * TESTCSR: TEST mode selection register. | ||
| 831 | */ | ||
| 832 | #define TESTCSR 0x0138 | ||
| 833 | |||
| 834 | /* | ||
| 835 | * ARCSR2: 1 Mbps ACK/CTS PLCP. | ||
| 836 | */ | ||
| 837 | #define ARCSR2 0x013c | ||
| 838 | #define ARCSR2_SIGNAL FIELD32(0x000000ff) | ||
| 839 | #define ARCSR2_SERVICE FIELD32(0x0000ff00) | ||
| 840 | #define ARCSR2_LENGTH FIELD32(0xffff0000) | ||
| 841 | |||
| 842 | /* | ||
| 843 | * ARCSR3: 2 Mbps ACK/CTS PLCP. | ||
| 844 | */ | ||
| 845 | #define ARCSR3 0x0140 | ||
| 846 | #define ARCSR3_SIGNAL FIELD32(0x000000ff) | ||
| 847 | #define ARCSR3_SERVICE FIELD32(0x0000ff00) | ||
| 848 | #define ARCSR3_LENGTH FIELD32(0xffff0000) | ||
| 849 | |||
| 850 | /* | ||
| 851 | * ARCSR4: 5.5 Mbps ACK/CTS PLCP. | ||
| 852 | */ | ||
| 853 | #define ARCSR4 0x0144 | ||
| 854 | #define ARCSR4_SIGNAL FIELD32(0x000000ff) | ||
| 855 | #define ARCSR4_SERVICE FIELD32(0x0000ff00) | ||
| 856 | #define ARCSR4_LENGTH FIELD32(0xffff0000) | ||
| 857 | |||
| 858 | /* | ||
| 859 | * ARCSR5: 11 Mbps ACK/CTS PLCP. | ||
| 860 | */ | ||
| 861 | #define ARCSR5 0x0148 | ||
| 862 | #define ARCSR5_SIGNAL FIELD32(0x000000ff) | ||
| 863 | #define ARCSR5_SERVICE FIELD32(0x0000ff00) | ||
| 864 | #define ARCSR5_LENGTH FIELD32(0xffff0000) | ||
| 865 | |||
| 866 | /* | ||
| 867 | * ARTCSR0: CCK ACK/CTS payload consumed time for 1/2/5.5/11 mbps. | ||
| 868 | */ | ||
| 869 | #define ARTCSR0 0x014c | ||
| 870 | #define ARTCSR0_ACK_CTS_11MBS FIELD32(0x000000ff) | ||
| 871 | #define ARTCSR0_ACK_CTS_5_5MBS FIELD32(0x0000ff00) | ||
| 872 | #define ARTCSR0_ACK_CTS_2MBS FIELD32(0x00ff0000) | ||
| 873 | #define ARTCSR0_ACK_CTS_1MBS FIELD32(0xff000000) | ||
| 874 | |||
| 875 | |||
| 876 | /* | ||
| 877 | * ARTCSR1: OFDM ACK/CTS payload consumed time for 6/9/12/18 mbps. | ||
| 878 | */ | ||
| 879 | #define ARTCSR1 0x0150 | ||
| 880 | #define ARTCSR1_ACK_CTS_6MBS FIELD32(0x000000ff) | ||
| 881 | #define ARTCSR1_ACK_CTS_9MBS FIELD32(0x0000ff00) | ||
| 882 | #define ARTCSR1_ACK_CTS_12MBS FIELD32(0x00ff0000) | ||
| 883 | #define ARTCSR1_ACK_CTS_18MBS FIELD32(0xff000000) | ||
| 884 | |||
| 885 | /* | ||
| 886 | * ARTCSR2: OFDM ACK/CTS payload consumed time for 24/36/48/54 mbps. | ||
| 887 | */ | ||
| 888 | #define ARTCSR2 0x0154 | ||
| 889 | #define ARTCSR2_ACK_CTS_24MBS FIELD32(0x000000ff) | ||
| 890 | #define ARTCSR2_ACK_CTS_36MBS FIELD32(0x0000ff00) | ||
| 891 | #define ARTCSR2_ACK_CTS_48MBS FIELD32(0x00ff0000) | ||
| 892 | #define ARTCSR2_ACK_CTS_54MBS FIELD32(0xff000000) | ||
| 893 | |||
| 894 | /* | ||
| 895 | * SECCSR1_RT2509: WEP control register. | ||
| 896 | * KICK_ENCRYPT: Kick encryption engine, self-clear. | ||
| 897 | * ONE_SHOT: 0: ring mode, 1: One shot only mode. | ||
| 898 | * DESC_ADDRESS: Descriptor physical address of frame. | ||
| 899 | */ | ||
| 900 | #define SECCSR1 0x0158 | ||
| 901 | #define SECCSR1_KICK_ENCRYPT FIELD32(0x00000001) | ||
| 902 | #define SECCSR1_ONE_SHOT FIELD32(0x00000002) | ||
| 903 | #define SECCSR1_DESC_ADDRESS FIELD32(0xfffffffc) | ||
| 904 | |||
| 905 | /* | ||
| 906 | * BBPCSR1: BBP TX configuration. | ||
| 907 | */ | ||
| 908 | #define BBPCSR1 0x015c | ||
| 909 | #define BBPCSR1_CCK FIELD32(0x00000003) | ||
| 910 | #define BBPCSR1_CCK_FLIP FIELD32(0x00000004) | ||
| 911 | #define BBPCSR1_OFDM FIELD32(0x00030000) | ||
| 912 | #define BBPCSR1_OFDM_FLIP FIELD32(0x00040000) | ||
| 913 | |||
| 914 | /* | ||
| 915 | * Dual band configuration registers. | ||
| 916 | * DBANDCSR0: Dual band configuration register 0. | ||
| 917 | * DBANDCSR1: Dual band configuration register 1. | ||
| 918 | */ | ||
| 919 | #define DBANDCSR0 0x0160 | ||
| 920 | #define DBANDCSR1 0x0164 | ||
| 921 | |||
| 922 | /* | ||
| 923 | * BBPPCSR: BBP Pin control register. | ||
| 924 | */ | ||
| 925 | #define BBPPCSR 0x0168 | ||
| 926 | |||
| 927 | /* | ||
| 928 | * MAC special debug mode selection registers. | ||
| 929 | * DBGSEL0: MAC special debug mode selection register 0. | ||
| 930 | * DBGSEL1: MAC special debug mode selection register 1. | ||
| 931 | */ | ||
| 932 | #define DBGSEL0 0x016c | ||
| 933 | #define DBGSEL1 0x0170 | ||
| 934 | |||
| 935 | /* | ||
| 936 | * BISTCSR: BBP BIST register. | ||
| 937 | */ | ||
| 938 | #define BISTCSR 0x0174 | ||
| 939 | |||
| 940 | /* | ||
| 941 | * Multicast filter registers. | ||
| 942 | * MCAST0: Multicast filter register 0. | ||
| 943 | * MCAST1: Multicast filter register 1. | ||
| 944 | */ | ||
| 945 | #define MCAST0 0x0178 | ||
| 946 | #define MCAST1 0x017c | ||
| 947 | |||
| 948 | /* | ||
| 949 | * UART registers. | ||
| 950 | * UARTCSR0: UART1 TX register. | ||
| 951 | * UARTCSR1: UART1 RX register. | ||
| 952 | * UARTCSR3: UART1 frame control register. | ||
| 953 | * UARTCSR4: UART1 buffer control register. | ||
| 954 | * UART2CSR0: UART2 TX register. | ||
| 955 | * UART2CSR1: UART2 RX register. | ||
| 956 | * UART2CSR3: UART2 frame control register. | ||
| 957 | * UART2CSR4: UART2 buffer control register. | ||
| 958 | */ | ||
| 959 | #define UARTCSR0 0x0180 | ||
| 960 | #define UARTCSR1 0x0184 | ||
| 961 | #define UARTCSR3 0x0188 | ||
| 962 | #define UARTCSR4 0x018c | ||
| 963 | #define UART2CSR0 0x0190 | ||
| 964 | #define UART2CSR1 0x0194 | ||
| 965 | #define UART2CSR3 0x0198 | ||
| 966 | #define UART2CSR4 0x019c | ||
| 967 | |||
| 968 | /* | ||
| 969 | * BBP registers. | ||
| 970 | * The wordsize of the BBP is 8 bits. | ||
| 971 | */ | ||
| 972 | |||
| 973 | /* | ||
| 974 | * R2: TX antenna control | ||
| 975 | */ | ||
| 976 | #define BBP_R2_TX_ANTENNA FIELD8(0x03) | ||
| 977 | #define BBP_R2_TX_IQ_FLIP FIELD8(0x04) | ||
| 978 | |||
| 979 | /* | ||
| 980 | * R14: RX antenna control | ||
| 981 | */ | ||
| 982 | #define BBP_R14_RX_ANTENNA FIELD8(0x03) | ||
| 983 | #define BBP_R14_RX_IQ_FLIP FIELD8(0x04) | ||
| 984 | |||
| 985 | /* | ||
| 986 | * BBP_R70 | ||
| 987 | */ | ||
| 988 | #define BBP_R70_JAPAN_FILTER FIELD8(0x08) | ||
| 989 | |||
| 990 | /* | ||
| 991 | * RF registers | ||
| 992 | */ | ||
| 993 | |||
| 994 | /* | ||
| 995 | * RF 1 | ||
| 996 | */ | ||
| 997 | #define RF1_TUNER FIELD32(0x00020000) | ||
| 998 | |||
| 999 | /* | ||
| 1000 | * RF 3 | ||
| 1001 | */ | ||
| 1002 | #define RF3_TUNER FIELD32(0x00000100) | ||
| 1003 | #define RF3_TXPOWER FIELD32(0x00003e00) | ||
| 1004 | |||
| 1005 | /* | ||
| 1006 | * EEPROM content. | ||
| 1007 | * The wordsize of the EEPROM is 16 bits. | ||
| 1008 | */ | ||
| 1009 | |||
| 1010 | /* | ||
| 1011 | * HW MAC address. | ||
| 1012 | */ | ||
| 1013 | #define EEPROM_MAC_ADDR_0 0x0002 | ||
| 1014 | #define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff) | ||
| 1015 | #define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00) | ||
| 1016 | #define EEPROM_MAC_ADDR1 0x0003 | ||
| 1017 | #define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff) | ||
| 1018 | #define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00) | ||
| 1019 | #define EEPROM_MAC_ADDR_2 0x0004 | ||
| 1020 | #define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff) | ||
| 1021 | #define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) | ||
| 1022 | |||
| 1023 | /* | ||
| 1024 | * EEPROM antenna. | ||
| 1025 | * ANTENNA_NUM: Number of antenna's. | ||
| 1026 | * TX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B. | ||
| 1027 | * RX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B. | ||
| 1028 | * LED_MODE: 0: default, 1: TX/RX activity,2: Single (ignore link), 3: rsvd. | ||
| 1029 | * DYN_TXAGC: Dynamic TX AGC control. | ||
| 1030 | * HARDWARE_RADIO: 1: Hardware controlled radio. Read GPIO0. | ||
| 1031 | * RF_TYPE: Rf_type of this adapter. | ||
| 1032 | */ | ||
| 1033 | #define EEPROM_ANTENNA 0x10 | ||
| 1034 | #define EEPROM_ANTENNA_NUM FIELD16(0x0003) | ||
| 1035 | #define EEPROM_ANTENNA_TX_DEFAULT FIELD16(0x000c) | ||
| 1036 | #define EEPROM_ANTENNA_RX_DEFAULT FIELD16(0x0030) | ||
| 1037 | #define EEPROM_ANTENNA_LED_MODE FIELD16(0x01c0) | ||
| 1038 | #define EEPROM_ANTENNA_DYN_TXAGC FIELD16(0x0200) | ||
| 1039 | #define EEPROM_ANTENNA_HARDWARE_RADIO FIELD16(0x0400) | ||
| 1040 | #define EEPROM_ANTENNA_RF_TYPE FIELD16(0xf800) | ||
| 1041 | |||
| 1042 | /* | ||
| 1043 | * EEPROM NIC config. | ||
| 1044 | * CARDBUS_ACCEL: 0: enable, 1: disable. | ||
| 1045 | * DYN_BBP_TUNE: 0: enable, 1: disable. | ||
| 1046 | * CCK_TX_POWER: CCK TX power compensation. | ||
| 1047 | */ | ||
| 1048 | #define EEPROM_NIC 0x11 | ||
| 1049 | #define EEPROM_NIC_CARDBUS_ACCEL FIELD16(0x0001) | ||
| 1050 | #define EEPROM_NIC_DYN_BBP_TUNE FIELD16(0x0002) | ||
| 1051 | #define EEPROM_NIC_CCK_TX_POWER FIELD16(0x000c) | ||
| 1052 | |||
| 1053 | /* | ||
| 1054 | * EEPROM geography. | ||
| 1055 | * GEO: Default geography setting for device. | ||
| 1056 | */ | ||
| 1057 | #define EEPROM_GEOGRAPHY 0x12 | ||
| 1058 | #define EEPROM_GEOGRAPHY_GEO FIELD16(0x0f00) | ||
| 1059 | |||
| 1060 | /* | ||
| 1061 | * EEPROM BBP. | ||
| 1062 | */ | ||
| 1063 | #define EEPROM_BBP_START 0x13 | ||
| 1064 | #define EEPROM_BBP_SIZE 16 | ||
| 1065 | #define EEPROM_BBP_VALUE FIELD16(0x00ff) | ||
| 1066 | #define EEPROM_BBP_REG_ID FIELD16(0xff00) | ||
| 1067 | |||
| 1068 | /* | ||
| 1069 | * EEPROM TXPOWER | ||
| 1070 | */ | ||
| 1071 | #define EEPROM_TXPOWER_START 0x23 | ||
| 1072 | #define EEPROM_TXPOWER_SIZE 7 | ||
| 1073 | #define EEPROM_TXPOWER_1 FIELD16(0x00ff) | ||
| 1074 | #define EEPROM_TXPOWER_2 FIELD16(0xff00) | ||
| 1075 | |||
| 1076 | /* | ||
| 1077 | * RSSI <-> dBm offset calibration | ||
| 1078 | */ | ||
| 1079 | #define EEPROM_CALIBRATE_OFFSET 0x3e | ||
| 1080 | #define EEPROM_CALIBRATE_OFFSET_RSSI FIELD16(0x00ff) | ||
| 1081 | |||
| 1082 | /* | ||
| 1083 | * DMA descriptor defines. | ||
| 1084 | */ | ||
| 1085 | #define TXD_DESC_SIZE ( 11 * sizeof(struct data_desc) ) | ||
| 1086 | #define RXD_DESC_SIZE ( 11 * sizeof(struct data_desc) ) | ||
| 1087 | |||
| 1088 | /* | ||
| 1089 | * TX descriptor format for TX, PRIO, ATIM and Beacon Ring. | ||
| 1090 | */ | ||
| 1091 | |||
| 1092 | /* | ||
| 1093 | * Word0 | ||
| 1094 | */ | ||
| 1095 | #define TXD_W0_OWNER_NIC FIELD32(0x00000001) | ||
| 1096 | #define TXD_W0_VALID FIELD32(0x00000002) | ||
| 1097 | #define TXD_W0_RESULT FIELD32(0x0000001c) | ||
| 1098 | #define TXD_W0_RETRY_COUNT FIELD32(0x000000e0) | ||
| 1099 | #define TXD_W0_MORE_FRAG FIELD32(0x00000100) | ||
| 1100 | #define TXD_W0_ACK FIELD32(0x00000200) | ||
| 1101 | #define TXD_W0_TIMESTAMP FIELD32(0x00000400) | ||
| 1102 | #define TXD_W0_OFDM FIELD32(0x00000800) | ||
| 1103 | #define TXD_W0_CIPHER_OWNER FIELD32(0x00001000) | ||
| 1104 | #define TXD_W0_IFS FIELD32(0x00006000) | ||
| 1105 | #define TXD_W0_RETRY_MODE FIELD32(0x00008000) | ||
| 1106 | #define TXD_W0_DATABYTE_COUNT FIELD32(0x0fff0000) | ||
| 1107 | #define TXD_W0_CIPHER_ALG FIELD32(0xe0000000) | ||
| 1108 | |||
| 1109 | /* | ||
| 1110 | * Word1 | ||
| 1111 | */ | ||
| 1112 | #define TXD_W1_BUFFER_ADDRESS FIELD32(0xffffffff) | ||
| 1113 | |||
| 1114 | /* | ||
| 1115 | * Word2 | ||
| 1116 | */ | ||
| 1117 | #define TXD_W2_IV_OFFSET FIELD32(0x0000003f) | ||
| 1118 | #define TXD_W2_AIFS FIELD32(0x000000c0) | ||
| 1119 | #define TXD_W2_CWMIN FIELD32(0x00000f00) | ||
| 1120 | #define TXD_W2_CWMAX FIELD32(0x0000f000) | ||
| 1121 | |||
| 1122 | /* | ||
| 1123 | * Word3: PLCP information | ||
| 1124 | */ | ||
| 1125 | #define TXD_W3_PLCP_SIGNAL FIELD32(0x000000ff) | ||
| 1126 | #define TXD_W3_PLCP_SERVICE FIELD32(0x0000ff00) | ||
| 1127 | #define TXD_W3_PLCP_LENGTH_LOW FIELD32(0x00ff0000) | ||
| 1128 | #define TXD_W3_PLCP_LENGTH_HIGH FIELD32(0xff000000) | ||
| 1129 | |||
| 1130 | /* | ||
| 1131 | * Word4 | ||
| 1132 | */ | ||
| 1133 | #define TXD_W4_IV FIELD32(0xffffffff) | ||
| 1134 | |||
| 1135 | /* | ||
| 1136 | * Word5 | ||
| 1137 | */ | ||
| 1138 | #define TXD_W5_EIV FIELD32(0xffffffff) | ||
| 1139 | |||
| 1140 | /* | ||
| 1141 | * Word6-9: Key | ||
| 1142 | */ | ||
| 1143 | #define TXD_W6_KEY FIELD32(0xffffffff) | ||
| 1144 | #define TXD_W7_KEY FIELD32(0xffffffff) | ||
| 1145 | #define TXD_W8_KEY FIELD32(0xffffffff) | ||
| 1146 | #define TXD_W9_KEY FIELD32(0xffffffff) | ||
| 1147 | |||
| 1148 | /* | ||
| 1149 | * Word10 | ||
| 1150 | */ | ||
| 1151 | #define TXD_W10_RTS FIELD32(0x00000001) | ||
| 1152 | #define TXD_W10_TX_RATE FIELD32(0x000000fe) | ||
| 1153 | |||
| 1154 | /* | ||
| 1155 | * RX descriptor format for RX Ring. | ||
| 1156 | */ | ||
| 1157 | |||
| 1158 | /* | ||
| 1159 | * Word0 | ||
| 1160 | */ | ||
| 1161 | #define RXD_W0_OWNER_NIC FIELD32(0x00000001) | ||
| 1162 | #define RXD_W0_UNICAST_TO_ME FIELD32(0x00000002) | ||
| 1163 | #define RXD_W0_MULTICAST FIELD32(0x00000004) | ||
| 1164 | #define RXD_W0_BROADCAST FIELD32(0x00000008) | ||
| 1165 | #define RXD_W0_MY_BSS FIELD32(0x00000010) | ||
| 1166 | #define RXD_W0_CRC_ERROR FIELD32(0x00000020) | ||
| 1167 | #define RXD_W0_OFDM FIELD32(0x00000040) | ||
| 1168 | #define RXD_W0_PHYSICAL_ERROR FIELD32(0x00000080) | ||
| 1169 | #define RXD_W0_CIPHER_OWNER FIELD32(0x00000100) | ||
| 1170 | #define RXD_W0_ICV_ERROR FIELD32(0x00000200) | ||
| 1171 | #define RXD_W0_IV_OFFSET FIELD32(0x0000fc00) | ||
| 1172 | #define RXD_W0_DATABYTE_COUNT FIELD32(0x0fff0000) | ||
| 1173 | #define RXD_W0_CIPHER_ALG FIELD32(0xe0000000) | ||
| 1174 | |||
| 1175 | /* | ||
| 1176 | * Word1 | ||
| 1177 | */ | ||
| 1178 | #define RXD_W1_BUFFER_ADDRESS FIELD32(0xffffffff) | ||
| 1179 | |||
| 1180 | /* | ||
| 1181 | * Word2 | ||
| 1182 | */ | ||
| 1183 | #define RXD_W2_SIGNAL FIELD32(0x000000ff) | ||
| 1184 | #define RXD_W2_RSSI FIELD32(0x0000ff00) | ||
| 1185 | #define RXD_W2_TA FIELD32(0xffff0000) | ||
| 1186 | |||
| 1187 | /* | ||
| 1188 | * Word3 | ||
| 1189 | */ | ||
| 1190 | #define RXD_W3_TA FIELD32(0xffffffff) | ||
| 1191 | |||
| 1192 | /* | ||
| 1193 | * Word4 | ||
| 1194 | */ | ||
| 1195 | #define RXD_W4_IV FIELD32(0xffffffff) | ||
| 1196 | |||
| 1197 | /* | ||
| 1198 | * Word5 | ||
| 1199 | */ | ||
| 1200 | #define RXD_W5_EIV FIELD32(0xffffffff) | ||
| 1201 | |||
| 1202 | /* | ||
| 1203 | * Word6-9: Key | ||
| 1204 | */ | ||
| 1205 | #define RXD_W6_KEY FIELD32(0xffffffff) | ||
| 1206 | #define RXD_W7_KEY FIELD32(0xffffffff) | ||
| 1207 | #define RXD_W8_KEY FIELD32(0xffffffff) | ||
| 1208 | #define RXD_W9_KEY FIELD32(0xffffffff) | ||
| 1209 | |||
| 1210 | /* | ||
| 1211 | * Word10 | ||
| 1212 | */ | ||
| 1213 | #define RXD_W10_DROP FIELD32(0x00000001) | ||
| 1214 | |||
| 1215 | /* | ||
| 1216 | * Macro's for converting txpower from EEPROM to dscape value | ||
| 1217 | * and from dscape value to register value. | ||
| 1218 | */ | ||
| 1219 | #define MIN_TXPOWER 0 | ||
| 1220 | #define MAX_TXPOWER 31 | ||
| 1221 | #define DEFAULT_TXPOWER 24 | ||
| 1222 | |||
| 1223 | #define TXPOWER_FROM_DEV(__txpower) \ | ||
| 1224 | ({ \ | ||
| 1225 | ((__txpower) > MAX_TXPOWER) ? \ | ||
| 1226 | DEFAULT_TXPOWER : (__txpower); \ | ||
| 1227 | }) | ||
| 1228 | |||
| 1229 | #define TXPOWER_TO_DEV(__txpower) \ | ||
| 1230 | ({ \ | ||
| 1231 | ((__txpower) <= MIN_TXPOWER) ? MIN_TXPOWER : \ | ||
| 1232 | (((__txpower) >= MAX_TXPOWER) ? MAX_TXPOWER : \ | ||
| 1233 | (__txpower)); \ | ||
| 1234 | }) | ||
| 1235 | |||
| 1236 | #endif /* RT2500PCI_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c new file mode 100644 index 00000000000..847bd7f58ee --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
| @@ -0,0 +1,1837 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2500usb | ||
| 23 | Abstract: rt2500usb device specific routines. | ||
| 24 | Supported chipsets: RT2570. | ||
| 25 | */ | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Set enviroment defines for rt2x00.h | ||
| 29 | */ | ||
| 30 | #define DRV_NAME "rt2500usb" | ||
| 31 | |||
| 32 | #include <linux/delay.h> | ||
| 33 | #include <linux/etherdevice.h> | ||
| 34 | #include <linux/init.h> | ||
| 35 | #include <linux/kernel.h> | ||
| 36 | #include <linux/module.h> | ||
| 37 | #include <linux/usb.h> | ||
| 38 | |||
| 39 | #include "rt2x00.h" | ||
| 40 | #include "rt2x00usb.h" | ||
| 41 | #include "rt2500usb.h" | ||
| 42 | |||
| 43 | /* | ||
| 44 | * Register access. | ||
| 45 | * All access to the CSR registers will go through the methods | ||
| 46 | * rt2500usb_register_read and rt2500usb_register_write. | ||
| 47 | * BBP and RF register require indirect register access, | ||
| 48 | * and use the CSR registers BBPCSR and RFCSR to achieve this. | ||
| 49 | * These indirect registers work with busy bits, | ||
| 50 | * and we will try maximal REGISTER_BUSY_COUNT times to access | ||
| 51 | * the register while taking a REGISTER_BUSY_DELAY us delay | ||
| 52 | * between each attampt. When the busy bit is still set at that time, | ||
| 53 | * the access attempt is considered to have failed, | ||
| 54 | * and we will print an error. | ||
| 55 | */ | ||
| 56 | static inline void rt2500usb_register_read(const struct rt2x00_dev *rt2x00dev, | ||
| 57 | const unsigned int offset, | ||
| 58 | u16 *value) | ||
| 59 | { | ||
| 60 | __le16 reg; | ||
| 61 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, | ||
| 62 | USB_VENDOR_REQUEST_IN, offset, | ||
| 63 | ®, sizeof(u16), REGISTER_TIMEOUT); | ||
| 64 | *value = le16_to_cpu(reg); | ||
| 65 | } | ||
| 66 | |||
| 67 | static inline void rt2500usb_register_multiread(const struct rt2x00_dev | ||
| 68 | *rt2x00dev, | ||
| 69 | const unsigned int offset, | ||
| 70 | void *value, const u16 length) | ||
| 71 | { | ||
| 72 | int timeout = REGISTER_TIMEOUT * (length / sizeof(u16)); | ||
| 73 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, | ||
| 74 | USB_VENDOR_REQUEST_IN, offset, | ||
| 75 | value, length, timeout); | ||
| 76 | } | ||
| 77 | |||
| 78 | static inline void rt2500usb_register_write(const struct rt2x00_dev *rt2x00dev, | ||
| 79 | const unsigned int offset, | ||
| 80 | u16 value) | ||
| 81 | { | ||
| 82 | __le16 reg = cpu_to_le16(value); | ||
| 83 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, | ||
| 84 | USB_VENDOR_REQUEST_OUT, offset, | ||
| 85 | ®, sizeof(u16), REGISTER_TIMEOUT); | ||
| 86 | } | ||
| 87 | |||
| 88 | static inline void rt2500usb_register_multiwrite(const struct rt2x00_dev | ||
| 89 | *rt2x00dev, | ||
| 90 | const unsigned int offset, | ||
| 91 | void *value, const u16 length) | ||
| 92 | { | ||
| 93 | int timeout = REGISTER_TIMEOUT * (length / sizeof(u16)); | ||
| 94 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, | ||
| 95 | USB_VENDOR_REQUEST_OUT, offset, | ||
| 96 | value, length, timeout); | ||
| 97 | } | ||
| 98 | |||
| 99 | static u16 rt2500usb_bbp_check(const struct rt2x00_dev *rt2x00dev) | ||
| 100 | { | ||
| 101 | u16 reg; | ||
| 102 | unsigned int i; | ||
| 103 | |||
| 104 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 105 | rt2500usb_register_read(rt2x00dev, PHY_CSR8, ®); | ||
| 106 | if (!rt2x00_get_field16(reg, PHY_CSR8_BUSY)) | ||
| 107 | break; | ||
| 108 | udelay(REGISTER_BUSY_DELAY); | ||
| 109 | } | ||
| 110 | |||
| 111 | return reg; | ||
| 112 | } | ||
| 113 | |||
| 114 | static void rt2500usb_bbp_write(const struct rt2x00_dev *rt2x00dev, | ||
| 115 | const unsigned int word, const u8 value) | ||
| 116 | { | ||
| 117 | u16 reg; | ||
| 118 | |||
| 119 | /* | ||
| 120 | * Wait until the BBP becomes ready. | ||
| 121 | */ | ||
| 122 | reg = rt2500usb_bbp_check(rt2x00dev); | ||
| 123 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { | ||
| 124 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); | ||
| 125 | return; | ||
| 126 | } | ||
| 127 | |||
| 128 | /* | ||
| 129 | * Write the data into the BBP. | ||
| 130 | */ | ||
| 131 | reg = 0; | ||
| 132 | rt2x00_set_field16(®, PHY_CSR7_DATA, value); | ||
| 133 | rt2x00_set_field16(®, PHY_CSR7_REG_ID, word); | ||
| 134 | rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 0); | ||
| 135 | |||
| 136 | rt2500usb_register_write(rt2x00dev, PHY_CSR7, reg); | ||
| 137 | } | ||
| 138 | |||
| 139 | static void rt2500usb_bbp_read(const struct rt2x00_dev *rt2x00dev, | ||
| 140 | const unsigned int word, u8 *value) | ||
| 141 | { | ||
| 142 | u16 reg; | ||
| 143 | |||
| 144 | /* | ||
| 145 | * Wait until the BBP becomes ready. | ||
| 146 | */ | ||
| 147 | reg = rt2500usb_bbp_check(rt2x00dev); | ||
| 148 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { | ||
| 149 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); | ||
| 150 | return; | ||
| 151 | } | ||
| 152 | |||
| 153 | /* | ||
| 154 | * Write the request into the BBP. | ||
| 155 | */ | ||
| 156 | reg = 0; | ||
| 157 | rt2x00_set_field16(®, PHY_CSR7_REG_ID, word); | ||
| 158 | rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 1); | ||
| 159 | |||
| 160 | rt2500usb_register_write(rt2x00dev, PHY_CSR7, reg); | ||
| 161 | |||
| 162 | /* | ||
| 163 | * Wait until the BBP becomes ready. | ||
| 164 | */ | ||
| 165 | reg = rt2500usb_bbp_check(rt2x00dev); | ||
| 166 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { | ||
| 167 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); | ||
| 168 | *value = 0xff; | ||
| 169 | return; | ||
| 170 | } | ||
| 171 | |||
| 172 | rt2500usb_register_read(rt2x00dev, PHY_CSR7, ®); | ||
| 173 | *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); | ||
| 174 | } | ||
| 175 | |||
| 176 | static void rt2500usb_rf_write(const struct rt2x00_dev *rt2x00dev, | ||
| 177 | const unsigned int word, const u32 value) | ||
| 178 | { | ||
| 179 | u16 reg; | ||
| 180 | unsigned int i; | ||
| 181 | |||
| 182 | if (!word) | ||
| 183 | return; | ||
| 184 | |||
| 185 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 186 | rt2500usb_register_read(rt2x00dev, PHY_CSR10, ®); | ||
| 187 | if (!rt2x00_get_field16(reg, PHY_CSR10_RF_BUSY)) | ||
| 188 | goto rf_write; | ||
| 189 | udelay(REGISTER_BUSY_DELAY); | ||
| 190 | } | ||
| 191 | |||
| 192 | ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n"); | ||
| 193 | return; | ||
| 194 | |||
| 195 | rf_write: | ||
| 196 | reg = 0; | ||
| 197 | rt2x00_set_field16(®, PHY_CSR9_RF_VALUE, value); | ||
| 198 | rt2500usb_register_write(rt2x00dev, PHY_CSR9, reg); | ||
| 199 | |||
| 200 | reg = 0; | ||
| 201 | rt2x00_set_field16(®, PHY_CSR10_RF_VALUE, value >> 16); | ||
| 202 | rt2x00_set_field16(®, PHY_CSR10_RF_NUMBER_OF_BITS, 20); | ||
| 203 | rt2x00_set_field16(®, PHY_CSR10_RF_IF_SELECT, 0); | ||
| 204 | rt2x00_set_field16(®, PHY_CSR10_RF_BUSY, 1); | ||
| 205 | |||
| 206 | rt2500usb_register_write(rt2x00dev, PHY_CSR10, reg); | ||
| 207 | rt2x00_rf_write(rt2x00dev, word, value); | ||
| 208 | } | ||
| 209 | |||
| 210 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
| 211 | #define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u16)) ) | ||
| 212 | |||
| 213 | static void rt2500usb_read_csr(const struct rt2x00_dev *rt2x00dev, | ||
| 214 | const unsigned int word, u32 *data) | ||
| 215 | { | ||
| 216 | rt2500usb_register_read(rt2x00dev, CSR_OFFSET(word), (u16 *) data); | ||
| 217 | } | ||
| 218 | |||
| 219 | static void rt2500usb_write_csr(const struct rt2x00_dev *rt2x00dev, | ||
| 220 | const unsigned int word, u32 data) | ||
| 221 | { | ||
| 222 | rt2500usb_register_write(rt2x00dev, CSR_OFFSET(word), data); | ||
| 223 | } | ||
| 224 | |||
| 225 | static const struct rt2x00debug rt2500usb_rt2x00debug = { | ||
| 226 | .owner = THIS_MODULE, | ||
| 227 | .csr = { | ||
| 228 | .read = rt2500usb_read_csr, | ||
| 229 | .write = rt2500usb_write_csr, | ||
| 230 | .word_size = sizeof(u16), | ||
| 231 | .word_count = CSR_REG_SIZE / sizeof(u16), | ||
| 232 | }, | ||
| 233 | .eeprom = { | ||
| 234 | .read = rt2x00_eeprom_read, | ||
| 235 | .write = rt2x00_eeprom_write, | ||
| 236 | .word_size = sizeof(u16), | ||
| 237 | .word_count = EEPROM_SIZE / sizeof(u16), | ||
| 238 | }, | ||
| 239 | .bbp = { | ||
| 240 | .read = rt2500usb_bbp_read, | ||
| 241 | .write = rt2500usb_bbp_write, | ||
| 242 | .word_size = sizeof(u8), | ||
| 243 | .word_count = BBP_SIZE / sizeof(u8), | ||
| 244 | }, | ||
| 245 | .rf = { | ||
| 246 | .read = rt2x00_rf_read, | ||
| 247 | .write = rt2500usb_rf_write, | ||
| 248 | .word_size = sizeof(u32), | ||
| 249 | .word_count = RF_SIZE / sizeof(u32), | ||
| 250 | }, | ||
| 251 | }; | ||
| 252 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
| 253 | |||
| 254 | /* | ||
| 255 | * Configuration handlers. | ||
| 256 | */ | ||
| 257 | static void rt2500usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *addr) | ||
| 258 | { | ||
| 259 | __le16 reg[3]; | ||
| 260 | |||
| 261 | memset(®, 0, sizeof(reg)); | ||
| 262 | memcpy(®, addr, ETH_ALEN); | ||
| 263 | |||
| 264 | /* | ||
| 265 | * The MAC address is passed to us as an array of bytes, | ||
| 266 | * that array is little endian, so no need for byte ordering. | ||
| 267 | */ | ||
| 268 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR2, ®, sizeof(reg)); | ||
| 269 | } | ||
| 270 | |||
| 271 | static void rt2500usb_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) | ||
| 272 | { | ||
| 273 | __le16 reg[3]; | ||
| 274 | |||
| 275 | memset(®, 0, sizeof(reg)); | ||
| 276 | memcpy(®, bssid, ETH_ALEN); | ||
| 277 | |||
| 278 | /* | ||
| 279 | * The BSSID is passed to us as an array of bytes, | ||
| 280 | * that array is little endian, so no need for byte ordering. | ||
| 281 | */ | ||
| 282 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR5, ®, sizeof(reg)); | ||
| 283 | } | ||
| 284 | |||
| 285 | static void rt2500usb_config_packet_filter(struct rt2x00_dev *rt2x00dev, | ||
| 286 | const unsigned int filter) | ||
| 287 | { | ||
| 288 | int promisc = !!(filter & IFF_PROMISC); | ||
| 289 | int multicast = !!(filter & IFF_MULTICAST); | ||
| 290 | int broadcast = !!(filter & IFF_BROADCAST); | ||
| 291 | u16 reg; | ||
| 292 | |||
| 293 | rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); | ||
| 294 | rt2x00_set_field16(®, TXRX_CSR2_DROP_NOT_TO_ME, !promisc); | ||
| 295 | rt2x00_set_field16(®, TXRX_CSR2_DROP_MULTICAST, !multicast); | ||
| 296 | rt2x00_set_field16(®, TXRX_CSR2_DROP_BROADCAST, !broadcast); | ||
| 297 | rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); | ||
| 298 | } | ||
| 299 | |||
| 300 | static void rt2500usb_config_type(struct rt2x00_dev *rt2x00dev, const int type) | ||
| 301 | { | ||
| 302 | u16 reg; | ||
| 303 | |||
| 304 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); | ||
| 305 | |||
| 306 | /* | ||
| 307 | * Apply hardware packet filter. | ||
| 308 | */ | ||
| 309 | rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); | ||
| 310 | |||
| 311 | if (!is_monitor_present(&rt2x00dev->interface) && | ||
| 312 | (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_STA)) | ||
| 313 | rt2x00_set_field16(®, TXRX_CSR2_DROP_TODS, 1); | ||
| 314 | else | ||
| 315 | rt2x00_set_field16(®, TXRX_CSR2_DROP_TODS, 0); | ||
| 316 | |||
| 317 | /* | ||
| 318 | * If there is a non-monitor interface present | ||
| 319 | * the packet should be strict (even if a monitor interface is present!). | ||
| 320 | * When there is only 1 interface present which is in monitor mode | ||
| 321 | * we should start accepting _all_ frames. | ||
| 322 | */ | ||
| 323 | if (is_interface_present(&rt2x00dev->interface)) { | ||
| 324 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CRC, 1); | ||
| 325 | rt2x00_set_field16(®, TXRX_CSR2_DROP_PHYSICAL, 1); | ||
| 326 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CONTROL, 1); | ||
| 327 | rt2x00_set_field16(®, TXRX_CSR2_DROP_VERSION_ERROR, 1); | ||
| 328 | } else if (is_monitor_present(&rt2x00dev->interface)) { | ||
| 329 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CRC, 0); | ||
| 330 | rt2x00_set_field16(®, TXRX_CSR2_DROP_PHYSICAL, 0); | ||
| 331 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CONTROL, 0); | ||
| 332 | rt2x00_set_field16(®, TXRX_CSR2_DROP_VERSION_ERROR, 0); | ||
| 333 | } | ||
| 334 | |||
| 335 | rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); | ||
| 336 | |||
| 337 | /* | ||
| 338 | * Enable beacon config | ||
| 339 | */ | ||
| 340 | rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®); | ||
| 341 | rt2x00_set_field16(®, TXRX_CSR20_OFFSET, | ||
| 342 | (PREAMBLE + get_duration(IEEE80211_HEADER, 2)) >> 6); | ||
| 343 | if (type == IEEE80211_IF_TYPE_STA) | ||
| 344 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 0); | ||
| 345 | else | ||
| 346 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 2); | ||
| 347 | rt2500usb_register_write(rt2x00dev, TXRX_CSR20, reg); | ||
| 348 | |||
| 349 | /* | ||
| 350 | * Enable synchronisation. | ||
| 351 | */ | ||
| 352 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); | ||
| 353 | rt2x00_set_field16(®, TXRX_CSR18_OFFSET, 0); | ||
| 354 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); | ||
| 355 | |||
| 356 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | ||
| 357 | if (is_interface_present(&rt2x00dev->interface)) { | ||
| 358 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | ||
| 359 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1); | ||
| 360 | } | ||
| 361 | |||
| 362 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
| 363 | if (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_AP) | ||
| 364 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, 2); | ||
| 365 | else if (type == IEEE80211_IF_TYPE_STA) | ||
| 366 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, 1); | ||
| 367 | else if (is_monitor_present(&rt2x00dev->interface) && | ||
| 368 | !is_interface_present(&rt2x00dev->interface)) | ||
| 369 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, 0); | ||
| 370 | |||
| 371 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
| 372 | } | ||
| 373 | |||
| 374 | static void rt2500usb_config_rate(struct rt2x00_dev *rt2x00dev, const int rate) | ||
| 375 | { | ||
| 376 | struct ieee80211_conf *conf = &rt2x00dev->hw->conf; | ||
| 377 | u16 reg; | ||
| 378 | u16 value; | ||
| 379 | u16 preamble; | ||
| 380 | |||
| 381 | if (DEVICE_GET_RATE_FIELD(rate, PREAMBLE)) | ||
| 382 | preamble = SHORT_PREAMBLE; | ||
| 383 | else | ||
| 384 | preamble = PREAMBLE; | ||
| 385 | |||
| 386 | reg = DEVICE_GET_RATE_FIELD(rate, RATEMASK) & DEV_BASIC_RATEMASK; | ||
| 387 | |||
| 388 | rt2500usb_register_write(rt2x00dev, TXRX_CSR11, reg); | ||
| 389 | |||
| 390 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); | ||
| 391 | value = ((conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) ? | ||
| 392 | SHORT_DIFS : DIFS) + | ||
| 393 | PLCP + preamble + get_duration(ACK_SIZE, 10); | ||
| 394 | rt2x00_set_field16(®, TXRX_CSR1_ACK_TIMEOUT, value); | ||
| 395 | rt2500usb_register_write(rt2x00dev, TXRX_CSR1, reg); | ||
| 396 | |||
| 397 | rt2500usb_register_read(rt2x00dev, TXRX_CSR10, ®); | ||
| 398 | if (preamble == SHORT_PREAMBLE) | ||
| 399 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, 1); | ||
| 400 | else | ||
| 401 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, 0); | ||
| 402 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); | ||
| 403 | } | ||
| 404 | |||
| 405 | static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, | ||
| 406 | const int phymode) | ||
| 407 | { | ||
| 408 | struct ieee80211_hw_mode *mode; | ||
| 409 | struct ieee80211_rate *rate; | ||
| 410 | |||
| 411 | if (phymode == MODE_IEEE80211A) | ||
| 412 | rt2x00dev->curr_hwmode = HWMODE_A; | ||
| 413 | else if (phymode == MODE_IEEE80211B) | ||
| 414 | rt2x00dev->curr_hwmode = HWMODE_B; | ||
| 415 | else | ||
| 416 | rt2x00dev->curr_hwmode = HWMODE_G; | ||
| 417 | |||
| 418 | mode = &rt2x00dev->hwmodes[rt2x00dev->curr_hwmode]; | ||
| 419 | rate = &mode->rates[mode->num_rates - 1]; | ||
| 420 | |||
| 421 | rt2500usb_config_rate(rt2x00dev, rate->val2); | ||
| 422 | |||
| 423 | if (phymode == MODE_IEEE80211B) { | ||
| 424 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, 0x000b); | ||
| 425 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, 0x0040); | ||
| 426 | } else { | ||
| 427 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, 0x0005); | ||
| 428 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, 0x016c); | ||
| 429 | } | ||
| 430 | } | ||
| 431 | |||
| 432 | static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev, | ||
| 433 | const int index, const int channel, | ||
| 434 | const int txpower) | ||
| 435 | { | ||
| 436 | struct rf_channel reg; | ||
| 437 | |||
| 438 | /* | ||
| 439 | * Fill rf_reg structure. | ||
| 440 | */ | ||
| 441 | memcpy(®, &rt2x00dev->spec.channels[index], sizeof(reg)); | ||
| 442 | |||
| 443 | /* | ||
| 444 | * Set TXpower. | ||
| 445 | */ | ||
| 446 | rt2x00_set_field32(®.rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower)); | ||
| 447 | |||
| 448 | /* | ||
| 449 | * For RT2525E we should first set the channel to half band higher. | ||
| 450 | */ | ||
| 451 | if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) { | ||
| 452 | static const u32 vals[] = { | ||
| 453 | 0x000008aa, 0x000008ae, 0x000008ae, 0x000008b2, | ||
| 454 | 0x000008b2, 0x000008b6, 0x000008b6, 0x000008ba, | ||
| 455 | 0x000008ba, 0x000008be, 0x000008b7, 0x00000902, | ||
| 456 | 0x00000902, 0x00000906 | ||
| 457 | }; | ||
| 458 | |||
| 459 | rt2500usb_rf_write(rt2x00dev, 2, vals[channel - 1]); | ||
| 460 | if (reg.rf4) | ||
| 461 | rt2500usb_rf_write(rt2x00dev, 4, reg.rf4); | ||
| 462 | } | ||
| 463 | |||
| 464 | rt2500usb_rf_write(rt2x00dev, 1, reg.rf1); | ||
| 465 | rt2500usb_rf_write(rt2x00dev, 2, reg.rf2); | ||
| 466 | rt2500usb_rf_write(rt2x00dev, 3, reg.rf3); | ||
| 467 | if (reg.rf4) | ||
| 468 | rt2500usb_rf_write(rt2x00dev, 4, reg.rf4); | ||
| 469 | } | ||
| 470 | |||
| 471 | static void rt2500usb_config_txpower(struct rt2x00_dev *rt2x00dev, | ||
| 472 | const int txpower) | ||
| 473 | { | ||
| 474 | u32 rf3; | ||
| 475 | |||
| 476 | rt2x00_rf_read(rt2x00dev, 3, &rf3); | ||
| 477 | rt2x00_set_field32(&rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower)); | ||
| 478 | rt2500usb_rf_write(rt2x00dev, 3, rf3); | ||
| 479 | } | ||
| 480 | |||
| 481 | static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, | ||
| 482 | const int antenna_tx, const int antenna_rx) | ||
| 483 | { | ||
| 484 | u8 r2; | ||
| 485 | u8 r14; | ||
| 486 | u16 csr5; | ||
| 487 | u16 csr6; | ||
| 488 | |||
| 489 | rt2500usb_bbp_read(rt2x00dev, 2, &r2); | ||
| 490 | rt2500usb_bbp_read(rt2x00dev, 14, &r14); | ||
| 491 | rt2500usb_register_read(rt2x00dev, PHY_CSR5, &csr5); | ||
| 492 | rt2500usb_register_read(rt2x00dev, PHY_CSR6, &csr6); | ||
| 493 | |||
| 494 | /* | ||
| 495 | * Configure the TX antenna. | ||
| 496 | */ | ||
| 497 | switch (antenna_tx) { | ||
| 498 | case ANTENNA_SW_DIVERSITY: | ||
| 499 | case ANTENNA_HW_DIVERSITY: | ||
| 500 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 1); | ||
| 501 | rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 1); | ||
| 502 | rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 1); | ||
| 503 | break; | ||
| 504 | case ANTENNA_A: | ||
| 505 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 0); | ||
| 506 | rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 0); | ||
| 507 | rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 0); | ||
| 508 | break; | ||
| 509 | case ANTENNA_B: | ||
| 510 | rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); | ||
| 511 | rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 2); | ||
| 512 | rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 2); | ||
| 513 | break; | ||
| 514 | } | ||
| 515 | |||
| 516 | /* | ||
| 517 | * Configure the RX antenna. | ||
| 518 | */ | ||
| 519 | switch (antenna_rx) { | ||
| 520 | case ANTENNA_SW_DIVERSITY: | ||
| 521 | case ANTENNA_HW_DIVERSITY: | ||
| 522 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 1); | ||
| 523 | break; | ||
| 524 | case ANTENNA_A: | ||
| 525 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); | ||
| 526 | break; | ||
| 527 | case ANTENNA_B: | ||
| 528 | rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); | ||
| 529 | break; | ||
| 530 | } | ||
| 531 | |||
| 532 | /* | ||
| 533 | * RT2525E and RT5222 need to flip TX I/Q | ||
| 534 | */ | ||
| 535 | if (rt2x00_rf(&rt2x00dev->chip, RF2525E) || | ||
| 536 | rt2x00_rf(&rt2x00dev->chip, RF5222)) { | ||
| 537 | rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1); | ||
| 538 | rt2x00_set_field16(&csr5, PHY_CSR5_CCK_FLIP, 1); | ||
| 539 | rt2x00_set_field16(&csr6, PHY_CSR6_OFDM_FLIP, 1); | ||
| 540 | |||
| 541 | /* | ||
| 542 | * RT2525E does not need RX I/Q Flip. | ||
| 543 | */ | ||
| 544 | if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) | ||
| 545 | rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0); | ||
| 546 | } else { | ||
| 547 | rt2x00_set_field16(&csr5, PHY_CSR5_CCK_FLIP, 0); | ||
| 548 | rt2x00_set_field16(&csr6, PHY_CSR6_OFDM_FLIP, 0); | ||
| 549 | } | ||
| 550 | |||
| 551 | rt2500usb_bbp_write(rt2x00dev, 2, r2); | ||
| 552 | rt2500usb_bbp_write(rt2x00dev, 14, r14); | ||
| 553 | rt2500usb_register_write(rt2x00dev, PHY_CSR5, csr5); | ||
| 554 | rt2500usb_register_write(rt2x00dev, PHY_CSR6, csr6); | ||
| 555 | } | ||
| 556 | |||
| 557 | static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev, | ||
| 558 | const int short_slot_time, | ||
| 559 | const int beacon_int) | ||
| 560 | { | ||
| 561 | u16 reg; | ||
| 562 | |||
| 563 | rt2500usb_register_write(rt2x00dev, MAC_CSR10, | ||
| 564 | short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME); | ||
| 565 | |||
| 566 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); | ||
| 567 | rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, beacon_int * 4); | ||
| 568 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); | ||
| 569 | } | ||
| 570 | |||
| 571 | static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, | ||
| 572 | const unsigned int flags, | ||
| 573 | struct ieee80211_conf *conf) | ||
| 574 | { | ||
| 575 | int short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME; | ||
| 576 | |||
| 577 | if (flags & CONFIG_UPDATE_PHYMODE) | ||
| 578 | rt2500usb_config_phymode(rt2x00dev, conf->phymode); | ||
| 579 | if (flags & CONFIG_UPDATE_CHANNEL) | ||
| 580 | rt2500usb_config_channel(rt2x00dev, conf->channel_val, | ||
| 581 | conf->channel, conf->power_level); | ||
| 582 | if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL)) | ||
| 583 | rt2500usb_config_txpower(rt2x00dev, conf->power_level); | ||
| 584 | if (flags & CONFIG_UPDATE_ANTENNA) | ||
| 585 | rt2500usb_config_antenna(rt2x00dev, conf->antenna_sel_tx, | ||
| 586 | conf->antenna_sel_rx); | ||
| 587 | if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) | ||
| 588 | rt2500usb_config_duration(rt2x00dev, short_slot_time, | ||
| 589 | conf->beacon_int); | ||
| 590 | } | ||
| 591 | |||
| 592 | /* | ||
| 593 | * LED functions. | ||
| 594 | */ | ||
| 595 | static void rt2500usb_enable_led(struct rt2x00_dev *rt2x00dev) | ||
| 596 | { | ||
| 597 | u16 reg; | ||
| 598 | |||
| 599 | rt2500usb_register_read(rt2x00dev, MAC_CSR21, ®); | ||
| 600 | rt2x00_set_field16(®, MAC_CSR21_ON_PERIOD, 70); | ||
| 601 | rt2x00_set_field16(®, MAC_CSR21_OFF_PERIOD, 30); | ||
| 602 | rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg); | ||
| 603 | |||
| 604 | rt2500usb_register_read(rt2x00dev, MAC_CSR20, ®); | ||
| 605 | |||
| 606 | if (rt2x00dev->led_mode == LED_MODE_TXRX_ACTIVITY) { | ||
| 607 | rt2x00_set_field16(®, MAC_CSR20_LINK, 1); | ||
| 608 | rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, 0); | ||
| 609 | } else if (rt2x00dev->led_mode == LED_MODE_ASUS) { | ||
| 610 | rt2x00_set_field16(®, MAC_CSR20_LINK, 0); | ||
| 611 | rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, 1); | ||
| 612 | } else { | ||
| 613 | rt2x00_set_field16(®, MAC_CSR20_LINK, 1); | ||
| 614 | rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, 1); | ||
| 615 | } | ||
| 616 | |||
| 617 | rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg); | ||
| 618 | } | ||
| 619 | |||
| 620 | static void rt2500usb_disable_led(struct rt2x00_dev *rt2x00dev) | ||
| 621 | { | ||
| 622 | u16 reg; | ||
| 623 | |||
| 624 | rt2500usb_register_read(rt2x00dev, MAC_CSR20, ®); | ||
| 625 | rt2x00_set_field16(®, MAC_CSR20_LINK, 0); | ||
| 626 | rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, 0); | ||
| 627 | rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg); | ||
| 628 | } | ||
| 629 | |||
| 630 | /* | ||
| 631 | * Link tuning | ||
| 632 | */ | ||
| 633 | static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev) | ||
| 634 | { | ||
| 635 | u16 reg; | ||
| 636 | |||
| 637 | /* | ||
| 638 | * Update FCS error count from register. | ||
| 639 | */ | ||
| 640 | rt2500usb_register_read(rt2x00dev, STA_CSR0, ®); | ||
| 641 | rt2x00dev->link.rx_failed = rt2x00_get_field16(reg, STA_CSR0_FCS_ERROR); | ||
| 642 | |||
| 643 | /* | ||
| 644 | * Update False CCA count from register. | ||
| 645 | */ | ||
| 646 | rt2500usb_register_read(rt2x00dev, STA_CSR3, ®); | ||
| 647 | rt2x00dev->link.false_cca = | ||
| 648 | rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR); | ||
| 649 | } | ||
| 650 | |||
| 651 | static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev) | ||
| 652 | { | ||
| 653 | u16 eeprom; | ||
| 654 | u16 value; | ||
| 655 | |||
| 656 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &eeprom); | ||
| 657 | value = rt2x00_get_field16(eeprom, EEPROM_BBPTUNE_R24_LOW); | ||
| 658 | rt2500usb_bbp_write(rt2x00dev, 24, value); | ||
| 659 | |||
| 660 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R25, &eeprom); | ||
| 661 | value = rt2x00_get_field16(eeprom, EEPROM_BBPTUNE_R25_LOW); | ||
| 662 | rt2500usb_bbp_write(rt2x00dev, 25, value); | ||
| 663 | |||
| 664 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R61, &eeprom); | ||
| 665 | value = rt2x00_get_field16(eeprom, EEPROM_BBPTUNE_R61_LOW); | ||
| 666 | rt2500usb_bbp_write(rt2x00dev, 61, value); | ||
| 667 | |||
| 668 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &eeprom); | ||
| 669 | value = rt2x00_get_field16(eeprom, EEPROM_BBPTUNE_VGCUPPER); | ||
| 670 | rt2500usb_bbp_write(rt2x00dev, 17, value); | ||
| 671 | |||
| 672 | rt2x00dev->link.vgc_level = value; | ||
| 673 | } | ||
| 674 | |||
| 675 | static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | ||
| 676 | { | ||
| 677 | int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); | ||
| 678 | u16 bbp_thresh; | ||
| 679 | u16 vgc_bound; | ||
| 680 | u16 sens; | ||
| 681 | u16 r24; | ||
| 682 | u16 r25; | ||
| 683 | u16 r61; | ||
| 684 | u16 r17_sens; | ||
| 685 | u8 r17; | ||
| 686 | u8 up_bound; | ||
| 687 | u8 low_bound; | ||
| 688 | |||
| 689 | /* | ||
| 690 | * Determine the BBP tuning threshold and correctly | ||
| 691 | * set BBP 24, 25 and 61. | ||
| 692 | */ | ||
| 693 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE, &bbp_thresh); | ||
| 694 | bbp_thresh = rt2x00_get_field16(bbp_thresh, EEPROM_BBPTUNE_THRESHOLD); | ||
| 695 | |||
| 696 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &r24); | ||
| 697 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R25, &r25); | ||
| 698 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R61, &r61); | ||
| 699 | |||
| 700 | if ((rssi + bbp_thresh) > 0) { | ||
| 701 | r24 = rt2x00_get_field16(r24, EEPROM_BBPTUNE_R24_HIGH); | ||
| 702 | r25 = rt2x00_get_field16(r25, EEPROM_BBPTUNE_R25_HIGH); | ||
| 703 | r61 = rt2x00_get_field16(r61, EEPROM_BBPTUNE_R61_HIGH); | ||
| 704 | } else { | ||
| 705 | r24 = rt2x00_get_field16(r24, EEPROM_BBPTUNE_R24_LOW); | ||
| 706 | r25 = rt2x00_get_field16(r25, EEPROM_BBPTUNE_R25_LOW); | ||
| 707 | r61 = rt2x00_get_field16(r61, EEPROM_BBPTUNE_R61_LOW); | ||
| 708 | } | ||
| 709 | |||
| 710 | rt2500usb_bbp_write(rt2x00dev, 24, r24); | ||
| 711 | rt2500usb_bbp_write(rt2x00dev, 25, r25); | ||
| 712 | rt2500usb_bbp_write(rt2x00dev, 61, r61); | ||
| 713 | |||
| 714 | /* | ||
| 715 | * Read current r17 value, as well as the sensitivity values | ||
| 716 | * for the r17 register. | ||
| 717 | */ | ||
| 718 | rt2500usb_bbp_read(rt2x00dev, 17, &r17); | ||
| 719 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &r17_sens); | ||
| 720 | |||
| 721 | /* | ||
| 722 | * A too low RSSI will cause too much false CCA which will | ||
| 723 | * then corrupt the R17 tuning. To remidy this the tuning should | ||
| 724 | * be stopped (While making sure the R17 value will not exceed limits) | ||
| 725 | */ | ||
| 726 | if (rssi >= -40) { | ||
| 727 | if (r17 != 0x60) | ||
| 728 | rt2500usb_bbp_write(rt2x00dev, 17, 0x60); | ||
| 729 | return; | ||
| 730 | } | ||
| 731 | |||
| 732 | /* | ||
| 733 | * Special big-R17 for short distance | ||
| 734 | */ | ||
| 735 | if (rssi >= -58) { | ||
| 736 | sens = rt2x00_get_field16(r17_sens, EEPROM_BBPTUNE_R17_LOW); | ||
| 737 | if (r17 != sens) | ||
| 738 | rt2500usb_bbp_write(rt2x00dev, 17, sens); | ||
| 739 | return; | ||
| 740 | } | ||
| 741 | |||
| 742 | /* | ||
| 743 | * Special mid-R17 for middle distance | ||
| 744 | */ | ||
| 745 | if (rssi >= -74) { | ||
| 746 | sens = rt2x00_get_field16(r17_sens, EEPROM_BBPTUNE_R17_HIGH); | ||
| 747 | if (r17 != sens) | ||
| 748 | rt2500usb_bbp_write(rt2x00dev, 17, sens); | ||
| 749 | return; | ||
| 750 | } | ||
| 751 | |||
| 752 | /* | ||
| 753 | * Leave short or middle distance condition, restore r17 | ||
| 754 | * to the dynamic tuning range. | ||
| 755 | */ | ||
| 756 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &vgc_bound); | ||
| 757 | vgc_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCUPPER); | ||
| 758 | |||
| 759 | low_bound = 0x32; | ||
| 760 | if (rssi >= -77) | ||
| 761 | up_bound = vgc_bound; | ||
| 762 | else | ||
| 763 | up_bound = vgc_bound - (-77 - rssi); | ||
| 764 | |||
| 765 | if (up_bound < low_bound) | ||
| 766 | up_bound = low_bound; | ||
| 767 | |||
| 768 | if (r17 > up_bound) { | ||
| 769 | rt2500usb_bbp_write(rt2x00dev, 17, up_bound); | ||
| 770 | rt2x00dev->link.vgc_level = up_bound; | ||
| 771 | } else if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) { | ||
| 772 | rt2500usb_bbp_write(rt2x00dev, 17, ++r17); | ||
| 773 | rt2x00dev->link.vgc_level = r17; | ||
| 774 | } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) { | ||
| 775 | rt2500usb_bbp_write(rt2x00dev, 17, --r17); | ||
| 776 | rt2x00dev->link.vgc_level = r17; | ||
| 777 | } | ||
| 778 | } | ||
| 779 | |||
| 780 | /* | ||
| 781 | * Initialization functions. | ||
| 782 | */ | ||
| 783 | static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) | ||
| 784 | { | ||
| 785 | u16 reg; | ||
| 786 | |||
| 787 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0x0001, | ||
| 788 | USB_MODE_TEST, REGISTER_TIMEOUT); | ||
| 789 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_SINGLE_WRITE, 0x0308, | ||
| 790 | 0x00f0, REGISTER_TIMEOUT); | ||
| 791 | |||
| 792 | rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); | ||
| 793 | rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX, 1); | ||
| 794 | rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); | ||
| 795 | |||
| 796 | rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x1111); | ||
| 797 | rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x1e11); | ||
| 798 | |||
| 799 | rt2500usb_register_read(rt2x00dev, MAC_CSR1, ®); | ||
| 800 | rt2x00_set_field16(®, MAC_CSR1_SOFT_RESET, 1); | ||
| 801 | rt2x00_set_field16(®, MAC_CSR1_BBP_RESET, 1); | ||
| 802 | rt2x00_set_field16(®, MAC_CSR1_HOST_READY, 0); | ||
| 803 | rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); | ||
| 804 | |||
| 805 | rt2500usb_register_read(rt2x00dev, MAC_CSR1, ®); | ||
| 806 | rt2x00_set_field16(®, MAC_CSR1_SOFT_RESET, 0); | ||
| 807 | rt2x00_set_field16(®, MAC_CSR1_BBP_RESET, 0); | ||
| 808 | rt2x00_set_field16(®, MAC_CSR1_HOST_READY, 0); | ||
| 809 | rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); | ||
| 810 | |||
| 811 | rt2500usb_register_read(rt2x00dev, TXRX_CSR5, ®); | ||
| 812 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0, 13); | ||
| 813 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0_VALID, 1); | ||
| 814 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID1, 12); | ||
| 815 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID1_VALID, 1); | ||
| 816 | rt2500usb_register_write(rt2x00dev, TXRX_CSR5, reg); | ||
| 817 | |||
| 818 | rt2500usb_register_read(rt2x00dev, TXRX_CSR6, ®); | ||
| 819 | rt2x00_set_field16(®, TXRX_CSR6_BBP_ID0, 10); | ||
| 820 | rt2x00_set_field16(®, TXRX_CSR6_BBP_ID0_VALID, 1); | ||
| 821 | rt2x00_set_field16(®, TXRX_CSR6_BBP_ID1, 11); | ||
| 822 | rt2x00_set_field16(®, TXRX_CSR6_BBP_ID1_VALID, 1); | ||
| 823 | rt2500usb_register_write(rt2x00dev, TXRX_CSR6, reg); | ||
| 824 | |||
| 825 | rt2500usb_register_read(rt2x00dev, TXRX_CSR7, ®); | ||
| 826 | rt2x00_set_field16(®, TXRX_CSR7_BBP_ID0, 7); | ||
| 827 | rt2x00_set_field16(®, TXRX_CSR7_BBP_ID0_VALID, 1); | ||
| 828 | rt2x00_set_field16(®, TXRX_CSR7_BBP_ID1, 6); | ||
| 829 | rt2x00_set_field16(®, TXRX_CSR7_BBP_ID1_VALID, 1); | ||
| 830 | rt2500usb_register_write(rt2x00dev, TXRX_CSR7, reg); | ||
| 831 | |||
| 832 | rt2500usb_register_read(rt2x00dev, TXRX_CSR8, ®); | ||
| 833 | rt2x00_set_field16(®, TXRX_CSR8_BBP_ID0, 5); | ||
| 834 | rt2x00_set_field16(®, TXRX_CSR8_BBP_ID0_VALID, 1); | ||
| 835 | rt2x00_set_field16(®, TXRX_CSR8_BBP_ID1, 0); | ||
| 836 | rt2x00_set_field16(®, TXRX_CSR8_BBP_ID1_VALID, 0); | ||
| 837 | rt2500usb_register_write(rt2x00dev, TXRX_CSR8, reg); | ||
| 838 | |||
| 839 | rt2500usb_register_write(rt2x00dev, TXRX_CSR21, 0xe78f); | ||
| 840 | rt2500usb_register_write(rt2x00dev, MAC_CSR9, 0xff1d); | ||
| 841 | |||
| 842 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) | ||
| 843 | return -EBUSY; | ||
| 844 | |||
| 845 | rt2500usb_register_read(rt2x00dev, MAC_CSR1, ®); | ||
| 846 | rt2x00_set_field16(®, MAC_CSR1_SOFT_RESET, 0); | ||
| 847 | rt2x00_set_field16(®, MAC_CSR1_BBP_RESET, 0); | ||
| 848 | rt2x00_set_field16(®, MAC_CSR1_HOST_READY, 1); | ||
| 849 | rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); | ||
| 850 | |||
| 851 | if (rt2x00_get_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) { | ||
| 852 | rt2500usb_register_read(rt2x00dev, PHY_CSR2, ®); | ||
| 853 | reg &= ~0x0002; | ||
| 854 | } else { | ||
| 855 | reg = 0x3002; | ||
| 856 | } | ||
| 857 | rt2500usb_register_write(rt2x00dev, PHY_CSR2, reg); | ||
| 858 | |||
| 859 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, 0x0002); | ||
| 860 | rt2500usb_register_write(rt2x00dev, MAC_CSR22, 0x0053); | ||
| 861 | rt2500usb_register_write(rt2x00dev, MAC_CSR15, 0x01ee); | ||
| 862 | rt2500usb_register_write(rt2x00dev, MAC_CSR16, 0x0000); | ||
| 863 | |||
| 864 | rt2500usb_register_read(rt2x00dev, MAC_CSR8, ®); | ||
| 865 | rt2x00_set_field16(®, MAC_CSR8_MAX_FRAME_UNIT, | ||
| 866 | rt2x00dev->rx->data_size); | ||
| 867 | rt2500usb_register_write(rt2x00dev, MAC_CSR8, reg); | ||
| 868 | |||
| 869 | rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
| 870 | rt2x00_set_field16(®, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER); | ||
| 871 | rt2x00_set_field16(®, TXRX_CSR0_KEY_ID, 0xff); | ||
| 872 | rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
| 873 | |||
| 874 | rt2500usb_register_read(rt2x00dev, MAC_CSR18, ®); | ||
| 875 | rt2x00_set_field16(®, MAC_CSR18_DELAY_AFTER_BEACON, 90); | ||
| 876 | rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg); | ||
| 877 | |||
| 878 | rt2500usb_register_read(rt2x00dev, PHY_CSR4, ®); | ||
| 879 | rt2x00_set_field16(®, PHY_CSR4_LOW_RF_LE, 1); | ||
| 880 | rt2500usb_register_write(rt2x00dev, PHY_CSR4, reg); | ||
| 881 | |||
| 882 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); | ||
| 883 | rt2x00_set_field16(®, TXRX_CSR1_AUTO_SEQUENCE, 1); | ||
| 884 | rt2500usb_register_write(rt2x00dev, TXRX_CSR1, reg); | ||
| 885 | |||
| 886 | return 0; | ||
| 887 | } | ||
| 888 | |||
| 889 | static int rt2500usb_init_bbp(struct rt2x00_dev *rt2x00dev) | ||
| 890 | { | ||
| 891 | unsigned int i; | ||
| 892 | u16 eeprom; | ||
| 893 | u8 value; | ||
| 894 | u8 reg_id; | ||
| 895 | |||
| 896 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 897 | rt2500usb_bbp_read(rt2x00dev, 0, &value); | ||
| 898 | if ((value != 0xff) && (value != 0x00)) | ||
| 899 | goto continue_csr_init; | ||
| 900 | NOTICE(rt2x00dev, "Waiting for BBP register.\n"); | ||
| 901 | udelay(REGISTER_BUSY_DELAY); | ||
| 902 | } | ||
| 903 | |||
| 904 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | ||
| 905 | return -EACCES; | ||
| 906 | |||
| 907 | continue_csr_init: | ||
| 908 | rt2500usb_bbp_write(rt2x00dev, 3, 0x02); | ||
| 909 | rt2500usb_bbp_write(rt2x00dev, 4, 0x19); | ||
| 910 | rt2500usb_bbp_write(rt2x00dev, 14, 0x1c); | ||
| 911 | rt2500usb_bbp_write(rt2x00dev, 15, 0x30); | ||
| 912 | rt2500usb_bbp_write(rt2x00dev, 16, 0xac); | ||
| 913 | rt2500usb_bbp_write(rt2x00dev, 18, 0x18); | ||
| 914 | rt2500usb_bbp_write(rt2x00dev, 19, 0xff); | ||
| 915 | rt2500usb_bbp_write(rt2x00dev, 20, 0x1e); | ||
| 916 | rt2500usb_bbp_write(rt2x00dev, 21, 0x08); | ||
| 917 | rt2500usb_bbp_write(rt2x00dev, 22, 0x08); | ||
| 918 | rt2500usb_bbp_write(rt2x00dev, 23, 0x08); | ||
| 919 | rt2500usb_bbp_write(rt2x00dev, 24, 0x80); | ||
| 920 | rt2500usb_bbp_write(rt2x00dev, 25, 0x50); | ||
| 921 | rt2500usb_bbp_write(rt2x00dev, 26, 0x08); | ||
| 922 | rt2500usb_bbp_write(rt2x00dev, 27, 0x23); | ||
| 923 | rt2500usb_bbp_write(rt2x00dev, 30, 0x10); | ||
| 924 | rt2500usb_bbp_write(rt2x00dev, 31, 0x2b); | ||
| 925 | rt2500usb_bbp_write(rt2x00dev, 32, 0xb9); | ||
| 926 | rt2500usb_bbp_write(rt2x00dev, 34, 0x12); | ||
| 927 | rt2500usb_bbp_write(rt2x00dev, 35, 0x50); | ||
| 928 | rt2500usb_bbp_write(rt2x00dev, 39, 0xc4); | ||
| 929 | rt2500usb_bbp_write(rt2x00dev, 40, 0x02); | ||
| 930 | rt2500usb_bbp_write(rt2x00dev, 41, 0x60); | ||
| 931 | rt2500usb_bbp_write(rt2x00dev, 53, 0x10); | ||
| 932 | rt2500usb_bbp_write(rt2x00dev, 54, 0x18); | ||
| 933 | rt2500usb_bbp_write(rt2x00dev, 56, 0x08); | ||
| 934 | rt2500usb_bbp_write(rt2x00dev, 57, 0x10); | ||
| 935 | rt2500usb_bbp_write(rt2x00dev, 58, 0x08); | ||
| 936 | rt2500usb_bbp_write(rt2x00dev, 61, 0x60); | ||
| 937 | rt2500usb_bbp_write(rt2x00dev, 62, 0x10); | ||
| 938 | rt2500usb_bbp_write(rt2x00dev, 75, 0xff); | ||
| 939 | |||
| 940 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
| 941 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | ||
| 942 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | ||
| 943 | |||
| 944 | if (eeprom != 0xffff && eeprom != 0x0000) { | ||
| 945 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | ||
| 946 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | ||
| 947 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
| 948 | reg_id, value); | ||
| 949 | rt2500usb_bbp_write(rt2x00dev, reg_id, value); | ||
| 950 | } | ||
| 951 | } | ||
| 952 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
| 953 | |||
| 954 | return 0; | ||
| 955 | } | ||
| 956 | |||
| 957 | /* | ||
| 958 | * Device state switch handlers. | ||
| 959 | */ | ||
| 960 | static void rt2500usb_toggle_rx(struct rt2x00_dev *rt2x00dev, | ||
| 961 | enum dev_state state) | ||
| 962 | { | ||
| 963 | u16 reg; | ||
| 964 | |||
| 965 | rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); | ||
| 966 | rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX, | ||
| 967 | state == STATE_RADIO_RX_OFF); | ||
| 968 | rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); | ||
| 969 | } | ||
| 970 | |||
| 971 | static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 972 | { | ||
| 973 | /* | ||
| 974 | * Initialize all registers. | ||
| 975 | */ | ||
| 976 | if (rt2500usb_init_registers(rt2x00dev) || | ||
| 977 | rt2500usb_init_bbp(rt2x00dev)) { | ||
| 978 | ERROR(rt2x00dev, "Register initialization failed.\n"); | ||
| 979 | return -EIO; | ||
| 980 | } | ||
| 981 | |||
| 982 | rt2x00usb_enable_radio(rt2x00dev); | ||
| 983 | |||
| 984 | /* | ||
| 985 | * Enable LED | ||
| 986 | */ | ||
| 987 | rt2500usb_enable_led(rt2x00dev); | ||
| 988 | |||
| 989 | return 0; | ||
| 990 | } | ||
| 991 | |||
| 992 | static void rt2500usb_disable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 993 | { | ||
| 994 | /* | ||
| 995 | * Disable LED | ||
| 996 | */ | ||
| 997 | rt2500usb_disable_led(rt2x00dev); | ||
| 998 | |||
| 999 | rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x2121); | ||
| 1000 | rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x2121); | ||
| 1001 | |||
| 1002 | /* | ||
| 1003 | * Disable synchronisation. | ||
| 1004 | */ | ||
| 1005 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); | ||
| 1006 | |||
| 1007 | rt2x00usb_disable_radio(rt2x00dev); | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | static int rt2500usb_set_state(struct rt2x00_dev *rt2x00dev, | ||
| 1011 | enum dev_state state) | ||
| 1012 | { | ||
| 1013 | u16 reg; | ||
| 1014 | u16 reg2; | ||
| 1015 | unsigned int i; | ||
| 1016 | char put_to_sleep; | ||
| 1017 | char bbp_state; | ||
| 1018 | char rf_state; | ||
| 1019 | |||
| 1020 | put_to_sleep = (state != STATE_AWAKE); | ||
| 1021 | |||
| 1022 | reg = 0; | ||
| 1023 | rt2x00_set_field16(®, MAC_CSR17_BBP_DESIRE_STATE, state); | ||
| 1024 | rt2x00_set_field16(®, MAC_CSR17_RF_DESIRE_STATE, state); | ||
| 1025 | rt2x00_set_field16(®, MAC_CSR17_PUT_TO_SLEEP, put_to_sleep); | ||
| 1026 | rt2500usb_register_write(rt2x00dev, MAC_CSR17, reg); | ||
| 1027 | rt2x00_set_field16(®, MAC_CSR17_SET_STATE, 1); | ||
| 1028 | rt2500usb_register_write(rt2x00dev, MAC_CSR17, reg); | ||
| 1029 | |||
| 1030 | /* | ||
| 1031 | * Device is not guaranteed to be in the requested state yet. | ||
| 1032 | * We must wait until the register indicates that the | ||
| 1033 | * device has entered the correct state. | ||
| 1034 | */ | ||
| 1035 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 1036 | rt2500usb_register_read(rt2x00dev, MAC_CSR17, ®2); | ||
| 1037 | bbp_state = rt2x00_get_field16(reg2, MAC_CSR17_BBP_CURR_STATE); | ||
| 1038 | rf_state = rt2x00_get_field16(reg2, MAC_CSR17_RF_CURR_STATE); | ||
| 1039 | if (bbp_state == state && rf_state == state) | ||
| 1040 | return 0; | ||
| 1041 | rt2500usb_register_write(rt2x00dev, MAC_CSR17, reg); | ||
| 1042 | msleep(30); | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | NOTICE(rt2x00dev, "Device failed to enter state %d, " | ||
| 1046 | "current device state: bbp %d and rf %d.\n", | ||
| 1047 | state, bbp_state, rf_state); | ||
| 1048 | |||
| 1049 | return -EBUSY; | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, | ||
| 1053 | enum dev_state state) | ||
| 1054 | { | ||
| 1055 | int retval = 0; | ||
| 1056 | |||
| 1057 | switch (state) { | ||
| 1058 | case STATE_RADIO_ON: | ||
| 1059 | retval = rt2500usb_enable_radio(rt2x00dev); | ||
| 1060 | break; | ||
| 1061 | case STATE_RADIO_OFF: | ||
| 1062 | rt2500usb_disable_radio(rt2x00dev); | ||
| 1063 | break; | ||
| 1064 | case STATE_RADIO_RX_ON: | ||
| 1065 | case STATE_RADIO_RX_OFF: | ||
| 1066 | rt2500usb_toggle_rx(rt2x00dev, state); | ||
| 1067 | break; | ||
| 1068 | case STATE_DEEP_SLEEP: | ||
| 1069 | case STATE_SLEEP: | ||
| 1070 | case STATE_STANDBY: | ||
| 1071 | case STATE_AWAKE: | ||
| 1072 | retval = rt2500usb_set_state(rt2x00dev, state); | ||
| 1073 | break; | ||
| 1074 | default: | ||
| 1075 | retval = -ENOTSUPP; | ||
| 1076 | break; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | return retval; | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | /* | ||
| 1083 | * TX descriptor initialization | ||
| 1084 | */ | ||
| 1085 | static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | ||
| 1086 | struct data_desc *txd, | ||
| 1087 | struct data_entry_desc *desc, | ||
| 1088 | struct ieee80211_hdr *ieee80211hdr, | ||
| 1089 | unsigned int length, | ||
| 1090 | struct ieee80211_tx_control *control) | ||
| 1091 | { | ||
| 1092 | u32 word; | ||
| 1093 | |||
| 1094 | /* | ||
| 1095 | * Start writing the descriptor words. | ||
| 1096 | */ | ||
| 1097 | rt2x00_desc_read(txd, 1, &word); | ||
| 1098 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | ||
| 1099 | rt2x00_set_field32(&word, TXD_W1_AIFS, desc->aifs); | ||
| 1100 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | ||
| 1101 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | ||
| 1102 | rt2x00_desc_write(txd, 1, word); | ||
| 1103 | |||
| 1104 | rt2x00_desc_read(txd, 2, &word); | ||
| 1105 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | ||
| 1106 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | ||
| 1107 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | ||
| 1108 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | ||
| 1109 | rt2x00_desc_write(txd, 2, word); | ||
| 1110 | |||
| 1111 | rt2x00_desc_read(txd, 0, &word); | ||
| 1112 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, control->retry_limit); | ||
| 1113 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | ||
| 1114 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | ||
| 1115 | rt2x00_set_field32(&word, TXD_W0_ACK, | ||
| 1116 | !(control->flags & IEEE80211_TXCTL_NO_ACK)); | ||
| 1117 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | ||
| 1118 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | ||
| 1119 | rt2x00_set_field32(&word, TXD_W0_OFDM, | ||
| 1120 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | ||
| 1121 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, | ||
| 1122 | !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)); | ||
| 1123 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | ||
| 1124 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length); | ||
| 1125 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); | ||
| 1126 | rt2x00_desc_write(txd, 0, word); | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | /* | ||
| 1130 | * TX data initialization | ||
| 1131 | */ | ||
| 1132 | static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
| 1133 | unsigned int queue) | ||
| 1134 | { | ||
| 1135 | u16 reg; | ||
| 1136 | |||
| 1137 | if (queue != IEEE80211_TX_QUEUE_BEACON) | ||
| 1138 | return; | ||
| 1139 | |||
| 1140 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | ||
| 1141 | if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) { | ||
| 1142 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 1); | ||
| 1143 | /* | ||
| 1144 | * Beacon generation will fail initially. | ||
| 1145 | * To prevent this we need to register the TXRX_CSR19 | ||
| 1146 | * register several times. | ||
| 1147 | */ | ||
| 1148 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
| 1149 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); | ||
| 1150 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
| 1151 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); | ||
| 1152 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
| 1153 | } | ||
| 1154 | } | ||
| 1155 | |||
| 1156 | /* | ||
| 1157 | * RX control handlers | ||
| 1158 | */ | ||
| 1159 | static int rt2500usb_fill_rxdone(struct data_entry *entry, | ||
| 1160 | int *signal, int *rssi, int *ofdm, int *size) | ||
| 1161 | { | ||
| 1162 | struct urb *urb = entry->priv; | ||
| 1163 | struct data_desc *rxd = (struct data_desc *)(entry->skb->data + | ||
| 1164 | (urb->actual_length - | ||
| 1165 | entry->ring->desc_size)); | ||
| 1166 | u32 word0; | ||
| 1167 | u32 word1; | ||
| 1168 | |||
| 1169 | rt2x00_desc_read(rxd, 0, &word0); | ||
| 1170 | rt2x00_desc_read(rxd, 1, &word1); | ||
| 1171 | |||
| 1172 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR) || | ||
| 1173 | rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR) || | ||
| 1174 | rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR)) | ||
| 1175 | return -EINVAL; | ||
| 1176 | |||
| 1177 | /* | ||
| 1178 | * Obtain the status about this packet. | ||
| 1179 | */ | ||
| 1180 | *signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | ||
| 1181 | *rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) - | ||
| 1182 | entry->ring->rt2x00dev->rssi_offset; | ||
| 1183 | *ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | ||
| 1184 | *size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
| 1185 | |||
| 1186 | return 0; | ||
| 1187 | } | ||
| 1188 | |||
| 1189 | /* | ||
| 1190 | * Interrupt functions. | ||
| 1191 | */ | ||
| 1192 | static void rt2500usb_beacondone(struct urb *urb) | ||
| 1193 | { | ||
| 1194 | struct data_entry *entry = (struct data_entry *)urb->context; | ||
| 1195 | struct data_ring *ring = entry->ring; | ||
| 1196 | |||
| 1197 | if (!test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) | ||
| 1198 | return; | ||
| 1199 | |||
| 1200 | /* | ||
| 1201 | * Check if this was the guardian beacon, | ||
| 1202 | * if that was the case we need to send the real beacon now. | ||
| 1203 | * Otherwise we should free the sk_buffer, the device | ||
| 1204 | * should be doing the rest of the work now. | ||
| 1205 | */ | ||
| 1206 | if (ring->index == 1) { | ||
| 1207 | rt2x00_ring_index_done_inc(ring); | ||
| 1208 | entry = rt2x00_get_data_entry(ring); | ||
| 1209 | usb_submit_urb(entry->priv, GFP_ATOMIC); | ||
| 1210 | rt2x00_ring_index_inc(ring); | ||
| 1211 | } else if (ring->index_done == 1) { | ||
| 1212 | entry = rt2x00_get_data_entry_done(ring); | ||
| 1213 | if (entry->skb) { | ||
| 1214 | dev_kfree_skb(entry->skb); | ||
| 1215 | entry->skb = NULL; | ||
| 1216 | } | ||
| 1217 | rt2x00_ring_index_done_inc(ring); | ||
| 1218 | } | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | /* | ||
| 1222 | * Device probe functions. | ||
| 1223 | */ | ||
| 1224 | static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | ||
| 1225 | { | ||
| 1226 | u16 word; | ||
| 1227 | u8 *mac; | ||
| 1228 | |||
| 1229 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); | ||
| 1230 | |||
| 1231 | /* | ||
| 1232 | * Start validation of the data that has been read. | ||
| 1233 | */ | ||
| 1234 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | ||
| 1235 | if (!is_valid_ether_addr(mac)) { | ||
| 1236 | random_ether_addr(mac); | ||
| 1237 | EEPROM(rt2x00dev, "MAC: " MAC_FMT "\n", MAC_ARG(mac)); | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | ||
| 1241 | if (word == 0xffff) { | ||
| 1242 | rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2); | ||
| 1243 | rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 0); | ||
| 1244 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 0); | ||
| 1245 | rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE, 0); | ||
| 1246 | rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0); | ||
| 1247 | rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); | ||
| 1248 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522); | ||
| 1249 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | ||
| 1250 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | ||
| 1254 | if (word == 0xffff) { | ||
| 1255 | rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); | ||
| 1256 | rt2x00_set_field16(&word, EEPROM_NIC_DYN_BBP_TUNE, 0); | ||
| 1257 | rt2x00_set_field16(&word, EEPROM_NIC_CCK_TX_POWER, 0); | ||
| 1258 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | ||
| 1259 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &word); | ||
| 1263 | if (word == 0xffff) { | ||
| 1264 | rt2x00_set_field16(&word, EEPROM_CALIBRATE_OFFSET_RSSI, | ||
| 1265 | DEFAULT_RSSI_OFFSET); | ||
| 1266 | rt2x00_eeprom_write(rt2x00dev, EEPROM_CALIBRATE_OFFSET, word); | ||
| 1267 | EEPROM(rt2x00dev, "Calibrate offset: 0x%04x\n", word); | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE, &word); | ||
| 1271 | if (word == 0xffff) { | ||
| 1272 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_THRESHOLD, 45); | ||
| 1273 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE, word); | ||
| 1274 | EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word); | ||
| 1275 | } | ||
| 1276 | |||
| 1277 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &word); | ||
| 1278 | if (word == 0xffff) { | ||
| 1279 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); | ||
| 1280 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); | ||
| 1281 | EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); | ||
| 1282 | } | ||
| 1283 | |||
| 1284 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &word); | ||
| 1285 | if (word == 0xffff) { | ||
| 1286 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_LOW, 0x48); | ||
| 1287 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); | ||
| 1288 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); | ||
| 1289 | EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word); | ||
| 1290 | } | ||
| 1291 | |||
| 1292 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); | ||
| 1293 | if (word == 0xffff) { | ||
| 1294 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R24_LOW, 0x40); | ||
| 1295 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R24_HIGH, 0x80); | ||
| 1296 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R24, word); | ||
| 1297 | EEPROM(rt2x00dev, "BBPtune r24: 0x%04x\n", word); | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R25, &word); | ||
| 1301 | if (word == 0xffff) { | ||
| 1302 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R25_LOW, 0x40); | ||
| 1303 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R25_HIGH, 0x50); | ||
| 1304 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R25, word); | ||
| 1305 | EEPROM(rt2x00dev, "BBPtune r25: 0x%04x\n", word); | ||
| 1306 | } | ||
| 1307 | |||
| 1308 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R61, &word); | ||
| 1309 | if (word == 0xffff) { | ||
| 1310 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R61_LOW, 0x60); | ||
| 1311 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R61_HIGH, 0x6d); | ||
| 1312 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R61, word); | ||
| 1313 | EEPROM(rt2x00dev, "BBPtune r61: 0x%04x\n", word); | ||
| 1314 | } | ||
| 1315 | |||
| 1316 | return 0; | ||
| 1317 | } | ||
| 1318 | |||
| 1319 | static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | ||
| 1320 | { | ||
| 1321 | u16 reg; | ||
| 1322 | u16 value; | ||
| 1323 | u16 eeprom; | ||
| 1324 | |||
| 1325 | /* | ||
| 1326 | * Read EEPROM word for configuration. | ||
| 1327 | */ | ||
| 1328 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
| 1329 | |||
| 1330 | /* | ||
| 1331 | * Identify RF chipset. | ||
| 1332 | */ | ||
| 1333 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | ||
| 1334 | rt2500usb_register_read(rt2x00dev, MAC_CSR0, ®); | ||
| 1335 | rt2x00_set_chip(rt2x00dev, RT2570, value, reg); | ||
| 1336 | |||
| 1337 | if (rt2x00_rev(&rt2x00dev->chip, 0xffff0)) { | ||
| 1338 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); | ||
| 1339 | return -ENODEV; | ||
| 1340 | } | ||
| 1341 | |||
| 1342 | if (!rt2x00_rf(&rt2x00dev->chip, RF2522) && | ||
| 1343 | !rt2x00_rf(&rt2x00dev->chip, RF2523) && | ||
| 1344 | !rt2x00_rf(&rt2x00dev->chip, RF2524) && | ||
| 1345 | !rt2x00_rf(&rt2x00dev->chip, RF2525) && | ||
| 1346 | !rt2x00_rf(&rt2x00dev->chip, RF2525E) && | ||
| 1347 | !rt2x00_rf(&rt2x00dev->chip, RF5222)) { | ||
| 1348 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | ||
| 1349 | return -ENODEV; | ||
| 1350 | } | ||
| 1351 | |||
| 1352 | /* | ||
| 1353 | * Identify default antenna configuration. | ||
| 1354 | */ | ||
| 1355 | rt2x00dev->hw->conf.antenna_sel_tx = | ||
| 1356 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT); | ||
| 1357 | rt2x00dev->hw->conf.antenna_sel_rx = | ||
| 1358 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT); | ||
| 1359 | |||
| 1360 | /* | ||
| 1361 | * Store led mode, for correct led behaviour. | ||
| 1362 | */ | ||
| 1363 | rt2x00dev->led_mode = | ||
| 1364 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | ||
| 1365 | |||
| 1366 | /* | ||
| 1367 | * Check if the BBP tuning should be disabled. | ||
| 1368 | */ | ||
| 1369 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | ||
| 1370 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_DYN_BBP_TUNE)) | ||
| 1371 | __set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags); | ||
| 1372 | |||
| 1373 | /* | ||
| 1374 | * Read the RSSI <-> dBm offset information. | ||
| 1375 | */ | ||
| 1376 | rt2x00_eeprom_read(rt2x00dev, EEPROM_CALIBRATE_OFFSET, &eeprom); | ||
| 1377 | rt2x00dev->rssi_offset = | ||
| 1378 | rt2x00_get_field16(eeprom, EEPROM_CALIBRATE_OFFSET_RSSI); | ||
| 1379 | |||
| 1380 | return 0; | ||
| 1381 | } | ||
| 1382 | |||
| 1383 | /* | ||
| 1384 | * RF value list for RF2522 | ||
| 1385 | * Supports: 2.4 GHz | ||
| 1386 | */ | ||
| 1387 | static const struct rf_channel rf_vals_bg_2522[] = { | ||
| 1388 | { 1, 0x00002050, 0x000c1fda, 0x00000101, 0 }, | ||
| 1389 | { 2, 0x00002050, 0x000c1fee, 0x00000101, 0 }, | ||
| 1390 | { 3, 0x00002050, 0x000c2002, 0x00000101, 0 }, | ||
| 1391 | { 4, 0x00002050, 0x000c2016, 0x00000101, 0 }, | ||
| 1392 | { 5, 0x00002050, 0x000c202a, 0x00000101, 0 }, | ||
| 1393 | { 6, 0x00002050, 0x000c203e, 0x00000101, 0 }, | ||
| 1394 | { 7, 0x00002050, 0x000c2052, 0x00000101, 0 }, | ||
| 1395 | { 8, 0x00002050, 0x000c2066, 0x00000101, 0 }, | ||
| 1396 | { 9, 0x00002050, 0x000c207a, 0x00000101, 0 }, | ||
| 1397 | { 10, 0x00002050, 0x000c208e, 0x00000101, 0 }, | ||
| 1398 | { 11, 0x00002050, 0x000c20a2, 0x00000101, 0 }, | ||
| 1399 | { 12, 0x00002050, 0x000c20b6, 0x00000101, 0 }, | ||
| 1400 | { 13, 0x00002050, 0x000c20ca, 0x00000101, 0 }, | ||
| 1401 | { 14, 0x00002050, 0x000c20fa, 0x00000101, 0 }, | ||
| 1402 | }; | ||
| 1403 | |||
| 1404 | /* | ||
| 1405 | * RF value list for RF2523 | ||
| 1406 | * Supports: 2.4 GHz | ||
| 1407 | */ | ||
| 1408 | static const struct rf_channel rf_vals_bg_2523[] = { | ||
| 1409 | { 1, 0x00022010, 0x00000c9e, 0x000e0111, 0x00000a1b }, | ||
| 1410 | { 2, 0x00022010, 0x00000ca2, 0x000e0111, 0x00000a1b }, | ||
| 1411 | { 3, 0x00022010, 0x00000ca6, 0x000e0111, 0x00000a1b }, | ||
| 1412 | { 4, 0x00022010, 0x00000caa, 0x000e0111, 0x00000a1b }, | ||
| 1413 | { 5, 0x00022010, 0x00000cae, 0x000e0111, 0x00000a1b }, | ||
| 1414 | { 6, 0x00022010, 0x00000cb2, 0x000e0111, 0x00000a1b }, | ||
| 1415 | { 7, 0x00022010, 0x00000cb6, 0x000e0111, 0x00000a1b }, | ||
| 1416 | { 8, 0x00022010, 0x00000cba, 0x000e0111, 0x00000a1b }, | ||
| 1417 | { 9, 0x00022010, 0x00000cbe, 0x000e0111, 0x00000a1b }, | ||
| 1418 | { 10, 0x00022010, 0x00000d02, 0x000e0111, 0x00000a1b }, | ||
| 1419 | { 11, 0x00022010, 0x00000d06, 0x000e0111, 0x00000a1b }, | ||
| 1420 | { 12, 0x00022010, 0x00000d0a, 0x000e0111, 0x00000a1b }, | ||
| 1421 | { 13, 0x00022010, 0x00000d0e, 0x000e0111, 0x00000a1b }, | ||
| 1422 | { 14, 0x00022010, 0x00000d1a, 0x000e0111, 0x00000a03 }, | ||
| 1423 | }; | ||
| 1424 | |||
| 1425 | /* | ||
| 1426 | * RF value list for RF2524 | ||
| 1427 | * Supports: 2.4 GHz | ||
| 1428 | */ | ||
| 1429 | static const struct rf_channel rf_vals_bg_2524[] = { | ||
| 1430 | { 1, 0x00032020, 0x00000c9e, 0x00000101, 0x00000a1b }, | ||
| 1431 | { 2, 0x00032020, 0x00000ca2, 0x00000101, 0x00000a1b }, | ||
| 1432 | { 3, 0x00032020, 0x00000ca6, 0x00000101, 0x00000a1b }, | ||
| 1433 | { 4, 0x00032020, 0x00000caa, 0x00000101, 0x00000a1b }, | ||
| 1434 | { 5, 0x00032020, 0x00000cae, 0x00000101, 0x00000a1b }, | ||
| 1435 | { 6, 0x00032020, 0x00000cb2, 0x00000101, 0x00000a1b }, | ||
| 1436 | { 7, 0x00032020, 0x00000cb6, 0x00000101, 0x00000a1b }, | ||
| 1437 | { 8, 0x00032020, 0x00000cba, 0x00000101, 0x00000a1b }, | ||
| 1438 | { 9, 0x00032020, 0x00000cbe, 0x00000101, 0x00000a1b }, | ||
| 1439 | { 10, 0x00032020, 0x00000d02, 0x00000101, 0x00000a1b }, | ||
| 1440 | { 11, 0x00032020, 0x00000d06, 0x00000101, 0x00000a1b }, | ||
| 1441 | { 12, 0x00032020, 0x00000d0a, 0x00000101, 0x00000a1b }, | ||
| 1442 | { 13, 0x00032020, 0x00000d0e, 0x00000101, 0x00000a1b }, | ||
| 1443 | { 14, 0x00032020, 0x00000d1a, 0x00000101, 0x00000a03 }, | ||
| 1444 | }; | ||
| 1445 | |||
| 1446 | /* | ||
| 1447 | * RF value list for RF2525 | ||
| 1448 | * Supports: 2.4 GHz | ||
| 1449 | */ | ||
| 1450 | static const struct rf_channel rf_vals_bg_2525[] = { | ||
| 1451 | { 1, 0x00022020, 0x00080c9e, 0x00060111, 0x00000a1b }, | ||
| 1452 | { 2, 0x00022020, 0x00080ca2, 0x00060111, 0x00000a1b }, | ||
| 1453 | { 3, 0x00022020, 0x00080ca6, 0x00060111, 0x00000a1b }, | ||
| 1454 | { 4, 0x00022020, 0x00080caa, 0x00060111, 0x00000a1b }, | ||
| 1455 | { 5, 0x00022020, 0x00080cae, 0x00060111, 0x00000a1b }, | ||
| 1456 | { 6, 0x00022020, 0x00080cb2, 0x00060111, 0x00000a1b }, | ||
| 1457 | { 7, 0x00022020, 0x00080cb6, 0x00060111, 0x00000a1b }, | ||
| 1458 | { 8, 0x00022020, 0x00080cba, 0x00060111, 0x00000a1b }, | ||
| 1459 | { 9, 0x00022020, 0x00080cbe, 0x00060111, 0x00000a1b }, | ||
| 1460 | { 10, 0x00022020, 0x00080d02, 0x00060111, 0x00000a1b }, | ||
| 1461 | { 11, 0x00022020, 0x00080d06, 0x00060111, 0x00000a1b }, | ||
| 1462 | { 12, 0x00022020, 0x00080d0a, 0x00060111, 0x00000a1b }, | ||
| 1463 | { 13, 0x00022020, 0x00080d0e, 0x00060111, 0x00000a1b }, | ||
| 1464 | { 14, 0x00022020, 0x00080d1a, 0x00060111, 0x00000a03 }, | ||
| 1465 | }; | ||
| 1466 | |||
| 1467 | /* | ||
| 1468 | * RF value list for RF2525e | ||
| 1469 | * Supports: 2.4 GHz | ||
| 1470 | */ | ||
| 1471 | static const struct rf_channel rf_vals_bg_2525e[] = { | ||
| 1472 | { 1, 0x00022010, 0x0000089a, 0x00060111, 0x00000e1b }, | ||
| 1473 | { 2, 0x00022010, 0x0000089e, 0x00060111, 0x00000e07 }, | ||
| 1474 | { 3, 0x00022010, 0x0000089e, 0x00060111, 0x00000e1b }, | ||
| 1475 | { 4, 0x00022010, 0x000008a2, 0x00060111, 0x00000e07 }, | ||
| 1476 | { 5, 0x00022010, 0x000008a2, 0x00060111, 0x00000e1b }, | ||
| 1477 | { 6, 0x00022010, 0x000008a6, 0x00060111, 0x00000e07 }, | ||
| 1478 | { 7, 0x00022010, 0x000008a6, 0x00060111, 0x00000e1b }, | ||
| 1479 | { 8, 0x00022010, 0x000008aa, 0x00060111, 0x00000e07 }, | ||
| 1480 | { 9, 0x00022010, 0x000008aa, 0x00060111, 0x00000e1b }, | ||
| 1481 | { 10, 0x00022010, 0x000008ae, 0x00060111, 0x00000e07 }, | ||
| 1482 | { 11, 0x00022010, 0x000008ae, 0x00060111, 0x00000e1b }, | ||
| 1483 | { 12, 0x00022010, 0x000008b2, 0x00060111, 0x00000e07 }, | ||
| 1484 | { 13, 0x00022010, 0x000008b2, 0x00060111, 0x00000e1b }, | ||
| 1485 | { 14, 0x00022010, 0x000008b6, 0x00060111, 0x00000e23 }, | ||
| 1486 | }; | ||
| 1487 | |||
| 1488 | /* | ||
| 1489 | * RF value list for RF5222 | ||
| 1490 | * Supports: 2.4 GHz & 5.2 GHz | ||
| 1491 | */ | ||
| 1492 | static const struct rf_channel rf_vals_5222[] = { | ||
| 1493 | { 1, 0x00022020, 0x00001136, 0x00000101, 0x00000a0b }, | ||
| 1494 | { 2, 0x00022020, 0x0000113a, 0x00000101, 0x00000a0b }, | ||
| 1495 | { 3, 0x00022020, 0x0000113e, 0x00000101, 0x00000a0b }, | ||
| 1496 | { 4, 0x00022020, 0x00001182, 0x00000101, 0x00000a0b }, | ||
| 1497 | { 5, 0x00022020, 0x00001186, 0x00000101, 0x00000a0b }, | ||
| 1498 | { 6, 0x00022020, 0x0000118a, 0x00000101, 0x00000a0b }, | ||
| 1499 | { 7, 0x00022020, 0x0000118e, 0x00000101, 0x00000a0b }, | ||
| 1500 | { 8, 0x00022020, 0x00001192, 0x00000101, 0x00000a0b }, | ||
| 1501 | { 9, 0x00022020, 0x00001196, 0x00000101, 0x00000a0b }, | ||
| 1502 | { 10, 0x00022020, 0x0000119a, 0x00000101, 0x00000a0b }, | ||
| 1503 | { 11, 0x00022020, 0x0000119e, 0x00000101, 0x00000a0b }, | ||
| 1504 | { 12, 0x00022020, 0x000011a2, 0x00000101, 0x00000a0b }, | ||
| 1505 | { 13, 0x00022020, 0x000011a6, 0x00000101, 0x00000a0b }, | ||
| 1506 | { 14, 0x00022020, 0x000011ae, 0x00000101, 0x00000a1b }, | ||
| 1507 | |||
| 1508 | /* 802.11 UNI / HyperLan 2 */ | ||
| 1509 | { 36, 0x00022010, 0x00018896, 0x00000101, 0x00000a1f }, | ||
| 1510 | { 40, 0x00022010, 0x0001889a, 0x00000101, 0x00000a1f }, | ||
| 1511 | { 44, 0x00022010, 0x0001889e, 0x00000101, 0x00000a1f }, | ||
| 1512 | { 48, 0x00022010, 0x000188a2, 0x00000101, 0x00000a1f }, | ||
| 1513 | { 52, 0x00022010, 0x000188a6, 0x00000101, 0x00000a1f }, | ||
| 1514 | { 66, 0x00022010, 0x000188aa, 0x00000101, 0x00000a1f }, | ||
| 1515 | { 60, 0x00022010, 0x000188ae, 0x00000101, 0x00000a1f }, | ||
| 1516 | { 64, 0x00022010, 0x000188b2, 0x00000101, 0x00000a1f }, | ||
| 1517 | |||
| 1518 | /* 802.11 HyperLan 2 */ | ||
| 1519 | { 100, 0x00022010, 0x00008802, 0x00000101, 0x00000a0f }, | ||
| 1520 | { 104, 0x00022010, 0x00008806, 0x00000101, 0x00000a0f }, | ||
| 1521 | { 108, 0x00022010, 0x0000880a, 0x00000101, 0x00000a0f }, | ||
| 1522 | { 112, 0x00022010, 0x0000880e, 0x00000101, 0x00000a0f }, | ||
| 1523 | { 116, 0x00022010, 0x00008812, 0x00000101, 0x00000a0f }, | ||
| 1524 | { 120, 0x00022010, 0x00008816, 0x00000101, 0x00000a0f }, | ||
| 1525 | { 124, 0x00022010, 0x0000881a, 0x00000101, 0x00000a0f }, | ||
| 1526 | { 128, 0x00022010, 0x0000881e, 0x00000101, 0x00000a0f }, | ||
| 1527 | { 132, 0x00022010, 0x00008822, 0x00000101, 0x00000a0f }, | ||
| 1528 | { 136, 0x00022010, 0x00008826, 0x00000101, 0x00000a0f }, | ||
| 1529 | |||
| 1530 | /* 802.11 UNII */ | ||
| 1531 | { 140, 0x00022010, 0x0000882a, 0x00000101, 0x00000a0f }, | ||
| 1532 | { 149, 0x00022020, 0x000090a6, 0x00000101, 0x00000a07 }, | ||
| 1533 | { 153, 0x00022020, 0x000090ae, 0x00000101, 0x00000a07 }, | ||
| 1534 | { 157, 0x00022020, 0x000090b6, 0x00000101, 0x00000a07 }, | ||
| 1535 | { 161, 0x00022020, 0x000090be, 0x00000101, 0x00000a07 }, | ||
| 1536 | }; | ||
| 1537 | |||
| 1538 | static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | ||
| 1539 | { | ||
| 1540 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
| 1541 | u8 *txpower; | ||
| 1542 | unsigned int i; | ||
| 1543 | |||
| 1544 | /* | ||
| 1545 | * Initialize all hw fields. | ||
| 1546 | */ | ||
| 1547 | rt2x00dev->hw->flags = | ||
| 1548 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | ||
| 1549 | IEEE80211_HW_RX_INCLUDES_FCS | | ||
| 1550 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
| 1551 | IEEE80211_HW_MONITOR_DURING_OPER | | ||
| 1552 | IEEE80211_HW_NO_PROBE_FILTERING; | ||
| 1553 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | ||
| 1554 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | ||
| 1555 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | ||
| 1556 | rt2x00dev->hw->queues = 2; | ||
| 1557 | |||
| 1558 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | ||
| 1559 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | ||
| 1560 | rt2x00_eeprom_addr(rt2x00dev, | ||
| 1561 | EEPROM_MAC_ADDR_0)); | ||
| 1562 | |||
| 1563 | /* | ||
| 1564 | * Convert tx_power array in eeprom. | ||
| 1565 | */ | ||
| 1566 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); | ||
| 1567 | for (i = 0; i < 14; i++) | ||
| 1568 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | ||
| 1569 | |||
| 1570 | /* | ||
| 1571 | * Initialize hw_mode information. | ||
| 1572 | */ | ||
| 1573 | spec->num_modes = 2; | ||
| 1574 | spec->num_rates = 12; | ||
| 1575 | spec->tx_power_a = NULL; | ||
| 1576 | spec->tx_power_bg = txpower; | ||
| 1577 | spec->tx_power_default = DEFAULT_TXPOWER; | ||
| 1578 | |||
| 1579 | if (rt2x00_rf(&rt2x00dev->chip, RF2522)) { | ||
| 1580 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522); | ||
| 1581 | spec->channels = rf_vals_bg_2522; | ||
| 1582 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2523)) { | ||
| 1583 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2523); | ||
| 1584 | spec->channels = rf_vals_bg_2523; | ||
| 1585 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2524)) { | ||
| 1586 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2524); | ||
| 1587 | spec->channels = rf_vals_bg_2524; | ||
| 1588 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2525)) { | ||
| 1589 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525); | ||
| 1590 | spec->channels = rf_vals_bg_2525; | ||
| 1591 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) { | ||
| 1592 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); | ||
| 1593 | spec->channels = rf_vals_bg_2525e; | ||
| 1594 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { | ||
| 1595 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); | ||
| 1596 | spec->channels = rf_vals_5222; | ||
| 1597 | spec->num_modes = 3; | ||
| 1598 | } | ||
| 1599 | } | ||
| 1600 | |||
| 1601 | static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | ||
| 1602 | { | ||
| 1603 | int retval; | ||
| 1604 | |||
| 1605 | /* | ||
| 1606 | * Allocate eeprom data. | ||
| 1607 | */ | ||
| 1608 | retval = rt2500usb_validate_eeprom(rt2x00dev); | ||
| 1609 | if (retval) | ||
| 1610 | return retval; | ||
| 1611 | |||
| 1612 | retval = rt2500usb_init_eeprom(rt2x00dev); | ||
| 1613 | if (retval) | ||
| 1614 | return retval; | ||
| 1615 | |||
| 1616 | /* | ||
| 1617 | * Initialize hw specifications. | ||
| 1618 | */ | ||
| 1619 | rt2500usb_probe_hw_mode(rt2x00dev); | ||
| 1620 | |||
| 1621 | /* | ||
| 1622 | * USB devices require scheduled packet filter toggling | ||
| 1623 | *This device requires the beacon ring | ||
| 1624 | */ | ||
| 1625 | __set_bit(PACKET_FILTER_SCHEDULED, &rt2x00dev->flags); | ||
| 1626 | __set_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags); | ||
| 1627 | |||
| 1628 | /* | ||
| 1629 | * Set the rssi offset. | ||
| 1630 | */ | ||
| 1631 | rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET; | ||
| 1632 | |||
| 1633 | return 0; | ||
| 1634 | } | ||
| 1635 | |||
| 1636 | /* | ||
| 1637 | * IEEE80211 stack callback functions. | ||
| 1638 | */ | ||
| 1639 | static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | ||
| 1640 | struct sk_buff *skb, | ||
| 1641 | struct ieee80211_tx_control *control) | ||
| 1642 | { | ||
| 1643 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1644 | struct usb_device *usb_dev = | ||
| 1645 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | ||
| 1646 | struct data_ring *ring = | ||
| 1647 | rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
| 1648 | struct data_entry *beacon; | ||
| 1649 | struct data_entry *guardian; | ||
| 1650 | int length; | ||
| 1651 | |||
| 1652 | /* | ||
| 1653 | * Just in case the ieee80211 doesn't set this, | ||
| 1654 | * but we need this queue set for the descriptor | ||
| 1655 | * initialization. | ||
| 1656 | */ | ||
| 1657 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
| 1658 | |||
| 1659 | /* | ||
| 1660 | * Obtain 2 entries, one for the guardian byte, | ||
| 1661 | * the second for the actual beacon. | ||
| 1662 | */ | ||
| 1663 | guardian = rt2x00_get_data_entry(ring); | ||
| 1664 | rt2x00_ring_index_inc(ring); | ||
| 1665 | beacon = rt2x00_get_data_entry(ring); | ||
| 1666 | |||
| 1667 | /* | ||
| 1668 | * First we create the beacon. | ||
| 1669 | */ | ||
| 1670 | skb_push(skb, ring->desc_size); | ||
| 1671 | rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data, | ||
| 1672 | (struct ieee80211_hdr *)(skb->data + | ||
| 1673 | ring->desc_size), | ||
| 1674 | skb->len - ring->desc_size, control); | ||
| 1675 | |||
| 1676 | /* | ||
| 1677 | * Length passed to usb_fill_urb cannot be an odd number, | ||
| 1678 | * so add 1 byte to make it even. | ||
| 1679 | */ | ||
| 1680 | length = skb->len; | ||
| 1681 | if (length % 2) | ||
| 1682 | length++; | ||
| 1683 | |||
| 1684 | usb_fill_bulk_urb(beacon->priv, usb_dev, | ||
| 1685 | usb_sndbulkpipe(usb_dev, 1), | ||
| 1686 | skb->data, length, rt2500usb_beacondone, beacon); | ||
| 1687 | |||
| 1688 | beacon->skb = skb; | ||
| 1689 | |||
| 1690 | /* | ||
| 1691 | * Second we need to create the guardian byte. | ||
| 1692 | * We only need a single byte, so lets recycle | ||
| 1693 | * the 'flags' field we are not using for beacons. | ||
| 1694 | */ | ||
| 1695 | guardian->flags = 0; | ||
| 1696 | usb_fill_bulk_urb(guardian->priv, usb_dev, | ||
| 1697 | usb_sndbulkpipe(usb_dev, 1), | ||
| 1698 | &guardian->flags, 1, rt2500usb_beacondone, guardian); | ||
| 1699 | |||
| 1700 | /* | ||
| 1701 | * Send out the guardian byte. | ||
| 1702 | */ | ||
| 1703 | usb_submit_urb(guardian->priv, GFP_ATOMIC); | ||
| 1704 | |||
| 1705 | /* | ||
| 1706 | * Enable beacon generation. | ||
| 1707 | */ | ||
| 1708 | rt2500usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
| 1709 | |||
| 1710 | return 0; | ||
| 1711 | } | ||
| 1712 | |||
| 1713 | static const struct ieee80211_ops rt2500usb_mac80211_ops = { | ||
| 1714 | .tx = rt2x00mac_tx, | ||
| 1715 | .add_interface = rt2x00mac_add_interface, | ||
| 1716 | .remove_interface = rt2x00mac_remove_interface, | ||
| 1717 | .config = rt2x00mac_config, | ||
| 1718 | .config_interface = rt2x00mac_config_interface, | ||
| 1719 | .set_multicast_list = rt2x00mac_set_multicast_list, | ||
| 1720 | .get_stats = rt2x00mac_get_stats, | ||
| 1721 | .conf_tx = rt2x00mac_conf_tx, | ||
| 1722 | .get_tx_stats = rt2x00mac_get_tx_stats, | ||
| 1723 | .beacon_update = rt2500usb_beacon_update, | ||
| 1724 | }; | ||
| 1725 | |||
| 1726 | static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | ||
| 1727 | .probe_hw = rt2500usb_probe_hw, | ||
| 1728 | .initialize = rt2x00usb_initialize, | ||
| 1729 | .uninitialize = rt2x00usb_uninitialize, | ||
| 1730 | .set_device_state = rt2500usb_set_device_state, | ||
| 1731 | .link_stats = rt2500usb_link_stats, | ||
| 1732 | .reset_tuner = rt2500usb_reset_tuner, | ||
| 1733 | .link_tuner = rt2500usb_link_tuner, | ||
| 1734 | .write_tx_desc = rt2500usb_write_tx_desc, | ||
| 1735 | .write_tx_data = rt2x00usb_write_tx_data, | ||
| 1736 | .kick_tx_queue = rt2500usb_kick_tx_queue, | ||
| 1737 | .fill_rxdone = rt2500usb_fill_rxdone, | ||
| 1738 | .config_mac_addr = rt2500usb_config_mac_addr, | ||
| 1739 | .config_bssid = rt2500usb_config_bssid, | ||
| 1740 | .config_packet_filter = rt2500usb_config_packet_filter, | ||
| 1741 | .config_type = rt2500usb_config_type, | ||
| 1742 | .config = rt2500usb_config, | ||
| 1743 | }; | ||
| 1744 | |||
| 1745 | static const struct rt2x00_ops rt2500usb_ops = { | ||
| 1746 | .name = DRV_NAME, | ||
| 1747 | .rxd_size = RXD_DESC_SIZE, | ||
| 1748 | .txd_size = TXD_DESC_SIZE, | ||
| 1749 | .eeprom_size = EEPROM_SIZE, | ||
| 1750 | .rf_size = RF_SIZE, | ||
| 1751 | .lib = &rt2500usb_rt2x00_ops, | ||
| 1752 | .hw = &rt2500usb_mac80211_ops, | ||
| 1753 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
| 1754 | .debugfs = &rt2500usb_rt2x00debug, | ||
| 1755 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
| 1756 | }; | ||
| 1757 | |||
| 1758 | /* | ||
| 1759 | * rt2500usb module information. | ||
| 1760 | */ | ||
| 1761 | static struct usb_device_id rt2500usb_device_table[] = { | ||
| 1762 | /* ASUS */ | ||
| 1763 | { USB_DEVICE(0x0b05, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1764 | { USB_DEVICE(0x0b05, 0x1707), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1765 | /* Belkin */ | ||
| 1766 | { USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1767 | { USB_DEVICE(0x050d, 0x7051), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1768 | { USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1769 | /* Cisco Systems */ | ||
| 1770 | { USB_DEVICE(0x13b1, 0x000d), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1771 | { USB_DEVICE(0x13b1, 0x0011), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1772 | { USB_DEVICE(0x13b1, 0x001a), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1773 | /* Conceptronic */ | ||
| 1774 | { USB_DEVICE(0x14b2, 0x3c02), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1775 | /* D-LINK */ | ||
| 1776 | { USB_DEVICE(0x2001, 0x3c00), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1777 | /* Gigabyte */ | ||
| 1778 | { USB_DEVICE(0x1044, 0x8001), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1779 | { USB_DEVICE(0x1044, 0x8007), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1780 | /* Hercules */ | ||
| 1781 | { USB_DEVICE(0x06f8, 0xe000), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1782 | /* Melco */ | ||
| 1783 | { USB_DEVICE(0x0411, 0x0066), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1784 | { USB_DEVICE(0x0411, 0x0067), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1785 | { USB_DEVICE(0x0411, 0x008b), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1786 | { USB_DEVICE(0x0411, 0x0097), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1787 | |||
| 1788 | /* MSI */ | ||
| 1789 | { USB_DEVICE(0x0db0, 0x6861), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1790 | { USB_DEVICE(0x0db0, 0x6865), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1791 | { USB_DEVICE(0x0db0, 0x6869), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1792 | /* Ralink */ | ||
| 1793 | { USB_DEVICE(0x148f, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1794 | { USB_DEVICE(0x148f, 0x2570), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1795 | { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1796 | { USB_DEVICE(0x148f, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1797 | /* Siemens */ | ||
| 1798 | { USB_DEVICE(0x0681, 0x3c06), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1799 | /* SMC */ | ||
| 1800 | { USB_DEVICE(0x0707, 0xee13), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1801 | /* Spairon */ | ||
| 1802 | { USB_DEVICE(0x114b, 0x0110), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1803 | /* Trust */ | ||
| 1804 | { USB_DEVICE(0x0eb0, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1805 | /* Zinwell */ | ||
| 1806 | { USB_DEVICE(0x5a57, 0x0260), USB_DEVICE_DATA(&rt2500usb_ops) }, | ||
| 1807 | { 0, } | ||
| 1808 | }; | ||
| 1809 | |||
| 1810 | MODULE_AUTHOR(DRV_PROJECT); | ||
| 1811 | MODULE_VERSION(DRV_VERSION); | ||
| 1812 | MODULE_DESCRIPTION("Ralink RT2500 USB Wireless LAN driver."); | ||
| 1813 | MODULE_SUPPORTED_DEVICE("Ralink RT2570 USB chipset based cards"); | ||
| 1814 | MODULE_DEVICE_TABLE(usb, rt2500usb_device_table); | ||
| 1815 | MODULE_LICENSE("GPL"); | ||
| 1816 | |||
| 1817 | static struct usb_driver rt2500usb_driver = { | ||
| 1818 | .name = DRV_NAME, | ||
| 1819 | .id_table = rt2500usb_device_table, | ||
| 1820 | .probe = rt2x00usb_probe, | ||
| 1821 | .disconnect = rt2x00usb_disconnect, | ||
| 1822 | .suspend = rt2x00usb_suspend, | ||
| 1823 | .resume = rt2x00usb_resume, | ||
| 1824 | }; | ||
| 1825 | |||
| 1826 | static int __init rt2500usb_init(void) | ||
| 1827 | { | ||
| 1828 | return usb_register(&rt2500usb_driver); | ||
| 1829 | } | ||
| 1830 | |||
| 1831 | static void __exit rt2500usb_exit(void) | ||
| 1832 | { | ||
| 1833 | usb_deregister(&rt2500usb_driver); | ||
| 1834 | } | ||
| 1835 | |||
| 1836 | module_init(rt2500usb_init); | ||
| 1837 | module_exit(rt2500usb_exit); | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h new file mode 100644 index 00000000000..b18d56e73cf --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2500usb.h | |||
| @@ -0,0 +1,798 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2500usb | ||
| 23 | Abstract: Data structures and registers for the rt2500usb module. | ||
| 24 | Supported chipsets: RT2570. | ||
| 25 | */ | ||
| 26 | |||
| 27 | #ifndef RT2500USB_H | ||
| 28 | #define RT2500USB_H | ||
| 29 | |||
| 30 | /* | ||
| 31 | * RF chip defines. | ||
| 32 | */ | ||
| 33 | #define RF2522 0x0000 | ||
| 34 | #define RF2523 0x0001 | ||
| 35 | #define RF2524 0x0002 | ||
| 36 | #define RF2525 0x0003 | ||
| 37 | #define RF2525E 0x0005 | ||
| 38 | #define RF5222 0x0010 | ||
| 39 | |||
| 40 | /* | ||
| 41 | * RT2570 version | ||
| 42 | */ | ||
| 43 | #define RT2570_VERSION_B 2 | ||
| 44 | #define RT2570_VERSION_C 3 | ||
| 45 | #define RT2570_VERSION_D 4 | ||
| 46 | |||
| 47 | /* | ||
| 48 | * Signal information. | ||
| 49 | * Defaul offset is required for RSSI <-> dBm conversion. | ||
| 50 | */ | ||
| 51 | #define MAX_SIGNAL 100 | ||
| 52 | #define MAX_RX_SSI -1 | ||
| 53 | #define DEFAULT_RSSI_OFFSET 120 | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Register layout information. | ||
| 57 | */ | ||
| 58 | #define CSR_REG_BASE 0x0400 | ||
| 59 | #define CSR_REG_SIZE 0x0100 | ||
| 60 | #define EEPROM_BASE 0x0000 | ||
| 61 | #define EEPROM_SIZE 0x006a | ||
| 62 | #define BBP_SIZE 0x0060 | ||
| 63 | #define RF_SIZE 0x0014 | ||
| 64 | |||
| 65 | /* | ||
| 66 | * Control/Status Registers(CSR). | ||
| 67 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 68 | */ | ||
| 69 | |||
| 70 | /* | ||
| 71 | * MAC_CSR0: ASIC revision number. | ||
| 72 | */ | ||
| 73 | #define MAC_CSR0 0x0400 | ||
| 74 | |||
| 75 | /* | ||
| 76 | * MAC_CSR1: System control. | ||
| 77 | * SOFT_RESET: Software reset, 1: reset, 0: normal. | ||
| 78 | * BBP_RESET: Hardware reset, 1: reset, 0, release. | ||
| 79 | * HOST_READY: Host ready after initialization. | ||
| 80 | */ | ||
| 81 | #define MAC_CSR1 0x0402 | ||
| 82 | #define MAC_CSR1_SOFT_RESET FIELD16(0x00000001) | ||
| 83 | #define MAC_CSR1_BBP_RESET FIELD16(0x00000002) | ||
| 84 | #define MAC_CSR1_HOST_READY FIELD16(0x00000004) | ||
| 85 | |||
| 86 | /* | ||
| 87 | * MAC_CSR2: STA MAC register 0. | ||
| 88 | */ | ||
| 89 | #define MAC_CSR2 0x0404 | ||
| 90 | #define MAC_CSR2_BYTE0 FIELD16(0x00ff) | ||
| 91 | #define MAC_CSR2_BYTE1 FIELD16(0xff00) | ||
| 92 | |||
| 93 | /* | ||
| 94 | * MAC_CSR3: STA MAC register 1. | ||
| 95 | */ | ||
| 96 | #define MAC_CSR3 0x0406 | ||
| 97 | #define MAC_CSR3_BYTE2 FIELD16(0x00ff) | ||
| 98 | #define MAC_CSR3_BYTE3 FIELD16(0xff00) | ||
| 99 | |||
| 100 | /* | ||
| 101 | * MAC_CSR4: STA MAC register 2. | ||
| 102 | */ | ||
| 103 | #define MAC_CSR4 0X0408 | ||
| 104 | #define MAC_CSR4_BYTE4 FIELD16(0x00ff) | ||
| 105 | #define MAC_CSR4_BYTE5 FIELD16(0xff00) | ||
| 106 | |||
| 107 | /* | ||
| 108 | * MAC_CSR5: BSSID register 0. | ||
| 109 | */ | ||
| 110 | #define MAC_CSR5 0x040a | ||
| 111 | #define MAC_CSR5_BYTE0 FIELD16(0x00ff) | ||
| 112 | #define MAC_CSR5_BYTE1 FIELD16(0xff00) | ||
| 113 | |||
| 114 | /* | ||
| 115 | * MAC_CSR6: BSSID register 1. | ||
| 116 | */ | ||
| 117 | #define MAC_CSR6 0x040c | ||
| 118 | #define MAC_CSR6_BYTE2 FIELD16(0x00ff) | ||
| 119 | #define MAC_CSR6_BYTE3 FIELD16(0xff00) | ||
| 120 | |||
| 121 | /* | ||
| 122 | * MAC_CSR7: BSSID register 2. | ||
| 123 | */ | ||
| 124 | #define MAC_CSR7 0x040e | ||
| 125 | #define MAC_CSR7_BYTE4 FIELD16(0x00ff) | ||
| 126 | #define MAC_CSR7_BYTE5 FIELD16(0xff00) | ||
| 127 | |||
| 128 | /* | ||
| 129 | * MAC_CSR8: Max frame length. | ||
| 130 | */ | ||
| 131 | #define MAC_CSR8 0x0410 | ||
| 132 | #define MAC_CSR8_MAX_FRAME_UNIT FIELD16(0x0fff) | ||
| 133 | |||
| 134 | /* | ||
| 135 | * Misc MAC_CSR registers. | ||
| 136 | * MAC_CSR9: Timer control. | ||
| 137 | * MAC_CSR10: Slot time. | ||
| 138 | * MAC_CSR11: IFS. | ||
| 139 | * MAC_CSR12: EIFS. | ||
| 140 | * MAC_CSR13: Power mode0. | ||
| 141 | * MAC_CSR14: Power mode1. | ||
| 142 | * MAC_CSR15: Power saving transition0 | ||
| 143 | * MAC_CSR16: Power saving transition1 | ||
| 144 | */ | ||
| 145 | #define MAC_CSR9 0x0412 | ||
| 146 | #define MAC_CSR10 0x0414 | ||
| 147 | #define MAC_CSR11 0x0416 | ||
| 148 | #define MAC_CSR12 0x0418 | ||
| 149 | #define MAC_CSR13 0x041a | ||
| 150 | #define MAC_CSR14 0x041c | ||
| 151 | #define MAC_CSR15 0x041e | ||
| 152 | #define MAC_CSR16 0x0420 | ||
| 153 | |||
| 154 | /* | ||
| 155 | * MAC_CSR17: Manual power control / status register. | ||
| 156 | * Allowed state: 0 deep_sleep, 1: sleep, 2: standby, 3: awake. | ||
| 157 | * SET_STATE: Set state. Write 1 to trigger, self cleared. | ||
| 158 | * BBP_DESIRE_STATE: BBP desired state. | ||
| 159 | * RF_DESIRE_STATE: RF desired state. | ||
| 160 | * BBP_CURRENT_STATE: BBP current state. | ||
| 161 | * RF_CURRENT_STATE: RF current state. | ||
| 162 | * PUT_TO_SLEEP: Put to sleep. Write 1 to trigger, self cleared. | ||
| 163 | */ | ||
| 164 | #define MAC_CSR17 0x0422 | ||
| 165 | #define MAC_CSR17_SET_STATE FIELD16(0x0001) | ||
| 166 | #define MAC_CSR17_BBP_DESIRE_STATE FIELD16(0x0006) | ||
| 167 | #define MAC_CSR17_RF_DESIRE_STATE FIELD16(0x0018) | ||
| 168 | #define MAC_CSR17_BBP_CURR_STATE FIELD16(0x0060) | ||
| 169 | #define MAC_CSR17_RF_CURR_STATE FIELD16(0x0180) | ||
| 170 | #define MAC_CSR17_PUT_TO_SLEEP FIELD16(0x0200) | ||
| 171 | |||
| 172 | /* | ||
| 173 | * MAC_CSR18: Wakeup timer register. | ||
| 174 | * DELAY_AFTER_BEACON: Delay after Tbcn expired in units of 1/16 TU. | ||
| 175 | * BEACONS_BEFORE_WAKEUP: Number of beacon before wakeup. | ||
| 176 | * AUTO_WAKE: Enable auto wakeup / sleep mechanism. | ||
| 177 | */ | ||
| 178 | #define MAC_CSR18 0x0424 | ||
| 179 | #define MAC_CSR18_DELAY_AFTER_BEACON FIELD16(0x00ff) | ||
| 180 | #define MAC_CSR18_BEACONS_BEFORE_WAKEUP FIELD16(0x7f00) | ||
| 181 | #define MAC_CSR18_AUTO_WAKE FIELD16(0x8000) | ||
| 182 | |||
| 183 | /* | ||
| 184 | * MAC_CSR19: GPIO control register. | ||
| 185 | */ | ||
| 186 | #define MAC_CSR19 0x0426 | ||
| 187 | |||
| 188 | /* | ||
| 189 | * MAC_CSR20: LED control register. | ||
| 190 | * ACTIVITY: 0: idle, 1: active. | ||
| 191 | * LINK: 0: linkoff, 1: linkup. | ||
| 192 | * ACTIVITY_POLARITY: 0: active low, 1: active high. | ||
| 193 | */ | ||
| 194 | #define MAC_CSR20 0x0428 | ||
| 195 | #define MAC_CSR20_ACTIVITY FIELD16(0x0001) | ||
| 196 | #define MAC_CSR20_LINK FIELD16(0x0002) | ||
| 197 | #define MAC_CSR20_ACTIVITY_POLARITY FIELD16(0x0004) | ||
| 198 | |||
| 199 | /* | ||
| 200 | * MAC_CSR21: LED control register. | ||
| 201 | * ON_PERIOD: On period, default 70ms. | ||
| 202 | * OFF_PERIOD: Off period, default 30ms. | ||
| 203 | */ | ||
| 204 | #define MAC_CSR21 0x042a | ||
| 205 | #define MAC_CSR21_ON_PERIOD FIELD16(0x00ff) | ||
| 206 | #define MAC_CSR21_OFF_PERIOD FIELD16(0xff00) | ||
| 207 | |||
| 208 | /* | ||
| 209 | * Collision window control register. | ||
| 210 | */ | ||
| 211 | #define MAC_CSR22 0x042c | ||
| 212 | |||
| 213 | /* | ||
| 214 | * Transmit related CSRs. | ||
| 215 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 216 | */ | ||
| 217 | |||
| 218 | /* | ||
| 219 | * TXRX_CSR0: Security control register. | ||
| 220 | */ | ||
| 221 | #define TXRX_CSR0 0x0440 | ||
| 222 | #define TXRX_CSR0_ALGORITHM FIELD16(0x0007) | ||
| 223 | #define TXRX_CSR0_IV_OFFSET FIELD16(0x01f8) | ||
| 224 | #define TXRX_CSR0_KEY_ID FIELD16(0x1e00) | ||
| 225 | |||
| 226 | /* | ||
| 227 | * TXRX_CSR1: TX configuration. | ||
| 228 | * ACK_TIMEOUT: ACK Timeout in unit of 1-us. | ||
| 229 | * TSF_OFFSET: TSF offset in MAC header. | ||
| 230 | * AUTO_SEQUENCE: Let ASIC control frame sequence number. | ||
| 231 | */ | ||
| 232 | #define TXRX_CSR1 0x0442 | ||
| 233 | #define TXRX_CSR1_ACK_TIMEOUT FIELD16(0x00ff) | ||
| 234 | #define TXRX_CSR1_TSF_OFFSET FIELD16(0x7f00) | ||
| 235 | #define TXRX_CSR1_AUTO_SEQUENCE FIELD16(0x8000) | ||
| 236 | |||
| 237 | /* | ||
| 238 | * TXRX_CSR2: RX control. | ||
| 239 | * DISABLE_RX: Disable rx engine. | ||
| 240 | * DROP_CRC: Drop crc error. | ||
| 241 | * DROP_PHYSICAL: Drop physical error. | ||
| 242 | * DROP_CONTROL: Drop control frame. | ||
| 243 | * DROP_NOT_TO_ME: Drop not to me unicast frame. | ||
| 244 | * DROP_TODS: Drop frame tods bit is true. | ||
| 245 | * DROP_VERSION_ERROR: Drop version error frame. | ||
| 246 | * DROP_MCAST: Drop multicast frames. | ||
| 247 | * DROP_BCAST: Drop broadcast frames. | ||
| 248 | */ | ||
| 249 | #define TXRX_CSR2 0x0444 | ||
| 250 | #define TXRX_CSR2_DISABLE_RX FIELD16(0x0001) | ||
| 251 | #define TXRX_CSR2_DROP_CRC FIELD16(0x0002) | ||
| 252 | #define TXRX_CSR2_DROP_PHYSICAL FIELD16(0x0004) | ||
| 253 | #define TXRX_CSR2_DROP_CONTROL FIELD16(0x0008) | ||
| 254 | #define TXRX_CSR2_DROP_NOT_TO_ME FIELD16(0x0010) | ||
| 255 | #define TXRX_CSR2_DROP_TODS FIELD16(0x0020) | ||
| 256 | #define TXRX_CSR2_DROP_VERSION_ERROR FIELD16(0x0040) | ||
| 257 | #define TXRX_CSR2_DROP_MULTICAST FIELD16(0x0200) | ||
| 258 | #define TXRX_CSR2_DROP_BROADCAST FIELD16(0x0400) | ||
| 259 | |||
| 260 | /* | ||
| 261 | * RX BBP ID registers | ||
| 262 | * TXRX_CSR3: CCK RX BBP ID. | ||
| 263 | * TXRX_CSR4: OFDM RX BBP ID. | ||
| 264 | */ | ||
| 265 | #define TXRX_CSR3 0x0446 | ||
| 266 | #define TXRX_CSR4 0x0448 | ||
| 267 | |||
| 268 | /* | ||
| 269 | * TXRX_CSR5: CCK TX BBP ID0. | ||
| 270 | */ | ||
| 271 | #define TXRX_CSR5 0x044a | ||
| 272 | #define TXRX_CSR5_BBP_ID0 FIELD16(0x007f) | ||
| 273 | #define TXRX_CSR5_BBP_ID0_VALID FIELD16(0x0080) | ||
| 274 | #define TXRX_CSR5_BBP_ID1 FIELD16(0x7f00) | ||
| 275 | #define TXRX_CSR5_BBP_ID1_VALID FIELD16(0x8000) | ||
| 276 | |||
| 277 | /* | ||
| 278 | * TXRX_CSR6: CCK TX BBP ID1. | ||
| 279 | */ | ||
| 280 | #define TXRX_CSR6 0x044c | ||
| 281 | #define TXRX_CSR6_BBP_ID0 FIELD16(0x007f) | ||
| 282 | #define TXRX_CSR6_BBP_ID0_VALID FIELD16(0x0080) | ||
| 283 | #define TXRX_CSR6_BBP_ID1 FIELD16(0x7f00) | ||
| 284 | #define TXRX_CSR6_BBP_ID1_VALID FIELD16(0x8000) | ||
| 285 | |||
| 286 | /* | ||
| 287 | * TXRX_CSR7: OFDM TX BBP ID0. | ||
| 288 | */ | ||
| 289 | #define TXRX_CSR7 0x044e | ||
| 290 | #define TXRX_CSR7_BBP_ID0 FIELD16(0x007f) | ||
| 291 | #define TXRX_CSR7_BBP_ID0_VALID FIELD16(0x0080) | ||
| 292 | #define TXRX_CSR7_BBP_ID1 FIELD16(0x7f00) | ||
| 293 | #define TXRX_CSR7_BBP_ID1_VALID FIELD16(0x8000) | ||
| 294 | |||
| 295 | /* | ||
| 296 | * TXRX_CSR5: OFDM TX BBP ID1. | ||
| 297 | */ | ||
| 298 | #define TXRX_CSR8 0x0450 | ||
| 299 | #define TXRX_CSR8_BBP_ID0 FIELD16(0x007f) | ||
| 300 | #define TXRX_CSR8_BBP_ID0_VALID FIELD16(0x0080) | ||
| 301 | #define TXRX_CSR8_BBP_ID1 FIELD16(0x7f00) | ||
| 302 | #define TXRX_CSR8_BBP_ID1_VALID FIELD16(0x8000) | ||
| 303 | |||
| 304 | /* | ||
| 305 | * TXRX_CSR9: TX ACK time-out. | ||
| 306 | */ | ||
| 307 | #define TXRX_CSR9 0x0452 | ||
| 308 | |||
| 309 | /* | ||
| 310 | * TXRX_CSR10: Auto responder control. | ||
| 311 | */ | ||
| 312 | #define TXRX_CSR10 0x0454 | ||
| 313 | #define TXRX_CSR10_AUTORESPOND_PREAMBLE FIELD16(0x0004) | ||
| 314 | |||
| 315 | /* | ||
| 316 | * TXRX_CSR11: Auto responder basic rate. | ||
| 317 | */ | ||
| 318 | #define TXRX_CSR11 0x0456 | ||
| 319 | |||
| 320 | /* | ||
| 321 | * ACK/CTS time registers. | ||
| 322 | */ | ||
| 323 | #define TXRX_CSR12 0x0458 | ||
| 324 | #define TXRX_CSR13 0x045a | ||
| 325 | #define TXRX_CSR14 0x045c | ||
| 326 | #define TXRX_CSR15 0x045e | ||
| 327 | #define TXRX_CSR16 0x0460 | ||
| 328 | #define TXRX_CSR17 0x0462 | ||
| 329 | |||
| 330 | /* | ||
| 331 | * TXRX_CSR18: Synchronization control register. | ||
| 332 | */ | ||
| 333 | #define TXRX_CSR18 0x0464 | ||
| 334 | #define TXRX_CSR18_OFFSET FIELD16(0x000f) | ||
| 335 | #define TXRX_CSR18_INTERVAL FIELD16(0xfff0) | ||
| 336 | |||
| 337 | /* | ||
| 338 | * TXRX_CSR19: Synchronization control register. | ||
| 339 | * TSF_COUNT: Enable TSF auto counting. | ||
| 340 | * TSF_SYNC: Tsf sync, 0: disable, 1: infra, 2: ad-hoc/master mode. | ||
| 341 | * TBCN: Enable Tbcn with reload value. | ||
| 342 | * BEACON_GEN: Enable beacon generator. | ||
| 343 | */ | ||
| 344 | #define TXRX_CSR19 0x0466 | ||
| 345 | #define TXRX_CSR19_TSF_COUNT FIELD16(0x0001) | ||
| 346 | #define TXRX_CSR19_TSF_SYNC FIELD16(0x0006) | ||
| 347 | #define TXRX_CSR19_TBCN FIELD16(0x0008) | ||
| 348 | #define TXRX_CSR19_BEACON_GEN FIELD16(0x0010) | ||
| 349 | |||
| 350 | /* | ||
| 351 | * TXRX_CSR20: Tx BEACON offset time control register. | ||
| 352 | * OFFSET: In units of usec. | ||
| 353 | * BCN_EXPECT_WINDOW: Default: 2^CWmin | ||
| 354 | */ | ||
| 355 | #define TXRX_CSR20 0x0468 | ||
| 356 | #define TXRX_CSR20_OFFSET FIELD16(0x1fff) | ||
| 357 | #define TXRX_CSR20_BCN_EXPECT_WINDOW FIELD16(0xe000) | ||
| 358 | |||
| 359 | /* | ||
| 360 | * TXRX_CSR21 | ||
| 361 | */ | ||
| 362 | #define TXRX_CSR21 0x046a | ||
| 363 | |||
| 364 | /* | ||
| 365 | * Encryption related CSRs. | ||
| 366 | * | ||
| 367 | */ | ||
| 368 | |||
| 369 | /* | ||
| 370 | * SEC_CSR0-SEC_CSR7: Shared key 0, word 0-7 | ||
| 371 | */ | ||
| 372 | #define SEC_CSR0 0x0480 | ||
| 373 | #define SEC_CSR1 0x0482 | ||
| 374 | #define SEC_CSR2 0x0484 | ||
| 375 | #define SEC_CSR3 0x0486 | ||
| 376 | #define SEC_CSR4 0x0488 | ||
| 377 | #define SEC_CSR5 0x048a | ||
| 378 | #define SEC_CSR6 0x048c | ||
| 379 | #define SEC_CSR7 0x048e | ||
| 380 | |||
| 381 | /* | ||
| 382 | * SEC_CSR8-SEC_CSR15: Shared key 1, word 0-7 | ||
| 383 | */ | ||
| 384 | #define SEC_CSR8 0x0490 | ||
| 385 | #define SEC_CSR9 0x0492 | ||
| 386 | #define SEC_CSR10 0x0494 | ||
| 387 | #define SEC_CSR11 0x0496 | ||
| 388 | #define SEC_CSR12 0x0498 | ||
| 389 | #define SEC_CSR13 0x049a | ||
| 390 | #define SEC_CSR14 0x049c | ||
| 391 | #define SEC_CSR15 0x049e | ||
| 392 | |||
| 393 | /* | ||
| 394 | * SEC_CSR16-SEC_CSR23: Shared key 2, word 0-7 | ||
| 395 | */ | ||
| 396 | #define SEC_CSR16 0x04a0 | ||
| 397 | #define SEC_CSR17 0x04a2 | ||
| 398 | #define SEC_CSR18 0X04A4 | ||
| 399 | #define SEC_CSR19 0x04a6 | ||
| 400 | #define SEC_CSR20 0x04a8 | ||
| 401 | #define SEC_CSR21 0x04aa | ||
| 402 | #define SEC_CSR22 0x04ac | ||
| 403 | #define SEC_CSR23 0x04ae | ||
| 404 | |||
| 405 | /* | ||
| 406 | * SEC_CSR24-SEC_CSR31: Shared key 3, word 0-7 | ||
| 407 | */ | ||
| 408 | #define SEC_CSR24 0x04b0 | ||
| 409 | #define SEC_CSR25 0x04b2 | ||
| 410 | #define SEC_CSR26 0x04b4 | ||
| 411 | #define SEC_CSR27 0x04b6 | ||
| 412 | #define SEC_CSR28 0x04b8 | ||
| 413 | #define SEC_CSR29 0x04ba | ||
| 414 | #define SEC_CSR30 0x04bc | ||
| 415 | #define SEC_CSR31 0x04be | ||
| 416 | |||
| 417 | /* | ||
| 418 | * PHY control registers. | ||
| 419 | */ | ||
| 420 | |||
| 421 | /* | ||
| 422 | * PHY_CSR0: RF switching timing control. | ||
| 423 | */ | ||
| 424 | #define PHY_CSR0 0x04c0 | ||
| 425 | |||
| 426 | /* | ||
| 427 | * PHY_CSR1: TX PA configuration. | ||
| 428 | */ | ||
| 429 | #define PHY_CSR1 0x04c2 | ||
| 430 | |||
| 431 | /* | ||
| 432 | * MAC configuration registers. | ||
| 433 | * PHY_CSR2: TX MAC configuration. | ||
| 434 | * PHY_CSR3: RX MAC configuration. | ||
| 435 | */ | ||
| 436 | #define PHY_CSR2 0x04c4 | ||
| 437 | #define PHY_CSR3 0x04c6 | ||
| 438 | |||
| 439 | /* | ||
| 440 | * PHY_CSR4: Interface configuration. | ||
| 441 | */ | ||
| 442 | #define PHY_CSR4 0x04c8 | ||
| 443 | #define PHY_CSR4_LOW_RF_LE FIELD16(0x0001) | ||
| 444 | |||
| 445 | /* | ||
| 446 | * BBP pre-TX registers. | ||
| 447 | * PHY_CSR5: BBP pre-TX CCK. | ||
| 448 | */ | ||
| 449 | #define PHY_CSR5 0x04ca | ||
| 450 | #define PHY_CSR5_CCK FIELD16(0x0003) | ||
| 451 | #define PHY_CSR5_CCK_FLIP FIELD16(0x0004) | ||
| 452 | |||
| 453 | /* | ||
| 454 | * BBP pre-TX registers. | ||
| 455 | * PHY_CSR6: BBP pre-TX OFDM. | ||
| 456 | */ | ||
| 457 | #define PHY_CSR6 0x04cc | ||
| 458 | #define PHY_CSR6_OFDM FIELD16(0x0003) | ||
| 459 | #define PHY_CSR6_OFDM_FLIP FIELD16(0x0004) | ||
| 460 | |||
| 461 | /* | ||
| 462 | * PHY_CSR7: BBP access register 0. | ||
| 463 | * BBP_DATA: BBP data. | ||
| 464 | * BBP_REG_ID: BBP register ID. | ||
| 465 | * BBP_READ_CONTROL: 0: write, 1: read. | ||
| 466 | */ | ||
| 467 | #define PHY_CSR7 0x04ce | ||
| 468 | #define PHY_CSR7_DATA FIELD16(0x00ff) | ||
| 469 | #define PHY_CSR7_REG_ID FIELD16(0x7f00) | ||
| 470 | #define PHY_CSR7_READ_CONTROL FIELD16(0x8000) | ||
| 471 | |||
| 472 | /* | ||
| 473 | * PHY_CSR8: BBP access register 1. | ||
| 474 | * BBP_BUSY: ASIC is busy execute BBP programming. | ||
| 475 | */ | ||
| 476 | #define PHY_CSR8 0x04d0 | ||
| 477 | #define PHY_CSR8_BUSY FIELD16(0x0001) | ||
| 478 | |||
| 479 | /* | ||
| 480 | * PHY_CSR9: RF access register. | ||
| 481 | * RF_VALUE: Register value + id to program into rf/if. | ||
| 482 | */ | ||
| 483 | #define PHY_CSR9 0x04d2 | ||
| 484 | #define PHY_CSR9_RF_VALUE FIELD16(0xffff) | ||
| 485 | |||
| 486 | /* | ||
| 487 | * PHY_CSR10: RF access register. | ||
| 488 | * RF_VALUE: Register value + id to program into rf/if. | ||
| 489 | * RF_NUMBER_OF_BITS: Number of bits used in value (i:20, rfmd:22). | ||
| 490 | * RF_IF_SELECT: Chip to program: 0: rf, 1: if. | ||
| 491 | * RF_PLL_LD: Rf pll_ld status. | ||
| 492 | * RF_BUSY: 1: asic is busy execute rf programming. | ||
| 493 | */ | ||
| 494 | #define PHY_CSR10 0x04d4 | ||
| 495 | #define PHY_CSR10_RF_VALUE FIELD16(0x00ff) | ||
| 496 | #define PHY_CSR10_RF_NUMBER_OF_BITS FIELD16(0x1f00) | ||
| 497 | #define PHY_CSR10_RF_IF_SELECT FIELD16(0x2000) | ||
| 498 | #define PHY_CSR10_RF_PLL_LD FIELD16(0x4000) | ||
| 499 | #define PHY_CSR10_RF_BUSY FIELD16(0x8000) | ||
| 500 | |||
| 501 | /* | ||
| 502 | * STA_CSR0: FCS error count. | ||
| 503 | * FCS_ERROR: FCS error count, cleared when read. | ||
| 504 | */ | ||
| 505 | #define STA_CSR0 0x04e0 | ||
| 506 | #define STA_CSR0_FCS_ERROR FIELD16(0xffff) | ||
| 507 | |||
| 508 | /* | ||
| 509 | * STA_CSR1: PLCP error count. | ||
| 510 | */ | ||
| 511 | #define STA_CSR1 0x04e2 | ||
| 512 | |||
| 513 | /* | ||
| 514 | * STA_CSR2: LONG error count. | ||
| 515 | */ | ||
| 516 | #define STA_CSR2 0x04e4 | ||
| 517 | |||
| 518 | /* | ||
| 519 | * STA_CSR3: CCA false alarm. | ||
| 520 | * FALSE_CCA_ERROR: False CCA error count, cleared when read. | ||
| 521 | */ | ||
| 522 | #define STA_CSR3 0x04e6 | ||
| 523 | #define STA_CSR3_FALSE_CCA_ERROR FIELD16(0xffff) | ||
| 524 | |||
| 525 | /* | ||
| 526 | * STA_CSR4: RX FIFO overflow. | ||
| 527 | */ | ||
| 528 | #define STA_CSR4 0x04e8 | ||
| 529 | |||
| 530 | /* | ||
| 531 | * STA_CSR5: Beacon sent counter. | ||
| 532 | */ | ||
| 533 | #define STA_CSR5 0x04ea | ||
| 534 | |||
| 535 | /* | ||
| 536 | * Statistics registers | ||
| 537 | */ | ||
| 538 | #define STA_CSR6 0x04ec | ||
| 539 | #define STA_CSR7 0x04ee | ||
| 540 | #define STA_CSR8 0x04f0 | ||
| 541 | #define STA_CSR9 0x04f2 | ||
| 542 | #define STA_CSR10 0x04f4 | ||
| 543 | |||
| 544 | /* | ||
| 545 | * BBP registers. | ||
| 546 | * The wordsize of the BBP is 8 bits. | ||
| 547 | */ | ||
| 548 | |||
| 549 | /* | ||
| 550 | * R2: TX antenna control | ||
| 551 | */ | ||
| 552 | #define BBP_R2_TX_ANTENNA FIELD8(0x03) | ||
| 553 | #define BBP_R2_TX_IQ_FLIP FIELD8(0x04) | ||
| 554 | |||
| 555 | /* | ||
| 556 | * R14: RX antenna control | ||
| 557 | */ | ||
| 558 | #define BBP_R14_RX_ANTENNA FIELD8(0x03) | ||
| 559 | #define BBP_R14_RX_IQ_FLIP FIELD8(0x04) | ||
| 560 | |||
| 561 | /* | ||
| 562 | * RF registers. | ||
| 563 | */ | ||
| 564 | |||
| 565 | /* | ||
| 566 | * RF 1 | ||
| 567 | */ | ||
| 568 | #define RF1_TUNER FIELD32(0x00020000) | ||
| 569 | |||
| 570 | /* | ||
| 571 | * RF 3 | ||
| 572 | */ | ||
| 573 | #define RF3_TUNER FIELD32(0x00000100) | ||
| 574 | #define RF3_TXPOWER FIELD32(0x00003e00) | ||
| 575 | |||
| 576 | /* | ||
| 577 | * EEPROM contents. | ||
| 578 | */ | ||
| 579 | |||
| 580 | /* | ||
| 581 | * HW MAC address. | ||
| 582 | */ | ||
| 583 | #define EEPROM_MAC_ADDR_0 0x0002 | ||
| 584 | #define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff) | ||
| 585 | #define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00) | ||
| 586 | #define EEPROM_MAC_ADDR1 0x0003 | ||
| 587 | #define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff) | ||
| 588 | #define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00) | ||
| 589 | #define EEPROM_MAC_ADDR_2 0x0004 | ||
| 590 | #define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff) | ||
| 591 | #define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) | ||
| 592 | |||
| 593 | /* | ||
| 594 | * EEPROM antenna. | ||
| 595 | * ANTENNA_NUM: Number of antenna's. | ||
| 596 | * TX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B. | ||
| 597 | * RX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B. | ||
| 598 | * LED_MODE: 0: default, 1: TX/RX activity, 2: Single (ignore link), 3: rsvd. | ||
| 599 | * DYN_TXAGC: Dynamic TX AGC control. | ||
| 600 | * HARDWARE_RADIO: 1: Hardware controlled radio. Read GPIO0. | ||
| 601 | * RF_TYPE: Rf_type of this adapter. | ||
| 602 | */ | ||
| 603 | #define EEPROM_ANTENNA 0x000b | ||
| 604 | #define EEPROM_ANTENNA_NUM FIELD16(0x0003) | ||
| 605 | #define EEPROM_ANTENNA_TX_DEFAULT FIELD16(0x000c) | ||
| 606 | #define EEPROM_ANTENNA_RX_DEFAULT FIELD16(0x0030) | ||
| 607 | #define EEPROM_ANTENNA_LED_MODE FIELD16(0x01c0) | ||
| 608 | #define EEPROM_ANTENNA_DYN_TXAGC FIELD16(0x0200) | ||
| 609 | #define EEPROM_ANTENNA_HARDWARE_RADIO FIELD16(0x0400) | ||
| 610 | #define EEPROM_ANTENNA_RF_TYPE FIELD16(0xf800) | ||
| 611 | |||
| 612 | /* | ||
| 613 | * EEPROM NIC config. | ||
| 614 | * CARDBUS_ACCEL: 0: enable, 1: disable. | ||
| 615 | * DYN_BBP_TUNE: 0: enable, 1: disable. | ||
| 616 | * CCK_TX_POWER: CCK TX power compensation. | ||
| 617 | */ | ||
| 618 | #define EEPROM_NIC 0x000c | ||
| 619 | #define EEPROM_NIC_CARDBUS_ACCEL FIELD16(0x0001) | ||
| 620 | #define EEPROM_NIC_DYN_BBP_TUNE FIELD16(0x0002) | ||
| 621 | #define EEPROM_NIC_CCK_TX_POWER FIELD16(0x000c) | ||
| 622 | |||
| 623 | /* | ||
| 624 | * EEPROM geography. | ||
| 625 | * GEO: Default geography setting for device. | ||
| 626 | */ | ||
| 627 | #define EEPROM_GEOGRAPHY 0x000d | ||
| 628 | #define EEPROM_GEOGRAPHY_GEO FIELD16(0x0f00) | ||
| 629 | |||
| 630 | /* | ||
| 631 | * EEPROM BBP. | ||
| 632 | */ | ||
| 633 | #define EEPROM_BBP_START 0x000e | ||
| 634 | #define EEPROM_BBP_SIZE 16 | ||
| 635 | #define EEPROM_BBP_VALUE FIELD16(0x00ff) | ||
| 636 | #define EEPROM_BBP_REG_ID FIELD16(0xff00) | ||
| 637 | |||
| 638 | /* | ||
| 639 | * EEPROM TXPOWER | ||
| 640 | */ | ||
| 641 | #define EEPROM_TXPOWER_START 0x001e | ||
| 642 | #define EEPROM_TXPOWER_SIZE 7 | ||
| 643 | #define EEPROM_TXPOWER_1 FIELD16(0x00ff) | ||
| 644 | #define EEPROM_TXPOWER_2 FIELD16(0xff00) | ||
| 645 | |||
| 646 | /* | ||
| 647 | * EEPROM Tuning threshold | ||
| 648 | */ | ||
| 649 | #define EEPROM_BBPTUNE 0x0030 | ||
| 650 | #define EEPROM_BBPTUNE_THRESHOLD FIELD16(0x00ff) | ||
| 651 | |||
| 652 | /* | ||
| 653 | * EEPROM BBP R24 Tuning. | ||
| 654 | */ | ||
| 655 | #define EEPROM_BBPTUNE_R24 0x0031 | ||
| 656 | #define EEPROM_BBPTUNE_R24_LOW FIELD16(0x00ff) | ||
| 657 | #define EEPROM_BBPTUNE_R24_HIGH FIELD16(0xff00) | ||
| 658 | |||
| 659 | /* | ||
| 660 | * EEPROM BBP R25 Tuning. | ||
| 661 | */ | ||
| 662 | #define EEPROM_BBPTUNE_R25 0x0032 | ||
| 663 | #define EEPROM_BBPTUNE_R25_LOW FIELD16(0x00ff) | ||
| 664 | #define EEPROM_BBPTUNE_R25_HIGH FIELD16(0xff00) | ||
| 665 | |||
| 666 | /* | ||
| 667 | * EEPROM BBP R24 Tuning. | ||
| 668 | */ | ||
| 669 | #define EEPROM_BBPTUNE_R61 0x0033 | ||
| 670 | #define EEPROM_BBPTUNE_R61_LOW FIELD16(0x00ff) | ||
| 671 | #define EEPROM_BBPTUNE_R61_HIGH FIELD16(0xff00) | ||
| 672 | |||
| 673 | /* | ||
| 674 | * EEPROM BBP VGC Tuning. | ||
| 675 | */ | ||
| 676 | #define EEPROM_BBPTUNE_VGC 0x0034 | ||
| 677 | #define EEPROM_BBPTUNE_VGCUPPER FIELD16(0x00ff) | ||
| 678 | |||
| 679 | /* | ||
| 680 | * EEPROM BBP R17 Tuning. | ||
| 681 | */ | ||
| 682 | #define EEPROM_BBPTUNE_R17 0x0035 | ||
| 683 | #define EEPROM_BBPTUNE_R17_LOW FIELD16(0x00ff) | ||
| 684 | #define EEPROM_BBPTUNE_R17_HIGH FIELD16(0xff00) | ||
| 685 | |||
| 686 | /* | ||
| 687 | * RSSI <-> dBm offset calibration | ||
| 688 | */ | ||
| 689 | #define EEPROM_CALIBRATE_OFFSET 0x0036 | ||
| 690 | #define EEPROM_CALIBRATE_OFFSET_RSSI FIELD16(0x00ff) | ||
| 691 | |||
| 692 | /* | ||
| 693 | * DMA descriptor defines. | ||
| 694 | */ | ||
| 695 | #define TXD_DESC_SIZE ( 5 * sizeof(struct data_desc) ) | ||
| 696 | #define RXD_DESC_SIZE ( 4 * sizeof(struct data_desc) ) | ||
| 697 | |||
| 698 | /* | ||
| 699 | * TX descriptor format for TX, PRIO, ATIM and Beacon Ring. | ||
| 700 | */ | ||
| 701 | |||
| 702 | /* | ||
| 703 | * Word0 | ||
| 704 | */ | ||
| 705 | #define TXD_W0_PACKET_ID FIELD32(0x0000000f) | ||
| 706 | #define TXD_W0_RETRY_LIMIT FIELD32(0x000000f0) | ||
| 707 | #define TXD_W0_MORE_FRAG FIELD32(0x00000100) | ||
| 708 | #define TXD_W0_ACK FIELD32(0x00000200) | ||
| 709 | #define TXD_W0_TIMESTAMP FIELD32(0x00000400) | ||
| 710 | #define TXD_W0_OFDM FIELD32(0x00000800) | ||
| 711 | #define TXD_W0_NEW_SEQ FIELD32(0x00001000) | ||
| 712 | #define TXD_W0_IFS FIELD32(0x00006000) | ||
| 713 | #define TXD_W0_DATABYTE_COUNT FIELD32(0x0fff0000) | ||
| 714 | #define TXD_W0_CIPHER FIELD32(0x20000000) | ||
| 715 | #define TXD_W0_KEY_ID FIELD32(0xc0000000) | ||
| 716 | |||
| 717 | /* | ||
| 718 | * Word1 | ||
| 719 | */ | ||
| 720 | #define TXD_W1_IV_OFFSET FIELD32(0x0000003f) | ||
| 721 | #define TXD_W1_AIFS FIELD32(0x000000c0) | ||
| 722 | #define TXD_W1_CWMIN FIELD32(0x00000f00) | ||
| 723 | #define TXD_W1_CWMAX FIELD32(0x0000f000) | ||
| 724 | |||
| 725 | /* | ||
| 726 | * Word2: PLCP information | ||
| 727 | */ | ||
| 728 | #define TXD_W2_PLCP_SIGNAL FIELD32(0x000000ff) | ||
| 729 | #define TXD_W2_PLCP_SERVICE FIELD32(0x0000ff00) | ||
| 730 | #define TXD_W2_PLCP_LENGTH_LOW FIELD32(0x00ff0000) | ||
| 731 | #define TXD_W2_PLCP_LENGTH_HIGH FIELD32(0xff000000) | ||
| 732 | |||
| 733 | /* | ||
| 734 | * Word3 | ||
| 735 | */ | ||
| 736 | #define TXD_W3_IV FIELD32(0xffffffff) | ||
| 737 | |||
| 738 | /* | ||
| 739 | * Word4 | ||
| 740 | */ | ||
| 741 | #define TXD_W4_EIV FIELD32(0xffffffff) | ||
| 742 | |||
| 743 | /* | ||
| 744 | * RX descriptor format for RX Ring. | ||
| 745 | */ | ||
| 746 | |||
| 747 | /* | ||
| 748 | * Word0 | ||
| 749 | */ | ||
| 750 | #define RXD_W0_UNICAST_TO_ME FIELD32(0x00000002) | ||
| 751 | #define RXD_W0_MULTICAST FIELD32(0x00000004) | ||
| 752 | #define RXD_W0_BROADCAST FIELD32(0x00000008) | ||
| 753 | #define RXD_W0_MY_BSS FIELD32(0x00000010) | ||
| 754 | #define RXD_W0_CRC_ERROR FIELD32(0x00000020) | ||
| 755 | #define RXD_W0_OFDM FIELD32(0x00000040) | ||
| 756 | #define RXD_W0_PHYSICAL_ERROR FIELD32(0x00000080) | ||
| 757 | #define RXD_W0_CIPHER FIELD32(0x00000100) | ||
| 758 | #define RXD_W0_CIPHER_ERROR FIELD32(0x00000200) | ||
| 759 | #define RXD_W0_DATABYTE_COUNT FIELD32(0x0fff0000) | ||
| 760 | |||
| 761 | /* | ||
| 762 | * Word1 | ||
| 763 | */ | ||
| 764 | #define RXD_W1_RSSI FIELD32(0x000000ff) | ||
| 765 | #define RXD_W1_SIGNAL FIELD32(0x0000ff00) | ||
| 766 | |||
| 767 | /* | ||
| 768 | * Word2 | ||
| 769 | */ | ||
| 770 | #define RXD_W2_IV FIELD32(0xffffffff) | ||
| 771 | |||
| 772 | /* | ||
| 773 | * Word3 | ||
| 774 | */ | ||
| 775 | #define RXD_W3_EIV FIELD32(0xffffffff) | ||
| 776 | |||
| 777 | /* | ||
| 778 | * Macro's for converting txpower from EEPROM to dscape value | ||
| 779 | * and from dscape value to register value. | ||
| 780 | */ | ||
| 781 | #define MIN_TXPOWER 0 | ||
| 782 | #define MAX_TXPOWER 31 | ||
| 783 | #define DEFAULT_TXPOWER 24 | ||
| 784 | |||
| 785 | #define TXPOWER_FROM_DEV(__txpower) \ | ||
| 786 | ({ \ | ||
| 787 | ((__txpower) > MAX_TXPOWER) ? \ | ||
| 788 | DEFAULT_TXPOWER : (__txpower); \ | ||
| 789 | }) | ||
| 790 | |||
| 791 | #define TXPOWER_TO_DEV(__txpower) \ | ||
| 792 | ({ \ | ||
| 793 | ((__txpower) <= MIN_TXPOWER) ? MIN_TXPOWER : \ | ||
| 794 | (((__txpower) >= MAX_TXPOWER) ? MAX_TXPOWER : \ | ||
| 795 | (__txpower)); \ | ||
| 796 | }) | ||
| 797 | |||
| 798 | #endif /* RT2500USB_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h new file mode 100644 index 00000000000..80b079d723d --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
| @@ -0,0 +1,807 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00 | ||
| 23 | Abstract: rt2x00 global information. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #ifndef RT2X00_H | ||
| 27 | #define RT2X00_H | ||
| 28 | |||
| 29 | #include <linux/bitops.h> | ||
| 30 | #include <linux/prefetch.h> | ||
| 31 | #include <linux/skbuff.h> | ||
| 32 | #include <linux/workqueue.h> | ||
| 33 | #include <linux/firmware.h> | ||
| 34 | |||
| 35 | #include <net/mac80211.h> | ||
| 36 | |||
| 37 | #include "rt2x00debug.h" | ||
| 38 | #include "rt2x00reg.h" | ||
| 39 | #include "rt2x00ring.h" | ||
| 40 | |||
| 41 | /* | ||
| 42 | * Module information. | ||
| 43 | * DRV_NAME should be set within the individual module source files. | ||
| 44 | */ | ||
| 45 | #define DRV_VERSION "2.0.8" | ||
| 46 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" | ||
| 47 | |||
| 48 | /* | ||
| 49 | * Debug definitions. | ||
| 50 | * Debug output has to be enabled during compile time. | ||
| 51 | */ | ||
| 52 | #define DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, __args...) \ | ||
| 53 | printk(__kernlvl "%s -> %s: %s - " __msg, \ | ||
| 54 | wiphy_name((__dev)->hw->wiphy), __FUNCTION__, __lvl, ##__args) | ||
| 55 | |||
| 56 | #define DEBUG_PRINTK_PROBE(__kernlvl, __lvl, __msg, __args...) \ | ||
| 57 | printk(__kernlvl "%s -> %s: %s - " __msg, \ | ||
| 58 | DRV_NAME, __FUNCTION__, __lvl, ##__args) | ||
| 59 | |||
| 60 | #ifdef CONFIG_RT2X00_DEBUG | ||
| 61 | #define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ | ||
| 62 | DEBUG_PRINTK_MSG(__dev, __kernlvl, __lvl, __msg, ##__args); | ||
| 63 | #else | ||
| 64 | #define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ | ||
| 65 | do { } while (0) | ||
| 66 | #endif /* CONFIG_RT2X00_DEBUG */ | ||
| 67 | |||
| 68 | /* | ||
| 69 | * Various debug levels. | ||
| 70 | * The debug levels PANIC and ERROR both indicate serious problems, | ||
| 71 | * for this reason they should never be ignored. | ||
| 72 | * The special ERROR_PROBE message is for messages that are generated | ||
| 73 | * when the rt2x00_dev is not yet initialized. | ||
| 74 | */ | ||
| 75 | #define PANIC(__dev, __msg, __args...) \ | ||
| 76 | DEBUG_PRINTK_MSG(__dev, KERN_CRIT, "Panic", __msg, ##__args) | ||
| 77 | #define ERROR(__dev, __msg, __args...) \ | ||
| 78 | DEBUG_PRINTK_MSG(__dev, KERN_ERR, "Error", __msg, ##__args) | ||
| 79 | #define ERROR_PROBE(__msg, __args...) \ | ||
| 80 | DEBUG_PRINTK_PROBE(KERN_ERR, "Error", __msg, ##__args) | ||
| 81 | #define WARNING(__dev, __msg, __args...) \ | ||
| 82 | DEBUG_PRINTK(__dev, KERN_WARNING, "Warning", __msg, ##__args) | ||
| 83 | #define NOTICE(__dev, __msg, __args...) \ | ||
| 84 | DEBUG_PRINTK(__dev, KERN_NOTICE, "Notice", __msg, ##__args) | ||
| 85 | #define INFO(__dev, __msg, __args...) \ | ||
| 86 | DEBUG_PRINTK(__dev, KERN_INFO, "Info", __msg, ##__args) | ||
| 87 | #define DEBUG(__dev, __msg, __args...) \ | ||
| 88 | DEBUG_PRINTK(__dev, KERN_DEBUG, "Debug", __msg, ##__args) | ||
| 89 | #define EEPROM(__dev, __msg, __args...) \ | ||
| 90 | DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args) | ||
| 91 | |||
| 92 | /* | ||
| 93 | * Ring sizes. | ||
| 94 | * Ralink PCI devices demand the Frame size to be a multiple of 128 bytes. | ||
| 95 | * DATA_FRAME_SIZE is used for TX, RX, ATIM and PRIO rings. | ||
| 96 | * MGMT_FRAME_SIZE is used for the BEACON ring. | ||
| 97 | */ | ||
| 98 | #define DATA_FRAME_SIZE 2432 | ||
| 99 | #define MGMT_FRAME_SIZE 256 | ||
| 100 | |||
| 101 | /* | ||
| 102 | * Number of entries in a packet ring. | ||
| 103 | * PCI devices only need 1 Beacon entry, | ||
| 104 | * but USB devices require a second because they | ||
| 105 | * have to send a Guardian byte first. | ||
| 106 | */ | ||
| 107 | #define RX_ENTRIES 12 | ||
| 108 | #define TX_ENTRIES 12 | ||
| 109 | #define ATIM_ENTRIES 1 | ||
| 110 | #define BEACON_ENTRIES 2 | ||
| 111 | |||
| 112 | /* | ||
| 113 | * Standard timing and size defines. | ||
| 114 | * These values should follow the ieee80211 specifications. | ||
| 115 | */ | ||
| 116 | #define ACK_SIZE 14 | ||
| 117 | #define IEEE80211_HEADER 24 | ||
| 118 | #define PLCP 48 | ||
| 119 | #define BEACON 100 | ||
| 120 | #define PREAMBLE 144 | ||
| 121 | #define SHORT_PREAMBLE 72 | ||
| 122 | #define SLOT_TIME 20 | ||
| 123 | #define SHORT_SLOT_TIME 9 | ||
| 124 | #define SIFS 10 | ||
| 125 | #define PIFS ( SIFS + SLOT_TIME ) | ||
| 126 | #define SHORT_PIFS ( SIFS + SHORT_SLOT_TIME ) | ||
| 127 | #define DIFS ( PIFS + SLOT_TIME ) | ||
| 128 | #define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME ) | ||
| 129 | #define EIFS ( SIFS + (8 * (IEEE80211_HEADER + ACK_SIZE)) ) | ||
| 130 | |||
| 131 | /* | ||
| 132 | * IEEE802.11 header defines | ||
| 133 | */ | ||
| 134 | static inline int is_rts_frame(u16 fc) | ||
| 135 | { | ||
| 136 | return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && | ||
| 137 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_RTS)); | ||
| 138 | } | ||
| 139 | |||
| 140 | static inline int is_cts_frame(u16 fc) | ||
| 141 | { | ||
| 142 | return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && | ||
| 143 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_CTS)); | ||
| 144 | } | ||
| 145 | |||
| 146 | static inline int is_probe_resp(u16 fc) | ||
| 147 | { | ||
| 148 | return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
| 149 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)); | ||
| 150 | } | ||
| 151 | |||
| 152 | /* | ||
| 153 | * Chipset identification | ||
| 154 | * The chipset on the device is composed of a RT and RF chip. | ||
| 155 | * The chipset combination is important for determining device capabilities. | ||
| 156 | */ | ||
| 157 | struct rt2x00_chip { | ||
| 158 | u16 rt; | ||
| 159 | #define RT2460 0x0101 | ||
| 160 | #define RT2560 0x0201 | ||
| 161 | #define RT2570 0x1201 | ||
| 162 | #define RT2561 0x0301 | ||
| 163 | #define RT2561s 0x0302 | ||
| 164 | #define RT2661 0x0401 | ||
| 165 | #define RT2571 0x1300 | ||
| 166 | |||
| 167 | u16 rf; | ||
| 168 | u32 rev; | ||
| 169 | }; | ||
| 170 | |||
| 171 | /* | ||
| 172 | * RF register values that belong to a particular channel. | ||
| 173 | */ | ||
| 174 | struct rf_channel { | ||
| 175 | int channel; | ||
| 176 | u32 rf1; | ||
| 177 | u32 rf2; | ||
| 178 | u32 rf3; | ||
| 179 | u32 rf4; | ||
| 180 | }; | ||
| 181 | |||
| 182 | /* | ||
| 183 | * To optimize the quality of the link we need to store | ||
| 184 | * the quality of received frames and periodically | ||
| 185 | * optimize the link. | ||
| 186 | */ | ||
| 187 | struct link { | ||
| 188 | /* | ||
| 189 | * Link tuner counter | ||
| 190 | * The number of times the link has been tuned | ||
| 191 | * since the radio has been switched on. | ||
| 192 | */ | ||
| 193 | u32 count; | ||
| 194 | |||
| 195 | /* | ||
| 196 | * Statistics required for Link tuning. | ||
| 197 | * For the average RSSI value we use the "Walking average" approach. | ||
| 198 | * When adding RSSI to the average value the following calculation | ||
| 199 | * is needed: | ||
| 200 | * | ||
| 201 | * avg_rssi = ((avg_rssi * 7) + rssi) / 8; | ||
| 202 | * | ||
| 203 | * The advantage of this approach is that we only need 1 variable | ||
| 204 | * to store the average in (No need for a count and a total). | ||
| 205 | * But more importantly, normal average values will over time | ||
| 206 | * move less and less towards newly added values this results | ||
| 207 | * that with link tuning, the device can have a very good RSSI | ||
| 208 | * for a few minutes but when the device is moved away from the AP | ||
| 209 | * the average will not decrease fast enough to compensate. | ||
| 210 | * The walking average compensates this and will move towards | ||
| 211 | * the new values correctly allowing a effective link tuning. | ||
| 212 | */ | ||
| 213 | int avg_rssi; | ||
| 214 | int vgc_level; | ||
| 215 | int false_cca; | ||
| 216 | |||
| 217 | /* | ||
| 218 | * Statistics required for Signal quality calculation. | ||
| 219 | * For calculating the Signal quality we have to determine | ||
| 220 | * the total number of success and failed RX and TX frames. | ||
| 221 | * After that we also use the average RSSI value to help | ||
| 222 | * determining the signal quality. | ||
| 223 | * For the calculation we will use the following algorithm: | ||
| 224 | * | ||
| 225 | * rssi_percentage = (avg_rssi * 100) / rssi_offset | ||
| 226 | * rx_percentage = (rx_success * 100) / rx_total | ||
| 227 | * tx_percentage = (tx_success * 100) / tx_total | ||
| 228 | * avg_signal = ((WEIGHT_RSSI * avg_rssi) + | ||
| 229 | * (WEIGHT_TX * tx_percentage) + | ||
| 230 | * (WEIGHT_RX * rx_percentage)) / 100 | ||
| 231 | * | ||
| 232 | * This value should then be checked to not be greated then 100. | ||
| 233 | */ | ||
| 234 | int rx_percentage; | ||
| 235 | int rx_success; | ||
| 236 | int rx_failed; | ||
| 237 | int tx_percentage; | ||
| 238 | int tx_success; | ||
| 239 | int tx_failed; | ||
| 240 | #define WEIGHT_RSSI 20 | ||
| 241 | #define WEIGHT_RX 40 | ||
| 242 | #define WEIGHT_TX 40 | ||
| 243 | |||
| 244 | /* | ||
| 245 | * Work structure for scheduling periodic link tuning. | ||
| 246 | */ | ||
| 247 | struct delayed_work work; | ||
| 248 | }; | ||
| 249 | |||
| 250 | /* | ||
| 251 | * Clear all counters inside the link structure. | ||
| 252 | * This can be easiest achieved by memsetting everything | ||
| 253 | * except for the work structure at the end. | ||
| 254 | */ | ||
| 255 | static inline void rt2x00_clear_link(struct link *link) | ||
| 256 | { | ||
| 257 | memset(link, 0x00, sizeof(*link) - sizeof(link->work)); | ||
| 258 | link->rx_percentage = 50; | ||
| 259 | link->tx_percentage = 50; | ||
| 260 | } | ||
| 261 | |||
| 262 | /* | ||
| 263 | * Update the rssi using the walking average approach. | ||
| 264 | */ | ||
| 265 | static inline void rt2x00_update_link_rssi(struct link *link, int rssi) | ||
| 266 | { | ||
| 267 | if (!link->avg_rssi) | ||
| 268 | link->avg_rssi = rssi; | ||
| 269 | else | ||
| 270 | link->avg_rssi = ((link->avg_rssi * 7) + rssi) / 8; | ||
| 271 | } | ||
| 272 | |||
| 273 | /* | ||
| 274 | * When the avg_rssi is unset or no frames have been received), | ||
| 275 | * we need to return the default value which needs to be less | ||
| 276 | * than -80 so the device will select the maximum sensitivity. | ||
| 277 | */ | ||
| 278 | static inline int rt2x00_get_link_rssi(struct link *link) | ||
| 279 | { | ||
| 280 | return (link->avg_rssi && link->rx_success) ? link->avg_rssi : -128; | ||
| 281 | } | ||
| 282 | |||
| 283 | /* | ||
| 284 | * Interface structure | ||
| 285 | * Configuration details about the current interface. | ||
| 286 | */ | ||
| 287 | struct interface { | ||
| 288 | /* | ||
| 289 | * Interface identification. The value is assigned | ||
| 290 | * to us by the 80211 stack, and is used to request | ||
| 291 | * new beacons. | ||
| 292 | */ | ||
| 293 | int id; | ||
| 294 | |||
| 295 | /* | ||
| 296 | * Current working type (IEEE80211_IF_TYPE_*). | ||
| 297 | * This excludes the type IEEE80211_IF_TYPE_MNTR | ||
| 298 | * since that is counted seperately in the monitor_count | ||
| 299 | * field. | ||
| 300 | * When set to INVALID_INTERFACE, no interface is configured. | ||
| 301 | */ | ||
| 302 | int type; | ||
| 303 | #define INVALID_INTERFACE IEEE80211_IF_TYPE_MGMT | ||
| 304 | |||
| 305 | /* | ||
| 306 | * MAC of the device. | ||
| 307 | */ | ||
| 308 | u8 mac[ETH_ALEN]; | ||
| 309 | |||
| 310 | /* | ||
| 311 | * BBSID of the AP to associate with. | ||
| 312 | */ | ||
| 313 | u8 bssid[ETH_ALEN]; | ||
| 314 | |||
| 315 | /* | ||
| 316 | * Store the packet filter mode for the current interface. | ||
| 317 | * monitor mode always disabled filtering. But in such | ||
| 318 | * cases we still need to store the value here in case | ||
| 319 | * the monitor mode interfaces are removed, while a | ||
| 320 | * non-monitor mode interface remains. | ||
| 321 | */ | ||
| 322 | unsigned short filter; | ||
| 323 | |||
| 324 | /* | ||
| 325 | * Monitor mode count, the number of interfaces | ||
| 326 | * in monitor mode that that have been added. | ||
| 327 | */ | ||
| 328 | unsigned short monitor_count; | ||
| 329 | }; | ||
| 330 | |||
| 331 | static inline int is_interface_present(struct interface *intf) | ||
| 332 | { | ||
| 333 | return !!intf->id; | ||
| 334 | } | ||
| 335 | |||
| 336 | static inline int is_monitor_present(struct interface *intf) | ||
| 337 | { | ||
| 338 | return !!intf->monitor_count; | ||
| 339 | } | ||
| 340 | |||
| 341 | /* | ||
| 342 | * Details about the supported modes, rates and channels | ||
| 343 | * of a particular chipset. This is used by rt2x00lib | ||
| 344 | * to build the ieee80211_hw_mode array for mac80211. | ||
| 345 | */ | ||
| 346 | struct hw_mode_spec { | ||
| 347 | /* | ||
| 348 | * Number of modes, rates and channels. | ||
| 349 | */ | ||
| 350 | int num_modes; | ||
| 351 | int num_rates; | ||
| 352 | int num_channels; | ||
| 353 | |||
| 354 | /* | ||
| 355 | * txpower values. | ||
| 356 | */ | ||
| 357 | const u8 *tx_power_a; | ||
| 358 | const u8 *tx_power_bg; | ||
| 359 | u8 tx_power_default; | ||
| 360 | |||
| 361 | /* | ||
| 362 | * Device/chipset specific value. | ||
| 363 | */ | ||
| 364 | const struct rf_channel *channels; | ||
| 365 | }; | ||
| 366 | |||
| 367 | /* | ||
| 368 | * rt2x00lib callback functions. | ||
| 369 | */ | ||
| 370 | struct rt2x00lib_ops { | ||
| 371 | /* | ||
| 372 | * Interrupt handlers. | ||
| 373 | */ | ||
| 374 | irq_handler_t irq_handler; | ||
| 375 | |||
| 376 | /* | ||
| 377 | * Device init handlers. | ||
| 378 | */ | ||
| 379 | int (*probe_hw) (struct rt2x00_dev *rt2x00dev); | ||
| 380 | char *(*get_firmware_name) (struct rt2x00_dev *rt2x00dev); | ||
| 381 | int (*load_firmware) (struct rt2x00_dev *rt2x00dev, void *data, | ||
| 382 | const size_t len); | ||
| 383 | |||
| 384 | /* | ||
| 385 | * Device initialization/deinitialization handlers. | ||
| 386 | */ | ||
| 387 | int (*initialize) (struct rt2x00_dev *rt2x00dev); | ||
| 388 | void (*uninitialize) (struct rt2x00_dev *rt2x00dev); | ||
| 389 | |||
| 390 | /* | ||
| 391 | * Radio control handlers. | ||
| 392 | */ | ||
| 393 | int (*set_device_state) (struct rt2x00_dev *rt2x00dev, | ||
| 394 | enum dev_state state); | ||
| 395 | int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev); | ||
| 396 | void (*link_stats) (struct rt2x00_dev *rt2x00dev); | ||
| 397 | void (*reset_tuner) (struct rt2x00_dev *rt2x00dev); | ||
| 398 | void (*link_tuner) (struct rt2x00_dev *rt2x00dev); | ||
| 399 | |||
| 400 | /* | ||
| 401 | * TX control handlers | ||
| 402 | */ | ||
| 403 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, | ||
| 404 | struct data_desc *txd, | ||
| 405 | struct data_entry_desc *desc, | ||
| 406 | struct ieee80211_hdr *ieee80211hdr, | ||
| 407 | unsigned int length, | ||
| 408 | struct ieee80211_tx_control *control); | ||
| 409 | int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, | ||
| 410 | struct data_ring *ring, struct sk_buff *skb, | ||
| 411 | struct ieee80211_tx_control *control); | ||
| 412 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, | ||
| 413 | unsigned int queue); | ||
| 414 | |||
| 415 | /* | ||
| 416 | * RX control handlers | ||
| 417 | */ | ||
| 418 | int (*fill_rxdone) (struct data_entry *entry, | ||
| 419 | int *signal, int *rssi, int *ofdm, int *size); | ||
| 420 | |||
| 421 | /* | ||
| 422 | * Configuration handlers. | ||
| 423 | */ | ||
| 424 | void (*config_mac_addr) (struct rt2x00_dev *rt2x00dev, u8 *mac); | ||
| 425 | void (*config_bssid) (struct rt2x00_dev *rt2x00dev, u8 *bssid); | ||
| 426 | void (*config_packet_filter) (struct rt2x00_dev *rt2x00dev, | ||
| 427 | const unsigned int filter); | ||
| 428 | void (*config_type) (struct rt2x00_dev *rt2x00dev, const int type); | ||
| 429 | void (*config) (struct rt2x00_dev *rt2x00dev, const unsigned int flags, | ||
| 430 | struct ieee80211_conf *conf); | ||
| 431 | #define CONFIG_UPDATE_PHYMODE ( 1 << 1 ) | ||
| 432 | #define CONFIG_UPDATE_CHANNEL ( 1 << 2 ) | ||
| 433 | #define CONFIG_UPDATE_TXPOWER ( 1 << 3 ) | ||
| 434 | #define CONFIG_UPDATE_ANTENNA ( 1 << 4 ) | ||
| 435 | #define CONFIG_UPDATE_SLOT_TIME ( 1 << 5 ) | ||
| 436 | #define CONFIG_UPDATE_BEACON_INT ( 1 << 6 ) | ||
| 437 | #define CONFIG_UPDATE_ALL 0xffff | ||
| 438 | }; | ||
| 439 | |||
| 440 | /* | ||
| 441 | * rt2x00 driver callback operation structure. | ||
| 442 | */ | ||
| 443 | struct rt2x00_ops { | ||
| 444 | const char *name; | ||
| 445 | const unsigned int rxd_size; | ||
| 446 | const unsigned int txd_size; | ||
| 447 | const unsigned int eeprom_size; | ||
| 448 | const unsigned int rf_size; | ||
| 449 | const struct rt2x00lib_ops *lib; | ||
| 450 | const struct ieee80211_ops *hw; | ||
| 451 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
| 452 | const struct rt2x00debug *debugfs; | ||
| 453 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
| 454 | }; | ||
| 455 | |||
| 456 | /* | ||
| 457 | * rt2x00 device structure. | ||
| 458 | */ | ||
| 459 | struct rt2x00_dev { | ||
| 460 | /* | ||
| 461 | * Device structure. | ||
| 462 | * The structure stored in here depends on the | ||
| 463 | * system bus (PCI or USB). | ||
| 464 | * When accessing this variable, the rt2x00dev_{pci,usb} | ||
| 465 | * macro's should be used for correct typecasting. | ||
| 466 | */ | ||
| 467 | void *dev; | ||
| 468 | #define rt2x00dev_pci(__dev) ( (struct pci_dev*)(__dev)->dev ) | ||
| 469 | #define rt2x00dev_usb(__dev) ( (struct usb_interface*)(__dev)->dev ) | ||
| 470 | |||
| 471 | /* | ||
| 472 | * Callback functions. | ||
| 473 | */ | ||
| 474 | const struct rt2x00_ops *ops; | ||
| 475 | |||
| 476 | /* | ||
| 477 | * IEEE80211 control structure. | ||
| 478 | */ | ||
| 479 | struct ieee80211_hw *hw; | ||
| 480 | struct ieee80211_hw_mode *hwmodes; | ||
| 481 | unsigned int curr_hwmode; | ||
| 482 | #define HWMODE_B 0 | ||
| 483 | #define HWMODE_G 1 | ||
| 484 | #define HWMODE_A 2 | ||
| 485 | |||
| 486 | /* | ||
| 487 | * rfkill structure for RF state switching support. | ||
| 488 | * This will only be compiled in when required. | ||
| 489 | */ | ||
| 490 | #ifdef CONFIG_RT2X00_LIB_RFKILL | ||
| 491 | struct rfkill *rfkill; | ||
| 492 | struct input_polled_dev *poll_dev; | ||
| 493 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ | ||
| 494 | |||
| 495 | /* | ||
| 496 | * If enabled, the debugfs interface structures | ||
| 497 | * required for deregistration of debugfs. | ||
| 498 | */ | ||
| 499 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
| 500 | const struct rt2x00debug_intf *debugfs_intf; | ||
| 501 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
| 502 | |||
| 503 | /* | ||
| 504 | * Device flags. | ||
| 505 | * In these flags the current status and some | ||
| 506 | * of the device capabilities are stored. | ||
| 507 | */ | ||
| 508 | unsigned long flags; | ||
| 509 | #define DEVICE_ENABLED_RADIO 1 | ||
| 510 | #define DEVICE_ENABLED_RADIO_HW 2 | ||
| 511 | #define DEVICE_INITIALIZED 3 | ||
| 512 | #define DEVICE_INITIALIZED_HW 4 | ||
| 513 | #define REQUIRE_FIRMWARE 5 | ||
| 514 | #define PACKET_FILTER_SCHEDULED 6 | ||
| 515 | #define PACKET_FILTER_PENDING 7 | ||
| 516 | #define INTERFACE_RESUME 8 | ||
| 517 | #define INTERFACE_ENABLED 9 | ||
| 518 | #define INTERFACE_ENABLED_MONITOR 10 | ||
| 519 | #define REQUIRE_BEACON_RING 11 | ||
| 520 | #define DEVICE_SUPPORT_HW_BUTTON 12 | ||
| 521 | #define CONFIG_FRAME_TYPE 13 | ||
| 522 | #define CONFIG_RF_SEQUENCE 14 | ||
| 523 | /* Hole: Add new Flag here */ | ||
| 524 | #define CONFIG_EXTERNAL_LNA_A 16 | ||
| 525 | #define CONFIG_EXTERNAL_LNA_BG 17 | ||
| 526 | #define CONFIG_DOUBLE_ANTENNA 18 | ||
| 527 | #define CONFIG_DISABLE_LINK_TUNING 19 | ||
| 528 | |||
| 529 | /* | ||
| 530 | * Chipset identification. | ||
| 531 | */ | ||
| 532 | struct rt2x00_chip chip; | ||
| 533 | |||
| 534 | /* | ||
| 535 | * hw capability specifications. | ||
| 536 | */ | ||
| 537 | struct hw_mode_spec spec; | ||
| 538 | |||
| 539 | /* | ||
| 540 | * Register pointers | ||
| 541 | * csr_addr: Base register address. (PCI) | ||
| 542 | * csr_cache: CSR cache for usb_control_msg. (USB) | ||
| 543 | */ | ||
| 544 | void __iomem *csr_addr; | ||
| 545 | void *csr_cache; | ||
| 546 | |||
| 547 | /* | ||
| 548 | * Interface configuration. | ||
| 549 | */ | ||
| 550 | struct interface interface; | ||
| 551 | |||
| 552 | /* | ||
| 553 | * Link quality | ||
| 554 | */ | ||
| 555 | struct link link; | ||
| 556 | |||
| 557 | /* | ||
| 558 | * EEPROM data. | ||
| 559 | */ | ||
| 560 | __le16 *eeprom; | ||
| 561 | |||
| 562 | /* | ||
| 563 | * Active RF register values. | ||
| 564 | * These are stored here so we don't need | ||
| 565 | * to read the rf registers and can directly | ||
| 566 | * use this value instead. | ||
| 567 | * This field should be accessed by using | ||
| 568 | * rt2x00_rf_read() and rt2x00_rf_write(). | ||
| 569 | */ | ||
| 570 | u32 *rf; | ||
| 571 | |||
| 572 | /* | ||
| 573 | * Current TX power value. | ||
| 574 | */ | ||
| 575 | u16 tx_power; | ||
| 576 | |||
| 577 | /* | ||
| 578 | * LED register (for rt61pci & rt73usb). | ||
| 579 | */ | ||
| 580 | u16 led_reg; | ||
| 581 | |||
| 582 | /* | ||
| 583 | * Led mode (LED_MODE_*) | ||
| 584 | */ | ||
| 585 | u8 led_mode; | ||
| 586 | |||
| 587 | /* | ||
| 588 | * Rssi <-> Dbm offset | ||
| 589 | */ | ||
| 590 | u8 rssi_offset; | ||
| 591 | |||
| 592 | /* | ||
| 593 | * Frequency offset (for rt61pci & rt73usb). | ||
| 594 | */ | ||
| 595 | u8 freq_offset; | ||
| 596 | |||
| 597 | /* | ||
| 598 | * Low level statistics which will have | ||
| 599 | * to be kept up to date while device is running. | ||
| 600 | */ | ||
| 601 | struct ieee80211_low_level_stats low_level_stats; | ||
| 602 | |||
| 603 | /* | ||
| 604 | * RX configuration information. | ||
| 605 | */ | ||
| 606 | struct ieee80211_rx_status rx_status; | ||
| 607 | |||
| 608 | /* | ||
| 609 | * Beacon scheduled work. | ||
| 610 | */ | ||
| 611 | struct work_struct beacon_work; | ||
| 612 | |||
| 613 | /* | ||
| 614 | * Data ring arrays for RX, TX and Beacon. | ||
| 615 | * The Beacon array also contains the Atim ring | ||
| 616 | * if that is supported by the device. | ||
| 617 | */ | ||
| 618 | int data_rings; | ||
| 619 | struct data_ring *rx; | ||
| 620 | struct data_ring *tx; | ||
| 621 | struct data_ring *bcn; | ||
| 622 | |||
| 623 | /* | ||
| 624 | * Firmware image. | ||
| 625 | */ | ||
| 626 | const struct firmware *fw; | ||
| 627 | }; | ||
| 628 | |||
| 629 | /* | ||
| 630 | * For-each loop for the ring array. | ||
| 631 | * All rings have been allocated as a single array, | ||
| 632 | * this means we can create a very simply loop macro | ||
| 633 | * that is capable of looping through all rings. | ||
| 634 | * ring_end(), txring_end() and ring_loop() are helper macro's which | ||
| 635 | * should not be used directly. Instead the following should be used: | ||
| 636 | * ring_for_each() - Loops through all rings (RX, TX, Beacon & Atim) | ||
| 637 | * txring_for_each() - Loops through TX data rings (TX only) | ||
| 638 | * txringall_for_each() - Loops through all TX rings (TX, Beacon & Atim) | ||
| 639 | */ | ||
| 640 | #define ring_end(__dev) \ | ||
| 641 | &(__dev)->rx[(__dev)->data_rings] | ||
| 642 | |||
| 643 | #define txring_end(__dev) \ | ||
| 644 | &(__dev)->tx[(__dev)->hw->queues] | ||
| 645 | |||
| 646 | #define ring_loop(__entry, __start, __end) \ | ||
| 647 | for ((__entry) = (__start); \ | ||
| 648 | prefetch(&(__entry)[1]), (__entry) != (__end); \ | ||
| 649 | (__entry) = &(__entry)[1]) | ||
| 650 | |||
| 651 | #define ring_for_each(__dev, __entry) \ | ||
| 652 | ring_loop(__entry, (__dev)->rx, ring_end(__dev)) | ||
| 653 | |||
| 654 | #define txring_for_each(__dev, __entry) \ | ||
| 655 | ring_loop(__entry, (__dev)->tx, txring_end(__dev)) | ||
| 656 | |||
| 657 | #define txringall_for_each(__dev, __entry) \ | ||
| 658 | ring_loop(__entry, (__dev)->tx, ring_end(__dev)) | ||
| 659 | |||
| 660 | /* | ||
| 661 | * Generic RF access. | ||
| 662 | * The RF is being accessed by word index. | ||
| 663 | */ | ||
| 664 | static inline void rt2x00_rf_read(const struct rt2x00_dev *rt2x00dev, | ||
| 665 | const unsigned int word, u32 *data) | ||
| 666 | { | ||
| 667 | *data = rt2x00dev->rf[word]; | ||
| 668 | } | ||
| 669 | |||
| 670 | static inline void rt2x00_rf_write(const struct rt2x00_dev *rt2x00dev, | ||
| 671 | const unsigned int word, u32 data) | ||
| 672 | { | ||
| 673 | rt2x00dev->rf[word] = data; | ||
| 674 | } | ||
| 675 | |||
| 676 | /* | ||
| 677 | * Generic EEPROM access. | ||
| 678 | * The EEPROM is being accessed by word index. | ||
| 679 | */ | ||
| 680 | static inline void *rt2x00_eeprom_addr(const struct rt2x00_dev *rt2x00dev, | ||
| 681 | const unsigned int word) | ||
| 682 | { | ||
| 683 | return (void *)&rt2x00dev->eeprom[word]; | ||
| 684 | } | ||
| 685 | |||
| 686 | static inline void rt2x00_eeprom_read(const struct rt2x00_dev *rt2x00dev, | ||
| 687 | const unsigned int word, u16 *data) | ||
| 688 | { | ||
| 689 | *data = le16_to_cpu(rt2x00dev->eeprom[word]); | ||
| 690 | } | ||
| 691 | |||
| 692 | static inline void rt2x00_eeprom_write(const struct rt2x00_dev *rt2x00dev, | ||
| 693 | const unsigned int word, u16 data) | ||
| 694 | { | ||
| 695 | rt2x00dev->eeprom[word] = cpu_to_le16(data); | ||
| 696 | } | ||
| 697 | |||
| 698 | /* | ||
| 699 | * Chipset handlers | ||
| 700 | */ | ||
| 701 | static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev, | ||
| 702 | const u16 rt, const u16 rf, const u32 rev) | ||
| 703 | { | ||
| 704 | INFO(rt2x00dev, | ||
| 705 | "Chipset detected - rt: %04x, rf: %04x, rev: %08x.\n", | ||
| 706 | rt, rf, rev); | ||
| 707 | |||
| 708 | rt2x00dev->chip.rt = rt; | ||
| 709 | rt2x00dev->chip.rf = rf; | ||
| 710 | rt2x00dev->chip.rev = rev; | ||
| 711 | } | ||
| 712 | |||
| 713 | static inline char rt2x00_rt(const struct rt2x00_chip *chipset, const u16 chip) | ||
| 714 | { | ||
| 715 | return (chipset->rt == chip); | ||
| 716 | } | ||
| 717 | |||
| 718 | static inline char rt2x00_rf(const struct rt2x00_chip *chipset, const u16 chip) | ||
| 719 | { | ||
| 720 | return (chipset->rf == chip); | ||
| 721 | } | ||
| 722 | |||
| 723 | static inline u16 rt2x00_get_rev(const struct rt2x00_chip *chipset) | ||
| 724 | { | ||
| 725 | return chipset->rev; | ||
| 726 | } | ||
| 727 | |||
| 728 | static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset, const u32 mask) | ||
| 729 | { | ||
| 730 | return chipset->rev & mask; | ||
| 731 | } | ||
| 732 | |||
| 733 | /* | ||
| 734 | * Duration calculations | ||
| 735 | * The rate variable passed is: 100kbs. | ||
| 736 | * To convert from bytes to bits we multiply size with 8, | ||
| 737 | * then the size is multiplied with 10 to make the | ||
| 738 | * real rate -> rate argument correction. | ||
| 739 | */ | ||
| 740 | static inline u16 get_duration(const unsigned int size, const u8 rate) | ||
| 741 | { | ||
| 742 | return ((size * 8 * 10) / rate); | ||
| 743 | } | ||
| 744 | |||
| 745 | static inline u16 get_duration_res(const unsigned int size, const u8 rate) | ||
| 746 | { | ||
| 747 | return ((size * 8 * 10) % rate); | ||
| 748 | } | ||
| 749 | |||
| 750 | /* | ||
| 751 | * Library functions. | ||
| 752 | */ | ||
| 753 | struct data_ring *rt2x00lib_get_ring(struct rt2x00_dev *rt2x00dev, | ||
| 754 | const unsigned int queue); | ||
| 755 | |||
| 756 | /* | ||
| 757 | * Interrupt context handlers. | ||
| 758 | */ | ||
| 759 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); | ||
| 760 | void rt2x00lib_txdone(struct data_entry *entry, | ||
| 761 | const int status, const int retry); | ||
| 762 | void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | ||
| 763 | const int signal, const int rssi, const int ofdm); | ||
| 764 | |||
| 765 | /* | ||
| 766 | * TX descriptor initializer | ||
| 767 | */ | ||
| 768 | void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | ||
| 769 | struct data_desc *txd, | ||
| 770 | struct ieee80211_hdr *ieee80211hdr, | ||
| 771 | unsigned int length, | ||
| 772 | struct ieee80211_tx_control *control); | ||
| 773 | |||
| 774 | /* | ||
| 775 | * mac80211 handlers. | ||
| 776 | */ | ||
| 777 | int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
| 778 | struct ieee80211_tx_control *control); | ||
| 779 | int rt2x00mac_start(struct ieee80211_hw *hw); | ||
| 780 | void rt2x00mac_stop(struct ieee80211_hw *hw); | ||
| 781 | int rt2x00mac_add_interface(struct ieee80211_hw *hw, | ||
| 782 | struct ieee80211_if_init_conf *conf); | ||
| 783 | void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | ||
| 784 | struct ieee80211_if_init_conf *conf); | ||
| 785 | int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); | ||
| 786 | int rt2x00mac_config_interface(struct ieee80211_hw *hw, int if_id, | ||
| 787 | struct ieee80211_if_conf *conf); | ||
| 788 | void rt2x00mac_set_multicast_list(struct ieee80211_hw *hw, | ||
| 789 | unsigned short flags, int mc_count); | ||
| 790 | int rt2x00mac_get_stats(struct ieee80211_hw *hw, | ||
| 791 | struct ieee80211_low_level_stats *stats); | ||
| 792 | int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, | ||
| 793 | struct ieee80211_tx_queue_stats *stats); | ||
| 794 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue, | ||
| 795 | const struct ieee80211_tx_queue_params *params); | ||
| 796 | |||
| 797 | /* | ||
| 798 | * Driver allocation handlers. | ||
| 799 | */ | ||
| 800 | int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev); | ||
| 801 | void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev); | ||
| 802 | #ifdef CONFIG_PM | ||
| 803 | int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state); | ||
| 804 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev); | ||
| 805 | #endif /* CONFIG_PM */ | ||
| 806 | |||
| 807 | #endif /* RT2X00_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c new file mode 100644 index 00000000000..de890a17d8f --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
| @@ -0,0 +1,165 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00lib | ||
| 23 | Abstract: rt2x00 generic configuration routines. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Set enviroment defines for rt2x00.h | ||
| 28 | */ | ||
| 29 | #define DRV_NAME "rt2x00lib" | ||
| 30 | |||
| 31 | #include <linux/kernel.h> | ||
| 32 | #include <linux/module.h> | ||
| 33 | |||
| 34 | #include "rt2x00.h" | ||
| 35 | #include "rt2x00lib.h" | ||
| 36 | |||
| 37 | void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac) | ||
| 38 | { | ||
| 39 | if (mac) | ||
| 40 | rt2x00dev->ops->lib->config_mac_addr(rt2x00dev, mac); | ||
| 41 | } | ||
| 42 | |||
| 43 | void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) | ||
| 44 | { | ||
| 45 | if (bssid) | ||
| 46 | rt2x00dev->ops->lib->config_bssid(rt2x00dev, bssid); | ||
| 47 | } | ||
| 48 | |||
| 49 | void rt2x00lib_config_packet_filter(struct rt2x00_dev *rt2x00dev, int filter) | ||
| 50 | { | ||
| 51 | /* | ||
| 52 | * Only configure the device when something has changed, | ||
| 53 | * or if we are in RESUME state in which case all configuration | ||
| 54 | * will be forced upon the device. | ||
| 55 | */ | ||
| 56 | if (!test_bit(INTERFACE_RESUME, &rt2x00dev->flags) && | ||
| 57 | !test_bit(PACKET_FILTER_PENDING, &rt2x00dev->flags)) | ||
| 58 | return; | ||
| 59 | |||
| 60 | /* | ||
| 61 | * Write configuration to device and clear the update flag. | ||
| 62 | */ | ||
| 63 | rt2x00dev->ops->lib->config_packet_filter(rt2x00dev, filter); | ||
| 64 | __clear_bit(PACKET_FILTER_PENDING, &rt2x00dev->flags); | ||
| 65 | } | ||
| 66 | |||
| 67 | void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, int type) | ||
| 68 | { | ||
| 69 | struct interface *intf = &rt2x00dev->interface; | ||
| 70 | |||
| 71 | /* | ||
| 72 | * Fallback when a invalid interface is attempted to | ||
| 73 | * be configured. If a monitor interface is present, | ||
| 74 | * we are going configure that, otherwise exit. | ||
| 75 | */ | ||
| 76 | if (type == INVALID_INTERFACE) { | ||
| 77 | if (is_monitor_present(intf)) | ||
| 78 | type = IEEE80211_IF_TYPE_MNTR; | ||
| 79 | else | ||
| 80 | return; | ||
| 81 | } | ||
| 82 | |||
| 83 | /* | ||
| 84 | * Only configure the device when something has changed, | ||
| 85 | * or if we are in RESUME state in which case all configuration | ||
| 86 | * will be forced upon the device. | ||
| 87 | */ | ||
| 88 | if (!test_bit(INTERFACE_RESUME, &rt2x00dev->flags) && | ||
| 89 | (!(is_interface_present(intf) ^ | ||
| 90 | test_bit(INTERFACE_ENABLED, &rt2x00dev->flags)) && | ||
| 91 | !(is_monitor_present(intf) ^ | ||
| 92 | test_bit(INTERFACE_ENABLED_MONITOR, &rt2x00dev->flags)))) | ||
| 93 | return; | ||
| 94 | |||
| 95 | /* | ||
| 96 | * Configure device. | ||
| 97 | */ | ||
| 98 | rt2x00dev->ops->lib->config_type(rt2x00dev, type); | ||
| 99 | |||
| 100 | /* | ||
| 101 | * Update the configuration flags. | ||
| 102 | */ | ||
| 103 | if (type != IEEE80211_IF_TYPE_MNTR) { | ||
| 104 | if (is_interface_present(intf)) | ||
| 105 | __set_bit(INTERFACE_ENABLED, &rt2x00dev->flags); | ||
| 106 | else | ||
| 107 | __clear_bit(INTERFACE_ENABLED, &rt2x00dev->flags); | ||
| 108 | } else { | ||
| 109 | if (is_monitor_present(intf)) | ||
| 110 | __set_bit(INTERFACE_ENABLED_MONITOR, &rt2x00dev->flags); | ||
| 111 | else | ||
| 112 | __clear_bit(INTERFACE_ENABLED_MONITOR, | ||
| 113 | &rt2x00dev->flags); | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf) | ||
| 118 | { | ||
| 119 | int flags = 0; | ||
| 120 | |||
| 121 | /* | ||
| 122 | * If we are in RESUME state we should | ||
| 123 | * force all configuration options. | ||
| 124 | */ | ||
| 125 | if (test_bit(INTERFACE_RESUME, &rt2x00dev->flags)) { | ||
| 126 | flags = CONFIG_UPDATE_ALL; | ||
| 127 | goto config; | ||
| 128 | } | ||
| 129 | |||
| 130 | /* | ||
| 131 | * Check which configuration options have been | ||
| 132 | * updated and should be send to the device. | ||
| 133 | */ | ||
| 134 | if (rt2x00dev->rx_status.phymode != conf->phymode) | ||
| 135 | flags |= CONFIG_UPDATE_PHYMODE; | ||
| 136 | if (rt2x00dev->rx_status.channel != conf->channel) | ||
| 137 | flags |= CONFIG_UPDATE_CHANNEL; | ||
| 138 | if (rt2x00dev->tx_power != conf->power_level) | ||
| 139 | flags |= CONFIG_UPDATE_TXPOWER; | ||
| 140 | if (rt2x00dev->rx_status.antenna == conf->antenna_sel_rx) | ||
| 141 | flags |= CONFIG_UPDATE_ANTENNA; | ||
| 142 | |||
| 143 | /* | ||
| 144 | * The following configuration options are never | ||
| 145 | * stored anywhere and will always be updated. | ||
| 146 | */ | ||
| 147 | flags |= CONFIG_UPDATE_SLOT_TIME; | ||
| 148 | flags |= CONFIG_UPDATE_BEACON_INT; | ||
| 149 | |||
| 150 | config: | ||
| 151 | rt2x00dev->ops->lib->config(rt2x00dev, flags, conf); | ||
| 152 | |||
| 153 | /* | ||
| 154 | * Some configuration changes affect the link quality | ||
| 155 | * which means we need to reset the link tuner. | ||
| 156 | */ | ||
| 157 | if (flags & (CONFIG_UPDATE_CHANNEL | CONFIG_UPDATE_ANTENNA)) | ||
| 158 | rt2x00lib_reset_link_tuner(rt2x00dev); | ||
| 159 | |||
| 160 | rt2x00dev->rx_status.phymode = conf->phymode; | ||
| 161 | rt2x00dev->rx_status.freq = conf->freq; | ||
| 162 | rt2x00dev->rx_status.channel = conf->channel; | ||
| 163 | rt2x00dev->tx_power = conf->power_level; | ||
| 164 | rt2x00dev->rx_status.antenna = conf->antenna_sel_rx; | ||
| 165 | } | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c new file mode 100644 index 00000000000..4d2aaecd9df --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
| @@ -0,0 +1,331 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00lib | ||
| 23 | Abstract: rt2x00 debugfs specific routines. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Set enviroment defines for rt2x00.h | ||
| 28 | */ | ||
| 29 | #define DRV_NAME "rt2x00lib" | ||
| 30 | |||
| 31 | #include <linux/debugfs.h> | ||
| 32 | #include <linux/kernel.h> | ||
| 33 | #include <linux/module.h> | ||
| 34 | #include <linux/uaccess.h> | ||
| 35 | |||
| 36 | #include "rt2x00.h" | ||
| 37 | #include "rt2x00lib.h" | ||
| 38 | |||
| 39 | #define PRINT_LINE_LEN_MAX 32 | ||
| 40 | |||
| 41 | struct rt2x00debug_intf { | ||
| 42 | /* | ||
| 43 | * Pointer to driver structure where | ||
| 44 | * this debugfs entry belongs to. | ||
| 45 | */ | ||
| 46 | struct rt2x00_dev *rt2x00dev; | ||
| 47 | |||
| 48 | /* | ||
| 49 | * Reference to the rt2x00debug structure | ||
| 50 | * which can be used to communicate with | ||
| 51 | * the registers. | ||
| 52 | */ | ||
| 53 | const struct rt2x00debug *debug; | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Debugfs entries for: | ||
| 57 | * - driver folder | ||
| 58 | * - driver file | ||
| 59 | * - chipset file | ||
| 60 | * - register offset/value files | ||
| 61 | * - eeprom offset/value files | ||
| 62 | * - bbp offset/value files | ||
| 63 | * - rf offset/value files | ||
| 64 | */ | ||
| 65 | struct dentry *driver_folder; | ||
| 66 | struct dentry *driver_entry; | ||
| 67 | struct dentry *chipset_entry; | ||
| 68 | struct dentry *csr_off_entry; | ||
| 69 | struct dentry *csr_val_entry; | ||
| 70 | struct dentry *eeprom_off_entry; | ||
| 71 | struct dentry *eeprom_val_entry; | ||
| 72 | struct dentry *bbp_off_entry; | ||
| 73 | struct dentry *bbp_val_entry; | ||
| 74 | struct dentry *rf_off_entry; | ||
| 75 | struct dentry *rf_val_entry; | ||
| 76 | |||
| 77 | /* | ||
| 78 | * Driver and chipset files will use a data buffer | ||
| 79 | * that has been created in advance. This will simplify | ||
| 80 | * the code since we can use the debugfs functions. | ||
| 81 | */ | ||
| 82 | struct debugfs_blob_wrapper driver_blob; | ||
| 83 | struct debugfs_blob_wrapper chipset_blob; | ||
| 84 | |||
| 85 | /* | ||
| 86 | * Requested offset for each register type. | ||
| 87 | */ | ||
| 88 | unsigned int offset_csr; | ||
| 89 | unsigned int offset_eeprom; | ||
| 90 | unsigned int offset_bbp; | ||
| 91 | unsigned int offset_rf; | ||
| 92 | }; | ||
| 93 | |||
| 94 | static int rt2x00debug_file_open(struct inode *inode, struct file *file) | ||
| 95 | { | ||
| 96 | struct rt2x00debug_intf *intf = inode->i_private; | ||
| 97 | |||
| 98 | file->private_data = inode->i_private; | ||
| 99 | |||
| 100 | if (!try_module_get(intf->debug->owner)) | ||
| 101 | return -EBUSY; | ||
| 102 | |||
| 103 | return 0; | ||
| 104 | } | ||
| 105 | |||
| 106 | static int rt2x00debug_file_release(struct inode *inode, struct file *file) | ||
| 107 | { | ||
| 108 | struct rt2x00debug_intf *intf = file->private_data; | ||
| 109 | |||
| 110 | module_put(intf->debug->owner); | ||
| 111 | |||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \ | ||
| 116 | static ssize_t rt2x00debug_read_##__name(struct file *file, \ | ||
| 117 | char __user *buf, \ | ||
| 118 | size_t length, \ | ||
| 119 | loff_t *offset) \ | ||
| 120 | { \ | ||
| 121 | struct rt2x00debug_intf *intf = file->private_data; \ | ||
| 122 | const struct rt2x00debug *debug = intf->debug; \ | ||
| 123 | char line[16]; \ | ||
| 124 | size_t size; \ | ||
| 125 | __type value; \ | ||
| 126 | \ | ||
| 127 | if (*offset) \ | ||
| 128 | return 0; \ | ||
| 129 | \ | ||
| 130 | if (intf->offset_##__name >= debug->__name.word_count) \ | ||
| 131 | return -EINVAL; \ | ||
| 132 | \ | ||
| 133 | debug->__name.read(intf->rt2x00dev, \ | ||
| 134 | intf->offset_##__name, &value); \ | ||
| 135 | \ | ||
| 136 | size = sprintf(line, __format, value); \ | ||
| 137 | \ | ||
| 138 | if (copy_to_user(buf, line, size)) \ | ||
| 139 | return -EFAULT; \ | ||
| 140 | \ | ||
| 141 | *offset += size; \ | ||
| 142 | return size; \ | ||
| 143 | } | ||
| 144 | |||
| 145 | #define RT2X00DEBUGFS_OPS_WRITE(__name, __type) \ | ||
| 146 | static ssize_t rt2x00debug_write_##__name(struct file *file, \ | ||
| 147 | const char __user *buf,\ | ||
| 148 | size_t length, \ | ||
| 149 | loff_t *offset) \ | ||
| 150 | { \ | ||
| 151 | struct rt2x00debug_intf *intf = file->private_data; \ | ||
| 152 | const struct rt2x00debug *debug = intf->debug; \ | ||
| 153 | char line[16]; \ | ||
| 154 | size_t size; \ | ||
| 155 | __type value; \ | ||
| 156 | \ | ||
| 157 | if (*offset) \ | ||
| 158 | return 0; \ | ||
| 159 | \ | ||
| 160 | if (!capable(CAP_NET_ADMIN)) \ | ||
| 161 | return -EPERM; \ | ||
| 162 | \ | ||
| 163 | if (intf->offset_##__name >= debug->__name.word_count) \ | ||
| 164 | return -EINVAL; \ | ||
| 165 | \ | ||
| 166 | if (copy_from_user(line, buf, length)) \ | ||
| 167 | return -EFAULT; \ | ||
| 168 | \ | ||
| 169 | size = strlen(line); \ | ||
| 170 | value = simple_strtoul(line, NULL, 0); \ | ||
| 171 | \ | ||
| 172 | debug->__name.write(intf->rt2x00dev, \ | ||
| 173 | intf->offset_##__name, value); \ | ||
| 174 | \ | ||
| 175 | *offset += size; \ | ||
| 176 | return size; \ | ||
| 177 | } | ||
| 178 | |||
| 179 | #define RT2X00DEBUGFS_OPS(__name, __format, __type) \ | ||
| 180 | RT2X00DEBUGFS_OPS_READ(__name, __format, __type); \ | ||
| 181 | RT2X00DEBUGFS_OPS_WRITE(__name, __type); \ | ||
| 182 | \ | ||
| 183 | static const struct file_operations rt2x00debug_fop_##__name = {\ | ||
| 184 | .owner = THIS_MODULE, \ | ||
| 185 | .read = rt2x00debug_read_##__name, \ | ||
| 186 | .write = rt2x00debug_write_##__name, \ | ||
| 187 | .open = rt2x00debug_file_open, \ | ||
| 188 | .release = rt2x00debug_file_release, \ | ||
| 189 | }; | ||
| 190 | |||
| 191 | RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32); | ||
| 192 | RT2X00DEBUGFS_OPS(eeprom, "0x%.4x\n", u16); | ||
| 193 | RT2X00DEBUGFS_OPS(bbp, "0x%.2x\n", u8); | ||
| 194 | RT2X00DEBUGFS_OPS(rf, "0x%.8x\n", u32); | ||
| 195 | |||
| 196 | static struct dentry *rt2x00debug_create_file_driver(const char *name, | ||
| 197 | struct rt2x00debug_intf | ||
| 198 | *intf, | ||
| 199 | struct debugfs_blob_wrapper | ||
| 200 | *blob) | ||
| 201 | { | ||
| 202 | char *data; | ||
| 203 | |||
| 204 | data = kzalloc(3 * PRINT_LINE_LEN_MAX, GFP_KERNEL); | ||
| 205 | if (!data) | ||
| 206 | return NULL; | ||
| 207 | |||
| 208 | blob->data = data; | ||
| 209 | data += sprintf(data, "driver: %s\n", intf->rt2x00dev->ops->name); | ||
| 210 | data += sprintf(data, "version: %s\n", DRV_VERSION); | ||
| 211 | data += sprintf(data, "compiled: %s %s\n", __DATE__, __TIME__); | ||
| 212 | blob->size = strlen(blob->data); | ||
| 213 | |||
| 214 | return debugfs_create_blob(name, S_IRUGO, intf->driver_folder, blob); | ||
| 215 | } | ||
| 216 | |||
| 217 | static struct dentry *rt2x00debug_create_file_chipset(const char *name, | ||
| 218 | struct rt2x00debug_intf | ||
| 219 | *intf, | ||
| 220 | struct | ||
| 221 | debugfs_blob_wrapper | ||
| 222 | *blob) | ||
| 223 | { | ||
| 224 | const struct rt2x00debug *debug = intf->debug; | ||
| 225 | char *data; | ||
| 226 | |||
| 227 | data = kzalloc(4 * PRINT_LINE_LEN_MAX, GFP_KERNEL); | ||
| 228 | if (!data) | ||
| 229 | return NULL; | ||
| 230 | |||
| 231 | blob->data = data; | ||
| 232 | data += sprintf(data, "csr length: %d\n", debug->csr.word_count); | ||
| 233 | data += sprintf(data, "eeprom length: %d\n", debug->eeprom.word_count); | ||
| 234 | data += sprintf(data, "bbp length: %d\n", debug->bbp.word_count); | ||
| 235 | data += sprintf(data, "rf length: %d\n", debug->rf.word_count); | ||
| 236 | blob->size = strlen(blob->data); | ||
| 237 | |||
| 238 | return debugfs_create_blob(name, S_IRUGO, intf->driver_folder, blob); | ||
| 239 | } | ||
| 240 | |||
| 241 | void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | ||
| 242 | { | ||
| 243 | const struct rt2x00debug *debug = rt2x00dev->ops->debugfs; | ||
| 244 | struct rt2x00debug_intf *intf; | ||
| 245 | |||
| 246 | intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL); | ||
| 247 | if (!intf) { | ||
| 248 | ERROR(rt2x00dev, "Failed to allocate debug handler.\n"); | ||
| 249 | return; | ||
| 250 | } | ||
| 251 | |||
| 252 | intf->debug = debug; | ||
| 253 | intf->rt2x00dev = rt2x00dev; | ||
| 254 | rt2x00dev->debugfs_intf = intf; | ||
| 255 | |||
| 256 | intf->driver_folder = | ||
| 257 | debugfs_create_dir(intf->rt2x00dev->ops->name, | ||
| 258 | rt2x00dev->hw->wiphy->debugfsdir); | ||
| 259 | if (IS_ERR(intf->driver_folder)) | ||
| 260 | goto exit; | ||
| 261 | |||
| 262 | intf->driver_entry = | ||
| 263 | rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob); | ||
| 264 | if (IS_ERR(intf->driver_entry)) | ||
| 265 | goto exit; | ||
| 266 | |||
| 267 | intf->chipset_entry = | ||
| 268 | rt2x00debug_create_file_chipset("chipset", | ||
| 269 | intf, &intf->chipset_blob); | ||
| 270 | if (IS_ERR(intf->chipset_entry)) | ||
| 271 | goto exit; | ||
| 272 | |||
| 273 | #define RT2X00DEBUGFS_CREATE_ENTRY(__intf, __name) \ | ||
| 274 | ({ \ | ||
| 275 | (__intf)->__name##_off_entry = \ | ||
| 276 | debugfs_create_u32(__stringify(__name) "_offset", \ | ||
| 277 | S_IRUGO | S_IWUSR, \ | ||
| 278 | (__intf)->driver_folder, \ | ||
| 279 | &(__intf)->offset_##__name); \ | ||
| 280 | if (IS_ERR((__intf)->__name##_off_entry)) \ | ||
| 281 | goto exit; \ | ||
| 282 | \ | ||
| 283 | (__intf)->__name##_val_entry = \ | ||
| 284 | debugfs_create_file(__stringify(__name) "_value", \ | ||
| 285 | S_IRUGO | S_IWUSR, \ | ||
| 286 | (__intf)->driver_folder, \ | ||
| 287 | (__intf), &rt2x00debug_fop_##__name);\ | ||
| 288 | if (IS_ERR((__intf)->__name##_val_entry)) \ | ||
| 289 | goto exit; \ | ||
| 290 | }) | ||
| 291 | |||
| 292 | RT2X00DEBUGFS_CREATE_ENTRY(intf, csr); | ||
| 293 | RT2X00DEBUGFS_CREATE_ENTRY(intf, eeprom); | ||
| 294 | RT2X00DEBUGFS_CREATE_ENTRY(intf, bbp); | ||
| 295 | RT2X00DEBUGFS_CREATE_ENTRY(intf, rf); | ||
| 296 | |||
| 297 | #undef RT2X00DEBUGFS_CREATE_ENTRY | ||
| 298 | |||
| 299 | return; | ||
| 300 | |||
| 301 | exit: | ||
| 302 | rt2x00debug_deregister(rt2x00dev); | ||
| 303 | ERROR(rt2x00dev, "Failed to register debug handler.\n"); | ||
| 304 | |||
| 305 | return; | ||
| 306 | } | ||
| 307 | |||
| 308 | void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) | ||
| 309 | { | ||
| 310 | const struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; | ||
| 311 | |||
| 312 | if (unlikely(!intf)) | ||
| 313 | return; | ||
| 314 | |||
| 315 | debugfs_remove(intf->rf_val_entry); | ||
| 316 | debugfs_remove(intf->rf_off_entry); | ||
| 317 | debugfs_remove(intf->bbp_val_entry); | ||
| 318 | debugfs_remove(intf->bbp_off_entry); | ||
| 319 | debugfs_remove(intf->eeprom_val_entry); | ||
| 320 | debugfs_remove(intf->eeprom_off_entry); | ||
| 321 | debugfs_remove(intf->csr_val_entry); | ||
| 322 | debugfs_remove(intf->csr_off_entry); | ||
| 323 | debugfs_remove(intf->chipset_entry); | ||
| 324 | debugfs_remove(intf->driver_entry); | ||
| 325 | debugfs_remove(intf->driver_folder); | ||
| 326 | kfree(intf->chipset_blob.data); | ||
| 327 | kfree(intf->driver_blob.data); | ||
| 328 | kfree(intf); | ||
| 329 | |||
| 330 | rt2x00dev->debugfs_intf = NULL; | ||
| 331 | } | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.h b/drivers/net/wireless/rt2x00/rt2x00debug.h new file mode 100644 index 00000000000..860e8fa3a0d --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00debug.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00debug | ||
| 23 | Abstract: Data structures for the rt2x00debug. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #ifndef RT2X00DEBUG_H | ||
| 27 | #define RT2X00DEBUG_H | ||
| 28 | |||
| 29 | struct rt2x00_dev; | ||
| 30 | |||
| 31 | #define RT2X00DEBUGFS_REGISTER_ENTRY(__name, __type) \ | ||
| 32 | struct reg##__name { \ | ||
| 33 | void (*read)(const struct rt2x00_dev *rt2x00dev, \ | ||
| 34 | const unsigned int word, __type *data); \ | ||
| 35 | void (*write)(const struct rt2x00_dev *rt2x00dev, \ | ||
| 36 | const unsigned int word, __type data); \ | ||
| 37 | \ | ||
| 38 | unsigned int word_size; \ | ||
| 39 | unsigned int word_count; \ | ||
| 40 | } __name | ||
| 41 | |||
| 42 | struct rt2x00debug { | ||
| 43 | /* | ||
| 44 | * Reference to the modules structure. | ||
| 45 | */ | ||
| 46 | struct module *owner; | ||
| 47 | |||
| 48 | /* | ||
| 49 | * Register access entries. | ||
| 50 | */ | ||
| 51 | RT2X00DEBUGFS_REGISTER_ENTRY(csr, u32); | ||
| 52 | RT2X00DEBUGFS_REGISTER_ENTRY(eeprom, u16); | ||
| 53 | RT2X00DEBUGFS_REGISTER_ENTRY(bbp, u8); | ||
| 54 | RT2X00DEBUGFS_REGISTER_ENTRY(rf, u32); | ||
| 55 | }; | ||
| 56 | |||
| 57 | #endif /* RT2X00DEBUG_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c new file mode 100644 index 00000000000..cd82eeface8 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
| @@ -0,0 +1,1133 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00lib | ||
| 23 | Abstract: rt2x00 generic device routines. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Set enviroment defines for rt2x00.h | ||
| 28 | */ | ||
| 29 | #define DRV_NAME "rt2x00lib" | ||
| 30 | |||
| 31 | #include <linux/kernel.h> | ||
| 32 | #include <linux/module.h> | ||
| 33 | |||
| 34 | #include "rt2x00.h" | ||
| 35 | #include "rt2x00lib.h" | ||
| 36 | |||
| 37 | /* | ||
| 38 | * Ring handler. | ||
| 39 | */ | ||
| 40 | struct data_ring *rt2x00lib_get_ring(struct rt2x00_dev *rt2x00dev, | ||
| 41 | const unsigned int queue) | ||
| 42 | { | ||
| 43 | int beacon = test_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags); | ||
| 44 | |||
| 45 | /* | ||
| 46 | * Check if we are requesting a reqular TX ring, | ||
| 47 | * or if we are requesting a Beacon or Atim ring. | ||
| 48 | * For Atim rings, we should check if it is supported. | ||
| 49 | */ | ||
| 50 | if (queue < rt2x00dev->hw->queues && rt2x00dev->tx) | ||
| 51 | return &rt2x00dev->tx[queue]; | ||
| 52 | |||
| 53 | if (!rt2x00dev->bcn || !beacon) | ||
| 54 | return NULL; | ||
| 55 | |||
| 56 | if (queue == IEEE80211_TX_QUEUE_BEACON) | ||
| 57 | return &rt2x00dev->bcn[0]; | ||
| 58 | else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON) | ||
| 59 | return &rt2x00dev->bcn[1]; | ||
| 60 | |||
| 61 | return NULL; | ||
| 62 | } | ||
| 63 | EXPORT_SYMBOL_GPL(rt2x00lib_get_ring); | ||
| 64 | |||
| 65 | /* | ||
| 66 | * Link tuning handlers | ||
| 67 | */ | ||
| 68 | static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) | ||
| 69 | { | ||
| 70 | rt2x00_clear_link(&rt2x00dev->link); | ||
| 71 | |||
| 72 | /* | ||
| 73 | * Reset the link tuner. | ||
| 74 | */ | ||
| 75 | rt2x00dev->ops->lib->reset_tuner(rt2x00dev); | ||
| 76 | |||
| 77 | queue_delayed_work(rt2x00dev->hw->workqueue, | ||
| 78 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); | ||
| 79 | } | ||
| 80 | |||
| 81 | static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev) | ||
| 82 | { | ||
| 83 | if (delayed_work_pending(&rt2x00dev->link.work)) | ||
| 84 | cancel_rearming_delayed_work(&rt2x00dev->link.work); | ||
| 85 | } | ||
| 86 | |||
| 87 | void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) | ||
| 88 | { | ||
| 89 | rt2x00lib_stop_link_tuner(rt2x00dev); | ||
| 90 | rt2x00lib_start_link_tuner(rt2x00dev); | ||
| 91 | } | ||
| 92 | |||
| 93 | /* | ||
| 94 | * Radio control handlers. | ||
| 95 | */ | ||
| 96 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 97 | { | ||
| 98 | int status; | ||
| 99 | |||
| 100 | /* | ||
| 101 | * Don't enable the radio twice. | ||
| 102 | * And check if the hardware button has been disabled. | ||
| 103 | */ | ||
| 104 | if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | ||
| 105 | (test_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags) && | ||
| 106 | !test_bit(DEVICE_ENABLED_RADIO_HW, &rt2x00dev->flags))) | ||
| 107 | return 0; | ||
| 108 | |||
| 109 | /* | ||
| 110 | * Enable radio. | ||
| 111 | */ | ||
| 112 | status = rt2x00dev->ops->lib->set_device_state(rt2x00dev, | ||
| 113 | STATE_RADIO_ON); | ||
| 114 | if (status) | ||
| 115 | return status; | ||
| 116 | |||
| 117 | __set_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags); | ||
| 118 | |||
| 119 | /* | ||
| 120 | * Enable RX. | ||
| 121 | */ | ||
| 122 | rt2x00lib_toggle_rx(rt2x00dev, 1); | ||
| 123 | |||
| 124 | /* | ||
| 125 | * Start the TX queues. | ||
| 126 | */ | ||
| 127 | ieee80211_start_queues(rt2x00dev->hw); | ||
| 128 | |||
| 129 | return 0; | ||
| 130 | } | ||
| 131 | |||
| 132 | void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 133 | { | ||
| 134 | if (!__test_and_clear_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
| 135 | return; | ||
| 136 | |||
| 137 | /* | ||
| 138 | * Stop beacon generation. | ||
| 139 | */ | ||
| 140 | if (work_pending(&rt2x00dev->beacon_work)) | ||
| 141 | cancel_work_sync(&rt2x00dev->beacon_work); | ||
| 142 | |||
| 143 | /* | ||
| 144 | * Stop the TX queues. | ||
| 145 | */ | ||
| 146 | ieee80211_stop_queues(rt2x00dev->hw); | ||
| 147 | |||
| 148 | /* | ||
| 149 | * Disable RX. | ||
| 150 | */ | ||
| 151 | rt2x00lib_toggle_rx(rt2x00dev, 0); | ||
| 152 | |||
| 153 | /* | ||
| 154 | * Disable radio. | ||
| 155 | */ | ||
| 156 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_OFF); | ||
| 157 | } | ||
| 158 | |||
| 159 | void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, int enable) | ||
| 160 | { | ||
| 161 | enum dev_state state = enable ? STATE_RADIO_RX_ON : STATE_RADIO_RX_OFF; | ||
| 162 | |||
| 163 | /* | ||
| 164 | * When we are disabling the RX, we should also stop the link tuner. | ||
| 165 | */ | ||
| 166 | if (!enable) | ||
| 167 | rt2x00lib_stop_link_tuner(rt2x00dev); | ||
| 168 | |||
| 169 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); | ||
| 170 | |||
| 171 | /* | ||
| 172 | * When we are enabling the RX, we should also start the link tuner. | ||
| 173 | */ | ||
| 174 | if (enable && is_interface_present(&rt2x00dev->interface)) | ||
| 175 | rt2x00lib_start_link_tuner(rt2x00dev); | ||
| 176 | } | ||
| 177 | |||
| 178 | static void rt2x00lib_precalculate_link_signal(struct link *link) | ||
| 179 | { | ||
| 180 | if (link->rx_failed || link->rx_success) | ||
| 181 | link->rx_percentage = | ||
| 182 | (link->rx_success * 100) / | ||
| 183 | (link->rx_failed + link->rx_success); | ||
| 184 | else | ||
| 185 | link->rx_percentage = 50; | ||
| 186 | |||
| 187 | if (link->tx_failed || link->tx_success) | ||
| 188 | link->tx_percentage = | ||
| 189 | (link->tx_success * 100) / | ||
| 190 | (link->tx_failed + link->tx_success); | ||
| 191 | else | ||
| 192 | link->tx_percentage = 50; | ||
| 193 | |||
| 194 | link->rx_success = 0; | ||
| 195 | link->rx_failed = 0; | ||
| 196 | link->tx_success = 0; | ||
| 197 | link->tx_failed = 0; | ||
| 198 | } | ||
| 199 | |||
| 200 | static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev, | ||
| 201 | int rssi) | ||
| 202 | { | ||
| 203 | int rssi_percentage = 0; | ||
| 204 | int signal; | ||
| 205 | |||
| 206 | /* | ||
| 207 | * We need a positive value for the RSSI. | ||
| 208 | */ | ||
| 209 | if (rssi < 0) | ||
| 210 | rssi += rt2x00dev->rssi_offset; | ||
| 211 | |||
| 212 | /* | ||
| 213 | * Calculate the different percentages, | ||
| 214 | * which will be used for the signal. | ||
| 215 | */ | ||
| 216 | if (rt2x00dev->rssi_offset) | ||
| 217 | rssi_percentage = (rssi * 100) / rt2x00dev->rssi_offset; | ||
| 218 | |||
| 219 | /* | ||
| 220 | * Add the individual percentages and use the WEIGHT | ||
| 221 | * defines to calculate the current link signal. | ||
| 222 | */ | ||
| 223 | signal = ((WEIGHT_RSSI * rssi_percentage) + | ||
| 224 | (WEIGHT_TX * rt2x00dev->link.tx_percentage) + | ||
| 225 | (WEIGHT_RX * rt2x00dev->link.rx_percentage)) / 100; | ||
| 226 | |||
| 227 | return (signal > 100) ? 100 : signal; | ||
| 228 | } | ||
| 229 | |||
| 230 | static void rt2x00lib_link_tuner(struct work_struct *work) | ||
| 231 | { | ||
| 232 | struct rt2x00_dev *rt2x00dev = | ||
| 233 | container_of(work, struct rt2x00_dev, link.work.work); | ||
| 234 | |||
| 235 | /* | ||
| 236 | * Update statistics. | ||
| 237 | */ | ||
| 238 | rt2x00dev->ops->lib->link_stats(rt2x00dev); | ||
| 239 | |||
| 240 | rt2x00dev->low_level_stats.dot11FCSErrorCount += | ||
| 241 | rt2x00dev->link.rx_failed; | ||
| 242 | |||
| 243 | rt2x00lib_precalculate_link_signal(&rt2x00dev->link); | ||
| 244 | |||
| 245 | /* | ||
| 246 | * Only perform the link tuning when Link tuning | ||
| 247 | * has been enabled (This could have been disabled from the EEPROM). | ||
| 248 | */ | ||
| 249 | if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags)) | ||
| 250 | rt2x00dev->ops->lib->link_tuner(rt2x00dev); | ||
| 251 | |||
| 252 | /* | ||
| 253 | * Increase tuner counter, and reschedule the next link tuner run. | ||
| 254 | */ | ||
| 255 | rt2x00dev->link.count++; | ||
| 256 | queue_delayed_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work, | ||
| 257 | LINK_TUNE_INTERVAL); | ||
| 258 | } | ||
| 259 | |||
| 260 | /* | ||
| 261 | * Interrupt context handlers. | ||
| 262 | */ | ||
| 263 | static void rt2x00lib_beacondone_scheduled(struct work_struct *work) | ||
| 264 | { | ||
| 265 | struct rt2x00_dev *rt2x00dev = | ||
| 266 | container_of(work, struct rt2x00_dev, beacon_work); | ||
| 267 | struct data_ring *ring = | ||
| 268 | rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
| 269 | struct data_entry *entry = rt2x00_get_data_entry(ring); | ||
| 270 | struct sk_buff *skb; | ||
| 271 | |||
| 272 | skb = ieee80211_beacon_get(rt2x00dev->hw, | ||
| 273 | rt2x00dev->interface.id, | ||
| 274 | &entry->tx_status.control); | ||
| 275 | if (!skb) | ||
| 276 | return; | ||
| 277 | |||
| 278 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb, | ||
| 279 | &entry->tx_status.control); | ||
| 280 | |||
| 281 | dev_kfree_skb(skb); | ||
| 282 | } | ||
| 283 | |||
| 284 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | ||
| 285 | { | ||
| 286 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
| 287 | return; | ||
| 288 | |||
| 289 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->beacon_work); | ||
| 290 | } | ||
| 291 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | ||
| 292 | |||
| 293 | void rt2x00lib_txdone(struct data_entry *entry, | ||
| 294 | const int status, const int retry) | ||
| 295 | { | ||
| 296 | struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; | ||
| 297 | struct ieee80211_tx_status *tx_status = &entry->tx_status; | ||
| 298 | struct ieee80211_low_level_stats *stats = &rt2x00dev->low_level_stats; | ||
| 299 | int success = !!(status == TX_SUCCESS || status == TX_SUCCESS_RETRY); | ||
| 300 | int fail = !!(status == TX_FAIL_RETRY || status == TX_FAIL_INVALID || | ||
| 301 | status == TX_FAIL_OTHER); | ||
| 302 | |||
| 303 | /* | ||
| 304 | * Update TX statistics. | ||
| 305 | */ | ||
| 306 | tx_status->flags = 0; | ||
| 307 | tx_status->ack_signal = 0; | ||
| 308 | tx_status->excessive_retries = (status == TX_FAIL_RETRY); | ||
| 309 | tx_status->retry_count = retry; | ||
| 310 | rt2x00dev->link.tx_success += success; | ||
| 311 | rt2x00dev->link.tx_failed += retry + fail; | ||
| 312 | |||
| 313 | if (!(tx_status->control.flags & IEEE80211_TXCTL_NO_ACK)) { | ||
| 314 | if (success) | ||
| 315 | tx_status->flags |= IEEE80211_TX_STATUS_ACK; | ||
| 316 | else | ||
| 317 | stats->dot11ACKFailureCount++; | ||
| 318 | } | ||
| 319 | |||
| 320 | tx_status->queue_length = entry->ring->stats.limit; | ||
| 321 | tx_status->queue_number = tx_status->control.queue; | ||
| 322 | |||
| 323 | if (tx_status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { | ||
| 324 | if (success) | ||
| 325 | stats->dot11RTSSuccessCount++; | ||
| 326 | else | ||
| 327 | stats->dot11RTSFailureCount++; | ||
| 328 | } | ||
| 329 | |||
| 330 | /* | ||
| 331 | * Send the tx_status to mac80211, | ||
| 332 | * that method also cleans up the skb structure. | ||
| 333 | */ | ||
| 334 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb, tx_status); | ||
| 335 | entry->skb = NULL; | ||
| 336 | } | ||
| 337 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | ||
| 338 | |||
| 339 | void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | ||
| 340 | const int signal, const int rssi, const int ofdm) | ||
| 341 | { | ||
| 342 | struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; | ||
| 343 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; | ||
| 344 | struct ieee80211_hw_mode *mode; | ||
| 345 | struct ieee80211_rate *rate; | ||
| 346 | unsigned int i; | ||
| 347 | int val = 0; | ||
| 348 | |||
| 349 | /* | ||
| 350 | * Update RX statistics. | ||
| 351 | */ | ||
| 352 | mode = &rt2x00dev->hwmodes[rt2x00dev->curr_hwmode]; | ||
| 353 | for (i = 0; i < mode->num_rates; i++) { | ||
| 354 | rate = &mode->rates[i]; | ||
| 355 | |||
| 356 | /* | ||
| 357 | * When frame was received with an OFDM bitrate, | ||
| 358 | * the signal is the PLCP value. If it was received with | ||
| 359 | * a CCK bitrate the signal is the rate in 0.5kbit/s. | ||
| 360 | */ | ||
| 361 | if (!ofdm) | ||
| 362 | val = DEVICE_GET_RATE_FIELD(rate->val, RATE); | ||
| 363 | else | ||
| 364 | val = DEVICE_GET_RATE_FIELD(rate->val, PLCP); | ||
| 365 | |||
| 366 | if (val == signal) { | ||
| 367 | val = rate->val; | ||
| 368 | break; | ||
| 369 | } | ||
| 370 | } | ||
| 371 | |||
| 372 | rt2x00_update_link_rssi(&rt2x00dev->link, rssi); | ||
| 373 | rt2x00dev->link.rx_success++; | ||
| 374 | rx_status->rate = val; | ||
| 375 | rx_status->signal = rt2x00lib_calculate_link_signal(rt2x00dev, rssi); | ||
| 376 | rx_status->ssi = rssi; | ||
| 377 | |||
| 378 | /* | ||
| 379 | * Send frame to mac80211 | ||
| 380 | */ | ||
| 381 | ieee80211_rx_irqsafe(rt2x00dev->hw, skb, rx_status); | ||
| 382 | } | ||
| 383 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); | ||
| 384 | |||
| 385 | /* | ||
| 386 | * TX descriptor initializer | ||
| 387 | */ | ||
| 388 | void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | ||
| 389 | struct data_desc *txd, | ||
| 390 | struct ieee80211_hdr *ieee80211hdr, | ||
| 391 | unsigned int length, | ||
| 392 | struct ieee80211_tx_control *control) | ||
| 393 | { | ||
| 394 | struct data_entry_desc desc; | ||
| 395 | struct data_ring *ring; | ||
| 396 | int tx_rate; | ||
| 397 | int bitrate; | ||
| 398 | int duration; | ||
| 399 | int residual; | ||
| 400 | u16 frame_control; | ||
| 401 | u16 seq_ctrl; | ||
| 402 | |||
| 403 | /* | ||
| 404 | * Make sure the descriptor is properly cleared. | ||
| 405 | */ | ||
| 406 | memset(&desc, 0x00, sizeof(desc)); | ||
| 407 | |||
| 408 | /* | ||
| 409 | * Get ring pointer, if we fail to obtain the | ||
| 410 | * correct ring, then use the first TX ring. | ||
| 411 | */ | ||
| 412 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
| 413 | if (!ring) | ||
| 414 | ring = rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0); | ||
| 415 | |||
| 416 | desc.cw_min = ring->tx_params.cw_min; | ||
| 417 | desc.cw_max = ring->tx_params.cw_max; | ||
| 418 | desc.aifs = ring->tx_params.aifs; | ||
| 419 | |||
| 420 | /* | ||
| 421 | * Identify queue | ||
| 422 | */ | ||
| 423 | if (control->queue < rt2x00dev->hw->queues) | ||
| 424 | desc.queue = control->queue; | ||
| 425 | else if (control->queue == IEEE80211_TX_QUEUE_BEACON || | ||
| 426 | control->queue == IEEE80211_TX_QUEUE_AFTER_BEACON) | ||
| 427 | desc.queue = QUEUE_MGMT; | ||
| 428 | else | ||
| 429 | desc.queue = QUEUE_OTHER; | ||
| 430 | |||
| 431 | /* | ||
| 432 | * Read required fields from ieee80211 header. | ||
| 433 | */ | ||
| 434 | frame_control = le16_to_cpu(ieee80211hdr->frame_control); | ||
| 435 | seq_ctrl = le16_to_cpu(ieee80211hdr->seq_ctrl); | ||
| 436 | |||
| 437 | tx_rate = control->tx_rate; | ||
| 438 | |||
| 439 | /* | ||
| 440 | * Check if this is a RTS/CTS frame | ||
| 441 | */ | ||
| 442 | if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { | ||
| 443 | __set_bit(ENTRY_TXD_BURST, &desc.flags); | ||
| 444 | if (is_rts_frame(frame_control)) | ||
| 445 | __set_bit(ENTRY_TXD_RTS_FRAME, &desc.flags); | ||
| 446 | if (control->rts_cts_rate) | ||
| 447 | tx_rate = control->rts_cts_rate; | ||
| 448 | } | ||
| 449 | |||
| 450 | /* | ||
| 451 | * Check for OFDM | ||
| 452 | */ | ||
| 453 | if (DEVICE_GET_RATE_FIELD(tx_rate, RATEMASK) & DEV_OFDM_RATEMASK) | ||
| 454 | __set_bit(ENTRY_TXD_OFDM_RATE, &desc.flags); | ||
| 455 | |||
| 456 | /* | ||
| 457 | * Check if more fragments are pending | ||
| 458 | */ | ||
| 459 | if (ieee80211_get_morefrag(ieee80211hdr)) { | ||
| 460 | __set_bit(ENTRY_TXD_BURST, &desc.flags); | ||
| 461 | __set_bit(ENTRY_TXD_MORE_FRAG, &desc.flags); | ||
| 462 | } | ||
| 463 | |||
| 464 | /* | ||
| 465 | * Beacons and probe responses require the tsf timestamp | ||
| 466 | * to be inserted into the frame. | ||
| 467 | */ | ||
| 468 | if (control->queue == IEEE80211_TX_QUEUE_BEACON || | ||
| 469 | is_probe_resp(frame_control)) | ||
| 470 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc.flags); | ||
| 471 | |||
| 472 | /* | ||
| 473 | * Determine with what IFS priority this frame should be send. | ||
| 474 | * Set ifs to IFS_SIFS when the this is not the first fragment, | ||
| 475 | * or this fragment came after RTS/CTS. | ||
| 476 | */ | ||
| 477 | if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 || | ||
| 478 | test_bit(ENTRY_TXD_RTS_FRAME, &desc.flags)) | ||
| 479 | desc.ifs = IFS_SIFS; | ||
| 480 | else | ||
| 481 | desc.ifs = IFS_BACKOFF; | ||
| 482 | |||
| 483 | /* | ||
| 484 | * PLCP setup | ||
| 485 | * Length calculation depends on OFDM/CCK rate. | ||
| 486 | */ | ||
| 487 | desc.signal = DEVICE_GET_RATE_FIELD(tx_rate, PLCP); | ||
| 488 | desc.service = 0x04; | ||
| 489 | |||
| 490 | if (test_bit(ENTRY_TXD_OFDM_RATE, &desc.flags)) { | ||
| 491 | desc.length_high = ((length + FCS_LEN) >> 6) & 0x3f; | ||
| 492 | desc.length_low = ((length + FCS_LEN) & 0x3f); | ||
| 493 | } else { | ||
| 494 | bitrate = DEVICE_GET_RATE_FIELD(tx_rate, RATE); | ||
| 495 | |||
| 496 | /* | ||
| 497 | * Convert length to microseconds. | ||
| 498 | */ | ||
| 499 | residual = get_duration_res(length + FCS_LEN, bitrate); | ||
| 500 | duration = get_duration(length + FCS_LEN, bitrate); | ||
| 501 | |||
| 502 | if (residual != 0) { | ||
| 503 | duration++; | ||
| 504 | |||
| 505 | /* | ||
| 506 | * Check if we need to set the Length Extension | ||
| 507 | */ | ||
| 508 | if (bitrate == 110 && residual <= 3) | ||
| 509 | desc.service |= 0x80; | ||
| 510 | } | ||
| 511 | |||
| 512 | desc.length_high = (duration >> 8) & 0xff; | ||
| 513 | desc.length_low = duration & 0xff; | ||
| 514 | |||
| 515 | /* | ||
| 516 | * When preamble is enabled we should set the | ||
| 517 | * preamble bit for the signal. | ||
| 518 | */ | ||
| 519 | if (DEVICE_GET_RATE_FIELD(tx_rate, PREAMBLE)) | ||
| 520 | desc.signal |= 0x08; | ||
| 521 | } | ||
| 522 | |||
| 523 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, txd, &desc, | ||
| 524 | ieee80211hdr, length, control); | ||
| 525 | } | ||
| 526 | EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc); | ||
| 527 | |||
| 528 | /* | ||
| 529 | * Driver initialization handlers. | ||
| 530 | */ | ||
| 531 | static void rt2x00lib_channel(struct ieee80211_channel *entry, | ||
| 532 | const int channel, const int tx_power, | ||
| 533 | const int value) | ||
| 534 | { | ||
| 535 | entry->chan = channel; | ||
| 536 | if (channel <= 14) | ||
| 537 | entry->freq = 2407 + (5 * channel); | ||
| 538 | else | ||
| 539 | entry->freq = 5000 + (5 * channel); | ||
| 540 | entry->val = value; | ||
| 541 | entry->flag = | ||
| 542 | IEEE80211_CHAN_W_IBSS | | ||
| 543 | IEEE80211_CHAN_W_ACTIVE_SCAN | | ||
| 544 | IEEE80211_CHAN_W_SCAN; | ||
| 545 | entry->power_level = tx_power; | ||
| 546 | entry->antenna_max = 0xff; | ||
| 547 | } | ||
| 548 | |||
| 549 | static void rt2x00lib_rate(struct ieee80211_rate *entry, | ||
| 550 | const int rate, const int mask, | ||
| 551 | const int plcp, const int flags) | ||
| 552 | { | ||
| 553 | entry->rate = rate; | ||
| 554 | entry->val = | ||
| 555 | DEVICE_SET_RATE_FIELD(rate, RATE) | | ||
| 556 | DEVICE_SET_RATE_FIELD(mask, RATEMASK) | | ||
| 557 | DEVICE_SET_RATE_FIELD(plcp, PLCP); | ||
| 558 | entry->flags = flags; | ||
| 559 | entry->val2 = entry->val; | ||
| 560 | if (entry->flags & IEEE80211_RATE_PREAMBLE2) | ||
| 561 | entry->val2 |= DEVICE_SET_RATE_FIELD(1, PREAMBLE); | ||
| 562 | entry->min_rssi_ack = 0; | ||
| 563 | entry->min_rssi_ack_delta = 0; | ||
| 564 | } | ||
| 565 | |||
| 566 | static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | ||
| 567 | struct hw_mode_spec *spec) | ||
| 568 | { | ||
| 569 | struct ieee80211_hw *hw = rt2x00dev->hw; | ||
| 570 | struct ieee80211_hw_mode *hwmodes; | ||
| 571 | struct ieee80211_channel *channels; | ||
| 572 | struct ieee80211_rate *rates; | ||
| 573 | unsigned int i; | ||
| 574 | unsigned char tx_power; | ||
| 575 | |||
| 576 | hwmodes = kzalloc(sizeof(*hwmodes) * spec->num_modes, GFP_KERNEL); | ||
| 577 | if (!hwmodes) | ||
| 578 | goto exit; | ||
| 579 | |||
| 580 | channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL); | ||
| 581 | if (!channels) | ||
| 582 | goto exit_free_modes; | ||
| 583 | |||
| 584 | rates = kzalloc(sizeof(*rates) * spec->num_rates, GFP_KERNEL); | ||
| 585 | if (!rates) | ||
| 586 | goto exit_free_channels; | ||
| 587 | |||
| 588 | /* | ||
| 589 | * Initialize Rate list. | ||
| 590 | */ | ||
| 591 | rt2x00lib_rate(&rates[0], 10, DEV_RATEMASK_1MB, | ||
| 592 | 0x00, IEEE80211_RATE_CCK); | ||
| 593 | rt2x00lib_rate(&rates[1], 20, DEV_RATEMASK_2MB, | ||
| 594 | 0x01, IEEE80211_RATE_CCK_2); | ||
| 595 | rt2x00lib_rate(&rates[2], 55, DEV_RATEMASK_5_5MB, | ||
| 596 | 0x02, IEEE80211_RATE_CCK_2); | ||
| 597 | rt2x00lib_rate(&rates[3], 110, DEV_RATEMASK_11MB, | ||
| 598 | 0x03, IEEE80211_RATE_CCK_2); | ||
| 599 | |||
| 600 | if (spec->num_rates > 4) { | ||
| 601 | rt2x00lib_rate(&rates[4], 60, DEV_RATEMASK_6MB, | ||
| 602 | 0x0b, IEEE80211_RATE_OFDM); | ||
| 603 | rt2x00lib_rate(&rates[5], 90, DEV_RATEMASK_9MB, | ||
| 604 | 0x0f, IEEE80211_RATE_OFDM); | ||
| 605 | rt2x00lib_rate(&rates[6], 120, DEV_RATEMASK_12MB, | ||
| 606 | 0x0a, IEEE80211_RATE_OFDM); | ||
| 607 | rt2x00lib_rate(&rates[7], 180, DEV_RATEMASK_18MB, | ||
| 608 | 0x0e, IEEE80211_RATE_OFDM); | ||
| 609 | rt2x00lib_rate(&rates[8], 240, DEV_RATEMASK_24MB, | ||
| 610 | 0x09, IEEE80211_RATE_OFDM); | ||
| 611 | rt2x00lib_rate(&rates[9], 360, DEV_RATEMASK_36MB, | ||
| 612 | 0x0d, IEEE80211_RATE_OFDM); | ||
| 613 | rt2x00lib_rate(&rates[10], 480, DEV_RATEMASK_48MB, | ||
| 614 | 0x08, IEEE80211_RATE_OFDM); | ||
| 615 | rt2x00lib_rate(&rates[11], 540, DEV_RATEMASK_54MB, | ||
| 616 | 0x0c, IEEE80211_RATE_OFDM); | ||
| 617 | } | ||
| 618 | |||
| 619 | /* | ||
| 620 | * Initialize Channel list. | ||
| 621 | */ | ||
| 622 | for (i = 0; i < spec->num_channels; i++) { | ||
| 623 | if (spec->channels[i].channel <= 14) | ||
| 624 | tx_power = spec->tx_power_bg[i]; | ||
| 625 | else if (spec->tx_power_a) | ||
| 626 | tx_power = spec->tx_power_a[i]; | ||
| 627 | else | ||
| 628 | tx_power = spec->tx_power_default; | ||
| 629 | |||
| 630 | rt2x00lib_channel(&channels[i], | ||
| 631 | spec->channels[i].channel, tx_power, i); | ||
| 632 | } | ||
| 633 | |||
| 634 | /* | ||
| 635 | * Intitialize 802.11b | ||
| 636 | * Rates: CCK. | ||
| 637 | * Channels: OFDM. | ||
| 638 | */ | ||
| 639 | if (spec->num_modes > HWMODE_B) { | ||
| 640 | hwmodes[HWMODE_B].mode = MODE_IEEE80211B; | ||
| 641 | hwmodes[HWMODE_B].num_channels = 14; | ||
| 642 | hwmodes[HWMODE_B].num_rates = 4; | ||
| 643 | hwmodes[HWMODE_B].channels = channels; | ||
| 644 | hwmodes[HWMODE_B].rates = rates; | ||
| 645 | } | ||
| 646 | |||
| 647 | /* | ||
| 648 | * Intitialize 802.11g | ||
| 649 | * Rates: CCK, OFDM. | ||
| 650 | * Channels: OFDM. | ||
| 651 | */ | ||
| 652 | if (spec->num_modes > HWMODE_G) { | ||
| 653 | hwmodes[HWMODE_G].mode = MODE_IEEE80211G; | ||
| 654 | hwmodes[HWMODE_G].num_channels = 14; | ||
| 655 | hwmodes[HWMODE_G].num_rates = spec->num_rates; | ||
| 656 | hwmodes[HWMODE_G].channels = channels; | ||
| 657 | hwmodes[HWMODE_G].rates = rates; | ||
| 658 | } | ||
| 659 | |||
| 660 | /* | ||
| 661 | * Intitialize 802.11a | ||
| 662 | * Rates: OFDM. | ||
| 663 | * Channels: OFDM, UNII, HiperLAN2. | ||
| 664 | */ | ||
| 665 | if (spec->num_modes > HWMODE_A) { | ||
| 666 | hwmodes[HWMODE_A].mode = MODE_IEEE80211A; | ||
| 667 | hwmodes[HWMODE_A].num_channels = spec->num_channels - 14; | ||
| 668 | hwmodes[HWMODE_A].num_rates = spec->num_rates - 4; | ||
| 669 | hwmodes[HWMODE_A].channels = &channels[14]; | ||
| 670 | hwmodes[HWMODE_A].rates = &rates[4]; | ||
| 671 | } | ||
| 672 | |||
| 673 | if (spec->num_modes > HWMODE_G && | ||
| 674 | ieee80211_register_hwmode(hw, &hwmodes[HWMODE_G])) | ||
| 675 | goto exit_free_rates; | ||
| 676 | |||
| 677 | if (spec->num_modes > HWMODE_B && | ||
| 678 | ieee80211_register_hwmode(hw, &hwmodes[HWMODE_B])) | ||
| 679 | goto exit_free_rates; | ||
| 680 | |||
| 681 | if (spec->num_modes > HWMODE_A && | ||
| 682 | ieee80211_register_hwmode(hw, &hwmodes[HWMODE_A])) | ||
| 683 | goto exit_free_rates; | ||
| 684 | |||
| 685 | rt2x00dev->hwmodes = hwmodes; | ||
| 686 | |||
| 687 | return 0; | ||
| 688 | |||
| 689 | exit_free_rates: | ||
| 690 | kfree(rates); | ||
| 691 | |||
| 692 | exit_free_channels: | ||
| 693 | kfree(channels); | ||
| 694 | |||
| 695 | exit_free_modes: | ||
| 696 | kfree(hwmodes); | ||
| 697 | |||
| 698 | exit: | ||
| 699 | ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n"); | ||
| 700 | return -ENOMEM; | ||
| 701 | } | ||
| 702 | |||
| 703 | static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev) | ||
| 704 | { | ||
| 705 | if (test_bit(DEVICE_INITIALIZED_HW, &rt2x00dev->flags)) | ||
| 706 | ieee80211_unregister_hw(rt2x00dev->hw); | ||
| 707 | |||
| 708 | if (likely(rt2x00dev->hwmodes)) { | ||
| 709 | kfree(rt2x00dev->hwmodes->channels); | ||
| 710 | kfree(rt2x00dev->hwmodes->rates); | ||
| 711 | kfree(rt2x00dev->hwmodes); | ||
| 712 | rt2x00dev->hwmodes = NULL; | ||
| 713 | } | ||
| 714 | } | ||
| 715 | |||
| 716 | static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) | ||
| 717 | { | ||
| 718 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
| 719 | int status; | ||
| 720 | |||
| 721 | /* | ||
| 722 | * Initialize HW modes. | ||
| 723 | */ | ||
| 724 | status = rt2x00lib_probe_hw_modes(rt2x00dev, spec); | ||
| 725 | if (status) | ||
| 726 | return status; | ||
| 727 | |||
| 728 | /* | ||
| 729 | * Register HW. | ||
| 730 | */ | ||
| 731 | status = ieee80211_register_hw(rt2x00dev->hw); | ||
| 732 | if (status) { | ||
| 733 | rt2x00lib_remove_hw(rt2x00dev); | ||
| 734 | return status; | ||
| 735 | } | ||
| 736 | |||
| 737 | __set_bit(DEVICE_INITIALIZED_HW, &rt2x00dev->flags); | ||
| 738 | |||
| 739 | return 0; | ||
| 740 | } | ||
| 741 | |||
| 742 | /* | ||
| 743 | * Initialization/uninitialization handlers. | ||
| 744 | */ | ||
| 745 | static int rt2x00lib_alloc_entries(struct data_ring *ring, | ||
| 746 | const u16 max_entries, const u16 data_size, | ||
| 747 | const u16 desc_size) | ||
| 748 | { | ||
| 749 | struct data_entry *entry; | ||
| 750 | unsigned int i; | ||
| 751 | |||
| 752 | ring->stats.limit = max_entries; | ||
| 753 | ring->data_size = data_size; | ||
| 754 | ring->desc_size = desc_size; | ||
| 755 | |||
| 756 | /* | ||
| 757 | * Allocate all ring entries. | ||
| 758 | */ | ||
| 759 | entry = kzalloc(ring->stats.limit * sizeof(*entry), GFP_KERNEL); | ||
| 760 | if (!entry) | ||
| 761 | return -ENOMEM; | ||
| 762 | |||
| 763 | for (i = 0; i < ring->stats.limit; i++) { | ||
| 764 | entry[i].flags = 0; | ||
| 765 | entry[i].ring = ring; | ||
| 766 | entry[i].skb = NULL; | ||
| 767 | } | ||
| 768 | |||
| 769 | ring->entry = entry; | ||
| 770 | |||
| 771 | return 0; | ||
| 772 | } | ||
| 773 | |||
| 774 | static int rt2x00lib_alloc_ring_entries(struct rt2x00_dev *rt2x00dev) | ||
| 775 | { | ||
| 776 | struct data_ring *ring; | ||
| 777 | |||
| 778 | /* | ||
| 779 | * Allocate the RX ring. | ||
| 780 | */ | ||
| 781 | if (rt2x00lib_alloc_entries(rt2x00dev->rx, RX_ENTRIES, DATA_FRAME_SIZE, | ||
| 782 | rt2x00dev->ops->rxd_size)) | ||
| 783 | return -ENOMEM; | ||
| 784 | |||
| 785 | /* | ||
| 786 | * First allocate the TX rings. | ||
| 787 | */ | ||
| 788 | txring_for_each(rt2x00dev, ring) { | ||
| 789 | if (rt2x00lib_alloc_entries(ring, TX_ENTRIES, DATA_FRAME_SIZE, | ||
| 790 | rt2x00dev->ops->txd_size)) | ||
| 791 | return -ENOMEM; | ||
| 792 | } | ||
| 793 | |||
| 794 | if (!test_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags)) | ||
| 795 | return 0; | ||
| 796 | |||
| 797 | /* | ||
| 798 | * Allocate the BEACON ring. | ||
| 799 | */ | ||
| 800 | if (rt2x00lib_alloc_entries(&rt2x00dev->bcn[0], BEACON_ENTRIES, | ||
| 801 | MGMT_FRAME_SIZE, rt2x00dev->ops->txd_size)) | ||
| 802 | return -ENOMEM; | ||
| 803 | |||
| 804 | /* | ||
| 805 | * Allocate the Atim ring. | ||
| 806 | */ | ||
| 807 | if (rt2x00lib_alloc_entries(&rt2x00dev->bcn[1], ATIM_ENTRIES, | ||
| 808 | DATA_FRAME_SIZE, rt2x00dev->ops->txd_size)) | ||
| 809 | return -ENOMEM; | ||
| 810 | |||
| 811 | return 0; | ||
| 812 | } | ||
| 813 | |||
| 814 | static void rt2x00lib_free_ring_entries(struct rt2x00_dev *rt2x00dev) | ||
| 815 | { | ||
| 816 | struct data_ring *ring; | ||
| 817 | |||
| 818 | ring_for_each(rt2x00dev, ring) { | ||
| 819 | kfree(ring->entry); | ||
| 820 | ring->entry = NULL; | ||
| 821 | } | ||
| 822 | } | ||
| 823 | |||
| 824 | void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) | ||
| 825 | { | ||
| 826 | if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) | ||
| 827 | return; | ||
| 828 | |||
| 829 | /* | ||
| 830 | * Unregister rfkill. | ||
| 831 | */ | ||
| 832 | rt2x00rfkill_unregister(rt2x00dev); | ||
| 833 | |||
| 834 | /* | ||
| 835 | * Allow the HW to uninitialize. | ||
| 836 | */ | ||
| 837 | rt2x00dev->ops->lib->uninitialize(rt2x00dev); | ||
| 838 | |||
| 839 | /* | ||
| 840 | * Free allocated ring entries. | ||
| 841 | */ | ||
| 842 | rt2x00lib_free_ring_entries(rt2x00dev); | ||
| 843 | } | ||
| 844 | |||
| 845 | int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | ||
| 846 | { | ||
| 847 | int status; | ||
| 848 | |||
| 849 | if (test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) | ||
| 850 | return 0; | ||
| 851 | |||
| 852 | /* | ||
| 853 | * Allocate all ring entries. | ||
| 854 | */ | ||
| 855 | status = rt2x00lib_alloc_ring_entries(rt2x00dev); | ||
| 856 | if (status) { | ||
| 857 | ERROR(rt2x00dev, "Ring entries allocation failed.\n"); | ||
| 858 | return status; | ||
| 859 | } | ||
| 860 | |||
| 861 | /* | ||
| 862 | * Initialize the device. | ||
| 863 | */ | ||
| 864 | status = rt2x00dev->ops->lib->initialize(rt2x00dev); | ||
| 865 | if (status) | ||
| 866 | goto exit; | ||
| 867 | |||
| 868 | __set_bit(DEVICE_INITIALIZED, &rt2x00dev->flags); | ||
| 869 | |||
| 870 | /* | ||
| 871 | * Register the rfkill handler. | ||
| 872 | */ | ||
| 873 | status = rt2x00rfkill_register(rt2x00dev); | ||
| 874 | if (status) | ||
| 875 | goto exit_unitialize; | ||
| 876 | |||
| 877 | return 0; | ||
| 878 | |||
| 879 | exit_unitialize: | ||
| 880 | rt2x00lib_uninitialize(rt2x00dev); | ||
| 881 | |||
| 882 | exit: | ||
| 883 | rt2x00lib_free_ring_entries(rt2x00dev); | ||
| 884 | |||
| 885 | return status; | ||
| 886 | } | ||
| 887 | |||
| 888 | /* | ||
| 889 | * driver allocation handlers. | ||
| 890 | */ | ||
| 891 | static int rt2x00lib_alloc_rings(struct rt2x00_dev *rt2x00dev) | ||
| 892 | { | ||
| 893 | struct data_ring *ring; | ||
| 894 | |||
| 895 | /* | ||
| 896 | * We need the following rings: | ||
| 897 | * RX: 1 | ||
| 898 | * TX: hw->queues | ||
| 899 | * Beacon: 1 (if required) | ||
| 900 | * Atim: 1 (if required) | ||
| 901 | */ | ||
| 902 | rt2x00dev->data_rings = 1 + rt2x00dev->hw->queues + | ||
| 903 | (2 * test_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags)); | ||
| 904 | |||
| 905 | ring = kzalloc(rt2x00dev->data_rings * sizeof(*ring), GFP_KERNEL); | ||
| 906 | if (!ring) { | ||
| 907 | ERROR(rt2x00dev, "Ring allocation failed.\n"); | ||
| 908 | return -ENOMEM; | ||
| 909 | } | ||
| 910 | |||
| 911 | /* | ||
| 912 | * Initialize pointers | ||
| 913 | */ | ||
| 914 | rt2x00dev->rx = ring; | ||
| 915 | rt2x00dev->tx = &rt2x00dev->rx[1]; | ||
| 916 | if (test_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags)) | ||
| 917 | rt2x00dev->bcn = &rt2x00dev->tx[rt2x00dev->hw->queues]; | ||
| 918 | |||
| 919 | /* | ||
| 920 | * Initialize ring parameters. | ||
| 921 | * cw_min: 2^5 = 32. | ||
| 922 | * cw_max: 2^10 = 1024. | ||
| 923 | */ | ||
| 924 | ring_for_each(rt2x00dev, ring) { | ||
| 925 | ring->rt2x00dev = rt2x00dev; | ||
| 926 | ring->tx_params.aifs = 2; | ||
| 927 | ring->tx_params.cw_min = 5; | ||
| 928 | ring->tx_params.cw_max = 10; | ||
| 929 | } | ||
| 930 | |||
| 931 | return 0; | ||
| 932 | } | ||
| 933 | |||
| 934 | static void rt2x00lib_free_rings(struct rt2x00_dev *rt2x00dev) | ||
| 935 | { | ||
| 936 | kfree(rt2x00dev->rx); | ||
| 937 | rt2x00dev->rx = NULL; | ||
| 938 | rt2x00dev->tx = NULL; | ||
| 939 | rt2x00dev->bcn = NULL; | ||
| 940 | } | ||
| 941 | |||
| 942 | int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | ||
| 943 | { | ||
| 944 | int retval = -ENOMEM; | ||
| 945 | |||
| 946 | /* | ||
| 947 | * Let the driver probe the device to detect the capabilities. | ||
| 948 | */ | ||
| 949 | retval = rt2x00dev->ops->lib->probe_hw(rt2x00dev); | ||
| 950 | if (retval) { | ||
| 951 | ERROR(rt2x00dev, "Failed to allocate device.\n"); | ||
| 952 | goto exit; | ||
| 953 | } | ||
| 954 | |||
| 955 | /* | ||
| 956 | * Initialize configuration work. | ||
| 957 | */ | ||
| 958 | INIT_WORK(&rt2x00dev->beacon_work, rt2x00lib_beacondone_scheduled); | ||
| 959 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); | ||
| 960 | |||
| 961 | /* | ||
| 962 | * Reset current working type. | ||
| 963 | */ | ||
| 964 | rt2x00dev->interface.type = INVALID_INTERFACE; | ||
| 965 | |||
| 966 | /* | ||
| 967 | * Allocate ring array. | ||
| 968 | */ | ||
| 969 | retval = rt2x00lib_alloc_rings(rt2x00dev); | ||
| 970 | if (retval) | ||
| 971 | goto exit; | ||
| 972 | |||
| 973 | /* | ||
| 974 | * Initialize ieee80211 structure. | ||
| 975 | */ | ||
| 976 | retval = rt2x00lib_probe_hw(rt2x00dev); | ||
| 977 | if (retval) { | ||
| 978 | ERROR(rt2x00dev, "Failed to initialize hw.\n"); | ||
| 979 | goto exit; | ||
| 980 | } | ||
| 981 | |||
| 982 | /* | ||
| 983 | * Allocatie rfkill. | ||
| 984 | */ | ||
| 985 | retval = rt2x00rfkill_allocate(rt2x00dev); | ||
| 986 | if (retval) | ||
| 987 | goto exit; | ||
| 988 | |||
| 989 | /* | ||
| 990 | * Open the debugfs entry. | ||
| 991 | */ | ||
| 992 | rt2x00debug_register(rt2x00dev); | ||
| 993 | |||
| 994 | return 0; | ||
| 995 | |||
| 996 | exit: | ||
| 997 | rt2x00lib_remove_dev(rt2x00dev); | ||
| 998 | |||
| 999 | return retval; | ||
| 1000 | } | ||
| 1001 | EXPORT_SYMBOL_GPL(rt2x00lib_probe_dev); | ||
| 1002 | |||
| 1003 | void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | ||
| 1004 | { | ||
| 1005 | /* | ||
| 1006 | * Disable radio. | ||
| 1007 | */ | ||
| 1008 | rt2x00lib_disable_radio(rt2x00dev); | ||
| 1009 | |||
| 1010 | /* | ||
| 1011 | * Uninitialize device. | ||
| 1012 | */ | ||
| 1013 | rt2x00lib_uninitialize(rt2x00dev); | ||
| 1014 | |||
| 1015 | /* | ||
| 1016 | * Close debugfs entry. | ||
| 1017 | */ | ||
| 1018 | rt2x00debug_deregister(rt2x00dev); | ||
| 1019 | |||
| 1020 | /* | ||
| 1021 | * Free rfkill | ||
| 1022 | */ | ||
| 1023 | rt2x00rfkill_free(rt2x00dev); | ||
| 1024 | |||
| 1025 | /* | ||
| 1026 | * Free ieee80211_hw memory. | ||
| 1027 | */ | ||
| 1028 | rt2x00lib_remove_hw(rt2x00dev); | ||
| 1029 | |||
| 1030 | /* | ||
| 1031 | * Free firmware image. | ||
| 1032 | */ | ||
| 1033 | rt2x00lib_free_firmware(rt2x00dev); | ||
| 1034 | |||
| 1035 | /* | ||
| 1036 | * Free ring structures. | ||
| 1037 | */ | ||
| 1038 | rt2x00lib_free_rings(rt2x00dev); | ||
| 1039 | } | ||
| 1040 | EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); | ||
| 1041 | |||
| 1042 | /* | ||
| 1043 | * Device state handlers | ||
| 1044 | */ | ||
| 1045 | #ifdef CONFIG_PM | ||
| 1046 | int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) | ||
| 1047 | { | ||
| 1048 | int retval; | ||
| 1049 | |||
| 1050 | NOTICE(rt2x00dev, "Going to sleep.\n"); | ||
| 1051 | |||
| 1052 | /* | ||
| 1053 | * Disable radio and unitialize all items | ||
| 1054 | * that must be recreated on resume. | ||
| 1055 | */ | ||
| 1056 | rt2x00lib_disable_radio(rt2x00dev); | ||
| 1057 | rt2x00lib_uninitialize(rt2x00dev); | ||
| 1058 | rt2x00debug_deregister(rt2x00dev); | ||
| 1059 | |||
| 1060 | /* | ||
| 1061 | * Set device mode to sleep for power management. | ||
| 1062 | */ | ||
| 1063 | retval = rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP); | ||
| 1064 | if (retval) | ||
| 1065 | return retval; | ||
| 1066 | |||
| 1067 | return 0; | ||
| 1068 | } | ||
| 1069 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); | ||
| 1070 | |||
| 1071 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | ||
| 1072 | { | ||
| 1073 | struct interface *intf = &rt2x00dev->interface; | ||
| 1074 | int retval; | ||
| 1075 | |||
| 1076 | NOTICE(rt2x00dev, "Waking up.\n"); | ||
| 1077 | __set_bit(INTERFACE_RESUME, &rt2x00dev->flags); | ||
| 1078 | |||
| 1079 | /* | ||
| 1080 | * Open the debugfs entry. | ||
| 1081 | */ | ||
| 1082 | rt2x00debug_register(rt2x00dev); | ||
| 1083 | |||
| 1084 | /* | ||
| 1085 | * Reinitialize device and all active interfaces. | ||
| 1086 | */ | ||
| 1087 | retval = rt2x00mac_start(rt2x00dev->hw); | ||
| 1088 | if (retval) | ||
| 1089 | goto exit; | ||
| 1090 | |||
| 1091 | /* | ||
| 1092 | * Reconfigure device. | ||
| 1093 | */ | ||
| 1094 | retval = rt2x00mac_config(rt2x00dev->hw, &rt2x00dev->hw->conf); | ||
| 1095 | if (retval) | ||
| 1096 | goto exit; | ||
| 1097 | |||
| 1098 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | ||
| 1099 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | ||
| 1100 | rt2x00lib_config_type(rt2x00dev, intf->type); | ||
| 1101 | rt2x00lib_config_packet_filter(rt2x00dev, intf->filter); | ||
| 1102 | |||
| 1103 | /* | ||
| 1104 | * When in Master or Ad-hoc mode, | ||
| 1105 | * restart Beacon transmitting by faking a beacondone event. | ||
| 1106 | */ | ||
| 1107 | if (intf->type == IEEE80211_IF_TYPE_AP || | ||
| 1108 | intf->type == IEEE80211_IF_TYPE_IBSS) | ||
| 1109 | rt2x00lib_beacondone(rt2x00dev); | ||
| 1110 | |||
| 1111 | __clear_bit(INTERFACE_RESUME, &rt2x00dev->flags); | ||
| 1112 | |||
| 1113 | return 0; | ||
| 1114 | |||
| 1115 | exit: | ||
| 1116 | rt2x00lib_disable_radio(rt2x00dev); | ||
| 1117 | rt2x00lib_uninitialize(rt2x00dev); | ||
| 1118 | rt2x00debug_deregister(rt2x00dev); | ||
| 1119 | |||
| 1120 | __clear_bit(INTERFACE_RESUME, &rt2x00dev->flags); | ||
| 1121 | |||
| 1122 | return retval; | ||
| 1123 | } | ||
| 1124 | EXPORT_SYMBOL_GPL(rt2x00lib_resume); | ||
| 1125 | #endif /* CONFIG_PM */ | ||
| 1126 | |||
| 1127 | /* | ||
| 1128 | * rt2x00lib module information. | ||
| 1129 | */ | ||
| 1130 | MODULE_AUTHOR(DRV_PROJECT); | ||
| 1131 | MODULE_VERSION(DRV_VERSION); | ||
| 1132 | MODULE_DESCRIPTION("rt2x00 library"); | ||
| 1133 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c new file mode 100644 index 00000000000..236025f8b90 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00lib | ||
| 23 | Abstract: rt2x00 firmware loading routines. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Set enviroment defines for rt2x00.h | ||
| 28 | */ | ||
| 29 | #define DRV_NAME "rt2x00lib" | ||
| 30 | |||
| 31 | #include <linux/crc-itu-t.h> | ||
| 32 | #include <linux/kernel.h> | ||
| 33 | #include <linux/module.h> | ||
| 34 | |||
| 35 | #include "rt2x00.h" | ||
| 36 | #include "rt2x00lib.h" | ||
| 37 | |||
| 38 | static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) | ||
| 39 | { | ||
| 40 | struct device *device = wiphy_dev(rt2x00dev->hw->wiphy); | ||
| 41 | const struct firmware *fw; | ||
| 42 | char *fw_name; | ||
| 43 | int retval; | ||
| 44 | u16 crc; | ||
| 45 | u16 tmp; | ||
| 46 | |||
| 47 | /* | ||
| 48 | * Read correct firmware from harddisk. | ||
| 49 | */ | ||
| 50 | fw_name = rt2x00dev->ops->lib->get_firmware_name(rt2x00dev); | ||
| 51 | if (!fw_name) { | ||
| 52 | ERROR(rt2x00dev, | ||
| 53 | "Invalid firmware filename.\n" | ||
| 54 | "Please file bug report to %s.\n", DRV_PROJECT); | ||
| 55 | return -EINVAL; | ||
| 56 | } | ||
| 57 | |||
| 58 | INFO(rt2x00dev, "Loading firmware file '%s'.\n", fw_name); | ||
| 59 | |||
| 60 | retval = request_firmware(&fw, fw_name, device); | ||
| 61 | if (retval) { | ||
| 62 | ERROR(rt2x00dev, "Failed to request Firmware.\n"); | ||
| 63 | return retval; | ||
| 64 | } | ||
| 65 | |||
| 66 | if (!fw || !fw->size || !fw->data) { | ||
| 67 | ERROR(rt2x00dev, "Failed to read Firmware.\n"); | ||
| 68 | return -ENOENT; | ||
| 69 | } | ||
| 70 | |||
| 71 | /* | ||
| 72 | * Validate the firmware using 16 bit CRC. | ||
| 73 | * The last 2 bytes of the firmware are the CRC | ||
| 74 | * so substract those 2 bytes from the CRC checksum, | ||
| 75 | * and set those 2 bytes to 0 when calculating CRC. | ||
| 76 | */ | ||
| 77 | tmp = 0; | ||
| 78 | crc = crc_itu_t(0, fw->data, fw->size - 2); | ||
| 79 | crc = crc_itu_t(crc, (u8 *)&tmp, 2); | ||
| 80 | |||
| 81 | if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) { | ||
| 82 | ERROR(rt2x00dev, "Firmware CRC error.\n"); | ||
| 83 | retval = -ENOENT; | ||
| 84 | goto exit; | ||
| 85 | } | ||
| 86 | |||
| 87 | INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n", | ||
| 88 | fw->data[fw->size - 4], fw->data[fw->size - 3]); | ||
| 89 | |||
| 90 | rt2x00dev->fw = fw; | ||
| 91 | |||
| 92 | return 0; | ||
| 93 | |||
| 94 | exit: | ||
| 95 | release_firmware(fw); | ||
| 96 | |||
| 97 | return retval; | ||
| 98 | } | ||
| 99 | |||
| 100 | int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev) | ||
| 101 | { | ||
| 102 | int retval; | ||
| 103 | |||
| 104 | if (!rt2x00dev->fw) { | ||
| 105 | retval = rt2x00lib_request_firmware(rt2x00dev); | ||
| 106 | if (retval) | ||
| 107 | return retval; | ||
| 108 | } | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Send firmware to the device. | ||
| 112 | */ | ||
| 113 | retval = rt2x00dev->ops->lib->load_firmware(rt2x00dev, | ||
| 114 | rt2x00dev->fw->data, | ||
| 115 | rt2x00dev->fw->size); | ||
| 116 | return retval; | ||
| 117 | } | ||
| 118 | |||
| 119 | void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev) | ||
| 120 | { | ||
| 121 | release_firmware(rt2x00dev->fw); | ||
| 122 | rt2x00dev->fw = NULL; | ||
| 123 | } | ||
| 124 | |||
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h new file mode 100644 index 00000000000..3324090a96a --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00lib | ||
| 23 | Abstract: Data structures and definitions for the rt2x00lib module. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #ifndef RT2X00LIB_H | ||
| 27 | #define RT2X00LIB_H | ||
| 28 | |||
| 29 | /* | ||
| 30 | * Interval defines | ||
| 31 | */ | ||
| 32 | #define LINK_TUNE_INTERVAL ( round_jiffies(HZ) ) | ||
| 33 | #define RFKILL_POLL_INTERVAL ( HZ / 4 ) | ||
| 34 | |||
| 35 | /* | ||
| 36 | * Radio control handlers. | ||
| 37 | */ | ||
| 38 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev); | ||
| 39 | void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev); | ||
| 40 | void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, int enable); | ||
| 41 | void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev); | ||
| 42 | |||
| 43 | /* | ||
| 44 | * Initialization handlers. | ||
| 45 | */ | ||
| 46 | int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev); | ||
| 47 | void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev); | ||
| 48 | |||
| 49 | /* | ||
| 50 | * Configuration handlers. | ||
| 51 | */ | ||
| 52 | void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac); | ||
| 53 | void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid); | ||
| 54 | void rt2x00lib_config_packet_filter(struct rt2x00_dev *rt2x00dev, int filter); | ||
| 55 | void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, int type); | ||
| 56 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf); | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Firmware handlers. | ||
| 60 | */ | ||
| 61 | #ifdef CONFIG_RT2X00_LIB_FIRMWARE | ||
| 62 | int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev); | ||
| 63 | void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev); | ||
| 64 | #else | ||
| 65 | static inline int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev) | ||
| 66 | { | ||
| 67 | return 0; | ||
| 68 | } | ||
| 69 | static inline void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev) | ||
| 70 | { | ||
| 71 | } | ||
| 72 | #endif /* CONFIG_RT2X00_LIB_FIRMWARE */ | ||
| 73 | |||
| 74 | /* | ||
| 75 | * Debugfs handlers. | ||
| 76 | */ | ||
| 77 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
| 78 | void rt2x00debug_register(struct rt2x00_dev *rt2x00dev); | ||
| 79 | void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev); | ||
| 80 | #else | ||
| 81 | static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | ||
| 82 | { | ||
| 83 | } | ||
| 84 | |||
| 85 | static inline void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) | ||
| 86 | { | ||
| 87 | } | ||
| 88 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
| 89 | |||
| 90 | /* | ||
| 91 | * RFkill handlers. | ||
| 92 | */ | ||
| 93 | #ifdef CONFIG_RT2X00_LIB_RFKILL | ||
| 94 | int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev); | ||
| 95 | void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev); | ||
| 96 | int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev); | ||
| 97 | void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev); | ||
| 98 | #else | ||
| 99 | static inline int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) | ||
| 100 | { | ||
| 101 | /* | ||
| 102 | * Force enable this flag, this will assure that | ||
| 103 | * devices with a hardware button but without rfkill support | ||
| 104 | * can still use their hardware. | ||
| 105 | */ | ||
| 106 | __set_bit(DEVICE_ENABLED_RADIO_HW, &rt2x00dev->flags); | ||
| 107 | |||
| 108 | return 0; | ||
| 109 | } | ||
| 110 | |||
| 111 | static inline void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) | ||
| 112 | { | ||
| 113 | } | ||
| 114 | |||
| 115 | static inline int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) | ||
| 116 | { | ||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | |||
| 120 | static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) | ||
| 121 | { | ||
| 122 | } | ||
| 123 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ | ||
| 124 | |||
| 125 | #endif /* RT2X00LIB_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c new file mode 100644 index 00000000000..778ed41e21e --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
| @@ -0,0 +1,459 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00mac | ||
| 23 | Abstract: rt2x00 generic mac80211 routines. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Set enviroment defines for rt2x00.h | ||
| 28 | */ | ||
| 29 | #define DRV_NAME "rt2x00lib" | ||
| 30 | |||
| 31 | #include <linux/kernel.h> | ||
| 32 | #include <linux/module.h> | ||
| 33 | |||
| 34 | #include "rt2x00.h" | ||
| 35 | #include "rt2x00lib.h" | ||
| 36 | |||
| 37 | static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | ||
| 38 | struct data_ring *ring, | ||
| 39 | struct sk_buff *frag_skb, | ||
| 40 | struct ieee80211_tx_control *control) | ||
| 41 | { | ||
| 42 | struct sk_buff *skb; | ||
| 43 | int size; | ||
| 44 | |||
| 45 | if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | ||
| 46 | size = sizeof(struct ieee80211_cts); | ||
| 47 | else | ||
| 48 | size = sizeof(struct ieee80211_rts); | ||
| 49 | |||
| 50 | skb = dev_alloc_skb(size + rt2x00dev->hw->extra_tx_headroom); | ||
| 51 | if (!skb) { | ||
| 52 | WARNING(rt2x00dev, "Failed to create RTS/CTS frame.\n"); | ||
| 53 | return NETDEV_TX_BUSY; | ||
| 54 | } | ||
| 55 | |||
| 56 | skb_reserve(skb, rt2x00dev->hw->extra_tx_headroom); | ||
| 57 | skb_put(skb, size); | ||
| 58 | |||
| 59 | if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | ||
| 60 | ieee80211_ctstoself_get(rt2x00dev->hw, rt2x00dev->interface.id, | ||
| 61 | frag_skb->data, frag_skb->len, control, | ||
| 62 | (struct ieee80211_cts *)(skb->data)); | ||
| 63 | else | ||
| 64 | ieee80211_rts_get(rt2x00dev->hw, rt2x00dev->interface.id, | ||
| 65 | frag_skb->data, frag_skb->len, control, | ||
| 66 | (struct ieee80211_rts *)(skb->data)); | ||
| 67 | |||
| 68 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) { | ||
| 69 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); | ||
| 70 | return NETDEV_TX_BUSY; | ||
| 71 | } | ||
| 72 | |||
| 73 | return NETDEV_TX_OK; | ||
| 74 | } | ||
| 75 | |||
| 76 | int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
| 77 | struct ieee80211_tx_control *control) | ||
| 78 | { | ||
| 79 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 80 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; | ||
| 81 | struct data_ring *ring; | ||
| 82 | u16 frame_control; | ||
| 83 | |||
| 84 | /* | ||
| 85 | * Determine which ring to put packet on. | ||
| 86 | */ | ||
| 87 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
| 88 | if (unlikely(!ring)) { | ||
| 89 | ERROR(rt2x00dev, | ||
| 90 | "Attempt to send packet over invalid queue %d.\n" | ||
| 91 | "Please file bug report to %s.\n", | ||
| 92 | control->queue, DRV_PROJECT); | ||
| 93 | dev_kfree_skb_any(skb); | ||
| 94 | return NETDEV_TX_OK; | ||
| 95 | } | ||
| 96 | |||
| 97 | /* | ||
| 98 | * If CTS/RTS is required. and this frame is not CTS or RTS, | ||
| 99 | * create and queue that frame first. But make sure we have | ||
| 100 | * at least enough entries available to send this CTS/RTS | ||
| 101 | * frame as well as the data frame. | ||
| 102 | */ | ||
| 103 | frame_control = le16_to_cpu(ieee80211hdr->frame_control); | ||
| 104 | if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) && | ||
| 105 | (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS | | ||
| 106 | IEEE80211_TXCTL_USE_CTS_PROTECT))) { | ||
| 107 | if (rt2x00_ring_free(ring) <= 1) | ||
| 108 | return NETDEV_TX_BUSY; | ||
| 109 | |||
| 110 | if (rt2x00mac_tx_rts_cts(rt2x00dev, ring, skb, control)) | ||
| 111 | return NETDEV_TX_BUSY; | ||
| 112 | } | ||
| 113 | |||
| 114 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) | ||
| 115 | return NETDEV_TX_BUSY; | ||
| 116 | |||
| 117 | if (rt2x00dev->ops->lib->kick_tx_queue) | ||
| 118 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
| 119 | |||
| 120 | return NETDEV_TX_OK; | ||
| 121 | } | ||
| 122 | EXPORT_SYMBOL_GPL(rt2x00mac_tx); | ||
| 123 | |||
| 124 | int rt2x00mac_start(struct ieee80211_hw *hw) | ||
| 125 | { | ||
| 126 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 127 | int status; | ||
| 128 | |||
| 129 | if (test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) | ||
| 130 | return 0; | ||
| 131 | |||
| 132 | /* | ||
| 133 | * If this is the first interface which is added, | ||
| 134 | * we should load the firmware now. | ||
| 135 | */ | ||
| 136 | if (test_bit(REQUIRE_FIRMWARE, &rt2x00dev->flags)) { | ||
| 137 | status = rt2x00lib_load_firmware(rt2x00dev); | ||
| 138 | if (status) | ||
| 139 | return status; | ||
| 140 | } | ||
| 141 | |||
| 142 | /* | ||
| 143 | * Initialize the device. | ||
| 144 | */ | ||
| 145 | status = rt2x00lib_initialize(rt2x00dev); | ||
| 146 | if (status) | ||
| 147 | return status; | ||
| 148 | |||
| 149 | /* | ||
| 150 | * Enable radio. | ||
| 151 | */ | ||
| 152 | status = rt2x00lib_enable_radio(rt2x00dev); | ||
| 153 | if (status) { | ||
| 154 | rt2x00lib_uninitialize(rt2x00dev); | ||
| 155 | return status; | ||
| 156 | } | ||
| 157 | |||
| 158 | return 0; | ||
| 159 | } | ||
| 160 | EXPORT_SYMBOL_GPL(rt2x00mac_start); | ||
| 161 | |||
| 162 | void rt2x00mac_stop(struct ieee80211_hw *hw) | ||
| 163 | { | ||
| 164 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 165 | |||
| 166 | /* | ||
| 167 | * Perhaps we can add something smarter here, | ||
| 168 | * but for now just disabling the radio should do. | ||
| 169 | */ | ||
| 170 | rt2x00lib_disable_radio(rt2x00dev); | ||
| 171 | } | ||
| 172 | EXPORT_SYMBOL_GPL(rt2x00mac_stop); | ||
| 173 | |||
| 174 | int rt2x00mac_add_interface(struct ieee80211_hw *hw, | ||
| 175 | struct ieee80211_if_init_conf *conf) | ||
| 176 | { | ||
| 177 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 178 | struct interface *intf = &rt2x00dev->interface; | ||
| 179 | int retval; | ||
| 180 | |||
| 181 | /* | ||
| 182 | * We only support 1 non-monitor interface. | ||
| 183 | */ | ||
| 184 | if (conf->type != IEEE80211_IF_TYPE_MNTR && is_interface_present(intf)) | ||
| 185 | return -ENOBUFS; | ||
| 186 | |||
| 187 | /* | ||
| 188 | * HACK: Placeholder until start/stop handler has been | ||
| 189 | * added to the mac80211 callback functions structure. | ||
| 190 | */ | ||
| 191 | retval = rt2x00mac_start(hw); | ||
| 192 | if (retval) | ||
| 193 | return retval; | ||
| 194 | |||
| 195 | /* | ||
| 196 | * We support muliple monitor mode interfaces. | ||
| 197 | * All we need to do is increase the monitor_count. | ||
| 198 | */ | ||
| 199 | if (conf->type == IEEE80211_IF_TYPE_MNTR) { | ||
| 200 | intf->monitor_count++; | ||
| 201 | } else { | ||
| 202 | intf->id = conf->if_id; | ||
| 203 | intf->type = conf->type; | ||
| 204 | if (conf->type == IEEE80211_IF_TYPE_AP) | ||
| 205 | memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN); | ||
| 206 | memcpy(&intf->mac, conf->mac_addr, ETH_ALEN); | ||
| 207 | intf->filter = 0; | ||
| 208 | } | ||
| 209 | |||
| 210 | /* | ||
| 211 | * Configure interface. | ||
| 212 | * The MAC adddress must be configured after the device | ||
| 213 | * has been initialized. Else the device can reset the | ||
| 214 | * MAC registers. | ||
| 215 | */ | ||
| 216 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | ||
| 217 | rt2x00lib_config_type(rt2x00dev, conf->type); | ||
| 218 | rt2x00lib_config_packet_filter(rt2x00dev, intf->filter); | ||
| 219 | |||
| 220 | return 0; | ||
| 221 | } | ||
| 222 | EXPORT_SYMBOL_GPL(rt2x00mac_add_interface); | ||
| 223 | |||
| 224 | void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | ||
| 225 | struct ieee80211_if_init_conf *conf) | ||
| 226 | { | ||
| 227 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 228 | struct interface *intf = &rt2x00dev->interface; | ||
| 229 | |||
| 230 | /* | ||
| 231 | * We only support 1 non-monitor interface. | ||
| 232 | */ | ||
| 233 | if (conf->type != IEEE80211_IF_TYPE_MNTR && !is_interface_present(intf)) | ||
| 234 | return; | ||
| 235 | |||
| 236 | /* | ||
| 237 | * When removing an monitor interface, decrease monitor_count. | ||
| 238 | * For non-monitor interfaces, all interface data needs to be reset. | ||
| 239 | */ | ||
| 240 | if (conf->type == IEEE80211_IF_TYPE_MNTR) { | ||
| 241 | intf->monitor_count--; | ||
| 242 | } else if (intf->type == conf->type) { | ||
| 243 | intf->id = 0; | ||
| 244 | intf->type = INVALID_INTERFACE; | ||
| 245 | memset(&intf->bssid, 0x00, ETH_ALEN); | ||
| 246 | memset(&intf->mac, 0x00, ETH_ALEN); | ||
| 247 | intf->filter = 0; | ||
| 248 | } | ||
| 249 | |||
| 250 | /* | ||
| 251 | * Make sure the bssid and mac address registers | ||
| 252 | * are cleared to prevent false ACKing of frames. | ||
| 253 | */ | ||
| 254 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | ||
| 255 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | ||
| 256 | rt2x00lib_config_type(rt2x00dev, intf->type); | ||
| 257 | |||
| 258 | /* | ||
| 259 | * HACK: Placeholder untill start/stop handler has been | ||
| 260 | * added to the mac80211 callback functions structure. | ||
| 261 | */ | ||
| 262 | rt2x00mac_stop(hw); | ||
| 263 | } | ||
| 264 | EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); | ||
| 265 | |||
| 266 | int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | ||
| 267 | { | ||
| 268 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 269 | |||
| 270 | /* | ||
| 271 | * If the device is not initialized we shouldn't accept | ||
| 272 | * any configuration changes. Mac80211 might be calling | ||
| 273 | * this function while we are trying to remove the device | ||
| 274 | * or perhaps suspending it. | ||
| 275 | */ | ||
| 276 | if (!test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) | ||
| 277 | return 0; | ||
| 278 | |||
| 279 | /* | ||
| 280 | * Check if we need to disable the radio, | ||
| 281 | * if this is not the case, at least the RX must be disabled. | ||
| 282 | */ | ||
| 283 | if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) { | ||
| 284 | if (!conf->radio_enabled) | ||
| 285 | rt2x00lib_disable_radio(rt2x00dev); | ||
| 286 | else | ||
| 287 | rt2x00lib_toggle_rx(rt2x00dev, 0); | ||
| 288 | } | ||
| 289 | |||
| 290 | rt2x00lib_config(rt2x00dev, conf); | ||
| 291 | |||
| 292 | /* | ||
| 293 | * If promisc mode cannot be configured in irq context, | ||
| 294 | * then it is now the time to configure it. | ||
| 295 | */ | ||
| 296 | if (test_bit(PACKET_FILTER_SCHEDULED, &rt2x00dev->flags)) | ||
| 297 | rt2x00lib_config_packet_filter(rt2x00dev, | ||
| 298 | rt2x00dev->interface.filter); | ||
| 299 | |||
| 300 | /* | ||
| 301 | * Reenable RX only if the radio should be on. | ||
| 302 | */ | ||
| 303 | if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
| 304 | rt2x00lib_toggle_rx(rt2x00dev, 1); | ||
| 305 | else if (conf->radio_enabled) | ||
| 306 | return rt2x00lib_enable_radio(rt2x00dev); | ||
| 307 | |||
| 308 | return 0; | ||
| 309 | } | ||
| 310 | EXPORT_SYMBOL_GPL(rt2x00mac_config); | ||
| 311 | |||
| 312 | int rt2x00mac_config_interface(struct ieee80211_hw *hw, int if_id, | ||
| 313 | struct ieee80211_if_conf *conf) | ||
| 314 | { | ||
| 315 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 316 | struct interface *intf = &rt2x00dev->interface; | ||
| 317 | int status; | ||
| 318 | |||
| 319 | /* | ||
| 320 | * If the device is not initialized we shouldn't accept | ||
| 321 | * any configuration changes. Mac80211 might be calling | ||
| 322 | * this function while we are trying to remove the device | ||
| 323 | * or perhaps suspending it. | ||
| 324 | */ | ||
| 325 | if (!test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) | ||
| 326 | return 0; | ||
| 327 | |||
| 328 | /* | ||
| 329 | * Monitor mode does not need configuring. | ||
| 330 | * If the given type does not match the configured type, | ||
| 331 | * there has been a problem. | ||
| 332 | */ | ||
| 333 | if (conf->type == IEEE80211_IF_TYPE_MNTR) | ||
| 334 | return 0; | ||
| 335 | else if (conf->type != intf->type) | ||
| 336 | return -EINVAL; | ||
| 337 | |||
| 338 | /* | ||
| 339 | * If the interface does not work in master mode, | ||
| 340 | * then the bssid value in the interface structure | ||
| 341 | * should now be set. | ||
| 342 | */ | ||
| 343 | if (conf->type != IEEE80211_IF_TYPE_AP) | ||
| 344 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); | ||
| 345 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | ||
| 346 | |||
| 347 | /* | ||
| 348 | * We only need to initialize the beacon when master mode is enabled. | ||
| 349 | */ | ||
| 350 | if (conf->type != IEEE80211_IF_TYPE_AP || !conf->beacon) | ||
| 351 | return 0; | ||
| 352 | |||
| 353 | status = rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, | ||
| 354 | conf->beacon, | ||
| 355 | conf->beacon_control); | ||
| 356 | if (status) | ||
| 357 | dev_kfree_skb(conf->beacon); | ||
| 358 | |||
| 359 | return status; | ||
| 360 | } | ||
| 361 | EXPORT_SYMBOL_GPL(rt2x00mac_config_interface); | ||
| 362 | |||
| 363 | void rt2x00mac_set_multicast_list(struct ieee80211_hw *hw, | ||
| 364 | unsigned short flags, int mc_count) | ||
| 365 | { | ||
| 366 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 367 | |||
| 368 | /* | ||
| 369 | * Check if the new state is different then the old state. | ||
| 370 | */ | ||
| 371 | if (rt2x00dev->interface.filter == flags) | ||
| 372 | return; | ||
| 373 | |||
| 374 | rt2x00dev->interface.filter = flags; | ||
| 375 | |||
| 376 | /* | ||
| 377 | * Raise the pending bit to indicate the | ||
| 378 | * packet filter should be updated. | ||
| 379 | */ | ||
| 380 | __set_bit(PACKET_FILTER_PENDING, &rt2x00dev->flags); | ||
| 381 | |||
| 382 | /* | ||
| 383 | * Check if Packet filter actions are allowed in | ||
| 384 | * atomic context. If not, raise the pending flag and | ||
| 385 | * let it be. | ||
| 386 | */ | ||
| 387 | if (!test_bit(PACKET_FILTER_SCHEDULED, &rt2x00dev->flags) || | ||
| 388 | !in_atomic()) | ||
| 389 | rt2x00lib_config_packet_filter(rt2x00dev, flags); | ||
| 390 | } | ||
| 391 | EXPORT_SYMBOL_GPL(rt2x00mac_set_multicast_list); | ||
| 392 | |||
| 393 | int rt2x00mac_get_stats(struct ieee80211_hw *hw, | ||
| 394 | struct ieee80211_low_level_stats *stats) | ||
| 395 | { | ||
| 396 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 397 | |||
| 398 | /* | ||
| 399 | * The dot11ACKFailureCount, dot11RTSFailureCount and | ||
| 400 | * dot11RTSSuccessCount are updated in interrupt time. | ||
| 401 | * dot11FCSErrorCount is updated in the link tuner. | ||
| 402 | */ | ||
| 403 | memcpy(stats, &rt2x00dev->low_level_stats, sizeof(*stats)); | ||
| 404 | |||
| 405 | return 0; | ||
| 406 | } | ||
| 407 | EXPORT_SYMBOL_GPL(rt2x00mac_get_stats); | ||
| 408 | |||
| 409 | int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, | ||
| 410 | struct ieee80211_tx_queue_stats *stats) | ||
| 411 | { | ||
| 412 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 413 | unsigned int i; | ||
| 414 | |||
| 415 | for (i = 0; i < hw->queues; i++) | ||
| 416 | memcpy(&stats->data[i], &rt2x00dev->tx[i].stats, | ||
| 417 | sizeof(rt2x00dev->tx[i].stats)); | ||
| 418 | |||
| 419 | return 0; | ||
| 420 | } | ||
| 421 | EXPORT_SYMBOL_GPL(rt2x00mac_get_tx_stats); | ||
| 422 | |||
| 423 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue, | ||
| 424 | const struct ieee80211_tx_queue_params *params) | ||
| 425 | { | ||
| 426 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 427 | struct data_ring *ring; | ||
| 428 | |||
| 429 | ring = rt2x00lib_get_ring(rt2x00dev, queue); | ||
| 430 | if (unlikely(!ring)) | ||
| 431 | return -EINVAL; | ||
| 432 | |||
| 433 | /* | ||
| 434 | * The passed variables are stored as real value ((2^n)-1). | ||
| 435 | * Ralink registers require to know the bit number 'n'. | ||
| 436 | */ | ||
| 437 | if (params->cw_min) | ||
| 438 | ring->tx_params.cw_min = fls(params->cw_min); | ||
| 439 | else | ||
| 440 | ring->tx_params.cw_min = 5; /* cw_min: 2^5 = 32. */ | ||
| 441 | |||
| 442 | if (params->cw_max) | ||
| 443 | ring->tx_params.cw_max = fls(params->cw_max); | ||
| 444 | else | ||
| 445 | ring->tx_params.cw_max = 10; /* cw_min: 2^10 = 1024. */ | ||
| 446 | |||
| 447 | if (params->aifs) | ||
| 448 | ring->tx_params.aifs = params->aifs; | ||
| 449 | else | ||
| 450 | ring->tx_params.aifs = 2; | ||
| 451 | |||
| 452 | INFO(rt2x00dev, | ||
| 453 | "Configured TX ring %d - CWmin: %d, CWmax: %d, Aifs: %d.\n", | ||
| 454 | queue, ring->tx_params.cw_min, ring->tx_params.cw_max, | ||
| 455 | ring->tx_params.aifs); | ||
| 456 | |||
| 457 | return 0; | ||
| 458 | } | ||
| 459 | EXPORT_SYMBOL_GPL(rt2x00mac_conf_tx); | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c new file mode 100644 index 00000000000..85629f1999a --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
| @@ -0,0 +1,481 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00pci | ||
| 23 | Abstract: rt2x00 generic pci device routines. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Set enviroment defines for rt2x00.h | ||
| 28 | */ | ||
| 29 | #define DRV_NAME "rt2x00pci" | ||
| 30 | |||
| 31 | #include <linux/dma-mapping.h> | ||
| 32 | #include <linux/kernel.h> | ||
| 33 | #include <linux/module.h> | ||
| 34 | #include <linux/pci.h> | ||
| 35 | |||
| 36 | #include "rt2x00.h" | ||
| 37 | #include "rt2x00pci.h" | ||
| 38 | |||
| 39 | /* | ||
| 40 | * Beacon handlers. | ||
| 41 | */ | ||
| 42 | int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
| 43 | struct ieee80211_tx_control *control) | ||
| 44 | { | ||
| 45 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 46 | struct data_ring *ring = | ||
| 47 | rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
| 48 | struct data_entry *entry = rt2x00_get_data_entry(ring); | ||
| 49 | |||
| 50 | /* | ||
| 51 | * Just in case mac80211 doesn't set this correctly, | ||
| 52 | * but we need this queue set for the descriptor | ||
| 53 | * initialization. | ||
| 54 | */ | ||
| 55 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
| 56 | |||
| 57 | /* | ||
| 58 | * Update the beacon entry. | ||
| 59 | */ | ||
| 60 | memcpy(entry->data_addr, skb->data, skb->len); | ||
| 61 | rt2x00lib_write_tx_desc(rt2x00dev, entry->priv, | ||
| 62 | (struct ieee80211_hdr *)skb->data, | ||
| 63 | skb->len, control); | ||
| 64 | |||
| 65 | /* | ||
| 66 | * Enable beacon generation. | ||
| 67 | */ | ||
| 68 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
| 69 | |||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | EXPORT_SYMBOL_GPL(rt2x00pci_beacon_update); | ||
| 73 | |||
| 74 | /* | ||
| 75 | * TX data handlers. | ||
| 76 | */ | ||
| 77 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | ||
| 78 | struct data_ring *ring, struct sk_buff *skb, | ||
| 79 | struct ieee80211_tx_control *control) | ||
| 80 | { | ||
| 81 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; | ||
| 82 | struct data_entry *entry = rt2x00_get_data_entry(ring); | ||
| 83 | struct data_desc *txd = entry->priv; | ||
| 84 | u32 word; | ||
| 85 | |||
| 86 | if (rt2x00_ring_full(ring)) { | ||
| 87 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | ||
| 88 | return -EINVAL; | ||
| 89 | } | ||
| 90 | |||
| 91 | rt2x00_desc_read(txd, 0, &word); | ||
| 92 | |||
| 93 | if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || | ||
| 94 | rt2x00_get_field32(word, TXD_ENTRY_VALID)) { | ||
| 95 | ERROR(rt2x00dev, | ||
| 96 | "Arrived at non-free entry in the non-full queue %d.\n" | ||
| 97 | "Please file bug report to %s.\n", | ||
| 98 | control->queue, DRV_PROJECT); | ||
| 99 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | ||
| 100 | return -EINVAL; | ||
| 101 | } | ||
| 102 | |||
| 103 | entry->skb = skb; | ||
| 104 | memcpy(&entry->tx_status.control, control, sizeof(*control)); | ||
| 105 | memcpy(entry->data_addr, skb->data, skb->len); | ||
| 106 | rt2x00lib_write_tx_desc(rt2x00dev, txd, ieee80211hdr, | ||
| 107 | skb->len, control); | ||
| 108 | |||
| 109 | rt2x00_ring_index_inc(ring); | ||
| 110 | |||
| 111 | if (rt2x00_ring_full(ring)) | ||
| 112 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | ||
| 113 | |||
| 114 | return 0; | ||
| 115 | } | ||
| 116 | EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); | ||
| 117 | |||
| 118 | /* | ||
| 119 | * RX data handlers. | ||
| 120 | */ | ||
| 121 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | ||
| 122 | { | ||
| 123 | struct data_ring *ring = rt2x00dev->rx; | ||
| 124 | struct data_entry *entry; | ||
| 125 | struct data_desc *rxd; | ||
| 126 | struct sk_buff *skb; | ||
| 127 | u32 desc; | ||
| 128 | int retval; | ||
| 129 | int signal; | ||
| 130 | int rssi; | ||
| 131 | int ofdm; | ||
| 132 | int size; | ||
| 133 | |||
| 134 | while (1) { | ||
| 135 | entry = rt2x00_get_data_entry(ring); | ||
| 136 | rxd = entry->priv; | ||
| 137 | rt2x00_desc_read(rxd, 0, &desc); | ||
| 138 | |||
| 139 | if (rt2x00_get_field32(desc, RXD_ENTRY_OWNER_NIC)) | ||
| 140 | break; | ||
| 141 | |||
| 142 | retval = rt2x00dev->ops->lib->fill_rxdone(entry, &signal, | ||
| 143 | &rssi, &ofdm, &size); | ||
| 144 | if (retval) | ||
| 145 | goto skip_entry; | ||
| 146 | |||
| 147 | /* | ||
| 148 | * Allocate the sk_buffer, initialize it and copy | ||
| 149 | * all data into it. | ||
| 150 | */ | ||
| 151 | skb = dev_alloc_skb(size + NET_IP_ALIGN); | ||
| 152 | if (!skb) | ||
| 153 | return; | ||
| 154 | |||
| 155 | skb_reserve(skb, NET_IP_ALIGN); | ||
| 156 | skb_put(skb, size); | ||
| 157 | memcpy(skb->data, entry->data_addr, size); | ||
| 158 | |||
| 159 | /* | ||
| 160 | * Send the frame to rt2x00lib for further processing. | ||
| 161 | */ | ||
| 162 | rt2x00lib_rxdone(entry, skb, signal, rssi, ofdm); | ||
| 163 | |||
| 164 | skip_entry: | ||
| 165 | if (test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) { | ||
| 166 | rt2x00_set_field32(&desc, RXD_ENTRY_OWNER_NIC, 1); | ||
| 167 | rt2x00_desc_write(rxd, 0, desc); | ||
| 168 | } | ||
| 169 | |||
| 170 | rt2x00_ring_index_inc(ring); | ||
| 171 | } | ||
| 172 | } | ||
| 173 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); | ||
| 174 | |||
| 175 | /* | ||
| 176 | * Device initialization handlers. | ||
| 177 | */ | ||
| 178 | #define priv_offset(__ring, __i) \ | ||
| 179 | ({ \ | ||
| 180 | ring->data_addr + (i * ring->desc_size); \ | ||
| 181 | }) | ||
| 182 | |||
| 183 | #define data_addr_offset(__ring, __i) \ | ||
| 184 | ({ \ | ||
| 185 | (__ring)->data_addr + \ | ||
| 186 | ((__ring)->stats.limit * (__ring)->desc_size) + \ | ||
| 187 | ((__i) * (__ring)->data_size); \ | ||
| 188 | }) | ||
| 189 | |||
| 190 | #define data_dma_offset(__ring, __i) \ | ||
| 191 | ({ \ | ||
| 192 | (__ring)->data_dma + \ | ||
| 193 | ((__ring)->stats.limit * (__ring)->desc_size) + \ | ||
| 194 | ((__i) * (__ring)->data_size); \ | ||
| 195 | }) | ||
| 196 | |||
| 197 | static int rt2x00pci_alloc_dma(struct rt2x00_dev *rt2x00dev, | ||
| 198 | struct data_ring *ring) | ||
| 199 | { | ||
| 200 | unsigned int i; | ||
| 201 | |||
| 202 | /* | ||
| 203 | * Allocate DMA memory for descriptor and buffer. | ||
| 204 | */ | ||
| 205 | ring->data_addr = pci_alloc_consistent(rt2x00dev_pci(rt2x00dev), | ||
| 206 | rt2x00_get_ring_size(ring), | ||
| 207 | &ring->data_dma); | ||
| 208 | if (!ring->data_addr) | ||
| 209 | return -ENOMEM; | ||
| 210 | |||
| 211 | /* | ||
| 212 | * Initialize all ring entries to contain valid | ||
| 213 | * addresses. | ||
| 214 | */ | ||
| 215 | for (i = 0; i < ring->stats.limit; i++) { | ||
| 216 | ring->entry[i].priv = priv_offset(ring, i); | ||
| 217 | ring->entry[i].data_addr = data_addr_offset(ring, i); | ||
| 218 | ring->entry[i].data_dma = data_dma_offset(ring, i); | ||
| 219 | } | ||
| 220 | |||
| 221 | return 0; | ||
| 222 | } | ||
| 223 | |||
| 224 | static void rt2x00pci_free_dma(struct rt2x00_dev *rt2x00dev, | ||
| 225 | struct data_ring *ring) | ||
| 226 | { | ||
| 227 | if (ring->data_addr) | ||
| 228 | pci_free_consistent(rt2x00dev_pci(rt2x00dev), | ||
| 229 | rt2x00_get_ring_size(ring), | ||
| 230 | ring->data_addr, ring->data_dma); | ||
| 231 | ring->data_addr = NULL; | ||
| 232 | } | ||
| 233 | |||
| 234 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | ||
| 235 | { | ||
| 236 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | ||
| 237 | struct data_ring *ring; | ||
| 238 | int status; | ||
| 239 | |||
| 240 | /* | ||
| 241 | * Allocate DMA | ||
| 242 | */ | ||
| 243 | ring_for_each(rt2x00dev, ring) { | ||
| 244 | status = rt2x00pci_alloc_dma(rt2x00dev, ring); | ||
| 245 | if (status) | ||
| 246 | goto exit; | ||
| 247 | } | ||
| 248 | |||
| 249 | /* | ||
| 250 | * Register interrupt handler. | ||
| 251 | */ | ||
| 252 | status = request_irq(pci_dev->irq, rt2x00dev->ops->lib->irq_handler, | ||
| 253 | IRQF_SHARED, pci_name(pci_dev), rt2x00dev); | ||
| 254 | if (status) { | ||
| 255 | ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", | ||
| 256 | pci_dev->irq, status); | ||
| 257 | return status; | ||
| 258 | } | ||
| 259 | |||
| 260 | return 0; | ||
| 261 | |||
| 262 | exit: | ||
| 263 | rt2x00pci_uninitialize(rt2x00dev); | ||
| 264 | |||
| 265 | return status; | ||
| 266 | } | ||
| 267 | EXPORT_SYMBOL_GPL(rt2x00pci_initialize); | ||
| 268 | |||
| 269 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) | ||
| 270 | { | ||
| 271 | struct data_ring *ring; | ||
| 272 | |||
| 273 | /* | ||
| 274 | * Free irq line. | ||
| 275 | */ | ||
| 276 | free_irq(rt2x00dev_pci(rt2x00dev)->irq, rt2x00dev); | ||
| 277 | |||
| 278 | /* | ||
| 279 | * Free DMA | ||
| 280 | */ | ||
| 281 | ring_for_each(rt2x00dev, ring) | ||
| 282 | rt2x00pci_free_dma(rt2x00dev, ring); | ||
| 283 | } | ||
| 284 | EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); | ||
| 285 | |||
| 286 | /* | ||
| 287 | * PCI driver handlers. | ||
| 288 | */ | ||
| 289 | static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev) | ||
| 290 | { | ||
| 291 | kfree(rt2x00dev->rf); | ||
| 292 | rt2x00dev->rf = NULL; | ||
| 293 | |||
| 294 | kfree(rt2x00dev->eeprom); | ||
| 295 | rt2x00dev->eeprom = NULL; | ||
| 296 | |||
| 297 | if (rt2x00dev->csr_addr) { | ||
| 298 | iounmap(rt2x00dev->csr_addr); | ||
| 299 | rt2x00dev->csr_addr = NULL; | ||
| 300 | } | ||
| 301 | } | ||
| 302 | |||
| 303 | static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev) | ||
| 304 | { | ||
| 305 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | ||
| 306 | |||
| 307 | rt2x00dev->csr_addr = ioremap(pci_resource_start(pci_dev, 0), | ||
| 308 | pci_resource_len(pci_dev, 0)); | ||
| 309 | if (!rt2x00dev->csr_addr) | ||
| 310 | goto exit; | ||
| 311 | |||
| 312 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); | ||
| 313 | if (!rt2x00dev->eeprom) | ||
| 314 | goto exit; | ||
| 315 | |||
| 316 | rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL); | ||
| 317 | if (!rt2x00dev->rf) | ||
| 318 | goto exit; | ||
| 319 | |||
| 320 | return 0; | ||
| 321 | |||
| 322 | exit: | ||
| 323 | ERROR_PROBE("Failed to allocate registers.\n"); | ||
| 324 | |||
| 325 | rt2x00pci_free_reg(rt2x00dev); | ||
| 326 | |||
| 327 | return -ENOMEM; | ||
| 328 | } | ||
| 329 | |||
| 330 | int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | ||
| 331 | { | ||
| 332 | struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_data; | ||
| 333 | struct ieee80211_hw *hw; | ||
| 334 | struct rt2x00_dev *rt2x00dev; | ||
| 335 | int retval; | ||
| 336 | |||
| 337 | retval = pci_request_regions(pci_dev, pci_name(pci_dev)); | ||
| 338 | if (retval) { | ||
| 339 | ERROR_PROBE("PCI request regions failed.\n"); | ||
| 340 | return retval; | ||
| 341 | } | ||
| 342 | |||
| 343 | retval = pci_enable_device(pci_dev); | ||
| 344 | if (retval) { | ||
| 345 | ERROR_PROBE("Enable device failed.\n"); | ||
| 346 | goto exit_release_regions; | ||
| 347 | } | ||
| 348 | |||
| 349 | pci_set_master(pci_dev); | ||
| 350 | |||
| 351 | if (pci_set_mwi(pci_dev)) | ||
| 352 | ERROR_PROBE("MWI not available.\n"); | ||
| 353 | |||
| 354 | if (pci_set_dma_mask(pci_dev, DMA_64BIT_MASK) && | ||
| 355 | pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { | ||
| 356 | ERROR_PROBE("PCI DMA not supported.\n"); | ||
| 357 | retval = -EIO; | ||
| 358 | goto exit_disable_device; | ||
| 359 | } | ||
| 360 | |||
| 361 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); | ||
| 362 | if (!hw) { | ||
| 363 | ERROR_PROBE("Failed to allocate hardware.\n"); | ||
| 364 | retval = -ENOMEM; | ||
| 365 | goto exit_disable_device; | ||
| 366 | } | ||
| 367 | |||
| 368 | pci_set_drvdata(pci_dev, hw); | ||
| 369 | |||
| 370 | rt2x00dev = hw->priv; | ||
| 371 | rt2x00dev->dev = pci_dev; | ||
| 372 | rt2x00dev->ops = ops; | ||
| 373 | rt2x00dev->hw = hw; | ||
| 374 | |||
| 375 | retval = rt2x00pci_alloc_reg(rt2x00dev); | ||
| 376 | if (retval) | ||
| 377 | goto exit_free_device; | ||
| 378 | |||
| 379 | retval = rt2x00lib_probe_dev(rt2x00dev); | ||
| 380 | if (retval) | ||
| 381 | goto exit_free_reg; | ||
| 382 | |||
| 383 | return 0; | ||
| 384 | |||
| 385 | exit_free_reg: | ||
| 386 | rt2x00pci_free_reg(rt2x00dev); | ||
| 387 | |||
| 388 | exit_free_device: | ||
| 389 | ieee80211_free_hw(hw); | ||
| 390 | |||
| 391 | exit_disable_device: | ||
| 392 | if (retval != -EBUSY) | ||
| 393 | pci_disable_device(pci_dev); | ||
| 394 | |||
| 395 | exit_release_regions: | ||
| 396 | pci_release_regions(pci_dev); | ||
| 397 | |||
| 398 | pci_set_drvdata(pci_dev, NULL); | ||
| 399 | |||
| 400 | return retval; | ||
| 401 | } | ||
| 402 | EXPORT_SYMBOL_GPL(rt2x00pci_probe); | ||
| 403 | |||
| 404 | void rt2x00pci_remove(struct pci_dev *pci_dev) | ||
| 405 | { | ||
| 406 | struct ieee80211_hw *hw = pci_get_drvdata(pci_dev); | ||
| 407 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 408 | |||
| 409 | /* | ||
| 410 | * Free all allocated data. | ||
| 411 | */ | ||
| 412 | rt2x00lib_remove_dev(rt2x00dev); | ||
| 413 | rt2x00pci_free_reg(rt2x00dev); | ||
| 414 | ieee80211_free_hw(hw); | ||
| 415 | |||
| 416 | /* | ||
| 417 | * Free the PCI device data. | ||
| 418 | */ | ||
| 419 | pci_set_drvdata(pci_dev, NULL); | ||
| 420 | pci_disable_device(pci_dev); | ||
| 421 | pci_release_regions(pci_dev); | ||
| 422 | } | ||
| 423 | EXPORT_SYMBOL_GPL(rt2x00pci_remove); | ||
| 424 | |||
| 425 | #ifdef CONFIG_PM | ||
| 426 | int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state) | ||
| 427 | { | ||
| 428 | struct ieee80211_hw *hw = pci_get_drvdata(pci_dev); | ||
| 429 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 430 | int retval; | ||
| 431 | |||
| 432 | retval = rt2x00lib_suspend(rt2x00dev, state); | ||
| 433 | if (retval) | ||
| 434 | return retval; | ||
| 435 | |||
| 436 | rt2x00pci_free_reg(rt2x00dev); | ||
| 437 | |||
| 438 | pci_save_state(pci_dev); | ||
| 439 | pci_disable_device(pci_dev); | ||
| 440 | return pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); | ||
| 441 | } | ||
| 442 | EXPORT_SYMBOL_GPL(rt2x00pci_suspend); | ||
| 443 | |||
| 444 | int rt2x00pci_resume(struct pci_dev *pci_dev) | ||
| 445 | { | ||
| 446 | struct ieee80211_hw *hw = pci_get_drvdata(pci_dev); | ||
| 447 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 448 | int retval; | ||
| 449 | |||
| 450 | if (pci_set_power_state(pci_dev, PCI_D0) || | ||
| 451 | pci_enable_device(pci_dev) || | ||
| 452 | pci_restore_state(pci_dev)) { | ||
| 453 | ERROR(rt2x00dev, "Failed to resume device.\n"); | ||
| 454 | return -EIO; | ||
| 455 | } | ||
| 456 | |||
| 457 | retval = rt2x00pci_alloc_reg(rt2x00dev); | ||
| 458 | if (retval) | ||
| 459 | return retval; | ||
| 460 | |||
| 461 | retval = rt2x00lib_resume(rt2x00dev); | ||
| 462 | if (retval) | ||
| 463 | goto exit_free_reg; | ||
| 464 | |||
| 465 | return 0; | ||
| 466 | |||
| 467 | exit_free_reg: | ||
| 468 | rt2x00pci_free_reg(rt2x00dev); | ||
| 469 | |||
| 470 | return retval; | ||
| 471 | } | ||
| 472 | EXPORT_SYMBOL_GPL(rt2x00pci_resume); | ||
| 473 | #endif /* CONFIG_PM */ | ||
| 474 | |||
| 475 | /* | ||
| 476 | * rt2x00pci module information. | ||
| 477 | */ | ||
| 478 | MODULE_AUTHOR(DRV_PROJECT); | ||
| 479 | MODULE_VERSION(DRV_VERSION); | ||
| 480 | MODULE_DESCRIPTION("rt2x00 library"); | ||
| 481 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h new file mode 100644 index 00000000000..82adeac061d --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h | |||
| @@ -0,0 +1,127 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00pci | ||
| 23 | Abstract: Data structures for the rt2x00pci module. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #ifndef RT2X00PCI_H | ||
| 27 | #define RT2X00PCI_H | ||
| 28 | |||
| 29 | #include <linux/io.h> | ||
| 30 | |||
| 31 | /* | ||
| 32 | * This variable should be used with the | ||
| 33 | * pci_driver structure initialization. | ||
| 34 | */ | ||
| 35 | #define PCI_DEVICE_DATA(__ops) .driver_data = (kernel_ulong_t)(__ops) | ||
| 36 | |||
| 37 | /* | ||
| 38 | * Register defines. | ||
| 39 | * Some registers require multiple attempts before success, | ||
| 40 | * in those cases REGISTER_BUSY_COUNT attempts should be | ||
| 41 | * taken with a REGISTER_BUSY_DELAY interval. | ||
| 42 | */ | ||
| 43 | #define REGISTER_BUSY_COUNT 5 | ||
| 44 | #define REGISTER_BUSY_DELAY 100 | ||
| 45 | |||
| 46 | /* | ||
| 47 | * Descriptor availability flags. | ||
| 48 | * All PCI device descriptors have these 2 flags | ||
| 49 | * with the exact same definition. | ||
| 50 | * By storing them here we can use them inside rt2x00pci | ||
| 51 | * for some simple entry availability checking. | ||
| 52 | */ | ||
| 53 | #define TXD_ENTRY_OWNER_NIC FIELD32(0x00000001) | ||
| 54 | #define TXD_ENTRY_VALID FIELD32(0x00000002) | ||
| 55 | #define RXD_ENTRY_OWNER_NIC FIELD32(0x00000001) | ||
| 56 | |||
| 57 | /* | ||
| 58 | * Register access. | ||
| 59 | */ | ||
| 60 | static inline void rt2x00pci_register_read(const struct rt2x00_dev *rt2x00dev, | ||
| 61 | const unsigned long offset, | ||
| 62 | u32 *value) | ||
| 63 | { | ||
| 64 | *value = readl(rt2x00dev->csr_addr + offset); | ||
| 65 | } | ||
| 66 | |||
| 67 | static inline void | ||
| 68 | rt2x00pci_register_multiread(const struct rt2x00_dev *rt2x00dev, | ||
| 69 | const unsigned long offset, | ||
| 70 | void *value, const u16 length) | ||
| 71 | { | ||
| 72 | memcpy_fromio(value, rt2x00dev->csr_addr + offset, length); | ||
| 73 | } | ||
| 74 | |||
| 75 | static inline void rt2x00pci_register_write(const struct rt2x00_dev *rt2x00dev, | ||
| 76 | const unsigned long offset, | ||
| 77 | u32 value) | ||
| 78 | { | ||
| 79 | writel(value, rt2x00dev->csr_addr + offset); | ||
| 80 | } | ||
| 81 | |||
| 82 | static inline void | ||
| 83 | rt2x00pci_register_multiwrite(const struct rt2x00_dev *rt2x00dev, | ||
| 84 | const unsigned long offset, | ||
| 85 | void *value, const u16 length) | ||
| 86 | { | ||
| 87 | memcpy_toio(rt2x00dev->csr_addr + offset, value, length); | ||
| 88 | } | ||
| 89 | |||
| 90 | /* | ||
| 91 | * Beacon handlers. | ||
| 92 | */ | ||
| 93 | int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
| 94 | struct ieee80211_tx_control *control); | ||
| 95 | |||
| 96 | /* | ||
| 97 | * TX data handlers. | ||
| 98 | */ | ||
| 99 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | ||
| 100 | struct data_ring *ring, struct sk_buff *skb, | ||
| 101 | struct ieee80211_tx_control *control); | ||
| 102 | |||
| 103 | /* | ||
| 104 | * RX data handlers. | ||
| 105 | */ | ||
| 106 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); | ||
| 107 | |||
| 108 | /* | ||
| 109 | * Device initialization handlers. | ||
| 110 | */ | ||
| 111 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev); | ||
| 112 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev); | ||
| 113 | |||
| 114 | /* | ||
| 115 | * PCI driver handlers. | ||
| 116 | */ | ||
| 117 | int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id); | ||
| 118 | void rt2x00pci_remove(struct pci_dev *pci_dev); | ||
| 119 | #ifdef CONFIG_PM | ||
| 120 | int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state); | ||
| 121 | int rt2x00pci_resume(struct pci_dev *pci_dev); | ||
| 122 | #else | ||
| 123 | #define rt2x00pci_suspend NULL | ||
| 124 | #define rt2x00pci_resume NULL | ||
| 125 | #endif /* CONFIG_PM */ | ||
| 126 | |||
| 127 | #endif /* RT2X00PCI_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h new file mode 100644 index 00000000000..7927d5f7bcc --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h | |||
| @@ -0,0 +1,283 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00 | ||
| 23 | Abstract: rt2x00 generic register information. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #ifndef RT2X00REG_H | ||
| 27 | #define RT2X00REG_H | ||
| 28 | |||
| 29 | /* | ||
| 30 | * TX result flags. | ||
| 31 | */ | ||
| 32 | enum TX_STATUS { | ||
| 33 | TX_SUCCESS = 0, | ||
| 34 | TX_SUCCESS_RETRY = 1, | ||
| 35 | TX_FAIL_RETRY = 2, | ||
| 36 | TX_FAIL_INVALID = 3, | ||
| 37 | TX_FAIL_OTHER = 4, | ||
| 38 | }; | ||
| 39 | |||
| 40 | /* | ||
| 41 | * Antenna values | ||
| 42 | */ | ||
| 43 | enum antenna { | ||
| 44 | ANTENNA_SW_DIVERSITY = 0, | ||
| 45 | ANTENNA_A = 1, | ||
| 46 | ANTENNA_B = 2, | ||
| 47 | ANTENNA_HW_DIVERSITY = 3, | ||
| 48 | }; | ||
| 49 | |||
| 50 | /* | ||
| 51 | * Led mode values. | ||
| 52 | */ | ||
| 53 | enum led_mode { | ||
| 54 | LED_MODE_DEFAULT = 0, | ||
| 55 | LED_MODE_TXRX_ACTIVITY = 1, | ||
| 56 | LED_MODE_SIGNAL_STRENGTH = 2, | ||
| 57 | LED_MODE_ASUS = 3, | ||
| 58 | LED_MODE_ALPHA = 4, | ||
| 59 | }; | ||
| 60 | |||
| 61 | /* | ||
| 62 | * Device states | ||
| 63 | */ | ||
| 64 | enum dev_state { | ||
| 65 | STATE_DEEP_SLEEP = 0, | ||
| 66 | STATE_SLEEP = 1, | ||
| 67 | STATE_STANDBY = 2, | ||
| 68 | STATE_AWAKE = 3, | ||
| 69 | |||
| 70 | /* | ||
| 71 | * Additional device states, these values are | ||
| 72 | * not strict since they are not directly passed | ||
| 73 | * into the device. | ||
| 74 | */ | ||
| 75 | STATE_RADIO_ON, | ||
| 76 | STATE_RADIO_OFF, | ||
| 77 | STATE_RADIO_RX_ON, | ||
| 78 | STATE_RADIO_RX_OFF, | ||
| 79 | STATE_RADIO_IRQ_ON, | ||
| 80 | STATE_RADIO_IRQ_OFF, | ||
| 81 | }; | ||
| 82 | |||
| 83 | /* | ||
| 84 | * IFS backoff values | ||
| 85 | */ | ||
| 86 | enum ifs { | ||
| 87 | IFS_BACKOFF = 0, | ||
| 88 | IFS_SIFS = 1, | ||
| 89 | IFS_NEW_BACKOFF = 2, | ||
| 90 | IFS_NONE = 3, | ||
| 91 | }; | ||
| 92 | |||
| 93 | /* | ||
| 94 | * Cipher types for hardware encryption | ||
| 95 | */ | ||
| 96 | enum cipher { | ||
| 97 | CIPHER_NONE = 0, | ||
| 98 | CIPHER_WEP64 = 1, | ||
| 99 | CIPHER_WEP128 = 2, | ||
| 100 | CIPHER_TKIP = 3, | ||
| 101 | CIPHER_AES = 4, | ||
| 102 | /* | ||
| 103 | * The following fields were added by rt61pci and rt73usb. | ||
| 104 | */ | ||
| 105 | CIPHER_CKIP64 = 5, | ||
| 106 | CIPHER_CKIP128 = 6, | ||
| 107 | CIPHER_TKIP_NO_MIC = 7, | ||
| 108 | }; | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Register handlers. | ||
| 112 | * We store the position of a register field inside a field structure, | ||
| 113 | * This will simplify the process of setting and reading a certain field | ||
| 114 | * inside the register while making sure the process remains byte order safe. | ||
| 115 | */ | ||
| 116 | struct rt2x00_field8 { | ||
| 117 | u8 bit_offset; | ||
| 118 | u8 bit_mask; | ||
| 119 | }; | ||
| 120 | |||
| 121 | struct rt2x00_field16 { | ||
| 122 | u16 bit_offset; | ||
| 123 | u16 bit_mask; | ||
| 124 | }; | ||
| 125 | |||
| 126 | struct rt2x00_field32 { | ||
| 127 | u32 bit_offset; | ||
| 128 | u32 bit_mask; | ||
| 129 | }; | ||
| 130 | |||
| 131 | /* | ||
| 132 | * Power of two check, this will check | ||
| 133 | * if the mask that has been given contains | ||
| 134 | * and contiguous set of bits. | ||
| 135 | */ | ||
| 136 | #define is_power_of_two(x) ( !((x) & ((x)-1)) ) | ||
| 137 | #define low_bit_mask(x) ( ((x)-1) & ~(x) ) | ||
| 138 | #define is_valid_mask(x) is_power_of_two(1 + (x) + low_bit_mask(x)) | ||
| 139 | |||
| 140 | #define FIELD8(__mask) \ | ||
| 141 | ({ \ | ||
| 142 | BUILD_BUG_ON(!(__mask) || \ | ||
| 143 | !is_valid_mask(__mask) || \ | ||
| 144 | (__mask) != (u8)(__mask)); \ | ||
| 145 | (struct rt2x00_field8) { \ | ||
| 146 | __ffs(__mask), (__mask) \ | ||
| 147 | }; \ | ||
| 148 | }) | ||
| 149 | |||
| 150 | #define FIELD16(__mask) \ | ||
| 151 | ({ \ | ||
| 152 | BUILD_BUG_ON(!(__mask) || \ | ||
| 153 | !is_valid_mask(__mask) || \ | ||
| 154 | (__mask) != (u16)(__mask));\ | ||
| 155 | (struct rt2x00_field16) { \ | ||
| 156 | __ffs(__mask), (__mask) \ | ||
| 157 | }; \ | ||
| 158 | }) | ||
| 159 | |||
| 160 | #define FIELD32(__mask) \ | ||
| 161 | ({ \ | ||
| 162 | BUILD_BUG_ON(!(__mask) || \ | ||
| 163 | !is_valid_mask(__mask) || \ | ||
| 164 | (__mask) != (u32)(__mask));\ | ||
| 165 | (struct rt2x00_field32) { \ | ||
| 166 | __ffs(__mask), (__mask) \ | ||
| 167 | }; \ | ||
| 168 | }) | ||
| 169 | |||
| 170 | static inline void rt2x00_set_field32(u32 *reg, | ||
| 171 | const struct rt2x00_field32 field, | ||
| 172 | const u32 value) | ||
| 173 | { | ||
| 174 | *reg &= ~(field.bit_mask); | ||
| 175 | *reg |= (value << field.bit_offset) & field.bit_mask; | ||
| 176 | } | ||
| 177 | |||
| 178 | static inline u32 rt2x00_get_field32(const u32 reg, | ||
| 179 | const struct rt2x00_field32 field) | ||
| 180 | { | ||
| 181 | return (reg & field.bit_mask) >> field.bit_offset; | ||
| 182 | } | ||
| 183 | |||
| 184 | static inline void rt2x00_set_field16(u16 *reg, | ||
| 185 | const struct rt2x00_field16 field, | ||
| 186 | const u16 value) | ||
| 187 | { | ||
| 188 | *reg &= ~(field.bit_mask); | ||
| 189 | *reg |= (value << field.bit_offset) & field.bit_mask; | ||
| 190 | } | ||
| 191 | |||
| 192 | static inline u16 rt2x00_get_field16(const u16 reg, | ||
| 193 | const struct rt2x00_field16 field) | ||
| 194 | { | ||
| 195 | return (reg & field.bit_mask) >> field.bit_offset; | ||
| 196 | } | ||
| 197 | |||
| 198 | static inline void rt2x00_set_field8(u8 *reg, | ||
| 199 | const struct rt2x00_field8 field, | ||
| 200 | const u8 value) | ||
| 201 | { | ||
| 202 | *reg &= ~(field.bit_mask); | ||
| 203 | *reg |= (value << field.bit_offset) & field.bit_mask; | ||
| 204 | } | ||
| 205 | |||
| 206 | static inline u8 rt2x00_get_field8(const u8 reg, | ||
| 207 | const struct rt2x00_field8 field) | ||
| 208 | { | ||
| 209 | return (reg & field.bit_mask) >> field.bit_offset; | ||
| 210 | } | ||
| 211 | |||
| 212 | /* | ||
| 213 | * Device specific rate value. | ||
| 214 | * We will have to create the device specific rate value | ||
| 215 | * passed to the ieee80211 kernel. We need to make it a consist of | ||
| 216 | * multiple fields because we want to store more then 1 device specific | ||
| 217 | * values inside the value. | ||
| 218 | * 1 - rate, stored as 100 kbit/s. | ||
| 219 | * 2 - preamble, short_preamble enabled flag. | ||
| 220 | * 3 - MASK_RATE, which rates are enabled in this mode, this mask | ||
| 221 | * corresponds with the TX register format for the current device. | ||
| 222 | * 4 - plcp, 802.11b rates are device specific, | ||
| 223 | * 802.11g rates are set according to the ieee802.11a-1999 p.14. | ||
| 224 | * The bit to enable preamble is set in a seperate define. | ||
| 225 | */ | ||
| 226 | #define DEV_RATE FIELD32(0x000007ff) | ||
| 227 | #define DEV_PREAMBLE FIELD32(0x00000800) | ||
| 228 | #define DEV_RATEMASK FIELD32(0x00fff000) | ||
| 229 | #define DEV_PLCP FIELD32(0xff000000) | ||
| 230 | |||
| 231 | /* | ||
| 232 | * Bitfields | ||
| 233 | */ | ||
| 234 | #define DEV_RATEBIT_1MB ( 1 << 0 ) | ||
| 235 | #define DEV_RATEBIT_2MB ( 1 << 1 ) | ||
| 236 | #define DEV_RATEBIT_5_5MB ( 1 << 2 ) | ||
| 237 | #define DEV_RATEBIT_11MB ( 1 << 3 ) | ||
| 238 | #define DEV_RATEBIT_6MB ( 1 << 4 ) | ||
| 239 | #define DEV_RATEBIT_9MB ( 1 << 5 ) | ||
| 240 | #define DEV_RATEBIT_12MB ( 1 << 6 ) | ||
| 241 | #define DEV_RATEBIT_18MB ( 1 << 7 ) | ||
| 242 | #define DEV_RATEBIT_24MB ( 1 << 8 ) | ||
| 243 | #define DEV_RATEBIT_36MB ( 1 << 9 ) | ||
| 244 | #define DEV_RATEBIT_48MB ( 1 << 10 ) | ||
| 245 | #define DEV_RATEBIT_54MB ( 1 << 11 ) | ||
| 246 | |||
| 247 | /* | ||
| 248 | * Bitmasks for DEV_RATEMASK | ||
| 249 | */ | ||
| 250 | #define DEV_RATEMASK_1MB ( (DEV_RATEBIT_1MB << 1) -1 ) | ||
| 251 | #define DEV_RATEMASK_2MB ( (DEV_RATEBIT_2MB << 1) -1 ) | ||
| 252 | #define DEV_RATEMASK_5_5MB ( (DEV_RATEBIT_5_5MB << 1) -1 ) | ||
| 253 | #define DEV_RATEMASK_11MB ( (DEV_RATEBIT_11MB << 1) -1 ) | ||
| 254 | #define DEV_RATEMASK_6MB ( (DEV_RATEBIT_6MB << 1) -1 ) | ||
| 255 | #define DEV_RATEMASK_9MB ( (DEV_RATEBIT_9MB << 1) -1 ) | ||
| 256 | #define DEV_RATEMASK_12MB ( (DEV_RATEBIT_12MB << 1) -1 ) | ||
| 257 | #define DEV_RATEMASK_18MB ( (DEV_RATEBIT_18MB << 1) -1 ) | ||
| 258 | #define DEV_RATEMASK_24MB ( (DEV_RATEBIT_24MB << 1) -1 ) | ||
| 259 | #define DEV_RATEMASK_36MB ( (DEV_RATEBIT_36MB << 1) -1 ) | ||
| 260 | #define DEV_RATEMASK_48MB ( (DEV_RATEBIT_48MB << 1) -1 ) | ||
| 261 | #define DEV_RATEMASK_54MB ( (DEV_RATEBIT_54MB << 1) -1 ) | ||
| 262 | |||
| 263 | /* | ||
| 264 | * Bitmask groups of bitrates | ||
| 265 | */ | ||
| 266 | #define DEV_BASIC_RATEMASK \ | ||
| 267 | ( DEV_RATEMASK_11MB | \ | ||
| 268 | DEV_RATEBIT_6MB | DEV_RATEBIT_12MB | DEV_RATEBIT_24MB ) | ||
| 269 | |||
| 270 | #define DEV_CCK_RATEMASK ( DEV_RATEMASK_11MB ) | ||
| 271 | #define DEV_OFDM_RATEMASK ( DEV_RATEMASK_54MB & ~DEV_CCK_RATEMASK ) | ||
| 272 | |||
| 273 | /* | ||
| 274 | * Macro's to set and get specific fields from the device specific val and val2 | ||
| 275 | * fields inside the ieee80211_rate entry. | ||
| 276 | */ | ||
| 277 | #define DEVICE_SET_RATE_FIELD(__value, __mask) \ | ||
| 278 | (int)( ((__value) << DEV_##__mask.bit_offset) & DEV_##__mask.bit_mask ) | ||
| 279 | |||
| 280 | #define DEVICE_GET_RATE_FIELD(__value, __mask) \ | ||
| 281 | (int)( ((__value) & DEV_##__mask.bit_mask) >> DEV_##__mask.bit_offset ) | ||
| 282 | |||
| 283 | #endif /* RT2X00REG_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c new file mode 100644 index 00000000000..dc5b696f475 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00rfkill | ||
| 23 | Abstract: rt2x00 rfkill routines. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Set enviroment defines for rt2x00.h | ||
| 28 | */ | ||
| 29 | #define DRV_NAME "rt2x00lib" | ||
| 30 | |||
| 31 | #include <linux/input-polldev.h> | ||
| 32 | #include <linux/kernel.h> | ||
| 33 | #include <linux/module.h> | ||
| 34 | #include <linux/rfkill.h> | ||
| 35 | |||
| 36 | #include "rt2x00.h" | ||
| 37 | #include "rt2x00lib.h" | ||
| 38 | |||
| 39 | static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state) | ||
| 40 | { | ||
| 41 | struct rt2x00_dev *rt2x00dev = data; | ||
| 42 | int retval = 0; | ||
| 43 | |||
| 44 | if (unlikely(!rt2x00dev)) | ||
| 45 | return 0; | ||
| 46 | |||
| 47 | /* | ||
| 48 | * Only continue if we have an active interface, | ||
| 49 | * either monitor or non-monitor should be present. | ||
| 50 | */ | ||
| 51 | if (!is_interface_present(&rt2x00dev->interface) && | ||
| 52 | !is_monitor_present(&rt2x00dev->interface)) | ||
| 53 | return 0; | ||
| 54 | |||
| 55 | if (state == RFKILL_STATE_ON) { | ||
| 56 | INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n"); | ||
| 57 | __set_bit(DEVICE_ENABLED_RADIO_HW, &rt2x00dev->flags); | ||
| 58 | retval = rt2x00lib_enable_radio(rt2x00dev); | ||
| 59 | } else if (state == RFKILL_STATE_OFF) { | ||
| 60 | INFO(rt2x00dev, "Hardware button pressed, disabling radio.\n"); | ||
| 61 | __clear_bit(DEVICE_ENABLED_RADIO_HW, &rt2x00dev->flags); | ||
| 62 | rt2x00lib_disable_radio(rt2x00dev); | ||
| 63 | } | ||
| 64 | |||
| 65 | return retval; | ||
| 66 | } | ||
| 67 | |||
| 68 | static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev) | ||
| 69 | { | ||
| 70 | struct rt2x00_dev *rt2x00dev = poll_dev->private; | ||
| 71 | int state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev); | ||
| 72 | |||
| 73 | if (rt2x00dev->rfkill->state != state) | ||
| 74 | input_report_key(poll_dev->input, KEY_WLAN, 1); | ||
| 75 | } | ||
| 76 | |||
| 77 | int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) | ||
| 78 | { | ||
| 79 | int retval; | ||
| 80 | |||
| 81 | if (!test_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) | ||
| 82 | return 0; | ||
| 83 | |||
| 84 | retval = rfkill_register(rt2x00dev->rfkill); | ||
| 85 | if (retval) { | ||
| 86 | ERROR(rt2x00dev, "Failed to register rfkill handler.\n"); | ||
| 87 | return retval; | ||
| 88 | } | ||
| 89 | |||
| 90 | retval = input_register_polled_device(rt2x00dev->poll_dev); | ||
| 91 | if (retval) { | ||
| 92 | ERROR(rt2x00dev, "Failed to register polled device.\n"); | ||
| 93 | rfkill_unregister(rt2x00dev->rfkill); | ||
| 94 | return retval; | ||
| 95 | } | ||
| 96 | |||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) | ||
| 101 | { | ||
| 102 | if (!test_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) | ||
| 103 | return; | ||
| 104 | |||
| 105 | input_unregister_polled_device(rt2x00dev->poll_dev); | ||
| 106 | rfkill_unregister(rt2x00dev->rfkill); | ||
| 107 | } | ||
| 108 | |||
| 109 | int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) | ||
| 110 | { | ||
| 111 | struct device *device = wiphy_dev(rt2x00dev->hw->wiphy); | ||
| 112 | |||
| 113 | if (!test_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) | ||
| 114 | return 0; | ||
| 115 | |||
| 116 | rt2x00dev->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); | ||
| 117 | if (!rt2x00dev->rfkill) { | ||
| 118 | ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n"); | ||
| 119 | return -ENOMEM; | ||
| 120 | } | ||
| 121 | |||
| 122 | rt2x00dev->rfkill->name = rt2x00dev->ops->name; | ||
| 123 | rt2x00dev->rfkill->data = rt2x00dev; | ||
| 124 | rt2x00dev->rfkill->state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev); | ||
| 125 | rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio; | ||
| 126 | |||
| 127 | rt2x00dev->poll_dev = input_allocate_polled_device(); | ||
| 128 | if (!rt2x00dev->poll_dev) { | ||
| 129 | ERROR(rt2x00dev, "Failed to allocate polled device.\n"); | ||
| 130 | rfkill_free(rt2x00dev->rfkill); | ||
| 131 | return -ENOMEM; | ||
| 132 | } | ||
| 133 | |||
| 134 | rt2x00dev->poll_dev->private = rt2x00dev; | ||
| 135 | rt2x00dev->poll_dev->poll = rt2x00rfkill_poll; | ||
| 136 | rt2x00dev->poll_dev->poll_interval = RFKILL_POLL_INTERVAL; | ||
| 137 | |||
| 138 | return 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) | ||
| 142 | { | ||
| 143 | if (!test_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) | ||
| 144 | return; | ||
| 145 | |||
| 146 | input_free_polled_device(rt2x00dev->poll_dev); | ||
| 147 | rfkill_free(rt2x00dev->rfkill); | ||
| 148 | } | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00ring.h b/drivers/net/wireless/rt2x00/rt2x00ring.h new file mode 100644 index 00000000000..122c75248e7 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00ring.h | |||
| @@ -0,0 +1,255 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00 | ||
| 23 | Abstract: rt2x00 ring datastructures and routines | ||
| 24 | */ | ||
| 25 | |||
| 26 | #ifndef RT2X00RING_H | ||
| 27 | #define RT2X00RING_H | ||
| 28 | |||
| 29 | /* | ||
| 30 | * data_desc | ||
| 31 | * Each data entry also contains a descriptor which is used by the | ||
| 32 | * device to determine what should be done with the packet and | ||
| 33 | * what the current status is. | ||
| 34 | * This structure is greatly simplified, but the descriptors | ||
| 35 | * are basically a list of little endian 32 bit values. | ||
| 36 | * Make the array by default 1 word big, this will allow us | ||
| 37 | * to use sizeof() correctly. | ||
| 38 | */ | ||
| 39 | struct data_desc { | ||
| 40 | __le32 word[1]; | ||
| 41 | }; | ||
| 42 | |||
| 43 | /* | ||
| 44 | * data_entry_desc | ||
| 45 | * Summary of information that should be written into the | ||
| 46 | * descriptor for sending a TX frame. | ||
| 47 | */ | ||
| 48 | struct data_entry_desc { | ||
| 49 | unsigned long flags; | ||
| 50 | #define ENTRY_TXDONE 1 | ||
| 51 | #define ENTRY_TXD_RTS_FRAME 2 | ||
| 52 | #define ENTRY_TXD_OFDM_RATE 3 | ||
| 53 | #define ENTRY_TXD_MORE_FRAG 4 | ||
| 54 | #define ENTRY_TXD_REQ_TIMESTAMP 5 | ||
| 55 | #define ENTRY_TXD_BURST 6 | ||
| 56 | |||
| 57 | /* | ||
| 58 | * Queue ID. ID's 0-4 are data TX rings | ||
| 59 | */ | ||
| 60 | int queue; | ||
| 61 | #define QUEUE_MGMT 13 | ||
| 62 | #define QUEUE_RX 14 | ||
| 63 | #define QUEUE_OTHER 15 | ||
| 64 | |||
| 65 | /* | ||
| 66 | * PLCP values. | ||
| 67 | */ | ||
| 68 | u16 length_high; | ||
| 69 | u16 length_low; | ||
| 70 | u16 signal; | ||
| 71 | u16 service; | ||
| 72 | |||
| 73 | /* | ||
| 74 | * Timing information | ||
| 75 | */ | ||
| 76 | int aifs; | ||
| 77 | int ifs; | ||
| 78 | int cw_min; | ||
| 79 | int cw_max; | ||
| 80 | }; | ||
| 81 | |||
| 82 | /* | ||
| 83 | * data_entry | ||
| 84 | * The data ring is a list of data entries. | ||
| 85 | * Each entry holds a reference to the descriptor | ||
| 86 | * and the data buffer. For TX rings the reference to the | ||
| 87 | * sk_buff of the packet being transmitted is also stored here. | ||
| 88 | */ | ||
| 89 | struct data_entry { | ||
| 90 | /* | ||
| 91 | * Status flags | ||
| 92 | */ | ||
| 93 | unsigned long flags; | ||
| 94 | #define ENTRY_OWNER_NIC 1 | ||
| 95 | |||
| 96 | /* | ||
| 97 | * Ring we belong to. | ||
| 98 | */ | ||
| 99 | struct data_ring *ring; | ||
| 100 | |||
| 101 | /* | ||
| 102 | * sk_buff for the packet which is being transmitted | ||
| 103 | * in this entry (Only used with TX related rings). | ||
| 104 | */ | ||
| 105 | struct sk_buff *skb; | ||
| 106 | |||
| 107 | /* | ||
| 108 | * Store a ieee80211_tx_status structure in each | ||
| 109 | * ring entry, this will optimize the txdone | ||
| 110 | * handler. | ||
| 111 | */ | ||
| 112 | struct ieee80211_tx_status tx_status; | ||
| 113 | |||
| 114 | /* | ||
| 115 | * private pointer specific to driver. | ||
| 116 | */ | ||
| 117 | void *priv; | ||
| 118 | |||
| 119 | /* | ||
| 120 | * Data address for this entry. | ||
| 121 | */ | ||
| 122 | void *data_addr; | ||
| 123 | dma_addr_t data_dma; | ||
| 124 | }; | ||
| 125 | |||
| 126 | /* | ||
| 127 | * data_ring | ||
| 128 | * Data rings are used by the device to send and receive packets. | ||
| 129 | * The data_addr is the base address of the data memory. | ||
| 130 | * To determine at which point in the ring we are, | ||
| 131 | * have to use the rt2x00_ring_index_*() functions. | ||
| 132 | */ | ||
| 133 | struct data_ring { | ||
| 134 | /* | ||
| 135 | * Pointer to main rt2x00dev structure where this | ||
| 136 | * ring belongs to. | ||
| 137 | */ | ||
| 138 | struct rt2x00_dev *rt2x00dev; | ||
| 139 | |||
| 140 | /* | ||
| 141 | * Base address for the device specific data entries. | ||
| 142 | */ | ||
| 143 | struct data_entry *entry; | ||
| 144 | |||
| 145 | /* | ||
| 146 | * TX queue statistic info. | ||
| 147 | */ | ||
| 148 | struct ieee80211_tx_queue_stats_data stats; | ||
| 149 | |||
| 150 | /* | ||
| 151 | * TX Queue parameters. | ||
| 152 | */ | ||
| 153 | struct ieee80211_tx_queue_params tx_params; | ||
| 154 | |||
| 155 | /* | ||
| 156 | * Base address for data ring. | ||
| 157 | */ | ||
| 158 | dma_addr_t data_dma; | ||
| 159 | void *data_addr; | ||
| 160 | |||
| 161 | /* | ||
| 162 | * Index variables. | ||
| 163 | */ | ||
| 164 | u16 index; | ||
| 165 | u16 index_done; | ||
| 166 | |||
| 167 | /* | ||
| 168 | * Size of packet and descriptor in bytes. | ||
| 169 | */ | ||
| 170 | u16 data_size; | ||
| 171 | u16 desc_size; | ||
| 172 | }; | ||
| 173 | |||
| 174 | /* | ||
| 175 | * Handlers to determine the address of the current device specific | ||
| 176 | * data entry, where either index or index_done points to. | ||
| 177 | */ | ||
| 178 | static inline struct data_entry *rt2x00_get_data_entry(struct data_ring *ring) | ||
| 179 | { | ||
| 180 | return &ring->entry[ring->index]; | ||
| 181 | } | ||
| 182 | |||
| 183 | static inline struct data_entry *rt2x00_get_data_entry_done(struct data_ring | ||
| 184 | *ring) | ||
| 185 | { | ||
| 186 | return &ring->entry[ring->index_done]; | ||
| 187 | } | ||
| 188 | |||
| 189 | /* | ||
| 190 | * Total ring memory | ||
| 191 | */ | ||
| 192 | static inline int rt2x00_get_ring_size(struct data_ring *ring) | ||
| 193 | { | ||
| 194 | return ring->stats.limit * (ring->desc_size + ring->data_size); | ||
| 195 | } | ||
| 196 | |||
| 197 | /* | ||
| 198 | * Ring index manipulation functions. | ||
| 199 | */ | ||
| 200 | static inline void rt2x00_ring_index_inc(struct data_ring *ring) | ||
| 201 | { | ||
| 202 | ring->index++; | ||
| 203 | if (ring->index >= ring->stats.limit) | ||
| 204 | ring->index = 0; | ||
| 205 | ring->stats.len++; | ||
| 206 | } | ||
| 207 | |||
| 208 | static inline void rt2x00_ring_index_done_inc(struct data_ring *ring) | ||
| 209 | { | ||
| 210 | ring->index_done++; | ||
| 211 | if (ring->index_done >= ring->stats.limit) | ||
| 212 | ring->index_done = 0; | ||
| 213 | ring->stats.len--; | ||
| 214 | ring->stats.count++; | ||
| 215 | } | ||
| 216 | |||
| 217 | static inline void rt2x00_ring_index_clear(struct data_ring *ring) | ||
| 218 | { | ||
| 219 | ring->index = 0; | ||
| 220 | ring->index_done = 0; | ||
| 221 | ring->stats.len = 0; | ||
| 222 | ring->stats.count = 0; | ||
| 223 | } | ||
| 224 | |||
| 225 | static inline int rt2x00_ring_empty(struct data_ring *ring) | ||
| 226 | { | ||
| 227 | return ring->stats.len == 0; | ||
| 228 | } | ||
| 229 | |||
| 230 | static inline int rt2x00_ring_full(struct data_ring *ring) | ||
| 231 | { | ||
| 232 | return ring->stats.len == ring->stats.limit; | ||
| 233 | } | ||
| 234 | |||
| 235 | static inline int rt2x00_ring_free(struct data_ring *ring) | ||
| 236 | { | ||
| 237 | return ring->stats.limit - ring->stats.len; | ||
| 238 | } | ||
| 239 | |||
| 240 | /* | ||
| 241 | * TX/RX Descriptor access functions. | ||
| 242 | */ | ||
| 243 | static inline void rt2x00_desc_read(struct data_desc *desc, | ||
| 244 | const u8 word, u32 *value) | ||
| 245 | { | ||
| 246 | *value = le32_to_cpu(desc->word[word]); | ||
| 247 | } | ||
| 248 | |||
| 249 | static inline void rt2x00_desc_write(struct data_desc *desc, | ||
| 250 | const u8 word, const u32 value) | ||
| 251 | { | ||
| 252 | desc->word[word] = cpu_to_le32(value); | ||
| 253 | } | ||
| 254 | |||
| 255 | #endif /* RT2X00RING_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c new file mode 100644 index 00000000000..a0f05ca54bb --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
| @@ -0,0 +1,595 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00usb | ||
| 23 | Abstract: rt2x00 generic usb device routines. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Set enviroment defines for rt2x00.h | ||
| 28 | */ | ||
| 29 | #define DRV_NAME "rt2x00usb" | ||
| 30 | |||
| 31 | #include <linux/kernel.h> | ||
| 32 | #include <linux/module.h> | ||
| 33 | #include <linux/usb.h> | ||
| 34 | |||
| 35 | #include "rt2x00.h" | ||
| 36 | #include "rt2x00usb.h" | ||
| 37 | |||
| 38 | /* | ||
| 39 | * Interfacing with the HW. | ||
| 40 | */ | ||
| 41 | int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev, | ||
| 42 | const u8 request, const u8 requesttype, | ||
| 43 | const u16 offset, const u16 value, | ||
| 44 | void *buffer, const u16 buffer_length, | ||
| 45 | u16 timeout) | ||
| 46 | { | ||
| 47 | struct usb_device *usb_dev = | ||
| 48 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | ||
| 49 | int status; | ||
| 50 | unsigned int i; | ||
| 51 | unsigned int pipe = | ||
| 52 | (requesttype == USB_VENDOR_REQUEST_IN) ? | ||
| 53 | usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0); | ||
| 54 | |||
| 55 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 56 | status = usb_control_msg(usb_dev, pipe, request, requesttype, | ||
| 57 | value, offset, buffer, buffer_length, | ||
| 58 | timeout); | ||
| 59 | if (status >= 0) | ||
| 60 | return 0; | ||
| 61 | |||
| 62 | /* | ||
| 63 | * Check for errors, | ||
| 64 | * -ETIMEDOUT: We need a bit more time to complete. | ||
| 65 | * -ENODEV: Device has disappeared, no point continuing. | ||
| 66 | */ | ||
| 67 | if (status == -ETIMEDOUT) | ||
| 68 | timeout *= 2; | ||
| 69 | else if (status == -ENODEV) | ||
| 70 | break; | ||
| 71 | } | ||
| 72 | |||
| 73 | ERROR(rt2x00dev, | ||
| 74 | "Vendor Request 0x%02x failed for offset 0x%04x with error %d.\n", | ||
| 75 | request, offset, status); | ||
| 76 | |||
| 77 | return status; | ||
| 78 | } | ||
| 79 | EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request); | ||
| 80 | |||
| 81 | int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev, | ||
| 82 | const u8 request, const u8 requesttype, | ||
| 83 | const u16 offset, void *buffer, | ||
| 84 | const u16 buffer_length, u16 timeout) | ||
| 85 | { | ||
| 86 | int status; | ||
| 87 | |||
| 88 | /* | ||
| 89 | * Check for Cache availability. | ||
| 90 | */ | ||
| 91 | if (unlikely(!rt2x00dev->csr_cache || buffer_length > CSR_CACHE_SIZE)) { | ||
| 92 | ERROR(rt2x00dev, "CSR cache not available.\n"); | ||
| 93 | return -ENOMEM; | ||
| 94 | } | ||
| 95 | |||
| 96 | if (requesttype == USB_VENDOR_REQUEST_OUT) | ||
| 97 | memcpy(rt2x00dev->csr_cache, buffer, buffer_length); | ||
| 98 | |||
| 99 | status = rt2x00usb_vendor_request(rt2x00dev, request, requesttype, | ||
| 100 | offset, 0, rt2x00dev->csr_cache, | ||
| 101 | buffer_length, timeout); | ||
| 102 | |||
| 103 | if (!status && requesttype == USB_VENDOR_REQUEST_IN) | ||
| 104 | memcpy(buffer, rt2x00dev->csr_cache, buffer_length); | ||
| 105 | |||
| 106 | return status; | ||
| 107 | } | ||
| 108 | EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); | ||
| 109 | |||
| 110 | /* | ||
| 111 | * TX data handlers. | ||
| 112 | */ | ||
| 113 | static void rt2x00usb_interrupt_txdone(struct urb *urb) | ||
| 114 | { | ||
| 115 | struct data_entry *entry = (struct data_entry *)urb->context; | ||
| 116 | struct data_ring *ring = entry->ring; | ||
| 117 | struct rt2x00_dev *rt2x00dev = ring->rt2x00dev; | ||
| 118 | struct data_desc *txd = (struct data_desc *)entry->skb->data; | ||
| 119 | u32 word; | ||
| 120 | int tx_status; | ||
| 121 | |||
| 122 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | ||
| 123 | !__test_and_clear_bit(ENTRY_OWNER_NIC, &entry->flags)) | ||
| 124 | return; | ||
| 125 | |||
| 126 | rt2x00_desc_read(txd, 0, &word); | ||
| 127 | |||
| 128 | /* | ||
| 129 | * Remove the descriptor data from the buffer. | ||
| 130 | */ | ||
| 131 | skb_pull(entry->skb, ring->desc_size); | ||
| 132 | |||
| 133 | /* | ||
| 134 | * Obtain the status about this packet. | ||
| 135 | */ | ||
| 136 | tx_status = !urb->status ? TX_SUCCESS : TX_FAIL_RETRY; | ||
| 137 | |||
| 138 | rt2x00lib_txdone(entry, tx_status, 0); | ||
| 139 | |||
| 140 | /* | ||
| 141 | * Make this entry available for reuse. | ||
| 142 | */ | ||
| 143 | entry->flags = 0; | ||
| 144 | rt2x00_ring_index_done_inc(entry->ring); | ||
| 145 | |||
| 146 | /* | ||
| 147 | * If the data ring was full before the txdone handler | ||
| 148 | * we must make sure the packet queue in the mac80211 stack | ||
| 149 | * is reenabled when the txdone handler has finished. | ||
| 150 | */ | ||
| 151 | if (!rt2x00_ring_full(ring)) | ||
| 152 | ieee80211_wake_queue(rt2x00dev->hw, | ||
| 153 | entry->tx_status.control.queue); | ||
| 154 | } | ||
| 155 | |||
| 156 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | ||
| 157 | struct data_ring *ring, struct sk_buff *skb, | ||
| 158 | struct ieee80211_tx_control *control) | ||
| 159 | { | ||
| 160 | struct usb_device *usb_dev = | ||
| 161 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | ||
| 162 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; | ||
| 163 | struct data_entry *entry = rt2x00_get_data_entry(ring); | ||
| 164 | u32 length = skb->len; | ||
| 165 | |||
| 166 | if (rt2x00_ring_full(ring)) { | ||
| 167 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | ||
| 168 | return -EINVAL; | ||
| 169 | } | ||
| 170 | |||
| 171 | if (test_bit(ENTRY_OWNER_NIC, &entry->flags)) { | ||
| 172 | ERROR(rt2x00dev, | ||
| 173 | "Arrived at non-free entry in the non-full queue %d.\n" | ||
| 174 | "Please file bug report to %s.\n", | ||
| 175 | control->queue, DRV_PROJECT); | ||
| 176 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | ||
| 177 | return -EINVAL; | ||
| 178 | } | ||
| 179 | |||
| 180 | /* | ||
| 181 | * Add the descriptor in front of the skb. | ||
| 182 | */ | ||
| 183 | skb_push(skb, rt2x00dev->hw->extra_tx_headroom); | ||
| 184 | memset(skb->data, 0x00, rt2x00dev->hw->extra_tx_headroom); | ||
| 185 | |||
| 186 | rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data, | ||
| 187 | ieee80211hdr, length, control); | ||
| 188 | memcpy(&entry->tx_status.control, control, sizeof(*control)); | ||
| 189 | entry->skb = skb; | ||
| 190 | |||
| 191 | /* | ||
| 192 | * Length passed to usb_fill_urb cannot be an odd number, | ||
| 193 | * so add 1 byte to make it even. | ||
| 194 | */ | ||
| 195 | length += rt2x00dev->hw->extra_tx_headroom; | ||
| 196 | if (length % 2) | ||
| 197 | length++; | ||
| 198 | |||
| 199 | __set_bit(ENTRY_OWNER_NIC, &entry->flags); | ||
| 200 | usb_fill_bulk_urb(entry->priv, usb_dev, | ||
| 201 | usb_sndbulkpipe(usb_dev, 1), | ||
| 202 | skb->data, length, rt2x00usb_interrupt_txdone, entry); | ||
| 203 | usb_submit_urb(entry->priv, GFP_ATOMIC); | ||
| 204 | |||
| 205 | rt2x00_ring_index_inc(ring); | ||
| 206 | |||
| 207 | if (rt2x00_ring_full(ring)) | ||
| 208 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | ||
| 209 | |||
| 210 | return 0; | ||
| 211 | } | ||
| 212 | EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data); | ||
| 213 | |||
| 214 | /* | ||
| 215 | * RX data handlers. | ||
| 216 | */ | ||
| 217 | static void rt2x00usb_interrupt_rxdone(struct urb *urb) | ||
| 218 | { | ||
| 219 | struct data_entry *entry = (struct data_entry *)urb->context; | ||
| 220 | struct data_ring *ring = entry->ring; | ||
| 221 | struct rt2x00_dev *rt2x00dev = ring->rt2x00dev; | ||
| 222 | struct sk_buff *skb; | ||
| 223 | int retval; | ||
| 224 | int signal; | ||
| 225 | int rssi; | ||
| 226 | int ofdm; | ||
| 227 | int size; | ||
| 228 | int frame_size; | ||
| 229 | |||
| 230 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | ||
| 231 | !test_and_clear_bit(ENTRY_OWNER_NIC, &entry->flags)) | ||
| 232 | return; | ||
| 233 | |||
| 234 | /* | ||
| 235 | * Check if the received data is simply too small | ||
| 236 | * to be actually valid, or if the urb is signaling | ||
| 237 | * a problem. | ||
| 238 | */ | ||
| 239 | if (urb->actual_length < entry->ring->desc_size || urb->status) | ||
| 240 | goto skip_entry; | ||
| 241 | |||
| 242 | retval = rt2x00dev->ops->lib->fill_rxdone(entry, &signal, &rssi, | ||
| 243 | &ofdm, &size); | ||
| 244 | if (retval) | ||
| 245 | goto skip_entry; | ||
| 246 | |||
| 247 | /* | ||
| 248 | * Allocate a new sk buffer to replace the current one. | ||
| 249 | * If allocation fails, we should drop the current frame | ||
| 250 | * so we can recycle the existing sk buffer for the new frame. | ||
| 251 | */ | ||
| 252 | frame_size = entry->ring->data_size + entry->ring->desc_size; | ||
| 253 | skb = dev_alloc_skb(frame_size + NET_IP_ALIGN); | ||
| 254 | if (!skb) | ||
| 255 | goto skip_entry; | ||
| 256 | |||
| 257 | skb_reserve(skb, NET_IP_ALIGN); | ||
| 258 | skb_put(skb, frame_size); | ||
| 259 | |||
| 260 | /* | ||
| 261 | * Trim the skb_buffer to only contain the valid | ||
| 262 | * frame data (so ignore the device's descriptor). | ||
| 263 | */ | ||
| 264 | skb_trim(entry->skb, size); | ||
| 265 | |||
| 266 | /* | ||
| 267 | * Send the frame to rt2x00lib for further processing. | ||
| 268 | */ | ||
| 269 | rt2x00lib_rxdone(entry, entry->skb, signal, rssi, ofdm); | ||
| 270 | |||
| 271 | /* | ||
| 272 | * Replace current entry's skb with the newly allocated one, | ||
| 273 | * and reinitialize the urb. | ||
| 274 | */ | ||
| 275 | entry->skb = skb; | ||
| 276 | urb->transfer_buffer = entry->skb->data; | ||
| 277 | urb->transfer_buffer_length = entry->skb->len; | ||
| 278 | |||
| 279 | skip_entry: | ||
| 280 | if (test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) { | ||
| 281 | __set_bit(ENTRY_OWNER_NIC, &entry->flags); | ||
| 282 | usb_submit_urb(urb, GFP_ATOMIC); | ||
| 283 | } | ||
| 284 | |||
| 285 | rt2x00_ring_index_inc(ring); | ||
| 286 | } | ||
| 287 | |||
| 288 | /* | ||
| 289 | * Radio handlers | ||
| 290 | */ | ||
| 291 | void rt2x00usb_enable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 292 | { | ||
| 293 | struct usb_device *usb_dev = | ||
| 294 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | ||
| 295 | struct data_ring *ring; | ||
| 296 | struct data_entry *entry; | ||
| 297 | unsigned int i; | ||
| 298 | |||
| 299 | /* | ||
| 300 | * Initialize the TX rings | ||
| 301 | */ | ||
| 302 | txringall_for_each(rt2x00dev, ring) { | ||
| 303 | for (i = 0; i < ring->stats.limit; i++) | ||
| 304 | ring->entry[i].flags = 0; | ||
| 305 | |||
| 306 | rt2x00_ring_index_clear(ring); | ||
| 307 | } | ||
| 308 | |||
| 309 | /* | ||
| 310 | * Initialize and start the RX ring. | ||
| 311 | */ | ||
| 312 | rt2x00_ring_index_clear(rt2x00dev->rx); | ||
| 313 | |||
| 314 | for (i = 0; i < rt2x00dev->rx->stats.limit; i++) { | ||
| 315 | entry = &rt2x00dev->rx->entry[i]; | ||
| 316 | |||
| 317 | usb_fill_bulk_urb(entry->priv, usb_dev, | ||
| 318 | usb_rcvbulkpipe(usb_dev, 1), | ||
| 319 | entry->skb->data, entry->skb->len, | ||
| 320 | rt2x00usb_interrupt_rxdone, entry); | ||
| 321 | |||
| 322 | __set_bit(ENTRY_OWNER_NIC, &entry->flags); | ||
| 323 | usb_submit_urb(entry->priv, GFP_ATOMIC); | ||
| 324 | } | ||
| 325 | } | ||
| 326 | EXPORT_SYMBOL_GPL(rt2x00usb_enable_radio); | ||
| 327 | |||
| 328 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 329 | { | ||
| 330 | struct data_ring *ring; | ||
| 331 | unsigned int i; | ||
| 332 | |||
| 333 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0x0000, 0x0000, | ||
| 334 | REGISTER_TIMEOUT); | ||
| 335 | |||
| 336 | /* | ||
| 337 | * Cancel all rings. | ||
| 338 | */ | ||
| 339 | ring_for_each(rt2x00dev, ring) { | ||
| 340 | for (i = 0; i < ring->stats.limit; i++) | ||
| 341 | usb_kill_urb(ring->entry[i].priv); | ||
| 342 | } | ||
| 343 | } | ||
| 344 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | ||
| 345 | |||
| 346 | /* | ||
| 347 | * Device initialization handlers. | ||
| 348 | */ | ||
| 349 | static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, | ||
| 350 | struct data_ring *ring) | ||
| 351 | { | ||
| 352 | unsigned int i; | ||
| 353 | |||
| 354 | /* | ||
| 355 | * Allocate the URB's | ||
| 356 | */ | ||
| 357 | for (i = 0; i < ring->stats.limit; i++) { | ||
| 358 | ring->entry[i].priv = usb_alloc_urb(0, GFP_KERNEL); | ||
| 359 | if (!ring->entry[i].priv) | ||
| 360 | return -ENOMEM; | ||
| 361 | } | ||
| 362 | |||
| 363 | return 0; | ||
| 364 | } | ||
| 365 | |||
| 366 | static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, | ||
| 367 | struct data_ring *ring) | ||
| 368 | { | ||
| 369 | unsigned int i; | ||
| 370 | |||
| 371 | if (!ring->entry) | ||
| 372 | return; | ||
| 373 | |||
| 374 | for (i = 0; i < ring->stats.limit; i++) { | ||
| 375 | usb_kill_urb(ring->entry[i].priv); | ||
| 376 | usb_free_urb(ring->entry[i].priv); | ||
| 377 | if (ring->entry[i].skb) | ||
| 378 | kfree_skb(ring->entry[i].skb); | ||
| 379 | } | ||
| 380 | } | ||
| 381 | |||
| 382 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) | ||
| 383 | { | ||
| 384 | struct data_ring *ring; | ||
| 385 | struct sk_buff *skb; | ||
| 386 | unsigned int entry_size; | ||
| 387 | unsigned int i; | ||
| 388 | int status; | ||
| 389 | |||
| 390 | /* | ||
| 391 | * Allocate DMA | ||
| 392 | */ | ||
| 393 | ring_for_each(rt2x00dev, ring) { | ||
| 394 | status = rt2x00usb_alloc_urb(rt2x00dev, ring); | ||
| 395 | if (status) | ||
| 396 | goto exit; | ||
| 397 | } | ||
| 398 | |||
| 399 | /* | ||
| 400 | * For the RX ring, skb's should be allocated. | ||
| 401 | */ | ||
| 402 | entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; | ||
| 403 | for (i = 0; i < rt2x00dev->rx->stats.limit; i++) { | ||
| 404 | skb = dev_alloc_skb(NET_IP_ALIGN + entry_size); | ||
| 405 | if (!skb) | ||
| 406 | goto exit; | ||
| 407 | |||
| 408 | skb_reserve(skb, NET_IP_ALIGN); | ||
| 409 | skb_put(skb, entry_size); | ||
| 410 | |||
| 411 | rt2x00dev->rx->entry[i].skb = skb; | ||
| 412 | } | ||
| 413 | |||
| 414 | return 0; | ||
| 415 | |||
| 416 | exit: | ||
| 417 | rt2x00usb_uninitialize(rt2x00dev); | ||
| 418 | |||
| 419 | return status; | ||
| 420 | } | ||
| 421 | EXPORT_SYMBOL_GPL(rt2x00usb_initialize); | ||
| 422 | |||
| 423 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev) | ||
| 424 | { | ||
| 425 | struct data_ring *ring; | ||
| 426 | |||
| 427 | ring_for_each(rt2x00dev, ring) | ||
| 428 | rt2x00usb_free_urb(rt2x00dev, ring); | ||
| 429 | } | ||
| 430 | EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize); | ||
| 431 | |||
| 432 | /* | ||
| 433 | * USB driver handlers. | ||
| 434 | */ | ||
| 435 | static void rt2x00usb_free_reg(struct rt2x00_dev *rt2x00dev) | ||
| 436 | { | ||
| 437 | kfree(rt2x00dev->rf); | ||
| 438 | rt2x00dev->rf = NULL; | ||
| 439 | |||
| 440 | kfree(rt2x00dev->eeprom); | ||
| 441 | rt2x00dev->eeprom = NULL; | ||
| 442 | |||
| 443 | kfree(rt2x00dev->csr_cache); | ||
| 444 | rt2x00dev->csr_cache = NULL; | ||
| 445 | } | ||
| 446 | |||
| 447 | static int rt2x00usb_alloc_reg(struct rt2x00_dev *rt2x00dev) | ||
| 448 | { | ||
| 449 | rt2x00dev->csr_cache = kzalloc(CSR_CACHE_SIZE, GFP_KERNEL); | ||
| 450 | if (!rt2x00dev->csr_cache) | ||
| 451 | goto exit; | ||
| 452 | |||
| 453 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); | ||
| 454 | if (!rt2x00dev->eeprom) | ||
| 455 | goto exit; | ||
| 456 | |||
| 457 | rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL); | ||
| 458 | if (!rt2x00dev->rf) | ||
| 459 | goto exit; | ||
| 460 | |||
| 461 | return 0; | ||
| 462 | |||
| 463 | exit: | ||
| 464 | ERROR_PROBE("Failed to allocate registers.\n"); | ||
| 465 | |||
| 466 | rt2x00usb_free_reg(rt2x00dev); | ||
| 467 | |||
| 468 | return -ENOMEM; | ||
| 469 | } | ||
| 470 | |||
| 471 | int rt2x00usb_probe(struct usb_interface *usb_intf, | ||
| 472 | const struct usb_device_id *id) | ||
| 473 | { | ||
| 474 | struct usb_device *usb_dev = interface_to_usbdev(usb_intf); | ||
| 475 | struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_info; | ||
| 476 | struct ieee80211_hw *hw; | ||
| 477 | struct rt2x00_dev *rt2x00dev; | ||
| 478 | int retval; | ||
| 479 | |||
| 480 | usb_dev = usb_get_dev(usb_dev); | ||
| 481 | |||
| 482 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); | ||
| 483 | if (!hw) { | ||
| 484 | ERROR_PROBE("Failed to allocate hardware.\n"); | ||
| 485 | retval = -ENOMEM; | ||
| 486 | goto exit_put_device; | ||
| 487 | } | ||
| 488 | |||
| 489 | usb_set_intfdata(usb_intf, hw); | ||
| 490 | |||
| 491 | rt2x00dev = hw->priv; | ||
| 492 | rt2x00dev->dev = usb_intf; | ||
| 493 | rt2x00dev->ops = ops; | ||
| 494 | rt2x00dev->hw = hw; | ||
| 495 | |||
| 496 | retval = rt2x00usb_alloc_reg(rt2x00dev); | ||
| 497 | if (retval) | ||
| 498 | goto exit_free_device; | ||
| 499 | |||
| 500 | retval = rt2x00lib_probe_dev(rt2x00dev); | ||
| 501 | if (retval) | ||
| 502 | goto exit_free_reg; | ||
| 503 | |||
| 504 | return 0; | ||
| 505 | |||
| 506 | exit_free_reg: | ||
| 507 | rt2x00usb_free_reg(rt2x00dev); | ||
| 508 | |||
| 509 | exit_free_device: | ||
| 510 | ieee80211_free_hw(hw); | ||
| 511 | |||
| 512 | exit_put_device: | ||
| 513 | usb_put_dev(usb_dev); | ||
| 514 | |||
| 515 | usb_set_intfdata(usb_intf, NULL); | ||
| 516 | |||
| 517 | return retval; | ||
| 518 | } | ||
| 519 | EXPORT_SYMBOL_GPL(rt2x00usb_probe); | ||
| 520 | |||
| 521 | void rt2x00usb_disconnect(struct usb_interface *usb_intf) | ||
| 522 | { | ||
| 523 | struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); | ||
| 524 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 525 | |||
| 526 | /* | ||
| 527 | * Free all allocated data. | ||
| 528 | */ | ||
| 529 | rt2x00lib_remove_dev(rt2x00dev); | ||
| 530 | rt2x00usb_free_reg(rt2x00dev); | ||
| 531 | ieee80211_free_hw(hw); | ||
| 532 | |||
| 533 | /* | ||
| 534 | * Free the USB device data. | ||
| 535 | */ | ||
| 536 | usb_set_intfdata(usb_intf, NULL); | ||
| 537 | usb_put_dev(interface_to_usbdev(usb_intf)); | ||
| 538 | } | ||
| 539 | EXPORT_SYMBOL_GPL(rt2x00usb_disconnect); | ||
| 540 | |||
| 541 | #ifdef CONFIG_PM | ||
| 542 | int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state) | ||
| 543 | { | ||
| 544 | struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); | ||
| 545 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 546 | int retval; | ||
| 547 | |||
| 548 | retval = rt2x00lib_suspend(rt2x00dev, state); | ||
| 549 | if (retval) | ||
| 550 | return retval; | ||
| 551 | |||
| 552 | rt2x00usb_free_reg(rt2x00dev); | ||
| 553 | |||
| 554 | /* | ||
| 555 | * Decrease usbdev refcount. | ||
| 556 | */ | ||
| 557 | usb_put_dev(interface_to_usbdev(usb_intf)); | ||
| 558 | |||
| 559 | return 0; | ||
| 560 | } | ||
| 561 | EXPORT_SYMBOL_GPL(rt2x00usb_suspend); | ||
| 562 | |||
| 563 | int rt2x00usb_resume(struct usb_interface *usb_intf) | ||
| 564 | { | ||
| 565 | struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); | ||
| 566 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 567 | int retval; | ||
| 568 | |||
| 569 | usb_get_dev(interface_to_usbdev(usb_intf)); | ||
| 570 | |||
| 571 | retval = rt2x00usb_alloc_reg(rt2x00dev); | ||
| 572 | if (retval) | ||
| 573 | return retval; | ||
| 574 | |||
| 575 | retval = rt2x00lib_resume(rt2x00dev); | ||
| 576 | if (retval) | ||
| 577 | goto exit_free_reg; | ||
| 578 | |||
| 579 | return 0; | ||
| 580 | |||
| 581 | exit_free_reg: | ||
| 582 | rt2x00usb_free_reg(rt2x00dev); | ||
| 583 | |||
| 584 | return retval; | ||
| 585 | } | ||
| 586 | EXPORT_SYMBOL_GPL(rt2x00usb_resume); | ||
| 587 | #endif /* CONFIG_PM */ | ||
| 588 | |||
| 589 | /* | ||
| 590 | * rt2x00pci module information. | ||
| 591 | */ | ||
| 592 | MODULE_AUTHOR(DRV_PROJECT); | ||
| 593 | MODULE_VERSION(DRV_VERSION); | ||
| 594 | MODULE_DESCRIPTION("rt2x00 library"); | ||
| 595 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h new file mode 100644 index 00000000000..d4113e5158f --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
| @@ -0,0 +1,180 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt2x00usb | ||
| 23 | Abstract: Data structures for the rt2x00usb module. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #ifndef RT2X00USB_H | ||
| 27 | #define RT2X00USB_H | ||
| 28 | |||
| 29 | /* | ||
| 30 | * This variable should be used with the | ||
| 31 | * usb_driver structure initialization. | ||
| 32 | */ | ||
| 33 | #define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops) | ||
| 34 | |||
| 35 | /* | ||
| 36 | * Register defines. | ||
| 37 | * Some registers require multiple attempts before success, | ||
| 38 | * in those cases REGISTER_BUSY_COUNT attempts should be | ||
| 39 | * taken with a REGISTER_BUSY_DELAY interval. | ||
| 40 | * For USB vendor requests we need to pass a timeout | ||
| 41 | * time in ms, for this we use the REGISTER_TIMEOUT, | ||
| 42 | * however when loading firmware a higher value is | ||
| 43 | * required. In that case we use the REGISTER_TIMEOUT_FIRMWARE. | ||
| 44 | */ | ||
| 45 | #define REGISTER_BUSY_COUNT 5 | ||
| 46 | #define REGISTER_BUSY_DELAY 100 | ||
| 47 | #define REGISTER_TIMEOUT 20 | ||
| 48 | #define REGISTER_TIMEOUT_FIRMWARE 1000 | ||
| 49 | |||
| 50 | /* | ||
| 51 | * Cache size | ||
| 52 | */ | ||
| 53 | #define CSR_CACHE_SIZE 8 | ||
| 54 | #define CSR_CACHE_SIZE_FIRMWARE 64 | ||
| 55 | |||
| 56 | /* | ||
| 57 | * USB request types. | ||
| 58 | */ | ||
| 59 | #define USB_VENDOR_REQUEST ( USB_TYPE_VENDOR | USB_RECIP_DEVICE ) | ||
| 60 | #define USB_VENDOR_REQUEST_IN ( USB_DIR_IN | USB_VENDOR_REQUEST ) | ||
| 61 | #define USB_VENDOR_REQUEST_OUT ( USB_DIR_OUT | USB_VENDOR_REQUEST ) | ||
| 62 | |||
| 63 | /* | ||
| 64 | * USB vendor commands. | ||
| 65 | */ | ||
| 66 | #define USB_DEVICE_MODE 0x01 | ||
| 67 | #define USB_SINGLE_WRITE 0x02 | ||
| 68 | #define USB_SINGLE_READ 0x03 | ||
| 69 | #define USB_MULTI_WRITE 0x06 | ||
| 70 | #define USB_MULTI_READ 0x07 | ||
| 71 | #define USB_EEPROM_WRITE 0x08 | ||
| 72 | #define USB_EEPROM_READ 0x09 | ||
| 73 | #define USB_LED_CONTROL 0x0a /* RT73USB */ | ||
| 74 | #define USB_RX_CONTROL 0x0c | ||
| 75 | |||
| 76 | /* | ||
| 77 | * Device modes offset | ||
| 78 | */ | ||
| 79 | #define USB_MODE_RESET 0x01 | ||
| 80 | #define USB_MODE_UNPLUG 0x02 | ||
| 81 | #define USB_MODE_FUNCTION 0x03 | ||
| 82 | #define USB_MODE_TEST 0x04 | ||
| 83 | #define USB_MODE_SLEEP 0x07 /* RT73USB */ | ||
| 84 | #define USB_MODE_FIRMWARE 0x08 /* RT73USB */ | ||
| 85 | #define USB_MODE_WAKEUP 0x09 /* RT73USB */ | ||
| 86 | |||
| 87 | /* | ||
| 88 | * Used to read/write from/to the device. | ||
| 89 | * This is the main function to communicate with the device, | ||
| 90 | * the buffer argument _must_ either be NULL or point to | ||
| 91 | * a buffer allocated by kmalloc. Failure to do so can lead | ||
| 92 | * to unexpected behavior depending on the architecture. | ||
| 93 | */ | ||
| 94 | int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev, | ||
| 95 | const u8 request, const u8 requesttype, | ||
| 96 | const u16 offset, const u16 value, | ||
| 97 | void *buffer, const u16 buffer_length, | ||
| 98 | u16 timeout); | ||
| 99 | |||
| 100 | /* | ||
| 101 | * Used to read/write from/to the device. | ||
| 102 | * This function will use a previously with kmalloc allocated cache | ||
| 103 | * to communicate with the device. The contents of the buffer pointer | ||
| 104 | * will be copied to this cache when writing, or read from the cache | ||
| 105 | * when reading. | ||
| 106 | * Buffers send to rt2x00usb_vendor_request _must_ be allocated with | ||
| 107 | * kmalloc. Hence the reason for using a previously allocated cache | ||
| 108 | * which has been allocated properly. | ||
| 109 | */ | ||
| 110 | int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev, | ||
| 111 | const u8 request, const u8 requesttype, | ||
| 112 | const u16 offset, void *buffer, | ||
| 113 | const u16 buffer_length, u16 timeout); | ||
| 114 | |||
| 115 | /* | ||
| 116 | * Simple wrapper around rt2x00usb_vendor_request to write a single | ||
| 117 | * command to the device. Since we don't use the buffer argument we | ||
| 118 | * don't have to worry about kmalloc here. | ||
| 119 | */ | ||
| 120 | static inline int rt2x00usb_vendor_request_sw(const struct rt2x00_dev | ||
| 121 | *rt2x00dev, | ||
| 122 | const u8 request, | ||
| 123 | const u16 offset, | ||
| 124 | const u16 value, | ||
| 125 | int timeout) | ||
| 126 | { | ||
| 127 | return rt2x00usb_vendor_request(rt2x00dev, request, | ||
| 128 | USB_VENDOR_REQUEST_OUT, offset, | ||
| 129 | value, NULL, 0, timeout); | ||
| 130 | } | ||
| 131 | |||
| 132 | /* | ||
| 133 | * Simple wrapper around rt2x00usb_vendor_request to read the eeprom | ||
| 134 | * from the device. Note that the eeprom argument _must_ be allocated using | ||
| 135 | * kmalloc for correct handling inside the kernel USB layer. | ||
| 136 | */ | ||
| 137 | static inline int rt2x00usb_eeprom_read(const struct rt2x00_dev *rt2x00dev, | ||
| 138 | __le16 *eeprom, const u16 lenght) | ||
| 139 | { | ||
| 140 | int timeout = REGISTER_TIMEOUT * (lenght / sizeof(u16)); | ||
| 141 | |||
| 142 | return rt2x00usb_vendor_request(rt2x00dev, USB_EEPROM_READ, | ||
| 143 | USB_VENDOR_REQUEST_IN, 0x0000, | ||
| 144 | 0x0000, eeprom, lenght, timeout); | ||
| 145 | } | ||
| 146 | |||
| 147 | /* | ||
| 148 | * Radio handlers | ||
| 149 | */ | ||
| 150 | void rt2x00usb_enable_radio(struct rt2x00_dev *rt2x00dev); | ||
| 151 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev); | ||
| 152 | |||
| 153 | /* | ||
| 154 | * TX data handlers. | ||
| 155 | */ | ||
| 156 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | ||
| 157 | struct data_ring *ring, struct sk_buff *skb, | ||
| 158 | struct ieee80211_tx_control *control); | ||
| 159 | |||
| 160 | /* | ||
| 161 | * Device initialization handlers. | ||
| 162 | */ | ||
| 163 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev); | ||
| 164 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev); | ||
| 165 | |||
| 166 | /* | ||
| 167 | * USB driver handlers. | ||
| 168 | */ | ||
| 169 | int rt2x00usb_probe(struct usb_interface *usb_intf, | ||
| 170 | const struct usb_device_id *id); | ||
| 171 | void rt2x00usb_disconnect(struct usb_interface *usb_intf); | ||
| 172 | #ifdef CONFIG_PM | ||
| 173 | int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state); | ||
| 174 | int rt2x00usb_resume(struct usb_interface *usb_intf); | ||
| 175 | #else | ||
| 176 | #define rt2x00usb_suspend NULL | ||
| 177 | #define rt2x00usb_resume NULL | ||
| 178 | #endif /* CONFIG_PM */ | ||
| 179 | |||
| 180 | #endif /* RT2X00USB_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c new file mode 100644 index 00000000000..730bed5a198 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
| @@ -0,0 +1,2603 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt61pci | ||
| 23 | Abstract: rt61pci device specific routines. | ||
| 24 | Supported chipsets: RT2561, RT2561s, RT2661. | ||
| 25 | */ | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Set enviroment defines for rt2x00.h | ||
| 29 | */ | ||
| 30 | #define DRV_NAME "rt61pci" | ||
| 31 | |||
| 32 | #include <linux/delay.h> | ||
| 33 | #include <linux/etherdevice.h> | ||
| 34 | #include <linux/init.h> | ||
| 35 | #include <linux/kernel.h> | ||
| 36 | #include <linux/module.h> | ||
| 37 | #include <linux/pci.h> | ||
| 38 | #include <linux/eeprom_93cx6.h> | ||
| 39 | |||
| 40 | #include "rt2x00.h" | ||
| 41 | #include "rt2x00pci.h" | ||
| 42 | #include "rt61pci.h" | ||
| 43 | |||
| 44 | /* | ||
| 45 | * Register access. | ||
| 46 | * BBP and RF register require indirect register access, | ||
| 47 | * and use the CSR registers PHY_CSR3 and PHY_CSR4 to achieve this. | ||
| 48 | * These indirect registers work with busy bits, | ||
| 49 | * and we will try maximal REGISTER_BUSY_COUNT times to access | ||
| 50 | * the register while taking a REGISTER_BUSY_DELAY us delay | ||
| 51 | * between each attampt. When the busy bit is still set at that time, | ||
| 52 | * the access attempt is considered to have failed, | ||
| 53 | * and we will print an error. | ||
| 54 | */ | ||
| 55 | static u32 rt61pci_bbp_check(const struct rt2x00_dev *rt2x00dev) | ||
| 56 | { | ||
| 57 | u32 reg; | ||
| 58 | unsigned int i; | ||
| 59 | |||
| 60 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 61 | rt2x00pci_register_read(rt2x00dev, PHY_CSR3, ®); | ||
| 62 | if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY)) | ||
| 63 | break; | ||
| 64 | udelay(REGISTER_BUSY_DELAY); | ||
| 65 | } | ||
| 66 | |||
| 67 | return reg; | ||
| 68 | } | ||
| 69 | |||
| 70 | static void rt61pci_bbp_write(const struct rt2x00_dev *rt2x00dev, | ||
| 71 | const unsigned int word, const u8 value) | ||
| 72 | { | ||
| 73 | u32 reg; | ||
| 74 | |||
| 75 | /* | ||
| 76 | * Wait until the BBP becomes ready. | ||
| 77 | */ | ||
| 78 | reg = rt61pci_bbp_check(rt2x00dev); | ||
| 79 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | ||
| 80 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); | ||
| 81 | return; | ||
| 82 | } | ||
| 83 | |||
| 84 | /* | ||
| 85 | * Write the data into the BBP. | ||
| 86 | */ | ||
| 87 | reg = 0; | ||
| 88 | rt2x00_set_field32(®, PHY_CSR3_VALUE, value); | ||
| 89 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); | ||
| 90 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | ||
| 91 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); | ||
| 92 | |||
| 93 | rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); | ||
| 94 | } | ||
| 95 | |||
| 96 | static void rt61pci_bbp_read(const struct rt2x00_dev *rt2x00dev, | ||
| 97 | const unsigned int word, u8 *value) | ||
| 98 | { | ||
| 99 | u32 reg; | ||
| 100 | |||
| 101 | /* | ||
| 102 | * Wait until the BBP becomes ready. | ||
| 103 | */ | ||
| 104 | reg = rt61pci_bbp_check(rt2x00dev); | ||
| 105 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | ||
| 106 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | ||
| 107 | return; | ||
| 108 | } | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Write the request into the BBP. | ||
| 112 | */ | ||
| 113 | reg = 0; | ||
| 114 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); | ||
| 115 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | ||
| 116 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); | ||
| 117 | |||
| 118 | rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); | ||
| 119 | |||
| 120 | /* | ||
| 121 | * Wait until the BBP becomes ready. | ||
| 122 | */ | ||
| 123 | reg = rt61pci_bbp_check(rt2x00dev); | ||
| 124 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | ||
| 125 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | ||
| 126 | *value = 0xff; | ||
| 127 | return; | ||
| 128 | } | ||
| 129 | |||
| 130 | *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); | ||
| 131 | } | ||
| 132 | |||
| 133 | static void rt61pci_rf_write(const struct rt2x00_dev *rt2x00dev, | ||
| 134 | const unsigned int word, const u32 value) | ||
| 135 | { | ||
| 136 | u32 reg; | ||
| 137 | unsigned int i; | ||
| 138 | |||
| 139 | if (!word) | ||
| 140 | return; | ||
| 141 | |||
| 142 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 143 | rt2x00pci_register_read(rt2x00dev, PHY_CSR4, ®); | ||
| 144 | if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY)) | ||
| 145 | goto rf_write; | ||
| 146 | udelay(REGISTER_BUSY_DELAY); | ||
| 147 | } | ||
| 148 | |||
| 149 | ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n"); | ||
| 150 | return; | ||
| 151 | |||
| 152 | rf_write: | ||
| 153 | reg = 0; | ||
| 154 | rt2x00_set_field32(®, PHY_CSR4_VALUE, value); | ||
| 155 | rt2x00_set_field32(®, PHY_CSR4_NUMBER_OF_BITS, 21); | ||
| 156 | rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); | ||
| 157 | rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); | ||
| 158 | |||
| 159 | rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg); | ||
| 160 | rt2x00_rf_write(rt2x00dev, word, value); | ||
| 161 | } | ||
| 162 | |||
| 163 | static void rt61pci_mcu_request(const struct rt2x00_dev *rt2x00dev, | ||
| 164 | const u8 command, const u8 token, | ||
| 165 | const u8 arg0, const u8 arg1) | ||
| 166 | { | ||
| 167 | u32 reg; | ||
| 168 | |||
| 169 | rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CSR, ®); | ||
| 170 | |||
| 171 | if (rt2x00_get_field32(reg, H2M_MAILBOX_CSR_OWNER)) { | ||
| 172 | ERROR(rt2x00dev, "mcu request error. " | ||
| 173 | "Request 0x%02x failed for token 0x%02x.\n", | ||
| 174 | command, token); | ||
| 175 | return; | ||
| 176 | } | ||
| 177 | |||
| 178 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_OWNER, 1); | ||
| 179 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); | ||
| 180 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0); | ||
| 181 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG1, arg1); | ||
| 182 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, reg); | ||
| 183 | |||
| 184 | rt2x00pci_register_read(rt2x00dev, HOST_CMD_CSR, ®); | ||
| 185 | rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); | ||
| 186 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); | ||
| 187 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); | ||
| 188 | } | ||
| 189 | |||
| 190 | static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | ||
| 191 | { | ||
| 192 | struct rt2x00_dev *rt2x00dev = eeprom->data; | ||
| 193 | u32 reg; | ||
| 194 | |||
| 195 | rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); | ||
| 196 | |||
| 197 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN); | ||
| 198 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT); | ||
| 199 | eeprom->reg_data_clock = | ||
| 200 | !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_CLOCK); | ||
| 201 | eeprom->reg_chip_select = | ||
| 202 | !!rt2x00_get_field32(reg, E2PROM_CSR_CHIP_SELECT); | ||
| 203 | } | ||
| 204 | |||
| 205 | static void rt61pci_eepromregister_write(struct eeprom_93cx6 *eeprom) | ||
| 206 | { | ||
| 207 | struct rt2x00_dev *rt2x00dev = eeprom->data; | ||
| 208 | u32 reg = 0; | ||
| 209 | |||
| 210 | rt2x00_set_field32(®, E2PROM_CSR_DATA_IN, !!eeprom->reg_data_in); | ||
| 211 | rt2x00_set_field32(®, E2PROM_CSR_DATA_OUT, !!eeprom->reg_data_out); | ||
| 212 | rt2x00_set_field32(®, E2PROM_CSR_DATA_CLOCK, | ||
| 213 | !!eeprom->reg_data_clock); | ||
| 214 | rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT, | ||
| 215 | !!eeprom->reg_chip_select); | ||
| 216 | |||
| 217 | rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg); | ||
| 218 | } | ||
| 219 | |||
| 220 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
| 221 | #define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) ) | ||
| 222 | |||
| 223 | static void rt61pci_read_csr(const struct rt2x00_dev *rt2x00dev, | ||
| 224 | const unsigned int word, u32 *data) | ||
| 225 | { | ||
| 226 | rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data); | ||
| 227 | } | ||
| 228 | |||
| 229 | static void rt61pci_write_csr(const struct rt2x00_dev *rt2x00dev, | ||
| 230 | const unsigned int word, u32 data) | ||
| 231 | { | ||
| 232 | rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data); | ||
| 233 | } | ||
| 234 | |||
| 235 | static const struct rt2x00debug rt61pci_rt2x00debug = { | ||
| 236 | .owner = THIS_MODULE, | ||
| 237 | .csr = { | ||
| 238 | .read = rt61pci_read_csr, | ||
| 239 | .write = rt61pci_write_csr, | ||
| 240 | .word_size = sizeof(u32), | ||
| 241 | .word_count = CSR_REG_SIZE / sizeof(u32), | ||
| 242 | }, | ||
| 243 | .eeprom = { | ||
| 244 | .read = rt2x00_eeprom_read, | ||
| 245 | .write = rt2x00_eeprom_write, | ||
| 246 | .word_size = sizeof(u16), | ||
| 247 | .word_count = EEPROM_SIZE / sizeof(u16), | ||
| 248 | }, | ||
| 249 | .bbp = { | ||
| 250 | .read = rt61pci_bbp_read, | ||
| 251 | .write = rt61pci_bbp_write, | ||
| 252 | .word_size = sizeof(u8), | ||
| 253 | .word_count = BBP_SIZE / sizeof(u8), | ||
| 254 | }, | ||
| 255 | .rf = { | ||
| 256 | .read = rt2x00_rf_read, | ||
| 257 | .write = rt61pci_rf_write, | ||
| 258 | .word_size = sizeof(u32), | ||
| 259 | .word_count = RF_SIZE / sizeof(u32), | ||
| 260 | }, | ||
| 261 | }; | ||
| 262 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
| 263 | |||
| 264 | #ifdef CONFIG_RT61PCI_RFKILL | ||
| 265 | static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | ||
| 266 | { | ||
| 267 | u32 reg; | ||
| 268 | |||
| 269 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | ||
| 270 | return rt2x00_get_field32(reg, MAC_CSR13_BIT5);; | ||
| 271 | } | ||
| 272 | #endif /* CONFIG_RT2400PCI_RFKILL */ | ||
| 273 | |||
| 274 | /* | ||
| 275 | * Configuration handlers. | ||
| 276 | */ | ||
| 277 | static void rt61pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *addr) | ||
| 278 | { | ||
| 279 | __le32 reg[2]; | ||
| 280 | u32 tmp; | ||
| 281 | |||
| 282 | memset(®, 0, sizeof(reg)); | ||
| 283 | memcpy(®, addr, ETH_ALEN); | ||
| 284 | |||
| 285 | tmp = le32_to_cpu(reg[1]); | ||
| 286 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | ||
| 287 | reg[1] = cpu_to_le32(tmp); | ||
| 288 | |||
| 289 | /* | ||
| 290 | * The MAC address is passed to us as an array of bytes, | ||
| 291 | * that array is little endian, so no need for byte ordering. | ||
| 292 | */ | ||
| 293 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, ®, sizeof(reg)); | ||
| 294 | } | ||
| 295 | |||
| 296 | static void rt61pci_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) | ||
| 297 | { | ||
| 298 | __le32 reg[2]; | ||
| 299 | u32 tmp; | ||
| 300 | |||
| 301 | memset(®, 0, sizeof(reg)); | ||
| 302 | memcpy(®, bssid, ETH_ALEN); | ||
| 303 | |||
| 304 | tmp = le32_to_cpu(reg[1]); | ||
| 305 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | ||
| 306 | reg[1] = cpu_to_le32(tmp); | ||
| 307 | |||
| 308 | /* | ||
| 309 | * The BSSID is passed to us as an array of bytes, | ||
| 310 | * that array is little endian, so no need for byte ordering. | ||
| 311 | */ | ||
| 312 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, ®, sizeof(reg)); | ||
| 313 | } | ||
| 314 | |||
| 315 | static void rt61pci_config_packet_filter(struct rt2x00_dev *rt2x00dev, | ||
| 316 | const unsigned int filter) | ||
| 317 | { | ||
| 318 | int promisc = !!(filter & IFF_PROMISC); | ||
| 319 | int multicast = !!(filter & IFF_MULTICAST); | ||
| 320 | int broadcast = !!(filter & IFF_BROADCAST); | ||
| 321 | u32 reg; | ||
| 322 | |||
| 323 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
| 324 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, !promisc); | ||
| 325 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, !multicast); | ||
| 326 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BORADCAST, !broadcast); | ||
| 327 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
| 328 | } | ||
| 329 | |||
| 330 | static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type) | ||
| 331 | { | ||
| 332 | u32 reg; | ||
| 333 | |||
| 334 | /* | ||
| 335 | * Clear current synchronisation setup. | ||
| 336 | * For the Beacon base registers we only need to clear | ||
| 337 | * the first byte since that byte contains the VALID and OWNER | ||
| 338 | * bits which (when set to 0) will invalidate the entire beacon. | ||
| 339 | */ | ||
| 340 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
| 341 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
| 342 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
| 343 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
| 344 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
| 345 | |||
| 346 | /* | ||
| 347 | * Apply hardware packet filter. | ||
| 348 | */ | ||
| 349 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
| 350 | |||
| 351 | if (!is_monitor_present(&rt2x00dev->interface) && | ||
| 352 | (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_STA)) | ||
| 353 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, 1); | ||
| 354 | else | ||
| 355 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, 0); | ||
| 356 | |||
| 357 | /* | ||
| 358 | * If there is a non-monitor interface present | ||
| 359 | * the packet should be strict (even if a monitor interface is present!). | ||
| 360 | * When there is only 1 interface present which is in monitor mode | ||
| 361 | * we should start accepting _all_ frames. | ||
| 362 | */ | ||
| 363 | if (is_interface_present(&rt2x00dev->interface)) { | ||
| 364 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, 1); | ||
| 365 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, 1); | ||
| 366 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, 1); | ||
| 367 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | ||
| 368 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1); | ||
| 369 | } else if (is_monitor_present(&rt2x00dev->interface)) { | ||
| 370 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, 0); | ||
| 371 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, 0); | ||
| 372 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, 0); | ||
| 373 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 0); | ||
| 374 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 0); | ||
| 375 | } | ||
| 376 | |||
| 377 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
| 378 | |||
| 379 | /* | ||
| 380 | * Enable synchronisation. | ||
| 381 | */ | ||
| 382 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
| 383 | if (is_interface_present(&rt2x00dev->interface)) { | ||
| 384 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
| 385 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
| 386 | } | ||
| 387 | |||
| 388 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
| 389 | if (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_AP) | ||
| 390 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 2); | ||
| 391 | else if (type == IEEE80211_IF_TYPE_STA) | ||
| 392 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 1); | ||
| 393 | else if (is_monitor_present(&rt2x00dev->interface) && | ||
| 394 | !is_interface_present(&rt2x00dev->interface)) | ||
| 395 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 0); | ||
| 396 | |||
| 397 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
| 398 | } | ||
| 399 | |||
| 400 | static void rt61pci_config_rate(struct rt2x00_dev *rt2x00dev, const int rate) | ||
| 401 | { | ||
| 402 | struct ieee80211_conf *conf = &rt2x00dev->hw->conf; | ||
| 403 | u32 reg; | ||
| 404 | u32 value; | ||
| 405 | u32 preamble; | ||
| 406 | |||
| 407 | if (DEVICE_GET_RATE_FIELD(rate, PREAMBLE)) | ||
| 408 | preamble = SHORT_PREAMBLE; | ||
| 409 | else | ||
| 410 | preamble = PREAMBLE; | ||
| 411 | |||
| 412 | /* | ||
| 413 | * Extract the allowed ratemask from the device specific rate value, | ||
| 414 | * We need to set TXRX_CSR5 to the basic rate mask so we need to mask | ||
| 415 | * off the non-basic rates. | ||
| 416 | */ | ||
| 417 | reg = DEVICE_GET_RATE_FIELD(rate, RATEMASK) & DEV_BASIC_RATEMASK; | ||
| 418 | |||
| 419 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, reg); | ||
| 420 | |||
| 421 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
| 422 | value = ((conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) ? | ||
| 423 | SHORT_DIFS : DIFS) + | ||
| 424 | PLCP + preamble + get_duration(ACK_SIZE, 10); | ||
| 425 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, value); | ||
| 426 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
| 427 | |||
| 428 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); | ||
| 429 | if (preamble == SHORT_PREAMBLE) | ||
| 430 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, 1); | ||
| 431 | else | ||
| 432 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, 0); | ||
| 433 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | ||
| 434 | } | ||
| 435 | |||
| 436 | static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, | ||
| 437 | const int phymode) | ||
| 438 | { | ||
| 439 | struct ieee80211_hw_mode *mode; | ||
| 440 | struct ieee80211_rate *rate; | ||
| 441 | |||
| 442 | if (phymode == MODE_IEEE80211A) | ||
| 443 | rt2x00dev->curr_hwmode = HWMODE_A; | ||
| 444 | else if (phymode == MODE_IEEE80211B) | ||
| 445 | rt2x00dev->curr_hwmode = HWMODE_B; | ||
| 446 | else | ||
| 447 | rt2x00dev->curr_hwmode = HWMODE_G; | ||
| 448 | |||
| 449 | mode = &rt2x00dev->hwmodes[rt2x00dev->curr_hwmode]; | ||
| 450 | rate = &mode->rates[mode->num_rates - 1]; | ||
| 451 | |||
| 452 | rt61pci_config_rate(rt2x00dev, rate->val2); | ||
| 453 | } | ||
| 454 | |||
| 455 | static void rt61pci_config_lock_channel(struct rt2x00_dev *rt2x00dev, | ||
| 456 | struct rf_channel *rf, | ||
| 457 | const int txpower) | ||
| 458 | { | ||
| 459 | u8 r3; | ||
| 460 | u8 r94; | ||
| 461 | u8 smart; | ||
| 462 | |||
| 463 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower)); | ||
| 464 | rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset); | ||
| 465 | |||
| 466 | smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) || | ||
| 467 | rt2x00_rf(&rt2x00dev->chip, RF2527)); | ||
| 468 | |||
| 469 | rt61pci_bbp_read(rt2x00dev, 3, &r3); | ||
| 470 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart); | ||
| 471 | rt61pci_bbp_write(rt2x00dev, 3, r3); | ||
| 472 | |||
| 473 | r94 = 6; | ||
| 474 | if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94)) | ||
| 475 | r94 += txpower - MAX_TXPOWER; | ||
| 476 | else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94)) | ||
| 477 | r94 += txpower; | ||
| 478 | rt61pci_bbp_write(rt2x00dev, 94, r94); | ||
| 479 | |||
| 480 | rt61pci_rf_write(rt2x00dev, 1, rf->rf1); | ||
| 481 | rt61pci_rf_write(rt2x00dev, 2, rf->rf2); | ||
| 482 | rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004); | ||
| 483 | rt61pci_rf_write(rt2x00dev, 4, rf->rf4); | ||
| 484 | |||
| 485 | udelay(200); | ||
| 486 | |||
| 487 | rt61pci_rf_write(rt2x00dev, 1, rf->rf1); | ||
| 488 | rt61pci_rf_write(rt2x00dev, 2, rf->rf2); | ||
| 489 | rt61pci_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004); | ||
| 490 | rt61pci_rf_write(rt2x00dev, 4, rf->rf4); | ||
| 491 | |||
| 492 | udelay(200); | ||
| 493 | |||
| 494 | rt61pci_rf_write(rt2x00dev, 1, rf->rf1); | ||
| 495 | rt61pci_rf_write(rt2x00dev, 2, rf->rf2); | ||
| 496 | rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004); | ||
| 497 | rt61pci_rf_write(rt2x00dev, 4, rf->rf4); | ||
| 498 | |||
| 499 | msleep(1); | ||
| 500 | } | ||
| 501 | |||
| 502 | static void rt61pci_config_channel(struct rt2x00_dev *rt2x00dev, | ||
| 503 | const int index, const int channel, | ||
| 504 | const int txpower) | ||
| 505 | { | ||
| 506 | struct rf_channel rf; | ||
| 507 | |||
| 508 | /* | ||
| 509 | * Fill rf_reg structure. | ||
| 510 | */ | ||
| 511 | memcpy(&rf, &rt2x00dev->spec.channels[index], sizeof(rf)); | ||
| 512 | |||
| 513 | rt61pci_config_lock_channel(rt2x00dev, &rf, txpower); | ||
| 514 | } | ||
| 515 | |||
| 516 | static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev, | ||
| 517 | const int txpower) | ||
| 518 | { | ||
| 519 | struct rf_channel rf; | ||
| 520 | |||
| 521 | rt2x00_rf_read(rt2x00dev, 1, &rf.rf1); | ||
| 522 | rt2x00_rf_read(rt2x00dev, 2, &rf.rf2); | ||
| 523 | rt2x00_rf_read(rt2x00dev, 3, &rf.rf3); | ||
| 524 | rt2x00_rf_read(rt2x00dev, 4, &rf.rf4); | ||
| 525 | |||
| 526 | rt61pci_config_lock_channel(rt2x00dev, &rf, txpower); | ||
| 527 | } | ||
| 528 | |||
| 529 | static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | ||
| 530 | const int antenna_tx, | ||
| 531 | const int antenna_rx) | ||
| 532 | { | ||
| 533 | u8 r3; | ||
| 534 | u8 r4; | ||
| 535 | u8 r77; | ||
| 536 | |||
| 537 | rt61pci_bbp_read(rt2x00dev, 3, &r3); | ||
| 538 | rt61pci_bbp_read(rt2x00dev, 4, &r4); | ||
| 539 | rt61pci_bbp_read(rt2x00dev, 77, &r77); | ||
| 540 | |||
| 541 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, | ||
| 542 | !rt2x00_rf(&rt2x00dev->chip, RF5225)); | ||
| 543 | |||
| 544 | switch (antenna_rx) { | ||
| 545 | case ANTENNA_SW_DIVERSITY: | ||
| 546 | case ANTENNA_HW_DIVERSITY: | ||
| 547 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | ||
| 548 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | ||
| 549 | !!(rt2x00dev->curr_hwmode != HWMODE_A)); | ||
| 550 | break; | ||
| 551 | case ANTENNA_A: | ||
| 552 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
| 553 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | ||
| 554 | |||
| 555 | if (rt2x00dev->curr_hwmode == HWMODE_A) | ||
| 556 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); | ||
| 557 | else | ||
| 558 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
| 559 | break; | ||
| 560 | case ANTENNA_B: | ||
| 561 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
| 562 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | ||
| 563 | |||
| 564 | if (rt2x00dev->curr_hwmode == HWMODE_A) | ||
| 565 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
| 566 | else | ||
| 567 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); | ||
| 568 | break; | ||
| 569 | } | ||
| 570 | |||
| 571 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
| 572 | rt61pci_bbp_write(rt2x00dev, 3, r3); | ||
| 573 | rt61pci_bbp_write(rt2x00dev, 4, r4); | ||
| 574 | } | ||
| 575 | |||
| 576 | static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev, | ||
| 577 | const int antenna_tx, | ||
| 578 | const int antenna_rx) | ||
| 579 | { | ||
| 580 | u8 r3; | ||
| 581 | u8 r4; | ||
| 582 | u8 r77; | ||
| 583 | |||
| 584 | rt61pci_bbp_read(rt2x00dev, 3, &r3); | ||
| 585 | rt61pci_bbp_read(rt2x00dev, 4, &r4); | ||
| 586 | rt61pci_bbp_read(rt2x00dev, 77, &r77); | ||
| 587 | |||
| 588 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, | ||
| 589 | !rt2x00_rf(&rt2x00dev->chip, RF2527)); | ||
| 590 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | ||
| 591 | !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); | ||
| 592 | |||
| 593 | switch (antenna_rx) { | ||
| 594 | case ANTENNA_SW_DIVERSITY: | ||
| 595 | case ANTENNA_HW_DIVERSITY: | ||
| 596 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | ||
| 597 | break; | ||
| 598 | case ANTENNA_A: | ||
| 599 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
| 600 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
| 601 | break; | ||
| 602 | case ANTENNA_B: | ||
| 603 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
| 604 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); | ||
| 605 | break; | ||
| 606 | } | ||
| 607 | |||
| 608 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
| 609 | rt61pci_bbp_write(rt2x00dev, 3, r3); | ||
| 610 | rt61pci_bbp_write(rt2x00dev, 4, r4); | ||
| 611 | } | ||
| 612 | |||
| 613 | static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev, | ||
| 614 | const int p1, const int p2) | ||
| 615 | { | ||
| 616 | u32 reg; | ||
| 617 | |||
| 618 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | ||
| 619 | |||
| 620 | if (p1 != 0xff) { | ||
| 621 | rt2x00_set_field32(®, MAC_CSR13_BIT4, !!p1); | ||
| 622 | rt2x00_set_field32(®, MAC_CSR13_BIT12, 0); | ||
| 623 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); | ||
| 624 | } | ||
| 625 | if (p2 != 0xff) { | ||
| 626 | rt2x00_set_field32(®, MAC_CSR13_BIT3, !p2); | ||
| 627 | rt2x00_set_field32(®, MAC_CSR13_BIT11, 0); | ||
| 628 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); | ||
| 629 | } | ||
| 630 | } | ||
| 631 | |||
| 632 | static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, | ||
| 633 | const int antenna_tx, | ||
| 634 | const int antenna_rx) | ||
| 635 | { | ||
| 636 | u16 eeprom; | ||
| 637 | u8 r3; | ||
| 638 | u8 r4; | ||
| 639 | u8 r77; | ||
| 640 | |||
| 641 | rt61pci_bbp_read(rt2x00dev, 3, &r3); | ||
| 642 | rt61pci_bbp_read(rt2x00dev, 4, &r4); | ||
| 643 | rt61pci_bbp_read(rt2x00dev, 77, &r77); | ||
| 644 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | ||
| 645 | |||
| 646 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0); | ||
| 647 | |||
| 648 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) && | ||
| 649 | rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) { | ||
| 650 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | ||
| 651 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 1); | ||
| 652 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1); | ||
| 653 | } else if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY)) { | ||
| 654 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED) >= 2) { | ||
| 655 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
| 656 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
| 657 | } | ||
| 658 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
| 659 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); | ||
| 660 | } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) && | ||
| 661 | rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) { | ||
| 662 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | ||
| 663 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | ||
| 664 | |||
| 665 | switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) { | ||
| 666 | case 0: | ||
| 667 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1); | ||
| 668 | break; | ||
| 669 | case 1: | ||
| 670 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0); | ||
| 671 | break; | ||
| 672 | case 2: | ||
| 673 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); | ||
| 674 | break; | ||
| 675 | case 3: | ||
| 676 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); | ||
| 677 | break; | ||
| 678 | } | ||
| 679 | } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) && | ||
| 680 | !rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) { | ||
| 681 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
| 682 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | ||
| 683 | |||
| 684 | switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) { | ||
| 685 | case 0: | ||
| 686 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); | ||
| 687 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
| 688 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1); | ||
| 689 | break; | ||
| 690 | case 1: | ||
| 691 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); | ||
| 692 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
| 693 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0); | ||
| 694 | break; | ||
| 695 | case 2: | ||
| 696 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
| 697 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
| 698 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); | ||
| 699 | break; | ||
| 700 | case 3: | ||
| 701 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
| 702 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
| 703 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); | ||
| 704 | break; | ||
| 705 | } | ||
| 706 | } | ||
| 707 | |||
| 708 | rt61pci_bbp_write(rt2x00dev, 3, r3); | ||
| 709 | rt61pci_bbp_write(rt2x00dev, 4, r4); | ||
| 710 | } | ||
| 711 | |||
| 712 | struct antenna_sel { | ||
| 713 | u8 word; | ||
| 714 | /* | ||
| 715 | * value[0] -> non-LNA | ||
| 716 | * value[1] -> LNA | ||
| 717 | */ | ||
| 718 | u8 value[2]; | ||
| 719 | }; | ||
| 720 | |||
| 721 | static const struct antenna_sel antenna_sel_a[] = { | ||
| 722 | { 96, { 0x58, 0x78 } }, | ||
| 723 | { 104, { 0x38, 0x48 } }, | ||
| 724 | { 75, { 0xfe, 0x80 } }, | ||
| 725 | { 86, { 0xfe, 0x80 } }, | ||
| 726 | { 88, { 0xfe, 0x80 } }, | ||
| 727 | { 35, { 0x60, 0x60 } }, | ||
| 728 | { 97, { 0x58, 0x58 } }, | ||
| 729 | { 98, { 0x58, 0x58 } }, | ||
| 730 | }; | ||
| 731 | |||
| 732 | static const struct antenna_sel antenna_sel_bg[] = { | ||
| 733 | { 96, { 0x48, 0x68 } }, | ||
| 734 | { 104, { 0x2c, 0x3c } }, | ||
| 735 | { 75, { 0xfe, 0x80 } }, | ||
| 736 | { 86, { 0xfe, 0x80 } }, | ||
| 737 | { 88, { 0xfe, 0x80 } }, | ||
| 738 | { 35, { 0x50, 0x50 } }, | ||
| 739 | { 97, { 0x48, 0x48 } }, | ||
| 740 | { 98, { 0x48, 0x48 } }, | ||
| 741 | }; | ||
| 742 | |||
| 743 | static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, | ||
| 744 | const int antenna_tx, const int antenna_rx) | ||
| 745 | { | ||
| 746 | const struct antenna_sel *sel; | ||
| 747 | unsigned int lna; | ||
| 748 | unsigned int i; | ||
| 749 | u32 reg; | ||
| 750 | |||
| 751 | rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); | ||
| 752 | |||
| 753 | if (rt2x00dev->curr_hwmode == HWMODE_A) { | ||
| 754 | sel = antenna_sel_a; | ||
| 755 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | ||
| 756 | |||
| 757 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 0); | ||
| 758 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 1); | ||
| 759 | } else { | ||
| 760 | sel = antenna_sel_bg; | ||
| 761 | lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | ||
| 762 | |||
| 763 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 1); | ||
| 764 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 0); | ||
| 765 | } | ||
| 766 | |||
| 767 | for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) | ||
| 768 | rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]); | ||
| 769 | |||
| 770 | rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); | ||
| 771 | |||
| 772 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | ||
| 773 | rt2x00_rf(&rt2x00dev->chip, RF5325)) | ||
| 774 | rt61pci_config_antenna_5x(rt2x00dev, antenna_tx, antenna_rx); | ||
| 775 | else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) | ||
| 776 | rt61pci_config_antenna_2x(rt2x00dev, antenna_tx, antenna_rx); | ||
| 777 | else if (rt2x00_rf(&rt2x00dev->chip, RF2529)) { | ||
| 778 | if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) | ||
| 779 | rt61pci_config_antenna_2x(rt2x00dev, antenna_tx, | ||
| 780 | antenna_rx); | ||
| 781 | else | ||
| 782 | rt61pci_config_antenna_2529(rt2x00dev, antenna_tx, | ||
| 783 | antenna_rx); | ||
| 784 | } | ||
| 785 | } | ||
| 786 | |||
| 787 | static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev, | ||
| 788 | const int short_slot_time, | ||
| 789 | const int beacon_int) | ||
| 790 | { | ||
| 791 | u32 reg; | ||
| 792 | |||
| 793 | rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); | ||
| 794 | rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, | ||
| 795 | short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME); | ||
| 796 | rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); | ||
| 797 | |||
| 798 | rt2x00pci_register_read(rt2x00dev, MAC_CSR8, ®); | ||
| 799 | rt2x00_set_field32(®, MAC_CSR8_SIFS, SIFS); | ||
| 800 | rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); | ||
| 801 | rt2x00_set_field32(®, MAC_CSR8_EIFS, EIFS); | ||
| 802 | rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg); | ||
| 803 | |||
| 804 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
| 805 | rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); | ||
| 806 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
| 807 | |||
| 808 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); | ||
| 809 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); | ||
| 810 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | ||
| 811 | |||
| 812 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
| 813 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, beacon_int * 16); | ||
| 814 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
| 815 | } | ||
| 816 | |||
| 817 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | ||
| 818 | const unsigned int flags, | ||
| 819 | struct ieee80211_conf *conf) | ||
| 820 | { | ||
| 821 | int short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME; | ||
| 822 | |||
| 823 | if (flags & CONFIG_UPDATE_PHYMODE) | ||
| 824 | rt61pci_config_phymode(rt2x00dev, conf->phymode); | ||
| 825 | if (flags & CONFIG_UPDATE_CHANNEL) | ||
| 826 | rt61pci_config_channel(rt2x00dev, conf->channel_val, | ||
| 827 | conf->channel, conf->power_level); | ||
| 828 | if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL)) | ||
| 829 | rt61pci_config_txpower(rt2x00dev, conf->power_level); | ||
| 830 | if (flags & CONFIG_UPDATE_ANTENNA) | ||
| 831 | rt61pci_config_antenna(rt2x00dev, conf->antenna_sel_tx, | ||
| 832 | conf->antenna_sel_rx); | ||
| 833 | if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) | ||
| 834 | rt61pci_config_duration(rt2x00dev, short_slot_time, | ||
| 835 | conf->beacon_int); | ||
| 836 | } | ||
| 837 | |||
| 838 | /* | ||
| 839 | * LED functions. | ||
| 840 | */ | ||
| 841 | static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
| 842 | { | ||
| 843 | u32 reg; | ||
| 844 | u16 led_reg; | ||
| 845 | u8 arg0; | ||
| 846 | u8 arg1; | ||
| 847 | |||
| 848 | rt2x00pci_register_read(rt2x00dev, MAC_CSR14, ®); | ||
| 849 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
| 850 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
| 851 | rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg); | ||
| 852 | |||
| 853 | led_reg = rt2x00dev->led_reg; | ||
| 854 | rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 1); | ||
| 855 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) | ||
| 856 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 1); | ||
| 857 | else | ||
| 858 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 1); | ||
| 859 | |||
| 860 | arg0 = led_reg & 0xff; | ||
| 861 | arg1 = (led_reg >> 8) & 0xff; | ||
| 862 | |||
| 863 | rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1); | ||
| 864 | } | ||
| 865 | |||
| 866 | static void rt61pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
| 867 | { | ||
| 868 | u16 led_reg; | ||
| 869 | u8 arg0; | ||
| 870 | u8 arg1; | ||
| 871 | |||
| 872 | led_reg = rt2x00dev->led_reg; | ||
| 873 | rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 0); | ||
| 874 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 0); | ||
| 875 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 0); | ||
| 876 | |||
| 877 | arg0 = led_reg & 0xff; | ||
| 878 | arg1 = (led_reg >> 8) & 0xff; | ||
| 879 | |||
| 880 | rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1); | ||
| 881 | } | ||
| 882 | |||
| 883 | static void rt61pci_activity_led(struct rt2x00_dev *rt2x00dev, int rssi) | ||
| 884 | { | ||
| 885 | u8 led; | ||
| 886 | |||
| 887 | if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH) | ||
| 888 | return; | ||
| 889 | |||
| 890 | /* | ||
| 891 | * Led handling requires a positive value for the rssi, | ||
| 892 | * to do that correctly we need to add the correction. | ||
| 893 | */ | ||
| 894 | rssi += rt2x00dev->rssi_offset; | ||
| 895 | |||
| 896 | if (rssi <= 30) | ||
| 897 | led = 0; | ||
| 898 | else if (rssi <= 39) | ||
| 899 | led = 1; | ||
| 900 | else if (rssi <= 49) | ||
| 901 | led = 2; | ||
| 902 | else if (rssi <= 53) | ||
| 903 | led = 3; | ||
| 904 | else if (rssi <= 63) | ||
| 905 | led = 4; | ||
| 906 | else | ||
| 907 | led = 5; | ||
| 908 | |||
| 909 | rt61pci_mcu_request(rt2x00dev, MCU_LED_STRENGTH, 0xff, led, 0); | ||
| 910 | } | ||
| 911 | |||
| 912 | /* | ||
| 913 | * Link tuning | ||
| 914 | */ | ||
| 915 | static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev) | ||
| 916 | { | ||
| 917 | u32 reg; | ||
| 918 | |||
| 919 | /* | ||
| 920 | * Update FCS error count from register. | ||
| 921 | */ | ||
| 922 | rt2x00pci_register_read(rt2x00dev, STA_CSR0, ®); | ||
| 923 | rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR); | ||
| 924 | |||
| 925 | /* | ||
| 926 | * Update False CCA count from register. | ||
| 927 | */ | ||
| 928 | rt2x00pci_register_read(rt2x00dev, STA_CSR1, ®); | ||
| 929 | rt2x00dev->link.false_cca = | ||
| 930 | rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); | ||
| 931 | } | ||
| 932 | |||
| 933 | static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev) | ||
| 934 | { | ||
| 935 | rt61pci_bbp_write(rt2x00dev, 17, 0x20); | ||
| 936 | rt2x00dev->link.vgc_level = 0x20; | ||
| 937 | } | ||
| 938 | |||
| 939 | static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | ||
| 940 | { | ||
| 941 | int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); | ||
| 942 | u8 r17; | ||
| 943 | u8 up_bound; | ||
| 944 | u8 low_bound; | ||
| 945 | |||
| 946 | /* | ||
| 947 | * Update Led strength | ||
| 948 | */ | ||
| 949 | rt61pci_activity_led(rt2x00dev, rssi); | ||
| 950 | |||
| 951 | rt61pci_bbp_read(rt2x00dev, 17, &r17); | ||
| 952 | |||
| 953 | /* | ||
| 954 | * Determine r17 bounds. | ||
| 955 | */ | ||
| 956 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | ||
| 957 | low_bound = 0x28; | ||
| 958 | up_bound = 0x48; | ||
| 959 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | ||
| 960 | low_bound += 0x10; | ||
| 961 | up_bound += 0x10; | ||
| 962 | } | ||
| 963 | } else { | ||
| 964 | low_bound = 0x20; | ||
| 965 | up_bound = 0x40; | ||
| 966 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { | ||
| 967 | low_bound += 0x10; | ||
| 968 | up_bound += 0x10; | ||
| 969 | } | ||
| 970 | } | ||
| 971 | |||
| 972 | /* | ||
| 973 | * Special big-R17 for very short distance | ||
| 974 | */ | ||
| 975 | if (rssi >= -35) { | ||
| 976 | if (r17 != 0x60) | ||
| 977 | rt61pci_bbp_write(rt2x00dev, 17, 0x60); | ||
| 978 | return; | ||
| 979 | } | ||
| 980 | |||
| 981 | /* | ||
| 982 | * Special big-R17 for short distance | ||
| 983 | */ | ||
| 984 | if (rssi >= -58) { | ||
| 985 | if (r17 != up_bound) | ||
| 986 | rt61pci_bbp_write(rt2x00dev, 17, up_bound); | ||
| 987 | return; | ||
| 988 | } | ||
| 989 | |||
| 990 | /* | ||
| 991 | * Special big-R17 for middle-short distance | ||
| 992 | */ | ||
| 993 | if (rssi >= -66) { | ||
| 994 | low_bound += 0x10; | ||
| 995 | if (r17 != low_bound) | ||
| 996 | rt61pci_bbp_write(rt2x00dev, 17, low_bound); | ||
| 997 | return; | ||
| 998 | } | ||
| 999 | |||
| 1000 | /* | ||
| 1001 | * Special mid-R17 for middle distance | ||
| 1002 | */ | ||
| 1003 | if (rssi >= -74) { | ||
| 1004 | low_bound += 0x08; | ||
| 1005 | if (r17 != low_bound) | ||
| 1006 | rt61pci_bbp_write(rt2x00dev, 17, low_bound); | ||
| 1007 | return; | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | /* | ||
| 1011 | * Special case: Change up_bound based on the rssi. | ||
| 1012 | * Lower up_bound when rssi is weaker then -74 dBm. | ||
| 1013 | */ | ||
| 1014 | up_bound -= 2 * (-74 - rssi); | ||
| 1015 | if (low_bound > up_bound) | ||
| 1016 | up_bound = low_bound; | ||
| 1017 | |||
| 1018 | if (r17 > up_bound) { | ||
| 1019 | rt61pci_bbp_write(rt2x00dev, 17, up_bound); | ||
| 1020 | return; | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | /* | ||
| 1024 | * r17 does not yet exceed upper limit, continue and base | ||
| 1025 | * the r17 tuning on the false CCA count. | ||
| 1026 | */ | ||
| 1027 | if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) { | ||
| 1028 | if (++r17 > up_bound) | ||
| 1029 | r17 = up_bound; | ||
| 1030 | rt61pci_bbp_write(rt2x00dev, 17, r17); | ||
| 1031 | } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) { | ||
| 1032 | if (--r17 < low_bound) | ||
| 1033 | r17 = low_bound; | ||
| 1034 | rt61pci_bbp_write(rt2x00dev, 17, r17); | ||
| 1035 | } | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | /* | ||
| 1039 | * Firmware name function. | ||
| 1040 | */ | ||
| 1041 | static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) | ||
| 1042 | { | ||
| 1043 | char *fw_name; | ||
| 1044 | |||
| 1045 | switch (rt2x00dev->chip.rt) { | ||
| 1046 | case RT2561: | ||
| 1047 | fw_name = FIRMWARE_RT2561; | ||
| 1048 | break; | ||
| 1049 | case RT2561s: | ||
| 1050 | fw_name = FIRMWARE_RT2561s; | ||
| 1051 | break; | ||
| 1052 | case RT2661: | ||
| 1053 | fw_name = FIRMWARE_RT2661; | ||
| 1054 | break; | ||
| 1055 | default: | ||
| 1056 | fw_name = NULL; | ||
| 1057 | break; | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | return fw_name; | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | /* | ||
| 1064 | * Initialization functions. | ||
| 1065 | */ | ||
| 1066 | static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | ||
| 1067 | const size_t len) | ||
| 1068 | { | ||
| 1069 | int i; | ||
| 1070 | u32 reg; | ||
| 1071 | |||
| 1072 | /* | ||
| 1073 | * Wait for stable hardware. | ||
| 1074 | */ | ||
| 1075 | for (i = 0; i < 100; i++) { | ||
| 1076 | rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); | ||
| 1077 | if (reg) | ||
| 1078 | break; | ||
| 1079 | msleep(1); | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | if (!reg) { | ||
| 1083 | ERROR(rt2x00dev, "Unstable hardware.\n"); | ||
| 1084 | return -EBUSY; | ||
| 1085 | } | ||
| 1086 | |||
| 1087 | /* | ||
| 1088 | * Prepare MCU and mailbox for firmware loading. | ||
| 1089 | */ | ||
| 1090 | reg = 0; | ||
| 1091 | rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 1); | ||
| 1092 | rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); | ||
| 1093 | rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); | ||
| 1094 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); | ||
| 1095 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, 0); | ||
| 1096 | |||
| 1097 | /* | ||
| 1098 | * Write firmware to device. | ||
| 1099 | */ | ||
| 1100 | reg = 0; | ||
| 1101 | rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 1); | ||
| 1102 | rt2x00_set_field32(®, MCU_CNTL_CSR_SELECT_BANK, 1); | ||
| 1103 | rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); | ||
| 1104 | |||
| 1105 | rt2x00pci_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, | ||
| 1106 | data, len); | ||
| 1107 | |||
| 1108 | rt2x00_set_field32(®, MCU_CNTL_CSR_SELECT_BANK, 0); | ||
| 1109 | rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); | ||
| 1110 | |||
| 1111 | rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 0); | ||
| 1112 | rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); | ||
| 1113 | |||
| 1114 | for (i = 0; i < 100; i++) { | ||
| 1115 | rt2x00pci_register_read(rt2x00dev, MCU_CNTL_CSR, ®); | ||
| 1116 | if (rt2x00_get_field32(reg, MCU_CNTL_CSR_READY)) | ||
| 1117 | break; | ||
| 1118 | msleep(1); | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | if (i == 100) { | ||
| 1122 | ERROR(rt2x00dev, "MCU Control register not ready.\n"); | ||
| 1123 | return -EBUSY; | ||
| 1124 | } | ||
| 1125 | |||
| 1126 | /* | ||
| 1127 | * Reset MAC and BBP registers. | ||
| 1128 | */ | ||
| 1129 | reg = 0; | ||
| 1130 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 1); | ||
| 1131 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 1); | ||
| 1132 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | ||
| 1133 | |||
| 1134 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | ||
| 1135 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 0); | ||
| 1136 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 0); | ||
| 1137 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | ||
| 1138 | |||
| 1139 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | ||
| 1140 | rt2x00_set_field32(®, MAC_CSR1_HOST_READY, 1); | ||
| 1141 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | ||
| 1142 | |||
| 1143 | return 0; | ||
| 1144 | } | ||
| 1145 | |||
| 1146 | static void rt61pci_init_rxring(struct rt2x00_dev *rt2x00dev) | ||
| 1147 | { | ||
| 1148 | struct data_ring *ring = rt2x00dev->rx; | ||
| 1149 | struct data_desc *rxd; | ||
| 1150 | unsigned int i; | ||
| 1151 | u32 word; | ||
| 1152 | |||
| 1153 | memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring)); | ||
| 1154 | |||
| 1155 | for (i = 0; i < ring->stats.limit; i++) { | ||
| 1156 | rxd = ring->entry[i].priv; | ||
| 1157 | |||
| 1158 | rt2x00_desc_read(rxd, 5, &word); | ||
| 1159 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, | ||
| 1160 | ring->entry[i].data_dma); | ||
| 1161 | rt2x00_desc_write(rxd, 5, word); | ||
| 1162 | |||
| 1163 | rt2x00_desc_read(rxd, 0, &word); | ||
| 1164 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | ||
| 1165 | rt2x00_desc_write(rxd, 0, word); | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | rt2x00_ring_index_clear(rt2x00dev->rx); | ||
| 1169 | } | ||
| 1170 | |||
| 1171 | static void rt61pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue) | ||
| 1172 | { | ||
| 1173 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | ||
| 1174 | struct data_desc *txd; | ||
| 1175 | unsigned int i; | ||
| 1176 | u32 word; | ||
| 1177 | |||
| 1178 | memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring)); | ||
| 1179 | |||
| 1180 | for (i = 0; i < ring->stats.limit; i++) { | ||
| 1181 | txd = ring->entry[i].priv; | ||
| 1182 | |||
| 1183 | rt2x00_desc_read(txd, 1, &word); | ||
| 1184 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); | ||
| 1185 | rt2x00_desc_write(txd, 1, word); | ||
| 1186 | |||
| 1187 | rt2x00_desc_read(txd, 5, &word); | ||
| 1188 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, queue); | ||
| 1189 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, i); | ||
| 1190 | rt2x00_desc_write(txd, 5, word); | ||
| 1191 | |||
| 1192 | rt2x00_desc_read(txd, 6, &word); | ||
| 1193 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, | ||
| 1194 | ring->entry[i].data_dma); | ||
| 1195 | rt2x00_desc_write(txd, 6, word); | ||
| 1196 | |||
| 1197 | rt2x00_desc_read(txd, 0, &word); | ||
| 1198 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | ||
| 1199 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | ||
| 1200 | rt2x00_desc_write(txd, 0, word); | ||
| 1201 | } | ||
| 1202 | |||
| 1203 | rt2x00_ring_index_clear(ring); | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | ||
| 1207 | { | ||
| 1208 | u32 reg; | ||
| 1209 | |||
| 1210 | /* | ||
| 1211 | * Initialize rings. | ||
| 1212 | */ | ||
| 1213 | rt61pci_init_rxring(rt2x00dev); | ||
| 1214 | rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0); | ||
| 1215 | rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA1); | ||
| 1216 | rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA2); | ||
| 1217 | rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA3); | ||
| 1218 | rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA4); | ||
| 1219 | |||
| 1220 | /* | ||
| 1221 | * Initialize registers. | ||
| 1222 | */ | ||
| 1223 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR0, ®); | ||
| 1224 | rt2x00_set_field32(®, TX_RING_CSR0_AC0_RING_SIZE, | ||
| 1225 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | ||
| 1226 | rt2x00_set_field32(®, TX_RING_CSR0_AC1_RING_SIZE, | ||
| 1227 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | ||
| 1228 | rt2x00_set_field32(®, TX_RING_CSR0_AC2_RING_SIZE, | ||
| 1229 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA2].stats.limit); | ||
| 1230 | rt2x00_set_field32(®, TX_RING_CSR0_AC3_RING_SIZE, | ||
| 1231 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA3].stats.limit); | ||
| 1232 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR0, reg); | ||
| 1233 | |||
| 1234 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR1, ®); | ||
| 1235 | rt2x00_set_field32(®, TX_RING_CSR1_MGMT_RING_SIZE, | ||
| 1236 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA4].stats.limit); | ||
| 1237 | rt2x00_set_field32(®, TX_RING_CSR1_TXD_SIZE, | ||
| 1238 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size / | ||
| 1239 | 4); | ||
| 1240 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); | ||
| 1241 | |||
| 1242 | rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); | ||
| 1243 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, | ||
| 1244 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | ||
| 1245 | rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); | ||
| 1246 | |||
| 1247 | rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); | ||
| 1248 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, | ||
| 1249 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | ||
| 1250 | rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); | ||
| 1251 | |||
| 1252 | rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); | ||
| 1253 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, | ||
| 1254 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA2].data_dma); | ||
| 1255 | rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); | ||
| 1256 | |||
| 1257 | rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); | ||
| 1258 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, | ||
| 1259 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA3].data_dma); | ||
| 1260 | rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); | ||
| 1261 | |||
| 1262 | rt2x00pci_register_read(rt2x00dev, MGMT_BASE_CSR, ®); | ||
| 1263 | rt2x00_set_field32(®, MGMT_BASE_CSR_RING_REGISTER, | ||
| 1264 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA4].data_dma); | ||
| 1265 | rt2x00pci_register_write(rt2x00dev, MGMT_BASE_CSR, reg); | ||
| 1266 | |||
| 1267 | rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®); | ||
| 1268 | rt2x00_set_field32(®, RX_RING_CSR_RING_SIZE, | ||
| 1269 | rt2x00dev->rx->stats.limit); | ||
| 1270 | rt2x00_set_field32(®, RX_RING_CSR_RXD_SIZE, | ||
| 1271 | rt2x00dev->rx->desc_size / 4); | ||
| 1272 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); | ||
| 1273 | rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); | ||
| 1274 | |||
| 1275 | rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); | ||
| 1276 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, | ||
| 1277 | rt2x00dev->rx->data_dma); | ||
| 1278 | rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); | ||
| 1279 | |||
| 1280 | rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); | ||
| 1281 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC0, 2); | ||
| 1282 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC1, 2); | ||
| 1283 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC2, 2); | ||
| 1284 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC3, 2); | ||
| 1285 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_MGMT, 0); | ||
| 1286 | rt2x00pci_register_write(rt2x00dev, TX_DMA_DST_CSR, reg); | ||
| 1287 | |||
| 1288 | rt2x00pci_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); | ||
| 1289 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC0, 1); | ||
| 1290 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1); | ||
| 1291 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1); | ||
| 1292 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC3, 1); | ||
| 1293 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_MGMT, 1); | ||
| 1294 | rt2x00pci_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg); | ||
| 1295 | |||
| 1296 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); | ||
| 1297 | rt2x00_set_field32(®, RX_CNTL_CSR_LOAD_RXD, 1); | ||
| 1298 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); | ||
| 1299 | |||
| 1300 | return 0; | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | ||
| 1304 | { | ||
| 1305 | u32 reg; | ||
| 1306 | |||
| 1307 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
| 1308 | rt2x00_set_field32(®, TXRX_CSR0_AUTO_TX_SEQ, 1); | ||
| 1309 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0); | ||
| 1310 | rt2x00_set_field32(®, TXRX_CSR0_TX_WITHOUT_WAITING, 0); | ||
| 1311 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
| 1312 | |||
| 1313 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR1, ®); | ||
| 1314 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0, 47); /* CCK Signal */ | ||
| 1315 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0_VALID, 1); | ||
| 1316 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID1, 30); /* Rssi */ | ||
| 1317 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID1_VALID, 1); | ||
| 1318 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID2, 42); /* OFDM Rate */ | ||
| 1319 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID2_VALID, 1); | ||
| 1320 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3, 30); /* Rssi */ | ||
| 1321 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3_VALID, 1); | ||
| 1322 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR1, reg); | ||
| 1323 | |||
| 1324 | /* | ||
| 1325 | * CCK TXD BBP registers | ||
| 1326 | */ | ||
| 1327 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR2, ®); | ||
| 1328 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0, 13); | ||
| 1329 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0_VALID, 1); | ||
| 1330 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID1, 12); | ||
| 1331 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID1_VALID, 1); | ||
| 1332 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID2, 11); | ||
| 1333 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID2_VALID, 1); | ||
| 1334 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3, 10); | ||
| 1335 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3_VALID, 1); | ||
| 1336 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR2, reg); | ||
| 1337 | |||
| 1338 | /* | ||
| 1339 | * OFDM TXD BBP registers | ||
| 1340 | */ | ||
| 1341 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR3, ®); | ||
| 1342 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0, 7); | ||
| 1343 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0_VALID, 1); | ||
| 1344 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1, 6); | ||
| 1345 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1_VALID, 1); | ||
| 1346 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2, 5); | ||
| 1347 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2_VALID, 1); | ||
| 1348 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR3, reg); | ||
| 1349 | |||
| 1350 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR7, ®); | ||
| 1351 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_6MBS, 59); | ||
| 1352 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_9MBS, 53); | ||
| 1353 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_12MBS, 49); | ||
| 1354 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_18MBS, 46); | ||
| 1355 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR7, reg); | ||
| 1356 | |||
| 1357 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR8, ®); | ||
| 1358 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_24MBS, 44); | ||
| 1359 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_36MBS, 42); | ||
| 1360 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_48MBS, 42); | ||
| 1361 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_54MBS, 42); | ||
| 1362 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR8, reg); | ||
| 1363 | |||
| 1364 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f); | ||
| 1365 | |||
| 1366 | rt2x00pci_register_write(rt2x00dev, MAC_CSR6, 0x00000fff); | ||
| 1367 | |||
| 1368 | rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); | ||
| 1369 | rt2x00_set_field32(®, MAC_CSR9_CW_SELECT, 0); | ||
| 1370 | rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); | ||
| 1371 | |||
| 1372 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x0000071c); | ||
| 1373 | |||
| 1374 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) | ||
| 1375 | return -EBUSY; | ||
| 1376 | |||
| 1377 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); | ||
| 1378 | |||
| 1379 | /* | ||
| 1380 | * Invalidate all Shared Keys (SEC_CSR0), | ||
| 1381 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) | ||
| 1382 | */ | ||
| 1383 | rt2x00pci_register_write(rt2x00dev, SEC_CSR0, 0x00000000); | ||
| 1384 | rt2x00pci_register_write(rt2x00dev, SEC_CSR1, 0x00000000); | ||
| 1385 | rt2x00pci_register_write(rt2x00dev, SEC_CSR5, 0x00000000); | ||
| 1386 | |||
| 1387 | rt2x00pci_register_write(rt2x00dev, PHY_CSR1, 0x000023b0); | ||
| 1388 | rt2x00pci_register_write(rt2x00dev, PHY_CSR5, 0x060a100c); | ||
| 1389 | rt2x00pci_register_write(rt2x00dev, PHY_CSR6, 0x00080606); | ||
| 1390 | rt2x00pci_register_write(rt2x00dev, PHY_CSR7, 0x00000a08); | ||
| 1391 | |||
| 1392 | rt2x00pci_register_write(rt2x00dev, PCI_CFG_CSR, 0x28ca4404); | ||
| 1393 | |||
| 1394 | rt2x00pci_register_write(rt2x00dev, TEST_MODE_CSR, 0x00000200); | ||
| 1395 | |||
| 1396 | rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); | ||
| 1397 | |||
| 1398 | rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR0, ®); | ||
| 1399 | rt2x00_set_field32(®, AC_TXOP_CSR0_AC0_TX_OP, 0); | ||
| 1400 | rt2x00_set_field32(®, AC_TXOP_CSR0_AC1_TX_OP, 0); | ||
| 1401 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR0, reg); | ||
| 1402 | |||
| 1403 | rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR1, ®); | ||
| 1404 | rt2x00_set_field32(®, AC_TXOP_CSR1_AC2_TX_OP, 192); | ||
| 1405 | rt2x00_set_field32(®, AC_TXOP_CSR1_AC3_TX_OP, 48); | ||
| 1406 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); | ||
| 1407 | |||
| 1408 | /* | ||
| 1409 | * We must clear the error counters. | ||
| 1410 | * These registers are cleared on read, | ||
| 1411 | * so we may pass a useless variable to store the value. | ||
| 1412 | */ | ||
| 1413 | rt2x00pci_register_read(rt2x00dev, STA_CSR0, ®); | ||
| 1414 | rt2x00pci_register_read(rt2x00dev, STA_CSR1, ®); | ||
| 1415 | rt2x00pci_register_read(rt2x00dev, STA_CSR2, ®); | ||
| 1416 | |||
| 1417 | /* | ||
| 1418 | * Reset MAC and BBP registers. | ||
| 1419 | */ | ||
| 1420 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | ||
| 1421 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 1); | ||
| 1422 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 1); | ||
| 1423 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | ||
| 1424 | |||
| 1425 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | ||
| 1426 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 0); | ||
| 1427 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 0); | ||
| 1428 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | ||
| 1429 | |||
| 1430 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | ||
| 1431 | rt2x00_set_field32(®, MAC_CSR1_HOST_READY, 1); | ||
| 1432 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | ||
| 1433 | |||
| 1434 | return 0; | ||
| 1435 | } | ||
| 1436 | |||
| 1437 | static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev) | ||
| 1438 | { | ||
| 1439 | unsigned int i; | ||
| 1440 | u16 eeprom; | ||
| 1441 | u8 reg_id; | ||
| 1442 | u8 value; | ||
| 1443 | |||
| 1444 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 1445 | rt61pci_bbp_read(rt2x00dev, 0, &value); | ||
| 1446 | if ((value != 0xff) && (value != 0x00)) | ||
| 1447 | goto continue_csr_init; | ||
| 1448 | NOTICE(rt2x00dev, "Waiting for BBP register.\n"); | ||
| 1449 | udelay(REGISTER_BUSY_DELAY); | ||
| 1450 | } | ||
| 1451 | |||
| 1452 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | ||
| 1453 | return -EACCES; | ||
| 1454 | |||
| 1455 | continue_csr_init: | ||
| 1456 | rt61pci_bbp_write(rt2x00dev, 3, 0x00); | ||
| 1457 | rt61pci_bbp_write(rt2x00dev, 15, 0x30); | ||
| 1458 | rt61pci_bbp_write(rt2x00dev, 21, 0xc8); | ||
| 1459 | rt61pci_bbp_write(rt2x00dev, 22, 0x38); | ||
| 1460 | rt61pci_bbp_write(rt2x00dev, 23, 0x06); | ||
| 1461 | rt61pci_bbp_write(rt2x00dev, 24, 0xfe); | ||
| 1462 | rt61pci_bbp_write(rt2x00dev, 25, 0x0a); | ||
| 1463 | rt61pci_bbp_write(rt2x00dev, 26, 0x0d); | ||
| 1464 | rt61pci_bbp_write(rt2x00dev, 34, 0x12); | ||
| 1465 | rt61pci_bbp_write(rt2x00dev, 37, 0x07); | ||
| 1466 | rt61pci_bbp_write(rt2x00dev, 39, 0xf8); | ||
| 1467 | rt61pci_bbp_write(rt2x00dev, 41, 0x60); | ||
| 1468 | rt61pci_bbp_write(rt2x00dev, 53, 0x10); | ||
| 1469 | rt61pci_bbp_write(rt2x00dev, 54, 0x18); | ||
| 1470 | rt61pci_bbp_write(rt2x00dev, 60, 0x10); | ||
| 1471 | rt61pci_bbp_write(rt2x00dev, 61, 0x04); | ||
| 1472 | rt61pci_bbp_write(rt2x00dev, 62, 0x04); | ||
| 1473 | rt61pci_bbp_write(rt2x00dev, 75, 0xfe); | ||
| 1474 | rt61pci_bbp_write(rt2x00dev, 86, 0xfe); | ||
| 1475 | rt61pci_bbp_write(rt2x00dev, 88, 0xfe); | ||
| 1476 | rt61pci_bbp_write(rt2x00dev, 90, 0x0f); | ||
| 1477 | rt61pci_bbp_write(rt2x00dev, 99, 0x00); | ||
| 1478 | rt61pci_bbp_write(rt2x00dev, 102, 0x16); | ||
| 1479 | rt61pci_bbp_write(rt2x00dev, 107, 0x04); | ||
| 1480 | |||
| 1481 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
| 1482 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | ||
| 1483 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | ||
| 1484 | |||
| 1485 | if (eeprom != 0xffff && eeprom != 0x0000) { | ||
| 1486 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | ||
| 1487 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | ||
| 1488 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
| 1489 | reg_id, value); | ||
| 1490 | rt61pci_bbp_write(rt2x00dev, reg_id, value); | ||
| 1491 | } | ||
| 1492 | } | ||
| 1493 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
| 1494 | |||
| 1495 | return 0; | ||
| 1496 | } | ||
| 1497 | |||
| 1498 | /* | ||
| 1499 | * Device state switch handlers. | ||
| 1500 | */ | ||
| 1501 | static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev, | ||
| 1502 | enum dev_state state) | ||
| 1503 | { | ||
| 1504 | u32 reg; | ||
| 1505 | |||
| 1506 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
| 1507 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, | ||
| 1508 | state == STATE_RADIO_RX_OFF); | ||
| 1509 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
| 1510 | } | ||
| 1511 | |||
| 1512 | static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | ||
| 1513 | enum dev_state state) | ||
| 1514 | { | ||
| 1515 | int mask = (state == STATE_RADIO_IRQ_OFF); | ||
| 1516 | u32 reg; | ||
| 1517 | |||
| 1518 | /* | ||
| 1519 | * When interrupts are being enabled, the interrupt registers | ||
| 1520 | * should clear the register to assure a clean state. | ||
| 1521 | */ | ||
| 1522 | if (state == STATE_RADIO_IRQ_ON) { | ||
| 1523 | rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | ||
| 1524 | rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); | ||
| 1525 | |||
| 1526 | rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®); | ||
| 1527 | rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg); | ||
| 1528 | } | ||
| 1529 | |||
| 1530 | /* | ||
| 1531 | * Only toggle the interrupts bits we are going to use. | ||
| 1532 | * Non-checked interrupt bits are disabled by default. | ||
| 1533 | */ | ||
| 1534 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); | ||
| 1535 | rt2x00_set_field32(®, INT_MASK_CSR_TXDONE, mask); | ||
| 1536 | rt2x00_set_field32(®, INT_MASK_CSR_RXDONE, mask); | ||
| 1537 | rt2x00_set_field32(®, INT_MASK_CSR_ENABLE_MITIGATION, mask); | ||
| 1538 | rt2x00_set_field32(®, INT_MASK_CSR_MITIGATION_PERIOD, 0xff); | ||
| 1539 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); | ||
| 1540 | |||
| 1541 | rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); | ||
| 1542 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_0, mask); | ||
| 1543 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_1, mask); | ||
| 1544 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_2, mask); | ||
| 1545 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_3, mask); | ||
| 1546 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_4, mask); | ||
| 1547 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_5, mask); | ||
| 1548 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_6, mask); | ||
| 1549 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_7, mask); | ||
| 1550 | rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); | ||
| 1551 | } | ||
| 1552 | |||
| 1553 | static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 1554 | { | ||
| 1555 | u32 reg; | ||
| 1556 | |||
| 1557 | /* | ||
| 1558 | * Initialize all registers. | ||
| 1559 | */ | ||
| 1560 | if (rt61pci_init_rings(rt2x00dev) || | ||
| 1561 | rt61pci_init_registers(rt2x00dev) || | ||
| 1562 | rt61pci_init_bbp(rt2x00dev)) { | ||
| 1563 | ERROR(rt2x00dev, "Register initialization failed.\n"); | ||
| 1564 | return -EIO; | ||
| 1565 | } | ||
| 1566 | |||
| 1567 | /* | ||
| 1568 | * Enable interrupts. | ||
| 1569 | */ | ||
| 1570 | rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | ||
| 1571 | |||
| 1572 | /* | ||
| 1573 | * Enable RX. | ||
| 1574 | */ | ||
| 1575 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); | ||
| 1576 | rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); | ||
| 1577 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); | ||
| 1578 | |||
| 1579 | /* | ||
| 1580 | * Enable LED | ||
| 1581 | */ | ||
| 1582 | rt61pci_enable_led(rt2x00dev); | ||
| 1583 | |||
| 1584 | return 0; | ||
| 1585 | } | ||
| 1586 | |||
| 1587 | static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 1588 | { | ||
| 1589 | u32 reg; | ||
| 1590 | |||
| 1591 | /* | ||
| 1592 | * Disable LED | ||
| 1593 | */ | ||
| 1594 | rt61pci_disable_led(rt2x00dev); | ||
| 1595 | |||
| 1596 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | ||
| 1597 | |||
| 1598 | /* | ||
| 1599 | * Disable synchronisation. | ||
| 1600 | */ | ||
| 1601 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
| 1602 | |||
| 1603 | /* | ||
| 1604 | * Cancel RX and TX. | ||
| 1605 | */ | ||
| 1606 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | ||
| 1607 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, 1); | ||
| 1608 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); | ||
| 1609 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); | ||
| 1610 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); | ||
| 1611 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_MGMT, 1); | ||
| 1612 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | ||
| 1613 | |||
| 1614 | /* | ||
| 1615 | * Disable interrupts. | ||
| 1616 | */ | ||
| 1617 | rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF); | ||
| 1618 | } | ||
| 1619 | |||
| 1620 | static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | ||
| 1621 | { | ||
| 1622 | u32 reg; | ||
| 1623 | unsigned int i; | ||
| 1624 | char put_to_sleep; | ||
| 1625 | char current_state; | ||
| 1626 | |||
| 1627 | put_to_sleep = (state != STATE_AWAKE); | ||
| 1628 | |||
| 1629 | rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®); | ||
| 1630 | rt2x00_set_field32(®, MAC_CSR12_FORCE_WAKEUP, !put_to_sleep); | ||
| 1631 | rt2x00_set_field32(®, MAC_CSR12_PUT_TO_SLEEP, put_to_sleep); | ||
| 1632 | rt2x00pci_register_write(rt2x00dev, MAC_CSR12, reg); | ||
| 1633 | |||
| 1634 | /* | ||
| 1635 | * Device is not guaranteed to be in the requested state yet. | ||
| 1636 | * We must wait until the register indicates that the | ||
| 1637 | * device has entered the correct state. | ||
| 1638 | */ | ||
| 1639 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 1640 | rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®); | ||
| 1641 | current_state = | ||
| 1642 | rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); | ||
| 1643 | if (current_state == !put_to_sleep) | ||
| 1644 | return 0; | ||
| 1645 | msleep(10); | ||
| 1646 | } | ||
| 1647 | |||
| 1648 | NOTICE(rt2x00dev, "Device failed to enter state %d, " | ||
| 1649 | "current device state %d.\n", !put_to_sleep, current_state); | ||
| 1650 | |||
| 1651 | return -EBUSY; | ||
| 1652 | } | ||
| 1653 | |||
| 1654 | static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | ||
| 1655 | enum dev_state state) | ||
| 1656 | { | ||
| 1657 | int retval = 0; | ||
| 1658 | |||
| 1659 | switch (state) { | ||
| 1660 | case STATE_RADIO_ON: | ||
| 1661 | retval = rt61pci_enable_radio(rt2x00dev); | ||
| 1662 | break; | ||
| 1663 | case STATE_RADIO_OFF: | ||
| 1664 | rt61pci_disable_radio(rt2x00dev); | ||
| 1665 | break; | ||
| 1666 | case STATE_RADIO_RX_ON: | ||
| 1667 | case STATE_RADIO_RX_OFF: | ||
| 1668 | rt61pci_toggle_rx(rt2x00dev, state); | ||
| 1669 | break; | ||
| 1670 | case STATE_DEEP_SLEEP: | ||
| 1671 | case STATE_SLEEP: | ||
| 1672 | case STATE_STANDBY: | ||
| 1673 | case STATE_AWAKE: | ||
| 1674 | retval = rt61pci_set_state(rt2x00dev, state); | ||
| 1675 | break; | ||
| 1676 | default: | ||
| 1677 | retval = -ENOTSUPP; | ||
| 1678 | break; | ||
| 1679 | } | ||
| 1680 | |||
| 1681 | return retval; | ||
| 1682 | } | ||
| 1683 | |||
| 1684 | /* | ||
| 1685 | * TX descriptor initialization | ||
| 1686 | */ | ||
| 1687 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | ||
| 1688 | struct data_desc *txd, | ||
| 1689 | struct data_entry_desc *desc, | ||
| 1690 | struct ieee80211_hdr *ieee80211hdr, | ||
| 1691 | unsigned int length, | ||
| 1692 | struct ieee80211_tx_control *control) | ||
| 1693 | { | ||
| 1694 | u32 word; | ||
| 1695 | |||
| 1696 | /* | ||
| 1697 | * Start writing the descriptor words. | ||
| 1698 | */ | ||
| 1699 | rt2x00_desc_read(txd, 1, &word); | ||
| 1700 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue); | ||
| 1701 | rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs); | ||
| 1702 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | ||
| 1703 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | ||
| 1704 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | ||
| 1705 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | ||
| 1706 | rt2x00_desc_write(txd, 1, word); | ||
| 1707 | |||
| 1708 | rt2x00_desc_read(txd, 2, &word); | ||
| 1709 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | ||
| 1710 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | ||
| 1711 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | ||
| 1712 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | ||
| 1713 | rt2x00_desc_write(txd, 2, word); | ||
| 1714 | |||
| 1715 | rt2x00_desc_read(txd, 5, &word); | ||
| 1716 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | ||
| 1717 | TXPOWER_TO_DEV(control->power_level)); | ||
| 1718 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | ||
| 1719 | rt2x00_desc_write(txd, 5, word); | ||
| 1720 | |||
| 1721 | rt2x00_desc_read(txd, 11, &word); | ||
| 1722 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, length); | ||
| 1723 | rt2x00_desc_write(txd, 11, word); | ||
| 1724 | |||
| 1725 | rt2x00_desc_read(txd, 0, &word); | ||
| 1726 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | ||
| 1727 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | ||
| 1728 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | ||
| 1729 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | ||
| 1730 | rt2x00_set_field32(&word, TXD_W0_ACK, | ||
| 1731 | !(control->flags & IEEE80211_TXCTL_NO_ACK)); | ||
| 1732 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | ||
| 1733 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | ||
| 1734 | rt2x00_set_field32(&word, TXD_W0_OFDM, | ||
| 1735 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | ||
| 1736 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | ||
| 1737 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | ||
| 1738 | !!(control->flags & | ||
| 1739 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | ||
| 1740 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | ||
| 1741 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length); | ||
| 1742 | rt2x00_set_field32(&word, TXD_W0_BURST, | ||
| 1743 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | ||
| 1744 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | ||
| 1745 | rt2x00_desc_write(txd, 0, word); | ||
| 1746 | } | ||
| 1747 | |||
| 1748 | /* | ||
| 1749 | * TX data initialization | ||
| 1750 | */ | ||
| 1751 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
| 1752 | unsigned int queue) | ||
| 1753 | { | ||
| 1754 | u32 reg; | ||
| 1755 | |||
| 1756 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | ||
| 1757 | /* | ||
| 1758 | * For Wi-Fi faily generated beacons between participating | ||
| 1759 | * stations. Set TBTT phase adaptive adjustment step to 8us. | ||
| 1760 | */ | ||
| 1761 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); | ||
| 1762 | |||
| 1763 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
| 1764 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { | ||
| 1765 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | ||
| 1766 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
| 1767 | } | ||
| 1768 | return; | ||
| 1769 | } | ||
| 1770 | |||
| 1771 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | ||
| 1772 | if (queue == IEEE80211_TX_QUEUE_DATA0) | ||
| 1773 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, 1); | ||
| 1774 | else if (queue == IEEE80211_TX_QUEUE_DATA1) | ||
| 1775 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, 1); | ||
| 1776 | else if (queue == IEEE80211_TX_QUEUE_DATA2) | ||
| 1777 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, 1); | ||
| 1778 | else if (queue == IEEE80211_TX_QUEUE_DATA3) | ||
| 1779 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, 1); | ||
| 1780 | else if (queue == IEEE80211_TX_QUEUE_DATA4) | ||
| 1781 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_MGMT, 1); | ||
| 1782 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | ||
| 1783 | } | ||
| 1784 | |||
| 1785 | /* | ||
| 1786 | * RX control handlers | ||
| 1787 | */ | ||
| 1788 | static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | ||
| 1789 | { | ||
| 1790 | u16 eeprom; | ||
| 1791 | u8 offset; | ||
| 1792 | u8 lna; | ||
| 1793 | |||
| 1794 | lna = rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_LNA); | ||
| 1795 | switch (lna) { | ||
| 1796 | case 3: | ||
| 1797 | offset = 90; | ||
| 1798 | break; | ||
| 1799 | case 2: | ||
| 1800 | offset = 74; | ||
| 1801 | break; | ||
| 1802 | case 1: | ||
| 1803 | offset = 64; | ||
| 1804 | break; | ||
| 1805 | default: | ||
| 1806 | return 0; | ||
| 1807 | } | ||
| 1808 | |||
| 1809 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | ||
| 1810 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) | ||
| 1811 | offset += 14; | ||
| 1812 | |||
| 1813 | if (lna == 3 || lna == 2) | ||
| 1814 | offset += 10; | ||
| 1815 | |||
| 1816 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom); | ||
| 1817 | offset -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1); | ||
| 1818 | } else { | ||
| 1819 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) | ||
| 1820 | offset += 14; | ||
| 1821 | |||
| 1822 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); | ||
| 1823 | offset -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1); | ||
| 1824 | } | ||
| 1825 | |||
| 1826 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; | ||
| 1827 | } | ||
| 1828 | |||
| 1829 | static int rt61pci_fill_rxdone(struct data_entry *entry, | ||
| 1830 | int *signal, int *rssi, int *ofdm, int *size) | ||
| 1831 | { | ||
| 1832 | struct data_desc *rxd = entry->priv; | ||
| 1833 | u32 word0; | ||
| 1834 | u32 word1; | ||
| 1835 | |||
| 1836 | rt2x00_desc_read(rxd, 0, &word0); | ||
| 1837 | rt2x00_desc_read(rxd, 1, &word1); | ||
| 1838 | |||
| 1839 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR) || | ||
| 1840 | rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR)) | ||
| 1841 | return -EINVAL; | ||
| 1842 | |||
| 1843 | /* | ||
| 1844 | * Obtain the status about this packet. | ||
| 1845 | */ | ||
| 1846 | *signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | ||
| 1847 | *rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1); | ||
| 1848 | *ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | ||
| 1849 | *size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
| 1850 | |||
| 1851 | return 0; | ||
| 1852 | } | ||
| 1853 | |||
| 1854 | /* | ||
| 1855 | * Interrupt functions. | ||
| 1856 | */ | ||
| 1857 | static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | ||
| 1858 | { | ||
| 1859 | struct data_ring *ring; | ||
| 1860 | struct data_entry *entry; | ||
| 1861 | struct data_desc *txd; | ||
| 1862 | u32 word; | ||
| 1863 | u32 reg; | ||
| 1864 | u32 old_reg; | ||
| 1865 | int type; | ||
| 1866 | int index; | ||
| 1867 | int tx_status; | ||
| 1868 | int retry; | ||
| 1869 | |||
| 1870 | /* | ||
| 1871 | * During each loop we will compare the freshly read | ||
| 1872 | * STA_CSR4 register value with the value read from | ||
| 1873 | * the previous loop. If the 2 values are equal then | ||
| 1874 | * we should stop processing because the chance it | ||
| 1875 | * quite big that the device has been unplugged and | ||
| 1876 | * we risk going into an endless loop. | ||
| 1877 | */ | ||
| 1878 | old_reg = 0; | ||
| 1879 | |||
| 1880 | while (1) { | ||
| 1881 | rt2x00pci_register_read(rt2x00dev, STA_CSR4, ®); | ||
| 1882 | if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) | ||
| 1883 | break; | ||
| 1884 | |||
| 1885 | if (old_reg == reg) | ||
| 1886 | break; | ||
| 1887 | old_reg = reg; | ||
| 1888 | |||
| 1889 | /* | ||
| 1890 | * Skip this entry when it contains an invalid | ||
| 1891 | * ring identication number. | ||
| 1892 | */ | ||
| 1893 | type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); | ||
| 1894 | ring = rt2x00lib_get_ring(rt2x00dev, type); | ||
| 1895 | if (unlikely(!ring)) | ||
| 1896 | continue; | ||
| 1897 | |||
| 1898 | /* | ||
| 1899 | * Skip this entry when it contains an invalid | ||
| 1900 | * index number. | ||
| 1901 | */ | ||
| 1902 | index = rt2x00_get_field32(reg, STA_CSR4_PID_SUBTYPE); | ||
| 1903 | if (unlikely(index >= ring->stats.limit)) | ||
| 1904 | continue; | ||
| 1905 | |||
| 1906 | entry = &ring->entry[index]; | ||
| 1907 | txd = entry->priv; | ||
| 1908 | rt2x00_desc_read(txd, 0, &word); | ||
| 1909 | |||
| 1910 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | ||
| 1911 | !rt2x00_get_field32(word, TXD_W0_VALID)) | ||
| 1912 | return; | ||
| 1913 | |||
| 1914 | /* | ||
| 1915 | * Obtain the status about this packet. | ||
| 1916 | */ | ||
| 1917 | tx_status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); | ||
| 1918 | retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); | ||
| 1919 | |||
| 1920 | rt2x00lib_txdone(entry, tx_status, retry); | ||
| 1921 | |||
| 1922 | /* | ||
| 1923 | * Make this entry available for reuse. | ||
| 1924 | */ | ||
| 1925 | entry->flags = 0; | ||
| 1926 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | ||
| 1927 | rt2x00_desc_write(txd, 0, word); | ||
| 1928 | rt2x00_ring_index_done_inc(entry->ring); | ||
| 1929 | |||
| 1930 | /* | ||
| 1931 | * If the data ring was full before the txdone handler | ||
| 1932 | * we must make sure the packet queue in the mac80211 stack | ||
| 1933 | * is reenabled when the txdone handler has finished. | ||
| 1934 | */ | ||
| 1935 | if (!rt2x00_ring_full(ring)) | ||
| 1936 | ieee80211_wake_queue(rt2x00dev->hw, | ||
| 1937 | entry->tx_status.control.queue); | ||
| 1938 | } | ||
| 1939 | } | ||
| 1940 | |||
| 1941 | static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) | ||
| 1942 | { | ||
| 1943 | struct rt2x00_dev *rt2x00dev = dev_instance; | ||
| 1944 | u32 reg_mcu; | ||
| 1945 | u32 reg; | ||
| 1946 | |||
| 1947 | /* | ||
| 1948 | * Get the interrupt sources & saved to local variable. | ||
| 1949 | * Write register value back to clear pending interrupts. | ||
| 1950 | */ | ||
| 1951 | rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®_mcu); | ||
| 1952 | rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu); | ||
| 1953 | |||
| 1954 | rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | ||
| 1955 | rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); | ||
| 1956 | |||
| 1957 | if (!reg && !reg_mcu) | ||
| 1958 | return IRQ_NONE; | ||
| 1959 | |||
| 1960 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
| 1961 | return IRQ_HANDLED; | ||
| 1962 | |||
| 1963 | /* | ||
| 1964 | * Handle interrupts, walk through all bits | ||
| 1965 | * and run the tasks, the bits are checked in order of | ||
| 1966 | * priority. | ||
| 1967 | */ | ||
| 1968 | |||
| 1969 | /* | ||
| 1970 | * 1 - Rx ring done interrupt. | ||
| 1971 | */ | ||
| 1972 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RXDONE)) | ||
| 1973 | rt2x00pci_rxdone(rt2x00dev); | ||
| 1974 | |||
| 1975 | /* | ||
| 1976 | * 2 - Tx ring done interrupt. | ||
| 1977 | */ | ||
| 1978 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TXDONE)) | ||
| 1979 | rt61pci_txdone(rt2x00dev); | ||
| 1980 | |||
| 1981 | /* | ||
| 1982 | * 3 - Handle MCU command done. | ||
| 1983 | */ | ||
| 1984 | if (reg_mcu) | ||
| 1985 | rt2x00pci_register_write(rt2x00dev, | ||
| 1986 | M2H_CMD_DONE_CSR, 0xffffffff); | ||
| 1987 | |||
| 1988 | return IRQ_HANDLED; | ||
| 1989 | } | ||
| 1990 | |||
| 1991 | /* | ||
| 1992 | * Device probe functions. | ||
| 1993 | */ | ||
| 1994 | static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | ||
| 1995 | { | ||
| 1996 | struct eeprom_93cx6 eeprom; | ||
| 1997 | u32 reg; | ||
| 1998 | u16 word; | ||
| 1999 | u8 *mac; | ||
| 2000 | s8 value; | ||
| 2001 | |||
| 2002 | rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); | ||
| 2003 | |||
| 2004 | eeprom.data = rt2x00dev; | ||
| 2005 | eeprom.register_read = rt61pci_eepromregister_read; | ||
| 2006 | eeprom.register_write = rt61pci_eepromregister_write; | ||
| 2007 | eeprom.width = rt2x00_get_field32(reg, E2PROM_CSR_TYPE_93C46) ? | ||
| 2008 | PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66; | ||
| 2009 | eeprom.reg_data_in = 0; | ||
| 2010 | eeprom.reg_data_out = 0; | ||
| 2011 | eeprom.reg_data_clock = 0; | ||
| 2012 | eeprom.reg_chip_select = 0; | ||
| 2013 | |||
| 2014 | eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom, | ||
| 2015 | EEPROM_SIZE / sizeof(u16)); | ||
| 2016 | |||
| 2017 | /* | ||
| 2018 | * Start validation of the data that has been read. | ||
| 2019 | */ | ||
| 2020 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | ||
| 2021 | if (!is_valid_ether_addr(mac)) { | ||
| 2022 | random_ether_addr(mac); | ||
| 2023 | EEPROM(rt2x00dev, "MAC: " MAC_FMT "\n", MAC_ARG(mac)); | ||
| 2024 | } | ||
| 2025 | |||
| 2026 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | ||
| 2027 | if (word == 0xffff) { | ||
| 2028 | rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2); | ||
| 2029 | rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 2); | ||
| 2030 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 2); | ||
| 2031 | rt2x00_set_field16(&word, EEPROM_ANTENNA_FRAME_TYPE, 0); | ||
| 2032 | rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0); | ||
| 2033 | rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); | ||
| 2034 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF5225); | ||
| 2035 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | ||
| 2036 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | ||
| 2037 | } | ||
| 2038 | |||
| 2039 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | ||
| 2040 | if (word == 0xffff) { | ||
| 2041 | rt2x00_set_field16(&word, EEPROM_NIC_ENABLE_DIVERSITY, 0); | ||
| 2042 | rt2x00_set_field16(&word, EEPROM_NIC_TX_DIVERSITY, 0); | ||
| 2043 | rt2x00_set_field16(&word, EEPROM_NIC_TX_RX_FIXED, 0); | ||
| 2044 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0); | ||
| 2045 | rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); | ||
| 2046 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); | ||
| 2047 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | ||
| 2048 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | ||
| 2049 | } | ||
| 2050 | |||
| 2051 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &word); | ||
| 2052 | if (word == 0xffff) { | ||
| 2053 | rt2x00_set_field16(&word, EEPROM_LED_LED_MODE, | ||
| 2054 | LED_MODE_DEFAULT); | ||
| 2055 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED, word); | ||
| 2056 | EEPROM(rt2x00dev, "Led: 0x%04x\n", word); | ||
| 2057 | } | ||
| 2058 | |||
| 2059 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); | ||
| 2060 | if (word == 0xffff) { | ||
| 2061 | rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); | ||
| 2062 | rt2x00_set_field16(&word, EEPROM_FREQ_SEQ, 0); | ||
| 2063 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); | ||
| 2064 | EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); | ||
| 2065 | } | ||
| 2066 | |||
| 2067 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &word); | ||
| 2068 | if (word == 0xffff) { | ||
| 2069 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); | ||
| 2070 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); | ||
| 2071 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); | ||
| 2072 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | ||
| 2073 | } else { | ||
| 2074 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_1); | ||
| 2075 | if (value < -10 || value > 10) | ||
| 2076 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); | ||
| 2077 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_2); | ||
| 2078 | if (value < -10 || value > 10) | ||
| 2079 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); | ||
| 2080 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); | ||
| 2081 | } | ||
| 2082 | |||
| 2083 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &word); | ||
| 2084 | if (word == 0xffff) { | ||
| 2085 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | ||
| 2086 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | ||
| 2087 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | ||
| 2088 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | ||
| 2089 | } else { | ||
| 2090 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | ||
| 2091 | if (value < -10 || value > 10) | ||
| 2092 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | ||
| 2093 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_2); | ||
| 2094 | if (value < -10 || value > 10) | ||
| 2095 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | ||
| 2096 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | ||
| 2097 | } | ||
| 2098 | |||
| 2099 | return 0; | ||
| 2100 | } | ||
| 2101 | |||
| 2102 | static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | ||
| 2103 | { | ||
| 2104 | u32 reg; | ||
| 2105 | u16 value; | ||
| 2106 | u16 eeprom; | ||
| 2107 | u16 device; | ||
| 2108 | |||
| 2109 | /* | ||
| 2110 | * Read EEPROM word for configuration. | ||
| 2111 | */ | ||
| 2112 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
| 2113 | |||
| 2114 | /* | ||
| 2115 | * Identify RF chipset. | ||
| 2116 | * To determine the RT chip we have to read the | ||
| 2117 | * PCI header of the device. | ||
| 2118 | */ | ||
| 2119 | pci_read_config_word(rt2x00dev_pci(rt2x00dev), | ||
| 2120 | PCI_CONFIG_HEADER_DEVICE, &device); | ||
| 2121 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | ||
| 2122 | rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); | ||
| 2123 | rt2x00_set_chip(rt2x00dev, device, value, reg); | ||
| 2124 | |||
| 2125 | if (!rt2x00_rf(&rt2x00dev->chip, RF5225) && | ||
| 2126 | !rt2x00_rf(&rt2x00dev->chip, RF5325) && | ||
| 2127 | !rt2x00_rf(&rt2x00dev->chip, RF2527) && | ||
| 2128 | !rt2x00_rf(&rt2x00dev->chip, RF2529)) { | ||
| 2129 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | ||
| 2130 | return -ENODEV; | ||
| 2131 | } | ||
| 2132 | |||
| 2133 | /* | ||
| 2134 | * Identify default antenna configuration. | ||
| 2135 | */ | ||
| 2136 | rt2x00dev->hw->conf.antenna_sel_tx = | ||
| 2137 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT); | ||
| 2138 | rt2x00dev->hw->conf.antenna_sel_rx = | ||
| 2139 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT); | ||
| 2140 | |||
| 2141 | /* | ||
| 2142 | * Read the Frame type. | ||
| 2143 | */ | ||
| 2144 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE)) | ||
| 2145 | __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); | ||
| 2146 | |||
| 2147 | /* | ||
| 2148 | * Determine number of antenna's. | ||
| 2149 | */ | ||
| 2150 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2) | ||
| 2151 | __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags); | ||
| 2152 | |||
| 2153 | /* | ||
| 2154 | * Detect if this device has an hardware controlled radio. | ||
| 2155 | */ | ||
| 2156 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) | ||
| 2157 | __set_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | ||
| 2158 | |||
| 2159 | /* | ||
| 2160 | * Read frequency offset and RF programming sequence. | ||
| 2161 | */ | ||
| 2162 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); | ||
| 2163 | if (rt2x00_get_field16(eeprom, EEPROM_FREQ_SEQ)) | ||
| 2164 | __set_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags); | ||
| 2165 | |||
| 2166 | rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); | ||
| 2167 | |||
| 2168 | /* | ||
| 2169 | * Read external LNA informations. | ||
| 2170 | */ | ||
| 2171 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | ||
| 2172 | |||
| 2173 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A)) | ||
| 2174 | __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | ||
| 2175 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) | ||
| 2176 | __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | ||
| 2177 | |||
| 2178 | /* | ||
| 2179 | * Store led settings, for correct led behaviour. | ||
| 2180 | * If the eeprom value is invalid, | ||
| 2181 | * switch to default led mode. | ||
| 2182 | */ | ||
| 2183 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | ||
| 2184 | |||
| 2185 | rt2x00dev->led_mode = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); | ||
| 2186 | |||
| 2187 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, | ||
| 2188 | rt2x00dev->led_mode); | ||
| 2189 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, | ||
| 2190 | rt2x00_get_field16(eeprom, | ||
| 2191 | EEPROM_LED_POLARITY_GPIO_0)); | ||
| 2192 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, | ||
| 2193 | rt2x00_get_field16(eeprom, | ||
| 2194 | EEPROM_LED_POLARITY_GPIO_1)); | ||
| 2195 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, | ||
| 2196 | rt2x00_get_field16(eeprom, | ||
| 2197 | EEPROM_LED_POLARITY_GPIO_2)); | ||
| 2198 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, | ||
| 2199 | rt2x00_get_field16(eeprom, | ||
| 2200 | EEPROM_LED_POLARITY_GPIO_3)); | ||
| 2201 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, | ||
| 2202 | rt2x00_get_field16(eeprom, | ||
| 2203 | EEPROM_LED_POLARITY_GPIO_4)); | ||
| 2204 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, | ||
| 2205 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); | ||
| 2206 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, | ||
| 2207 | rt2x00_get_field16(eeprom, | ||
| 2208 | EEPROM_LED_POLARITY_RDY_G)); | ||
| 2209 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, | ||
| 2210 | rt2x00_get_field16(eeprom, | ||
| 2211 | EEPROM_LED_POLARITY_RDY_A)); | ||
| 2212 | |||
| 2213 | return 0; | ||
| 2214 | } | ||
| 2215 | |||
| 2216 | /* | ||
| 2217 | * RF value list for RF5225 & RF5325 | ||
| 2218 | * Supports: 2.4 GHz & 5.2 GHz, rf_sequence disabled | ||
| 2219 | */ | ||
| 2220 | static const struct rf_channel rf_vals_noseq[] = { | ||
| 2221 | { 1, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa0b }, | ||
| 2222 | { 2, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa1f }, | ||
| 2223 | { 3, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa0b }, | ||
| 2224 | { 4, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa1f }, | ||
| 2225 | { 5, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa0b }, | ||
| 2226 | { 6, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa1f }, | ||
| 2227 | { 7, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa0b }, | ||
| 2228 | { 8, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa1f }, | ||
| 2229 | { 9, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa0b }, | ||
| 2230 | { 10, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa1f }, | ||
| 2231 | { 11, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa0b }, | ||
| 2232 | { 12, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa1f }, | ||
| 2233 | { 13, 0x00002ccc, 0x0000479e, 0x00068455, 0x000ffa0b }, | ||
| 2234 | { 14, 0x00002ccc, 0x000047a2, 0x00068455, 0x000ffa13 }, | ||
| 2235 | |||
| 2236 | /* 802.11 UNI / HyperLan 2 */ | ||
| 2237 | { 36, 0x00002ccc, 0x0000499a, 0x0009be55, 0x000ffa23 }, | ||
| 2238 | { 40, 0x00002ccc, 0x000049a2, 0x0009be55, 0x000ffa03 }, | ||
| 2239 | { 44, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000ffa0b }, | ||
| 2240 | { 48, 0x00002ccc, 0x000049aa, 0x0009be55, 0x000ffa13 }, | ||
| 2241 | { 52, 0x00002ccc, 0x000049ae, 0x0009ae55, 0x000ffa1b }, | ||
| 2242 | { 56, 0x00002ccc, 0x000049b2, 0x0009ae55, 0x000ffa23 }, | ||
| 2243 | { 60, 0x00002ccc, 0x000049ba, 0x0009ae55, 0x000ffa03 }, | ||
| 2244 | { 64, 0x00002ccc, 0x000049be, 0x0009ae55, 0x000ffa0b }, | ||
| 2245 | |||
| 2246 | /* 802.11 HyperLan 2 */ | ||
| 2247 | { 100, 0x00002ccc, 0x00004a2a, 0x000bae55, 0x000ffa03 }, | ||
| 2248 | { 104, 0x00002ccc, 0x00004a2e, 0x000bae55, 0x000ffa0b }, | ||
| 2249 | { 108, 0x00002ccc, 0x00004a32, 0x000bae55, 0x000ffa13 }, | ||
| 2250 | { 112, 0x00002ccc, 0x00004a36, 0x000bae55, 0x000ffa1b }, | ||
| 2251 | { 116, 0x00002ccc, 0x00004a3a, 0x000bbe55, 0x000ffa23 }, | ||
| 2252 | { 120, 0x00002ccc, 0x00004a82, 0x000bbe55, 0x000ffa03 }, | ||
| 2253 | { 124, 0x00002ccc, 0x00004a86, 0x000bbe55, 0x000ffa0b }, | ||
| 2254 | { 128, 0x00002ccc, 0x00004a8a, 0x000bbe55, 0x000ffa13 }, | ||
| 2255 | { 132, 0x00002ccc, 0x00004a8e, 0x000bbe55, 0x000ffa1b }, | ||
| 2256 | { 136, 0x00002ccc, 0x00004a92, 0x000bbe55, 0x000ffa23 }, | ||
| 2257 | |||
| 2258 | /* 802.11 UNII */ | ||
| 2259 | { 140, 0x00002ccc, 0x00004a9a, 0x000bbe55, 0x000ffa03 }, | ||
| 2260 | { 149, 0x00002ccc, 0x00004aa2, 0x000bbe55, 0x000ffa1f }, | ||
| 2261 | { 153, 0x00002ccc, 0x00004aa6, 0x000bbe55, 0x000ffa27 }, | ||
| 2262 | { 157, 0x00002ccc, 0x00004aae, 0x000bbe55, 0x000ffa07 }, | ||
| 2263 | { 161, 0x00002ccc, 0x00004ab2, 0x000bbe55, 0x000ffa0f }, | ||
| 2264 | { 165, 0x00002ccc, 0x00004ab6, 0x000bbe55, 0x000ffa17 }, | ||
| 2265 | |||
| 2266 | /* MMAC(Japan)J52 ch 34,38,42,46 */ | ||
| 2267 | { 34, 0x00002ccc, 0x0000499a, 0x0009be55, 0x000ffa0b }, | ||
| 2268 | { 38, 0x00002ccc, 0x0000499e, 0x0009be55, 0x000ffa13 }, | ||
| 2269 | { 42, 0x00002ccc, 0x000049a2, 0x0009be55, 0x000ffa1b }, | ||
| 2270 | { 46, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000ffa23 }, | ||
| 2271 | }; | ||
| 2272 | |||
| 2273 | /* | ||
| 2274 | * RF value list for RF5225 & RF5325 | ||
| 2275 | * Supports: 2.4 GHz & 5.2 GHz, rf_sequence enabled | ||
| 2276 | */ | ||
| 2277 | static const struct rf_channel rf_vals_seq[] = { | ||
| 2278 | { 1, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa0b }, | ||
| 2279 | { 2, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa1f }, | ||
| 2280 | { 3, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa0b }, | ||
| 2281 | { 4, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa1f }, | ||
| 2282 | { 5, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa0b }, | ||
| 2283 | { 6, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa1f }, | ||
| 2284 | { 7, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa0b }, | ||
| 2285 | { 8, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa1f }, | ||
| 2286 | { 9, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa0b }, | ||
| 2287 | { 10, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa1f }, | ||
| 2288 | { 11, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa0b }, | ||
| 2289 | { 12, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa1f }, | ||
| 2290 | { 13, 0x00002ccc, 0x0000479e, 0x00068455, 0x000ffa0b }, | ||
| 2291 | { 14, 0x00002ccc, 0x000047a2, 0x00068455, 0x000ffa13 }, | ||
| 2292 | |||
| 2293 | /* 802.11 UNI / HyperLan 2 */ | ||
| 2294 | { 36, 0x00002cd4, 0x0004481a, 0x00098455, 0x000c0a03 }, | ||
| 2295 | { 40, 0x00002cd0, 0x00044682, 0x00098455, 0x000c0a03 }, | ||
| 2296 | { 44, 0x00002cd0, 0x00044686, 0x00098455, 0x000c0a1b }, | ||
| 2297 | { 48, 0x00002cd0, 0x0004468e, 0x00098655, 0x000c0a0b }, | ||
| 2298 | { 52, 0x00002cd0, 0x00044692, 0x00098855, 0x000c0a23 }, | ||
| 2299 | { 56, 0x00002cd0, 0x0004469a, 0x00098c55, 0x000c0a13 }, | ||
| 2300 | { 60, 0x00002cd0, 0x000446a2, 0x00098e55, 0x000c0a03 }, | ||
| 2301 | { 64, 0x00002cd0, 0x000446a6, 0x00099255, 0x000c0a1b }, | ||
| 2302 | |||
| 2303 | /* 802.11 HyperLan 2 */ | ||
| 2304 | { 100, 0x00002cd4, 0x0004489a, 0x000b9855, 0x000c0a03 }, | ||
| 2305 | { 104, 0x00002cd4, 0x000448a2, 0x000b9855, 0x000c0a03 }, | ||
| 2306 | { 108, 0x00002cd4, 0x000448aa, 0x000b9855, 0x000c0a03 }, | ||
| 2307 | { 112, 0x00002cd4, 0x000448b2, 0x000b9a55, 0x000c0a03 }, | ||
| 2308 | { 116, 0x00002cd4, 0x000448ba, 0x000b9a55, 0x000c0a03 }, | ||
| 2309 | { 120, 0x00002cd0, 0x00044702, 0x000b9a55, 0x000c0a03 }, | ||
| 2310 | { 124, 0x00002cd0, 0x00044706, 0x000b9a55, 0x000c0a1b }, | ||
| 2311 | { 128, 0x00002cd0, 0x0004470e, 0x000b9c55, 0x000c0a0b }, | ||
| 2312 | { 132, 0x00002cd0, 0x00044712, 0x000b9c55, 0x000c0a23 }, | ||
| 2313 | { 136, 0x00002cd0, 0x0004471a, 0x000b9e55, 0x000c0a13 }, | ||
| 2314 | |||
| 2315 | /* 802.11 UNII */ | ||
| 2316 | { 140, 0x00002cd0, 0x00044722, 0x000b9e55, 0x000c0a03 }, | ||
| 2317 | { 149, 0x00002cd0, 0x0004472e, 0x000ba255, 0x000c0a1b }, | ||
| 2318 | { 153, 0x00002cd0, 0x00044736, 0x000ba255, 0x000c0a0b }, | ||
| 2319 | { 157, 0x00002cd4, 0x0004490a, 0x000ba255, 0x000c0a17 }, | ||
| 2320 | { 161, 0x00002cd4, 0x00044912, 0x000ba255, 0x000c0a17 }, | ||
| 2321 | { 165, 0x00002cd4, 0x0004491a, 0x000ba255, 0x000c0a17 }, | ||
| 2322 | |||
| 2323 | /* MMAC(Japan)J52 ch 34,38,42,46 */ | ||
| 2324 | { 34, 0x00002ccc, 0x0000499a, 0x0009be55, 0x000c0a0b }, | ||
| 2325 | { 38, 0x00002ccc, 0x0000499e, 0x0009be55, 0x000c0a13 }, | ||
| 2326 | { 42, 0x00002ccc, 0x000049a2, 0x0009be55, 0x000c0a1b }, | ||
| 2327 | { 46, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000c0a23 }, | ||
| 2328 | }; | ||
| 2329 | |||
| 2330 | static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | ||
| 2331 | { | ||
| 2332 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
| 2333 | u8 *txpower; | ||
| 2334 | unsigned int i; | ||
| 2335 | |||
| 2336 | /* | ||
| 2337 | * Initialize all hw fields. | ||
| 2338 | */ | ||
| 2339 | rt2x00dev->hw->flags = | ||
| 2340 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | ||
| 2341 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
| 2342 | IEEE80211_HW_MONITOR_DURING_OPER | | ||
| 2343 | IEEE80211_HW_NO_PROBE_FILTERING; | ||
| 2344 | rt2x00dev->hw->extra_tx_headroom = 0; | ||
| 2345 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | ||
| 2346 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | ||
| 2347 | rt2x00dev->hw->queues = 5; | ||
| 2348 | |||
| 2349 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | ||
| 2350 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | ||
| 2351 | rt2x00_eeprom_addr(rt2x00dev, | ||
| 2352 | EEPROM_MAC_ADDR_0)); | ||
| 2353 | |||
| 2354 | /* | ||
| 2355 | * Convert tx_power array in eeprom. | ||
| 2356 | */ | ||
| 2357 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); | ||
| 2358 | for (i = 0; i < 14; i++) | ||
| 2359 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | ||
| 2360 | |||
| 2361 | /* | ||
| 2362 | * Initialize hw_mode information. | ||
| 2363 | */ | ||
| 2364 | spec->num_modes = 2; | ||
| 2365 | spec->num_rates = 12; | ||
| 2366 | spec->tx_power_a = NULL; | ||
| 2367 | spec->tx_power_bg = txpower; | ||
| 2368 | spec->tx_power_default = DEFAULT_TXPOWER; | ||
| 2369 | |||
| 2370 | if (!test_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags)) { | ||
| 2371 | spec->num_channels = 14; | ||
| 2372 | spec->channels = rf_vals_noseq; | ||
| 2373 | } else { | ||
| 2374 | spec->num_channels = 14; | ||
| 2375 | spec->channels = rf_vals_seq; | ||
| 2376 | } | ||
| 2377 | |||
| 2378 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | ||
| 2379 | rt2x00_rf(&rt2x00dev->chip, RF5325)) { | ||
| 2380 | spec->num_modes = 3; | ||
| 2381 | spec->num_channels = ARRAY_SIZE(rf_vals_seq); | ||
| 2382 | |||
| 2383 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | ||
| 2384 | for (i = 0; i < 14; i++) | ||
| 2385 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | ||
| 2386 | |||
| 2387 | spec->tx_power_a = txpower; | ||
| 2388 | } | ||
| 2389 | } | ||
| 2390 | |||
| 2391 | static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | ||
| 2392 | { | ||
| 2393 | int retval; | ||
| 2394 | |||
| 2395 | /* | ||
| 2396 | * Allocate eeprom data. | ||
| 2397 | */ | ||
| 2398 | retval = rt61pci_validate_eeprom(rt2x00dev); | ||
| 2399 | if (retval) | ||
| 2400 | return retval; | ||
| 2401 | |||
| 2402 | retval = rt61pci_init_eeprom(rt2x00dev); | ||
| 2403 | if (retval) | ||
| 2404 | return retval; | ||
| 2405 | |||
| 2406 | /* | ||
| 2407 | * Initialize hw specifications. | ||
| 2408 | */ | ||
| 2409 | rt61pci_probe_hw_mode(rt2x00dev); | ||
| 2410 | |||
| 2411 | /* | ||
| 2412 | * This device requires firmware | ||
| 2413 | */ | ||
| 2414 | __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->flags); | ||
| 2415 | |||
| 2416 | /* | ||
| 2417 | * Set the rssi offset. | ||
| 2418 | */ | ||
| 2419 | rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET; | ||
| 2420 | |||
| 2421 | return 0; | ||
| 2422 | } | ||
| 2423 | |||
| 2424 | /* | ||
| 2425 | * IEEE80211 stack callback functions. | ||
| 2426 | */ | ||
| 2427 | static int rt61pci_set_retry_limit(struct ieee80211_hw *hw, | ||
| 2428 | u32 short_retry, u32 long_retry) | ||
| 2429 | { | ||
| 2430 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 2431 | u32 reg; | ||
| 2432 | |||
| 2433 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); | ||
| 2434 | rt2x00_set_field32(®, TXRX_CSR4_LONG_RETRY_LIMIT, long_retry); | ||
| 2435 | rt2x00_set_field32(®, TXRX_CSR4_SHORT_RETRY_LIMIT, short_retry); | ||
| 2436 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | ||
| 2437 | |||
| 2438 | return 0; | ||
| 2439 | } | ||
| 2440 | |||
| 2441 | static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) | ||
| 2442 | { | ||
| 2443 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 2444 | u64 tsf; | ||
| 2445 | u32 reg; | ||
| 2446 | |||
| 2447 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR13, ®); | ||
| 2448 | tsf = (u64) rt2x00_get_field32(reg, TXRX_CSR13_HIGH_TSFTIMER) << 32; | ||
| 2449 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR12, ®); | ||
| 2450 | tsf |= rt2x00_get_field32(reg, TXRX_CSR12_LOW_TSFTIMER); | ||
| 2451 | |||
| 2452 | return tsf; | ||
| 2453 | } | ||
| 2454 | |||
| 2455 | static void rt61pci_reset_tsf(struct ieee80211_hw *hw) | ||
| 2456 | { | ||
| 2457 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 2458 | |||
| 2459 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR12, 0); | ||
| 2460 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR13, 0); | ||
| 2461 | } | ||
| 2462 | |||
| 2463 | int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
| 2464 | struct ieee80211_tx_control *control) | ||
| 2465 | { | ||
| 2466 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 2467 | |||
| 2468 | /* | ||
| 2469 | * Just in case the ieee80211 doesn't set this, | ||
| 2470 | * but we need this queue set for the descriptor | ||
| 2471 | * initialization. | ||
| 2472 | */ | ||
| 2473 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
| 2474 | |||
| 2475 | /* | ||
| 2476 | * We need to append the descriptor in front of the | ||
| 2477 | * beacon frame. | ||
| 2478 | */ | ||
| 2479 | if (skb_headroom(skb) < TXD_DESC_SIZE) { | ||
| 2480 | if (pskb_expand_head(skb, TXD_DESC_SIZE, 0, GFP_ATOMIC)) { | ||
| 2481 | dev_kfree_skb(skb); | ||
| 2482 | return -ENOMEM; | ||
| 2483 | } | ||
| 2484 | } | ||
| 2485 | |||
| 2486 | /* | ||
| 2487 | * First we create the beacon. | ||
| 2488 | */ | ||
| 2489 | skb_push(skb, TXD_DESC_SIZE); | ||
| 2490 | rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data, | ||
| 2491 | (struct ieee80211_hdr *)(skb->data + | ||
| 2492 | TXD_DESC_SIZE), | ||
| 2493 | skb->len - TXD_DESC_SIZE, control); | ||
| 2494 | |||
| 2495 | /* | ||
| 2496 | * Write entire beacon with descriptor to register, | ||
| 2497 | * and kick the beacon generator. | ||
| 2498 | */ | ||
| 2499 | rt2x00pci_register_multiwrite(rt2x00dev, HW_BEACON_BASE0, skb->data, skb->len); | ||
| 2500 | rt61pci_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
| 2501 | |||
| 2502 | return 0; | ||
| 2503 | } | ||
| 2504 | |||
| 2505 | static const struct ieee80211_ops rt61pci_mac80211_ops = { | ||
| 2506 | .tx = rt2x00mac_tx, | ||
| 2507 | .add_interface = rt2x00mac_add_interface, | ||
| 2508 | .remove_interface = rt2x00mac_remove_interface, | ||
| 2509 | .config = rt2x00mac_config, | ||
| 2510 | .config_interface = rt2x00mac_config_interface, | ||
| 2511 | .set_multicast_list = rt2x00mac_set_multicast_list, | ||
| 2512 | .get_stats = rt2x00mac_get_stats, | ||
| 2513 | .set_retry_limit = rt61pci_set_retry_limit, | ||
| 2514 | .conf_tx = rt2x00mac_conf_tx, | ||
| 2515 | .get_tx_stats = rt2x00mac_get_tx_stats, | ||
| 2516 | .get_tsf = rt61pci_get_tsf, | ||
| 2517 | .reset_tsf = rt61pci_reset_tsf, | ||
| 2518 | .beacon_update = rt61pci_beacon_update, | ||
| 2519 | }; | ||
| 2520 | |||
| 2521 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | ||
| 2522 | .irq_handler = rt61pci_interrupt, | ||
| 2523 | .probe_hw = rt61pci_probe_hw, | ||
| 2524 | .get_firmware_name = rt61pci_get_firmware_name, | ||
| 2525 | .load_firmware = rt61pci_load_firmware, | ||
| 2526 | .initialize = rt2x00pci_initialize, | ||
| 2527 | .uninitialize = rt2x00pci_uninitialize, | ||
| 2528 | .set_device_state = rt61pci_set_device_state, | ||
| 2529 | #ifdef CONFIG_RT61PCI_RFKILL | ||
| 2530 | .rfkill_poll = rt61pci_rfkill_poll, | ||
| 2531 | #endif /* CONFIG_RT61PCI_RFKILL */ | ||
| 2532 | .link_stats = rt61pci_link_stats, | ||
| 2533 | .reset_tuner = rt61pci_reset_tuner, | ||
| 2534 | .link_tuner = rt61pci_link_tuner, | ||
| 2535 | .write_tx_desc = rt61pci_write_tx_desc, | ||
| 2536 | .write_tx_data = rt2x00pci_write_tx_data, | ||
| 2537 | .kick_tx_queue = rt61pci_kick_tx_queue, | ||
| 2538 | .fill_rxdone = rt61pci_fill_rxdone, | ||
| 2539 | .config_mac_addr = rt61pci_config_mac_addr, | ||
| 2540 | .config_bssid = rt61pci_config_bssid, | ||
| 2541 | .config_packet_filter = rt61pci_config_packet_filter, | ||
| 2542 | .config_type = rt61pci_config_type, | ||
| 2543 | .config = rt61pci_config, | ||
| 2544 | }; | ||
| 2545 | |||
| 2546 | static const struct rt2x00_ops rt61pci_ops = { | ||
| 2547 | .name = DRV_NAME, | ||
| 2548 | .rxd_size = RXD_DESC_SIZE, | ||
| 2549 | .txd_size = TXD_DESC_SIZE, | ||
| 2550 | .eeprom_size = EEPROM_SIZE, | ||
| 2551 | .rf_size = RF_SIZE, | ||
| 2552 | .lib = &rt61pci_rt2x00_ops, | ||
| 2553 | .hw = &rt61pci_mac80211_ops, | ||
| 2554 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
| 2555 | .debugfs = &rt61pci_rt2x00debug, | ||
| 2556 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
| 2557 | }; | ||
| 2558 | |||
| 2559 | /* | ||
| 2560 | * RT61pci module information. | ||
| 2561 | */ | ||
| 2562 | static struct pci_device_id rt61pci_device_table[] = { | ||
| 2563 | /* RT2561s */ | ||
| 2564 | { PCI_DEVICE(0x1814, 0x0301), PCI_DEVICE_DATA(&rt61pci_ops) }, | ||
| 2565 | /* RT2561 v2 */ | ||
| 2566 | { PCI_DEVICE(0x1814, 0x0302), PCI_DEVICE_DATA(&rt61pci_ops) }, | ||
| 2567 | /* RT2661 */ | ||
| 2568 | { PCI_DEVICE(0x1814, 0x0401), PCI_DEVICE_DATA(&rt61pci_ops) }, | ||
| 2569 | { 0, } | ||
| 2570 | }; | ||
| 2571 | |||
| 2572 | MODULE_AUTHOR(DRV_PROJECT); | ||
| 2573 | MODULE_VERSION(DRV_VERSION); | ||
| 2574 | MODULE_DESCRIPTION("Ralink RT61 PCI & PCMCIA Wireless LAN driver."); | ||
| 2575 | MODULE_SUPPORTED_DEVICE("Ralink RT2561, RT2561s & RT2661 " | ||
| 2576 | "PCI & PCMCIA chipset based cards"); | ||
| 2577 | MODULE_DEVICE_TABLE(pci, rt61pci_device_table); | ||
| 2578 | MODULE_FIRMWARE(FIRMWARE_RT2561); | ||
| 2579 | MODULE_FIRMWARE(FIRMWARE_RT2561s); | ||
| 2580 | MODULE_FIRMWARE(FIRMWARE_RT2661); | ||
| 2581 | MODULE_LICENSE("GPL"); | ||
| 2582 | |||
| 2583 | static struct pci_driver rt61pci_driver = { | ||
| 2584 | .name = DRV_NAME, | ||
| 2585 | .id_table = rt61pci_device_table, | ||
| 2586 | .probe = rt2x00pci_probe, | ||
| 2587 | .remove = __devexit_p(rt2x00pci_remove), | ||
| 2588 | .suspend = rt2x00pci_suspend, | ||
| 2589 | .resume = rt2x00pci_resume, | ||
| 2590 | }; | ||
| 2591 | |||
| 2592 | static int __init rt61pci_init(void) | ||
| 2593 | { | ||
| 2594 | return pci_register_driver(&rt61pci_driver); | ||
| 2595 | } | ||
| 2596 | |||
| 2597 | static void __exit rt61pci_exit(void) | ||
| 2598 | { | ||
| 2599 | pci_unregister_driver(&rt61pci_driver); | ||
| 2600 | } | ||
| 2601 | |||
| 2602 | module_init(rt61pci_init); | ||
| 2603 | module_exit(rt61pci_exit); | ||
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h new file mode 100644 index 00000000000..6721d7dd32b --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt61pci.h | |||
| @@ -0,0 +1,1457 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt61pci | ||
| 23 | Abstract: Data structures and registers for the rt61pci module. | ||
| 24 | Supported chipsets: RT2561, RT2561s, RT2661. | ||
| 25 | */ | ||
| 26 | |||
| 27 | #ifndef RT61PCI_H | ||
| 28 | #define RT61PCI_H | ||
| 29 | |||
| 30 | /* | ||
| 31 | * RF chip defines. | ||
| 32 | */ | ||
| 33 | #define RF5225 0x0001 | ||
| 34 | #define RF5325 0x0002 | ||
| 35 | #define RF2527 0x0003 | ||
| 36 | #define RF2529 0x0004 | ||
| 37 | |||
| 38 | /* | ||
| 39 | * Signal information. | ||
| 40 | * Defaul offset is required for RSSI <-> dBm conversion. | ||
| 41 | */ | ||
| 42 | #define MAX_SIGNAL 100 | ||
| 43 | #define MAX_RX_SSI -1 | ||
| 44 | #define DEFAULT_RSSI_OFFSET 120 | ||
| 45 | |||
| 46 | /* | ||
| 47 | * Register layout information. | ||
| 48 | */ | ||
| 49 | #define CSR_REG_BASE 0x3000 | ||
| 50 | #define CSR_REG_SIZE 0x04b0 | ||
| 51 | #define EEPROM_BASE 0x0000 | ||
| 52 | #define EEPROM_SIZE 0x0100 | ||
| 53 | #define BBP_SIZE 0x0080 | ||
| 54 | #define RF_SIZE 0x0014 | ||
| 55 | |||
| 56 | /* | ||
| 57 | * PCI registers. | ||
| 58 | */ | ||
| 59 | |||
| 60 | /* | ||
| 61 | * PCI Configuration Header | ||
| 62 | */ | ||
| 63 | #define PCI_CONFIG_HEADER_VENDOR 0x0000 | ||
| 64 | #define PCI_CONFIG_HEADER_DEVICE 0x0002 | ||
| 65 | |||
| 66 | /* | ||
| 67 | * HOST_CMD_CSR: For HOST to interrupt embedded processor | ||
| 68 | */ | ||
| 69 | #define HOST_CMD_CSR 0x0008 | ||
| 70 | #define HOST_CMD_CSR_HOST_COMMAND FIELD32(0x0000007f) | ||
| 71 | #define HOST_CMD_CSR_INTERRUPT_MCU FIELD32(0x00000080) | ||
| 72 | |||
| 73 | /* | ||
| 74 | * MCU_CNTL_CSR | ||
| 75 | * SELECT_BANK: Select 8051 program bank. | ||
| 76 | * RESET: Enable 8051 reset state. | ||
| 77 | * READY: Ready state for 8051. | ||
| 78 | */ | ||
| 79 | #define MCU_CNTL_CSR 0x000c | ||
| 80 | #define MCU_CNTL_CSR_SELECT_BANK FIELD32(0x00000001) | ||
| 81 | #define MCU_CNTL_CSR_RESET FIELD32(0x00000002) | ||
| 82 | #define MCU_CNTL_CSR_READY FIELD32(0x00000004) | ||
| 83 | |||
| 84 | /* | ||
| 85 | * SOFT_RESET_CSR | ||
| 86 | */ | ||
| 87 | #define SOFT_RESET_CSR 0x0010 | ||
| 88 | |||
| 89 | /* | ||
| 90 | * MCU_INT_SOURCE_CSR: MCU interrupt source/mask register. | ||
| 91 | */ | ||
| 92 | #define MCU_INT_SOURCE_CSR 0x0014 | ||
| 93 | #define MCU_INT_SOURCE_CSR_0 FIELD32(0x00000001) | ||
| 94 | #define MCU_INT_SOURCE_CSR_1 FIELD32(0x00000002) | ||
| 95 | #define MCU_INT_SOURCE_CSR_2 FIELD32(0x00000004) | ||
| 96 | #define MCU_INT_SOURCE_CSR_3 FIELD32(0x00000008) | ||
| 97 | #define MCU_INT_SOURCE_CSR_4 FIELD32(0x00000010) | ||
| 98 | #define MCU_INT_SOURCE_CSR_5 FIELD32(0x00000020) | ||
| 99 | #define MCU_INT_SOURCE_CSR_6 FIELD32(0x00000040) | ||
| 100 | #define MCU_INT_SOURCE_CSR_7 FIELD32(0x00000080) | ||
| 101 | #define MCU_INT_SOURCE_CSR_TWAKEUP FIELD32(0x00000100) | ||
| 102 | #define MCU_INT_SOURCE_CSR_TBTT_EXPIRE FIELD32(0x00000200) | ||
| 103 | |||
| 104 | /* | ||
| 105 | * MCU_INT_MASK_CSR: MCU interrupt source/mask register. | ||
| 106 | */ | ||
| 107 | #define MCU_INT_MASK_CSR 0x0018 | ||
| 108 | #define MCU_INT_MASK_CSR_0 FIELD32(0x00000001) | ||
| 109 | #define MCU_INT_MASK_CSR_1 FIELD32(0x00000002) | ||
| 110 | #define MCU_INT_MASK_CSR_2 FIELD32(0x00000004) | ||
| 111 | #define MCU_INT_MASK_CSR_3 FIELD32(0x00000008) | ||
| 112 | #define MCU_INT_MASK_CSR_4 FIELD32(0x00000010) | ||
| 113 | #define MCU_INT_MASK_CSR_5 FIELD32(0x00000020) | ||
| 114 | #define MCU_INT_MASK_CSR_6 FIELD32(0x00000040) | ||
| 115 | #define MCU_INT_MASK_CSR_7 FIELD32(0x00000080) | ||
| 116 | #define MCU_INT_MASK_CSR_TWAKEUP FIELD32(0x00000100) | ||
| 117 | #define MCU_INT_MASK_CSR_TBTT_EXPIRE FIELD32(0x00000200) | ||
| 118 | |||
| 119 | /* | ||
| 120 | * PCI_USEC_CSR | ||
| 121 | */ | ||
| 122 | #define PCI_USEC_CSR 0x001c | ||
| 123 | |||
| 124 | /* | ||
| 125 | * Security key table memory. | ||
| 126 | * 16 entries 32-byte for shared key table | ||
| 127 | * 64 entries 32-byte for pairwise key table | ||
| 128 | * 64 entries 8-byte for pairwise ta key table | ||
| 129 | */ | ||
| 130 | #define SHARED_KEY_TABLE_BASE 0x1000 | ||
| 131 | #define PAIRWISE_KEY_TABLE_BASE 0x1200 | ||
| 132 | #define PAIRWISE_TA_TABLE_BASE 0x1a00 | ||
| 133 | |||
| 134 | struct hw_key_entry { | ||
| 135 | u8 key[16]; | ||
| 136 | u8 tx_mic[8]; | ||
| 137 | u8 rx_mic[8]; | ||
| 138 | } __attribute__ ((packed)); | ||
| 139 | |||
| 140 | struct hw_pairwise_ta_entry { | ||
| 141 | u8 address[6]; | ||
| 142 | u8 reserved[2]; | ||
| 143 | } __attribute__ ((packed)); | ||
| 144 | |||
| 145 | /* | ||
| 146 | * Other on-chip shared memory space. | ||
| 147 | */ | ||
| 148 | #define HW_CIS_BASE 0x2000 | ||
| 149 | #define HW_NULL_BASE 0x2b00 | ||
| 150 | |||
| 151 | /* | ||
| 152 | * Since NULL frame won't be that long (256 byte), | ||
| 153 | * We steal 16 tail bytes to save debugging settings. | ||
| 154 | */ | ||
| 155 | #define HW_DEBUG_SETTING_BASE 0x2bf0 | ||
| 156 | |||
| 157 | /* | ||
| 158 | * On-chip BEACON frame space. | ||
| 159 | */ | ||
| 160 | #define HW_BEACON_BASE0 0x2c00 | ||
| 161 | #define HW_BEACON_BASE1 0x2d00 | ||
| 162 | #define HW_BEACON_BASE2 0x2e00 | ||
| 163 | #define HW_BEACON_BASE3 0x2f00 | ||
| 164 | #define HW_BEACON_OFFSET 0x0100 | ||
| 165 | |||
| 166 | /* | ||
| 167 | * HOST-MCU shared memory. | ||
| 168 | */ | ||
| 169 | |||
| 170 | /* | ||
| 171 | * H2M_MAILBOX_CSR: Host-to-MCU Mailbox. | ||
| 172 | */ | ||
| 173 | #define H2M_MAILBOX_CSR 0x2100 | ||
| 174 | #define H2M_MAILBOX_CSR_ARG0 FIELD32(0x000000ff) | ||
| 175 | #define H2M_MAILBOX_CSR_ARG1 FIELD32(0x0000ff00) | ||
| 176 | #define H2M_MAILBOX_CSR_CMD_TOKEN FIELD32(0x00ff0000) | ||
| 177 | #define H2M_MAILBOX_CSR_OWNER FIELD32(0xff000000) | ||
| 178 | |||
| 179 | /* | ||
| 180 | * MCU_LEDCS: LED control for MCU Mailbox. | ||
| 181 | */ | ||
| 182 | #define MCU_LEDCS_LED_MODE FIELD16(0x001f) | ||
| 183 | #define MCU_LEDCS_RADIO_STATUS FIELD16(0x0020) | ||
| 184 | #define MCU_LEDCS_LINK_BG_STATUS FIELD16(0x0040) | ||
| 185 | #define MCU_LEDCS_LINK_A_STATUS FIELD16(0x0080) | ||
| 186 | #define MCU_LEDCS_POLARITY_GPIO_0 FIELD16(0x0100) | ||
| 187 | #define MCU_LEDCS_POLARITY_GPIO_1 FIELD16(0x0200) | ||
| 188 | #define MCU_LEDCS_POLARITY_GPIO_2 FIELD16(0x0400) | ||
| 189 | #define MCU_LEDCS_POLARITY_GPIO_3 FIELD16(0x0800) | ||
| 190 | #define MCU_LEDCS_POLARITY_GPIO_4 FIELD16(0x1000) | ||
| 191 | #define MCU_LEDCS_POLARITY_ACT FIELD16(0x2000) | ||
| 192 | #define MCU_LEDCS_POLARITY_READY_BG FIELD16(0x4000) | ||
| 193 | #define MCU_LEDCS_POLARITY_READY_A FIELD16(0x8000) | ||
| 194 | |||
| 195 | /* | ||
| 196 | * M2H_CMD_DONE_CSR. | ||
| 197 | */ | ||
| 198 | #define M2H_CMD_DONE_CSR 0x2104 | ||
| 199 | |||
| 200 | /* | ||
| 201 | * MCU_TXOP_ARRAY_BASE. | ||
| 202 | */ | ||
| 203 | #define MCU_TXOP_ARRAY_BASE 0x2110 | ||
| 204 | |||
| 205 | /* | ||
| 206 | * MAC Control/Status Registers(CSR). | ||
| 207 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 208 | */ | ||
| 209 | |||
| 210 | /* | ||
| 211 | * MAC_CSR0: ASIC revision number. | ||
| 212 | */ | ||
| 213 | #define MAC_CSR0 0x3000 | ||
| 214 | |||
| 215 | /* | ||
| 216 | * MAC_CSR1: System control register. | ||
| 217 | * SOFT_RESET: Software reset bit, 1: reset, 0: normal. | ||
| 218 | * BBP_RESET: Hardware reset BBP. | ||
| 219 | * HOST_READY: Host is ready after initialization, 1: ready. | ||
| 220 | */ | ||
| 221 | #define MAC_CSR1 0x3004 | ||
| 222 | #define MAC_CSR1_SOFT_RESET FIELD32(0x00000001) | ||
| 223 | #define MAC_CSR1_BBP_RESET FIELD32(0x00000002) | ||
| 224 | #define MAC_CSR1_HOST_READY FIELD32(0x00000004) | ||
| 225 | |||
| 226 | /* | ||
| 227 | * MAC_CSR2: STA MAC register 0. | ||
| 228 | */ | ||
| 229 | #define MAC_CSR2 0x3008 | ||
| 230 | #define MAC_CSR2_BYTE0 FIELD32(0x000000ff) | ||
| 231 | #define MAC_CSR2_BYTE1 FIELD32(0x0000ff00) | ||
| 232 | #define MAC_CSR2_BYTE2 FIELD32(0x00ff0000) | ||
| 233 | #define MAC_CSR2_BYTE3 FIELD32(0xff000000) | ||
| 234 | |||
| 235 | /* | ||
| 236 | * MAC_CSR3: STA MAC register 1. | ||
| 237 | */ | ||
| 238 | #define MAC_CSR3 0x300c | ||
| 239 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) | ||
| 240 | #define MAC_CSR3_BYTE5 FIELD32(0x0000ff00) | ||
| 241 | #define MAC_CSR3_UNICAST_TO_ME_MASK FIELD32(0x00ff0000) | ||
| 242 | |||
| 243 | /* | ||
| 244 | * MAC_CSR4: BSSID register 0. | ||
| 245 | */ | ||
| 246 | #define MAC_CSR4 0x3010 | ||
| 247 | #define MAC_CSR4_BYTE0 FIELD32(0x000000ff) | ||
| 248 | #define MAC_CSR4_BYTE1 FIELD32(0x0000ff00) | ||
| 249 | #define MAC_CSR4_BYTE2 FIELD32(0x00ff0000) | ||
| 250 | #define MAC_CSR4_BYTE3 FIELD32(0xff000000) | ||
| 251 | |||
| 252 | /* | ||
| 253 | * MAC_CSR5: BSSID register 1. | ||
| 254 | * BSS_ID_MASK: 3: one BSSID, 0: 4 BSSID, 2 or 1: 2 BSSID. | ||
| 255 | */ | ||
| 256 | #define MAC_CSR5 0x3014 | ||
| 257 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) | ||
| 258 | #define MAC_CSR5_BYTE5 FIELD32(0x0000ff00) | ||
| 259 | #define MAC_CSR5_BSS_ID_MASK FIELD32(0x00ff0000) | ||
| 260 | |||
| 261 | /* | ||
| 262 | * MAC_CSR6: Maximum frame length register. | ||
| 263 | */ | ||
| 264 | #define MAC_CSR6 0x3018 | ||
| 265 | #define MAC_CSR6_MAX_FRAME_UNIT FIELD32(0x00000fff) | ||
| 266 | |||
| 267 | /* | ||
| 268 | * MAC_CSR7: Reserved | ||
| 269 | */ | ||
| 270 | #define MAC_CSR7 0x301c | ||
| 271 | |||
| 272 | /* | ||
| 273 | * MAC_CSR8: SIFS/EIFS register. | ||
| 274 | * All units are in US. | ||
| 275 | */ | ||
| 276 | #define MAC_CSR8 0x3020 | ||
| 277 | #define MAC_CSR8_SIFS FIELD32(0x000000ff) | ||
| 278 | #define MAC_CSR8_SIFS_AFTER_RX_OFDM FIELD32(0x0000ff00) | ||
| 279 | #define MAC_CSR8_EIFS FIELD32(0xffff0000) | ||
| 280 | |||
| 281 | /* | ||
| 282 | * MAC_CSR9: Back-Off control register. | ||
| 283 | * SLOT_TIME: Slot time, default is 20us for 802.11BG. | ||
| 284 | * CWMIN: Bit for Cwmin. default Cwmin is 31 (2^5 - 1). | ||
| 285 | * CWMAX: Bit for Cwmax, default Cwmax is 1023 (2^10 - 1). | ||
| 286 | * CW_SELECT: 1: CWmin/Cwmax select from register, 0:select from TxD. | ||
| 287 | */ | ||
| 288 | #define MAC_CSR9 0x3024 | ||
| 289 | #define MAC_CSR9_SLOT_TIME FIELD32(0x000000ff) | ||
| 290 | #define MAC_CSR9_CWMIN FIELD32(0x00000f00) | ||
| 291 | #define MAC_CSR9_CWMAX FIELD32(0x0000f000) | ||
| 292 | #define MAC_CSR9_CW_SELECT FIELD32(0x00010000) | ||
| 293 | |||
| 294 | /* | ||
| 295 | * MAC_CSR10: Power state configuration. | ||
| 296 | */ | ||
| 297 | #define MAC_CSR10 0x3028 | ||
| 298 | |||
| 299 | /* | ||
| 300 | * MAC_CSR11: Power saving transition time register. | ||
| 301 | * DELAY_AFTER_TBCN: Delay after Tbcn expired in units of TU. | ||
| 302 | * TBCN_BEFORE_WAKEUP: Number of beacon before wakeup. | ||
| 303 | * WAKEUP_LATENCY: In unit of TU. | ||
| 304 | */ | ||
| 305 | #define MAC_CSR11 0x302c | ||
| 306 | #define MAC_CSR11_DELAY_AFTER_TBCN FIELD32(0x000000ff) | ||
| 307 | #define MAC_CSR11_TBCN_BEFORE_WAKEUP FIELD32(0x00007f00) | ||
| 308 | #define MAC_CSR11_AUTOWAKE FIELD32(0x00008000) | ||
| 309 | #define MAC_CSR11_WAKEUP_LATENCY FIELD32(0x000f0000) | ||
| 310 | |||
| 311 | /* | ||
| 312 | * MAC_CSR12: Manual power control / status register (merge CSR20 & PWRCSR1). | ||
| 313 | * CURRENT_STATE: 0:sleep, 1:awake. | ||
| 314 | * FORCE_WAKEUP: This has higher priority than PUT_TO_SLEEP. | ||
| 315 | * BBP_CURRENT_STATE: 0: BBP sleep, 1: BBP awake. | ||
| 316 | */ | ||
| 317 | #define MAC_CSR12 0x3030 | ||
| 318 | #define MAC_CSR12_CURRENT_STATE FIELD32(0x00000001) | ||
| 319 | #define MAC_CSR12_PUT_TO_SLEEP FIELD32(0x00000002) | ||
| 320 | #define MAC_CSR12_FORCE_WAKEUP FIELD32(0x00000004) | ||
| 321 | #define MAC_CSR12_BBP_CURRENT_STATE FIELD32(0x00000008) | ||
| 322 | |||
| 323 | /* | ||
| 324 | * MAC_CSR13: GPIO. | ||
| 325 | */ | ||
| 326 | #define MAC_CSR13 0x3034 | ||
| 327 | #define MAC_CSR13_BIT0 FIELD32(0x00000001) | ||
| 328 | #define MAC_CSR13_BIT1 FIELD32(0x00000002) | ||
| 329 | #define MAC_CSR13_BIT2 FIELD32(0x00000004) | ||
| 330 | #define MAC_CSR13_BIT3 FIELD32(0x00000008) | ||
| 331 | #define MAC_CSR13_BIT4 FIELD32(0x00000010) | ||
| 332 | #define MAC_CSR13_BIT5 FIELD32(0x00000020) | ||
| 333 | #define MAC_CSR13_BIT6 FIELD32(0x00000040) | ||
| 334 | #define MAC_CSR13_BIT7 FIELD32(0x00000080) | ||
| 335 | #define MAC_CSR13_BIT8 FIELD32(0x00000100) | ||
| 336 | #define MAC_CSR13_BIT9 FIELD32(0x00000200) | ||
| 337 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) | ||
| 338 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) | ||
| 339 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) | ||
| 340 | |||
| 341 | /* | ||
| 342 | * MAC_CSR14: LED control register. | ||
| 343 | * ON_PERIOD: On period, default 70ms. | ||
| 344 | * OFF_PERIOD: Off period, default 30ms. | ||
| 345 | * HW_LED: HW TX activity, 1: normal OFF, 0: normal ON. | ||
| 346 | * SW_LED: s/w LED, 1: ON, 0: OFF. | ||
| 347 | * HW_LED_POLARITY: 0: active low, 1: active high. | ||
| 348 | */ | ||
| 349 | #define MAC_CSR14 0x3038 | ||
| 350 | #define MAC_CSR14_ON_PERIOD FIELD32(0x000000ff) | ||
| 351 | #define MAC_CSR14_OFF_PERIOD FIELD32(0x0000ff00) | ||
| 352 | #define MAC_CSR14_HW_LED FIELD32(0x00010000) | ||
| 353 | #define MAC_CSR14_SW_LED FIELD32(0x00020000) | ||
| 354 | #define MAC_CSR14_HW_LED_POLARITY FIELD32(0x00040000) | ||
| 355 | #define MAC_CSR14_SW_LED2 FIELD32(0x00080000) | ||
| 356 | |||
| 357 | /* | ||
| 358 | * MAC_CSR15: NAV control. | ||
| 359 | */ | ||
| 360 | #define MAC_CSR15 0x303c | ||
| 361 | |||
| 362 | /* | ||
| 363 | * TXRX control registers. | ||
| 364 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 365 | */ | ||
| 366 | |||
| 367 | /* | ||
| 368 | * TXRX_CSR0: TX/RX configuration register. | ||
| 369 | * TSF_OFFSET: Default is 24. | ||
| 370 | * AUTO_TX_SEQ: 1: ASIC auto replace sequence nr in outgoing frame. | ||
| 371 | * DISABLE_RX: Disable Rx engine. | ||
| 372 | * DROP_CRC: Drop CRC error. | ||
| 373 | * DROP_PHYSICAL: Drop physical error. | ||
| 374 | * DROP_CONTROL: Drop control frame. | ||
| 375 | * DROP_NOT_TO_ME: Drop not to me unicast frame. | ||
| 376 | * DROP_TO_DS: Drop fram ToDs bit is true. | ||
| 377 | * DROP_VERSION_ERROR: Drop version error frame. | ||
| 378 | * DROP_MULTICAST: Drop multicast frames. | ||
| 379 | * DROP_BORADCAST: Drop broadcast frames. | ||
| 380 | * ROP_ACK_CTS: Drop received ACK and CTS. | ||
| 381 | */ | ||
| 382 | #define TXRX_CSR0 0x3040 | ||
| 383 | #define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff) | ||
| 384 | #define TXRX_CSR0_TSF_OFFSET FIELD32(0x00007e00) | ||
| 385 | #define TXRX_CSR0_AUTO_TX_SEQ FIELD32(0x00008000) | ||
| 386 | #define TXRX_CSR0_DISABLE_RX FIELD32(0x00010000) | ||
| 387 | #define TXRX_CSR0_DROP_CRC FIELD32(0x00020000) | ||
| 388 | #define TXRX_CSR0_DROP_PHYSICAL FIELD32(0x00040000) | ||
| 389 | #define TXRX_CSR0_DROP_CONTROL FIELD32(0x00080000) | ||
| 390 | #define TXRX_CSR0_DROP_NOT_TO_ME FIELD32(0x00100000) | ||
| 391 | #define TXRX_CSR0_DROP_TO_DS FIELD32(0x00200000) | ||
| 392 | #define TXRX_CSR0_DROP_VERSION_ERROR FIELD32(0x00400000) | ||
| 393 | #define TXRX_CSR0_DROP_MULTICAST FIELD32(0x00800000) | ||
| 394 | #define TXRX_CSR0_DROP_BORADCAST FIELD32(0x01000000) | ||
| 395 | #define TXRX_CSR0_DROP_ACK_CTS FIELD32(0x02000000) | ||
| 396 | #define TXRX_CSR0_TX_WITHOUT_WAITING FIELD32(0x04000000) | ||
| 397 | |||
| 398 | /* | ||
| 399 | * TXRX_CSR1 | ||
| 400 | */ | ||
| 401 | #define TXRX_CSR1 0x3044 | ||
| 402 | #define TXRX_CSR1_BBP_ID0 FIELD32(0x0000007f) | ||
| 403 | #define TXRX_CSR1_BBP_ID0_VALID FIELD32(0x00000080) | ||
| 404 | #define TXRX_CSR1_BBP_ID1 FIELD32(0x00007f00) | ||
| 405 | #define TXRX_CSR1_BBP_ID1_VALID FIELD32(0x00008000) | ||
| 406 | #define TXRX_CSR1_BBP_ID2 FIELD32(0x007f0000) | ||
| 407 | #define TXRX_CSR1_BBP_ID2_VALID FIELD32(0x00800000) | ||
| 408 | #define TXRX_CSR1_BBP_ID3 FIELD32(0x7f000000) | ||
| 409 | #define TXRX_CSR1_BBP_ID3_VALID FIELD32(0x80000000) | ||
| 410 | |||
| 411 | /* | ||
| 412 | * TXRX_CSR2 | ||
| 413 | */ | ||
| 414 | #define TXRX_CSR2 0x3048 | ||
| 415 | #define TXRX_CSR2_BBP_ID0 FIELD32(0x0000007f) | ||
| 416 | #define TXRX_CSR2_BBP_ID0_VALID FIELD32(0x00000080) | ||
| 417 | #define TXRX_CSR2_BBP_ID1 FIELD32(0x00007f00) | ||
| 418 | #define TXRX_CSR2_BBP_ID1_VALID FIELD32(0x00008000) | ||
| 419 | #define TXRX_CSR2_BBP_ID2 FIELD32(0x007f0000) | ||
| 420 | #define TXRX_CSR2_BBP_ID2_VALID FIELD32(0x00800000) | ||
| 421 | #define TXRX_CSR2_BBP_ID3 FIELD32(0x7f000000) | ||
| 422 | #define TXRX_CSR2_BBP_ID3_VALID FIELD32(0x80000000) | ||
| 423 | |||
| 424 | /* | ||
| 425 | * TXRX_CSR3 | ||
| 426 | */ | ||
| 427 | #define TXRX_CSR3 0x304c | ||
| 428 | #define TXRX_CSR3_BBP_ID0 FIELD32(0x0000007f) | ||
| 429 | #define TXRX_CSR3_BBP_ID0_VALID FIELD32(0x00000080) | ||
| 430 | #define TXRX_CSR3_BBP_ID1 FIELD32(0x00007f00) | ||
| 431 | #define TXRX_CSR3_BBP_ID1_VALID FIELD32(0x00008000) | ||
| 432 | #define TXRX_CSR3_BBP_ID2 FIELD32(0x007f0000) | ||
| 433 | #define TXRX_CSR3_BBP_ID2_VALID FIELD32(0x00800000) | ||
| 434 | #define TXRX_CSR3_BBP_ID3 FIELD32(0x7f000000) | ||
| 435 | #define TXRX_CSR3_BBP_ID3_VALID FIELD32(0x80000000) | ||
| 436 | |||
| 437 | /* | ||
| 438 | * TXRX_CSR4: Auto-Responder/Tx-retry register. | ||
| 439 | * AUTORESPOND_PREAMBLE: 0:long, 1:short preamble. | ||
| 440 | * OFDM_TX_RATE_DOWN: 1:enable. | ||
| 441 | * OFDM_TX_RATE_STEP: 0:1-step, 1: 2-step, 2:3-step, 3:4-step. | ||
| 442 | * OFDM_TX_FALLBACK_CCK: 0: Fallback to OFDM 6M only, 1: Fallback to CCK 1M,2M. | ||
| 443 | */ | ||
| 444 | #define TXRX_CSR4 0x3050 | ||
| 445 | #define TXRX_CSR4_TX_ACK_TIMEOUT FIELD32(0x000000ff) | ||
| 446 | #define TXRX_CSR4_CNTL_ACK_POLICY FIELD32(0x00000700) | ||
| 447 | #define TXRX_CSR4_ACK_CTS_PSM FIELD32(0x00010000) | ||
| 448 | #define TXRX_CSR4_AUTORESPOND_ENABLE FIELD32(0x00020000) | ||
| 449 | #define TXRX_CSR4_AUTORESPOND_PREAMBLE FIELD32(0x00040000) | ||
| 450 | #define TXRX_CSR4_OFDM_TX_RATE_DOWN FIELD32(0x00080000) | ||
| 451 | #define TXRX_CSR4_OFDM_TX_RATE_STEP FIELD32(0x00300000) | ||
| 452 | #define TXRX_CSR4_OFDM_TX_FALLBACK_CCK FIELD32(0x00400000) | ||
| 453 | #define TXRX_CSR4_LONG_RETRY_LIMIT FIELD32(0x0f000000) | ||
| 454 | #define TXRX_CSR4_SHORT_RETRY_LIMIT FIELD32(0xf0000000) | ||
| 455 | |||
| 456 | /* | ||
| 457 | * TXRX_CSR5 | ||
| 458 | */ | ||
| 459 | #define TXRX_CSR5 0x3054 | ||
| 460 | |||
| 461 | /* | ||
| 462 | * TXRX_CSR6: ACK/CTS payload consumed time | ||
| 463 | */ | ||
| 464 | #define TXRX_CSR6 0x3058 | ||
| 465 | |||
| 466 | /* | ||
| 467 | * TXRX_CSR7: OFDM ACK/CTS payload consumed time for 6/9/12/18 mbps. | ||
| 468 | */ | ||
| 469 | #define TXRX_CSR7 0x305c | ||
| 470 | #define TXRX_CSR7_ACK_CTS_6MBS FIELD32(0x000000ff) | ||
| 471 | #define TXRX_CSR7_ACK_CTS_9MBS FIELD32(0x0000ff00) | ||
| 472 | #define TXRX_CSR7_ACK_CTS_12MBS FIELD32(0x00ff0000) | ||
| 473 | #define TXRX_CSR7_ACK_CTS_18MBS FIELD32(0xff000000) | ||
| 474 | |||
| 475 | /* | ||
| 476 | * TXRX_CSR8: OFDM ACK/CTS payload consumed time for 24/36/48/54 mbps. | ||
| 477 | */ | ||
| 478 | #define TXRX_CSR8 0x3060 | ||
| 479 | #define TXRX_CSR8_ACK_CTS_24MBS FIELD32(0x000000ff) | ||
| 480 | #define TXRX_CSR8_ACK_CTS_36MBS FIELD32(0x0000ff00) | ||
| 481 | #define TXRX_CSR8_ACK_CTS_48MBS FIELD32(0x00ff0000) | ||
| 482 | #define TXRX_CSR8_ACK_CTS_54MBS FIELD32(0xff000000) | ||
| 483 | |||
| 484 | /* | ||
| 485 | * TXRX_CSR9: Synchronization control register. | ||
| 486 | * BEACON_INTERVAL: In unit of 1/16 TU. | ||
| 487 | * TSF_TICKING: Enable TSF auto counting. | ||
| 488 | * TSF_SYNC: Tsf sync, 0: disable, 1: infra, 2: ad-hoc/master mode. | ||
| 489 | * BEACON_GEN: Enable beacon generator. | ||
| 490 | */ | ||
| 491 | #define TXRX_CSR9 0x3064 | ||
| 492 | #define TXRX_CSR9_BEACON_INTERVAL FIELD32(0x0000ffff) | ||
| 493 | #define TXRX_CSR9_TSF_TICKING FIELD32(0x00010000) | ||
| 494 | #define TXRX_CSR9_TSF_SYNC FIELD32(0x00060000) | ||
| 495 | #define TXRX_CSR9_TBTT_ENABLE FIELD32(0x00080000) | ||
| 496 | #define TXRX_CSR9_BEACON_GEN FIELD32(0x00100000) | ||
| 497 | #define TXRX_CSR9_TIMESTAMP_COMPENSATE FIELD32(0xff000000) | ||
| 498 | |||
| 499 | /* | ||
| 500 | * TXRX_CSR10: BEACON alignment. | ||
| 501 | */ | ||
| 502 | #define TXRX_CSR10 0x3068 | ||
| 503 | |||
| 504 | /* | ||
| 505 | * TXRX_CSR11: AES mask. | ||
| 506 | */ | ||
| 507 | #define TXRX_CSR11 0x306c | ||
| 508 | |||
| 509 | /* | ||
| 510 | * TXRX_CSR12: TSF low 32. | ||
| 511 | */ | ||
| 512 | #define TXRX_CSR12 0x3070 | ||
| 513 | #define TXRX_CSR12_LOW_TSFTIMER FIELD32(0xffffffff) | ||
| 514 | |||
| 515 | /* | ||
| 516 | * TXRX_CSR13: TSF high 32. | ||
| 517 | */ | ||
| 518 | #define TXRX_CSR13 0x3074 | ||
| 519 | #define TXRX_CSR13_HIGH_TSFTIMER FIELD32(0xffffffff) | ||
| 520 | |||
| 521 | /* | ||
| 522 | * TXRX_CSR14: TBTT timer. | ||
| 523 | */ | ||
| 524 | #define TXRX_CSR14 0x3078 | ||
| 525 | |||
| 526 | /* | ||
| 527 | * TXRX_CSR15: TKIP MIC priority byte "AND" mask. | ||
| 528 | */ | ||
| 529 | #define TXRX_CSR15 0x307c | ||
| 530 | |||
| 531 | /* | ||
| 532 | * PHY control registers. | ||
| 533 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 534 | */ | ||
| 535 | |||
| 536 | /* | ||
| 537 | * PHY_CSR0: RF/PS control. | ||
| 538 | */ | ||
| 539 | #define PHY_CSR0 0x3080 | ||
| 540 | #define PHY_CSR0_PA_PE_BG FIELD32(0x00010000) | ||
| 541 | #define PHY_CSR0_PA_PE_A FIELD32(0x00020000) | ||
| 542 | |||
| 543 | /* | ||
| 544 | * PHY_CSR1 | ||
| 545 | */ | ||
| 546 | #define PHY_CSR1 0x3084 | ||
| 547 | |||
| 548 | /* | ||
| 549 | * PHY_CSR2: Pre-TX BBP control. | ||
| 550 | */ | ||
| 551 | #define PHY_CSR2 0x3088 | ||
| 552 | |||
| 553 | /* | ||
| 554 | * PHY_CSR3: BBP serial control register. | ||
| 555 | * VALUE: Register value to program into BBP. | ||
| 556 | * REG_NUM: Selected BBP register. | ||
| 557 | * READ_CONTROL: 0: Write BBP, 1: Read BBP. | ||
| 558 | * BUSY: 1: ASIC is busy execute BBP programming. | ||
| 559 | */ | ||
| 560 | #define PHY_CSR3 0x308c | ||
| 561 | #define PHY_CSR3_VALUE FIELD32(0x000000ff) | ||
| 562 | #define PHY_CSR3_REGNUM FIELD32(0x00007f00) | ||
| 563 | #define PHY_CSR3_READ_CONTROL FIELD32(0x00008000) | ||
| 564 | #define PHY_CSR3_BUSY FIELD32(0x00010000) | ||
| 565 | |||
| 566 | /* | ||
| 567 | * PHY_CSR4: RF serial control register | ||
| 568 | * VALUE: Register value (include register id) serial out to RF/IF chip. | ||
| 569 | * NUMBER_OF_BITS: Number of bits used in RFRegValue (I:20, RFMD:22). | ||
| 570 | * IF_SELECT: 1: select IF to program, 0: select RF to program. | ||
| 571 | * PLL_LD: RF PLL_LD status. | ||
| 572 | * BUSY: 1: ASIC is busy execute RF programming. | ||
| 573 | */ | ||
| 574 | #define PHY_CSR4 0x3090 | ||
| 575 | #define PHY_CSR4_VALUE FIELD32(0x00ffffff) | ||
| 576 | #define PHY_CSR4_NUMBER_OF_BITS FIELD32(0x1f000000) | ||
| 577 | #define PHY_CSR4_IF_SELECT FIELD32(0x20000000) | ||
| 578 | #define PHY_CSR4_PLL_LD FIELD32(0x40000000) | ||
| 579 | #define PHY_CSR4_BUSY FIELD32(0x80000000) | ||
| 580 | |||
| 581 | /* | ||
| 582 | * PHY_CSR5: RX to TX signal switch timing control. | ||
| 583 | */ | ||
| 584 | #define PHY_CSR5 0x3094 | ||
| 585 | #define PHY_CSR5_IQ_FLIP FIELD32(0x00000004) | ||
| 586 | |||
| 587 | /* | ||
| 588 | * PHY_CSR6: TX to RX signal timing control. | ||
| 589 | */ | ||
| 590 | #define PHY_CSR6 0x3098 | ||
| 591 | #define PHY_CSR6_IQ_FLIP FIELD32(0x00000004) | ||
| 592 | |||
| 593 | /* | ||
| 594 | * PHY_CSR7: TX DAC switching timing control. | ||
| 595 | */ | ||
| 596 | #define PHY_CSR7 0x309c | ||
| 597 | |||
| 598 | /* | ||
| 599 | * Security control register. | ||
| 600 | */ | ||
| 601 | |||
| 602 | /* | ||
| 603 | * SEC_CSR0: Shared key table control. | ||
| 604 | */ | ||
| 605 | #define SEC_CSR0 0x30a0 | ||
| 606 | #define SEC_CSR0_BSS0_KEY0_VALID FIELD32(0x00000001) | ||
| 607 | #define SEC_CSR0_BSS0_KEY1_VALID FIELD32(0x00000002) | ||
| 608 | #define SEC_CSR0_BSS0_KEY2_VALID FIELD32(0x00000004) | ||
| 609 | #define SEC_CSR0_BSS0_KEY3_VALID FIELD32(0x00000008) | ||
| 610 | #define SEC_CSR0_BSS1_KEY0_VALID FIELD32(0x00000010) | ||
| 611 | #define SEC_CSR0_BSS1_KEY1_VALID FIELD32(0x00000020) | ||
| 612 | #define SEC_CSR0_BSS1_KEY2_VALID FIELD32(0x00000040) | ||
| 613 | #define SEC_CSR0_BSS1_KEY3_VALID FIELD32(0x00000080) | ||
| 614 | #define SEC_CSR0_BSS2_KEY0_VALID FIELD32(0x00000100) | ||
| 615 | #define SEC_CSR0_BSS2_KEY1_VALID FIELD32(0x00000200) | ||
| 616 | #define SEC_CSR0_BSS2_KEY2_VALID FIELD32(0x00000400) | ||
| 617 | #define SEC_CSR0_BSS2_KEY3_VALID FIELD32(0x00000800) | ||
| 618 | #define SEC_CSR0_BSS3_KEY0_VALID FIELD32(0x00001000) | ||
| 619 | #define SEC_CSR0_BSS3_KEY1_VALID FIELD32(0x00002000) | ||
| 620 | #define SEC_CSR0_BSS3_KEY2_VALID FIELD32(0x00004000) | ||
| 621 | #define SEC_CSR0_BSS3_KEY3_VALID FIELD32(0x00008000) | ||
| 622 | |||
| 623 | /* | ||
| 624 | * SEC_CSR1: Shared key table security mode register. | ||
| 625 | */ | ||
| 626 | #define SEC_CSR1 0x30a4 | ||
| 627 | #define SEC_CSR1_BSS0_KEY0_CIPHER_ALG FIELD32(0x00000007) | ||
| 628 | #define SEC_CSR1_BSS0_KEY1_CIPHER_ALG FIELD32(0x00000070) | ||
| 629 | #define SEC_CSR1_BSS0_KEY2_CIPHER_ALG FIELD32(0x00000700) | ||
| 630 | #define SEC_CSR1_BSS0_KEY3_CIPHER_ALG FIELD32(0x00007000) | ||
| 631 | #define SEC_CSR1_BSS1_KEY0_CIPHER_ALG FIELD32(0x00070000) | ||
| 632 | #define SEC_CSR1_BSS1_KEY1_CIPHER_ALG FIELD32(0x00700000) | ||
| 633 | #define SEC_CSR1_BSS1_KEY2_CIPHER_ALG FIELD32(0x07000000) | ||
| 634 | #define SEC_CSR1_BSS1_KEY3_CIPHER_ALG FIELD32(0x70000000) | ||
| 635 | |||
| 636 | /* | ||
| 637 | * Pairwise key table valid bitmap registers. | ||
| 638 | * SEC_CSR2: pairwise key table valid bitmap 0. | ||
| 639 | * SEC_CSR3: pairwise key table valid bitmap 1. | ||
| 640 | */ | ||
| 641 | #define SEC_CSR2 0x30a8 | ||
| 642 | #define SEC_CSR3 0x30ac | ||
| 643 | |||
| 644 | /* | ||
| 645 | * SEC_CSR4: Pairwise key table lookup control. | ||
| 646 | */ | ||
| 647 | #define SEC_CSR4 0x30b0 | ||
| 648 | |||
| 649 | /* | ||
| 650 | * SEC_CSR5: shared key table security mode register. | ||
| 651 | */ | ||
| 652 | #define SEC_CSR5 0x30b4 | ||
| 653 | #define SEC_CSR5_BSS2_KEY0_CIPHER_ALG FIELD32(0x00000007) | ||
| 654 | #define SEC_CSR5_BSS2_KEY1_CIPHER_ALG FIELD32(0x00000070) | ||
| 655 | #define SEC_CSR5_BSS2_KEY2_CIPHER_ALG FIELD32(0x00000700) | ||
| 656 | #define SEC_CSR5_BSS2_KEY3_CIPHER_ALG FIELD32(0x00007000) | ||
| 657 | #define SEC_CSR5_BSS3_KEY0_CIPHER_ALG FIELD32(0x00070000) | ||
| 658 | #define SEC_CSR5_BSS3_KEY1_CIPHER_ALG FIELD32(0x00700000) | ||
| 659 | #define SEC_CSR5_BSS3_KEY2_CIPHER_ALG FIELD32(0x07000000) | ||
| 660 | #define SEC_CSR5_BSS3_KEY3_CIPHER_ALG FIELD32(0x70000000) | ||
| 661 | |||
| 662 | /* | ||
| 663 | * STA control registers. | ||
| 664 | */ | ||
| 665 | |||
| 666 | /* | ||
| 667 | * STA_CSR0: RX PLCP error count & RX FCS error count. | ||
| 668 | */ | ||
| 669 | #define STA_CSR0 0x30c0 | ||
| 670 | #define STA_CSR0_FCS_ERROR FIELD32(0x0000ffff) | ||
| 671 | #define STA_CSR0_PLCP_ERROR FIELD32(0xffff0000) | ||
| 672 | |||
| 673 | /* | ||
| 674 | * STA_CSR1: RX False CCA count & RX LONG frame count. | ||
| 675 | */ | ||
| 676 | #define STA_CSR1 0x30c4 | ||
| 677 | #define STA_CSR1_PHYSICAL_ERROR FIELD32(0x0000ffff) | ||
| 678 | #define STA_CSR1_FALSE_CCA_ERROR FIELD32(0xffff0000) | ||
| 679 | |||
| 680 | /* | ||
| 681 | * STA_CSR2: TX Beacon count and RX FIFO overflow count. | ||
| 682 | */ | ||
| 683 | #define STA_CSR2 0x30c8 | ||
| 684 | #define STA_CSR2_RX_FIFO_OVERFLOW_COUNT FIELD32(0x0000ffff) | ||
| 685 | #define STA_CSR2_RX_OVERFLOW_COUNT FIELD32(0xffff0000) | ||
| 686 | |||
| 687 | /* | ||
| 688 | * STA_CSR3: TX Beacon count. | ||
| 689 | */ | ||
| 690 | #define STA_CSR3 0x30cc | ||
| 691 | #define STA_CSR3_TX_BEACON_COUNT FIELD32(0x0000ffff) | ||
| 692 | |||
| 693 | /* | ||
| 694 | * STA_CSR4: TX Result status register. | ||
| 695 | * VALID: 1:This register contains a valid TX result. | ||
| 696 | */ | ||
| 697 | #define STA_CSR4 0x30d0 | ||
| 698 | #define STA_CSR4_VALID FIELD32(0x00000001) | ||
| 699 | #define STA_CSR4_TX_RESULT FIELD32(0x0000000e) | ||
| 700 | #define STA_CSR4_RETRY_COUNT FIELD32(0x000000f0) | ||
| 701 | #define STA_CSR4_PID_SUBTYPE FIELD32(0x00001f00) | ||
| 702 | #define STA_CSR4_PID_TYPE FIELD32(0x0000e000) | ||
| 703 | #define STA_CSR4_TXRATE FIELD32(0x000f0000) | ||
| 704 | |||
| 705 | /* | ||
| 706 | * QOS control registers. | ||
| 707 | */ | ||
| 708 | |||
| 709 | /* | ||
| 710 | * QOS_CSR0: TXOP holder MAC address register. | ||
| 711 | */ | ||
| 712 | #define QOS_CSR0 0x30e0 | ||
| 713 | #define QOS_CSR0_BYTE0 FIELD32(0x000000ff) | ||
| 714 | #define QOS_CSR0_BYTE1 FIELD32(0x0000ff00) | ||
| 715 | #define QOS_CSR0_BYTE2 FIELD32(0x00ff0000) | ||
| 716 | #define QOS_CSR0_BYTE3 FIELD32(0xff000000) | ||
| 717 | |||
| 718 | /* | ||
| 719 | * QOS_CSR1: TXOP holder MAC address register. | ||
| 720 | */ | ||
| 721 | #define QOS_CSR1 0x30e4 | ||
| 722 | #define QOS_CSR1_BYTE4 FIELD32(0x000000ff) | ||
| 723 | #define QOS_CSR1_BYTE5 FIELD32(0x0000ff00) | ||
| 724 | |||
| 725 | /* | ||
| 726 | * QOS_CSR2: TXOP holder timeout register. | ||
| 727 | */ | ||
| 728 | #define QOS_CSR2 0x30e8 | ||
| 729 | |||
| 730 | /* | ||
| 731 | * RX QOS-CFPOLL MAC address register. | ||
| 732 | * QOS_CSR3: RX QOS-CFPOLL MAC address 0. | ||
| 733 | * QOS_CSR4: RX QOS-CFPOLL MAC address 1. | ||
| 734 | */ | ||
| 735 | #define QOS_CSR3 0x30ec | ||
| 736 | #define QOS_CSR4 0x30f0 | ||
| 737 | |||
| 738 | /* | ||
| 739 | * QOS_CSR5: "QosControl" field of the RX QOS-CFPOLL. | ||
| 740 | */ | ||
| 741 | #define QOS_CSR5 0x30f4 | ||
| 742 | |||
| 743 | /* | ||
| 744 | * Host DMA registers. | ||
| 745 | */ | ||
| 746 | |||
| 747 | /* | ||
| 748 | * AC0_BASE_CSR: AC_BK base address. | ||
| 749 | */ | ||
| 750 | #define AC0_BASE_CSR 0x3400 | ||
| 751 | #define AC0_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) | ||
| 752 | |||
| 753 | /* | ||
| 754 | * AC1_BASE_CSR: AC_BE base address. | ||
| 755 | */ | ||
| 756 | #define AC1_BASE_CSR 0x3404 | ||
| 757 | #define AC1_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) | ||
| 758 | |||
| 759 | /* | ||
| 760 | * AC2_BASE_CSR: AC_VI base address. | ||
| 761 | */ | ||
| 762 | #define AC2_BASE_CSR 0x3408 | ||
| 763 | #define AC2_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) | ||
| 764 | |||
| 765 | /* | ||
| 766 | * AC3_BASE_CSR: AC_VO base address. | ||
| 767 | */ | ||
| 768 | #define AC3_BASE_CSR 0x340c | ||
| 769 | #define AC3_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) | ||
| 770 | |||
| 771 | /* | ||
| 772 | * MGMT_BASE_CSR: MGMT ring base address. | ||
| 773 | */ | ||
| 774 | #define MGMT_BASE_CSR 0x3410 | ||
| 775 | #define MGMT_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) | ||
| 776 | |||
| 777 | /* | ||
| 778 | * TX_RING_CSR0: TX Ring size for AC_BK, AC_BE, AC_VI, AC_VO. | ||
| 779 | */ | ||
| 780 | #define TX_RING_CSR0 0x3418 | ||
| 781 | #define TX_RING_CSR0_AC0_RING_SIZE FIELD32(0x000000ff) | ||
| 782 | #define TX_RING_CSR0_AC1_RING_SIZE FIELD32(0x0000ff00) | ||
| 783 | #define TX_RING_CSR0_AC2_RING_SIZE FIELD32(0x00ff0000) | ||
| 784 | #define TX_RING_CSR0_AC3_RING_SIZE FIELD32(0xff000000) | ||
| 785 | |||
| 786 | /* | ||
| 787 | * TX_RING_CSR1: TX Ring size for MGMT Ring, HCCA Ring | ||
| 788 | * TXD_SIZE: In unit of 32-bit. | ||
| 789 | */ | ||
| 790 | #define TX_RING_CSR1 0x341c | ||
| 791 | #define TX_RING_CSR1_MGMT_RING_SIZE FIELD32(0x000000ff) | ||
| 792 | #define TX_RING_CSR1_HCCA_RING_SIZE FIELD32(0x0000ff00) | ||
| 793 | #define TX_RING_CSR1_TXD_SIZE FIELD32(0x003f0000) | ||
| 794 | |||
| 795 | /* | ||
| 796 | * AIFSN_CSR: AIFSN for each EDCA AC. | ||
| 797 | * AIFSN0: For AC_BK. | ||
| 798 | * AIFSN1: For AC_BE. | ||
| 799 | * AIFSN2: For AC_VI. | ||
| 800 | * AIFSN3: For AC_VO. | ||
| 801 | */ | ||
| 802 | #define AIFSN_CSR 0x3420 | ||
| 803 | #define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f) | ||
| 804 | #define AIFSN_CSR_AIFSN1 FIELD32(0x000000f0) | ||
| 805 | #define AIFSN_CSR_AIFSN2 FIELD32(0x00000f00) | ||
| 806 | #define AIFSN_CSR_AIFSN3 FIELD32(0x0000f000) | ||
| 807 | |||
| 808 | /* | ||
| 809 | * CWMIN_CSR: CWmin for each EDCA AC. | ||
| 810 | * CWMIN0: For AC_BK. | ||
| 811 | * CWMIN1: For AC_BE. | ||
| 812 | * CWMIN2: For AC_VI. | ||
| 813 | * CWMIN3: For AC_VO. | ||
| 814 | */ | ||
| 815 | #define CWMIN_CSR 0x3424 | ||
| 816 | #define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f) | ||
| 817 | #define CWMIN_CSR_CWMIN1 FIELD32(0x000000f0) | ||
| 818 | #define CWMIN_CSR_CWMIN2 FIELD32(0x00000f00) | ||
| 819 | #define CWMIN_CSR_CWMIN3 FIELD32(0x0000f000) | ||
| 820 | |||
| 821 | /* | ||
| 822 | * CWMAX_CSR: CWmax for each EDCA AC. | ||
| 823 | * CWMAX0: For AC_BK. | ||
| 824 | * CWMAX1: For AC_BE. | ||
| 825 | * CWMAX2: For AC_VI. | ||
| 826 | * CWMAX3: For AC_VO. | ||
| 827 | */ | ||
| 828 | #define CWMAX_CSR 0x3428 | ||
| 829 | #define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f) | ||
| 830 | #define CWMAX_CSR_CWMAX1 FIELD32(0x000000f0) | ||
| 831 | #define CWMAX_CSR_CWMAX2 FIELD32(0x00000f00) | ||
| 832 | #define CWMAX_CSR_CWMAX3 FIELD32(0x0000f000) | ||
| 833 | |||
| 834 | /* | ||
| 835 | * TX_DMA_DST_CSR: TX DMA destination | ||
| 836 | * 0: TX ring0, 1: TX ring1, 2: TX ring2 3: invalid | ||
| 837 | */ | ||
| 838 | #define TX_DMA_DST_CSR 0x342c | ||
| 839 | #define TX_DMA_DST_CSR_DEST_AC0 FIELD32(0x00000003) | ||
| 840 | #define TX_DMA_DST_CSR_DEST_AC1 FIELD32(0x0000000c) | ||
| 841 | #define TX_DMA_DST_CSR_DEST_AC2 FIELD32(0x00000030) | ||
| 842 | #define TX_DMA_DST_CSR_DEST_AC3 FIELD32(0x000000c0) | ||
| 843 | #define TX_DMA_DST_CSR_DEST_MGMT FIELD32(0x00000300) | ||
| 844 | |||
| 845 | /* | ||
| 846 | * TX_CNTL_CSR: KICK/Abort TX. | ||
| 847 | * KICK_TX_AC0: For AC_BK. | ||
| 848 | * KICK_TX_AC1: For AC_BE. | ||
| 849 | * KICK_TX_AC2: For AC_VI. | ||
| 850 | * KICK_TX_AC3: For AC_VO. | ||
| 851 | * ABORT_TX_AC0: For AC_BK. | ||
| 852 | * ABORT_TX_AC1: For AC_BE. | ||
| 853 | * ABORT_TX_AC2: For AC_VI. | ||
| 854 | * ABORT_TX_AC3: For AC_VO. | ||
| 855 | */ | ||
| 856 | #define TX_CNTL_CSR 0x3430 | ||
| 857 | #define TX_CNTL_CSR_KICK_TX_AC0 FIELD32(0x00000001) | ||
| 858 | #define TX_CNTL_CSR_KICK_TX_AC1 FIELD32(0x00000002) | ||
| 859 | #define TX_CNTL_CSR_KICK_TX_AC2 FIELD32(0x00000004) | ||
| 860 | #define TX_CNTL_CSR_KICK_TX_AC3 FIELD32(0x00000008) | ||
| 861 | #define TX_CNTL_CSR_KICK_TX_MGMT FIELD32(0x00000010) | ||
| 862 | #define TX_CNTL_CSR_ABORT_TX_AC0 FIELD32(0x00010000) | ||
| 863 | #define TX_CNTL_CSR_ABORT_TX_AC1 FIELD32(0x00020000) | ||
| 864 | #define TX_CNTL_CSR_ABORT_TX_AC2 FIELD32(0x00040000) | ||
| 865 | #define TX_CNTL_CSR_ABORT_TX_AC3 FIELD32(0x00080000) | ||
| 866 | #define TX_CNTL_CSR_ABORT_TX_MGMT FIELD32(0x00100000) | ||
| 867 | |||
| 868 | /* | ||
| 869 | * LOAD_TX_RING_CSR: Load RX de | ||
| 870 | */ | ||
| 871 | #define LOAD_TX_RING_CSR 0x3434 | ||
| 872 | #define LOAD_TX_RING_CSR_LOAD_TXD_AC0 FIELD32(0x00000001) | ||
| 873 | #define LOAD_TX_RING_CSR_LOAD_TXD_AC1 FIELD32(0x00000002) | ||
| 874 | #define LOAD_TX_RING_CSR_LOAD_TXD_AC2 FIELD32(0x00000004) | ||
| 875 | #define LOAD_TX_RING_CSR_LOAD_TXD_AC3 FIELD32(0x00000008) | ||
| 876 | #define LOAD_TX_RING_CSR_LOAD_TXD_MGMT FIELD32(0x00000010) | ||
| 877 | |||
| 878 | /* | ||
| 879 | * Several read-only registers, for debugging. | ||
| 880 | */ | ||
| 881 | #define AC0_TXPTR_CSR 0x3438 | ||
| 882 | #define AC1_TXPTR_CSR 0x343c | ||
| 883 | #define AC2_TXPTR_CSR 0x3440 | ||
| 884 | #define AC3_TXPTR_CSR 0x3444 | ||
| 885 | #define MGMT_TXPTR_CSR 0x3448 | ||
| 886 | |||
| 887 | /* | ||
| 888 | * RX_BASE_CSR | ||
| 889 | */ | ||
| 890 | #define RX_BASE_CSR 0x3450 | ||
| 891 | #define RX_BASE_CSR_RING_REGISTER FIELD32(0xffffffff) | ||
| 892 | |||
| 893 | /* | ||
| 894 | * RX_RING_CSR. | ||
| 895 | * RXD_SIZE: In unit of 32-bit. | ||
| 896 | */ | ||
| 897 | #define RX_RING_CSR 0x3454 | ||
| 898 | #define RX_RING_CSR_RING_SIZE FIELD32(0x000000ff) | ||
| 899 | #define RX_RING_CSR_RXD_SIZE FIELD32(0x00003f00) | ||
| 900 | #define RX_RING_CSR_RXD_WRITEBACK_SIZE FIELD32(0x00070000) | ||
| 901 | |||
| 902 | /* | ||
| 903 | * RX_CNTL_CSR | ||
| 904 | */ | ||
| 905 | #define RX_CNTL_CSR 0x3458 | ||
| 906 | #define RX_CNTL_CSR_ENABLE_RX_DMA FIELD32(0x00000001) | ||
| 907 | #define RX_CNTL_CSR_LOAD_RXD FIELD32(0x00000002) | ||
| 908 | |||
| 909 | /* | ||
| 910 | * RXPTR_CSR: Read-only, for debugging. | ||
| 911 | */ | ||
| 912 | #define RXPTR_CSR 0x345c | ||
| 913 | |||
| 914 | /* | ||
| 915 | * PCI_CFG_CSR | ||
| 916 | */ | ||
| 917 | #define PCI_CFG_CSR 0x3460 | ||
| 918 | |||
| 919 | /* | ||
| 920 | * BUF_FORMAT_CSR | ||
| 921 | */ | ||
| 922 | #define BUF_FORMAT_CSR 0x3464 | ||
| 923 | |||
| 924 | /* | ||
| 925 | * INT_SOURCE_CSR: Interrupt source register. | ||
| 926 | * Write one to clear corresponding bit. | ||
| 927 | */ | ||
| 928 | #define INT_SOURCE_CSR 0x3468 | ||
| 929 | #define INT_SOURCE_CSR_TXDONE FIELD32(0x00000001) | ||
| 930 | #define INT_SOURCE_CSR_RXDONE FIELD32(0x00000002) | ||
| 931 | #define INT_SOURCE_CSR_BEACON_DONE FIELD32(0x00000004) | ||
| 932 | #define INT_SOURCE_CSR_TX_ABORT_DONE FIELD32(0x00000010) | ||
| 933 | #define INT_SOURCE_CSR_AC0_DMA_DONE FIELD32(0x00010000) | ||
| 934 | #define INT_SOURCE_CSR_AC1_DMA_DONE FIELD32(0x00020000) | ||
| 935 | #define INT_SOURCE_CSR_AC2_DMA_DONE FIELD32(0x00040000) | ||
| 936 | #define INT_SOURCE_CSR_AC3_DMA_DONE FIELD32(0x00080000) | ||
| 937 | #define INT_SOURCE_CSR_MGMT_DMA_DONE FIELD32(0x00100000) | ||
| 938 | #define INT_SOURCE_CSR_HCCA_DMA_DONE FIELD32(0x00200000) | ||
| 939 | |||
| 940 | /* | ||
| 941 | * INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF. | ||
| 942 | * MITIGATION_PERIOD: Interrupt mitigation in unit of 32 PCI clock. | ||
| 943 | */ | ||
| 944 | #define INT_MASK_CSR 0x346c | ||
| 945 | #define INT_MASK_CSR_TXDONE FIELD32(0x00000001) | ||
| 946 | #define INT_MASK_CSR_RXDONE FIELD32(0x00000002) | ||
| 947 | #define INT_MASK_CSR_BEACON_DONE FIELD32(0x00000004) | ||
| 948 | #define INT_MASK_CSR_TX_ABORT_DONE FIELD32(0x00000010) | ||
| 949 | #define INT_MASK_CSR_ENABLE_MITIGATION FIELD32(0x00000080) | ||
| 950 | #define INT_MASK_CSR_MITIGATION_PERIOD FIELD32(0x0000ff00) | ||
| 951 | #define INT_MASK_CSR_AC0_DMA_DONE FIELD32(0x00010000) | ||
| 952 | #define INT_MASK_CSR_AC1_DMA_DONE FIELD32(0x00020000) | ||
| 953 | #define INT_MASK_CSR_AC2_DMA_DONE FIELD32(0x00040000) | ||
| 954 | #define INT_MASK_CSR_AC3_DMA_DONE FIELD32(0x00080000) | ||
| 955 | #define INT_MASK_CSR_MGMT_DMA_DONE FIELD32(0x00100000) | ||
| 956 | #define INT_MASK_CSR_HCCA_DMA_DONE FIELD32(0x00200000) | ||
| 957 | |||
| 958 | /* | ||
| 959 | * E2PROM_CSR: EEPROM control register. | ||
| 960 | * RELOAD: Write 1 to reload eeprom content. | ||
| 961 | * TYPE_93C46: 1: 93c46, 0:93c66. | ||
| 962 | * LOAD_STATUS: 1:loading, 0:done. | ||
| 963 | */ | ||
| 964 | #define E2PROM_CSR 0x3470 | ||
| 965 | #define E2PROM_CSR_RELOAD FIELD32(0x00000001) | ||
| 966 | #define E2PROM_CSR_DATA_CLOCK FIELD32(0x00000002) | ||
| 967 | #define E2PROM_CSR_CHIP_SELECT FIELD32(0x00000004) | ||
| 968 | #define E2PROM_CSR_DATA_IN FIELD32(0x00000008) | ||
| 969 | #define E2PROM_CSR_DATA_OUT FIELD32(0x00000010) | ||
| 970 | #define E2PROM_CSR_TYPE_93C46 FIELD32(0x00000020) | ||
| 971 | #define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040) | ||
| 972 | |||
| 973 | /* | ||
| 974 | * AC_TXOP_CSR0: AC_BK/AC_BE TXOP register. | ||
| 975 | * AC0_TX_OP: For AC_BK, in unit of 32us. | ||
| 976 | * AC1_TX_OP: For AC_BE, in unit of 32us. | ||
| 977 | */ | ||
| 978 | #define AC_TXOP_CSR0 0x3474 | ||
| 979 | #define AC_TXOP_CSR0_AC0_TX_OP FIELD32(0x0000ffff) | ||
| 980 | #define AC_TXOP_CSR0_AC1_TX_OP FIELD32(0xffff0000) | ||
| 981 | |||
| 982 | /* | ||
| 983 | * AC_TXOP_CSR1: AC_VO/AC_VI TXOP register. | ||
| 984 | * AC2_TX_OP: For AC_VI, in unit of 32us. | ||
| 985 | * AC3_TX_OP: For AC_VO, in unit of 32us. | ||
| 986 | */ | ||
| 987 | #define AC_TXOP_CSR1 0x3478 | ||
| 988 | #define AC_TXOP_CSR1_AC2_TX_OP FIELD32(0x0000ffff) | ||
| 989 | #define AC_TXOP_CSR1_AC3_TX_OP FIELD32(0xffff0000) | ||
| 990 | |||
| 991 | /* | ||
| 992 | * DMA_STATUS_CSR | ||
| 993 | */ | ||
| 994 | #define DMA_STATUS_CSR 0x3480 | ||
| 995 | |||
| 996 | /* | ||
| 997 | * TEST_MODE_CSR | ||
| 998 | */ | ||
| 999 | #define TEST_MODE_CSR 0x3484 | ||
| 1000 | |||
| 1001 | /* | ||
| 1002 | * UART0_TX_CSR | ||
| 1003 | */ | ||
| 1004 | #define UART0_TX_CSR 0x3488 | ||
| 1005 | |||
| 1006 | /* | ||
| 1007 | * UART0_RX_CSR | ||
| 1008 | */ | ||
| 1009 | #define UART0_RX_CSR 0x348c | ||
| 1010 | |||
| 1011 | /* | ||
| 1012 | * UART0_FRAME_CSR | ||
| 1013 | */ | ||
| 1014 | #define UART0_FRAME_CSR 0x3490 | ||
| 1015 | |||
| 1016 | /* | ||
| 1017 | * UART0_BUFFER_CSR | ||
| 1018 | */ | ||
| 1019 | #define UART0_BUFFER_CSR 0x3494 | ||
| 1020 | |||
| 1021 | /* | ||
| 1022 | * IO_CNTL_CSR | ||
| 1023 | */ | ||
| 1024 | #define IO_CNTL_CSR 0x3498 | ||
| 1025 | |||
| 1026 | /* | ||
| 1027 | * UART_INT_SOURCE_CSR | ||
| 1028 | */ | ||
| 1029 | #define UART_INT_SOURCE_CSR 0x34a8 | ||
| 1030 | |||
| 1031 | /* | ||
| 1032 | * UART_INT_MASK_CSR | ||
| 1033 | */ | ||
| 1034 | #define UART_INT_MASK_CSR 0x34ac | ||
| 1035 | |||
| 1036 | /* | ||
| 1037 | * PBF_QUEUE_CSR | ||
| 1038 | */ | ||
| 1039 | #define PBF_QUEUE_CSR 0x34b0 | ||
| 1040 | |||
| 1041 | /* | ||
| 1042 | * Firmware DMA registers. | ||
| 1043 | * Firmware DMA registers are dedicated for MCU usage | ||
| 1044 | * and should not be touched by host driver. | ||
| 1045 | * Therefore we skip the definition of these registers. | ||
| 1046 | */ | ||
| 1047 | #define FW_TX_BASE_CSR 0x34c0 | ||
| 1048 | #define FW_TX_START_CSR 0x34c4 | ||
| 1049 | #define FW_TX_LAST_CSR 0x34c8 | ||
| 1050 | #define FW_MODE_CNTL_CSR 0x34cc | ||
| 1051 | #define FW_TXPTR_CSR 0x34d0 | ||
| 1052 | |||
| 1053 | /* | ||
| 1054 | * 8051 firmware image. | ||
| 1055 | */ | ||
| 1056 | #define FIRMWARE_RT2561 "rt2561.bin" | ||
| 1057 | #define FIRMWARE_RT2561s "rt2561s.bin" | ||
| 1058 | #define FIRMWARE_RT2661 "rt2661.bin" | ||
| 1059 | #define FIRMWARE_IMAGE_BASE 0x4000 | ||
| 1060 | |||
| 1061 | /* | ||
| 1062 | * BBP registers. | ||
| 1063 | * The wordsize of the BBP is 8 bits. | ||
| 1064 | */ | ||
| 1065 | |||
| 1066 | /* | ||
| 1067 | * R2 | ||
| 1068 | */ | ||
| 1069 | #define BBP_R2_BG_MODE FIELD8(0x20) | ||
| 1070 | |||
| 1071 | /* | ||
| 1072 | * R3 | ||
| 1073 | */ | ||
| 1074 | #define BBP_R3_SMART_MODE FIELD8(0x01) | ||
| 1075 | |||
| 1076 | /* | ||
| 1077 | * R4: RX antenna control | ||
| 1078 | * FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529) | ||
| 1079 | */ | ||
| 1080 | #define BBP_R4_RX_ANTENNA FIELD8(0x03) | ||
| 1081 | #define BBP_R4_RX_FRAME_END FIELD8(0x20) | ||
| 1082 | |||
| 1083 | /* | ||
| 1084 | * R77 | ||
| 1085 | */ | ||
| 1086 | #define BBP_R77_PAIR FIELD8(0x03) | ||
| 1087 | |||
| 1088 | /* | ||
| 1089 | * RF registers | ||
| 1090 | */ | ||
| 1091 | |||
| 1092 | /* | ||
| 1093 | * RF 3 | ||
| 1094 | */ | ||
| 1095 | #define RF3_TXPOWER FIELD32(0x00003e00) | ||
| 1096 | |||
| 1097 | /* | ||
| 1098 | * RF 4 | ||
| 1099 | */ | ||
| 1100 | #define RF4_FREQ_OFFSET FIELD32(0x0003f000) | ||
| 1101 | |||
| 1102 | /* | ||
| 1103 | * EEPROM content. | ||
| 1104 | * The wordsize of the EEPROM is 16 bits. | ||
| 1105 | */ | ||
| 1106 | |||
| 1107 | /* | ||
| 1108 | * HW MAC address. | ||
| 1109 | */ | ||
| 1110 | #define EEPROM_MAC_ADDR_0 0x0002 | ||
| 1111 | #define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff) | ||
| 1112 | #define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00) | ||
| 1113 | #define EEPROM_MAC_ADDR1 0x0004 | ||
| 1114 | #define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff) | ||
| 1115 | #define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00) | ||
| 1116 | #define EEPROM_MAC_ADDR_2 0x0006 | ||
| 1117 | #define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff) | ||
| 1118 | #define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) | ||
| 1119 | |||
| 1120 | /* | ||
| 1121 | * EEPROM antenna. | ||
| 1122 | * ANTENNA_NUM: Number of antenna's. | ||
| 1123 | * TX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B. | ||
| 1124 | * RX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B. | ||
| 1125 | * FRAME_TYPE: 0: DPDT , 1: SPDT , noted this bit is valid for g only. | ||
| 1126 | * DYN_TXAGC: Dynamic TX AGC control. | ||
| 1127 | * HARDWARE_RADIO: 1: Hardware controlled radio. Read GPIO0. | ||
| 1128 | * RF_TYPE: Rf_type of this adapter. | ||
| 1129 | */ | ||
| 1130 | #define EEPROM_ANTENNA 0x0010 | ||
| 1131 | #define EEPROM_ANTENNA_NUM FIELD16(0x0003) | ||
| 1132 | #define EEPROM_ANTENNA_TX_DEFAULT FIELD16(0x000c) | ||
| 1133 | #define EEPROM_ANTENNA_RX_DEFAULT FIELD16(0x0030) | ||
| 1134 | #define EEPROM_ANTENNA_FRAME_TYPE FIELD16(0x0040) | ||
| 1135 | #define EEPROM_ANTENNA_DYN_TXAGC FIELD16(0x0200) | ||
| 1136 | #define EEPROM_ANTENNA_HARDWARE_RADIO FIELD16(0x0400) | ||
| 1137 | #define EEPROM_ANTENNA_RF_TYPE FIELD16(0xf800) | ||
| 1138 | |||
| 1139 | /* | ||
| 1140 | * EEPROM NIC config. | ||
| 1141 | * ENABLE_DIVERSITY: 1:enable, 0:disable. | ||
| 1142 | * EXTERNAL_LNA_BG: External LNA enable for 2.4G. | ||
| 1143 | * CARDBUS_ACCEL: 0:enable, 1:disable. | ||
| 1144 | * EXTERNAL_LNA_A: External LNA enable for 5G. | ||
| 1145 | */ | ||
| 1146 | #define EEPROM_NIC 0x0011 | ||
| 1147 | #define EEPROM_NIC_ENABLE_DIVERSITY FIELD16(0x0001) | ||
| 1148 | #define EEPROM_NIC_TX_DIVERSITY FIELD16(0x0002) | ||
| 1149 | #define EEPROM_NIC_TX_RX_FIXED FIELD16(0x000c) | ||
| 1150 | #define EEPROM_NIC_EXTERNAL_LNA_BG FIELD16(0x0010) | ||
| 1151 | #define EEPROM_NIC_CARDBUS_ACCEL FIELD16(0x0020) | ||
| 1152 | #define EEPROM_NIC_EXTERNAL_LNA_A FIELD16(0x0040) | ||
| 1153 | |||
| 1154 | /* | ||
| 1155 | * EEPROM geography. | ||
| 1156 | * GEO_A: Default geographical setting for 5GHz band | ||
| 1157 | * GEO: Default geographical setting. | ||
| 1158 | */ | ||
| 1159 | #define EEPROM_GEOGRAPHY 0x0012 | ||
| 1160 | #define EEPROM_GEOGRAPHY_GEO_A FIELD16(0x00ff) | ||
| 1161 | #define EEPROM_GEOGRAPHY_GEO FIELD16(0xff00) | ||
| 1162 | |||
| 1163 | /* | ||
| 1164 | * EEPROM BBP. | ||
| 1165 | */ | ||
| 1166 | #define EEPROM_BBP_START 0x0013 | ||
| 1167 | #define EEPROM_BBP_SIZE 16 | ||
| 1168 | #define EEPROM_BBP_VALUE FIELD16(0x00ff) | ||
| 1169 | #define EEPROM_BBP_REG_ID FIELD16(0xff00) | ||
| 1170 | |||
| 1171 | /* | ||
| 1172 | * EEPROM TXPOWER 802.11G | ||
| 1173 | */ | ||
| 1174 | #define EEPROM_TXPOWER_G_START 0x0023 | ||
| 1175 | #define EEPROM_TXPOWER_G_SIZE 7 | ||
| 1176 | #define EEPROM_TXPOWER_G_1 FIELD16(0x00ff) | ||
| 1177 | #define EEPROM_TXPOWER_G_2 FIELD16(0xff00) | ||
| 1178 | |||
| 1179 | /* | ||
| 1180 | * EEPROM Frequency | ||
| 1181 | */ | ||
| 1182 | #define EEPROM_FREQ 0x002f | ||
| 1183 | #define EEPROM_FREQ_OFFSET FIELD16(0x00ff) | ||
| 1184 | #define EEPROM_FREQ_SEQ_MASK FIELD16(0xff00) | ||
| 1185 | #define EEPROM_FREQ_SEQ FIELD16(0x0300) | ||
| 1186 | |||
| 1187 | /* | ||
| 1188 | * EEPROM LED. | ||
| 1189 | * POLARITY_RDY_G: Polarity RDY_G setting. | ||
| 1190 | * POLARITY_RDY_A: Polarity RDY_A setting. | ||
| 1191 | * POLARITY_ACT: Polarity ACT setting. | ||
| 1192 | * POLARITY_GPIO_0: Polarity GPIO0 setting. | ||
| 1193 | * POLARITY_GPIO_1: Polarity GPIO1 setting. | ||
| 1194 | * POLARITY_GPIO_2: Polarity GPIO2 setting. | ||
| 1195 | * POLARITY_GPIO_3: Polarity GPIO3 setting. | ||
| 1196 | * POLARITY_GPIO_4: Polarity GPIO4 setting. | ||
| 1197 | * LED_MODE: Led mode. | ||
| 1198 | */ | ||
| 1199 | #define EEPROM_LED 0x0030 | ||
| 1200 | #define EEPROM_LED_POLARITY_RDY_G FIELD16(0x0001) | ||
| 1201 | #define EEPROM_LED_POLARITY_RDY_A FIELD16(0x0002) | ||
| 1202 | #define EEPROM_LED_POLARITY_ACT FIELD16(0x0004) | ||
| 1203 | #define EEPROM_LED_POLARITY_GPIO_0 FIELD16(0x0008) | ||
| 1204 | #define EEPROM_LED_POLARITY_GPIO_1 FIELD16(0x0010) | ||
| 1205 | #define EEPROM_LED_POLARITY_GPIO_2 FIELD16(0x0020) | ||
| 1206 | #define EEPROM_LED_POLARITY_GPIO_3 FIELD16(0x0040) | ||
| 1207 | #define EEPROM_LED_POLARITY_GPIO_4 FIELD16(0x0080) | ||
| 1208 | #define EEPROM_LED_LED_MODE FIELD16(0x1f00) | ||
| 1209 | |||
| 1210 | /* | ||
| 1211 | * EEPROM TXPOWER 802.11A | ||
| 1212 | */ | ||
| 1213 | #define EEPROM_TXPOWER_A_START 0x0031 | ||
| 1214 | #define EEPROM_TXPOWER_A_SIZE 12 | ||
| 1215 | #define EEPROM_TXPOWER_A_1 FIELD16(0x00ff) | ||
| 1216 | #define EEPROM_TXPOWER_A_2 FIELD16(0xff00) | ||
| 1217 | |||
| 1218 | /* | ||
| 1219 | * EEPROM RSSI offset 802.11BG | ||
| 1220 | */ | ||
| 1221 | #define EEPROM_RSSI_OFFSET_BG 0x004d | ||
| 1222 | #define EEPROM_RSSI_OFFSET_BG_1 FIELD16(0x00ff) | ||
| 1223 | #define EEPROM_RSSI_OFFSET_BG_2 FIELD16(0xff00) | ||
| 1224 | |||
| 1225 | /* | ||
| 1226 | * EEPROM RSSI offset 802.11A | ||
| 1227 | */ | ||
| 1228 | #define EEPROM_RSSI_OFFSET_A 0x004e | ||
| 1229 | #define EEPROM_RSSI_OFFSET_A_1 FIELD16(0x00ff) | ||
| 1230 | #define EEPROM_RSSI_OFFSET_A_2 FIELD16(0xff00) | ||
| 1231 | |||
| 1232 | /* | ||
| 1233 | * MCU mailbox commands. | ||
| 1234 | */ | ||
| 1235 | #define MCU_SLEEP 0x30 | ||
| 1236 | #define MCU_WAKEUP 0x31 | ||
| 1237 | #define MCU_LED 0x50 | ||
| 1238 | #define MCU_LED_STRENGTH 0x52 | ||
| 1239 | |||
| 1240 | /* | ||
| 1241 | * DMA descriptor defines. | ||
| 1242 | */ | ||
| 1243 | #define TXD_DESC_SIZE ( 16 * sizeof(struct data_desc) ) | ||
| 1244 | #define RXD_DESC_SIZE ( 16 * sizeof(struct data_desc) ) | ||
| 1245 | |||
| 1246 | /* | ||
| 1247 | * TX descriptor format for TX, PRIO and Beacon Ring. | ||
| 1248 | */ | ||
| 1249 | |||
| 1250 | /* | ||
| 1251 | * Word0 | ||
| 1252 | * TKIP_MIC: ASIC appends TKIP MIC if TKIP is used. | ||
| 1253 | * KEY_TABLE: Use per-client pairwise KEY table. | ||
| 1254 | * KEY_INDEX: | ||
| 1255 | * Key index (0~31) to the pairwise KEY table. | ||
| 1256 | * 0~3 to shared KEY table 0 (BSS0). | ||
| 1257 | * 4~7 to shared KEY table 1 (BSS1). | ||
| 1258 | * 8~11 to shared KEY table 2 (BSS2). | ||
| 1259 | * 12~15 to shared KEY table 3 (BSS3). | ||
| 1260 | * BURST: Next frame belongs to same "burst" event. | ||
| 1261 | */ | ||
| 1262 | #define TXD_W0_OWNER_NIC FIELD32(0x00000001) | ||
| 1263 | #define TXD_W0_VALID FIELD32(0x00000002) | ||
| 1264 | #define TXD_W0_MORE_FRAG FIELD32(0x00000004) | ||
| 1265 | #define TXD_W0_ACK FIELD32(0x00000008) | ||
| 1266 | #define TXD_W0_TIMESTAMP FIELD32(0x00000010) | ||
| 1267 | #define TXD_W0_OFDM FIELD32(0x00000020) | ||
| 1268 | #define TXD_W0_IFS FIELD32(0x00000040) | ||
| 1269 | #define TXD_W0_RETRY_MODE FIELD32(0x00000080) | ||
| 1270 | #define TXD_W0_TKIP_MIC FIELD32(0x00000100) | ||
| 1271 | #define TXD_W0_KEY_TABLE FIELD32(0x00000200) | ||
| 1272 | #define TXD_W0_KEY_INDEX FIELD32(0x0000fc00) | ||
| 1273 | #define TXD_W0_DATABYTE_COUNT FIELD32(0x0fff0000) | ||
| 1274 | #define TXD_W0_BURST FIELD32(0x10000000) | ||
| 1275 | #define TXD_W0_CIPHER_ALG FIELD32(0xe0000000) | ||
| 1276 | |||
| 1277 | /* | ||
| 1278 | * Word1 | ||
| 1279 | * HOST_Q_ID: EDCA/HCCA queue ID. | ||
| 1280 | * HW_SEQUENCE: MAC overwrites the frame sequence number. | ||
| 1281 | * BUFFER_COUNT: Number of buffers in this TXD. | ||
| 1282 | */ | ||
| 1283 | #define TXD_W1_HOST_Q_ID FIELD32(0x0000000f) | ||
| 1284 | #define TXD_W1_AIFSN FIELD32(0x000000f0) | ||
| 1285 | #define TXD_W1_CWMIN FIELD32(0x00000f00) | ||
| 1286 | #define TXD_W1_CWMAX FIELD32(0x0000f000) | ||
| 1287 | #define TXD_W1_IV_OFFSET FIELD32(0x003f0000) | ||
| 1288 | #define TXD_W1_PIGGY_BACK FIELD32(0x01000000) | ||
| 1289 | #define TXD_W1_HW_SEQUENCE FIELD32(0x10000000) | ||
| 1290 | #define TXD_W1_BUFFER_COUNT FIELD32(0xe0000000) | ||
| 1291 | |||
| 1292 | /* | ||
| 1293 | * Word2: PLCP information | ||
| 1294 | */ | ||
| 1295 | #define TXD_W2_PLCP_SIGNAL FIELD32(0x000000ff) | ||
| 1296 | #define TXD_W2_PLCP_SERVICE FIELD32(0x0000ff00) | ||
| 1297 | #define TXD_W2_PLCP_LENGTH_LOW FIELD32(0x00ff0000) | ||
| 1298 | #define TXD_W2_PLCP_LENGTH_HIGH FIELD32(0xff000000) | ||
| 1299 | |||
| 1300 | /* | ||
| 1301 | * Word3 | ||
| 1302 | */ | ||
| 1303 | #define TXD_W3_IV FIELD32(0xffffffff) | ||
| 1304 | |||
| 1305 | /* | ||
| 1306 | * Word4 | ||
| 1307 | */ | ||
| 1308 | #define TXD_W4_EIV FIELD32(0xffffffff) | ||
| 1309 | |||
| 1310 | /* | ||
| 1311 | * Word5 | ||
| 1312 | * FRAME_OFFSET: Frame start offset inside ASIC TXFIFO (after TXINFO field). | ||
| 1313 | * TXD_W5_PID_SUBTYPE: Driver assigned packet ID index for txdone handler. | ||
| 1314 | * TXD_W5_PID_TYPE: Driver assigned packet ID type for txdone handler. | ||
| 1315 | * WAITING_DMA_DONE_INT: TXD been filled with data | ||
| 1316 | * and waiting for TxDoneISR housekeeping. | ||
| 1317 | */ | ||
| 1318 | #define TXD_W5_FRAME_OFFSET FIELD32(0x000000ff) | ||
| 1319 | #define TXD_W5_PID_SUBTYPE FIELD32(0x00001f00) | ||
| 1320 | #define TXD_W5_PID_TYPE FIELD32(0x0000e000) | ||
| 1321 | #define TXD_W5_TX_POWER FIELD32(0x00ff0000) | ||
| 1322 | #define TXD_W5_WAITING_DMA_DONE_INT FIELD32(0x01000000) | ||
| 1323 | |||
| 1324 | /* | ||
| 1325 | * the above 24-byte is called TXINFO and will be DMAed to MAC block | ||
| 1326 | * through TXFIFO. MAC block use this TXINFO to control the transmission | ||
| 1327 | * behavior of this frame. | ||
| 1328 | * The following fields are not used by MAC block. | ||
| 1329 | * They are used by DMA block and HOST driver only. | ||
| 1330 | * Once a frame has been DMA to ASIC, all the following fields are useless | ||
| 1331 | * to ASIC. | ||
| 1332 | */ | ||
| 1333 | |||
| 1334 | /* | ||
| 1335 | * Word6-10: Buffer physical address | ||
| 1336 | */ | ||
| 1337 | #define TXD_W6_BUFFER_PHYSICAL_ADDRESS FIELD32(0xffffffff) | ||
| 1338 | #define TXD_W7_BUFFER_PHYSICAL_ADDRESS FIELD32(0xffffffff) | ||
| 1339 | #define TXD_W8_BUFFER_PHYSICAL_ADDRESS FIELD32(0xffffffff) | ||
| 1340 | #define TXD_W9_BUFFER_PHYSICAL_ADDRESS FIELD32(0xffffffff) | ||
| 1341 | #define TXD_W10_BUFFER_PHYSICAL_ADDRESS FIELD32(0xffffffff) | ||
| 1342 | |||
| 1343 | /* | ||
| 1344 | * Word11-13: Buffer length | ||
| 1345 | */ | ||
| 1346 | #define TXD_W11_BUFFER_LENGTH0 FIELD32(0x00000fff) | ||
| 1347 | #define TXD_W11_BUFFER_LENGTH1 FIELD32(0x0fff0000) | ||
| 1348 | #define TXD_W12_BUFFER_LENGTH2 FIELD32(0x00000fff) | ||
| 1349 | #define TXD_W12_BUFFER_LENGTH3 FIELD32(0x0fff0000) | ||
| 1350 | #define TXD_W13_BUFFER_LENGTH4 FIELD32(0x00000fff) | ||
| 1351 | |||
| 1352 | /* | ||
| 1353 | * Word14 | ||
| 1354 | */ | ||
| 1355 | #define TXD_W14_SK_BUFFER FIELD32(0xffffffff) | ||
| 1356 | |||
| 1357 | /* | ||
| 1358 | * Word15 | ||
| 1359 | */ | ||
| 1360 | #define TXD_W15_NEXT_SK_BUFFER FIELD32(0xffffffff) | ||
| 1361 | |||
| 1362 | /* | ||
| 1363 | * RX descriptor format for RX Ring. | ||
| 1364 | */ | ||
| 1365 | |||
| 1366 | /* | ||
| 1367 | * Word0 | ||
| 1368 | * CIPHER_ERROR: 1:ICV error, 2:MIC error, 3:invalid key. | ||
| 1369 | * KEY_INDEX: Decryption key actually used. | ||
| 1370 | */ | ||
| 1371 | #define RXD_W0_OWNER_NIC FIELD32(0x00000001) | ||
| 1372 | #define RXD_W0_DROP FIELD32(0x00000002) | ||
| 1373 | #define RXD_W0_UNICAST_TO_ME FIELD32(0x00000004) | ||
| 1374 | #define RXD_W0_MULTICAST FIELD32(0x00000008) | ||
| 1375 | #define RXD_W0_BROADCAST FIELD32(0x00000010) | ||
| 1376 | #define RXD_W0_MY_BSS FIELD32(0x00000020) | ||
| 1377 | #define RXD_W0_CRC_ERROR FIELD32(0x00000040) | ||
| 1378 | #define RXD_W0_OFDM FIELD32(0x00000080) | ||
| 1379 | #define RXD_W0_CIPHER_ERROR FIELD32(0x00000300) | ||
| 1380 | #define RXD_W0_KEY_INDEX FIELD32(0x0000fc00) | ||
| 1381 | #define RXD_W0_DATABYTE_COUNT FIELD32(0x0fff0000) | ||
| 1382 | #define RXD_W0_CIPHER_ALG FIELD32(0xe0000000) | ||
| 1383 | |||
| 1384 | /* | ||
| 1385 | * Word1 | ||
| 1386 | * SIGNAL: RX raw data rate reported by BBP. | ||
| 1387 | */ | ||
| 1388 | #define RXD_W1_SIGNAL FIELD32(0x000000ff) | ||
| 1389 | #define RXD_W1_RSSI_AGC FIELD32(0x00001f00) | ||
| 1390 | #define RXD_W1_RSSI_LNA FIELD32(0x00006000) | ||
| 1391 | #define RXD_W1_FRAME_OFFSET FIELD32(0x7f000000) | ||
| 1392 | |||
| 1393 | /* | ||
| 1394 | * Word2 | ||
| 1395 | * IV: Received IV of originally encrypted. | ||
| 1396 | */ | ||
| 1397 | #define RXD_W2_IV FIELD32(0xffffffff) | ||
| 1398 | |||
| 1399 | /* | ||
| 1400 | * Word3 | ||
| 1401 | * EIV: Received EIV of originally encrypted. | ||
| 1402 | */ | ||
| 1403 | #define RXD_W3_EIV FIELD32(0xffffffff) | ||
| 1404 | |||
| 1405 | /* | ||
| 1406 | * Word4 | ||
| 1407 | */ | ||
| 1408 | #define RXD_W4_RESERVED FIELD32(0xffffffff) | ||
| 1409 | |||
| 1410 | /* | ||
| 1411 | * the above 20-byte is called RXINFO and will be DMAed to MAC RX block | ||
| 1412 | * and passed to the HOST driver. | ||
| 1413 | * The following fields are for DMA block and HOST usage only. | ||
| 1414 | * Can't be touched by ASIC MAC block. | ||
| 1415 | */ | ||
| 1416 | |||
| 1417 | /* | ||
| 1418 | * Word5 | ||
| 1419 | */ | ||
| 1420 | #define RXD_W5_BUFFER_PHYSICAL_ADDRESS FIELD32(0xffffffff) | ||
| 1421 | |||
| 1422 | /* | ||
| 1423 | * Word6-15: Reserved | ||
| 1424 | */ | ||
| 1425 | #define RXD_W6_RESERVED FIELD32(0xffffffff) | ||
| 1426 | #define RXD_W7_RESERVED FIELD32(0xffffffff) | ||
| 1427 | #define RXD_W8_RESERVED FIELD32(0xffffffff) | ||
| 1428 | #define RXD_W9_RESERVED FIELD32(0xffffffff) | ||
| 1429 | #define RXD_W10_RESERVED FIELD32(0xffffffff) | ||
| 1430 | #define RXD_W11_RESERVED FIELD32(0xffffffff) | ||
| 1431 | #define RXD_W12_RESERVED FIELD32(0xffffffff) | ||
| 1432 | #define RXD_W13_RESERVED FIELD32(0xffffffff) | ||
| 1433 | #define RXD_W14_RESERVED FIELD32(0xffffffff) | ||
| 1434 | #define RXD_W15_RESERVED FIELD32(0xffffffff) | ||
| 1435 | |||
| 1436 | /* | ||
| 1437 | * Macro's for converting txpower from EEPROM to dscape value | ||
| 1438 | * and from dscape value to register value. | ||
| 1439 | */ | ||
| 1440 | #define MIN_TXPOWER 0 | ||
| 1441 | #define MAX_TXPOWER 31 | ||
| 1442 | #define DEFAULT_TXPOWER 24 | ||
| 1443 | |||
| 1444 | #define TXPOWER_FROM_DEV(__txpower) \ | ||
| 1445 | ({ \ | ||
| 1446 | ((__txpower) > MAX_TXPOWER) ? \ | ||
| 1447 | DEFAULT_TXPOWER : (__txpower); \ | ||
| 1448 | }) | ||
| 1449 | |||
| 1450 | #define TXPOWER_TO_DEV(__txpower) \ | ||
| 1451 | ({ \ | ||
| 1452 | ((__txpower) <= MIN_TXPOWER) ? MIN_TXPOWER : \ | ||
| 1453 | (((__txpower) >= MAX_TXPOWER) ? MAX_TXPOWER : \ | ||
| 1454 | (__txpower)); \ | ||
| 1455 | }) | ||
| 1456 | |||
| 1457 | #endif /* RT61PCI_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c new file mode 100644 index 00000000000..b047c7c0f9e --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
| @@ -0,0 +1,2124 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt73usb | ||
| 23 | Abstract: rt73usb device specific routines. | ||
| 24 | Supported chipsets: rt2571W & rt2671. | ||
| 25 | */ | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Set enviroment defines for rt2x00.h | ||
| 29 | */ | ||
| 30 | #define DRV_NAME "rt73usb" | ||
| 31 | |||
| 32 | #include <linux/delay.h> | ||
| 33 | #include <linux/etherdevice.h> | ||
| 34 | #include <linux/init.h> | ||
| 35 | #include <linux/kernel.h> | ||
| 36 | #include <linux/module.h> | ||
| 37 | #include <linux/usb.h> | ||
| 38 | |||
| 39 | #include "rt2x00.h" | ||
| 40 | #include "rt2x00usb.h" | ||
| 41 | #include "rt73usb.h" | ||
| 42 | |||
| 43 | /* | ||
| 44 | * Register access. | ||
| 45 | * All access to the CSR registers will go through the methods | ||
| 46 | * rt73usb_register_read and rt73usb_register_write. | ||
| 47 | * BBP and RF register require indirect register access, | ||
| 48 | * and use the CSR registers BBPCSR and RFCSR to achieve this. | ||
| 49 | * These indirect registers work with busy bits, | ||
| 50 | * and we will try maximal REGISTER_BUSY_COUNT times to access | ||
| 51 | * the register while taking a REGISTER_BUSY_DELAY us delay | ||
| 52 | * between each attampt. When the busy bit is still set at that time, | ||
| 53 | * the access attempt is considered to have failed, | ||
| 54 | * and we will print an error. | ||
| 55 | */ | ||
| 56 | static inline void rt73usb_register_read(const struct rt2x00_dev *rt2x00dev, | ||
| 57 | const unsigned int offset, u32 *value) | ||
| 58 | { | ||
| 59 | __le32 reg; | ||
| 60 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, | ||
| 61 | USB_VENDOR_REQUEST_IN, offset, | ||
| 62 | ®, sizeof(u32), REGISTER_TIMEOUT); | ||
| 63 | *value = le32_to_cpu(reg); | ||
| 64 | } | ||
| 65 | |||
| 66 | static inline void rt73usb_register_multiread(const struct rt2x00_dev | ||
| 67 | *rt2x00dev, | ||
| 68 | const unsigned int offset, | ||
| 69 | void *value, const u32 length) | ||
| 70 | { | ||
| 71 | int timeout = REGISTER_TIMEOUT * (length / sizeof(u32)); | ||
| 72 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, | ||
| 73 | USB_VENDOR_REQUEST_IN, offset, | ||
| 74 | value, length, timeout); | ||
| 75 | } | ||
| 76 | |||
| 77 | static inline void rt73usb_register_write(const struct rt2x00_dev *rt2x00dev, | ||
| 78 | const unsigned int offset, u32 value) | ||
| 79 | { | ||
| 80 | __le32 reg = cpu_to_le32(value); | ||
| 81 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, | ||
| 82 | USB_VENDOR_REQUEST_OUT, offset, | ||
| 83 | ®, sizeof(u32), REGISTER_TIMEOUT); | ||
| 84 | } | ||
| 85 | |||
| 86 | static inline void rt73usb_register_multiwrite(const struct rt2x00_dev | ||
| 87 | *rt2x00dev, | ||
| 88 | const unsigned int offset, | ||
| 89 | void *value, const u32 length) | ||
| 90 | { | ||
| 91 | int timeout = REGISTER_TIMEOUT * (length / sizeof(u32)); | ||
| 92 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, | ||
| 93 | USB_VENDOR_REQUEST_OUT, offset, | ||
| 94 | value, length, timeout); | ||
| 95 | } | ||
| 96 | |||
| 97 | static u32 rt73usb_bbp_check(const struct rt2x00_dev *rt2x00dev) | ||
| 98 | { | ||
| 99 | u32 reg; | ||
| 100 | unsigned int i; | ||
| 101 | |||
| 102 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 103 | rt73usb_register_read(rt2x00dev, PHY_CSR3, ®); | ||
| 104 | if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY)) | ||
| 105 | break; | ||
| 106 | udelay(REGISTER_BUSY_DELAY); | ||
| 107 | } | ||
| 108 | |||
| 109 | return reg; | ||
| 110 | } | ||
| 111 | |||
| 112 | static void rt73usb_bbp_write(const struct rt2x00_dev *rt2x00dev, | ||
| 113 | const unsigned int word, const u8 value) | ||
| 114 | { | ||
| 115 | u32 reg; | ||
| 116 | |||
| 117 | /* | ||
| 118 | * Wait until the BBP becomes ready. | ||
| 119 | */ | ||
| 120 | reg = rt73usb_bbp_check(rt2x00dev); | ||
| 121 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | ||
| 122 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); | ||
| 123 | return; | ||
| 124 | } | ||
| 125 | |||
| 126 | /* | ||
| 127 | * Write the data into the BBP. | ||
| 128 | */ | ||
| 129 | reg = 0; | ||
| 130 | rt2x00_set_field32(®, PHY_CSR3_VALUE, value); | ||
| 131 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); | ||
| 132 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | ||
| 133 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); | ||
| 134 | |||
| 135 | rt73usb_register_write(rt2x00dev, PHY_CSR3, reg); | ||
| 136 | } | ||
| 137 | |||
| 138 | static void rt73usb_bbp_read(const struct rt2x00_dev *rt2x00dev, | ||
| 139 | const unsigned int word, u8 *value) | ||
| 140 | { | ||
| 141 | u32 reg; | ||
| 142 | |||
| 143 | /* | ||
| 144 | * Wait until the BBP becomes ready. | ||
| 145 | */ | ||
| 146 | reg = rt73usb_bbp_check(rt2x00dev); | ||
| 147 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | ||
| 148 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | ||
| 149 | return; | ||
| 150 | } | ||
| 151 | |||
| 152 | /* | ||
| 153 | * Write the request into the BBP. | ||
| 154 | */ | ||
| 155 | reg = 0; | ||
| 156 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); | ||
| 157 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | ||
| 158 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); | ||
| 159 | |||
| 160 | rt73usb_register_write(rt2x00dev, PHY_CSR3, reg); | ||
| 161 | |||
| 162 | /* | ||
| 163 | * Wait until the BBP becomes ready. | ||
| 164 | */ | ||
| 165 | reg = rt73usb_bbp_check(rt2x00dev); | ||
| 166 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | ||
| 167 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | ||
| 168 | *value = 0xff; | ||
| 169 | return; | ||
| 170 | } | ||
| 171 | |||
| 172 | *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); | ||
| 173 | } | ||
| 174 | |||
| 175 | static void rt73usb_rf_write(const struct rt2x00_dev *rt2x00dev, | ||
| 176 | const unsigned int word, const u32 value) | ||
| 177 | { | ||
| 178 | u32 reg; | ||
| 179 | unsigned int i; | ||
| 180 | |||
| 181 | if (!word) | ||
| 182 | return; | ||
| 183 | |||
| 184 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 185 | rt73usb_register_read(rt2x00dev, PHY_CSR4, ®); | ||
| 186 | if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY)) | ||
| 187 | goto rf_write; | ||
| 188 | udelay(REGISTER_BUSY_DELAY); | ||
| 189 | } | ||
| 190 | |||
| 191 | ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n"); | ||
| 192 | return; | ||
| 193 | |||
| 194 | rf_write: | ||
| 195 | reg = 0; | ||
| 196 | rt2x00_set_field32(®, PHY_CSR4_VALUE, value); | ||
| 197 | |||
| 198 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | ||
| 199 | rt2x00_rf(&rt2x00dev->chip, RF2527)) | ||
| 200 | rt2x00_set_field32(®, PHY_CSR4_NUMBER_OF_BITS, 21); | ||
| 201 | else | ||
| 202 | rt2x00_set_field32(®, PHY_CSR4_NUMBER_OF_BITS, 20); | ||
| 203 | |||
| 204 | rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); | ||
| 205 | rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); | ||
| 206 | |||
| 207 | rt73usb_register_write(rt2x00dev, PHY_CSR4, reg); | ||
| 208 | rt2x00_rf_write(rt2x00dev, word, value); | ||
| 209 | } | ||
| 210 | |||
| 211 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
| 212 | #define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) ) | ||
| 213 | |||
| 214 | static void rt73usb_read_csr(const struct rt2x00_dev *rt2x00dev, | ||
| 215 | const unsigned int word, u32 *data) | ||
| 216 | { | ||
| 217 | rt73usb_register_read(rt2x00dev, CSR_OFFSET(word), data); | ||
| 218 | } | ||
| 219 | |||
| 220 | static void rt73usb_write_csr(const struct rt2x00_dev *rt2x00dev, | ||
| 221 | const unsigned int word, u32 data) | ||
| 222 | { | ||
| 223 | rt73usb_register_write(rt2x00dev, CSR_OFFSET(word), data); | ||
| 224 | } | ||
| 225 | |||
| 226 | static const struct rt2x00debug rt73usb_rt2x00debug = { | ||
| 227 | .owner = THIS_MODULE, | ||
| 228 | .csr = { | ||
| 229 | .read = rt73usb_read_csr, | ||
| 230 | .write = rt73usb_write_csr, | ||
| 231 | .word_size = sizeof(u32), | ||
| 232 | .word_count = CSR_REG_SIZE / sizeof(u32), | ||
| 233 | }, | ||
| 234 | .eeprom = { | ||
| 235 | .read = rt2x00_eeprom_read, | ||
| 236 | .write = rt2x00_eeprom_write, | ||
| 237 | .word_size = sizeof(u16), | ||
| 238 | .word_count = EEPROM_SIZE / sizeof(u16), | ||
| 239 | }, | ||
| 240 | .bbp = { | ||
| 241 | .read = rt73usb_bbp_read, | ||
| 242 | .write = rt73usb_bbp_write, | ||
| 243 | .word_size = sizeof(u8), | ||
| 244 | .word_count = BBP_SIZE / sizeof(u8), | ||
| 245 | }, | ||
| 246 | .rf = { | ||
| 247 | .read = rt2x00_rf_read, | ||
| 248 | .write = rt73usb_rf_write, | ||
| 249 | .word_size = sizeof(u32), | ||
| 250 | .word_count = RF_SIZE / sizeof(u32), | ||
| 251 | }, | ||
| 252 | }; | ||
| 253 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
| 254 | |||
| 255 | /* | ||
| 256 | * Configuration handlers. | ||
| 257 | */ | ||
| 258 | static void rt73usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *addr) | ||
| 259 | { | ||
| 260 | __le32 reg[2]; | ||
| 261 | u32 tmp; | ||
| 262 | |||
| 263 | memset(®, 0, sizeof(reg)); | ||
| 264 | memcpy(®, addr, ETH_ALEN); | ||
| 265 | |||
| 266 | tmp = le32_to_cpu(reg[1]); | ||
| 267 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | ||
| 268 | reg[1] = cpu_to_le32(tmp); | ||
| 269 | |||
| 270 | /* | ||
| 271 | * The MAC address is passed to us as an array of bytes, | ||
| 272 | * that array is little endian, so no need for byte ordering. | ||
| 273 | */ | ||
| 274 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, ®, sizeof(reg)); | ||
| 275 | } | ||
| 276 | |||
| 277 | static void rt73usb_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) | ||
| 278 | { | ||
| 279 | __le32 reg[2]; | ||
| 280 | u32 tmp; | ||
| 281 | |||
| 282 | memset(®, 0, sizeof(reg)); | ||
| 283 | memcpy(®, bssid, ETH_ALEN); | ||
| 284 | |||
| 285 | tmp = le32_to_cpu(reg[1]); | ||
| 286 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | ||
| 287 | reg[1] = cpu_to_le32(tmp); | ||
| 288 | |||
| 289 | /* | ||
| 290 | * The BSSID is passed to us as an array of bytes, | ||
| 291 | * that array is little endian, so no need for byte ordering. | ||
| 292 | */ | ||
| 293 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, ®, sizeof(reg)); | ||
| 294 | } | ||
| 295 | |||
| 296 | static void rt73usb_config_packet_filter(struct rt2x00_dev *rt2x00dev, | ||
| 297 | const unsigned int filter) | ||
| 298 | { | ||
| 299 | int promisc = !!(filter & IFF_PROMISC); | ||
| 300 | int multicast = !!(filter & IFF_MULTICAST); | ||
| 301 | int broadcast = !!(filter & IFF_BROADCAST); | ||
| 302 | u32 reg; | ||
| 303 | |||
| 304 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
| 305 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, !promisc); | ||
| 306 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, !multicast); | ||
| 307 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BORADCAST, !broadcast); | ||
| 308 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
| 309 | } | ||
| 310 | |||
| 311 | static void rt73usb_config_type(struct rt2x00_dev *rt2x00dev, const int type) | ||
| 312 | { | ||
| 313 | u32 reg; | ||
| 314 | |||
| 315 | /* | ||
| 316 | * Clear current synchronisation setup. | ||
| 317 | * For the Beacon base registers we only need to clear | ||
| 318 | * the first byte since that byte contains the VALID and OWNER | ||
| 319 | * bits which (when set to 0) will invalidate the entire beacon. | ||
| 320 | */ | ||
| 321 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
| 322 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
| 323 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
| 324 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
| 325 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
| 326 | |||
| 327 | /* | ||
| 328 | * Apply hardware packet filter. | ||
| 329 | */ | ||
| 330 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
| 331 | |||
| 332 | if (!is_monitor_present(&rt2x00dev->interface) && | ||
| 333 | (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_STA)) | ||
| 334 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, 1); | ||
| 335 | else | ||
| 336 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, 0); | ||
| 337 | |||
| 338 | /* | ||
| 339 | * If there is a non-monitor interface present | ||
| 340 | * the packet should be strict (even if a monitor interface is present!). | ||
| 341 | * When there is only 1 interface present which is in monitor mode | ||
| 342 | * we should start accepting _all_ frames. | ||
| 343 | */ | ||
| 344 | if (is_interface_present(&rt2x00dev->interface)) { | ||
| 345 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, 1); | ||
| 346 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, 1); | ||
| 347 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, 1); | ||
| 348 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | ||
| 349 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1); | ||
| 350 | } else if (is_monitor_present(&rt2x00dev->interface)) { | ||
| 351 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, 0); | ||
| 352 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, 0); | ||
| 353 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, 0); | ||
| 354 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 0); | ||
| 355 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 0); | ||
| 356 | } | ||
| 357 | |||
| 358 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
| 359 | |||
| 360 | /* | ||
| 361 | * Enable synchronisation. | ||
| 362 | */ | ||
| 363 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
| 364 | if (is_interface_present(&rt2x00dev->interface)) { | ||
| 365 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
| 366 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
| 367 | } | ||
| 368 | |||
| 369 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
| 370 | if (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_AP) | ||
| 371 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 2); | ||
| 372 | else if (type == IEEE80211_IF_TYPE_STA) | ||
| 373 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 1); | ||
| 374 | else if (is_monitor_present(&rt2x00dev->interface) && | ||
| 375 | !is_interface_present(&rt2x00dev->interface)) | ||
| 376 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 0); | ||
| 377 | |||
| 378 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
| 379 | } | ||
| 380 | |||
| 381 | static void rt73usb_config_rate(struct rt2x00_dev *rt2x00dev, const int rate) | ||
| 382 | { | ||
| 383 | struct ieee80211_conf *conf = &rt2x00dev->hw->conf; | ||
| 384 | u32 reg; | ||
| 385 | u32 value; | ||
| 386 | u32 preamble; | ||
| 387 | |||
| 388 | if (DEVICE_GET_RATE_FIELD(rate, PREAMBLE)) | ||
| 389 | preamble = SHORT_PREAMBLE; | ||
| 390 | else | ||
| 391 | preamble = PREAMBLE; | ||
| 392 | |||
| 393 | reg = DEVICE_GET_RATE_FIELD(rate, RATEMASK) & DEV_BASIC_RATEMASK; | ||
| 394 | |||
| 395 | rt73usb_register_write(rt2x00dev, TXRX_CSR5, reg); | ||
| 396 | |||
| 397 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
| 398 | value = ((conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) ? | ||
| 399 | SHORT_DIFS : DIFS) + | ||
| 400 | PLCP + preamble + get_duration(ACK_SIZE, 10); | ||
| 401 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, value); | ||
| 402 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
| 403 | |||
| 404 | rt73usb_register_read(rt2x00dev, TXRX_CSR4, ®); | ||
| 405 | if (preamble == SHORT_PREAMBLE) | ||
| 406 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, 1); | ||
| 407 | else | ||
| 408 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, 0); | ||
| 409 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); | ||
| 410 | } | ||
| 411 | |||
| 412 | static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, | ||
| 413 | const int phymode) | ||
| 414 | { | ||
| 415 | struct ieee80211_hw_mode *mode; | ||
| 416 | struct ieee80211_rate *rate; | ||
| 417 | |||
| 418 | if (phymode == MODE_IEEE80211A) | ||
| 419 | rt2x00dev->curr_hwmode = HWMODE_A; | ||
| 420 | else if (phymode == MODE_IEEE80211B) | ||
| 421 | rt2x00dev->curr_hwmode = HWMODE_B; | ||
| 422 | else | ||
| 423 | rt2x00dev->curr_hwmode = HWMODE_G; | ||
| 424 | |||
| 425 | mode = &rt2x00dev->hwmodes[rt2x00dev->curr_hwmode]; | ||
| 426 | rate = &mode->rates[mode->num_rates - 1]; | ||
| 427 | |||
| 428 | rt73usb_config_rate(rt2x00dev, rate->val2); | ||
| 429 | } | ||
| 430 | |||
| 431 | static void rt73usb_config_lock_channel(struct rt2x00_dev *rt2x00dev, | ||
| 432 | struct rf_channel *rf, | ||
| 433 | const int txpower) | ||
| 434 | { | ||
| 435 | u8 r3; | ||
| 436 | u8 r94; | ||
| 437 | u8 smart; | ||
| 438 | |||
| 439 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower)); | ||
| 440 | rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset); | ||
| 441 | |||
| 442 | smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) || | ||
| 443 | rt2x00_rf(&rt2x00dev->chip, RF2527)); | ||
| 444 | |||
| 445 | rt73usb_bbp_read(rt2x00dev, 3, &r3); | ||
| 446 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart); | ||
| 447 | rt73usb_bbp_write(rt2x00dev, 3, r3); | ||
| 448 | |||
| 449 | r94 = 6; | ||
| 450 | if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94)) | ||
| 451 | r94 += txpower - MAX_TXPOWER; | ||
| 452 | else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94)) | ||
| 453 | r94 += txpower; | ||
| 454 | rt73usb_bbp_write(rt2x00dev, 94, r94); | ||
| 455 | |||
| 456 | rt73usb_rf_write(rt2x00dev, 1, rf->rf1); | ||
| 457 | rt73usb_rf_write(rt2x00dev, 2, rf->rf2); | ||
| 458 | rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004); | ||
| 459 | rt73usb_rf_write(rt2x00dev, 4, rf->rf4); | ||
| 460 | |||
| 461 | rt73usb_rf_write(rt2x00dev, 1, rf->rf1); | ||
| 462 | rt73usb_rf_write(rt2x00dev, 2, rf->rf2); | ||
| 463 | rt73usb_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004); | ||
| 464 | rt73usb_rf_write(rt2x00dev, 4, rf->rf4); | ||
| 465 | |||
| 466 | rt73usb_rf_write(rt2x00dev, 1, rf->rf1); | ||
| 467 | rt73usb_rf_write(rt2x00dev, 2, rf->rf2); | ||
| 468 | rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004); | ||
| 469 | rt73usb_rf_write(rt2x00dev, 4, rf->rf4); | ||
| 470 | |||
| 471 | udelay(10); | ||
| 472 | } | ||
| 473 | |||
| 474 | static void rt73usb_config_channel(struct rt2x00_dev *rt2x00dev, | ||
| 475 | const int index, const int channel, | ||
| 476 | const int txpower) | ||
| 477 | { | ||
| 478 | struct rf_channel rf; | ||
| 479 | |||
| 480 | /* | ||
| 481 | * Fill rf_reg structure. | ||
| 482 | */ | ||
| 483 | memcpy(&rf, &rt2x00dev->spec.channels[index], sizeof(rf)); | ||
| 484 | |||
| 485 | rt73usb_config_lock_channel(rt2x00dev, &rf, txpower); | ||
| 486 | } | ||
| 487 | |||
| 488 | static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev, | ||
| 489 | const int txpower) | ||
| 490 | { | ||
| 491 | struct rf_channel rf; | ||
| 492 | |||
| 493 | rt2x00_rf_read(rt2x00dev, 1, &rf.rf1); | ||
| 494 | rt2x00_rf_read(rt2x00dev, 2, &rf.rf2); | ||
| 495 | rt2x00_rf_read(rt2x00dev, 3, &rf.rf3); | ||
| 496 | rt2x00_rf_read(rt2x00dev, 4, &rf.rf4); | ||
| 497 | |||
| 498 | rt73usb_config_lock_channel(rt2x00dev, &rf, txpower); | ||
| 499 | } | ||
| 500 | |||
| 501 | static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | ||
| 502 | const int antenna_tx, | ||
| 503 | const int antenna_rx) | ||
| 504 | { | ||
| 505 | u8 r3; | ||
| 506 | u8 r4; | ||
| 507 | u8 r77; | ||
| 508 | |||
| 509 | rt73usb_bbp_read(rt2x00dev, 3, &r3); | ||
| 510 | rt73usb_bbp_read(rt2x00dev, 4, &r4); | ||
| 511 | rt73usb_bbp_read(rt2x00dev, 77, &r77); | ||
| 512 | |||
| 513 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0); | ||
| 514 | |||
| 515 | switch (antenna_rx) { | ||
| 516 | case ANTENNA_SW_DIVERSITY: | ||
| 517 | case ANTENNA_HW_DIVERSITY: | ||
| 518 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | ||
| 519 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | ||
| 520 | !!(rt2x00dev->curr_hwmode != HWMODE_A)); | ||
| 521 | break; | ||
| 522 | case ANTENNA_A: | ||
| 523 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
| 524 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | ||
| 525 | |||
| 526 | if (rt2x00dev->curr_hwmode == HWMODE_A) | ||
| 527 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); | ||
| 528 | else | ||
| 529 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
| 530 | break; | ||
| 531 | case ANTENNA_B: | ||
| 532 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
| 533 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | ||
| 534 | |||
| 535 | if (rt2x00dev->curr_hwmode == HWMODE_A) | ||
| 536 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
| 537 | else | ||
| 538 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); | ||
| 539 | break; | ||
| 540 | } | ||
| 541 | |||
| 542 | rt73usb_bbp_write(rt2x00dev, 77, r77); | ||
| 543 | rt73usb_bbp_write(rt2x00dev, 3, r3); | ||
| 544 | rt73usb_bbp_write(rt2x00dev, 4, r4); | ||
| 545 | } | ||
| 546 | |||
| 547 | static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev, | ||
| 548 | const int antenna_tx, | ||
| 549 | const int antenna_rx) | ||
| 550 | { | ||
| 551 | u8 r3; | ||
| 552 | u8 r4; | ||
| 553 | u8 r77; | ||
| 554 | |||
| 555 | rt73usb_bbp_read(rt2x00dev, 3, &r3); | ||
| 556 | rt73usb_bbp_read(rt2x00dev, 4, &r4); | ||
| 557 | rt73usb_bbp_read(rt2x00dev, 77, &r77); | ||
| 558 | |||
| 559 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0); | ||
| 560 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | ||
| 561 | !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); | ||
| 562 | |||
| 563 | switch (antenna_rx) { | ||
| 564 | case ANTENNA_SW_DIVERSITY: | ||
| 565 | case ANTENNA_HW_DIVERSITY: | ||
| 566 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | ||
| 567 | break; | ||
| 568 | case ANTENNA_A: | ||
| 569 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
| 570 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
| 571 | break; | ||
| 572 | case ANTENNA_B: | ||
| 573 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
| 574 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); | ||
| 575 | break; | ||
| 576 | } | ||
| 577 | |||
| 578 | rt73usb_bbp_write(rt2x00dev, 77, r77); | ||
| 579 | rt73usb_bbp_write(rt2x00dev, 3, r3); | ||
| 580 | rt73usb_bbp_write(rt2x00dev, 4, r4); | ||
| 581 | } | ||
| 582 | |||
| 583 | struct antenna_sel { | ||
| 584 | u8 word; | ||
| 585 | /* | ||
| 586 | * value[0] -> non-LNA | ||
| 587 | * value[1] -> LNA | ||
| 588 | */ | ||
| 589 | u8 value[2]; | ||
| 590 | }; | ||
| 591 | |||
| 592 | static const struct antenna_sel antenna_sel_a[] = { | ||
| 593 | { 96, { 0x58, 0x78 } }, | ||
| 594 | { 104, { 0x38, 0x48 } }, | ||
| 595 | { 75, { 0xfe, 0x80 } }, | ||
| 596 | { 86, { 0xfe, 0x80 } }, | ||
| 597 | { 88, { 0xfe, 0x80 } }, | ||
| 598 | { 35, { 0x60, 0x60 } }, | ||
| 599 | { 97, { 0x58, 0x58 } }, | ||
| 600 | { 98, { 0x58, 0x58 } }, | ||
| 601 | }; | ||
| 602 | |||
| 603 | static const struct antenna_sel antenna_sel_bg[] = { | ||
| 604 | { 96, { 0x48, 0x68 } }, | ||
| 605 | { 104, { 0x2c, 0x3c } }, | ||
| 606 | { 75, { 0xfe, 0x80 } }, | ||
| 607 | { 86, { 0xfe, 0x80 } }, | ||
| 608 | { 88, { 0xfe, 0x80 } }, | ||
| 609 | { 35, { 0x50, 0x50 } }, | ||
| 610 | { 97, { 0x48, 0x48 } }, | ||
| 611 | { 98, { 0x48, 0x48 } }, | ||
| 612 | }; | ||
| 613 | |||
| 614 | static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, | ||
| 615 | const int antenna_tx, const int antenna_rx) | ||
| 616 | { | ||
| 617 | const struct antenna_sel *sel; | ||
| 618 | unsigned int lna; | ||
| 619 | unsigned int i; | ||
| 620 | u32 reg; | ||
| 621 | |||
| 622 | rt73usb_register_read(rt2x00dev, PHY_CSR0, ®); | ||
| 623 | |||
| 624 | if (rt2x00dev->curr_hwmode == HWMODE_A) { | ||
| 625 | sel = antenna_sel_a; | ||
| 626 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | ||
| 627 | |||
| 628 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 0); | ||
| 629 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 1); | ||
| 630 | } else { | ||
| 631 | sel = antenna_sel_bg; | ||
| 632 | lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | ||
| 633 | |||
| 634 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 1); | ||
| 635 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 0); | ||
| 636 | } | ||
| 637 | |||
| 638 | for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) | ||
| 639 | rt73usb_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]); | ||
| 640 | |||
| 641 | rt73usb_register_write(rt2x00dev, PHY_CSR0, reg); | ||
| 642 | |||
| 643 | if (rt2x00_rf(&rt2x00dev->chip, RF5226) || | ||
| 644 | rt2x00_rf(&rt2x00dev->chip, RF5225)) | ||
| 645 | rt73usb_config_antenna_5x(rt2x00dev, antenna_tx, antenna_rx); | ||
| 646 | else if (rt2x00_rf(&rt2x00dev->chip, RF2528) || | ||
| 647 | rt2x00_rf(&rt2x00dev->chip, RF2527)) | ||
| 648 | rt73usb_config_antenna_2x(rt2x00dev, antenna_tx, antenna_rx); | ||
| 649 | } | ||
| 650 | |||
| 651 | static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev, | ||
| 652 | const int short_slot_time, | ||
| 653 | const int beacon_int) | ||
| 654 | { | ||
| 655 | u32 reg; | ||
| 656 | |||
| 657 | rt73usb_register_read(rt2x00dev, MAC_CSR9, ®); | ||
| 658 | rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, | ||
| 659 | short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME); | ||
| 660 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); | ||
| 661 | |||
| 662 | rt73usb_register_read(rt2x00dev, MAC_CSR8, ®); | ||
| 663 | rt2x00_set_field32(®, MAC_CSR8_SIFS, SIFS); | ||
| 664 | rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); | ||
| 665 | rt2x00_set_field32(®, MAC_CSR8_EIFS, EIFS); | ||
| 666 | rt73usb_register_write(rt2x00dev, MAC_CSR8, reg); | ||
| 667 | |||
| 668 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
| 669 | rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); | ||
| 670 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
| 671 | |||
| 672 | rt73usb_register_read(rt2x00dev, TXRX_CSR4, ®); | ||
| 673 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); | ||
| 674 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); | ||
| 675 | |||
| 676 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
| 677 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, beacon_int * 16); | ||
| 678 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
| 679 | } | ||
| 680 | |||
| 681 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | ||
| 682 | const unsigned int flags, | ||
| 683 | struct ieee80211_conf *conf) | ||
| 684 | { | ||
| 685 | int short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME; | ||
| 686 | |||
| 687 | if (flags & CONFIG_UPDATE_PHYMODE) | ||
| 688 | rt73usb_config_phymode(rt2x00dev, conf->phymode); | ||
| 689 | if (flags & CONFIG_UPDATE_CHANNEL) | ||
| 690 | rt73usb_config_channel(rt2x00dev, conf->channel_val, | ||
| 691 | conf->channel, conf->power_level); | ||
| 692 | if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL)) | ||
| 693 | rt73usb_config_txpower(rt2x00dev, conf->power_level); | ||
| 694 | if (flags & CONFIG_UPDATE_ANTENNA) | ||
| 695 | rt73usb_config_antenna(rt2x00dev, conf->antenna_sel_tx, | ||
| 696 | conf->antenna_sel_rx); | ||
| 697 | if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) | ||
| 698 | rt73usb_config_duration(rt2x00dev, short_slot_time, | ||
| 699 | conf->beacon_int); | ||
| 700 | } | ||
| 701 | |||
| 702 | /* | ||
| 703 | * LED functions. | ||
| 704 | */ | ||
| 705 | static void rt73usb_enable_led(struct rt2x00_dev *rt2x00dev) | ||
| 706 | { | ||
| 707 | u32 reg; | ||
| 708 | |||
| 709 | rt73usb_register_read(rt2x00dev, MAC_CSR14, ®); | ||
| 710 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
| 711 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
| 712 | rt73usb_register_write(rt2x00dev, MAC_CSR14, reg); | ||
| 713 | |||
| 714 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1); | ||
| 715 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) | ||
| 716 | rt2x00_set_field16(&rt2x00dev->led_reg, | ||
| 717 | MCU_LEDCS_LINK_A_STATUS, 1); | ||
| 718 | else | ||
| 719 | rt2x00_set_field16(&rt2x00dev->led_reg, | ||
| 720 | MCU_LEDCS_LINK_BG_STATUS, 1); | ||
| 721 | |||
| 722 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000, | ||
| 723 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
| 724 | } | ||
| 725 | |||
| 726 | static void rt73usb_disable_led(struct rt2x00_dev *rt2x00dev) | ||
| 727 | { | ||
| 728 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 0); | ||
| 729 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, 0); | ||
| 730 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, 0); | ||
| 731 | |||
| 732 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000, | ||
| 733 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
| 734 | } | ||
| 735 | |||
| 736 | static void rt73usb_activity_led(struct rt2x00_dev *rt2x00dev, int rssi) | ||
| 737 | { | ||
| 738 | u32 led; | ||
| 739 | |||
| 740 | if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH) | ||
| 741 | return; | ||
| 742 | |||
| 743 | /* | ||
| 744 | * Led handling requires a positive value for the rssi, | ||
| 745 | * to do that correctly we need to add the correction. | ||
| 746 | */ | ||
| 747 | rssi += rt2x00dev->rssi_offset; | ||
| 748 | |||
| 749 | if (rssi <= 30) | ||
| 750 | led = 0; | ||
| 751 | else if (rssi <= 39) | ||
| 752 | led = 1; | ||
| 753 | else if (rssi <= 49) | ||
| 754 | led = 2; | ||
| 755 | else if (rssi <= 53) | ||
| 756 | led = 3; | ||
| 757 | else if (rssi <= 63) | ||
| 758 | led = 4; | ||
| 759 | else | ||
| 760 | led = 5; | ||
| 761 | |||
| 762 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, led, | ||
| 763 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
| 764 | } | ||
| 765 | |||
| 766 | /* | ||
| 767 | * Link tuning | ||
| 768 | */ | ||
| 769 | static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev) | ||
| 770 | { | ||
| 771 | u32 reg; | ||
| 772 | |||
| 773 | /* | ||
| 774 | * Update FCS error count from register. | ||
| 775 | */ | ||
| 776 | rt73usb_register_read(rt2x00dev, STA_CSR0, ®); | ||
| 777 | rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR); | ||
| 778 | |||
| 779 | /* | ||
| 780 | * Update False CCA count from register. | ||
| 781 | */ | ||
| 782 | rt73usb_register_read(rt2x00dev, STA_CSR1, ®); | ||
| 783 | reg = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); | ||
| 784 | rt2x00dev->link.false_cca = | ||
| 785 | rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); | ||
| 786 | } | ||
| 787 | |||
| 788 | static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev) | ||
| 789 | { | ||
| 790 | rt73usb_bbp_write(rt2x00dev, 17, 0x20); | ||
| 791 | rt2x00dev->link.vgc_level = 0x20; | ||
| 792 | } | ||
| 793 | |||
| 794 | static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | ||
| 795 | { | ||
| 796 | int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); | ||
| 797 | u8 r17; | ||
| 798 | u8 up_bound; | ||
| 799 | u8 low_bound; | ||
| 800 | |||
| 801 | /* | ||
| 802 | * Update Led strength | ||
| 803 | */ | ||
| 804 | rt73usb_activity_led(rt2x00dev, rssi); | ||
| 805 | |||
| 806 | rt73usb_bbp_read(rt2x00dev, 17, &r17); | ||
| 807 | |||
| 808 | /* | ||
| 809 | * Determine r17 bounds. | ||
| 810 | */ | ||
| 811 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | ||
| 812 | low_bound = 0x28; | ||
| 813 | up_bound = 0x48; | ||
| 814 | |||
| 815 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | ||
| 816 | low_bound += 0x10; | ||
| 817 | up_bound += 0x10; | ||
| 818 | } | ||
| 819 | } else { | ||
| 820 | if (rssi > -82) { | ||
| 821 | low_bound = 0x1c; | ||
| 822 | up_bound = 0x40; | ||
| 823 | } else if (rssi > -84) { | ||
| 824 | low_bound = 0x1c; | ||
| 825 | up_bound = 0x20; | ||
| 826 | } else { | ||
| 827 | low_bound = 0x1c; | ||
| 828 | up_bound = 0x1c; | ||
| 829 | } | ||
| 830 | |||
| 831 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { | ||
| 832 | low_bound += 0x14; | ||
| 833 | up_bound += 0x10; | ||
| 834 | } | ||
| 835 | } | ||
| 836 | |||
| 837 | /* | ||
| 838 | * Special big-R17 for very short distance | ||
| 839 | */ | ||
| 840 | if (rssi > -35) { | ||
| 841 | if (r17 != 0x60) | ||
| 842 | rt73usb_bbp_write(rt2x00dev, 17, 0x60); | ||
| 843 | return; | ||
| 844 | } | ||
| 845 | |||
| 846 | /* | ||
| 847 | * Special big-R17 for short distance | ||
| 848 | */ | ||
| 849 | if (rssi >= -58) { | ||
| 850 | if (r17 != up_bound) | ||
| 851 | rt73usb_bbp_write(rt2x00dev, 17, up_bound); | ||
| 852 | return; | ||
| 853 | } | ||
| 854 | |||
| 855 | /* | ||
| 856 | * Special big-R17 for middle-short distance | ||
| 857 | */ | ||
| 858 | if (rssi >= -66) { | ||
| 859 | low_bound += 0x10; | ||
| 860 | if (r17 != low_bound) | ||
| 861 | rt73usb_bbp_write(rt2x00dev, 17, low_bound); | ||
| 862 | return; | ||
| 863 | } | ||
| 864 | |||
| 865 | /* | ||
| 866 | * Special mid-R17 for middle distance | ||
| 867 | */ | ||
| 868 | if (rssi >= -74) { | ||
| 869 | if (r17 != (low_bound + 0x10)) | ||
| 870 | rt73usb_bbp_write(rt2x00dev, 17, low_bound + 0x08); | ||
| 871 | return; | ||
| 872 | } | ||
| 873 | |||
| 874 | /* | ||
| 875 | * Special case: Change up_bound based on the rssi. | ||
| 876 | * Lower up_bound when rssi is weaker then -74 dBm. | ||
| 877 | */ | ||
| 878 | up_bound -= 2 * (-74 - rssi); | ||
| 879 | if (low_bound > up_bound) | ||
| 880 | up_bound = low_bound; | ||
| 881 | |||
| 882 | if (r17 > up_bound) { | ||
| 883 | rt73usb_bbp_write(rt2x00dev, 17, up_bound); | ||
| 884 | return; | ||
| 885 | } | ||
| 886 | |||
| 887 | /* | ||
| 888 | * r17 does not yet exceed upper limit, continue and base | ||
| 889 | * the r17 tuning on the false CCA count. | ||
| 890 | */ | ||
| 891 | if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) { | ||
| 892 | r17 += 4; | ||
| 893 | if (r17 > up_bound) | ||
| 894 | r17 = up_bound; | ||
| 895 | rt73usb_bbp_write(rt2x00dev, 17, r17); | ||
| 896 | } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) { | ||
| 897 | r17 -= 4; | ||
| 898 | if (r17 < low_bound) | ||
| 899 | r17 = low_bound; | ||
| 900 | rt73usb_bbp_write(rt2x00dev, 17, r17); | ||
| 901 | } | ||
| 902 | } | ||
| 903 | |||
| 904 | /* | ||
| 905 | * Firmware name function. | ||
| 906 | */ | ||
| 907 | static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev) | ||
| 908 | { | ||
| 909 | return FIRMWARE_RT2571; | ||
| 910 | } | ||
| 911 | |||
| 912 | /* | ||
| 913 | * Initialization functions. | ||
| 914 | */ | ||
| 915 | static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | ||
| 916 | const size_t len) | ||
| 917 | { | ||
| 918 | unsigned int i; | ||
| 919 | int status; | ||
| 920 | u32 reg; | ||
| 921 | char *ptr = data; | ||
| 922 | char *cache; | ||
| 923 | int buflen; | ||
| 924 | int timeout; | ||
| 925 | |||
| 926 | /* | ||
| 927 | * Wait for stable hardware. | ||
| 928 | */ | ||
| 929 | for (i = 0; i < 100; i++) { | ||
| 930 | rt73usb_register_read(rt2x00dev, MAC_CSR0, ®); | ||
| 931 | if (reg) | ||
| 932 | break; | ||
| 933 | msleep(1); | ||
| 934 | } | ||
| 935 | |||
| 936 | if (!reg) { | ||
| 937 | ERROR(rt2x00dev, "Unstable hardware.\n"); | ||
| 938 | return -EBUSY; | ||
| 939 | } | ||
| 940 | |||
| 941 | /* | ||
| 942 | * Write firmware to device. | ||
| 943 | * We setup a seperate cache for this action, | ||
| 944 | * since we are going to write larger chunks of data | ||
| 945 | * then normally used cache size. | ||
| 946 | */ | ||
| 947 | cache = kmalloc(CSR_CACHE_SIZE_FIRMWARE, GFP_KERNEL); | ||
| 948 | if (!cache) { | ||
| 949 | ERROR(rt2x00dev, "Failed to allocate firmware cache.\n"); | ||
| 950 | return -ENOMEM; | ||
| 951 | } | ||
| 952 | |||
| 953 | for (i = 0; i < len; i += CSR_CACHE_SIZE_FIRMWARE) { | ||
| 954 | buflen = min_t(int, len - i, CSR_CACHE_SIZE_FIRMWARE); | ||
| 955 | timeout = REGISTER_TIMEOUT * (buflen / sizeof(u32)); | ||
| 956 | |||
| 957 | memcpy(cache, ptr, buflen); | ||
| 958 | |||
| 959 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | ||
| 960 | USB_VENDOR_REQUEST_OUT, | ||
| 961 | FIRMWARE_IMAGE_BASE + i, 0x0000, | ||
| 962 | cache, buflen, timeout); | ||
| 963 | |||
| 964 | ptr += buflen; | ||
| 965 | } | ||
| 966 | |||
| 967 | kfree(cache); | ||
| 968 | |||
| 969 | /* | ||
| 970 | * Send firmware request to device to load firmware, | ||
| 971 | * we need to specify a long timeout time. | ||
| 972 | */ | ||
| 973 | status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, | ||
| 974 | 0x0000, USB_MODE_FIRMWARE, | ||
| 975 | REGISTER_TIMEOUT_FIRMWARE); | ||
| 976 | if (status < 0) { | ||
| 977 | ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); | ||
| 978 | return status; | ||
| 979 | } | ||
| 980 | |||
| 981 | rt73usb_disable_led(rt2x00dev); | ||
| 982 | |||
| 983 | return 0; | ||
| 984 | } | ||
| 985 | |||
| 986 | static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | ||
| 987 | { | ||
| 988 | u32 reg; | ||
| 989 | |||
| 990 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
| 991 | rt2x00_set_field32(®, TXRX_CSR0_AUTO_TX_SEQ, 1); | ||
| 992 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0); | ||
| 993 | rt2x00_set_field32(®, TXRX_CSR0_TX_WITHOUT_WAITING, 0); | ||
| 994 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
| 995 | |||
| 996 | rt73usb_register_read(rt2x00dev, TXRX_CSR1, ®); | ||
| 997 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0, 47); /* CCK Signal */ | ||
| 998 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0_VALID, 1); | ||
| 999 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID1, 30); /* Rssi */ | ||
| 1000 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID1_VALID, 1); | ||
| 1001 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID2, 42); /* OFDM Rate */ | ||
| 1002 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID2_VALID, 1); | ||
| 1003 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3, 30); /* Rssi */ | ||
| 1004 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3_VALID, 1); | ||
| 1005 | rt73usb_register_write(rt2x00dev, TXRX_CSR1, reg); | ||
| 1006 | |||
| 1007 | /* | ||
| 1008 | * CCK TXD BBP registers | ||
| 1009 | */ | ||
| 1010 | rt73usb_register_read(rt2x00dev, TXRX_CSR2, ®); | ||
| 1011 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0, 13); | ||
| 1012 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0_VALID, 1); | ||
| 1013 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID1, 12); | ||
| 1014 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID1_VALID, 1); | ||
| 1015 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID2, 11); | ||
| 1016 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID2_VALID, 1); | ||
| 1017 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3, 10); | ||
| 1018 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3_VALID, 1); | ||
| 1019 | rt73usb_register_write(rt2x00dev, TXRX_CSR2, reg); | ||
| 1020 | |||
| 1021 | /* | ||
| 1022 | * OFDM TXD BBP registers | ||
| 1023 | */ | ||
| 1024 | rt73usb_register_read(rt2x00dev, TXRX_CSR3, ®); | ||
| 1025 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0, 7); | ||
| 1026 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0_VALID, 1); | ||
| 1027 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1, 6); | ||
| 1028 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1_VALID, 1); | ||
| 1029 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2, 5); | ||
| 1030 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2_VALID, 1); | ||
| 1031 | rt73usb_register_write(rt2x00dev, TXRX_CSR3, reg); | ||
| 1032 | |||
| 1033 | rt73usb_register_read(rt2x00dev, TXRX_CSR7, ®); | ||
| 1034 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_6MBS, 59); | ||
| 1035 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_9MBS, 53); | ||
| 1036 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_12MBS, 49); | ||
| 1037 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_18MBS, 46); | ||
| 1038 | rt73usb_register_write(rt2x00dev, TXRX_CSR7, reg); | ||
| 1039 | |||
| 1040 | rt73usb_register_read(rt2x00dev, TXRX_CSR8, ®); | ||
| 1041 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_24MBS, 44); | ||
| 1042 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_36MBS, 42); | ||
| 1043 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_48MBS, 42); | ||
| 1044 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_54MBS, 42); | ||
| 1045 | rt73usb_register_write(rt2x00dev, TXRX_CSR8, reg); | ||
| 1046 | |||
| 1047 | rt73usb_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f); | ||
| 1048 | |||
| 1049 | rt73usb_register_read(rt2x00dev, MAC_CSR6, ®); | ||
| 1050 | rt2x00_set_field32(®, MAC_CSR6_MAX_FRAME_UNIT, 0xfff); | ||
| 1051 | rt73usb_register_write(rt2x00dev, MAC_CSR6, reg); | ||
| 1052 | |||
| 1053 | rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00000718); | ||
| 1054 | |||
| 1055 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) | ||
| 1056 | return -EBUSY; | ||
| 1057 | |||
| 1058 | rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00); | ||
| 1059 | |||
| 1060 | /* | ||
| 1061 | * Invalidate all Shared Keys (SEC_CSR0), | ||
| 1062 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) | ||
| 1063 | */ | ||
| 1064 | rt73usb_register_write(rt2x00dev, SEC_CSR0, 0x00000000); | ||
| 1065 | rt73usb_register_write(rt2x00dev, SEC_CSR1, 0x00000000); | ||
| 1066 | rt73usb_register_write(rt2x00dev, SEC_CSR5, 0x00000000); | ||
| 1067 | |||
| 1068 | reg = 0x000023b0; | ||
| 1069 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | ||
| 1070 | rt2x00_rf(&rt2x00dev->chip, RF2527)) | ||
| 1071 | rt2x00_set_field32(®, PHY_CSR1_RF_RPI, 1); | ||
| 1072 | rt73usb_register_write(rt2x00dev, PHY_CSR1, reg); | ||
| 1073 | |||
| 1074 | rt73usb_register_write(rt2x00dev, PHY_CSR5, 0x00040a06); | ||
| 1075 | rt73usb_register_write(rt2x00dev, PHY_CSR6, 0x00080606); | ||
| 1076 | rt73usb_register_write(rt2x00dev, PHY_CSR7, 0x00000408); | ||
| 1077 | |||
| 1078 | rt73usb_register_read(rt2x00dev, AC_TXOP_CSR0, ®); | ||
| 1079 | rt2x00_set_field32(®, AC_TXOP_CSR0_AC0_TX_OP, 0); | ||
| 1080 | rt2x00_set_field32(®, AC_TXOP_CSR0_AC1_TX_OP, 0); | ||
| 1081 | rt73usb_register_write(rt2x00dev, AC_TXOP_CSR0, reg); | ||
| 1082 | |||
| 1083 | rt73usb_register_read(rt2x00dev, AC_TXOP_CSR1, ®); | ||
| 1084 | rt2x00_set_field32(®, AC_TXOP_CSR1_AC2_TX_OP, 192); | ||
| 1085 | rt2x00_set_field32(®, AC_TXOP_CSR1_AC3_TX_OP, 48); | ||
| 1086 | rt73usb_register_write(rt2x00dev, AC_TXOP_CSR1, reg); | ||
| 1087 | |||
| 1088 | rt73usb_register_read(rt2x00dev, MAC_CSR9, ®); | ||
| 1089 | rt2x00_set_field32(®, MAC_CSR9_CW_SELECT, 0); | ||
| 1090 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); | ||
| 1091 | |||
| 1092 | /* | ||
| 1093 | * We must clear the error counters. | ||
| 1094 | * These registers are cleared on read, | ||
| 1095 | * so we may pass a useless variable to store the value. | ||
| 1096 | */ | ||
| 1097 | rt73usb_register_read(rt2x00dev, STA_CSR0, ®); | ||
| 1098 | rt73usb_register_read(rt2x00dev, STA_CSR1, ®); | ||
| 1099 | rt73usb_register_read(rt2x00dev, STA_CSR2, ®); | ||
| 1100 | |||
| 1101 | /* | ||
| 1102 | * Reset MAC and BBP registers. | ||
| 1103 | */ | ||
| 1104 | rt73usb_register_read(rt2x00dev, MAC_CSR1, ®); | ||
| 1105 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 1); | ||
| 1106 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 1); | ||
| 1107 | rt73usb_register_write(rt2x00dev, MAC_CSR1, reg); | ||
| 1108 | |||
| 1109 | rt73usb_register_read(rt2x00dev, MAC_CSR1, ®); | ||
| 1110 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 0); | ||
| 1111 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 0); | ||
| 1112 | rt73usb_register_write(rt2x00dev, MAC_CSR1, reg); | ||
| 1113 | |||
| 1114 | rt73usb_register_read(rt2x00dev, MAC_CSR1, ®); | ||
| 1115 | rt2x00_set_field32(®, MAC_CSR1_HOST_READY, 1); | ||
| 1116 | rt73usb_register_write(rt2x00dev, MAC_CSR1, reg); | ||
| 1117 | |||
| 1118 | return 0; | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev) | ||
| 1122 | { | ||
| 1123 | unsigned int i; | ||
| 1124 | u16 eeprom; | ||
| 1125 | u8 reg_id; | ||
| 1126 | u8 value; | ||
| 1127 | |||
| 1128 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 1129 | rt73usb_bbp_read(rt2x00dev, 0, &value); | ||
| 1130 | if ((value != 0xff) && (value != 0x00)) | ||
| 1131 | goto continue_csr_init; | ||
| 1132 | NOTICE(rt2x00dev, "Waiting for BBP register.\n"); | ||
| 1133 | udelay(REGISTER_BUSY_DELAY); | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | ||
| 1137 | return -EACCES; | ||
| 1138 | |||
| 1139 | continue_csr_init: | ||
| 1140 | rt73usb_bbp_write(rt2x00dev, 3, 0x80); | ||
| 1141 | rt73usb_bbp_write(rt2x00dev, 15, 0x30); | ||
| 1142 | rt73usb_bbp_write(rt2x00dev, 21, 0xc8); | ||
| 1143 | rt73usb_bbp_write(rt2x00dev, 22, 0x38); | ||
| 1144 | rt73usb_bbp_write(rt2x00dev, 23, 0x06); | ||
| 1145 | rt73usb_bbp_write(rt2x00dev, 24, 0xfe); | ||
| 1146 | rt73usb_bbp_write(rt2x00dev, 25, 0x0a); | ||
| 1147 | rt73usb_bbp_write(rt2x00dev, 26, 0x0d); | ||
| 1148 | rt73usb_bbp_write(rt2x00dev, 32, 0x0b); | ||
| 1149 | rt73usb_bbp_write(rt2x00dev, 34, 0x12); | ||
| 1150 | rt73usb_bbp_write(rt2x00dev, 37, 0x07); | ||
| 1151 | rt73usb_bbp_write(rt2x00dev, 39, 0xf8); | ||
| 1152 | rt73usb_bbp_write(rt2x00dev, 41, 0x60); | ||
| 1153 | rt73usb_bbp_write(rt2x00dev, 53, 0x10); | ||
| 1154 | rt73usb_bbp_write(rt2x00dev, 54, 0x18); | ||
| 1155 | rt73usb_bbp_write(rt2x00dev, 60, 0x10); | ||
| 1156 | rt73usb_bbp_write(rt2x00dev, 61, 0x04); | ||
| 1157 | rt73usb_bbp_write(rt2x00dev, 62, 0x04); | ||
| 1158 | rt73usb_bbp_write(rt2x00dev, 75, 0xfe); | ||
| 1159 | rt73usb_bbp_write(rt2x00dev, 86, 0xfe); | ||
| 1160 | rt73usb_bbp_write(rt2x00dev, 88, 0xfe); | ||
| 1161 | rt73usb_bbp_write(rt2x00dev, 90, 0x0f); | ||
| 1162 | rt73usb_bbp_write(rt2x00dev, 99, 0x00); | ||
| 1163 | rt73usb_bbp_write(rt2x00dev, 102, 0x16); | ||
| 1164 | rt73usb_bbp_write(rt2x00dev, 107, 0x04); | ||
| 1165 | |||
| 1166 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
| 1167 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | ||
| 1168 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | ||
| 1169 | |||
| 1170 | if (eeprom != 0xffff && eeprom != 0x0000) { | ||
| 1171 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | ||
| 1172 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | ||
| 1173 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
| 1174 | reg_id, value); | ||
| 1175 | rt73usb_bbp_write(rt2x00dev, reg_id, value); | ||
| 1176 | } | ||
| 1177 | } | ||
| 1178 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
| 1179 | |||
| 1180 | return 0; | ||
| 1181 | } | ||
| 1182 | |||
| 1183 | /* | ||
| 1184 | * Device state switch handlers. | ||
| 1185 | */ | ||
| 1186 | static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev, | ||
| 1187 | enum dev_state state) | ||
| 1188 | { | ||
| 1189 | u32 reg; | ||
| 1190 | |||
| 1191 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
| 1192 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, | ||
| 1193 | state == STATE_RADIO_RX_OFF); | ||
| 1194 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
| 1195 | } | ||
| 1196 | |||
| 1197 | static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 1198 | { | ||
| 1199 | /* | ||
| 1200 | * Initialize all registers. | ||
| 1201 | */ | ||
| 1202 | if (rt73usb_init_registers(rt2x00dev) || | ||
| 1203 | rt73usb_init_bbp(rt2x00dev)) { | ||
| 1204 | ERROR(rt2x00dev, "Register initialization failed.\n"); | ||
| 1205 | return -EIO; | ||
| 1206 | } | ||
| 1207 | |||
| 1208 | rt2x00usb_enable_radio(rt2x00dev); | ||
| 1209 | |||
| 1210 | /* | ||
| 1211 | * Enable LED | ||
| 1212 | */ | ||
| 1213 | rt73usb_enable_led(rt2x00dev); | ||
| 1214 | |||
| 1215 | return 0; | ||
| 1216 | } | ||
| 1217 | |||
| 1218 | static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev) | ||
| 1219 | { | ||
| 1220 | /* | ||
| 1221 | * Disable LED | ||
| 1222 | */ | ||
| 1223 | rt73usb_disable_led(rt2x00dev); | ||
| 1224 | |||
| 1225 | rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | ||
| 1226 | |||
| 1227 | /* | ||
| 1228 | * Disable synchronisation. | ||
| 1229 | */ | ||
| 1230 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
| 1231 | |||
| 1232 | rt2x00usb_disable_radio(rt2x00dev); | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | ||
| 1236 | { | ||
| 1237 | u32 reg; | ||
| 1238 | unsigned int i; | ||
| 1239 | char put_to_sleep; | ||
| 1240 | char current_state; | ||
| 1241 | |||
| 1242 | put_to_sleep = (state != STATE_AWAKE); | ||
| 1243 | |||
| 1244 | rt73usb_register_read(rt2x00dev, MAC_CSR12, ®); | ||
| 1245 | rt2x00_set_field32(®, MAC_CSR12_FORCE_WAKEUP, !put_to_sleep); | ||
| 1246 | rt2x00_set_field32(®, MAC_CSR12_PUT_TO_SLEEP, put_to_sleep); | ||
| 1247 | rt73usb_register_write(rt2x00dev, MAC_CSR12, reg); | ||
| 1248 | |||
| 1249 | /* | ||
| 1250 | * Device is not guaranteed to be in the requested state yet. | ||
| 1251 | * We must wait until the register indicates that the | ||
| 1252 | * device has entered the correct state. | ||
| 1253 | */ | ||
| 1254 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
| 1255 | rt73usb_register_read(rt2x00dev, MAC_CSR12, ®); | ||
| 1256 | current_state = | ||
| 1257 | rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); | ||
| 1258 | if (current_state == !put_to_sleep) | ||
| 1259 | return 0; | ||
| 1260 | msleep(10); | ||
| 1261 | } | ||
| 1262 | |||
| 1263 | NOTICE(rt2x00dev, "Device failed to enter state %d, " | ||
| 1264 | "current device state %d.\n", !put_to_sleep, current_state); | ||
| 1265 | |||
| 1266 | return -EBUSY; | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | ||
| 1270 | enum dev_state state) | ||
| 1271 | { | ||
| 1272 | int retval = 0; | ||
| 1273 | |||
| 1274 | switch (state) { | ||
| 1275 | case STATE_RADIO_ON: | ||
| 1276 | retval = rt73usb_enable_radio(rt2x00dev); | ||
| 1277 | break; | ||
| 1278 | case STATE_RADIO_OFF: | ||
| 1279 | rt73usb_disable_radio(rt2x00dev); | ||
| 1280 | break; | ||
| 1281 | case STATE_RADIO_RX_ON: | ||
| 1282 | case STATE_RADIO_RX_OFF: | ||
| 1283 | rt73usb_toggle_rx(rt2x00dev, state); | ||
| 1284 | break; | ||
| 1285 | case STATE_DEEP_SLEEP: | ||
| 1286 | case STATE_SLEEP: | ||
| 1287 | case STATE_STANDBY: | ||
| 1288 | case STATE_AWAKE: | ||
| 1289 | retval = rt73usb_set_state(rt2x00dev, state); | ||
| 1290 | break; | ||
| 1291 | default: | ||
| 1292 | retval = -ENOTSUPP; | ||
| 1293 | break; | ||
| 1294 | } | ||
| 1295 | |||
| 1296 | return retval; | ||
| 1297 | } | ||
| 1298 | |||
| 1299 | /* | ||
| 1300 | * TX descriptor initialization | ||
| 1301 | */ | ||
| 1302 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | ||
| 1303 | struct data_desc *txd, | ||
| 1304 | struct data_entry_desc *desc, | ||
| 1305 | struct ieee80211_hdr *ieee80211hdr, | ||
| 1306 | unsigned int length, | ||
| 1307 | struct ieee80211_tx_control *control) | ||
| 1308 | { | ||
| 1309 | u32 word; | ||
| 1310 | |||
| 1311 | /* | ||
| 1312 | * Start writing the descriptor words. | ||
| 1313 | */ | ||
| 1314 | rt2x00_desc_read(txd, 1, &word); | ||
| 1315 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue); | ||
| 1316 | rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs); | ||
| 1317 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | ||
| 1318 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | ||
| 1319 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | ||
| 1320 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | ||
| 1321 | rt2x00_desc_write(txd, 1, word); | ||
| 1322 | |||
| 1323 | rt2x00_desc_read(txd, 2, &word); | ||
| 1324 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | ||
| 1325 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | ||
| 1326 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | ||
| 1327 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | ||
| 1328 | rt2x00_desc_write(txd, 2, word); | ||
| 1329 | |||
| 1330 | rt2x00_desc_read(txd, 5, &word); | ||
| 1331 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | ||
| 1332 | TXPOWER_TO_DEV(control->power_level)); | ||
| 1333 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | ||
| 1334 | rt2x00_desc_write(txd, 5, word); | ||
| 1335 | |||
| 1336 | rt2x00_desc_read(txd, 0, &word); | ||
| 1337 | rt2x00_set_field32(&word, TXD_W0_BURST, | ||
| 1338 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | ||
| 1339 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | ||
| 1340 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | ||
| 1341 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | ||
| 1342 | rt2x00_set_field32(&word, TXD_W0_ACK, | ||
| 1343 | !(control->flags & IEEE80211_TXCTL_NO_ACK)); | ||
| 1344 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | ||
| 1345 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | ||
| 1346 | rt2x00_set_field32(&word, TXD_W0_OFDM, | ||
| 1347 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | ||
| 1348 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | ||
| 1349 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | ||
| 1350 | !!(control->flags & | ||
| 1351 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | ||
| 1352 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | ||
| 1353 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length); | ||
| 1354 | rt2x00_set_field32(&word, TXD_W0_BURST2, | ||
| 1355 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | ||
| 1356 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | ||
| 1357 | rt2x00_desc_write(txd, 0, word); | ||
| 1358 | } | ||
| 1359 | |||
| 1360 | /* | ||
| 1361 | * TX data initialization | ||
| 1362 | */ | ||
| 1363 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
| 1364 | unsigned int queue) | ||
| 1365 | { | ||
| 1366 | u32 reg; | ||
| 1367 | |||
| 1368 | if (queue != IEEE80211_TX_QUEUE_BEACON) | ||
| 1369 | return; | ||
| 1370 | |||
| 1371 | /* | ||
| 1372 | * For Wi-Fi faily generated beacons between participating stations. | ||
| 1373 | * Set TBTT phase adaptive adjustment step to 8us (default 16us) | ||
| 1374 | */ | ||
| 1375 | rt73usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); | ||
| 1376 | |||
| 1377 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
| 1378 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { | ||
| 1379 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | ||
| 1380 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
| 1381 | } | ||
| 1382 | } | ||
| 1383 | |||
| 1384 | /* | ||
| 1385 | * RX control handlers | ||
| 1386 | */ | ||
| 1387 | static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | ||
| 1388 | { | ||
| 1389 | u16 eeprom; | ||
| 1390 | u8 offset; | ||
| 1391 | u8 lna; | ||
| 1392 | |||
| 1393 | lna = rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_LNA); | ||
| 1394 | switch (lna) { | ||
| 1395 | case 3: | ||
| 1396 | offset = 90; | ||
| 1397 | break; | ||
| 1398 | case 2: | ||
| 1399 | offset = 74; | ||
| 1400 | break; | ||
| 1401 | case 1: | ||
| 1402 | offset = 64; | ||
| 1403 | break; | ||
| 1404 | default: | ||
| 1405 | return 0; | ||
| 1406 | } | ||
| 1407 | |||
| 1408 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | ||
| 1409 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | ||
| 1410 | if (lna == 3 || lna == 2) | ||
| 1411 | offset += 10; | ||
| 1412 | } else { | ||
| 1413 | if (lna == 3) | ||
| 1414 | offset += 6; | ||
| 1415 | else if (lna == 2) | ||
| 1416 | offset += 8; | ||
| 1417 | } | ||
| 1418 | |||
| 1419 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom); | ||
| 1420 | offset -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1); | ||
| 1421 | } else { | ||
| 1422 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) | ||
| 1423 | offset += 14; | ||
| 1424 | |||
| 1425 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); | ||
| 1426 | offset -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1); | ||
| 1427 | } | ||
| 1428 | |||
| 1429 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; | ||
| 1430 | } | ||
| 1431 | |||
| 1432 | static int rt73usb_fill_rxdone(struct data_entry *entry, | ||
| 1433 | int *signal, int *rssi, int *ofdm, int *size) | ||
| 1434 | { | ||
| 1435 | struct data_desc *rxd = (struct data_desc *)entry->skb->data; | ||
| 1436 | u32 word0; | ||
| 1437 | u32 word1; | ||
| 1438 | |||
| 1439 | rt2x00_desc_read(rxd, 0, &word0); | ||
| 1440 | rt2x00_desc_read(rxd, 1, &word1); | ||
| 1441 | |||
| 1442 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR) || | ||
| 1443 | rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR)) | ||
| 1444 | return -EINVAL; | ||
| 1445 | |||
| 1446 | /* | ||
| 1447 | * Obtain the status about this packet. | ||
| 1448 | */ | ||
| 1449 | *signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | ||
| 1450 | *rssi = rt73usb_agc_to_rssi(entry->ring->rt2x00dev, word1); | ||
| 1451 | *ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | ||
| 1452 | *size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
| 1453 | |||
| 1454 | /* | ||
| 1455 | * Pull the skb to clear the descriptor area. | ||
| 1456 | */ | ||
| 1457 | skb_pull(entry->skb, entry->ring->desc_size); | ||
| 1458 | |||
| 1459 | return 0; | ||
| 1460 | } | ||
| 1461 | |||
| 1462 | /* | ||
| 1463 | * Device probe functions. | ||
| 1464 | */ | ||
| 1465 | static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | ||
| 1466 | { | ||
| 1467 | u16 word; | ||
| 1468 | u8 *mac; | ||
| 1469 | s8 value; | ||
| 1470 | |||
| 1471 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); | ||
| 1472 | |||
| 1473 | /* | ||
| 1474 | * Start validation of the data that has been read. | ||
| 1475 | */ | ||
| 1476 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | ||
| 1477 | if (!is_valid_ether_addr(mac)) { | ||
| 1478 | random_ether_addr(mac); | ||
| 1479 | EEPROM(rt2x00dev, "MAC: " MAC_FMT "\n", MAC_ARG(mac)); | ||
| 1480 | } | ||
| 1481 | |||
| 1482 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | ||
| 1483 | if (word == 0xffff) { | ||
| 1484 | rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2); | ||
| 1485 | rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 2); | ||
| 1486 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 2); | ||
| 1487 | rt2x00_set_field16(&word, EEPROM_ANTENNA_FRAME_TYPE, 0); | ||
| 1488 | rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0); | ||
| 1489 | rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); | ||
| 1490 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF5226); | ||
| 1491 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | ||
| 1492 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | ||
| 1493 | } | ||
| 1494 | |||
| 1495 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | ||
| 1496 | if (word == 0xffff) { | ||
| 1497 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA, 0); | ||
| 1498 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | ||
| 1499 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | ||
| 1500 | } | ||
| 1501 | |||
| 1502 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &word); | ||
| 1503 | if (word == 0xffff) { | ||
| 1504 | rt2x00_set_field16(&word, EEPROM_LED_POLARITY_RDY_G, 0); | ||
| 1505 | rt2x00_set_field16(&word, EEPROM_LED_POLARITY_RDY_A, 0); | ||
| 1506 | rt2x00_set_field16(&word, EEPROM_LED_POLARITY_ACT, 0); | ||
| 1507 | rt2x00_set_field16(&word, EEPROM_LED_POLARITY_GPIO_0, 0); | ||
| 1508 | rt2x00_set_field16(&word, EEPROM_LED_POLARITY_GPIO_1, 0); | ||
| 1509 | rt2x00_set_field16(&word, EEPROM_LED_POLARITY_GPIO_2, 0); | ||
| 1510 | rt2x00_set_field16(&word, EEPROM_LED_POLARITY_GPIO_3, 0); | ||
| 1511 | rt2x00_set_field16(&word, EEPROM_LED_POLARITY_GPIO_4, 0); | ||
| 1512 | rt2x00_set_field16(&word, EEPROM_LED_LED_MODE, | ||
| 1513 | LED_MODE_DEFAULT); | ||
| 1514 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED, word); | ||
| 1515 | EEPROM(rt2x00dev, "Led: 0x%04x\n", word); | ||
| 1516 | } | ||
| 1517 | |||
| 1518 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); | ||
| 1519 | if (word == 0xffff) { | ||
| 1520 | rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); | ||
| 1521 | rt2x00_set_field16(&word, EEPROM_FREQ_SEQ, 0); | ||
| 1522 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); | ||
| 1523 | EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); | ||
| 1524 | } | ||
| 1525 | |||
| 1526 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &word); | ||
| 1527 | if (word == 0xffff) { | ||
| 1528 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); | ||
| 1529 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); | ||
| 1530 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); | ||
| 1531 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | ||
| 1532 | } else { | ||
| 1533 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_1); | ||
| 1534 | if (value < -10 || value > 10) | ||
| 1535 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); | ||
| 1536 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_2); | ||
| 1537 | if (value < -10 || value > 10) | ||
| 1538 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); | ||
| 1539 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &word); | ||
| 1543 | if (word == 0xffff) { | ||
| 1544 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | ||
| 1545 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | ||
| 1546 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | ||
| 1547 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | ||
| 1548 | } else { | ||
| 1549 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | ||
| 1550 | if (value < -10 || value > 10) | ||
| 1551 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | ||
| 1552 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_2); | ||
| 1553 | if (value < -10 || value > 10) | ||
| 1554 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | ||
| 1555 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | ||
| 1556 | } | ||
| 1557 | |||
| 1558 | return 0; | ||
| 1559 | } | ||
| 1560 | |||
| 1561 | static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | ||
| 1562 | { | ||
| 1563 | u32 reg; | ||
| 1564 | u16 value; | ||
| 1565 | u16 eeprom; | ||
| 1566 | |||
| 1567 | /* | ||
| 1568 | * Read EEPROM word for configuration. | ||
| 1569 | */ | ||
| 1570 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
| 1571 | |||
| 1572 | /* | ||
| 1573 | * Identify RF chipset. | ||
| 1574 | */ | ||
| 1575 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | ||
| 1576 | rt73usb_register_read(rt2x00dev, MAC_CSR0, ®); | ||
| 1577 | rt2x00_set_chip(rt2x00dev, RT2571, value, reg); | ||
| 1578 | |||
| 1579 | if (!rt2x00_rev(&rt2x00dev->chip, 0x25730)) { | ||
| 1580 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); | ||
| 1581 | return -ENODEV; | ||
| 1582 | } | ||
| 1583 | |||
| 1584 | if (!rt2x00_rf(&rt2x00dev->chip, RF5226) && | ||
| 1585 | !rt2x00_rf(&rt2x00dev->chip, RF2528) && | ||
| 1586 | !rt2x00_rf(&rt2x00dev->chip, RF5225) && | ||
| 1587 | !rt2x00_rf(&rt2x00dev->chip, RF2527)) { | ||
| 1588 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | ||
| 1589 | return -ENODEV; | ||
| 1590 | } | ||
| 1591 | |||
| 1592 | /* | ||
| 1593 | * Identify default antenna configuration. | ||
| 1594 | */ | ||
| 1595 | rt2x00dev->hw->conf.antenna_sel_tx = | ||
| 1596 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT); | ||
| 1597 | rt2x00dev->hw->conf.antenna_sel_rx = | ||
| 1598 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT); | ||
| 1599 | |||
| 1600 | /* | ||
| 1601 | * Read the Frame type. | ||
| 1602 | */ | ||
| 1603 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE)) | ||
| 1604 | __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); | ||
| 1605 | |||
| 1606 | /* | ||
| 1607 | * Read frequency offset. | ||
| 1608 | */ | ||
| 1609 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); | ||
| 1610 | rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); | ||
| 1611 | |||
| 1612 | /* | ||
| 1613 | * Read external LNA informations. | ||
| 1614 | */ | ||
| 1615 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | ||
| 1616 | |||
| 1617 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA)) { | ||
| 1618 | __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | ||
| 1619 | __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | ||
| 1620 | } | ||
| 1621 | |||
| 1622 | /* | ||
| 1623 | * Store led settings, for correct led behaviour. | ||
| 1624 | */ | ||
| 1625 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | ||
| 1626 | |||
| 1627 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, | ||
| 1628 | rt2x00dev->led_mode); | ||
| 1629 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, | ||
| 1630 | rt2x00_get_field16(eeprom, | ||
| 1631 | EEPROM_LED_POLARITY_GPIO_0)); | ||
| 1632 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, | ||
| 1633 | rt2x00_get_field16(eeprom, | ||
| 1634 | EEPROM_LED_POLARITY_GPIO_1)); | ||
| 1635 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, | ||
| 1636 | rt2x00_get_field16(eeprom, | ||
| 1637 | EEPROM_LED_POLARITY_GPIO_2)); | ||
| 1638 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, | ||
| 1639 | rt2x00_get_field16(eeprom, | ||
| 1640 | EEPROM_LED_POLARITY_GPIO_3)); | ||
| 1641 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, | ||
| 1642 | rt2x00_get_field16(eeprom, | ||
| 1643 | EEPROM_LED_POLARITY_GPIO_4)); | ||
| 1644 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, | ||
| 1645 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); | ||
| 1646 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, | ||
| 1647 | rt2x00_get_field16(eeprom, | ||
| 1648 | EEPROM_LED_POLARITY_RDY_G)); | ||
| 1649 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, | ||
| 1650 | rt2x00_get_field16(eeprom, | ||
| 1651 | EEPROM_LED_POLARITY_RDY_A)); | ||
| 1652 | |||
| 1653 | return 0; | ||
| 1654 | } | ||
| 1655 | |||
| 1656 | /* | ||
| 1657 | * RF value list for RF2528 | ||
| 1658 | * Supports: 2.4 GHz | ||
| 1659 | */ | ||
| 1660 | static const struct rf_channel rf_vals_bg_2528[] = { | ||
| 1661 | { 1, 0x00002c0c, 0x00000786, 0x00068255, 0x000fea0b }, | ||
| 1662 | { 2, 0x00002c0c, 0x00000786, 0x00068255, 0x000fea1f }, | ||
| 1663 | { 3, 0x00002c0c, 0x0000078a, 0x00068255, 0x000fea0b }, | ||
| 1664 | { 4, 0x00002c0c, 0x0000078a, 0x00068255, 0x000fea1f }, | ||
| 1665 | { 5, 0x00002c0c, 0x0000078e, 0x00068255, 0x000fea0b }, | ||
| 1666 | { 6, 0x00002c0c, 0x0000078e, 0x00068255, 0x000fea1f }, | ||
| 1667 | { 7, 0x00002c0c, 0x00000792, 0x00068255, 0x000fea0b }, | ||
| 1668 | { 8, 0x00002c0c, 0x00000792, 0x00068255, 0x000fea1f }, | ||
| 1669 | { 9, 0x00002c0c, 0x00000796, 0x00068255, 0x000fea0b }, | ||
| 1670 | { 10, 0x00002c0c, 0x00000796, 0x00068255, 0x000fea1f }, | ||
| 1671 | { 11, 0x00002c0c, 0x0000079a, 0x00068255, 0x000fea0b }, | ||
| 1672 | { 12, 0x00002c0c, 0x0000079a, 0x00068255, 0x000fea1f }, | ||
| 1673 | { 13, 0x00002c0c, 0x0000079e, 0x00068255, 0x000fea0b }, | ||
| 1674 | { 14, 0x00002c0c, 0x000007a2, 0x00068255, 0x000fea13 }, | ||
| 1675 | }; | ||
| 1676 | |||
| 1677 | /* | ||
| 1678 | * RF value list for RF5226 | ||
| 1679 | * Supports: 2.4 GHz & 5.2 GHz | ||
| 1680 | */ | ||
| 1681 | static const struct rf_channel rf_vals_5226[] = { | ||
| 1682 | { 1, 0x00002c0c, 0x00000786, 0x00068255, 0x000fea0b }, | ||
| 1683 | { 2, 0x00002c0c, 0x00000786, 0x00068255, 0x000fea1f }, | ||
| 1684 | { 3, 0x00002c0c, 0x0000078a, 0x00068255, 0x000fea0b }, | ||
| 1685 | { 4, 0x00002c0c, 0x0000078a, 0x00068255, 0x000fea1f }, | ||
| 1686 | { 5, 0x00002c0c, 0x0000078e, 0x00068255, 0x000fea0b }, | ||
| 1687 | { 6, 0x00002c0c, 0x0000078e, 0x00068255, 0x000fea1f }, | ||
| 1688 | { 7, 0x00002c0c, 0x00000792, 0x00068255, 0x000fea0b }, | ||
| 1689 | { 8, 0x00002c0c, 0x00000792, 0x00068255, 0x000fea1f }, | ||
| 1690 | { 9, 0x00002c0c, 0x00000796, 0x00068255, 0x000fea0b }, | ||
| 1691 | { 10, 0x00002c0c, 0x00000796, 0x00068255, 0x000fea1f }, | ||
| 1692 | { 11, 0x00002c0c, 0x0000079a, 0x00068255, 0x000fea0b }, | ||
| 1693 | { 12, 0x00002c0c, 0x0000079a, 0x00068255, 0x000fea1f }, | ||
| 1694 | { 13, 0x00002c0c, 0x0000079e, 0x00068255, 0x000fea0b }, | ||
| 1695 | { 14, 0x00002c0c, 0x000007a2, 0x00068255, 0x000fea13 }, | ||
| 1696 | |||
| 1697 | /* 802.11 UNI / HyperLan 2 */ | ||
| 1698 | { 36, 0x00002c0c, 0x0000099a, 0x00098255, 0x000fea23 }, | ||
| 1699 | { 40, 0x00002c0c, 0x000009a2, 0x00098255, 0x000fea03 }, | ||
| 1700 | { 44, 0x00002c0c, 0x000009a6, 0x00098255, 0x000fea0b }, | ||
| 1701 | { 48, 0x00002c0c, 0x000009aa, 0x00098255, 0x000fea13 }, | ||
| 1702 | { 52, 0x00002c0c, 0x000009ae, 0x00098255, 0x000fea1b }, | ||
| 1703 | { 56, 0x00002c0c, 0x000009b2, 0x00098255, 0x000fea23 }, | ||
| 1704 | { 60, 0x00002c0c, 0x000009ba, 0x00098255, 0x000fea03 }, | ||
| 1705 | { 64, 0x00002c0c, 0x000009be, 0x00098255, 0x000fea0b }, | ||
| 1706 | |||
| 1707 | /* 802.11 HyperLan 2 */ | ||
| 1708 | { 100, 0x00002c0c, 0x00000a2a, 0x000b8255, 0x000fea03 }, | ||
| 1709 | { 104, 0x00002c0c, 0x00000a2e, 0x000b8255, 0x000fea0b }, | ||
| 1710 | { 108, 0x00002c0c, 0x00000a32, 0x000b8255, 0x000fea13 }, | ||
| 1711 | { 112, 0x00002c0c, 0x00000a36, 0x000b8255, 0x000fea1b }, | ||
| 1712 | { 116, 0x00002c0c, 0x00000a3a, 0x000b8255, 0x000fea23 }, | ||
| 1713 | { 120, 0x00002c0c, 0x00000a82, 0x000b8255, 0x000fea03 }, | ||
| 1714 | { 124, 0x00002c0c, 0x00000a86, 0x000b8255, 0x000fea0b }, | ||
| 1715 | { 128, 0x00002c0c, 0x00000a8a, 0x000b8255, 0x000fea13 }, | ||
| 1716 | { 132, 0x00002c0c, 0x00000a8e, 0x000b8255, 0x000fea1b }, | ||
| 1717 | { 136, 0x00002c0c, 0x00000a92, 0x000b8255, 0x000fea23 }, | ||
| 1718 | |||
| 1719 | /* 802.11 UNII */ | ||
| 1720 | { 140, 0x00002c0c, 0x00000a9a, 0x000b8255, 0x000fea03 }, | ||
| 1721 | { 149, 0x00002c0c, 0x00000aa2, 0x000b8255, 0x000fea1f }, | ||
| 1722 | { 153, 0x00002c0c, 0x00000aa6, 0x000b8255, 0x000fea27 }, | ||
| 1723 | { 157, 0x00002c0c, 0x00000aae, 0x000b8255, 0x000fea07 }, | ||
| 1724 | { 161, 0x00002c0c, 0x00000ab2, 0x000b8255, 0x000fea0f }, | ||
| 1725 | { 165, 0x00002c0c, 0x00000ab6, 0x000b8255, 0x000fea17 }, | ||
| 1726 | |||
| 1727 | /* MMAC(Japan)J52 ch 34,38,42,46 */ | ||
| 1728 | { 34, 0x00002c0c, 0x0008099a, 0x000da255, 0x000d3a0b }, | ||
| 1729 | { 38, 0x00002c0c, 0x0008099e, 0x000da255, 0x000d3a13 }, | ||
| 1730 | { 42, 0x00002c0c, 0x000809a2, 0x000da255, 0x000d3a1b }, | ||
| 1731 | { 46, 0x00002c0c, 0x000809a6, 0x000da255, 0x000d3a23 }, | ||
| 1732 | }; | ||
| 1733 | |||
| 1734 | /* | ||
| 1735 | * RF value list for RF5225 & RF2527 | ||
| 1736 | * Supports: 2.4 GHz & 5.2 GHz | ||
| 1737 | */ | ||
| 1738 | static const struct rf_channel rf_vals_5225_2527[] = { | ||
| 1739 | { 1, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa0b }, | ||
| 1740 | { 2, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa1f }, | ||
| 1741 | { 3, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa0b }, | ||
| 1742 | { 4, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa1f }, | ||
| 1743 | { 5, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa0b }, | ||
| 1744 | { 6, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa1f }, | ||
| 1745 | { 7, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa0b }, | ||
| 1746 | { 8, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa1f }, | ||
| 1747 | { 9, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa0b }, | ||
| 1748 | { 10, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa1f }, | ||
| 1749 | { 11, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa0b }, | ||
| 1750 | { 12, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa1f }, | ||
| 1751 | { 13, 0x00002ccc, 0x0000479e, 0x00068455, 0x000ffa0b }, | ||
| 1752 | { 14, 0x00002ccc, 0x000047a2, 0x00068455, 0x000ffa13 }, | ||
| 1753 | |||
| 1754 | /* 802.11 UNI / HyperLan 2 */ | ||
| 1755 | { 36, 0x00002ccc, 0x0000499a, 0x0009be55, 0x000ffa23 }, | ||
| 1756 | { 40, 0x00002ccc, 0x000049a2, 0x0009be55, 0x000ffa03 }, | ||
| 1757 | { 44, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000ffa0b }, | ||
| 1758 | { 48, 0x00002ccc, 0x000049aa, 0x0009be55, 0x000ffa13 }, | ||
| 1759 | { 52, 0x00002ccc, 0x000049ae, 0x0009ae55, 0x000ffa1b }, | ||
| 1760 | { 56, 0x00002ccc, 0x000049b2, 0x0009ae55, 0x000ffa23 }, | ||
| 1761 | { 60, 0x00002ccc, 0x000049ba, 0x0009ae55, 0x000ffa03 }, | ||
| 1762 | { 64, 0x00002ccc, 0x000049be, 0x0009ae55, 0x000ffa0b }, | ||
| 1763 | |||
| 1764 | /* 802.11 HyperLan 2 */ | ||
| 1765 | { 100, 0x00002ccc, 0x00004a2a, 0x000bae55, 0x000ffa03 }, | ||
| 1766 | { 104, 0x00002ccc, 0x00004a2e, 0x000bae55, 0x000ffa0b }, | ||
| 1767 | { 108, 0x00002ccc, 0x00004a32, 0x000bae55, 0x000ffa13 }, | ||
| 1768 | { 112, 0x00002ccc, 0x00004a36, 0x000bae55, 0x000ffa1b }, | ||
| 1769 | { 116, 0x00002ccc, 0x00004a3a, 0x000bbe55, 0x000ffa23 }, | ||
| 1770 | { 120, 0x00002ccc, 0x00004a82, 0x000bbe55, 0x000ffa03 }, | ||
| 1771 | { 124, 0x00002ccc, 0x00004a86, 0x000bbe55, 0x000ffa0b }, | ||
| 1772 | { 128, 0x00002ccc, 0x00004a8a, 0x000bbe55, 0x000ffa13 }, | ||
| 1773 | { 132, 0x00002ccc, 0x00004a8e, 0x000bbe55, 0x000ffa1b }, | ||
| 1774 | { 136, 0x00002ccc, 0x00004a92, 0x000bbe55, 0x000ffa23 }, | ||
| 1775 | |||
| 1776 | /* 802.11 UNII */ | ||
| 1777 | { 140, 0x00002ccc, 0x00004a9a, 0x000bbe55, 0x000ffa03 }, | ||
| 1778 | { 149, 0x00002ccc, 0x00004aa2, 0x000bbe55, 0x000ffa1f }, | ||
| 1779 | { 153, 0x00002ccc, 0x00004aa6, 0x000bbe55, 0x000ffa27 }, | ||
| 1780 | { 157, 0x00002ccc, 0x00004aae, 0x000bbe55, 0x000ffa07 }, | ||
| 1781 | { 161, 0x00002ccc, 0x00004ab2, 0x000bbe55, 0x000ffa0f }, | ||
| 1782 | { 165, 0x00002ccc, 0x00004ab6, 0x000bbe55, 0x000ffa17 }, | ||
| 1783 | |||
| 1784 | /* MMAC(Japan)J52 ch 34,38,42,46 */ | ||
| 1785 | { 34, 0x00002ccc, 0x0000499a, 0x0009be55, 0x000ffa0b }, | ||
| 1786 | { 38, 0x00002ccc, 0x0000499e, 0x0009be55, 0x000ffa13 }, | ||
| 1787 | { 42, 0x00002ccc, 0x000049a2, 0x0009be55, 0x000ffa1b }, | ||
| 1788 | { 46, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000ffa23 }, | ||
| 1789 | }; | ||
| 1790 | |||
| 1791 | |||
| 1792 | static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | ||
| 1793 | { | ||
| 1794 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
| 1795 | u8 *txpower; | ||
| 1796 | unsigned int i; | ||
| 1797 | |||
| 1798 | /* | ||
| 1799 | * Initialize all hw fields. | ||
| 1800 | */ | ||
| 1801 | rt2x00dev->hw->flags = | ||
| 1802 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | ||
| 1803 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
| 1804 | IEEE80211_HW_MONITOR_DURING_OPER | | ||
| 1805 | IEEE80211_HW_NO_PROBE_FILTERING; | ||
| 1806 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | ||
| 1807 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | ||
| 1808 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | ||
| 1809 | rt2x00dev->hw->queues = 5; | ||
| 1810 | |||
| 1811 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | ||
| 1812 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | ||
| 1813 | rt2x00_eeprom_addr(rt2x00dev, | ||
| 1814 | EEPROM_MAC_ADDR_0)); | ||
| 1815 | |||
| 1816 | /* | ||
| 1817 | * Convert tx_power array in eeprom. | ||
| 1818 | */ | ||
| 1819 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); | ||
| 1820 | for (i = 0; i < 14; i++) | ||
| 1821 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | ||
| 1822 | |||
| 1823 | /* | ||
| 1824 | * Initialize hw_mode information. | ||
| 1825 | */ | ||
| 1826 | spec->num_modes = 2; | ||
| 1827 | spec->num_rates = 12; | ||
| 1828 | spec->tx_power_a = NULL; | ||
| 1829 | spec->tx_power_bg = txpower; | ||
| 1830 | spec->tx_power_default = DEFAULT_TXPOWER; | ||
| 1831 | |||
| 1832 | if (rt2x00_rf(&rt2x00dev->chip, RF2528)) { | ||
| 1833 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); | ||
| 1834 | spec->channels = rf_vals_bg_2528; | ||
| 1835 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) { | ||
| 1836 | spec->num_channels = ARRAY_SIZE(rf_vals_5226); | ||
| 1837 | spec->channels = rf_vals_5226; | ||
| 1838 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) { | ||
| 1839 | spec->num_channels = 14; | ||
| 1840 | spec->channels = rf_vals_5225_2527; | ||
| 1841 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) { | ||
| 1842 | spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527); | ||
| 1843 | spec->channels = rf_vals_5225_2527; | ||
| 1844 | } | ||
| 1845 | |||
| 1846 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | ||
| 1847 | rt2x00_rf(&rt2x00dev->chip, RF5226)) { | ||
| 1848 | spec->num_modes = 3; | ||
| 1849 | |||
| 1850 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | ||
| 1851 | for (i = 0; i < 14; i++) | ||
| 1852 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | ||
| 1853 | |||
| 1854 | spec->tx_power_a = txpower; | ||
| 1855 | } | ||
| 1856 | } | ||
| 1857 | |||
| 1858 | static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | ||
| 1859 | { | ||
| 1860 | int retval; | ||
| 1861 | |||
| 1862 | /* | ||
| 1863 | * Allocate eeprom data. | ||
| 1864 | */ | ||
| 1865 | retval = rt73usb_validate_eeprom(rt2x00dev); | ||
| 1866 | if (retval) | ||
| 1867 | return retval; | ||
| 1868 | |||
| 1869 | retval = rt73usb_init_eeprom(rt2x00dev); | ||
| 1870 | if (retval) | ||
| 1871 | return retval; | ||
| 1872 | |||
| 1873 | /* | ||
| 1874 | * Initialize hw specifications. | ||
| 1875 | */ | ||
| 1876 | rt73usb_probe_hw_mode(rt2x00dev); | ||
| 1877 | |||
| 1878 | /* | ||
| 1879 | * USB devices require scheduled packet filter toggling | ||
| 1880 | * This device requires firmware | ||
| 1881 | */ | ||
| 1882 | __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->flags); | ||
| 1883 | __set_bit(PACKET_FILTER_SCHEDULED, &rt2x00dev->flags); | ||
| 1884 | |||
| 1885 | /* | ||
| 1886 | * Set the rssi offset. | ||
| 1887 | */ | ||
| 1888 | rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET; | ||
| 1889 | |||
| 1890 | return 0; | ||
| 1891 | } | ||
| 1892 | |||
| 1893 | /* | ||
| 1894 | * IEEE80211 stack callback functions. | ||
| 1895 | */ | ||
| 1896 | static int rt73usb_set_retry_limit(struct ieee80211_hw *hw, | ||
| 1897 | u32 short_retry, u32 long_retry) | ||
| 1898 | { | ||
| 1899 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1900 | u32 reg; | ||
| 1901 | |||
| 1902 | rt73usb_register_read(rt2x00dev, TXRX_CSR4, ®); | ||
| 1903 | rt2x00_set_field32(®, TXRX_CSR4_LONG_RETRY_LIMIT, long_retry); | ||
| 1904 | rt2x00_set_field32(®, TXRX_CSR4_SHORT_RETRY_LIMIT, short_retry); | ||
| 1905 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); | ||
| 1906 | |||
| 1907 | return 0; | ||
| 1908 | } | ||
| 1909 | |||
| 1910 | #if 0 | ||
| 1911 | /* | ||
| 1912 | * Mac80211 demands get_tsf must be atomic. | ||
| 1913 | * This is not possible for rt73usb since all register access | ||
| 1914 | * functions require sleeping. Untill mac80211 no longer needs | ||
| 1915 | * get_tsf to be atomic, this function should be disabled. | ||
| 1916 | */ | ||
| 1917 | static u64 rt73usb_get_tsf(struct ieee80211_hw *hw) | ||
| 1918 | { | ||
| 1919 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1920 | u64 tsf; | ||
| 1921 | u32 reg; | ||
| 1922 | |||
| 1923 | rt73usb_register_read(rt2x00dev, TXRX_CSR13, ®); | ||
| 1924 | tsf = (u64) rt2x00_get_field32(reg, TXRX_CSR13_HIGH_TSFTIMER) << 32; | ||
| 1925 | rt73usb_register_read(rt2x00dev, TXRX_CSR12, ®); | ||
| 1926 | tsf |= rt2x00_get_field32(reg, TXRX_CSR12_LOW_TSFTIMER); | ||
| 1927 | |||
| 1928 | return tsf; | ||
| 1929 | } | ||
| 1930 | #endif | ||
| 1931 | |||
| 1932 | static void rt73usb_reset_tsf(struct ieee80211_hw *hw) | ||
| 1933 | { | ||
| 1934 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1935 | |||
| 1936 | rt73usb_register_write(rt2x00dev, TXRX_CSR12, 0); | ||
| 1937 | rt73usb_register_write(rt2x00dev, TXRX_CSR13, 0); | ||
| 1938 | } | ||
| 1939 | |||
| 1940 | int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
| 1941 | struct ieee80211_tx_control *control) | ||
| 1942 | { | ||
| 1943 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
| 1944 | int timeout; | ||
| 1945 | |||
| 1946 | /* | ||
| 1947 | * Just in case the ieee80211 doesn't set this, | ||
| 1948 | * but we need this queue set for the descriptor | ||
| 1949 | * initialization. | ||
| 1950 | */ | ||
| 1951 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
| 1952 | |||
| 1953 | /* | ||
| 1954 | * First we create the beacon. | ||
| 1955 | */ | ||
| 1956 | skb_push(skb, TXD_DESC_SIZE); | ||
| 1957 | rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data, | ||
| 1958 | (struct ieee80211_hdr *)(skb->data + | ||
| 1959 | TXD_DESC_SIZE), | ||
| 1960 | skb->len - TXD_DESC_SIZE, control); | ||
| 1961 | |||
| 1962 | /* | ||
| 1963 | * Write entire beacon with descriptor to register, | ||
| 1964 | * and kick the beacon generator. | ||
| 1965 | */ | ||
| 1966 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); | ||
| 1967 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | ||
| 1968 | USB_VENDOR_REQUEST_OUT, | ||
| 1969 | HW_BEACON_BASE0, 0x0000, | ||
| 1970 | skb->data, skb->len, timeout); | ||
| 1971 | rt73usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
| 1972 | |||
| 1973 | return 0; | ||
| 1974 | } | ||
| 1975 | |||
| 1976 | static const struct ieee80211_ops rt73usb_mac80211_ops = { | ||
| 1977 | .tx = rt2x00mac_tx, | ||
| 1978 | .add_interface = rt2x00mac_add_interface, | ||
| 1979 | .remove_interface = rt2x00mac_remove_interface, | ||
| 1980 | .config = rt2x00mac_config, | ||
| 1981 | .config_interface = rt2x00mac_config_interface, | ||
| 1982 | .set_multicast_list = rt2x00mac_set_multicast_list, | ||
| 1983 | .get_stats = rt2x00mac_get_stats, | ||
| 1984 | .set_retry_limit = rt73usb_set_retry_limit, | ||
| 1985 | .conf_tx = rt2x00mac_conf_tx, | ||
| 1986 | .get_tx_stats = rt2x00mac_get_tx_stats, | ||
| 1987 | #if 0 | ||
| 1988 | /* | ||
| 1989 | * See comment at the rt73usb_get_tsf function. | ||
| 1990 | */ | ||
| 1991 | .get_tsf = rt73usb_get_tsf, | ||
| 1992 | #endif | ||
| 1993 | .reset_tsf = rt73usb_reset_tsf, | ||
| 1994 | .beacon_update = rt73usb_beacon_update, | ||
| 1995 | }; | ||
| 1996 | |||
| 1997 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | ||
| 1998 | .probe_hw = rt73usb_probe_hw, | ||
| 1999 | .get_firmware_name = rt73usb_get_firmware_name, | ||
| 2000 | .load_firmware = rt73usb_load_firmware, | ||
| 2001 | .initialize = rt2x00usb_initialize, | ||
| 2002 | .uninitialize = rt2x00usb_uninitialize, | ||
| 2003 | .set_device_state = rt73usb_set_device_state, | ||
| 2004 | .link_stats = rt73usb_link_stats, | ||
| 2005 | .reset_tuner = rt73usb_reset_tuner, | ||
| 2006 | .link_tuner = rt73usb_link_tuner, | ||
| 2007 | .write_tx_desc = rt73usb_write_tx_desc, | ||
| 2008 | .write_tx_data = rt2x00usb_write_tx_data, | ||
| 2009 | .kick_tx_queue = rt73usb_kick_tx_queue, | ||
| 2010 | .fill_rxdone = rt73usb_fill_rxdone, | ||
| 2011 | .config_mac_addr = rt73usb_config_mac_addr, | ||
| 2012 | .config_bssid = rt73usb_config_bssid, | ||
| 2013 | .config_packet_filter = rt73usb_config_packet_filter, | ||
| 2014 | .config_type = rt73usb_config_type, | ||
| 2015 | .config = rt73usb_config, | ||
| 2016 | }; | ||
| 2017 | |||
| 2018 | static const struct rt2x00_ops rt73usb_ops = { | ||
| 2019 | .name = DRV_NAME, | ||
| 2020 | .rxd_size = RXD_DESC_SIZE, | ||
| 2021 | .txd_size = TXD_DESC_SIZE, | ||
| 2022 | .eeprom_size = EEPROM_SIZE, | ||
| 2023 | .rf_size = RF_SIZE, | ||
| 2024 | .lib = &rt73usb_rt2x00_ops, | ||
| 2025 | .hw = &rt73usb_mac80211_ops, | ||
| 2026 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
| 2027 | .debugfs = &rt73usb_rt2x00debug, | ||
| 2028 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
| 2029 | }; | ||
| 2030 | |||
| 2031 | /* | ||
| 2032 | * rt73usb module information. | ||
| 2033 | */ | ||
| 2034 | static struct usb_device_id rt73usb_device_table[] = { | ||
| 2035 | /* AboCom */ | ||
| 2036 | { USB_DEVICE(0x07b8, 0xb21d), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2037 | /* Askey */ | ||
| 2038 | { USB_DEVICE(0x1690, 0x0722), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2039 | /* ASUS */ | ||
| 2040 | { USB_DEVICE(0x0b05, 0x1723), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2041 | { USB_DEVICE(0x0b05, 0x1724), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2042 | /* Belkin */ | ||
| 2043 | { USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2044 | { USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2045 | { USB_DEVICE(0x050d, 0x905b), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2046 | /* Billionton */ | ||
| 2047 | { USB_DEVICE(0x1631, 0xc019), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2048 | /* Buffalo */ | ||
| 2049 | { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2050 | /* CNet */ | ||
| 2051 | { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2052 | { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2053 | /* Conceptronic */ | ||
| 2054 | { USB_DEVICE(0x14b2, 0x3c22), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2055 | /* D-Link */ | ||
| 2056 | { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2057 | { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2058 | /* Gemtek */ | ||
| 2059 | { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2060 | /* Gigabyte */ | ||
| 2061 | { USB_DEVICE(0x1044, 0x8008), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2062 | { USB_DEVICE(0x1044, 0x800a), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2063 | /* Huawei-3Com */ | ||
| 2064 | { USB_DEVICE(0x1472, 0x0009), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2065 | /* Hercules */ | ||
| 2066 | { USB_DEVICE(0x06f8, 0xe010), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2067 | { USB_DEVICE(0x06f8, 0xe020), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2068 | /* Linksys */ | ||
| 2069 | { USB_DEVICE(0x13b1, 0x0020), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2070 | { USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2071 | /* MSI */ | ||
| 2072 | { USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2073 | { USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2074 | { USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2075 | { USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2076 | /* Ralink */ | ||
| 2077 | { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2078 | { USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2079 | /* Qcom */ | ||
| 2080 | { USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2081 | { USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2082 | { USB_DEVICE(0x18e8, 0x6238), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2083 | /* Senao */ | ||
| 2084 | { USB_DEVICE(0x1740, 0x7100), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2085 | /* Sitecom */ | ||
| 2086 | { USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2087 | { USB_DEVICE(0x0df6, 0x90ac), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2088 | /* Surecom */ | ||
| 2089 | { USB_DEVICE(0x0769, 0x31f3), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2090 | /* Planex */ | ||
| 2091 | { USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2092 | { USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2093 | { 0, } | ||
| 2094 | }; | ||
| 2095 | |||
| 2096 | MODULE_AUTHOR(DRV_PROJECT); | ||
| 2097 | MODULE_VERSION(DRV_VERSION); | ||
| 2098 | MODULE_DESCRIPTION("Ralink RT73 USB Wireless LAN driver."); | ||
| 2099 | MODULE_SUPPORTED_DEVICE("Ralink RT2571W & RT2671 USB chipset based cards"); | ||
| 2100 | MODULE_DEVICE_TABLE(usb, rt73usb_device_table); | ||
| 2101 | MODULE_FIRMWARE(FIRMWARE_RT2571); | ||
| 2102 | MODULE_LICENSE("GPL"); | ||
| 2103 | |||
| 2104 | static struct usb_driver rt73usb_driver = { | ||
| 2105 | .name = DRV_NAME, | ||
| 2106 | .id_table = rt73usb_device_table, | ||
| 2107 | .probe = rt2x00usb_probe, | ||
| 2108 | .disconnect = rt2x00usb_disconnect, | ||
| 2109 | .suspend = rt2x00usb_suspend, | ||
| 2110 | .resume = rt2x00usb_resume, | ||
| 2111 | }; | ||
| 2112 | |||
| 2113 | static int __init rt73usb_init(void) | ||
| 2114 | { | ||
| 2115 | return usb_register(&rt73usb_driver); | ||
| 2116 | } | ||
| 2117 | |||
| 2118 | static void __exit rt73usb_exit(void) | ||
| 2119 | { | ||
| 2120 | usb_deregister(&rt73usb_driver); | ||
| 2121 | } | ||
| 2122 | |||
| 2123 | module_init(rt73usb_init); | ||
| 2124 | module_exit(rt73usb_exit); | ||
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h new file mode 100644 index 00000000000..5d63a1a714f --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt73usb.h | |||
| @@ -0,0 +1,1024 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
| 3 | <http://rt2x00.serialmonkey.com> | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 2 of the License, or | ||
| 8 | (at your option) any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, write to the | ||
| 17 | Free Software Foundation, Inc., | ||
| 18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* | ||
| 22 | Module: rt73usb | ||
| 23 | Abstract: Data structures and registers for the rt73usb module. | ||
| 24 | Supported chipsets: rt2571W & rt2671. | ||
| 25 | */ | ||
| 26 | |||
| 27 | #ifndef RT73USB_H | ||
| 28 | #define RT73USB_H | ||
| 29 | |||
| 30 | /* | ||
| 31 | * RF chip defines. | ||
| 32 | */ | ||
| 33 | #define RF5226 0x0001 | ||
| 34 | #define RF2528 0x0002 | ||
| 35 | #define RF5225 0x0003 | ||
| 36 | #define RF2527 0x0004 | ||
| 37 | |||
| 38 | /* | ||
| 39 | * Signal information. | ||
| 40 | * Defaul offset is required for RSSI <-> dBm conversion. | ||
| 41 | */ | ||
| 42 | #define MAX_SIGNAL 100 | ||
| 43 | #define MAX_RX_SSI -1 | ||
| 44 | #define DEFAULT_RSSI_OFFSET 120 | ||
| 45 | |||
| 46 | /* | ||
| 47 | * Register layout information. | ||
| 48 | */ | ||
| 49 | #define CSR_REG_BASE 0x3000 | ||
| 50 | #define CSR_REG_SIZE 0x04b0 | ||
| 51 | #define EEPROM_BASE 0x0000 | ||
| 52 | #define EEPROM_SIZE 0x0100 | ||
| 53 | #define BBP_SIZE 0x0080 | ||
| 54 | #define RF_SIZE 0x0014 | ||
| 55 | |||
| 56 | /* | ||
| 57 | * USB registers. | ||
| 58 | */ | ||
| 59 | |||
| 60 | /* | ||
| 61 | * MCU_LEDCS: LED control for MCU Mailbox. | ||
| 62 | */ | ||
| 63 | #define MCU_LEDCS_LED_MODE FIELD16(0x001f) | ||
| 64 | #define MCU_LEDCS_RADIO_STATUS FIELD16(0x0020) | ||
| 65 | #define MCU_LEDCS_LINK_BG_STATUS FIELD16(0x0040) | ||
| 66 | #define MCU_LEDCS_LINK_A_STATUS FIELD16(0x0080) | ||
| 67 | #define MCU_LEDCS_POLARITY_GPIO_0 FIELD16(0x0100) | ||
| 68 | #define MCU_LEDCS_POLARITY_GPIO_1 FIELD16(0x0200) | ||
| 69 | #define MCU_LEDCS_POLARITY_GPIO_2 FIELD16(0x0400) | ||
| 70 | #define MCU_LEDCS_POLARITY_GPIO_3 FIELD16(0x0800) | ||
| 71 | #define MCU_LEDCS_POLARITY_GPIO_4 FIELD16(0x1000) | ||
| 72 | #define MCU_LEDCS_POLARITY_ACT FIELD16(0x2000) | ||
| 73 | #define MCU_LEDCS_POLARITY_READY_BG FIELD16(0x4000) | ||
| 74 | #define MCU_LEDCS_POLARITY_READY_A FIELD16(0x8000) | ||
| 75 | |||
| 76 | /* | ||
| 77 | * 8051 firmware image. | ||
| 78 | */ | ||
| 79 | #define FIRMWARE_RT2571 "rt73.bin" | ||
| 80 | #define FIRMWARE_IMAGE_BASE 0x0800 | ||
| 81 | |||
| 82 | /* | ||
| 83 | * Security key table memory. | ||
| 84 | * 16 entries 32-byte for shared key table | ||
| 85 | * 64 entries 32-byte for pairwise key table | ||
| 86 | * 64 entries 8-byte for pairwise ta key table | ||
| 87 | */ | ||
| 88 | #define SHARED_KEY_TABLE_BASE 0x1000 | ||
| 89 | #define PAIRWISE_KEY_TABLE_BASE 0x1200 | ||
| 90 | #define PAIRWISE_TA_TABLE_BASE 0x1a00 | ||
| 91 | |||
| 92 | struct hw_key_entry { | ||
| 93 | u8 key[16]; | ||
| 94 | u8 tx_mic[8]; | ||
| 95 | u8 rx_mic[8]; | ||
| 96 | } __attribute__ ((packed)); | ||
| 97 | |||
| 98 | struct hw_pairwise_ta_entry { | ||
| 99 | u8 address[6]; | ||
| 100 | u8 reserved[2]; | ||
| 101 | } __attribute__ ((packed)); | ||
| 102 | |||
| 103 | /* | ||
| 104 | * Since NULL frame won't be that long (256 byte), | ||
| 105 | * We steal 16 tail bytes to save debugging settings. | ||
| 106 | */ | ||
| 107 | #define HW_DEBUG_SETTING_BASE 0x2bf0 | ||
| 108 | |||
| 109 | /* | ||
| 110 | * On-chip BEACON frame space. | ||
| 111 | */ | ||
| 112 | #define HW_BEACON_BASE0 0x2400 | ||
| 113 | #define HW_BEACON_BASE1 0x2500 | ||
| 114 | #define HW_BEACON_BASE2 0x2600 | ||
| 115 | #define HW_BEACON_BASE3 0x2700 | ||
| 116 | |||
| 117 | /* | ||
| 118 | * MAC Control/Status Registers(CSR). | ||
| 119 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 120 | */ | ||
| 121 | |||
| 122 | /* | ||
| 123 | * MAC_CSR0: ASIC revision number. | ||
| 124 | */ | ||
| 125 | #define MAC_CSR0 0x3000 | ||
| 126 | |||
| 127 | /* | ||
| 128 | * MAC_CSR1: System control register. | ||
| 129 | * SOFT_RESET: Software reset bit, 1: reset, 0: normal. | ||
| 130 | * BBP_RESET: Hardware reset BBP. | ||
| 131 | * HOST_READY: Host is ready after initialization, 1: ready. | ||
| 132 | */ | ||
| 133 | #define MAC_CSR1 0x3004 | ||
| 134 | #define MAC_CSR1_SOFT_RESET FIELD32(0x00000001) | ||
| 135 | #define MAC_CSR1_BBP_RESET FIELD32(0x00000002) | ||
| 136 | #define MAC_CSR1_HOST_READY FIELD32(0x00000004) | ||
| 137 | |||
| 138 | /* | ||
| 139 | * MAC_CSR2: STA MAC register 0. | ||
| 140 | */ | ||
| 141 | #define MAC_CSR2 0x3008 | ||
| 142 | #define MAC_CSR2_BYTE0 FIELD32(0x000000ff) | ||
| 143 | #define MAC_CSR2_BYTE1 FIELD32(0x0000ff00) | ||
| 144 | #define MAC_CSR2_BYTE2 FIELD32(0x00ff0000) | ||
| 145 | #define MAC_CSR2_BYTE3 FIELD32(0xff000000) | ||
| 146 | |||
| 147 | /* | ||
| 148 | * MAC_CSR3: STA MAC register 1. | ||
| 149 | */ | ||
| 150 | #define MAC_CSR3 0x300c | ||
| 151 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) | ||
| 152 | #define MAC_CSR3_BYTE5 FIELD32(0x0000ff00) | ||
| 153 | #define MAC_CSR3_UNICAST_TO_ME_MASK FIELD32(0x00ff0000) | ||
| 154 | |||
| 155 | /* | ||
| 156 | * MAC_CSR4: BSSID register 0. | ||
| 157 | */ | ||
| 158 | #define MAC_CSR4 0x3010 | ||
| 159 | #define MAC_CSR4_BYTE0 FIELD32(0x000000ff) | ||
| 160 | #define MAC_CSR4_BYTE1 FIELD32(0x0000ff00) | ||
| 161 | #define MAC_CSR4_BYTE2 FIELD32(0x00ff0000) | ||
| 162 | #define MAC_CSR4_BYTE3 FIELD32(0xff000000) | ||
| 163 | |||
| 164 | /* | ||
| 165 | * MAC_CSR5: BSSID register 1. | ||
| 166 | * BSS_ID_MASK: 3: one BSSID, 0: 4 BSSID, 2 or 1: 2 BSSID. | ||
| 167 | */ | ||
| 168 | #define MAC_CSR5 0x3014 | ||
| 169 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) | ||
| 170 | #define MAC_CSR5_BYTE5 FIELD32(0x0000ff00) | ||
| 171 | #define MAC_CSR5_BSS_ID_MASK FIELD32(0x00ff0000) | ||
| 172 | |||
| 173 | /* | ||
| 174 | * MAC_CSR6: Maximum frame length register. | ||
| 175 | */ | ||
| 176 | #define MAC_CSR6 0x3018 | ||
| 177 | #define MAC_CSR6_MAX_FRAME_UNIT FIELD32(0x00000fff) | ||
| 178 | |||
| 179 | /* | ||
| 180 | * MAC_CSR7: Reserved | ||
| 181 | */ | ||
| 182 | #define MAC_CSR7 0x301c | ||
| 183 | |||
| 184 | /* | ||
| 185 | * MAC_CSR8: SIFS/EIFS register. | ||
| 186 | * All units are in US. | ||
| 187 | */ | ||
| 188 | #define MAC_CSR8 0x3020 | ||
| 189 | #define MAC_CSR8_SIFS FIELD32(0x000000ff) | ||
| 190 | #define MAC_CSR8_SIFS_AFTER_RX_OFDM FIELD32(0x0000ff00) | ||
| 191 | #define MAC_CSR8_EIFS FIELD32(0xffff0000) | ||
| 192 | |||
| 193 | /* | ||
| 194 | * MAC_CSR9: Back-Off control register. | ||
| 195 | * SLOT_TIME: Slot time, default is 20us for 802.11BG. | ||
| 196 | * CWMIN: Bit for Cwmin. default Cwmin is 31 (2^5 - 1). | ||
| 197 | * CWMAX: Bit for Cwmax, default Cwmax is 1023 (2^10 - 1). | ||
| 198 | * CW_SELECT: 1: CWmin/Cwmax select from register, 0:select from TxD. | ||
| 199 | */ | ||
| 200 | #define MAC_CSR9 0x3024 | ||
| 201 | #define MAC_CSR9_SLOT_TIME FIELD32(0x000000ff) | ||
| 202 | #define MAC_CSR9_CWMIN FIELD32(0x00000f00) | ||
| 203 | #define MAC_CSR9_CWMAX FIELD32(0x0000f000) | ||
| 204 | #define MAC_CSR9_CW_SELECT FIELD32(0x00010000) | ||
| 205 | |||
| 206 | /* | ||
| 207 | * MAC_CSR10: Power state configuration. | ||
| 208 | */ | ||
| 209 | #define MAC_CSR10 0x3028 | ||
| 210 | |||
| 211 | /* | ||
| 212 | * MAC_CSR11: Power saving transition time register. | ||
| 213 | * DELAY_AFTER_TBCN: Delay after Tbcn expired in units of TU. | ||
| 214 | * TBCN_BEFORE_WAKEUP: Number of beacon before wakeup. | ||
| 215 | * WAKEUP_LATENCY: In unit of TU. | ||
| 216 | */ | ||
| 217 | #define MAC_CSR11 0x302c | ||
| 218 | #define MAC_CSR11_DELAY_AFTER_TBCN FIELD32(0x000000ff) | ||
| 219 | #define MAC_CSR11_TBCN_BEFORE_WAKEUP FIELD32(0x00007f00) | ||
| 220 | #define MAC_CSR11_AUTOWAKE FIELD32(0x00008000) | ||
| 221 | #define MAC_CSR11_WAKEUP_LATENCY FIELD32(0x000f0000) | ||
| 222 | |||
| 223 | /* | ||
| 224 | * MAC_CSR12: Manual power control / status register (merge CSR20 & PWRCSR1). | ||
| 225 | * CURRENT_STATE: 0:sleep, 1:awake. | ||
| 226 | * FORCE_WAKEUP: This has higher priority than PUT_TO_SLEEP. | ||
| 227 | * BBP_CURRENT_STATE: 0: BBP sleep, 1: BBP awake. | ||
| 228 | */ | ||
| 229 | #define MAC_CSR12 0x3030 | ||
| 230 | #define MAC_CSR12_CURRENT_STATE FIELD32(0x00000001) | ||
| 231 | #define MAC_CSR12_PUT_TO_SLEEP FIELD32(0x00000002) | ||
| 232 | #define MAC_CSR12_FORCE_WAKEUP FIELD32(0x00000004) | ||
| 233 | #define MAC_CSR12_BBP_CURRENT_STATE FIELD32(0x00000008) | ||
| 234 | |||
| 235 | /* | ||
| 236 | * MAC_CSR13: GPIO. | ||
| 237 | */ | ||
| 238 | #define MAC_CSR13 0x3034 | ||
| 239 | |||
| 240 | /* | ||
| 241 | * MAC_CSR14: LED control register. | ||
| 242 | * ON_PERIOD: On period, default 70ms. | ||
| 243 | * OFF_PERIOD: Off period, default 30ms. | ||
| 244 | * HW_LED: HW TX activity, 1: normal OFF, 0: normal ON. | ||
| 245 | * SW_LED: s/w LED, 1: ON, 0: OFF. | ||
| 246 | * HW_LED_POLARITY: 0: active low, 1: active high. | ||
| 247 | */ | ||
| 248 | #define MAC_CSR14 0x3038 | ||
| 249 | #define MAC_CSR14_ON_PERIOD FIELD32(0x000000ff) | ||
| 250 | #define MAC_CSR14_OFF_PERIOD FIELD32(0x0000ff00) | ||
| 251 | #define MAC_CSR14_HW_LED FIELD32(0x00010000) | ||
| 252 | #define MAC_CSR14_SW_LED FIELD32(0x00020000) | ||
| 253 | #define MAC_CSR14_HW_LED_POLARITY FIELD32(0x00040000) | ||
| 254 | #define MAC_CSR14_SW_LED2 FIELD32(0x00080000) | ||
| 255 | |||
| 256 | /* | ||
| 257 | * MAC_CSR15: NAV control. | ||
| 258 | */ | ||
| 259 | #define MAC_CSR15 0x303c | ||
| 260 | |||
| 261 | /* | ||
| 262 | * TXRX control registers. | ||
| 263 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 264 | */ | ||
| 265 | |||
| 266 | /* | ||
| 267 | * TXRX_CSR0: TX/RX configuration register. | ||
| 268 | * TSF_OFFSET: Default is 24. | ||
| 269 | * AUTO_TX_SEQ: 1: ASIC auto replace sequence nr in outgoing frame. | ||
| 270 | * DISABLE_RX: Disable Rx engine. | ||
| 271 | * DROP_CRC: Drop CRC error. | ||
| 272 | * DROP_PHYSICAL: Drop physical error. | ||
| 273 | * DROP_CONTROL: Drop control frame. | ||
| 274 | * DROP_NOT_TO_ME: Drop not to me unicast frame. | ||
| 275 | * DROP_TO_DS: Drop fram ToDs bit is true. | ||
| 276 | * DROP_VERSION_ERROR: Drop version error frame. | ||
| 277 | * DROP_MULTICAST: Drop multicast frames. | ||
| 278 | * DROP_BORADCAST: Drop broadcast frames. | ||
| 279 | * ROP_ACK_CTS: Drop received ACK and CTS. | ||
| 280 | */ | ||
| 281 | #define TXRX_CSR0 0x3040 | ||
| 282 | #define TXRX_CSR0_RX_ACK_TIMEOUT FIELD32(0x000001ff) | ||
| 283 | #define TXRX_CSR0_TSF_OFFSET FIELD32(0x00007e00) | ||
| 284 | #define TXRX_CSR0_AUTO_TX_SEQ FIELD32(0x00008000) | ||
| 285 | #define TXRX_CSR0_DISABLE_RX FIELD32(0x00010000) | ||
| 286 | #define TXRX_CSR0_DROP_CRC FIELD32(0x00020000) | ||
| 287 | #define TXRX_CSR0_DROP_PHYSICAL FIELD32(0x00040000) | ||
| 288 | #define TXRX_CSR0_DROP_CONTROL FIELD32(0x00080000) | ||
| 289 | #define TXRX_CSR0_DROP_NOT_TO_ME FIELD32(0x00100000) | ||
| 290 | #define TXRX_CSR0_DROP_TO_DS FIELD32(0x00200000) | ||
| 291 | #define TXRX_CSR0_DROP_VERSION_ERROR FIELD32(0x00400000) | ||
| 292 | #define TXRX_CSR0_DROP_MULTICAST FIELD32(0x00800000) | ||
| 293 | #define TXRX_CSR0_DROP_BORADCAST FIELD32(0x01000000) | ||
| 294 | #define TXRX_CSR0_DROP_ACK_CTS FIELD32(0x02000000) | ||
| 295 | #define TXRX_CSR0_TX_WITHOUT_WAITING FIELD32(0x04000000) | ||
| 296 | |||
| 297 | /* | ||
| 298 | * TXRX_CSR1 | ||
| 299 | */ | ||
| 300 | #define TXRX_CSR1 0x3044 | ||
| 301 | #define TXRX_CSR1_BBP_ID0 FIELD32(0x0000007f) | ||
| 302 | #define TXRX_CSR1_BBP_ID0_VALID FIELD32(0x00000080) | ||
| 303 | #define TXRX_CSR1_BBP_ID1 FIELD32(0x00007f00) | ||
| 304 | #define TXRX_CSR1_BBP_ID1_VALID FIELD32(0x00008000) | ||
| 305 | #define TXRX_CSR1_BBP_ID2 FIELD32(0x007f0000) | ||
| 306 | #define TXRX_CSR1_BBP_ID2_VALID FIELD32(0x00800000) | ||
| 307 | #define TXRX_CSR1_BBP_ID3 FIELD32(0x7f000000) | ||
| 308 | #define TXRX_CSR1_BBP_ID3_VALID FIELD32(0x80000000) | ||
| 309 | |||
| 310 | /* | ||
| 311 | * TXRX_CSR2 | ||
| 312 | */ | ||
| 313 | #define TXRX_CSR2 0x3048 | ||
| 314 | #define TXRX_CSR2_BBP_ID0 FIELD32(0x0000007f) | ||
| 315 | #define TXRX_CSR2_BBP_ID0_VALID FIELD32(0x00000080) | ||
| 316 | #define TXRX_CSR2_BBP_ID1 FIELD32(0x00007f00) | ||
| 317 | #define TXRX_CSR2_BBP_ID1_VALID FIELD32(0x00008000) | ||
| 318 | #define TXRX_CSR2_BBP_ID2 FIELD32(0x007f0000) | ||
| 319 | #define TXRX_CSR2_BBP_ID2_VALID FIELD32(0x00800000) | ||
| 320 | #define TXRX_CSR2_BBP_ID3 FIELD32(0x7f000000) | ||
| 321 | #define TXRX_CSR2_BBP_ID3_VALID FIELD32(0x80000000) | ||
| 322 | |||
| 323 | /* | ||
| 324 | * TXRX_CSR3 | ||
| 325 | */ | ||
| 326 | #define TXRX_CSR3 0x304c | ||
| 327 | #define TXRX_CSR3_BBP_ID0 FIELD32(0x0000007f) | ||
| 328 | #define TXRX_CSR3_BBP_ID0_VALID FIELD32(0x00000080) | ||
| 329 | #define TXRX_CSR3_BBP_ID1 FIELD32(0x00007f00) | ||
| 330 | #define TXRX_CSR3_BBP_ID1_VALID FIELD32(0x00008000) | ||
| 331 | #define TXRX_CSR3_BBP_ID2 FIELD32(0x007f0000) | ||
| 332 | #define TXRX_CSR3_BBP_ID2_VALID FIELD32(0x00800000) | ||
| 333 | #define TXRX_CSR3_BBP_ID3 FIELD32(0x7f000000) | ||
| 334 | #define TXRX_CSR3_BBP_ID3_VALID FIELD32(0x80000000) | ||
| 335 | |||
| 336 | /* | ||
| 337 | * TXRX_CSR4: Auto-Responder/Tx-retry register. | ||
| 338 | * AUTORESPOND_PREAMBLE: 0:long, 1:short preamble. | ||
| 339 | * OFDM_TX_RATE_DOWN: 1:enable. | ||
| 340 | * OFDM_TX_RATE_STEP: 0:1-step, 1: 2-step, 2:3-step, 3:4-step. | ||
| 341 | * OFDM_TX_FALLBACK_CCK: 0: Fallback to OFDM 6M only, 1: Fallback to CCK 1M,2M. | ||
| 342 | */ | ||
| 343 | #define TXRX_CSR4 0x3050 | ||
| 344 | #define TXRX_CSR4_TX_ACK_TIMEOUT FIELD32(0x000000ff) | ||
| 345 | #define TXRX_CSR4_CNTL_ACK_POLICY FIELD32(0x00000700) | ||
| 346 | #define TXRX_CSR4_ACK_CTS_PSM FIELD32(0x00010000) | ||
| 347 | #define TXRX_CSR4_AUTORESPOND_ENABLE FIELD32(0x00020000) | ||
| 348 | #define TXRX_CSR4_AUTORESPOND_PREAMBLE FIELD32(0x00040000) | ||
| 349 | #define TXRX_CSR4_OFDM_TX_RATE_DOWN FIELD32(0x00080000) | ||
| 350 | #define TXRX_CSR4_OFDM_TX_RATE_STEP FIELD32(0x00300000) | ||
| 351 | #define TXRX_CSR4_OFDM_TX_FALLBACK_CCK FIELD32(0x00400000) | ||
| 352 | #define TXRX_CSR4_LONG_RETRY_LIMIT FIELD32(0x0f000000) | ||
| 353 | #define TXRX_CSR4_SHORT_RETRY_LIMIT FIELD32(0xf0000000) | ||
| 354 | |||
| 355 | /* | ||
| 356 | * TXRX_CSR5 | ||
| 357 | */ | ||
| 358 | #define TXRX_CSR5 0x3054 | ||
| 359 | |||
| 360 | /* | ||
| 361 | * TXRX_CSR6: ACK/CTS payload consumed time | ||
| 362 | */ | ||
| 363 | #define TXRX_CSR6 0x3058 | ||
| 364 | |||
| 365 | /* | ||
| 366 | * TXRX_CSR7: OFDM ACK/CTS payload consumed time for 6/9/12/18 mbps. | ||
| 367 | */ | ||
| 368 | #define TXRX_CSR7 0x305c | ||
| 369 | #define TXRX_CSR7_ACK_CTS_6MBS FIELD32(0x000000ff) | ||
| 370 | #define TXRX_CSR7_ACK_CTS_9MBS FIELD32(0x0000ff00) | ||
| 371 | #define TXRX_CSR7_ACK_CTS_12MBS FIELD32(0x00ff0000) | ||
| 372 | #define TXRX_CSR7_ACK_CTS_18MBS FIELD32(0xff000000) | ||
| 373 | |||
| 374 | /* | ||
| 375 | * TXRX_CSR8: OFDM ACK/CTS payload consumed time for 24/36/48/54 mbps. | ||
| 376 | */ | ||
| 377 | #define TXRX_CSR8 0x3060 | ||
| 378 | #define TXRX_CSR8_ACK_CTS_24MBS FIELD32(0x000000ff) | ||
| 379 | #define TXRX_CSR8_ACK_CTS_36MBS FIELD32(0x0000ff00) | ||
| 380 | #define TXRX_CSR8_ACK_CTS_48MBS FIELD32(0x00ff0000) | ||
| 381 | #define TXRX_CSR8_ACK_CTS_54MBS FIELD32(0xff000000) | ||
| 382 | |||
| 383 | /* | ||
| 384 | * TXRX_CSR9: Synchronization control register. | ||
| 385 | * BEACON_INTERVAL: In unit of 1/16 TU. | ||
| 386 | * TSF_TICKING: Enable TSF auto counting. | ||
| 387 | * TSF_SYNC: Tsf sync, 0: disable, 1: infra, 2: ad-hoc/master mode. | ||
| 388 | * BEACON_GEN: Enable beacon generator. | ||
| 389 | */ | ||
| 390 | #define TXRX_CSR9 0x3064 | ||
| 391 | #define TXRX_CSR9_BEACON_INTERVAL FIELD32(0x0000ffff) | ||
| 392 | #define TXRX_CSR9_TSF_TICKING FIELD32(0x00010000) | ||
| 393 | #define TXRX_CSR9_TSF_SYNC FIELD32(0x00060000) | ||
| 394 | #define TXRX_CSR9_TBTT_ENABLE FIELD32(0x00080000) | ||
| 395 | #define TXRX_CSR9_BEACON_GEN FIELD32(0x00100000) | ||
| 396 | #define TXRX_CSR9_TIMESTAMP_COMPENSATE FIELD32(0xff000000) | ||
| 397 | |||
| 398 | /* | ||
| 399 | * TXRX_CSR10: BEACON alignment. | ||
| 400 | */ | ||
| 401 | #define TXRX_CSR10 0x3068 | ||
| 402 | |||
| 403 | /* | ||
| 404 | * TXRX_CSR11: AES mask. | ||
| 405 | */ | ||
| 406 | #define TXRX_CSR11 0x306c | ||
| 407 | |||
| 408 | /* | ||
| 409 | * TXRX_CSR12: TSF low 32. | ||
| 410 | */ | ||
| 411 | #define TXRX_CSR12 0x3070 | ||
| 412 | #define TXRX_CSR12_LOW_TSFTIMER FIELD32(0xffffffff) | ||
| 413 | |||
| 414 | /* | ||
| 415 | * TXRX_CSR13: TSF high 32. | ||
| 416 | */ | ||
| 417 | #define TXRX_CSR13 0x3074 | ||
| 418 | #define TXRX_CSR13_HIGH_TSFTIMER FIELD32(0xffffffff) | ||
| 419 | |||
| 420 | /* | ||
| 421 | * TXRX_CSR14: TBTT timer. | ||
| 422 | */ | ||
| 423 | #define TXRX_CSR14 0x3078 | ||
| 424 | |||
| 425 | /* | ||
| 426 | * TXRX_CSR15: TKIP MIC priority byte "AND" mask. | ||
| 427 | */ | ||
| 428 | #define TXRX_CSR15 0x307c | ||
| 429 | |||
| 430 | /* | ||
| 431 | * PHY control registers. | ||
| 432 | * Some values are set in TU, whereas 1 TU == 1024 us. | ||
| 433 | */ | ||
| 434 | |||
| 435 | /* | ||
| 436 | * PHY_CSR0: RF/PS control. | ||
| 437 | */ | ||
| 438 | #define PHY_CSR0 0x3080 | ||
| 439 | #define PHY_CSR0_PA_PE_BG FIELD32(0x00010000) | ||
| 440 | #define PHY_CSR0_PA_PE_A FIELD32(0x00020000) | ||
| 441 | |||
| 442 | /* | ||
| 443 | * PHY_CSR1 | ||
| 444 | */ | ||
| 445 | #define PHY_CSR1 0x3084 | ||
| 446 | #define PHY_CSR1_RF_RPI FIELD32(0x00010000) | ||
| 447 | |||
| 448 | /* | ||
| 449 | * PHY_CSR2: Pre-TX BBP control. | ||
| 450 | */ | ||
| 451 | #define PHY_CSR2 0x3088 | ||
| 452 | |||
| 453 | /* | ||
| 454 | * PHY_CSR3: BBP serial control register. | ||
| 455 | * VALUE: Register value to program into BBP. | ||
| 456 | * REG_NUM: Selected BBP register. | ||
| 457 | * READ_CONTROL: 0: Write BBP, 1: Read BBP. | ||
| 458 | * BUSY: 1: ASIC is busy execute BBP programming. | ||
| 459 | */ | ||
| 460 | #define PHY_CSR3 0x308c | ||
| 461 | #define PHY_CSR3_VALUE FIELD32(0x000000ff) | ||
| 462 | #define PHY_CSR3_REGNUM FIELD32(0x00007f00) | ||
| 463 | #define PHY_CSR3_READ_CONTROL FIELD32(0x00008000) | ||
| 464 | #define PHY_CSR3_BUSY FIELD32(0x00010000) | ||
| 465 | |||
| 466 | /* | ||
| 467 | * PHY_CSR4: RF serial control register | ||
| 468 | * VALUE: Register value (include register id) serial out to RF/IF chip. | ||
| 469 | * NUMBER_OF_BITS: Number of bits used in RFRegValue (I:20, RFMD:22). | ||
| 470 | * IF_SELECT: 1: select IF to program, 0: select RF to program. | ||
| 471 | * PLL_LD: RF PLL_LD status. | ||
| 472 | * BUSY: 1: ASIC is busy execute RF programming. | ||
| 473 | */ | ||
| 474 | #define PHY_CSR4 0x3090 | ||
| 475 | #define PHY_CSR4_VALUE FIELD32(0x00ffffff) | ||
| 476 | #define PHY_CSR4_NUMBER_OF_BITS FIELD32(0x1f000000) | ||
| 477 | #define PHY_CSR4_IF_SELECT FIELD32(0x20000000) | ||
| 478 | #define PHY_CSR4_PLL_LD FIELD32(0x40000000) | ||
| 479 | #define PHY_CSR4_BUSY FIELD32(0x80000000) | ||
| 480 | |||
| 481 | /* | ||
| 482 | * PHY_CSR5: RX to TX signal switch timing control. | ||
| 483 | */ | ||
| 484 | #define PHY_CSR5 0x3094 | ||
| 485 | #define PHY_CSR5_IQ_FLIP FIELD32(0x00000004) | ||
| 486 | |||
| 487 | /* | ||
| 488 | * PHY_CSR6: TX to RX signal timing control. | ||
| 489 | */ | ||
| 490 | #define PHY_CSR6 0x3098 | ||
| 491 | #define PHY_CSR6_IQ_FLIP FIELD32(0x00000004) | ||
| 492 | |||
| 493 | /* | ||
| 494 | * PHY_CSR7: TX DAC switching timing control. | ||
| 495 | */ | ||
| 496 | #define PHY_CSR7 0x309c | ||
| 497 | |||
| 498 | /* | ||
| 499 | * Security control register. | ||
| 500 | */ | ||
| 501 | |||
| 502 | /* | ||
| 503 | * SEC_CSR0: Shared key table control. | ||
| 504 | */ | ||
| 505 | #define SEC_CSR0 0x30a0 | ||
| 506 | #define SEC_CSR0_BSS0_KEY0_VALID FIELD32(0x00000001) | ||
| 507 | #define SEC_CSR0_BSS0_KEY1_VALID FIELD32(0x00000002) | ||
| 508 | #define SEC_CSR0_BSS0_KEY2_VALID FIELD32(0x00000004) | ||
| 509 | #define SEC_CSR0_BSS0_KEY3_VALID FIELD32(0x00000008) | ||
| 510 | #define SEC_CSR0_BSS1_KEY0_VALID FIELD32(0x00000010) | ||
| 511 | #define SEC_CSR0_BSS1_KEY1_VALID FIELD32(0x00000020) | ||
| 512 | #define SEC_CSR0_BSS1_KEY2_VALID FIELD32(0x00000040) | ||
| 513 | #define SEC_CSR0_BSS1_KEY3_VALID FIELD32(0x00000080) | ||
| 514 | #define SEC_CSR0_BSS2_KEY0_VALID FIELD32(0x00000100) | ||
| 515 | #define SEC_CSR0_BSS2_KEY1_VALID FIELD32(0x00000200) | ||
| 516 | #define SEC_CSR0_BSS2_KEY2_VALID FIELD32(0x00000400) | ||
| 517 | #define SEC_CSR0_BSS2_KEY3_VALID FIELD32(0x00000800) | ||
| 518 | #define SEC_CSR0_BSS3_KEY0_VALID FIELD32(0x00001000) | ||
| 519 | #define SEC_CSR0_BSS3_KEY1_VALID FIELD32(0x00002000) | ||
| 520 | #define SEC_CSR0_BSS3_KEY2_VALID FIELD32(0x00004000) | ||
| 521 | #define SEC_CSR0_BSS3_KEY3_VALID FIELD32(0x00008000) | ||
| 522 | |||
| 523 | /* | ||
| 524 | * SEC_CSR1: Shared key table security mode register. | ||
| 525 | */ | ||
| 526 | #define SEC_CSR1 0x30a4 | ||
| 527 | #define SEC_CSR1_BSS0_KEY0_CIPHER_ALG FIELD32(0x00000007) | ||
| 528 | #define SEC_CSR1_BSS0_KEY1_CIPHER_ALG FIELD32(0x00000070) | ||
| 529 | #define SEC_CSR1_BSS0_KEY2_CIPHER_ALG FIELD32(0x00000700) | ||
| 530 | #define SEC_CSR1_BSS0_KEY3_CIPHER_ALG FIELD32(0x00007000) | ||
| 531 | #define SEC_CSR1_BSS1_KEY0_CIPHER_ALG FIELD32(0x00070000) | ||
| 532 | #define SEC_CSR1_BSS1_KEY1_CIPHER_ALG FIELD32(0x00700000) | ||
| 533 | #define SEC_CSR1_BSS1_KEY2_CIPHER_ALG FIELD32(0x07000000) | ||
| 534 | #define SEC_CSR1_BSS1_KEY3_CIPHER_ALG FIELD32(0x70000000) | ||
| 535 | |||
| 536 | /* | ||
| 537 | * Pairwise key table valid bitmap registers. | ||
| 538 | * SEC_CSR2: pairwise key table valid bitmap 0. | ||
| 539 | * SEC_CSR3: pairwise key table valid bitmap 1. | ||
| 540 | */ | ||
| 541 | #define SEC_CSR2 0x30a8 | ||
| 542 | #define SEC_CSR3 0x30ac | ||
| 543 | |||
| 544 | /* | ||
| 545 | * SEC_CSR4: Pairwise key table lookup control. | ||
| 546 | */ | ||
| 547 | #define SEC_CSR4 0x30b0 | ||
| 548 | |||
| 549 | /* | ||
| 550 | * SEC_CSR5: shared key table security mode register. | ||
| 551 | */ | ||
| 552 | #define SEC_CSR5 0x30b4 | ||
| 553 | #define SEC_CSR5_BSS2_KEY0_CIPHER_ALG FIELD32(0x00000007) | ||
| 554 | #define SEC_CSR5_BSS2_KEY1_CIPHER_ALG FIELD32(0x00000070) | ||
| 555 | #define SEC_CSR5_BSS2_KEY2_CIPHER_ALG FIELD32(0x00000700) | ||
| 556 | #define SEC_CSR5_BSS2_KEY3_CIPHER_ALG FIELD32(0x00007000) | ||
| 557 | #define SEC_CSR5_BSS3_KEY0_CIPHER_ALG FIELD32(0x00070000) | ||
| 558 | #define SEC_CSR5_BSS3_KEY1_CIPHER_ALG FIELD32(0x00700000) | ||
| 559 | #define SEC_CSR5_BSS3_KEY2_CIPHER_ALG FIELD32(0x07000000) | ||
| 560 | #define SEC_CSR5_BSS3_KEY3_CIPHER_ALG FIELD32(0x70000000) | ||
| 561 | |||
| 562 | /* | ||
| 563 | * STA control registers. | ||
| 564 | */ | ||
| 565 | |||
| 566 | /* | ||
| 567 | * STA_CSR0: RX PLCP error count & RX FCS error count. | ||
| 568 | */ | ||
| 569 | #define STA_CSR0 0x30c0 | ||
| 570 | #define STA_CSR0_FCS_ERROR FIELD32(0x0000ffff) | ||
| 571 | #define STA_CSR0_PLCP_ERROR FIELD32(0xffff0000) | ||
| 572 | |||
| 573 | /* | ||
| 574 | * STA_CSR1: RX False CCA count & RX LONG frame count. | ||
| 575 | */ | ||
| 576 | #define STA_CSR1 0x30c4 | ||
| 577 | #define STA_CSR1_PHYSICAL_ERROR FIELD32(0x0000ffff) | ||
| 578 | #define STA_CSR1_FALSE_CCA_ERROR FIELD32(0xffff0000) | ||
| 579 | |||
| 580 | /* | ||
| 581 | * STA_CSR2: TX Beacon count and RX FIFO overflow count. | ||
| 582 | */ | ||
| 583 | #define STA_CSR2 0x30c8 | ||
| 584 | #define STA_CSR2_RX_FIFO_OVERFLOW_COUNT FIELD32(0x0000ffff) | ||
| 585 | #define STA_CSR2_RX_OVERFLOW_COUNT FIELD32(0xffff0000) | ||
| 586 | |||
| 587 | /* | ||
| 588 | * STA_CSR3: TX Beacon count. | ||
| 589 | */ | ||
| 590 | #define STA_CSR3 0x30cc | ||
| 591 | #define STA_CSR3_TX_BEACON_COUNT FIELD32(0x0000ffff) | ||
| 592 | |||
| 593 | /* | ||
| 594 | * STA_CSR4: TX Retry count. | ||
| 595 | */ | ||
| 596 | #define STA_CSR4 0x30d0 | ||
| 597 | #define STA_CSR4_TX_NO_RETRY_COUNT FIELD32(0x0000ffff) | ||
| 598 | #define STA_CSR4_TX_ONE_RETRY_COUNT FIELD32(0xffff0000) | ||
| 599 | |||
| 600 | /* | ||
| 601 | * STA_CSR5: TX Retry count. | ||
| 602 | */ | ||
| 603 | #define STA_CSR5 0x30d4 | ||
| 604 | #define STA_CSR4_TX_MULTI_RETRY_COUNT FIELD32(0x0000ffff) | ||
| 605 | #define STA_CSR4_TX_RETRY_FAIL_COUNT FIELD32(0xffff0000) | ||
| 606 | |||
| 607 | /* | ||
| 608 | * QOS control registers. | ||
| 609 | */ | ||
| 610 | |||
| 611 | /* | ||
| 612 | * QOS_CSR1: TXOP holder MAC address register. | ||
| 613 | */ | ||
| 614 | #define QOS_CSR1 0x30e4 | ||
| 615 | #define QOS_CSR1_BYTE4 FIELD32(0x000000ff) | ||
| 616 | #define QOS_CSR1_BYTE5 FIELD32(0x0000ff00) | ||
| 617 | |||
| 618 | /* | ||
| 619 | * QOS_CSR2: TXOP holder timeout register. | ||
| 620 | */ | ||
| 621 | #define QOS_CSR2 0x30e8 | ||
| 622 | |||
| 623 | /* | ||
| 624 | * RX QOS-CFPOLL MAC address register. | ||
| 625 | * QOS_CSR3: RX QOS-CFPOLL MAC address 0. | ||
| 626 | * QOS_CSR4: RX QOS-CFPOLL MAC address 1. | ||
| 627 | */ | ||
| 628 | #define QOS_CSR3 0x30ec | ||
| 629 | #define QOS_CSR4 0x30f0 | ||
| 630 | |||
| 631 | /* | ||
| 632 | * QOS_CSR5: "QosControl" field of the RX QOS-CFPOLL. | ||
| 633 | */ | ||
| 634 | #define QOS_CSR5 0x30f4 | ||
| 635 | |||
| 636 | /* | ||
| 637 | * WMM Scheduler Register | ||
| 638 | */ | ||
| 639 | |||
| 640 | /* | ||
| 641 | * AIFSN_CSR: AIFSN for each EDCA AC. | ||
| 642 | * AIFSN0: For AC_BK. | ||
| 643 | * AIFSN1: For AC_BE. | ||
| 644 | * AIFSN2: For AC_VI. | ||
| 645 | * AIFSN3: For AC_VO. | ||
| 646 | */ | ||
| 647 | #define AIFSN_CSR 0x0400 | ||
| 648 | #define AIFSN_CSR_AIFSN0 FIELD32(0x0000000f) | ||
| 649 | #define AIFSN_CSR_AIFSN1 FIELD32(0x000000f0) | ||
| 650 | #define AIFSN_CSR_AIFSN2 FIELD32(0x00000f00) | ||
| 651 | #define AIFSN_CSR_AIFSN3 FIELD32(0x0000f000) | ||
| 652 | |||
| 653 | /* | ||
| 654 | * CWMIN_CSR: CWmin for each EDCA AC. | ||
| 655 | * CWMIN0: For AC_BK. | ||
| 656 | * CWMIN1: For AC_BE. | ||
| 657 | * CWMIN2: For AC_VI. | ||
| 658 | * CWMIN3: For AC_VO. | ||
| 659 | */ | ||
| 660 | #define CWMIN_CSR 0x0404 | ||
| 661 | #define CWMIN_CSR_CWMIN0 FIELD32(0x0000000f) | ||
| 662 | #define CWMIN_CSR_CWMIN1 FIELD32(0x000000f0) | ||
| 663 | #define CWMIN_CSR_CWMIN2 FIELD32(0x00000f00) | ||
| 664 | #define CWMIN_CSR_CWMIN3 FIELD32(0x0000f000) | ||
| 665 | |||
| 666 | /* | ||
| 667 | * CWMAX_CSR: CWmax for each EDCA AC. | ||
| 668 | * CWMAX0: For AC_BK. | ||
| 669 | * CWMAX1: For AC_BE. | ||
| 670 | * CWMAX2: For AC_VI. | ||
| 671 | * CWMAX3: For AC_VO. | ||
| 672 | */ | ||
| 673 | #define CWMAX_CSR 0x0408 | ||
| 674 | #define CWMAX_CSR_CWMAX0 FIELD32(0x0000000f) | ||
| 675 | #define CWMAX_CSR_CWMAX1 FIELD32(0x000000f0) | ||
| 676 | #define CWMAX_CSR_CWMAX2 FIELD32(0x00000f00) | ||
| 677 | #define CWMAX_CSR_CWMAX3 FIELD32(0x0000f000) | ||
| 678 | |||
| 679 | /* | ||
| 680 | * AC_TXOP_CSR0: AC_BK/AC_BE TXOP register. | ||
| 681 | * AC0_TX_OP: For AC_BK, in unit of 32us. | ||
| 682 | * AC1_TX_OP: For AC_BE, in unit of 32us. | ||
| 683 | */ | ||
| 684 | #define AC_TXOP_CSR0 0x040c | ||
| 685 | #define AC_TXOP_CSR0_AC0_TX_OP FIELD32(0x0000ffff) | ||
| 686 | #define AC_TXOP_CSR0_AC1_TX_OP FIELD32(0xffff0000) | ||
| 687 | |||
| 688 | /* | ||
| 689 | * AC_TXOP_CSR1: AC_VO/AC_VI TXOP register. | ||
| 690 | * AC2_TX_OP: For AC_VI, in unit of 32us. | ||
| 691 | * AC3_TX_OP: For AC_VO, in unit of 32us. | ||
| 692 | */ | ||
| 693 | #define AC_TXOP_CSR1 0x0410 | ||
| 694 | #define AC_TXOP_CSR1_AC2_TX_OP FIELD32(0x0000ffff) | ||
| 695 | #define AC_TXOP_CSR1_AC3_TX_OP FIELD32(0xffff0000) | ||
| 696 | |||
| 697 | /* | ||
| 698 | * BBP registers. | ||
| 699 | * The wordsize of the BBP is 8 bits. | ||
| 700 | */ | ||
| 701 | |||
| 702 | /* | ||
| 703 | * R2 | ||
| 704 | */ | ||
| 705 | #define BBP_R2_BG_MODE FIELD8(0x20) | ||
| 706 | |||
| 707 | /* | ||
| 708 | * R3 | ||
| 709 | */ | ||
| 710 | #define BBP_R3_SMART_MODE FIELD8(0x01) | ||
| 711 | |||
| 712 | /* | ||
| 713 | * R4: RX antenna control | ||
| 714 | * FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529) | ||
| 715 | */ | ||
| 716 | #define BBP_R4_RX_ANTENNA FIELD8(0x03) | ||
| 717 | #define BBP_R4_RX_FRAME_END FIELD8(0x20) | ||
| 718 | |||
| 719 | /* | ||
| 720 | * R77 | ||
| 721 | */ | ||
| 722 | #define BBP_R77_PAIR FIELD8(0x03) | ||
| 723 | |||
| 724 | /* | ||
| 725 | * RF registers | ||
| 726 | */ | ||
| 727 | |||
| 728 | /* | ||
| 729 | * RF 3 | ||
| 730 | */ | ||
| 731 | #define RF3_TXPOWER FIELD32(0x00003e00) | ||
| 732 | |||
| 733 | /* | ||
| 734 | * RF 4 | ||
| 735 | */ | ||
| 736 | #define RF4_FREQ_OFFSET FIELD32(0x0003f000) | ||
| 737 | |||
| 738 | /* | ||
| 739 | * EEPROM content. | ||
| 740 | * The wordsize of the EEPROM is 16 bits. | ||
| 741 | */ | ||
| 742 | |||
| 743 | /* | ||
| 744 | * HW MAC address. | ||
| 745 | */ | ||
| 746 | #define EEPROM_MAC_ADDR_0 0x0002 | ||
| 747 | #define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff) | ||
| 748 | #define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00) | ||
| 749 | #define EEPROM_MAC_ADDR1 0x0003 | ||
| 750 | #define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff) | ||
| 751 | #define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00) | ||
| 752 | #define EEPROM_MAC_ADDR_2 0x0004 | ||
| 753 | #define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff) | ||
| 754 | #define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) | ||
| 755 | |||
| 756 | /* | ||
| 757 | * EEPROM antenna. | ||
| 758 | * ANTENNA_NUM: Number of antenna's. | ||
| 759 | * TX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B. | ||
| 760 | * RX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B. | ||
| 761 | * FRAME_TYPE: 0: DPDT , 1: SPDT , noted this bit is valid for g only. | ||
| 762 | * DYN_TXAGC: Dynamic TX AGC control. | ||
| 763 | * HARDWARE_RADIO: 1: Hardware controlled radio. Read GPIO0. | ||
| 764 | * RF_TYPE: Rf_type of this adapter. | ||
| 765 | */ | ||
| 766 | #define EEPROM_ANTENNA 0x0010 | ||
| 767 | #define EEPROM_ANTENNA_NUM FIELD16(0x0003) | ||
| 768 | #define EEPROM_ANTENNA_TX_DEFAULT FIELD16(0x000c) | ||
| 769 | #define EEPROM_ANTENNA_RX_DEFAULT FIELD16(0x0030) | ||
| 770 | #define EEPROM_ANTENNA_FRAME_TYPE FIELD16(0x0040) | ||
| 771 | #define EEPROM_ANTENNA_DYN_TXAGC FIELD16(0x0200) | ||
| 772 | #define EEPROM_ANTENNA_HARDWARE_RADIO FIELD16(0x0400) | ||
| 773 | #define EEPROM_ANTENNA_RF_TYPE FIELD16(0xf800) | ||
| 774 | |||
| 775 | /* | ||
| 776 | * EEPROM NIC config. | ||
| 777 | * EXTERNAL_LNA: External LNA. | ||
| 778 | */ | ||
| 779 | #define EEPROM_NIC 0x0011 | ||
| 780 | #define EEPROM_NIC_EXTERNAL_LNA FIELD16(0x0010) | ||
| 781 | |||
| 782 | /* | ||
| 783 | * EEPROM geography. | ||
| 784 | * GEO_A: Default geographical setting for 5GHz band | ||
| 785 | * GEO: Default geographical setting. | ||
| 786 | */ | ||
| 787 | #define EEPROM_GEOGRAPHY 0x0012 | ||
| 788 | #define EEPROM_GEOGRAPHY_GEO_A FIELD16(0x00ff) | ||
| 789 | #define EEPROM_GEOGRAPHY_GEO FIELD16(0xff00) | ||
| 790 | |||
| 791 | /* | ||
| 792 | * EEPROM BBP. | ||
| 793 | */ | ||
| 794 | #define EEPROM_BBP_START 0x0013 | ||
| 795 | #define EEPROM_BBP_SIZE 16 | ||
| 796 | #define EEPROM_BBP_VALUE FIELD16(0x00ff) | ||
| 797 | #define EEPROM_BBP_REG_ID FIELD16(0xff00) | ||
| 798 | |||
| 799 | /* | ||
| 800 | * EEPROM TXPOWER 802.11G | ||
| 801 | */ | ||
| 802 | #define EEPROM_TXPOWER_G_START 0x0023 | ||
| 803 | #define EEPROM_TXPOWER_G_SIZE 7 | ||
| 804 | #define EEPROM_TXPOWER_G_1 FIELD16(0x00ff) | ||
| 805 | #define EEPROM_TXPOWER_G_2 FIELD16(0xff00) | ||
| 806 | |||
| 807 | /* | ||
| 808 | * EEPROM Frequency | ||
| 809 | */ | ||
| 810 | #define EEPROM_FREQ 0x002f | ||
| 811 | #define EEPROM_FREQ_OFFSET FIELD16(0x00ff) | ||
| 812 | #define EEPROM_FREQ_SEQ_MASK FIELD16(0xff00) | ||
| 813 | #define EEPROM_FREQ_SEQ FIELD16(0x0300) | ||
| 814 | |||
| 815 | /* | ||
| 816 | * EEPROM LED. | ||
| 817 | * POLARITY_RDY_G: Polarity RDY_G setting. | ||
| 818 | * POLARITY_RDY_A: Polarity RDY_A setting. | ||
| 819 | * POLARITY_ACT: Polarity ACT setting. | ||
| 820 | * POLARITY_GPIO_0: Polarity GPIO0 setting. | ||
| 821 | * POLARITY_GPIO_1: Polarity GPIO1 setting. | ||
| 822 | * POLARITY_GPIO_2: Polarity GPIO2 setting. | ||
| 823 | * POLARITY_GPIO_3: Polarity GPIO3 setting. | ||
| 824 | * POLARITY_GPIO_4: Polarity GPIO4 setting. | ||
| 825 | * LED_MODE: Led mode. | ||
| 826 | */ | ||
| 827 | #define EEPROM_LED 0x0030 | ||
| 828 | #define EEPROM_LED_POLARITY_RDY_G FIELD16(0x0001) | ||
| 829 | #define EEPROM_LED_POLARITY_RDY_A FIELD16(0x0002) | ||
| 830 | #define EEPROM_LED_POLARITY_ACT FIELD16(0x0004) | ||
| 831 | #define EEPROM_LED_POLARITY_GPIO_0 FIELD16(0x0008) | ||
| 832 | #define EEPROM_LED_POLARITY_GPIO_1 FIELD16(0x0010) | ||
| 833 | #define EEPROM_LED_POLARITY_GPIO_2 FIELD16(0x0020) | ||
| 834 | #define EEPROM_LED_POLARITY_GPIO_3 FIELD16(0x0040) | ||
| 835 | #define EEPROM_LED_POLARITY_GPIO_4 FIELD16(0x0080) | ||
| 836 | #define EEPROM_LED_LED_MODE FIELD16(0x1f00) | ||
| 837 | |||
| 838 | /* | ||
| 839 | * EEPROM TXPOWER 802.11A | ||
| 840 | */ | ||
| 841 | #define EEPROM_TXPOWER_A_START 0x0031 | ||
| 842 | #define EEPROM_TXPOWER_A_SIZE 12 | ||
| 843 | #define EEPROM_TXPOWER_A_1 FIELD16(0x00ff) | ||
| 844 | #define EEPROM_TXPOWER_A_2 FIELD16(0xff00) | ||
| 845 | |||
| 846 | /* | ||
| 847 | * EEPROM RSSI offset 802.11BG | ||
| 848 | */ | ||
| 849 | #define EEPROM_RSSI_OFFSET_BG 0x004d | ||
| 850 | #define EEPROM_RSSI_OFFSET_BG_1 FIELD16(0x00ff) | ||
| 851 | #define EEPROM_RSSI_OFFSET_BG_2 FIELD16(0xff00) | ||
| 852 | |||
| 853 | /* | ||
| 854 | * EEPROM RSSI offset 802.11A | ||
| 855 | */ | ||
| 856 | #define EEPROM_RSSI_OFFSET_A 0x004e | ||
| 857 | #define EEPROM_RSSI_OFFSET_A_1 FIELD16(0x00ff) | ||
| 858 | #define EEPROM_RSSI_OFFSET_A_2 FIELD16(0xff00) | ||
| 859 | |||
| 860 | /* | ||
| 861 | * DMA descriptor defines. | ||
| 862 | */ | ||
| 863 | #define TXD_DESC_SIZE ( 6 * sizeof(struct data_desc) ) | ||
| 864 | #define RXD_DESC_SIZE ( 6 * sizeof(struct data_desc) ) | ||
| 865 | |||
| 866 | /* | ||
| 867 | * TX descriptor format for TX, PRIO and Beacon Ring. | ||
| 868 | */ | ||
| 869 | |||
| 870 | /* | ||
| 871 | * Word0 | ||
| 872 | * BURST: Next frame belongs to same "burst" event. | ||
| 873 | * TKIP_MIC: ASIC appends TKIP MIC if TKIP is used. | ||
| 874 | * KEY_TABLE: Use per-client pairwise KEY table. | ||
| 875 | * KEY_INDEX: | ||
| 876 | * Key index (0~31) to the pairwise KEY table. | ||
| 877 | * 0~3 to shared KEY table 0 (BSS0). | ||
| 878 | * 4~7 to shared KEY table 1 (BSS1). | ||
| 879 | * 8~11 to shared KEY table 2 (BSS2). | ||
| 880 | * 12~15 to shared KEY table 3 (BSS3). | ||
| 881 | * BURST2: For backward compatibility, set to same value as BURST. | ||
| 882 | */ | ||
| 883 | #define TXD_W0_BURST FIELD32(0x00000001) | ||
| 884 | #define TXD_W0_VALID FIELD32(0x00000002) | ||
| 885 | #define TXD_W0_MORE_FRAG FIELD32(0x00000004) | ||
| 886 | #define TXD_W0_ACK FIELD32(0x00000008) | ||
| 887 | #define TXD_W0_TIMESTAMP FIELD32(0x00000010) | ||
| 888 | #define TXD_W0_OFDM FIELD32(0x00000020) | ||
| 889 | #define TXD_W0_IFS FIELD32(0x00000040) | ||
| 890 | #define TXD_W0_RETRY_MODE FIELD32(0x00000080) | ||
| 891 | #define TXD_W0_TKIP_MIC FIELD32(0x00000100) | ||
| 892 | #define TXD_W0_KEY_TABLE FIELD32(0x00000200) | ||
| 893 | #define TXD_W0_KEY_INDEX FIELD32(0x0000fc00) | ||
| 894 | #define TXD_W0_DATABYTE_COUNT FIELD32(0x0fff0000) | ||
| 895 | #define TXD_W0_BURST2 FIELD32(0x10000000) | ||
| 896 | #define TXD_W0_CIPHER_ALG FIELD32(0xe0000000) | ||
| 897 | |||
| 898 | /* | ||
| 899 | * Word1 | ||
| 900 | * HOST_Q_ID: EDCA/HCCA queue ID. | ||
| 901 | * HW_SEQUENCE: MAC overwrites the frame sequence number. | ||
| 902 | * BUFFER_COUNT: Number of buffers in this TXD. | ||
| 903 | */ | ||
| 904 | #define TXD_W1_HOST_Q_ID FIELD32(0x0000000f) | ||
| 905 | #define TXD_W1_AIFSN FIELD32(0x000000f0) | ||
| 906 | #define TXD_W1_CWMIN FIELD32(0x00000f00) | ||
| 907 | #define TXD_W1_CWMAX FIELD32(0x0000f000) | ||
| 908 | #define TXD_W1_IV_OFFSET FIELD32(0x003f0000) | ||
| 909 | #define TXD_W1_HW_SEQUENCE FIELD32(0x10000000) | ||
| 910 | #define TXD_W1_BUFFER_COUNT FIELD32(0xe0000000) | ||
| 911 | |||
| 912 | /* | ||
| 913 | * Word2: PLCP information | ||
| 914 | */ | ||
| 915 | #define TXD_W2_PLCP_SIGNAL FIELD32(0x000000ff) | ||
| 916 | #define TXD_W2_PLCP_SERVICE FIELD32(0x0000ff00) | ||
| 917 | #define TXD_W2_PLCP_LENGTH_LOW FIELD32(0x00ff0000) | ||
| 918 | #define TXD_W2_PLCP_LENGTH_HIGH FIELD32(0xff000000) | ||
| 919 | |||
| 920 | /* | ||
| 921 | * Word3 | ||
| 922 | */ | ||
| 923 | #define TXD_W3_IV FIELD32(0xffffffff) | ||
| 924 | |||
| 925 | /* | ||
| 926 | * Word4 | ||
| 927 | */ | ||
| 928 | #define TXD_W4_EIV FIELD32(0xffffffff) | ||
| 929 | |||
| 930 | /* | ||
| 931 | * Word5 | ||
| 932 | * FRAME_OFFSET: Frame start offset inside ASIC TXFIFO (after TXINFO field). | ||
| 933 | * PACKET_ID: Driver assigned packet ID to categorize TXResult in interrupt. | ||
| 934 | * WAITING_DMA_DONE_INT: TXD been filled with data | ||
| 935 | * and waiting for TxDoneISR housekeeping. | ||
| 936 | */ | ||
| 937 | #define TXD_W5_FRAME_OFFSET FIELD32(0x000000ff) | ||
| 938 | #define TXD_W5_PACKET_ID FIELD32(0x0000ff00) | ||
| 939 | #define TXD_W5_TX_POWER FIELD32(0x00ff0000) | ||
| 940 | #define TXD_W5_WAITING_DMA_DONE_INT FIELD32(0x01000000) | ||
| 941 | |||
| 942 | /* | ||
| 943 | * RX descriptor format for RX Ring. | ||
| 944 | */ | ||
| 945 | |||
| 946 | /* | ||
| 947 | * Word0 | ||
| 948 | * CIPHER_ERROR: 1:ICV error, 2:MIC error, 3:invalid key. | ||
| 949 | * KEY_INDEX: Decryption key actually used. | ||
| 950 | */ | ||
| 951 | #define RXD_W0_OWNER_NIC FIELD32(0x00000001) | ||
| 952 | #define RXD_W0_DROP FIELD32(0x00000002) | ||
| 953 | #define RXD_W0_UNICAST_TO_ME FIELD32(0x00000004) | ||
| 954 | #define RXD_W0_MULTICAST FIELD32(0x00000008) | ||
| 955 | #define RXD_W0_BROADCAST FIELD32(0x00000010) | ||
| 956 | #define RXD_W0_MY_BSS FIELD32(0x00000020) | ||
| 957 | #define RXD_W0_CRC_ERROR FIELD32(0x00000040) | ||
| 958 | #define RXD_W0_OFDM FIELD32(0x00000080) | ||
| 959 | #define RXD_W0_CIPHER_ERROR FIELD32(0x00000300) | ||
| 960 | #define RXD_W0_KEY_INDEX FIELD32(0x0000fc00) | ||
| 961 | #define RXD_W0_DATABYTE_COUNT FIELD32(0x0fff0000) | ||
| 962 | #define RXD_W0_CIPHER_ALG FIELD32(0xe0000000) | ||
| 963 | |||
| 964 | /* | ||
| 965 | * WORD1 | ||
| 966 | * SIGNAL: RX raw data rate reported by BBP. | ||
| 967 | * RSSI: RSSI reported by BBP. | ||
| 968 | */ | ||
| 969 | #define RXD_W1_SIGNAL FIELD32(0x000000ff) | ||
| 970 | #define RXD_W1_RSSI_AGC FIELD32(0x00001f00) | ||
| 971 | #define RXD_W1_RSSI_LNA FIELD32(0x00006000) | ||
| 972 | #define RXD_W1_FRAME_OFFSET FIELD32(0x7f000000) | ||
| 973 | |||
| 974 | /* | ||
| 975 | * Word2 | ||
| 976 | * IV: Received IV of originally encrypted. | ||
| 977 | */ | ||
| 978 | #define RXD_W2_IV FIELD32(0xffffffff) | ||
| 979 | |||
| 980 | /* | ||
| 981 | * Word3 | ||
| 982 | * EIV: Received EIV of originally encrypted. | ||
| 983 | */ | ||
| 984 | #define RXD_W3_EIV FIELD32(0xffffffff) | ||
| 985 | |||
| 986 | /* | ||
| 987 | * Word4 | ||
| 988 | */ | ||
| 989 | #define RXD_W4_RESERVED FIELD32(0xffffffff) | ||
| 990 | |||
| 991 | /* | ||
| 992 | * the above 20-byte is called RXINFO and will be DMAed to MAC RX block | ||
| 993 | * and passed to the HOST driver. | ||
| 994 | * The following fields are for DMA block and HOST usage only. | ||
| 995 | * Can't be touched by ASIC MAC block. | ||
| 996 | */ | ||
| 997 | |||
| 998 | /* | ||
| 999 | * Word5 | ||
| 1000 | */ | ||
| 1001 | #define RXD_W5_RESERVED FIELD32(0xffffffff) | ||
| 1002 | |||
| 1003 | /* | ||
| 1004 | * Macro's for converting txpower from EEPROM to dscape value | ||
| 1005 | * and from dscape value to register value. | ||
| 1006 | */ | ||
| 1007 | #define MIN_TXPOWER 0 | ||
| 1008 | #define MAX_TXPOWER 31 | ||
| 1009 | #define DEFAULT_TXPOWER 24 | ||
| 1010 | |||
| 1011 | #define TXPOWER_FROM_DEV(__txpower) \ | ||
| 1012 | ({ \ | ||
| 1013 | ((__txpower) > MAX_TXPOWER) ? \ | ||
| 1014 | DEFAULT_TXPOWER : (__txpower); \ | ||
| 1015 | }) | ||
| 1016 | |||
| 1017 | #define TXPOWER_TO_DEV(__txpower) \ | ||
| 1018 | ({ \ | ||
| 1019 | ((__txpower) <= MIN_TXPOWER) ? MIN_TXPOWER : \ | ||
| 1020 | (((__txpower) >= MAX_TXPOWER) ? MAX_TXPOWER : \ | ||
| 1021 | (__txpower)); \ | ||
| 1022 | }) | ||
| 1023 | |||
| 1024 | #endif /* RT73USB_H */ | ||
