diff options
author | Ivo van Doorn <IvDoorn@gmail.com> | 2007-09-25 20:57:13 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:51:39 -0400 |
commit | 95ea36275f3c9a1d3d04c217b4b576c657c4e70e (patch) | |
tree | 55477b946a46aa871a087857a1dc698d74fe79d2 /drivers/net/wireless/rt2x00/rt61pci.c | |
parent | b481de9ca074528fe8c429604e2777db8b89806a (diff) |
[RT2x00]: add driver for Ralink wireless hardware
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt61pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 2603 |
1 files changed, 2603 insertions, 0 deletions
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c new file mode 100644 index 000000000000..730bed5a1984 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -0,0 +1,2603 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt61pci | ||
23 | Abstract: rt61pci device specific routines. | ||
24 | Supported chipsets: RT2561, RT2561s, RT2661. | ||
25 | */ | ||
26 | |||
27 | /* | ||
28 | * Set enviroment defines for rt2x00.h | ||
29 | */ | ||
30 | #define DRV_NAME "rt61pci" | ||
31 | |||
32 | #include <linux/delay.h> | ||
33 | #include <linux/etherdevice.h> | ||
34 | #include <linux/init.h> | ||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/module.h> | ||
37 | #include <linux/pci.h> | ||
38 | #include <linux/eeprom_93cx6.h> | ||
39 | |||
40 | #include "rt2x00.h" | ||
41 | #include "rt2x00pci.h" | ||
42 | #include "rt61pci.h" | ||
43 | |||
44 | /* | ||
45 | * Register access. | ||
46 | * BBP and RF register require indirect register access, | ||
47 | * and use the CSR registers PHY_CSR3 and PHY_CSR4 to achieve this. | ||
48 | * These indirect registers work with busy bits, | ||
49 | * and we will try maximal REGISTER_BUSY_COUNT times to access | ||
50 | * the register while taking a REGISTER_BUSY_DELAY us delay | ||
51 | * between each attampt. When the busy bit is still set at that time, | ||
52 | * the access attempt is considered to have failed, | ||
53 | * and we will print an error. | ||
54 | */ | ||
55 | static u32 rt61pci_bbp_check(const struct rt2x00_dev *rt2x00dev) | ||
56 | { | ||
57 | u32 reg; | ||
58 | unsigned int i; | ||
59 | |||
60 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
61 | rt2x00pci_register_read(rt2x00dev, PHY_CSR3, ®); | ||
62 | if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY)) | ||
63 | break; | ||
64 | udelay(REGISTER_BUSY_DELAY); | ||
65 | } | ||
66 | |||
67 | return reg; | ||
68 | } | ||
69 | |||
70 | static void rt61pci_bbp_write(const struct rt2x00_dev *rt2x00dev, | ||
71 | const unsigned int word, const u8 value) | ||
72 | { | ||
73 | u32 reg; | ||
74 | |||
75 | /* | ||
76 | * Wait until the BBP becomes ready. | ||
77 | */ | ||
78 | reg = rt61pci_bbp_check(rt2x00dev); | ||
79 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | ||
80 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); | ||
81 | return; | ||
82 | } | ||
83 | |||
84 | /* | ||
85 | * Write the data into the BBP. | ||
86 | */ | ||
87 | reg = 0; | ||
88 | rt2x00_set_field32(®, PHY_CSR3_VALUE, value); | ||
89 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); | ||
90 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | ||
91 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); | ||
92 | |||
93 | rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); | ||
94 | } | ||
95 | |||
96 | static void rt61pci_bbp_read(const struct rt2x00_dev *rt2x00dev, | ||
97 | const unsigned int word, u8 *value) | ||
98 | { | ||
99 | u32 reg; | ||
100 | |||
101 | /* | ||
102 | * Wait until the BBP becomes ready. | ||
103 | */ | ||
104 | reg = rt61pci_bbp_check(rt2x00dev); | ||
105 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | ||
106 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | ||
107 | return; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Write the request into the BBP. | ||
112 | */ | ||
113 | reg = 0; | ||
114 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); | ||
115 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | ||
116 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); | ||
117 | |||
118 | rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); | ||
119 | |||
120 | /* | ||
121 | * Wait until the BBP becomes ready. | ||
122 | */ | ||
123 | reg = rt61pci_bbp_check(rt2x00dev); | ||
124 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | ||
125 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | ||
126 | *value = 0xff; | ||
127 | return; | ||
128 | } | ||
129 | |||
130 | *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); | ||
131 | } | ||
132 | |||
133 | static void rt61pci_rf_write(const struct rt2x00_dev *rt2x00dev, | ||
134 | const unsigned int word, const u32 value) | ||
135 | { | ||
136 | u32 reg; | ||
137 | unsigned int i; | ||
138 | |||
139 | if (!word) | ||
140 | return; | ||
141 | |||
142 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
143 | rt2x00pci_register_read(rt2x00dev, PHY_CSR4, ®); | ||
144 | if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY)) | ||
145 | goto rf_write; | ||
146 | udelay(REGISTER_BUSY_DELAY); | ||
147 | } | ||
148 | |||
149 | ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n"); | ||
150 | return; | ||
151 | |||
152 | rf_write: | ||
153 | reg = 0; | ||
154 | rt2x00_set_field32(®, PHY_CSR4_VALUE, value); | ||
155 | rt2x00_set_field32(®, PHY_CSR4_NUMBER_OF_BITS, 21); | ||
156 | rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); | ||
157 | rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); | ||
158 | |||
159 | rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg); | ||
160 | rt2x00_rf_write(rt2x00dev, word, value); | ||
161 | } | ||
162 | |||
163 | static void rt61pci_mcu_request(const struct rt2x00_dev *rt2x00dev, | ||
164 | const u8 command, const u8 token, | ||
165 | const u8 arg0, const u8 arg1) | ||
166 | { | ||
167 | u32 reg; | ||
168 | |||
169 | rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CSR, ®); | ||
170 | |||
171 | if (rt2x00_get_field32(reg, H2M_MAILBOX_CSR_OWNER)) { | ||
172 | ERROR(rt2x00dev, "mcu request error. " | ||
173 | "Request 0x%02x failed for token 0x%02x.\n", | ||
174 | command, token); | ||
175 | return; | ||
176 | } | ||
177 | |||
178 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_OWNER, 1); | ||
179 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); | ||
180 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0); | ||
181 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG1, arg1); | ||
182 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, reg); | ||
183 | |||
184 | rt2x00pci_register_read(rt2x00dev, HOST_CMD_CSR, ®); | ||
185 | rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); | ||
186 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); | ||
187 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); | ||
188 | } | ||
189 | |||
190 | static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | ||
191 | { | ||
192 | struct rt2x00_dev *rt2x00dev = eeprom->data; | ||
193 | u32 reg; | ||
194 | |||
195 | rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); | ||
196 | |||
197 | eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN); | ||
198 | eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT); | ||
199 | eeprom->reg_data_clock = | ||
200 | !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_CLOCK); | ||
201 | eeprom->reg_chip_select = | ||
202 | !!rt2x00_get_field32(reg, E2PROM_CSR_CHIP_SELECT); | ||
203 | } | ||
204 | |||
205 | static void rt61pci_eepromregister_write(struct eeprom_93cx6 *eeprom) | ||
206 | { | ||
207 | struct rt2x00_dev *rt2x00dev = eeprom->data; | ||
208 | u32 reg = 0; | ||
209 | |||
210 | rt2x00_set_field32(®, E2PROM_CSR_DATA_IN, !!eeprom->reg_data_in); | ||
211 | rt2x00_set_field32(®, E2PROM_CSR_DATA_OUT, !!eeprom->reg_data_out); | ||
212 | rt2x00_set_field32(®, E2PROM_CSR_DATA_CLOCK, | ||
213 | !!eeprom->reg_data_clock); | ||
214 | rt2x00_set_field32(®, E2PROM_CSR_CHIP_SELECT, | ||
215 | !!eeprom->reg_chip_select); | ||
216 | |||
217 | rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg); | ||
218 | } | ||
219 | |||
220 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
221 | #define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) ) | ||
222 | |||
223 | static void rt61pci_read_csr(const struct rt2x00_dev *rt2x00dev, | ||
224 | const unsigned int word, u32 *data) | ||
225 | { | ||
226 | rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data); | ||
227 | } | ||
228 | |||
229 | static void rt61pci_write_csr(const struct rt2x00_dev *rt2x00dev, | ||
230 | const unsigned int word, u32 data) | ||
231 | { | ||
232 | rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data); | ||
233 | } | ||
234 | |||
235 | static const struct rt2x00debug rt61pci_rt2x00debug = { | ||
236 | .owner = THIS_MODULE, | ||
237 | .csr = { | ||
238 | .read = rt61pci_read_csr, | ||
239 | .write = rt61pci_write_csr, | ||
240 | .word_size = sizeof(u32), | ||
241 | .word_count = CSR_REG_SIZE / sizeof(u32), | ||
242 | }, | ||
243 | .eeprom = { | ||
244 | .read = rt2x00_eeprom_read, | ||
245 | .write = rt2x00_eeprom_write, | ||
246 | .word_size = sizeof(u16), | ||
247 | .word_count = EEPROM_SIZE / sizeof(u16), | ||
248 | }, | ||
249 | .bbp = { | ||
250 | .read = rt61pci_bbp_read, | ||
251 | .write = rt61pci_bbp_write, | ||
252 | .word_size = sizeof(u8), | ||
253 | .word_count = BBP_SIZE / sizeof(u8), | ||
254 | }, | ||
255 | .rf = { | ||
256 | .read = rt2x00_rf_read, | ||
257 | .write = rt61pci_rf_write, | ||
258 | .word_size = sizeof(u32), | ||
259 | .word_count = RF_SIZE / sizeof(u32), | ||
260 | }, | ||
261 | }; | ||
262 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
263 | |||
264 | #ifdef CONFIG_RT61PCI_RFKILL | ||
265 | static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | ||
266 | { | ||
267 | u32 reg; | ||
268 | |||
269 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | ||
270 | return rt2x00_get_field32(reg, MAC_CSR13_BIT5);; | ||
271 | } | ||
272 | #endif /* CONFIG_RT2400PCI_RFKILL */ | ||
273 | |||
274 | /* | ||
275 | * Configuration handlers. | ||
276 | */ | ||
277 | static void rt61pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *addr) | ||
278 | { | ||
279 | __le32 reg[2]; | ||
280 | u32 tmp; | ||
281 | |||
282 | memset(®, 0, sizeof(reg)); | ||
283 | memcpy(®, addr, ETH_ALEN); | ||
284 | |||
285 | tmp = le32_to_cpu(reg[1]); | ||
286 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | ||
287 | reg[1] = cpu_to_le32(tmp); | ||
288 | |||
289 | /* | ||
290 | * The MAC address is passed to us as an array of bytes, | ||
291 | * that array is little endian, so no need for byte ordering. | ||
292 | */ | ||
293 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, ®, sizeof(reg)); | ||
294 | } | ||
295 | |||
296 | static void rt61pci_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) | ||
297 | { | ||
298 | __le32 reg[2]; | ||
299 | u32 tmp; | ||
300 | |||
301 | memset(®, 0, sizeof(reg)); | ||
302 | memcpy(®, bssid, ETH_ALEN); | ||
303 | |||
304 | tmp = le32_to_cpu(reg[1]); | ||
305 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | ||
306 | reg[1] = cpu_to_le32(tmp); | ||
307 | |||
308 | /* | ||
309 | * The BSSID is passed to us as an array of bytes, | ||
310 | * that array is little endian, so no need for byte ordering. | ||
311 | */ | ||
312 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, ®, sizeof(reg)); | ||
313 | } | ||
314 | |||
315 | static void rt61pci_config_packet_filter(struct rt2x00_dev *rt2x00dev, | ||
316 | const unsigned int filter) | ||
317 | { | ||
318 | int promisc = !!(filter & IFF_PROMISC); | ||
319 | int multicast = !!(filter & IFF_MULTICAST); | ||
320 | int broadcast = !!(filter & IFF_BROADCAST); | ||
321 | u32 reg; | ||
322 | |||
323 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
324 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, !promisc); | ||
325 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, !multicast); | ||
326 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BORADCAST, !broadcast); | ||
327 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
328 | } | ||
329 | |||
330 | static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type) | ||
331 | { | ||
332 | u32 reg; | ||
333 | |||
334 | /* | ||
335 | * Clear current synchronisation setup. | ||
336 | * For the Beacon base registers we only need to clear | ||
337 | * the first byte since that byte contains the VALID and OWNER | ||
338 | * bits which (when set to 0) will invalidate the entire beacon. | ||
339 | */ | ||
340 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
341 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
342 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
343 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
344 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
345 | |||
346 | /* | ||
347 | * Apply hardware packet filter. | ||
348 | */ | ||
349 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
350 | |||
351 | if (!is_monitor_present(&rt2x00dev->interface) && | ||
352 | (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_STA)) | ||
353 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, 1); | ||
354 | else | ||
355 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, 0); | ||
356 | |||
357 | /* | ||
358 | * If there is a non-monitor interface present | ||
359 | * the packet should be strict (even if a monitor interface is present!). | ||
360 | * When there is only 1 interface present which is in monitor mode | ||
361 | * we should start accepting _all_ frames. | ||
362 | */ | ||
363 | if (is_interface_present(&rt2x00dev->interface)) { | ||
364 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, 1); | ||
365 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, 1); | ||
366 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, 1); | ||
367 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | ||
368 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1); | ||
369 | } else if (is_monitor_present(&rt2x00dev->interface)) { | ||
370 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, 0); | ||
371 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, 0); | ||
372 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, 0); | ||
373 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 0); | ||
374 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 0); | ||
375 | } | ||
376 | |||
377 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
378 | |||
379 | /* | ||
380 | * Enable synchronisation. | ||
381 | */ | ||
382 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
383 | if (is_interface_present(&rt2x00dev->interface)) { | ||
384 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
385 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
386 | } | ||
387 | |||
388 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
389 | if (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_AP) | ||
390 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 2); | ||
391 | else if (type == IEEE80211_IF_TYPE_STA) | ||
392 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 1); | ||
393 | else if (is_monitor_present(&rt2x00dev->interface) && | ||
394 | !is_interface_present(&rt2x00dev->interface)) | ||
395 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 0); | ||
396 | |||
397 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
398 | } | ||
399 | |||
400 | static void rt61pci_config_rate(struct rt2x00_dev *rt2x00dev, const int rate) | ||
401 | { | ||
402 | struct ieee80211_conf *conf = &rt2x00dev->hw->conf; | ||
403 | u32 reg; | ||
404 | u32 value; | ||
405 | u32 preamble; | ||
406 | |||
407 | if (DEVICE_GET_RATE_FIELD(rate, PREAMBLE)) | ||
408 | preamble = SHORT_PREAMBLE; | ||
409 | else | ||
410 | preamble = PREAMBLE; | ||
411 | |||
412 | /* | ||
413 | * Extract the allowed ratemask from the device specific rate value, | ||
414 | * We need to set TXRX_CSR5 to the basic rate mask so we need to mask | ||
415 | * off the non-basic rates. | ||
416 | */ | ||
417 | reg = DEVICE_GET_RATE_FIELD(rate, RATEMASK) & DEV_BASIC_RATEMASK; | ||
418 | |||
419 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, reg); | ||
420 | |||
421 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
422 | value = ((conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) ? | ||
423 | SHORT_DIFS : DIFS) + | ||
424 | PLCP + preamble + get_duration(ACK_SIZE, 10); | ||
425 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, value); | ||
426 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
427 | |||
428 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); | ||
429 | if (preamble == SHORT_PREAMBLE) | ||
430 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, 1); | ||
431 | else | ||
432 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, 0); | ||
433 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | ||
434 | } | ||
435 | |||
436 | static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, | ||
437 | const int phymode) | ||
438 | { | ||
439 | struct ieee80211_hw_mode *mode; | ||
440 | struct ieee80211_rate *rate; | ||
441 | |||
442 | if (phymode == MODE_IEEE80211A) | ||
443 | rt2x00dev->curr_hwmode = HWMODE_A; | ||
444 | else if (phymode == MODE_IEEE80211B) | ||
445 | rt2x00dev->curr_hwmode = HWMODE_B; | ||
446 | else | ||
447 | rt2x00dev->curr_hwmode = HWMODE_G; | ||
448 | |||
449 | mode = &rt2x00dev->hwmodes[rt2x00dev->curr_hwmode]; | ||
450 | rate = &mode->rates[mode->num_rates - 1]; | ||
451 | |||
452 | rt61pci_config_rate(rt2x00dev, rate->val2); | ||
453 | } | ||
454 | |||
455 | static void rt61pci_config_lock_channel(struct rt2x00_dev *rt2x00dev, | ||
456 | struct rf_channel *rf, | ||
457 | const int txpower) | ||
458 | { | ||
459 | u8 r3; | ||
460 | u8 r94; | ||
461 | u8 smart; | ||
462 | |||
463 | rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower)); | ||
464 | rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset); | ||
465 | |||
466 | smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) || | ||
467 | rt2x00_rf(&rt2x00dev->chip, RF2527)); | ||
468 | |||
469 | rt61pci_bbp_read(rt2x00dev, 3, &r3); | ||
470 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart); | ||
471 | rt61pci_bbp_write(rt2x00dev, 3, r3); | ||
472 | |||
473 | r94 = 6; | ||
474 | if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94)) | ||
475 | r94 += txpower - MAX_TXPOWER; | ||
476 | else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94)) | ||
477 | r94 += txpower; | ||
478 | rt61pci_bbp_write(rt2x00dev, 94, r94); | ||
479 | |||
480 | rt61pci_rf_write(rt2x00dev, 1, rf->rf1); | ||
481 | rt61pci_rf_write(rt2x00dev, 2, rf->rf2); | ||
482 | rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004); | ||
483 | rt61pci_rf_write(rt2x00dev, 4, rf->rf4); | ||
484 | |||
485 | udelay(200); | ||
486 | |||
487 | rt61pci_rf_write(rt2x00dev, 1, rf->rf1); | ||
488 | rt61pci_rf_write(rt2x00dev, 2, rf->rf2); | ||
489 | rt61pci_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004); | ||
490 | rt61pci_rf_write(rt2x00dev, 4, rf->rf4); | ||
491 | |||
492 | udelay(200); | ||
493 | |||
494 | rt61pci_rf_write(rt2x00dev, 1, rf->rf1); | ||
495 | rt61pci_rf_write(rt2x00dev, 2, rf->rf2); | ||
496 | rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004); | ||
497 | rt61pci_rf_write(rt2x00dev, 4, rf->rf4); | ||
498 | |||
499 | msleep(1); | ||
500 | } | ||
501 | |||
502 | static void rt61pci_config_channel(struct rt2x00_dev *rt2x00dev, | ||
503 | const int index, const int channel, | ||
504 | const int txpower) | ||
505 | { | ||
506 | struct rf_channel rf; | ||
507 | |||
508 | /* | ||
509 | * Fill rf_reg structure. | ||
510 | */ | ||
511 | memcpy(&rf, &rt2x00dev->spec.channels[index], sizeof(rf)); | ||
512 | |||
513 | rt61pci_config_lock_channel(rt2x00dev, &rf, txpower); | ||
514 | } | ||
515 | |||
516 | static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev, | ||
517 | const int txpower) | ||
518 | { | ||
519 | struct rf_channel rf; | ||
520 | |||
521 | rt2x00_rf_read(rt2x00dev, 1, &rf.rf1); | ||
522 | rt2x00_rf_read(rt2x00dev, 2, &rf.rf2); | ||
523 | rt2x00_rf_read(rt2x00dev, 3, &rf.rf3); | ||
524 | rt2x00_rf_read(rt2x00dev, 4, &rf.rf4); | ||
525 | |||
526 | rt61pci_config_lock_channel(rt2x00dev, &rf, txpower); | ||
527 | } | ||
528 | |||
529 | static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | ||
530 | const int antenna_tx, | ||
531 | const int antenna_rx) | ||
532 | { | ||
533 | u8 r3; | ||
534 | u8 r4; | ||
535 | u8 r77; | ||
536 | |||
537 | rt61pci_bbp_read(rt2x00dev, 3, &r3); | ||
538 | rt61pci_bbp_read(rt2x00dev, 4, &r4); | ||
539 | rt61pci_bbp_read(rt2x00dev, 77, &r77); | ||
540 | |||
541 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, | ||
542 | !rt2x00_rf(&rt2x00dev->chip, RF5225)); | ||
543 | |||
544 | switch (antenna_rx) { | ||
545 | case ANTENNA_SW_DIVERSITY: | ||
546 | case ANTENNA_HW_DIVERSITY: | ||
547 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | ||
548 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | ||
549 | !!(rt2x00dev->curr_hwmode != HWMODE_A)); | ||
550 | break; | ||
551 | case ANTENNA_A: | ||
552 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
553 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | ||
554 | |||
555 | if (rt2x00dev->curr_hwmode == HWMODE_A) | ||
556 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); | ||
557 | else | ||
558 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
559 | break; | ||
560 | case ANTENNA_B: | ||
561 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
562 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | ||
563 | |||
564 | if (rt2x00dev->curr_hwmode == HWMODE_A) | ||
565 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
566 | else | ||
567 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); | ||
568 | break; | ||
569 | } | ||
570 | |||
571 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
572 | rt61pci_bbp_write(rt2x00dev, 3, r3); | ||
573 | rt61pci_bbp_write(rt2x00dev, 4, r4); | ||
574 | } | ||
575 | |||
576 | static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev, | ||
577 | const int antenna_tx, | ||
578 | const int antenna_rx) | ||
579 | { | ||
580 | u8 r3; | ||
581 | u8 r4; | ||
582 | u8 r77; | ||
583 | |||
584 | rt61pci_bbp_read(rt2x00dev, 3, &r3); | ||
585 | rt61pci_bbp_read(rt2x00dev, 4, &r4); | ||
586 | rt61pci_bbp_read(rt2x00dev, 77, &r77); | ||
587 | |||
588 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, | ||
589 | !rt2x00_rf(&rt2x00dev->chip, RF2527)); | ||
590 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | ||
591 | !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); | ||
592 | |||
593 | switch (antenna_rx) { | ||
594 | case ANTENNA_SW_DIVERSITY: | ||
595 | case ANTENNA_HW_DIVERSITY: | ||
596 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | ||
597 | break; | ||
598 | case ANTENNA_A: | ||
599 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
600 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
601 | break; | ||
602 | case ANTENNA_B: | ||
603 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
604 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); | ||
605 | break; | ||
606 | } | ||
607 | |||
608 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
609 | rt61pci_bbp_write(rt2x00dev, 3, r3); | ||
610 | rt61pci_bbp_write(rt2x00dev, 4, r4); | ||
611 | } | ||
612 | |||
613 | static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev, | ||
614 | const int p1, const int p2) | ||
615 | { | ||
616 | u32 reg; | ||
617 | |||
618 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | ||
619 | |||
620 | if (p1 != 0xff) { | ||
621 | rt2x00_set_field32(®, MAC_CSR13_BIT4, !!p1); | ||
622 | rt2x00_set_field32(®, MAC_CSR13_BIT12, 0); | ||
623 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); | ||
624 | } | ||
625 | if (p2 != 0xff) { | ||
626 | rt2x00_set_field32(®, MAC_CSR13_BIT3, !p2); | ||
627 | rt2x00_set_field32(®, MAC_CSR13_BIT11, 0); | ||
628 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); | ||
629 | } | ||
630 | } | ||
631 | |||
632 | static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, | ||
633 | const int antenna_tx, | ||
634 | const int antenna_rx) | ||
635 | { | ||
636 | u16 eeprom; | ||
637 | u8 r3; | ||
638 | u8 r4; | ||
639 | u8 r77; | ||
640 | |||
641 | rt61pci_bbp_read(rt2x00dev, 3, &r3); | ||
642 | rt61pci_bbp_read(rt2x00dev, 4, &r4); | ||
643 | rt61pci_bbp_read(rt2x00dev, 77, &r77); | ||
644 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | ||
645 | |||
646 | rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0); | ||
647 | |||
648 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) && | ||
649 | rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) { | ||
650 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | ||
651 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 1); | ||
652 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1); | ||
653 | } else if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY)) { | ||
654 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED) >= 2) { | ||
655 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
656 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
657 | } | ||
658 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
659 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); | ||
660 | } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) && | ||
661 | rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) { | ||
662 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); | ||
663 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | ||
664 | |||
665 | switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) { | ||
666 | case 0: | ||
667 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1); | ||
668 | break; | ||
669 | case 1: | ||
670 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0); | ||
671 | break; | ||
672 | case 2: | ||
673 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); | ||
674 | break; | ||
675 | case 3: | ||
676 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); | ||
677 | break; | ||
678 | } | ||
679 | } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) && | ||
680 | !rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) { | ||
681 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); | ||
682 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | ||
683 | |||
684 | switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) { | ||
685 | case 0: | ||
686 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); | ||
687 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
688 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1); | ||
689 | break; | ||
690 | case 1: | ||
691 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); | ||
692 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
693 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0); | ||
694 | break; | ||
695 | case 2: | ||
696 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
697 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
698 | rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); | ||
699 | break; | ||
700 | case 3: | ||
701 | rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); | ||
702 | rt61pci_bbp_write(rt2x00dev, 77, r77); | ||
703 | rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); | ||
704 | break; | ||
705 | } | ||
706 | } | ||
707 | |||
708 | rt61pci_bbp_write(rt2x00dev, 3, r3); | ||
709 | rt61pci_bbp_write(rt2x00dev, 4, r4); | ||
710 | } | ||
711 | |||
712 | struct antenna_sel { | ||
713 | u8 word; | ||
714 | /* | ||
715 | * value[0] -> non-LNA | ||
716 | * value[1] -> LNA | ||
717 | */ | ||
718 | u8 value[2]; | ||
719 | }; | ||
720 | |||
721 | static const struct antenna_sel antenna_sel_a[] = { | ||
722 | { 96, { 0x58, 0x78 } }, | ||
723 | { 104, { 0x38, 0x48 } }, | ||
724 | { 75, { 0xfe, 0x80 } }, | ||
725 | { 86, { 0xfe, 0x80 } }, | ||
726 | { 88, { 0xfe, 0x80 } }, | ||
727 | { 35, { 0x60, 0x60 } }, | ||
728 | { 97, { 0x58, 0x58 } }, | ||
729 | { 98, { 0x58, 0x58 } }, | ||
730 | }; | ||
731 | |||
732 | static const struct antenna_sel antenna_sel_bg[] = { | ||
733 | { 96, { 0x48, 0x68 } }, | ||
734 | { 104, { 0x2c, 0x3c } }, | ||
735 | { 75, { 0xfe, 0x80 } }, | ||
736 | { 86, { 0xfe, 0x80 } }, | ||
737 | { 88, { 0xfe, 0x80 } }, | ||
738 | { 35, { 0x50, 0x50 } }, | ||
739 | { 97, { 0x48, 0x48 } }, | ||
740 | { 98, { 0x48, 0x48 } }, | ||
741 | }; | ||
742 | |||
743 | static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, | ||
744 | const int antenna_tx, const int antenna_rx) | ||
745 | { | ||
746 | const struct antenna_sel *sel; | ||
747 | unsigned int lna; | ||
748 | unsigned int i; | ||
749 | u32 reg; | ||
750 | |||
751 | rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); | ||
752 | |||
753 | if (rt2x00dev->curr_hwmode == HWMODE_A) { | ||
754 | sel = antenna_sel_a; | ||
755 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | ||
756 | |||
757 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 0); | ||
758 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 1); | ||
759 | } else { | ||
760 | sel = antenna_sel_bg; | ||
761 | lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | ||
762 | |||
763 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 1); | ||
764 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 0); | ||
765 | } | ||
766 | |||
767 | for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) | ||
768 | rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]); | ||
769 | |||
770 | rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); | ||
771 | |||
772 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | ||
773 | rt2x00_rf(&rt2x00dev->chip, RF5325)) | ||
774 | rt61pci_config_antenna_5x(rt2x00dev, antenna_tx, antenna_rx); | ||
775 | else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) | ||
776 | rt61pci_config_antenna_2x(rt2x00dev, antenna_tx, antenna_rx); | ||
777 | else if (rt2x00_rf(&rt2x00dev->chip, RF2529)) { | ||
778 | if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) | ||
779 | rt61pci_config_antenna_2x(rt2x00dev, antenna_tx, | ||
780 | antenna_rx); | ||
781 | else | ||
782 | rt61pci_config_antenna_2529(rt2x00dev, antenna_tx, | ||
783 | antenna_rx); | ||
784 | } | ||
785 | } | ||
786 | |||
787 | static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev, | ||
788 | const int short_slot_time, | ||
789 | const int beacon_int) | ||
790 | { | ||
791 | u32 reg; | ||
792 | |||
793 | rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); | ||
794 | rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, | ||
795 | short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME); | ||
796 | rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); | ||
797 | |||
798 | rt2x00pci_register_read(rt2x00dev, MAC_CSR8, ®); | ||
799 | rt2x00_set_field32(®, MAC_CSR8_SIFS, SIFS); | ||
800 | rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); | ||
801 | rt2x00_set_field32(®, MAC_CSR8_EIFS, EIFS); | ||
802 | rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg); | ||
803 | |||
804 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
805 | rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); | ||
806 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
807 | |||
808 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); | ||
809 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); | ||
810 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | ||
811 | |||
812 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
813 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, beacon_int * 16); | ||
814 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
815 | } | ||
816 | |||
817 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | ||
818 | const unsigned int flags, | ||
819 | struct ieee80211_conf *conf) | ||
820 | { | ||
821 | int short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME; | ||
822 | |||
823 | if (flags & CONFIG_UPDATE_PHYMODE) | ||
824 | rt61pci_config_phymode(rt2x00dev, conf->phymode); | ||
825 | if (flags & CONFIG_UPDATE_CHANNEL) | ||
826 | rt61pci_config_channel(rt2x00dev, conf->channel_val, | ||
827 | conf->channel, conf->power_level); | ||
828 | if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL)) | ||
829 | rt61pci_config_txpower(rt2x00dev, conf->power_level); | ||
830 | if (flags & CONFIG_UPDATE_ANTENNA) | ||
831 | rt61pci_config_antenna(rt2x00dev, conf->antenna_sel_tx, | ||
832 | conf->antenna_sel_rx); | ||
833 | if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) | ||
834 | rt61pci_config_duration(rt2x00dev, short_slot_time, | ||
835 | conf->beacon_int); | ||
836 | } | ||
837 | |||
838 | /* | ||
839 | * LED functions. | ||
840 | */ | ||
841 | static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
842 | { | ||
843 | u32 reg; | ||
844 | u16 led_reg; | ||
845 | u8 arg0; | ||
846 | u8 arg1; | ||
847 | |||
848 | rt2x00pci_register_read(rt2x00dev, MAC_CSR14, ®); | ||
849 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
850 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
851 | rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg); | ||
852 | |||
853 | led_reg = rt2x00dev->led_reg; | ||
854 | rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 1); | ||
855 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) | ||
856 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 1); | ||
857 | else | ||
858 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 1); | ||
859 | |||
860 | arg0 = led_reg & 0xff; | ||
861 | arg1 = (led_reg >> 8) & 0xff; | ||
862 | |||
863 | rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1); | ||
864 | } | ||
865 | |||
866 | static void rt61pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
867 | { | ||
868 | u16 led_reg; | ||
869 | u8 arg0; | ||
870 | u8 arg1; | ||
871 | |||
872 | led_reg = rt2x00dev->led_reg; | ||
873 | rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 0); | ||
874 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 0); | ||
875 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 0); | ||
876 | |||
877 | arg0 = led_reg & 0xff; | ||
878 | arg1 = (led_reg >> 8) & 0xff; | ||
879 | |||
880 | rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1); | ||
881 | } | ||
882 | |||
883 | static void rt61pci_activity_led(struct rt2x00_dev *rt2x00dev, int rssi) | ||
884 | { | ||
885 | u8 led; | ||
886 | |||
887 | if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH) | ||
888 | return; | ||
889 | |||
890 | /* | ||
891 | * Led handling requires a positive value for the rssi, | ||
892 | * to do that correctly we need to add the correction. | ||
893 | */ | ||
894 | rssi += rt2x00dev->rssi_offset; | ||
895 | |||
896 | if (rssi <= 30) | ||
897 | led = 0; | ||
898 | else if (rssi <= 39) | ||
899 | led = 1; | ||
900 | else if (rssi <= 49) | ||
901 | led = 2; | ||
902 | else if (rssi <= 53) | ||
903 | led = 3; | ||
904 | else if (rssi <= 63) | ||
905 | led = 4; | ||
906 | else | ||
907 | led = 5; | ||
908 | |||
909 | rt61pci_mcu_request(rt2x00dev, MCU_LED_STRENGTH, 0xff, led, 0); | ||
910 | } | ||
911 | |||
912 | /* | ||
913 | * Link tuning | ||
914 | */ | ||
915 | static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev) | ||
916 | { | ||
917 | u32 reg; | ||
918 | |||
919 | /* | ||
920 | * Update FCS error count from register. | ||
921 | */ | ||
922 | rt2x00pci_register_read(rt2x00dev, STA_CSR0, ®); | ||
923 | rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR); | ||
924 | |||
925 | /* | ||
926 | * Update False CCA count from register. | ||
927 | */ | ||
928 | rt2x00pci_register_read(rt2x00dev, STA_CSR1, ®); | ||
929 | rt2x00dev->link.false_cca = | ||
930 | rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); | ||
931 | } | ||
932 | |||
933 | static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev) | ||
934 | { | ||
935 | rt61pci_bbp_write(rt2x00dev, 17, 0x20); | ||
936 | rt2x00dev->link.vgc_level = 0x20; | ||
937 | } | ||
938 | |||
939 | static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | ||
940 | { | ||
941 | int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); | ||
942 | u8 r17; | ||
943 | u8 up_bound; | ||
944 | u8 low_bound; | ||
945 | |||
946 | /* | ||
947 | * Update Led strength | ||
948 | */ | ||
949 | rt61pci_activity_led(rt2x00dev, rssi); | ||
950 | |||
951 | rt61pci_bbp_read(rt2x00dev, 17, &r17); | ||
952 | |||
953 | /* | ||
954 | * Determine r17 bounds. | ||
955 | */ | ||
956 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | ||
957 | low_bound = 0x28; | ||
958 | up_bound = 0x48; | ||
959 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | ||
960 | low_bound += 0x10; | ||
961 | up_bound += 0x10; | ||
962 | } | ||
963 | } else { | ||
964 | low_bound = 0x20; | ||
965 | up_bound = 0x40; | ||
966 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { | ||
967 | low_bound += 0x10; | ||
968 | up_bound += 0x10; | ||
969 | } | ||
970 | } | ||
971 | |||
972 | /* | ||
973 | * Special big-R17 for very short distance | ||
974 | */ | ||
975 | if (rssi >= -35) { | ||
976 | if (r17 != 0x60) | ||
977 | rt61pci_bbp_write(rt2x00dev, 17, 0x60); | ||
978 | return; | ||
979 | } | ||
980 | |||
981 | /* | ||
982 | * Special big-R17 for short distance | ||
983 | */ | ||
984 | if (rssi >= -58) { | ||
985 | if (r17 != up_bound) | ||
986 | rt61pci_bbp_write(rt2x00dev, 17, up_bound); | ||
987 | return; | ||
988 | } | ||
989 | |||
990 | /* | ||
991 | * Special big-R17 for middle-short distance | ||
992 | */ | ||
993 | if (rssi >= -66) { | ||
994 | low_bound += 0x10; | ||
995 | if (r17 != low_bound) | ||
996 | rt61pci_bbp_write(rt2x00dev, 17, low_bound); | ||
997 | return; | ||
998 | } | ||
999 | |||
1000 | /* | ||
1001 | * Special mid-R17 for middle distance | ||
1002 | */ | ||
1003 | if (rssi >= -74) { | ||
1004 | low_bound += 0x08; | ||
1005 | if (r17 != low_bound) | ||
1006 | rt61pci_bbp_write(rt2x00dev, 17, low_bound); | ||
1007 | return; | ||
1008 | } | ||
1009 | |||
1010 | /* | ||
1011 | * Special case: Change up_bound based on the rssi. | ||
1012 | * Lower up_bound when rssi is weaker then -74 dBm. | ||
1013 | */ | ||
1014 | up_bound -= 2 * (-74 - rssi); | ||
1015 | if (low_bound > up_bound) | ||
1016 | up_bound = low_bound; | ||
1017 | |||
1018 | if (r17 > up_bound) { | ||
1019 | rt61pci_bbp_write(rt2x00dev, 17, up_bound); | ||
1020 | return; | ||
1021 | } | ||
1022 | |||
1023 | /* | ||
1024 | * r17 does not yet exceed upper limit, continue and base | ||
1025 | * the r17 tuning on the false CCA count. | ||
1026 | */ | ||
1027 | if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) { | ||
1028 | if (++r17 > up_bound) | ||
1029 | r17 = up_bound; | ||
1030 | rt61pci_bbp_write(rt2x00dev, 17, r17); | ||
1031 | } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) { | ||
1032 | if (--r17 < low_bound) | ||
1033 | r17 = low_bound; | ||
1034 | rt61pci_bbp_write(rt2x00dev, 17, r17); | ||
1035 | } | ||
1036 | } | ||
1037 | |||
1038 | /* | ||
1039 | * Firmware name function. | ||
1040 | */ | ||
1041 | static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) | ||
1042 | { | ||
1043 | char *fw_name; | ||
1044 | |||
1045 | switch (rt2x00dev->chip.rt) { | ||
1046 | case RT2561: | ||
1047 | fw_name = FIRMWARE_RT2561; | ||
1048 | break; | ||
1049 | case RT2561s: | ||
1050 | fw_name = FIRMWARE_RT2561s; | ||
1051 | break; | ||
1052 | case RT2661: | ||
1053 | fw_name = FIRMWARE_RT2661; | ||
1054 | break; | ||
1055 | default: | ||
1056 | fw_name = NULL; | ||
1057 | break; | ||
1058 | } | ||
1059 | |||
1060 | return fw_name; | ||
1061 | } | ||
1062 | |||
1063 | /* | ||
1064 | * Initialization functions. | ||
1065 | */ | ||
1066 | static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | ||
1067 | const size_t len) | ||
1068 | { | ||
1069 | int i; | ||
1070 | u32 reg; | ||
1071 | |||
1072 | /* | ||
1073 | * Wait for stable hardware. | ||
1074 | */ | ||
1075 | for (i = 0; i < 100; i++) { | ||
1076 | rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); | ||
1077 | if (reg) | ||
1078 | break; | ||
1079 | msleep(1); | ||
1080 | } | ||
1081 | |||
1082 | if (!reg) { | ||
1083 | ERROR(rt2x00dev, "Unstable hardware.\n"); | ||
1084 | return -EBUSY; | ||
1085 | } | ||
1086 | |||
1087 | /* | ||
1088 | * Prepare MCU and mailbox for firmware loading. | ||
1089 | */ | ||
1090 | reg = 0; | ||
1091 | rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 1); | ||
1092 | rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); | ||
1093 | rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); | ||
1094 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); | ||
1095 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, 0); | ||
1096 | |||
1097 | /* | ||
1098 | * Write firmware to device. | ||
1099 | */ | ||
1100 | reg = 0; | ||
1101 | rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 1); | ||
1102 | rt2x00_set_field32(®, MCU_CNTL_CSR_SELECT_BANK, 1); | ||
1103 | rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); | ||
1104 | |||
1105 | rt2x00pci_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, | ||
1106 | data, len); | ||
1107 | |||
1108 | rt2x00_set_field32(®, MCU_CNTL_CSR_SELECT_BANK, 0); | ||
1109 | rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); | ||
1110 | |||
1111 | rt2x00_set_field32(®, MCU_CNTL_CSR_RESET, 0); | ||
1112 | rt2x00pci_register_write(rt2x00dev, MCU_CNTL_CSR, reg); | ||
1113 | |||
1114 | for (i = 0; i < 100; i++) { | ||
1115 | rt2x00pci_register_read(rt2x00dev, MCU_CNTL_CSR, ®); | ||
1116 | if (rt2x00_get_field32(reg, MCU_CNTL_CSR_READY)) | ||
1117 | break; | ||
1118 | msleep(1); | ||
1119 | } | ||
1120 | |||
1121 | if (i == 100) { | ||
1122 | ERROR(rt2x00dev, "MCU Control register not ready.\n"); | ||
1123 | return -EBUSY; | ||
1124 | } | ||
1125 | |||
1126 | /* | ||
1127 | * Reset MAC and BBP registers. | ||
1128 | */ | ||
1129 | reg = 0; | ||
1130 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 1); | ||
1131 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 1); | ||
1132 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | ||
1133 | |||
1134 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | ||
1135 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 0); | ||
1136 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 0); | ||
1137 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | ||
1138 | |||
1139 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | ||
1140 | rt2x00_set_field32(®, MAC_CSR1_HOST_READY, 1); | ||
1141 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | ||
1142 | |||
1143 | return 0; | ||
1144 | } | ||
1145 | |||
1146 | static void rt61pci_init_rxring(struct rt2x00_dev *rt2x00dev) | ||
1147 | { | ||
1148 | struct data_ring *ring = rt2x00dev->rx; | ||
1149 | struct data_desc *rxd; | ||
1150 | unsigned int i; | ||
1151 | u32 word; | ||
1152 | |||
1153 | memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring)); | ||
1154 | |||
1155 | for (i = 0; i < ring->stats.limit; i++) { | ||
1156 | rxd = ring->entry[i].priv; | ||
1157 | |||
1158 | rt2x00_desc_read(rxd, 5, &word); | ||
1159 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, | ||
1160 | ring->entry[i].data_dma); | ||
1161 | rt2x00_desc_write(rxd, 5, word); | ||
1162 | |||
1163 | rt2x00_desc_read(rxd, 0, &word); | ||
1164 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | ||
1165 | rt2x00_desc_write(rxd, 0, word); | ||
1166 | } | ||
1167 | |||
1168 | rt2x00_ring_index_clear(rt2x00dev->rx); | ||
1169 | } | ||
1170 | |||
1171 | static void rt61pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue) | ||
1172 | { | ||
1173 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | ||
1174 | struct data_desc *txd; | ||
1175 | unsigned int i; | ||
1176 | u32 word; | ||
1177 | |||
1178 | memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring)); | ||
1179 | |||
1180 | for (i = 0; i < ring->stats.limit; i++) { | ||
1181 | txd = ring->entry[i].priv; | ||
1182 | |||
1183 | rt2x00_desc_read(txd, 1, &word); | ||
1184 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); | ||
1185 | rt2x00_desc_write(txd, 1, word); | ||
1186 | |||
1187 | rt2x00_desc_read(txd, 5, &word); | ||
1188 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, queue); | ||
1189 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, i); | ||
1190 | rt2x00_desc_write(txd, 5, word); | ||
1191 | |||
1192 | rt2x00_desc_read(txd, 6, &word); | ||
1193 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, | ||
1194 | ring->entry[i].data_dma); | ||
1195 | rt2x00_desc_write(txd, 6, word); | ||
1196 | |||
1197 | rt2x00_desc_read(txd, 0, &word); | ||
1198 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | ||
1199 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | ||
1200 | rt2x00_desc_write(txd, 0, word); | ||
1201 | } | ||
1202 | |||
1203 | rt2x00_ring_index_clear(ring); | ||
1204 | } | ||
1205 | |||
1206 | static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | ||
1207 | { | ||
1208 | u32 reg; | ||
1209 | |||
1210 | /* | ||
1211 | * Initialize rings. | ||
1212 | */ | ||
1213 | rt61pci_init_rxring(rt2x00dev); | ||
1214 | rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0); | ||
1215 | rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA1); | ||
1216 | rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA2); | ||
1217 | rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA3); | ||
1218 | rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA4); | ||
1219 | |||
1220 | /* | ||
1221 | * Initialize registers. | ||
1222 | */ | ||
1223 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR0, ®); | ||
1224 | rt2x00_set_field32(®, TX_RING_CSR0_AC0_RING_SIZE, | ||
1225 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | ||
1226 | rt2x00_set_field32(®, TX_RING_CSR0_AC1_RING_SIZE, | ||
1227 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | ||
1228 | rt2x00_set_field32(®, TX_RING_CSR0_AC2_RING_SIZE, | ||
1229 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA2].stats.limit); | ||
1230 | rt2x00_set_field32(®, TX_RING_CSR0_AC3_RING_SIZE, | ||
1231 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA3].stats.limit); | ||
1232 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR0, reg); | ||
1233 | |||
1234 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR1, ®); | ||
1235 | rt2x00_set_field32(®, TX_RING_CSR1_MGMT_RING_SIZE, | ||
1236 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA4].stats.limit); | ||
1237 | rt2x00_set_field32(®, TX_RING_CSR1_TXD_SIZE, | ||
1238 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size / | ||
1239 | 4); | ||
1240 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); | ||
1241 | |||
1242 | rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); | ||
1243 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, | ||
1244 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | ||
1245 | rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); | ||
1246 | |||
1247 | rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); | ||
1248 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, | ||
1249 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | ||
1250 | rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); | ||
1251 | |||
1252 | rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); | ||
1253 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, | ||
1254 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA2].data_dma); | ||
1255 | rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); | ||
1256 | |||
1257 | rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); | ||
1258 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, | ||
1259 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA3].data_dma); | ||
1260 | rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); | ||
1261 | |||
1262 | rt2x00pci_register_read(rt2x00dev, MGMT_BASE_CSR, ®); | ||
1263 | rt2x00_set_field32(®, MGMT_BASE_CSR_RING_REGISTER, | ||
1264 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA4].data_dma); | ||
1265 | rt2x00pci_register_write(rt2x00dev, MGMT_BASE_CSR, reg); | ||
1266 | |||
1267 | rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®); | ||
1268 | rt2x00_set_field32(®, RX_RING_CSR_RING_SIZE, | ||
1269 | rt2x00dev->rx->stats.limit); | ||
1270 | rt2x00_set_field32(®, RX_RING_CSR_RXD_SIZE, | ||
1271 | rt2x00dev->rx->desc_size / 4); | ||
1272 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); | ||
1273 | rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); | ||
1274 | |||
1275 | rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); | ||
1276 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, | ||
1277 | rt2x00dev->rx->data_dma); | ||
1278 | rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); | ||
1279 | |||
1280 | rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); | ||
1281 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC0, 2); | ||
1282 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC1, 2); | ||
1283 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC2, 2); | ||
1284 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC3, 2); | ||
1285 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_MGMT, 0); | ||
1286 | rt2x00pci_register_write(rt2x00dev, TX_DMA_DST_CSR, reg); | ||
1287 | |||
1288 | rt2x00pci_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); | ||
1289 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC0, 1); | ||
1290 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1); | ||
1291 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1); | ||
1292 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC3, 1); | ||
1293 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_MGMT, 1); | ||
1294 | rt2x00pci_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg); | ||
1295 | |||
1296 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); | ||
1297 | rt2x00_set_field32(®, RX_CNTL_CSR_LOAD_RXD, 1); | ||
1298 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); | ||
1299 | |||
1300 | return 0; | ||
1301 | } | ||
1302 | |||
1303 | static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | ||
1304 | { | ||
1305 | u32 reg; | ||
1306 | |||
1307 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
1308 | rt2x00_set_field32(®, TXRX_CSR0_AUTO_TX_SEQ, 1); | ||
1309 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, 0); | ||
1310 | rt2x00_set_field32(®, TXRX_CSR0_TX_WITHOUT_WAITING, 0); | ||
1311 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
1312 | |||
1313 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR1, ®); | ||
1314 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0, 47); /* CCK Signal */ | ||
1315 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID0_VALID, 1); | ||
1316 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID1, 30); /* Rssi */ | ||
1317 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID1_VALID, 1); | ||
1318 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID2, 42); /* OFDM Rate */ | ||
1319 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID2_VALID, 1); | ||
1320 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3, 30); /* Rssi */ | ||
1321 | rt2x00_set_field32(®, TXRX_CSR1_BBP_ID3_VALID, 1); | ||
1322 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR1, reg); | ||
1323 | |||
1324 | /* | ||
1325 | * CCK TXD BBP registers | ||
1326 | */ | ||
1327 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR2, ®); | ||
1328 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0, 13); | ||
1329 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID0_VALID, 1); | ||
1330 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID1, 12); | ||
1331 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID1_VALID, 1); | ||
1332 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID2, 11); | ||
1333 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID2_VALID, 1); | ||
1334 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3, 10); | ||
1335 | rt2x00_set_field32(®, TXRX_CSR2_BBP_ID3_VALID, 1); | ||
1336 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR2, reg); | ||
1337 | |||
1338 | /* | ||
1339 | * OFDM TXD BBP registers | ||
1340 | */ | ||
1341 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR3, ®); | ||
1342 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0, 7); | ||
1343 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID0_VALID, 1); | ||
1344 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1, 6); | ||
1345 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID1_VALID, 1); | ||
1346 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2, 5); | ||
1347 | rt2x00_set_field32(®, TXRX_CSR3_BBP_ID2_VALID, 1); | ||
1348 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR3, reg); | ||
1349 | |||
1350 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR7, ®); | ||
1351 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_6MBS, 59); | ||
1352 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_9MBS, 53); | ||
1353 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_12MBS, 49); | ||
1354 | rt2x00_set_field32(®, TXRX_CSR7_ACK_CTS_18MBS, 46); | ||
1355 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR7, reg); | ||
1356 | |||
1357 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR8, ®); | ||
1358 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_24MBS, 44); | ||
1359 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_36MBS, 42); | ||
1360 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_48MBS, 42); | ||
1361 | rt2x00_set_field32(®, TXRX_CSR8_ACK_CTS_54MBS, 42); | ||
1362 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR8, reg); | ||
1363 | |||
1364 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f); | ||
1365 | |||
1366 | rt2x00pci_register_write(rt2x00dev, MAC_CSR6, 0x00000fff); | ||
1367 | |||
1368 | rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); | ||
1369 | rt2x00_set_field32(®, MAC_CSR9_CW_SELECT, 0); | ||
1370 | rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); | ||
1371 | |||
1372 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x0000071c); | ||
1373 | |||
1374 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) | ||
1375 | return -EBUSY; | ||
1376 | |||
1377 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); | ||
1378 | |||
1379 | /* | ||
1380 | * Invalidate all Shared Keys (SEC_CSR0), | ||
1381 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) | ||
1382 | */ | ||
1383 | rt2x00pci_register_write(rt2x00dev, SEC_CSR0, 0x00000000); | ||
1384 | rt2x00pci_register_write(rt2x00dev, SEC_CSR1, 0x00000000); | ||
1385 | rt2x00pci_register_write(rt2x00dev, SEC_CSR5, 0x00000000); | ||
1386 | |||
1387 | rt2x00pci_register_write(rt2x00dev, PHY_CSR1, 0x000023b0); | ||
1388 | rt2x00pci_register_write(rt2x00dev, PHY_CSR5, 0x060a100c); | ||
1389 | rt2x00pci_register_write(rt2x00dev, PHY_CSR6, 0x00080606); | ||
1390 | rt2x00pci_register_write(rt2x00dev, PHY_CSR7, 0x00000a08); | ||
1391 | |||
1392 | rt2x00pci_register_write(rt2x00dev, PCI_CFG_CSR, 0x28ca4404); | ||
1393 | |||
1394 | rt2x00pci_register_write(rt2x00dev, TEST_MODE_CSR, 0x00000200); | ||
1395 | |||
1396 | rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); | ||
1397 | |||
1398 | rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR0, ®); | ||
1399 | rt2x00_set_field32(®, AC_TXOP_CSR0_AC0_TX_OP, 0); | ||
1400 | rt2x00_set_field32(®, AC_TXOP_CSR0_AC1_TX_OP, 0); | ||
1401 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR0, reg); | ||
1402 | |||
1403 | rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR1, ®); | ||
1404 | rt2x00_set_field32(®, AC_TXOP_CSR1_AC2_TX_OP, 192); | ||
1405 | rt2x00_set_field32(®, AC_TXOP_CSR1_AC3_TX_OP, 48); | ||
1406 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); | ||
1407 | |||
1408 | /* | ||
1409 | * We must clear the error counters. | ||
1410 | * These registers are cleared on read, | ||
1411 | * so we may pass a useless variable to store the value. | ||
1412 | */ | ||
1413 | rt2x00pci_register_read(rt2x00dev, STA_CSR0, ®); | ||
1414 | rt2x00pci_register_read(rt2x00dev, STA_CSR1, ®); | ||
1415 | rt2x00pci_register_read(rt2x00dev, STA_CSR2, ®); | ||
1416 | |||
1417 | /* | ||
1418 | * Reset MAC and BBP registers. | ||
1419 | */ | ||
1420 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | ||
1421 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 1); | ||
1422 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 1); | ||
1423 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | ||
1424 | |||
1425 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | ||
1426 | rt2x00_set_field32(®, MAC_CSR1_SOFT_RESET, 0); | ||
1427 | rt2x00_set_field32(®, MAC_CSR1_BBP_RESET, 0); | ||
1428 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | ||
1429 | |||
1430 | rt2x00pci_register_read(rt2x00dev, MAC_CSR1, ®); | ||
1431 | rt2x00_set_field32(®, MAC_CSR1_HOST_READY, 1); | ||
1432 | rt2x00pci_register_write(rt2x00dev, MAC_CSR1, reg); | ||
1433 | |||
1434 | return 0; | ||
1435 | } | ||
1436 | |||
1437 | static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev) | ||
1438 | { | ||
1439 | unsigned int i; | ||
1440 | u16 eeprom; | ||
1441 | u8 reg_id; | ||
1442 | u8 value; | ||
1443 | |||
1444 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
1445 | rt61pci_bbp_read(rt2x00dev, 0, &value); | ||
1446 | if ((value != 0xff) && (value != 0x00)) | ||
1447 | goto continue_csr_init; | ||
1448 | NOTICE(rt2x00dev, "Waiting for BBP register.\n"); | ||
1449 | udelay(REGISTER_BUSY_DELAY); | ||
1450 | } | ||
1451 | |||
1452 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | ||
1453 | return -EACCES; | ||
1454 | |||
1455 | continue_csr_init: | ||
1456 | rt61pci_bbp_write(rt2x00dev, 3, 0x00); | ||
1457 | rt61pci_bbp_write(rt2x00dev, 15, 0x30); | ||
1458 | rt61pci_bbp_write(rt2x00dev, 21, 0xc8); | ||
1459 | rt61pci_bbp_write(rt2x00dev, 22, 0x38); | ||
1460 | rt61pci_bbp_write(rt2x00dev, 23, 0x06); | ||
1461 | rt61pci_bbp_write(rt2x00dev, 24, 0xfe); | ||
1462 | rt61pci_bbp_write(rt2x00dev, 25, 0x0a); | ||
1463 | rt61pci_bbp_write(rt2x00dev, 26, 0x0d); | ||
1464 | rt61pci_bbp_write(rt2x00dev, 34, 0x12); | ||
1465 | rt61pci_bbp_write(rt2x00dev, 37, 0x07); | ||
1466 | rt61pci_bbp_write(rt2x00dev, 39, 0xf8); | ||
1467 | rt61pci_bbp_write(rt2x00dev, 41, 0x60); | ||
1468 | rt61pci_bbp_write(rt2x00dev, 53, 0x10); | ||
1469 | rt61pci_bbp_write(rt2x00dev, 54, 0x18); | ||
1470 | rt61pci_bbp_write(rt2x00dev, 60, 0x10); | ||
1471 | rt61pci_bbp_write(rt2x00dev, 61, 0x04); | ||
1472 | rt61pci_bbp_write(rt2x00dev, 62, 0x04); | ||
1473 | rt61pci_bbp_write(rt2x00dev, 75, 0xfe); | ||
1474 | rt61pci_bbp_write(rt2x00dev, 86, 0xfe); | ||
1475 | rt61pci_bbp_write(rt2x00dev, 88, 0xfe); | ||
1476 | rt61pci_bbp_write(rt2x00dev, 90, 0x0f); | ||
1477 | rt61pci_bbp_write(rt2x00dev, 99, 0x00); | ||
1478 | rt61pci_bbp_write(rt2x00dev, 102, 0x16); | ||
1479 | rt61pci_bbp_write(rt2x00dev, 107, 0x04); | ||
1480 | |||
1481 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
1482 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | ||
1483 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | ||
1484 | |||
1485 | if (eeprom != 0xffff && eeprom != 0x0000) { | ||
1486 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | ||
1487 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | ||
1488 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
1489 | reg_id, value); | ||
1490 | rt61pci_bbp_write(rt2x00dev, reg_id, value); | ||
1491 | } | ||
1492 | } | ||
1493 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
1494 | |||
1495 | return 0; | ||
1496 | } | ||
1497 | |||
1498 | /* | ||
1499 | * Device state switch handlers. | ||
1500 | */ | ||
1501 | static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev, | ||
1502 | enum dev_state state) | ||
1503 | { | ||
1504 | u32 reg; | ||
1505 | |||
1506 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
1507 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, | ||
1508 | state == STATE_RADIO_RX_OFF); | ||
1509 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
1510 | } | ||
1511 | |||
1512 | static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | ||
1513 | enum dev_state state) | ||
1514 | { | ||
1515 | int mask = (state == STATE_RADIO_IRQ_OFF); | ||
1516 | u32 reg; | ||
1517 | |||
1518 | /* | ||
1519 | * When interrupts are being enabled, the interrupt registers | ||
1520 | * should clear the register to assure a clean state. | ||
1521 | */ | ||
1522 | if (state == STATE_RADIO_IRQ_ON) { | ||
1523 | rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | ||
1524 | rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); | ||
1525 | |||
1526 | rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®); | ||
1527 | rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg); | ||
1528 | } | ||
1529 | |||
1530 | /* | ||
1531 | * Only toggle the interrupts bits we are going to use. | ||
1532 | * Non-checked interrupt bits are disabled by default. | ||
1533 | */ | ||
1534 | rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); | ||
1535 | rt2x00_set_field32(®, INT_MASK_CSR_TXDONE, mask); | ||
1536 | rt2x00_set_field32(®, INT_MASK_CSR_RXDONE, mask); | ||
1537 | rt2x00_set_field32(®, INT_MASK_CSR_ENABLE_MITIGATION, mask); | ||
1538 | rt2x00_set_field32(®, INT_MASK_CSR_MITIGATION_PERIOD, 0xff); | ||
1539 | rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); | ||
1540 | |||
1541 | rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); | ||
1542 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_0, mask); | ||
1543 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_1, mask); | ||
1544 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_2, mask); | ||
1545 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_3, mask); | ||
1546 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_4, mask); | ||
1547 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_5, mask); | ||
1548 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_6, mask); | ||
1549 | rt2x00_set_field32(®, MCU_INT_MASK_CSR_7, mask); | ||
1550 | rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); | ||
1551 | } | ||
1552 | |||
1553 | static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | ||
1554 | { | ||
1555 | u32 reg; | ||
1556 | |||
1557 | /* | ||
1558 | * Initialize all registers. | ||
1559 | */ | ||
1560 | if (rt61pci_init_rings(rt2x00dev) || | ||
1561 | rt61pci_init_registers(rt2x00dev) || | ||
1562 | rt61pci_init_bbp(rt2x00dev)) { | ||
1563 | ERROR(rt2x00dev, "Register initialization failed.\n"); | ||
1564 | return -EIO; | ||
1565 | } | ||
1566 | |||
1567 | /* | ||
1568 | * Enable interrupts. | ||
1569 | */ | ||
1570 | rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | ||
1571 | |||
1572 | /* | ||
1573 | * Enable RX. | ||
1574 | */ | ||
1575 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); | ||
1576 | rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); | ||
1577 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); | ||
1578 | |||
1579 | /* | ||
1580 | * Enable LED | ||
1581 | */ | ||
1582 | rt61pci_enable_led(rt2x00dev); | ||
1583 | |||
1584 | return 0; | ||
1585 | } | ||
1586 | |||
1587 | static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | ||
1588 | { | ||
1589 | u32 reg; | ||
1590 | |||
1591 | /* | ||
1592 | * Disable LED | ||
1593 | */ | ||
1594 | rt61pci_disable_led(rt2x00dev); | ||
1595 | |||
1596 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | ||
1597 | |||
1598 | /* | ||
1599 | * Disable synchronisation. | ||
1600 | */ | ||
1601 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
1602 | |||
1603 | /* | ||
1604 | * Cancel RX and TX. | ||
1605 | */ | ||
1606 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | ||
1607 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, 1); | ||
1608 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); | ||
1609 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); | ||
1610 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); | ||
1611 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_MGMT, 1); | ||
1612 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | ||
1613 | |||
1614 | /* | ||
1615 | * Disable interrupts. | ||
1616 | */ | ||
1617 | rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF); | ||
1618 | } | ||
1619 | |||
1620 | static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | ||
1621 | { | ||
1622 | u32 reg; | ||
1623 | unsigned int i; | ||
1624 | char put_to_sleep; | ||
1625 | char current_state; | ||
1626 | |||
1627 | put_to_sleep = (state != STATE_AWAKE); | ||
1628 | |||
1629 | rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®); | ||
1630 | rt2x00_set_field32(®, MAC_CSR12_FORCE_WAKEUP, !put_to_sleep); | ||
1631 | rt2x00_set_field32(®, MAC_CSR12_PUT_TO_SLEEP, put_to_sleep); | ||
1632 | rt2x00pci_register_write(rt2x00dev, MAC_CSR12, reg); | ||
1633 | |||
1634 | /* | ||
1635 | * Device is not guaranteed to be in the requested state yet. | ||
1636 | * We must wait until the register indicates that the | ||
1637 | * device has entered the correct state. | ||
1638 | */ | ||
1639 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
1640 | rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®); | ||
1641 | current_state = | ||
1642 | rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); | ||
1643 | if (current_state == !put_to_sleep) | ||
1644 | return 0; | ||
1645 | msleep(10); | ||
1646 | } | ||
1647 | |||
1648 | NOTICE(rt2x00dev, "Device failed to enter state %d, " | ||
1649 | "current device state %d.\n", !put_to_sleep, current_state); | ||
1650 | |||
1651 | return -EBUSY; | ||
1652 | } | ||
1653 | |||
1654 | static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | ||
1655 | enum dev_state state) | ||
1656 | { | ||
1657 | int retval = 0; | ||
1658 | |||
1659 | switch (state) { | ||
1660 | case STATE_RADIO_ON: | ||
1661 | retval = rt61pci_enable_radio(rt2x00dev); | ||
1662 | break; | ||
1663 | case STATE_RADIO_OFF: | ||
1664 | rt61pci_disable_radio(rt2x00dev); | ||
1665 | break; | ||
1666 | case STATE_RADIO_RX_ON: | ||
1667 | case STATE_RADIO_RX_OFF: | ||
1668 | rt61pci_toggle_rx(rt2x00dev, state); | ||
1669 | break; | ||
1670 | case STATE_DEEP_SLEEP: | ||
1671 | case STATE_SLEEP: | ||
1672 | case STATE_STANDBY: | ||
1673 | case STATE_AWAKE: | ||
1674 | retval = rt61pci_set_state(rt2x00dev, state); | ||
1675 | break; | ||
1676 | default: | ||
1677 | retval = -ENOTSUPP; | ||
1678 | break; | ||
1679 | } | ||
1680 | |||
1681 | return retval; | ||
1682 | } | ||
1683 | |||
1684 | /* | ||
1685 | * TX descriptor initialization | ||
1686 | */ | ||
1687 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | ||
1688 | struct data_desc *txd, | ||
1689 | struct data_entry_desc *desc, | ||
1690 | struct ieee80211_hdr *ieee80211hdr, | ||
1691 | unsigned int length, | ||
1692 | struct ieee80211_tx_control *control) | ||
1693 | { | ||
1694 | u32 word; | ||
1695 | |||
1696 | /* | ||
1697 | * Start writing the descriptor words. | ||
1698 | */ | ||
1699 | rt2x00_desc_read(txd, 1, &word); | ||
1700 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue); | ||
1701 | rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs); | ||
1702 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | ||
1703 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | ||
1704 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | ||
1705 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | ||
1706 | rt2x00_desc_write(txd, 1, word); | ||
1707 | |||
1708 | rt2x00_desc_read(txd, 2, &word); | ||
1709 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | ||
1710 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | ||
1711 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | ||
1712 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | ||
1713 | rt2x00_desc_write(txd, 2, word); | ||
1714 | |||
1715 | rt2x00_desc_read(txd, 5, &word); | ||
1716 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | ||
1717 | TXPOWER_TO_DEV(control->power_level)); | ||
1718 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | ||
1719 | rt2x00_desc_write(txd, 5, word); | ||
1720 | |||
1721 | rt2x00_desc_read(txd, 11, &word); | ||
1722 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, length); | ||
1723 | rt2x00_desc_write(txd, 11, word); | ||
1724 | |||
1725 | rt2x00_desc_read(txd, 0, &word); | ||
1726 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | ||
1727 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | ||
1728 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | ||
1729 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | ||
1730 | rt2x00_set_field32(&word, TXD_W0_ACK, | ||
1731 | !(control->flags & IEEE80211_TXCTL_NO_ACK)); | ||
1732 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | ||
1733 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | ||
1734 | rt2x00_set_field32(&word, TXD_W0_OFDM, | ||
1735 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | ||
1736 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | ||
1737 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | ||
1738 | !!(control->flags & | ||
1739 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | ||
1740 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | ||
1741 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length); | ||
1742 | rt2x00_set_field32(&word, TXD_W0_BURST, | ||
1743 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | ||
1744 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | ||
1745 | rt2x00_desc_write(txd, 0, word); | ||
1746 | } | ||
1747 | |||
1748 | /* | ||
1749 | * TX data initialization | ||
1750 | */ | ||
1751 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
1752 | unsigned int queue) | ||
1753 | { | ||
1754 | u32 reg; | ||
1755 | |||
1756 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | ||
1757 | /* | ||
1758 | * For Wi-Fi faily generated beacons between participating | ||
1759 | * stations. Set TBTT phase adaptive adjustment step to 8us. | ||
1760 | */ | ||
1761 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); | ||
1762 | |||
1763 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1764 | if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) { | ||
1765 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | ||
1766 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1767 | } | ||
1768 | return; | ||
1769 | } | ||
1770 | |||
1771 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | ||
1772 | if (queue == IEEE80211_TX_QUEUE_DATA0) | ||
1773 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, 1); | ||
1774 | else if (queue == IEEE80211_TX_QUEUE_DATA1) | ||
1775 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, 1); | ||
1776 | else if (queue == IEEE80211_TX_QUEUE_DATA2) | ||
1777 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, 1); | ||
1778 | else if (queue == IEEE80211_TX_QUEUE_DATA3) | ||
1779 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, 1); | ||
1780 | else if (queue == IEEE80211_TX_QUEUE_DATA4) | ||
1781 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_MGMT, 1); | ||
1782 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | ||
1783 | } | ||
1784 | |||
1785 | /* | ||
1786 | * RX control handlers | ||
1787 | */ | ||
1788 | static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | ||
1789 | { | ||
1790 | u16 eeprom; | ||
1791 | u8 offset; | ||
1792 | u8 lna; | ||
1793 | |||
1794 | lna = rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_LNA); | ||
1795 | switch (lna) { | ||
1796 | case 3: | ||
1797 | offset = 90; | ||
1798 | break; | ||
1799 | case 2: | ||
1800 | offset = 74; | ||
1801 | break; | ||
1802 | case 1: | ||
1803 | offset = 64; | ||
1804 | break; | ||
1805 | default: | ||
1806 | return 0; | ||
1807 | } | ||
1808 | |||
1809 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | ||
1810 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) | ||
1811 | offset += 14; | ||
1812 | |||
1813 | if (lna == 3 || lna == 2) | ||
1814 | offset += 10; | ||
1815 | |||
1816 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom); | ||
1817 | offset -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1); | ||
1818 | } else { | ||
1819 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) | ||
1820 | offset += 14; | ||
1821 | |||
1822 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); | ||
1823 | offset -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1); | ||
1824 | } | ||
1825 | |||
1826 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; | ||
1827 | } | ||
1828 | |||
1829 | static int rt61pci_fill_rxdone(struct data_entry *entry, | ||
1830 | int *signal, int *rssi, int *ofdm, int *size) | ||
1831 | { | ||
1832 | struct data_desc *rxd = entry->priv; | ||
1833 | u32 word0; | ||
1834 | u32 word1; | ||
1835 | |||
1836 | rt2x00_desc_read(rxd, 0, &word0); | ||
1837 | rt2x00_desc_read(rxd, 1, &word1); | ||
1838 | |||
1839 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR) || | ||
1840 | rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR)) | ||
1841 | return -EINVAL; | ||
1842 | |||
1843 | /* | ||
1844 | * Obtain the status about this packet. | ||
1845 | */ | ||
1846 | *signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | ||
1847 | *rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1); | ||
1848 | *ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | ||
1849 | *size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | ||
1850 | |||
1851 | return 0; | ||
1852 | } | ||
1853 | |||
1854 | /* | ||
1855 | * Interrupt functions. | ||
1856 | */ | ||
1857 | static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | ||
1858 | { | ||
1859 | struct data_ring *ring; | ||
1860 | struct data_entry *entry; | ||
1861 | struct data_desc *txd; | ||
1862 | u32 word; | ||
1863 | u32 reg; | ||
1864 | u32 old_reg; | ||
1865 | int type; | ||
1866 | int index; | ||
1867 | int tx_status; | ||
1868 | int retry; | ||
1869 | |||
1870 | /* | ||
1871 | * During each loop we will compare the freshly read | ||
1872 | * STA_CSR4 register value with the value read from | ||
1873 | * the previous loop. If the 2 values are equal then | ||
1874 | * we should stop processing because the chance it | ||
1875 | * quite big that the device has been unplugged and | ||
1876 | * we risk going into an endless loop. | ||
1877 | */ | ||
1878 | old_reg = 0; | ||
1879 | |||
1880 | while (1) { | ||
1881 | rt2x00pci_register_read(rt2x00dev, STA_CSR4, ®); | ||
1882 | if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) | ||
1883 | break; | ||
1884 | |||
1885 | if (old_reg == reg) | ||
1886 | break; | ||
1887 | old_reg = reg; | ||
1888 | |||
1889 | /* | ||
1890 | * Skip this entry when it contains an invalid | ||
1891 | * ring identication number. | ||
1892 | */ | ||
1893 | type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); | ||
1894 | ring = rt2x00lib_get_ring(rt2x00dev, type); | ||
1895 | if (unlikely(!ring)) | ||
1896 | continue; | ||
1897 | |||
1898 | /* | ||
1899 | * Skip this entry when it contains an invalid | ||
1900 | * index number. | ||
1901 | */ | ||
1902 | index = rt2x00_get_field32(reg, STA_CSR4_PID_SUBTYPE); | ||
1903 | if (unlikely(index >= ring->stats.limit)) | ||
1904 | continue; | ||
1905 | |||
1906 | entry = &ring->entry[index]; | ||
1907 | txd = entry->priv; | ||
1908 | rt2x00_desc_read(txd, 0, &word); | ||
1909 | |||
1910 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | ||
1911 | !rt2x00_get_field32(word, TXD_W0_VALID)) | ||
1912 | return; | ||
1913 | |||
1914 | /* | ||
1915 | * Obtain the status about this packet. | ||
1916 | */ | ||
1917 | tx_status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); | ||
1918 | retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); | ||
1919 | |||
1920 | rt2x00lib_txdone(entry, tx_status, retry); | ||
1921 | |||
1922 | /* | ||
1923 | * Make this entry available for reuse. | ||
1924 | */ | ||
1925 | entry->flags = 0; | ||
1926 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | ||
1927 | rt2x00_desc_write(txd, 0, word); | ||
1928 | rt2x00_ring_index_done_inc(entry->ring); | ||
1929 | |||
1930 | /* | ||
1931 | * If the data ring was full before the txdone handler | ||
1932 | * we must make sure the packet queue in the mac80211 stack | ||
1933 | * is reenabled when the txdone handler has finished. | ||
1934 | */ | ||
1935 | if (!rt2x00_ring_full(ring)) | ||
1936 | ieee80211_wake_queue(rt2x00dev->hw, | ||
1937 | entry->tx_status.control.queue); | ||
1938 | } | ||
1939 | } | ||
1940 | |||
1941 | static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) | ||
1942 | { | ||
1943 | struct rt2x00_dev *rt2x00dev = dev_instance; | ||
1944 | u32 reg_mcu; | ||
1945 | u32 reg; | ||
1946 | |||
1947 | /* | ||
1948 | * Get the interrupt sources & saved to local variable. | ||
1949 | * Write register value back to clear pending interrupts. | ||
1950 | */ | ||
1951 | rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®_mcu); | ||
1952 | rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu); | ||
1953 | |||
1954 | rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | ||
1955 | rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); | ||
1956 | |||
1957 | if (!reg && !reg_mcu) | ||
1958 | return IRQ_NONE; | ||
1959 | |||
1960 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
1961 | return IRQ_HANDLED; | ||
1962 | |||
1963 | /* | ||
1964 | * Handle interrupts, walk through all bits | ||
1965 | * and run the tasks, the bits are checked in order of | ||
1966 | * priority. | ||
1967 | */ | ||
1968 | |||
1969 | /* | ||
1970 | * 1 - Rx ring done interrupt. | ||
1971 | */ | ||
1972 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RXDONE)) | ||
1973 | rt2x00pci_rxdone(rt2x00dev); | ||
1974 | |||
1975 | /* | ||
1976 | * 2 - Tx ring done interrupt. | ||
1977 | */ | ||
1978 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TXDONE)) | ||
1979 | rt61pci_txdone(rt2x00dev); | ||
1980 | |||
1981 | /* | ||
1982 | * 3 - Handle MCU command done. | ||
1983 | */ | ||
1984 | if (reg_mcu) | ||
1985 | rt2x00pci_register_write(rt2x00dev, | ||
1986 | M2H_CMD_DONE_CSR, 0xffffffff); | ||
1987 | |||
1988 | return IRQ_HANDLED; | ||
1989 | } | ||
1990 | |||
1991 | /* | ||
1992 | * Device probe functions. | ||
1993 | */ | ||
1994 | static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | ||
1995 | { | ||
1996 | struct eeprom_93cx6 eeprom; | ||
1997 | u32 reg; | ||
1998 | u16 word; | ||
1999 | u8 *mac; | ||
2000 | s8 value; | ||
2001 | |||
2002 | rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); | ||
2003 | |||
2004 | eeprom.data = rt2x00dev; | ||
2005 | eeprom.register_read = rt61pci_eepromregister_read; | ||
2006 | eeprom.register_write = rt61pci_eepromregister_write; | ||
2007 | eeprom.width = rt2x00_get_field32(reg, E2PROM_CSR_TYPE_93C46) ? | ||
2008 | PCI_EEPROM_WIDTH_93C46 : PCI_EEPROM_WIDTH_93C66; | ||
2009 | eeprom.reg_data_in = 0; | ||
2010 | eeprom.reg_data_out = 0; | ||
2011 | eeprom.reg_data_clock = 0; | ||
2012 | eeprom.reg_chip_select = 0; | ||
2013 | |||
2014 | eeprom_93cx6_multiread(&eeprom, EEPROM_BASE, rt2x00dev->eeprom, | ||
2015 | EEPROM_SIZE / sizeof(u16)); | ||
2016 | |||
2017 | /* | ||
2018 | * Start validation of the data that has been read. | ||
2019 | */ | ||
2020 | mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); | ||
2021 | if (!is_valid_ether_addr(mac)) { | ||
2022 | random_ether_addr(mac); | ||
2023 | EEPROM(rt2x00dev, "MAC: " MAC_FMT "\n", MAC_ARG(mac)); | ||
2024 | } | ||
2025 | |||
2026 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); | ||
2027 | if (word == 0xffff) { | ||
2028 | rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2); | ||
2029 | rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 2); | ||
2030 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 2); | ||
2031 | rt2x00_set_field16(&word, EEPROM_ANTENNA_FRAME_TYPE, 0); | ||
2032 | rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0); | ||
2033 | rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); | ||
2034 | rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF5225); | ||
2035 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | ||
2036 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | ||
2037 | } | ||
2038 | |||
2039 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word); | ||
2040 | if (word == 0xffff) { | ||
2041 | rt2x00_set_field16(&word, EEPROM_NIC_ENABLE_DIVERSITY, 0); | ||
2042 | rt2x00_set_field16(&word, EEPROM_NIC_TX_DIVERSITY, 0); | ||
2043 | rt2x00_set_field16(&word, EEPROM_NIC_TX_RX_FIXED, 0); | ||
2044 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0); | ||
2045 | rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); | ||
2046 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); | ||
2047 | rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word); | ||
2048 | EEPROM(rt2x00dev, "NIC: 0x%04x\n", word); | ||
2049 | } | ||
2050 | |||
2051 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &word); | ||
2052 | if (word == 0xffff) { | ||
2053 | rt2x00_set_field16(&word, EEPROM_LED_LED_MODE, | ||
2054 | LED_MODE_DEFAULT); | ||
2055 | rt2x00_eeprom_write(rt2x00dev, EEPROM_LED, word); | ||
2056 | EEPROM(rt2x00dev, "Led: 0x%04x\n", word); | ||
2057 | } | ||
2058 | |||
2059 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word); | ||
2060 | if (word == 0xffff) { | ||
2061 | rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0); | ||
2062 | rt2x00_set_field16(&word, EEPROM_FREQ_SEQ, 0); | ||
2063 | rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word); | ||
2064 | EEPROM(rt2x00dev, "Freq: 0x%04x\n", word); | ||
2065 | } | ||
2066 | |||
2067 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &word); | ||
2068 | if (word == 0xffff) { | ||
2069 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); | ||
2070 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); | ||
2071 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); | ||
2072 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | ||
2073 | } else { | ||
2074 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_1); | ||
2075 | if (value < -10 || value > 10) | ||
2076 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_1, 0); | ||
2077 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_BG_2); | ||
2078 | if (value < -10 || value > 10) | ||
2079 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_BG_2, 0); | ||
2080 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_BG, word); | ||
2081 | } | ||
2082 | |||
2083 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &word); | ||
2084 | if (word == 0xffff) { | ||
2085 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | ||
2086 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | ||
2087 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | ||
2088 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | ||
2089 | } else { | ||
2090 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | ||
2091 | if (value < -10 || value > 10) | ||
2092 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | ||
2093 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_2); | ||
2094 | if (value < -10 || value > 10) | ||
2095 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | ||
2096 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | ||
2097 | } | ||
2098 | |||
2099 | return 0; | ||
2100 | } | ||
2101 | |||
2102 | static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | ||
2103 | { | ||
2104 | u32 reg; | ||
2105 | u16 value; | ||
2106 | u16 eeprom; | ||
2107 | u16 device; | ||
2108 | |||
2109 | /* | ||
2110 | * Read EEPROM word for configuration. | ||
2111 | */ | ||
2112 | rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); | ||
2113 | |||
2114 | /* | ||
2115 | * Identify RF chipset. | ||
2116 | * To determine the RT chip we have to read the | ||
2117 | * PCI header of the device. | ||
2118 | */ | ||
2119 | pci_read_config_word(rt2x00dev_pci(rt2x00dev), | ||
2120 | PCI_CONFIG_HEADER_DEVICE, &device); | ||
2121 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | ||
2122 | rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); | ||
2123 | rt2x00_set_chip(rt2x00dev, device, value, reg); | ||
2124 | |||
2125 | if (!rt2x00_rf(&rt2x00dev->chip, RF5225) && | ||
2126 | !rt2x00_rf(&rt2x00dev->chip, RF5325) && | ||
2127 | !rt2x00_rf(&rt2x00dev->chip, RF2527) && | ||
2128 | !rt2x00_rf(&rt2x00dev->chip, RF2529)) { | ||
2129 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | ||
2130 | return -ENODEV; | ||
2131 | } | ||
2132 | |||
2133 | /* | ||
2134 | * Identify default antenna configuration. | ||
2135 | */ | ||
2136 | rt2x00dev->hw->conf.antenna_sel_tx = | ||
2137 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT); | ||
2138 | rt2x00dev->hw->conf.antenna_sel_rx = | ||
2139 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT); | ||
2140 | |||
2141 | /* | ||
2142 | * Read the Frame type. | ||
2143 | */ | ||
2144 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE)) | ||
2145 | __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); | ||
2146 | |||
2147 | /* | ||
2148 | * Determine number of antenna's. | ||
2149 | */ | ||
2150 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2) | ||
2151 | __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags); | ||
2152 | |||
2153 | /* | ||
2154 | * Detect if this device has an hardware controlled radio. | ||
2155 | */ | ||
2156 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) | ||
2157 | __set_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | ||
2158 | |||
2159 | /* | ||
2160 | * Read frequency offset and RF programming sequence. | ||
2161 | */ | ||
2162 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); | ||
2163 | if (rt2x00_get_field16(eeprom, EEPROM_FREQ_SEQ)) | ||
2164 | __set_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags); | ||
2165 | |||
2166 | rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET); | ||
2167 | |||
2168 | /* | ||
2169 | * Read external LNA informations. | ||
2170 | */ | ||
2171 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | ||
2172 | |||
2173 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A)) | ||
2174 | __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | ||
2175 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) | ||
2176 | __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); | ||
2177 | |||
2178 | /* | ||
2179 | * Store led settings, for correct led behaviour. | ||
2180 | * If the eeprom value is invalid, | ||
2181 | * switch to default led mode. | ||
2182 | */ | ||
2183 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | ||
2184 | |||
2185 | rt2x00dev->led_mode = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); | ||
2186 | |||
2187 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, | ||
2188 | rt2x00dev->led_mode); | ||
2189 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, | ||
2190 | rt2x00_get_field16(eeprom, | ||
2191 | EEPROM_LED_POLARITY_GPIO_0)); | ||
2192 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, | ||
2193 | rt2x00_get_field16(eeprom, | ||
2194 | EEPROM_LED_POLARITY_GPIO_1)); | ||
2195 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, | ||
2196 | rt2x00_get_field16(eeprom, | ||
2197 | EEPROM_LED_POLARITY_GPIO_2)); | ||
2198 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, | ||
2199 | rt2x00_get_field16(eeprom, | ||
2200 | EEPROM_LED_POLARITY_GPIO_3)); | ||
2201 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, | ||
2202 | rt2x00_get_field16(eeprom, | ||
2203 | EEPROM_LED_POLARITY_GPIO_4)); | ||
2204 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, | ||
2205 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); | ||
2206 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, | ||
2207 | rt2x00_get_field16(eeprom, | ||
2208 | EEPROM_LED_POLARITY_RDY_G)); | ||
2209 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, | ||
2210 | rt2x00_get_field16(eeprom, | ||
2211 | EEPROM_LED_POLARITY_RDY_A)); | ||
2212 | |||
2213 | return 0; | ||
2214 | } | ||
2215 | |||
2216 | /* | ||
2217 | * RF value list for RF5225 & RF5325 | ||
2218 | * Supports: 2.4 GHz & 5.2 GHz, rf_sequence disabled | ||
2219 | */ | ||
2220 | static const struct rf_channel rf_vals_noseq[] = { | ||
2221 | { 1, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa0b }, | ||
2222 | { 2, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa1f }, | ||
2223 | { 3, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa0b }, | ||
2224 | { 4, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa1f }, | ||
2225 | { 5, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa0b }, | ||
2226 | { 6, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa1f }, | ||
2227 | { 7, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa0b }, | ||
2228 | { 8, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa1f }, | ||
2229 | { 9, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa0b }, | ||
2230 | { 10, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa1f }, | ||
2231 | { 11, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa0b }, | ||
2232 | { 12, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa1f }, | ||
2233 | { 13, 0x00002ccc, 0x0000479e, 0x00068455, 0x000ffa0b }, | ||
2234 | { 14, 0x00002ccc, 0x000047a2, 0x00068455, 0x000ffa13 }, | ||
2235 | |||
2236 | /* 802.11 UNI / HyperLan 2 */ | ||
2237 | { 36, 0x00002ccc, 0x0000499a, 0x0009be55, 0x000ffa23 }, | ||
2238 | { 40, 0x00002ccc, 0x000049a2, 0x0009be55, 0x000ffa03 }, | ||
2239 | { 44, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000ffa0b }, | ||
2240 | { 48, 0x00002ccc, 0x000049aa, 0x0009be55, 0x000ffa13 }, | ||
2241 | { 52, 0x00002ccc, 0x000049ae, 0x0009ae55, 0x000ffa1b }, | ||
2242 | { 56, 0x00002ccc, 0x000049b2, 0x0009ae55, 0x000ffa23 }, | ||
2243 | { 60, 0x00002ccc, 0x000049ba, 0x0009ae55, 0x000ffa03 }, | ||
2244 | { 64, 0x00002ccc, 0x000049be, 0x0009ae55, 0x000ffa0b }, | ||
2245 | |||
2246 | /* 802.11 HyperLan 2 */ | ||
2247 | { 100, 0x00002ccc, 0x00004a2a, 0x000bae55, 0x000ffa03 }, | ||
2248 | { 104, 0x00002ccc, 0x00004a2e, 0x000bae55, 0x000ffa0b }, | ||
2249 | { 108, 0x00002ccc, 0x00004a32, 0x000bae55, 0x000ffa13 }, | ||
2250 | { 112, 0x00002ccc, 0x00004a36, 0x000bae55, 0x000ffa1b }, | ||
2251 | { 116, 0x00002ccc, 0x00004a3a, 0x000bbe55, 0x000ffa23 }, | ||
2252 | { 120, 0x00002ccc, 0x00004a82, 0x000bbe55, 0x000ffa03 }, | ||
2253 | { 124, 0x00002ccc, 0x00004a86, 0x000bbe55, 0x000ffa0b }, | ||
2254 | { 128, 0x00002ccc, 0x00004a8a, 0x000bbe55, 0x000ffa13 }, | ||
2255 | { 132, 0x00002ccc, 0x00004a8e, 0x000bbe55, 0x000ffa1b }, | ||
2256 | { 136, 0x00002ccc, 0x00004a92, 0x000bbe55, 0x000ffa23 }, | ||
2257 | |||
2258 | /* 802.11 UNII */ | ||
2259 | { 140, 0x00002ccc, 0x00004a9a, 0x000bbe55, 0x000ffa03 }, | ||
2260 | { 149, 0x00002ccc, 0x00004aa2, 0x000bbe55, 0x000ffa1f }, | ||
2261 | { 153, 0x00002ccc, 0x00004aa6, 0x000bbe55, 0x000ffa27 }, | ||
2262 | { 157, 0x00002ccc, 0x00004aae, 0x000bbe55, 0x000ffa07 }, | ||
2263 | { 161, 0x00002ccc, 0x00004ab2, 0x000bbe55, 0x000ffa0f }, | ||
2264 | { 165, 0x00002ccc, 0x00004ab6, 0x000bbe55, 0x000ffa17 }, | ||
2265 | |||
2266 | /* MMAC(Japan)J52 ch 34,38,42,46 */ | ||
2267 | { 34, 0x00002ccc, 0x0000499a, 0x0009be55, 0x000ffa0b }, | ||
2268 | { 38, 0x00002ccc, 0x0000499e, 0x0009be55, 0x000ffa13 }, | ||
2269 | { 42, 0x00002ccc, 0x000049a2, 0x0009be55, 0x000ffa1b }, | ||
2270 | { 46, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000ffa23 }, | ||
2271 | }; | ||
2272 | |||
2273 | /* | ||
2274 | * RF value list for RF5225 & RF5325 | ||
2275 | * Supports: 2.4 GHz & 5.2 GHz, rf_sequence enabled | ||
2276 | */ | ||
2277 | static const struct rf_channel rf_vals_seq[] = { | ||
2278 | { 1, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa0b }, | ||
2279 | { 2, 0x00002ccc, 0x00004786, 0x00068455, 0x000ffa1f }, | ||
2280 | { 3, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa0b }, | ||
2281 | { 4, 0x00002ccc, 0x0000478a, 0x00068455, 0x000ffa1f }, | ||
2282 | { 5, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa0b }, | ||
2283 | { 6, 0x00002ccc, 0x0000478e, 0x00068455, 0x000ffa1f }, | ||
2284 | { 7, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa0b }, | ||
2285 | { 8, 0x00002ccc, 0x00004792, 0x00068455, 0x000ffa1f }, | ||
2286 | { 9, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa0b }, | ||
2287 | { 10, 0x00002ccc, 0x00004796, 0x00068455, 0x000ffa1f }, | ||
2288 | { 11, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa0b }, | ||
2289 | { 12, 0x00002ccc, 0x0000479a, 0x00068455, 0x000ffa1f }, | ||
2290 | { 13, 0x00002ccc, 0x0000479e, 0x00068455, 0x000ffa0b }, | ||
2291 | { 14, 0x00002ccc, 0x000047a2, 0x00068455, 0x000ffa13 }, | ||
2292 | |||
2293 | /* 802.11 UNI / HyperLan 2 */ | ||
2294 | { 36, 0x00002cd4, 0x0004481a, 0x00098455, 0x000c0a03 }, | ||
2295 | { 40, 0x00002cd0, 0x00044682, 0x00098455, 0x000c0a03 }, | ||
2296 | { 44, 0x00002cd0, 0x00044686, 0x00098455, 0x000c0a1b }, | ||
2297 | { 48, 0x00002cd0, 0x0004468e, 0x00098655, 0x000c0a0b }, | ||
2298 | { 52, 0x00002cd0, 0x00044692, 0x00098855, 0x000c0a23 }, | ||
2299 | { 56, 0x00002cd0, 0x0004469a, 0x00098c55, 0x000c0a13 }, | ||
2300 | { 60, 0x00002cd0, 0x000446a2, 0x00098e55, 0x000c0a03 }, | ||
2301 | { 64, 0x00002cd0, 0x000446a6, 0x00099255, 0x000c0a1b }, | ||
2302 | |||
2303 | /* 802.11 HyperLan 2 */ | ||
2304 | { 100, 0x00002cd4, 0x0004489a, 0x000b9855, 0x000c0a03 }, | ||
2305 | { 104, 0x00002cd4, 0x000448a2, 0x000b9855, 0x000c0a03 }, | ||
2306 | { 108, 0x00002cd4, 0x000448aa, 0x000b9855, 0x000c0a03 }, | ||
2307 | { 112, 0x00002cd4, 0x000448b2, 0x000b9a55, 0x000c0a03 }, | ||
2308 | { 116, 0x00002cd4, 0x000448ba, 0x000b9a55, 0x000c0a03 }, | ||
2309 | { 120, 0x00002cd0, 0x00044702, 0x000b9a55, 0x000c0a03 }, | ||
2310 | { 124, 0x00002cd0, 0x00044706, 0x000b9a55, 0x000c0a1b }, | ||
2311 | { 128, 0x00002cd0, 0x0004470e, 0x000b9c55, 0x000c0a0b }, | ||
2312 | { 132, 0x00002cd0, 0x00044712, 0x000b9c55, 0x000c0a23 }, | ||
2313 | { 136, 0x00002cd0, 0x0004471a, 0x000b9e55, 0x000c0a13 }, | ||
2314 | |||
2315 | /* 802.11 UNII */ | ||
2316 | { 140, 0x00002cd0, 0x00044722, 0x000b9e55, 0x000c0a03 }, | ||
2317 | { 149, 0x00002cd0, 0x0004472e, 0x000ba255, 0x000c0a1b }, | ||
2318 | { 153, 0x00002cd0, 0x00044736, 0x000ba255, 0x000c0a0b }, | ||
2319 | { 157, 0x00002cd4, 0x0004490a, 0x000ba255, 0x000c0a17 }, | ||
2320 | { 161, 0x00002cd4, 0x00044912, 0x000ba255, 0x000c0a17 }, | ||
2321 | { 165, 0x00002cd4, 0x0004491a, 0x000ba255, 0x000c0a17 }, | ||
2322 | |||
2323 | /* MMAC(Japan)J52 ch 34,38,42,46 */ | ||
2324 | { 34, 0x00002ccc, 0x0000499a, 0x0009be55, 0x000c0a0b }, | ||
2325 | { 38, 0x00002ccc, 0x0000499e, 0x0009be55, 0x000c0a13 }, | ||
2326 | { 42, 0x00002ccc, 0x000049a2, 0x0009be55, 0x000c0a1b }, | ||
2327 | { 46, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000c0a23 }, | ||
2328 | }; | ||
2329 | |||
2330 | static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | ||
2331 | { | ||
2332 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
2333 | u8 *txpower; | ||
2334 | unsigned int i; | ||
2335 | |||
2336 | /* | ||
2337 | * Initialize all hw fields. | ||
2338 | */ | ||
2339 | rt2x00dev->hw->flags = | ||
2340 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | ||
2341 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
2342 | IEEE80211_HW_MONITOR_DURING_OPER | | ||
2343 | IEEE80211_HW_NO_PROBE_FILTERING; | ||
2344 | rt2x00dev->hw->extra_tx_headroom = 0; | ||
2345 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | ||
2346 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | ||
2347 | rt2x00dev->hw->queues = 5; | ||
2348 | |||
2349 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | ||
2350 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | ||
2351 | rt2x00_eeprom_addr(rt2x00dev, | ||
2352 | EEPROM_MAC_ADDR_0)); | ||
2353 | |||
2354 | /* | ||
2355 | * Convert tx_power array in eeprom. | ||
2356 | */ | ||
2357 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); | ||
2358 | for (i = 0; i < 14; i++) | ||
2359 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | ||
2360 | |||
2361 | /* | ||
2362 | * Initialize hw_mode information. | ||
2363 | */ | ||
2364 | spec->num_modes = 2; | ||
2365 | spec->num_rates = 12; | ||
2366 | spec->tx_power_a = NULL; | ||
2367 | spec->tx_power_bg = txpower; | ||
2368 | spec->tx_power_default = DEFAULT_TXPOWER; | ||
2369 | |||
2370 | if (!test_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags)) { | ||
2371 | spec->num_channels = 14; | ||
2372 | spec->channels = rf_vals_noseq; | ||
2373 | } else { | ||
2374 | spec->num_channels = 14; | ||
2375 | spec->channels = rf_vals_seq; | ||
2376 | } | ||
2377 | |||
2378 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | ||
2379 | rt2x00_rf(&rt2x00dev->chip, RF5325)) { | ||
2380 | spec->num_modes = 3; | ||
2381 | spec->num_channels = ARRAY_SIZE(rf_vals_seq); | ||
2382 | |||
2383 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | ||
2384 | for (i = 0; i < 14; i++) | ||
2385 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | ||
2386 | |||
2387 | spec->tx_power_a = txpower; | ||
2388 | } | ||
2389 | } | ||
2390 | |||
2391 | static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | ||
2392 | { | ||
2393 | int retval; | ||
2394 | |||
2395 | /* | ||
2396 | * Allocate eeprom data. | ||
2397 | */ | ||
2398 | retval = rt61pci_validate_eeprom(rt2x00dev); | ||
2399 | if (retval) | ||
2400 | return retval; | ||
2401 | |||
2402 | retval = rt61pci_init_eeprom(rt2x00dev); | ||
2403 | if (retval) | ||
2404 | return retval; | ||
2405 | |||
2406 | /* | ||
2407 | * Initialize hw specifications. | ||
2408 | */ | ||
2409 | rt61pci_probe_hw_mode(rt2x00dev); | ||
2410 | |||
2411 | /* | ||
2412 | * This device requires firmware | ||
2413 | */ | ||
2414 | __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->flags); | ||
2415 | |||
2416 | /* | ||
2417 | * Set the rssi offset. | ||
2418 | */ | ||
2419 | rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET; | ||
2420 | |||
2421 | return 0; | ||
2422 | } | ||
2423 | |||
2424 | /* | ||
2425 | * IEEE80211 stack callback functions. | ||
2426 | */ | ||
2427 | static int rt61pci_set_retry_limit(struct ieee80211_hw *hw, | ||
2428 | u32 short_retry, u32 long_retry) | ||
2429 | { | ||
2430 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2431 | u32 reg; | ||
2432 | |||
2433 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); | ||
2434 | rt2x00_set_field32(®, TXRX_CSR4_LONG_RETRY_LIMIT, long_retry); | ||
2435 | rt2x00_set_field32(®, TXRX_CSR4_SHORT_RETRY_LIMIT, short_retry); | ||
2436 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | ||
2437 | |||
2438 | return 0; | ||
2439 | } | ||
2440 | |||
2441 | static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) | ||
2442 | { | ||
2443 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2444 | u64 tsf; | ||
2445 | u32 reg; | ||
2446 | |||
2447 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR13, ®); | ||
2448 | tsf = (u64) rt2x00_get_field32(reg, TXRX_CSR13_HIGH_TSFTIMER) << 32; | ||
2449 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR12, ®); | ||
2450 | tsf |= rt2x00_get_field32(reg, TXRX_CSR12_LOW_TSFTIMER); | ||
2451 | |||
2452 | return tsf; | ||
2453 | } | ||
2454 | |||
2455 | static void rt61pci_reset_tsf(struct ieee80211_hw *hw) | ||
2456 | { | ||
2457 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2458 | |||
2459 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR12, 0); | ||
2460 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR13, 0); | ||
2461 | } | ||
2462 | |||
2463 | int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
2464 | struct ieee80211_tx_control *control) | ||
2465 | { | ||
2466 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2467 | |||
2468 | /* | ||
2469 | * Just in case the ieee80211 doesn't set this, | ||
2470 | * but we need this queue set for the descriptor | ||
2471 | * initialization. | ||
2472 | */ | ||
2473 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
2474 | |||
2475 | /* | ||
2476 | * We need to append the descriptor in front of the | ||
2477 | * beacon frame. | ||
2478 | */ | ||
2479 | if (skb_headroom(skb) < TXD_DESC_SIZE) { | ||
2480 | if (pskb_expand_head(skb, TXD_DESC_SIZE, 0, GFP_ATOMIC)) { | ||
2481 | dev_kfree_skb(skb); | ||
2482 | return -ENOMEM; | ||
2483 | } | ||
2484 | } | ||
2485 | |||
2486 | /* | ||
2487 | * First we create the beacon. | ||
2488 | */ | ||
2489 | skb_push(skb, TXD_DESC_SIZE); | ||
2490 | rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data, | ||
2491 | (struct ieee80211_hdr *)(skb->data + | ||
2492 | TXD_DESC_SIZE), | ||
2493 | skb->len - TXD_DESC_SIZE, control); | ||
2494 | |||
2495 | /* | ||
2496 | * Write entire beacon with descriptor to register, | ||
2497 | * and kick the beacon generator. | ||
2498 | */ | ||
2499 | rt2x00pci_register_multiwrite(rt2x00dev, HW_BEACON_BASE0, skb->data, skb->len); | ||
2500 | rt61pci_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
2501 | |||
2502 | return 0; | ||
2503 | } | ||
2504 | |||
2505 | static const struct ieee80211_ops rt61pci_mac80211_ops = { | ||
2506 | .tx = rt2x00mac_tx, | ||
2507 | .add_interface = rt2x00mac_add_interface, | ||
2508 | .remove_interface = rt2x00mac_remove_interface, | ||
2509 | .config = rt2x00mac_config, | ||
2510 | .config_interface = rt2x00mac_config_interface, | ||
2511 | .set_multicast_list = rt2x00mac_set_multicast_list, | ||
2512 | .get_stats = rt2x00mac_get_stats, | ||
2513 | .set_retry_limit = rt61pci_set_retry_limit, | ||
2514 | .conf_tx = rt2x00mac_conf_tx, | ||
2515 | .get_tx_stats = rt2x00mac_get_tx_stats, | ||
2516 | .get_tsf = rt61pci_get_tsf, | ||
2517 | .reset_tsf = rt61pci_reset_tsf, | ||
2518 | .beacon_update = rt61pci_beacon_update, | ||
2519 | }; | ||
2520 | |||
2521 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | ||
2522 | .irq_handler = rt61pci_interrupt, | ||
2523 | .probe_hw = rt61pci_probe_hw, | ||
2524 | .get_firmware_name = rt61pci_get_firmware_name, | ||
2525 | .load_firmware = rt61pci_load_firmware, | ||
2526 | .initialize = rt2x00pci_initialize, | ||
2527 | .uninitialize = rt2x00pci_uninitialize, | ||
2528 | .set_device_state = rt61pci_set_device_state, | ||
2529 | #ifdef CONFIG_RT61PCI_RFKILL | ||
2530 | .rfkill_poll = rt61pci_rfkill_poll, | ||
2531 | #endif /* CONFIG_RT61PCI_RFKILL */ | ||
2532 | .link_stats = rt61pci_link_stats, | ||
2533 | .reset_tuner = rt61pci_reset_tuner, | ||
2534 | .link_tuner = rt61pci_link_tuner, | ||
2535 | .write_tx_desc = rt61pci_write_tx_desc, | ||
2536 | .write_tx_data = rt2x00pci_write_tx_data, | ||
2537 | .kick_tx_queue = rt61pci_kick_tx_queue, | ||
2538 | .fill_rxdone = rt61pci_fill_rxdone, | ||
2539 | .config_mac_addr = rt61pci_config_mac_addr, | ||
2540 | .config_bssid = rt61pci_config_bssid, | ||
2541 | .config_packet_filter = rt61pci_config_packet_filter, | ||
2542 | .config_type = rt61pci_config_type, | ||
2543 | .config = rt61pci_config, | ||
2544 | }; | ||
2545 | |||
2546 | static const struct rt2x00_ops rt61pci_ops = { | ||
2547 | .name = DRV_NAME, | ||
2548 | .rxd_size = RXD_DESC_SIZE, | ||
2549 | .txd_size = TXD_DESC_SIZE, | ||
2550 | .eeprom_size = EEPROM_SIZE, | ||
2551 | .rf_size = RF_SIZE, | ||
2552 | .lib = &rt61pci_rt2x00_ops, | ||
2553 | .hw = &rt61pci_mac80211_ops, | ||
2554 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
2555 | .debugfs = &rt61pci_rt2x00debug, | ||
2556 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
2557 | }; | ||
2558 | |||
2559 | /* | ||
2560 | * RT61pci module information. | ||
2561 | */ | ||
2562 | static struct pci_device_id rt61pci_device_table[] = { | ||
2563 | /* RT2561s */ | ||
2564 | { PCI_DEVICE(0x1814, 0x0301), PCI_DEVICE_DATA(&rt61pci_ops) }, | ||
2565 | /* RT2561 v2 */ | ||
2566 | { PCI_DEVICE(0x1814, 0x0302), PCI_DEVICE_DATA(&rt61pci_ops) }, | ||
2567 | /* RT2661 */ | ||
2568 | { PCI_DEVICE(0x1814, 0x0401), PCI_DEVICE_DATA(&rt61pci_ops) }, | ||
2569 | { 0, } | ||
2570 | }; | ||
2571 | |||
2572 | MODULE_AUTHOR(DRV_PROJECT); | ||
2573 | MODULE_VERSION(DRV_VERSION); | ||
2574 | MODULE_DESCRIPTION("Ralink RT61 PCI & PCMCIA Wireless LAN driver."); | ||
2575 | MODULE_SUPPORTED_DEVICE("Ralink RT2561, RT2561s & RT2661 " | ||
2576 | "PCI & PCMCIA chipset based cards"); | ||
2577 | MODULE_DEVICE_TABLE(pci, rt61pci_device_table); | ||
2578 | MODULE_FIRMWARE(FIRMWARE_RT2561); | ||
2579 | MODULE_FIRMWARE(FIRMWARE_RT2561s); | ||
2580 | MODULE_FIRMWARE(FIRMWARE_RT2661); | ||
2581 | MODULE_LICENSE("GPL"); | ||
2582 | |||
2583 | static struct pci_driver rt61pci_driver = { | ||
2584 | .name = DRV_NAME, | ||
2585 | .id_table = rt61pci_device_table, | ||
2586 | .probe = rt2x00pci_probe, | ||
2587 | .remove = __devexit_p(rt2x00pci_remove), | ||
2588 | .suspend = rt2x00pci_suspend, | ||
2589 | .resume = rt2x00pci_resume, | ||
2590 | }; | ||
2591 | |||
2592 | static int __init rt61pci_init(void) | ||
2593 | { | ||
2594 | return pci_register_driver(&rt61pci_driver); | ||
2595 | } | ||
2596 | |||
2597 | static void __exit rt61pci_exit(void) | ||
2598 | { | ||
2599 | pci_unregister_driver(&rt61pci_driver); | ||
2600 | } | ||
2601 | |||
2602 | module_init(rt61pci_init); | ||
2603 | module_exit(rt61pci_exit); | ||