blob: 365f66fe7c68a741480419a57c65ba2ec93f65a1 [file] [log] [blame]
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001/*
2 Copyright (C) 2004 - 2009 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: rt2800usb
23 Abstract: rt2800usb device specific routines.
24 Supported chipsets: RT2800U.
25 */
26
27#include <linux/crc-ccitt.h>
28#include <linux/delay.h>
29#include <linux/etherdevice.h>
30#include <linux/init.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/usb.h>
34
35#include "rt2x00.h"
36#include "rt2x00usb.h"
Bartlomiej Zolnierkiewicz7ef5cc92009-11-04 18:35:32 +010037#include "rt2800lib.h"
Bartlomiej Zolnierkiewiczb54f78a2009-11-04 18:35:54 +010038#include "rt2800.h"
Ivo van Doornd53d9e62009-04-26 15:47:48 +020039#include "rt2800usb.h"
40
41/*
42 * Allow hardware encryption to be disabled.
43 */
44static int modparam_nohwcrypt = 1;
45module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
46MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
47
Ivo van Doornd53d9e62009-04-26 15:47:48 +020048/*
49 * Firmware functions
50 */
51static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
52{
53 return FIRMWARE_RT2870;
54}
55
56static bool rt2800usb_check_crc(const u8 *data, const size_t len)
57{
58 u16 fw_crc;
59 u16 crc;
60
61 /*
62 * The last 2 bytes in the firmware array are the crc checksum itself,
63 * this means that we should never pass those 2 bytes to the crc
64 * algorithm.
65 */
66 fw_crc = (data[len - 2] << 8 | data[len - 1]);
67
68 /*
69 * Use the crc ccitt algorithm.
70 * This will return the same value as the legacy driver which
71 * used bit ordering reversion on the both the firmware bytes
72 * before input input as well as on the final output.
73 * Obviously using crc ccitt directly is much more efficient.
74 */
75 crc = crc_ccitt(~0, data, len - 2);
76
77 /*
78 * There is a small difference between the crc-itu-t + bitrev and
79 * the crc-ccitt crc calculation. In the latter method the 2 bytes
80 * will be swapped, use swab16 to convert the crc to the correct
81 * value.
82 */
83 crc = swab16(crc);
84
85 return fw_crc == crc;
86}
87
88static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev,
89 const u8 *data, const size_t len)
90{
91 u16 chipset = (rt2x00_rev(&rt2x00dev->chip) >> 16) & 0xffff;
92 size_t offset = 0;
93
94 /*
95 * Firmware files:
96 * There are 2 variations of the rt2870 firmware.
97 * a) size: 4kb
98 * b) size: 8kb
99 * Note that (b) contains 2 seperate firmware blobs of 4k
100 * within the file. The first blob is the same firmware as (a),
101 * but the second blob is for the additional chipsets.
102 */
103 if (len != 4096 && len != 8192)
104 return FW_BAD_LENGTH;
105
106 /*
107 * Check if we need the upper 4kb firmware data or not.
108 */
109 if ((len == 4096) &&
110 (chipset != 0x2860) &&
111 (chipset != 0x2872) &&
112 (chipset != 0x3070))
113 return FW_BAD_VERSION;
114
115 /*
116 * 8kb firmware files must be checked as if it were
117 * 2 seperate firmware files.
118 */
119 while (offset < len) {
120 if (!rt2800usb_check_crc(data + offset, 4096))
121 return FW_BAD_CRC;
122
123 offset += 4096;
124 }
125
126 return FW_OK;
127}
128
129static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
130 const u8 *data, const size_t len)
131{
132 unsigned int i;
133 int status;
134 u32 reg;
135 u32 offset;
136 u32 length;
137 u16 chipset = (rt2x00_rev(&rt2x00dev->chip) >> 16) & 0xffff;
138
139 /*
140 * Check which section of the firmware we need.
141 */
Ivo van Doorn15e46922009-04-28 20:14:58 +0200142 if ((chipset == 0x2860) ||
143 (chipset == 0x2872) ||
144 (chipset == 0x3070)) {
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200145 offset = 0;
146 length = 4096;
147 } else {
148 offset = 4096;
149 length = 4096;
150 }
151
152 /*
153 * Wait for stable hardware.
154 */
155 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100156 rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200157 if (reg && reg != ~0)
158 break;
159 msleep(1);
160 }
161
162 if (i == REGISTER_BUSY_COUNT) {
163 ERROR(rt2x00dev, "Unstable hardware.\n");
164 return -EBUSY;
165 }
166
167 /*
168 * Write firmware to device.
169 */
170 rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
171 USB_VENDOR_REQUEST_OUT,
172 FIRMWARE_IMAGE_BASE,
173 data + offset, length,
174 REGISTER_TIMEOUT32(length));
175
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100176 rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
177 rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200178
179 /*
180 * Send firmware request to device to load firmware,
181 * we need to specify a long timeout time.
182 */
183 status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE,
184 0, USB_MODE_FIRMWARE,
185 REGISTER_TIMEOUT_FIRMWARE);
186 if (status < 0) {
187 ERROR(rt2x00dev, "Failed to write Firmware to device.\n");
188 return status;
189 }
190
Ivo van Doorn15e46922009-04-28 20:14:58 +0200191 msleep(10);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100192 rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
Ivo van Doorn15e46922009-04-28 20:14:58 +0200193
194 /*
195 * Send signal to firmware during boot time.
196 */
Bartlomiej Zolnierkiewicz4f2c5322009-11-04 18:34:32 +0100197 rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);
Ivo van Doorn15e46922009-04-28 20:14:58 +0200198
199 if ((chipset == 0x3070) ||
200 (chipset == 0x3071) ||
201 (chipset == 0x3572)) {
202 udelay(200);
Bartlomiej Zolnierkiewicz4f2c5322009-11-04 18:34:32 +0100203 rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
Ivo van Doorn15e46922009-04-28 20:14:58 +0200204 udelay(10);
205 }
206
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200207 /*
208 * Wait for device to stabilize.
209 */
210 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100211 rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200212 if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
213 break;
214 msleep(1);
215 }
216
217 if (i == REGISTER_BUSY_COUNT) {
218 ERROR(rt2x00dev, "PBF system register not ready.\n");
219 return -EBUSY;
220 }
221
222 /*
223 * Initialize firmware.
224 */
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100225 rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
226 rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200227 msleep(1);
228
229 return 0;
230}
231
232/*
233 * Initialization functions.
234 */
235static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
236{
237 u32 reg;
238 unsigned int i;
239
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +0100240 if (rt2x00_intf_is_usb(rt2x00dev)) {
241 /*
242 * Wait untill BBP and RF are ready.
243 */
244 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
245 rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
246 if (reg && reg != ~0)
247 break;
248 msleep(1);
249 }
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200250
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +0100251 if (i == REGISTER_BUSY_COUNT) {
252 ERROR(rt2x00dev, "Unstable hardware.\n");
253 return -EBUSY;
254 }
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200255
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +0100256 rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
257 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL,
258 reg & ~0x00002000);
259 }
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200260
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100261 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200262 rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
263 rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100264 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200265
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +0100266 if (rt2x00_intf_is_usb(rt2x00dev)) {
267 rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200268
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +0100269 rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
270 USB_MODE_RESET, REGISTER_TIMEOUT);
271 }
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200272
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100273 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200274
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100275 rt2800_register_read(rt2x00dev, BCN_OFFSET0, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200276 rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */
277 rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1, 0xe8); /* 0x3a00 */
278 rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2, 0xf0); /* 0x3c00 */
279 rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3, 0xf8); /* 0x3e00 */
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100280 rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200281
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100282 rt2800_register_read(rt2x00dev, BCN_OFFSET1, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200283 rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4, 0xc8); /* 0x3200 */
284 rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5, 0xd0); /* 0x3400 */
285 rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6, 0x77); /* 0x1dc0 */
286 rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7, 0x6f); /* 0x1bc0 */
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100287 rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200288
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100289 rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
290 rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200291
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100292 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200293
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100294 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200295 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL, 0);
296 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
297 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, 0);
298 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
299 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
300 rt2x00_set_field32(&reg, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100301 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200302
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +0100303 if (rt2x00_intf_is_usb(rt2x00dev) &&
304 rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100305 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
306 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
307 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200308 } else {
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100309 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
310 rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200311 }
312
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100313 rt2800_register_read(rt2x00dev, TX_LINK_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200314 rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB_LIFETIME, 32);
315 rt2x00_set_field32(&reg, TX_LINK_CFG_MFB_ENABLE, 0);
316 rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_UMFS_ENABLE, 0);
317 rt2x00_set_field32(&reg, TX_LINK_CFG_TX_MRQ_EN, 0);
318 rt2x00_set_field32(&reg, TX_LINK_CFG_TX_RDG_EN, 0);
319 rt2x00_set_field32(&reg, TX_LINK_CFG_TX_CF_ACK_EN, 1);
320 rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB, 0);
321 rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFS, 0);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100322 rt2800_register_write(rt2x00dev, TX_LINK_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200323
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100324 rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200325 rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_MPDU_LIFETIME, 9);
326 rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_TX_OP_TIMEOUT, 10);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100327 rt2800_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200328
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100329 rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200330 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
331 if (rt2x00_rev(&rt2x00dev->chip) >= RT2880E_VERSION &&
332 rt2x00_rev(&rt2x00dev->chip) < RT3070_VERSION)
333 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
334 else
335 rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
336 rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_PSDU, 0);
337 rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 0);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100338 rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200339
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100340 rt2800_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200341
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100342 rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200343 rt2x00_set_field32(&reg, AUTO_RSP_CFG_AUTORESPONDER, 1);
344 rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MMODE, 0);
345 rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MREF, 0);
346 rt2x00_set_field32(&reg, AUTO_RSP_CFG_DUAL_CTS_EN, 0);
347 rt2x00_set_field32(&reg, AUTO_RSP_CFG_ACK_CTS_PSM_BIT, 0);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100348 rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200349
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100350 rt2800_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200351 rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_RATE, 8);
352 rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_CTRL, 0);
353 rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_NAV, 1);
354 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1);
355 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
356 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1);
357 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 1);
358 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1);
359 rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 1);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100360 rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200361
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100362 rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200363 rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_RATE, 8);
364 rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL, 0);
365 rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_NAV, 1);
366 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1);
367 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
368 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1);
369 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 1);
370 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1);
371 rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 1);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100372 rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200373
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100374 rt2800_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200375 rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_RATE, 0x4004);
376 rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_CTRL, 0);
377 rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_NAV, 1);
378 rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
379 rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
380 rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
381 rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
382 rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
383 rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100384 rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200385
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100386 rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200387 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
388 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 0);
389 rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV, 1);
390 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
391 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
392 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
393 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
394 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
395 rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100396 rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200397
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100398 rt2800_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200399 rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_RATE, 0x4004);
400 rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_CTRL, 0);
401 rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_NAV, 1);
402 rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
403 rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
404 rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
405 rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
406 rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
407 rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100408 rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200409
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100410 rt2800_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200411 rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_RATE, 0x4084);
412 rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_CTRL, 0);
413 rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_NAV, 1);
414 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
415 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
416 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
417 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
418 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
419 rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100420 rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200421
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +0100422 if (rt2x00_intf_is_usb(rt2x00dev)) {
423 rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200424
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +0100425 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
426 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
427 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
428 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
429 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
430 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 3);
431 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 0);
432 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_BIG_ENDIAN, 0);
433 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_HDR_SCATTER, 0);
434 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_HDR_SEG_LEN, 0);
435 rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
436 }
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200437
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100438 rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f);
439 rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200440
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100441 rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200442 rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32);
443 rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES,
444 IEEE80211_MAX_RTS_THRESHOLD);
445 rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_FBK_EN, 0);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100446 rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200447
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100448 rt2800_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca);
449 rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200450
451 /*
452 * ASIC will keep garbage value after boot, clear encryption keys.
453 */
Ivo van Doorn1738c9e2009-08-17 18:53:57 +0200454 for (i = 0; i < 4; i++)
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100455 rt2800_register_write(rt2x00dev,
Ivo van Doorn1738c9e2009-08-17 18:53:57 +0200456 SHARED_KEY_MODE_ENTRY(i), 0);
457
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200458 for (i = 0; i < 256; i++) {
459 u32 wcid[2] = { 0xffffffff, 0x00ffffff };
Bartlomiej Zolnierkiewicz678b4ee2009-11-04 18:33:20 +0100460 rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200461 wcid, sizeof(wcid));
462
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100463 rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 1);
464 rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200465 }
466
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200467 /*
468 * Clear all beacons
469 * For the Beacon base registers we only need to clear
470 * the first byte since that byte contains the VALID and OWNER
471 * bits which (when set to 0) will invalidate the entire beacon.
472 */
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100473 rt2800_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
474 rt2800_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
475 rt2800_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
476 rt2800_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
477 rt2800_register_write(rt2x00dev, HW_BEACON_BASE4, 0);
478 rt2800_register_write(rt2x00dev, HW_BEACON_BASE5, 0);
479 rt2800_register_write(rt2x00dev, HW_BEACON_BASE6, 0);
480 rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200481
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +0100482 if (rt2x00_intf_is_usb(rt2x00dev)) {
483 rt2800_register_read(rt2x00dev, USB_CYC_CFG, &reg);
484 rt2x00_set_field32(&reg, USB_CYC_CFG_CLOCK_CYCLE, 30);
485 rt2800_register_write(rt2x00dev, USB_CYC_CFG, reg);
486 }
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200487
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100488 rt2800_register_read(rt2x00dev, HT_FBK_CFG0, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200489 rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS0FBK, 0);
490 rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS1FBK, 0);
491 rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS2FBK, 1);
492 rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS3FBK, 2);
493 rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS4FBK, 3);
494 rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS5FBK, 4);
495 rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS6FBK, 5);
496 rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS7FBK, 6);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100497 rt2800_register_write(rt2x00dev, HT_FBK_CFG0, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200498
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100499 rt2800_register_read(rt2x00dev, HT_FBK_CFG1, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200500 rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS8FBK, 8);
501 rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS9FBK, 8);
502 rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS10FBK, 9);
503 rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS11FBK, 10);
504 rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS12FBK, 11);
505 rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS13FBK, 12);
506 rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS14FBK, 13);
507 rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS15FBK, 14);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100508 rt2800_register_write(rt2x00dev, HT_FBK_CFG1, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200509
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100510 rt2800_register_read(rt2x00dev, LG_FBK_CFG0, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200511 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS0FBK, 8);
512 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS1FBK, 8);
Ivo van Doorncd80b682009-08-17 18:55:40 +0200513 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS2FBK, 9);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200514 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS3FBK, 10);
515 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS4FBK, 11);
516 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS5FBK, 12);
517 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS6FBK, 13);
518 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS7FBK, 14);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100519 rt2800_register_write(rt2x00dev, LG_FBK_CFG0, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200520
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100521 rt2800_register_read(rt2x00dev, LG_FBK_CFG1, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200522 rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS0FBK, 0);
523 rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS1FBK, 0);
524 rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS2FBK, 1);
525 rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS3FBK, 2);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100526 rt2800_register_write(rt2x00dev, LG_FBK_CFG1, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200527
528 /*
529 * We must clear the error counters.
530 * These registers are cleared on read,
531 * so we may pass a useless variable to store the value.
532 */
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100533 rt2800_register_read(rt2x00dev, RX_STA_CNT0, &reg);
534 rt2800_register_read(rt2x00dev, RX_STA_CNT1, &reg);
535 rt2800_register_read(rt2x00dev, RX_STA_CNT2, &reg);
536 rt2800_register_read(rt2x00dev, TX_STA_CNT0, &reg);
537 rt2800_register_read(rt2x00dev, TX_STA_CNT1, &reg);
538 rt2800_register_read(rt2x00dev, TX_STA_CNT2, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200539
540 return 0;
541}
542
543static int rt2800usb_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev)
544{
545 unsigned int i;
546 u32 reg;
547
548 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100549 rt2800_register_read(rt2x00dev, MAC_STATUS_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200550 if (!rt2x00_get_field32(reg, MAC_STATUS_CFG_BBP_RF_BUSY))
551 return 0;
552
553 udelay(REGISTER_BUSY_DELAY);
554 }
555
556 ERROR(rt2x00dev, "BBP/RF register access failed, aborting.\n");
557 return -EACCES;
558}
559
560static int rt2800usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
561{
562 unsigned int i;
563 u8 value;
564
Ivo van Doorn15e46922009-04-28 20:14:58 +0200565 /*
566 * BBP was enabled after firmware was loaded,
567 * but we need to reactivate it now.
568 */
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100569 rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
570 rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
Ivo van Doorn15e46922009-04-28 20:14:58 +0200571 msleep(1);
572
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200573 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100574 rt2800_bbp_read(rt2x00dev, 0, &value);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200575 if ((value != 0xff) && (value != 0x00))
576 return 0;
577 udelay(REGISTER_BUSY_DELAY);
578 }
579
580 ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
581 return -EACCES;
582}
583
584static int rt2800usb_init_bbp(struct rt2x00_dev *rt2x00dev)
585{
586 unsigned int i;
587 u16 eeprom;
588 u8 reg_id;
589 u8 value;
590
591 if (unlikely(rt2800usb_wait_bbp_rf_ready(rt2x00dev) ||
592 rt2800usb_wait_bbp_ready(rt2x00dev)))
593 return -EACCES;
594
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100595 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
596 rt2800_bbp_write(rt2x00dev, 66, 0x38);
597 rt2800_bbp_write(rt2x00dev, 69, 0x12);
598 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
599 rt2800_bbp_write(rt2x00dev, 73, 0x10);
600 rt2800_bbp_write(rt2x00dev, 81, 0x37);
601 rt2800_bbp_write(rt2x00dev, 82, 0x62);
602 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
603 rt2800_bbp_write(rt2x00dev, 84, 0x99);
604 rt2800_bbp_write(rt2x00dev, 86, 0x00);
605 rt2800_bbp_write(rt2x00dev, 91, 0x04);
606 rt2800_bbp_write(rt2x00dev, 92, 0x00);
607 rt2800_bbp_write(rt2x00dev, 103, 0x00);
608 rt2800_bbp_write(rt2x00dev, 105, 0x05);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200609
610 if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100611 rt2800_bbp_write(rt2x00dev, 69, 0x16);
612 rt2800_bbp_write(rt2x00dev, 73, 0x12);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200613 }
614
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +0100615 if (rt2x00_rev(&rt2x00dev->chip) > RT2860D_VERSION)
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100616 rt2800_bbp_write(rt2x00dev, 84, 0x19);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200617
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +0100618 if (rt2x00_intf_is_usb(rt2x00dev) &&
619 rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100620 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
621 rt2800_bbp_write(rt2x00dev, 84, 0x99);
622 rt2800_bbp_write(rt2x00dev, 105, 0x05);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200623 }
624
625 for (i = 0; i < EEPROM_BBP_SIZE; i++) {
626 rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
627
628 if (eeprom != 0xffff && eeprom != 0x0000) {
629 reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
630 value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE);
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100631 rt2800_bbp_write(rt2x00dev, reg_id, value);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200632 }
633 }
634
635 return 0;
636}
637
638static u8 rt2800usb_init_rx_filter(struct rt2x00_dev *rt2x00dev,
639 bool bw40, u8 rfcsr24, u8 filter_target)
640{
641 unsigned int i;
642 u8 bbp;
643 u8 rfcsr;
644 u8 passband;
645 u8 stopband;
646 u8 overtuned = 0;
647
Bartlomiej Zolnierkiewicze91fea92009-11-04 18:34:04 +0100648 rt2800_rfcsr_write(rt2x00dev, 24, rfcsr24);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200649
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100650 rt2800_bbp_read(rt2x00dev, 4, &bbp);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200651 rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * bw40);
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100652 rt2800_bbp_write(rt2x00dev, 4, bbp);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200653
Bartlomiej Zolnierkiewicze91fea92009-11-04 18:34:04 +0100654 rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200655 rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 1);
Bartlomiej Zolnierkiewicze91fea92009-11-04 18:34:04 +0100656 rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200657
658 /*
659 * Set power & frequency of passband test tone
660 */
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100661 rt2800_bbp_write(rt2x00dev, 24, 0);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200662
663 for (i = 0; i < 100; i++) {
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100664 rt2800_bbp_write(rt2x00dev, 25, 0x90);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200665 msleep(1);
666
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100667 rt2800_bbp_read(rt2x00dev, 55, &passband);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200668 if (passband)
669 break;
670 }
671
672 /*
673 * Set power & frequency of stopband test tone
674 */
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100675 rt2800_bbp_write(rt2x00dev, 24, 0x06);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200676
677 for (i = 0; i < 100; i++) {
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100678 rt2800_bbp_write(rt2x00dev, 25, 0x90);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200679 msleep(1);
680
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100681 rt2800_bbp_read(rt2x00dev, 55, &stopband);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200682
683 if ((passband - stopband) <= filter_target) {
684 rfcsr24++;
685 overtuned += ((passband - stopband) == filter_target);
686 } else
687 break;
688
Bartlomiej Zolnierkiewicze91fea92009-11-04 18:34:04 +0100689 rt2800_rfcsr_write(rt2x00dev, 24, rfcsr24);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200690 }
691
692 rfcsr24 -= !!overtuned;
693
Bartlomiej Zolnierkiewicze91fea92009-11-04 18:34:04 +0100694 rt2800_rfcsr_write(rt2x00dev, 24, rfcsr24);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200695 return rfcsr24;
696}
697
698static int rt2800usb_init_rfcsr(struct rt2x00_dev *rt2x00dev)
699{
700 u8 rfcsr;
701 u8 bbp;
702
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +0100703 if (rt2x00_intf_is_usb(rt2x00dev) &&
704 rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200705 return 0;
706
707 /*
708 * Init RF calibration.
709 */
Bartlomiej Zolnierkiewicze91fea92009-11-04 18:34:04 +0100710 rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200711 rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
Bartlomiej Zolnierkiewicze91fea92009-11-04 18:34:04 +0100712 rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200713 msleep(1);
714 rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
Bartlomiej Zolnierkiewicze91fea92009-11-04 18:34:04 +0100715 rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200716
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +0100717 if (rt2x00_intf_is_usb(rt2x00dev)) {
718 rt2800_rfcsr_write(rt2x00dev, 4, 0x40);
719 rt2800_rfcsr_write(rt2x00dev, 5, 0x03);
720 rt2800_rfcsr_write(rt2x00dev, 6, 0x02);
721 rt2800_rfcsr_write(rt2x00dev, 7, 0x70);
722 rt2800_rfcsr_write(rt2x00dev, 9, 0x0f);
723 rt2800_rfcsr_write(rt2x00dev, 10, 0x71);
724 rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
725 rt2800_rfcsr_write(rt2x00dev, 12, 0x7b);
726 rt2800_rfcsr_write(rt2x00dev, 14, 0x90);
727 rt2800_rfcsr_write(rt2x00dev, 15, 0x58);
728 rt2800_rfcsr_write(rt2x00dev, 16, 0xb3);
729 rt2800_rfcsr_write(rt2x00dev, 17, 0x92);
730 rt2800_rfcsr_write(rt2x00dev, 18, 0x2c);
731 rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
732 rt2800_rfcsr_write(rt2x00dev, 20, 0xba);
733 rt2800_rfcsr_write(rt2x00dev, 21, 0xdb);
734 rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
735 rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
736 rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
737 rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
738 }
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200739
740 /*
741 * Set RX Filter calibration for 20MHz and 40MHz
742 */
743 rt2x00dev->calibration[0] =
744 rt2800usb_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
745 rt2x00dev->calibration[1] =
746 rt2800usb_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
747
748 /*
749 * Set back to initial state
750 */
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100751 rt2800_bbp_write(rt2x00dev, 24, 0);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200752
Bartlomiej Zolnierkiewicze91fea92009-11-04 18:34:04 +0100753 rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200754 rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0);
Bartlomiej Zolnierkiewicze91fea92009-11-04 18:34:04 +0100755 rt2800_rfcsr_write(rt2x00dev, 22, rfcsr);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200756
757 /*
758 * set BBP back to BW20
759 */
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100760 rt2800_bbp_read(rt2x00dev, 4, &bbp);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200761 rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
Bartlomiej Zolnierkiewiczeff6ece2009-11-04 18:33:50 +0100762 rt2800_bbp_write(rt2x00dev, 4, bbp);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200763
764 return 0;
765}
766
767/*
768 * Device state switch handlers.
769 */
770static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
771 enum dev_state state)
772{
773 u32 reg;
774
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100775 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200776 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
777 (state == STATE_RADIO_RX_ON) ||
778 (state == STATE_RADIO_RX_ON_LINK));
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100779 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200780}
781
782static int rt2800usb_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
783{
784 unsigned int i;
785 u32 reg;
786
787 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100788 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200789 if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
790 !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
791 return 0;
792
793 msleep(1);
794 }
795
796 ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
797 return -EACCES;
798}
799
800static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
801{
802 u32 reg;
803 u16 word;
804
805 /*
806 * Initialize all registers.
807 */
808 if (unlikely(rt2800usb_wait_wpdma_ready(rt2x00dev) ||
809 rt2800usb_init_registers(rt2x00dev) ||
810 rt2800usb_init_bbp(rt2x00dev) ||
811 rt2800usb_init_rfcsr(rt2x00dev)))
812 return -EIO;
813
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100814 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200815 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100816 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200817
818 udelay(50);
819
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100820 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200821 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
822 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
823 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100824 rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200825
826
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100827 rt2800_register_read(rt2x00dev, USB_DMA_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200828 rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0);
829 /* Don't use bulk in aggregation when working with USB 1.1 */
830 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN,
831 (rt2x00dev->rx->usb_maxpacket == 512));
832 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128);
Ivo van Doorn15e46922009-04-28 20:14:58 +0200833 /*
834 * Total room for RX frames in kilobytes, PBF might still exceed
835 * this limit so reduce the number to prevent errors.
836 */
837 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT,
838 ((RX_ENTRIES * DATA_FRAME_SIZE) / 1024) - 3);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200839 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
840 rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100841 rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200842
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100843 rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200844 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
845 rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100846 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200847
848 /*
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200849 * Initialize LED control
850 */
851 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
Bartlomiej Zolnierkiewicz4f2c5322009-11-04 18:34:32 +0100852 rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200853 word & 0xff, (word >> 8) & 0xff);
854
855 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
Bartlomiej Zolnierkiewicz4f2c5322009-11-04 18:34:32 +0100856 rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200857 word & 0xff, (word >> 8) & 0xff);
858
859 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
Bartlomiej Zolnierkiewicz4f2c5322009-11-04 18:34:32 +0100860 rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200861 word & 0xff, (word >> 8) & 0xff);
862
863 return 0;
864}
865
866static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev)
867{
868 u32 reg;
869
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100870 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200871 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
872 rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100873 rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200874
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +0100875 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
876 rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0);
877 rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200878
879 /* Wait for DMA, ignore error */
880 rt2800usb_wait_wpdma_ready(rt2x00dev);
881
882 rt2x00usb_disable_radio(rt2x00dev);
883}
884
885static int rt2800usb_set_state(struct rt2x00_dev *rt2x00dev,
886 enum dev_state state)
887{
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200888 if (state == STATE_AWAKE)
Bartlomiej Zolnierkiewicz4f2c5322009-11-04 18:34:32 +0100889 rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200890 else
Bartlomiej Zolnierkiewicz4f2c5322009-11-04 18:34:32 +0100891 rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200892
893 return 0;
894}
895
896static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
897 enum dev_state state)
898{
899 int retval = 0;
900
901 switch (state) {
902 case STATE_RADIO_ON:
903 /*
904 * Before the radio can be enabled, the device first has
905 * to be woken up. After that it needs a bit of time
Luis Correia49513482009-07-17 21:39:19 +0200906 * to be fully awake and then the radio can be enabled.
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200907 */
908 rt2800usb_set_state(rt2x00dev, STATE_AWAKE);
909 msleep(1);
910 retval = rt2800usb_enable_radio(rt2x00dev);
911 break;
912 case STATE_RADIO_OFF:
913 /*
Luis Correia49513482009-07-17 21:39:19 +0200914 * After the radio has been disabled, the device should
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200915 * be put to sleep for powersaving.
916 */
917 rt2800usb_disable_radio(rt2x00dev);
918 rt2800usb_set_state(rt2x00dev, STATE_SLEEP);
919 break;
920 case STATE_RADIO_RX_ON:
921 case STATE_RADIO_RX_ON_LINK:
922 case STATE_RADIO_RX_OFF:
923 case STATE_RADIO_RX_OFF_LINK:
924 rt2800usb_toggle_rx(rt2x00dev, state);
925 break;
926 case STATE_RADIO_IRQ_ON:
927 case STATE_RADIO_IRQ_OFF:
928 /* No support, but no error either */
929 break;
930 case STATE_DEEP_SLEEP:
931 case STATE_SLEEP:
932 case STATE_STANDBY:
933 case STATE_AWAKE:
934 retval = rt2800usb_set_state(rt2x00dev, state);
935 break;
936 default:
937 retval = -ENOTSUPP;
938 break;
939 }
940
941 if (unlikely(retval))
942 ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
943 state, retval);
944
945 return retval;
946}
947
948/*
949 * TX descriptor initialization
950 */
951static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
952 struct sk_buff *skb,
953 struct txentry_desc *txdesc)
954{
955 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
956 __le32 *txi = skbdesc->desc;
957 __le32 *txwi = &txi[TXINFO_DESC_SIZE / sizeof(__le32)];
958 u32 word;
959
960 /*
961 * Initialize TX Info descriptor
962 */
963 rt2x00_desc_read(txwi, 0, &word);
964 rt2x00_set_field32(&word, TXWI_W0_FRAG,
965 test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
966 rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0);
967 rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0);
968 rt2x00_set_field32(&word, TXWI_W0_TS,
969 test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
970 rt2x00_set_field32(&word, TXWI_W0_AMPDU,
971 test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags));
972 rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density);
973 rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->ifs);
974 rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs);
975 rt2x00_set_field32(&word, TXWI_W0_BW,
976 test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags));
977 rt2x00_set_field32(&word, TXWI_W0_SHORT_GI,
978 test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags));
979 rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc);
980 rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode);
981 rt2x00_desc_write(txwi, 0, word);
982
983 rt2x00_desc_read(txwi, 1, &word);
984 rt2x00_set_field32(&word, TXWI_W1_ACK,
985 test_bit(ENTRY_TXD_ACK, &txdesc->flags));
986 rt2x00_set_field32(&word, TXWI_W1_NSEQ,
987 test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
988 rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
989 rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
990 test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
Benoit PAPILLAULT17616312009-10-15 21:17:09 +0200991 txdesc->key_idx : 0xff);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200992 rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
993 skb->len - txdesc->l2pad);
994 rt2x00_set_field32(&word, TXWI_W1_PACKETID,
Ivo van Doorn534aff02009-08-17 18:55:15 +0200995 skbdesc->entry->queue->qid + 1);
Ivo van Doornd53d9e62009-04-26 15:47:48 +0200996 rt2x00_desc_write(txwi, 1, word);
997
998 /*
999 * Always write 0 to IV/EIV fields, hardware will insert the IV
1000 * from the IVEIV register when TXINFO_W0_WIV is set to 0.
1001 * When TXINFO_W0_WIV is set to 1 it will use the IV data
1002 * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which
1003 * crypto entry in the registers should be used to encrypt the frame.
1004 */
1005 _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
1006 _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
1007
1008 /*
1009 * Initialize TX descriptor
1010 */
1011 rt2x00_desc_read(txi, 0, &word);
1012 rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
1013 skb->len + TXWI_DESC_SIZE);
1014 rt2x00_set_field32(&word, TXINFO_W0_WIV,
1015 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
1016 rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
1017 rt2x00_set_field32(&word, TXINFO_W0_SW_USE_LAST_ROUND, 0);
1018 rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_NEXT_VALID, 0);
1019 rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_BURST,
1020 test_bit(ENTRY_TXD_BURST, &txdesc->flags));
1021 rt2x00_desc_write(txi, 0, word);
1022}
1023
1024/*
1025 * TX data initialization
1026 */
1027static void rt2800usb_write_beacon(struct queue_entry *entry)
1028{
1029 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1030 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1031 unsigned int beacon_base;
1032 u32 reg;
1033
1034 /*
1035 * Add the descriptor in front of the skb.
1036 */
1037 skb_push(entry->skb, entry->queue->desc_size);
1038 memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
1039 skbdesc->desc = entry->skb->data;
1040
1041 /*
1042 * Disable beaconing while we are reloading the beacon data,
1043 * otherwise we might be sending out invalid data.
1044 */
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001045 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001046 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001047 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001048
1049 /*
1050 * Write entire beacon with descriptor to register.
1051 */
1052 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
1053 rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
1054 USB_VENDOR_REQUEST_OUT, beacon_base,
1055 entry->skb->data, entry->skb->len,
1056 REGISTER_TIMEOUT32(entry->skb->len));
1057
1058 /*
1059 * Clean up the beacon skb.
1060 */
1061 dev_kfree_skb(entry->skb);
1062 entry->skb = NULL;
1063}
1064
1065static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
1066{
1067 int length;
1068
1069 /*
1070 * The length _must_ include 4 bytes padding,
1071 * it should always be multiple of 4,
1072 * but it must _not_ be a multiple of the USB packet size.
1073 */
1074 length = roundup(entry->skb->len + 4, 4);
1075 length += (4 * !(length % entry->queue->usb_maxpacket));
1076
1077 return length;
1078}
1079
1080static void rt2800usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
1081 const enum data_queue_qid queue)
1082{
1083 u32 reg;
1084
1085 if (queue != QID_BEACON) {
1086 rt2x00usb_kick_tx_queue(rt2x00dev, queue);
1087 return;
1088 }
1089
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001090 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001091 if (!rt2x00_get_field32(reg, BCN_TIME_CFG_BEACON_GEN)) {
1092 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
1093 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
1094 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001095 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001096 }
1097}
1098
1099/*
1100 * RX control handlers
1101 */
1102static void rt2800usb_fill_rxdone(struct queue_entry *entry,
1103 struct rxdone_entry_desc *rxdesc)
1104{
1105 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1106 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1107 __le32 *rxd = (__le32 *)entry->skb->data;
1108 __le32 *rxwi;
1109 u32 rxd0;
1110 u32 rxwi0;
1111 u32 rxwi1;
1112 u32 rxwi2;
1113 u32 rxwi3;
1114
1115 /*
1116 * Copy descriptor to the skbdesc->desc buffer, making it safe from
1117 * moving of frame data in rt2x00usb.
1118 */
1119 memcpy(skbdesc->desc, rxd, skbdesc->desc_len);
1120 rxd = (__le32 *)skbdesc->desc;
Bartlomiej Zolnierkiewiczd42c8d82009-11-04 18:35:47 +01001121 rxwi = &rxd[RXINFO_DESC_SIZE / sizeof(__le32)];
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001122
1123 /*
1124 * It is now safe to read the descriptor on all architectures.
1125 */
1126 rt2x00_desc_read(rxd, 0, &rxd0);
1127 rt2x00_desc_read(rxwi, 0, &rxwi0);
1128 rt2x00_desc_read(rxwi, 1, &rxwi1);
1129 rt2x00_desc_read(rxwi, 2, &rxwi2);
1130 rt2x00_desc_read(rxwi, 3, &rxwi3);
1131
1132 if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR))
1133 rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
1134
1135 if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
1136 rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
1137 rxdesc->cipher_status =
1138 rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
1139 }
1140
1141 if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) {
1142 /*
1143 * Hardware has stripped IV/EIV data from 802.11 frame during
1144 * decryption. Unfortunately the descriptor doesn't contain
1145 * any fields with the EIV/IV data either, so they can't
1146 * be restored by rt2x00lib.
1147 */
1148 rxdesc->flags |= RX_FLAG_IV_STRIPPED;
1149
1150 if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS)
1151 rxdesc->flags |= RX_FLAG_DECRYPTED;
1152 else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC)
1153 rxdesc->flags |= RX_FLAG_MMIC_ERROR;
1154 }
1155
1156 if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS))
1157 rxdesc->dev_flags |= RXDONE_MY_BSS;
1158
Ivo van Doorn0fefe0f2009-08-17 18:54:50 +02001159 if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD)) {
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001160 rxdesc->dev_flags |= RXDONE_L2PAD;
Ivo van Doorn0fefe0f2009-08-17 18:54:50 +02001161 skbdesc->flags |= SKBDESC_L2_PADDED;
1162 }
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001163
1164 if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
1165 rxdesc->flags |= RX_FLAG_SHORT_GI;
1166
1167 if (rt2x00_get_field32(rxwi1, RXWI_W1_BW))
1168 rxdesc->flags |= RX_FLAG_40MHZ;
1169
1170 /*
1171 * Detect RX rate, always use MCS as signal type.
1172 */
1173 rxdesc->dev_flags |= RXDONE_SIGNAL_MCS;
1174 rxdesc->rate_mode = rt2x00_get_field32(rxwi1, RXWI_W1_PHYMODE);
1175 rxdesc->signal = rt2x00_get_field32(rxwi1, RXWI_W1_MCS);
1176
1177 /*
1178 * Mask of 0x8 bit to remove the short preamble flag.
1179 */
1180 if (rxdesc->rate_mode == RATE_MODE_CCK)
1181 rxdesc->signal &= ~0x8;
1182
1183 rxdesc->rssi =
1184 (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) +
1185 rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2;
1186
1187 rxdesc->noise =
1188 (rt2x00_get_field32(rxwi3, RXWI_W3_SNR0) +
1189 rt2x00_get_field32(rxwi3, RXWI_W3_SNR1)) / 2;
1190
1191 rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT);
1192
1193 /*
1194 * Remove RXWI descriptor from start of buffer.
1195 */
1196 skb_pull(entry->skb, skbdesc->desc_len);
1197 skb_trim(entry->skb, rxdesc->size);
1198}
1199
1200/*
1201 * Device probe functions.
1202 */
1203static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
1204{
1205 u16 word;
1206 u8 *mac;
1207 u8 default_lna_gain;
1208
1209 rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE);
1210
1211 /*
1212 * Start validation of the data that has been read.
1213 */
1214 mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
1215 if (!is_valid_ether_addr(mac)) {
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001216 random_ether_addr(mac);
Johannes Berge91d8332009-07-15 17:21:41 +02001217 EEPROM(rt2x00dev, "MAC: %pM\n", mac);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001218 }
1219
1220 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
1221 if (word == 0xffff) {
1222 rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
1223 rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1);
1224 rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820);
1225 rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
1226 EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
1227 } else if (rt2x00_rev(&rt2x00dev->chip) < RT2883_VERSION) {
1228 /*
1229 * There is a max of 2 RX streams for RT2870 series
1230 */
1231 if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2)
1232 rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
1233 rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
1234 }
1235
1236 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word);
1237 if (word == 0xffff) {
1238 rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0);
1239 rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0);
1240 rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0);
1241 rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0);
1242 rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
1243 rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0);
1244 rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0);
1245 rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0);
1246 rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0);
1247 rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0);
1248 rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word);
1249 EEPROM(rt2x00dev, "NIC: 0x%04x\n", word);
1250 }
1251
1252 rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word);
1253 if ((word & 0x00ff) == 0x00ff) {
1254 rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0);
1255 rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE,
1256 LED_MODE_TXRX_ACTIVITY);
1257 rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
1258 rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
1259 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555);
1260 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221);
1261 rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8);
1262 EEPROM(rt2x00dev, "Freq: 0x%04x\n", word);
1263 }
1264
1265 /*
1266 * During the LNA validation we are going to use
1267 * lna0 as correct value. Note that EEPROM_LNA
1268 * is never validated.
1269 */
1270 rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word);
1271 default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0);
1272
1273 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word);
1274 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10)
1275 rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0);
1276 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10)
1277 rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
1278 rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
1279
1280 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
1281 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
1282 rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
1283 if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
1284 rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
1285 rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
1286 default_lna_gain);
1287 rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
1288
1289 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
1290 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
1291 rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0);
1292 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10)
1293 rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0);
1294 rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word);
1295
1296 rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
1297 if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
1298 rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
1299 if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
1300 rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
1301 rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
1302 default_lna_gain);
1303 rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
1304
1305 return 0;
1306}
1307
1308static int rt2800usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
1309{
1310 u32 reg;
1311 u16 value;
1312 u16 eeprom;
1313
1314 /*
1315 * Read EEPROM word for configuration.
1316 */
1317 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
1318
1319 /*
1320 * Identify RF chipset.
1321 */
1322 value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001323 rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001324 rt2x00_set_chip(rt2x00dev, RT2870, value, reg);
1325
1326 /*
1327 * The check for rt2860 is not a typo, some rt2870 hardware
1328 * identifies itself as rt2860 in the CSR register.
1329 */
Ivo van Doorn358623c2009-05-05 19:46:08 +02001330 if (!rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28600000) &&
1331 !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28700000) &&
1332 !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28800000) &&
1333 !rt2x00_check_rev(&rt2x00dev->chip, 0xffff0000, 0x30700000)) {
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001334 ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
1335 return -ENODEV;
1336 }
1337
1338 if (!rt2x00_rf(&rt2x00dev->chip, RF2820) &&
1339 !rt2x00_rf(&rt2x00dev->chip, RF2850) &&
1340 !rt2x00_rf(&rt2x00dev->chip, RF2720) &&
1341 !rt2x00_rf(&rt2x00dev->chip, RF2750) &&
1342 !rt2x00_rf(&rt2x00dev->chip, RF3020) &&
1343 !rt2x00_rf(&rt2x00dev->chip, RF2020)) {
1344 ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
1345 return -ENODEV;
1346 }
1347
1348 /*
1349 * Identify default antenna configuration.
1350 */
1351 rt2x00dev->default_ant.tx =
1352 rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH);
1353 rt2x00dev->default_ant.rx =
1354 rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH);
1355
1356 /*
1357 * Read frequency offset and RF programming sequence.
1358 */
1359 rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
1360 rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
1361
1362 /*
1363 * Read external LNA informations.
1364 */
1365 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
1366
1367 if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A))
1368 __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
1369 if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
1370 __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
1371
1372 /*
1373 * Detect if this device has an hardware controlled radio.
1374 */
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001375 if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO))
1376 __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001377
1378 /*
1379 * Store led settings, for correct led behaviour.
1380 */
1381#ifdef CONFIG_RT2X00_LIB_LEDS
Bartlomiej Zolnierkiewiczf4450612009-11-04 18:36:40 +01001382 rt2800_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
1383 rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
1384 rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001385
1386 rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ,
1387 &rt2x00dev->led_mcu_reg);
1388#endif /* CONFIG_RT2X00_LIB_LEDS */
1389
1390 return 0;
1391}
1392
1393/*
1394 * RF value list for rt2870
1395 * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750)
1396 */
1397static const struct rf_channel rf_vals[] = {
1398 { 1, 0x18402ecc, 0x184c0786, 0x1816b455, 0x1800510b },
1399 { 2, 0x18402ecc, 0x184c0786, 0x18168a55, 0x1800519f },
1400 { 3, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800518b },
1401 { 4, 0x18402ecc, 0x184c078a, 0x18168a55, 0x1800519f },
1402 { 5, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800518b },
1403 { 6, 0x18402ecc, 0x184c078e, 0x18168a55, 0x1800519f },
1404 { 7, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800518b },
1405 { 8, 0x18402ecc, 0x184c0792, 0x18168a55, 0x1800519f },
1406 { 9, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800518b },
1407 { 10, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800519f },
1408 { 11, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800518b },
1409 { 12, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800519f },
1410 { 13, 0x18402ecc, 0x184c079e, 0x18168a55, 0x1800518b },
1411 { 14, 0x18402ecc, 0x184c07a2, 0x18168a55, 0x18005193 },
1412
1413 /* 802.11 UNI / HyperLan 2 */
1414 { 36, 0x18402ecc, 0x184c099a, 0x18158a55, 0x180ed1a3 },
1415 { 38, 0x18402ecc, 0x184c099e, 0x18158a55, 0x180ed193 },
1416 { 40, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed183 },
1417 { 44, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed1a3 },
1418 { 46, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed18b },
1419 { 48, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed19b },
1420 { 52, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed193 },
1421 { 54, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed1a3 },
1422 { 56, 0x18402ec8, 0x184c068e, 0x18158a55, 0x180ed18b },
1423 { 60, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed183 },
1424 { 62, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed193 },
1425 { 64, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed1a3 },
1426
1427 /* 802.11 HyperLan 2 */
1428 { 100, 0x18402ec8, 0x184c06b2, 0x18178a55, 0x180ed783 },
1429 { 102, 0x18402ec8, 0x184c06b2, 0x18578a55, 0x180ed793 },
1430 { 104, 0x18402ec8, 0x185c06b2, 0x18578a55, 0x180ed1a3 },
1431 { 108, 0x18402ecc, 0x185c0a32, 0x18578a55, 0x180ed193 },
1432 { 110, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed183 },
1433 { 112, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed19b },
1434 { 116, 0x18402ecc, 0x184c0a3a, 0x18178a55, 0x180ed1a3 },
1435 { 118, 0x18402ecc, 0x184c0a3e, 0x18178a55, 0x180ed193 },
1436 { 120, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed183 },
1437 { 124, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed193 },
1438 { 126, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed15b },
1439 { 128, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed1a3 },
1440 { 132, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed18b },
1441 { 134, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed193 },
1442 { 136, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed19b },
1443 { 140, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed183 },
1444
1445 /* 802.11 UNII */
1446 { 149, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed1a7 },
1447 { 151, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed187 },
1448 { 153, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed18f },
1449 { 157, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed19f },
1450 { 159, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed1a7 },
1451 { 161, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed187 },
1452 { 165, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed197 },
1453 { 167, 0x18402ec4, 0x184c03d2, 0x18179855, 0x1815531f },
1454 { 169, 0x18402ec4, 0x184c03d2, 0x18179855, 0x18155327 },
1455 { 171, 0x18402ec4, 0x184c03d6, 0x18179855, 0x18155307 },
1456 { 173, 0x18402ec4, 0x184c03d6, 0x18179855, 0x1815530f },
1457
1458 /* 802.11 Japan */
1459 { 184, 0x15002ccc, 0x1500491e, 0x1509be55, 0x150c0a0b },
1460 { 188, 0x15002ccc, 0x15004922, 0x1509be55, 0x150c0a13 },
1461 { 192, 0x15002ccc, 0x15004926, 0x1509be55, 0x150c0a1b },
1462 { 196, 0x15002ccc, 0x1500492a, 0x1509be55, 0x150c0a23 },
1463 { 208, 0x15002ccc, 0x1500493a, 0x1509be55, 0x150c0a13 },
1464 { 212, 0x15002ccc, 0x1500493e, 0x1509be55, 0x150c0a1b },
1465 { 216, 0x15002ccc, 0x15004982, 0x1509be55, 0x150c0a23 },
1466};
1467
1468/*
1469 * RF value list for rt3070
1470 * Supports: 2.4 GHz
1471 */
1472static const struct rf_channel rf_vals_3070[] = {
1473 {1, 241, 2, 2 },
1474 {2, 241, 2, 7 },
1475 {3, 242, 2, 2 },
1476 {4, 242, 2, 7 },
1477 {5, 243, 2, 2 },
1478 {6, 243, 2, 7 },
1479 {7, 244, 2, 2 },
1480 {8, 244, 2, 7 },
1481 {9, 245, 2, 2 },
1482 {10, 245, 2, 7 },
1483 {11, 246, 2, 2 },
1484 {12, 246, 2, 7 },
1485 {13, 247, 2, 2 },
1486 {14, 248, 2, 4 },
1487};
1488
1489static int rt2800usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1490{
1491 struct hw_mode_spec *spec = &rt2x00dev->spec;
1492 struct channel_info *info;
1493 char *tx_power1;
1494 char *tx_power2;
1495 unsigned int i;
1496 u16 eeprom;
1497
1498 /*
1499 * Initialize all hw fields.
1500 */
1501 rt2x00dev->hw->flags =
1502 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1503 IEEE80211_HW_SIGNAL_DBM |
1504 IEEE80211_HW_SUPPORTS_PS |
1505 IEEE80211_HW_PS_NULLFUNC_STACK;
1506 rt2x00dev->hw->extra_tx_headroom = TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
1507
1508 SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
1509 SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
1510 rt2x00_eeprom_addr(rt2x00dev,
1511 EEPROM_MAC_ADDR_0));
1512
1513 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
1514
1515 /*
1516 * Initialize HT information.
1517 */
1518 spec->ht.ht_supported = true;
1519 spec->ht.cap =
1520 IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
1521 IEEE80211_HT_CAP_GRN_FLD |
1522 IEEE80211_HT_CAP_SGI_20 |
1523 IEEE80211_HT_CAP_SGI_40 |
1524 IEEE80211_HT_CAP_TX_STBC |
1525 IEEE80211_HT_CAP_RX_STBC |
1526 IEEE80211_HT_CAP_PSMP_SUPPORT;
1527 spec->ht.ampdu_factor = 3;
1528 spec->ht.ampdu_density = 4;
1529 spec->ht.mcs.tx_params =
1530 IEEE80211_HT_MCS_TX_DEFINED |
1531 IEEE80211_HT_MCS_TX_RX_DIFF |
1532 ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
1533 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
1534
1535 switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
1536 case 3:
1537 spec->ht.mcs.rx_mask[2] = 0xff;
1538 case 2:
1539 spec->ht.mcs.rx_mask[1] = 0xff;
1540 case 1:
1541 spec->ht.mcs.rx_mask[0] = 0xff;
1542 spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */
1543 break;
1544 }
1545
1546 /*
1547 * Initialize hw_mode information.
1548 */
1549 spec->supported_bands = SUPPORT_BAND_2GHZ;
1550 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
1551
1552 if (rt2x00_rf(&rt2x00dev->chip, RF2820) ||
1553 rt2x00_rf(&rt2x00dev->chip, RF2720)) {
1554 spec->num_channels = 14;
1555 spec->channels = rf_vals;
1556 } else if (rt2x00_rf(&rt2x00dev->chip, RF2850) ||
1557 rt2x00_rf(&rt2x00dev->chip, RF2750)) {
1558 spec->supported_bands |= SUPPORT_BAND_5GHZ;
1559 spec->num_channels = ARRAY_SIZE(rf_vals);
1560 spec->channels = rf_vals;
1561 } else if (rt2x00_rf(&rt2x00dev->chip, RF3020) ||
1562 rt2x00_rf(&rt2x00dev->chip, RF2020)) {
1563 spec->num_channels = ARRAY_SIZE(rf_vals_3070);
1564 spec->channels = rf_vals_3070;
1565 }
1566
1567 /*
1568 * Create channel information array
1569 */
1570 info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
1571 if (!info)
1572 return -ENOMEM;
1573
1574 spec->channels_info = info;
1575
1576 tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
1577 tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
1578
1579 for (i = 0; i < 14; i++) {
1580 info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]);
1581 info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]);
1582 }
1583
1584 if (spec->num_channels > 14) {
1585 tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
1586 tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
1587
1588 for (i = 14; i < spec->num_channels; i++) {
1589 info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]);
1590 info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]);
1591 }
1592 }
1593
1594 return 0;
1595}
1596
Bartlomiej Zolnierkiewicz7a345d32009-11-04 18:34:53 +01001597static const struct rt2800_ops rt2800usb_rt2800_ops = {
1598 .register_read = rt2x00usb_register_read,
1599 .register_write = rt2x00usb_register_write,
1600 .register_write_lock = rt2x00usb_register_write_lock,
1601
1602 .register_multiread = rt2x00usb_register_multiread,
1603 .register_multiwrite = rt2x00usb_register_multiwrite,
1604
1605 .regbusy_read = rt2x00usb_regbusy_read,
1606};
1607
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001608static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
1609{
1610 int retval;
1611
Bartlomiej Zolnierkiewicz4d6f8b92009-11-04 18:36:17 +01001612 rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_USB);
1613
Bartlomiej Zolnierkiewicz7a345d32009-11-04 18:34:53 +01001614 rt2x00dev->priv = (void *)&rt2800usb_rt2800_ops;
1615
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001616 /*
1617 * Allocate eeprom data.
1618 */
1619 retval = rt2800usb_validate_eeprom(rt2x00dev);
1620 if (retval)
1621 return retval;
1622
1623 retval = rt2800usb_init_eeprom(rt2x00dev);
1624 if (retval)
1625 return retval;
1626
1627 /*
1628 * Initialize hw specifications.
1629 */
1630 retval = rt2800usb_probe_hw_mode(rt2x00dev);
1631 if (retval)
1632 return retval;
1633
1634 /*
Igor Perminov1afcfd542009-08-08 23:55:55 +02001635 * This device has multiple filters for control frames
1636 * and has a separate filter for PS Poll frames.
1637 */
1638 __set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
1639 __set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags);
1640
1641 /*
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001642 * This device requires firmware.
1643 */
1644 __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001645 __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
1646 if (!modparam_nohwcrypt)
1647 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
1648
1649 /*
1650 * Set the rssi offset.
1651 */
1652 rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
1653
1654 return 0;
1655}
1656
1657/*
1658 * IEEE80211 stack callback functions.
1659 */
1660static void rt2800usb_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx,
1661 u32 *iv32, u16 *iv16)
1662{
1663 struct rt2x00_dev *rt2x00dev = hw->priv;
1664 struct mac_iveiv_entry iveiv_entry;
1665 u32 offset;
1666
1667 offset = MAC_IVEIV_ENTRY(hw_key_idx);
Bartlomiej Zolnierkiewicz678b4ee2009-11-04 18:33:20 +01001668 rt2800_register_multiread(rt2x00dev, offset,
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001669 &iveiv_entry, sizeof(iveiv_entry));
1670
1671 memcpy(&iveiv_entry.iv[0], iv16, sizeof(iv16));
1672 memcpy(&iveiv_entry.iv[4], iv32, sizeof(iv32));
1673}
1674
1675static int rt2800usb_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1676{
1677 struct rt2x00_dev *rt2x00dev = hw->priv;
1678 u32 reg;
1679 bool enabled = (value < IEEE80211_MAX_RTS_THRESHOLD);
1680
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001681 rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001682 rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES, value);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001683 rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001684
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001685 rt2800_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001686 rt2x00_set_field32(&reg, CCK_PROT_CFG_RTS_TH_EN, enabled);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001687 rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001688
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001689 rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001690 rt2x00_set_field32(&reg, OFDM_PROT_CFG_RTS_TH_EN, enabled);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001691 rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001692
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001693 rt2800_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001694 rt2x00_set_field32(&reg, MM20_PROT_CFG_RTS_TH_EN, enabled);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001695 rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001696
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001697 rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001698 rt2x00_set_field32(&reg, MM40_PROT_CFG_RTS_TH_EN, enabled);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001699 rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001700
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001701 rt2800_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001702 rt2x00_set_field32(&reg, GF20_PROT_CFG_RTS_TH_EN, enabled);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001703 rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001704
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001705 rt2800_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001706 rt2x00_set_field32(&reg, GF40_PROT_CFG_RTS_TH_EN, enabled);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001707 rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001708
1709 return 0;
1710}
1711
1712static int rt2800usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
1713 const struct ieee80211_tx_queue_params *params)
1714{
1715 struct rt2x00_dev *rt2x00dev = hw->priv;
1716 struct data_queue *queue;
1717 struct rt2x00_field32 field;
1718 int retval;
1719 u32 reg;
1720 u32 offset;
1721
1722 /*
1723 * First pass the configuration through rt2x00lib, that will
1724 * update the queue settings and validate the input. After that
1725 * we are free to update the registers based on the value
1726 * in the queue parameter.
1727 */
1728 retval = rt2x00mac_conf_tx(hw, queue_idx, params);
1729 if (retval)
1730 return retval;
1731
1732 /*
1733 * We only need to perform additional register initialization
1734 * for WMM queues/
1735 */
1736 if (queue_idx >= 4)
1737 return 0;
1738
1739 queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
1740
1741 /* Update WMM TXOP register */
1742 offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2)));
1743 field.bit_offset = (queue_idx & 1) * 16;
1744 field.bit_mask = 0xffff << field.bit_offset;
1745
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001746 rt2800_register_read(rt2x00dev, offset, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001747 rt2x00_set_field32(&reg, field, queue->txop);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001748 rt2800_register_write(rt2x00dev, offset, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001749
1750 /* Update WMM registers */
1751 field.bit_offset = queue_idx * 4;
1752 field.bit_mask = 0xf << field.bit_offset;
1753
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001754 rt2800_register_read(rt2x00dev, WMM_AIFSN_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001755 rt2x00_set_field32(&reg, field, queue->aifs);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001756 rt2800_register_write(rt2x00dev, WMM_AIFSN_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001757
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001758 rt2800_register_read(rt2x00dev, WMM_CWMIN_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001759 rt2x00_set_field32(&reg, field, queue->cw_min);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001760 rt2800_register_write(rt2x00dev, WMM_CWMIN_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001761
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001762 rt2800_register_read(rt2x00dev, WMM_CWMAX_CFG, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001763 rt2x00_set_field32(&reg, field, queue->cw_max);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001764 rt2800_register_write(rt2x00dev, WMM_CWMAX_CFG, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001765
1766 /* Update EDCA registers */
1767 offset = EDCA_AC0_CFG + (sizeof(u32) * queue_idx);
1768
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001769 rt2800_register_read(rt2x00dev, offset, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001770 rt2x00_set_field32(&reg, EDCA_AC0_CFG_TX_OP, queue->txop);
1771 rt2x00_set_field32(&reg, EDCA_AC0_CFG_AIFSN, queue->aifs);
1772 rt2x00_set_field32(&reg, EDCA_AC0_CFG_CWMIN, queue->cw_min);
1773 rt2x00_set_field32(&reg, EDCA_AC0_CFG_CWMAX, queue->cw_max);
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001774 rt2800_register_write(rt2x00dev, offset, reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001775
1776 return 0;
1777}
1778
1779static u64 rt2800usb_get_tsf(struct ieee80211_hw *hw)
1780{
1781 struct rt2x00_dev *rt2x00dev = hw->priv;
1782 u64 tsf;
1783 u32 reg;
1784
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001785 rt2800_register_read(rt2x00dev, TSF_TIMER_DW1, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001786 tsf = (u64) rt2x00_get_field32(reg, TSF_TIMER_DW1_HIGH_WORD) << 32;
Bartlomiej Zolnierkiewiczabbb5052009-11-04 18:33:05 +01001787 rt2800_register_read(rt2x00dev, TSF_TIMER_DW0, &reg);
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001788 tsf |= rt2x00_get_field32(reg, TSF_TIMER_DW0_LOW_WORD);
1789
1790 return tsf;
1791}
1792
1793static const struct ieee80211_ops rt2800usb_mac80211_ops = {
1794 .tx = rt2x00mac_tx,
1795 .start = rt2x00mac_start,
1796 .stop = rt2x00mac_stop,
1797 .add_interface = rt2x00mac_add_interface,
1798 .remove_interface = rt2x00mac_remove_interface,
1799 .config = rt2x00mac_config,
1800 .configure_filter = rt2x00mac_configure_filter,
Stefan Steuerwald930c06f2009-07-10 20:42:55 +02001801 .set_tim = rt2x00mac_set_tim,
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001802 .set_key = rt2x00mac_set_key,
1803 .get_stats = rt2x00mac_get_stats,
1804 .get_tkip_seq = rt2800usb_get_tkip_seq,
1805 .set_rts_threshold = rt2800usb_set_rts_threshold,
1806 .bss_info_changed = rt2x00mac_bss_info_changed,
1807 .conf_tx = rt2800usb_conf_tx,
1808 .get_tx_stats = rt2x00mac_get_tx_stats,
1809 .get_tsf = rt2800usb_get_tsf,
Ivo van Doorne47a5cd2009-07-01 15:17:35 +02001810 .rfkill_poll = rt2x00mac_rfkill_poll,
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001811};
1812
1813static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
1814 .probe_hw = rt2800usb_probe_hw,
1815 .get_firmware_name = rt2800usb_get_firmware_name,
1816 .check_firmware = rt2800usb_check_firmware,
1817 .load_firmware = rt2800usb_load_firmware,
1818 .initialize = rt2x00usb_initialize,
1819 .uninitialize = rt2x00usb_uninitialize,
1820 .clear_entry = rt2x00usb_clear_entry,
1821 .set_device_state = rt2800usb_set_device_state,
Bartlomiej Zolnierkiewiczf4450612009-11-04 18:36:40 +01001822 .rfkill_poll = rt2800_rfkill_poll,
1823 .link_stats = rt2800_link_stats,
1824 .reset_tuner = rt2800_reset_tuner,
1825 .link_tuner = rt2800_link_tuner,
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001826 .write_tx_desc = rt2800usb_write_tx_desc,
1827 .write_tx_data = rt2x00usb_write_tx_data,
1828 .write_beacon = rt2800usb_write_beacon,
1829 .get_tx_data_len = rt2800usb_get_tx_data_len,
1830 .kick_tx_queue = rt2800usb_kick_tx_queue,
1831 .kill_tx_queue = rt2x00usb_kill_tx_queue,
1832 .fill_rxdone = rt2800usb_fill_rxdone,
Bartlomiej Zolnierkiewiczf4450612009-11-04 18:36:40 +01001833 .config_shared_key = rt2800_config_shared_key,
1834 .config_pairwise_key = rt2800_config_pairwise_key,
1835 .config_filter = rt2800_config_filter,
1836 .config_intf = rt2800_config_intf,
1837 .config_erp = rt2800_config_erp,
1838 .config_ant = rt2800_config_ant,
1839 .config = rt2800_config,
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001840};
1841
1842static const struct data_queue_desc rt2800usb_queue_rx = {
1843 .entry_num = RX_ENTRIES,
1844 .data_size = AGGREGATION_SIZE,
Bartlomiej Zolnierkiewiczd42c8d82009-11-04 18:35:47 +01001845 .desc_size = RXINFO_DESC_SIZE + RXWI_DESC_SIZE,
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001846 .priv_size = sizeof(struct queue_entry_priv_usb),
1847};
1848
1849static const struct data_queue_desc rt2800usb_queue_tx = {
1850 .entry_num = TX_ENTRIES,
1851 .data_size = AGGREGATION_SIZE,
1852 .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
1853 .priv_size = sizeof(struct queue_entry_priv_usb),
1854};
1855
1856static const struct data_queue_desc rt2800usb_queue_bcn = {
1857 .entry_num = 8 * BEACON_ENTRIES,
1858 .data_size = MGMT_FRAME_SIZE,
1859 .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
1860 .priv_size = sizeof(struct queue_entry_priv_usb),
1861};
1862
1863static const struct rt2x00_ops rt2800usb_ops = {
1864 .name = KBUILD_MODNAME,
1865 .max_sta_intf = 1,
1866 .max_ap_intf = 8,
1867 .eeprom_size = EEPROM_SIZE,
1868 .rf_size = RF_SIZE,
1869 .tx_queues = NUM_TX_QUEUES,
1870 .rx = &rt2800usb_queue_rx,
1871 .tx = &rt2800usb_queue_tx,
1872 .bcn = &rt2800usb_queue_bcn,
1873 .lib = &rt2800usb_rt2x00_ops,
1874 .hw = &rt2800usb_mac80211_ops,
1875#ifdef CONFIG_RT2X00_LIB_DEBUGFS
Bartlomiej Zolnierkiewiczf4450612009-11-04 18:36:40 +01001876 .debugfs = &rt2800_rt2x00debug,
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001877#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
1878};
1879
1880/*
1881 * rt2800usb module information.
1882 */
1883static struct usb_device_id rt2800usb_device_table[] = {
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001884 /* Abocom */
1885 { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
1886 { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
1887 { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
1888 { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
1889 { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
1890 { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
1891 /* AirTies */
1892 { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
1893 /* Amigo */
1894 { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
1895 { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
1896 /* Amit */
1897 { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
1898 /* ASUS */
1899 { USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) },
1900 { USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) },
1901 { USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) },
1902 { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) },
1903 { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) },
1904 /* AzureWave */
1905 { USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) },
1906 { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) },
1907 { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
1908 { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) },
1909 /* Belkin */
1910 { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) },
1911 { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) },
1912 { USB_DEVICE(0x050d, 0x815c), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doorn2c617b02009-05-19 07:26:04 +02001913 { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001914 /* Buffalo */
1915 { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) },
1916 { USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) },
1917 /* Conceptronic */
1918 { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) },
1919 { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) },
1920 { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) },
1921 { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
1922 { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
1923 { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
1924 { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) },
1925 { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) },
1926 { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) },
1927 { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) },
1928 /* Corega */
1929 { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) },
1930 { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
1931 { USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
1932 { USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
1933 { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
1934 /* D-Link */
1935 { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
1936 { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) },
1937 { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornce2ebc92009-05-22 21:33:21 +02001938 { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
1939 { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
1940 { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001941 { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
1942 { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
1943 /* Edimax */
1944 { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
1945 { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
1946 { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornce2ebc92009-05-22 21:33:21 +02001947 /* Encore */
1948 { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001949 /* EnGenius */
1950 { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
1951 { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
1952 { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
1953 { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
1954 { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
1955 { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) },
1956 /* Gemtek */
1957 { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
1958 /* Gigabyte */
1959 { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
1960 { USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) },
1961 { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
1962 /* Hawking */
1963 { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) },
1964 { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
1965 { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
1966 { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornce2ebc92009-05-22 21:33:21 +02001967 /* I-O DATA */
1968 { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001969 /* LevelOne */
1970 { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
1971 { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
1972 /* Linksys */
1973 { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
1974 { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doorne430d602009-04-27 23:58:31 +02001975 { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001976 /* Logitec */
1977 { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) },
1978 { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) },
1979 { USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) },
1980 /* Motorola */
1981 { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
1982 { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) },
1983 /* Ovislink */
1984 { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
1985 /* Pegatron */
1986 { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
1987 { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornce2ebc92009-05-22 21:33:21 +02001988 { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornd53d9e62009-04-26 15:47:48 +02001989 /* Philips */
1990 { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
1991 /* Planex */
1992 { USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) },
1993 { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) },
1994 { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
1995 /* Qcom */
1996 { USB_DEVICE(0x18e8, 0x6259), USB_DEVICE_DATA(&rt2800usb_ops) },
1997 /* Quanta */
1998 { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
1999 /* Ralink */
Ivo van Doornce2ebc92009-05-22 21:33:21 +02002000 { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornd53d9e62009-04-26 15:47:48 +02002001 { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
2002 { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
2003 { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
2004 { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
2005 { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
2006 { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
2007 { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
2008 { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
2009 /* Samsung */
2010 { USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) },
2011 /* Siemens */
2012 { USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) },
2013 /* Sitecom */
2014 { USB_DEVICE(0x0df6, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
2015 { USB_DEVICE(0x0df6, 0x002b), USB_DEVICE_DATA(&rt2800usb_ops) },
2016 { USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) },
2017 { USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) },
2018 { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) },
2019 { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) },
2020 { USB_DEVICE(0x0df6, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
2021 { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) },
2022 { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
2023 { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
2024 { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornce2ebc92009-05-22 21:33:21 +02002025 { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornd53d9e62009-04-26 15:47:48 +02002026 /* SMC */
2027 { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
2028 { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
2029 { USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) },
2030 { USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) },
2031 { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) },
2032 { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) },
2033 { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) },
2034 { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) },
2035 { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) },
2036 /* Sparklan */
2037 { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doorn3b91c362009-05-21 19:16:14 +02002038 /* Sweex */
2039 { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) },
2040 { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) },
2041 { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornd53d9e62009-04-26 15:47:48 +02002042 /* U-Media*/
2043 { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) },
2044 /* ZCOM */
2045 { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) },
2046 { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) },
2047 /* Zinwell */
2048 { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
2049 { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornce2ebc92009-05-22 21:33:21 +02002050 { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
2051 { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
Ivo van Doornd53d9e62009-04-26 15:47:48 +02002052 /* Zyxel */
2053 { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
2054 { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) },
2055 { 0, }
2056};
2057
2058MODULE_AUTHOR(DRV_PROJECT);
2059MODULE_VERSION(DRV_VERSION);
2060MODULE_DESCRIPTION("Ralink RT2800 USB Wireless LAN driver.");
2061MODULE_SUPPORTED_DEVICE("Ralink RT2870 USB chipset based cards");
2062MODULE_DEVICE_TABLE(usb, rt2800usb_device_table);
2063MODULE_FIRMWARE(FIRMWARE_RT2870);
2064MODULE_LICENSE("GPL");
2065
2066static struct usb_driver rt2800usb_driver = {
2067 .name = KBUILD_MODNAME,
2068 .id_table = rt2800usb_device_table,
2069 .probe = rt2x00usb_probe,
2070 .disconnect = rt2x00usb_disconnect,
2071 .suspend = rt2x00usb_suspend,
2072 .resume = rt2x00usb_resume,
2073};
2074
2075static int __init rt2800usb_init(void)
2076{
2077 return usb_register(&rt2800usb_driver);
2078}
2079
2080static void __exit rt2800usb_exit(void)
2081{
2082 usb_deregister(&rt2800usb_driver);
2083}
2084
2085module_init(rt2800usb_init);
2086module_exit(rt2800usb_exit);